From db4b397e2e222e7454982017595f86e1d7c17606 Mon Sep 17 00:00:00 2001 From: Sergey Matyunin Date: Tue, 15 Sep 2026 00:16:35 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=20=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B5=D0=B9=20=D0=BE=D0=BA=D0=BE=D0=BD=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D0=BB=D0=BD=D0=B5=D1=87=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BB=D1=83=D1=87=D0=B5=D0=B9=20(#577)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: #577 User-Visible: yes --- custom_components/houseplan/const.py | 2 +- .../houseplan/frontend/houseplan-assets.json | 274 ++++++++--------- ...-Caayxvt2.js => backdrop-pick-CXmKHH6_.js} | 2 +- .../{de-JVEEGD9u.js => de-BRgmJptb.js} | 2 +- .../houseplan-assets/editor-DCXyMNgY.js | 10 +- .../frontend/houseplan-assets/fr-B8hQ5YK4.js | 2 +- .../furniture-plan-art.generated-D_9nJ3h5.js | 2 +- ...BCGpvbDT.js => houseplan-card-Di_izZTU.js} | 160 +++++----- ...s => houseplan-editor-runtime-dzTrOQhv.js} | 282 +++++++++--------- .../houseplan-onboarding-runtime-BLRnH1D6.js | 60 ++-- ...=> hp-zigbee-topology-overlay-_ZK20cr6.js} | 2 +- .../iso-scene-render-BIRwzucU.js | 4 +- ...s => live-interaction-runtime-AJRZAUON.js} | 2 +- ...ort-BAtsOfAV.js => pdf-export-B2sbsWvc.js} | 4 +- .../summary-panel-editor-BDoONUEa.js | 2 +- ..._.js => summary-panel-metrics-O-xxtEs5.js} | 2 +- .../summary-panel-runtime-loaded-CNpqraog.js | 4 +- .../zigbee-topology-Ba2URGlk.js | 2 +- ...js => zigbee-topology-runtime-BZVl6ukN.js} | 2 +- .../houseplan/frontend/houseplan-card.js | 2 +- .../houseplan/frontend/houseplan-panel.js | 2 +- .../houseplan/support_package.py | 3 + custom_components/houseplan/validation.py | 2 + demo/smoke_sun.mjs | 35 ++- dist/houseplan-assets.json | 274 ++++++++--------- ...-Caayxvt2.js => backdrop-pick-CXmKHH6_.js} | 2 +- .../{de-JVEEGD9u.js => de-BRgmJptb.js} | 2 +- .../houseplan-assets/editor-DCXyMNgY.js | 10 +- .../houseplan-assets/fr-B8hQ5YK4.js | 2 +- .../furniture-plan-art.generated-D_9nJ3h5.js | 2 +- ...BCGpvbDT.js => houseplan-card-Di_izZTU.js} | 160 +++++----- ...s => houseplan-editor-runtime-dzTrOQhv.js} | 282 +++++++++--------- .../houseplan-onboarding-runtime-BLRnH1D6.js | 60 ++-- ...=> hp-zigbee-topology-overlay-_ZK20cr6.js} | 2 +- .../iso-scene-render-BIRwzucU.js | 4 +- ...s => live-interaction-runtime-AJRZAUON.js} | 2 +- ...ort-BAtsOfAV.js => pdf-export-B2sbsWvc.js} | 4 +- .../summary-panel-editor-BDoONUEa.js | 2 +- ..._.js => summary-panel-metrics-O-xxtEs5.js} | 2 +- .../summary-panel-runtime-loaded-CNpqraog.js | 4 +- .../zigbee-topology-Ba2URGlk.js | 2 +- ...js => zigbee-topology-runtime-BZVl6ukN.js} | 2 +- dist/houseplan-card.js | 2 +- dist/houseplan-panel.js | 2 +- docs/CHANGELOG.md | 6 + docs/CHANGELOG.ru.md | 6 + docs/CONFIG-COMPATIBILITY.md | 14 + docs/SUN.md | 35 ++- docs/TESTING.md | 15 + docs/USER-GUIDE.ru.md | 15 +- docs/WALL-THICKNESS.md | 19 +- docs/images/screenshots.json | 24 +- scripts/bundle-budget.mjs | 7 +- scripts/config-field-registry.mjs | 15 + scripts/config-schema.json | 7 + scripts/mutation-registry.mjs | 57 ++++ src/houseplan-card.ts | 17 +- src/houseplan-editor-runtime.ts | 14 +- src/i18n/de.json | 3 + src/i18n/en.json | 3 + src/i18n/fr.json | 3 + src/i18n/ru.json | 3 + src/sun-settings-view.ts | 20 ++ src/sun.ts | 47 ++- src/types.ts | 5 + test/config-schema-parity.test.mjs | 3 +- test/sun.test.mjs | 43 ++- tests_backend/test_ha_import_export.py | 14 + tests_backend/test_support_package.py | 3 + tests_backend/test_validation.py | 10 +- 70 files changed, 1209 insertions(+), 885 deletions(-) rename custom_components/houseplan/frontend/houseplan-assets/{backdrop-pick-Caayxvt2.js => backdrop-pick-CXmKHH6_.js} (99%) rename custom_components/houseplan/frontend/houseplan-assets/{de-JVEEGD9u.js => de-BRgmJptb.js} (71%) rename dist/houseplan-assets/editor-C5Zq-3aA.js => custom_components/houseplan/frontend/houseplan-assets/editor-DCXyMNgY.js (84%) rename dist/houseplan-assets/fr-B-ete5Dh.js => custom_components/houseplan/frontend/houseplan-assets/fr-B8hQ5YK4.js (71%) rename dist/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js => custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js (99%) rename custom_components/houseplan/frontend/houseplan-assets/{houseplan-card-BCGpvbDT.js => houseplan-card-Di_izZTU.js} (72%) rename custom_components/houseplan/frontend/houseplan-assets/{houseplan-editor-runtime-BNMtEwiN.js => houseplan-editor-runtime-dzTrOQhv.js} (80%) rename dist/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js => custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js (82%) rename custom_components/houseplan/frontend/houseplan-assets/{hp-zigbee-topology-overlay-D3IWAxB8.js => hp-zigbee-topology-overlay-_ZK20cr6.js} (95%) rename dist/houseplan-assets/iso-scene-render-ceJKJKhC.js => custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-BIRwzucU.js (95%) rename custom_components/houseplan/frontend/houseplan-assets/{live-interaction-runtime-CxW-k-p_.js => live-interaction-runtime-AJRZAUON.js} (76%) rename custom_components/houseplan/frontend/houseplan-assets/{pdf-export-BAtsOfAV.js => pdf-export-B2sbsWvc.js} (99%) rename dist/houseplan-assets/summary-panel-editor-BAGJ8QwD.js => custom_components/houseplan/frontend/houseplan-assets/summary-panel-editor-BDoONUEa.js (97%) rename custom_components/houseplan/frontend/houseplan-assets/{summary-panel-metrics-CXnAEe7_.js => summary-panel-metrics-O-xxtEs5.js} (68%) rename dist/houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js => custom_components/houseplan/frontend/houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js (99%) rename dist/houseplan-assets/zigbee-topology-DlU7AXvw.js => custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-Ba2URGlk.js (95%) rename custom_components/houseplan/frontend/houseplan-assets/{zigbee-topology-runtime-CWcX1vcd.js => zigbee-topology-runtime-BZVl6ukN.js} (93%) rename dist/houseplan-assets/{backdrop-pick-Caayxvt2.js => backdrop-pick-CXmKHH6_.js} (99%) rename dist/houseplan-assets/{de-JVEEGD9u.js => de-BRgmJptb.js} (71%) rename custom_components/houseplan/frontend/houseplan-assets/editor-C5Zq-3aA.js => dist/houseplan-assets/editor-DCXyMNgY.js (84%) rename custom_components/houseplan/frontend/houseplan-assets/fr-B-ete5Dh.js => dist/houseplan-assets/fr-B8hQ5YK4.js (71%) rename custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js => dist/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js (99%) rename dist/houseplan-assets/{houseplan-card-BCGpvbDT.js => houseplan-card-Di_izZTU.js} (72%) rename dist/houseplan-assets/{houseplan-editor-runtime-BNMtEwiN.js => houseplan-editor-runtime-dzTrOQhv.js} (80%) rename custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js => dist/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js (82%) rename dist/houseplan-assets/{hp-zigbee-topology-overlay-D3IWAxB8.js => hp-zigbee-topology-overlay-_ZK20cr6.js} (95%) rename custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-ceJKJKhC.js => dist/houseplan-assets/iso-scene-render-BIRwzucU.js (95%) rename dist/houseplan-assets/{live-interaction-runtime-CxW-k-p_.js => live-interaction-runtime-AJRZAUON.js} (76%) rename dist/houseplan-assets/{pdf-export-BAtsOfAV.js => pdf-export-B2sbsWvc.js} (99%) rename custom_components/houseplan/frontend/houseplan-assets/summary-panel-editor-BAGJ8QwD.js => dist/houseplan-assets/summary-panel-editor-BDoONUEa.js (97%) rename dist/houseplan-assets/{summary-panel-metrics-CXnAEe7_.js => summary-panel-metrics-O-xxtEs5.js} (68%) rename custom_components/houseplan/frontend/houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js => dist/houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js (99%) rename custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-DlU7AXvw.js => dist/houseplan-assets/zigbee-topology-Ba2URGlk.js (95%) rename dist/houseplan-assets/{zigbee-topology-runtime-CWcX1vcd.js => zigbee-topology-runtime-BZVl6ukN.js} (93%) create mode 100644 src/sun-settings-view.ts diff --git a/custom_components/houseplan/const.py b/custom_components/houseplan/const.py index f6ce6557..31cb7c6a 100755 --- a/custom_components/houseplan/const.py +++ b/custom_components/houseplan/const.py @@ -91,7 +91,7 @@ MAX_IMPORT_PREVIEWS_TOTAL = 3 DEFAULT_CONFIG: dict[str, object] = { "spaces": [], "markers": [], - "settings": {"bg_mode": "daynight"}, + "settings": {"bg_mode": "daynight", "sun_ray_origin": "inner"}, } # #42: THE stable public error-code contract. Every code a user-facing diff --git a/custom_components/houseplan/frontend/houseplan-assets.json b/custom_components/houseplan/frontend/houseplan-assets.json index 34562d31..a0538754 100644 --- a/custom_components/houseplan/frontend/houseplan-assets.json +++ b/custom_components/houseplan/frontend/houseplan-assets.json @@ -1,295 +1,295 @@ { "schema": 1, - "fingerprint": "0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e", + "fingerprint": "530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33", "entry": "houseplan-card.js", "panelEntry": "houseplan-panel.js", "initialViewFiles": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", + "houseplan-assets/houseplan-card-Di_izZTU.js", "houseplan-card.js" ], - "initialViewGzipBytes": 290379, + "initialViewGzipBytes": 290629, "initialPanelFiles": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", + "houseplan-assets/houseplan-card-Di_izZTU.js", "houseplan-panel.js" ], - "initialPanelGzipBytes": 291901, + "initialPanelGzipBytes": 292151, "initialPanelOnlyFiles": [ "houseplan-panel.js" ], - "initialPanelOnlyGzipBytes": 2325, + "initialPanelOnlyGzipBytes": 2327, "lazyFiles": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/de-JVEEGD9u.js", - "houseplan-assets/editor-C5Zq-3aA.js", - "houseplan-assets/fr-B-ete5Dh.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js", - "houseplan-assets/hp-zigbee-topology-overlay-D3IWAxB8.js", - "houseplan-assets/iso-scene-render-ceJKJKhC.js", - "houseplan-assets/live-interaction-runtime-CxW-k-p_.js", - "houseplan-assets/pdf-export-BAtsOfAV.js", - "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js", - "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/de-BRgmJptb.js", + "houseplan-assets/editor-DCXyMNgY.js", + "houseplan-assets/fr-B8hQ5YK4.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js", + "houseplan-assets/hp-zigbee-topology-overlay-_ZK20cr6.js", + "houseplan-assets/iso-scene-render-BIRwzucU.js", + "houseplan-assets/live-interaction-runtime-AJRZAUON.js", + "houseplan-assets/pdf-export-B2sbsWvc.js", + "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js", + "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js" ], - "lazyGzipBytes": 418510, + "lazyGzipBytes": 418756, "lazyEditorFiles": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/editor-C5Zq-3aA.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/editor-DCXyMNgY.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js" ], - "lazyEditorGzipBytes": 204784, + "lazyEditorGzipBytes": 204934, "lazyOnboardingFiles": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js" ], - "lazyOnboardingGzipBytes": 13914, + "lazyOnboardingGzipBytes": 13919, "lazyLocaleFiles": [ - "houseplan-assets/de-JVEEGD9u.js", - "houseplan-assets/fr-B-ete5Dh.js" + "houseplan-assets/de-BRgmJptb.js", + "houseplan-assets/fr-B8hQ5YK4.js" ], - "lazyLocaleGzipBytes": 54845, + "lazyLocaleGzipBytes": 54925, "lazyIsometricFiles": [ - "houseplan-assets/iso-scene-render-ceJKJKhC.js" + "houseplan-assets/iso-scene-render-BIRwzucU.js" ], - "lazyIsometricGzipBytes": 13232, + "lazyIsometricGzipBytes": 13236, "lazyFurnitureArtFiles": [ - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js" + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js" ], - "lazyFurnitureArtGzipBytes": 10252, + "lazyFurnitureArtGzipBytes": 10254, "lazyPdfFiles": [ - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/pdf-export-BAtsOfAV.js" + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/pdf-export-B2sbsWvc.js" ], - "lazyPdfGzipBytes": 120125, + "lazyPdfGzipBytes": 120129, "files": [ { - "path": "houseplan-assets/backdrop-pick-Caayxvt2.js", - "sha256": "3a8a8a4b522eaae770f7b0cdd5612aaa542fd81e2fef1adcb58d21d9b093b360", + "path": "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "sha256": "45a9c60eb50b3859a5a5f5330830dd5c72353b63d6f06cf8417712db248b2320", "rawBytes": 19956, - "gzipBytes": 6881, + "gzipBytes": 6880, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/de-JVEEGD9u.js", - "sha256": "f300635f221656a36e591183395cc38c77c093e2347ce98ac0b0f324f7ec8306", - "rawBytes": 91437, - "gzipBytes": 27709, + "path": "houseplan-assets/de-BRgmJptb.js", + "sha256": "0023bc3edc741291b1d463fdc3f1a24006af13ca13932e3cd37f9e761b022fe9", + "rawBytes": 91590, + "gzipBytes": 27744, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/editor-C5Zq-3aA.js", - "sha256": "4878d5efac2222fdd3fda5e695588a8d5cfe463027397b2fc8499bd6e649c6a7", + "path": "houseplan-assets/editor-DCXyMNgY.js", + "sha256": "4dba6280fe0f491e4c8a0c349e94aa7031de545fe086f9c01f3ab376db2013b7", "rawBytes": 3831, - "gzipBytes": 1583, + "gzipBytes": 1584, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/fr-B-ete5Dh.js", - "sha256": "c4d9a2f7bf0fca73861727752c5cd9b41e8cda469685e32eb34dedc8ec0f790b", - "rawBytes": 93701, - "gzipBytes": 27136, + "path": "houseplan-assets/fr-B8hQ5YK4.js", + "sha256": "5c33cb26bb68392be61510c8eb0e06ae152e0bff506f493eddaaa2c44e19aadf", + "rawBytes": 93884, + "gzipBytes": 27181, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "sha256": "69da2271017aa401f35e87387fb06d384617ee78f0d534bbd28792f5c3cb33e8", + "path": "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "sha256": "aabb06ce9a989322682a7b485a7810036f390aac547aa89bbbb03c74a7e1bde7", "rawBytes": 33655, - "gzipBytes": 10252, + "gzipBytes": 10254, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/houseplan-card-BCGpvbDT.js", - "sha256": "83f27e261a8a7a32463b67762c859e431d1468a32af7249627ec326f16696772", - "rawBytes": 1031731, - "gzipBytes": 289576, + "path": "houseplan-assets/houseplan-card-Di_izZTU.js", + "sha256": "634b25343fd2bf984b27e5a7ba7de1f24a7343b0909379bd16faa563f9499913", + "rawBytes": 1032408, + "gzipBytes": 289824, "isEntry": false, "imports": [], "dynamicImports": [ - "houseplan-assets/de-JVEEGD9u.js", - "houseplan-assets/editor-C5Zq-3aA.js", - "houseplan-assets/fr-B-ete5Dh.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js", - "houseplan-assets/hp-zigbee-topology-overlay-D3IWAxB8.js", - "houseplan-assets/iso-scene-render-ceJKJKhC.js", - "houseplan-assets/live-interaction-runtime-CxW-k-p_.js", - "houseplan-assets/pdf-export-BAtsOfAV.js", - "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js" + "houseplan-assets/de-BRgmJptb.js", + "houseplan-assets/editor-DCXyMNgY.js", + "houseplan-assets/fr-B8hQ5YK4.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js", + "houseplan-assets/hp-zigbee-topology-overlay-_ZK20cr6.js", + "houseplan-assets/iso-scene-render-BIRwzucU.js", + "houseplan-assets/live-interaction-runtime-AJRZAUON.js", + "houseplan-assets/pdf-export-B2sbsWvc.js", + "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js" ] }, { - "path": "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "sha256": "7a0814ddc88324ad5dcb87f43852bd1f92ed90e4bda658cab3a8cdfee3209c18", - "rawBytes": 669271, - "gzipBytes": 178643, + "path": "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "sha256": "f6556f260a8d8598a9f9667be241cce323d505281569ec6a5a3f01103edf9476", + "rawBytes": 669985, + "gzipBytes": 178790, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js" ], "dynamicImports": [ - "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js" + "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js" ] }, { - "path": "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js", - "sha256": "6484dea33a514dff985b752d3f3ff87086a87ab2e46e79d29773d382d9fe4695", + "path": "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js", + "sha256": "a8eff518545ca4ff644e03bdc2861bcd7e79b28e1ff65642f28fb7ca216711c8", "rawBytes": 28287, - "gzipBytes": 7033, + "gzipBytes": 7039, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/hp-zigbee-topology-overlay-D3IWAxB8.js", - "sha256": "1dd14e9ee7bb06dd0ca154b471e16f410abc14c0beb5e310266f71514e770f9b", + "path": "houseplan-assets/hp-zigbee-topology-overlay-_ZK20cr6.js", + "sha256": "b9341d7245eca9bb514c73d2fda78b5023d9d964bddf605c7af842ac71af4451", "rawBytes": 10756, - "gzipBytes": 3685, + "gzipBytes": 3686, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js", - "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js" + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js", + "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/iso-scene-render-ceJKJKhC.js", - "sha256": "e7032d13f4479fa28d8b378c900a339577e74f5c377da9b080697e20e02f5903", + "path": "houseplan-assets/iso-scene-render-BIRwzucU.js", + "sha256": "a2b6ff57e2d3d0d275ffe392c71c1cdfac8f546c41abfe8a2c7be2911624c341", "rawBytes": 39206, - "gzipBytes": 13232, + "gzipBytes": 13236, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/live-interaction-runtime-CxW-k-p_.js", - "sha256": "3b0f3ae94e957cb662f63abeb5b7fb95012da6654a0ad5a857cf7b1b6a4cb6ac", + "path": "houseplan-assets/live-interaction-runtime-AJRZAUON.js", + "sha256": "dff5f0f1ad7a5e92226f812e4948705e55b5556c802003ac1147339ea641e775", "rawBytes": 8216, - "gzipBytes": 3209, + "gzipBytes": 3210, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/pdf-export-BAtsOfAV.js", - "sha256": "2e57254cc4a637a6ed689ee1de9af9f4dc60595489683b238ead4026f7e4d60b", + "path": "houseplan-assets/pdf-export-B2sbsWvc.js", + "sha256": "63d543a4fa25f03b26f255a4ea8c6096440fd3a0c3dc1b96e8402560fe9709b6", "rawBytes": 236244, - "gzipBytes": 109873, + "gzipBytes": 109875, "isEntry": false, "imports": [ - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/summary-panel-editor-BAGJ8QwD.js", - "sha256": "72d3ad8f8d61228dc255eed21ff157ad9c96ee8a35bd7b7b999f4090adb1925c", + "path": "houseplan-assets/summary-panel-editor-BDoONUEa.js", + "sha256": "caf18642431f5c391e03c7c06f1d45dbe71ffc06417c65cc24f726dff2840fd1", "rawBytes": 14824, - "gzipBytes": 3401, + "gzipBytes": 3400, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js" + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/summary-panel-metrics-CXnAEe7_.js", - "sha256": "c73f5de8717a8a7d5e7e0d0861fb9d007876b50c4c62f97b3c7f1739cd5bb38f", + "path": "houseplan-assets/summary-panel-metrics-O-xxtEs5.js", + "sha256": "e6eb617c543828e8d13193c442489da5b335be1706ac4285bf8dd6ac6861c300", "rawBytes": 2610, - "gzipBytes": 1304, + "gzipBytes": 1306, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js", - "sha256": "8609218f07a5ec5399a2ba61707a2854dfaa65e80b11dc628ddb3ece70d77f72", + "path": "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js", + "sha256": "d436e392b8472c75e3fce9f4f61bc38d8261b34c740cf796eab2f6916d191da1", "rawBytes": 73366, - "gzipBytes": 20089, + "gzipBytes": 20088, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [ - "houseplan-assets/summary-panel-editor-BAGJ8QwD.js", - "houseplan-assets/summary-panel-metrics-CXnAEe7_.js" + "houseplan-assets/summary-panel-editor-BDoONUEa.js", + "houseplan-assets/summary-panel-metrics-O-xxtEs5.js" ] }, { - "path": "houseplan-assets/zigbee-topology-DlU7AXvw.js", - "sha256": "f7f21945cb650b57fa6469a7205aa687415b208f9649e2e8bae9dd27aa6cf4e6", + "path": "houseplan-assets/zigbee-topology-Ba2URGlk.js", + "sha256": "c22937699ac98c72b3fa9e8d94555cbaf108fcb6354ba1660c71d06504e0b0d0", "rawBytes": 18961, - "gzipBytes": 7425, + "gzipBytes": 7426, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js", - "sha256": "7ae2a9b1aac6ea4ee128341cce087684b546efd2788b97fa6941138ddb702f9f", + "path": "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js", + "sha256": "9495447f3dfda1bbc1a4612742a0a42aeadca02949f9e5ff87e8d5b8ae18e146", "rawBytes": 3941, - "gzipBytes": 1760, + "gzipBytes": 1763, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js" + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js" ], "dynamicImports": [] }, { "path": "houseplan-card.js", - "sha256": "642174a115a5be423b55f552e351f4445e58f744c22c4eb1378fc376ef16d65b", + "sha256": "f31ba79b59bd0c95d9696f77702c5cff2d0900b1962547c42c7e7f7f807b0e10", "rawBytes": 1205, - "gzipBytes": 803, + "gzipBytes": 805, "isEntry": true, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { "path": "houseplan-panel.js", - "sha256": "8383bd59c693f7f9cc4b2aee4886b6a9fb90a715d91630e6473ce3aeae09216b", + "sha256": "174775f68968418e501fdbe42a83541d6003dbb0e58aa223d7f419936e88c8cf", "rawBytes": 6165, - "gzipBytes": 2325, + "gzipBytes": 2327, "isEntry": true, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] } diff --git a/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-Caayxvt2.js b/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-CXmKHH6_.js similarity index 99% rename from custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-Caayxvt2.js rename to custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-CXmKHH6_.js index d7309ffa..da8a357c 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-Caayxvt2.js +++ b/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-CXmKHH6_.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{D as e,c as t,A as i,p as o,q as n,dD as r}from"./houseplan-card-BCGpvbDT.js";function s(e){const t=e.visualViewport;return t&&Number.isFinite(t.width)&&Number.isFinite(t.height)?{left:Number(t.offsetLeft)||0,top:Number(t.offsetTop)||0,width:Math.max(0,Number(t.width)||0),height:Math.max(0,Number(t.height)||0)}:{left:0,top:0,width:e.innerWidth,height:e.innerHeight}}function a(e,t,i,o=7,n=8){const r=i.left+n,s=i.top+n,a=Math.max(r,i.left+i.width-n),l=Math.max(s,i.top+i.height-n),h=Math.max(0,a-r),c=Math.max(0,l-s),d=Math.min(Math.max(0,t.width),h),u=Math.min(Math.max(0,t.height),c);let p=e.left;p+d>a&&(p=e.right-d),p=Math.min(Math.max(r,p),Math.max(r,a-d));const g=e.bottom+o,_=e.top-o-u;let m="bottom",f=g;return g+u>l&&_>=s?(m="top",f=Math.min(Math.max(s,_),Math.max(s,l-u))):f=Math.min(Math.max(s,g),Math.max(s,l-u)),{left:Math.round(p),top:Math.round(f),side:m,maxWidth:Math.round(h),maxHeight:Math.round(c)}}class l{constructor(e,t,i){this.owner=e,this.name=t,this.keydown=i,this.host=null,this.root=null}window(){return this.owner.ownerDocument.defaultView}dialog(){return this.owner.closest("hp-dialog")}usesPopover(e=!1){const t=this.window();return!e&&!!t&&function(e){const t=e.HTMLElement?.prototype;return"function"==typeof t?.showPopover&&"function"==typeof t?.hidePopover}(t)}get hasFallback(){return!!this.host}containsPath(e){return e.includes(this.owner)||!!this.host&&e.includes(this.host)}ownsActiveElement(){let e=this.owner.ownerDocument.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return!(!e||e!==this.owner&&!this.owner.shadowRoot?.contains(e)&&!this.root?.contains(e))}renderFallback(i,o){const n=this.ensureFallback();return n?(e(t`${i}`,n),n):null}surface(e,t){return t?this.owner.shadowRoot?.querySelector(e)||null:this.root?.querySelector(e)||null}destroy(){this.root&&e(i,this.root),this.host?.remove(),this.host=null,this.root=null}ensureFallback(){if(this.root?.isConnected)return this.root;const e=this.dialog()?.overlayPortal()||this.owner.ownerDocument.body;if(!e)return null;const t=this.owner.ownerDocument.createElement("div");return t.dataset.hpOverlay=this.name,t.style.display="contents",this.keydown&&t.addEventListener("keydown",this.keydown,!0),e.append(t),this.host=t,this.root=t.attachShadow({mode:"open"}),this.root}}let h=0;class c extends n{constructor(){super(...arguments),this.text="",this.ariaLabel="",this.pointerHover=!1,this._open=!1,this._openTimer=0,this._closeTimer=0,this._positionRaf=0,this._forceFallback=!1,this._hoverOwned=!1,this._overlayDispose=null,this._scrollDialog=null,this._descriptionId="hp-help-description-"+ ++h,this._surfacePointerEnter=()=>{const e=this._window();this._closeTimer&&e?.clearTimeout(this._closeTimer),this._closeTimer=0},this._surfacePointerLeave=()=>{this._scheduleClose()},this._outsidePointerDown=e=>{if(!this._open)return;const t=e.composedPath();this._floating.containsPath(t)||this._closeHelp(!1,"outside")},this._dialogScroll=e=>{const t=this._floating.containsPath(e.composedPath()),i=e.target,o=this._dialog(),n=i instanceof Node&&(i===o||i instanceof Element&&i.contains(this));var r;this._open&&(r=n,!t&&r)&&this._closeHelp(!1,"scroll")},this._keyDown=e=>{if(!this._open||e.defaultPrevented)return;if("Escape"===e.key)return e.preventDefault(),e.stopImmediatePropagation(),void this._closeHelp(this._floating.ownsActiveElement(),"escape");const t=this.renderRoot.querySelector(".trigger");if(!t||!e.composedPath().includes(t))return;const i=this._surface();if(!i||i.scrollHeight<=i.clientHeight)return;const o=Math.max(40,.8*i.clientHeight),n={ArrowDown:40,ArrowUp:-40,PageDown:o,PageUp:-o};if("Home"===e.key)i.scrollTop=0;else if("End"===e.key)i.scrollTop=i.scrollHeight;else{if(!(e.key in n))return;i.scrollBy({top:n[e.key],behavior:"auto"})}e.preventDefault(),e.stopImmediatePropagation()},this._floating=new l(this,"help",this._keyDown),this._queuePosition=()=>{if(!this._open||this._positionRaf)return;const e=this._window();e&&(this._positionRaf=e.requestAnimationFrame(()=>{this._positionRaf=0,this._position()||this._closeHelp()}))}}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this._keyDown,!0)}willUpdate(){this.toggleAttribute("data-has-content",this._hasContent())}disconnectedCallback(){const e=this.ownerDocument.defaultView;this._unsubscribeOpenListeners(),this.removeEventListener("keydown",this._keyDown,!0),this._clearTimers(),this._positionRaf&&e?.cancelAnimationFrame(this._positionRaf),this._positionRaf=0,this._closeHelp(!1,"disconnect"),super.disconnectedCallback()}updated(e){if(e.has("pointerHover")&&!this.pointerHover){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._openTimer=0,this._hoverOwned&&this._closeHelp(!1,"outside")}this._hasContent()||!this._open?this._open&&e.has("text")&&(this._usesPopover()||this._renderFallback(),this._queuePosition()):this._closeHelp()}_window(){return this._floating.window()}_dialog(){return this._floating.dialog()}_usesPopover(){return this._floating.usesPopover(this._forceFallback)}_hasContent(){return e=this.text,t=this.ariaLabel,"string"==typeof e&&e.trim().length>0&&"string"==typeof t&&t.trim().length>0;var e,t}_clearTimers(){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._closeTimer&&e?.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=0}_scheduleOpen(){const e=this._window();this.pointerHover&&e&&!this._open&&!this._openTimer&&(this._closeTimer&&e.clearTimeout(this._closeTimer),this._closeTimer=0,this._openTimer=e.setTimeout(()=>{this._openTimer=0,this.isConnected&&(this._hoverOwned=!0,this._openHelp())},300))}_scheduleClose(){const e=this._window(),t=this.renderRoot.querySelector(".trigger");e&&!t?.matches(":focus-visible")&&(this._openTimer&&e.clearTimeout(this._openTimer),this._closeTimer&&e.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=e.setTimeout(()=>{this._closeTimer=0,this.isConnected&&this._closeHelp()},150))}_triggerPointerEnter(e){this.pointerHover&&"mouse"===e.pointerType&&this._scheduleOpen()}_triggerPointerLeave(e){"mouse"===e.pointerType&&this._scheduleClose()}_triggerFocus(){queueMicrotask(()=>{const e=this.renderRoot.querySelector(".trigger");e?.matches(":focus-visible")&&(this._hoverOwned=!1,this._openHelp())})}_triggerBlur(){this._scheduleClose()}_triggerClick(){this._open?this._closeHelp():(this._hoverOwned=!1,this._openHelp())}_subscribeOpenListeners(){this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("keydown",this._keyDown,!0);const e=this._window();e?.addEventListener("resize",this._queuePosition),e?.addEventListener("orientationchange",this._queuePosition),e?.visualViewport?.addEventListener("resize",this._queuePosition),e?.visualViewport?.addEventListener("scroll",this._queuePosition),this._scrollDialog=this._dialog(),this._scrollDialog?.addEventListener("scroll",this._dialogScroll,!0)}_unsubscribeOpenListeners(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("keydown",this._keyDown,!0);const e=this._window();e?.removeEventListener("resize",this._queuePosition),e?.removeEventListener("orientationchange",this._queuePosition),e?.visualViewport?.removeEventListener("resize",this._queuePosition),e?.visualViewport?.removeEventListener("scroll",this._queuePosition),this._scrollDialog?.removeEventListener("scroll",this._dialogScroll,!0),this._scrollDialog=null}async _openHelp(){!this._open&&this._hasContent()&&(this._clearTimers(),this._forceFallback=!1,this._open=!0,this._subscribeOpenListeners(),await this.updateComplete,this._open&&(this._usesPopover()||this._renderFallback(),this._position()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:e=>this._closeHelp("escape"===e&&this._floating.ownsActiveElement(),e)})||null:this._closeHelp()))}_closeHelp(e=!1,t="exclusive"){if(!this._open&&!this._floating.hasFallback)return;this._clearTimers();const i=this._overlayDispose;this._overlayDispose=null,i?.();const o=this.renderRoot.querySelector(".tooltip");if(o?.hidePopover)try{o.matches(":popover-open")&&o.hidePopover()}catch{}this._open=!1,this._hoverOwned=!1,this._unsubscribeOpenListeners(),this._floating.destroy(),e&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_tooltipTemplate(e){return t`
a&&(p=e.right-d),p=Math.min(Math.max(r,p),Math.max(r,a-d));const g=e.bottom+o,_=e.top-o-u;let m="bottom",f=g;return g+u>l&&_>=s?(m="top",f=Math.min(Math.max(s,_),Math.max(s,l-u))):f=Math.min(Math.max(s,g),Math.max(s,l-u)),{left:Math.round(p),top:Math.round(f),side:m,maxWidth:Math.round(h),maxHeight:Math.round(c)}}class l{constructor(e,t,i){this.owner=e,this.name=t,this.keydown=i,this.host=null,this.root=null}window(){return this.owner.ownerDocument.defaultView}dialog(){return this.owner.closest("hp-dialog")}usesPopover(e=!1){const t=this.window();return!e&&!!t&&function(e){const t=e.HTMLElement?.prototype;return"function"==typeof t?.showPopover&&"function"==typeof t?.hidePopover}(t)}get hasFallback(){return!!this.host}containsPath(e){return e.includes(this.owner)||!!this.host&&e.includes(this.host)}ownsActiveElement(){let e=this.owner.ownerDocument.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return!(!e||e!==this.owner&&!this.owner.shadowRoot?.contains(e)&&!this.root?.contains(e))}renderFallback(i,o){const n=this.ensureFallback();return n?(e(t`${i}`,n),n):null}surface(e,t){return t?this.owner.shadowRoot?.querySelector(e)||null:this.root?.querySelector(e)||null}destroy(){this.root&&e(i,this.root),this.host?.remove(),this.host=null,this.root=null}ensureFallback(){if(this.root?.isConnected)return this.root;const e=this.dialog()?.overlayPortal()||this.owner.ownerDocument.body;if(!e)return null;const t=this.owner.ownerDocument.createElement("div");return t.dataset.hpOverlay=this.name,t.style.display="contents",this.keydown&&t.addEventListener("keydown",this.keydown,!0),e.append(t),this.host=t,this.root=t.attachShadow({mode:"open"}),this.root}}let h=0;class c extends n{constructor(){super(...arguments),this.text="",this.ariaLabel="",this.pointerHover=!1,this._open=!1,this._openTimer=0,this._closeTimer=0,this._positionRaf=0,this._forceFallback=!1,this._hoverOwned=!1,this._overlayDispose=null,this._scrollDialog=null,this._descriptionId="hp-help-description-"+ ++h,this._surfacePointerEnter=()=>{const e=this._window();this._closeTimer&&e?.clearTimeout(this._closeTimer),this._closeTimer=0},this._surfacePointerLeave=()=>{this._scheduleClose()},this._outsidePointerDown=e=>{if(!this._open)return;const t=e.composedPath();this._floating.containsPath(t)||this._closeHelp(!1,"outside")},this._dialogScroll=e=>{const t=this._floating.containsPath(e.composedPath()),i=e.target,o=this._dialog(),n=i instanceof Node&&(i===o||i instanceof Element&&i.contains(this));var r;this._open&&(r=n,!t&&r)&&this._closeHelp(!1,"scroll")},this._keyDown=e=>{if(!this._open||e.defaultPrevented)return;if("Escape"===e.key)return e.preventDefault(),e.stopImmediatePropagation(),void this._closeHelp(this._floating.ownsActiveElement(),"escape");const t=this.renderRoot.querySelector(".trigger");if(!t||!e.composedPath().includes(t))return;const i=this._surface();if(!i||i.scrollHeight<=i.clientHeight)return;const o=Math.max(40,.8*i.clientHeight),n={ArrowDown:40,ArrowUp:-40,PageDown:o,PageUp:-o};if("Home"===e.key)i.scrollTop=0;else if("End"===e.key)i.scrollTop=i.scrollHeight;else{if(!(e.key in n))return;i.scrollBy({top:n[e.key],behavior:"auto"})}e.preventDefault(),e.stopImmediatePropagation()},this._floating=new l(this,"help",this._keyDown),this._queuePosition=()=>{if(!this._open||this._positionRaf)return;const e=this._window();e&&(this._positionRaf=e.requestAnimationFrame(()=>{this._positionRaf=0,this._position()||this._closeHelp()}))}}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this._keyDown,!0)}willUpdate(){this.toggleAttribute("data-has-content",this._hasContent())}disconnectedCallback(){const e=this.ownerDocument.defaultView;this._unsubscribeOpenListeners(),this.removeEventListener("keydown",this._keyDown,!0),this._clearTimers(),this._positionRaf&&e?.cancelAnimationFrame(this._positionRaf),this._positionRaf=0,this._closeHelp(!1,"disconnect"),super.disconnectedCallback()}updated(e){if(e.has("pointerHover")&&!this.pointerHover){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._openTimer=0,this._hoverOwned&&this._closeHelp(!1,"outside")}this._hasContent()||!this._open?this._open&&e.has("text")&&(this._usesPopover()||this._renderFallback(),this._queuePosition()):this._closeHelp()}_window(){return this._floating.window()}_dialog(){return this._floating.dialog()}_usesPopover(){return this._floating.usesPopover(this._forceFallback)}_hasContent(){return e=this.text,t=this.ariaLabel,"string"==typeof e&&e.trim().length>0&&"string"==typeof t&&t.trim().length>0;var e,t}_clearTimers(){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._closeTimer&&e?.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=0}_scheduleOpen(){const e=this._window();this.pointerHover&&e&&!this._open&&!this._openTimer&&(this._closeTimer&&e.clearTimeout(this._closeTimer),this._closeTimer=0,this._openTimer=e.setTimeout(()=>{this._openTimer=0,this.isConnected&&(this._hoverOwned=!0,this._openHelp())},300))}_scheduleClose(){const e=this._window(),t=this.renderRoot.querySelector(".trigger");e&&!t?.matches(":focus-visible")&&(this._openTimer&&e.clearTimeout(this._openTimer),this._closeTimer&&e.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=e.setTimeout(()=>{this._closeTimer=0,this.isConnected&&this._closeHelp()},150))}_triggerPointerEnter(e){this.pointerHover&&"mouse"===e.pointerType&&this._scheduleOpen()}_triggerPointerLeave(e){"mouse"===e.pointerType&&this._scheduleClose()}_triggerFocus(){queueMicrotask(()=>{const e=this.renderRoot.querySelector(".trigger");e?.matches(":focus-visible")&&(this._hoverOwned=!1,this._openHelp())})}_triggerBlur(){this._scheduleClose()}_triggerClick(){this._open?this._closeHelp():(this._hoverOwned=!1,this._openHelp())}_subscribeOpenListeners(){this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("keydown",this._keyDown,!0);const e=this._window();e?.addEventListener("resize",this._queuePosition),e?.addEventListener("orientationchange",this._queuePosition),e?.visualViewport?.addEventListener("resize",this._queuePosition),e?.visualViewport?.addEventListener("scroll",this._queuePosition),this._scrollDialog=this._dialog(),this._scrollDialog?.addEventListener("scroll",this._dialogScroll,!0)}_unsubscribeOpenListeners(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("keydown",this._keyDown,!0);const e=this._window();e?.removeEventListener("resize",this._queuePosition),e?.removeEventListener("orientationchange",this._queuePosition),e?.visualViewport?.removeEventListener("resize",this._queuePosition),e?.visualViewport?.removeEventListener("scroll",this._queuePosition),this._scrollDialog?.removeEventListener("scroll",this._dialogScroll,!0),this._scrollDialog=null}async _openHelp(){!this._open&&this._hasContent()&&(this._clearTimers(),this._forceFallback=!1,this._open=!0,this._subscribeOpenListeners(),await this.updateComplete,this._open&&(this._usesPopover()||this._renderFallback(),this._position()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:e=>this._closeHelp("escape"===e&&this._floating.ownsActiveElement(),e)})||null:this._closeHelp()))}_closeHelp(e=!1,t="exclusive"){if(!this._open&&!this._floating.hasFallback)return;this._clearTimers();const i=this._overlayDispose;this._overlayDispose=null,i?.();const o=this.renderRoot.querySelector(".tooltip");if(o?.hidePopover)try{o.matches(":popover-open")&&o.hidePopover()}catch{}this._open=!1,this._hoverOwned=!1,this._unsubscribeOpenListeners(),this._floating.destroy(),e&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_tooltipTemplate(e){return t``}_renderFallback(){const e=c.styles.cssText;this._floating.renderFallback(this._tooltipTemplate(!1),e)}_surface(){return this._floating.surface(".tooltip",this._usesPopover())}_position(){if(!this._open)return!1;const e=this._window(),t=this.renderRoot.querySelector(".trigger");let i=this._surface();if(!e||!t?.isConnected||!i?.isConnected)return!1;const o=s(e);if(i.style.maxWidth=`${Math.max(0,Math.min(320,o.width-16))}px`,i.style.maxHeight=`${Math.max(0,o.height-16)}px`,i.style.visibility="hidden",this._usesPopover()&&i.showPopover)try{i.matches(":popover-open")||i.showPopover()}catch{if(this._forceFallback=!0,this._renderFallback(),i=this._surface(),!i?.isConnected)return!1;i.style.visibility="hidden"}const n=t.getBoundingClientRect(),r=i.getBoundingClientRect();if(!(n.width&&n.height&&r.width&&r.height))return!1;const l=a(n,r,o);return i.style.left=`${l.left}px`,i.style.top=`${l.top}px`,i.dataset.side=l.side,i.style.visibility="",!0}render(){if(!this._hasContent())return i;const e=this.ariaLabel.trim();return t` ({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`({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`h[e.name]||e.name} + .computeLabel=${e=>f[e.name]||e.name} @value-changed=${this._valueChanged} >`;return c` - ${d(f.slice(0,3))} + ${d(h.slice(0,3))} ${_?c``: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); diff --git a/dist/houseplan-assets/fr-B-ete5Dh.js b/custom_components/houseplan/frontend/houseplan-assets/fr-B8hQ5YK4.js similarity index 71% rename from dist/houseplan-assets/fr-B-ete5Dh.js rename to custom_components/houseplan/frontend/houseplan-assets/fr-B8hQ5YK4.js index 04a33a71..0cfa1990 100644 --- a/dist/houseplan-assets/fr-B-ete5Dh.js +++ b/custom_components/houseplan/frontend/houseplan-assets/fr-B8hQ5YK4.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";var e={"editor.context_actions":"Actions : {object}","editor.tool_options":"Options de l’outil : {tool}","editor.palette":"Palette : {tool}","editor.open_group":"Groupe d’outils : {group}","editor.group_active":"{group} — actif : {item}","editor.disabled_action":"{action} est indisponible : {reason}","editor.loading":"Chargement de l'éditeur…","editor.loading_aria":"L'éditeur de plan est en cours de chargement","editor.load_failed":"Impossible de charger l'éditeur.","editor.refresh_advice":"Actualisez la page et réessayez.","editor.retry_advice":"Vérifiez votre connexion et appuyez à nouveau.","version_mismatch.title":"Les versions de House Plan ne correspondent pas","version_mismatch.body":"Si Home Assistant redémarre encore, attendez la fin, puis rechargez cette page.","version_mismatch.frontend":"Carte","version_mismatch.backend":"Intégration","version_mismatch.reload":"Recharger la page","color_picker.title":"Sélecteur de couleur","color_picker.hue":"Teinte","color_picker.saturation":"Saturation","color_picker.value":"Luminosité","color_picker.hex":"Couleur hexadécimale","color_picker.invalid_hex":"Saisissez une couleur hexadécimale à 3 ou 6 chiffres","color_picker.confirm":"OK","btn.properties":"Propriétés","btn.keep_as_walls":"Conserver comme murs","btn.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","btn.delete_room_with_walls":"Supprimer la pièce et les murs","title.markup_select":"Sélectionner et modifier les murs et les colonnes","title.markup_column":"Colonne : cliquez sur un point de la grille pour placer une colonne carrée","markup.partition":"Cloison","markup.column":"Colonne","markup.hint_column":"cliquez sur un point de la grille pour placer une colonne carrée","history.wall_segment":"Ajouter un segment de mur","history.column_add":"Ajouter une colonne","history.physical_edit":"Modifier l’objet physique","history.physical_delete":"Supprimer l’objet physique","history.physical_move":"Déplacer l’objet physique","history.wall_face_batch":"Créer des pièces à partir des murs","toast.column_duplicate":"Une colonne avec le même centre et la même dimension extérieure existe déjà","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.shape":"Forme","physical.square":"Carré","physical.circle":"Cercle","physical.diameter":"Diamètre","physical.side":"Côté","physical.rotation":"Angle de rotation","physical.length":"Longueur","physical.allowed_range":"Autorisé : {min}–{max} {unit}","physical.column_size_title":"Côté extérieur de la colonne carrée placée par le clic (1–150 cm).","card.title":"Plan de la maison","count.devices":"{n} app.","empty.no_spaces":"Aucun espace pour le moment.","nav.spaces":"Espaces House Plan","empty.add_first":"Ajoutez le premier espace et importez un plan.","empty.read_only":"Aucun espace n’est configuré. Demandez à un administrateur d’en ajouter un.","empty.install":"Installez l’intégration House Plan et ajoutez-la dans « Appareils et services ».","btn.add_space":"Ajouter un espace","btn.cancel":"Annuler","btn.save":"Enregistrer","btn.close":"Fermer","btn.delete":"Supprimer","btn.copy":"Copier","btn.edit":"Modifier","btn.open_in_ha":"Ouvrir dans HA","btn.reset":"Réinitialiser","btn.attach":"Joindre…","btn.upload":"Importer…","btn.replace":"Remplacer…","title.zoom_in":"Zoomer","title.zoom_out":"Dézoomer","title.zoom_fit":"Tout ajuster","title.configure_space":"Configurer l’espace","title.add_space":"Ajouter un espace","title.markup_add":"Murs : tracez une chaîne continue ; chaque segment accepté est enregistré séparément. Maj verrouille à 45°","title.markup_merge":"Fusionner : cliquez sur une pièce, puis sur la pièce voisine avec laquelle elle partage un mur","title.markup_split":"Diviser une pièce : cliquez sur la pièce, puis sur deux points de ses murs","title.markup_delroom":"Supprimer une pièce : cliquez à l’intérieur de la pièce puis confirmez","title.need_plan":"Importer une image de plan","markup.add":"Murs","markup.merge":"Fusionner","markup.split":"Diviser","markup.resize":"Redimensionner","title.markup_resize":"Redimensionner les pièces : faites glisser une poignée disponible sur un mur horizontal ou vertical","markup.hint_resize":"faites glisser une poignée de mur disponible · le mur s’arrête à la première position non sûre · Échap annule · Ctrl+Z — annuler","resize.disabled.diagonal":"Ce mur est incliné ; le redimensionnement ne prend en charge que les murs horizontaux et verticaux","resize.disabled.side-angle":"Un mur adjacent est incliné ; le redimensionnement exige que les deux murs adjacents rencontrent ce mur à angle droit","resize.disabled.duplicate-physical-wall":"Une cloison distincte ou une colonne chevauche ce mur ; supprimez-la ou déplacez-la avant de redimensionner","resize.disabled.partial-shared":"Une pièce voisine n’utilise qu’une partie de ce mur ; il ne peut donc pas être déplacé en toute sécurité comme un mur partagé unique","resize.disabled.unequal-shared":"La pièce voisine utilise des extrémités ou une longueur de mur différentes ; les murs ne peuvent donc pas être déplacés ensemble en toute sécurité","resize.disabled.multiple-rooms":"Déplacer ce mur affecterait plus de deux pièces","resize.disabled.thickness-conflict":"L’épaisseur du mur ne peut pas être conservée en toute sécurité","resize.disabled.opening-conflict":"Une ouverture sur ce mur ne peut pas être déplacée en toute sécurité","resize.disabled.invalid-geometry":"Ce mur ne peut pas être redimensionné sans modifier la structure du plan","resize.limit_stopped":"Mur arrêté : l'étape suivante enfreindrait une limite de jonction","resize.commit_failed":"Le redimensionnement a été annulé car le plan final n’a pas passé le contrôle de géométrie","resize.preview_failed":"Le redimensionnement s’est arrêté à la dernière position sûre car la géométrie du plan ne pouvait pas être préservée","markup.opening":"Ouverture","markup.delete_room":"Supprimer la pièce","history.undo":"Annuler","history.redo":"Rétablir","history.undo_named":"Annuler : {name} (Ctrl+Z)","history.redo_named":"Rétablir : {name} (Ctrl+Maj+Z / Ctrl+Y)","history.undo_empty":"Rien à annuler","history.redo_empty":"Rien à rétablir","history.undone":"Annulé : {name}","history.redone":"Rétabli : {name}","history.add_room":"Créer une pièce","history.split_room":"Diviser la pièce","history.merge_rooms":"Fusionner les pièces","history.resize_room":"Redimensionner la pièce","history.wall_thickness":"Modifier l’épaisseur du mur","history.add_opening":"Ajouter une ouverture de porte ou de fenêtre","history.edit_opening":"Modifier l’ouverture","history.move_opening":"Déplacer l’ouverture","history.delete_opening":"Supprimer l’ouverture","history.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","history.delete_room_with_walls":"Supprimer la pièce et les murs","history.decor_add":"Ajouter un objet décoratif","history.decor_edit":"Modifier l’objet décoratif","history.decor_move":"Déplacer l’objet décoratif","history.decor_transform":"Transformer l’objet décoratif","history.decor_delete":"Supprimer l’objet décoratif","history.backdrop_transform":"Transformer l’arrière-plan du plan","history.device_move":"Déplacer {name}","history.device_stale":"L’historique des positions n’est plus applicable et a été effacé","opening.new":"Nouvelle ouverture","opening.edit":"Ouverture","opening.door":"Porte","opening.window":"Fenêtre","opening.gate":"Portail","opening.passage":"Passage ouvert","opening.passage_binding_warning":"L’enregistrement supprimera le capteur d’ouverture/fermeture et la serrure.","opening.invalid_passage_fields":"Le passage ouvert du plan « {room} » possède des paramètres non pris en charge : {fields}.","opening.type_label":"Type","opening.length_label":"Longueur, cm","opening.contact_label":"Capteur d’ouverture/fermeture","opening.lock_label":"Serrure","opening.none":"— aucun —","opening.search_ph":"Rechercher : nom ou ID d’entité…","opening.invert":"Inverser ouvert/fermé","opening.flip_h":"Charnière sur l’autre montant","opening.flip_v":"Ouverture de l’autre côté","opening.open":"Ouvert","opening.closed":"Fermé","opening.locked":"Verrouillé","opening.unlocked":"Déverrouillé","opening.state_unknown":"indisponible","opening.no_entities":"Aucun capteur associé — symbole statique sur le plan.","toast.opening_no_wall":"Cliquez près d’un mur de pièce ou d’un mur indépendant","opening.host_partition":"Mur indépendant","opening.partition_orphan":"Le mur indépendant de cette ouverture n’existe plus","opening.partition_jamb_margin":"Laissez au moins {distance} entre l’ouverture et l’extrémité du mur","opening.rebind_partition":"Associer à un autre mur indépendant","confirm.delete_partition_openings_title":"Supprimer le mur et les ouvertures ?","confirm.delete_partition_openings_body":"Ce mur contient {count} ouverture(s). Elles seront supprimées avec lui.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.hint_points":"points : {n} · Maj — pas de 45° · Échap — terminer la chaîne · Ctrl+Z — annuler un point · fermer une zone propose de créer une pièce","markup.hint_start":"cliquez sur un point de la grille pour commencer une chaîne de murs","tip.lqi":"signal Zigbee moyen :","tip.area":"surface : {value}","info.device_header":"Appareil sur le plan","info.model":"Modèle","info.state":"État","info.link":"Lien","info.manuals":"Manuels","info.none":"Aucune information supplémentaire","marker.new_device":"Nouvel appareil","marker.name_label":"Nom (affiché sur le plan)","marker.name_ph":"Nom","marker.binding_label":"Associer à un appareil HA","marker.binding_disabled":"désactivé dans Home Assistant","marker.virtual_option":"Appareil virtuel (sans association)","marker.search_ph":"Rechercher un appareil / groupe…","marker.nothing_found":"aucun résultat","marker.room_label":"Pièce","marker.room_override":" (placement forcé)","marker.room_choose":"— sélectionner une pièce —","marker.room_auto":"— selon la zone de l’appareil (auto) —","marker.icon_label":"Icône","marker.icon_ph":"mdi:… (vide = auto)","marker.display_label":"Affichage","display.badge":"Icône + état","display.icon_ripple":"Icône + état et activité","display.static_icon":"Icône toujours statique","marker.display_hint_badge":"L’icône et le fond dynamique affichent l’état de l’appareil sans la pulsation d’activité habituelle. Les alarmes rouges restent visibles.","marker.display_hint_icon_ripple":"L’icône, le fond dynamique et la pulsation affichent une brève animation pour les événements et une animation continue pour le fonctionnement, le mouvement ou la présence. Les alarmes rouges restent prioritaires.","marker.display_hint_value":"Une valeur Home Assistant sélectionnée ou résolue automatiquement remplace l’icône tandis que le fond continue d’indiquer l’état. Les alarmes rouges restent visibles.","marker.display_hint_static_icon":"Le contour adapté au thème et l’icône restent toujours identiques. L’état, l’activité, l’indisponibilité et les alarmes ne modifient pas l’apparence.","marker.static_alarm_warning":"Cet appareil peut signaler des alarmes. L’affichage statique masque l’indication visuelle d’alarme du marqueur.","marker.preview.title":"Aperçu de l’affichage","marker.preview.actual":"Actuel","marker.preview.example":"Exemple","marker.preview.integration":"Fourni par","marker.preview.source":"Source d’affichage","marker.preview.current_state":"État actuel","marker.preview.result":"Sur le plan","marker.preview.details":"Détails de la source","marker.preview.select_source":"Choisissez un appareil ou une entité Home Assistant pour voir son affichage réel.","marker.preview.unknown_provider":"Intégration inconnue","marker.preview.virtual_provider":"House Plan · appareil virtuel","marker.preview.no_source":"Aucune source active","marker.preview.no_state":"Aucun état actuel","marker.preview.mixed_states":"Plusieurs états différents","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} de plus","marker.preview.scaled":"L’aperçu est redimensionné à {n}% pour tenir dans la zone. La taille enregistrée reste inchangée.","marker.preview.demo_short":"Afficher une activité brève","marker.preview.demo_continuous":"Afficher une activité continue","marker.preview.stop_continuous":"Arrêter l’activité continue","marker.preview.demo_short_notice":"Exemple d’activité brève ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_continuous_notice":"Exemple d’activité continue ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_already_visible":"L’état actuel affiche déjà un véritable effet d’activité ou d’alarme.","marker.preview.reduced_motion":"La réduction des animations est activée sur le système ; l’activité normale est donc affichée sous forme de point.","marker.preview.reason.neutral":"Fond sombre neutre","marker.preview.reason.working":"Fond jaune : l’appareil fonctionne actuellement","marker.preview.reason.working_activity":"Fond jaune et effet d’activité : l’appareil fonctionne actuellement","marker.preview.reason.open":"Fond orange : physiquement ouvert ou déverrouillé","marker.preview.reason.cover_icon_state":"Fond neutre ; l’entité de volet contrôle l’état et l’icône affichés","marker.preview.reason.presence":"Effet d’activité tant qu’une présence est détectée","marker.preview.reason.event":"Effet d’activité bref après un événement détecté","marker.preview.reason.transition":"Effet d’activité pendant que l’appareil se déplace ou change d’état","marker.preview.reason.media_neutral":"Les appareils multimédias restent sur un fond sombre neutre tant qu’ils sont disponibles","marker.preview.reason.unavailable":"Fond neutre atténué : indisponible ou éteint","marker.preview.reason.alarm":"Fond d’alarme rouge ; l’indication d’alarme est toujours affichée","marker.preview.reason.live_states_disabled":"Le style selon les états en direct est désactivé pour cette carte","marker.preview.reason.value_no_state":"Aucune valeur d’état exploitable ; l’icône est affichée à la place","marker.preview.reason.value_ambiguous_sources":"Plusieurs sources de valeur possibles ; l’icône est affichée à la place","marker.preview.reason.value_non_scalar":"La source n’a pas renvoyé de valeur simple ; l’icône est affichée à la place","marker.preview.reason.value_virtual":"Un appareil virtuel n’a aucune valeur Home Assistant ; l’icône est affichée à la place","marker.preview.reason.vacuum_live_plan_only":"La position et la trajectoire en direct de l’aspirateur ne sont disponibles que sur le plan complet","marker.preview.reason.hidden_design_preview":"L’appareil est masqué sur le plan ; cet aperçu de conception reste visible","marker.preview.reason.composite_power_source":"L’état provient de l’entité d’alimentation de l’appareil ; les interrupteurs auxiliaires sont ignorés","marker.preview.reason.activity_display_disabled":"Le mode d’affichage sélectionné n’affiche pas les effets d’activité habituels","marker.preview.reason.ha_disabled":"L’association Home Assistant est désactivée et sera masquée sur le plan","marker.preview.reason.orphaned":"L’association Home Assistant enregistrée est introuvable","marker.preview.reason.static_icon":"Mode statique : l’état de l’appareil ne modifie pas l’icône","marker.activity_color":"Couleur de la pulsation d’activité","marker.ripple_size":"Taille de la pulsation d’activité","marker.activity_alarm_note":"La couleur et la taille n’affectent que l’activité normale et ne modifient pas les alarmes rouges.","marker.pulse_a11y_alarm":"Alarme","marker.pulse_a11y_event":"Événement récent","marker.pulse_a11y_presence":"Présence détectée","marker.pulse_a11y_transition":"Changement d’état","marker.pulse_a11y_running":"En fonctionnement","marker.state_a11y_neutral":"État par défaut","marker.state_a11y_working":"En fonctionnement","marker.state_a11y_open":"Ouvert","marker.state_a11y_locked":"Verrouillé","marker.state_a11y_unlocked":"Déverrouillé","marker.state_a11y_alarm":"Alarme","marker.state_a11y_unavailable":"Indisponible","marker.lqi_a11y_low":"LQI {value}, signal faible","marker.lqi_a11y_mid":"LQI {value}, signal moyen","marker.lqi_a11y_high":"LQI {value}, signal fort","marker.size_label":"Taille / rotation de l’icône","marker.angle_label":"Rotation","marker.model_label":"Modèle","marker.model_ph":"ex. Aqara T&H","marker.link_label":"Lien","marker.desc_label":"Description","marker.desc_ph":"Notes, caractéristiques…","marker.manuals_label":"Manuels (PDF, etc.)","marker.sub_device":"appareil","marker.sub_z2m_group":" · groupe Z2M","marker.sub_group":"groupe","marker.sub_helper":"assistant","space.new":"Nouvel espace","space.copy_title":"Copier l’espace","space.copy_name":"Nom du nouvel espace","space.copy_fallback":"Espace","space.copy_create":"Créer la copie","space.copy_optimize_title":"Optimiser avant de copier ?","space.copy_optimize_body":"Avant de créer « {name} », House Plan doit optimiser tout le plan, y compris les autres espaces. Continuer ?","space.copy_optimize_confirm":"Optimiser et copier","space.copy_error_changed":"Le plan a changé pendant la confirmation. Vérifiez-le et réessayez.","space.copy_error_source_missing":"L’espace source n’existe plus. Rouvrez ses réglages et réessayez.","space.copy_error_source_invalid":"House Plan n’a pas pu valider tous les murs de cet espace. Corrigez l’espace source.","space.copy_error_spaces_limit":"House Plan contient déjà le nombre maximal d’espaces.","space.copy_error_partitions_limit":"Cet espace contient trop de murs pour être copié.","space.copy_error_openings_limit":"Cet espace contient trop d’ouvertures pour être copié.","space.copy_error_decor_limit":"Cet espace contient trop d’objets d’arrière-plan pour être copié.","space.copy_error_columns_limit":"Cet espace contient trop de colonnes pour être copié.","space.copy_error_opening_host":"Une ouverture n’est plus rattachée à un mur. Corrigez-la ou supprimez-la avant la copie.","space.copy_error_geometry":"La copie créerait une géométrie de murs non sûre. Corrigez l’espace source.","space.copy_error_optimize_geometry":"La copie est arrêtée car l’optimisation de tout le plan n’est pas sûre pour un espace.","space.header":"Espace","space.title_label":"Titre","space.title_ph":"ex. Garage","space.plan_label":"Plan (arrière-plan)","space.no_plan":"aucune image de plan","space.plan_alt":"plan","room.new":"Nouvelle pièce","room.name_label":"Nom affiché","room.name_ph":"ex. Terrasse","room.area_label":"Zone Home Assistant (non attribuée)","room.no_area_option":"— aucune zone —","room.default_name":"Pièce","device.unnamed":"sans nom","device.light_group":"groupe de lumières","device.fallback":"appareil","device.virtual":"appareil virtuel","confirm.delete_room_title":"Supprimer la pièce « {name} » ?","confirm.delete_room_body":"Choisissez si les murs physiques propres à la pièce doivent être conservés. Les murs partagés avec une autre pièce sont toujours conservés.","confirm.remove_marker_title":"Supprimer l’appareil du plan ?","confirm.remove_marker_body":"L’appareil disparaîtra complètement et ne contribuera plus aux données du plan. Vous pourrez l’ajouter de nouveau plus tard.","confirm.erase_decor":"Effacer l’objet {kind} ? Vous pouvez annuler cette action depuis l’historique de l’éditeur.","confirm.delete_space_title":"Supprimer l’espace ?","confirm.delete_space_body":"L’espace, toutes ses pièces et tout le tracé du plan seront supprimés.","confirm.delete_space_vac_routes":"Les affectations de cartes de robots seront aussi supprimées : {count}.","space.delete_blocked":"Cet espace est encore utilisé par {n} appareil(s). Déplacez-les vers un autre espace ou supprimez-les d’abord.","toast.pos_save_failed":"Échec de l’enregistrement de la position : {err}","toast.no_entity":"L’appareil n’a aucune entité adaptée","toast.ha_disabled_action":"Un objet Home Assistant désactivé ne peut pas être utilisé sur le plan.","toast.ha_disabled_show_device":"Un appareil désactivé dans Home Assistant ne peut pas être affiché sur le plan. Activez-le d’abord dans Home Assistant.","toast.ha_disabled_show_entity":"Une entité désactivée dans Home Assistant ne peut pas être affichée sur le plan. Activez-la d’abord dans Home Assistant.","toast.ha_disabled_add":"Un objet Home Assistant désactivé ne peut pas être ajouté au plan. Activez-le d’abord dans Home Assistant.","toast.ha_binding_unverified":"L’état de l’objet n’a pas pu être vérifié via le registre Home Assistant. L’affichage et les actions sont temporairement indisponibles.","toast.markup_needs_server":"Le tracé est disponible une fois la configuration déplacée sur le serveur","toast.space_order_changed":"L’ordre a changé. Si une carte fixe son étage par numéro, vérifiez ces tableaux de bord.","toast.conflict":"La configuration a été modifiée dans une autre fenêtre — données actualisées, répétez votre dernière action","toast.cfg_save_failed":"Échec de l’enregistrement de la configuration : {err}","toast.room_overlap":"Le contour chevauche la pièce « {name} » — les pièces ne doivent pas se chevaucher","toast.contour_cannot_close":"Le contour ne peut pas être fermé car il est dégénéré ou s’auto-intersecte","toast.merge_not_adjacent":"Seules les pièces partageant un mur peuvent être fusionnées","toast.rooms_merged":"Pièces fusionnées dans « {name} »","toast.split_pick_wall":"Commencez la découpe sur le mur de la pièce","toast.split_bad_cut":"La découpe doit aller d’un mur à l’autre à l’intérieur de la pièce, sans croiser de mur ni se croiser elle-même","merge.header":"Fusionner les pièces","merge.hint":"La pièce fusionnée conserve un nom et une zone. L’autre zone est libérée — ses appareils quittent le plan jusqu’à ce qu’une autre pièce la récupère.","merge.keep":"Conserver","merge.no_area":"aucune zone","toast.room_saved":"Pièce enregistrée ({n}). Appareils ajoutés : {added}. Tracez la suivante ou quittez le mode tracé.","toast.room_saved_no_area":"Pièce enregistrée ({n}, sans zone). Tracez la suivante ou quittez le mode tracé.","toast.marker_needs_server":"La modification des appareils est disponible une fois la configuration déplacée sur le serveur","toast.virtual_name_required":"Saisissez un nom pour l’appareil virtuel","toast.marker_saved":"Appareil enregistré","toast.marker_removed":"Appareil supprimé du plan","toast.integration_missing":"L’intégration House Plan n’est pas installée — gestion indisponible","toast.plan_formats":"Formats pris en charge : SVG, PNG, JPG, WebP","toast.plan_required":"Importez un plan — il est obligatoire","toast.space_added_onboard":"Espace ajouté. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","toast.space_added":"Espace ajouté","toast.space_copied":"Espace « {name} » créé","toast.space_saved":"Espace enregistré","toast.space_deleted":"Espace supprimé","toast.delete_failed":"Échec de la suppression : {err}","toast.error":"Erreur : {err}","toast.toggle_target_unavailable":"La cible « {name} » est indisponible — aucune action n’a été effectuée","toast.toggle_targets_unavailable":"Cibles indisponibles : {names}. Aucune action n’a été effectuée","toast.file_failed":"Le fichier « {name} » n’a pas été importé : {err}","toast.files_attached":"Fichiers joints : {n}","err.unknown":"erreur inconnue","err.code":"code {code}","err.too_large":"fichier supérieur à {mb} Mo","err.bad_ext":"type non pris en charge (PDF/image attendu)","err.unauthorized":"droits administrateur requis","editor.title":"Titre","editor.default_floor":"Espace initial","editor.default_floor_missing":"L’espace initial « {id} » n’existe plus. Choisissez un autre espace.","editor.floor":"Espace fixe","editor.floor_none":"— non fixé —","editor.floor_index":"Index YAML {index} (conservé)","fixed_floor.loading":"Chargement de l’espace fixe…","fixed_floor.invalid_title":"L’espace fixe est indisponible","fixed_floor.invalid_body":"Vérifiez floor dans la configuration de la carte. Valeur configurée : {value}","editor.icon_size":"Taille des icônes, % de la largeur du plan","editor.show_temperature":"Afficher la température","editor.live_states":"États en direct (on/off, ouvert…)","editor.light_pools":"Halos lumineux et ombres des murs","editor.show_signal":"Afficher le signal Zigbee (LQI)","editor.language":"Langue de l’interface","editor.lang_auto":"Auto (profil HA)","title.icon_rules":"Règles d’icônes : quelle icône MDI attribuer aux appareils selon leur nom","rules.title":"Règles d’icônes","rules.hint":"Les règles sont testées de haut en bas sur « nom de l’appareil + modèle » (expression régulière insensible à la casse) ; la première correspondance gagne. Si rien ne correspond, la classe d’appareil de l’entité est utilisée, puis l’icône générique.","rules.pattern_ph":"regex, ex. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Ajouter une règle","rules.reset":"Réinitialiser par défaut","rules.test_ph":"Tester un nom d’appareil…","rules.invalid":"expression régulière invalide","rules.saved":"Règles d’icônes enregistrées","btn.up":"Monter","btn.down":"Descendre","tap.info":"Fiche de l’appareil","tap.more_info":"Boîte de dialogue Plus d’infos de HA","tap.toggle":"Basculer l’état","marker.tap_label":"Action au toucher pour cet appareil","tap.toggle_note":"L’état déterminé est affiché ci-dessous. Les appareils sécurisés ne sont jamais basculés depuis le plan.","import.title":"Créer des espaces à partir des étages HA","import.hint":"Votre Home Assistant connaît déjà ces étages. Sélectionnez ceux à transformer en espaces du plan — vous importerez ensuite une image de plan pour chacun. Les pièces sont ensuite tracées manuellement sur le plan.","import.start":"Créer {n} espace(s)","import.manual":"Commencer de zéro","import.progress":"Étage {i} sur {n}","import.done":"Espaces créés. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","btn.skip":"Passer","space.scale_label":"Échelle (taille d’une cellule de grille)","space.cell_cm.help":"Relie la grille aux dimensions réelles : les longueurs, les surfaces, l’épaisseur des murs, la taille des ouvertures et le rayon du halo en dépendent. Une modification ultérieure change les dimensions calculées de tout l’espace sans déplacer ses points sur le plan.","space.cell_cm.help.aria":"Aide : échelle de l’espace","space.scale_unit":"cm par cellule","space.scale_unit_imperial":"po par cellule","space.display_section":"Affichage","space.show_borders":"Toujours afficher les contours des pièces","space.zero_wall_style":"Murs d’épaisseur nulle","space.zero_wall_style.help":"Les murs d’épaisseur nulle en pointillés laissent passer le halo et les rayons du soleil, tandis que les murs pleins les bloquent comme une barrière sans surface. Ce choix s’applique à tous ces murs de l’espace, même si leur ligne est masquée en mode Vue.","space.zero_wall_style.help.aria":"Aide : style des murs d’épaisseur nulle","space.zero_wall_dashed":"Pointillés","space.zero_wall_solid":"Plein","space.show_names":"Afficher les noms des pièces (faire glisser pour déplacer)","space.room_color":"Couleur du contour et du nom","space.opacity":"Opacité","space.fill_label":"Remplissage de la pièce","space.fill_mode.help":"« Couleur personnalisée » définit le style, tandis que « Lumière », « Température » et « LQI » utilisent les données actuelles de Home Assistant. Le halo s’active séparément.","space.fill_mode.help.aria":"Aide : mode de remplissage des pièces","fill.none":"Aucun","fill.lqi":"Signal Zigbee","fill.light":"Lumières","fill.custom":"Couleur personnalisée","space.custom_fill":"Couleur de remplissage","space.source_file":"J’ai une image de plan","space.source_draw":"Aucune image — je tracerai les pièces à la main","fill.temp":"Température","tip.temp_avg":"température moyenne :","tip.hum_avg":"humidité moyenne :","space_card.button":"Ouvrir le plan de l’espace","space_card.not_found":"Espace « {id} » introuvable","space_card.loading":"Chargement…","continuity.restore_plan":"Restauration du plan…","continuity.restore_connection":"Restauration de la connexion aux appareils…","continuity.retry":"Réessayer","editor.space":"Espace","editor.framing":"Cadrage","editor.fit_content":"Tout le contenu visible","editor.fit_house":"Ajusté à la géométrie de la maison","editor.show_button":"Afficher le bouton","editor.button_label":"Libellé du bouton","editor.button_target":"Chemin du tableau de bord cible","marker.sub_entity":"entité","title.general_settings":"Paramètres généraux","title.export_pdf":"Enregistrer en PDF","pdf.title":"Enregistrement en PDF","pdf.dimensions":"Afficher les dimensions et les surfaces","pdf.decor":"Afficher les meubles et les autres éléments","pdf.room_names":"Afficher les noms des pièces","pdf.backdrop":"Afficher le fond de plan","pdf.save":"Enregistrer","pdf.saving":"Création…","pdf.failed":"Impossible de créer le PDF.","pdf.too_large":"Les images dépassent la limite PDF de 25 Mo.","pdf.asset_failed":"Impossible de charger une image de fond ou de décoration.","pdf.scale":"Échelle 1:{n}","pdf.north":"Nord","gs.title":"Paramètres généraux","gs.light_group":"Remplissage : lumières","gs.light_on":"Lumières allumées","gs.light_off":"Toutes les lumières éteintes","gs.temp_group":"Remplissage : température","gs.temp_cold":"Froid","gs.temp_ok":"Confortable","gs.temp_hot":"Chaud","gs.lqi_group":"Remplissage : signal Zigbee","gs.lqi_low":"Signal faible","gs.lqi_high":"Signal fort","gs.reset":"Réinitialiser par défaut","gs.saved":"Paramètres généraux enregistrés","gs.radar_show_live":"Afficher la présence en direct sur le plan","gs.radar_show_live_hint":"Masque ou affiche toutes les cibles radar en direct. Cela ne démarre ni n’arrête l’enregistrement des observations.","radar.title":"Présence sur le plan","radar.help":"Reliez ce marqueur aux entités radar exactes de Home Assistant, placez le capteur et choisissez son profil de coordonnées. Les positions en direct sont limitées à la pièce sélectionnée.","radar.help.aria":"Aide : paramètres du radar de présence","radar.enabled":"Utiliser ce radar de présence","radar.show_live":"Afficher les cibles en direct","radar.configure":"Configurer le radar","radar.configure_on_plan":"Configurer sur le plan","radar.change_installation":"Changer l’installation","radar.no_contour":"Cette pièce n’a pas de contour. Les points radar ne seront pas limités.","radar.discard_setup_title":"Abandonner la configuration du radar ?","radar.discard_setup":"La configuration du radar non enregistrée sera perdue.","radar.step_place_mount":"Indiquez la position physique du capteur","radar.step_place_heading":"Indiquez un point droit devant le capteur","radar.step_reference":"Indiquez la position de référence {n}, puis lancez la mesure","radar.step_check_reference":"Indiquez une position de contrôle indépendante","radar.start_measure":"Lancer la mesure","radar.countdown":"Placez-vous sur le repère dans {seconds} s","radar.capturing":"Restez immobile et seul pendant la mesure…","radar.fit_ready":"Le calibrage est prêt","radar.check_third":"Vérifier à une autre position","radar.check_complete":"Contrôle indépendant terminé","radar.error_distance":"Écart de position : {distance}","radar.ambiguous_target":"Plusieurs cibles ont été signalées. Recommencez la mesure seul.","radar.insufficient_samples":"Coordonnées actuelles insuffisantes. Réessayez ou utilisez le réglage manuel.","radar.bad_references":"Choisissez des références espacées dans des directions différentes du capteur.","radar.ambiguous_sources":"Les mesures permettent deux directions également plausibles. Choisissez des repères distinguant la gauche de la droite.","radar.bad_fit":"Les mesures ne correspondent pas. Vérifiez les unités, la position du capteur et les références.","radar.desktop_hint":"Utilisez un ordinateur pour un réglage précis. L’édition sur appareils tactiles est prise en charge au mieux.","radar.detected":"House Plan a reconnu les métadonnées radar de cet appareil. Vérifiez les sources exactes avant d’enregistrer.","radar.detected_ld2450":"House Plan a trouvé un ensemble de coordonnées ESPHome LD2450. Vérifiez les sources X/Y exactes avant d’enregistrer.","radar.additional_actions":"Actions supplémentaires","radar.declare":"Ceci est un radar de présence","radar.profile":"Profil de données","radar.profile_esphome_ld2450_v1":"ESPHome LD2450 (cibles X/Y)","radar.profile_cartesian_v1":"Cibles cartésiennes (X/Y)","radar.profile_polar_v1":"Cible polaire (distance/angle)","radar.profile_range_v1":"Distance uniquement","radar.profile_zones_v1":"États des zones","radar.profile_presence_v1":"Présence uniquement","radar.room":"Pièce observée","radar.room_choose":"Choisir une pièce","radar.target":"Cible {n}","radar.axis_x":"Entité de coordonnée X","radar.axis_y":"Entité de coordonnée Y","radar.add_target":"Ajouter un emplacement de cible","radar.range_channel":"Canal de distance {n}","radar.add_range":"Ajouter un canal de distance","radar.presence_gate":"Entité de présence du canal","radar.swap_axes":"Permuter les axes X et Y","radar.axis_x_sign":"Direction X","radar.axis_y_sign":"Direction Y","radar.distance_source":"Entité de distance","radar.angle_source":"Entité d’angle","radar.angle_unit":"Unité d’angle","radar.degrees":"Degrés","radar.radians":"Radians","radar.angle_zero":"Direction de l’angle zéro","radar.angle_forward":"Vers l’avant","radar.angle_right":"Vers la droite","radar.angle_clockwise":"Les angles augmentent dans le sens horaire","radar.zone_source":"Entité de zone","radar.occupancy_source":"Entité de présence","radar.count_source":"Entité du nombre de cibles","radar.availability_source":"Entité de disponibilité","radar.source_choose":"Choisir une entité","radar.source_optional":"Facultatif","radar.source_missing":"actuellement indisponible","radar.saved_unsupported":"Cette configuration radar enregistrée est incomplète ou non prise en charge. Elle reste inactive ; supprimez-la ou mettez House Plan à jour avant de la reconfigurer.","radar.occupancy":"Présence (activée/désactivée)","radar.count":"Nombre","radar.mount":"Position et direction","radar.mount_hint":"Il s’agit de la position physique du capteur. Déplacer son marqueur décoratif ne la modifie pas.","radar.heading":"Direction, °","radar.range_cm":"Portée, cm","radar.fov_deg":"Champ de vision, °","radar.unit":"Unité de la source","radar.mirror":"Inverser l’axe gauche/droite","radar.remove":"Supprimer les paramètres radar","radar.invalid":"Renseignez la pièce, les sources et la position du radar avant d’enregistrer.","radar.check_sources":"Vérifier les données en direct","radar.checking":"Vérification…","radar.health":"État de la connexion","radar.live_summary":"Cibles actuelles : {targets} ; arcs de distance : {ranges}","radar.health_ok":"Données actuelles reçues","radar.health_off":"Aucune cible détectée","radar.health_stale":"Certaines coordonnées sont obsolètes","radar.health_partial":"Certaines sources sont à jour, d’autres sont obsolètes","radar.health_restricted":"L’accès à une ou plusieurs sources est limité","radar.health_incomplete":"Le rapport radar actuel est incomplet","radar.health_position_unavailable":"Présence signalée ; position actuelle indisponible","radar.health_unavailable":"Données du capteur indisponibles","radar.health_needs_setup":"L’installation doit être configurée","radar.health_inconsistent":"Les sources fournissent des valeurs contradictoires","radar.health_unknown":"L’état actuel est inconnu","radar.health_disabled":"Le radar est désactivé","radar.error_invalid_radar":"Vérifiez les paramètres radar.","radar.error_invalid_selection":"Sélectionnez une pièce existante et des sources valides.","radar.error_source_restricted":"Vous n’avez pas accès à toutes les sources sélectionnées.","radar.error_rate_limited":"Trop de demandes. Réessayez dans un instant.","radar.error_not_ready":"Le traitement radar n’est pas encore prêt.","radar.error_conflict":"Le plan a changé. Rouvrez la configuration radar et réessayez.","radar.error_source_unavailable":"Une ou plusieurs sources radar sélectionnées sont indisponibles.","radar.error_unsupported_capability":"Cette fonction radar n’est pas prise en charge par l’intégration installée.","radar.report_age":"il y a {seconds} s","space.show_lqi":"Afficher le signal Zigbee (LQI) à côté des appareils","space.hide_decor":"Masquer la couche décorative","space.hide_decor_tip":"Les lignes, formes, étiquettes et meubles restent à leur place — visibles dans l’éditeur d’arrière-plan, mais pas sur le plan.","space.hide_openings":"Masquer les ouvertures","space.hide_openings_tip":"Les symboles de portes, fenêtres et portails ne sont pas dessinés, mais les ouvertures continuent de fonctionner : la lumière les traverse, le soleil entre par les fenêtres et les capteurs de contact continuent de les ouvrir. L’éditeur de plan les affiche toujours.","gs.light_none":"Aucune source lumineuse","mode.plan":"Éditeur de plan","mode.devices":"Éditeur d’appareils","display.value":"Valeur + état","marker.subarea":"aucune zone, manuel","device.new":"Nouvel appareil — ouvrez son éditeur pour fermer","opening.unlock_action":"Déverrouiller","opening.lock_action":"Verrouiller","opening.lock_pending":"En cours…","title.close_editor":"Fermer l’éditeur (retour à la vue)","title.add_device":"Ajouter un appareil au plan","devbar.add":"Ajouter","devbar.rules":"Règles d’icônes","device_inbox.button":"Appareils","device_inbox.title":"Appareils sur le plan","device_inbox.search":"Rechercher appareils, entités et intégrations…","device_inbox.add_virtual":"Ajouter un appareil virtuel","device_inbox.tab_on_plan":"Sur le plan","device_inbox.tab_available":"Disponibles","device_inbox.tab_hidden":"Masqués","device_inbox.tab_readd":"De nouveau disponibles","device_inbox.only_new":"Nouveaux uniquement","device_inbox.show_entities":"Afficher les entités","device_inbox.show_hidden":"Afficher les masqués sur le plan","device_inbox.show_hidden.help":"Affiche temporairement les marqueurs masqués et désactivés sous forme de fantômes réservés à l’éditeur. La visibilité enregistrée des appareils ne change pas.","device_inbox.show_hidden.help.aria":"Aide : afficher les appareils masqués sur le plan","device_inbox.new":"Nouveau","device_inbox.find":"Trouver sur le plan","device_inbox.edit":"Modifier","device_inbox.hide":"Masquer","device_inbox.show":"Afficher","device_inbox.add":"Ajouter","device_inbox.readd":"Ajouter à nouveau","device_inbox.hide_available":"Masquer de la liste","device_inbox.show_more":"Afficher plus","device_inbox.more_actions":"Plus d'actions","device_inbox.find_hidden_hint":"Activez d'abord « Afficher les masqués sur le plan »","device_inbox.show_disabled":"Activez cette liaison dans Home Assistant avant de l'afficher","device_inbox.empty_on_plan":"Aucun appareil correspondant n'est encore sur le plan.","device_inbox.empty_available":"Aucun appareil disponible à ajouter.","device_inbox.empty_hidden":"Il n'y a aucun appareil masqué.","device_inbox.empty_readd":"Aucun appareil supprimé n'est disponible pour un nouvel ajout.","device_inbox.reason_visible_auto":"Découvert automatiquement","device_inbox.reason_visible_explicit":"Ajouté explicitement","device_inbox.reason_manual_hidden":"Masqué par l'utilisateur","device_inbox.reason_automatic_hidden":"Masqué automatiquement","device_inbox.reason_service_entry":"Entrée de registre de service uniquement","device_inbox.reason_excluded_integration":"Intégration « {integration} » exclue par les filtres de découverte","device_inbox.reason_excluded_domain":"Type d'entité non spatial","device_inbox.reason_grouped_light":"Représenté par un groupe de lumières de la pièce","device_inbox.reason_represented_by_parent":"Représenté par son appareil parent","device_inbox.reason_removed":"Précédemment retiré du plan","device_inbox.reason_available":"Disponible pour ajout au plan","device_inbox.reason_no_bound_room":"La zone HA n'est liée à aucune pièce du plan","device_inbox.status_ha_disabled":"Désactivé dans Home Assistant","device_inbox.status_orphaned":"La liaison n'existe plus dans Home Assistant","device_inbox.status_unverified":"Le registre Home Assistant est temporairement indisponible","device_inbox.saved":"Liste des appareils mise à jour","device_inbox.filters_excluded":"Intégrations exclues","device_inbox.filters_group_lights":"Regrouper les lumières de la pièce en un marqueur","device_inbox.filters_preview_appear":"apparaîtra : {count}","device_inbox.filters_preview_hide":"disparaîtra : {count}","device_inbox.filters_preview_lights":"lumières concernées : {count}","device_inbox.filters_reset":"Rétablir les recommandées","device_inbox.filters_save":"Enregistrer les filtres","device_inbox.filters_search_ph":"Ajouter une intégration…","device_inbox.filters_title":"Filtres de découverte","space.roomcard_section":"La carte de pièce affiche :","space.label_temp":"Température","space.label_hum":"Humidité","space.label_lqi":"Signal Zigbee moyen","space.label_light":"Lumières allumées/éteintes","roomcard.light_on":"Allumé","roomcard.light_off":"Éteint","roomcard.light_partial":"{on} sur {total}","toast.split_pick_inside":"Les points intermédiaires de découpe doivent se trouver à l’intérieur de la pièce","mode.decor":"Éditeur d’arrière-plan","decor.select":"Sélectionner","decor.line":"Ligne","decor.rect":"Rectangle","decor.ellipse":"Ovale","decor.text":"Texte","decor.erase":"Effacer","decor.erase_confirm_title":"Effacer l’objet ?","decor.color":"Couleur","decor.width":"Épaisseur de ligne","decor.line_style":"Style de ligne","decor.line_style_solid":"Plein","decor.line_style_dashed":"Pointillés","decor.fill":"Remplissage","decor.fill_color":"Couleur de remplissage","decor.length":"Longueur","decor.size":"Taille","decor.flip_h":"Retourner horizontalement","decor.flip_v":"Retourner verticalement","decor.angle":"Angle de rotation, °","decor.text_size":"Taille du texte","decor.backdrop_properties":"Propriétés de l’arrière-plan du plan","decor.text_title":"Étiquette de texte","decor.object_title":"Modifier {kind}","decor.text_label":"Texte","decor.live_group":"Insérer une variable HA","decor.live_entity":"Entité","decor.live_entity_ph":"choisir une entité","decor.live_attr":"Valeur","decor.live_attr_ph":"choisir l’état ou un attribut","decor.live_state":"État","decor.backdrop":"Image d’arrière-plan","decor.backdrop_hint":"Faites glisser pour déplacer ; tirez un coin pour redimensionner ; utilisez la poignée supérieure pour faire pivoter. Maj modifie les proportions ou libère l’angle.","decor.backdrop_reset":"Réinitialiser l’image","decor.backdrop_reset_done":"L’image a retrouvé sa position et sa taille d’origine","marker.icon_auto":"Auto : {icon} (selon les règles d’icônes ; choisissez-en une pour remplacer)","marker.icon_pin_auto":"Épingle","mode.plan_tip":"Éditeur de plan — la géométrie du logement : dessiner et diviser/fusionner les pièces, les associer aux zones HA, placer portes, fenêtres et portails, déplacer les cartes de pièces, régler l’échelle","mode.devices_tip":"Éditeur d’appareils — tout ce qui concerne les icônes : faire glisser pour positionner, cliquer pour modifier l’association/l’icône/l’affichage, ajouter des appareils virtuels, règles d’icônes","mode.decor_tip":"Éditeur d’arrière-plan — décoration purement visuelle sous le plan : lignes, rectangles, ovales et étiquettes de texte qui ne réagissent jamais aux clics","space.glow_enabled":"Halo des sources lumineuses","gs.glow_group":"Halo des sources lumineuses","gs.glow_base":"Obscurité de la maison","gs.glow_light":"Couleur / intensité de lumière par défaut","gs.wall_group":"Murs","gs.wall_fill":"Remplissage des murs","gs.glow_radius":"Rayon du halo","gs.glow_radius.help":"Définit le rayon général du halo en mètres ou en pieds ; le rayon propre à un appareil remplace cette valeur.","gs.glow_radius.help.aria":"Aide : rayon général du halo","gs.unit_m":"m","gs.unit_ft":"pi","marker.controls_label":"Contrôle d’autres sources lumineuses","marker.controls.help":"Avec l’action « Basculer l’état », les sources répertoriées basculent avec ce marqueur. Leur halo reste sur leurs propres marqueurs et ce lien ne transforme pas à lui seul le marqueur de contrôle en source lumineuse.","marker.controls.help.aria":"Aide : contrôler d’autres sources lumineuses","marker.controls_filter":"Rechercher des lumières et interrupteurs…","info.controls":"Contrôle","marker.glow_radius_label":"Rayon du halo","marker.glow_radius.help":"Définit le rayon du halo en mètres ou en pieds ; une valeur vide utilise le rayon des paramètres généraux.","marker.glow_radius.help.aria":"Aide : rayon du halo","markup.wallthick":"Épaisseur","markup.select":"Sélectionner","title.markup_wallthick":"Épaisseur — cliquez sur un mur pour définir son épaisseur de 0 à 100 cm.","markup.hint_wallthick":"cliquez sur un mur · Échap ferme sans appliquer","wallthick.field":"Épaisseur","wallthick.unit_cm":"cm","wallthick.unit_in":"po","wallthick.apply_room":"Appliquer à tous les murs de cette pièce","markup.draw_wall_title":"Épaisseur de chaque nouveau segment de mur (0–100 cm). Les murs partagés conservent la valeur existante.","room.queue_progress":"Pièce {current} sur {total}","toast.wall_rooms_saved":"Pièces créées : {n}","toast.wall_chain_saved":"Chaîne de murs enregistrée","toast.wallthick_pick":"Cliquez sur un mur","toast.wallthick_set":"Épaisseur du mur définie","toast.wallthick_cleared":"Épaisseur du mur supprimée","toast.physical_range":"Saisissez une valeur comprise entre {min} et {max} {unit}","toast.zero_wall_opening_conflict":"Supprimez d’abord l’ouverture sur ce segment de mur.","toast.zero_wall_ambiguous":"Le segment de mur est ambigu. Simplifiez ou ajustez la jonction.","toast.zero_wall_migration_blocked":"L’espace n’a pas été converti : {reason}. Aucune donnée n’a été modifiée.","toast.physical_angle":"Saisissez un angle de rotation compris entre 0° inclus et 90° exclu","toast.physical_limit":"L’espace a atteint la limite pour ce type de géométrie","toast.geometry_unsafe":"Modification annulée : la géométrie des murs n’a pas pu être construite en toute sécurité.","junction.limit_angle":"L'angle entre les murs est trop aigu : {actual}°, minimum {limit}°.","junction.limit_valence":"Trop de murs se rejoignent en un nœud : {actual}, maximum {limit}.","junction.limit_length":"Le segment de mur est trop court : {actual} cm, minimum {limit} cm.","junction.limit_distance":"Les murs et les nœuds sont trop proches : {actual} cm, minimum {limit} cm.","junction.limit_clearance":"Il ne reste plus d'intérieur de pièce : {actual} cm², minimum {limit} cm².","junction.limit_check_failed":"La vérification des jonctions n'a pas pu s'exécuter — la modification n'a pas été enregistrée","toast.wall_model_migration_blocked":"Le modèle de murs n’a pas pu être mis à jour : {reason}. Le plan n’a pas été modifié. Lancez « Optimiser les plans » ; si l’erreur se reproduit, corrigez la géométrie de mur conflictuelle.","toast.wall_model_client_outdated":"Mettez à jour la carte et rechargez la page avant de modifier le plan.","wall_model.reason.invalid-room":"contour de pièce invalide","wall_model.reason.zero-length":"segment de mur de longueur nulle","wall_model.reason.third-owner":"mur partagé par plus de deux pièces","wall_model.reason.duplicate-id":"identifiants de mur en conflit","wall_model.reason.thickness-conflict":"valeurs d’épaisseur de mur en conflit","wall_model.reason.opening-host":"l’ouverture ne peut pas être attribuée à un seul mur","toast.delete_room_pick":"Cliquez à l’intérieur de la pièce que vous souhaitez supprimer","toast.plan_snap_ambiguous":"Zoomez pour choisir le nœud du mur","toast.wall_repair_ambiguous":"Le contour de la pièce possède plusieurs connexions possibles. Zoomez et reliez-le explicitement.","toast.wall_repair_too_large":"L’écart dépasse 2 cm. Reliez les murs avant de créer la pièce.","toast.wall_repair_changed":"La géométrie des murs a changé. Essayez de créer de nouveau la pièce.","toast.opening_on_zero_wall":"Les ouvertures ne peuvent pas être placées sur un mur d’épaisseur nulle","marker.from_ha_option":"Choisir dans la liste HA","marker.show_entities":"Afficher les entités","marker.show_entities_tip":"Ajoute à la liste non seulement les appareils, mais aussi toutes leurs entités","marker.pick_ph":"Choisir un appareil…","room.open_area":"Ouvrir la zone HA","room.fit_action":"Ajuster la pièce {name}","view.volumetric":"Vue volumétrique","view.flat":"Vue plane","kiosk.title":"Tailles pour cet écran","kiosk.hint":"Enregistrées uniquement sur cet appareil — chaque tablette murale ou TV peut avoir ses propres tailles confortables.","kiosk.icon_scale":"Taille des icônes d’appareils","kiosk.font_scale":"Taille du texte des cartes de pièces","editor.kiosk":"Mode appareil mural (kiosque)","editor.cycle":"Changer automatiquement d’espace toutes les N secondes (kiosque, 0 = désactivé)","room.settings_title":"Paramètres de la pièce","room.settings_section":"Paramètres de la pièce (remplacent ceux de l’espace)","room.fill_label":"Remplissage de CETTE pièce","fill.inherit":"Comme l’espace","room.custom_fill_space":"Couleur de l’espace","room.custom_fill_own":"Couleur de la pièce","room.temp_range_label":"Plage de confort","room.temp_range_min":"Limite basse de température confortable","room.temp_range_max":"Limite haute de température confortable","room.temp_range_reset":"Comme l’espace","room.temp_range.help":"Cette plage s’applique uniquement à cette pièce. Un champ vide hérite de la limite correspondante de l’espace ; si les limites sont inversées, House Plan utilise la plus petite comme limite basse et la plus grande comme limite haute.","room.temp_range.help.aria":"À propos de la plage de confort de la pièce","room.temp_src_label":"Source de température","room.hum_src_label":"Source d’humidité","room.src_average":"Moyenne des capteurs de la pièce (par défaut)","room.src_pick":"Un appareil ou une entité HA spécifique","room.src_ph":"Choisir une source…","toast.room_updated":"Pièce mise à jour","space.card_font":"Taille de police des cartes de pièces (tout l’espace)","room.sizes_section":"Tailles de police","room.name_scale":"Taille du nom de la pièce","room.label_scale":"Taille des mesures","preview.room_name":"Salon","toast.cfg_reload_failed":"Impossible de recharger le plan depuis le serveur : {err}","toast.locale_load_failed":"Impossible de charger le pack de langue. L'anglais est utilisé jusqu'au rechargement de la page.","toast.furniture_art_load_failed":"Impossible de charger les dessins de meubles. Rechargez la page pour les afficher.","room.settings_short":"Paramètres de la pièce","room.unnamed":"Pièce sans nom","marker.use_climate_temp":"Inclure la température de l’appareil dans la pièce","marker.use_climate_temp_tip":"Ajoute la valeur current_temperature d’un climatiseur ou thermostat à la moyenne de la pièce. Configurez séparément le badge de valeur externe ci-dessous.","marker.value_badge_title":"Badge de valeur","marker.value_badge.help":"Affiche une valeur sélectionnée à côté de l’icône. Cela n’affecte pas les mesures de la pièce, la lumière, le halo ni l’action au toucher.","marker.value_badge.help.aria":"Aide : badge de valeur de l’appareil","marker.value_badge_enabled":"Afficher un badge de valeur","marker.value_badge_source":"Valeur","marker.value_badge_source.help":"Choisissez un état précis, un attribut pris en charge ou une valeur dérivée de cet appareil.","marker.value_badge_source.help.aria":"Aide : source du badge de valeur","marker.value_badge_position":"Position","marker.value_badge_position.help":"Le côté choisi reste fixe et ne bascule pas automatiquement au bord du plan.","marker.value_badge_position.help.aria":"Aide : position du badge de valeur","marker.value_badge_right":"À droite","marker.value_badge_bottom":"En dessous","marker.value_badge_left":"À gauche","marker.value_badge_top":"Au-dessus","marker.value_badge_empty":"Cet appareil n’a aucune valeur disponible","marker.value_badge_static":"Une icône statique n’affiche pas de valeurs en direct. Le paramètre est conservé.","marker.value_badge_missing":"Source indisponible","marker.value_badge_missing_hint":"La source enregistrée est actuellement indisponible. Conservez-la, désactivez le badge ou choisissez une autre valeur.","marker.value_badge_duplicate":"La même valeur est déjà affichée dans l’icône.","marker.value_badge_state":"État · {name}","marker.value_badge_marker_state":"État de la source lumineuse · {name}","marker.value_badge_lqi":"Qualité moyenne du signal Zigbee","marker.value_badge_attr_current_temperature":"Température actuelle · {name}","marker.value_badge_attr_temperature":"Température cible · {name}","marker.value_badge_attr_current_humidity":"Humidité actuelle · {name}","marker.value_badge_attr_humidity":"Humidité · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Vitesse · {name}","marker.value_badge_attr_brightness":"Luminosité · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Batterie · {name}","marker.value_badge_attr_fan_speed":"Vitesse du ventilateur · {name}","marker.value_source":"Source de la valeur","marker.value_source.help":"Choisissez la valeur qui remplace l’icône. L’action au toucher ne change pas.","marker.value_source.help.aria":"Aide : source de la valeur dans le marqueur","marker.value_source_auto":"Automatique (comme avant)","marker.value_source_missing_hint":"La source enregistrée est indisponible. Le marqueur affiche — jusqu’à son retour ou jusqu’au choix d’une autre valeur.","marker.light_role_label":"Cet appareil est-il une source lumineuse ?","marker.light_role.help":"« Auto » utilise le rôle déterminé de l’appareil lié, « Toujours » force sa propre source et « Jamais » l’exclut ; les lumières liées ci-dessus restent indépendantes.","marker.light_role.help.aria":"Aide : cet appareil est-il une source lumineuse","marker.light_role_auto_yes":"Auto (source lumineuse)","marker.light_role_auto_no":"Auto (pas une source lumineuse)","marker.light_role_always":"Toujours une source lumineuse","marker.light_role_never":"Jamais une source lumineuse","marker.light_entity_label":"Entité lumineuse principale","marker.light_entity.help":"Pour un appareil composite, choisissez l’entité dont l’état, la couleur et la luminosité représentent cette source sur le plan. Le choix automatique reste compatible avec les anciens plans.","marker.light_entity.help.aria":"Aide : entité lumineuse principale","marker.light_entity_auto":"Automatique ({entity})","marker.light_entity_none":"aucune entité contrôlable","marker.light_entity_missing":"L’entité enregistrée {entity} est indisponible. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.toggle_entity_label":"Entité à basculer","marker.toggle_entity.help":"Pour un appareil composite, choisissez précisément la lumière ou l’interrupteur propre à actionner par un toucher. Automatique conserve les règles de cible précédentes et reste indépendant de l’entité lumineuse principale.","marker.toggle_entity.help.aria":"Aide : entité à basculer","marker.toggle_entity_auto":"Automatique ({entity})","marker.toggle_entity_none":"aucune entité propre contrôlable","marker.toggle_entity_missing":"L’entité enregistrée {entity} ne fait plus partie des canaux sélectionnables de ce marqueur. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.glow_color_label":"Couleur et luminosité du halo","marker.glow_mode.help":"Utilisez les valeurs en direct de la source, remplacez uniquement sa couleur ou fixez à la fois la couleur et la luminosité. Le minimum est 1 % ; pour désactiver la source, choisissez « Jamais ».","marker.glow_mode.help.aria":"Aide : couleur et luminosité du halo","marker.glow_mode_auto":"Depuis la source","marker.glow_mode_color":"Définir la couleur","marker.glow_mode_fixed":"Définir la couleur et la luminosité","marker.glow_color":"Couleur du halo","marker.glow_brightness":"Luminosité","marker.glow_disabled_never":"Les paramètres du halo sont indisponibles car ce marqueur est explicitement défini comme n’étant pas une source lumineuse.","marker.glow_disabled_auto":"Le mode Auto n’a trouvé aucune source lumineuse spatiale pour ce marqueur.","marker.glow_disabled_no_entity":"Aucune entité Home Assistant contrôlable et active n’est disponible pour cette source spatiale.","marker.glow_passive_hint":"Cette source ne possède aucune donnée Home Assistant propre. Définissez manuellement sa couleur et sa luminosité ; son rayon reste disponible.","marker.control_broken":"La source enregistrée est absente ou n’est plus marquée comme lumière","marker.control_missing_label":"Lumière du plan manquante","marker.control_passive":"source passive","toast.marker_control_cycle":"Ce lien créerait une chaîne circulaire de contrôles de lumière.","toast.marker_binding_required":"Choisissez un appareil Home Assistant avant de lier une autre source lumineuse.","confirm.unlock_title":"Déverrouiller ?","confirm.unlock_body":"House Plan enverra une commande de déverrouillage à cette serrure.","toast.files_migrate_failed":"Les pièces jointes n’ont pas pu être déplacées vers la nouvelle association ; les liens continuent de pointer vers les anciens fichiers : {err}","space.pick_saved":"Déjà importé","space.pick_saved_hint":"Plans stockés sur le serveur, y compris ceux que vous avez précédemment dissociés","space.no_saved":"Aucun plan n’est encore stocké sur le serveur.","space.loading":"Chargement…","space.used_by":"utilisé par : {list}","space.in_use":"Un espace utilise encore ce plan — dissociez-le d’abord","btn.use":"Utiliser","confirm.delete_plan_title":"Supprimer le fichier du plan ?","confirm.delete_plan_body":"Le fichier sera supprimé du serveur. Cette action est irréversible.","toast.plans_list_failed":"Impossible de lister les plans stockés : {err}","toast.plan_delete_failed":"Impossible de supprimer le plan : {err}","marker.hide":"Masquer","marker.hide_tip":"L’appareil disparaîtra du plan après l’enregistrement mais continuera de compter dans le signal de la pièce. Restaurez-le via « Masqués et désactivés » dans l’éditeur d’appareils.","marker.show":"Afficher","marker.show_tip":"L’appareil apparaîtra de nouveau sur le plan après l’enregistrement.","marker.hidden_ghost":"Appareil masqué par l’utilisateur","marker.ha_disabled_device":"L’appareil est désactivé dans Home Assistant et masqué du plan.","marker.ha_disabled_entity":"L’entité est désactivée dans Home Assistant et masquée du plan.","marker.ha_disabled_all_entities":"L’appareil n’a aucune entité Home Assistant active ; il est donc masqué du plan.","marker.ha_registry_limited":"Le registre Home Assistant complet n’est pas accessible à cet utilisateur. L’objet non vérifié ne peut pas être affiché ni utilisé pour le moment.","marker.delete_tip":"Supprimer complètement l’appareil du plan et de tous les agrégats. Vous pourrez l’ajouter de nouveau plus tard.","tap.run":"Exécuter une automatisation/un script/une scène","tap.none":"Ne rien faire","marker.run_target_label":"Élément à exécuter","marker.run_search_ph":"Rechercher : automatisation, script ou scène…","marker.run_target_gone":"Cible {id} introuvable — choisissez-en une autre","marker.tap_confirm":"Demander une confirmation","marker.tap_confirm_tip":"Afficher une boîte de dialogue de confirmation avant l’action — protection contre les appuis accidentels.","marker.toggle_hint_single":"Cible : {name} ({id}).","marker.virtual_light_target":"Lumière virtuelle : {name}.","marker.virtual_light_current":"État manuel : {state} → {effect}.","marker.virtual_light_state_on":"allumé","marker.virtual_light_state_off":"éteint","marker.toggle_hint_group":"Basculera {count} source(s) : {names}.","marker.toggle_hint_current":"Actuellement : {state} → {effect}.","marker.toggle_hint_group_current":"Actuellement allumées : {on} sur {count} → {effect}.","marker.toggle_hint_skipped":"Seront ignorées ({count}) : {targets}.","marker.toggle_effect_turn_on":"sera allumé","marker.toggle_effect_turn_off":"sera éteint","marker.toggle_effect_open":"sera ouvert","marker.toggle_effect_close":"sera fermé","marker.toggle_effect_stop":"sera arrêté","marker.toggle_effect_toggle":"l’état sera basculé","marker.toggle_skip_missing":"introuvable","marker.toggle_skip_ha_disabled":"désactivé dans HA","marker.toggle_skip_unavailable":"indisponible","marker.toggle_skip_unsupported":"basculement non pris en charge","marker.toggle_skip_secure":"bloqué pour des raisons de sécurité","marker.toggle_none_no_binding":"Cet appareil n’a aucune association ; il n’y a donc aucun état à basculer. Un toucher ne fera rien.","marker.toggle_none_no_actionable_entity":"Cet appareil n’a aucun état pouvant être basculé. Un toucher ne fera rien.","marker.toggle_none_configured_targets_missing":"Les cibles configurées sont indisponibles. L’entité propre de l’appareil ne leur sera pas substituée.","marker.toggle_none_ha_disabled":"La cible est désactivée dans Home Assistant et ne peut pas être utilisée sur le plan.","marker.toggle_none_unavailable":"La cible est actuellement indisponible. Un toucher ne fera rien.","marker.toggle_none_unsupported":"Home Assistant n’expose aucune opération de basculement sûre pour cette entité. Un toucher ne fera rien.","marker.toggle_none_secure":"Le basculement des serrures, alarmes et portails sécurisés depuis le plan est bloqué pour des raisons de sécurité.","run.automation":"automatisation","run.script":"script","run.scene":"scène","confirm.tap_run":"Exécuter « {name} » ?","confirm.tap_toggle":"Basculer « {name} » ?","confirm.current_state":"État actuel : {state}","confirm.expected_state":"Après basculement : {state}","confirm.group_current":"{on} allumé(s) sur {total}","confirm.group_all_on":"tout est allumé","confirm.group_all_off":"tout est éteint","confirm.unavailable_targets":"Indisponibles : {count}","confirm.expected_by_ha":"Home Assistant déterminera l’état","confirm.state_on":"Allumé","confirm.state_off":"Éteint","confirm.state_open":"Ouvert","confirm.state_closed":"Fermé","confirm.state_opening":"Ouverture en cours","confirm.state_closing":"Fermeture en cours","confirm.state_stopped":"Arrêté","confirm.state_unknown":"Inconnu","toast.run_started":"Démarré : {name}","toast.run_target_missing":"Cible d’exécution introuvable — vérifiez les paramètres de l’appareil","toast.run_target_required":"Choisissez une automatisation, un script ou une scène","toast.tap_target_changed":"La cible de l’action a changé. Réessayez.","toast.virtual_light_toggle_failed":"Impossible de basculer la lumière virtuelle : {err}","toast.value_badge_source_required":"Choisissez une valeur pour le badge","btn.run":"Exécuter","vac.section":"Robot aspirateur : position en direct","vac.autocal":"Configurer automatiquement","vac.live":"Position en direct sur le plan","vac.trail":"Afficher le trajet du robot","vac.autocal_no_rooms":"L’intégration ne fournit aucune liste de pièces — ouvrez « Ajuster manuellement »","vac.route_warn_unmapped":"Le robot nettoie une carte qui n'est assignée à aucun étage","vac.route_warn_needs_calibration":"La carte est assignée à un étage mais n'est pas calibrée","vac.route_warn_ambiguous":"Deux cartes sont indiscernables — aucun étage choisi","vac.route_warn_missing_space":"L'espace de cette carte a été supprimé","vac.autocal_no_match":"Les noms de pièces ne correspondent pas (il en faut ≥3 en commun) — ouvrez « Ajuster manuellement »","vac.autocal_done":"Terminé : association via {rooms} pièces. Lancez un nettoyage et vérifiez","vac.cal_need_pos":"Le robot ne transmet pas de coordonnées — lancez un nettoyage puis mettez-le en pause","vac.cal_done":"Calibration enregistrée. Lancez un nettoyage et vérifiez","vac.cal_cancelled":"Calibration annulée","vac.fit":"Ajuster manuellement","vac.fit_hint":"Faites glisser la carte du robot pour la positionner, étirez-la par les coins","vac.fit_rotate":"Rotation de 90°","vac.fit_mirror":"Miroir","vac.trail_never":"Jamais","vac.trail_cleaning":"Pendant le nettoyage","vac.trail_always":"Toujours","gs.bg_group":"Arrière-plan de la scène","gs.bg_color":"Arrière-plan autour du plan","gs.bg_default":"Valeur par défaut du thème","gs.bg_theme":"valeur par défaut du thème","gs.bg_mode":"Arrière-plan du plan","gs.bg_mode.help":"« Suit le soleil » utilise sun.sun ou, à défaut, l’heure locale du navigateur ; « Couleur statique » affiche toujours la couleur choisie.","gs.bg_mode.help.aria":"Aide : arrière-plan général du plan","gs.bg_static":"Couleur statique","gs.bg_daynight":"Suit le soleil","gs.sun_group":"Soleil","gs.sun_missing":"L’entité sun.sun est introuvable — l’arrière-plan suit votre heure locale ; les rayons de soleil par les fenêtres sont indisponibles.","gs.north":"Nord sur le plan","gs.north.help":"L’angle se mesure dans le sens horaire depuis la verticale supérieure du plan ; le nord sert aux rayons des fenêtres, pas à l’arrière-plan « Suit le soleil ».","gs.north.help.aria":"Aide : direction générale du nord","gs.north_ph":"non défini","gs.north_clear":"Effacer","gs.north_letter":"N","gs.sun_rays":"Lumière du soleil à travers les fenêtres","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · documentation et problèmes","gs.about_telegram":"Discussion Telegram","support.title":"Aide et commentaires","space.bg_color":"Arrière-plan autour du plan","space.bg_inherit":"Hériter des paramètres généraux","space.bg_inherited":"hérite des paramètres généraux","space.bg_mode":"Arrière-plan du plan","space.bg_mode.help":"Héritez de l’arrière-plan général ou remplacez-le pour cet espace par une couleur statique ou le mode « Suit le soleil ».","space.bg_mode.help.aria":"Aide : arrière-plan de l’espace","space.north":"Nord sur le plan (remplacement)","space.north.help":"Remplace le nord général pour cet espace ; l’angle se mesure dans le sens horaire depuis la verticale supérieure du plan et sert aux rayons des fenêtres.","space.north.help.aria":"Aide : nord de cet espace","space.north_inherited":"hérité : {v}","space.sun_rays":"Lumière du soleil à travers les fenêtres","space.sun_inherit":"Hériter des paramètres généraux","space.sun_on":"Activé","space.sun_off":"Désactivé","canvas.far_objects":"{n} objet(s) éloigné(s) du plan","canvas.show_far":"Afficher","canvas.home_tip":"Le plan est là-bas — cliquez pour l’ajuster à l’écran","gs.grid_group":"Maintenance du plan","gs.grid_hint":"Met à jour les modèles de données, aligne les éléments du plan sur la grille et fusionne les fragments de murs redondants. Un rapport précis est affiché avant tout enregistrement.","gs.align_all":"Optimiser les plans","gs.align_title":"Optimiser les plans","gs.align_none":"Tous les plans utilisent déjà le modèle de données optimisé actuel.","gs.optimize_no_automatic_changes":"Aucune modification automatique n’est à appliquer. Vérifiez les éléments ci-dessous.","gs.align_count":"{n} élément(s) sur {total} seront déplacés, de {cm} cm au maximum.","gs.align_where":"Le plus grand déplacement se trouve dans « {s} ».","gs.align_turned":"Ouvertures dont l’angle est corrigé : {n}.","gs.align_preflight_failed":"Impossible de vérifier en toute sécurité la géométrie des espaces suivants : {spaces}{more}.","gs.align_preflight_hint":"Les plans n’ont pas été modifiés. Copiez les diagnostics avec le bouton ci-dessous et joignez-les au rapport de bug avec un export de l’espace.","gs.preflight_reason_prepare-exception":"Impossible de préparer la géométrie de l’espace (exception lors de la construction du modèle)","gs.preflight_reason_wall-null":"Le corps du mur n’a pas pu être construit (l’union a renvoyé un résultat vide)","gs.preflight_reason_wall-degraded-extra":"Le corps du mur s’est dégradé avec une géométrie supplémentaire","gs.preflight_reason_wall-failed-core":"Le noyau du corps du mur n’a pas pu être assemblé","gs.preflight_reason_wall-exception":"La construction du mur a déclenché une exception","gs.preflight_reason_floor-null":"Le contour du sol n’a pas pu être construit","gs.preflight_reason_floor-exception":"La construction du sol a déclenché une exception","gs.preflight_copy":"Copier les diagnostics","gs.preflight_copied":"Diagnostics copiés","gs.preflight_update_hint":"Les versions de la carte et de l’intégration diffèrent — mettez House Plan à jour puis réessayez.","gs.align_preflight_space":"Espace {n}","gs.align_preflight_more":", et {n} de plus","gs.optimize_changes":"Migrations de modèle : {m} ; espaces mis à jour : {c} ; valeurs de coordonnées parasites supprimées : {p} ; fragments de murs réels fusionnés : {w} ; fragments de murs d’épaisseur nulle fusionnés : {s} ; murs indépendants : {i}.","gs.zero_walls_migrated":"Portions de murs virtuels converties : {n}.","gs.wall_segments_migrated":"Segments de murs stabilisés : {n}.","gs.room_drafts_migrated":"Contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","gs.optimize_lattice_summary":"Valeurs de coordonnées parasites normalisées : {n} ; déplacement maximal : {cm} cm.","gs.optimize_lattice_space":"{space} : valeurs de coordonnées normalisées : {n} ; valeurs hors grille laissées inchangées : {far}.","gs.optimize_coincident_partitions":"Sections de murs indépendants masquées absorbées dans les murs des pièces : {n}.","gs.optimize_openings_rehosted":"Ouvertures rattachées aux murs des pièces : {n}.","gs.optimize_walls_straightened":"Murs redressés : {n} ; déplacement maximal : {cm} cm.","gs.optimize_walls_straightened_where":"Plus grande correction de mur : {s}.","gs.optimize_walls_straighten_skipped":"Murs proches d’un axe laissés inchangés car ils ne pouvaient pas être réparés en toute sécurité : {n}.","gs.optimize_glow_migration":"Ancien mode Glow : {spaces} espaces → aucun remplissage de données + Glow indépendant ; {rooms} pièces → remplissage de données hérité + Glow indépendant.","gs.optimize_references":"Références réparées : espaces — {spaces} ; pièces — {rooms} ; positions — {positions} ; appareils dissociés des espaces manquants — {detached}.","gs.optimize_reference_more":", et {n} de plus","gs.optimize_orphans_removed":"Enregistrements oubliés supprimés : {total} — étiquettes de pièces : {rooms} ; appareils : {devices} ; marqueurs de groupe : {groups}. Ils appartenaient à des espaces supprimés précédemment.","gs.optimize_live_positions":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles seront conservées.","gs.optimize_live_positions_remove":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles sont sélectionnées pour suppression.","gs.optimize_live_names":" : {names}{more}","gs.optimize_live_remove":"Supprimer les anciennes positions","gs.optimize_live_keep":"Conserver les anciennes positions","gs.optimize_live_selected":"Les anciennes positions seront supprimées après l’application de l’optimisation.","gs.optimize_unverified":"Impossible de vérifier en toute sécurité les positions : {n}. Elles ont été laissées inchangées.","gs.optimize_registry_limited":"Un accès administrateur complet aux registres Home Assistant est requis pour une vérification sûre.","gs.optimize_vacuum_warning":"Associations de pièces d’aspirateur nécessitant encore une vérification : {n}.","gs.optimize_details":"Détails","gs.optimize_details_more":"Et {n} enregistrement(s) de plus.","gs.optimize_detail_removed":"sera supprimé","gs.optimize_detail_live":"sera conservé","gs.optimize_detail_unverified":"non vérifié","gs.optimize_detail_room_label":"étiquette de pièce","gs.optimize_detail_device":"appareil","gs.optimize_detail_group":"marqueur de groupe","gs.optimize_detail_unknown":"propriétaire inconnu","gs.optimize_detail_item":"{status} : {kind} {id} ; ancien espace {space}","gs.align_warn":"Les éléments volontairement placés entre les nœuds de la grille seront déplacés. Une seule annulation est disponible après l’opération, uniquement jusqu’à la prochaine modification du plan.","gs.align_run":"Optimiser","gs.align_done":"Plans optimisés : {n} élément(s) déplacé(s), {m} enregistrement(s) maintenu(s), {r} référence(s) réparée(s)","gs.optimize_undo":"Annuler la dernière optimisation","gs.optimize_undone":"La dernière optimisation a été annulée","decor.furniture":"Mobilier","decor.image":"Image","decor.image_title":"Images personnalisées","decor.image_upload":"Importer une image","decor.image_replace":"Remplacer l’image","decor.image_uploading":"Importation…","decor.image_asset":"Fichier image","decor.image_pick_hint":"Importez une image ou choisissez-en une existante.","decor.image_place_hint":"Cliquez sur le plan pour placer l’image.","decor.image_none":"Aucune image importée pour le moment.","decor.image_unavailable":"Image indisponible","decor.image_used":"Utilisée dans {n} objets","decor.image_upload_failed":"Impossible d’importer l’image : {err}","decor.image_error_capacity":"Le stockage des images personnalisées est plein.","decor.image_in_use":"Supprimez toutes les copies placées avant ce fichier.","decor.image_delete_title":"Supprimer le fichier image ?","decor.image_delete_message":"Supprimer « {name} » de House Plan ? Cette action est irréversible.","furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis","common.yes":"Oui","common.no":"Non","vac.diag_source":"Source","vac.diag_platform":"Intégration","vac.diag_status":"État","vac.diag_position":"Position","vac.diag_rooms":"Pièces","vac.diag_rooms_value":"{total} · {matched} noms correspondent · {readiness}","vac.autocal_ready":"calibration automatique disponible","vac.autocal_not_ready":"3 noms correspondants requis","vac.diag_path":"Chemin de l’intégration","vac.diag_map":"ID de carte","vac.source_none":"non sélectionné","vac.source_status_ok":"Prêt","vac.source_status_missing":"Manquant","vac.source_status_disabled":"Désactivé dans Home Assistant","vac.source_status_unavailable":"Indisponible","vac.source_status_unverified":"Impossible à vérifier avec les autorisations actuelles","vac.source_status_unsupported":"Aucune donnée de position","vac.source_status_none":"Aucune source","vac.source_banner_missing":"La source enregistrée n’existe plus. Elle n’a pas été remplacée automatiquement ; choisissez une autre source ou restaurez-la dans Home Assistant.","vac.source_banner_disabled":"La source enregistrée est désactivée dans Home Assistant. Activez-la ou choisissez une autre source.","vac.source_banner_unverified":"Les autorisations Home Assistant actuelles ne permettent pas de vérifier cette source enregistrée. Elle reste épinglée et ne sera pas remplacée automatiquement.","vac.choose_source":"Choisir la source","vac.source_auto":"Automatique","vac.source_auto_hint":"Utiliser une entité compatible de cet appareil","vac.all_cameras":"Toutes les caméras","vac.all_cameras_warn":"Une caméra peut ne pas fournir de données du robot. Choisissez-en une uniquement s’il s’agit de la carte de votre aspirateur.","vac.all_cameras_empty":"Aucune autre entité caméra trouvée.","vac.platform_unknown":"intégration inconnue","vac.cap_position":"position","vac.cap_rooms_short":"pièces","vac.cap_path":"trajet","vac.cap_map":"ID de carte","vac.cap_none":"aucune donnée de robot détectée","vac.xcme_hint":"Activez ces attributs Xiaomi Cloud Map Extractor :","vac.documentation":"Documentation","vac.residual_title":"Vérifier la calibration automatique","vac.residual_message":"Les pièces correspondantes présentent un écart maximal de {error}. Appliquez cette calibration approximative, affinez-la manuellement ou annulez sans modifier la configuration enregistrée.","vac.apply_proposal":"Appliquer","gs.backup_group":"Sauvegarde et transfert","gs.backup_hint":"Téléchargez une sauvegarde JSON portable ou prévisualisez et importez une sauvegarde créée par House Plan.","backup.export_open":"Exporter","backup.import_open":"Importer","backup.export_title":"Exporter House Plan","backup.import_title":"Importer House Plan","backup.export_hint":"Choisissez si la sauvegarde doit contenir toute la configuration House Plan ou uniquement l’espace actuel.","backup.full":"Sauvegarde complète","backup.current_space":"Espace actuel","backup.current_space_title":"Espace actuel : {title}","backup.no_current_space":"Aucun espace actuel","backup.plan_only":"Plan uniquement","backup.plan_only_hint":"Conserver les pièces, murs, ouvertures, décorations et positions des étiquettes de pièces sans les appareils ni les associations Home Assistant.","backup.plan_only_preview":"Ce fichier contient uniquement le plan","backup.privacy_warning":"L’archive conserve les noms, identifiants Home Assistant et coordonnées exactes. Les plans internes et pièces jointes sont référencés, pas intégrés ; les états d’exécution et trajets d’aspirateur ne sont pas inclus.","backup.download":"Télécharger le JSON","backup.export_done":"Sauvegarde téléchargée","backup.reading":"Vérification de la sauvegarde…","backup.revalidated":"Le plan a changé depuis cet aperçu. Le résumé a été actualisé ; vérifiez-le et confirmez de nouveau.","backup.error.support_invalid_message":"Vérifiez le message d’assistance et réessayez.","backup.error.support_package_too_large":"Le paquet d’assistance anonymisé dépasse la limite de 8 Mio.","backup.error.support_preview_expired":"L’aperçu de la pièce jointe d’assistance a expiré ou n’est plus disponible.","backup.error.support_rate_limited":"Trop de rapports ou d’aperçus d’assistance ont été demandés. Réessayez plus tard.","backup.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","backup.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible.","backup.error.unauthorized":"Vous n’avez pas l’autorisation d’exporter ou d’importer ce plan.","backup.error.not_ready":"House Plan n’est pas encore prêt. Réessayez dans un instant.","backup.error.too_large":"La sauvegarde dépasse la limite de 8 Mio.","backup.error.invalid_json":"Le fichier sélectionné n’est pas un JSON valide.","backup.error.invalid_format":"Le fichier sélectionné n’est pas une sauvegarde House Plan.","backup.error.invalid_image":"L’image est endommagée ou ne correspond pas à son format.","backup.error.unsupported_export_version":"Ce format de sauvegarde n’est pas pris en charge par la version installée.","backup.error.unsupported_image":"Utilisez une image PNG, JPEG, WebP ou SVG prise en charge.","backup.error.future_model":"La sauvegarde a été créée avec un modèle de données House Plan plus récent.","backup.error.invalid_config":"La sauvegarde contient une configuration House Plan invalide.","backup.error.wall_model_migration_blocked":"Le modèle de murs de la sauvegarde n’a pas pu être mis à niveau en toute sécurité. Optimisez d’abord le plan source, puis exportez-le de nouveau.","backup.error.invalid_layout":"La sauvegarde contient des positions d’objets invalides.","backup.error.invalid_content":"La sauvegarde contient des références de contenu invalides ou incohérentes.","backup.error.space_not_found":"L’espace sélectionné n’existe plus.","backup.error.capacity_exceeded":"L’ajout de cette sauvegarde dépasserait les limites du plan.","backup.error.preview_expired":"L’aperçu a expiré. Sélectionnez de nouveau le fichier de sauvegarde.","backup.error.preview_owner_mismatch":"Cet aperçu appartient à un autre utilisateur Home Assistant.","backup.error.conflict":"Le plan a changé depuis l’aperçu. Vérifiez le résumé actualisé.","backup.error.content_confirmation_required":"Confirmez que le contenu local indisponible peut être dissocié.","backup.error.commit_failed":"La sauvegarde n’a pas pu être appliquée en toute sécurité. Le plan précédent a été restauré ou est en attente de récupération.","backup.error.missing_plan":"Un fichier de plan référencé a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.missing_content":"Une pièce jointe locale référencée a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.marker_control_missing":"Une lumière liée au plan est absente de la sauvegarde.","backup.error.marker_control_not_light":"Une cible liée au plan n’est plus marquée comme source lumineuse.","backup.error.marker_control_self":"Une source lumineuse ne peut pas se contrôler elle-même.","backup.error.marker_control_cycle":"La sauvegarde contient une chaîne circulaire de contrôles de lumière.","backup.error.duplicate_marker_control":"La sauvegarde contient un lien de lumière du plan en doublon.","backup.error.no_backup":"Aucun instantané d’importation ou d’optimisation n’est disponible à restaurer.","backup.error.in_use":"L'élément est encore utilisé","backup.error.invalid_data":"La requête contient des données invalides","backup.error.invalid_light_entity":"La lumière principale doit être une entité light.* ou switch.*","backup.error.invalid_marker_control":"Référence de contrôle de marqueur invalide","backup.error.invalid_name":"Le nom est invalide","backup.error.invalid_partition_opening_host":"L'ouverture doit conserver sa cloison porteuse","backup.error.invalid_partition_opening_jamb_margin":"L'ouverture ne laisse aucun jambage physique au bout du mur","backup.error.invalid_passage_fields":"Un passage ouvert ne peut pas porter de réglages de porte","backup.error.invalid_space_id":"Espace inconnu","backup.error.invalid_toggle_entity":"L'entité de bascule doit être light.* ou switch.*","backup.error.invalid_value_badge":"Réglages de badge de valeur invalides","backup.error.invalid_value_badge_attribute":"Attribut de badge de valeur invalide","backup.error.invalid_value_badge_position":"Position de badge de valeur invalide","backup.error.invalid_value_badge_source":"Source de badge de valeur invalide","backup.error.invalid_vacuum_map_route":"Vérifiez l'affectation des cartes du robot aux espaces.","backup.error.invalid_value_source":"Source de valeur invalide","backup.error.invalid_value_source_attribute":"Attribut de source de valeur invalide","backup.error.io_error":"Une opération de fichier a échoué sur le serveur","backup.error.not_toggleable":"Cet appareil ne peut pas être basculé","backup.error.nothing_to_repair":"Rien à réparer","backup.error.space_in_use":"L'espace est encore référencé","backup.error.value_badge_source_required":"Le badge de valeur nécessite une source","backup.error.wall_model_client_outdated":"Le plan a été mis à jour ailleurs — rechargez la page","backup.same_source":"Créée sur cette instance Home Assistant","backup.foreign_source":"Créée sur une autre instance Home Assistant","backup.created":"Créée : {value}","backup.versions":"Carte {card} ; intégration {integration} ; modèle de données {model}","backup.count_spaces":"Espaces : {n}","backup.count_rooms":"Pièces : {n}","backup.count_walls":"Murs : {n}","backup.count_openings":"Ouvertures : {n}","backup.count_decor":"Objets décoratifs : {n}","backup.count_markers":"Appareils : {n}","backup.count_layout":"Positions : {n}","backup.bindings":"Associations — appareils : {device}, entités : {entity}, virtuels : {virtual} ; positions sans espace : {legacy}","backup.binding_status":"État des cibles — actives : {active}, désactivées : {disabled}, manquantes : {missing}","backup.missing_areas":"Zones absentes sur la cible : {areas}","backup.dropped_marker_links":"Liens de lumières du plan hors de cet espace transféré omis : {n}.","backup.room_drafts_migrated":"Anciens contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","backup.repaired_target_refs":"Références existantes restaurées par cet import d’espace : {n}.","backup.preserved_unresolved_refs":"Références qui n’ont pas pu être restaurées sans ambiguïté conservées : {n}.","backup.preserved_unresolved_hint":"Aucune donnée n’a été devinée ni supprimée. Après l’importation, lancez « Optimiser les plans » pour examiner les références restantes.","backup.import_details":"Détails des références d’importation","backup.import_detail.incoming_remapped":"Références mises à jour dans la copie importée : {n}","backup.import_detail.target_repaired":"Références existantes restaurées : {n}","backup.import_detail.preserved_unresolved":"Références non résolues conservées : {n}","backup.import_detail.collisions":"Conflits de destination conservés en toute sécurité : {n}","backup.import_detail.dropped_links":"Liens entrants omis selon les règles de transfert : {n}","backup.import_detail.bounded_lineages":"Identifiants trop imbriqués maintenus dans les limites : {n}","backup.replace_warning":"Cela remplace la configuration et la disposition actuelles. Les fichiers importés ne sont jamais supprimés. Une seule annulation reste disponible jusqu’à la prochaine modification du plan.","backup.foreign_bookkeeping":"Les données de suivi des appareils connus/nouveaux propres à l’instance ne seront pas importées.","backup.final_name":"Nom du nouvel espace","backup.target_settings":"Les paramètres généraux de l’instance cible restent inchangés.","backup.duplicates":"Associations déjà présentes : {n}","backup.skip":"Ignorer les appareils en doublon","backup.virtual_copy":"Ajouter des copies virtuelles statiques sûres","backup.content":"Contenu référencé","backup.decor_images_summary":"Images personnalisées : {objects} objets, {assets} fichiers ; fichiers absents : {missing}.","backup.content_available":"disponible localement","backup.content_external":"lien externe","backup.content_detach_required":"sera dissocié","backup.confirm_detach":"Je comprends que les plans internes et pièces jointes indisponibles seront dissociés de la configuration importée.","backup.confirm_missing_images":"Je comprends que les images personnalisées absentes resteront des espaces réservés réparables et que les autres fichiers locaux indisponibles seront dissociés.","backup.replace":"Remplacer","backup.add":"Ajouter un espace","backup.space_done":"Espace importé : {rooms} pièces, {markers} appareils, {refs} références existantes restaurées","backup.full_done":"Sauvegarde restaurée : {spaces} espaces, {rooms} pièces, {markers} appareils","backup.undo_import":"Annuler la dernière importation complète","backup.import_undone":"Importation complète annulée","backdrop.large_title":"Grande image","backdrop.large_body":"Cette image fait {w}×{h} (fichier de {fileMb} Mo) et nécessite environ {decodedMb} Mo de mémoire pour s'afficher. Sur tablette, cela peut faire planter la page.","backdrop.unknown_body":"Les dimensions de l'image n'ont pas pu être lues — le fichier est peut-être endommagé. Continuer peut faire planter la page sur tablette.","backdrop.reduced_dimensions":"Copie réduite : {w}×{h} px.","backdrop.use_downscaled":"Téléverser une copie réduite","backdrop.reducing":"Réduction…","backdrop.keep_original":"Conserver l'original","backdrop.too_large_title":"Image trop grande","backdrop.too_large_body":"Cette image dépasse ce que les navigateurs peuvent afficher ({w}×{h}, limite {limit} px par côté). Réduisez-la dans un éditeur de bureau puis téléversez-la à nouveau.","backdrop.downscale_failed":"Impossible de créer la copie réduite. Le plan actuel n'a pas été modifié."};const r="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";export{e as dictionary,r as fingerprint}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";var e={"editor.context_actions":"Actions : {object}","editor.tool_options":"Options de l’outil : {tool}","editor.palette":"Palette : {tool}","editor.open_group":"Groupe d’outils : {group}","editor.group_active":"{group} — actif : {item}","editor.disabled_action":"{action} est indisponible : {reason}","editor.loading":"Chargement de l'éditeur…","editor.loading_aria":"L'éditeur de plan est en cours de chargement","editor.load_failed":"Impossible de charger l'éditeur.","editor.refresh_advice":"Actualisez la page et réessayez.","editor.retry_advice":"Vérifiez votre connexion et appuyez à nouveau.","version_mismatch.title":"Les versions de House Plan ne correspondent pas","version_mismatch.body":"Si Home Assistant redémarre encore, attendez la fin, puis rechargez cette page.","version_mismatch.frontend":"Carte","version_mismatch.backend":"Intégration","version_mismatch.reload":"Recharger la page","color_picker.title":"Sélecteur de couleur","color_picker.hue":"Teinte","color_picker.saturation":"Saturation","color_picker.value":"Luminosité","color_picker.hex":"Couleur hexadécimale","color_picker.invalid_hex":"Saisissez une couleur hexadécimale à 3 ou 6 chiffres","color_picker.confirm":"OK","btn.properties":"Propriétés","btn.keep_as_walls":"Conserver comme murs","btn.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","btn.delete_room_with_walls":"Supprimer la pièce et les murs","title.markup_select":"Sélectionner et modifier les murs et les colonnes","title.markup_column":"Colonne : cliquez sur un point de la grille pour placer une colonne carrée","markup.partition":"Cloison","markup.column":"Colonne","markup.hint_column":"cliquez sur un point de la grille pour placer une colonne carrée","history.wall_segment":"Ajouter un segment de mur","history.column_add":"Ajouter une colonne","history.physical_edit":"Modifier l’objet physique","history.physical_delete":"Supprimer l’objet physique","history.physical_move":"Déplacer l’objet physique","history.wall_face_batch":"Créer des pièces à partir des murs","toast.column_duplicate":"Une colonne avec le même centre et la même dimension extérieure existe déjà","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.shape":"Forme","physical.square":"Carré","physical.circle":"Cercle","physical.diameter":"Diamètre","physical.side":"Côté","physical.rotation":"Angle de rotation","physical.length":"Longueur","physical.allowed_range":"Autorisé : {min}–{max} {unit}","physical.column_size_title":"Côté extérieur de la colonne carrée placée par le clic (1–150 cm).","card.title":"Plan de la maison","count.devices":"{n} app.","empty.no_spaces":"Aucun espace pour le moment.","nav.spaces":"Espaces House Plan","empty.add_first":"Ajoutez le premier espace et importez un plan.","empty.read_only":"Aucun espace n’est configuré. Demandez à un administrateur d’en ajouter un.","empty.install":"Installez l’intégration House Plan et ajoutez-la dans « Appareils et services ».","btn.add_space":"Ajouter un espace","btn.cancel":"Annuler","btn.save":"Enregistrer","btn.close":"Fermer","btn.delete":"Supprimer","btn.copy":"Copier","btn.edit":"Modifier","btn.open_in_ha":"Ouvrir dans HA","btn.reset":"Réinitialiser","btn.attach":"Joindre…","btn.upload":"Importer…","btn.replace":"Remplacer…","title.zoom_in":"Zoomer","title.zoom_out":"Dézoomer","title.zoom_fit":"Tout ajuster","title.configure_space":"Configurer l’espace","title.add_space":"Ajouter un espace","title.markup_add":"Murs : tracez une chaîne continue ; chaque segment accepté est enregistré séparément. Maj verrouille à 45°","title.markup_merge":"Fusionner : cliquez sur une pièce, puis sur la pièce voisine avec laquelle elle partage un mur","title.markup_split":"Diviser une pièce : cliquez sur la pièce, puis sur deux points de ses murs","title.markup_delroom":"Supprimer une pièce : cliquez à l’intérieur de la pièce puis confirmez","title.need_plan":"Importer une image de plan","markup.add":"Murs","markup.merge":"Fusionner","markup.split":"Diviser","markup.resize":"Redimensionner","title.markup_resize":"Redimensionner les pièces : faites glisser une poignée disponible sur un mur horizontal ou vertical","markup.hint_resize":"faites glisser une poignée de mur disponible · le mur s’arrête à la première position non sûre · Échap annule · Ctrl+Z — annuler","resize.disabled.diagonal":"Ce mur est incliné ; le redimensionnement ne prend en charge que les murs horizontaux et verticaux","resize.disabled.side-angle":"Un mur adjacent est incliné ; le redimensionnement exige que les deux murs adjacents rencontrent ce mur à angle droit","resize.disabled.duplicate-physical-wall":"Une cloison distincte ou une colonne chevauche ce mur ; supprimez-la ou déplacez-la avant de redimensionner","resize.disabled.partial-shared":"Une pièce voisine n’utilise qu’une partie de ce mur ; il ne peut donc pas être déplacé en toute sécurité comme un mur partagé unique","resize.disabled.unequal-shared":"La pièce voisine utilise des extrémités ou une longueur de mur différentes ; les murs ne peuvent donc pas être déplacés ensemble en toute sécurité","resize.disabled.multiple-rooms":"Déplacer ce mur affecterait plus de deux pièces","resize.disabled.thickness-conflict":"L’épaisseur du mur ne peut pas être conservée en toute sécurité","resize.disabled.opening-conflict":"Une ouverture sur ce mur ne peut pas être déplacée en toute sécurité","resize.disabled.invalid-geometry":"Ce mur ne peut pas être redimensionné sans modifier la structure du plan","resize.limit_stopped":"Mur arrêté : l'étape suivante enfreindrait une limite de jonction","resize.commit_failed":"Le redimensionnement a été annulé car le plan final n’a pas passé le contrôle de géométrie","resize.preview_failed":"Le redimensionnement s’est arrêté à la dernière position sûre car la géométrie du plan ne pouvait pas être préservée","markup.opening":"Ouverture","markup.delete_room":"Supprimer la pièce","history.undo":"Annuler","history.redo":"Rétablir","history.undo_named":"Annuler : {name} (Ctrl+Z)","history.redo_named":"Rétablir : {name} (Ctrl+Maj+Z / Ctrl+Y)","history.undo_empty":"Rien à annuler","history.redo_empty":"Rien à rétablir","history.undone":"Annulé : {name}","history.redone":"Rétabli : {name}","history.add_room":"Créer une pièce","history.split_room":"Diviser la pièce","history.merge_rooms":"Fusionner les pièces","history.resize_room":"Redimensionner la pièce","history.wall_thickness":"Modifier l’épaisseur du mur","history.add_opening":"Ajouter une ouverture de porte ou de fenêtre","history.edit_opening":"Modifier l’ouverture","history.move_opening":"Déplacer l’ouverture","history.delete_opening":"Supprimer l’ouverture","history.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","history.delete_room_with_walls":"Supprimer la pièce et les murs","history.decor_add":"Ajouter un objet décoratif","history.decor_edit":"Modifier l’objet décoratif","history.decor_move":"Déplacer l’objet décoratif","history.decor_transform":"Transformer l’objet décoratif","history.decor_delete":"Supprimer l’objet décoratif","history.backdrop_transform":"Transformer l’arrière-plan du plan","history.device_move":"Déplacer {name}","history.device_stale":"L’historique des positions n’est plus applicable et a été effacé","opening.new":"Nouvelle ouverture","opening.edit":"Ouverture","opening.door":"Porte","opening.window":"Fenêtre","opening.gate":"Portail","opening.passage":"Passage ouvert","opening.passage_binding_warning":"L’enregistrement supprimera le capteur d’ouverture/fermeture et la serrure.","opening.invalid_passage_fields":"Le passage ouvert du plan « {room} » possède des paramètres non pris en charge : {fields}.","opening.type_label":"Type","opening.length_label":"Longueur, cm","opening.contact_label":"Capteur d’ouverture/fermeture","opening.lock_label":"Serrure","opening.none":"— aucun —","opening.search_ph":"Rechercher : nom ou ID d’entité…","opening.invert":"Inverser ouvert/fermé","opening.flip_h":"Charnière sur l’autre montant","opening.flip_v":"Ouverture de l’autre côté","opening.open":"Ouvert","opening.closed":"Fermé","opening.locked":"Verrouillé","opening.unlocked":"Déverrouillé","opening.state_unknown":"indisponible","opening.no_entities":"Aucun capteur associé — symbole statique sur le plan.","toast.opening_no_wall":"Cliquez près d’un mur de pièce ou d’un mur indépendant","opening.host_partition":"Mur indépendant","opening.partition_orphan":"Le mur indépendant de cette ouverture n’existe plus","opening.partition_jamb_margin":"Laissez au moins {distance} entre l’ouverture et l’extrémité du mur","opening.rebind_partition":"Associer à un autre mur indépendant","confirm.delete_partition_openings_title":"Supprimer le mur et les ouvertures ?","confirm.delete_partition_openings_body":"Ce mur contient {count} ouverture(s). Elles seront supprimées avec lui.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.hint_points":"points : {n} · Maj — pas de 45° · Échap — terminer la chaîne · Ctrl+Z — annuler un point · fermer une zone propose de créer une pièce","markup.hint_start":"cliquez sur un point de la grille pour commencer une chaîne de murs","tip.lqi":"signal Zigbee moyen :","tip.area":"surface : {value}","info.device_header":"Appareil sur le plan","info.model":"Modèle","info.state":"État","info.link":"Lien","info.manuals":"Manuels","info.none":"Aucune information supplémentaire","marker.new_device":"Nouvel appareil","marker.name_label":"Nom (affiché sur le plan)","marker.name_ph":"Nom","marker.binding_label":"Associer à un appareil HA","marker.binding_disabled":"désactivé dans Home Assistant","marker.virtual_option":"Appareil virtuel (sans association)","marker.search_ph":"Rechercher un appareil / groupe…","marker.nothing_found":"aucun résultat","marker.room_label":"Pièce","marker.room_override":" (placement forcé)","marker.room_choose":"— sélectionner une pièce —","marker.room_auto":"— selon la zone de l’appareil (auto) —","marker.icon_label":"Icône","marker.icon_ph":"mdi:… (vide = auto)","marker.display_label":"Affichage","display.badge":"Icône + état","display.icon_ripple":"Icône + état et activité","display.static_icon":"Icône toujours statique","marker.display_hint_badge":"L’icône et le fond dynamique affichent l’état de l’appareil sans la pulsation d’activité habituelle. Les alarmes rouges restent visibles.","marker.display_hint_icon_ripple":"L’icône, le fond dynamique et la pulsation affichent une brève animation pour les événements et une animation continue pour le fonctionnement, le mouvement ou la présence. Les alarmes rouges restent prioritaires.","marker.display_hint_value":"Une valeur Home Assistant sélectionnée ou résolue automatiquement remplace l’icône tandis que le fond continue d’indiquer l’état. Les alarmes rouges restent visibles.","marker.display_hint_static_icon":"Le contour adapté au thème et l’icône restent toujours identiques. L’état, l’activité, l’indisponibilité et les alarmes ne modifient pas l’apparence.","marker.static_alarm_warning":"Cet appareil peut signaler des alarmes. L’affichage statique masque l’indication visuelle d’alarme du marqueur.","marker.preview.title":"Aperçu de l’affichage","marker.preview.actual":"Actuel","marker.preview.example":"Exemple","marker.preview.integration":"Fourni par","marker.preview.source":"Source d’affichage","marker.preview.current_state":"État actuel","marker.preview.result":"Sur le plan","marker.preview.details":"Détails de la source","marker.preview.select_source":"Choisissez un appareil ou une entité Home Assistant pour voir son affichage réel.","marker.preview.unknown_provider":"Intégration inconnue","marker.preview.virtual_provider":"House Plan · appareil virtuel","marker.preview.no_source":"Aucune source active","marker.preview.no_state":"Aucun état actuel","marker.preview.mixed_states":"Plusieurs états différents","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} de plus","marker.preview.scaled":"L’aperçu est redimensionné à {n}% pour tenir dans la zone. La taille enregistrée reste inchangée.","marker.preview.demo_short":"Afficher une activité brève","marker.preview.demo_continuous":"Afficher une activité continue","marker.preview.stop_continuous":"Arrêter l’activité continue","marker.preview.demo_short_notice":"Exemple d’activité brève ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_continuous_notice":"Exemple d’activité continue ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_already_visible":"L’état actuel affiche déjà un véritable effet d’activité ou d’alarme.","marker.preview.reduced_motion":"La réduction des animations est activée sur le système ; l’activité normale est donc affichée sous forme de point.","marker.preview.reason.neutral":"Fond sombre neutre","marker.preview.reason.working":"Fond jaune : l’appareil fonctionne actuellement","marker.preview.reason.working_activity":"Fond jaune et effet d’activité : l’appareil fonctionne actuellement","marker.preview.reason.open":"Fond orange : physiquement ouvert ou déverrouillé","marker.preview.reason.cover_icon_state":"Fond neutre ; l’entité de volet contrôle l’état et l’icône affichés","marker.preview.reason.presence":"Effet d’activité tant qu’une présence est détectée","marker.preview.reason.event":"Effet d’activité bref après un événement détecté","marker.preview.reason.transition":"Effet d’activité pendant que l’appareil se déplace ou change d’état","marker.preview.reason.media_neutral":"Les appareils multimédias restent sur un fond sombre neutre tant qu’ils sont disponibles","marker.preview.reason.unavailable":"Fond neutre atténué : indisponible ou éteint","marker.preview.reason.alarm":"Fond d’alarme rouge ; l’indication d’alarme est toujours affichée","marker.preview.reason.live_states_disabled":"Le style selon les états en direct est désactivé pour cette carte","marker.preview.reason.value_no_state":"Aucune valeur d’état exploitable ; l’icône est affichée à la place","marker.preview.reason.value_ambiguous_sources":"Plusieurs sources de valeur possibles ; l’icône est affichée à la place","marker.preview.reason.value_non_scalar":"La source n’a pas renvoyé de valeur simple ; l’icône est affichée à la place","marker.preview.reason.value_virtual":"Un appareil virtuel n’a aucune valeur Home Assistant ; l’icône est affichée à la place","marker.preview.reason.vacuum_live_plan_only":"La position et la trajectoire en direct de l’aspirateur ne sont disponibles que sur le plan complet","marker.preview.reason.hidden_design_preview":"L’appareil est masqué sur le plan ; cet aperçu de conception reste visible","marker.preview.reason.composite_power_source":"L’état provient de l’entité d’alimentation de l’appareil ; les interrupteurs auxiliaires sont ignorés","marker.preview.reason.activity_display_disabled":"Le mode d’affichage sélectionné n’affiche pas les effets d’activité habituels","marker.preview.reason.ha_disabled":"L’association Home Assistant est désactivée et sera masquée sur le plan","marker.preview.reason.orphaned":"L’association Home Assistant enregistrée est introuvable","marker.preview.reason.static_icon":"Mode statique : l’état de l’appareil ne modifie pas l’icône","marker.activity_color":"Couleur de la pulsation d’activité","marker.ripple_size":"Taille de la pulsation d’activité","marker.activity_alarm_note":"La couleur et la taille n’affectent que l’activité normale et ne modifient pas les alarmes rouges.","marker.pulse_a11y_alarm":"Alarme","marker.pulse_a11y_event":"Événement récent","marker.pulse_a11y_presence":"Présence détectée","marker.pulse_a11y_transition":"Changement d’état","marker.pulse_a11y_running":"En fonctionnement","marker.state_a11y_neutral":"État par défaut","marker.state_a11y_working":"En fonctionnement","marker.state_a11y_open":"Ouvert","marker.state_a11y_locked":"Verrouillé","marker.state_a11y_unlocked":"Déverrouillé","marker.state_a11y_alarm":"Alarme","marker.state_a11y_unavailable":"Indisponible","marker.lqi_a11y_low":"LQI {value}, signal faible","marker.lqi_a11y_mid":"LQI {value}, signal moyen","marker.lqi_a11y_high":"LQI {value}, signal fort","marker.size_label":"Taille / rotation de l’icône","marker.angle_label":"Rotation","marker.model_label":"Modèle","marker.model_ph":"ex. Aqara T&H","marker.link_label":"Lien","marker.desc_label":"Description","marker.desc_ph":"Notes, caractéristiques…","marker.manuals_label":"Manuels (PDF, etc.)","marker.sub_device":"appareil","marker.sub_z2m_group":" · groupe Z2M","marker.sub_group":"groupe","marker.sub_helper":"assistant","space.new":"Nouvel espace","space.copy_title":"Copier l’espace","space.copy_name":"Nom du nouvel espace","space.copy_fallback":"Espace","space.copy_create":"Créer la copie","space.copy_optimize_title":"Optimiser avant de copier ?","space.copy_optimize_body":"Avant de créer « {name} », House Plan doit optimiser tout le plan, y compris les autres espaces. Continuer ?","space.copy_optimize_confirm":"Optimiser et copier","space.copy_error_changed":"Le plan a changé pendant la confirmation. Vérifiez-le et réessayez.","space.copy_error_source_missing":"L’espace source n’existe plus. Rouvrez ses réglages et réessayez.","space.copy_error_source_invalid":"House Plan n’a pas pu valider tous les murs de cet espace. Corrigez l’espace source.","space.copy_error_spaces_limit":"House Plan contient déjà le nombre maximal d’espaces.","space.copy_error_partitions_limit":"Cet espace contient trop de murs pour être copié.","space.copy_error_openings_limit":"Cet espace contient trop d’ouvertures pour être copié.","space.copy_error_decor_limit":"Cet espace contient trop d’objets d’arrière-plan pour être copié.","space.copy_error_columns_limit":"Cet espace contient trop de colonnes pour être copié.","space.copy_error_opening_host":"Une ouverture n’est plus rattachée à un mur. Corrigez-la ou supprimez-la avant la copie.","space.copy_error_geometry":"La copie créerait une géométrie de murs non sûre. Corrigez l’espace source.","space.copy_error_optimize_geometry":"La copie est arrêtée car l’optimisation de tout le plan n’est pas sûre pour un espace.","space.header":"Espace","space.title_label":"Titre","space.title_ph":"ex. Garage","space.plan_label":"Plan (arrière-plan)","space.no_plan":"aucune image de plan","space.plan_alt":"plan","room.new":"Nouvelle pièce","room.name_label":"Nom affiché","room.name_ph":"ex. Terrasse","room.area_label":"Zone Home Assistant (non attribuée)","room.no_area_option":"— aucune zone —","room.default_name":"Pièce","device.unnamed":"sans nom","device.light_group":"groupe de lumières","device.fallback":"appareil","device.virtual":"appareil virtuel","confirm.delete_room_title":"Supprimer la pièce « {name} » ?","confirm.delete_room_body":"Choisissez si les murs physiques propres à la pièce doivent être conservés. Les murs partagés avec une autre pièce sont toujours conservés.","confirm.remove_marker_title":"Supprimer l’appareil du plan ?","confirm.remove_marker_body":"L’appareil disparaîtra complètement et ne contribuera plus aux données du plan. Vous pourrez l’ajouter de nouveau plus tard.","confirm.erase_decor":"Effacer l’objet {kind} ? Vous pouvez annuler cette action depuis l’historique de l’éditeur.","confirm.delete_space_title":"Supprimer l’espace ?","confirm.delete_space_body":"L’espace, toutes ses pièces et tout le tracé du plan seront supprimés.","confirm.delete_space_vac_routes":"Les affectations de cartes de robots seront aussi supprimées : {count}.","space.delete_blocked":"Cet espace est encore utilisé par {n} appareil(s). Déplacez-les vers un autre espace ou supprimez-les d’abord.","toast.pos_save_failed":"Échec de l’enregistrement de la position : {err}","toast.no_entity":"L’appareil n’a aucune entité adaptée","toast.ha_disabled_action":"Un objet Home Assistant désactivé ne peut pas être utilisé sur le plan.","toast.ha_disabled_show_device":"Un appareil désactivé dans Home Assistant ne peut pas être affiché sur le plan. Activez-le d’abord dans Home Assistant.","toast.ha_disabled_show_entity":"Une entité désactivée dans Home Assistant ne peut pas être affichée sur le plan. Activez-la d’abord dans Home Assistant.","toast.ha_disabled_add":"Un objet Home Assistant désactivé ne peut pas être ajouté au plan. Activez-le d’abord dans Home Assistant.","toast.ha_binding_unverified":"L’état de l’objet n’a pas pu être vérifié via le registre Home Assistant. L’affichage et les actions sont temporairement indisponibles.","toast.markup_needs_server":"Le tracé est disponible une fois la configuration déplacée sur le serveur","toast.space_order_changed":"L’ordre a changé. Si une carte fixe son étage par numéro, vérifiez ces tableaux de bord.","toast.conflict":"La configuration a été modifiée dans une autre fenêtre — données actualisées, répétez votre dernière action","toast.cfg_save_failed":"Échec de l’enregistrement de la configuration : {err}","toast.room_overlap":"Le contour chevauche la pièce « {name} » — les pièces ne doivent pas se chevaucher","toast.contour_cannot_close":"Le contour ne peut pas être fermé car il est dégénéré ou s’auto-intersecte","toast.merge_not_adjacent":"Seules les pièces partageant un mur peuvent être fusionnées","toast.rooms_merged":"Pièces fusionnées dans « {name} »","toast.split_pick_wall":"Commencez la découpe sur le mur de la pièce","toast.split_bad_cut":"La découpe doit aller d’un mur à l’autre à l’intérieur de la pièce, sans croiser de mur ni se croiser elle-même","merge.header":"Fusionner les pièces","merge.hint":"La pièce fusionnée conserve un nom et une zone. L’autre zone est libérée — ses appareils quittent le plan jusqu’à ce qu’une autre pièce la récupère.","merge.keep":"Conserver","merge.no_area":"aucune zone","toast.room_saved":"Pièce enregistrée ({n}). Appareils ajoutés : {added}. Tracez la suivante ou quittez le mode tracé.","toast.room_saved_no_area":"Pièce enregistrée ({n}, sans zone). Tracez la suivante ou quittez le mode tracé.","toast.marker_needs_server":"La modification des appareils est disponible une fois la configuration déplacée sur le serveur","toast.virtual_name_required":"Saisissez un nom pour l’appareil virtuel","toast.marker_saved":"Appareil enregistré","toast.marker_removed":"Appareil supprimé du plan","toast.integration_missing":"L’intégration House Plan n’est pas installée — gestion indisponible","toast.plan_formats":"Formats pris en charge : SVG, PNG, JPG, WebP","toast.plan_required":"Importez un plan — il est obligatoire","toast.space_added_onboard":"Espace ajouté. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","toast.space_added":"Espace ajouté","toast.space_copied":"Espace « {name} » créé","toast.space_saved":"Espace enregistré","toast.space_deleted":"Espace supprimé","toast.delete_failed":"Échec de la suppression : {err}","toast.error":"Erreur : {err}","toast.toggle_target_unavailable":"La cible « {name} » est indisponible — aucune action n’a été effectuée","toast.toggle_targets_unavailable":"Cibles indisponibles : {names}. Aucune action n’a été effectuée","toast.file_failed":"Le fichier « {name} » n’a pas été importé : {err}","toast.files_attached":"Fichiers joints : {n}","err.unknown":"erreur inconnue","err.code":"code {code}","err.too_large":"fichier supérieur à {mb} Mo","err.bad_ext":"type non pris en charge (PDF/image attendu)","err.unauthorized":"droits administrateur requis","editor.title":"Titre","editor.default_floor":"Espace initial","editor.default_floor_missing":"L’espace initial « {id} » n’existe plus. Choisissez un autre espace.","editor.floor":"Espace fixe","editor.floor_none":"— non fixé —","editor.floor_index":"Index YAML {index} (conservé)","fixed_floor.loading":"Chargement de l’espace fixe…","fixed_floor.invalid_title":"L’espace fixe est indisponible","fixed_floor.invalid_body":"Vérifiez floor dans la configuration de la carte. Valeur configurée : {value}","editor.icon_size":"Taille des icônes, % de la largeur du plan","editor.show_temperature":"Afficher la température","editor.live_states":"États en direct (on/off, ouvert…)","editor.light_pools":"Halos lumineux et ombres des murs","editor.show_signal":"Afficher le signal Zigbee (LQI)","editor.language":"Langue de l’interface","editor.lang_auto":"Auto (profil HA)","title.icon_rules":"Règles d’icônes : quelle icône MDI attribuer aux appareils selon leur nom","rules.title":"Règles d’icônes","rules.hint":"Les règles sont testées de haut en bas sur « nom de l’appareil + modèle » (expression régulière insensible à la casse) ; la première correspondance gagne. Si rien ne correspond, la classe d’appareil de l’entité est utilisée, puis l’icône générique.","rules.pattern_ph":"regex, ex. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Ajouter une règle","rules.reset":"Réinitialiser par défaut","rules.test_ph":"Tester un nom d’appareil…","rules.invalid":"expression régulière invalide","rules.saved":"Règles d’icônes enregistrées","btn.up":"Monter","btn.down":"Descendre","tap.info":"Fiche de l’appareil","tap.more_info":"Boîte de dialogue Plus d’infos de HA","tap.toggle":"Basculer l’état","marker.tap_label":"Action au toucher pour cet appareil","tap.toggle_note":"L’état déterminé est affiché ci-dessous. Les appareils sécurisés ne sont jamais basculés depuis le plan.","import.title":"Créer des espaces à partir des étages HA","import.hint":"Votre Home Assistant connaît déjà ces étages. Sélectionnez ceux à transformer en espaces du plan — vous importerez ensuite une image de plan pour chacun. Les pièces sont ensuite tracées manuellement sur le plan.","import.start":"Créer {n} espace(s)","import.manual":"Commencer de zéro","import.progress":"Étage {i} sur {n}","import.done":"Espaces créés. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","btn.skip":"Passer","space.scale_label":"Échelle (taille d’une cellule de grille)","space.cell_cm.help":"Relie la grille aux dimensions réelles : les longueurs, les surfaces, l’épaisseur des murs, la taille des ouvertures et le rayon du halo en dépendent. Une modification ultérieure change les dimensions calculées de tout l’espace sans déplacer ses points sur le plan.","space.cell_cm.help.aria":"Aide : échelle de l’espace","space.scale_unit":"cm par cellule","space.scale_unit_imperial":"po par cellule","space.display_section":"Affichage","space.show_borders":"Toujours afficher les contours des pièces","space.zero_wall_style":"Murs d’épaisseur nulle","space.zero_wall_style.help":"Les murs d’épaisseur nulle en pointillés laissent passer le halo et les rayons du soleil, tandis que les murs pleins les bloquent comme une barrière sans surface. Ce choix s’applique à tous ces murs de l’espace, même si leur ligne est masquée en mode Vue.","space.zero_wall_style.help.aria":"Aide : style des murs d’épaisseur nulle","space.zero_wall_dashed":"Pointillés","space.zero_wall_solid":"Plein","space.show_names":"Afficher les noms des pièces (faire glisser pour déplacer)","space.room_color":"Couleur du contour et du nom","space.opacity":"Opacité","space.fill_label":"Remplissage de la pièce","space.fill_mode.help":"« Couleur personnalisée » définit le style, tandis que « Lumière », « Température » et « LQI » utilisent les données actuelles de Home Assistant. Le halo s’active séparément.","space.fill_mode.help.aria":"Aide : mode de remplissage des pièces","fill.none":"Aucun","fill.lqi":"Signal Zigbee","fill.light":"Lumières","fill.custom":"Couleur personnalisée","space.custom_fill":"Couleur de remplissage","space.source_file":"J’ai une image de plan","space.source_draw":"Aucune image — je tracerai les pièces à la main","fill.temp":"Température","tip.temp_avg":"température moyenne :","tip.hum_avg":"humidité moyenne :","space_card.button":"Ouvrir le plan de l’espace","space_card.not_found":"Espace « {id} » introuvable","space_card.loading":"Chargement…","continuity.restore_plan":"Restauration du plan…","continuity.restore_connection":"Restauration de la connexion aux appareils…","continuity.retry":"Réessayer","editor.space":"Espace","editor.framing":"Cadrage","editor.fit_content":"Tout le contenu visible","editor.fit_house":"Ajusté à la géométrie de la maison","editor.show_button":"Afficher le bouton","editor.button_label":"Libellé du bouton","editor.button_target":"Chemin du tableau de bord cible","marker.sub_entity":"entité","title.general_settings":"Paramètres généraux","title.export_pdf":"Enregistrer en PDF","pdf.title":"Enregistrement en PDF","pdf.dimensions":"Afficher les dimensions et les surfaces","pdf.decor":"Afficher les meubles et les autres éléments","pdf.room_names":"Afficher les noms des pièces","pdf.backdrop":"Afficher le fond de plan","pdf.save":"Enregistrer","pdf.saving":"Création…","pdf.failed":"Impossible de créer le PDF.","pdf.too_large":"Les images dépassent la limite PDF de 25 Mo.","pdf.asset_failed":"Impossible de charger une image de fond ou de décoration.","pdf.scale":"Échelle 1:{n}","pdf.north":"Nord","gs.title":"Paramètres généraux","gs.light_group":"Remplissage : lumières","gs.light_on":"Lumières allumées","gs.light_off":"Toutes les lumières éteintes","gs.temp_group":"Remplissage : température","gs.temp_cold":"Froid","gs.temp_ok":"Confortable","gs.temp_hot":"Chaud","gs.lqi_group":"Remplissage : signal Zigbee","gs.lqi_low":"Signal faible","gs.lqi_high":"Signal fort","gs.reset":"Réinitialiser par défaut","gs.saved":"Paramètres généraux enregistrés","gs.radar_show_live":"Afficher la présence en direct sur le plan","gs.radar_show_live_hint":"Masque ou affiche toutes les cibles radar en direct. Cela ne démarre ni n’arrête l’enregistrement des observations.","radar.title":"Présence sur le plan","radar.help":"Reliez ce marqueur aux entités radar exactes de Home Assistant, placez le capteur et choisissez son profil de coordonnées. Les positions en direct sont limitées à la pièce sélectionnée.","radar.help.aria":"Aide : paramètres du radar de présence","radar.enabled":"Utiliser ce radar de présence","radar.show_live":"Afficher les cibles en direct","radar.configure":"Configurer le radar","radar.configure_on_plan":"Configurer sur le plan","radar.change_installation":"Changer l’installation","radar.no_contour":"Cette pièce n’a pas de contour. Les points radar ne seront pas limités.","radar.discard_setup_title":"Abandonner la configuration du radar ?","radar.discard_setup":"La configuration du radar non enregistrée sera perdue.","radar.step_place_mount":"Indiquez la position physique du capteur","radar.step_place_heading":"Indiquez un point droit devant le capteur","radar.step_reference":"Indiquez la position de référence {n}, puis lancez la mesure","radar.step_check_reference":"Indiquez une position de contrôle indépendante","radar.start_measure":"Lancer la mesure","radar.countdown":"Placez-vous sur le repère dans {seconds} s","radar.capturing":"Restez immobile et seul pendant la mesure…","radar.fit_ready":"Le calibrage est prêt","radar.check_third":"Vérifier à une autre position","radar.check_complete":"Contrôle indépendant terminé","radar.error_distance":"Écart de position : {distance}","radar.ambiguous_target":"Plusieurs cibles ont été signalées. Recommencez la mesure seul.","radar.insufficient_samples":"Coordonnées actuelles insuffisantes. Réessayez ou utilisez le réglage manuel.","radar.bad_references":"Choisissez des références espacées dans des directions différentes du capteur.","radar.ambiguous_sources":"Les mesures permettent deux directions également plausibles. Choisissez des repères distinguant la gauche de la droite.","radar.bad_fit":"Les mesures ne correspondent pas. Vérifiez les unités, la position du capteur et les références.","radar.desktop_hint":"Utilisez un ordinateur pour un réglage précis. L’édition sur appareils tactiles est prise en charge au mieux.","radar.detected":"House Plan a reconnu les métadonnées radar de cet appareil. Vérifiez les sources exactes avant d’enregistrer.","radar.detected_ld2450":"House Plan a trouvé un ensemble de coordonnées ESPHome LD2450. Vérifiez les sources X/Y exactes avant d’enregistrer.","radar.additional_actions":"Actions supplémentaires","radar.declare":"Ceci est un radar de présence","radar.profile":"Profil de données","radar.profile_esphome_ld2450_v1":"ESPHome LD2450 (cibles X/Y)","radar.profile_cartesian_v1":"Cibles cartésiennes (X/Y)","radar.profile_polar_v1":"Cible polaire (distance/angle)","radar.profile_range_v1":"Distance uniquement","radar.profile_zones_v1":"États des zones","radar.profile_presence_v1":"Présence uniquement","radar.room":"Pièce observée","radar.room_choose":"Choisir une pièce","radar.target":"Cible {n}","radar.axis_x":"Entité de coordonnée X","radar.axis_y":"Entité de coordonnée Y","radar.add_target":"Ajouter un emplacement de cible","radar.range_channel":"Canal de distance {n}","radar.add_range":"Ajouter un canal de distance","radar.presence_gate":"Entité de présence du canal","radar.swap_axes":"Permuter les axes X et Y","radar.axis_x_sign":"Direction X","radar.axis_y_sign":"Direction Y","radar.distance_source":"Entité de distance","radar.angle_source":"Entité d’angle","radar.angle_unit":"Unité d’angle","radar.degrees":"Degrés","radar.radians":"Radians","radar.angle_zero":"Direction de l’angle zéro","radar.angle_forward":"Vers l’avant","radar.angle_right":"Vers la droite","radar.angle_clockwise":"Les angles augmentent dans le sens horaire","radar.zone_source":"Entité de zone","radar.occupancy_source":"Entité de présence","radar.count_source":"Entité du nombre de cibles","radar.availability_source":"Entité de disponibilité","radar.source_choose":"Choisir une entité","radar.source_optional":"Facultatif","radar.source_missing":"actuellement indisponible","radar.saved_unsupported":"Cette configuration radar enregistrée est incomplète ou non prise en charge. Elle reste inactive ; supprimez-la ou mettez House Plan à jour avant de la reconfigurer.","radar.occupancy":"Présence (activée/désactivée)","radar.count":"Nombre","radar.mount":"Position et direction","radar.mount_hint":"Il s’agit de la position physique du capteur. Déplacer son marqueur décoratif ne la modifie pas.","radar.heading":"Direction, °","radar.range_cm":"Portée, cm","radar.fov_deg":"Champ de vision, °","radar.unit":"Unité de la source","radar.mirror":"Inverser l’axe gauche/droite","radar.remove":"Supprimer les paramètres radar","radar.invalid":"Renseignez la pièce, les sources et la position du radar avant d’enregistrer.","radar.check_sources":"Vérifier les données en direct","radar.checking":"Vérification…","radar.health":"État de la connexion","radar.live_summary":"Cibles actuelles : {targets} ; arcs de distance : {ranges}","radar.health_ok":"Données actuelles reçues","radar.health_off":"Aucune cible détectée","radar.health_stale":"Certaines coordonnées sont obsolètes","radar.health_partial":"Certaines sources sont à jour, d’autres sont obsolètes","radar.health_restricted":"L’accès à une ou plusieurs sources est limité","radar.health_incomplete":"Le rapport radar actuel est incomplet","radar.health_position_unavailable":"Présence signalée ; position actuelle indisponible","radar.health_unavailable":"Données du capteur indisponibles","radar.health_needs_setup":"L’installation doit être configurée","radar.health_inconsistent":"Les sources fournissent des valeurs contradictoires","radar.health_unknown":"L’état actuel est inconnu","radar.health_disabled":"Le radar est désactivé","radar.error_invalid_radar":"Vérifiez les paramètres radar.","radar.error_invalid_selection":"Sélectionnez une pièce existante et des sources valides.","radar.error_source_restricted":"Vous n’avez pas accès à toutes les sources sélectionnées.","radar.error_rate_limited":"Trop de demandes. Réessayez dans un instant.","radar.error_not_ready":"Le traitement radar n’est pas encore prêt.","radar.error_conflict":"Le plan a changé. Rouvrez la configuration radar et réessayez.","radar.error_source_unavailable":"Une ou plusieurs sources radar sélectionnées sont indisponibles.","radar.error_unsupported_capability":"Cette fonction radar n’est pas prise en charge par l’intégration installée.","radar.report_age":"il y a {seconds} s","space.show_lqi":"Afficher le signal Zigbee (LQI) à côté des appareils","space.hide_decor":"Masquer la couche décorative","space.hide_decor_tip":"Les lignes, formes, étiquettes et meubles restent à leur place — visibles dans l’éditeur d’arrière-plan, mais pas sur le plan.","space.hide_openings":"Masquer les ouvertures","space.hide_openings_tip":"Les symboles de portes, fenêtres et portails ne sont pas dessinés, mais les ouvertures continuent de fonctionner : la lumière les traverse, le soleil entre par les fenêtres et les capteurs de contact continuent de les ouvrir. L’éditeur de plan les affiche toujours.","gs.light_none":"Aucune source lumineuse","mode.plan":"Éditeur de plan","mode.devices":"Éditeur d’appareils","display.value":"Valeur + état","marker.subarea":"aucune zone, manuel","device.new":"Nouvel appareil — ouvrez son éditeur pour fermer","opening.unlock_action":"Déverrouiller","opening.lock_action":"Verrouiller","opening.lock_pending":"En cours…","title.close_editor":"Fermer l’éditeur (retour à la vue)","title.add_device":"Ajouter un appareil au plan","devbar.add":"Ajouter","devbar.rules":"Règles d’icônes","device_inbox.button":"Appareils","device_inbox.title":"Appareils sur le plan","device_inbox.search":"Rechercher appareils, entités et intégrations…","device_inbox.add_virtual":"Ajouter un appareil virtuel","device_inbox.tab_on_plan":"Sur le plan","device_inbox.tab_available":"Disponibles","device_inbox.tab_hidden":"Masqués","device_inbox.tab_readd":"De nouveau disponibles","device_inbox.only_new":"Nouveaux uniquement","device_inbox.show_entities":"Afficher les entités","device_inbox.show_hidden":"Afficher les masqués sur le plan","device_inbox.show_hidden.help":"Affiche temporairement les marqueurs masqués et désactivés sous forme de fantômes réservés à l’éditeur. La visibilité enregistrée des appareils ne change pas.","device_inbox.show_hidden.help.aria":"Aide : afficher les appareils masqués sur le plan","device_inbox.new":"Nouveau","device_inbox.find":"Trouver sur le plan","device_inbox.edit":"Modifier","device_inbox.hide":"Masquer","device_inbox.show":"Afficher","device_inbox.add":"Ajouter","device_inbox.readd":"Ajouter à nouveau","device_inbox.hide_available":"Masquer de la liste","device_inbox.show_more":"Afficher plus","device_inbox.more_actions":"Plus d'actions","device_inbox.find_hidden_hint":"Activez d'abord « Afficher les masqués sur le plan »","device_inbox.show_disabled":"Activez cette liaison dans Home Assistant avant de l'afficher","device_inbox.empty_on_plan":"Aucun appareil correspondant n'est encore sur le plan.","device_inbox.empty_available":"Aucun appareil disponible à ajouter.","device_inbox.empty_hidden":"Il n'y a aucun appareil masqué.","device_inbox.empty_readd":"Aucun appareil supprimé n'est disponible pour un nouvel ajout.","device_inbox.reason_visible_auto":"Découvert automatiquement","device_inbox.reason_visible_explicit":"Ajouté explicitement","device_inbox.reason_manual_hidden":"Masqué par l'utilisateur","device_inbox.reason_automatic_hidden":"Masqué automatiquement","device_inbox.reason_service_entry":"Entrée de registre de service uniquement","device_inbox.reason_excluded_integration":"Intégration « {integration} » exclue par les filtres de découverte","device_inbox.reason_excluded_domain":"Type d'entité non spatial","device_inbox.reason_grouped_light":"Représenté par un groupe de lumières de la pièce","device_inbox.reason_represented_by_parent":"Représenté par son appareil parent","device_inbox.reason_removed":"Précédemment retiré du plan","device_inbox.reason_available":"Disponible pour ajout au plan","device_inbox.reason_no_bound_room":"La zone HA n'est liée à aucune pièce du plan","device_inbox.status_ha_disabled":"Désactivé dans Home Assistant","device_inbox.status_orphaned":"La liaison n'existe plus dans Home Assistant","device_inbox.status_unverified":"Le registre Home Assistant est temporairement indisponible","device_inbox.saved":"Liste des appareils mise à jour","device_inbox.filters_excluded":"Intégrations exclues","device_inbox.filters_group_lights":"Regrouper les lumières de la pièce en un marqueur","device_inbox.filters_preview_appear":"apparaîtra : {count}","device_inbox.filters_preview_hide":"disparaîtra : {count}","device_inbox.filters_preview_lights":"lumières concernées : {count}","device_inbox.filters_reset":"Rétablir les recommandées","device_inbox.filters_save":"Enregistrer les filtres","device_inbox.filters_search_ph":"Ajouter une intégration…","device_inbox.filters_title":"Filtres de découverte","space.roomcard_section":"La carte de pièce affiche :","space.label_temp":"Température","space.label_hum":"Humidité","space.label_lqi":"Signal Zigbee moyen","space.label_light":"Lumières allumées/éteintes","roomcard.light_on":"Allumé","roomcard.light_off":"Éteint","roomcard.light_partial":"{on} sur {total}","toast.split_pick_inside":"Les points intermédiaires de découpe doivent se trouver à l’intérieur de la pièce","mode.decor":"Éditeur d’arrière-plan","decor.select":"Sélectionner","decor.line":"Ligne","decor.rect":"Rectangle","decor.ellipse":"Ovale","decor.text":"Texte","decor.erase":"Effacer","decor.erase_confirm_title":"Effacer l’objet ?","decor.color":"Couleur","decor.width":"Épaisseur de ligne","decor.line_style":"Style de ligne","decor.line_style_solid":"Plein","decor.line_style_dashed":"Pointillés","decor.fill":"Remplissage","decor.fill_color":"Couleur de remplissage","decor.length":"Longueur","decor.size":"Taille","decor.flip_h":"Retourner horizontalement","decor.flip_v":"Retourner verticalement","decor.angle":"Angle de rotation, °","decor.text_size":"Taille du texte","decor.backdrop_properties":"Propriétés de l’arrière-plan du plan","decor.text_title":"Étiquette de texte","decor.object_title":"Modifier {kind}","decor.text_label":"Texte","decor.live_group":"Insérer une variable HA","decor.live_entity":"Entité","decor.live_entity_ph":"choisir une entité","decor.live_attr":"Valeur","decor.live_attr_ph":"choisir l’état ou un attribut","decor.live_state":"État","decor.backdrop":"Image d’arrière-plan","decor.backdrop_hint":"Faites glisser pour déplacer ; tirez un coin pour redimensionner ; utilisez la poignée supérieure pour faire pivoter. Maj modifie les proportions ou libère l’angle.","decor.backdrop_reset":"Réinitialiser l’image","decor.backdrop_reset_done":"L’image a retrouvé sa position et sa taille d’origine","marker.icon_auto":"Auto : {icon} (selon les règles d’icônes ; choisissez-en une pour remplacer)","marker.icon_pin_auto":"Épingle","mode.plan_tip":"Éditeur de plan — la géométrie du logement : dessiner et diviser/fusionner les pièces, les associer aux zones HA, placer portes, fenêtres et portails, déplacer les cartes de pièces, régler l’échelle","mode.devices_tip":"Éditeur d’appareils — tout ce qui concerne les icônes : faire glisser pour positionner, cliquer pour modifier l’association/l’icône/l’affichage, ajouter des appareils virtuels, règles d’icônes","mode.decor_tip":"Éditeur d’arrière-plan — décoration purement visuelle sous le plan : lignes, rectangles, ovales et étiquettes de texte qui ne réagissent jamais aux clics","space.glow_enabled":"Halo des sources lumineuses","gs.glow_group":"Halo des sources lumineuses","gs.glow_base":"Obscurité de la maison","gs.glow_light":"Couleur / intensité de lumière par défaut","gs.wall_group":"Murs","gs.wall_fill":"Remplissage des murs","gs.glow_radius":"Rayon du halo","gs.glow_radius.help":"Définit le rayon général du halo en mètres ou en pieds ; le rayon propre à un appareil remplace cette valeur.","gs.glow_radius.help.aria":"Aide : rayon général du halo","gs.unit_m":"m","gs.unit_ft":"pi","marker.controls_label":"Contrôle d’autres sources lumineuses","marker.controls.help":"Avec l’action « Basculer l’état », les sources répertoriées basculent avec ce marqueur. Leur halo reste sur leurs propres marqueurs et ce lien ne transforme pas à lui seul le marqueur de contrôle en source lumineuse.","marker.controls.help.aria":"Aide : contrôler d’autres sources lumineuses","marker.controls_filter":"Rechercher des lumières et interrupteurs…","info.controls":"Contrôle","marker.glow_radius_label":"Rayon du halo","marker.glow_radius.help":"Définit le rayon du halo en mètres ou en pieds ; une valeur vide utilise le rayon des paramètres généraux.","marker.glow_radius.help.aria":"Aide : rayon du halo","markup.wallthick":"Épaisseur","markup.select":"Sélectionner","title.markup_wallthick":"Épaisseur — cliquez sur un mur pour définir son épaisseur de 0 à 100 cm.","markup.hint_wallthick":"cliquez sur un mur · Échap ferme sans appliquer","wallthick.field":"Épaisseur","wallthick.unit_cm":"cm","wallthick.unit_in":"po","wallthick.apply_room":"Appliquer à tous les murs de cette pièce","markup.draw_wall_title":"Épaisseur de chaque nouveau segment de mur (0–100 cm). Les murs partagés conservent la valeur existante.","room.queue_progress":"Pièce {current} sur {total}","toast.wall_rooms_saved":"Pièces créées : {n}","toast.wall_chain_saved":"Chaîne de murs enregistrée","toast.wallthick_pick":"Cliquez sur un mur","toast.wallthick_set":"Épaisseur du mur définie","toast.wallthick_cleared":"Épaisseur du mur supprimée","toast.physical_range":"Saisissez une valeur comprise entre {min} et {max} {unit}","toast.zero_wall_opening_conflict":"Supprimez d’abord l’ouverture sur ce segment de mur.","toast.zero_wall_ambiguous":"Le segment de mur est ambigu. Simplifiez ou ajustez la jonction.","toast.zero_wall_migration_blocked":"L’espace n’a pas été converti : {reason}. Aucune donnée n’a été modifiée.","toast.physical_angle":"Saisissez un angle de rotation compris entre 0° inclus et 90° exclu","toast.physical_limit":"L’espace a atteint la limite pour ce type de géométrie","toast.geometry_unsafe":"Modification annulée : la géométrie des murs n’a pas pu être construite en toute sécurité.","junction.limit_angle":"L'angle entre les murs est trop aigu : {actual}°, minimum {limit}°.","junction.limit_valence":"Trop de murs se rejoignent en un nœud : {actual}, maximum {limit}.","junction.limit_length":"Le segment de mur est trop court : {actual} cm, minimum {limit} cm.","junction.limit_distance":"Les murs et les nœuds sont trop proches : {actual} cm, minimum {limit} cm.","junction.limit_clearance":"Il ne reste plus d'intérieur de pièce : {actual} cm², minimum {limit} cm².","junction.limit_check_failed":"La vérification des jonctions n'a pas pu s'exécuter — la modification n'a pas été enregistrée","toast.wall_model_migration_blocked":"Le modèle de murs n’a pas pu être mis à jour : {reason}. Le plan n’a pas été modifié. Lancez « Optimiser les plans » ; si l’erreur se reproduit, corrigez la géométrie de mur conflictuelle.","toast.wall_model_client_outdated":"Mettez à jour la carte et rechargez la page avant de modifier le plan.","wall_model.reason.invalid-room":"contour de pièce invalide","wall_model.reason.zero-length":"segment de mur de longueur nulle","wall_model.reason.third-owner":"mur partagé par plus de deux pièces","wall_model.reason.duplicate-id":"identifiants de mur en conflit","wall_model.reason.thickness-conflict":"valeurs d’épaisseur de mur en conflit","wall_model.reason.opening-host":"l’ouverture ne peut pas être attribuée à un seul mur","toast.delete_room_pick":"Cliquez à l’intérieur de la pièce que vous souhaitez supprimer","toast.plan_snap_ambiguous":"Zoomez pour choisir le nœud du mur","toast.wall_repair_ambiguous":"Le contour de la pièce possède plusieurs connexions possibles. Zoomez et reliez-le explicitement.","toast.wall_repair_too_large":"L’écart dépasse 2 cm. Reliez les murs avant de créer la pièce.","toast.wall_repair_changed":"La géométrie des murs a changé. Essayez de créer de nouveau la pièce.","toast.opening_on_zero_wall":"Les ouvertures ne peuvent pas être placées sur un mur d’épaisseur nulle","marker.from_ha_option":"Choisir dans la liste HA","marker.show_entities":"Afficher les entités","marker.show_entities_tip":"Ajoute à la liste non seulement les appareils, mais aussi toutes leurs entités","marker.pick_ph":"Choisir un appareil…","room.open_area":"Ouvrir la zone HA","room.fit_action":"Ajuster la pièce {name}","view.volumetric":"Vue volumétrique","view.flat":"Vue plane","kiosk.title":"Tailles pour cet écran","kiosk.hint":"Enregistrées uniquement sur cet appareil — chaque tablette murale ou TV peut avoir ses propres tailles confortables.","kiosk.icon_scale":"Taille des icônes d’appareils","kiosk.font_scale":"Taille du texte des cartes de pièces","editor.kiosk":"Mode appareil mural (kiosque)","editor.cycle":"Changer automatiquement d’espace toutes les N secondes (kiosque, 0 = désactivé)","room.settings_title":"Paramètres de la pièce","room.settings_section":"Paramètres de la pièce (remplacent ceux de l’espace)","room.fill_label":"Remplissage de CETTE pièce","fill.inherit":"Comme l’espace","room.custom_fill_space":"Couleur de l’espace","room.custom_fill_own":"Couleur de la pièce","room.temp_range_label":"Plage de confort","room.temp_range_min":"Limite basse de température confortable","room.temp_range_max":"Limite haute de température confortable","room.temp_range_reset":"Comme l’espace","room.temp_range.help":"Cette plage s’applique uniquement à cette pièce. Un champ vide hérite de la limite correspondante de l’espace ; si les limites sont inversées, House Plan utilise la plus petite comme limite basse et la plus grande comme limite haute.","room.temp_range.help.aria":"À propos de la plage de confort de la pièce","room.temp_src_label":"Source de température","room.hum_src_label":"Source d’humidité","room.src_average":"Moyenne des capteurs de la pièce (par défaut)","room.src_pick":"Un appareil ou une entité HA spécifique","room.src_ph":"Choisir une source…","toast.room_updated":"Pièce mise à jour","space.card_font":"Taille de police des cartes de pièces (tout l’espace)","room.sizes_section":"Tailles de police","room.name_scale":"Taille du nom de la pièce","room.label_scale":"Taille des mesures","preview.room_name":"Salon","toast.cfg_reload_failed":"Impossible de recharger le plan depuis le serveur : {err}","toast.locale_load_failed":"Impossible de charger le pack de langue. L'anglais est utilisé jusqu'au rechargement de la page.","toast.furniture_art_load_failed":"Impossible de charger les dessins de meubles. Rechargez la page pour les afficher.","room.settings_short":"Paramètres de la pièce","room.unnamed":"Pièce sans nom","marker.use_climate_temp":"Inclure la température de l’appareil dans la pièce","marker.use_climate_temp_tip":"Ajoute la valeur current_temperature d’un climatiseur ou thermostat à la moyenne de la pièce. Configurez séparément le badge de valeur externe ci-dessous.","marker.value_badge_title":"Badge de valeur","marker.value_badge.help":"Affiche une valeur sélectionnée à côté de l’icône. Cela n’affecte pas les mesures de la pièce, la lumière, le halo ni l’action au toucher.","marker.value_badge.help.aria":"Aide : badge de valeur de l’appareil","marker.value_badge_enabled":"Afficher un badge de valeur","marker.value_badge_source":"Valeur","marker.value_badge_source.help":"Choisissez un état précis, un attribut pris en charge ou une valeur dérivée de cet appareil.","marker.value_badge_source.help.aria":"Aide : source du badge de valeur","marker.value_badge_position":"Position","marker.value_badge_position.help":"Le côté choisi reste fixe et ne bascule pas automatiquement au bord du plan.","marker.value_badge_position.help.aria":"Aide : position du badge de valeur","marker.value_badge_right":"À droite","marker.value_badge_bottom":"En dessous","marker.value_badge_left":"À gauche","marker.value_badge_top":"Au-dessus","marker.value_badge_empty":"Cet appareil n’a aucune valeur disponible","marker.value_badge_static":"Une icône statique n’affiche pas de valeurs en direct. Le paramètre est conservé.","marker.value_badge_missing":"Source indisponible","marker.value_badge_missing_hint":"La source enregistrée est actuellement indisponible. Conservez-la, désactivez le badge ou choisissez une autre valeur.","marker.value_badge_duplicate":"La même valeur est déjà affichée dans l’icône.","marker.value_badge_state":"État · {name}","marker.value_badge_marker_state":"État de la source lumineuse · {name}","marker.value_badge_lqi":"Qualité moyenne du signal Zigbee","marker.value_badge_attr_current_temperature":"Température actuelle · {name}","marker.value_badge_attr_temperature":"Température cible · {name}","marker.value_badge_attr_current_humidity":"Humidité actuelle · {name}","marker.value_badge_attr_humidity":"Humidité · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Vitesse · {name}","marker.value_badge_attr_brightness":"Luminosité · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Batterie · {name}","marker.value_badge_attr_fan_speed":"Vitesse du ventilateur · {name}","marker.value_source":"Source de la valeur","marker.value_source.help":"Choisissez la valeur qui remplace l’icône. L’action au toucher ne change pas.","marker.value_source.help.aria":"Aide : source de la valeur dans le marqueur","marker.value_source_auto":"Automatique (comme avant)","marker.value_source_missing_hint":"La source enregistrée est indisponible. Le marqueur affiche — jusqu’à son retour ou jusqu’au choix d’une autre valeur.","marker.light_role_label":"Cet appareil est-il une source lumineuse ?","marker.light_role.help":"« Auto » utilise le rôle déterminé de l’appareil lié, « Toujours » force sa propre source et « Jamais » l’exclut ; les lumières liées ci-dessus restent indépendantes.","marker.light_role.help.aria":"Aide : cet appareil est-il une source lumineuse","marker.light_role_auto_yes":"Auto (source lumineuse)","marker.light_role_auto_no":"Auto (pas une source lumineuse)","marker.light_role_always":"Toujours une source lumineuse","marker.light_role_never":"Jamais une source lumineuse","marker.light_entity_label":"Entité lumineuse principale","marker.light_entity.help":"Pour un appareil composite, choisissez l’entité dont l’état, la couleur et la luminosité représentent cette source sur le plan. Le choix automatique reste compatible avec les anciens plans.","marker.light_entity.help.aria":"Aide : entité lumineuse principale","marker.light_entity_auto":"Automatique ({entity})","marker.light_entity_none":"aucune entité contrôlable","marker.light_entity_missing":"L’entité enregistrée {entity} est indisponible. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.toggle_entity_label":"Entité à basculer","marker.toggle_entity.help":"Pour un appareil composite, choisissez précisément la lumière ou l’interrupteur propre à actionner par un toucher. Automatique conserve les règles de cible précédentes et reste indépendant de l’entité lumineuse principale.","marker.toggle_entity.help.aria":"Aide : entité à basculer","marker.toggle_entity_auto":"Automatique ({entity})","marker.toggle_entity_none":"aucune entité propre contrôlable","marker.toggle_entity_missing":"L’entité enregistrée {entity} ne fait plus partie des canaux sélectionnables de ce marqueur. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.glow_color_label":"Couleur et luminosité du halo","marker.glow_mode.help":"Utilisez les valeurs en direct de la source, remplacez uniquement sa couleur ou fixez à la fois la couleur et la luminosité. Le minimum est 1 % ; pour désactiver la source, choisissez « Jamais ».","marker.glow_mode.help.aria":"Aide : couleur et luminosité du halo","marker.glow_mode_auto":"Depuis la source","marker.glow_mode_color":"Définir la couleur","marker.glow_mode_fixed":"Définir la couleur et la luminosité","marker.glow_color":"Couleur du halo","marker.glow_brightness":"Luminosité","marker.glow_disabled_never":"Les paramètres du halo sont indisponibles car ce marqueur est explicitement défini comme n’étant pas une source lumineuse.","marker.glow_disabled_auto":"Le mode Auto n’a trouvé aucune source lumineuse spatiale pour ce marqueur.","marker.glow_disabled_no_entity":"Aucune entité Home Assistant contrôlable et active n’est disponible pour cette source spatiale.","marker.glow_passive_hint":"Cette source ne possède aucune donnée Home Assistant propre. Définissez manuellement sa couleur et sa luminosité ; son rayon reste disponible.","marker.control_broken":"La source enregistrée est absente ou n’est plus marquée comme lumière","marker.control_missing_label":"Lumière du plan manquante","marker.control_passive":"source passive","toast.marker_control_cycle":"Ce lien créerait une chaîne circulaire de contrôles de lumière.","toast.marker_binding_required":"Choisissez un appareil Home Assistant avant de lier une autre source lumineuse.","confirm.unlock_title":"Déverrouiller ?","confirm.unlock_body":"House Plan enverra une commande de déverrouillage à cette serrure.","toast.files_migrate_failed":"Les pièces jointes n’ont pas pu être déplacées vers la nouvelle association ; les liens continuent de pointer vers les anciens fichiers : {err}","space.pick_saved":"Déjà importé","space.pick_saved_hint":"Plans stockés sur le serveur, y compris ceux que vous avez précédemment dissociés","space.no_saved":"Aucun plan n’est encore stocké sur le serveur.","space.loading":"Chargement…","space.used_by":"utilisé par : {list}","space.in_use":"Un espace utilise encore ce plan — dissociez-le d’abord","btn.use":"Utiliser","confirm.delete_plan_title":"Supprimer le fichier du plan ?","confirm.delete_plan_body":"Le fichier sera supprimé du serveur. Cette action est irréversible.","toast.plans_list_failed":"Impossible de lister les plans stockés : {err}","toast.plan_delete_failed":"Impossible de supprimer le plan : {err}","marker.hide":"Masquer","marker.hide_tip":"L’appareil disparaîtra du plan après l’enregistrement mais continuera de compter dans le signal de la pièce. Restaurez-le via « Masqués et désactivés » dans l’éditeur d’appareils.","marker.show":"Afficher","marker.show_tip":"L’appareil apparaîtra de nouveau sur le plan après l’enregistrement.","marker.hidden_ghost":"Appareil masqué par l’utilisateur","marker.ha_disabled_device":"L’appareil est désactivé dans Home Assistant et masqué du plan.","marker.ha_disabled_entity":"L’entité est désactivée dans Home Assistant et masquée du plan.","marker.ha_disabled_all_entities":"L’appareil n’a aucune entité Home Assistant active ; il est donc masqué du plan.","marker.ha_registry_limited":"Le registre Home Assistant complet n’est pas accessible à cet utilisateur. L’objet non vérifié ne peut pas être affiché ni utilisé pour le moment.","marker.delete_tip":"Supprimer complètement l’appareil du plan et de tous les agrégats. Vous pourrez l’ajouter de nouveau plus tard.","tap.run":"Exécuter une automatisation/un script/une scène","tap.none":"Ne rien faire","marker.run_target_label":"Élément à exécuter","marker.run_search_ph":"Rechercher : automatisation, script ou scène…","marker.run_target_gone":"Cible {id} introuvable — choisissez-en une autre","marker.tap_confirm":"Demander une confirmation","marker.tap_confirm_tip":"Afficher une boîte de dialogue de confirmation avant l’action — protection contre les appuis accidentels.","marker.toggle_hint_single":"Cible : {name} ({id}).","marker.virtual_light_target":"Lumière virtuelle : {name}.","marker.virtual_light_current":"État manuel : {state} → {effect}.","marker.virtual_light_state_on":"allumé","marker.virtual_light_state_off":"éteint","marker.toggle_hint_group":"Basculera {count} source(s) : {names}.","marker.toggle_hint_current":"Actuellement : {state} → {effect}.","marker.toggle_hint_group_current":"Actuellement allumées : {on} sur {count} → {effect}.","marker.toggle_hint_skipped":"Seront ignorées ({count}) : {targets}.","marker.toggle_effect_turn_on":"sera allumé","marker.toggle_effect_turn_off":"sera éteint","marker.toggle_effect_open":"sera ouvert","marker.toggle_effect_close":"sera fermé","marker.toggle_effect_stop":"sera arrêté","marker.toggle_effect_toggle":"l’état sera basculé","marker.toggle_skip_missing":"introuvable","marker.toggle_skip_ha_disabled":"désactivé dans HA","marker.toggle_skip_unavailable":"indisponible","marker.toggle_skip_unsupported":"basculement non pris en charge","marker.toggle_skip_secure":"bloqué pour des raisons de sécurité","marker.toggle_none_no_binding":"Cet appareil n’a aucune association ; il n’y a donc aucun état à basculer. Un toucher ne fera rien.","marker.toggle_none_no_actionable_entity":"Cet appareil n’a aucun état pouvant être basculé. Un toucher ne fera rien.","marker.toggle_none_configured_targets_missing":"Les cibles configurées sont indisponibles. L’entité propre de l’appareil ne leur sera pas substituée.","marker.toggle_none_ha_disabled":"La cible est désactivée dans Home Assistant et ne peut pas être utilisée sur le plan.","marker.toggle_none_unavailable":"La cible est actuellement indisponible. Un toucher ne fera rien.","marker.toggle_none_unsupported":"Home Assistant n’expose aucune opération de basculement sûre pour cette entité. Un toucher ne fera rien.","marker.toggle_none_secure":"Le basculement des serrures, alarmes et portails sécurisés depuis le plan est bloqué pour des raisons de sécurité.","run.automation":"automatisation","run.script":"script","run.scene":"scène","confirm.tap_run":"Exécuter « {name} » ?","confirm.tap_toggle":"Basculer « {name} » ?","confirm.current_state":"État actuel : {state}","confirm.expected_state":"Après basculement : {state}","confirm.group_current":"{on} allumé(s) sur {total}","confirm.group_all_on":"tout est allumé","confirm.group_all_off":"tout est éteint","confirm.unavailable_targets":"Indisponibles : {count}","confirm.expected_by_ha":"Home Assistant déterminera l’état","confirm.state_on":"Allumé","confirm.state_off":"Éteint","confirm.state_open":"Ouvert","confirm.state_closed":"Fermé","confirm.state_opening":"Ouverture en cours","confirm.state_closing":"Fermeture en cours","confirm.state_stopped":"Arrêté","confirm.state_unknown":"Inconnu","toast.run_started":"Démarré : {name}","toast.run_target_missing":"Cible d’exécution introuvable — vérifiez les paramètres de l’appareil","toast.run_target_required":"Choisissez une automatisation, un script ou une scène","toast.tap_target_changed":"La cible de l’action a changé. Réessayez.","toast.virtual_light_toggle_failed":"Impossible de basculer la lumière virtuelle : {err}","toast.value_badge_source_required":"Choisissez une valeur pour le badge","btn.run":"Exécuter","vac.section":"Robot aspirateur : position en direct","vac.autocal":"Configurer automatiquement","vac.live":"Position en direct sur le plan","vac.trail":"Afficher le trajet du robot","vac.autocal_no_rooms":"L’intégration ne fournit aucune liste de pièces — ouvrez « Ajuster manuellement »","vac.route_warn_unmapped":"Le robot nettoie une carte qui n'est assignée à aucun étage","vac.route_warn_needs_calibration":"La carte est assignée à un étage mais n'est pas calibrée","vac.route_warn_ambiguous":"Deux cartes sont indiscernables — aucun étage choisi","vac.route_warn_missing_space":"L'espace de cette carte a été supprimé","vac.autocal_no_match":"Les noms de pièces ne correspondent pas (il en faut ≥3 en commun) — ouvrez « Ajuster manuellement »","vac.autocal_done":"Terminé : association via {rooms} pièces. Lancez un nettoyage et vérifiez","vac.cal_need_pos":"Le robot ne transmet pas de coordonnées — lancez un nettoyage puis mettez-le en pause","vac.cal_done":"Calibration enregistrée. Lancez un nettoyage et vérifiez","vac.cal_cancelled":"Calibration annulée","vac.fit":"Ajuster manuellement","vac.fit_hint":"Faites glisser la carte du robot pour la positionner, étirez-la par les coins","vac.fit_rotate":"Rotation de 90°","vac.fit_mirror":"Miroir","vac.trail_never":"Jamais","vac.trail_cleaning":"Pendant le nettoyage","vac.trail_always":"Toujours","gs.bg_group":"Arrière-plan de la scène","gs.bg_color":"Arrière-plan autour du plan","gs.bg_default":"Valeur par défaut du thème","gs.bg_theme":"valeur par défaut du thème","gs.bg_mode":"Arrière-plan du plan","gs.bg_mode.help":"« Suit le soleil » utilise sun.sun ou, à défaut, l’heure locale du navigateur ; « Couleur statique » affiche toujours la couleur choisie.","gs.bg_mode.help.aria":"Aide : arrière-plan général du plan","gs.bg_static":"Couleur statique","gs.bg_daynight":"Suit le soleil","gs.sun_group":"Soleil","gs.sun_missing":"L’entité sun.sun est introuvable — l’arrière-plan suit votre heure locale ; les rayons de soleil par les fenêtres sont indisponibles.","gs.north":"Nord sur le plan","gs.north.help":"L’angle se mesure dans le sens horaire depuis la verticale supérieure du plan ; le nord sert aux rayons des fenêtres, pas à l’arrière-plan « Suit le soleil ».","gs.north.help.aria":"Aide : direction générale du nord","gs.north_ph":"non défini","gs.north_clear":"Effacer","gs.north_letter":"N","gs.sun_rays":"Lumière du soleil à travers les fenêtres","gs.sun_ray_origin":"Rayons du soleil","gs.sun_ray_origin.inner":"Depuis les angles intérieurs des fenêtres","gs.sun_ray_origin.outer":"Depuis les angles extérieurs des fenêtres","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · documentation et problèmes","gs.about_telegram":"Discussion Telegram","support.title":"Aide et commentaires","space.bg_color":"Arrière-plan autour du plan","space.bg_inherit":"Hériter des paramètres généraux","space.bg_inherited":"hérite des paramètres généraux","space.bg_mode":"Arrière-plan du plan","space.bg_mode.help":"Héritez de l’arrière-plan général ou remplacez-le pour cet espace par une couleur statique ou le mode « Suit le soleil ».","space.bg_mode.help.aria":"Aide : arrière-plan de l’espace","space.north":"Nord sur le plan (remplacement)","space.north.help":"Remplace le nord général pour cet espace ; l’angle se mesure dans le sens horaire depuis la verticale supérieure du plan et sert aux rayons des fenêtres.","space.north.help.aria":"Aide : nord de cet espace","space.north_inherited":"hérité : {v}","space.sun_rays":"Lumière du soleil à travers les fenêtres","space.sun_inherit":"Hériter des paramètres généraux","space.sun_on":"Activé","space.sun_off":"Désactivé","canvas.far_objects":"{n} objet(s) éloigné(s) du plan","canvas.show_far":"Afficher","canvas.home_tip":"Le plan est là-bas — cliquez pour l’ajuster à l’écran","gs.grid_group":"Maintenance du plan","gs.grid_hint":"Met à jour les modèles de données, aligne les éléments du plan sur la grille et fusionne les fragments de murs redondants. Un rapport précis est affiché avant tout enregistrement.","gs.align_all":"Optimiser les plans","gs.align_title":"Optimiser les plans","gs.align_none":"Tous les plans utilisent déjà le modèle de données optimisé actuel.","gs.optimize_no_automatic_changes":"Aucune modification automatique n’est à appliquer. Vérifiez les éléments ci-dessous.","gs.align_count":"{n} élément(s) sur {total} seront déplacés, de {cm} cm au maximum.","gs.align_where":"Le plus grand déplacement se trouve dans « {s} ».","gs.align_turned":"Ouvertures dont l’angle est corrigé : {n}.","gs.align_preflight_failed":"Impossible de vérifier en toute sécurité la géométrie des espaces suivants : {spaces}{more}.","gs.align_preflight_hint":"Les plans n’ont pas été modifiés. Copiez les diagnostics avec le bouton ci-dessous et joignez-les au rapport de bug avec un export de l’espace.","gs.preflight_reason_prepare-exception":"Impossible de préparer la géométrie de l’espace (exception lors de la construction du modèle)","gs.preflight_reason_wall-null":"Le corps du mur n’a pas pu être construit (l’union a renvoyé un résultat vide)","gs.preflight_reason_wall-degraded-extra":"Le corps du mur s’est dégradé avec une géométrie supplémentaire","gs.preflight_reason_wall-failed-core":"Le noyau du corps du mur n’a pas pu être assemblé","gs.preflight_reason_wall-exception":"La construction du mur a déclenché une exception","gs.preflight_reason_floor-null":"Le contour du sol n’a pas pu être construit","gs.preflight_reason_floor-exception":"La construction du sol a déclenché une exception","gs.preflight_copy":"Copier les diagnostics","gs.preflight_copied":"Diagnostics copiés","gs.preflight_update_hint":"Les versions de la carte et de l’intégration diffèrent — mettez House Plan à jour puis réessayez.","gs.align_preflight_space":"Espace {n}","gs.align_preflight_more":", et {n} de plus","gs.optimize_changes":"Migrations de modèle : {m} ; espaces mis à jour : {c} ; valeurs de coordonnées parasites supprimées : {p} ; fragments de murs réels fusionnés : {w} ; fragments de murs d’épaisseur nulle fusionnés : {s} ; murs indépendants : {i}.","gs.zero_walls_migrated":"Portions de murs virtuels converties : {n}.","gs.wall_segments_migrated":"Segments de murs stabilisés : {n}.","gs.room_drafts_migrated":"Contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","gs.optimize_lattice_summary":"Valeurs de coordonnées parasites normalisées : {n} ; déplacement maximal : {cm} cm.","gs.optimize_lattice_space":"{space} : valeurs de coordonnées normalisées : {n} ; valeurs hors grille laissées inchangées : {far}.","gs.optimize_coincident_partitions":"Sections de murs indépendants masquées absorbées dans les murs des pièces : {n}.","gs.optimize_openings_rehosted":"Ouvertures rattachées aux murs des pièces : {n}.","gs.optimize_walls_straightened":"Murs redressés : {n} ; déplacement maximal : {cm} cm.","gs.optimize_walls_straightened_where":"Plus grande correction de mur : {s}.","gs.optimize_walls_straighten_skipped":"Murs proches d’un axe laissés inchangés car ils ne pouvaient pas être réparés en toute sécurité : {n}.","gs.optimize_glow_migration":"Ancien mode Glow : {spaces} espaces → aucun remplissage de données + Glow indépendant ; {rooms} pièces → remplissage de données hérité + Glow indépendant.","gs.optimize_references":"Références réparées : espaces — {spaces} ; pièces — {rooms} ; positions — {positions} ; appareils dissociés des espaces manquants — {detached}.","gs.optimize_reference_more":", et {n} de plus","gs.optimize_orphans_removed":"Enregistrements oubliés supprimés : {total} — étiquettes de pièces : {rooms} ; appareils : {devices} ; marqueurs de groupe : {groups}. Ils appartenaient à des espaces supprimés précédemment.","gs.optimize_live_positions":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles seront conservées.","gs.optimize_live_positions_remove":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles sont sélectionnées pour suppression.","gs.optimize_live_names":" : {names}{more}","gs.optimize_live_remove":"Supprimer les anciennes positions","gs.optimize_live_keep":"Conserver les anciennes positions","gs.optimize_live_selected":"Les anciennes positions seront supprimées après l’application de l’optimisation.","gs.optimize_unverified":"Impossible de vérifier en toute sécurité les positions : {n}. Elles ont été laissées inchangées.","gs.optimize_registry_limited":"Un accès administrateur complet aux registres Home Assistant est requis pour une vérification sûre.","gs.optimize_vacuum_warning":"Associations de pièces d’aspirateur nécessitant encore une vérification : {n}.","gs.optimize_details":"Détails","gs.optimize_details_more":"Et {n} enregistrement(s) de plus.","gs.optimize_detail_removed":"sera supprimé","gs.optimize_detail_live":"sera conservé","gs.optimize_detail_unverified":"non vérifié","gs.optimize_detail_room_label":"étiquette de pièce","gs.optimize_detail_device":"appareil","gs.optimize_detail_group":"marqueur de groupe","gs.optimize_detail_unknown":"propriétaire inconnu","gs.optimize_detail_item":"{status} : {kind} {id} ; ancien espace {space}","gs.align_warn":"Les éléments volontairement placés entre les nœuds de la grille seront déplacés. Une seule annulation est disponible après l’opération, uniquement jusqu’à la prochaine modification du plan.","gs.align_run":"Optimiser","gs.align_done":"Plans optimisés : {n} élément(s) déplacé(s), {m} enregistrement(s) maintenu(s), {r} référence(s) réparée(s)","gs.optimize_undo":"Annuler la dernière optimisation","gs.optimize_undone":"La dernière optimisation a été annulée","decor.furniture":"Mobilier","decor.image":"Image","decor.image_title":"Images personnalisées","decor.image_upload":"Importer une image","decor.image_replace":"Remplacer l’image","decor.image_uploading":"Importation…","decor.image_asset":"Fichier image","decor.image_pick_hint":"Importez une image ou choisissez-en une existante.","decor.image_place_hint":"Cliquez sur le plan pour placer l’image.","decor.image_none":"Aucune image importée pour le moment.","decor.image_unavailable":"Image indisponible","decor.image_used":"Utilisée dans {n} objets","decor.image_upload_failed":"Impossible d’importer l’image : {err}","decor.image_error_capacity":"Le stockage des images personnalisées est plein.","decor.image_in_use":"Supprimez toutes les copies placées avant ce fichier.","decor.image_delete_title":"Supprimer le fichier image ?","decor.image_delete_message":"Supprimer « {name} » de House Plan ? Cette action est irréversible.","furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis","common.yes":"Oui","common.no":"Non","vac.diag_source":"Source","vac.diag_platform":"Intégration","vac.diag_status":"État","vac.diag_position":"Position","vac.diag_rooms":"Pièces","vac.diag_rooms_value":"{total} · {matched} noms correspondent · {readiness}","vac.autocal_ready":"calibration automatique disponible","vac.autocal_not_ready":"3 noms correspondants requis","vac.diag_path":"Chemin de l’intégration","vac.diag_map":"ID de carte","vac.source_none":"non sélectionné","vac.source_status_ok":"Prêt","vac.source_status_missing":"Manquant","vac.source_status_disabled":"Désactivé dans Home Assistant","vac.source_status_unavailable":"Indisponible","vac.source_status_unverified":"Impossible à vérifier avec les autorisations actuelles","vac.source_status_unsupported":"Aucune donnée de position","vac.source_status_none":"Aucune source","vac.source_banner_missing":"La source enregistrée n’existe plus. Elle n’a pas été remplacée automatiquement ; choisissez une autre source ou restaurez-la dans Home Assistant.","vac.source_banner_disabled":"La source enregistrée est désactivée dans Home Assistant. Activez-la ou choisissez une autre source.","vac.source_banner_unverified":"Les autorisations Home Assistant actuelles ne permettent pas de vérifier cette source enregistrée. Elle reste épinglée et ne sera pas remplacée automatiquement.","vac.choose_source":"Choisir la source","vac.source_auto":"Automatique","vac.source_auto_hint":"Utiliser une entité compatible de cet appareil","vac.all_cameras":"Toutes les caméras","vac.all_cameras_warn":"Une caméra peut ne pas fournir de données du robot. Choisissez-en une uniquement s’il s’agit de la carte de votre aspirateur.","vac.all_cameras_empty":"Aucune autre entité caméra trouvée.","vac.platform_unknown":"intégration inconnue","vac.cap_position":"position","vac.cap_rooms_short":"pièces","vac.cap_path":"trajet","vac.cap_map":"ID de carte","vac.cap_none":"aucune donnée de robot détectée","vac.xcme_hint":"Activez ces attributs Xiaomi Cloud Map Extractor :","vac.documentation":"Documentation","vac.residual_title":"Vérifier la calibration automatique","vac.residual_message":"Les pièces correspondantes présentent un écart maximal de {error}. Appliquez cette calibration approximative, affinez-la manuellement ou annulez sans modifier la configuration enregistrée.","vac.apply_proposal":"Appliquer","gs.backup_group":"Sauvegarde et transfert","gs.backup_hint":"Téléchargez une sauvegarde JSON portable ou prévisualisez et importez une sauvegarde créée par House Plan.","backup.export_open":"Exporter","backup.import_open":"Importer","backup.export_title":"Exporter House Plan","backup.import_title":"Importer House Plan","backup.export_hint":"Choisissez si la sauvegarde doit contenir toute la configuration House Plan ou uniquement l’espace actuel.","backup.full":"Sauvegarde complète","backup.current_space":"Espace actuel","backup.current_space_title":"Espace actuel : {title}","backup.no_current_space":"Aucun espace actuel","backup.plan_only":"Plan uniquement","backup.plan_only_hint":"Conserver les pièces, murs, ouvertures, décorations et positions des étiquettes de pièces sans les appareils ni les associations Home Assistant.","backup.plan_only_preview":"Ce fichier contient uniquement le plan","backup.privacy_warning":"L’archive conserve les noms, identifiants Home Assistant et coordonnées exactes. Les plans internes et pièces jointes sont référencés, pas intégrés ; les états d’exécution et trajets d’aspirateur ne sont pas inclus.","backup.download":"Télécharger le JSON","backup.export_done":"Sauvegarde téléchargée","backup.reading":"Vérification de la sauvegarde…","backup.revalidated":"Le plan a changé depuis cet aperçu. Le résumé a été actualisé ; vérifiez-le et confirmez de nouveau.","backup.error.support_invalid_message":"Vérifiez le message d’assistance et réessayez.","backup.error.support_package_too_large":"Le paquet d’assistance anonymisé dépasse la limite de 8 Mio.","backup.error.support_preview_expired":"L’aperçu de la pièce jointe d’assistance a expiré ou n’est plus disponible.","backup.error.support_rate_limited":"Trop de rapports ou d’aperçus d’assistance ont été demandés. Réessayez plus tard.","backup.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","backup.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible.","backup.error.unauthorized":"Vous n’avez pas l’autorisation d’exporter ou d’importer ce plan.","backup.error.not_ready":"House Plan n’est pas encore prêt. Réessayez dans un instant.","backup.error.too_large":"La sauvegarde dépasse la limite de 8 Mio.","backup.error.invalid_json":"Le fichier sélectionné n’est pas un JSON valide.","backup.error.invalid_format":"Le fichier sélectionné n’est pas une sauvegarde House Plan.","backup.error.invalid_image":"L’image est endommagée ou ne correspond pas à son format.","backup.error.unsupported_export_version":"Ce format de sauvegarde n’est pas pris en charge par la version installée.","backup.error.unsupported_image":"Utilisez une image PNG, JPEG, WebP ou SVG prise en charge.","backup.error.future_model":"La sauvegarde a été créée avec un modèle de données House Plan plus récent.","backup.error.invalid_config":"La sauvegarde contient une configuration House Plan invalide.","backup.error.wall_model_migration_blocked":"Le modèle de murs de la sauvegarde n’a pas pu être mis à niveau en toute sécurité. Optimisez d’abord le plan source, puis exportez-le de nouveau.","backup.error.invalid_layout":"La sauvegarde contient des positions d’objets invalides.","backup.error.invalid_content":"La sauvegarde contient des références de contenu invalides ou incohérentes.","backup.error.space_not_found":"L’espace sélectionné n’existe plus.","backup.error.capacity_exceeded":"L’ajout de cette sauvegarde dépasserait les limites du plan.","backup.error.preview_expired":"L’aperçu a expiré. Sélectionnez de nouveau le fichier de sauvegarde.","backup.error.preview_owner_mismatch":"Cet aperçu appartient à un autre utilisateur Home Assistant.","backup.error.conflict":"Le plan a changé depuis l’aperçu. Vérifiez le résumé actualisé.","backup.error.content_confirmation_required":"Confirmez que le contenu local indisponible peut être dissocié.","backup.error.commit_failed":"La sauvegarde n’a pas pu être appliquée en toute sécurité. Le plan précédent a été restauré ou est en attente de récupération.","backup.error.missing_plan":"Un fichier de plan référencé a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.missing_content":"Une pièce jointe locale référencée a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.marker_control_missing":"Une lumière liée au plan est absente de la sauvegarde.","backup.error.marker_control_not_light":"Une cible liée au plan n’est plus marquée comme source lumineuse.","backup.error.marker_control_self":"Une source lumineuse ne peut pas se contrôler elle-même.","backup.error.marker_control_cycle":"La sauvegarde contient une chaîne circulaire de contrôles de lumière.","backup.error.duplicate_marker_control":"La sauvegarde contient un lien de lumière du plan en doublon.","backup.error.no_backup":"Aucun instantané d’importation ou d’optimisation n’est disponible à restaurer.","backup.error.in_use":"L'élément est encore utilisé","backup.error.invalid_data":"La requête contient des données invalides","backup.error.invalid_light_entity":"La lumière principale doit être une entité light.* ou switch.*","backup.error.invalid_marker_control":"Référence de contrôle de marqueur invalide","backup.error.invalid_name":"Le nom est invalide","backup.error.invalid_partition_opening_host":"L'ouverture doit conserver sa cloison porteuse","backup.error.invalid_partition_opening_jamb_margin":"L'ouverture ne laisse aucun jambage physique au bout du mur","backup.error.invalid_passage_fields":"Un passage ouvert ne peut pas porter de réglages de porte","backup.error.invalid_space_id":"Espace inconnu","backup.error.invalid_toggle_entity":"L'entité de bascule doit être light.* ou switch.*","backup.error.invalid_value_badge":"Réglages de badge de valeur invalides","backup.error.invalid_value_badge_attribute":"Attribut de badge de valeur invalide","backup.error.invalid_value_badge_position":"Position de badge de valeur invalide","backup.error.invalid_value_badge_source":"Source de badge de valeur invalide","backup.error.invalid_vacuum_map_route":"Vérifiez l'affectation des cartes du robot aux espaces.","backup.error.invalid_value_source":"Source de valeur invalide","backup.error.invalid_value_source_attribute":"Attribut de source de valeur invalide","backup.error.io_error":"Une opération de fichier a échoué sur le serveur","backup.error.not_toggleable":"Cet appareil ne peut pas être basculé","backup.error.nothing_to_repair":"Rien à réparer","backup.error.space_in_use":"L'espace est encore référencé","backup.error.value_badge_source_required":"Le badge de valeur nécessite une source","backup.error.wall_model_client_outdated":"Le plan a été mis à jour ailleurs — rechargez la page","backup.same_source":"Créée sur cette instance Home Assistant","backup.foreign_source":"Créée sur une autre instance Home Assistant","backup.created":"Créée : {value}","backup.versions":"Carte {card} ; intégration {integration} ; modèle de données {model}","backup.count_spaces":"Espaces : {n}","backup.count_rooms":"Pièces : {n}","backup.count_walls":"Murs : {n}","backup.count_openings":"Ouvertures : {n}","backup.count_decor":"Objets décoratifs : {n}","backup.count_markers":"Appareils : {n}","backup.count_layout":"Positions : {n}","backup.bindings":"Associations — appareils : {device}, entités : {entity}, virtuels : {virtual} ; positions sans espace : {legacy}","backup.binding_status":"État des cibles — actives : {active}, désactivées : {disabled}, manquantes : {missing}","backup.missing_areas":"Zones absentes sur la cible : {areas}","backup.dropped_marker_links":"Liens de lumières du plan hors de cet espace transféré omis : {n}.","backup.room_drafts_migrated":"Anciens contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","backup.repaired_target_refs":"Références existantes restaurées par cet import d’espace : {n}.","backup.preserved_unresolved_refs":"Références qui n’ont pas pu être restaurées sans ambiguïté conservées : {n}.","backup.preserved_unresolved_hint":"Aucune donnée n’a été devinée ni supprimée. Après l’importation, lancez « Optimiser les plans » pour examiner les références restantes.","backup.import_details":"Détails des références d’importation","backup.import_detail.incoming_remapped":"Références mises à jour dans la copie importée : {n}","backup.import_detail.target_repaired":"Références existantes restaurées : {n}","backup.import_detail.preserved_unresolved":"Références non résolues conservées : {n}","backup.import_detail.collisions":"Conflits de destination conservés en toute sécurité : {n}","backup.import_detail.dropped_links":"Liens entrants omis selon les règles de transfert : {n}","backup.import_detail.bounded_lineages":"Identifiants trop imbriqués maintenus dans les limites : {n}","backup.replace_warning":"Cela remplace la configuration et la disposition actuelles. Les fichiers importés ne sont jamais supprimés. Une seule annulation reste disponible jusqu’à la prochaine modification du plan.","backup.foreign_bookkeeping":"Les données de suivi des appareils connus/nouveaux propres à l’instance ne seront pas importées.","backup.final_name":"Nom du nouvel espace","backup.target_settings":"Les paramètres généraux de l’instance cible restent inchangés.","backup.duplicates":"Associations déjà présentes : {n}","backup.skip":"Ignorer les appareils en doublon","backup.virtual_copy":"Ajouter des copies virtuelles statiques sûres","backup.content":"Contenu référencé","backup.decor_images_summary":"Images personnalisées : {objects} objets, {assets} fichiers ; fichiers absents : {missing}.","backup.content_available":"disponible localement","backup.content_external":"lien externe","backup.content_detach_required":"sera dissocié","backup.confirm_detach":"Je comprends que les plans internes et pièces jointes indisponibles seront dissociés de la configuration importée.","backup.confirm_missing_images":"Je comprends que les images personnalisées absentes resteront des espaces réservés réparables et que les autres fichiers locaux indisponibles seront dissociés.","backup.replace":"Remplacer","backup.add":"Ajouter un espace","backup.space_done":"Espace importé : {rooms} pièces, {markers} appareils, {refs} références existantes restaurées","backup.full_done":"Sauvegarde restaurée : {spaces} espaces, {rooms} pièces, {markers} appareils","backup.undo_import":"Annuler la dernière importation complète","backup.import_undone":"Importation complète annulée","backdrop.large_title":"Grande image","backdrop.large_body":"Cette image fait {w}×{h} (fichier de {fileMb} Mo) et nécessite environ {decodedMb} Mo de mémoire pour s'afficher. Sur tablette, cela peut faire planter la page.","backdrop.unknown_body":"Les dimensions de l'image n'ont pas pu être lues — le fichier est peut-être endommagé. Continuer peut faire planter la page sur tablette.","backdrop.reduced_dimensions":"Copie réduite : {w}×{h} px.","backdrop.use_downscaled":"Téléverser une copie réduite","backdrop.reducing":"Réduction…","backdrop.keep_original":"Conserver l'original","backdrop.too_large_title":"Image trop grande","backdrop.too_large_body":"Cette image dépasse ce que les navigateurs peuvent afficher ({w}×{h}, limite {limit} px par côté). Réduisez-la dans un éditeur de bureau puis téléversez-la à nouveau.","backdrop.downscale_failed":"Impossible de créer la copie réduite. Le plan actuel n'a pas été modifié."};const r="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";export{e as dictionary,r as fingerprint}; diff --git a/dist/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js b/custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js similarity index 99% rename from dist/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js rename to custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js index ed8f81c3..11c00407 100644 --- a/dist/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js +++ b/custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";const c="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e",a={coffee_table:{d:"M3.84 5.884c0-1.21 1.048-2.192 2.34-2.192h107.64c1.293 0 2.34.981 2.34 2.192v48.23c0 1.212-1.047 2.193-2.34 2.193H6.18c-1.292 0-2.34-.981-2.34-2.192z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},coffee_table_round:{d:"M3.765 40a36.235 36.235 0 1 0 72.47 0 36.235 36.235 0 1 0-72.47 0 m56.26 26.96-3.843-3.843a.906.906 0 0 1 0-1.28l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.843 3.844a.906.906 0 0 1 0 1.28l-3.843 3.844a.906.906 0 0 1-1.281 0m-34.423-34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.844a.906.906 0 0 1 0 1.28l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.843a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.843a.906.906 0 0 1-1.28 0",viewW:80,viewH:80},coffee_table_oval:{d:"M3.84 30c0-14.53 12.572-26.308 28.08-26.308h56.16c15.509 0 28.08 11.778 28.08 26.308s-12.571 26.307-28.08 26.307H31.92C16.412 56.307 3.84 44.53 3.84 30 M80.592 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877M31.92 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876",viewW:120,viewH:60},coffee_table_rounded:{d:"M3.84 12.461c0-4.843 4.19-8.77 9.36-8.77h93.6c5.17 0 9.36 3.927 9.36 8.77v35.077c0 4.843-4.19 8.77-9.36 8.77H13.2c-5.17 0-9.36-3.927-9.36-8.77z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},table_dining:{d:"M3.879 6.08c0-1.265 1.065-2.29 2.378-2.29h147.484c1.314 0 2.38 1.025 2.38 2.29v77.84c0 1.265-1.066 2.29-2.38 2.29H6.257c-1.313 0-2.378-1.025-2.378-2.29z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},table_round:{d:"M3.826 55a51.174 51.174 0 1 0 102.349 0A51.174 51.174 0 1 0 3.826 55 m81.005 32.303-3.947-3.947a.93.93 0 0 1 0-1.316l3.947-3.948a.93.93 0 0 1 1.316 0l3.948 3.948a.93.93 0 0 1 0 1.316l-3.948 3.947a.93.93 0 0 1-1.316 0m0 54.897-3.947-3.948a.93.93 0 0 1 0-1.316l3.947-3.947a.93.93 0 0 1 1.316 0l3.948 3.947a.93.93 0 0 1 0 1.316L82.32 87.2a.93.93 0 0 1-1.316 0M27.04 32.304l-3.947-3.948a.93.93 0 0 1 0-1.315l3.948-3.948a.93.93 0 0 1 1.315 0l3.948 3.948a.93.93 0 0 1 0 1.315l-3.948 3.948a.93.93 0 0 1-1.315 0m-.001 54.604-3.947-3.948a.93.93 0 0 1 0-1.316l3.948-3.947a.93.93 0 0 1 1.315 0l3.948 3.947a.93.93 0 0 1 0 1.316l-3.948 3.948a.93.93 0 0 1-1.315 0",viewW:110,viewH:110},table_dining_oval:{d:"M3.892 50c0-25.51 21.418-46.19 47.838-46.19h76.54c26.42 0 47.839 20.68 47.839 46.19S154.69 96.19 128.27 96.19H51.73C25.31 96.19 3.892 75.51 3.892 50 M122.53 19.514V13.97a.957.924 0 0 1 .956-.924h5.74a.957.924 0 0 1 .958.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m.001 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.957-.924M49.816 19.515v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .958.924v5.542a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m0 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.923h-5.74a.957.924 0 0 1-.957-.924",viewW:180,viewH:100},table_dining_rounded:{d:"M3.879 17.527c0-7.587 6.39-13.737 14.272-13.737h123.696c7.883 0 14.273 6.15 14.273 13.737v54.947c0 7.587-6.39 13.737-14.273 13.737H18.151c-7.882 0-14.272-6.15-14.272-13.737z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},desk:{d:"M3.862 5.967c0-1.234 1.057-2.234 2.362-2.234h127.552c1.305 0 2.362 1 2.362 2.234v58.066c0 1.234-1.057 2.233-2.362 2.233H6.224c-1.305 0-2.362-1-2.362-2.233z M9.531 15.346v-5.36a.945.893 0 0 1 .945-.893h5.67a.945.893 0 0 1 .944.893v5.36a.945.893 0 0 1-.945.894h-5.669a.945.893 0 0 1-.945-.894m113.379.001v-5.36a.945.893 0 0 1 .945-.894h5.67a.945.893 0 0 1 .944.894v5.36a.945.893 0 0 1-.945.893h-5.669a.945.893 0 0 1-.945-.893M9.53 60.013v-5.36a.945.893 0 0 1 .946-.893h5.669a.945.893 0 0 1 .945.893v5.36a.945.893 0 0 1-.945.894h-5.67a.945.893 0 0 1-.944-.894m113.38.001v-5.36a.945.893 0 0 1 .945-.894h5.669a.945.893 0 0 1 .945.894v5.36a.945.893 0 0 1-.945.893h-5.67a.945.893 0 0 1-.944-.893m-97.318-2.681h88.814",viewW:140,viewH:70},desk_corner:{d:"M156.12 66.202a2.38 2.38 0 0 1-2.379 2.38H94.272c-13.138 0-23.788 10.65-23.788 23.787v61.372a2.38 2.38 0 0 1-2.379 2.38H6.257a2.38 2.38 0 0 1-2.378-2.38V6.257A2.38 2.38 0 0 1 6.257 3.88h147.484a2.38 2.38 0 0 1 2.38 2.378z M9.588 16.249v-5.71a.95.95 0 0 1 .951-.95h5.71a.95.95 0 0 1 .95.95v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m133.212.001v-5.71a.95.95 0 0 1 .951-.951h5.71a.95.95 0 0 1 .95.951v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m0 45.672v-5.71a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.95-.951M9.587 149.46v-5.708a.95.95 0 0 1 .952-.952h5.709a.95.95 0 0 1 .951.952v5.709a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.951-.951m47.576 0v-5.709a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.95h-5.71a.95.95 0 0 1-.951-.95m51.382-90.396H95.569a34.6 34.6 0 0 0-34.6 34.6v12.976",viewW:160,viewH:160},chair:{d:"M39.452 12.433H10.548a4.398 4.398 0 1 1 0-8.796h28.904a4.398 4.398 0 0 1 0 8.796m-28.904 0H8.035a4.4 4.4 0 0 0-4.398 4.399V40.08a6.283 6.283 0 0 0 6.283 6.284h30.16a6.283 6.283 0 0 0 6.284-6.284V16.832c0-2.43-1.97-4.399-4.399-4.399h-2.513",viewW:50,viewH:50},chair_bar:{d:"M38.579 17.168c1.326 2.526 1.947 6.015 1.947 9.071 0 10.018-8.07 18.139-18.025 18.139S4.475 36.257 4.475 26.239c0-3.056.586-6.552 1.912-9.078m32.192.007a3.59 3.59 0 0 1-3.333-.976m3.333.976a3.6 3.6 0 0 0 1.765-.976m-33.827.996-.13-.027a3.6 3.6 0 0 1-1.731-.969m30.59 0a18 18 0 0 0-5.848-3.932 17.93 17.93 0 0 0-13.796 0 18 18 0 0 0-5.848 3.932 3.59 3.59 0 0 1-3.237.996m28.729-.996a3.59 3.59 0 0 0 5.098 0m-33.827.996a3.6 3.6 0 0 1-1.861-.996 3.644 3.644 0 0 1 0-5.13 25.2 25.2 0 0 1 8.187-5.505A25.1 25.1 0 0 1 22.5 3.623a25.1 25.1 0 0 1 9.657 1.934 25.2 25.2 0 0 1 8.187 5.505 3.644 3.644 0 0 1 0 5.13",viewW:45,viewH:48},armchair:{d:"M75.702 13.011q.012-.225.012-.453c0-4.843-3.917-8.768-8.748-8.768H23.034c-4.83 0-8.747 3.925-8.747 8.768q0 .228.011.453M77.132 72.09q.59.091 1.206.092c4.348 0 7.873-3.533 7.873-7.892V20.45c0-4.359-3.525-7.892-7.873-7.892-.924 0-1.812.16-2.636.453a7.89 7.89 0 0 0-5.237 7.438v.148m0 0a8.7 8.7 0 0 1-3.499.73H23.034a8.7 8.7 0 0 1-3.499-.73m50.93 0V64.29a7.89 7.89 0 0 0 6.667 7.8M14.298 13.01a7.89 7.89 0 0 1 5.237 7.438v.148m0 0V64.29a7.89 7.89 0 0 1-6.666 7.8q-.59.091-1.206.092c-4.348 0-7.873-3.533-7.873-7.892V20.45c0-4.359 3.525-7.892 7.873-7.892.924 0 1.811.16 2.635.453M77.132 72.09c-1.585 8.05-8.667 14.12-17.164 14.12H30.032c-8.496 0-15.578-6.07-17.163-14.12",viewW:90,viewH:90},armchair_office:{d:"M56.968 18.845q0-.368-.05-.72M49.051 13.8H15.95a5.04 5.04 0 0 1-5.038-5.043 5.04 5.04 0 0 1 5.038-5.043h33.103a5.04 5.04 0 0 1 5.038 5.043 5.04 5.04 0 0 1-5.038 5.043m-33.103 0h-2.88a5.04 5.04 0 0 0-4.986 4.323M49.052 13.8h2.879a5.04 5.04 0 0 1 4.986 4.324m.051 24.826a4.32 4.32 0 0 0 4.318-4.323v-16.18a4.32 4.32 0 0 0-4.369-4.322m.051 24.826a4.32 4.32 0 0 1-4.318-4.323V22.447a4.32 4.32 0 0 1 4.267-4.322m-11.84 37.24h4.695c.736 0 1.446-.111 2.115-.317a7.21 7.21 0 0 0 5.081-6.889v-5.208M8.084 18.124h-.051a4.32 4.32 0 0 0-4.318 4.323v16.18a4.32 4.32 0 0 0 4.318 4.324 4.32 4.32 0 0 0 4.317-4.323V22.447a4.32 4.32 0 0 0-4.266-4.323m11.935 37.24h-4.79a7.2 7.2 0 0 1-2.04-.294 7.21 7.21 0 0 1-5.156-6.91v-5.21m37.045 12.414 5.177 5.183c.969.97 2.534.987 3.524.038a2.526 2.526 0 0 0 .038-3.605l-1.93-1.932m-6.81.316H20.02m-6.83-.294-1.909 1.91c-.998 1-.98 2.627.038 3.605.99.949 2.555.932 3.524-.038l5.177-5.183",viewW:65,viewH:65},sofa:{d:"M90 19.365v57.111m0-57.11V7.683m0 11.681c0 2.151-1.836 3.894-4.1 3.894H30.544a10.7 10.7 0 0 1-4.136-.825M90 19.365c0 2.151 1.836 3.894 4.1 3.894h55.356c1.472 0 2.871-.294 4.137-.825M90 76.476c0 5.376-4.59 9.735-10.25 9.735H30.543c-5.266 0-9.605-3.772-10.185-8.625M90 76.476c0 5.376 4.59 9.735 10.25 9.735h49.206c5.266 0 9.605-3.772 10.185-8.625M90 7.684c0-2.15-1.837-3.894-4.101-3.894H30.544c-5.661 0-10.25 4.358-10.25 9.735q0 .416.036.825M90 7.684c0-2.15 1.836-3.894 4.1-3.894h55.356c5.661 0 10.25 4.358 10.25 9.735q0 .416-.036.825m0 0a10.7 10.7 0 0 1 4.137-.825h2.05c5.662 0 10.252 4.358 10.252 9.734v45.43c0 5.376-4.59 9.734-10.251 9.734h-2.05c-1.484 0-2.894-.3-4.167-.837m0 0c-3.585-1.517-6.084-4.93-6.084-8.898V23.26q0-.417.036-.825c.32-3.622 2.728-6.68 6.077-8.084m-139.34 0c3.35 1.404 5.758 4.462 6.078 8.084q.036.408.036.825v45.43c0 3.967-2.5 7.38-6.085 8.897a10.7 10.7 0 0 1-4.166.837h-2.05c-5.662 0-10.251-4.358-10.251-9.735V23.26c0-5.376 4.59-9.734 10.25-9.734h2.05c1.473 0 2.872.294 4.138.825",viewW:180,viewH:90},sofa_three_seat:{d:"M86.553 18.593V76.96m0-58.366V7.491m0 11.102c0 2.044-1.762 3.701-3.935 3.701H29.496c-1.413 0-2.756-.28-3.97-.784m61.027-2.917c0 2.044 1.762 3.701 3.935 3.701h59.024c2.174 0 3.935-1.657 3.935-3.7M86.553 76.958c0 5.11-4.404 9.252-9.837 9.252h-47.22c-5.054 0-9.218-3.585-9.775-8.198m66.832-1.054c0 5.11 4.404 9.252 9.837 9.252h47.22c5.433 0 9.837-4.142 9.837-9.252m0-58.366V76.96m0-58.366V7.491m0 11.102c0 2.044 1.762 3.701 3.936 3.701h53.122c1.413 0 2.756-.28 3.97-.784m-61.028 55.449c0 5.11 4.405 9.252 9.838 9.252h47.22c5.054 0 9.218-3.585 9.775-8.198M86.553 7.491c0-2.044-1.762-3.701-3.935-3.701H29.496c-5.433 0-9.838 4.142-9.838 9.252q0 .396.035.784m66.86-6.335c0-2.044 1.762-3.701 3.935-3.701h59.024c2.174 0 3.935 1.657 3.935 3.7m0 0c0-2.043 1.762-3.7 3.936-3.7h53.122c5.433 0 9.838 4.142 9.838 9.252 0 .258.022.517 0 .77m-.063 64.201c1.22.512 2.574.796 3.998.796h1.967c5.433 0 9.837-4.142 9.837-9.252V22.294c0-5.11-4.404-9.252-9.837-9.252h-1.967c-5.153 0-9.38 3.725-9.803 8.468q-.036.387-.035.784v47.263c0 3.771 2.399 7.015 5.84 8.456M19.693 13.826a10.3 10.3 0 0 0-3.97-.784h-1.967c-5.433 0-9.838 4.142-9.838 9.252v47.263c0 5.11 4.405 9.252 9.838 9.252h1.967c1.424 0 2.777-.284 3.998-.796 3.441-1.441 5.84-4.685 5.84-8.456V22.294a9 9 0 0 0-.035-.784c-.307-3.443-2.618-6.349-5.833-7.684",viewW:240,viewH:90},sofa_corner_right:{d:"M93.673 20.687V83.69m0-63.004v-12.6m0 12.6c0 2.32-1.913 4.2-4.273 4.2H31.704a10.8 10.8 0 0 1-4.311-.89m66.28-3.31c0 2.32 1.914 4.2 4.274 4.2h64.106c2.36 0 4.274-1.88 4.274-4.2M93.673 83.692c0 5.8-4.783 10.501-10.684 10.501H31.704c-5.489 0-10.011-4.068-10.616-9.304m72.585-1.197c0 5.8 4.784 10.501 10.684 10.501h51.286c5.9 0 10.684-4.701 10.684-10.5m0-63.005V83.69m0-63.004v-12.6m0 12.6c0 2.32 1.914 4.2 4.273 4.2h57.696c1.534 0 2.993-.317 4.312-.89m-66.28 59.695v71.923c0 5.799 4.782 10.5 10.684 10.5h51.284c5.49 0 10.012-4.068 10.616-9.304V84.888M93.673 8.086c0-2.32-1.913-4.2-4.273-4.2H31.704c-5.9 0-10.684 4.7-10.684 10.5q0 .45.038.89m72.615-7.19c0-2.32 1.914-4.2 4.274-4.2h64.106c2.36 0 4.274 1.88 4.274 4.2m0 0c0-2.32 1.914-4.2 4.273-4.2h57.696c5.9 0 10.685 4.7 10.685 10.5 0 .293.024.587 0 .874m-.07 69.628c1.327.58 2.797.904 4.344.904h2.136c5.901 0 10.684-4.702 10.684-10.501V24.887c0-5.8-4.783-10.5-10.684-10.5h-2.136c-5.596 0-10.187 4.227-10.647 9.61q-.038.44-.038.89V75.29c0 4.28 2.605 7.961 6.342 9.597M21.059 15.276a10.8 10.8 0 0 0-4.312-.89H14.61c-5.9 0-10.684 4.701-10.684 10.5v50.405c0 5.8 4.783 10.5 10.684 10.5h2.137c1.546 0 3.016-.322 4.342-.903 3.737-1.636 6.342-5.317 6.342-9.597V24.887q0-.45-.037-.89c-.334-3.907-2.844-7.206-6.335-8.72",viewW:260,viewH:170},bed_single:{d:"M3.79 14.024c0 5.59 4.318 10.122 9.645 10.122h63.13c5.328 0 9.646-4.532 9.646-10.122m-22.797 46.93V46.23c0-5.082-3.926-9.201-8.769-9.201h-19.29c-4.842 0-8.768 4.12-8.768 9.201v14.723m-22.797 0h82.42m0 22.085H3.79m8.768 113.06h64.885c4.842 0 8.768-4.12 8.768-9.202V13.104c0-5.082-3.926-9.202-8.768-9.202H12.558c-4.843 0-8.768 4.12-8.768 9.202v173.792c0 5.082 3.925 9.202 8.768 9.202",viewW:90,viewH:200},bed_double:{d:"M3.879 14.073c0 5.618 4.516 10.172 10.088 10.172h132.065c5.571 0 10.088-4.554 10.088-10.172m-81.165 47.16V46.438c0-5.107-4.106-9.247-9.171-9.247H45.607c-5.065 0-9.17 4.14-9.17 9.247v14.795m89.877 0V46.438c0-5.107-4.107-9.247-9.172-9.247H96.966c-5.065 0-9.171 4.14-9.171 9.247v14.795m-83.916 0H156.12m0 22.192H3.88m9.17 112.673h133.9c5.065 0 9.171-4.14 9.171-9.247V13.15c0-5.107-4.106-9.247-9.171-9.247H13.05c-5.064 0-9.17 4.14-9.17 9.247v173.7c0 5.107 4.106 9.247 9.17 9.247",viewW:160,viewH:200},nightstand:{d:"M5.773 3.555h38.454a2.136 2.056 0 0 1 2.137 2.056v28.777a2.136 2.056 0 0 1-2.137 2.056H5.773a2.136 2.056 0 0 1-2.136-2.056V5.611a2.136 2.056 0 0 1 2.136-2.056",viewW:50,viewH:40},cabinet_tv:{d:"M56.772 17.88h5.315m0 0h5.315m-5.315 0v9.214m9.832-9.214 5.315 9.45 5.314-9.45M6.224 41.4h127.552c1.305 0 2.362-.94 2.362-2.1V5.7c0-1.16-1.057-2.1-2.362-2.1H6.224c-1.305 0-2.362.94-2.362 2.1v33.6c0 1.16 1.057 2.1 2.362 2.1",viewW:140,viewH:45},cabinet_shoe:{d:"m39.722 16.231 1.505-1.596m1.134 3.15 1.53-1.738M6.03 31.5h67.94c1.251 0 2.265-.895 2.265-2v-24c0-1.105-1.014-2-2.264-2H6.03c-1.251 0-2.265.895-2.265 2v24c0 1.105 1.014 2 2.265 2m41.966-14.305L46.92 17.1a3.4 3.4 0 0 1-1.813-.706l-4.583-3.62c-1.264-1-3.277-.326-3.475 1.161-.185 1.39-1.983 2.1-3.28 1.299l-1.532-.947c-.968-.513-2.2.103-2.2 1.1v3.463c0 1.559 1.43 2.823 3.196 2.823h14.51c1.404 0 2.542-1.005 2.542-2.245 0-1.153-.99-2.118-2.289-2.233",viewW:80,viewH:35},cabinet_sink:{d:"M3.765 5.773c0-1.18 1.014-2.136 2.265-2.136h67.94c1.251 0 2.265.956 2.265 2.136v38.454c0 1.18-1.014 2.137-2.264 2.137H6.03c-1.251 0-2.265-.957-2.265-2.137z M36.088 32.135c2.525 1.88 6.205 1.88 8.73 0s3.167-5.101 1.52-7.637l-5.879-8.043-5.893 8.043c-1.644 2.536-1.003 5.755 1.522 7.637",viewW:80,viewH:50},bookshelf:{d:"M57.12 20.488H45.473c-.514 0-1.008.124-1.372.345s-.568.52-.568.832m4.076-8.236h5.434M6.119 3.5h87.762c1.276 0 2.31.895 2.31 2v24c0 1.105-1.034 2-2.31 2H6.12c-1.275 0-2.31-.895-2.31-2v-24c0-1.105 1.035-2 2.31-2m51 6.4v14.118H45.474a2.04 2.04 0 0 1-1.372-.517 1.7 1.7 0 0 1-.568-1.248V11.665c0-.468.204-.917.568-1.248a2.04 2.04 0 0 1 1.372-.517z",viewW:100,viewH:35},wall_unit:{d:"M6.336 41.4h227.328a2.418 2.1 0 0 0 2.418-2.1V5.7a2.418 2.1 0 0 0-2.418-2.1H6.336a2.418 2.1 0 0 0-2.418 2.1v33.6a2.418 2.1 0 0 0 2.418 2.1m43.744-5.88V9.48m46.432 26.04V9.48m46.433 26.04V9.48m46.433 26.04V9.48",viewW:240,viewH:45},wardrobe:{d:"M93.87 20.25a3.3 3.3 0 0 0-1.072-2.407 3.8 3.8 0 0 0-2.586-.997c-.97 0-1.9.358-2.587.997a3.3 3.3 0 0 0-1.071 2.407c0 2.838 1.225 5.107 3.658 6.81h-.015m0 0 14.58 7.537c.57.295 1.046.726 1.377 1.25.331.523.505 1.12.505 1.727v1.401a3.3 3.3 0 0 1-1.071 2.407 3.8 3.8 0 0 1-2.587.998H77.393a3.8 3.8 0 0 1-2.586-.998 3.3 3.3 0 0 1-1.072-2.407v-1.4c0-.608.174-1.205.505-1.728a3.55 3.55 0 0 1 1.377-1.25zM6.284 3.691h167.433c1.32 0 2.392.981 2.392 2.192v48.23c0 1.212-1.071 2.193-2.392 2.193H6.284c-1.321 0-2.392-.981-2.392-2.192V5.885c0-1.212 1.07-2.193 2.392-2.193",viewW:180,viewH:60},kitchen_floor:{d:"M3.692 5.884c0-1.21.981-2.192 2.192-2.192h48.23c1.212 0 2.193.981 2.193 2.192v48.23a2.19 2.19 0 0 1-2.192 2.193H5.885a2.19 2.19 0 0 1-2.193-2.192z",viewW:60,viewH:60},kitchen_floor_corner:{d:"M45.944 41.767a2.29 2.29 0 0 0 2.29 2.29H83.92a2.29 2.29 0 0 1 2.29 2.29V83.92a2.29 2.29 0 0 1-2.29 2.29H6.08a2.29 2.29 0 0 1-2.29-2.29V6.08a2.29 2.29 0 0 1 2.29-2.29h37.576a2.29 2.29 0 0 1 2.29 2.29z",viewW:90,viewH:90},kitchen_wall:{d:"m4.444 31.033 50.75-27.007m-50.752-.06 50.75 27.008M5.884 31.5h48.23c1.212 0 2.193-.895 2.193-2v-24c0-1.105-.981-2-2.192-2H5.885c-1.212 0-2.193.895-2.193 2v24c0 1.105.981 2 2.192 2",viewW:60,viewH:35},kitchen_wall_corner:{d:"M3.772 29.59 29.88 4.383M4.57 55.43 55.43 30M4.175 4.383l26.701 23.863m-27.184.877L55.43 55.43M28.41 3.692H5.884c-1.21 0-2.192.981-2.192 2.192v48.23c0 1.212.981 2.193 2.192 2.193h48.23a2.19 2.19 0 0 0 2.193-2.192V31.589c0-1.21-.981-2.192-2.192-2.192h-21.32a2.19 2.19 0 0 1-2.193-2.192V5.885a2.19 2.19 0 0 0-2.192-2.193",viewW:60,viewH:60},shelf_floor:{d:"M6.12 31.5h87.76a2.31 2 0 0 0 2.31-2v-24a2.31 2 0 0 0-2.31-2H6.12a2.31 2 0 0 0-2.31 2v24a2.31 2 0 0 0 2.31 2 M9.089 25.933c-.494.112-.776.546-.63.97s.664.675 1.157.564l-.263-.767zM90.912 9.067c.493-.112.775-.546.63-.97s-.664-.675-1.158-.564l.264.767zM11.875 26.956c.493-.112.775-.546.63-.97s-.664-.676-1.158-.564l.264.767zm3.988-2.556c-.493.112-.775.546-.63.969s.664.676 1.158.564l-.264-.766zm5.045.511c.493-.112.775-.545.63-.969s-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.111-.775.545-.63.968.146.424.664.677 1.158.565l-.264-.767zm5.044.51c.494-.111.776-.545.63-.968-.145-.424-.664-.676-1.157-.565l.263.767zm3.99-2.555c-.495.112-.777.546-.63.97.145.423.663.675 1.157.563l-.264-.766zm5.043.511c.494-.112.776-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.989-2.555c-.494.111-.776.545-.63.969s.664.676 1.157.564l-.263-.767zm5.044.51c.494-.11.776-.545.63-.968-.146-.424-.664-.676-1.158-.565l.264.767zm3.989-2.555c-.494.112-.776.546-.63.97.145.423.664.675 1.157.564l-.264-.767zm5.044.511c.493-.111.775-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.988-2.555c-.493.112-.775.545-.63.969s.664.676 1.158.564l-.264-.767zm5.045.51c.493-.11.775-.545.63-.968-.146-.424-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.112-.775.546-.63.97s.664.675 1.158.564l-.264-.767zm5.044.511c.494-.111.776-.545.63-.968-.145-.424-.664-.677-1.157-.565l.264.767zm3.99-2.555c-.494.112-.777.545-.63.969.145.423.663.676 1.157.564l-.264-.766zm5.043.511c.494-.112.776-.546.63-.969s-.664-.676-1.157-.564l.263.766zm3.989-2.556c-.494.112-.776.546-.63.97s.664.676 1.158.564l-.264-.767zM9.353 26.7l.263.767 2.259-.511-.264-.767-.264-.767-2.258.511zm6.774-1.533.264.766 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.045.264.767 4.516-1.022-.264-.767-.263-.767-4.517 1.023zm9.033-2.044.264.766 4.516-1.022-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.263.767 4.517-1.022-.264-.767-.264-.767-4.516 1.023zm9.032-2.044.264.767 4.517-1.023-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.264.767 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.044.264.767 4.516-1.023-.263-.766-.264-.767-4.517 1.022zm9.033-2.044.264.766 4.516-1.022-.264-.767-.263-.766-4.517 1.022zM88.39 8.81l.264.767 2.258-.511-.264-.767-.264-.767-2.258.511z M9.089 9.067c-.494-.112-.776-.546-.63-.97s.664-.675 1.157-.564l-.263.767zm81.823 16.866c.493.112.775.546.63.97s-.664.675-1.158.564l.264-.767zM11.875 8.044c.493.112.775.546.63.97s-.664.676-1.158.564l.264-.767zm3.988 2.556c-.493-.112-.775-.546-.63-.969s.664-.676 1.158-.564l-.264.766zm5.045-.511c.493.112.775.545.63.969s-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.111-.775-.545-.63-.968.146-.424.664-.677 1.158-.565l-.264.767zm5.044-.51c.494.111.776.545.63.968-.145.424-.664.676-1.157.565l.263-.767zm3.99 2.555c-.495-.112-.777-.546-.63-.97.145-.423.663-.675 1.157-.563l-.264.766zm5.043-.511c.494.112.776.545.63.969s-.664.676-1.158.564l.264-.767zm3.989 2.555c-.494-.111-.776-.545-.63-.969s.664-.676 1.157-.564l-.263.767zm5.044-.51c.494.11.776.545.63.968-.146.424-.664.676-1.158.565l.264-.767zm3.989 2.555c-.494-.112-.776-.546-.63-.97.145-.423.664-.675 1.157-.564l-.264.767zm5.044-.511c.493.111.775.545.63.969s-.664.676-1.158.564l.264-.767zm3.988 2.555c-.493-.112-.775-.545-.63-.969s.664-.676 1.158-.564l-.264.767zm5.045-.51c.493.11.775.545.63.968-.146.424-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.112-.775-.546-.63-.97s.664-.675 1.158-.564l-.264.767zm5.044-.511c.494.111.776.545.63.968-.145.424-.664.677-1.157.565l.264-.767zm3.99 2.555c-.494-.112-.777-.545-.63-.969.145-.423.663-.676 1.157-.564l-.264.766zm5.043-.511c.494.112.776.546.63.969s-.664.676-1.157.564l.263-.766zm3.989 2.556c-.494-.112-.776-.546-.63-.97s.664-.676 1.158-.564l-.264.767zM9.353 8.3l.263-.767 2.259.511-.264.767-.264.767-2.258-.511zm6.774 1.533.264-.766 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.045.264-.767 4.516 1.022-.264.767-.263.767-4.517-1.023zm9.033 2.044.264-.766 4.516 1.022-.264.766-.264.767-4.516-1.022zm9.033 2.045.263-.767 4.517 1.022-.264.767-.264.767-4.516-1.023zm9.032 2.044.264-.767 4.517 1.023-.264.766-.264.767-4.516-1.022zm9.033 2.045.264-.767 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.044.264-.767 4.516 1.023-.263.766-.264.767-4.517-1.022zm9.033 2.044.264-.766 4.516 1.022-.264.767-.263.766-4.517-1.022zm9.033 2.045.264-.767 2.258.511-.264.767-.264.767-2.258-.511z",viewW:100,viewH:35},shelf_wall:{d:"M18.36 3.15v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.309-.82-2.309-1.833V3.15m73.905 0v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.31-.82-2.31-1.833V3.15m-75.29 0H93.65c1.276 0 2.31.82 2.31 1.833V19.65c0 1.012-1.034 1.833-2.31 1.833H5.888c-1.275 0-2.31-.82-2.31-1.833V4.983c0-1.012 1.035-1.833 2.31-1.833",viewW:100,viewH:25},cooktop_two:{d:"M15 30.982v-1.71m3.086 5.128h1.542M15 39.527v-1.709M10.372 34.4h1.542M5.84 46.364h18.322c1.331 0 2.41-1.196 2.41-2.67V6.306c0-1.475-1.079-2.67-2.41-2.67H5.839c-1.331 0-2.41 1.195-2.41 2.67v37.386c0 1.475 1.079 2.67 2.41 2.67m14.56-29.91c0 3.304-2.417 5.982-5.4 5.982-2.981 0-5.4-2.678-5.4-5.981s2.419-5.982 5.4-5.982c2.983 0 5.4 2.678 5.4 5.982M18.858 34.4c0 2.36-1.727 4.273-3.857 4.273s-3.857-1.913-3.857-4.273S12.87 30.127 15 30.127s3.857 1.913 3.857 4.273",viewW:30,viewH:50},stove:{d:"M41.4 35.261a.877.877 0 1 0-1.754 0zm4.384 6.138a.877.877 0 1 0 0-1.753zM41.4 44.03a.877.877 0 1 0-1.753 0zm-4.384-2.63a.877.877 0 1 0 0-1.754zM5.885 3.691v.877h48.23V2.815H5.885zm50.422 2.192h-.877v48.23h1.754V5.885zm-2.192 50.423v-.877H5.885v1.754h48.23zM3.692 54.115h.877V5.885H2.815v48.23zm2.192 2.192v-.877a1.315 1.315 0 0 1-1.315-1.315H2.815a3.07 3.07 0 0 0 3.07 3.069zm50.423-2.192h-.877c0 .726-.589 1.315-1.315 1.315v1.754a3.07 3.07 0 0 0 3.069-3.07zM54.115 3.692v.877c.726 0 1.315.589 1.315 1.315h1.754a3.07 3.07 0 0 0-3.07-3.069zm-48.23 0v-.877a3.07 3.07 0 0 0-3.07 3.07h1.754c0-.727.589-1.316 1.315-1.316zm19.73 36.83h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.015zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.261h-1.754a7.015 7.015 0 0 0 7.015 7.015zm-6.138-6.138h.877a5.26 5.26 0 0 1 5.261-5.262v-1.754a7.015 7.015 0 0 0-7.015 7.016zm6.138-6.139v.877a5.26 5.26 0 0 1 5.262 5.262h1.754a7.015 7.015 0 0 0-7.016-7.016zm27.185-14.908h-.877a5.26 5.26 0 0 1-5.261 5.262v1.754a7.015 7.015 0 0 0 7.015-7.016zm-6.138 6.139v-.877a5.26 5.26 0 0 1-5.262-5.262h-1.754a7.015 7.015 0 0 0 7.016 7.016zm-6.139-6.139h.877a5.26 5.26 0 0 1 5.262-5.261v-1.754a7.015 7.015 0 0 0-7.016 7.015zm6.139-6.138v.877a5.26 5.26 0 0 1 5.261 5.261h1.754a7.015 7.015 0 0 0-7.015-7.015zm4.384 27.185h-.877a3.51 3.51 0 0 1-3.507 3.507v1.754a5.26 5.26 0 0 0 5.261-5.261zm-4.384 4.384v-.877a3.51 3.51 0 0 1-3.508-3.507H35.26a5.26 5.26 0 0 0 5.262 5.261zm-4.385-4.384h.877a3.51 3.51 0 0 1 3.508-3.508V35.26a5.26 5.26 0 0 0-5.262 5.262zm4.385-4.385v.877a3.51 3.51 0 0 1 3.507 3.508h1.754a5.26 5.26 0 0 0-5.261-5.262zm0 .877h.876V35.26h-1.753v1.754zm3.508 3.508v.876h1.753v-1.753h-1.753zm-3.508 5.261h.876V44.03h-1.753v1.754zm-5.261-5.261v.876h1.753v-1.753h-1.753zm-9.647-21.047h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.016zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.262h-1.754a7.015 7.015 0 0 0 7.015 7.016zm-6.138-6.139h.877a5.26 5.26 0 0 1 5.261-5.261v-1.754a7.015 7.015 0 0 0-7.015 7.015zm6.138-6.138v.877a5.26 5.26 0 0 1 5.262 5.261h1.754a7.015 7.015 0 0 0-7.016-7.015z",viewW:60,viewH:60},tv:{d:"M45.134 10.766H6.18c-1.292 0-2.34.848-2.34 1.894v2.68c0 1.045 1.048 1.893 2.34 1.893h38.954m0-6.467V5.288c0-1.046 1.048-1.894 2.34-1.894h26.704c1.292 0 2.34.848 2.34 1.894v5.478m-31.384 0h31.384m0 0h37.302c1.293 0 2.34.848 2.34 1.894v2.68c0 1.045-1.047 1.893-2.34 1.893H76.518m-31.384 0v5.479c0 1.046 1.048 1.894 2.34 1.894h26.704c1.292 0 2.34-.848 2.34-1.894v-5.479m-31.384 0h31.384",viewW:120,viewH:28},tv_wall:{d:"M35.664 11.4c-.517 0-.936.269-.936.6s.419.6.936.6zm49.553 1.2c.517 0 .936-.269.936-.6s-.42-.6-.936-.6zM6.18 3v.6h107.64V2.4H6.18zm109.98 1.5h-.936v1.8h1.872V4.5zm-2.34 3.3v-.6H6.18v1.2h107.64zM3.84 6.3h.936V4.5H2.904v1.8zm2.34 1.5v-.6c-.775 0-1.404-.403-1.404-.9H2.904c0 1.16 1.467 2.1 3.276 2.1zm109.98-1.5h-.936c0 .497-.629.9-1.404.9v1.2c1.81 0 3.276-.94 3.276-2.1zM113.82 3v.6c.775 0 1.404.403 1.404.9h1.872c0-1.16-1.467-2.1-3.276-2.1zM6.18 3v-.6c-1.81 0-3.276.94-3.276 2.1h1.872c0-.497.629-.9 1.404-.9zm61.308 4.2h-.936V12h1.872V7.2zM52.512 12h.936V7.2h-1.872V12zm-16.848 0v.6h49.553v-1.2H35.664z",viewW:120,viewH:15},toilet:{d:"M3.555 48.976c0 9.55 7.125 17.29 15.914 17.29h1.061c8.79 0 15.914-7.74 15.914-17.29V5.966c0-1.233-.92-2.233-2.056-2.233H5.611c-1.135 0-2.056 1-2.056 2.234z M7.666 49.12c0 7.003 5.225 12.68 11.67 12.68h1.327c6.445 0 11.67-5.677 11.67-12.68V31.873c0-1.233-.92-2.233-2.056-2.233H9.722c-1.135 0-2.056 1-2.056 2.233zM33.792 3.733c1.465 0 2.652 1.29 2.652 2.882v12.103c0 1.592-1.187 2.882-2.652 2.882H6.208c-1.465 0-2.653-1.29-2.653-2.882V6.615c0-1.591 1.188-2.882 2.653-2.882z M24.11 50.186c0 2.467-1.84 4.467-4.11 4.467s-4.111-2-4.111-4.467 1.84-4.466 4.11-4.466 4.112 2 4.112 4.466",viewW:40,viewH:70},toilet_built_in:{d:"M3.555 34.56c0 9.263 7.125 16.774 15.914 16.774h1.061c8.79 0 15.914-7.51 15.914-16.775V5.833c0-1.196-.92-2.166-2.056-2.166H5.611c-1.135 0-2.056.97-2.056 2.166z M7.666 34.7c0 6.793 5.225 12.3 11.67 12.3h1.327c6.445 0 11.67-5.507 11.67-12.3V14.5c0-1.197-.92-2.167-2.056-2.167H9.722c-1.135 0-2.056.97-2.056 2.167z M24.11 35.733c0 2.394-1.84 4.334-4.11 4.334s-4.111-1.94-4.111-4.334 1.84-4.333 4.11-4.333 4.112 1.94 4.112 4.333",viewW:40,viewH:55},bathtub:{d:"M3.885 6c0-1.243 1.068-2.25 2.386-2.25h157.458c1.318 0 2.386 1.007 2.386 2.25v63c0 1.243-1.068 2.25-2.386 2.25H6.27c-1.318 0-2.386-1.007-2.386-2.25z M13.428 37.5c0-13.669 11.75-24.75 26.243-24.75h90.658c14.493 0 26.243 11.081 26.243 24.75s-11.75 24.75-26.243 24.75H39.67c-14.493 0-26.243-11.081-26.243-24.75 M31.56 37.5c0 2.237-1.923 4.05-4.295 4.05s-4.294-1.813-4.294-4.05 1.923-4.05 4.294-4.05c2.372 0 4.295 1.813 4.295 4.05",viewW:170,viewH:75},bathtub_corner:{d:"M3.862 6.224a2.36 2.36 0 0 1 2.362-2.362H133.97c1.197 0 2.168.97 2.168 2.168 0 71.857-58.251 130.108-130.108 130.108a2.17 2.17 0 0 1-2.168-2.168z M13.31 32.207c0-10.437 8.46-18.897 18.897-18.897h87.628a2.13 2.13 0 0 1 2.13 2.13c0 58.833-47.692 106.526-106.524 106.526a2.13 2.13 0 0 1-2.13-2.131z M32.207 27.483a4.724 4.724 0 1 1-9.449 0 4.724 4.724 0 0 1 9.449 0",viewW:140,viewH:140},bidet:{d:"M22.466 3.692v10.085c0 1.21-.92 2.192-2.055 2.192h-.822c-1.136 0-2.056-.981-2.056-2.192V3.692m4.933 8.77h2.878c1.135 0 2.056-.982 2.056-2.193v-.877c0-1.21-.92-2.192-2.056-2.192h-2.878m-4.933 5.262h-2.878c-1.135 0-2.055-.982-2.055-2.193v-.877c0-1.21.92-2.192 2.055-2.192h2.878M5.611 3.692h28.777c1.136 0 2.056.981 2.056 2.192v33.45c0 9.374-7.125 16.973-15.914 16.973h-1.06c-8.79 0-15.915-7.599-15.915-16.972V5.885c0-1.212.92-2.193 2.056-2.193m4.11 15.785h20.556c1.136 0 2.056.981 2.056 2.192v17.807c0 6.874-5.225 12.447-11.67 12.447h-1.327c-6.445 0-11.67-5.573-11.67-12.447V21.67c0-1.21.92-2.192 2.056-2.192m13.567 7.892c0 1.937-1.472 3.508-3.288 3.508-1.817 0-3.29-1.57-3.29-3.508s1.473-3.507 3.29-3.507 3.288 1.57 3.288 3.507",viewW:40,viewH:60},bidet_built_in:{d:"M17.318 12.182h-8.06c-.88 0-1.592.74-1.592 1.654v16.126c0 6.698 5.225 12.129 11.67 12.129h1.327c6.445 0 11.67-5.43 11.67-12.13V13.837c0-.914-.713-1.654-1.591-1.654H22.68m-.215-8.545v9.827c0 1.18-.92 2.136-2.055 2.136h-.822c-1.136 0-2.056-.956-2.056-2.136V3.637m10.689 8.545V3.637m-16.445 0v8.545M5.611 3.637h28.777c1.136 0 2.056.956 2.056 2.136v24.051c0 9.135-7.125 16.54-15.914 16.54h-1.06c-8.79 0-15.915-7.405-15.915-16.54V5.773c0-1.18.92-2.136 2.056-2.136M23.289 23.29c0 1.888-1.473 3.418-3.29 3.418s-3.288-1.53-3.288-3.418 1.472-3.418 3.289-3.418c1.816 0 3.288 1.53 3.288 3.418",viewW:40,viewH:50},kitchen_sink:{d:"M38.188 8.7h10.598c1.211 0 2.193.956 2.193 2.136v28.2c0 1.18-.982 2.136-2.193 2.136H11.08c-1.21 0-2.192-.956-2.192-2.136v-28.2c0-1.18.981-2.136 2.192-2.136h10.599m10.885-5.128V15.11c0 1.18-.981 2.136-2.192 2.136h-.877c-1.21 0-2.192-.957-2.192-2.136V3.572m5.261 7.691h3.07c1.21 0 2.192-.956 2.192-2.136v-.855c0-1.18-.982-2.136-2.192-2.136h-3.07m-5.261 5.127h-3.07c-1.21 0-2.192-.956-2.192-2.136v-.855c0-1.18.982-2.136 2.193-2.136h3.069M5.817 46.299h48.231c1.21 0 2.192-.956 2.192-2.136V5.709c0-1.18-.981-2.137-2.192-2.137H5.818c-1.211 0-2.193.957-2.193 2.137v38.454c0 1.18.982 2.136 2.192 2.136M33.44 25.79c0 1.888-1.57 3.418-3.507 3.418s-3.508-1.53-3.508-3.418c0-1.887 1.57-3.418 3.508-3.418s3.507 1.53 3.507 3.418",viewW:60,viewH:50},kitchen_sink_double:{d:"M53.173 12.182c-.468 0-.847.354-.847.79s.38.79.847.79zm21.979 1.58c.467 0 .846-.353.846-.79 0-.436-.379-.79-.846-.79zM6.01 3.572v.79h77.842v-1.58H6.01zM86.14 5.71h-.847v38.454h1.694V5.709zM83.85 46.3v-.79H6.01v1.58h77.842zM3.72 44.163h.847V5.709H2.873v38.454zm2.29 2.136v-.79c-.797 0-1.443-.603-1.443-1.346H2.873c0 1.616 1.404 2.926 3.137 2.926zm80.131-2.136h-.847c0 .743-.646 1.346-1.442 1.346v1.58c1.732 0 3.136-1.31 3.136-2.926zm-2.29-40.59v.79c.797 0 1.443.602 1.443 1.346h1.694c0-1.617-1.404-2.927-3.136-2.927zm-77.841 0v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.744.646-1.347 1.443-1.347zm5.494 37.599v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2h-1.694v28.2zm-32.97-28.2h-.846v28.2h1.694v-28.2zM39.895 8.7v-.79h-5.669v1.58h5.669zm-22.721 0v-.79h-5.669v1.58h5.669zm-7.958 2.136h.847c0-.744.645-1.346 1.442-1.346V7.91c-1.732 0-3.136 1.31-3.136 2.926zm32.968 0h.847c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.442.603 1.442 1.347zm-2.29 30.336v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.645 1.346-1.442 1.346zm-28.389 0v-.79c-.797 0-1.442-.603-1.442-1.346H8.368c0 1.616 1.404 2.926 3.136 2.926zm13.737-23.927v.79h.916v-1.58h-.916zm3.205-2.136h.847V3.572H27.6V15.11zM22.952 3.572h-.847V15.11h1.693V3.572zm3.205 13.673v.79c1.732 0 3.136-1.31 3.136-2.926H27.6c0 .743-.646 1.346-1.443 1.346zm-.916 0v-.79c-.797 0-1.443-.603-1.443-1.346h-1.693c0 1.616 1.404 2.926 3.136 2.926zm3.205-5.982v.79h3.206v-1.58h-3.206zm5.495-2.136h.847v-.855h-1.694v.855zm-2.29-2.991v-.79h-3.205v1.58h3.206zm2.29 2.136h.847c0-1.616-1.404-2.926-3.136-2.926v1.58c.796 0 1.442.603 1.442 1.346zm-2.29 2.991v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.646 1.346-1.442 1.346zm-11.905 0v.79h3.206v-1.58h-3.206zm3.206-5.127v-.79h-3.206v1.58h3.206zm-5.495 2.136h-.847v.855h1.694v-.855zm2.29-2.136v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.743.646-1.346 1.442-1.346zm0 5.127v-.79c-.797 0-1.443-.603-1.443-1.346H16.61c0 1.616 1.404 2.926 3.136 2.926zm9.615 14.527h-.847c0 1.452-1.26 2.628-2.816 2.628v1.58c2.49 0 4.51-1.884 4.51-4.208zM25.7 29.208v-.79c-1.555 0-2.816-1.176-2.816-2.628H21.19c0 2.324 2.02 4.209 4.51 4.209zm-3.663-3.418h.847c0-1.451 1.26-2.628 2.816-2.628v-1.58c-2.49 0-4.51 1.884-4.51 4.208zm3.663-3.418v.79c1.555 0 2.816 1.177 2.816 2.628h1.694c0-2.324-2.02-4.208-4.51-4.208zm24.268 18.8v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2H79.8v28.2zM78.356 8.7v-.79h-28.39v1.58h28.39zm-30.68 2.136h-.846v28.2h1.694v-28.2zm2.29-2.136v-.79c-1.732 0-3.136 1.31-3.136 2.926h1.694c0-.744.646-1.346 1.442-1.346zm30.68 2.136h.846c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.443.603 1.443 1.347zm-2.29 30.336v.79c1.732 0 3.136-1.31 3.136-2.926H79.8c0 .743-.646 1.346-1.443 1.346zm-28.39 0v-.79c-.796 0-1.442-.603-1.442-1.346H46.83c0 1.616 1.404 2.926 3.136 2.926zm3.206-28.2v.79h21.979v-1.58h-21.98z",viewW:90,viewH:50}};export{c as FURNITURE_ART_FINGERPRINT,a as GENERATED_FURNITURE_ART}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";const c="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33",v={coffee_table:{d:"M3.84 5.884c0-1.21 1.048-2.192 2.34-2.192h107.64c1.293 0 2.34.981 2.34 2.192v48.23c0 1.212-1.047 2.193-2.34 2.193H6.18c-1.292 0-2.34-.981-2.34-2.192z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},coffee_table_round:{d:"M3.765 40a36.235 36.235 0 1 0 72.47 0 36.235 36.235 0 1 0-72.47 0 m56.26 26.96-3.843-3.843a.906.906 0 0 1 0-1.28l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.843 3.844a.906.906 0 0 1 0 1.28l-3.843 3.844a.906.906 0 0 1-1.281 0m-34.423-34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.844a.906.906 0 0 1 0 1.28l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.843a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.843a.906.906 0 0 1-1.28 0",viewW:80,viewH:80},coffee_table_oval:{d:"M3.84 30c0-14.53 12.572-26.308 28.08-26.308h56.16c15.509 0 28.08 11.778 28.08 26.308s-12.571 26.307-28.08 26.307H31.92C16.412 56.307 3.84 44.53 3.84 30 M80.592 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877M31.92 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876",viewW:120,viewH:60},coffee_table_rounded:{d:"M3.84 12.461c0-4.843 4.19-8.77 9.36-8.77h93.6c5.17 0 9.36 3.927 9.36 8.77v35.077c0 4.843-4.19 8.77-9.36 8.77H13.2c-5.17 0-9.36-3.927-9.36-8.77z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},table_dining:{d:"M3.879 6.08c0-1.265 1.065-2.29 2.378-2.29h147.484c1.314 0 2.38 1.025 2.38 2.29v77.84c0 1.265-1.066 2.29-2.38 2.29H6.257c-1.313 0-2.378-1.025-2.378-2.29z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},table_round:{d:"M3.826 55a51.174 51.174 0 1 0 102.349 0A51.174 51.174 0 1 0 3.826 55 m81.005 32.303-3.947-3.947a.93.93 0 0 1 0-1.316l3.947-3.948a.93.93 0 0 1 1.316 0l3.948 3.948a.93.93 0 0 1 0 1.316l-3.948 3.947a.93.93 0 0 1-1.316 0m0 54.897-3.947-3.948a.93.93 0 0 1 0-1.316l3.947-3.947a.93.93 0 0 1 1.316 0l3.948 3.947a.93.93 0 0 1 0 1.316L82.32 87.2a.93.93 0 0 1-1.316 0M27.04 32.304l-3.947-3.948a.93.93 0 0 1 0-1.315l3.948-3.948a.93.93 0 0 1 1.315 0l3.948 3.948a.93.93 0 0 1 0 1.315l-3.948 3.948a.93.93 0 0 1-1.315 0m-.001 54.604-3.947-3.948a.93.93 0 0 1 0-1.316l3.948-3.947a.93.93 0 0 1 1.315 0l3.948 3.947a.93.93 0 0 1 0 1.316l-3.948 3.948a.93.93 0 0 1-1.315 0",viewW:110,viewH:110},table_dining_oval:{d:"M3.892 50c0-25.51 21.418-46.19 47.838-46.19h76.54c26.42 0 47.839 20.68 47.839 46.19S154.69 96.19 128.27 96.19H51.73C25.31 96.19 3.892 75.51 3.892 50 M122.53 19.514V13.97a.957.924 0 0 1 .956-.924h5.74a.957.924 0 0 1 .958.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m.001 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.957-.924M49.816 19.515v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .958.924v5.542a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m0 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.923h-5.74a.957.924 0 0 1-.957-.924",viewW:180,viewH:100},table_dining_rounded:{d:"M3.879 17.527c0-7.587 6.39-13.737 14.272-13.737h123.696c7.883 0 14.273 6.15 14.273 13.737v54.947c0 7.587-6.39 13.737-14.273 13.737H18.151c-7.882 0-14.272-6.15-14.272-13.737z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},desk:{d:"M3.862 5.967c0-1.234 1.057-2.234 2.362-2.234h127.552c1.305 0 2.362 1 2.362 2.234v58.066c0 1.234-1.057 2.233-2.362 2.233H6.224c-1.305 0-2.362-1-2.362-2.233z M9.531 15.346v-5.36a.945.893 0 0 1 .945-.893h5.67a.945.893 0 0 1 .944.893v5.36a.945.893 0 0 1-.945.894h-5.669a.945.893 0 0 1-.945-.894m113.379.001v-5.36a.945.893 0 0 1 .945-.894h5.67a.945.893 0 0 1 .944.894v5.36a.945.893 0 0 1-.945.893h-5.669a.945.893 0 0 1-.945-.893M9.53 60.013v-5.36a.945.893 0 0 1 .946-.893h5.669a.945.893 0 0 1 .945.893v5.36a.945.893 0 0 1-.945.894h-5.67a.945.893 0 0 1-.944-.894m113.38.001v-5.36a.945.893 0 0 1 .945-.894h5.669a.945.893 0 0 1 .945.894v5.36a.945.893 0 0 1-.945.893h-5.67a.945.893 0 0 1-.944-.893m-97.318-2.681h88.814",viewW:140,viewH:70},desk_corner:{d:"M156.12 66.202a2.38 2.38 0 0 1-2.379 2.38H94.272c-13.138 0-23.788 10.65-23.788 23.787v61.372a2.38 2.38 0 0 1-2.379 2.38H6.257a2.38 2.38 0 0 1-2.378-2.38V6.257A2.38 2.38 0 0 1 6.257 3.88h147.484a2.38 2.38 0 0 1 2.38 2.378z M9.588 16.249v-5.71a.95.95 0 0 1 .951-.95h5.71a.95.95 0 0 1 .95.95v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m133.212.001v-5.71a.95.95 0 0 1 .951-.951h5.71a.95.95 0 0 1 .95.951v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m0 45.672v-5.71a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.95-.951M9.587 149.46v-5.708a.95.95 0 0 1 .952-.952h5.709a.95.95 0 0 1 .951.952v5.709a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.951-.951m47.576 0v-5.709a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.95h-5.71a.95.95 0 0 1-.951-.95m51.382-90.396H95.569a34.6 34.6 0 0 0-34.6 34.6v12.976",viewW:160,viewH:160},chair:{d:"M39.452 12.433H10.548a4.398 4.398 0 1 1 0-8.796h28.904a4.398 4.398 0 0 1 0 8.796m-28.904 0H8.035a4.4 4.4 0 0 0-4.398 4.399V40.08a6.283 6.283 0 0 0 6.283 6.284h30.16a6.283 6.283 0 0 0 6.284-6.284V16.832c0-2.43-1.97-4.399-4.399-4.399h-2.513",viewW:50,viewH:50},chair_bar:{d:"M38.579 17.168c1.326 2.526 1.947 6.015 1.947 9.071 0 10.018-8.07 18.139-18.025 18.139S4.475 36.257 4.475 26.239c0-3.056.586-6.552 1.912-9.078m32.192.007a3.59 3.59 0 0 1-3.333-.976m3.333.976a3.6 3.6 0 0 0 1.765-.976m-33.827.996-.13-.027a3.6 3.6 0 0 1-1.731-.969m30.59 0a18 18 0 0 0-5.848-3.932 17.93 17.93 0 0 0-13.796 0 18 18 0 0 0-5.848 3.932 3.59 3.59 0 0 1-3.237.996m28.729-.996a3.59 3.59 0 0 0 5.098 0m-33.827.996a3.6 3.6 0 0 1-1.861-.996 3.644 3.644 0 0 1 0-5.13 25.2 25.2 0 0 1 8.187-5.505A25.1 25.1 0 0 1 22.5 3.623a25.1 25.1 0 0 1 9.657 1.934 25.2 25.2 0 0 1 8.187 5.505 3.644 3.644 0 0 1 0 5.13",viewW:45,viewH:48},armchair:{d:"M75.702 13.011q.012-.225.012-.453c0-4.843-3.917-8.768-8.748-8.768H23.034c-4.83 0-8.747 3.925-8.747 8.768q0 .228.011.453M77.132 72.09q.59.091 1.206.092c4.348 0 7.873-3.533 7.873-7.892V20.45c0-4.359-3.525-7.892-7.873-7.892-.924 0-1.812.16-2.636.453a7.89 7.89 0 0 0-5.237 7.438v.148m0 0a8.7 8.7 0 0 1-3.499.73H23.034a8.7 8.7 0 0 1-3.499-.73m50.93 0V64.29a7.89 7.89 0 0 0 6.667 7.8M14.298 13.01a7.89 7.89 0 0 1 5.237 7.438v.148m0 0V64.29a7.89 7.89 0 0 1-6.666 7.8q-.59.091-1.206.092c-4.348 0-7.873-3.533-7.873-7.892V20.45c0-4.359 3.525-7.892 7.873-7.892.924 0 1.811.16 2.635.453M77.132 72.09c-1.585 8.05-8.667 14.12-17.164 14.12H30.032c-8.496 0-15.578-6.07-17.163-14.12",viewW:90,viewH:90},armchair_office:{d:"M56.968 18.845q0-.368-.05-.72M49.051 13.8H15.95a5.04 5.04 0 0 1-5.038-5.043 5.04 5.04 0 0 1 5.038-5.043h33.103a5.04 5.04 0 0 1 5.038 5.043 5.04 5.04 0 0 1-5.038 5.043m-33.103 0h-2.88a5.04 5.04 0 0 0-4.986 4.323M49.052 13.8h2.879a5.04 5.04 0 0 1 4.986 4.324m.051 24.826a4.32 4.32 0 0 0 4.318-4.323v-16.18a4.32 4.32 0 0 0-4.369-4.322m.051 24.826a4.32 4.32 0 0 1-4.318-4.323V22.447a4.32 4.32 0 0 1 4.267-4.322m-11.84 37.24h4.695c.736 0 1.446-.111 2.115-.317a7.21 7.21 0 0 0 5.081-6.889v-5.208M8.084 18.124h-.051a4.32 4.32 0 0 0-4.318 4.323v16.18a4.32 4.32 0 0 0 4.318 4.324 4.32 4.32 0 0 0 4.317-4.323V22.447a4.32 4.32 0 0 0-4.266-4.323m11.935 37.24h-4.79a7.2 7.2 0 0 1-2.04-.294 7.21 7.21 0 0 1-5.156-6.91v-5.21m37.045 12.414 5.177 5.183c.969.97 2.534.987 3.524.038a2.526 2.526 0 0 0 .038-3.605l-1.93-1.932m-6.81.316H20.02m-6.83-.294-1.909 1.91c-.998 1-.98 2.627.038 3.605.99.949 2.555.932 3.524-.038l5.177-5.183",viewW:65,viewH:65},sofa:{d:"M90 19.365v57.111m0-57.11V7.683m0 11.681c0 2.151-1.836 3.894-4.1 3.894H30.544a10.7 10.7 0 0 1-4.136-.825M90 19.365c0 2.151 1.836 3.894 4.1 3.894h55.356c1.472 0 2.871-.294 4.137-.825M90 76.476c0 5.376-4.59 9.735-10.25 9.735H30.543c-5.266 0-9.605-3.772-10.185-8.625M90 76.476c0 5.376 4.59 9.735 10.25 9.735h49.206c5.266 0 9.605-3.772 10.185-8.625M90 7.684c0-2.15-1.837-3.894-4.101-3.894H30.544c-5.661 0-10.25 4.358-10.25 9.735q0 .416.036.825M90 7.684c0-2.15 1.836-3.894 4.1-3.894h55.356c5.661 0 10.25 4.358 10.25 9.735q0 .416-.036.825m0 0a10.7 10.7 0 0 1 4.137-.825h2.05c5.662 0 10.252 4.358 10.252 9.734v45.43c0 5.376-4.59 9.734-10.251 9.734h-2.05c-1.484 0-2.894-.3-4.167-.837m0 0c-3.585-1.517-6.084-4.93-6.084-8.898V23.26q0-.417.036-.825c.32-3.622 2.728-6.68 6.077-8.084m-139.34 0c3.35 1.404 5.758 4.462 6.078 8.084q.036.408.036.825v45.43c0 3.967-2.5 7.38-6.085 8.897a10.7 10.7 0 0 1-4.166.837h-2.05c-5.662 0-10.251-4.358-10.251-9.735V23.26c0-5.376 4.59-9.734 10.25-9.734h2.05c1.473 0 2.872.294 4.138.825",viewW:180,viewH:90},sofa_three_seat:{d:"M86.553 18.593V76.96m0-58.366V7.491m0 11.102c0 2.044-1.762 3.701-3.935 3.701H29.496c-1.413 0-2.756-.28-3.97-.784m61.027-2.917c0 2.044 1.762 3.701 3.935 3.701h59.024c2.174 0 3.935-1.657 3.935-3.7M86.553 76.958c0 5.11-4.404 9.252-9.837 9.252h-47.22c-5.054 0-9.218-3.585-9.775-8.198m66.832-1.054c0 5.11 4.404 9.252 9.837 9.252h47.22c5.433 0 9.837-4.142 9.837-9.252m0-58.366V76.96m0-58.366V7.491m0 11.102c0 2.044 1.762 3.701 3.936 3.701h53.122c1.413 0 2.756-.28 3.97-.784m-61.028 55.449c0 5.11 4.405 9.252 9.838 9.252h47.22c5.054 0 9.218-3.585 9.775-8.198M86.553 7.491c0-2.044-1.762-3.701-3.935-3.701H29.496c-5.433 0-9.838 4.142-9.838 9.252q0 .396.035.784m66.86-6.335c0-2.044 1.762-3.701 3.935-3.701h59.024c2.174 0 3.935 1.657 3.935 3.7m0 0c0-2.043 1.762-3.7 3.936-3.7h53.122c5.433 0 9.838 4.142 9.838 9.252 0 .258.022.517 0 .77m-.063 64.201c1.22.512 2.574.796 3.998.796h1.967c5.433 0 9.837-4.142 9.837-9.252V22.294c0-5.11-4.404-9.252-9.837-9.252h-1.967c-5.153 0-9.38 3.725-9.803 8.468q-.036.387-.035.784v47.263c0 3.771 2.399 7.015 5.84 8.456M19.693 13.826a10.3 10.3 0 0 0-3.97-.784h-1.967c-5.433 0-9.838 4.142-9.838 9.252v47.263c0 5.11 4.405 9.252 9.838 9.252h1.967c1.424 0 2.777-.284 3.998-.796 3.441-1.441 5.84-4.685 5.84-8.456V22.294a9 9 0 0 0-.035-.784c-.307-3.443-2.618-6.349-5.833-7.684",viewW:240,viewH:90},sofa_corner_right:{d:"M93.673 20.687V83.69m0-63.004v-12.6m0 12.6c0 2.32-1.913 4.2-4.273 4.2H31.704a10.8 10.8 0 0 1-4.311-.89m66.28-3.31c0 2.32 1.914 4.2 4.274 4.2h64.106c2.36 0 4.274-1.88 4.274-4.2M93.673 83.692c0 5.8-4.783 10.501-10.684 10.501H31.704c-5.489 0-10.011-4.068-10.616-9.304m72.585-1.197c0 5.8 4.784 10.501 10.684 10.501h51.286c5.9 0 10.684-4.701 10.684-10.5m0-63.005V83.69m0-63.004v-12.6m0 12.6c0 2.32 1.914 4.2 4.273 4.2h57.696c1.534 0 2.993-.317 4.312-.89m-66.28 59.695v71.923c0 5.799 4.782 10.5 10.684 10.5h51.284c5.49 0 10.012-4.068 10.616-9.304V84.888M93.673 8.086c0-2.32-1.913-4.2-4.273-4.2H31.704c-5.9 0-10.684 4.7-10.684 10.5q0 .45.038.89m72.615-7.19c0-2.32 1.914-4.2 4.274-4.2h64.106c2.36 0 4.274 1.88 4.274 4.2m0 0c0-2.32 1.914-4.2 4.273-4.2h57.696c5.9 0 10.685 4.7 10.685 10.5 0 .293.024.587 0 .874m-.07 69.628c1.327.58 2.797.904 4.344.904h2.136c5.901 0 10.684-4.702 10.684-10.501V24.887c0-5.8-4.783-10.5-10.684-10.5h-2.136c-5.596 0-10.187 4.227-10.647 9.61q-.038.44-.038.89V75.29c0 4.28 2.605 7.961 6.342 9.597M21.059 15.276a10.8 10.8 0 0 0-4.312-.89H14.61c-5.9 0-10.684 4.701-10.684 10.5v50.405c0 5.8 4.783 10.5 10.684 10.5h2.137c1.546 0 3.016-.322 4.342-.903 3.737-1.636 6.342-5.317 6.342-9.597V24.887q0-.45-.037-.89c-.334-3.907-2.844-7.206-6.335-8.72",viewW:260,viewH:170},bed_single:{d:"M3.79 14.024c0 5.59 4.318 10.122 9.645 10.122h63.13c5.328 0 9.646-4.532 9.646-10.122m-22.797 46.93V46.23c0-5.082-3.926-9.201-8.769-9.201h-19.29c-4.842 0-8.768 4.12-8.768 9.201v14.723m-22.797 0h82.42m0 22.085H3.79m8.768 113.06h64.885c4.842 0 8.768-4.12 8.768-9.202V13.104c0-5.082-3.926-9.202-8.768-9.202H12.558c-4.843 0-8.768 4.12-8.768 9.202v173.792c0 5.082 3.925 9.202 8.768 9.202",viewW:90,viewH:200},bed_double:{d:"M3.879 14.073c0 5.618 4.516 10.172 10.088 10.172h132.065c5.571 0 10.088-4.554 10.088-10.172m-81.165 47.16V46.438c0-5.107-4.106-9.247-9.171-9.247H45.607c-5.065 0-9.17 4.14-9.17 9.247v14.795m89.877 0V46.438c0-5.107-4.107-9.247-9.172-9.247H96.966c-5.065 0-9.171 4.14-9.171 9.247v14.795m-83.916 0H156.12m0 22.192H3.88m9.17 112.673h133.9c5.065 0 9.171-4.14 9.171-9.247V13.15c0-5.107-4.106-9.247-9.171-9.247H13.05c-5.064 0-9.17 4.14-9.17 9.247v173.7c0 5.107 4.106 9.247 9.17 9.247",viewW:160,viewH:200},nightstand:{d:"M5.773 3.555h38.454a2.136 2.056 0 0 1 2.137 2.056v28.777a2.136 2.056 0 0 1-2.137 2.056H5.773a2.136 2.056 0 0 1-2.136-2.056V5.611a2.136 2.056 0 0 1 2.136-2.056",viewW:50,viewH:40},cabinet_tv:{d:"M56.772 17.88h5.315m0 0h5.315m-5.315 0v9.214m9.832-9.214 5.315 9.45 5.314-9.45M6.224 41.4h127.552c1.305 0 2.362-.94 2.362-2.1V5.7c0-1.16-1.057-2.1-2.362-2.1H6.224c-1.305 0-2.362.94-2.362 2.1v33.6c0 1.16 1.057 2.1 2.362 2.1",viewW:140,viewH:45},cabinet_shoe:{d:"m39.722 16.231 1.505-1.596m1.134 3.15 1.53-1.738M6.03 31.5h67.94c1.251 0 2.265-.895 2.265-2v-24c0-1.105-1.014-2-2.264-2H6.03c-1.251 0-2.265.895-2.265 2v24c0 1.105 1.014 2 2.265 2m41.966-14.305L46.92 17.1a3.4 3.4 0 0 1-1.813-.706l-4.583-3.62c-1.264-1-3.277-.326-3.475 1.161-.185 1.39-1.983 2.1-3.28 1.299l-1.532-.947c-.968-.513-2.2.103-2.2 1.1v3.463c0 1.559 1.43 2.823 3.196 2.823h14.51c1.404 0 2.542-1.005 2.542-2.245 0-1.153-.99-2.118-2.289-2.233",viewW:80,viewH:35},cabinet_sink:{d:"M3.765 5.773c0-1.18 1.014-2.136 2.265-2.136h67.94c1.251 0 2.265.956 2.265 2.136v38.454c0 1.18-1.014 2.137-2.264 2.137H6.03c-1.251 0-2.265-.957-2.265-2.137z M36.088 32.135c2.525 1.88 6.205 1.88 8.73 0s3.167-5.101 1.52-7.637l-5.879-8.043-5.893 8.043c-1.644 2.536-1.003 5.755 1.522 7.637",viewW:80,viewH:50},bookshelf:{d:"M57.12 20.488H45.473c-.514 0-1.008.124-1.372.345s-.568.52-.568.832m4.076-8.236h5.434M6.119 3.5h87.762c1.276 0 2.31.895 2.31 2v24c0 1.105-1.034 2-2.31 2H6.12c-1.275 0-2.31-.895-2.31-2v-24c0-1.105 1.035-2 2.31-2m51 6.4v14.118H45.474a2.04 2.04 0 0 1-1.372-.517 1.7 1.7 0 0 1-.568-1.248V11.665c0-.468.204-.917.568-1.248a2.04 2.04 0 0 1 1.372-.517z",viewW:100,viewH:35},wall_unit:{d:"M6.336 41.4h227.328a2.418 2.1 0 0 0 2.418-2.1V5.7a2.418 2.1 0 0 0-2.418-2.1H6.336a2.418 2.1 0 0 0-2.418 2.1v33.6a2.418 2.1 0 0 0 2.418 2.1m43.744-5.88V9.48m46.432 26.04V9.48m46.433 26.04V9.48m46.433 26.04V9.48",viewW:240,viewH:45},wardrobe:{d:"M93.87 20.25a3.3 3.3 0 0 0-1.072-2.407 3.8 3.8 0 0 0-2.586-.997c-.97 0-1.9.358-2.587.997a3.3 3.3 0 0 0-1.071 2.407c0 2.838 1.225 5.107 3.658 6.81h-.015m0 0 14.58 7.537c.57.295 1.046.726 1.377 1.25.331.523.505 1.12.505 1.727v1.401a3.3 3.3 0 0 1-1.071 2.407 3.8 3.8 0 0 1-2.587.998H77.393a3.8 3.8 0 0 1-2.586-.998 3.3 3.3 0 0 1-1.072-2.407v-1.4c0-.608.174-1.205.505-1.728a3.55 3.55 0 0 1 1.377-1.25zM6.284 3.691h167.433c1.32 0 2.392.981 2.392 2.192v48.23c0 1.212-1.071 2.193-2.392 2.193H6.284c-1.321 0-2.392-.981-2.392-2.192V5.885c0-1.212 1.07-2.193 2.392-2.193",viewW:180,viewH:60},kitchen_floor:{d:"M3.692 5.884c0-1.21.981-2.192 2.192-2.192h48.23c1.212 0 2.193.981 2.193 2.192v48.23a2.19 2.19 0 0 1-2.192 2.193H5.885a2.19 2.19 0 0 1-2.193-2.192z",viewW:60,viewH:60},kitchen_floor_corner:{d:"M45.944 41.767a2.29 2.29 0 0 0 2.29 2.29H83.92a2.29 2.29 0 0 1 2.29 2.29V83.92a2.29 2.29 0 0 1-2.29 2.29H6.08a2.29 2.29 0 0 1-2.29-2.29V6.08a2.29 2.29 0 0 1 2.29-2.29h37.576a2.29 2.29 0 0 1 2.29 2.29z",viewW:90,viewH:90},kitchen_wall:{d:"m4.444 31.033 50.75-27.007m-50.752-.06 50.75 27.008M5.884 31.5h48.23c1.212 0 2.193-.895 2.193-2v-24c0-1.105-.981-2-2.192-2H5.885c-1.212 0-2.193.895-2.193 2v24c0 1.105.981 2 2.192 2",viewW:60,viewH:35},kitchen_wall_corner:{d:"M3.772 29.59 29.88 4.383M4.57 55.43 55.43 30M4.175 4.383l26.701 23.863m-27.184.877L55.43 55.43M28.41 3.692H5.884c-1.21 0-2.192.981-2.192 2.192v48.23c0 1.212.981 2.193 2.192 2.193h48.23a2.19 2.19 0 0 0 2.193-2.192V31.589c0-1.21-.981-2.192-2.192-2.192h-21.32a2.19 2.19 0 0 1-2.193-2.192V5.885a2.19 2.19 0 0 0-2.192-2.193",viewW:60,viewH:60},shelf_floor:{d:"M6.12 31.5h87.76a2.31 2 0 0 0 2.31-2v-24a2.31 2 0 0 0-2.31-2H6.12a2.31 2 0 0 0-2.31 2v24a2.31 2 0 0 0 2.31 2 M9.089 25.933c-.494.112-.776.546-.63.97s.664.675 1.157.564l-.263-.767zM90.912 9.067c.493-.112.775-.546.63-.97s-.664-.675-1.158-.564l.264.767zM11.875 26.956c.493-.112.775-.546.63-.97s-.664-.676-1.158-.564l.264.767zm3.988-2.556c-.493.112-.775.546-.63.969s.664.676 1.158.564l-.264-.766zm5.045.511c.493-.112.775-.545.63-.969s-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.111-.775.545-.63.968.146.424.664.677 1.158.565l-.264-.767zm5.044.51c.494-.111.776-.545.63-.968-.145-.424-.664-.676-1.157-.565l.263.767zm3.99-2.555c-.495.112-.777.546-.63.97.145.423.663.675 1.157.563l-.264-.766zm5.043.511c.494-.112.776-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.989-2.555c-.494.111-.776.545-.63.969s.664.676 1.157.564l-.263-.767zm5.044.51c.494-.11.776-.545.63-.968-.146-.424-.664-.676-1.158-.565l.264.767zm3.989-2.555c-.494.112-.776.546-.63.97.145.423.664.675 1.157.564l-.264-.767zm5.044.511c.493-.111.775-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.988-2.555c-.493.112-.775.545-.63.969s.664.676 1.158.564l-.264-.767zm5.045.51c.493-.11.775-.545.63-.968-.146-.424-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.112-.775.546-.63.97s.664.675 1.158.564l-.264-.767zm5.044.511c.494-.111.776-.545.63-.968-.145-.424-.664-.677-1.157-.565l.264.767zm3.99-2.555c-.494.112-.777.545-.63.969.145.423.663.676 1.157.564l-.264-.766zm5.043.511c.494-.112.776-.546.63-.969s-.664-.676-1.157-.564l.263.766zm3.989-2.556c-.494.112-.776.546-.63.97s.664.676 1.158.564l-.264-.767zM9.353 26.7l.263.767 2.259-.511-.264-.767-.264-.767-2.258.511zm6.774-1.533.264.766 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.045.264.767 4.516-1.022-.264-.767-.263-.767-4.517 1.023zm9.033-2.044.264.766 4.516-1.022-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.263.767 4.517-1.022-.264-.767-.264-.767-4.516 1.023zm9.032-2.044.264.767 4.517-1.023-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.264.767 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.044.264.767 4.516-1.023-.263-.766-.264-.767-4.517 1.022zm9.033-2.044.264.766 4.516-1.022-.264-.767-.263-.766-4.517 1.022zM88.39 8.81l.264.767 2.258-.511-.264-.767-.264-.767-2.258.511z M9.089 9.067c-.494-.112-.776-.546-.63-.97s.664-.675 1.157-.564l-.263.767zm81.823 16.866c.493.112.775.546.63.97s-.664.675-1.158.564l.264-.767zM11.875 8.044c.493.112.775.546.63.97s-.664.676-1.158.564l.264-.767zm3.988 2.556c-.493-.112-.775-.546-.63-.969s.664-.676 1.158-.564l-.264.766zm5.045-.511c.493.112.775.545.63.969s-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.111-.775-.545-.63-.968.146-.424.664-.677 1.158-.565l-.264.767zm5.044-.51c.494.111.776.545.63.968-.145.424-.664.676-1.157.565l.263-.767zm3.99 2.555c-.495-.112-.777-.546-.63-.97.145-.423.663-.675 1.157-.563l-.264.766zm5.043-.511c.494.112.776.545.63.969s-.664.676-1.158.564l.264-.767zm3.989 2.555c-.494-.111-.776-.545-.63-.969s.664-.676 1.157-.564l-.263.767zm5.044-.51c.494.11.776.545.63.968-.146.424-.664.676-1.158.565l.264-.767zm3.989 2.555c-.494-.112-.776-.546-.63-.97.145-.423.664-.675 1.157-.564l-.264.767zm5.044-.511c.493.111.775.545.63.969s-.664.676-1.158.564l.264-.767zm3.988 2.555c-.493-.112-.775-.545-.63-.969s.664-.676 1.158-.564l-.264.767zm5.045-.51c.493.11.775.545.63.968-.146.424-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.112-.775-.546-.63-.97s.664-.675 1.158-.564l-.264.767zm5.044-.511c.494.111.776.545.63.968-.145.424-.664.677-1.157.565l.264-.767zm3.99 2.555c-.494-.112-.777-.545-.63-.969.145-.423.663-.676 1.157-.564l-.264.766zm5.043-.511c.494.112.776.546.63.969s-.664.676-1.157.564l.263-.766zm3.989 2.556c-.494-.112-.776-.546-.63-.97s.664-.676 1.158-.564l-.264.767zM9.353 8.3l.263-.767 2.259.511-.264.767-.264.767-2.258-.511zm6.774 1.533.264-.766 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.045.264-.767 4.516 1.022-.264.767-.263.767-4.517-1.023zm9.033 2.044.264-.766 4.516 1.022-.264.766-.264.767-4.516-1.022zm9.033 2.045.263-.767 4.517 1.022-.264.767-.264.767-4.516-1.023zm9.032 2.044.264-.767 4.517 1.023-.264.766-.264.767-4.516-1.022zm9.033 2.045.264-.767 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.044.264-.767 4.516 1.023-.263.766-.264.767-4.517-1.022zm9.033 2.044.264-.766 4.516 1.022-.264.767-.263.766-4.517-1.022zm9.033 2.045.264-.767 2.258.511-.264.767-.264.767-2.258-.511z",viewW:100,viewH:35},shelf_wall:{d:"M18.36 3.15v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.309-.82-2.309-1.833V3.15m73.905 0v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.31-.82-2.31-1.833V3.15m-75.29 0H93.65c1.276 0 2.31.82 2.31 1.833V19.65c0 1.012-1.034 1.833-2.31 1.833H5.888c-1.275 0-2.31-.82-2.31-1.833V4.983c0-1.012 1.035-1.833 2.31-1.833",viewW:100,viewH:25},cooktop_two:{d:"M15 30.982v-1.71m3.086 5.128h1.542M15 39.527v-1.709M10.372 34.4h1.542M5.84 46.364h18.322c1.331 0 2.41-1.196 2.41-2.67V6.306c0-1.475-1.079-2.67-2.41-2.67H5.839c-1.331 0-2.41 1.195-2.41 2.67v37.386c0 1.475 1.079 2.67 2.41 2.67m14.56-29.91c0 3.304-2.417 5.982-5.4 5.982-2.981 0-5.4-2.678-5.4-5.981s2.419-5.982 5.4-5.982c2.983 0 5.4 2.678 5.4 5.982M18.858 34.4c0 2.36-1.727 4.273-3.857 4.273s-3.857-1.913-3.857-4.273S12.87 30.127 15 30.127s3.857 1.913 3.857 4.273",viewW:30,viewH:50},stove:{d:"M41.4 35.261a.877.877 0 1 0-1.754 0zm4.384 6.138a.877.877 0 1 0 0-1.753zM41.4 44.03a.877.877 0 1 0-1.753 0zm-4.384-2.63a.877.877 0 1 0 0-1.754zM5.885 3.691v.877h48.23V2.815H5.885zm50.422 2.192h-.877v48.23h1.754V5.885zm-2.192 50.423v-.877H5.885v1.754h48.23zM3.692 54.115h.877V5.885H2.815v48.23zm2.192 2.192v-.877a1.315 1.315 0 0 1-1.315-1.315H2.815a3.07 3.07 0 0 0 3.07 3.069zm50.423-2.192h-.877c0 .726-.589 1.315-1.315 1.315v1.754a3.07 3.07 0 0 0 3.069-3.07zM54.115 3.692v.877c.726 0 1.315.589 1.315 1.315h1.754a3.07 3.07 0 0 0-3.07-3.069zm-48.23 0v-.877a3.07 3.07 0 0 0-3.07 3.07h1.754c0-.727.589-1.316 1.315-1.316zm19.73 36.83h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.015zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.261h-1.754a7.015 7.015 0 0 0 7.015 7.015zm-6.138-6.138h.877a5.26 5.26 0 0 1 5.261-5.262v-1.754a7.015 7.015 0 0 0-7.015 7.016zm6.138-6.139v.877a5.26 5.26 0 0 1 5.262 5.262h1.754a7.015 7.015 0 0 0-7.016-7.016zm27.185-14.908h-.877a5.26 5.26 0 0 1-5.261 5.262v1.754a7.015 7.015 0 0 0 7.015-7.016zm-6.138 6.139v-.877a5.26 5.26 0 0 1-5.262-5.262h-1.754a7.015 7.015 0 0 0 7.016 7.016zm-6.139-6.139h.877a5.26 5.26 0 0 1 5.262-5.261v-1.754a7.015 7.015 0 0 0-7.016 7.015zm6.139-6.138v.877a5.26 5.26 0 0 1 5.261 5.261h1.754a7.015 7.015 0 0 0-7.015-7.015zm4.384 27.185h-.877a3.51 3.51 0 0 1-3.507 3.507v1.754a5.26 5.26 0 0 0 5.261-5.261zm-4.384 4.384v-.877a3.51 3.51 0 0 1-3.508-3.507H35.26a5.26 5.26 0 0 0 5.262 5.261zm-4.385-4.384h.877a3.51 3.51 0 0 1 3.508-3.508V35.26a5.26 5.26 0 0 0-5.262 5.262zm4.385-4.385v.877a3.51 3.51 0 0 1 3.507 3.508h1.754a5.26 5.26 0 0 0-5.261-5.262zm0 .877h.876V35.26h-1.753v1.754zm3.508 3.508v.876h1.753v-1.753h-1.753zm-3.508 5.261h.876V44.03h-1.753v1.754zm-5.261-5.261v.876h1.753v-1.753h-1.753zm-9.647-21.047h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.016zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.262h-1.754a7.015 7.015 0 0 0 7.015 7.016zm-6.138-6.139h.877a5.26 5.26 0 0 1 5.261-5.261v-1.754a7.015 7.015 0 0 0-7.015 7.015zm6.138-6.138v.877a5.26 5.26 0 0 1 5.262 5.261h1.754a7.015 7.015 0 0 0-7.016-7.015z",viewW:60,viewH:60},tv:{d:"M45.134 10.766H6.18c-1.292 0-2.34.848-2.34 1.894v2.68c0 1.045 1.048 1.893 2.34 1.893h38.954m0-6.467V5.288c0-1.046 1.048-1.894 2.34-1.894h26.704c1.292 0 2.34.848 2.34 1.894v5.478m-31.384 0h31.384m0 0h37.302c1.293 0 2.34.848 2.34 1.894v2.68c0 1.045-1.047 1.893-2.34 1.893H76.518m-31.384 0v5.479c0 1.046 1.048 1.894 2.34 1.894h26.704c1.292 0 2.34-.848 2.34-1.894v-5.479m-31.384 0h31.384",viewW:120,viewH:28},tv_wall:{d:"M35.664 11.4c-.517 0-.936.269-.936.6s.419.6.936.6zm49.553 1.2c.517 0 .936-.269.936-.6s-.42-.6-.936-.6zM6.18 3v.6h107.64V2.4H6.18zm109.98 1.5h-.936v1.8h1.872V4.5zm-2.34 3.3v-.6H6.18v1.2h107.64zM3.84 6.3h.936V4.5H2.904v1.8zm2.34 1.5v-.6c-.775 0-1.404-.403-1.404-.9H2.904c0 1.16 1.467 2.1 3.276 2.1zm109.98-1.5h-.936c0 .497-.629.9-1.404.9v1.2c1.81 0 3.276-.94 3.276-2.1zM113.82 3v.6c.775 0 1.404.403 1.404.9h1.872c0-1.16-1.467-2.1-3.276-2.1zM6.18 3v-.6c-1.81 0-3.276.94-3.276 2.1h1.872c0-.497.629-.9 1.404-.9zm61.308 4.2h-.936V12h1.872V7.2zM52.512 12h.936V7.2h-1.872V12zm-16.848 0v.6h49.553v-1.2H35.664z",viewW:120,viewH:15},toilet:{d:"M3.555 48.976c0 9.55 7.125 17.29 15.914 17.29h1.061c8.79 0 15.914-7.74 15.914-17.29V5.966c0-1.233-.92-2.233-2.056-2.233H5.611c-1.135 0-2.056 1-2.056 2.234z M7.666 49.12c0 7.003 5.225 12.68 11.67 12.68h1.327c6.445 0 11.67-5.677 11.67-12.68V31.873c0-1.233-.92-2.233-2.056-2.233H9.722c-1.135 0-2.056 1-2.056 2.233zM33.792 3.733c1.465 0 2.652 1.29 2.652 2.882v12.103c0 1.592-1.187 2.882-2.652 2.882H6.208c-1.465 0-2.653-1.29-2.653-2.882V6.615c0-1.591 1.188-2.882 2.653-2.882z M24.11 50.186c0 2.467-1.84 4.467-4.11 4.467s-4.111-2-4.111-4.467 1.84-4.466 4.11-4.466 4.112 2 4.112 4.466",viewW:40,viewH:70},toilet_built_in:{d:"M3.555 34.56c0 9.263 7.125 16.774 15.914 16.774h1.061c8.79 0 15.914-7.51 15.914-16.775V5.833c0-1.196-.92-2.166-2.056-2.166H5.611c-1.135 0-2.056.97-2.056 2.166z M7.666 34.7c0 6.793 5.225 12.3 11.67 12.3h1.327c6.445 0 11.67-5.507 11.67-12.3V14.5c0-1.197-.92-2.167-2.056-2.167H9.722c-1.135 0-2.056.97-2.056 2.167z M24.11 35.733c0 2.394-1.84 4.334-4.11 4.334s-4.111-1.94-4.111-4.334 1.84-4.333 4.11-4.333 4.112 1.94 4.112 4.333",viewW:40,viewH:55},bathtub:{d:"M3.885 6c0-1.243 1.068-2.25 2.386-2.25h157.458c1.318 0 2.386 1.007 2.386 2.25v63c0 1.243-1.068 2.25-2.386 2.25H6.27c-1.318 0-2.386-1.007-2.386-2.25z M13.428 37.5c0-13.669 11.75-24.75 26.243-24.75h90.658c14.493 0 26.243 11.081 26.243 24.75s-11.75 24.75-26.243 24.75H39.67c-14.493 0-26.243-11.081-26.243-24.75 M31.56 37.5c0 2.237-1.923 4.05-4.295 4.05s-4.294-1.813-4.294-4.05 1.923-4.05 4.294-4.05c2.372 0 4.295 1.813 4.295 4.05",viewW:170,viewH:75},bathtub_corner:{d:"M3.862 6.224a2.36 2.36 0 0 1 2.362-2.362H133.97c1.197 0 2.168.97 2.168 2.168 0 71.857-58.251 130.108-130.108 130.108a2.17 2.17 0 0 1-2.168-2.168z M13.31 32.207c0-10.437 8.46-18.897 18.897-18.897h87.628a2.13 2.13 0 0 1 2.13 2.13c0 58.833-47.692 106.526-106.524 106.526a2.13 2.13 0 0 1-2.13-2.131z M32.207 27.483a4.724 4.724 0 1 1-9.449 0 4.724 4.724 0 0 1 9.449 0",viewW:140,viewH:140},bidet:{d:"M22.466 3.692v10.085c0 1.21-.92 2.192-2.055 2.192h-.822c-1.136 0-2.056-.981-2.056-2.192V3.692m4.933 8.77h2.878c1.135 0 2.056-.982 2.056-2.193v-.877c0-1.21-.92-2.192-2.056-2.192h-2.878m-4.933 5.262h-2.878c-1.135 0-2.055-.982-2.055-2.193v-.877c0-1.21.92-2.192 2.055-2.192h2.878M5.611 3.692h28.777c1.136 0 2.056.981 2.056 2.192v33.45c0 9.374-7.125 16.973-15.914 16.973h-1.06c-8.79 0-15.915-7.599-15.915-16.972V5.885c0-1.212.92-2.193 2.056-2.193m4.11 15.785h20.556c1.136 0 2.056.981 2.056 2.192v17.807c0 6.874-5.225 12.447-11.67 12.447h-1.327c-6.445 0-11.67-5.573-11.67-12.447V21.67c0-1.21.92-2.192 2.056-2.192m13.567 7.892c0 1.937-1.472 3.508-3.288 3.508-1.817 0-3.29-1.57-3.29-3.508s1.473-3.507 3.29-3.507 3.288 1.57 3.288 3.507",viewW:40,viewH:60},bidet_built_in:{d:"M17.318 12.182h-8.06c-.88 0-1.592.74-1.592 1.654v16.126c0 6.698 5.225 12.129 11.67 12.129h1.327c6.445 0 11.67-5.43 11.67-12.13V13.837c0-.914-.713-1.654-1.591-1.654H22.68m-.215-8.545v9.827c0 1.18-.92 2.136-2.055 2.136h-.822c-1.136 0-2.056-.956-2.056-2.136V3.637m10.689 8.545V3.637m-16.445 0v8.545M5.611 3.637h28.777c1.136 0 2.056.956 2.056 2.136v24.051c0 9.135-7.125 16.54-15.914 16.54h-1.06c-8.79 0-15.915-7.405-15.915-16.54V5.773c0-1.18.92-2.136 2.056-2.136M23.289 23.29c0 1.888-1.473 3.418-3.29 3.418s-3.288-1.53-3.288-3.418 1.472-3.418 3.289-3.418c1.816 0 3.288 1.53 3.288 3.418",viewW:40,viewH:50},kitchen_sink:{d:"M38.188 8.7h10.598c1.211 0 2.193.956 2.193 2.136v28.2c0 1.18-.982 2.136-2.193 2.136H11.08c-1.21 0-2.192-.956-2.192-2.136v-28.2c0-1.18.981-2.136 2.192-2.136h10.599m10.885-5.128V15.11c0 1.18-.981 2.136-2.192 2.136h-.877c-1.21 0-2.192-.957-2.192-2.136V3.572m5.261 7.691h3.07c1.21 0 2.192-.956 2.192-2.136v-.855c0-1.18-.982-2.136-2.192-2.136h-3.07m-5.261 5.127h-3.07c-1.21 0-2.192-.956-2.192-2.136v-.855c0-1.18.982-2.136 2.193-2.136h3.069M5.817 46.299h48.231c1.21 0 2.192-.956 2.192-2.136V5.709c0-1.18-.981-2.137-2.192-2.137H5.818c-1.211 0-2.193.957-2.193 2.137v38.454c0 1.18.982 2.136 2.192 2.136M33.44 25.79c0 1.888-1.57 3.418-3.507 3.418s-3.508-1.53-3.508-3.418c0-1.887 1.57-3.418 3.508-3.418s3.507 1.53 3.507 3.418",viewW:60,viewH:50},kitchen_sink_double:{d:"M53.173 12.182c-.468 0-.847.354-.847.79s.38.79.847.79zm21.979 1.58c.467 0 .846-.353.846-.79 0-.436-.379-.79-.846-.79zM6.01 3.572v.79h77.842v-1.58H6.01zM86.14 5.71h-.847v38.454h1.694V5.709zM83.85 46.3v-.79H6.01v1.58h77.842zM3.72 44.163h.847V5.709H2.873v38.454zm2.29 2.136v-.79c-.797 0-1.443-.603-1.443-1.346H2.873c0 1.616 1.404 2.926 3.137 2.926zm80.131-2.136h-.847c0 .743-.646 1.346-1.442 1.346v1.58c1.732 0 3.136-1.31 3.136-2.926zm-2.29-40.59v.79c.797 0 1.443.602 1.443 1.346h1.694c0-1.617-1.404-2.927-3.136-2.927zm-77.841 0v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.744.646-1.347 1.443-1.347zm5.494 37.599v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2h-1.694v28.2zm-32.97-28.2h-.846v28.2h1.694v-28.2zM39.895 8.7v-.79h-5.669v1.58h5.669zm-22.721 0v-.79h-5.669v1.58h5.669zm-7.958 2.136h.847c0-.744.645-1.346 1.442-1.346V7.91c-1.732 0-3.136 1.31-3.136 2.926zm32.968 0h.847c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.442.603 1.442 1.347zm-2.29 30.336v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.645 1.346-1.442 1.346zm-28.389 0v-.79c-.797 0-1.442-.603-1.442-1.346H8.368c0 1.616 1.404 2.926 3.136 2.926zm13.737-23.927v.79h.916v-1.58h-.916zm3.205-2.136h.847V3.572H27.6V15.11zM22.952 3.572h-.847V15.11h1.693V3.572zm3.205 13.673v.79c1.732 0 3.136-1.31 3.136-2.926H27.6c0 .743-.646 1.346-1.443 1.346zm-.916 0v-.79c-.797 0-1.443-.603-1.443-1.346h-1.693c0 1.616 1.404 2.926 3.136 2.926zm3.205-5.982v.79h3.206v-1.58h-3.206zm5.495-2.136h.847v-.855h-1.694v.855zm-2.29-2.991v-.79h-3.205v1.58h3.206zm2.29 2.136h.847c0-1.616-1.404-2.926-3.136-2.926v1.58c.796 0 1.442.603 1.442 1.346zm-2.29 2.991v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.646 1.346-1.442 1.346zm-11.905 0v.79h3.206v-1.58h-3.206zm3.206-5.127v-.79h-3.206v1.58h3.206zm-5.495 2.136h-.847v.855h1.694v-.855zm2.29-2.136v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.743.646-1.346 1.442-1.346zm0 5.127v-.79c-.797 0-1.443-.603-1.443-1.346H16.61c0 1.616 1.404 2.926 3.136 2.926zm9.615 14.527h-.847c0 1.452-1.26 2.628-2.816 2.628v1.58c2.49 0 4.51-1.884 4.51-4.208zM25.7 29.208v-.79c-1.555 0-2.816-1.176-2.816-2.628H21.19c0 2.324 2.02 4.209 4.51 4.209zm-3.663-3.418h.847c0-1.451 1.26-2.628 2.816-2.628v-1.58c-2.49 0-4.51 1.884-4.51 4.208zm3.663-3.418v.79c1.555 0 2.816 1.177 2.816 2.628h1.694c0-2.324-2.02-4.208-4.51-4.208zm24.268 18.8v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2H79.8v28.2zM78.356 8.7v-.79h-28.39v1.58h28.39zm-30.68 2.136h-.846v28.2h1.694v-28.2zm2.29-2.136v-.79c-1.732 0-3.136 1.31-3.136 2.926h1.694c0-.744.646-1.346 1.442-1.346zm30.68 2.136h.846c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.443.603 1.443 1.347zm-2.29 30.336v.79c1.732 0 3.136-1.31 3.136-2.926H79.8c0 .743-.646 1.346-1.443 1.346zm-28.39 0v-.79c-.796 0-1.442-.603-1.442-1.346H46.83c0 1.616 1.404 2.926 3.136 2.926zm3.206-28.2v.79h21.979v-1.58h-21.98z",viewW:90,viewH:50}};export{c as FURNITURE_ART_FINGERPRINT,v as GENERATED_FURNITURE_ART}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-BCGpvbDT.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-Di_izZTU.js similarity index 72% rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-card-BCGpvbDT.js rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-card-Di_izZTU.js index 2eeab64c..4d872ef2 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-BCGpvbDT.js +++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-Di_izZTU.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),n=new WeakMap;let r=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=n.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&n.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const n=1===e.length?e[0]:t.reduce((t,i,n)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[n+1],e[0]);return new r(n,e,i)},s=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new r("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:a,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,m=_?_.emptyScript:"",g=p.reactiveElementPolyfillSupport,f=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},y=(e,t)=>!a(e,t),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=b){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(e,i,t);void 0!==n&&l(this.prototype,e,n)}}static getPropertyDescriptor(e,t,i){const{get:n,set:r}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:n,set(t){const o=n?.call(this);r?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const e=u(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(s(e))}else void 0!==e&&t.push(s(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,n)=>{if(t)i.adoptedStyleSheets=n.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of n){const n=document.createElement("style"),r=e.litNonce;void 0!==r&&n.setAttribute("nonce",r),n.textContent=t.cssText,i.appendChild(n)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,i);if(void 0!==n&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==r?this.removeAttribute(n):this.setAttribute(n,r),this._$Em=null}}_$AK(e,t){const i=this.constructor,n=i._$Eh.get(e);if(void 0!==n&&this._$Em!==n){const e=i.getPropertyOptions(n),r="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=n;const o=r.fromAttribute(t,e.type);this[n]=o??this._$Ej?.get(n)??o,this._$Em=null}}requestUpdate(e,t,i,n=!1,r){if(void 0!==e){const o=this.constructor;if(!1===n&&(r=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??y)(r,t)||i.useDefault&&i.reflect&&r===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:n,wrapped:r},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==r||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===n&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,n=this[t];!0!==e||this._$AL.has(t)||void 0===n||this.C(t,void 0,i,n)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,g?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,S=k.trustedTypes,$=S?S.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",R=`lit$${Math.random().toFixed(9).slice(2)}$`,C="?"+R,T=`<${C}>`,D=document,A=()=>D.createComment(""),P=e=>null===e||"object"!=typeof e&&"function"!=typeof e,F=Array.isArray,z="[ \t\n\f\r]",I=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,O=/-->/g,E=/>/g,N=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!F(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==$?$.createHTML(t):t}const X=(e,t)=>{const i=e.length-1,n=[];let r,o=2===t?"":3===t?"":"",s=I;for(let t=0;t"===l[0]?(s=r??I,c=-1):void 0===l[1]?c=-2:(c=s.lastIndex-l[2].length,a=l[1],s=void 0===l[3]?N:'"'===l[3]?L:H):s===L||s===H?s=N:s===O||s===E?s=I:(s=N,r=void 0);const d=s===N&&e[t+1].startsWith("/>")?" ":"";o+=s===I?i+T:c>=0?(n.push(a),i.slice(0,c)+M+i.slice(c)+R+d):i+R+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),n]};class Z{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let r=0,o=0;const s=e.length-1,a=this.parts,[l,c]=X(e,t);if(this.el=Z.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=K.nextNode())&&a.length0){n.textContent=S?S.emptyScript:"";for(let i=0;iF(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==G&&P(this._$AH)?this._$AA.nextSibling.data=e:this.T(D.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,n="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=Z.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(t);else{const e=new Q(n,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=V.get(e.strings);return void 0===t&&V.set(e.strings,t=new Z(e)),t}k(e){F(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,n=0;for(const r of e)n===t.length?t.push(i=new ee(this.O(A()),this.O(A()),this,this.options)):i=t[n],i._$AI(r),n++;n2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!P(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const n=e;let s,a;for(e=r[0],s=0;s{const n=i?.renderBefore??t;let r=n._$litPart$;if(void 0===r){const e=i?.renderBefore??null;n._$litPart$=r=new ee(t.insertBefore(A(),e),e,void 0,i??{})}return r._$AI(e),r},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const ue=2,pe=e=>(...t)=>({_$litDirective$:e,values:t});let _e=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,i){this._$Ct=e,this._$AM=t,this._$Ci=i}_$AS(e,t){return this.update(e,t)}update(e,t){return this.render(...t)}};const{I:me}=se,ge=e=>e,fe=(e,t)=>void 0!==e?._$litType$,ve=()=>document.createComment(""),ye=(e,t,i)=>{const n=e._$AA.parentNode,r=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=n.insertBefore(ve(),r),o=n.insertBefore(ve(),r);i=new me(t,o,e,e.options)}else{const t=i._$AB.nextSibling,o=i._$AM,s=o!==e;if(s){let t;i._$AQ?.(e),i._$AM=e,void 0!==i._$AP&&(t=e._$AU)!==o._$AU&&i._$AP(t)}if(t!==r||s){let e=i._$AA;for(;e!==t;){const t=ge(e).nextSibling;ge(n).insertBefore(e,r),e=t}}}return i},be=(e,t,i=e)=>(e._$AI(t,i),e),we={},ke=(e,t=we)=>e._$AH=t,xe=e=>e._$AH,Se=e=>{e._$AR(),e._$AA.remove()},$e=e=>(e=>null!=e?._$litType$?.h)(e)?e._$litType$.h:e.strings,Me=pe(class extends _e{constructor(e){super(e),this.et=new WeakMap}render(e){return[e]}update(e,[t]){const i=fe(this.it)?$e(this.it):null,n=fe(t)?$e(t):null;if(null!==i&&(null===n||i!==n)){const t=xe(e).pop();let n=this.et.get(i);if(void 0===n){const e=document.createDocumentFragment();n=le(G,e),n.setConnected(!1),this.et.set(i,n)}ke(n,[t]),ye(n,void 0,t)}if(null!==n){if(null===i||i!==n){const t=this.et.get(n);if(void 0!==t){const i=xe(t).pop();(e=>{e._$AR()})(e),ye(e,void 0,i),ke(e,[i])}}this.it=t}else this.it=void 0;return this.render(t)}}),Re=pe(class extends _e{constructor(){super(...arguments),this.key=G}render(e,t){return this.key=e,t}update(e,[t,i]){return t!==this.key&&(ke(e),this.key=t),i}}),Ce=(e,t,i)=>{const n=new Map;for(let r=t;r<=i;r++)n.set(e[r],r);return n},Te=pe(class extends _e{constructor(e){if(super(e),e.type!==ue)throw Error("repeat() can only be used in text expressions")}dt(e,t,i){let n;void 0===i?i=t:void 0!==t&&(n=t);const r=[],o=[];let s=0;for(const t of e)r[s]=n?n(t,s):s,o[s]=i(t,s),s++;return{values:o,keys:r}}render(e,t,i){return this.dt(e,t,i).values}update(e,[t,i,n]){const r=xe(e),{values:o,keys:s}=this.dt(t,i,n);if(!Array.isArray(r))return this.ut=s,o;const a=this.ut??=[],l=[];let c,h,d=0,u=r.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===r[d])d++;else if(null===r[u])u--;else if(a[d]===s[p])l[p]=be(r[d],o[p]),d++,p++;else if(a[u]===s[_])l[_]=be(r[u],o[_]),u--,_--;else if(a[d]===s[_])l[_]=be(r[d],o[_]),ye(e,l[_+1],r[d]),d++,_--;else if(a[u]===s[p])l[p]=be(r[u],o[p]),ye(e,r[d],r[u]),u--,p++;else if(void 0===c&&(c=Ce(s,p,_),h=Ce(a,d,u)),c.has(a[d]))if(c.has(a[u])){const t=h.get(s[p]),i=void 0!==t?r[t]:null;if(null===i){const t=ye(e,r[d]);be(t,o[p]),l[p]=t}else l[p]=be(i,o[p]),ye(e,r[d],i),r[t]=null;p++}else Se(r[u]),u--;else Se(r[d]),d++;for(;p<=_;){const t=ye(e,l[_+1]);be(t,o[p]),l[p++]=t}for(;d<=u;){const e=r[d++];null!==e&&Se(e)}return this.ut=s,ke(e,l),U}}),De=new WeakMap;let Ae=0;class Pe extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",this.dismissOnScrim=!1,this.flexContent=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=null,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Ae,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._usesHaDialog()?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._usesHaDialog())return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const n=this._deepActiveElement(),r=i[0],o=i[i.length-1];!e.shiftKey||n!==r&&i.includes(n)?e.shiftKey||n!==o||(e.preventDefault(),r.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}_usesHaDialog(){return!0===this._useHaDialog&&!this.alert}connectedCallback(){this.setAttribute("data-hp","dialog"),super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=De.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),De.set(e,t),null===this._useHaDialog&&(this._useHaDialog=!!customElements.get("ha-dialog")),this.addEventListener("keydown",this._onKeyDown,!0),queueMicrotask(()=>{this._ensureNativeModal()&&this._focusInitial()})}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const n=t?De.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=De.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void De.delete(t);const n=i?.closest("hp-dialog");i?.isConnected&&n&&e.dialogs.has(n)&&i.focus({preventScroll:!0})})}firstUpdated(e){super.firstUpdated(e),this._ensureNativeModal(),queueMicrotask(()=>this._focusInitial())}updated(e){super.updated(e),this._ensureNativeModal()}_ensureNativeModal(){if(this._usesHaDialog()||!this.isConnected)return!1;const e=this.renderRoot.querySelector("dialog");if(!e?.isConnected)return!1;try{return!e.matches(":modal")&&(e.open&&e.close(),e.showModal(),!0)}catch{return!1}}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),t=[],i=new Set,n=r=>{if(!i.has(r)){if(i.add(r),r instanceof HTMLElement){if(r.matches(e)&&t.push(r),r instanceof HTMLSlotElement){for(const e of r.assignedNodes({flatten:!0}))n(e);return}if(r.shadowRoot){for(const e of r.shadowRoot.childNodes)n(e);return}}for(const e of r.childNodes)n(e)}};for(const e of this.childNodes)n(e);const r=this.overlayPortal();return r&&n(r),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}rejectClose(){this._closing=!1,this.requestUpdate()}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const n={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(n);let r=!1;return()=>{if(r)return;r=!0;const e=this._overlays.findIndex(e=>e.token===n.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=j` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),n=new WeakMap;let r=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=n.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&n.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const n=1===e.length?e[0]:t.reduce((t,i,n)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[n+1],e[0]);return new r(n,e,i)},s=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new r("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:a,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,m=_?_.emptyScript:"",g=p.reactiveElementPolyfillSupport,f=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},y=(e,t)=>!a(e,t),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=b){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(e,i,t);void 0!==n&&l(this.prototype,e,n)}}static getPropertyDescriptor(e,t,i){const{get:n,set:r}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:n,set(t){const o=n?.call(this);r?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const e=u(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(s(e))}else void 0!==e&&t.push(s(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,n)=>{if(t)i.adoptedStyleSheets=n.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of n){const n=document.createElement("style"),r=e.litNonce;void 0!==r&&n.setAttribute("nonce",r),n.textContent=t.cssText,i.appendChild(n)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,i);if(void 0!==n&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==r?this.removeAttribute(n):this.setAttribute(n,r),this._$Em=null}}_$AK(e,t){const i=this.constructor,n=i._$Eh.get(e);if(void 0!==n&&this._$Em!==n){const e=i.getPropertyOptions(n),r="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=n;const o=r.fromAttribute(t,e.type);this[n]=o??this._$Ej?.get(n)??o,this._$Em=null}}requestUpdate(e,t,i,n=!1,r){if(void 0!==e){const o=this.constructor;if(!1===n&&(r=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??y)(r,t)||i.useDefault&&i.reflect&&r===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:n,wrapped:r},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==r||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===n&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,n=this[t];!0!==e||this._$AL.has(t)||void 0===n||this.C(t,void 0,i,n)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,g?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,S=k.trustedTypes,$=S?S.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",R=`lit$${Math.random().toFixed(9).slice(2)}$`,C="?"+R,T=`<${C}>`,D=document,A=()=>D.createComment(""),P=e=>null===e||"object"!=typeof e&&"function"!=typeof e,F=Array.isArray,z="[ \t\n\f\r]",I=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,O=/-->/g,E=/>/g,N=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!F(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==$?$.createHTML(t):t}const X=(e,t)=>{const i=e.length-1,n=[];let r,o=2===t?"":3===t?"":"",s=I;for(let t=0;t"===l[0]?(s=r??I,c=-1):void 0===l[1]?c=-2:(c=s.lastIndex-l[2].length,a=l[1],s=void 0===l[3]?N:'"'===l[3]?L:H):s===L||s===H?s=N:s===O||s===E?s=I:(s=N,r=void 0);const d=s===N&&e[t+1].startsWith("/>")?" ":"";o+=s===I?i+T:c>=0?(n.push(a),i.slice(0,c)+M+i.slice(c)+R+d):i+R+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),n]};class Z{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let r=0,o=0;const s=e.length-1,a=this.parts,[l,c]=X(e,t);if(this.el=Z.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=K.nextNode())&&a.length0){n.textContent=S?S.emptyScript:"";for(let i=0;iF(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==G&&P(this._$AH)?this._$AA.nextSibling.data=e:this.T(D.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,n="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=Z.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(t);else{const e=new Q(n,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=V.get(e.strings);return void 0===t&&V.set(e.strings,t=new Z(e)),t}k(e){F(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,n=0;for(const r of e)n===t.length?t.push(i=new ee(this.O(A()),this.O(A()),this,this.options)):i=t[n],i._$AI(r),n++;n2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!P(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const n=e;let s,a;for(e=r[0],s=0;s{const n=i?.renderBefore??t;let r=n._$litPart$;if(void 0===r){const e=i?.renderBefore??null;n._$litPart$=r=new ee(t.insertBefore(A(),e),e,void 0,i??{})}return r._$AI(e),r},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const ue=2,pe=e=>(...t)=>({_$litDirective$:e,values:t});let _e=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,i){this._$Ct=e,this._$AM=t,this._$Ci=i}_$AS(e,t){return this.update(e,t)}update(e,t){return this.render(...t)}};const{I:me}=se,ge=e=>e,fe=(e,t)=>void 0!==e?._$litType$,ve=()=>document.createComment(""),ye=(e,t,i)=>{const n=e._$AA.parentNode,r=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=n.insertBefore(ve(),r),o=n.insertBefore(ve(),r);i=new me(t,o,e,e.options)}else{const t=i._$AB.nextSibling,o=i._$AM,s=o!==e;if(s){let t;i._$AQ?.(e),i._$AM=e,void 0!==i._$AP&&(t=e._$AU)!==o._$AU&&i._$AP(t)}if(t!==r||s){let e=i._$AA;for(;e!==t;){const t=ge(e).nextSibling;ge(n).insertBefore(e,r),e=t}}}return i},be=(e,t,i=e)=>(e._$AI(t,i),e),we={},ke=(e,t=we)=>e._$AH=t,xe=e=>e._$AH,Se=e=>{e._$AR(),e._$AA.remove()},$e=e=>(e=>null!=e?._$litType$?.h)(e)?e._$litType$.h:e.strings,Me=pe(class extends _e{constructor(e){super(e),this.et=new WeakMap}render(e){return[e]}update(e,[t]){const i=fe(this.it)?$e(this.it):null,n=fe(t)?$e(t):null;if(null!==i&&(null===n||i!==n)){const t=xe(e).pop();let n=this.et.get(i);if(void 0===n){const e=document.createDocumentFragment();n=le(G,e),n.setConnected(!1),this.et.set(i,n)}ke(n,[t]),ye(n,void 0,t)}if(null!==n){if(null===i||i!==n){const t=this.et.get(n);if(void 0!==t){const i=xe(t).pop();(e=>{e._$AR()})(e),ye(e,void 0,i),ke(e,[i])}}this.it=t}else this.it=void 0;return this.render(t)}}),Re=pe(class extends _e{constructor(){super(...arguments),this.key=G}render(e,t){return this.key=e,t}update(e,[t,i]){return t!==this.key&&(ke(e),this.key=t),i}}),Ce=(e,t,i)=>{const n=new Map;for(let r=t;r<=i;r++)n.set(e[r],r);return n},Te=pe(class extends _e{constructor(e){if(super(e),e.type!==ue)throw Error("repeat() can only be used in text expressions")}dt(e,t,i){let n;void 0===i?i=t:void 0!==t&&(n=t);const r=[],o=[];let s=0;for(const t of e)r[s]=n?n(t,s):s,o[s]=i(t,s),s++;return{values:o,keys:r}}render(e,t,i){return this.dt(e,t,i).values}update(e,[t,i,n]){const r=xe(e),{values:o,keys:s}=this.dt(t,i,n);if(!Array.isArray(r))return this.ut=s,o;const a=this.ut??=[],l=[];let c,h,d=0,u=r.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===r[d])d++;else if(null===r[u])u--;else if(a[d]===s[p])l[p]=be(r[d],o[p]),d++,p++;else if(a[u]===s[_])l[_]=be(r[u],o[_]),u--,_--;else if(a[d]===s[_])l[_]=be(r[d],o[_]),ye(e,l[_+1],r[d]),d++,_--;else if(a[u]===s[p])l[p]=be(r[u],o[p]),ye(e,r[d],r[u]),u--,p++;else if(void 0===c&&(c=Ce(s,p,_),h=Ce(a,d,u)),c.has(a[d]))if(c.has(a[u])){const t=h.get(s[p]),i=void 0!==t?r[t]:null;if(null===i){const t=ye(e,r[d]);be(t,o[p]),l[p]=t}else l[p]=be(i,o[p]),ye(e,r[d],i),r[t]=null;p++}else Se(r[u]),u--;else Se(r[d]),d++;for(;p<=_;){const t=ye(e,l[_+1]);be(t,o[p]),l[p++]=t}for(;d<=u;){const e=r[d++];null!==e&&Se(e)}return this.ut=s,ke(e,l),U}}),De=new WeakMap;let Ae=0;class Pe extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",this.dismissOnScrim=!1,this.flexContent=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=null,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Ae,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._usesHaDialog()?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._usesHaDialog())return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const n=this._deepActiveElement(),r=i[0],o=i[i.length-1];!e.shiftKey||n!==r&&i.includes(n)?e.shiftKey||n!==o||(e.preventDefault(),r.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}_usesHaDialog(){return!0===this._useHaDialog&&!this.alert}connectedCallback(){this.setAttribute("data-hp","dialog"),super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=De.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),De.set(e,t),null===this._useHaDialog&&(this._useHaDialog=!!customElements.get("ha-dialog")),this.addEventListener("keydown",this._onKeyDown,!0),queueMicrotask(()=>{this._ensureNativeModal()&&this._focusInitial()})}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const n=t?De.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=De.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void De.delete(t);const n=i?.closest("hp-dialog");i?.isConnected&&n&&e.dialogs.has(n)&&i.focus({preventScroll:!0})})}firstUpdated(e){super.firstUpdated(e),this._ensureNativeModal(),queueMicrotask(()=>this._focusInitial())}updated(e){super.updated(e),this._ensureNativeModal()}_ensureNativeModal(){if(this._usesHaDialog()||!this.isConnected)return!1;const e=this.renderRoot.querySelector("dialog");if(!e?.isConnected)return!1;try{return!e.matches(":modal")&&(e.open&&e.close(),e.showModal(),!0)}catch{return!1}}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),t=[],i=new Set,n=r=>{if(!i.has(r)){if(i.add(r),r instanceof HTMLElement){if(r.matches(e)&&t.push(r),r instanceof HTMLSlotElement){for(const e of r.assignedNodes({flatten:!0}))n(e);return}if(r.shadowRoot){for(const e of r.shadowRoot.childNodes)n(e);return}}for(const e of r.childNodes)n(e)}};for(const e of this.childNodes)n(e);const r=this.overlayPortal();return r&&n(r),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}rejectClose(){this._closing=!1,this.requestUpdate()}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const n={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(n);let r=!1;return()=>{if(r)return;r=!0;const e=this._overlays.findIndex(e=>e.token===n.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=j` ${this.icon?j``:G} ${this.title} `;return this._usesHaDialog()?this.describedBy?j`{this._active={...t,resolve:e},this._changed(t)})}resolve(e,t){const i=this._active;return!(!i||i.token!==e)&&(this._active=null,this._changed(null),i.resolve(t),!0)}cancel(){const e=this._active;return!!e&&this.resolve(e.token,!1)}}const Ie=new Set(["hacs","sun","backup","hassio","met","telegram_bot","mobile_app","systemmonitor","better_thermostat","adaptive_lighting","yandex_pogoda","upnp_serial_number"]),Oe=[{pattern:"протечк|leak|water sensor",icon:"mdi:water-alert"},{pattern:"клапан|valve",icon:"mdi:pipe-valve"},{pattern:"дым|smoke",icon:"mdi:smoke-detector"},{pattern:"термоголов|trv|radiator",icon:"mdi:radiator"},{pattern:"чайник|kettle|термопот",icon:"mdi:kettle"},{pattern:"сауна|sauna|harvia|парная|парилк",icon:"mdi:hot-tub"},{pattern:"температ|temperature|thermometer|climate sensor",icon:"mdi:thermometer"},{pattern:"qingping|air monitor|молекул|air quality",icon:"mdi:air-filter"},{pattern:"штор|curtain|blind|shade",icon:"mdi:roller-shade"},{pattern:"розетк|plug|socket|outlet",icon:"mdi:power-socket-de"},{pattern:"выключат|switch",icon:"mdi:light-switch"},{pattern:"лампа|лампочк|bulb|gx53|светильник|rgb|lamp|light strip",icon:"mdi:lightbulb"},{pattern:"камер|camera",icon:"mdi:cctv"},{pattern:"замок|ttlock|lock|sn609|sn9161",icon:"mdi:lock"},{pattern:"ворота|garage|gate",icon:"mdi:garage-variant"},{pattern:"калитк|door|открыт|contact",icon:"mdi:door"},{pattern:"счётчик|счетчик|kws|meter",icon:"mdi:meter-electric"},{pattern:"вводный автомат|breaker|wifimcbn",icon:"mdi:electric-switch"},{pattern:"myheat|котёл|котел|boiler|отоплен|heating",icon:"mdi:water-boiler"},{pattern:"холодильник|fridge",icon:"mdi:fridge"},{pattern:"стиральн|washer|washing",icon:"mdi:washing-machine"},{pattern:"сушилк|dryer",icon:"mdi:tumble-dryer"},{pattern:"пылесос|vacuum|dreame|roborock",icon:"mdi:robot-vacuum"},{pattern:"soundbar",icon:"mdi:soundbar"},{pattern:"колонк|станц|speaker|яндекс|yandex|алиса|alice",icon:"mdi:speaker"},{pattern:"tv|телевизор|hyundaitv|mitv|television",icon:"mdi:television"},{pattern:"keenetic|роутер|router|mesh|access point",icon:"mdi:router-wireless"},{pattern:"ибп|ups|kirpich",icon:"mdi:battery-charging-high"},{pattern:"slzb|координат|zigbee|coordinator",icon:"mdi:zigbee"},{pattern:"motion|движен|presence|присутств",icon:"mdi:motion-sensor"},{pattern:"humidity|влажн",icon:"mdi:water-percent"}];function Ee(e){const t=[];for(const i of e)if(i&&"string"==typeof i.pattern&&i.icon)try{t.push({re:new RegExp(i.pattern,"i"),icon:i.icon})}catch{}return t}function Ne(e){try{return new RegExp(e,"i"),!0}catch{return!1}}const He=Ee(Oe),Le={temperature:"mdi:thermometer",humidity:"mdi:water-percent",motion:"mdi:motion-sensor",occupancy:"mdi:motion-sensor",presence:"mdi:motion-sensor",door:"mdi:door",window:"mdi:window-closed",garage_door:"mdi:garage-variant",smoke:"mdi:smoke-detector",moisture:"mdi:water-alert",gas:"mdi:gas-cylinder",power:"mdi:meter-electric",energy:"mdi:meter-electric",illuminance:"mdi:brightness-5",co2:"mdi:molecule-co2",pm25:"mdi:air-filter",battery:"mdi:battery"},Be="mdi:chip";function qe(e,t,i){const n=((e||"")+" "+(t||"")).toLowerCase();for(const{re:e,icon:t}of i??He)if(e.test(n))return t;return Be}const je=["light","switch","cover","valve","lock","climate","fan","media_player","camera","vacuum","humidifier","water_heater","alarm_control_panel","sensor","binary_sensor","event","button","number","select","update"];var We=/^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i,Ue=Math.ceil,Ge=Math.floor,Ve="[BigNumber Error] ",Ke=Ve+"Number primitive has more than 15 significant digits: ",Ye=1e14,Xe=14,Ze=9007199254740991,Je=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],Qe=1e7,et=1e9;function tt(e){var t=0|e;return e>0||e===t?t:t-1}function it(e){for(var t,i,n=1,r=e.length,o=e[0]+"";nc^i?1:-1;for(a=(l=r.length)<(c=o.length)?l:c,s=0;so[s]^i?1:-1;return l==c?0:l>c^i?1:-1}function rt(e,t,i,n){if(ei||e!==Ge(e))throw Error(Ve+(n||"Argument")+("number"==typeof e?ei?" out of range: ":" not an integer: ":" not a primitive number: ")+String(e))}function ot(e){var t=e.c.length-1;return tt(e.e/Xe)==t&&e.c[t]%2!=0}function st(e,t){return(e.length>1?e.charAt(0)+"."+e.slice(1):e)+(t<0?"e":"e+")+t}function at(e,t,i){var n,r;if(t<0){for(r=i+".";++t;r+=i);e=r+e}else if(++t>(n=e.length)){for(r=i,t-=n;--t;r+=i);e+=r}else ty?u.c=u.e=null:e.e=10;l/=10,a++);return void(a>y?u.c=u.e=null:(u.e=a,u.c=[e]))}d=String(e)}else{if(!We.test(d=String(e)))return r(u,d,c);u.s=45==d.charCodeAt(0)?(d=d.slice(1),-1):1}(a=d.indexOf("."))>-1&&(d=d.replace(".","")),(l=d.search(/e/i))>0?(a<0&&(a=l),a+=+d.slice(l+1),d=d.substring(0,l)):a<0&&(a=d.length)}else{if(rt(t,2,S.length,"Base"),10==t&&$)return D(u=new M(e),_+u.e+1,m);if(d=String(e),c="number"==typeof e){if(0*e!=0)return r(u,d,c,t);if(u.s=1/e<0?(d=d.slice(1),-1):1,M.DEBUG&&d.replace(/^0\.0*|\./,"").length>15)throw Error(Ke+e)}else u.s=45===d.charCodeAt(0)?(d=d.slice(1),-1):1;for(i=S.slice(0,t),a=l=0,h=d.length;la){a=h;continue}}else if(!s&&(d==d.toUpperCase()&&(d=d.toLowerCase())||d==d.toLowerCase()&&(d=d.toUpperCase()))){s=!0,l=-1,a=0;continue}return r(u,String(e),c,t)}c=!1,(a=(d=n(d,t,10,u.s)).indexOf("."))>-1?d=d.replace(".",""):a=d.length}for(l=0;48===d.charCodeAt(l);l++);for(h=d.length;48===d.charCodeAt(--h););if(d=d.slice(l,++h)){if(h-=l,c&&M.DEBUG&&h>15&&(e>Ze||e!==Ge(e)))throw Error(Ke+u.s*e);if((a=a-l-1)>y)u.c=u.e=null;else if(a=f)?st(l,s):at(l,s,"0");else if(o=(e=D(new M(e),t,i)).e,a=(l=it(e.c)).length,1==n||2==n&&(t<=o||o<=g)){for(;as),l=at(l,o,"0"),o+1>a){if(--t>0)for(l+=".";t--;l+="0");}else if((t+=o-a)>0)for(o+1==a&&(l+=".");t--;l+="0");return e.s<0&&r?"-"+l:l}function C(e,t){for(var i,n,r=1,o=new M(e[0]);r=10;r/=10,n++);return(i=n+i*Xe-1)>y?e.c=e.e=null:i=10;a/=10,r++);if((o=t-r)<0)o+=Xe,s=t,l=d[c=0],h=Ge(l/u[r-s-1]%10);else if((c=Ue((o+1)/Xe))>=d.length){if(!n)break e;for(;d.length<=c;d.push(0));l=h=0,r=1,s=(o%=Xe)-Xe+1}else{for(l=a=d[c],r=1;a>=10;a/=10,r++);h=(s=(o%=Xe)-Xe+r)<0?0:Ge(l/u[r-s-1]%10)}if(n=n||t<0||null!=d[c+1]||(s<0?l:l%u[r-s-1]),n=i<4?(h||n)&&(0==i||i==(e.s<0?3:2)):h>5||5==h&&(4==i||n||6==i&&(o>0?s>0?l/u[r-s]:0:d[c-1])%10&1||i==(e.s<0?8:7)),t<1||!d[0])return d.length=0,n?(t-=e.e+1,d[0]=u[(Xe-t%Xe)%Xe],e.e=-t||0):d[0]=e.e=0,e;if(0==o?(d.length=c,a=1,c--):(d.length=c+1,a=u[Xe-o],d[c]=s>0?Ge(l/u[r-s]%u[s])*a:0),n)for(;;){if(0==c){for(o=1,s=d[0];s>=10;s/=10,o++);for(s=d[0]+=a,a=1;s>=10;s/=10,a++);o!=a&&(e.e++,d[0]==Ye&&(d[0]=1));break}if(d[c]+=a,d[c]!=Ye)break;d[c--]=0,a=1}for(o=d.length;0===d[--o];d.pop());}e.e>y?e.c=e.e=null:e.e=f?st(t,i):at(t,i,"0"),e.s<0?"-"+t:t)}return M.clone=e,M.ROUND_UP=0,M.ROUND_DOWN=1,M.ROUND_CEIL=2,M.ROUND_FLOOR=3,M.ROUND_HALF_UP=4,M.ROUND_HALF_DOWN=5,M.ROUND_HALF_EVEN=6,M.ROUND_HALF_CEIL=7,M.ROUND_HALF_FLOOR=8,M.EUCLID=9,M.config=M.set=function(e){var t,i;if(null!=e){if("object"!=typeof e)throw Error(Ve+"Object expected: "+e);if(e.hasOwnProperty(t="DECIMAL_PLACES")&&(rt(i=e[t],0,et,t),_=i),e.hasOwnProperty(t="ROUNDING_MODE")&&(rt(i=e[t],0,8,t),m=i),e.hasOwnProperty(t="EXPONENTIAL_AT")&&((i=e[t])&&i.pop?(rt(i[0],-et,0,t),rt(i[1],0,et,t),g=i[0],f=i[1]):(rt(i,-et,et,t),g=-(f=i<0?-i:i))),e.hasOwnProperty(t="RANGE"))if((i=e[t])&&i.pop)rt(i[0],-et,-1,t),rt(i[1],1,et,t),v=i[0],y=i[1];else{if(rt(i,-et,et,t),!i)throw Error(Ve+t+" cannot be zero: "+i);v=-(y=i<0?-i:i)}if(e.hasOwnProperty(t="CRYPTO")){if((i=e[t])!==!!i)throw Error(Ve+t+" not true or false: "+i);if(i){if("undefined"==typeof crypto||!crypto||!crypto.getRandomValues&&!crypto.randomBytes)throw b=!i,Error(Ve+"crypto unavailable");b=i}else b=i}if(e.hasOwnProperty(t="MODULO_MODE")&&(rt(i=e[t],0,9,t),w=i),e.hasOwnProperty(t="POW_PRECISION")&&(rt(i=e[t],0,et,t),k=i),e.hasOwnProperty(t="FORMAT")){if("object"!=typeof(i=e[t]))throw Error(Ve+t+" not an object: "+i);x=i}if(e.hasOwnProperty(t="ALPHABET")){if("string"!=typeof(i=e[t])||/^.?$|[+\-.\s]|(.).*\1/.test(i))throw Error(Ve+t+" invalid: "+i);$="0123456789"==i.slice(0,10),S=i}}return{DECIMAL_PLACES:_,ROUNDING_MODE:m,EXPONENTIAL_AT:[g,f],RANGE:[v,y],CRYPTO:b,MODULO_MODE:w,POW_PRECISION:k,FORMAT:x,ALPHABET:S}},M.isBigNumber=function(e){if(!e||!0!==e._isBigNumber)return!1;if(!M.DEBUG)return!0;var t,i,n=e.c,r=e.e,o=e.s;e:if("[object Array]"=={}.toString.call(n)){if((1===o||-1===o)&&r>=-et&&r<=et&&r===Ge(r)){if(0===n[0]){if(0===r&&1===n.length)return!0;break e}if((t=(r+1)%Xe)<1&&(t+=Xe),String(n[0]).length==t){for(t=0;t=Ye||i!==Ge(i))break e;if(0!==i)return!0}}}else if(null===n&&null===r&&(null===o||1===o||-1===o))return!0;throw Error(Ve+"Invalid BigNumber: "+e)},M.maximum=M.max=function(){return C(arguments,-1)},M.minimum=M.min=function(){return C(arguments,1)},M.random=(o=9007199254740992,s=Math.random()*o&2097151?function(){return Ge(Math.random()*o)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)},function(e){var t,i,n,r,o,a=0,l=[],c=new M(p);if(null==e?e=_:rt(e,0,et),r=Ue(e/Xe),b)if(crypto.getRandomValues){for(t=crypto.getRandomValues(new Uint32Array(r*=2));a>>11))>=9e15?(i=crypto.getRandomValues(new Uint32Array(2)),t[a]=i[0],t[a+1]=i[1]):(l.push(o%1e14),a+=2);a=r/2}else{if(!crypto.randomBytes)throw b=!1,Error(Ve+"crypto unavailable");for(t=crypto.randomBytes(r*=7);a=9e15?crypto.randomBytes(7).copy(t,a):(l.push(o%1e14),a+=7);a=r/7}if(!b)for(;a=10;o/=10,a++);ai-1&&(null==s[r+1]&&(s[r+1]=0),s[r+1]+=s[r]/i|0,s[r]%=i)}return s.reverse()}return function(n,r,o,s,a){var l,c,h,d,u,p,g,f,v=n.indexOf("."),y=_,b=m;for(v>=0&&(d=k,k=0,n=n.replace(".",""),p=(f=new M(r)).pow(n.length-v),k=d,f.c=t(at(it(p.c),p.e,"0"),10,o,e),f.e=f.c.length),h=d=(g=t(n,r,o,a?(l=S,e):(l=e,S))).length;0==g[--d];g.pop());if(!g[0])return l.charAt(0);if(v<0?--h:(p.c=g,p.e=h,p.s=s,g=(p=i(p,f,y,b,o)).c,u=p.r,h=p.e),v=g[c=h+y+1],d=o/2,u=u||c<0||null!=g[c+1],u=b<4?(null!=v||u)&&(0==b||b==(p.s<0?3:2)):v>d||v==d&&(4==b||u||6==b&&1&g[c-1]||b==(p.s<0?8:7)),c<1||!g[0])n=u?at(l.charAt(1),-y,l.charAt(0)):l.charAt(0);else{if(g.length=c,u)for(--o;++g[--c]>o;)g[c]=0,c||(++h,g=[1].concat(g));for(d=g.length;!g[--d];);for(v=0,n="";v<=d;n+=l.charAt(g[v++]));n=at(n,h,l.charAt(0))}return n}}(),i=function(){function e(e,t,i){var n,r,o,s,a=0,l=e.length,c=t%Qe,h=t/Qe|0;for(e=e.slice();l--;)a=((r=c*(o=e[l]%Qe)+(n=h*o+(s=e[l]/Qe|0)*c)%Qe*Qe+a)/i|0)+(n/Qe|0)+h*s,e[l]=r%i;return a&&(e=[a].concat(e)),e}function t(e,t,i,n){var r,o;if(i!=n)o=i>n?1:-1;else for(r=o=0;rt[r]?1:-1;break}return o}function i(e,t,i,n){for(var r=0;i--;)e[i]-=r,r=e[i]1;e.splice(0,1));}return function(n,r,o,s,a){var l,c,h,d,u,p,_,m,g,f,v,y,b,w,k,x,S,$=n.s==r.s?1:-1,R=n.c,C=r.c;if(!(R&&R[0]&&C&&C[0]))return new M(n.s&&r.s&&(R?!C||R[0]!=C[0]:C)?R&&0==R[0]||!C?0*$:$/0:NaN);for(g=(m=new M($)).c=[],$=o+(c=n.e-r.e)+1,a||(a=Ye,c=tt(n.e/Xe)-tt(r.e/Xe),$=$/Xe|0),h=0;C[h]==(R[h]||0);h++);if(C[h]>(R[h]||0)&&c--,$<0)g.push(1),d=!0;else{for(w=R.length,x=C.length,h=0,$+=2,(u=Ge(a/(C[0]+1)))>1&&(C=e(C,u,a),R=e(R,u,a),x=C.length,w=R.length),b=x,v=(f=R.slice(0,x)).length;v=a/2&&k++;do{if(u=0,(l=t(C,f,x,v))<0){if(y=f[0],x!=v&&(y=y*a+(f[1]||0)),(u=Ge(y/k))>1)for(u>=a&&(u=a-1),_=(p=e(C,u,a)).length,v=f.length;1==t(p,f,_,v);)u--,i(p,x<_?S:C,_,a),_=p.length,l=1;else 0==u&&(l=u=1),_=(p=C.slice()).length;if(_=10;$/=10,h++);D(m,o+(m.e=h+c*Xe-1)+1,s,d)}else m.e=c,m.r=+d;return m}}(),a=/^(-?)0([xbo])(?=\w[\w.]*$)/i,l=/^([^.]+)\.$/,c=/^\.([^.]+)$/,h=/^-?(Infinity|NaN)$/,d=/^\s*\+(?=[\w.])|^\s+|\s+$/g,r=function(e,t,i,n){var r,o=i?t:t.replace(d,"");if(h.test(o))e.s=isNaN(o)?null:o<0?-1:1;else{if(!i&&(o=o.replace(a,function(e,t,i){return r="x"==(i=i.toLowerCase())?16:"b"==i?2:8,n&&n!=r?e:t}),n&&(r=n,o=o.replace(l,"$1").replace(c,"0.$1")),t!=o))return new M(o,r);if(M.DEBUG)throw Error(Ve+"Not a"+(n?" base "+n:"")+" number: "+t);e.s=null}e.c=e.e=null},u.absoluteValue=u.abs=function(){var e=new M(this);return e.s<0&&(e.s=1),e},u.comparedTo=function(e,t){return nt(this,new M(e,t))},u.decimalPlaces=u.dp=function(e,t){var i,n,r,o=this;if(null!=e)return rt(e,0,et),null==t?t=m:rt(t,0,8),D(new M(o),e+o.e+1,t);if(!(i=o.c))return null;if(n=((r=i.length-1)-tt(this.e/Xe))*Xe,r=i[r])for(;r%10==0;r/=10,n--);return n<0&&(n=0),n},u.dividedBy=u.div=function(e,t){return i(this,new M(e,t),_,m)},u.dividedToIntegerBy=u.idiv=function(e,t){return i(this,new M(e,t),0,1)},u.exponentiatedBy=u.pow=function(e,t){var i,n,r,o,s,a,l,c,h=this;if((e=new M(e)).c&&!e.isInteger())throw Error(Ve+"Exponent not an integer: "+A(e));if(null!=t&&(t=new M(t)),s=e.e>14,!h.c||!h.c[0]||1==h.c[0]&&!h.e&&1==h.c.length||!e.c||!e.c[0])return c=new M(Math.pow(+A(h),s?e.s*(2-ot(e)):+A(e))),t?c.mod(t):c;if(a=e.s<0,t){if(t.c?!t.c[0]:!t.s)return new M(NaN);(n=!a&&h.isInteger()&&t.isInteger())&&(h=h.mod(t))}else{if(e.e>9&&(h.e>0||h.e<-1||(0==h.e?h.c[0]>1||s&&h.c[1]>=24e7:h.c[0]<8e13||s&&h.c[0]<=9999975e7)))return o=h.s<0&&ot(e)?-0:0,h.e>-1&&(o=1/o),new M(a?1/o:o);k&&(o=Ue(k/Xe+2))}for(s?(i=new M(.5),a&&(e.s=1),l=ot(e)):l=(r=Math.abs(+A(e)))%2,c=new M(p);;){if(l){if(!(c=c.times(h)).c)break;o?c.c.length>o&&(c.c.length=o):n&&(c=c.mod(t))}if(r){if(0===(r=Ge(r/2)))break;l=r%2}else if(D(e=e.times(i),e.e+1,1),e.e>14)l=ot(e);else{if(0===(r=+A(e)))break;l=r%2}h=h.times(h),o?h.c&&h.c.length>o&&(h.c.length=o):n&&(h=h.mod(t))}return n?c:(a&&(c=p.div(c)),t?c.mod(t):o?D(c,k,m,void 0):c)},u.integerValue=function(e){var t=new M(this);return null==e?e=m:rt(e,0,8),D(t,t.e+1,e)},u.isEqualTo=u.eq=function(e,t){return 0===nt(this,new M(e,t))},u.isFinite=function(){return!!this.c},u.isGreaterThan=u.gt=function(e,t){return nt(this,new M(e,t))>0},u.isGreaterThanOrEqualTo=u.gte=function(e,t){return 1===(t=nt(this,new M(e,t)))||0===t},u.isInteger=function(){return!!this.c&&tt(this.e/Xe)>this.c.length-2},u.isLessThan=u.lt=function(e,t){return nt(this,new M(e,t))<0},u.isLessThanOrEqualTo=u.lte=function(e,t){return-1===(t=nt(this,new M(e,t)))||0===t},u.isNaN=function(){return!this.s},u.isNegative=function(){return this.s<0},u.isPositive=function(){return this.s>0},u.isZero=function(){return!!this.c&&0==this.c[0]},u.minus=function(e,t){var i,n,r,o,s=this,a=s.s;if(t=(e=new M(e,t)).s,!a||!t)return new M(NaN);if(a!=t)return e.s=-t,s.plus(e);var l=s.e/Xe,c=e.e/Xe,h=s.c,d=e.c;if(!l||!c){if(!h||!d)return h?(e.s=-t,e):new M(d?s:NaN);if(!h[0]||!d[0])return d[0]?(e.s=-t,e):new M(h[0]?s:3==m?-0:0)}if(l=tt(l),c=tt(c),h=h.slice(),a=l-c){for((o=a<0)?(a=-a,r=h):(c=l,r=d),r.reverse(),t=a;t--;r.push(0));r.reverse()}else for(n=(o=(a=h.length)<(t=d.length))?a:t,a=t=0;t0)for(;t--;h[i++]=0);for(t=Ye-1;n>a;){if(h[--n]=0;){for(i=0,u=y[r]%g,p=y[r]/g|0,o=r+(s=l);o>r;)i=((c=u*(c=v[--s]%g)+(a=p*c+(h=v[s]/g|0)*u)%g*g+_[o]+i)/m|0)+(a/g|0)+p*h,_[o--]=c%m;_[o]=i}return i?++n:_.splice(0,1),T(e,_,n)},u.negated=function(){var e=new M(this);return e.s=-e.s||null,e},u.plus=function(e,t){var i,n=this,r=n.s;if(t=(e=new M(e,t)).s,!r||!t)return new M(NaN);if(r!=t)return e.s=-t,n.minus(e);var o=n.e/Xe,s=e.e/Xe,a=n.c,l=e.c;if(!o||!s){if(!a||!l)return new M(r/0);if(!a[0]||!l[0])return l[0]?e:new M(a[0]?n:0*r)}if(o=tt(o),s=tt(s),a=a.slice(),r=o-s){for(r>0?(s=o,i=l):(r=-r,i=a),i.reverse();r--;i.push(0));i.reverse()}for((r=a.length)-(t=l.length)<0&&(i=l,l=a,a=i,t=r),r=0;t;)r=(a[--t]=a[t]+l[t]+r)/Ye|0,a[t]=Ye===a[t]?0:a[t]%Ye;return r&&(a=[r].concat(a),++s),T(e,a,s)},u.precision=u.sd=function(e,t){var i,n,r,o=this;if(null!=e&&e!==!!e)return rt(e,1,et),null==t?t=m:rt(t,0,8),D(new M(o),e,t);if(!(i=o.c))return null;if(n=(r=i.length-1)*Xe+1,r=i[r]){for(;r%10==0;r/=10,n--);for(r=i[0];r>=10;r/=10,n++);}return e&&o.e+1>n&&(n=o.e+1),n},u.shiftedBy=function(e){return rt(e,-9007199254740991,Ze),this.times("1e"+e)},u.squareRoot=u.sqrt=function(){var e,t,n,r,o,s=this,a=s.c,l=s.s,c=s.e,h=_+4,d=new M("0.5");if(1!==l||!a||!a[0])return new M(!l||l<0&&(!a||a[0])?NaN:a?s:1/0);if(0==(l=Math.sqrt(+A(s)))||l==1/0?(((t=it(a)).length+c)%2==0&&(t+="0"),l=Math.sqrt(+t),c=tt((c+1)/2)-(c<0||c%2),n=new M(t=l==1/0?"5e"+c:(t=l.toExponential()).slice(0,t.indexOf("e")+1)+c)):n=new M(l+""),n.c[0])for((l=(c=n.e)+h)<3&&(l=0);;)if(o=n,n=d.times(o.plus(i(s,o,h,1))),it(o.c).slice(0,l)===(t=it(n.c)).slice(0,l)){if(n.e0&&_>0){for(o=_%a||a,h=p.substr(0,o);o<_;o+=a)h+=c+p.substr(o,a);l>0&&(h+=c+p.slice(o)),u&&(h="-"+h)}n=d?h+(i.decimalSeparator||"")+((l=+i.fractionGroupSize)?d.replace(new RegExp("\\d{"+l+"}\\B","g"),"$&"+(i.fractionGroupSeparator||"")):d):h}return(i.prefix||"")+n+(i.suffix||"")},u.toFraction=function(e){var t,n,r,o,s,a,l,c,h,d,u,_,g=this,f=g.c;if(null!=e&&(!(l=new M(e)).isInteger()&&(l.c||1!==l.s)||l.lt(p)))throw Error(Ve+"Argument "+(l.isInteger()?"out of range: ":"not an integer: ")+A(l));if(!f)return new M(g);for(t=new M(p),h=n=new M(p),r=c=new M(p),_=it(f),s=t.e=_.length-g.e-1,t.c[0]=Je[(a=s%Xe)<0?Xe+a:a],e=!e||l.comparedTo(t)>0?s>0?t:h:l,a=y,y=1/0,l=new M(_),c.c[0]=0;d=i(l,t,0,1),1!=(o=n.plus(d.times(r))).comparedTo(e);)n=r,r=o,h=c.plus(d.times(o=h)),c=o,t=l.minus(d.times(o=t)),l=o;return o=i(e.minus(n),r,0,1),c=c.plus(o.times(h)),n=n.plus(o.times(r)),c.s=h.s=g.s,u=i(h,r,s*=2,m).minus(g).abs().comparedTo(i(c,n,s,m).minus(g).abs())<1?[h,r]:[c,n],y=a,u},u.toNumber=function(){return+A(this)},u.toPrecision=function(e,t){return null!=e&&rt(e,1,et),R(this,e,t,2)},u.toString=function(e){var t,i=this,r=i.s,o=i.e;return null===o?r?(t="Infinity",r<0&&(t="-"+t)):t="NaN":(null==e?t=o<=g||o>=f?st(it(i.c),o):at(it(i.c),o,"0"):10===e&&$?t=at(it((i=D(new M(i),_+o+1,m)).c),i.e,"0"):(rt(e,2,S.length,"Base"),t=n(at(it(i.c),o,"0"),10,e,r,!0)),r<0&&i.c[0]&&(t="-"+t)),t},u.valueOf=u.toJSON=function(){return A(this)},u._isBigNumber=!0,u[Symbol.toStringTag]="BigNumber",u[Symbol.for("nodejs.util.inspect.custom")]=u.valueOf,null!=t&&M.set(t),M}(),ct=class{key;left=null;right=null;constructor(e){this.key=e}},ht=class extends ct{constructor(e){super(e)}},dt=class{size=0;modificationCount=0;splayCount=0;splay(e){const t=this.root;if(null==t)return this.compare(e,e),-1;let i=null,n=null,r=null,o=null,s=t;const a=this.compare;let l;for(;;)if(l=a(s.key,e),l>0){let t=s.left;if(null==t)break;if(l=a(t.key,e),l>0&&(s.left=t.right,t.right=s,s=t,t=s.left,null==t))break;null==i?n=s:i.left=s,i=s,s=t}else{if(!(l<0))break;{let t=s.right;if(null==t)break;if(l=a(t.key,e),l<0&&(s.right=t.left,t.left=s,s=t,t=s.right,null==t))break;null==r?o=s:r.right=s,r=s,s=t}}return null!=r&&(r.right=s.left,s.left=o),null!=i&&(i.left=s.right,s.right=n),this.root!==s&&(this.root=s,this.splayCount++),l}splayMin(e){let t=e,i=t.left;for(;null!=i;){const e=i;t.left=e.right,e.right=t,t=e,i=t.left}return t}splayMax(e){let t=e,i=t.right;for(;null!=i;){const e=i;t.right=e.left,e.left=t,t=e,i=t.right}return t}_delete(e){if(null==this.root)return null;if(0!=this.splay(e))return null;let t=this.root;const i=t,n=t.left;if(this.size--,null==n)this.root=t.right;else{const e=t.right;t=this.splayMax(n),t.right=e,this.root=t}return this.modificationCount++,i}addNewRoot(e,t){this.size++,this.modificationCount++;const i=this.root;null!=i?(t<0?(e.left=i,e.right=i.right,i.right=null):(e.right=i,e.left=i.left,i.left=null),this.root=e):this.root=e}_first(){const e=this.root;return null==e?null:(this.root=this.splayMin(e),this.root)}_last(){const e=this.root;return null==e?null:(this.root=this.splayMax(e),this.root)}clear(){this.root=null,this.size=0,this.modificationCount++}has(e){return this.validKey(e)&&0==this.splay(e)}defaultCompare(){return(e,t)=>et?1:0}wrap(){return{getRoot:()=>this.root,setRoot:e=>{this.root=e},getSize:()=>this.size,getModificationCount:()=>this.modificationCount,getSplayCount:()=>this.splayCount,setSplayCount:e=>{this.splayCount=e},splay:e=>this.splay(e),has:e=>this.has(e)}}},ut=class e extends dt{root=null;compare;validKey;constructor(e,t){super(),this.compare=e??this.defaultCompare(),this.validKey=t??(e=>null!=e&&null!=e)}delete(e){return!!this.validKey(e)&&null!=this._delete(e)}deleteAll(e){for(const t of e)this.delete(t)}forEach(e){const t=this[Symbol.iterator]();let i;for(;i=t.next(),!i.done;)e(i.value,i.value,this)}add(e){const t=this.splay(e);return 0!=t&&this.addNewRoot(new ht(e),t),this}addAndReturn(e){const t=this.splay(e);return 0!=t&&this.addNewRoot(new ht(e),t),this.root.key}addAll(e){for(const t of e)this.add(t)}isEmpty(){return null==this.root}isNotEmpty(){return null!=this.root}single(){if(0==this.size)throw"Bad state: No element";if(this.size>1)throw"Bad state: Too many element";return this.root.key}first(){if(0==this.size)throw"Bad state: No element";return this._first().key}last(){if(0==this.size)throw"Bad state: No element";return this._last().key}lastBefore(e){if(null==e)throw"Invalid arguments(s)";if(null==this.root)return null;if(this.splay(e)<0)return this.root.key;let t=this.root.left;if(null==t)return null;let i=t.right;for(;null!=i;)t=i,i=t.right;return t.key}firstAfter(e){if(null==e)throw"Invalid arguments(s)";if(null==this.root)return null;if(this.splay(e)>0)return this.root.key;let t=this.root.right;if(null==t)return null;let i=t.left;for(;null!=i;)t=i,i=t.left;return t.key}retainAll(t){const i=new e(this.compare,this.validKey),n=this.modificationCount;for(const e of t){if(n!=this.modificationCount)throw"Concurrent modification during iteration.";this.validKey(e)&&0==this.splay(e)&&i.add(this.root.key)}i.size!=this.size&&(this.root=i.root,this.size=i.size,this.modificationCount++)}lookup(e){if(!this.validKey(e))return null;return 0!=this.splay(e)?null:this.root.key}intersection(t){const i=new e(this.compare,this.validKey);for(const e of this)t.has(e)&&i.add(e);return i}difference(t){const i=new e(this.compare,this.validKey);for(const e of this)t.has(e)||i.add(e);return i}union(e){const t=this.clone();return t.addAll(e),t}clone(){const t=new e(this.compare,this.validKey);return t.size=this.size,t.root=this.copyNode(this.root),t}copyNode(e){if(null==e)return null;const t=new ht(e.key);return function e(t,i){let n,r;do{if(n=t.left,r=t.right,null!=n){const t=new ht(n.key);i.left=t,e(n,t)}if(null!=r){const e=new ht(r.key);i.right=e,t=r,i=e}}while(null!=r)}(e,t),t}toSet(){return this.clone()}entries(){return new mt(this.wrap())}keys(){return this[Symbol.iterator]()}values(){return this[Symbol.iterator]()}[Symbol.iterator](){return new _t(this.wrap())}[Symbol.toStringTag]="[object Set]"},pt=class{tree;path=new Array;modificationCount=null;splayCount;constructor(e){this.tree=e,this.splayCount=e.getSplayCount()}[Symbol.iterator](){return this}next(){return this.moveNext()?{done:!1,value:this.current()}:{done:!0,value:null}}current(){if(!this.path.length)return null;const e=this.path[this.path.length-1];return this.getValue(e)}rebuildPath(e){this.path.splice(0,this.path.length),this.tree.splay(e),this.path.push(this.tree.getRoot()),this.splayCount=this.tree.getSplayCount()}findLeftMostDescendent(e){for(;null!=e;)this.path.push(e),e=e.left}moveNext(){if(this.modificationCount!=this.tree.getModificationCount()){if(null==this.modificationCount){this.modificationCount=this.tree.getModificationCount();let e=this.tree.getRoot();for(;null!=e;)this.path.push(e),e=e.left;return this.path.length>0}throw"Concurrent modification during iteration."}if(!this.path.length)return!1;this.splayCount!=this.tree.getSplayCount()&&this.rebuildPath(this.path[this.path.length-1].key);let e=this.path[this.path.length-1],t=e.right;if(null!=t){for(;null!=t;)this.path.push(t),t=t.left;return!0}for(this.path.pop();this.path.length&&this.path[this.path.length-1].right===e;)e=this.path.pop();return this.path.length>0}},_t=class extends pt{getValue(e){return e.key}},mt=class extends pt{getValue(e){return[e.key,e.key]}},gt=e=>()=>e,ft=e=>{const t=e?(t,i)=>i.minus(t).abs().isLessThanOrEqualTo(e):gt(!1);return(e,i)=>t(e,i)?0:e.comparedTo(i)};function vt(e){const t=e?(t,i,n,r,o)=>t.exponentiatedBy(2).isLessThanOrEqualTo(r.minus(i).exponentiatedBy(2).plus(o.minus(n).exponentiatedBy(2)).times(e)):gt(!1);return(e,i,n)=>{const r=e.x,o=e.y,s=n.x,a=n.y,l=o.minus(a).times(i.x.minus(s)).minus(r.minus(s).times(i.y.minus(a)));return t(l,r,o,s,a)?0:l.comparedTo(0)}}var yt=e=>e,bt=e=>{if(e){const t=new ut(ft(e)),i=new ut(ft(e)),n=(e,t)=>t.addAndReturn(e),r=e=>({x:n(e.x,t),y:n(e.y,i)});return r({x:new lt(0),y:new lt(0)}),r}return yt},wt=e=>({set:e=>{kt=wt(e)},reset:()=>wt(e),compare:ft(e),snap:bt(e),orient:vt(e)}),kt=wt(),xt=(e,t)=>e.ll.x.isLessThanOrEqualTo(t.x)&&t.x.isLessThanOrEqualTo(e.ur.x)&&e.ll.y.isLessThanOrEqualTo(t.y)&&t.y.isLessThanOrEqualTo(e.ur.y),St=(e,t)=>{if(t.ur.x.isLessThan(e.ll.x)||e.ur.x.isLessThan(t.ll.x)||t.ur.y.isLessThan(e.ll.y)||e.ur.y.isLessThan(t.ll.y))return null;const i=e.ll.x.isLessThan(t.ll.x)?t.ll.x:e.ll.x,n=e.ur.x.isLessThan(t.ur.x)?e.ur.x:t.ur.x;return{ll:{x:i,y:e.ll.y.isLessThan(t.ll.y)?t.ll.y:e.ll.y},ur:{x:n,y:e.ur.y.isLessThan(t.ur.y)?e.ur.y:t.ur.y}}},$t=(e,t)=>e.x.times(t.y).minus(e.y.times(t.x)),Mt=(e,t)=>e.x.times(t.x).plus(e.y.times(t.y)),Rt=e=>Mt(e,e).sqrt(),Ct=(e,t,i)=>{const n={x:t.x.minus(e.x),y:t.y.minus(e.y)},r={x:i.x.minus(e.x),y:i.y.minus(e.y)};return $t(r,n).div(Rt(r)).div(Rt(n))},Tt=(e,t,i)=>{const n={x:t.x.minus(e.x),y:t.y.minus(e.y)},r={x:i.x.minus(e.x),y:i.y.minus(e.y)};return Mt(r,n).div(Rt(r)).div(Rt(n))},Dt=(e,t,i)=>t.y.isZero()?null:{x:e.x.plus(t.x.div(t.y).times(i.minus(e.y))),y:i},At=(e,t,i)=>t.x.isZero()?null:{x:i,y:e.y.plus(t.y.div(t.x).times(i.minus(e.x)))},Pt=class e{point;isLeft;segment;otherSE;consumedBy;static compare(t,i){const n=e.comparePoints(t.point,i.point);return 0!==n?n:(t.point!==i.point&&t.link(i),t.isLeft!==i.isLeft?t.isLeft?1:-1:Lt.compare(t.segment,i.segment))}static comparePoints(e,t){return e.x.isLessThan(t.x)?-1:e.x.isGreaterThan(t.x)?1:e.y.isLessThan(t.y)?-1:e.y.isGreaterThan(t.y)?1:0}constructor(e,t){void 0===e.events?e.events=[this]:e.events.push(this),this.point=e,this.isLeft=t}link(e){if(e.point===this.point)throw new Error("Tried to link already linked events");const t=e.point.events;for(let e=0,i=t.length;e{const n=i.otherSE;t.set(i,{sine:Ct(this.point,e.point,n.point),cosine:Tt(this.point,e.point,n.point)})};return(e,n)=>{t.has(e)||i(e),t.has(n)||i(n);const{sine:r,cosine:o}=t.get(e),{sine:s,cosine:a}=t.get(n);return r.isGreaterThanOrEqualTo(0)&&s.isGreaterThanOrEqualTo(0)?o.isLessThan(a)?1:o.isGreaterThan(a)?-1:0:r.isLessThan(0)&&s.isLessThan(0)?o.isLessThan(a)?-1:o.isGreaterThan(a)?1:0:s.isLessThan(r)?-1:s.isGreaterThan(r)?1:0}}},Ft=class e{events;poly;_isExteriorRing;_enclosingRing;static factory(t){const i=[];for(let n=0,r=t.length;n0&&(e=i)}let t=e.segment.prevInResult(),i=t?t.prevInResult():null;for(;;){if(!t)return null;if(!i)return t.ringOut;if(i.ringOut!==t.ringOut)return i.ringOut?.enclosingRing()!==t.ringOut?t.ringOut:t.ringOut?.enclosingRing();t=i.prevInResult(),i=t?t.prevInResult():null}}},zt=class{exteriorRing;interiorRings;constructor(e){this.exteriorRing=e,e.poly=this,this.interiorRings=[]}addInterior(e){this.interiorRings.push(e),e.poly=this}getGeom(){const e=this.exteriorRing.getGeom();if(null===e)return null;const t=[e];for(let e=0,i=this.interiorRings.length;e0?(this.tree.delete(t),i.push(e)):(this.segments.push(t),t.prev=n)}else{if(n&&r){const e=n.getIntersection(r);if(null!==e){if(!n.isAnEndpoint(e)){const t=this._splitSafely(n,e);for(let e=0,n=t.length;e0)return-1;const n=t.comparePoint(e.rightSE.point);return 0!==n?n:-1}if(i.isGreaterThan(n)){if(s.isLessThan(a)&&s.isLessThan(c))return-1;if(s.isGreaterThan(a)&&s.isGreaterThan(c))return 1;const i=t.comparePoint(e.leftSE.point);if(0!==i)return i;const n=e.comparePoint(t.rightSE.point);return n<0?1:n>0?-1:1}if(s.isLessThan(a))return-1;if(s.isGreaterThan(a))return 1;if(r.isLessThan(o)){const i=t.comparePoint(e.rightSE.point);if(0!==i)return i}if(r.isGreaterThan(o)){const i=e.comparePoint(t.rightSE.point);if(i<0)return 1;if(i>0)return-1}if(!r.eq(o)){const e=l.minus(s),t=r.minus(i),h=c.minus(a),d=o.minus(n);if(e.isGreaterThan(t)&&h.isLessThan(d))return 1;if(e.isLessThan(t)&&h.isGreaterThan(d))return-1}return r.isGreaterThan(o)?1:r.isLessThan(o)||l.isLessThan(c)?-1:l.isGreaterThan(c)?1:e.idt.id?1:0}constructor(e,t,i,n){this.id=++Ht,this.leftSE=e,e.segment=this,e.otherSE=t,this.rightSE=t,t.segment=this,t.otherSE=e,this.rings=i,this.windings=n}static fromRing(t,i,n){let r,o,s;const a=Pt.comparePoints(t,i);if(a<0)r=t,o=i,s=1;else{if(!(a>0))throw new Error(`Tried to create degenerate segment at [${t.x}, ${t.y}]`);r=i,o=t,s=-1}const l=new Pt(r,!0),c=new Pt(o,!1);return new e(l,c,[n],[s])}replaceRightSE(e){this.rightSE=e,this.rightSE.segment=this,this.rightSE.otherSE=this.leftSE,this.leftSE.otherSE=this.rightSE}bbox(){const e=this.leftSE.point.y,t=this.rightSE.point.y;return{ll:{x:this.leftSE.point.x,y:e.isLessThan(t)?e:t},ur:{x:this.rightSE.point.x,y:e.isGreaterThan(t)?e:t}}}vector(){return{x:this.rightSE.point.x.minus(this.leftSE.point.x),y:this.rightSE.point.y.minus(this.leftSE.point.y)}}isAnEndpoint(e){return e.x.eq(this.leftSE.point.x)&&e.y.eq(this.leftSE.point.y)||e.x.eq(this.rightSE.point.x)&&e.y.eq(this.rightSE.point.y)}comparePoint(e){return kt.orient(this.leftSE.point,e,this.rightSE.point)}getIntersection(e){const t=this.bbox(),i=e.bbox(),n=St(t,i);if(null===n)return null;const r=this.leftSE.point,o=this.rightSE.point,s=e.leftSE.point,a=e.rightSE.point,l=xt(t,s)&&0===this.comparePoint(s),c=xt(i,r)&&0===e.comparePoint(r),h=xt(t,a)&&0===this.comparePoint(a),d=xt(i,o)&&0===e.comparePoint(o);if(c&&l)return d&&!h?o:!d&&h?a:null;if(c)return h&&r.x.eq(a.x)&&r.y.eq(a.y)?null:r;if(l)return d&&o.x.eq(s.x)&&o.y.eq(s.y)?null:s;if(d&&h)return null;if(d)return o;if(h)return a;const u=((e,t,i,n)=>{if(t.x.isZero())return At(i,n,e.x);if(n.x.isZero())return At(e,t,i.x);if(t.y.isZero())return Dt(i,n,e.y);if(n.y.isZero())return Dt(e,t,i.y);const r=$t(t,n);if(r.isZero())return null;const o={x:i.x.minus(e.x),y:i.y.minus(e.y)},s=$t(o,t).div(r),a=$t(o,n).div(r),l=e.x.plus(a.times(t.x)),c=i.x.plus(s.times(n.x)),h=e.y.plus(a.times(t.y)),d=i.y.plus(s.times(n.y));return{x:l.plus(c).div(2),y:h.plus(d).div(2)}})(r,this.vector(),s,e.vector());return null===u?null:xt(n,u)?kt.snap(u):null}split(t){const i=[],n=void 0!==t.events,r=new Pt(t,!0),o=new Pt(t,!1),s=this.rightSE;this.replaceRightSE(o),i.push(o),i.push(r);const a=new e(r,s,this.rings.slice(),this.windings.slice());return Pt.comparePoints(a.leftSE.point,a.rightSE.point)>0&&a.swapEvents(),Pt.comparePoints(this.leftSE.point,this.rightSE.point)>0&&this.swapEvents(),n&&(r.checkForConsuming(),o.checkForConsuming()),i}swapEvents(){const e=this.rightSE;this.rightSE=this.leftSE,this.leftSE=e,this.leftSE.isLeft=!0,this.rightSE.isLeft=!1;for(let e=0,t=this.windings.length;e0){const e=i;i=n,n=e}if(i.prev===n){const e=i;i=n,n=e}for(let e=0,t=n.rings.length;e1===e.length&&e[0].isSubject;this._isInResult=i(e)!==i(t);break}}return this._isInResult}},Bt=class{poly;isExterior;segments;bbox;constructor(e,t,i){if(!Array.isArray(e)||0===e.length)throw new Error("Input geometry is not a valid Polygon or MultiPolygon");if(this.poly=t,this.isExterior=i,this.segments=[],"number"!=typeof e[0][0]||"number"!=typeof e[0][1])throw new Error("Input geometry is not a valid Polygon or MultiPolygon");const n=kt.snap({x:new lt(e[0][0]),y:new lt(e[0][1])});this.bbox={ll:{x:n.x,y:n.y},ur:{x:n.x,y:n.y}};let r=n;for(let t=1,i=e.length;tNt.run("union",e,t),Ut=(e,...t)=>Nt.run("intersection",e,t),Gt=(e,...t)=>Nt.run("difference",e,t);kt.set;const Vt=/^#[0-9a-fA-F]{6}$/;function Kt(e,t){return"string"==typeof e&&Vt.test(e)?e:t}const Yt="(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])",Xt=new RegExp(`^rgb\\(${Yt}, ${Yt}, ${Yt}\\)$`);function Zt(e){if(!Array.isArray(e)||e.length<3)return null;const t=e.slice(0,3);if(!t.every(e=>"number"==typeof e&&Number.isFinite(e)))return null;const[i,n,r]=t.map(e=>Math.round(Math.min(255,Math.max(0,e))));return`rgb(${i}, ${n}, ${r})`}function Jt(e){const t=Math.max(0,Math.min(120,(e-40)/140*120));return`hsl(${Math.round(t)}, 85%, 55%)`}function Qt(e,t){if(!(Number.isFinite(e)&&t>0))return e;const i=Math.round(e/t)*t;return Math.abs(i-e)<=1e-9*t?e:i}function ei(e,t,i,n=1/0){if(!(i>0&&e?.every(Number.isFinite)&&t?.every(Number.isFinite)))return[t[0],t[1]];const r=t[0]-e[0],o=t[1]-e[1];if(Math.abs(r)+Math.abs(o)<=1e-12)return[e[0],e[1]];const s=Math.PI/4;let a=Math.atan2(o,r);a<0&&(a+=2*Math.PI);const l=Math.floor(a/s+.5)%8,[c,h]=[[1,0],[1,1],[0,1],[-1,1],[-1,0],[-1,-1],[0,-1],[1,-1]][l],d=c*c+h*h;let u=Math.max(0,Math.round((r*c+o*h)/(i*d)));if(Number.isFinite(n)&&n>=0){const t=(e,t)=>{if(!t)return 1/0;const r=t>0?n-e:e+n;return Math.max(0,Math.floor((r+1e-9*i)/i))};u=Math.min(u,t(e[0],c),t(e[1],h))}return[e[0]+c*u*i,e[1]+h*u*i]}function ti(e,t){if(t){const t=e/2.54;let i=Math.floor(t/12),n=Math.round(t-12*i);return 12===n&&(i+=1,n=0),`${i}′ ${n}″`}return`${(e/100).toFixed(2)} m`}function ii(e,t,i=1){const n=e[0].toFixed(i),r=e[1].toFixed(i),o=t[0].toFixed(i),s=t[1].toFixed(i),a=n=3?e.poly:e&&null!=e.x&&null!=e.y&&null!=e.w&&null!=e.h?[[e.x,e.y],[e.x+e.w,e.y],[e.x+e.w,e.y+e.h],[e.x,e.y+e.h]]:null}function ri(e){const t=[];for(const i of e||[])i?.poly?.length>=3?t.push({poly:i.poly.map(e=>e.join(",")).join(" ")}):i&&null!=i.x&&null!=i.y&&null!=i.w&&null!=i.h&&t.push({rect:{x:i.x,y:i.y,w:i.w,h:i.h,rx:.03*Math.min(i.w,i.h)}});return t}function oi(e){const t=[],i=new Set;for(const n of e||[]){const e=ni(n);if(e)for(let n=0;n=90?e-=180:e<-90&&(e+=180),n.step&&n.step>0){const i=Math.sqrt(d),o=Math.min(Math.max(n.length||0,0)/2,i/2);let a=Math.round(u*i/n.step)*n.step;Math.abs(u*i-i/2)<=n.step/2&&(a=i/2),a=Math.max(o,Math.min(i-o,a));const l=a/i;r={x:t+l*c,y:s+l*h,angle:e}}else r={x:p[0],y:p[1],angle:e}}}return r}function ai(e,t,i){let n=null,r=1/0;for(let o=0;o=r)continue;r=_;const m=Math.sqrt(u),g=(i>0?Math.max(0,Math.min(m,Math.round(p*m/i)*i)):p*m)/m;n=[s+g*h,a+g*d]}return n}function li(e,t,i,n,r,o=1){const s=t*Math.PI/180,a=[Math.cos(s),Math.sin(s)];let l=null,c=o;for(const t of oi(n)){const i=[[t[0],t[1]],[t[2],t[3]]],n=t=>Math.abs(a[0]*(t[1]-e[1])-a[1]*(t[0]-e[0]));if(n(i[0])>o||n(i[1])>o)continue;const r=(i[0][0]-e[0])*a[0]+(i[0][1]-e[1])*a[1],s=(i[1][0]-e[0])*a[0]+(i[1][1]-e[1])*a[1],h=Math.min(r,s),d=Math.max(r,s),u=h>0?h:d<0?-d:0;u[e[0]+a[0]*t,e[1]+a[1]*t],g=(h+d)/2;return{wallA:m(h),wallB:m(d),sideA:p,sideB:_,midA:m((h-u)/2),midB:m((u+d)/2),wallCenter:m(g),centered:Math.abs(g)<=r}}function ci(e,t,i=!1,n){if("passage"===e)return 1;if(null==t||"unavailable"===t||"unknown"===t)return"window"===e?0:1;const r="string"==typeof n?n.trim()?Number(n):NaN:Number(n),o=null!=n&&Number.isFinite(r)?Math.max(0,Math.min(1,r/100)):function(e){return["on","open","home","detected","playing","cleaning"].includes(String(e))}(t)?1:0;return i?1-o:o}function hi(e){const t=Number.isFinite(e)?Math.max(0,Math.min(1,e)):0;return Math.min(1,Math.max(0,.05*Math.round(t/.05)))}function di(e,t){return(Number.isFinite(e)&&e>0?e:0)*(Number.isFinite(t)?Math.max(0,Math.min(1,t)):0)}function ui(e){return"passage"===e.type?[]:[e.contact,e.lock].filter(e=>"string"==typeof e&&e.length>0)}function pi(e,t,i=200){const n=t.trim().toLowerCase();return(n?e.filter(e=>e.label.toLowerCase().includes(n)||e.value.toLowerCase().includes(n)):e).slice(0,Math.max(0,i))}function _i(e,t,i=.001){return Math.abs(e[0]-t[0])e[1]!=l>e[1]&&e[0]<(a-o)*(e[1]-s)/(l-s)+o&&(i=!i)}return i}function gi(e,t,i){const n=i[0]-t[0],r=i[1]-t[1],o=n*n+r*r;let s=o?((e[0]-t[0])*n+(e[1]-t[1])*r)/o:0;return s=Math.max(0,Math.min(1,s)),Math.hypot(e[0]-(t[0]+s*n),e[1]-(t[1]+s*r))}function fi(e,t){if(!t||t.length<2)return null;let i=null,n=1/0;for(let r=0;rr&&s<-r||o<-r&&s>r)&&(a>r&&l<-r||a<-r&&l>r)}function ki(e,t=24){const i=e.map(e=>e[0]),n=e.map(e=>e[1]),r=Math.min(...i),o=Math.max(...i),s=Math.min(...n),a=Math.max(...n),l=Math.max(o-r,a-s)||1;let c=0,h=0,d=0;for(let t=0;t1e-9?[h/(3*c),d/(3*c)]:[(r+o)/2,(s+a)/2],p=(t,i)=>{const n=((t,i)=>{if(!mi([t,i],e))return-1/0;let n=1/0;for(let r=0;rm&&(m=c,_=[n,l])}if(_){const[e,i]=_,n=(o-r)/t,l=(a-s)/t;for(let t=-4;t<=4;t++)for(let r=-4;r<=4;r++){const o=e+n*t/4,s=i+l*r/4,a=p(o,s);a>m&&(m=a,_=[o,s])}}return _||xi(e)||e[0]}function xi(e,t=1e-6){if(!e||e.length<3)return null;const i=e.length,n=[e.reduce((e,t)=>e+t[0],0)/i,e.reduce((e,t)=>e+t[1],0)/i];if(yi(n,e,t))return n;for(let n=0;n$i(e,t,i));return n.filter(e=>!n.some(t=>t!==e&&$i(t,e,i)))}function Ci(e){if(!e||e.length<3)return 0;let t=0;for(let i=0;i[e[0],e[1]]),[e[0][0],e[0][1]]]]}function Di(e,t){if(!e||!t||e.length<3||t.length<3)return null;const i=Wt(Ti(e),Ti(t));if(1!==i.length)return null;if(1!==i[0].length)return null;const n=i[0][0].slice(0,-1).map(e=>[e[0],e[1]]);return n.length>=3?n:null}function Ai(e,t,i){for(let n=0;n1&&_i(i[0],i[i.length-1],t)&&i.pop(),i}function Fi(e,t,i=1e-6){if(!e||e.length<3||!t||t.length<2)return null;const n=t[0],r=t[t.length-1];if(_i(n,r,i))return null;const o=Ai(e,n,i),s=Ai(e,r,i);if(o<0||s<0)return null;const a=t.slice(1,-1);for(const t of a)if(!yi(t,e,i))return null;for(let i=0;i{const s=[t];let a=(n+1)%e.length;for(let t=0;t<=e.length&&(s.push(e[a]),a!==o);t++)a=(a+1)%e.length;return s.push(r),Pi(s,i)};let c,h;if(o===s){const s=Pi([...t],i);if(s.length<3||Ci(s)<=i)return null;const a=[];for(let i=0;i=0?t:[...t].reverse();for(const e of i)a.push(e)}c=Pi(a,i),h=s}else c=Pi([...l(n,o,r,s),...[...a].reverse()],i),h=Pi([...l(r,s,n,o),...a],i);return c.length<3||h.length<3||Ci(c)<=i||Ci(h)<=i||Math.abs(Ci(c)+Ci(h)-Ci(e))>Math.max(i,1e-6*Ci(e))?null:[c,h]}function zi(e,t,i){const[n,r]=e.split(":");return"device"===n?r:"entity"===n?"lg_"+r:t&&t.startsWith("v_")?t:i()}function Ii(e){return e.length?Math.round(e.reduce((e,t)=>e+t,0)/e.length):null}function Oi(e,t){if(t>e[2]/e[3]){const i=e[3],n=e[3]*t;return{x:e[0]-(n-e[2])/2,y:e[1],w:n,h:i}}const i=e[2],n=e[2]/t;return{x:e[0],y:e[1]-(n-e[3])/2,w:i,h:n}}function Ei(e,t,i,n){if(e.length<2)return;const r=t.x+n,o=t.x+t.w-n,s=t.y+n,a=t.y+t.h-n;for(let t=0;t<60;t++){let t=!1;for(let n=0;n=0)i=t.slice(0,r).trim(),n=t.slice(r+1).trim();else{const e=t.split(".");e.length>2&&(i=e.slice(0,2).join("."),n=e.slice(2).join("."))}return/^[a-z0-9_]+\.[a-z0-9_]+$/.test(i)?r>=0&&!n||n&&!/^[a-zA-Z0-9_.-]+$/.test(n)?null:n?{entity:i,attr:n}:{entity:i}:null}function Yi(e,t){const i=String(e??"").trim(),n=String(t??"").trim(),r=Ki(n?`${i}:${n}`:i);return r?`{${r.entity}${r.attr?`:${r.attr}`:""}}`:""}function Xi(e,t,i){const n=String(t??"").trim();if(!n)return null;const r=e?.states?.[n];if(!r)return null;const o=String(i??"").trim(),s=e=>e.slice(0,60);if(o){const t=function(e){if(null==e)return null;if(Array.isArray(e)){const t=e.map(e=>null==e?"":String(e)).join(", ");return t?t.slice(0,60):null}if("object"==typeof e)return null;const t=String(e);return""===t?null:t.slice(0,60)}(r.attributes?.[o]);if(null===t)return null;const i=e?.formatEntityAttributeValue;if("function"==typeof i)try{const t=i.call(e,r,o);if("string"==typeof t&&""!==t)return{text:s(t),formatted:!0}}catch{}return{text:t,formatted:!1}}const a=r.state;if(null==a||""===a)return null;const l=e?.formatEntityState;if("function"==typeof l)try{const t=l.call(e,r);if("string"==typeof t&&""!==t)return{text:s(t),formatted:!0}}catch{}return{text:s(String(a)),formatted:!1}}function Zi(e,t,i){const n=String(t??"").trim(),r=String(i??"").trim()||n;if(!r)return e.text;const o=e.formatted&&n?function(e,t){if(!t)return e;const i=e.replace(/\s+$/,"");return i.endsWith(t)?i.slice(0,i.length-t.length).replace(/\s+$/,""):e}(e.text,n):e.text;return`${o} ${r}`}function Ji(e,t){const i=(t?.entity||"").trim();if(!i)return"";const n=e?.states?.[i],r=n?.state;if(!n||null==r||""===r||"unavailable"===r||"unknown"===r)return Gi;const o=(t?.attr||"").trim(),s=Xi(e,i,o||null);if(null===s)return Gi;return Zi(s,o?"":String(n.attributes?.unit_of_measurement??"").trim(),t?.unit)}function Qi(e,t,i,n=()=>!0){const r=e??"";let o=!1;const s=r.replace(/\{([^{}\r\n]+)\}/g,(e,t)=>{const r=Ki(t);return r?(o=!0,n(r.entity||"")?Ji(i,r):Gi):e});if(o)return s;const a=(t?.entity||"").trim();if(!a)return r;if(!n(a)){const e=r.indexOf(Vi);return e>=0?r.slice(0,e)+Gi+r.slice(e+2):r?`${r} ${Gi}`:Gi}const l=Ji(i,t),c=r.indexOf(Vi);return c>=0?r.slice(0,c)+l+r.slice(c+2):r?`${r} ${l}`:l}const en=20;function tn(e){const t=Number(e?.scale);if(Number.isFinite(t)&&t>0)return Math.min(20,Math.max(.15,t));return{s:.7,m:1,l:1.5}[String(e?.size??"")]??1}function nn(e,t){if(!t)return e;let i=e;for(const[e,n]of Object.entries(t))i=i.split("{"+e+"}").join(String(n));return i}const rn="#55606c",on=.55,sn=20,an=25,ln={c:"#607d8b",a:.18};function cn(e,t=ln){const i=e&&"object"==typeof e?e:null,n=i?.a;return{c:Kt(i?.c,t.c),a:"number"==typeof n&&Number.isFinite(n)?Math.min(1,Math.max(0,n)):t.a}}function hn(e,t){const i=cn(e),n=t?.settings?.custom_fill;return n&&"object"==typeof n?cn(n,i):i}function dn(e,t,i){const n=(e,t)=>"number"==typeof e&&Number.isFinite(e)?e:t,r=n(e,20),o=n(t,25),s=n(i?.settings?.temp_min,r),a=n(i?.settings?.temp_max,o);return{min:Math.min(s,a),max:Math.max(s,a)}}function un(e){const t=e?.settings||{},i=!e?.plan_url,n="glow"===t.fill_mode;return{showBorders:t.show_borders??i,showNames:t.show_names??i,color:Kt(t.room_color,rn),opacity:"number"==typeof t.room_opacity?Math.min(1,Math.max(0,t.room_opacity)):.55,fill:["lqi","light","temp","custom"].includes(t.fill_mode)?t.fill_mode:"none",customFill:cn(t.custom_fill),glow:"boolean"==typeof t.glow_enabled?t.glow_enabled:n,tempMin:"number"==typeof t.temp_min?t.temp_min:20,tempMax:"number"==typeof t.temp_max?t.temp_max:25,showLqi:"boolean"==typeof t.show_lqi?t.show_lqi:null,cardFontScale:"number"==typeof t.card_font_scale&&t.card_font_scale>0?Math.min(3,Math.max(.5,t.card_font_scale)):1,labelTemp:!0===t.label_temp,labelHum:!0===t.label_hum,labelLqi:!0===t.label_lqi,labelLight:!0===t.label_light,bgColor:Kt(t.bg_color,null),hideDecor:!0===t.hide_decor,hideOpenings:!0===t.hide_openings}}function pn(e,t){if(t.bgColor)return t.bgColor;const i=e?.bg_color;return Kt(i,"")}function _n(e){return!1!==e?.show_room_tooltip}const mn={light_on:{c:"#ffd45c",a:.18},light_off:{c:"#9aa0a6",a:.14},light_none:{c:"#6b7480",a:0},temp_cold:{c:"#4fc3f7",a:.18},temp_ok:{c:"#66d17a",a:.18},temp_hot:{c:"#ffd45c",a:.18},lqi_low:{c:"#f25a4a",a:.18},lqi_high:{c:"#4bd28f",a:.18},glow_base:{c:"#0d1b2a",a:.5},glow_light:{c:"#ffd9a0",a:.85},wall_fill:{c:"#ffffff",a:1}};function gn(e){const t={},i=e?.fill_colors||{};for(const e of Object.keys(mn)){const n=mn[e],r=i[e];t[e]={c:Kt(r?.c,n.c),a:r&&"number"==typeof r.a?Math.min(1,Math.max(0,r.a)):n.a}}return t}function fn(e,t,i){const n=Math.min(1,Math.max(0,i)),r=[1,3,5].map(t=>parseInt(e.slice(t,t+2),16)),o=[1,3,5].map(e=>parseInt(t.slice(e,e+2),16)),s=r.map((e,t)=>Math.round(e+(o[t]-e)*n));return"#"+s.map(e=>e.toString(16).padStart(2,"0")).join("")}function vn(e,t,i,n,r,o,s,a=ln){const l=function(e,t,i,n,r,o,s,a=ln){if("custom"===e)return cn(a);if("lqi"===e){if(null==t)return null;const e=(t-40)/140;return{c:fn(s.lqi_low.c,s.lqi_high.c,e),a:s.lqi_low.a+(s.lqi_high.a-s.lqi_low.a)*Math.min(1,Math.max(0,e))}}if("light"===e)return"none"===i?s.light_none.a>0?s.light_none:null:"on"===i?s.light_on:s.light_off;if("temp"===e){if(null==n)return null;const e=Math.min(r,o),t=Math.max(r,o);return nt?s.temp_hot:s.temp_ok}return null}(e,t,i,n,r,o,s,a);return l?{color:l.c,opacity:l.a,mode:e}:null}const yn={blind:["mdi:blinds","mdi:blinds-open"],shade:["mdi:blinds","mdi:blinds-open"],shutter:["mdi:window-shutter","mdi:window-shutter-open"],curtain:["mdi:curtains-closed","mdi:curtains"],window:["mdi:window-closed","mdi:window-open"],awning:["mdi:awning-outline","mdi:awning"],door:["mdi:door-closed","mdi:door-open"],garage:["mdi:garage","mdi:garage-open"],gate:["mdi:gate","mdi:gate-open"],damper:["mdi:circle-slice-8","mdi:circle-outline"]},bn=[["mdi:roller-shade-closed","mdi:roller-shade"],["mdi:blinds-horizontal-closed","mdi:blinds-horizontal"],["mdi:garage-variant","mdi:garage-open-variant"],["mdi:door","mdi:door-open"]];function wn(e){for(const t of[...Object.values(yn),...bn])if(e===t[0]||e===t[1])return t;return null}function kn(e,t,i,n,r){if(!n||"unavailable"===n||"unknown"===n)return e;if(r){const i="cover"===t?wn(e):null;return i?"closed"===n?i[0]:i[1]:e}if("binary_sensor"===t){if("door"===i)return"on"===n?"mdi:door-open":"mdi:door-closed";if("window"===i)return"on"===n?"mdi:window-open":"mdi:window-closed";if("garage_door"===i)return"on"===n?"mdi:garage-open-variant":"mdi:garage-variant"}if("cover"===t){const t=yn[String(i||"")];if(t)return"closed"===n?t[0]:t[1];const r=wn(e);return r?"closed"===n?r[0]:r[1]:e}return"lock"===t?"locked"===n?"mdi:lock":"mdi:lock-open-variant":"light"===t&&"mdi:lightbulb"===e&&"on"===n?"mdi:lightbulb-on":e}function xn(e){const t=Math.min(4e4,Math.max(1e3,e))/100,i=t<=66?255:329.698727446*Math.pow(t-60,-.1332047592),n=t<=66?99.4708025861*Math.log(t)-161.1195681661:288.1221695283*Math.pow(t-60,-.0755148492),r=t>=66?255:t<=19?0:138.5177312231*Math.log(t-10)-305.0447927307,o=e=>Math.round(Math.min(255,Math.max(0,e)));return[o(i),o(n),o(r)]}const Sn=1/2.2;function $n(e){const t=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/.exec(e);return t?"#"+t.slice(1).map(e=>Math.min(255,Number(e)).toString(16).padStart(2,"0")).join(""):null}function Mn(e){if(!e||"object"!=typeof e||Array.isArray(e))return null;const t=e;if(Object.keys(t).some(e=>"c"!==e&&"bri"!==e))return null;const i=Kt(t.c,null);return i?void 0===t.bri||null===t.bri?{c:i}:"number"!=typeof t.bri||!Number.isFinite(t.bri)||t.bri<.01||t.bri>1?null:{c:i,bri:t.bri}:null}function Rn(e,t,i){const n=Mn(t),r=e?.attributes||{},o=n?.bri??function(e){const t=e?.attributes?.brightness,i="number"==typeof t?t:"string"==typeof t&&""!==t.trim()?Number(t):Number.NaN;return Number.isFinite(i)?Math.max(0,Math.min(1,i/255)):1}(e);if(n)return{c:n.c,bri:o};const s=Zt(r.rgb_color);if(s)return{c:$n(s)||Kt(i,"#ffd9a0"),bri:o};const a=Number(r.color_temp_kelvin)||(Number(r.color_temp)>0?1e6/Number(r.color_temp):NaN);return Number.isFinite(a)&&a>0?{c:(l=xn(a),"#"+l.slice(0,3).map(e=>Math.min(255,Math.max(0,Math.round(Number(e)||0))).toString(16).padStart(2,"0")).join("")),bri:o}:{c:Kt(i,"#ffd9a0"),bri:o};var l}function Cn(e,t,i){return"on"===e?.state?Rn(e,t,i):null}function Tn(e,t=1){const i=Math.max(0,Math.min(1,Number.isFinite(e)?e:1)),n=.7*Math.max(0,Math.min(1,Number.isFinite(t)?t:1))*(.4+.6*Math.pow(i,Sn));return Math.max(0,Math.min(1,n))}function Dn(e){return e.startsWith("light.")||e.startsWith("switch.")}function An(e,t,i=1e-6){const n=[];if(!e||!t||e.length<3||t.length<3)return n;for(let r=0;ru||l>u)continue;const p=(r[0]-o[0])*h+(r[1]-o[1])*d,_=(s[0]-o[0])*h+(s[1]-o[1])*d,m=Math.max(0,Math.min(p,_)),g=Math.min(c,Math.max(p,_));g-m>i&&n.push([o[0]+h*m,o[1]+d*m,o[0]+h*g,o[1]+d*g])}}return n}function Pn(e,t,i=1e-6){const n=[];for(const r of e){const e=[r[0],r[1]],o=[r[2],r[3]],s=o[0]-e[0],a=o[1]-e[1],l=Math.hypot(s,a);if(lo||r>o)continue;const s=(n[0]-e[0])*c+(n[1]-e[1])*h,a=(n[2]-e[0])*c+(n[3]-e[1])*h,u=Math.max(0,Math.min(s,a)),p=Math.min(l,Math.max(s,a));p-u>i&&d.push([u,p])}if(!d.length){n.push([e[0],e[1],o[0],o[1]]);continue}d.sort((e,t)=>e[0]-t[0]);let u=0;for(const[t,r]of d)t-u>i&&n.push([e[0]+c*u,e[1]+h*u,e[0]+c*t,e[1]+h*t]),u=Math.max(u,r);l-u>i&&n.push([e[0]+c*u,e[1]+h*u,o[0],o[1]])}return n}function Fn(e,t,i=1e-6){const n=[];for(let t=0;t{if("string"!=typeof e||!e)return;const i=En(e);i.startsWith("/api/houseplan/content/")&&t.add(i)};for(const t of e?.spaces||[]){i(t?.plan_url);for(const e of t?.markers||[])for(const t of e?.pdfs||[])i(t?.url)}for(const t of e?.markers||[])for(const e of t?.pdfs||[])i(e?.url);return t}function En(e){return e?e.startsWith("/houseplan_files/plans/")?"/api/houseplan/content/plans/_/"+e.slice(23):e.startsWith("/houseplan_files/files/")?"/api/houseplan/content/files/"+e.slice(23):e:""}function Nn(e,t){const i=t?.settings?.fill_mode;return"none"===i||"lqi"===i||"light"===i||"temp"===i||"custom"===i?i:e}function Hn(e,t){const i=t?.settings;return"boolean"==typeof i?.glow?i.glow:"glow"===i?.fill_mode||e}function Ln(e,t,i,n){if(!t||!i||t===i)return e;const r="/files/"+t+"/",o="/files/"+i+"/";return e.map(e=>{if(!e.url.includes(r))return e;const t=e.url.split(r)[1]||"",[i,s]=[t.split("?")[0],t.includes("?")?"?"+t.split("?")[1]:""];if(n){const t=n[decodeURIComponent(i)]??n[i];return t?{...e,url:e.url.split(r+i)[0]+o+encodeURIComponent(t)+s}:e}return{...e,url:e.url.split(r).join(o)}})}function Bn(e,t=1){const i=Number(e);return Number.isFinite(i)&&i>0?Math.min(3,Math.max(.5,i)):t}function qn(e,t,i){let n=null,r=null;for(const o of t){if(!(Math.abs(o[0]-e[0])<1e-6&&Math.abs(o[1]-e[1])<1e-6)){if(Math.abs(o[0]-e[0])<=i){const t=Math.abs(o[1]-e[1]);t>1e-6&&(!n||t1e-6&&(!r||t"number"==typeof e&&Number.isFinite(e),tr=(e,t,i)=>Math.min(i,Math.max(t,e));function ir(e){return e.elevation<=-6?"night":e.elevation>=6?"day":e.rising?"dawn":"dusk"}function nr(e){const t=(Math.floor(Number(e)||0)%1440+1440)%1440;return t>=300&&t<480?"dawn":t>=480&&t<1080?"day":t>=1080&&t<1260?"dusk":"night"}function rr(e){const t=ir(e),i=e.azimuth*Math.PI/180;return{sunX:50-42*Math.sin(i),sunY:78-tr(e.elevation,0,90)/90*64,sunOpacity:"night"===t?0:tr((e.elevation+6)/12,0,1)}}function or(e){const t=(Math.floor(Number(e)||0)%1440+1440)%1440;if(t<300||t>=1260)return{sunX:50,sunY:78,sunOpacity:0};const i=(t-300)/960,n=(t-300)/120,r=(1260-t)/120;return{sunX:8+84*i,sunY:78-64*Math.sin(i*Math.PI),sunOpacity:Math.max(.18,Math.min(n,r,1))}}function sr(e,t=new Date){const i=function(e){const t=e?.states?.["sun.sun"]?.attributes;return t&&er(t.azimuth)&&er(t.elevation)&&"boolean"==typeof t.rising?{azimuth:Zn(t.azimuth),elevation:t.elevation,rising:t.rising}:null}(e);if(i)return{phase:ir(i),source:"sun",...rr(i)};const n="number"==typeof t?t:function(e=new Date){return 60*e.getHours()+e.getMinutes()}(t);return{phase:nr(n),source:"clock",...or(n)}}function ar(e){return`${e.source}|${e.phase}|${e.sunX.toFixed(2)}|${e.sunY.toFixed(2)}|`+e.sunOpacity.toFixed(3)}const lr=[[-90,"#070c14"],[-12,"#070c14"],[-4,"#131a28"],[0,"#4a3527"],[10,"#e8ddcf"],[30,"#ffffff"],[90,"#ffffff"]],cr=e=>Math.min(1,Math.max(0,e));function hr(e,t,i=6){const n=e.angle*Math.PI/180,r=[Math.sin(n),-Math.cos(n)],o=n=>{const o=[e.x+r[0]*i*n,e.y+r[1]*i*n];return t.find(e=>e.poly.length>=3&&mi(o,e.poly))||null},s=o(1),a=o(-1);return s&&a?null:s||a?s?{normal:[-r[0],-r[1]],roomId:s.id}:{normal:r,roomId:a.id}:null}function dr(e,t,i){return i>0&&e[0]*t[0]+e[1]*t[1]>.05}function ur(e,t,i,n){return[[e[0],e[1]],[t[0],t[1]],[t[0]+i[0]*n,t[1]+i[1]*n],[e[0]+i[0]*n,e[1]+i[1]*n]]}function pr(e,t){try{const i=Ut([[...e.map(e=>[e[0],e[1]]),[e[0][0],e[0][1]]]],[[...t.map(e=>[e[0],e[1]]),[t[0][0],t[0][1]]]]),n=[];for(const e of i){const t=e?.[0];!Array.isArray(t)||t.length<4||n.push(t.slice(0,t.length-1).map(e=>[e[0],e[1]]))}return n}catch{return[]}}function _r(e,t,i,n,r,o,s){if(!(n>0))return[];const a=Jn(i,r),l=[-a[0],-a[1]],c=function(e){const t=Math.min(90,Math.max(0,e));return.7*(.8+1.7*Math.pow(1-t/90,1.6))}(n),h=[];for(const i of t){if(!(i.length>0))continue;const t=hr(i,e);if(!t||!dr(t.normal,a,n))continue;const r=e.find(e=>e.id===t.roomId);if(!r)continue;const d=o&&o[t.roomId]||r.poly,u=i.angle*Math.PI/180,p=i.length/2,_=[-t.normal[0],-t.normal[1]],m=Math.max(0,s?.[i.id]||0),g=i.x+_[0]*m/2,f=i.y+_[1]*m/2,v=Math.cos(u)*p,y=Math.sin(u)*p,b=[g-v,f-y],w=[g+v,f+y],k=c*i.length,x=pr(ur(b,w,l,k),d);if(!x.length)continue;const S=l[0]*_[0]+l[1]*_[1];h.push({openingId:i.id,roomId:t.roomId,polys:x,a:b,b:w,dir:l,len:k,normal:_,depth:k*S})}return h}const mr=e=>"number"==typeof e&&Number.isInteger(e)&&e>=0&&e<=359?e:null;function gr(e,t){const i=mr(t?.north_deg);return null!==i?i:mr(e?.north_deg)}function fr(e,t){const i=e=>"static"===e||"daynight"===e?e:null;return i(t?.bg_mode)??i(e?.bg_mode)??"static"}function vr(e,t){const i=t?.sun_rays;return"boolean"==typeof i?i:!0===e?.sun_rays}function yr(e){const t=e?.states?.["sun.sun"]?.attributes,i=Number(t?.azimuth),n=Number(t?.elevation);return Number.isFinite(i)&&Number.isFinite(n)?{azimuth:i,elevation:n}:null}const br=["dawn","day","dusk","night"];function wr(e){if(!e)return"";const t=Qn[e.phase];return[`--hp-day-cycle-outline-near:${t.outlineNear}`,`--hp-day-cycle-outline-mid:${t.outlineMid}`,`--hp-day-cycle-outline-far:${t.outlineFar}`].join(";")}function kr(e,t=1){if(!e)return G;const i=[`--hp-day-cycle-sun-x:${e.sunX.toFixed(2)}%`,`--hp-day-cycle-sun-y:${e.sunY.toFixed(2)}%`,`--hp-day-cycle-sun-opacity:${e.sunOpacity.toFixed(3)}`,`opacity:${Math.min(1,Math.max(0,t)).toFixed(4)}`].join(";");return j``:G} - `}}ug.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},ug.styles=[op,o`.hp-static-title{font-weight:700;padding:10px 14px 6px;font-size:16px;color:var(--primary-text-color);}.hp-static-body{position:relative;}.hp-static-stage{position:relative;width:100%;container-type:inline-size;overflow:hidden;pointer-events:none;background:var(--ha-card-background,var(--card-background-color,#111));}.hp-static-stage svg{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;}.hp-paper{fill:var(--ha-card-background,var(--card-background-color,#111));stroke:none;}.wallbody-fill{fill:var(--wall-fill,#ffffff);fill-opacity:var(--wall-fill-op,1);fill-rule:evenodd;stroke:none;pointer-events:none;}.wallbody{fill:url(#hp-wall-hatch);fill-rule:evenodd;stroke:var(--room-stroke,var(--hp-muted,#607d8b));stroke-width:calc(0.6px * var(--hp-cell-visual-scale,1));pointer-events:none;}.wallbody.solid{fill:none;}.hp-static-stage .devlayer{position:absolute;inset:0;z-index:2;}.hp-static-foot{padding:8px 12px 12px;pointer-events:auto;}.hp-static-btn{width:100%;padding:9px 14px;border:none;border-radius:10px;background:var(--primary-color,#3ea6ff);color:var(--text-primary-color,#fff);font-size:14px;font-weight:600;cursor:pointer;}:host([data-pointer-hover]) .hp-static-btn:hover{filter:brightness(1.08);}.hp-static-error{padding:24px;text-align:center;color:var(--secondary-text-color,#9aa4ad);}`],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",ug),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const pg=o`:host{--hp-editor-tray-bg-fallback:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 94%,var(--hp-line));--hp-editor-tray-bg:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 86%,transparent);--hp-editor-tray-border:color-mix(in srgb,var(--hp-line) 82%,var(--hp-accent));--hp-editor-tray-blur:8px;--hp-editor-tray-shadow:var(--shadow-2);}.editor-secondary-host{position:absolute;inset:var(--sp-2) var(--sp-4) auto;z-index:70;display:flex;justify-content:flex-end;pointer-events:none;}.editor-secondary-host.kind-palette,.editor-secondary-host.kind-group{justify-content:flex-start;}.editor-secondary{pointer-events:none;max-width:100%;display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);color:var(--hp-txt);background:var(--card-background-color,var(--hp-bg));background:var(--hp-editor-tray-bg-fallback);border:1px solid var(--hp-line);border-color:var(--hp-editor-tray-border);border-radius:var(--rad-l);box-shadow:var(--hp-editor-tray-shadow);opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity 0.1s ease,transform 0.1s cubic-bezier(0.2,0.7,0.2,1),visibility 0s linear 0.1s;touch-action:auto;}.editor-secondary-host.open .editor-secondary{pointer-events:auto;opacity:1;visibility:visible;transform:translateY(0);transition-duration:0.14s,0.14s,0s;transition-delay:0s;}.editor-secondary-host.blocked .editor-secondary{pointer-events:none;}@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.editor-secondary{background:var(--hp-editor-tray-bg);-webkit-backdrop-filter:blur(var(--hp-editor-tray-blur));backdrop-filter:blur(var(--hp-editor-tray-blur));}}.editor-secondary-content,.editor-group-items{display:flex;align-items:center;gap:var(--sp-3);min-width:0;}.editor-context-label{max-width:14rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-inline-end:var(--sp-4);border-inline-end:1px solid var(--hp-line);color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary.kind-palette{width:min(760px,100%);align-items:stretch;padding:0;overflow:hidden;}.editor-secondary.kind-palette .editor-secondary-content,.editor-secondary.kind-palette .furnpalette{width:100%;}.editor-secondary.kind-palette .furnpalette{max-height:38vh;border:0;background:transparent;}.editor-group-launcher .group-chevron{--mdc-icon-size:16px;transition:transform 0.14s ease;}.editor-group-launcher[aria-expanded="true"] .group-chevron{transform:rotate(180deg);}.editor-secondary .bdhint{font-size:var(--fs-s);color:var(--hp-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.editor-secondary .dfill{display:inline-flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-s);cursor:pointer;}.editor-secondary .dfill input[type="checkbox"]{width:16px;height:16px;flex:none;margin:0;padding:0;}.editor-secondary hp-color-opacity{flex:0 0 auto;}.editor-secondary input{width:74px;background:transparent;border:1px solid var(--hp-line);color:var(--hp-txt);border-radius:var(--rad-s);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-m);}.editor-secondary label,.editor-secondary .hint{color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary .drawwall{display:inline-flex;align-items:center;gap:var(--sp-3);white-space:nowrap;}.editor-secondary .drawwall input{width:4.2em;}.editor-secondary .drawwall .opl{color:var(--hp-muted);font-size:var(--fs-s);}@container (min-width:560px) and (max-width:899px){.editor-secondary-content,.editor-group-items{flex-wrap:wrap;justify-content:flex-end;}}@container (max-width:559px){.editor-secondary-host{inset-inline:var(--sp-4);}.editor-secondary{max-width:100%;}.editor-secondary-content,.editor-group-items{overflow-x:auto;scrollbar-width:thin;}.editor-secondary-content>*,.editor-group-items>*{flex:none;}.editor-context-label{display:none;}}@media (prefers-reduced-motion:reduce){.editor-secondary{transition:none;}.editor-group-launcher .group-chevron{transition:none;}}`;class _g{constructor(e=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(e))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(e){this._undo.push(e),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const e=this._undo.pop()??null;return e&&this._redo.push(e),e}redo(){const e=this._redo.pop()??null;return e&&this._undo.push(e),e}removeWhere(e){const t=this._undo.length,i=this._redo.length;return this._undo=this._undo.filter(t=>!e(t)),this._redo=this._redo.filter(t=>!e(t)),t+i-this._undo.length-this._redo.length}clear(){this._undo=[],this._redo=[]}}function mg(e,t){const i=e[t];return i&&Number.isFinite(i.x)&&Number.isFinite(i.y)?{x:i.x,y:i.y,..."string"==typeof i.s?{s:i.s}:{}}:null}function gg(e,t,i){if(null===i){if(!(t in e))return e;const i={...e};return delete i[t],i}const n={...e[t]||{}};delete n.x,delete n.y,delete n.s;const r={...n,x:i.x,y:i.y,...void 0!==i.s?{s:i.s}:{}};return{...e,[t]:r}}const fg="houseplan-card:version-reload-target:v1";function vg(e){if("string"!=typeof e)return null;return e.trim()||null}class yg{constructor(e){this.hooks=e,this._input={frontendVersion:null,backendVersion:null,kiosk:!1,reducedMotion:!1},this._relation={kind:"unknown"},this._banner=null,this._connected=!1,this._attemptTarget=null,this._attemptState=null,this._noticeToken=0}get relation(){return this._relation}get banner(){return this._banner}get hasCurrentMismatchNotice(){return"mismatch"===this._relation.kind&&"visible"===this._banner?.phase}connect(){this._connected||(this._connected=!0,this._attemptTarget=null,this._attemptState=null,this._reconcile())}disconnect(){(this._connected||this._banner)&&(this._connected=!1,this._cancelTimer(),this._banner&&(this._banner=null,this.hooks.changed()))}update(e){const t={frontendVersion:vg(e.frontendVersion),backendVersion:vg(e.backendVersion),kiosk:!0===e.kiosk,reducedMotion:!0===e.reducedMotion},i=function(e,t){const i=vg(e),n=vg(t);return i&&n?i===n?{kind:"equal",frontend:i,backend:n}:{kind:"mismatch",frontend:i,backend:n}:{kind:"unknown"}}(t.frontendVersion,t.backendVersion),n=!((e,t)=>e.frontendVersion===t.frontendVersion&&e.backendVersion===t.backendVersion&&e.kiosk===t.kiosk&&e.reducedMotion===t.reducedMotion)(this._input,t)||!((e,t)=>e.kind===t.kind&&("unknown"===e.kind||"unknown"!==t.kind&&e.frontend===t.frontend&&e.backend===t.backend))(this._relation,i);this._input=t,this._relation=i,n&&this._reconcile()}finishBannerExit(e){this._banner&&"leaving"===this._banner.phase&&this._banner.token===e&&(this._banner=null,this.hooks.changed())}_reconcile(){if(this._cancelTimer(),!this._connected||"mismatch"!==this._relation.kind)return this._attemptTarget=null,this._attemptState=null,void this._hideBanner();if(!this._input.kiosk)return this._attemptTarget=null,this._attemptState=null,void this._showBanner(this._relation.frontend,this._relation.backend);const e=this._relation.backend;if(this._attemptTarget===e&&null!==this._attemptState||(this._attemptTarget=e,this._attemptState=function(e,t){try{const i=e();return i?i.getItem(fg)===t?"attempted":"fresh":"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e)),"fresh"===this._attemptState)return this._hideBanner(),void this._armTimer();this._showBanner(this._relation.frontend,e)}_armTimer(){this._connected&&void 0===this._timer&&"mismatch"===this._relation.kind&&this._input.kiosk&&"fresh"===this._attemptState&&(this._timer=this.hooks.clock.setTimeout(()=>{this._timer=void 0,this._tick()},250))}_cancelTimer(){void 0!==this._timer&&(this.hooks.clock.clearTimeout(this._timer),this._timer=void 0)}_tick(){if(!this._connected||"mismatch"!==this._relation.kind||!this._input.kiosk||"fresh"!==this._attemptState)return;if(!function(e){return e.connected&&e.initialFrameSettled&&e.viewOnly&&e.surfacesIdle&&e.configWritesIdle&&e.physicalWritesIdle&&e.layoutWritesIdle&&e.gesturesIdle&&e.interactionPauseElapsed&&e.baseZoom}(this.hooks.safety()))return void this._armTimer();const e=this._relation.backend,t=function(e,t){try{const i=e();return i?i.getItem(fg)===t?"attempted":(i.setItem(fg,t),"claimed"):"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e);if(this._attemptTarget=e,this._attemptState="claimed"===t?"attempted":t,"claimed"===t){this._showBanner(this._relation.frontend,e);try{this.hooks.reload()}catch{}}else this._showBanner(this._relation.frontend,e)}_showBanner(e,t){"visible"===this._banner?.phase&&this._banner.frontend===e&&this._banner.backend===t||(this._banner={frontend:e,backend:t,phase:"visible",token:++this._noticeToken},this.hooks.changed())}_hideBanner(){if(this._banner)return this._input.reducedMotion?(this._banner=null,void this.hooks.changed()):void("leaving"!==this._banner.phase&&(this._banner={...this._banner,phase:"leaving",token:++this._noticeToken},this.hooks.changed()))}}const bg=1;function wg(e,t){const i=t&&"object"==typeof t?t:{};e._haIntegrationVersion=vg(i.integration_version);const n=i.support_api;e._haSupportApi="number"==typeof n&&Number.isSafeInteger(n)?n:null,e._haDecorAssetsApi=1===i.decor_assets_api?1:null,e._haSummaryPanelApi=1===i.summary_panel_api?1:null,e._haRadarStage1Api=1===i.radar_stage1_api?1:null,e._syncVersionRecovery()}function kg(e){const t=e._stageEl,i=e._loadOk&&!e._loading&&e._continuityDataReady&&!e._resumeSettling&&!e._connectionWasLost&&!e._booting&&!e._bootFading&&!e._bootSettling&&!e._bootSoft&&e._continuity.hasCompleteFrame&&"steady"===e._continuity.state&&!e._continuity.overlayBlocksInteraction&&!!t&&t.clientWidth>0&&t.clientHeight>0,n=!(0!==e._pointers.size||0!==e._touchContacts.size||e._touchSequenceMultitouch||e._roomPointer||e._panStart||e._panLock||e._pinchStart||e._swipeStart||e._tabDrag||e._tabDragRelease||e._drag||e._deviceDrag||e._rlResize||e._resize?.dragging||e._physicalDrag||e._physicalRotate||e._opDrag||e._decorDraft||e._decorMove||e._dtDrag||e._bdDrag||e._furnTouchPending||e._compassDrag||e._viewportGestureDirty||e._devicePositionBusy||e._modeTransitionBusy||e._cameraTransition.active||e._slide||0!==e._warmModeRequest),r=!(e._editorSecondaryDialogBlocked||e._partitionDeleteDialog||e._roomDeleteDialog||e._backdropGuard||e._vacFit||e._editorSecondary?.hasOpenGroup||e._furnPalette||e._decorImagePalette);return{connected:e.isConnected,initialFrameSettled:i,viewOnly:!0===e._config?.kiosk&&"view"===e._mode&&!e._editing,surfacesIdle:r,configWritesIdle:0===e._writesPending&&!e._saveConfigDebounced.pending(),physicalWritesIdle:0===e._pendingPhysicalWrites.size,layoutWritesIdle:!e._persistLayout.pending()&&0===e._dirtyPos.size&&0===e._sentPos.size&&!e._devicePositionBusy,gesturesIdle:n,interactionPauseElapsed:Date.now()>=e._cyclePausedUntil,baseZoom:e._zoom<=1.001}}class xg{constructor(){this.seen=null,this.diagnosticsCache=null}observe(e,t,i,n){this.invalidateDiagnosticsForHass(e,t,i),this.intake(t,n)}intake(e,t){e&&this.seen!==e&&(this.seen=e,t())}invalidate(){this.diagnosticsCache=null}invalidateDiagnosticsForHass(e,t,i){this.diagnosticsCache&&(e?.entities!==t?.entities||e?.devices!==t?.devices||[...i?.entityIds||[]].some(i=>!!e?.states?.[i]!=!!t?.states?.[i]))&&this.invalidate()}diagnostics(e,t,i){if(this.diagnosticsCache)return this.diagnosticsCache;const n={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of t)e.removed||"virtual"===e.binding||n[i(e.binding).kind]++;return this.diagnosticsCache={registry:hd(e),bindings:n},this.diagnosticsCache}}function Sg(e){const t=e;t._hassSequence++,t._renderSnapshotAt=Date.now(),t._continuity.note("hass-snapshot"),t._ensureHaRegistryAuthority(),t._planHassMemo=null,t._hookConnection(),!t._loadOk&&!t._loading&&t._loadTries<8&&t._loadFromServer(),t._maybeRebuildDevices(),t._vacTick(),t._activityTick()}function $g(e){return!!e&&"object"==typeof e&&1===e.version}function Mg(e,t){const i=e.radar;return e.space===t&&!0!==e.hidden&&!0!==e.removed&&$g(i)&&!0===i.enabled&&!1!==i.show_live}const Rg={ok:"radar.health_ok",off:"radar.health_off",stale:"radar.health_stale",partial:"radar.health_partial",restricted:"radar.health_restricted",incomplete:"radar.health_incomplete",position_unavailable:"radar.health_position_unavailable",unavailable:"radar.health_unavailable",needs_setup:"radar.health_needs_setup",inconsistent:"radar.health_inconsistent",unknown:"radar.health_unknown"};const Cg=e=>"number"==typeof e&&Number.isFinite(e);class Tg{constructor(e){this.host=e,this.frames=new Map,this.connection=null,this.space="",this.generation=0,this.expiryTimer=0,this.deadlines=new Map}sync(e,t){const i=this.host.hass?.connection;if(!t||!i||!this.host.isConnected)return void this.stop();if(this.unsubscribe&&this.connection===i&&this.space===e)return;this.stop(),this.connection=i,this.space=e;const n=++this.generation,r=i.subscribeMessage?.bind(i);"function"==typeof r&&Promise.resolve(r(e=>{if(n!==this.generation||!this.host.isConnected)return;const t=function(e){if(!e||"object"!=typeof e)return null;const t=e;if("string"!=typeof t.marker_id||"string"!=typeof t.server_session_id||!Number.isSafeInteger(t.seq)||"string"!=typeof t.health)return null;const i=Array.isArray(t.targets)?t.targets.slice(0,256).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;return"string"==typeof t.slot&&Cg(t.x)&&Cg(t.y)&&Cg(t.expires_at)&&Cg(t.reported_at)&&("bounded_latest"===t.pair_quality||"coherent"===t.pair_quality)?[{...t,included:!0===t.included,smooth:!0===t.smooth}]:[]}):[],n=Array.isArray(t.ranges)?t.ranges.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if(!("string"==typeof t.id&&Cg(t.x)&&Cg(t.y)&&Cg(t.radius)&&Cg(t.expires_at)&&Cg(t.reported_at)))return[];const i=Array.isArray(t.segments)?t.segments.slice(0,64).flatMap(e=>{if(!Array.isArray(e))return[];const t=e.slice(0,181).flatMap(e=>Array.isArray(e)&&2===e.length&&Cg(e[0])&&Cg(e[1])?[[e[0],e[1]]]:[]);return t.length>=2?[t]:[]}):void 0;return[{...t,...i?{segments:i}:{}}]}):[],r=Array.isArray(t.zones)?t.zones.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if("string"!=typeof t.id)return[];const i=t.state;if(null!==i&&"boolean"!=typeof i&&!Cg(i))return[];const n=Array.isArray(t.polygon)?t.polygon.slice(0,64).flatMap(e=>Array.isArray(e)&&2===e.length&&Cg(e[0])&&Cg(e[1])?[[e[0],e[1]]]:[]):[];return[{id:t.id,state:i,...n.length>=3?{polygon:n}:{}}]}):[];return{server_session_id:t.server_session_id,marker_id:t.marker_id,source_generation:"string"==typeof t.source_generation?t.source_generation:void 0,calibration_revision:"string"==typeof t.calibration_revision?t.calibration_revision:void 0,seq:t.seq,reported_at:Cg(t.reported_at)?t.reported_at:void 0,expires_at:Cg(t.expires_at)?t.expires_at:void 0,health:t.health,reported_presence:"boolean"==typeof t.reported_presence?t.reported_presence:null,complete:!0===t.complete,targets:i,ranges:n,zones:r}}(e);if(!t)return;if(!function(e,t){return!e||t.server_session_id!==e.server_session_id||t.source_generation!==e.source_generation||t.calibration_revision!==e.calibration_revision||t.seq>e.seq}(this.frames.get(t.marker_id),t))return;const i=function(e,t=Date.now()){if(!Cg(e.expires_at))return null;if(!Cg(e.reported_at))return Math.max(0,1e3*e.expires_at-t);const i=Math.max(0,1e3*(e.expires_at-e.reported_at)),n=Math.max(0,t-1e3*e.reported_at);return Math.max(0,i-n)}(t);"restricted"===t.health||"disabled"===t.health||0===i?(this.frames.delete(t.marker_id),this.deadlines.delete(t.marker_id)):(this.frames.set(t.marker_id,t),null==i?this.deadlines.delete(t.marker_id):this.deadlines.set(t.marker_id,this.monotonicNow()+i)),this.armExpiry(),this.host.requestUpdate()},{type:"houseplan/radar/subscribe",space_id:e})).then(e=>{n===this.generation&&this.host.isConnected?"function"==typeof e&&(this.unsubscribe=e):"function"==typeof e&&e()}).catch(()=>{n===this.generation&&this.stop()})}stop(){this.generation++,this.unsubscribe?.(),this.unsubscribe=void 0,this.connection=null,this.space="",clearTimeout(this.expiryTimer),this.expiryTimer=0,this.frames.size&&(this.frames.clear(),this.host.isConnected&&this.host.requestUpdate()),this.deadlines.clear()}armExpiry(){clearTimeout(this.expiryTimer);const e=this.monotonicNow(),t=[...this.deadlines.values()].filter(t=>t>e);if(!t.length)return;const i=Math.max(20,Math.min(...t)-e+10);this.expiryTimer=window.setTimeout(()=>{this.expiryTimer=0;let e=!1;const t=this.monotonicNow();for(const[i,n]of this.deadlines)n>t||(this.deadlines.delete(i),this.frames.delete(i),e=!0);this.armExpiry(),e&&this.host.isConnected&&this.host.requestUpdate()},i)}monotonicNow(){return globalThis.performance?.now?.()??Date.now()}}const Dg=Object.freeze({enabled:!1,z2mBaseTopics:Object.freeze([])});function Ag(e){if("string"!=typeof e)return null;const t=e.trim().replace(/^\/+|\/+$/g,"").replace(/\/{2,}/g,"/");return!t||t.length>180||/[#+\u0000-\u001f\u007f]/.test(t)?null:t}function Pg(e){const t=e?.zigbee_topology;if(!t||"object"!=typeof t)return Dg;const i=t,n=Array.isArray(i.z2m_base_topics)?i.z2m_base_topics:Array.isArray(i.z2mBaseTopics)?i.z2mBaseTopics:[],r=new Set,o=[];for(const e of n){const t=Ag(e);if(t&&!r.has(t)&&(r.add(t),o.push(t),8===o.length))break}return{enabled:!0===i.enabled,z2mBaseTopics:o}}function Fg(e,t){const i={...e},n=t.z2mBaseTopics.map(Ag).filter(Boolean);return t.enabled||n.length?i.zigbee_topology={enabled:!0===t.enabled,z2m_base_topics:[...new Set(n)].slice(0,8)}:delete i.zigbee_topology,i}const zg={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Ig=e=>Math.max(0,Math.min(1,e)),Og=(e,t,i)=>e+(t-e)*i,Eg=(e,t,i)=>{const n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},Ng=e=>{const t=Ig(e);if(0===t||1===t)return t;let i=0,n=1,r=t;for(let e=0;e<12;e++)r=(i+n)/2,Eg(r,.2,.2)0&&e.w>0?t/e.w:1,viewBox:{...e}}}function Lg(e,t,i){const n=Math.max(1e-9,e.pixelsPerUnit),r=Math.max(1e-9,t/n),o=Math.max(1e-9,i/n);return{x:e.centerX-r/2,y:e.centerY-o/2,w:r,h:o}}function Bg(e){const t=e.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(t);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const n=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t)?.[1];return n?[parseInt(n.slice(0,2),16),parseInt(n.slice(2,4),16),parseInt(n.slice(4,6),16),8===n.length?parseInt(n.slice(6,8),16)/255:1]:null}function qg(e,t,i){const n=Bg(e),r=Bg(t);if(!n||!r)return i<.5?e:t;const o=Ig(i);return`rgba(${Math.round(Og(n[0],r[0],o))}, ${Math.round(Og(n[1],r[1],o))}, ${Math.round(Og(n[2],r[2],o))}, ${Og(n[3],r[3],o).toFixed(3)})`}class jg{constructor(e,t=zg){this._hooks=e,this._clock=t,this._token=0,this._raf=0,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase||"preparing"===this._state?.phase}get presented(){return this._state?.presented||null}start(e,t,i,n=220){this.cancel(!1);const r=++this._token,o=this._clock.now();if(this._state={token:r,phase:n<=0?"settling":"running",from:e,to:t,presented:n<=0?t:e,startedAt:o,duration:Math.max(0,n),targetMode:i},n<=0)return this._hooks.frame(this._state),this._hooks.settled(this._state),this._state=null,r;this._hooks.frame(this._state);const s=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Ig((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:function(e,t,i){const n=Ng(i),r=Og(e.stageWidth,t.stageWidth,n),o=Og(e.stageHeight,t.stageHeight,n),s=Math.max(1e-9,e.viewport.pixelsPerUnit),a=Math.max(1e-9,t.viewport.pixelsPerUnit),l={centerX:Og(e.viewport.centerX,t.viewport.centerX,n),centerY:Og(e.viewport.centerY,t.viewport.centerY,n),pixelsPerUnit:Math.exp(Og(Math.log(s),Math.log(a),n))};return{presentedMode:n<.5?e.presentedMode:t.presentedMode,editorChromeHeight:Og(e.editorChromeHeight,t.editorChromeHeight,n),stageWidth:r,stageHeight:o,viewport:{...l,viewBox:Lg(l,r,o)},stageColor:qg(e.stageColor,t.stageColor,n),paperColor:qg(e.paperColor,t.paperColor,n),sceneBrightness:Og(e.sceneBrightness,t.sceneBrightness,n),architectureOpacity:Og(e.architectureOpacity,t.architectureOpacity,n),backdropOpacity:Og(e.backdropOpacity,t.backdropOpacity,n),viewWeight:Og(e.viewWeight,t.viewWeight,n),editorWeight:Og(e.editorWeight,t.editorWeight,n),toolbarContentOpacity:Og(e.toolbarContentOpacity,t.toolbarContentOpacity,n)}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i<1?this._raf=this._clock.requestFrame(s):(this._raf=0,this._hooks.settled(t),this._state?.token===r&&(this._state=null))};return this._raf=this._clock.requestFrame(s),r}cancel(e=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=t.to,this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}}const Wg={now:()=>"undefined"!=typeof performance?performance.now():Date.now(),requestFrame:e=>"function"==typeof requestAnimationFrame?requestAnimationFrame(e):null,cancelFrame:e=>{"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e)}},Ug=e=>Number.isFinite(e);function Gg(e){return!!e&&Ug(e.zoom)&&e.zoom>0&&Ug(e.viewBox.x)&&Ug(e.viewBox.y)&&Ug(e.viewBox.w)&&e.viewBox.w>0&&Ug(e.viewBox.h)&&e.viewBox.h>0}function Vg(e){return{zoom:e.zoom,viewBox:{...e.viewBox}}}function Kg(e,t){return Math.abs(e.zoom-t.zoom)<1e-9&&Math.abs(e.viewBox.x-t.viewBox.x)<1e-6&&Math.abs(e.viewBox.y-t.viewBox.y)<1e-6&&Math.abs(e.viewBox.w-t.viewBox.w)<1e-6&&Math.abs(e.viewBox.h-t.viewBox.h)<1e-6}const Yg=(e,t,i)=>e+(t-e)*i,Xg=(e,t,i)=>Math.exp(Yg(Math.log(e),Math.log(t),i));class Zg{constructor(e,t=Wg){this._hooks=e,this._clock=t,this._token=0,this._raf=null,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase}get presented(){return this._state?.presented||null}get target(){return this._state?.to||null}start(e,t,i,n){this.cancel(!1);const r=++this._token,o=Vg(e),s=Vg(t),a=n>0&&Gg(o)&&Gg(s),l=this._clock.now(),c={token:r,phase:a?"running":"settling",from:o,to:s,presented:Vg(a?o:s),startedAt:l,duration:a?n:0,reason:i};if(this._state=c,this._hooks.frame(c),!a)return this._settle(r),r;const h=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Math.max(0,Math.min(1,(e-t.startedAt)/t.duration));if(t.presented=i>=1?Vg(t.to):function(e,t,i){if(!Gg(e))return Vg(t);if(!Gg(t))return Vg(e);const n=Ng(i);if(n<=0)return Vg(e);if(n>=1)return Vg(t);const r=e.viewBox.x+e.viewBox.w/2,o=e.viewBox.y+e.viewBox.h/2,s=t.viewBox.x+t.viewBox.w/2,a=t.viewBox.y+t.viewBox.h/2,l=Xg(e.viewBox.w,t.viewBox.w,n),c=Xg(e.viewBox.h,t.viewBox.h,n),h=Yg(r,s,n),d=Yg(o,a,n);return{zoom:Xg(e.zoom,t.zoom,n),viewBox:{x:h-l/2,y:d-c/2,w:l,h:c}}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i>=1)return this._raf=null,void this._settle(r);this._raf=this._clock.requestFrame(h),null===this._raf&&this._settle(r)};return this._raf=this._clock.requestFrame(h),null===this._raf&&(c.phase="settling",c.presented=Vg(s),this._hooks.frame(c),this._settle(r)),r}cancel(e=!0){null!==this._raf&&this._clock.cancelFrame(this._raf),this._raf=null;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=Vg(t.to),this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}_settle(e){const t=this._state;t&&t.token===e&&(t.phase="settling",t.presented=Vg(t.to),this._hooks.settled(t),this._state?.token===e&&(this._state=null))}}function Jg(e,t,i){const n=e.querySelector("ha-card");if(!n)return null;const r=n.getBoundingClientRect(),o=t.getBoundingClientRect().top-r.top,s=i?0:Math.min(Math.max(r.top,0),120),a=Math.round(o+s);return a>=0?a:null}const Qg=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])}),ef=84,tf=10,nf=4,rf=4;function of(e){return[e.rotDeg,e.tiltDeg,e.xyScale,e.zScale,e.origin[0],e.origin[1]].every(Number.isFinite)&&Math.abs(e.xyScale)>1e-12&&Math.abs(Math.cos(e.tiltDeg*Math.PI/180))>1e-12}function sf(e,t,i=Qg){if(!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");return function(e,t){if(!Number.isFinite(e[0])||!Number.isFinite(e[1])||!t.every(Number.isFinite))throw new Error("invalid isometric affine input");const[i,n,r,o,s,a]=t;return[i*e[0]+r*e[1]+s,n*e[0]+o*e[1]+a]}(e,lf(t,i))}function af(e,t=Qg){if(!of(t)||!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=(e[0]-t.origin[0])/t.xyScale,o=(e[1]-t.origin[1])/(t.xyScale*Math.cos(n));return[t.origin[0]+r*Math.cos(i)+o*Math.sin(i),t.origin[1]-r*Math.sin(i)+o*Math.cos(i)]}function lf(e=0,t=Qg){if(!of(t)||!Number.isFinite(e))throw new Error("invalid isometric camera");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=t.xyScale*Math.cos(i),o=-t.xyScale*Math.sin(i),s=t.xyScale*Math.sin(i)*Math.cos(n),a=t.xyScale*Math.cos(i)*Math.cos(n);return[r,s,o,a,t.origin[0]-r*t.origin[0]-o*t.origin[1],t.origin[1]-s*t.origin[0]-a*t.origin[1]-e*t.zScale*Math.sin(n)]}function cf(e=Qg){return function(e=0,t=Qg){return`matrix(${lf(e,t).map(e=>Number(e.toFixed(12))).join(" ")})`}(0,e)}function hf(e,t=Qg){const{rect:i,wallHeight:n}=e,r=e.openingHeight??n,o=e.floorDepth??0,s=e.raisedHeight??n;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o)||!Number.isFinite(s)||n<0||r<0||o<0||s<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],l=Math.max(n,r,s),c=a.flatMap(e=>[sf(e,-o,t),sf(e,l,t)]),h=c.map(e=>e[0]),d=c.map(e=>e[1]),u=Math.min(...h),p=Math.min(...d);return{x:u,y:p,w:Math.max(...h)-u,h:Math.max(...d)-p}}const df=[".dev",".vacpuck",".oplock",".op-hit",".opening",".rlgo","a","button","input","select","textarea",'[contenteditable]:not([contenteditable="false"])',"[data-room-fit-block]",'[role="link"]','[role="button"]'].join(","),uf=(e,t)=>{try{return"function"==typeof e?.matches&&e.matches(t)}catch{return!1}};function pf(e){for(const t of e){const e=t;if(uf(e,".roomlabel[data-id]")){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(uf(e,df))return{kind:"interactive"};if(uf(e,'[data-hp="room"][data-id]')){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(uf(e,".stage"))return{kind:"background"}}return{kind:"outside"}}function _f(e){const t=pf(e);return"room"===t.kind?t.roomId:null}class mf{constructor(){this.pointer=null,this.sequence=null}clear(){this.pointer=null,this.sequence=null}clearOutside(e){let t={kind:"outside"};try{t=pf(e.composedPath())}catch{}"outside"===t.kind&&this.clear()}pointerDown(e,t,i){let n={kind:"outside"};try{n=pf(e.composedPath())}catch{}this.pointer=function(e){const t="mouse"===(i=e.pointerType)||"touch"===i||"pen"===i?i:null;var i;return t&&"view"===e.mode&&"background"===e.owner.kind&&!e.blocked&&e.isPrimary&&0===e.button&&Number.isFinite(e.x)&&Number.isFinite(e.y)?{pointerId:e.pointerId,spaceId:e.spaceId,modality:t,x:e.x,y:e.y}:null}({pointerId:e.pointerId,pointerType:e.pointerType,isPrimary:e.isPrimary,button:e.button,spaceId:t,mode:i?"view":"blocked",owner:n,blocked:!i,x:e.clientX,y:e.clientY}),this.pointer||(this.sequence=null)}pointerUp(e,t,i,n,r=Date.now()){let o={kind:"outside"};try{o=pf(e.composedPath())}catch{}const s=function(e,t,i){if(!t||"view"!==i.mode||"background"!==i.owner.kind||i.blocked||t.pointerId!==i.pointerId||t.spaceId!==i.spaceId||!Number.isFinite(i.x)||!Number.isFinite(i.y)||!Number.isFinite(i.now)||Math.abs(i.x-t.x)+Math.abs(i.y-t.y)>=8)return{sequence:null,trigger:!1};const n=e?i.now-e.at:Number.POSITIVE_INFINITY;return e&&e.spaceId===i.spaceId&&e.modality===t.modality&&n>=0&&n<=350?{sequence:null,trigger:!0}:{sequence:{at:i.now,spaceId:i.spaceId,modality:t.modality},trigger:!1}}(this.sequence,this.pointer,{pointerId:e.pointerId,spaceId:t,mode:i?"view":"blocked",owner:o,blocked:n||!i,x:e.clientX,y:e.clientY,now:r});return this.pointer=null,this.sequence=s.sequence,s.trigger}}const gf=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function ff(e){return!!e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&e.w>0&&Number.isFinite(e.h)&&e.h>0}function vf(e,t=0){if(!e.length||!Number.isFinite(t)||t<0||!e.every(gf))return null;let i=1/0,n=1/0,r=-1/0,o=-1/0;for(const t of e)i=Math.min(i,t[0]),n=Math.min(n,t[1]),r=Math.max(r,t[0]),o=Math.max(o,t[1]);const s=r-i,a=o-n;return s>0&&a>0?{x:i-t,y:n-t,w:s+2*t,h:a+2*t}:null}function yf(e,t,i){const n="string"!=typeof t||"invalid"!==t&&"no-borders"!==t&&"unverified"!==t&&!/^[a-z0-9]{1,8}$/i.test(t)?"redacted":t;return Object.freeze({kind:e,fingerprint:n,terminal:!!i})}function bf(e,t){return`${e("editor.load_failed")} ${e(t.terminal?"editor.refresh_advice":"editor.retry_advice")}`}class wf extends Error{}class kf{constructor(e){this.options=e,this._state="idle",this._inFlight=null}get state(){return this._state}ensure(){return"ready"===this._state?Promise.resolve(!0):"failed"===this._state?Promise.resolve(!1):(this._inFlight||(this._setState("loading"),this._inFlight=this._loadWithRetry().finally(()=>{this._inFlight=null})),this._inFlight)}async _loadWithRetry(){let e=new Error("Editor runtime did not load"),t=!1;for(const i of[0,1])try{const e=await this.options.load(i);if(e.fingerprint!==this.options.expectedFingerprint)throw new wf(`Editor runtime fingerprint mismatch: expected ${this.options.expectedFingerprint}, got ${e.fingerprint}`);const t=e.create();return this.options.install(t),this._setState("ready"),!0}catch(i){e=i,i instanceof wf&&(t=!0)}return this._setState(t?"failed":"idle"),this.options.failed?.(e,{terminal:t}),!1}_setState(e){e!==this._state&&(this._state=e,this.options.stateChanged?.(e))}}const xf=(e,t)=>{if(!e.has(t))return{hit:!1};const i=e.get(t);return e.delete(t),e.set(t,i),{hit:!0,value:i}},Sf=(e,t,i,n)=>{for(e.delete(t),e.set(t,i);e.size>n;){const t=e.keys().next().value;if(void 0===t)break;e.delete(t)}},$f=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Mf=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`,Rf="houseplan_card_alpha_v1",Cf=Object.freeze([Object.freeze({id:"iso",issue:89,summary:"Volumetric plan renderer"})]);function Tf(e){return/^[a-z][a-z0-9-]*$/.test(e.id)&&Number.isInteger(e.issue)&&e.issue>0&&!!e.summary.trim()}function Df(e){const t=String(e||"").replace(/^#/,"");return new URLSearchParams(t)}function Af(e){return Df(e).get("space")||""}function Pf(e,t,i=Cf){const n=function(e){const t=new Set;for(const i of e){if(!Tf(i)||t.has(i.id))return!1;t.add(i.id)}return!0}(i),r=function(e){let t,i=!1;const n=e=>{for(const n of e.getAll("hp_alpha"))i=!0,"1"===n?t=!0:"0"===n&&(t=!1)};return n(new URLSearchParams(String(e.search||"").replace(/^\?/,""))),n(Df(e.hash)),{present:i,value:t}}(e),o=void 0!==r.value,s="1"===t,a=o?!0===r.value:!r.present&&s,l=n&&a;return{alpha:l,active:Object.freeze(l?i.map(e=>e.id).sort():[]),space:Af(e.hash),persist:n&&o?l?"1":"0":void 0,knownUrlOperation:o}}let Ff={alpha:!1,active:Object.freeze([]),space:""},zf=!1,If="";const Of=new Set;function Ef(){if("undefined"==typeof window)return Ff;const e=Pf(window.location,function(){try{return window.localStorage.getItem(Rf)}catch{return null}}());void 0!==e.persist&&function(e){try{window.localStorage.setItem(Rf,e)}catch{}}(e.persist),Ff={alpha:e.alpha,active:e.active,space:e.space},window.__hpAlpha=e.alpha,window.__hpLabs=e.active;for(const e of Of)e(Ff);return Ff}function Nf(){Ef()}function Hf(){if("undefined"==typeof window)return Ff;if(!zf){zf=!0,window.__hpLabsListenerCleanup?.(),window.addEventListener("hashchange",Nf),window.addEventListener("popstate",Nf);const e=()=>{window.removeEventListener("hashchange",Nf),window.removeEventListener("popstate",Nf),window.__hpLabsListenerCleanup===e&&delete window.__hpLabsListenerCleanup};window.__hpLabsListenerCleanup=e}return Ef()}const Lf={window:120,door:90,passage:90,gate:300};function Bf(e){return Lf[e]}function qf(e,t){return{type:e,lengthCm:Bf(e),flipH:!1,flipV:!1,revision:t}}function jf(e,t){const i=Math.max(0,e.renderedLength)/2,n=Math.max(0,e.target.physicalHalfWidth),r=n+.18*Math.max(0,t),o=e=>({x1:e,y1:-r,x2:e,y2:r});return{rect:{x:-i,y:n?-n:0,width:2*i,height:2*n},boundaries:[o(-i),o(i)]}}function Wf(e,t){const i=[e[0],e[1]],n=[t[0],t[1]];return function(e,t){return e[0]-t[0]||e[1]-t[1]}(i,n)<=0?{a:i,b:n}:{a:n,b:i}}function Uf(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const n=Wf(e.a,e.b);if(Math.hypot(n.b[0]-n.a[0],n.b[1]-n.a[1])<=1e-9)return;const r=function(e,t){const i=e=>(Math.abs(e)<=5e-10?0:Math.round(1e6*e)/1e6).toFixed(6);return`${i(e[0])},${i(e[1])}>${i(t[0])},${i(t[1])}`}(n.a,n.b),o=t.get(r);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,e.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(e.partitionHost&&(o.partitionHost&&o.partitionHost.id!==e.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=e.partitionHost));t.set(r,{segmentKey:r,a:n.a,b:n.b,physicalHalfWidth:Math.max(0,e.half||0),sourceOrder:i,...e.partitionHost?{partitionHost:e.partitionHost}:{}})}),[...t.values()]}function Gf(e,t){if(Math.abs(e.distance-t.distance)>1e-9)return e.distance-t.distance;if(Math.abs(e.perpendicular-t.perpendicular)>1e-9)return e.perpendicular-t.perpendicular;return(e.target.segmentKeyt.target.segmentKey?1:0)||e.target.sourceOrder-t.target.sourceOrder}function Vf(e){const t=Uf(e.intervals).map(t=>{const i=function(e,t){const i=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,a=(e[0]-t.a[0])*o+(e[1]-t.a[1])*s,l=Math.max(0,Math.min(r,a)),c=t.a[0]+l*o,h=t.a[1]+l*s;return{along:l,length:r,x:c,y:h,distance:Math.hypot(e[0]-c,e[1]-h),perpendicular:Math.abs((e[0]-t.a[0])*s-(e[1]-t.a[1])*o)}}(e.pointer,t);return{target:t,...i,envelope:Math.max(e.baseTolerance,t.physicalHalfWidth+e.bodyPointerPadding)}}).filter(e=>e.distance<=e.envelope+1e-9).filter(t=>!function(e,t,i,n,r){const o=t.b[0]-t.a[0],s=t.b[1]-t.a[1],a=Math.hypot(o,s);if(!(a>1e-9))return!1;const l=o/a,c=s/a;for(const o of i){if(!o.open&&o.kind)continue;const i=Wf(o.a,o.b),s=i.b[0]-i.a[0],a=i.b[1]-i.a[1],h=Math.hypot(s,a);if(!(h>1e-9))continue;const d=s/h,u=a/h;if(Math.abs(l*u-c*d)>1e-6)continue;if(Math.abs((i.a[0]-t.a[0])*c-(i.a[1]-t.a[1])*l)>r)continue;const p=(e[0]-i.a[0])*d+(e[1]-i.a[1])*u,_=1e-9;if(!(p<=_||p>=h-_)&&Math.abs((e[0]-i.a[0])*u-(e[1]-i.a[1])*d)<=n+1e-9)return!0}return!1}(e.pointer,t.target,e.intervals,t.envelope,Math.max(1e-9,Math.min(e.baseTolerance,.04*e.gridStep)))),i=t.filter(t=>!!t.target.partitionHost&&e.renderedLength+2*t.target.physicalHalfWidth>t.length+1e-9).sort(Gf),n=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(Gf);let r=n[0];if(!r)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=n.filter(e=>Math.abs(e.distance-r.distance)<=1e-9&&Math.abs(e.perpendicular-r.perpendicular)<=1e-9),s=o.filter(e=>e.target.partitionHost);if(s.length){if(1!==new Set(s.map(e=>e.target.partitionHost.id)).size||s.some(e=>e.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const e=s[0],t=e.target.b[0]-e.target.a[0],i=e.target.b[1]-e.target.a[1],n=Math.hypot(t,i),a=t/n,l=i/n;if(!o.every(t=>{const i=t.target.b[0]-t.target.a[0],n=t.target.b[1]-t.target.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,c=Math.abs(a*s-l*o)<=1e-6,h=Math.abs((t.target.a[0]-e.target.a[0])*l-(t.target.a[1]-e.target.a[1])*a);return c&&h<=1e-9}))return{candidate:null,jambBlockedTarget:null};r=e}if(r.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:a,length:l}=r,c=a.b[0]-a.a[0],h=a.b[1]-a.a[1],d=c/l,u=h/l,p=a.partitionHost?a.physicalHalfWidth:0,_=Math.min(Math.max(0,e.renderedLength)/2+p,l/2);let m=r.along;const g=Math.max(e.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=a.a[0]+d*m,y=a.a[1]+u*m,b=Math.max(0,e.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),S=Math.max(0,l-k),$=[a.a[0]+d*(w-x/2),a.a[1]+u*(w-x/2)],M=[a.a[0]+d*(k+S/2),a.a[1]+u*(k+S/2)];let R=180*Math.atan2(h,c)/Math.PI;R>=90?R-=180:R<-90&&(R+=180);const C=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:e.preset.revision,geometryRevision:e.geometryRevision,pointer:[e.pointer[0],e.pointer[1]],type:e.preset.type,lengthCm:e.preset.lengthCm,flipH:e.preset.flipH,flipV:e.preset.flipV,x:v,y:y,angle:R,renderedLength:e.renderedLength,target:a,...a.partitionHost?{host:{...a.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:$},{distance:S,midpoint:M}],guide:C?{x:v,y:y,angle:R}:null}},jambBlockedTarget:null}}function Kf(e,t,i,n,r=1e-6){return e.presetRevision===i&&e.geometryRevision===n&&Math.hypot(e.pointer[0]-t[0],e.pointer[1]-t[1])<=r}function Yf(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}class Xf{constructor(e,t,i){this.loader=e,this.host=t,this.adopted=i,this.attachment=null}connect(){if(this.runtime)return void this.runtime.connect();this.attachment?.cancel();const e=this.loader.attach(this.host,e=>this.adopt(e));this.runtime||(this.attachment=e)}disconnect(){this.attachment?.cancel(),this.attachment=null,this.runtime?.disconnect()}adopt(e){this.attachment=null,this.runtime||(this.runtime=e,this.adopted(e))}}const Zf=new class{constructor(e){this.load=e,this.factory=null,this.pending=null}get warm(){return null!==this.factory}create(e){return this.factory?this.factory(e):null}attach(e,t){let i=!0;const n={cancel:()=>{i=!1}},r=this.create(e);return r?(t(r),n):(this.ensure().then(n=>{i&&t(n(e))},()=>{}),n)}ensure(){return this.factory?Promise.resolve(this.factory):(this.pending||(this.pending=this.load().then(e=>(this.factory=e,this.pending=null,e),e=>{throw this.pending=null,e})),this.pending)}reset(){this.factory=null,this.pending=null}}(()=>import("./summary-panel-runtime-loaded-BcKBuVQ7.js").then(function(e){return e.e}).then(({LoadedSummaryPanelRuntime:e})=>t=>new e(t)));function Jf(e){const t=globalThis.__HP_VERSION_OVERRIDE__;return"string"==typeof t&&t.length>0?t:e}let Qf=0;const ev="1.76.0-beta.3",tv="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e",iv=1500,nv=new Map;let rv=0,ov=1e4;const sv="houseplan_card_layout_v1",av="houseplan_card_cfg_v1",lv="houseplan_card_zoom_v1",cv="houseplan_card_nav_v1",hv="houseplan_card_view_v1",dv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",uv=1e3,pv=(e,t)=>{const i=Math.min(e.x,t.x),n=Math.min(e.y,t.y);return{x:i,y:n,w:Math.max(e.x+e.w,t.x+t.w)-i,h:Math.max(e.y+e.h,t.y+t.h)-n}},_v=(e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)},mv=e=>{history.pushState(null,"",e),_v(window,"location-changed",{replace:!1})},gv=(e,t)=>{let i,n=null;const r=(...r)=>{clearTimeout(i),n=r,i=window.setTimeout(()=>{i=void 0;const t=n;n=null,t&&e(...t)},t)};return r.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const t=n;n=null,t&&e(...t)},r.cancel=()=>{clearTimeout(i),i=void 0,n=null},r.pending=()=>void 0!==i,r},fv=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}},vv=["edges","corners"];class yv extends he{constructor(){var e;super(...arguments),this._editorRuntime=null,this._liveRt=null,this._onboardingRuntime=null,this._editorRuntimeLoadingVisible=!1,this._backdropGuard=null,this._editorModeRequest=0,this._warmModeRequest=0,this._editorRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./houseplan-editor-runtime-BNMtEwiN.js"):await import((()=>{const e=new URL("./houseplan-editor-runtime-BNMtEwiN.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.EDITOR_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanEditorRuntime(this)}},install:e=>{this._editorRuntime=e},stateChanged:e=>this._editorRuntimeStateChanged(e),failed:(e,t)=>{console.error("[houseplan] unable to load editor runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(bf(e=>this._t(e),t))}}),this._onboardingRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./houseplan-onboarding-runtime-D2XH4RQC.js"):await import((()=>{const e=new URL("./houseplan-onboarding-runtime-D2XH4RQC.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.ONBOARDING_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanOnboardingRuntime(this)}},install:e=>{this._onboardingRuntime=e},failed:(e,t)=>{console.error("[houseplan] unable to load onboarding runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(bf(e=>this._t(e),t))}}),this._isoSceneRuntime=null,this._isoSceneRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./iso-scene-render-ceJKJKhC.js"):await import((()=>{const e=new URL("./iso-scene-render-ceJKJKhC.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.ISO_SCENE_RUNTIME_FINGERPRINT,create:()=>t}},install:e=>{const t=this._effectiveProjection();this._isoSceneRuntime=e,this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i),this.isConnected&&this.requestUpdate()},failed:(e,t)=>{console.warn("[houseplan] hidden isometric runtime diagnostic",yf("runtime-load","unverified",t.terminal)),this.isConnected&&this.requestUpdate()}}),this._pdfRuntime=null,this._pdfRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./pdf-export-BAtsOfAV.js"):await import((()=>{const e=new URL("./pdf-export-BAtsOfAV.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.PDF_EXPORT_FINGERPRINT,create:()=>new t.PdfExportRuntime}},install:e=>{this._pdfRuntime=e,this.isConnected&&this.requestUpdate()},failed:(e,t)=>{if(console.error("[houseplan] unable to load PDF export runtime",e),!t.terminal||!this._versionRecovery.hasCurrentMismatchNotice){const e=bf(e=>this._t(e),t),i=this._t("editor.load_failed"),n=e.startsWith(i)?e.slice(i.length).trim():e;this._showToast(`${this._t("pdf.failed")} ${n}`.trim())}}}),this.panelHost=!1,this.narrow=null,this._space="f1",this._adoption=new Lu((e,t)=>this.requestUpdate(e,t)),this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._configReloadAuthority=new Wu,this._virtualLights=Eh(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._areaRelocationIds=new Set,this._areaSnapshotCleanupCandidates=new Map,this._areaRelocationSyncKey="",this._areaRelocationWrite=Promise.resolve(),this._tip=null,this._hoverRoom=null,this._pointerModality=new rg(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...xr},this._decorStyleSeeded=!1,this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._decorImagePalette=null,this._decorAssetCatalog=[],this._decorAssets=new Map,this._decorAssetBusy=!1,this._furnCategory=null,this._furnPreviewInput=null,this._furnTouchPending=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this._cancelDevicePressFeedback(),e.matches&&this._cancelCameraTransition(!0),e.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:e.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this._syncVersionRecovery(),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new jg({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._cameraTransitionFit=null,this._cameraTransition=new Zg({frame:e=>this._applyCameraTransitionFrame(e),settled:e=>this._settleCameraTransition(e)}),this._editorSecondaryCopy={groupActive:(e,t)=>this._t("editor.group_active",{group:e,item:t}),openGroup:e=>this._t("editor.open_group",{group:e}),disabledAction:(e,t)=>this._t("editor.disabled_action",{action:e,reason:t})},this._tool="draw",this._geometryHistory=new _g(50),this._devicePositionHistory=new _g(50),this._devicePositionBusy=!1,this._wallDialog=null,this._drawWallField=null,this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainRedo=[],this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._renderIsoScene=null,this._isoProjectionSnapshot=null,this._isoStructuralBuildCount=0,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowRuntimeState=vm(),this._glowRuntimeHost={window:()=>this.ownerDocument.defaultView||window,isConnected:()=>this.isConnected,requestUpdate:()=>this.requestUpdate(),reducedMotion:()=>this._reducedMotion},this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszLimitViolation=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempMin="",this._roomTempMax="",this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._roomFocus=null,this._roomPointer=null,this._doubleFit=new mf,this._deviceHits=new yc,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._viewportGestureDirty=!1,this._touchContacts=new Map,this._touchClickGuard=new dc,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:e=>this._guardTouchGesture(e)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._dangerConfirm=null,this._dangerConfirmController=new ze(e=>{this._dangerConfirm=e}),this._confirmDanger=e=>this._config&&this.hass?"warm"===this._syncDangerConfirmLocaleGate()||this._dangerConfirmMissingSpace()?Promise.resolve(!1):this._dangerConfirmController.confirm(e):Promise.resolve(!1),this._cancelDangerConfirm=()=>{this._dangerConfirmController.cancel()},this._onDangerConfirmDecision=e=>{this._dangerConfirmController.resolve(e.detail.token,e.detail.accepted)},this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._versionRecovery=(e=this,new yg({clock:{setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e)},storage:()=>e.ownerDocument.defaultView?.sessionStorage??null,safety:()=>kg(e),reload:()=>e._reloadDocument(),changed:()=>{e.requestUpdate()}})),this._haSupportApi=null,this._haDecorAssetsApi=null,this._haSummaryPanelApi=null,this._haRadarStage1Api=null,this._radarLive=new Tg(this),this._decorAssetSyncToken=0,this._alignDialog=null,this._settingsDialog=null,this._pdfDialog=!1,this._supportDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=e=>this._onKey(e),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++rv,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={alpha:!1,active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._summarySlot=new Xf(Zf,this,e=>{this._summary=e,this._capturedSnapshotSequence=-1,this.isConnected&&(e.connect(),this.hasUpdated&&this.requestUpdate())}),this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),this._summary?.visibility(e.kind),"hidden"===e.kind)return this._radarLive.stop(),this._editorRuntime?._cancelRadarSetup(),this._clearRoomFocus(!0),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._cancelCameraTransition(!0),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,this._syncRadarLive(),!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+Qm)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._onLabsSnapshot=e=>{const t=this._effectiveProjection();this._labs=e,this._isoProjectionSnapshot=null,this._labsIso&&this._ensureIsoSceneRuntime();const i=this._effectiveProjection();this._convertProjectionView(t,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const e=this._hashSpace();if(e&&this._model.find(t=>t.id===e)&&e!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._deviceDrag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._cfgEpochPreservedConfig=null,this._terminalFrame=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._renderLife=new xg,this._liveEditorPaintCount=0,this._onHaRegistryUpdate=()=>{const e=td(this.hass);e.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=e.revision,this._renderLife.invalidate(),this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,ed(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new hc(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=gv(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=vo(this._layout[t]);e&&(this._layout={...this._layout,[t]:e},this._sentPos.set(t,e),this.hass.callWS({type:"houseplan/layout/update",device_id:t,pos:e}).then(e=>this._noteLayoutRev(e)).catch(e=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))).finally(()=>{this._sentPos.get(t)===e&&this._sentPos.delete(t)}))}this._cacheSnapshot()}else this._persistLocalLayout()},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>this._editorRuntimeOrThrow()._undoGeometry(),this._redoGeometry=()=>this._editorRuntimeOrThrow()._redoGeometry(),this._saveConfigDebounced=gv(()=>{this._serverCfg&&this._writeConfig().catch(e=>{const t=!0===e?.physicalGeometryRolledBack;"geometry-unsafe"!==e?.code&&("wall_model_client_outdated"===e?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===e?.code?(this._showToast(this._t("toast.conflict")),t||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)})),t&&this._reloadRejectedPhysicalWrite())})},500),this._wallChainSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>this._editorRuntimeOrThrow()._savePhysicalDialog(),this._deletePhysicalSelection=()=>this._editorRuntimeOrThrow()._deletePhysicalSelection(),this._confirmPartitionDelete=()=>this._editorRuntimeOrThrow()._confirmPartitionDelete(),this._confirmRoomDelete=e=>this._editorRuntimeOrThrow()._confirmRoomDelete(e),this._rebindPartitionOpening=()=>this._editorRuntimeOrThrow()._rebindPartitionOpening(),this._keepClosedAsPartitions=()=>this._editorRuntimeOrThrow()._keepClosedAsPartitions(),this._toggleServerPlans=async()=>this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._toggleServerPlans():this._editorRuntimeOrThrow()._toggleServerPlans(),this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=ar(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(this._editorRuntime)return this._editorRuntime._openSettingsDialog();this._ensureEditorRuntime().then(e=>{e&&this._openSettingsDialog()})},this._openSupportDialog=()=>{this._editorRuntime?this._editorRuntime._openSupportDialog():this._ensureEditorRuntime().then(e=>{e&&this._openSupportDialog()})},this._openPdfDialog=()=>{this._pdfRuntimeLoader.ensure().then(e=>{e&&(this._pdfDialog=!0,this.requestUpdate())})},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._editorRuntimeOrThrow()._openAlignDialog(),this._toggleOptimizeLivePositions=()=>this._editorRuntimeOrThrow()._toggleOptimizeLivePositions(),this._optimizeUndoBusy=!1,this._openBackupExport=()=>this._editorRuntimeOrThrow()._openBackupExport(),this._openRulesDialog=()=>this._editorRuntimeOrThrow()._openRulesDialog(),this._climateCache=null,this._gearPtCache=new WeakMap}requestUpdate(e,t,i){if("hass"===e&&this.hass&&this._liveRt){const e=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;if(!this._liveRt.hass(t,this.hass,e?{entityIds:e.entityIds}:null,()=>Sg(this))&&!this._summary?.observeHassComposition())return}void 0!==e&&(this._terminalFrame=0),this._editorRuntime?._routeLiveEditorUpdate(e,t)||(this._liveRt?.clear(),super.requestUpdate(e,t,i))}_editorRuntimeOrThrow(){if(!this._editorRuntime)throw new Error("Houseplan editor runtime is not loaded");return this._editorRuntime}async _ensureEditorRuntime(){return this._editorRuntimeLoader.ensure()}async _ensureOnboardingRuntime(){return this._onboardingRuntimeLoader.ensure()}async _ensureIsoSceneRuntime(){return this._isoSceneRuntimeLoader.ensure()}_editorRuntimeStateChanged(e){clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,"loading"!==e?(this._editorRuntimeLoadingVisible=!1,this.requestUpdate()):this._editorRuntimeLoadingTimer=window.setTimeout(()=>{this._editorRuntimeLoadingVisible=!0,this.requestUpdate()},150)}async _requestMode(e,t=!0,i=!1){const n=++this._editorModeRequest;if(i&&(this._warmModeRequest=n,this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null),"view"===e||await this._ensureEditorRuntime()){if(n===this._editorModeRequest&&this.isConnected)return i?(this._adoptMode(e),this._warmRevivePending&&(clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmReviveDialog()),this.requestUpdate(),void this.updateComplete.then(()=>requestAnimationFrame(()=>requestAnimationFrame(()=>{if(this._warmModeRequest!==n||n!==this._editorModeRequest)return;const e=this._stageEl;this._lastValidStageSize=e&&e.clientWidth>0&&e.clientHeight>0?[e.clientWidth,e.clientHeight]:null,this._pendingRefitSize=null,this._warmModeRequest=0})))):void this._setMode(e,t);this._warmModeRequest===n&&(this._warmModeRequest=0)}else this._warmModeRequest===n&&(this._warmModeRequest=0)}get _layout(){return this._adoption.layout}set _layout(e){this._adoption.stageLocalLayout(e)}get _layoutRev(){return this._adoption.layoutRev}set _layoutRev(e){this._adoption.seedIdentity({layoutRev:e})}get _layoutContentFingerprint(){return this._adoption.layoutFingerprint}set _layoutContentFingerprint(e){this._adoption.seedIdentity({layoutFingerprint:e})}get _serverCfg(){return this._adoption.config}set _serverCfg(e){this._adoption.stageLocalConfig(e)}get _cfgRev(){return this._adoption.configRev}set _cfgRev(e){this._adoption.seedIdentity({configRev:e})}get _cfgContentFingerprint(){return this._adoption.configFingerprint}set _cfgContentFingerprint(e){this._adoption.seedIdentity({configFingerprint:e})}_seedDecorStyle(e){var t,i;if(t=Al,i=this,Cl(e,Nl)&&"pending"===t.state()&&(t.art("",i),t.ensure()),this._decorStyleSeeded||!e)return;this._decorStyleSeeded=!0;const n=e.settings?.decor_default_style;n&&(this._decorStyle=function(e,t){if(!e||"object"!=typeof e)return{...t};const i=e,n="string"==typeof i.color&&i.color?i.color:t.color,r="string"==typeof i.fill_color&&i.fill_color?i.fill_color:t.fillColor,o=Number(i.width_cm);return{color:n,opacity:Sr(i.opacity,t.opacity),widthCm:Number.isFinite(o)&&o>0?Math.max(.1,Math.min(100,o)):t.widthCm,fill:"boolean"==typeof i.fill?i.fill:t.fill,fillColor:r,fillOpacity:Sr(i.fill_opacity,t.fillOpacity)}}(n,xr))}get _canManageConfiguration(){return null!==this._serverCanWrite?this._serverCanWrite:!0===this.hass?.user?.is_admin}get _canEdit(){return this._norm&&this._canManageConfiguration}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}get _doubleFitEnabled(){return!("view"!==this._mode||this._vacFit||this._modeTransitionBusy||this._touchSequenceMultitouch||"steady"!==this._continuity.state||this._continuity.overlayBlocksInteraction)}_cameraState(){const e=this._viewOr(this._baseVb());return{zoom:this._zoom,viewBox:{...e}}}_normalizeCameraState(e){const t=this._cameraTransitionFit||Oi(this._baseVb(),this._stageAspect());return{zoom:Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,e.zoom)),viewBox:this._clampView({...e.viewBox},t)}}_applyCameraTransitionFrame(e){const t=this._normalizeCameraState(e.presented);e.presented=t,this._zoom=t.zoom,this._view={...t.viewBox},this._liveVp(!0)}_settleCameraTransition(e){const t=this._normalizeCameraState(e.to);this._zoom=t.zoom,this._view={...t.viewBox},this._cameraTransitionFit=null,"room"!==e.reason&&this._saveZoom(),this.requestUpdate()}_cancelCameraTransition(e=!1,t=!1){const i=this._cameraTransition.state?.reason,n=t&&this._cameraTransition.active?this._cameraTransition.presented?.zoom:void 0;this._cameraTransition.cancel(e),this._cameraTransitionFit=null,void 0!==n&&"room"!==i&&this._saveZoom()}_prepareCameraCommand(){this._bootSoftCancel(),this._modeTransitionBusy&&this._cancelModeTransition(!0),"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1))}_startCameraTransition(e,t,i,n){const r=this._cameraState(),o=this._cameraTransition.target;return(!o||!Kg(o,e))&&(Kg(r,e)?(this._cancelCameraTransition(!1),!1):(this._cameraTransitionFit={...t},this._cameraTransition.start(r,e,i,this._reducedMotion?0:n),!0))}_cssColor(e,t){const i=String(e||"").trim();if(!i)return t;const n=document.createElement("span");n.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(n);const r=getComputedStyle(n).color||t;return n.remove(),r}_currentModeVisual(e=this._mode){const t=this._modeTransition.presented||this._modeTransitionVisual;if(t)return{...t,viewport:{...t.viewport,viewBox:{...t.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const n=this.renderRoot.querySelector(".editorchrome"),r=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),s=this.renderRoot.querySelector(".hp-backdrop"),a=this.renderRoot.querySelector(".zoomwrap"),l=a?getComputedStyle(a).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:e,editorChromeHeight:"view"===e?0:n?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Hg(r,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===e?.35:1,backdropOpacity:s&&Number(getComputedStyle(s).opacity)||1,viewWeight:"view"===e?1:0,editorWeight:"view"===e?0:1,toolbarContentOpacity:"view"===e?0:1}}_viewForModeTarget(e,t,i,n,r){const o=Oi(this._baseVb(),n/r),s=Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,e)),a=o.w/s,l=o.h/s,c=t??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-a/2,y:h-l/2,w:a,h:l},o)}_targetStageColor(e){return"view"!==e?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(e){return"view"===e&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(e){return 1}_applyModeTransitionFrame(e){e.targetMode===this._mode&&(this._modeTransitionVisual=e.presented,this._view={...e.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(e){if(e.targetMode!==this._mode)return;const t=this._modeTransitionRequest;this._view={...e.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[e.to.stageWidth,e.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._modeTransitionBusy||e.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-e.to.stageWidth)>.5||Math.abs(i.clientHeight-e.to.stageHeight)>.5)){const e=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,e?e.x+e.w/2:void 0,e?e.y+e.h/2:void 0),this.requestUpdate()}const n=this.renderRoot.activeElement;(!n||!n.isConnected||!!n.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(e=!0){this._cancelCameraTransition(!1);const t=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(e),e&&t||(this._modeTransitionVisual=null)}_adoptMode(e){e!==this._mode&&(this._clearRoomFocus(!0),this._resetDeviceHitState()),this._cancelModeTransition(!1),this._mode=e,this._isoProjectionSnapshot=null,"view"!==e&&(this._editorChromeMode=e)}_commitViewModeAtomic(e,t,i,n){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=t,e){const r=this._stageEl?.clientWidth||e.stageWidth,o=Math.max(1,e.stageHeight+e.editorChromeHeight);this._view=this._viewForModeTarget(t,i,n,r,o),this._lastValidStageSize=[r,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(e,t,i,n,r,o){this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._mode!==i)return void(e===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const s=this.renderRoot.querySelector(".editorchrome-inner"),a="view"===i?0:s?.scrollHeight||0,l=Math.max(1,(this.panelHost?this.clientHeight:innerHeight)-Jg(this.renderRoot,this._stageEl,this.panelHost)),c=this._stageEl?.clientWidth||t.stageWidth,h=this._viewForModeTarget(n,r,o,c,l),d={presentedMode:i,editorChromeHeight:a,stageWidth:c,stageHeight:l,viewport:Hg(h,c),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const u=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,d,i,this._reducedMotion||u?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(e=this._model,t=this._loadOk){const i=this._config?.floor,n=function(e){if(!e.hasFloor)return{kind:"absent"};const t=e.floor;if("string"==typeof t)return t.length?e.spaceIds.includes(t)?{kind:"valid",id:t,source:"id"}:{kind:"invalid",reason:"unknown-id",value:t}:{kind:"invalid",reason:"empty-id",value:t};if("number"==typeof t){if(!Number.isFinite(t))return{kind:"invalid",reason:"non-finite-index",value:t};if(!Number.isInteger(t))return{kind:"invalid",reason:"fractional-index",value:t};if(t<0)return{kind:"invalid",reason:"negative-index",value:t};const i=e.spaceIds[t];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:t}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:t}}({spaceIds:e.map(e=>e.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||t?n:"number"==typeof i?"valid"===n.kind||"invalid"===n.kind&&"out-of-range-index"===n.reason?{kind:"pending",value:i}:n:"valid"===n.kind||"invalid"===n.kind&&"unknown-id"!==n.reason?n:{kind:"pending",value:i}}_canCommitSpace(e,t=!1){if(t||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===e}_commitSpace(e,t=!1){return!!this._canCommitSpace(e,t)&&(e!==this._space&&(this._clearRoomFocus(!0),this._resetDeviceHitState(),this._cancelDangerConfirm(),this._cancelCameraTransition(!1),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._editorRuntime?._clearFurniturePreview()),this._space=e,this._isoProjectionSnapshot=null,!0)}_slideTo(e,t){if(e===this._space)return!0;if(!this._canCommitSpace(e))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary?.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,this._restoreZoom(),i||(this._slide=t,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Yf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){Yf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(fv(e),this._tabDragRelease=e=>this._tabPointerUp(e),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:t,pointerId:e.pointerId,x:e.clientX,y:e.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(e,t,i){const n=this._model.map(e=>e.id),r=n.indexOf(i);if(r<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const s of o){const o=s.dataset.id||"";if(!o||o===i)continue;const a=s.getBoundingClientRect();if(ea.right||ta.bottom)continue;const l=n.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,n;const r=this._tabDropTargetAt(e.clientX,e.clientY,t.id);t.moved&&t.targetId===r?.targetId&&t.placement===r?.placement||(this._tabDrag={...t,moved:!0,targetId:r?.targetId||null,placement:r?.placement||null})}_tabPointerUp(e){const t=this._tabDrag;if(t&&t.pointerId!==e.pointerId)return;const i="pointerup"===e.type&&t?.moved?this._tabDropTargetAt(e.clientX,e.clientY,t.id):null;"pointerup"===e.type&&t?.moved&&this._suppressNextTabClick(),this._endTabDrag(),t?.moved&&i&&this._commitTabOrder(t.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(e){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(e)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(e,t){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const n=this._model.map(e=>e.id),r=function(e,t,i){const n=e.indexOf(t),r=e.indexOf(i);if(n<0||r<0||n===r)return e;const o=e.slice();return o.splice(n,1),o.splice(r,0,t),o}(n,e,t);if(r===n)return;const o=new Map(this._devices.map(e=>[String(e.id),String(e.area||"")])),s=function(e,t,i,n=()=>""){if(!i)return[];const r=[];for(const o of e){if(!o||!0===o.removed)continue;const e="string"==typeof o.id?o.id:"";if(!e)continue;if("string"==typeof o.space&&o.space)continue;const s=("string"==typeof o.area?o.area:"")||n(e)||"";s&&t[s]||r.push({id:e,space:i})}return r}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),n[0]||"",e=>o.get(e)||"");if(s.length){const e=new Map(s.map(e=>[e.id,e.space]));for(const t of i.markers||[]){const i=e.get(String(t.id));i&&(t.space=i)}}i.spaces=function(e,t){const i=new Map(t.map((e,t)=>[e,t]));return e.map((e,t)=>({space:e,index:t})).sort((e,t)=>(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)||e.index-t.index).map(e=>e.space)}(i.spaces||[],r),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(e){if(this._endTabDrag(),e===this._space)return;const t=this._model.map(e=>e.id),i=t.indexOf(this._space),n=t.indexOf(e);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(e,i>=0&&n0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const e=this._model.map(e=>e.id),t=e.indexOf(this._space);this._slideTo(e[(t+1)%e.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(e){this._wallUnionCacheValue=e,null===e&&this._wallUnionPool.clear()}get _glowClipCache(){return this._glowRuntimeState.clipCache}get _glowGeometryWarnings(){return this._glowRuntimeState.geometryWarnings}get _glowFeatherUnits(){return this._glowRuntimeState.featherUnits}set _glowFeatherUnits(e){this._glowRuntimeState.featherUnits=e}get _glowRenderedSources(){return this._glowRuntimeState.renderedSources}get _glowLastAppearance(){return this._glowRuntimeState.lastAppearance}get _glowFeatherSuspendUntil(){return this._glowRuntimeState.featherSuspendUntil}set _glowFeatherSuspendUntil(e){this._glowRuntimeState.featherSuspendUntil=e}get _glowFeatherResumeTimer(){return this._glowRuntimeState.featherResumeTimer}set _glowFeatherResumeTimer(e){this._glowRuntimeState.featherResumeTimer=e}get _glowSourceSeq(){return this._glowRuntimeState.sourceSeq}set _glowSourceSeq(e){this._glowRuntimeState.sourceSeq=e}get _touchSequenceMultitouch(){return this._touchClickGuard.sequenceMultitouch}_syncDangerConfirmLocaleGate(){return this._config&&this.hass?cp(this,_p,bp(this.hass,this._config.language)):"ready"}_dangerConfirmMissingSpace(){const e=this._model;if(!e.length)return!1;const t=this._fixedFloorState(e);return"pending"!==t.kind&&"invalid"!==t.kind&&!this._spaceModel()}_syncVersionRecovery(){this._versionRecovery.update({frontendVersion:Jf(ev),backendVersion:this._haIntegrationVersion,kiosk:!0===this._config?.kiosk,reducedMotion:this._reducedMotion})}_newContinuityController(){return new sc(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(hv,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(e){const t=this._view;if(!t)return null;const i=[t.x+t.w/2,t.y+t.h/2],n="iso"===e?af(i):i;return{x:n[0],y:n[1]}}_convertProjectionView(e,t){if(e===t)return;this._clearRoomFocus(!0);const i=this._logicalViewCenter(e);this._view=null;const n=i?"iso"===t?sf([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,n?.[0],n?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(e){if(!this._labsIso||"view"!==this._mode)return;const t=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:e},"iso"===e){this._ensureIsoSceneRuntime();const e=this._isoSceneKey();e&&this._isoFallback.delete(e),this._isoFallback.delete(`${this._space}|no-borders`),this._clearIsoInvalidFallback()}this._saveViewPreference(),this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i)}_hashSpace(){return Af(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,this._configReloadAuthority.observeContext(Uu(this)),window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const e=cg(this.ownerDocument);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=rc(this.ownerDocument,this._pageVisibility),this._languageFailureUnsub?.(),this._languageFailureUnsub=function(...e){return()=>{for(const t of e)t()}}((t=()=>{this._showToast(this._t("toast.locale_load_failed"))},pp.add(t),()=>pp.delete(t)),function(e){return Dl.add(e),()=>{Dl.delete(e)}}(()=>this._showToast(this._t("toast.furniture_art_load_failed")))),super.connectedCallback(),this._summarySlot.connect(),this._ensureLiveRuntime().catch(()=>this.requestUpdate()),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{let t=!1;for(const i of e){for(const e of i.addedNodes)this._syncPointerHoverSubtree(e);const e=e=>{if(e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e;return t.matches(".devlayer, .devlayer *")||!!t.querySelector?.(".devlayer")};(e(i.target)||[...i.addedNodes,...i.removedNodes].some(e))&&(t=!0)}t&&this._invalidateDeviceHitGeometry()}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","data-id"]})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._syncVersionRecovery(),this._versionRecovery.connect(),lg(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>this._referencedContentUrls()),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(e){Of.add(e);const t=Hf();return"undefined"==typeof window&&e(t),()=>{Of.delete(e)}}(this._onLabsSnapshot),this._labsIso&&this._ensureIsoSceneRuntime(),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},iv)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._versionRecovery.disconnect(),this._configReloadAuthority.invalidateLifecycle(),this._liveRt?.dispose(),this._radarLive.stop(),this._editorRuntime?._disposeLiveEditor(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._languageFailureUnsub?.(),this._languageFailureUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._warmModeRequest=0,this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._summarySlot.disconnect(),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const e of this._activityRt.values())clearTimeout(e.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,this._editorRuntimeLoadingVisible=!1,this._modeTransition.dispose(),this._cameraTransition.dispose(),this._cameraTransitionFit=null,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),this._cancelDeviceDrag(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer),Am(this._glowRuntimeState,this._glowRuntimeHost),this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._touchContacts.clear(),this._touchClickGuard.reset(),this._resetDeviceHitState(),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary?.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(e){if("Escape"===e.key&&this._vacFit){if(this._vacFit.busy)return;return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void e.stopPropagation()}if("Escape"===e.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm.busy||(this._vacCalConfirm=null));if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._pdfDialog)return void(this._pdfDialog=!1);if(this._supportDialog)return void this._editorRuntime?._closeSupportDialog();if(this._settingsDialog)return void(this._settingsDialog=null);if(this._summary?.closeDialogIfIdle())return;if(this._markerDialog)return void this._closeMarkerDialog();if(this._deviceInbox)return void(this._deviceInbox=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary?.hasOpenGroup)return e.preventDefault(),void this._editorSecondary?.closeGroup(!0)}const t=e.composedPath?.()||[e.target],i=t.some(e=>e?.matches?.('input, textarea, select, [contenteditable="true"]')),n=t.some(e=>e?.classList?.contains?.("editor-secondary")),r=e.ctrlKey||e.metaKey,o=e.key.toLowerCase(),s=/^[a-z]$/.test(o),a="z"===o||!s&&"KeyZ"===e.code,l="y"===o||!s&&"KeyY"===e.code,c=r&&(a&&e.shiftKey||l),h=r&&a&&!e.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry();if(("Delete"===e.key||"Backspace"===e.key)&&this._decorSel&&!i&&!n)return e.preventDefault(),void this._decorDeleteSel();const t="ArrowLeft"===e.key?[-this._gridPitch,0]:"ArrowRight"===e.key?[this._gridPitch,0]:"ArrowUp"===e.key?[0,-this._gridPitch]:"ArrowDown"===e.key?[0,this._gridPitch]:null;return!t||r||e.altKey||"select"!==this._decorTool||!this._decorSel||!this._decorList.some(e=>e.id===this._decorSel)||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag||i||n||this._editorSecondaryDialogBlocked?void("Escape"===e.key&&(e.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._furnPalette=null,this._furnCategory=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(e.preventDefault(),void this._decorNudge(t[0],t[1]))}if("devices"===this._mode){if((h||c)&&i)return;return c?(e.preventDefault(),void this._redoDevicePosition()):h?(e.preventDefault(),void this._undoDevicePosition()):void("Escape"===e.key&&this._deviceDrag&&(e.preventDefault(),this._cancelDeviceDrag()))}if(this._markup&&(!h&&!c||!i)){if(("Delete"===e.key||"Backspace"===e.key)&&this._physicalSel&&!i&&!n)return e.preventDefault(),void this._deletePhysicalSelection();if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===e.key)return this._physicalDrag||this._physicalRotate?(e.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(e.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(e.preventDefault(),void this._finishWallChain()):this._physicalSel?(e.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():("exit-tool"===this._resize?.escapeIdle()&&(this._tool="draw"),void this.requestUpdate())):"split"===this._tool?(e.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(e.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(e.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(e.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length)return this._contourClosed?(this._path=this._path.slice(0,-1),void(this._closingWallCm=null)):void(this._activeWallChainPartitionIds.length&&this._path.length>1?this._undoActiveWallPoint():this._path=this._path.slice(0,-1))}_undoActiveWallPoint(){const e=[...this._activeWallChainPartitionIds],t=e[e.length-1],i=this._spaceModel()?.partitions.find(e=>e.id===t),n=this._path[0]?[...this._path[0]]:null,r=this._path.slice(0,-1).map(e=>[...e]),o=this._wallChainSegmentCms.slice(0,-1),s=this._geometryHistory.undo();if(!s)return this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._wallChainRedo=[],void(this._path=n?[n]:[]);this._applyGeometryState(s.before,!0)?(this._activeWallChainId||=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=e.slice(0,-1),this._path=r.length?r:n?[n]:[],this._wallChainSegmentCms=o,i&&this._wallChainRedo.push({id:i.id,point:[...i.b],cm:i.cm}),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:s.name}))):this._geometryHistory.clear()}static async getConfigElement(){return await import("./editor-C5Zq-3aA.js"),document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of nv.values())for(const t of e)clearTimeout(t.evict);nv.clear(),ov=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const n of nv.values())for(const r of n)e++,r.dlg&&(t++,i.push(r.dlg.kind));return{keys:nv.size,slots:e,dlgs:t,drafts:i}}setConfig(e){const t=this._config,i=!!t&&Object.prototype.hasOwnProperty.call(t,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...e};(i!==this._hasFixedFloor||t?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&e.default_floor&&this._commitSpace(e.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(lv)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(hv)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}if(this._labs=Hf(),this.isConnected&&this._labsIso&&this._ensureIsoSceneRuntime(),!this._summary?.applyLocalScaleForCurrentIdentity())try{const e=JSON.parse(localStorage.getItem("houseplan_card_kiosk_v1")||"null");this._kioskScale={icon:Bn(e?.icon),font:Bn(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(av)||"null");this._adoption.restoreCached(e)&&(this._seedDecorStyle(this._serverCfg),this._cfgEpoch++,this._virtualLights=Eh(e.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1),this._syncVersionRecovery()}_warmAdopt(){if(this._config?.kiosk)return;const e=Mf(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),n=nv.get(e);if(!n||!n.length)return;const r=n.find(e=>e.owner===this._warmGen);if(r)return this._warmLongReturn=!!r.freed&&Date.now()-r.freed>=tc,clearTimeout(r.evict),r.evict=0,r.freed=0,r.live=!0,this._warmSlot=r,this._warmKey=e,r.frameFingerprint&&this._continuity.adoptCompleteFrame(r.frameFingerprint),void(!this._devices.length&&r.devices?.length&&(this._devices=[...r.devices]));const{slot:o,sure:s}=((e,t,i,n)=>{const r=e=>{const t=!!i&&e.place?.deref()===i;return t&&e.idx===n?4:e.live?0:t?3:2};let o=null,s=0,a=0,l=null;for(const i of e){if(i.owner===t)continue;l=i;const e=r(i);e<=0||(e>s?(o=i,s=e,a=1):e===s&&a++)}return!o||a>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(n,this._warmGen,t,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=tc,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},iv)),this._warmKey=e,s?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=t?new WeakRef(t):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},n.push(this._warmSlot),this._warmTrim(n)))}_warmIdx(e){const t=e?.children;if(!t)return-1;for(let e=0;e4;){const t=e.findIndex(e=>!e.live);if(t<0)break;clearTimeout(e[t].evict),e.splice(t,1)}}_warmScheduleEvict(e,t){if(clearTimeout(e.evict),!(e.dlg||e.vp&&"view"!==e.vp.mode))return;const i=e.freed,n=e.owner;e.evict=window.setTimeout(()=>{if(e.evict=0,e.freed!==i||e.owner!==n)return;var r;e.dlg=null,e.vp=(r=e.vp)&&"view"!==r.mode?{...r,mode:"view",zoom:r.snap?.space===r.space?r.snap.zoom:r.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:r,e.frameFingerprint="";const o=nv.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},ov+250)}_warmAdoptViewport(e){const t=this._warmVp;if(!t||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(e=>e.id===t.space)||"valid"===i.kind&&i.id!==t.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(t.space,!0),this._navApplied=!0;const n="view"!==t.mode&&this._canEdit&&!e.kiosk?t.mode:"view";this._adoptMode("view"),this._pendingNavMode="view"===t.mode||this._canEdit||e.kiosk?null:t.mode,this._zoom=t.zoom;const r=this._effectiveProjection(),o=r===t.projection&&this._labsIso===t.activeLabsIso;if(this._view=o&&t.view?{...t.view}:null,this._viewModeSnap=o&&t.snap?{...t.snap}:null,!o&&t.logicalCenter){const e="iso"===r?sf([t.logicalCenter.x,t.logicalCenter.y],0):[t.logicalCenter.x,t.logicalCenter.y];this._applyView(t.zoom,e[0],e[1])}var s;this._tool="opening"===(s=function(e){return"partition"===e?"draw":e}(s=t.tool))?"draw":"string"==typeof s&&$f.has(s)?s:"draw",this._decorTool=t.decorTool,this._showHidden=t.showHidden,this._showFar!==t.showFar&&(this._showFar=t.showFar,this._frame=null),this._selId=t.selId,this._resize?.restoreSelection(t.rszSel),this._decorSel=t.decorSel,this._warmVpArmed=!0,"view"!==n&&this._requestMode(n,!1,!0)}_warmPatch(e,t=!1){if(this._config?.kiosk)return;const i=Mf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!t)return;const e=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:this._warmIdx(e),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const n=nv.get(i)||[];for(n.push(this._warmSlot),nv.set(i,n),this._warmTrim(n);nv.size>8;){const e=nv.keys().next().value;if(void 0===e||e===i)break;for(const t of nv.get(e)||[])clearTimeout(t.evict);nv.delete(e)}}Object.assign(this._warmSlot,e)}}_warmViewportState(){const e=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:e,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(e),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._resize?.selectedRoomId,decorSel:this._decorSel}}_warmDialogState(){const e=(e,t)=>({kind:e,space:this._space,mode:this._mode,data:t});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?e("openingInfo",this._openingInfo.id):this._infoCard?e("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:e("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:e("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:e("marker",this._markerDialog):this._openingDialog?e("opening",this._openingDialog):this._backdropDialog?e("backdrop",this._backdropDialog):this._decorShapeDialog?e("decorShape",this._decorShapeDialog):this._decorTextDialog?e("decorText",this._decorTextDialog):this._roomDialog?e("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempMin:this._roomTempMin,tempMax:this._roomTempMax,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:e("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const e={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices,hdrH:this._hdrH};if(this._warmRevivePending||(e.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const t=this.parentNode;e.place=t?new WeakRef(t):null,e.idx=this._warmIdx(t)}this._warmPatch(e)}_warmReviveDialog(){const e=this._warmSlot;if(this._warmReviveTimer=void 0,!e||!e.dlg)return void(this._warmRevivePending=!1);const t=e.dlg,i=e.freed;if(t.mode===this._mode||"view"===t.mode||this._warmVp?.mode!==t.mode||this._editorRuntime){if(this._warmRevivePending=!1,e.dlg=null,e.freed=0,clearTimeout(e.evict),e.evict=0,i&&!(Date.now()-i>ov)&&t.space===this._space&&t.mode===this._mode){switch(t.kind){case"space":this._spaceDialog={...t.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...t.data,busy:!1};break;case"settings":this._settingsDialog={...t.data,busy:!1};break;case"rules":this._rulesDialog={...t.data,busy:!1};break;case"opening":this._openingDialog={...t.data};break;case"backdrop":this._backdropDialog={...t.data};break;case"decorShape":this._decorShapeDialog={...t.data};break;case"decorText":{this._decorTextDialog={...t.data};const e=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:e,end:e};break}case"room":{const e=t.data;this._roomEditId=e.editId,this._roomFill=e.fill,this._roomCustomFill=e.customFill||null,this._roomTempMin=e.tempMin||"",this._roomTempMax=e.tempMax||"",this._roomTempSrc=e.tempSrc,this._roomHumSrc=e.humSrc,this._roomSrcOpen=e.srcOpen,this._roomSrcFilter=e.srcFilter,this._roomNameScale=e.nameScale,this._roomLabelScale=e.labelScale,this._areaSel=e.areaSel,this._nameSel=e.nameSel,this._pendingSplit=e.pendingSplit,this._wallFaceBatch=e.wallFaceBatch||null,this._path=e.path,this._wallFaceBatch&&(this._activeWallChainId=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=[...this._wallFaceBatch.activePartitionIds],this._wallChainSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const e=this._devices.find(e=>e.id===t.data);e&&(this._infoCard=e);break}case"openingInfo":{const e=(this._curSpaceCfg?.openings||[]).find(e=>e.id===t.data);e&&(this._openingInfo=e);break}}this.requestUpdate()}}else this._warmRevivePending=!0}_cacheSnapshot(){if(this._serverCfg)try{this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const n=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(Lh).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>n.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev);const e=this._adoption.snapshot(function(e){return{rev:e.rev,config_rev:e.configRev,off:[...e.off].sort()}}(this._virtualLights));e&&localStorage.setItem(av,JSON.stringify(e))}catch{}}_beginContinuityCandidate(e,t,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(e,i))}_continuityStageValid(){const e=this._stageEl;return!!e&&e.clientWidth>0&&e.clientHeight>0}_versionReloadSafetySnapshot(){return kg(this)}_continuityAssetsReady(){if(!this._model.length)return!1;const e=this._model.length?this._spaceModel():null;return!e?.bg?.href||this._signer.isReady(this.hass,e.bg.href)}_initialSpaceSelection(e,t=this._loadOk){const i=this._fixedFloorState(e,t);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(e){const t=new Set(e.spaceIds.filter(e=>!!e));if(!t.size)return{id:null,source:"none"};const i=[["hash",!1===e.acceptHash?null:e.hashSpace],["current",e.preserveCurrent?e.currentSpace:null],["saved",e.savedSpace],["default",e.defaultSpace],["first",e.spaceIds[0]]];for(const[e,n]of i)if(n&&t.has(n))return{id:n,source:e};return{id:null,source:"none"}}({spaceIds:e.map(e=>e.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(e,t=this._loadOk){const i=this._initialSpaceSelection(e,t);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(e,t=this._space){const i=Ya(e),n=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==n.kind)return"";const r=this._initialSpaceSelection(i,!0).id||(i.some(e=>e.id===t)?t:i[0]?.id);return i.find(e=>e.id===r)?.bg?.href||""}_visualFrameFingerprint(){const e=this._stageEl,t=e?[e.clientWidth,e.clientHeight]:[0,0];return lc([this._cfgRev,this._adoption.currentConfigFingerprint(),this._layoutRev,this._adoption.currentLayoutFingerprint(),this._space,this._mode,this._view,t,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const e=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==e)return this._stagedDeviceSnapshotToken=e,void this.requestUpdate();this._continuityPaintToken!==e&&(this._continuityPaintToken=e,this._continuity.candidateReady(e)&&this._continuity.commitAfterPaint(e,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(e,t){this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const e="connection"===this._continuity.recoveryReason;return j`
"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const _g=o`:host{--hp-editor-tray-bg-fallback:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 94%,var(--hp-line));--hp-editor-tray-bg:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 86%,transparent);--hp-editor-tray-border:color-mix(in srgb,var(--hp-line) 82%,var(--hp-accent));--hp-editor-tray-blur:8px;--hp-editor-tray-shadow:var(--shadow-2);}.editor-secondary-host{position:absolute;inset:var(--sp-2) var(--sp-4) auto;z-index:70;display:flex;justify-content:flex-end;pointer-events:none;}.editor-secondary-host.kind-palette,.editor-secondary-host.kind-group{justify-content:flex-start;}.editor-secondary{pointer-events:none;max-width:100%;display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);color:var(--hp-txt);background:var(--card-background-color,var(--hp-bg));background:var(--hp-editor-tray-bg-fallback);border:1px solid var(--hp-line);border-color:var(--hp-editor-tray-border);border-radius:var(--rad-l);box-shadow:var(--hp-editor-tray-shadow);opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity 0.1s ease,transform 0.1s cubic-bezier(0.2,0.7,0.2,1),visibility 0s linear 0.1s;touch-action:auto;}.editor-secondary-host.open .editor-secondary{pointer-events:auto;opacity:1;visibility:visible;transform:translateY(0);transition-duration:0.14s,0.14s,0s;transition-delay:0s;}.editor-secondary-host.blocked .editor-secondary{pointer-events:none;}@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.editor-secondary{background:var(--hp-editor-tray-bg);-webkit-backdrop-filter:blur(var(--hp-editor-tray-blur));backdrop-filter:blur(var(--hp-editor-tray-blur));}}.editor-secondary-content,.editor-group-items{display:flex;align-items:center;gap:var(--sp-3);min-width:0;}.editor-context-label{max-width:14rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-inline-end:var(--sp-4);border-inline-end:1px solid var(--hp-line);color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary.kind-palette{width:min(760px,100%);align-items:stretch;padding:0;overflow:hidden;}.editor-secondary.kind-palette .editor-secondary-content,.editor-secondary.kind-palette .furnpalette{width:100%;}.editor-secondary.kind-palette .furnpalette{max-height:38vh;border:0;background:transparent;}.editor-group-launcher .group-chevron{--mdc-icon-size:16px;transition:transform 0.14s ease;}.editor-group-launcher[aria-expanded="true"] .group-chevron{transform:rotate(180deg);}.editor-secondary .bdhint{font-size:var(--fs-s);color:var(--hp-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.editor-secondary .dfill{display:inline-flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-s);cursor:pointer;}.editor-secondary .dfill input[type="checkbox"]{width:16px;height:16px;flex:none;margin:0;padding:0;}.editor-secondary hp-color-opacity{flex:0 0 auto;}.editor-secondary input{width:74px;background:transparent;border:1px solid var(--hp-line);color:var(--hp-txt);border-radius:var(--rad-s);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-m);}.editor-secondary label,.editor-secondary .hint{color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary .drawwall{display:inline-flex;align-items:center;gap:var(--sp-3);white-space:nowrap;}.editor-secondary .drawwall input{width:4.2em;}.editor-secondary .drawwall .opl{color:var(--hp-muted);font-size:var(--fs-s);}@container (min-width:560px) and (max-width:899px){.editor-secondary-content,.editor-group-items{flex-wrap:wrap;justify-content:flex-end;}}@container (max-width:559px){.editor-secondary-host{inset-inline:var(--sp-4);}.editor-secondary{max-width:100%;}.editor-secondary-content,.editor-group-items{overflow-x:auto;scrollbar-width:thin;}.editor-secondary-content>*,.editor-group-items>*{flex:none;}.editor-context-label{display:none;}}@media (prefers-reduced-motion:reduce){.editor-secondary{transition:none;}.editor-group-launcher .group-chevron{transition:none;}}`;class mg{constructor(e=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(e))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(e){this._undo.push(e),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const e=this._undo.pop()??null;return e&&this._redo.push(e),e}redo(){const e=this._redo.pop()??null;return e&&this._undo.push(e),e}removeWhere(e){const t=this._undo.length,i=this._redo.length;return this._undo=this._undo.filter(t=>!e(t)),this._redo=this._redo.filter(t=>!e(t)),t+i-this._undo.length-this._redo.length}clear(){this._undo=[],this._redo=[]}}function gg(e,t){const i=e[t];return i&&Number.isFinite(i.x)&&Number.isFinite(i.y)?{x:i.x,y:i.y,..."string"==typeof i.s?{s:i.s}:{}}:null}function fg(e,t,i){if(null===i){if(!(t in e))return e;const i={...e};return delete i[t],i}const n={...e[t]||{}};delete n.x,delete n.y,delete n.s;const r={...n,x:i.x,y:i.y,...void 0!==i.s?{s:i.s}:{}};return{...e,[t]:r}}const vg="houseplan-card:version-reload-target:v1";function yg(e){if("string"!=typeof e)return null;return e.trim()||null}class bg{constructor(e){this.hooks=e,this._input={frontendVersion:null,backendVersion:null,kiosk:!1,reducedMotion:!1},this._relation={kind:"unknown"},this._banner=null,this._connected=!1,this._attemptTarget=null,this._attemptState=null,this._noticeToken=0}get relation(){return this._relation}get banner(){return this._banner}get hasCurrentMismatchNotice(){return"mismatch"===this._relation.kind&&"visible"===this._banner?.phase}connect(){this._connected||(this._connected=!0,this._attemptTarget=null,this._attemptState=null,this._reconcile())}disconnect(){(this._connected||this._banner)&&(this._connected=!1,this._cancelTimer(),this._banner&&(this._banner=null,this.hooks.changed()))}update(e){const t={frontendVersion:yg(e.frontendVersion),backendVersion:yg(e.backendVersion),kiosk:!0===e.kiosk,reducedMotion:!0===e.reducedMotion},i=function(e,t){const i=yg(e),n=yg(t);return i&&n?i===n?{kind:"equal",frontend:i,backend:n}:{kind:"mismatch",frontend:i,backend:n}:{kind:"unknown"}}(t.frontendVersion,t.backendVersion),n=!((e,t)=>e.frontendVersion===t.frontendVersion&&e.backendVersion===t.backendVersion&&e.kiosk===t.kiosk&&e.reducedMotion===t.reducedMotion)(this._input,t)||!((e,t)=>e.kind===t.kind&&("unknown"===e.kind||"unknown"!==t.kind&&e.frontend===t.frontend&&e.backend===t.backend))(this._relation,i);this._input=t,this._relation=i,n&&this._reconcile()}finishBannerExit(e){this._banner&&"leaving"===this._banner.phase&&this._banner.token===e&&(this._banner=null,this.hooks.changed())}_reconcile(){if(this._cancelTimer(),!this._connected||"mismatch"!==this._relation.kind)return this._attemptTarget=null,this._attemptState=null,void this._hideBanner();if(!this._input.kiosk)return this._attemptTarget=null,this._attemptState=null,void this._showBanner(this._relation.frontend,this._relation.backend);const e=this._relation.backend;if(this._attemptTarget===e&&null!==this._attemptState||(this._attemptTarget=e,this._attemptState=function(e,t){try{const i=e();return i?i.getItem(vg)===t?"attempted":"fresh":"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e)),"fresh"===this._attemptState)return this._hideBanner(),void this._armTimer();this._showBanner(this._relation.frontend,e)}_armTimer(){this._connected&&void 0===this._timer&&"mismatch"===this._relation.kind&&this._input.kiosk&&"fresh"===this._attemptState&&(this._timer=this.hooks.clock.setTimeout(()=>{this._timer=void 0,this._tick()},250))}_cancelTimer(){void 0!==this._timer&&(this.hooks.clock.clearTimeout(this._timer),this._timer=void 0)}_tick(){if(!this._connected||"mismatch"!==this._relation.kind||!this._input.kiosk||"fresh"!==this._attemptState)return;if(!function(e){return e.connected&&e.initialFrameSettled&&e.viewOnly&&e.surfacesIdle&&e.configWritesIdle&&e.physicalWritesIdle&&e.layoutWritesIdle&&e.gesturesIdle&&e.interactionPauseElapsed&&e.baseZoom}(this.hooks.safety()))return void this._armTimer();const e=this._relation.backend,t=function(e,t){try{const i=e();return i?i.getItem(vg)===t?"attempted":(i.setItem(vg,t),"claimed"):"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e);if(this._attemptTarget=e,this._attemptState="claimed"===t?"attempted":t,"claimed"===t){this._showBanner(this._relation.frontend,e);try{this.hooks.reload()}catch{}}else this._showBanner(this._relation.frontend,e)}_showBanner(e,t){"visible"===this._banner?.phase&&this._banner.frontend===e&&this._banner.backend===t||(this._banner={frontend:e,backend:t,phase:"visible",token:++this._noticeToken},this.hooks.changed())}_hideBanner(){if(this._banner)return this._input.reducedMotion?(this._banner=null,void this.hooks.changed()):void("leaving"!==this._banner.phase&&(this._banner={...this._banner,phase:"leaving",token:++this._noticeToken},this.hooks.changed()))}}const wg=1;function kg(e,t){const i=t&&"object"==typeof t?t:{};e._haIntegrationVersion=yg(i.integration_version);const n=i.support_api;e._haSupportApi="number"==typeof n&&Number.isSafeInteger(n)?n:null,e._haDecorAssetsApi=1===i.decor_assets_api?1:null,e._haSummaryPanelApi=1===i.summary_panel_api?1:null,e._haRadarStage1Api=1===i.radar_stage1_api?1:null,e._syncVersionRecovery()}function xg(e){const t=e._stageEl,i=e._loadOk&&!e._loading&&e._continuityDataReady&&!e._resumeSettling&&!e._connectionWasLost&&!e._booting&&!e._bootFading&&!e._bootSettling&&!e._bootSoft&&e._continuity.hasCompleteFrame&&"steady"===e._continuity.state&&!e._continuity.overlayBlocksInteraction&&!!t&&t.clientWidth>0&&t.clientHeight>0,n=!(0!==e._pointers.size||0!==e._touchContacts.size||e._touchSequenceMultitouch||e._roomPointer||e._panStart||e._panLock||e._pinchStart||e._swipeStart||e._tabDrag||e._tabDragRelease||e._drag||e._deviceDrag||e._rlResize||e._resize?.dragging||e._physicalDrag||e._physicalRotate||e._opDrag||e._decorDraft||e._decorMove||e._dtDrag||e._bdDrag||e._furnTouchPending||e._compassDrag||e._viewportGestureDirty||e._devicePositionBusy||e._modeTransitionBusy||e._cameraTransition.active||e._slide||0!==e._warmModeRequest),r=!(e._editorSecondaryDialogBlocked||e._partitionDeleteDialog||e._roomDeleteDialog||e._backdropGuard||e._vacFit||e._editorSecondary?.hasOpenGroup||e._furnPalette||e._decorImagePalette);return{connected:e.isConnected,initialFrameSettled:i,viewOnly:!0===e._config?.kiosk&&"view"===e._mode&&!e._editing,surfacesIdle:r,configWritesIdle:0===e._writesPending&&!e._saveConfigDebounced.pending(),physicalWritesIdle:0===e._pendingPhysicalWrites.size,layoutWritesIdle:!e._persistLayout.pending()&&0===e._dirtyPos.size&&0===e._sentPos.size&&!e._devicePositionBusy,gesturesIdle:n,interactionPauseElapsed:Date.now()>=e._cyclePausedUntil,baseZoom:e._zoom<=1.001}}class Sg{constructor(){this.seen=null,this.diagnosticsCache=null}observe(e,t,i,n){this.invalidateDiagnosticsForHass(e,t,i),this.intake(t,n)}intake(e,t){e&&this.seen!==e&&(this.seen=e,t())}invalidate(){this.diagnosticsCache=null}invalidateDiagnosticsForHass(e,t,i){this.diagnosticsCache&&(e?.entities!==t?.entities||e?.devices!==t?.devices||[...i?.entityIds||[]].some(i=>!!e?.states?.[i]!=!!t?.states?.[i]))&&this.invalidate()}diagnostics(e,t,i){if(this.diagnosticsCache)return this.diagnosticsCache;const n={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of t)e.removed||"virtual"===e.binding||n[i(e.binding).kind]++;return this.diagnosticsCache={registry:dd(e),bindings:n},this.diagnosticsCache}}function $g(e){const t=e;t._hassSequence++,t._renderSnapshotAt=Date.now(),t._continuity.note("hass-snapshot"),t._ensureHaRegistryAuthority(),t._planHassMemo=null,t._hookConnection(),!t._loadOk&&!t._loading&&t._loadTries<8&&t._loadFromServer(),t._maybeRebuildDevices(),t._vacTick(),t._activityTick()}function Mg(e){return!!e&&"object"==typeof e&&1===e.version}function Rg(e,t){const i=e.radar;return e.space===t&&!0!==e.hidden&&!0!==e.removed&&Mg(i)&&!0===i.enabled&&!1!==i.show_live}const Cg={ok:"radar.health_ok",off:"radar.health_off",stale:"radar.health_stale",partial:"radar.health_partial",restricted:"radar.health_restricted",incomplete:"radar.health_incomplete",position_unavailable:"radar.health_position_unavailable",unavailable:"radar.health_unavailable",needs_setup:"radar.health_needs_setup",inconsistent:"radar.health_inconsistent",unknown:"radar.health_unknown"};const Tg=e=>"number"==typeof e&&Number.isFinite(e);class Dg{constructor(e){this.host=e,this.frames=new Map,this.connection=null,this.space="",this.generation=0,this.expiryTimer=0,this.deadlines=new Map}sync(e,t){const i=this.host.hass?.connection;if(!t||!i||!this.host.isConnected)return void this.stop();if(this.unsubscribe&&this.connection===i&&this.space===e)return;this.stop(),this.connection=i,this.space=e;const n=++this.generation,r=i.subscribeMessage?.bind(i);"function"==typeof r&&Promise.resolve(r(e=>{if(n!==this.generation||!this.host.isConnected)return;const t=function(e){if(!e||"object"!=typeof e)return null;const t=e;if("string"!=typeof t.marker_id||"string"!=typeof t.server_session_id||!Number.isSafeInteger(t.seq)||"string"!=typeof t.health)return null;const i=Array.isArray(t.targets)?t.targets.slice(0,256).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;return"string"==typeof t.slot&&Tg(t.x)&&Tg(t.y)&&Tg(t.expires_at)&&Tg(t.reported_at)&&("bounded_latest"===t.pair_quality||"coherent"===t.pair_quality)?[{...t,included:!0===t.included,smooth:!0===t.smooth}]:[]}):[],n=Array.isArray(t.ranges)?t.ranges.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if(!("string"==typeof t.id&&Tg(t.x)&&Tg(t.y)&&Tg(t.radius)&&Tg(t.expires_at)&&Tg(t.reported_at)))return[];const i=Array.isArray(t.segments)?t.segments.slice(0,64).flatMap(e=>{if(!Array.isArray(e))return[];const t=e.slice(0,181).flatMap(e=>Array.isArray(e)&&2===e.length&&Tg(e[0])&&Tg(e[1])?[[e[0],e[1]]]:[]);return t.length>=2?[t]:[]}):void 0;return[{...t,...i?{segments:i}:{}}]}):[],r=Array.isArray(t.zones)?t.zones.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if("string"!=typeof t.id)return[];const i=t.state;if(null!==i&&"boolean"!=typeof i&&!Tg(i))return[];const n=Array.isArray(t.polygon)?t.polygon.slice(0,64).flatMap(e=>Array.isArray(e)&&2===e.length&&Tg(e[0])&&Tg(e[1])?[[e[0],e[1]]]:[]):[];return[{id:t.id,state:i,...n.length>=3?{polygon:n}:{}}]}):[];return{server_session_id:t.server_session_id,marker_id:t.marker_id,source_generation:"string"==typeof t.source_generation?t.source_generation:void 0,calibration_revision:"string"==typeof t.calibration_revision?t.calibration_revision:void 0,seq:t.seq,reported_at:Tg(t.reported_at)?t.reported_at:void 0,expires_at:Tg(t.expires_at)?t.expires_at:void 0,health:t.health,reported_presence:"boolean"==typeof t.reported_presence?t.reported_presence:null,complete:!0===t.complete,targets:i,ranges:n,zones:r}}(e);if(!t)return;if(!function(e,t){return!e||t.server_session_id!==e.server_session_id||t.source_generation!==e.source_generation||t.calibration_revision!==e.calibration_revision||t.seq>e.seq}(this.frames.get(t.marker_id),t))return;const i=function(e,t=Date.now()){if(!Tg(e.expires_at))return null;if(!Tg(e.reported_at))return Math.max(0,1e3*e.expires_at-t);const i=Math.max(0,1e3*(e.expires_at-e.reported_at)),n=Math.max(0,t-1e3*e.reported_at);return Math.max(0,i-n)}(t);"restricted"===t.health||"disabled"===t.health||0===i?(this.frames.delete(t.marker_id),this.deadlines.delete(t.marker_id)):(this.frames.set(t.marker_id,t),null==i?this.deadlines.delete(t.marker_id):this.deadlines.set(t.marker_id,this.monotonicNow()+i)),this.armExpiry(),this.host.requestUpdate()},{type:"houseplan/radar/subscribe",space_id:e})).then(e=>{n===this.generation&&this.host.isConnected?"function"==typeof e&&(this.unsubscribe=e):"function"==typeof e&&e()}).catch(()=>{n===this.generation&&this.stop()})}stop(){this.generation++,this.unsubscribe?.(),this.unsubscribe=void 0,this.connection=null,this.space="",clearTimeout(this.expiryTimer),this.expiryTimer=0,this.frames.size&&(this.frames.clear(),this.host.isConnected&&this.host.requestUpdate()),this.deadlines.clear()}armExpiry(){clearTimeout(this.expiryTimer);const e=this.monotonicNow(),t=[...this.deadlines.values()].filter(t=>t>e);if(!t.length)return;const i=Math.max(20,Math.min(...t)-e+10);this.expiryTimer=window.setTimeout(()=>{this.expiryTimer=0;let e=!1;const t=this.monotonicNow();for(const[i,n]of this.deadlines)n>t||(this.deadlines.delete(i),this.frames.delete(i),e=!0);this.armExpiry(),e&&this.host.isConnected&&this.host.requestUpdate()},i)}monotonicNow(){return globalThis.performance?.now?.()??Date.now()}}const Ag=Object.freeze({enabled:!1,z2mBaseTopics:Object.freeze([])});function Pg(e){if("string"!=typeof e)return null;const t=e.trim().replace(/^\/+|\/+$/g,"").replace(/\/{2,}/g,"/");return!t||t.length>180||/[#+\u0000-\u001f\u007f]/.test(t)?null:t}function Fg(e){const t=e?.zigbee_topology;if(!t||"object"!=typeof t)return Ag;const i=t,n=Array.isArray(i.z2m_base_topics)?i.z2m_base_topics:Array.isArray(i.z2mBaseTopics)?i.z2mBaseTopics:[],r=new Set,o=[];for(const e of n){const t=Pg(e);if(t&&!r.has(t)&&(r.add(t),o.push(t),8===o.length))break}return{enabled:!0===i.enabled,z2mBaseTopics:o}}function zg(e,t){const i={...e},n=t.z2mBaseTopics.map(Pg).filter(Boolean);return t.enabled||n.length?i.zigbee_topology={enabled:!0===t.enabled,z2m_base_topics:[...new Set(n)].slice(0,8)}:delete i.zigbee_topology,i}const Ig={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Og=e=>Math.max(0,Math.min(1,e)),Eg=(e,t,i)=>e+(t-e)*i,Ng=(e,t,i)=>{const n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},Hg=e=>{const t=Og(e);if(0===t||1===t)return t;let i=0,n=1,r=t;for(let e=0;e<12;e++)r=(i+n)/2,Ng(r,.2,.2)0&&e.w>0?t/e.w:1,viewBox:{...e}}}function Bg(e,t,i){const n=Math.max(1e-9,e.pixelsPerUnit),r=Math.max(1e-9,t/n),o=Math.max(1e-9,i/n);return{x:e.centerX-r/2,y:e.centerY-o/2,w:r,h:o}}function qg(e){const t=e.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(t);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const n=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t)?.[1];return n?[parseInt(n.slice(0,2),16),parseInt(n.slice(2,4),16),parseInt(n.slice(4,6),16),8===n.length?parseInt(n.slice(6,8),16)/255:1]:null}function jg(e,t,i){const n=qg(e),r=qg(t);if(!n||!r)return i<.5?e:t;const o=Og(i);return`rgba(${Math.round(Eg(n[0],r[0],o))}, ${Math.round(Eg(n[1],r[1],o))}, ${Math.round(Eg(n[2],r[2],o))}, ${Eg(n[3],r[3],o).toFixed(3)})`}class Wg{constructor(e,t=Ig){this._hooks=e,this._clock=t,this._token=0,this._raf=0,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase||"preparing"===this._state?.phase}get presented(){return this._state?.presented||null}start(e,t,i,n=220){this.cancel(!1);const r=++this._token,o=this._clock.now();if(this._state={token:r,phase:n<=0?"settling":"running",from:e,to:t,presented:n<=0?t:e,startedAt:o,duration:Math.max(0,n),targetMode:i},n<=0)return this._hooks.frame(this._state),this._hooks.settled(this._state),this._state=null,r;this._hooks.frame(this._state);const s=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Og((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:function(e,t,i){const n=Hg(i),r=Eg(e.stageWidth,t.stageWidth,n),o=Eg(e.stageHeight,t.stageHeight,n),s=Math.max(1e-9,e.viewport.pixelsPerUnit),a=Math.max(1e-9,t.viewport.pixelsPerUnit),l={centerX:Eg(e.viewport.centerX,t.viewport.centerX,n),centerY:Eg(e.viewport.centerY,t.viewport.centerY,n),pixelsPerUnit:Math.exp(Eg(Math.log(s),Math.log(a),n))};return{presentedMode:n<.5?e.presentedMode:t.presentedMode,editorChromeHeight:Eg(e.editorChromeHeight,t.editorChromeHeight,n),stageWidth:r,stageHeight:o,viewport:{...l,viewBox:Bg(l,r,o)},stageColor:jg(e.stageColor,t.stageColor,n),paperColor:jg(e.paperColor,t.paperColor,n),sceneBrightness:Eg(e.sceneBrightness,t.sceneBrightness,n),architectureOpacity:Eg(e.architectureOpacity,t.architectureOpacity,n),backdropOpacity:Eg(e.backdropOpacity,t.backdropOpacity,n),viewWeight:Eg(e.viewWeight,t.viewWeight,n),editorWeight:Eg(e.editorWeight,t.editorWeight,n),toolbarContentOpacity:Eg(e.toolbarContentOpacity,t.toolbarContentOpacity,n)}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i<1?this._raf=this._clock.requestFrame(s):(this._raf=0,this._hooks.settled(t),this._state?.token===r&&(this._state=null))};return this._raf=this._clock.requestFrame(s),r}cancel(e=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=t.to,this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}}const Ug={now:()=>"undefined"!=typeof performance?performance.now():Date.now(),requestFrame:e=>"function"==typeof requestAnimationFrame?requestAnimationFrame(e):null,cancelFrame:e=>{"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e)}},Gg=e=>Number.isFinite(e);function Vg(e){return!!e&&Gg(e.zoom)&&e.zoom>0&&Gg(e.viewBox.x)&&Gg(e.viewBox.y)&&Gg(e.viewBox.w)&&e.viewBox.w>0&&Gg(e.viewBox.h)&&e.viewBox.h>0}function Kg(e){return{zoom:e.zoom,viewBox:{...e.viewBox}}}function Yg(e,t){return Math.abs(e.zoom-t.zoom)<1e-9&&Math.abs(e.viewBox.x-t.viewBox.x)<1e-6&&Math.abs(e.viewBox.y-t.viewBox.y)<1e-6&&Math.abs(e.viewBox.w-t.viewBox.w)<1e-6&&Math.abs(e.viewBox.h-t.viewBox.h)<1e-6}const Xg=(e,t,i)=>e+(t-e)*i,Zg=(e,t,i)=>Math.exp(Xg(Math.log(e),Math.log(t),i));class Jg{constructor(e,t=Ug){this._hooks=e,this._clock=t,this._token=0,this._raf=null,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase}get presented(){return this._state?.presented||null}get target(){return this._state?.to||null}start(e,t,i,n){this.cancel(!1);const r=++this._token,o=Kg(e),s=Kg(t),a=n>0&&Vg(o)&&Vg(s),l=this._clock.now(),c={token:r,phase:a?"running":"settling",from:o,to:s,presented:Kg(a?o:s),startedAt:l,duration:a?n:0,reason:i};if(this._state=c,this._hooks.frame(c),!a)return this._settle(r),r;const h=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Math.max(0,Math.min(1,(e-t.startedAt)/t.duration));if(t.presented=i>=1?Kg(t.to):function(e,t,i){if(!Vg(e))return Kg(t);if(!Vg(t))return Kg(e);const n=Hg(i);if(n<=0)return Kg(e);if(n>=1)return Kg(t);const r=e.viewBox.x+e.viewBox.w/2,o=e.viewBox.y+e.viewBox.h/2,s=t.viewBox.x+t.viewBox.w/2,a=t.viewBox.y+t.viewBox.h/2,l=Zg(e.viewBox.w,t.viewBox.w,n),c=Zg(e.viewBox.h,t.viewBox.h,n),h=Xg(r,s,n),d=Xg(o,a,n);return{zoom:Zg(e.zoom,t.zoom,n),viewBox:{x:h-l/2,y:d-c/2,w:l,h:c}}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i>=1)return this._raf=null,void this._settle(r);this._raf=this._clock.requestFrame(h),null===this._raf&&this._settle(r)};return this._raf=this._clock.requestFrame(h),null===this._raf&&(c.phase="settling",c.presented=Kg(s),this._hooks.frame(c),this._settle(r)),r}cancel(e=!0){null!==this._raf&&this._clock.cancelFrame(this._raf),this._raf=null;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=Kg(t.to),this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}_settle(e){const t=this._state;t&&t.token===e&&(t.phase="settling",t.presented=Kg(t.to),this._hooks.settled(t),this._state?.token===e&&(this._state=null))}}function Qg(e,t,i){const n=e.querySelector("ha-card");if(!n)return null;const r=n.getBoundingClientRect(),o=t.getBoundingClientRect().top-r.top,s=i?0:Math.min(Math.max(r.top,0),120),a=Math.round(o+s);return a>=0?a:null}const ef=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])}),tf=84,nf=10,rf=4,of=4;function sf(e){return[e.rotDeg,e.tiltDeg,e.xyScale,e.zScale,e.origin[0],e.origin[1]].every(Number.isFinite)&&Math.abs(e.xyScale)>1e-12&&Math.abs(Math.cos(e.tiltDeg*Math.PI/180))>1e-12}function af(e,t,i=ef){if(!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");return function(e,t){if(!Number.isFinite(e[0])||!Number.isFinite(e[1])||!t.every(Number.isFinite))throw new Error("invalid isometric affine input");const[i,n,r,o,s,a]=t;return[i*e[0]+r*e[1]+s,n*e[0]+o*e[1]+a]}(e,cf(t,i))}function lf(e,t=ef){if(!sf(t)||!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=(e[0]-t.origin[0])/t.xyScale,o=(e[1]-t.origin[1])/(t.xyScale*Math.cos(n));return[t.origin[0]+r*Math.cos(i)+o*Math.sin(i),t.origin[1]-r*Math.sin(i)+o*Math.cos(i)]}function cf(e=0,t=ef){if(!sf(t)||!Number.isFinite(e))throw new Error("invalid isometric camera");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=t.xyScale*Math.cos(i),o=-t.xyScale*Math.sin(i),s=t.xyScale*Math.sin(i)*Math.cos(n),a=t.xyScale*Math.cos(i)*Math.cos(n);return[r,s,o,a,t.origin[0]-r*t.origin[0]-o*t.origin[1],t.origin[1]-s*t.origin[0]-a*t.origin[1]-e*t.zScale*Math.sin(n)]}function hf(e=ef){return function(e=0,t=ef){return`matrix(${cf(e,t).map(e=>Number(e.toFixed(12))).join(" ")})`}(0,e)}function df(e,t=ef){const{rect:i,wallHeight:n}=e,r=e.openingHeight??n,o=e.floorDepth??0,s=e.raisedHeight??n;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o)||!Number.isFinite(s)||n<0||r<0||o<0||s<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],l=Math.max(n,r,s),c=a.flatMap(e=>[af(e,-o,t),af(e,l,t)]),h=c.map(e=>e[0]),d=c.map(e=>e[1]),u=Math.min(...h),p=Math.min(...d);return{x:u,y:p,w:Math.max(...h)-u,h:Math.max(...d)-p}}const uf=[".dev",".vacpuck",".oplock",".op-hit",".opening",".rlgo","a","button","input","select","textarea",'[contenteditable]:not([contenteditable="false"])',"[data-room-fit-block]",'[role="link"]','[role="button"]'].join(","),pf=(e,t)=>{try{return"function"==typeof e?.matches&&e.matches(t)}catch{return!1}};function _f(e){for(const t of e){const e=t;if(pf(e,".roomlabel[data-id]")){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(pf(e,uf))return{kind:"interactive"};if(pf(e,'[data-hp="room"][data-id]')){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(pf(e,".stage"))return{kind:"background"}}return{kind:"outside"}}function mf(e){const t=_f(e);return"room"===t.kind?t.roomId:null}class gf{constructor(){this.pointer=null,this.sequence=null}clear(){this.pointer=null,this.sequence=null}clearOutside(e){let t={kind:"outside"};try{t=_f(e.composedPath())}catch{}"outside"===t.kind&&this.clear()}pointerDown(e,t,i){let n={kind:"outside"};try{n=_f(e.composedPath())}catch{}this.pointer=function(e){const t="mouse"===(i=e.pointerType)||"touch"===i||"pen"===i?i:null;var i;return t&&"view"===e.mode&&"background"===e.owner.kind&&!e.blocked&&e.isPrimary&&0===e.button&&Number.isFinite(e.x)&&Number.isFinite(e.y)?{pointerId:e.pointerId,spaceId:e.spaceId,modality:t,x:e.x,y:e.y}:null}({pointerId:e.pointerId,pointerType:e.pointerType,isPrimary:e.isPrimary,button:e.button,spaceId:t,mode:i?"view":"blocked",owner:n,blocked:!i,x:e.clientX,y:e.clientY}),this.pointer||(this.sequence=null)}pointerUp(e,t,i,n,r=Date.now()){let o={kind:"outside"};try{o=_f(e.composedPath())}catch{}const s=function(e,t,i){if(!t||"view"!==i.mode||"background"!==i.owner.kind||i.blocked||t.pointerId!==i.pointerId||t.spaceId!==i.spaceId||!Number.isFinite(i.x)||!Number.isFinite(i.y)||!Number.isFinite(i.now)||Math.abs(i.x-t.x)+Math.abs(i.y-t.y)>=8)return{sequence:null,trigger:!1};const n=e?i.now-e.at:Number.POSITIVE_INFINITY;return e&&e.spaceId===i.spaceId&&e.modality===t.modality&&n>=0&&n<=350?{sequence:null,trigger:!0}:{sequence:{at:i.now,spaceId:i.spaceId,modality:t.modality},trigger:!1}}(this.sequence,this.pointer,{pointerId:e.pointerId,spaceId:t,mode:i?"view":"blocked",owner:o,blocked:n||!i,x:e.clientX,y:e.clientY,now:r});return this.pointer=null,this.sequence=s.sequence,s.trigger}}const ff=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function vf(e){return!!e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&e.w>0&&Number.isFinite(e.h)&&e.h>0}function yf(e,t=0){if(!e.length||!Number.isFinite(t)||t<0||!e.every(ff))return null;let i=1/0,n=1/0,r=-1/0,o=-1/0;for(const t of e)i=Math.min(i,t[0]),n=Math.min(n,t[1]),r=Math.max(r,t[0]),o=Math.max(o,t[1]);const s=r-i,a=o-n;return s>0&&a>0?{x:i-t,y:n-t,w:s+2*t,h:a+2*t}:null}function bf(e,t,i){const n="string"!=typeof t||"invalid"!==t&&"no-borders"!==t&&"unverified"!==t&&!/^[a-z0-9]{1,8}$/i.test(t)?"redacted":t;return Object.freeze({kind:e,fingerprint:n,terminal:!!i})}function wf(e,t){return`${e("editor.load_failed")} ${e(t.terminal?"editor.refresh_advice":"editor.retry_advice")}`}class kf extends Error{}class xf{constructor(e){this.options=e,this._state="idle",this._inFlight=null}get state(){return this._state}ensure(){return"ready"===this._state?Promise.resolve(!0):"failed"===this._state?Promise.resolve(!1):(this._inFlight||(this._setState("loading"),this._inFlight=this._loadWithRetry().finally(()=>{this._inFlight=null})),this._inFlight)}async _loadWithRetry(){let e=new Error("Editor runtime did not load"),t=!1;for(const i of[0,1])try{const e=await this.options.load(i);if(e.fingerprint!==this.options.expectedFingerprint)throw new kf(`Editor runtime fingerprint mismatch: expected ${this.options.expectedFingerprint}, got ${e.fingerprint}`);const t=e.create();return this.options.install(t),this._setState("ready"),!0}catch(i){e=i,i instanceof kf&&(t=!0)}return this._setState(t?"failed":"idle"),this.options.failed?.(e,{terminal:t}),!1}_setState(e){e!==this._state&&(this._state=e,this.options.stateChanged?.(e))}}const Sf=(e,t)=>{if(!e.has(t))return{hit:!1};const i=e.get(t);return e.delete(t),e.set(t,i),{hit:!0,value:i}},$f=(e,t,i,n)=>{for(e.delete(t),e.set(t,i);e.size>n;){const t=e.keys().next().value;if(void 0===t)break;e.delete(t)}},Mf=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Rf=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`,Cf="houseplan_card_alpha_v1",Tf=Object.freeze([Object.freeze({id:"iso",issue:89,summary:"Volumetric plan renderer"})]);function Df(e){return/^[a-z][a-z0-9-]*$/.test(e.id)&&Number.isInteger(e.issue)&&e.issue>0&&!!e.summary.trim()}function Af(e){const t=String(e||"").replace(/^#/,"");return new URLSearchParams(t)}function Pf(e){return Af(e).get("space")||""}function Ff(e,t,i=Tf){const n=function(e){const t=new Set;for(const i of e){if(!Df(i)||t.has(i.id))return!1;t.add(i.id)}return!0}(i),r=function(e){let t,i=!1;const n=e=>{for(const n of e.getAll("hp_alpha"))i=!0,"1"===n?t=!0:"0"===n&&(t=!1)};return n(new URLSearchParams(String(e.search||"").replace(/^\?/,""))),n(Af(e.hash)),{present:i,value:t}}(e),o=void 0!==r.value,s="1"===t,a=o?!0===r.value:!r.present&&s,l=n&&a;return{alpha:l,active:Object.freeze(l?i.map(e=>e.id).sort():[]),space:Pf(e.hash),persist:n&&o?l?"1":"0":void 0,knownUrlOperation:o}}let zf={alpha:!1,active:Object.freeze([]),space:""},If=!1,Of="";const Ef=new Set;function Nf(){if("undefined"==typeof window)return zf;const e=Ff(window.location,function(){try{return window.localStorage.getItem(Cf)}catch{return null}}());void 0!==e.persist&&function(e){try{window.localStorage.setItem(Cf,e)}catch{}}(e.persist),zf={alpha:e.alpha,active:e.active,space:e.space},window.__hpAlpha=e.alpha,window.__hpLabs=e.active;for(const e of Ef)e(zf);return zf}function Hf(){Nf()}function Lf(){if("undefined"==typeof window)return zf;if(!If){If=!0,window.__hpLabsListenerCleanup?.(),window.addEventListener("hashchange",Hf),window.addEventListener("popstate",Hf);const e=()=>{window.removeEventListener("hashchange",Hf),window.removeEventListener("popstate",Hf),window.__hpLabsListenerCleanup===e&&delete window.__hpLabsListenerCleanup};window.__hpLabsListenerCleanup=e}return Nf()}const Bf={window:120,door:90,passage:90,gate:300};function qf(e){return Bf[e]}function jf(e,t){return{type:e,lengthCm:qf(e),flipH:!1,flipV:!1,revision:t}}function Wf(e,t){const i=Math.max(0,e.renderedLength)/2,n=Math.max(0,e.target.physicalHalfWidth),r=n+.18*Math.max(0,t),o=e=>({x1:e,y1:-r,x2:e,y2:r});return{rect:{x:-i,y:n?-n:0,width:2*i,height:2*n},boundaries:[o(-i),o(i)]}}function Uf(e,t){const i=[e[0],e[1]],n=[t[0],t[1]];return function(e,t){return e[0]-t[0]||e[1]-t[1]}(i,n)<=0?{a:i,b:n}:{a:n,b:i}}function Gf(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const n=Uf(e.a,e.b);if(Math.hypot(n.b[0]-n.a[0],n.b[1]-n.a[1])<=1e-9)return;const r=function(e,t){const i=e=>(Math.abs(e)<=5e-10?0:Math.round(1e6*e)/1e6).toFixed(6);return`${i(e[0])},${i(e[1])}>${i(t[0])},${i(t[1])}`}(n.a,n.b),o=t.get(r);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,e.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(e.partitionHost&&(o.partitionHost&&o.partitionHost.id!==e.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=e.partitionHost));t.set(r,{segmentKey:r,a:n.a,b:n.b,physicalHalfWidth:Math.max(0,e.half||0),sourceOrder:i,...e.partitionHost?{partitionHost:e.partitionHost}:{}})}),[...t.values()]}function Vf(e,t){if(Math.abs(e.distance-t.distance)>1e-9)return e.distance-t.distance;if(Math.abs(e.perpendicular-t.perpendicular)>1e-9)return e.perpendicular-t.perpendicular;return(e.target.segmentKeyt.target.segmentKey?1:0)||e.target.sourceOrder-t.target.sourceOrder}function Kf(e){const t=Gf(e.intervals).map(t=>{const i=function(e,t){const i=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,a=(e[0]-t.a[0])*o+(e[1]-t.a[1])*s,l=Math.max(0,Math.min(r,a)),c=t.a[0]+l*o,h=t.a[1]+l*s;return{along:l,length:r,x:c,y:h,distance:Math.hypot(e[0]-c,e[1]-h),perpendicular:Math.abs((e[0]-t.a[0])*s-(e[1]-t.a[1])*o)}}(e.pointer,t);return{target:t,...i,envelope:Math.max(e.baseTolerance,t.physicalHalfWidth+e.bodyPointerPadding)}}).filter(e=>e.distance<=e.envelope+1e-9).filter(t=>!function(e,t,i,n,r){const o=t.b[0]-t.a[0],s=t.b[1]-t.a[1],a=Math.hypot(o,s);if(!(a>1e-9))return!1;const l=o/a,c=s/a;for(const o of i){if(!o.open&&o.kind)continue;const i=Uf(o.a,o.b),s=i.b[0]-i.a[0],a=i.b[1]-i.a[1],h=Math.hypot(s,a);if(!(h>1e-9))continue;const d=s/h,u=a/h;if(Math.abs(l*u-c*d)>1e-6)continue;if(Math.abs((i.a[0]-t.a[0])*c-(i.a[1]-t.a[1])*l)>r)continue;const p=(e[0]-i.a[0])*d+(e[1]-i.a[1])*u,_=1e-9;if(!(p<=_||p>=h-_)&&Math.abs((e[0]-i.a[0])*u-(e[1]-i.a[1])*d)<=n+1e-9)return!0}return!1}(e.pointer,t.target,e.intervals,t.envelope,Math.max(1e-9,Math.min(e.baseTolerance,.04*e.gridStep)))),i=t.filter(t=>!!t.target.partitionHost&&e.renderedLength+2*t.target.physicalHalfWidth>t.length+1e-9).sort(Vf),n=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(Vf);let r=n[0];if(!r)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=n.filter(e=>Math.abs(e.distance-r.distance)<=1e-9&&Math.abs(e.perpendicular-r.perpendicular)<=1e-9),s=o.filter(e=>e.target.partitionHost);if(s.length){if(1!==new Set(s.map(e=>e.target.partitionHost.id)).size||s.some(e=>e.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const e=s[0],t=e.target.b[0]-e.target.a[0],i=e.target.b[1]-e.target.a[1],n=Math.hypot(t,i),a=t/n,l=i/n;if(!o.every(t=>{const i=t.target.b[0]-t.target.a[0],n=t.target.b[1]-t.target.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,c=Math.abs(a*s-l*o)<=1e-6,h=Math.abs((t.target.a[0]-e.target.a[0])*l-(t.target.a[1]-e.target.a[1])*a);return c&&h<=1e-9}))return{candidate:null,jambBlockedTarget:null};r=e}if(r.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:a,length:l}=r,c=a.b[0]-a.a[0],h=a.b[1]-a.a[1],d=c/l,u=h/l,p=a.partitionHost?a.physicalHalfWidth:0,_=Math.min(Math.max(0,e.renderedLength)/2+p,l/2);let m=r.along;const g=Math.max(e.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=a.a[0]+d*m,y=a.a[1]+u*m,b=Math.max(0,e.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),S=Math.max(0,l-k),$=[a.a[0]+d*(w-x/2),a.a[1]+u*(w-x/2)],M=[a.a[0]+d*(k+S/2),a.a[1]+u*(k+S/2)];let R=180*Math.atan2(h,c)/Math.PI;R>=90?R-=180:R<-90&&(R+=180);const C=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:e.preset.revision,geometryRevision:e.geometryRevision,pointer:[e.pointer[0],e.pointer[1]],type:e.preset.type,lengthCm:e.preset.lengthCm,flipH:e.preset.flipH,flipV:e.preset.flipV,x:v,y:y,angle:R,renderedLength:e.renderedLength,target:a,...a.partitionHost?{host:{...a.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:$},{distance:S,midpoint:M}],guide:C?{x:v,y:y,angle:R}:null}},jambBlockedTarget:null}}function Yf(e,t,i,n,r=1e-6){return e.presetRevision===i&&e.geometryRevision===n&&Math.hypot(e.pointer[0]-t[0],e.pointer[1]-t[1])<=r}function Xf(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}class Zf{constructor(e,t,i){this.loader=e,this.host=t,this.adopted=i,this.attachment=null}connect(){if(this.runtime)return void this.runtime.connect();this.attachment?.cancel();const e=this.loader.attach(this.host,e=>this.adopt(e));this.runtime||(this.attachment=e)}disconnect(){this.attachment?.cancel(),this.attachment=null,this.runtime?.disconnect()}adopt(e){this.attachment=null,this.runtime||(this.runtime=e,this.adopted(e))}}const Jf=new class{constructor(e){this.load=e,this.factory=null,this.pending=null}get warm(){return null!==this.factory}create(e){return this.factory?this.factory(e):null}attach(e,t){let i=!0;const n={cancel:()=>{i=!1}},r=this.create(e);return r?(t(r),n):(this.ensure().then(n=>{i&&t(n(e))},()=>{}),n)}ensure(){return this.factory?Promise.resolve(this.factory):(this.pending||(this.pending=this.load().then(e=>(this.factory=e,this.pending=null,e),e=>{throw this.pending=null,e})),this.pending)}reset(){this.factory=null,this.pending=null}}(()=>import("./summary-panel-runtime-loaded-CNpqraog.js").then(function(e){return e.e}).then(({LoadedSummaryPanelRuntime:e})=>t=>new e(t)));function Qf(e){const t=globalThis.__HP_VERSION_OVERRIDE__;return"string"==typeof t&&t.length>0?t:e}let ev=0;const tv="1.76.0-beta.3",iv="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33",nv=1500,rv=new Map;let ov=0,sv=1e4;const av="houseplan_card_layout_v1",lv="houseplan_card_cfg_v1",cv="houseplan_card_zoom_v1",hv="houseplan_card_nav_v1",dv="houseplan_card_view_v1",uv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",pv=1e3,_v=(e,t)=>{const i=Math.min(e.x,t.x),n=Math.min(e.y,t.y);return{x:i,y:n,w:Math.max(e.x+e.w,t.x+t.w)-i,h:Math.max(e.y+e.h,t.y+t.h)-n}},mv=(e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)},gv=e=>{history.pushState(null,"",e),mv(window,"location-changed",{replace:!1})},fv=(e,t)=>{let i,n=null;const r=(...r)=>{clearTimeout(i),n=r,i=window.setTimeout(()=>{i=void 0;const t=n;n=null,t&&e(...t)},t)};return r.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const t=n;n=null,t&&e(...t)},r.cancel=()=>{clearTimeout(i),i=void 0,n=null},r.pending=()=>void 0!==i,r},vv=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}},yv=["edges","corners"];class bv extends he{constructor(){var e;super(...arguments),this._editorRuntime=null,this._liveRt=null,this._onboardingRuntime=null,this._editorRuntimeLoadingVisible=!1,this._backdropGuard=null,this._editorModeRequest=0,this._warmModeRequest=0,this._editorRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./houseplan-editor-runtime-dzTrOQhv.js"):await import((()=>{const e=new URL("./houseplan-editor-runtime-dzTrOQhv.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.EDITOR_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanEditorRuntime(this)}},install:e=>{this._editorRuntime=e},stateChanged:e=>this._editorRuntimeStateChanged(e),failed:(e,t)=>{console.error("[houseplan] unable to load editor runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(wf(e=>this._t(e),t))}}),this._onboardingRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./houseplan-onboarding-runtime-BLRnH1D6.js"):await import((()=>{const e=new URL("./houseplan-onboarding-runtime-BLRnH1D6.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.ONBOARDING_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanOnboardingRuntime(this)}},install:e=>{this._onboardingRuntime=e},failed:(e,t)=>{console.error("[houseplan] unable to load onboarding runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(wf(e=>this._t(e),t))}}),this._isoSceneRuntime=null,this._isoSceneRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./iso-scene-render-BIRwzucU.js"):await import((()=>{const e=new URL("./iso-scene-render-BIRwzucU.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.ISO_SCENE_RUNTIME_FINGERPRINT,create:()=>t}},install:e=>{const t=this._effectiveProjection();this._isoSceneRuntime=e,this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i),this.isConnected&&this.requestUpdate()},failed:(e,t)=>{console.warn("[houseplan] hidden isometric runtime diagnostic",bf("runtime-load","unverified",t.terminal)),this.isConnected&&this.requestUpdate()}}),this._pdfRuntime=null,this._pdfRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./pdf-export-B2sbsWvc.js"):await import((()=>{const e=new URL("./pdf-export-B2sbsWvc.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.PDF_EXPORT_FINGERPRINT,create:()=>new t.PdfExportRuntime}},install:e=>{this._pdfRuntime=e,this.isConnected&&this.requestUpdate()},failed:(e,t)=>{if(console.error("[houseplan] unable to load PDF export runtime",e),!t.terminal||!this._versionRecovery.hasCurrentMismatchNotice){const e=wf(e=>this._t(e),t),i=this._t("editor.load_failed"),n=e.startsWith(i)?e.slice(i.length).trim():e;this._showToast(`${this._t("pdf.failed")} ${n}`.trim())}}}),this.panelHost=!1,this.narrow=null,this._space="f1",this._adoption=new Bu((e,t)=>this.requestUpdate(e,t)),this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._configReloadAuthority=new Uu,this._virtualLights=Nh(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._areaRelocationIds=new Set,this._areaSnapshotCleanupCandidates=new Map,this._areaRelocationSyncKey="",this._areaRelocationWrite=Promise.resolve(),this._tip=null,this._hoverRoom=null,this._pointerModality=new og(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Sr},this._decorStyleSeeded=!1,this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._decorImagePalette=null,this._decorAssetCatalog=[],this._decorAssets=new Map,this._decorAssetBusy=!1,this._furnCategory=null,this._furnPreviewInput=null,this._furnTouchPending=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this._cancelDevicePressFeedback(),e.matches&&this._cancelCameraTransition(!0),e.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:e.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this._syncVersionRecovery(),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new Wg({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._cameraTransitionFit=null,this._cameraTransition=new Jg({frame:e=>this._applyCameraTransitionFrame(e),settled:e=>this._settleCameraTransition(e)}),this._editorSecondaryCopy={groupActive:(e,t)=>this._t("editor.group_active",{group:e,item:t}),openGroup:e=>this._t("editor.open_group",{group:e}),disabledAction:(e,t)=>this._t("editor.disabled_action",{action:e,reason:t})},this._tool="draw",this._geometryHistory=new mg(50),this._devicePositionHistory=new mg(50),this._devicePositionBusy=!1,this._wallDialog=null,this._drawWallField=null,this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainRedo=[],this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._renderIsoScene=null,this._isoProjectionSnapshot=null,this._isoStructuralBuildCount=0,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowRuntimeState=ym(),this._glowRuntimeHost={window:()=>this.ownerDocument.defaultView||window,isConnected:()=>this.isConnected,requestUpdate:()=>this.requestUpdate(),reducedMotion:()=>this._reducedMotion},this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszLimitViolation=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempMin="",this._roomTempMax="",this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._roomFocus=null,this._roomPointer=null,this._doubleFit=new gf,this._deviceHits=new bc,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._viewportGestureDirty=!1,this._touchContacts=new Map,this._touchClickGuard=new uc,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:e=>this._guardTouchGesture(e)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._dangerConfirm=null,this._dangerConfirmController=new ze(e=>{this._dangerConfirm=e}),this._confirmDanger=e=>this._config&&this.hass?"warm"===this._syncDangerConfirmLocaleGate()||this._dangerConfirmMissingSpace()?Promise.resolve(!1):this._dangerConfirmController.confirm(e):Promise.resolve(!1),this._cancelDangerConfirm=()=>{this._dangerConfirmController.cancel()},this._onDangerConfirmDecision=e=>{this._dangerConfirmController.resolve(e.detail.token,e.detail.accepted)},this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._versionRecovery=(e=this,new bg({clock:{setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e)},storage:()=>e.ownerDocument.defaultView?.sessionStorage??null,safety:()=>xg(e),reload:()=>e._reloadDocument(),changed:()=>{e.requestUpdate()}})),this._haSupportApi=null,this._haDecorAssetsApi=null,this._haSummaryPanelApi=null,this._haRadarStage1Api=null,this._radarLive=new Dg(this),this._decorAssetSyncToken=0,this._alignDialog=null,this._settingsDialog=null,this._pdfDialog=!1,this._supportDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=e=>this._onKey(e),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++ov,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={alpha:!1,active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._summarySlot=new Zf(Jf,this,e=>{this._summary=e,this._capturedSnapshotSequence=-1,this.isConnected&&(e.connect(),this.hasUpdated&&this.requestUpdate())}),this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),this._summary?.visibility(e.kind),"hidden"===e.kind)return this._radarLive.stop(),this._editorRuntime?._cancelRadarSetup(),this._clearRoomFocus(!0),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._cancelCameraTransition(!0),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,this._syncRadarLive(),!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+eg)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._onLabsSnapshot=e=>{const t=this._effectiveProjection();this._labs=e,this._isoProjectionSnapshot=null,this._labsIso&&this._ensureIsoSceneRuntime();const i=this._effectiveProjection();this._convertProjectionView(t,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const e=this._hashSpace();if(e&&this._model.find(t=>t.id===e)&&e!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._deviceDrag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._cfgEpochPreservedConfig=null,this._terminalFrame=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._renderLife=new Sg,this._liveEditorPaintCount=0,this._onHaRegistryUpdate=()=>{const e=id(this.hass);e.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=e.revision,this._renderLife.invalidate(),this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,td(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new dc(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=fv(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=yo(this._layout[t]);e&&(this._layout={...this._layout,[t]:e},this._sentPos.set(t,e),this.hass.callWS({type:"houseplan/layout/update",device_id:t,pos:e}).then(e=>this._noteLayoutRev(e)).catch(e=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))).finally(()=>{this._sentPos.get(t)===e&&this._sentPos.delete(t)}))}this._cacheSnapshot()}else this._persistLocalLayout()},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>this._editorRuntimeOrThrow()._undoGeometry(),this._redoGeometry=()=>this._editorRuntimeOrThrow()._redoGeometry(),this._saveConfigDebounced=fv(()=>{this._serverCfg&&this._writeConfig().catch(e=>{const t=!0===e?.physicalGeometryRolledBack;"geometry-unsafe"!==e?.code&&("wall_model_client_outdated"===e?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===e?.code?(this._showToast(this._t("toast.conflict")),t||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)})),t&&this._reloadRejectedPhysicalWrite())})},500),this._wallChainSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>this._editorRuntimeOrThrow()._savePhysicalDialog(),this._deletePhysicalSelection=()=>this._editorRuntimeOrThrow()._deletePhysicalSelection(),this._confirmPartitionDelete=()=>this._editorRuntimeOrThrow()._confirmPartitionDelete(),this._confirmRoomDelete=e=>this._editorRuntimeOrThrow()._confirmRoomDelete(e),this._rebindPartitionOpening=()=>this._editorRuntimeOrThrow()._rebindPartitionOpening(),this._keepClosedAsPartitions=()=>this._editorRuntimeOrThrow()._keepClosedAsPartitions(),this._toggleServerPlans=async()=>this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._toggleServerPlans():this._editorRuntimeOrThrow()._toggleServerPlans(),this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=ar(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(this._editorRuntime)return this._editorRuntime._openSettingsDialog();this._ensureEditorRuntime().then(e=>{e&&this._openSettingsDialog()})},this._openSupportDialog=()=>{this._editorRuntime?this._editorRuntime._openSupportDialog():this._ensureEditorRuntime().then(e=>{e&&this._openSupportDialog()})},this._openPdfDialog=()=>{this._pdfRuntimeLoader.ensure().then(e=>{e&&(this._pdfDialog=!0,this.requestUpdate())})},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._editorRuntimeOrThrow()._openAlignDialog(),this._toggleOptimizeLivePositions=()=>this._editorRuntimeOrThrow()._toggleOptimizeLivePositions(),this._optimizeUndoBusy=!1,this._openBackupExport=()=>this._editorRuntimeOrThrow()._openBackupExport(),this._openRulesDialog=()=>this._editorRuntimeOrThrow()._openRulesDialog(),this._climateCache=null,this._gearPtCache=new WeakMap}requestUpdate(e,t,i){if("hass"===e&&this.hass&&this._liveRt){const e=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;if(!this._liveRt.hass(t,this.hass,e?{entityIds:e.entityIds}:null,()=>$g(this))&&!this._summary?.observeHassComposition())return}void 0!==e&&(this._terminalFrame=0),this._editorRuntime?._routeLiveEditorUpdate(e,t)||(this._liveRt?.clear(),super.requestUpdate(e,t,i))}_editorRuntimeOrThrow(){if(!this._editorRuntime)throw new Error("Houseplan editor runtime is not loaded");return this._editorRuntime}async _ensureEditorRuntime(){return this._editorRuntimeLoader.ensure()}async _ensureOnboardingRuntime(){return this._onboardingRuntimeLoader.ensure()}async _ensureIsoSceneRuntime(){return this._isoSceneRuntimeLoader.ensure()}_editorRuntimeStateChanged(e){clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,"loading"!==e?(this._editorRuntimeLoadingVisible=!1,this.requestUpdate()):this._editorRuntimeLoadingTimer=window.setTimeout(()=>{this._editorRuntimeLoadingVisible=!0,this.requestUpdate()},150)}async _requestMode(e,t=!0,i=!1){const n=++this._editorModeRequest;if(i&&(this._warmModeRequest=n,this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null),"view"===e||await this._ensureEditorRuntime()){if(n===this._editorModeRequest&&this.isConnected)return i?(this._adoptMode(e),this._warmRevivePending&&(clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmReviveDialog()),this.requestUpdate(),void this.updateComplete.then(()=>requestAnimationFrame(()=>requestAnimationFrame(()=>{if(this._warmModeRequest!==n||n!==this._editorModeRequest)return;const e=this._stageEl;this._lastValidStageSize=e&&e.clientWidth>0&&e.clientHeight>0?[e.clientWidth,e.clientHeight]:null,this._pendingRefitSize=null,this._warmModeRequest=0})))):void this._setMode(e,t);this._warmModeRequest===n&&(this._warmModeRequest=0)}else this._warmModeRequest===n&&(this._warmModeRequest=0)}get _layout(){return this._adoption.layout}set _layout(e){this._adoption.stageLocalLayout(e)}get _layoutRev(){return this._adoption.layoutRev}set _layoutRev(e){this._adoption.seedIdentity({layoutRev:e})}get _layoutContentFingerprint(){return this._adoption.layoutFingerprint}set _layoutContentFingerprint(e){this._adoption.seedIdentity({layoutFingerprint:e})}get _serverCfg(){return this._adoption.config}set _serverCfg(e){this._adoption.stageLocalConfig(e)}get _cfgRev(){return this._adoption.configRev}set _cfgRev(e){this._adoption.seedIdentity({configRev:e})}get _cfgContentFingerprint(){return this._adoption.configFingerprint}set _cfgContentFingerprint(e){this._adoption.seedIdentity({configFingerprint:e})}_seedDecorStyle(e){var t,i;if(t=Pl,i=this,Tl(e,Hl)&&"pending"===t.state()&&(t.art("",i),t.ensure()),this._decorStyleSeeded||!e)return;this._decorStyleSeeded=!0;const n=e.settings?.decor_default_style;n&&(this._decorStyle=function(e,t){if(!e||"object"!=typeof e)return{...t};const i=e,n="string"==typeof i.color&&i.color?i.color:t.color,r="string"==typeof i.fill_color&&i.fill_color?i.fill_color:t.fillColor,o=Number(i.width_cm);return{color:n,opacity:$r(i.opacity,t.opacity),widthCm:Number.isFinite(o)&&o>0?Math.max(.1,Math.min(100,o)):t.widthCm,fill:"boolean"==typeof i.fill?i.fill:t.fill,fillColor:r,fillOpacity:$r(i.fill_opacity,t.fillOpacity)}}(n,Sr))}get _canManageConfiguration(){return null!==this._serverCanWrite?this._serverCanWrite:!0===this.hass?.user?.is_admin}get _canEdit(){return this._norm&&this._canManageConfiguration}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}get _doubleFitEnabled(){return!("view"!==this._mode||this._vacFit||this._modeTransitionBusy||this._touchSequenceMultitouch||"steady"!==this._continuity.state||this._continuity.overlayBlocksInteraction)}_cameraState(){const e=this._viewOr(this._baseVb());return{zoom:this._zoom,viewBox:{...e}}}_normalizeCameraState(e){const t=this._cameraTransitionFit||Oi(this._baseVb(),this._stageAspect());return{zoom:Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,e.zoom)),viewBox:this._clampView({...e.viewBox},t)}}_applyCameraTransitionFrame(e){const t=this._normalizeCameraState(e.presented);e.presented=t,this._zoom=t.zoom,this._view={...t.viewBox},this._liveVp(!0)}_settleCameraTransition(e){const t=this._normalizeCameraState(e.to);this._zoom=t.zoom,this._view={...t.viewBox},this._cameraTransitionFit=null,"room"!==e.reason&&this._saveZoom(),this.requestUpdate()}_cancelCameraTransition(e=!1,t=!1){const i=this._cameraTransition.state?.reason,n=t&&this._cameraTransition.active?this._cameraTransition.presented?.zoom:void 0;this._cameraTransition.cancel(e),this._cameraTransitionFit=null,void 0!==n&&"room"!==i&&this._saveZoom()}_prepareCameraCommand(){this._bootSoftCancel(),this._modeTransitionBusy&&this._cancelModeTransition(!0),"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1))}_startCameraTransition(e,t,i,n){const r=this._cameraState(),o=this._cameraTransition.target;return(!o||!Yg(o,e))&&(Yg(r,e)?(this._cancelCameraTransition(!1),!1):(this._cameraTransitionFit={...t},this._cameraTransition.start(r,e,i,this._reducedMotion?0:n),!0))}_cssColor(e,t){const i=String(e||"").trim();if(!i)return t;const n=document.createElement("span");n.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(n);const r=getComputedStyle(n).color||t;return n.remove(),r}_currentModeVisual(e=this._mode){const t=this._modeTransition.presented||this._modeTransitionVisual;if(t)return{...t,viewport:{...t.viewport,viewBox:{...t.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const n=this.renderRoot.querySelector(".editorchrome"),r=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),s=this.renderRoot.querySelector(".hp-backdrop"),a=this.renderRoot.querySelector(".zoomwrap"),l=a?getComputedStyle(a).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:e,editorChromeHeight:"view"===e?0:n?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Lg(r,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===e?.35:1,backdropOpacity:s&&Number(getComputedStyle(s).opacity)||1,viewWeight:"view"===e?1:0,editorWeight:"view"===e?0:1,toolbarContentOpacity:"view"===e?0:1}}_viewForModeTarget(e,t,i,n,r){const o=Oi(this._baseVb(),n/r),s=Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,e)),a=o.w/s,l=o.h/s,c=t??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-a/2,y:h-l/2,w:a,h:l},o)}_targetStageColor(e){return"view"!==e?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(e){return"view"===e&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(e){return 1}_applyModeTransitionFrame(e){e.targetMode===this._mode&&(this._modeTransitionVisual=e.presented,this._view={...e.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(e){if(e.targetMode!==this._mode)return;const t=this._modeTransitionRequest;this._view={...e.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[e.to.stageWidth,e.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._modeTransitionBusy||e.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-e.to.stageWidth)>.5||Math.abs(i.clientHeight-e.to.stageHeight)>.5)){const e=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,e?e.x+e.w/2:void 0,e?e.y+e.h/2:void 0),this.requestUpdate()}const n=this.renderRoot.activeElement;(!n||!n.isConnected||!!n.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(e=!0){this._cancelCameraTransition(!1);const t=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(e),e&&t||(this._modeTransitionVisual=null)}_adoptMode(e){e!==this._mode&&(this._clearRoomFocus(!0),this._resetDeviceHitState()),this._cancelModeTransition(!1),this._mode=e,this._isoProjectionSnapshot=null,"view"!==e&&(this._editorChromeMode=e)}_commitViewModeAtomic(e,t,i,n){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=t,e){const r=this._stageEl?.clientWidth||e.stageWidth,o=Math.max(1,e.stageHeight+e.editorChromeHeight);this._view=this._viewForModeTarget(t,i,n,r,o),this._lastValidStageSize=[r,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(e,t,i,n,r,o){this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._mode!==i)return void(e===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const s=this.renderRoot.querySelector(".editorchrome-inner"),a="view"===i?0:s?.scrollHeight||0,l=Math.max(1,(this.panelHost?this.clientHeight:innerHeight)-Qg(this.renderRoot,this._stageEl,this.panelHost)),c=this._stageEl?.clientWidth||t.stageWidth,h=this._viewForModeTarget(n,r,o,c,l),d={presentedMode:i,editorChromeHeight:a,stageWidth:c,stageHeight:l,viewport:Lg(h,c),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const u=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,d,i,this._reducedMotion||u?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(e=this._model,t=this._loadOk){const i=this._config?.floor,n=function(e){if(!e.hasFloor)return{kind:"absent"};const t=e.floor;if("string"==typeof t)return t.length?e.spaceIds.includes(t)?{kind:"valid",id:t,source:"id"}:{kind:"invalid",reason:"unknown-id",value:t}:{kind:"invalid",reason:"empty-id",value:t};if("number"==typeof t){if(!Number.isFinite(t))return{kind:"invalid",reason:"non-finite-index",value:t};if(!Number.isInteger(t))return{kind:"invalid",reason:"fractional-index",value:t};if(t<0)return{kind:"invalid",reason:"negative-index",value:t};const i=e.spaceIds[t];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:t}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:t}}({spaceIds:e.map(e=>e.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||t?n:"number"==typeof i?"valid"===n.kind||"invalid"===n.kind&&"out-of-range-index"===n.reason?{kind:"pending",value:i}:n:"valid"===n.kind||"invalid"===n.kind&&"unknown-id"!==n.reason?n:{kind:"pending",value:i}}_canCommitSpace(e,t=!1){if(t||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===e}_commitSpace(e,t=!1){return!!this._canCommitSpace(e,t)&&(e!==this._space&&(this._clearRoomFocus(!0),this._resetDeviceHitState(),this._cancelDangerConfirm(),this._cancelCameraTransition(!1),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._editorRuntime?._clearFurniturePreview()),this._space=e,this._isoProjectionSnapshot=null,!0)}_slideTo(e,t){if(e===this._space)return!0;if(!this._canCommitSpace(e))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary?.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,this._restoreZoom(),i||(this._slide=t,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Xf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){Xf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(vv(e),this._tabDragRelease=e=>this._tabPointerUp(e),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:t,pointerId:e.pointerId,x:e.clientX,y:e.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(e,t,i){const n=this._model.map(e=>e.id),r=n.indexOf(i);if(r<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const s of o){const o=s.dataset.id||"";if(!o||o===i)continue;const a=s.getBoundingClientRect();if(ea.right||ta.bottom)continue;const l=n.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,n;const r=this._tabDropTargetAt(e.clientX,e.clientY,t.id);t.moved&&t.targetId===r?.targetId&&t.placement===r?.placement||(this._tabDrag={...t,moved:!0,targetId:r?.targetId||null,placement:r?.placement||null})}_tabPointerUp(e){const t=this._tabDrag;if(t&&t.pointerId!==e.pointerId)return;const i="pointerup"===e.type&&t?.moved?this._tabDropTargetAt(e.clientX,e.clientY,t.id):null;"pointerup"===e.type&&t?.moved&&this._suppressNextTabClick(),this._endTabDrag(),t?.moved&&i&&this._commitTabOrder(t.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(e){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(e)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(e,t){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const n=this._model.map(e=>e.id),r=function(e,t,i){const n=e.indexOf(t),r=e.indexOf(i);if(n<0||r<0||n===r)return e;const o=e.slice();return o.splice(n,1),o.splice(r,0,t),o}(n,e,t);if(r===n)return;const o=new Map(this._devices.map(e=>[String(e.id),String(e.area||"")])),s=function(e,t,i,n=()=>""){if(!i)return[];const r=[];for(const o of e){if(!o||!0===o.removed)continue;const e="string"==typeof o.id?o.id:"";if(!e)continue;if("string"==typeof o.space&&o.space)continue;const s=("string"==typeof o.area?o.area:"")||n(e)||"";s&&t[s]||r.push({id:e,space:i})}return r}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),n[0]||"",e=>o.get(e)||"");if(s.length){const e=new Map(s.map(e=>[e.id,e.space]));for(const t of i.markers||[]){const i=e.get(String(t.id));i&&(t.space=i)}}i.spaces=function(e,t){const i=new Map(t.map((e,t)=>[e,t]));return e.map((e,t)=>({space:e,index:t})).sort((e,t)=>(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)||e.index-t.index).map(e=>e.space)}(i.spaces||[],r),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(e){if(this._endTabDrag(),e===this._space)return;const t=this._model.map(e=>e.id),i=t.indexOf(this._space),n=t.indexOf(e);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(e,i>=0&&n0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const e=this._model.map(e=>e.id),t=e.indexOf(this._space);this._slideTo(e[(t+1)%e.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(e){this._wallUnionCacheValue=e,null===e&&this._wallUnionPool.clear()}get _glowClipCache(){return this._glowRuntimeState.clipCache}get _glowGeometryWarnings(){return this._glowRuntimeState.geometryWarnings}get _glowFeatherUnits(){return this._glowRuntimeState.featherUnits}set _glowFeatherUnits(e){this._glowRuntimeState.featherUnits=e}get _glowRenderedSources(){return this._glowRuntimeState.renderedSources}get _glowLastAppearance(){return this._glowRuntimeState.lastAppearance}get _glowFeatherSuspendUntil(){return this._glowRuntimeState.featherSuspendUntil}set _glowFeatherSuspendUntil(e){this._glowRuntimeState.featherSuspendUntil=e}get _glowFeatherResumeTimer(){return this._glowRuntimeState.featherResumeTimer}set _glowFeatherResumeTimer(e){this._glowRuntimeState.featherResumeTimer=e}get _glowSourceSeq(){return this._glowRuntimeState.sourceSeq}set _glowSourceSeq(e){this._glowRuntimeState.sourceSeq=e}get _touchSequenceMultitouch(){return this._touchClickGuard.sequenceMultitouch}_syncDangerConfirmLocaleGate(){return this._config&&this.hass?hp(this,mp,wp(this.hass,this._config.language)):"ready"}_dangerConfirmMissingSpace(){const e=this._model;if(!e.length)return!1;const t=this._fixedFloorState(e);return"pending"!==t.kind&&"invalid"!==t.kind&&!this._spaceModel()}_syncVersionRecovery(){this._versionRecovery.update({frontendVersion:Qf(tv),backendVersion:this._haIntegrationVersion,kiosk:!0===this._config?.kiosk,reducedMotion:this._reducedMotion})}_newContinuityController(){return new ac(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(dv,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(e){const t=this._view;if(!t)return null;const i=[t.x+t.w/2,t.y+t.h/2],n="iso"===e?lf(i):i;return{x:n[0],y:n[1]}}_convertProjectionView(e,t){if(e===t)return;this._clearRoomFocus(!0);const i=this._logicalViewCenter(e);this._view=null;const n=i?"iso"===t?af([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,n?.[0],n?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(e){if(!this._labsIso||"view"!==this._mode)return;const t=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:e},"iso"===e){this._ensureIsoSceneRuntime();const e=this._isoSceneKey();e&&this._isoFallback.delete(e),this._isoFallback.delete(`${this._space}|no-borders`),this._clearIsoInvalidFallback()}this._saveViewPreference(),this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i)}_hashSpace(){return Pf(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,this._configReloadAuthority.observeContext(Gu(this)),window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const e=hg(this.ownerDocument);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=oc(this.ownerDocument,this._pageVisibility),this._languageFailureUnsub?.(),this._languageFailureUnsub=function(...e){return()=>{for(const t of e)t()}}((t=()=>{this._showToast(this._t("toast.locale_load_failed"))},_p.add(t),()=>_p.delete(t)),function(e){return Al.add(e),()=>{Al.delete(e)}}(()=>this._showToast(this._t("toast.furniture_art_load_failed")))),super.connectedCallback(),this._summarySlot.connect(),this._ensureLiveRuntime().catch(()=>this.requestUpdate()),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{let t=!1;for(const i of e){for(const e of i.addedNodes)this._syncPointerHoverSubtree(e);const e=e=>{if(e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e;return t.matches(".devlayer, .devlayer *")||!!t.querySelector?.(".devlayer")};(e(i.target)||[...i.addedNodes,...i.removedNodes].some(e))&&(t=!0)}t&&this._invalidateDeviceHitGeometry()}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","data-id"]})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._syncVersionRecovery(),this._versionRecovery.connect(),cg(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>this._referencedContentUrls()),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(e){Ef.add(e);const t=Lf();return"undefined"==typeof window&&e(t),()=>{Ef.delete(e)}}(this._onLabsSnapshot),this._labsIso&&this._ensureIsoSceneRuntime(),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},nv)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._versionRecovery.disconnect(),this._configReloadAuthority.invalidateLifecycle(),this._liveRt?.dispose(),this._radarLive.stop(),this._editorRuntime?._disposeLiveEditor(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._languageFailureUnsub?.(),this._languageFailureUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._warmModeRequest=0,this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._summarySlot.disconnect(),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const e of this._activityRt.values())clearTimeout(e.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,this._editorRuntimeLoadingVisible=!1,this._modeTransition.dispose(),this._cameraTransition.dispose(),this._cameraTransitionFit=null,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),this._cancelDeviceDrag(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer),Pm(this._glowRuntimeState,this._glowRuntimeHost),this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._touchContacts.clear(),this._touchClickGuard.reset(),this._resetDeviceHitState(),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary?.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(e){if("Escape"===e.key&&this._vacFit){if(this._vacFit.busy)return;return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void e.stopPropagation()}if("Escape"===e.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm.busy||(this._vacCalConfirm=null));if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._pdfDialog)return void(this._pdfDialog=!1);if(this._supportDialog)return void this._editorRuntime?._closeSupportDialog();if(this._settingsDialog)return void(this._settingsDialog=null);if(this._summary?.closeDialogIfIdle())return;if(this._markerDialog)return void this._closeMarkerDialog();if(this._deviceInbox)return void(this._deviceInbox=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary?.hasOpenGroup)return e.preventDefault(),void this._editorSecondary?.closeGroup(!0)}const t=e.composedPath?.()||[e.target],i=t.some(e=>e?.matches?.('input, textarea, select, [contenteditable="true"]')),n=t.some(e=>e?.classList?.contains?.("editor-secondary")),r=e.ctrlKey||e.metaKey,o=e.key.toLowerCase(),s=/^[a-z]$/.test(o),a="z"===o||!s&&"KeyZ"===e.code,l="y"===o||!s&&"KeyY"===e.code,c=r&&(a&&e.shiftKey||l),h=r&&a&&!e.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry();if(("Delete"===e.key||"Backspace"===e.key)&&this._decorSel&&!i&&!n)return e.preventDefault(),void this._decorDeleteSel();const t="ArrowLeft"===e.key?[-this._gridPitch,0]:"ArrowRight"===e.key?[this._gridPitch,0]:"ArrowUp"===e.key?[0,-this._gridPitch]:"ArrowDown"===e.key?[0,this._gridPitch]:null;return!t||r||e.altKey||"select"!==this._decorTool||!this._decorSel||!this._decorList.some(e=>e.id===this._decorSel)||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag||i||n||this._editorSecondaryDialogBlocked?void("Escape"===e.key&&(e.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._furnPalette=null,this._furnCategory=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(e.preventDefault(),void this._decorNudge(t[0],t[1]))}if("devices"===this._mode){if((h||c)&&i)return;return c?(e.preventDefault(),void this._redoDevicePosition()):h?(e.preventDefault(),void this._undoDevicePosition()):void("Escape"===e.key&&this._deviceDrag&&(e.preventDefault(),this._cancelDeviceDrag()))}if(this._markup&&(!h&&!c||!i)){if(("Delete"===e.key||"Backspace"===e.key)&&this._physicalSel&&!i&&!n)return e.preventDefault(),void this._deletePhysicalSelection();if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===e.key)return this._physicalDrag||this._physicalRotate?(e.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(e.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(e.preventDefault(),void this._finishWallChain()):this._physicalSel?(e.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():("exit-tool"===this._resize?.escapeIdle()&&(this._tool="draw"),void this.requestUpdate())):"split"===this._tool?(e.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(e.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(e.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(e.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length)return this._contourClosed?(this._path=this._path.slice(0,-1),void(this._closingWallCm=null)):void(this._activeWallChainPartitionIds.length&&this._path.length>1?this._undoActiveWallPoint():this._path=this._path.slice(0,-1))}_undoActiveWallPoint(){const e=[...this._activeWallChainPartitionIds],t=e[e.length-1],i=this._spaceModel()?.partitions.find(e=>e.id===t),n=this._path[0]?[...this._path[0]]:null,r=this._path.slice(0,-1).map(e=>[...e]),o=this._wallChainSegmentCms.slice(0,-1),s=this._geometryHistory.undo();if(!s)return this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._wallChainRedo=[],void(this._path=n?[n]:[]);this._applyGeometryState(s.before,!0)?(this._activeWallChainId||=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=e.slice(0,-1),this._path=r.length?r:n?[n]:[],this._wallChainSegmentCms=o,i&&this._wallChainRedo.push({id:i.id,point:[...i.b],cm:i.cm}),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:s.name}))):this._geometryHistory.clear()}static async getConfigElement(){return await import("./editor-DCXyMNgY.js"),document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of rv.values())for(const t of e)clearTimeout(t.evict);rv.clear(),sv=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const n of rv.values())for(const r of n)e++,r.dlg&&(t++,i.push(r.dlg.kind));return{keys:rv.size,slots:e,dlgs:t,drafts:i}}setConfig(e){const t=this._config,i=!!t&&Object.prototype.hasOwnProperty.call(t,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...e};(i!==this._hasFixedFloor||t?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&e.default_floor&&this._commitSpace(e.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(cv)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(dv)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}if(this._labs=Lf(),this.isConnected&&this._labsIso&&this._ensureIsoSceneRuntime(),!this._summary?.applyLocalScaleForCurrentIdentity())try{const e=JSON.parse(localStorage.getItem("houseplan_card_kiosk_v1")||"null");this._kioskScale={icon:Bn(e?.icon),font:Bn(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(lv)||"null");this._adoption.restoreCached(e)&&(this._seedDecorStyle(this._serverCfg),this._cfgEpoch++,this._virtualLights=Nh(e.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1),this._syncVersionRecovery()}_warmAdopt(){if(this._config?.kiosk)return;const e=Rf(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),n=rv.get(e);if(!n||!n.length)return;const r=n.find(e=>e.owner===this._warmGen);if(r)return this._warmLongReturn=!!r.freed&&Date.now()-r.freed>=ic,clearTimeout(r.evict),r.evict=0,r.freed=0,r.live=!0,this._warmSlot=r,this._warmKey=e,r.frameFingerprint&&this._continuity.adoptCompleteFrame(r.frameFingerprint),void(!this._devices.length&&r.devices?.length&&(this._devices=[...r.devices]));const{slot:o,sure:s}=((e,t,i,n)=>{const r=e=>{const t=!!i&&e.place?.deref()===i;return t&&e.idx===n?4:e.live?0:t?3:2};let o=null,s=0,a=0,l=null;for(const i of e){if(i.owner===t)continue;l=i;const e=r(i);e<=0||(e>s?(o=i,s=e,a=1):e===s&&a++)}return!o||a>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(n,this._warmGen,t,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=ic,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},nv)),this._warmKey=e,s?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=t?new WeakRef(t):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},n.push(this._warmSlot),this._warmTrim(n)))}_warmIdx(e){const t=e?.children;if(!t)return-1;for(let e=0;e4;){const t=e.findIndex(e=>!e.live);if(t<0)break;clearTimeout(e[t].evict),e.splice(t,1)}}_warmScheduleEvict(e,t){if(clearTimeout(e.evict),!(e.dlg||e.vp&&"view"!==e.vp.mode))return;const i=e.freed,n=e.owner;e.evict=window.setTimeout(()=>{if(e.evict=0,e.freed!==i||e.owner!==n)return;var r;e.dlg=null,e.vp=(r=e.vp)&&"view"!==r.mode?{...r,mode:"view",zoom:r.snap?.space===r.space?r.snap.zoom:r.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:r,e.frameFingerprint="";const o=rv.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},sv+250)}_warmAdoptViewport(e){const t=this._warmVp;if(!t||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(e=>e.id===t.space)||"valid"===i.kind&&i.id!==t.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(t.space,!0),this._navApplied=!0;const n="view"!==t.mode&&this._canEdit&&!e.kiosk?t.mode:"view";this._adoptMode("view"),this._pendingNavMode="view"===t.mode||this._canEdit||e.kiosk?null:t.mode,this._zoom=t.zoom;const r=this._effectiveProjection(),o=r===t.projection&&this._labsIso===t.activeLabsIso;if(this._view=o&&t.view?{...t.view}:null,this._viewModeSnap=o&&t.snap?{...t.snap}:null,!o&&t.logicalCenter){const e="iso"===r?af([t.logicalCenter.x,t.logicalCenter.y],0):[t.logicalCenter.x,t.logicalCenter.y];this._applyView(t.zoom,e[0],e[1])}var s;this._tool="opening"===(s=function(e){return"partition"===e?"draw":e}(s=t.tool))?"draw":"string"==typeof s&&Mf.has(s)?s:"draw",this._decorTool=t.decorTool,this._showHidden=t.showHidden,this._showFar!==t.showFar&&(this._showFar=t.showFar,this._frame=null),this._selId=t.selId,this._resize?.restoreSelection(t.rszSel),this._decorSel=t.decorSel,this._warmVpArmed=!0,"view"!==n&&this._requestMode(n,!1,!0)}_warmPatch(e,t=!1){if(this._config?.kiosk)return;const i=Rf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!t)return;const e=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:this._warmIdx(e),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const n=rv.get(i)||[];for(n.push(this._warmSlot),rv.set(i,n),this._warmTrim(n);rv.size>8;){const e=rv.keys().next().value;if(void 0===e||e===i)break;for(const t of rv.get(e)||[])clearTimeout(t.evict);rv.delete(e)}}Object.assign(this._warmSlot,e)}}_warmViewportState(){const e=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:e,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(e),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._resize?.selectedRoomId,decorSel:this._decorSel}}_warmDialogState(){const e=(e,t)=>({kind:e,space:this._space,mode:this._mode,data:t});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?e("openingInfo",this._openingInfo.id):this._infoCard?e("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:e("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:e("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:e("marker",this._markerDialog):this._openingDialog?e("opening",this._openingDialog):this._backdropDialog?e("backdrop",this._backdropDialog):this._decorShapeDialog?e("decorShape",this._decorShapeDialog):this._decorTextDialog?e("decorText",this._decorTextDialog):this._roomDialog?e("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempMin:this._roomTempMin,tempMax:this._roomTempMax,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:e("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const e={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices,hdrH:this._hdrH};if(this._warmRevivePending||(e.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const t=this.parentNode;e.place=t?new WeakRef(t):null,e.idx=this._warmIdx(t)}this._warmPatch(e)}_warmReviveDialog(){const e=this._warmSlot;if(this._warmReviveTimer=void 0,!e||!e.dlg)return void(this._warmRevivePending=!1);const t=e.dlg,i=e.freed;if(t.mode===this._mode||"view"===t.mode||this._warmVp?.mode!==t.mode||this._editorRuntime){if(this._warmRevivePending=!1,e.dlg=null,e.freed=0,clearTimeout(e.evict),e.evict=0,i&&!(Date.now()-i>sv)&&t.space===this._space&&t.mode===this._mode){switch(t.kind){case"space":this._spaceDialog={...t.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...t.data,busy:!1};break;case"settings":this._settingsDialog={...t.data,busy:!1};break;case"rules":this._rulesDialog={...t.data,busy:!1};break;case"opening":this._openingDialog={...t.data};break;case"backdrop":this._backdropDialog={...t.data};break;case"decorShape":this._decorShapeDialog={...t.data};break;case"decorText":{this._decorTextDialog={...t.data};const e=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:e,end:e};break}case"room":{const e=t.data;this._roomEditId=e.editId,this._roomFill=e.fill,this._roomCustomFill=e.customFill||null,this._roomTempMin=e.tempMin||"",this._roomTempMax=e.tempMax||"",this._roomTempSrc=e.tempSrc,this._roomHumSrc=e.humSrc,this._roomSrcOpen=e.srcOpen,this._roomSrcFilter=e.srcFilter,this._roomNameScale=e.nameScale,this._roomLabelScale=e.labelScale,this._areaSel=e.areaSel,this._nameSel=e.nameSel,this._pendingSplit=e.pendingSplit,this._wallFaceBatch=e.wallFaceBatch||null,this._path=e.path,this._wallFaceBatch&&(this._activeWallChainId=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=[...this._wallFaceBatch.activePartitionIds],this._wallChainSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const e=this._devices.find(e=>e.id===t.data);e&&(this._infoCard=e);break}case"openingInfo":{const e=(this._curSpaceCfg?.openings||[]).find(e=>e.id===t.data);e&&(this._openingInfo=e);break}}this.requestUpdate()}}else this._warmRevivePending=!0}_cacheSnapshot(){if(this._serverCfg)try{this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const n=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(Bh).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>n.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev);const e=this._adoption.snapshot(function(e){return{rev:e.rev,config_rev:e.configRev,off:[...e.off].sort()}}(this._virtualLights));e&&localStorage.setItem(lv,JSON.stringify(e))}catch{}}_beginContinuityCandidate(e,t,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(e,i))}_continuityStageValid(){const e=this._stageEl;return!!e&&e.clientWidth>0&&e.clientHeight>0}_versionReloadSafetySnapshot(){return xg(this)}_continuityAssetsReady(){if(!this._model.length)return!1;const e=this._model.length?this._spaceModel():null;return!e?.bg?.href||this._signer.isReady(this.hass,e.bg.href)}_initialSpaceSelection(e,t=this._loadOk){const i=this._fixedFloorState(e,t);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(e){const t=new Set(e.spaceIds.filter(e=>!!e));if(!t.size)return{id:null,source:"none"};const i=[["hash",!1===e.acceptHash?null:e.hashSpace],["current",e.preserveCurrent?e.currentSpace:null],["saved",e.savedSpace],["default",e.defaultSpace],["first",e.spaceIds[0]]];for(const[e,n]of i)if(n&&t.has(n))return{id:n,source:e};return{id:null,source:"none"}}({spaceIds:e.map(e=>e.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(e,t=this._loadOk){const i=this._initialSpaceSelection(e,t);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(e,t=this._space){const i=Xa(e),n=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==n.kind)return"";const r=this._initialSpaceSelection(i,!0).id||(i.some(e=>e.id===t)?t:i[0]?.id);return i.find(e=>e.id===r)?.bg?.href||""}_visualFrameFingerprint(){const e=this._stageEl,t=e?[e.clientWidth,e.clientHeight]:[0,0];return cc([this._cfgRev,this._adoption.currentConfigFingerprint(),this._layoutRev,this._adoption.currentLayoutFingerprint(),this._space,this._mode,this._view,t,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const e=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==e)return this._stagedDeviceSnapshotToken=e,void this.requestUpdate();this._continuityPaintToken!==e&&(this._continuityPaintToken=e,this._continuity.candidateReady(e)&&this._continuity.commitAfterPaint(e,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(e,t){this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const e="connection"===this._continuity.recoveryReason;return j`
e.stopPropagation()} @click=${e=>e.stopPropagation()} @@ -356,7 +356,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 aria-label=${this._t("editor.loading_aria")}> ${this._t("editor.loading")} -
`:G}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}getGridOptions(){return{columns:"full"}}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],n=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(n?n[0]+"/"+n[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Ya(e).map((t,i)=>{const n=e.spaces[i]?.plan_url;return t.bg&&n?{...t,bg:{...t.bg,href:n}}:t})}_spaceModel(){return this._hasFixedFloor?bc(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return bc(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0,this._clearRoomFocus(!0);for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._deviceDrag=null,this._resetDeviceHitState(),this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary?.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit))return;const e=this._serverCfg,t=Jd({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const n of t){const t="h"+n.slice(n.indexOf(":")+1);e.markers.push({id:t,binding:n,hidden:!0}),i.push(n.slice(n.indexOf(":")+1))}const n={...e.settings||{},filter_seeded:!0};delete n.show_all,i.length&&Array.isArray(n.new_device_ids)&&(n.new_device_ids=n.new_device_ids.filter(e=>!i.includes(e))),e.settings=n,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Ee(e)),this._rulesCompiled}get _fillColors(){return gn(this._settings)}get _excluded(){return su(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,this._summary?.willUpdate(),e.has("hass")&&this._configReloadAuthority.observeContext(Uu(this)),e.has("_serverCfg")){const e=this._cfgEpochPreservedConfig===this._serverCfg;this._cfgEpochPreservedConfig=null,e||this._cfgEpoch++,this._renderLife.invalidate()}if(this._syncEmptySpaceState(),this._dangerConfirm&&(this._dangerConfirmMissingSpace()||"warm"===this._syncDangerConfirmLocaleGate())&&this._cancelDangerConfirm(),e.has("hass")&&this.hass){const t=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;this._renderLife.observe(e.get("hass"),this.hass,t?{entityIds:t.entityIds}:null,()=>Sg(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._summary?.updated(),this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._syncRadarLive(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>{this._invalidateDeviceHitGeometry(),this._refitView(),requestAnimationFrame(()=>this._summary?.resized())}),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=Jg(this.renderRoot,e,this.panelHost);null!==t&&(t>=0&&t!==this._hdrH&&(this._hdrH=t),t>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:t,stageH:e.clientHeight}))};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary?.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&this._canManageConfiguration&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,n=t.level??1e9;return i!==n?i-n:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptConfigCapabilities(e){wg(this,e)}_syncRadarLive(){const e=this._serverCfg?.settings?.radar,t=(this._serverCfg?.markers||[]).some(e=>Mg(e,this._space));this._radarLive.sync(this._space,1===this._haRadarStage1Api&&"view"===this._mode&&!1!==e?.show_live&&t&&"hidden"!==this.ownerDocument.visibilityState)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await hm(this.hass,am(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptAuthoritative(e){return Bu(this,e)}_rollbackOptimistic(e){const t=this._adoption.rollbackOptimistic(e);return t&&this.requestUpdate(),t}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}_getAuthoritativeConfig(){return e=this,async function(e,t){const i=await e();return t(i),i}(()=>e.hass.callWS({type:"houseplan/config/get"}),t=>wg(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;let i=!1;const n=()=>{i=!0,this._regSignature="",this._maybeRebuildDevices()};try{const[i,r]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this._adoptAuthoritative({cfgResp:i,layResp:r,reason:"structural-response",profile:"reload",beforeAdopt:()=>{this._connectionWasLost=!1,this._serverStorage=!0},afterAdopt:()=>{this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,n()}})).status)return;this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(sv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,i||n(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],n=(n,r,o,s)=>{n()||i.push(async()=>{const i=await e.subscribeEvents(s,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!n()?r(i):i?.()})};if(n(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),n(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),n(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),n(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=qh(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const r=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=r,r.finally(()=>{this._liveSyncAttempt===r&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){return Gu(this,e,t)}_scheduleLoadRetry(e=!1){if(void 0!==this._loadRetryTimer)return;const t=Math.min(8e3,500*2**Math.min(4,Math.max(1,this._loadTries-7)));this._loadRetryTimer=window.setTimeout(()=>{this._loadRetryTimer=void 0,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}async _ensureLiveRuntime(){if(this._liveRt)return;const e=await import("./live-interaction-runtime-CxW-k-p_.js");this._liveRt=new e.LiveRuntime(this),this.isConnected&&this.requestUpdate()}_liveVp(e=!1){this._liveRt?this._liveRt.viewport(e):this.requestUpdate()}_syncLiveHover(){this._liveRt?this._liveRt.hover():this.requestUpdate()}_flushHa(){this._liveRt?.take()&&(this._terminalFrame=2,super.requestUpdate())}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._renderLife.invalidate(),this._areaSnapshotCleanupCandidates.clear(),this._planHassMemo=null,this._haRegistryRelease=Qh(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return td(this.hass)}get _planHass(){const e=this._haRegistry,t=nd(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=od(this.hass,e),r=sd(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:n,full:r},n}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+Qm)>e?1:0)).join("|"),i=Hh(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const n=this._planHass,r=new Map,o=new Map,s=new Set(["sun.sun"]);for(const e of this._summary?.entityIds()||[])s.add(e);this._vacFit?.source&&s.add(this._vacFit.source);const a=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void s.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?a.add(n):"entity"===i&&s.add(n)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of ui(t))s.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Ki(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,Qi(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!Xd(n,e,Yd(this._markers))))}const h=Id(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(m_(e.id,t),d_(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,n),i=t?qc(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=sh(e.id,e.marker?.vacuum??null,e.space,t),a=lh({routes:s,observed:ch(s,[t],t=>this._vacObservedMapId(e,t,n)),spaceIds:new Set(this._model.map(e=>e.id))});o.set(`vacuum:${e.id}`,{source:t,telemetry:i,routes:s,resolution:a,mapId:i?this._vacMapId(e,i,n):null,runtime:r?{trail:r.trail,lastTs:r.lastTs,moving:r.moving,jump:r.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=__({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,positions:(u=this._model.length>0,p=this._devices,_=e=>this._livePos(e),u?new Map(p.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:s,deviceIds:a,areaIds:l});var u,p,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _renderVacuumDevices(){return this._renderDeviceSnapshot?.vacuumDevices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return cd(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const{registry:e,bindings:t}=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e));return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&mv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else mv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_referencedContentUrls(){const e=On(this._serverCfg);for(const t of this._decorAssets.values())e.add(t.url);return e}_resign(){this._signer.resign(this.hass,this._referencedContentUrls())}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){this._adoption.noteLayoutRevision(e?.rev)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,n]of e)null===n?delete i[t]:i[t]=n;this._adoption.adoptMergedLayout(i,t,()=>{this._cancelDeviceDrag(),this._devicePositionHistory.clear()}),this._canOptimizeUndo=!!t?.can_optimize_undo,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_persistLocalLayout(){this._layout=yo(no(this._layout)),localStorage.setItem(sv,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=nd(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+bp(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const n=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=eu({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const r=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+r.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const n of r)i.set(n,cd(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=ld(),i=Date.now();for(const[n,r]of e)"active"===r.kind?t[n]={kind:"active",ts:i}:"ha_disabled"===r.kind&&(t[n]={kind:"ha_disabled",reason:r.reason,ts:i});const n=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Vh=n;try{localStorage.setItem(Gh,JSON.stringify(n))}catch{}}(i),this._haBindingCacheKey=o}let s=null;if(t.authoritative&&(s=this._resolveAreaRelocations(t),this._areaRelocationIds=new Set(s.relocateIds),this._areaRelocationIds.size)){this._cancelDeviceDrag();const e=this._areaRelocationIds;this._devicePositionHistory.removeWhere(({before:t,after:i})=>e.has(t.deviceId)||e.has(i.deviceId));const t=this._markerDialog;if(t?.devId&&!t.roomTouched&&this._areaRelocationIds.has(t.devId)){const e=this._devices.find(e=>e.id===t.devId);e&&(this._markerDialog={...t,room:e.marker?.room_id?`${e.space}#@${e.marker.room_id}`:e.space&&e.area?`${e.space}#${e.area}`:""})}}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),s&&this._syncAreaRelocations(s),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const l=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==n.get(e.id));l&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._deviceDrag&&"ha_disabled"===this._devices.find(e=>e.id===this._deviceDrag.id)?.bindingStatus?.kind&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear()),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(_v(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=Z_(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])X_(t)&&Number.isFinite(r)&&i.has(t)&&n.set(t,r);const r=new Set,o=new Set;for(const t of e.markers||[])t.removed||(Y_(t.id)&&r.add(t.id),X_(t.binding)&&o.add(t.binding));const s=new Set(Object.keys(e.registryDevices||{})),a=new Set(Object.keys(e.registryEntities||{})),l=new Set(Object.keys(e.liveStates||{})),c=new Map;for(const[e,i]of Object.entries(t)){const t=c.get(i.binding)||[];t.push(e),c.set(i.binding,t)}const h=new Set;let d=!1;for(const[t,i]of c){const[c,u]=im(t);if(o.has(t)||i.some(e=>r.has(e))||("device"===c?s.has(u):a.has(u)||l.has(u))){n.delete(t);continue}const p="device"===c?s.size>0:a.size>0;if(!e.authoritative||!p)continue;const _=n.get(t);if(void 0!==_){if(_!==e.revision)for(const e of i)h.add(e)}else n.set(t,e.revision),d=!0}return{removeIds:h,candidates:n,needsConfirmationRefresh:d}}({snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,revision:e.revision,registryDevices:e.devices,registryEntities:e.entities,liveStates:this.hass?.states,markers:this._markers,previousCandidates:this._areaSnapshotCleanupCandidates});return this._areaSnapshotCleanupCandidates=t.candidates,t.needsConfirmationRefresh&&this._canEdit&&ed(this.hass),nm({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:uv})}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:n,known:r}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),n=e.filter(e=>!i.has(e));return{fresh:n,known:n.length?[...t,...n]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||n.length){const e=[...new Set([...i.new_device_ids||[],...n])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:r,new_device_ids:e}},this._saveConfig()}}_syncAreaRelocations(e){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit&&this._haRegistry.authoritative))return;const t=e.decisions.filter(e=>e.updateSnapshot||e.removeSnapshot);if(!t.length)return;const i=ac({snapshot:Z_(this._settings.marker_area_snapshot),decisions:t});i!==this._areaRelocationSyncKey&&(this._areaRelocationSyncKey=i,this._areaRelocationWrite=this._areaRelocationWrite.catch(()=>{}).then(async()=>{if(!this._serverCfg||!this._haRegistry.authoritative)return;const e=this._resolveAreaRelocations();this._areaRelocationIds=new Set(e.relocateIds);const t=new Set,i=new Map;let n=!1;for(const r of e.decisions){if(!r.relocate)continue;const e=mg(this._layout,r.id);try{await this._persistDevicePlacement(r.id,null),t.add(r.id),e&&i.set(r.id,e),this._areaRelocationIds.delete(r.id)}catch(t){n=!0,this._layout=gg(this._layout,r.id,e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}}const r=this._settings,o=function(e,t,i=new Set){const n=Z_(e);for(const e of t.decisions)e.removeSnapshot?delete n[e.id]:e.updateSnapshot&&e.binding&&e.area&&(e.relocate&&!i.has(e.id)||(n[e.id]={binding:e.binding,area:e.area}));return n}(r.marker_area_snapshot,e,t),s=[...new Set([...Array.isArray(r.new_device_ids)?r.new_device_ids:[],...t])],a=ac(o)!==ac(Z_(r.marker_area_snapshot)),l=ac(s)!==ac(Array.isArray(r.new_device_ids)?r.new_device_ids:[]);if(a||l){const e=r.marker_area_snapshot,n=r.new_device_ids,a={...this._serverCfg,settings:{...r,marker_area_snapshot:o,...l?{new_device_ids:s}:{}}};this._setAreaLifecycleConfig(a);try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.cancel(),await this._writeConfig()}catch(r){const a=this._settings;if(ac(a.marker_area_snapshot)===ac(o)&&ac(a.new_device_ids)===ac(l?s:n)){const t={...a};void 0===e?delete t.marker_area_snapshot:t.marker_area_snapshot=e,void 0===n?delete t.new_device_ids:t.new_device_ids=n;const i={...this._serverCfg,settings:t};this._setAreaLifecycleConfig(i),this._adoption.refreshConfigFingerprint()}for(const e of t)this._areaRelocationIds.add(e);const c=new Set;for(const[e,t]of i)try{await this._persistDevicePlacement(e,t)}catch(t){c.add(e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}this._areaRelocationSyncKey="",this._regSignature="";if("conflict"===(r&&"object"==typeof r&&"code"in r?r.code:void 0)?(this._showToast(this._t("toast.conflict")),await this._reloadConfigOnly(!0)):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(r)})),c.size&&this._serverCfg){const e=this._settings,t=[...new Set([...Array.isArray(e.new_device_ids)?e.new_device_ids:[],...c])],i={...this._serverCfg,settings:{...e,new_device_ids:t}};this._setAreaLifecycleConfig(i);try{await this._writeConfig()}catch(e){this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)}))}}}}n&&(this._areaRelocationSyncKey=""),this.requestUpdate()}))}get _newIds(){const e=this._settings.new_device_ids;return new Set([...Array.isArray(e)?e:[],...this._areaRelocationIds])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const n=Nd(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return Ii(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),n=Math.min(...t),r=Math.min(...i);return{x:n,y:r,w:Math.max(...t)-n,h:Math.max(...i)-r}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const n=t/100*wl(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const r=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!r.length)continue;const o=this._roomBounds(t),s=.1*Math.min(o.w,o.h),a=o.w-2*s,l=o.h-2*s,c=Math.max(1,Math.round(Math.sqrt(r.length*a/Math.max(l,1)))),h=Math.ceil(r.length/c),d=a/c,u=l/Math.max(h,1),p=r.map((e,t)=>({x:o.x+s+d*(t%c+.5),y:o.y+s+u*(Math.floor(t/c)+.5)}));Ei(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=il(p[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._areaRelocationIds.has(e.id)?void 0:this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*uv,y:i.y*uv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?il(bl(t)):{x:500,y:500}}_devicePlacementForCanvas(e,t,i){if(!this._norm)return{x:Math.round(t),y:Math.round(i)};const n=this._gridPitch,r=Math.round(t/n)*n,o=Math.round(i/n)*n;return{s:e.space,x:rl(r/uv),y:rl(o/uv)}}_previewDevicePlacement(e,t){this._layout=gg(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null,this._deviceHits.cancel(e.pointerId);try{e.source?.hasPointerCapture?.(e.pointerId)&&e.source.releasePointerCapture(e.pointerId)}catch{}return this._previewDevicePlacement(e.id,e.before),!0}async _persistDevicePlacement(e,t){if(this._layout=gg(this._layout,e,t),this._serverStorage){let i=null,n=!1;try{let r;if(null===t)i=null,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/delete",device_id:e});else{const t=vo(this._layout[e]);ac(t)!==ac(this._layout[e])&&(this._layout={...this._layout,[e]:t}),i=t,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t})}this._noteLayoutRev(r),this._adoption.refreshLayoutFingerprint(),this._cacheSnapshot()}finally{n&&this._sentPos.get(e)===i&&this._sentPos.delete(e)}return}this._persistLocalLayout()}_devicePositionStateValid(e){const t=this._devices.find(t=>t.id===e.deviceId);return!!t&&t.space===e.spaceId&&"ha_disabled"!==t.bindingStatus?.kind&&!!this._spaceModelById(e.spaceId)}async _runDevicePositionHistory(e){if(this._cancelDeviceDrag()||this._devicePositionBusy)return;const t="undo"===e?this._devicePositionHistory.undo():this._devicePositionHistory.redo();if(!t)return;const i="undo"===e?t.before:t.after;if(!this._devicePositionStateValid(i))return this._devicePositionHistory.clear(),this._showToast(this._t("history.device_stale")),void this.requestUpdate();const n=mg(this._layout,i.deviceId);i.spaceId!==this._space&&(this._commitSpace(i.spaceId),this._restoreZoom()),this._devicePositionBusy=!0,this._previewDevicePlacement(i.deviceId,i.placement);try{await this._persistDevicePlacement(i.deviceId,i.placement),this._showToast(this._t("undo"===e?"history.undone":"history.redone",{name:t.name}))}catch(t){this._previewDevicePlacement(i.deviceId,n),"undo"===e?this._devicePositionHistory.redo():this._devicePositionHistory.undo(),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}finally{this._devicePositionBusy=!1,this.requestUpdate()}}_undoDevicePosition(){this._runDevicePositionHistory("undo")}_redoDevicePosition(){this._runDevicePositionHistory("redo")}_savePos(e,t,i){this._spaceModelById(e.space)&&(this._layout=gg(this._layout,e.id,this._devicePlacementForCanvas(e,t,i)),this._dirtyPos.add(e.id),this._persistLayout())}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const n=i?null:this._renderDeviceSnapshot?.presentations.get(m_(e.id,t));return n||d_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,h_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=Ld(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Hd(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Vn(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._kiosk&&(this._cyclePausedUntil=Math.max(this._cyclePausedUntil,Date.now()+6e4)),this._nativeMoreInfoEntity=e,_v(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._roomPointer=null,this._doubleFit.clear(),this._deviceHits.clearPointers()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_invalidateDeviceHitGeometry(){this._deviceHits.invalidate()}_resetDeviceHitState(){this._deviceHits.reset(this.renderRoot)}_deviceHitOwnerAt(e,t){return"view"!==this._mode&&"devices"!==this._mode?null:this._deviceHits.at(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForPointerEvent(e,t){return this._deviceHits.pointer(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForClickEvent(e,t){return this._deviceHits.click(this.renderRoot,this._renderDevices,this._space,e,t)}_showDeviceTip(e,t){this._liveRt?this._liveRt.devicePointerTip(e,t):this._ensureLiveRuntime().then(()=>this._liveRt?.devicePointerTip(e,t))}_showDeviceFocusTip(e,t){const i=e.currentTarget;this._liveRt?this._liveRt.deviceFocusTip(i,t):this._ensureLiveRuntime().then(()=>this._liveRt?.deviceFocusTip(i,t))}_hideDeviceFocusTip(e){this._liveRt?.deviceBlur(e)}_clearPointerHover(){this._liveRt?this._liveRt.pointerLeave():this._clearTransientHover()}_ctxDevice(e,t){"view"===this._mode&&(t=this._deviceForPointerEvent(e,t),e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if(e.stopPropagation(),t=this._deviceForClickEvent(e,t),this._deviceDrag?.moved||this._suppressClick||this._holdFired)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const n=Ru(i.tapAction,i.primary?.split(".")[0]);if("none"===n)return;const r=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===n){const e=this._toggleIntent(i);if(!e)return;if(!Fu(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Fu(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=qh(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:n}=t;this._startDevicePressFeedback(i.id),this.hass.callService(n.domain,n.service,n.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},n=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const r=this._toggleConfirmationLines(e);if(!r.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:n}),lines:r,initialIntent:e,deviceId:i.id,exec:()=>{const n=this._devices.find(e=>e.id===i.id),r=n?this._toggleIntent(n):null;r&&!Fu(r)&&this._showUnavailableToggleTargets(r)||(r&&Iu(e,r)?t(r):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===n)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===n){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),n=this.hass.states[e];if(!t||!n)return void this._showToast(this._t("toast.run_target_missing"));const o=n.attributes?.friendly_name||e;return void r(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===n&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Fu(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!zu.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!zu.has(n.reason))continue;const e=String(n.name||n.entityId||n.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const n=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),r=Number.isFinite(n)?Math.max(.95,Math.min(1,n)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(r)},{scale:"0.95",offset:.5},{scale:"1"}],s=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,s);const a=()=>{this._devicePressAnimations.get(e)===s&&this._devicePressAnimations.delete(e)};s.addEventListener("finish",a,{once:!0}),s.addEventListener("cancel",a,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return wp(bp(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex"),confirm:this._t("color_picker.confirm")}}_help(e){return this._editorRuntimeOrThrow()._help(e)}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const n=this._pos(i);t.push({minX:n.x,minY:n.y,maxX:n.x,maxY:n.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,n=Math.cos(i)*e.rlen/2,r=Math.sin(i)*e.rlen/2,o=ll([[e.rx-n,e.ry-r],[e.rx+n,e.ry+r]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){if("image"===e.kind&&!this._decorAssets.has(e.asset_id)&&"decor"!==this._mode)continue;const n=ll("line"===e.kind?[[e.x1*uv,e.y1*i],[e.x2*uv,e.y2*i]]:"text"===e.kind?[[e.x*uv,e.y*i]]:Fr({x:e.x*uv,y:e.y*i,w:e.w*uv,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=ll(i);e&&t.push(e)}}return pl(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:uv,h:uv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const n=fl(this._contentItems(e));let r=n.all||yl(e),o=this._showFar?r:n.core||yl(e);return t&&t.id===e.id&&i&&t.grow&&(o=pv(t.rect,o),r=pv(t.all,r)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:r,outliers:n.outliers},this._frame}_isoSource(){const e=this._isoSceneRuntime;if(!e)return null;const t=this._spaceModel();if(!t)return null;const i=this._spaceWalls,n=this._openCuts(),r=this._openingsR;return e.createIsoStructuralSource({space:t,walls:i,openCuts:n,openings:r,partitionCuts:()=>this._partitionOpeningCuts(t),roomOpenings:()=>this._roomWallOpeningInputs(r,t),cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,coordinateScale:uv,onBuild:()=>{this._isoStructuralBuildCount+=1}})}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return this._isoInvalidKey()}}_isoInvalidKey(){return`${this._space}|invalid|${this._cfgEpoch}`}_clearIsoInvalidFallback(e){const t=`${this._space}|invalid|`;for(const i of this._isoFallback)i.startsWith(t)&&i!==e&&this._isoFallback.delete(i)}_isoScene(e=this._isoSource()){const t=this._isoSceneRuntime;if(!t||!e)return null;let i=this._frameOf().rect;const n=this._spaceDisplayForRender(),r=this._spaceModel();if(r&&n.showNames)for(const e of r.rooms)if(e.name){const t=this._labelPos(e,r.id);i=pv(i,{x:t.x,y:t.y,w:0,h:0})}const o=t.resolveIsoScene({source:e,cache:this._isoGeometryCache,cellCm:this._cellCm,liveFrame:i});if(!r||!n.showBorders)return o;const s=this._config?.icon_size??2.5,a=s>8?2.5:s,l=this._stageEl?.getBoundingClientRect?.()??null,c=l?.height?l.width/l.height:o.frame.w/o.frame.h,h=Oi([o.frame.x,o.frame.y,o.frame.w,o.frame.h],c),d=this._isoOverlayScene(r,this._renderDevices.filter(e=>e.space===r.id&&!e.hidden),h,n,t.resolveIsoDecorationLayers(n),o,a,w_(a),n.showLqi??this._config?.show_signal??!0,!1),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>Oi([e.x,e.y,e.w,e.h],c)});return u?{...o,frame:u.bounds,overlayFitEntries:d.entries}:o}_latchIsoFallback(e,t){if(this._isoFallback.has(e))return;this._isoFallback.add(e);const i=e.includes("|invalid|")?"invalid":e.split("|").pop()||"invalid";console.warn("HOUSEPLAN ISO FALLBACK: #89/#160",yf("structural",i,!0))}_effectiveProjection(){if(this._isoProjectionSnapshot)return this._isoProjectionSnapshot;const e=e=>this._isoProjectionSnapshot=e,t=()=>("iso"===this._renderProjection&&(this._cancelCameraTransition(!1),this._view=null,this._viewModeSnap=null),e("flat"));if(this._renderIsoScene=null,"iso"!==this._desiredProjection||!this._model.length||!this._isoSceneRuntime)return e("flat");if(!this._spaceDisplayForRender().showBorders)return this._isoFallback.has(`${this._space}|no-borders`)?t():e("iso");let i=this._isoInvalidKey();if(this._clearIsoInvalidFallback(i),this._isoFallback.has(i))return t();try{const n=this._isoSource();if(!n)return e("flat");if(i=n.key,this._isoFallback.has(i))return t();const r=this._isoScene(n);return r?this._isoFallback.has(r.key)?t():(this._renderIsoScene=r,e("iso")):e("flat")}catch(e){return this._latchIsoFallback(i,e),t()}}_scenePoint(e){return"iso"===this._renderProjection?sf(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=af([e.x,e.y]),i=af([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_isoOverlayScene(e,t,i,n,r,o,s,a,l,c=!0){const h=this._isoSceneRuntime;return h&&r?.structural&&o?h.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,wallSilhouettes:o.wallSilhouettes,resolveCollisions:c,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:"view"===this._mode?this._kioskScale.icon:1,kioskFontScale:"view"===this._mode?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),positionOf:e=>this._pos(e),presentationOf:(e,t)=>this._devicePresentation(e,t),labelPositionOf:(e,t)=>this._labelPos(e,t),labelScaleOf:e=>this._labelScale(e),openingEntityAvailable:e=>this._renderOpeningEntityAvailable(e),openingWallIndex:()=>this._openingWallIndexFor(e,this._openCuts()).value}):null}_baseVb(e=this._effectiveProjection(),t=this._renderIsoScene){if("iso"===e){if(!this._spaceDisplayForRender().showBorders){const e=hf({rect:this._frameOf().rect,wallHeight:0});return[e.x,e.y,e.w,e.h]}const e=t?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const i=this._frameOf().rect;return[i.x,i.y,i.w,i.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom()}_clearRoomFocus(e=!1){this._doubleFit.clear(),this._roomFocus=null,e&&(this._roomPointer=null)}_roomFitBounds(e,t){const i=ni(e);if(!i||!e.id)return null;const n=this._spaceWalls,r=this._openCuts(),o=this._wallUnionGeometry(),s=n.length&&this._innerRoomContour(t,e.id,r,o?.roomGeom,o?.multiWallNodes)||i,a=this._spaceDisplayForRender();let l=[];if(a.showBorders&&n.length){const i=Cs(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,uv);i&&(l=ia(i.poly,i.offsets,o?.multiWallNodes)||i.poly)}const c=this._effectiveProjection();return function(e){const t=e.floor,i=e.wall||[],n=e.padding??0;if(!t.length||!t.every(gf)||!i.every(gf)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return vf([...t,...i],n);const r=e.wallHeight??0,o=e.floorDepth??0;if(!Number.isFinite(r)||r<0||!Number.isFinite(o)||o<0)return null;try{const e=[];for(const i of t){const t=[i[0],i[1]];e.push(sf(t,0)),o>0&&e.push(sf(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(sf(i,0)),r>0&&e.push(sf(i,r))}return vf(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?Ha(84,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?Ha(10,this._cellCm):0,padding:a.showBorders?Ha(1.25,this._cellCm):0})}_fitRoom(e,t=!0){if("view"!==this._mode)return!1;this._doubleFit.clear();const i=this._spaceModel(),n=i?.rooms.find(t=>t.id===e);if(!i||!n)return this._clearRoomFocus(),!1;let r=this._roomFitBounds(n,i);if(!r)return this._clearRoomFocus(),!1;this._roomFocus={spaceId:i.id,roomId:e};const o=this._stageEl;if(!o||o.clientWidth<=0||o.clientHeight<=0)return!0;const s=Oi(this._baseVb(),o.clientWidth/o.clientHeight),a=e=>function(e){const t=e.safeFraction??.8,{bounds:i,baseFit:n,stageWidth:r,stageHeight:o,minZoom:s,maxZoom:a}=e;if(!ff(i)||!ff(n)||!Number.isFinite(r)||r<=0||!Number.isFinite(o)||o<=0||!Number.isFinite(s)||s<=0||!Number.isFinite(a)||a1)return null;const l=r/o,c=Math.max(i.w/t,i.h/t*l);if(!Number.isFinite(c)||c<=0)return null;const h=Math.min(a,Math.max(s,n.w/c)),d=n.w/h,u=d/l;return{zoom:h,viewBox:{x:i.x+i.w/2-d/2,y:i.y+i.h/2-u/2,w:d,h:u}}}({bounds:e,baseFit:s,stageWidth:o.clientWidth,stageHeight:o.clientHeight,minZoom:yv.ZOOM_MIN,maxZoom:yv.ZOOM_MAX});let l=a(r);const c=this._isoSceneRuntime,h=this._renderIsoScene?.overlayFitEntries;if(l&&"iso"===this._effectiveProjection()&&c&&h?.length){const e=c.resolveIsoOverlayFitEnvelope({baseBounds:r,entries:h,ownerId:n.id,stageSize:{width:o.clientWidth,height:o.clientHeight},targetView:e=>a(e)?.viewBox??null});e&&(r=e.bounds,l=a(r))}if(!l)return this._clearRoomFocus(),!1;const d=this._cameraState(),u=function(e,t,i,n){const r=[e,t,i,n],o=Math.min(...r.map(e=>e.x)),s=Math.min(...r.map(e=>e.y));return{x:o,y:s,w:Math.max(...r.map(e=>e.x+e.w))-o,h:Math.max(...r.map(e=>e.y+e.h))-s}}(s,d.viewBox,l.viewBox,r);return l.viewBox=this._clampView(l.viewBox,u),t?(this._prepareCameraCommand(),this._startCameraTransition(l,u,"room",220),!0):(this._cancelCameraTransition(!1),Kg(d,l)||(this._zoom=l.zoom,this._view={...l.viewBox},this.requestUpdate()),!0)}_fitAll(e="fit"){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom(e)}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:j`
+
`:G}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}getGridOptions(){return{columns:"full"}}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],n=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(n?n[0]+"/"+n[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Xa(e).map((t,i)=>{const n=e.spaces[i]?.plan_url;return t.bg&&n?{...t,bg:{...t.bg,href:n}}:t})}_spaceModel(){return this._hasFixedFloor?wc(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return wc(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0,this._clearRoomFocus(!0);for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._deviceDrag=null,this._resetDeviceHitState(),this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary?.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit))return;const e=this._serverCfg,t=Qd({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const n of t){const t="h"+n.slice(n.indexOf(":")+1);e.markers.push({id:t,binding:n,hidden:!0}),i.push(n.slice(n.indexOf(":")+1))}const n={...e.settings||{},filter_seeded:!0};delete n.show_all,i.length&&Array.isArray(n.new_device_ids)&&(n.new_device_ids=n.new_device_ids.filter(e=>!i.includes(e))),e.settings=n,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Ee(e)),this._rulesCompiled}get _fillColors(){return gn(this._settings)}get _excluded(){return au(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,this._summary?.willUpdate(),e.has("hass")&&this._configReloadAuthority.observeContext(Gu(this)),e.has("_serverCfg")){const e=this._cfgEpochPreservedConfig===this._serverCfg;this._cfgEpochPreservedConfig=null,e||this._cfgEpoch++,this._renderLife.invalidate()}if(this._syncEmptySpaceState(),this._dangerConfirm&&(this._dangerConfirmMissingSpace()||"warm"===this._syncDangerConfirmLocaleGate())&&this._cancelDangerConfirm(),e.has("hass")&&this.hass){const t=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;this._renderLife.observe(e.get("hass"),this.hass,t?{entityIds:t.entityIds}:null,()=>$g(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._summary?.updated(),this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._syncRadarLive(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>{this._invalidateDeviceHitGeometry(),this._refitView(),requestAnimationFrame(()=>this._summary?.resized())}),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=Qg(this.renderRoot,e,this.panelHost);null!==t&&(t>=0&&t!==this._hdrH&&(this._hdrH=t),t>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:t,stageH:e.clientHeight}))};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary?.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&this._canManageConfiguration&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,n=t.level??1e9;return i!==n?i-n:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptConfigCapabilities(e){kg(this,e)}_syncRadarLive(){const e=this._serverCfg?.settings?.radar,t=(this._serverCfg?.markers||[]).some(e=>Rg(e,this._space));this._radarLive.sync(this._space,1===this._haRadarStage1Api&&"view"===this._mode&&!1!==e?.show_live&&t&&"hidden"!==this.ownerDocument.visibilityState)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await dm(this.hass,lm(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptAuthoritative(e){return qu(this,e)}_rollbackOptimistic(e){const t=this._adoption.rollbackOptimistic(e);return t&&this.requestUpdate(),t}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}_getAuthoritativeConfig(){return e=this,async function(e,t){const i=await e();return t(i),i}(()=>e.hass.callWS({type:"houseplan/config/get"}),t=>kg(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;let i=!1;const n=()=>{i=!0,this._regSignature="",this._maybeRebuildDevices()};try{const[i,r]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this._adoptAuthoritative({cfgResp:i,layResp:r,reason:"structural-response",profile:"reload",beforeAdopt:()=>{this._connectionWasLost=!1,this._serverStorage=!0},afterAdopt:()=>{this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,n()}})).status)return;this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(av)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,i||n(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],n=(n,r,o,s)=>{n()||i.push(async()=>{const i=await e.subscribeEvents(s,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!n()?r(i):i?.()})};if(n(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),n(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),n(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),n(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=jh(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const r=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=r,r.finally(()=>{this._liveSyncAttempt===r&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){return Vu(this,e,t)}_scheduleLoadRetry(e=!1){if(void 0!==this._loadRetryTimer)return;const t=Math.min(8e3,500*2**Math.min(4,Math.max(1,this._loadTries-7)));this._loadRetryTimer=window.setTimeout(()=>{this._loadRetryTimer=void 0,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}async _ensureLiveRuntime(){if(this._liveRt)return;const e=await import("./live-interaction-runtime-AJRZAUON.js");this._liveRt=new e.LiveRuntime(this),this.isConnected&&this.requestUpdate()}_liveVp(e=!1){this._liveRt?this._liveRt.viewport(e):this.requestUpdate()}_syncLiveHover(){this._liveRt?this._liveRt.hover():this.requestUpdate()}_flushHa(){this._liveRt?.take()&&(this._terminalFrame=2,super.requestUpdate())}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._renderLife.invalidate(),this._areaSnapshotCleanupCandidates.clear(),this._planHassMemo=null,this._haRegistryRelease=ed(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return id(this.hass)}get _planHass(){const e=this._haRegistry,t=rd(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=sd(this.hass,e),r=ad(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:n,full:r},n}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+eg)>e?1:0)).join("|"),i=Lh(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const n=this._planHass,r=new Map,o=new Map,s=new Set(["sun.sun"]);for(const e of this._summary?.entityIds()||[])s.add(e);this._vacFit?.source&&s.add(this._vacFit.source);const a=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void s.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?a.add(n):"entity"===i&&s.add(n)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of ui(t))s.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Ki(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,Qi(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!Zd(n,e,Xd(this._markers))))}const h=Od(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(g_(e.id,t),u_(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,n),i=t?jc(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=ah(e.id,e.marker?.vacuum??null,e.space,t),a=ch({routes:s,observed:hh(s,[t],t=>this._vacObservedMapId(e,t,n)),spaceIds:new Set(this._model.map(e=>e.id))});o.set(`vacuum:${e.id}`,{source:t,telemetry:i,routes:s,resolution:a,mapId:i?this._vacMapId(e,i,n):null,runtime:r?{trail:r.trail,lastTs:r.lastTs,moving:r.moving,jump:r.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=m_({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,positions:(u=this._model.length>0,p=this._devices,_=e=>this._livePos(e),u?new Map(p.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:s,deviceIds:a,areaIds:l});var u,p,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _renderVacuumDevices(){return this._renderDeviceSnapshot?.vacuumDevices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return hd(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const{registry:e,bindings:t}=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e));return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&gv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else gv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_referencedContentUrls(){const e=On(this._serverCfg);for(const t of this._decorAssets.values())e.add(t.url);return e}_resign(){this._signer.resign(this.hass,this._referencedContentUrls())}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){this._adoption.noteLayoutRevision(e?.rev)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,n]of e)null===n?delete i[t]:i[t]=n;this._adoption.adoptMergedLayout(i,t,()=>{this._cancelDeviceDrag(),this._devicePositionHistory.clear()}),this._canOptimizeUndo=!!t?.can_optimize_undo,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_persistLocalLayout(){this._layout=bo(ro(this._layout)),localStorage.setItem(av,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=rd(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+wp(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const n=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=tu({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const r=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+r.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const n of r)i.set(n,hd(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=cd(),i=Date.now();for(const[n,r]of e)"active"===r.kind?t[n]={kind:"active",ts:i}:"ha_disabled"===r.kind&&(t[n]={kind:"ha_disabled",reason:r.reason,ts:i});const n=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Kh=n;try{localStorage.setItem(Vh,JSON.stringify(n))}catch{}}(i),this._haBindingCacheKey=o}let s=null;if(t.authoritative&&(s=this._resolveAreaRelocations(t),this._areaRelocationIds=new Set(s.relocateIds),this._areaRelocationIds.size)){this._cancelDeviceDrag();const e=this._areaRelocationIds;this._devicePositionHistory.removeWhere(({before:t,after:i})=>e.has(t.deviceId)||e.has(i.deviceId));const t=this._markerDialog;if(t?.devId&&!t.roomTouched&&this._areaRelocationIds.has(t.devId)){const e=this._devices.find(e=>e.id===t.devId);e&&(this._markerDialog={...t,room:e.marker?.room_id?`${e.space}#@${e.marker.room_id}`:e.space&&e.area?`${e.space}#${e.area}`:""})}}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),s&&this._syncAreaRelocations(s),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const l=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==n.get(e.id));l&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._deviceDrag&&"ha_disabled"===this._devices.find(e=>e.id===this._deviceDrag.id)?.bindingStatus?.kind&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear()),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(mv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=J_(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])Z_(t)&&Number.isFinite(r)&&i.has(t)&&n.set(t,r);const r=new Set,o=new Set;for(const t of e.markers||[])t.removed||(X_(t.id)&&r.add(t.id),Z_(t.binding)&&o.add(t.binding));const s=new Set(Object.keys(e.registryDevices||{})),a=new Set(Object.keys(e.registryEntities||{})),l=new Set(Object.keys(e.liveStates||{})),c=new Map;for(const[e,i]of Object.entries(t)){const t=c.get(i.binding)||[];t.push(e),c.set(i.binding,t)}const h=new Set;let d=!1;for(const[t,i]of c){const[c,u]=nm(t);if(o.has(t)||i.some(e=>r.has(e))||("device"===c?s.has(u):a.has(u)||l.has(u))){n.delete(t);continue}const p="device"===c?s.size>0:a.size>0;if(!e.authoritative||!p)continue;const _=n.get(t);if(void 0!==_){if(_!==e.revision)for(const e of i)h.add(e)}else n.set(t,e.revision),d=!0}return{removeIds:h,candidates:n,needsConfirmationRefresh:d}}({snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,revision:e.revision,registryDevices:e.devices,registryEntities:e.entities,liveStates:this.hass?.states,markers:this._markers,previousCandidates:this._areaSnapshotCleanupCandidates});return this._areaSnapshotCleanupCandidates=t.candidates,t.needsConfirmationRefresh&&this._canEdit&&td(this.hass),rm({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:pv})}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:n,known:r}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),n=e.filter(e=>!i.has(e));return{fresh:n,known:n.length?[...t,...n]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||n.length){const e=[...new Set([...i.new_device_ids||[],...n])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:r,new_device_ids:e}},this._saveConfig()}}_syncAreaRelocations(e){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit&&this._haRegistry.authoritative))return;const t=e.decisions.filter(e=>e.updateSnapshot||e.removeSnapshot);if(!t.length)return;const i=lc({snapshot:J_(this._settings.marker_area_snapshot),decisions:t});i!==this._areaRelocationSyncKey&&(this._areaRelocationSyncKey=i,this._areaRelocationWrite=this._areaRelocationWrite.catch(()=>{}).then(async()=>{if(!this._serverCfg||!this._haRegistry.authoritative)return;const e=this._resolveAreaRelocations();this._areaRelocationIds=new Set(e.relocateIds);const t=new Set,i=new Map;let n=!1;for(const r of e.decisions){if(!r.relocate)continue;const e=gg(this._layout,r.id);try{await this._persistDevicePlacement(r.id,null),t.add(r.id),e&&i.set(r.id,e),this._areaRelocationIds.delete(r.id)}catch(t){n=!0,this._layout=fg(this._layout,r.id,e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}}const r=this._settings,o=function(e,t,i=new Set){const n=J_(e);for(const e of t.decisions)e.removeSnapshot?delete n[e.id]:e.updateSnapshot&&e.binding&&e.area&&(e.relocate&&!i.has(e.id)||(n[e.id]={binding:e.binding,area:e.area}));return n}(r.marker_area_snapshot,e,t),s=[...new Set([...Array.isArray(r.new_device_ids)?r.new_device_ids:[],...t])],a=lc(o)!==lc(J_(r.marker_area_snapshot)),l=lc(s)!==lc(Array.isArray(r.new_device_ids)?r.new_device_ids:[]);if(a||l){const e=r.marker_area_snapshot,n=r.new_device_ids,a={...this._serverCfg,settings:{...r,marker_area_snapshot:o,...l?{new_device_ids:s}:{}}};this._setAreaLifecycleConfig(a);try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.cancel(),await this._writeConfig()}catch(r){const a=this._settings;if(lc(a.marker_area_snapshot)===lc(o)&&lc(a.new_device_ids)===lc(l?s:n)){const t={...a};void 0===e?delete t.marker_area_snapshot:t.marker_area_snapshot=e,void 0===n?delete t.new_device_ids:t.new_device_ids=n;const i={...this._serverCfg,settings:t};this._setAreaLifecycleConfig(i),this._adoption.refreshConfigFingerprint()}for(const e of t)this._areaRelocationIds.add(e);const c=new Set;for(const[e,t]of i)try{await this._persistDevicePlacement(e,t)}catch(t){c.add(e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}this._areaRelocationSyncKey="",this._regSignature="";if("conflict"===(r&&"object"==typeof r&&"code"in r?r.code:void 0)?(this._showToast(this._t("toast.conflict")),await this._reloadConfigOnly(!0)):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(r)})),c.size&&this._serverCfg){const e=this._settings,t=[...new Set([...Array.isArray(e.new_device_ids)?e.new_device_ids:[],...c])],i={...this._serverCfg,settings:{...e,new_device_ids:t}};this._setAreaLifecycleConfig(i);try{await this._writeConfig()}catch(e){this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)}))}}}}n&&(this._areaRelocationSyncKey=""),this.requestUpdate()}))}get _newIds(){const e=this._settings.new_device_ids;return new Set([...Array.isArray(e)?e:[],...this._areaRelocationIds])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const n=Hd(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return Ii(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),n=Math.min(...t),r=Math.min(...i);return{x:n,y:r,w:Math.max(...t)-n,h:Math.max(...i)-r}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const n=t/100*kl(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const r=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!r.length)continue;const o=this._roomBounds(t),s=.1*Math.min(o.w,o.h),a=o.w-2*s,l=o.h-2*s,c=Math.max(1,Math.round(Math.sqrt(r.length*a/Math.max(l,1)))),h=Math.ceil(r.length/c),d=a/c,u=l/Math.max(h,1),p=r.map((e,t)=>({x:o.x+s+d*(t%c+.5),y:o.y+s+u*(Math.floor(t/c)+.5)}));Ei(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=nl(p[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._areaRelocationIds.has(e.id)?void 0:this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*pv,y:i.y*pv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?nl(wl(t)):{x:500,y:500}}_devicePlacementForCanvas(e,t,i){if(!this._norm)return{x:Math.round(t),y:Math.round(i)};const n=this._gridPitch,r=Math.round(t/n)*n,o=Math.round(i/n)*n;return{s:e.space,x:ol(r/pv),y:ol(o/pv)}}_previewDevicePlacement(e,t){this._layout=fg(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null,this._deviceHits.cancel(e.pointerId);try{e.source?.hasPointerCapture?.(e.pointerId)&&e.source.releasePointerCapture(e.pointerId)}catch{}return this._previewDevicePlacement(e.id,e.before),!0}async _persistDevicePlacement(e,t){if(this._layout=fg(this._layout,e,t),this._serverStorage){let i=null,n=!1;try{let r;if(null===t)i=null,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/delete",device_id:e});else{const t=yo(this._layout[e]);lc(t)!==lc(this._layout[e])&&(this._layout={...this._layout,[e]:t}),i=t,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t})}this._noteLayoutRev(r),this._adoption.refreshLayoutFingerprint(),this._cacheSnapshot()}finally{n&&this._sentPos.get(e)===i&&this._sentPos.delete(e)}return}this._persistLocalLayout()}_devicePositionStateValid(e){const t=this._devices.find(t=>t.id===e.deviceId);return!!t&&t.space===e.spaceId&&"ha_disabled"!==t.bindingStatus?.kind&&!!this._spaceModelById(e.spaceId)}async _runDevicePositionHistory(e){if(this._cancelDeviceDrag()||this._devicePositionBusy)return;const t="undo"===e?this._devicePositionHistory.undo():this._devicePositionHistory.redo();if(!t)return;const i="undo"===e?t.before:t.after;if(!this._devicePositionStateValid(i))return this._devicePositionHistory.clear(),this._showToast(this._t("history.device_stale")),void this.requestUpdate();const n=gg(this._layout,i.deviceId);i.spaceId!==this._space&&(this._commitSpace(i.spaceId),this._restoreZoom()),this._devicePositionBusy=!0,this._previewDevicePlacement(i.deviceId,i.placement);try{await this._persistDevicePlacement(i.deviceId,i.placement),this._showToast(this._t("undo"===e?"history.undone":"history.redone",{name:t.name}))}catch(t){this._previewDevicePlacement(i.deviceId,n),"undo"===e?this._devicePositionHistory.redo():this._devicePositionHistory.undo(),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}finally{this._devicePositionBusy=!1,this.requestUpdate()}}_undoDevicePosition(){this._runDevicePositionHistory("undo")}_redoDevicePosition(){this._runDevicePositionHistory("redo")}_savePos(e,t,i){this._spaceModelById(e.space)&&(this._layout=fg(this._layout,e.id,this._devicePlacementForCanvas(e,t,i)),this._dirtyPos.add(e.id),this._persistLayout())}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const n=i?null:this._renderDeviceSnapshot?.presentations.get(g_(e.id,t));return n||u_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,d_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=Bd(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Ld(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Vn(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._kiosk&&(this._cyclePausedUntil=Math.max(this._cyclePausedUntil,Date.now()+6e4)),this._nativeMoreInfoEntity=e,mv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._roomPointer=null,this._doubleFit.clear(),this._deviceHits.clearPointers()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_invalidateDeviceHitGeometry(){this._deviceHits.invalidate()}_resetDeviceHitState(){this._deviceHits.reset(this.renderRoot)}_deviceHitOwnerAt(e,t){return"view"!==this._mode&&"devices"!==this._mode?null:this._deviceHits.at(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForPointerEvent(e,t){return this._deviceHits.pointer(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForClickEvent(e,t){return this._deviceHits.click(this.renderRoot,this._renderDevices,this._space,e,t)}_showDeviceTip(e,t){this._liveRt?this._liveRt.devicePointerTip(e,t):this._ensureLiveRuntime().then(()=>this._liveRt?.devicePointerTip(e,t))}_showDeviceFocusTip(e,t){const i=e.currentTarget;this._liveRt?this._liveRt.deviceFocusTip(i,t):this._ensureLiveRuntime().then(()=>this._liveRt?.deviceFocusTip(i,t))}_hideDeviceFocusTip(e){this._liveRt?.deviceBlur(e)}_clearPointerHover(){this._liveRt?this._liveRt.pointerLeave():this._clearTransientHover()}_ctxDevice(e,t){"view"===this._mode&&(t=this._deviceForPointerEvent(e,t),e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if(e.stopPropagation(),t=this._deviceForClickEvent(e,t),this._deviceDrag?.moved||this._suppressClick||this._holdFired)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const n=Cu(i.tapAction,i.primary?.split(".")[0]);if("none"===n)return;const r=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===n){const e=this._toggleIntent(i);if(!e)return;if(!zu(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=zu(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=jh(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:n}=t;this._startDevicePressFeedback(i.id),this.hass.callService(n.domain,n.service,n.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},n=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const r=this._toggleConfirmationLines(e);if(!r.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:n}),lines:r,initialIntent:e,deviceId:i.id,exec:()=>{const n=this._devices.find(e=>e.id===i.id),r=n?this._toggleIntent(n):null;r&&!zu(r)&&this._showUnavailableToggleTargets(r)||(r&&Ou(e,r)?t(r):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===n)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===n){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),n=this.hass.states[e];if(!t||!n)return void this._showToast(this._t("toast.run_target_missing"));const o=n.attributes?.friendly_name||e;return void r(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===n&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||zu(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Iu.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!Iu.has(n.reason))continue;const e=String(n.name||n.entityId||n.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const n=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),r=Number.isFinite(n)?Math.max(.95,Math.min(1,n)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(r)},{scale:"0.95",offset:.5},{scale:"1"}],s=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,s);const a=()=>{this._devicePressAnimations.get(e)===s&&this._devicePressAnimations.delete(e)};s.addEventListener("finish",a,{once:!0}),s.addEventListener("cancel",a,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return kp(wp(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex"),confirm:this._t("color_picker.confirm")}}_help(e){return this._editorRuntimeOrThrow()._help(e)}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const n=this._pos(i);t.push({minX:n.x,minY:n.y,maxX:n.x,maxY:n.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,n=Math.cos(i)*e.rlen/2,r=Math.sin(i)*e.rlen/2,o=cl([[e.rx-n,e.ry-r],[e.rx+n,e.ry+r]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){if("image"===e.kind&&!this._decorAssets.has(e.asset_id)&&"decor"!==this._mode)continue;const n=cl("line"===e.kind?[[e.x1*pv,e.y1*i],[e.x2*pv,e.y2*i]]:"text"===e.kind?[[e.x*pv,e.y*i]]:zr({x:e.x*pv,y:e.y*i,w:e.w*pv,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=cl(i);e&&t.push(e)}}return _l(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:pv,h:pv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const n=vl(this._contentItems(e));let r=n.all||bl(e),o=this._showFar?r:n.core||bl(e);return t&&t.id===e.id&&i&&t.grow&&(o=_v(t.rect,o),r=_v(t.all,r)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:r,outliers:n.outliers},this._frame}_isoSource(){const e=this._isoSceneRuntime;if(!e)return null;const t=this._spaceModel();if(!t)return null;const i=this._spaceWalls,n=this._openCuts(),r=this._openingsR;return e.createIsoStructuralSource({space:t,walls:i,openCuts:n,openings:r,partitionCuts:()=>this._partitionOpeningCuts(t),roomOpenings:()=>this._roomWallOpeningInputs(r,t),cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,coordinateScale:pv,onBuild:()=>{this._isoStructuralBuildCount+=1}})}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return this._isoInvalidKey()}}_isoInvalidKey(){return`${this._space}|invalid|${this._cfgEpoch}`}_clearIsoInvalidFallback(e){const t=`${this._space}|invalid|`;for(const i of this._isoFallback)i.startsWith(t)&&i!==e&&this._isoFallback.delete(i)}_isoScene(e=this._isoSource()){const t=this._isoSceneRuntime;if(!t||!e)return null;let i=this._frameOf().rect;const n=this._spaceDisplayForRender(),r=this._spaceModel();if(r&&n.showNames)for(const e of r.rooms)if(e.name){const t=this._labelPos(e,r.id);i=_v(i,{x:t.x,y:t.y,w:0,h:0})}const o=t.resolveIsoScene({source:e,cache:this._isoGeometryCache,cellCm:this._cellCm,liveFrame:i});if(!r||!n.showBorders)return o;const s=this._config?.icon_size??2.5,a=s>8?2.5:s,l=this._stageEl?.getBoundingClientRect?.()??null,c=l?.height?l.width/l.height:o.frame.w/o.frame.h,h=Oi([o.frame.x,o.frame.y,o.frame.w,o.frame.h],c),d=this._isoOverlayScene(r,this._renderDevices.filter(e=>e.space===r.id&&!e.hidden),h,n,t.resolveIsoDecorationLayers(n),o,a,k_(a),n.showLqi??this._config?.show_signal??!0,!1),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>Oi([e.x,e.y,e.w,e.h],c)});return u?{...o,frame:u.bounds,overlayFitEntries:d.entries}:o}_latchIsoFallback(e,t){if(this._isoFallback.has(e))return;this._isoFallback.add(e);const i=e.includes("|invalid|")?"invalid":e.split("|").pop()||"invalid";console.warn("HOUSEPLAN ISO FALLBACK: #89/#160",bf("structural",i,!0))}_effectiveProjection(){if(this._isoProjectionSnapshot)return this._isoProjectionSnapshot;const e=e=>this._isoProjectionSnapshot=e,t=()=>("iso"===this._renderProjection&&(this._cancelCameraTransition(!1),this._view=null,this._viewModeSnap=null),e("flat"));if(this._renderIsoScene=null,"iso"!==this._desiredProjection||!this._model.length||!this._isoSceneRuntime)return e("flat");if(!this._spaceDisplayForRender().showBorders)return this._isoFallback.has(`${this._space}|no-borders`)?t():e("iso");let i=this._isoInvalidKey();if(this._clearIsoInvalidFallback(i),this._isoFallback.has(i))return t();try{const n=this._isoSource();if(!n)return e("flat");if(i=n.key,this._isoFallback.has(i))return t();const r=this._isoScene(n);return r?this._isoFallback.has(r.key)?t():(this._renderIsoScene=r,e("iso")):e("flat")}catch(e){return this._latchIsoFallback(i,e),t()}}_scenePoint(e){return"iso"===this._renderProjection?af(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=lf([e.x,e.y]),i=lf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_isoOverlayScene(e,t,i,n,r,o,s,a,l,c=!0){const h=this._isoSceneRuntime;return h&&r?.structural&&o?h.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,wallSilhouettes:o.wallSilhouettes,resolveCollisions:c,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:"view"===this._mode?this._kioskScale.icon:1,kioskFontScale:"view"===this._mode?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),positionOf:e=>this._pos(e),presentationOf:(e,t)=>this._devicePresentation(e,t),labelPositionOf:(e,t)=>this._labelPos(e,t),labelScaleOf:e=>this._labelScale(e),openingEntityAvailable:e=>this._renderOpeningEntityAvailable(e),openingWallIndex:()=>this._openingWallIndexFor(e,this._openCuts()).value}):null}_baseVb(e=this._effectiveProjection(),t=this._renderIsoScene){if("iso"===e){if(!this._spaceDisplayForRender().showBorders){const e=df({rect:this._frameOf().rect,wallHeight:0});return[e.x,e.y,e.w,e.h]}const e=t?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const i=this._frameOf().rect;return[i.x,i.y,i.w,i.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom()}_clearRoomFocus(e=!1){this._doubleFit.clear(),this._roomFocus=null,e&&(this._roomPointer=null)}_roomFitBounds(e,t){const i=ni(e);if(!i||!e.id)return null;const n=this._spaceWalls,r=this._openCuts(),o=this._wallUnionGeometry(),s=n.length&&this._innerRoomContour(t,e.id,r,o?.roomGeom,o?.multiWallNodes)||i,a=this._spaceDisplayForRender();let l=[];if(a.showBorders&&n.length){const i=Ts(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,pv);i&&(l=na(i.poly,i.offsets,o?.multiWallNodes)||i.poly)}const c=this._effectiveProjection();return function(e){const t=e.floor,i=e.wall||[],n=e.padding??0;if(!t.length||!t.every(ff)||!i.every(ff)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return yf([...t,...i],n);const r=e.wallHeight??0,o=e.floorDepth??0;if(!Number.isFinite(r)||r<0||!Number.isFinite(o)||o<0)return null;try{const e=[];for(const i of t){const t=[i[0],i[1]];e.push(af(t,0)),o>0&&e.push(af(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(af(i,0)),r>0&&e.push(af(i,r))}return yf(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?La(84,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?La(10,this._cellCm):0,padding:a.showBorders?La(1.25,this._cellCm):0})}_fitRoom(e,t=!0){if("view"!==this._mode)return!1;this._doubleFit.clear();const i=this._spaceModel(),n=i?.rooms.find(t=>t.id===e);if(!i||!n)return this._clearRoomFocus(),!1;let r=this._roomFitBounds(n,i);if(!r)return this._clearRoomFocus(),!1;this._roomFocus={spaceId:i.id,roomId:e};const o=this._stageEl;if(!o||o.clientWidth<=0||o.clientHeight<=0)return!0;const s=Oi(this._baseVb(),o.clientWidth/o.clientHeight),a=e=>function(e){const t=e.safeFraction??.8,{bounds:i,baseFit:n,stageWidth:r,stageHeight:o,minZoom:s,maxZoom:a}=e;if(!vf(i)||!vf(n)||!Number.isFinite(r)||r<=0||!Number.isFinite(o)||o<=0||!Number.isFinite(s)||s<=0||!Number.isFinite(a)||a1)return null;const l=r/o,c=Math.max(i.w/t,i.h/t*l);if(!Number.isFinite(c)||c<=0)return null;const h=Math.min(a,Math.max(s,n.w/c)),d=n.w/h,u=d/l;return{zoom:h,viewBox:{x:i.x+i.w/2-d/2,y:i.y+i.h/2-u/2,w:d,h:u}}}({bounds:e,baseFit:s,stageWidth:o.clientWidth,stageHeight:o.clientHeight,minZoom:bv.ZOOM_MIN,maxZoom:bv.ZOOM_MAX});let l=a(r);const c=this._isoSceneRuntime,h=this._renderIsoScene?.overlayFitEntries;if(l&&"iso"===this._effectiveProjection()&&c&&h?.length){const e=c.resolveIsoOverlayFitEnvelope({baseBounds:r,entries:h,ownerId:n.id,stageSize:{width:o.clientWidth,height:o.clientHeight},targetView:e=>a(e)?.viewBox??null});e&&(r=e.bounds,l=a(r))}if(!l)return this._clearRoomFocus(),!1;const d=this._cameraState(),u=function(e,t,i,n){const r=[e,t,i,n],o=Math.min(...r.map(e=>e.x)),s=Math.min(...r.map(e=>e.y));return{x:o,y:s,w:Math.max(...r.map(e=>e.x+e.w))-o,h:Math.max(...r.map(e=>e.y+e.h))-s}}(s,d.viewBox,l.viewBox,r);return l.viewBox=this._clampView(l.viewBox,u),t?(this._prepareCameraCommand(),this._startCameraTransition(l,u,"room",220),!0):(this._cancelCameraTransition(!1),Yg(d,l)||(this._zoom=l.zoom,this._view={...l.viewBox},this.requestUpdate()),!0)}_fitAll(e="fit"){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom(e)}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:j`
${this._t("canvas.far_objects",{n:this._outliers})} @@ -364,7 +364,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 style="left:${a.toFixed(1)}%;top:${l.toFixed(1)}%" @click=${e=>{e.stopPropagation(),this._fitAll("home")}}> - `}_stageAspect(e=this._baseVb()){const t=this._stageEl;return t&&t.clientHeight?t.clientWidth/t.clientHeight:e[2]/e[3]}_viewOr(e){return this._view&&this._view.w?this._view:Oi(e,this._stageAspect(e))}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._viewModeSnap;if(t?.space===this._space&&t.w)return t.w*t.zoom/this._zoom;const i=this._stageEl,n=this.renderRoot.querySelector(".editorchrome");if(!i?.clientWidth||!i.clientHeight)return e.w;const r=i.clientHeight+(n?.offsetHeight||0);return this._viewForModeTarget(this._zoom,void 0,void 0,i.clientWidth,r).w}_screenToVb(e,t){const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i?.clientWidth||1,o=i?.clientHeight||1;return[n.x+e/r*n.w,n.y+t/o*n.h]}_clampView(e,t){const i=(e,t,i,n)=>{const r=1*Math.max(t,n),o=i-r,s=i+n-t+r;return Math.max(Math.min(o,s),Math.min(Math.max(o,s),e))};return{w:e.w,h:e.h,x:i(e.x,e.w,t.x,t.w),y:i(e.y,e.h,t.y,t.h)}}_applyView(e,t,i){this._cancelCameraTransition(!1);const n=this._baseVb(),r=Oi(n,this._stageAspect()),o=Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,e)),s=r.w/o,a=r.h/o,l=this._viewOr(n),c=t??l.x+l.w/2,h=i??l.y+l.h/2,d=this._clampView({x:c-s/2,y:h-a/2,w:s,h:a},r);return!(this._view&&Math.abs(this._zoom-o)<1e-9&&Math.abs(this._view.x-d.x)<1e-6&&Math.abs(this._view.y-d.y)<1e-6&&Math.abs(this._view.w-d.w)<1e-6&&Math.abs(this._view.h-d.h)<1e-6)&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=o,this._view=d,this._liveVp(),!0)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const e=()=>{if(!this._booting)return;const t=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=t);const n=t-this._bootStart;var r,o,s;n>=1200||n>=700&&i>0&&t-this._bootLastChange>=250&&(r=Al,o=this._serverCfg,s=Nl,"pending"!==r.state()||!Cl(o,s))?this._bootSettled():this._bootTimer=window.setTimeout(e,100)};this._bootTimer=window.setTimeout(e,100)}_bootSettled(){this._booting&&!this._bootSettling&&(this._bootSettling=!0,this._refitView(),this._bootSettleRaf=requestAnimationFrame(()=>{this._bootSettleRaf=0,this._finishBootSettled()}))}_finishBootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1,this._bootSettling=!1;const e=this._stageEl?.clientHeight??0;!this._config?.kiosk&&e>0&&this._warmPatch({hdrH:this._hdrH,stageH:e,vp:this._warmViewportState()},!0),this._bootFading=!0,this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220),this._bootSoft=!0,clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},iv)}_bootSoftCancel(){if(!this._bootSoft)return;clearTimeout(this._bootSoftTimer),this._bootSoft=!1;const e=function(e,t,i,n){if(!t)return null;const r=Jg(e,t,i);return i||n||null===r||(t.style.height=`calc(100dvh - ${r}px)`),t.classList.remove("hpsettle"),t.getBoundingClientRect(),t.clientWidth<=0||t.clientHeight<=0?null:{headerHeight:r,size:[t.clientWidth,t.clientHeight]}}(this.renderRoot,this._stageEl,this.panelHost,this._kiosk);if(!e)return;null!==e.headerHeight&&(this._hdrH=e.headerHeight),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null,this._lastValidStageSize=e.size;const t=this._view;t&&this._applyView(this._zoom,t.x+t.w/2,t.y+t.h/2)}_beginResumeSettle(){this._booting||this._resumeSettling||(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0),this._viewportInvalidAt=0,this._beginContinuityCandidate("warm-resume",!1),this._loading?this.requestUpdate():this._loadFromServer())}_refitView(){if(this._modeTransitionBusy||this._warmModeRequest)return;const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return this._cancelCameraTransition(!1),void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight];if(this._bootSoft&&this._warmVp)return this._lastValidStageSize=t,void(this._pendingRefitSize=null);const i=this._lastValidStageSize,n=!!i&&Math.abs(i[0]-t[0])<=.5&&Math.abs(i[1]-t[1])<=.5,r=this._viewportInvalidAt?Date.now()-this._viewportInvalidAt:0;if(this._viewportInvalidAt=0,n)this._pendingRefitSize=null;else{if(this._cancelCameraTransition(!1),!i)return this._lastValidStageSize=t,void(this._roomFocus?.spaceId===this._space?this._fitRoom(this._roomFocus.roomId,!1):this._view||this._applyView(this._zoom));this._pendingRefitSize=t,this._refitRaf||(this._refitRaf=requestAnimationFrame(()=>{this._refitRaf=0;const e=this._pendingRefitSize;this._pendingRefitSize=null;const t=this._stageEl;if(!e||!t||t.clientWidth<=0||t.clientHeight<=0)return;if(Math.abs(t.clientWidth-e[0])>.5||Math.abs(t.clientHeight-e[1])>.5)return void this._refitView();const i=this._lastValidStageSize;if(i&&Math.abs(i[0]-e[0])<=.5&&Math.abs(i[1]-e[1])<=.5)return;this._lastValidStageSize=e;const n=this._view;r>=tc?this._beginContinuityCandidate("stage-size-restored",!0,"stage-size"):this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._roomFocus?.spaceId!==this._space?this._applyView(this._zoom,n?n.x+n.w/2:void 0,n?n.y+n.h/2:void 0):this._fitRoom(this._roomFocus.roomId,!1)}))}}_cameraTargetAt(e,t,i,n=!1){const r=this._stageEl;if(!r||r.clientWidth<=0||r.clientHeight<=0)return null;const o=Oi(this._baseVb(),this._stageAspect()),s=Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,i)),a=function(e,t,i,n,r,o,s){if(!Gg(e)||!Gg({zoom:t,viewBox:i})||!Ug(n)||n<=0||!Ug(r)||r<=0||!Ug(o)||!Ug(s))return null;const a=o/n,l=s/r,c=e.viewBox.x+a*e.viewBox.w,h=e.viewBox.y+l*e.viewBox.h,d=i.w/t,u=i.h/t;return{zoom:t,viewBox:{x:c-a*d,y:h-l*u,w:d,h:u}}}(n&&this._cameraTransition.target||this._cameraState(),s,o,r.clientWidth,r.clientHeight,e,t);return a?(a.viewBox=this._clampView(a.viewBox,o),{target:a,fit:o}):null}_zoomAt(e,t,i){this._clearRoomFocus(),this._cancelCameraTransition(!1);const n=this._cameraTargetAt(e,t,i);n&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=n.target.zoom,this._view={...n.target.viewBox},this._liveVp())}_onWheel(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;e.preventDefault();const i=t.getBoundingClientRect(),n=e.deltaY<0?1.15:1/1.15,r=this._cameraTransition.target?.zoom??this._zoom,o=this._cameraTargetAt(e.clientX-i.left,e.clientY-i.top,r*n,!0);o&&this._startCameraTransition(o.target,o.fit,"wheel",160)}_stepZoom(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;const i=this._cameraTransition.target?.zoom??this._zoom,n=this._cameraTargetAt(t.clientWidth/2,t.clientHeight/2,i*(e>0?1.4:1/1.4),!0);n&&this._startCameraTransition(n.target,n.fit,"button",180)}_resetZoom(e="fit"){this._clearRoomFocus(),this._prepareCameraCommand();const t=Oi(this._baseVb(),this._stageAspect());this._startCameraTransition({zoom:1,viewBox:{...t}},t,e,220)}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem(lv,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){this._clearRoomFocus(!0),this._cancelCameraTransition(!1);const e=this._zoomBySpace[this._space]||1;this._zoom=e;const t=this._stageEl;if(t&&t.clientHeight){const t=this._baseVb();return this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const t=this._baseVb();this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),this.requestUpdate()})}_stagePointerDown(e){this._bootSoftCancel();const t=e.isPrimary&&0===e.button&&"view"===this._mode?_f(e.composedPath()):null;if(this._roomPointer=t?{pointerId:e.pointerId,spaceId:this._space,roomId:t}:null,this._doubleFit.pointerDown(e,this._space,this._doubleFitEnabled),this._cancelCameraTransition(!1,!0),this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:e.clientX,y:e.clientY,id:e.pointerId},e.target.closest?.(".dev, .roomlabel, .oplock")||(clearTimeout(this._kioskHoldTimer),this._kioskHoldTimer=window.setTimeout(()=>{this._roomPointer=null,this._doubleFit.clear(),this._kioskDialog=!0,this._swipeStart=null},3e3))):(this._swipeStart=null,clearTimeout(this._kioskHoldTimer))),this._drag||this._deviceDrag)return;if(this._markup&&e.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&e.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(e))return;this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY});const i=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:e.clientX,sy:e.clientY,vx:i.x,vy:i.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y);this._pinchStart={dist:t,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return!this._hasFixedFloor&&this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(e){if(this._physicalRotate?.pid!==e.pointerId)if(this._physicalDrag?.pid!==e.pointerId)if(this._dtDrag?.pid!==e.pointerId)if(this._bdDrag?.pid!==e.pointerId){if(this._decorDraft?.pid===e.pointerId){const t=this._decorDraft;let i=this._decorSnap(this._svgPoint(e),e.pointerType);if(e.shiftKey&&("rect"===t.kind||"ellipse"===t.kind)){const e=i[0]-t.a[0],n=i[1]-t.a[1],r=Math.max(Math.abs(e),Math.abs(n));i=this._snap([t.a[0]+(e<0?-r:r),t.a[1]+(n<0?-r:r)])}return void(this._decorDraft={...t,b:i})}if(this._decorMove?.pid!==e.pointerId){if("decor"!==this._mode||"furniture"!==this._decorTool&&"image"!==this._decorTool||!this._editorRuntime||(this._notePointer(e),!this._editorRuntime._furnPointerMove(e,this._pointerModality.hoverEnabled)))if(this._pointers.has(e.pointerId)){if(this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(e),this._pinchStart&&this._pointers.size>=2){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),n=(e[0].x+e[1].x)/2-i.left,r=(e[0].y+e[1].y)/2-i.top;this._zoomAt(n,r,this._pinchStart.zoom*t),this._viewportGestureDirty=!0,this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const t=e.clientX-this._panStart.sx,i=e.clientY-this._panStart.sy;Math.abs(t)+Math.abs(i)>4&&(this._roomPointer=null,this._doubleFit.clear(),this._suppressClick=!0,clearTimeout(this._holdTimer),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover()),null===this._panLock&&Math.abs(t)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(t)>1.5*Math.abs(i)?"swipe":"pan","pan"===this._panLock&&this._clearRoomFocus());const n=this._stageEl;if("pan"===this._panLock&&n){const e=this._baseVb(),r=this._viewOr(e),o=Oi(e,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-t/(n.clientWidth||1)*r.w,y:this._panStart.vy-i/(n.clientHeight||1)*r.h,w:r.w,h:r.h},o),this._viewportGestureDirty=!0,this._liveVp()}}}else this._markupMove(e)}else this._decorMoveUpdate(e)}else this._bdMove(e);else this._dtMove(e);else this._physicalMove(e);else this._physicalRotateMove(e)}_stagePointerLeave(e){this._editorRuntime?._cancelPointerMove("markup-hover"),"decor"===this._mode&&this._editorRuntime?._furnPointerLeave(e),this._markup&&("opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover())}_stagePointerUp(e){this._deviceHits.release(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover");const t=(i=this._roomPointer,n=e.pointerId,r=this._space,o=this._roomPointer&&"view"===this._mode?_f(e.composedPath()):null,s=this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired||this._touchSequenceMultitouch,!i||s||i.pointerId!==n||i.spaceId!==r||i.roomId!==o?null:i.roomId);var i,n,r,o,s;this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null);if(this._doubleFit.pointerUp(e,this._space,this._doubleFitEnabled,this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired)&&this._fitAll("double-tap"),this._kiosk){clearTimeout(this._kioskHoldTimer);const i=this._swipeStart;if(this._swipeStart=null,!t&&i&&i.id===e.pointerId){const t=e.clientX-i.x,n=e.clientY-i.y,r="pan"===this._panLock?null:function(e,t,i,n,r,o=60){if(i>1.001||n.length<2)return null;if(Math.abs(e)e.id),this._space);r&&this._slideTo(r,t<0?"left":"right")&&(this._saveNav(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._showKioskDots())}}this._physicalDrag?.pid!==e.pointerId?this._physicalRotate?.pid!==e.pointerId?this._dtDrag?.pid!==e.pointerId?this._bdDrag?.pid!==e.pointerId?this._decorDraft?.pid!==e.pointerId?this._decorMove?.pid!==e.pointerId?this._editorRuntime?._furnPointerUp(e)||(this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._suppressClick&&setTimeout(()=>this._suppressClick=!1,0)),this._viewportGestureDirty&&0===this._pointers.size&&!t&&(this._viewportGestureDirty=!1,this.requestUpdate()),t&&this._fitRoom(t)):this._editorRuntimeOrThrow()._dmUp():this._decorCommitDraft():this._bdUp():this._dtUp():this._physicalRotateUp(e):this._physicalUp(e)}_clickRoom(e){!this._suppressClick&&e.area&&mv("/config/areas/area/"+e.area)}_roomLabelKey(e,t){"view"!==this._mode||"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),e.stopPropagation(),this._fitRoom(t))}_pointerDown(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if("view"===this._mode&&"touch"===e.pointerType&&this._touchSequenceMultitouch)return;if(t=this._deviceHits.begin(this.renderRoot,this._renderDevices,this._space,e,t),"view"===this._mode){this._holdFired=!1,clearTimeout(this._holdTimer);const i=e.pointerId,n=e.currentTarget;return void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._interruptViewGesture(i,n),this._infoCard=t},600))}if("ha_disabled"===t.bindingStatus?.kind||this._devicePositionBusy)return;if(this._deviceDrag)return void(this._deviceDrag.pointerId!==e.pointerId&&this._cancelDeviceDrag());e.preventDefault();const i=this._pos(t);this._deviceDrag={id:t.id,spaceId:t.space,displayName:t.name,pointerId:e.pointerId,source:e.currentTarget,sx:e.clientX,sy:e.clientY,ox:i.x,oy:i.y,moved:!1,before:mg(this._layout,t.id),start:this._devicePlacementForCanvas(t,i.x,i.y)},fv(e),this._tip=null,this._syncLiveHover()}_pointerMove(e,t){if("view"!==this._mode&&"devices"!==this._mode)return null;if(t=this._deviceForPointerEvent(e,t),"devices"!==this._mode)return t;const i=this._deviceDrag;return i&&i.id===t.id&&i.pointerId===e.pointerId?(this._editorRuntimeOrThrow()._queuePointerMove("device",()=>this._pointerMoveNow(e,t)),t):t}_pointerMoveNow(e,t){if("devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;const n=this.renderRoot.querySelector(".stage");if(!n)return;const r=this._baseVb(),o=n.getBoundingClientRect(),s=this._viewOr(r),a=(e.clientX-i.sx)/o.width*s.w,l=(e.clientY-i.sy)/o.height*s.h;Math.abs(e.clientX-i.sx)+Math.abs(e.clientY-i.sy)>3&&(i.moved=!0,clearTimeout(this._holdTimer));const c=nl(i.ox+a),h=nl(i.oy+l);this._previewDevicePlacement(t.id,this._devicePlacementForCanvas(t,c,h))}_pointerUp(e,t){if(t=this._deviceForPointerEvent(e,t),this._deviceHits.release(e.pointerId),clearTimeout(this._holdTimer),"devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;this._editorRuntimeOrThrow()._flushPointerMove("device"),this._deviceDrag=null;const n=mg(this._layout,t.id);var r,o;i.moved&&null!==n&&(r=n,o=i.start,null===r||null===o?r!==o:r.x!==o.x||r.y!==o.y||r.s!==o.s)?(this._selId=t.id,this._suppressClick=!0,window.setTimeout(()=>{this._suppressClick=!1},0),this._devicePositionBusy=!0,this.requestUpdate(),this._persistDevicePlacement(t.id,n).then(()=>{const e=this._t("history.device_move",{name:i.displayName});this._devicePositionHistory.push({name:e,before:{deviceId:i.id,spaceId:i.spaceId,placement:i.before},after:{deviceId:i.id,spaceId:i.spaceId,placement:n}})}).catch(e=>{this._previewDevicePlacement(t.id,i.before),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))}).finally(()=>{this._devicePositionBusy=!1,this.requestUpdate()})):this._previewDevicePlacement(t.id,i.before)}_pointerCancel(e,t){t=this._deviceForPointerEvent(e,t),this._deviceHits.cancel(e.pointerId),this._deviceDrag?.id===t.id&&this._deviceDrag.pointerId===e.pointerId&&this._cancelDeviceDrag()}_showToast(e){for(const e of this.renderRoot.querySelectorAll("hp-dialog"))e.closeTransientOverlays("toast");this._toast=e,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}_syncPointerHoverTargets(){const e=this._pointerModality.hoverEnabled;for(const t of this.renderRoot.querySelectorAll(dv))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(dv)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(dv))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),this._liveRt?.clearDeviceFocus(),this._deviceHits.hover(this.renderRoot,null),this._tip&&(this._tip=null),this._hoverRoom&&(this._hoverRoom=null),this._syncLiveHover()}_notePointer(e){const t=this._pointerModality.modality,i=this._pointerModality.note(e);"touch"!==i&&"pen"!==i||t===i&&!this._tip&&!this._hoverRoom||this._clearTransientHover()}_guardTouchGesture(e){if(this._editorSecondary?.handleOutsideDismiss(e))return;if(this._touchClickGuard.handleActivation(e,this._suppressClick))return;const t=e;if(this._notePointer(t),"pointercancel"===e.type||"lostpointercapture"===e.type?this._doubleFit.clear():"pointerdown"===e.type&&this._doubleFit.clearOutside(t),"pointerdown"===e.type&&this._touchClickGuard.pointerDown(t.pointerId,t.pointerType),"touch"!==t.pointerType)return;if("pointerdown"===e.type){if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._deviceHits.clearPointers(),this._clearRoomFocus(!0),this._clearTransientHover(),clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),this._swipeStart=null;const e=[...this._touchContacts.values()];if("view"===this._mode&&!this._vacFit&&e.every(e=>e.inStage)){this._pointers=new Map([...this._touchContacts].map(([e,t])=>[e,{x:t.x,y:t.y}]));const[t,i]=e;this._pinchStart={dist:Math.hypot(t.x-i.x,t.y-i.y),zoom:this._zoom},this._panStart=null,this._panLock=null}else this._vacFit&&(this._pointers.clear(),this._pinchStart=null,this._panStart=null,this._panLock=null)}return}if("pointermove"===e.type){const e=this._touchContacts.get(t.pointerId);if(!e)return;const i={...e,x:t.clientX,y:t.clientY};if(this._touchContacts.set(t.pointerId,i),this._touchSequenceMultitouch&&"view"===this._mode&&!this._vacFit&&this._pinchStart&&[...this._touchContacts.values()].every(e=>e.inStage)){this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=[...this._touchContacts.values()];if(e.length>=2&&this._stageEl){const[t,i]=e,n=Math.hypot(t.x-i.x,t.y-i.y)/(this._pinchStart.dist||1),r=this._stageEl.getBoundingClientRect();this._zoomAt((t.x+i.x)/2-r.left,(t.y+i.y)/2-r.top,this._pinchStart.zoom*n),this._saveZoom()}}return}if("pointerup"!==e.type&&"pointercancel"!==e.type&&"lostpointercapture"!==e.type)return;const i=this._touchClickGuard.pointerTerminal(t.pointerId,t.pointerType);if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),i){if(this._pointers.delete(t.pointerId),!this._vacFit&&this._pointers.size>=2){const[e,t]=[...this._pointers.values()];this._pinchStart={dist:Math.hypot(e.x-t.x,e.y-t.y),zoom:this._zoom}}else this._pinchStart=null;0===this._pointers.size&&(this._panStart=null,this._panLock=null)}}_showTip(e,t,i,n,r,o,s=!1){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||this._deviceDrag||s&&this._liveRt?.deviceFocusActive()||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:n,temp:r,hum:o,room:s,source:"pointer"},this._syncLiveHover()))}_roomTipEnabledForPointer(e){return"view"===this._mode&&(this._notePointer(e),!!_n(this._settings)||(this._tip?.room&&(this._tip=null,this._syncLiveHover()),!1))}get _gridPitch(){return Qa}get _cellCm(){const e=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(e)&&e>0?e:5}_fmtLen(e,t){const i=function(e,t,i,n){return Math.hypot(t[0]-e[0],t[1]-e[1])/i*n}(e,t,this._gridPitch,this._cellCm);return ti(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const e=this._resize?.preview;return e&&e.space===this._space?e.sp:this._serverCfg?.spaces.find(e=>e.id===this._space)}get _renderCfg(){const e=this._resize?.preview;return e&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(t=>t.id===e.space?e.sp:t)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,uv}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return oi(e?.rooms||[]).map(e=>[e[0]*uv,e[1]*t,e[2]*uv,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(cv)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(cv,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,this._configReloadAuthority.invalidateLifecycle(),this._summary?.leaveRoute(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._drawWallField=null,this._showHidden=!1,this._tapConfirm=null,this._vacCalConfirm=null,this._decorEraseConfirm=null,this._openingInfo=null,this._closeInfoCard(),this._rulesDialog=null,this._alignDialog=null,this._preflightClipboardFallback=null,this._backupImportDialog=null,this._backupExportDialog=null,this._pdfDialog=!1,this._supportDialog?.preview?.token&&this._editorRuntime?._discardSupportPreview(this._supportDialog.preview.token),this._supportDialog=null,this._settingsDialog=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._openingDialog=null,this._physicalDialog=null,this._wallDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._mergeDialog=null,this._roomDialog=!1,this._spaceDialog=null,this._importDialog=null;const e=this._warmSlot;e?.owner===this._warmGen&&(e.vp=this._warmViewportState(),e.dlg=null,e.frameFingerprint="",clearTimeout(e.evict),e.evict=0),this._saveNav()}_setMode(e,t=!0){return e!==this._mode&&(this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._resetDeviceHitState(),this._clearTransientHover(!0)),this._warmModeRequest=0,this._editorRuntime?this._editorRuntime._setMode(e,t):"view"===e?void this._editorModeRequest++:void this._requestMode(e,t)}_primeDrawWallField(){return this._editorRuntimeOrThrow()._primeDrawWallField()}get _drawWallFieldValue(){return null===this._drawWallField?Do(15,this._imperial):this._drawWallField}get _drawWallCm(){const e=(e=>{const t=String(e??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(t))return null;const i=Number(t);return Number.isFinite(i)?i:null})(this._drawWallFieldValue);if(null==e||e<0)return null;const t=this._imperial?2.54*e:e,i="column"===this._tool?ua:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?ua:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){return this._editorRuntimeOrThrow()._showPhysicalRange(e,t)}_mergeSpacePartitions(e,t){return this._editorRuntimeOrThrow()._mergeSpacePartitions(e,t)}_finishWallChain(){return this._editorRuntimeOrThrow()._finishWallChain()}_activateMarkupTool(e){return this._editorRuntimeOrThrow()._activateMarkupTool(e)}_limitReached(e){return this._editorRuntimeOrThrow()._limitReached(e)}_svgPoint(e){return this._editorRuntimeOrThrow()._svgPoint(e)}_snap(e){return this._editorRuntimeOrThrow()._snap(e)}_snapDrawPoint(e,t=!1){return this._editorRuntimeOrThrow()._snapDrawPoint(e,t)}_planSnapOpeningCuts(e,t){return this._editorRuntimeOrThrow()._planSnapOpeningCuts(e,t)}_planSnapGeometrySnapshot(){return this._editorRuntimeOrThrow()._planSnapGeometrySnapshot()}_hiddenWallDiagnosticSnapshot(){return this._editorRuntimeOrThrow()._hiddenWallDiagnosticSnapshot()}_planStructuralGeometrySnapshot(){return this._editorRuntimeOrThrow()._planStructuralGeometrySnapshot()}_planSnapContextKey(e){return this._editorRuntimeOrThrow()._planSnapContextKey(e)}_resolvePlanDrawPoint(e,t){return this._editorRuntimeOrThrow()._resolvePlanDrawPoint(e,t)}get _activePlanSnapCandidate(){if(!this._markup||"draw"!==this._tool)return null;const e=this._planSnapHover;if(!e)return null;const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.candidate:null}get _activePlanSnapConflicts(){if(!this._markup||"draw"!==this._tool)return[];const e=this._planSnapHover;if(!e)return[];const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.conflicts:[]}_clearPlanSnapHover(e=!0){return this._editorRuntime?this._editorRuntimeOrThrow()._clearPlanSnapHover(e):(this._planSnapHover=null,void(e&&(this._cursorPt=null)))}_samePt(e,t){return _i(e,t)}_dropLegacySegments(){return this._editorRuntimeOrThrow()._dropLegacySegments()}_rollbackRejectedPhysicalWrites(e){return this._editorRuntimeOrThrow()._rollbackRejectedPhysicalWrites(e)}async _reloadRejectedPhysicalWrite(){return this._editorRuntimeOrThrow()._reloadRejectedPhysicalWrite()}get _cfgWriting(){return this._writesPending>0}async _sendConfigCandidate(e){const t=bo(e),i=await this.hass.callWS({type:"houseplan/config/set",config:t,expected_rev:this._cfgRev});this._adoption.acceptConfigWrite(t,i)}_writeConfig(){if(this._editorRuntime)return this._editorRuntime._writeConfig();this._writesPending++,this._writeChain=Eu(this._writeChain,async()=>{if(!this._serverCfg)return;const e=bo(this._serverCfg);this._adoption.stageConfigCandidate(e),await this._sendConfigCandidate(e)});return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_geometrySnapshotFromConfig(e,t){return this._editorRuntimeOrThrow()._geometrySnapshotFromConfig(e,t)}_geometrySnapshot(e=this._space){return this._editorRuntimeOrThrow()._geometrySnapshot(e)}_recordGeometry(e,t){return this._editorRuntimeOrThrow()._recordGeometry(e,t)}_restoreGeometryStateInConfig(e,t,i=!1){return this._editorRuntimeOrThrow()._restoreGeometryStateInConfig(e,t,i)}_restoreGeometryStateLocal(e){return this._editorRuntimeOrThrow()._restoreGeometryStateLocal(e)}_wallModelBlockerLabel(e){return this._editorRuntimeOrThrow()._wallModelBlockerLabel(e)}_hasLegacyZeroWallFields(e=this._serverCfg){return this._editorRuntimeOrThrow()._hasLegacyZeroWallFields(e)}_showWallModelMigrationBlocked(e){return this._editorRuntimeOrThrow()._showWallModelMigrationBlocked(e)}_limitSegmentsOf(e){return this._editorRuntimeOrThrow()._limitSegmentsOf(e)}_junctionLimitViolations(e,t,i,n){return this._editorRuntimeOrThrow()._junctionLimitViolations(e,t,i,n)}_junctionLimitLabel(e){return this._editorRuntimeOrThrow()._junctionLimitLabel(e)}_junctionLimitsIntroduced(e,t,i){return this._editorRuntimeOrThrow()._junctionLimitsIntroduced(e,t,i)}_commitPhysicalGeometry(e,t,i=[]){return this._editorRuntimeOrThrow()._commitPhysicalGeometry(e,t,i)}_clearGeometryGesture(){return this._editorRuntime?this._editorRuntimeOrThrow()._clearGeometryGesture():(this._path=[],this._planSnapHover=null,this._cursorPt=null,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingPreset=null,this._openingRebindId=null,this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._roomDeleteDialog=null,this._wallDialog=null,this._physicalDialog=null,this._physicalSel=null,this._physicalDrag=null,this._physicalRotate=null,this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._openingDialog=null,this._resize?.reset(),this._decorDraft=null,this._decorMove=null,this._dtDrag=null,void(this._bdDrag=null))}_stagePointerCancel(e){if(this._deviceHits.cancel(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover"),this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null),this._doubleFit.clear(),this._editorRuntime)return this._editorRuntime._stagePointerCancel(e);this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._swipeStart=null),this._viewportGestureDirty&&0===this._pointers.size&&(this._viewportGestureDirty=!1,this.requestUpdate())}_applyGeometryState(e,t=!1){return this._editorRuntimeOrThrow()._applyGeometryState(e,t)}_roomAt(e){return this._editorRuntimeOrThrow()._roomAt(e)}_overlapRoom(e){return this._editorRuntimeOrThrow()._overlapRoom(e)}_pointInRoom(e,t){return t.poly?mi(e,t.poly):null!=t.x&&e[0]>=t.x&&e[0]<=t.x+t.w&&e[1]>=t.y&&e[1]<=t.y+t.h}_contourSelfIntersects(e){return this._editorRuntimeOrThrow()._contourSelfIntersects(e)}_canAppendWallPoint(){return this._editorRuntimeOrThrow()._canAppendWallPoint()}_markupClick(e){if(this._editorRuntime)return this._editorRuntime._markupClick(e)}_activeWallSourceKey(e){return this._editorRuntimeOrThrow()._activeWallSourceKey(e)}_wallGraphSources(e){return this._editorRuntimeOrThrow()._wallGraphSources(e)}_wallFaceGraph(e,t){return this._editorRuntimeOrThrow()._wallFaceGraph(e,t)}_offerWallFaces(e,t=this._path.length-2,i){return this._editorRuntimeOrThrow()._offerWallFaces(e,t,i)}_beginWallFaceBatch(e){return this._editorRuntimeOrThrow()._beginWallFaceBatch(e)}_offerExistingWallFace(e){return this._editorRuntimeOrThrow()._offerExistingWallFace(e)}_columnClick(e){return this._editorRuntimeOrThrow()._columnClick(e)}_openPhysicalDialog(e,t){return this._editorRuntimeOrThrow()._openPhysicalDialog(e,t)}_physicalDown(e,t,i){return this._editorRuntimeOrThrow()._physicalDown(e,t,i)}_clampPhysicalDelta(e,t,i){return this._editorRuntimeOrThrow()._clampPhysicalDelta(e,t,i)}_physicalMove(e){return this._editorRuntimeOrThrow()._physicalMove(e)}_physicalUp(e){return this._editorRuntimeOrThrow()._physicalUp(e)}_registerPhysicalTap(e,t){return this._editorRuntimeOrThrow()._registerPhysicalTap(e,t)}_cancelPhysicalGesture(){return this._editorRuntimeOrThrow()._cancelPhysicalGesture()}_physicalRotateDown(e,t){return this._editorRuntimeOrThrow()._physicalRotateDown(e,t)}_physicalRotateMove(e){return this._editorRuntimeOrThrow()._physicalRotateMove(e)}_physicalRotateUp(e){return this._editorRuntimeOrThrow()._physicalRotateUp(e)}_rszRooms(){return this._editorRuntimeOrThrow()._rszRooms()}_rszOpenings(){return this._editorRuntimeOrThrow()._rszOpenings()}_rszObstacles(){return this._editorRuntimeOrThrow()._rszObstacles()}_rszOptsFor(e,t){return this._editorRuntimeOrThrow()._rszOptsFor(e,t)}_rszResolution(e,t,i){return this._editorRuntimeOrThrow()._rszResolution(e,t,i)}_rszSnapshot(){return this._editorRuntimeOrThrow()._rszSnapshot()}_rszResetController(){return this._editorRuntimeOrThrow()._rszResetController()}_rszProjectPreview(e,t,i,n,r){return this._editorRuntimeOrThrow()._rszProjectPreview(e,t,i,n,r)}_rszAcceptPreview(e,t){return this._editorRuntimeOrThrow()._rszAcceptPreview(e,t)}_rszSpaceCandidateGeometry(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateGeometry(e,t)}_rszSpaceCandidateRenderable(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateRenderable(e,t)}_rszCandidateRenderable(e){return this._editorRuntimeOrThrow()._rszCandidateRenderable(e)}_rszEdgeDown(e,t,i){return this._editorRuntimeOrThrow()._rszEdgeDown(e,t,i)}_rszReasonText(e){return this._editorRuntimeOrThrow()._rszReasonText(e)}_rszDisabledActivate(e,t){return this._editorRuntimeOrThrow()._rszDisabledActivate(e,t)}_rszDisabledKey(e,t){return this._editorRuntimeOrThrow()._rszDisabledKey(e,t)}_rszMove(e){return this._editorRuntimeOrThrow()._rszMove(e)}_rszUp(e){return this._editorRuntimeOrThrow()._rszUp(e)}_rszCancelDrag(e){return this._editorRuntimeOrThrow()._rszCancelDrag(e)}_rszPointerCancel(e){return this._editorRuntimeOrThrow()._rszPointerCancel(e)}_rszEdgeLabels(e,t,i=this._resize?.rooms){return this._editorRuntimeOrThrow()._rszEdgeLabels(e,t,i)}_rszInnerSpanCms(e,t,i){return this._editorRuntimeOrThrow()._rszInnerSpanCms(e,t,i)}_renderResizeMeasurements(){return this._editorRuntimeOrThrow()._renderResizeMeasurements()}_renderResizeLayer(e,t){return this._editorRuntimeOrThrow()._renderResizeLayer(e,t)}get _openingsR(){const e=this._curSpaceCfg,t=this._spaceH,i=this._spaceModel();return i?(e?.openings||[]).flatMap(e=>{const n={...e,rx:e.x*uv,ry:e.y*t,rlen:e.length*uv};if(!e.host||"wall"===e.host.kind)return[n];const r=Xu(e,i.partitions,uv,this._cellCm,this._gridPitch);if(!r.resolved)return"plan"===this._mode?[{...n,orphanReason:r.reason||"invalid-host"}]:[];let[o,s]=r.resolved.center;const a=this._physicalDrag;return a?.moved&&"partition"===a.kind&&a.id===e.host.id&&(o+=a.delta[0],s+=a.delta[1]),[{...e,rx:o,ry:s,rlen:r.resolved.length,angle:r.resolved.angle,partitionHost:r.resolved}]}):[]}_partitionOpeningCuts(e=this._spaceModel(),t=()=>!0){if(!e)return[];return W_(j_(this._curSpaceCfg?.id===e.id?this._curSpaceCfg:null,e,this._cellCm,this._gridPitch,uv),t)}_roomWallOpeningInputs(e=this._openingsR,t=this._spaceModel()){if(!t)return[];const i=this._openCuts();return U_(e,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,uv)}_openingFace(e,t,i){return e.partitionHost?ep(e.partitionHost,i):la(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen,flip_v:i})}_cmToUnits(e){return e/this._cellCm*this._gridPitch}get _decorList(){const e=this._curSpaceCfg;return Array.isArray(e?.decor)?e.decor:[]}get _decorH(){return uv}_decorResolvedStyle(e){return function(e,t,i,n=xr){const r="rect"===e?.kind||"ellipse"===e?.kind,o=e,s=Kt(o?.color,n.color);return{color:s,opacity:Sr(o?.opacity,n.opacity),widthCm:Dr(e,t,i,n.widthCm),fill:!!r&&!0===o?.fill,fillColor:Kt(o?.fill_color,o?.fill?s:n.fillColor),fillOpacity:r&&o?.fill?Sr(o?.fill_opacity,.25):n.fillOpacity}}(e,this._cellCm,this._gridPitch,xr)}_decorWidthUnits(e){return((e,t,i,n=xr.widthCm)=>{const r=Number(e?.width_cm);if(Number.isFinite(r)&&r>0)return Cr(r,t,i);const o=Number(e?.width);return Number.isFinite(o)&&o>0?o:Cr(n,t,i)})(e,this._cellCm,this._gridPitch,xr.widthCm)}_decorTextSizeCm(e){if("text"===e?.kind){const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?t:Tr(20*tn(e),this._cellCm,this._gridPitch)}return Tr(20,this._cellCm,this._gridPitch)}_decorTextUnits(e){if("text"!==e.kind)return 20;const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?Cr(t,this._cellCm,this._gridPitch):20*tn(e)}_decorSmallField(e){return Math.round(100*(this._imperial?e/2.54:e))/100}_decorSmallCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(100,t)):.1}_decorTextCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(2e3,t)):.1}_decorLargeField(e){return Math.round(100*(this._imperial?e/30.48:e/100))/100}_decorLargeCm(e){const t=this._imperial?30.48*e:100*e;return Number.isFinite(t)?Math.max(.1,Math.min(Xa*this._cellCm,t)):.1}_angleField(e){const t=Number(e);return Number.isFinite(t)?String(Number(t.toFixed(3))):"0"}_decorBoxOf(e){return"rect"!==e.kind&&"ellipse"!==e.kind&&"furniture"!==e.kind&&"image"!==e.kind?null:{x:e.x*uv,y:e.y*this._decorH,w:e.w*uv,h:e.h*this._decorH,angle:$r(e.angle)||void 0}}_decorSnapGeometry(e){return this._editorRuntimeOrThrow()._decorSnapGeometry(e)}_decorSnap(e,t="mouse",i){return this._editorRuntimeOrThrow()._decorSnap(e,t,i)}_replaceDecor(e,t){return this._editorRuntimeOrThrow()._replaceDecor(e,t)}_cancelDecorGesture(){return this._editorRuntimeOrThrow()._cancelDecorGesture()}_decorPointerDown(e){return this._editorRuntimeOrThrow()._decorPointerDown(e)}_decorCommitDraft(){return this._editorRuntimeOrThrow()._decorCommitDraft()}_decorShapeDown(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDown(e,t)}_decorMoveUpdate(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-move",()=>this._editorRuntimeOrThrow()._decorMoveUpdate(e))}_decorNudge(e,t){if("decor"!==this._mode||"select"!==this._decorTool||!this._decorSel||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag)return!1;const i=this._decorList.find(e=>e.id===this._decorSel),n=this._curSpaceCfg;if(!i||!n)return!1;const r=function(e,t,i,n,r,o){if(!([t,i,n,r,o].every(Number.isFinite)&&r>0))return null;let s;if(s="line"===e.kind?[[e.x1,e.y1],[e.x2,e.y2]]:"text"===e.kind?[[e.x,e.y]]:Fr(e),!s.length||s.some(e=>!e.slice(0,2).every(Number.isFinite)))return null;const a=s.map(e=>e[0]),l=s.map(e=>e[1]),c=Math.min(...a),h=Math.max(...a),d=Math.min(...l),u=Math.max(...l),p=t/n,_=i/r,m=p>0?Math.min(p,Math.max(0,o-h)):Math.max(p,Math.min(0,-o-c)),g=_>0?Math.min(_,Math.max(0,o-u)):Math.max(_,Math.min(0,-o-d));return m||g?"line"===e.kind?{...e,x1:e.x1+m,y1:e.y1+g,x2:e.x2+m,y2:e.y2+g}:{...e,x:e.x+m,y:e.y+g}:null}(i,e,t,uv,this._decorH,Xa);if(!r)return!1;const o=this._geometrySnapshot();return n.decor=this._decorList.map(e=>e.id===i.id?r:e),this._recordGeometry(this._t("history.decor_move"),o),this._saveConfig(),this.requestUpdate(),!0}_decorShapeDbl(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDbl(e,t)}_openDecorProperties(e){return this._editorRuntimeOrThrow()._openDecorProperties(e)}_decorOpenText(e){return this._editorRuntimeOrThrow()._decorOpenText(e)}_decorRememberTextSelection(e){return this._editorRuntimeOrThrow()._decorRememberTextSelection(e)}_decorInsertLiveVariable(e){return this._editorRuntimeOrThrow()._decorInsertLiveVariable(e)}_decorSaveText(){return this._editorRuntimeOrThrow()._decorSaveText()}_decorSaveShape(){return this._editorRuntimeOrThrow()._decorSaveShape()}get _dtSel(){return"decor"===this._mode&&"select"===this._decorTool&&this._decorSel&&this._decorList.find(e=>e.id===this._decorSel)||null}_dtPivot(e){return this._editorRuntimeOrThrow()._dtPivot(e)}_dtApply(e,t){return this._editorRuntimeOrThrow()._dtApply(e,t)}_dtStart(e,t,i,n){return this._editorRuntimeOrThrow()._dtStart(e,t,i,n)}_dtMove(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-transform",()=>this._editorRuntimeOrThrow()._dtMove(e))}_dtUp(){return this._editorRuntimeOrThrow()._flushPointerMove("decor-transform"),this._editorRuntimeOrThrow()._dtUp()}_dtMeasure(){return this._editorRuntimeOrThrow()._dtMeasure()}_deleteDecor(e){return this._editorRuntimeOrThrow()._deleteDecor(e)}_decorDeleteSel(){return this._editorRuntimeOrThrow()._decorDeleteSel()}_confirmDecorErase(){return this._editorRuntimeOrThrow()._confirmDecorErase()}get _bdBase(){const e=this._curSpaceCfg;return e?.plan_url?{...Wa(e.plan_aspect,uv)}:null}get _bdRect(){const e=this._curSpaceCfg;return e?.plan_url?Va(e,uv):null}get _bdParams(){const e=this._curSpaceCfg,t=Number(e?.plan_x),i=Number(e?.plan_y),n=Number(e?.plan_scale),r=Number(e?.plan_scale_x),o=Number(e?.plan_scale_y),s=Number.isFinite(n)&&n>0?n:1;return{dx:Number.isFinite(t)?t:0,dy:Number.isFinite(i)?i:0,sx:Number.isFinite(r)&&r>0?r:s,sy:Number.isFinite(o)&&o>0?o:s,angle:$r(e?.plan_angle)}}_openBackdropDialog(e){if(this._editorRuntime)return this._editorRuntime._openBackdropDialog(e)}_saveBackdropDialog(){return this._editorRuntimeOrThrow()._saveBackdropDialog()}get _bdActive(){return"decor"===this._mode&&!!this._bdRect&&"backdrop"===this._decorTool}get _bdMovable(){return"decor"===this._mode&&"backdrop"===this._decorTool&&!!this._bdRect}_bdApply(e,t,i,n,r){return this._editorRuntimeOrThrow()._bdApply(e,t,i,n,r)}_bdStart(e,t,i=!1){return this._editorRuntimeOrThrow()._bdStart(e,t,i)}_bdMove(e){return this._editorRuntimeOrThrow()._bdMove(e)}get _bdMoved(){if("decor"!==this._mode||!this._bdRect)return!1;const e=this._bdParams;return 0!==e.dx||0!==e.dy||1!==e.sx||1!==e.sy||0!==e.angle}_bdReset(){return this._editorRuntimeOrThrow()._bdReset()}_bdUp(){return this._editorRuntimeOrThrow()._bdUp()}get _bdLive(){if(!this._bdDrag)return null;const e=this._bdRect;return e?{x:e.x+e.w/2,y:e.y+e.h/2,text:`${this._fmtLen([0,0],[e.w,0])} × ${this._fmtLen([0,0],[0,e.h])}`}:null}_renderBackdropFrame(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderBackdropFrame(e):G}_renderTextFrame(e){const t=this._dtSel;if(!t)return G;if("text"===t.kind&&this._dtBox?.id!==t.id)return G;const i="text"===t.kind?this._dtBox:this._decorBoxOf(t);if("line"!==t.kind&&!i)return G;const n=.018*Math.max(e.w,e.h),r=n/4;if("line"===t.kind){const e=[t.x1*uv,t.y1*this._decorH],i=[t.x2*uv,t.y2*this._decorH];return W` + `}_stageAspect(e=this._baseVb()){const t=this._stageEl;return t&&t.clientHeight?t.clientWidth/t.clientHeight:e[2]/e[3]}_viewOr(e){return this._view&&this._view.w?this._view:Oi(e,this._stageAspect(e))}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._viewModeSnap;if(t?.space===this._space&&t.w)return t.w*t.zoom/this._zoom;const i=this._stageEl,n=this.renderRoot.querySelector(".editorchrome");if(!i?.clientWidth||!i.clientHeight)return e.w;const r=i.clientHeight+(n?.offsetHeight||0);return this._viewForModeTarget(this._zoom,void 0,void 0,i.clientWidth,r).w}_screenToVb(e,t){const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i?.clientWidth||1,o=i?.clientHeight||1;return[n.x+e/r*n.w,n.y+t/o*n.h]}_clampView(e,t){const i=(e,t,i,n)=>{const r=1*Math.max(t,n),o=i-r,s=i+n-t+r;return Math.max(Math.min(o,s),Math.min(Math.max(o,s),e))};return{w:e.w,h:e.h,x:i(e.x,e.w,t.x,t.w),y:i(e.y,e.h,t.y,t.h)}}_applyView(e,t,i){this._cancelCameraTransition(!1);const n=this._baseVb(),r=Oi(n,this._stageAspect()),o=Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,e)),s=r.w/o,a=r.h/o,l=this._viewOr(n),c=t??l.x+l.w/2,h=i??l.y+l.h/2,d=this._clampView({x:c-s/2,y:h-a/2,w:s,h:a},r);return!(this._view&&Math.abs(this._zoom-o)<1e-9&&Math.abs(this._view.x-d.x)<1e-6&&Math.abs(this._view.y-d.y)<1e-6&&Math.abs(this._view.w-d.w)<1e-6&&Math.abs(this._view.h-d.h)<1e-6)&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=o,this._view=d,this._liveVp(),!0)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const e=()=>{if(!this._booting)return;const t=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=t);const n=t-this._bootStart;var r,o,s;n>=1200||n>=700&&i>0&&t-this._bootLastChange>=250&&(r=Pl,o=this._serverCfg,s=Hl,"pending"!==r.state()||!Tl(o,s))?this._bootSettled():this._bootTimer=window.setTimeout(e,100)};this._bootTimer=window.setTimeout(e,100)}_bootSettled(){this._booting&&!this._bootSettling&&(this._bootSettling=!0,this._refitView(),this._bootSettleRaf=requestAnimationFrame(()=>{this._bootSettleRaf=0,this._finishBootSettled()}))}_finishBootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1,this._bootSettling=!1;const e=this._stageEl?.clientHeight??0;!this._config?.kiosk&&e>0&&this._warmPatch({hdrH:this._hdrH,stageH:e,vp:this._warmViewportState()},!0),this._bootFading=!0,this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220),this._bootSoft=!0,clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},nv)}_bootSoftCancel(){if(!this._bootSoft)return;clearTimeout(this._bootSoftTimer),this._bootSoft=!1;const e=function(e,t,i,n){if(!t)return null;const r=Qg(e,t,i);return i||n||null===r||(t.style.height=`calc(100dvh - ${r}px)`),t.classList.remove("hpsettle"),t.getBoundingClientRect(),t.clientWidth<=0||t.clientHeight<=0?null:{headerHeight:r,size:[t.clientWidth,t.clientHeight]}}(this.renderRoot,this._stageEl,this.panelHost,this._kiosk);if(!e)return;null!==e.headerHeight&&(this._hdrH=e.headerHeight),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null,this._lastValidStageSize=e.size;const t=this._view;t&&this._applyView(this._zoom,t.x+t.w/2,t.y+t.h/2)}_beginResumeSettle(){this._booting||this._resumeSettling||(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0),this._viewportInvalidAt=0,this._beginContinuityCandidate("warm-resume",!1),this._loading?this.requestUpdate():this._loadFromServer())}_refitView(){if(this._modeTransitionBusy||this._warmModeRequest)return;const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return this._cancelCameraTransition(!1),void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight];if(this._bootSoft&&this._warmVp)return this._lastValidStageSize=t,void(this._pendingRefitSize=null);const i=this._lastValidStageSize,n=!!i&&Math.abs(i[0]-t[0])<=.5&&Math.abs(i[1]-t[1])<=.5,r=this._viewportInvalidAt?Date.now()-this._viewportInvalidAt:0;if(this._viewportInvalidAt=0,n)this._pendingRefitSize=null;else{if(this._cancelCameraTransition(!1),!i)return this._lastValidStageSize=t,void(this._roomFocus?.spaceId===this._space?this._fitRoom(this._roomFocus.roomId,!1):this._view||this._applyView(this._zoom));this._pendingRefitSize=t,this._refitRaf||(this._refitRaf=requestAnimationFrame(()=>{this._refitRaf=0;const e=this._pendingRefitSize;this._pendingRefitSize=null;const t=this._stageEl;if(!e||!t||t.clientWidth<=0||t.clientHeight<=0)return;if(Math.abs(t.clientWidth-e[0])>.5||Math.abs(t.clientHeight-e[1])>.5)return void this._refitView();const i=this._lastValidStageSize;if(i&&Math.abs(i[0]-e[0])<=.5&&Math.abs(i[1]-e[1])<=.5)return;this._lastValidStageSize=e;const n=this._view;r>=ic?this._beginContinuityCandidate("stage-size-restored",!0,"stage-size"):this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._roomFocus?.spaceId!==this._space?this._applyView(this._zoom,n?n.x+n.w/2:void 0,n?n.y+n.h/2:void 0):this._fitRoom(this._roomFocus.roomId,!1)}))}}_cameraTargetAt(e,t,i,n=!1){const r=this._stageEl;if(!r||r.clientWidth<=0||r.clientHeight<=0)return null;const o=Oi(this._baseVb(),this._stageAspect()),s=Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,i)),a=function(e,t,i,n,r,o,s){if(!Vg(e)||!Vg({zoom:t,viewBox:i})||!Gg(n)||n<=0||!Gg(r)||r<=0||!Gg(o)||!Gg(s))return null;const a=o/n,l=s/r,c=e.viewBox.x+a*e.viewBox.w,h=e.viewBox.y+l*e.viewBox.h,d=i.w/t,u=i.h/t;return{zoom:t,viewBox:{x:c-a*d,y:h-l*u,w:d,h:u}}}(n&&this._cameraTransition.target||this._cameraState(),s,o,r.clientWidth,r.clientHeight,e,t);return a?(a.viewBox=this._clampView(a.viewBox,o),{target:a,fit:o}):null}_zoomAt(e,t,i){this._clearRoomFocus(),this._cancelCameraTransition(!1);const n=this._cameraTargetAt(e,t,i);n&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=n.target.zoom,this._view={...n.target.viewBox},this._liveVp())}_onWheel(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;e.preventDefault();const i=t.getBoundingClientRect(),n=e.deltaY<0?1.15:1/1.15,r=this._cameraTransition.target?.zoom??this._zoom,o=this._cameraTargetAt(e.clientX-i.left,e.clientY-i.top,r*n,!0);o&&this._startCameraTransition(o.target,o.fit,"wheel",160)}_stepZoom(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;const i=this._cameraTransition.target?.zoom??this._zoom,n=this._cameraTargetAt(t.clientWidth/2,t.clientHeight/2,i*(e>0?1.4:1/1.4),!0);n&&this._startCameraTransition(n.target,n.fit,"button",180)}_resetZoom(e="fit"){this._clearRoomFocus(),this._prepareCameraCommand();const t=Oi(this._baseVb(),this._stageAspect());this._startCameraTransition({zoom:1,viewBox:{...t}},t,e,220)}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem(cv,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){this._clearRoomFocus(!0),this._cancelCameraTransition(!1);const e=this._zoomBySpace[this._space]||1;this._zoom=e;const t=this._stageEl;if(t&&t.clientHeight){const t=this._baseVb();return this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const t=this._baseVb();this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),this.requestUpdate()})}_stagePointerDown(e){this._bootSoftCancel();const t=e.isPrimary&&0===e.button&&"view"===this._mode?mf(e.composedPath()):null;if(this._roomPointer=t?{pointerId:e.pointerId,spaceId:this._space,roomId:t}:null,this._doubleFit.pointerDown(e,this._space,this._doubleFitEnabled),this._cancelCameraTransition(!1,!0),this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:e.clientX,y:e.clientY,id:e.pointerId},e.target.closest?.(".dev, .roomlabel, .oplock")||(clearTimeout(this._kioskHoldTimer),this._kioskHoldTimer=window.setTimeout(()=>{this._roomPointer=null,this._doubleFit.clear(),this._kioskDialog=!0,this._swipeStart=null},3e3))):(this._swipeStart=null,clearTimeout(this._kioskHoldTimer))),this._drag||this._deviceDrag)return;if(this._markup&&e.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&e.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(e))return;this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY});const i=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:e.clientX,sy:e.clientY,vx:i.x,vy:i.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y);this._pinchStart={dist:t,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return!this._hasFixedFloor&&this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(e){if(this._physicalRotate?.pid!==e.pointerId)if(this._physicalDrag?.pid!==e.pointerId)if(this._dtDrag?.pid!==e.pointerId)if(this._bdDrag?.pid!==e.pointerId){if(this._decorDraft?.pid===e.pointerId){const t=this._decorDraft;let i=this._decorSnap(this._svgPoint(e),e.pointerType);if(e.shiftKey&&("rect"===t.kind||"ellipse"===t.kind)){const e=i[0]-t.a[0],n=i[1]-t.a[1],r=Math.max(Math.abs(e),Math.abs(n));i=this._snap([t.a[0]+(e<0?-r:r),t.a[1]+(n<0?-r:r)])}return void(this._decorDraft={...t,b:i})}if(this._decorMove?.pid!==e.pointerId){if("decor"!==this._mode||"furniture"!==this._decorTool&&"image"!==this._decorTool||!this._editorRuntime||(this._notePointer(e),!this._editorRuntime._furnPointerMove(e,this._pointerModality.hoverEnabled)))if(this._pointers.has(e.pointerId)){if(this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(e),this._pinchStart&&this._pointers.size>=2){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),n=(e[0].x+e[1].x)/2-i.left,r=(e[0].y+e[1].y)/2-i.top;this._zoomAt(n,r,this._pinchStart.zoom*t),this._viewportGestureDirty=!0,this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const t=e.clientX-this._panStart.sx,i=e.clientY-this._panStart.sy;Math.abs(t)+Math.abs(i)>4&&(this._roomPointer=null,this._doubleFit.clear(),this._suppressClick=!0,clearTimeout(this._holdTimer),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover()),null===this._panLock&&Math.abs(t)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(t)>1.5*Math.abs(i)?"swipe":"pan","pan"===this._panLock&&this._clearRoomFocus());const n=this._stageEl;if("pan"===this._panLock&&n){const e=this._baseVb(),r=this._viewOr(e),o=Oi(e,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-t/(n.clientWidth||1)*r.w,y:this._panStart.vy-i/(n.clientHeight||1)*r.h,w:r.w,h:r.h},o),this._viewportGestureDirty=!0,this._liveVp()}}}else this._markupMove(e)}else this._decorMoveUpdate(e)}else this._bdMove(e);else this._dtMove(e);else this._physicalMove(e);else this._physicalRotateMove(e)}_stagePointerLeave(e){this._editorRuntime?._cancelPointerMove("markup-hover"),"decor"===this._mode&&this._editorRuntime?._furnPointerLeave(e),this._markup&&("opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover())}_stagePointerUp(e){this._deviceHits.release(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover");const t=(i=this._roomPointer,n=e.pointerId,r=this._space,o=this._roomPointer&&"view"===this._mode?mf(e.composedPath()):null,s=this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired||this._touchSequenceMultitouch,!i||s||i.pointerId!==n||i.spaceId!==r||i.roomId!==o?null:i.roomId);var i,n,r,o,s;this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null);if(this._doubleFit.pointerUp(e,this._space,this._doubleFitEnabled,this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired)&&this._fitAll("double-tap"),this._kiosk){clearTimeout(this._kioskHoldTimer);const i=this._swipeStart;if(this._swipeStart=null,!t&&i&&i.id===e.pointerId){const t=e.clientX-i.x,n=e.clientY-i.y,r="pan"===this._panLock?null:function(e,t,i,n,r,o=60){if(i>1.001||n.length<2)return null;if(Math.abs(e)e.id),this._space);r&&this._slideTo(r,t<0?"left":"right")&&(this._saveNav(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._showKioskDots())}}this._physicalDrag?.pid!==e.pointerId?this._physicalRotate?.pid!==e.pointerId?this._dtDrag?.pid!==e.pointerId?this._bdDrag?.pid!==e.pointerId?this._decorDraft?.pid!==e.pointerId?this._decorMove?.pid!==e.pointerId?this._editorRuntime?._furnPointerUp(e)||(this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._suppressClick&&setTimeout(()=>this._suppressClick=!1,0)),this._viewportGestureDirty&&0===this._pointers.size&&!t&&(this._viewportGestureDirty=!1,this.requestUpdate()),t&&this._fitRoom(t)):this._editorRuntimeOrThrow()._dmUp():this._decorCommitDraft():this._bdUp():this._dtUp():this._physicalRotateUp(e):this._physicalUp(e)}_clickRoom(e){!this._suppressClick&&e.area&&gv("/config/areas/area/"+e.area)}_roomLabelKey(e,t){"view"!==this._mode||"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),e.stopPropagation(),this._fitRoom(t))}_pointerDown(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if("view"===this._mode&&"touch"===e.pointerType&&this._touchSequenceMultitouch)return;if(t=this._deviceHits.begin(this.renderRoot,this._renderDevices,this._space,e,t),"view"===this._mode){this._holdFired=!1,clearTimeout(this._holdTimer);const i=e.pointerId,n=e.currentTarget;return void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._interruptViewGesture(i,n),this._infoCard=t},600))}if("ha_disabled"===t.bindingStatus?.kind||this._devicePositionBusy)return;if(this._deviceDrag)return void(this._deviceDrag.pointerId!==e.pointerId&&this._cancelDeviceDrag());e.preventDefault();const i=this._pos(t);this._deviceDrag={id:t.id,spaceId:t.space,displayName:t.name,pointerId:e.pointerId,source:e.currentTarget,sx:e.clientX,sy:e.clientY,ox:i.x,oy:i.y,moved:!1,before:gg(this._layout,t.id),start:this._devicePlacementForCanvas(t,i.x,i.y)},vv(e),this._tip=null,this._syncLiveHover()}_pointerMove(e,t){if("view"!==this._mode&&"devices"!==this._mode)return null;if(t=this._deviceForPointerEvent(e,t),"devices"!==this._mode)return t;const i=this._deviceDrag;return i&&i.id===t.id&&i.pointerId===e.pointerId?(this._editorRuntimeOrThrow()._queuePointerMove("device",()=>this._pointerMoveNow(e,t)),t):t}_pointerMoveNow(e,t){if("devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;const n=this.renderRoot.querySelector(".stage");if(!n)return;const r=this._baseVb(),o=n.getBoundingClientRect(),s=this._viewOr(r),a=(e.clientX-i.sx)/o.width*s.w,l=(e.clientY-i.sy)/o.height*s.h;Math.abs(e.clientX-i.sx)+Math.abs(e.clientY-i.sy)>3&&(i.moved=!0,clearTimeout(this._holdTimer));const c=rl(i.ox+a),h=rl(i.oy+l);this._previewDevicePlacement(t.id,this._devicePlacementForCanvas(t,c,h))}_pointerUp(e,t){if(t=this._deviceForPointerEvent(e,t),this._deviceHits.release(e.pointerId),clearTimeout(this._holdTimer),"devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;this._editorRuntimeOrThrow()._flushPointerMove("device"),this._deviceDrag=null;const n=gg(this._layout,t.id);var r,o;i.moved&&null!==n&&(r=n,o=i.start,null===r||null===o?r!==o:r.x!==o.x||r.y!==o.y||r.s!==o.s)?(this._selId=t.id,this._suppressClick=!0,window.setTimeout(()=>{this._suppressClick=!1},0),this._devicePositionBusy=!0,this.requestUpdate(),this._persistDevicePlacement(t.id,n).then(()=>{const e=this._t("history.device_move",{name:i.displayName});this._devicePositionHistory.push({name:e,before:{deviceId:i.id,spaceId:i.spaceId,placement:i.before},after:{deviceId:i.id,spaceId:i.spaceId,placement:n}})}).catch(e=>{this._previewDevicePlacement(t.id,i.before),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))}).finally(()=>{this._devicePositionBusy=!1,this.requestUpdate()})):this._previewDevicePlacement(t.id,i.before)}_pointerCancel(e,t){t=this._deviceForPointerEvent(e,t),this._deviceHits.cancel(e.pointerId),this._deviceDrag?.id===t.id&&this._deviceDrag.pointerId===e.pointerId&&this._cancelDeviceDrag()}_showToast(e){for(const e of this.renderRoot.querySelectorAll("hp-dialog"))e.closeTransientOverlays("toast");this._toast=e,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}_syncPointerHoverTargets(){const e=this._pointerModality.hoverEnabled;for(const t of this.renderRoot.querySelectorAll(uv))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(uv)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(uv))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),this._liveRt?.clearDeviceFocus(),this._deviceHits.hover(this.renderRoot,null),this._tip&&(this._tip=null),this._hoverRoom&&(this._hoverRoom=null),this._syncLiveHover()}_notePointer(e){const t=this._pointerModality.modality,i=this._pointerModality.note(e);"touch"!==i&&"pen"!==i||t===i&&!this._tip&&!this._hoverRoom||this._clearTransientHover()}_guardTouchGesture(e){if(this._editorSecondary?.handleOutsideDismiss(e))return;if(this._touchClickGuard.handleActivation(e,this._suppressClick))return;const t=e;if(this._notePointer(t),"pointercancel"===e.type||"lostpointercapture"===e.type?this._doubleFit.clear():"pointerdown"===e.type&&this._doubleFit.clearOutside(t),"pointerdown"===e.type&&this._touchClickGuard.pointerDown(t.pointerId,t.pointerType),"touch"!==t.pointerType)return;if("pointerdown"===e.type){if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._deviceHits.clearPointers(),this._clearRoomFocus(!0),this._clearTransientHover(),clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),this._swipeStart=null;const e=[...this._touchContacts.values()];if("view"===this._mode&&!this._vacFit&&e.every(e=>e.inStage)){this._pointers=new Map([...this._touchContacts].map(([e,t])=>[e,{x:t.x,y:t.y}]));const[t,i]=e;this._pinchStart={dist:Math.hypot(t.x-i.x,t.y-i.y),zoom:this._zoom},this._panStart=null,this._panLock=null}else this._vacFit&&(this._pointers.clear(),this._pinchStart=null,this._panStart=null,this._panLock=null)}return}if("pointermove"===e.type){const e=this._touchContacts.get(t.pointerId);if(!e)return;const i={...e,x:t.clientX,y:t.clientY};if(this._touchContacts.set(t.pointerId,i),this._touchSequenceMultitouch&&"view"===this._mode&&!this._vacFit&&this._pinchStart&&[...this._touchContacts.values()].every(e=>e.inStage)){this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=[...this._touchContacts.values()];if(e.length>=2&&this._stageEl){const[t,i]=e,n=Math.hypot(t.x-i.x,t.y-i.y)/(this._pinchStart.dist||1),r=this._stageEl.getBoundingClientRect();this._zoomAt((t.x+i.x)/2-r.left,(t.y+i.y)/2-r.top,this._pinchStart.zoom*n),this._saveZoom()}}return}if("pointerup"!==e.type&&"pointercancel"!==e.type&&"lostpointercapture"!==e.type)return;const i=this._touchClickGuard.pointerTerminal(t.pointerId,t.pointerType);if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),i){if(this._pointers.delete(t.pointerId),!this._vacFit&&this._pointers.size>=2){const[e,t]=[...this._pointers.values()];this._pinchStart={dist:Math.hypot(e.x-t.x,e.y-t.y),zoom:this._zoom}}else this._pinchStart=null;0===this._pointers.size&&(this._panStart=null,this._panLock=null)}}_showTip(e,t,i,n,r,o,s=!1){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||this._deviceDrag||s&&this._liveRt?.deviceFocusActive()||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:n,temp:r,hum:o,room:s,source:"pointer"},this._syncLiveHover()))}_roomTipEnabledForPointer(e){return"view"===this._mode&&(this._notePointer(e),!!_n(this._settings)||(this._tip?.room&&(this._tip=null,this._syncLiveHover()),!1))}get _gridPitch(){return el}get _cellCm(){const e=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(e)&&e>0?e:5}_fmtLen(e,t){const i=function(e,t,i,n){return Math.hypot(t[0]-e[0],t[1]-e[1])/i*n}(e,t,this._gridPitch,this._cellCm);return ti(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const e=this._resize?.preview;return e&&e.space===this._space?e.sp:this._serverCfg?.spaces.find(e=>e.id===this._space)}get _renderCfg(){const e=this._resize?.preview;return e&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(t=>t.id===e.space?e.sp:t)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,pv}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return oi(e?.rooms||[]).map(e=>[e[0]*pv,e[1]*t,e[2]*pv,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(hv)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(hv,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,this._configReloadAuthority.invalidateLifecycle(),this._summary?.leaveRoute(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._drawWallField=null,this._showHidden=!1,this._tapConfirm=null,this._vacCalConfirm=null,this._decorEraseConfirm=null,this._openingInfo=null,this._closeInfoCard(),this._rulesDialog=null,this._alignDialog=null,this._preflightClipboardFallback=null,this._backupImportDialog=null,this._backupExportDialog=null,this._pdfDialog=!1,this._supportDialog?.preview?.token&&this._editorRuntime?._discardSupportPreview(this._supportDialog.preview.token),this._supportDialog=null,this._settingsDialog=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._openingDialog=null,this._physicalDialog=null,this._wallDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._mergeDialog=null,this._roomDialog=!1,this._spaceDialog=null,this._importDialog=null;const e=this._warmSlot;e?.owner===this._warmGen&&(e.vp=this._warmViewportState(),e.dlg=null,e.frameFingerprint="",clearTimeout(e.evict),e.evict=0),this._saveNav()}_setMode(e,t=!0){return e!==this._mode&&(this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._resetDeviceHitState(),this._clearTransientHover(!0)),this._warmModeRequest=0,this._editorRuntime?this._editorRuntime._setMode(e,t):"view"===e?void this._editorModeRequest++:void this._requestMode(e,t)}_primeDrawWallField(){return this._editorRuntimeOrThrow()._primeDrawWallField()}get _drawWallFieldValue(){return null===this._drawWallField?Ao(15,this._imperial):this._drawWallField}get _drawWallCm(){const e=(e=>{const t=String(e??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(t))return null;const i=Number(t);return Number.isFinite(i)?i:null})(this._drawWallFieldValue);if(null==e||e<0)return null;const t=this._imperial?2.54*e:e,i="column"===this._tool?pa:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?pa:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){return this._editorRuntimeOrThrow()._showPhysicalRange(e,t)}_mergeSpacePartitions(e,t){return this._editorRuntimeOrThrow()._mergeSpacePartitions(e,t)}_finishWallChain(){return this._editorRuntimeOrThrow()._finishWallChain()}_activateMarkupTool(e){return this._editorRuntimeOrThrow()._activateMarkupTool(e)}_limitReached(e){return this._editorRuntimeOrThrow()._limitReached(e)}_svgPoint(e){return this._editorRuntimeOrThrow()._svgPoint(e)}_snap(e){return this._editorRuntimeOrThrow()._snap(e)}_snapDrawPoint(e,t=!1){return this._editorRuntimeOrThrow()._snapDrawPoint(e,t)}_planSnapOpeningCuts(e,t){return this._editorRuntimeOrThrow()._planSnapOpeningCuts(e,t)}_planSnapGeometrySnapshot(){return this._editorRuntimeOrThrow()._planSnapGeometrySnapshot()}_hiddenWallDiagnosticSnapshot(){return this._editorRuntimeOrThrow()._hiddenWallDiagnosticSnapshot()}_planStructuralGeometrySnapshot(){return this._editorRuntimeOrThrow()._planStructuralGeometrySnapshot()}_planSnapContextKey(e){return this._editorRuntimeOrThrow()._planSnapContextKey(e)}_resolvePlanDrawPoint(e,t){return this._editorRuntimeOrThrow()._resolvePlanDrawPoint(e,t)}get _activePlanSnapCandidate(){if(!this._markup||"draw"!==this._tool)return null;const e=this._planSnapHover;if(!e)return null;const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.candidate:null}get _activePlanSnapConflicts(){if(!this._markup||"draw"!==this._tool)return[];const e=this._planSnapHover;if(!e)return[];const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.conflicts:[]}_clearPlanSnapHover(e=!0){return this._editorRuntime?this._editorRuntimeOrThrow()._clearPlanSnapHover(e):(this._planSnapHover=null,void(e&&(this._cursorPt=null)))}_samePt(e,t){return _i(e,t)}_dropLegacySegments(){return this._editorRuntimeOrThrow()._dropLegacySegments()}_rollbackRejectedPhysicalWrites(e){return this._editorRuntimeOrThrow()._rollbackRejectedPhysicalWrites(e)}async _reloadRejectedPhysicalWrite(){return this._editorRuntimeOrThrow()._reloadRejectedPhysicalWrite()}get _cfgWriting(){return this._writesPending>0}async _sendConfigCandidate(e){const t=wo(e),i=await this.hass.callWS({type:"houseplan/config/set",config:t,expected_rev:this._cfgRev});this._adoption.acceptConfigWrite(t,i)}_writeConfig(){if(this._editorRuntime)return this._editorRuntime._writeConfig();this._writesPending++,this._writeChain=Nu(this._writeChain,async()=>{if(!this._serverCfg)return;const e=wo(this._serverCfg);this._adoption.stageConfigCandidate(e),await this._sendConfigCandidate(e)});return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_geometrySnapshotFromConfig(e,t){return this._editorRuntimeOrThrow()._geometrySnapshotFromConfig(e,t)}_geometrySnapshot(e=this._space){return this._editorRuntimeOrThrow()._geometrySnapshot(e)}_recordGeometry(e,t){return this._editorRuntimeOrThrow()._recordGeometry(e,t)}_restoreGeometryStateInConfig(e,t,i=!1){return this._editorRuntimeOrThrow()._restoreGeometryStateInConfig(e,t,i)}_restoreGeometryStateLocal(e){return this._editorRuntimeOrThrow()._restoreGeometryStateLocal(e)}_wallModelBlockerLabel(e){return this._editorRuntimeOrThrow()._wallModelBlockerLabel(e)}_hasLegacyZeroWallFields(e=this._serverCfg){return this._editorRuntimeOrThrow()._hasLegacyZeroWallFields(e)}_showWallModelMigrationBlocked(e){return this._editorRuntimeOrThrow()._showWallModelMigrationBlocked(e)}_limitSegmentsOf(e){return this._editorRuntimeOrThrow()._limitSegmentsOf(e)}_junctionLimitViolations(e,t,i,n){return this._editorRuntimeOrThrow()._junctionLimitViolations(e,t,i,n)}_junctionLimitLabel(e){return this._editorRuntimeOrThrow()._junctionLimitLabel(e)}_junctionLimitsIntroduced(e,t,i){return this._editorRuntimeOrThrow()._junctionLimitsIntroduced(e,t,i)}_commitPhysicalGeometry(e,t,i=[]){return this._editorRuntimeOrThrow()._commitPhysicalGeometry(e,t,i)}_clearGeometryGesture(){return this._editorRuntime?this._editorRuntimeOrThrow()._clearGeometryGesture():(this._path=[],this._planSnapHover=null,this._cursorPt=null,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingPreset=null,this._openingRebindId=null,this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._roomDeleteDialog=null,this._wallDialog=null,this._physicalDialog=null,this._physicalSel=null,this._physicalDrag=null,this._physicalRotate=null,this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._openingDialog=null,this._resize?.reset(),this._decorDraft=null,this._decorMove=null,this._dtDrag=null,void(this._bdDrag=null))}_stagePointerCancel(e){if(this._deviceHits.cancel(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover"),this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null),this._doubleFit.clear(),this._editorRuntime)return this._editorRuntime._stagePointerCancel(e);this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._swipeStart=null),this._viewportGestureDirty&&0===this._pointers.size&&(this._viewportGestureDirty=!1,this.requestUpdate())}_applyGeometryState(e,t=!1){return this._editorRuntimeOrThrow()._applyGeometryState(e,t)}_roomAt(e){return this._editorRuntimeOrThrow()._roomAt(e)}_overlapRoom(e){return this._editorRuntimeOrThrow()._overlapRoom(e)}_pointInRoom(e,t){return t.poly?mi(e,t.poly):null!=t.x&&e[0]>=t.x&&e[0]<=t.x+t.w&&e[1]>=t.y&&e[1]<=t.y+t.h}_contourSelfIntersects(e){return this._editorRuntimeOrThrow()._contourSelfIntersects(e)}_canAppendWallPoint(){return this._editorRuntimeOrThrow()._canAppendWallPoint()}_markupClick(e){if(this._editorRuntime)return this._editorRuntime._markupClick(e)}_activeWallSourceKey(e){return this._editorRuntimeOrThrow()._activeWallSourceKey(e)}_wallGraphSources(e){return this._editorRuntimeOrThrow()._wallGraphSources(e)}_wallFaceGraph(e,t){return this._editorRuntimeOrThrow()._wallFaceGraph(e,t)}_offerWallFaces(e,t=this._path.length-2,i){return this._editorRuntimeOrThrow()._offerWallFaces(e,t,i)}_beginWallFaceBatch(e){return this._editorRuntimeOrThrow()._beginWallFaceBatch(e)}_offerExistingWallFace(e){return this._editorRuntimeOrThrow()._offerExistingWallFace(e)}_columnClick(e){return this._editorRuntimeOrThrow()._columnClick(e)}_openPhysicalDialog(e,t){return this._editorRuntimeOrThrow()._openPhysicalDialog(e,t)}_physicalDown(e,t,i){return this._editorRuntimeOrThrow()._physicalDown(e,t,i)}_clampPhysicalDelta(e,t,i){return this._editorRuntimeOrThrow()._clampPhysicalDelta(e,t,i)}_physicalMove(e){return this._editorRuntimeOrThrow()._physicalMove(e)}_physicalUp(e){return this._editorRuntimeOrThrow()._physicalUp(e)}_registerPhysicalTap(e,t){return this._editorRuntimeOrThrow()._registerPhysicalTap(e,t)}_cancelPhysicalGesture(){return this._editorRuntimeOrThrow()._cancelPhysicalGesture()}_physicalRotateDown(e,t){return this._editorRuntimeOrThrow()._physicalRotateDown(e,t)}_physicalRotateMove(e){return this._editorRuntimeOrThrow()._physicalRotateMove(e)}_physicalRotateUp(e){return this._editorRuntimeOrThrow()._physicalRotateUp(e)}_rszRooms(){return this._editorRuntimeOrThrow()._rszRooms()}_rszOpenings(){return this._editorRuntimeOrThrow()._rszOpenings()}_rszObstacles(){return this._editorRuntimeOrThrow()._rszObstacles()}_rszOptsFor(e,t){return this._editorRuntimeOrThrow()._rszOptsFor(e,t)}_rszResolution(e,t,i){return this._editorRuntimeOrThrow()._rszResolution(e,t,i)}_rszSnapshot(){return this._editorRuntimeOrThrow()._rszSnapshot()}_rszResetController(){return this._editorRuntimeOrThrow()._rszResetController()}_rszProjectPreview(e,t,i,n,r){return this._editorRuntimeOrThrow()._rszProjectPreview(e,t,i,n,r)}_rszAcceptPreview(e,t){return this._editorRuntimeOrThrow()._rszAcceptPreview(e,t)}_rszSpaceCandidateGeometry(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateGeometry(e,t)}_rszSpaceCandidateRenderable(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateRenderable(e,t)}_rszCandidateRenderable(e){return this._editorRuntimeOrThrow()._rszCandidateRenderable(e)}_rszEdgeDown(e,t,i){return this._editorRuntimeOrThrow()._rszEdgeDown(e,t,i)}_rszReasonText(e){return this._editorRuntimeOrThrow()._rszReasonText(e)}_rszDisabledActivate(e,t){return this._editorRuntimeOrThrow()._rszDisabledActivate(e,t)}_rszDisabledKey(e,t){return this._editorRuntimeOrThrow()._rszDisabledKey(e,t)}_rszMove(e){return this._editorRuntimeOrThrow()._rszMove(e)}_rszUp(e){return this._editorRuntimeOrThrow()._rszUp(e)}_rszCancelDrag(e){return this._editorRuntimeOrThrow()._rszCancelDrag(e)}_rszPointerCancel(e){return this._editorRuntimeOrThrow()._rszPointerCancel(e)}_rszEdgeLabels(e,t,i=this._resize?.rooms){return this._editorRuntimeOrThrow()._rszEdgeLabels(e,t,i)}_rszInnerSpanCms(e,t,i){return this._editorRuntimeOrThrow()._rszInnerSpanCms(e,t,i)}_renderResizeMeasurements(){return this._editorRuntimeOrThrow()._renderResizeMeasurements()}_renderResizeLayer(e,t){return this._editorRuntimeOrThrow()._renderResizeLayer(e,t)}get _openingsR(){const e=this._curSpaceCfg,t=this._spaceH,i=this._spaceModel();return i?(e?.openings||[]).flatMap(e=>{const n={...e,rx:e.x*pv,ry:e.y*t,rlen:e.length*pv};if(!e.host||"wall"===e.host.kind)return[n];const r=Zu(e,i.partitions,pv,this._cellCm,this._gridPitch);if(!r.resolved)return"plan"===this._mode?[{...n,orphanReason:r.reason||"invalid-host"}]:[];let[o,s]=r.resolved.center;const a=this._physicalDrag;return a?.moved&&"partition"===a.kind&&a.id===e.host.id&&(o+=a.delta[0],s+=a.delta[1]),[{...e,rx:o,ry:s,rlen:r.resolved.length,angle:r.resolved.angle,partitionHost:r.resolved}]}):[]}_partitionOpeningCuts(e=this._spaceModel(),t=()=>!0){if(!e)return[];return U_(W_(this._curSpaceCfg?.id===e.id?this._curSpaceCfg:null,e,this._cellCm,this._gridPitch,pv),t)}_roomWallOpeningInputs(e=this._openingsR,t=this._spaceModel()){if(!t)return[];const i=this._openCuts();return G_(e,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,pv)}_openingFace(e,t,i){return e.partitionHost?tp(e.partitionHost,i):ca(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen,flip_v:i})}_cmToUnits(e){return e/this._cellCm*this._gridPitch}get _decorList(){const e=this._curSpaceCfg;return Array.isArray(e?.decor)?e.decor:[]}get _decorH(){return pv}_decorResolvedStyle(e){return function(e,t,i,n=Sr){const r="rect"===e?.kind||"ellipse"===e?.kind,o=e,s=Kt(o?.color,n.color);return{color:s,opacity:$r(o?.opacity,n.opacity),widthCm:Ar(e,t,i,n.widthCm),fill:!!r&&!0===o?.fill,fillColor:Kt(o?.fill_color,o?.fill?s:n.fillColor),fillOpacity:r&&o?.fill?$r(o?.fill_opacity,.25):n.fillOpacity}}(e,this._cellCm,this._gridPitch,Sr)}_decorWidthUnits(e){return((e,t,i,n=Sr.widthCm)=>{const r=Number(e?.width_cm);if(Number.isFinite(r)&&r>0)return Tr(r,t,i);const o=Number(e?.width);return Number.isFinite(o)&&o>0?o:Tr(n,t,i)})(e,this._cellCm,this._gridPitch,Sr.widthCm)}_decorTextSizeCm(e){if("text"===e?.kind){const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?t:Dr(20*tn(e),this._cellCm,this._gridPitch)}return Dr(20,this._cellCm,this._gridPitch)}_decorTextUnits(e){if("text"!==e.kind)return 20;const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?Tr(t,this._cellCm,this._gridPitch):20*tn(e)}_decorSmallField(e){return Math.round(100*(this._imperial?e/2.54:e))/100}_decorSmallCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(100,t)):.1}_decorTextCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(2e3,t)):.1}_decorLargeField(e){return Math.round(100*(this._imperial?e/30.48:e/100))/100}_decorLargeCm(e){const t=this._imperial?30.48*e:100*e;return Number.isFinite(t)?Math.max(.1,Math.min(Za*this._cellCm,t)):.1}_angleField(e){const t=Number(e);return Number.isFinite(t)?String(Number(t.toFixed(3))):"0"}_decorBoxOf(e){return"rect"!==e.kind&&"ellipse"!==e.kind&&"furniture"!==e.kind&&"image"!==e.kind?null:{x:e.x*pv,y:e.y*this._decorH,w:e.w*pv,h:e.h*this._decorH,angle:Mr(e.angle)||void 0}}_decorSnapGeometry(e){return this._editorRuntimeOrThrow()._decorSnapGeometry(e)}_decorSnap(e,t="mouse",i){return this._editorRuntimeOrThrow()._decorSnap(e,t,i)}_replaceDecor(e,t){return this._editorRuntimeOrThrow()._replaceDecor(e,t)}_cancelDecorGesture(){return this._editorRuntimeOrThrow()._cancelDecorGesture()}_decorPointerDown(e){return this._editorRuntimeOrThrow()._decorPointerDown(e)}_decorCommitDraft(){return this._editorRuntimeOrThrow()._decorCommitDraft()}_decorShapeDown(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDown(e,t)}_decorMoveUpdate(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-move",()=>this._editorRuntimeOrThrow()._decorMoveUpdate(e))}_decorNudge(e,t){if("decor"!==this._mode||"select"!==this._decorTool||!this._decorSel||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag)return!1;const i=this._decorList.find(e=>e.id===this._decorSel),n=this._curSpaceCfg;if(!i||!n)return!1;const r=function(e,t,i,n,r,o){if(!([t,i,n,r,o].every(Number.isFinite)&&r>0))return null;let s;if(s="line"===e.kind?[[e.x1,e.y1],[e.x2,e.y2]]:"text"===e.kind?[[e.x,e.y]]:zr(e),!s.length||s.some(e=>!e.slice(0,2).every(Number.isFinite)))return null;const a=s.map(e=>e[0]),l=s.map(e=>e[1]),c=Math.min(...a),h=Math.max(...a),d=Math.min(...l),u=Math.max(...l),p=t/n,_=i/r,m=p>0?Math.min(p,Math.max(0,o-h)):Math.max(p,Math.min(0,-o-c)),g=_>0?Math.min(_,Math.max(0,o-u)):Math.max(_,Math.min(0,-o-d));return m||g?"line"===e.kind?{...e,x1:e.x1+m,y1:e.y1+g,x2:e.x2+m,y2:e.y2+g}:{...e,x:e.x+m,y:e.y+g}:null}(i,e,t,pv,this._decorH,Za);if(!r)return!1;const o=this._geometrySnapshot();return n.decor=this._decorList.map(e=>e.id===i.id?r:e),this._recordGeometry(this._t("history.decor_move"),o),this._saveConfig(),this.requestUpdate(),!0}_decorShapeDbl(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDbl(e,t)}_openDecorProperties(e){return this._editorRuntimeOrThrow()._openDecorProperties(e)}_decorOpenText(e){return this._editorRuntimeOrThrow()._decorOpenText(e)}_decorRememberTextSelection(e){return this._editorRuntimeOrThrow()._decorRememberTextSelection(e)}_decorInsertLiveVariable(e){return this._editorRuntimeOrThrow()._decorInsertLiveVariable(e)}_decorSaveText(){return this._editorRuntimeOrThrow()._decorSaveText()}_decorSaveShape(){return this._editorRuntimeOrThrow()._decorSaveShape()}get _dtSel(){return"decor"===this._mode&&"select"===this._decorTool&&this._decorSel&&this._decorList.find(e=>e.id===this._decorSel)||null}_dtPivot(e){return this._editorRuntimeOrThrow()._dtPivot(e)}_dtApply(e,t){return this._editorRuntimeOrThrow()._dtApply(e,t)}_dtStart(e,t,i,n){return this._editorRuntimeOrThrow()._dtStart(e,t,i,n)}_dtMove(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-transform",()=>this._editorRuntimeOrThrow()._dtMove(e))}_dtUp(){return this._editorRuntimeOrThrow()._flushPointerMove("decor-transform"),this._editorRuntimeOrThrow()._dtUp()}_dtMeasure(){return this._editorRuntimeOrThrow()._dtMeasure()}_deleteDecor(e){return this._editorRuntimeOrThrow()._deleteDecor(e)}_decorDeleteSel(){return this._editorRuntimeOrThrow()._decorDeleteSel()}_confirmDecorErase(){return this._editorRuntimeOrThrow()._confirmDecorErase()}get _bdBase(){const e=this._curSpaceCfg;return e?.plan_url?{...Ua(e.plan_aspect,pv)}:null}get _bdRect(){const e=this._curSpaceCfg;return e?.plan_url?Ka(e,pv):null}get _bdParams(){const e=this._curSpaceCfg,t=Number(e?.plan_x),i=Number(e?.plan_y),n=Number(e?.plan_scale),r=Number(e?.plan_scale_x),o=Number(e?.plan_scale_y),s=Number.isFinite(n)&&n>0?n:1;return{dx:Number.isFinite(t)?t:0,dy:Number.isFinite(i)?i:0,sx:Number.isFinite(r)&&r>0?r:s,sy:Number.isFinite(o)&&o>0?o:s,angle:Mr(e?.plan_angle)}}_openBackdropDialog(e){if(this._editorRuntime)return this._editorRuntime._openBackdropDialog(e)}_saveBackdropDialog(){return this._editorRuntimeOrThrow()._saveBackdropDialog()}get _bdActive(){return"decor"===this._mode&&!!this._bdRect&&"backdrop"===this._decorTool}get _bdMovable(){return"decor"===this._mode&&"backdrop"===this._decorTool&&!!this._bdRect}_bdApply(e,t,i,n,r){return this._editorRuntimeOrThrow()._bdApply(e,t,i,n,r)}_bdStart(e,t,i=!1){return this._editorRuntimeOrThrow()._bdStart(e,t,i)}_bdMove(e){return this._editorRuntimeOrThrow()._bdMove(e)}get _bdMoved(){if("decor"!==this._mode||!this._bdRect)return!1;const e=this._bdParams;return 0!==e.dx||0!==e.dy||1!==e.sx||1!==e.sy||0!==e.angle}_bdReset(){return this._editorRuntimeOrThrow()._bdReset()}_bdUp(){return this._editorRuntimeOrThrow()._bdUp()}get _bdLive(){if(!this._bdDrag)return null;const e=this._bdRect;return e?{x:e.x+e.w/2,y:e.y+e.h/2,text:`${this._fmtLen([0,0],[e.w,0])} × ${this._fmtLen([0,0],[0,e.h])}`}:null}_renderBackdropFrame(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderBackdropFrame(e):G}_renderTextFrame(e){const t=this._dtSel;if(!t)return G;if("text"===t.kind&&this._dtBox?.id!==t.id)return G;const i="text"===t.kind?this._dtBox:this._decorBoxOf(t);if("line"!==t.kind&&!i)return G;const n=.018*Math.max(e.w,e.h),r=n/4;if("line"===t.kind){const e=[t.x1*pv,t.y1*this._decorH],i=[t.x2*pv,t.y2*this._decorH];return W` ${[e,i].map((e,t)=>W`this._dtStart(e,"scale",void 0,t)}> @@ -375,13 +375,13 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 this._dtStart(e,"rotate")}> - ${vv.map(e=>"edges"===e?d.map(([e,t,o])=>{const s=e<0?i.x:e>0?i.x+i.w:i.x+i.w/2,a=t<0?i.y:t>0?i.y+i.h:i.y+i.h/2;return W`"edges"===e?d.map(([e,t,o])=>{const s=e<0?i.x:e>0?i.x+i.w:i.x+i.w/2,a=t<0?i.y:t>0?i.y+i.h:i.y+i.h/2;return W`this._dtStart(i,"scale",[e,t])}> `}):l.map(([e,t,o])=>W`this._dtStart(i,"scale",[e,t])}>`))} - `}_renderDecorLayer(e,t=this._viewOr(this._baseVb())){const i=uv,n=this._decorH,r="decor"===this._mode,o=r&&"erase"===this._decorTool,s=this._stageEl,a="iso"===this._renderProjection?1:function(e,t,i,n){const r=Number(e),o=Number(t),s=Number(i),a=Number(n);if(![r,o,s,a].every(e=>Number.isFinite(e)&&e>0))return 1;const l=Math.min(r/s,o/a);return Number.isFinite(l)&&l>0?l:1}(s?.clientWidth,s?.clientHeight,t.w,t.h),l=this._decorList.filter(t=>void 0===e||t.id===e).map(e=>{const t="dshape"+(r&&this._decorSel===e.id?" dsel":""),s=this._decorResolvedStyle(e),l=this._decorWidthUnits(e),c=t=>this._decorShapeDown(t,e),h=t=>this._decorShapeDbl(t,e);if("line"===e.kind)return W``}_renderDecorLayer(e,t=this._viewOr(this._baseVb())){const i=pv,n=this._decorH,r="decor"===this._mode,o=r&&"erase"===this._decorTool,s=this._stageEl,a="iso"===this._renderProjection?1:function(e,t,i,n){const r=Number(e),o=Number(t),s=Number(i),a=Number(n);if(![r,o,s,a].every(e=>Number.isFinite(e)&&e>0))return 1;const l=Math.min(r/s,o/a);return Number.isFinite(l)&&l>0?l:1}(s?.clientWidth,s?.clientHeight,t.w,t.h),l=this._decorList.filter(t=>void 0===e||t.id===e).map(e=>{const t="dshape"+(r&&this._decorSel===e.id?" dsel":""),s=this._decorResolvedStyle(e),l=this._decorWidthUnits(e),c=t=>this._decorShapeDown(t,e),h=t=>this._decorShapeDbl(t,e);if("line"===e.kind)return W``:G}`;if("rect"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=$r(e.angle);return W``:G}`;if("rect"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=Mr(e.angle);return W``:G}`}if("ellipse"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=$r(e.angle);return W``:G}`}if("ellipse"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=Mr(e.angle);return W``:G}`}if("image"===e.kind){const s=lm(e,i,n);if(!s)return G;const[a,l,d,u,p,_]=s,m=this._decorAssets.get(e.asset_id);if(!m)return r&&this._editorRuntime?this._editorRuntime._renderMissingDecorImage(e,t,_,a,l,d,u,c,h):G;const g=this._display(m.url);return g?W``:G}`}if("image"===e.kind){const s=cm(e,i,n);if(!s)return G;const[a,l,d,u,p,_]=s,m=this._decorAssets.get(e.asset_id);if(!m)return r&&this._editorRuntime?this._editorRuntime._renderMissingDecorImage(e,t,_,a,l,d,u,c,h):G;const g=this._display(m.url);return g?W`this._signer.markLoaded(this._renderPlanHass,m.url,g)} @pointerdown=${c} @dblclick=${h}> ${o?W``:G}`:G}if("furniture"===e.kind){const d=Vl(e.symbol,this);if(!d)return G;const u=Jl(e,i,n,d.viewW,d.viewH),p=Kl(l,a),_=Kl(l+Cr(20,this._cellCm,this._gridPitch),a);return W``:G}`:G}if("furniture"===e.kind){const d=Kl(e.symbol,this);if(!d)return G;const u=Ql(e,i,n,d.viewW,d.viewH),p=Yl(l,a),_=Yl(l+Tr(20,this._cellCm,this._gridPitch),a);return W`this._renderEntityAvailable(e))),l=e.x*i,d=e.y*n,u=Number(e.angle)||0,p=d-(a.length-1)*r*1.2/2;return W`${a.map((e,t)=>W`${e}`)}`}return G});let c=G;const h=this._decorDraft;if(h){const e=this._decorStyle,t=Cr(e.widthCm,this._cellCm,this._gridPitch);if("line"===h.kind)c=W`${a.map((e,t)=>W`${e}`)}`}return G});let c=G;const h=this._decorDraft;if(h){const e=this._decorStyle,t=Tr(e.widthCm,this._cellCm,this._gridPitch);if("line"===h.kind)c=W``;else{const i=Math.min(h.a[0],h.b[0]),n=Math.min(h.a[1],h.b[1]),r=Math.abs(h.b[0]-h.a[0]),o=Math.abs(h.b[1]-h.a[1]);c="rect"===h.kind?W``:W``}}return W`${l}${c}${this._editorRuntime?._renderFurniturePlacementPreview(a)??G}${this._editorRuntime?._renderDecorImagePlacementPreview()??G}`}get _editorToolbarGroups(){return"plan"!==this._mode?[]:[{id:"opening",label:this._t("markup.opening"),icon:"mdi:door",activeItemId:"opening"===this._tool?this._openingPreset?.type:void 0,items:[{id:"window",label:this._t("opening.window"),icon:"mdi:window-closed-variant",role:"tool",invoke:()=>this._activateOpeningPlacement("window")},{id:"door",label:this._t("opening.door"),icon:"mdi:door-open",role:"tool",invoke:()=>this._activateOpeningPlacement("door")},{id:"passage",label:this._t("opening.passage"),icon:"mdi:arch",role:"tool",invoke:()=>this._activateOpeningPlacement("passage")},{id:"gate",label:this._t("opening.gate"),icon:"mdi:gate",role:"tool",invoke:()=>this._activateOpeningPlacement("gate")}]}]}_renderEditorGroupLauncher(e){return this._editorRuntimeOrThrow()._renderEditorGroupLauncher(e)}get _editorSecondaryContextId(){const e=`editor:${this._mode}:${this._space}:${this._cfgEpoch}`,t=this._editorSecondary?.activeGroup(this._editorToolbarGroups);if(t)return`${e}:group:${t.id}:${this._editorSecondary?.groupGeneration}`;if("plan"===this._mode){const t=this._physicalSel;return t?`${e}:selection:${t.kind}:${t.id}`:`${e}:tool:${this._tool}:${this._path.length}`}return"decor"===this._mode?"furniture"===this._decorTool?`${e}:palette:furniture:${this._furnPalette?.symbol||"none"}`:"image"===this._decorTool?`${e}:palette:image:${this._decorImagePalette?.asset_id||"none"}`:"select"===this._decorTool&&this._decorSel?`${e}:selection:decor:${this._decorSel}`:`${e}:tool:${this._decorTool}:${this._bdMoved?1:0}:${this._bdDrag?1:0}`:`${e}:none`}_runEditorContext(e,t){return this._editorRuntimeOrThrow()._runEditorContext(e,t)}_renderEditorGroupModel(e){return this._editorRuntimeOrThrow()._renderEditorGroupModel(e)}_renderDrawWallControl(){return this._editorRuntimeOrThrow()._renderDrawWallControl()}_renderPlanSecondary(){return this._editorRuntimeOrThrow()._renderPlanSecondary()}_renderDecorSecondary(){return this._editorRuntimeOrThrow()._renderDecorSecondary()}_withBackdropReset(e){return this._editorRuntimeOrThrow()._withBackdropReset(e)}get _editorSecondaryDialogBlocked(){return!!(this._dangerConfirm||this._tapConfirm||this._vacCalConfirm||this._roomDialog||this._mergeDialog||this._openingDialog||this._physicalDialog||this._openingInfo||this._decorTextDialog||this._decorShapeDialog||this._backdropDialog||this._decorEraseConfirm||this._spaceDialog||this._markerDialog||this._deviceInbox||this._infoCard||this._rulesDialog||this._settingsDialog||this._supportDialog||this._alignDialog||this._importDialog||this._kioskDialog||this._summary?.blocksOtherDialogs()||this._backupExportDialog||this._backupImportDialog||this._wallDialog)}_renderEditorSecondary(){return this._editorRuntimeOrThrow()._renderEditorSecondary()}_renderDecorBar(){return this._editorRuntimeOrThrow()._renderDecorBar()}_renderDecorEraseConfirm(){return this._editorRuntimeOrThrow()._renderDecorEraseConfirm()}_renderDecorTextDialog(){return this._editorRuntimeOrThrow()._renderDecorTextDialog()}_renderDecorShapeDialog(){return this._editorRuntimeOrThrow()._renderDecorShapeDialog()}_renderBackdropDialog(){return this._editorRuntimeOrThrow()._renderBackdropDialog()}_cssPxToRender(e){return this._editorRuntimeOrThrow()._cssPxToRender(e)}_renderZeroWalls(e){if(e&&!e.showBorders&&!this._editing)return W``;const t=this._zeroWalls();if(!t.lines.length)return W``;const i=e?.color||"var(--hp-muted)";return W` ${t.lines.map(e=>W``)} - `}_zeroWalls(){const e=this._spaceModel();return e?E_(this._curSpaceCfg,e,uv,.02*this._gridPitch):{style:F_(this._curSpaceCfg),lines:[],contour:[],barriers:[],transmissive:[]}}_openCuts(){return this._zeroWalls().contour}_deleteRoomClick(e){return this._editorRuntimeOrThrow()._deleteRoomClick(e)}get _wallKeyPitch(){return el}get _spaceWalls(){const e=this._curSpaceCfg?.walls;return Array.isArray(e)?e:[]}_intervalCm(e){const t=this._spaceModel();return t?Ps(t.rooms,this._spaceWalls,this._openCuts(),e,this._wallKeyPitch,this._cellCm,this._gridPitch,uv):0}_normalizeWalls(e,t){const i=this._spaceModel();if(!i)return[];return Uo(As(i.rooms,e,t,this._wallKeyPitch,this._cellCm,this._gridPitch,uv),this._curSpaceCfg?.rooms||[],el,1,t.map(e=>[e[0]/uv,e[1]/uv,e[2]/uv,e[3]/uv]))}_paperShapes(e){if(!this._spaceWalls.length)return ri(e);const t=this._wallUnionGeometry();return t?.paperD?[{path:t.paperD}]:ri(e)}_wallUnionGeometry(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._physicalBodiesR();if(!t.length&&!i.length)return null;const n=`${this._space}|${this._cfgEpoch}|${e.rooms.length}`;if(!this._wallUnionCache||this._wallUnionCache.key!==n){const r=xf(this._wallUnionPool,n);if(r.hit)this._wallUnionCache=r.value;else{const r=this._openCuts(),o=this._roomWallOpeningInputs(),s=Js(e.rooms,t,r,o,this._wallKeyPitch,this._cellCm,this._gridPitch,uv,i);s&&Object.defineProperty(s,"sourceFingerprint",{value:ac([this._curSpaceCfg,this._cellCm,this._gridPitch]),enumerable:!1});const a={key:n,value:s};Sf(this._wallUnionPool,n,a,8),this._wallUnionCache=a}}return this._wallUnionCache.value}_thickWallCuts(){const e=this._spaceModel();if(!e)return[];const t=this._spaceWalls;if(!t.length)return[];const i=this._openCuts();return ea(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,uv).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]])}_innerRoomContour(e,t,i=this._openCuts(),n=this._wallUnionGeometry()?.roomGeom,r=this._wallUnionGeometry()?.multiWallNodes){const o=i.map(e=>e.join(",")).join(";"),s=`${e.id}|${this._cfgEpoch}|${t}|${o}`,a=xf(this._innerContourCache,s);if(a.hit)return a.value;const l=Is(e.rooms,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,uv,n,r);return Sf(this._innerContourCache,s,l,600),l}_wallThickHit(e){return this._editorRuntimeOrThrow()._wallThickHit(e)}get _wallThickHover(){if(!this._markup||"wallthick"!==this._tool||!this._cursorPt||this._wallDialog)return null;const e=this._wallThickHit(this._cursorPt);if(!e)return null;const t=function(e,t,i){const n=Number.isFinite(e)&&e>0?e:0,r=Number.isFinite(t)&&t>0?t:5,o=Number.isFinite(i)&&i>0?i:0;return n>0?Ao(n,r,o)/2:Ha(1.5*o,r)}(e.cm,this._cellCm,this._gridPitch);let i="";for(const n of e.segs)i+=(i?" ":"")+as([[n[0],n[1]],[n[2],n[3]]],t,!1);return{segs:e.segs,open:e.open,d:i}}_wallThickClick(e){return this._editorRuntimeOrThrow()._wallThickClick(e)}_wallThickApply(e){return this._editorRuntimeOrThrow()._wallThickApply(e)}_wallHatchDefs(e){const t=Ro(this._cellCm);return W` + `}_zeroWalls(){const e=this._spaceModel();return e?N_(this._curSpaceCfg,e,pv,.02*this._gridPitch):{style:z_(this._curSpaceCfg),lines:[],contour:[],barriers:[],transmissive:[]}}_openCuts(){return this._zeroWalls().contour}_deleteRoomClick(e){return this._editorRuntimeOrThrow()._deleteRoomClick(e)}get _wallKeyPitch(){return tl}get _spaceWalls(){const e=this._curSpaceCfg?.walls;return Array.isArray(e)?e:[]}_intervalCm(e){const t=this._spaceModel();return t?Fs(t.rooms,this._spaceWalls,this._openCuts(),e,this._wallKeyPitch,this._cellCm,this._gridPitch,pv):0}_normalizeWalls(e,t){const i=this._spaceModel();if(!i)return[];return Go(Ps(i.rooms,e,t,this._wallKeyPitch,this._cellCm,this._gridPitch,pv),this._curSpaceCfg?.rooms||[],tl,1,t.map(e=>[e[0]/pv,e[1]/pv,e[2]/pv,e[3]/pv]))}_paperShapes(e){if(!this._spaceWalls.length)return ri(e);const t=this._wallUnionGeometry();return t?.paperD?[{path:t.paperD}]:ri(e)}_wallUnionGeometry(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._physicalBodiesR();if(!t.length&&!i.length)return null;const n=`${this._space}|${this._cfgEpoch}|${e.rooms.length}`;if(!this._wallUnionCache||this._wallUnionCache.key!==n){const r=Sf(this._wallUnionPool,n);if(r.hit)this._wallUnionCache=r.value;else{const r=this._openCuts(),o=this._roomWallOpeningInputs(),s=Qs(e.rooms,t,r,o,this._wallKeyPitch,this._cellCm,this._gridPitch,pv,i);s&&Object.defineProperty(s,"sourceFingerprint",{value:lc([this._curSpaceCfg,this._cellCm,this._gridPitch]),enumerable:!1});const a={key:n,value:s};$f(this._wallUnionPool,n,a,8),this._wallUnionCache=a}}return this._wallUnionCache.value}_thickWallCuts(){const e=this._spaceModel();if(!e)return[];const t=this._spaceWalls;if(!t.length)return[];const i=this._openCuts();return ta(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,pv).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]])}_innerRoomContour(e,t,i=this._openCuts(),n=this._wallUnionGeometry()?.roomGeom,r=this._wallUnionGeometry()?.multiWallNodes){const o=i.map(e=>e.join(",")).join(";"),s=`${e.id}|${this._cfgEpoch}|${t}|${o}`,a=Sf(this._innerContourCache,s);if(a.hit)return a.value;const l=Os(e.rooms,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,pv,n,r);return $f(this._innerContourCache,s,l,600),l}_wallThickHit(e){return this._editorRuntimeOrThrow()._wallThickHit(e)}get _wallThickHover(){if(!this._markup||"wallthick"!==this._tool||!this._cursorPt||this._wallDialog)return null;const e=this._wallThickHit(this._cursorPt);if(!e)return null;const t=function(e,t,i){const n=Number.isFinite(e)&&e>0?e:0,r=Number.isFinite(t)&&t>0?t:5,o=Number.isFinite(i)&&i>0?i:0;return n>0?Po(n,r,o)/2:La(1.5*o,r)}(e.cm,this._cellCm,this._gridPitch);let i="";for(const n of e.segs)i+=(i?" ":"")+ls([[n[0],n[1]],[n[2],n[3]]],t,!1);return{segs:e.segs,open:e.open,d:i}}_wallThickClick(e){return this._editorRuntimeOrThrow()._wallThickClick(e)}_wallThickApply(e){return this._editorRuntimeOrThrow()._wallThickApply(e)}_wallHatchDefs(e){const t=Co(this._cellCm);return W` - `}_resolvedRoomFills(e,t){const i=new Map,n=new Map;for(const r of e.rooms){const e=this._roomDialog&&r.id===this._roomEditId?this._roomFill||t.fill:Nn(t.fill,r),o=this._roomDialog&&r.id===this._roomEditId?this._roomCustomFill||t.customFill:hn(t.customFill,r),s=Rc(t.tempMin,t.tempMax,r,this._roomTempMin,this._roomTempMax,this._roomDialog&&r.id===this._roomEditId),a=vn(e,"lqi"===e&&r.area?this._roomLqi(r.area):null,"light"===e?Ed(Id(this._renderPlanHass,this._renderDevices,r,this._virtualLights)):"none","temp"===e?this._roomTemp(r):null,s.min,s.max,this._fillColors,o);i.set(r,a),r.id&&n.set(r.id,a)}return{byRoom:i,byId:n}}_spaceDisplayForRender(){const e=un(this._curSpaceCfg),t=this._spaceDialog;return t&&"edit"===t.mode&&t.spaceId===this._space?{...e,showBorders:t.showBorders,showNames:t.showNames,hideDecor:t.hideDecor,hideOpenings:t.hideOpenings,color:t.roomColor,opacity:t.roomOpacity,fill:t.fillMode,customFill:t.customFill?cn(t.customFill):ln,glow:t.glowEnabled,tempMin:t.tempMin,tempMax:t.tempMax,showLqi:t.showLqi,cardFontScale:t.cardFontScale,labelTemp:t.labelTemp,labelHum:t.labelHum,labelLqi:t.labelLqi,labelLight:t.labelLight}:e}_openingWallIndexFor(e,t){const i=e.rooms.map(e=>`${e.id}:${e.poly?.map(e=>e.join(",")).join("/")||`${e.x},${e.y},${e.w},${e.h}`}`).join(";"),n=this._spaceWalls.map(e=>`${e.key}:${e.a?.join(",")||""}:${e.b?.join(",")||""}:${e.cm}`).join(";"),r=t.map(e=>e.join(",")).join(";"),o=[e.id,this._cfgEpoch,this._wallKeyPitch,this._cellCm,this._gridPitch,i,n,r].join("|");let s=this._openingWallIndexCache.get(o);return s||(s=na(e.rooms,this._spaceWalls,t,this._wallKeyPitch,this._cellCm,this._gridPitch,uv)),Sf(this._openingWallIndexCache,o,s,4),{key:o,value:s}}_renderOpeningTunnelFills(e,t,i="data"){if(this._markup||!this._spaceWalls.length||!this._openingsR.length)return W``;if("glow-base"===i&&![...t.byRoom.values()].some(Boolean))return W``;const n=this._openCuts(),r=this._openingsR.map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=r.map(e=>`${e.x},${e.y},${e.angle},${e.length}`).join(";"),s=this._openingWallIndexFor(e,n),a=`${s.key}|${o}`;return this._openingTunnelCache&&this._openingTunnelCache.key===a||(this._openingTunnelCache={key:a,value:da(s.value,r)}),k_({openings:this._openingsR,geometries:this._openingTunnelCache.value,fillsByRoomId:t.byId,idPrefix:`${e.id}-${i}`,groupClass:"data"===i?"opening-tunnels":"opening-tunnels glow-base-tunnels",dataLayer:i})}_resolvedGlowBase(e,t,i){const n=new Map,r=new Map,o=this._fillColors.glow_base;for(const s of e.rooms){const e=i.byRoom.get(s),a=Hn(t.glow,s)&&(!e||e.opacity<=0)?{color:o.c,opacity:o.a,mode:"glow"}:null;n.set(s,a),s.id&&r.set(s.id,a)}return{byRoom:n,byId:r}}_renderGlowBaseRooms(e,t){if(this._markup||![...t.byRoom.values()].some(Boolean))return W``;const i=new Map(e.rooms.map(e=>[e,ni(e)])),n=this._openCuts(),r=this._wallUnionGeometry()?.roomGeom,o=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z",s=e.rooms.map(s=>{const a=t.byRoom.get(s)||null,l=i.get(s)||null;if(!a||!l)return G;const c=this._spaceWalls.length&&s.id&&this._innerRoomContour(e,s.id,n,r)||l,h=Ri(c,e.rooms.filter(e=>e!==s).map(e=>i.get(e)).filter(e=>!!e)),d=this._cleanFloor(s,c,e).path;return d||h.length?W``}_resolvedRoomFills(e,t){const i=new Map,n=new Map;for(const r of e.rooms){const e=this._roomDialog&&r.id===this._roomEditId?this._roomFill||t.fill:Nn(t.fill,r),o=this._roomDialog&&r.id===this._roomEditId?this._roomCustomFill||t.customFill:hn(t.customFill,r),s=Cc(t.tempMin,t.tempMax,r,this._roomTempMin,this._roomTempMax,this._roomDialog&&r.id===this._roomEditId),a=vn(e,"lqi"===e&&r.area?this._roomLqi(r.area):null,"light"===e?Nd(Od(this._renderPlanHass,this._renderDevices,r,this._virtualLights)):"none","temp"===e?this._roomTemp(r):null,s.min,s.max,this._fillColors,o);i.set(r,a),r.id&&n.set(r.id,a)}return{byRoom:i,byId:n}}_spaceDisplayForRender(){const e=un(this._curSpaceCfg),t=this._spaceDialog;return t&&"edit"===t.mode&&t.spaceId===this._space?{...e,showBorders:t.showBorders,showNames:t.showNames,hideDecor:t.hideDecor,hideOpenings:t.hideOpenings,color:t.roomColor,opacity:t.roomOpacity,fill:t.fillMode,customFill:t.customFill?cn(t.customFill):ln,glow:t.glowEnabled,tempMin:t.tempMin,tempMax:t.tempMax,showLqi:t.showLqi,cardFontScale:t.cardFontScale,labelTemp:t.labelTemp,labelHum:t.labelHum,labelLqi:t.labelLqi,labelLight:t.labelLight}:e}_openingWallIndexFor(e,t){const i=e.rooms.map(e=>`${e.id}:${e.poly?.map(e=>e.join(",")).join("/")||`${e.x},${e.y},${e.w},${e.h}`}`).join(";"),n=this._spaceWalls.map(e=>`${e.key}:${e.a?.join(",")||""}:${e.b?.join(",")||""}:${e.cm}`).join(";"),r=t.map(e=>e.join(",")).join(";"),o=[e.id,this._cfgEpoch,this._wallKeyPitch,this._cellCm,this._gridPitch,i,n,r].join("|");let s=this._openingWallIndexCache.get(o);return s||(s=ra(e.rooms,this._spaceWalls,t,this._wallKeyPitch,this._cellCm,this._gridPitch,pv)),$f(this._openingWallIndexCache,o,s,4),{key:o,value:s}}_renderOpeningTunnelFills(e,t,i="data"){if(this._markup||!this._spaceWalls.length||!this._openingsR.length)return W``;if("glow-base"===i&&![...t.byRoom.values()].some(Boolean))return W``;const n=this._openCuts(),r=this._openingsR.map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=r.map(e=>`${e.x},${e.y},${e.angle},${e.length}`).join(";"),s=this._openingWallIndexFor(e,n),a=`${s.key}|${o}`;return this._openingTunnelCache&&this._openingTunnelCache.key===a||(this._openingTunnelCache={key:a,value:ua(s.value,r)}),x_({openings:this._openingsR,geometries:this._openingTunnelCache.value,fillsByRoomId:t.byId,idPrefix:`${e.id}-${i}`,groupClass:"data"===i?"opening-tunnels":"opening-tunnels glow-base-tunnels",dataLayer:i})}_resolvedGlowBase(e,t,i){const n=new Map,r=new Map,o=this._fillColors.glow_base;for(const s of e.rooms){const e=i.byRoom.get(s),a=Hn(t.glow,s)&&(!e||e.opacity<=0)?{color:o.c,opacity:o.a,mode:"glow"}:null;n.set(s,a),s.id&&r.set(s.id,a)}return{byRoom:n,byId:r}}_renderGlowBaseRooms(e,t){if(this._markup||![...t.byRoom.values()].some(Boolean))return W``;const i=new Map(e.rooms.map(e=>[e,ni(e)])),n=this._openCuts(),r=this._wallUnionGeometry()?.roomGeom,o=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z",s=e.rooms.map(s=>{const a=t.byRoom.get(s)||null,l=i.get(s)||null;if(!a||!l)return G;const c=this._spaceWalls.length&&s.id&&this._innerRoomContour(e,s.id,n,r)||l,h=Ri(c,e.rooms.filter(e=>e!==s).map(e=>i.get(e)).filter(e=>!!e)),d=this._cleanFloor(s,c,e).path;return d||h.length?W``:s.poly||c!==l?W``:W``});return W``}_renderWallBodies(e){if("iso"===this._renderProjection)return W``;if(e&&!e.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const t=this._wallUnionGeometry();if(!t)return W``;const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i&&i.clientWidth&&n.w?i.clientWidth/n.w:1,o=e?.color||"#607d8b",s=Mo(t.depthUnits,r)||Co(Ro(this._cellCm),r),a=this._fillColors.wall_fill;return W` + fill=${a.color} fill-opacity=${a.opacity} pointer-events="none">`});return W``}_renderWallBodies(e){if("iso"===this._renderProjection)return W``;if(e&&!e.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const t=this._wallUnionGeometry();if(!t)return W``;const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i&&i.clientWidth&&n.w?i.clientWidth/n.w:1,o=e?.color||"#607d8b",s=Ro(t.depthUnits,r)||To(Co(this._cellCm),r),a=this._fillColors.wall_fill;return W` ${t.paths.map(e=>W` `)} - `}_roomHoverPaths(e){const t=this._hoverRoom;if("view"!==this._mode||!t||t.space!==e.id)return null;const i=e.rooms.find(e=>e===t.room||!!e.id&&e.id===t.room.id);if(!i)return null;const n=ni(i);if(!n)return null;const r=e.rooms.filter(e=>e!==i).map(e=>({room:e,poly:ni(e)})).filter(e=>!!e.poly),o=Ri(n,r.map(e=>e.poly)),s=this._openCuts(),a=.02*this._gridPitch,l=s.filter(e=>{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return n.some((e,i)=>Un(t,[e[0],e[1],...n[(i+1)%n.length]])<=4*a)}),c=this._spaceWalls,h=this._wallUnionGeometry()?.roomGeom,d=c.length&&i.id&&this._innerRoomContour(e,i.id,s,h)||n,u=[{axis:n,face:d}];for(const t of o){const i=r.find(e=>e.poly===t)?.room;let n=t;if(c.length&&i?.id){const r=Cs(e.rooms,i.id,c,s,this._wallKeyPitch,this._cellCm,this._gridPitch,uv);r&&(n=ia(r.poly,r.offsets)||t)}u.push({axis:t,face:n})}const p=this._roomWallOpeningInputs(this._openingsR,e).map(e=>{const t=e.angle*Math.PI/180,i=Math.cos(t)*e.length/2,n=Math.sin(t)*e.length/2;return[e.x-i,e.y-n,e.x+i,e.y+n]}),_=l.concat(p),m=u.map(({axis:e,face:t})=>{const i=_.map(i=>((e,t,i)=>{const n=e[2]-e[0],r=e[3]-e[1],o=Math.hypot(n,r);if(o.05)&&Un([c,h],[i[0],i[1],n[0],n[1]])<=4*a){d=!0;break}}if(!d)return null;let u=null;for(let e=0;e.05)continue;const p=Un([c,h],[t[0],t[1],n[0],n[1]]);(!u||p!!e);return i.length?Fn(t,i,a).map(e=>`M ${e[0]} ${e[1]} L ${e[2]} ${e[3]}`).join(" "):`M ${t.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`}).filter(Boolean).join(" ");if(!m)return null;const g=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`;return{fillD:[this._cleanFloor(i,d,e).path||g(d),...o.map(g)].join(" "),outlineD:m}}_renderRoomHoverFill(e){return W` + `}_roomHoverPaths(e){const t=this._hoverRoom;if("view"!==this._mode||!t||t.space!==e.id)return null;const i=e.rooms.find(e=>e===t.room||!!e.id&&e.id===t.room.id);if(!i)return null;const n=ni(i);if(!n)return null;const r=e.rooms.filter(e=>e!==i).map(e=>({room:e,poly:ni(e)})).filter(e=>!!e.poly),o=Ri(n,r.map(e=>e.poly)),s=this._openCuts(),a=.02*this._gridPitch,l=s.filter(e=>{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return n.some((e,i)=>Un(t,[e[0],e[1],...n[(i+1)%n.length]])<=4*a)}),c=this._spaceWalls,h=this._wallUnionGeometry()?.roomGeom,d=c.length&&i.id&&this._innerRoomContour(e,i.id,s,h)||n,u=[{axis:n,face:d}];for(const t of o){const i=r.find(e=>e.poly===t)?.room;let n=t;if(c.length&&i?.id){const r=Ts(e.rooms,i.id,c,s,this._wallKeyPitch,this._cellCm,this._gridPitch,pv);r&&(n=na(r.poly,r.offsets)||t)}u.push({axis:t,face:n})}const p=this._roomWallOpeningInputs(this._openingsR,e).map(e=>{const t=e.angle*Math.PI/180,i=Math.cos(t)*e.length/2,n=Math.sin(t)*e.length/2;return[e.x-i,e.y-n,e.x+i,e.y+n]}),_=l.concat(p),m=u.map(({axis:e,face:t})=>{const i=_.map(i=>((e,t,i)=>{const n=e[2]-e[0],r=e[3]-e[1],o=Math.hypot(n,r);if(o.05)&&Un([c,h],[i[0],i[1],n[0],n[1]])<=4*a){d=!0;break}}if(!d)return null;let u=null;for(let e=0;e.05)continue;const p=Un([c,h],[t[0],t[1],n[0],n[1]]);(!u||p!!e);return i.length?Fn(t,i,a).map(e=>`M ${e[0]} ${e[1]} L ${e[2]} ${e[3]}`).join(" "):`M ${t.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`}).filter(Boolean).join(" ");if(!m)return null;const g=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`;return{fillD:[this._cleanFloor(i,d,e).path||g(d),...o.map(g)].join(" "),outlineD:m}}_renderRoomHoverFill(e){return W` `}_renderRoomHoverOutline(e){return W` @@ -473,23 +473,23 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 d="${e?.outlineD||""}" ?hidden=${!e}> - `}_renderWallThickUi(){return this._editorRuntime?this._editorRuntimeOrThrow()._renderWallThickUi():W``}_renderWallThickDialog(){return this._editorRuntimeOrThrow()._renderWallThickDialog()}_openingAt(e){return this._editorRuntimeOrThrow()._openingAt(e)}_resolveOpeningPlacement(e){return this._editorRuntimeOrThrow()._resolveOpeningPlacement(e)}_activateOpeningPlacement(e){return this._editorRuntimeOrThrow()._activateOpeningPlacement(e)}_clearOpeningPlacement(e){return this._editorRuntime?this._editorRuntimeOrThrow()._clearOpeningPlacement(e):(this._openingHoverCandidate=null,this._openingJambBlockCm=null,void(e&&(this._openingPreset=null,this._openingRebindId=null)))}_openingClick(e){return this._editorRuntimeOrThrow()._openingClick(e)}_editOpening(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._editOpening(e)}_opPointerDown(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerDown(e,t)}_opPointerMove(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerMove(e,t)}_opRuler(e,t){return this._editorRuntimeOrThrow()._opRuler(e,t)}_opPointerUp(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerUp(e,t)}_opClick(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opClick(e,t)}_saveOpening(){return this._editorRuntimeOrThrow()._saveOpening()}_deleteOpening(){return this._editorRuntimeOrThrow()._deleteOpening()}_contactCandidates(){return this._editorRuntimeOrThrow()._contactCandidates()}_lockCandidates(){return this._editorRuntimeOrThrow()._lockCandidates()}_toggleOpeningEntityPicker(e){return this._editorRuntimeOrThrow()._toggleOpeningEntityPicker(e)}_filterOpeningEntities(e,t){return this._editorRuntimeOrThrow()._filterOpeningEntities(e,t)}_selectOpeningEntity(e,t){return this._editorRuntimeOrThrow()._selectOpeningEntity(e,t)}_mergeClick(e){return this._editorRuntimeOrThrow()._mergeClick(e)}_commitMerge(){return this._editorRuntimeOrThrow()._commitMerge()}_splitClick(e){return this._editorRuntimeOrThrow()._splitClick(e)}get _contourClosed(){return this._path.length>=4&&this._samePt(this._path[0],this._path[this._path.length-1])&&(null!=this._closingWallCm||!this._activeWallChainId)}_markupMove(e){this._markup&&this._editorRuntime&&this._editorRuntimeOrThrow()._queuePointerMove("markup-hover",()=>this._editorRuntime._markupMove(e))}get _openingPreview(){const e=this._openingPreset;if("opening"!==this._tool||!e||!this._cursorPt)return null;const t=this._cursorPt,i=this._openingHoverCandidate;if(i&&Kf(i,[t[0],t[1]],e.revision,this._cfgEpoch))return i;if(this._openingAt(t))return this._openingHoverCandidate=null,null;const n=this._resolveOpeningPlacement(t);return this._openingHoverCandidate=n,n}get _opMeasureView(){return this._opMeasure||this._openingPreview?.measure||null}_saveRoom(){return this._editorRuntimeOrThrow()._saveRoom()}_decideWallFace(e){return this._editorRuntimeOrThrow()._decideWallFace(e)}_wallSourceCmAt(e,t,i){return this._editorRuntimeOrThrow()._wallSourceCmAt(e,t,i)}_activePathWithRepair(e,t){return this._editorRuntimeOrThrow()._activePathWithRepair(e,t)}_validateWallRepair(e,t){return this._editorRuntimeOrThrow()._validateWallRepair(e,t)}_applyWallRepair(e,t){return this._editorRuntimeOrThrow()._applyWallRepair(e,t)}_applyWallFaceBatch(){return this._editorRuntimeOrThrow()._applyWallFaceBatch()}_commitRoom(){return this._editorRuntimeOrThrow()._commitRoom()}_cancelPath(){return this._editorRuntimeOrThrow()._cancelPath()}_roomDialogCancel(){return this._editorRuntimeOrThrow()._roomDialogCancel()}get _freeAreas(){const e=new Set;for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area&&e.add(i.area);for(const t of this._wallFaceBatch?.decisions||[])t.create&&t.area&&e.add(t.area);return Object.values(this.hass?.areas||{}).filter(t=>!e.has(t.area_id)).sort((e,t)=>(e.name||"").localeCompare(t.name||""))}_openDeviceInbox(){return this._editorRuntimeOrThrow()._openDeviceInbox()}_closeMarkerDialog(){return this._editorRuntimeOrThrow()._closeMarkerDialog()}_deviceInboxCandidates(e){return this._editorRuntimeOrThrow()._deviceInboxCandidates(e)}_deviceInboxRows(){return this._editorRuntimeOrThrow()._deviceInboxRows()}_deviceForInboxRow(e){return this._editorRuntimeOrThrow()._deviceForInboxRow(e)}_openInboxMarker(e,t=!1){return this._editorRuntimeOrThrow()._openInboxMarker(e,t)}async _setInboxHidden(e,t){return this._editorRuntimeOrThrow()._setInboxHidden(e,t)}_findInboxDevice(e){return this._editorRuntimeOrThrow()._findInboxDevice(e)}_deviceInboxTabKey(e){return this._editorRuntimeOrThrow()._deviceInboxTabKey(e)}_openMarkerDialog(e){if(this._editorRuntime)return this._editorRuntime._openMarkerDialog(e);this._ensureEditorRuntime().then(t=>{t&&this._openMarkerDialog(e)})}_runCandidates(){return this._editorRuntimeOrThrow()._runCandidates()}_bindingCandidates(){return this._editorRuntimeOrThrow()._bindingCandidates()}_physicalBodiesR(e=this._spaceModel()){if(!e)return[];const t=`${e.id}|${this._cfgEpoch}|${this._cellCm}|${this._gridPitch}`;if(this._physicalBodiesCache?.key===t)return this._physicalBodiesCache.all;const i=$a(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e));return this._physicalBodiesCache={key:t,...i},i.all}_rawPhysicalBodiesR(e=this._spaceModel()){if(!e)return[];this._physicalBodiesR(e);const t=this._physicalBodiesCache;return t?[...t.partitions,...t.columns]:[]}_cleanFloor(e,t,i=this._spaceModel()){if(!i)return{floor:t,geom:null,path:"",area:Aa([[[...t,t[0]]]])};const n=e.id||`#${i.rooms.indexOf(e)}`,r=`${i.id}|${this._cfgEpoch}|${n}`;if(!this._resize?.preview){const e=xf(this._cleanFloorCache,r);if(e.hit)return e.value}const o=t.map(e=>e[0]),s=t.map(e=>e[1]),a=[Math.min(...o),Math.min(...s),Math.max(...o),Math.max(...s)],l=this._physicalBodiesR(i).filter(e=>{const t=e.map(e=>e[0]),i=e.map(e=>e[1]);return Math.max(...t)>=a[0]&&Math.min(...t)<=a[2]&&Math.max(...i)>=a[1]&&Math.min(...i)<=a[3]}),c=l.length?Da(t,l):null,h={floor:t,geom:c,path:c?ya(c):"",area:Aa(c||[[[...t,t[0]]]])};return this._resize?.preview||Sf(this._cleanFloorCache,r,h,600),h}_autoIconForBinding(e){if("virtual"===e)return"mdi:map-marker";const[t,i]=e.split(":");if(!i)return"";const n=this._fullRegistryHass,r=this._bindingStatus(e),o="active"===r.kind?r.enabledEntityIds:r.allEntityIds;if("device"===t){const e=n.devices?.[i];if(!e)return"mdi:help-circle";const t=o;return t.some(e=>e.startsWith("lock."))?"mdi:lock":Wd(n,e.name_by_user||e.name||"",e.model,t,this._iconRules)}if("entity"===t){const e=n.entities?.[i],t=this.hass.states?.[i],r=e?.name||t?.attributes?.friendly_name||i;return i.startsWith("lock.")?"mdi:lock":Wd(n,r,"",[i],this._iconRules)}return""}_allRoomsFlat(){const e=[];for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area?e.push({value:t.id+"#"+i.area,label:(t.title||t.id)+" · "+i.name}):i.id&&e.push({value:t.id+"#@"+i.id,label:(t.title||t.id)+" · "+i.name+" · "+this._t("marker.subarea")});return e}_errText(e){if(!e)return this._t("err.unknown");if("string"==typeof e)return e;if("invalid_passage_fields"===e.code){const t=String(e.message||e.error||"");let i="",n=[];try{const e=JSON.parse(t);i=String(e.space??""),n=Array.isArray(e.fields)?e.fields.map(String):[]}catch{const e=t.match(/space=([^;]*);\s*opening=([^;]*);\s*fields=([^;]*)/);e&&(i=e[1],n=e[3].split(",").filter(Boolean))}if(i||n.length){const e=this._serverCfg?.spaces?.find(e=>String(e.id)===i),t={contact:"opening.contact_label",lock:"opening.lock_label",invert:"opening.invert",flip_h:"opening.flip_h",flip_v:"opening.flip_v"},r=n.map(e=>t[e]?this._t(t[e]):e).join(", ");return this._t("opening.invalid_passage_fields",{room:e?.title||i,fields:r})}}if("invalid_partition_opening_jamb_margin"===e.code){const t=String(e.message||e.error||"");let i=NaN;try{i=Number(JSON.parse(t).margin_cm)}catch{const e=t.match(/margin_cm=([^;}"]*)/);i=e?Number(e[1]):NaN}if(Number.isFinite(i))return this._t("opening.partition_jamb_margin",{distance:ti(i,this._imperial)})}if(null!=e.code){const t=`backup.error.${e.code}`,i=this._t(t);return e.message&&console.warn("[houseplan] backend error",e.code,e.message),i!==t?i:this._t("err.code",{code:e.code})}if(e.message)return e.message;if(e.error)return e.error;try{return JSON.stringify(e)}catch{return String(e)}}_backupErrorText(e){return this._editorRuntimeOrThrow()._backupErrorText(e)}async _pickMarkerFiles(e){return this._editorRuntimeOrThrow()._pickMarkerFiles(e)}_removeMarkerPdf(e){return this._editorRuntimeOrThrow()._removeMarkerPdf(e)}_markerLightFields(e){return this._editorRuntimeOrThrow()._markerLightFields(e)}_markerTapActionFields(e){return this._editorRuntimeOrThrow()._markerTapActionFields(e)}_markerToggleEntityFields(e){return this._editorRuntimeOrThrow()._markerToggleEntityFields(e)}async _saveMarker(){return this._editorRuntimeOrThrow()._saveMarker()}async _deleteMarker(){return this._editorRuntimeOrThrow()._deleteMarker()}_normPos(e,t,i){return{s:e,x:t/uv,y:i/uv}}_spaceDialogUsesOnboardingRuntime(e){return"create"===e&&!this._editorRuntime&&(!!this._onboardingRuntime||0===(this._serverCfg?.spaces.length||0)||this._importTotal>0||this._importQueue.length>0)}_spaceRuntimeOrThrow(){if(!this._onboardingRuntime)throw new Error("Houseplan onboarding runtime is not loaded");return this._onboardingRuntime}_openSpaceDialog(e,t){return this._spaceDialogUsesOnboardingRuntime(e)?this._onboardingRuntime?void this._onboardingRuntime._openSpaceDialog(e,t):void this._ensureOnboardingRuntime().then(i=>{i&&this._spaceRuntimeOrThrow()._openSpaceDialog(e,t)}):this._editorRuntime?this._editorRuntime._openSpaceDialog(e,t):void this._ensureEditorRuntime().then(i=>{i&&this._openSpaceDialog(e,t)})}async _pickPlanFile(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._pickPlanFile(e):this._editorRuntimeOrThrow()._pickPlanFile(e)}_useServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._useServerPlan(e):this._editorRuntimeOrThrow()._useServerPlan(e)}async _readPlanAspect(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._readPlanAspect(e):this._editorRuntimeOrThrow()._readPlanAspect(e)}async _deleteServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._deleteServerPlan(e):this._editorRuntimeOrThrow()._deleteServerPlan(e)}_renderServerPlans(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime(e.mode)?this._onboardingRuntime._renderServerPlans(e):this._editorRuntimeOrThrow()._renderServerPlans(e)}async _saveSpaceDialog(){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._saveSpaceDialog():this._editorRuntimeOrThrow()._saveSpaceDialog()}async _deleteSpace(){return this._editorRuntimeOrThrow()._deleteSpace()}async _saveConfigNow(){return this._editorRuntimeOrThrow()._saveConfigNow()}_startImport(){return this._onboardingRuntime?this._onboardingRuntime._startImport():this._editorRuntimeOrThrow()._startImport()}_openNextImport(){return this._onboardingRuntime?this._onboardingRuntime._openNextImport():this._editorRuntimeOrThrow()._openNextImport()}_skipImport(){return this._onboardingRuntime?this._onboardingRuntime._skipImport():this._editorRuntimeOrThrow()._skipImport()}_renderImportDialog(){return this._onboardingRuntime?this._onboardingRuntime._renderImportDialog():this._editorRuntimeOrThrow()._renderImportDialog()}_sunGlobal(){const e=this._settingsDialog;return e?{...this._settings,north_deg:e.northDeg??void 0,bg_mode:e.bgMode,sun_rays:e.sunRays}:this._settings}_sunSpace(){const e=this._spaceDialog,t=this._curSpaceCfg?.settings||{};return e&&"edit"===e.mode&&e.spaceId===this._space?{...t,north_deg:e.northDeg??void 0,bg_mode:e.bgMode??void 0,sun_rays:e.sunRays??void 0}:t}_effNorth(){return gr(this._sunGlobal(),this._sunSpace())}_effBgMode(){return fr(this._sunGlobal(),this._sunSpace())}_dayCycleState(e=new Date){return(this._modeTransitionVisual?.viewWeight??("view"===this._mode?1:0))<=0||"daynight"!==this._effBgMode()?null:sr(this._renderPlanHass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?ar(e):"";const t="clock"===e?.source&&"hidden"!==this.ownerDocument.visibilityState&&this.isConnected;t&&!this._dayCycleTimer?this._dayCycleTimer=window.setInterval(this._dayCycleTick,3e4):!t&&this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_dayCycleVisibility(e){"hidden"!==e.kind?(this._dayCycleTick(),this._syncDayCycleClock()):this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_effSunRays(){return vr(this._sunGlobal(),this._sunSpace())}_sunNow(){return null!==this._effNorth()?yr(this._renderPlanHass):null}_renderSunRays(e){const t=W``,i=this._modeTransitionVisual?.viewWeight??0;if(this._editing&&i<=0||!this._effSunRays())return this._sunFadeReset(),t;const n=this._effNorth(),r=null!==n?yr(this._renderPlanHass):null;if(!r||r.elevation<=0)return this._sunFadeReset(),t;if(o=r.elevation,Number(o)>=3)this._sunOutTimer&&(clearTimeout(this._sunOutTimer),this._sunOutTimer=0),this._sunOut=!1,this._sunShown=!0;else{if(!this._sunShown)return t;this._sunOut||(this._sunOut=!0,this._sunOutTimer=window.setTimeout(()=>{this._sunOutTimer=0,this._sunShown=!1,this._sunOut=!1,this.requestUpdate()},2e3))}var o;const s=this._zeroWalls(),a=s.barriers.map(e=>e.join(",")).join(";"),l=`${e.id}|${r.azimuth}|${r.elevation}|${n}|${this._cfgEpoch}|${s.style}|${a}`;if(!this._sunRaysCache||this._sunRaysCache.key!==l){const t=e.rooms.map(e=>({id:e.id||"",poly:ni(e)})).filter(e=>!!e.id&&!!e.poly),i=this._openingsR.filter(e=>"window"===e.type&&"partition"!==e.host?.kind).map(e=>({id:e.id,x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=this._spaceWalls,a=this._openCuts(),c=this._openingWallIndexFor(e,a).value,h={},d={},u=this._wallUnionGeometry()?.roomGeom;if(o.length){for(const i of t){const t=this._innerRoomContour(e,i.id,a,u);t&&(h[i.id]=t)}for(const e of i){const t=la(c,{x:e.x,y:e.y,angle:e.angle,length:e.length});t.cm>0&&(d[e.id]=Ao(t.cm,this._cellCm,this._gridPitch))}}let p=_r(t,i,r.azimuth,r.elevation,n,o.length?h:void 0,o.length?d:void 0);const _=[...this._physicalBodiesR(e),...s.barriers.map(e=>[[e[0],e[1]],[e[2],e[3]]])];_.length&&(p=p.map(e=>{const t=function(e,t,i){return i>0?e.map(e=>function(e){const t=[...e].sort((e,t)=>e[0]-t[0]||e[1]-t[1]);if(t.length<=2)return t;const i=(e,t,i)=>(t[0]-e[0])*(i[1]-e[1])-(t[1]-e[1])*(i[0]-e[0]),n=[];for(const e of t){for(;n.length>=2&&i(n[n.length-2],n[n.length-1],e)<=0;)n.pop();n.push(e)}const r=[];for(let e=t.length-1;e>=0;e--){const n=t[e];for(;r.length>=2&&i(r[r.length-2],r[r.length-1],n)<=0;)r.pop();r.push(n)}return n.slice(0,-1).concat(r.slice(0,-1))}([...e,...e.map(e=>[e[0]+t[0]*i,e[1]+t[1]*i])])).filter(e=>e.length>=3):e}(_,e.dir,e.len),i=e.polys.map(e=>Da(e,t));return{...e,paths:i.map(ya).filter(Boolean),polys:i.flatMap(Fa)}}).filter(e=>e.paths?.length||e.polys.length)),this._sunRaysCache={key:l,rays:p,rims:p.map(e=>function(e,t=1e-4){const[i,n]=e.dir,r=-n,o=i,s=[];for(const a of[e.a,e.b]){const l=[];for(const s of e.polys)for(let e=0;et)continue;if(Math.abs((h[0]-a[0])*r+(h[1]-a[1])*o)>t)continue;const d=(c[0]-a[0])*i+(c[1]-a[1])*n,u=(h[0]-a[0])*i+(h[1]-a[1])*n;Math.abs(u-d)<=t||l.push(de[0]-t[0]);const c=[];for(const e of l){const i=c[c.length-1];i&&e[0]<=i[1]+t?i[1]=Math.max(i[1],e[1]):c.push([e[0],e[1]])}for(const[e,t]of c)s.push([[a[0]+i*e,a[1]+n*e],[a[0]+i*t,a[1]+n*t]])}return s}(e))}}const c=this._sunRaysCache.rays,h=this._sunRaysCache.rims;if(!c.length)return t;const d=(u=function(e){const t=Math.min(90,Math.max(-90,Number(e)||0));let i=lr[lr.length-1][1];for(let e=1;e - ${c.map((e,t)=>{const i=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2,r=i+e.normal[0]*e.depth,o=n+e.normal[1]*e.depth;return W``}_renderWallThickUi(){return this._editorRuntime?this._editorRuntimeOrThrow()._renderWallThickUi():W``}_renderWallThickDialog(){return this._editorRuntimeOrThrow()._renderWallThickDialog()}_openingAt(e){return this._editorRuntimeOrThrow()._openingAt(e)}_resolveOpeningPlacement(e){return this._editorRuntimeOrThrow()._resolveOpeningPlacement(e)}_activateOpeningPlacement(e){return this._editorRuntimeOrThrow()._activateOpeningPlacement(e)}_clearOpeningPlacement(e){return this._editorRuntime?this._editorRuntimeOrThrow()._clearOpeningPlacement(e):(this._openingHoverCandidate=null,this._openingJambBlockCm=null,void(e&&(this._openingPreset=null,this._openingRebindId=null)))}_openingClick(e){return this._editorRuntimeOrThrow()._openingClick(e)}_editOpening(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._editOpening(e)}_opPointerDown(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerDown(e,t)}_opPointerMove(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerMove(e,t)}_opRuler(e,t){return this._editorRuntimeOrThrow()._opRuler(e,t)}_opPointerUp(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerUp(e,t)}_opClick(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opClick(e,t)}_saveOpening(){return this._editorRuntimeOrThrow()._saveOpening()}_deleteOpening(){return this._editorRuntimeOrThrow()._deleteOpening()}_contactCandidates(){return this._editorRuntimeOrThrow()._contactCandidates()}_lockCandidates(){return this._editorRuntimeOrThrow()._lockCandidates()}_toggleOpeningEntityPicker(e){return this._editorRuntimeOrThrow()._toggleOpeningEntityPicker(e)}_filterOpeningEntities(e,t){return this._editorRuntimeOrThrow()._filterOpeningEntities(e,t)}_selectOpeningEntity(e,t){return this._editorRuntimeOrThrow()._selectOpeningEntity(e,t)}_mergeClick(e){return this._editorRuntimeOrThrow()._mergeClick(e)}_commitMerge(){return this._editorRuntimeOrThrow()._commitMerge()}_splitClick(e){return this._editorRuntimeOrThrow()._splitClick(e)}get _contourClosed(){return this._path.length>=4&&this._samePt(this._path[0],this._path[this._path.length-1])&&(null!=this._closingWallCm||!this._activeWallChainId)}_markupMove(e){this._markup&&this._editorRuntime&&this._editorRuntimeOrThrow()._queuePointerMove("markup-hover",()=>this._editorRuntime._markupMove(e))}get _openingPreview(){const e=this._openingPreset;if("opening"!==this._tool||!e||!this._cursorPt)return null;const t=this._cursorPt,i=this._openingHoverCandidate;if(i&&Yf(i,[t[0],t[1]],e.revision,this._cfgEpoch))return i;if(this._openingAt(t))return this._openingHoverCandidate=null,null;const n=this._resolveOpeningPlacement(t);return this._openingHoverCandidate=n,n}get _opMeasureView(){return this._opMeasure||this._openingPreview?.measure||null}_saveRoom(){return this._editorRuntimeOrThrow()._saveRoom()}_decideWallFace(e){return this._editorRuntimeOrThrow()._decideWallFace(e)}_wallSourceCmAt(e,t,i){return this._editorRuntimeOrThrow()._wallSourceCmAt(e,t,i)}_activePathWithRepair(e,t){return this._editorRuntimeOrThrow()._activePathWithRepair(e,t)}_validateWallRepair(e,t){return this._editorRuntimeOrThrow()._validateWallRepair(e,t)}_applyWallRepair(e,t){return this._editorRuntimeOrThrow()._applyWallRepair(e,t)}_applyWallFaceBatch(){return this._editorRuntimeOrThrow()._applyWallFaceBatch()}_commitRoom(){return this._editorRuntimeOrThrow()._commitRoom()}_cancelPath(){return this._editorRuntimeOrThrow()._cancelPath()}_roomDialogCancel(){return this._editorRuntimeOrThrow()._roomDialogCancel()}get _freeAreas(){const e=new Set;for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area&&e.add(i.area);for(const t of this._wallFaceBatch?.decisions||[])t.create&&t.area&&e.add(t.area);return Object.values(this.hass?.areas||{}).filter(t=>!e.has(t.area_id)).sort((e,t)=>(e.name||"").localeCompare(t.name||""))}_openDeviceInbox(){return this._editorRuntimeOrThrow()._openDeviceInbox()}_closeMarkerDialog(){return this._editorRuntimeOrThrow()._closeMarkerDialog()}_deviceInboxCandidates(e){return this._editorRuntimeOrThrow()._deviceInboxCandidates(e)}_deviceInboxRows(){return this._editorRuntimeOrThrow()._deviceInboxRows()}_deviceForInboxRow(e){return this._editorRuntimeOrThrow()._deviceForInboxRow(e)}_openInboxMarker(e,t=!1){return this._editorRuntimeOrThrow()._openInboxMarker(e,t)}async _setInboxHidden(e,t){return this._editorRuntimeOrThrow()._setInboxHidden(e,t)}_findInboxDevice(e){return this._editorRuntimeOrThrow()._findInboxDevice(e)}_deviceInboxTabKey(e){return this._editorRuntimeOrThrow()._deviceInboxTabKey(e)}_openMarkerDialog(e){if(this._editorRuntime)return this._editorRuntime._openMarkerDialog(e);this._ensureEditorRuntime().then(t=>{t&&this._openMarkerDialog(e)})}_runCandidates(){return this._editorRuntimeOrThrow()._runCandidates()}_bindingCandidates(){return this._editorRuntimeOrThrow()._bindingCandidates()}_physicalBodiesR(e=this._spaceModel()){if(!e)return[];const t=`${e.id}|${this._cfgEpoch}|${this._cellCm}|${this._gridPitch}`;if(this._physicalBodiesCache?.key===t)return this._physicalBodiesCache.all;const i=Ma(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e));return this._physicalBodiesCache={key:t,...i},i.all}_rawPhysicalBodiesR(e=this._spaceModel()){if(!e)return[];this._physicalBodiesR(e);const t=this._physicalBodiesCache;return t?[...t.partitions,...t.columns]:[]}_cleanFloor(e,t,i=this._spaceModel()){if(!i)return{floor:t,geom:null,path:"",area:Pa([[[...t,t[0]]]])};const n=e.id||`#${i.rooms.indexOf(e)}`,r=`${i.id}|${this._cfgEpoch}|${n}`;if(!this._resize?.preview){const e=Sf(this._cleanFloorCache,r);if(e.hit)return e.value}const o=t.map(e=>e[0]),s=t.map(e=>e[1]),a=[Math.min(...o),Math.min(...s),Math.max(...o),Math.max(...s)],l=this._physicalBodiesR(i).filter(e=>{const t=e.map(e=>e[0]),i=e.map(e=>e[1]);return Math.max(...t)>=a[0]&&Math.min(...t)<=a[2]&&Math.max(...i)>=a[1]&&Math.min(...i)<=a[3]}),c=l.length?Aa(t,l):null,h={floor:t,geom:c,path:c?ba(c):"",area:Pa(c||[[[...t,t[0]]]])};return this._resize?.preview||$f(this._cleanFloorCache,r,h,600),h}_autoIconForBinding(e){if("virtual"===e)return"mdi:map-marker";const[t,i]=e.split(":");if(!i)return"";const n=this._fullRegistryHass,r=this._bindingStatus(e),o="active"===r.kind?r.enabledEntityIds:r.allEntityIds;if("device"===t){const e=n.devices?.[i];if(!e)return"mdi:help-circle";const t=o;return t.some(e=>e.startsWith("lock."))?"mdi:lock":Ud(n,e.name_by_user||e.name||"",e.model,t,this._iconRules)}if("entity"===t){const e=n.entities?.[i],t=this.hass.states?.[i],r=e?.name||t?.attributes?.friendly_name||i;return i.startsWith("lock.")?"mdi:lock":Ud(n,r,"",[i],this._iconRules)}return""}_allRoomsFlat(){const e=[];for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area?e.push({value:t.id+"#"+i.area,label:(t.title||t.id)+" · "+i.name}):i.id&&e.push({value:t.id+"#@"+i.id,label:(t.title||t.id)+" · "+i.name+" · "+this._t("marker.subarea")});return e}_errText(e){if(!e)return this._t("err.unknown");if("string"==typeof e)return e;if("invalid_passage_fields"===e.code){const t=String(e.message||e.error||"");let i="",n=[];try{const e=JSON.parse(t);i=String(e.space??""),n=Array.isArray(e.fields)?e.fields.map(String):[]}catch{const e=t.match(/space=([^;]*);\s*opening=([^;]*);\s*fields=([^;]*)/);e&&(i=e[1],n=e[3].split(",").filter(Boolean))}if(i||n.length){const e=this._serverCfg?.spaces?.find(e=>String(e.id)===i),t={contact:"opening.contact_label",lock:"opening.lock_label",invert:"opening.invert",flip_h:"opening.flip_h",flip_v:"opening.flip_v"},r=n.map(e=>t[e]?this._t(t[e]):e).join(", ");return this._t("opening.invalid_passage_fields",{room:e?.title||i,fields:r})}}if("invalid_partition_opening_jamb_margin"===e.code){const t=String(e.message||e.error||"");let i=NaN;try{i=Number(JSON.parse(t).margin_cm)}catch{const e=t.match(/margin_cm=([^;}"]*)/);i=e?Number(e[1]):NaN}if(Number.isFinite(i))return this._t("opening.partition_jamb_margin",{distance:ti(i,this._imperial)})}if(null!=e.code){const t=`backup.error.${e.code}`,i=this._t(t);return e.message&&console.warn("[houseplan] backend error",e.code,e.message),i!==t?i:this._t("err.code",{code:e.code})}if(e.message)return e.message;if(e.error)return e.error;try{return JSON.stringify(e)}catch{return String(e)}}_backupErrorText(e){return this._editorRuntimeOrThrow()._backupErrorText(e)}async _pickMarkerFiles(e){return this._editorRuntimeOrThrow()._pickMarkerFiles(e)}_removeMarkerPdf(e){return this._editorRuntimeOrThrow()._removeMarkerPdf(e)}_markerLightFields(e){return this._editorRuntimeOrThrow()._markerLightFields(e)}_markerTapActionFields(e){return this._editorRuntimeOrThrow()._markerTapActionFields(e)}_markerToggleEntityFields(e){return this._editorRuntimeOrThrow()._markerToggleEntityFields(e)}async _saveMarker(){return this._editorRuntimeOrThrow()._saveMarker()}async _deleteMarker(){return this._editorRuntimeOrThrow()._deleteMarker()}_normPos(e,t,i){return{s:e,x:t/pv,y:i/pv}}_spaceDialogUsesOnboardingRuntime(e){return"create"===e&&!this._editorRuntime&&(!!this._onboardingRuntime||0===(this._serverCfg?.spaces.length||0)||this._importTotal>0||this._importQueue.length>0)}_spaceRuntimeOrThrow(){if(!this._onboardingRuntime)throw new Error("Houseplan onboarding runtime is not loaded");return this._onboardingRuntime}_openSpaceDialog(e,t){return this._spaceDialogUsesOnboardingRuntime(e)?this._onboardingRuntime?void this._onboardingRuntime._openSpaceDialog(e,t):void this._ensureOnboardingRuntime().then(i=>{i&&this._spaceRuntimeOrThrow()._openSpaceDialog(e,t)}):this._editorRuntime?this._editorRuntime._openSpaceDialog(e,t):void this._ensureEditorRuntime().then(i=>{i&&this._openSpaceDialog(e,t)})}async _pickPlanFile(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._pickPlanFile(e):this._editorRuntimeOrThrow()._pickPlanFile(e)}_useServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._useServerPlan(e):this._editorRuntimeOrThrow()._useServerPlan(e)}async _readPlanAspect(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._readPlanAspect(e):this._editorRuntimeOrThrow()._readPlanAspect(e)}async _deleteServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._deleteServerPlan(e):this._editorRuntimeOrThrow()._deleteServerPlan(e)}_renderServerPlans(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime(e.mode)?this._onboardingRuntime._renderServerPlans(e):this._editorRuntimeOrThrow()._renderServerPlans(e)}async _saveSpaceDialog(){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._saveSpaceDialog():this._editorRuntimeOrThrow()._saveSpaceDialog()}async _deleteSpace(){return this._editorRuntimeOrThrow()._deleteSpace()}async _saveConfigNow(){return this._editorRuntimeOrThrow()._saveConfigNow()}_startImport(){return this._onboardingRuntime?this._onboardingRuntime._startImport():this._editorRuntimeOrThrow()._startImport()}_openNextImport(){return this._onboardingRuntime?this._onboardingRuntime._openNextImport():this._editorRuntimeOrThrow()._openNextImport()}_skipImport(){return this._onboardingRuntime?this._onboardingRuntime._skipImport():this._editorRuntimeOrThrow()._skipImport()}_renderImportDialog(){return this._onboardingRuntime?this._onboardingRuntime._renderImportDialog():this._editorRuntimeOrThrow()._renderImportDialog()}_sunGlobal(){const e=this._settingsDialog;return e?{...this._settings,north_deg:e.northDeg??void 0,bg_mode:e.bgMode,sun_rays:e.sunRays,sun_ray_origin:e.sunRayOrigin}:this._settings}_sunSpace(){const e=this._spaceDialog,t=this._curSpaceCfg?.settings||{};return e&&"edit"===e.mode&&e.spaceId===this._space?{...t,north_deg:e.northDeg??void 0,bg_mode:e.bgMode??void 0,sun_rays:e.sunRays??void 0}:t}_effNorth(){return gr(this._sunGlobal(),this._sunSpace())}_effBgMode(){return vr(this._sunGlobal(),this._sunSpace())}_dayCycleState(e=new Date){return(this._modeTransitionVisual?.viewWeight??("view"===this._mode?1:0))<=0||"daynight"!==this._effBgMode()?null:sr(this._renderPlanHass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?ar(e):"";const t="clock"===e?.source&&"hidden"!==this.ownerDocument.visibilityState&&this.isConnected;t&&!this._dayCycleTimer?this._dayCycleTimer=window.setInterval(this._dayCycleTick,3e4):!t&&this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_dayCycleVisibility(e){"hidden"!==e.kind?(this._dayCycleTick(),this._syncDayCycleClock()):this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_effSunRays(){return yr(this._sunGlobal(),this._sunSpace())}_effSunRayOrigin(){return fr(this._sunGlobal())}_sunNow(){return null!==this._effNorth()?br(this._renderPlanHass):null}_renderSunRays(e){const t=W``,i=this._modeTransitionVisual?.viewWeight??0;if(this._editing&&i<=0||!this._effSunRays())return this._sunFadeReset(),t;const n=this._effNorth(),r=null!==n?br(this._renderPlanHass):null;if(!r||r.elevation<=0)return this._sunFadeReset(),t;if(o=r.elevation,Number(o)>=3)this._sunOutTimer&&(clearTimeout(this._sunOutTimer),this._sunOutTimer=0),this._sunOut=!1,this._sunShown=!0;else{if(!this._sunShown)return t;this._sunOut||(this._sunOut=!0,this._sunOutTimer=window.setTimeout(()=>{this._sunOutTimer=0,this._sunShown=!1,this._sunOut=!1,this.requestUpdate()},2e3))}var o;const s=this._zeroWalls(),a=s.barriers.map(e=>e.join(",")).join(";"),l=this._effSunRayOrigin(),c=`${e.id}|${r.azimuth}|${r.elevation}|${n}|${l}|${this._cfgEpoch}|${s.style}|${a}`;if(!this._sunRaysCache||this._sunRaysCache.key!==c){const t=e.rooms.map(e=>({id:e.id||"",poly:ni(e)})).filter(e=>!!e.id&&!!e.poly),i=this._openingsR.filter(e=>"window"===e.type&&"partition"!==e.host?.kind).map(e=>({id:e.id,x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=this._spaceWalls,a=this._openCuts(),h=this._openingWallIndexFor(e,a).value,d={},u={},p=this._wallUnionGeometry()?.roomGeom;if(o.length){for(const i of t){const t=this._innerRoomContour(e,i.id,a,p);t&&(d[i.id]=t)}for(const e of i){const t=ca(h,{x:e.x,y:e.y,angle:e.angle,length:e.length});t.cm>0&&(u[e.id]=Po(t.cm,this._cellCm,this._gridPitch))}}let _=_r(t,i,r.azimuth,r.elevation,n,o.length?d:void 0,o.length?u:void 0,l);const m=[...this._physicalBodiesR(e),...s.barriers.map(e=>[[e[0],e[1]],[e[2],e[3]]])];m.length&&(_=_.map(e=>{const t=function(e,t,i){return i>0?e.map(e=>function(e){const t=[...e].sort((e,t)=>e[0]-t[0]||e[1]-t[1]);if(t.length<=2)return t;const i=(e,t,i)=>(t[0]-e[0])*(i[1]-e[1])-(t[1]-e[1])*(i[0]-e[0]),n=[];for(const e of t){for(;n.length>=2&&i(n[n.length-2],n[n.length-1],e)<=0;)n.pop();n.push(e)}const r=[];for(let e=t.length-1;e>=0;e--){const n=t[e];for(;r.length>=2&&i(r[r.length-2],r[r.length-1],n)<=0;)r.pop();r.push(n)}return n.slice(0,-1).concat(r.slice(0,-1))}([...e,...e.map(e=>[e[0]+t[0]*i,e[1]+t[1]*i])])).filter(e=>e.length>=3):e}(m,e.dir,e.len),i=e.polys.map(e=>Aa(e,t));return{...e,paths:i.map(ba).filter(Boolean),polys:i.flatMap(za)}}).filter(e=>e.paths?.length||e.polys.length)),this._sunRaysCache={key:c,rays:_,rims:_.map(e=>function(e,t=1e-4){const[i,n]=e.dir,r=-n,o=i,s=[];for(const a of[e.a,e.b]){const l=[];for(const s of e.polys)for(let e=0;et)continue;if(Math.abs((h[0]-a[0])*r+(h[1]-a[1])*o)>t)continue;const d=(c[0]-a[0])*i+(c[1]-a[1])*n,u=(h[0]-a[0])*i+(h[1]-a[1])*n;Math.abs(u-d)<=t||l.push(de[0]-t[0]);const c=[];for(const e of l){const i=c[c.length-1];i&&e[0]<=i[1]+t?i[1]=Math.max(i[1],e[1]):c.push([e[0],e[1]])}for(const[e,t]of c)s.push([[a[0]+i*e,a[1]+n*e],[a[0]+i*t,a[1]+n*t]])}return s}(e))}}const h=this._sunRaysCache.rays,d=this._sunRaysCache.rims;if(!h.length)return t;const u=(p=function(e){const t=Math.min(90,Math.max(-90,Number(e)||0));let i=lr[lr.length-1][1];for(let e=1;e + ${h.map((e,t)=>{const i=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2,r=i+e.normal[0]*e.depth,o=n+e.normal[1]*e.depth;return W` - ${p.map(([e,t])=>W``)} + ${_.map(([e,t])=>W``)} - ${_.map(([e,t])=>W`W``)} `})} - ${c.map((e,t)=>e.paths?.length?e.paths.map(e=>W``):e.polys.map(e=>W`e.paths?.length?e.paths.map(e=>W``):e.polys.map(e=>W``))} - ${c.map((e,t)=>(h[t]||[]).map(e=>W`(d[t]||[]).map(e=>W``))} @@ -507,7 +507,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this._t("gs.north_letter")} ${null===e?"—":e+"°"} - `}_stageBg(e){const t=this._settingsDialog,i=this._spaceDialog,n=t?t.bgColor||"":pn(this._settings,{bgColor:null});return(i&&"edit"===i.mode&&i.spaceId===this._space?i.bgColor||"":e.bgColor||"")||n}_stageBgHex(){const e=this._stageEl;if(e){const t=getComputedStyle(e).backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(t)return"#"+t.slice(1,4).map(e=>(+e).toString(16).padStart(2,"0")).join("")}return"#111111"}_renderPdfDialog(){const e=this._pdfRuntime,t=this._spaceModel(),i=this._curSpaceCfg;if(!(e&&t&&i&&this._serverCfg))return G;const n=new Map;for(const[e,t]of this._decorAssets)n.set(e,{url:this._display(t.url),mime:t.mime});const r=this._wallUnionGeometry(),o=this._openCuts(),s=new Map(t.rooms.flatMap(e=>e.id?[[e.id,e]]:[]));return e.render({config:this._serverCfg,rawSpace:i,space:t,layout:this._layout,imperial:this._imperial,cardTitle:this._config?.title||this._t("card.title"),version:Jf(ev),hass:this.hass,backdropUrl:t.bg?this._display(t.bg.href):"",decorAssets:n,sharedWallGeometry:r,resolveInnerContour:e=>this._innerRoomContour(t,e,o,r?.roomGeom,r?.multiWallNodes),resolveRoomArea:(e,i)=>{const n=s.get(e);return n?this._cleanFloor(n,i,t).area:void 0},t:(e,t)=>this._t(e,t),toast:e=>this._showToast(e),close:()=>{this._pdfDialog=!1,this.requestUpdate()}})}_preflightDiagnostics(e,t){return this._editorRuntimeOrThrow()._preflightDiagnostics(e,t)}_reportPreflightFailure(e,t){return this._editorRuntimeOrThrow()._reportPreflightFailure(e,t)}_preflightVersionsDiffer(){return this._editorRuntimeOrThrow()._preflightVersionsDiffer()}async _copyPreflightDiagnostics(){return this._editorRuntimeOrThrow()._copyPreflightDiagnostics()}_checkOptimizeGeometry(e){return this._editorRuntimeOrThrow()._checkOptimizeGeometryImpl(e)}_checkSpacePhysicalGeometry(e,t,i){return this._editorRuntimeOrThrow()._checkSpacePhysicalGeometryImpl(e,t,i)}_optimizeReferenceContext(e){return this._editorRuntimeOrThrow()._optimizeReferenceContext(e)}_previewAlignDialog(e){return this._editorRuntimeOrThrow()._previewAlignDialog(e)}async _runAlignToGrid(){return this._editorRuntimeOrThrow()._runAlignToGrid()}async _undoPlanOptimization(){return this._editorRuntimeOrThrow()._undoPlanOptimization()}async _runBackupExport(){return this._editorRuntimeOrThrow()._runBackupExport()}async _pickBackupImport(e){return this._editorRuntimeOrThrow()._pickBackupImport(e)}async _setBackupDuplicatePolicy(e){return this._editorRuntimeOrThrow()._setBackupDuplicatePolicy(e)}async _applyBackupImport(){return this._editorRuntimeOrThrow()._applyBackupImport()}_renderBackupExportDialog(){return this._editorRuntimeOrThrow()._renderBackupExportDialog()}_renderBackupImportDialog(){return this._editorRuntimeOrThrow()._renderBackupImportDialog()}_setFillColor(e,t){return this._editorRuntimeOrThrow()._setFillColor(e,t)}async _saveSettingsDialog(){return this._editorRuntimeOrThrow()._saveSettingsDialog()}_boolInput(e,t,i=!1){return this._editorRuntimeOrThrow()._boolInput(e,t,i)}_rangeInput(e,t,i,n,r,o=!1,s){return this._editorRuntimeOrThrow()._rangeInput(e,t,i,n,r,o,s)}_renderColorRow(e,t){return this._editorRuntimeOrThrow()._renderColorRow(e,t)}get _glowRadiusCm(){const e=Number(this._settings.glow_radius_cm);return Number.isFinite(e)&&e>0?e:300}get _imperial(){return"mi"===this.hass?.config?.unit_system?.length}get _glowRadiusPlaceholder(){const e=this._glowRadiusCm;return this._imperial?String(Math.round(e/30.48*10)/10):String(e/100)}_glowTransition(e,t){return Rm(this._glowRuntimeState,this._glowRuntimeHost,e,t)}_forgetGlowSource(e){Cm(this._glowRuntimeState,this._glowRuntimeHost,e)}_forgetGlowSpace(e){Tm(this._glowRuntimeState,this._glowRuntimeHost,e)}_warnGlowGeometryFallback(e,t,i,n){Pm(this._glowRuntimeState,e,t,i,n)}_lightBarriers(e,t){const i=km({rawSpaceConfig:this._curSpaceCfg,space:e,openings:this._openingsR,cellCm:this._cellCm,gridPitch:this._gridPitch,openingAmount:e=>this._openingAmt(e)}),n=`${e.id}|${i.fingerprint}`,r=xf(this._lightBarrierPool,n);if(r.hit)return this._lightBarrierCache=r.value,r.value.value;const o=xm({space:e,revision:i,walls:this._spaceWalls,zeroWalls:this._zeroWalls(),wallKeyPitch:this._wallKeyPitch,cellCm:this._cellCm,gridPitch:this._gridPitch,coordScale:uv,sharedWallGeometry:this._wallUnionGeometry(),physicalBodies:(t,i)=>(this._lightPhysicalBodiesCache?.key!==i&&(this._lightPhysicalBodiesCache={key:i,all:$a(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,t).all}),this._lightPhysicalBodiesCache.all)}),s={key:n,value:o};return Sf(this._lightBarrierPool,n,s,8),this._lightBarrierCache=s,o}_renderGlowLayer(e,t,i=this._viewOr(this._baseVb())){const n=this._fillColors,r=this._glowRadiusCm/this._cellCm*this._gridPitch,o=e.rooms.map(e=>({r:e,poly:ni(e)})).filter(e=>!!e.poly),s=o.filter(({r:e})=>Hn(t.glow,e));if(!s.length)return this._forgetGlowSpace(e.id),W``;const a=this._lightBarriers(e,o),l=wm({hass:this._renderPlanHass,devices:this._renderDevices,virtualLights:this._virtualLights,spaceId:e.id,defaultColor:n.glow_light.c,paletteAlpha:n.glow_light.a,defaultRadiusUnits:r,cellCm:this._cellCm,gridPitch:this._gridPitch,position:e=>this._pos(e)}),c=[],h=new Set;for(const t of l){const{key:i,pos:n}=t;if(h.add(i),$m(n,a)){this._forgetGlowSource(i);continue}const r=this._glowTransition(i,!!t.appearance);if(!r)continue;t.appearance&&this._glowLastAppearance.set(i,t.appearance);const s=this._glowLastAppearance.get(i);if(!s)continue;let l=null;const d=`${e.id}|${a.fingerprint}|${n.x.toFixed(4)},${n.y.toFixed(4)}|${t.radius.toFixed(4)}`,u=ym(this._glowRuntimeState,d);u.hit?l=u.value:(l=Sm({spaceId:e.id,source:n,radius:t.radius,scene:a,polygons:o.map(({r:e,poly:t})=>({room:e,poly:t})),onBoundsFailure:(t,i)=>this._warnGlowGeometryFallback(e.id,a.fingerprint,t,i)}),bm(this._glowRuntimeState,d,l)),c.push({key:i,sourceEid:t.sourceEid,domId:r.domId,entering:r.entering,leaving:r.leaving,pos:n,c:s.c,alpha:s.alpha,geometry:l,r:t.radius})}if(Dm(this._glowRuntimeState,this._glowRuntimeHost,e.id,h),!c.length)return W``;const d=this._spaceWalls,u=s.length===o.length?[]:this._openCuts(),p=this._wallUnionGeometry()?.roomGeom,_=s.length===o.length?null:s.map(({r:t,poly:i})=>{const n=d.length&&t.id&&this._innerRoomContour(e,t.id,u,p)||i,r=this._cleanFloor(t,n,e).path,s=Ri(n,o.filter(e=>e.r!==t).map(e=>e.poly)),a=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z";return[r||a(n),...s.map(a)].join(" ")}),m=this._stageEl?.clientWidth&&i.w?this._stageEl.clientWidth/i.w:1,g=!this._pinchStart&&!this._panStart&&!this._cameraTransition.active,f=Fm(this._glowRuntimeState,m,g);return zm({spots:c,enabledClip:_,feather:f.feather,featherEnabled:f.enabled,screenBlend:this._glowScreenBlend})}_renderAlignDialog(){return this._editorRuntimeOrThrow()._renderAlignDialog()}_renderSettingsDialog(){return this._editorRuntimeOrThrow()._renderSettingsDialog()}_renderSupportDialog(){return this._editorRuntimeOrThrow()._renderSupportDialog()}_rulesSet(e){return this._editorRuntimeOrThrow()._rulesSet(e)}async _saveRules(){return this._editorRuntimeOrThrow()._saveRules()}_renderRulesDialog(){return this._editorRuntimeOrThrow()._renderRulesDialog()}_saveKioskScale(e){this._summary?.saveScale(e)}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>{const n=Math.round(100*e[t]);return j` + `}_stageBg(e){const t=this._settingsDialog,i=this._spaceDialog,n=t?t.bgColor||"":pn(this._settings,{bgColor:null});return(i&&"edit"===i.mode&&i.spaceId===this._space?i.bgColor||"":e.bgColor||"")||n}_stageBgHex(){const e=this._stageEl;if(e){const t=getComputedStyle(e).backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(t)return"#"+t.slice(1,4).map(e=>(+e).toString(16).padStart(2,"0")).join("")}return"#111111"}_renderPdfDialog(){const e=this._pdfRuntime,t=this._spaceModel(),i=this._curSpaceCfg;if(!(e&&t&&i&&this._serverCfg))return G;const n=new Map;for(const[e,t]of this._decorAssets)n.set(e,{url:this._display(t.url),mime:t.mime});const r=this._wallUnionGeometry(),o=this._openCuts(),s=new Map(t.rooms.flatMap(e=>e.id?[[e.id,e]]:[]));return e.render({config:this._serverCfg,rawSpace:i,space:t,layout:this._layout,imperial:this._imperial,cardTitle:this._config?.title||this._t("card.title"),version:Qf(tv),hass:this.hass,backdropUrl:t.bg?this._display(t.bg.href):"",decorAssets:n,sharedWallGeometry:r,resolveInnerContour:e=>this._innerRoomContour(t,e,o,r?.roomGeom,r?.multiWallNodes),resolveRoomArea:(e,i)=>{const n=s.get(e);return n?this._cleanFloor(n,i,t).area:void 0},t:(e,t)=>this._t(e,t),toast:e=>this._showToast(e),close:()=>{this._pdfDialog=!1,this.requestUpdate()}})}_preflightDiagnostics(e,t){return this._editorRuntimeOrThrow()._preflightDiagnostics(e,t)}_reportPreflightFailure(e,t){return this._editorRuntimeOrThrow()._reportPreflightFailure(e,t)}_preflightVersionsDiffer(){return this._editorRuntimeOrThrow()._preflightVersionsDiffer()}async _copyPreflightDiagnostics(){return this._editorRuntimeOrThrow()._copyPreflightDiagnostics()}_checkOptimizeGeometry(e){return this._editorRuntimeOrThrow()._checkOptimizeGeometryImpl(e)}_checkSpacePhysicalGeometry(e,t,i){return this._editorRuntimeOrThrow()._checkSpacePhysicalGeometryImpl(e,t,i)}_optimizeReferenceContext(e){return this._editorRuntimeOrThrow()._optimizeReferenceContext(e)}_previewAlignDialog(e){return this._editorRuntimeOrThrow()._previewAlignDialog(e)}async _runAlignToGrid(){return this._editorRuntimeOrThrow()._runAlignToGrid()}async _undoPlanOptimization(){return this._editorRuntimeOrThrow()._undoPlanOptimization()}async _runBackupExport(){return this._editorRuntimeOrThrow()._runBackupExport()}async _pickBackupImport(e){return this._editorRuntimeOrThrow()._pickBackupImport(e)}async _setBackupDuplicatePolicy(e){return this._editorRuntimeOrThrow()._setBackupDuplicatePolicy(e)}async _applyBackupImport(){return this._editorRuntimeOrThrow()._applyBackupImport()}_renderBackupExportDialog(){return this._editorRuntimeOrThrow()._renderBackupExportDialog()}_renderBackupImportDialog(){return this._editorRuntimeOrThrow()._renderBackupImportDialog()}_setFillColor(e,t){return this._editorRuntimeOrThrow()._setFillColor(e,t)}async _saveSettingsDialog(){return this._editorRuntimeOrThrow()._saveSettingsDialog()}_boolInput(e,t,i=!1){return this._editorRuntimeOrThrow()._boolInput(e,t,i)}_rangeInput(e,t,i,n,r,o=!1,s){return this._editorRuntimeOrThrow()._rangeInput(e,t,i,n,r,o,s)}_renderColorRow(e,t){return this._editorRuntimeOrThrow()._renderColorRow(e,t)}get _glowRadiusCm(){const e=Number(this._settings.glow_radius_cm);return Number.isFinite(e)&&e>0?e:300}get _imperial(){return"mi"===this.hass?.config?.unit_system?.length}get _glowRadiusPlaceholder(){const e=this._glowRadiusCm;return this._imperial?String(Math.round(e/30.48*10)/10):String(e/100)}_glowTransition(e,t){return Cm(this._glowRuntimeState,this._glowRuntimeHost,e,t)}_forgetGlowSource(e){Tm(this._glowRuntimeState,this._glowRuntimeHost,e)}_forgetGlowSpace(e){Dm(this._glowRuntimeState,this._glowRuntimeHost,e)}_warnGlowGeometryFallback(e,t,i,n){Fm(this._glowRuntimeState,e,t,i,n)}_lightBarriers(e,t){const i=xm({rawSpaceConfig:this._curSpaceCfg,space:e,openings:this._openingsR,cellCm:this._cellCm,gridPitch:this._gridPitch,openingAmount:e=>this._openingAmt(e)}),n=`${e.id}|${i.fingerprint}`,r=Sf(this._lightBarrierPool,n);if(r.hit)return this._lightBarrierCache=r.value,r.value.value;const o=Sm({space:e,revision:i,walls:this._spaceWalls,zeroWalls:this._zeroWalls(),wallKeyPitch:this._wallKeyPitch,cellCm:this._cellCm,gridPitch:this._gridPitch,coordScale:pv,sharedWallGeometry:this._wallUnionGeometry(),physicalBodies:(t,i)=>(this._lightPhysicalBodiesCache?.key!==i&&(this._lightPhysicalBodiesCache={key:i,all:Ma(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,t).all}),this._lightPhysicalBodiesCache.all)}),s={key:n,value:o};return $f(this._lightBarrierPool,n,s,8),this._lightBarrierCache=s,o}_renderGlowLayer(e,t,i=this._viewOr(this._baseVb())){const n=this._fillColors,r=this._glowRadiusCm/this._cellCm*this._gridPitch,o=e.rooms.map(e=>({r:e,poly:ni(e)})).filter(e=>!!e.poly),s=o.filter(({r:e})=>Hn(t.glow,e));if(!s.length)return this._forgetGlowSpace(e.id),W``;const a=this._lightBarriers(e,o),l=km({hass:this._renderPlanHass,devices:this._renderDevices,virtualLights:this._virtualLights,spaceId:e.id,defaultColor:n.glow_light.c,paletteAlpha:n.glow_light.a,defaultRadiusUnits:r,cellCm:this._cellCm,gridPitch:this._gridPitch,position:e=>this._pos(e)}),c=[],h=new Set;for(const t of l){const{key:i,pos:n}=t;if(h.add(i),Mm(n,a)){this._forgetGlowSource(i);continue}const r=this._glowTransition(i,!!t.appearance);if(!r)continue;t.appearance&&this._glowLastAppearance.set(i,t.appearance);const s=this._glowLastAppearance.get(i);if(!s)continue;let l=null;const d=`${e.id}|${a.fingerprint}|${n.x.toFixed(4)},${n.y.toFixed(4)}|${t.radius.toFixed(4)}`,u=bm(this._glowRuntimeState,d);u.hit?l=u.value:(l=$m({spaceId:e.id,source:n,radius:t.radius,scene:a,polygons:o.map(({r:e,poly:t})=>({room:e,poly:t})),onBoundsFailure:(t,i)=>this._warnGlowGeometryFallback(e.id,a.fingerprint,t,i)}),wm(this._glowRuntimeState,d,l)),c.push({key:i,sourceEid:t.sourceEid,domId:r.domId,entering:r.entering,leaving:r.leaving,pos:n,c:s.c,alpha:s.alpha,geometry:l,r:t.radius})}if(Am(this._glowRuntimeState,this._glowRuntimeHost,e.id,h),!c.length)return W``;const d=this._spaceWalls,u=s.length===o.length?[]:this._openCuts(),p=this._wallUnionGeometry()?.roomGeom,_=s.length===o.length?null:s.map(({r:t,poly:i})=>{const n=d.length&&t.id&&this._innerRoomContour(e,t.id,u,p)||i,r=this._cleanFloor(t,n,e).path,s=Ri(n,o.filter(e=>e.r!==t).map(e=>e.poly)),a=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z";return[r||a(n),...s.map(a)].join(" ")}),m=this._stageEl?.clientWidth&&i.w?this._stageEl.clientWidth/i.w:1,g=!this._pinchStart&&!this._panStart&&!this._cameraTransition.active,f=zm(this._glowRuntimeState,m,g);return Im({spots:c,enabledClip:_,feather:f.feather,featherEnabled:f.enabled,screenBlend:this._glowScreenBlend})}_renderAlignDialog(){return this._editorRuntimeOrThrow()._renderAlignDialog()}_renderSettingsDialog(){return this._editorRuntimeOrThrow()._renderSettingsDialog()}_renderSupportDialog(){return this._editorRuntimeOrThrow()._renderSupportDialog()}_rulesSet(e){return this._editorRuntimeOrThrow()._rulesSet(e)}async _saveRules(){return this._editorRuntimeOrThrow()._saveRules()}_renderRulesDialog(){return this._editorRuntimeOrThrow()._renderRulesDialog()}_saveKioskScale(e){this._summary?.saveScale(e)}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>{const n=Math.round(100*e[t]);return j`
{const i=Number(e.target.value);Number.isFinite(i)&&this._saveKioskScale({[t]:i/100})}} aria-label=${i} /> @@ -528,7 +528,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 .request=${this._dangerConfirm.request} .token=${this._dangerConfirm.token} @hp-confirm-decision=${this._onDangerConfirmDecision}> - `:G}_renderRoot(e){return j`${e}${this._renderVersionBanner()}${this._renderDangerConfirm()}`}render(){const e=this._renderBody();return e===G?e:this._renderRoot(e)}_renderBody(){if(!this._config||!this.hass)return G;const e=this._terminalFrame;if(this._terminalFrame=0,1===e)return U;const t=this._syncDangerConfirmLocaleGate();if("cold"===t)return hp();if("warm"===t)return U;const i=!!this._importDialog||!(!this._spaceDialog||!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)),n="view"!==this._mode||!!(this._roomDialog||this._mergeDialog||this._openingDialog||this._physicalDialog||this._partitionDeleteDialog||this._roomDeleteDialog||this._decorTextDialog||this._decorShapeDialog||this._backdropDialog||this._decorEraseConfirm||this._spaceDialog&&!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)||this._deviceInbox||this._markerDialog||this._rulesDialog||this._settingsDialog||this._supportDialog||this._alignDialog||this._backupExportDialog||this._backupImportDialog||this._kioskDialog||this._vacFit||this._vacCalConfirm);i&&!this._onboardingRuntime&&this._ensureOnboardingRuntime(),n&&!this._editorRuntime&&this._ensureEditorRuntime();const r=this._model,o=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e)),s=this._fixedFloorState(r);if("pending"===s.kind)return j` + `:G}_renderRoot(e){return j`${e}${this._renderVersionBanner()}${this._renderDangerConfirm()}`}render(){const e=this._renderBody();return e===G?e:this._renderRoot(e)}_renderBody(){if(!this._config||!this.hass)return G;const e=this._terminalFrame;if(this._terminalFrame=0,1===e)return U;const t=this._syncDangerConfirmLocaleGate();if("cold"===t)return dp();if("warm"===t)return U;const i=!!this._importDialog||!(!this._spaceDialog||!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)),n="view"!==this._mode||!!(this._roomDialog||this._mergeDialog||this._openingDialog||this._physicalDialog||this._partitionDeleteDialog||this._roomDeleteDialog||this._decorTextDialog||this._decorShapeDialog||this._backdropDialog||this._decorEraseConfirm||this._spaceDialog&&!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)||this._deviceInbox||this._markerDialog||this._rulesDialog||this._settingsDialog||this._supportDialog||this._alignDialog||this._backupExportDialog||this._backupImportDialog||this._kioskDialog||this._vacFit||this._vacCalConfirm);i&&!this._onboardingRuntime&&this._ensureOnboardingRuntime(),n&&!this._editorRuntime&&this._ensureEditorRuntime();const r=this._model,o=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e)),s=this._fixedFloorState(r);if("pending"===s.kind)return j` ${this.panelHost?G:j`
${this._config.title||this._t("card.title")}
`} @@ -571,7 +571,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this._spaceDialog&&(this._onboardingRuntime||this._editorRuntime)?this._renderSpaceDialog():G} ${this._importDialog&&this._onboardingRuntime?this._renderImportDialog():G} ${this._toast?j``:G} -
`;const a=this._spaceModel();if(!a)return G;const l="valid"===s.kind?[a]:r,c=a.vb;let h=this._effectiveProjection();this._renderProjection=h,this._labs.active.length&&function(){const e=Ff,t=e.alpha?e.active.join(","):"";if(!t||t===If)return;If=t;const i=new Map(Cf.map(e=>[e.id,e])),n=e.active.map(e=>`${e} (#${i.get(e).issue})`).join(", ");console.info(`HOUSEPLAN ALPHA: hp_alpha=1; ${n}`)}();let d="iso"===h;const u=d?this._isoSceneRuntime:null,p="devices"===this._mode&&this._showAll,_=this._renderDevices.filter(e=>e.space===a.id&&(!e.hidden||p)),m=this._renderDeviceSnapshot,g=this._spaceDisplayForRender(),f=this._resolvedRoomFills(a,g),v=this._resolvedGlowBase(a,g,f),y=g.showLqi??this._config.show_signal??!0,b=this._config.icon_size??2.5,w=b>8?2.5:b,k=w_(w);let x=d?this._renderIsoScene:null,S=this._viewOr(this._baseVb(h,x)),$=null;try{$=u?.resolveIsoFramePresentation({projection:h,display:g,scene:x,openings:this._openingsR,amountOf:e=>this._openingAmt(e),cellCm:this._cellCm,overlays:e=>this._isoOverlayScene(a,_,S,g,e,x,w,k,y)})??null}catch(e){this._latchIsoFallback(g.showBorders?x?.key||this._isoInvalidKey():`${a.id}|no-borders`,e),this._cancelCameraTransition(!1),h="flat",d=!1,x=null,$=null,this._renderProjection="flat",this._renderIsoScene=null,this._isoProjectionSnapshot="flat",this._view=null,this._viewModeSnap=null,S=this._viewOr(this._baseVb("flat",null))}const M=$?.layers??null,R=$?.overlays??null,C=this._editing?"":this._stageBg(g),T=this._opMeasureView,D="view"===this._mode?this._editorChromeMode:this._mode,A=this._roomHoverPaths(a),P=a.bg?this._display(a.bg.href):"",F=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,z=this._modeTransitionVisual,I=this._dayCycleState(),O=z?.viewWeight??("view"===this._mode?1:0),E=this._modeTransition.state?.from.presentedMode,N=!this._markup||!!z&&("view"===z.presentedMode||"devices"===z.presentedMode||"view"===E||"devices"===E),H=z?.stageColor||C,L=z?.sceneBrightness??1;return j` +
`;const a=this._spaceModel();if(!a)return G;const l="valid"===s.kind?[a]:r,c=a.vb;let h=this._effectiveProjection();this._renderProjection=h,this._labs.active.length&&function(){const e=zf,t=e.alpha?e.active.join(","):"";if(!t||t===Of)return;Of=t;const i=new Map(Tf.map(e=>[e.id,e])),n=e.active.map(e=>`${e} (#${i.get(e).issue})`).join(", ");console.info(`HOUSEPLAN ALPHA: hp_alpha=1; ${n}`)}();let d="iso"===h;const u=d?this._isoSceneRuntime:null,p="devices"===this._mode&&this._showAll,_=this._renderDevices.filter(e=>e.space===a.id&&(!e.hidden||p)),m=this._renderDeviceSnapshot,g=this._spaceDisplayForRender(),f=this._resolvedRoomFills(a,g),v=this._resolvedGlowBase(a,g,f),y=g.showLqi??this._config.show_signal??!0,b=this._config.icon_size??2.5,w=b>8?2.5:b,k=k_(w);let x=d?this._renderIsoScene:null,S=this._viewOr(this._baseVb(h,x)),$=null;try{$=u?.resolveIsoFramePresentation({projection:h,display:g,scene:x,openings:this._openingsR,amountOf:e=>this._openingAmt(e),cellCm:this._cellCm,overlays:e=>this._isoOverlayScene(a,_,S,g,e,x,w,k,y)})??null}catch(e){this._latchIsoFallback(g.showBorders?x?.key||this._isoInvalidKey():`${a.id}|no-borders`,e),this._cancelCameraTransition(!1),h="flat",d=!1,x=null,$=null,this._renderProjection="flat",this._renderIsoScene=null,this._isoProjectionSnapshot="flat",this._view=null,this._viewModeSnap=null,S=this._viewOr(this._baseVb("flat",null))}const M=$?.layers??null,R=$?.overlays??null,C=this._editing?"":this._stageBg(g),T=this._opMeasureView,D="view"===this._mode?this._editorChromeMode:this._mode,A=this._roomHoverPaths(a),P=a.bg?this._display(a.bg.href):"",F=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,z=this._modeTransitionVisual,I=this._dayCycleState(),O=z?.viewWeight??("view"===this._mode?1:0),E=this._modeTransition.state?.from.presentedMode,N=!this._markup||!!z&&("view"===z.presentedMode||"devices"===z.presentedMode||"view"===E||"devices"===E),H=z?.stageColor||C,L=z?.sceneBrightness??1;return j` this._markupClick(e)} @wheel=${e=>this._onWheel(e)} @pointerdown=${e=>{this._notePointer(e),this._stagePointerDown(e)}} @@ -683,7 +683,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointerleave=${e=>this._stagePointerLeave(e)} @pointerup=${e=>this._stagePointerUp(e)} @pointercancel=${e=>this._stagePointerCancel(e)}> - ${kr(I,O)} + ${xr(I,O)} ${this._editorRuntime?this._renderEditorSecondary():G}
+ transform=${d?hf():G}> ${""} ${this._wallHatchDefs(g.color)}${W`${this._paperShapes(a.rooms).map(e=>"path"in e?W``:"poly"in e?W``:W``)}`} ${this._editing?this._renderMarkupDefs(c):G} @@ -792,20 +792,20 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${$?.raised??G} `:G)} ${""} -
+
${function(e,t,i){const n=[...e];if(!n.length)return G;const r=[],o=[],s=[];for(const e of n){for(const t of e.zones){if(!(!0===t.state||"number"==typeof t.state&&t.state>0)||!t.polygon)continue;const e=t.polygon.map(e=>i([1e3*e[0],1e3*e[1]]));s.push(W``${e[0]},${e[1]}`).join(" ")}>`)}for(const t of e.ranges)if(t.segments)for(const e of t.segments){const t=e.map(e=>i([1e3*e[0],1e3*e[1]]));o.push(W``${e[0]},${e[1]}`).join(" ")}>`)}for(const n of e.targets){if(!n.included)continue;const o=i([1e3*n.x,1e3*n.y]),s=(o[0]-t.x)/t.w*100,a=(o[1]-t.y)/t.h*100;r.push(j``)}}return o.length||s.length||r.length?j`${o.length||s.length?W``:G}${r}`:G}([...this._radarLive.frames.values()].filter(e=>{const t=this._serverCfg?.markers.find(t=>t.id===e.marker_id);return!!t&&Mg(t,this._space)}),S,e=>this._scenePoint(e))} + aria-hidden="true">${s}${o}`:G}${r}`:G}([...this._radarLive.frames.values()].filter(e=>{const t=this._serverCfg?.markers.find(t=>t.id===e.marker_id);return!!t&&Rg(t,this._space)}),S,e=>this._scenePoint(e))} ${Re(a.id,Te(_,e=>e.id,e=>this._renderDevice(e,S,y,R?.devices.get(e.id))))} ${this._renderVacuums(this._renderVacuumDevices,S,a.id)} ${this._renderVacFit(S)} ${this._renderOpeningLocks(S,R?.locks)} ${g.showNames||this._markup?a.rooms.map(e=>this._renderRoomLabel(e,a,S,g,R?.rooms.get(e))):G} ${this._markup?a.rooms.map(e=>this._renderRoomGear(e,a,S)):G} - ${B={hass:this.hass,settings:this._settings,devices:this._renderDevices,registry:this._haRegistry,currentSpace:a.id,spaces:this._serverCfg?.spaces,viewKey:S,view:"view"===this._mode,kiosk:this._kiosk},B.view&&!B.kiosk&&!0===B.hass?.user?.is_admin&&Pg(B.settings).enabled?(import("./hp-zigbee-topology-overlay-D3IWAxB8.js"),j``):G}
@@ -903,16 +903,16 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 `:G} ${this._toast?j``:G} - `;var B}_vacCandidateStatus(e,t,i=this._planHass){const n=this._bindingStatus("entity:"+e);if("ha_disabled"===n.kind)return"disabled";if("orphaned"===n.kind)return"missing";if("unverified"===n.kind)return"unverified";const r=i?.states?.[e];return"unavailable"===r?.state?"unavailable":t?.hasPosition?"ok":"unsupported"}_vacOpenAllCameras(e){const t=this._haRegistry.entities||{},i=[];for(const[e,n]of Object.entries(this.hass?.states||{})){if(!e.startsWith("camera."))continue;const r=Uc(e,n,t[e]);r&&i.push(r)}this._vacAllCameraCache={devId:e.id,candidates:i},this._vacAllCamerasFor=e.id}_vacSourceResolution(e,t=!1,i=this._planHass){const n=e.marker?.vacuum,r="string"==typeof n?.source&&!!n.source,o=new Set(e.entities||[]),s=new Set(o);r&&s.add(n.source);const a=i?.entities||{},l=[];for(const e of s){const t=i?.states?.[e],o=Uc(e,t,a[e]);o?l.push(o):r&&e===n.source&&l.push({entityId:e,name:String(t?.attributes?.friendly_name||e),platform:a[e]?.platform?String(a[e].platform):null,category:e.startsWith("camera.")?"camera":"partial",hasPosition:!1,hasRooms:!1,hasPath:!1,hasMapId:!1,score:0})}if(t&&this._vacAllCameraCache?.devId===e.id){const e=new Set(l.map(e=>e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,n){const r="string"==typeof e&&e.length>0,o=new Set(t),s=Array.from(i).sort((t,i)=>r&&t.entityId===e?-1:r&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(r){const t=s.find(t=>t.entityId===e);return{entityId:e,status:n[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:s}}const a=s.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===n[e.entityId]);return a?{entityId:a.entityId,status:"ok",pinned:!1,candidates:s}:{entityId:null,status:"none",pinned:!1,candidates:s}}(n?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=Id(this._planHass,this._devices,null,this._virtualLights)){const i=s_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:c_(this._planHass,e,i)}}_stampActivity(e,t,i){let n=this._activityRt.get(e);n||(n=eg(i||"",[]),this._activityRt.set(e,n)),null!=i&&(n.sources=i),ig(n,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=Id(this._planHass,this._devices,null,this._virtualLights);for(const n of this._devices){if(n.hidden)continue;if("icon_ripple"!==Li(n.marker?.display))continue;t.add(n.id);const r=this._activitySnapshot(n,i);e.set(n.id,r);const{samples:o,sourceKey:s}=r;let a=this._activityRt.get(n.id);a?a.sources!==s&&tg(a,s,o,window.clearTimeout.bind(window)):(a=eg(s,o),this._activityRt.set(n.id,a))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Li(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:n,sourceKey:r}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==r)continue;const s=ng(o,n,window.clearTimeout.bind(window));s&&this._stampActivity(t.id,s,r)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Li(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),n=Xc(this.hass.states[i||""]?.state),r=qc(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),n&&!o.moving&&(o.trail=[],o.lastPos=null);const s="never"!==ih(e.marker?.vacuum)&&!r?.path.length;!n&&o.moving&&(o.endedTs=Date.now(),s&&o.lastPos&&(o.trail=Yc(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=n;const a=r?.pos;if(n&&a){const e=a.x+":"+a.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,s&&o.lastPos&&(o.trail=Yc(o.trail,o.lastPos,40)),o.lastPos=[a.x,a.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const n={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(n),n}_renderVacSection(e){return this._editorRuntimeOrThrow()._renderVacSection(e)}_vacMapId(e,t,i=this._planHass){const n=this._vacEntity(e),r=n?i?.states?.[n]?.attributes?.selected_map:null;return o=t.mapId,s=r,"default"!==o?o:null!=s?String(s):"default";var o,s}_vacObservedMapId(e,t,i=this._planHass){const n=qc(i?.states?.[t]?.attributes);return n?this._vacMapId(e,n,i):void 0}_vacSaveMatrix(e,t,i,n,r=""){return this._editorRuntimeOrThrow()._vacSaveMatrix(e,t,i,n,r)}_vacPlanRoomAnchors(e){return this._editorRuntimeOrThrow()._vacPlanRoomAnchors(e)}_vacAutoCalibrate(e){return this._editorRuntimeOrThrow()._vacAutoCalibrate(e)}_vacApplyCalibrationProposal(e){return this._editorRuntimeOrThrow()._vacApplyCalibrationProposal(e)}_vacStartFit(e){return this._editorRuntimeOrThrow()._vacStartFit(e)}_vacFitSave(){return this._editorRuntimeOrThrow()._vacFitSave()}_vacFitTurn(e){return this._editorRuntimeOrThrow()._vacFitTurn(e)}_vacGhostCentre(e){return this._editorRuntimeOrThrow()._vacGhostCentre(e)}_vacDelta(e,t,i){return this._editorRuntimeOrThrow()._vacDelta(e,t,i)}_vacFitPointer(e,t){return this._editorRuntimeOrThrow()._vacFitPointer(e,t)}_renderVacFit(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderVacFit(e):G}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,n=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!n.length)return void(this._vacRaf=0);const r=t.getBoundingClientRect();for(const t of n){const n=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),s=i.x+(o.left+o.width/2-r.left)/r.width*i.w,a=i.y+(o.top+o.height/2-r.top)/r.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${n}"]`))t.setAttribute("x2",s.toFixed(1)),t.setAttribute("y2",a.toFixed(1))}this._vacRafLoop()})}_vacTrailPathD(e,t){const i=e.map(e=>e.map(([e,i])=>Ac(t,e,i))),n=function(e,t,i=console.warn){if(!Number.isFinite(t)||t<=0)return[];const n=[];let r=0;for(const i of e){if(!i.every(Lc)){r++;continue}const e=i.filter((e,t)=>0===t||!Bc(e,i[t-1]));if(e.length<2)continue;const o=[{kind:"move",point:e[0]}];if(2!==e.length){for(let i=1;i0&&i(`[houseplan] vacuum trail: ${r} segment(s) dropped — non-finite point (check map calibration)`),n}(i,this._cmToUnits(17.5)),r=e=>{const t=this._scenePoint(e);return`${t[0].toFixed(1)} ${t[1].toFixed(1)}`};return n.map(e=>e.map(e=>"move"===e.kind?`M ${r(e.point)}`:"line"===e.kind?`L ${r(e.point)}`:`Q ${r(e.control)} ${r(e.point)}`).join(" ")).join(" ")}_renderVacuums(e,t,i){if(this._markup||"decor"===this._mode)return G;const n=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,r=this._vacJumpOnce||n!==this._vacViewKey;this._vacViewKey=n,this._vacJumpOnce=!1;const o=[],s=[];for(const n of e){if(n.hidden||!this._isVacDev(n))continue;if("static_icon"===Li(n.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${n.id}`),a=e?.source??this._vacSource(n,this._renderPlanHass);if(!a)continue;const l=e?.telemetry??qc(this._renderPlanHass?.states[a]?.attributes);if(!l)continue;const c=e?.routes??sh(n.id,n.marker?.vacuum??null,n.space,a),h=e?.resolution??lh({routes:c,observed:ch(c,[a],e=>this._vacObservedMapId(n,e)),spaceIds:new Set(this._model.map(e=>e.id))}),d=e?.server??this._vacSrvTrails[n.id],u=dh({resolution:h,routes:c,renderSpace:i,rootSource:n.marker?.vacuum?.source??null,serverCurrent:d?.current??null,serverPrevious:d?.previous??null,explicitRoutes:Array.isArray(n.marker?.vacuum?.map_routes)});if(!u.live&&!u.previous)continue;const p=u.live,_=e?.runtime??this._vacRt.get(n.id),m=_?.moving??!1,g=ih(n.marker?.vacuum),f="always"===g||"cleaning"===g&&m,v=d,y=u.currentRunMatches&&Array.isArray(v?.current?.points)?v.current:null,b=u.previous&&Array.isArray(v?.previous?.points)?v.previous:null;if("always"===g&&b&&u.previous){const e=Ec(b.points),t=this._vacTrailPathD(e,u.previous);t&&s.push(W``)}if(f&&p){const e=Nc(l,y,_?.trail||[]),t=!m||"integration"!==e.source&&"server"!==e.source?e.path:Hc(e.path);if(t.length){const e=this._vacTrailPathD(t,p);e&&s.push(W``);const i=t[t.length-1];if(m&&i?.length>=2){const e=i[i.length-1],[t,r]=Ac(p,e[0],e[1]),o=this._scenePoint([t,r]),a=o[0].toFixed(1),l=o[1].toFixed(1);s.push(W``)}}}if(!m||!l.pos||!p)continue;const[w,k]=Ac(p,l.pos.x,l.pos.y),x=this._scenePoint([w,k]),S=(x[0]-t.x)/t.w*100,$=(x[1]-t.y)/t.h*100,M=_&&_.lastTs>0&&Date.now()-_.lastTs>6e4,R=n.marker?.icon||n.icon||"mdi:robot-vacuum";o.push(j`
e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,n){const r="string"==typeof e&&e.length>0,o=new Set(t),s=Array.from(i).sort((t,i)=>r&&t.entityId===e?-1:r&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(r){const t=s.find(t=>t.entityId===e);return{entityId:e,status:n[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:s}}const a=s.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===n[e.entityId]);return a?{entityId:a.entityId,status:"ok",pinned:!1,candidates:s}:{entityId:null,status:"none",pinned:!1,candidates:s}}(n?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=Od(this._planHass,this._devices,null,this._virtualLights)){const i=a_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:h_(this._planHass,e,i)}}_stampActivity(e,t,i){let n=this._activityRt.get(e);n||(n=tg(i||"",[]),this._activityRt.set(e,n)),null!=i&&(n.sources=i),ng(n,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=Od(this._planHass,this._devices,null,this._virtualLights);for(const n of this._devices){if(n.hidden)continue;if("icon_ripple"!==Li(n.marker?.display))continue;t.add(n.id);const r=this._activitySnapshot(n,i);e.set(n.id,r);const{samples:o,sourceKey:s}=r;let a=this._activityRt.get(n.id);a?a.sources!==s&&ig(a,s,o,window.clearTimeout.bind(window)):(a=tg(s,o),this._activityRt.set(n.id,a))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Li(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:n,sourceKey:r}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==r)continue;const s=rg(o,n,window.clearTimeout.bind(window));s&&this._stampActivity(t.id,s,r)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Li(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),n=Zc(this.hass.states[i||""]?.state),r=jc(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),n&&!o.moving&&(o.trail=[],o.lastPos=null);const s="never"!==nh(e.marker?.vacuum)&&!r?.path.length;!n&&o.moving&&(o.endedTs=Date.now(),s&&o.lastPos&&(o.trail=Xc(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=n;const a=r?.pos;if(n&&a){const e=a.x+":"+a.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,s&&o.lastPos&&(o.trail=Xc(o.trail,o.lastPos,40)),o.lastPos=[a.x,a.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const n={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(n),n}_renderVacSection(e){return this._editorRuntimeOrThrow()._renderVacSection(e)}_vacMapId(e,t,i=this._planHass){const n=this._vacEntity(e),r=n?i?.states?.[n]?.attributes?.selected_map:null;return o=t.mapId,s=r,"default"!==o?o:null!=s?String(s):"default";var o,s}_vacObservedMapId(e,t,i=this._planHass){const n=jc(i?.states?.[t]?.attributes);return n?this._vacMapId(e,n,i):void 0}_vacSaveMatrix(e,t,i,n,r=""){return this._editorRuntimeOrThrow()._vacSaveMatrix(e,t,i,n,r)}_vacPlanRoomAnchors(e){return this._editorRuntimeOrThrow()._vacPlanRoomAnchors(e)}_vacAutoCalibrate(e){return this._editorRuntimeOrThrow()._vacAutoCalibrate(e)}_vacApplyCalibrationProposal(e){return this._editorRuntimeOrThrow()._vacApplyCalibrationProposal(e)}_vacStartFit(e){return this._editorRuntimeOrThrow()._vacStartFit(e)}_vacFitSave(){return this._editorRuntimeOrThrow()._vacFitSave()}_vacFitTurn(e){return this._editorRuntimeOrThrow()._vacFitTurn(e)}_vacGhostCentre(e){return this._editorRuntimeOrThrow()._vacGhostCentre(e)}_vacDelta(e,t,i){return this._editorRuntimeOrThrow()._vacDelta(e,t,i)}_vacFitPointer(e,t){return this._editorRuntimeOrThrow()._vacFitPointer(e,t)}_renderVacFit(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderVacFit(e):G}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,n=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!n.length)return void(this._vacRaf=0);const r=t.getBoundingClientRect();for(const t of n){const n=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),s=i.x+(o.left+o.width/2-r.left)/r.width*i.w,a=i.y+(o.top+o.height/2-r.top)/r.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${n}"]`))t.setAttribute("x2",s.toFixed(1)),t.setAttribute("y2",a.toFixed(1))}this._vacRafLoop()})}_vacTrailPathD(e,t){const i=e.map(e=>e.map(([e,i])=>Pc(t,e,i))),n=function(e,t,i=console.warn){if(!Number.isFinite(t)||t<=0)return[];const n=[];let r=0;for(const i of e){if(!i.every(Bc)){r++;continue}const e=i.filter((e,t)=>0===t||!qc(e,i[t-1]));if(e.length<2)continue;const o=[{kind:"move",point:e[0]}];if(2!==e.length){for(let i=1;i0&&i(`[houseplan] vacuum trail: ${r} segment(s) dropped — non-finite point (check map calibration)`),n}(i,this._cmToUnits(17.5)),r=e=>{const t=this._scenePoint(e);return`${t[0].toFixed(1)} ${t[1].toFixed(1)}`};return n.map(e=>e.map(e=>"move"===e.kind?`M ${r(e.point)}`:"line"===e.kind?`L ${r(e.point)}`:`Q ${r(e.control)} ${r(e.point)}`).join(" ")).join(" ")}_renderVacuums(e,t,i){if(this._markup||"decor"===this._mode)return G;const n=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,r=this._vacJumpOnce||n!==this._vacViewKey;this._vacViewKey=n,this._vacJumpOnce=!1;const o=[],s=[];for(const n of e){if(n.hidden||!this._isVacDev(n))continue;if("static_icon"===Li(n.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${n.id}`),a=e?.source??this._vacSource(n,this._renderPlanHass);if(!a)continue;const l=e?.telemetry??jc(this._renderPlanHass?.states[a]?.attributes);if(!l)continue;const c=e?.routes??ah(n.id,n.marker?.vacuum??null,n.space,a),h=e?.resolution??ch({routes:c,observed:hh(c,[a],e=>this._vacObservedMapId(n,e)),spaceIds:new Set(this._model.map(e=>e.id))}),d=e?.server??this._vacSrvTrails[n.id],u=uh({resolution:h,routes:c,renderSpace:i,rootSource:n.marker?.vacuum?.source??null,serverCurrent:d?.current??null,serverPrevious:d?.previous??null,explicitRoutes:Array.isArray(n.marker?.vacuum?.map_routes)});if(!u.live&&!u.previous)continue;const p=u.live,_=e?.runtime??this._vacRt.get(n.id),m=_?.moving??!1,g=nh(n.marker?.vacuum),f="always"===g||"cleaning"===g&&m,v=d,y=u.currentRunMatches&&Array.isArray(v?.current?.points)?v.current:null,b=u.previous&&Array.isArray(v?.previous?.points)?v.previous:null;if("always"===g&&b&&u.previous){const e=Nc(b.points),t=this._vacTrailPathD(e,u.previous);t&&s.push(W``)}if(f&&p){const e=Hc(l,y,_?.trail||[]),t=!m||"integration"!==e.source&&"server"!==e.source?e.path:Lc(e.path);if(t.length){const e=this._vacTrailPathD(t,p);e&&s.push(W``);const i=t[t.length-1];if(m&&i?.length>=2){const e=i[i.length-1],[t,r]=Pc(p,e[0],e[1]),o=this._scenePoint([t,r]),a=o[0].toFixed(1),l=o[1].toFixed(1);s.push(W``)}}}if(!m||!l.pos||!p)continue;const[w,k]=Pc(p,l.pos.x,l.pos.y),x=this._scenePoint([w,k]),S=(x[0]-t.x)/t.w*100,$=(x[1]-t.y)/t.h*100,M=_&&_.lastTs>0&&Date.now()-_.lastTs>6e4,R=n.marker?.icon||n.icon||"mdi:robot-vacuum";o.push(j`
{e.stopPropagation();const t=this._vacEntity(n);t&&this._openMoreInfo(t)}}>
`)}return this._vacLastView=t,o.length&&!this._vacRaf&&this._vacRafLoop(),o.length||s.length?j` ${s.length?W`${s}`:G} - ${o}`:G}_renderDevice(e,t,i=!0,n){const r=this._pos(e),o=n?.visualScene??this._scenePoint([r.x,r.y]),s=(o[0]-t.x)/t.w*100,a=(o[1]-t.y)/t.h*100,l=this._devicePresentation(e,i),c=[`left:${s}%`,`top:${a}%`,...v_(l)],h=l.disabledReason,d=l.haDisabled?this._t(`marker.ha_disabled_${h}`):e.userHidden?this._t("marker.hidden_ghost"):e.name,u=e_(l),p="view"===this._mode||"devices"===this._mode,_=Qp([d,l.haDisabled?"":this._t(`marker.state_a11y_${u}`),"none"!==l.pulse.kind?this._t(`marker.pulse_a11y_${l.pulse.reason}`):"",l.valueFullText||l.valueText||"",Pp(l.valueBadge),null!=l.lqiText&&l.lqiBand?this._t(`marker.lqi_a11y_${l.lqiBand}`,{value:l.lqiText}):""]);return j`
this._clickDevice(t,e)} @keydown=${t=>this._keyDevice(t,e)} @@ -945,10 +945,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointercancel=${t=>this._pointerCancel(t,e)} @lostpointercapture=${t=>this._pointerCancel(t,e)} > - ${b_(l,{newDevice:this._newIds.has(e.id),newDeviceTitle:this._t("device.new"),disabledTitle:l.haDisabled?d:""})} + ${w_(l,{newDevice:this._newIds.has(e.id),newDeviceTitle:this._t("device.new"),disabledTitle:l.haDisabled?d:""})} ${this._vacRouteBadge(e)}
`}_vacRouteBadge(e){if(!this._isVacDev(e)||e.hidden)return G;if("static_icon"===Li(e.marker?.display))return G;const t=this._renderDeviceSnapshot?.facts.get(`vacuum:${e.id}`),i=function(e,t){if(!t||!e)return null;switch(e.kind){case"unmapped":case"needs_calibration":case"ambiguous":case"missing_space":return e.kind;default:return null}}(t?.resolution,this._vacRt.get(e.id)?.moving??!1);if(!i)return G;const n=this._t(`vac.route_warn_${i}`);return j` - `}_roomArea(e){const t=ni(e);if(!t)return null;const i=this._spaceModel();if(!i)return null;const n=this._spaceWalls.length&&e.id&&this._innerRoomContour(i,e.id)||t,r=this._cleanFloor(e,n),o=this._cellCm/this._gridPitch;return Xn(r.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source,i=ru(this._spaceModel()?.id,e);return t?iu(this._renderPlanHass,t,"temp",this._markers):i?this._climate().get(i)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source,i=ru(this._spaceModel()?.id,e);return t?iu(this._renderPlanHass,t,"hum",this._markers):i?this._climate().get(i)?.hum??null:null}_climate(){const e=this._serverCfg?.markers,t=this._renderPlanHass,i=this._climateCache,n=this._settings.exclude_integrations;if(i&&i.h===t&&i.r===this._iconRules&&i.mk===e&&i.ex===n)return i.m;const r=au(t,this._iconRules,e,this._excluded);return this._climateCache={h:t,r:this._iconRules,mk:e,ex:n,m:r},r}_resetRoomDialogFields(){return this._editorRuntimeOrThrow()._resetRoomDialogFields()}_openRoomEdit(e){return this._editorRuntimeOrThrow()._openRoomEdit(e)}_roomSettingsFromDialog(){return this._editorRuntimeOrThrow()._roomSettingsFromDialog()}_saveRoomEdit(){return this._editorRuntimeOrThrow()._saveRoomEdit()}_roomSrcCandidates(){return this._editorRuntimeOrThrow()._roomSrcCandidates()}_roomSrcLabel(e){return this._editorRuntimeOrThrow()._roomSrcLabel(e)}_labelPos(e,t){const i=this._layout["rl_"+(e.id||"")];if(i&&i.s===t)return{x:i.x*uv,y:i.y*uv};const n=this._roomCenter(e),r=this._gridPitch;return{x:nl(Qt(n[0],r)),y:nl(Qt(n[1],r))}}_labelDown(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelDown(e,t,i)}_labelMove(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelMove(e,t,i)}_labelUp(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelUp(e)}_labelScale(e){const t=this._layout["rl_"+(e.id||"")]?.k;return"number"==typeof t&&Number.isFinite(t)?Math.min(3,Math.max(.5,t)):1}_rlResizeDown(e,t,i){return this._editorRuntimeOrThrow()._rlResizeDown(e,t,i)}_rlResizeMove(e){return this._editorRuntimeOrThrow()._rlResizeMove(e)}_rlResizeUp(){return this._editorRuntimeOrThrow()._rlResizeUp()}_renderRoomGear(e,t,i){return this._editorRuntimeOrThrow()._renderRoomGear(e,t,i)}_renderRoomLabel(e,t,i,n,r){if(!e.name&&!this._markup)return G;const o=this._labelPos(e,t.id),s=r?.visualScene??this._scenePoint([o.x,o.y]),a=(s[0]-i.x)/i.w*100,l=(s[1]-i.y)/i.h*100,c=Math.min(1,n.opacity+.25),h=this._labelScale(e),d=[];if(n.labelTemp||n.labelHum||n.labelLqi&&e.area||n.labelLight){if(n.labelTemp){const t=this._roomTemp(e);null!=t&&d.push(j`${t}°`)}if(n.labelHum){const t=this._roomHum(e);null!=t&&d.push(j`${t}%`)}if(n.labelLqi&&e.area){const t=this._roomLqi(e.area);null!=t&&d.push(j`${t}`)}if(n.labelLight){const t=(u=Id(this._renderPlanHass,this._renderDevices,e,this._virtualLights)).length?{on:u.filter(e=>e.on).length,total:u.length}:null;if(t){const e=0===t.on?this._t("roomcard.light_off"):t.on===t.total?this._t("roomcard.light_on"):this._t("roomcard.light_partial",{on:t.on,total:t.total});d.push(j`${e}`)}}}var u;const p=!!e.area,_=!this._markup;return j`
`}_roomArea(e){const t=ni(e);if(!t)return null;const i=this._spaceModel();if(!i)return null;const n=this._spaceWalls.length&&e.id&&this._innerRoomContour(i,e.id)||t,r=this._cleanFloor(e,n),o=this._cellCm/this._gridPitch;return Xn(r.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source,i=ou(this._spaceModel()?.id,e);return t?nu(this._renderPlanHass,t,"temp",this._markers):i?this._climate().get(i)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source,i=ou(this._spaceModel()?.id,e);return t?nu(this._renderPlanHass,t,"hum",this._markers):i?this._climate().get(i)?.hum??null:null}_climate(){const e=this._serverCfg?.markers,t=this._renderPlanHass,i=this._climateCache,n=this._settings.exclude_integrations;if(i&&i.h===t&&i.r===this._iconRules&&i.mk===e&&i.ex===n)return i.m;const r=lu(t,this._iconRules,e,this._excluded);return this._climateCache={h:t,r:this._iconRules,mk:e,ex:n,m:r},r}_resetRoomDialogFields(){return this._editorRuntimeOrThrow()._resetRoomDialogFields()}_openRoomEdit(e){return this._editorRuntimeOrThrow()._openRoomEdit(e)}_roomSettingsFromDialog(){return this._editorRuntimeOrThrow()._roomSettingsFromDialog()}_saveRoomEdit(){return this._editorRuntimeOrThrow()._saveRoomEdit()}_roomSrcCandidates(){return this._editorRuntimeOrThrow()._roomSrcCandidates()}_roomSrcLabel(e){return this._editorRuntimeOrThrow()._roomSrcLabel(e)}_labelPos(e,t){const i=this._layout["rl_"+(e.id||"")];if(i&&i.s===t)return{x:i.x*pv,y:i.y*pv};const n=this._roomCenter(e),r=this._gridPitch;return{x:rl(Qt(n[0],r)),y:rl(Qt(n[1],r))}}_labelDown(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelDown(e,t,i)}_labelMove(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelMove(e,t,i)}_labelUp(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelUp(e)}_labelScale(e){const t=this._layout["rl_"+(e.id||"")]?.k;return"number"==typeof t&&Number.isFinite(t)?Math.min(3,Math.max(.5,t)):1}_rlResizeDown(e,t,i){return this._editorRuntimeOrThrow()._rlResizeDown(e,t,i)}_rlResizeMove(e){return this._editorRuntimeOrThrow()._rlResizeMove(e)}_rlResizeUp(){return this._editorRuntimeOrThrow()._rlResizeUp()}_renderRoomGear(e,t,i){return this._editorRuntimeOrThrow()._renderRoomGear(e,t,i)}_renderRoomLabel(e,t,i,n,r){if(!e.name&&!this._markup)return G;const o=this._labelPos(e,t.id),s=r?.visualScene??this._scenePoint([o.x,o.y]),a=(s[0]-i.x)/i.w*100,l=(s[1]-i.y)/i.h*100,c=Math.min(1,n.opacity+.25),h=this._labelScale(e),d=[];if(n.labelTemp||n.labelHum||n.labelLqi&&e.area||n.labelLight){if(n.labelTemp){const t=this._roomTemp(e);null!=t&&d.push(j`${t}°`)}if(n.labelHum){const t=this._roomHum(e);null!=t&&d.push(j`${t}%`)}if(n.labelLqi&&e.area){const t=this._roomLqi(e.area);null!=t&&d.push(j`${t}`)}if(n.labelLight){const t=(u=Od(this._renderPlanHass,this._renderDevices,e,this._virtualLights)).length?{on:u.filter(e=>e.on).length,total:u.length}:null;if(t){const e=0===t.on?this._t("roomcard.light_off"):t.on===t.total?this._t("roomcard.light_on"):this._t("roomcard.light_partial",{on:t.on,total:t.total});d.push(j`${e}`)}}}var u;const p=!!e.area,_=!this._markup;return j`
${r.text}
`:G} `}get _measureAnchor(){return this._markup&&this._cursorPt?"draw"===this._tool&&this._path.length&&!this._contourClosed?this._path[this._path.length-1]:"split"===this._tool&&this._splitSel?.pts?.length?this._splitSel.pts[this._splitSel.pts.length-1]:null:null}_renderMeasureLabel(e){const t=this._measureAnchor,i=this._cursorPt,n=(i[0]-e.x)/e.w*100,r=(i[1]-e.y)/e.h*100,o=jn(t,i),s=Math.round(10*o)/10,a=function(e,t,i=.001){if(e.length<2||t.length<2)return!1;const n=Math.abs(t[0]-e[0]),r=Math.abs(t[1]-e[1]);if(!Number.isFinite(n)||!Number.isFinite(r)||Math.hypot(n,r)<=i)return!1;const o=Math.max(n,r,1);return n<=i*o||r<=i*o||Math.abs(n-r)<=i*o}(t,i,2e-4*this._gridPitch);return j`
- ${this._fmtLen(t,i)} · ${s}°
`}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[n,r]=e.b;if(Math.abs(t-n)<1e-6&&Math.abs(i-r)<1e-6)return null;const o=(t+n)/2,s=(i+r)/2;if("line"===e.kind){const t=jn(e.a,e.b);return{x:o,y:s,on45:Wn(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const a=this._fmtLen([t,i],[n,i]),l=this._fmtLen([n,i],[n,r]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(n-t)/2,0]),a=this._fmtLen([0,0],[0,Math.abs(r-i)/2]);return{x:o,y:s,on45:!1,text:Math.abs(Math.abs(n-t)-Math.abs(r-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${a}`}}return{x:o,y:s,on45:!1,text:`${a} × ${l} · ${Xn(Tr(Math.abs(n-t),this._cellCm,this._gridPitch)*Tr(Math.abs(r-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._deviceDrag?.moved){const e=this._devices.find(e=>e.id===this._deviceDrag.id);return e?(()=>{const t=this._livePos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=uv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){return this._editorRuntimeOrThrow()._alignCandidates()}_renderAlignGuides(){return this._editorRuntime?._renderAlignGuides()??G}_renderOpeningCenterTick(e){return this._editorRuntimeOrThrow()._renderOpeningCenterTick(e)}_renderOpeningDimensionGuides(e){return this._editorRuntimeOrThrow()._renderOpeningDimensionGuides(e)}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]:null;return ci(e.type,t?.state,!!e.invert,t?.attributes?.current_position)}_planEntityAvailable(e){return!!e&&(!Xd(this._fullRegistryHass,e,Yd(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!Xd(this._renderPlanHass,e,Yd(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=td(e)){return!!t&&"active"===cd(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){return this._editorRuntimeOrThrow()._renderOpeningPlacementPreview()}_renderOpenings(e,t){const i=t?this._openingsR.filter(e=>t.includes(e.id)):this._openingsR;if(!i.length)return W``;const n=this._spaceModel();if(!n)return W``;const r=e.color,o=this._spaceWalls,s=this._openCuts(),a=this._openingWallIndexFor(n,s).value;return W`${Re(n.id,Te(i,e=>e.id,e=>{if(e.orphanReason)return W``}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[n,r]=e.b;if(Math.abs(t-n)<1e-6&&Math.abs(i-r)<1e-6)return null;const o=(t+n)/2,s=(i+r)/2;if("line"===e.kind){const t=jn(e.a,e.b);return{x:o,y:s,on45:Wn(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const a=this._fmtLen([t,i],[n,i]),l=this._fmtLen([n,i],[n,r]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(n-t)/2,0]),a=this._fmtLen([0,0],[0,Math.abs(r-i)/2]);return{x:o,y:s,on45:!1,text:Math.abs(Math.abs(n-t)-Math.abs(r-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${a}`}}return{x:o,y:s,on45:!1,text:`${a} × ${l} · ${Xn(Dr(Math.abs(n-t),this._cellCm,this._gridPitch)*Dr(Math.abs(r-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._deviceDrag?.moved){const e=this._devices.find(e=>e.id===this._deviceDrag.id);return e?(()=>{const t=this._livePos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=pv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){return this._editorRuntimeOrThrow()._alignCandidates()}_renderAlignGuides(){return this._editorRuntime?._renderAlignGuides()??G}_renderOpeningCenterTick(e){return this._editorRuntimeOrThrow()._renderOpeningCenterTick(e)}_renderOpeningDimensionGuides(e){return this._editorRuntimeOrThrow()._renderOpeningDimensionGuides(e)}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]:null;return ci(e.type,t?.state,!!e.invert,t?.attributes?.current_position)}_planEntityAvailable(e){return!!e&&(!Zd(this._fullRegistryHass,e,Xd(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!Zd(this._renderPlanHass,e,Xd(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=id(e)){return!!t&&"active"===hd(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){return this._editorRuntimeOrThrow()._renderOpeningPlacementPreview()}_renderOpenings(e,t){const i=t?this._openingsR.filter(e=>t.includes(e.id)):this._openingsR;if(!i.length)return W``;const n=this._spaceModel();if(!n)return W``;const r=e.color,o=this._spaceWalls,s=this._openCuts(),a=this._openingWallIndexFor(n,s).value;return W`${Re(n.id,Te(i,e=>e.id,e=>{if(e.orphanReason)return W`{t.stopPropagation(),this._editOpening(e)}}> - + ! - `;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":r,n="gate"===e.type?!e.flip_v:e.flip_v,s=e.partitionHost||o.length||"gate"===e.type?this._openingFace(e,a,!!n):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:r,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:s},{half:c,outlineHalf:h,hitHalf:d}=$p(l),u=Ha(10,this._cellCm),p=Ha(12,this._cellCm);return W``;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":r,n="gate"===e.type?!e.flip_v:e.flip_v,s=e.partitionHost||o.length||"gate"===e.type?this._openingFace(e,a,!!n):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:r,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:s},{half:c,outlineHalf:h,hitHalf:d}=Mp(l),u=La(10,this._cellCm),p=La(12,this._cellCm);return W` - ${Dp(l)} + ${Ap(l)} + rx="${La(6,this._cellCm)}"> this._opClick(t,e)} @@ -1011,7 +1011,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointermove=${t=>this._opPointerMove(t,e)} @pointerup=${t=>this._opPointerUp(t,e)} @pointercancel=${t=>this._opPointerUp(t,e)}> - `}))}`}_renderOpeningLocks(e,t){const i=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!i.length)return j``;const n=this._spaceModel();if(!n)return j``;const r=this._openCuts(),o=this._openingWallIndexFor(n,r).value;return j`${i.map(i=>{const n=this._renderPlanHass.states[i.lock]?.state,r="locked"===n,s=r||["unlocked","open","opening","unlocking","locking"].includes(String(n)),a="gate"===i.type?this._openingFace(i,o,!i.flip_v):null,l=Sp({x:i.rx,y:i.ry,angle:i.angle,flipV:!!i.flip_v,gateFace:a},this._cellCm)[0],c=t?.get(String(i.id)),h=c?.visualScene??this._scenePoint(l),d=(h[0]-e.x)/e.w*100,u=(h[1]-e.y)/e.h*100;return j`
`}))}`}_renderOpeningLocks(e,t){const i=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!i.length)return j``;const n=this._spaceModel();if(!n)return j``;const r=this._openCuts(),o=this._openingWallIndexFor(n,r).value;return j`${i.map(i=>{const n=this._renderPlanHass.states[i.lock]?.state,r="locked"===n,s=r||["unlocked","open","opening","unlocking","locking"].includes(String(n)),a="gate"===i.type?this._openingFace(i,o,!i.flip_v):null,l=$p({x:i.rx,y:i.ry,angle:i.angle,flipV:!!i.flip_v,gateFace:a},this._cellCm)[0],c=t?.get(String(i.id)),h=c?.visualScene??this._scenePoint(l),d=(h[0]-e.x)/e.w*100,u=(h[1]-e.y)/e.h*100;return j`
this._openingInfo=null}>${this._t("btn.close")}
- `}_renderOpeningDialog(){return this._editorRuntimeOrThrow()._renderOpeningDialog()}_gridLevels(){return this._editorRuntimeOrThrow()._gridLevels()}_renderMarkupDefs(e){return this._editorRuntimeOrThrow()._renderMarkupDefs(e)}_renderPhysicalEditorLayer(){return this._editorRuntimeOrThrow()._renderPhysicalEditorLayer()}_renderHiddenWallDiagnosticOverlay(){return this._editorRuntimeOrThrow()._renderHiddenWallDiagnosticOverlay()}_renderPlanSnapOverlay(){return this._editorRuntimeOrThrow()._renderPlanSnapOverlay()}_syncPlanSnapActiveMarker(e){return this._editorRuntimeOrThrow()._syncPlanSnapActiveMarker(e)}_syncPlanSnapConflictMarkers(e){return this._editorRuntimeOrThrow()._syncPlanSnapConflictMarkers(e)}_planSnapPhysicalSegment(e){return this._editorRuntimeOrThrow()._planSnapPhysicalSegment(e)}_drawPreviewJoinPatchD(e,t){return this._editorRuntimeOrThrow()._drawPreviewJoinPatchD(e,t)}_renderMarkupLayer(e){return this._editorRuntimeOrThrow()._renderMarkupLayer(e)}_renderActiveChainInk(){return this._editorRuntimeOrThrow()._renderActiveChainInk()}_renderPartitionDeleteDialog(){return this._editorRuntimeOrThrow()._renderPartitionDeleteDialog()}_renderRoomDeleteDialog(){return this._editorRuntimeOrThrow()._renderRoomDeleteDialog()}_renderPhysicalDialog(){return this._editorRuntimeOrThrow()._renderPhysicalDialog()}_renderMarkupBar(){return this._editorRuntimeOrThrow()._renderMarkupBar()}_renderDevicesBar(){return this._editorRuntimeOrThrow()._renderDevicesBar()}_renderDeviceInbox(){return this._editorRuntimeOrThrow()._renderDeviceInbox()}_cardEntities(e){const t=this._planHass,i=[],n=new Set,r=e=>{if(!e||n.has(e)||!t.states[e])return;const r=t.entities[e];if("config"===r?.entity_category||"diagnostic"===r?.entity_category)return;n.add(e);const o=e.split(".")[0];["light","switch","fan","humidifier","siren","input_boolean"].includes(o)?i.push({eid:e,kind:"toggle"}):["cover","valve","lock","climate","media_player","vacuum","water_heater"].includes(o)?i.push({eid:e,kind:"open"}):["sensor","binary_sensor","number","select"].includes(o)&&i.push({eid:e,kind:"value"})};for(const i of Id(t,this._devices,null,this._virtualLights))if(i.device.id===e.id)for(const e of[...i.serviceEids,...i.stateEids])r(e);e.primary&&r(e.primary);for(const t of e.entities)r(t);return i.slice(0,12)}_cardToggle(e){const t=e.split(".")[0];"lock"!==t&&"alarm_control_panel"!==t&&this._planEntityAvailable(e)&&this.hass.callService("homeassistant","toggle",{entity_id:e}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))}_renderInfoCard(){const e=this._infoCard,t=e.primary?this.hass.states[e.primary]:void 0,i=t?Xi(this.hass,e.primary)?.text??t.state:null,n=$g(e.marker?.radar)?e.marker.radar:null,r=n?this._radarLive.frames.get(e.marker?.id||e.id):null,o=n?function(e,t){return!0!==e.enabled?"radar.health_disabled":Rg[t||""]||"radar.health_unknown"}(n,r?.health):null,s=(e.controls??e.marker?.controls??[]).filter(Dn).filter(e=>this._planEntityAvailable(e));return j``}_renderOpeningDialog(){return this._editorRuntimeOrThrow()._renderOpeningDialog()}_gridLevels(){return this._editorRuntimeOrThrow()._gridLevels()}_renderMarkupDefs(e){return this._editorRuntimeOrThrow()._renderMarkupDefs(e)}_renderPhysicalEditorLayer(){return this._editorRuntimeOrThrow()._renderPhysicalEditorLayer()}_renderHiddenWallDiagnosticOverlay(){return this._editorRuntimeOrThrow()._renderHiddenWallDiagnosticOverlay()}_renderPlanSnapOverlay(){return this._editorRuntimeOrThrow()._renderPlanSnapOverlay()}_syncPlanSnapActiveMarker(e){return this._editorRuntimeOrThrow()._syncPlanSnapActiveMarker(e)}_syncPlanSnapConflictMarkers(e){return this._editorRuntimeOrThrow()._syncPlanSnapConflictMarkers(e)}_planSnapPhysicalSegment(e){return this._editorRuntimeOrThrow()._planSnapPhysicalSegment(e)}_drawPreviewJoinPatchD(e,t){return this._editorRuntimeOrThrow()._drawPreviewJoinPatchD(e,t)}_renderMarkupLayer(e){return this._editorRuntimeOrThrow()._renderMarkupLayer(e)}_renderActiveChainInk(){return this._editorRuntimeOrThrow()._renderActiveChainInk()}_renderPartitionDeleteDialog(){return this._editorRuntimeOrThrow()._renderPartitionDeleteDialog()}_renderRoomDeleteDialog(){return this._editorRuntimeOrThrow()._renderRoomDeleteDialog()}_renderPhysicalDialog(){return this._editorRuntimeOrThrow()._renderPhysicalDialog()}_renderMarkupBar(){return this._editorRuntimeOrThrow()._renderMarkupBar()}_renderDevicesBar(){return this._editorRuntimeOrThrow()._renderDevicesBar()}_renderDeviceInbox(){return this._editorRuntimeOrThrow()._renderDeviceInbox()}_cardEntities(e){const t=this._planHass,i=[],n=new Set,r=e=>{if(!e||n.has(e)||!t.states[e])return;const r=t.entities[e];if("config"===r?.entity_category||"diagnostic"===r?.entity_category)return;n.add(e);const o=e.split(".")[0];["light","switch","fan","humidifier","siren","input_boolean"].includes(o)?i.push({eid:e,kind:"toggle"}):["cover","valve","lock","climate","media_player","vacuum","water_heater"].includes(o)?i.push({eid:e,kind:"open"}):["sensor","binary_sensor","number","select"].includes(o)&&i.push({eid:e,kind:"value"})};for(const i of Od(t,this._devices,null,this._virtualLights))if(i.device.id===e.id)for(const e of[...i.serviceEids,...i.stateEids])r(e);e.primary&&r(e.primary);for(const t of e.entities)r(t);return i.slice(0,12)}_cardToggle(e){const t=e.split(".")[0];"lock"!==t&&"alarm_control_panel"!==t&&this._planEntityAvailable(e)&&this.hass.callService("homeassistant","toggle",{entity_id:e}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))}_renderInfoCard(){const e=this._infoCard,t=e.primary?this.hass.states[e.primary]:void 0,i=t?Xi(this.hass,e.primary)?.text??t.state:null,n=Mg(e.marker?.radar)?e.marker.radar:null,r=n?this._radarLive.frames.get(e.marker?.id||e.id):null,o=n?function(e,t){return!0!==e.enabled?"radar.health_disabled":Cg[t||""]||"radar.health_unknown"}(n,r?.health):null,s=(e.controls??e.marker?.controls??[]).filter(Dn).filter(e=>this._planEntityAvailable(e));return j`
@@ -1086,7 +1086,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
-
`}_markerValueBadgeFields(e){return this._editorRuntimeOrThrow()._markerValueBadgeFields(e)}_markerDraft(e){return this._editorRuntimeOrThrow()._markerDraft(e)}_markerPreviewDevice(e){return this._editorRuntimeOrThrow()._markerPreviewDevice(e)}_markerPreviewDevices(e){return this._editorRuntimeOrThrow()._markerPreviewDevices(e)}_toggleIntent(e,t=this._devices){return Au({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){return this._editorRuntimeOrThrow()._toggleIntentForDialog(e)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const n={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return n?this._t(n):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!Fu(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,n=i?e.targets.filter(e=>"on"===e.state).length:0,r=i?0===n?t.groupAllOff():t.groupCurrent(n,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(r),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){return this._editorRuntimeOrThrow()._toggleHintLines(e)}_effectiveStoredTapAction(e,t){return this._editorRuntimeOrThrow()._effectiveStoredTapAction(e,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._editorRuntimeOrThrow()._effectiveMarkerTapAction(e,t)}_announceToggleDraft(e){return this._editorRuntimeOrThrow()._announceToggleDraft(e)}_valueBadgeForBinding(e,t){return this._editorRuntimeOrThrow()._valueBadgeForBinding(e,t)}_markerSpatialSource(e){return this._editorRuntimeOrThrow()._markerSpatialSource(e)}_markerAutoHasSpatialSource(e){return this._editorRuntimeOrThrow()._markerAutoHasSpatialSource(e)}_setMarkerLightRole(e){return this._editorRuntimeOrThrow()._setMarkerLightRole(e)}_controlRefInfo(e){return this._editorRuntimeOrThrow()._controlRefInfo(e)}_valueBadgeCandidateLabel(e){return this._editorRuntimeOrThrow()._valueBadgeCandidateLabel(e)}_controlCandidates(e){return this._editorRuntimeOrThrow()._controlCandidates(e)}_addControlRef(e,t){return this._editorRuntimeOrThrow()._addControlRef(e,t)}_setMarkerGlowMode(e){return this._editorRuntimeOrThrow()._setMarkerGlowMode(e)}_renderMarkerDialog(){return this._editorRuntimeOrThrow()._renderMarkerDialog()}_renderSpaceDialog(){return this._onboardingRuntime&&this._spaceDialog&&this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)?this._onboardingRuntime._renderSpaceDialog():this._editorRuntimeOrThrow()._renderSpaceDialog()}_renderMergeDialog(){return this._editorRuntimeOrThrow()._renderMergeDialog()}_renderCardPreview(e,t,i){const n=18*e;return j`
+ `}_markerValueBadgeFields(e){return this._editorRuntimeOrThrow()._markerValueBadgeFields(e)}_markerDraft(e){return this._editorRuntimeOrThrow()._markerDraft(e)}_markerPreviewDevice(e){return this._editorRuntimeOrThrow()._markerPreviewDevice(e)}_markerPreviewDevices(e){return this._editorRuntimeOrThrow()._markerPreviewDevices(e)}_toggleIntent(e,t=this._devices){return Pu({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){return this._editorRuntimeOrThrow()._toggleIntentForDialog(e)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const n={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return n?this._t(n):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!zu(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,n=i?e.targets.filter(e=>"on"===e.state).length:0,r=i?0===n?t.groupAllOff():t.groupCurrent(n,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(r),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){return this._editorRuntimeOrThrow()._toggleHintLines(e)}_effectiveStoredTapAction(e,t){return this._editorRuntimeOrThrow()._effectiveStoredTapAction(e,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._editorRuntimeOrThrow()._effectiveMarkerTapAction(e,t)}_announceToggleDraft(e){return this._editorRuntimeOrThrow()._announceToggleDraft(e)}_valueBadgeForBinding(e,t){return this._editorRuntimeOrThrow()._valueBadgeForBinding(e,t)}_markerSpatialSource(e){return this._editorRuntimeOrThrow()._markerSpatialSource(e)}_markerAutoHasSpatialSource(e){return this._editorRuntimeOrThrow()._markerAutoHasSpatialSource(e)}_setMarkerLightRole(e){return this._editorRuntimeOrThrow()._setMarkerLightRole(e)}_controlRefInfo(e){return this._editorRuntimeOrThrow()._controlRefInfo(e)}_valueBadgeCandidateLabel(e){return this._editorRuntimeOrThrow()._valueBadgeCandidateLabel(e)}_controlCandidates(e){return this._editorRuntimeOrThrow()._controlCandidates(e)}_addControlRef(e,t){return this._editorRuntimeOrThrow()._addControlRef(e,t)}_setMarkerGlowMode(e){return this._editorRuntimeOrThrow()._setMarkerGlowMode(e)}_renderMarkerDialog(){return this._editorRuntimeOrThrow()._renderMarkerDialog()}_renderSpaceDialog(){return this._onboardingRuntime&&this._spaceDialog&&this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)?this._onboardingRuntime._renderSpaceDialog():this._editorRuntimeOrThrow()._renderSpaceDialog()}_renderMergeDialog(){return this._editorRuntimeOrThrow()._renderMergeDialog()}_renderCardPreview(e,t,i){const n=18*e;return j`
${this._t("preview.room_name")} @@ -1094,4 +1094,4 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 45% · ${this._t("roomcard.light_partial",{on:1,total:3})} -
`}_renderRoomSource(e){return this._editorRuntimeOrThrow()._renderRoomSource(e)}_renderRoomDialog(){return this._editorRuntimeOrThrow()._renderRoomDialog()}}yv.properties={_tabDrag:{state:!0},_hdrH:{state:!0},_booting:{state:!0},_bootFading:{state:!0},_bootSoft:{state:!0},_continuityEpoch:{state:!0},_editorRuntimeLoadingVisible:{state:!0},_backdropGuard:{state:!0},_tapConfirm:{state:!0},_dangerConfirm:{state:!0},hass:{attribute:!1},panelHost:{type:Boolean,attribute:"panel-host",reflect:!0},narrow:{attribute:!1},_config:{state:!0},_space:{state:!0},_devices:{state:!0},_selId:{state:!0},_toast:{state:!0},_mode:{state:!0},_tool:{state:!0},_wallDialog:{state:!0},_drawWallField:{state:!0},_activeWallChainId:{state:!0},_physicalSel:{state:!0},_physicalDialog:{state:!0},_partitionDeleteDialog:{state:!0},_roomDeleteDialog:{state:!0},_physicalDrag:{state:!0},_physicalRotate:{state:!0},_duplicateColumnId:{state:!0},_opMeasure:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_mergeSel:{state:!0},_openingPreset:{state:!0},_openingDialog:{state:!0},_openingInfo:{state:!0},_mergeDialog:{state:!0},_splitSel:{state:!0},_decorTool:{state:!0},_decorStyle:{state:!0},_decorDraft:{state:!0},_decorSel:{state:!0},_decorEraseConfirm:{state:!0},_decorTextDialog:{state:!0},_decorShapeDialog:{state:!0},_backdropDialog:{state:!0},_furnPalette:{state:!0},_decorImagePalette:{state:!0},_decorAssetCatalog:{state:!0},_decorAssetBusy:{state:!0},_furnCategory:{state:!0},_furnPreviewInput:{state:!0},_bdDrag:{state:!0},_dtBox:{state:!0},_dtDrag:{state:!0},_kioskDialog:{state:!0},_vacFit:{state:!0},_vacAllCamerasFor:{state:!0},_vacCalConfirm:{state:!0},_kioskDots:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_roomEditId:{state:!0},_roomFill:{state:!0},_roomCustomFill:{state:!0},_roomTempMin:{state:!0},_roomTempMax:{state:!0},_roomTempSrc:{state:!0},_roomHumSrc:{state:!0},_roomSrcOpen:{state:!0},_roomSrcFilter:{state:!0},_roomNameScale:{state:!0},_roomLabelScale:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_deviceInbox:{state:!0},_rulesDialog:{state:!0},_settingsDialog:{state:!0},_pdfDialog:{state:!0},_supportDialog:{state:!0},_alignDialog:{state:!0},_preflightClipboardFallback:{state:!0},_backupExportDialog:{state:!0},_backupImportDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0}},yv.ZOOM_MAX=8,yv.ZOOM_MIN=1/3,yv.styles=[op,pg],customElements.get("houseplan-card")||customElements.define("houseplan-card",yv),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-card"===e.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info(`%c HOUSEPLAN-CARD %c v${ev} `,"background:#3ea6ff;color:#04121f;font-weight:700","");export{Wl as $,G as A,Pp as B,b_ as C,le as D,U as E,Ag as F,wi as G,Lr as H,$i as I,Mi as J,Ut as K,Ci as L,el as M,ja as N,wo as O,ni as P,Oo as Q,M_ as R,R_ as S,ys as T,io as U,Go as V,_i as W,Wo as X,L_ as Y,El as Z,rl as _,sh as a,fr as a$,Bl as a0,Cs as a1,ds as a2,Rs as a3,Zs as a4,Is as a5,Mc as a6,$c as a7,si as a8,Ja as a9,Yd as aA,Xd as aB,$g as aC,ti as aD,oi as aE,Pn as aF,Un as aG,dm as aH,Cr as aI,cm as aJ,Pl as aK,Hl as aL,Ql as aM,Xa as aN,ec as aO,Vl as aP,gs as aQ,ea as aR,es as aS,ua as aT,Oa as aU,N_ as aV,_a as aW,Ds as aX,Pg as aY,_n as aZ,vr as a_,Xu as aa,rp as ab,Ts as ac,ko as ad,ip as ae,Ku as af,Zo as ag,As as ah,Zu as ai,na as aj,sa as ak,fo as al,yo as am,Jr as an,O_ as ao,Ko as ap,Qa as aq,Uo as ar,Ua as as,Ga as at,en as au,tn as av,Ki as aw,Yi as ax,Ya as ay,ac as az,eh as b,li as b$,gr as b0,pn as b1,Oe as b2,kp as b3,sf as b4,Do as b5,nl as b6,Qt as b7,ei as b8,Br as b9,Nr as bA,Er as bB,Tr as bC,$r as bD,Rr as bE,Pr as bF,jn as bG,Sr as bH,Mr as bI,Xl as bJ,Ir as bK,Zl as bL,Ul as bM,Ll as bN,Jl as bO,Kl as bP,Yl as bQ,rm as bR,Jo as bS,$p as bT,tp as bU,Vf as bV,ep as bW,la as bX,qf as bY,Kf as bZ,C_ as b_,ma as ba,bc as bb,E_ as bc,bo as bd,Eu as be,q_ as bf,yi as bg,mi as bh,Fi as bi,za as bj,wa as bk,ba as bl,Yo as bm,Xo as bn,Qs as bo,kl as bp,Aa as bq,Da as br,Yn as bs,Xn as bt,ki as bu,ms as bv,_s as bw,j_ as bx,W_ as by,zr as bz,j as c,Sl as c$,Ju as c0,np as c1,Di as c2,fi as c3,ai as c4,vi as c5,Qo as c6,zi as c7,Mn as c8,Wp as c9,B_ as cA,Ar as cB,mn as cC,Fg as cD,so as cE,yr as cF,Ee as cG,qe as cH,Ne as cI,qc as cJ,Vc as cK,ih as cL,Ic as cM,Kc as cN,jc as cO,Wc as cP,th as cQ,Jc as cR,Ac as cS,Cc as cT,Bn as cU,Tc as cV,qn as cW,ci as cX,jf as cY,Dp as cZ,Bf as c_,Up as ca,wd as cb,Ru as cc,Li as cd,Ui as ce,Kn as cf,Ln as cg,Gd as ch,J_ as ci,vo as cj,Kd as ck,Ud as cl,un as cm,cn,ln as co,Ba as cp,F_ as cq,an as cr,sn as cs,on as ct,rn as cu,La as cv,kc as cw,wc as cx,Jf as cy,K_ as cz,ta as d,Rl as d$,Ps as d0,ss as d1,as as d2,Ie as d3,su as d4,Gp as d5,Vp as d6,tu as d7,Ou as d8,Od as d9,eu as dA,Za as dB,Al as dC,Dc as dD,Qg as dE,ef as dF,xp as dG,nf as dH,wl as dI,tf as dJ,rf as dK,$a as dL,Vs as dM,Sp as dN,Ri as dO,f_ as dP,xf as dQ,Sf as dR,hf as dS,y_ as dT,Na as dU,Hr as dV,Pa as dW,aa as dX,Dr as dY,Fr as dZ,Fa as d_,Id as da,Ad as db,xd as dc,Dn as dd,bd as de,Vd as df,Rn as dg,d_ as dh,zp as di,Pd as dj,Fd as dk,Sd as dl,ku as dm,Bi as dn,Hi as dp,Ip as dq,Ni as dr,xc as ds,qa as dt,Sc as du,qi as dv,ji as dw,xo as dx,pi as dy,Jd as dz,pe as e,U_ as e0,Ia as e1,lm as e2,yp as e3,cp as e4,_p as e5,hp as e6,Jt as e7,bg as e8,G_ as e9,Xi as ea,Zi as eb,Wt as ec,yv as ed,Qc as f,Mo as g,Co as h,_e as i,Ro as j,Ha as k,bp as l,Ao as m,rh as n,ch as o,o as p,he as q,lh as r,nn as s,Kt as t,op as u,wp as v,W as w,Yp as x,g_ as y,v_ as z}; +
`}_renderRoomSource(e){return this._editorRuntimeOrThrow()._renderRoomSource(e)}_renderRoomDialog(){return this._editorRuntimeOrThrow()._renderRoomDialog()}}bv.properties={_tabDrag:{state:!0},_hdrH:{state:!0},_booting:{state:!0},_bootFading:{state:!0},_bootSoft:{state:!0},_continuityEpoch:{state:!0},_editorRuntimeLoadingVisible:{state:!0},_backdropGuard:{state:!0},_tapConfirm:{state:!0},_dangerConfirm:{state:!0},hass:{attribute:!1},panelHost:{type:Boolean,attribute:"panel-host",reflect:!0},narrow:{attribute:!1},_config:{state:!0},_space:{state:!0},_devices:{state:!0},_selId:{state:!0},_toast:{state:!0},_mode:{state:!0},_tool:{state:!0},_wallDialog:{state:!0},_drawWallField:{state:!0},_activeWallChainId:{state:!0},_physicalSel:{state:!0},_physicalDialog:{state:!0},_partitionDeleteDialog:{state:!0},_roomDeleteDialog:{state:!0},_physicalDrag:{state:!0},_physicalRotate:{state:!0},_duplicateColumnId:{state:!0},_opMeasure:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_mergeSel:{state:!0},_openingPreset:{state:!0},_openingDialog:{state:!0},_openingInfo:{state:!0},_mergeDialog:{state:!0},_splitSel:{state:!0},_decorTool:{state:!0},_decorStyle:{state:!0},_decorDraft:{state:!0},_decorSel:{state:!0},_decorEraseConfirm:{state:!0},_decorTextDialog:{state:!0},_decorShapeDialog:{state:!0},_backdropDialog:{state:!0},_furnPalette:{state:!0},_decorImagePalette:{state:!0},_decorAssetCatalog:{state:!0},_decorAssetBusy:{state:!0},_furnCategory:{state:!0},_furnPreviewInput:{state:!0},_bdDrag:{state:!0},_dtBox:{state:!0},_dtDrag:{state:!0},_kioskDialog:{state:!0},_vacFit:{state:!0},_vacAllCamerasFor:{state:!0},_vacCalConfirm:{state:!0},_kioskDots:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_roomEditId:{state:!0},_roomFill:{state:!0},_roomCustomFill:{state:!0},_roomTempMin:{state:!0},_roomTempMax:{state:!0},_roomTempSrc:{state:!0},_roomHumSrc:{state:!0},_roomSrcOpen:{state:!0},_roomSrcFilter:{state:!0},_roomNameScale:{state:!0},_roomLabelScale:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_deviceInbox:{state:!0},_rulesDialog:{state:!0},_settingsDialog:{state:!0},_pdfDialog:{state:!0},_supportDialog:{state:!0},_alignDialog:{state:!0},_preflightClipboardFallback:{state:!0},_backupExportDialog:{state:!0},_backupImportDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0}},bv.ZOOM_MAX=8,bv.ZOOM_MIN=1/3,bv.styles=[sp,_g],customElements.get("houseplan-card")||customElements.define("houseplan-card",bv),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-card"===e.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info(`%c HOUSEPLAN-CARD %c v${tv} `,"background:#3ea6ff;color:#04121f;font-weight:700","");export{Ul as $,G as A,Fp as B,w_ as C,le as D,U as E,Pg as F,wi as G,Br as H,$i as I,Mi as J,Ut as K,Ci as L,tl as M,Wa as N,ko as O,ni as P,Eo as Q,R_ as R,C_ as S,bs as T,no as U,Vo as V,_i as W,Uo as X,B_ as Y,Nl as Z,ol as _,ah as a,yr as a$,ql as a0,Ts as a1,us as a2,Cs as a3,Js as a4,Os as a5,Rc as a6,Mc as a7,si as a8,Qa as a9,Xd as aA,Zd as aB,Mg as aC,ti as aD,oi as aE,Pn as aF,Un as aG,um as aH,Tr as aI,hm as aJ,Fl as aK,Ll as aL,ec as aM,Za as aN,tc as aO,Kl as aP,fs as aQ,ta as aR,ts as aS,pa as aT,Ea as aU,H_ as aV,ma as aW,As as aX,Fg as aY,_n as aZ,fr as a_,Zu as aa,op as ab,Ds as ac,xo as ad,np as ae,Yu as af,Jo as ag,Ps as ah,Ju as ai,ra as aj,aa as ak,vo as al,bo as am,Qr as an,E_ as ao,Yo as ap,el as aq,Go as ar,Ga as as,Va as at,en as au,tn as av,Ki as aw,Yi as ax,Xa as ay,lc as az,th as b,T_ as b$,vr as b0,gr as b1,pn as b2,Oe as b3,xp as b4,af as b5,Ao as b6,rl as b7,Qt as b8,ei as b9,Ir as bA,Hr as bB,Nr as bC,Dr as bD,Mr as bE,Cr as bF,Fr as bG,jn as bH,$r as bI,Rr as bJ,Zl as bK,Or as bL,Jl as bM,Gl as bN,Bl as bO,Ql as bP,Yl as bQ,Xl as bR,om as bS,Qo as bT,Mp as bU,ip as bV,Kf as bW,tp as bX,ca as bY,jf as bZ,Yf as b_,qr as ba,ga as bb,wc as bc,N_ as bd,wo as be,Nu as bf,j_ as bg,yi as bh,mi as bi,Fi as bj,Ia as bk,ka as bl,wa as bm,Xo as bn,Zo as bo,ea as bp,xl as bq,Pa as br,Aa as bs,Yn as bt,Xn as bu,ki as bv,gs as bw,ms as bx,W_ as by,U_ as bz,j as c,qf as c$,li as c0,Qu as c1,rp as c2,Di as c3,fi as c4,ai as c5,vi as c6,es as c7,zi as c8,Mn as c9,Y_ as cA,q_ as cB,Pr as cC,mn as cD,zg as cE,ao as cF,br as cG,Ee as cH,qe as cI,Ne as cJ,jc as cK,Kc as cL,nh as cM,Oc as cN,Yc as cO,Wc as cP,Uc as cQ,ih as cR,Qc as cS,Pc as cT,Tc as cU,Bn as cV,Dc as cW,qn as cX,ci as cY,Wf as cZ,Ap as c_,Up as ca,Gp as cb,kd as cc,Cu as cd,Li as ce,Ui as cf,Kn as cg,Ln as ch,Vd as ci,Q_ as cj,yo as ck,Yd as cl,Gd as cm,un as cn,cn as co,ln as cp,qa as cq,z_ as cr,an as cs,sn as ct,on as cu,rn as cv,Ba as cw,xc as cx,kc as cy,Qf as cz,ia as d,za as d$,$l as d0,Fs as d1,as as d2,ls as d3,Ie as d4,au as d5,Vp as d6,Kp as d7,iu as d8,Eu as d9,Qd as dA,tu as dB,Ja as dC,Pl as dD,Ac as dE,ef as dF,tf as dG,Sp as dH,rf as dI,kl as dJ,nf as dK,of as dL,Ma as dM,Ks as dN,$p as dO,Ri as dP,v_ as dQ,Sf as dR,$f as dS,df as dT,b_ as dU,Ha as dV,Lr as dW,Fa as dX,la as dY,Ar as dZ,zr as d_,Ed as da,Od as db,Pd as dc,Sd as dd,Dn as de,wd as df,Kd as dg,Rn as dh,u_ as di,Ip as dj,Fd as dk,zd as dl,$d as dm,xu as dn,Bi as dp,Hi as dq,Op as dr,Ni as ds,Sc as dt,ja as du,$c as dv,qi as dw,ji as dx,So as dy,pi as dz,pe as e,Cl as e0,G_ as e1,Oa as e2,cm as e3,bp as e4,hp as e5,mp as e6,dp as e7,Jt as e8,wg as e9,V_ as ea,Xi as eb,Zi as ec,Wt as ed,bv as ee,eh as f,Ro as g,To as h,_e as i,Co as j,La as k,wp as l,Po as m,oh as n,hh as o,o as p,he as q,ch as r,nn as s,Kt as t,sp as u,kp as v,W as w,Xp as x,f_ as y,y_ as z}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js similarity index 80% rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js index f695edc6..b9755ddf 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js +++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{e as t,i as e,E as s,s as i,a as o,n as a,f as n,b as r,l,o as h,r as c,A as d,c as p,D as u,w as _,N as m,d as g,g as f,h as b,j as v,k as y,m as $,p as w,q as k,t as x,u as S,v as M,x as C,y as P,z as D,B as I,C as T,F as z,G as R,H as A,I as F,J as N,K as E,L as H,M as O,O as L,P as B,Q as W,R as j,S as G,T as q,U,V as K,W as V,X as J,Y,Z as X,_ as Z,$ as Q,a0 as tt,a1 as et,a2 as st,a3 as it,a4 as ot,a5 as at,a6 as nt,a7 as rt,a8 as lt,a9 as ht,aa as ct,ab as dt,ac as pt,ad as ut,ae as _t,af as mt,ag as gt,ah as ft,ai as bt,aj as vt,ak as yt,al as $t,am as wt,an as kt,ao as xt,ap as St,aq as Mt,ar as Ct,as as Pt,at as Dt,au as It,av as Tt,aw as zt,ax as Rt,ay as At,az as Ft,aA as Nt,aB as Et,aC as Ht,aD as Ot,aE as Lt,aF as Bt,aG as Wt,aH as jt,aI as Gt,aJ as qt,aK as Ut,aL as Kt,aM as Vt,aN as Jt,aO as Yt,aP as Xt,aQ as Zt,aR as Qt,aS as te,aT as ee,aU as se,aV as ie,aW as oe,aX as ae,aY as ne,aZ as re,a_ as le,a$ as he,b0 as ce,b1 as de,b2 as pe,b3 as ue,b4 as _e,b5 as me,b6 as ge,b7 as fe,b8 as be,b9 as ve,ba as ye,bb as $e,bc as we,bd as ke,be as xe,bf as Se,bg as Me,bh as Ce,bi as Pe,bj as De,bk as Ie,bl as Te,bm as ze,bn as Re,bo as Ae,bp as Fe,bq as Ne,br as Ee,bs as He,bt as Oe,bu as Le,bv as Be,bw as We,bx as je,by as Ge,bz as qe,bA as Ue,bB as Ke,bC as Ve,bD as Je,bE as Ye,bF as Xe,bG as Ze,bH as Qe,bI as ts,bJ as es,bK as ss,bL as is,bM as os,bN as as,bO as ns,bP as rs,bQ as ls,bR as hs,bS as cs,bT as ds,bU as ps,bV as us,bW as _s,bX as ms,bY as gs,bZ as fs,b_ as bs,b$ as vs,c0 as ys,c1 as $s,c2 as ws,c3 as ks,c4 as xs,c5 as Ss,c6 as Ms,c7 as Cs,c8 as Ps,c9 as Ds,ca as Is,cb as Ts,cc as zs,cd as Rs,ce as As,cf as Fs,cg as Ns,ch as Es,ci as Hs,cj as Os,ck as Ls,cl as Bs,cm as Ws,cn as js,co as Gs,cp as qs,cq as Us,cr as Ks,cs as Vs,ct as Js,cu as Ys,cv as Xs,cw as Zs,cx as Qs,cy as ti,cz as ei,cA as si,cB as ii,cC as oi,cD as ai,cE as ni,cF as ri,cG as li,cH as hi,cI as ci,cJ as di,cK as pi,cL as ui,cM as _i,cN as mi,cO as gi,cP as fi,cQ as bi,cR as vi,cS as yi,cT as $i,cU as wi,cV as ki,cW as xi,cX as Si,cY as Mi,cZ as Ci,c_ as Pi,c$ as Di,d0 as Ii,d1 as Ti,d2 as zi,d3 as Ri,d4 as Ai,d5 as Fi,d6 as Ni,d7 as Ei,d8 as Hi,d9 as Oi,da as Li,db as Bi,dc as Wi,dd as ji,de as Gi,df as qi,dg as Ui,dh as Ki,di as Vi,dj as Ji,dk as Yi,dl as Xi,dm as Zi,dn as Qi,dp as to,dq as eo,dr as so,ds as io,dt as oo,du as ao,dv as no,dw as ro,dx as lo,dy as ho,dz as co,dA as po,dB as uo,dC as _o}from"./houseplan-card-BCGpvbDT.js";import{F as mo,f as go,p as fo,c as bo,e as vo,r as yo,a as $o,s as wo}from"./backdrop-pick-Caayxvt2.js";import{t as ko,h as xo,m as So,T as Mo}from"./zigbee-topology-DlU7AXvw.js";import{GENERATED_FURNITURE_ART as Co,FURNITURE_ART_FINGERPRINT as Po}from"./furniture-plan-art.generated-MsQg9zvn.js";const Do={},Io=t(class extends e{constructor(){super(...arguments),this.ot=Do}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return s}else if(this.ot===e)return s;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}});var To={"gs.hint":"Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.","gs.show_room_tooltip":"Show the room information window on hover","support.about_group":"About the card","support.guide_group":"Documentation","support.guide":"User guide","support.form_group":"Send a report or suggestion","support.contact":"Contact details (email/tg/WhatsApp), optional.","support.message":"Message","support.attach":"Attach anonymized information from your plan","support.attach_hint":"Includes only allowed plan geometry, settings and bounded runtime facts. Excludes names, Home Assistant IDs, live states, URLs, files, and your message/contact.","support.geometry_warning":"The package contains no names or Home Assistant IDs, but it does contain the exact geometry and dimensions of your home.","support.close_busy_title":"Stop the current operation?","support.close_busy_body":"House Plan is preparing or sending the report. Closing now stops waiting for the result.","support.building":"Preparing anonymized data…","support.preview_summary":"Package v{version} · {spaces} spaces · {size} KiB","support.prepared":"Snapshot prepared {n} min ago","support.show_data":"Show data","support.download":"Download JSON","support.refresh":"Refresh snapshot","support.privacy":"When you send, your message, optional contact and, if selected, exact geometry leave your Home Assistant through the House Plan project relay and are visible to maintainers. The project node keeps the report for up to 30 days. Network infrastructure sees your HA server address, but House Plan does not retain it raw; rate-limit and idempotency metadata is kept for up to 24 hours.","support.error_title":"The report was not sent","support.manual_recovery":"You can keep the message and attachment and continue manually:","support.copy_message":"Copy message","support.success":"Report sent: {id}. Save this number when contacting support.","support.copy_id":"Copy ID","support.sending":"Sending…","support.retry":"Retry","support.send":"Send","support.update_required":"Update the House Plan card and integration to compatible versions to send reports.","support.message_copied":"Message copied","support.id_copied":"Report ID copied","support.copy_failed":"Could not access the clipboard. Select and copy the text manually.","support.validation.message_required":"Enter a message.","support.validation.message_too_long":"The message must contain no more than 10,000 characters.","support.validation.contact_too_long":"Contact details must contain no more than 320 characters.","support.validation.preview_missing":"Wait for the attachment preview or turn the attachment off.","support.validation.preview_expired":"The attachment preview expired. Refresh the snapshot.","support.error.support_invalid_message":"Check the message and try again.","support.error.support_preview_expired":"The attachment preview expired or is no longer available. Refresh the snapshot.","support.error.support_package_too_large":"The anonymized package exceeds the 8 MiB limit.","support.error.support_rate_limited":"Too many reports or previews were requested. Try again later.","support.error.support_unavailable":"The private support service is temporarily unavailable. Your draft remains here.","support.error.support_rejected":"The report did not pass the support service validation.","support.error.unauthorized":"You do not have permission to send this report.","vac.routes_section":"Maps and floors","vac.routes_current_map":"Current map","vac.routes_no_map":"no telemetry","vac.routes_status":"Routing","vac.routes_state_ready":"map assigned and calibrated","vac.routes_state_needs_calibration":"map assigned, calibration needed","vac.routes_state_unmapped":"current map is not assigned to a floor","vac.routes_state_ambiguous":"two maps are indistinguishable — no floor is chosen","vac.routes_state_missing_space":"the map's space was deleted","vac.routes_state_none":"no map data","vac.routes_empty":"No map is assigned to a floor yet.","vac.route_map_default":"no map id","vac.route_active":"Active","vac.route_space":"Space","vac.route_space_none":"not selected","vac.route_status_ready":"ready","vac.route_status_needs_calibration":"needs calibration","vac.route_status_ambiguous":"ambiguous","vac.route_status_missing_space":"space deleted","vac.route_missing_space_group":"Deleted space","vac.route_add_current":"Add current map","vac.route_delete":"Remove map","vac.route_delete_title":"Remove the map from its floor?","vac.route_delete_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_delete_confirm":"Remove","vac.route_space_title":"Move the map to another space?","vac.route_space_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_space_confirm":"Move","vac.route_missing_space_hint":"One of the maps points at a deleted space: pick a new one or remove the map. Until then the robot is not drawn for that map.","vac.route_default_hint":"The source reports no stable map id. Several floors cannot be told apart without another source or the robot's own selected map.","vac.route_target_hint":"The dock stays in the “{space}” space regardless of the current map.","vac.route_add_source":"Add a map source","vac.route_add_source_hint":"For integrations that give each map its own camera. The “All cameras” section above widens this list.","vac.route_source_no_map":"no map reported"};const zo={en:To,ru:{"gs.hint":"Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.","gs.show_room_tooltip":"Показывать окно с информацией при наведении на комнату","support.about_group":"О карточке","support.guide_group":"Документация","support.guide":"Руководство пользователя","support.form_group":"Отправить репорт или предложение","support.contact":"Контакт для связи (email/tg/WhatsApp), необязательно.","support.message":"Сообщение","support.attach":"Прикрепить обезличенную информацию из вашего плана","support.attach_hint":"В пакет входят только разрешённые геометрия, настройки и ограниченные сведения о среде. Не входят имена, HA id, текущие состояния, URL, файлы, сообщение и контакт.","support.geometry_warning":"Пакет не содержит имён и HA id, но содержит точную геометрию и размеры дома.","support.close_busy_title":"Прервать текущую операцию?","support.close_busy_body":"House Plan подготавливает или отправляет репорт. При закрытии ожидание результата прекратится.","support.building":"Подготавливаем обезличенные данные…","support.preview_summary":"Пакет v{version} · пространств: {spaces} · {size} КиБ","support.prepared":"Снимок подготовлен {n} мин назад","support.show_data":"Показать данные","support.download":"Скачать JSON","support.refresh":"Обновить снимок","support.privacy":"При отправке сообщение, необязательный контакт и, если выбран пакет, точная геометрия покидают ваш Home Assistant через relay проекта House Plan и доступны мейнтейнерам. Узел проекта хранит репорт до 30 дней. Сетевая инфраструктура видит адрес сервера HA, но House Plan не сохраняет его в исходном виде; метаданные лимитов и идемпотентности хранятся до 24 часов.","support.error_title":"Репорт не отправлен","support.manual_recovery":"Сообщение и вложение можно сохранить и продолжить вручную:","support.copy_message":"Копировать сообщение","support.success":"Репорт отправлен: {id}. Сохраните номер для связи с поддержкой.","support.copy_id":"Копировать ID","support.sending":"Отправляем…","support.retry":"Повторить","support.send":"Отправить","support.update_required":"Обновите карточку и интеграцию House Plan до совместимых версий, чтобы отправлять репорты.","support.message_copied":"Сообщение скопировано","support.id_copied":"ID репорта скопирован","support.copy_failed":"Не удалось получить доступ к буферу обмена. Выделите и скопируйте текст вручную.","support.validation.message_required":"Введите сообщение.","support.validation.message_too_long":"Сообщение должно содержать не более 10 000 символов.","support.validation.contact_too_long":"Контакт должен содержать не более 320 символов.","support.validation.preview_missing":"Дождитесь предпросмотра вложения или отключите его.","support.validation.preview_expired":"Предпросмотр вложения истёк. Обновите снимок.","support.error.support_invalid_message":"Проверьте сообщение и повторите попытку.","support.error.support_preview_expired":"Предпросмотр вложения истёк или больше недоступен. Обновите снимок.","support.error.support_package_too_large":"Обезличенный пакет превышает лимит 8 МиБ.","support.error.support_rate_limited":"Запрошено слишком много репортов или предпросмотров. Повторите позже.","support.error.support_unavailable":"Закрытая служба поддержки временно недоступна. Черновик сохранён в этом окне.","support.error.support_rejected":"Репорт не прошёл проверку службы поддержки.","support.error.unauthorized":"У вас нет прав на отправку этого репорта.","vac.routes_section":"Карты и этажи","vac.routes_current_map":"Текущая карта","vac.routes_no_map":"источник молчит","vac.routes_status":"Маршрутизация","vac.routes_state_ready":"карта сопоставлена и откалибрована","vac.routes_state_needs_calibration":"карта сопоставлена, нужна калибровка","vac.routes_state_unmapped":"текущая карта не сопоставлена этажу","vac.routes_state_ambiguous":"две карты неразличимы — этаж не выбирается","vac.routes_state_missing_space":"пространство карты удалено","vac.routes_state_none":"нет данных о карте","vac.routes_empty":"Ни одна карта ещё не сопоставлена этажу.","vac.route_map_default":"без идентификатора","vac.route_active":"Текущая","vac.route_space":"Пространство","vac.route_space_none":"не выбрано","vac.route_status_ready":"готова","vac.route_status_needs_calibration":"нужна калибровка","vac.route_status_ambiguous":"неоднозначна","vac.route_status_missing_space":"пространство удалено","vac.route_missing_space_group":"Пространство удалено","vac.route_add_current":"Добавить текущую карту","vac.route_delete":"Удалить карту","vac.route_delete_title":"Удалить карту с этажа?","vac.route_delete_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_delete_confirm":"Удалить","vac.route_space_title":"Перенести карту в другое пространство?","vac.route_space_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_space_confirm":"Перенести","vac.route_missing_space_hint":"Одна из карт ссылается на удалённое пространство: выберите новое или удалите карту. Пока ссылка не исправлена, робот на этой карте не рисуется.","vac.route_default_hint":"Источник не сообщает стабильный идентификатор карты. Несколько этажей нельзя различить без другого источника или собственной карты робота.","vac.route_target_hint":"Док остаётся в пространстве «{space}» независимо от текущей карты.","vac.route_add_source":"Добавить источник карты","vac.route_add_source_hint":"Для интеграций, где у каждой карты своя камера. Список расширяется разделом «Все камеры» выше.","vac.route_source_no_map":"карта не читается"},de:{"gs.hint":"Füllfarben gelten für jeden Bereich; jede Farbe hat ihre eigene Deckkraft. Der Füllmodus wird in den Einstellungen des jeweiligen Bereichs festgelegt.","gs.show_room_tooltip":"Rauminformationen beim Darüberfahren anzeigen","support.about_group":"Über die Karte","support.guide_group":"Dokumentation","support.guide":"Benutzerhandbuch","support.form_group":"Bericht oder Vorschlag senden","support.contact":"Kontakt (E-Mail/tg/WhatsApp), optional.","support.message":"Nachricht","support.attach":"Anonymisierte Informationen aus dem Plan anhängen","support.attach_hint":"Enthält nur erlaubte Plangeometrie, Einstellungen und begrenzte Laufzeitdaten. Namen, Home-Assistant-IDs, Live-Zustände, URLs, Dateien, Nachricht und Kontakt werden ausgeschlossen.","support.geometry_warning":"Das Paket enthält keine Namen oder Home-Assistant-IDs, aber die exakte Geometrie und die Maße Ihres Hauses.","support.close_busy_title":"Aktuellen Vorgang abbrechen?","support.close_busy_body":"House Plan bereitet den Bericht vor oder sendet ihn. Beim Schließen wird nicht weiter auf das Ergebnis gewartet.","support.building":"Anonymisierte Daten werden vorbereitet…","support.preview_summary":"Paket v{version} · {spaces} Bereiche · {size} KiB","support.prepared":"Schnappschuss vor {n} Min. erstellt","support.show_data":"Daten anzeigen","support.download":"JSON herunterladen","support.refresh":"Schnappschuss aktualisieren","support.privacy":"Beim Senden verlassen Ihre Nachricht, der optionale Kontakt und, falls ausgewählt, die exakte Geometrie Ihren Home Assistant über das House-Plan-Projektrelay und sind für die Maintainer sichtbar. Der Projektserver speichert den Bericht bis zu 30 Tage. Die Netzwerkinfrastruktur sieht die Adresse Ihres HA-Servers, House Plan speichert sie jedoch nicht im Rohformat; Limit- und Idempotenzdaten bleiben bis zu 24 Stunden erhalten.","support.error_title":"Der Bericht wurde nicht gesendet","support.manual_recovery":"Nachricht und Anhang können gespeichert und manuell weitergegeben werden:","support.copy_message":"Nachricht kopieren","support.success":"Bericht gesendet: {id}. Bewahren Sie diese Nummer für den Support auf.","support.copy_id":"ID kopieren","support.sending":"Wird gesendet…","support.retry":"Erneut versuchen","support.send":"Senden","support.update_required":"Aktualisieren Sie House-Plan-Karte und Integration auf kompatible Versionen, um Berichte zu senden.","support.message_copied":"Nachricht kopiert","support.id_copied":"Berichts-ID kopiert","support.copy_failed":"Kein Zugriff auf die Zwischenablage. Markieren und kopieren Sie den Text manuell.","support.validation.message_required":"Geben Sie eine Nachricht ein.","support.validation.message_too_long":"Die Nachricht darf höchstens 10.000 Zeichen enthalten.","support.validation.contact_too_long":"Der Kontakt darf höchstens 320 Zeichen enthalten.","support.validation.preview_missing":"Warten Sie auf die Vorschau oder deaktivieren Sie den Anhang.","support.validation.preview_expired":"Die Anhangsvorschau ist abgelaufen. Aktualisieren Sie den Schnappschuss.","support.error.support_invalid_message":"Prüfen Sie die Nachricht und versuchen Sie es erneut.","support.error.support_preview_expired":"Die Anhangsvorschau ist abgelaufen oder nicht mehr verfügbar. Aktualisieren Sie den Schnappschuss.","support.error.support_package_too_large":"Das anonymisierte Paket überschreitet das Limit von 8 MiB.","support.error.support_rate_limited":"Zu viele Berichte oder Vorschauen wurden angefordert. Versuchen Sie es später erneut.","support.error.support_unavailable":"Der private Supportdienst ist vorübergehend nicht verfügbar. Der Entwurf bleibt in diesem Fenster erhalten.","support.error.support_rejected":"Der Bericht hat die Prüfung des Supportdienstes nicht bestanden.","support.error.unauthorized":"Sie dürfen diesen Bericht nicht senden.","vac.routes_section":"Karten und Etagen","vac.routes_current_map":"Aktuelle Karte","vac.routes_no_map":"keine Telemetrie","vac.routes_status":"Zuordnung","vac.routes_state_ready":"Karte zugeordnet und kalibriert","vac.routes_state_needs_calibration":"Karte zugeordnet, Kalibrierung nötig","vac.routes_state_unmapped":"aktuelle Karte keiner Etage zugeordnet","vac.routes_state_ambiguous":"zwei Karten nicht unterscheidbar — keine Etage gewählt","vac.routes_state_missing_space":"der Raum der Karte wurde gelöscht","vac.routes_state_none":"keine Kartendaten","vac.routes_empty":"Noch keine Karte einer Etage zugeordnet.","vac.route_map_default":"ohne Karten-ID","vac.route_active":"Aktiv","vac.route_space":"Raum","vac.route_space_none":"nicht gewählt","vac.route_status_ready":"bereit","vac.route_status_needs_calibration":"Kalibrierung nötig","vac.route_status_ambiguous":"mehrdeutig","vac.route_status_missing_space":"Raum gelöscht","vac.route_missing_space_group":"Gelöschter Bereich","vac.route_add_current":"Aktuelle Karte hinzufügen","vac.route_delete":"Karte entfernen","vac.route_delete_title":"Karte von der Etage entfernen?","vac.route_delete_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_delete_confirm":"Entfernen","vac.route_space_title":"Karte in einen anderen Raum verschieben?","vac.route_space_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_space_confirm":"Verschieben","vac.route_missing_space_hint":"Eine Karte verweist auf einen gelöschten Raum: neuen wählen oder Karte entfernen. Bis dahin wird der Roboter für diese Karte nicht gezeichnet.","vac.route_default_hint":"Die Quelle meldet keine stabile Karten-ID. Mehrere Etagen lassen sich ohne andere Quelle oder die vom Roboter gewählte Karte nicht unterscheiden.","vac.route_target_hint":"Die Station bleibt unabhängig von der aktuellen Karte im Raum „{space}“.","vac.route_add_source":"Kartenquelle hinzufügen","vac.route_add_source_hint":"Für Integrationen, die jeder Karte eine eigene Kamera geben. Der Abschnitt „Alle Kameras“ oben erweitert diese Liste.","vac.route_source_no_map":"keine Karte gemeldet"},fr:{"gs.hint":"Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.","gs.show_room_tooltip":"Afficher les informations de la pièce au survol","support.about_group":"À propos de la carte","support.guide_group":"Documentation d’aide","support.guide":"Guide utilisateur","support.form_group":"Envoyer un rapport ou une suggestion","support.contact":"Contact (e-mail/tg/WhatsApp), facultatif.","support.message":"Votre message","support.attach":"Joindre des informations anonymisées de votre plan","support.attach_hint":"Inclut uniquement la géométrie, les réglages autorisés et des données d’exécution limitées. Exclut les noms, identifiants Home Assistant, états en direct, URL, fichiers, message et contact.","support.geometry_warning":"Le paquet ne contient ni noms ni identifiants Home Assistant, mais il contient la géométrie et les dimensions exactes de votre logement.","support.close_busy_title":"Interrompre l’opération en cours ?","support.close_busy_body":"House Plan prépare ou envoie le rapport. Fermer maintenant arrête l’attente du résultat.","support.building":"Préparation des données anonymisées…","support.preview_summary":"Paquet v{version} · {spaces} espaces · {size} Kio","support.prepared":"Instantané préparé il y a {n} min","support.show_data":"Afficher les données","support.download":"Télécharger le JSON","support.refresh":"Actualiser l’instantané","support.privacy":"Lors de l’envoi, votre message, le contact facultatif et, si elle est sélectionnée, la géométrie exacte quittent votre Home Assistant via le relais du projet House Plan et sont visibles par les mainteneurs. Le serveur du projet conserve le rapport jusqu’à 30 jours. L’infrastructure réseau voit l’adresse de votre serveur HA, mais House Plan ne la conserve pas en clair ; les métadonnées de limitation et d’idempotence sont gardées jusqu’à 24 heures.","support.error_title":"Le rapport n’a pas été envoyé","support.manual_recovery":"Vous pouvez conserver le message et la pièce jointe puis continuer manuellement :","support.copy_message":"Copier le message","support.success":"Rapport envoyé : {id}. Conservez ce numéro pour contacter l’assistance.","support.copy_id":"Copier l’ID","support.sending":"Envoi…","support.retry":"Réessayer","support.send":"Envoyer","support.update_required":"Mettez à jour la carte et l’intégration House Plan vers des versions compatibles pour envoyer des rapports.","support.message_copied":"Message copié","support.id_copied":"ID du rapport copié","support.copy_failed":"Impossible d’accéder au presse-papiers. Sélectionnez et copiez le texte manuellement.","support.validation.message_required":"Saisissez un message.","support.validation.message_too_long":"Le message ne doit pas dépasser 10 000 caractères.","support.validation.contact_too_long":"Le contact ne doit pas dépasser 320 caractères.","support.validation.preview_missing":"Attendez l’aperçu de la pièce jointe ou désactivez-la.","support.validation.preview_expired":"L’aperçu de la pièce jointe a expiré. Actualisez l’instantané.","support.error.support_invalid_message":"Vérifiez le message et réessayez.","support.error.support_preview_expired":"L’aperçu de la pièce jointe a expiré ou n’est plus disponible. Actualisez l’instantané.","support.error.support_package_too_large":"Le paquet anonymisé dépasse la limite de 8 Mio.","support.error.support_rate_limited":"Trop de rapports ou d’aperçus ont été demandés. Réessayez plus tard.","support.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible. Le brouillon reste dans cette fenêtre.","support.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","support.error.unauthorized":"Vous n’êtes pas autorisé à envoyer ce rapport.","vac.routes_section":"Cartes et étages","vac.routes_current_map":"Carte actuelle","vac.routes_no_map":"aucune télémétrie","vac.routes_status":"Routage","vac.routes_state_ready":"carte assignée et calibrée","vac.routes_state_needs_calibration":"carte assignée, calibrage requis","vac.routes_state_unmapped":"carte actuelle non assignée à un étage","vac.routes_state_ambiguous":"deux cartes indiscernables — aucun étage choisi","vac.routes_state_missing_space":"l'espace de la carte a été supprimé","vac.routes_state_none":"aucune donnée de carte","vac.routes_empty":"Aucune carte n'est encore assignée à un étage.","vac.route_map_default":"sans identifiant","vac.route_active":"Active","vac.route_space":"Espace","vac.route_space_none":"non sélectionné","vac.route_status_ready":"prête","vac.route_status_needs_calibration":"calibrage requis","vac.route_status_ambiguous":"ambiguë","vac.route_status_missing_space":"espace supprimé","vac.route_missing_space_group":"Espace supprimé","vac.route_add_current":"Ajouter la carte actuelle","vac.route_delete":"Supprimer la carte","vac.route_delete_title":"Retirer la carte de son étage ?","vac.route_delete_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_delete_confirm":"Supprimer","vac.route_space_title":"Déplacer la carte vers un autre espace ?","vac.route_space_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_space_confirm":"Déplacer","vac.route_missing_space_hint":"Une carte pointe vers un espace supprimé : choisissez-en un autre ou supprimez la carte. D'ici là, le robot n'est pas dessiné pour cette carte.","vac.route_default_hint":"La source ne fournit pas d'identifiant de carte stable. Plusieurs étages ne peuvent pas être distingués sans une autre source ou la carte sélectionnée du robot.","vac.route_target_hint":"La station reste dans l'espace « {space} » quelle que soit la carte actuelle.","vac.route_add_source":"Ajouter une source de carte","vac.route_add_source_hint":"Pour les intégrations qui donnent à chaque carte sa propre caméra. La section « Toutes les caméras » ci-dessus élargit cette liste.","vac.route_source_no_map":"aucune carte signalée"}};function Ro(t,e,s){return i(zo[t]?.[e]??To[e]??e,s)}function Ao(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function Fo(t,e,s){return{...t,space:s.has(e)?e:""}}function No(t,e=Math.random){const s=new Set(t);for(let t=0;t<64;t+=1){const t="vr_"+Math.floor(16777215*e()).toString(36).padStart(5,"0");if(!s.has(t))return t}return"vr_"+Date.now().toString(36)}function Eo(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const Ho=new WeakMap,Oo=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function Lo(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>Ro(n,t,e),u=e.marker?.vacuum||{},_=Array.isArray(u.map_routes),m=i._vacSource(e)||"",g=o(e.id,u,e.space,m),f=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),b=new Set(f.map(t=>t.id)),v=h(g,[m],t=>i._vacObservedMapId(e,t)),y=c({routes:g,observed:v,spaceIds:b}),$="ready"===y.kind||"needs_calibration"===y.kind||"missing_space"===y.kind?y.route.id:"",w=m?v[m]:void 0,k=async s=>{let o=_?u.map_routes??null:null;if(!o&&(o=function(t,e,s,i){if(!s)return null;const o=t?.calibration;if(!o||"object"!=typeof o)return null;const n=new Set,r=[];for(const t of Object.keys(o)){const l=a(o[t]);if(!l)continue;const h=i(n);n.add(h),r.push({id:h,source:s,map_id:t,space:e,calibration:l})}return r.length?r:null}(u,e.space,m,t=>No(t))??[],!m&&Object.keys(u.calibration||{}).length))return!1;const n=s(o);return!!n&&(async s=>{const o=i._serverCfg;if(!o)return!1;const a=JSON.parse(JSON.stringify(o));a.markers=a.markers||[];let n=a.markers.find(t=>t.id===e.id);if(!n){if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return!1;n={id:e.id,binding:`${e.bindingKind}:${e.bindingRef}`,space:e.space||null,area:e.area||null,hidden:!!e.hidden},a.markers.push(n)}n.vacuum={...n.vacuum||{},map_routes:s},delete n.vacuum.calibration;const r=i._adoption.beginOptimistic(o,a);i._adoption.stageLocalConfig(a),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return i._rollbackOptimistic(r),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},x=s.candidates.filter(t=>t.entityId!==m&&!g.some(e=>e.source===t.entityId)),S=async(t,e)=>{if(!e||e===t.space)return;await i._confirmDanger({key:"vacuum_route_space",kind:"warning",title:r("vac.route_space_title"),message:r("vac.route_space_body"),objectName:t.map_id||r("vac.route_map_default"),confirmLabel:r("vac.route_space_confirm"),cancelLabel:i._t("btn.cancel")})&&await k(s=>function(t,e,s,i){return t.map(t=>t.id===e?{...t,id:i,space:s,calibration:null}:t)}(s,t.id,e,No(new Set(g.map(t=>t.id)))))},M=new Map(f.map((t,e)=>[t.id,e])),C=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),P=g.filter(t=>b.has(t.space)).sort((t,e)=>(M.get(t.space)??0)-(M.get(e.space)??0)||C(t,e)),D=g.filter(t=>!b.has(t.space)).sort(C),I=[...P,...D],T=!!m&&void 0!==w&&!g.some(t=>t.source===m&&t.map_id===w);let z=Ho.get(t);const R=z?.source||"",A=z?.mapId||"",F=!!z&&g.some(t=>t.source===R&&t.map_id===A);z&&(z.markerId!==e.id||i._vacObservedMapId(e,z.source)!==z.mapId||F&&!z.saving)&&(Ho.delete(t),z=void 0),z?.space&&!b.has(z.space)&&(z=Fo(z,"",b),Ho.set(t,z));const N=s=>p` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{e as t,i as e,E as s,s as i,a as o,n as a,f as n,b as r,l,o as h,r as c,A as d,c as p,D as u,w as _,N as m,d as g,g as f,h as b,j as v,k as y,m as $,p as w,q as k,t as x,u as S,v as M,x as C,y as P,z as D,B as I,C as T,F as R,G as z,H as A,I as F,J as N,K as E,L as H,M as O,O as L,P as B,Q as W,R as j,S as G,T as q,U,V as K,W as V,X as J,Y,Z as X,_ as Z,$ as Q,a0 as tt,a1 as et,a2 as st,a3 as it,a4 as ot,a5 as at,a6 as nt,a7 as rt,a8 as lt,a9 as ht,aa as ct,ab as dt,ac as pt,ad as ut,ae as _t,af as mt,ag as gt,ah as ft,ai as bt,aj as vt,ak as yt,al as $t,am as wt,an as kt,ao as xt,ap as St,aq as Mt,ar as Ct,as as Pt,at as Dt,au as It,av as Tt,aw as Rt,ax as zt,ay as At,az as Ft,aA as Nt,aB as Et,aC as Ht,aD as Ot,aE as Lt,aF as Bt,aG as Wt,aH as jt,aI as Gt,aJ as qt,aK as Ut,aL as Kt,aM as Vt,aN as Jt,aO as Yt,aP as Xt,aQ as Zt,aR as Qt,aS as te,aT as ee,aU as se,aV as ie,aW as oe,aX as ae,aY as ne,aZ as re,a_ as le,a$ as he,b0 as ce,b1 as de,b2 as pe,b3 as ue,b4 as _e,b5 as me,b6 as ge,b7 as fe,b8 as be,b9 as ve,ba as ye,bb as $e,bc as we,bd as ke,be as xe,bf as Se,bg as Me,bh as Ce,bi as Pe,bj as De,bk as Ie,bl as Te,bm as Re,bn as ze,bo as Ae,bp as Fe,bq as Ne,br as Ee,bs as He,bt as Oe,bu as Le,bv as Be,bw as We,bx as je,by as Ge,bz as qe,bA as Ue,bB as Ke,bC as Ve,bD as Je,bE as Ye,bF as Xe,bG as Ze,bH as Qe,bI as ts,bJ as es,bK as ss,bL as is,bM as os,bN as as,bO as ns,bP as rs,bQ as ls,bR as hs,bS as cs,bT as ds,bU as ps,bV as us,bW as _s,bX as ms,bY as gs,bZ as fs,b_ as bs,b$ as vs,c0 as ys,c1 as $s,c2 as ws,c3 as ks,c4 as xs,c5 as Ss,c6 as Ms,c7 as Cs,c8 as Ps,c9 as Ds,ca as Is,cb as Ts,cc as Rs,cd as zs,ce as As,cf as Fs,cg as Ns,ch as Es,ci as Hs,cj as Os,ck as Ls,cl as Bs,cm as Ws,cn as js,co as Gs,cp as qs,cq as Us,cr as Ks,cs as Vs,ct as Js,cu as Ys,cv as Xs,cw as Zs,cx as Qs,cy as ti,cz as ei,cA as si,cB as ii,cC as oi,cD as ai,cE as ni,cF as ri,cG as li,cH as hi,cI as ci,cJ as di,cK as pi,cL as ui,cM as _i,cN as mi,cO as gi,cP as fi,cQ as bi,cR as vi,cS as yi,cT as $i,cU as wi,cV as ki,cW as xi,cX as Si,cY as Mi,cZ as Ci,c_ as Pi,c$ as Di,d0 as Ii,d1 as Ti,d2 as Ri,d3 as zi,d4 as Ai,d5 as Fi,d6 as Ni,d7 as Ei,d8 as Hi,d9 as Oi,da as Li,db as Bi,dc as Wi,dd as ji,de as Gi,df as qi,dg as Ui,dh as Ki,di as Vi,dj as Ji,dk as Yi,dl as Xi,dm as Zi,dn as Qi,dp as to,dq as eo,dr as so,ds as io,dt as oo,du as ao,dv as no,dw as ro,dx as lo,dy as ho,dz as co,dA as po,dB as uo,dC as _o,dD as mo}from"./houseplan-card-Di_izZTU.js";import{F as go,f as fo,p as bo,c as vo,e as yo,r as $o,a as wo,s as ko}from"./backdrop-pick-CXmKHH6_.js";import{t as xo,h as So,m as Mo,T as Co}from"./zigbee-topology-Ba2URGlk.js";import{GENERATED_FURNITURE_ART as Po,FURNITURE_ART_FINGERPRINT as Do}from"./furniture-plan-art.generated-D_9nJ3h5.js";const Io={},To=t(class extends e{constructor(){super(...arguments),this.ot=Io}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return s}else if(this.ot===e)return s;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}});var Ro={"gs.hint":"Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.","gs.show_room_tooltip":"Show the room information window on hover","support.about_group":"About the card","support.guide_group":"Documentation","support.guide":"User guide","support.form_group":"Send a report or suggestion","support.contact":"Contact details (email/tg/WhatsApp), optional.","support.message":"Message","support.attach":"Attach anonymized information from your plan","support.attach_hint":"Includes only allowed plan geometry, settings and bounded runtime facts. Excludes names, Home Assistant IDs, live states, URLs, files, and your message/contact.","support.geometry_warning":"The package contains no names or Home Assistant IDs, but it does contain the exact geometry and dimensions of your home.","support.close_busy_title":"Stop the current operation?","support.close_busy_body":"House Plan is preparing or sending the report. Closing now stops waiting for the result.","support.building":"Preparing anonymized data…","support.preview_summary":"Package v{version} · {spaces} spaces · {size} KiB","support.prepared":"Snapshot prepared {n} min ago","support.show_data":"Show data","support.download":"Download JSON","support.refresh":"Refresh snapshot","support.privacy":"When you send, your message, optional contact and, if selected, exact geometry leave your Home Assistant through the House Plan project relay and are visible to maintainers. The project node keeps the report for up to 30 days. Network infrastructure sees your HA server address, but House Plan does not retain it raw; rate-limit and idempotency metadata is kept for up to 24 hours.","support.error_title":"The report was not sent","support.manual_recovery":"You can keep the message and attachment and continue manually:","support.copy_message":"Copy message","support.success":"Report sent: {id}. Save this number when contacting support.","support.copy_id":"Copy ID","support.sending":"Sending…","support.retry":"Retry","support.send":"Send","support.update_required":"Update the House Plan card and integration to compatible versions to send reports.","support.message_copied":"Message copied","support.id_copied":"Report ID copied","support.copy_failed":"Could not access the clipboard. Select and copy the text manually.","support.validation.message_required":"Enter a message.","support.validation.message_too_long":"The message must contain no more than 10,000 characters.","support.validation.contact_too_long":"Contact details must contain no more than 320 characters.","support.validation.preview_missing":"Wait for the attachment preview or turn the attachment off.","support.validation.preview_expired":"The attachment preview expired. Refresh the snapshot.","support.error.support_invalid_message":"Check the message and try again.","support.error.support_preview_expired":"The attachment preview expired or is no longer available. Refresh the snapshot.","support.error.support_package_too_large":"The anonymized package exceeds the 8 MiB limit.","support.error.support_rate_limited":"Too many reports or previews were requested. Try again later.","support.error.support_unavailable":"The private support service is temporarily unavailable. Your draft remains here.","support.error.support_rejected":"The report did not pass the support service validation.","support.error.unauthorized":"You do not have permission to send this report.","vac.routes_section":"Maps and floors","vac.routes_current_map":"Current map","vac.routes_no_map":"no telemetry","vac.routes_status":"Routing","vac.routes_state_ready":"map assigned and calibrated","vac.routes_state_needs_calibration":"map assigned, calibration needed","vac.routes_state_unmapped":"current map is not assigned to a floor","vac.routes_state_ambiguous":"two maps are indistinguishable — no floor is chosen","vac.routes_state_missing_space":"the map's space was deleted","vac.routes_state_none":"no map data","vac.routes_empty":"No map is assigned to a floor yet.","vac.route_map_default":"no map id","vac.route_active":"Active","vac.route_space":"Space","vac.route_space_none":"not selected","vac.route_status_ready":"ready","vac.route_status_needs_calibration":"needs calibration","vac.route_status_ambiguous":"ambiguous","vac.route_status_missing_space":"space deleted","vac.route_missing_space_group":"Deleted space","vac.route_add_current":"Add current map","vac.route_delete":"Remove map","vac.route_delete_title":"Remove the map from its floor?","vac.route_delete_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_delete_confirm":"Remove","vac.route_space_title":"Move the map to another space?","vac.route_space_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_space_confirm":"Move","vac.route_missing_space_hint":"One of the maps points at a deleted space: pick a new one or remove the map. Until then the robot is not drawn for that map.","vac.route_default_hint":"The source reports no stable map id. Several floors cannot be told apart without another source or the robot's own selected map.","vac.route_target_hint":"The dock stays in the “{space}” space regardless of the current map.","vac.route_add_source":"Add a map source","vac.route_add_source_hint":"For integrations that give each map its own camera. The “All cameras” section above widens this list.","vac.route_source_no_map":"no map reported"};const zo={en:Ro,ru:{"gs.hint":"Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.","gs.show_room_tooltip":"Показывать окно с информацией при наведении на комнату","support.about_group":"О карточке","support.guide_group":"Документация","support.guide":"Руководство пользователя","support.form_group":"Отправить репорт или предложение","support.contact":"Контакт для связи (email/tg/WhatsApp), необязательно.","support.message":"Сообщение","support.attach":"Прикрепить обезличенную информацию из вашего плана","support.attach_hint":"В пакет входят только разрешённые геометрия, настройки и ограниченные сведения о среде. Не входят имена, HA id, текущие состояния, URL, файлы, сообщение и контакт.","support.geometry_warning":"Пакет не содержит имён и HA id, но содержит точную геометрию и размеры дома.","support.close_busy_title":"Прервать текущую операцию?","support.close_busy_body":"House Plan подготавливает или отправляет репорт. При закрытии ожидание результата прекратится.","support.building":"Подготавливаем обезличенные данные…","support.preview_summary":"Пакет v{version} · пространств: {spaces} · {size} КиБ","support.prepared":"Снимок подготовлен {n} мин назад","support.show_data":"Показать данные","support.download":"Скачать JSON","support.refresh":"Обновить снимок","support.privacy":"При отправке сообщение, необязательный контакт и, если выбран пакет, точная геометрия покидают ваш Home Assistant через relay проекта House Plan и доступны мейнтейнерам. Узел проекта хранит репорт до 30 дней. Сетевая инфраструктура видит адрес сервера HA, но House Plan не сохраняет его в исходном виде; метаданные лимитов и идемпотентности хранятся до 24 часов.","support.error_title":"Репорт не отправлен","support.manual_recovery":"Сообщение и вложение можно сохранить и продолжить вручную:","support.copy_message":"Копировать сообщение","support.success":"Репорт отправлен: {id}. Сохраните номер для связи с поддержкой.","support.copy_id":"Копировать ID","support.sending":"Отправляем…","support.retry":"Повторить","support.send":"Отправить","support.update_required":"Обновите карточку и интеграцию House Plan до совместимых версий, чтобы отправлять репорты.","support.message_copied":"Сообщение скопировано","support.id_copied":"ID репорта скопирован","support.copy_failed":"Не удалось получить доступ к буферу обмена. Выделите и скопируйте текст вручную.","support.validation.message_required":"Введите сообщение.","support.validation.message_too_long":"Сообщение должно содержать не более 10 000 символов.","support.validation.contact_too_long":"Контакт должен содержать не более 320 символов.","support.validation.preview_missing":"Дождитесь предпросмотра вложения или отключите его.","support.validation.preview_expired":"Предпросмотр вложения истёк. Обновите снимок.","support.error.support_invalid_message":"Проверьте сообщение и повторите попытку.","support.error.support_preview_expired":"Предпросмотр вложения истёк или больше недоступен. Обновите снимок.","support.error.support_package_too_large":"Обезличенный пакет превышает лимит 8 МиБ.","support.error.support_rate_limited":"Запрошено слишком много репортов или предпросмотров. Повторите позже.","support.error.support_unavailable":"Закрытая служба поддержки временно недоступна. Черновик сохранён в этом окне.","support.error.support_rejected":"Репорт не прошёл проверку службы поддержки.","support.error.unauthorized":"У вас нет прав на отправку этого репорта.","vac.routes_section":"Карты и этажи","vac.routes_current_map":"Текущая карта","vac.routes_no_map":"источник молчит","vac.routes_status":"Маршрутизация","vac.routes_state_ready":"карта сопоставлена и откалибрована","vac.routes_state_needs_calibration":"карта сопоставлена, нужна калибровка","vac.routes_state_unmapped":"текущая карта не сопоставлена этажу","vac.routes_state_ambiguous":"две карты неразличимы — этаж не выбирается","vac.routes_state_missing_space":"пространство карты удалено","vac.routes_state_none":"нет данных о карте","vac.routes_empty":"Ни одна карта ещё не сопоставлена этажу.","vac.route_map_default":"без идентификатора","vac.route_active":"Текущая","vac.route_space":"Пространство","vac.route_space_none":"не выбрано","vac.route_status_ready":"готова","vac.route_status_needs_calibration":"нужна калибровка","vac.route_status_ambiguous":"неоднозначна","vac.route_status_missing_space":"пространство удалено","vac.route_missing_space_group":"Пространство удалено","vac.route_add_current":"Добавить текущую карту","vac.route_delete":"Удалить карту","vac.route_delete_title":"Удалить карту с этажа?","vac.route_delete_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_delete_confirm":"Удалить","vac.route_space_title":"Перенести карту в другое пространство?","vac.route_space_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_space_confirm":"Перенести","vac.route_missing_space_hint":"Одна из карт ссылается на удалённое пространство: выберите новое или удалите карту. Пока ссылка не исправлена, робот на этой карте не рисуется.","vac.route_default_hint":"Источник не сообщает стабильный идентификатор карты. Несколько этажей нельзя различить без другого источника или собственной карты робота.","vac.route_target_hint":"Док остаётся в пространстве «{space}» независимо от текущей карты.","vac.route_add_source":"Добавить источник карты","vac.route_add_source_hint":"Для интеграций, где у каждой карты своя камера. Список расширяется разделом «Все камеры» выше.","vac.route_source_no_map":"карта не читается"},de:{"gs.hint":"Füllfarben gelten für jeden Bereich; jede Farbe hat ihre eigene Deckkraft. Der Füllmodus wird in den Einstellungen des jeweiligen Bereichs festgelegt.","gs.show_room_tooltip":"Rauminformationen beim Darüberfahren anzeigen","support.about_group":"Über die Karte","support.guide_group":"Dokumentation","support.guide":"Benutzerhandbuch","support.form_group":"Bericht oder Vorschlag senden","support.contact":"Kontakt (E-Mail/tg/WhatsApp), optional.","support.message":"Nachricht","support.attach":"Anonymisierte Informationen aus dem Plan anhängen","support.attach_hint":"Enthält nur erlaubte Plangeometrie, Einstellungen und begrenzte Laufzeitdaten. Namen, Home-Assistant-IDs, Live-Zustände, URLs, Dateien, Nachricht und Kontakt werden ausgeschlossen.","support.geometry_warning":"Das Paket enthält keine Namen oder Home-Assistant-IDs, aber die exakte Geometrie und die Maße Ihres Hauses.","support.close_busy_title":"Aktuellen Vorgang abbrechen?","support.close_busy_body":"House Plan bereitet den Bericht vor oder sendet ihn. Beim Schließen wird nicht weiter auf das Ergebnis gewartet.","support.building":"Anonymisierte Daten werden vorbereitet…","support.preview_summary":"Paket v{version} · {spaces} Bereiche · {size} KiB","support.prepared":"Schnappschuss vor {n} Min. erstellt","support.show_data":"Daten anzeigen","support.download":"JSON herunterladen","support.refresh":"Schnappschuss aktualisieren","support.privacy":"Beim Senden verlassen Ihre Nachricht, der optionale Kontakt und, falls ausgewählt, die exakte Geometrie Ihren Home Assistant über das House-Plan-Projektrelay und sind für die Maintainer sichtbar. Der Projektserver speichert den Bericht bis zu 30 Tage. Die Netzwerkinfrastruktur sieht die Adresse Ihres HA-Servers, House Plan speichert sie jedoch nicht im Rohformat; Limit- und Idempotenzdaten bleiben bis zu 24 Stunden erhalten.","support.error_title":"Der Bericht wurde nicht gesendet","support.manual_recovery":"Nachricht und Anhang können gespeichert und manuell weitergegeben werden:","support.copy_message":"Nachricht kopieren","support.success":"Bericht gesendet: {id}. Bewahren Sie diese Nummer für den Support auf.","support.copy_id":"ID kopieren","support.sending":"Wird gesendet…","support.retry":"Erneut versuchen","support.send":"Senden","support.update_required":"Aktualisieren Sie House-Plan-Karte und Integration auf kompatible Versionen, um Berichte zu senden.","support.message_copied":"Nachricht kopiert","support.id_copied":"Berichts-ID kopiert","support.copy_failed":"Kein Zugriff auf die Zwischenablage. Markieren und kopieren Sie den Text manuell.","support.validation.message_required":"Geben Sie eine Nachricht ein.","support.validation.message_too_long":"Die Nachricht darf höchstens 10.000 Zeichen enthalten.","support.validation.contact_too_long":"Der Kontakt darf höchstens 320 Zeichen enthalten.","support.validation.preview_missing":"Warten Sie auf die Vorschau oder deaktivieren Sie den Anhang.","support.validation.preview_expired":"Die Anhangsvorschau ist abgelaufen. Aktualisieren Sie den Schnappschuss.","support.error.support_invalid_message":"Prüfen Sie die Nachricht und versuchen Sie es erneut.","support.error.support_preview_expired":"Die Anhangsvorschau ist abgelaufen oder nicht mehr verfügbar. Aktualisieren Sie den Schnappschuss.","support.error.support_package_too_large":"Das anonymisierte Paket überschreitet das Limit von 8 MiB.","support.error.support_rate_limited":"Zu viele Berichte oder Vorschauen wurden angefordert. Versuchen Sie es später erneut.","support.error.support_unavailable":"Der private Supportdienst ist vorübergehend nicht verfügbar. Der Entwurf bleibt in diesem Fenster erhalten.","support.error.support_rejected":"Der Bericht hat die Prüfung des Supportdienstes nicht bestanden.","support.error.unauthorized":"Sie dürfen diesen Bericht nicht senden.","vac.routes_section":"Karten und Etagen","vac.routes_current_map":"Aktuelle Karte","vac.routes_no_map":"keine Telemetrie","vac.routes_status":"Zuordnung","vac.routes_state_ready":"Karte zugeordnet und kalibriert","vac.routes_state_needs_calibration":"Karte zugeordnet, Kalibrierung nötig","vac.routes_state_unmapped":"aktuelle Karte keiner Etage zugeordnet","vac.routes_state_ambiguous":"zwei Karten nicht unterscheidbar — keine Etage gewählt","vac.routes_state_missing_space":"der Raum der Karte wurde gelöscht","vac.routes_state_none":"keine Kartendaten","vac.routes_empty":"Noch keine Karte einer Etage zugeordnet.","vac.route_map_default":"ohne Karten-ID","vac.route_active":"Aktiv","vac.route_space":"Raum","vac.route_space_none":"nicht gewählt","vac.route_status_ready":"bereit","vac.route_status_needs_calibration":"Kalibrierung nötig","vac.route_status_ambiguous":"mehrdeutig","vac.route_status_missing_space":"Raum gelöscht","vac.route_missing_space_group":"Gelöschter Bereich","vac.route_add_current":"Aktuelle Karte hinzufügen","vac.route_delete":"Karte entfernen","vac.route_delete_title":"Karte von der Etage entfernen?","vac.route_delete_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_delete_confirm":"Entfernen","vac.route_space_title":"Karte in einen anderen Raum verschieben?","vac.route_space_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_space_confirm":"Verschieben","vac.route_missing_space_hint":"Eine Karte verweist auf einen gelöschten Raum: neuen wählen oder Karte entfernen. Bis dahin wird der Roboter für diese Karte nicht gezeichnet.","vac.route_default_hint":"Die Quelle meldet keine stabile Karten-ID. Mehrere Etagen lassen sich ohne andere Quelle oder die vom Roboter gewählte Karte nicht unterscheiden.","vac.route_target_hint":"Die Station bleibt unabhängig von der aktuellen Karte im Raum „{space}“.","vac.route_add_source":"Kartenquelle hinzufügen","vac.route_add_source_hint":"Für Integrationen, die jeder Karte eine eigene Kamera geben. Der Abschnitt „Alle Kameras“ oben erweitert diese Liste.","vac.route_source_no_map":"keine Karte gemeldet"},fr:{"gs.hint":"Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.","gs.show_room_tooltip":"Afficher les informations de la pièce au survol","support.about_group":"À propos de la carte","support.guide_group":"Documentation d’aide","support.guide":"Guide utilisateur","support.form_group":"Envoyer un rapport ou une suggestion","support.contact":"Contact (e-mail/tg/WhatsApp), facultatif.","support.message":"Votre message","support.attach":"Joindre des informations anonymisées de votre plan","support.attach_hint":"Inclut uniquement la géométrie, les réglages autorisés et des données d’exécution limitées. Exclut les noms, identifiants Home Assistant, états en direct, URL, fichiers, message et contact.","support.geometry_warning":"Le paquet ne contient ni noms ni identifiants Home Assistant, mais il contient la géométrie et les dimensions exactes de votre logement.","support.close_busy_title":"Interrompre l’opération en cours ?","support.close_busy_body":"House Plan prépare ou envoie le rapport. Fermer maintenant arrête l’attente du résultat.","support.building":"Préparation des données anonymisées…","support.preview_summary":"Paquet v{version} · {spaces} espaces · {size} Kio","support.prepared":"Instantané préparé il y a {n} min","support.show_data":"Afficher les données","support.download":"Télécharger le JSON","support.refresh":"Actualiser l’instantané","support.privacy":"Lors de l’envoi, votre message, le contact facultatif et, si elle est sélectionnée, la géométrie exacte quittent votre Home Assistant via le relais du projet House Plan et sont visibles par les mainteneurs. Le serveur du projet conserve le rapport jusqu’à 30 jours. L’infrastructure réseau voit l’adresse de votre serveur HA, mais House Plan ne la conserve pas en clair ; les métadonnées de limitation et d’idempotence sont gardées jusqu’à 24 heures.","support.error_title":"Le rapport n’a pas été envoyé","support.manual_recovery":"Vous pouvez conserver le message et la pièce jointe puis continuer manuellement :","support.copy_message":"Copier le message","support.success":"Rapport envoyé : {id}. Conservez ce numéro pour contacter l’assistance.","support.copy_id":"Copier l’ID","support.sending":"Envoi…","support.retry":"Réessayer","support.send":"Envoyer","support.update_required":"Mettez à jour la carte et l’intégration House Plan vers des versions compatibles pour envoyer des rapports.","support.message_copied":"Message copié","support.id_copied":"ID du rapport copié","support.copy_failed":"Impossible d’accéder au presse-papiers. Sélectionnez et copiez le texte manuellement.","support.validation.message_required":"Saisissez un message.","support.validation.message_too_long":"Le message ne doit pas dépasser 10 000 caractères.","support.validation.contact_too_long":"Le contact ne doit pas dépasser 320 caractères.","support.validation.preview_missing":"Attendez l’aperçu de la pièce jointe ou désactivez-la.","support.validation.preview_expired":"L’aperçu de la pièce jointe a expiré. Actualisez l’instantané.","support.error.support_invalid_message":"Vérifiez le message et réessayez.","support.error.support_preview_expired":"L’aperçu de la pièce jointe a expiré ou n’est plus disponible. Actualisez l’instantané.","support.error.support_package_too_large":"Le paquet anonymisé dépasse la limite de 8 Mio.","support.error.support_rate_limited":"Trop de rapports ou d’aperçus ont été demandés. Réessayez plus tard.","support.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible. Le brouillon reste dans cette fenêtre.","support.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","support.error.unauthorized":"Vous n’êtes pas autorisé à envoyer ce rapport.","vac.routes_section":"Cartes et étages","vac.routes_current_map":"Carte actuelle","vac.routes_no_map":"aucune télémétrie","vac.routes_status":"Routage","vac.routes_state_ready":"carte assignée et calibrée","vac.routes_state_needs_calibration":"carte assignée, calibrage requis","vac.routes_state_unmapped":"carte actuelle non assignée à un étage","vac.routes_state_ambiguous":"deux cartes indiscernables — aucun étage choisi","vac.routes_state_missing_space":"l'espace de la carte a été supprimé","vac.routes_state_none":"aucune donnée de carte","vac.routes_empty":"Aucune carte n'est encore assignée à un étage.","vac.route_map_default":"sans identifiant","vac.route_active":"Active","vac.route_space":"Espace","vac.route_space_none":"non sélectionné","vac.route_status_ready":"prête","vac.route_status_needs_calibration":"calibrage requis","vac.route_status_ambiguous":"ambiguë","vac.route_status_missing_space":"espace supprimé","vac.route_missing_space_group":"Espace supprimé","vac.route_add_current":"Ajouter la carte actuelle","vac.route_delete":"Supprimer la carte","vac.route_delete_title":"Retirer la carte de son étage ?","vac.route_delete_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_delete_confirm":"Supprimer","vac.route_space_title":"Déplacer la carte vers un autre espace ?","vac.route_space_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_space_confirm":"Déplacer","vac.route_missing_space_hint":"Une carte pointe vers un espace supprimé : choisissez-en un autre ou supprimez la carte. D'ici là, le robot n'est pas dessiné pour cette carte.","vac.route_default_hint":"La source ne fournit pas d'identifiant de carte stable. Plusieurs étages ne peuvent pas être distingués sans une autre source ou la carte sélectionnée du robot.","vac.route_target_hint":"La station reste dans l'espace « {space} » quelle que soit la carte actuelle.","vac.route_add_source":"Ajouter une source de carte","vac.route_add_source_hint":"Pour les intégrations qui donnent à chaque carte sa propre caméra. La section « Toutes les caméras » ci-dessus élargit cette liste.","vac.route_source_no_map":"aucune carte signalée"}};function Ao(t,e,s){return i(zo[t]?.[e]??Ro[e]??e,s)}function Fo(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function No(t,e,s){return{...t,space:s.has(e)?e:""}}function Eo(t,e=Math.random){const s=new Set(t);for(let t=0;t<64;t+=1){const t="vr_"+Math.floor(16777215*e()).toString(36).padStart(5,"0");if(!s.has(t))return t}return"vr_"+Date.now().toString(36)}function Ho(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const Oo=new WeakMap,Lo=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function Bo(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>Ao(n,t,e),u=e.marker?.vacuum||{},_=Array.isArray(u.map_routes),m=i._vacSource(e)||"",g=o(e.id,u,e.space,m),f=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),b=new Set(f.map(t=>t.id)),v=h(g,[m],t=>i._vacObservedMapId(e,t)),y=c({routes:g,observed:v,spaceIds:b}),$="ready"===y.kind||"needs_calibration"===y.kind||"missing_space"===y.kind?y.route.id:"",w=m?v[m]:void 0,k=async s=>{let o=_?u.map_routes??null:null;if(!o&&(o=function(t,e,s,i){if(!s)return null;const o=t?.calibration;if(!o||"object"!=typeof o)return null;const n=new Set,r=[];for(const t of Object.keys(o)){const l=a(o[t]);if(!l)continue;const h=i(n);n.add(h),r.push({id:h,source:s,map_id:t,space:e,calibration:l})}return r.length?r:null}(u,e.space,m,t=>Eo(t))??[],!m&&Object.keys(u.calibration||{}).length))return!1;const n=s(o);return!!n&&(async s=>{const o=i._serverCfg;if(!o)return!1;const a=JSON.parse(JSON.stringify(o));a.markers=a.markers||[];let n=a.markers.find(t=>t.id===e.id);if(!n){if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return!1;n={id:e.id,binding:`${e.bindingKind}:${e.bindingRef}`,space:e.space||null,area:e.area||null,hidden:!!e.hidden},a.markers.push(n)}n.vacuum={...n.vacuum||{},map_routes:s},delete n.vacuum.calibration;const r=i._adoption.beginOptimistic(o,a);i._adoption.stageLocalConfig(a),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return i._rollbackOptimistic(r),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},x=s.candidates.filter(t=>t.entityId!==m&&!g.some(e=>e.source===t.entityId)),S=async(t,e)=>{if(!e||e===t.space)return;await i._confirmDanger({key:"vacuum_route_space",kind:"warning",title:r("vac.route_space_title"),message:r("vac.route_space_body"),objectName:t.map_id||r("vac.route_map_default"),confirmLabel:r("vac.route_space_confirm"),cancelLabel:i._t("btn.cancel")})&&await k(s=>function(t,e,s,i){return t.map(t=>t.id===e?{...t,id:i,space:s,calibration:null}:t)}(s,t.id,e,Eo(new Set(g.map(t=>t.id)))))},M=new Map(f.map((t,e)=>[t.id,e])),C=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),P=g.filter(t=>b.has(t.space)).sort((t,e)=>(M.get(t.space)??0)-(M.get(e.space)??0)||C(t,e)),D=g.filter(t=>!b.has(t.space)).sort(C),I=[...P,...D],T=!!m&&void 0!==w&&!g.some(t=>t.source===m&&t.map_id===w);let R=Oo.get(t);const z=R?.source||"",A=R?.mapId||"",F=!!R&&g.some(t=>t.source===z&&t.map_id===A);R&&(R.markerId!==e.id||i._vacObservedMapId(e,R.source)!==R.mapId||F&&!R.saving)&&(Oo.delete(t),R=void 0),R?.space&&!b.has(R.space)&&(R=No(R,"",b),Oo.set(t,R));const N=s=>p`
  • ${s.map_id||r("vac.route_map_default")} @@ -27,26 +27,26 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${r("vac.routes_current_map")}${void 0===w?r("vac.routes_no_map"):w||r("vac.route_map_default")}
    ${r("vac.routes_status")}${r(`vac.routes_state_${y.kind}`)}
    - ${P.length||z?p`
      - ${z?p` + ${P.length||R?p`
        + ${R?p`
      • -
        ${z.mapId||r("vac.route_map_default")}
        - ${z.source} +
        ${R.mapId||r("vac.route_map_default")}
        + ${R.source}
        - + + ?disabled=${!!R.saving||!b.has(R.space)} + @click=${()=>{(async()=>{const e=Oo.get(t);if(!e||e.saving||!b.has(e.space))return;Oo.set(t,{...e,saving:!0}),i.requestUpdate();const s=await k(t=>function(t,e,s,i){return e.source&&s.has(e.space)&&!t.some(t=>t.source===e.source&&t.map_id===e.mapId)?function(t,e,s){return[...t,{...e,id:s,calibration:e.calibration??null}]}(t,{source:e.source,map_id:e.mapId,space:e.space},i):null}(t,e,b,Eo(new Set(t.map(t=>t.id))))),o=Oo.get(t);o?.markerId===e.markerId&&o.source===e.source&&o.mapId===e.mapId&&(s?Oo.delete(t):Oo.set(t,e)),i.requestUpdate()})()}}>${i._t("btn.save")}
      • `:d} ${P.map(N)} @@ -59,18 +59,18 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
          ${D.map(N)}
        `:d} - ${I.length||z?d:p`
        ${r("vac.routes_empty")}
        `} + ${I.length||R?d:p`
        ${r("vac.routes_empty")}
        `}
        - +
        ${x.length?p`
        ${r("vac.route_add_source")}
        ${r("vac.route_add_source_hint")}
        ${x.map(s=>{const o=i._vacObservedMapId(e,s.entityId);return p``})} @@ -80,8 +80,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
        ${r("vac.route_missing_space_hint")}
        `:d} ${g.some(t=>"default"===t.map_id)?p`
        ${r("vac.route_default_hint")}
        `:d} - ${I.length?p`
        ${r("vac.route_target_hint",{space:Oo(i,e.space)})}
        `:d} -
        `}const Bo=new WeakMap;function Wo(t,e,s){let i=Bo.get(t);i||(i=new Map,Bo.set(t,i));const o=i.get(e);if(o)return void(o.run=s);const a={run:s};i.set(e,a),queueMicrotask(()=>{i.get(e)===a&&(i.delete(e),a.run())})}function jo(t,e){const s=Bo.get(t),i=s?.get(e);i&&(s.delete(e),i.run())}function Go(t,e){const s=Bo.get(t);if(!s)return;const i=e?[...s].filter(([t])=>t===e):[...s];for(const[t]of i)s.delete(t);s.size||Bo.delete(t)}const qo=new WeakMap,Uo=new Set(["_cursorPt","_opMeasure","_physicalDrag","_physicalRotate","_decorDraft","_dtBox","_dtDrag","_bdDrag","_furnPreviewInput","_layout"]),Ko=new Set(["_cursorPt","_opMeasure","_furnPreviewInput"]),Vo=new Set(["_physicalDrag","_physicalRotate","_decorDraft","_dtDrag","_bdDrag"]),Jo=t=>{let e=qo.get(t);return e||(e={raf:0,requestedRevision:0,paintedRevision:0,waiters:[],hidden:[],transparent:[],dimmed:[]},qo.set(t,e)),e},Yo=(t,e)=>{t.paintedRevision=Math.max(t.paintedRevision,e);const s=t.waiters.filter(e=>e.revision<=t.paintedRevision);t.waiters=t.waiters.filter(e=>e.revision>t.paintedRevision);for(const t of s)t.resolve()},Xo=t=>!!("view"!==t._mode&&(t._deviceDrag||t._physicalDrag||t._physicalRotate||t._decorDraft||t._decorMove||t._dtDrag||t._bdDrag||t._opDrag||t._resize?.dragging));function Zo(t,e,s){const i=t;if(!i?.isConnected||"view"===i._mode)return!1;const o=void 0!==e&&Uo.has(e);if("_layout"===e&&!i._deviceDrag)return!1;if("_dtBox"===e&&!i._dtDrag)return!1;if(void 0!==e&&Vo.has(e)&&null==s&&null!=i[e]&&Xo(i))return!1;if(void 0!==e&&Vo.has(e)&&null==i[e])return!1;if(void 0!==e&&Ko.has(e)&&null==i[e])return!1;return!!(o&&(Ko.has(e)||Xo(i))||void 0===e&&Xo(i))&&(function(t){const e=Jo(t);if(e.requestedRevision++,e.raf||"function"!=typeof requestAnimationFrame)return;e.raf=requestAnimationFrame(()=>{e.raf=0;const s=e.requestedRevision;!function(t){const e=t,s=e.renderRoot;if(!s)return;const i=Jo(e);ea(i),oa(e,s);const o=s.querySelector("[data-hp-live-editor]");if(!o)return;if(ta(i,s,".hp-editor-only-layer:not(.hp-plan-snap-layer)"),"plan"===e._mode)e._opDrag&&Qo(i,s,".wallbodies"),e._resize?.dragging&&(ra(i,s,".wallbodies"),ta(i,s,".resize-layer"),na(i,s,e._resize.plan?.movingOpeningIds||[])),e._opDrag&&ta(i,s,".openinglayer");else if("decor"===e._mode){const t=e._dtDrag?.id||e._decorMove?.id;t&&aa(i,s,t),ta(i,s,".dtframe, .backdropframe")}u(ia(e),o);const a=s.querySelector("[data-hp-live-editor-html]");if(a){const t=e._viewOr(e._baseVb());u(e._renderLiveEditorMeasurements(t),a)}e._liveEditorPaintCount=(e._liveEditorPaintCount||0)+1}(t),Yo(e,s)})}(i),!0)}const Qo=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"hidden"!==i.style.visibility&&(i.style.visibility="hidden",t.hidden.push(i))},ta=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},ea=t=>{for(const e of t.hidden)e.style.removeProperty("visibility");t.hidden.length=0;for(const e of t.transparent)e.style.removeProperty("opacity");t.transparent.length=0;for(const e of t.dimmed)e.style.removeProperty("opacity");t.dimmed.length=0},sa=(t,e,s=[])=>{if("iso"===t._renderProjection)return _``;const i=t._spaceModel();if(!i)return _``;const o=new Set(s),a=(i.rooms||[]).filter(t=>!!t.id&&o.has(t.id)).flatMap(t=>{const e=t.poly||[];return e.map((t,s)=>[t,e[(s+1)%e.length]])}),n=(t,e)=>{const[s,i]=e,o=i[0]-s[0],a=i[1]-s[1],n=o*o+a*a;if(!(n>0))return!1;const r=((t[0]-s[0])*o+(t[1]-s[1])*a)/n,l=Math.max(0,Math.min(1,r));return Math.hypot(t[0]-s[0]-o*l,t[1]-s[1]-a*l)<1e-4},r=[...t._spaceWalls.filter(t=>{const e=(t.a||[]).map(t=>t*m),s=(t.b||[]).map(t=>t*m);return a.some(t=>n(e,t)&&n(s,t))}).map((e,s)=>((e,s,i,o)=>{const a=Math.hypot(s[0]-e[0],s[1]-e[1]);if(!(a>1e-9&&i>0))return null;const n=$(i,t._cellCm,t._gridPitch)/2,r=-(s[1]-e[1])/a*n,l=(s[0]-e[0])/a*n;return{key:o,kind:"outer",cm:i,a:e,b:s,depthUnits:2*n,quad:[[e[0]+r,e[1]+l],[s[0]+r,s[1]+l],[s[0]-r,s[1]-l],[e[0]-r,e[1]-l]]}})((e.a||[]).map(t=>t*m),(e.b||[]).map(t=>t*m),e.cm,e.key||`wall-${s}`))].filter(t=>!!t),l=t._openingsR.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),h=r.map(t=>g(t,l)).filter(Boolean);if(!h.length)return _``;const c=Math.max(...r.map(t=>t.depthUnits),0),d=t._viewOr(t._baseVb()),p=t._stageEl?.clientWidth&&d.w?t._stageEl.clientWidth/d.w:1,u=f(c,p)||b(v(t._cellCm),p),w=e?.color||"#607d8b",k=t._fillColors.wall_fill,x=h.join(" ");return _`${r("vac.route_target_hint",{space:Lo(i,e.space)})}
  • `:d} +
    `}const Wo=new WeakMap;function jo(t,e,s){let i=Wo.get(t);i||(i=new Map,Wo.set(t,i));const o=i.get(e);if(o)return void(o.run=s);const a={run:s};i.set(e,a),queueMicrotask(()=>{i.get(e)===a&&(i.delete(e),a.run())})}function Go(t,e){const s=Wo.get(t),i=s?.get(e);i&&(s.delete(e),i.run())}function qo(t,e){const s=Wo.get(t);if(!s)return;const i=e?[...s].filter(([t])=>t===e):[...s];for(const[t]of i)s.delete(t);s.size||Wo.delete(t)}const Uo=new WeakMap,Ko=new Set(["_cursorPt","_opMeasure","_physicalDrag","_physicalRotate","_decorDraft","_dtBox","_dtDrag","_bdDrag","_furnPreviewInput","_layout"]),Vo=new Set(["_cursorPt","_opMeasure","_furnPreviewInput"]),Jo=new Set(["_physicalDrag","_physicalRotate","_decorDraft","_dtDrag","_bdDrag"]),Yo=t=>{let e=Uo.get(t);return e||(e={raf:0,requestedRevision:0,paintedRevision:0,waiters:[],hidden:[],transparent:[],dimmed:[]},Uo.set(t,e)),e},Xo=(t,e)=>{t.paintedRevision=Math.max(t.paintedRevision,e);const s=t.waiters.filter(e=>e.revision<=t.paintedRevision);t.waiters=t.waiters.filter(e=>e.revision>t.paintedRevision);for(const t of s)t.resolve()},Zo=t=>!!("view"!==t._mode&&(t._deviceDrag||t._physicalDrag||t._physicalRotate||t._decorDraft||t._decorMove||t._dtDrag||t._bdDrag||t._opDrag||t._resize?.dragging));function Qo(t,e,s){const i=t;if(!i?.isConnected||"view"===i._mode)return!1;const o=void 0!==e&&Ko.has(e);if("_layout"===e&&!i._deviceDrag)return!1;if("_dtBox"===e&&!i._dtDrag)return!1;if(void 0!==e&&Jo.has(e)&&null==s&&null!=i[e]&&Zo(i))return!1;if(void 0!==e&&Jo.has(e)&&null==i[e])return!1;if(void 0!==e&&Vo.has(e)&&null==i[e])return!1;return!!(o&&(Vo.has(e)||Zo(i))||void 0===e&&Zo(i))&&(function(t){const e=Yo(t);if(e.requestedRevision++,e.raf||"function"!=typeof requestAnimationFrame)return;e.raf=requestAnimationFrame(()=>{e.raf=0;const s=e.requestedRevision;!function(t){const e=t,s=e.renderRoot;if(!s)return;const i=Yo(e);sa(i),aa(e,s);const o=s.querySelector("[data-hp-live-editor]");if(!o)return;if(ea(i,s,".hp-editor-only-layer:not(.hp-plan-snap-layer)"),"plan"===e._mode)e._opDrag&&ta(i,s,".wallbodies"),e._resize?.dragging&&(la(i,s,".wallbodies"),ea(i,s,".resize-layer"),ra(i,s,e._resize.plan?.movingOpeningIds||[])),e._opDrag&&ea(i,s,".openinglayer");else if("decor"===e._mode){const t=e._dtDrag?.id||e._decorMove?.id;t&&na(i,s,t),ea(i,s,".dtframe, .backdropframe")}u(oa(e),o);const a=s.querySelector("[data-hp-live-editor-html]");if(a){const t=e._viewOr(e._baseVb());u(e._renderLiveEditorMeasurements(t),a)}e._liveEditorPaintCount=(e._liveEditorPaintCount||0)+1}(t),Xo(e,s)})}(i),!0)}const ta=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"hidden"!==i.style.visibility&&(i.style.visibility="hidden",t.hidden.push(i))},ea=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},sa=t=>{for(const e of t.hidden)e.style.removeProperty("visibility");t.hidden.length=0;for(const e of t.transparent)e.style.removeProperty("opacity");t.transparent.length=0;for(const e of t.dimmed)e.style.removeProperty("opacity");t.dimmed.length=0},ia=(t,e,s=[])=>{if("iso"===t._renderProjection)return _``;const i=t._spaceModel();if(!i)return _``;const o=new Set(s),a=(i.rooms||[]).filter(t=>!!t.id&&o.has(t.id)).flatMap(t=>{const e=t.poly||[];return e.map((t,s)=>[t,e[(s+1)%e.length]])}),n=(t,e)=>{const[s,i]=e,o=i[0]-s[0],a=i[1]-s[1],n=o*o+a*a;if(!(n>0))return!1;const r=((t[0]-s[0])*o+(t[1]-s[1])*a)/n,l=Math.max(0,Math.min(1,r));return Math.hypot(t[0]-s[0]-o*l,t[1]-s[1]-a*l)<1e-4},r=[...t._spaceWalls.filter(t=>{const e=(t.a||[]).map(t=>t*m),s=(t.b||[]).map(t=>t*m);return a.some(t=>n(e,t)&&n(s,t))}).map((e,s)=>((e,s,i,o)=>{const a=Math.hypot(s[0]-e[0],s[1]-e[1]);if(!(a>1e-9&&i>0))return null;const n=$(i,t._cellCm,t._gridPitch)/2,r=-(s[1]-e[1])/a*n,l=(s[0]-e[0])/a*n;return{key:o,kind:"outer",cm:i,a:e,b:s,depthUnits:2*n,quad:[[e[0]+r,e[1]+l],[s[0]+r,s[1]+l],[s[0]-r,s[1]-l],[e[0]-r,e[1]-l]]}})((e.a||[]).map(t=>t*m),(e.b||[]).map(t=>t*m),e.cm,e.key||`wall-${s}`))].filter(t=>!!t),l=t._openingsR.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),h=r.map(t=>g(t,l)).filter(Boolean);if(!h.length)return _``;const c=Math.max(...r.map(t=>t.depthUnits),0),d=t._viewOr(t._baseVb()),p=t._stageEl?.clientWidth&&d.w?t._stageEl.clientWidth/d.w:1,u=f(c,p)||b(v(t._cellCm),p),w=e?.color||"#607d8b",k=t._fillColors.wall_fill,x=h.join(" ");return _` @@ -89,8 +89,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 data-id="preview" data-kind="preview" d=${x} fill=${u?"none":"url(#hp-wall-hatch)"} fill-rule="nonzero" stroke=${w} stroke-width=${y(.6,t._cellCm)}> - `},ia=t=>{if("plan"===t._mode)return(t=>{const e=t._baseVb(),s=t._viewOr(e),i=t._opMeasureView;if(t._resize?.dragging){const e=t._spaceDisplayForRender(),i=t._resize.plan;return _``},oa=t=>{if("plan"===t._mode)return(t=>{const e=t._baseVb(),s=t._viewOr(e),i=t._opMeasureView;if(t._resize?.dragging){const e=t._spaceDisplayForRender(),i=t._resize.plan;return _``}return _``},oa=(t,e)=>{const s=t._deviceDrag;if(!s)return;const i=t._devices.find(t=>t.id===s.id),o=[...e.querySelectorAll('[data-hp="device"]')].find(t=>t.dataset.id===s.id);if(!i||!o)return;const a=t._livePos(i),n=t._scenePoint([a.x,a.y]),r=t._viewOr(t._baseVb());o.style.left=(n[0]-r.x)/r.w*100+"%",o.style.top=(n[1]-r.y)/r.h*100+"%"},aa=(t,e,s)=>{for(const i of e.querySelectorAll('.decorlayer [data-hp="decor"]'))i.closest("[data-hp-live-editor]")||i.dataset.id!==s||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},na=(t,e,s)=>{const i=new Set(s);for(const s of e.querySelectorAll('.openinglayer [data-hp="opening"]'))!s.closest("[data-hp-live-editor]")&&i.has(s.dataset.id||"")&&(s.style.opacity="0",t.transparent.push(s))},ra=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||(i.style.opacity="0.35",t.dimmed.push(i))};const la=(t,e,s)=>Math.min(s,Math.max(e,Number.isFinite(t)?t:e));function ha(t){return Number.isFinite(t)?(t%360+360)%360:0}function ca(t){if("string"!=typeof t)return null;const e=t.trim().replace(/^#/,""),s=/^[0-9a-fA-F]{3}$/.test(e)?e.split("").map(t=>`${t}${t}`).join(""):e;return/^[0-9a-fA-F]{6}$/.test(s)?`#${s.toLowerCase()}`:null}function da(t){const e=ca(t);return e?{r:Number.parseInt(e.slice(1,3),16),g:Number.parseInt(e.slice(3,5),16),b:Number.parseInt(e.slice(5,7),16)}:null}function pa(t){const e=la(t.r,0,255)/255,s=la(t.g,0,255)/255,i=la(t.b,0,255)/255,o=Math.max(e,s,i),a=o-Math.min(e,s,i);let n=0;return a>0&&(n=o===e?(s-i)/a%6*60:o===s?60*((i-e)/a+2):60*((e-s)/a+4)),{h:ha(n),s:0===o?0:a/o*100,v:100*o}}function ua(t){return function(t){const e=t=>Math.round(la(t,0,255)).toString(16).padStart(2,"0");return`#${e(t.r)}${e(t.g)}${e(t.b)}`}(function(t){const e=ha(t.h),s=la(t.s,0,100)/100,i=la(t.v,0,100)/100,o=i*s,a=o*(1-Math.abs(e/60%2-1)),n=i-o;let r;return r=e<60?[o,a,0]:e<120?[a,o,0]:e<180?[0,o,a]:e<240?[0,a,o]:e<300?[a,0,o]:[o,0,a],{r:Math.round(255*(r[0]+n)),g:Math.round(255*(r[1]+n)),b:Math.round(255*(r[2]+n))}}(t))}const _a={title:"Color picker",hue:"Hue",saturation:"Saturation",value:"Brightness",hex:"Hex color",invalidHex:"Enter a 3- or 6-digit hex color",confirm:"OK"};class ma extends k{constructor(){super(...arguments),this.label="",this.opacityLabel="Opacity",this.color="#607d8b",this.opacity=1,this.disabled=!1,this.showOpacity=!0,this.pickerLabels=_a,this._open=!1,this._pickerRaf=0,this._emitRaf=0,this._forceFallback=!1,this._overlayDispose=null,this._hue=0,this._saturation=0,this._value=0,this._hexDraft="#607d8b",this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor="#607d8b",this._activePointerId=null,this._outsidePointerDown=t=>{if(!this._open)return;const e=t.composedPath();this._floating.containsPath(e)||this._closePicker(!1,"outside")},this._keyDown=t=>{this._open&&"Escape"===t.key&&(t.preventDefault(),t.stopImmediatePropagation(),this._closePicker(this._floating.ownsActiveElement(),"escape"))},this._floating=new mo(this,"color-opacity",this._keyDown),this._queuePickerPosition=()=>{if(!this._open)return;this._pickerRaf&&cancelAnimationFrame(this._pickerRaf);const t=this._window();t&&(this._pickerRaf=t.requestAnimationFrame(()=>{this._pickerRaf=0,this._positionPicker()||this._closePicker()}))}}connectedCallback(){super.connectedCallback(),this._syncFromColor(this.color,!1),this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.addEventListener("resize",this._queuePickerPosition),t?.addEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.addEventListener("resize",this._queuePickerPosition),t?.visualViewport?.addEventListener("scroll",this._queuePickerPosition),this.addEventListener("keydown",this._keyDown,!0)}disconnectedCallback(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.removeEventListener("resize",this._queuePickerPosition),t?.removeEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.removeEventListener("resize",this._queuePickerPosition),t?.visualViewport?.removeEventListener("scroll",this._queuePickerPosition),this.removeEventListener("keydown",this._keyDown,!0),this._pickerRaf&&cancelAnimationFrame(this._pickerRaf),this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._pickerRaf=0,this._emitRaf=0,this._closePicker(!1,"disconnect"),super.disconnectedCallback()}updated(t){if(t.has("color")){const t=ca(this.color);t&&t!==this._lastValidColor&&this._syncFromColor(t,this._open)}this.disabled&&this._open?this._closePicker():this._open&&(this._supportsPopover()||this._renderFallback(),(t.has("color")||t.has("opacity")||t.has("showOpacity")||t.has("label")||t.has("opacityLabel")||t.has("pickerLabels"))&&this._queuePickerPosition())}_window(){return this._floating.window()}_supportsPopover(){return this._floating.usesPopover(this._forceFallback)}_dialog(){return this._floating.dialog()}async _toggle(){this.disabled||(this._open?this._closePicker():(this._forceFallback=!1,this._syncFromColor(this.color,!1),this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._activePointerId=null,this._open=!0,await this.updateComplete,this._open&&(this._supportsPopover()||this._renderFallback(),this._positionPicker()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:t=>this._closePicker("escape"===t&&this._floating.ownsActiveElement(),t)})||null:this._closePicker())))}_closePicker(t=!1,e="exclusive"){if(!this._open&&!this._floating.hasFallback)return;const s=this._overlayDispose;this._overlayDispose=null,s?.();const i=this.renderRoot.querySelector(".picker");if(i?.hidePopover)try{i.matches(":popover-open")&&i.hidePopover()}catch{}this._open=!1,this._cancelQueuedEmit(),this._activePointerId=null,this._floating.destroy(),t&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_surface(){return this._floating.surface(".picker",this._supportsPopover())}_renderFallback(){const t=ma.styles.cssText;this._floating.renderFallback(this._pickerTemplate(!1),t)}_positionPicker(){if(!this._open)return!1;const t=this._window(),e=this.renderRoot.querySelector(".trigger");let s=this._surface();if(!t||!e?.isConnected||!s?.isConnected)return!1;const i=go(t);if(s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden",this._supportsPopover()&&s.showPopover)try{s.matches(":popover-open")||s.showPopover()}catch{if(this._forceFallback=!0,this._renderFallback(),s=this._surface(),!s?.isConnected)return!1;s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden"}const o=e.getBoundingClientRect(),a=s.getBoundingClientRect();if(!(o.width&&o.height&&a.width&&a.height))return!1;const n=fo(o,a,i);return s.style.left=`${n.left}px`,s.style.top=`${n.top}px`,s.dataset.side=n.side,s.style.visibility="",!0}_labels(){const t=this.pickerLabels||_a;return{title:t.title||_a.title,hue:t.hue||_a.hue,saturation:t.saturation||_a.saturation,value:t.value||_a.value,hex:t.hex||_a.hex,invalidHex:t.invalidHex||_a.invalidHex,confirm:t.confirm||_a.confirm}}_syncFromColor(t,e){const s=ca(x(t,"#607d8b"))||"#607d8b",i=da(s);if(!i)return;const o=pa(i);(!e||o.s>1e-4)&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._hexDraft=s,this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor=s}_cancelQueuedEmit(t=!1){this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._emitRaf=0,t&&this._syncFromColor(this._lastValidColor,!0)}_queueHsvEmit(){if(this._emitRaf)return;const t=this._window();t?this._emitRaf=t.requestAnimationFrame(()=>{this._emitRaf=0,this._emitHsv()}):this._emitHsv()}_emitHsv(){this._emit(ua({h:this._hue,s:this._saturation,v:this._value}),this.opacity)}_setHue(t){this._hue=Math.min(359,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setSaturation(t){this._saturation=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setValue(t){this._value=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setOpacity(t){this._emit(this._lastValidColor,t)}_shiftRangeKey(t,e,s,i,o){if(!t.shiftKey)return;const a="ArrowRight"===t.key||"ArrowUp"===t.key?10:"ArrowLeft"===t.key||"ArrowDown"===t.key?-10:0;a&&(t.preventDefault(),t.stopPropagation(),o(Math.min(i,Math.max(s,e+a))))}_setSvFromPointer(t,e){const s=t.currentTarget.getBoundingClientRect();s.width&&s.height&&(this._saturation=Math.min(100,Math.max(0,(t.clientX-s.left)/s.width*100)),this._value=Math.min(100,Math.max(0,100*(1-(t.clientY-s.top)/s.height))),e?(this._cancelQueuedEmit(),this._emitHsv()):this._queueHsvEmit())}_svPointerDown(t){if(t.preventDefault(),t.stopPropagation(),null===this._activePointerId){this._activePointerId=t.pointerId;try{t.currentTarget.setPointerCapture(t.pointerId)}catch{}this._setSvFromPointer(t,!0)}}_svPointerMove(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!1))}_svPointerUp(t){if(t.pointerId===this._activePointerId){t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!0),this._activePointerId=null;try{t.currentTarget.releasePointerCapture(t.pointerId)}catch{}}}_svPointerCancel(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._activePointerId=null,this._cancelQueuedEmit(!0))}_svLostPointerCapture(t){t.pointerId===this._activePointerId&&(this._activePointerId=null,this._cancelQueuedEmit(!0))}_hexInput(t){const e=t.target.value;this._hexDraft=e;const s=ca(e),i=s?da(s):null;if(!s||!i)return void(this._hexInvalid=this._hexNeedsValidInput);this._hexNeedsValidInput=!1,this._hexInvalid=!1;const o=pa(i);o.s>1e-4&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._emit(s,this.opacity,!0)}_commitHex(){const t=ca(this._hexDraft);if(!t)return this._hexDraft=this._lastValidColor,this._hexInvalid=!0,void(this._hexNeedsValidInput=!0);this._hexDraft=t,this._hexNeedsValidInput?this._hexInvalid=!0:(this._hexInvalid=!1,t!==this._lastValidColor&&this._emit(t,this.opacity))}_confirm(t){t.preventDefault(),t.stopPropagation(),this._commitHex(),this._hexInvalid||this._hexNeedsValidInput?this.updateComplete.then(()=>{this._surface()?.querySelector('input[type="text"]')?.focus()}):this._closePicker(!0)}_hexKeyDown(t){"Enter"===t.key&&(t.preventDefault(),t.stopPropagation(),this._commitHex())}_emit(t,e,s=!1){const i=ca(t)||this._lastValidColor,o=Number.isFinite(e)?e:Number(this.opacity)||0,a=Math.min(1,Math.max(0,o));this.color=i,this.opacity=a,this._lastValidColor=i,s||(this._hexDraft=i),this._hexInvalid=this._hexNeedsValidInput,this.dispatchEvent(new CustomEvent("hp-color-opacity-change",{detail:{color:i,opacity:a},bubbles:!0,composed:!0}))}_pickerTemplate(t){const e=Math.round(100*Math.min(1,Math.max(0,Number(this.opacity)||0))),s=ua({h:this._hue,s:this._saturation,v:this._value}),i=ua({h:this._hue,s:100,v:100}),o=this._labels(),a=Math.round(this._hue),n=Math.round(this._saturation),r=Math.round(this._value);return p` + `},aa=(t,e)=>{const s=t._deviceDrag;if(!s)return;const i=t._devices.find(t=>t.id===s.id),o=[...e.querySelectorAll('[data-hp="device"]')].find(t=>t.dataset.id===s.id);if(!i||!o)return;const a=t._livePos(i),n=t._scenePoint([a.x,a.y]),r=t._viewOr(t._baseVb());o.style.left=(n[0]-r.x)/r.w*100+"%",o.style.top=(n[1]-r.y)/r.h*100+"%"},na=(t,e,s)=>{for(const i of e.querySelectorAll('.decorlayer [data-hp="decor"]'))i.closest("[data-hp-live-editor]")||i.dataset.id!==s||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},ra=(t,e,s)=>{const i=new Set(s);for(const s of e.querySelectorAll('.openinglayer [data-hp="opening"]'))!s.closest("[data-hp-live-editor]")&&i.has(s.dataset.id||"")&&(s.style.opacity="0",t.transparent.push(s))},la=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||(i.style.opacity="0.35",t.dimmed.push(i))};const ha=(t,e,s)=>Math.min(s,Math.max(e,Number.isFinite(t)?t:e));function ca(t){return Number.isFinite(t)?(t%360+360)%360:0}function da(t){if("string"!=typeof t)return null;const e=t.trim().replace(/^#/,""),s=/^[0-9a-fA-F]{3}$/.test(e)?e.split("").map(t=>`${t}${t}`).join(""):e;return/^[0-9a-fA-F]{6}$/.test(s)?`#${s.toLowerCase()}`:null}function pa(t){const e=da(t);return e?{r:Number.parseInt(e.slice(1,3),16),g:Number.parseInt(e.slice(3,5),16),b:Number.parseInt(e.slice(5,7),16)}:null}function ua(t){const e=ha(t.r,0,255)/255,s=ha(t.g,0,255)/255,i=ha(t.b,0,255)/255,o=Math.max(e,s,i),a=o-Math.min(e,s,i);let n=0;return a>0&&(n=o===e?(s-i)/a%6*60:o===s?60*((i-e)/a+2):60*((e-s)/a+4)),{h:ca(n),s:0===o?0:a/o*100,v:100*o}}function _a(t){return function(t){const e=t=>Math.round(ha(t,0,255)).toString(16).padStart(2,"0");return`#${e(t.r)}${e(t.g)}${e(t.b)}`}(function(t){const e=ca(t.h),s=ha(t.s,0,100)/100,i=ha(t.v,0,100)/100,o=i*s,a=o*(1-Math.abs(e/60%2-1)),n=i-o;let r;return r=e<60?[o,a,0]:e<120?[a,o,0]:e<180?[0,o,a]:e<240?[0,a,o]:e<300?[a,0,o]:[o,0,a],{r:Math.round(255*(r[0]+n)),g:Math.round(255*(r[1]+n)),b:Math.round(255*(r[2]+n))}}(t))}const ma={title:"Color picker",hue:"Hue",saturation:"Saturation",value:"Brightness",hex:"Hex color",invalidHex:"Enter a 3- or 6-digit hex color",confirm:"OK"};class ga extends k{constructor(){super(...arguments),this.label="",this.opacityLabel="Opacity",this.color="#607d8b",this.opacity=1,this.disabled=!1,this.showOpacity=!0,this.pickerLabels=ma,this._open=!1,this._pickerRaf=0,this._emitRaf=0,this._forceFallback=!1,this._overlayDispose=null,this._hue=0,this._saturation=0,this._value=0,this._hexDraft="#607d8b",this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor="#607d8b",this._activePointerId=null,this._outsidePointerDown=t=>{if(!this._open)return;const e=t.composedPath();this._floating.containsPath(e)||this._closePicker(!1,"outside")},this._keyDown=t=>{this._open&&"Escape"===t.key&&(t.preventDefault(),t.stopImmediatePropagation(),this._closePicker(this._floating.ownsActiveElement(),"escape"))},this._floating=new go(this,"color-opacity",this._keyDown),this._queuePickerPosition=()=>{if(!this._open)return;this._pickerRaf&&cancelAnimationFrame(this._pickerRaf);const t=this._window();t&&(this._pickerRaf=t.requestAnimationFrame(()=>{this._pickerRaf=0,this._positionPicker()||this._closePicker()}))}}connectedCallback(){super.connectedCallback(),this._syncFromColor(this.color,!1),this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.addEventListener("resize",this._queuePickerPosition),t?.addEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.addEventListener("resize",this._queuePickerPosition),t?.visualViewport?.addEventListener("scroll",this._queuePickerPosition),this.addEventListener("keydown",this._keyDown,!0)}disconnectedCallback(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.removeEventListener("resize",this._queuePickerPosition),t?.removeEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.removeEventListener("resize",this._queuePickerPosition),t?.visualViewport?.removeEventListener("scroll",this._queuePickerPosition),this.removeEventListener("keydown",this._keyDown,!0),this._pickerRaf&&cancelAnimationFrame(this._pickerRaf),this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._pickerRaf=0,this._emitRaf=0,this._closePicker(!1,"disconnect"),super.disconnectedCallback()}updated(t){if(t.has("color")){const t=da(this.color);t&&t!==this._lastValidColor&&this._syncFromColor(t,this._open)}this.disabled&&this._open?this._closePicker():this._open&&(this._supportsPopover()||this._renderFallback(),(t.has("color")||t.has("opacity")||t.has("showOpacity")||t.has("label")||t.has("opacityLabel")||t.has("pickerLabels"))&&this._queuePickerPosition())}_window(){return this._floating.window()}_supportsPopover(){return this._floating.usesPopover(this._forceFallback)}_dialog(){return this._floating.dialog()}async _toggle(){this.disabled||(this._open?this._closePicker():(this._forceFallback=!1,this._syncFromColor(this.color,!1),this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._activePointerId=null,this._open=!0,await this.updateComplete,this._open&&(this._supportsPopover()||this._renderFallback(),this._positionPicker()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:t=>this._closePicker("escape"===t&&this._floating.ownsActiveElement(),t)})||null:this._closePicker())))}_closePicker(t=!1,e="exclusive"){if(!this._open&&!this._floating.hasFallback)return;const s=this._overlayDispose;this._overlayDispose=null,s?.();const i=this.renderRoot.querySelector(".picker");if(i?.hidePopover)try{i.matches(":popover-open")&&i.hidePopover()}catch{}this._open=!1,this._cancelQueuedEmit(),this._activePointerId=null,this._floating.destroy(),t&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_surface(){return this._floating.surface(".picker",this._supportsPopover())}_renderFallback(){const t=ga.styles.cssText;this._floating.renderFallback(this._pickerTemplate(!1),t)}_positionPicker(){if(!this._open)return!1;const t=this._window(),e=this.renderRoot.querySelector(".trigger");let s=this._surface();if(!t||!e?.isConnected||!s?.isConnected)return!1;const i=fo(t);if(s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden",this._supportsPopover()&&s.showPopover)try{s.matches(":popover-open")||s.showPopover()}catch{if(this._forceFallback=!0,this._renderFallback(),s=this._surface(),!s?.isConnected)return!1;s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden"}const o=e.getBoundingClientRect(),a=s.getBoundingClientRect();if(!(o.width&&o.height&&a.width&&a.height))return!1;const n=bo(o,a,i);return s.style.left=`${n.left}px`,s.style.top=`${n.top}px`,s.dataset.side=n.side,s.style.visibility="",!0}_labels(){const t=this.pickerLabels||ma;return{title:t.title||ma.title,hue:t.hue||ma.hue,saturation:t.saturation||ma.saturation,value:t.value||ma.value,hex:t.hex||ma.hex,invalidHex:t.invalidHex||ma.invalidHex,confirm:t.confirm||ma.confirm}}_syncFromColor(t,e){const s=da(x(t,"#607d8b"))||"#607d8b",i=pa(s);if(!i)return;const o=ua(i);(!e||o.s>1e-4)&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._hexDraft=s,this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor=s}_cancelQueuedEmit(t=!1){this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._emitRaf=0,t&&this._syncFromColor(this._lastValidColor,!0)}_queueHsvEmit(){if(this._emitRaf)return;const t=this._window();t?this._emitRaf=t.requestAnimationFrame(()=>{this._emitRaf=0,this._emitHsv()}):this._emitHsv()}_emitHsv(){this._emit(_a({h:this._hue,s:this._saturation,v:this._value}),this.opacity)}_setHue(t){this._hue=Math.min(359,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setSaturation(t){this._saturation=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setValue(t){this._value=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setOpacity(t){this._emit(this._lastValidColor,t)}_shiftRangeKey(t,e,s,i,o){if(!t.shiftKey)return;const a="ArrowRight"===t.key||"ArrowUp"===t.key?10:"ArrowLeft"===t.key||"ArrowDown"===t.key?-10:0;a&&(t.preventDefault(),t.stopPropagation(),o(Math.min(i,Math.max(s,e+a))))}_setSvFromPointer(t,e){const s=t.currentTarget.getBoundingClientRect();s.width&&s.height&&(this._saturation=Math.min(100,Math.max(0,(t.clientX-s.left)/s.width*100)),this._value=Math.min(100,Math.max(0,100*(1-(t.clientY-s.top)/s.height))),e?(this._cancelQueuedEmit(),this._emitHsv()):this._queueHsvEmit())}_svPointerDown(t){if(t.preventDefault(),t.stopPropagation(),null===this._activePointerId){this._activePointerId=t.pointerId;try{t.currentTarget.setPointerCapture(t.pointerId)}catch{}this._setSvFromPointer(t,!0)}}_svPointerMove(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!1))}_svPointerUp(t){if(t.pointerId===this._activePointerId){t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!0),this._activePointerId=null;try{t.currentTarget.releasePointerCapture(t.pointerId)}catch{}}}_svPointerCancel(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._activePointerId=null,this._cancelQueuedEmit(!0))}_svLostPointerCapture(t){t.pointerId===this._activePointerId&&(this._activePointerId=null,this._cancelQueuedEmit(!0))}_hexInput(t){const e=t.target.value;this._hexDraft=e;const s=da(e),i=s?pa(s):null;if(!s||!i)return void(this._hexInvalid=this._hexNeedsValidInput);this._hexNeedsValidInput=!1,this._hexInvalid=!1;const o=ua(i);o.s>1e-4&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._emit(s,this.opacity,!0)}_commitHex(){const t=da(this._hexDraft);if(!t)return this._hexDraft=this._lastValidColor,this._hexInvalid=!0,void(this._hexNeedsValidInput=!0);this._hexDraft=t,this._hexNeedsValidInput?this._hexInvalid=!0:(this._hexInvalid=!1,t!==this._lastValidColor&&this._emit(t,this.opacity))}_confirm(t){t.preventDefault(),t.stopPropagation(),this._commitHex(),this._hexInvalid||this._hexNeedsValidInput?this.updateComplete.then(()=>{this._surface()?.querySelector('input[type="text"]')?.focus()}):this._closePicker(!0)}_hexKeyDown(t){"Enter"===t.key&&(t.preventDefault(),t.stopPropagation(),this._commitHex())}_emit(t,e,s=!1){const i=da(t)||this._lastValidColor,o=Number.isFinite(e)?e:Number(this.opacity)||0,a=Math.min(1,Math.max(0,o));this.color=i,this.opacity=a,this._lastValidColor=i,s||(this._hexDraft=i),this._hexInvalid=this._hexNeedsValidInput,this.dispatchEvent(new CustomEvent("hp-color-opacity-change",{detail:{color:i,opacity:a},bubbles:!0,composed:!0}))}_pickerTemplate(t){const e=Math.round(100*Math.min(1,Math.max(0,Number(this.opacity)||0))),s=_a({h:this._hue,s:this._saturation,v:this._value}),i=_a({h:this._hue,s:100,v:100}),o=this._labels(),a=Math.round(this._hue),n=Math.round(this._saturation),r=Math.round(this._value);return p` `}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),s=this._renderedContext,i=e?.dataset.contextId||"";if(i&&s&&i!==s&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=i,s&&i!==s&&this._focusOwned){const s=i?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");s?.focus?.(),this._focusOwned=!!i}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const o=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);o&&null!==o.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(_c(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const s=_c(t,t=>t.classList.contains("editor-secondary")),i=_c(t,t=>!!t.dataset.editorGroup),o=_c(t,t=>!!t.dataset.editorPalette),a=_c(t,t=>t.classList.contains("stage"));if(!(s||i||o||"stay-open-on-canvas"===e?.dismissPolicy&&a))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,s){if(t.id!==this._openGroupId)return;const i=t.items.find(t=>t.id===e);if(!i||i.disabled)return;const o="toggle"===i.role&&"stay-open"===i.closePolicy,a=0===s.detail;o||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),i.invoke(),!o&&a&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const s=e.indexOf(this.host.root().activeElement),i="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?s<=0?e.length-1:s-1:(s+1)%e.length;e[i]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const gc=t=>t.stopPropagation(),fc=new WeakSet,bc=t=>{t._regSignature="",t._maybeRebuildDevices(),t.requestUpdate()};async function vc(t,e,s,i,o,a=""){const n=t.host,r=n._serverCfg;if(!r)return!1;let l=JSON.parse(JSON.stringify(r));l.markers=l.markers||[];let h=l.markers.find(t=>t.id===e);if(!h){const t=n._devices.find(t=>t.id===e);if(!t||"device"!==t.bindingKind&&"entity"!==t.bindingKind||!t.bindingRef)return!1;h={id:t.id,binding:`${t.bindingKind}:${t.bindingRef}`,space:t.space||null,area:t.area||null,hidden:!!t.hidden},l.markers.push(h)}h.vacuum=function(t,e){const s=e.matrix.map(t=>Number(t.toFixed(6))),i=t?.map_routes;if(Array.isArray(i)&&i.length){const o=i.find(t=>t.id===e.routeId)||i.find(t=>t.source===e.source&&t.map_id===e.mapId);if(o)return{...t,map_routes:Eo(i,o.id,s)}}return{...t,source:e.source,calibration:{...t?.calibration||{},[e.mapId]:s}}}(h.vacuum||{},{source:s,mapId:i,routeId:a,matrix:o}),l=t._prepareConfigCandidate(l);const c=n._adoption.beginOptimistic(r,l);n._adoption.stageLocalConfig(l),bc(n),n._saveConfigDebounced.pending()&&n._saveConfigDebounced.cancel();try{return await t._saveConfigNow(c),!0}catch(t){return n._rollbackOptimistic(c),bc(n),n._showToast(n._t("toast.cfg_save_failed",{err:n._errText(t)})),!1}}function yc(t){return 1===t}function $c(t){return`${t}-${globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`}function wc(t){const e=function(t){return JSON.stringify({message:t.message.trim(),contact:t.contact.trim(),previewToken:t.attach&&t.preview?t.preview.token:""})}(t);return{idempotencyKey:t.submissionFingerprint&&t.submissionFingerprint!==e?$c("report"):t.idempotencyKey,fingerprint:e}}function kc(t){return[...t].length}function xc(t,e=Date.now()){const s=t.message.trim();return s?kc(s)>1e4?"message_too_long":kc(t.contact.trim())>320?"contact_too_long":t.attach&&!t.preview?"preview_missing":t.attach&&t.preview.expiresAt<=e?"preview_expired":null:"message_required"}function Sc(t,e=Date.now()){return"building"!==t.status&&"sending"!==t.status&&"success"!==t.status&&null===xc(t,e)}function Mc(t){const e=function(t){const e=/Firefox\/(\d+)/i.exec(t);if(e)return{family:"firefox",major:Number(e[1])||0};const s=/(?:Chrome|Chromium|Edg)\/(\d+)/i.exec(t);if(s)return{family:"chromium",major:Number(s[1])||0};const i=/Version\/(\d+).+Safari\//i.exec(t);return i?{family:"webkit",major:Number(i[1])||0}:{family:"unknown",major:0}}(t.userAgent??globalThis.navigator?.userAgent??""),s=t.now??Date.now(),i=Number(t.registryLastSuccess||0),o=i<=0?"unknown":s-i<=6e5?"fresh":"stale",a=["en","ru","de","fr"].includes(t.language)?t.language:"en",n=globalThis.matchMedia?.bind(globalThis);return{browser_family:e.family,browser_major:Math.max(0,Math.min(999,e.major)),language:a,coarse_pointer:t.coarsePointer??!!n?.("(pointer: coarse)").matches,hover_capable:t.hoverCapable??!!n?.("(hover: hover)").matches,registry_access:"full"===t.registryAccess?"full":"limited"===t.registryAccess?"partial":"unavailable",registry_age_bucket:o}}function Cc(t){const e=t&&"object"==typeof t&&"code"in t?String(t.code||""):"";return new Set(["support_invalid_message","support_preview_expired","support_package_too_large","support_rate_limited","support_unavailable","support_rejected","unauthorized"]).has(e)?e:"support_unavailable"}const Pc=[{id:"air_conditioner",group:"appliance",art:{d:"M20.5 39h69a2.5 2.5 0 0 1 2.5 2.5V69a2.5 2.5 0 0 1-2.5 2.5h-69A2.5 2.5 0 0 1 18 69V41.5a2.5 2.5 0 0 1 2.5-2.5 M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v8.5H25z M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v3.5H25z",viewW:110,viewH:110}},{id:"armchair",group:"furniture",art:{d:"M42.5 29h25a10 10 0 0 1 10 10v26.5a10 10 0 0 1-10 10h-25a10 10 0 0 1-10-10V39a10 10 0 0 1 10-10 M77.5 48.5a6 6 0 0 1 2 11.657V71.5a4 4 0 0 1-4 4H34a4 4 0 0 1-4-4V60.157A6.001 6.001 0 0 1 32 48.5a6 6 0 0 1 5.419 3.424A4 4 0 0 1 38 54v7h33.5v-6.5q0-.107.005-.213A6 6 0 0 1 77.5 48.5 M42.75 57h24.5A4.75 4.75 0 0 1 72 61.75a4.75 4.75 0 0 1-4.75 4.75h-24.5A4.75 4.75 0 0 1 38 61.75 4.75 4.75 0 0 1 42.75 57M36.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 41.392 82H38a1.5 1.5 0 0 1-1.5-1.5zm36 0h-8l1.674 5.441A1.5 1.5 0 0 0 67.608 82H71a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"bathtub",group:"sanitary",art:{d:"M28 75h8l-1.674 5.441a1.5 1.5 0 0 1-1.434 1.059H29.5A1.5 1.5 0 0 1 28 80zm53 0h-8l1.674 5.441a1.5 1.5 0 0 0 1.434 1.059H79.5A1.5 1.5 0 0 0 81 80zM19.5 46.5H90a2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5H19.5A2.5 2.5 0 0 1 17 49a2.5 2.5 0 0 1 2.5-2.5 M19.5 51.5H90L86.633 68a10 10 0 0 1-9.798 8h-44.17a10 10 0 0 1-9.798-8zM30 36v-2a5 5 0 1 0-10 0v12.5",viewW:110,viewH:110}},{id:"bed",group:"furniture",art:{d:"M16 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 20.892 82H17.5a1.5 1.5 0 0 1-1.5-1.5zm78.5 0h-8l1.674 5.441A1.5 1.5 0 0 0 89.608 82H93a1.5 1.5 0 0 0 1.5-1.5zM25 29h60.5a2.5 2.5 0 0 1 2.5 2.5V68a2.5 2.5 0 0 1-2.5 2.5H25a2.5 2.5 0 0 1-2.5-2.5V31.5A2.5 2.5 0 0 1 25 29 M16 59.5c0-5.523 4.477-10 10-10h58.5c5.523 0 10 4.477 10 10v6H16zm-1 6h80.5a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H15a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1m15.5-20a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4h-21zm28.5 0a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4H59z",viewW:110,viewH:110}},{id:"bidet",group:"sanitary",art:{d:"M36 57.5c0 5.523 4.477 10 10 10h18.5c5.523 0 10-4.477 10-10V53H36zm8.5 22a1 1 0 0 0 1 1H65a1 1 0 0 0 1-1v-12H44.5zm-8.5-32a1 1 0 0 1 1-1h36.5a1 1 0 0 1 1 1V53H36zM50.5 41a1 1 0 0 1 1-1H59a1 1 0 0 1 1 1v5.5h-9.5zM53 30a1 1 0 0 1 1-1h2.5a1 1 0 0 1 1 1v10H53zm-4 6a1 1 0 0 1-1-1v-2.5a1 1 0 0 1 1-1h4V36z",viewW:110,viewH:110}},{id:"boiler",group:"appliance",art:{d:"M46.5 81.5h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zm12.5 0h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zM44 23h22.5a8 8 0 0 1 8 8v42.5a8 8 0 0 1-8 8H44a8 8 0 0 1-8-8V31a8 8 0 0 1 8-8 M36 31a8 8 0 0 1 8-8h22.5a8 8 0 0 1 8 8v42H36z M48.5 42.5a7 7 0 1 0 14 0 7 7 0 1 0-14 0m6.5 0 3.5-3.5",viewW:110,viewH:110}},{id:"chair",group:"furniture",art:{d:"M40.5 39.5C40.5 32.596 46.096 27 53 27h4c6.904 0 12.5 5.596 12.5 12.5v13a5 5 0 0 1-5 5h-19a5 5 0 0 1-5-5z M41.25 54h27.5A3.25 3.25 0 0 1 72 57.25a3.25 3.25 0 0 1-3.25 3.25h-27.5A3.25 3.25 0 0 1 38 57.25 3.25 3.25 0 0 1 41.25 54m28.25 6.5H64l1.88 21.63a1.5 1.5 0 0 0 1.495 1.37H68a1.5 1.5 0 0 0 1.5-1.5zm-29 0H46l-1.88 21.63a1.5 1.5 0 0 1-1.495 1.37H42a1.5 1.5 0 0 1-1.5-1.5z",viewW:110,viewH:110}},{id:"coffee_table",group:"furniture",art:{d:"M25 51h5.238l-1.534 15.646A1.5 1.5 0 0 1 27.211 68H26.5a1.5 1.5 0 0 1-1.5-1.5zm60.238 0H80l1.534 15.646A1.5 1.5 0 0 0 83.027 68h.711a1.5 1.5 0 0 0 1.5-1.5z M24.34 43.485A2.5 2.5 0 0 1 26.625 42h56.75a2.5 2.5 0 0 1 2.285 1.485l2.715 6.109A1 1 0 0 1 87.461 51H22.54a1 1 0 0 1-.914-1.406z M87.5 51h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"computer",group:"appliance",art:{d:"M24.5 38h40a2.5 2.5 0 0 1 2.5 2.5v22a2.5 2.5 0 0 1-2.5 2.5h-40a2.5 2.5 0 0 1-2.5-2.5v-22a2.5 2.5 0 0 1 2.5-2.5m50 0h11a2.5 2.5 0 0 1 2.5 2.5v29a2.5 2.5 0 0 1-2.5 2.5h-11a2.5 2.5 0 0 1-2.5-2.5v-29a2.5 2.5 0 0 1 2.5-2.5M43 65h5v7h-5zm-6 7h16m23-12h8m-8-17h8 M35 56V46h5m-5 7h5 M39.5 53a3.5 3.5 0 1 0 0-7m15.036 8.536a5 5 0 1 1 0-7.071",viewW:110,viewH:110}},{id:"cooktop",group:"appliance",art:{d:"M27.5 29h55a2.5 2.5 0 0 1 2.5 2.5v47a2.5 2.5 0 0 1-2.5 2.5h-55a2.5 2.5 0 0 1-2.5-2.5v-47a2.5 2.5 0 0 1 2.5-2.5 M33.5 66.5a8 8 0 1 0 16 0 8 8 0 1 0-16 0m26.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0m3 23a5 5 0 1 0 10 0 5 5 0 1 0-10 0m-29.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0",viewW:110,viewH:110}},{id:"dining_table",group:"furniture",art:{d:"M83.5 43H78l6.742 30.82A1.5 1.5 0 0 0 86.207 75h.54a1.5 1.5 0 0 0 1.482-1.732zm-56 0H33l-6.742 30.82A1.5 1.5 0 0 1 24.793 75h-.54a1.5 1.5 0 0 1-1.482-1.732zm-2.62-7.406A2.5 2.5 0 0 1 27.21 34h56.58a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044A1 1 0 0 1 87.538 43H23.462a1 1 0 0 1-.932-1.362z M88.5 43h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"dishwasher",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5M43 42h24m-1.5-11a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"dryer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5 M55.994 55.5s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m5.979-11s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m-8.519-11s-.886 1.81-.986 3.143c-.132 1.761 1.066 2.554.986 4.321-.067 1.479-.986 3.536-.986 3.536",viewW:110,viewH:110}},{id:"exercise",group:"other",art:{d:"m60.752 62.03-5.379-2.312 11.066-25.75a1.5 1.5 0 0 1 1.97-.786l2.624 1.127a1.5 1.5 0 0 1 .786 1.97zm-18.648-4.512-4.353 1.189-4.474-16.382a1.5 1.5 0 0 1 1.052-1.842l1.459-.398a1.5 1.5 0 0 1 1.842 1.052z M41.297 38.173a2.215 2.215 0 0 1 0 4.43H29.781a2.215 2.215 0 0 1 0-4.43zm33.219 38.091a2.657 2.657 0 1 1 0 5.315H28.453a2.657 2.657 0 1 1 0-5.315zm8.641-51.366a1.795 1.795 0 0 1 .68 2.41l-3.03 5.59a5 5 0 0 1-4.396 2.618H65.657a1.772 1.772 0 1 1 0-3.544h9.61a3 3 0 0 0 2.598-1.5l2.84-4.917a1.795 1.795 0 0 1 2.452-.657M29.339 65.787c0-6.699 6.457-11.503 12.873-9.579l24.291 7.288a10 10 0 0 1 7.127 9.578v3.19H29.339zm0 15.852h7.086l-1.394 3.486a1.5 1.5 0 0 1-1.393.943h-2.8a1.5 1.5 0 0 1-1.5-1.5zm44.291 0h-7.087l1.395 3.486a1.5 1.5 0 0 0 1.392.943h2.8a1.5 1.5 0 0 0 1.5-1.5z M35.54 66.077a4.872 4.872 0 1 0 9.743 0 4.872 4.872 0 1 0-9.744 0",viewW:110,viewH:110}},{id:"fireplace",group:"other",art:{d:"M26.672 34.425h55.99v39.47h-55.99Z M23 74.894a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v5.802a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zM23 29a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v4.425a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zm15.145 21.44a5 5 0 0 1 5-5h23.043a5 5 0 0 1 5 5v23.454H38.145z M44.57 65.633a2.754 2.754 0 0 1 2.754-2.753H62.01v5.507H47.324a2.754 2.754 0 0 1-2.754-2.754m20.194 5.507a2.754 2.754 0 0 0-2.754-2.753H47.324v5.507H62.01a2.754 2.754 0 0 0 2.754-2.754 M44.57 71.14a2.754 2.754 0 1 0 5.508 0 2.754 2.754 0 1 0-5.508 0m14.688-5.507a2.754 2.754 0 1 0 5.507 0 2.754 2.754 0 1 0-5.507 0",viewW:110,viewH:110}},{id:"fridge",group:"appliance",art:{d:"M35.5 18H75a2.5 2.5 0 0 1 2.5 2.5v64A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5v-64a2.5 2.5 0 0 1 2.5-2.5 M33 46.5h44.5v38A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5zm2.5 44a1 1 0 0 0 1 1h37a1 1 0 0 0 1-1V87h-39zm3-49.5v-9.5m0 30.5v-9.5",viewW:110,viewH:110}},{id:"hood",group:"appliance",art:{d:"M44.308 57h21.384L83 69H27zM44 37.5a2.5 2.5 0 0 1 2.5-2.5h17a2.5 2.5 0 0 1 2.5 2.5V57H44zM80.5 74h-51a2.5 2.5 0 0 1-2.5-2.5V70a1 1 0 0 1 1-1h54a1 1 0 0 1 1 1v1.5a2.5 2.5 0 0 1-2.5 2.5",viewW:110,viewH:110}},{id:"kitchen_cabinet",group:"furniture",art:{d:"M38 88a1 1 0 0 0 1 1h32a1 1 0 0 0 1-1v-3H38zm17-68h16.5a2.5 2.5 0 0 1 2.5 2.5v17a2.5 2.5 0 0 1-2.5 2.5H55zm-19 2.5a2.5 2.5 0 0 1 2.5-2.5H55v22H38.5a2.5 2.5 0 0 1-2.5-2.5zM59 33v5m-8-5v5m4 47h16.5a2.5 2.5 0 0 0 2.5-2.5v-17a2.5 2.5 0 0 0-2.5-2.5H55zm-19-2.5a2.5 2.5 0 0 0 2.5 2.5H55V63H38.5a2.5 2.5 0 0 0-2.5 2.5zM67 67h-5m-14 0h-5",viewW:110,viewH:110}},{id:"kitchen_sink",group:"sanitary",art:{d:"M21.5 84h68a2.5 2.5 0 0 0 2.5-2.5v-35a2.5 2.5 0 0 0-2.5-2.5h-68a2.5 2.5 0 0 0-2.5 2.5v35a2.5 2.5 0 0 0 2.5 2.5 M26 78h26.5a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H26a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m23-24v5m9.5 19H85a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H58.5a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m-6-39.5a1 1 0 0 0-1-1H44a1 1 0 0 0-1 1V44h9.5zM58 33v-2a5 5 0 1 0-10 0v6.5M62 54v5",viewW:110,viewH:110}},{id:"nightstand",group:"furniture",art:{d:"M76.5 73.5h-8l1.674 5.441A1.5 1.5 0 0 0 71.608 80H75a1.5 1.5 0 0 0 1.5-1.5zm-42.5 0h8l-1.674 5.441A1.5 1.5 0 0 1 38.892 80H35.5a1.5 1.5 0 0 1-1.5-1.5z M34.5 30.5h41A2.5 2.5 0 0 1 78 33v40.5a2.5 2.5 0 0 1-2.5 2.5h-41a2.5 2.5 0 0 1-2.5-2.5V33a2.5 2.5 0 0 1 2.5-2.5 M32 39.5h46v18H32Zm18.5 9H60M50.5 66H60",viewW:110,viewH:110}},{id:"oven",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5 M40.5 47h29a2.5 2.5 0 0 1 2.5 2.5v20a2.5 2.5 0 0 1-2.5 2.5h-29a2.5 2.5 0 0 1-2.5-2.5v-20a2.5 2.5 0 0 1 2.5-2.5m25-16a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5M43 42h24",viewW:110,viewH:110}},{id:"plant",group:"other",art:{d:"M45.952 75.849a2.5 2.5 0 0 0 2.485 2.231H63.43a2.5 2.5 0 0 0 2.485-2.231l1.571-14.532H44.381zM60.236 44.78C58.423 36.174 66.805 29.605 77 31.87c0 8.155-8.609 16.763-16.763 12.912m-9.761 5.147c1.517-8.665-7.085-14.943-17.195-12.33.28 8.15 9.178 16.458 17.195 12.33 M55.706 55.88v-2.944m0 0c1.133-5.89 7.09-10.956 12.912-15.404M55.706 52.936c-4.938-4.146-7.982-6.16-14.044-9.061m1.453 12.005h25.636a1 1 0 0 1 1 1v3.437a1 1 0 0 1-1 1H43.115a1 1 0 0 1-1-1v-3.436a1 1 0 0 1 1-1",viewW:110,viewH:110}},{id:"rug",group:"other",art:{d:"M90.27 33.874h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.154h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20M28.12 32h54.025a2.5 2.5 0 0 1 2.5 2.5v40.439a2.5 2.5 0 0 1-2.5 2.5H28.12a2.5 2.5 0 0 1-2.5-2.5V34.5a2.5 2.5 0 0 1 2.5-2.5 M25.62 34.5a2.5 2.5 0 0 1 2.5-2.5h1.717v45.439H28.12a2.5 2.5 0 0 1-2.5-2.5zm59.026 0a2.5 2.5 0 0 0-2.5-2.5H80.43v45.439h1.716a2.5 2.5 0 0 0 2.5-2.5zM37.8 54.485l17.801-8.432 17.801 8.432-17.8 8.432z",viewW:110,viewH:110}},{id:"shelving",group:"furniture",art:{d:"M28 58.5h53V39H28Z M64 58.5h5V47a1 1 0 0 0-1-1h-3a1 1 0 0 0-1 1zM52.5 39h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-12 0h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-5 29.5V71a1 1 0 0 1 1 1H49a1 1 0 0 1 1-1v-2.5a1 1 0 0 1-1-1H36.5a1 1 0 0 1-1 1m33.5-10h7v-14a1 1 0 0 0-1-1h-5a1 1 0 0 0-1 1zM47.5 39h-7V25a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1zm-12 34v4a1 1 0 0 1 1 1h14a1 1 0 0 1 1-1v-4a1 1 0 0 1-1-1h-14a1 1 0 0 1-1 1M28 78h53v7H28Z M28 89.5V23a2.5 2.5 0 0 1 2.5-2.5h48A2.5 2.5 0 0 1 81 23v66.5",viewW:110,viewH:110}},{id:"shower",group:"sanitary",art:{d:"M31 84h49a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H31a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1m31.5-47.6v-4.686a11.7 11.7 0 0 0-3.441-8.283A11.77 11.77 0 0 0 50.75 20a11.77 11.77 0 0 0-8.309 3.431A11.7 11.7 0 0 0 39 31.714V84 M72 39.25a10.25 10.25 0 1 0-20.5 0zm-17.25 5v2.5m7.25-2.5v2.5m7.25-2.5v2.5m-14.5 3.75V53M62 50.5V53m7.25-2.5V53m-14.5 3.75v2.5m7.25-2.5v2.5m7.25-2.5v2.5M54.75 63v2.5M62 63v2.5m7.25-2.5v2.5",viewW:110,viewH:110}},{id:"sink",group:"sanitary",art:{d:"M30 57c0 5.523 4.477 10 10 10h29.5c5.523 0 10-4.477 10-10v-6.5A2.5 2.5 0 0 0 77 48H32.5a2.5 2.5 0 0 0-2.5 2.5zm14 22a1 1 0 0 0 1 1h19.5a1 1 0 0 0 1-1V67H44zm6-36.5a1 1 0 0 1 1-1h7.5a1 1 0 0 1 1 1V48H50zM45 37v-2a5 5 0 1 1 10 0v6.5",viewW:110,viewH:110}},{id:"sofa",group:"furniture",art:{d:"M59.5 29h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5m-34 0h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5 M18.5 44a5 5 0 0 1 5 5v12H86V49a5 5 0 0 1 5-5h.5a5 5 0 0 1 5 5v21.5a5 5 0 0 1-5 5H18a5 5 0 0 1-5-5V49a5 5 0 0 1 5-5z M25.25 57h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 25.25 57m34 0h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 59.25 57M18.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 23.392 82H20a1.5 1.5 0 0 1-1.5-1.5zm72 0h-8l1.674 5.441A1.5 1.5 0 0 0 85.608 82H89a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"stairs",group:"other",art:{d:"M73.47 46.365v-17.62m-10.571 25.55V36.674M52.326 61.783V45.484M42.193 69.273v-15.86M28.979 77.761a1 1 0 0 1 1-1h53.624v6.489a1 1 0 0 1-1 1H29.98a1 1 0 0 1-1-1z M26.777 57.497a1 1 0 0 1 1-1h2.846a1 1 0 0 1 1 1V83.25a1 1 0 0 1-1 1h-2.846a1 1 0 0 1-1-1z m73.113 28.633-41.492 32.93v-4.405l39.9-32.007a.7.7 0 0 1 .428-.151h3.724a1.762 1.762 0 1 1 0 3.524h-2.248a.5.5 0 0 0-.312.109M25.895 53.414a3.084 3.084 0 1 0 6.167 0 3.084 3.084 0 1 0-6.167 0m14.978 16.859a1 1 0 0 1 1-1h41.73v7.488h-42.73zm10.131-7.489a1 1 0 0 1 1-1h31.598v7.488H51.004z M61.576 55.294a1 1 0 0 1 1-1h21.026v7.49H61.576z M72.15 47.806a1 1 0 0 1 1-1h9.454a1 1 0 0 1 1 1v6.489H72.15z",viewW:110,viewH:110}},{id:"toilet",group:"sanitary",art:{d:"M32 26.5a2.5 2.5 0 0 1 2.5-2.5H45a2.5 2.5 0 0 1 2.5 2.5V57H32zM47.5 52h29a2.5 2.5 0 0 1 2.5 2.5V57H47.5zm17.037 20.102C73.95 70.288 79 62.01 79 57H32c.5 7.5 8.072 7 7 11l-2.342 16.862a1 1 0 0 0 .99 1.138H66.72a1 1 0 0 0 .97-1.243z",viewW:110,viewH:110}},{id:"tv",group:"appliance",art:{d:"M23.5 31H86a2.5 2.5 0 0 1 2.5 2.5v34A2.5 2.5 0 0 1 86 70H23.5a2.5 2.5 0 0 1-2.5-2.5v-34a2.5 2.5 0 0 1 2.5-2.5M50 70h9.5v8H50Zm-10 8h30M42.5 45.5h5m5 0h-5m0 0v9.75 m56.75 45.5 5 10 5-10",viewW:110,viewH:110}},{id:"wardrobe",group:"furniture",art:{d:"M28 23a2.5 2.5 0 0 1 2.5-2.5h24V85h-24a2.5 2.5 0 0 1-2.5-2.5zm2 65.5a1 1 0 0 0 1 1h47a1 1 0 0 0 1-1V85H30zM81 23a2.5 2.5 0 0 0-2.5-2.5h-24V85h24a2.5 2.5 0 0 0 2.5-2.5zM50.5 48v9.5m8-9.5v9.5",viewW:110,viewH:110}},{id:"washer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"work_table",group:"furniture",art:{d:"M88.5 47h-20v14h20zm-12 4h4m7.984-8h-66v4h66zm-66 4h4v26.5a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5z M24.866 35.597A2.5 2.5 0 0 1 27.197 34h56.577a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044a1 1 0 0 1-.93 1.362H23.46a1 1 0 0 1-.933-1.361zM88.5 61h-20v12.5A1.5 1.5 0 0 0 70 75h17a1.5 1.5 0 0 0 1.5-1.5zm-12 4h4",viewW:110,viewH:110}}];class Dc{constructor(t,e){this.host=t,this.hooks=e}place(t,e="mouse"){const s=this.host._decorImagePalette,i=this.host._curSpaceCfg;if(!s||!i)return;const o=this.hooks.decorSnap(t,e),a=jt(s.width,s.height),n=Gt(a.w,this.host._cellCm,this.host._gridPitch)/m,r=Gt(a.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,l="di"+Date.now().toString(36)+Math.random().toString(36).slice(2,5),h=this.hooks.geometrySnapshot();i.decor=[...this.host._decorList,{id:l,kind:"image",asset_id:s.asset_id,x:Z(o[0]/m-n/2),y:Z(o[1]/this.host._decorH-r/2),w:n,h:r,opacity:1}],this.host._decorSel=l,this.host._decorTool="select",this.host._decorImagePalette=null,this.hooks.clearFurniturePreview(),this.hooks.recordGeometry(this.host._t("history.decor_add"),h),this.hooks.saveConfig(),this.host.requestUpdate()}renderPlacementPreview(){const t=this.host._furnPreviewInput,e=this.host._decorImagePalette;if(!t||!e||"decor"!==this.host._mode||"image"!==this.host._decorTool||!this.host._pointerModality.hoverEnabled)return d;const s=this.hooks.decorSnap(t.raw,"mouse"),i=jt(e.width,e.height),o=Gt(i.w,this.host._cellCm,this.host._gridPitch)/m,a=Gt(i.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,n=this.host._display(e.url);return n?_``}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),s=this._renderedContext,i=e?.dataset.contextId||"";if(i&&s&&i!==s&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=i,s&&i!==s&&this._focusOwned){const s=i?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");s?.focus?.(),this._focusOwned=!!i}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const o=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);o&&null!==o.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(mc(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const s=mc(t,t=>t.classList.contains("editor-secondary")),i=mc(t,t=>!!t.dataset.editorGroup),o=mc(t,t=>!!t.dataset.editorPalette),a=mc(t,t=>t.classList.contains("stage"));if(!(s||i||o||"stay-open-on-canvas"===e?.dismissPolicy&&a))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,s){if(t.id!==this._openGroupId)return;const i=t.items.find(t=>t.id===e);if(!i||i.disabled)return;const o="toggle"===i.role&&"stay-open"===i.closePolicy,a=0===s.detail;o||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),i.invoke(),!o&&a&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const s=e.indexOf(this.host.root().activeElement),i="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?s<=0?e.length-1:s-1:(s+1)%e.length;e[i]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const fc=t=>t.stopPropagation(),bc=new WeakSet,vc=t=>{t._regSignature="",t._maybeRebuildDevices(),t.requestUpdate()};async function yc(t,e,s,i,o,a=""){const n=t.host,r=n._serverCfg;if(!r)return!1;let l=JSON.parse(JSON.stringify(r));l.markers=l.markers||[];let h=l.markers.find(t=>t.id===e);if(!h){const t=n._devices.find(t=>t.id===e);if(!t||"device"!==t.bindingKind&&"entity"!==t.bindingKind||!t.bindingRef)return!1;h={id:t.id,binding:`${t.bindingKind}:${t.bindingRef}`,space:t.space||null,area:t.area||null,hidden:!!t.hidden},l.markers.push(h)}h.vacuum=function(t,e){const s=e.matrix.map(t=>Number(t.toFixed(6))),i=t?.map_routes;if(Array.isArray(i)&&i.length){const o=i.find(t=>t.id===e.routeId)||i.find(t=>t.source===e.source&&t.map_id===e.mapId);if(o)return{...t,map_routes:Ho(i,o.id,s)}}return{...t,source:e.source,calibration:{...t?.calibration||{},[e.mapId]:s}}}(h.vacuum||{},{source:s,mapId:i,routeId:a,matrix:o}),l=t._prepareConfigCandidate(l);const c=n._adoption.beginOptimistic(r,l);n._adoption.stageLocalConfig(l),vc(n),n._saveConfigDebounced.pending()&&n._saveConfigDebounced.cancel();try{return await t._saveConfigNow(c),!0}catch(t){return n._rollbackOptimistic(c),vc(n),n._showToast(n._t("toast.cfg_save_failed",{err:n._errText(t)})),!1}}function $c(t){return 1===t}function wc(t){return`${t}-${globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`}function kc(t){const e=function(t){return JSON.stringify({message:t.message.trim(),contact:t.contact.trim(),previewToken:t.attach&&t.preview?t.preview.token:""})}(t);return{idempotencyKey:t.submissionFingerprint&&t.submissionFingerprint!==e?wc("report"):t.idempotencyKey,fingerprint:e}}function xc(t){return[...t].length}function Sc(t,e=Date.now()){const s=t.message.trim();return s?xc(s)>1e4?"message_too_long":xc(t.contact.trim())>320?"contact_too_long":t.attach&&!t.preview?"preview_missing":t.attach&&t.preview.expiresAt<=e?"preview_expired":null:"message_required"}function Mc(t,e=Date.now()){return"building"!==t.status&&"sending"!==t.status&&"success"!==t.status&&null===Sc(t,e)}function Cc(t){const e=function(t){const e=/Firefox\/(\d+)/i.exec(t);if(e)return{family:"firefox",major:Number(e[1])||0};const s=/(?:Chrome|Chromium|Edg)\/(\d+)/i.exec(t);if(s)return{family:"chromium",major:Number(s[1])||0};const i=/Version\/(\d+).+Safari\//i.exec(t);return i?{family:"webkit",major:Number(i[1])||0}:{family:"unknown",major:0}}(t.userAgent??globalThis.navigator?.userAgent??""),s=t.now??Date.now(),i=Number(t.registryLastSuccess||0),o=i<=0?"unknown":s-i<=6e5?"fresh":"stale",a=["en","ru","de","fr"].includes(t.language)?t.language:"en",n=globalThis.matchMedia?.bind(globalThis);return{browser_family:e.family,browser_major:Math.max(0,Math.min(999,e.major)),language:a,coarse_pointer:t.coarsePointer??!!n?.("(pointer: coarse)").matches,hover_capable:t.hoverCapable??!!n?.("(hover: hover)").matches,registry_access:"full"===t.registryAccess?"full":"limited"===t.registryAccess?"partial":"unavailable",registry_age_bucket:o}}function Pc(t){const e=t&&"object"==typeof t&&"code"in t?String(t.code||""):"";return new Set(["support_invalid_message","support_preview_expired","support_package_too_large","support_rate_limited","support_unavailable","support_rejected","unauthorized"]).has(e)?e:"support_unavailable"}const Dc=[{id:"air_conditioner",group:"appliance",art:{d:"M20.5 39h69a2.5 2.5 0 0 1 2.5 2.5V69a2.5 2.5 0 0 1-2.5 2.5h-69A2.5 2.5 0 0 1 18 69V41.5a2.5 2.5 0 0 1 2.5-2.5 M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v8.5H25z M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v3.5H25z",viewW:110,viewH:110}},{id:"armchair",group:"furniture",art:{d:"M42.5 29h25a10 10 0 0 1 10 10v26.5a10 10 0 0 1-10 10h-25a10 10 0 0 1-10-10V39a10 10 0 0 1 10-10 M77.5 48.5a6 6 0 0 1 2 11.657V71.5a4 4 0 0 1-4 4H34a4 4 0 0 1-4-4V60.157A6.001 6.001 0 0 1 32 48.5a6 6 0 0 1 5.419 3.424A4 4 0 0 1 38 54v7h33.5v-6.5q0-.107.005-.213A6 6 0 0 1 77.5 48.5 M42.75 57h24.5A4.75 4.75 0 0 1 72 61.75a4.75 4.75 0 0 1-4.75 4.75h-24.5A4.75 4.75 0 0 1 38 61.75 4.75 4.75 0 0 1 42.75 57M36.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 41.392 82H38a1.5 1.5 0 0 1-1.5-1.5zm36 0h-8l1.674 5.441A1.5 1.5 0 0 0 67.608 82H71a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"bathtub",group:"sanitary",art:{d:"M28 75h8l-1.674 5.441a1.5 1.5 0 0 1-1.434 1.059H29.5A1.5 1.5 0 0 1 28 80zm53 0h-8l1.674 5.441a1.5 1.5 0 0 0 1.434 1.059H79.5A1.5 1.5 0 0 0 81 80zM19.5 46.5H90a2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5H19.5A2.5 2.5 0 0 1 17 49a2.5 2.5 0 0 1 2.5-2.5 M19.5 51.5H90L86.633 68a10 10 0 0 1-9.798 8h-44.17a10 10 0 0 1-9.798-8zM30 36v-2a5 5 0 1 0-10 0v12.5",viewW:110,viewH:110}},{id:"bed",group:"furniture",art:{d:"M16 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 20.892 82H17.5a1.5 1.5 0 0 1-1.5-1.5zm78.5 0h-8l1.674 5.441A1.5 1.5 0 0 0 89.608 82H93a1.5 1.5 0 0 0 1.5-1.5zM25 29h60.5a2.5 2.5 0 0 1 2.5 2.5V68a2.5 2.5 0 0 1-2.5 2.5H25a2.5 2.5 0 0 1-2.5-2.5V31.5A2.5 2.5 0 0 1 25 29 M16 59.5c0-5.523 4.477-10 10-10h58.5c5.523 0 10 4.477 10 10v6H16zm-1 6h80.5a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H15a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1m15.5-20a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4h-21zm28.5 0a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4H59z",viewW:110,viewH:110}},{id:"bidet",group:"sanitary",art:{d:"M36 57.5c0 5.523 4.477 10 10 10h18.5c5.523 0 10-4.477 10-10V53H36zm8.5 22a1 1 0 0 0 1 1H65a1 1 0 0 0 1-1v-12H44.5zm-8.5-32a1 1 0 0 1 1-1h36.5a1 1 0 0 1 1 1V53H36zM50.5 41a1 1 0 0 1 1-1H59a1 1 0 0 1 1 1v5.5h-9.5zM53 30a1 1 0 0 1 1-1h2.5a1 1 0 0 1 1 1v10H53zm-4 6a1 1 0 0 1-1-1v-2.5a1 1 0 0 1 1-1h4V36z",viewW:110,viewH:110}},{id:"boiler",group:"appliance",art:{d:"M46.5 81.5h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zm12.5 0h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zM44 23h22.5a8 8 0 0 1 8 8v42.5a8 8 0 0 1-8 8H44a8 8 0 0 1-8-8V31a8 8 0 0 1 8-8 M36 31a8 8 0 0 1 8-8h22.5a8 8 0 0 1 8 8v42H36z M48.5 42.5a7 7 0 1 0 14 0 7 7 0 1 0-14 0m6.5 0 3.5-3.5",viewW:110,viewH:110}},{id:"chair",group:"furniture",art:{d:"M40.5 39.5C40.5 32.596 46.096 27 53 27h4c6.904 0 12.5 5.596 12.5 12.5v13a5 5 0 0 1-5 5h-19a5 5 0 0 1-5-5z M41.25 54h27.5A3.25 3.25 0 0 1 72 57.25a3.25 3.25 0 0 1-3.25 3.25h-27.5A3.25 3.25 0 0 1 38 57.25 3.25 3.25 0 0 1 41.25 54m28.25 6.5H64l1.88 21.63a1.5 1.5 0 0 0 1.495 1.37H68a1.5 1.5 0 0 0 1.5-1.5zm-29 0H46l-1.88 21.63a1.5 1.5 0 0 1-1.495 1.37H42a1.5 1.5 0 0 1-1.5-1.5z",viewW:110,viewH:110}},{id:"coffee_table",group:"furniture",art:{d:"M25 51h5.238l-1.534 15.646A1.5 1.5 0 0 1 27.211 68H26.5a1.5 1.5 0 0 1-1.5-1.5zm60.238 0H80l1.534 15.646A1.5 1.5 0 0 0 83.027 68h.711a1.5 1.5 0 0 0 1.5-1.5z M24.34 43.485A2.5 2.5 0 0 1 26.625 42h56.75a2.5 2.5 0 0 1 2.285 1.485l2.715 6.109A1 1 0 0 1 87.461 51H22.54a1 1 0 0 1-.914-1.406z M87.5 51h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"computer",group:"appliance",art:{d:"M24.5 38h40a2.5 2.5 0 0 1 2.5 2.5v22a2.5 2.5 0 0 1-2.5 2.5h-40a2.5 2.5 0 0 1-2.5-2.5v-22a2.5 2.5 0 0 1 2.5-2.5m50 0h11a2.5 2.5 0 0 1 2.5 2.5v29a2.5 2.5 0 0 1-2.5 2.5h-11a2.5 2.5 0 0 1-2.5-2.5v-29a2.5 2.5 0 0 1 2.5-2.5M43 65h5v7h-5zm-6 7h16m23-12h8m-8-17h8 M35 56V46h5m-5 7h5 M39.5 53a3.5 3.5 0 1 0 0-7m15.036 8.536a5 5 0 1 1 0-7.071",viewW:110,viewH:110}},{id:"cooktop",group:"appliance",art:{d:"M27.5 29h55a2.5 2.5 0 0 1 2.5 2.5v47a2.5 2.5 0 0 1-2.5 2.5h-55a2.5 2.5 0 0 1-2.5-2.5v-47a2.5 2.5 0 0 1 2.5-2.5 M33.5 66.5a8 8 0 1 0 16 0 8 8 0 1 0-16 0m26.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0m3 23a5 5 0 1 0 10 0 5 5 0 1 0-10 0m-29.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0",viewW:110,viewH:110}},{id:"dining_table",group:"furniture",art:{d:"M83.5 43H78l6.742 30.82A1.5 1.5 0 0 0 86.207 75h.54a1.5 1.5 0 0 0 1.482-1.732zm-56 0H33l-6.742 30.82A1.5 1.5 0 0 1 24.793 75h-.54a1.5 1.5 0 0 1-1.482-1.732zm-2.62-7.406A2.5 2.5 0 0 1 27.21 34h56.58a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044A1 1 0 0 1 87.538 43H23.462a1 1 0 0 1-.932-1.362z M88.5 43h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"dishwasher",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5M43 42h24m-1.5-11a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"dryer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5 M55.994 55.5s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m5.979-11s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m-8.519-11s-.886 1.81-.986 3.143c-.132 1.761 1.066 2.554.986 4.321-.067 1.479-.986 3.536-.986 3.536",viewW:110,viewH:110}},{id:"exercise",group:"other",art:{d:"m60.752 62.03-5.379-2.312 11.066-25.75a1.5 1.5 0 0 1 1.97-.786l2.624 1.127a1.5 1.5 0 0 1 .786 1.97zm-18.648-4.512-4.353 1.189-4.474-16.382a1.5 1.5 0 0 1 1.052-1.842l1.459-.398a1.5 1.5 0 0 1 1.842 1.052z M41.297 38.173a2.215 2.215 0 0 1 0 4.43H29.781a2.215 2.215 0 0 1 0-4.43zm33.219 38.091a2.657 2.657 0 1 1 0 5.315H28.453a2.657 2.657 0 1 1 0-5.315zm8.641-51.366a1.795 1.795 0 0 1 .68 2.41l-3.03 5.59a5 5 0 0 1-4.396 2.618H65.657a1.772 1.772 0 1 1 0-3.544h9.61a3 3 0 0 0 2.598-1.5l2.84-4.917a1.795 1.795 0 0 1 2.452-.657M29.339 65.787c0-6.699 6.457-11.503 12.873-9.579l24.291 7.288a10 10 0 0 1 7.127 9.578v3.19H29.339zm0 15.852h7.086l-1.394 3.486a1.5 1.5 0 0 1-1.393.943h-2.8a1.5 1.5 0 0 1-1.5-1.5zm44.291 0h-7.087l1.395 3.486a1.5 1.5 0 0 0 1.392.943h2.8a1.5 1.5 0 0 0 1.5-1.5z M35.54 66.077a4.872 4.872 0 1 0 9.743 0 4.872 4.872 0 1 0-9.744 0",viewW:110,viewH:110}},{id:"fireplace",group:"other",art:{d:"M26.672 34.425h55.99v39.47h-55.99Z M23 74.894a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v5.802a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zM23 29a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v4.425a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zm15.145 21.44a5 5 0 0 1 5-5h23.043a5 5 0 0 1 5 5v23.454H38.145z M44.57 65.633a2.754 2.754 0 0 1 2.754-2.753H62.01v5.507H47.324a2.754 2.754 0 0 1-2.754-2.754m20.194 5.507a2.754 2.754 0 0 0-2.754-2.753H47.324v5.507H62.01a2.754 2.754 0 0 0 2.754-2.754 M44.57 71.14a2.754 2.754 0 1 0 5.508 0 2.754 2.754 0 1 0-5.508 0m14.688-5.507a2.754 2.754 0 1 0 5.507 0 2.754 2.754 0 1 0-5.507 0",viewW:110,viewH:110}},{id:"fridge",group:"appliance",art:{d:"M35.5 18H75a2.5 2.5 0 0 1 2.5 2.5v64A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5v-64a2.5 2.5 0 0 1 2.5-2.5 M33 46.5h44.5v38A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5zm2.5 44a1 1 0 0 0 1 1h37a1 1 0 0 0 1-1V87h-39zm3-49.5v-9.5m0 30.5v-9.5",viewW:110,viewH:110}},{id:"hood",group:"appliance",art:{d:"M44.308 57h21.384L83 69H27zM44 37.5a2.5 2.5 0 0 1 2.5-2.5h17a2.5 2.5 0 0 1 2.5 2.5V57H44zM80.5 74h-51a2.5 2.5 0 0 1-2.5-2.5V70a1 1 0 0 1 1-1h54a1 1 0 0 1 1 1v1.5a2.5 2.5 0 0 1-2.5 2.5",viewW:110,viewH:110}},{id:"kitchen_cabinet",group:"furniture",art:{d:"M38 88a1 1 0 0 0 1 1h32a1 1 0 0 0 1-1v-3H38zm17-68h16.5a2.5 2.5 0 0 1 2.5 2.5v17a2.5 2.5 0 0 1-2.5 2.5H55zm-19 2.5a2.5 2.5 0 0 1 2.5-2.5H55v22H38.5a2.5 2.5 0 0 1-2.5-2.5zM59 33v5m-8-5v5m4 47h16.5a2.5 2.5 0 0 0 2.5-2.5v-17a2.5 2.5 0 0 0-2.5-2.5H55zm-19-2.5a2.5 2.5 0 0 0 2.5 2.5H55V63H38.5a2.5 2.5 0 0 0-2.5 2.5zM67 67h-5m-14 0h-5",viewW:110,viewH:110}},{id:"kitchen_sink",group:"sanitary",art:{d:"M21.5 84h68a2.5 2.5 0 0 0 2.5-2.5v-35a2.5 2.5 0 0 0-2.5-2.5h-68a2.5 2.5 0 0 0-2.5 2.5v35a2.5 2.5 0 0 0 2.5 2.5 M26 78h26.5a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H26a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m23-24v5m9.5 19H85a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H58.5a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m-6-39.5a1 1 0 0 0-1-1H44a1 1 0 0 0-1 1V44h9.5zM58 33v-2a5 5 0 1 0-10 0v6.5M62 54v5",viewW:110,viewH:110}},{id:"nightstand",group:"furniture",art:{d:"M76.5 73.5h-8l1.674 5.441A1.5 1.5 0 0 0 71.608 80H75a1.5 1.5 0 0 0 1.5-1.5zm-42.5 0h8l-1.674 5.441A1.5 1.5 0 0 1 38.892 80H35.5a1.5 1.5 0 0 1-1.5-1.5z M34.5 30.5h41A2.5 2.5 0 0 1 78 33v40.5a2.5 2.5 0 0 1-2.5 2.5h-41a2.5 2.5 0 0 1-2.5-2.5V33a2.5 2.5 0 0 1 2.5-2.5 M32 39.5h46v18H32Zm18.5 9H60M50.5 66H60",viewW:110,viewH:110}},{id:"oven",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5 M40.5 47h29a2.5 2.5 0 0 1 2.5 2.5v20a2.5 2.5 0 0 1-2.5 2.5h-29a2.5 2.5 0 0 1-2.5-2.5v-20a2.5 2.5 0 0 1 2.5-2.5m25-16a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5M43 42h24",viewW:110,viewH:110}},{id:"plant",group:"other",art:{d:"M45.952 75.849a2.5 2.5 0 0 0 2.485 2.231H63.43a2.5 2.5 0 0 0 2.485-2.231l1.571-14.532H44.381zM60.236 44.78C58.423 36.174 66.805 29.605 77 31.87c0 8.155-8.609 16.763-16.763 12.912m-9.761 5.147c1.517-8.665-7.085-14.943-17.195-12.33.28 8.15 9.178 16.458 17.195 12.33 M55.706 55.88v-2.944m0 0c1.133-5.89 7.09-10.956 12.912-15.404M55.706 52.936c-4.938-4.146-7.982-6.16-14.044-9.061m1.453 12.005h25.636a1 1 0 0 1 1 1v3.437a1 1 0 0 1-1 1H43.115a1 1 0 0 1-1-1v-3.436a1 1 0 0 1 1-1",viewW:110,viewH:110}},{id:"rug",group:"other",art:{d:"M90.27 33.874h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.154h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20M28.12 32h54.025a2.5 2.5 0 0 1 2.5 2.5v40.439a2.5 2.5 0 0 1-2.5 2.5H28.12a2.5 2.5 0 0 1-2.5-2.5V34.5a2.5 2.5 0 0 1 2.5-2.5 M25.62 34.5a2.5 2.5 0 0 1 2.5-2.5h1.717v45.439H28.12a2.5 2.5 0 0 1-2.5-2.5zm59.026 0a2.5 2.5 0 0 0-2.5-2.5H80.43v45.439h1.716a2.5 2.5 0 0 0 2.5-2.5zM37.8 54.485l17.801-8.432 17.801 8.432-17.8 8.432z",viewW:110,viewH:110}},{id:"shelving",group:"furniture",art:{d:"M28 58.5h53V39H28Z M64 58.5h5V47a1 1 0 0 0-1-1h-3a1 1 0 0 0-1 1zM52.5 39h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-12 0h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-5 29.5V71a1 1 0 0 1 1 1H49a1 1 0 0 1 1-1v-2.5a1 1 0 0 1-1-1H36.5a1 1 0 0 1-1 1m33.5-10h7v-14a1 1 0 0 0-1-1h-5a1 1 0 0 0-1 1zM47.5 39h-7V25a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1zm-12 34v4a1 1 0 0 1 1 1h14a1 1 0 0 1 1-1v-4a1 1 0 0 1-1-1h-14a1 1 0 0 1-1 1M28 78h53v7H28Z M28 89.5V23a2.5 2.5 0 0 1 2.5-2.5h48A2.5 2.5 0 0 1 81 23v66.5",viewW:110,viewH:110}},{id:"shower",group:"sanitary",art:{d:"M31 84h49a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H31a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1m31.5-47.6v-4.686a11.7 11.7 0 0 0-3.441-8.283A11.77 11.77 0 0 0 50.75 20a11.77 11.77 0 0 0-8.309 3.431A11.7 11.7 0 0 0 39 31.714V84 M72 39.25a10.25 10.25 0 1 0-20.5 0zm-17.25 5v2.5m7.25-2.5v2.5m7.25-2.5v2.5m-14.5 3.75V53M62 50.5V53m7.25-2.5V53m-14.5 3.75v2.5m7.25-2.5v2.5m7.25-2.5v2.5M54.75 63v2.5M62 63v2.5m7.25-2.5v2.5",viewW:110,viewH:110}},{id:"sink",group:"sanitary",art:{d:"M30 57c0 5.523 4.477 10 10 10h29.5c5.523 0 10-4.477 10-10v-6.5A2.5 2.5 0 0 0 77 48H32.5a2.5 2.5 0 0 0-2.5 2.5zm14 22a1 1 0 0 0 1 1h19.5a1 1 0 0 0 1-1V67H44zm6-36.5a1 1 0 0 1 1-1h7.5a1 1 0 0 1 1 1V48H50zM45 37v-2a5 5 0 1 1 10 0v6.5",viewW:110,viewH:110}},{id:"sofa",group:"furniture",art:{d:"M59.5 29h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5m-34 0h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5 M18.5 44a5 5 0 0 1 5 5v12H86V49a5 5 0 0 1 5-5h.5a5 5 0 0 1 5 5v21.5a5 5 0 0 1-5 5H18a5 5 0 0 1-5-5V49a5 5 0 0 1 5-5z M25.25 57h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 25.25 57m34 0h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 59.25 57M18.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 23.392 82H20a1.5 1.5 0 0 1-1.5-1.5zm72 0h-8l1.674 5.441A1.5 1.5 0 0 0 85.608 82H89a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"stairs",group:"other",art:{d:"M73.47 46.365v-17.62m-10.571 25.55V36.674M52.326 61.783V45.484M42.193 69.273v-15.86M28.979 77.761a1 1 0 0 1 1-1h53.624v6.489a1 1 0 0 1-1 1H29.98a1 1 0 0 1-1-1z M26.777 57.497a1 1 0 0 1 1-1h2.846a1 1 0 0 1 1 1V83.25a1 1 0 0 1-1 1h-2.846a1 1 0 0 1-1-1z m73.113 28.633-41.492 32.93v-4.405l39.9-32.007a.7.7 0 0 1 .428-.151h3.724a1.762 1.762 0 1 1 0 3.524h-2.248a.5.5 0 0 0-.312.109M25.895 53.414a3.084 3.084 0 1 0 6.167 0 3.084 3.084 0 1 0-6.167 0m14.978 16.859a1 1 0 0 1 1-1h41.73v7.488h-42.73zm10.131-7.489a1 1 0 0 1 1-1h31.598v7.488H51.004z M61.576 55.294a1 1 0 0 1 1-1h21.026v7.49H61.576z M72.15 47.806a1 1 0 0 1 1-1h9.454a1 1 0 0 1 1 1v6.489H72.15z",viewW:110,viewH:110}},{id:"toilet",group:"sanitary",art:{d:"M32 26.5a2.5 2.5 0 0 1 2.5-2.5H45a2.5 2.5 0 0 1 2.5 2.5V57H32zM47.5 52h29a2.5 2.5 0 0 1 2.5 2.5V57H47.5zm17.037 20.102C73.95 70.288 79 62.01 79 57H32c.5 7.5 8.072 7 7 11l-2.342 16.862a1 1 0 0 0 .99 1.138H66.72a1 1 0 0 0 .97-1.243z",viewW:110,viewH:110}},{id:"tv",group:"appliance",art:{d:"M23.5 31H86a2.5 2.5 0 0 1 2.5 2.5v34A2.5 2.5 0 0 1 86 70H23.5a2.5 2.5 0 0 1-2.5-2.5v-34a2.5 2.5 0 0 1 2.5-2.5M50 70h9.5v8H50Zm-10 8h30M42.5 45.5h5m5 0h-5m0 0v9.75 m56.75 45.5 5 10 5-10",viewW:110,viewH:110}},{id:"wardrobe",group:"furniture",art:{d:"M28 23a2.5 2.5 0 0 1 2.5-2.5h24V85h-24a2.5 2.5 0 0 1-2.5-2.5zm2 65.5a1 1 0 0 0 1 1h47a1 1 0 0 0 1-1V85H30zM81 23a2.5 2.5 0 0 0-2.5-2.5h-24V85h24a2.5 2.5 0 0 0 2.5-2.5zM50.5 48v9.5m8-9.5v9.5",viewW:110,viewH:110}},{id:"washer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"work_table",group:"furniture",art:{d:"M88.5 47h-20v14h20zm-12 4h4m7.984-8h-66v4h66zm-66 4h4v26.5a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5z M24.866 35.597A2.5 2.5 0 0 1 27.197 34h56.577a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044a1 1 0 0 1-.93 1.362H23.46a1 1 0 0 1-.933-1.361zM88.5 61h-20v12.5A1.5 1.5 0 0 0 70 75h17a1.5 1.5 0 0 0 1.5-1.5zm-12 4h4",viewW:110,viewH:110}}];class Ic{constructor(t,e){this.host=t,this.hooks=e}place(t,e="mouse"){const s=this.host._decorImagePalette,i=this.host._curSpaceCfg;if(!s||!i)return;const o=this.hooks.decorSnap(t,e),a=jt(s.width,s.height),n=Gt(a.w,this.host._cellCm,this.host._gridPitch)/m,r=Gt(a.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,l="di"+Date.now().toString(36)+Math.random().toString(36).slice(2,5),h=this.hooks.geometrySnapshot();i.decor=[...this.host._decorList,{id:l,kind:"image",asset_id:s.asset_id,x:Z(o[0]/m-n/2),y:Z(o[1]/this.host._decorH-r/2),w:n,h:r,opacity:1}],this.host._decorSel=l,this.host._decorTool="select",this.host._decorImagePalette=null,this.hooks.clearFurniturePreview(),this.hooks.recordGeometry(this.host._t("history.decor_add"),h),this.hooks.saveConfig(),this.host.requestUpdate()}renderPlacementPreview(){const t=this.host._furnPreviewInput,e=this.host._decorImagePalette;if(!t||!e||"decor"!==this.host._mode||"image"!==this.host._decorTool||!this.host._pointerModality.hoverEnabled)return d;const s=this.hooks.decorSnap(t.raw,"mouse"),i=jt(e.width,e.height),o=Gt(i.w,this.host._cellCm,this.host._gridPitch)/m,a=Gt(i.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,n=this.host._display(e.url);return n?_``:d}renderMissing(t,e,s,i,o,a,n,r,l){const h=i+a/2,c=o+n/2;return _`${this.host._t("decor.image_unavailable")} - `}async uploadFromInput(t,e=!1){const s=t.target,i=s.files?.[0];if(s.value="",!i||this.host._decorAssetBusy)return;let o;try{o=await bo(i,2097152)}catch{return void this.host._showToast(this.host._t("backup.error.invalid_image"))}if("reject"!==o.kind)return"guard"===o.kind?(this.hooks.setGuardReplace(e),void(this.host._backdropGuard=o.state)):void await this.upload(i,i.name,e);this.host._showToast(this.host._t("toast.plan_formats"))}async upload(t,e,s){if(!this.host._decorAssetBusy){this.host._decorAssetBusy=!0;try{const i=new FormData;i.append("file",t,e);const o=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth("/api/houseplan/assets/upload",{method:"POST",body:i}):await fetch("/api/houseplan/assets/upload",{method:"POST",body:i,headers:this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}),a=await o.json().catch(()=>({}));if(!o.ok||a.error||!a.asset){const t={invalid_format:"backup.error.invalid_image",invalid_image:"backup.error.invalid_image",unsupported_image:"backup.error.unsupported_image",too_large:"backdrop.too_large_title",capacity_exceeded:"decor.image_error_capacity"};throw new Error(this.host._t(t[String(a.error)]||"backup.error.io_error"))}const n=qt({assets:[a.asset]}).values().next().value;if(!n)throw new Error(this.host._t("backup.error.io_error"));this.host._decorAssets=new Map(this.host._decorAssets).set(n.asset_id,n),this.host._decorAssetCatalog=[n,...this.host._decorAssetCatalog.filter(t=>t.asset_id!==n.asset_id)],s&&"image"===this.host._decorShapeDialog?.kind?this.host._decorShapeDialog={...this.host._decorShapeDialog,assetId:n.asset_id}:this.host._decorImagePalette=n,this.host.requestUpdate()}catch(t){this.host._showToast(this.host._t("decor.image_upload_failed",{err:this.host._errText(t)}))}finally{this.host._decorAssetBusy=!1}}}async delete(t){if(t.used_by?.length)return void this.host._showToast(this.host._t("decor.image_in_use"));if(await this.host._confirmDanger({key:`delete-decor-asset:${t.asset_id}`,kind:"destructive",title:this.host._t("decor.image_delete_title"),message:this.host._t("decor.image_delete_message",{name:t.name}),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}))try{await this.host.hass.callWS({type:"houseplan/assets/delete",asset_id:t.asset_id}),this.host._decorAssetCatalog=this.host._decorAssetCatalog.filter(e=>e.asset_id!==t.asset_id),this.host._decorAssets.delete(t.asset_id),this.host._decorImagePalette?.asset_id===t.asset_id&&(this.host._decorImagePalette=null),this.host.requestUpdate()}catch(t){this.host._showToast("in_use"===t?.code?this.host._t("decor.image_in_use"):this.host._t("backup.error.io_error"))}}async loadCatalog(){try{const t=await this.host.hass.callWS({type:"houseplan/assets/list"}),e=qt(t);this.host._decorAssetCatalog=[...e.values()],this.host._decorAssets=new Map([...this.host._decorAssets,...e]),this.host.requestUpdate()}catch{this.host._showToast(this.host._t("backup.error.io_error"))}}renderImagePalette(){const t=this.host._decorImagePalette;return p``}renderFurniturePalette(){const t=this.host._furnPalette,e=this.host._furnCategory,s=Ut.flatMap(t=>Kt(t)),i=Pc.filter(t=>s.some(e=>e.category===t.id)),o=i.find(t=>t.id===e)||null,a=o?s.filter(t=>t.category===o.id):[],n=this.host._t(this.host._imperial?"gs.unit_ft":"gs.unit_m");return p`
    t.stopPropagation()}> +
    `}renderFurniturePalette(){const t=this.host._furnPalette,e=this.host._furnCategory,s=Ut.flatMap(t=>Kt(t)),i=Dc.filter(t=>s.some(e=>e.category===t.id)),o=i.find(t=>t.id===e)||null,a=o?s.filter(t=>t.category===o.id):[],n=this.host._t(this.host._imperial?"gs.unit_ft":"gs.unit_m");return p`
    t.stopPropagation()}>
    ${this.host._t("furn.title")} @@ -646,7 +646,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 {this.host._drawWallField=t.target.value}} title=${this.host._t("draw"===this.host._tool?"markup.draw_wall_title":"physical.column_size_title")} /> ${this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")} - ${this.host._t("physical.allowed_range",{min:me(t,this.host._imperial),max:me(this.host._drawWallMaxCm,this.host._imperial),unit:this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")})} + ${this.host._t("physical.allowed_range",{min:ge(t,this.host._imperial),max:ge(this.host._drawWallMaxCm,this.host._imperial),unit:this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")})} `}_renderPlanSecondary(){const t=this.host._editorSecondaryContextId,e=this.host._physicalSel;if(e){if(!("partition"===e.kind?!!this.host._curSpaceCfg.partitions?.some(t=>t.id===e.id):!!this.host._curSpaceCfg.wall_columns?.some(t=>t.id===e.id)))return null;const s="partition"===e.kind?this.host._t("markup.partition"):"column"===e.kind?this.host._t("markup.column"):this.host._t("markup.add");return{contextId:t,kind:"selection",ariaLabel:this.host._t("editor.context_actions",{object:s}),visibleLabel:s,content:p` `;return t?{...t,kind:"selection"===t.kind?"mixed":t.kind,content:p`${t.content}${s}`}:{contextId:e,kind:"tool",ariaLabel:this.host._t("editor.tool_options",{tool:this.host._t("decor.backdrop")}),content:s}}_renderEditorSecondary(){if(!this.host._editing)return d;const t=this.host._editorSecondary.activeGroup(this.host._editorToolbarGroups),e=t?this._renderEditorGroupModel(t):"plan"===this.host._mode?this._renderPlanSecondary():"decor"===this.host._mode?this._withBackdropReset(this._renderDecorSecondary()):null;return this.host._editorSecondary.render(e,this.host._editorSecondaryDialogBlocked)}_renderDecorBar(){const t=[["select","mdi:cursor-default-outline","decor.select"],...this.host._bdRect?[["backdrop","mdi:image-move","decor.backdrop"]]:[],["line","mdi:vector-line","decor.line"],["rect","mdi:rectangle-outline","decor.rect"],["ellipse","mdi:ellipse-outline","decor.ellipse"],["text","mdi:format-text","decor.text"],["furniture","mdi:sofa-outline","decor.furniture"],...this.host._haDecorAssetsApi===hs?[["image","mdi:image-plus-outline","decor.image"]]:[],["erase","mdi:eraser","decor.erase"]],e=this.host._geometryHistory.undoName,s=this.host._geometryHistory.redoName;return p`
    + `;return t?{...t,kind:"selection"===t.kind?"mixed":t.kind,content:p`${t.content}${s}`}:{contextId:e,kind:"tool",ariaLabel:this.host._t("editor.tool_options",{tool:this.host._t("decor.backdrop")}),content:s}}_renderEditorSecondary(){if(!this.host._editing)return d;const t=this.host._editorSecondary.activeGroup(this.host._editorToolbarGroups),e=t?this._renderEditorGroupModel(t):"plan"===this.host._mode?this._renderPlanSecondary():"decor"===this.host._mode?this._withBackdropReset(this._renderDecorSecondary()):null;return this.host._editorSecondary.render(e,this.host._editorSecondaryDialogBlocked)}_renderDecorBar(){const t=[["select","mdi:cursor-default-outline","decor.select"],...this.host._bdRect?[["backdrop","mdi:image-move","decor.backdrop"]]:[],["line","mdi:vector-line","decor.line"],["rect","mdi:rectangle-outline","decor.rect"],["ellipse","mdi:ellipse-outline","decor.ellipse"],["text","mdi:format-text","decor.text"],["furniture","mdi:sofa-outline","decor.furniture"],...this.host._haDecorAssetsApi===cs?[["image","mdi:image-plus-outline","decor.image"]]:[],["erase","mdi:eraser","decor.erase"]],e=this.host._geometryHistory.undoName,s=this.host._geometryHistory.redoName;return p`
    ${t.map(([t,e,s])=>p`
    @@ -938,10 +938,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    - `}_cssPxToRender(t){const e=this.host._stageEl,s=this.host._viewOr(this.host._baseVb());return e?.clientWidth&&e.clientHeight?Math.max(s.w/e.clientWidth,s.h/e.clientHeight)*t:this.host._gridPitch/8*t}_deleteRoomClick(t){const e=this.host._spaceModel();if(!e)return;const s=[...e.rooms].reverse().find(e=>this._pointInRoom(t,e));s?s.id&&(this.host._roomDeleteDialog={roomId:s.id,name:s.name}):this.host._showToast(this.host._t("toast.delete_room_pick"))}_wallThickHit(t){const e=this.host._spaceModel();if(!e)return null;const s=6*this.host._gridPitch,i=this.host._openCuts();let o=null;const a=(t,e,i)=>{e>s||(!o||e100)return void this._showPhysicalRange(100);if("room"!==e.source.kind){const t=this._geometrySnapshot(),i=(s.partitions||[]).find(t=>t.id===e.source.id);if(!i)return;if(0===n&&ie(s.openings,{kind:"partition",id:i.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));i.cm=n,this.host._wallDialog=null;return this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),t)&&this.host._showToast(this.host._t("toast.wallthick_set")),void this.host.requestUpdate()}const r=this._geometrySnapshot(),l=n>0?n:null;if(0===n){const i=.02*this.host._gridPitch,o=[e.a[0],e.a[1],e.b[0],e.b[1]],a=(s.rooms||[]).find(t=>t.id===e.roomId),n=new Set(t&&a&&Array.isArray(a.wall_ids)?a.wall_ids:(s.wall_segments||[]).filter(t=>{const e=[Number(t.a?.[0])*sd,Number(t.a?.[1])*sd],s=[Number(t.b?.[0])*sd,Number(t.b?.[1])*sd];return Wt(e,o)<=i&&Wt(s,o)<=i}).map(t=>String(t.id))),r=(s.openings||[]).some(t=>{if("partition"===t.host?.kind)return!1;if("wall"===t.host?.kind&&n.has(t.host.id))return!0;if(t.host)return!1;const e=[Number(t.x)*sd,Number(t.y)*sd];return e.every(Number.isFinite)&&Wt(e,o)<=i});if(r)return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"))}let h,c=this.host._openCuts();if(n>0&&c.length){const o=[];if(t&&e.roomId){const t=(s.rooms||[]).find(t=>t.id===e.roomId),a=new Set(Array.isArray(t?.wall_ids)?t.wall_ids:[]);for(const t of s.wall_segments||[])a.has(t.id)&&o.push([Number(t.a?.[0])*sd,Number(t.a?.[1])*sd,Number(t.b?.[0])*sd,Number(t.b?.[1])*sd]);if(!o.length){const t=i.rooms.find(t=>t.id===e.roomId),s=t?B(t):null;for(let t=0;s&&t!o.some(e=>Wt([t[0],t[1]],e)<=a&&Wt([t[2],t[3]],e)<=a&&Wt([e[0],e[1]],t)<=a&&Wt([e[2],e[3]],t)<=a))}h=t&&e.roomId?cs(s.walls,i.rooms,e.roomId,l,this.host._wallKeyPitch,c,sd):gt(s.walls,e.a,e.b,l,this.host._wallKeyPitch,sd),h=this.host._normalizeWalls(h,c);for(const t of s.wall_segments||[])t.cm=J(h,t.a,t.b,O,1);h.length?s.walls=h:delete s.walls,this.host._wallDialog=null,this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),r)&&this.host._showToast(this.host._t(0===n?"toast.wallthick_cleared":"toast.wallthick_set")),this.host.requestUpdate()}_wallHatchDefs(t){if(!this.host._spaceWalls.length&&!this.host._physicalBodiesR().length&&!this.host._markup)return _``;const e=v(this.host._cellCm);return _` + `}_cssPxToRender(t){const e=this.host._stageEl,s=this.host._viewOr(this.host._baseVb());return e?.clientWidth&&e.clientHeight?Math.max(s.w/e.clientWidth,s.h/e.clientHeight)*t:this.host._gridPitch/8*t}_deleteRoomClick(t){const e=this.host._spaceModel();if(!e)return;const s=[...e.rooms].reverse().find(e=>this._pointInRoom(t,e));s?s.id&&(this.host._roomDeleteDialog={roomId:s.id,name:s.name}):this.host._showToast(this.host._t("toast.delete_room_pick"))}_wallThickHit(t){const e=this.host._spaceModel();if(!e)return null;const s=6*this.host._gridPitch,i=this.host._openCuts();let o=null;const a=(t,e,i)=>{e>s||(!o||e100)return void this._showPhysicalRange(100);if("room"!==e.source.kind){const t=this._geometrySnapshot(),i=(s.partitions||[]).find(t=>t.id===e.source.id);if(!i)return;if(0===n&&ie(s.openings,{kind:"partition",id:i.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));i.cm=n,this.host._wallDialog=null;return this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),t)&&this.host._showToast(this.host._t("toast.wallthick_set")),void this.host.requestUpdate()}const r=this._geometrySnapshot(),l=n>0?n:null;if(0===n){const i=.02*this.host._gridPitch,o=[e.a[0],e.a[1],e.b[0],e.b[1]],a=(s.rooms||[]).find(t=>t.id===e.roomId),n=new Set(t&&a&&Array.isArray(a.wall_ids)?a.wall_ids:(s.wall_segments||[]).filter(t=>{const e=[Number(t.a?.[0])*id,Number(t.a?.[1])*id],s=[Number(t.b?.[0])*id,Number(t.b?.[1])*id];return Wt(e,o)<=i&&Wt(s,o)<=i}).map(t=>String(t.id))),r=(s.openings||[]).some(t=>{if("partition"===t.host?.kind)return!1;if("wall"===t.host?.kind&&n.has(t.host.id))return!0;if(t.host)return!1;const e=[Number(t.x)*id,Number(t.y)*id];return e.every(Number.isFinite)&&Wt(e,o)<=i});if(r)return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"))}let h,c=this.host._openCuts();if(n>0&&c.length){const o=[];if(t&&e.roomId){const t=(s.rooms||[]).find(t=>t.id===e.roomId),a=new Set(Array.isArray(t?.wall_ids)?t.wall_ids:[]);for(const t of s.wall_segments||[])a.has(t.id)&&o.push([Number(t.a?.[0])*id,Number(t.a?.[1])*id,Number(t.b?.[0])*id,Number(t.b?.[1])*id]);if(!o.length){const t=i.rooms.find(t=>t.id===e.roomId),s=t?B(t):null;for(let t=0;s&&t!o.some(e=>Wt([t[0],t[1]],e)<=a&&Wt([t[2],t[3]],e)<=a&&Wt([e[0],e[1]],t)<=a&&Wt([e[2],e[3]],t)<=a))}h=t&&e.roomId?ds(s.walls,i.rooms,e.roomId,l,this.host._wallKeyPitch,c,id):gt(s.walls,e.a,e.b,l,this.host._wallKeyPitch,id),h=this.host._normalizeWalls(h,c);for(const t of s.wall_segments||[])t.cm=J(h,t.a,t.b,O,1);h.length?s.walls=h:delete s.walls,this.host._wallDialog=null,this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),r)&&this.host._showToast(this.host._t(0===n?"toast.wallthick_cleared":"toast.wallthick_set")),this.host.requestUpdate()}_wallHatchDefs(t){if(!this.host._spaceWalls.length&&!this.host._physicalBodiesR().length&&!this.host._markup)return _``;const e=v(this.host._cellCm);return _` - + `}_renderWallThickUi(){const t=this.host._wallThickHover;return t&&t.d?_``:_``}_renderWallThickDialog(){const t=this.host._wallDialog;return t?p`
    -
    `:p``}_openingAt(t){if(!this.host._openingsR.length)return null;const e=this.host._openingsR.flatMap(e=>{const s=e.angle*Math.PI/180,i=t[0]-e.rx,o=t[1]-e.ry,a=i*Math.cos(s)+o*Math.sin(s);return Math.abs(a)>e.rlen/2+y(12,this.host._cellCm)?[]:[{o:e,localY:-i*Math.sin(s)+o*Math.cos(s)}]});if(!e.length)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i).value;return e.find(({o:t,localY:e})=>{const s="gate"===t.type?!t.flip_v:t.flip_v,i=t.partitionHost||this.host._spaceWalls.length||"gate"===t.type?this.host._openingFace(t,o,!!s):{ox:0,oy:0,cm:0,side:-1},a=ds({type:t.type,length:t.rlen,angle:t.angle,amount:this.host._openingAmt(t),flipH:!!t.flip_h,flipV:!!t.flip_v,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:i});return Math.abs(e)<=a.hitHalf})?.o||null}_resolveOpeningPlacement(t){const e=this.host._openingPreset;if("opening"!==this.host._tool||!e)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i),a=`${o.key}|partitions:${this.host._cfgEpoch}`;this.host._openingPlacementIntervalsCache&&this.host._openingPlacementIntervalsCache.key===a||(this.host._openingPlacementIntervalsCache={key:a,value:[...pt(s.rooms,this.host._spaceWalls,i,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd),...ps(s.partitions,this.host._cellCm,this.host._gridPitch)]}),this.host._openingDimensionContextCache&&this.host._openingDimensionContextCache.key===a||(this.host._openingDimensionContextCache={key:a,value:Ec({rooms:s.rooms,walls:this.host._spaceWalls,openCuts:i,partitions:s.partitions,roomOpenings:this.host._roomWallOpeningInputs(),partitionCuts:this._partitionOpeningCuts(s),pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:sd,epsilon:2e-4*this.host._gridPitch})});const n=us({pointer:[t[0],t[1]],preset:e,geometryRevision:this.host._cfgEpoch,renderedLength:this.host._cmToUnits(e.lengthCm),intervals:this.host._openingPlacementIntervalsCache.value,baseTolerance:1.5*this.host._gridPitch,bodyPointerPadding:this._cssPxToRender("touch"===this.host._pointerModality.modality||"pen"===this.host._pointerModality.modality?10:6),gridStep:this.host._gridPitch});this.host._openingJambBlockCm=n.jambBlockedTarget?n.jambBlockedTarget.physicalHalfWidth/this.host._gridPitch*this.host._cellCm:null;const r=n.candidate;if(!r)return null;const l="gate"===r.type?!r.flipV:r.flipV;let h;if(r.host){const t=ct({id:"preview",type:r.type,x:r.x/sd,y:r.y/sd,angle:r.angle,length:r.renderedLength/sd,host:r.host},s.partitions,sd,this.host._cellCm,this.host._gridPitch).resolved;h=t?_s(t,l):{ox:0,oy:0,cm:0,side:-1}}else h=ms(o.value,{x:r.x,y:r.y,angle:r.angle,length:r.renderedLength,flip_v:l});const c="mi"===this.host.hass?.config?.unit_system?.length,d=Gc(r,this.host._openingDimensionContextCache.value).map(t=>({x:t.label[0],y:t.label[1],text:Ot(t.distance/this.host._gridPitch*this.host._cellCm,c),dimension:t}));return{...r,face:h,measure:{labels:d,guide:r.measure.guide}}}_activateOpeningPlacement(t){this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingPreset=gs(t,++this.host._openingPresetRevision),this.host._openingHoverCandidate=null,this.host._cursorPt=null)}_clearOpeningPlacement(t){this.host._openingHoverCandidate=null,this.host._openingJambBlockCm=null,t&&(this.host._openingPreset=null,this.host._openingRebindId=null)}_openingClick(t){const e=this.host._spaceModel();if(!e)return;const s=this.host._openingRebindId?null:this._openingAt(t);if(s)return void this._editOpening(s);const i=this.host._openingPreset;if(!i)return;const o=this.host._openingHoverCandidate,a=o&&fs(o,[t[0],t[1]],i.revision,this.host._cfgEpoch)?o:this._resolveOpeningPlacement(t);if(!a){if(null!=this.host._openingJambBlockCm)return void this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(this.host._openingJambBlockCm,this.host._imperial)}));const s=1.5*this.host._gridPitch,i=lt(t,e.rooms,s);return i&&bs(i.x,i.y,i.angle,this.host._openCuts(),s)?void this.host._showToast(this.host._t("toast.opening_on_zero_wall")):void this.host._showToast(this.host._t("toast.opening_no_wall"))}const n=this.host._openingRebindId?this.host._curSpaceCfg?.openings?.find(t=>t.id===this.host._openingRebindId):null;this.host._openingDialog={...n?{id:n.id,type:n.type,lengthCm:Math.round(n.length*sd/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:n.contact||"",lock:n.lock||"",invert:!!n.invert,flipH:!!n.flip_h,flipV:!!n.flip_v}:{type:a.type,lengthCm:a.lengthCm,contact:"",lock:"",invert:!1,flipH:a.flipH,flipV:a.flipV},...a.host?{host:a.host}:{},x:a.x,y:a.y,angle:a.angle},this.host._openingRebindId=null,this.host._openingHoverCandidate=null,this.host._cursorPt=null}_editOpening(t){this.host._openingDialog={id:t.id,type:t.type,lengthCm:Math.round(t.rlen/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:t.contact||"",lock:t.lock||"",invert:!!t.invert,flipH:!!t.flip_h,flipV:!!t.flip_v,..."partition"===t.host?.kind?{host:{...t.host}}:{},x:t.rx,y:t.ry,angle:t.angle}}_opPointerDown(t,e){if("plan"===this.host._mode&&this.host._spaceModel()&&"resize"!==this.host._tool){t.preventDefault(),t.stopPropagation();try{od(t)}catch{}this.host._opDrag={id:e.id,moved:!1,sx:t.clientX,sy:t.clientY,dirty:!1,before:this._geometrySnapshot()}}}_opPointerMove(t,e){Wo(this.host,"opening",()=>this._opPointerMoveNow(t,e))}_opPointerMoveNow(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;if(Math.abs(t.clientX-this.host._opDrag.sx)+Math.abs(t.clientY-this.host._opDrag.sy)<=3)return;const s=this.host._spaceModel();if(!s)return;const i=this._svgPoint(t),o=this.host._curSpaceCfg,a=o?.openings?.find(t=>t.id===e.id);if(!a)return;if("partition"===a.host?.kind){const t=s.partitions.find(t=>t.id===a.host.id);if(!t)return;const e=t.b[0]-t.a[0],o=t.b[1]-t.a[1],n=Math.hypot(e,o);if(!(n>1e-9))return;const r=e/n,l=o/n;if(Math.abs((i[0]-t.a[0])*l-(i[1]-t.a[1])*r)>4*this.host._gridPitch)return;const h=a.length*sd/2+mt(t,this.host._cellCm,this.host._gridPitch);let c=(i[0]-t.a[0])*r+(i[1]-t.a[1])*l;if(c=Math.round(c/this.host._gridPitch)*this.host._gridPitch,c=Math.max(h,Math.min(n-h,c)),n<2*h-1e-9)return;const d=c/n,p=(t.a[0]+r*c)/sd,u=(t.a[1]+l*c)/this.host._spaceH;let _=180*Math.atan2(o,e)/Math.PI;_>=90?_-=180:_<-90&&(_+=180);const m=a.host.t!==d||a.x!==p||a.y!==u||a.angle!==_;return this.host._opDrag.moved=!0,m&&(this.host._opDrag.dirty=!0),a.host={...a.host,t:d},a.x=p,a.y=u,a.angle=_,this.host._opMeasure=null,m&&this.host._cfgEpoch++,void this.host.requestUpdate()}const n=lt(i,s.rooms,4*this.host._gridPitch);if(!n)return;this.host._opDrag.moved=!0;const r=this._opRuler(n,a.length*sd);this.host._opMeasure=r.measure;const l=r.x/sd,h=r.y/this.host._spaceH,c=a.x!==l||a.y!==h||a.angle!==n.angle;if(c&&(this.host._opDrag.dirty=!0),a.x=l,a.y=h,a.angle=n.angle,Number(this.host._serverCfg?.model_version||0)>=9){const t=Hn(a,o?.wall_segments||[]);t?a.host=t:delete a.host}c&&this.host._cfgEpoch++,this.host.requestUpdate()}_opRuler(t,e){const s=this.host._spaceModel()?.rooms||[],i=this.host._gridPitch/2;let o=t.x,a=t.y,n=vs([o,a],t.angle,e,s,i);if(n&&n.centered&&(o!==n.wallCenter[0]||a!==n.wallCenter[1]))[o,a]=n.wallCenter,n=vs([o,a],t.angle,e,s,i);else if(n){const[r,l]=n.wallA,[h,c]=n.wallB,d=h-r,p=c-l,u=Math.hypot(d,p);if(u>0){const h=this.host._gridPitch,c=Math.min(e/2,u/2);let _=Math.round(((o-r)*d+(a-l)*p)/u/h)*h;_=Math.max(c,Math.min(u-c,_)),o=r+_/u*d,a=l+_/u*p,n=vs([o,a],t.angle,e,s,i)||n}}if(!n)return{x:o,y:a,angle:t.angle,measure:null};const r="mi"===this.host.hass?.config?.unit_system?.length,l=(t,e)=>({x:e[0],y:e[1],text:Ot(t/this.host._gridPitch*this.host._cellCm,r)});return{x:o,y:a,angle:t.angle,measure:{labels:[l(n.sideA,n.midA),l(n.sideB,n.midB)],guide:n.centered?{x:n.wallCenter[0],y:n.wallCenter[1],angle:t.angle}:null}}}_opPointerUp(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;jo(this.host,"opening");const s=this.host._opDrag,i=s.moved;this.host._opMeasure=null,i&&s.dirty&&this._commitPhysicalGeometry(this.host._t("history.move_opening"),s.before);const o=()=>{this.host._opDrag=null,this.host.requestUpdate()};i?window.setTimeout(o,0):o()}_opClick(t,e){"plan"===this.host._mode&&"resize"===this.host._tool||(t.stopPropagation(),this.host._opDrag?.moved||"plan"===this.host._mode&&this._editOpening(e))}_saveOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=this._geometrySnapshot(),o=this.host._spaceH,a=(e.openings||[]).find(e=>e.id===t.id),n={...a||{},id:t.id||"o"+Date.now().toString(36),type:t.type,x:t.x/sd,y:t.y/o,angle:t.angle,length:a&&!t.lengthTouched?a.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/sd,...t.host?{host:{...t.host}}:{}};if("partition"===n.host?.kind){const t=ys(a,n)?bt(n,s.partitions,sd,this.host._cellCm,this.host._gridPitch):ct(n,s.partitions,sd,this.host._cellCm,this.host._gridPitch);if(!t.resolved){const e=s.partitions.find(t=>t.id===n.host.id);if("does-not-fit-jamb"===t.reason&&e){const t=mt(e,this.host._cellCm,this.host._gridPitch);this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(t/this.host._gridPitch*this.host._cellCm,this.host._imperial)}))}else this.host._showToast(this.host._t("opening.partition_orphan"));return}const i=(e.openings||[]).flatMap(t=>{if(!t.host||t.id===n.id)return[];const e=ct(t,s.partitions,sd,this.host._cellCm,this.host._gridPitch).resolved;return e?[e]:[]});if($s(t.resolved,i))return void this.host._showToast(this.host._t("toast.opening_no_wall"));Object.assign(n,dt(n,t.resolved,sd))}else if(Number(this.host._serverCfg?.model_version||0)>=9){const t=Hn(n,e.wall_segments||[]);if(!t)return void this.host._showToast(this.host._t("toast.opening_no_wall"));n.host=t}else delete n.host;"passage"===t.type?(delete n.contact,delete n.lock,delete n.invert,delete n.flip_h,delete n.flip_v):(n.contact=t.contact||null,n.lock=("door"===t.type||"gate"===t.type)&&t.lock||null,n.invert=t.invert||void 0,n.flip_h="gate"!==t.type&&t.flipH||void 0,n.flip_v=t.flipV||void 0),e.openings=e.openings||[];const r=e.openings.findIndex(t=>t.id===n.id);r>=0?e.openings[r]=n:e.openings.push(n),this._commitPhysicalGeometry(this.host._t(t.id?"history.edit_opening":"history.add_opening"),i),this.host._openingDialog=null,this.host.requestUpdate()}_deleteOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg;if(!t?.id||!e?.openings)return;const s=this._geometrySnapshot();e.openings=e.openings.filter(e=>e.id!==t.id),this._commitPhysicalGeometry(this.host._t("history.delete_opening"),s),this.host._openingDialog=null,this.host.requestUpdate()}_contactCandidates(){const t=[];for(const e of Object.keys(this.host.hass.states)){if(!this.host._openingEntityAvailable(e))continue;const s=e.split(".")[0];if("binary_sensor"!==s&&"cover"!==s)continue;const i=this.host.hass.states[e],o=["door","window","opening","garage_door","garage"].includes(i?.attributes?.device_class||"");("cover"!==s||o)&&t.push([e,i?.attributes?.friendly_name||e,o?0:1])}return t.sort((t,e)=>t[2]-e[2]||t[1].localeCompare(e[1])).map(([t,e])=>({value:t,label:e}))}_lockCandidates(){return Object.keys(this.host.hass.states).filter(t=>t.startsWith("lock.")&&this.host._openingEntityAvailable(t)).map(t=>({value:t,label:this.host.hass.states[t]?.attributes?.friendly_name||t})).sort((t,e)=>t.label.localeCompare(e.label))}_toggleOpeningEntityPicker(t){const e=this.host._openingDialog;if(!e)return;const s="contact"===t?!e.contactOpen:!e.lockOpen;this.host._openingDialog={...e,contactOpen:"contact"===t&&s,lockOpen:"lock"===t&&s}}_filterOpeningEntities(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contactFilter:e}:{...s,lockFilter:e})}_selectOpeningEntity(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contact:e,contactOpen:!1,contactFilter:""}:{...s,lock:e,lockOpen:!1,lockFilter:""})}_mergeClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms,i=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!i?.id)return;const o=i.id;if(!this.host._mergeSel||this.host._mergeSel===o)return void(this.host._mergeSel=this.host._mergeSel===o?null:o);const a=s.find(t=>t.id===this.host._mergeSel),n=a?B(a):null,r=B(i),l=n&&r?ws(n,r):null;if(!l)return this.host._showToast(this.host._t("toast.merge_not_adjacent")),void(this.host._mergeSel=null);this.host._mergeDialog={aId:this.host._mergeSel,bId:o,poly:l,pick:"a"},this.host._mergeSel=null}_commitMerge(){const t=this.host._mergeDialog,e=this.host._curSpaceCfg;if(!t||!e||!this.host._spaceModel())return;const s=this._geometrySnapshot(),i=this.host._spaceH,o="a"===t.pick?t.aId:t.bId,a="a"===t.pick?t.bId:t.aId,n=Jc(this.host._serverCfg?.markers||[],{kind:"merge",dropId:a,keepId:o});s&&n.changed&&(s.roomReferences=n.before);const r=e.rooms.find(t=>t.id===o);if(!r)return void(this.host._mergeDialog=null);r.poly=t.poly.map(t=>[t[0]/sd,t[1]/i]),delete r.x,delete r.y,delete r.w,delete r.h,e.rooms=e.rooms.filter(t=>t.id!==a),n.changed&&this.host._serverCfg&&(this.host._serverCfg.markers=n.markers);const l=this._commitPhysicalGeometry(this.host._t("history.merge_rooms"),s);this.host._mergeDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),l&&this.host._showToast(this.host._t("toast.rooms_merged",{name:r.name||""}))}_splitClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms;if(!this.host._splitSel){const e=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!e?.id)return;return void(this.host._splitSel={roomId:e.id,pts:[]})}const i=s.find(t=>t.id===this.host._splitSel.roomId),o=i?B(i):null;if(!i||!o)return void(this.host._splitSel=null);const a=.02*this.host._gridPitch,n=6*this.host._gridPitch,r=ks(t,o),l=r&&xs(r,o,this.host._gridPitch)||r,h=r&&l&&Math.hypot(r[0]-t[0],r[1]-t[1])<=n?l:null,c=!!h&&Ss(h,o,a),d=this.host._splitSel.pts;if(!d.length)return c?void(this.host._splitSel={...this.host._splitSel,pts:[h]}):void this.host._showToast(this.host._t("toast.split_pick_wall"));if(!c){const e=this._snap(t);return Me(e,o,a)?void(this.host._splitSel={...this.host._splitSel,pts:[...d,e]}):void this.host._showToast(this.host._t("toast.split_pick_inside"))}const p=Pe(o,[...d,h],a);if(!p)return void this.host._showToast(this.host._t("toast.split_bad_cut"));this._resetRoomDialogFields();const[u,_]=p,m=H(u)>=H(_)?u:_,g=m===u?_:u;this.host._pendingSplit={roomId:i.id,mainPoly:m,newPoly:g},this.host._cursorPt=null,this.host._nameSel="",this.host._areaSel="",this.host._roomDialog=!0}_markupMove(t){if(!this.host._markup)return;if("column"===this.host._tool)return void(this.host._cursorPt=this._snap(this._svgPoint(t)));if("opening"===this.host._tool||"wallthick"===this.host._tool)return void(this.host._cursorPt=this._svgPoint(t));const e="draw"===this.host._tool&&!this.host._contourClosed,s="split"===this.host._tool&&!!this.host._splitSel?.pts?.length;if(!e&&!s)return;const i=this._svgPoint(t);if(e){const e=this._resolvePlanDrawPoint(i,t.shiftKey);if(this.host._planSnapHover={contextKey:e.contextKey,candidate:e.candidate,conflicts:e.conflicts},this._syncPlanSnapConflictMarkers(e.conflicts),this._syncPlanSnapActiveMarker(e.candidate),!this.host._path.length)return;return void(this.host._cursorPt=e.point)}this.host._cursorPt=this._snap(i)}_saveRoom(){(this.host._areaSel||this.host._nameSel.trim())&&nt(this.host._roomTempMin,this.host._roomTempMax).valid&&(this.host._wallFaceBatch?this._decideWallFace(!0):this._commitRoom())}_decideWallFace(t){const e=this.host._wallFaceBatch;if(!e)return;const s=e.candidates[e.index];if(!s)return;if(!t&&(s.existing||s.repair)&&1===e.candidates.length)return this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate();const i=t?{candidate:s,create:!0,name:this.host._nameSel.trim(),area:this.host._areaSel||null,settings:this._roomSettingsFromDialog()?JSON.parse(JSON.stringify(this._roomSettingsFromDialog())):null}:{candidate:s,create:!1},o=[...e.decisions,i],a=e.index+1;if(a"number"==typeof t&&Number.isFinite(t)&&t>=0?t:null,o=.02*this.host._gridPitch,a=this.host._spaceModel();if(!a)return ut;for(const e of this._planSnapGeometrySnapshot().value.segments)if(!("room"===e.sourceKind||Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])>o)&&"partition"===e.sourceKind)return i(a.partitions.find(t=>t.id===e.sourceId)?.cm)??ut;const n=Rh(Math.max(0,e.length-1),s,this.host._drawWallCm,ut);for(let s=0;s+1[...t]);if(!e)return s;const i=this.host._activeWallChainPartitionIds.findIndex((t,s)=>this._activeWallSourceKey(s)===e.sourceKey),o=i>=0?i+("b"===e.endpoint?1:0):-1;return o>=0&&oe.key===t.sourceKey),a=i.find(e=>e.key===t.targetSourceKey);if(!o||!a)return!1;const n="a"===t.endpoint?o.a:o.b;return!(Math.hypot(n[0]-t.from[0],n[1]-t.from[1])>s)&&(!(Wt(t.to,[a.a[0],a.a[1],a.b[0],a.b[1]])>s)&&!function(t,e){if(!t.sourceKey.startsWith("static:partition|"))return!1;const s=t.sourceKey.slice(17).split("|")[0];return!!s&&e.some(t=>"partition"===t.host?.kind&&t.host.id===s)}(t,this.host._curSpaceCfg?.openings||[]))}_applyWallRepair(t,e){const s=this.host._curSpaceCfg;if(!s||!this._validateWallRepair(t,e.activePath))return!1;if(!t.sourceKey.startsWith("static:"))return!1;const[i,o]=t.sourceKey.slice(7).split("|");if("partition"===i){const i=(s.partitions||[]).find(t=>t.id===o);if(!i)return!1;const a=[i.a[0]*sd,i.a[1]*sd],n=[i.b[0]*sd,i.b[1]*sd],r=Math.hypot(a[0]-t.from[0],a[1]-t.from[1])<=2e-4*this.host._gridPitch?i.a:Math.hypot(n[0]-t.from[0],n[1]-t.from[1])<=2e-4*this.host._gridPitch?i.b:null;if(!r)return!1;(e=>{e[0]=t.to[0]/sd,e[1]=t.to[1]/sd})(r);const l=e.activePartitionIds.indexOf(o);if(l>=0){const s=l+("b"===t.endpoint?1:0);e.activePath[s]&&(e.activePath[s]=[...t.to])}return!0}return!1}_applyWallFaceBatch(){const t=this.host._wallFaceBatch,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=(t,e)=>{this.host._showToast(this.host._t(t,e)),this._roomDialogCancel()},o=t.decisions.filter(t=>t.create),a=o.map(t=>t.candidate.ring),n=s.rooms;for(let t=0;ts.id!==e&&!!B(s)&&N(a[t],B(s)));if(s)return void i("toast.room_overlap",{name:s.name||""})}if((e.rooms||[]).length+o.length>400)return void i("toast.physical_limit");if(o.some(t=>t.candidate.split&&!e.rooms.some(e=>e.id===t.candidate.split.roomId)))return void i("toast.contour_cannot_close");const r=o.map(t=>t.candidate.repair).filter(t=>!!t);if(r.length>1||r[0]&&!this._validateWallRepair(r[0],t.activePath))return void i("toast.wall_repair_changed");if(this._activePathWithRepair(t.activePath,r[0]),!o.length){if(!this._finalizeWallChainPartitions(t.activePartitionIds))return;return this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host.requestUpdate(),void this.host._showToast(this.host._t("toast.wall_chain_saved"))}const l=new Set(t.activePartitionIds),h=2e-4*this.host._gridPitch,c=o.map(t=>t.candidate.ring.map((t,e,i)=>{const o=i[(e+1)%i.length],a=s.partitions.filter(e=>{const s=Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1]);if(!(s>h))return!1;const i=(e.b[0]-e.a[0])/s,a=(e.b[1]-e.a[1])/s,n=t=>(t[0]-e.a[0])*i+(t[1]-e.a[1])*a;return Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&Wt(o,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&n(t)>=-h&&n(t)<=s+h&&n(o)>=-h&&n(o)<=s+h});return a.sort((t,e)=>Number(l.has(e.id))-Number(l.has(t.id))||Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])-Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1])||t.id.localeCompare(e.id)),a[0]?.id||""})),d=this._geometrySnapshot();if(!d)return void i("toast.geometry_unsafe");const p=()=>{this._restoreGeometryStateLocal(d),i("toast.geometry_unsafe")};if(r[0]&&!this._applyWallRepair(r[0],t))return void i("toast.wall_repair_changed");const u=o.some(t=>!!t.candidate.split),_=u?ae(s.rooms,e.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd):null,m=u&&Array.isArray(e.walls)?e.walls:null;for(const t of o){const s=t.candidate.split;if(!s)continue;const i=e.rooms.find(t=>t.id===s.roomId);if(!i)return void p();i.poly=s.mainPoly.map(t=>[t[0]/sd,t[1]/this.host._spaceH]),delete i.x,delete i.y,delete i.w,delete i.h}const g=Date.now().toString(36),f=[];if(o.forEach((t,s)=>{const i=t.area?this.host.hass.areas[t.area]?.name:"",o={id:`r${g}-${s}`,name:t.name||i||this.host._t("room.default_name"),area:t.area||null,poly:t.candidate.ring.map(t=>[t[0]/sd,t[1]/this.host._spaceH]),...c[s].some(Boolean)?{wall_ids:c[s]}:{},...t.settings?{settings:JSON.parse(JSON.stringify(t.settings))}:{}};e.rooms.push(o),f.push({room:o,decision:t})}),u){const t=this.host._normalizeWalls(_,this.host._openCuts());t.length?e.walls=t:m?.length?e.walls=m:delete e.walls}if(f.length){this.host._cfgEpoch++;const s=this.host._openCuts(),i=this.host._spaceModel();if(!i)return void p();let o=e.walls;for(const{room:e,decision:a}of f){const n=a.candidate.ring,r=this._wallSourceCmAt(n[0],t.activePath,t.activeCms);o=Ms(o,i.rooms,e.id,r,this.host._wallKeyPitch,s,sd);for(const a of pt(i.rooms,o,s,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd)){if(a.roomId!==e.id||"outer"!==a.kind)continue;const s=[(a.a[0]+a.b[0])/2,(a.a[1]+a.b[1])/2];o=gt(o,a.a,a.b,this._wallSourceCmAt(s,t.activePath,t.activeCms),this.host._wallKeyPitch,sd)}}const a=this.host._normalizeWalls(o,s);a.length?e.walls=a:delete e.walls,this.host._cfgEpoch++;const n=this.host._spaceModel();if(!n)return void p();const r=wl(e,n,e.walls,s,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:sd,allowCoincidentPartitions:!0});r.walls.length?e.walls=r.walls:delete e.walls,r.partitions.length?e.partitions=r.partitions:delete e.partitions,r.openings.length?e.openings=r.openings:delete e.openings}if(!this._commitPhysicalGeometry(this.host._t("history.wall_face_batch"),d))return;this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host._regSignature="",this.host._maybeRebuildDevices();const b=new Set(o.map(t=>t.area).filter(t=>!!t));if(b.size){const t={...this.host._layout};for(const e of this.host._devices){if(!b.has(e.area||"")||e.space!==this.host._space)continue;if(this.host._layout[e.id])continue;const s=this.host._defPos[e.id];s&&(t[e.id]={s:this.host._space,x:s.x/sd,y:s.y/sd},this.host._dirtyPos.add(e.id))}this.host._layout=t,this.host._persistLayout()}this.host._showToast(this.host._t(o.length?"toast.wall_rooms_saved":"toast.wall_chain_saved",{n:o.length}))}_commitRoom(){const t=this.host._curSpaceCfg,e=this.host._spaceModel();if(!t||!e)return;const s=this._geometrySnapshot();if(!s)return;const i=()=>{this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe"))},o=this.host._spaceH,a=!!this.host._pendingSplit,n=a?ae(e.rooms,t.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd):null,r=a&&Array.isArray(t.walls)?t.walls:null;let l;if(this.host._pendingSplit){const e=t.rooms.find(t=>t.id===this.host._pendingSplit.roomId);if(!e)return this.host._pendingSplit=null,this.host._splitSel=null,void(this.host._roomDialog=!1);e.poly=this.host._pendingSplit.mainPoly.map(t=>[t[0]/sd,t[1]/o]),delete e.x,delete e.y,delete e.w,delete e.h,l=this.host._pendingSplit.newPoly}else{if(!this.host._contourClosed)return;l=this.host._path.slice(0,-1)}const h=this.host._areaSel?this.host.hass.areas[this.host._areaSel]?.name:"",c={id:"r"+Date.now().toString(36),name:this.host._nameSel||h||this.host._t("room.default_name"),area:this.host._areaSel||null,poly:l.map(t=>[t[0]/sd,t[1]/o]),...this._roomSettingsFromDialog()?{settings:this._roomSettingsFromDialog()}:{}};if(t.rooms.push(c),a){const e=this.host._normalizeWalls(n,this.host._openCuts());e.length?t.walls=e:r?.length?t.walls=r:delete t.walls}if(!a){const e=Rh(l.length,[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,ut),s=e[0];if(null!=s){this.host._cfgEpoch++;const o=this.host._openCuts(),a=this.host._spaceModel();if(!a)return void i();let n=Ms(t.walls,a.rooms,c.id,s,this.host._wallKeyPitch,o,sd);for(const t of pt(a.rooms,n,o,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd)){if(t.roomId!==c.id||"outer"!==t.kind)continue;const s=[(t.a[0]+t.b[0])/2,(t.a[1]+t.b[1])/2],i=l.findIndex((t,e)=>{const i=l[(e+1)%l.length];return Wt(s,[t[0],t[1],i[0],i[1]])<=.02*this.host._gridPitch});i>=0&&(n=gt(n,t.a,t.b,e[i],this.host._wallKeyPitch,sd))}n=this.host._normalizeWalls(n,o),n.length?t.walls=n:delete t.walls;const r=this.host._spaceModel();if(!r)return void i();const h=wl(t,r,t.walls,o,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:sd,allowCoincidentPartitions:!0});h.walls.length?t.walls=h.walls:delete t.walls,h.partitions.length?t.partitions=h.partitions:delete t.partitions,h.openings.length?t.openings=h.openings:delete t.openings}}const d=this._commitPhysicalGeometry(this.host._t(a?"history.split_room":"history.add_room"),s);this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._pendingSplit=null,this.host._splitSel=null;const p=this.host._areaSel;if(this.host._areaSel="",this.host._nameSel="",this.host._roomDialog=!1,this.host._regSignature="",this.host._maybeRebuildDevices(),!d)return;let u=0;if(p){const t=sd,e={...this.host._layout};for(const s of this.host._devices){if(s.area!==p||s.space!==this.host._space)continue;if(u++,this.host._layout[s.id])continue;const i=this.host._defPos[s.id];i&&(e[s.id]={s:this.host._space,x:i.x/sd,y:i.y/t},this.host._dirtyPos.add(s.id))}this.host._layout=e,this.host._persistLayout()}const _=this.host._model.find(t=>t.id===this.host._space)?.rooms.length||0;this.host._showToast(p?this.host._t("toast.room_saved",{n:_,added:u}):this.host._t("toast.room_saved_no_area",{n:_}))}_cancelPath(){this.host._wallRepairDiagnostic=null,this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),this.host._roomDialog=!1,this.host._pendingSplit=null,this.host._wallFaceBatch=null,this.host._splitSel=null,this.host._mergeSel=null,this.host._mergeDialog=null,this.host._physicalSel=null,this.host._physicalDrag=null,this.host._physicalRotate=null,this._clearOpeningPlacement(!0)}_roomDialogCancel(){if(this.host._roomDialog=!1,this.host._roomEditId)return this.host._roomEditId=null,this.host._nameSel="",void(this.host._areaSel="");if(this.host._wallFaceBatch){const t=this.host._wallFaceBatch;return this.host._wallFaceBatch=null,this.host._path=t.activePath.map(t=>[...t]),this.host._wallChainSegmentCms=[...t.activeCms],this.host._activeWallChainPartitionIds=[...t.activePartitionIds],this.host._activeWallChainId||=`chain-${Date.now().toString(36)}`,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate()}if(this.host._pendingSplit)return this.host._pendingSplit=null,void(this.host._splitSel=null);this.host._undoPoint()}_openDeviceInbox(){this.host._deviceInboxReturn=null,this.host._deviceInbox=this.host._deviceInbox||{tab:"on_plan",search:"",showEntities:!1,onlyNew:!1,limit:100}}_closeMarkerDialog(){this._radarSetup.isDirty()?this._closeMarkerDialogGuarded():(this._radarSetup.reset(),function(t){if(t._markerDialog=null,!t._deviceInboxReturn)return;const e={...t._deviceInboxReturn};t._deviceInbox=e,t._deviceInboxReturn=null,e.anchor&&t.updateComplete.then(()=>requestAnimationFrame(()=>{const s=`.device-inbox-row[data-binding="${CSS.escape(e.anchor)}"]`;t.renderRoot.querySelector(s)?.scrollIntoView({block:"nearest"})}))}(this.host))}async _closeMarkerDialogGuarded(){if(!await this._radarSetup.discardIfAllowed())return await this.host.updateComplete,void this.host.renderRoot.querySelector("#marker-dialog")?.rejectClose();this._closeMarkerDialog()}_deviceInboxCandidates(t){return Yl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:t,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}})}_deviceInboxRows(){const t=this.host._deviceInbox||this.host._deviceInboxReturn,e=!!t?.showEntities,s=[this.host._haRegistry.revision,this.host._cfgRev,this.host._cfgEpoch,this.host._regSignature,this.host._newSyncKey,e?1:0,this.host._showAll?1:0,l(this.host.hass,this.host._config?.language)].join("|");if(this.host._deviceInboxMemo?.key===s)return this.host._deviceInboxMemo.rows;const i=this._deviceInboxCandidates(e),o=new Set(i.map(t=>t.value));for(const t of this.host._markers)t.binding&&"virtual"!==t.binding&&o.add(t.binding);for(const t of this.host._devices)t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&o.add(`${t.bindingKind}:${t.bindingRef}`);const a=new Map;for(const t of o)a.set(t,this.host._bindingStatus(t));const n=this.host._areaToSpace,r={};for(const[t,e]of Object.entries(this.host.hass?.areas||{}))r[t]=n[t]?.room?.name||e?.name||t;for(const[t,e]of Object.entries(n))r[t]=e.room.name||r[t]||t;const h=Object.fromEntries(this.host._model.map(t=>[t.id,t.title])),c=Object.fromEntries(Object.entries(n).map(([t,e])=>[t,e.space])),d={},p=new Map;for(const[t,e]of Object.entries(this.host._fullRegistryHass.entities||{})){const s=String(e?.platform||"").trim();if(s&&(d[`entity:${t}`]=s),s&&e?.device_id){const t=p.get(e.device_id)||new Set;t.add(s),p.set(e.device_id,t)}}for(const[t,e]of p)d[`device:${t}`]=[...e].sort().join(", ");const u={};for(const[t,e]of Object.entries(this.host._fullRegistryHass.devices||{})){const s=`device:${t}`,i=p.get(t)||new Set,o=Array.isArray(e?.identifiers?.[0])?String(e.identifiers[0][0]||""):"";o&&!d[s]&&(d[s]=o);const a=[o,...i].some(t=>this.host._excluded.has(t));"service"===e?.entry_type?u[s]="service_entry":a?u[s]="excluded_integration":"Group"===e?.model?u[s]="grouped_light":/scene/i.test(e?.model||"")?u[s]="excluded_domain":(/bridge/i.test(`${e?.model||""}${e?.name||""}`)||"myheat"===o&&e?.via_device_id)&&(u[s]="represented_by_parent")}const _=function(t){const{devices:e,markers:s,candidates:i,statuses:o,newDeviceIds:a,showHiddenOnPlan:n,areaNames:r={},spaceNames:l={},spaceByArea:h={},integrationByBinding:c={},reasonByBinding:d={}}=t,p=new Map;for(const t of e)!t.virtual&&t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&p.set(`${t.bindingKind}:${t.bindingRef}`,t);const u=new Map,_=new Map;for(const t of s)t?.binding&&"virtual"!==t.binding&&(t.removed?_.set(t.binding,t):u.set(t.binding,t));const m=new Map(i.map(t=>[t.value,t])),g=new Set([...p.keys(),...u.keys(),...m.keys(),...[..._.keys()].filter(t=>m.has(t))]),f=[];for(const t of g){const e=p.get(t),s=u.get(t),i=s?void 0:_.get(t),g=m.get(t);let b;if(i&&g)b="readd";else if(!0===s?.hidden)b="hidden";else if(e||s)b="on_plan";else{if(!g)continue;b="available"}const v=e?.bindingStatus||o.get(t)||Xl,y=s||i,$=Zl(t),w=e?.area||g?.areaId||y?.area||"",k=e?.space||y?.space||h[w]||"",x=e?.name||y?.name||g?.label||t,S=e?.model||y?.model||g?.model||"",M=!!g?.parentDeviceId&&p.has(`device:${g.parentDeviceId}`),C="readd"===b?"removed":"hidden"===b?s&&Ql(s)?d[t]||"automatic_hidden":"manual_hidden":"on_plan"===b?s?"visible_explicit":"visible_auto":d[t]||(M?"represented_by_parent":w&&k?"available":"no_bound_room"),P=!!e&&(!e.hidden||n),D="active"===v.kind,I=P&&(D||"ha_disabled"===v.kind&&n),T=[x,S,c[t],r[w],l[k],t,g?.sub].filter(Boolean).join(" ").toLocaleLowerCase();f.push({key:t,binding:t,category:b,status:v,reason:C,deviceId:e?.id,markerId:y?.id,name:x,icon:e?.icon||y?.icon||("entity"===$?"mdi:code-braces":"mdi:devices"),model:S,integration:c[t]||"",areaId:w,areaName:r[w]||"",spaceId:k,spaceName:l[k]||"",kind:$,isNew:!!e&&a.has(e.id),searchText:T,canFind:I,canEdit:!!e||!!s,canHide:"on_plan"===b&&D,canShow:"hidden"===b&&D,canAdd:("available"===b||"readd"===b)&&D})}const b=t=>"active"===t.status.kind?1:0;return f.sort((t,e)=>t.category.localeCompare(e.category)||Number(e.isNew)-Number(t.isNew)||b(t)-b(e)||t.name.localeCompare(e.name)||t.binding.localeCompare(e.binding))}({devices:this.host._devices,markers:this.host._markers,candidates:i,statuses:a,newDeviceIds:this.host._newIds,showHiddenOnPlan:this.host._showAll,areaNames:r,spaceNames:h,spaceByArea:c,integrationByBinding:d,reasonByBinding:u});return this.host._deviceInboxMemo={key:s,rows:_},_}_deviceForInboxRow(t){const e=t.deviceId?this.host._devices.find(e=>e.id===t.deviceId):null;if(e)return e;const s=t.markerId?this.host._markers.find(e=>e.id===t.markerId):null;return!s||s.removed?null:{id:s.id,name:t.name,model:t.model,area:t.areaId,space:t.spaceId||this.host._space,hidden:!0===s.hidden||"ha_disabled"===t.status.kind,userHidden:!0===s.hidden,bindingStatus:t.status,icon:t.icon,entities:"active"===t.status.kind?t.status.enabledEntityIds:[],allEntities:t.status.allEntityIds,primary:"active"===t.status.kind?t.status.enabledEntityIds[0]:void 0,marker:s,bindingKind:t.kind,bindingRef:t.binding.slice(t.binding.indexOf(":")+1),pdfs:s.pdfs||[]}}_openInboxMarker(t,e=!1){const s=this.host._deviceInbox;if(s){if(this.host._deviceInboxReturn={...s,anchor:t.key},this.host._deviceInbox=null,!e){const e=this._deviceForInboxRow(t);return void(e?this._openMarkerDialog(e):this._closeMarkerDialog())}this._openMarkerDialog(),this.host._markerDialog?this.host._markerDialog={...this.host._markerDialog,bindingMode:"ha",binding:t.binding,bindingOpen:!1,showEntities:"entity"===t.kind,name:""}:this._closeMarkerDialog()}}async _setInboxHidden(t,e){const s=this.host._deviceInbox,i=this.host._serverCfg;if(!s||!i||s.busy||"active"!==t.status.kind)return;const o=i.markers||[],a=o.find(e=>!e.removed&&e.binding===t.binding);if(!e&&!a)return;const n=a?.id||Cs(t.binding,t.markerId,()=>`m_${Date.now().toString(36)}`),r=a?{...a,hidden:e}:{id:n,binding:t.binding,hidden:!0};i.markers=[...o.filter(e=>e.id!==n&&(e.binding!==t.binding||!0===e.removed)),r],this.host._deviceInbox={...s,busy:t.key,anchor:t.key};try{await this._saveConfigNow(),this.host._regSignature="",this.host._deviceInboxMemo=null,this.host._maybeRebuildDevices(),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("device_inbox.saved"))}catch(t){this.host._serverCfg===i&&(i.markers=o),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_findInboxDevice(t){if(!t.canFind)return;const e=this._deviceForInboxRow(t);if(!e)return;if(this.host._deviceInbox=null,e.space&&e.space!==this.host._space){if(!this.host._commitSpace(e.space))return;this.host._restoreZoom()}const s=()=>{const t=this.host._devices.find(t=>t.id===e.id)||e,s=this.host._pos(t);this.host._applyView(this.host._zoom,s.x,s.y),this.host._selId=t.id,this.host.requestUpdate(),window.setTimeout(()=>{this.host._selId===t.id&&(this.host._selId=null,this.host.requestUpdate())},1500)};requestAnimationFrame(()=>requestAnimationFrame(s))}_openMarkerDialog(t){if(this.host._vacAllCamerasFor=null,this.host._vacAllCameraCache=null,t&&this.host._ackNewDevice(t.id),this.host._norm)if(t){const e=t.marker,s=Object.prototype.hasOwnProperty.call(e||{},"is_light"),i=Object.prototype.hasOwnProperty.call(e||{},"light_entity"),o=Object.prototype.hasOwnProperty.call(e||{},"glow_color"),a=Object.prototype.hasOwnProperty.call(e||{},"value_badge"),n=Object.prototype.hasOwnProperty.call(e||{},"value_source"),r=Object.prototype.hasOwnProperty.call(e||{},"tap_action"),l=Object.prototype.hasOwnProperty.call(e||{},"toggle_entity"),h=Ps(e?.glow_color),c=this.host._devicePresentation(t,!0).valueBadge,d=Ds(this.host._planHass,t,this.host._devices),p=Is(this.host._planHass,t,d),u=nh(t,this.host._fullRegistryHass),_=this.host._spaceModelById(t.space)||this.host._spaceModel(),m=this.host._pos(t),g=_?lh(t,_,[m.x,m.y],this.host._fullRegistryHass):null;this.host._markerDialog={devId:t.id,name:t.name,binding:"virtual"===t.bindingKind?"virtual":t.bindingKind+":"+t.bindingRef,bindingMode:"virtual"===t.bindingKind?"virtual":"ha",bindingOpen:!1,showEntities:"entity"===t.bindingKind&&!!this.host._fullRegistryHass.entities[t.bindingRef||""]?.device_id,bindingFilter:"",icon:t.marker?.icon||"",autoIcon:t.icon||"",display:Rs(t.marker?.display),rippleColor:x(t.marker?.ripple_color,""),rippleSize:Number(t.marker?.ripple_size)>0?Number(t.marker.ripple_size):1.5,size:Number(t.marker?.size)>0?Number(t.marker.size):1,angle:Number(t.marker?.angle)||0,tapAction:zs(t.marker?.tap_action,t.primary?.split(".")[0]),tapActionTouched:!1,originalHasTapAction:r,originalTapAction:t.marker?.tap_action,tapHintAnnouncement:"",toggleEntity:e?.toggle_entity||"",toggleEntityTouched:!1,originalHasToggleEntity:l,originalToggleEntity:e?.toggle_entity,tapTarget:t.marker?.tap_target||"",tapConfirm:!0===t.marker?.tap_confirm,runFilter:"",controls:Ts(t.marker?.binding,t.marker?.controls,t.entities),controlsFilter:"",lightRole:!0===e?.is_light?"always":!1===e?.is_light?"never":"auto",lightRoleTouched:!1,originalHasIsLight:s,originalIsLight:e?.is_light,lightEntity:e?.light_entity||"",lightEntityTouched:!1,originalHasLightEntity:i,originalLightEntity:e?.light_entity,glowMode:null!=h?.bri?"fixed":h?"color":"auto",glowColor:h?.c||this.host._fillColors.glow_light.c,glowBrightness:Math.max(1,Math.round(100*(h?.bri??1))),glowColorDrafted:!!h,glowBrightnessDrafted:null!=h?.bri,glowTouched:!1,originalHasGlowColor:o&&(!!h||null===e?.glow_color),originalGlowColor:h||(null===e?.glow_color?null:void 0),valueBadgeEnabled:a?!0===e?.value_badge?.enabled:!!c,valueBadgeSource:e?.value_badge?.source||c?.source||p,valueBadgePosition:e?.value_badge?.position||c?.position||"right",valueBadgeTouched:!1,originalHasValueBadge:a,originalValueBadge:e?.value_badge,valueSource:e?.value_source||null,valueSourceTouched:!1,originalHasValueSource:n,originalValueSource:e?.value_source,useClimateTemp:!0===t.marker?.use_climate_temp,glowRadius:Number(t.marker?.glow_radius_cm)>0?String(this.host._imperial?Math.round(Number(t.marker.glow_radius_cm)/30.48*10)/10:Math.round(Number(t.marker.glow_radius_cm))/100):"",model:t.model||"",link:t.link||"",description:t.description||"",pdfs:[...t.pdfs||[]],room:t.marker?.room_id?t.space+"#@"+t.marker.room_id:t.space&&t.area?t.space+"#"+t.area:"",roomTouched:!1,radar:g,radarEligible:u.eligible,radarTouched:!1,radarRemove:!1,hideFromPlan:!0===t.marker?.hidden,busy:!1}}else this.host._markerDialog={name:"",binding:"virtual",bindingMode:"virtual",bindingOpen:!1,showEntities:!1,bindingFilter:"",icon:"",autoIcon:"",display:"badge",rippleColor:"",rippleSize:1.5,size:1,angle:0,tapAction:"info",tapActionTouched:!1,originalHasTapAction:!1,originalTapAction:void 0,tapHintAnnouncement:"",toggleEntity:"",toggleEntityTouched:!1,originalHasToggleEntity:!1,originalToggleEntity:void 0,tapTarget:"",tapConfirm:!1,runFilter:"",controls:[],controlsFilter:"",lightRole:"auto",lightRoleTouched:!1,originalHasIsLight:!1,originalIsLight:void 0,lightEntity:"",lightEntityTouched:!1,originalHasLightEntity:!1,originalLightEntity:void 0,glowMode:"auto",glowColor:this.host._fillColors.glow_light.c,glowBrightness:100,glowColorDrafted:!1,glowBrightnessDrafted:!1,glowTouched:!1,originalHasGlowColor:!1,originalGlowColor:void 0,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgePosition:"right",valueBadgeTouched:!1,originalHasValueBadge:!1,originalValueBadge:void 0,valueSource:null,valueSourceTouched:!1,originalHasValueSource:!1,originalValueSource:void 0,useClimateTemp:!1,glowRadius:"",model:"",link:"",description:"",pdfs:[],room:"",roomTouched:!1,radar:null,radarEligible:!1,radarTouched:!1,radarRemove:!1,hideFromPlan:!1,busy:!1,uploadId:"up_"+Date.now().toString(36)+Math.random().toString(36).slice(2,6)};else this.host._showToast(this.host._t("toast.marker_needs_server"))}_runCandidates(){const t=[];for(const e of As)for(const[s,i]of Object.entries(this.host.hass.states))s.startsWith(e+".")&&this.host._planEntityAvailable(s)&&t.push({value:s,label:i?.attributes?.friendly_name||s,sub:this.host._t("run."+e)});return t.sort((t,e)=>t.sub.localeCompare(e.sub)||t.label.localeCompare(e.label))}_bindingCandidates(){const t=Yl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:!!this.host._markerDialog?.showEntities,currentBinding:this.host._markerDialog?.binding,currentDeviceId:this.host._markerDialog?.devId,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}}),e=(this.host._markerDialog?.bindingFilter||"").toLowerCase().trim(),s=e?t.filter(t=>(t.label+" "+t.sub+" "+t.value).toLowerCase().includes(e)):t;return s.sort((t,e)=>t.label.localeCompare(e.label)),s.slice(0,200)}_backupErrorText(t){const e=t?.code??t?.error;if("string"==typeof e){const t=`backup.error.${e}`,s=this.host._t(t);if(s!==t)return s}return this.host._errText(t)}async _pickMarkerFiles(t){const e=t.target,s=e.files?[...e.files]:[];if(e.value="",!s.length||!this.host._markerDialog)return;const i=this.host._markerDialog.uploadId||this.host._markerDialog.devId||"new",o=[];for(const t of s)try{const e=new FormData;e.append("marker_id",i),e.append("file",t,t.name);const s=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth("/api/houseplan/upload",{method:"POST",body:e}):await fetch("/api/houseplan/upload",{method:"POST",body:e,headers:this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}),a=await s.json().catch(()=>({}));if(!s.ok||a.error){const t={too_large:this.host._t("err.too_large",{mb:a.max_mb||50}),bad_ext:this.host._t("err.bad_ext"),unauthorized:this.host._t("err.unauthorized")};throw new Error(t[a.error]||a.error||"HTTP "+s.status)}o.push({name:a.name||t.name,url:a.url})}catch(e){this.host._showToast(this.host._t("toast.file_failed",{name:t.name,err:this.host._errText(e)}))}o.length&&this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:[...this.host._markerDialog.pdfs,...o]},this.host._showToast(this.host._t("toast.files_attached",{n:o.length})))}_removeMarkerPdf(t){this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:this.host._markerDialog.pdfs.filter(e=>e.url!==t)})}_markerLightFields(t){const e={};if(t.lightRoleTouched?"always"===t.lightRole?e.is_light=!0:"never"===t.lightRole&&(e.is_light=!1):t.originalHasIsLight&&(e.is_light=t.originalIsLight??null),t.lightEntityTouched?t.lightEntity&&(e.light_entity=t.lightEntity):t.originalHasLightEntity&&(e.light_entity=t.originalLightEntity??null),t.glowTouched){if("auto"!==t.glowMode){const s={c:x(t.glowColor,this.host._fillColors.glow_light.c)};"fixed"===t.glowMode&&(s.bri=Math.max(.01,Math.min(1,Math.round(t.glowBrightness)/100))),e.glow_color=s}}else t.originalHasGlowColor&&(e.glow_color=t.originalGlowColor??null);return e}_markerTapActionFields(t){return t.tapActionTouched?{tap_action:t.tapAction||null}:t.originalHasTapAction?{tap_action:t.originalTapAction??null}:{}}_markerToggleEntityFields(t){return(e={touched:t.toggleEntityTouched,originalHas:t.originalHasToggleEntity,original:t.originalToggleEntity,value:t.toggleEntity}).touched?e.value?{toggle_entity:e.value}:{}:e.originalHas?{toggle_entity:e.original??null}:{};var e}async _saveMarker(){const t=this.host._markerDialog;if(!t||t.busy)return;const e=this._effectiveMarkerTapAction(t);if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return;if("virtual"===t.binding&&!t.name.trim())return void this.host._showToast(this.host._t("toast.virtual_name_required"));if("run"===e&&!t.tapTarget)return void this.host._showToast(this.host._t("toast.run_target_required"));if(t.valueBadgeTouched&&t.valueBadgeEnabled&&!t.valueBadgeSource)return void this.host._showToast(this.host._t("toast.value_badge_source_required"));if("ha"===t.bindingMode){const e=this.host._bindingStatus(t.binding),s=t.devId?this.host._markers.find(e=>e.id===t.devId):null,i=!s||s.binding!==t.binding;if("active"!==e.kind&&i)return void this.host._showToast(this.host._t("ha_disabled"===e.kind?"toast.ha_disabled_add":"toast.ha_binding_unverified"));if("ha_disabled"===e.kind&&!0===s?.hidden&&!t.hideFromPlan)return this.host._markerDialog={...t,hideFromPlan:!0},void this.host._showToast(this.host._t("entity"===e.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device"))}const s=this.host._serverCfg;if(!s)return;const i=this.host._cfgRev,o=Ft(s);let a=JSON.parse(JSON.stringify(s));const n=a.markers||[],r=Cs(t.binding,t.devId,()=>"v_"+Date.now().toString(36)),l=t.devId,h=l?this.host._devices.find(t=>t.id===l):null,c=l?n.find(t=>t.id===l):null,d=!!c&&("string"==typeof c.area&&c.area.length>0||null===c.area&&!!c.space&&!!c.room_id),p="virtual"===t.binding||t.roomTouched||d,u="virtual"===t.binding||t.roomTouched?Fs(t.room):null;let _=d&&!t.roomTouched?c?.space||null:u?.space||null;const m=d&&!t.roomTouched?c?.area||null:u?.area||null,g=d&&!t.roomTouched?c?.room_id||null:u?.roomId||null,f=_||h?.space||null,b=f?this.host._spaceModelById(f):this.host._spaceModel();if(!b)return;const v=b.id;"virtual"!==t.binding||_||(_=v);let y={};if(t.radarTouched){if(t.radarRemove)y={radar:null};else if(t.radar){const e=dh(t.radar,b.cellCm||5);if(!e)return void this.host._showToast(this.host._t("radar.invalid"));y={radar:e}}}else c&&Object.prototype.hasOwnProperty.call(c,"radar")&&(y={radar:c.radar});this.host._markerDialog={...t,busy:!0};let $=null,w=!1;try{const c="virtual"===t.binding?[]:n.filter(e=>e.removed&&e.binding===t.binding).map(t=>t.id),d=c.length>0,u=Ts(t.binding,t.controls,this.host._bindingEntities(t.binding)),f=n.find(t=>t.id===r||t.id===l)?.vacuum||null,k={id:r,vacuum:f,...y,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle?t.angle:null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===e&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:u.length?u:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:!!t.hideFromPlan};p&&(k.space=_,k.area=m,k.room_id=g);const x=h?.marker?.room_id??null,S=t.roomTouched&&null!=h&&(h.space!==_||h.area!==m||x!==g);let M=!1;const C=t.uploadId||l;if(C&&C!==r&&k.pdfs?.length)try{const t=await this.host.hass.callWS({type:"houseplan/files/migrate",from_id:C,to_id:r}),e=t?.mapping||{};k.pdfs=Ns(k.pdfs,C,r,e),M=Object.keys(e).length>0}catch(t){this.host._showToast(this.host._t("toast.files_migrate_failed",{err:this.host._errText(t)}))}a.markers=n,l&&l!==r&&(a.markers=Es(a.markers,l,r)),l&&l!==r&&"derived_marker_state"===k.value_badge?.source?.kind&&k.value_badge.source.ref===`marker:${l}`&&(k.value_badge.source={kind:"derived_marker_state",ref:`marker:${r}`}),l&&l!==r&&"derived_marker_state"===k.value_source?.kind&&k.value_source.ref===`marker:${l}`&&(k.value_source={kind:"derived_marker_state",ref:`marker:${r}`}),a.markers=a.markers.filter(t=>t.id!==r&&t.id!==l&&("virtual"===k.binding||t.binding!==k.binding)),a.markers.push(k);const P=new Set(c);l&&l!==r&&P.add(l),P.delete(r),P.size&&a.settings?.marker_area_snapshot&&(a.settings={...a.settings,marker_area_snapshot:Hs(a.settings.marker_area_snapshot,P)});let D=null;const I=l?this.host._layout[l]:null,T=I?{s:I.s||h?.space||this.host._space,x:I.x,y:I.y}:l&&h&&this.host._defPos[l]?this.host._normPos(h.space,this.host._defPos[l].x,this.host._defPos[l].y):null;if(!d&&T&&T.s===v)r===l&&this.host._layout[r]&&!S||(D={s:T.s,x:T.x,y:T.y});else if(d||!this.host._layout[r]||S){let t=b.vb[0]+b.vb[2]/2,e=b.vb[1]+b.vb[3]/2;const s=g?b.rooms.find(t=>t.id===g):m?b.rooms.find(t=>t.area===m):void 0;s&&([t,e]=this.host._roomCenter(s)),D=this.host._normPos(v,t,e)}if(this.host._serverCfg!==s||this.host._cfgRev!==i||Ft(s)!==o)return this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),void this.host._showToast(this.host._t("toast.conflict"));if(a=this._prepareConfigCandidate(a),$=this.host._adoption.beginOptimistic(s,a),this.host._serverCfg=a,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate(),this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.cancel(),await this._saveConfigNow($),w=!0,D){const t=Os(D);this.host._layout={...this.host._layout,[r]:t},this.host._noteLayoutRev(await this.host.hass.callWS({type:"houseplan/layout/update",device_id:r,pos:t}))}const z=new Set(c);l&&l!==r&&z.add(l),z.delete(r);for(const t of z)delete this.host._layout[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{});M&&C&&await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:C}).catch(()=>{}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_saved"))}catch(t){!w&&$&&(this.host._rollbackOptimistic($),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteMarker(){const t=this.host._markerDialog;if(!t||t.busy||!t.devId)return;const e=t.devId?this.host._devices.find(e=>e.id===t.devId):null,s=this.host._markers.find(e=>e.id===t.devId);if(!e&&!s)return;const i=e?"virtual"===e.bindingKind?"virtual":e.bindingKind&&e.bindingRef?`${e.bindingKind}:${e.bindingRef}`:"":s.binding;if(!i)return;const o=t.name||this.host._t("device.fallback"),a=t.devId,n=await this.host._confirmDanger({key:"remove-marker",kind:"destructive",title:this.host._t("confirm.remove_marker_title"),message:this.host._t("confirm.remove_marker_body"),objectName:o,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._markerDialog;if(!n||!r||r.busy||r.devId!==a)return;const l=this.host._devices.find(t=>t.id===a),h=this.host._markers.find(t=>t.id===a);if(!l&&!h)return;const c=this.host._serverCfg;if(!c)return;c.markers=c.markers||[];const d=c.markers,p=l?"virtual"===l.bindingKind?"virtual":l.bindingKind&&l.bindingRef?`${l.bindingKind}:${l.bindingRef}`:"":h.binding;if(!p||p!==i)return;const u=Ls(c.markers,a,p,"virtual"===p);c.markers=Bs(u.markers,u.cleanupIds);const _=u.cleanupIds;_.size&&c.settings?.marker_area_snapshot&&(c.settings={...c.settings,marker_area_snapshot:Hs(c.settings.marker_area_snapshot,_)}),this.host._markerDialog={...r,busy:!0};try{await this._saveConfigNow();for(const t of _){delete this.host._layout[t],delete this.host._defPos[t],this.host._dirtyPos.delete(t),this.host._sentPos.delete(t);const e=this.host._activityRt.get(t);e&&clearTimeout(e.timer),this.host._activityRt.delete(t),this.host._vacRt.delete(t),delete this.host._vacSrvTrails[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:t}).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/trail/delete",marker_id:t}).catch(()=>{})}this.host._deviceInboxReturn&&(this.host._deviceInboxReturn={...this.host._deviceInboxReturn,tab:"readd",anchor:p}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._infoCard?.id===a&&this.host._closeInfoCard(),this.host._selId===a&&(this.host._selId=null),this.host._drag?.id===a&&(this.host._drag=null),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_removed"))}catch(t){this.host._serverCfg===c&&(c.markers=d),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_openSpaceDialog(t,e){if(this.host._serverStorage&&this.host._serverCfg)if("edit"===t){const s=this.host._serverCfg.spaces.find(t=>t.id===e);if(!s)return;const i=Ws(s),o=s.settings?.custom_fill&&"object"==typeof s.settings.custom_fill?js(s.settings.custom_fill):null,a="none"===i.fill?{...o||Gs,a:0}:o;this.host._spaceDialog={mode:t,spaceId:e,title:s.title,planUrl:s.plan_url||null,planFile:null,source:s.plan_url?"file":"draw",showBorders:i.showBorders,showNames:i.showNames,zeroWallStyle:Us(s),displayTouched:!0,hideDecor:i.hideDecor,hideOpenings:i.hideOpenings,roomColor:i.color,roomOpacity:i.opacity,fillMode:"none"===i.fill?"custom":i.fill,customFill:a,glowEnabled:i.glow,bgColor:i.bgColor,bgMode:"static"===s.settings?.bg_mode||"daynight"===s.settings?.bg_mode?s.settings.bg_mode:null,northDeg:ce({},s.settings),sunRays:"boolean"==typeof s.settings?.sun_rays?s.settings.sun_rays:null,tempMin:i.tempMin,tempMax:i.tempMax,showLqi:i.showLqi??this.host._config?.show_signal??!0,cardFontScale:i.cardFontScale,labelTemp:i.labelTemp,labelHum:i.labelHum,labelLqi:i.labelLqi,labelLight:i.labelLight,cellCm:Number(s.cell_cm)>0?Number(s.cell_cm):5,cellCmInput:qs(Number(s.cell_cm)>0?Number(s.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1}}else this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...Zs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Ys,roomOpacity:Js,fillMode:"custom",customFill:{...Gs,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Vs,tempMax:Ks,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Xs(this.host._imperial),cellCmInput:qs(Xs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1};else this.host._showToast(this.host._t("toast.integration_missing"))}async _pickPlanFile(t){const e=t.target,s=e.files?.[0];if(!s||!this.host._spaceDialog)return;e.value="",this._decorAssetGuardReplace=null;const i=await bo(s);if("reject"===i.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===i.kind)return void(this.host._backdropGuard=i.state);const o=await vo(s,i.ext,s.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:o})}_renderBackdropGuard(){const t=this._decorAssetGuardReplace;return null!==t?yo(this.host,()=>{},()=>{this.host._backdropGuard=null,this._decorAssetGuardReplace=null},this.host.hass,(e,s)=>this._uploadDecorImage(e,s,t),(this.host._backdropGuard?.file.size||0)<=2097152)??d:yo(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??d}_useServerPlan(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let e=0;e<40;e++){const e=this.host._display(t);if(e){const s=await new Promise(t=>{const s=new Image;s.onload=()=>t(s.naturalWidth&&s.naturalHeight?s.naturalWidth/s.naturalHeight:0),s.onerror=()=>t(0),s.src=e}),i=this.host._spaceDialog;return i&&i.planUrl===t&&Number.isFinite(s)&&s>0?(this.host._spaceDialog={...i,savedAspect:s},s):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const e=this.host._spaceDialog,s=e?.saved?.find(e=>e.name===t);if(!e||!s||s.used_by.length||s.url===e.planUrl)return;const i=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),o=this.host._spaceDialog,a=o?.saved?.find(e=>e.name===t);if(i&&o&&a&&a.url===s.url&&a.modified===s.modified&&!a.used_by.length&&a.url!==o.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const e=this.host._spaceDialog;e?.saved&&(this.host._spaceDialog={...e,saved:e.saved.filter(e=>e.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return p`
    ${this.host._t("space.loading")}
    `;const e=t.saved||[];if(!e.length)return p`
    ${this.host._t("space.no_saved")}
    `;return p`
    +
    `:p``}_openingAt(t){if(!this.host._openingsR.length)return null;const e=this.host._openingsR.flatMap(e=>{const s=e.angle*Math.PI/180,i=t[0]-e.rx,o=t[1]-e.ry,a=i*Math.cos(s)+o*Math.sin(s);return Math.abs(a)>e.rlen/2+y(12,this.host._cellCm)?[]:[{o:e,localY:-i*Math.sin(s)+o*Math.cos(s)}]});if(!e.length)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i).value;return e.find(({o:t,localY:e})=>{const s="gate"===t.type?!t.flip_v:t.flip_v,i=t.partitionHost||this.host._spaceWalls.length||"gate"===t.type?this.host._openingFace(t,o,!!s):{ox:0,oy:0,cm:0,side:-1},a=ps({type:t.type,length:t.rlen,angle:t.angle,amount:this.host._openingAmt(t),flipH:!!t.flip_h,flipV:!!t.flip_v,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:i});return Math.abs(e)<=a.hitHalf})?.o||null}_resolveOpeningPlacement(t){const e=this.host._openingPreset;if("opening"!==this.host._tool||!e)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i),a=`${o.key}|partitions:${this.host._cfgEpoch}`;this.host._openingPlacementIntervalsCache&&this.host._openingPlacementIntervalsCache.key===a||(this.host._openingPlacementIntervalsCache={key:a,value:[...pt(s.rooms,this.host._spaceWalls,i,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id),...us(s.partitions,this.host._cellCm,this.host._gridPitch)]}),this.host._openingDimensionContextCache&&this.host._openingDimensionContextCache.key===a||(this.host._openingDimensionContextCache={key:a,value:Hc({rooms:s.rooms,walls:this.host._spaceWalls,openCuts:i,partitions:s.partitions,roomOpenings:this.host._roomWallOpeningInputs(),partitionCuts:this._partitionOpeningCuts(s),pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:id,epsilon:2e-4*this.host._gridPitch})});const n=_s({pointer:[t[0],t[1]],preset:e,geometryRevision:this.host._cfgEpoch,renderedLength:this.host._cmToUnits(e.lengthCm),intervals:this.host._openingPlacementIntervalsCache.value,baseTolerance:1.5*this.host._gridPitch,bodyPointerPadding:this._cssPxToRender("touch"===this.host._pointerModality.modality||"pen"===this.host._pointerModality.modality?10:6),gridStep:this.host._gridPitch});this.host._openingJambBlockCm=n.jambBlockedTarget?n.jambBlockedTarget.physicalHalfWidth/this.host._gridPitch*this.host._cellCm:null;const r=n.candidate;if(!r)return null;const l="gate"===r.type?!r.flipV:r.flipV;let h;if(r.host){const t=ct({id:"preview",type:r.type,x:r.x/id,y:r.y/id,angle:r.angle,length:r.renderedLength/id,host:r.host},s.partitions,id,this.host._cellCm,this.host._gridPitch).resolved;h=t?ms(t,l):{ox:0,oy:0,cm:0,side:-1}}else h=gs(o.value,{x:r.x,y:r.y,angle:r.angle,length:r.renderedLength,flip_v:l});const c="mi"===this.host.hass?.config?.unit_system?.length,d=qc(r,this.host._openingDimensionContextCache.value).map(t=>({x:t.label[0],y:t.label[1],text:Ot(t.distance/this.host._gridPitch*this.host._cellCm,c),dimension:t}));return{...r,face:h,measure:{labels:d,guide:r.measure.guide}}}_activateOpeningPlacement(t){this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingPreset=fs(t,++this.host._openingPresetRevision),this.host._openingHoverCandidate=null,this.host._cursorPt=null)}_clearOpeningPlacement(t){this.host._openingHoverCandidate=null,this.host._openingJambBlockCm=null,t&&(this.host._openingPreset=null,this.host._openingRebindId=null)}_openingClick(t){const e=this.host._spaceModel();if(!e)return;const s=this.host._openingRebindId?null:this._openingAt(t);if(s)return void this._editOpening(s);const i=this.host._openingPreset;if(!i)return;const o=this.host._openingHoverCandidate,a=o&&bs(o,[t[0],t[1]],i.revision,this.host._cfgEpoch)?o:this._resolveOpeningPlacement(t);if(!a){if(null!=this.host._openingJambBlockCm)return void this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(this.host._openingJambBlockCm,this.host._imperial)}));const s=1.5*this.host._gridPitch,i=lt(t,e.rooms,s);return i&&vs(i.x,i.y,i.angle,this.host._openCuts(),s)?void this.host._showToast(this.host._t("toast.opening_on_zero_wall")):void this.host._showToast(this.host._t("toast.opening_no_wall"))}const n=this.host._openingRebindId?this.host._curSpaceCfg?.openings?.find(t=>t.id===this.host._openingRebindId):null;this.host._openingDialog={...n?{id:n.id,type:n.type,lengthCm:Math.round(n.length*id/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:n.contact||"",lock:n.lock||"",invert:!!n.invert,flipH:!!n.flip_h,flipV:!!n.flip_v}:{type:a.type,lengthCm:a.lengthCm,contact:"",lock:"",invert:!1,flipH:a.flipH,flipV:a.flipV},...a.host?{host:a.host}:{},x:a.x,y:a.y,angle:a.angle},this.host._openingRebindId=null,this.host._openingHoverCandidate=null,this.host._cursorPt=null}_editOpening(t){this.host._openingDialog={id:t.id,type:t.type,lengthCm:Math.round(t.rlen/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:t.contact||"",lock:t.lock||"",invert:!!t.invert,flipH:!!t.flip_h,flipV:!!t.flip_v,..."partition"===t.host?.kind?{host:{...t.host}}:{},x:t.rx,y:t.ry,angle:t.angle}}_opPointerDown(t,e){if("plan"===this.host._mode&&this.host._spaceModel()&&"resize"!==this.host._tool){t.preventDefault(),t.stopPropagation();try{ad(t)}catch{}this.host._opDrag={id:e.id,moved:!1,sx:t.clientX,sy:t.clientY,dirty:!1,before:this._geometrySnapshot()}}}_opPointerMove(t,e){jo(this.host,"opening",()=>this._opPointerMoveNow(t,e))}_opPointerMoveNow(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;if(Math.abs(t.clientX-this.host._opDrag.sx)+Math.abs(t.clientY-this.host._opDrag.sy)<=3)return;const s=this.host._spaceModel();if(!s)return;const i=this._svgPoint(t),o=this.host._curSpaceCfg,a=o?.openings?.find(t=>t.id===e.id);if(!a)return;if("partition"===a.host?.kind){const t=s.partitions.find(t=>t.id===a.host.id);if(!t)return;const e=t.b[0]-t.a[0],o=t.b[1]-t.a[1],n=Math.hypot(e,o);if(!(n>1e-9))return;const r=e/n,l=o/n;if(Math.abs((i[0]-t.a[0])*l-(i[1]-t.a[1])*r)>4*this.host._gridPitch)return;const h=a.length*id/2+mt(t,this.host._cellCm,this.host._gridPitch);let c=(i[0]-t.a[0])*r+(i[1]-t.a[1])*l;if(c=Math.round(c/this.host._gridPitch)*this.host._gridPitch,c=Math.max(h,Math.min(n-h,c)),n<2*h-1e-9)return;const d=c/n,p=(t.a[0]+r*c)/id,u=(t.a[1]+l*c)/this.host._spaceH;let _=180*Math.atan2(o,e)/Math.PI;_>=90?_-=180:_<-90&&(_+=180);const m=a.host.t!==d||a.x!==p||a.y!==u||a.angle!==_;return this.host._opDrag.moved=!0,m&&(this.host._opDrag.dirty=!0),a.host={...a.host,t:d},a.x=p,a.y=u,a.angle=_,this.host._opMeasure=null,m&&this.host._cfgEpoch++,void this.host.requestUpdate()}const n=lt(i,s.rooms,4*this.host._gridPitch);if(!n)return;this.host._opDrag.moved=!0;const r=this._opRuler(n,a.length*id);this.host._opMeasure=r.measure;const l=r.x/id,h=r.y/this.host._spaceH,c=a.x!==l||a.y!==h||a.angle!==n.angle;if(c&&(this.host._opDrag.dirty=!0),a.x=l,a.y=h,a.angle=n.angle,Number(this.host._serverCfg?.model_version||0)>=9){const t=On(a,o?.wall_segments||[]);t?a.host=t:delete a.host}c&&this.host._cfgEpoch++,this.host.requestUpdate()}_opRuler(t,e){const s=this.host._spaceModel()?.rooms||[],i=this.host._gridPitch/2;let o=t.x,a=t.y,n=ys([o,a],t.angle,e,s,i);if(n&&n.centered&&(o!==n.wallCenter[0]||a!==n.wallCenter[1]))[o,a]=n.wallCenter,n=ys([o,a],t.angle,e,s,i);else if(n){const[r,l]=n.wallA,[h,c]=n.wallB,d=h-r,p=c-l,u=Math.hypot(d,p);if(u>0){const h=this.host._gridPitch,c=Math.min(e/2,u/2);let _=Math.round(((o-r)*d+(a-l)*p)/u/h)*h;_=Math.max(c,Math.min(u-c,_)),o=r+_/u*d,a=l+_/u*p,n=ys([o,a],t.angle,e,s,i)||n}}if(!n)return{x:o,y:a,angle:t.angle,measure:null};const r="mi"===this.host.hass?.config?.unit_system?.length,l=(t,e)=>({x:e[0],y:e[1],text:Ot(t/this.host._gridPitch*this.host._cellCm,r)});return{x:o,y:a,angle:t.angle,measure:{labels:[l(n.sideA,n.midA),l(n.sideB,n.midB)],guide:n.centered?{x:n.wallCenter[0],y:n.wallCenter[1],angle:t.angle}:null}}}_opPointerUp(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;Go(this.host,"opening");const s=this.host._opDrag,i=s.moved;this.host._opMeasure=null,i&&s.dirty&&this._commitPhysicalGeometry(this.host._t("history.move_opening"),s.before);const o=()=>{this.host._opDrag=null,this.host.requestUpdate()};i?window.setTimeout(o,0):o()}_opClick(t,e){"plan"===this.host._mode&&"resize"===this.host._tool||(t.stopPropagation(),this.host._opDrag?.moved||"plan"===this.host._mode&&this._editOpening(e))}_saveOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=this._geometrySnapshot(),o=this.host._spaceH,a=(e.openings||[]).find(e=>e.id===t.id),n={...a||{},id:t.id||"o"+Date.now().toString(36),type:t.type,x:t.x/id,y:t.y/o,angle:t.angle,length:a&&!t.lengthTouched?a.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/id,...t.host?{host:{...t.host}}:{}};if("partition"===n.host?.kind){const t=$s(a,n)?bt(n,s.partitions,id,this.host._cellCm,this.host._gridPitch):ct(n,s.partitions,id,this.host._cellCm,this.host._gridPitch);if(!t.resolved){const e=s.partitions.find(t=>t.id===n.host.id);if("does-not-fit-jamb"===t.reason&&e){const t=mt(e,this.host._cellCm,this.host._gridPitch);this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(t/this.host._gridPitch*this.host._cellCm,this.host._imperial)}))}else this.host._showToast(this.host._t("opening.partition_orphan"));return}const i=(e.openings||[]).flatMap(t=>{if(!t.host||t.id===n.id)return[];const e=ct(t,s.partitions,id,this.host._cellCm,this.host._gridPitch).resolved;return e?[e]:[]});if(ws(t.resolved,i))return void this.host._showToast(this.host._t("toast.opening_no_wall"));Object.assign(n,dt(n,t.resolved,id))}else if(Number(this.host._serverCfg?.model_version||0)>=9){const t=On(n,e.wall_segments||[]);if(!t)return void this.host._showToast(this.host._t("toast.opening_no_wall"));n.host=t}else delete n.host;"passage"===t.type?(delete n.contact,delete n.lock,delete n.invert,delete n.flip_h,delete n.flip_v):(n.contact=t.contact||null,n.lock=("door"===t.type||"gate"===t.type)&&t.lock||null,n.invert=t.invert||void 0,n.flip_h="gate"!==t.type&&t.flipH||void 0,n.flip_v=t.flipV||void 0),e.openings=e.openings||[];const r=e.openings.findIndex(t=>t.id===n.id);r>=0?e.openings[r]=n:e.openings.push(n),this._commitPhysicalGeometry(this.host._t(t.id?"history.edit_opening":"history.add_opening"),i),this.host._openingDialog=null,this.host.requestUpdate()}_deleteOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg;if(!t?.id||!e?.openings)return;const s=this._geometrySnapshot();e.openings=e.openings.filter(e=>e.id!==t.id),this._commitPhysicalGeometry(this.host._t("history.delete_opening"),s),this.host._openingDialog=null,this.host.requestUpdate()}_contactCandidates(){const t=[];for(const e of Object.keys(this.host.hass.states)){if(!this.host._openingEntityAvailable(e))continue;const s=e.split(".")[0];if("binary_sensor"!==s&&"cover"!==s)continue;const i=this.host.hass.states[e],o=["door","window","opening","garage_door","garage"].includes(i?.attributes?.device_class||"");("cover"!==s||o)&&t.push([e,i?.attributes?.friendly_name||e,o?0:1])}return t.sort((t,e)=>t[2]-e[2]||t[1].localeCompare(e[1])).map(([t,e])=>({value:t,label:e}))}_lockCandidates(){return Object.keys(this.host.hass.states).filter(t=>t.startsWith("lock.")&&this.host._openingEntityAvailable(t)).map(t=>({value:t,label:this.host.hass.states[t]?.attributes?.friendly_name||t})).sort((t,e)=>t.label.localeCompare(e.label))}_toggleOpeningEntityPicker(t){const e=this.host._openingDialog;if(!e)return;const s="contact"===t?!e.contactOpen:!e.lockOpen;this.host._openingDialog={...e,contactOpen:"contact"===t&&s,lockOpen:"lock"===t&&s}}_filterOpeningEntities(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contactFilter:e}:{...s,lockFilter:e})}_selectOpeningEntity(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contact:e,contactOpen:!1,contactFilter:""}:{...s,lock:e,lockOpen:!1,lockFilter:""})}_mergeClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms,i=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!i?.id)return;const o=i.id;if(!this.host._mergeSel||this.host._mergeSel===o)return void(this.host._mergeSel=this.host._mergeSel===o?null:o);const a=s.find(t=>t.id===this.host._mergeSel),n=a?B(a):null,r=B(i),l=n&&r?ks(n,r):null;if(!l)return this.host._showToast(this.host._t("toast.merge_not_adjacent")),void(this.host._mergeSel=null);this.host._mergeDialog={aId:this.host._mergeSel,bId:o,poly:l,pick:"a"},this.host._mergeSel=null}_commitMerge(){const t=this.host._mergeDialog,e=this.host._curSpaceCfg;if(!t||!e||!this.host._spaceModel())return;const s=this._geometrySnapshot(),i=this.host._spaceH,o="a"===t.pick?t.aId:t.bId,a="a"===t.pick?t.bId:t.aId,n=Yc(this.host._serverCfg?.markers||[],{kind:"merge",dropId:a,keepId:o});s&&n.changed&&(s.roomReferences=n.before);const r=e.rooms.find(t=>t.id===o);if(!r)return void(this.host._mergeDialog=null);r.poly=t.poly.map(t=>[t[0]/id,t[1]/i]),delete r.x,delete r.y,delete r.w,delete r.h,e.rooms=e.rooms.filter(t=>t.id!==a),n.changed&&this.host._serverCfg&&(this.host._serverCfg.markers=n.markers);const l=this._commitPhysicalGeometry(this.host._t("history.merge_rooms"),s);this.host._mergeDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),l&&this.host._showToast(this.host._t("toast.rooms_merged",{name:r.name||""}))}_splitClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms;if(!this.host._splitSel){const e=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!e?.id)return;return void(this.host._splitSel={roomId:e.id,pts:[]})}const i=s.find(t=>t.id===this.host._splitSel.roomId),o=i?B(i):null;if(!i||!o)return void(this.host._splitSel=null);const a=.02*this.host._gridPitch,n=6*this.host._gridPitch,r=xs(t,o),l=r&&Ss(r,o,this.host._gridPitch)||r,h=r&&l&&Math.hypot(r[0]-t[0],r[1]-t[1])<=n?l:null,c=!!h&&Ms(h,o,a),d=this.host._splitSel.pts;if(!d.length)return c?void(this.host._splitSel={...this.host._splitSel,pts:[h]}):void this.host._showToast(this.host._t("toast.split_pick_wall"));if(!c){const e=this._snap(t);return Ce(e,o,a)?void(this.host._splitSel={...this.host._splitSel,pts:[...d,e]}):void this.host._showToast(this.host._t("toast.split_pick_inside"))}const p=De(o,[...d,h],a);if(!p)return void this.host._showToast(this.host._t("toast.split_bad_cut"));this._resetRoomDialogFields();const[u,_]=p,m=H(u)>=H(_)?u:_,g=m===u?_:u;this.host._pendingSplit={roomId:i.id,mainPoly:m,newPoly:g},this.host._cursorPt=null,this.host._nameSel="",this.host._areaSel="",this.host._roomDialog=!0}_markupMove(t){if(!this.host._markup)return;if("column"===this.host._tool)return void(this.host._cursorPt=this._snap(this._svgPoint(t)));if("opening"===this.host._tool||"wallthick"===this.host._tool)return void(this.host._cursorPt=this._svgPoint(t));const e="draw"===this.host._tool&&!this.host._contourClosed,s="split"===this.host._tool&&!!this.host._splitSel?.pts?.length;if(!e&&!s)return;const i=this._svgPoint(t);if(e){const e=this._resolvePlanDrawPoint(i,t.shiftKey);if(this.host._planSnapHover={contextKey:e.contextKey,candidate:e.candidate,conflicts:e.conflicts},this._syncPlanSnapConflictMarkers(e.conflicts),this._syncPlanSnapActiveMarker(e.candidate),!this.host._path.length)return;return void(this.host._cursorPt=e.point)}this.host._cursorPt=this._snap(i)}_saveRoom(){(this.host._areaSel||this.host._nameSel.trim())&&nt(this.host._roomTempMin,this.host._roomTempMax).valid&&(this.host._wallFaceBatch?this._decideWallFace(!0):this._commitRoom())}_decideWallFace(t){const e=this.host._wallFaceBatch;if(!e)return;const s=e.candidates[e.index];if(!s)return;if(!t&&(s.existing||s.repair)&&1===e.candidates.length)return this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate();const i=t?{candidate:s,create:!0,name:this.host._nameSel.trim(),area:this.host._areaSel||null,settings:this._roomSettingsFromDialog()?JSON.parse(JSON.stringify(this._roomSettingsFromDialog())):null}:{candidate:s,create:!1},o=[...e.decisions,i],a=e.index+1;if(a"number"==typeof t&&Number.isFinite(t)&&t>=0?t:null,o=.02*this.host._gridPitch,a=this.host._spaceModel();if(!a)return ut;for(const e of this._planSnapGeometrySnapshot().value.segments)if(!("room"===e.sourceKind||Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])>o)&&"partition"===e.sourceKind)return i(a.partitions.find(t=>t.id===e.sourceId)?.cm)??ut;const n=Ah(Math.max(0,e.length-1),s,this.host._drawWallCm,ut);for(let s=0;s+1[...t]);if(!e)return s;const i=this.host._activeWallChainPartitionIds.findIndex((t,s)=>this._activeWallSourceKey(s)===e.sourceKey),o=i>=0?i+("b"===e.endpoint?1:0):-1;return o>=0&&oe.key===t.sourceKey),a=i.find(e=>e.key===t.targetSourceKey);if(!o||!a)return!1;const n="a"===t.endpoint?o.a:o.b;return!(Math.hypot(n[0]-t.from[0],n[1]-t.from[1])>s)&&(!(Wt(t.to,[a.a[0],a.a[1],a.b[0],a.b[1]])>s)&&!function(t,e){if(!t.sourceKey.startsWith("static:partition|"))return!1;const s=t.sourceKey.slice(17).split("|")[0];return!!s&&e.some(t=>"partition"===t.host?.kind&&t.host.id===s)}(t,this.host._curSpaceCfg?.openings||[]))}_applyWallRepair(t,e){const s=this.host._curSpaceCfg;if(!s||!this._validateWallRepair(t,e.activePath))return!1;if(!t.sourceKey.startsWith("static:"))return!1;const[i,o]=t.sourceKey.slice(7).split("|");if("partition"===i){const i=(s.partitions||[]).find(t=>t.id===o);if(!i)return!1;const a=[i.a[0]*id,i.a[1]*id],n=[i.b[0]*id,i.b[1]*id],r=Math.hypot(a[0]-t.from[0],a[1]-t.from[1])<=2e-4*this.host._gridPitch?i.a:Math.hypot(n[0]-t.from[0],n[1]-t.from[1])<=2e-4*this.host._gridPitch?i.b:null;if(!r)return!1;(e=>{e[0]=t.to[0]/id,e[1]=t.to[1]/id})(r);const l=e.activePartitionIds.indexOf(o);if(l>=0){const s=l+("b"===t.endpoint?1:0);e.activePath[s]&&(e.activePath[s]=[...t.to])}return!0}return!1}_applyWallFaceBatch(){const t=this.host._wallFaceBatch,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=(t,e)=>{this.host._showToast(this.host._t(t,e)),this._roomDialogCancel()},o=t.decisions.filter(t=>t.create),a=o.map(t=>t.candidate.ring),n=s.rooms;for(let t=0;ts.id!==e&&!!B(s)&&N(a[t],B(s)));if(s)return void i("toast.room_overlap",{name:s.name||""})}if((e.rooms||[]).length+o.length>400)return void i("toast.physical_limit");if(o.some(t=>t.candidate.split&&!e.rooms.some(e=>e.id===t.candidate.split.roomId)))return void i("toast.contour_cannot_close");const r=o.map(t=>t.candidate.repair).filter(t=>!!t);if(r.length>1||r[0]&&!this._validateWallRepair(r[0],t.activePath))return void i("toast.wall_repair_changed");if(this._activePathWithRepair(t.activePath,r[0]),!o.length){if(!this._finalizeWallChainPartitions(t.activePartitionIds))return;return this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host.requestUpdate(),void this.host._showToast(this.host._t("toast.wall_chain_saved"))}const l=new Set(t.activePartitionIds),h=2e-4*this.host._gridPitch,c=o.map(t=>t.candidate.ring.map((t,e,i)=>{const o=i[(e+1)%i.length],a=s.partitions.filter(e=>{const s=Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1]);if(!(s>h))return!1;const i=(e.b[0]-e.a[0])/s,a=(e.b[1]-e.a[1])/s,n=t=>(t[0]-e.a[0])*i+(t[1]-e.a[1])*a;return Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&Wt(o,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&n(t)>=-h&&n(t)<=s+h&&n(o)>=-h&&n(o)<=s+h});return a.sort((t,e)=>Number(l.has(e.id))-Number(l.has(t.id))||Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])-Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1])||t.id.localeCompare(e.id)),a[0]?.id||""})),d=this._geometrySnapshot();if(!d)return void i("toast.geometry_unsafe");const p=()=>{this._restoreGeometryStateLocal(d),i("toast.geometry_unsafe")};if(r[0]&&!this._applyWallRepair(r[0],t))return void i("toast.wall_repair_changed");const u=o.some(t=>!!t.candidate.split),_=u?ae(s.rooms,e.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id):null,m=u&&Array.isArray(e.walls)?e.walls:null;for(const t of o){const s=t.candidate.split;if(!s)continue;const i=e.rooms.find(t=>t.id===s.roomId);if(!i)return void p();i.poly=s.mainPoly.map(t=>[t[0]/id,t[1]/this.host._spaceH]),delete i.x,delete i.y,delete i.w,delete i.h}const g=Date.now().toString(36),f=[];if(o.forEach((t,s)=>{const i=t.area?this.host.hass.areas[t.area]?.name:"",o={id:`r${g}-${s}`,name:t.name||i||this.host._t("room.default_name"),area:t.area||null,poly:t.candidate.ring.map(t=>[t[0]/id,t[1]/this.host._spaceH]),...c[s].some(Boolean)?{wall_ids:c[s]}:{},...t.settings?{settings:JSON.parse(JSON.stringify(t.settings))}:{}};e.rooms.push(o),f.push({room:o,decision:t})}),u){const t=this.host._normalizeWalls(_,this.host._openCuts());t.length?e.walls=t:m?.length?e.walls=m:delete e.walls}if(f.length){this.host._cfgEpoch++;const s=this.host._openCuts(),i=this.host._spaceModel();if(!i)return void p();let o=e.walls;for(const{room:e,decision:a}of f){const n=a.candidate.ring,r=this._wallSourceCmAt(n[0],t.activePath,t.activeCms);o=Cs(o,i.rooms,e.id,r,this.host._wallKeyPitch,s,id);for(const a of pt(i.rooms,o,s,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id)){if(a.roomId!==e.id||"outer"!==a.kind)continue;const s=[(a.a[0]+a.b[0])/2,(a.a[1]+a.b[1])/2];o=gt(o,a.a,a.b,this._wallSourceCmAt(s,t.activePath,t.activeCms),this.host._wallKeyPitch,id)}}const a=this.host._normalizeWalls(o,s);a.length?e.walls=a:delete e.walls,this.host._cfgEpoch++;const n=this.host._spaceModel();if(!n)return void p();const r=kl(e,n,e.walls,s,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:id,allowCoincidentPartitions:!0});r.walls.length?e.walls=r.walls:delete e.walls,r.partitions.length?e.partitions=r.partitions:delete e.partitions,r.openings.length?e.openings=r.openings:delete e.openings}if(!this._commitPhysicalGeometry(this.host._t("history.wall_face_batch"),d))return;this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host._regSignature="",this.host._maybeRebuildDevices();const b=new Set(o.map(t=>t.area).filter(t=>!!t));if(b.size){const t={...this.host._layout};for(const e of this.host._devices){if(!b.has(e.area||"")||e.space!==this.host._space)continue;if(this.host._layout[e.id])continue;const s=this.host._defPos[e.id];s&&(t[e.id]={s:this.host._space,x:s.x/id,y:s.y/id},this.host._dirtyPos.add(e.id))}this.host._layout=t,this.host._persistLayout()}this.host._showToast(this.host._t(o.length?"toast.wall_rooms_saved":"toast.wall_chain_saved",{n:o.length}))}_commitRoom(){const t=this.host._curSpaceCfg,e=this.host._spaceModel();if(!t||!e)return;const s=this._geometrySnapshot();if(!s)return;const i=()=>{this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe"))},o=this.host._spaceH,a=!!this.host._pendingSplit,n=a?ae(e.rooms,t.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id):null,r=a&&Array.isArray(t.walls)?t.walls:null;let l;if(this.host._pendingSplit){const e=t.rooms.find(t=>t.id===this.host._pendingSplit.roomId);if(!e)return this.host._pendingSplit=null,this.host._splitSel=null,void(this.host._roomDialog=!1);e.poly=this.host._pendingSplit.mainPoly.map(t=>[t[0]/id,t[1]/o]),delete e.x,delete e.y,delete e.w,delete e.h,l=this.host._pendingSplit.newPoly}else{if(!this.host._contourClosed)return;l=this.host._path.slice(0,-1)}const h=this.host._areaSel?this.host.hass.areas[this.host._areaSel]?.name:"",c={id:"r"+Date.now().toString(36),name:this.host._nameSel||h||this.host._t("room.default_name"),area:this.host._areaSel||null,poly:l.map(t=>[t[0]/id,t[1]/o]),...this._roomSettingsFromDialog()?{settings:this._roomSettingsFromDialog()}:{}};if(t.rooms.push(c),a){const e=this.host._normalizeWalls(n,this.host._openCuts());e.length?t.walls=e:r?.length?t.walls=r:delete t.walls}if(!a){const e=Ah(l.length,[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,ut),s=e[0];if(null!=s){this.host._cfgEpoch++;const o=this.host._openCuts(),a=this.host._spaceModel();if(!a)return void i();let n=Cs(t.walls,a.rooms,c.id,s,this.host._wallKeyPitch,o,id);for(const t of pt(a.rooms,n,o,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id)){if(t.roomId!==c.id||"outer"!==t.kind)continue;const s=[(t.a[0]+t.b[0])/2,(t.a[1]+t.b[1])/2],i=l.findIndex((t,e)=>{const i=l[(e+1)%l.length];return Wt(s,[t[0],t[1],i[0],i[1]])<=.02*this.host._gridPitch});i>=0&&(n=gt(n,t.a,t.b,e[i],this.host._wallKeyPitch,id))}n=this.host._normalizeWalls(n,o),n.length?t.walls=n:delete t.walls;const r=this.host._spaceModel();if(!r)return void i();const h=kl(t,r,t.walls,o,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:id,allowCoincidentPartitions:!0});h.walls.length?t.walls=h.walls:delete t.walls,h.partitions.length?t.partitions=h.partitions:delete t.partitions,h.openings.length?t.openings=h.openings:delete t.openings}}const d=this._commitPhysicalGeometry(this.host._t(a?"history.split_room":"history.add_room"),s);this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._pendingSplit=null,this.host._splitSel=null;const p=this.host._areaSel;if(this.host._areaSel="",this.host._nameSel="",this.host._roomDialog=!1,this.host._regSignature="",this.host._maybeRebuildDevices(),!d)return;let u=0;if(p){const t=id,e={...this.host._layout};for(const s of this.host._devices){if(s.area!==p||s.space!==this.host._space)continue;if(u++,this.host._layout[s.id])continue;const i=this.host._defPos[s.id];i&&(e[s.id]={s:this.host._space,x:i.x/id,y:i.y/t},this.host._dirtyPos.add(s.id))}this.host._layout=e,this.host._persistLayout()}const _=this.host._model.find(t=>t.id===this.host._space)?.rooms.length||0;this.host._showToast(p?this.host._t("toast.room_saved",{n:_,added:u}):this.host._t("toast.room_saved_no_area",{n:_}))}_cancelPath(){this.host._wallRepairDiagnostic=null,this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),this.host._roomDialog=!1,this.host._pendingSplit=null,this.host._wallFaceBatch=null,this.host._splitSel=null,this.host._mergeSel=null,this.host._mergeDialog=null,this.host._physicalSel=null,this.host._physicalDrag=null,this.host._physicalRotate=null,this._clearOpeningPlacement(!0)}_roomDialogCancel(){if(this.host._roomDialog=!1,this.host._roomEditId)return this.host._roomEditId=null,this.host._nameSel="",void(this.host._areaSel="");if(this.host._wallFaceBatch){const t=this.host._wallFaceBatch;return this.host._wallFaceBatch=null,this.host._path=t.activePath.map(t=>[...t]),this.host._wallChainSegmentCms=[...t.activeCms],this.host._activeWallChainPartitionIds=[...t.activePartitionIds],this.host._activeWallChainId||=`chain-${Date.now().toString(36)}`,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate()}if(this.host._pendingSplit)return this.host._pendingSplit=null,void(this.host._splitSel=null);this.host._undoPoint()}_openDeviceInbox(){this.host._deviceInboxReturn=null,this.host._deviceInbox=this.host._deviceInbox||{tab:"on_plan",search:"",showEntities:!1,onlyNew:!1,limit:100}}_closeMarkerDialog(){this._radarSetup.isDirty()?this._closeMarkerDialogGuarded():(this._radarSetup.reset(),function(t){if(t._markerDialog=null,!t._deviceInboxReturn)return;const e={...t._deviceInboxReturn};t._deviceInbox=e,t._deviceInboxReturn=null,e.anchor&&t.updateComplete.then(()=>requestAnimationFrame(()=>{const s=`.device-inbox-row[data-binding="${CSS.escape(e.anchor)}"]`;t.renderRoot.querySelector(s)?.scrollIntoView({block:"nearest"})}))}(this.host))}async _closeMarkerDialogGuarded(){if(!await this._radarSetup.discardIfAllowed())return await this.host.updateComplete,void this.host.renderRoot.querySelector("#marker-dialog")?.rejectClose();this._closeMarkerDialog()}_deviceInboxCandidates(t){return Xl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:t,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}})}_deviceInboxRows(){const t=this.host._deviceInbox||this.host._deviceInboxReturn,e=!!t?.showEntities,s=[this.host._haRegistry.revision,this.host._cfgRev,this.host._cfgEpoch,this.host._regSignature,this.host._newSyncKey,e?1:0,this.host._showAll?1:0,l(this.host.hass,this.host._config?.language)].join("|");if(this.host._deviceInboxMemo?.key===s)return this.host._deviceInboxMemo.rows;const i=this._deviceInboxCandidates(e),o=new Set(i.map(t=>t.value));for(const t of this.host._markers)t.binding&&"virtual"!==t.binding&&o.add(t.binding);for(const t of this.host._devices)t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&o.add(`${t.bindingKind}:${t.bindingRef}`);const a=new Map;for(const t of o)a.set(t,this.host._bindingStatus(t));const n=this.host._areaToSpace,r={};for(const[t,e]of Object.entries(this.host.hass?.areas||{}))r[t]=n[t]?.room?.name||e?.name||t;for(const[t,e]of Object.entries(n))r[t]=e.room.name||r[t]||t;const h=Object.fromEntries(this.host._model.map(t=>[t.id,t.title])),c=Object.fromEntries(Object.entries(n).map(([t,e])=>[t,e.space])),d={},p=new Map;for(const[t,e]of Object.entries(this.host._fullRegistryHass.entities||{})){const s=String(e?.platform||"").trim();if(s&&(d[`entity:${t}`]=s),s&&e?.device_id){const t=p.get(e.device_id)||new Set;t.add(s),p.set(e.device_id,t)}}for(const[t,e]of p)d[`device:${t}`]=[...e].sort().join(", ");const u={};for(const[t,e]of Object.entries(this.host._fullRegistryHass.devices||{})){const s=`device:${t}`,i=p.get(t)||new Set,o=Array.isArray(e?.identifiers?.[0])?String(e.identifiers[0][0]||""):"";o&&!d[s]&&(d[s]=o);const a=[o,...i].some(t=>this.host._excluded.has(t));"service"===e?.entry_type?u[s]="service_entry":a?u[s]="excluded_integration":"Group"===e?.model?u[s]="grouped_light":/scene/i.test(e?.model||"")?u[s]="excluded_domain":(/bridge/i.test(`${e?.model||""}${e?.name||""}`)||"myheat"===o&&e?.via_device_id)&&(u[s]="represented_by_parent")}const _=function(t){const{devices:e,markers:s,candidates:i,statuses:o,newDeviceIds:a,showHiddenOnPlan:n,areaNames:r={},spaceNames:l={},spaceByArea:h={},integrationByBinding:c={},reasonByBinding:d={}}=t,p=new Map;for(const t of e)!t.virtual&&t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&p.set(`${t.bindingKind}:${t.bindingRef}`,t);const u=new Map,_=new Map;for(const t of s)t?.binding&&"virtual"!==t.binding&&(t.removed?_.set(t.binding,t):u.set(t.binding,t));const m=new Map(i.map(t=>[t.value,t])),g=new Set([...p.keys(),...u.keys(),...m.keys(),...[..._.keys()].filter(t=>m.has(t))]),f=[];for(const t of g){const e=p.get(t),s=u.get(t),i=s?void 0:_.get(t),g=m.get(t);let b;if(i&&g)b="readd";else if(!0===s?.hidden)b="hidden";else if(e||s)b="on_plan";else{if(!g)continue;b="available"}const v=e?.bindingStatus||o.get(t)||Zl,y=s||i,$=Ql(t),w=e?.area||g?.areaId||y?.area||"",k=e?.space||y?.space||h[w]||"",x=e?.name||y?.name||g?.label||t,S=e?.model||y?.model||g?.model||"",M=!!g?.parentDeviceId&&p.has(`device:${g.parentDeviceId}`),C="readd"===b?"removed":"hidden"===b?s&&th(s)?d[t]||"automatic_hidden":"manual_hidden":"on_plan"===b?s?"visible_explicit":"visible_auto":d[t]||(M?"represented_by_parent":w&&k?"available":"no_bound_room"),P=!!e&&(!e.hidden||n),D="active"===v.kind,I=P&&(D||"ha_disabled"===v.kind&&n),T=[x,S,c[t],r[w],l[k],t,g?.sub].filter(Boolean).join(" ").toLocaleLowerCase();f.push({key:t,binding:t,category:b,status:v,reason:C,deviceId:e?.id,markerId:y?.id,name:x,icon:e?.icon||y?.icon||("entity"===$?"mdi:code-braces":"mdi:devices"),model:S,integration:c[t]||"",areaId:w,areaName:r[w]||"",spaceId:k,spaceName:l[k]||"",kind:$,isNew:!!e&&a.has(e.id),searchText:T,canFind:I,canEdit:!!e||!!s,canHide:"on_plan"===b&&D,canShow:"hidden"===b&&D,canAdd:("available"===b||"readd"===b)&&D})}const b=t=>"active"===t.status.kind?1:0;return f.sort((t,e)=>t.category.localeCompare(e.category)||Number(e.isNew)-Number(t.isNew)||b(t)-b(e)||t.name.localeCompare(e.name)||t.binding.localeCompare(e.binding))}({devices:this.host._devices,markers:this.host._markers,candidates:i,statuses:a,newDeviceIds:this.host._newIds,showHiddenOnPlan:this.host._showAll,areaNames:r,spaceNames:h,spaceByArea:c,integrationByBinding:d,reasonByBinding:u});return this.host._deviceInboxMemo={key:s,rows:_},_}_deviceForInboxRow(t){const e=t.deviceId?this.host._devices.find(e=>e.id===t.deviceId):null;if(e)return e;const s=t.markerId?this.host._markers.find(e=>e.id===t.markerId):null;return!s||s.removed?null:{id:s.id,name:t.name,model:t.model,area:t.areaId,space:t.spaceId||this.host._space,hidden:!0===s.hidden||"ha_disabled"===t.status.kind,userHidden:!0===s.hidden,bindingStatus:t.status,icon:t.icon,entities:"active"===t.status.kind?t.status.enabledEntityIds:[],allEntities:t.status.allEntityIds,primary:"active"===t.status.kind?t.status.enabledEntityIds[0]:void 0,marker:s,bindingKind:t.kind,bindingRef:t.binding.slice(t.binding.indexOf(":")+1),pdfs:s.pdfs||[]}}_openInboxMarker(t,e=!1){const s=this.host._deviceInbox;if(s){if(this.host._deviceInboxReturn={...s,anchor:t.key},this.host._deviceInbox=null,!e){const e=this._deviceForInboxRow(t);return void(e?this._openMarkerDialog(e):this._closeMarkerDialog())}this._openMarkerDialog(),this.host._markerDialog?this.host._markerDialog={...this.host._markerDialog,bindingMode:"ha",binding:t.binding,bindingOpen:!1,showEntities:"entity"===t.kind,name:""}:this._closeMarkerDialog()}}async _setInboxHidden(t,e){const s=this.host._deviceInbox,i=this.host._serverCfg;if(!s||!i||s.busy||"active"!==t.status.kind)return;const o=i.markers||[],a=o.find(e=>!e.removed&&e.binding===t.binding);if(!e&&!a)return;const n=a?.id||Ps(t.binding,t.markerId,()=>`m_${Date.now().toString(36)}`),r=a?{...a,hidden:e}:{id:n,binding:t.binding,hidden:!0};i.markers=[...o.filter(e=>e.id!==n&&(e.binding!==t.binding||!0===e.removed)),r],this.host._deviceInbox={...s,busy:t.key,anchor:t.key};try{await this._saveConfigNow(),this.host._regSignature="",this.host._deviceInboxMemo=null,this.host._maybeRebuildDevices(),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("device_inbox.saved"))}catch(t){this.host._serverCfg===i&&(i.markers=o),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_findInboxDevice(t){if(!t.canFind)return;const e=this._deviceForInboxRow(t);if(!e)return;if(this.host._deviceInbox=null,e.space&&e.space!==this.host._space){if(!this.host._commitSpace(e.space))return;this.host._restoreZoom()}const s=()=>{const t=this.host._devices.find(t=>t.id===e.id)||e,s=this.host._pos(t);this.host._applyView(this.host._zoom,s.x,s.y),this.host._selId=t.id,this.host.requestUpdate(),window.setTimeout(()=>{this.host._selId===t.id&&(this.host._selId=null,this.host.requestUpdate())},1500)};requestAnimationFrame(()=>requestAnimationFrame(s))}_openMarkerDialog(t){if(this.host._vacAllCamerasFor=null,this.host._vacAllCameraCache=null,t&&this.host._ackNewDevice(t.id),this.host._norm)if(t){const e=t.marker,s=Object.prototype.hasOwnProperty.call(e||{},"is_light"),i=Object.prototype.hasOwnProperty.call(e||{},"light_entity"),o=Object.prototype.hasOwnProperty.call(e||{},"glow_color"),a=Object.prototype.hasOwnProperty.call(e||{},"value_badge"),n=Object.prototype.hasOwnProperty.call(e||{},"value_source"),r=Object.prototype.hasOwnProperty.call(e||{},"tap_action"),l=Object.prototype.hasOwnProperty.call(e||{},"toggle_entity"),h=Ds(e?.glow_color),c=this.host._devicePresentation(t,!0).valueBadge,d=Is(this.host._planHass,t,this.host._devices),p=Ts(this.host._planHass,t,d),u=rh(t,this.host._fullRegistryHass),_=this.host._spaceModelById(t.space)||this.host._spaceModel(),m=this.host._pos(t),g=_?hh(t,_,[m.x,m.y],this.host._fullRegistryHass):null;this.host._markerDialog={devId:t.id,name:t.name,binding:"virtual"===t.bindingKind?"virtual":t.bindingKind+":"+t.bindingRef,bindingMode:"virtual"===t.bindingKind?"virtual":"ha",bindingOpen:!1,showEntities:"entity"===t.bindingKind&&!!this.host._fullRegistryHass.entities[t.bindingRef||""]?.device_id,bindingFilter:"",icon:t.marker?.icon||"",autoIcon:t.icon||"",display:As(t.marker?.display),rippleColor:x(t.marker?.ripple_color,""),rippleSize:Number(t.marker?.ripple_size)>0?Number(t.marker.ripple_size):1.5,size:Number(t.marker?.size)>0?Number(t.marker.size):1,angle:Number(t.marker?.angle)||0,tapAction:zs(t.marker?.tap_action,t.primary?.split(".")[0]),tapActionTouched:!1,originalHasTapAction:r,originalTapAction:t.marker?.tap_action,tapHintAnnouncement:"",toggleEntity:e?.toggle_entity||"",toggleEntityTouched:!1,originalHasToggleEntity:l,originalToggleEntity:e?.toggle_entity,tapTarget:t.marker?.tap_target||"",tapConfirm:!0===t.marker?.tap_confirm,runFilter:"",controls:Rs(t.marker?.binding,t.marker?.controls,t.entities),controlsFilter:"",lightRole:!0===e?.is_light?"always":!1===e?.is_light?"never":"auto",lightRoleTouched:!1,originalHasIsLight:s,originalIsLight:e?.is_light,lightEntity:e?.light_entity||"",lightEntityTouched:!1,originalHasLightEntity:i,originalLightEntity:e?.light_entity,glowMode:null!=h?.bri?"fixed":h?"color":"auto",glowColor:h?.c||this.host._fillColors.glow_light.c,glowBrightness:Math.max(1,Math.round(100*(h?.bri??1))),glowColorDrafted:!!h,glowBrightnessDrafted:null!=h?.bri,glowTouched:!1,originalHasGlowColor:o&&(!!h||null===e?.glow_color),originalGlowColor:h||(null===e?.glow_color?null:void 0),valueBadgeEnabled:a?!0===e?.value_badge?.enabled:!!c,valueBadgeSource:e?.value_badge?.source||c?.source||p,valueBadgePosition:e?.value_badge?.position||c?.position||"right",valueBadgeTouched:!1,originalHasValueBadge:a,originalValueBadge:e?.value_badge,valueSource:e?.value_source||null,valueSourceTouched:!1,originalHasValueSource:n,originalValueSource:e?.value_source,useClimateTemp:!0===t.marker?.use_climate_temp,glowRadius:Number(t.marker?.glow_radius_cm)>0?String(this.host._imperial?Math.round(Number(t.marker.glow_radius_cm)/30.48*10)/10:Math.round(Number(t.marker.glow_radius_cm))/100):"",model:t.model||"",link:t.link||"",description:t.description||"",pdfs:[...t.pdfs||[]],room:t.marker?.room_id?t.space+"#@"+t.marker.room_id:t.space&&t.area?t.space+"#"+t.area:"",roomTouched:!1,radar:g,radarEligible:u.eligible,radarTouched:!1,radarRemove:!1,hideFromPlan:!0===t.marker?.hidden,busy:!1}}else this.host._markerDialog={name:"",binding:"virtual",bindingMode:"virtual",bindingOpen:!1,showEntities:!1,bindingFilter:"",icon:"",autoIcon:"",display:"badge",rippleColor:"",rippleSize:1.5,size:1,angle:0,tapAction:"info",tapActionTouched:!1,originalHasTapAction:!1,originalTapAction:void 0,tapHintAnnouncement:"",toggleEntity:"",toggleEntityTouched:!1,originalHasToggleEntity:!1,originalToggleEntity:void 0,tapTarget:"",tapConfirm:!1,runFilter:"",controls:[],controlsFilter:"",lightRole:"auto",lightRoleTouched:!1,originalHasIsLight:!1,originalIsLight:void 0,lightEntity:"",lightEntityTouched:!1,originalHasLightEntity:!1,originalLightEntity:void 0,glowMode:"auto",glowColor:this.host._fillColors.glow_light.c,glowBrightness:100,glowColorDrafted:!1,glowBrightnessDrafted:!1,glowTouched:!1,originalHasGlowColor:!1,originalGlowColor:void 0,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgePosition:"right",valueBadgeTouched:!1,originalHasValueBadge:!1,originalValueBadge:void 0,valueSource:null,valueSourceTouched:!1,originalHasValueSource:!1,originalValueSource:void 0,useClimateTemp:!1,glowRadius:"",model:"",link:"",description:"",pdfs:[],room:"",roomTouched:!1,radar:null,radarEligible:!1,radarTouched:!1,radarRemove:!1,hideFromPlan:!1,busy:!1,uploadId:"up_"+Date.now().toString(36)+Math.random().toString(36).slice(2,6)};else this.host._showToast(this.host._t("toast.marker_needs_server"))}_runCandidates(){const t=[];for(const e of Fs)for(const[s,i]of Object.entries(this.host.hass.states))s.startsWith(e+".")&&this.host._planEntityAvailable(s)&&t.push({value:s,label:i?.attributes?.friendly_name||s,sub:this.host._t("run."+e)});return t.sort((t,e)=>t.sub.localeCompare(e.sub)||t.label.localeCompare(e.label))}_bindingCandidates(){const t=Xl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:!!this.host._markerDialog?.showEntities,currentBinding:this.host._markerDialog?.binding,currentDeviceId:this.host._markerDialog?.devId,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}}),e=(this.host._markerDialog?.bindingFilter||"").toLowerCase().trim(),s=e?t.filter(t=>(t.label+" "+t.sub+" "+t.value).toLowerCase().includes(e)):t;return s.sort((t,e)=>t.label.localeCompare(e.label)),s.slice(0,200)}_backupErrorText(t){const e=t?.code??t?.error;if("string"==typeof e){const t=`backup.error.${e}`,s=this.host._t(t);if(s!==t)return s}return this.host._errText(t)}async _pickMarkerFiles(t){const e=t.target,s=e.files?[...e.files]:[];if(e.value="",!s.length||!this.host._markerDialog)return;const i=this.host._markerDialog.uploadId||this.host._markerDialog.devId||"new",o=[];for(const t of s)try{const e=new FormData;e.append("marker_id",i),e.append("file",t,t.name);const s=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth("/api/houseplan/upload",{method:"POST",body:e}):await fetch("/api/houseplan/upload",{method:"POST",body:e,headers:this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}),a=await s.json().catch(()=>({}));if(!s.ok||a.error){const t={too_large:this.host._t("err.too_large",{mb:a.max_mb||50}),bad_ext:this.host._t("err.bad_ext"),unauthorized:this.host._t("err.unauthorized")};throw new Error(t[a.error]||a.error||"HTTP "+s.status)}o.push({name:a.name||t.name,url:a.url})}catch(e){this.host._showToast(this.host._t("toast.file_failed",{name:t.name,err:this.host._errText(e)}))}o.length&&this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:[...this.host._markerDialog.pdfs,...o]},this.host._showToast(this.host._t("toast.files_attached",{n:o.length})))}_removeMarkerPdf(t){this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:this.host._markerDialog.pdfs.filter(e=>e.url!==t)})}_markerLightFields(t){const e={};if(t.lightRoleTouched?"always"===t.lightRole?e.is_light=!0:"never"===t.lightRole&&(e.is_light=!1):t.originalHasIsLight&&(e.is_light=t.originalIsLight??null),t.lightEntityTouched?t.lightEntity&&(e.light_entity=t.lightEntity):t.originalHasLightEntity&&(e.light_entity=t.originalLightEntity??null),t.glowTouched){if("auto"!==t.glowMode){const s={c:x(t.glowColor,this.host._fillColors.glow_light.c)};"fixed"===t.glowMode&&(s.bri=Math.max(.01,Math.min(1,Math.round(t.glowBrightness)/100))),e.glow_color=s}}else t.originalHasGlowColor&&(e.glow_color=t.originalGlowColor??null);return e}_markerTapActionFields(t){return t.tapActionTouched?{tap_action:t.tapAction||null}:t.originalHasTapAction?{tap_action:t.originalTapAction??null}:{}}_markerToggleEntityFields(t){return(e={touched:t.toggleEntityTouched,originalHas:t.originalHasToggleEntity,original:t.originalToggleEntity,value:t.toggleEntity}).touched?e.value?{toggle_entity:e.value}:{}:e.originalHas?{toggle_entity:e.original??null}:{};var e}async _saveMarker(){const t=this.host._markerDialog;if(!t||t.busy)return;const e=this._effectiveMarkerTapAction(t);if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return;if("virtual"===t.binding&&!t.name.trim())return void this.host._showToast(this.host._t("toast.virtual_name_required"));if("run"===e&&!t.tapTarget)return void this.host._showToast(this.host._t("toast.run_target_required"));if(t.valueBadgeTouched&&t.valueBadgeEnabled&&!t.valueBadgeSource)return void this.host._showToast(this.host._t("toast.value_badge_source_required"));if("ha"===t.bindingMode){const e=this.host._bindingStatus(t.binding),s=t.devId?this.host._markers.find(e=>e.id===t.devId):null,i=!s||s.binding!==t.binding;if("active"!==e.kind&&i)return void this.host._showToast(this.host._t("ha_disabled"===e.kind?"toast.ha_disabled_add":"toast.ha_binding_unverified"));if("ha_disabled"===e.kind&&!0===s?.hidden&&!t.hideFromPlan)return this.host._markerDialog={...t,hideFromPlan:!0},void this.host._showToast(this.host._t("entity"===e.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device"))}const s=this.host._serverCfg;if(!s)return;const i=this.host._cfgRev,o=Ft(s);let a=JSON.parse(JSON.stringify(s));const n=a.markers||[],r=Ps(t.binding,t.devId,()=>"v_"+Date.now().toString(36)),l=t.devId,h=l?this.host._devices.find(t=>t.id===l):null,c=l?n.find(t=>t.id===l):null,d=!!c&&("string"==typeof c.area&&c.area.length>0||null===c.area&&!!c.space&&!!c.room_id),p="virtual"===t.binding||t.roomTouched||d,u="virtual"===t.binding||t.roomTouched?Ns(t.room):null;let _=d&&!t.roomTouched?c?.space||null:u?.space||null;const m=d&&!t.roomTouched?c?.area||null:u?.area||null,g=d&&!t.roomTouched?c?.room_id||null:u?.roomId||null,f=_||h?.space||null,b=f?this.host._spaceModelById(f):this.host._spaceModel();if(!b)return;const v=b.id;"virtual"!==t.binding||_||(_=v);let y={};if(t.radarTouched){if(t.radarRemove)y={radar:null};else if(t.radar){const e=ph(t.radar,b.cellCm||5);if(!e)return void this.host._showToast(this.host._t("radar.invalid"));y={radar:e}}}else c&&Object.prototype.hasOwnProperty.call(c,"radar")&&(y={radar:c.radar});this.host._markerDialog={...t,busy:!0};let $=null,w=!1;try{const c="virtual"===t.binding?[]:n.filter(e=>e.removed&&e.binding===t.binding).map(t=>t.id),d=c.length>0,u=Rs(t.binding,t.controls,this.host._bindingEntities(t.binding)),f=n.find(t=>t.id===r||t.id===l)?.vacuum||null,k={id:r,vacuum:f,...y,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle?t.angle:null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===e&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:u.length?u:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:!!t.hideFromPlan};p&&(k.space=_,k.area=m,k.room_id=g);const x=h?.marker?.room_id??null,S=t.roomTouched&&null!=h&&(h.space!==_||h.area!==m||x!==g);let M=!1;const C=t.uploadId||l;if(C&&C!==r&&k.pdfs?.length)try{const t=await this.host.hass.callWS({type:"houseplan/files/migrate",from_id:C,to_id:r}),e=t?.mapping||{};k.pdfs=Es(k.pdfs,C,r,e),M=Object.keys(e).length>0}catch(t){this.host._showToast(this.host._t("toast.files_migrate_failed",{err:this.host._errText(t)}))}a.markers=n,l&&l!==r&&(a.markers=Hs(a.markers,l,r)),l&&l!==r&&"derived_marker_state"===k.value_badge?.source?.kind&&k.value_badge.source.ref===`marker:${l}`&&(k.value_badge.source={kind:"derived_marker_state",ref:`marker:${r}`}),l&&l!==r&&"derived_marker_state"===k.value_source?.kind&&k.value_source.ref===`marker:${l}`&&(k.value_source={kind:"derived_marker_state",ref:`marker:${r}`}),a.markers=a.markers.filter(t=>t.id!==r&&t.id!==l&&("virtual"===k.binding||t.binding!==k.binding)),a.markers.push(k);const P=new Set(c);l&&l!==r&&P.add(l),P.delete(r),P.size&&a.settings?.marker_area_snapshot&&(a.settings={...a.settings,marker_area_snapshot:Os(a.settings.marker_area_snapshot,P)});let D=null;const I=l?this.host._layout[l]:null,T=I?{s:I.s||h?.space||this.host._space,x:I.x,y:I.y}:l&&h&&this.host._defPos[l]?this.host._normPos(h.space,this.host._defPos[l].x,this.host._defPos[l].y):null;if(!d&&T&&T.s===v)r===l&&this.host._layout[r]&&!S||(D={s:T.s,x:T.x,y:T.y});else if(d||!this.host._layout[r]||S){let t=b.vb[0]+b.vb[2]/2,e=b.vb[1]+b.vb[3]/2;const s=g?b.rooms.find(t=>t.id===g):m?b.rooms.find(t=>t.area===m):void 0;s&&([t,e]=this.host._roomCenter(s)),D=this.host._normPos(v,t,e)}if(this.host._serverCfg!==s||this.host._cfgRev!==i||Ft(s)!==o)return this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),void this.host._showToast(this.host._t("toast.conflict"));if(a=this._prepareConfigCandidate(a),$=this.host._adoption.beginOptimistic(s,a),this.host._serverCfg=a,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate(),this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.cancel(),await this._saveConfigNow($),w=!0,D){const t=Ls(D);this.host._layout={...this.host._layout,[r]:t},this.host._noteLayoutRev(await this.host.hass.callWS({type:"houseplan/layout/update",device_id:r,pos:t}))}const R=new Set(c);l&&l!==r&&R.add(l),R.delete(r);for(const t of R)delete this.host._layout[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{});M&&C&&await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:C}).catch(()=>{}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_saved"))}catch(t){!w&&$&&(this.host._rollbackOptimistic($),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteMarker(){const t=this.host._markerDialog;if(!t||t.busy||!t.devId)return;const e=t.devId?this.host._devices.find(e=>e.id===t.devId):null,s=this.host._markers.find(e=>e.id===t.devId);if(!e&&!s)return;const i=e?"virtual"===e.bindingKind?"virtual":e.bindingKind&&e.bindingRef?`${e.bindingKind}:${e.bindingRef}`:"":s.binding;if(!i)return;const o=t.name||this.host._t("device.fallback"),a=t.devId,n=await this.host._confirmDanger({key:"remove-marker",kind:"destructive",title:this.host._t("confirm.remove_marker_title"),message:this.host._t("confirm.remove_marker_body"),objectName:o,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._markerDialog;if(!n||!r||r.busy||r.devId!==a)return;const l=this.host._devices.find(t=>t.id===a),h=this.host._markers.find(t=>t.id===a);if(!l&&!h)return;const c=this.host._serverCfg;if(!c)return;c.markers=c.markers||[];const d=c.markers,p=l?"virtual"===l.bindingKind?"virtual":l.bindingKind&&l.bindingRef?`${l.bindingKind}:${l.bindingRef}`:"":h.binding;if(!p||p!==i)return;const u=Bs(c.markers,a,p,"virtual"===p);c.markers=Ws(u.markers,u.cleanupIds);const _=u.cleanupIds;_.size&&c.settings?.marker_area_snapshot&&(c.settings={...c.settings,marker_area_snapshot:Os(c.settings.marker_area_snapshot,_)}),this.host._markerDialog={...r,busy:!0};try{await this._saveConfigNow();for(const t of _){delete this.host._layout[t],delete this.host._defPos[t],this.host._dirtyPos.delete(t),this.host._sentPos.delete(t);const e=this.host._activityRt.get(t);e&&clearTimeout(e.timer),this.host._activityRt.delete(t),this.host._vacRt.delete(t),delete this.host._vacSrvTrails[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:t}).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/trail/delete",marker_id:t}).catch(()=>{})}this.host._deviceInboxReturn&&(this.host._deviceInboxReturn={...this.host._deviceInboxReturn,tab:"readd",anchor:p}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._infoCard?.id===a&&this.host._closeInfoCard(),this.host._selId===a&&(this.host._selId=null),this.host._drag?.id===a&&(this.host._drag=null),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_removed"))}catch(t){this.host._serverCfg===c&&(c.markers=d),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_openSpaceDialog(t,e){if(this.host._serverStorage&&this.host._serverCfg)if("edit"===t){const s=this.host._serverCfg.spaces.find(t=>t.id===e);if(!s)return;const i=js(s),o=s.settings?.custom_fill&&"object"==typeof s.settings.custom_fill?Gs(s.settings.custom_fill):null,a="none"===i.fill?{...o||qs,a:0}:o;this.host._spaceDialog={mode:t,spaceId:e,title:s.title,planUrl:s.plan_url||null,planFile:null,source:s.plan_url?"file":"draw",showBorders:i.showBorders,showNames:i.showNames,zeroWallStyle:Ks(s),displayTouched:!0,hideDecor:i.hideDecor,hideOpenings:i.hideOpenings,roomColor:i.color,roomOpacity:i.opacity,fillMode:"none"===i.fill?"custom":i.fill,customFill:a,glowEnabled:i.glow,bgColor:i.bgColor,bgMode:"static"===s.settings?.bg_mode||"daynight"===s.settings?.bg_mode?s.settings.bg_mode:null,northDeg:de({},s.settings),sunRays:"boolean"==typeof s.settings?.sun_rays?s.settings.sun_rays:null,tempMin:i.tempMin,tempMax:i.tempMax,showLqi:i.showLqi??this.host._config?.show_signal??!0,cardFontScale:i.cardFontScale,labelTemp:i.labelTemp,labelHum:i.labelHum,labelLqi:i.labelLqi,labelLight:i.labelLight,cellCm:Number(s.cell_cm)>0?Number(s.cell_cm):5,cellCmInput:Us(Number(s.cell_cm)>0?Number(s.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1}}else this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...Qs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Xs,roomOpacity:Ys,fillMode:"custom",customFill:{...qs,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Js,tempMax:Vs,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Zs(this.host._imperial),cellCmInput:Us(Zs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1};else this.host._showToast(this.host._t("toast.integration_missing"))}async _pickPlanFile(t){const e=t.target,s=e.files?.[0];if(!s||!this.host._spaceDialog)return;e.value="",this._decorAssetGuardReplace=null;const i=await vo(s);if("reject"===i.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===i.kind)return void(this.host._backdropGuard=i.state);const o=await yo(s,i.ext,s.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:o})}_renderBackdropGuard(){const t=this._decorAssetGuardReplace;return null!==t?$o(this.host,()=>{},()=>{this.host._backdropGuard=null,this._decorAssetGuardReplace=null},this.host.hass,(e,s)=>this._uploadDecorImage(e,s,t),(this.host._backdropGuard?.file.size||0)<=2097152)??d:$o(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??d}_useServerPlan(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let e=0;e<40;e++){const e=this.host._display(t);if(e){const s=await new Promise(t=>{const s=new Image;s.onload=()=>t(s.naturalWidth&&s.naturalHeight?s.naturalWidth/s.naturalHeight:0),s.onerror=()=>t(0),s.src=e}),i=this.host._spaceDialog;return i&&i.planUrl===t&&Number.isFinite(s)&&s>0?(this.host._spaceDialog={...i,savedAspect:s},s):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const e=this.host._spaceDialog,s=e?.saved?.find(e=>e.name===t);if(!e||!s||s.used_by.length||s.url===e.planUrl)return;const i=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),o=this.host._spaceDialog,a=o?.saved?.find(e=>e.name===t);if(i&&o&&a&&a.url===s.url&&a.modified===s.modified&&!a.used_by.length&&a.url!==o.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const e=this.host._spaceDialog;e?.saved&&(this.host._spaceDialog={...e,saved:e.saved.filter(e=>e.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return p`
    ${this.host._t("space.loading")}
    `;const e=t.saved||[];if(!e.length)return p`
    ${this.host._t("space.no_saved")}
    `;return p`
    ${e.map(e=>{return p`
    @@ -980,7 +980,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    `;var s})} -
    `}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const e="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const s="create"===t.mode?"s"+Date.now().toString(36):t.spaceId;let i=null;if("file"===t.source&&t.planFile){i={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:s,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let o=t.savedAspect||null;!i&&"file"===t.source&&t.planUrl&&!o&&this.host._aspectJob&&(o=await this.host._aspectJob||null);const a=this.host._serverCfg;let n;if("create"===t.mode)n=Qs(s,t.title.trim()),a.spaces.push(n);else{if(n=a.spaces.find(t=>t.id===s),!n)throw new Error("space "+s+" is gone from the config");n.title=t.title.trim()}i?(n.plan_url=i.url,n.plan_aspect=i.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==n.plan_url&&(n.plan_url=t.planUrl,n.plan_aspect=o),"draw"===t.source&&(n.plan_url=null,n.plan_aspect=null,delete n.plan_x,delete n.plan_y,delete n.plan_scale,delete n.plan_scale_x,delete n.plan_scale_y,delete n.plan_angle),n.settings={...n.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):Vs,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):Ks,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},n.zero_wall_style=t.zeroWallStyle,n.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(td,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(n.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length?this._openNextImport():e||this.host._importTotal>0?(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._showToast(this.host._t(e&&!this.host._importTotal?"toast.space_added_onboard":"import.done"))):(this.host._showToast("create"===t.mode?this.host._t("toast.space_added"):this.host._t("toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?this._setMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._saveNav())))}catch(t){"conflict"!==t?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const e=this.host._serverCfg;if(!e)return;const s=e.spaces.find(e=>e.id===t.spaceId),i=$o(e,this.host._layout||{},t.spaceId||""),o=1===e.spaces.length&&e.spaces[0]?.id===t.spaceId;if(i.count&&!o)return void(this.host._spaceDialog={...t,deleteBlockers:i.count});if(!s)return;const a=t.spaceId,n=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:wo(this.host._t("confirm.delete_space_body"),this.host._t("confirm.delete_space_vac_routes"),i.routeCount),objectName:s.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._spaceDialog,l=this.host._serverCfg;if(!n||!r||"edit"!==r.mode||r.busy||r.spaceId!==a||!l)return;if(!l.spaces.find(t=>t.id===a))return;const h=$o(l,this.host._layout||{},a),c=1===l.spaces.length&&l.spaces[0]?.id===a;if(!h.count||c){this.host._spaceDialog={...r,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:a,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,e]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:e,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...r,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===a&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){"conflict"!==t?.code&&"space_in_use"!==t?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=$o(e,this.host._layout||{},a),s=1===e.spaces.length&&e.spaces[0]?.id===a;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...r,deleteBlockers:h.count}}async _saveConfigNow(t=null){this.host._cfgEpoch++;try{await this._writeConfig(t)}catch(t){throw t?.physicalGeometryRolledBack?await this._reloadRejectedPhysicalWrite():"conflict"===t?.code&&await this.host._reloadConfigOnly(),t}}_saveSpaceCopy(){return Vl(this.host,{clearGeometryGesture:()=>this._clearGeometryGesture(),optimizeReferenceContext:()=>this._optimizeReferenceContext(!1),reportPreflightFailure:(t,e)=>this._reportPreflightFailure(t,e),saveConfigNow:t=>this._saveConfigNow(t),setMode:()=>this._setMode("plan"),showWallModelMigrationBlocked:t=>this._showWallModelMigrationBlocked(t)})}_startImport(){const t=this.host._importDialog;if(!t)return;const e=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,e.length?(this.host._importQueue=e,this.host._importTotal=e.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();void 0!==t&&(this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...Zs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Ys,roomOpacity:Js,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Vs,tempMax:Ks,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Xs(this.host._imperial),cellCmInput:qs(Xs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1})}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._showToast(this.host._t("import.done")))}_renderImportDialog(){const t=this.host._importDialog,e=t.floors.filter(t=>t.checked).length;return p``}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const e="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const s="create"===t.mode?"s"+Date.now().toString(36):t.spaceId;let i=null;if("file"===t.source&&t.planFile){i={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:s,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let o=t.savedAspect||null;!i&&"file"===t.source&&t.planUrl&&!o&&this.host._aspectJob&&(o=await this.host._aspectJob||null);const a=this.host._serverCfg;let n;if("create"===t.mode)n=ti(s,t.title.trim()),a.spaces.push(n);else{if(n=a.spaces.find(t=>t.id===s),!n)throw new Error("space "+s+" is gone from the config");n.title=t.title.trim()}i?(n.plan_url=i.url,n.plan_aspect=i.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==n.plan_url&&(n.plan_url=t.planUrl,n.plan_aspect=o),"draw"===t.source&&(n.plan_url=null,n.plan_aspect=null,delete n.plan_x,delete n.plan_y,delete n.plan_scale,delete n.plan_scale_x,delete n.plan_scale_y,delete n.plan_angle),n.settings={...n.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):Js,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):Vs,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},n.zero_wall_style=t.zeroWallStyle,n.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(ed,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(n.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length?this._openNextImport():e||this.host._importTotal>0?(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._showToast(this.host._t(e&&!this.host._importTotal?"toast.space_added_onboard":"import.done"))):(this.host._showToast("create"===t.mode?this.host._t("toast.space_added"):this.host._t("toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?this._setMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._saveNav())))}catch(t){"conflict"!==t?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const e=this.host._serverCfg;if(!e)return;const s=e.spaces.find(e=>e.id===t.spaceId),i=wo(e,this.host._layout||{},t.spaceId||""),o=1===e.spaces.length&&e.spaces[0]?.id===t.spaceId;if(i.count&&!o)return void(this.host._spaceDialog={...t,deleteBlockers:i.count});if(!s)return;const a=t.spaceId,n=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:ko(this.host._t("confirm.delete_space_body"),this.host._t("confirm.delete_space_vac_routes"),i.routeCount),objectName:s.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._spaceDialog,l=this.host._serverCfg;if(!n||!r||"edit"!==r.mode||r.busy||r.spaceId!==a||!l)return;if(!l.spaces.find(t=>t.id===a))return;const h=wo(l,this.host._layout||{},a),c=1===l.spaces.length&&l.spaces[0]?.id===a;if(!h.count||c){this.host._spaceDialog={...r,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:a,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,e]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:e,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...r,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===a&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){"conflict"!==t?.code&&"space_in_use"!==t?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=wo(e,this.host._layout||{},a),s=1===e.spaces.length&&e.spaces[0]?.id===a;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...r,deleteBlockers:h.count}}async _saveConfigNow(t=null){this.host._cfgEpoch++;try{await this._writeConfig(t)}catch(t){throw t?.physicalGeometryRolledBack?await this._reloadRejectedPhysicalWrite():"conflict"===t?.code&&await this.host._reloadConfigOnly(),t}}_saveSpaceCopy(){return Jl(this.host,{clearGeometryGesture:()=>this._clearGeometryGesture(),optimizeReferenceContext:()=>this._optimizeReferenceContext(!1),reportPreflightFailure:(t,e)=>this._reportPreflightFailure(t,e),saveConfigNow:t=>this._saveConfigNow(t),setMode:()=>this._setMode("plan"),showWallModelMigrationBlocked:t=>this._showWallModelMigrationBlocked(t)})}_startImport(){const t=this.host._importDialog;if(!t)return;const e=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,e.length?(this.host._importQueue=e,this.host._importTotal=e.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();void 0!==t&&(this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...Qs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Xs,roomOpacity:Ys,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Js,tempMax:Vs,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Zs(this.host._imperial),cellCmInput:Us(Zs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1})}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._showToast(this.host._t("import.done")))}_renderImportDialog(){const t=this.host._importDialog,e=t.floors.filter(t=>t.checked).length;return p`this.host._importDialog=null}>
    ${this.host._t("import.hint")}
    @@ -1000,13 +1000,13 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("import.start",{n:e})}
    -
    `}_supportPatch(t,e){const s=this.host._supportDialog;if(!s||s.draftId!==t)return null;const i={...s,...e};return this.host._supportDialog=i,i}async _focusSupport(t){await this.host.updateComplete,this.host.renderRoot.querySelector(t)?.focus({preventScroll:!0})}_updateSupportDraft(t,e){const s=this.host._supportDialog;if(!s||"building"===s.status||"sending"===s.status||"success"===s.status)return;const i={...s,[t]:e},o=xc({...i,attach:!1,preview:null});"message_required"===o&&"validation.message_required"===s.errorCode||"message_too_long"===o||"contact_too_long"===o?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:`validation.${o}`}):i.attach&&i.preview&&i.preview.expiresAt<=Date.now()?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:"support_preview_expired"}):this._supportPatch(s.draftId,{[t]:e,status:i.attach&&i.preview?"ready":"idle",errorCode:""})}async _discardSupportPreview(t){if(t)try{await this.host.hass.callWS({type:"houseplan/support/preview/discard",token:t})}catch{}}async _closeSupportDialog(){const t=this.host._supportDialog;if(t){if("building"===t.status||"sending"===t.status){const t=l(this.host.hass,this.host._config?.language);if(!await this.host._confirmDanger({key:"close-support-busy",kind:"warning",title:Ro(t,"support.close_busy_title"),message:Ro(t,"support.close_busy_body"),confirmLabel:this.host._t("btn.close"),cancelLabel:this.host._t("btn.cancel")}))return await this.host.updateComplete,void this.host.renderRoot.querySelector("#support-dialog")?.rejectClose()}clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this.host._supportDialog=null,t.preview?.token&&"success"!==t.status&&this._discardSupportPreview(t.preview.token)}}_scheduleSupportExpiry(t,e){clearTimeout(this._supportExpiryTimer);const s=Math.max(0,e.expiresAt-Date.now());this._supportExpiryTimer=window.setTimeout(()=>{const s=this.host._supportDialog;s&&s.draftId===t&&s.preview?.token===e.token&&s.attach&&"success"!==s.status&&"sending"!==s.status&&this._supportPatch(t,{status:"error",errorCode:"support_preview_expired"})},Math.min(s+20,2147483647))}_supportFacts(){const t=this.host._haRegistry;return Mc({userAgent:globalThis.navigator?.userAgent||"",language:l(this.host.hass,this.host._config?.language),registryAccess:t.access,registryLastSuccess:t.lastSuccess})}_supportPreviewRequestIsCurrent(t,e){const s=this.host._supportDialog;return e===this._supportPreviewGeneration&&s?.draftId===t&&s.attach}async _buildSupportPreview(t){const e=this.host._supportDialog;if(!e||e.draftId!==t||!e.attach||!yc(this.host._haSupportApi))return;const s=++this._supportPreviewGeneration;this._supportPatch(t,{status:"building",errorCode:""});let i="";try{const e=await this.host.hass.callWS({type:"houseplan/support/preview",card_version:ti(Yc),...this._supportFacts(),draft_id:t}),o=e&&"object"==typeof e?e:{},a=Date.now(),n="string"==typeof o.text?o.text:"",r=Number(o.size),l=Number(o.expires_in),h=Number(o.spaces),c=String(o.token||"");/^[0-9a-f]{48}$/.test(c)&&(i=c);const d=String(o.sha256||""),p=Number(o.version),u=String(o.format||""),_=(new TextEncoder).encode(n).byteLength;if(!/^[0-9a-f]{48}$/.test(c)||!/^[0-9a-f]{64}$/.test(d)||"houseplan-support-package"!==u||1!==p||!Number.isInteger(r)||r!==_||!Number.isInteger(h)||h<0||!Number.isFinite(l)||l<=0||l>600||!n.endsWith("\n"))throw{code:"support_rejected"};const m={token:c,expiresAt:a+1e3*l,size:r,sha256:d,spaces:h,format:u,version:p,text:n,preparedAt:a};if(!this._supportPreviewRequestIsCurrent(t,s))return i="",void this._discardSupportPreview(c);if(!this._supportPatch(t,{status:"ready",preview:m,errorCode:"",rawOpen:!1}))return i="",void this._discardSupportPreview(c);i="",this._scheduleSupportExpiry(t,m)}catch(e){if(i){const t=i;i="",this._discardSupportPreview(t)}if(!this._supportPreviewRequestIsCurrent(t,s))return;if(!this._supportPatch(t,{status:"error",errorCode:Cc(e)}))return;this._focusSupport("#support-error")}}async _setSupportAttachment(t){const e=this.host._supportDialog;if(!e||"sending"===e.status||"success"===e.status)return;const s=e.preview?.token||"";if(!t)return this._supportPreviewGeneration+=1,clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPatch(e.draftId,{attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:""}),void(s&&this._discardSupportPreview(s));this._supportPatch(e.draftId,{attach:!0,errorCode:""}),await this._buildSupportPreview(e.draftId)}async _refreshSupportPreview(){const t=this.host._supportDialog;t&&t.attach&&"building"!==t.status&&"sending"!==t.status&&await this._buildSupportPreview(t.draftId)}_downloadSupportPreview(){const t=this.host._supportDialog?.preview;if(!t)return;const e=new Blob([t.text],{type:"application/json;charset=utf-8"}),s=URL.createObjectURL(e),i=document.createElement("a");i.href=s,i.download=`houseplan-support-${t.sha256.slice(0,12)}.json`,i.style.display="none",document.body.append(i),i.click(),i.remove(),window.setTimeout(()=>URL.revokeObjectURL(s),0)}async _copySupportText(t,e){const s=l(this.host.hass,this.host._config?.language);try{await navigator.clipboard.writeText(t),this.host._showToast(Ro(s,e))}catch{this.host._showToast(Ro(s,"support.copy_failed"))}}async _submitSupport(){const t=this.host._supportDialog;if(!t||!yc(this.host._haSupportApi))return;const e=xc(t);if(e)return this._supportPatch(t.draftId,{status:"error",errorCode:`validation.${e}`}),void this._focusSupport("#support-message");if(!Sc(t))return;const s=wc(t),i=this._supportPatch(t.draftId,{status:"sending",errorCode:"",idempotencyKey:s.idempotencyKey,submissionFingerprint:s.fingerprint});if(i)try{const e=await this.host.hass.callWS({type:"houseplan/support/submit",message:i.message.trim(),contact:i.contact.trim(),...i.attach&&i.preview?{preview_token:i.preview.token}:{},idempotency_key:i.idempotencyKey}),s=e&&"object"==typeof e&&"report_id"in e?String(e.report_id||""):"";if(!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(s))throw{code:"support_unavailable"};if(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,!this._supportPatch(t.draftId,{status:"success",reportId:s,errorCode:""}))return;this._focusSupport("#support-receipt")}catch(e){if(!this._supportPatch(t.draftId,{status:"error",errorCode:Cc(e)}))return;this._focusSupport("#support-error")}}_supportErrorText(t){const e=l(this.host.hass,this.host._config?.language);if(t.errorCode.startsWith("validation.")){return Ro(e,`support.validation.${t.errorCode.slice(11)}`)}return Ro(e,`support.error.${t.errorCode||"support_unavailable"}`)}_supportMessageKeydown(t){"Enter"===t.key&&(t.ctrlKey||t.metaKey)&&(t.preventDefault(),this._submitSupport())}_renderSupportDialog(){const t=this.host._supportDialog,e=l(this.host.hass,this.host._config?.language),s="ru"===e?"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.ru.md":"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.md",i=yc(this.host._haSupportApi),o=(t,s)=>Ro(e,t,s),a="building"===t.status||"sending"===t.status,n=xc(t),r=t.preview?Math.max(0,Math.floor((Date.now()-t.preview.preparedAt)/6e4)):0,h="error"===t.status&&!t.errorCode.startsWith("validation."),c="validation.contact_too_long"===t.errorCode,u="validation.message_required"===t.errorCode||"validation.message_too_long"===t.errorCode;return p``}_supportPatch(t,e){const s=this.host._supportDialog;if(!s||s.draftId!==t)return null;const i={...s,...e};return this.host._supportDialog=i,i}async _focusSupport(t){await this.host.updateComplete,this.host.renderRoot.querySelector(t)?.focus({preventScroll:!0})}_updateSupportDraft(t,e){const s=this.host._supportDialog;if(!s||"building"===s.status||"sending"===s.status||"success"===s.status)return;const i={...s,[t]:e},o=Sc({...i,attach:!1,preview:null});"message_required"===o&&"validation.message_required"===s.errorCode||"message_too_long"===o||"contact_too_long"===o?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:`validation.${o}`}):i.attach&&i.preview&&i.preview.expiresAt<=Date.now()?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:"support_preview_expired"}):this._supportPatch(s.draftId,{[t]:e,status:i.attach&&i.preview?"ready":"idle",errorCode:""})}async _discardSupportPreview(t){if(t)try{await this.host.hass.callWS({type:"houseplan/support/preview/discard",token:t})}catch{}}async _closeSupportDialog(){const t=this.host._supportDialog;if(t){if("building"===t.status||"sending"===t.status){const t=l(this.host.hass,this.host._config?.language);if(!await this.host._confirmDanger({key:"close-support-busy",kind:"warning",title:Ao(t,"support.close_busy_title"),message:Ao(t,"support.close_busy_body"),confirmLabel:this.host._t("btn.close"),cancelLabel:this.host._t("btn.cancel")}))return await this.host.updateComplete,void this.host.renderRoot.querySelector("#support-dialog")?.rejectClose()}clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this.host._supportDialog=null,t.preview?.token&&"success"!==t.status&&this._discardSupportPreview(t.preview.token)}}_scheduleSupportExpiry(t,e){clearTimeout(this._supportExpiryTimer);const s=Math.max(0,e.expiresAt-Date.now());this._supportExpiryTimer=window.setTimeout(()=>{const s=this.host._supportDialog;s&&s.draftId===t&&s.preview?.token===e.token&&s.attach&&"success"!==s.status&&"sending"!==s.status&&this._supportPatch(t,{status:"error",errorCode:"support_preview_expired"})},Math.min(s+20,2147483647))}_supportFacts(){const t=this.host._haRegistry;return Cc({userAgent:globalThis.navigator?.userAgent||"",language:l(this.host.hass,this.host._config?.language),registryAccess:t.access,registryLastSuccess:t.lastSuccess})}_supportPreviewRequestIsCurrent(t,e){const s=this.host._supportDialog;return e===this._supportPreviewGeneration&&s?.draftId===t&&s.attach}async _buildSupportPreview(t){const e=this.host._supportDialog;if(!e||e.draftId!==t||!e.attach||!$c(this.host._haSupportApi))return;const s=++this._supportPreviewGeneration;this._supportPatch(t,{status:"building",errorCode:""});let i="";try{const e=await this.host.hass.callWS({type:"houseplan/support/preview",card_version:ei(Xc),...this._supportFacts(),draft_id:t}),o=e&&"object"==typeof e?e:{},a=Date.now(),n="string"==typeof o.text?o.text:"",r=Number(o.size),l=Number(o.expires_in),h=Number(o.spaces),c=String(o.token||"");/^[0-9a-f]{48}$/.test(c)&&(i=c);const d=String(o.sha256||""),p=Number(o.version),u=String(o.format||""),_=(new TextEncoder).encode(n).byteLength;if(!/^[0-9a-f]{48}$/.test(c)||!/^[0-9a-f]{64}$/.test(d)||"houseplan-support-package"!==u||1!==p||!Number.isInteger(r)||r!==_||!Number.isInteger(h)||h<0||!Number.isFinite(l)||l<=0||l>600||!n.endsWith("\n"))throw{code:"support_rejected"};const m={token:c,expiresAt:a+1e3*l,size:r,sha256:d,spaces:h,format:u,version:p,text:n,preparedAt:a};if(!this._supportPreviewRequestIsCurrent(t,s))return i="",void this._discardSupportPreview(c);if(!this._supportPatch(t,{status:"ready",preview:m,errorCode:"",rawOpen:!1}))return i="",void this._discardSupportPreview(c);i="",this._scheduleSupportExpiry(t,m)}catch(e){if(i){const t=i;i="",this._discardSupportPreview(t)}if(!this._supportPreviewRequestIsCurrent(t,s))return;if(!this._supportPatch(t,{status:"error",errorCode:Pc(e)}))return;this._focusSupport("#support-error")}}async _setSupportAttachment(t){const e=this.host._supportDialog;if(!e||"sending"===e.status||"success"===e.status)return;const s=e.preview?.token||"";if(!t)return this._supportPreviewGeneration+=1,clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPatch(e.draftId,{attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:""}),void(s&&this._discardSupportPreview(s));this._supportPatch(e.draftId,{attach:!0,errorCode:""}),await this._buildSupportPreview(e.draftId)}async _refreshSupportPreview(){const t=this.host._supportDialog;t&&t.attach&&"building"!==t.status&&"sending"!==t.status&&await this._buildSupportPreview(t.draftId)}_downloadSupportPreview(){const t=this.host._supportDialog?.preview;if(!t)return;const e=new Blob([t.text],{type:"application/json;charset=utf-8"}),s=URL.createObjectURL(e),i=document.createElement("a");i.href=s,i.download=`houseplan-support-${t.sha256.slice(0,12)}.json`,i.style.display="none",document.body.append(i),i.click(),i.remove(),window.setTimeout(()=>URL.revokeObjectURL(s),0)}async _copySupportText(t,e){const s=l(this.host.hass,this.host._config?.language);try{await navigator.clipboard.writeText(t),this.host._showToast(Ao(s,e))}catch{this.host._showToast(Ao(s,"support.copy_failed"))}}async _submitSupport(){const t=this.host._supportDialog;if(!t||!$c(this.host._haSupportApi))return;const e=Sc(t);if(e)return this._supportPatch(t.draftId,{status:"error",errorCode:`validation.${e}`}),void this._focusSupport("#support-message");if(!Mc(t))return;const s=kc(t),i=this._supportPatch(t.draftId,{status:"sending",errorCode:"",idempotencyKey:s.idempotencyKey,submissionFingerprint:s.fingerprint});if(i)try{const e=await this.host.hass.callWS({type:"houseplan/support/submit",message:i.message.trim(),contact:i.contact.trim(),...i.attach&&i.preview?{preview_token:i.preview.token}:{},idempotency_key:i.idempotencyKey}),s=e&&"object"==typeof e&&"report_id"in e?String(e.report_id||""):"";if(!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(s))throw{code:"support_unavailable"};if(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,!this._supportPatch(t.draftId,{status:"success",reportId:s,errorCode:""}))return;this._focusSupport("#support-receipt")}catch(e){if(!this._supportPatch(t.draftId,{status:"error",errorCode:Pc(e)}))return;this._focusSupport("#support-error")}}_supportErrorText(t){const e=l(this.host.hass,this.host._config?.language);if(t.errorCode.startsWith("validation.")){return Ao(e,`support.validation.${t.errorCode.slice(11)}`)}return Ao(e,`support.error.${t.errorCode||"support_unavailable"}`)}_supportMessageKeydown(t){"Enter"===t.key&&(t.ctrlKey||t.metaKey)&&(t.preventDefault(),this._submitSupport())}_renderSupportDialog(){const t=this.host._supportDialog,e=l(this.host.hass,this.host._config?.language),s="ru"===e?"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.ru.md":"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.md",i=$c(this.host._haSupportApi),o=(t,s)=>Ao(e,t,s),a="building"===t.status||"sending"===t.status,n=Sc(t),r=t.preview?Math.max(0,Math.floor((Date.now()-t.preview.preparedAt)/6e4)):0,h="error"===t.status&&!t.errorCode.startsWith("validation."),c="validation.contact_too_long"===t.errorCode,u="validation.message_required"===t.errorCode||"validation.message_too_long"===t.errorCode;return p`{this._closeSupportDialog()}}>

    ${o("support.about_group")}

    -
    ${this.host._t("gs.about_version",{v:ti(Yc)})}
    +
    ${this.host._t("gs.about_version",{v:ei(Xc)})}
    - `;var _}_preflightDiagnostics(t,e){const s=new Map((e?.spaces||[]).map(t=>[String(t?.id||""),t]));return{kind:"houseplan-optimize-preflight",origin:"runtime",cardVersion:ti(Yc),checkedAt:(new Date).toISOString(),preflightFingerprint:t.fingerprint,failures:t.failures.map(t=>({spaceId:t.spaceId,displayName:t.displayName,reason:t.reason,detail:t.detail??null,spaceGeometryFingerprint:s.has(t.spaceId)?Y(s.get(t.spaceId)):null}))}}_reportPreflightFailure(t,e){t.ok||t.fingerprint===this.host._reportedPreflightFingerprint||(this.host._reportedPreflightFingerprint=t.fingerprint,console.warn("[houseplan] optimize preflight failed",this._preflightDiagnostics(t,e)))}_preflightVersionsDiffer(){const t=this.host._haIntegrationVersion;return"string"==typeof t&&t.length>0&&t!==ti(Yc)}async _copyPreflightDiagnostics(){const t=this.host._alignDialog?.preflight;if(!t||t.ok)return;const e=JSON.stringify(this._preflightDiagnostics(t,this.host._alignDialog?.config??null),null,2);try{await navigator.clipboard.writeText(e),this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.preflight_copied"))}catch{this.host._preflightClipboardFallback=e}}_checkOptimizeGeometryImpl(t){return ei(t,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)})})}_checkSpacePhysicalGeometryImpl(t,e,s){return si(t,e,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)}),captureWallGeometry:s?(t,e)=>s(e):void 0})}_optimizeReferenceContext(t){const e=this.host._haRegistry,s=this.host._fullRegistryHass,i={},o=(...t)=>{for(const e of t){const t=String(e||"").trim();if(t)return t}return""};for(const[t,s]of Object.entries(e.devices||{}))i[t]=o(s?.name_by_user,s?.name,s?.model);for(const[t,s]of Object.entries(e.entities||{}))i[`lg_${t}`]=o(this.host.hass?.states?.[t]?.attributes?.friendly_name,s?.name,s?.original_name);for(const t of this.host._devices)i[t.id]=o(t.name,i[t.id]);for(const t of this.host._serverCfg?.markers||[]){const e=String(t.binding||"").indexOf(":"),a=e>0?t.binding.slice(0,e):"",n=e>0?t.binding.slice(e+1):"",r="device"===a?s?.devices?.[n]:"entity"===a?s?.entities?.[n]:null;i[t.id]=o(t.name,"device"===a?r?.name_by_user:null,r?.name,"entity"===a?this.host.hass?.states?.[n]?.attributes?.friendly_name:null,i[t.id])}return{effectiveAreaByMarker:Object.fromEntries(this.host._devices.filter(t=>!t.virtual&&!!t.area).map(t=>[t.id,t.area])),ownerRoster:{authoritative:e.authoritative,deviceIds:Object.keys(e.devices||{}),entityIds:[...new Set([...Object.keys(e.entities||{}),...Object.keys(this.host.hass?.states||{})])],names:i},removeLiveMissingPositions:t}}_previewAlignDialog(t){if(!this.host._norm||!this.host._serverCfg)return;const e=this.host._serverCfg.spaces||[];let s;try{s=Al(this.host._serverCfg,this.host._layout||{},this._optimizeReferenceContext(t))}catch(t){return void this._showWallModelMigrationBlocked(t)}const i=s.changed?this.host._checkOptimizeGeometry(s.config):null;i&&this._reportPreflightFailure(i,s.config);const o=Math.ceil(10*s.report.maxShiftCm)/10,a=e.find(t=>null!=t?.id&&String(t.id)===s.report.maxSpace),n=e.length>1&&a?String(a.title||a.id):"";this.host._preflightClipboardFallback=null,this.host._alignDialog={report:s.report,config:s.config,layout:s.layout,cm:o,where:n,preflight:i,changed:s.changed,busy:!1,removeLiveMissingPositions:t}}async _runAlignToGrid(){let t=this.host._alignDialog;if(!t||t.busy||!this.host._serverCfg||!t.changed||!t.preflight?.ok)return;const e=Ft(t.config);if(t.preflight.fingerprint!==e){const e=this.host._checkOptimizeGeometry(t.config);if(this._reportPreflightFailure(e,t.config),t={...t,preflight:e},this.host._alignDialog=t,!e.ok)return}this._clearGeometryGesture(),this.host._alignDialog={...t,busy:!0};try{await qr(this.host,t.config,t.layout),this.host._alignDialog=null,this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.align_done",{n:String(t.report.moved),m:String(t.report.migrated+t.report.canonicalized+t.report.coordsCanonicalized+t.report.latticeCoordinatesCanonicalized+t.report.wallsMerged+t.report.spansMerged+t.report.partitionsMerged+t.report.partitionsReconciled+t.report.openingsRehosted+t.report.wallsStraightened),r:String(t.report.spaceRefsRemapped+t.report.roomRefsRemapped+t.report.positionsRemapped+t.report.markersDetached+t.report.orphanRoomLabelsRemoved+t.report.orphanDevicePositionsRemoved+t.report.orphanGroupPositionsRemoved)}))}catch(t){if(this.host._alignDialog&&(this.host._alignDialog={...this.host._alignDialog,busy:!1}),"wall_model_client_outdated"===t?.code)return void this.host._showToast(this.host._t("toast.wall_model_client_outdated"));"conflict"===t?.code&&await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _undoPlanOptimization(){if(!this.host._canOptimizeUndo||this.host._optimizeUndoBusy)return;const t=this.host._undoKind;this._clearGeometryGesture(),this.host._optimizeUndoBusy=!0,this.host.requestUpdate();try{await this.host.hass.callWS({type:"houseplan/plan/optimize_undo",expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[e,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:e,layResp:s,reason:"optimize-undo",profile:"post-write"})).status)return;this.host._geometryHistory.clear(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._cacheSnapshot(),this.host.requestUpdate(),this.host._showToast(this.host._t("import"===t?"backup.import_undone":"gs.optimize_undone"))}catch(t){this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}finally{this.host._optimizeUndoBusy=!1,this.host.requestUpdate()}}async _runBackupExport(){const t=this.host._backupExportDialog;if(t&&!t.busy){this.host._backupExportDialog={...t,busy:!0,error:""};try{const e=await this.host.hass.callWS({type:"houseplan/export/create",kind:t.kind,space_id:"space"===t.kind?this.host._space:void 0,..."space"===t.kind&&t.planOnly?{plan_only:!0}:{},card_version:ti(Yc)}),s=new Blob([JSON.stringify(e.document,null,2)+"\n"],{type:"application/json;charset=utf-8"}),i=URL.createObjectURL(s),o=document.createElement("a");o.href=i,o.download=e.filename||`houseplan-${t.kind}.json`,o.style.display="none",document.body.append(o),o.click(),o.remove(),window.setTimeout(()=>URL.revokeObjectURL(i),0),this.host._backupExportDialog=null,this.host._showToast(this.host._t("backup.export_done"))}catch(t){this.host._backupExportDialog&&(this.host._backupExportDialog={...this.host._backupExportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _pickBackupImport(t){const e=t.target,s=e.files?.[0];if(e.value="",s){this.host._settingsDialog=null,this.host._backupImportDialog={filename:s.name,size:s.size,token:"",preview:null,expectedConfigRev:this.host._cfgRev,expectedLayoutRev:this.host._layoutRev,duplicatePolicy:"skip",confirmMissing:!1,busy:!0,error:""};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),await this.host._writeChain,this.host._persistLayout.pending()&&this.host._persistLayout.flush();const t="/api/houseplan/import/preview?duplicate_policy=skip",e={method:"POST",body:s,headers:{"content-type":"application/json"}},i=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth(t,e):await fetch(t,{...e,headers:{...e.headers,...this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}}),o=await i.json().catch(()=>({}));if(!i.ok||o.error)throw Object.assign(new Error(o.message||o.error||`HTTP ${i.status}`),{code:o.error});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,token:o.token,preview:o.preview,expectedConfigRev:o.expected_config_rev,expectedLayoutRev:o.expected_layout_rev,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _setBackupDuplicatePolicy(t){const e=this.host._backupImportDialog;if(e&&!e.busy&&e.token&&t!==e.duplicatePolicy){this.host._backupImportDialog={...e,duplicatePolicy:t,busy:!0,error:""};try{const s=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:e.token,duplicate_policy:t});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,preview:{...e.preview,...s.preview},expectedConfigRev:s.expected_config_rev,expectedLayoutRev:s.expected_layout_rev,confirmMissing:!1,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,duplicatePolicy:e.duplicatePolicy,preview:e.preview,confirmMissing:e.confirmMissing,busy:!1,error:this._backupErrorText(t)})}}}async _applyBackupImport(){const t=this.host._backupImportDialog;if(!t||t.busy||!t.token||!t.preview)return;if(t.preview.confirmation_required&&!t.confirmMissing)return;this.host._backupImportDialog={...t,busy:!0,error:""};const e=this.host._space;try{const s=await this.host.hass.callWS({type:"houseplan/import/apply",token:t.token,expected_config_rev:t.expectedConfigRev,expected_layout_rev:t.expectedLayoutRev,duplicate_policy:t.duplicatePolicy,confirm_missing_content:t.confirmMissing}),[i,o]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:i,layResp:o,reason:"import-apply",profile:"post-write"})).status)return this.host._backupImportDialog={...t,busy:!1,error:""},void this.host.requestUpdate();this.host._geometryHistory.clear(),this.host._dirtyPos.clear(),this.host._sentPos.clear(),this.host._defPos={},this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._visibleDeviceSnapshot=null,this.host._candidateDeviceSnapshot=null,this.host._stagedDeviceSnapshotToken=-1,this.host._capturedSnapshotConfigEpoch=-1,this.host._regSignature="",this.host._signer.invalidate(this.host.hass),this.host._resign(),this.host._maybeRebuildDevices();const a=this.host._serverCfg?.spaces||[],n="space"===s.kind&&s.space_id?s.space_id:a.some(t=>t.id===e)?e:a[0]?.id||this.host._space;this.host._hasFixedFloor?this.host._adoptInitialSpace(this.host._model,!0):this.host._commitSpace(n),this.host._backupImportDialog=null,this.host._cacheSnapshot(),this.host.requestUpdate();const r="space"===s.kind?t.preview.counts:s.counts;this.host._showToast(this.host._t("space"===s.kind?"backup.space_done":"backup.full_done",{spaces:String(r?.spaces||0),rooms:String(r?.rooms||0),markers:String(r?.markers||0),refs:String(s.repaired_target_refs||0)}))}catch(t){if("conflict"===t?.code&&this.host._backupImportDialog?.token)try{const t=this.host._backupImportDialog,e=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:t.token,duplicate_policy:t.duplicatePolicy});return void(this.host._backupImportDialog={...t,preview:{...t.preview,...e.preview},expectedConfigRev:e.expected_config_rev,expectedLayoutRev:e.expected_layout_rev,confirmMissing:!1,busy:!1,error:this.host._t("backup.revalidated")})}catch(e){t=e}this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}_renderBackupExportDialog(){const t=this.host._backupExportDialog,e=(this.host._serverCfg?.spaces||[]).find(t=>t.id===this.host._space);return p``;var _}_preflightDiagnostics(t,e){const s=new Map((e?.spaces||[]).map(t=>[String(t?.id||""),t]));return{kind:"houseplan-optimize-preflight",origin:"runtime",cardVersion:ei(Xc),checkedAt:(new Date).toISOString(),preflightFingerprint:t.fingerprint,failures:t.failures.map(t=>({spaceId:t.spaceId,displayName:t.displayName,reason:t.reason,detail:t.detail??null,spaceGeometryFingerprint:s.has(t.spaceId)?Y(s.get(t.spaceId)):null}))}}_reportPreflightFailure(t,e){t.ok||t.fingerprint===this.host._reportedPreflightFingerprint||(this.host._reportedPreflightFingerprint=t.fingerprint,console.warn("[houseplan] optimize preflight failed",this._preflightDiagnostics(t,e)))}_preflightVersionsDiffer(){const t=this.host._haIntegrationVersion;return"string"==typeof t&&t.length>0&&t!==ei(Xc)}async _copyPreflightDiagnostics(){const t=this.host._alignDialog?.preflight;if(!t||t.ok)return;const e=JSON.stringify(this._preflightDiagnostics(t,this.host._alignDialog?.config??null),null,2);try{await navigator.clipboard.writeText(e),this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.preflight_copied"))}catch{this.host._preflightClipboardFallback=e}}_checkOptimizeGeometryImpl(t){return si(t,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)})})}_checkSpacePhysicalGeometryImpl(t,e,s){return ii(t,e,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)}),captureWallGeometry:s?(t,e)=>s(e):void 0})}_optimizeReferenceContext(t){const e=this.host._haRegistry,s=this.host._fullRegistryHass,i={},o=(...t)=>{for(const e of t){const t=String(e||"").trim();if(t)return t}return""};for(const[t,s]of Object.entries(e.devices||{}))i[t]=o(s?.name_by_user,s?.name,s?.model);for(const[t,s]of Object.entries(e.entities||{}))i[`lg_${t}`]=o(this.host.hass?.states?.[t]?.attributes?.friendly_name,s?.name,s?.original_name);for(const t of this.host._devices)i[t.id]=o(t.name,i[t.id]);for(const t of this.host._serverCfg?.markers||[]){const e=String(t.binding||"").indexOf(":"),a=e>0?t.binding.slice(0,e):"",n=e>0?t.binding.slice(e+1):"",r="device"===a?s?.devices?.[n]:"entity"===a?s?.entities?.[n]:null;i[t.id]=o(t.name,"device"===a?r?.name_by_user:null,r?.name,"entity"===a?this.host.hass?.states?.[n]?.attributes?.friendly_name:null,i[t.id])}return{effectiveAreaByMarker:Object.fromEntries(this.host._devices.filter(t=>!t.virtual&&!!t.area).map(t=>[t.id,t.area])),ownerRoster:{authoritative:e.authoritative,deviceIds:Object.keys(e.devices||{}),entityIds:[...new Set([...Object.keys(e.entities||{}),...Object.keys(this.host.hass?.states||{})])],names:i},removeLiveMissingPositions:t}}_previewAlignDialog(t){if(!this.host._norm||!this.host._serverCfg)return;const e=this.host._serverCfg.spaces||[];let s;try{s=Fl(this.host._serverCfg,this.host._layout||{},this._optimizeReferenceContext(t))}catch(t){return void this._showWallModelMigrationBlocked(t)}const i=s.changed?this.host._checkOptimizeGeometry(s.config):null;i&&this._reportPreflightFailure(i,s.config);const o=Math.ceil(10*s.report.maxShiftCm)/10,a=e.find(t=>null!=t?.id&&String(t.id)===s.report.maxSpace),n=e.length>1&&a?String(a.title||a.id):"";this.host._preflightClipboardFallback=null,this.host._alignDialog={report:s.report,config:s.config,layout:s.layout,cm:o,where:n,preflight:i,changed:s.changed,busy:!1,removeLiveMissingPositions:t}}async _runAlignToGrid(){let t=this.host._alignDialog;if(!t||t.busy||!this.host._serverCfg||!t.changed||!t.preflight?.ok)return;const e=Ft(t.config);if(t.preflight.fingerprint!==e){const e=this.host._checkOptimizeGeometry(t.config);if(this._reportPreflightFailure(e,t.config),t={...t,preflight:e},this.host._alignDialog=t,!e.ok)return}this._clearGeometryGesture(),this.host._alignDialog={...t,busy:!0};try{await Ur(this.host,t.config,t.layout),this.host._alignDialog=null,this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.align_done",{n:String(t.report.moved),m:String(t.report.migrated+t.report.canonicalized+t.report.coordsCanonicalized+t.report.latticeCoordinatesCanonicalized+t.report.wallsMerged+t.report.spansMerged+t.report.partitionsMerged+t.report.partitionsReconciled+t.report.openingsRehosted+t.report.wallsStraightened),r:String(t.report.spaceRefsRemapped+t.report.roomRefsRemapped+t.report.positionsRemapped+t.report.markersDetached+t.report.orphanRoomLabelsRemoved+t.report.orphanDevicePositionsRemoved+t.report.orphanGroupPositionsRemoved)}))}catch(t){if(this.host._alignDialog&&(this.host._alignDialog={...this.host._alignDialog,busy:!1}),"wall_model_client_outdated"===t?.code)return void this.host._showToast(this.host._t("toast.wall_model_client_outdated"));"conflict"===t?.code&&await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _undoPlanOptimization(){if(!this.host._canOptimizeUndo||this.host._optimizeUndoBusy)return;const t=this.host._undoKind;this._clearGeometryGesture(),this.host._optimizeUndoBusy=!0,this.host.requestUpdate();try{await this.host.hass.callWS({type:"houseplan/plan/optimize_undo",expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[e,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:e,layResp:s,reason:"optimize-undo",profile:"post-write"})).status)return;this.host._geometryHistory.clear(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._cacheSnapshot(),this.host.requestUpdate(),this.host._showToast(this.host._t("import"===t?"backup.import_undone":"gs.optimize_undone"))}catch(t){this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}finally{this.host._optimizeUndoBusy=!1,this.host.requestUpdate()}}async _runBackupExport(){const t=this.host._backupExportDialog;if(t&&!t.busy){this.host._backupExportDialog={...t,busy:!0,error:""};try{const e=await this.host.hass.callWS({type:"houseplan/export/create",kind:t.kind,space_id:"space"===t.kind?this.host._space:void 0,..."space"===t.kind&&t.planOnly?{plan_only:!0}:{},card_version:ei(Xc)}),s=new Blob([JSON.stringify(e.document,null,2)+"\n"],{type:"application/json;charset=utf-8"}),i=URL.createObjectURL(s),o=document.createElement("a");o.href=i,o.download=e.filename||`houseplan-${t.kind}.json`,o.style.display="none",document.body.append(o),o.click(),o.remove(),window.setTimeout(()=>URL.revokeObjectURL(i),0),this.host._backupExportDialog=null,this.host._showToast(this.host._t("backup.export_done"))}catch(t){this.host._backupExportDialog&&(this.host._backupExportDialog={...this.host._backupExportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _pickBackupImport(t){const e=t.target,s=e.files?.[0];if(e.value="",s){this.host._settingsDialog=null,this.host._backupImportDialog={filename:s.name,size:s.size,token:"",preview:null,expectedConfigRev:this.host._cfgRev,expectedLayoutRev:this.host._layoutRev,duplicatePolicy:"skip",confirmMissing:!1,busy:!0,error:""};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),await this.host._writeChain,this.host._persistLayout.pending()&&this.host._persistLayout.flush();const t="/api/houseplan/import/preview?duplicate_policy=skip",e={method:"POST",body:s,headers:{"content-type":"application/json"}},i=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth(t,e):await fetch(t,{...e,headers:{...e.headers,...this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}}),o=await i.json().catch(()=>({}));if(!i.ok||o.error)throw Object.assign(new Error(o.message||o.error||`HTTP ${i.status}`),{code:o.error});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,token:o.token,preview:o.preview,expectedConfigRev:o.expected_config_rev,expectedLayoutRev:o.expected_layout_rev,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _setBackupDuplicatePolicy(t){const e=this.host._backupImportDialog;if(e&&!e.busy&&e.token&&t!==e.duplicatePolicy){this.host._backupImportDialog={...e,duplicatePolicy:t,busy:!0,error:""};try{const s=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:e.token,duplicate_policy:t});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,preview:{...e.preview,...s.preview},expectedConfigRev:s.expected_config_rev,expectedLayoutRev:s.expected_layout_rev,confirmMissing:!1,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,duplicatePolicy:e.duplicatePolicy,preview:e.preview,confirmMissing:e.confirmMissing,busy:!1,error:this._backupErrorText(t)})}}}async _applyBackupImport(){const t=this.host._backupImportDialog;if(!t||t.busy||!t.token||!t.preview)return;if(t.preview.confirmation_required&&!t.confirmMissing)return;this.host._backupImportDialog={...t,busy:!0,error:""};const e=this.host._space;try{const s=await this.host.hass.callWS({type:"houseplan/import/apply",token:t.token,expected_config_rev:t.expectedConfigRev,expected_layout_rev:t.expectedLayoutRev,duplicate_policy:t.duplicatePolicy,confirm_missing_content:t.confirmMissing}),[i,o]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:i,layResp:o,reason:"import-apply",profile:"post-write"})).status)return this.host._backupImportDialog={...t,busy:!1,error:""},void this.host.requestUpdate();this.host._geometryHistory.clear(),this.host._dirtyPos.clear(),this.host._sentPos.clear(),this.host._defPos={},this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._visibleDeviceSnapshot=null,this.host._candidateDeviceSnapshot=null,this.host._stagedDeviceSnapshotToken=-1,this.host._capturedSnapshotConfigEpoch=-1,this.host._regSignature="",this.host._signer.invalidate(this.host.hass),this.host._resign(),this.host._maybeRebuildDevices();const a=this.host._serverCfg?.spaces||[],n="space"===s.kind&&s.space_id?s.space_id:a.some(t=>t.id===e)?e:a[0]?.id||this.host._space;this.host._hasFixedFloor?this.host._adoptInitialSpace(this.host._model,!0):this.host._commitSpace(n),this.host._backupImportDialog=null,this.host._cacheSnapshot(),this.host.requestUpdate();const r="space"===s.kind?t.preview.counts:s.counts;this.host._showToast(this.host._t("space"===s.kind?"backup.space_done":"backup.full_done",{spaces:String(r?.spaces||0),rooms:String(r?.rooms||0),markers:String(r?.markers||0),refs:String(s.repaired_target_refs||0)}))}catch(t){if("conflict"===t?.code&&this.host._backupImportDialog?.token)try{const t=this.host._backupImportDialog,e=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:t.token,duplicate_policy:t.duplicatePolicy});return void(this.host._backupImportDialog={...t,preview:{...t.preview,...e.preview},expectedConfigRev:e.expected_config_rev,expectedLayoutRev:e.expected_layout_rev,confirmMissing:!1,busy:!1,error:this.host._t("backup.revalidated")})}catch(e){t=e}this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}_renderBackupExportDialog(){const t=this.host._backupExportDialog,e=(this.host._serverCfg?.spaces||[]).find(t=>t.id===this.host._space);return p`this.host._backupExportDialog=null}>
    ${this.host._t("backup.export_hint")}
    @@ -1217,7 +1217,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${t.busy?"…":this.host._t("full"===e.kind?"backup.replace":"backup.add")} `:d}
    -
    `}_setFillColor(t,e){const s=this.host._settingsDialog;this.host._settingsDialog={...s,colors:{...s.colors,[t]:{...s.colors[t],...e}}}}_updateDecorStyle(t){this.host._decorStyle=t,null!==this._decorStylePersistTimer&&window.clearTimeout(this._decorStylePersistTimer),this._decorStylePersistTimer=window.setTimeout(()=>{this._decorStylePersistTimer=null,this._persistDecorStyle()},1e3)}_persistDecorStyle(){const t=this.host._serverCfg;if(!t)return;const e=ii(this.host._decorStyle),s={...t.settings},i=JSON.stringify(s.decor_default_style??null);e?s.decor_default_style=e:delete s.decor_default_style,JSON.stringify(s.decor_default_style??null)!==i&&(this.host._serverCfg={...t,settings:s},this._saveConfig())}async _saveSettingsDialog(){const t=this.host._settingsDialog;if(!t||t.busy)return;this.host._settingsDialog={...t,busy:!0};let e=null;try{const s=this.host._serverCfg,i=JSON.stringify(t.colors)===JSON.stringify(oi);let o={...s.settings};i?delete o.fill_colors:o.fill_colors=t.colors;const a=this.host._imperial?30.48*t.glowRadius:100*t.glowRadius;Number.isFinite(a)&&a>0&&300!==Math.round(a)?o.glow_radius_cm=Math.round(a):delete o.glow_radius_cm,t.bgColor?o.bg_color=t.bgColor:delete o.bg_color,null!==t.northDeg&&Number.isInteger(t.northDeg)&&t.northDeg>=0&&t.northDeg<=359?o.north_deg=t.northDeg:delete o.north_deg,o.bg_mode=t.bgMode,t.sunRays?o.sun_rays=!0:delete o.sun_rays,t.showRoomTooltip?delete o.show_room_tooltip:o.show_room_tooltip=!1;const n=o.radar;n&&null!=n.version&&1!==n.version||(o.radar={...n||{},version:1},t.radarShowLive?delete o.radar.show_live:o.radar.show_live=!1),o=ai(o,t.zigbeeTopology),delete o.weather_entity;const r={...s,settings:o};e=this.host._adoption.beginOptimistic(s,r),this.host._serverCfg=r,await this._saveConfigNow(e),!t.showRoomTooltip&&this.host._tip?.room&&(this.host._tip=null),this.host._settingsDialog=null,this.host.requestUpdate(),this.host._showToast(this.host._t("gs.saved"))}catch(t){e&&this.host._rollbackOptimistic(e),this.host._settingsDialog&&(this.host._settingsDialog={...this.host._settingsDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_boolInput(t,e,s=!1){const i=t=>e(!!t.target.checked);return customElements.get("ha-switch")?p``:p``}_rangeInput(t,e,s,i,o,a=!1,n){const r=t=>{const e=Number(t.target.value);Number.isFinite(e)&&o(e)};return customElements.get("ha-slider")?p``}_setFillColor(t,e){const s=this.host._settingsDialog;this.host._settingsDialog={...s,colors:{...s.colors,[t]:{...s.colors[t],...e}}}}_updateDecorStyle(t){this.host._decorStyle=t,null!==this._decorStylePersistTimer&&window.clearTimeout(this._decorStylePersistTimer),this._decorStylePersistTimer=window.setTimeout(()=>{this._decorStylePersistTimer=null,this._persistDecorStyle()},1e3)}_persistDecorStyle(){const t=this.host._serverCfg;if(!t)return;const e=oi(this.host._decorStyle),s={...t.settings},i=JSON.stringify(s.decor_default_style??null);e?s.decor_default_style=e:delete s.decor_default_style,JSON.stringify(s.decor_default_style??null)!==i&&(this.host._serverCfg={...t,settings:s},this._saveConfig())}async _saveSettingsDialog(){const t=this.host._settingsDialog;if(!t||t.busy)return;this.host._settingsDialog={...t,busy:!0};let e=null;try{const s=this.host._serverCfg,i=JSON.stringify(t.colors)===JSON.stringify(ai);let o={...s.settings};i?delete o.fill_colors:o.fill_colors=t.colors;const a=this.host._imperial?30.48*t.glowRadius:100*t.glowRadius;Number.isFinite(a)&&a>0&&300!==Math.round(a)?o.glow_radius_cm=Math.round(a):delete o.glow_radius_cm,t.bgColor?o.bg_color=t.bgColor:delete o.bg_color,null!==t.northDeg&&Number.isInteger(t.northDeg)&&t.northDeg>=0&&t.northDeg<=359?o.north_deg=t.northDeg:delete o.north_deg,o.bg_mode=t.bgMode,t.sunRays?o.sun_rays=!0:delete o.sun_rays,o.sun_ray_origin=t.sunRayOrigin,t.showRoomTooltip?delete o.show_room_tooltip:o.show_room_tooltip=!1;const n=o.radar;n&&null!=n.version&&1!==n.version||(o.radar={...n||{},version:1},t.radarShowLive?delete o.radar.show_live:o.radar.show_live=!1),o=ni(o,t.zigbeeTopology),delete o.weather_entity;const r={...s,settings:o};e=this.host._adoption.beginOptimistic(s,r),this.host._serverCfg=r,await this._saveConfigNow(e),!t.showRoomTooltip&&this.host._tip?.room&&(this.host._tip=null),this.host._settingsDialog=null,this.host.requestUpdate(),this.host._showToast(this.host._t("gs.saved"))}catch(t){e&&this.host._rollbackOptimistic(e),this.host._settingsDialog&&(this.host._settingsDialog={...this.host._settingsDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_boolInput(t,e,s=!1){const i=t=>e(!!t.target.checked);return customElements.get("ha-switch")?p``:p``}_rangeInput(t,e,s,i,o,a=!1,n){const r=t=>{const e=Number(t.target.value);Number.isFinite(e)&&o(e)};return customElements.get("ha-slider")?p``:p``}_renderColorRow(t,e){const s=this.host._settingsDialog.colors[t];return p`
    ${this.host._t("gs.align_count",{n:String(e.moved),total:String(e.total),cm:String(t.cm)})}

    `:d} ${e.latticeCoordinatesCanonicalized?p` -

    ${this.host._t("gs.optimize_lattice_summary",{n:String(e.latticeCoordinatesCanonicalized),cm:ni(e.latticeMaxShiftCm)})}

    +

    ${this.host._t("gs.optimize_lattice_summary",{n:String(e.latticeCoordinatesCanonicalized),cm:ri(e.latticeMaxShiftCm)})}

    ${e.latticeSpaces.map(t=>p`

    ${this.host._t("gs.optimize_lattice_space",{space:t.space,n:String(t.canonicalized),far:String(t.far)})}

    `)} `:d} ${t.where?p`

    ${this.host._t("gs.align_where",{s:t.where})}

    `:d} @@ -1306,10 +1306,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 `}_renderSettingsDialog(){return p`this.host._settingsDialog=null}>
    -
    ${Ro(l(this.host.hass,this.host._config?.language),"gs.hint")}
    +
    ${Ao(l(this.host.hass,this.host._config?.language),"gs.hint")}
    `:d} - ${ri(this.host.hass)?d:p`
    ${this.host._t("gs.sun_missing")}
    `} + ${li(this.host.hass)?d:p`
    ${this.host._t("gs.sun_missing")}
    `}
    ${this.host._renderCompass()}
    @@ -1381,6 +1381,14 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this._boolInput(this.host._settingsDialog.sunRays,t=>this.host._settingsDialog={...this.host._settingsDialog,sunRays:t})} ${this.host._t("gs.sun_rays")} + ${t=this.host._settingsDialog.sunRayOrigin,e=t=>this.host._t(t),s=t=>this.host._settingsDialog={...this.host._settingsDialog,sunRayOrigin:t},p`
    + + +
    `} ${this.host._canEdit?p`
    ${this.host._t("gs.backup_hint")}
    @@ -1415,7 +1423,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    `:d}
    - @@ -1424,7 +1432,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._settingsDialog.busy?"…":this.host._t("btn.save")}
    -
    `}_rulesSet(t){this.host._rulesDialog={...this.host._rulesDialog,rules:t}}async _saveRules(){const t=this.host._rulesDialog;if(!t||t.busy)return;const e=t.rules.filter(t=>t.pattern.trim()&&t.icon.trim());this.host._rulesDialog={...t,busy:!0};try{const t=this.host._serverCfg,s=JSON.stringify(e)===JSON.stringify(pe),i={...t.settings};s?delete i.icon_rules:i.icon_rules=e,this.host._serverCfg={...t,settings:i},await this._saveConfigNow(),this.host._rulesDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("rules.saved"))}catch(t){this.host._rulesDialog&&(this.host._rulesDialog={...this.host._rulesDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_renderRulesDialog(){const t=this.host._rulesDialog,e=li(t.rules),s=t.test.trim()?hi(t.test,"",e):null,i=(e,s)=>{const i=[...t.rules],o=e+s;o<0||o>=i.length||([i[e],i[o]]=[i[o],i[e]],this._rulesSet(i))};return p``;var t,e,s}_rulesSet(t){this.host._rulesDialog={...this.host._rulesDialog,rules:t}}async _saveRules(){const t=this.host._rulesDialog;if(!t||t.busy)return;const e=t.rules.filter(t=>t.pattern.trim()&&t.icon.trim());this.host._rulesDialog={...t,busy:!0};try{const t=this.host._serverCfg,s=JSON.stringify(e)===JSON.stringify(ue),i={...t.settings};s?delete i.icon_rules:i.icon_rules=e,this.host._serverCfg={...t,settings:i},await this._saveConfigNow(),this.host._rulesDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("rules.saved"))}catch(t){this.host._rulesDialog&&(this.host._rulesDialog={...this.host._rulesDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_renderRulesDialog(){const t=this.host._rulesDialog,e=hi(t.rules),s=t.test.trim()?ci(t.test,"",e):null,i=(e,s)=>{const i=[...t.rules],o=e+s;o<0||o>=i.length||([i[e],i[o]]=[i[o],i[e]],this._rulesSet(i))};return p`this.host._rulesDialog=null}>
    ${this.host._t("rules.hint")}
    @@ -1434,7 +1442,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @input=${e=>this.host._rulesDialog={...t,test:e.target.value}} /> ${s?p`${s}`:d}
    - ${t.rules.map((e,s)=>{const o=""!==e.pattern.trim()&&!ci(e.pattern);return p`
    + ${t.rules.map((e,s)=>{const o=""!==e.pattern.trim()&&!di(e.pattern);return p`
    - @@ -1481,7 +1489,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    - `}_renderVacSection(t){const e=this.host._devices.find(e=>e.id===t.devId);if(!e||!this.host._isVacDev(e))return d;const s=e.marker?.vacuum||{},o=this.host._vacAllCamerasFor===e.id,a=this.host._vacSourceResolution(e,o),n=a.entityId,r=a.candidates.find(t=>t.entityId===n)||null,l=n?di(this.host.hass?.states[n]?.attributes):null,h=!1!==s.live&&("ok"===a.status||"unsupported"===a.status),c=this._vacPlanRoomAnchors(e.space),u=l?pi(l.rooms,c.map(t=>t.name)):0,_=!!(h&&l&&u>=3),m=t=>{const s=this.host._vacEnsureMarker(e);s&&(s.vacuum={...s.vacuum||{},...t},this.host._regSignature="",this.host._maybeRebuildDevices(),this._saveConfig(),this.host.requestUpdate())},g=new Set(e.entities||[]),f=a.candidates.filter(t=>g.has(t.entityId)||t.entityId===s.source),b=o?a.candidates.filter(t=>t.entityId.startsWith("camera.")&&!f.some(e=>e.entityId===t.entityId)):[],v=t=>[t.hasPosition?this.host._t("vac.cap_position"):"",t.hasRooms?this.host._t("vac.cap_rooms_short"):"",t.hasPath?this.host._t("vac.cap_path"):"",t.hasMapId?this.host._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this.host._t("vac.cap_none"),y=t=>p` + `}_renderVacSection(t){const e=this.host._devices.find(e=>e.id===t.devId);if(!e||!this.host._isVacDev(e))return d;const s=e.marker?.vacuum||{},o=this.host._vacAllCamerasFor===e.id,a=this.host._vacSourceResolution(e,o),n=a.entityId,r=a.candidates.find(t=>t.entityId===n)||null,l=n?pi(this.host.hass?.states[n]?.attributes):null,h=!1!==s.live&&("ok"===a.status||"unsupported"===a.status),c=this._vacPlanRoomAnchors(e.space),u=l?ui(l.rooms,c.map(t=>t.name)):0,_=!!(h&&l&&u>=3),m=t=>{const s=this.host._vacEnsureMarker(e);s&&(s.vacuum={...s.vacuum||{},...t},this.host._regSignature="",this.host._maybeRebuildDevices(),this._saveConfig(),this.host.requestUpdate())},g=new Set(e.entities||[]),f=a.candidates.filter(t=>g.has(t.entityId)||t.entityId===s.source),b=o?a.candidates.filter(t=>t.entityId.startsWith("camera.")&&!f.some(e=>e.entityId===t.entityId)):[],v=t=>[t.hasPosition?this.host._t("vac.cap_position"):"",t.hasRooms?this.host._t("vac.cap_rooms_short"):"",t.hasPath?this.host._t("vac.cap_path"):"",t.hasMapId?this.host._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this.host._t("vac.cap_none"),y=t=>p`
    `}_vacMapId(t,e,s=this.host._planHass){return this.host._vacMapId(t,e,s)}_vacSaveMatrix(t,e,s,i,o=""){return vc(this,t,e,s,i,o)}_vacPlanRoomAnchors(t){return(this.host._spaceModelById(t)?.rooms||[]).map(t=>({room:t,poly:B(t)})).filter(({room:t,poly:e})=>t.name&&e).map(({room:t,poly:e})=>{const s=_i(e);return s?{name:String(t.name),cx:s[0],cy:s[1]}:null}).filter(Boolean)}async _vacAutoCalibrate(t){if(this.host._markerDialog?.busy)return;const e=this.host._vacSource(t),s=e?di(this.host.hass?.states[e]?.attributes):null;if(!e||!s||s.rooms.length<3)return void this.host._showToast(this.host._t("vac.autocal_no_rooms"));const i=this._vacMapId(t,s),a=function(t,e,s,i,a){const n=o(t,e,s,i).find(t=>t.source===i&&t.map_id===a);return{space:n?.space||s,routeId:n?.id||""}}(t.id,t.marker?.vacuum??null,t.space,e,i),n=mi(s.rooms,this._vacPlanRoomAnchors(a.space));if(!n)return void this.host._showToast(this.host._t("vac.autocal_no_match"));const r=this.host._serverCfg?.spaces?.find(t=>t.id===a.space),l=Number(r?.cell_cm),h=Number.isFinite(l)&&l>0?l:5,c=gi(n.residual,this.host._gridPitch,h);c>fi?this.host._vacCalConfirm={markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length,error:Ot(c,"mi"===this.host.hass?.config?.unit_system?.length)}:await async function(t,e){if(fc.has(t))return;fc.add(t);const s=t.host,i=s._markerDialog,o=i?{...i,busy:!0}:null;o&&(s._markerDialog=o,s.requestUpdate());try{await vc(t,e.markerId,e.source,e.mapId,e.matrix,e.routeId)&&s._showToast(s._t("vac.autocal_done",{rooms:String(e.rooms)}))}finally{fc.delete(t),o&&s._markerDialog===o&&(s._markerDialog={...o,busy:!1},s.requestUpdate())}}(this,{markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length})}_vacApplyCalibrationProposal(t){return async function(t,e){const s=t.host,i=s._vacCalConfirm;if(!i||i.busy)return;if(e){const t=s._devices.find(t=>t.id===i.markerId),e=n(i.matrix);if(!t||!e)return;const o=i.space||t.space;if(o!==s._space&&!s._commitSpace(o))return;return s._vacCalConfirm=null,s._markerDialog=null,void(s._vacFit={markerId:i.markerId,source:i.source,routeId:i.routeId,mapId:i.mapId,p:e,drag:null})}const o={...i,busy:!0};s._vacCalConfirm=o,s.requestUpdate();const a=await vc(t,i.markerId,i.source,i.mapId,i.matrix,i.routeId);s._vacCalConfirm===o&&(s._vacCalConfirm=a?null:{...i,busy:!1},s.requestUpdate()),a&&s._showToast(s._t("vac.autocal_done",{rooms:String(i.rooms)}))}(this,t)}_vacStartFit(t,e=""){if(this.host._markerDialog?.busy)return;const s=this.host._vacSource(t),i=s?di(this.host.hass?.states[s]?.attributes):null;if(!s||!i)return void this.host._showToast(this.host._t("vac.cal_need_pos"));const l=this._vacMapId(t,i),h=function(t,e,s){const i=o(t,e,s.dockSpace,s.source),l=i.find(t=>t.id===s.routeId)||i.find(t=>t.source===s.source&&t.map_id===s.mapId)||null,h=l?.space||s.dockSpace,c=s.viewBoxOf(h);if(!c)return null;const d=a(l?l.calibration:e?.calibration?.[s.mapId]),p=d&&n(d)||r(s.rooms,c);return{space:h,routeId:l?.id||"",params:p}}(t.id,t.marker?.vacuum??null,{routeId:e,source:s,mapId:l,dockSpace:t.space,rooms:i.rooms,viewBoxOf:t=>this.host._spaceModelById(t)?.vb??null});h&&(this.host._markerDialog=null,(h.space===this.host._space||this.host._commitSpace(h.space))&&(this.host._vacFit={markerId:t.id,source:s,mapId:l,routeId:h.routeId,p:h.params,drag:null}))}_vacFitSave(){return async function(t,e){const s=t.host,i=s._vacFit;if(!i||i.busy)return;const o={...i,busy:!0,drag:null};s._vacFit=o,s.requestUpdate();const a=await vc(t,i.markerId,i.source,i.mapId,e(i.p),i.routeId);s._vacFit===o&&(s._vacFit=a?null:{...i,busy:!1,drag:null},s.requestUpdate()),a&&s._showToast(s._t("vac.cal_done"))}(this,vi)}_vacFitTurn(t){const e=this.host._vacFit;if(!e||e.busy)return;const s=di(this.host.hass?.states[e.source]?.attributes),i=this._vacGhostCentre(s?.rooms||[]),o={...e.p,...t};this.host._vacFit={...e,p:bi(o,e.p,i[0],i[1])}}_vacGhostCentre(t){const e=[],s=[];for(const i of t)e.push(i.x0??i.cx,i.x1??i.cx),s.push(i.y0??i.cy,i.y1??i.cy);return e.length?[(Math.min(...e)+Math.max(...e))/2,(Math.min(...s)+Math.max(...s))/2]:[0,0]}_vacDelta(t,e,s){const i=this.host._stageEl,o=i?.clientWidth||1,a=i?.clientHeight||1;return[e/o*t.w,s/a*t.h]}_vacFitPointer(t,e){const s=this.host._vacFit;if(!s)return;if(t.stopPropagation(),s.busy)return;if("pointerdown"===t.type){const e=t.target,i=e.getAttribute?.("data-corner");try{t.currentTarget.setPointerCapture?.(t.pointerId)}catch{}return void(this.host._vacFit={...s,drag:i?{kind:"scale",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:Number(i.split(",")[0]),fy:Number(i.split(",")[1])}:{kind:"move",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:0,fy:0}})}const i=s.drag;if(i){if("pointermove"===t.type){const[o,a]=this._vacDelta(e,t.clientX-i.sx,t.clientY-i.sy);if("move"===i.kind)this.host._vacFit={...s,p:{...i.p0,ox:i.p0.ox+o,oy:i.p0.oy+a}};else{const t=di(this.host.hass?.states[s.source]?.attributes),e=this._vacGhostCentre(t?.rooms||[]),n=vi(i.p0),[r,l]=yi(n,e[0],e[1]),[h,c]=yi(n,i.fx,i.fy),d=Math.hypot(r-h,l-c)||1,[p,u]=[2*r-h,2*l-c],_=Math.hypot(p+2*o-h,u+2*a-c)/2,m=Math.max(.05,_/d),g={...i.p0,s:i.p0.s*m};this.host._vacFit={...s,p:bi(g,i.p0,i.fx,i.fy)}}return}"pointerup"!==t.type&&"pointercancel"!==t.type||(this.host._vacFit={...s,drag:null})}}_renderVacFit(t){const e=this.host._vacFit;if(!e)return d;const s=di(this.host._renderPlanHass?.states?.[e.source]?.attributes);if(!s)return d;const i=vi(e.p),o=[],a=[],n=[];for(const t of s.rooms){if(null==t.x0)continue;const e=[[t.x0,t.y0],[t.x1,t.y0],[t.x1,t.y1],[t.x0,t.y1]].map(([t,e])=>yi(i,t,e));e.forEach(([t,e])=>{a.push(t),n.push(e)});const[s,r]=yi(i,t.cx,t.cy);o.push(_` - ${t.name}`)}let r=d;if(s.pos){const[e,o]=yi(i,s.pos.x,s.pos.y);r=_``}const l=[];if(a.length){const e=(()=>{const t=i[0]*i[4]-i[1]*i[3];return(e,s)=>[(i[4]*(e-i[2])-i[1]*(s-i[5]))/t,(-i[3]*(e-i[2])+i[0]*(s-i[5]))/t]})(),s=Math.min(...a),o=Math.max(...a),r=Math.min(...n),h=Math.max(...n),c=.022*t.w,d=c/4;for(const[t,i,a,n]of[[s,r,o,h],[o,r,s,h],[o,h,s,r],[s,h,o,r]]){const s=e(a,n);l.push(_``}_vacMapId(t,e,s=this.host._planHass){return this.host._vacMapId(t,e,s)}_vacSaveMatrix(t,e,s,i,o=""){return yc(this,t,e,s,i,o)}_vacPlanRoomAnchors(t){return(this.host._spaceModelById(t)?.rooms||[]).map(t=>({room:t,poly:B(t)})).filter(({room:t,poly:e})=>t.name&&e).map(({room:t,poly:e})=>{const s=mi(e);return s?{name:String(t.name),cx:s[0],cy:s[1]}:null}).filter(Boolean)}async _vacAutoCalibrate(t){if(this.host._markerDialog?.busy)return;const e=this.host._vacSource(t),s=e?pi(this.host.hass?.states[e]?.attributes):null;if(!e||!s||s.rooms.length<3)return void this.host._showToast(this.host._t("vac.autocal_no_rooms"));const i=this._vacMapId(t,s),a=function(t,e,s,i,a){const n=o(t,e,s,i).find(t=>t.source===i&&t.map_id===a);return{space:n?.space||s,routeId:n?.id||""}}(t.id,t.marker?.vacuum??null,t.space,e,i),n=gi(s.rooms,this._vacPlanRoomAnchors(a.space));if(!n)return void this.host._showToast(this.host._t("vac.autocal_no_match"));const r=this.host._serverCfg?.spaces?.find(t=>t.id===a.space),l=Number(r?.cell_cm),h=Number.isFinite(l)&&l>0?l:5,c=fi(n.residual,this.host._gridPitch,h);c>bi?this.host._vacCalConfirm={markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length,error:Ot(c,"mi"===this.host.hass?.config?.unit_system?.length)}:await async function(t,e){if(bc.has(t))return;bc.add(t);const s=t.host,i=s._markerDialog,o=i?{...i,busy:!0}:null;o&&(s._markerDialog=o,s.requestUpdate());try{await yc(t,e.markerId,e.source,e.mapId,e.matrix,e.routeId)&&s._showToast(s._t("vac.autocal_done",{rooms:String(e.rooms)}))}finally{bc.delete(t),o&&s._markerDialog===o&&(s._markerDialog={...o,busy:!1},s.requestUpdate())}}(this,{markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length})}_vacApplyCalibrationProposal(t){return async function(t,e){const s=t.host,i=s._vacCalConfirm;if(!i||i.busy)return;if(e){const t=s._devices.find(t=>t.id===i.markerId),e=n(i.matrix);if(!t||!e)return;const o=i.space||t.space;if(o!==s._space&&!s._commitSpace(o))return;return s._vacCalConfirm=null,s._markerDialog=null,void(s._vacFit={markerId:i.markerId,source:i.source,routeId:i.routeId,mapId:i.mapId,p:e,drag:null})}const o={...i,busy:!0};s._vacCalConfirm=o,s.requestUpdate();const a=await yc(t,i.markerId,i.source,i.mapId,i.matrix,i.routeId);s._vacCalConfirm===o&&(s._vacCalConfirm=a?null:{...i,busy:!1},s.requestUpdate()),a&&s._showToast(s._t("vac.autocal_done",{rooms:String(i.rooms)}))}(this,t)}_vacStartFit(t,e=""){if(this.host._markerDialog?.busy)return;const s=this.host._vacSource(t),i=s?pi(this.host.hass?.states[s]?.attributes):null;if(!s||!i)return void this.host._showToast(this.host._t("vac.cal_need_pos"));const l=this._vacMapId(t,i),h=function(t,e,s){const i=o(t,e,s.dockSpace,s.source),l=i.find(t=>t.id===s.routeId)||i.find(t=>t.source===s.source&&t.map_id===s.mapId)||null,h=l?.space||s.dockSpace,c=s.viewBoxOf(h);if(!c)return null;const d=a(l?l.calibration:e?.calibration?.[s.mapId]),p=d&&n(d)||r(s.rooms,c);return{space:h,routeId:l?.id||"",params:p}}(t.id,t.marker?.vacuum??null,{routeId:e,source:s,mapId:l,dockSpace:t.space,rooms:i.rooms,viewBoxOf:t=>this.host._spaceModelById(t)?.vb??null});h&&(this.host._markerDialog=null,(h.space===this.host._space||this.host._commitSpace(h.space))&&(this.host._vacFit={markerId:t.id,source:s,mapId:l,routeId:h.routeId,p:h.params,drag:null}))}_vacFitSave(){return async function(t,e){const s=t.host,i=s._vacFit;if(!i||i.busy)return;const o={...i,busy:!0,drag:null};s._vacFit=o,s.requestUpdate();const a=await yc(t,i.markerId,i.source,i.mapId,e(i.p),i.routeId);s._vacFit===o&&(s._vacFit=a?null:{...i,busy:!1,drag:null},s.requestUpdate()),a&&s._showToast(s._t("vac.cal_done"))}(this,yi)}_vacFitTurn(t){const e=this.host._vacFit;if(!e||e.busy)return;const s=pi(this.host.hass?.states[e.source]?.attributes),i=this._vacGhostCentre(s?.rooms||[]),o={...e.p,...t};this.host._vacFit={...e,p:vi(o,e.p,i[0],i[1])}}_vacGhostCentre(t){const e=[],s=[];for(const i of t)e.push(i.x0??i.cx,i.x1??i.cx),s.push(i.y0??i.cy,i.y1??i.cy);return e.length?[(Math.min(...e)+Math.max(...e))/2,(Math.min(...s)+Math.max(...s))/2]:[0,0]}_vacDelta(t,e,s){const i=this.host._stageEl,o=i?.clientWidth||1,a=i?.clientHeight||1;return[e/o*t.w,s/a*t.h]}_vacFitPointer(t,e){const s=this.host._vacFit;if(!s)return;if(t.stopPropagation(),s.busy)return;if("pointerdown"===t.type){const e=t.target,i=e.getAttribute?.("data-corner");try{t.currentTarget.setPointerCapture?.(t.pointerId)}catch{}return void(this.host._vacFit={...s,drag:i?{kind:"scale",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:Number(i.split(",")[0]),fy:Number(i.split(",")[1])}:{kind:"move",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:0,fy:0}})}const i=s.drag;if(i){if("pointermove"===t.type){const[o,a]=this._vacDelta(e,t.clientX-i.sx,t.clientY-i.sy);if("move"===i.kind)this.host._vacFit={...s,p:{...i.p0,ox:i.p0.ox+o,oy:i.p0.oy+a}};else{const t=pi(this.host.hass?.states[s.source]?.attributes),e=this._vacGhostCentre(t?.rooms||[]),n=yi(i.p0),[r,l]=$i(n,e[0],e[1]),[h,c]=$i(n,i.fx,i.fy),d=Math.hypot(r-h,l-c)||1,[p,u]=[2*r-h,2*l-c],_=Math.hypot(p+2*o-h,u+2*a-c)/2,m=Math.max(.05,_/d),g={...i.p0,s:i.p0.s*m};this.host._vacFit={...s,p:vi(g,i.p0,i.fx,i.fy)}}return}"pointerup"!==t.type&&"pointercancel"!==t.type||(this.host._vacFit={...s,drag:null})}}_renderVacFit(t){const e=this.host._vacFit;if(!e)return d;const s=pi(this.host._renderPlanHass?.states?.[e.source]?.attributes);if(!s)return d;const i=yi(e.p),o=[],a=[],n=[];for(const t of s.rooms){if(null==t.x0)continue;const e=[[t.x0,t.y0],[t.x1,t.y0],[t.x1,t.y1],[t.x0,t.y1]].map(([t,e])=>$i(i,t,e));e.forEach(([t,e])=>{a.push(t),n.push(e)});const[s,r]=$i(i,t.cx,t.cy);o.push(_` + ${t.name}`)}let r=d;if(s.pos){const[e,o]=$i(i,s.pos.x,s.pos.y);r=_``}const l=[];if(a.length){const e=(()=>{const t=i[0]*i[4]-i[1]*i[3];return(e,s)=>[(i[4]*(e-i[2])-i[1]*(s-i[5]))/t,(-i[3]*(e-i[2])+i[0]*(s-i[5]))/t]})(),s=Math.min(...a),o=Math.max(...a),r=Math.min(...n),h=Math.max(...n),c=.022*t.w,d=c/4;for(const[t,i,a,n]of[[s,r,o,h],[o,r,s,h],[o,h,s,r],[s,h,o,r]]){const s=e(a,n);l.push(_` `)}}return p`this._vacFitPointer(e,t)} @pointermove=${e=>this._vacFitPointer(e,t)} @pointerup=${e=>this._vacFitPointer(e,t)} - @pointercancel=${e=>this._vacFitPointer(e,t)}>${o}${r}${l}`}_resetRoomDialogFields(){this.host._roomEditId=null,this.host._roomFill="",this.host._roomCustomFill=null,this.host._roomTempMin="",this.host._roomTempMax="",this.host._roomTempSrc="",this.host._roomHumSrc="",this.host._roomSrcOpen=null,this.host._roomSrcFilter="",this.host._roomNameScale=1,this.host._roomLabelScale=1}_openRoomEdit(t){if(!t.id)return;this.host._roomEditId=t.id,this.host._nameSel=t.name||"",this.host._areaSel=t.area||"",this.host._roomFill="glow"===t.settings?.fill_mode?"":t.settings?.fill_mode||"";const e=t.settings?.custom_fill;this.host._roomCustomFill=e&&"object"==typeof e?js(e,Ws(this.host._curSpaceCfg).customFill):null,[this.host._roomTempMin,this.host._roomTempMax]=$i(t.settings),this.host._roomTempSrc=t.settings?.temp_source||"",this.host._roomHumSrc=t.settings?.hum_source||"",this.host._roomNameScale=wi(t.settings?.name_scale),this.host._roomLabelScale=wi(t.settings?.label_scale),this.host._roomSrcOpen=null,this.host._roomSrcFilter="",this.host._roomDialog=!0}_roomSettingsFromDialog(){const t={};return this.host._roomFill&&(t.fill_mode=this.host._roomFill),this.host._roomCustomFill&&(t.custom_fill=this.host._roomCustomFill),this.host._roomTempSrc&&(t.temp_source=this.host._roomTempSrc),this.host._roomHumSrc&&(t.hum_source=this.host._roomHumSrc),ki(t,this.host._roomTempMin,this.host._roomTempMax),1!==this.host._roomNameScale&&(t.name_scale=this.host._roomNameScale),1!==this.host._roomLabelScale&&(t.label_scale=this.host._roomLabelScale),Object.keys(t).length?t:null}_saveRoomEdit(){const t=this.host._curSpaceCfg,e=t?.rooms.find(t=>t.id===this.host._roomEditId);if(!e)return this.host._roomDialog=!1,void(this.host._roomEditId=null);e.name=this.host._nameSel.trim()||e.name,e.area=this.host._areaSel||null;const s=e.settings||{},i={...s};ki(i,this.host._roomTempMin,this.host._roomTempMax)&&(this.host._roomFill?i.fill_mode=this.host._roomFill:delete i.fill_mode,this.host._roomCustomFill?i.custom_fill=this.host._roomCustomFill:delete i.custom_fill,"glow"===s.fill_mode&&"boolean"!=typeof s.glow&&(i.glow=!0),this.host._roomTempSrc?i.temp_source=this.host._roomTempSrc:delete i.temp_source,this.host._roomHumSrc?i.hum_source=this.host._roomHumSrc:delete i.hum_source,1!==this.host._roomNameScale?i.name_scale=this.host._roomNameScale:delete i.name_scale,1!==this.host._roomLabelScale?i.label_scale=this.host._roomLabelScale:delete i.label_scale,Object.keys(i).length?e.settings=i:delete e.settings,this._saveConfig(),this.host._roomDialog=!1,this.host._roomEditId=null,this.host._nameSel="",this.host._areaSel="",this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate(),this.host._showToast(this.host._t("toast.room_updated")))}_roomSrcCandidates(){const t=this.host._planHass,e=Nt(this.host._markers),s=this.host._roomSrcFilter.trim().toLowerCase(),i=[];for(const o of Object.values(t.devices)){if("service"===o.entry_type)continue;if(e.devices.has(o.id))continue;const t=(o.name_by_user||o.name||o.id).trim();s&&!t.toLowerCase().includes(s)||i.push({value:"device:"+o.id,label:t,sub:o.model||this.host._t("marker.sub_device")})}for(const[o,a]of Object.entries(t.entities)){if(!o.startsWith("sensor.")||a.hidden)continue;if(Et(t,o,e))continue;const n=a.name||t.states[o]?.attributes?.friendly_name||o;s&&!(n+" "+o).toLowerCase().includes(s)||i.push({value:"entity:"+o,label:n,sub:o})}return i.sort((t,e)=>t.label.localeCompare(e.label)),i.slice(0,200)}_roomSrcLabel(t){const e=t.indexOf(":"),s=t.slice(0,e),i=t.slice(e+1);return"device"===s?this.host._fullRegistryHass.devices[i]?.name_by_user||this.host._fullRegistryHass.devices[i]?.name||i:this.host._fullRegistryHass.entities[i]?.name||this.host.hass.states[i]?.attributes?.friendly_name||i}_labelPos(t,e){const s=this.host._layout["rl_"+(t.id||"")];if(s&&s.s===e)return{x:s.x*sd,y:s.y*sd};const i=this._snap(this.host._roomCenter(t));return{x:i[0],y:i[1]}}_labelDown(t,e,s){if("plan"!==this.host._mode)return;t.preventDefault(),t.stopPropagation();const i=this._labelPos(e,s);this.host._drag={id:"rl_"+(e.id||""),sx:t.clientX,sy:t.clientY,ox:i.x,oy:i.y,moved:!1},od(t),this.host._tip=null}_labelMove(t,e,s){const i="rl_"+(e.id||"");if(!this.host._drag||this.host._drag.id!==i)return;const o=this.host._stageEl;if(!o)return;const a=this.host._spaceModelById(s);if(!a)return;const n=a.vb,r=o.getBoundingClientRect(),l=this.host._viewOr(n),h=(t.clientX-this.host._drag.sx)/r.width*l.w,c=(t.clientY-this.host._drag.sy)/r.height*l.h;Math.abs(t.clientX-this.host._drag.sx)+Math.abs(t.clientY-this.host._drag.sy)>3&&(this.host._drag.moved=!0);const d=ge(this.host._drag.ox+h),p=ge(this.host._drag.oy+c);this.host._savePos({id:i,space:s},d,p)}_labelUp(t){const e="rl_"+(t.id||"");if(!this.host._drag||this.host._drag.id!==e)return;const s=this.host._drag.moved;this.host._drag=s?this.host._drag:null,s&&window.setTimeout(()=>this.host._drag=null,0)}_labelScale(t){const e=this.host._layout["rl_"+(t.id||"")]?.k;return"number"==typeof e&&Number.isFinite(e)?Math.min(3,Math.max(.5,e)):1}_rlResizeDown(t,e,s){if("plan"!==this.host._mode)return;t.preventDefault(),t.stopPropagation();const i=t.target.closest(".roomlabel");if(!i)return;const o=i.getBoundingClientRect(),a=o.left+o.width/2,n=o.top+o.height/2,r=Math.max(8,Math.hypot(t.clientX-a,t.clientY-n));this.host._rlResize={id:"rl_"+(e.id||""),space:s,k0:this._labelScale(e),cx:a,cy:n,d0:r},od(t)}_rlResizeMove(t){const e=this.host._rlResize;if(!e)return;t.stopPropagation();const s=Math.max(8,Math.hypot(t.clientX-e.cx,t.clientY-e.cy)),i=Math.min(3,Math.max(.5,e.k0*(s/e.d0))),o=this.host._layout[e.id];if(o)this.host._layout={...this.host._layout,[e.id]:{...o,k:i}};else{const t=e.id.slice(3),s=this.host._spaceModelById(e.space);if(!s)return;const o=s.rooms.find(e=>e.id===t);if(!o)return;const a=this._labelPos(o,e.space);this.host._layout={...this.host._layout,[e.id]:{s:e.space,x:a.x/sd,y:a.y/sd,k:i}}}this.host._dirtyPos.add(e.id)}_rlResizeUp(){this.host._rlResize&&(this.host._rlResize=null,this.host._persistLayout())}_renderRoomGear(t,e,s){if(!t.id)return d;let i=null;if(t.poly?(i=this.host._gearPtCache.get(t.poly)||null,i||(i=Le(t.poly),this.host._gearPtCache.set(t.poly,i))):null!=t.x&&null!=t.y&&(i=[t.x+(t.w||0)/2,t.y+(t.h||0)/2]),!i)return d;const o=(i[0]-s.x)/s.w*100,a=(i[1]-s.y)/s.h*100;return p``}_alignCandidates(){const t=[],e=this.host._spaceModel();if(this.host._markup){if(!e)return t;if(this.host._drag?.id.startsWith("rl_")){const s=this.host._drag.id.slice(3);for(const i of e.rooms){if(!i.name||i.id===s)continue;const e=this._labelPos(i,this.host._space);t.push([e.x,e.y])}return t}for(const s of e.rooms){const e=B(s);if(e)for(const s of e)t.push(s)}if("draw"===this.host._tool)for(const e of this.host._path)t.push(e);if("split"===this.host._tool&&this.host._splitSel?.pts)for(const e of this.host._splitSel.pts)t.push(e);return t}if("devices"===this.host._mode){const e=this.host._deviceDrag?.id??this.host._drag?.id;for(const s of this.host._devices){if(s.space!==this.host._space||s.id===e||"ha_disabled"===s.bindingStatus?.kind)continue;const i=this.host._pos(s);t.push([i.x,i.y])}return t}if("decor"===this.host._mode){const e=this.host._decorMove?.id;return t.push(...this._decorSnapGeometry(e).points),this.host._decorDraft&&t.push(this.host._decorDraft.a),t}return t}_renderAlignGuides(){const t=this.host._alignPoint;if(!t)return _``;const e=this.host._drag?.id.startsWith("rl_")?.5*this.host._gridPitch:.05*this.host._gridPitch,s=xi(t,this._alignCandidates(),e);if(!s.length)return _``;const i=this.host._gridPitch,o=1.5*i;return _` + `}_alignCandidates(){const t=[],e=this.host._spaceModel();if(this.host._markup){if(!e)return t;if(this.host._drag?.id.startsWith("rl_")){const s=this.host._drag.id.slice(3);for(const i of e.rooms){if(!i.name||i.id===s)continue;const e=this._labelPos(i,this.host._space);t.push([e.x,e.y])}return t}for(const s of e.rooms){const e=B(s);if(e)for(const s of e)t.push(s)}if("draw"===this.host._tool)for(const e of this.host._path)t.push(e);if("split"===this.host._tool&&this.host._splitSel?.pts)for(const e of this.host._splitSel.pts)t.push(e);return t}if("devices"===this.host._mode){const e=this.host._deviceDrag?.id??this.host._drag?.id;for(const s of this.host._devices){if(s.space!==this.host._space||s.id===e||"ha_disabled"===s.bindingStatus?.kind)continue;const i=this.host._pos(s);t.push([i.x,i.y])}return t}if("decor"===this.host._mode){const e=this.host._decorMove?.id;return t.push(...this._decorSnapGeometry(e).points),this.host._decorDraft&&t.push(this.host._decorDraft.a),t}return t}_renderAlignGuides(){const t=this.host._alignPoint;if(!t)return _``;const e=this.host._drag?.id.startsWith("rl_")?.5*this.host._gridPitch:.05*this.host._gridPitch,s=Si(t,this._alignCandidates(),e);if(!s.length)return _``;const i=this.host._gridPitch,o=1.5*i;return _` ${s.map(e=>{const[s,a,n,r]="x"===e.axis?[e.at,e.from[1],e.at,t[1]+Math.sign(t[1]-e.from[1])*o]:[e.from[0],e.at,t[0]+Math.sign(t[0]-e.from[0])*o,e.at];return _` `})} @@ -1577,7 +1585,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 x2=${t.to[0]} y2=${t.to[1]}> ${o(t.from,"from")}${o(t.to,"to")} `})} - `}_renderOpeningPlacementPreview(){const t=this.host._openingPreview;if(!t)return _``;const e={type:t.type,length:t.renderedLength,angle:t.angle,amount:Si(t.type,null),flipH:t.flipH,flipV:t.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:t.face},s="passage"===t.type?Mi(t,y(this.host._gridPitch,this.host._cellCm)):null;return _``}_renderOpeningPlacementPreview(){const t=this.host._openingPreview;if(!t)return _``;const e={type:t.type,length:t.renderedLength,angle:t.angle,amount:Mi(t.type,null),flipH:t.flipH,flipV:t.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:t.face},s="passage"===t.type?Ci(t,y(this.host._gridPitch,this.host._cellCm)):null;return _` `}_renderOpeningDialog(){const t=this.host._openingDialog,e=this.host._spaceModel()?.partitions||[],s=t.id?this.host._curSpaceCfg?.openings?.find(e=>e.id===t.id):null,i={id:t.id||"preview",type:t.type,x:t.x/sd,y:t.y/this.host._spaceH,angle:t.angle,length:s&&!t.lengthTouched?s.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/sd,...t.host?{host:t.host}:{}},o=ys(s,i),a=t.host?o?bt(i,e,sd,this.host._cellCm,this.host._gridPitch):ct(i,e,sd,this.host._cellCm,this.host._gridPitch):null,n="does-not-fit-jamb"===a?.reason,r=t.host?e.find(e=>e.id===t.host.id):null,l=r?Ot(r.cm/2,this.host._imperial):"",h=!!t.host&&!a?.resolved&&!n,c="gate"===t.type?"mdi:gate":"window"===t.type?"mdi:window-closed-variant":"passage"===t.type?"mdi:arch":"mdi:door",u=(e,s)=>{const i="contact"===e?t.contact:t.lock,o="contact"===e?!!t.contactOpen:!!t.lockOpen,a="contact"===e?t.contactFilter||"":t.lockFilter||"",n=s.find(t=>t.value===i),r=n?.label||this.host.hass.states[i]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[i]?.name||i,l=ho(s,a);return p` + r=${y(.18*this.host._gridPitch,this.host._cellCm)}>`}_renderOpeningDialog(){const t=this.host._openingDialog,e=this.host._spaceModel()?.partitions||[],s=t.id?this.host._curSpaceCfg?.openings?.find(e=>e.id===t.id):null,i={id:t.id||"preview",type:t.type,x:t.x/id,y:t.y/this.host._spaceH,angle:t.angle,length:s&&!t.lengthTouched?s.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/id,...t.host?{host:t.host}:{}},o=$s(s,i),a=t.host?o?bt(i,e,id,this.host._cellCm,this.host._gridPitch):ct(i,e,id,this.host._cellCm,this.host._gridPitch):null,n="does-not-fit-jamb"===a?.reason,r=t.host?e.find(e=>e.id===t.host.id):null,l=r?Ot(r.cm/2,this.host._imperial):"",h=!!t.host&&!a?.resolved&&!n,c="gate"===t.type?"mdi:gate":"window"===t.type?"mdi:window-closed-variant":"passage"===t.type?"mdi:arch":"mdi:door",u=(e,s)=>{const i="contact"===e?t.contact:t.lock,o="contact"===e?!!t.contactOpen:!!t.lockOpen,a="contact"===e?t.contactFilter||"":t.lockFilter||"",n=s.find(t=>t.value===i),r=n?.label||this.host.hass.states[i]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[i]?.name||i,l=co(s,a);return p`
    `:d} @@ -1680,7 +1688,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    - `}_gridLevels(){const t=this.host._stageEl,e=this.host._viewOr(this.host._baseVb()),s=t&&t.clientWidth&&e.w?t.clientWidth/e.w:1;return Di(this.host._gridPitch,s)}_renderMarkupDefs(t){const e=this._gridLevels();if(!e)return _``;const s=this.host._gridPitch*e.fine,i=this.host._gridPitch*e.coarse,o=this.host._gridPitch*e.fine*.14;return _` + `}_gridLevels(){const t=this.host._stageEl,e=this.host._viewOr(this.host._baseVb()),s=t&&t.clientWidth&&e.w?t.clientWidth/e.w:1;return Ii(this.host._gridPitch,s)}_renderMarkupDefs(t){const e=this._gridLevels();if(!e)return _``;const s=this.host._gridPitch*e.fine,i=this.host._gridPitch*e.coarse,o=this.host._gridPitch*e.fine*.14;return _` @@ -1694,7 +1702,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 - `}_renderPhysicalEditorLayer(){const t=this.host._spaceModel();if(!t)return _``;const e=this.host._gridPitch,s=this.host._viewOr(this.host._baseVb()),i=this.host._stageEl,o=i?.clientWidth?s.w/i.clientWidth:e/8,a=Math.max(.22*e,8*o),n=Math.max(a,12*o),r=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`,l=(t,e)=>this.host._physicalSel?.kind===t&&this.host._physicalSel.id===e||"column"===t&&this.host._duplicateColumnId===e,h=(t.partitions||[]).map(t=>{const e=Te(t.a,t.b,t.cm,this.host._cellCm,this.host._gridPitch);return e?_``}_renderPhysicalEditorLayer(){const t=this.host._spaceModel();if(!t)return _``;const e=this.host._gridPitch,s=this.host._viewOr(this.host._baseVb()),i=this.host._stageEl,o=i?.clientWidth?s.w/i.clientWidth:e/8,a=Math.max(.22*e,8*o),n=Math.max(a,12*o),r=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`,l=(t,e)=>this.host._physicalSel?.kind===t&&this.host._physicalSel.id===e||"column"===t&&this.host._duplicateColumnId===e,h=(t.partitions||[]).map(t=>{const e=Re(t.a,t.b,t.cm,this.host._cellCm,this.host._gridPitch);return e?_`this._physicalDown(e,"partition",t.id)} @@ -1705,7 +1713,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 stroke-width=${24} vector-effect="non-scaling-stroke" @pointerdown=${e=>this._physicalDown(e,"partition",t.id)} @pointermove=${t=>this._physicalMove(t)} - @pointerup=${t=>this._physicalUp(t)}>`}),c=(t.wall_columns||[]).map(t=>{const e=this.host._physicalRotate?.id===t.id?{...t,angle:this.host._physicalRotate.angle}:t,s=Ie(e,this.host._cellCm,this.host._gridPitch);return _`this._physicalUp(t)}>`}),c=(t.wall_columns||[]).map(t=>{const e=this.host._physicalRotate?.id===t.id?{...t,angle:this.host._physicalRotate.angle}:t,s=Te(e,this.host._cellCm,this.host._gridPitch);return _`this._physicalDown(e,"column",t.id)} @@ -1713,17 +1721,17 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointerup=${t=>this._physicalUp(t)}>`}),p=this.host._physicalDrag,u=(()=>{if(!p?.moved)return d;if("partition"===p.kind&&0===Number(p.base.cm)){const t=p.base;return _``}const t="partition"===p.kind?Te(p.base.a,p.base.b,p.base.cm,this.host._cellCm,this.host._gridPitch):Ie(p.base,this.host._cellCm,this.host._gridPitch);return t?_``:d})(),m=(()=>{const s=this.host._physicalSel;if(!s)return d;if("partition"===s.kind){const e=t.partitions.find(t=>t.id===s.id);if(!e)return d;const i=Te(e.a,e.b,e.cm,this.host._cellCm,this.host._gridPitch),o=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2;return _` + transform="translate(${p.delta[0]} ${p.delta[1]})">`}const t="partition"===p.kind?Re(p.base.a,p.base.b,p.base.cm,this.host._cellCm,this.host._gridPitch):Te(p.base,this.host._cellCm,this.host._gridPitch);return t?_``:d})(),m=(()=>{const s=this.host._physicalSel;if(!s)return d;if("partition"===s.kind){const e=t.partitions.find(t=>t.id===s.id);if(!e)return d;const i=Re(e.a,e.b,e.cm,this.host._cellCm,this.host._gridPitch),o=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2;return _` ${i?_``:_``} - `}const i=t.wall_columns.find(t=>t.id===s.id);if(!i)return d;const l=this.host._physicalRotate?.id===i.id?{...i,angle:this.host._physicalRotate.angle}:i,h=Ie(l,this.host._cellCm,this.host._gridPitch);if("square"!==l.shape)return _` + `}const i=t.wall_columns.find(t=>t.id===s.id);if(!i)return d;const l=this.host._physicalRotate?.id===i.id?{...i,angle:this.host._physicalRotate.angle}:i,h=Te(l,this.host._cellCm,this.host._gridPitch);if("square"!==l.shape)return _` - `;const c=$(l.cm,this.host._cellCm,this.host._gridPitch),p=ye(l.angle)*Math.PI/180,u=Math.sin(p),m=-Math.cos(p),g=[l.center[0]+u*c/2,l.center[1]+m*c/2],f=[g[0]+u*Math.max(e,24*o),g[1]+m*Math.max(e,24*o)];return _` + `;const c=$(l.cm,this.host._cellCm,this.host._gridPitch),p=$e(l.angle)*Math.PI/180,u=Math.sin(p),m=-Math.cos(p),g=[l.center[0]+u*c/2,l.center[1]+m*c/2],f=[g[0]+u*Math.max(e,24*o),g[1]+m*Math.max(e,24*o)];return _` @@ -1749,7 +1757,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 data-segment-count=${t.segments.length} data-endpoint-count=${t.endpoints.length} aria-hidden="true" pointer-events="none"> - ${Io([t,i,[...s].sort().join("|")],()=>_` + ${To([t,i,[...s].sort().join("|")],()=>_` ${t.segments.map(t=>_` - `}_syncPlanSnapActiveMarker(t){const e=this.host.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(e){if(e.setAttribute("class",`plan-snap-node${t?" active":""}${"line"===t?.kind?" dynamic":""}`),e.setAttribute("data-active",t?"true":"false"),e.setAttribute("visibility",t?"visible":"hidden"),!t)return e.removeAttribute("data-kind"),void e.removeAttribute("data-key");e.setAttribute("data-kind",t.kind),e.setAttribute("data-key",t.key),e.setAttribute("cx",String(t.point[0])),e.setAttribute("cy",String(t.point[1])),e.setAttribute("r",String($(10,this.host._cellCm,this.host._gridPitch)))}}_syncPlanSnapConflictMarkers(t){const e=new Set(t.map(t=>t.key));for(const t of this.host.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])t.setAttribute("class","plan-snap-node"+(e.has(t.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(t){let e=0;const s=this.host._spaceModel();return s?(e="partition"===t.sourceKind?Number(s.partitions.find(e=>e.id===t.sourceId)?.cm)||0:Ii(s.rooms,this.host._spaceWalls,this.host._openCuts(),[t.a[0],t.a[1],t.b[0],t.b[1]],this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd),e>0?{a:[...t.a],b:[...t.b],halfDepth:$(e,this.host._cellCm,this.host._gridPitch)/2}:null):null}_drawPreviewJoinPatchD(t,e){if(t.length<2)return"";const s=[];for(let i=0;i+10&&s.push({a:t[i],b:t[i+1],halfDepth:e[i]});if(!s.length)return"";const i=2e-4*this.host._gridPitch,o=this._planSnapGeometrySnapshot().value.segments.filter(e=>t.some(t=>Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=i)).map(t=>this._planSnapPhysicalSegment(t)).filter(t=>!!t);return Ti([...s,...o],i).map(t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(t){const e=this.host._openCuts(),s=this.host._thickWallCuts(),i=e.concat(s),o=i.length?Bt(this.host._segments,i,.02*this.host._gridPitch):this.host._segments,a=this.host._path,n=this.host._gridPitch,r=this.host._viewOr(this.host._baseVb()),l="draw"===this.host._tool?this.host._drawWallCm:null,h=(()=>"draw"===this.host._tool&&a.length&&null!=l?this.host._contourClosed?a:this.host._cursorPt?[...a,this.host._cursorPt]:a.length>=2?a:null:null)(),c=h?Rh(h.length-1,this.host._contourClosed?[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0]:this.host._wallChainSegmentCms,l,ut).map(t=>$(t,this.host._cellCm,this.host._gridPitch)/2):[],p=h?zi(h,$(l,this.host._cellCm,this.host._gridPitch)/2,this.host._contourClosed,c):"",u=h?this._drawPreviewJoinPatchD(h,c):"",m=this.host._wallFaceBatch?.candidates[this.host._wallFaceBatch.index]?.repair||this.host._wallRepairDiagnostic;return _` + `}_syncPlanSnapActiveMarker(t){const e=this.host.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(e){if(e.setAttribute("class",`plan-snap-node${t?" active":""}${"line"===t?.kind?" dynamic":""}`),e.setAttribute("data-active",t?"true":"false"),e.setAttribute("visibility",t?"visible":"hidden"),!t)return e.removeAttribute("data-kind"),void e.removeAttribute("data-key");e.setAttribute("data-kind",t.kind),e.setAttribute("data-key",t.key),e.setAttribute("cx",String(t.point[0])),e.setAttribute("cy",String(t.point[1])),e.setAttribute("r",String($(10,this.host._cellCm,this.host._gridPitch)))}}_syncPlanSnapConflictMarkers(t){const e=new Set(t.map(t=>t.key));for(const t of this.host.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])t.setAttribute("class","plan-snap-node"+(e.has(t.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(t){let e=0;const s=this.host._spaceModel();return s?(e="partition"===t.sourceKind?Number(s.partitions.find(e=>e.id===t.sourceId)?.cm)||0:Ti(s.rooms,this.host._spaceWalls,this.host._openCuts(),[t.a[0],t.a[1],t.b[0],t.b[1]],this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id),e>0?{a:[...t.a],b:[...t.b],halfDepth:$(e,this.host._cellCm,this.host._gridPitch)/2}:null):null}_drawPreviewJoinPatchD(t,e){if(t.length<2)return"";const s=[];for(let i=0;i+10&&s.push({a:t[i],b:t[i+1],halfDepth:e[i]});if(!s.length)return"";const i=2e-4*this.host._gridPitch,o=this._planSnapGeometrySnapshot().value.segments.filter(e=>t.some(t=>Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=i)).map(t=>this._planSnapPhysicalSegment(t)).filter(t=>!!t);return Ri([...s,...o],i).map(t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(t){const e=this.host._openCuts(),s=this.host._thickWallCuts(),i=e.concat(s),o=i.length?Bt(this.host._segments,i,.02*this.host._gridPitch):this.host._segments,a=this.host._path,n=this.host._gridPitch,r=this.host._viewOr(this.host._baseVb()),l="draw"===this.host._tool?this.host._drawWallCm:null,h=(()=>"draw"===this.host._tool&&a.length&&null!=l?this.host._contourClosed?a:this.host._cursorPt?[...a,this.host._cursorPt]:a.length>=2?a:null:null)(),c=h?Ah(h.length-1,this.host._contourClosed?[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0]:this.host._wallChainSegmentCms,l,ut).map(t=>$(t,this.host._cellCm,this.host._gridPitch)/2):[],p=h?zi(h,$(l,this.host._cellCm,this.host._gridPitch)/2,this.host._contourClosed,c):"",u=h?this._drawPreviewJoinPatchD(h,c):"",m=this.host._wallFaceBatch?.candidates[this.host._wallFaceBatch.index]?.repair||this.host._wallRepairDiagnostic;return _` ${this._gridLevels()?_``:d} ${o.map(t=>_``)} ${this._renderPhysicalEditorLayer()} - ${"column"===this.host._tool&&this.host._cursorPt&&this.host._drawWallCm?_`{const t={shape:"square",center:this.host._cursorPt,cm:this.host._drawWallCm};return`M ${Ie(t,this.host._cellCm,this.host._gridPitch).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`})()}>`:d} + ${"column"===this.host._tool&&this.host._cursorPt&&this.host._drawWallCm?_`{const t={shape:"square",center:this.host._cursorPt,cm:this.host._drawWallCm};return`M ${Te(t,this.host._cellCm,this.host._gridPitch).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`})()}>`:d} ${p?_` `:d} - ${h&&0===l?_`t.join(",")).join(" ")}>`:d} ${u?_` `:d} @@ -1800,7 +1808,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623

    ${this.host._t("confirm.delete_partition_openings_body",{count:t.openings.length})}

      - ${t.openings.map(t=>p`
    • ${this.host._t("confirm.delete_partition_openings_item",{type:this.host._t(`opening.${t.type}`),length:Ot(t.length*sd/this.host._gridPitch*this.host._cellCm,e)})}
    • `)} + ${t.openings.map(t=>p`
    • ${this.host._t("confirm.delete_partition_openings_item",{type:this.host._t(`opening.${t.type}`),length:Ot(t.length*id/this.host._gridPitch*this.host._cellCm,e)})}
    • `)}
    @@ -1843,8 +1851,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 `:d}
    this.host._physicalDialog={...t,cm:e.target.value}} /> ${this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")}
    ${e&&"square"===t.shape?p` @@ -1967,7 +1975,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    -
    `}_discoveryFilterState(t){const e=this.host._settings,s=void 0!==t.draftGroupLights?t.draftGroupLights:!1!==e.group_lights,i=e.exclude_integrations,o=void 0!==t.draftExcluded?null===t.draftExcluded?[...Ri]:t.draftExcluded:i?[...i]:[...Ri],a=void 0!==t.draftExcluded?null===t.draftExcluded:!i,n=void 0!==t.draftGroupLights||void 0!==t.draftExcluded;return{groupLights:s,excluded:o.sort(),usesProductList:a,dirty:n}}_registryIntegrations(){const t=new Set,e=this.host._fullRegistryHass;for(const s of Object.values(e?.entities||{}))s?.platform&&t.add(String(s.platform));for(const s of Object.values(e?.devices||{})){const e=s?.identifiers?.[0],i=Array.isArray(e)?e[0]:null;i&&t.add(String(i))}return[...t].sort()}_discoveryFilterPreview(t){const e=this._discoveryFilterState(t),s=[e.groupLights?1:0,e.usesProductList?"p":e.excluded.join(","),this.host._cfgEpoch,this.host._regSignature].join("|");if(this._discoveryPreviewMemo?.key===s)return this._discoveryPreviewMemo.value;const i={hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),markers:this.host._markers,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||"",loc:t=>this.host._t(t),iconRules:this.host._iconRules},o=(t,e)=>new Set(co({...i,settings:t,excluded:e})),a=(t,e)=>new Set(po({...i,settings:t,excluded:e}).map(t=>t.bindingRef||t.id)),n=Ai(this.host._settings),r={...this.host._settings,group_lights:e.groupLights},l=new Set(e.excluded),h=o(this.host._settings,n),c=o(r,l),d=a(this.host._settings,n),p=a(r,l);let u=0,_=0,m=0;const g=t=>t.includes("light.");for(const t of h)c.has(t)||(u++,g(t)&&m++);for(const t of c)h.has(t)||(_++,g(t)&&m++);for(const t of p)d.has(t)||(u++,g(t)&&m++);for(const t of d)p.has(t)||(_++,g(t)&&m++);const f={appear:u,hide:_,lights:m};return this._discoveryPreviewMemo={key:s,value:f},f}async _saveDiscoveryFilters(t){const e=this.host._serverCfg;if(!e)return;const s=this._discoveryFilterState(t),i={...e.settings};s.groupLights?delete i.group_lights:i.group_lights=!1,s.usesProductList?delete i.exclude_integrations:i.exclude_integrations=s.excluded,this.host._serverCfg={...e,settings:i},this.host._deviceInboxMemo=null,this._discoveryPreviewMemo=null,this.host._regSignature="",this.host._deviceInbox&&(this.host._deviceInbox={...t,draftGroupLights:void 0,draftExcluded:void 0}),this._saveConfig(),this.host._maybeRebuildDevices(),this.host.requestUpdate()}_renderDiscoveryFilters(t){const e=this._discoveryFilterState(t),s=e=>this.host._deviceInbox={...t,...e},i=t.filtersOpen&&e.dirty?this._discoveryFilterPreview(t):null,o=this._registryIntegrations().filter(t=>!e.excluded.includes(t));return p`
    `}_discoveryFilterState(t){const e=this.host._settings,s=void 0!==t.draftGroupLights?t.draftGroupLights:!1!==e.group_lights,i=e.exclude_integrations,o=void 0!==t.draftExcluded?null===t.draftExcluded?[...Ai]:t.draftExcluded:i?[...i]:[...Ai],a=void 0!==t.draftExcluded?null===t.draftExcluded:!i,n=void 0!==t.draftGroupLights||void 0!==t.draftExcluded;return{groupLights:s,excluded:o.sort(),usesProductList:a,dirty:n}}_registryIntegrations(){const t=new Set,e=this.host._fullRegistryHass;for(const s of Object.values(e?.entities||{}))s?.platform&&t.add(String(s.platform));for(const s of Object.values(e?.devices||{})){const e=s?.identifiers?.[0],i=Array.isArray(e)?e[0]:null;i&&t.add(String(i))}return[...t].sort()}_discoveryFilterPreview(t){const e=this._discoveryFilterState(t),s=[e.groupLights?1:0,e.usesProductList?"p":e.excluded.join(","),this.host._cfgEpoch,this.host._regSignature].join("|");if(this._discoveryPreviewMemo?.key===s)return this._discoveryPreviewMemo.value;const i={hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),markers:this.host._markers,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||"",loc:t=>this.host._t(t),iconRules:this.host._iconRules},o=(t,e)=>new Set(po({...i,settings:t,excluded:e})),a=(t,e)=>new Set(uo({...i,settings:t,excluded:e}).map(t=>t.bindingRef||t.id)),n=Fi(this.host._settings),r={...this.host._settings,group_lights:e.groupLights},l=new Set(e.excluded),h=o(this.host._settings,n),c=o(r,l),d=a(this.host._settings,n),p=a(r,l);let u=0,_=0,m=0;const g=t=>t.includes("light.");for(const t of h)c.has(t)||(u++,g(t)&&m++);for(const t of c)h.has(t)||(_++,g(t)&&m++);for(const t of p)d.has(t)||(u++,g(t)&&m++);for(const t of d)p.has(t)||(_++,g(t)&&m++);const f={appear:u,hide:_,lights:m};return this._discoveryPreviewMemo={key:s,value:f},f}async _saveDiscoveryFilters(t){const e=this.host._serverCfg;if(!e)return;const s=this._discoveryFilterState(t),i={...e.settings};s.groupLights?delete i.group_lights:i.group_lights=!1,s.usesProductList?delete i.exclude_integrations:i.exclude_integrations=s.excluded,this.host._serverCfg={...e,settings:i},this.host._deviceInboxMemo=null,this._discoveryPreviewMemo=null,this.host._regSignature="",this.host._deviceInbox&&(this.host._deviceInbox={...t,draftGroupLights:void 0,draftExcluded:void 0}),this._saveConfig(),this.host._maybeRebuildDevices(),this.host.requestUpdate()}_renderDiscoveryFilters(t){const e=this._discoveryFilterState(t),s=e=>this.host._deviceInbox={...t,...e},i=t.filtersOpen&&e.dirty?this._discoveryFilterPreview(t):null,o=this._registryIntegrations().filter(t=>!e.excluded.includes(t));return p`
    s({filtersOpen:t.target.open})}> ${this.host._t("device_inbox.filters_title")}
    - `}_markerValueBadgeFields(t){return Fi({touched:t.valueBadgeTouched,originalHas:t.originalHasValueBadge,original:t.originalValueBadge,enabled:t.valueBadgeEnabled,source:t.valueBadgeSource,position:t.valueBadgePosition})}_markerValueSourceFields(t){return Ni({touched:t.valueSourceTouched,originalHas:t.originalHasValueSource,original:t.originalValueSource,source:t.valueSource})}_markerDraft(t){if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return null;const e=Fs(t.room),s=Cs(t.binding,t.devId,()=>"__hp_device_preview__"),i=this.host._markers.find(e=>e.id===s||e.id===t.devId),o=Ts(t.binding,t.controls,this.host._bindingEntities(t.binding)),a=this._effectiveStoredTapAction(t),n={id:s,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle||null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===a&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:o.length?o:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:t.hideFromPlan,vacuum:i?.vacuum||null},r=!!i&&("string"==typeof i.area&&i.area.length>0||null===i.area&&!!i.space&&!!i.room_id);return"virtual"===t.binding||t.roomTouched?(n.space=e?.space||("virtual"===t.binding?this.host._space:null),n.area=e?.area||null,n.room_id=e?.roomId||null):r&&(n.space=i.space,n.area=i.area,n.room_id=i.room_id),n}_markerPreviewDevice(t){const e=this._markerDraft(t);if(!e)return null;const s=`${this.host._haRegistry.revision}\n${Ft(this.host._markers)}\n${JSON.stringify(e)}`;if(this.host._markerPreviewMemo?.key===s)return this.host._markerPreviewMemo.device;const i=Ei({hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),marker:e,siblingMarkers:this.host._markers,settings:this.host._settings,excluded:this.host._excluded,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||this.host._space,loc:t=>this.host._t(t),iconRules:this.host._iconRules});return this.host._markerPreviewMemo={key:s,device:i},i}_markerPreviewDevices(t){const e=this.host._markerPreviewDevicesMemo;if(e?.base===this.host._devices&&e.preview===t)return e.devices;const s=[...this.host._devices.filter(e=>e.id!==t.id),t];return this.host._markerPreviewDevicesMemo={base:this.host._devices,preview:t,devices:s},s}_toggleIntent(t,e=this.host._devices){return this.host._toggleIntent(t,e)}_toggleIntentForDialog(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s=this._markerPreviewDevices(e);return this._toggleIntent(e,s)}_toggleStateText(t,e){return this.host._toggleStateText(t,e)}_toggleConfirmationStateText(t){return this.host._toggleConfirmationStateText(t)}_toggleConfirmationLines(t){return this.host._toggleConfirmationLines(t)}_toggleHintLines(t){if(!t)return[];const e=t=>this.host._t(`marker.toggle_effect_${t.replace("-","_")}`),s=t=>this.host._t(`marker.toggle_skip_${t.replace("-","_")}`);return Hi(t,{single:t=>{if("via"in t&&"virtual-light"===t.via)return this.host._t("marker.virtual_light_target",{name:t.name});const e=t.entityId||("ref"in t?t.ref:""),s=t.name||e;return this.host._t("marker.toggle_hint_single",{name:s,id:e})},group:t=>this.host._t("marker.toggle_hint_group",{count:t.length,names:t.map(t=>`${t.name} (${t.entityId})`).join(", ")}),currentNext:(t,s)=>"virtual-light"===t.via?this.host._t("marker.virtual_light_current",{state:this.host._t("on"===t.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:e(s)}):this.host._t("marker.toggle_hint_current",{state:this._toggleStateText(t.entityId,t.state),effect:e(s)}),groupCurrentNext:(t,s)=>this.host._t("marker.toggle_hint_group_current",{on:t.filter(t=>"on"===t.state).length,count:t.length,effect:e(s)}),skipped:t=>this.host._t("marker.toggle_hint_skipped",{count:t.length,targets:t.map(t=>{const e=t.entityId||t.ref;return`${t.name||e} (${e}: ${s(t.reason)})`}).join(", ")}),none:t=>this.host._t(`marker.toggle_none_${t.replaceAll("-","_")}`)})}_effectiveStoredTapAction(t,e){return t.tapActionTouched?t.tapAction:zs(t.originalHasTapAction?t.originalTapAction:null,e)}_effectiveMarkerTapAction(t,e=this._markerPreviewDevice(t)){return this._effectiveStoredTapAction(t,e?.primary?.split(".")[0])}_announceToggleDraft(t){const e=this._markerPreviewDevice(t),s=t.tapActionTouched?t:{...t,tapAction:this._effectiveMarkerTapAction(t,e)},i="toggle"===s.tapAction?this._toggleHintLines(this._toggleIntentForDialog(s)).join(" "):"";return{...s,tapHintAnnouncement:i}}_valueBadgeForBinding(t,e){const s={...t,binding:e,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},i=this._markerPreviewDevice(s);if(!i)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const o=[...this.host._devices.filter(t=>t.id!==i.id),i],a=Ds(this.host._planHass,i,o),n=Is(this.host._planHass,i,a);return{valueBadgeEnabled:t.valueBadgeEnabled&&!!n,valueBadgeSource:n,valueBadgeTouched:!0}}_markerSpatialSource(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s={...e,hidden:!1};return Oi(Li(this.host._planHass,[...this.host._devices.filter(t=>t.id!==s.id),s],null,this.host._virtualLights).filter(t=>t.device.id===s.id))}_markerAutoHasSpatialSource(t){const e={...t,lightRole:"auto",lightRoleTouched:!0},s=this._markerPreviewDevice(e);return!!s&&Bi(this.host._planHass,{...s})}_setMarkerLightRole(t){const e=this.host._markerDialog;e&&(this.host._markerDialog={...e,lightRole:t,lightRoleTouched:!0})}_controlRefInfo(t){if(!t.startsWith("marker:"))return{label:this.host.hass.states[t]?.attributes?.friendly_name||t,sub:t,icon:t.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this.host._planEntityAvailable(t)};const e=t.slice(7),s=this.host._markers.find(t=>t.id===e),i=this.host._devices.find(t=>t.id===e);if(!s||s.removed||!0!==s.is_light)return{label:this.host._t("marker.control_missing_label"),sub:`${this.host._t("marker.control_broken")} (${t})`,icon:"mdi:alert-outline",warning:!0};const o=this.host._serverCfg?.spaces.find(t=>t.id===(i?.space||s.space)),a=!!i&&Wi(i).length>0;return{label:s.name||i?.name||e,sub:[o?.title||i?.space||s.space,s.room_id||i?.area,a?"":this.host._t("marker.control_passive")].filter(Boolean).join(" · "),icon:s.icon||i?.icon||"mdi:lightbulb-outline",warning:!0===s.hidden||!0===i?.hidden}}_valueBadgeCandidateLabel(t){const e=t.source;if("derived_lqi"===e.kind)return this.host._t("marker.value_badge_lqi");if("derived_marker_state"===e.kind)return this.host._t("marker.value_badge_marker_state",{name:t.label});if("entity_state"===e.kind)return this.host._t("marker.value_badge_state",{name:t.label});const s=this.host.hass.states[e.entity_id]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[e.entity_id]?.name||e.entity_id;return this.host._t(`marker.value_badge_attr_${e.attribute}`,{name:s})}_controlCandidates(t){const e=this._markerDraft(t)?.id||t.devId||"",s=[],i=new Set;for(const t of this.host._markers){if(t.id===e||t.removed||t.hidden||!0!==t.is_light)continue;if("virtual"!==t.binding&&"active"!==this.host._bindingStatus(t.binding).kind)continue;const o=this.host._devices.find(e=>e.id===t.id);if(!o||o.hidden)continue;const a=this._controlRefInfo(`marker:${t.id}`);for(const t of Wi(o))i.add(t);s.push({value:`marker:${t.id}`,label:a.label,sub:a.sub,icon:a.icon,search:`${a.label} ${a.sub} ${t.id} ${Wi(o).join(" ")}`.toLowerCase()})}const o=Object.keys(this.host.hass.states||{}).filter(e=>ji(e)&&!i.has(e)&&Gi(t.binding,[e],this.host._bindingEntities(t.binding)).length>0&&this.host._planEntityAvailable(e)).map(t=>{const e=this._controlRefInfo(t);return{value:t,label:e.label,sub:t,icon:e.icon,search:`${e.label} ${t}`.toLowerCase()}}),a=t.controlsFilter.trim().toLowerCase();return[...s,...o].filter(e=>!t.controls.includes(e.value)&&(!a||e.search.includes(a))).slice(0,12).map(({search:t,...e})=>e)}_addControlRef(t,e){if(e.startsWith("marker:")){const s=this._markerDraft(t)?.id||t.devId||"";if(!s)return void this.host._showToast(this.host._t("toast.marker_binding_required"));const i=e.slice(7),o=this._markerDraft(t),a=o?[...this.host._markers.filter(t=>t.id!==s),o]:this.host._markers;if(qi(a,s,i))return void this.host._showToast(this.host._t("toast.marker_control_cycle"))}this.host._markerDialog=this._announceToggleDraft({...t,controls:[...t.controls,e],controlsFilter:""})}_setMarkerGlowMode(t){const e=this.host._markerDialog;if(!e)return;if("auto"===t)return void(this.host._markerDialog={...e,glowMode:t,glowTouched:!0});const s=this._markerSpatialSource(e),i=Ui(s?this.host._planHass.states[s.eid]:void 0,null,this.host._fillColors.glow_light.c),o=!e.glowColorDrafted,a="fixed"===t&&!e.glowBrightnessDrafted;this.host._markerDialog={...e,glowMode:t,glowColor:o?i.c:e.glowColor,glowBrightness:a?Math.max(1,Math.round(100*i.bri)):e.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:e.glowBrightnessDrafted||"fixed"===t,glowTouched:!0}}_renderRadarSection(t,e,s="main"){return ph({dialog:t,device:e,registryHass:this.host._fullRegistryHass,planHass:this.host._planHass,hass:this.host.hass,spaceModelById:t=>this.host._spaceModelById(t),currentSpace:()=>this.host._spaceModel(),position:t=>this.host._pos(t),updateDialog:t=>{this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,...t})},dialogDeviceId:()=>this.host._markerDialog?.devId,t:(t,e)=>this.host._t(t,e),help:t=>this._help(t),boolInput:(t,e)=>this._boolInput(t,e),toast:t=>this.host._showToast(t),setup:this._radarSetup,configRev:this.host._cfgRev},s)}_renderMarkerDialog(){const t=this.host._markerDialog,e="virtual"===t.bindingMode,s=this._bindingCandidates();this.host._bindingEntities(t.binding);const i=e?null:this.host._bindingStatus(t.binding),o=!e&&this.host._bindingHasHaPage(t.binding),a=this._markerPreviewDevice(t),n=this._effectiveMarkerTapAction(t,a),r=a?Ws(this.host._serverCfg?.spaces.find(t=>t.id===a.space)):null,l=a?this._markerPreviewDevices(a):this.host._devices,h="toggle"===n&&a?this._toggleIntent(a,l):null,c=this._toggleHintLines(h),u=a?Ki(this.host._planHass,a,{liveStates:!1!==this.host._config?.live_states,showTemperature:!1!==this.host._config?.show_temperature,showSignal:r?.showLqi??!1!==this.host._config?.show_signal,designPreview:!0,activityRuntime:this.host._activityRt.get(a.id),lightDevices:l,registryHass:this.host._fullRegistryHass,reducedMotion:this.host._reducedMotion}):null,_=a?Ds(this.host._planHass,a,l):[],m=a?Is(this.host._planHass,a,_):null,g=t.valueBadgeTouched?t.valueBadgeEnabled:!!u?.valueBadge,f=t.valueBadgeTouched?t.valueBadgeSource:u?.valueBadge?.source||t.valueBadgeSource,b=t.valueBadgeTouched?t.valueBadgePosition:u?.valueBadge?.position||t.valueBadgePosition,v=Vi(f),y=!!f&&!_.some(t=>t.key===v),$=_.find(t=>t.key===v),w=Vi(t.valueSource),k=!(!t.valueSource||w&&_.some(t=>t.key===w)),x=_.find(t=>t.key===w),S=u?.valueSource?.sourceKey||"",M=this._markerAutoHasSpatialSource(t),C=!!a&&Ji(this.host._planHass,{...a}),P=Yi(t.lightRole,M,C,t.glowMode),D=!P.sourceExists,I=!P.fromSourceEnabled,T=P.passive,z=P.effectiveMode,R="never"===t.lightRole?this.host._t("marker.glow_disabled_never"):"auto"!==t.lightRole||M?T?this.host._t("marker.glow_passive_hint"):this.host._t("marker.glow_disabled_no_entity"):this.host._t("marker.glow_disabled_auto"),A=a?Wi(a):[],F=a&&Xi(a)||"",N=!!t.lightEntity&&!A.includes(t.lightEntity),E=a?Zi(a):[],H=!!t.toggleEntity&&!E.includes(t.toggleEntity),O="toggle"===n?this._toggleIntentForDialog({...t,toggleEntity:"",toggleEntityTouched:!0}):null,L=O?[...O.targets,...O.skippedTargets].map(t=>t.entityId||("ref"in t?t.ref:"")).filter(Boolean).join(", "):"",B=(()=>{if(e)return null;const i=s.find(e=>e.value===t.binding);if(i)return i.label;const[o,a]=t.binding.split(":");return"device"===o?this.host._fullRegistryHass.devices[a]?.name_by_user||this.host._fullRegistryHass.devices[a]?.name||a:this.host._fullRegistryHass.entities[a]?.name||this.host.hass.states[a]?.attributes?.friendly_name||a})();return p``}_markerValueBadgeFields(t){return Ni({touched:t.valueBadgeTouched,originalHas:t.originalHasValueBadge,original:t.originalValueBadge,enabled:t.valueBadgeEnabled,source:t.valueBadgeSource,position:t.valueBadgePosition})}_markerValueSourceFields(t){return Ei({touched:t.valueSourceTouched,originalHas:t.originalHasValueSource,original:t.originalValueSource,source:t.valueSource})}_markerDraft(t){if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return null;const e=Ns(t.room),s=Ps(t.binding,t.devId,()=>"__hp_device_preview__"),i=this.host._markers.find(e=>e.id===s||e.id===t.devId),o=Rs(t.binding,t.controls,this.host._bindingEntities(t.binding)),a=this._effectiveStoredTapAction(t),n={id:s,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle||null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===a&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:o.length?o:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:t.hideFromPlan,vacuum:i?.vacuum||null},r=!!i&&("string"==typeof i.area&&i.area.length>0||null===i.area&&!!i.space&&!!i.room_id);return"virtual"===t.binding||t.roomTouched?(n.space=e?.space||("virtual"===t.binding?this.host._space:null),n.area=e?.area||null,n.room_id=e?.roomId||null):r&&(n.space=i.space,n.area=i.area,n.room_id=i.room_id),n}_markerPreviewDevice(t){const e=this._markerDraft(t);if(!e)return null;const s=`${this.host._haRegistry.revision}\n${Ft(this.host._markers)}\n${JSON.stringify(e)}`;if(this.host._markerPreviewMemo?.key===s)return this.host._markerPreviewMemo.device;const i=Hi({hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),marker:e,siblingMarkers:this.host._markers,settings:this.host._settings,excluded:this.host._excluded,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||this.host._space,loc:t=>this.host._t(t),iconRules:this.host._iconRules});return this.host._markerPreviewMemo={key:s,device:i},i}_markerPreviewDevices(t){const e=this.host._markerPreviewDevicesMemo;if(e?.base===this.host._devices&&e.preview===t)return e.devices;const s=[...this.host._devices.filter(e=>e.id!==t.id),t];return this.host._markerPreviewDevicesMemo={base:this.host._devices,preview:t,devices:s},s}_toggleIntent(t,e=this.host._devices){return this.host._toggleIntent(t,e)}_toggleIntentForDialog(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s=this._markerPreviewDevices(e);return this._toggleIntent(e,s)}_toggleStateText(t,e){return this.host._toggleStateText(t,e)}_toggleConfirmationStateText(t){return this.host._toggleConfirmationStateText(t)}_toggleConfirmationLines(t){return this.host._toggleConfirmationLines(t)}_toggleHintLines(t){if(!t)return[];const e=t=>this.host._t(`marker.toggle_effect_${t.replace("-","_")}`),s=t=>this.host._t(`marker.toggle_skip_${t.replace("-","_")}`);return Oi(t,{single:t=>{if("via"in t&&"virtual-light"===t.via)return this.host._t("marker.virtual_light_target",{name:t.name});const e=t.entityId||("ref"in t?t.ref:""),s=t.name||e;return this.host._t("marker.toggle_hint_single",{name:s,id:e})},group:t=>this.host._t("marker.toggle_hint_group",{count:t.length,names:t.map(t=>`${t.name} (${t.entityId})`).join(", ")}),currentNext:(t,s)=>"virtual-light"===t.via?this.host._t("marker.virtual_light_current",{state:this.host._t("on"===t.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:e(s)}):this.host._t("marker.toggle_hint_current",{state:this._toggleStateText(t.entityId,t.state),effect:e(s)}),groupCurrentNext:(t,s)=>this.host._t("marker.toggle_hint_group_current",{on:t.filter(t=>"on"===t.state).length,count:t.length,effect:e(s)}),skipped:t=>this.host._t("marker.toggle_hint_skipped",{count:t.length,targets:t.map(t=>{const e=t.entityId||t.ref;return`${t.name||e} (${e}: ${s(t.reason)})`}).join(", ")}),none:t=>this.host._t(`marker.toggle_none_${t.replaceAll("-","_")}`)})}_effectiveStoredTapAction(t,e){return t.tapActionTouched?t.tapAction:zs(t.originalHasTapAction?t.originalTapAction:null,e)}_effectiveMarkerTapAction(t,e=this._markerPreviewDevice(t)){return this._effectiveStoredTapAction(t,e?.primary?.split(".")[0])}_announceToggleDraft(t){const e=this._markerPreviewDevice(t),s=t.tapActionTouched?t:{...t,tapAction:this._effectiveMarkerTapAction(t,e)},i="toggle"===s.tapAction?this._toggleHintLines(this._toggleIntentForDialog(s)).join(" "):"";return{...s,tapHintAnnouncement:i}}_valueBadgeForBinding(t,e){const s={...t,binding:e,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},i=this._markerPreviewDevice(s);if(!i)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const o=[...this.host._devices.filter(t=>t.id!==i.id),i],a=Is(this.host._planHass,i,o),n=Ts(this.host._planHass,i,a);return{valueBadgeEnabled:t.valueBadgeEnabled&&!!n,valueBadgeSource:n,valueBadgeTouched:!0}}_markerSpatialSource(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s={...e,hidden:!1};return Li(Bi(this.host._planHass,[...this.host._devices.filter(t=>t.id!==s.id),s],null,this.host._virtualLights).filter(t=>t.device.id===s.id))}_markerAutoHasSpatialSource(t){const e={...t,lightRole:"auto",lightRoleTouched:!0},s=this._markerPreviewDevice(e);return!!s&&Wi(this.host._planHass,{...s})}_setMarkerLightRole(t){const e=this.host._markerDialog;e&&(this.host._markerDialog={...e,lightRole:t,lightRoleTouched:!0})}_controlRefInfo(t){if(!t.startsWith("marker:"))return{label:this.host.hass.states[t]?.attributes?.friendly_name||t,sub:t,icon:t.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this.host._planEntityAvailable(t)};const e=t.slice(7),s=this.host._markers.find(t=>t.id===e),i=this.host._devices.find(t=>t.id===e);if(!s||s.removed||!0!==s.is_light)return{label:this.host._t("marker.control_missing_label"),sub:`${this.host._t("marker.control_broken")} (${t})`,icon:"mdi:alert-outline",warning:!0};const o=this.host._serverCfg?.spaces.find(t=>t.id===(i?.space||s.space)),a=!!i&&ji(i).length>0;return{label:s.name||i?.name||e,sub:[o?.title||i?.space||s.space,s.room_id||i?.area,a?"":this.host._t("marker.control_passive")].filter(Boolean).join(" · "),icon:s.icon||i?.icon||"mdi:lightbulb-outline",warning:!0===s.hidden||!0===i?.hidden}}_valueBadgeCandidateLabel(t){const e=t.source;if("derived_lqi"===e.kind)return this.host._t("marker.value_badge_lqi");if("derived_marker_state"===e.kind)return this.host._t("marker.value_badge_marker_state",{name:t.label});if("entity_state"===e.kind)return this.host._t("marker.value_badge_state",{name:t.label});const s=this.host.hass.states[e.entity_id]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[e.entity_id]?.name||e.entity_id;return this.host._t(`marker.value_badge_attr_${e.attribute}`,{name:s})}_controlCandidates(t){const e=this._markerDraft(t)?.id||t.devId||"",s=[],i=new Set;for(const t of this.host._markers){if(t.id===e||t.removed||t.hidden||!0!==t.is_light)continue;if("virtual"!==t.binding&&"active"!==this.host._bindingStatus(t.binding).kind)continue;const o=this.host._devices.find(e=>e.id===t.id);if(!o||o.hidden)continue;const a=this._controlRefInfo(`marker:${t.id}`);for(const t of ji(o))i.add(t);s.push({value:`marker:${t.id}`,label:a.label,sub:a.sub,icon:a.icon,search:`${a.label} ${a.sub} ${t.id} ${ji(o).join(" ")}`.toLowerCase()})}const o=Object.keys(this.host.hass.states||{}).filter(e=>Gi(e)&&!i.has(e)&&qi(t.binding,[e],this.host._bindingEntities(t.binding)).length>0&&this.host._planEntityAvailable(e)).map(t=>{const e=this._controlRefInfo(t);return{value:t,label:e.label,sub:t,icon:e.icon,search:`${e.label} ${t}`.toLowerCase()}}),a=t.controlsFilter.trim().toLowerCase();return[...s,...o].filter(e=>!t.controls.includes(e.value)&&(!a||e.search.includes(a))).slice(0,12).map(({search:t,...e})=>e)}_addControlRef(t,e){if(e.startsWith("marker:")){const s=this._markerDraft(t)?.id||t.devId||"";if(!s)return void this.host._showToast(this.host._t("toast.marker_binding_required"));const i=e.slice(7),o=this._markerDraft(t),a=o?[...this.host._markers.filter(t=>t.id!==s),o]:this.host._markers;if(Ui(a,s,i))return void this.host._showToast(this.host._t("toast.marker_control_cycle"))}this.host._markerDialog=this._announceToggleDraft({...t,controls:[...t.controls,e],controlsFilter:""})}_setMarkerGlowMode(t){const e=this.host._markerDialog;if(!e)return;if("auto"===t)return void(this.host._markerDialog={...e,glowMode:t,glowTouched:!0});const s=this._markerSpatialSource(e),i=Ki(s?this.host._planHass.states[s.eid]:void 0,null,this.host._fillColors.glow_light.c),o=!e.glowColorDrafted,a="fixed"===t&&!e.glowBrightnessDrafted;this.host._markerDialog={...e,glowMode:t,glowColor:o?i.c:e.glowColor,glowBrightness:a?Math.max(1,Math.round(100*i.bri)):e.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:e.glowBrightnessDrafted||"fixed"===t,glowTouched:!0}}_renderRadarSection(t,e,s="main"){return uh({dialog:t,device:e,registryHass:this.host._fullRegistryHass,planHass:this.host._planHass,hass:this.host.hass,spaceModelById:t=>this.host._spaceModelById(t),currentSpace:()=>this.host._spaceModel(),position:t=>this.host._pos(t),updateDialog:t=>{this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,...t})},dialogDeviceId:()=>this.host._markerDialog?.devId,t:(t,e)=>this.host._t(t,e),help:t=>this._help(t),boolInput:(t,e)=>this._boolInput(t,e),toast:t=>this.host._showToast(t),setup:this._radarSetup,configRev:this.host._cfgRev},s)}_renderMarkerDialog(){const t=this.host._markerDialog,e="virtual"===t.bindingMode,s=this._bindingCandidates();this.host._bindingEntities(t.binding);const i=e?null:this.host._bindingStatus(t.binding),o=!e&&this.host._bindingHasHaPage(t.binding),a=this._markerPreviewDevice(t),n=this._effectiveMarkerTapAction(t,a),r=a?js(this.host._serverCfg?.spaces.find(t=>t.id===a.space)):null,l=a?this._markerPreviewDevices(a):this.host._devices,h="toggle"===n&&a?this._toggleIntent(a,l):null,c=this._toggleHintLines(h),u=a?Vi(this.host._planHass,a,{liveStates:!1!==this.host._config?.live_states,showTemperature:!1!==this.host._config?.show_temperature,showSignal:r?.showLqi??!1!==this.host._config?.show_signal,designPreview:!0,activityRuntime:this.host._activityRt.get(a.id),lightDevices:l,registryHass:this.host._fullRegistryHass,reducedMotion:this.host._reducedMotion}):null,_=a?Is(this.host._planHass,a,l):[],m=a?Ts(this.host._planHass,a,_):null,g=t.valueBadgeTouched?t.valueBadgeEnabled:!!u?.valueBadge,f=t.valueBadgeTouched?t.valueBadgeSource:u?.valueBadge?.source||t.valueBadgeSource,b=t.valueBadgeTouched?t.valueBadgePosition:u?.valueBadge?.position||t.valueBadgePosition,v=Ji(f),y=!!f&&!_.some(t=>t.key===v),$=_.find(t=>t.key===v),w=Ji(t.valueSource),k=!(!t.valueSource||w&&_.some(t=>t.key===w)),x=_.find(t=>t.key===w),S=u?.valueSource?.sourceKey||"",M=this._markerAutoHasSpatialSource(t),C=!!a&&Yi(this.host._planHass,{...a}),P=Xi(t.lightRole,M,C,t.glowMode),D=!P.sourceExists,I=!P.fromSourceEnabled,T=P.passive,R=P.effectiveMode,z="never"===t.lightRole?this.host._t("marker.glow_disabled_never"):"auto"!==t.lightRole||M?T?this.host._t("marker.glow_passive_hint"):this.host._t("marker.glow_disabled_no_entity"):this.host._t("marker.glow_disabled_auto"),A=a?ji(a):[],F=a&&Zi(a)||"",N=!!t.lightEntity&&!A.includes(t.lightEntity),E=a?Qi(a):[],H=!!t.toggleEntity&&!E.includes(t.toggleEntity),O="toggle"===n?this._toggleIntentForDialog({...t,toggleEntity:"",toggleEntityTouched:!0}):null,L=O?[...O.targets,...O.skippedTargets].map(t=>t.entityId||("ref"in t?t.ref:"")).filter(Boolean).join(", "):"",B=(()=>{if(e)return null;const i=s.find(e=>e.value===t.binding);if(i)return i.label;const[o,a]=t.binding.split(":");return"device"===o?this.host._fullRegistryHass.devices[a]?.name_by_user||this.host._fullRegistryHass.devices[a]?.name||a:this.host._fullRegistryHass.entities[a]?.name||this.host.hass.states[a]?.attributes?.friendly_name||a})();return p`this._closeMarkerDialog()}>
    @@ -2123,7 +2131,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    @@ -2148,7 +2156,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @input=${e=>this.host._markerDialog={...t,bindingFilter:e.target.value}} />
    ${s.map(e=>p`
    {if(e.value===t.binding)return void(this.host._markerDialog={...t,bindingOpen:!1});const s={...t,binding:e.value,bindingOpen:!1,controls:Ts(e.value,t.controls,this.host._bindingEntities(e.value)),autoIcon:this.host._autoIconForBinding(e.value),...sh(t.radar,t.radarTouched,t.radarRemove)};this.host._markerDialog=this._announceToggleDraft({...s,...this._valueBadgeForBinding(s,e.value),valueSource:null,valueSourceTouched:!0})}}> + @click=${()=>{if(e.value===t.binding)return void(this.host._markerDialog={...t,bindingOpen:!1});const s={...t,binding:e.value,bindingOpen:!1,controls:Rs(e.value,t.controls,this.host._bindingEntities(e.value)),autoIcon:this.host._autoIconForBinding(e.value),...ih(t.radar,t.radarTouched,t.radarRemove)};this.host._markerDialog=this._announceToggleDraft({...s,...this._valueBadgeForBinding(s,e.value),valueSource:null,valueSourceTouched:!0})}}> ${e.label}${e.sub}
    `)} ${s.length?d:p`
    ${this.host._t("marker.nothing_found")}
    `} @@ -2158,7 +2166,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 {const s={...t,tapAction:e.target.value,tapActionTouched:!0};this.host._markerDialog=this._announceToggleDraft(s)}}> - ${Qi.map(t=>[t,"tap."+t.replace("-","_")]).map(([t,e])=>p``)} @@ -2285,30 +2293,30 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("marker.glow_color_label")}${this._help("marker.glow_mode.help")}
    - ${"auto"!==z?p`
    + ${"auto"!==R?p`
    {this.host._markerDialog={...t,glowMode:z,glowColor:e.detail.color,glowColorDrafted:!0,glowTouched:!0}}}> - ${"fixed"===z?p` + @hp-color-opacity-change=${e=>{this.host._markerDialog={...t,glowMode:R,glowColor:e.detail.color,glowColorDrafted:!0,glowTouched:!0}}}> + ${"fixed"===R?p` ${this.host._t("marker.glow_brightness")} - ${this._rangeInput(1,100,1,t.glowBrightness,e=>{this.host._markerDialog={...t,glowMode:z,glowBrightness:e,glowBrightnessDrafted:!0,glowTouched:!0}},D,this.host._t("marker.glow_brightness"))} + ${this._rangeInput(1,100,1,t.glowBrightness,e=>{this.host._markerDialog={...t,glowMode:R,glowBrightness:e,glowBrightnessDrafted:!0,glowTouched:!0}},D,this.host._t("marker.glow_brightness"))} ${Math.round(t.glowBrightness)}%`:d}
    `:d} @@ -2327,7 +2335,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${D||T?p`

    - ${R} + ${z}

    `:d} @@ -2347,19 +2355,19 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 -

    ${this.host._t(Zc[t.display])}

    +

    ${this.host._t(Qc[t.display])}

    ${"value"===t.display?p`
    ${this._help("marker.value_source.help")}
    this.host._markerDialog={...t,valueBadgeSource:eo(e.target.value),valueBadgeEnabled:!0,valueBadgeTouched:!0}}> + @change=${e=>this.host._markerDialog={...t,valueBadgeSource:so(e.target.value),valueBadgeEnabled:!0,valueBadgeTouched:!0}}> ${y?p``:d} @@ -2481,7 +2489,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${t.pdfs.map(t=>p` - ${t.name} + ${t.name} this._removeMarkerPdf(t.url)}>`)}
    this.host._spaceDialog={...t,fillMode:e}} /> ${this.host._t(s)} @@ -2703,8 +2711,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 .label=${this.host._t("space.custom_fill")} .opacityLabel=${this.host._t("space.opacity")} .pickerLabels=${this.host._colorPickerLabels} - .color=${(t.customFill||Gs).c} - .opacity=${(t.customFill||Gs).a} + .color=${(t.customFill||qs).c} + .opacity=${(t.customFill||qs).a} @hp-color-opacity-change=${e=>{this.host._spaceDialog={...t,customFill:{c:e.detail.color,a:e.detail.opacity}}}}> ${t.customFill?p`
    `)}
    -
    `:d}`:d}`}_renderRoomDialog(){const t=!!this.host._roomEditId,e=t?null:this.host._wallFaceBatch,s=e&&e.candidates.length>1?this.host._t("room.queue_progress",{current:e.index+1,total:e.candidates.length}):"",i=Ws(this.host._curSpaceCfg),o=this.host._roomFill||i.fill,a=this.host._roomCustomFill||i.customFill,n=nt(this.host._roomTempMin,this.host._roomTempMax).valid,r=(!!this.host._areaSel||!!this.host._nameSel.trim())&&n,l=[...this.host._freeAreas];if(t&&this.host._areaSel&&!l.some(t=>t.area_id===this.host._areaSel)){const t=this.host.hass.areas[this.host._areaSel];t&&l.unshift(t)}return p``:d}`:d}`}_renderRoomDialog(){const t=!!this.host._roomEditId,e=t?null:this.host._wallFaceBatch,s=e&&e.candidates.length>1?this.host._t("room.queue_progress",{current:e.index+1,total:e.candidates.length}):"",i=js(this.host._curSpaceCfg),o=this.host._roomFill||i.fill,a=this.host._roomCustomFill||i.customFill,n=nt(this.host._roomTempMin,this.host._roomTempMax).valid,r=(!!this.host._areaSel||!!this.host._nameSel.trim())&&n,l=[...this.host._freeAreas];if(t&&this.host._areaSel&&!l.some(t=>t.area_id===this.host._areaSel)){const t=this.host.hass.areas[this.host._areaSel];t&&l.unshift(t)}return p`this._roomDialogCancel()}>
    @@ -2803,7 +2811,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 - ${[["","fill.inherit"],...ro.map(t=>[t,"fill."+t])].map(([t,e])=>p`
    - ${this.host._renderCardPreview(Ws(this.host._curSpaceCfg).cardFontScale,this.host._roomNameScale,this.host._roomLabelScale)} + ${this.host._renderCardPreview(js(this.host._curSpaceCfg).cardFontScale,this.host._roomNameScale,this.host._roomLabelScale)}
    @@ -2868,4 +2876,4 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("btn.save")} `}
    -
    `}}export{ad as EDITOR_RUNTIME_FINGERPRINT,nd as HouseplanEditorRuntime}; +
    `}}export{nd as EDITOR_RUNTIME_FINGERPRINT,rd as HouseplanEditorRuntime}; diff --git a/dist/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js similarity index 82% rename from dist/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js index fde24f47..92ed0a1b 100644 --- a/dist/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js +++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js @@ -1,6 +1,6 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{l as t,b3 as s,A as e,v as a,c as o,cm as l,cn as i,co as h,cp as c,b0 as n,cq as r,cv as p,cr as d,cs as _,ct as u,cu as g,cw as m,cx as b,ds as $,dt as v,du as f,a$ as y,b1 as w,dv as D}from"./houseplan-card-BCGpvbDT.js";import{c as k,e as S,r as C,a as M}from"./backdrop-pick-Caayxvt2.js";const F=1e3,x=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},T="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";class L{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_help(l){const i=`${l}.aria`,h=t(this.host.hass,this.host._config?.language);return s(h,l)&&s(h,i)?o``:e}_openSpaceDialog(t,s){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===t){const e=this.host._serverCfg.spaces.find(t=>t.id===s);if(!e)return;const a=l(e),o=e.settings?.custom_fill&&"object"==typeof e.settings.custom_fill?i(e.settings.custom_fill):null,p="none"===a.fill?{...o||h,a:0}:o;return void(this.host._spaceDialog={mode:t,spaceId:s,title:e.title,planUrl:e.plan_url||null,planFile:null,source:e.plan_url?"file":"draw",showBorders:a.showBorders,showNames:a.showNames,zeroWallStyle:r(e),displayTouched:!0,hideDecor:a.hideDecor,hideOpenings:a.hideOpenings,roomColor:a.color,roomOpacity:a.opacity,fillMode:"none"===a.fill?"custom":a.fill,customFill:p,glowEnabled:a.glow,bgColor:a.bgColor,bgMode:"static"===e.settings?.bg_mode||"daynight"===e.settings?.bg_mode?e.settings.bg_mode:null,northDeg:n({},e.settings),sunRays:"boolean"==typeof e.settings?.sun_rays?e.settings.sun_rays:null,tempMin:a.tempMin,tempMax:a.tempMax,showLqi:a.showLqi??this.host._config?.show_signal??!0,cardFontScale:a.cardFontScale,labelTemp:a.labelTemp,labelHum:a.labelHum,labelLqi:a.labelLqi,labelLight:a.labelLight,cellCm:Number(e.cell_cm)>0?Number(e.cell_cm):5,cellCmInput:c(Number(e.cell_cm)>0?Number(e.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const e=p(this.host._imperial);this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:{...h,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:e,cellCmInput:c(e,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const a=await k(e);if("reject"===a.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===a.kind)return void(this.host._backdropGuard=a.state);const o=await S(e,a.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:o})}_renderBackdropGuard(){return C(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??e}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),a=this.host._spaceDialog;return a&&a.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...a,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const s=this.host._spaceDialog,e=s?.saved?.find(s=>s.name===t);if(!s||!e||e.used_by.length||e.url===s.planUrl)return;const a=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),o=this.host._spaceDialog,l=o?.saved?.find(s=>s.name===t);if(a&&o&&l&&l.url===e.url&&l.modified===e.modified&&!l.used_by.length&&l.url!==o.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return o`
    ${this.host._t("space.loading")}
    `;const s=t.saved||[];if(!s.length)return o`
    ${this.host._t("space.no_saved")}
    `;return o`
    - ${s.map(s=>{return o` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{l as t,b4 as s,A as e,v as o,c as a,cn as l,co as i,cp as h,cq as c,b1 as n,cr as r,cw as p,cs as d,ct as _,cu as u,cv as g,cx as m,cy as b,dt as $,du as f,dv as v,b0 as y,b2 as w,dw as D}from"./houseplan-card-Di_izZTU.js";import{c as k,e as S,r as C,a as M}from"./backdrop-pick-CXmKHH6_.js";const F=1e3,x=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},T="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";class L{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_help(l){const i=`${l}.aria`,h=t(this.host.hass,this.host._config?.language);return s(h,l)&&s(h,i)?a``:e}_openSpaceDialog(t,s){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===t){const e=this.host._serverCfg.spaces.find(t=>t.id===s);if(!e)return;const o=l(e),a=e.settings?.custom_fill&&"object"==typeof e.settings.custom_fill?i(e.settings.custom_fill):null,p="none"===o.fill?{...a||h,a:0}:a;return void(this.host._spaceDialog={mode:t,spaceId:s,title:e.title,planUrl:e.plan_url||null,planFile:null,source:e.plan_url?"file":"draw",showBorders:o.showBorders,showNames:o.showNames,zeroWallStyle:r(e),displayTouched:!0,hideDecor:o.hideDecor,hideOpenings:o.hideOpenings,roomColor:o.color,roomOpacity:o.opacity,fillMode:"none"===o.fill?"custom":o.fill,customFill:p,glowEnabled:o.glow,bgColor:o.bgColor,bgMode:"static"===e.settings?.bg_mode||"daynight"===e.settings?.bg_mode?e.settings.bg_mode:null,northDeg:n({},e.settings),sunRays:"boolean"==typeof e.settings?.sun_rays?e.settings.sun_rays:null,tempMin:o.tempMin,tempMax:o.tempMax,showLqi:o.showLqi??this.host._config?.show_signal??!0,cardFontScale:o.cardFontScale,labelTemp:o.labelTemp,labelHum:o.labelHum,labelLqi:o.labelLqi,labelLight:o.labelLight,cellCm:Number(e.cell_cm)>0?Number(e.cell_cm):5,cellCmInput:c(Number(e.cell_cm)>0?Number(e.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const e=p(this.host._imperial);this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:{...h,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:e,cellCmInput:c(e,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await k(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await S(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return C(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??e}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const s=this.host._spaceDialog,e=s?.saved?.find(s=>s.name===t);if(!s||!e||e.used_by.length||e.url===s.planUrl)return;const o=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._spaceDialog,l=a?.saved?.find(s=>s.name===t);if(o&&a&&l&&l.url===e.url&&l.modified===e.modified&&!l.used_by.length&&l.url!==a.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return a`
    ${this.host._t("space.loading")}
    `;const s=t.saved||[];if(!s.length)return a`
    ${this.host._t("space.no_saved")}
    `;return a`
    + ${s.map(s=>{return a`
    @@ -16,16 +16,16 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    `;var e})} -
    `}async _saveConfigNow(){this.host._cfgEpoch++;try{await this.host._writeConfig()}catch(t){const s=t;throw s?.physicalGeometryRolledBack?await this.host._reloadRejectedPhysicalWrite():"conflict"===s?.code&&await this.host._reloadConfigOnly(),t}}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const s="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const e="create"===t.mode?`s${Date.now().toString(36)}`:t.spaceId;let a=null;if("file"===t.source&&t.planFile){a={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:e,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let o=t.savedAspect||null;!a&&"file"===t.source&&t.planUrl&&!o&&this.host._aspectJob&&(o=await this.host._aspectJob||null);const l=this.host._serverCfg;let i=l.spaces.find(t=>t.id===e);if("create"===t.mode)i=b(e,t.title.trim()),l.spaces.push(i);else{if(!i)throw new Error(`space ${e} is gone from the config`);i.title=t.title.trim()}if(!i)throw new Error(`space ${e} is unavailable`);if(a?(i.plan_url=a.url,i.plan_aspect=a.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==i.plan_url&&(i.plan_url=t.planUrl,i.plan_aspect=o),"draw"===t.source&&(i.plan_url=null,i.plan_aspect=null,delete i.plan_x,delete i.plan_y,delete i.plan_scale,delete i.plan_scale_x,delete i.plan_scale_y,delete i.plan_angle),i.settings={...i.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):_,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):d,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},i.zero_wall_style=t.zeroWallStyle,i.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(F,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(i.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length)this._openNextImport();else if(s||this.host._importTotal>0){const t=this.host._importTotal>0;this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),await this.host._requestMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._showToast(this.host._t(s&&!t?"toast.space_added_onboard":"import.done"))}else this.host._showToast(this.host._t("create"===t.mode?"toast.space_added":"toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?await this.host._requestMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._saveNav()))}catch(t){const s=t;"conflict"!==s?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const s=this.host._serverCfg;if(!s)return;const e=s.spaces.find(s=>s.id===t.spaceId);if(!e)return;const a=M(s,this.host._layout||{},t.spaceId||""),o=1===s.spaces.length&&s.spaces[0]?.id===t.spaceId;if(a.count&&!o)return void(this.host._spaceDialog={...t,deleteBlockers:a.count});const l=t.spaceId,i=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:this.host._t("confirm.delete_space_body"),objectName:e.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),h=this.host._spaceDialog,c=this.host._serverCfg;if(!i||!h||"edit"!==h.mode||h.busy||h.spaceId!==l||!c)return;if(!c.spaces.find(t=>t.id===l))return;const n=M(c,this.host._layout||{},l),r=1===c.spaces.length&&c.spaces[0]?.id===l;if(!n.count||r){this.host._spaceDialog={...h,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:l,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:s,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...h,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===l&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){const s=t;"conflict"!==s?.code&&"space_in_use"!==s?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=M(e,this.host._layout||{},l),s=1===e.spaces.length&&e.spaces[0]?.id===l;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...h,deleteBlockers:n.count}}_startImport(){const t=this.host._importDialog;if(!t)return;const s=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,s.length?(this.host._importQueue=s,this.host._importTotal=s.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();if(void 0===t)return;const s=p(this.host._imperial);this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:s,cellCmInput:c(s,this.host._imperial),cellCmTouched:!1,busy:!1}}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this.host._requestMode("plan").then(()=>{this.host._showToast(this.host._t("import.done"))}))}_renderImportDialog(){const t=this.host._importDialog,s=t.floors.filter(t=>t.checked).length;return o``}async _saveConfigNow(){this.host._cfgEpoch++;try{await this.host._writeConfig()}catch(t){const s=t;throw s?.physicalGeometryRolledBack?await this.host._reloadRejectedPhysicalWrite():"conflict"===s?.code&&await this.host._reloadConfigOnly(),t}}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const s="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const e="create"===t.mode?`s${Date.now().toString(36)}`:t.spaceId;let o=null;if("file"===t.source&&t.planFile){o={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:e,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let a=t.savedAspect||null;!o&&"file"===t.source&&t.planUrl&&!a&&this.host._aspectJob&&(a=await this.host._aspectJob||null);const l=this.host._serverCfg;let i=l.spaces.find(t=>t.id===e);if("create"===t.mode)i=b(e,t.title.trim()),l.spaces.push(i);else{if(!i)throw new Error(`space ${e} is gone from the config`);i.title=t.title.trim()}if(!i)throw new Error(`space ${e} is unavailable`);if(o?(i.plan_url=o.url,i.plan_aspect=o.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==i.plan_url&&(i.plan_url=t.planUrl,i.plan_aspect=a),"draw"===t.source&&(i.plan_url=null,i.plan_aspect=null,delete i.plan_x,delete i.plan_y,delete i.plan_scale,delete i.plan_scale_x,delete i.plan_scale_y,delete i.plan_angle),i.settings={...i.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):_,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):d,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},i.zero_wall_style=t.zeroWallStyle,i.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(F,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(i.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length)this._openNextImport();else if(s||this.host._importTotal>0){const t=this.host._importTotal>0;this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),await this.host._requestMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._showToast(this.host._t(s&&!t?"toast.space_added_onboard":"import.done"))}else this.host._showToast(this.host._t("create"===t.mode?"toast.space_added":"toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?await this.host._requestMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._saveNav()))}catch(t){const s=t;"conflict"!==s?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const s=this.host._serverCfg;if(!s)return;const e=s.spaces.find(s=>s.id===t.spaceId);if(!e)return;const o=M(s,this.host._layout||{},t.spaceId||""),a=1===s.spaces.length&&s.spaces[0]?.id===t.spaceId;if(o.count&&!a)return void(this.host._spaceDialog={...t,deleteBlockers:o.count});const l=t.spaceId,i=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:this.host._t("confirm.delete_space_body"),objectName:e.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),h=this.host._spaceDialog,c=this.host._serverCfg;if(!i||!h||"edit"!==h.mode||h.busy||h.spaceId!==l||!c)return;if(!c.spaces.find(t=>t.id===l))return;const n=M(c,this.host._layout||{},l),r=1===c.spaces.length&&c.spaces[0]?.id===l;if(!n.count||r){this.host._spaceDialog={...h,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:l,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:s,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...h,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===l&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){const s=t;"conflict"!==s?.code&&"space_in_use"!==s?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=M(e,this.host._layout||{},l),s=1===e.spaces.length&&e.spaces[0]?.id===l;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...h,deleteBlockers:n.count}}_startImport(){const t=this.host._importDialog;if(!t)return;const s=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,s.length?(this.host._importQueue=s,this.host._importTotal=s.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();if(void 0===t)return;const s=p(this.host._imperial);this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:s,cellCmInput:c(s,this.host._imperial),cellCmTouched:!1,busy:!1}}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this.host._requestMode("plan").then(()=>{this.host._showToast(this.host._t("import.done"))}))}_renderImportDialog(){const t=this.host._importDialog,s=t.floors.filter(t=>t.checked).length;return a`this.host._importDialog=null}>
    ${this.host._t("import.hint")}
    - ${t.floors.map((s,a)=>o`
    @@ -36,11 +36,11 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("import.start",{n:s})}
    -
    `}_boolInput(t,s){return o`s(t.target.checked)} />`}_rangeInput(t,s,e,a,l){return o`l(Number(t.target.value))} />`}_renderSpaceDialog(){return this._renderSpaceDialogBody(this.host._spaceDialog)}_renderSpaceDialogBody(t){const s=this.host._importTotal>0&&"create"===t.mode?this.host._t("import.progress",{i:this.host._importTotal-this.host._importQueue.length,n:this.host._importTotal}):"",a=()=>{this.host._spaceDialog=null,this.host._importQueue=[],this.host._importTotal=0};return o``}_boolInput(t,s){return a`s(t.target.checked)} />`}_rangeInput(t,s,e,o,l){return a`l(Number(t.target.value))} />`}_renderSpaceDialog(){return this._renderSpaceDialogBody(this.host._spaceDialog)}_renderSpaceDialogBody(t){const s=this.host._importTotal>0&&"create"===t.mode?this.host._t("import.progress",{i:this.host._importTotal-this.host._importQueue.length,n:this.host._importTotal}):"",o=()=>{this.host._spaceDialog=null,this.host._importQueue=[],this.host._importTotal=0};return a` + icon="mdi:floor-plan" wide @hp-close=${o}>
    ${this.host._t("space.source_file")} - ${"file"===t.source?o`
    - ${t.planFile?o`${t.planFile.name}`:t.planUrl?o`${this.host._t("space.plan_alt")}`:o`${this.host._t("space.no_plan")}`} + ${"file"===t.source?a`
    + ${t.planFile?a`${t.planFile.name}`:t.planUrl?a`${this.host._t("space.plan_alt")}`:a`${this.host._t("space.no_plan")}`}
    @@ -107,7 +107,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${this.host._t("space.hide_openings_tip")}
    - ${[["labelTemp","space.label_temp"],["labelHum","space.label_hum"],["labelLqi","space.label_lqi"],["labelLight","space.label_light"]].map(([s,e])=>o`
    - ${D.map(t=>[t,`fill.${t}`]).map(([s,a])=>o` - ${t.deleteBlockers?o` `}renderDialog(){return this.dialog&&this.editorRenderer?(this.dialog.localOnly||this.refreshEntityIndex(),this.editorRenderer({host:this.host,dialog:this.dialog,local:this.local,storageUnavailable:this.storageUnavailable,problems:this.problems(this.dialog),entityIndex:this.entityIndex||O({},null),setDialog:e=>{this.dialog=e,this.host.requestUpdate()},saveLocal:e=>this.saveLocal(e),mutate:e=>this.mutate(e),deleteBlock:e=>{this.deleteBlock(e)},dragStart:(e,t)=>this.dragStart(e,t),drop:(e,t)=>this.drop(e,t),sourceToken:e=>this.sourceToken(e),openSource:(e,t)=>this.openSource(e,t),closeSource:e=>this.closeSource(e),setSource:(e,t,s)=>this.setSource(e,t,s),save:()=>{this.saveDialog()},reload:()=>{this.reloadDialog()},close:()=>this.closeDialogIfIdle(),t:e=>this.t(e)})):t}t(e){return e.startsWith("summary.")?function(e,t){const s=e.toLowerCase().split("-")[0];return(T[s]||T.en)[t]||T.en[t]||t}(r(this.host.hass,this.host._config?.language),e):this.host._t(e)}ensureStyle(){const e=this.host.renderRoot;if(this.styleSheet&&e.adoptedStyleSheets.includes(this.styleSheet))return;const t=this.host.ownerDocument.defaultView?.CSSStyleSheet;if(t&&"adoptedStyleSheets"in e){const s=new t;return s.replaceSync(M),this.styleSheet=s,void(e.adoptedStyleSheets=[...e.adoptedStyleSheets,s])}if(e.querySelector("style[data-hp-summary]"))return;const s=this.host.ownerDocument.createElement("style");s.dataset.hpSummary="true",s.textContent=M,e.insertBefore(s,e.firstChild)}ensureDialogStyle(){const e=this.host.renderRoot.querySelector('hp-dialog[data-kind="summary"]')?.shadowRoot;if(!e||this.styledDialogRoots.has(e))return;const t=this.host.ownerDocument.defaultView?.CSSStyleSheet;if(t&&"adoptedStyleSheets"in e)this.dialogStyleSheet||(this.dialogStyleSheet=new t,this.dialogStyleSheet.replaceSync($)),e.adoptedStyleSheets=[...e.adoptedStyleSheets,this.dialogStyleSheet];else{const t=this.host.ownerDocument.createElement("style");t.dataset.hpSummaryShell="true",t.textContent=$,e.appendChild(t)}this.styledDialogRoots.add(e)}placementSlot(){return N(this.host)}preferenceKey(){return function(e){const t=l(e.userId),s=l(e.slot);return t&&s?`houseplan.summary-panel.v1:${[t,l(e.path)||"/",l(e.host)||"card",s].map(e=>encodeURIComponent(e)).join(":")}`:null}({userId:this.host.hass?.user?.id||this.host.hass?.user?.name,path:location.pathname,host:this.host.panelHost?"panel":"lovelace",slot:this.placementSlot()})}identity(){return JSON.stringify({key:this.preferenceKey(),user:this.host.hass?.user?.id||this.host.hass?.user?.name||"",route:location.pathname,host:this.host.panelHost?"panel":"lovelace",slot:this.placementSlot(),kiosk:this.host._kiosk,canManage:this.host._canManageConfiguration})}syncLifecycle(){const e=this.identity();this.lifecycleIdentity&&e!==this.lifecycleIdentity&&this.resetLifecycle(),this.lifecycleIdentity=e}resetLifecycle(){this.presentation.reset(),this.lifecycleGeneration++,this.dialog=null,this.entityIndex=null,this.deviceMemo=null,this.areaMemo=null,this.clockContext="",this.storageKey=null,this.storageUnavailable=!1,this.local={version:1,show:!1,icon_scale:1,font_scale:1},this.clockTimer&&clearTimeout(this.clockTimer),this.clockTimer=0,this.lifecycleIdentity=this.connected?this.identity():"",this.host.requestUpdate()}current(e){return this.connected&&e===this.lifecycleGeneration&&this.lifecycleIdentity===this.identity()}refreshEntityIndex(){this.entityIndex=O(this.host.hass?.states,this.entityIndex)}syncNativeNarrow(){if(this.host.panelHost)return;let e=this.host;for(let t=0;e&&t<12;t++){const t=e.getRootNode();if(e=e.parentNode||(t instanceof ShadowRoot?t.host:null),!e||e===this.host)continue;const s=e.narrow;if("boolean"==typeof s)return void(this.host.narrow!==s&&(this.host.narrow=s))}}loadLocal(){const e=this.preferenceKey();if(!e||e===this.storageKey)return;let t=null,s=null,r=!0;try{t=JSON.parse(localStorage.getItem(e)||"null")}catch{r=!1}try{s=JSON.parse(localStorage.getItem("houseplan_card_kiosk_v1")||"null")}catch{r=!1}this.storageKey=e,this.storageUnavailable=!r,this.local=function(e,t){const s=e&&"object"==typeof e?e:{},r=t&&"object"==typeof t?t:{};return{version:1,show:!0===s.show,icon_scale:v(m(s,"icon_scale")?s.icon_scale:r.icon),font_scale:v(m(s,"font_scale")?s.font_scale:r.font)}}(t,s),this.host._kioskScale={icon:this.local.icon_scale,font:this.local.font_scale}}saveLocal(e){this.local={...this.local,...e,version:1,icon_scale:v(e.icon_scale??this.local.icon_scale),font_scale:v(e.font_scale??this.local.font_scale)},this.host._kioskScale={icon:this.local.icon_scale,font:this.local.font_scale},this.storageKey||=this.preferenceKey();let t=!1;try{this.storageKey&&(localStorage.setItem(this.storageKey,JSON.stringify(this.local)),t=!0)}catch{}this.storageUnavailable=!t,t||this.host._showToast?.(this.t("summary.storage_unavailable")),this.host.requestUpdate()}config(){return function(e,t){const s=e?.summary_panel;return void 0===s?{config:d(t),derived:!0,unsupported:!1}:h(s)?{config:s,derived:!1,unsupported:!1}:{config:null,derived:!1,unsupported:!0}}(this.host._settings,this.translate)}async openDialog(){const e=this.lifecycleGeneration;this.loadLocal();try{this.editorLoad||=import("./summary-panel-editor-BDoONUEa.js").then(e=>e.renderSummaryPanelEditor),this.editorRenderer=await this.editorLoad}catch(t){if(this.editorLoad=null,!this.current(e))return;return void this.host._showToast?.(`${this.t("summary.load_failed")} ${this.host._errText(t)}`)}if(!this.current(e))return;const t=this.config(),s=t.config||d(this.translate),r=this.host._haSummaryPanelApi!==i,a=t.unsupported?"summary.unsupported_schema":r&&this.host._canManageConfiguration?"summary.backend_required":"summary.local_only";this.dialog={draft:y(s),base:y(s),baseRevision:this.host._cfgRev,localShow:this.local.show,baseLocalShow:this.local.show,localOnly:this.host._kiosk||!this.host._canManageConfiguration||r||t.unsupported,localOnlyHint:a,busy:!1,attempted:!1,entityFilter:"",activeSource:null,error:"",conflict:!1},this.dialog.localOnly||this.refreshEntityIndex(),this.host.requestUpdate()}problems(e=this.dialog){return!e||e.localOnly?[]:g(f(e.draft),e.base,new Set(this.host._model.map(e=>e.id)),new Set(Object.keys(this.host.hass?.states||{})))}mutate(e){if(!this.dialog||this.dialog.busy||this.dialog.localOnly)return;const t=y(this.dialog.draft);e(t);const s=this.dialog.activeSource,r=!s||t.blocks.some(e=>e.id===s.blockId&&e.values.some(e=>e.id===s.valueId));this.dialog={...this.dialog,draft:t,error:"",conflict:!1,activeSource:r?s:null,entityFilter:r?this.dialog.entityFilter:""},this.host.requestUpdate()}async deleteBlock(e){const t=this.dialog?.draft.blocks[e];if(!t)return;const s=this.lifecycleGeneration;if(t.values.length){if(!await this.host._confirmDanger({key:"summary-block",kind:"warning",title:this.t("summary.delete_block_title"),message:this.t("summary.delete_block_body"),objectName:t.title,confirmLabel:this.t("btn.delete"),cancelLabel:this.t("btn.cancel")})||!this.current(s))return}this.mutate(e=>{const s=e.blocks.findIndex(e=>e.id===t.id);s>=0&&e.blocks.splice(s,1)})}sourceToken(e){return"system"===e.type?`system:${e.key}`:`entity:${e.entity_id}`}openSource(e,t){!this.dialog||this.dialog.busy||this.dialog.localOnly||(this.refreshEntityIndex(),this.dialog={...this.dialog,activeSource:{blockId:e,valueId:t},entityFilter:""},this.host.requestUpdate(),this.host.updateComplete.then(()=>{this.dialog?.activeSource?.blockId===e&&this.dialog.activeSource.valueId===t&&this.host.renderRoot.querySelector("[data-summary-picker-search]")?.focus()}))}closeSource(e=!1){const t=this.dialog?.activeSource;this.dialog&&t&&(this.dialog={...this.dialog,activeSource:null,entityFilter:""},this.host.requestUpdate(),e&&this.focusSource(t.blockId,t.valueId))}async focusSource(e,t){await this.host.updateComplete;const s=`${e}\n${t}`,r=this.host.renderRoot.querySelectorAll("[data-summary-source-owner]");[...r].find(e=>e.dataset.summarySourceOwner===s)?.focus()}setSource(e,t,s){this.mutate(r=>{const i=r.blocks.find(t=>t.id===e)?.values.find(e=>e.id===t);if(i)if(s.startsWith("system:")){const e=s.slice(7);(e=>"device_count"===e||"total_area"===e||"datetime"===e)(e)&&(i.source={type:"system",key:e})}else i.source={type:"entity",entity_id:s.startsWith("entity:")?s.slice(7):s}}),this.dialog&&(this.dialog={...this.dialog,activeSource:null,entityFilter:""}),this.host.requestUpdate(),this.focusSource(e,t)}dragStart(e,t){e.dataTransfer?.setData("text/x-houseplan-summary",t),e.dataTransfer&&(e.dataTransfer.effectAllowed="move")}drop(e,t){e.preventDefault(),e.stopPropagation();const s=e.dataTransfer?.getData("text/x-houseplan-summary")||"",r=s.split(":").map(Number),i=t.split(":").map(Number);s.startsWith("block:")&&t.startsWith("block:")?this.mutate(e=>{e.blocks=w(e.blocks,r[1],i[1])}):s.startsWith("value:")&&t.startsWith("value:")&&r[1]===i[1]&&this.mutate(e=>{e.blocks[r[1]].values=w(e.blocks[r[1]].values,r[2],i[2])})}async saveDialog(){const e=this.dialog;if(!e||e.busy)return;const t=this.lifecycleGeneration,s=f(e.draft);if((e.localOnly?[]:g(s,e.base,new Set(this.host._model.map(e=>e.id)),new Set(Object.keys(this.host.hass?.states||{})))).some(e=>"error"===e.kind))return this.dialog={...e,draft:s,attempted:!0},this.host.requestUpdate(),await this.host.updateComplete,void this.host.renderRoot.querySelector('[data-summary-error="true"]')?.focus?.();this.dialog={...e,draft:s,busy:!0,attempted:!1,error:"",conflict:!1},this.host.requestUpdate();try{if(!e.localOnly&&!_(s,e.base)){this.host._writesPending++;const r=a(this.host._writeChain,async()=>{if(!this.current(t))return;if(!this.host._serverCfg)throw new Error(this.t("summary.save_failed"));if(this.host._cfgRev!==e.baseRevision)throw new Error(this.t("summary.conflict"));const r=o({...this.host._serverCfg,settings:{...this.host._serverCfg.settings||{},summary_panel:s}});let i=!1;try{if(await this.host._sendConfigCandidate(r),!this.current(t))return}catch(e){if(!this.current(t))throw e;try{const r=await this.host._getAuthoritativeConfig();if(!this.current(t))throw e;const a=function(e,t){if(!c(e))return null;const s=e.config,r=e.rev;if(!c(s)||!Array.isArray(s.spaces)||"number"!=typeof r||!Number.isSafeInteger(r)||r<0)return null;const i=c(s.settings)?s.settings:null,a=i?.summary_panel;return h(a)&&_(a,t)?{config:s,rev:r}:null}(r,s);if(!a)throw e;const o=await this.host._adoptAuthoritative({cfgResp:r,reason:"summary-recovery",profile:"reload"});if("adopted"!==o.status)throw e;o.spaceChanged&&this.host._restoreZoom(),this.host._regSignature="",this.host._maybeRebuildDevices(),i=!0}catch{throw e}}if(!i){if(!this.current(t))return;this.host._adoption.stageConfigCandidate(r),this.host._cacheSnapshot()}});this.host._writeChain=r,await r.finally(()=>{this.host._writesPending--})}if(!this.current(t))return;this.saveLocal({show:e.localShow}),this.dialog=null}catch(s){if(!this.current(t))return;const r="conflict"===s?.code||this.host._cfgRev!==e.baseRevision;this.dialog={...this.dialog||e,busy:!1,conflict:r,error:r?this.t("summary.conflict"):this.host._errText(s)}}this.current(t)&&this.host.requestUpdate()}async reloadDialog(){const e=this.dialog;if(!e||e.busy)return;const t=this.lifecycleGeneration;this.dialog={...e,busy:!0,error:"",conflict:!1},this.host.requestUpdate();try{if(await this.host._reloadConfigOnly(!0),!this.current(t))return;if(e.conflict&&this.host._cfgRev===e.baseRevision)throw new Error(this.t("summary.load_failed"));const s=this.config().config||d(this.translate);this.dialog={...e,draft:y(s),base:y(s),baseRevision:this.host._cfgRev,busy:!1,attempted:!1,error:"",conflict:!1}}catch(s){if(!this.current(t))return;this.dialog={...e,busy:!1,error:this.host._errText(s),conflict:!0}}this.current(t)&&this.host.requestUpdate()}metricsFresh(){return!!this.deviceMemo&&!!this.areaMemo&&this.deviceMemo.cfgEpoch===this.host._cfgEpoch&&this.deviceMemo.layoutRev===this.host._layoutRev&&this.deviceMemo.registryRev===this.host._haRegistry.revision&&this.areaMemo.cfgEpoch===this.host._cfgEpoch}scheduleMetrics(){if(this.metricsRefresh||!this.metricsModule||this.metricsFresh())return;const e=this.lifecycleGeneration,t="undefined"==typeof window?void 0:window,s=()=>{if(this.metricsRefresh=0,!this.current(e))return;const t=this.advanceMetrics(8);this.host.requestUpdate(),t||this.scheduleMetrics()};this.metricsRefresh=t?.setTimeout(()=>{"function"==typeof t.requestAnimationFrame?t.requestAnimationFrame(()=>t.setTimeout(s,0)):s()},0)||0}advanceMetrics(e=8){const t=this.metricsModule;if(!t)return!0;if(this.computeDeviceCount(),!this.host._serverCfg)return this.areaMemo={cfgEpoch:this.host._cfgEpoch,value:null},!0;if(this.areaMemo&&this.areaMemo.cfgEpoch===this.host._cfgEpoch)return!0;this.areaSteps&&this.areaStepsEpoch===this.host._cfgEpoch||(this.areaSteps=t.cleanFloorAreaSteps(this.host._serverCfg,this.host._model),this.areaStepsEpoch=this.host._cfgEpoch);const s=Date.now();let r=this.areaSteps.next();for(;!r.done&&Date.now()-s[e,t.space])),spaceIds:new Set(this.host._model.map(e=>e.id)),firstSpaceId:this.host._model[0]?.id||"",markers:this.host._markers});this.deviceMemo={cfgEpoch:this.host._cfgEpoch,layoutRev:this.host._layoutRev,registryRev:this.host._haRegistry.revision,value:t?.size??null}}}computeMetrics(){for(;!this.advanceMetrics(Number.POSITIVE_INFINITY););}metrics(){return{deviceCount:this.deviceMemo?this.deviceMemo.value:null,areaM2:this.areaMemo?this.areaMemo.value:null,now:this.clock}}valueState(e){const t=this.metricsModule;if(!t)return{kind:"pending"};if("entity"===e.source.type){const s=t.summaryEntityValue(this.host.hass,e.source.entity_id);return null===s?{kind:"unavailable"}:{kind:"ready",text:s}}const s="device_count"===e.source.key||"total_area"===e.source.key,i="device_count"===e.source.key?this.deviceMemo:this.areaMemo;if(s&&!i)return this.scheduleMetrics(),{kind:"pending"};s&&this.scheduleMetrics();const a=t.summarySystemValue(e.source,this.metrics(),this.host.hass,r(this.host.hass,this.host._config?.language));return null===a?{kind:"unavailable"}:{kind:"ready",text:a}}value(e){const t=this.valueState(e);return"ready"===t.kind?t.text:this.t("summary.unavailable")}ensureMetrics(){if(this.metricsModule||this.metricsLoad)return;const e=this.lifecycleGeneration;this.metricsLoad=import("./summary-panel-metrics-O-xxtEs5.js"),this.metricsLoad.then(t=>{this.metricsModule=t,this.current(e)&&this.host.requestUpdate()}).catch(()=>{}).finally(()=>{this.metricsLoad=null})}layout(){return function(e){const t=Math.max(0,Number(e.width)||0),s=Math.max(0,Number(e.height)||0),r=t>=s?"right":"bottom",i=Math.max(0,e.safeLeft||0)+12,a=Math.max(0,e.safeRight||0)+12,o=Math.max(Math.max(0,e.safeTop||0)+12,e.controlTop||0),n=Math.max(Math.max(0,e.safeBottom||0)+12,e.controlBottom||0),l=Math.max(0,t-i-a),m=Math.max(0,s-o-n),c="bottom"===r?Math.min(.6*s,m):m;return{side:r,fits:t>0&&s>0&&l>=280&&c>=Math.max(0,e.minimumHeight),availableWidth:l,heightCap:c,top:o,bottom:n}}({width:this.stage.width,height:this.stage.height,...this.safeInsets(),controlTop:this.host._kiosk?this.stage.controlTop:0,minimumHeight:this.stage.minimumHeight})}syncPresentation(e=!1){const t=this.config().config,s=this.layout(),r=!!t&&"view"===this.host._mode&&s.fits&&b({view:!0,localShow:!0,showOnMobile:t.show_on_mobile,narrow:this.host.narrow,fits:!0});this.presentation.sync(r&&this.local.show,s.side,e||!r||"hidden"===this.host.ownerDocument.visibilityState)}measureLayout(){const e=this.host._stageEl;if(!e)return;const t=this.host.renderRoot.querySelector(".summary-measure"),s=this.host.renderRoot.querySelector(".summary-control.kiosk"),r=e.getBoundingClientRect(),i=s?.getBoundingClientRect(),a={width:Math.round(e.clientWidth),height:Math.round(e.clientHeight),minimumHeight:Math.max(162,Math.ceil(t?.getBoundingClientRect().height||0)),controlTop:i?Math.max(0,Math.ceil(i.bottom-r.top+12)):0};a.width===this.stage.width&&a.height===this.stage.height&&a.minimumHeight===this.stage.minimumHeight&&a.controlTop===this.stage.controlTop||(this.stage=a,this.host.requestUpdate())}safeInsets(){const e=this.host.renderRoot.querySelector(".summary-safe-probe");if(!e)return{safeLeft:0,safeRight:0,safeTop:0,safeBottom:0};const t=this.host.ownerDocument.defaultView?.getComputedStyle(e);if(!t)return{safeLeft:0,safeRight:0,safeTop:0,safeBottom:0};const s=e=>Number.parseFloat(e)||0;return{safeLeft:s(t.paddingLeft),safeRight:s(t.paddingRight),safeTop:s(t.paddingTop),safeBottom:s(t.paddingBottom)}}hasVisibleClock(){const e=this.config().config;return!("hidden"===this.host.ownerDocument.visibilityState||!e)&&(!!b({view:"view"===this.host._mode,localShow:this.local.show,showOnMobile:e.show_on_mobile,narrow:this.host.narrow,fits:this.layout().fits})&&p(e,this.host._space).some(e=>e.values.some(e=>"system"===e.source.type&&"datetime"===e.source.key)))}syncClock(){const e=`${r(this.host.hass,this.host._config?.language)}\n${this.host.hass?.config?.time_zone||""}`;e!==this.clockContext&&(this.clockContext=e,this.clock=new Date);const t=this.hasVisibleClock();if(t&&!this.clockTimer){this.clock=new Date;const e=()=>{this.clock=new Date,this.clockTimer=0,this.host.requestUpdate(),this.syncClock()};this.clockTimer=window.setTimeout(e,6e4-Date.now()%6e4+25)}else!t&&this.clockTimer&&(clearTimeout(this.clockTimer),this.clockTimer=0)}}});export{C as a,U as b,k as c,x as d,j as e,w as m,f as n,_ as s}; diff --git a/dist/houseplan-assets/zigbee-topology-DlU7AXvw.js b/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-Ba2URGlk.js similarity index 95% rename from dist/houseplan-assets/zigbee-topology-DlU7AXvw.js rename to custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-Ba2URGlk.js index 75902f0d..885c9315 100644 --- a/dist/houseplan-assets/zigbee-topology-DlU7AXvw.js +++ b/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-Ba2URGlk.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{s as e,F as n}from"./houseplan-card-BCGpvbDT.js";var t={title:"Zigbee links",toggle:"Show Zigbee links when hovering over a device",hint:"Shows observed direct neighbours only. Nothing is fetched while you hover.",help:"Shows which Zigbee devices each device talks to directly. Line colour is link quality (LQI) on the same scale as the device's LQI reading: red at 40 and below, green at 180 and above. A dashed line means quality was not reported. An arrow points to the next device on the way to the coordinator: one arrow leads out, incoming arrows are the devices that route through this one. A line without an arrow is a spare neighbour. This is the route tree House Plan builds, not the path a packet takes right now: a label at the end of an arrow means its target is not on this plan, and no arrow at all means the route is unknown. Data comes from the last load and goes stale; links are shown with a mouse only.",help_aria:"Help: Zigbee links",admin_only:"Topology data is available to Home Assistant administrators only.",save_first:"Save this setting before loading topology data.",zha:"ZHA",zha_read:"Read ZHA data",zha_hint:"Reads ZHA's cached topology; it does not start a radio scan.",z2m:"Zigbee2MQTT",z2m_topics:"Base topics (one per line)",z2m_update:"Update map",z2m_warning:"A network-map scan can take 10 seconds to 2 minutes and may temporarily reduce Zigbee responsiveness.",status_idle:"Data not loaded",status_loading:"Loading…",status_ready:"Received {time}",status_stale:"Received {time} · stale",status_partial:"Received {time} · some nodes were omitted",status_no_links:"Received {time} · no observed links found",error_permission:"Administrator permission is required.",error_unsupported:"This provider or Home Assistant API is unavailable.",error_timeout:"The provider did not respond in time.",error_invalid_topic:"Check the Zigbee2MQTT base topic.",error_invalid_payload:"The provider returned unsupported topology data.",error_provider:"Topology data could not be loaded.",remote_count:"+{n} in other spaces",route_device_not_on_plan:"device is not on the plan",route_coordinator_not_on_plan:"coordinator is not on the plan",route_other_space:"another space"};const i={en:t,ru:{title:"Связи Zigbee",toggle:"Показывать связи Zigbee при наведении на устройство",hint:"Показываются только наблюдаемые прямые соседи. Наведение ничего не запрашивает.",help:"Показывает, с какими устройствами Zigbee каждое связано напрямую. Цвет линии — качество связи (LQI) по той же шкале, что у показателя LQI устройства: красный при 40 и ниже, зелёный при 180 и выше. Пунктир — качество не сообщено. Стрелка ведёт к следующему устройству по пути к координатору: исходящая одна, входящие — те, кто ходит через это устройство. Линия без стрелки — запасной сосед. Это дерево маршрутов, которое строит House Plan, а не путь пакета в эту секунду: подпись на конце стрелки значит, что цель не на этом плане, а отсутствие стрелки — что путь неизвестен. Данные из последней загрузки и устаревают, связи видны только при работе мышью.",help_aria:"Справка: связи Zigbee",admin_only:"Данные топологии доступны только администраторам Home Assistant.",save_first:"Сохраните настройку перед загрузкой данных топологии.",zha:"ZHA",zha_read:"Прочитать данные ZHA",zha_hint:"Читает сохранённую топологию ZHA и не запускает радио-сканирование.",z2m:"Zigbee2MQTT",z2m_topics:"Базовые топики (по одному в строке)",z2m_update:"Обновить карту",z2m_warning:"Сканирование карты сети занимает от 10 секунд до 2 минут и временно может снизить отзывчивость Zigbee.",status_idle:"Данные не загружены",status_loading:"Загрузка…",status_ready:"Получено: {time}",status_stale:"Получено: {time} · данные устарели",status_partial:"Получено: {time} · часть узлов не показана",status_no_links:"Получено: {time} · наблюдаемые связи не найдены",error_permission:"Нужны права администратора.",error_unsupported:"Провайдер или API Home Assistant недоступен.",error_timeout:"Провайдер не ответил вовремя.",error_invalid_topic:"Проверьте базовый топик Zigbee2MQTT.",error_invalid_payload:"Провайдер вернул неподдерживаемые данные топологии.",error_provider:"Не удалось загрузить данные топологии.",remote_count:"+{n} в других пространствах",route_device_not_on_plan:"устройства нет на плане",route_coordinator_not_on_plan:"координатора нет на плане",route_other_space:"другое пространство"},de:{title:"Zigbee-Verbindungen",toggle:"Zigbee-Verbindungen beim Darüberfahren über ein Gerät anzeigen",hint:"Es werden nur beobachtete direkte Nachbarn angezeigt. Beim Darüberfahren werden keine Daten abgerufen.",help:"Zeigt, mit welchen Zigbee-Geräten jedes Gerät direkt verbunden ist. Die Linienfarbe ist die Verbindungsqualität (LQI) auf derselben Skala wie der LQI-Wert des Geräts: rot bei 40 und darunter, grün bei 180 und darüber. Eine gestrichelte Linie bedeutet, dass die Qualität nicht gemeldet wurde. Ein Pfeil zeigt auf das nächste Gerät auf dem Weg zum Koordinator: ein Pfeil führt hinaus, eingehende Pfeile sind die Geräte, die über dieses Gerät routen. Eine Linie ohne Pfeil ist ein Ersatznachbar. Das ist der Routenbaum, den House Plan bildet, nicht der Weg eines Pakets in diesem Moment: eine Beschriftung am Pfeilende bedeutet, dass das Ziel nicht auf diesem Plan liegt, und ein fehlender Pfeil, dass die Route unbekannt ist. Die Daten stammen aus dem letzten Laden und veralten; Verbindungen sind nur mit der Maus sichtbar.",help_aria:"Hilfe: Zigbee-Verbindungen",admin_only:"Topologiedaten sind nur für Home-Assistant-Administratoren verfügbar.",save_first:"Speichere diese Einstellung, bevor Topologiedaten geladen werden.",zha:"ZHA",zha_read:"ZHA-Daten lesen",zha_hint:"Liest den ZHA-Topologiecache; es wird kein Funkscan gestartet.",z2m:"Zigbee2MQTT",z2m_topics:"Basistopics (eines pro Zeile)",z2m_update:"Karte aktualisieren",z2m_warning:"Ein Netzwerkscan kann 10 Sekunden bis 2 Minuten dauern und Zigbee vorübergehend verlangsamen.",status_idle:"Daten nicht geladen",status_loading:"Wird geladen…",status_ready:"Empfangen: {time}",status_stale:"Empfangen: {time} · veraltet",status_partial:"Empfangen: {time} · einige Knoten fehlen",status_no_links:"Empfangen: {time} · keine beobachteten Verbindungen gefunden",error_permission:"Administratorrechte sind erforderlich.",error_unsupported:"Dieser Anbieter oder die Home-Assistant-API ist nicht verfügbar.",error_timeout:"Der Anbieter hat nicht rechtzeitig geantwortet.",error_invalid_topic:"Prüfe das Zigbee2MQTT-Basistopic.",error_invalid_payload:"Der Anbieter hat nicht unterstützte Topologiedaten geliefert.",error_provider:"Topologiedaten konnten nicht geladen werden.",remote_count:"+{n} in anderen Bereichen",route_device_not_on_plan:"Gerät ist nicht im Plan",route_coordinator_not_on_plan:"Koordinator ist nicht im Plan",route_other_space:"anderer Bereich"},fr:{title:"Liens Zigbee",toggle:"Afficher les liens Zigbee au survol d’un appareil",hint:"Seuls les voisins directs observés sont affichés. Le survol ne lance aucune requête.",help:"Montre avec quels appareils Zigbee chaque appareil communique directement. La couleur de la ligne est la qualité du lien (LQI) sur la même échelle que l'indicateur LQI de l'appareil : rouge à 40 et en dessous, vert à 180 et au-dessus. Une ligne pointillée signifie que la qualité n'a pas été communiquée. Une flèche pointe vers l'appareil suivant sur le chemin du coordinateur : une flèche part, les flèches entrantes sont les appareils qui passent par celui-ci. Une ligne sans flèche est un voisin de secours. C'est l'arbre de routes que construit House Plan, pas le trajet d'un paquet à cet instant : une étiquette au bout d'une flèche signifie que sa cible n'est pas sur ce plan, et l'absence de flèche que la route est inconnue. Les données proviennent du dernier chargement et vieillissent ; les liens ne sont visibles qu'à la souris.",help_aria:"Aide : liens Zigbee",admin_only:"Les données de topologie sont réservées aux administrateurs Home Assistant.",save_first:"Enregistrez ce réglage avant de charger les données de topologie.",zha:"ZHA",zha_read:"Lire les données ZHA",zha_hint:"Lit la topologie en cache de ZHA sans lancer d’analyse radio.",z2m:"Zigbee2MQTT",z2m_topics:"Topics de base (un par ligne)",z2m_update:"Actualiser la carte",z2m_warning:"L’analyse de la carte réseau peut durer de 10 secondes à 2 minutes et réduire temporairement la réactivité de Zigbee.",status_idle:"Données non chargées",status_loading:"Chargement…",status_ready:"Reçu : {time}",status_stale:"Reçu : {time} · obsolète",status_partial:"Reçu : {time} · certains nœuds sont omis",status_no_links:"Reçu : {time} · aucun lien observé trouvé",error_permission:"Les droits administrateur sont requis.",error_unsupported:"Ce fournisseur ou l’API Home Assistant n’est pas disponible.",error_timeout:"Le fournisseur n’a pas répondu à temps.",error_invalid_topic:"Vérifiez le topic de base Zigbee2MQTT.",error_invalid_payload:"Le fournisseur a renvoyé des données de topologie non prises en charge.",error_provider:"Impossible de charger les données de topologie.",remote_count:"+{n} dans d’autres espaces",route_device_not_on_plan:"appareil absent du plan",route_coordinator_not_on_plan:"coordinateur absent du plan",route_other_space:"autre espace"}};function r(e,n){const r=i[e]?.[n]??t[n];return"string"==typeof r&&r.trim().length>0}function o(n,r,o){return e(i[n]?.[r]??t[r]??r,o)}const s=3e5,a=2097152,d=6e3;function l(e){return null!==e&&"object"==typeof e?e:null}function u(e){if("string"!=typeof e&&"number"!=typeof e)return null;let n=String(e).trim().toLowerCase();return n=/^0x[0-9a-f]{16}$/.test(n)?n.slice(2):n.replace(/[:-]/g,""),/^[0-9a-f]{16}$/.test(n)?n:null}function c(e,n,t){return`${e}:${n}:${t}`}function p(e){const n=String(e||"").toLowerCase().replace(/[ _-]/g,"");return n.includes("coordinator")?"coordinator":n.includes("router")?"router":n.includes("enddevice")||"end"===n?"end":"unknown"}const h=["parent","child","sibling","none","previous_child"];function g(e){const n=l(e),t=function(e){const n=Number(e);return Number.isFinite(n)&&n>=0&&n<=255?Math.round(n):void 0}(n?.lqi??n?.linkquality??n?.link_quality),i=function(e){if("number"==typeof e)return h[e];if("string"!=typeof e)return;const n=e.trim().toLowerCase().replace(/[\s_-]+/g,"");return"previouschild"===n?"previous_child":n.slice(0,40)||void 0}(n?.relationship);return{...void 0===t?{}:{lqi:t},...i?{relationship:i}:{}}}function f(e,n){return Array.isArray(e)&&e.length<=n?e:null}function _(e){if("string"==typeof e)return e.length<=a;try{return JSON.stringify(e).length<=a}catch{return!1}}function m(e,n,t,i,r){if(t===i)return void n.push({code:"self_link",nodeKey:t});const o=t=d){t.push({code:"invalid_payload"});break}const n=l(e),i=u(n?.ieee??n?.ieee_address);if(!i){t.push({code:"invalid_payload",nodeKey:s});continue}const a=c("zha","zha",i);r.has(a)||r.set(a,{key:a,ieee:i,role:p(n?.device_type)}),m(o,t,s,a,e)}else null!=n?.neighbors&&t.push({code:"invalid_payload",nodeKey:s})}return{provider:"zha",instanceId:"zha",obtainedAt:n,freshness:"provider-cache",nodes:[...r.values()],links:[...o.values()],warnings:t}}function v(e,n){const t=l(e),i=u(t?.ieeeAddr??t?.ieee_address??t?.ieee??e);if(i)return i;for(const i of[t?.id,t?.networkAddress,t?.network_address,e])if(null!=i){const e=n.get(String(i));if(e)return e}return null}function y(e,t,i=Date.now()){const r=[],o=n(t)||"invalid",s=_(e)?function(e){let n=e;if("string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}const t=l(n),i=l(t?.data);if(n=i?.value??t?.value??t?.data??n,"string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}return n}(e):null,h=l(s),g=f(h?.nodes,1e3),b=f(h?.links,d);if(!g||!b)return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[],links:[],warnings:[{code:"invalid_payload"}]};const y=new Map,k=new Map;for(const e of g){const n=l(e),t=u(n?.ieeeAddr??n?.ieee_address??n?.ieee);if(!t){r.push({code:"invalid_payload"});continue}const i=c("z2m",o,t);y.set(i,{key:i,ieee:t,role:p(n?.type??n?.device_type),..."boolean"==typeof n?.failed?{available:!n.failed}:{}});for(const e of[n?.id,n?.networkAddress,n?.network_address])null!=e&&k.set(String(e),t)}const w=new Map;for(const e of b){const n=l(e),t=u(n?.sourceIeeeAddr)??v(n?.source,k),i=u(n?.targetIeeeAddr)??v(n?.target,k);if(!t||!i){r.push({code:"invalid_payload"});continue}const s=c("z2m",o,t),a=c("z2m",o,i);y.has(s)||y.set(s,{key:s,ieee:t,role:"unknown"}),y.has(a)||y.set(a,{key:a,ieee:i,role:"unknown"}),m(w,r,s,a,e)}return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[...y.values()],links:[...w.values()],warnings:r}}function k(e){if("string"!=typeof e)return null;const n=u(e);if(n)return n;const t=e.toLowerCase().match(/^zigbee2mqtt(?:_bridge)?_(.+)$/);return t?u(t[1]):null}function w(e,n){if(e.deviceId&&n.devices[e.deviceId])return[e.deviceId];const t=new Set;for(const[i,r]of Object.entries(n.devices)){const n=l(r);(Array.isArray(n?.identifiers)?n.identifiers:[]).some(n=>Array.isArray(n)&&k(n[1])===e.ieee)&&t.add(i)}if(t.size)return[...t];for(const i of Object.values(n.entities)){const n=l(i);"string"==typeof n?.device_id&&"string"==typeof n.unique_id&&(k(n.unique_id)===e.ieee&&t.add(n.device_id))}return[...t]}function z(e){return!e.hidden&&!e.virtual&&"ha_disabled"!==e.bindingStatus?.kind&&"orphaned"!==e.bindingStatus?.kind&&"unverified"!==e.bindingStatus?.kind}function A(e){const n=new Map,t=new Map,i=e.nodes.filter(e=>"coordinator"===e.role).map(e=>e.key).sort();if(1!==i.length)return{distances:n,parents:t};const r=i[0],o=function(e){const n=new Set(e.nodes.map(e=>e.key)),t=new Map;for(const e of[...n].sort())t.set(e,[]);for(const i of[...e.links].sort((e,n)=>`${e.a}\0${e.b}`.localeCompare(`${n.a}\0${n.b}`)))n.has(i.a)&&n.has(i.b)&&(t.get(i.a).push({neighborKey:i.b,observation:i.aToB}),t.get(i.b).push({neighborKey:i.a,observation:i.bToA}));for(const e of t.values())e.sort((e,n)=>e.neighborKey.localeCompare(n.neighborKey));return t}(e);if(!o.has(r))return{distances:n,parents:t};n.set(r,0);const s=[r];for(let e=0;en.get(e)===i-1).sort((e,n)=>{const t="parent"===e.observation?.relationship?1:0,i="parent"===n.observation?.relationship?1:0;if(t!==i)return i-t;const r=e.observation?.lqi??-1;return(n.observation?.lqi??-1)-r||e.neighborKey.localeCompare(n.neighborKey)});r[0]&&t.set(e,r[0].neighborKey)}return{coordinatorKey:r,distances:n,parents:t}}function Z(e,n,t){const i=new Map,r=[];for(const o of e.nodes){if(!1===o.available){r.push({code:"provider_scan_failure",nodeKey:o.key});continue}const e=w(o,t);if(1!==e.length){r.push({code:"unmatched_device",nodeKey:o.key});continue}const s=e[0];let a=n.filter(e=>z(e)&&"device"===e.bindingKind&&e.bindingRef===s);a.length||(a=n.filter(e=>z(e)&&"entity"===e.bindingKind&&!!e.bindingRef&&t.entities[e.bindingRef]?.device_id===s)),1===a.length?i.set(o.key,{markerId:a[0].id,space:a[0].space}):r.push({code:a.length>1?"ambiguous_placement":"unmatched_device",nodeKey:o.key})}return{placements:i,warnings:r}}function T(e,n,t){return e.map(e=>({topology:e,placements:Z(e,n,t).placements,routes:A(e)}))}function q(e,n,t){const i=new Map,r=new Set,o=new Map;let s=0;for(const{topology:a,placements:d,routes:l}of e){const e=new Set([...d].filter(([,e])=>e.markerId===t&&e.space===n).map(([e])=>e));if(e.size){for(const t of e){const e=l.parents.get(t);if(!e)continue;const i=d.get(e);if(i?.space===n)continue;let r;r=i?{kind:"remote-space",spaceId:i.space}:"coordinator"===a.nodes.find(n=>n.key===e)?.role?{kind:"unplaced-coordinator"}:{kind:"unplaced-device"};const s="remote-space"===r.kind?`${r.kind}:${r.spaceId}`:r.kind;o.set(s,r)}for(const o of a.links){const a=e.has(o.a),u=e.has(o.b);if(!a&&!u)continue;const c=a?o.a:o.b,p=a?o.b:o.a,h=d.get(p);if(!h||h.markerId===t){s++;continue}const g=l.parents.get(c)===p;if(h.space!==n){g||r.add(h.markerId);continue}const f=a?o.aToB:o.bToA,_=g?"toward-neighbor":l.parents.get(p)===c?"toward-origin":void 0,m=i.get(h.markerId);m?(void 0===m.line.lqi&&void 0!==f?.lqi&&(m.line.lqi=f.lqi),_&&m.directions.add(_)):i.set(h.markerId,{line:{neighborMarkerId:h.markerId,lqi:f?.lqi},directions:new Set(_?[_]:[])})}}}return{lines:[...i.values()].map(({line:e,directions:n})=>1===n.size?{...e,routeDirection:[...n][0]}:e),remoteCount:r.size,omittedCount:s,parentTargets:[...o.values()]}}export{s as T,T as a,y as b,r as h,Z as m,b as n,q as r,o as t}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{s as e,F as n}from"./houseplan-card-Di_izZTU.js";var t={title:"Zigbee links",toggle:"Show Zigbee links when hovering over a device",hint:"Shows observed direct neighbours only. Nothing is fetched while you hover.",help:"Shows which Zigbee devices each device talks to directly. Line colour is link quality (LQI) on the same scale as the device's LQI reading: red at 40 and below, green at 180 and above. A dashed line means quality was not reported. An arrow points to the next device on the way to the coordinator: one arrow leads out, incoming arrows are the devices that route through this one. A line without an arrow is a spare neighbour. This is the route tree House Plan builds, not the path a packet takes right now: a label at the end of an arrow means its target is not on this plan, and no arrow at all means the route is unknown. Data comes from the last load and goes stale; links are shown with a mouse only.",help_aria:"Help: Zigbee links",admin_only:"Topology data is available to Home Assistant administrators only.",save_first:"Save this setting before loading topology data.",zha:"ZHA",zha_read:"Read ZHA data",zha_hint:"Reads ZHA's cached topology; it does not start a radio scan.",z2m:"Zigbee2MQTT",z2m_topics:"Base topics (one per line)",z2m_update:"Update map",z2m_warning:"A network-map scan can take 10 seconds to 2 minutes and may temporarily reduce Zigbee responsiveness.",status_idle:"Data not loaded",status_loading:"Loading…",status_ready:"Received {time}",status_stale:"Received {time} · stale",status_partial:"Received {time} · some nodes were omitted",status_no_links:"Received {time} · no observed links found",error_permission:"Administrator permission is required.",error_unsupported:"This provider or Home Assistant API is unavailable.",error_timeout:"The provider did not respond in time.",error_invalid_topic:"Check the Zigbee2MQTT base topic.",error_invalid_payload:"The provider returned unsupported topology data.",error_provider:"Topology data could not be loaded.",remote_count:"+{n} in other spaces",route_device_not_on_plan:"device is not on the plan",route_coordinator_not_on_plan:"coordinator is not on the plan",route_other_space:"another space"};const i={en:t,ru:{title:"Связи Zigbee",toggle:"Показывать связи Zigbee при наведении на устройство",hint:"Показываются только наблюдаемые прямые соседи. Наведение ничего не запрашивает.",help:"Показывает, с какими устройствами Zigbee каждое связано напрямую. Цвет линии — качество связи (LQI) по той же шкале, что у показателя LQI устройства: красный при 40 и ниже, зелёный при 180 и выше. Пунктир — качество не сообщено. Стрелка ведёт к следующему устройству по пути к координатору: исходящая одна, входящие — те, кто ходит через это устройство. Линия без стрелки — запасной сосед. Это дерево маршрутов, которое строит House Plan, а не путь пакета в эту секунду: подпись на конце стрелки значит, что цель не на этом плане, а отсутствие стрелки — что путь неизвестен. Данные из последней загрузки и устаревают, связи видны только при работе мышью.",help_aria:"Справка: связи Zigbee",admin_only:"Данные топологии доступны только администраторам Home Assistant.",save_first:"Сохраните настройку перед загрузкой данных топологии.",zha:"ZHA",zha_read:"Прочитать данные ZHA",zha_hint:"Читает сохранённую топологию ZHA и не запускает радио-сканирование.",z2m:"Zigbee2MQTT",z2m_topics:"Базовые топики (по одному в строке)",z2m_update:"Обновить карту",z2m_warning:"Сканирование карты сети занимает от 10 секунд до 2 минут и временно может снизить отзывчивость Zigbee.",status_idle:"Данные не загружены",status_loading:"Загрузка…",status_ready:"Получено: {time}",status_stale:"Получено: {time} · данные устарели",status_partial:"Получено: {time} · часть узлов не показана",status_no_links:"Получено: {time} · наблюдаемые связи не найдены",error_permission:"Нужны права администратора.",error_unsupported:"Провайдер или API Home Assistant недоступен.",error_timeout:"Провайдер не ответил вовремя.",error_invalid_topic:"Проверьте базовый топик Zigbee2MQTT.",error_invalid_payload:"Провайдер вернул неподдерживаемые данные топологии.",error_provider:"Не удалось загрузить данные топологии.",remote_count:"+{n} в других пространствах",route_device_not_on_plan:"устройства нет на плане",route_coordinator_not_on_plan:"координатора нет на плане",route_other_space:"другое пространство"},de:{title:"Zigbee-Verbindungen",toggle:"Zigbee-Verbindungen beim Darüberfahren über ein Gerät anzeigen",hint:"Es werden nur beobachtete direkte Nachbarn angezeigt. Beim Darüberfahren werden keine Daten abgerufen.",help:"Zeigt, mit welchen Zigbee-Geräten jedes Gerät direkt verbunden ist. Die Linienfarbe ist die Verbindungsqualität (LQI) auf derselben Skala wie der LQI-Wert des Geräts: rot bei 40 und darunter, grün bei 180 und darüber. Eine gestrichelte Linie bedeutet, dass die Qualität nicht gemeldet wurde. Ein Pfeil zeigt auf das nächste Gerät auf dem Weg zum Koordinator: ein Pfeil führt hinaus, eingehende Pfeile sind die Geräte, die über dieses Gerät routen. Eine Linie ohne Pfeil ist ein Ersatznachbar. Das ist der Routenbaum, den House Plan bildet, nicht der Weg eines Pakets in diesem Moment: eine Beschriftung am Pfeilende bedeutet, dass das Ziel nicht auf diesem Plan liegt, und ein fehlender Pfeil, dass die Route unbekannt ist. Die Daten stammen aus dem letzten Laden und veralten; Verbindungen sind nur mit der Maus sichtbar.",help_aria:"Hilfe: Zigbee-Verbindungen",admin_only:"Topologiedaten sind nur für Home-Assistant-Administratoren verfügbar.",save_first:"Speichere diese Einstellung, bevor Topologiedaten geladen werden.",zha:"ZHA",zha_read:"ZHA-Daten lesen",zha_hint:"Liest den ZHA-Topologiecache; es wird kein Funkscan gestartet.",z2m:"Zigbee2MQTT",z2m_topics:"Basistopics (eines pro Zeile)",z2m_update:"Karte aktualisieren",z2m_warning:"Ein Netzwerkscan kann 10 Sekunden bis 2 Minuten dauern und Zigbee vorübergehend verlangsamen.",status_idle:"Daten nicht geladen",status_loading:"Wird geladen…",status_ready:"Empfangen: {time}",status_stale:"Empfangen: {time} · veraltet",status_partial:"Empfangen: {time} · einige Knoten fehlen",status_no_links:"Empfangen: {time} · keine beobachteten Verbindungen gefunden",error_permission:"Administratorrechte sind erforderlich.",error_unsupported:"Dieser Anbieter oder die Home-Assistant-API ist nicht verfügbar.",error_timeout:"Der Anbieter hat nicht rechtzeitig geantwortet.",error_invalid_topic:"Prüfe das Zigbee2MQTT-Basistopic.",error_invalid_payload:"Der Anbieter hat nicht unterstützte Topologiedaten geliefert.",error_provider:"Topologiedaten konnten nicht geladen werden.",remote_count:"+{n} in anderen Bereichen",route_device_not_on_plan:"Gerät ist nicht im Plan",route_coordinator_not_on_plan:"Koordinator ist nicht im Plan",route_other_space:"anderer Bereich"},fr:{title:"Liens Zigbee",toggle:"Afficher les liens Zigbee au survol d’un appareil",hint:"Seuls les voisins directs observés sont affichés. Le survol ne lance aucune requête.",help:"Montre avec quels appareils Zigbee chaque appareil communique directement. La couleur de la ligne est la qualité du lien (LQI) sur la même échelle que l'indicateur LQI de l'appareil : rouge à 40 et en dessous, vert à 180 et au-dessus. Une ligne pointillée signifie que la qualité n'a pas été communiquée. Une flèche pointe vers l'appareil suivant sur le chemin du coordinateur : une flèche part, les flèches entrantes sont les appareils qui passent par celui-ci. Une ligne sans flèche est un voisin de secours. C'est l'arbre de routes que construit House Plan, pas le trajet d'un paquet à cet instant : une étiquette au bout d'une flèche signifie que sa cible n'est pas sur ce plan, et l'absence de flèche que la route est inconnue. Les données proviennent du dernier chargement et vieillissent ; les liens ne sont visibles qu'à la souris.",help_aria:"Aide : liens Zigbee",admin_only:"Les données de topologie sont réservées aux administrateurs Home Assistant.",save_first:"Enregistrez ce réglage avant de charger les données de topologie.",zha:"ZHA",zha_read:"Lire les données ZHA",zha_hint:"Lit la topologie en cache de ZHA sans lancer d’analyse radio.",z2m:"Zigbee2MQTT",z2m_topics:"Topics de base (un par ligne)",z2m_update:"Actualiser la carte",z2m_warning:"L’analyse de la carte réseau peut durer de 10 secondes à 2 minutes et réduire temporairement la réactivité de Zigbee.",status_idle:"Données non chargées",status_loading:"Chargement…",status_ready:"Reçu : {time}",status_stale:"Reçu : {time} · obsolète",status_partial:"Reçu : {time} · certains nœuds sont omis",status_no_links:"Reçu : {time} · aucun lien observé trouvé",error_permission:"Les droits administrateur sont requis.",error_unsupported:"Ce fournisseur ou l’API Home Assistant n’est pas disponible.",error_timeout:"Le fournisseur n’a pas répondu à temps.",error_invalid_topic:"Vérifiez le topic de base Zigbee2MQTT.",error_invalid_payload:"Le fournisseur a renvoyé des données de topologie non prises en charge.",error_provider:"Impossible de charger les données de topologie.",remote_count:"+{n} dans d’autres espaces",route_device_not_on_plan:"appareil absent du plan",route_coordinator_not_on_plan:"coordinateur absent du plan",route_other_space:"autre espace"}};function r(e,n){const r=i[e]?.[n]??t[n];return"string"==typeof r&&r.trim().length>0}function o(n,r,o){return e(i[n]?.[r]??t[r]??r,o)}const s=3e5,a=2097152,d=6e3;function l(e){return null!==e&&"object"==typeof e?e:null}function u(e){if("string"!=typeof e&&"number"!=typeof e)return null;let n=String(e).trim().toLowerCase();return n=/^0x[0-9a-f]{16}$/.test(n)?n.slice(2):n.replace(/[:-]/g,""),/^[0-9a-f]{16}$/.test(n)?n:null}function c(e,n,t){return`${e}:${n}:${t}`}function p(e){const n=String(e||"").toLowerCase().replace(/[ _-]/g,"");return n.includes("coordinator")?"coordinator":n.includes("router")?"router":n.includes("enddevice")||"end"===n?"end":"unknown"}const h=["parent","child","sibling","none","previous_child"];function g(e){const n=l(e),t=function(e){const n=Number(e);return Number.isFinite(n)&&n>=0&&n<=255?Math.round(n):void 0}(n?.lqi??n?.linkquality??n?.link_quality),i=function(e){if("number"==typeof e)return h[e];if("string"!=typeof e)return;const n=e.trim().toLowerCase().replace(/[\s_-]+/g,"");return"previouschild"===n?"previous_child":n.slice(0,40)||void 0}(n?.relationship);return{...void 0===t?{}:{lqi:t},...i?{relationship:i}:{}}}function f(e,n){return Array.isArray(e)&&e.length<=n?e:null}function _(e){if("string"==typeof e)return e.length<=a;try{return JSON.stringify(e).length<=a}catch{return!1}}function b(e,n,t,i,r){if(t===i)return void n.push({code:"self_link",nodeKey:t});const o=t=d){t.push({code:"invalid_payload"});break}const n=l(e),i=u(n?.ieee??n?.ieee_address);if(!i){t.push({code:"invalid_payload",nodeKey:s});continue}const a=c("zha","zha",i);r.has(a)||r.set(a,{key:a,ieee:i,role:p(n?.device_type)}),b(o,t,s,a,e)}else null!=n?.neighbors&&t.push({code:"invalid_payload",nodeKey:s})}return{provider:"zha",instanceId:"zha",obtainedAt:n,freshness:"provider-cache",nodes:[...r.values()],links:[...o.values()],warnings:t}}function v(e,n){const t=l(e),i=u(t?.ieeeAddr??t?.ieee_address??t?.ieee??e);if(i)return i;for(const i of[t?.id,t?.networkAddress,t?.network_address,e])if(null!=i){const e=n.get(String(i));if(e)return e}return null}function y(e,t,i=Date.now()){const r=[],o=n(t)||"invalid",s=_(e)?function(e){let n=e;if("string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}const t=l(n),i=l(t?.data);if(n=i?.value??t?.value??t?.data??n,"string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}return n}(e):null,h=l(s),g=f(h?.nodes,1e3),m=f(h?.links,d);if(!g||!m)return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[],links:[],warnings:[{code:"invalid_payload"}]};const y=new Map,k=new Map;for(const e of g){const n=l(e),t=u(n?.ieeeAddr??n?.ieee_address??n?.ieee);if(!t){r.push({code:"invalid_payload"});continue}const i=c("z2m",o,t);y.set(i,{key:i,ieee:t,role:p(n?.type??n?.device_type),..."boolean"==typeof n?.failed?{available:!n.failed}:{}});for(const e of[n?.id,n?.networkAddress,n?.network_address])null!=e&&k.set(String(e),t)}const w=new Map;for(const e of m){const n=l(e),t=u(n?.sourceIeeeAddr)??v(n?.source,k),i=u(n?.targetIeeeAddr)??v(n?.target,k);if(!t||!i){r.push({code:"invalid_payload"});continue}const s=c("z2m",o,t),a=c("z2m",o,i);y.has(s)||y.set(s,{key:s,ieee:t,role:"unknown"}),y.has(a)||y.set(a,{key:a,ieee:i,role:"unknown"}),b(w,r,s,a,e)}return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[...y.values()],links:[...w.values()],warnings:r}}function k(e){if("string"!=typeof e)return null;const n=u(e);if(n)return n;const t=e.toLowerCase().match(/^zigbee2mqtt(?:_bridge)?_(.+)$/);return t?u(t[1]):null}function w(e,n){if(e.deviceId&&n.devices[e.deviceId])return[e.deviceId];const t=new Set;for(const[i,r]of Object.entries(n.devices)){const n=l(r);(Array.isArray(n?.identifiers)?n.identifiers:[]).some(n=>Array.isArray(n)&&k(n[1])===e.ieee)&&t.add(i)}if(t.size)return[...t];for(const i of Object.values(n.entities)){const n=l(i);"string"==typeof n?.device_id&&"string"==typeof n.unique_id&&(k(n.unique_id)===e.ieee&&t.add(n.device_id))}return[...t]}function z(e){return!e.hidden&&!e.virtual&&"ha_disabled"!==e.bindingStatus?.kind&&"orphaned"!==e.bindingStatus?.kind&&"unverified"!==e.bindingStatus?.kind}function A(e){const n=new Map,t=new Map,i=e.nodes.filter(e=>"coordinator"===e.role).map(e=>e.key).sort();if(1!==i.length)return{distances:n,parents:t};const r=i[0],o=function(e){const n=new Set(e.nodes.map(e=>e.key)),t=new Map;for(const e of[...n].sort())t.set(e,[]);for(const i of[...e.links].sort((e,n)=>`${e.a}\0${e.b}`.localeCompare(`${n.a}\0${n.b}`)))n.has(i.a)&&n.has(i.b)&&(t.get(i.a).push({neighborKey:i.b,observation:i.aToB}),t.get(i.b).push({neighborKey:i.a,observation:i.bToA}));for(const e of t.values())e.sort((e,n)=>e.neighborKey.localeCompare(n.neighborKey));return t}(e);if(!o.has(r))return{distances:n,parents:t};n.set(r,0);const s=[r];for(let e=0;en.get(e)===i-1).sort((e,n)=>{const t="parent"===e.observation?.relationship?1:0,i="parent"===n.observation?.relationship?1:0;if(t!==i)return i-t;const r=e.observation?.lqi??-1;return(n.observation?.lqi??-1)-r||e.neighborKey.localeCompare(n.neighborKey)});r[0]&&t.set(e,r[0].neighborKey)}return{coordinatorKey:r,distances:n,parents:t}}function Z(e,n,t){const i=new Map,r=[];for(const o of e.nodes){if(!1===o.available){r.push({code:"provider_scan_failure",nodeKey:o.key});continue}const e=w(o,t);if(1!==e.length){r.push({code:"unmatched_device",nodeKey:o.key});continue}const s=e[0];let a=n.filter(e=>z(e)&&"device"===e.bindingKind&&e.bindingRef===s);a.length||(a=n.filter(e=>z(e)&&"entity"===e.bindingKind&&!!e.bindingRef&&t.entities[e.bindingRef]?.device_id===s)),1===a.length?i.set(o.key,{markerId:a[0].id,space:a[0].space}):r.push({code:a.length>1?"ambiguous_placement":"unmatched_device",nodeKey:o.key})}return{placements:i,warnings:r}}function T(e,n,t){return e.map(e=>({topology:e,placements:Z(e,n,t).placements,routes:A(e)}))}function q(e,n,t){const i=new Map,r=new Set,o=new Map;let s=0;for(const{topology:a,placements:d,routes:l}of e){const e=new Set([...d].filter(([,e])=>e.markerId===t&&e.space===n).map(([e])=>e));if(e.size){for(const t of e){const e=l.parents.get(t);if(!e)continue;const i=d.get(e);if(i?.space===n)continue;let r;r=i?{kind:"remote-space",spaceId:i.space}:"coordinator"===a.nodes.find(n=>n.key===e)?.role?{kind:"unplaced-coordinator"}:{kind:"unplaced-device"};const s="remote-space"===r.kind?`${r.kind}:${r.spaceId}`:r.kind;o.set(s,r)}for(const o of a.links){const a=e.has(o.a),u=e.has(o.b);if(!a&&!u)continue;const c=a?o.a:o.b,p=a?o.b:o.a,h=d.get(p);if(!h||h.markerId===t){s++;continue}const g=l.parents.get(c)===p;if(h.space!==n){g||r.add(h.markerId);continue}const f=a?o.aToB:o.bToA,_=g?"toward-neighbor":l.parents.get(p)===c?"toward-origin":void 0,b=i.get(h.markerId);b?(void 0===b.line.lqi&&void 0!==f?.lqi&&(b.line.lqi=f.lqi),_&&b.directions.add(_)):i.set(h.markerId,{line:{neighborMarkerId:h.markerId,lqi:f?.lqi},directions:new Set(_?[_]:[])})}}}return{lines:[...i.values()].map(({line:e,directions:n})=>1===n.size?{...e,routeDirection:[...n][0]}:e),remoteCount:r.size,omittedCount:s,parentTargets:[...o.values()]}}export{s as T,T as a,y as b,r as h,Z as m,m as n,q as r,o as t}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js b/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js similarity index 93% rename from custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js rename to custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js index 2c569cdb..8eadc5bd 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js +++ b/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{n as t,b as n}from"./zigbee-topology-DlU7AXvw.js";import{F as e}from"./houseplan-card-BCGpvbDT.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__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{n as t,b as n}from"./zigbee-topology-Ba2URGlk.js";import{F as e}from"./houseplan-card-Di_izZTU.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}; diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js index 7309dba8..122a7e21 100644 --- a/custom_components/houseplan/frontend/houseplan-card.js +++ b/custom_components/houseplan/frontend/houseplan-card.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";try{await import("./houseplan-assets/houseplan-card-BCGpvbDT.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__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";try{await import("./houseplan-assets/houseplan-card-Di_izZTU.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)} diff --git a/custom_components/houseplan/frontend/houseplan-panel.js b/custom_components/houseplan/frontend/houseplan-panel.js index 182b7bc1..a2188bd9 100644 --- a/custom_components/houseplan/frontend/houseplan-panel.js +++ b/custom_components/houseplan/frontend/houseplan-panel.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";try{await import("./houseplan-assets/houseplan-card-BCGpvbDT.js")}catch(e){if(!customElements.get("houseplan-panel")){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-panel",class extends HTMLElement{connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;min-height:100%;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-panel.js: the card implementation chunk is unavailable",e)}const e=["panel","hass","narrow","route"];class n extends HTMLElement{constructor(){super(),this._narrow=!1,this.attachShadow({mode:"open"}),this._adoptPreUpgradeProperties()}connectedCallback(){this._adoptPreUpgradeProperties(),this._ensureShell()}_adoptPreUpgradeProperties(){for(const n of e){if(!Object.prototype.hasOwnProperty.call(this,n))continue;const e=this[n];delete this[n],this[n]=e}}get hass(){return this._hass}set hass(e){this._hass=e,this._ensureShell(),this._card&&(this._card.hass=e),this._syncMenuLabel()}get narrow(){return this._narrow}set narrow(e){this._narrow=Boolean(e),this.toggleAttribute("narrow",this._narrow),this._card&&(this._card.narrow=this._narrow)}get route(){return this._route}set route(e){this._route=e}get panel(){return this._panel}set panel(e){this._panel=e}_ensureShell(){if(this._card||!this.shadowRoot)return;const e=document.createElement("style");e.textContent="\n :host {\n display: block;\n width: 100%;\n /* HA mounts a custom panel inside , a block with\n * safe-area padding and NO height, so a percentage here resolves to\n * auto and the stage collapses to 0 px (#488). Take the viewport\n * like HA's own iframe panels do, minus the insets HA pads with. */\n height: 100vh;\n height: calc(100dvh - var(--safe-area-inset-top, 0px) - var(--safe-area-inset-bottom, 0px));\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n color: var(--primary-text-color);\n background: var(--primary-background-color);\n }\n .page {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n overflow: hidden;\n }\n .appbar {\n box-sizing: border-box;\n min-width: 0;\n min-height: var(--header-height, 56px);\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 0 16px;\n background: var(--app-header-background-color, var(--primary-background-color));\n color: var(--app-header-text-color, var(--primary-text-color));\n border-bottom: 1px solid var(--divider-color);\n z-index: 1;\n }\n .toolbar {\n min-width: 0;\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .menu {\n box-sizing: border-box;\n width: 44px;\n height: 44px;\n min-width: 44px;\n min-height: 44px;\n margin: 0;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 50%;\n color: inherit;\n background: transparent;\n cursor: pointer;\n }\n .menu:focus-visible {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n }\n @media (hover: hover) {\n .menu:hover { background: var(--secondary-background-color); }\n }\n .menu ha-icon { --mdc-icon-size: 24px; }\n .title {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 20px;\n font-weight: 500;\n line-height: 1.2;\n }\n .title ha-icon {\n --mdc-icon-size: 24px;\n color: var(--primary-color);\n }\n .content {\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n }\n houseplan-card {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n }\n ";const n=document.createElement("div");n.className="page";const t=document.createElement("header");t.className="appbar";const a=document.createElement("div");a.className="toolbar",a.setAttribute("role","toolbar");const o=document.createElement("button");o.className="menu",o.dataset.hp="panel-menu",o.type="button",o.innerHTML='',o.addEventListener("click",()=>{o.dispatchEvent(new CustomEvent("hass-toggle-menu",{bubbles:!0,composed:!0}))}),this._menuButton=o;const i=document.createElement("div");i.className="title",i.dataset.hp="panel-title",i.setAttribute("role","heading"),i.setAttribute("aria-level","1"),i.innerHTML='House Plan',a.append(o,i),t.append(a);const r=document.createElement("main");r.className="content";const s=document.createElement("houseplan-card");s.panelHost=!0,s.narrow=this._narrow,s.setConfig({type:"custom:houseplan-card"}),void 0!==this._hass&&(s.hass=this._hass),r.append(s),n.append(t,r),this.shadowRoot.append(e,n),this._card=s,this._syncMenuLabel()}_syncMenuLabel(){if(!this._menuButton)return;const e=this._hass?.localize?.("ui.common.menu")||this._hass?.localize?.("ui.panel.lovelace.menu")||"Menu";this._menuButton.setAttribute("aria-label",e),this._menuButton.title=e}}customElements.get("houseplan-panel")||customElements.define("houseplan-panel",n);export{n as HouseplanPanel}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";try{await import("./houseplan-assets/houseplan-card-Di_izZTU.js")}catch(e){if(!customElements.get("houseplan-panel")){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-panel",class extends HTMLElement{connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;min-height:100%;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-panel.js: the card implementation chunk is unavailable",e)}const e=["panel","hass","narrow","route"];class n extends HTMLElement{constructor(){super(),this._narrow=!1,this.attachShadow({mode:"open"}),this._adoptPreUpgradeProperties()}connectedCallback(){this._adoptPreUpgradeProperties(),this._ensureShell()}_adoptPreUpgradeProperties(){for(const n of e){if(!Object.prototype.hasOwnProperty.call(this,n))continue;const e=this[n];delete this[n],this[n]=e}}get hass(){return this._hass}set hass(e){this._hass=e,this._ensureShell(),this._card&&(this._card.hass=e),this._syncMenuLabel()}get narrow(){return this._narrow}set narrow(e){this._narrow=Boolean(e),this.toggleAttribute("narrow",this._narrow),this._card&&(this._card.narrow=this._narrow)}get route(){return this._route}set route(e){this._route=e}get panel(){return this._panel}set panel(e){this._panel=e}_ensureShell(){if(this._card||!this.shadowRoot)return;const e=document.createElement("style");e.textContent="\n :host {\n display: block;\n width: 100%;\n /* HA mounts a custom panel inside , a block with\n * safe-area padding and NO height, so a percentage here resolves to\n * auto and the stage collapses to 0 px (#488). Take the viewport\n * like HA's own iframe panels do, minus the insets HA pads with. */\n height: 100vh;\n height: calc(100dvh - var(--safe-area-inset-top, 0px) - var(--safe-area-inset-bottom, 0px));\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n color: var(--primary-text-color);\n background: var(--primary-background-color);\n }\n .page {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n overflow: hidden;\n }\n .appbar {\n box-sizing: border-box;\n min-width: 0;\n min-height: var(--header-height, 56px);\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 0 16px;\n background: var(--app-header-background-color, var(--primary-background-color));\n color: var(--app-header-text-color, var(--primary-text-color));\n border-bottom: 1px solid var(--divider-color);\n z-index: 1;\n }\n .toolbar {\n min-width: 0;\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .menu {\n box-sizing: border-box;\n width: 44px;\n height: 44px;\n min-width: 44px;\n min-height: 44px;\n margin: 0;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 50%;\n color: inherit;\n background: transparent;\n cursor: pointer;\n }\n .menu:focus-visible {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n }\n @media (hover: hover) {\n .menu:hover { background: var(--secondary-background-color); }\n }\n .menu ha-icon { --mdc-icon-size: 24px; }\n .title {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 20px;\n font-weight: 500;\n line-height: 1.2;\n }\n .title ha-icon {\n --mdc-icon-size: 24px;\n color: var(--primary-color);\n }\n .content {\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n }\n houseplan-card {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n }\n ";const n=document.createElement("div");n.className="page";const t=document.createElement("header");t.className="appbar";const a=document.createElement("div");a.className="toolbar",a.setAttribute("role","toolbar");const o=document.createElement("button");o.className="menu",o.dataset.hp="panel-menu",o.type="button",o.innerHTML='',o.addEventListener("click",()=>{o.dispatchEvent(new CustomEvent("hass-toggle-menu",{bubbles:!0,composed:!0}))}),this._menuButton=o;const i=document.createElement("div");i.className="title",i.dataset.hp="panel-title",i.setAttribute("role","heading"),i.setAttribute("aria-level","1"),i.innerHTML='House Plan',a.append(o,i),t.append(a);const r=document.createElement("main");r.className="content";const s=document.createElement("houseplan-card");s.panelHost=!0,s.narrow=this._narrow,s.setConfig({type:"custom:houseplan-card"}),void 0!==this._hass&&(s.hass=this._hass),r.append(s),n.append(t,r),this.shadowRoot.append(e,n),this._card=s,this._syncMenuLabel()}_syncMenuLabel(){if(!this._menuButton)return;const e=this._hass?.localize?.("ui.common.menu")||this._hass?.localize?.("ui.panel.lovelace.menu")||"Menu";this._menuButton.setAttribute("aria-label",e),this._menuButton.title=e}}customElements.get("houseplan-panel")||customElements.define("houseplan-panel",n);export{n as HouseplanPanel}; diff --git a/custom_components/houseplan/support_package.py b/custom_components/houseplan/support_package.py index 276c3c86..3c37e2a7 100644 --- a/custom_components/houseplan/support_package.py +++ b/custom_components/houseplan/support_package.py @@ -149,6 +149,9 @@ def _global_settings(value: object) -> dict[str, Any]: out = _copy_keys(value, ("glow_radius_cm", "bg_color", "north_deg", "bg_mode", "sun_rays")) if not isinstance(value, dict): return out + sun_ray_origin = value.get("sun_ray_origin") + if sun_ray_origin in ("inner", "outer"): + out["sun_ray_origin"] = sun_ray_origin show_room_tooltip = value.get("show_room_tooltip") if isinstance(show_room_tooltip, bool): out["show_room_tooltip"] = show_room_tooltip diff --git a/custom_components/houseplan/validation.py b/custom_components/houseplan/validation.py index b1632ce1..35e66eb9 100644 --- a/custom_components/houseplan/validation.py +++ b/custom_components/houseplan/validation.py @@ -1339,6 +1339,7 @@ def _north_deg(value): _BG_MODE = vol.In(["static", "daynight"]) +_SUN_RAY_ORIGIN = vol.In(["inner", "outer"]) SPACE_DISPLAY_SCHEMA = vol.Schema( { @@ -2195,6 +2196,7 @@ CONFIG_SCHEMA = vol.All( vol.Optional("north_deg"): _north_deg, vol.Optional("bg_mode"): _BG_MODE, vol.Optional("sun_rays"): bool, + vol.Optional("sun_ray_origin"): _SUN_RAY_ORIGIN, vol.Optional("show_room_tooltip"): bool, vol.Optional("summary_panel"): SUMMARY_PANEL_WIRE_SCHEMA, vol.Optional("radar"): vol.Schema({}, extra=vol.ALLOW_EXTRA), diff --git a/demo/smoke_sun.mjs b/demo/smoke_sun.mjs index e9abe1c2..7fff6965 100644 --- a/demo/smoke_sun.mjs +++ b/demo/smoke_sun.mjs @@ -185,17 +185,48 @@ await page.mouse.move(box.cx + 45, box.cy); // on the ring, due right = 90° await page.mouse.down(); await page.mouse.move(box.cx, box.cy + 45); // drag on to due down = 180° await page.mouse.up(); -const dlg = await page.evaluate(() => { +const dlg = await page.evaluate(async () => { const c = window.__card; const sr = c.shadowRoot; + const originSelect = sr.querySelector('#gs-sun-ray-origin'); const out = { compassDragSets180: c._settingsDialog?.northDeg === 180, dialogHasModeSelect: !!sr.querySelector('hp-dialog select.areasel'), dialogHasRaysToggle: [...sr.querySelectorAll('hp-dialog .srcrow input[type=checkbox]')].length > 0, + dialogHasOriginSelect: !!originSelect, + originDefaultsInner: originSelect?.value === 'inner' && c._settingsDialog?.sunRayOrigin === 'inner', + originAvailableWhenRaysOff: false, dialogHasNoWeatherList: sr.querySelectorAll('#hp-weather-list option').length === 0, dialogNumberMatches: sr.querySelector('.suncol input[type=number]')?.value === '180', }; - c._settingsDialog = null; + c._settingsDialog = { ...c._settingsDialog, northDeg: 0, sunRays: false }; + await c.updateComplete; + out.originAvailableWhenRaysOff = !sr.querySelector('#gs-sun-ray-origin')?.disabled; + c._settingsDialog = { ...c._settingsDialog, sunRays: true }; + await c.updateComplete; + const cacheBefore = c._sunRaysCache; + const changedOrigin = sr.querySelector('#gs-sun-ray-origin'); + changedOrigin.value = 'outer'; + changedOrigin.dispatchEvent(new Event('change', { bubbles: true, composed: true })); + await c.updateComplete; + out.originPendingRekeysGeometry = c._settingsDialog?.sunRayOrigin === 'outer' + && c._sunRaysCache !== cacheBefore; + await c._saveSettingsDialog(); + await c.updateComplete; + out.originSavedOuter = c._serverCfg.settings.sun_ray_origin === 'outer'; + + c._openSettingsDialog(); + c.requestUpdate(); + await c.updateComplete; + const restored = sr.querySelector('#gs-sun-ray-origin'); + out.originRoundTripsToDialog = restored?.value === 'outer' + && c._settingsDialog?.sunRayOrigin === 'outer'; + restored.value = 'inner'; + restored.dispatchEvent(new Event('change', { bubbles: true, composed: true })); + await c.updateComplete; + await c._saveSettingsDialog(); + await c.updateComplete; + out.originSavedInner = c._serverCfg.settings.sun_ray_origin === 'inner'; return out; }); Object.assign(res, dlg); diff --git a/dist/houseplan-assets.json b/dist/houseplan-assets.json index 34562d31..a0538754 100644 --- a/dist/houseplan-assets.json +++ b/dist/houseplan-assets.json @@ -1,295 +1,295 @@ { "schema": 1, - "fingerprint": "0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e", + "fingerprint": "530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33", "entry": "houseplan-card.js", "panelEntry": "houseplan-panel.js", "initialViewFiles": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", + "houseplan-assets/houseplan-card-Di_izZTU.js", "houseplan-card.js" ], - "initialViewGzipBytes": 290379, + "initialViewGzipBytes": 290629, "initialPanelFiles": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", + "houseplan-assets/houseplan-card-Di_izZTU.js", "houseplan-panel.js" ], - "initialPanelGzipBytes": 291901, + "initialPanelGzipBytes": 292151, "initialPanelOnlyFiles": [ "houseplan-panel.js" ], - "initialPanelOnlyGzipBytes": 2325, + "initialPanelOnlyGzipBytes": 2327, "lazyFiles": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/de-JVEEGD9u.js", - "houseplan-assets/editor-C5Zq-3aA.js", - "houseplan-assets/fr-B-ete5Dh.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js", - "houseplan-assets/hp-zigbee-topology-overlay-D3IWAxB8.js", - "houseplan-assets/iso-scene-render-ceJKJKhC.js", - "houseplan-assets/live-interaction-runtime-CxW-k-p_.js", - "houseplan-assets/pdf-export-BAtsOfAV.js", - "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js", - "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/de-BRgmJptb.js", + "houseplan-assets/editor-DCXyMNgY.js", + "houseplan-assets/fr-B8hQ5YK4.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js", + "houseplan-assets/hp-zigbee-topology-overlay-_ZK20cr6.js", + "houseplan-assets/iso-scene-render-BIRwzucU.js", + "houseplan-assets/live-interaction-runtime-AJRZAUON.js", + "houseplan-assets/pdf-export-B2sbsWvc.js", + "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js", + "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js" ], - "lazyGzipBytes": 418510, + "lazyGzipBytes": 418756, "lazyEditorFiles": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/editor-C5Zq-3aA.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/editor-DCXyMNgY.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js" ], - "lazyEditorGzipBytes": 204784, + "lazyEditorGzipBytes": 204934, "lazyOnboardingFiles": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js" ], - "lazyOnboardingGzipBytes": 13914, + "lazyOnboardingGzipBytes": 13919, "lazyLocaleFiles": [ - "houseplan-assets/de-JVEEGD9u.js", - "houseplan-assets/fr-B-ete5Dh.js" + "houseplan-assets/de-BRgmJptb.js", + "houseplan-assets/fr-B8hQ5YK4.js" ], - "lazyLocaleGzipBytes": 54845, + "lazyLocaleGzipBytes": 54925, "lazyIsometricFiles": [ - "houseplan-assets/iso-scene-render-ceJKJKhC.js" + "houseplan-assets/iso-scene-render-BIRwzucU.js" ], - "lazyIsometricGzipBytes": 13232, + "lazyIsometricGzipBytes": 13236, "lazyFurnitureArtFiles": [ - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js" + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js" ], - "lazyFurnitureArtGzipBytes": 10252, + "lazyFurnitureArtGzipBytes": 10254, "lazyPdfFiles": [ - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/pdf-export-BAtsOfAV.js" + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/pdf-export-B2sbsWvc.js" ], - "lazyPdfGzipBytes": 120125, + "lazyPdfGzipBytes": 120129, "files": [ { - "path": "houseplan-assets/backdrop-pick-Caayxvt2.js", - "sha256": "3a8a8a4b522eaae770f7b0cdd5612aaa542fd81e2fef1adcb58d21d9b093b360", + "path": "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "sha256": "45a9c60eb50b3859a5a5f5330830dd5c72353b63d6f06cf8417712db248b2320", "rawBytes": 19956, - "gzipBytes": 6881, + "gzipBytes": 6880, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/de-JVEEGD9u.js", - "sha256": "f300635f221656a36e591183395cc38c77c093e2347ce98ac0b0f324f7ec8306", - "rawBytes": 91437, - "gzipBytes": 27709, + "path": "houseplan-assets/de-BRgmJptb.js", + "sha256": "0023bc3edc741291b1d463fdc3f1a24006af13ca13932e3cd37f9e761b022fe9", + "rawBytes": 91590, + "gzipBytes": 27744, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/editor-C5Zq-3aA.js", - "sha256": "4878d5efac2222fdd3fda5e695588a8d5cfe463027397b2fc8499bd6e649c6a7", + "path": "houseplan-assets/editor-DCXyMNgY.js", + "sha256": "4dba6280fe0f491e4c8a0c349e94aa7031de545fe086f9c01f3ab376db2013b7", "rawBytes": 3831, - "gzipBytes": 1583, + "gzipBytes": 1584, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/fr-B-ete5Dh.js", - "sha256": "c4d9a2f7bf0fca73861727752c5cd9b41e8cda469685e32eb34dedc8ec0f790b", - "rawBytes": 93701, - "gzipBytes": 27136, + "path": "houseplan-assets/fr-B8hQ5YK4.js", + "sha256": "5c33cb26bb68392be61510c8eb0e06ae152e0bff506f493eddaaa2c44e19aadf", + "rawBytes": 93884, + "gzipBytes": 27181, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "sha256": "69da2271017aa401f35e87387fb06d384617ee78f0d534bbd28792f5c3cb33e8", + "path": "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "sha256": "aabb06ce9a989322682a7b485a7810036f390aac547aa89bbbb03c74a7e1bde7", "rawBytes": 33655, - "gzipBytes": 10252, + "gzipBytes": 10254, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/houseplan-card-BCGpvbDT.js", - "sha256": "83f27e261a8a7a32463b67762c859e431d1468a32af7249627ec326f16696772", - "rawBytes": 1031731, - "gzipBytes": 289576, + "path": "houseplan-assets/houseplan-card-Di_izZTU.js", + "sha256": "634b25343fd2bf984b27e5a7ba7de1f24a7343b0909379bd16faa563f9499913", + "rawBytes": 1032408, + "gzipBytes": 289824, "isEntry": false, "imports": [], "dynamicImports": [ - "houseplan-assets/de-JVEEGD9u.js", - "houseplan-assets/editor-C5Zq-3aA.js", - "houseplan-assets/fr-B-ete5Dh.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js", - "houseplan-assets/hp-zigbee-topology-overlay-D3IWAxB8.js", - "houseplan-assets/iso-scene-render-ceJKJKhC.js", - "houseplan-assets/live-interaction-runtime-CxW-k-p_.js", - "houseplan-assets/pdf-export-BAtsOfAV.js", - "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js" + "houseplan-assets/de-BRgmJptb.js", + "houseplan-assets/editor-DCXyMNgY.js", + "houseplan-assets/fr-B8hQ5YK4.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js", + "houseplan-assets/hp-zigbee-topology-overlay-_ZK20cr6.js", + "houseplan-assets/iso-scene-render-BIRwzucU.js", + "houseplan-assets/live-interaction-runtime-AJRZAUON.js", + "houseplan-assets/pdf-export-B2sbsWvc.js", + "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js" ] }, { - "path": "houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js", - "sha256": "7a0814ddc88324ad5dcb87f43852bd1f92ed90e4bda658cab3a8cdfee3209c18", - "rawBytes": 669271, - "gzipBytes": 178643, + "path": "houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js", + "sha256": "f6556f260a8d8598a9f9667be241cce323d505281569ec6a5a3f01103edf9476", + "rawBytes": 669985, + "gzipBytes": 178790, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js" ], "dynamicImports": [ - "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js" + "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js" ] }, { - "path": "houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js", - "sha256": "6484dea33a514dff985b752d3f3ff87086a87ab2e46e79d29773d382d9fe4695", + "path": "houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js", + "sha256": "a8eff518545ca4ff644e03bdc2861bcd7e79b28e1ff65642f28fb7ca216711c8", "rawBytes": 28287, - "gzipBytes": 7033, + "gzipBytes": 7039, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-Caayxvt2.js", - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/backdrop-pick-CXmKHH6_.js", + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/hp-zigbee-topology-overlay-D3IWAxB8.js", - "sha256": "1dd14e9ee7bb06dd0ca154b471e16f410abc14c0beb5e310266f71514e770f9b", + "path": "houseplan-assets/hp-zigbee-topology-overlay-_ZK20cr6.js", + "sha256": "b9341d7245eca9bb514c73d2fda78b5023d9d964bddf605c7af842ac71af4451", "rawBytes": 10756, - "gzipBytes": 3685, + "gzipBytes": 3686, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js", - "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js" + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js", + "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/iso-scene-render-ceJKJKhC.js", - "sha256": "e7032d13f4479fa28d8b378c900a339577e74f5c377da9b080697e20e02f5903", + "path": "houseplan-assets/iso-scene-render-BIRwzucU.js", + "sha256": "a2b6ff57e2d3d0d275ffe392c71c1cdfac8f546c41abfe8a2c7be2911624c341", "rawBytes": 39206, - "gzipBytes": 13232, + "gzipBytes": 13236, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/live-interaction-runtime-CxW-k-p_.js", - "sha256": "3b0f3ae94e957cb662f63abeb5b7fb95012da6654a0ad5a857cf7b1b6a4cb6ac", + "path": "houseplan-assets/live-interaction-runtime-AJRZAUON.js", + "sha256": "dff5f0f1ad7a5e92226f812e4948705e55b5556c802003ac1147339ea641e775", "rawBytes": 8216, - "gzipBytes": 3209, + "gzipBytes": 3210, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/pdf-export-BAtsOfAV.js", - "sha256": "2e57254cc4a637a6ed689ee1de9af9f4dc60595489683b238ead4026f7e4d60b", + "path": "houseplan-assets/pdf-export-B2sbsWvc.js", + "sha256": "63d543a4fa25f03b26f255a4ea8c6096440fd3a0c3dc1b96e8402560fe9709b6", "rawBytes": 236244, - "gzipBytes": 109873, + "gzipBytes": 109875, "isEntry": false, "imports": [ - "houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js", - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js", + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/summary-panel-editor-BAGJ8QwD.js", - "sha256": "72d3ad8f8d61228dc255eed21ff157ad9c96ee8a35bd7b7b999f4090adb1925c", + "path": "houseplan-assets/summary-panel-editor-BDoONUEa.js", + "sha256": "caf18642431f5c391e03c7c06f1d45dbe71ffc06417c65cc24f726dff2840fd1", "rawBytes": 14824, - "gzipBytes": 3401, + "gzipBytes": 3400, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js" + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/summary-panel-metrics-CXnAEe7_.js", - "sha256": "c73f5de8717a8a7d5e7e0d0861fb9d007876b50c4c62f97b3c7f1739cd5bb38f", + "path": "houseplan-assets/summary-panel-metrics-O-xxtEs5.js", + "sha256": "e6eb617c543828e8d13193c442489da5b335be1706ac4285bf8dd6ac6861c300", "rawBytes": 2610, - "gzipBytes": 1304, + "gzipBytes": 1306, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/summary-panel-runtime-loaded-BcKBuVQ7.js", - "sha256": "8609218f07a5ec5399a2ba61707a2854dfaa65e80b11dc628ddb3ece70d77f72", + "path": "houseplan-assets/summary-panel-runtime-loaded-CNpqraog.js", + "sha256": "d436e392b8472c75e3fce9f4f61bc38d8261b34c740cf796eab2f6916d191da1", "rawBytes": 73366, - "gzipBytes": 20089, + "gzipBytes": 20088, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [ - "houseplan-assets/summary-panel-editor-BAGJ8QwD.js", - "houseplan-assets/summary-panel-metrics-CXnAEe7_.js" + "houseplan-assets/summary-panel-editor-BDoONUEa.js", + "houseplan-assets/summary-panel-metrics-O-xxtEs5.js" ] }, { - "path": "houseplan-assets/zigbee-topology-DlU7AXvw.js", - "sha256": "f7f21945cb650b57fa6469a7205aa687415b208f9649e2e8bae9dd27aa6cf4e6", + "path": "houseplan-assets/zigbee-topology-Ba2URGlk.js", + "sha256": "c22937699ac98c72b3fa9e8d94555cbaf108fcb6354ba1660c71d06504e0b0d0", "rawBytes": 18961, - "gzipBytes": 7425, + "gzipBytes": 7426, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js", - "sha256": "7ae2a9b1aac6ea4ee128341cce087684b546efd2788b97fa6941138ddb702f9f", + "path": "houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js", + "sha256": "9495447f3dfda1bbc1a4612742a0a42aeadca02949f9e5ff87e8d5b8ae18e146", "rawBytes": 3941, - "gzipBytes": 1760, + "gzipBytes": 1763, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js", - "houseplan-assets/zigbee-topology-DlU7AXvw.js" + "houseplan-assets/houseplan-card-Di_izZTU.js", + "houseplan-assets/zigbee-topology-Ba2URGlk.js" ], "dynamicImports": [] }, { "path": "houseplan-card.js", - "sha256": "642174a115a5be423b55f552e351f4445e58f744c22c4eb1378fc376ef16d65b", + "sha256": "f31ba79b59bd0c95d9696f77702c5cff2d0900b1962547c42c7e7f7f807b0e10", "rawBytes": 1205, - "gzipBytes": 803, + "gzipBytes": 805, "isEntry": true, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] }, { "path": "houseplan-panel.js", - "sha256": "8383bd59c693f7f9cc4b2aee4886b6a9fb90a715d91630e6473ce3aeae09216b", + "sha256": "174775f68968418e501fdbe42a83541d6003dbb0e58aa223d7f419936e88c8cf", "rawBytes": 6165, - "gzipBytes": 2325, + "gzipBytes": 2327, "isEntry": true, "imports": [ - "houseplan-assets/houseplan-card-BCGpvbDT.js" + "houseplan-assets/houseplan-card-Di_izZTU.js" ], "dynamicImports": [] } diff --git a/dist/houseplan-assets/backdrop-pick-Caayxvt2.js b/dist/houseplan-assets/backdrop-pick-CXmKHH6_.js similarity index 99% rename from dist/houseplan-assets/backdrop-pick-Caayxvt2.js rename to dist/houseplan-assets/backdrop-pick-CXmKHH6_.js index d7309ffa..da8a357c 100644 --- a/dist/houseplan-assets/backdrop-pick-Caayxvt2.js +++ b/dist/houseplan-assets/backdrop-pick-CXmKHH6_.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{D as e,c as t,A as i,p as o,q as n,dD as r}from"./houseplan-card-BCGpvbDT.js";function s(e){const t=e.visualViewport;return t&&Number.isFinite(t.width)&&Number.isFinite(t.height)?{left:Number(t.offsetLeft)||0,top:Number(t.offsetTop)||0,width:Math.max(0,Number(t.width)||0),height:Math.max(0,Number(t.height)||0)}:{left:0,top:0,width:e.innerWidth,height:e.innerHeight}}function a(e,t,i,o=7,n=8){const r=i.left+n,s=i.top+n,a=Math.max(r,i.left+i.width-n),l=Math.max(s,i.top+i.height-n),h=Math.max(0,a-r),c=Math.max(0,l-s),d=Math.min(Math.max(0,t.width),h),u=Math.min(Math.max(0,t.height),c);let p=e.left;p+d>a&&(p=e.right-d),p=Math.min(Math.max(r,p),Math.max(r,a-d));const g=e.bottom+o,_=e.top-o-u;let m="bottom",f=g;return g+u>l&&_>=s?(m="top",f=Math.min(Math.max(s,_),Math.max(s,l-u))):f=Math.min(Math.max(s,g),Math.max(s,l-u)),{left:Math.round(p),top:Math.round(f),side:m,maxWidth:Math.round(h),maxHeight:Math.round(c)}}class l{constructor(e,t,i){this.owner=e,this.name=t,this.keydown=i,this.host=null,this.root=null}window(){return this.owner.ownerDocument.defaultView}dialog(){return this.owner.closest("hp-dialog")}usesPopover(e=!1){const t=this.window();return!e&&!!t&&function(e){const t=e.HTMLElement?.prototype;return"function"==typeof t?.showPopover&&"function"==typeof t?.hidePopover}(t)}get hasFallback(){return!!this.host}containsPath(e){return e.includes(this.owner)||!!this.host&&e.includes(this.host)}ownsActiveElement(){let e=this.owner.ownerDocument.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return!(!e||e!==this.owner&&!this.owner.shadowRoot?.contains(e)&&!this.root?.contains(e))}renderFallback(i,o){const n=this.ensureFallback();return n?(e(t`${i}`,n),n):null}surface(e,t){return t?this.owner.shadowRoot?.querySelector(e)||null:this.root?.querySelector(e)||null}destroy(){this.root&&e(i,this.root),this.host?.remove(),this.host=null,this.root=null}ensureFallback(){if(this.root?.isConnected)return this.root;const e=this.dialog()?.overlayPortal()||this.owner.ownerDocument.body;if(!e)return null;const t=this.owner.ownerDocument.createElement("div");return t.dataset.hpOverlay=this.name,t.style.display="contents",this.keydown&&t.addEventListener("keydown",this.keydown,!0),e.append(t),this.host=t,this.root=t.attachShadow({mode:"open"}),this.root}}let h=0;class c extends n{constructor(){super(...arguments),this.text="",this.ariaLabel="",this.pointerHover=!1,this._open=!1,this._openTimer=0,this._closeTimer=0,this._positionRaf=0,this._forceFallback=!1,this._hoverOwned=!1,this._overlayDispose=null,this._scrollDialog=null,this._descriptionId="hp-help-description-"+ ++h,this._surfacePointerEnter=()=>{const e=this._window();this._closeTimer&&e?.clearTimeout(this._closeTimer),this._closeTimer=0},this._surfacePointerLeave=()=>{this._scheduleClose()},this._outsidePointerDown=e=>{if(!this._open)return;const t=e.composedPath();this._floating.containsPath(t)||this._closeHelp(!1,"outside")},this._dialogScroll=e=>{const t=this._floating.containsPath(e.composedPath()),i=e.target,o=this._dialog(),n=i instanceof Node&&(i===o||i instanceof Element&&i.contains(this));var r;this._open&&(r=n,!t&&r)&&this._closeHelp(!1,"scroll")},this._keyDown=e=>{if(!this._open||e.defaultPrevented)return;if("Escape"===e.key)return e.preventDefault(),e.stopImmediatePropagation(),void this._closeHelp(this._floating.ownsActiveElement(),"escape");const t=this.renderRoot.querySelector(".trigger");if(!t||!e.composedPath().includes(t))return;const i=this._surface();if(!i||i.scrollHeight<=i.clientHeight)return;const o=Math.max(40,.8*i.clientHeight),n={ArrowDown:40,ArrowUp:-40,PageDown:o,PageUp:-o};if("Home"===e.key)i.scrollTop=0;else if("End"===e.key)i.scrollTop=i.scrollHeight;else{if(!(e.key in n))return;i.scrollBy({top:n[e.key],behavior:"auto"})}e.preventDefault(),e.stopImmediatePropagation()},this._floating=new l(this,"help",this._keyDown),this._queuePosition=()=>{if(!this._open||this._positionRaf)return;const e=this._window();e&&(this._positionRaf=e.requestAnimationFrame(()=>{this._positionRaf=0,this._position()||this._closeHelp()}))}}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this._keyDown,!0)}willUpdate(){this.toggleAttribute("data-has-content",this._hasContent())}disconnectedCallback(){const e=this.ownerDocument.defaultView;this._unsubscribeOpenListeners(),this.removeEventListener("keydown",this._keyDown,!0),this._clearTimers(),this._positionRaf&&e?.cancelAnimationFrame(this._positionRaf),this._positionRaf=0,this._closeHelp(!1,"disconnect"),super.disconnectedCallback()}updated(e){if(e.has("pointerHover")&&!this.pointerHover){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._openTimer=0,this._hoverOwned&&this._closeHelp(!1,"outside")}this._hasContent()||!this._open?this._open&&e.has("text")&&(this._usesPopover()||this._renderFallback(),this._queuePosition()):this._closeHelp()}_window(){return this._floating.window()}_dialog(){return this._floating.dialog()}_usesPopover(){return this._floating.usesPopover(this._forceFallback)}_hasContent(){return e=this.text,t=this.ariaLabel,"string"==typeof e&&e.trim().length>0&&"string"==typeof t&&t.trim().length>0;var e,t}_clearTimers(){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._closeTimer&&e?.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=0}_scheduleOpen(){const e=this._window();this.pointerHover&&e&&!this._open&&!this._openTimer&&(this._closeTimer&&e.clearTimeout(this._closeTimer),this._closeTimer=0,this._openTimer=e.setTimeout(()=>{this._openTimer=0,this.isConnected&&(this._hoverOwned=!0,this._openHelp())},300))}_scheduleClose(){const e=this._window(),t=this.renderRoot.querySelector(".trigger");e&&!t?.matches(":focus-visible")&&(this._openTimer&&e.clearTimeout(this._openTimer),this._closeTimer&&e.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=e.setTimeout(()=>{this._closeTimer=0,this.isConnected&&this._closeHelp()},150))}_triggerPointerEnter(e){this.pointerHover&&"mouse"===e.pointerType&&this._scheduleOpen()}_triggerPointerLeave(e){"mouse"===e.pointerType&&this._scheduleClose()}_triggerFocus(){queueMicrotask(()=>{const e=this.renderRoot.querySelector(".trigger");e?.matches(":focus-visible")&&(this._hoverOwned=!1,this._openHelp())})}_triggerBlur(){this._scheduleClose()}_triggerClick(){this._open?this._closeHelp():(this._hoverOwned=!1,this._openHelp())}_subscribeOpenListeners(){this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("keydown",this._keyDown,!0);const e=this._window();e?.addEventListener("resize",this._queuePosition),e?.addEventListener("orientationchange",this._queuePosition),e?.visualViewport?.addEventListener("resize",this._queuePosition),e?.visualViewport?.addEventListener("scroll",this._queuePosition),this._scrollDialog=this._dialog(),this._scrollDialog?.addEventListener("scroll",this._dialogScroll,!0)}_unsubscribeOpenListeners(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("keydown",this._keyDown,!0);const e=this._window();e?.removeEventListener("resize",this._queuePosition),e?.removeEventListener("orientationchange",this._queuePosition),e?.visualViewport?.removeEventListener("resize",this._queuePosition),e?.visualViewport?.removeEventListener("scroll",this._queuePosition),this._scrollDialog?.removeEventListener("scroll",this._dialogScroll,!0),this._scrollDialog=null}async _openHelp(){!this._open&&this._hasContent()&&(this._clearTimers(),this._forceFallback=!1,this._open=!0,this._subscribeOpenListeners(),await this.updateComplete,this._open&&(this._usesPopover()||this._renderFallback(),this._position()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:e=>this._closeHelp("escape"===e&&this._floating.ownsActiveElement(),e)})||null:this._closeHelp()))}_closeHelp(e=!1,t="exclusive"){if(!this._open&&!this._floating.hasFallback)return;this._clearTimers();const i=this._overlayDispose;this._overlayDispose=null,i?.();const o=this.renderRoot.querySelector(".tooltip");if(o?.hidePopover)try{o.matches(":popover-open")&&o.hidePopover()}catch{}this._open=!1,this._hoverOwned=!1,this._unsubscribeOpenListeners(),this._floating.destroy(),e&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_tooltipTemplate(e){return t`
    a&&(p=e.right-d),p=Math.min(Math.max(r,p),Math.max(r,a-d));const g=e.bottom+o,_=e.top-o-u;let m="bottom",f=g;return g+u>l&&_>=s?(m="top",f=Math.min(Math.max(s,_),Math.max(s,l-u))):f=Math.min(Math.max(s,g),Math.max(s,l-u)),{left:Math.round(p),top:Math.round(f),side:m,maxWidth:Math.round(h),maxHeight:Math.round(c)}}class l{constructor(e,t,i){this.owner=e,this.name=t,this.keydown=i,this.host=null,this.root=null}window(){return this.owner.ownerDocument.defaultView}dialog(){return this.owner.closest("hp-dialog")}usesPopover(e=!1){const t=this.window();return!e&&!!t&&function(e){const t=e.HTMLElement?.prototype;return"function"==typeof t?.showPopover&&"function"==typeof t?.hidePopover}(t)}get hasFallback(){return!!this.host}containsPath(e){return e.includes(this.owner)||!!this.host&&e.includes(this.host)}ownsActiveElement(){let e=this.owner.ownerDocument.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return!(!e||e!==this.owner&&!this.owner.shadowRoot?.contains(e)&&!this.root?.contains(e))}renderFallback(i,o){const n=this.ensureFallback();return n?(e(t`${i}`,n),n):null}surface(e,t){return t?this.owner.shadowRoot?.querySelector(e)||null:this.root?.querySelector(e)||null}destroy(){this.root&&e(i,this.root),this.host?.remove(),this.host=null,this.root=null}ensureFallback(){if(this.root?.isConnected)return this.root;const e=this.dialog()?.overlayPortal()||this.owner.ownerDocument.body;if(!e)return null;const t=this.owner.ownerDocument.createElement("div");return t.dataset.hpOverlay=this.name,t.style.display="contents",this.keydown&&t.addEventListener("keydown",this.keydown,!0),e.append(t),this.host=t,this.root=t.attachShadow({mode:"open"}),this.root}}let h=0;class c extends n{constructor(){super(...arguments),this.text="",this.ariaLabel="",this.pointerHover=!1,this._open=!1,this._openTimer=0,this._closeTimer=0,this._positionRaf=0,this._forceFallback=!1,this._hoverOwned=!1,this._overlayDispose=null,this._scrollDialog=null,this._descriptionId="hp-help-description-"+ ++h,this._surfacePointerEnter=()=>{const e=this._window();this._closeTimer&&e?.clearTimeout(this._closeTimer),this._closeTimer=0},this._surfacePointerLeave=()=>{this._scheduleClose()},this._outsidePointerDown=e=>{if(!this._open)return;const t=e.composedPath();this._floating.containsPath(t)||this._closeHelp(!1,"outside")},this._dialogScroll=e=>{const t=this._floating.containsPath(e.composedPath()),i=e.target,o=this._dialog(),n=i instanceof Node&&(i===o||i instanceof Element&&i.contains(this));var r;this._open&&(r=n,!t&&r)&&this._closeHelp(!1,"scroll")},this._keyDown=e=>{if(!this._open||e.defaultPrevented)return;if("Escape"===e.key)return e.preventDefault(),e.stopImmediatePropagation(),void this._closeHelp(this._floating.ownsActiveElement(),"escape");const t=this.renderRoot.querySelector(".trigger");if(!t||!e.composedPath().includes(t))return;const i=this._surface();if(!i||i.scrollHeight<=i.clientHeight)return;const o=Math.max(40,.8*i.clientHeight),n={ArrowDown:40,ArrowUp:-40,PageDown:o,PageUp:-o};if("Home"===e.key)i.scrollTop=0;else if("End"===e.key)i.scrollTop=i.scrollHeight;else{if(!(e.key in n))return;i.scrollBy({top:n[e.key],behavior:"auto"})}e.preventDefault(),e.stopImmediatePropagation()},this._floating=new l(this,"help",this._keyDown),this._queuePosition=()=>{if(!this._open||this._positionRaf)return;const e=this._window();e&&(this._positionRaf=e.requestAnimationFrame(()=>{this._positionRaf=0,this._position()||this._closeHelp()}))}}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this._keyDown,!0)}willUpdate(){this.toggleAttribute("data-has-content",this._hasContent())}disconnectedCallback(){const e=this.ownerDocument.defaultView;this._unsubscribeOpenListeners(),this.removeEventListener("keydown",this._keyDown,!0),this._clearTimers(),this._positionRaf&&e?.cancelAnimationFrame(this._positionRaf),this._positionRaf=0,this._closeHelp(!1,"disconnect"),super.disconnectedCallback()}updated(e){if(e.has("pointerHover")&&!this.pointerHover){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._openTimer=0,this._hoverOwned&&this._closeHelp(!1,"outside")}this._hasContent()||!this._open?this._open&&e.has("text")&&(this._usesPopover()||this._renderFallback(),this._queuePosition()):this._closeHelp()}_window(){return this._floating.window()}_dialog(){return this._floating.dialog()}_usesPopover(){return this._floating.usesPopover(this._forceFallback)}_hasContent(){return e=this.text,t=this.ariaLabel,"string"==typeof e&&e.trim().length>0&&"string"==typeof t&&t.trim().length>0;var e,t}_clearTimers(){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._closeTimer&&e?.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=0}_scheduleOpen(){const e=this._window();this.pointerHover&&e&&!this._open&&!this._openTimer&&(this._closeTimer&&e.clearTimeout(this._closeTimer),this._closeTimer=0,this._openTimer=e.setTimeout(()=>{this._openTimer=0,this.isConnected&&(this._hoverOwned=!0,this._openHelp())},300))}_scheduleClose(){const e=this._window(),t=this.renderRoot.querySelector(".trigger");e&&!t?.matches(":focus-visible")&&(this._openTimer&&e.clearTimeout(this._openTimer),this._closeTimer&&e.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=e.setTimeout(()=>{this._closeTimer=0,this.isConnected&&this._closeHelp()},150))}_triggerPointerEnter(e){this.pointerHover&&"mouse"===e.pointerType&&this._scheduleOpen()}_triggerPointerLeave(e){"mouse"===e.pointerType&&this._scheduleClose()}_triggerFocus(){queueMicrotask(()=>{const e=this.renderRoot.querySelector(".trigger");e?.matches(":focus-visible")&&(this._hoverOwned=!1,this._openHelp())})}_triggerBlur(){this._scheduleClose()}_triggerClick(){this._open?this._closeHelp():(this._hoverOwned=!1,this._openHelp())}_subscribeOpenListeners(){this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("keydown",this._keyDown,!0);const e=this._window();e?.addEventListener("resize",this._queuePosition),e?.addEventListener("orientationchange",this._queuePosition),e?.visualViewport?.addEventListener("resize",this._queuePosition),e?.visualViewport?.addEventListener("scroll",this._queuePosition),this._scrollDialog=this._dialog(),this._scrollDialog?.addEventListener("scroll",this._dialogScroll,!0)}_unsubscribeOpenListeners(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("keydown",this._keyDown,!0);const e=this._window();e?.removeEventListener("resize",this._queuePosition),e?.removeEventListener("orientationchange",this._queuePosition),e?.visualViewport?.removeEventListener("resize",this._queuePosition),e?.visualViewport?.removeEventListener("scroll",this._queuePosition),this._scrollDialog?.removeEventListener("scroll",this._dialogScroll,!0),this._scrollDialog=null}async _openHelp(){!this._open&&this._hasContent()&&(this._clearTimers(),this._forceFallback=!1,this._open=!0,this._subscribeOpenListeners(),await this.updateComplete,this._open&&(this._usesPopover()||this._renderFallback(),this._position()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:e=>this._closeHelp("escape"===e&&this._floating.ownsActiveElement(),e)})||null:this._closeHelp()))}_closeHelp(e=!1,t="exclusive"){if(!this._open&&!this._floating.hasFallback)return;this._clearTimers();const i=this._overlayDispose;this._overlayDispose=null,i?.();const o=this.renderRoot.querySelector(".tooltip");if(o?.hidePopover)try{o.matches(":popover-open")&&o.hidePopover()}catch{}this._open=!1,this._hoverOwned=!1,this._unsubscribeOpenListeners(),this._floating.destroy(),e&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_tooltipTemplate(e){return t``}_renderFallback(){const e=c.styles.cssText;this._floating.renderFallback(this._tooltipTemplate(!1),e)}_surface(){return this._floating.surface(".tooltip",this._usesPopover())}_position(){if(!this._open)return!1;const e=this._window(),t=this.renderRoot.querySelector(".trigger");let i=this._surface();if(!e||!t?.isConnected||!i?.isConnected)return!1;const o=s(e);if(i.style.maxWidth=`${Math.max(0,Math.min(320,o.width-16))}px`,i.style.maxHeight=`${Math.max(0,o.height-16)}px`,i.style.visibility="hidden",this._usesPopover()&&i.showPopover)try{i.matches(":popover-open")||i.showPopover()}catch{if(this._forceFallback=!0,this._renderFallback(),i=this._surface(),!i?.isConnected)return!1;i.style.visibility="hidden"}const n=t.getBoundingClientRect(),r=i.getBoundingClientRect();if(!(n.width&&n.height&&r.width&&r.height))return!1;const l=a(n,r,o);return i.style.left=`${l.left}px`,i.style.top=`${l.top}px`,i.dataset.side=l.side,i.style.visibility="",!0}render(){if(!this._hasContent())return i;const e=this.ariaLabel.trim();return t` ({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`({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`h[e.name]||e.name} + .computeLabel=${e=>f[e.name]||e.name} @value-changed=${this._valueChanged} >`;return c` - ${d(f.slice(0,3))} + ${d(h.slice(0,3))} ${_?c``: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); diff --git a/custom_components/houseplan/frontend/houseplan-assets/fr-B-ete5Dh.js b/dist/houseplan-assets/fr-B8hQ5YK4.js similarity index 71% rename from custom_components/houseplan/frontend/houseplan-assets/fr-B-ete5Dh.js rename to dist/houseplan-assets/fr-B8hQ5YK4.js index 04a33a71..0cfa1990 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/fr-B-ete5Dh.js +++ b/dist/houseplan-assets/fr-B8hQ5YK4.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";var e={"editor.context_actions":"Actions : {object}","editor.tool_options":"Options de l’outil : {tool}","editor.palette":"Palette : {tool}","editor.open_group":"Groupe d’outils : {group}","editor.group_active":"{group} — actif : {item}","editor.disabled_action":"{action} est indisponible : {reason}","editor.loading":"Chargement de l'éditeur…","editor.loading_aria":"L'éditeur de plan est en cours de chargement","editor.load_failed":"Impossible de charger l'éditeur.","editor.refresh_advice":"Actualisez la page et réessayez.","editor.retry_advice":"Vérifiez votre connexion et appuyez à nouveau.","version_mismatch.title":"Les versions de House Plan ne correspondent pas","version_mismatch.body":"Si Home Assistant redémarre encore, attendez la fin, puis rechargez cette page.","version_mismatch.frontend":"Carte","version_mismatch.backend":"Intégration","version_mismatch.reload":"Recharger la page","color_picker.title":"Sélecteur de couleur","color_picker.hue":"Teinte","color_picker.saturation":"Saturation","color_picker.value":"Luminosité","color_picker.hex":"Couleur hexadécimale","color_picker.invalid_hex":"Saisissez une couleur hexadécimale à 3 ou 6 chiffres","color_picker.confirm":"OK","btn.properties":"Propriétés","btn.keep_as_walls":"Conserver comme murs","btn.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","btn.delete_room_with_walls":"Supprimer la pièce et les murs","title.markup_select":"Sélectionner et modifier les murs et les colonnes","title.markup_column":"Colonne : cliquez sur un point de la grille pour placer une colonne carrée","markup.partition":"Cloison","markup.column":"Colonne","markup.hint_column":"cliquez sur un point de la grille pour placer une colonne carrée","history.wall_segment":"Ajouter un segment de mur","history.column_add":"Ajouter une colonne","history.physical_edit":"Modifier l’objet physique","history.physical_delete":"Supprimer l’objet physique","history.physical_move":"Déplacer l’objet physique","history.wall_face_batch":"Créer des pièces à partir des murs","toast.column_duplicate":"Une colonne avec le même centre et la même dimension extérieure existe déjà","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.shape":"Forme","physical.square":"Carré","physical.circle":"Cercle","physical.diameter":"Diamètre","physical.side":"Côté","physical.rotation":"Angle de rotation","physical.length":"Longueur","physical.allowed_range":"Autorisé : {min}–{max} {unit}","physical.column_size_title":"Côté extérieur de la colonne carrée placée par le clic (1–150 cm).","card.title":"Plan de la maison","count.devices":"{n} app.","empty.no_spaces":"Aucun espace pour le moment.","nav.spaces":"Espaces House Plan","empty.add_first":"Ajoutez le premier espace et importez un plan.","empty.read_only":"Aucun espace n’est configuré. Demandez à un administrateur d’en ajouter un.","empty.install":"Installez l’intégration House Plan et ajoutez-la dans « Appareils et services ».","btn.add_space":"Ajouter un espace","btn.cancel":"Annuler","btn.save":"Enregistrer","btn.close":"Fermer","btn.delete":"Supprimer","btn.copy":"Copier","btn.edit":"Modifier","btn.open_in_ha":"Ouvrir dans HA","btn.reset":"Réinitialiser","btn.attach":"Joindre…","btn.upload":"Importer…","btn.replace":"Remplacer…","title.zoom_in":"Zoomer","title.zoom_out":"Dézoomer","title.zoom_fit":"Tout ajuster","title.configure_space":"Configurer l’espace","title.add_space":"Ajouter un espace","title.markup_add":"Murs : tracez une chaîne continue ; chaque segment accepté est enregistré séparément. Maj verrouille à 45°","title.markup_merge":"Fusionner : cliquez sur une pièce, puis sur la pièce voisine avec laquelle elle partage un mur","title.markup_split":"Diviser une pièce : cliquez sur la pièce, puis sur deux points de ses murs","title.markup_delroom":"Supprimer une pièce : cliquez à l’intérieur de la pièce puis confirmez","title.need_plan":"Importer une image de plan","markup.add":"Murs","markup.merge":"Fusionner","markup.split":"Diviser","markup.resize":"Redimensionner","title.markup_resize":"Redimensionner les pièces : faites glisser une poignée disponible sur un mur horizontal ou vertical","markup.hint_resize":"faites glisser une poignée de mur disponible · le mur s’arrête à la première position non sûre · Échap annule · Ctrl+Z — annuler","resize.disabled.diagonal":"Ce mur est incliné ; le redimensionnement ne prend en charge que les murs horizontaux et verticaux","resize.disabled.side-angle":"Un mur adjacent est incliné ; le redimensionnement exige que les deux murs adjacents rencontrent ce mur à angle droit","resize.disabled.duplicate-physical-wall":"Une cloison distincte ou une colonne chevauche ce mur ; supprimez-la ou déplacez-la avant de redimensionner","resize.disabled.partial-shared":"Une pièce voisine n’utilise qu’une partie de ce mur ; il ne peut donc pas être déplacé en toute sécurité comme un mur partagé unique","resize.disabled.unequal-shared":"La pièce voisine utilise des extrémités ou une longueur de mur différentes ; les murs ne peuvent donc pas être déplacés ensemble en toute sécurité","resize.disabled.multiple-rooms":"Déplacer ce mur affecterait plus de deux pièces","resize.disabled.thickness-conflict":"L’épaisseur du mur ne peut pas être conservée en toute sécurité","resize.disabled.opening-conflict":"Une ouverture sur ce mur ne peut pas être déplacée en toute sécurité","resize.disabled.invalid-geometry":"Ce mur ne peut pas être redimensionné sans modifier la structure du plan","resize.limit_stopped":"Mur arrêté : l'étape suivante enfreindrait une limite de jonction","resize.commit_failed":"Le redimensionnement a été annulé car le plan final n’a pas passé le contrôle de géométrie","resize.preview_failed":"Le redimensionnement s’est arrêté à la dernière position sûre car la géométrie du plan ne pouvait pas être préservée","markup.opening":"Ouverture","markup.delete_room":"Supprimer la pièce","history.undo":"Annuler","history.redo":"Rétablir","history.undo_named":"Annuler : {name} (Ctrl+Z)","history.redo_named":"Rétablir : {name} (Ctrl+Maj+Z / Ctrl+Y)","history.undo_empty":"Rien à annuler","history.redo_empty":"Rien à rétablir","history.undone":"Annulé : {name}","history.redone":"Rétabli : {name}","history.add_room":"Créer une pièce","history.split_room":"Diviser la pièce","history.merge_rooms":"Fusionner les pièces","history.resize_room":"Redimensionner la pièce","history.wall_thickness":"Modifier l’épaisseur du mur","history.add_opening":"Ajouter une ouverture de porte ou de fenêtre","history.edit_opening":"Modifier l’ouverture","history.move_opening":"Déplacer l’ouverture","history.delete_opening":"Supprimer l’ouverture","history.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","history.delete_room_with_walls":"Supprimer la pièce et les murs","history.decor_add":"Ajouter un objet décoratif","history.decor_edit":"Modifier l’objet décoratif","history.decor_move":"Déplacer l’objet décoratif","history.decor_transform":"Transformer l’objet décoratif","history.decor_delete":"Supprimer l’objet décoratif","history.backdrop_transform":"Transformer l’arrière-plan du plan","history.device_move":"Déplacer {name}","history.device_stale":"L’historique des positions n’est plus applicable et a été effacé","opening.new":"Nouvelle ouverture","opening.edit":"Ouverture","opening.door":"Porte","opening.window":"Fenêtre","opening.gate":"Portail","opening.passage":"Passage ouvert","opening.passage_binding_warning":"L’enregistrement supprimera le capteur d’ouverture/fermeture et la serrure.","opening.invalid_passage_fields":"Le passage ouvert du plan « {room} » possède des paramètres non pris en charge : {fields}.","opening.type_label":"Type","opening.length_label":"Longueur, cm","opening.contact_label":"Capteur d’ouverture/fermeture","opening.lock_label":"Serrure","opening.none":"— aucun —","opening.search_ph":"Rechercher : nom ou ID d’entité…","opening.invert":"Inverser ouvert/fermé","opening.flip_h":"Charnière sur l’autre montant","opening.flip_v":"Ouverture de l’autre côté","opening.open":"Ouvert","opening.closed":"Fermé","opening.locked":"Verrouillé","opening.unlocked":"Déverrouillé","opening.state_unknown":"indisponible","opening.no_entities":"Aucun capteur associé — symbole statique sur le plan.","toast.opening_no_wall":"Cliquez près d’un mur de pièce ou d’un mur indépendant","opening.host_partition":"Mur indépendant","opening.partition_orphan":"Le mur indépendant de cette ouverture n’existe plus","opening.partition_jamb_margin":"Laissez au moins {distance} entre l’ouverture et l’extrémité du mur","opening.rebind_partition":"Associer à un autre mur indépendant","confirm.delete_partition_openings_title":"Supprimer le mur et les ouvertures ?","confirm.delete_partition_openings_body":"Ce mur contient {count} ouverture(s). Elles seront supprimées avec lui.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.hint_points":"points : {n} · Maj — pas de 45° · Échap — terminer la chaîne · Ctrl+Z — annuler un point · fermer une zone propose de créer une pièce","markup.hint_start":"cliquez sur un point de la grille pour commencer une chaîne de murs","tip.lqi":"signal Zigbee moyen :","tip.area":"surface : {value}","info.device_header":"Appareil sur le plan","info.model":"Modèle","info.state":"État","info.link":"Lien","info.manuals":"Manuels","info.none":"Aucune information supplémentaire","marker.new_device":"Nouvel appareil","marker.name_label":"Nom (affiché sur le plan)","marker.name_ph":"Nom","marker.binding_label":"Associer à un appareil HA","marker.binding_disabled":"désactivé dans Home Assistant","marker.virtual_option":"Appareil virtuel (sans association)","marker.search_ph":"Rechercher un appareil / groupe…","marker.nothing_found":"aucun résultat","marker.room_label":"Pièce","marker.room_override":" (placement forcé)","marker.room_choose":"— sélectionner une pièce —","marker.room_auto":"— selon la zone de l’appareil (auto) —","marker.icon_label":"Icône","marker.icon_ph":"mdi:… (vide = auto)","marker.display_label":"Affichage","display.badge":"Icône + état","display.icon_ripple":"Icône + état et activité","display.static_icon":"Icône toujours statique","marker.display_hint_badge":"L’icône et le fond dynamique affichent l’état de l’appareil sans la pulsation d’activité habituelle. Les alarmes rouges restent visibles.","marker.display_hint_icon_ripple":"L’icône, le fond dynamique et la pulsation affichent une brève animation pour les événements et une animation continue pour le fonctionnement, le mouvement ou la présence. Les alarmes rouges restent prioritaires.","marker.display_hint_value":"Une valeur Home Assistant sélectionnée ou résolue automatiquement remplace l’icône tandis que le fond continue d’indiquer l’état. Les alarmes rouges restent visibles.","marker.display_hint_static_icon":"Le contour adapté au thème et l’icône restent toujours identiques. L’état, l’activité, l’indisponibilité et les alarmes ne modifient pas l’apparence.","marker.static_alarm_warning":"Cet appareil peut signaler des alarmes. L’affichage statique masque l’indication visuelle d’alarme du marqueur.","marker.preview.title":"Aperçu de l’affichage","marker.preview.actual":"Actuel","marker.preview.example":"Exemple","marker.preview.integration":"Fourni par","marker.preview.source":"Source d’affichage","marker.preview.current_state":"État actuel","marker.preview.result":"Sur le plan","marker.preview.details":"Détails de la source","marker.preview.select_source":"Choisissez un appareil ou une entité Home Assistant pour voir son affichage réel.","marker.preview.unknown_provider":"Intégration inconnue","marker.preview.virtual_provider":"House Plan · appareil virtuel","marker.preview.no_source":"Aucune source active","marker.preview.no_state":"Aucun état actuel","marker.preview.mixed_states":"Plusieurs états différents","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} de plus","marker.preview.scaled":"L’aperçu est redimensionné à {n}% pour tenir dans la zone. La taille enregistrée reste inchangée.","marker.preview.demo_short":"Afficher une activité brève","marker.preview.demo_continuous":"Afficher une activité continue","marker.preview.stop_continuous":"Arrêter l’activité continue","marker.preview.demo_short_notice":"Exemple d’activité brève ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_continuous_notice":"Exemple d’activité continue ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_already_visible":"L’état actuel affiche déjà un véritable effet d’activité ou d’alarme.","marker.preview.reduced_motion":"La réduction des animations est activée sur le système ; l’activité normale est donc affichée sous forme de point.","marker.preview.reason.neutral":"Fond sombre neutre","marker.preview.reason.working":"Fond jaune : l’appareil fonctionne actuellement","marker.preview.reason.working_activity":"Fond jaune et effet d’activité : l’appareil fonctionne actuellement","marker.preview.reason.open":"Fond orange : physiquement ouvert ou déverrouillé","marker.preview.reason.cover_icon_state":"Fond neutre ; l’entité de volet contrôle l’état et l’icône affichés","marker.preview.reason.presence":"Effet d’activité tant qu’une présence est détectée","marker.preview.reason.event":"Effet d’activité bref après un événement détecté","marker.preview.reason.transition":"Effet d’activité pendant que l’appareil se déplace ou change d’état","marker.preview.reason.media_neutral":"Les appareils multimédias restent sur un fond sombre neutre tant qu’ils sont disponibles","marker.preview.reason.unavailable":"Fond neutre atténué : indisponible ou éteint","marker.preview.reason.alarm":"Fond d’alarme rouge ; l’indication d’alarme est toujours affichée","marker.preview.reason.live_states_disabled":"Le style selon les états en direct est désactivé pour cette carte","marker.preview.reason.value_no_state":"Aucune valeur d’état exploitable ; l’icône est affichée à la place","marker.preview.reason.value_ambiguous_sources":"Plusieurs sources de valeur possibles ; l’icône est affichée à la place","marker.preview.reason.value_non_scalar":"La source n’a pas renvoyé de valeur simple ; l’icône est affichée à la place","marker.preview.reason.value_virtual":"Un appareil virtuel n’a aucune valeur Home Assistant ; l’icône est affichée à la place","marker.preview.reason.vacuum_live_plan_only":"La position et la trajectoire en direct de l’aspirateur ne sont disponibles que sur le plan complet","marker.preview.reason.hidden_design_preview":"L’appareil est masqué sur le plan ; cet aperçu de conception reste visible","marker.preview.reason.composite_power_source":"L’état provient de l’entité d’alimentation de l’appareil ; les interrupteurs auxiliaires sont ignorés","marker.preview.reason.activity_display_disabled":"Le mode d’affichage sélectionné n’affiche pas les effets d’activité habituels","marker.preview.reason.ha_disabled":"L’association Home Assistant est désactivée et sera masquée sur le plan","marker.preview.reason.orphaned":"L’association Home Assistant enregistrée est introuvable","marker.preview.reason.static_icon":"Mode statique : l’état de l’appareil ne modifie pas l’icône","marker.activity_color":"Couleur de la pulsation d’activité","marker.ripple_size":"Taille de la pulsation d’activité","marker.activity_alarm_note":"La couleur et la taille n’affectent que l’activité normale et ne modifient pas les alarmes rouges.","marker.pulse_a11y_alarm":"Alarme","marker.pulse_a11y_event":"Événement récent","marker.pulse_a11y_presence":"Présence détectée","marker.pulse_a11y_transition":"Changement d’état","marker.pulse_a11y_running":"En fonctionnement","marker.state_a11y_neutral":"État par défaut","marker.state_a11y_working":"En fonctionnement","marker.state_a11y_open":"Ouvert","marker.state_a11y_locked":"Verrouillé","marker.state_a11y_unlocked":"Déverrouillé","marker.state_a11y_alarm":"Alarme","marker.state_a11y_unavailable":"Indisponible","marker.lqi_a11y_low":"LQI {value}, signal faible","marker.lqi_a11y_mid":"LQI {value}, signal moyen","marker.lqi_a11y_high":"LQI {value}, signal fort","marker.size_label":"Taille / rotation de l’icône","marker.angle_label":"Rotation","marker.model_label":"Modèle","marker.model_ph":"ex. Aqara T&H","marker.link_label":"Lien","marker.desc_label":"Description","marker.desc_ph":"Notes, caractéristiques…","marker.manuals_label":"Manuels (PDF, etc.)","marker.sub_device":"appareil","marker.sub_z2m_group":" · groupe Z2M","marker.sub_group":"groupe","marker.sub_helper":"assistant","space.new":"Nouvel espace","space.copy_title":"Copier l’espace","space.copy_name":"Nom du nouvel espace","space.copy_fallback":"Espace","space.copy_create":"Créer la copie","space.copy_optimize_title":"Optimiser avant de copier ?","space.copy_optimize_body":"Avant de créer « {name} », House Plan doit optimiser tout le plan, y compris les autres espaces. Continuer ?","space.copy_optimize_confirm":"Optimiser et copier","space.copy_error_changed":"Le plan a changé pendant la confirmation. Vérifiez-le et réessayez.","space.copy_error_source_missing":"L’espace source n’existe plus. Rouvrez ses réglages et réessayez.","space.copy_error_source_invalid":"House Plan n’a pas pu valider tous les murs de cet espace. Corrigez l’espace source.","space.copy_error_spaces_limit":"House Plan contient déjà le nombre maximal d’espaces.","space.copy_error_partitions_limit":"Cet espace contient trop de murs pour être copié.","space.copy_error_openings_limit":"Cet espace contient trop d’ouvertures pour être copié.","space.copy_error_decor_limit":"Cet espace contient trop d’objets d’arrière-plan pour être copié.","space.copy_error_columns_limit":"Cet espace contient trop de colonnes pour être copié.","space.copy_error_opening_host":"Une ouverture n’est plus rattachée à un mur. Corrigez-la ou supprimez-la avant la copie.","space.copy_error_geometry":"La copie créerait une géométrie de murs non sûre. Corrigez l’espace source.","space.copy_error_optimize_geometry":"La copie est arrêtée car l’optimisation de tout le plan n’est pas sûre pour un espace.","space.header":"Espace","space.title_label":"Titre","space.title_ph":"ex. Garage","space.plan_label":"Plan (arrière-plan)","space.no_plan":"aucune image de plan","space.plan_alt":"plan","room.new":"Nouvelle pièce","room.name_label":"Nom affiché","room.name_ph":"ex. Terrasse","room.area_label":"Zone Home Assistant (non attribuée)","room.no_area_option":"— aucune zone —","room.default_name":"Pièce","device.unnamed":"sans nom","device.light_group":"groupe de lumières","device.fallback":"appareil","device.virtual":"appareil virtuel","confirm.delete_room_title":"Supprimer la pièce « {name} » ?","confirm.delete_room_body":"Choisissez si les murs physiques propres à la pièce doivent être conservés. Les murs partagés avec une autre pièce sont toujours conservés.","confirm.remove_marker_title":"Supprimer l’appareil du plan ?","confirm.remove_marker_body":"L’appareil disparaîtra complètement et ne contribuera plus aux données du plan. Vous pourrez l’ajouter de nouveau plus tard.","confirm.erase_decor":"Effacer l’objet {kind} ? Vous pouvez annuler cette action depuis l’historique de l’éditeur.","confirm.delete_space_title":"Supprimer l’espace ?","confirm.delete_space_body":"L’espace, toutes ses pièces et tout le tracé du plan seront supprimés.","confirm.delete_space_vac_routes":"Les affectations de cartes de robots seront aussi supprimées : {count}.","space.delete_blocked":"Cet espace est encore utilisé par {n} appareil(s). Déplacez-les vers un autre espace ou supprimez-les d’abord.","toast.pos_save_failed":"Échec de l’enregistrement de la position : {err}","toast.no_entity":"L’appareil n’a aucune entité adaptée","toast.ha_disabled_action":"Un objet Home Assistant désactivé ne peut pas être utilisé sur le plan.","toast.ha_disabled_show_device":"Un appareil désactivé dans Home Assistant ne peut pas être affiché sur le plan. Activez-le d’abord dans Home Assistant.","toast.ha_disabled_show_entity":"Une entité désactivée dans Home Assistant ne peut pas être affichée sur le plan. Activez-la d’abord dans Home Assistant.","toast.ha_disabled_add":"Un objet Home Assistant désactivé ne peut pas être ajouté au plan. Activez-le d’abord dans Home Assistant.","toast.ha_binding_unverified":"L’état de l’objet n’a pas pu être vérifié via le registre Home Assistant. L’affichage et les actions sont temporairement indisponibles.","toast.markup_needs_server":"Le tracé est disponible une fois la configuration déplacée sur le serveur","toast.space_order_changed":"L’ordre a changé. Si une carte fixe son étage par numéro, vérifiez ces tableaux de bord.","toast.conflict":"La configuration a été modifiée dans une autre fenêtre — données actualisées, répétez votre dernière action","toast.cfg_save_failed":"Échec de l’enregistrement de la configuration : {err}","toast.room_overlap":"Le contour chevauche la pièce « {name} » — les pièces ne doivent pas se chevaucher","toast.contour_cannot_close":"Le contour ne peut pas être fermé car il est dégénéré ou s’auto-intersecte","toast.merge_not_adjacent":"Seules les pièces partageant un mur peuvent être fusionnées","toast.rooms_merged":"Pièces fusionnées dans « {name} »","toast.split_pick_wall":"Commencez la découpe sur le mur de la pièce","toast.split_bad_cut":"La découpe doit aller d’un mur à l’autre à l’intérieur de la pièce, sans croiser de mur ni se croiser elle-même","merge.header":"Fusionner les pièces","merge.hint":"La pièce fusionnée conserve un nom et une zone. L’autre zone est libérée — ses appareils quittent le plan jusqu’à ce qu’une autre pièce la récupère.","merge.keep":"Conserver","merge.no_area":"aucune zone","toast.room_saved":"Pièce enregistrée ({n}). Appareils ajoutés : {added}. Tracez la suivante ou quittez le mode tracé.","toast.room_saved_no_area":"Pièce enregistrée ({n}, sans zone). Tracez la suivante ou quittez le mode tracé.","toast.marker_needs_server":"La modification des appareils est disponible une fois la configuration déplacée sur le serveur","toast.virtual_name_required":"Saisissez un nom pour l’appareil virtuel","toast.marker_saved":"Appareil enregistré","toast.marker_removed":"Appareil supprimé du plan","toast.integration_missing":"L’intégration House Plan n’est pas installée — gestion indisponible","toast.plan_formats":"Formats pris en charge : SVG, PNG, JPG, WebP","toast.plan_required":"Importez un plan — il est obligatoire","toast.space_added_onboard":"Espace ajouté. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","toast.space_added":"Espace ajouté","toast.space_copied":"Espace « {name} » créé","toast.space_saved":"Espace enregistré","toast.space_deleted":"Espace supprimé","toast.delete_failed":"Échec de la suppression : {err}","toast.error":"Erreur : {err}","toast.toggle_target_unavailable":"La cible « {name} » est indisponible — aucune action n’a été effectuée","toast.toggle_targets_unavailable":"Cibles indisponibles : {names}. Aucune action n’a été effectuée","toast.file_failed":"Le fichier « {name} » n’a pas été importé : {err}","toast.files_attached":"Fichiers joints : {n}","err.unknown":"erreur inconnue","err.code":"code {code}","err.too_large":"fichier supérieur à {mb} Mo","err.bad_ext":"type non pris en charge (PDF/image attendu)","err.unauthorized":"droits administrateur requis","editor.title":"Titre","editor.default_floor":"Espace initial","editor.default_floor_missing":"L’espace initial « {id} » n’existe plus. Choisissez un autre espace.","editor.floor":"Espace fixe","editor.floor_none":"— non fixé —","editor.floor_index":"Index YAML {index} (conservé)","fixed_floor.loading":"Chargement de l’espace fixe…","fixed_floor.invalid_title":"L’espace fixe est indisponible","fixed_floor.invalid_body":"Vérifiez floor dans la configuration de la carte. Valeur configurée : {value}","editor.icon_size":"Taille des icônes, % de la largeur du plan","editor.show_temperature":"Afficher la température","editor.live_states":"États en direct (on/off, ouvert…)","editor.light_pools":"Halos lumineux et ombres des murs","editor.show_signal":"Afficher le signal Zigbee (LQI)","editor.language":"Langue de l’interface","editor.lang_auto":"Auto (profil HA)","title.icon_rules":"Règles d’icônes : quelle icône MDI attribuer aux appareils selon leur nom","rules.title":"Règles d’icônes","rules.hint":"Les règles sont testées de haut en bas sur « nom de l’appareil + modèle » (expression régulière insensible à la casse) ; la première correspondance gagne. Si rien ne correspond, la classe d’appareil de l’entité est utilisée, puis l’icône générique.","rules.pattern_ph":"regex, ex. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Ajouter une règle","rules.reset":"Réinitialiser par défaut","rules.test_ph":"Tester un nom d’appareil…","rules.invalid":"expression régulière invalide","rules.saved":"Règles d’icônes enregistrées","btn.up":"Monter","btn.down":"Descendre","tap.info":"Fiche de l’appareil","tap.more_info":"Boîte de dialogue Plus d’infos de HA","tap.toggle":"Basculer l’état","marker.tap_label":"Action au toucher pour cet appareil","tap.toggle_note":"L’état déterminé est affiché ci-dessous. Les appareils sécurisés ne sont jamais basculés depuis le plan.","import.title":"Créer des espaces à partir des étages HA","import.hint":"Votre Home Assistant connaît déjà ces étages. Sélectionnez ceux à transformer en espaces du plan — vous importerez ensuite une image de plan pour chacun. Les pièces sont ensuite tracées manuellement sur le plan.","import.start":"Créer {n} espace(s)","import.manual":"Commencer de zéro","import.progress":"Étage {i} sur {n}","import.done":"Espaces créés. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","btn.skip":"Passer","space.scale_label":"Échelle (taille d’une cellule de grille)","space.cell_cm.help":"Relie la grille aux dimensions réelles : les longueurs, les surfaces, l’épaisseur des murs, la taille des ouvertures et le rayon du halo en dépendent. Une modification ultérieure change les dimensions calculées de tout l’espace sans déplacer ses points sur le plan.","space.cell_cm.help.aria":"Aide : échelle de l’espace","space.scale_unit":"cm par cellule","space.scale_unit_imperial":"po par cellule","space.display_section":"Affichage","space.show_borders":"Toujours afficher les contours des pièces","space.zero_wall_style":"Murs d’épaisseur nulle","space.zero_wall_style.help":"Les murs d’épaisseur nulle en pointillés laissent passer le halo et les rayons du soleil, tandis que les murs pleins les bloquent comme une barrière sans surface. Ce choix s’applique à tous ces murs de l’espace, même si leur ligne est masquée en mode Vue.","space.zero_wall_style.help.aria":"Aide : style des murs d’épaisseur nulle","space.zero_wall_dashed":"Pointillés","space.zero_wall_solid":"Plein","space.show_names":"Afficher les noms des pièces (faire glisser pour déplacer)","space.room_color":"Couleur du contour et du nom","space.opacity":"Opacité","space.fill_label":"Remplissage de la pièce","space.fill_mode.help":"« Couleur personnalisée » définit le style, tandis que « Lumière », « Température » et « LQI » utilisent les données actuelles de Home Assistant. Le halo s’active séparément.","space.fill_mode.help.aria":"Aide : mode de remplissage des pièces","fill.none":"Aucun","fill.lqi":"Signal Zigbee","fill.light":"Lumières","fill.custom":"Couleur personnalisée","space.custom_fill":"Couleur de remplissage","space.source_file":"J’ai une image de plan","space.source_draw":"Aucune image — je tracerai les pièces à la main","fill.temp":"Température","tip.temp_avg":"température moyenne :","tip.hum_avg":"humidité moyenne :","space_card.button":"Ouvrir le plan de l’espace","space_card.not_found":"Espace « {id} » introuvable","space_card.loading":"Chargement…","continuity.restore_plan":"Restauration du plan…","continuity.restore_connection":"Restauration de la connexion aux appareils…","continuity.retry":"Réessayer","editor.space":"Espace","editor.framing":"Cadrage","editor.fit_content":"Tout le contenu visible","editor.fit_house":"Ajusté à la géométrie de la maison","editor.show_button":"Afficher le bouton","editor.button_label":"Libellé du bouton","editor.button_target":"Chemin du tableau de bord cible","marker.sub_entity":"entité","title.general_settings":"Paramètres généraux","title.export_pdf":"Enregistrer en PDF","pdf.title":"Enregistrement en PDF","pdf.dimensions":"Afficher les dimensions et les surfaces","pdf.decor":"Afficher les meubles et les autres éléments","pdf.room_names":"Afficher les noms des pièces","pdf.backdrop":"Afficher le fond de plan","pdf.save":"Enregistrer","pdf.saving":"Création…","pdf.failed":"Impossible de créer le PDF.","pdf.too_large":"Les images dépassent la limite PDF de 25 Mo.","pdf.asset_failed":"Impossible de charger une image de fond ou de décoration.","pdf.scale":"Échelle 1:{n}","pdf.north":"Nord","gs.title":"Paramètres généraux","gs.light_group":"Remplissage : lumières","gs.light_on":"Lumières allumées","gs.light_off":"Toutes les lumières éteintes","gs.temp_group":"Remplissage : température","gs.temp_cold":"Froid","gs.temp_ok":"Confortable","gs.temp_hot":"Chaud","gs.lqi_group":"Remplissage : signal Zigbee","gs.lqi_low":"Signal faible","gs.lqi_high":"Signal fort","gs.reset":"Réinitialiser par défaut","gs.saved":"Paramètres généraux enregistrés","gs.radar_show_live":"Afficher la présence en direct sur le plan","gs.radar_show_live_hint":"Masque ou affiche toutes les cibles radar en direct. Cela ne démarre ni n’arrête l’enregistrement des observations.","radar.title":"Présence sur le plan","radar.help":"Reliez ce marqueur aux entités radar exactes de Home Assistant, placez le capteur et choisissez son profil de coordonnées. Les positions en direct sont limitées à la pièce sélectionnée.","radar.help.aria":"Aide : paramètres du radar de présence","radar.enabled":"Utiliser ce radar de présence","radar.show_live":"Afficher les cibles en direct","radar.configure":"Configurer le radar","radar.configure_on_plan":"Configurer sur le plan","radar.change_installation":"Changer l’installation","radar.no_contour":"Cette pièce n’a pas de contour. Les points radar ne seront pas limités.","radar.discard_setup_title":"Abandonner la configuration du radar ?","radar.discard_setup":"La configuration du radar non enregistrée sera perdue.","radar.step_place_mount":"Indiquez la position physique du capteur","radar.step_place_heading":"Indiquez un point droit devant le capteur","radar.step_reference":"Indiquez la position de référence {n}, puis lancez la mesure","radar.step_check_reference":"Indiquez une position de contrôle indépendante","radar.start_measure":"Lancer la mesure","radar.countdown":"Placez-vous sur le repère dans {seconds} s","radar.capturing":"Restez immobile et seul pendant la mesure…","radar.fit_ready":"Le calibrage est prêt","radar.check_third":"Vérifier à une autre position","radar.check_complete":"Contrôle indépendant terminé","radar.error_distance":"Écart de position : {distance}","radar.ambiguous_target":"Plusieurs cibles ont été signalées. Recommencez la mesure seul.","radar.insufficient_samples":"Coordonnées actuelles insuffisantes. Réessayez ou utilisez le réglage manuel.","radar.bad_references":"Choisissez des références espacées dans des directions différentes du capteur.","radar.ambiguous_sources":"Les mesures permettent deux directions également plausibles. Choisissez des repères distinguant la gauche de la droite.","radar.bad_fit":"Les mesures ne correspondent pas. Vérifiez les unités, la position du capteur et les références.","radar.desktop_hint":"Utilisez un ordinateur pour un réglage précis. L’édition sur appareils tactiles est prise en charge au mieux.","radar.detected":"House Plan a reconnu les métadonnées radar de cet appareil. Vérifiez les sources exactes avant d’enregistrer.","radar.detected_ld2450":"House Plan a trouvé un ensemble de coordonnées ESPHome LD2450. Vérifiez les sources X/Y exactes avant d’enregistrer.","radar.additional_actions":"Actions supplémentaires","radar.declare":"Ceci est un radar de présence","radar.profile":"Profil de données","radar.profile_esphome_ld2450_v1":"ESPHome LD2450 (cibles X/Y)","radar.profile_cartesian_v1":"Cibles cartésiennes (X/Y)","radar.profile_polar_v1":"Cible polaire (distance/angle)","radar.profile_range_v1":"Distance uniquement","radar.profile_zones_v1":"États des zones","radar.profile_presence_v1":"Présence uniquement","radar.room":"Pièce observée","radar.room_choose":"Choisir une pièce","radar.target":"Cible {n}","radar.axis_x":"Entité de coordonnée X","radar.axis_y":"Entité de coordonnée Y","radar.add_target":"Ajouter un emplacement de cible","radar.range_channel":"Canal de distance {n}","radar.add_range":"Ajouter un canal de distance","radar.presence_gate":"Entité de présence du canal","radar.swap_axes":"Permuter les axes X et Y","radar.axis_x_sign":"Direction X","radar.axis_y_sign":"Direction Y","radar.distance_source":"Entité de distance","radar.angle_source":"Entité d’angle","radar.angle_unit":"Unité d’angle","radar.degrees":"Degrés","radar.radians":"Radians","radar.angle_zero":"Direction de l’angle zéro","radar.angle_forward":"Vers l’avant","radar.angle_right":"Vers la droite","radar.angle_clockwise":"Les angles augmentent dans le sens horaire","radar.zone_source":"Entité de zone","radar.occupancy_source":"Entité de présence","radar.count_source":"Entité du nombre de cibles","radar.availability_source":"Entité de disponibilité","radar.source_choose":"Choisir une entité","radar.source_optional":"Facultatif","radar.source_missing":"actuellement indisponible","radar.saved_unsupported":"Cette configuration radar enregistrée est incomplète ou non prise en charge. Elle reste inactive ; supprimez-la ou mettez House Plan à jour avant de la reconfigurer.","radar.occupancy":"Présence (activée/désactivée)","radar.count":"Nombre","radar.mount":"Position et direction","radar.mount_hint":"Il s’agit de la position physique du capteur. Déplacer son marqueur décoratif ne la modifie pas.","radar.heading":"Direction, °","radar.range_cm":"Portée, cm","radar.fov_deg":"Champ de vision, °","radar.unit":"Unité de la source","radar.mirror":"Inverser l’axe gauche/droite","radar.remove":"Supprimer les paramètres radar","radar.invalid":"Renseignez la pièce, les sources et la position du radar avant d’enregistrer.","radar.check_sources":"Vérifier les données en direct","radar.checking":"Vérification…","radar.health":"État de la connexion","radar.live_summary":"Cibles actuelles : {targets} ; arcs de distance : {ranges}","radar.health_ok":"Données actuelles reçues","radar.health_off":"Aucune cible détectée","radar.health_stale":"Certaines coordonnées sont obsolètes","radar.health_partial":"Certaines sources sont à jour, d’autres sont obsolètes","radar.health_restricted":"L’accès à une ou plusieurs sources est limité","radar.health_incomplete":"Le rapport radar actuel est incomplet","radar.health_position_unavailable":"Présence signalée ; position actuelle indisponible","radar.health_unavailable":"Données du capteur indisponibles","radar.health_needs_setup":"L’installation doit être configurée","radar.health_inconsistent":"Les sources fournissent des valeurs contradictoires","radar.health_unknown":"L’état actuel est inconnu","radar.health_disabled":"Le radar est désactivé","radar.error_invalid_radar":"Vérifiez les paramètres radar.","radar.error_invalid_selection":"Sélectionnez une pièce existante et des sources valides.","radar.error_source_restricted":"Vous n’avez pas accès à toutes les sources sélectionnées.","radar.error_rate_limited":"Trop de demandes. Réessayez dans un instant.","radar.error_not_ready":"Le traitement radar n’est pas encore prêt.","radar.error_conflict":"Le plan a changé. Rouvrez la configuration radar et réessayez.","radar.error_source_unavailable":"Une ou plusieurs sources radar sélectionnées sont indisponibles.","radar.error_unsupported_capability":"Cette fonction radar n’est pas prise en charge par l’intégration installée.","radar.report_age":"il y a {seconds} s","space.show_lqi":"Afficher le signal Zigbee (LQI) à côté des appareils","space.hide_decor":"Masquer la couche décorative","space.hide_decor_tip":"Les lignes, formes, étiquettes et meubles restent à leur place — visibles dans l’éditeur d’arrière-plan, mais pas sur le plan.","space.hide_openings":"Masquer les ouvertures","space.hide_openings_tip":"Les symboles de portes, fenêtres et portails ne sont pas dessinés, mais les ouvertures continuent de fonctionner : la lumière les traverse, le soleil entre par les fenêtres et les capteurs de contact continuent de les ouvrir. L’éditeur de plan les affiche toujours.","gs.light_none":"Aucune source lumineuse","mode.plan":"Éditeur de plan","mode.devices":"Éditeur d’appareils","display.value":"Valeur + état","marker.subarea":"aucune zone, manuel","device.new":"Nouvel appareil — ouvrez son éditeur pour fermer","opening.unlock_action":"Déverrouiller","opening.lock_action":"Verrouiller","opening.lock_pending":"En cours…","title.close_editor":"Fermer l’éditeur (retour à la vue)","title.add_device":"Ajouter un appareil au plan","devbar.add":"Ajouter","devbar.rules":"Règles d’icônes","device_inbox.button":"Appareils","device_inbox.title":"Appareils sur le plan","device_inbox.search":"Rechercher appareils, entités et intégrations…","device_inbox.add_virtual":"Ajouter un appareil virtuel","device_inbox.tab_on_plan":"Sur le plan","device_inbox.tab_available":"Disponibles","device_inbox.tab_hidden":"Masqués","device_inbox.tab_readd":"De nouveau disponibles","device_inbox.only_new":"Nouveaux uniquement","device_inbox.show_entities":"Afficher les entités","device_inbox.show_hidden":"Afficher les masqués sur le plan","device_inbox.show_hidden.help":"Affiche temporairement les marqueurs masqués et désactivés sous forme de fantômes réservés à l’éditeur. La visibilité enregistrée des appareils ne change pas.","device_inbox.show_hidden.help.aria":"Aide : afficher les appareils masqués sur le plan","device_inbox.new":"Nouveau","device_inbox.find":"Trouver sur le plan","device_inbox.edit":"Modifier","device_inbox.hide":"Masquer","device_inbox.show":"Afficher","device_inbox.add":"Ajouter","device_inbox.readd":"Ajouter à nouveau","device_inbox.hide_available":"Masquer de la liste","device_inbox.show_more":"Afficher plus","device_inbox.more_actions":"Plus d'actions","device_inbox.find_hidden_hint":"Activez d'abord « Afficher les masqués sur le plan »","device_inbox.show_disabled":"Activez cette liaison dans Home Assistant avant de l'afficher","device_inbox.empty_on_plan":"Aucun appareil correspondant n'est encore sur le plan.","device_inbox.empty_available":"Aucun appareil disponible à ajouter.","device_inbox.empty_hidden":"Il n'y a aucun appareil masqué.","device_inbox.empty_readd":"Aucun appareil supprimé n'est disponible pour un nouvel ajout.","device_inbox.reason_visible_auto":"Découvert automatiquement","device_inbox.reason_visible_explicit":"Ajouté explicitement","device_inbox.reason_manual_hidden":"Masqué par l'utilisateur","device_inbox.reason_automatic_hidden":"Masqué automatiquement","device_inbox.reason_service_entry":"Entrée de registre de service uniquement","device_inbox.reason_excluded_integration":"Intégration « {integration} » exclue par les filtres de découverte","device_inbox.reason_excluded_domain":"Type d'entité non spatial","device_inbox.reason_grouped_light":"Représenté par un groupe de lumières de la pièce","device_inbox.reason_represented_by_parent":"Représenté par son appareil parent","device_inbox.reason_removed":"Précédemment retiré du plan","device_inbox.reason_available":"Disponible pour ajout au plan","device_inbox.reason_no_bound_room":"La zone HA n'est liée à aucune pièce du plan","device_inbox.status_ha_disabled":"Désactivé dans Home Assistant","device_inbox.status_orphaned":"La liaison n'existe plus dans Home Assistant","device_inbox.status_unverified":"Le registre Home Assistant est temporairement indisponible","device_inbox.saved":"Liste des appareils mise à jour","device_inbox.filters_excluded":"Intégrations exclues","device_inbox.filters_group_lights":"Regrouper les lumières de la pièce en un marqueur","device_inbox.filters_preview_appear":"apparaîtra : {count}","device_inbox.filters_preview_hide":"disparaîtra : {count}","device_inbox.filters_preview_lights":"lumières concernées : {count}","device_inbox.filters_reset":"Rétablir les recommandées","device_inbox.filters_save":"Enregistrer les filtres","device_inbox.filters_search_ph":"Ajouter une intégration…","device_inbox.filters_title":"Filtres de découverte","space.roomcard_section":"La carte de pièce affiche :","space.label_temp":"Température","space.label_hum":"Humidité","space.label_lqi":"Signal Zigbee moyen","space.label_light":"Lumières allumées/éteintes","roomcard.light_on":"Allumé","roomcard.light_off":"Éteint","roomcard.light_partial":"{on} sur {total}","toast.split_pick_inside":"Les points intermédiaires de découpe doivent se trouver à l’intérieur de la pièce","mode.decor":"Éditeur d’arrière-plan","decor.select":"Sélectionner","decor.line":"Ligne","decor.rect":"Rectangle","decor.ellipse":"Ovale","decor.text":"Texte","decor.erase":"Effacer","decor.erase_confirm_title":"Effacer l’objet ?","decor.color":"Couleur","decor.width":"Épaisseur de ligne","decor.line_style":"Style de ligne","decor.line_style_solid":"Plein","decor.line_style_dashed":"Pointillés","decor.fill":"Remplissage","decor.fill_color":"Couleur de remplissage","decor.length":"Longueur","decor.size":"Taille","decor.flip_h":"Retourner horizontalement","decor.flip_v":"Retourner verticalement","decor.angle":"Angle de rotation, °","decor.text_size":"Taille du texte","decor.backdrop_properties":"Propriétés de l’arrière-plan du plan","decor.text_title":"Étiquette de texte","decor.object_title":"Modifier {kind}","decor.text_label":"Texte","decor.live_group":"Insérer une variable HA","decor.live_entity":"Entité","decor.live_entity_ph":"choisir une entité","decor.live_attr":"Valeur","decor.live_attr_ph":"choisir l’état ou un attribut","decor.live_state":"État","decor.backdrop":"Image d’arrière-plan","decor.backdrop_hint":"Faites glisser pour déplacer ; tirez un coin pour redimensionner ; utilisez la poignée supérieure pour faire pivoter. Maj modifie les proportions ou libère l’angle.","decor.backdrop_reset":"Réinitialiser l’image","decor.backdrop_reset_done":"L’image a retrouvé sa position et sa taille d’origine","marker.icon_auto":"Auto : {icon} (selon les règles d’icônes ; choisissez-en une pour remplacer)","marker.icon_pin_auto":"Épingle","mode.plan_tip":"Éditeur de plan — la géométrie du logement : dessiner et diviser/fusionner les pièces, les associer aux zones HA, placer portes, fenêtres et portails, déplacer les cartes de pièces, régler l’échelle","mode.devices_tip":"Éditeur d’appareils — tout ce qui concerne les icônes : faire glisser pour positionner, cliquer pour modifier l’association/l’icône/l’affichage, ajouter des appareils virtuels, règles d’icônes","mode.decor_tip":"Éditeur d’arrière-plan — décoration purement visuelle sous le plan : lignes, rectangles, ovales et étiquettes de texte qui ne réagissent jamais aux clics","space.glow_enabled":"Halo des sources lumineuses","gs.glow_group":"Halo des sources lumineuses","gs.glow_base":"Obscurité de la maison","gs.glow_light":"Couleur / intensité de lumière par défaut","gs.wall_group":"Murs","gs.wall_fill":"Remplissage des murs","gs.glow_radius":"Rayon du halo","gs.glow_radius.help":"Définit le rayon général du halo en mètres ou en pieds ; le rayon propre à un appareil remplace cette valeur.","gs.glow_radius.help.aria":"Aide : rayon général du halo","gs.unit_m":"m","gs.unit_ft":"pi","marker.controls_label":"Contrôle d’autres sources lumineuses","marker.controls.help":"Avec l’action « Basculer l’état », les sources répertoriées basculent avec ce marqueur. Leur halo reste sur leurs propres marqueurs et ce lien ne transforme pas à lui seul le marqueur de contrôle en source lumineuse.","marker.controls.help.aria":"Aide : contrôler d’autres sources lumineuses","marker.controls_filter":"Rechercher des lumières et interrupteurs…","info.controls":"Contrôle","marker.glow_radius_label":"Rayon du halo","marker.glow_radius.help":"Définit le rayon du halo en mètres ou en pieds ; une valeur vide utilise le rayon des paramètres généraux.","marker.glow_radius.help.aria":"Aide : rayon du halo","markup.wallthick":"Épaisseur","markup.select":"Sélectionner","title.markup_wallthick":"Épaisseur — cliquez sur un mur pour définir son épaisseur de 0 à 100 cm.","markup.hint_wallthick":"cliquez sur un mur · Échap ferme sans appliquer","wallthick.field":"Épaisseur","wallthick.unit_cm":"cm","wallthick.unit_in":"po","wallthick.apply_room":"Appliquer à tous les murs de cette pièce","markup.draw_wall_title":"Épaisseur de chaque nouveau segment de mur (0–100 cm). Les murs partagés conservent la valeur existante.","room.queue_progress":"Pièce {current} sur {total}","toast.wall_rooms_saved":"Pièces créées : {n}","toast.wall_chain_saved":"Chaîne de murs enregistrée","toast.wallthick_pick":"Cliquez sur un mur","toast.wallthick_set":"Épaisseur du mur définie","toast.wallthick_cleared":"Épaisseur du mur supprimée","toast.physical_range":"Saisissez une valeur comprise entre {min} et {max} {unit}","toast.zero_wall_opening_conflict":"Supprimez d’abord l’ouverture sur ce segment de mur.","toast.zero_wall_ambiguous":"Le segment de mur est ambigu. Simplifiez ou ajustez la jonction.","toast.zero_wall_migration_blocked":"L’espace n’a pas été converti : {reason}. Aucune donnée n’a été modifiée.","toast.physical_angle":"Saisissez un angle de rotation compris entre 0° inclus et 90° exclu","toast.physical_limit":"L’espace a atteint la limite pour ce type de géométrie","toast.geometry_unsafe":"Modification annulée : la géométrie des murs n’a pas pu être construite en toute sécurité.","junction.limit_angle":"L'angle entre les murs est trop aigu : {actual}°, minimum {limit}°.","junction.limit_valence":"Trop de murs se rejoignent en un nœud : {actual}, maximum {limit}.","junction.limit_length":"Le segment de mur est trop court : {actual} cm, minimum {limit} cm.","junction.limit_distance":"Les murs et les nœuds sont trop proches : {actual} cm, minimum {limit} cm.","junction.limit_clearance":"Il ne reste plus d'intérieur de pièce : {actual} cm², minimum {limit} cm².","junction.limit_check_failed":"La vérification des jonctions n'a pas pu s'exécuter — la modification n'a pas été enregistrée","toast.wall_model_migration_blocked":"Le modèle de murs n’a pas pu être mis à jour : {reason}. Le plan n’a pas été modifié. Lancez « Optimiser les plans » ; si l’erreur se reproduit, corrigez la géométrie de mur conflictuelle.","toast.wall_model_client_outdated":"Mettez à jour la carte et rechargez la page avant de modifier le plan.","wall_model.reason.invalid-room":"contour de pièce invalide","wall_model.reason.zero-length":"segment de mur de longueur nulle","wall_model.reason.third-owner":"mur partagé par plus de deux pièces","wall_model.reason.duplicate-id":"identifiants de mur en conflit","wall_model.reason.thickness-conflict":"valeurs d’épaisseur de mur en conflit","wall_model.reason.opening-host":"l’ouverture ne peut pas être attribuée à un seul mur","toast.delete_room_pick":"Cliquez à l’intérieur de la pièce que vous souhaitez supprimer","toast.plan_snap_ambiguous":"Zoomez pour choisir le nœud du mur","toast.wall_repair_ambiguous":"Le contour de la pièce possède plusieurs connexions possibles. Zoomez et reliez-le explicitement.","toast.wall_repair_too_large":"L’écart dépasse 2 cm. Reliez les murs avant de créer la pièce.","toast.wall_repair_changed":"La géométrie des murs a changé. Essayez de créer de nouveau la pièce.","toast.opening_on_zero_wall":"Les ouvertures ne peuvent pas être placées sur un mur d’épaisseur nulle","marker.from_ha_option":"Choisir dans la liste HA","marker.show_entities":"Afficher les entités","marker.show_entities_tip":"Ajoute à la liste non seulement les appareils, mais aussi toutes leurs entités","marker.pick_ph":"Choisir un appareil…","room.open_area":"Ouvrir la zone HA","room.fit_action":"Ajuster la pièce {name}","view.volumetric":"Vue volumétrique","view.flat":"Vue plane","kiosk.title":"Tailles pour cet écran","kiosk.hint":"Enregistrées uniquement sur cet appareil — chaque tablette murale ou TV peut avoir ses propres tailles confortables.","kiosk.icon_scale":"Taille des icônes d’appareils","kiosk.font_scale":"Taille du texte des cartes de pièces","editor.kiosk":"Mode appareil mural (kiosque)","editor.cycle":"Changer automatiquement d’espace toutes les N secondes (kiosque, 0 = désactivé)","room.settings_title":"Paramètres de la pièce","room.settings_section":"Paramètres de la pièce (remplacent ceux de l’espace)","room.fill_label":"Remplissage de CETTE pièce","fill.inherit":"Comme l’espace","room.custom_fill_space":"Couleur de l’espace","room.custom_fill_own":"Couleur de la pièce","room.temp_range_label":"Plage de confort","room.temp_range_min":"Limite basse de température confortable","room.temp_range_max":"Limite haute de température confortable","room.temp_range_reset":"Comme l’espace","room.temp_range.help":"Cette plage s’applique uniquement à cette pièce. Un champ vide hérite de la limite correspondante de l’espace ; si les limites sont inversées, House Plan utilise la plus petite comme limite basse et la plus grande comme limite haute.","room.temp_range.help.aria":"À propos de la plage de confort de la pièce","room.temp_src_label":"Source de température","room.hum_src_label":"Source d’humidité","room.src_average":"Moyenne des capteurs de la pièce (par défaut)","room.src_pick":"Un appareil ou une entité HA spécifique","room.src_ph":"Choisir une source…","toast.room_updated":"Pièce mise à jour","space.card_font":"Taille de police des cartes de pièces (tout l’espace)","room.sizes_section":"Tailles de police","room.name_scale":"Taille du nom de la pièce","room.label_scale":"Taille des mesures","preview.room_name":"Salon","toast.cfg_reload_failed":"Impossible de recharger le plan depuis le serveur : {err}","toast.locale_load_failed":"Impossible de charger le pack de langue. L'anglais est utilisé jusqu'au rechargement de la page.","toast.furniture_art_load_failed":"Impossible de charger les dessins de meubles. Rechargez la page pour les afficher.","room.settings_short":"Paramètres de la pièce","room.unnamed":"Pièce sans nom","marker.use_climate_temp":"Inclure la température de l’appareil dans la pièce","marker.use_climate_temp_tip":"Ajoute la valeur current_temperature d’un climatiseur ou thermostat à la moyenne de la pièce. Configurez séparément le badge de valeur externe ci-dessous.","marker.value_badge_title":"Badge de valeur","marker.value_badge.help":"Affiche une valeur sélectionnée à côté de l’icône. Cela n’affecte pas les mesures de la pièce, la lumière, le halo ni l’action au toucher.","marker.value_badge.help.aria":"Aide : badge de valeur de l’appareil","marker.value_badge_enabled":"Afficher un badge de valeur","marker.value_badge_source":"Valeur","marker.value_badge_source.help":"Choisissez un état précis, un attribut pris en charge ou une valeur dérivée de cet appareil.","marker.value_badge_source.help.aria":"Aide : source du badge de valeur","marker.value_badge_position":"Position","marker.value_badge_position.help":"Le côté choisi reste fixe et ne bascule pas automatiquement au bord du plan.","marker.value_badge_position.help.aria":"Aide : position du badge de valeur","marker.value_badge_right":"À droite","marker.value_badge_bottom":"En dessous","marker.value_badge_left":"À gauche","marker.value_badge_top":"Au-dessus","marker.value_badge_empty":"Cet appareil n’a aucune valeur disponible","marker.value_badge_static":"Une icône statique n’affiche pas de valeurs en direct. Le paramètre est conservé.","marker.value_badge_missing":"Source indisponible","marker.value_badge_missing_hint":"La source enregistrée est actuellement indisponible. Conservez-la, désactivez le badge ou choisissez une autre valeur.","marker.value_badge_duplicate":"La même valeur est déjà affichée dans l’icône.","marker.value_badge_state":"État · {name}","marker.value_badge_marker_state":"État de la source lumineuse · {name}","marker.value_badge_lqi":"Qualité moyenne du signal Zigbee","marker.value_badge_attr_current_temperature":"Température actuelle · {name}","marker.value_badge_attr_temperature":"Température cible · {name}","marker.value_badge_attr_current_humidity":"Humidité actuelle · {name}","marker.value_badge_attr_humidity":"Humidité · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Vitesse · {name}","marker.value_badge_attr_brightness":"Luminosité · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Batterie · {name}","marker.value_badge_attr_fan_speed":"Vitesse du ventilateur · {name}","marker.value_source":"Source de la valeur","marker.value_source.help":"Choisissez la valeur qui remplace l’icône. L’action au toucher ne change pas.","marker.value_source.help.aria":"Aide : source de la valeur dans le marqueur","marker.value_source_auto":"Automatique (comme avant)","marker.value_source_missing_hint":"La source enregistrée est indisponible. Le marqueur affiche — jusqu’à son retour ou jusqu’au choix d’une autre valeur.","marker.light_role_label":"Cet appareil est-il une source lumineuse ?","marker.light_role.help":"« Auto » utilise le rôle déterminé de l’appareil lié, « Toujours » force sa propre source et « Jamais » l’exclut ; les lumières liées ci-dessus restent indépendantes.","marker.light_role.help.aria":"Aide : cet appareil est-il une source lumineuse","marker.light_role_auto_yes":"Auto (source lumineuse)","marker.light_role_auto_no":"Auto (pas une source lumineuse)","marker.light_role_always":"Toujours une source lumineuse","marker.light_role_never":"Jamais une source lumineuse","marker.light_entity_label":"Entité lumineuse principale","marker.light_entity.help":"Pour un appareil composite, choisissez l’entité dont l’état, la couleur et la luminosité représentent cette source sur le plan. Le choix automatique reste compatible avec les anciens plans.","marker.light_entity.help.aria":"Aide : entité lumineuse principale","marker.light_entity_auto":"Automatique ({entity})","marker.light_entity_none":"aucune entité contrôlable","marker.light_entity_missing":"L’entité enregistrée {entity} est indisponible. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.toggle_entity_label":"Entité à basculer","marker.toggle_entity.help":"Pour un appareil composite, choisissez précisément la lumière ou l’interrupteur propre à actionner par un toucher. Automatique conserve les règles de cible précédentes et reste indépendant de l’entité lumineuse principale.","marker.toggle_entity.help.aria":"Aide : entité à basculer","marker.toggle_entity_auto":"Automatique ({entity})","marker.toggle_entity_none":"aucune entité propre contrôlable","marker.toggle_entity_missing":"L’entité enregistrée {entity} ne fait plus partie des canaux sélectionnables de ce marqueur. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.glow_color_label":"Couleur et luminosité du halo","marker.glow_mode.help":"Utilisez les valeurs en direct de la source, remplacez uniquement sa couleur ou fixez à la fois la couleur et la luminosité. Le minimum est 1 % ; pour désactiver la source, choisissez « Jamais ».","marker.glow_mode.help.aria":"Aide : couleur et luminosité du halo","marker.glow_mode_auto":"Depuis la source","marker.glow_mode_color":"Définir la couleur","marker.glow_mode_fixed":"Définir la couleur et la luminosité","marker.glow_color":"Couleur du halo","marker.glow_brightness":"Luminosité","marker.glow_disabled_never":"Les paramètres du halo sont indisponibles car ce marqueur est explicitement défini comme n’étant pas une source lumineuse.","marker.glow_disabled_auto":"Le mode Auto n’a trouvé aucune source lumineuse spatiale pour ce marqueur.","marker.glow_disabled_no_entity":"Aucune entité Home Assistant contrôlable et active n’est disponible pour cette source spatiale.","marker.glow_passive_hint":"Cette source ne possède aucune donnée Home Assistant propre. Définissez manuellement sa couleur et sa luminosité ; son rayon reste disponible.","marker.control_broken":"La source enregistrée est absente ou n’est plus marquée comme lumière","marker.control_missing_label":"Lumière du plan manquante","marker.control_passive":"source passive","toast.marker_control_cycle":"Ce lien créerait une chaîne circulaire de contrôles de lumière.","toast.marker_binding_required":"Choisissez un appareil Home Assistant avant de lier une autre source lumineuse.","confirm.unlock_title":"Déverrouiller ?","confirm.unlock_body":"House Plan enverra une commande de déverrouillage à cette serrure.","toast.files_migrate_failed":"Les pièces jointes n’ont pas pu être déplacées vers la nouvelle association ; les liens continuent de pointer vers les anciens fichiers : {err}","space.pick_saved":"Déjà importé","space.pick_saved_hint":"Plans stockés sur le serveur, y compris ceux que vous avez précédemment dissociés","space.no_saved":"Aucun plan n’est encore stocké sur le serveur.","space.loading":"Chargement…","space.used_by":"utilisé par : {list}","space.in_use":"Un espace utilise encore ce plan — dissociez-le d’abord","btn.use":"Utiliser","confirm.delete_plan_title":"Supprimer le fichier du plan ?","confirm.delete_plan_body":"Le fichier sera supprimé du serveur. Cette action est irréversible.","toast.plans_list_failed":"Impossible de lister les plans stockés : {err}","toast.plan_delete_failed":"Impossible de supprimer le plan : {err}","marker.hide":"Masquer","marker.hide_tip":"L’appareil disparaîtra du plan après l’enregistrement mais continuera de compter dans le signal de la pièce. Restaurez-le via « Masqués et désactivés » dans l’éditeur d’appareils.","marker.show":"Afficher","marker.show_tip":"L’appareil apparaîtra de nouveau sur le plan après l’enregistrement.","marker.hidden_ghost":"Appareil masqué par l’utilisateur","marker.ha_disabled_device":"L’appareil est désactivé dans Home Assistant et masqué du plan.","marker.ha_disabled_entity":"L’entité est désactivée dans Home Assistant et masquée du plan.","marker.ha_disabled_all_entities":"L’appareil n’a aucune entité Home Assistant active ; il est donc masqué du plan.","marker.ha_registry_limited":"Le registre Home Assistant complet n’est pas accessible à cet utilisateur. L’objet non vérifié ne peut pas être affiché ni utilisé pour le moment.","marker.delete_tip":"Supprimer complètement l’appareil du plan et de tous les agrégats. Vous pourrez l’ajouter de nouveau plus tard.","tap.run":"Exécuter une automatisation/un script/une scène","tap.none":"Ne rien faire","marker.run_target_label":"Élément à exécuter","marker.run_search_ph":"Rechercher : automatisation, script ou scène…","marker.run_target_gone":"Cible {id} introuvable — choisissez-en une autre","marker.tap_confirm":"Demander une confirmation","marker.tap_confirm_tip":"Afficher une boîte de dialogue de confirmation avant l’action — protection contre les appuis accidentels.","marker.toggle_hint_single":"Cible : {name} ({id}).","marker.virtual_light_target":"Lumière virtuelle : {name}.","marker.virtual_light_current":"État manuel : {state} → {effect}.","marker.virtual_light_state_on":"allumé","marker.virtual_light_state_off":"éteint","marker.toggle_hint_group":"Basculera {count} source(s) : {names}.","marker.toggle_hint_current":"Actuellement : {state} → {effect}.","marker.toggle_hint_group_current":"Actuellement allumées : {on} sur {count} → {effect}.","marker.toggle_hint_skipped":"Seront ignorées ({count}) : {targets}.","marker.toggle_effect_turn_on":"sera allumé","marker.toggle_effect_turn_off":"sera éteint","marker.toggle_effect_open":"sera ouvert","marker.toggle_effect_close":"sera fermé","marker.toggle_effect_stop":"sera arrêté","marker.toggle_effect_toggle":"l’état sera basculé","marker.toggle_skip_missing":"introuvable","marker.toggle_skip_ha_disabled":"désactivé dans HA","marker.toggle_skip_unavailable":"indisponible","marker.toggle_skip_unsupported":"basculement non pris en charge","marker.toggle_skip_secure":"bloqué pour des raisons de sécurité","marker.toggle_none_no_binding":"Cet appareil n’a aucune association ; il n’y a donc aucun état à basculer. Un toucher ne fera rien.","marker.toggle_none_no_actionable_entity":"Cet appareil n’a aucun état pouvant être basculé. Un toucher ne fera rien.","marker.toggle_none_configured_targets_missing":"Les cibles configurées sont indisponibles. L’entité propre de l’appareil ne leur sera pas substituée.","marker.toggle_none_ha_disabled":"La cible est désactivée dans Home Assistant et ne peut pas être utilisée sur le plan.","marker.toggle_none_unavailable":"La cible est actuellement indisponible. Un toucher ne fera rien.","marker.toggle_none_unsupported":"Home Assistant n’expose aucune opération de basculement sûre pour cette entité. Un toucher ne fera rien.","marker.toggle_none_secure":"Le basculement des serrures, alarmes et portails sécurisés depuis le plan est bloqué pour des raisons de sécurité.","run.automation":"automatisation","run.script":"script","run.scene":"scène","confirm.tap_run":"Exécuter « {name} » ?","confirm.tap_toggle":"Basculer « {name} » ?","confirm.current_state":"État actuel : {state}","confirm.expected_state":"Après basculement : {state}","confirm.group_current":"{on} allumé(s) sur {total}","confirm.group_all_on":"tout est allumé","confirm.group_all_off":"tout est éteint","confirm.unavailable_targets":"Indisponibles : {count}","confirm.expected_by_ha":"Home Assistant déterminera l’état","confirm.state_on":"Allumé","confirm.state_off":"Éteint","confirm.state_open":"Ouvert","confirm.state_closed":"Fermé","confirm.state_opening":"Ouverture en cours","confirm.state_closing":"Fermeture en cours","confirm.state_stopped":"Arrêté","confirm.state_unknown":"Inconnu","toast.run_started":"Démarré : {name}","toast.run_target_missing":"Cible d’exécution introuvable — vérifiez les paramètres de l’appareil","toast.run_target_required":"Choisissez une automatisation, un script ou une scène","toast.tap_target_changed":"La cible de l’action a changé. Réessayez.","toast.virtual_light_toggle_failed":"Impossible de basculer la lumière virtuelle : {err}","toast.value_badge_source_required":"Choisissez une valeur pour le badge","btn.run":"Exécuter","vac.section":"Robot aspirateur : position en direct","vac.autocal":"Configurer automatiquement","vac.live":"Position en direct sur le plan","vac.trail":"Afficher le trajet du robot","vac.autocal_no_rooms":"L’intégration ne fournit aucune liste de pièces — ouvrez « Ajuster manuellement »","vac.route_warn_unmapped":"Le robot nettoie une carte qui n'est assignée à aucun étage","vac.route_warn_needs_calibration":"La carte est assignée à un étage mais n'est pas calibrée","vac.route_warn_ambiguous":"Deux cartes sont indiscernables — aucun étage choisi","vac.route_warn_missing_space":"L'espace de cette carte a été supprimé","vac.autocal_no_match":"Les noms de pièces ne correspondent pas (il en faut ≥3 en commun) — ouvrez « Ajuster manuellement »","vac.autocal_done":"Terminé : association via {rooms} pièces. Lancez un nettoyage et vérifiez","vac.cal_need_pos":"Le robot ne transmet pas de coordonnées — lancez un nettoyage puis mettez-le en pause","vac.cal_done":"Calibration enregistrée. Lancez un nettoyage et vérifiez","vac.cal_cancelled":"Calibration annulée","vac.fit":"Ajuster manuellement","vac.fit_hint":"Faites glisser la carte du robot pour la positionner, étirez-la par les coins","vac.fit_rotate":"Rotation de 90°","vac.fit_mirror":"Miroir","vac.trail_never":"Jamais","vac.trail_cleaning":"Pendant le nettoyage","vac.trail_always":"Toujours","gs.bg_group":"Arrière-plan de la scène","gs.bg_color":"Arrière-plan autour du plan","gs.bg_default":"Valeur par défaut du thème","gs.bg_theme":"valeur par défaut du thème","gs.bg_mode":"Arrière-plan du plan","gs.bg_mode.help":"« Suit le soleil » utilise sun.sun ou, à défaut, l’heure locale du navigateur ; « Couleur statique » affiche toujours la couleur choisie.","gs.bg_mode.help.aria":"Aide : arrière-plan général du plan","gs.bg_static":"Couleur statique","gs.bg_daynight":"Suit le soleil","gs.sun_group":"Soleil","gs.sun_missing":"L’entité sun.sun est introuvable — l’arrière-plan suit votre heure locale ; les rayons de soleil par les fenêtres sont indisponibles.","gs.north":"Nord sur le plan","gs.north.help":"L’angle se mesure dans le sens horaire depuis la verticale supérieure du plan ; le nord sert aux rayons des fenêtres, pas à l’arrière-plan « Suit le soleil ».","gs.north.help.aria":"Aide : direction générale du nord","gs.north_ph":"non défini","gs.north_clear":"Effacer","gs.north_letter":"N","gs.sun_rays":"Lumière du soleil à travers les fenêtres","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · documentation et problèmes","gs.about_telegram":"Discussion Telegram","support.title":"Aide et commentaires","space.bg_color":"Arrière-plan autour du plan","space.bg_inherit":"Hériter des paramètres généraux","space.bg_inherited":"hérite des paramètres généraux","space.bg_mode":"Arrière-plan du plan","space.bg_mode.help":"Héritez de l’arrière-plan général ou remplacez-le pour cet espace par une couleur statique ou le mode « Suit le soleil ».","space.bg_mode.help.aria":"Aide : arrière-plan de l’espace","space.north":"Nord sur le plan (remplacement)","space.north.help":"Remplace le nord général pour cet espace ; l’angle se mesure dans le sens horaire depuis la verticale supérieure du plan et sert aux rayons des fenêtres.","space.north.help.aria":"Aide : nord de cet espace","space.north_inherited":"hérité : {v}","space.sun_rays":"Lumière du soleil à travers les fenêtres","space.sun_inherit":"Hériter des paramètres généraux","space.sun_on":"Activé","space.sun_off":"Désactivé","canvas.far_objects":"{n} objet(s) éloigné(s) du plan","canvas.show_far":"Afficher","canvas.home_tip":"Le plan est là-bas — cliquez pour l’ajuster à l’écran","gs.grid_group":"Maintenance du plan","gs.grid_hint":"Met à jour les modèles de données, aligne les éléments du plan sur la grille et fusionne les fragments de murs redondants. Un rapport précis est affiché avant tout enregistrement.","gs.align_all":"Optimiser les plans","gs.align_title":"Optimiser les plans","gs.align_none":"Tous les plans utilisent déjà le modèle de données optimisé actuel.","gs.optimize_no_automatic_changes":"Aucune modification automatique n’est à appliquer. Vérifiez les éléments ci-dessous.","gs.align_count":"{n} élément(s) sur {total} seront déplacés, de {cm} cm au maximum.","gs.align_where":"Le plus grand déplacement se trouve dans « {s} ».","gs.align_turned":"Ouvertures dont l’angle est corrigé : {n}.","gs.align_preflight_failed":"Impossible de vérifier en toute sécurité la géométrie des espaces suivants : {spaces}{more}.","gs.align_preflight_hint":"Les plans n’ont pas été modifiés. Copiez les diagnostics avec le bouton ci-dessous et joignez-les au rapport de bug avec un export de l’espace.","gs.preflight_reason_prepare-exception":"Impossible de préparer la géométrie de l’espace (exception lors de la construction du modèle)","gs.preflight_reason_wall-null":"Le corps du mur n’a pas pu être construit (l’union a renvoyé un résultat vide)","gs.preflight_reason_wall-degraded-extra":"Le corps du mur s’est dégradé avec une géométrie supplémentaire","gs.preflight_reason_wall-failed-core":"Le noyau du corps du mur n’a pas pu être assemblé","gs.preflight_reason_wall-exception":"La construction du mur a déclenché une exception","gs.preflight_reason_floor-null":"Le contour du sol n’a pas pu être construit","gs.preflight_reason_floor-exception":"La construction du sol a déclenché une exception","gs.preflight_copy":"Copier les diagnostics","gs.preflight_copied":"Diagnostics copiés","gs.preflight_update_hint":"Les versions de la carte et de l’intégration diffèrent — mettez House Plan à jour puis réessayez.","gs.align_preflight_space":"Espace {n}","gs.align_preflight_more":", et {n} de plus","gs.optimize_changes":"Migrations de modèle : {m} ; espaces mis à jour : {c} ; valeurs de coordonnées parasites supprimées : {p} ; fragments de murs réels fusionnés : {w} ; fragments de murs d’épaisseur nulle fusionnés : {s} ; murs indépendants : {i}.","gs.zero_walls_migrated":"Portions de murs virtuels converties : {n}.","gs.wall_segments_migrated":"Segments de murs stabilisés : {n}.","gs.room_drafts_migrated":"Contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","gs.optimize_lattice_summary":"Valeurs de coordonnées parasites normalisées : {n} ; déplacement maximal : {cm} cm.","gs.optimize_lattice_space":"{space} : valeurs de coordonnées normalisées : {n} ; valeurs hors grille laissées inchangées : {far}.","gs.optimize_coincident_partitions":"Sections de murs indépendants masquées absorbées dans les murs des pièces : {n}.","gs.optimize_openings_rehosted":"Ouvertures rattachées aux murs des pièces : {n}.","gs.optimize_walls_straightened":"Murs redressés : {n} ; déplacement maximal : {cm} cm.","gs.optimize_walls_straightened_where":"Plus grande correction de mur : {s}.","gs.optimize_walls_straighten_skipped":"Murs proches d’un axe laissés inchangés car ils ne pouvaient pas être réparés en toute sécurité : {n}.","gs.optimize_glow_migration":"Ancien mode Glow : {spaces} espaces → aucun remplissage de données + Glow indépendant ; {rooms} pièces → remplissage de données hérité + Glow indépendant.","gs.optimize_references":"Références réparées : espaces — {spaces} ; pièces — {rooms} ; positions — {positions} ; appareils dissociés des espaces manquants — {detached}.","gs.optimize_reference_more":", et {n} de plus","gs.optimize_orphans_removed":"Enregistrements oubliés supprimés : {total} — étiquettes de pièces : {rooms} ; appareils : {devices} ; marqueurs de groupe : {groups}. Ils appartenaient à des espaces supprimés précédemment.","gs.optimize_live_positions":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles seront conservées.","gs.optimize_live_positions_remove":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles sont sélectionnées pour suppression.","gs.optimize_live_names":" : {names}{more}","gs.optimize_live_remove":"Supprimer les anciennes positions","gs.optimize_live_keep":"Conserver les anciennes positions","gs.optimize_live_selected":"Les anciennes positions seront supprimées après l’application de l’optimisation.","gs.optimize_unverified":"Impossible de vérifier en toute sécurité les positions : {n}. Elles ont été laissées inchangées.","gs.optimize_registry_limited":"Un accès administrateur complet aux registres Home Assistant est requis pour une vérification sûre.","gs.optimize_vacuum_warning":"Associations de pièces d’aspirateur nécessitant encore une vérification : {n}.","gs.optimize_details":"Détails","gs.optimize_details_more":"Et {n} enregistrement(s) de plus.","gs.optimize_detail_removed":"sera supprimé","gs.optimize_detail_live":"sera conservé","gs.optimize_detail_unverified":"non vérifié","gs.optimize_detail_room_label":"étiquette de pièce","gs.optimize_detail_device":"appareil","gs.optimize_detail_group":"marqueur de groupe","gs.optimize_detail_unknown":"propriétaire inconnu","gs.optimize_detail_item":"{status} : {kind} {id} ; ancien espace {space}","gs.align_warn":"Les éléments volontairement placés entre les nœuds de la grille seront déplacés. Une seule annulation est disponible après l’opération, uniquement jusqu’à la prochaine modification du plan.","gs.align_run":"Optimiser","gs.align_done":"Plans optimisés : {n} élément(s) déplacé(s), {m} enregistrement(s) maintenu(s), {r} référence(s) réparée(s)","gs.optimize_undo":"Annuler la dernière optimisation","gs.optimize_undone":"La dernière optimisation a été annulée","decor.furniture":"Mobilier","decor.image":"Image","decor.image_title":"Images personnalisées","decor.image_upload":"Importer une image","decor.image_replace":"Remplacer l’image","decor.image_uploading":"Importation…","decor.image_asset":"Fichier image","decor.image_pick_hint":"Importez une image ou choisissez-en une existante.","decor.image_place_hint":"Cliquez sur le plan pour placer l’image.","decor.image_none":"Aucune image importée pour le moment.","decor.image_unavailable":"Image indisponible","decor.image_used":"Utilisée dans {n} objets","decor.image_upload_failed":"Impossible d’importer l’image : {err}","decor.image_error_capacity":"Le stockage des images personnalisées est plein.","decor.image_in_use":"Supprimez toutes les copies placées avant ce fichier.","decor.image_delete_title":"Supprimer le fichier image ?","decor.image_delete_message":"Supprimer « {name} » de House Plan ? Cette action est irréversible.","furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis","common.yes":"Oui","common.no":"Non","vac.diag_source":"Source","vac.diag_platform":"Intégration","vac.diag_status":"État","vac.diag_position":"Position","vac.diag_rooms":"Pièces","vac.diag_rooms_value":"{total} · {matched} noms correspondent · {readiness}","vac.autocal_ready":"calibration automatique disponible","vac.autocal_not_ready":"3 noms correspondants requis","vac.diag_path":"Chemin de l’intégration","vac.diag_map":"ID de carte","vac.source_none":"non sélectionné","vac.source_status_ok":"Prêt","vac.source_status_missing":"Manquant","vac.source_status_disabled":"Désactivé dans Home Assistant","vac.source_status_unavailable":"Indisponible","vac.source_status_unverified":"Impossible à vérifier avec les autorisations actuelles","vac.source_status_unsupported":"Aucune donnée de position","vac.source_status_none":"Aucune source","vac.source_banner_missing":"La source enregistrée n’existe plus. Elle n’a pas été remplacée automatiquement ; choisissez une autre source ou restaurez-la dans Home Assistant.","vac.source_banner_disabled":"La source enregistrée est désactivée dans Home Assistant. Activez-la ou choisissez une autre source.","vac.source_banner_unverified":"Les autorisations Home Assistant actuelles ne permettent pas de vérifier cette source enregistrée. Elle reste épinglée et ne sera pas remplacée automatiquement.","vac.choose_source":"Choisir la source","vac.source_auto":"Automatique","vac.source_auto_hint":"Utiliser une entité compatible de cet appareil","vac.all_cameras":"Toutes les caméras","vac.all_cameras_warn":"Une caméra peut ne pas fournir de données du robot. Choisissez-en une uniquement s’il s’agit de la carte de votre aspirateur.","vac.all_cameras_empty":"Aucune autre entité caméra trouvée.","vac.platform_unknown":"intégration inconnue","vac.cap_position":"position","vac.cap_rooms_short":"pièces","vac.cap_path":"trajet","vac.cap_map":"ID de carte","vac.cap_none":"aucune donnée de robot détectée","vac.xcme_hint":"Activez ces attributs Xiaomi Cloud Map Extractor :","vac.documentation":"Documentation","vac.residual_title":"Vérifier la calibration automatique","vac.residual_message":"Les pièces correspondantes présentent un écart maximal de {error}. Appliquez cette calibration approximative, affinez-la manuellement ou annulez sans modifier la configuration enregistrée.","vac.apply_proposal":"Appliquer","gs.backup_group":"Sauvegarde et transfert","gs.backup_hint":"Téléchargez une sauvegarde JSON portable ou prévisualisez et importez une sauvegarde créée par House Plan.","backup.export_open":"Exporter","backup.import_open":"Importer","backup.export_title":"Exporter House Plan","backup.import_title":"Importer House Plan","backup.export_hint":"Choisissez si la sauvegarde doit contenir toute la configuration House Plan ou uniquement l’espace actuel.","backup.full":"Sauvegarde complète","backup.current_space":"Espace actuel","backup.current_space_title":"Espace actuel : {title}","backup.no_current_space":"Aucun espace actuel","backup.plan_only":"Plan uniquement","backup.plan_only_hint":"Conserver les pièces, murs, ouvertures, décorations et positions des étiquettes de pièces sans les appareils ni les associations Home Assistant.","backup.plan_only_preview":"Ce fichier contient uniquement le plan","backup.privacy_warning":"L’archive conserve les noms, identifiants Home Assistant et coordonnées exactes. Les plans internes et pièces jointes sont référencés, pas intégrés ; les états d’exécution et trajets d’aspirateur ne sont pas inclus.","backup.download":"Télécharger le JSON","backup.export_done":"Sauvegarde téléchargée","backup.reading":"Vérification de la sauvegarde…","backup.revalidated":"Le plan a changé depuis cet aperçu. Le résumé a été actualisé ; vérifiez-le et confirmez de nouveau.","backup.error.support_invalid_message":"Vérifiez le message d’assistance et réessayez.","backup.error.support_package_too_large":"Le paquet d’assistance anonymisé dépasse la limite de 8 Mio.","backup.error.support_preview_expired":"L’aperçu de la pièce jointe d’assistance a expiré ou n’est plus disponible.","backup.error.support_rate_limited":"Trop de rapports ou d’aperçus d’assistance ont été demandés. Réessayez plus tard.","backup.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","backup.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible.","backup.error.unauthorized":"Vous n’avez pas l’autorisation d’exporter ou d’importer ce plan.","backup.error.not_ready":"House Plan n’est pas encore prêt. Réessayez dans un instant.","backup.error.too_large":"La sauvegarde dépasse la limite de 8 Mio.","backup.error.invalid_json":"Le fichier sélectionné n’est pas un JSON valide.","backup.error.invalid_format":"Le fichier sélectionné n’est pas une sauvegarde House Plan.","backup.error.invalid_image":"L’image est endommagée ou ne correspond pas à son format.","backup.error.unsupported_export_version":"Ce format de sauvegarde n’est pas pris en charge par la version installée.","backup.error.unsupported_image":"Utilisez une image PNG, JPEG, WebP ou SVG prise en charge.","backup.error.future_model":"La sauvegarde a été créée avec un modèle de données House Plan plus récent.","backup.error.invalid_config":"La sauvegarde contient une configuration House Plan invalide.","backup.error.wall_model_migration_blocked":"Le modèle de murs de la sauvegarde n’a pas pu être mis à niveau en toute sécurité. Optimisez d’abord le plan source, puis exportez-le de nouveau.","backup.error.invalid_layout":"La sauvegarde contient des positions d’objets invalides.","backup.error.invalid_content":"La sauvegarde contient des références de contenu invalides ou incohérentes.","backup.error.space_not_found":"L’espace sélectionné n’existe plus.","backup.error.capacity_exceeded":"L’ajout de cette sauvegarde dépasserait les limites du plan.","backup.error.preview_expired":"L’aperçu a expiré. Sélectionnez de nouveau le fichier de sauvegarde.","backup.error.preview_owner_mismatch":"Cet aperçu appartient à un autre utilisateur Home Assistant.","backup.error.conflict":"Le plan a changé depuis l’aperçu. Vérifiez le résumé actualisé.","backup.error.content_confirmation_required":"Confirmez que le contenu local indisponible peut être dissocié.","backup.error.commit_failed":"La sauvegarde n’a pas pu être appliquée en toute sécurité. Le plan précédent a été restauré ou est en attente de récupération.","backup.error.missing_plan":"Un fichier de plan référencé a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.missing_content":"Une pièce jointe locale référencée a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.marker_control_missing":"Une lumière liée au plan est absente de la sauvegarde.","backup.error.marker_control_not_light":"Une cible liée au plan n’est plus marquée comme source lumineuse.","backup.error.marker_control_self":"Une source lumineuse ne peut pas se contrôler elle-même.","backup.error.marker_control_cycle":"La sauvegarde contient une chaîne circulaire de contrôles de lumière.","backup.error.duplicate_marker_control":"La sauvegarde contient un lien de lumière du plan en doublon.","backup.error.no_backup":"Aucun instantané d’importation ou d’optimisation n’est disponible à restaurer.","backup.error.in_use":"L'élément est encore utilisé","backup.error.invalid_data":"La requête contient des données invalides","backup.error.invalid_light_entity":"La lumière principale doit être une entité light.* ou switch.*","backup.error.invalid_marker_control":"Référence de contrôle de marqueur invalide","backup.error.invalid_name":"Le nom est invalide","backup.error.invalid_partition_opening_host":"L'ouverture doit conserver sa cloison porteuse","backup.error.invalid_partition_opening_jamb_margin":"L'ouverture ne laisse aucun jambage physique au bout du mur","backup.error.invalid_passage_fields":"Un passage ouvert ne peut pas porter de réglages de porte","backup.error.invalid_space_id":"Espace inconnu","backup.error.invalid_toggle_entity":"L'entité de bascule doit être light.* ou switch.*","backup.error.invalid_value_badge":"Réglages de badge de valeur invalides","backup.error.invalid_value_badge_attribute":"Attribut de badge de valeur invalide","backup.error.invalid_value_badge_position":"Position de badge de valeur invalide","backup.error.invalid_value_badge_source":"Source de badge de valeur invalide","backup.error.invalid_vacuum_map_route":"Vérifiez l'affectation des cartes du robot aux espaces.","backup.error.invalid_value_source":"Source de valeur invalide","backup.error.invalid_value_source_attribute":"Attribut de source de valeur invalide","backup.error.io_error":"Une opération de fichier a échoué sur le serveur","backup.error.not_toggleable":"Cet appareil ne peut pas être basculé","backup.error.nothing_to_repair":"Rien à réparer","backup.error.space_in_use":"L'espace est encore référencé","backup.error.value_badge_source_required":"Le badge de valeur nécessite une source","backup.error.wall_model_client_outdated":"Le plan a été mis à jour ailleurs — rechargez la page","backup.same_source":"Créée sur cette instance Home Assistant","backup.foreign_source":"Créée sur une autre instance Home Assistant","backup.created":"Créée : {value}","backup.versions":"Carte {card} ; intégration {integration} ; modèle de données {model}","backup.count_spaces":"Espaces : {n}","backup.count_rooms":"Pièces : {n}","backup.count_walls":"Murs : {n}","backup.count_openings":"Ouvertures : {n}","backup.count_decor":"Objets décoratifs : {n}","backup.count_markers":"Appareils : {n}","backup.count_layout":"Positions : {n}","backup.bindings":"Associations — appareils : {device}, entités : {entity}, virtuels : {virtual} ; positions sans espace : {legacy}","backup.binding_status":"État des cibles — actives : {active}, désactivées : {disabled}, manquantes : {missing}","backup.missing_areas":"Zones absentes sur la cible : {areas}","backup.dropped_marker_links":"Liens de lumières du plan hors de cet espace transféré omis : {n}.","backup.room_drafts_migrated":"Anciens contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","backup.repaired_target_refs":"Références existantes restaurées par cet import d’espace : {n}.","backup.preserved_unresolved_refs":"Références qui n’ont pas pu être restaurées sans ambiguïté conservées : {n}.","backup.preserved_unresolved_hint":"Aucune donnée n’a été devinée ni supprimée. Après l’importation, lancez « Optimiser les plans » pour examiner les références restantes.","backup.import_details":"Détails des références d’importation","backup.import_detail.incoming_remapped":"Références mises à jour dans la copie importée : {n}","backup.import_detail.target_repaired":"Références existantes restaurées : {n}","backup.import_detail.preserved_unresolved":"Références non résolues conservées : {n}","backup.import_detail.collisions":"Conflits de destination conservés en toute sécurité : {n}","backup.import_detail.dropped_links":"Liens entrants omis selon les règles de transfert : {n}","backup.import_detail.bounded_lineages":"Identifiants trop imbriqués maintenus dans les limites : {n}","backup.replace_warning":"Cela remplace la configuration et la disposition actuelles. Les fichiers importés ne sont jamais supprimés. Une seule annulation reste disponible jusqu’à la prochaine modification du plan.","backup.foreign_bookkeeping":"Les données de suivi des appareils connus/nouveaux propres à l’instance ne seront pas importées.","backup.final_name":"Nom du nouvel espace","backup.target_settings":"Les paramètres généraux de l’instance cible restent inchangés.","backup.duplicates":"Associations déjà présentes : {n}","backup.skip":"Ignorer les appareils en doublon","backup.virtual_copy":"Ajouter des copies virtuelles statiques sûres","backup.content":"Contenu référencé","backup.decor_images_summary":"Images personnalisées : {objects} objets, {assets} fichiers ; fichiers absents : {missing}.","backup.content_available":"disponible localement","backup.content_external":"lien externe","backup.content_detach_required":"sera dissocié","backup.confirm_detach":"Je comprends que les plans internes et pièces jointes indisponibles seront dissociés de la configuration importée.","backup.confirm_missing_images":"Je comprends que les images personnalisées absentes resteront des espaces réservés réparables et que les autres fichiers locaux indisponibles seront dissociés.","backup.replace":"Remplacer","backup.add":"Ajouter un espace","backup.space_done":"Espace importé : {rooms} pièces, {markers} appareils, {refs} références existantes restaurées","backup.full_done":"Sauvegarde restaurée : {spaces} espaces, {rooms} pièces, {markers} appareils","backup.undo_import":"Annuler la dernière importation complète","backup.import_undone":"Importation complète annulée","backdrop.large_title":"Grande image","backdrop.large_body":"Cette image fait {w}×{h} (fichier de {fileMb} Mo) et nécessite environ {decodedMb} Mo de mémoire pour s'afficher. Sur tablette, cela peut faire planter la page.","backdrop.unknown_body":"Les dimensions de l'image n'ont pas pu être lues — le fichier est peut-être endommagé. Continuer peut faire planter la page sur tablette.","backdrop.reduced_dimensions":"Copie réduite : {w}×{h} px.","backdrop.use_downscaled":"Téléverser une copie réduite","backdrop.reducing":"Réduction…","backdrop.keep_original":"Conserver l'original","backdrop.too_large_title":"Image trop grande","backdrop.too_large_body":"Cette image dépasse ce que les navigateurs peuvent afficher ({w}×{h}, limite {limit} px par côté). Réduisez-la dans un éditeur de bureau puis téléversez-la à nouveau.","backdrop.downscale_failed":"Impossible de créer la copie réduite. Le plan actuel n'a pas été modifié."};const r="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";export{e as dictionary,r as fingerprint}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";var e={"editor.context_actions":"Actions : {object}","editor.tool_options":"Options de l’outil : {tool}","editor.palette":"Palette : {tool}","editor.open_group":"Groupe d’outils : {group}","editor.group_active":"{group} — actif : {item}","editor.disabled_action":"{action} est indisponible : {reason}","editor.loading":"Chargement de l'éditeur…","editor.loading_aria":"L'éditeur de plan est en cours de chargement","editor.load_failed":"Impossible de charger l'éditeur.","editor.refresh_advice":"Actualisez la page et réessayez.","editor.retry_advice":"Vérifiez votre connexion et appuyez à nouveau.","version_mismatch.title":"Les versions de House Plan ne correspondent pas","version_mismatch.body":"Si Home Assistant redémarre encore, attendez la fin, puis rechargez cette page.","version_mismatch.frontend":"Carte","version_mismatch.backend":"Intégration","version_mismatch.reload":"Recharger la page","color_picker.title":"Sélecteur de couleur","color_picker.hue":"Teinte","color_picker.saturation":"Saturation","color_picker.value":"Luminosité","color_picker.hex":"Couleur hexadécimale","color_picker.invalid_hex":"Saisissez une couleur hexadécimale à 3 ou 6 chiffres","color_picker.confirm":"OK","btn.properties":"Propriétés","btn.keep_as_walls":"Conserver comme murs","btn.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","btn.delete_room_with_walls":"Supprimer la pièce et les murs","title.markup_select":"Sélectionner et modifier les murs et les colonnes","title.markup_column":"Colonne : cliquez sur un point de la grille pour placer une colonne carrée","markup.partition":"Cloison","markup.column":"Colonne","markup.hint_column":"cliquez sur un point de la grille pour placer une colonne carrée","history.wall_segment":"Ajouter un segment de mur","history.column_add":"Ajouter une colonne","history.physical_edit":"Modifier l’objet physique","history.physical_delete":"Supprimer l’objet physique","history.physical_move":"Déplacer l’objet physique","history.wall_face_batch":"Créer des pièces à partir des murs","toast.column_duplicate":"Une colonne avec le même centre et la même dimension extérieure existe déjà","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.shape":"Forme","physical.square":"Carré","physical.circle":"Cercle","physical.diameter":"Diamètre","physical.side":"Côté","physical.rotation":"Angle de rotation","physical.length":"Longueur","physical.allowed_range":"Autorisé : {min}–{max} {unit}","physical.column_size_title":"Côté extérieur de la colonne carrée placée par le clic (1–150 cm).","card.title":"Plan de la maison","count.devices":"{n} app.","empty.no_spaces":"Aucun espace pour le moment.","nav.spaces":"Espaces House Plan","empty.add_first":"Ajoutez le premier espace et importez un plan.","empty.read_only":"Aucun espace n’est configuré. Demandez à un administrateur d’en ajouter un.","empty.install":"Installez l’intégration House Plan et ajoutez-la dans « Appareils et services ».","btn.add_space":"Ajouter un espace","btn.cancel":"Annuler","btn.save":"Enregistrer","btn.close":"Fermer","btn.delete":"Supprimer","btn.copy":"Copier","btn.edit":"Modifier","btn.open_in_ha":"Ouvrir dans HA","btn.reset":"Réinitialiser","btn.attach":"Joindre…","btn.upload":"Importer…","btn.replace":"Remplacer…","title.zoom_in":"Zoomer","title.zoom_out":"Dézoomer","title.zoom_fit":"Tout ajuster","title.configure_space":"Configurer l’espace","title.add_space":"Ajouter un espace","title.markup_add":"Murs : tracez une chaîne continue ; chaque segment accepté est enregistré séparément. Maj verrouille à 45°","title.markup_merge":"Fusionner : cliquez sur une pièce, puis sur la pièce voisine avec laquelle elle partage un mur","title.markup_split":"Diviser une pièce : cliquez sur la pièce, puis sur deux points de ses murs","title.markup_delroom":"Supprimer une pièce : cliquez à l’intérieur de la pièce puis confirmez","title.need_plan":"Importer une image de plan","markup.add":"Murs","markup.merge":"Fusionner","markup.split":"Diviser","markup.resize":"Redimensionner","title.markup_resize":"Redimensionner les pièces : faites glisser une poignée disponible sur un mur horizontal ou vertical","markup.hint_resize":"faites glisser une poignée de mur disponible · le mur s’arrête à la première position non sûre · Échap annule · Ctrl+Z — annuler","resize.disabled.diagonal":"Ce mur est incliné ; le redimensionnement ne prend en charge que les murs horizontaux et verticaux","resize.disabled.side-angle":"Un mur adjacent est incliné ; le redimensionnement exige que les deux murs adjacents rencontrent ce mur à angle droit","resize.disabled.duplicate-physical-wall":"Une cloison distincte ou une colonne chevauche ce mur ; supprimez-la ou déplacez-la avant de redimensionner","resize.disabled.partial-shared":"Une pièce voisine n’utilise qu’une partie de ce mur ; il ne peut donc pas être déplacé en toute sécurité comme un mur partagé unique","resize.disabled.unequal-shared":"La pièce voisine utilise des extrémités ou une longueur de mur différentes ; les murs ne peuvent donc pas être déplacés ensemble en toute sécurité","resize.disabled.multiple-rooms":"Déplacer ce mur affecterait plus de deux pièces","resize.disabled.thickness-conflict":"L’épaisseur du mur ne peut pas être conservée en toute sécurité","resize.disabled.opening-conflict":"Une ouverture sur ce mur ne peut pas être déplacée en toute sécurité","resize.disabled.invalid-geometry":"Ce mur ne peut pas être redimensionné sans modifier la structure du plan","resize.limit_stopped":"Mur arrêté : l'étape suivante enfreindrait une limite de jonction","resize.commit_failed":"Le redimensionnement a été annulé car le plan final n’a pas passé le contrôle de géométrie","resize.preview_failed":"Le redimensionnement s’est arrêté à la dernière position sûre car la géométrie du plan ne pouvait pas être préservée","markup.opening":"Ouverture","markup.delete_room":"Supprimer la pièce","history.undo":"Annuler","history.redo":"Rétablir","history.undo_named":"Annuler : {name} (Ctrl+Z)","history.redo_named":"Rétablir : {name} (Ctrl+Maj+Z / Ctrl+Y)","history.undo_empty":"Rien à annuler","history.redo_empty":"Rien à rétablir","history.undone":"Annulé : {name}","history.redone":"Rétabli : {name}","history.add_room":"Créer une pièce","history.split_room":"Diviser la pièce","history.merge_rooms":"Fusionner les pièces","history.resize_room":"Redimensionner la pièce","history.wall_thickness":"Modifier l’épaisseur du mur","history.add_opening":"Ajouter une ouverture de porte ou de fenêtre","history.edit_opening":"Modifier l’ouverture","history.move_opening":"Déplacer l’ouverture","history.delete_opening":"Supprimer l’ouverture","history.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","history.delete_room_with_walls":"Supprimer la pièce et les murs","history.decor_add":"Ajouter un objet décoratif","history.decor_edit":"Modifier l’objet décoratif","history.decor_move":"Déplacer l’objet décoratif","history.decor_transform":"Transformer l’objet décoratif","history.decor_delete":"Supprimer l’objet décoratif","history.backdrop_transform":"Transformer l’arrière-plan du plan","history.device_move":"Déplacer {name}","history.device_stale":"L’historique des positions n’est plus applicable et a été effacé","opening.new":"Nouvelle ouverture","opening.edit":"Ouverture","opening.door":"Porte","opening.window":"Fenêtre","opening.gate":"Portail","opening.passage":"Passage ouvert","opening.passage_binding_warning":"L’enregistrement supprimera le capteur d’ouverture/fermeture et la serrure.","opening.invalid_passage_fields":"Le passage ouvert du plan « {room} » possède des paramètres non pris en charge : {fields}.","opening.type_label":"Type","opening.length_label":"Longueur, cm","opening.contact_label":"Capteur d’ouverture/fermeture","opening.lock_label":"Serrure","opening.none":"— aucun —","opening.search_ph":"Rechercher : nom ou ID d’entité…","opening.invert":"Inverser ouvert/fermé","opening.flip_h":"Charnière sur l’autre montant","opening.flip_v":"Ouverture de l’autre côté","opening.open":"Ouvert","opening.closed":"Fermé","opening.locked":"Verrouillé","opening.unlocked":"Déverrouillé","opening.state_unknown":"indisponible","opening.no_entities":"Aucun capteur associé — symbole statique sur le plan.","toast.opening_no_wall":"Cliquez près d’un mur de pièce ou d’un mur indépendant","opening.host_partition":"Mur indépendant","opening.partition_orphan":"Le mur indépendant de cette ouverture n’existe plus","opening.partition_jamb_margin":"Laissez au moins {distance} entre l’ouverture et l’extrémité du mur","opening.rebind_partition":"Associer à un autre mur indépendant","confirm.delete_partition_openings_title":"Supprimer le mur et les ouvertures ?","confirm.delete_partition_openings_body":"Ce mur contient {count} ouverture(s). Elles seront supprimées avec lui.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.hint_points":"points : {n} · Maj — pas de 45° · Échap — terminer la chaîne · Ctrl+Z — annuler un point · fermer une zone propose de créer une pièce","markup.hint_start":"cliquez sur un point de la grille pour commencer une chaîne de murs","tip.lqi":"signal Zigbee moyen :","tip.area":"surface : {value}","info.device_header":"Appareil sur le plan","info.model":"Modèle","info.state":"État","info.link":"Lien","info.manuals":"Manuels","info.none":"Aucune information supplémentaire","marker.new_device":"Nouvel appareil","marker.name_label":"Nom (affiché sur le plan)","marker.name_ph":"Nom","marker.binding_label":"Associer à un appareil HA","marker.binding_disabled":"désactivé dans Home Assistant","marker.virtual_option":"Appareil virtuel (sans association)","marker.search_ph":"Rechercher un appareil / groupe…","marker.nothing_found":"aucun résultat","marker.room_label":"Pièce","marker.room_override":" (placement forcé)","marker.room_choose":"— sélectionner une pièce —","marker.room_auto":"— selon la zone de l’appareil (auto) —","marker.icon_label":"Icône","marker.icon_ph":"mdi:… (vide = auto)","marker.display_label":"Affichage","display.badge":"Icône + état","display.icon_ripple":"Icône + état et activité","display.static_icon":"Icône toujours statique","marker.display_hint_badge":"L’icône et le fond dynamique affichent l’état de l’appareil sans la pulsation d’activité habituelle. Les alarmes rouges restent visibles.","marker.display_hint_icon_ripple":"L’icône, le fond dynamique et la pulsation affichent une brève animation pour les événements et une animation continue pour le fonctionnement, le mouvement ou la présence. Les alarmes rouges restent prioritaires.","marker.display_hint_value":"Une valeur Home Assistant sélectionnée ou résolue automatiquement remplace l’icône tandis que le fond continue d’indiquer l’état. Les alarmes rouges restent visibles.","marker.display_hint_static_icon":"Le contour adapté au thème et l’icône restent toujours identiques. L’état, l’activité, l’indisponibilité et les alarmes ne modifient pas l’apparence.","marker.static_alarm_warning":"Cet appareil peut signaler des alarmes. L’affichage statique masque l’indication visuelle d’alarme du marqueur.","marker.preview.title":"Aperçu de l’affichage","marker.preview.actual":"Actuel","marker.preview.example":"Exemple","marker.preview.integration":"Fourni par","marker.preview.source":"Source d’affichage","marker.preview.current_state":"État actuel","marker.preview.result":"Sur le plan","marker.preview.details":"Détails de la source","marker.preview.select_source":"Choisissez un appareil ou une entité Home Assistant pour voir son affichage réel.","marker.preview.unknown_provider":"Intégration inconnue","marker.preview.virtual_provider":"House Plan · appareil virtuel","marker.preview.no_source":"Aucune source active","marker.preview.no_state":"Aucun état actuel","marker.preview.mixed_states":"Plusieurs états différents","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} de plus","marker.preview.scaled":"L’aperçu est redimensionné à {n}% pour tenir dans la zone. La taille enregistrée reste inchangée.","marker.preview.demo_short":"Afficher une activité brève","marker.preview.demo_continuous":"Afficher une activité continue","marker.preview.stop_continuous":"Arrêter l’activité continue","marker.preview.demo_short_notice":"Exemple d’activité brève ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_continuous_notice":"Exemple d’activité continue ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_already_visible":"L’état actuel affiche déjà un véritable effet d’activité ou d’alarme.","marker.preview.reduced_motion":"La réduction des animations est activée sur le système ; l’activité normale est donc affichée sous forme de point.","marker.preview.reason.neutral":"Fond sombre neutre","marker.preview.reason.working":"Fond jaune : l’appareil fonctionne actuellement","marker.preview.reason.working_activity":"Fond jaune et effet d’activité : l’appareil fonctionne actuellement","marker.preview.reason.open":"Fond orange : physiquement ouvert ou déverrouillé","marker.preview.reason.cover_icon_state":"Fond neutre ; l’entité de volet contrôle l’état et l’icône affichés","marker.preview.reason.presence":"Effet d’activité tant qu’une présence est détectée","marker.preview.reason.event":"Effet d’activité bref après un événement détecté","marker.preview.reason.transition":"Effet d’activité pendant que l’appareil se déplace ou change d’état","marker.preview.reason.media_neutral":"Les appareils multimédias restent sur un fond sombre neutre tant qu’ils sont disponibles","marker.preview.reason.unavailable":"Fond neutre atténué : indisponible ou éteint","marker.preview.reason.alarm":"Fond d’alarme rouge ; l’indication d’alarme est toujours affichée","marker.preview.reason.live_states_disabled":"Le style selon les états en direct est désactivé pour cette carte","marker.preview.reason.value_no_state":"Aucune valeur d’état exploitable ; l’icône est affichée à la place","marker.preview.reason.value_ambiguous_sources":"Plusieurs sources de valeur possibles ; l’icône est affichée à la place","marker.preview.reason.value_non_scalar":"La source n’a pas renvoyé de valeur simple ; l’icône est affichée à la place","marker.preview.reason.value_virtual":"Un appareil virtuel n’a aucune valeur Home Assistant ; l’icône est affichée à la place","marker.preview.reason.vacuum_live_plan_only":"La position et la trajectoire en direct de l’aspirateur ne sont disponibles que sur le plan complet","marker.preview.reason.hidden_design_preview":"L’appareil est masqué sur le plan ; cet aperçu de conception reste visible","marker.preview.reason.composite_power_source":"L’état provient de l’entité d’alimentation de l’appareil ; les interrupteurs auxiliaires sont ignorés","marker.preview.reason.activity_display_disabled":"Le mode d’affichage sélectionné n’affiche pas les effets d’activité habituels","marker.preview.reason.ha_disabled":"L’association Home Assistant est désactivée et sera masquée sur le plan","marker.preview.reason.orphaned":"L’association Home Assistant enregistrée est introuvable","marker.preview.reason.static_icon":"Mode statique : l’état de l’appareil ne modifie pas l’icône","marker.activity_color":"Couleur de la pulsation d’activité","marker.ripple_size":"Taille de la pulsation d’activité","marker.activity_alarm_note":"La couleur et la taille n’affectent que l’activité normale et ne modifient pas les alarmes rouges.","marker.pulse_a11y_alarm":"Alarme","marker.pulse_a11y_event":"Événement récent","marker.pulse_a11y_presence":"Présence détectée","marker.pulse_a11y_transition":"Changement d’état","marker.pulse_a11y_running":"En fonctionnement","marker.state_a11y_neutral":"État par défaut","marker.state_a11y_working":"En fonctionnement","marker.state_a11y_open":"Ouvert","marker.state_a11y_locked":"Verrouillé","marker.state_a11y_unlocked":"Déverrouillé","marker.state_a11y_alarm":"Alarme","marker.state_a11y_unavailable":"Indisponible","marker.lqi_a11y_low":"LQI {value}, signal faible","marker.lqi_a11y_mid":"LQI {value}, signal moyen","marker.lqi_a11y_high":"LQI {value}, signal fort","marker.size_label":"Taille / rotation de l’icône","marker.angle_label":"Rotation","marker.model_label":"Modèle","marker.model_ph":"ex. Aqara T&H","marker.link_label":"Lien","marker.desc_label":"Description","marker.desc_ph":"Notes, caractéristiques…","marker.manuals_label":"Manuels (PDF, etc.)","marker.sub_device":"appareil","marker.sub_z2m_group":" · groupe Z2M","marker.sub_group":"groupe","marker.sub_helper":"assistant","space.new":"Nouvel espace","space.copy_title":"Copier l’espace","space.copy_name":"Nom du nouvel espace","space.copy_fallback":"Espace","space.copy_create":"Créer la copie","space.copy_optimize_title":"Optimiser avant de copier ?","space.copy_optimize_body":"Avant de créer « {name} », House Plan doit optimiser tout le plan, y compris les autres espaces. Continuer ?","space.copy_optimize_confirm":"Optimiser et copier","space.copy_error_changed":"Le plan a changé pendant la confirmation. Vérifiez-le et réessayez.","space.copy_error_source_missing":"L’espace source n’existe plus. Rouvrez ses réglages et réessayez.","space.copy_error_source_invalid":"House Plan n’a pas pu valider tous les murs de cet espace. Corrigez l’espace source.","space.copy_error_spaces_limit":"House Plan contient déjà le nombre maximal d’espaces.","space.copy_error_partitions_limit":"Cet espace contient trop de murs pour être copié.","space.copy_error_openings_limit":"Cet espace contient trop d’ouvertures pour être copié.","space.copy_error_decor_limit":"Cet espace contient trop d’objets d’arrière-plan pour être copié.","space.copy_error_columns_limit":"Cet espace contient trop de colonnes pour être copié.","space.copy_error_opening_host":"Une ouverture n’est plus rattachée à un mur. Corrigez-la ou supprimez-la avant la copie.","space.copy_error_geometry":"La copie créerait une géométrie de murs non sûre. Corrigez l’espace source.","space.copy_error_optimize_geometry":"La copie est arrêtée car l’optimisation de tout le plan n’est pas sûre pour un espace.","space.header":"Espace","space.title_label":"Titre","space.title_ph":"ex. Garage","space.plan_label":"Plan (arrière-plan)","space.no_plan":"aucune image de plan","space.plan_alt":"plan","room.new":"Nouvelle pièce","room.name_label":"Nom affiché","room.name_ph":"ex. Terrasse","room.area_label":"Zone Home Assistant (non attribuée)","room.no_area_option":"— aucune zone —","room.default_name":"Pièce","device.unnamed":"sans nom","device.light_group":"groupe de lumières","device.fallback":"appareil","device.virtual":"appareil virtuel","confirm.delete_room_title":"Supprimer la pièce « {name} » ?","confirm.delete_room_body":"Choisissez si les murs physiques propres à la pièce doivent être conservés. Les murs partagés avec une autre pièce sont toujours conservés.","confirm.remove_marker_title":"Supprimer l’appareil du plan ?","confirm.remove_marker_body":"L’appareil disparaîtra complètement et ne contribuera plus aux données du plan. Vous pourrez l’ajouter de nouveau plus tard.","confirm.erase_decor":"Effacer l’objet {kind} ? Vous pouvez annuler cette action depuis l’historique de l’éditeur.","confirm.delete_space_title":"Supprimer l’espace ?","confirm.delete_space_body":"L’espace, toutes ses pièces et tout le tracé du plan seront supprimés.","confirm.delete_space_vac_routes":"Les affectations de cartes de robots seront aussi supprimées : {count}.","space.delete_blocked":"Cet espace est encore utilisé par {n} appareil(s). Déplacez-les vers un autre espace ou supprimez-les d’abord.","toast.pos_save_failed":"Échec de l’enregistrement de la position : {err}","toast.no_entity":"L’appareil n’a aucune entité adaptée","toast.ha_disabled_action":"Un objet Home Assistant désactivé ne peut pas être utilisé sur le plan.","toast.ha_disabled_show_device":"Un appareil désactivé dans Home Assistant ne peut pas être affiché sur le plan. Activez-le d’abord dans Home Assistant.","toast.ha_disabled_show_entity":"Une entité désactivée dans Home Assistant ne peut pas être affichée sur le plan. Activez-la d’abord dans Home Assistant.","toast.ha_disabled_add":"Un objet Home Assistant désactivé ne peut pas être ajouté au plan. Activez-le d’abord dans Home Assistant.","toast.ha_binding_unverified":"L’état de l’objet n’a pas pu être vérifié via le registre Home Assistant. L’affichage et les actions sont temporairement indisponibles.","toast.markup_needs_server":"Le tracé est disponible une fois la configuration déplacée sur le serveur","toast.space_order_changed":"L’ordre a changé. Si une carte fixe son étage par numéro, vérifiez ces tableaux de bord.","toast.conflict":"La configuration a été modifiée dans une autre fenêtre — données actualisées, répétez votre dernière action","toast.cfg_save_failed":"Échec de l’enregistrement de la configuration : {err}","toast.room_overlap":"Le contour chevauche la pièce « {name} » — les pièces ne doivent pas se chevaucher","toast.contour_cannot_close":"Le contour ne peut pas être fermé car il est dégénéré ou s’auto-intersecte","toast.merge_not_adjacent":"Seules les pièces partageant un mur peuvent être fusionnées","toast.rooms_merged":"Pièces fusionnées dans « {name} »","toast.split_pick_wall":"Commencez la découpe sur le mur de la pièce","toast.split_bad_cut":"La découpe doit aller d’un mur à l’autre à l’intérieur de la pièce, sans croiser de mur ni se croiser elle-même","merge.header":"Fusionner les pièces","merge.hint":"La pièce fusionnée conserve un nom et une zone. L’autre zone est libérée — ses appareils quittent le plan jusqu’à ce qu’une autre pièce la récupère.","merge.keep":"Conserver","merge.no_area":"aucune zone","toast.room_saved":"Pièce enregistrée ({n}). Appareils ajoutés : {added}. Tracez la suivante ou quittez le mode tracé.","toast.room_saved_no_area":"Pièce enregistrée ({n}, sans zone). Tracez la suivante ou quittez le mode tracé.","toast.marker_needs_server":"La modification des appareils est disponible une fois la configuration déplacée sur le serveur","toast.virtual_name_required":"Saisissez un nom pour l’appareil virtuel","toast.marker_saved":"Appareil enregistré","toast.marker_removed":"Appareil supprimé du plan","toast.integration_missing":"L’intégration House Plan n’est pas installée — gestion indisponible","toast.plan_formats":"Formats pris en charge : SVG, PNG, JPG, WebP","toast.plan_required":"Importez un plan — il est obligatoire","toast.space_added_onboard":"Espace ajouté. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","toast.space_added":"Espace ajouté","toast.space_copied":"Espace « {name} » créé","toast.space_saved":"Espace enregistré","toast.space_deleted":"Espace supprimé","toast.delete_failed":"Échec de la suppression : {err}","toast.error":"Erreur : {err}","toast.toggle_target_unavailable":"La cible « {name} » est indisponible — aucune action n’a été effectuée","toast.toggle_targets_unavailable":"Cibles indisponibles : {names}. Aucune action n’a été effectuée","toast.file_failed":"Le fichier « {name} » n’a pas été importé : {err}","toast.files_attached":"Fichiers joints : {n}","err.unknown":"erreur inconnue","err.code":"code {code}","err.too_large":"fichier supérieur à {mb} Mo","err.bad_ext":"type non pris en charge (PDF/image attendu)","err.unauthorized":"droits administrateur requis","editor.title":"Titre","editor.default_floor":"Espace initial","editor.default_floor_missing":"L’espace initial « {id} » n’existe plus. Choisissez un autre espace.","editor.floor":"Espace fixe","editor.floor_none":"— non fixé —","editor.floor_index":"Index YAML {index} (conservé)","fixed_floor.loading":"Chargement de l’espace fixe…","fixed_floor.invalid_title":"L’espace fixe est indisponible","fixed_floor.invalid_body":"Vérifiez floor dans la configuration de la carte. Valeur configurée : {value}","editor.icon_size":"Taille des icônes, % de la largeur du plan","editor.show_temperature":"Afficher la température","editor.live_states":"États en direct (on/off, ouvert…)","editor.light_pools":"Halos lumineux et ombres des murs","editor.show_signal":"Afficher le signal Zigbee (LQI)","editor.language":"Langue de l’interface","editor.lang_auto":"Auto (profil HA)","title.icon_rules":"Règles d’icônes : quelle icône MDI attribuer aux appareils selon leur nom","rules.title":"Règles d’icônes","rules.hint":"Les règles sont testées de haut en bas sur « nom de l’appareil + modèle » (expression régulière insensible à la casse) ; la première correspondance gagne. Si rien ne correspond, la classe d’appareil de l’entité est utilisée, puis l’icône générique.","rules.pattern_ph":"regex, ex. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Ajouter une règle","rules.reset":"Réinitialiser par défaut","rules.test_ph":"Tester un nom d’appareil…","rules.invalid":"expression régulière invalide","rules.saved":"Règles d’icônes enregistrées","btn.up":"Monter","btn.down":"Descendre","tap.info":"Fiche de l’appareil","tap.more_info":"Boîte de dialogue Plus d’infos de HA","tap.toggle":"Basculer l’état","marker.tap_label":"Action au toucher pour cet appareil","tap.toggle_note":"L’état déterminé est affiché ci-dessous. Les appareils sécurisés ne sont jamais basculés depuis le plan.","import.title":"Créer des espaces à partir des étages HA","import.hint":"Votre Home Assistant connaît déjà ces étages. Sélectionnez ceux à transformer en espaces du plan — vous importerez ensuite une image de plan pour chacun. Les pièces sont ensuite tracées manuellement sur le plan.","import.start":"Créer {n} espace(s)","import.manual":"Commencer de zéro","import.progress":"Étage {i} sur {n}","import.done":"Espaces créés. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","btn.skip":"Passer","space.scale_label":"Échelle (taille d’une cellule de grille)","space.cell_cm.help":"Relie la grille aux dimensions réelles : les longueurs, les surfaces, l’épaisseur des murs, la taille des ouvertures et le rayon du halo en dépendent. Une modification ultérieure change les dimensions calculées de tout l’espace sans déplacer ses points sur le plan.","space.cell_cm.help.aria":"Aide : échelle de l’espace","space.scale_unit":"cm par cellule","space.scale_unit_imperial":"po par cellule","space.display_section":"Affichage","space.show_borders":"Toujours afficher les contours des pièces","space.zero_wall_style":"Murs d’épaisseur nulle","space.zero_wall_style.help":"Les murs d’épaisseur nulle en pointillés laissent passer le halo et les rayons du soleil, tandis que les murs pleins les bloquent comme une barrière sans surface. Ce choix s’applique à tous ces murs de l’espace, même si leur ligne est masquée en mode Vue.","space.zero_wall_style.help.aria":"Aide : style des murs d’épaisseur nulle","space.zero_wall_dashed":"Pointillés","space.zero_wall_solid":"Plein","space.show_names":"Afficher les noms des pièces (faire glisser pour déplacer)","space.room_color":"Couleur du contour et du nom","space.opacity":"Opacité","space.fill_label":"Remplissage de la pièce","space.fill_mode.help":"« Couleur personnalisée » définit le style, tandis que « Lumière », « Température » et « LQI » utilisent les données actuelles de Home Assistant. Le halo s’active séparément.","space.fill_mode.help.aria":"Aide : mode de remplissage des pièces","fill.none":"Aucun","fill.lqi":"Signal Zigbee","fill.light":"Lumières","fill.custom":"Couleur personnalisée","space.custom_fill":"Couleur de remplissage","space.source_file":"J’ai une image de plan","space.source_draw":"Aucune image — je tracerai les pièces à la main","fill.temp":"Température","tip.temp_avg":"température moyenne :","tip.hum_avg":"humidité moyenne :","space_card.button":"Ouvrir le plan de l’espace","space_card.not_found":"Espace « {id} » introuvable","space_card.loading":"Chargement…","continuity.restore_plan":"Restauration du plan…","continuity.restore_connection":"Restauration de la connexion aux appareils…","continuity.retry":"Réessayer","editor.space":"Espace","editor.framing":"Cadrage","editor.fit_content":"Tout le contenu visible","editor.fit_house":"Ajusté à la géométrie de la maison","editor.show_button":"Afficher le bouton","editor.button_label":"Libellé du bouton","editor.button_target":"Chemin du tableau de bord cible","marker.sub_entity":"entité","title.general_settings":"Paramètres généraux","title.export_pdf":"Enregistrer en PDF","pdf.title":"Enregistrement en PDF","pdf.dimensions":"Afficher les dimensions et les surfaces","pdf.decor":"Afficher les meubles et les autres éléments","pdf.room_names":"Afficher les noms des pièces","pdf.backdrop":"Afficher le fond de plan","pdf.save":"Enregistrer","pdf.saving":"Création…","pdf.failed":"Impossible de créer le PDF.","pdf.too_large":"Les images dépassent la limite PDF de 25 Mo.","pdf.asset_failed":"Impossible de charger une image de fond ou de décoration.","pdf.scale":"Échelle 1:{n}","pdf.north":"Nord","gs.title":"Paramètres généraux","gs.light_group":"Remplissage : lumières","gs.light_on":"Lumières allumées","gs.light_off":"Toutes les lumières éteintes","gs.temp_group":"Remplissage : température","gs.temp_cold":"Froid","gs.temp_ok":"Confortable","gs.temp_hot":"Chaud","gs.lqi_group":"Remplissage : signal Zigbee","gs.lqi_low":"Signal faible","gs.lqi_high":"Signal fort","gs.reset":"Réinitialiser par défaut","gs.saved":"Paramètres généraux enregistrés","gs.radar_show_live":"Afficher la présence en direct sur le plan","gs.radar_show_live_hint":"Masque ou affiche toutes les cibles radar en direct. Cela ne démarre ni n’arrête l’enregistrement des observations.","radar.title":"Présence sur le plan","radar.help":"Reliez ce marqueur aux entités radar exactes de Home Assistant, placez le capteur et choisissez son profil de coordonnées. Les positions en direct sont limitées à la pièce sélectionnée.","radar.help.aria":"Aide : paramètres du radar de présence","radar.enabled":"Utiliser ce radar de présence","radar.show_live":"Afficher les cibles en direct","radar.configure":"Configurer le radar","radar.configure_on_plan":"Configurer sur le plan","radar.change_installation":"Changer l’installation","radar.no_contour":"Cette pièce n’a pas de contour. Les points radar ne seront pas limités.","radar.discard_setup_title":"Abandonner la configuration du radar ?","radar.discard_setup":"La configuration du radar non enregistrée sera perdue.","radar.step_place_mount":"Indiquez la position physique du capteur","radar.step_place_heading":"Indiquez un point droit devant le capteur","radar.step_reference":"Indiquez la position de référence {n}, puis lancez la mesure","radar.step_check_reference":"Indiquez une position de contrôle indépendante","radar.start_measure":"Lancer la mesure","radar.countdown":"Placez-vous sur le repère dans {seconds} s","radar.capturing":"Restez immobile et seul pendant la mesure…","radar.fit_ready":"Le calibrage est prêt","radar.check_third":"Vérifier à une autre position","radar.check_complete":"Contrôle indépendant terminé","radar.error_distance":"Écart de position : {distance}","radar.ambiguous_target":"Plusieurs cibles ont été signalées. Recommencez la mesure seul.","radar.insufficient_samples":"Coordonnées actuelles insuffisantes. Réessayez ou utilisez le réglage manuel.","radar.bad_references":"Choisissez des références espacées dans des directions différentes du capteur.","radar.ambiguous_sources":"Les mesures permettent deux directions également plausibles. Choisissez des repères distinguant la gauche de la droite.","radar.bad_fit":"Les mesures ne correspondent pas. Vérifiez les unités, la position du capteur et les références.","radar.desktop_hint":"Utilisez un ordinateur pour un réglage précis. L’édition sur appareils tactiles est prise en charge au mieux.","radar.detected":"House Plan a reconnu les métadonnées radar de cet appareil. Vérifiez les sources exactes avant d’enregistrer.","radar.detected_ld2450":"House Plan a trouvé un ensemble de coordonnées ESPHome LD2450. Vérifiez les sources X/Y exactes avant d’enregistrer.","radar.additional_actions":"Actions supplémentaires","radar.declare":"Ceci est un radar de présence","radar.profile":"Profil de données","radar.profile_esphome_ld2450_v1":"ESPHome LD2450 (cibles X/Y)","radar.profile_cartesian_v1":"Cibles cartésiennes (X/Y)","radar.profile_polar_v1":"Cible polaire (distance/angle)","radar.profile_range_v1":"Distance uniquement","radar.profile_zones_v1":"États des zones","radar.profile_presence_v1":"Présence uniquement","radar.room":"Pièce observée","radar.room_choose":"Choisir une pièce","radar.target":"Cible {n}","radar.axis_x":"Entité de coordonnée X","radar.axis_y":"Entité de coordonnée Y","radar.add_target":"Ajouter un emplacement de cible","radar.range_channel":"Canal de distance {n}","radar.add_range":"Ajouter un canal de distance","radar.presence_gate":"Entité de présence du canal","radar.swap_axes":"Permuter les axes X et Y","radar.axis_x_sign":"Direction X","radar.axis_y_sign":"Direction Y","radar.distance_source":"Entité de distance","radar.angle_source":"Entité d’angle","radar.angle_unit":"Unité d’angle","radar.degrees":"Degrés","radar.radians":"Radians","radar.angle_zero":"Direction de l’angle zéro","radar.angle_forward":"Vers l’avant","radar.angle_right":"Vers la droite","radar.angle_clockwise":"Les angles augmentent dans le sens horaire","radar.zone_source":"Entité de zone","radar.occupancy_source":"Entité de présence","radar.count_source":"Entité du nombre de cibles","radar.availability_source":"Entité de disponibilité","radar.source_choose":"Choisir une entité","radar.source_optional":"Facultatif","radar.source_missing":"actuellement indisponible","radar.saved_unsupported":"Cette configuration radar enregistrée est incomplète ou non prise en charge. Elle reste inactive ; supprimez-la ou mettez House Plan à jour avant de la reconfigurer.","radar.occupancy":"Présence (activée/désactivée)","radar.count":"Nombre","radar.mount":"Position et direction","radar.mount_hint":"Il s’agit de la position physique du capteur. Déplacer son marqueur décoratif ne la modifie pas.","radar.heading":"Direction, °","radar.range_cm":"Portée, cm","radar.fov_deg":"Champ de vision, °","radar.unit":"Unité de la source","radar.mirror":"Inverser l’axe gauche/droite","radar.remove":"Supprimer les paramètres radar","radar.invalid":"Renseignez la pièce, les sources et la position du radar avant d’enregistrer.","radar.check_sources":"Vérifier les données en direct","radar.checking":"Vérification…","radar.health":"État de la connexion","radar.live_summary":"Cibles actuelles : {targets} ; arcs de distance : {ranges}","radar.health_ok":"Données actuelles reçues","radar.health_off":"Aucune cible détectée","radar.health_stale":"Certaines coordonnées sont obsolètes","radar.health_partial":"Certaines sources sont à jour, d’autres sont obsolètes","radar.health_restricted":"L’accès à une ou plusieurs sources est limité","radar.health_incomplete":"Le rapport radar actuel est incomplet","radar.health_position_unavailable":"Présence signalée ; position actuelle indisponible","radar.health_unavailable":"Données du capteur indisponibles","radar.health_needs_setup":"L’installation doit être configurée","radar.health_inconsistent":"Les sources fournissent des valeurs contradictoires","radar.health_unknown":"L’état actuel est inconnu","radar.health_disabled":"Le radar est désactivé","radar.error_invalid_radar":"Vérifiez les paramètres radar.","radar.error_invalid_selection":"Sélectionnez une pièce existante et des sources valides.","radar.error_source_restricted":"Vous n’avez pas accès à toutes les sources sélectionnées.","radar.error_rate_limited":"Trop de demandes. Réessayez dans un instant.","radar.error_not_ready":"Le traitement radar n’est pas encore prêt.","radar.error_conflict":"Le plan a changé. Rouvrez la configuration radar et réessayez.","radar.error_source_unavailable":"Une ou plusieurs sources radar sélectionnées sont indisponibles.","radar.error_unsupported_capability":"Cette fonction radar n’est pas prise en charge par l’intégration installée.","radar.report_age":"il y a {seconds} s","space.show_lqi":"Afficher le signal Zigbee (LQI) à côté des appareils","space.hide_decor":"Masquer la couche décorative","space.hide_decor_tip":"Les lignes, formes, étiquettes et meubles restent à leur place — visibles dans l’éditeur d’arrière-plan, mais pas sur le plan.","space.hide_openings":"Masquer les ouvertures","space.hide_openings_tip":"Les symboles de portes, fenêtres et portails ne sont pas dessinés, mais les ouvertures continuent de fonctionner : la lumière les traverse, le soleil entre par les fenêtres et les capteurs de contact continuent de les ouvrir. L’éditeur de plan les affiche toujours.","gs.light_none":"Aucune source lumineuse","mode.plan":"Éditeur de plan","mode.devices":"Éditeur d’appareils","display.value":"Valeur + état","marker.subarea":"aucune zone, manuel","device.new":"Nouvel appareil — ouvrez son éditeur pour fermer","opening.unlock_action":"Déverrouiller","opening.lock_action":"Verrouiller","opening.lock_pending":"En cours…","title.close_editor":"Fermer l’éditeur (retour à la vue)","title.add_device":"Ajouter un appareil au plan","devbar.add":"Ajouter","devbar.rules":"Règles d’icônes","device_inbox.button":"Appareils","device_inbox.title":"Appareils sur le plan","device_inbox.search":"Rechercher appareils, entités et intégrations…","device_inbox.add_virtual":"Ajouter un appareil virtuel","device_inbox.tab_on_plan":"Sur le plan","device_inbox.tab_available":"Disponibles","device_inbox.tab_hidden":"Masqués","device_inbox.tab_readd":"De nouveau disponibles","device_inbox.only_new":"Nouveaux uniquement","device_inbox.show_entities":"Afficher les entités","device_inbox.show_hidden":"Afficher les masqués sur le plan","device_inbox.show_hidden.help":"Affiche temporairement les marqueurs masqués et désactivés sous forme de fantômes réservés à l’éditeur. La visibilité enregistrée des appareils ne change pas.","device_inbox.show_hidden.help.aria":"Aide : afficher les appareils masqués sur le plan","device_inbox.new":"Nouveau","device_inbox.find":"Trouver sur le plan","device_inbox.edit":"Modifier","device_inbox.hide":"Masquer","device_inbox.show":"Afficher","device_inbox.add":"Ajouter","device_inbox.readd":"Ajouter à nouveau","device_inbox.hide_available":"Masquer de la liste","device_inbox.show_more":"Afficher plus","device_inbox.more_actions":"Plus d'actions","device_inbox.find_hidden_hint":"Activez d'abord « Afficher les masqués sur le plan »","device_inbox.show_disabled":"Activez cette liaison dans Home Assistant avant de l'afficher","device_inbox.empty_on_plan":"Aucun appareil correspondant n'est encore sur le plan.","device_inbox.empty_available":"Aucun appareil disponible à ajouter.","device_inbox.empty_hidden":"Il n'y a aucun appareil masqué.","device_inbox.empty_readd":"Aucun appareil supprimé n'est disponible pour un nouvel ajout.","device_inbox.reason_visible_auto":"Découvert automatiquement","device_inbox.reason_visible_explicit":"Ajouté explicitement","device_inbox.reason_manual_hidden":"Masqué par l'utilisateur","device_inbox.reason_automatic_hidden":"Masqué automatiquement","device_inbox.reason_service_entry":"Entrée de registre de service uniquement","device_inbox.reason_excluded_integration":"Intégration « {integration} » exclue par les filtres de découverte","device_inbox.reason_excluded_domain":"Type d'entité non spatial","device_inbox.reason_grouped_light":"Représenté par un groupe de lumières de la pièce","device_inbox.reason_represented_by_parent":"Représenté par son appareil parent","device_inbox.reason_removed":"Précédemment retiré du plan","device_inbox.reason_available":"Disponible pour ajout au plan","device_inbox.reason_no_bound_room":"La zone HA n'est liée à aucune pièce du plan","device_inbox.status_ha_disabled":"Désactivé dans Home Assistant","device_inbox.status_orphaned":"La liaison n'existe plus dans Home Assistant","device_inbox.status_unverified":"Le registre Home Assistant est temporairement indisponible","device_inbox.saved":"Liste des appareils mise à jour","device_inbox.filters_excluded":"Intégrations exclues","device_inbox.filters_group_lights":"Regrouper les lumières de la pièce en un marqueur","device_inbox.filters_preview_appear":"apparaîtra : {count}","device_inbox.filters_preview_hide":"disparaîtra : {count}","device_inbox.filters_preview_lights":"lumières concernées : {count}","device_inbox.filters_reset":"Rétablir les recommandées","device_inbox.filters_save":"Enregistrer les filtres","device_inbox.filters_search_ph":"Ajouter une intégration…","device_inbox.filters_title":"Filtres de découverte","space.roomcard_section":"La carte de pièce affiche :","space.label_temp":"Température","space.label_hum":"Humidité","space.label_lqi":"Signal Zigbee moyen","space.label_light":"Lumières allumées/éteintes","roomcard.light_on":"Allumé","roomcard.light_off":"Éteint","roomcard.light_partial":"{on} sur {total}","toast.split_pick_inside":"Les points intermédiaires de découpe doivent se trouver à l’intérieur de la pièce","mode.decor":"Éditeur d’arrière-plan","decor.select":"Sélectionner","decor.line":"Ligne","decor.rect":"Rectangle","decor.ellipse":"Ovale","decor.text":"Texte","decor.erase":"Effacer","decor.erase_confirm_title":"Effacer l’objet ?","decor.color":"Couleur","decor.width":"Épaisseur de ligne","decor.line_style":"Style de ligne","decor.line_style_solid":"Plein","decor.line_style_dashed":"Pointillés","decor.fill":"Remplissage","decor.fill_color":"Couleur de remplissage","decor.length":"Longueur","decor.size":"Taille","decor.flip_h":"Retourner horizontalement","decor.flip_v":"Retourner verticalement","decor.angle":"Angle de rotation, °","decor.text_size":"Taille du texte","decor.backdrop_properties":"Propriétés de l’arrière-plan du plan","decor.text_title":"Étiquette de texte","decor.object_title":"Modifier {kind}","decor.text_label":"Texte","decor.live_group":"Insérer une variable HA","decor.live_entity":"Entité","decor.live_entity_ph":"choisir une entité","decor.live_attr":"Valeur","decor.live_attr_ph":"choisir l’état ou un attribut","decor.live_state":"État","decor.backdrop":"Image d’arrière-plan","decor.backdrop_hint":"Faites glisser pour déplacer ; tirez un coin pour redimensionner ; utilisez la poignée supérieure pour faire pivoter. Maj modifie les proportions ou libère l’angle.","decor.backdrop_reset":"Réinitialiser l’image","decor.backdrop_reset_done":"L’image a retrouvé sa position et sa taille d’origine","marker.icon_auto":"Auto : {icon} (selon les règles d’icônes ; choisissez-en une pour remplacer)","marker.icon_pin_auto":"Épingle","mode.plan_tip":"Éditeur de plan — la géométrie du logement : dessiner et diviser/fusionner les pièces, les associer aux zones HA, placer portes, fenêtres et portails, déplacer les cartes de pièces, régler l’échelle","mode.devices_tip":"Éditeur d’appareils — tout ce qui concerne les icônes : faire glisser pour positionner, cliquer pour modifier l’association/l’icône/l’affichage, ajouter des appareils virtuels, règles d’icônes","mode.decor_tip":"Éditeur d’arrière-plan — décoration purement visuelle sous le plan : lignes, rectangles, ovales et étiquettes de texte qui ne réagissent jamais aux clics","space.glow_enabled":"Halo des sources lumineuses","gs.glow_group":"Halo des sources lumineuses","gs.glow_base":"Obscurité de la maison","gs.glow_light":"Couleur / intensité de lumière par défaut","gs.wall_group":"Murs","gs.wall_fill":"Remplissage des murs","gs.glow_radius":"Rayon du halo","gs.glow_radius.help":"Définit le rayon général du halo en mètres ou en pieds ; le rayon propre à un appareil remplace cette valeur.","gs.glow_radius.help.aria":"Aide : rayon général du halo","gs.unit_m":"m","gs.unit_ft":"pi","marker.controls_label":"Contrôle d’autres sources lumineuses","marker.controls.help":"Avec l’action « Basculer l’état », les sources répertoriées basculent avec ce marqueur. Leur halo reste sur leurs propres marqueurs et ce lien ne transforme pas à lui seul le marqueur de contrôle en source lumineuse.","marker.controls.help.aria":"Aide : contrôler d’autres sources lumineuses","marker.controls_filter":"Rechercher des lumières et interrupteurs…","info.controls":"Contrôle","marker.glow_radius_label":"Rayon du halo","marker.glow_radius.help":"Définit le rayon du halo en mètres ou en pieds ; une valeur vide utilise le rayon des paramètres généraux.","marker.glow_radius.help.aria":"Aide : rayon du halo","markup.wallthick":"Épaisseur","markup.select":"Sélectionner","title.markup_wallthick":"Épaisseur — cliquez sur un mur pour définir son épaisseur de 0 à 100 cm.","markup.hint_wallthick":"cliquez sur un mur · Échap ferme sans appliquer","wallthick.field":"Épaisseur","wallthick.unit_cm":"cm","wallthick.unit_in":"po","wallthick.apply_room":"Appliquer à tous les murs de cette pièce","markup.draw_wall_title":"Épaisseur de chaque nouveau segment de mur (0–100 cm). Les murs partagés conservent la valeur existante.","room.queue_progress":"Pièce {current} sur {total}","toast.wall_rooms_saved":"Pièces créées : {n}","toast.wall_chain_saved":"Chaîne de murs enregistrée","toast.wallthick_pick":"Cliquez sur un mur","toast.wallthick_set":"Épaisseur du mur définie","toast.wallthick_cleared":"Épaisseur du mur supprimée","toast.physical_range":"Saisissez une valeur comprise entre {min} et {max} {unit}","toast.zero_wall_opening_conflict":"Supprimez d’abord l’ouverture sur ce segment de mur.","toast.zero_wall_ambiguous":"Le segment de mur est ambigu. Simplifiez ou ajustez la jonction.","toast.zero_wall_migration_blocked":"L’espace n’a pas été converti : {reason}. Aucune donnée n’a été modifiée.","toast.physical_angle":"Saisissez un angle de rotation compris entre 0° inclus et 90° exclu","toast.physical_limit":"L’espace a atteint la limite pour ce type de géométrie","toast.geometry_unsafe":"Modification annulée : la géométrie des murs n’a pas pu être construite en toute sécurité.","junction.limit_angle":"L'angle entre les murs est trop aigu : {actual}°, minimum {limit}°.","junction.limit_valence":"Trop de murs se rejoignent en un nœud : {actual}, maximum {limit}.","junction.limit_length":"Le segment de mur est trop court : {actual} cm, minimum {limit} cm.","junction.limit_distance":"Les murs et les nœuds sont trop proches : {actual} cm, minimum {limit} cm.","junction.limit_clearance":"Il ne reste plus d'intérieur de pièce : {actual} cm², minimum {limit} cm².","junction.limit_check_failed":"La vérification des jonctions n'a pas pu s'exécuter — la modification n'a pas été enregistrée","toast.wall_model_migration_blocked":"Le modèle de murs n’a pas pu être mis à jour : {reason}. Le plan n’a pas été modifié. Lancez « Optimiser les plans » ; si l’erreur se reproduit, corrigez la géométrie de mur conflictuelle.","toast.wall_model_client_outdated":"Mettez à jour la carte et rechargez la page avant de modifier le plan.","wall_model.reason.invalid-room":"contour de pièce invalide","wall_model.reason.zero-length":"segment de mur de longueur nulle","wall_model.reason.third-owner":"mur partagé par plus de deux pièces","wall_model.reason.duplicate-id":"identifiants de mur en conflit","wall_model.reason.thickness-conflict":"valeurs d’épaisseur de mur en conflit","wall_model.reason.opening-host":"l’ouverture ne peut pas être attribuée à un seul mur","toast.delete_room_pick":"Cliquez à l’intérieur de la pièce que vous souhaitez supprimer","toast.plan_snap_ambiguous":"Zoomez pour choisir le nœud du mur","toast.wall_repair_ambiguous":"Le contour de la pièce possède plusieurs connexions possibles. Zoomez et reliez-le explicitement.","toast.wall_repair_too_large":"L’écart dépasse 2 cm. Reliez les murs avant de créer la pièce.","toast.wall_repair_changed":"La géométrie des murs a changé. Essayez de créer de nouveau la pièce.","toast.opening_on_zero_wall":"Les ouvertures ne peuvent pas être placées sur un mur d’épaisseur nulle","marker.from_ha_option":"Choisir dans la liste HA","marker.show_entities":"Afficher les entités","marker.show_entities_tip":"Ajoute à la liste non seulement les appareils, mais aussi toutes leurs entités","marker.pick_ph":"Choisir un appareil…","room.open_area":"Ouvrir la zone HA","room.fit_action":"Ajuster la pièce {name}","view.volumetric":"Vue volumétrique","view.flat":"Vue plane","kiosk.title":"Tailles pour cet écran","kiosk.hint":"Enregistrées uniquement sur cet appareil — chaque tablette murale ou TV peut avoir ses propres tailles confortables.","kiosk.icon_scale":"Taille des icônes d’appareils","kiosk.font_scale":"Taille du texte des cartes de pièces","editor.kiosk":"Mode appareil mural (kiosque)","editor.cycle":"Changer automatiquement d’espace toutes les N secondes (kiosque, 0 = désactivé)","room.settings_title":"Paramètres de la pièce","room.settings_section":"Paramètres de la pièce (remplacent ceux de l’espace)","room.fill_label":"Remplissage de CETTE pièce","fill.inherit":"Comme l’espace","room.custom_fill_space":"Couleur de l’espace","room.custom_fill_own":"Couleur de la pièce","room.temp_range_label":"Plage de confort","room.temp_range_min":"Limite basse de température confortable","room.temp_range_max":"Limite haute de température confortable","room.temp_range_reset":"Comme l’espace","room.temp_range.help":"Cette plage s’applique uniquement à cette pièce. Un champ vide hérite de la limite correspondante de l’espace ; si les limites sont inversées, House Plan utilise la plus petite comme limite basse et la plus grande comme limite haute.","room.temp_range.help.aria":"À propos de la plage de confort de la pièce","room.temp_src_label":"Source de température","room.hum_src_label":"Source d’humidité","room.src_average":"Moyenne des capteurs de la pièce (par défaut)","room.src_pick":"Un appareil ou une entité HA spécifique","room.src_ph":"Choisir une source…","toast.room_updated":"Pièce mise à jour","space.card_font":"Taille de police des cartes de pièces (tout l’espace)","room.sizes_section":"Tailles de police","room.name_scale":"Taille du nom de la pièce","room.label_scale":"Taille des mesures","preview.room_name":"Salon","toast.cfg_reload_failed":"Impossible de recharger le plan depuis le serveur : {err}","toast.locale_load_failed":"Impossible de charger le pack de langue. L'anglais est utilisé jusqu'au rechargement de la page.","toast.furniture_art_load_failed":"Impossible de charger les dessins de meubles. Rechargez la page pour les afficher.","room.settings_short":"Paramètres de la pièce","room.unnamed":"Pièce sans nom","marker.use_climate_temp":"Inclure la température de l’appareil dans la pièce","marker.use_climate_temp_tip":"Ajoute la valeur current_temperature d’un climatiseur ou thermostat à la moyenne de la pièce. Configurez séparément le badge de valeur externe ci-dessous.","marker.value_badge_title":"Badge de valeur","marker.value_badge.help":"Affiche une valeur sélectionnée à côté de l’icône. Cela n’affecte pas les mesures de la pièce, la lumière, le halo ni l’action au toucher.","marker.value_badge.help.aria":"Aide : badge de valeur de l’appareil","marker.value_badge_enabled":"Afficher un badge de valeur","marker.value_badge_source":"Valeur","marker.value_badge_source.help":"Choisissez un état précis, un attribut pris en charge ou une valeur dérivée de cet appareil.","marker.value_badge_source.help.aria":"Aide : source du badge de valeur","marker.value_badge_position":"Position","marker.value_badge_position.help":"Le côté choisi reste fixe et ne bascule pas automatiquement au bord du plan.","marker.value_badge_position.help.aria":"Aide : position du badge de valeur","marker.value_badge_right":"À droite","marker.value_badge_bottom":"En dessous","marker.value_badge_left":"À gauche","marker.value_badge_top":"Au-dessus","marker.value_badge_empty":"Cet appareil n’a aucune valeur disponible","marker.value_badge_static":"Une icône statique n’affiche pas de valeurs en direct. Le paramètre est conservé.","marker.value_badge_missing":"Source indisponible","marker.value_badge_missing_hint":"La source enregistrée est actuellement indisponible. Conservez-la, désactivez le badge ou choisissez une autre valeur.","marker.value_badge_duplicate":"La même valeur est déjà affichée dans l’icône.","marker.value_badge_state":"État · {name}","marker.value_badge_marker_state":"État de la source lumineuse · {name}","marker.value_badge_lqi":"Qualité moyenne du signal Zigbee","marker.value_badge_attr_current_temperature":"Température actuelle · {name}","marker.value_badge_attr_temperature":"Température cible · {name}","marker.value_badge_attr_current_humidity":"Humidité actuelle · {name}","marker.value_badge_attr_humidity":"Humidité · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Vitesse · {name}","marker.value_badge_attr_brightness":"Luminosité · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Batterie · {name}","marker.value_badge_attr_fan_speed":"Vitesse du ventilateur · {name}","marker.value_source":"Source de la valeur","marker.value_source.help":"Choisissez la valeur qui remplace l’icône. L’action au toucher ne change pas.","marker.value_source.help.aria":"Aide : source de la valeur dans le marqueur","marker.value_source_auto":"Automatique (comme avant)","marker.value_source_missing_hint":"La source enregistrée est indisponible. Le marqueur affiche — jusqu’à son retour ou jusqu’au choix d’une autre valeur.","marker.light_role_label":"Cet appareil est-il une source lumineuse ?","marker.light_role.help":"« Auto » utilise le rôle déterminé de l’appareil lié, « Toujours » force sa propre source et « Jamais » l’exclut ; les lumières liées ci-dessus restent indépendantes.","marker.light_role.help.aria":"Aide : cet appareil est-il une source lumineuse","marker.light_role_auto_yes":"Auto (source lumineuse)","marker.light_role_auto_no":"Auto (pas une source lumineuse)","marker.light_role_always":"Toujours une source lumineuse","marker.light_role_never":"Jamais une source lumineuse","marker.light_entity_label":"Entité lumineuse principale","marker.light_entity.help":"Pour un appareil composite, choisissez l’entité dont l’état, la couleur et la luminosité représentent cette source sur le plan. Le choix automatique reste compatible avec les anciens plans.","marker.light_entity.help.aria":"Aide : entité lumineuse principale","marker.light_entity_auto":"Automatique ({entity})","marker.light_entity_none":"aucune entité contrôlable","marker.light_entity_missing":"L’entité enregistrée {entity} est indisponible. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.toggle_entity_label":"Entité à basculer","marker.toggle_entity.help":"Pour un appareil composite, choisissez précisément la lumière ou l’interrupteur propre à actionner par un toucher. Automatique conserve les règles de cible précédentes et reste indépendant de l’entité lumineuse principale.","marker.toggle_entity.help.aria":"Aide : entité à basculer","marker.toggle_entity_auto":"Automatique ({entity})","marker.toggle_entity_none":"aucune entité propre contrôlable","marker.toggle_entity_missing":"L’entité enregistrée {entity} ne fait plus partie des canaux sélectionnables de ce marqueur. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.glow_color_label":"Couleur et luminosité du halo","marker.glow_mode.help":"Utilisez les valeurs en direct de la source, remplacez uniquement sa couleur ou fixez à la fois la couleur et la luminosité. Le minimum est 1 % ; pour désactiver la source, choisissez « Jamais ».","marker.glow_mode.help.aria":"Aide : couleur et luminosité du halo","marker.glow_mode_auto":"Depuis la source","marker.glow_mode_color":"Définir la couleur","marker.glow_mode_fixed":"Définir la couleur et la luminosité","marker.glow_color":"Couleur du halo","marker.glow_brightness":"Luminosité","marker.glow_disabled_never":"Les paramètres du halo sont indisponibles car ce marqueur est explicitement défini comme n’étant pas une source lumineuse.","marker.glow_disabled_auto":"Le mode Auto n’a trouvé aucune source lumineuse spatiale pour ce marqueur.","marker.glow_disabled_no_entity":"Aucune entité Home Assistant contrôlable et active n’est disponible pour cette source spatiale.","marker.glow_passive_hint":"Cette source ne possède aucune donnée Home Assistant propre. Définissez manuellement sa couleur et sa luminosité ; son rayon reste disponible.","marker.control_broken":"La source enregistrée est absente ou n’est plus marquée comme lumière","marker.control_missing_label":"Lumière du plan manquante","marker.control_passive":"source passive","toast.marker_control_cycle":"Ce lien créerait une chaîne circulaire de contrôles de lumière.","toast.marker_binding_required":"Choisissez un appareil Home Assistant avant de lier une autre source lumineuse.","confirm.unlock_title":"Déverrouiller ?","confirm.unlock_body":"House Plan enverra une commande de déverrouillage à cette serrure.","toast.files_migrate_failed":"Les pièces jointes n’ont pas pu être déplacées vers la nouvelle association ; les liens continuent de pointer vers les anciens fichiers : {err}","space.pick_saved":"Déjà importé","space.pick_saved_hint":"Plans stockés sur le serveur, y compris ceux que vous avez précédemment dissociés","space.no_saved":"Aucun plan n’est encore stocké sur le serveur.","space.loading":"Chargement…","space.used_by":"utilisé par : {list}","space.in_use":"Un espace utilise encore ce plan — dissociez-le d’abord","btn.use":"Utiliser","confirm.delete_plan_title":"Supprimer le fichier du plan ?","confirm.delete_plan_body":"Le fichier sera supprimé du serveur. Cette action est irréversible.","toast.plans_list_failed":"Impossible de lister les plans stockés : {err}","toast.plan_delete_failed":"Impossible de supprimer le plan : {err}","marker.hide":"Masquer","marker.hide_tip":"L’appareil disparaîtra du plan après l’enregistrement mais continuera de compter dans le signal de la pièce. Restaurez-le via « Masqués et désactivés » dans l’éditeur d’appareils.","marker.show":"Afficher","marker.show_tip":"L’appareil apparaîtra de nouveau sur le plan après l’enregistrement.","marker.hidden_ghost":"Appareil masqué par l’utilisateur","marker.ha_disabled_device":"L’appareil est désactivé dans Home Assistant et masqué du plan.","marker.ha_disabled_entity":"L’entité est désactivée dans Home Assistant et masquée du plan.","marker.ha_disabled_all_entities":"L’appareil n’a aucune entité Home Assistant active ; il est donc masqué du plan.","marker.ha_registry_limited":"Le registre Home Assistant complet n’est pas accessible à cet utilisateur. L’objet non vérifié ne peut pas être affiché ni utilisé pour le moment.","marker.delete_tip":"Supprimer complètement l’appareil du plan et de tous les agrégats. Vous pourrez l’ajouter de nouveau plus tard.","tap.run":"Exécuter une automatisation/un script/une scène","tap.none":"Ne rien faire","marker.run_target_label":"Élément à exécuter","marker.run_search_ph":"Rechercher : automatisation, script ou scène…","marker.run_target_gone":"Cible {id} introuvable — choisissez-en une autre","marker.tap_confirm":"Demander une confirmation","marker.tap_confirm_tip":"Afficher une boîte de dialogue de confirmation avant l’action — protection contre les appuis accidentels.","marker.toggle_hint_single":"Cible : {name} ({id}).","marker.virtual_light_target":"Lumière virtuelle : {name}.","marker.virtual_light_current":"État manuel : {state} → {effect}.","marker.virtual_light_state_on":"allumé","marker.virtual_light_state_off":"éteint","marker.toggle_hint_group":"Basculera {count} source(s) : {names}.","marker.toggle_hint_current":"Actuellement : {state} → {effect}.","marker.toggle_hint_group_current":"Actuellement allumées : {on} sur {count} → {effect}.","marker.toggle_hint_skipped":"Seront ignorées ({count}) : {targets}.","marker.toggle_effect_turn_on":"sera allumé","marker.toggle_effect_turn_off":"sera éteint","marker.toggle_effect_open":"sera ouvert","marker.toggle_effect_close":"sera fermé","marker.toggle_effect_stop":"sera arrêté","marker.toggle_effect_toggle":"l’état sera basculé","marker.toggle_skip_missing":"introuvable","marker.toggle_skip_ha_disabled":"désactivé dans HA","marker.toggle_skip_unavailable":"indisponible","marker.toggle_skip_unsupported":"basculement non pris en charge","marker.toggle_skip_secure":"bloqué pour des raisons de sécurité","marker.toggle_none_no_binding":"Cet appareil n’a aucune association ; il n’y a donc aucun état à basculer. Un toucher ne fera rien.","marker.toggle_none_no_actionable_entity":"Cet appareil n’a aucun état pouvant être basculé. Un toucher ne fera rien.","marker.toggle_none_configured_targets_missing":"Les cibles configurées sont indisponibles. L’entité propre de l’appareil ne leur sera pas substituée.","marker.toggle_none_ha_disabled":"La cible est désactivée dans Home Assistant et ne peut pas être utilisée sur le plan.","marker.toggle_none_unavailable":"La cible est actuellement indisponible. Un toucher ne fera rien.","marker.toggle_none_unsupported":"Home Assistant n’expose aucune opération de basculement sûre pour cette entité. Un toucher ne fera rien.","marker.toggle_none_secure":"Le basculement des serrures, alarmes et portails sécurisés depuis le plan est bloqué pour des raisons de sécurité.","run.automation":"automatisation","run.script":"script","run.scene":"scène","confirm.tap_run":"Exécuter « {name} » ?","confirm.tap_toggle":"Basculer « {name} » ?","confirm.current_state":"État actuel : {state}","confirm.expected_state":"Après basculement : {state}","confirm.group_current":"{on} allumé(s) sur {total}","confirm.group_all_on":"tout est allumé","confirm.group_all_off":"tout est éteint","confirm.unavailable_targets":"Indisponibles : {count}","confirm.expected_by_ha":"Home Assistant déterminera l’état","confirm.state_on":"Allumé","confirm.state_off":"Éteint","confirm.state_open":"Ouvert","confirm.state_closed":"Fermé","confirm.state_opening":"Ouverture en cours","confirm.state_closing":"Fermeture en cours","confirm.state_stopped":"Arrêté","confirm.state_unknown":"Inconnu","toast.run_started":"Démarré : {name}","toast.run_target_missing":"Cible d’exécution introuvable — vérifiez les paramètres de l’appareil","toast.run_target_required":"Choisissez une automatisation, un script ou une scène","toast.tap_target_changed":"La cible de l’action a changé. Réessayez.","toast.virtual_light_toggle_failed":"Impossible de basculer la lumière virtuelle : {err}","toast.value_badge_source_required":"Choisissez une valeur pour le badge","btn.run":"Exécuter","vac.section":"Robot aspirateur : position en direct","vac.autocal":"Configurer automatiquement","vac.live":"Position en direct sur le plan","vac.trail":"Afficher le trajet du robot","vac.autocal_no_rooms":"L’intégration ne fournit aucune liste de pièces — ouvrez « Ajuster manuellement »","vac.route_warn_unmapped":"Le robot nettoie une carte qui n'est assignée à aucun étage","vac.route_warn_needs_calibration":"La carte est assignée à un étage mais n'est pas calibrée","vac.route_warn_ambiguous":"Deux cartes sont indiscernables — aucun étage choisi","vac.route_warn_missing_space":"L'espace de cette carte a été supprimé","vac.autocal_no_match":"Les noms de pièces ne correspondent pas (il en faut ≥3 en commun) — ouvrez « Ajuster manuellement »","vac.autocal_done":"Terminé : association via {rooms} pièces. Lancez un nettoyage et vérifiez","vac.cal_need_pos":"Le robot ne transmet pas de coordonnées — lancez un nettoyage puis mettez-le en pause","vac.cal_done":"Calibration enregistrée. Lancez un nettoyage et vérifiez","vac.cal_cancelled":"Calibration annulée","vac.fit":"Ajuster manuellement","vac.fit_hint":"Faites glisser la carte du robot pour la positionner, étirez-la par les coins","vac.fit_rotate":"Rotation de 90°","vac.fit_mirror":"Miroir","vac.trail_never":"Jamais","vac.trail_cleaning":"Pendant le nettoyage","vac.trail_always":"Toujours","gs.bg_group":"Arrière-plan de la scène","gs.bg_color":"Arrière-plan autour du plan","gs.bg_default":"Valeur par défaut du thème","gs.bg_theme":"valeur par défaut du thème","gs.bg_mode":"Arrière-plan du plan","gs.bg_mode.help":"« Suit le soleil » utilise sun.sun ou, à défaut, l’heure locale du navigateur ; « Couleur statique » affiche toujours la couleur choisie.","gs.bg_mode.help.aria":"Aide : arrière-plan général du plan","gs.bg_static":"Couleur statique","gs.bg_daynight":"Suit le soleil","gs.sun_group":"Soleil","gs.sun_missing":"L’entité sun.sun est introuvable — l’arrière-plan suit votre heure locale ; les rayons de soleil par les fenêtres sont indisponibles.","gs.north":"Nord sur le plan","gs.north.help":"L’angle se mesure dans le sens horaire depuis la verticale supérieure du plan ; le nord sert aux rayons des fenêtres, pas à l’arrière-plan « Suit le soleil ».","gs.north.help.aria":"Aide : direction générale du nord","gs.north_ph":"non défini","gs.north_clear":"Effacer","gs.north_letter":"N","gs.sun_rays":"Lumière du soleil à travers les fenêtres","gs.sun_ray_origin":"Rayons du soleil","gs.sun_ray_origin.inner":"Depuis les angles intérieurs des fenêtres","gs.sun_ray_origin.outer":"Depuis les angles extérieurs des fenêtres","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · documentation et problèmes","gs.about_telegram":"Discussion Telegram","support.title":"Aide et commentaires","space.bg_color":"Arrière-plan autour du plan","space.bg_inherit":"Hériter des paramètres généraux","space.bg_inherited":"hérite des paramètres généraux","space.bg_mode":"Arrière-plan du plan","space.bg_mode.help":"Héritez de l’arrière-plan général ou remplacez-le pour cet espace par une couleur statique ou le mode « Suit le soleil ».","space.bg_mode.help.aria":"Aide : arrière-plan de l’espace","space.north":"Nord sur le plan (remplacement)","space.north.help":"Remplace le nord général pour cet espace ; l’angle se mesure dans le sens horaire depuis la verticale supérieure du plan et sert aux rayons des fenêtres.","space.north.help.aria":"Aide : nord de cet espace","space.north_inherited":"hérité : {v}","space.sun_rays":"Lumière du soleil à travers les fenêtres","space.sun_inherit":"Hériter des paramètres généraux","space.sun_on":"Activé","space.sun_off":"Désactivé","canvas.far_objects":"{n} objet(s) éloigné(s) du plan","canvas.show_far":"Afficher","canvas.home_tip":"Le plan est là-bas — cliquez pour l’ajuster à l’écran","gs.grid_group":"Maintenance du plan","gs.grid_hint":"Met à jour les modèles de données, aligne les éléments du plan sur la grille et fusionne les fragments de murs redondants. Un rapport précis est affiché avant tout enregistrement.","gs.align_all":"Optimiser les plans","gs.align_title":"Optimiser les plans","gs.align_none":"Tous les plans utilisent déjà le modèle de données optimisé actuel.","gs.optimize_no_automatic_changes":"Aucune modification automatique n’est à appliquer. Vérifiez les éléments ci-dessous.","gs.align_count":"{n} élément(s) sur {total} seront déplacés, de {cm} cm au maximum.","gs.align_where":"Le plus grand déplacement se trouve dans « {s} ».","gs.align_turned":"Ouvertures dont l’angle est corrigé : {n}.","gs.align_preflight_failed":"Impossible de vérifier en toute sécurité la géométrie des espaces suivants : {spaces}{more}.","gs.align_preflight_hint":"Les plans n’ont pas été modifiés. Copiez les diagnostics avec le bouton ci-dessous et joignez-les au rapport de bug avec un export de l’espace.","gs.preflight_reason_prepare-exception":"Impossible de préparer la géométrie de l’espace (exception lors de la construction du modèle)","gs.preflight_reason_wall-null":"Le corps du mur n’a pas pu être construit (l’union a renvoyé un résultat vide)","gs.preflight_reason_wall-degraded-extra":"Le corps du mur s’est dégradé avec une géométrie supplémentaire","gs.preflight_reason_wall-failed-core":"Le noyau du corps du mur n’a pas pu être assemblé","gs.preflight_reason_wall-exception":"La construction du mur a déclenché une exception","gs.preflight_reason_floor-null":"Le contour du sol n’a pas pu être construit","gs.preflight_reason_floor-exception":"La construction du sol a déclenché une exception","gs.preflight_copy":"Copier les diagnostics","gs.preflight_copied":"Diagnostics copiés","gs.preflight_update_hint":"Les versions de la carte et de l’intégration diffèrent — mettez House Plan à jour puis réessayez.","gs.align_preflight_space":"Espace {n}","gs.align_preflight_more":", et {n} de plus","gs.optimize_changes":"Migrations de modèle : {m} ; espaces mis à jour : {c} ; valeurs de coordonnées parasites supprimées : {p} ; fragments de murs réels fusionnés : {w} ; fragments de murs d’épaisseur nulle fusionnés : {s} ; murs indépendants : {i}.","gs.zero_walls_migrated":"Portions de murs virtuels converties : {n}.","gs.wall_segments_migrated":"Segments de murs stabilisés : {n}.","gs.room_drafts_migrated":"Contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","gs.optimize_lattice_summary":"Valeurs de coordonnées parasites normalisées : {n} ; déplacement maximal : {cm} cm.","gs.optimize_lattice_space":"{space} : valeurs de coordonnées normalisées : {n} ; valeurs hors grille laissées inchangées : {far}.","gs.optimize_coincident_partitions":"Sections de murs indépendants masquées absorbées dans les murs des pièces : {n}.","gs.optimize_openings_rehosted":"Ouvertures rattachées aux murs des pièces : {n}.","gs.optimize_walls_straightened":"Murs redressés : {n} ; déplacement maximal : {cm} cm.","gs.optimize_walls_straightened_where":"Plus grande correction de mur : {s}.","gs.optimize_walls_straighten_skipped":"Murs proches d’un axe laissés inchangés car ils ne pouvaient pas être réparés en toute sécurité : {n}.","gs.optimize_glow_migration":"Ancien mode Glow : {spaces} espaces → aucun remplissage de données + Glow indépendant ; {rooms} pièces → remplissage de données hérité + Glow indépendant.","gs.optimize_references":"Références réparées : espaces — {spaces} ; pièces — {rooms} ; positions — {positions} ; appareils dissociés des espaces manquants — {detached}.","gs.optimize_reference_more":", et {n} de plus","gs.optimize_orphans_removed":"Enregistrements oubliés supprimés : {total} — étiquettes de pièces : {rooms} ; appareils : {devices} ; marqueurs de groupe : {groups}. Ils appartenaient à des espaces supprimés précédemment.","gs.optimize_live_positions":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles seront conservées.","gs.optimize_live_positions_remove":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles sont sélectionnées pour suppression.","gs.optimize_live_names":" : {names}{more}","gs.optimize_live_remove":"Supprimer les anciennes positions","gs.optimize_live_keep":"Conserver les anciennes positions","gs.optimize_live_selected":"Les anciennes positions seront supprimées après l’application de l’optimisation.","gs.optimize_unverified":"Impossible de vérifier en toute sécurité les positions : {n}. Elles ont été laissées inchangées.","gs.optimize_registry_limited":"Un accès administrateur complet aux registres Home Assistant est requis pour une vérification sûre.","gs.optimize_vacuum_warning":"Associations de pièces d’aspirateur nécessitant encore une vérification : {n}.","gs.optimize_details":"Détails","gs.optimize_details_more":"Et {n} enregistrement(s) de plus.","gs.optimize_detail_removed":"sera supprimé","gs.optimize_detail_live":"sera conservé","gs.optimize_detail_unverified":"non vérifié","gs.optimize_detail_room_label":"étiquette de pièce","gs.optimize_detail_device":"appareil","gs.optimize_detail_group":"marqueur de groupe","gs.optimize_detail_unknown":"propriétaire inconnu","gs.optimize_detail_item":"{status} : {kind} {id} ; ancien espace {space}","gs.align_warn":"Les éléments volontairement placés entre les nœuds de la grille seront déplacés. Une seule annulation est disponible après l’opération, uniquement jusqu’à la prochaine modification du plan.","gs.align_run":"Optimiser","gs.align_done":"Plans optimisés : {n} élément(s) déplacé(s), {m} enregistrement(s) maintenu(s), {r} référence(s) réparée(s)","gs.optimize_undo":"Annuler la dernière optimisation","gs.optimize_undone":"La dernière optimisation a été annulée","decor.furniture":"Mobilier","decor.image":"Image","decor.image_title":"Images personnalisées","decor.image_upload":"Importer une image","decor.image_replace":"Remplacer l’image","decor.image_uploading":"Importation…","decor.image_asset":"Fichier image","decor.image_pick_hint":"Importez une image ou choisissez-en une existante.","decor.image_place_hint":"Cliquez sur le plan pour placer l’image.","decor.image_none":"Aucune image importée pour le moment.","decor.image_unavailable":"Image indisponible","decor.image_used":"Utilisée dans {n} objets","decor.image_upload_failed":"Impossible d’importer l’image : {err}","decor.image_error_capacity":"Le stockage des images personnalisées est plein.","decor.image_in_use":"Supprimez toutes les copies placées avant ce fichier.","decor.image_delete_title":"Supprimer le fichier image ?","decor.image_delete_message":"Supprimer « {name} » de House Plan ? Cette action est irréversible.","furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis","common.yes":"Oui","common.no":"Non","vac.diag_source":"Source","vac.diag_platform":"Intégration","vac.diag_status":"État","vac.diag_position":"Position","vac.diag_rooms":"Pièces","vac.diag_rooms_value":"{total} · {matched} noms correspondent · {readiness}","vac.autocal_ready":"calibration automatique disponible","vac.autocal_not_ready":"3 noms correspondants requis","vac.diag_path":"Chemin de l’intégration","vac.diag_map":"ID de carte","vac.source_none":"non sélectionné","vac.source_status_ok":"Prêt","vac.source_status_missing":"Manquant","vac.source_status_disabled":"Désactivé dans Home Assistant","vac.source_status_unavailable":"Indisponible","vac.source_status_unverified":"Impossible à vérifier avec les autorisations actuelles","vac.source_status_unsupported":"Aucune donnée de position","vac.source_status_none":"Aucune source","vac.source_banner_missing":"La source enregistrée n’existe plus. Elle n’a pas été remplacée automatiquement ; choisissez une autre source ou restaurez-la dans Home Assistant.","vac.source_banner_disabled":"La source enregistrée est désactivée dans Home Assistant. Activez-la ou choisissez une autre source.","vac.source_banner_unverified":"Les autorisations Home Assistant actuelles ne permettent pas de vérifier cette source enregistrée. Elle reste épinglée et ne sera pas remplacée automatiquement.","vac.choose_source":"Choisir la source","vac.source_auto":"Automatique","vac.source_auto_hint":"Utiliser une entité compatible de cet appareil","vac.all_cameras":"Toutes les caméras","vac.all_cameras_warn":"Une caméra peut ne pas fournir de données du robot. Choisissez-en une uniquement s’il s’agit de la carte de votre aspirateur.","vac.all_cameras_empty":"Aucune autre entité caméra trouvée.","vac.platform_unknown":"intégration inconnue","vac.cap_position":"position","vac.cap_rooms_short":"pièces","vac.cap_path":"trajet","vac.cap_map":"ID de carte","vac.cap_none":"aucune donnée de robot détectée","vac.xcme_hint":"Activez ces attributs Xiaomi Cloud Map Extractor :","vac.documentation":"Documentation","vac.residual_title":"Vérifier la calibration automatique","vac.residual_message":"Les pièces correspondantes présentent un écart maximal de {error}. Appliquez cette calibration approximative, affinez-la manuellement ou annulez sans modifier la configuration enregistrée.","vac.apply_proposal":"Appliquer","gs.backup_group":"Sauvegarde et transfert","gs.backup_hint":"Téléchargez une sauvegarde JSON portable ou prévisualisez et importez une sauvegarde créée par House Plan.","backup.export_open":"Exporter","backup.import_open":"Importer","backup.export_title":"Exporter House Plan","backup.import_title":"Importer House Plan","backup.export_hint":"Choisissez si la sauvegarde doit contenir toute la configuration House Plan ou uniquement l’espace actuel.","backup.full":"Sauvegarde complète","backup.current_space":"Espace actuel","backup.current_space_title":"Espace actuel : {title}","backup.no_current_space":"Aucun espace actuel","backup.plan_only":"Plan uniquement","backup.plan_only_hint":"Conserver les pièces, murs, ouvertures, décorations et positions des étiquettes de pièces sans les appareils ni les associations Home Assistant.","backup.plan_only_preview":"Ce fichier contient uniquement le plan","backup.privacy_warning":"L’archive conserve les noms, identifiants Home Assistant et coordonnées exactes. Les plans internes et pièces jointes sont référencés, pas intégrés ; les états d’exécution et trajets d’aspirateur ne sont pas inclus.","backup.download":"Télécharger le JSON","backup.export_done":"Sauvegarde téléchargée","backup.reading":"Vérification de la sauvegarde…","backup.revalidated":"Le plan a changé depuis cet aperçu. Le résumé a été actualisé ; vérifiez-le et confirmez de nouveau.","backup.error.support_invalid_message":"Vérifiez le message d’assistance et réessayez.","backup.error.support_package_too_large":"Le paquet d’assistance anonymisé dépasse la limite de 8 Mio.","backup.error.support_preview_expired":"L’aperçu de la pièce jointe d’assistance a expiré ou n’est plus disponible.","backup.error.support_rate_limited":"Trop de rapports ou d’aperçus d’assistance ont été demandés. Réessayez plus tard.","backup.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","backup.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible.","backup.error.unauthorized":"Vous n’avez pas l’autorisation d’exporter ou d’importer ce plan.","backup.error.not_ready":"House Plan n’est pas encore prêt. Réessayez dans un instant.","backup.error.too_large":"La sauvegarde dépasse la limite de 8 Mio.","backup.error.invalid_json":"Le fichier sélectionné n’est pas un JSON valide.","backup.error.invalid_format":"Le fichier sélectionné n’est pas une sauvegarde House Plan.","backup.error.invalid_image":"L’image est endommagée ou ne correspond pas à son format.","backup.error.unsupported_export_version":"Ce format de sauvegarde n’est pas pris en charge par la version installée.","backup.error.unsupported_image":"Utilisez une image PNG, JPEG, WebP ou SVG prise en charge.","backup.error.future_model":"La sauvegarde a été créée avec un modèle de données House Plan plus récent.","backup.error.invalid_config":"La sauvegarde contient une configuration House Plan invalide.","backup.error.wall_model_migration_blocked":"Le modèle de murs de la sauvegarde n’a pas pu être mis à niveau en toute sécurité. Optimisez d’abord le plan source, puis exportez-le de nouveau.","backup.error.invalid_layout":"La sauvegarde contient des positions d’objets invalides.","backup.error.invalid_content":"La sauvegarde contient des références de contenu invalides ou incohérentes.","backup.error.space_not_found":"L’espace sélectionné n’existe plus.","backup.error.capacity_exceeded":"L’ajout de cette sauvegarde dépasserait les limites du plan.","backup.error.preview_expired":"L’aperçu a expiré. Sélectionnez de nouveau le fichier de sauvegarde.","backup.error.preview_owner_mismatch":"Cet aperçu appartient à un autre utilisateur Home Assistant.","backup.error.conflict":"Le plan a changé depuis l’aperçu. Vérifiez le résumé actualisé.","backup.error.content_confirmation_required":"Confirmez que le contenu local indisponible peut être dissocié.","backup.error.commit_failed":"La sauvegarde n’a pas pu être appliquée en toute sécurité. Le plan précédent a été restauré ou est en attente de récupération.","backup.error.missing_plan":"Un fichier de plan référencé a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.missing_content":"Une pièce jointe locale référencée a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.marker_control_missing":"Une lumière liée au plan est absente de la sauvegarde.","backup.error.marker_control_not_light":"Une cible liée au plan n’est plus marquée comme source lumineuse.","backup.error.marker_control_self":"Une source lumineuse ne peut pas se contrôler elle-même.","backup.error.marker_control_cycle":"La sauvegarde contient une chaîne circulaire de contrôles de lumière.","backup.error.duplicate_marker_control":"La sauvegarde contient un lien de lumière du plan en doublon.","backup.error.no_backup":"Aucun instantané d’importation ou d’optimisation n’est disponible à restaurer.","backup.error.in_use":"L'élément est encore utilisé","backup.error.invalid_data":"La requête contient des données invalides","backup.error.invalid_light_entity":"La lumière principale doit être une entité light.* ou switch.*","backup.error.invalid_marker_control":"Référence de contrôle de marqueur invalide","backup.error.invalid_name":"Le nom est invalide","backup.error.invalid_partition_opening_host":"L'ouverture doit conserver sa cloison porteuse","backup.error.invalid_partition_opening_jamb_margin":"L'ouverture ne laisse aucun jambage physique au bout du mur","backup.error.invalid_passage_fields":"Un passage ouvert ne peut pas porter de réglages de porte","backup.error.invalid_space_id":"Espace inconnu","backup.error.invalid_toggle_entity":"L'entité de bascule doit être light.* ou switch.*","backup.error.invalid_value_badge":"Réglages de badge de valeur invalides","backup.error.invalid_value_badge_attribute":"Attribut de badge de valeur invalide","backup.error.invalid_value_badge_position":"Position de badge de valeur invalide","backup.error.invalid_value_badge_source":"Source de badge de valeur invalide","backup.error.invalid_vacuum_map_route":"Vérifiez l'affectation des cartes du robot aux espaces.","backup.error.invalid_value_source":"Source de valeur invalide","backup.error.invalid_value_source_attribute":"Attribut de source de valeur invalide","backup.error.io_error":"Une opération de fichier a échoué sur le serveur","backup.error.not_toggleable":"Cet appareil ne peut pas être basculé","backup.error.nothing_to_repair":"Rien à réparer","backup.error.space_in_use":"L'espace est encore référencé","backup.error.value_badge_source_required":"Le badge de valeur nécessite une source","backup.error.wall_model_client_outdated":"Le plan a été mis à jour ailleurs — rechargez la page","backup.same_source":"Créée sur cette instance Home Assistant","backup.foreign_source":"Créée sur une autre instance Home Assistant","backup.created":"Créée : {value}","backup.versions":"Carte {card} ; intégration {integration} ; modèle de données {model}","backup.count_spaces":"Espaces : {n}","backup.count_rooms":"Pièces : {n}","backup.count_walls":"Murs : {n}","backup.count_openings":"Ouvertures : {n}","backup.count_decor":"Objets décoratifs : {n}","backup.count_markers":"Appareils : {n}","backup.count_layout":"Positions : {n}","backup.bindings":"Associations — appareils : {device}, entités : {entity}, virtuels : {virtual} ; positions sans espace : {legacy}","backup.binding_status":"État des cibles — actives : {active}, désactivées : {disabled}, manquantes : {missing}","backup.missing_areas":"Zones absentes sur la cible : {areas}","backup.dropped_marker_links":"Liens de lumières du plan hors de cet espace transféré omis : {n}.","backup.room_drafts_migrated":"Anciens contours inachevés convertis en murs ordinaires : {drafts} ; segments : {segments}.","backup.repaired_target_refs":"Références existantes restaurées par cet import d’espace : {n}.","backup.preserved_unresolved_refs":"Références qui n’ont pas pu être restaurées sans ambiguïté conservées : {n}.","backup.preserved_unresolved_hint":"Aucune donnée n’a été devinée ni supprimée. Après l’importation, lancez « Optimiser les plans » pour examiner les références restantes.","backup.import_details":"Détails des références d’importation","backup.import_detail.incoming_remapped":"Références mises à jour dans la copie importée : {n}","backup.import_detail.target_repaired":"Références existantes restaurées : {n}","backup.import_detail.preserved_unresolved":"Références non résolues conservées : {n}","backup.import_detail.collisions":"Conflits de destination conservés en toute sécurité : {n}","backup.import_detail.dropped_links":"Liens entrants omis selon les règles de transfert : {n}","backup.import_detail.bounded_lineages":"Identifiants trop imbriqués maintenus dans les limites : {n}","backup.replace_warning":"Cela remplace la configuration et la disposition actuelles. Les fichiers importés ne sont jamais supprimés. Une seule annulation reste disponible jusqu’à la prochaine modification du plan.","backup.foreign_bookkeeping":"Les données de suivi des appareils connus/nouveaux propres à l’instance ne seront pas importées.","backup.final_name":"Nom du nouvel espace","backup.target_settings":"Les paramètres généraux de l’instance cible restent inchangés.","backup.duplicates":"Associations déjà présentes : {n}","backup.skip":"Ignorer les appareils en doublon","backup.virtual_copy":"Ajouter des copies virtuelles statiques sûres","backup.content":"Contenu référencé","backup.decor_images_summary":"Images personnalisées : {objects} objets, {assets} fichiers ; fichiers absents : {missing}.","backup.content_available":"disponible localement","backup.content_external":"lien externe","backup.content_detach_required":"sera dissocié","backup.confirm_detach":"Je comprends que les plans internes et pièces jointes indisponibles seront dissociés de la configuration importée.","backup.confirm_missing_images":"Je comprends que les images personnalisées absentes resteront des espaces réservés réparables et que les autres fichiers locaux indisponibles seront dissociés.","backup.replace":"Remplacer","backup.add":"Ajouter un espace","backup.space_done":"Espace importé : {rooms} pièces, {markers} appareils, {refs} références existantes restaurées","backup.full_done":"Sauvegarde restaurée : {spaces} espaces, {rooms} pièces, {markers} appareils","backup.undo_import":"Annuler la dernière importation complète","backup.import_undone":"Importation complète annulée","backdrop.large_title":"Grande image","backdrop.large_body":"Cette image fait {w}×{h} (fichier de {fileMb} Mo) et nécessite environ {decodedMb} Mo de mémoire pour s'afficher. Sur tablette, cela peut faire planter la page.","backdrop.unknown_body":"Les dimensions de l'image n'ont pas pu être lues — le fichier est peut-être endommagé. Continuer peut faire planter la page sur tablette.","backdrop.reduced_dimensions":"Copie réduite : {w}×{h} px.","backdrop.use_downscaled":"Téléverser une copie réduite","backdrop.reducing":"Réduction…","backdrop.keep_original":"Conserver l'original","backdrop.too_large_title":"Image trop grande","backdrop.too_large_body":"Cette image dépasse ce que les navigateurs peuvent afficher ({w}×{h}, limite {limit} px par côté). Réduisez-la dans un éditeur de bureau puis téléversez-la à nouveau.","backdrop.downscale_failed":"Impossible de créer la copie réduite. Le plan actuel n'a pas été modifié."};const r="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";export{e as dictionary,r as fingerprint}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js b/dist/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js similarity index 99% rename from custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js rename to dist/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js index ed8f81c3..11c00407 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/furniture-plan-art.generated-MsQg9zvn.js +++ b/dist/houseplan-assets/furniture-plan-art.generated-D_9nJ3h5.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";const c="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e",a={coffee_table:{d:"M3.84 5.884c0-1.21 1.048-2.192 2.34-2.192h107.64c1.293 0 2.34.981 2.34 2.192v48.23c0 1.212-1.047 2.193-2.34 2.193H6.18c-1.292 0-2.34-.981-2.34-2.192z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},coffee_table_round:{d:"M3.765 40a36.235 36.235 0 1 0 72.47 0 36.235 36.235 0 1 0-72.47 0 m56.26 26.96-3.843-3.843a.906.906 0 0 1 0-1.28l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.843 3.844a.906.906 0 0 1 0 1.28l-3.843 3.844a.906.906 0 0 1-1.281 0m-34.423-34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.844a.906.906 0 0 1 0 1.28l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.843a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.843a.906.906 0 0 1-1.28 0",viewW:80,viewH:80},coffee_table_oval:{d:"M3.84 30c0-14.53 12.572-26.308 28.08-26.308h56.16c15.509 0 28.08 11.778 28.08 26.308s-12.571 26.307-28.08 26.307H31.92C16.412 56.307 3.84 44.53 3.84 30 M80.592 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877M31.92 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876",viewW:120,viewH:60},coffee_table_rounded:{d:"M3.84 12.461c0-4.843 4.19-8.77 9.36-8.77h93.6c5.17 0 9.36 3.927 9.36 8.77v35.077c0 4.843-4.19 8.77-9.36 8.77H13.2c-5.17 0-9.36-3.927-9.36-8.77z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},table_dining:{d:"M3.879 6.08c0-1.265 1.065-2.29 2.378-2.29h147.484c1.314 0 2.38 1.025 2.38 2.29v77.84c0 1.265-1.066 2.29-2.38 2.29H6.257c-1.313 0-2.378-1.025-2.378-2.29z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},table_round:{d:"M3.826 55a51.174 51.174 0 1 0 102.349 0A51.174 51.174 0 1 0 3.826 55 m81.005 32.303-3.947-3.947a.93.93 0 0 1 0-1.316l3.947-3.948a.93.93 0 0 1 1.316 0l3.948 3.948a.93.93 0 0 1 0 1.316l-3.948 3.947a.93.93 0 0 1-1.316 0m0 54.897-3.947-3.948a.93.93 0 0 1 0-1.316l3.947-3.947a.93.93 0 0 1 1.316 0l3.948 3.947a.93.93 0 0 1 0 1.316L82.32 87.2a.93.93 0 0 1-1.316 0M27.04 32.304l-3.947-3.948a.93.93 0 0 1 0-1.315l3.948-3.948a.93.93 0 0 1 1.315 0l3.948 3.948a.93.93 0 0 1 0 1.315l-3.948 3.948a.93.93 0 0 1-1.315 0m-.001 54.604-3.947-3.948a.93.93 0 0 1 0-1.316l3.948-3.947a.93.93 0 0 1 1.315 0l3.948 3.947a.93.93 0 0 1 0 1.316l-3.948 3.948a.93.93 0 0 1-1.315 0",viewW:110,viewH:110},table_dining_oval:{d:"M3.892 50c0-25.51 21.418-46.19 47.838-46.19h76.54c26.42 0 47.839 20.68 47.839 46.19S154.69 96.19 128.27 96.19H51.73C25.31 96.19 3.892 75.51 3.892 50 M122.53 19.514V13.97a.957.924 0 0 1 .956-.924h5.74a.957.924 0 0 1 .958.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m.001 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.957-.924M49.816 19.515v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .958.924v5.542a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m0 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.923h-5.74a.957.924 0 0 1-.957-.924",viewW:180,viewH:100},table_dining_rounded:{d:"M3.879 17.527c0-7.587 6.39-13.737 14.272-13.737h123.696c7.883 0 14.273 6.15 14.273 13.737v54.947c0 7.587-6.39 13.737-14.273 13.737H18.151c-7.882 0-14.272-6.15-14.272-13.737z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},desk:{d:"M3.862 5.967c0-1.234 1.057-2.234 2.362-2.234h127.552c1.305 0 2.362 1 2.362 2.234v58.066c0 1.234-1.057 2.233-2.362 2.233H6.224c-1.305 0-2.362-1-2.362-2.233z M9.531 15.346v-5.36a.945.893 0 0 1 .945-.893h5.67a.945.893 0 0 1 .944.893v5.36a.945.893 0 0 1-.945.894h-5.669a.945.893 0 0 1-.945-.894m113.379.001v-5.36a.945.893 0 0 1 .945-.894h5.67a.945.893 0 0 1 .944.894v5.36a.945.893 0 0 1-.945.893h-5.669a.945.893 0 0 1-.945-.893M9.53 60.013v-5.36a.945.893 0 0 1 .946-.893h5.669a.945.893 0 0 1 .945.893v5.36a.945.893 0 0 1-.945.894h-5.67a.945.893 0 0 1-.944-.894m113.38.001v-5.36a.945.893 0 0 1 .945-.894h5.669a.945.893 0 0 1 .945.894v5.36a.945.893 0 0 1-.945.893h-5.67a.945.893 0 0 1-.944-.893m-97.318-2.681h88.814",viewW:140,viewH:70},desk_corner:{d:"M156.12 66.202a2.38 2.38 0 0 1-2.379 2.38H94.272c-13.138 0-23.788 10.65-23.788 23.787v61.372a2.38 2.38 0 0 1-2.379 2.38H6.257a2.38 2.38 0 0 1-2.378-2.38V6.257A2.38 2.38 0 0 1 6.257 3.88h147.484a2.38 2.38 0 0 1 2.38 2.378z M9.588 16.249v-5.71a.95.95 0 0 1 .951-.95h5.71a.95.95 0 0 1 .95.95v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m133.212.001v-5.71a.95.95 0 0 1 .951-.951h5.71a.95.95 0 0 1 .95.951v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m0 45.672v-5.71a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.95-.951M9.587 149.46v-5.708a.95.95 0 0 1 .952-.952h5.709a.95.95 0 0 1 .951.952v5.709a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.951-.951m47.576 0v-5.709a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.95h-5.71a.95.95 0 0 1-.951-.95m51.382-90.396H95.569a34.6 34.6 0 0 0-34.6 34.6v12.976",viewW:160,viewH:160},chair:{d:"M39.452 12.433H10.548a4.398 4.398 0 1 1 0-8.796h28.904a4.398 4.398 0 0 1 0 8.796m-28.904 0H8.035a4.4 4.4 0 0 0-4.398 4.399V40.08a6.283 6.283 0 0 0 6.283 6.284h30.16a6.283 6.283 0 0 0 6.284-6.284V16.832c0-2.43-1.97-4.399-4.399-4.399h-2.513",viewW:50,viewH:50},chair_bar:{d:"M38.579 17.168c1.326 2.526 1.947 6.015 1.947 9.071 0 10.018-8.07 18.139-18.025 18.139S4.475 36.257 4.475 26.239c0-3.056.586-6.552 1.912-9.078m32.192.007a3.59 3.59 0 0 1-3.333-.976m3.333.976a3.6 3.6 0 0 0 1.765-.976m-33.827.996-.13-.027a3.6 3.6 0 0 1-1.731-.969m30.59 0a18 18 0 0 0-5.848-3.932 17.93 17.93 0 0 0-13.796 0 18 18 0 0 0-5.848 3.932 3.59 3.59 0 0 1-3.237.996m28.729-.996a3.59 3.59 0 0 0 5.098 0m-33.827.996a3.6 3.6 0 0 1-1.861-.996 3.644 3.644 0 0 1 0-5.13 25.2 25.2 0 0 1 8.187-5.505A25.1 25.1 0 0 1 22.5 3.623a25.1 25.1 0 0 1 9.657 1.934 25.2 25.2 0 0 1 8.187 5.505 3.644 3.644 0 0 1 0 5.13",viewW:45,viewH:48},armchair:{d:"M75.702 13.011q.012-.225.012-.453c0-4.843-3.917-8.768-8.748-8.768H23.034c-4.83 0-8.747 3.925-8.747 8.768q0 .228.011.453M77.132 72.09q.59.091 1.206.092c4.348 0 7.873-3.533 7.873-7.892V20.45c0-4.359-3.525-7.892-7.873-7.892-.924 0-1.812.16-2.636.453a7.89 7.89 0 0 0-5.237 7.438v.148m0 0a8.7 8.7 0 0 1-3.499.73H23.034a8.7 8.7 0 0 1-3.499-.73m50.93 0V64.29a7.89 7.89 0 0 0 6.667 7.8M14.298 13.01a7.89 7.89 0 0 1 5.237 7.438v.148m0 0V64.29a7.89 7.89 0 0 1-6.666 7.8q-.59.091-1.206.092c-4.348 0-7.873-3.533-7.873-7.892V20.45c0-4.359 3.525-7.892 7.873-7.892.924 0 1.811.16 2.635.453M77.132 72.09c-1.585 8.05-8.667 14.12-17.164 14.12H30.032c-8.496 0-15.578-6.07-17.163-14.12",viewW:90,viewH:90},armchair_office:{d:"M56.968 18.845q0-.368-.05-.72M49.051 13.8H15.95a5.04 5.04 0 0 1-5.038-5.043 5.04 5.04 0 0 1 5.038-5.043h33.103a5.04 5.04 0 0 1 5.038 5.043 5.04 5.04 0 0 1-5.038 5.043m-33.103 0h-2.88a5.04 5.04 0 0 0-4.986 4.323M49.052 13.8h2.879a5.04 5.04 0 0 1 4.986 4.324m.051 24.826a4.32 4.32 0 0 0 4.318-4.323v-16.18a4.32 4.32 0 0 0-4.369-4.322m.051 24.826a4.32 4.32 0 0 1-4.318-4.323V22.447a4.32 4.32 0 0 1 4.267-4.322m-11.84 37.24h4.695c.736 0 1.446-.111 2.115-.317a7.21 7.21 0 0 0 5.081-6.889v-5.208M8.084 18.124h-.051a4.32 4.32 0 0 0-4.318 4.323v16.18a4.32 4.32 0 0 0 4.318 4.324 4.32 4.32 0 0 0 4.317-4.323V22.447a4.32 4.32 0 0 0-4.266-4.323m11.935 37.24h-4.79a7.2 7.2 0 0 1-2.04-.294 7.21 7.21 0 0 1-5.156-6.91v-5.21m37.045 12.414 5.177 5.183c.969.97 2.534.987 3.524.038a2.526 2.526 0 0 0 .038-3.605l-1.93-1.932m-6.81.316H20.02m-6.83-.294-1.909 1.91c-.998 1-.98 2.627.038 3.605.99.949 2.555.932 3.524-.038l5.177-5.183",viewW:65,viewH:65},sofa:{d:"M90 19.365v57.111m0-57.11V7.683m0 11.681c0 2.151-1.836 3.894-4.1 3.894H30.544a10.7 10.7 0 0 1-4.136-.825M90 19.365c0 2.151 1.836 3.894 4.1 3.894h55.356c1.472 0 2.871-.294 4.137-.825M90 76.476c0 5.376-4.59 9.735-10.25 9.735H30.543c-5.266 0-9.605-3.772-10.185-8.625M90 76.476c0 5.376 4.59 9.735 10.25 9.735h49.206c5.266 0 9.605-3.772 10.185-8.625M90 7.684c0-2.15-1.837-3.894-4.101-3.894H30.544c-5.661 0-10.25 4.358-10.25 9.735q0 .416.036.825M90 7.684c0-2.15 1.836-3.894 4.1-3.894h55.356c5.661 0 10.25 4.358 10.25 9.735q0 .416-.036.825m0 0a10.7 10.7 0 0 1 4.137-.825h2.05c5.662 0 10.252 4.358 10.252 9.734v45.43c0 5.376-4.59 9.734-10.251 9.734h-2.05c-1.484 0-2.894-.3-4.167-.837m0 0c-3.585-1.517-6.084-4.93-6.084-8.898V23.26q0-.417.036-.825c.32-3.622 2.728-6.68 6.077-8.084m-139.34 0c3.35 1.404 5.758 4.462 6.078 8.084q.036.408.036.825v45.43c0 3.967-2.5 7.38-6.085 8.897a10.7 10.7 0 0 1-4.166.837h-2.05c-5.662 0-10.251-4.358-10.251-9.735V23.26c0-5.376 4.59-9.734 10.25-9.734h2.05c1.473 0 2.872.294 4.138.825",viewW:180,viewH:90},sofa_three_seat:{d:"M86.553 18.593V76.96m0-58.366V7.491m0 11.102c0 2.044-1.762 3.701-3.935 3.701H29.496c-1.413 0-2.756-.28-3.97-.784m61.027-2.917c0 2.044 1.762 3.701 3.935 3.701h59.024c2.174 0 3.935-1.657 3.935-3.7M86.553 76.958c0 5.11-4.404 9.252-9.837 9.252h-47.22c-5.054 0-9.218-3.585-9.775-8.198m66.832-1.054c0 5.11 4.404 9.252 9.837 9.252h47.22c5.433 0 9.837-4.142 9.837-9.252m0-58.366V76.96m0-58.366V7.491m0 11.102c0 2.044 1.762 3.701 3.936 3.701h53.122c1.413 0 2.756-.28 3.97-.784m-61.028 55.449c0 5.11 4.405 9.252 9.838 9.252h47.22c5.054 0 9.218-3.585 9.775-8.198M86.553 7.491c0-2.044-1.762-3.701-3.935-3.701H29.496c-5.433 0-9.838 4.142-9.838 9.252q0 .396.035.784m66.86-6.335c0-2.044 1.762-3.701 3.935-3.701h59.024c2.174 0 3.935 1.657 3.935 3.7m0 0c0-2.043 1.762-3.7 3.936-3.7h53.122c5.433 0 9.838 4.142 9.838 9.252 0 .258.022.517 0 .77m-.063 64.201c1.22.512 2.574.796 3.998.796h1.967c5.433 0 9.837-4.142 9.837-9.252V22.294c0-5.11-4.404-9.252-9.837-9.252h-1.967c-5.153 0-9.38 3.725-9.803 8.468q-.036.387-.035.784v47.263c0 3.771 2.399 7.015 5.84 8.456M19.693 13.826a10.3 10.3 0 0 0-3.97-.784h-1.967c-5.433 0-9.838 4.142-9.838 9.252v47.263c0 5.11 4.405 9.252 9.838 9.252h1.967c1.424 0 2.777-.284 3.998-.796 3.441-1.441 5.84-4.685 5.84-8.456V22.294a9 9 0 0 0-.035-.784c-.307-3.443-2.618-6.349-5.833-7.684",viewW:240,viewH:90},sofa_corner_right:{d:"M93.673 20.687V83.69m0-63.004v-12.6m0 12.6c0 2.32-1.913 4.2-4.273 4.2H31.704a10.8 10.8 0 0 1-4.311-.89m66.28-3.31c0 2.32 1.914 4.2 4.274 4.2h64.106c2.36 0 4.274-1.88 4.274-4.2M93.673 83.692c0 5.8-4.783 10.501-10.684 10.501H31.704c-5.489 0-10.011-4.068-10.616-9.304m72.585-1.197c0 5.8 4.784 10.501 10.684 10.501h51.286c5.9 0 10.684-4.701 10.684-10.5m0-63.005V83.69m0-63.004v-12.6m0 12.6c0 2.32 1.914 4.2 4.273 4.2h57.696c1.534 0 2.993-.317 4.312-.89m-66.28 59.695v71.923c0 5.799 4.782 10.5 10.684 10.5h51.284c5.49 0 10.012-4.068 10.616-9.304V84.888M93.673 8.086c0-2.32-1.913-4.2-4.273-4.2H31.704c-5.9 0-10.684 4.7-10.684 10.5q0 .45.038.89m72.615-7.19c0-2.32 1.914-4.2 4.274-4.2h64.106c2.36 0 4.274 1.88 4.274 4.2m0 0c0-2.32 1.914-4.2 4.273-4.2h57.696c5.9 0 10.685 4.7 10.685 10.5 0 .293.024.587 0 .874m-.07 69.628c1.327.58 2.797.904 4.344.904h2.136c5.901 0 10.684-4.702 10.684-10.501V24.887c0-5.8-4.783-10.5-10.684-10.5h-2.136c-5.596 0-10.187 4.227-10.647 9.61q-.038.44-.038.89V75.29c0 4.28 2.605 7.961 6.342 9.597M21.059 15.276a10.8 10.8 0 0 0-4.312-.89H14.61c-5.9 0-10.684 4.701-10.684 10.5v50.405c0 5.8 4.783 10.5 10.684 10.5h2.137c1.546 0 3.016-.322 4.342-.903 3.737-1.636 6.342-5.317 6.342-9.597V24.887q0-.45-.037-.89c-.334-3.907-2.844-7.206-6.335-8.72",viewW:260,viewH:170},bed_single:{d:"M3.79 14.024c0 5.59 4.318 10.122 9.645 10.122h63.13c5.328 0 9.646-4.532 9.646-10.122m-22.797 46.93V46.23c0-5.082-3.926-9.201-8.769-9.201h-19.29c-4.842 0-8.768 4.12-8.768 9.201v14.723m-22.797 0h82.42m0 22.085H3.79m8.768 113.06h64.885c4.842 0 8.768-4.12 8.768-9.202V13.104c0-5.082-3.926-9.202-8.768-9.202H12.558c-4.843 0-8.768 4.12-8.768 9.202v173.792c0 5.082 3.925 9.202 8.768 9.202",viewW:90,viewH:200},bed_double:{d:"M3.879 14.073c0 5.618 4.516 10.172 10.088 10.172h132.065c5.571 0 10.088-4.554 10.088-10.172m-81.165 47.16V46.438c0-5.107-4.106-9.247-9.171-9.247H45.607c-5.065 0-9.17 4.14-9.17 9.247v14.795m89.877 0V46.438c0-5.107-4.107-9.247-9.172-9.247H96.966c-5.065 0-9.171 4.14-9.171 9.247v14.795m-83.916 0H156.12m0 22.192H3.88m9.17 112.673h133.9c5.065 0 9.171-4.14 9.171-9.247V13.15c0-5.107-4.106-9.247-9.171-9.247H13.05c-5.064 0-9.17 4.14-9.17 9.247v173.7c0 5.107 4.106 9.247 9.17 9.247",viewW:160,viewH:200},nightstand:{d:"M5.773 3.555h38.454a2.136 2.056 0 0 1 2.137 2.056v28.777a2.136 2.056 0 0 1-2.137 2.056H5.773a2.136 2.056 0 0 1-2.136-2.056V5.611a2.136 2.056 0 0 1 2.136-2.056",viewW:50,viewH:40},cabinet_tv:{d:"M56.772 17.88h5.315m0 0h5.315m-5.315 0v9.214m9.832-9.214 5.315 9.45 5.314-9.45M6.224 41.4h127.552c1.305 0 2.362-.94 2.362-2.1V5.7c0-1.16-1.057-2.1-2.362-2.1H6.224c-1.305 0-2.362.94-2.362 2.1v33.6c0 1.16 1.057 2.1 2.362 2.1",viewW:140,viewH:45},cabinet_shoe:{d:"m39.722 16.231 1.505-1.596m1.134 3.15 1.53-1.738M6.03 31.5h67.94c1.251 0 2.265-.895 2.265-2v-24c0-1.105-1.014-2-2.264-2H6.03c-1.251 0-2.265.895-2.265 2v24c0 1.105 1.014 2 2.265 2m41.966-14.305L46.92 17.1a3.4 3.4 0 0 1-1.813-.706l-4.583-3.62c-1.264-1-3.277-.326-3.475 1.161-.185 1.39-1.983 2.1-3.28 1.299l-1.532-.947c-.968-.513-2.2.103-2.2 1.1v3.463c0 1.559 1.43 2.823 3.196 2.823h14.51c1.404 0 2.542-1.005 2.542-2.245 0-1.153-.99-2.118-2.289-2.233",viewW:80,viewH:35},cabinet_sink:{d:"M3.765 5.773c0-1.18 1.014-2.136 2.265-2.136h67.94c1.251 0 2.265.956 2.265 2.136v38.454c0 1.18-1.014 2.137-2.264 2.137H6.03c-1.251 0-2.265-.957-2.265-2.137z M36.088 32.135c2.525 1.88 6.205 1.88 8.73 0s3.167-5.101 1.52-7.637l-5.879-8.043-5.893 8.043c-1.644 2.536-1.003 5.755 1.522 7.637",viewW:80,viewH:50},bookshelf:{d:"M57.12 20.488H45.473c-.514 0-1.008.124-1.372.345s-.568.52-.568.832m4.076-8.236h5.434M6.119 3.5h87.762c1.276 0 2.31.895 2.31 2v24c0 1.105-1.034 2-2.31 2H6.12c-1.275 0-2.31-.895-2.31-2v-24c0-1.105 1.035-2 2.31-2m51 6.4v14.118H45.474a2.04 2.04 0 0 1-1.372-.517 1.7 1.7 0 0 1-.568-1.248V11.665c0-.468.204-.917.568-1.248a2.04 2.04 0 0 1 1.372-.517z",viewW:100,viewH:35},wall_unit:{d:"M6.336 41.4h227.328a2.418 2.1 0 0 0 2.418-2.1V5.7a2.418 2.1 0 0 0-2.418-2.1H6.336a2.418 2.1 0 0 0-2.418 2.1v33.6a2.418 2.1 0 0 0 2.418 2.1m43.744-5.88V9.48m46.432 26.04V9.48m46.433 26.04V9.48m46.433 26.04V9.48",viewW:240,viewH:45},wardrobe:{d:"M93.87 20.25a3.3 3.3 0 0 0-1.072-2.407 3.8 3.8 0 0 0-2.586-.997c-.97 0-1.9.358-2.587.997a3.3 3.3 0 0 0-1.071 2.407c0 2.838 1.225 5.107 3.658 6.81h-.015m0 0 14.58 7.537c.57.295 1.046.726 1.377 1.25.331.523.505 1.12.505 1.727v1.401a3.3 3.3 0 0 1-1.071 2.407 3.8 3.8 0 0 1-2.587.998H77.393a3.8 3.8 0 0 1-2.586-.998 3.3 3.3 0 0 1-1.072-2.407v-1.4c0-.608.174-1.205.505-1.728a3.55 3.55 0 0 1 1.377-1.25zM6.284 3.691h167.433c1.32 0 2.392.981 2.392 2.192v48.23c0 1.212-1.071 2.193-2.392 2.193H6.284c-1.321 0-2.392-.981-2.392-2.192V5.885c0-1.212 1.07-2.193 2.392-2.193",viewW:180,viewH:60},kitchen_floor:{d:"M3.692 5.884c0-1.21.981-2.192 2.192-2.192h48.23c1.212 0 2.193.981 2.193 2.192v48.23a2.19 2.19 0 0 1-2.192 2.193H5.885a2.19 2.19 0 0 1-2.193-2.192z",viewW:60,viewH:60},kitchen_floor_corner:{d:"M45.944 41.767a2.29 2.29 0 0 0 2.29 2.29H83.92a2.29 2.29 0 0 1 2.29 2.29V83.92a2.29 2.29 0 0 1-2.29 2.29H6.08a2.29 2.29 0 0 1-2.29-2.29V6.08a2.29 2.29 0 0 1 2.29-2.29h37.576a2.29 2.29 0 0 1 2.29 2.29z",viewW:90,viewH:90},kitchen_wall:{d:"m4.444 31.033 50.75-27.007m-50.752-.06 50.75 27.008M5.884 31.5h48.23c1.212 0 2.193-.895 2.193-2v-24c0-1.105-.981-2-2.192-2H5.885c-1.212 0-2.193.895-2.193 2v24c0 1.105.981 2 2.192 2",viewW:60,viewH:35},kitchen_wall_corner:{d:"M3.772 29.59 29.88 4.383M4.57 55.43 55.43 30M4.175 4.383l26.701 23.863m-27.184.877L55.43 55.43M28.41 3.692H5.884c-1.21 0-2.192.981-2.192 2.192v48.23c0 1.212.981 2.193 2.192 2.193h48.23a2.19 2.19 0 0 0 2.193-2.192V31.589c0-1.21-.981-2.192-2.192-2.192h-21.32a2.19 2.19 0 0 1-2.193-2.192V5.885a2.19 2.19 0 0 0-2.192-2.193",viewW:60,viewH:60},shelf_floor:{d:"M6.12 31.5h87.76a2.31 2 0 0 0 2.31-2v-24a2.31 2 0 0 0-2.31-2H6.12a2.31 2 0 0 0-2.31 2v24a2.31 2 0 0 0 2.31 2 M9.089 25.933c-.494.112-.776.546-.63.97s.664.675 1.157.564l-.263-.767zM90.912 9.067c.493-.112.775-.546.63-.97s-.664-.675-1.158-.564l.264.767zM11.875 26.956c.493-.112.775-.546.63-.97s-.664-.676-1.158-.564l.264.767zm3.988-2.556c-.493.112-.775.546-.63.969s.664.676 1.158.564l-.264-.766zm5.045.511c.493-.112.775-.545.63-.969s-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.111-.775.545-.63.968.146.424.664.677 1.158.565l-.264-.767zm5.044.51c.494-.111.776-.545.63-.968-.145-.424-.664-.676-1.157-.565l.263.767zm3.99-2.555c-.495.112-.777.546-.63.97.145.423.663.675 1.157.563l-.264-.766zm5.043.511c.494-.112.776-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.989-2.555c-.494.111-.776.545-.63.969s.664.676 1.157.564l-.263-.767zm5.044.51c.494-.11.776-.545.63-.968-.146-.424-.664-.676-1.158-.565l.264.767zm3.989-2.555c-.494.112-.776.546-.63.97.145.423.664.675 1.157.564l-.264-.767zm5.044.511c.493-.111.775-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.988-2.555c-.493.112-.775.545-.63.969s.664.676 1.158.564l-.264-.767zm5.045.51c.493-.11.775-.545.63-.968-.146-.424-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.112-.775.546-.63.97s.664.675 1.158.564l-.264-.767zm5.044.511c.494-.111.776-.545.63-.968-.145-.424-.664-.677-1.157-.565l.264.767zm3.99-2.555c-.494.112-.777.545-.63.969.145.423.663.676 1.157.564l-.264-.766zm5.043.511c.494-.112.776-.546.63-.969s-.664-.676-1.157-.564l.263.766zm3.989-2.556c-.494.112-.776.546-.63.97s.664.676 1.158.564l-.264-.767zM9.353 26.7l.263.767 2.259-.511-.264-.767-.264-.767-2.258.511zm6.774-1.533.264.766 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.045.264.767 4.516-1.022-.264-.767-.263-.767-4.517 1.023zm9.033-2.044.264.766 4.516-1.022-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.263.767 4.517-1.022-.264-.767-.264-.767-4.516 1.023zm9.032-2.044.264.767 4.517-1.023-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.264.767 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.044.264.767 4.516-1.023-.263-.766-.264-.767-4.517 1.022zm9.033-2.044.264.766 4.516-1.022-.264-.767-.263-.766-4.517 1.022zM88.39 8.81l.264.767 2.258-.511-.264-.767-.264-.767-2.258.511z M9.089 9.067c-.494-.112-.776-.546-.63-.97s.664-.675 1.157-.564l-.263.767zm81.823 16.866c.493.112.775.546.63.97s-.664.675-1.158.564l.264-.767zM11.875 8.044c.493.112.775.546.63.97s-.664.676-1.158.564l.264-.767zm3.988 2.556c-.493-.112-.775-.546-.63-.969s.664-.676 1.158-.564l-.264.766zm5.045-.511c.493.112.775.545.63.969s-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.111-.775-.545-.63-.968.146-.424.664-.677 1.158-.565l-.264.767zm5.044-.51c.494.111.776.545.63.968-.145.424-.664.676-1.157.565l.263-.767zm3.99 2.555c-.495-.112-.777-.546-.63-.97.145-.423.663-.675 1.157-.563l-.264.766zm5.043-.511c.494.112.776.545.63.969s-.664.676-1.158.564l.264-.767zm3.989 2.555c-.494-.111-.776-.545-.63-.969s.664-.676 1.157-.564l-.263.767zm5.044-.51c.494.11.776.545.63.968-.146.424-.664.676-1.158.565l.264-.767zm3.989 2.555c-.494-.112-.776-.546-.63-.97.145-.423.664-.675 1.157-.564l-.264.767zm5.044-.511c.493.111.775.545.63.969s-.664.676-1.158.564l.264-.767zm3.988 2.555c-.493-.112-.775-.545-.63-.969s.664-.676 1.158-.564l-.264.767zm5.045-.51c.493.11.775.545.63.968-.146.424-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.112-.775-.546-.63-.97s.664-.675 1.158-.564l-.264.767zm5.044-.511c.494.111.776.545.63.968-.145.424-.664.677-1.157.565l.264-.767zm3.99 2.555c-.494-.112-.777-.545-.63-.969.145-.423.663-.676 1.157-.564l-.264.766zm5.043-.511c.494.112.776.546.63.969s-.664.676-1.157.564l.263-.766zm3.989 2.556c-.494-.112-.776-.546-.63-.97s.664-.676 1.158-.564l-.264.767zM9.353 8.3l.263-.767 2.259.511-.264.767-.264.767-2.258-.511zm6.774 1.533.264-.766 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.045.264-.767 4.516 1.022-.264.767-.263.767-4.517-1.023zm9.033 2.044.264-.766 4.516 1.022-.264.766-.264.767-4.516-1.022zm9.033 2.045.263-.767 4.517 1.022-.264.767-.264.767-4.516-1.023zm9.032 2.044.264-.767 4.517 1.023-.264.766-.264.767-4.516-1.022zm9.033 2.045.264-.767 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.044.264-.767 4.516 1.023-.263.766-.264.767-4.517-1.022zm9.033 2.044.264-.766 4.516 1.022-.264.767-.263.766-4.517-1.022zm9.033 2.045.264-.767 2.258.511-.264.767-.264.767-2.258-.511z",viewW:100,viewH:35},shelf_wall:{d:"M18.36 3.15v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.309-.82-2.309-1.833V3.15m73.905 0v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.31-.82-2.31-1.833V3.15m-75.29 0H93.65c1.276 0 2.31.82 2.31 1.833V19.65c0 1.012-1.034 1.833-2.31 1.833H5.888c-1.275 0-2.31-.82-2.31-1.833V4.983c0-1.012 1.035-1.833 2.31-1.833",viewW:100,viewH:25},cooktop_two:{d:"M15 30.982v-1.71m3.086 5.128h1.542M15 39.527v-1.709M10.372 34.4h1.542M5.84 46.364h18.322c1.331 0 2.41-1.196 2.41-2.67V6.306c0-1.475-1.079-2.67-2.41-2.67H5.839c-1.331 0-2.41 1.195-2.41 2.67v37.386c0 1.475 1.079 2.67 2.41 2.67m14.56-29.91c0 3.304-2.417 5.982-5.4 5.982-2.981 0-5.4-2.678-5.4-5.981s2.419-5.982 5.4-5.982c2.983 0 5.4 2.678 5.4 5.982M18.858 34.4c0 2.36-1.727 4.273-3.857 4.273s-3.857-1.913-3.857-4.273S12.87 30.127 15 30.127s3.857 1.913 3.857 4.273",viewW:30,viewH:50},stove:{d:"M41.4 35.261a.877.877 0 1 0-1.754 0zm4.384 6.138a.877.877 0 1 0 0-1.753zM41.4 44.03a.877.877 0 1 0-1.753 0zm-4.384-2.63a.877.877 0 1 0 0-1.754zM5.885 3.691v.877h48.23V2.815H5.885zm50.422 2.192h-.877v48.23h1.754V5.885zm-2.192 50.423v-.877H5.885v1.754h48.23zM3.692 54.115h.877V5.885H2.815v48.23zm2.192 2.192v-.877a1.315 1.315 0 0 1-1.315-1.315H2.815a3.07 3.07 0 0 0 3.07 3.069zm50.423-2.192h-.877c0 .726-.589 1.315-1.315 1.315v1.754a3.07 3.07 0 0 0 3.069-3.07zM54.115 3.692v.877c.726 0 1.315.589 1.315 1.315h1.754a3.07 3.07 0 0 0-3.07-3.069zm-48.23 0v-.877a3.07 3.07 0 0 0-3.07 3.07h1.754c0-.727.589-1.316 1.315-1.316zm19.73 36.83h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.015zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.261h-1.754a7.015 7.015 0 0 0 7.015 7.015zm-6.138-6.138h.877a5.26 5.26 0 0 1 5.261-5.262v-1.754a7.015 7.015 0 0 0-7.015 7.016zm6.138-6.139v.877a5.26 5.26 0 0 1 5.262 5.262h1.754a7.015 7.015 0 0 0-7.016-7.016zm27.185-14.908h-.877a5.26 5.26 0 0 1-5.261 5.262v1.754a7.015 7.015 0 0 0 7.015-7.016zm-6.138 6.139v-.877a5.26 5.26 0 0 1-5.262-5.262h-1.754a7.015 7.015 0 0 0 7.016 7.016zm-6.139-6.139h.877a5.26 5.26 0 0 1 5.262-5.261v-1.754a7.015 7.015 0 0 0-7.016 7.015zm6.139-6.138v.877a5.26 5.26 0 0 1 5.261 5.261h1.754a7.015 7.015 0 0 0-7.015-7.015zm4.384 27.185h-.877a3.51 3.51 0 0 1-3.507 3.507v1.754a5.26 5.26 0 0 0 5.261-5.261zm-4.384 4.384v-.877a3.51 3.51 0 0 1-3.508-3.507H35.26a5.26 5.26 0 0 0 5.262 5.261zm-4.385-4.384h.877a3.51 3.51 0 0 1 3.508-3.508V35.26a5.26 5.26 0 0 0-5.262 5.262zm4.385-4.385v.877a3.51 3.51 0 0 1 3.507 3.508h1.754a5.26 5.26 0 0 0-5.261-5.262zm0 .877h.876V35.26h-1.753v1.754zm3.508 3.508v.876h1.753v-1.753h-1.753zm-3.508 5.261h.876V44.03h-1.753v1.754zm-5.261-5.261v.876h1.753v-1.753h-1.753zm-9.647-21.047h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.016zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.262h-1.754a7.015 7.015 0 0 0 7.015 7.016zm-6.138-6.139h.877a5.26 5.26 0 0 1 5.261-5.261v-1.754a7.015 7.015 0 0 0-7.015 7.015zm6.138-6.138v.877a5.26 5.26 0 0 1 5.262 5.261h1.754a7.015 7.015 0 0 0-7.016-7.015z",viewW:60,viewH:60},tv:{d:"M45.134 10.766H6.18c-1.292 0-2.34.848-2.34 1.894v2.68c0 1.045 1.048 1.893 2.34 1.893h38.954m0-6.467V5.288c0-1.046 1.048-1.894 2.34-1.894h26.704c1.292 0 2.34.848 2.34 1.894v5.478m-31.384 0h31.384m0 0h37.302c1.293 0 2.34.848 2.34 1.894v2.68c0 1.045-1.047 1.893-2.34 1.893H76.518m-31.384 0v5.479c0 1.046 1.048 1.894 2.34 1.894h26.704c1.292 0 2.34-.848 2.34-1.894v-5.479m-31.384 0h31.384",viewW:120,viewH:28},tv_wall:{d:"M35.664 11.4c-.517 0-.936.269-.936.6s.419.6.936.6zm49.553 1.2c.517 0 .936-.269.936-.6s-.42-.6-.936-.6zM6.18 3v.6h107.64V2.4H6.18zm109.98 1.5h-.936v1.8h1.872V4.5zm-2.34 3.3v-.6H6.18v1.2h107.64zM3.84 6.3h.936V4.5H2.904v1.8zm2.34 1.5v-.6c-.775 0-1.404-.403-1.404-.9H2.904c0 1.16 1.467 2.1 3.276 2.1zm109.98-1.5h-.936c0 .497-.629.9-1.404.9v1.2c1.81 0 3.276-.94 3.276-2.1zM113.82 3v.6c.775 0 1.404.403 1.404.9h1.872c0-1.16-1.467-2.1-3.276-2.1zM6.18 3v-.6c-1.81 0-3.276.94-3.276 2.1h1.872c0-.497.629-.9 1.404-.9zm61.308 4.2h-.936V12h1.872V7.2zM52.512 12h.936V7.2h-1.872V12zm-16.848 0v.6h49.553v-1.2H35.664z",viewW:120,viewH:15},toilet:{d:"M3.555 48.976c0 9.55 7.125 17.29 15.914 17.29h1.061c8.79 0 15.914-7.74 15.914-17.29V5.966c0-1.233-.92-2.233-2.056-2.233H5.611c-1.135 0-2.056 1-2.056 2.234z M7.666 49.12c0 7.003 5.225 12.68 11.67 12.68h1.327c6.445 0 11.67-5.677 11.67-12.68V31.873c0-1.233-.92-2.233-2.056-2.233H9.722c-1.135 0-2.056 1-2.056 2.233zM33.792 3.733c1.465 0 2.652 1.29 2.652 2.882v12.103c0 1.592-1.187 2.882-2.652 2.882H6.208c-1.465 0-2.653-1.29-2.653-2.882V6.615c0-1.591 1.188-2.882 2.653-2.882z M24.11 50.186c0 2.467-1.84 4.467-4.11 4.467s-4.111-2-4.111-4.467 1.84-4.466 4.11-4.466 4.112 2 4.112 4.466",viewW:40,viewH:70},toilet_built_in:{d:"M3.555 34.56c0 9.263 7.125 16.774 15.914 16.774h1.061c8.79 0 15.914-7.51 15.914-16.775V5.833c0-1.196-.92-2.166-2.056-2.166H5.611c-1.135 0-2.056.97-2.056 2.166z M7.666 34.7c0 6.793 5.225 12.3 11.67 12.3h1.327c6.445 0 11.67-5.507 11.67-12.3V14.5c0-1.197-.92-2.167-2.056-2.167H9.722c-1.135 0-2.056.97-2.056 2.167z M24.11 35.733c0 2.394-1.84 4.334-4.11 4.334s-4.111-1.94-4.111-4.334 1.84-4.333 4.11-4.333 4.112 1.94 4.112 4.333",viewW:40,viewH:55},bathtub:{d:"M3.885 6c0-1.243 1.068-2.25 2.386-2.25h157.458c1.318 0 2.386 1.007 2.386 2.25v63c0 1.243-1.068 2.25-2.386 2.25H6.27c-1.318 0-2.386-1.007-2.386-2.25z M13.428 37.5c0-13.669 11.75-24.75 26.243-24.75h90.658c14.493 0 26.243 11.081 26.243 24.75s-11.75 24.75-26.243 24.75H39.67c-14.493 0-26.243-11.081-26.243-24.75 M31.56 37.5c0 2.237-1.923 4.05-4.295 4.05s-4.294-1.813-4.294-4.05 1.923-4.05 4.294-4.05c2.372 0 4.295 1.813 4.295 4.05",viewW:170,viewH:75},bathtub_corner:{d:"M3.862 6.224a2.36 2.36 0 0 1 2.362-2.362H133.97c1.197 0 2.168.97 2.168 2.168 0 71.857-58.251 130.108-130.108 130.108a2.17 2.17 0 0 1-2.168-2.168z M13.31 32.207c0-10.437 8.46-18.897 18.897-18.897h87.628a2.13 2.13 0 0 1 2.13 2.13c0 58.833-47.692 106.526-106.524 106.526a2.13 2.13 0 0 1-2.13-2.131z M32.207 27.483a4.724 4.724 0 1 1-9.449 0 4.724 4.724 0 0 1 9.449 0",viewW:140,viewH:140},bidet:{d:"M22.466 3.692v10.085c0 1.21-.92 2.192-2.055 2.192h-.822c-1.136 0-2.056-.981-2.056-2.192V3.692m4.933 8.77h2.878c1.135 0 2.056-.982 2.056-2.193v-.877c0-1.21-.92-2.192-2.056-2.192h-2.878m-4.933 5.262h-2.878c-1.135 0-2.055-.982-2.055-2.193v-.877c0-1.21.92-2.192 2.055-2.192h2.878M5.611 3.692h28.777c1.136 0 2.056.981 2.056 2.192v33.45c0 9.374-7.125 16.973-15.914 16.973h-1.06c-8.79 0-15.915-7.599-15.915-16.972V5.885c0-1.212.92-2.193 2.056-2.193m4.11 15.785h20.556c1.136 0 2.056.981 2.056 2.192v17.807c0 6.874-5.225 12.447-11.67 12.447h-1.327c-6.445 0-11.67-5.573-11.67-12.447V21.67c0-1.21.92-2.192 2.056-2.192m13.567 7.892c0 1.937-1.472 3.508-3.288 3.508-1.817 0-3.29-1.57-3.29-3.508s1.473-3.507 3.29-3.507 3.288 1.57 3.288 3.507",viewW:40,viewH:60},bidet_built_in:{d:"M17.318 12.182h-8.06c-.88 0-1.592.74-1.592 1.654v16.126c0 6.698 5.225 12.129 11.67 12.129h1.327c6.445 0 11.67-5.43 11.67-12.13V13.837c0-.914-.713-1.654-1.591-1.654H22.68m-.215-8.545v9.827c0 1.18-.92 2.136-2.055 2.136h-.822c-1.136 0-2.056-.956-2.056-2.136V3.637m10.689 8.545V3.637m-16.445 0v8.545M5.611 3.637h28.777c1.136 0 2.056.956 2.056 2.136v24.051c0 9.135-7.125 16.54-15.914 16.54h-1.06c-8.79 0-15.915-7.405-15.915-16.54V5.773c0-1.18.92-2.136 2.056-2.136M23.289 23.29c0 1.888-1.473 3.418-3.29 3.418s-3.288-1.53-3.288-3.418 1.472-3.418 3.289-3.418c1.816 0 3.288 1.53 3.288 3.418",viewW:40,viewH:50},kitchen_sink:{d:"M38.188 8.7h10.598c1.211 0 2.193.956 2.193 2.136v28.2c0 1.18-.982 2.136-2.193 2.136H11.08c-1.21 0-2.192-.956-2.192-2.136v-28.2c0-1.18.981-2.136 2.192-2.136h10.599m10.885-5.128V15.11c0 1.18-.981 2.136-2.192 2.136h-.877c-1.21 0-2.192-.957-2.192-2.136V3.572m5.261 7.691h3.07c1.21 0 2.192-.956 2.192-2.136v-.855c0-1.18-.982-2.136-2.192-2.136h-3.07m-5.261 5.127h-3.07c-1.21 0-2.192-.956-2.192-2.136v-.855c0-1.18.982-2.136 2.193-2.136h3.069M5.817 46.299h48.231c1.21 0 2.192-.956 2.192-2.136V5.709c0-1.18-.981-2.137-2.192-2.137H5.818c-1.211 0-2.193.957-2.193 2.137v38.454c0 1.18.982 2.136 2.192 2.136M33.44 25.79c0 1.888-1.57 3.418-3.507 3.418s-3.508-1.53-3.508-3.418c0-1.887 1.57-3.418 3.508-3.418s3.507 1.53 3.507 3.418",viewW:60,viewH:50},kitchen_sink_double:{d:"M53.173 12.182c-.468 0-.847.354-.847.79s.38.79.847.79zm21.979 1.58c.467 0 .846-.353.846-.79 0-.436-.379-.79-.846-.79zM6.01 3.572v.79h77.842v-1.58H6.01zM86.14 5.71h-.847v38.454h1.694V5.709zM83.85 46.3v-.79H6.01v1.58h77.842zM3.72 44.163h.847V5.709H2.873v38.454zm2.29 2.136v-.79c-.797 0-1.443-.603-1.443-1.346H2.873c0 1.616 1.404 2.926 3.137 2.926zm80.131-2.136h-.847c0 .743-.646 1.346-1.442 1.346v1.58c1.732 0 3.136-1.31 3.136-2.926zm-2.29-40.59v.79c.797 0 1.443.602 1.443 1.346h1.694c0-1.617-1.404-2.927-3.136-2.927zm-77.841 0v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.744.646-1.347 1.443-1.347zm5.494 37.599v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2h-1.694v28.2zm-32.97-28.2h-.846v28.2h1.694v-28.2zM39.895 8.7v-.79h-5.669v1.58h5.669zm-22.721 0v-.79h-5.669v1.58h5.669zm-7.958 2.136h.847c0-.744.645-1.346 1.442-1.346V7.91c-1.732 0-3.136 1.31-3.136 2.926zm32.968 0h.847c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.442.603 1.442 1.347zm-2.29 30.336v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.645 1.346-1.442 1.346zm-28.389 0v-.79c-.797 0-1.442-.603-1.442-1.346H8.368c0 1.616 1.404 2.926 3.136 2.926zm13.737-23.927v.79h.916v-1.58h-.916zm3.205-2.136h.847V3.572H27.6V15.11zM22.952 3.572h-.847V15.11h1.693V3.572zm3.205 13.673v.79c1.732 0 3.136-1.31 3.136-2.926H27.6c0 .743-.646 1.346-1.443 1.346zm-.916 0v-.79c-.797 0-1.443-.603-1.443-1.346h-1.693c0 1.616 1.404 2.926 3.136 2.926zm3.205-5.982v.79h3.206v-1.58h-3.206zm5.495-2.136h.847v-.855h-1.694v.855zm-2.29-2.991v-.79h-3.205v1.58h3.206zm2.29 2.136h.847c0-1.616-1.404-2.926-3.136-2.926v1.58c.796 0 1.442.603 1.442 1.346zm-2.29 2.991v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.646 1.346-1.442 1.346zm-11.905 0v.79h3.206v-1.58h-3.206zm3.206-5.127v-.79h-3.206v1.58h3.206zm-5.495 2.136h-.847v.855h1.694v-.855zm2.29-2.136v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.743.646-1.346 1.442-1.346zm0 5.127v-.79c-.797 0-1.443-.603-1.443-1.346H16.61c0 1.616 1.404 2.926 3.136 2.926zm9.615 14.527h-.847c0 1.452-1.26 2.628-2.816 2.628v1.58c2.49 0 4.51-1.884 4.51-4.208zM25.7 29.208v-.79c-1.555 0-2.816-1.176-2.816-2.628H21.19c0 2.324 2.02 4.209 4.51 4.209zm-3.663-3.418h.847c0-1.451 1.26-2.628 2.816-2.628v-1.58c-2.49 0-4.51 1.884-4.51 4.208zm3.663-3.418v.79c1.555 0 2.816 1.177 2.816 2.628h1.694c0-2.324-2.02-4.208-4.51-4.208zm24.268 18.8v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2H79.8v28.2zM78.356 8.7v-.79h-28.39v1.58h28.39zm-30.68 2.136h-.846v28.2h1.694v-28.2zm2.29-2.136v-.79c-1.732 0-3.136 1.31-3.136 2.926h1.694c0-.744.646-1.346 1.442-1.346zm30.68 2.136h.846c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.443.603 1.443 1.347zm-2.29 30.336v.79c1.732 0 3.136-1.31 3.136-2.926H79.8c0 .743-.646 1.346-1.443 1.346zm-28.39 0v-.79c-.796 0-1.442-.603-1.442-1.346H46.83c0 1.616 1.404 2.926 3.136 2.926zm3.206-28.2v.79h21.979v-1.58h-21.98z",viewW:90,viewH:50}};export{c as FURNITURE_ART_FINGERPRINT,a as GENERATED_FURNITURE_ART}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";const c="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33",v={coffee_table:{d:"M3.84 5.884c0-1.21 1.048-2.192 2.34-2.192h107.64c1.293 0 2.34.981 2.34 2.192v48.23c0 1.212-1.047 2.193-2.34 2.193H6.18c-1.292 0-2.34-.981-2.34-2.192z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},coffee_table_round:{d:"M3.765 40a36.235 36.235 0 1 0 72.47 0 36.235 36.235 0 1 0-72.47 0 m56.26 26.96-3.843-3.843a.906.906 0 0 1 0-1.28l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.843 3.844a.906.906 0 0 1 0 1.28l-3.843 3.844a.906.906 0 0 1-1.281 0m-34.423-34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.844a.906.906 0 0 1 1.281 0l3.844 3.844a.906.906 0 0 1 0 1.28l-3.844 3.844a.906.906 0 0 1-1.28 0m-.001 34.66-3.843-3.843a.906.906 0 0 1 0-1.281l3.843-3.843a.906.906 0 0 1 1.281 0l3.844 3.843a.906.906 0 0 1 0 1.281l-3.844 3.843a.906.906 0 0 1-1.28 0",viewW:80,viewH:80},coffee_table_oval:{d:"M3.84 30c0-14.53 12.572-26.308 28.08-26.308h56.16c15.509 0 28.08 11.778 28.08 26.308s-12.571 26.307-28.08 26.307H31.92C16.412 56.307 3.84 44.53 3.84 30 M80.592 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877M31.92 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876m0 35.077v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.876h-5.616a.936.877 0 0 1-.936-.876",viewW:120,viewH:60},coffee_table_rounded:{d:"M3.84 12.461c0-4.843 4.19-8.77 9.36-8.77h93.6c5.17 0 9.36 3.927 9.36 8.77v35.077c0 4.843-4.19 8.77-9.36 8.77H13.2c-5.17 0-9.36-3.927-9.36-8.77z M103.056 15.093V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m-93.6-35.077V9.83a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877m0 35.078v-5.262a.936.877 0 0 1 .936-.877h5.616a.936.877 0 0 1 .936.877v5.262a.936.877 0 0 1-.936.877h-5.616a.936.877 0 0 1-.936-.877",viewW:120,viewH:60},table_dining:{d:"M3.879 6.08c0-1.265 1.065-2.29 2.378-2.29h147.484c1.314 0 2.38 1.025 2.38 2.29v77.84c0 1.265-1.066 2.29-2.38 2.29H6.257c-1.313 0-2.378-1.025-2.378-2.29z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},table_round:{d:"M3.826 55a51.174 51.174 0 1 0 102.349 0A51.174 51.174 0 1 0 3.826 55 m81.005 32.303-3.947-3.947a.93.93 0 0 1 0-1.316l3.947-3.948a.93.93 0 0 1 1.316 0l3.948 3.948a.93.93 0 0 1 0 1.316l-3.948 3.947a.93.93 0 0 1-1.316 0m0 54.897-3.947-3.948a.93.93 0 0 1 0-1.316l3.947-3.947a.93.93 0 0 1 1.316 0l3.948 3.947a.93.93 0 0 1 0 1.316L82.32 87.2a.93.93 0 0 1-1.316 0M27.04 32.304l-3.947-3.948a.93.93 0 0 1 0-1.315l3.948-3.948a.93.93 0 0 1 1.315 0l3.948 3.948a.93.93 0 0 1 0 1.315l-3.948 3.948a.93.93 0 0 1-1.315 0m-.001 54.604-3.947-3.948a.93.93 0 0 1 0-1.316l3.948-3.947a.93.93 0 0 1 1.315 0l3.948 3.947a.93.93 0 0 1 0 1.316l-3.948 3.948a.93.93 0 0 1-1.315 0",viewW:110,viewH:110},table_dining_oval:{d:"M3.892 50c0-25.51 21.418-46.19 47.838-46.19h76.54c26.42 0 47.839 20.68 47.839 46.19S154.69 96.19 128.27 96.19H51.73C25.31 96.19 3.892 75.51 3.892 50 M122.53 19.514V13.97a.957.924 0 0 1 .956-.924h5.74a.957.924 0 0 1 .958.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m.001 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.957-.924M49.816 19.515v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .958.924v5.542a.957.924 0 0 1-.957.924h-5.74a.957.924 0 0 1-.958-.924m0 66.516v-5.543a.957.924 0 0 1 .957-.924h5.74a.957.924 0 0 1 .957.924v5.543a.957.924 0 0 1-.957.923h-5.74a.957.924 0 0 1-.957-.924",viewW:180,viewH:100},table_dining_rounded:{d:"M3.879 17.527c0-7.587 6.39-13.737 14.272-13.737h123.696c7.883 0 14.273 6.15 14.273 13.737v54.947c0 7.587-6.39 13.737-14.273 13.737H18.151c-7.882 0-14.272-6.15-14.272-13.737z M138.994 19.358v-5.495a.952.916 0 0 1 .951-.915h5.71a.952.916 0 0 1 .95.915v5.495a.952.916 0 0 1-.95.916h-5.71a.952.916 0 0 1-.951-.916m-.001 56.778v-5.495a.952.916 0 0 1 .952-.915h5.709a.952.916 0 0 1 .951.915v5.495a.952.916 0 0 1-.951.916h-5.71a.952.916 0 0 1-.95-.916m-125.6-56.778v-5.495a.952.916 0 0 1 .951-.916h5.71a.952.916 0 0 1 .95.916v5.495a.952.916 0 0 1-.95.915h-5.71a.952.916 0 0 1-.951-.915m-.001 56.779v-5.495a.952.916 0 0 1 .952-.916h5.709a.952.916 0 0 1 .951.916v5.495a.952.916 0 0 1-.951.915h-5.71a.952.916 0 0 1-.95-.915",viewW:160,viewH:90},desk:{d:"M3.862 5.967c0-1.234 1.057-2.234 2.362-2.234h127.552c1.305 0 2.362 1 2.362 2.234v58.066c0 1.234-1.057 2.233-2.362 2.233H6.224c-1.305 0-2.362-1-2.362-2.233z M9.531 15.346v-5.36a.945.893 0 0 1 .945-.893h5.67a.945.893 0 0 1 .944.893v5.36a.945.893 0 0 1-.945.894h-5.669a.945.893 0 0 1-.945-.894m113.379.001v-5.36a.945.893 0 0 1 .945-.894h5.67a.945.893 0 0 1 .944.894v5.36a.945.893 0 0 1-.945.893h-5.669a.945.893 0 0 1-.945-.893M9.53 60.013v-5.36a.945.893 0 0 1 .946-.893h5.669a.945.893 0 0 1 .945.893v5.36a.945.893 0 0 1-.945.894h-5.67a.945.893 0 0 1-.944-.894m113.38.001v-5.36a.945.893 0 0 1 .945-.894h5.669a.945.893 0 0 1 .945.894v5.36a.945.893 0 0 1-.945.893h-5.67a.945.893 0 0 1-.944-.893m-97.318-2.681h88.814",viewW:140,viewH:70},desk_corner:{d:"M156.12 66.202a2.38 2.38 0 0 1-2.379 2.38H94.272c-13.138 0-23.788 10.65-23.788 23.787v61.372a2.38 2.38 0 0 1-2.379 2.38H6.257a2.38 2.38 0 0 1-2.378-2.38V6.257A2.38 2.38 0 0 1 6.257 3.88h147.484a2.38 2.38 0 0 1 2.38 2.378z M9.588 16.249v-5.71a.95.95 0 0 1 .951-.95h5.71a.95.95 0 0 1 .95.95v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m133.212.001v-5.71a.95.95 0 0 1 .951-.951h5.71a.95.95 0 0 1 .95.951v5.71a.95.95 0 0 1-.95.951h-5.71a.95.95 0 0 1-.951-.951m0 45.672v-5.71a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.95-.951M9.587 149.46v-5.708a.95.95 0 0 1 .952-.952h5.709a.95.95 0 0 1 .951.952v5.709a.95.95 0 0 1-.951.951h-5.71a.95.95 0 0 1-.951-.951m47.576 0v-5.709a.95.95 0 0 1 .952-.951h5.709a.95.95 0 0 1 .951.951v5.71a.95.95 0 0 1-.951.95h-5.71a.95.95 0 0 1-.951-.95m51.382-90.396H95.569a34.6 34.6 0 0 0-34.6 34.6v12.976",viewW:160,viewH:160},chair:{d:"M39.452 12.433H10.548a4.398 4.398 0 1 1 0-8.796h28.904a4.398 4.398 0 0 1 0 8.796m-28.904 0H8.035a4.4 4.4 0 0 0-4.398 4.399V40.08a6.283 6.283 0 0 0 6.283 6.284h30.16a6.283 6.283 0 0 0 6.284-6.284V16.832c0-2.43-1.97-4.399-4.399-4.399h-2.513",viewW:50,viewH:50},chair_bar:{d:"M38.579 17.168c1.326 2.526 1.947 6.015 1.947 9.071 0 10.018-8.07 18.139-18.025 18.139S4.475 36.257 4.475 26.239c0-3.056.586-6.552 1.912-9.078m32.192.007a3.59 3.59 0 0 1-3.333-.976m3.333.976a3.6 3.6 0 0 0 1.765-.976m-33.827.996-.13-.027a3.6 3.6 0 0 1-1.731-.969m30.59 0a18 18 0 0 0-5.848-3.932 17.93 17.93 0 0 0-13.796 0 18 18 0 0 0-5.848 3.932 3.59 3.59 0 0 1-3.237.996m28.729-.996a3.59 3.59 0 0 0 5.098 0m-33.827.996a3.6 3.6 0 0 1-1.861-.996 3.644 3.644 0 0 1 0-5.13 25.2 25.2 0 0 1 8.187-5.505A25.1 25.1 0 0 1 22.5 3.623a25.1 25.1 0 0 1 9.657 1.934 25.2 25.2 0 0 1 8.187 5.505 3.644 3.644 0 0 1 0 5.13",viewW:45,viewH:48},armchair:{d:"M75.702 13.011q.012-.225.012-.453c0-4.843-3.917-8.768-8.748-8.768H23.034c-4.83 0-8.747 3.925-8.747 8.768q0 .228.011.453M77.132 72.09q.59.091 1.206.092c4.348 0 7.873-3.533 7.873-7.892V20.45c0-4.359-3.525-7.892-7.873-7.892-.924 0-1.812.16-2.636.453a7.89 7.89 0 0 0-5.237 7.438v.148m0 0a8.7 8.7 0 0 1-3.499.73H23.034a8.7 8.7 0 0 1-3.499-.73m50.93 0V64.29a7.89 7.89 0 0 0 6.667 7.8M14.298 13.01a7.89 7.89 0 0 1 5.237 7.438v.148m0 0V64.29a7.89 7.89 0 0 1-6.666 7.8q-.59.091-1.206.092c-4.348 0-7.873-3.533-7.873-7.892V20.45c0-4.359 3.525-7.892 7.873-7.892.924 0 1.811.16 2.635.453M77.132 72.09c-1.585 8.05-8.667 14.12-17.164 14.12H30.032c-8.496 0-15.578-6.07-17.163-14.12",viewW:90,viewH:90},armchair_office:{d:"M56.968 18.845q0-.368-.05-.72M49.051 13.8H15.95a5.04 5.04 0 0 1-5.038-5.043 5.04 5.04 0 0 1 5.038-5.043h33.103a5.04 5.04 0 0 1 5.038 5.043 5.04 5.04 0 0 1-5.038 5.043m-33.103 0h-2.88a5.04 5.04 0 0 0-4.986 4.323M49.052 13.8h2.879a5.04 5.04 0 0 1 4.986 4.324m.051 24.826a4.32 4.32 0 0 0 4.318-4.323v-16.18a4.32 4.32 0 0 0-4.369-4.322m.051 24.826a4.32 4.32 0 0 1-4.318-4.323V22.447a4.32 4.32 0 0 1 4.267-4.322m-11.84 37.24h4.695c.736 0 1.446-.111 2.115-.317a7.21 7.21 0 0 0 5.081-6.889v-5.208M8.084 18.124h-.051a4.32 4.32 0 0 0-4.318 4.323v16.18a4.32 4.32 0 0 0 4.318 4.324 4.32 4.32 0 0 0 4.317-4.323V22.447a4.32 4.32 0 0 0-4.266-4.323m11.935 37.24h-4.79a7.2 7.2 0 0 1-2.04-.294 7.21 7.21 0 0 1-5.156-6.91v-5.21m37.045 12.414 5.177 5.183c.969.97 2.534.987 3.524.038a2.526 2.526 0 0 0 .038-3.605l-1.93-1.932m-6.81.316H20.02m-6.83-.294-1.909 1.91c-.998 1-.98 2.627.038 3.605.99.949 2.555.932 3.524-.038l5.177-5.183",viewW:65,viewH:65},sofa:{d:"M90 19.365v57.111m0-57.11V7.683m0 11.681c0 2.151-1.836 3.894-4.1 3.894H30.544a10.7 10.7 0 0 1-4.136-.825M90 19.365c0 2.151 1.836 3.894 4.1 3.894h55.356c1.472 0 2.871-.294 4.137-.825M90 76.476c0 5.376-4.59 9.735-10.25 9.735H30.543c-5.266 0-9.605-3.772-10.185-8.625M90 76.476c0 5.376 4.59 9.735 10.25 9.735h49.206c5.266 0 9.605-3.772 10.185-8.625M90 7.684c0-2.15-1.837-3.894-4.101-3.894H30.544c-5.661 0-10.25 4.358-10.25 9.735q0 .416.036.825M90 7.684c0-2.15 1.836-3.894 4.1-3.894h55.356c5.661 0 10.25 4.358 10.25 9.735q0 .416-.036.825m0 0a10.7 10.7 0 0 1 4.137-.825h2.05c5.662 0 10.252 4.358 10.252 9.734v45.43c0 5.376-4.59 9.734-10.251 9.734h-2.05c-1.484 0-2.894-.3-4.167-.837m0 0c-3.585-1.517-6.084-4.93-6.084-8.898V23.26q0-.417.036-.825c.32-3.622 2.728-6.68 6.077-8.084m-139.34 0c3.35 1.404 5.758 4.462 6.078 8.084q.036.408.036.825v45.43c0 3.967-2.5 7.38-6.085 8.897a10.7 10.7 0 0 1-4.166.837h-2.05c-5.662 0-10.251-4.358-10.251-9.735V23.26c0-5.376 4.59-9.734 10.25-9.734h2.05c1.473 0 2.872.294 4.138.825",viewW:180,viewH:90},sofa_three_seat:{d:"M86.553 18.593V76.96m0-58.366V7.491m0 11.102c0 2.044-1.762 3.701-3.935 3.701H29.496c-1.413 0-2.756-.28-3.97-.784m61.027-2.917c0 2.044 1.762 3.701 3.935 3.701h59.024c2.174 0 3.935-1.657 3.935-3.7M86.553 76.958c0 5.11-4.404 9.252-9.837 9.252h-47.22c-5.054 0-9.218-3.585-9.775-8.198m66.832-1.054c0 5.11 4.404 9.252 9.837 9.252h47.22c5.433 0 9.837-4.142 9.837-9.252m0-58.366V76.96m0-58.366V7.491m0 11.102c0 2.044 1.762 3.701 3.936 3.701h53.122c1.413 0 2.756-.28 3.97-.784m-61.028 55.449c0 5.11 4.405 9.252 9.838 9.252h47.22c5.054 0 9.218-3.585 9.775-8.198M86.553 7.491c0-2.044-1.762-3.701-3.935-3.701H29.496c-5.433 0-9.838 4.142-9.838 9.252q0 .396.035.784m66.86-6.335c0-2.044 1.762-3.701 3.935-3.701h59.024c2.174 0 3.935 1.657 3.935 3.7m0 0c0-2.043 1.762-3.7 3.936-3.7h53.122c5.433 0 9.838 4.142 9.838 9.252 0 .258.022.517 0 .77m-.063 64.201c1.22.512 2.574.796 3.998.796h1.967c5.433 0 9.837-4.142 9.837-9.252V22.294c0-5.11-4.404-9.252-9.837-9.252h-1.967c-5.153 0-9.38 3.725-9.803 8.468q-.036.387-.035.784v47.263c0 3.771 2.399 7.015 5.84 8.456M19.693 13.826a10.3 10.3 0 0 0-3.97-.784h-1.967c-5.433 0-9.838 4.142-9.838 9.252v47.263c0 5.11 4.405 9.252 9.838 9.252h1.967c1.424 0 2.777-.284 3.998-.796 3.441-1.441 5.84-4.685 5.84-8.456V22.294a9 9 0 0 0-.035-.784c-.307-3.443-2.618-6.349-5.833-7.684",viewW:240,viewH:90},sofa_corner_right:{d:"M93.673 20.687V83.69m0-63.004v-12.6m0 12.6c0 2.32-1.913 4.2-4.273 4.2H31.704a10.8 10.8 0 0 1-4.311-.89m66.28-3.31c0 2.32 1.914 4.2 4.274 4.2h64.106c2.36 0 4.274-1.88 4.274-4.2M93.673 83.692c0 5.8-4.783 10.501-10.684 10.501H31.704c-5.489 0-10.011-4.068-10.616-9.304m72.585-1.197c0 5.8 4.784 10.501 10.684 10.501h51.286c5.9 0 10.684-4.701 10.684-10.5m0-63.005V83.69m0-63.004v-12.6m0 12.6c0 2.32 1.914 4.2 4.273 4.2h57.696c1.534 0 2.993-.317 4.312-.89m-66.28 59.695v71.923c0 5.799 4.782 10.5 10.684 10.5h51.284c5.49 0 10.012-4.068 10.616-9.304V84.888M93.673 8.086c0-2.32-1.913-4.2-4.273-4.2H31.704c-5.9 0-10.684 4.7-10.684 10.5q0 .45.038.89m72.615-7.19c0-2.32 1.914-4.2 4.274-4.2h64.106c2.36 0 4.274 1.88 4.274 4.2m0 0c0-2.32 1.914-4.2 4.273-4.2h57.696c5.9 0 10.685 4.7 10.685 10.5 0 .293.024.587 0 .874m-.07 69.628c1.327.58 2.797.904 4.344.904h2.136c5.901 0 10.684-4.702 10.684-10.501V24.887c0-5.8-4.783-10.5-10.684-10.5h-2.136c-5.596 0-10.187 4.227-10.647 9.61q-.038.44-.038.89V75.29c0 4.28 2.605 7.961 6.342 9.597M21.059 15.276a10.8 10.8 0 0 0-4.312-.89H14.61c-5.9 0-10.684 4.701-10.684 10.5v50.405c0 5.8 4.783 10.5 10.684 10.5h2.137c1.546 0 3.016-.322 4.342-.903 3.737-1.636 6.342-5.317 6.342-9.597V24.887q0-.45-.037-.89c-.334-3.907-2.844-7.206-6.335-8.72",viewW:260,viewH:170},bed_single:{d:"M3.79 14.024c0 5.59 4.318 10.122 9.645 10.122h63.13c5.328 0 9.646-4.532 9.646-10.122m-22.797 46.93V46.23c0-5.082-3.926-9.201-8.769-9.201h-19.29c-4.842 0-8.768 4.12-8.768 9.201v14.723m-22.797 0h82.42m0 22.085H3.79m8.768 113.06h64.885c4.842 0 8.768-4.12 8.768-9.202V13.104c0-5.082-3.926-9.202-8.768-9.202H12.558c-4.843 0-8.768 4.12-8.768 9.202v173.792c0 5.082 3.925 9.202 8.768 9.202",viewW:90,viewH:200},bed_double:{d:"M3.879 14.073c0 5.618 4.516 10.172 10.088 10.172h132.065c5.571 0 10.088-4.554 10.088-10.172m-81.165 47.16V46.438c0-5.107-4.106-9.247-9.171-9.247H45.607c-5.065 0-9.17 4.14-9.17 9.247v14.795m89.877 0V46.438c0-5.107-4.107-9.247-9.172-9.247H96.966c-5.065 0-9.171 4.14-9.171 9.247v14.795m-83.916 0H156.12m0 22.192H3.88m9.17 112.673h133.9c5.065 0 9.171-4.14 9.171-9.247V13.15c0-5.107-4.106-9.247-9.171-9.247H13.05c-5.064 0-9.17 4.14-9.17 9.247v173.7c0 5.107 4.106 9.247 9.17 9.247",viewW:160,viewH:200},nightstand:{d:"M5.773 3.555h38.454a2.136 2.056 0 0 1 2.137 2.056v28.777a2.136 2.056 0 0 1-2.137 2.056H5.773a2.136 2.056 0 0 1-2.136-2.056V5.611a2.136 2.056 0 0 1 2.136-2.056",viewW:50,viewH:40},cabinet_tv:{d:"M56.772 17.88h5.315m0 0h5.315m-5.315 0v9.214m9.832-9.214 5.315 9.45 5.314-9.45M6.224 41.4h127.552c1.305 0 2.362-.94 2.362-2.1V5.7c0-1.16-1.057-2.1-2.362-2.1H6.224c-1.305 0-2.362.94-2.362 2.1v33.6c0 1.16 1.057 2.1 2.362 2.1",viewW:140,viewH:45},cabinet_shoe:{d:"m39.722 16.231 1.505-1.596m1.134 3.15 1.53-1.738M6.03 31.5h67.94c1.251 0 2.265-.895 2.265-2v-24c0-1.105-1.014-2-2.264-2H6.03c-1.251 0-2.265.895-2.265 2v24c0 1.105 1.014 2 2.265 2m41.966-14.305L46.92 17.1a3.4 3.4 0 0 1-1.813-.706l-4.583-3.62c-1.264-1-3.277-.326-3.475 1.161-.185 1.39-1.983 2.1-3.28 1.299l-1.532-.947c-.968-.513-2.2.103-2.2 1.1v3.463c0 1.559 1.43 2.823 3.196 2.823h14.51c1.404 0 2.542-1.005 2.542-2.245 0-1.153-.99-2.118-2.289-2.233",viewW:80,viewH:35},cabinet_sink:{d:"M3.765 5.773c0-1.18 1.014-2.136 2.265-2.136h67.94c1.251 0 2.265.956 2.265 2.136v38.454c0 1.18-1.014 2.137-2.264 2.137H6.03c-1.251 0-2.265-.957-2.265-2.137z M36.088 32.135c2.525 1.88 6.205 1.88 8.73 0s3.167-5.101 1.52-7.637l-5.879-8.043-5.893 8.043c-1.644 2.536-1.003 5.755 1.522 7.637",viewW:80,viewH:50},bookshelf:{d:"M57.12 20.488H45.473c-.514 0-1.008.124-1.372.345s-.568.52-.568.832m4.076-8.236h5.434M6.119 3.5h87.762c1.276 0 2.31.895 2.31 2v24c0 1.105-1.034 2-2.31 2H6.12c-1.275 0-2.31-.895-2.31-2v-24c0-1.105 1.035-2 2.31-2m51 6.4v14.118H45.474a2.04 2.04 0 0 1-1.372-.517 1.7 1.7 0 0 1-.568-1.248V11.665c0-.468.204-.917.568-1.248a2.04 2.04 0 0 1 1.372-.517z",viewW:100,viewH:35},wall_unit:{d:"M6.336 41.4h227.328a2.418 2.1 0 0 0 2.418-2.1V5.7a2.418 2.1 0 0 0-2.418-2.1H6.336a2.418 2.1 0 0 0-2.418 2.1v33.6a2.418 2.1 0 0 0 2.418 2.1m43.744-5.88V9.48m46.432 26.04V9.48m46.433 26.04V9.48m46.433 26.04V9.48",viewW:240,viewH:45},wardrobe:{d:"M93.87 20.25a3.3 3.3 0 0 0-1.072-2.407 3.8 3.8 0 0 0-2.586-.997c-.97 0-1.9.358-2.587.997a3.3 3.3 0 0 0-1.071 2.407c0 2.838 1.225 5.107 3.658 6.81h-.015m0 0 14.58 7.537c.57.295 1.046.726 1.377 1.25.331.523.505 1.12.505 1.727v1.401a3.3 3.3 0 0 1-1.071 2.407 3.8 3.8 0 0 1-2.587.998H77.393a3.8 3.8 0 0 1-2.586-.998 3.3 3.3 0 0 1-1.072-2.407v-1.4c0-.608.174-1.205.505-1.728a3.55 3.55 0 0 1 1.377-1.25zM6.284 3.691h167.433c1.32 0 2.392.981 2.392 2.192v48.23c0 1.212-1.071 2.193-2.392 2.193H6.284c-1.321 0-2.392-.981-2.392-2.192V5.885c0-1.212 1.07-2.193 2.392-2.193",viewW:180,viewH:60},kitchen_floor:{d:"M3.692 5.884c0-1.21.981-2.192 2.192-2.192h48.23c1.212 0 2.193.981 2.193 2.192v48.23a2.19 2.19 0 0 1-2.192 2.193H5.885a2.19 2.19 0 0 1-2.193-2.192z",viewW:60,viewH:60},kitchen_floor_corner:{d:"M45.944 41.767a2.29 2.29 0 0 0 2.29 2.29H83.92a2.29 2.29 0 0 1 2.29 2.29V83.92a2.29 2.29 0 0 1-2.29 2.29H6.08a2.29 2.29 0 0 1-2.29-2.29V6.08a2.29 2.29 0 0 1 2.29-2.29h37.576a2.29 2.29 0 0 1 2.29 2.29z",viewW:90,viewH:90},kitchen_wall:{d:"m4.444 31.033 50.75-27.007m-50.752-.06 50.75 27.008M5.884 31.5h48.23c1.212 0 2.193-.895 2.193-2v-24c0-1.105-.981-2-2.192-2H5.885c-1.212 0-2.193.895-2.193 2v24c0 1.105.981 2 2.192 2",viewW:60,viewH:35},kitchen_wall_corner:{d:"M3.772 29.59 29.88 4.383M4.57 55.43 55.43 30M4.175 4.383l26.701 23.863m-27.184.877L55.43 55.43M28.41 3.692H5.884c-1.21 0-2.192.981-2.192 2.192v48.23c0 1.212.981 2.193 2.192 2.193h48.23a2.19 2.19 0 0 0 2.193-2.192V31.589c0-1.21-.981-2.192-2.192-2.192h-21.32a2.19 2.19 0 0 1-2.193-2.192V5.885a2.19 2.19 0 0 0-2.192-2.193",viewW:60,viewH:60},shelf_floor:{d:"M6.12 31.5h87.76a2.31 2 0 0 0 2.31-2v-24a2.31 2 0 0 0-2.31-2H6.12a2.31 2 0 0 0-2.31 2v24a2.31 2 0 0 0 2.31 2 M9.089 25.933c-.494.112-.776.546-.63.97s.664.675 1.157.564l-.263-.767zM90.912 9.067c.493-.112.775-.546.63-.97s-.664-.675-1.158-.564l.264.767zM11.875 26.956c.493-.112.775-.546.63-.97s-.664-.676-1.158-.564l.264.767zm3.988-2.556c-.493.112-.775.546-.63.969s.664.676 1.158.564l-.264-.766zm5.045.511c.493-.112.775-.545.63-.969s-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.111-.775.545-.63.968.146.424.664.677 1.158.565l-.264-.767zm5.044.51c.494-.111.776-.545.63-.968-.145-.424-.664-.676-1.157-.565l.263.767zm3.99-2.555c-.495.112-.777.546-.63.97.145.423.663.675 1.157.563l-.264-.766zm5.043.511c.494-.112.776-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.989-2.555c-.494.111-.776.545-.63.969s.664.676 1.157.564l-.263-.767zm5.044.51c.494-.11.776-.545.63-.968-.146-.424-.664-.676-1.158-.565l.264.767zm3.989-2.555c-.494.112-.776.546-.63.97.145.423.664.675 1.157.564l-.264-.767zm5.044.511c.493-.111.775-.545.63-.969s-.664-.676-1.158-.564l.264.767zm3.988-2.555c-.493.112-.775.545-.63.969s.664.676 1.158.564l-.264-.767zm5.045.51c.493-.11.775-.545.63-.968-.146-.424-.664-.676-1.158-.564l.264.766zm3.988-2.555c-.493.112-.775.546-.63.97s.664.675 1.158.564l-.264-.767zm5.044.511c.494-.111.776-.545.63-.968-.145-.424-.664-.677-1.157-.565l.264.767zm3.99-2.555c-.494.112-.777.545-.63.969.145.423.663.676 1.157.564l-.264-.766zm5.043.511c.494-.112.776-.546.63-.969s-.664-.676-1.157-.564l.263.766zm3.989-2.556c-.494.112-.776.546-.63.97s.664.676 1.158.564l-.264-.767zM9.353 26.7l.263.767 2.259-.511-.264-.767-.264-.767-2.258.511zm6.774-1.533.264.766 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.045.264.767 4.516-1.022-.264-.767-.263-.767-4.517 1.023zm9.033-2.044.264.766 4.516-1.022-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.263.767 4.517-1.022-.264-.767-.264-.767-4.516 1.023zm9.032-2.044.264.767 4.517-1.023-.264-.766-.264-.767-4.516 1.022zm9.033-2.045.264.767 4.517-1.022-.264-.767-.264-.766-4.517 1.022zm9.033-2.044.264.767 4.516-1.023-.263-.766-.264-.767-4.517 1.022zm9.033-2.044.264.766 4.516-1.022-.264-.767-.263-.766-4.517 1.022zM88.39 8.81l.264.767 2.258-.511-.264-.767-.264-.767-2.258.511z M9.089 9.067c-.494-.112-.776-.546-.63-.97s.664-.675 1.157-.564l-.263.767zm81.823 16.866c.493.112.775.546.63.97s-.664.675-1.158.564l.264-.767zM11.875 8.044c.493.112.775.546.63.97s-.664.676-1.158.564l.264-.767zm3.988 2.556c-.493-.112-.775-.546-.63-.969s.664-.676 1.158-.564l-.264.766zm5.045-.511c.493.112.775.545.63.969s-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.111-.775-.545-.63-.968.146-.424.664-.677 1.158-.565l-.264.767zm5.044-.51c.494.111.776.545.63.968-.145.424-.664.676-1.157.565l.263-.767zm3.99 2.555c-.495-.112-.777-.546-.63-.97.145-.423.663-.675 1.157-.563l-.264.766zm5.043-.511c.494.112.776.545.63.969s-.664.676-1.158.564l.264-.767zm3.989 2.555c-.494-.111-.776-.545-.63-.969s.664-.676 1.157-.564l-.263.767zm5.044-.51c.494.11.776.545.63.968-.146.424-.664.676-1.158.565l.264-.767zm3.989 2.555c-.494-.112-.776-.546-.63-.97.145-.423.664-.675 1.157-.564l-.264.767zm5.044-.511c.493.111.775.545.63.969s-.664.676-1.158.564l.264-.767zm3.988 2.555c-.493-.112-.775-.545-.63-.969s.664-.676 1.158-.564l-.264.767zm5.045-.51c.493.11.775.545.63.968-.146.424-.664.676-1.158.564l.264-.766zm3.988 2.555c-.493-.112-.775-.546-.63-.97s.664-.675 1.158-.564l-.264.767zm5.044-.511c.494.111.776.545.63.968-.145.424-.664.677-1.157.565l.264-.767zm3.99 2.555c-.494-.112-.777-.545-.63-.969.145-.423.663-.676 1.157-.564l-.264.766zm5.043-.511c.494.112.776.546.63.969s-.664.676-1.157.564l.263-.766zm3.989 2.556c-.494-.112-.776-.546-.63-.97s.664-.676 1.158-.564l-.264.767zM9.353 8.3l.263-.767 2.259.511-.264.767-.264.767-2.258-.511zm6.774 1.533.264-.766 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.045.264-.767 4.516 1.022-.264.767-.263.767-4.517-1.023zm9.033 2.044.264-.766 4.516 1.022-.264.766-.264.767-4.516-1.022zm9.033 2.045.263-.767 4.517 1.022-.264.767-.264.767-4.516-1.023zm9.032 2.044.264-.767 4.517 1.023-.264.766-.264.767-4.516-1.022zm9.033 2.045.264-.767 4.517 1.022-.264.767-.264.766-4.517-1.022zm9.033 2.044.264-.767 4.516 1.023-.263.766-.264.767-4.517-1.022zm9.033 2.044.264-.766 4.516 1.022-.264.767-.263.766-4.517-1.022zm9.033 2.045.264-.767 2.258.511-.264.767-.264.767-2.258-.511z",viewW:100,viewH:35},shelf_wall:{d:"M18.36 3.15v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.309-.82-2.309-1.833V3.15m73.905 0v2.567c0 1.012-1.034 1.833-2.31 1.833h-.924c-1.275 0-2.31-.82-2.31-1.833V3.15m-75.29 0H93.65c1.276 0 2.31.82 2.31 1.833V19.65c0 1.012-1.034 1.833-2.31 1.833H5.888c-1.275 0-2.31-.82-2.31-1.833V4.983c0-1.012 1.035-1.833 2.31-1.833",viewW:100,viewH:25},cooktop_two:{d:"M15 30.982v-1.71m3.086 5.128h1.542M15 39.527v-1.709M10.372 34.4h1.542M5.84 46.364h18.322c1.331 0 2.41-1.196 2.41-2.67V6.306c0-1.475-1.079-2.67-2.41-2.67H5.839c-1.331 0-2.41 1.195-2.41 2.67v37.386c0 1.475 1.079 2.67 2.41 2.67m14.56-29.91c0 3.304-2.417 5.982-5.4 5.982-2.981 0-5.4-2.678-5.4-5.981s2.419-5.982 5.4-5.982c2.983 0 5.4 2.678 5.4 5.982M18.858 34.4c0 2.36-1.727 4.273-3.857 4.273s-3.857-1.913-3.857-4.273S12.87 30.127 15 30.127s3.857 1.913 3.857 4.273",viewW:30,viewH:50},stove:{d:"M41.4 35.261a.877.877 0 1 0-1.754 0zm4.384 6.138a.877.877 0 1 0 0-1.753zM41.4 44.03a.877.877 0 1 0-1.753 0zm-4.384-2.63a.877.877 0 1 0 0-1.754zM5.885 3.691v.877h48.23V2.815H5.885zm50.422 2.192h-.877v48.23h1.754V5.885zm-2.192 50.423v-.877H5.885v1.754h48.23zM3.692 54.115h.877V5.885H2.815v48.23zm2.192 2.192v-.877a1.315 1.315 0 0 1-1.315-1.315H2.815a3.07 3.07 0 0 0 3.07 3.069zm50.423-2.192h-.877c0 .726-.589 1.315-1.315 1.315v1.754a3.07 3.07 0 0 0 3.069-3.07zM54.115 3.692v.877c.726 0 1.315.589 1.315 1.315h1.754a3.07 3.07 0 0 0-3.07-3.069zm-48.23 0v-.877a3.07 3.07 0 0 0-3.07 3.07h1.754c0-.727.589-1.316 1.315-1.316zm19.73 36.83h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.015zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.261h-1.754a7.015 7.015 0 0 0 7.015 7.015zm-6.138-6.138h.877a5.26 5.26 0 0 1 5.261-5.262v-1.754a7.015 7.015 0 0 0-7.015 7.016zm6.138-6.139v.877a5.26 5.26 0 0 1 5.262 5.262h1.754a7.015 7.015 0 0 0-7.016-7.016zm27.185-14.908h-.877a5.26 5.26 0 0 1-5.261 5.262v1.754a7.015 7.015 0 0 0 7.015-7.016zm-6.138 6.139v-.877a5.26 5.26 0 0 1-5.262-5.262h-1.754a7.015 7.015 0 0 0 7.016 7.016zm-6.139-6.139h.877a5.26 5.26 0 0 1 5.262-5.261v-1.754a7.015 7.015 0 0 0-7.016 7.015zm6.139-6.138v.877a5.26 5.26 0 0 1 5.261 5.261h1.754a7.015 7.015 0 0 0-7.015-7.015zm4.384 27.185h-.877a3.51 3.51 0 0 1-3.507 3.507v1.754a5.26 5.26 0 0 0 5.261-5.261zm-4.384 4.384v-.877a3.51 3.51 0 0 1-3.508-3.507H35.26a5.26 5.26 0 0 0 5.262 5.261zm-4.385-4.384h.877a3.51 3.51 0 0 1 3.508-3.508V35.26a5.26 5.26 0 0 0-5.262 5.262zm4.385-4.385v.877a3.51 3.51 0 0 1 3.507 3.508h1.754a5.26 5.26 0 0 0-5.261-5.262zm0 .877h.876V35.26h-1.753v1.754zm3.508 3.508v.876h1.753v-1.753h-1.753zm-3.508 5.261h.876V44.03h-1.753v1.754zm-5.261-5.261v.876h1.753v-1.753h-1.753zm-9.647-21.047h-.877a5.26 5.26 0 0 1-5.262 5.262v1.754a7.015 7.015 0 0 0 7.016-7.016zm-6.139 6.139v-.877a5.26 5.26 0 0 1-5.261-5.262h-1.754a7.015 7.015 0 0 0 7.015 7.016zm-6.138-6.139h.877a5.26 5.26 0 0 1 5.261-5.261v-1.754a7.015 7.015 0 0 0-7.015 7.015zm6.138-6.138v.877a5.26 5.26 0 0 1 5.262 5.261h1.754a7.015 7.015 0 0 0-7.016-7.015z",viewW:60,viewH:60},tv:{d:"M45.134 10.766H6.18c-1.292 0-2.34.848-2.34 1.894v2.68c0 1.045 1.048 1.893 2.34 1.893h38.954m0-6.467V5.288c0-1.046 1.048-1.894 2.34-1.894h26.704c1.292 0 2.34.848 2.34 1.894v5.478m-31.384 0h31.384m0 0h37.302c1.293 0 2.34.848 2.34 1.894v2.68c0 1.045-1.047 1.893-2.34 1.893H76.518m-31.384 0v5.479c0 1.046 1.048 1.894 2.34 1.894h26.704c1.292 0 2.34-.848 2.34-1.894v-5.479m-31.384 0h31.384",viewW:120,viewH:28},tv_wall:{d:"M35.664 11.4c-.517 0-.936.269-.936.6s.419.6.936.6zm49.553 1.2c.517 0 .936-.269.936-.6s-.42-.6-.936-.6zM6.18 3v.6h107.64V2.4H6.18zm109.98 1.5h-.936v1.8h1.872V4.5zm-2.34 3.3v-.6H6.18v1.2h107.64zM3.84 6.3h.936V4.5H2.904v1.8zm2.34 1.5v-.6c-.775 0-1.404-.403-1.404-.9H2.904c0 1.16 1.467 2.1 3.276 2.1zm109.98-1.5h-.936c0 .497-.629.9-1.404.9v1.2c1.81 0 3.276-.94 3.276-2.1zM113.82 3v.6c.775 0 1.404.403 1.404.9h1.872c0-1.16-1.467-2.1-3.276-2.1zM6.18 3v-.6c-1.81 0-3.276.94-3.276 2.1h1.872c0-.497.629-.9 1.404-.9zm61.308 4.2h-.936V12h1.872V7.2zM52.512 12h.936V7.2h-1.872V12zm-16.848 0v.6h49.553v-1.2H35.664z",viewW:120,viewH:15},toilet:{d:"M3.555 48.976c0 9.55 7.125 17.29 15.914 17.29h1.061c8.79 0 15.914-7.74 15.914-17.29V5.966c0-1.233-.92-2.233-2.056-2.233H5.611c-1.135 0-2.056 1-2.056 2.234z M7.666 49.12c0 7.003 5.225 12.68 11.67 12.68h1.327c6.445 0 11.67-5.677 11.67-12.68V31.873c0-1.233-.92-2.233-2.056-2.233H9.722c-1.135 0-2.056 1-2.056 2.233zM33.792 3.733c1.465 0 2.652 1.29 2.652 2.882v12.103c0 1.592-1.187 2.882-2.652 2.882H6.208c-1.465 0-2.653-1.29-2.653-2.882V6.615c0-1.591 1.188-2.882 2.653-2.882z M24.11 50.186c0 2.467-1.84 4.467-4.11 4.467s-4.111-2-4.111-4.467 1.84-4.466 4.11-4.466 4.112 2 4.112 4.466",viewW:40,viewH:70},toilet_built_in:{d:"M3.555 34.56c0 9.263 7.125 16.774 15.914 16.774h1.061c8.79 0 15.914-7.51 15.914-16.775V5.833c0-1.196-.92-2.166-2.056-2.166H5.611c-1.135 0-2.056.97-2.056 2.166z M7.666 34.7c0 6.793 5.225 12.3 11.67 12.3h1.327c6.445 0 11.67-5.507 11.67-12.3V14.5c0-1.197-.92-2.167-2.056-2.167H9.722c-1.135 0-2.056.97-2.056 2.167z M24.11 35.733c0 2.394-1.84 4.334-4.11 4.334s-4.111-1.94-4.111-4.334 1.84-4.333 4.11-4.333 4.112 1.94 4.112 4.333",viewW:40,viewH:55},bathtub:{d:"M3.885 6c0-1.243 1.068-2.25 2.386-2.25h157.458c1.318 0 2.386 1.007 2.386 2.25v63c0 1.243-1.068 2.25-2.386 2.25H6.27c-1.318 0-2.386-1.007-2.386-2.25z M13.428 37.5c0-13.669 11.75-24.75 26.243-24.75h90.658c14.493 0 26.243 11.081 26.243 24.75s-11.75 24.75-26.243 24.75H39.67c-14.493 0-26.243-11.081-26.243-24.75 M31.56 37.5c0 2.237-1.923 4.05-4.295 4.05s-4.294-1.813-4.294-4.05 1.923-4.05 4.294-4.05c2.372 0 4.295 1.813 4.295 4.05",viewW:170,viewH:75},bathtub_corner:{d:"M3.862 6.224a2.36 2.36 0 0 1 2.362-2.362H133.97c1.197 0 2.168.97 2.168 2.168 0 71.857-58.251 130.108-130.108 130.108a2.17 2.17 0 0 1-2.168-2.168z M13.31 32.207c0-10.437 8.46-18.897 18.897-18.897h87.628a2.13 2.13 0 0 1 2.13 2.13c0 58.833-47.692 106.526-106.524 106.526a2.13 2.13 0 0 1-2.13-2.131z M32.207 27.483a4.724 4.724 0 1 1-9.449 0 4.724 4.724 0 0 1 9.449 0",viewW:140,viewH:140},bidet:{d:"M22.466 3.692v10.085c0 1.21-.92 2.192-2.055 2.192h-.822c-1.136 0-2.056-.981-2.056-2.192V3.692m4.933 8.77h2.878c1.135 0 2.056-.982 2.056-2.193v-.877c0-1.21-.92-2.192-2.056-2.192h-2.878m-4.933 5.262h-2.878c-1.135 0-2.055-.982-2.055-2.193v-.877c0-1.21.92-2.192 2.055-2.192h2.878M5.611 3.692h28.777c1.136 0 2.056.981 2.056 2.192v33.45c0 9.374-7.125 16.973-15.914 16.973h-1.06c-8.79 0-15.915-7.599-15.915-16.972V5.885c0-1.212.92-2.193 2.056-2.193m4.11 15.785h20.556c1.136 0 2.056.981 2.056 2.192v17.807c0 6.874-5.225 12.447-11.67 12.447h-1.327c-6.445 0-11.67-5.573-11.67-12.447V21.67c0-1.21.92-2.192 2.056-2.192m13.567 7.892c0 1.937-1.472 3.508-3.288 3.508-1.817 0-3.29-1.57-3.29-3.508s1.473-3.507 3.29-3.507 3.288 1.57 3.288 3.507",viewW:40,viewH:60},bidet_built_in:{d:"M17.318 12.182h-8.06c-.88 0-1.592.74-1.592 1.654v16.126c0 6.698 5.225 12.129 11.67 12.129h1.327c6.445 0 11.67-5.43 11.67-12.13V13.837c0-.914-.713-1.654-1.591-1.654H22.68m-.215-8.545v9.827c0 1.18-.92 2.136-2.055 2.136h-.822c-1.136 0-2.056-.956-2.056-2.136V3.637m10.689 8.545V3.637m-16.445 0v8.545M5.611 3.637h28.777c1.136 0 2.056.956 2.056 2.136v24.051c0 9.135-7.125 16.54-15.914 16.54h-1.06c-8.79 0-15.915-7.405-15.915-16.54V5.773c0-1.18.92-2.136 2.056-2.136M23.289 23.29c0 1.888-1.473 3.418-3.29 3.418s-3.288-1.53-3.288-3.418 1.472-3.418 3.289-3.418c1.816 0 3.288 1.53 3.288 3.418",viewW:40,viewH:50},kitchen_sink:{d:"M38.188 8.7h10.598c1.211 0 2.193.956 2.193 2.136v28.2c0 1.18-.982 2.136-2.193 2.136H11.08c-1.21 0-2.192-.956-2.192-2.136v-28.2c0-1.18.981-2.136 2.192-2.136h10.599m10.885-5.128V15.11c0 1.18-.981 2.136-2.192 2.136h-.877c-1.21 0-2.192-.957-2.192-2.136V3.572m5.261 7.691h3.07c1.21 0 2.192-.956 2.192-2.136v-.855c0-1.18-.982-2.136-2.192-2.136h-3.07m-5.261 5.127h-3.07c-1.21 0-2.192-.956-2.192-2.136v-.855c0-1.18.982-2.136 2.193-2.136h3.069M5.817 46.299h48.231c1.21 0 2.192-.956 2.192-2.136V5.709c0-1.18-.981-2.137-2.192-2.137H5.818c-1.211 0-2.193.957-2.193 2.137v38.454c0 1.18.982 2.136 2.192 2.136M33.44 25.79c0 1.888-1.57 3.418-3.507 3.418s-3.508-1.53-3.508-3.418c0-1.887 1.57-3.418 3.508-3.418s3.507 1.53 3.507 3.418",viewW:60,viewH:50},kitchen_sink_double:{d:"M53.173 12.182c-.468 0-.847.354-.847.79s.38.79.847.79zm21.979 1.58c.467 0 .846-.353.846-.79 0-.436-.379-.79-.846-.79zM6.01 3.572v.79h77.842v-1.58H6.01zM86.14 5.71h-.847v38.454h1.694V5.709zM83.85 46.3v-.79H6.01v1.58h77.842zM3.72 44.163h.847V5.709H2.873v38.454zm2.29 2.136v-.79c-.797 0-1.443-.603-1.443-1.346H2.873c0 1.616 1.404 2.926 3.137 2.926zm80.131-2.136h-.847c0 .743-.646 1.346-1.442 1.346v1.58c1.732 0 3.136-1.31 3.136-2.926zm-2.29-40.59v.79c.797 0 1.443.602 1.443 1.346h1.694c0-1.617-1.404-2.927-3.136-2.927zm-77.841 0v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.744.646-1.347 1.443-1.347zm5.494 37.599v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2h-1.694v28.2zm-32.97-28.2h-.846v28.2h1.694v-28.2zM39.895 8.7v-.79h-5.669v1.58h5.669zm-22.721 0v-.79h-5.669v1.58h5.669zm-7.958 2.136h.847c0-.744.645-1.346 1.442-1.346V7.91c-1.732 0-3.136 1.31-3.136 2.926zm32.968 0h.847c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.442.603 1.442 1.347zm-2.29 30.336v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.645 1.346-1.442 1.346zm-28.389 0v-.79c-.797 0-1.442-.603-1.442-1.346H8.368c0 1.616 1.404 2.926 3.136 2.926zm13.737-23.927v.79h.916v-1.58h-.916zm3.205-2.136h.847V3.572H27.6V15.11zM22.952 3.572h-.847V15.11h1.693V3.572zm3.205 13.673v.79c1.732 0 3.136-1.31 3.136-2.926H27.6c0 .743-.646 1.346-1.443 1.346zm-.916 0v-.79c-.797 0-1.443-.603-1.443-1.346h-1.693c0 1.616 1.404 2.926 3.136 2.926zm3.205-5.982v.79h3.206v-1.58h-3.206zm5.495-2.136h.847v-.855h-1.694v.855zm-2.29-2.991v-.79h-3.205v1.58h3.206zm2.29 2.136h.847c0-1.616-1.404-2.926-3.136-2.926v1.58c.796 0 1.442.603 1.442 1.346zm-2.29 2.991v.79c1.733 0 3.137-1.31 3.137-2.926h-1.694c0 .743-.646 1.346-1.442 1.346zm-11.905 0v.79h3.206v-1.58h-3.206zm3.206-5.127v-.79h-3.206v1.58h3.206zm-5.495 2.136h-.847v.855h1.694v-.855zm2.29-2.136v-.79c-1.733 0-3.137 1.31-3.137 2.926h1.694c0-.743.646-1.346 1.442-1.346zm0 5.127v-.79c-.797 0-1.443-.603-1.443-1.346H16.61c0 1.616 1.404 2.926 3.136 2.926zm9.615 14.527h-.847c0 1.452-1.26 2.628-2.816 2.628v1.58c2.49 0 4.51-1.884 4.51-4.208zM25.7 29.208v-.79c-1.555 0-2.816-1.176-2.816-2.628H21.19c0 2.324 2.02 4.209 4.51 4.209zm-3.663-3.418h.847c0-1.451 1.26-2.628 2.816-2.628v-1.58c-2.49 0-4.51 1.884-4.51 4.208zm3.663-3.418v.79c1.555 0 2.816 1.177 2.816 2.628h1.694c0-2.324-2.02-4.208-4.51-4.208zm24.268 18.8v.79h28.39v-1.58h-28.39zm30.68-2.136h.846v-28.2H79.8v28.2zM78.356 8.7v-.79h-28.39v1.58h28.39zm-30.68 2.136h-.846v28.2h1.694v-28.2zm2.29-2.136v-.79c-1.732 0-3.136 1.31-3.136 2.926h1.694c0-.744.646-1.346 1.442-1.346zm30.68 2.136h.846c0-1.616-1.404-2.927-3.136-2.927v1.58c.797 0 1.443.603 1.443 1.347zm-2.29 30.336v.79c1.732 0 3.136-1.31 3.136-2.926H79.8c0 .743-.646 1.346-1.443 1.346zm-28.39 0v-.79c-.796 0-1.442-.603-1.442-1.346H46.83c0 1.616 1.404 2.926 3.136 2.926zm3.206-28.2v.79h21.979v-1.58h-21.98z",viewW:90,viewH:50}};export{c as FURNITURE_ART_FINGERPRINT,v as GENERATED_FURNITURE_ART}; diff --git a/dist/houseplan-assets/houseplan-card-BCGpvbDT.js b/dist/houseplan-assets/houseplan-card-Di_izZTU.js similarity index 72% rename from dist/houseplan-assets/houseplan-card-BCGpvbDT.js rename to dist/houseplan-assets/houseplan-card-Di_izZTU.js index 2eeab64c..4d872ef2 100644 --- a/dist/houseplan-assets/houseplan-card-BCGpvbDT.js +++ b/dist/houseplan-assets/houseplan-card-Di_izZTU.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),n=new WeakMap;let r=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=n.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&n.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const n=1===e.length?e[0]:t.reduce((t,i,n)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[n+1],e[0]);return new r(n,e,i)},s=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new r("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:a,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,m=_?_.emptyScript:"",g=p.reactiveElementPolyfillSupport,f=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},y=(e,t)=>!a(e,t),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=b){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(e,i,t);void 0!==n&&l(this.prototype,e,n)}}static getPropertyDescriptor(e,t,i){const{get:n,set:r}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:n,set(t){const o=n?.call(this);r?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const e=u(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(s(e))}else void 0!==e&&t.push(s(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,n)=>{if(t)i.adoptedStyleSheets=n.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of n){const n=document.createElement("style"),r=e.litNonce;void 0!==r&&n.setAttribute("nonce",r),n.textContent=t.cssText,i.appendChild(n)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,i);if(void 0!==n&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==r?this.removeAttribute(n):this.setAttribute(n,r),this._$Em=null}}_$AK(e,t){const i=this.constructor,n=i._$Eh.get(e);if(void 0!==n&&this._$Em!==n){const e=i.getPropertyOptions(n),r="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=n;const o=r.fromAttribute(t,e.type);this[n]=o??this._$Ej?.get(n)??o,this._$Em=null}}requestUpdate(e,t,i,n=!1,r){if(void 0!==e){const o=this.constructor;if(!1===n&&(r=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??y)(r,t)||i.useDefault&&i.reflect&&r===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:n,wrapped:r},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==r||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===n&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,n=this[t];!0!==e||this._$AL.has(t)||void 0===n||this.C(t,void 0,i,n)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,g?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,S=k.trustedTypes,$=S?S.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",R=`lit$${Math.random().toFixed(9).slice(2)}$`,C="?"+R,T=`<${C}>`,D=document,A=()=>D.createComment(""),P=e=>null===e||"object"!=typeof e&&"function"!=typeof e,F=Array.isArray,z="[ \t\n\f\r]",I=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,O=/-->/g,E=/>/g,N=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!F(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==$?$.createHTML(t):t}const X=(e,t)=>{const i=e.length-1,n=[];let r,o=2===t?"":3===t?"":"",s=I;for(let t=0;t"===l[0]?(s=r??I,c=-1):void 0===l[1]?c=-2:(c=s.lastIndex-l[2].length,a=l[1],s=void 0===l[3]?N:'"'===l[3]?L:H):s===L||s===H?s=N:s===O||s===E?s=I:(s=N,r=void 0);const d=s===N&&e[t+1].startsWith("/>")?" ":"";o+=s===I?i+T:c>=0?(n.push(a),i.slice(0,c)+M+i.slice(c)+R+d):i+R+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),n]};class Z{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let r=0,o=0;const s=e.length-1,a=this.parts,[l,c]=X(e,t);if(this.el=Z.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=K.nextNode())&&a.length0){n.textContent=S?S.emptyScript:"";for(let i=0;iF(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==G&&P(this._$AH)?this._$AA.nextSibling.data=e:this.T(D.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,n="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=Z.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(t);else{const e=new Q(n,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=V.get(e.strings);return void 0===t&&V.set(e.strings,t=new Z(e)),t}k(e){F(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,n=0;for(const r of e)n===t.length?t.push(i=new ee(this.O(A()),this.O(A()),this,this.options)):i=t[n],i._$AI(r),n++;n2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!P(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const n=e;let s,a;for(e=r[0],s=0;s{const n=i?.renderBefore??t;let r=n._$litPart$;if(void 0===r){const e=i?.renderBefore??null;n._$litPart$=r=new ee(t.insertBefore(A(),e),e,void 0,i??{})}return r._$AI(e),r},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const ue=2,pe=e=>(...t)=>({_$litDirective$:e,values:t});let _e=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,i){this._$Ct=e,this._$AM=t,this._$Ci=i}_$AS(e,t){return this.update(e,t)}update(e,t){return this.render(...t)}};const{I:me}=se,ge=e=>e,fe=(e,t)=>void 0!==e?._$litType$,ve=()=>document.createComment(""),ye=(e,t,i)=>{const n=e._$AA.parentNode,r=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=n.insertBefore(ve(),r),o=n.insertBefore(ve(),r);i=new me(t,o,e,e.options)}else{const t=i._$AB.nextSibling,o=i._$AM,s=o!==e;if(s){let t;i._$AQ?.(e),i._$AM=e,void 0!==i._$AP&&(t=e._$AU)!==o._$AU&&i._$AP(t)}if(t!==r||s){let e=i._$AA;for(;e!==t;){const t=ge(e).nextSibling;ge(n).insertBefore(e,r),e=t}}}return i},be=(e,t,i=e)=>(e._$AI(t,i),e),we={},ke=(e,t=we)=>e._$AH=t,xe=e=>e._$AH,Se=e=>{e._$AR(),e._$AA.remove()},$e=e=>(e=>null!=e?._$litType$?.h)(e)?e._$litType$.h:e.strings,Me=pe(class extends _e{constructor(e){super(e),this.et=new WeakMap}render(e){return[e]}update(e,[t]){const i=fe(this.it)?$e(this.it):null,n=fe(t)?$e(t):null;if(null!==i&&(null===n||i!==n)){const t=xe(e).pop();let n=this.et.get(i);if(void 0===n){const e=document.createDocumentFragment();n=le(G,e),n.setConnected(!1),this.et.set(i,n)}ke(n,[t]),ye(n,void 0,t)}if(null!==n){if(null===i||i!==n){const t=this.et.get(n);if(void 0!==t){const i=xe(t).pop();(e=>{e._$AR()})(e),ye(e,void 0,i),ke(e,[i])}}this.it=t}else this.it=void 0;return this.render(t)}}),Re=pe(class extends _e{constructor(){super(...arguments),this.key=G}render(e,t){return this.key=e,t}update(e,[t,i]){return t!==this.key&&(ke(e),this.key=t),i}}),Ce=(e,t,i)=>{const n=new Map;for(let r=t;r<=i;r++)n.set(e[r],r);return n},Te=pe(class extends _e{constructor(e){if(super(e),e.type!==ue)throw Error("repeat() can only be used in text expressions")}dt(e,t,i){let n;void 0===i?i=t:void 0!==t&&(n=t);const r=[],o=[];let s=0;for(const t of e)r[s]=n?n(t,s):s,o[s]=i(t,s),s++;return{values:o,keys:r}}render(e,t,i){return this.dt(e,t,i).values}update(e,[t,i,n]){const r=xe(e),{values:o,keys:s}=this.dt(t,i,n);if(!Array.isArray(r))return this.ut=s,o;const a=this.ut??=[],l=[];let c,h,d=0,u=r.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===r[d])d++;else if(null===r[u])u--;else if(a[d]===s[p])l[p]=be(r[d],o[p]),d++,p++;else if(a[u]===s[_])l[_]=be(r[u],o[_]),u--,_--;else if(a[d]===s[_])l[_]=be(r[d],o[_]),ye(e,l[_+1],r[d]),d++,_--;else if(a[u]===s[p])l[p]=be(r[u],o[p]),ye(e,r[d],r[u]),u--,p++;else if(void 0===c&&(c=Ce(s,p,_),h=Ce(a,d,u)),c.has(a[d]))if(c.has(a[u])){const t=h.get(s[p]),i=void 0!==t?r[t]:null;if(null===i){const t=ye(e,r[d]);be(t,o[p]),l[p]=t}else l[p]=be(i,o[p]),ye(e,r[d],i),r[t]=null;p++}else Se(r[u]),u--;else Se(r[d]),d++;for(;p<=_;){const t=ye(e,l[_+1]);be(t,o[p]),l[p++]=t}for(;d<=u;){const e=r[d++];null!==e&&Se(e)}return this.ut=s,ke(e,l),U}}),De=new WeakMap;let Ae=0;class Pe extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",this.dismissOnScrim=!1,this.flexContent=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=null,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Ae,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._usesHaDialog()?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._usesHaDialog())return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const n=this._deepActiveElement(),r=i[0],o=i[i.length-1];!e.shiftKey||n!==r&&i.includes(n)?e.shiftKey||n!==o||(e.preventDefault(),r.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}_usesHaDialog(){return!0===this._useHaDialog&&!this.alert}connectedCallback(){this.setAttribute("data-hp","dialog"),super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=De.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),De.set(e,t),null===this._useHaDialog&&(this._useHaDialog=!!customElements.get("ha-dialog")),this.addEventListener("keydown",this._onKeyDown,!0),queueMicrotask(()=>{this._ensureNativeModal()&&this._focusInitial()})}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const n=t?De.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=De.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void De.delete(t);const n=i?.closest("hp-dialog");i?.isConnected&&n&&e.dialogs.has(n)&&i.focus({preventScroll:!0})})}firstUpdated(e){super.firstUpdated(e),this._ensureNativeModal(),queueMicrotask(()=>this._focusInitial())}updated(e){super.updated(e),this._ensureNativeModal()}_ensureNativeModal(){if(this._usesHaDialog()||!this.isConnected)return!1;const e=this.renderRoot.querySelector("dialog");if(!e?.isConnected)return!1;try{return!e.matches(":modal")&&(e.open&&e.close(),e.showModal(),!0)}catch{return!1}}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),t=[],i=new Set,n=r=>{if(!i.has(r)){if(i.add(r),r instanceof HTMLElement){if(r.matches(e)&&t.push(r),r instanceof HTMLSlotElement){for(const e of r.assignedNodes({flatten:!0}))n(e);return}if(r.shadowRoot){for(const e of r.shadowRoot.childNodes)n(e);return}}for(const e of r.childNodes)n(e)}};for(const e of this.childNodes)n(e);const r=this.overlayPortal();return r&&n(r),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}rejectClose(){this._closing=!1,this.requestUpdate()}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const n={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(n);let r=!1;return()=>{if(r)return;r=!0;const e=this._overlays.findIndex(e=>e.token===n.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=j` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),n=new WeakMap;let r=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=n.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&n.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const n=1===e.length?e[0]:t.reduce((t,i,n)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[n+1],e[0]);return new r(n,e,i)},s=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new r("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:a,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,m=_?_.emptyScript:"",g=p.reactiveElementPolyfillSupport,f=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},y=(e,t)=>!a(e,t),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=b){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(e,i,t);void 0!==n&&l(this.prototype,e,n)}}static getPropertyDescriptor(e,t,i){const{get:n,set:r}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:n,set(t){const o=n?.call(this);r?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const e=u(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(s(e))}else void 0!==e&&t.push(s(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,n)=>{if(t)i.adoptedStyleSheets=n.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of n){const n=document.createElement("style"),r=e.litNonce;void 0!==r&&n.setAttribute("nonce",r),n.textContent=t.cssText,i.appendChild(n)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,i);if(void 0!==n&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==r?this.removeAttribute(n):this.setAttribute(n,r),this._$Em=null}}_$AK(e,t){const i=this.constructor,n=i._$Eh.get(e);if(void 0!==n&&this._$Em!==n){const e=i.getPropertyOptions(n),r="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=n;const o=r.fromAttribute(t,e.type);this[n]=o??this._$Ej?.get(n)??o,this._$Em=null}}requestUpdate(e,t,i,n=!1,r){if(void 0!==e){const o=this.constructor;if(!1===n&&(r=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??y)(r,t)||i.useDefault&&i.reflect&&r===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:n,wrapped:r},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==r||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===n&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,n=this[t];!0!==e||this._$AL.has(t)||void 0===n||this.C(t,void 0,i,n)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,g?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,S=k.trustedTypes,$=S?S.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",R=`lit$${Math.random().toFixed(9).slice(2)}$`,C="?"+R,T=`<${C}>`,D=document,A=()=>D.createComment(""),P=e=>null===e||"object"!=typeof e&&"function"!=typeof e,F=Array.isArray,z="[ \t\n\f\r]",I=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,O=/-->/g,E=/>/g,N=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!F(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==$?$.createHTML(t):t}const X=(e,t)=>{const i=e.length-1,n=[];let r,o=2===t?"":3===t?"":"",s=I;for(let t=0;t"===l[0]?(s=r??I,c=-1):void 0===l[1]?c=-2:(c=s.lastIndex-l[2].length,a=l[1],s=void 0===l[3]?N:'"'===l[3]?L:H):s===L||s===H?s=N:s===O||s===E?s=I:(s=N,r=void 0);const d=s===N&&e[t+1].startsWith("/>")?" ":"";o+=s===I?i+T:c>=0?(n.push(a),i.slice(0,c)+M+i.slice(c)+R+d):i+R+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),n]};class Z{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let r=0,o=0;const s=e.length-1,a=this.parts,[l,c]=X(e,t);if(this.el=Z.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=K.nextNode())&&a.length0){n.textContent=S?S.emptyScript:"";for(let i=0;iF(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==G&&P(this._$AH)?this._$AA.nextSibling.data=e:this.T(D.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,n="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=Z.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(t);else{const e=new Q(n,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=V.get(e.strings);return void 0===t&&V.set(e.strings,t=new Z(e)),t}k(e){F(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,n=0;for(const r of e)n===t.length?t.push(i=new ee(this.O(A()),this.O(A()),this,this.options)):i=t[n],i._$AI(r),n++;n2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!P(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const n=e;let s,a;for(e=r[0],s=0;s{const n=i?.renderBefore??t;let r=n._$litPart$;if(void 0===r){const e=i?.renderBefore??null;n._$litPart$=r=new ee(t.insertBefore(A(),e),e,void 0,i??{})}return r._$AI(e),r},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const ue=2,pe=e=>(...t)=>({_$litDirective$:e,values:t});let _e=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,i){this._$Ct=e,this._$AM=t,this._$Ci=i}_$AS(e,t){return this.update(e,t)}update(e,t){return this.render(...t)}};const{I:me}=se,ge=e=>e,fe=(e,t)=>void 0!==e?._$litType$,ve=()=>document.createComment(""),ye=(e,t,i)=>{const n=e._$AA.parentNode,r=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=n.insertBefore(ve(),r),o=n.insertBefore(ve(),r);i=new me(t,o,e,e.options)}else{const t=i._$AB.nextSibling,o=i._$AM,s=o!==e;if(s){let t;i._$AQ?.(e),i._$AM=e,void 0!==i._$AP&&(t=e._$AU)!==o._$AU&&i._$AP(t)}if(t!==r||s){let e=i._$AA;for(;e!==t;){const t=ge(e).nextSibling;ge(n).insertBefore(e,r),e=t}}}return i},be=(e,t,i=e)=>(e._$AI(t,i),e),we={},ke=(e,t=we)=>e._$AH=t,xe=e=>e._$AH,Se=e=>{e._$AR(),e._$AA.remove()},$e=e=>(e=>null!=e?._$litType$?.h)(e)?e._$litType$.h:e.strings,Me=pe(class extends _e{constructor(e){super(e),this.et=new WeakMap}render(e){return[e]}update(e,[t]){const i=fe(this.it)?$e(this.it):null,n=fe(t)?$e(t):null;if(null!==i&&(null===n||i!==n)){const t=xe(e).pop();let n=this.et.get(i);if(void 0===n){const e=document.createDocumentFragment();n=le(G,e),n.setConnected(!1),this.et.set(i,n)}ke(n,[t]),ye(n,void 0,t)}if(null!==n){if(null===i||i!==n){const t=this.et.get(n);if(void 0!==t){const i=xe(t).pop();(e=>{e._$AR()})(e),ye(e,void 0,i),ke(e,[i])}}this.it=t}else this.it=void 0;return this.render(t)}}),Re=pe(class extends _e{constructor(){super(...arguments),this.key=G}render(e,t){return this.key=e,t}update(e,[t,i]){return t!==this.key&&(ke(e),this.key=t),i}}),Ce=(e,t,i)=>{const n=new Map;for(let r=t;r<=i;r++)n.set(e[r],r);return n},Te=pe(class extends _e{constructor(e){if(super(e),e.type!==ue)throw Error("repeat() can only be used in text expressions")}dt(e,t,i){let n;void 0===i?i=t:void 0!==t&&(n=t);const r=[],o=[];let s=0;for(const t of e)r[s]=n?n(t,s):s,o[s]=i(t,s),s++;return{values:o,keys:r}}render(e,t,i){return this.dt(e,t,i).values}update(e,[t,i,n]){const r=xe(e),{values:o,keys:s}=this.dt(t,i,n);if(!Array.isArray(r))return this.ut=s,o;const a=this.ut??=[],l=[];let c,h,d=0,u=r.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===r[d])d++;else if(null===r[u])u--;else if(a[d]===s[p])l[p]=be(r[d],o[p]),d++,p++;else if(a[u]===s[_])l[_]=be(r[u],o[_]),u--,_--;else if(a[d]===s[_])l[_]=be(r[d],o[_]),ye(e,l[_+1],r[d]),d++,_--;else if(a[u]===s[p])l[p]=be(r[u],o[p]),ye(e,r[d],r[u]),u--,p++;else if(void 0===c&&(c=Ce(s,p,_),h=Ce(a,d,u)),c.has(a[d]))if(c.has(a[u])){const t=h.get(s[p]),i=void 0!==t?r[t]:null;if(null===i){const t=ye(e,r[d]);be(t,o[p]),l[p]=t}else l[p]=be(i,o[p]),ye(e,r[d],i),r[t]=null;p++}else Se(r[u]),u--;else Se(r[d]),d++;for(;p<=_;){const t=ye(e,l[_+1]);be(t,o[p]),l[p++]=t}for(;d<=u;){const e=r[d++];null!==e&&Se(e)}return this.ut=s,ke(e,l),U}}),De=new WeakMap;let Ae=0;class Pe extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",this.dismissOnScrim=!1,this.flexContent=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=null,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Ae,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._usesHaDialog()?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._usesHaDialog())return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const n=this._deepActiveElement(),r=i[0],o=i[i.length-1];!e.shiftKey||n!==r&&i.includes(n)?e.shiftKey||n!==o||(e.preventDefault(),r.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}_usesHaDialog(){return!0===this._useHaDialog&&!this.alert}connectedCallback(){this.setAttribute("data-hp","dialog"),super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=De.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),De.set(e,t),null===this._useHaDialog&&(this._useHaDialog=!!customElements.get("ha-dialog")),this.addEventListener("keydown",this._onKeyDown,!0),queueMicrotask(()=>{this._ensureNativeModal()&&this._focusInitial()})}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const n=t?De.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=De.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void De.delete(t);const n=i?.closest("hp-dialog");i?.isConnected&&n&&e.dialogs.has(n)&&i.focus({preventScroll:!0})})}firstUpdated(e){super.firstUpdated(e),this._ensureNativeModal(),queueMicrotask(()=>this._focusInitial())}updated(e){super.updated(e),this._ensureNativeModal()}_ensureNativeModal(){if(this._usesHaDialog()||!this.isConnected)return!1;const e=this.renderRoot.querySelector("dialog");if(!e?.isConnected)return!1;try{return!e.matches(":modal")&&(e.open&&e.close(),e.showModal(),!0)}catch{return!1}}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),t=[],i=new Set,n=r=>{if(!i.has(r)){if(i.add(r),r instanceof HTMLElement){if(r.matches(e)&&t.push(r),r instanceof HTMLSlotElement){for(const e of r.assignedNodes({flatten:!0}))n(e);return}if(r.shadowRoot){for(const e of r.shadowRoot.childNodes)n(e);return}}for(const e of r.childNodes)n(e)}};for(const e of this.childNodes)n(e);const r=this.overlayPortal();return r&&n(r),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}rejectClose(){this._closing=!1,this.requestUpdate()}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const n={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(n);let r=!1;return()=>{if(r)return;r=!0;const e=this._overlays.findIndex(e=>e.token===n.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=j` ${this.icon?j``:G} ${this.title} `;return this._usesHaDialog()?this.describedBy?j`{this._active={...t,resolve:e},this._changed(t)})}resolve(e,t){const i=this._active;return!(!i||i.token!==e)&&(this._active=null,this._changed(null),i.resolve(t),!0)}cancel(){const e=this._active;return!!e&&this.resolve(e.token,!1)}}const Ie=new Set(["hacs","sun","backup","hassio","met","telegram_bot","mobile_app","systemmonitor","better_thermostat","adaptive_lighting","yandex_pogoda","upnp_serial_number"]),Oe=[{pattern:"протечк|leak|water sensor",icon:"mdi:water-alert"},{pattern:"клапан|valve",icon:"mdi:pipe-valve"},{pattern:"дым|smoke",icon:"mdi:smoke-detector"},{pattern:"термоголов|trv|radiator",icon:"mdi:radiator"},{pattern:"чайник|kettle|термопот",icon:"mdi:kettle"},{pattern:"сауна|sauna|harvia|парная|парилк",icon:"mdi:hot-tub"},{pattern:"температ|temperature|thermometer|climate sensor",icon:"mdi:thermometer"},{pattern:"qingping|air monitor|молекул|air quality",icon:"mdi:air-filter"},{pattern:"штор|curtain|blind|shade",icon:"mdi:roller-shade"},{pattern:"розетк|plug|socket|outlet",icon:"mdi:power-socket-de"},{pattern:"выключат|switch",icon:"mdi:light-switch"},{pattern:"лампа|лампочк|bulb|gx53|светильник|rgb|lamp|light strip",icon:"mdi:lightbulb"},{pattern:"камер|camera",icon:"mdi:cctv"},{pattern:"замок|ttlock|lock|sn609|sn9161",icon:"mdi:lock"},{pattern:"ворота|garage|gate",icon:"mdi:garage-variant"},{pattern:"калитк|door|открыт|contact",icon:"mdi:door"},{pattern:"счётчик|счетчик|kws|meter",icon:"mdi:meter-electric"},{pattern:"вводный автомат|breaker|wifimcbn",icon:"mdi:electric-switch"},{pattern:"myheat|котёл|котел|boiler|отоплен|heating",icon:"mdi:water-boiler"},{pattern:"холодильник|fridge",icon:"mdi:fridge"},{pattern:"стиральн|washer|washing",icon:"mdi:washing-machine"},{pattern:"сушилк|dryer",icon:"mdi:tumble-dryer"},{pattern:"пылесос|vacuum|dreame|roborock",icon:"mdi:robot-vacuum"},{pattern:"soundbar",icon:"mdi:soundbar"},{pattern:"колонк|станц|speaker|яндекс|yandex|алиса|alice",icon:"mdi:speaker"},{pattern:"tv|телевизор|hyundaitv|mitv|television",icon:"mdi:television"},{pattern:"keenetic|роутер|router|mesh|access point",icon:"mdi:router-wireless"},{pattern:"ибп|ups|kirpich",icon:"mdi:battery-charging-high"},{pattern:"slzb|координат|zigbee|coordinator",icon:"mdi:zigbee"},{pattern:"motion|движен|presence|присутств",icon:"mdi:motion-sensor"},{pattern:"humidity|влажн",icon:"mdi:water-percent"}];function Ee(e){const t=[];for(const i of e)if(i&&"string"==typeof i.pattern&&i.icon)try{t.push({re:new RegExp(i.pattern,"i"),icon:i.icon})}catch{}return t}function Ne(e){try{return new RegExp(e,"i"),!0}catch{return!1}}const He=Ee(Oe),Le={temperature:"mdi:thermometer",humidity:"mdi:water-percent",motion:"mdi:motion-sensor",occupancy:"mdi:motion-sensor",presence:"mdi:motion-sensor",door:"mdi:door",window:"mdi:window-closed",garage_door:"mdi:garage-variant",smoke:"mdi:smoke-detector",moisture:"mdi:water-alert",gas:"mdi:gas-cylinder",power:"mdi:meter-electric",energy:"mdi:meter-electric",illuminance:"mdi:brightness-5",co2:"mdi:molecule-co2",pm25:"mdi:air-filter",battery:"mdi:battery"},Be="mdi:chip";function qe(e,t,i){const n=((e||"")+" "+(t||"")).toLowerCase();for(const{re:e,icon:t}of i??He)if(e.test(n))return t;return Be}const je=["light","switch","cover","valve","lock","climate","fan","media_player","camera","vacuum","humidifier","water_heater","alarm_control_panel","sensor","binary_sensor","event","button","number","select","update"];var We=/^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i,Ue=Math.ceil,Ge=Math.floor,Ve="[BigNumber Error] ",Ke=Ve+"Number primitive has more than 15 significant digits: ",Ye=1e14,Xe=14,Ze=9007199254740991,Je=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],Qe=1e7,et=1e9;function tt(e){var t=0|e;return e>0||e===t?t:t-1}function it(e){for(var t,i,n=1,r=e.length,o=e[0]+"";nc^i?1:-1;for(a=(l=r.length)<(c=o.length)?l:c,s=0;so[s]^i?1:-1;return l==c?0:l>c^i?1:-1}function rt(e,t,i,n){if(ei||e!==Ge(e))throw Error(Ve+(n||"Argument")+("number"==typeof e?ei?" out of range: ":" not an integer: ":" not a primitive number: ")+String(e))}function ot(e){var t=e.c.length-1;return tt(e.e/Xe)==t&&e.c[t]%2!=0}function st(e,t){return(e.length>1?e.charAt(0)+"."+e.slice(1):e)+(t<0?"e":"e+")+t}function at(e,t,i){var n,r;if(t<0){for(r=i+".";++t;r+=i);e=r+e}else if(++t>(n=e.length)){for(r=i,t-=n;--t;r+=i);e+=r}else ty?u.c=u.e=null:e.e=10;l/=10,a++);return void(a>y?u.c=u.e=null:(u.e=a,u.c=[e]))}d=String(e)}else{if(!We.test(d=String(e)))return r(u,d,c);u.s=45==d.charCodeAt(0)?(d=d.slice(1),-1):1}(a=d.indexOf("."))>-1&&(d=d.replace(".","")),(l=d.search(/e/i))>0?(a<0&&(a=l),a+=+d.slice(l+1),d=d.substring(0,l)):a<0&&(a=d.length)}else{if(rt(t,2,S.length,"Base"),10==t&&$)return D(u=new M(e),_+u.e+1,m);if(d=String(e),c="number"==typeof e){if(0*e!=0)return r(u,d,c,t);if(u.s=1/e<0?(d=d.slice(1),-1):1,M.DEBUG&&d.replace(/^0\.0*|\./,"").length>15)throw Error(Ke+e)}else u.s=45===d.charCodeAt(0)?(d=d.slice(1),-1):1;for(i=S.slice(0,t),a=l=0,h=d.length;la){a=h;continue}}else if(!s&&(d==d.toUpperCase()&&(d=d.toLowerCase())||d==d.toLowerCase()&&(d=d.toUpperCase()))){s=!0,l=-1,a=0;continue}return r(u,String(e),c,t)}c=!1,(a=(d=n(d,t,10,u.s)).indexOf("."))>-1?d=d.replace(".",""):a=d.length}for(l=0;48===d.charCodeAt(l);l++);for(h=d.length;48===d.charCodeAt(--h););if(d=d.slice(l,++h)){if(h-=l,c&&M.DEBUG&&h>15&&(e>Ze||e!==Ge(e)))throw Error(Ke+u.s*e);if((a=a-l-1)>y)u.c=u.e=null;else if(a=f)?st(l,s):at(l,s,"0");else if(o=(e=D(new M(e),t,i)).e,a=(l=it(e.c)).length,1==n||2==n&&(t<=o||o<=g)){for(;as),l=at(l,o,"0"),o+1>a){if(--t>0)for(l+=".";t--;l+="0");}else if((t+=o-a)>0)for(o+1==a&&(l+=".");t--;l+="0");return e.s<0&&r?"-"+l:l}function C(e,t){for(var i,n,r=1,o=new M(e[0]);r=10;r/=10,n++);return(i=n+i*Xe-1)>y?e.c=e.e=null:i=10;a/=10,r++);if((o=t-r)<0)o+=Xe,s=t,l=d[c=0],h=Ge(l/u[r-s-1]%10);else if((c=Ue((o+1)/Xe))>=d.length){if(!n)break e;for(;d.length<=c;d.push(0));l=h=0,r=1,s=(o%=Xe)-Xe+1}else{for(l=a=d[c],r=1;a>=10;a/=10,r++);h=(s=(o%=Xe)-Xe+r)<0?0:Ge(l/u[r-s-1]%10)}if(n=n||t<0||null!=d[c+1]||(s<0?l:l%u[r-s-1]),n=i<4?(h||n)&&(0==i||i==(e.s<0?3:2)):h>5||5==h&&(4==i||n||6==i&&(o>0?s>0?l/u[r-s]:0:d[c-1])%10&1||i==(e.s<0?8:7)),t<1||!d[0])return d.length=0,n?(t-=e.e+1,d[0]=u[(Xe-t%Xe)%Xe],e.e=-t||0):d[0]=e.e=0,e;if(0==o?(d.length=c,a=1,c--):(d.length=c+1,a=u[Xe-o],d[c]=s>0?Ge(l/u[r-s]%u[s])*a:0),n)for(;;){if(0==c){for(o=1,s=d[0];s>=10;s/=10,o++);for(s=d[0]+=a,a=1;s>=10;s/=10,a++);o!=a&&(e.e++,d[0]==Ye&&(d[0]=1));break}if(d[c]+=a,d[c]!=Ye)break;d[c--]=0,a=1}for(o=d.length;0===d[--o];d.pop());}e.e>y?e.c=e.e=null:e.e=f?st(t,i):at(t,i,"0"),e.s<0?"-"+t:t)}return M.clone=e,M.ROUND_UP=0,M.ROUND_DOWN=1,M.ROUND_CEIL=2,M.ROUND_FLOOR=3,M.ROUND_HALF_UP=4,M.ROUND_HALF_DOWN=5,M.ROUND_HALF_EVEN=6,M.ROUND_HALF_CEIL=7,M.ROUND_HALF_FLOOR=8,M.EUCLID=9,M.config=M.set=function(e){var t,i;if(null!=e){if("object"!=typeof e)throw Error(Ve+"Object expected: "+e);if(e.hasOwnProperty(t="DECIMAL_PLACES")&&(rt(i=e[t],0,et,t),_=i),e.hasOwnProperty(t="ROUNDING_MODE")&&(rt(i=e[t],0,8,t),m=i),e.hasOwnProperty(t="EXPONENTIAL_AT")&&((i=e[t])&&i.pop?(rt(i[0],-et,0,t),rt(i[1],0,et,t),g=i[0],f=i[1]):(rt(i,-et,et,t),g=-(f=i<0?-i:i))),e.hasOwnProperty(t="RANGE"))if((i=e[t])&&i.pop)rt(i[0],-et,-1,t),rt(i[1],1,et,t),v=i[0],y=i[1];else{if(rt(i,-et,et,t),!i)throw Error(Ve+t+" cannot be zero: "+i);v=-(y=i<0?-i:i)}if(e.hasOwnProperty(t="CRYPTO")){if((i=e[t])!==!!i)throw Error(Ve+t+" not true or false: "+i);if(i){if("undefined"==typeof crypto||!crypto||!crypto.getRandomValues&&!crypto.randomBytes)throw b=!i,Error(Ve+"crypto unavailable");b=i}else b=i}if(e.hasOwnProperty(t="MODULO_MODE")&&(rt(i=e[t],0,9,t),w=i),e.hasOwnProperty(t="POW_PRECISION")&&(rt(i=e[t],0,et,t),k=i),e.hasOwnProperty(t="FORMAT")){if("object"!=typeof(i=e[t]))throw Error(Ve+t+" not an object: "+i);x=i}if(e.hasOwnProperty(t="ALPHABET")){if("string"!=typeof(i=e[t])||/^.?$|[+\-.\s]|(.).*\1/.test(i))throw Error(Ve+t+" invalid: "+i);$="0123456789"==i.slice(0,10),S=i}}return{DECIMAL_PLACES:_,ROUNDING_MODE:m,EXPONENTIAL_AT:[g,f],RANGE:[v,y],CRYPTO:b,MODULO_MODE:w,POW_PRECISION:k,FORMAT:x,ALPHABET:S}},M.isBigNumber=function(e){if(!e||!0!==e._isBigNumber)return!1;if(!M.DEBUG)return!0;var t,i,n=e.c,r=e.e,o=e.s;e:if("[object Array]"=={}.toString.call(n)){if((1===o||-1===o)&&r>=-et&&r<=et&&r===Ge(r)){if(0===n[0]){if(0===r&&1===n.length)return!0;break e}if((t=(r+1)%Xe)<1&&(t+=Xe),String(n[0]).length==t){for(t=0;t=Ye||i!==Ge(i))break e;if(0!==i)return!0}}}else if(null===n&&null===r&&(null===o||1===o||-1===o))return!0;throw Error(Ve+"Invalid BigNumber: "+e)},M.maximum=M.max=function(){return C(arguments,-1)},M.minimum=M.min=function(){return C(arguments,1)},M.random=(o=9007199254740992,s=Math.random()*o&2097151?function(){return Ge(Math.random()*o)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)},function(e){var t,i,n,r,o,a=0,l=[],c=new M(p);if(null==e?e=_:rt(e,0,et),r=Ue(e/Xe),b)if(crypto.getRandomValues){for(t=crypto.getRandomValues(new Uint32Array(r*=2));a>>11))>=9e15?(i=crypto.getRandomValues(new Uint32Array(2)),t[a]=i[0],t[a+1]=i[1]):(l.push(o%1e14),a+=2);a=r/2}else{if(!crypto.randomBytes)throw b=!1,Error(Ve+"crypto unavailable");for(t=crypto.randomBytes(r*=7);a=9e15?crypto.randomBytes(7).copy(t,a):(l.push(o%1e14),a+=7);a=r/7}if(!b)for(;a=10;o/=10,a++);ai-1&&(null==s[r+1]&&(s[r+1]=0),s[r+1]+=s[r]/i|0,s[r]%=i)}return s.reverse()}return function(n,r,o,s,a){var l,c,h,d,u,p,g,f,v=n.indexOf("."),y=_,b=m;for(v>=0&&(d=k,k=0,n=n.replace(".",""),p=(f=new M(r)).pow(n.length-v),k=d,f.c=t(at(it(p.c),p.e,"0"),10,o,e),f.e=f.c.length),h=d=(g=t(n,r,o,a?(l=S,e):(l=e,S))).length;0==g[--d];g.pop());if(!g[0])return l.charAt(0);if(v<0?--h:(p.c=g,p.e=h,p.s=s,g=(p=i(p,f,y,b,o)).c,u=p.r,h=p.e),v=g[c=h+y+1],d=o/2,u=u||c<0||null!=g[c+1],u=b<4?(null!=v||u)&&(0==b||b==(p.s<0?3:2)):v>d||v==d&&(4==b||u||6==b&&1&g[c-1]||b==(p.s<0?8:7)),c<1||!g[0])n=u?at(l.charAt(1),-y,l.charAt(0)):l.charAt(0);else{if(g.length=c,u)for(--o;++g[--c]>o;)g[c]=0,c||(++h,g=[1].concat(g));for(d=g.length;!g[--d];);for(v=0,n="";v<=d;n+=l.charAt(g[v++]));n=at(n,h,l.charAt(0))}return n}}(),i=function(){function e(e,t,i){var n,r,o,s,a=0,l=e.length,c=t%Qe,h=t/Qe|0;for(e=e.slice();l--;)a=((r=c*(o=e[l]%Qe)+(n=h*o+(s=e[l]/Qe|0)*c)%Qe*Qe+a)/i|0)+(n/Qe|0)+h*s,e[l]=r%i;return a&&(e=[a].concat(e)),e}function t(e,t,i,n){var r,o;if(i!=n)o=i>n?1:-1;else for(r=o=0;rt[r]?1:-1;break}return o}function i(e,t,i,n){for(var r=0;i--;)e[i]-=r,r=e[i]1;e.splice(0,1));}return function(n,r,o,s,a){var l,c,h,d,u,p,_,m,g,f,v,y,b,w,k,x,S,$=n.s==r.s?1:-1,R=n.c,C=r.c;if(!(R&&R[0]&&C&&C[0]))return new M(n.s&&r.s&&(R?!C||R[0]!=C[0]:C)?R&&0==R[0]||!C?0*$:$/0:NaN);for(g=(m=new M($)).c=[],$=o+(c=n.e-r.e)+1,a||(a=Ye,c=tt(n.e/Xe)-tt(r.e/Xe),$=$/Xe|0),h=0;C[h]==(R[h]||0);h++);if(C[h]>(R[h]||0)&&c--,$<0)g.push(1),d=!0;else{for(w=R.length,x=C.length,h=0,$+=2,(u=Ge(a/(C[0]+1)))>1&&(C=e(C,u,a),R=e(R,u,a),x=C.length,w=R.length),b=x,v=(f=R.slice(0,x)).length;v=a/2&&k++;do{if(u=0,(l=t(C,f,x,v))<0){if(y=f[0],x!=v&&(y=y*a+(f[1]||0)),(u=Ge(y/k))>1)for(u>=a&&(u=a-1),_=(p=e(C,u,a)).length,v=f.length;1==t(p,f,_,v);)u--,i(p,x<_?S:C,_,a),_=p.length,l=1;else 0==u&&(l=u=1),_=(p=C.slice()).length;if(_=10;$/=10,h++);D(m,o+(m.e=h+c*Xe-1)+1,s,d)}else m.e=c,m.r=+d;return m}}(),a=/^(-?)0([xbo])(?=\w[\w.]*$)/i,l=/^([^.]+)\.$/,c=/^\.([^.]+)$/,h=/^-?(Infinity|NaN)$/,d=/^\s*\+(?=[\w.])|^\s+|\s+$/g,r=function(e,t,i,n){var r,o=i?t:t.replace(d,"");if(h.test(o))e.s=isNaN(o)?null:o<0?-1:1;else{if(!i&&(o=o.replace(a,function(e,t,i){return r="x"==(i=i.toLowerCase())?16:"b"==i?2:8,n&&n!=r?e:t}),n&&(r=n,o=o.replace(l,"$1").replace(c,"0.$1")),t!=o))return new M(o,r);if(M.DEBUG)throw Error(Ve+"Not a"+(n?" base "+n:"")+" number: "+t);e.s=null}e.c=e.e=null},u.absoluteValue=u.abs=function(){var e=new M(this);return e.s<0&&(e.s=1),e},u.comparedTo=function(e,t){return nt(this,new M(e,t))},u.decimalPlaces=u.dp=function(e,t){var i,n,r,o=this;if(null!=e)return rt(e,0,et),null==t?t=m:rt(t,0,8),D(new M(o),e+o.e+1,t);if(!(i=o.c))return null;if(n=((r=i.length-1)-tt(this.e/Xe))*Xe,r=i[r])for(;r%10==0;r/=10,n--);return n<0&&(n=0),n},u.dividedBy=u.div=function(e,t){return i(this,new M(e,t),_,m)},u.dividedToIntegerBy=u.idiv=function(e,t){return i(this,new M(e,t),0,1)},u.exponentiatedBy=u.pow=function(e,t){var i,n,r,o,s,a,l,c,h=this;if((e=new M(e)).c&&!e.isInteger())throw Error(Ve+"Exponent not an integer: "+A(e));if(null!=t&&(t=new M(t)),s=e.e>14,!h.c||!h.c[0]||1==h.c[0]&&!h.e&&1==h.c.length||!e.c||!e.c[0])return c=new M(Math.pow(+A(h),s?e.s*(2-ot(e)):+A(e))),t?c.mod(t):c;if(a=e.s<0,t){if(t.c?!t.c[0]:!t.s)return new M(NaN);(n=!a&&h.isInteger()&&t.isInteger())&&(h=h.mod(t))}else{if(e.e>9&&(h.e>0||h.e<-1||(0==h.e?h.c[0]>1||s&&h.c[1]>=24e7:h.c[0]<8e13||s&&h.c[0]<=9999975e7)))return o=h.s<0&&ot(e)?-0:0,h.e>-1&&(o=1/o),new M(a?1/o:o);k&&(o=Ue(k/Xe+2))}for(s?(i=new M(.5),a&&(e.s=1),l=ot(e)):l=(r=Math.abs(+A(e)))%2,c=new M(p);;){if(l){if(!(c=c.times(h)).c)break;o?c.c.length>o&&(c.c.length=o):n&&(c=c.mod(t))}if(r){if(0===(r=Ge(r/2)))break;l=r%2}else if(D(e=e.times(i),e.e+1,1),e.e>14)l=ot(e);else{if(0===(r=+A(e)))break;l=r%2}h=h.times(h),o?h.c&&h.c.length>o&&(h.c.length=o):n&&(h=h.mod(t))}return n?c:(a&&(c=p.div(c)),t?c.mod(t):o?D(c,k,m,void 0):c)},u.integerValue=function(e){var t=new M(this);return null==e?e=m:rt(e,0,8),D(t,t.e+1,e)},u.isEqualTo=u.eq=function(e,t){return 0===nt(this,new M(e,t))},u.isFinite=function(){return!!this.c},u.isGreaterThan=u.gt=function(e,t){return nt(this,new M(e,t))>0},u.isGreaterThanOrEqualTo=u.gte=function(e,t){return 1===(t=nt(this,new M(e,t)))||0===t},u.isInteger=function(){return!!this.c&&tt(this.e/Xe)>this.c.length-2},u.isLessThan=u.lt=function(e,t){return nt(this,new M(e,t))<0},u.isLessThanOrEqualTo=u.lte=function(e,t){return-1===(t=nt(this,new M(e,t)))||0===t},u.isNaN=function(){return!this.s},u.isNegative=function(){return this.s<0},u.isPositive=function(){return this.s>0},u.isZero=function(){return!!this.c&&0==this.c[0]},u.minus=function(e,t){var i,n,r,o,s=this,a=s.s;if(t=(e=new M(e,t)).s,!a||!t)return new M(NaN);if(a!=t)return e.s=-t,s.plus(e);var l=s.e/Xe,c=e.e/Xe,h=s.c,d=e.c;if(!l||!c){if(!h||!d)return h?(e.s=-t,e):new M(d?s:NaN);if(!h[0]||!d[0])return d[0]?(e.s=-t,e):new M(h[0]?s:3==m?-0:0)}if(l=tt(l),c=tt(c),h=h.slice(),a=l-c){for((o=a<0)?(a=-a,r=h):(c=l,r=d),r.reverse(),t=a;t--;r.push(0));r.reverse()}else for(n=(o=(a=h.length)<(t=d.length))?a:t,a=t=0;t0)for(;t--;h[i++]=0);for(t=Ye-1;n>a;){if(h[--n]=0;){for(i=0,u=y[r]%g,p=y[r]/g|0,o=r+(s=l);o>r;)i=((c=u*(c=v[--s]%g)+(a=p*c+(h=v[s]/g|0)*u)%g*g+_[o]+i)/m|0)+(a/g|0)+p*h,_[o--]=c%m;_[o]=i}return i?++n:_.splice(0,1),T(e,_,n)},u.negated=function(){var e=new M(this);return e.s=-e.s||null,e},u.plus=function(e,t){var i,n=this,r=n.s;if(t=(e=new M(e,t)).s,!r||!t)return new M(NaN);if(r!=t)return e.s=-t,n.minus(e);var o=n.e/Xe,s=e.e/Xe,a=n.c,l=e.c;if(!o||!s){if(!a||!l)return new M(r/0);if(!a[0]||!l[0])return l[0]?e:new M(a[0]?n:0*r)}if(o=tt(o),s=tt(s),a=a.slice(),r=o-s){for(r>0?(s=o,i=l):(r=-r,i=a),i.reverse();r--;i.push(0));i.reverse()}for((r=a.length)-(t=l.length)<0&&(i=l,l=a,a=i,t=r),r=0;t;)r=(a[--t]=a[t]+l[t]+r)/Ye|0,a[t]=Ye===a[t]?0:a[t]%Ye;return r&&(a=[r].concat(a),++s),T(e,a,s)},u.precision=u.sd=function(e,t){var i,n,r,o=this;if(null!=e&&e!==!!e)return rt(e,1,et),null==t?t=m:rt(t,0,8),D(new M(o),e,t);if(!(i=o.c))return null;if(n=(r=i.length-1)*Xe+1,r=i[r]){for(;r%10==0;r/=10,n--);for(r=i[0];r>=10;r/=10,n++);}return e&&o.e+1>n&&(n=o.e+1),n},u.shiftedBy=function(e){return rt(e,-9007199254740991,Ze),this.times("1e"+e)},u.squareRoot=u.sqrt=function(){var e,t,n,r,o,s=this,a=s.c,l=s.s,c=s.e,h=_+4,d=new M("0.5");if(1!==l||!a||!a[0])return new M(!l||l<0&&(!a||a[0])?NaN:a?s:1/0);if(0==(l=Math.sqrt(+A(s)))||l==1/0?(((t=it(a)).length+c)%2==0&&(t+="0"),l=Math.sqrt(+t),c=tt((c+1)/2)-(c<0||c%2),n=new M(t=l==1/0?"5e"+c:(t=l.toExponential()).slice(0,t.indexOf("e")+1)+c)):n=new M(l+""),n.c[0])for((l=(c=n.e)+h)<3&&(l=0);;)if(o=n,n=d.times(o.plus(i(s,o,h,1))),it(o.c).slice(0,l)===(t=it(n.c)).slice(0,l)){if(n.e0&&_>0){for(o=_%a||a,h=p.substr(0,o);o<_;o+=a)h+=c+p.substr(o,a);l>0&&(h+=c+p.slice(o)),u&&(h="-"+h)}n=d?h+(i.decimalSeparator||"")+((l=+i.fractionGroupSize)?d.replace(new RegExp("\\d{"+l+"}\\B","g"),"$&"+(i.fractionGroupSeparator||"")):d):h}return(i.prefix||"")+n+(i.suffix||"")},u.toFraction=function(e){var t,n,r,o,s,a,l,c,h,d,u,_,g=this,f=g.c;if(null!=e&&(!(l=new M(e)).isInteger()&&(l.c||1!==l.s)||l.lt(p)))throw Error(Ve+"Argument "+(l.isInteger()?"out of range: ":"not an integer: ")+A(l));if(!f)return new M(g);for(t=new M(p),h=n=new M(p),r=c=new M(p),_=it(f),s=t.e=_.length-g.e-1,t.c[0]=Je[(a=s%Xe)<0?Xe+a:a],e=!e||l.comparedTo(t)>0?s>0?t:h:l,a=y,y=1/0,l=new M(_),c.c[0]=0;d=i(l,t,0,1),1!=(o=n.plus(d.times(r))).comparedTo(e);)n=r,r=o,h=c.plus(d.times(o=h)),c=o,t=l.minus(d.times(o=t)),l=o;return o=i(e.minus(n),r,0,1),c=c.plus(o.times(h)),n=n.plus(o.times(r)),c.s=h.s=g.s,u=i(h,r,s*=2,m).minus(g).abs().comparedTo(i(c,n,s,m).minus(g).abs())<1?[h,r]:[c,n],y=a,u},u.toNumber=function(){return+A(this)},u.toPrecision=function(e,t){return null!=e&&rt(e,1,et),R(this,e,t,2)},u.toString=function(e){var t,i=this,r=i.s,o=i.e;return null===o?r?(t="Infinity",r<0&&(t="-"+t)):t="NaN":(null==e?t=o<=g||o>=f?st(it(i.c),o):at(it(i.c),o,"0"):10===e&&$?t=at(it((i=D(new M(i),_+o+1,m)).c),i.e,"0"):(rt(e,2,S.length,"Base"),t=n(at(it(i.c),o,"0"),10,e,r,!0)),r<0&&i.c[0]&&(t="-"+t)),t},u.valueOf=u.toJSON=function(){return A(this)},u._isBigNumber=!0,u[Symbol.toStringTag]="BigNumber",u[Symbol.for("nodejs.util.inspect.custom")]=u.valueOf,null!=t&&M.set(t),M}(),ct=class{key;left=null;right=null;constructor(e){this.key=e}},ht=class extends ct{constructor(e){super(e)}},dt=class{size=0;modificationCount=0;splayCount=0;splay(e){const t=this.root;if(null==t)return this.compare(e,e),-1;let i=null,n=null,r=null,o=null,s=t;const a=this.compare;let l;for(;;)if(l=a(s.key,e),l>0){let t=s.left;if(null==t)break;if(l=a(t.key,e),l>0&&(s.left=t.right,t.right=s,s=t,t=s.left,null==t))break;null==i?n=s:i.left=s,i=s,s=t}else{if(!(l<0))break;{let t=s.right;if(null==t)break;if(l=a(t.key,e),l<0&&(s.right=t.left,t.left=s,s=t,t=s.right,null==t))break;null==r?o=s:r.right=s,r=s,s=t}}return null!=r&&(r.right=s.left,s.left=o),null!=i&&(i.left=s.right,s.right=n),this.root!==s&&(this.root=s,this.splayCount++),l}splayMin(e){let t=e,i=t.left;for(;null!=i;){const e=i;t.left=e.right,e.right=t,t=e,i=t.left}return t}splayMax(e){let t=e,i=t.right;for(;null!=i;){const e=i;t.right=e.left,e.left=t,t=e,i=t.right}return t}_delete(e){if(null==this.root)return null;if(0!=this.splay(e))return null;let t=this.root;const i=t,n=t.left;if(this.size--,null==n)this.root=t.right;else{const e=t.right;t=this.splayMax(n),t.right=e,this.root=t}return this.modificationCount++,i}addNewRoot(e,t){this.size++,this.modificationCount++;const i=this.root;null!=i?(t<0?(e.left=i,e.right=i.right,i.right=null):(e.right=i,e.left=i.left,i.left=null),this.root=e):this.root=e}_first(){const e=this.root;return null==e?null:(this.root=this.splayMin(e),this.root)}_last(){const e=this.root;return null==e?null:(this.root=this.splayMax(e),this.root)}clear(){this.root=null,this.size=0,this.modificationCount++}has(e){return this.validKey(e)&&0==this.splay(e)}defaultCompare(){return(e,t)=>et?1:0}wrap(){return{getRoot:()=>this.root,setRoot:e=>{this.root=e},getSize:()=>this.size,getModificationCount:()=>this.modificationCount,getSplayCount:()=>this.splayCount,setSplayCount:e=>{this.splayCount=e},splay:e=>this.splay(e),has:e=>this.has(e)}}},ut=class e extends dt{root=null;compare;validKey;constructor(e,t){super(),this.compare=e??this.defaultCompare(),this.validKey=t??(e=>null!=e&&null!=e)}delete(e){return!!this.validKey(e)&&null!=this._delete(e)}deleteAll(e){for(const t of e)this.delete(t)}forEach(e){const t=this[Symbol.iterator]();let i;for(;i=t.next(),!i.done;)e(i.value,i.value,this)}add(e){const t=this.splay(e);return 0!=t&&this.addNewRoot(new ht(e),t),this}addAndReturn(e){const t=this.splay(e);return 0!=t&&this.addNewRoot(new ht(e),t),this.root.key}addAll(e){for(const t of e)this.add(t)}isEmpty(){return null==this.root}isNotEmpty(){return null!=this.root}single(){if(0==this.size)throw"Bad state: No element";if(this.size>1)throw"Bad state: Too many element";return this.root.key}first(){if(0==this.size)throw"Bad state: No element";return this._first().key}last(){if(0==this.size)throw"Bad state: No element";return this._last().key}lastBefore(e){if(null==e)throw"Invalid arguments(s)";if(null==this.root)return null;if(this.splay(e)<0)return this.root.key;let t=this.root.left;if(null==t)return null;let i=t.right;for(;null!=i;)t=i,i=t.right;return t.key}firstAfter(e){if(null==e)throw"Invalid arguments(s)";if(null==this.root)return null;if(this.splay(e)>0)return this.root.key;let t=this.root.right;if(null==t)return null;let i=t.left;for(;null!=i;)t=i,i=t.left;return t.key}retainAll(t){const i=new e(this.compare,this.validKey),n=this.modificationCount;for(const e of t){if(n!=this.modificationCount)throw"Concurrent modification during iteration.";this.validKey(e)&&0==this.splay(e)&&i.add(this.root.key)}i.size!=this.size&&(this.root=i.root,this.size=i.size,this.modificationCount++)}lookup(e){if(!this.validKey(e))return null;return 0!=this.splay(e)?null:this.root.key}intersection(t){const i=new e(this.compare,this.validKey);for(const e of this)t.has(e)&&i.add(e);return i}difference(t){const i=new e(this.compare,this.validKey);for(const e of this)t.has(e)||i.add(e);return i}union(e){const t=this.clone();return t.addAll(e),t}clone(){const t=new e(this.compare,this.validKey);return t.size=this.size,t.root=this.copyNode(this.root),t}copyNode(e){if(null==e)return null;const t=new ht(e.key);return function e(t,i){let n,r;do{if(n=t.left,r=t.right,null!=n){const t=new ht(n.key);i.left=t,e(n,t)}if(null!=r){const e=new ht(r.key);i.right=e,t=r,i=e}}while(null!=r)}(e,t),t}toSet(){return this.clone()}entries(){return new mt(this.wrap())}keys(){return this[Symbol.iterator]()}values(){return this[Symbol.iterator]()}[Symbol.iterator](){return new _t(this.wrap())}[Symbol.toStringTag]="[object Set]"},pt=class{tree;path=new Array;modificationCount=null;splayCount;constructor(e){this.tree=e,this.splayCount=e.getSplayCount()}[Symbol.iterator](){return this}next(){return this.moveNext()?{done:!1,value:this.current()}:{done:!0,value:null}}current(){if(!this.path.length)return null;const e=this.path[this.path.length-1];return this.getValue(e)}rebuildPath(e){this.path.splice(0,this.path.length),this.tree.splay(e),this.path.push(this.tree.getRoot()),this.splayCount=this.tree.getSplayCount()}findLeftMostDescendent(e){for(;null!=e;)this.path.push(e),e=e.left}moveNext(){if(this.modificationCount!=this.tree.getModificationCount()){if(null==this.modificationCount){this.modificationCount=this.tree.getModificationCount();let e=this.tree.getRoot();for(;null!=e;)this.path.push(e),e=e.left;return this.path.length>0}throw"Concurrent modification during iteration."}if(!this.path.length)return!1;this.splayCount!=this.tree.getSplayCount()&&this.rebuildPath(this.path[this.path.length-1].key);let e=this.path[this.path.length-1],t=e.right;if(null!=t){for(;null!=t;)this.path.push(t),t=t.left;return!0}for(this.path.pop();this.path.length&&this.path[this.path.length-1].right===e;)e=this.path.pop();return this.path.length>0}},_t=class extends pt{getValue(e){return e.key}},mt=class extends pt{getValue(e){return[e.key,e.key]}},gt=e=>()=>e,ft=e=>{const t=e?(t,i)=>i.minus(t).abs().isLessThanOrEqualTo(e):gt(!1);return(e,i)=>t(e,i)?0:e.comparedTo(i)};function vt(e){const t=e?(t,i,n,r,o)=>t.exponentiatedBy(2).isLessThanOrEqualTo(r.minus(i).exponentiatedBy(2).plus(o.minus(n).exponentiatedBy(2)).times(e)):gt(!1);return(e,i,n)=>{const r=e.x,o=e.y,s=n.x,a=n.y,l=o.minus(a).times(i.x.minus(s)).minus(r.minus(s).times(i.y.minus(a)));return t(l,r,o,s,a)?0:l.comparedTo(0)}}var yt=e=>e,bt=e=>{if(e){const t=new ut(ft(e)),i=new ut(ft(e)),n=(e,t)=>t.addAndReturn(e),r=e=>({x:n(e.x,t),y:n(e.y,i)});return r({x:new lt(0),y:new lt(0)}),r}return yt},wt=e=>({set:e=>{kt=wt(e)},reset:()=>wt(e),compare:ft(e),snap:bt(e),orient:vt(e)}),kt=wt(),xt=(e,t)=>e.ll.x.isLessThanOrEqualTo(t.x)&&t.x.isLessThanOrEqualTo(e.ur.x)&&e.ll.y.isLessThanOrEqualTo(t.y)&&t.y.isLessThanOrEqualTo(e.ur.y),St=(e,t)=>{if(t.ur.x.isLessThan(e.ll.x)||e.ur.x.isLessThan(t.ll.x)||t.ur.y.isLessThan(e.ll.y)||e.ur.y.isLessThan(t.ll.y))return null;const i=e.ll.x.isLessThan(t.ll.x)?t.ll.x:e.ll.x,n=e.ur.x.isLessThan(t.ur.x)?e.ur.x:t.ur.x;return{ll:{x:i,y:e.ll.y.isLessThan(t.ll.y)?t.ll.y:e.ll.y},ur:{x:n,y:e.ur.y.isLessThan(t.ur.y)?e.ur.y:t.ur.y}}},$t=(e,t)=>e.x.times(t.y).minus(e.y.times(t.x)),Mt=(e,t)=>e.x.times(t.x).plus(e.y.times(t.y)),Rt=e=>Mt(e,e).sqrt(),Ct=(e,t,i)=>{const n={x:t.x.minus(e.x),y:t.y.minus(e.y)},r={x:i.x.minus(e.x),y:i.y.minus(e.y)};return $t(r,n).div(Rt(r)).div(Rt(n))},Tt=(e,t,i)=>{const n={x:t.x.minus(e.x),y:t.y.minus(e.y)},r={x:i.x.minus(e.x),y:i.y.minus(e.y)};return Mt(r,n).div(Rt(r)).div(Rt(n))},Dt=(e,t,i)=>t.y.isZero()?null:{x:e.x.plus(t.x.div(t.y).times(i.minus(e.y))),y:i},At=(e,t,i)=>t.x.isZero()?null:{x:i,y:e.y.plus(t.y.div(t.x).times(i.minus(e.x)))},Pt=class e{point;isLeft;segment;otherSE;consumedBy;static compare(t,i){const n=e.comparePoints(t.point,i.point);return 0!==n?n:(t.point!==i.point&&t.link(i),t.isLeft!==i.isLeft?t.isLeft?1:-1:Lt.compare(t.segment,i.segment))}static comparePoints(e,t){return e.x.isLessThan(t.x)?-1:e.x.isGreaterThan(t.x)?1:e.y.isLessThan(t.y)?-1:e.y.isGreaterThan(t.y)?1:0}constructor(e,t){void 0===e.events?e.events=[this]:e.events.push(this),this.point=e,this.isLeft=t}link(e){if(e.point===this.point)throw new Error("Tried to link already linked events");const t=e.point.events;for(let e=0,i=t.length;e{const n=i.otherSE;t.set(i,{sine:Ct(this.point,e.point,n.point),cosine:Tt(this.point,e.point,n.point)})};return(e,n)=>{t.has(e)||i(e),t.has(n)||i(n);const{sine:r,cosine:o}=t.get(e),{sine:s,cosine:a}=t.get(n);return r.isGreaterThanOrEqualTo(0)&&s.isGreaterThanOrEqualTo(0)?o.isLessThan(a)?1:o.isGreaterThan(a)?-1:0:r.isLessThan(0)&&s.isLessThan(0)?o.isLessThan(a)?-1:o.isGreaterThan(a)?1:0:s.isLessThan(r)?-1:s.isGreaterThan(r)?1:0}}},Ft=class e{events;poly;_isExteriorRing;_enclosingRing;static factory(t){const i=[];for(let n=0,r=t.length;n0&&(e=i)}let t=e.segment.prevInResult(),i=t?t.prevInResult():null;for(;;){if(!t)return null;if(!i)return t.ringOut;if(i.ringOut!==t.ringOut)return i.ringOut?.enclosingRing()!==t.ringOut?t.ringOut:t.ringOut?.enclosingRing();t=i.prevInResult(),i=t?t.prevInResult():null}}},zt=class{exteriorRing;interiorRings;constructor(e){this.exteriorRing=e,e.poly=this,this.interiorRings=[]}addInterior(e){this.interiorRings.push(e),e.poly=this}getGeom(){const e=this.exteriorRing.getGeom();if(null===e)return null;const t=[e];for(let e=0,i=this.interiorRings.length;e0?(this.tree.delete(t),i.push(e)):(this.segments.push(t),t.prev=n)}else{if(n&&r){const e=n.getIntersection(r);if(null!==e){if(!n.isAnEndpoint(e)){const t=this._splitSafely(n,e);for(let e=0,n=t.length;e0)return-1;const n=t.comparePoint(e.rightSE.point);return 0!==n?n:-1}if(i.isGreaterThan(n)){if(s.isLessThan(a)&&s.isLessThan(c))return-1;if(s.isGreaterThan(a)&&s.isGreaterThan(c))return 1;const i=t.comparePoint(e.leftSE.point);if(0!==i)return i;const n=e.comparePoint(t.rightSE.point);return n<0?1:n>0?-1:1}if(s.isLessThan(a))return-1;if(s.isGreaterThan(a))return 1;if(r.isLessThan(o)){const i=t.comparePoint(e.rightSE.point);if(0!==i)return i}if(r.isGreaterThan(o)){const i=e.comparePoint(t.rightSE.point);if(i<0)return 1;if(i>0)return-1}if(!r.eq(o)){const e=l.minus(s),t=r.minus(i),h=c.minus(a),d=o.minus(n);if(e.isGreaterThan(t)&&h.isLessThan(d))return 1;if(e.isLessThan(t)&&h.isGreaterThan(d))return-1}return r.isGreaterThan(o)?1:r.isLessThan(o)||l.isLessThan(c)?-1:l.isGreaterThan(c)?1:e.idt.id?1:0}constructor(e,t,i,n){this.id=++Ht,this.leftSE=e,e.segment=this,e.otherSE=t,this.rightSE=t,t.segment=this,t.otherSE=e,this.rings=i,this.windings=n}static fromRing(t,i,n){let r,o,s;const a=Pt.comparePoints(t,i);if(a<0)r=t,o=i,s=1;else{if(!(a>0))throw new Error(`Tried to create degenerate segment at [${t.x}, ${t.y}]`);r=i,o=t,s=-1}const l=new Pt(r,!0),c=new Pt(o,!1);return new e(l,c,[n],[s])}replaceRightSE(e){this.rightSE=e,this.rightSE.segment=this,this.rightSE.otherSE=this.leftSE,this.leftSE.otherSE=this.rightSE}bbox(){const e=this.leftSE.point.y,t=this.rightSE.point.y;return{ll:{x:this.leftSE.point.x,y:e.isLessThan(t)?e:t},ur:{x:this.rightSE.point.x,y:e.isGreaterThan(t)?e:t}}}vector(){return{x:this.rightSE.point.x.minus(this.leftSE.point.x),y:this.rightSE.point.y.minus(this.leftSE.point.y)}}isAnEndpoint(e){return e.x.eq(this.leftSE.point.x)&&e.y.eq(this.leftSE.point.y)||e.x.eq(this.rightSE.point.x)&&e.y.eq(this.rightSE.point.y)}comparePoint(e){return kt.orient(this.leftSE.point,e,this.rightSE.point)}getIntersection(e){const t=this.bbox(),i=e.bbox(),n=St(t,i);if(null===n)return null;const r=this.leftSE.point,o=this.rightSE.point,s=e.leftSE.point,a=e.rightSE.point,l=xt(t,s)&&0===this.comparePoint(s),c=xt(i,r)&&0===e.comparePoint(r),h=xt(t,a)&&0===this.comparePoint(a),d=xt(i,o)&&0===e.comparePoint(o);if(c&&l)return d&&!h?o:!d&&h?a:null;if(c)return h&&r.x.eq(a.x)&&r.y.eq(a.y)?null:r;if(l)return d&&o.x.eq(s.x)&&o.y.eq(s.y)?null:s;if(d&&h)return null;if(d)return o;if(h)return a;const u=((e,t,i,n)=>{if(t.x.isZero())return At(i,n,e.x);if(n.x.isZero())return At(e,t,i.x);if(t.y.isZero())return Dt(i,n,e.y);if(n.y.isZero())return Dt(e,t,i.y);const r=$t(t,n);if(r.isZero())return null;const o={x:i.x.minus(e.x),y:i.y.minus(e.y)},s=$t(o,t).div(r),a=$t(o,n).div(r),l=e.x.plus(a.times(t.x)),c=i.x.plus(s.times(n.x)),h=e.y.plus(a.times(t.y)),d=i.y.plus(s.times(n.y));return{x:l.plus(c).div(2),y:h.plus(d).div(2)}})(r,this.vector(),s,e.vector());return null===u?null:xt(n,u)?kt.snap(u):null}split(t){const i=[],n=void 0!==t.events,r=new Pt(t,!0),o=new Pt(t,!1),s=this.rightSE;this.replaceRightSE(o),i.push(o),i.push(r);const a=new e(r,s,this.rings.slice(),this.windings.slice());return Pt.comparePoints(a.leftSE.point,a.rightSE.point)>0&&a.swapEvents(),Pt.comparePoints(this.leftSE.point,this.rightSE.point)>0&&this.swapEvents(),n&&(r.checkForConsuming(),o.checkForConsuming()),i}swapEvents(){const e=this.rightSE;this.rightSE=this.leftSE,this.leftSE=e,this.leftSE.isLeft=!0,this.rightSE.isLeft=!1;for(let e=0,t=this.windings.length;e0){const e=i;i=n,n=e}if(i.prev===n){const e=i;i=n,n=e}for(let e=0,t=n.rings.length;e1===e.length&&e[0].isSubject;this._isInResult=i(e)!==i(t);break}}return this._isInResult}},Bt=class{poly;isExterior;segments;bbox;constructor(e,t,i){if(!Array.isArray(e)||0===e.length)throw new Error("Input geometry is not a valid Polygon or MultiPolygon");if(this.poly=t,this.isExterior=i,this.segments=[],"number"!=typeof e[0][0]||"number"!=typeof e[0][1])throw new Error("Input geometry is not a valid Polygon or MultiPolygon");const n=kt.snap({x:new lt(e[0][0]),y:new lt(e[0][1])});this.bbox={ll:{x:n.x,y:n.y},ur:{x:n.x,y:n.y}};let r=n;for(let t=1,i=e.length;tNt.run("union",e,t),Ut=(e,...t)=>Nt.run("intersection",e,t),Gt=(e,...t)=>Nt.run("difference",e,t);kt.set;const Vt=/^#[0-9a-fA-F]{6}$/;function Kt(e,t){return"string"==typeof e&&Vt.test(e)?e:t}const Yt="(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])",Xt=new RegExp(`^rgb\\(${Yt}, ${Yt}, ${Yt}\\)$`);function Zt(e){if(!Array.isArray(e)||e.length<3)return null;const t=e.slice(0,3);if(!t.every(e=>"number"==typeof e&&Number.isFinite(e)))return null;const[i,n,r]=t.map(e=>Math.round(Math.min(255,Math.max(0,e))));return`rgb(${i}, ${n}, ${r})`}function Jt(e){const t=Math.max(0,Math.min(120,(e-40)/140*120));return`hsl(${Math.round(t)}, 85%, 55%)`}function Qt(e,t){if(!(Number.isFinite(e)&&t>0))return e;const i=Math.round(e/t)*t;return Math.abs(i-e)<=1e-9*t?e:i}function ei(e,t,i,n=1/0){if(!(i>0&&e?.every(Number.isFinite)&&t?.every(Number.isFinite)))return[t[0],t[1]];const r=t[0]-e[0],o=t[1]-e[1];if(Math.abs(r)+Math.abs(o)<=1e-12)return[e[0],e[1]];const s=Math.PI/4;let a=Math.atan2(o,r);a<0&&(a+=2*Math.PI);const l=Math.floor(a/s+.5)%8,[c,h]=[[1,0],[1,1],[0,1],[-1,1],[-1,0],[-1,-1],[0,-1],[1,-1]][l],d=c*c+h*h;let u=Math.max(0,Math.round((r*c+o*h)/(i*d)));if(Number.isFinite(n)&&n>=0){const t=(e,t)=>{if(!t)return 1/0;const r=t>0?n-e:e+n;return Math.max(0,Math.floor((r+1e-9*i)/i))};u=Math.min(u,t(e[0],c),t(e[1],h))}return[e[0]+c*u*i,e[1]+h*u*i]}function ti(e,t){if(t){const t=e/2.54;let i=Math.floor(t/12),n=Math.round(t-12*i);return 12===n&&(i+=1,n=0),`${i}′ ${n}″`}return`${(e/100).toFixed(2)} m`}function ii(e,t,i=1){const n=e[0].toFixed(i),r=e[1].toFixed(i),o=t[0].toFixed(i),s=t[1].toFixed(i),a=n=3?e.poly:e&&null!=e.x&&null!=e.y&&null!=e.w&&null!=e.h?[[e.x,e.y],[e.x+e.w,e.y],[e.x+e.w,e.y+e.h],[e.x,e.y+e.h]]:null}function ri(e){const t=[];for(const i of e||[])i?.poly?.length>=3?t.push({poly:i.poly.map(e=>e.join(",")).join(" ")}):i&&null!=i.x&&null!=i.y&&null!=i.w&&null!=i.h&&t.push({rect:{x:i.x,y:i.y,w:i.w,h:i.h,rx:.03*Math.min(i.w,i.h)}});return t}function oi(e){const t=[],i=new Set;for(const n of e||[]){const e=ni(n);if(e)for(let n=0;n=90?e-=180:e<-90&&(e+=180),n.step&&n.step>0){const i=Math.sqrt(d),o=Math.min(Math.max(n.length||0,0)/2,i/2);let a=Math.round(u*i/n.step)*n.step;Math.abs(u*i-i/2)<=n.step/2&&(a=i/2),a=Math.max(o,Math.min(i-o,a));const l=a/i;r={x:t+l*c,y:s+l*h,angle:e}}else r={x:p[0],y:p[1],angle:e}}}return r}function ai(e,t,i){let n=null,r=1/0;for(let o=0;o=r)continue;r=_;const m=Math.sqrt(u),g=(i>0?Math.max(0,Math.min(m,Math.round(p*m/i)*i)):p*m)/m;n=[s+g*h,a+g*d]}return n}function li(e,t,i,n,r,o=1){const s=t*Math.PI/180,a=[Math.cos(s),Math.sin(s)];let l=null,c=o;for(const t of oi(n)){const i=[[t[0],t[1]],[t[2],t[3]]],n=t=>Math.abs(a[0]*(t[1]-e[1])-a[1]*(t[0]-e[0]));if(n(i[0])>o||n(i[1])>o)continue;const r=(i[0][0]-e[0])*a[0]+(i[0][1]-e[1])*a[1],s=(i[1][0]-e[0])*a[0]+(i[1][1]-e[1])*a[1],h=Math.min(r,s),d=Math.max(r,s),u=h>0?h:d<0?-d:0;u[e[0]+a[0]*t,e[1]+a[1]*t],g=(h+d)/2;return{wallA:m(h),wallB:m(d),sideA:p,sideB:_,midA:m((h-u)/2),midB:m((u+d)/2),wallCenter:m(g),centered:Math.abs(g)<=r}}function ci(e,t,i=!1,n){if("passage"===e)return 1;if(null==t||"unavailable"===t||"unknown"===t)return"window"===e?0:1;const r="string"==typeof n?n.trim()?Number(n):NaN:Number(n),o=null!=n&&Number.isFinite(r)?Math.max(0,Math.min(1,r/100)):function(e){return["on","open","home","detected","playing","cleaning"].includes(String(e))}(t)?1:0;return i?1-o:o}function hi(e){const t=Number.isFinite(e)?Math.max(0,Math.min(1,e)):0;return Math.min(1,Math.max(0,.05*Math.round(t/.05)))}function di(e,t){return(Number.isFinite(e)&&e>0?e:0)*(Number.isFinite(t)?Math.max(0,Math.min(1,t)):0)}function ui(e){return"passage"===e.type?[]:[e.contact,e.lock].filter(e=>"string"==typeof e&&e.length>0)}function pi(e,t,i=200){const n=t.trim().toLowerCase();return(n?e.filter(e=>e.label.toLowerCase().includes(n)||e.value.toLowerCase().includes(n)):e).slice(0,Math.max(0,i))}function _i(e,t,i=.001){return Math.abs(e[0]-t[0])e[1]!=l>e[1]&&e[0]<(a-o)*(e[1]-s)/(l-s)+o&&(i=!i)}return i}function gi(e,t,i){const n=i[0]-t[0],r=i[1]-t[1],o=n*n+r*r;let s=o?((e[0]-t[0])*n+(e[1]-t[1])*r)/o:0;return s=Math.max(0,Math.min(1,s)),Math.hypot(e[0]-(t[0]+s*n),e[1]-(t[1]+s*r))}function fi(e,t){if(!t||t.length<2)return null;let i=null,n=1/0;for(let r=0;rr&&s<-r||o<-r&&s>r)&&(a>r&&l<-r||a<-r&&l>r)}function ki(e,t=24){const i=e.map(e=>e[0]),n=e.map(e=>e[1]),r=Math.min(...i),o=Math.max(...i),s=Math.min(...n),a=Math.max(...n),l=Math.max(o-r,a-s)||1;let c=0,h=0,d=0;for(let t=0;t1e-9?[h/(3*c),d/(3*c)]:[(r+o)/2,(s+a)/2],p=(t,i)=>{const n=((t,i)=>{if(!mi([t,i],e))return-1/0;let n=1/0;for(let r=0;rm&&(m=c,_=[n,l])}if(_){const[e,i]=_,n=(o-r)/t,l=(a-s)/t;for(let t=-4;t<=4;t++)for(let r=-4;r<=4;r++){const o=e+n*t/4,s=i+l*r/4,a=p(o,s);a>m&&(m=a,_=[o,s])}}return _||xi(e)||e[0]}function xi(e,t=1e-6){if(!e||e.length<3)return null;const i=e.length,n=[e.reduce((e,t)=>e+t[0],0)/i,e.reduce((e,t)=>e+t[1],0)/i];if(yi(n,e,t))return n;for(let n=0;n$i(e,t,i));return n.filter(e=>!n.some(t=>t!==e&&$i(t,e,i)))}function Ci(e){if(!e||e.length<3)return 0;let t=0;for(let i=0;i[e[0],e[1]]),[e[0][0],e[0][1]]]]}function Di(e,t){if(!e||!t||e.length<3||t.length<3)return null;const i=Wt(Ti(e),Ti(t));if(1!==i.length)return null;if(1!==i[0].length)return null;const n=i[0][0].slice(0,-1).map(e=>[e[0],e[1]]);return n.length>=3?n:null}function Ai(e,t,i){for(let n=0;n1&&_i(i[0],i[i.length-1],t)&&i.pop(),i}function Fi(e,t,i=1e-6){if(!e||e.length<3||!t||t.length<2)return null;const n=t[0],r=t[t.length-1];if(_i(n,r,i))return null;const o=Ai(e,n,i),s=Ai(e,r,i);if(o<0||s<0)return null;const a=t.slice(1,-1);for(const t of a)if(!yi(t,e,i))return null;for(let i=0;i{const s=[t];let a=(n+1)%e.length;for(let t=0;t<=e.length&&(s.push(e[a]),a!==o);t++)a=(a+1)%e.length;return s.push(r),Pi(s,i)};let c,h;if(o===s){const s=Pi([...t],i);if(s.length<3||Ci(s)<=i)return null;const a=[];for(let i=0;i=0?t:[...t].reverse();for(const e of i)a.push(e)}c=Pi(a,i),h=s}else c=Pi([...l(n,o,r,s),...[...a].reverse()],i),h=Pi([...l(r,s,n,o),...a],i);return c.length<3||h.length<3||Ci(c)<=i||Ci(h)<=i||Math.abs(Ci(c)+Ci(h)-Ci(e))>Math.max(i,1e-6*Ci(e))?null:[c,h]}function zi(e,t,i){const[n,r]=e.split(":");return"device"===n?r:"entity"===n?"lg_"+r:t&&t.startsWith("v_")?t:i()}function Ii(e){return e.length?Math.round(e.reduce((e,t)=>e+t,0)/e.length):null}function Oi(e,t){if(t>e[2]/e[3]){const i=e[3],n=e[3]*t;return{x:e[0]-(n-e[2])/2,y:e[1],w:n,h:i}}const i=e[2],n=e[2]/t;return{x:e[0],y:e[1]-(n-e[3])/2,w:i,h:n}}function Ei(e,t,i,n){if(e.length<2)return;const r=t.x+n,o=t.x+t.w-n,s=t.y+n,a=t.y+t.h-n;for(let t=0;t<60;t++){let t=!1;for(let n=0;n=0)i=t.slice(0,r).trim(),n=t.slice(r+1).trim();else{const e=t.split(".");e.length>2&&(i=e.slice(0,2).join("."),n=e.slice(2).join("."))}return/^[a-z0-9_]+\.[a-z0-9_]+$/.test(i)?r>=0&&!n||n&&!/^[a-zA-Z0-9_.-]+$/.test(n)?null:n?{entity:i,attr:n}:{entity:i}:null}function Yi(e,t){const i=String(e??"").trim(),n=String(t??"").trim(),r=Ki(n?`${i}:${n}`:i);return r?`{${r.entity}${r.attr?`:${r.attr}`:""}}`:""}function Xi(e,t,i){const n=String(t??"").trim();if(!n)return null;const r=e?.states?.[n];if(!r)return null;const o=String(i??"").trim(),s=e=>e.slice(0,60);if(o){const t=function(e){if(null==e)return null;if(Array.isArray(e)){const t=e.map(e=>null==e?"":String(e)).join(", ");return t?t.slice(0,60):null}if("object"==typeof e)return null;const t=String(e);return""===t?null:t.slice(0,60)}(r.attributes?.[o]);if(null===t)return null;const i=e?.formatEntityAttributeValue;if("function"==typeof i)try{const t=i.call(e,r,o);if("string"==typeof t&&""!==t)return{text:s(t),formatted:!0}}catch{}return{text:t,formatted:!1}}const a=r.state;if(null==a||""===a)return null;const l=e?.formatEntityState;if("function"==typeof l)try{const t=l.call(e,r);if("string"==typeof t&&""!==t)return{text:s(t),formatted:!0}}catch{}return{text:s(String(a)),formatted:!1}}function Zi(e,t,i){const n=String(t??"").trim(),r=String(i??"").trim()||n;if(!r)return e.text;const o=e.formatted&&n?function(e,t){if(!t)return e;const i=e.replace(/\s+$/,"");return i.endsWith(t)?i.slice(0,i.length-t.length).replace(/\s+$/,""):e}(e.text,n):e.text;return`${o} ${r}`}function Ji(e,t){const i=(t?.entity||"").trim();if(!i)return"";const n=e?.states?.[i],r=n?.state;if(!n||null==r||""===r||"unavailable"===r||"unknown"===r)return Gi;const o=(t?.attr||"").trim(),s=Xi(e,i,o||null);if(null===s)return Gi;return Zi(s,o?"":String(n.attributes?.unit_of_measurement??"").trim(),t?.unit)}function Qi(e,t,i,n=()=>!0){const r=e??"";let o=!1;const s=r.replace(/\{([^{}\r\n]+)\}/g,(e,t)=>{const r=Ki(t);return r?(o=!0,n(r.entity||"")?Ji(i,r):Gi):e});if(o)return s;const a=(t?.entity||"").trim();if(!a)return r;if(!n(a)){const e=r.indexOf(Vi);return e>=0?r.slice(0,e)+Gi+r.slice(e+2):r?`${r} ${Gi}`:Gi}const l=Ji(i,t),c=r.indexOf(Vi);return c>=0?r.slice(0,c)+l+r.slice(c+2):r?`${r} ${l}`:l}const en=20;function tn(e){const t=Number(e?.scale);if(Number.isFinite(t)&&t>0)return Math.min(20,Math.max(.15,t));return{s:.7,m:1,l:1.5}[String(e?.size??"")]??1}function nn(e,t){if(!t)return e;let i=e;for(const[e,n]of Object.entries(t))i=i.split("{"+e+"}").join(String(n));return i}const rn="#55606c",on=.55,sn=20,an=25,ln={c:"#607d8b",a:.18};function cn(e,t=ln){const i=e&&"object"==typeof e?e:null,n=i?.a;return{c:Kt(i?.c,t.c),a:"number"==typeof n&&Number.isFinite(n)?Math.min(1,Math.max(0,n)):t.a}}function hn(e,t){const i=cn(e),n=t?.settings?.custom_fill;return n&&"object"==typeof n?cn(n,i):i}function dn(e,t,i){const n=(e,t)=>"number"==typeof e&&Number.isFinite(e)?e:t,r=n(e,20),o=n(t,25),s=n(i?.settings?.temp_min,r),a=n(i?.settings?.temp_max,o);return{min:Math.min(s,a),max:Math.max(s,a)}}function un(e){const t=e?.settings||{},i=!e?.plan_url,n="glow"===t.fill_mode;return{showBorders:t.show_borders??i,showNames:t.show_names??i,color:Kt(t.room_color,rn),opacity:"number"==typeof t.room_opacity?Math.min(1,Math.max(0,t.room_opacity)):.55,fill:["lqi","light","temp","custom"].includes(t.fill_mode)?t.fill_mode:"none",customFill:cn(t.custom_fill),glow:"boolean"==typeof t.glow_enabled?t.glow_enabled:n,tempMin:"number"==typeof t.temp_min?t.temp_min:20,tempMax:"number"==typeof t.temp_max?t.temp_max:25,showLqi:"boolean"==typeof t.show_lqi?t.show_lqi:null,cardFontScale:"number"==typeof t.card_font_scale&&t.card_font_scale>0?Math.min(3,Math.max(.5,t.card_font_scale)):1,labelTemp:!0===t.label_temp,labelHum:!0===t.label_hum,labelLqi:!0===t.label_lqi,labelLight:!0===t.label_light,bgColor:Kt(t.bg_color,null),hideDecor:!0===t.hide_decor,hideOpenings:!0===t.hide_openings}}function pn(e,t){if(t.bgColor)return t.bgColor;const i=e?.bg_color;return Kt(i,"")}function _n(e){return!1!==e?.show_room_tooltip}const mn={light_on:{c:"#ffd45c",a:.18},light_off:{c:"#9aa0a6",a:.14},light_none:{c:"#6b7480",a:0},temp_cold:{c:"#4fc3f7",a:.18},temp_ok:{c:"#66d17a",a:.18},temp_hot:{c:"#ffd45c",a:.18},lqi_low:{c:"#f25a4a",a:.18},lqi_high:{c:"#4bd28f",a:.18},glow_base:{c:"#0d1b2a",a:.5},glow_light:{c:"#ffd9a0",a:.85},wall_fill:{c:"#ffffff",a:1}};function gn(e){const t={},i=e?.fill_colors||{};for(const e of Object.keys(mn)){const n=mn[e],r=i[e];t[e]={c:Kt(r?.c,n.c),a:r&&"number"==typeof r.a?Math.min(1,Math.max(0,r.a)):n.a}}return t}function fn(e,t,i){const n=Math.min(1,Math.max(0,i)),r=[1,3,5].map(t=>parseInt(e.slice(t,t+2),16)),o=[1,3,5].map(e=>parseInt(t.slice(e,e+2),16)),s=r.map((e,t)=>Math.round(e+(o[t]-e)*n));return"#"+s.map(e=>e.toString(16).padStart(2,"0")).join("")}function vn(e,t,i,n,r,o,s,a=ln){const l=function(e,t,i,n,r,o,s,a=ln){if("custom"===e)return cn(a);if("lqi"===e){if(null==t)return null;const e=(t-40)/140;return{c:fn(s.lqi_low.c,s.lqi_high.c,e),a:s.lqi_low.a+(s.lqi_high.a-s.lqi_low.a)*Math.min(1,Math.max(0,e))}}if("light"===e)return"none"===i?s.light_none.a>0?s.light_none:null:"on"===i?s.light_on:s.light_off;if("temp"===e){if(null==n)return null;const e=Math.min(r,o),t=Math.max(r,o);return nt?s.temp_hot:s.temp_ok}return null}(e,t,i,n,r,o,s,a);return l?{color:l.c,opacity:l.a,mode:e}:null}const yn={blind:["mdi:blinds","mdi:blinds-open"],shade:["mdi:blinds","mdi:blinds-open"],shutter:["mdi:window-shutter","mdi:window-shutter-open"],curtain:["mdi:curtains-closed","mdi:curtains"],window:["mdi:window-closed","mdi:window-open"],awning:["mdi:awning-outline","mdi:awning"],door:["mdi:door-closed","mdi:door-open"],garage:["mdi:garage","mdi:garage-open"],gate:["mdi:gate","mdi:gate-open"],damper:["mdi:circle-slice-8","mdi:circle-outline"]},bn=[["mdi:roller-shade-closed","mdi:roller-shade"],["mdi:blinds-horizontal-closed","mdi:blinds-horizontal"],["mdi:garage-variant","mdi:garage-open-variant"],["mdi:door","mdi:door-open"]];function wn(e){for(const t of[...Object.values(yn),...bn])if(e===t[0]||e===t[1])return t;return null}function kn(e,t,i,n,r){if(!n||"unavailable"===n||"unknown"===n)return e;if(r){const i="cover"===t?wn(e):null;return i?"closed"===n?i[0]:i[1]:e}if("binary_sensor"===t){if("door"===i)return"on"===n?"mdi:door-open":"mdi:door-closed";if("window"===i)return"on"===n?"mdi:window-open":"mdi:window-closed";if("garage_door"===i)return"on"===n?"mdi:garage-open-variant":"mdi:garage-variant"}if("cover"===t){const t=yn[String(i||"")];if(t)return"closed"===n?t[0]:t[1];const r=wn(e);return r?"closed"===n?r[0]:r[1]:e}return"lock"===t?"locked"===n?"mdi:lock":"mdi:lock-open-variant":"light"===t&&"mdi:lightbulb"===e&&"on"===n?"mdi:lightbulb-on":e}function xn(e){const t=Math.min(4e4,Math.max(1e3,e))/100,i=t<=66?255:329.698727446*Math.pow(t-60,-.1332047592),n=t<=66?99.4708025861*Math.log(t)-161.1195681661:288.1221695283*Math.pow(t-60,-.0755148492),r=t>=66?255:t<=19?0:138.5177312231*Math.log(t-10)-305.0447927307,o=e=>Math.round(Math.min(255,Math.max(0,e)));return[o(i),o(n),o(r)]}const Sn=1/2.2;function $n(e){const t=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/.exec(e);return t?"#"+t.slice(1).map(e=>Math.min(255,Number(e)).toString(16).padStart(2,"0")).join(""):null}function Mn(e){if(!e||"object"!=typeof e||Array.isArray(e))return null;const t=e;if(Object.keys(t).some(e=>"c"!==e&&"bri"!==e))return null;const i=Kt(t.c,null);return i?void 0===t.bri||null===t.bri?{c:i}:"number"!=typeof t.bri||!Number.isFinite(t.bri)||t.bri<.01||t.bri>1?null:{c:i,bri:t.bri}:null}function Rn(e,t,i){const n=Mn(t),r=e?.attributes||{},o=n?.bri??function(e){const t=e?.attributes?.brightness,i="number"==typeof t?t:"string"==typeof t&&""!==t.trim()?Number(t):Number.NaN;return Number.isFinite(i)?Math.max(0,Math.min(1,i/255)):1}(e);if(n)return{c:n.c,bri:o};const s=Zt(r.rgb_color);if(s)return{c:$n(s)||Kt(i,"#ffd9a0"),bri:o};const a=Number(r.color_temp_kelvin)||(Number(r.color_temp)>0?1e6/Number(r.color_temp):NaN);return Number.isFinite(a)&&a>0?{c:(l=xn(a),"#"+l.slice(0,3).map(e=>Math.min(255,Math.max(0,Math.round(Number(e)||0))).toString(16).padStart(2,"0")).join("")),bri:o}:{c:Kt(i,"#ffd9a0"),bri:o};var l}function Cn(e,t,i){return"on"===e?.state?Rn(e,t,i):null}function Tn(e,t=1){const i=Math.max(0,Math.min(1,Number.isFinite(e)?e:1)),n=.7*Math.max(0,Math.min(1,Number.isFinite(t)?t:1))*(.4+.6*Math.pow(i,Sn));return Math.max(0,Math.min(1,n))}function Dn(e){return e.startsWith("light.")||e.startsWith("switch.")}function An(e,t,i=1e-6){const n=[];if(!e||!t||e.length<3||t.length<3)return n;for(let r=0;ru||l>u)continue;const p=(r[0]-o[0])*h+(r[1]-o[1])*d,_=(s[0]-o[0])*h+(s[1]-o[1])*d,m=Math.max(0,Math.min(p,_)),g=Math.min(c,Math.max(p,_));g-m>i&&n.push([o[0]+h*m,o[1]+d*m,o[0]+h*g,o[1]+d*g])}}return n}function Pn(e,t,i=1e-6){const n=[];for(const r of e){const e=[r[0],r[1]],o=[r[2],r[3]],s=o[0]-e[0],a=o[1]-e[1],l=Math.hypot(s,a);if(lo||r>o)continue;const s=(n[0]-e[0])*c+(n[1]-e[1])*h,a=(n[2]-e[0])*c+(n[3]-e[1])*h,u=Math.max(0,Math.min(s,a)),p=Math.min(l,Math.max(s,a));p-u>i&&d.push([u,p])}if(!d.length){n.push([e[0],e[1],o[0],o[1]]);continue}d.sort((e,t)=>e[0]-t[0]);let u=0;for(const[t,r]of d)t-u>i&&n.push([e[0]+c*u,e[1]+h*u,e[0]+c*t,e[1]+h*t]),u=Math.max(u,r);l-u>i&&n.push([e[0]+c*u,e[1]+h*u,o[0],o[1]])}return n}function Fn(e,t,i=1e-6){const n=[];for(let t=0;t{if("string"!=typeof e||!e)return;const i=En(e);i.startsWith("/api/houseplan/content/")&&t.add(i)};for(const t of e?.spaces||[]){i(t?.plan_url);for(const e of t?.markers||[])for(const t of e?.pdfs||[])i(t?.url)}for(const t of e?.markers||[])for(const e of t?.pdfs||[])i(e?.url);return t}function En(e){return e?e.startsWith("/houseplan_files/plans/")?"/api/houseplan/content/plans/_/"+e.slice(23):e.startsWith("/houseplan_files/files/")?"/api/houseplan/content/files/"+e.slice(23):e:""}function Nn(e,t){const i=t?.settings?.fill_mode;return"none"===i||"lqi"===i||"light"===i||"temp"===i||"custom"===i?i:e}function Hn(e,t){const i=t?.settings;return"boolean"==typeof i?.glow?i.glow:"glow"===i?.fill_mode||e}function Ln(e,t,i,n){if(!t||!i||t===i)return e;const r="/files/"+t+"/",o="/files/"+i+"/";return e.map(e=>{if(!e.url.includes(r))return e;const t=e.url.split(r)[1]||"",[i,s]=[t.split("?")[0],t.includes("?")?"?"+t.split("?")[1]:""];if(n){const t=n[decodeURIComponent(i)]??n[i];return t?{...e,url:e.url.split(r+i)[0]+o+encodeURIComponent(t)+s}:e}return{...e,url:e.url.split(r).join(o)}})}function Bn(e,t=1){const i=Number(e);return Number.isFinite(i)&&i>0?Math.min(3,Math.max(.5,i)):t}function qn(e,t,i){let n=null,r=null;for(const o of t){if(!(Math.abs(o[0]-e[0])<1e-6&&Math.abs(o[1]-e[1])<1e-6)){if(Math.abs(o[0]-e[0])<=i){const t=Math.abs(o[1]-e[1]);t>1e-6&&(!n||t1e-6&&(!r||t"number"==typeof e&&Number.isFinite(e),tr=(e,t,i)=>Math.min(i,Math.max(t,e));function ir(e){return e.elevation<=-6?"night":e.elevation>=6?"day":e.rising?"dawn":"dusk"}function nr(e){const t=(Math.floor(Number(e)||0)%1440+1440)%1440;return t>=300&&t<480?"dawn":t>=480&&t<1080?"day":t>=1080&&t<1260?"dusk":"night"}function rr(e){const t=ir(e),i=e.azimuth*Math.PI/180;return{sunX:50-42*Math.sin(i),sunY:78-tr(e.elevation,0,90)/90*64,sunOpacity:"night"===t?0:tr((e.elevation+6)/12,0,1)}}function or(e){const t=(Math.floor(Number(e)||0)%1440+1440)%1440;if(t<300||t>=1260)return{sunX:50,sunY:78,sunOpacity:0};const i=(t-300)/960,n=(t-300)/120,r=(1260-t)/120;return{sunX:8+84*i,sunY:78-64*Math.sin(i*Math.PI),sunOpacity:Math.max(.18,Math.min(n,r,1))}}function sr(e,t=new Date){const i=function(e){const t=e?.states?.["sun.sun"]?.attributes;return t&&er(t.azimuth)&&er(t.elevation)&&"boolean"==typeof t.rising?{azimuth:Zn(t.azimuth),elevation:t.elevation,rising:t.rising}:null}(e);if(i)return{phase:ir(i),source:"sun",...rr(i)};const n="number"==typeof t?t:function(e=new Date){return 60*e.getHours()+e.getMinutes()}(t);return{phase:nr(n),source:"clock",...or(n)}}function ar(e){return`${e.source}|${e.phase}|${e.sunX.toFixed(2)}|${e.sunY.toFixed(2)}|`+e.sunOpacity.toFixed(3)}const lr=[[-90,"#070c14"],[-12,"#070c14"],[-4,"#131a28"],[0,"#4a3527"],[10,"#e8ddcf"],[30,"#ffffff"],[90,"#ffffff"]],cr=e=>Math.min(1,Math.max(0,e));function hr(e,t,i=6){const n=e.angle*Math.PI/180,r=[Math.sin(n),-Math.cos(n)],o=n=>{const o=[e.x+r[0]*i*n,e.y+r[1]*i*n];return t.find(e=>e.poly.length>=3&&mi(o,e.poly))||null},s=o(1),a=o(-1);return s&&a?null:s||a?s?{normal:[-r[0],-r[1]],roomId:s.id}:{normal:r,roomId:a.id}:null}function dr(e,t,i){return i>0&&e[0]*t[0]+e[1]*t[1]>.05}function ur(e,t,i,n){return[[e[0],e[1]],[t[0],t[1]],[t[0]+i[0]*n,t[1]+i[1]*n],[e[0]+i[0]*n,e[1]+i[1]*n]]}function pr(e,t){try{const i=Ut([[...e.map(e=>[e[0],e[1]]),[e[0][0],e[0][1]]]],[[...t.map(e=>[e[0],e[1]]),[t[0][0],t[0][1]]]]),n=[];for(const e of i){const t=e?.[0];!Array.isArray(t)||t.length<4||n.push(t.slice(0,t.length-1).map(e=>[e[0],e[1]]))}return n}catch{return[]}}function _r(e,t,i,n,r,o,s){if(!(n>0))return[];const a=Jn(i,r),l=[-a[0],-a[1]],c=function(e){const t=Math.min(90,Math.max(0,e));return.7*(.8+1.7*Math.pow(1-t/90,1.6))}(n),h=[];for(const i of t){if(!(i.length>0))continue;const t=hr(i,e);if(!t||!dr(t.normal,a,n))continue;const r=e.find(e=>e.id===t.roomId);if(!r)continue;const d=o&&o[t.roomId]||r.poly,u=i.angle*Math.PI/180,p=i.length/2,_=[-t.normal[0],-t.normal[1]],m=Math.max(0,s?.[i.id]||0),g=i.x+_[0]*m/2,f=i.y+_[1]*m/2,v=Math.cos(u)*p,y=Math.sin(u)*p,b=[g-v,f-y],w=[g+v,f+y],k=c*i.length,x=pr(ur(b,w,l,k),d);if(!x.length)continue;const S=l[0]*_[0]+l[1]*_[1];h.push({openingId:i.id,roomId:t.roomId,polys:x,a:b,b:w,dir:l,len:k,normal:_,depth:k*S})}return h}const mr=e=>"number"==typeof e&&Number.isInteger(e)&&e>=0&&e<=359?e:null;function gr(e,t){const i=mr(t?.north_deg);return null!==i?i:mr(e?.north_deg)}function fr(e,t){const i=e=>"static"===e||"daynight"===e?e:null;return i(t?.bg_mode)??i(e?.bg_mode)??"static"}function vr(e,t){const i=t?.sun_rays;return"boolean"==typeof i?i:!0===e?.sun_rays}function yr(e){const t=e?.states?.["sun.sun"]?.attributes,i=Number(t?.azimuth),n=Number(t?.elevation);return Number.isFinite(i)&&Number.isFinite(n)?{azimuth:i,elevation:n}:null}const br=["dawn","day","dusk","night"];function wr(e){if(!e)return"";const t=Qn[e.phase];return[`--hp-day-cycle-outline-near:${t.outlineNear}`,`--hp-day-cycle-outline-mid:${t.outlineMid}`,`--hp-day-cycle-outline-far:${t.outlineFar}`].join(";")}function kr(e,t=1){if(!e)return G;const i=[`--hp-day-cycle-sun-x:${e.sunX.toFixed(2)}%`,`--hp-day-cycle-sun-y:${e.sunY.toFixed(2)}%`,`--hp-day-cycle-sun-opacity:${e.sunOpacity.toFixed(3)}`,`opacity:${Math.min(1,Math.max(0,t)).toFixed(4)}`].join(";");return j``:G} - `}}ug.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},ug.styles=[op,o`.hp-static-title{font-weight:700;padding:10px 14px 6px;font-size:16px;color:var(--primary-text-color);}.hp-static-body{position:relative;}.hp-static-stage{position:relative;width:100%;container-type:inline-size;overflow:hidden;pointer-events:none;background:var(--ha-card-background,var(--card-background-color,#111));}.hp-static-stage svg{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;}.hp-paper{fill:var(--ha-card-background,var(--card-background-color,#111));stroke:none;}.wallbody-fill{fill:var(--wall-fill,#ffffff);fill-opacity:var(--wall-fill-op,1);fill-rule:evenodd;stroke:none;pointer-events:none;}.wallbody{fill:url(#hp-wall-hatch);fill-rule:evenodd;stroke:var(--room-stroke,var(--hp-muted,#607d8b));stroke-width:calc(0.6px * var(--hp-cell-visual-scale,1));pointer-events:none;}.wallbody.solid{fill:none;}.hp-static-stage .devlayer{position:absolute;inset:0;z-index:2;}.hp-static-foot{padding:8px 12px 12px;pointer-events:auto;}.hp-static-btn{width:100%;padding:9px 14px;border:none;border-radius:10px;background:var(--primary-color,#3ea6ff);color:var(--text-primary-color,#fff);font-size:14px;font-weight:600;cursor:pointer;}:host([data-pointer-hover]) .hp-static-btn:hover{filter:brightness(1.08);}.hp-static-error{padding:24px;text-align:center;color:var(--secondary-text-color,#9aa4ad);}`],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",ug),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const pg=o`:host{--hp-editor-tray-bg-fallback:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 94%,var(--hp-line));--hp-editor-tray-bg:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 86%,transparent);--hp-editor-tray-border:color-mix(in srgb,var(--hp-line) 82%,var(--hp-accent));--hp-editor-tray-blur:8px;--hp-editor-tray-shadow:var(--shadow-2);}.editor-secondary-host{position:absolute;inset:var(--sp-2) var(--sp-4) auto;z-index:70;display:flex;justify-content:flex-end;pointer-events:none;}.editor-secondary-host.kind-palette,.editor-secondary-host.kind-group{justify-content:flex-start;}.editor-secondary{pointer-events:none;max-width:100%;display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);color:var(--hp-txt);background:var(--card-background-color,var(--hp-bg));background:var(--hp-editor-tray-bg-fallback);border:1px solid var(--hp-line);border-color:var(--hp-editor-tray-border);border-radius:var(--rad-l);box-shadow:var(--hp-editor-tray-shadow);opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity 0.1s ease,transform 0.1s cubic-bezier(0.2,0.7,0.2,1),visibility 0s linear 0.1s;touch-action:auto;}.editor-secondary-host.open .editor-secondary{pointer-events:auto;opacity:1;visibility:visible;transform:translateY(0);transition-duration:0.14s,0.14s,0s;transition-delay:0s;}.editor-secondary-host.blocked .editor-secondary{pointer-events:none;}@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.editor-secondary{background:var(--hp-editor-tray-bg);-webkit-backdrop-filter:blur(var(--hp-editor-tray-blur));backdrop-filter:blur(var(--hp-editor-tray-blur));}}.editor-secondary-content,.editor-group-items{display:flex;align-items:center;gap:var(--sp-3);min-width:0;}.editor-context-label{max-width:14rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-inline-end:var(--sp-4);border-inline-end:1px solid var(--hp-line);color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary.kind-palette{width:min(760px,100%);align-items:stretch;padding:0;overflow:hidden;}.editor-secondary.kind-palette .editor-secondary-content,.editor-secondary.kind-palette .furnpalette{width:100%;}.editor-secondary.kind-palette .furnpalette{max-height:38vh;border:0;background:transparent;}.editor-group-launcher .group-chevron{--mdc-icon-size:16px;transition:transform 0.14s ease;}.editor-group-launcher[aria-expanded="true"] .group-chevron{transform:rotate(180deg);}.editor-secondary .bdhint{font-size:var(--fs-s);color:var(--hp-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.editor-secondary .dfill{display:inline-flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-s);cursor:pointer;}.editor-secondary .dfill input[type="checkbox"]{width:16px;height:16px;flex:none;margin:0;padding:0;}.editor-secondary hp-color-opacity{flex:0 0 auto;}.editor-secondary input{width:74px;background:transparent;border:1px solid var(--hp-line);color:var(--hp-txt);border-radius:var(--rad-s);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-m);}.editor-secondary label,.editor-secondary .hint{color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary .drawwall{display:inline-flex;align-items:center;gap:var(--sp-3);white-space:nowrap;}.editor-secondary .drawwall input{width:4.2em;}.editor-secondary .drawwall .opl{color:var(--hp-muted);font-size:var(--fs-s);}@container (min-width:560px) and (max-width:899px){.editor-secondary-content,.editor-group-items{flex-wrap:wrap;justify-content:flex-end;}}@container (max-width:559px){.editor-secondary-host{inset-inline:var(--sp-4);}.editor-secondary{max-width:100%;}.editor-secondary-content,.editor-group-items{overflow-x:auto;scrollbar-width:thin;}.editor-secondary-content>*,.editor-group-items>*{flex:none;}.editor-context-label{display:none;}}@media (prefers-reduced-motion:reduce){.editor-secondary{transition:none;}.editor-group-launcher .group-chevron{transition:none;}}`;class _g{constructor(e=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(e))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(e){this._undo.push(e),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const e=this._undo.pop()??null;return e&&this._redo.push(e),e}redo(){const e=this._redo.pop()??null;return e&&this._undo.push(e),e}removeWhere(e){const t=this._undo.length,i=this._redo.length;return this._undo=this._undo.filter(t=>!e(t)),this._redo=this._redo.filter(t=>!e(t)),t+i-this._undo.length-this._redo.length}clear(){this._undo=[],this._redo=[]}}function mg(e,t){const i=e[t];return i&&Number.isFinite(i.x)&&Number.isFinite(i.y)?{x:i.x,y:i.y,..."string"==typeof i.s?{s:i.s}:{}}:null}function gg(e,t,i){if(null===i){if(!(t in e))return e;const i={...e};return delete i[t],i}const n={...e[t]||{}};delete n.x,delete n.y,delete n.s;const r={...n,x:i.x,y:i.y,...void 0!==i.s?{s:i.s}:{}};return{...e,[t]:r}}const fg="houseplan-card:version-reload-target:v1";function vg(e){if("string"!=typeof e)return null;return e.trim()||null}class yg{constructor(e){this.hooks=e,this._input={frontendVersion:null,backendVersion:null,kiosk:!1,reducedMotion:!1},this._relation={kind:"unknown"},this._banner=null,this._connected=!1,this._attemptTarget=null,this._attemptState=null,this._noticeToken=0}get relation(){return this._relation}get banner(){return this._banner}get hasCurrentMismatchNotice(){return"mismatch"===this._relation.kind&&"visible"===this._banner?.phase}connect(){this._connected||(this._connected=!0,this._attemptTarget=null,this._attemptState=null,this._reconcile())}disconnect(){(this._connected||this._banner)&&(this._connected=!1,this._cancelTimer(),this._banner&&(this._banner=null,this.hooks.changed()))}update(e){const t={frontendVersion:vg(e.frontendVersion),backendVersion:vg(e.backendVersion),kiosk:!0===e.kiosk,reducedMotion:!0===e.reducedMotion},i=function(e,t){const i=vg(e),n=vg(t);return i&&n?i===n?{kind:"equal",frontend:i,backend:n}:{kind:"mismatch",frontend:i,backend:n}:{kind:"unknown"}}(t.frontendVersion,t.backendVersion),n=!((e,t)=>e.frontendVersion===t.frontendVersion&&e.backendVersion===t.backendVersion&&e.kiosk===t.kiosk&&e.reducedMotion===t.reducedMotion)(this._input,t)||!((e,t)=>e.kind===t.kind&&("unknown"===e.kind||"unknown"!==t.kind&&e.frontend===t.frontend&&e.backend===t.backend))(this._relation,i);this._input=t,this._relation=i,n&&this._reconcile()}finishBannerExit(e){this._banner&&"leaving"===this._banner.phase&&this._banner.token===e&&(this._banner=null,this.hooks.changed())}_reconcile(){if(this._cancelTimer(),!this._connected||"mismatch"!==this._relation.kind)return this._attemptTarget=null,this._attemptState=null,void this._hideBanner();if(!this._input.kiosk)return this._attemptTarget=null,this._attemptState=null,void this._showBanner(this._relation.frontend,this._relation.backend);const e=this._relation.backend;if(this._attemptTarget===e&&null!==this._attemptState||(this._attemptTarget=e,this._attemptState=function(e,t){try{const i=e();return i?i.getItem(fg)===t?"attempted":"fresh":"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e)),"fresh"===this._attemptState)return this._hideBanner(),void this._armTimer();this._showBanner(this._relation.frontend,e)}_armTimer(){this._connected&&void 0===this._timer&&"mismatch"===this._relation.kind&&this._input.kiosk&&"fresh"===this._attemptState&&(this._timer=this.hooks.clock.setTimeout(()=>{this._timer=void 0,this._tick()},250))}_cancelTimer(){void 0!==this._timer&&(this.hooks.clock.clearTimeout(this._timer),this._timer=void 0)}_tick(){if(!this._connected||"mismatch"!==this._relation.kind||!this._input.kiosk||"fresh"!==this._attemptState)return;if(!function(e){return e.connected&&e.initialFrameSettled&&e.viewOnly&&e.surfacesIdle&&e.configWritesIdle&&e.physicalWritesIdle&&e.layoutWritesIdle&&e.gesturesIdle&&e.interactionPauseElapsed&&e.baseZoom}(this.hooks.safety()))return void this._armTimer();const e=this._relation.backend,t=function(e,t){try{const i=e();return i?i.getItem(fg)===t?"attempted":(i.setItem(fg,t),"claimed"):"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e);if(this._attemptTarget=e,this._attemptState="claimed"===t?"attempted":t,"claimed"===t){this._showBanner(this._relation.frontend,e);try{this.hooks.reload()}catch{}}else this._showBanner(this._relation.frontend,e)}_showBanner(e,t){"visible"===this._banner?.phase&&this._banner.frontend===e&&this._banner.backend===t||(this._banner={frontend:e,backend:t,phase:"visible",token:++this._noticeToken},this.hooks.changed())}_hideBanner(){if(this._banner)return this._input.reducedMotion?(this._banner=null,void this.hooks.changed()):void("leaving"!==this._banner.phase&&(this._banner={...this._banner,phase:"leaving",token:++this._noticeToken},this.hooks.changed()))}}const bg=1;function wg(e,t){const i=t&&"object"==typeof t?t:{};e._haIntegrationVersion=vg(i.integration_version);const n=i.support_api;e._haSupportApi="number"==typeof n&&Number.isSafeInteger(n)?n:null,e._haDecorAssetsApi=1===i.decor_assets_api?1:null,e._haSummaryPanelApi=1===i.summary_panel_api?1:null,e._haRadarStage1Api=1===i.radar_stage1_api?1:null,e._syncVersionRecovery()}function kg(e){const t=e._stageEl,i=e._loadOk&&!e._loading&&e._continuityDataReady&&!e._resumeSettling&&!e._connectionWasLost&&!e._booting&&!e._bootFading&&!e._bootSettling&&!e._bootSoft&&e._continuity.hasCompleteFrame&&"steady"===e._continuity.state&&!e._continuity.overlayBlocksInteraction&&!!t&&t.clientWidth>0&&t.clientHeight>0,n=!(0!==e._pointers.size||0!==e._touchContacts.size||e._touchSequenceMultitouch||e._roomPointer||e._panStart||e._panLock||e._pinchStart||e._swipeStart||e._tabDrag||e._tabDragRelease||e._drag||e._deviceDrag||e._rlResize||e._resize?.dragging||e._physicalDrag||e._physicalRotate||e._opDrag||e._decorDraft||e._decorMove||e._dtDrag||e._bdDrag||e._furnTouchPending||e._compassDrag||e._viewportGestureDirty||e._devicePositionBusy||e._modeTransitionBusy||e._cameraTransition.active||e._slide||0!==e._warmModeRequest),r=!(e._editorSecondaryDialogBlocked||e._partitionDeleteDialog||e._roomDeleteDialog||e._backdropGuard||e._vacFit||e._editorSecondary?.hasOpenGroup||e._furnPalette||e._decorImagePalette);return{connected:e.isConnected,initialFrameSettled:i,viewOnly:!0===e._config?.kiosk&&"view"===e._mode&&!e._editing,surfacesIdle:r,configWritesIdle:0===e._writesPending&&!e._saveConfigDebounced.pending(),physicalWritesIdle:0===e._pendingPhysicalWrites.size,layoutWritesIdle:!e._persistLayout.pending()&&0===e._dirtyPos.size&&0===e._sentPos.size&&!e._devicePositionBusy,gesturesIdle:n,interactionPauseElapsed:Date.now()>=e._cyclePausedUntil,baseZoom:e._zoom<=1.001}}class xg{constructor(){this.seen=null,this.diagnosticsCache=null}observe(e,t,i,n){this.invalidateDiagnosticsForHass(e,t,i),this.intake(t,n)}intake(e,t){e&&this.seen!==e&&(this.seen=e,t())}invalidate(){this.diagnosticsCache=null}invalidateDiagnosticsForHass(e,t,i){this.diagnosticsCache&&(e?.entities!==t?.entities||e?.devices!==t?.devices||[...i?.entityIds||[]].some(i=>!!e?.states?.[i]!=!!t?.states?.[i]))&&this.invalidate()}diagnostics(e,t,i){if(this.diagnosticsCache)return this.diagnosticsCache;const n={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of t)e.removed||"virtual"===e.binding||n[i(e.binding).kind]++;return this.diagnosticsCache={registry:hd(e),bindings:n},this.diagnosticsCache}}function Sg(e){const t=e;t._hassSequence++,t._renderSnapshotAt=Date.now(),t._continuity.note("hass-snapshot"),t._ensureHaRegistryAuthority(),t._planHassMemo=null,t._hookConnection(),!t._loadOk&&!t._loading&&t._loadTries<8&&t._loadFromServer(),t._maybeRebuildDevices(),t._vacTick(),t._activityTick()}function $g(e){return!!e&&"object"==typeof e&&1===e.version}function Mg(e,t){const i=e.radar;return e.space===t&&!0!==e.hidden&&!0!==e.removed&&$g(i)&&!0===i.enabled&&!1!==i.show_live}const Rg={ok:"radar.health_ok",off:"radar.health_off",stale:"radar.health_stale",partial:"radar.health_partial",restricted:"radar.health_restricted",incomplete:"radar.health_incomplete",position_unavailable:"radar.health_position_unavailable",unavailable:"radar.health_unavailable",needs_setup:"radar.health_needs_setup",inconsistent:"radar.health_inconsistent",unknown:"radar.health_unknown"};const Cg=e=>"number"==typeof e&&Number.isFinite(e);class Tg{constructor(e){this.host=e,this.frames=new Map,this.connection=null,this.space="",this.generation=0,this.expiryTimer=0,this.deadlines=new Map}sync(e,t){const i=this.host.hass?.connection;if(!t||!i||!this.host.isConnected)return void this.stop();if(this.unsubscribe&&this.connection===i&&this.space===e)return;this.stop(),this.connection=i,this.space=e;const n=++this.generation,r=i.subscribeMessage?.bind(i);"function"==typeof r&&Promise.resolve(r(e=>{if(n!==this.generation||!this.host.isConnected)return;const t=function(e){if(!e||"object"!=typeof e)return null;const t=e;if("string"!=typeof t.marker_id||"string"!=typeof t.server_session_id||!Number.isSafeInteger(t.seq)||"string"!=typeof t.health)return null;const i=Array.isArray(t.targets)?t.targets.slice(0,256).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;return"string"==typeof t.slot&&Cg(t.x)&&Cg(t.y)&&Cg(t.expires_at)&&Cg(t.reported_at)&&("bounded_latest"===t.pair_quality||"coherent"===t.pair_quality)?[{...t,included:!0===t.included,smooth:!0===t.smooth}]:[]}):[],n=Array.isArray(t.ranges)?t.ranges.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if(!("string"==typeof t.id&&Cg(t.x)&&Cg(t.y)&&Cg(t.radius)&&Cg(t.expires_at)&&Cg(t.reported_at)))return[];const i=Array.isArray(t.segments)?t.segments.slice(0,64).flatMap(e=>{if(!Array.isArray(e))return[];const t=e.slice(0,181).flatMap(e=>Array.isArray(e)&&2===e.length&&Cg(e[0])&&Cg(e[1])?[[e[0],e[1]]]:[]);return t.length>=2?[t]:[]}):void 0;return[{...t,...i?{segments:i}:{}}]}):[],r=Array.isArray(t.zones)?t.zones.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if("string"!=typeof t.id)return[];const i=t.state;if(null!==i&&"boolean"!=typeof i&&!Cg(i))return[];const n=Array.isArray(t.polygon)?t.polygon.slice(0,64).flatMap(e=>Array.isArray(e)&&2===e.length&&Cg(e[0])&&Cg(e[1])?[[e[0],e[1]]]:[]):[];return[{id:t.id,state:i,...n.length>=3?{polygon:n}:{}}]}):[];return{server_session_id:t.server_session_id,marker_id:t.marker_id,source_generation:"string"==typeof t.source_generation?t.source_generation:void 0,calibration_revision:"string"==typeof t.calibration_revision?t.calibration_revision:void 0,seq:t.seq,reported_at:Cg(t.reported_at)?t.reported_at:void 0,expires_at:Cg(t.expires_at)?t.expires_at:void 0,health:t.health,reported_presence:"boolean"==typeof t.reported_presence?t.reported_presence:null,complete:!0===t.complete,targets:i,ranges:n,zones:r}}(e);if(!t)return;if(!function(e,t){return!e||t.server_session_id!==e.server_session_id||t.source_generation!==e.source_generation||t.calibration_revision!==e.calibration_revision||t.seq>e.seq}(this.frames.get(t.marker_id),t))return;const i=function(e,t=Date.now()){if(!Cg(e.expires_at))return null;if(!Cg(e.reported_at))return Math.max(0,1e3*e.expires_at-t);const i=Math.max(0,1e3*(e.expires_at-e.reported_at)),n=Math.max(0,t-1e3*e.reported_at);return Math.max(0,i-n)}(t);"restricted"===t.health||"disabled"===t.health||0===i?(this.frames.delete(t.marker_id),this.deadlines.delete(t.marker_id)):(this.frames.set(t.marker_id,t),null==i?this.deadlines.delete(t.marker_id):this.deadlines.set(t.marker_id,this.monotonicNow()+i)),this.armExpiry(),this.host.requestUpdate()},{type:"houseplan/radar/subscribe",space_id:e})).then(e=>{n===this.generation&&this.host.isConnected?"function"==typeof e&&(this.unsubscribe=e):"function"==typeof e&&e()}).catch(()=>{n===this.generation&&this.stop()})}stop(){this.generation++,this.unsubscribe?.(),this.unsubscribe=void 0,this.connection=null,this.space="",clearTimeout(this.expiryTimer),this.expiryTimer=0,this.frames.size&&(this.frames.clear(),this.host.isConnected&&this.host.requestUpdate()),this.deadlines.clear()}armExpiry(){clearTimeout(this.expiryTimer);const e=this.monotonicNow(),t=[...this.deadlines.values()].filter(t=>t>e);if(!t.length)return;const i=Math.max(20,Math.min(...t)-e+10);this.expiryTimer=window.setTimeout(()=>{this.expiryTimer=0;let e=!1;const t=this.monotonicNow();for(const[i,n]of this.deadlines)n>t||(this.deadlines.delete(i),this.frames.delete(i),e=!0);this.armExpiry(),e&&this.host.isConnected&&this.host.requestUpdate()},i)}monotonicNow(){return globalThis.performance?.now?.()??Date.now()}}const Dg=Object.freeze({enabled:!1,z2mBaseTopics:Object.freeze([])});function Ag(e){if("string"!=typeof e)return null;const t=e.trim().replace(/^\/+|\/+$/g,"").replace(/\/{2,}/g,"/");return!t||t.length>180||/[#+\u0000-\u001f\u007f]/.test(t)?null:t}function Pg(e){const t=e?.zigbee_topology;if(!t||"object"!=typeof t)return Dg;const i=t,n=Array.isArray(i.z2m_base_topics)?i.z2m_base_topics:Array.isArray(i.z2mBaseTopics)?i.z2mBaseTopics:[],r=new Set,o=[];for(const e of n){const t=Ag(e);if(t&&!r.has(t)&&(r.add(t),o.push(t),8===o.length))break}return{enabled:!0===i.enabled,z2mBaseTopics:o}}function Fg(e,t){const i={...e},n=t.z2mBaseTopics.map(Ag).filter(Boolean);return t.enabled||n.length?i.zigbee_topology={enabled:!0===t.enabled,z2m_base_topics:[...new Set(n)].slice(0,8)}:delete i.zigbee_topology,i}const zg={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Ig=e=>Math.max(0,Math.min(1,e)),Og=(e,t,i)=>e+(t-e)*i,Eg=(e,t,i)=>{const n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},Ng=e=>{const t=Ig(e);if(0===t||1===t)return t;let i=0,n=1,r=t;for(let e=0;e<12;e++)r=(i+n)/2,Eg(r,.2,.2)0&&e.w>0?t/e.w:1,viewBox:{...e}}}function Lg(e,t,i){const n=Math.max(1e-9,e.pixelsPerUnit),r=Math.max(1e-9,t/n),o=Math.max(1e-9,i/n);return{x:e.centerX-r/2,y:e.centerY-o/2,w:r,h:o}}function Bg(e){const t=e.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(t);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const n=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t)?.[1];return n?[parseInt(n.slice(0,2),16),parseInt(n.slice(2,4),16),parseInt(n.slice(4,6),16),8===n.length?parseInt(n.slice(6,8),16)/255:1]:null}function qg(e,t,i){const n=Bg(e),r=Bg(t);if(!n||!r)return i<.5?e:t;const o=Ig(i);return`rgba(${Math.round(Og(n[0],r[0],o))}, ${Math.round(Og(n[1],r[1],o))}, ${Math.round(Og(n[2],r[2],o))}, ${Og(n[3],r[3],o).toFixed(3)})`}class jg{constructor(e,t=zg){this._hooks=e,this._clock=t,this._token=0,this._raf=0,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase||"preparing"===this._state?.phase}get presented(){return this._state?.presented||null}start(e,t,i,n=220){this.cancel(!1);const r=++this._token,o=this._clock.now();if(this._state={token:r,phase:n<=0?"settling":"running",from:e,to:t,presented:n<=0?t:e,startedAt:o,duration:Math.max(0,n),targetMode:i},n<=0)return this._hooks.frame(this._state),this._hooks.settled(this._state),this._state=null,r;this._hooks.frame(this._state);const s=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Ig((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:function(e,t,i){const n=Ng(i),r=Og(e.stageWidth,t.stageWidth,n),o=Og(e.stageHeight,t.stageHeight,n),s=Math.max(1e-9,e.viewport.pixelsPerUnit),a=Math.max(1e-9,t.viewport.pixelsPerUnit),l={centerX:Og(e.viewport.centerX,t.viewport.centerX,n),centerY:Og(e.viewport.centerY,t.viewport.centerY,n),pixelsPerUnit:Math.exp(Og(Math.log(s),Math.log(a),n))};return{presentedMode:n<.5?e.presentedMode:t.presentedMode,editorChromeHeight:Og(e.editorChromeHeight,t.editorChromeHeight,n),stageWidth:r,stageHeight:o,viewport:{...l,viewBox:Lg(l,r,o)},stageColor:qg(e.stageColor,t.stageColor,n),paperColor:qg(e.paperColor,t.paperColor,n),sceneBrightness:Og(e.sceneBrightness,t.sceneBrightness,n),architectureOpacity:Og(e.architectureOpacity,t.architectureOpacity,n),backdropOpacity:Og(e.backdropOpacity,t.backdropOpacity,n),viewWeight:Og(e.viewWeight,t.viewWeight,n),editorWeight:Og(e.editorWeight,t.editorWeight,n),toolbarContentOpacity:Og(e.toolbarContentOpacity,t.toolbarContentOpacity,n)}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i<1?this._raf=this._clock.requestFrame(s):(this._raf=0,this._hooks.settled(t),this._state?.token===r&&(this._state=null))};return this._raf=this._clock.requestFrame(s),r}cancel(e=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=t.to,this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}}const Wg={now:()=>"undefined"!=typeof performance?performance.now():Date.now(),requestFrame:e=>"function"==typeof requestAnimationFrame?requestAnimationFrame(e):null,cancelFrame:e=>{"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e)}},Ug=e=>Number.isFinite(e);function Gg(e){return!!e&&Ug(e.zoom)&&e.zoom>0&&Ug(e.viewBox.x)&&Ug(e.viewBox.y)&&Ug(e.viewBox.w)&&e.viewBox.w>0&&Ug(e.viewBox.h)&&e.viewBox.h>0}function Vg(e){return{zoom:e.zoom,viewBox:{...e.viewBox}}}function Kg(e,t){return Math.abs(e.zoom-t.zoom)<1e-9&&Math.abs(e.viewBox.x-t.viewBox.x)<1e-6&&Math.abs(e.viewBox.y-t.viewBox.y)<1e-6&&Math.abs(e.viewBox.w-t.viewBox.w)<1e-6&&Math.abs(e.viewBox.h-t.viewBox.h)<1e-6}const Yg=(e,t,i)=>e+(t-e)*i,Xg=(e,t,i)=>Math.exp(Yg(Math.log(e),Math.log(t),i));class Zg{constructor(e,t=Wg){this._hooks=e,this._clock=t,this._token=0,this._raf=null,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase}get presented(){return this._state?.presented||null}get target(){return this._state?.to||null}start(e,t,i,n){this.cancel(!1);const r=++this._token,o=Vg(e),s=Vg(t),a=n>0&&Gg(o)&&Gg(s),l=this._clock.now(),c={token:r,phase:a?"running":"settling",from:o,to:s,presented:Vg(a?o:s),startedAt:l,duration:a?n:0,reason:i};if(this._state=c,this._hooks.frame(c),!a)return this._settle(r),r;const h=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Math.max(0,Math.min(1,(e-t.startedAt)/t.duration));if(t.presented=i>=1?Vg(t.to):function(e,t,i){if(!Gg(e))return Vg(t);if(!Gg(t))return Vg(e);const n=Ng(i);if(n<=0)return Vg(e);if(n>=1)return Vg(t);const r=e.viewBox.x+e.viewBox.w/2,o=e.viewBox.y+e.viewBox.h/2,s=t.viewBox.x+t.viewBox.w/2,a=t.viewBox.y+t.viewBox.h/2,l=Xg(e.viewBox.w,t.viewBox.w,n),c=Xg(e.viewBox.h,t.viewBox.h,n),h=Yg(r,s,n),d=Yg(o,a,n);return{zoom:Xg(e.zoom,t.zoom,n),viewBox:{x:h-l/2,y:d-c/2,w:l,h:c}}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i>=1)return this._raf=null,void this._settle(r);this._raf=this._clock.requestFrame(h),null===this._raf&&this._settle(r)};return this._raf=this._clock.requestFrame(h),null===this._raf&&(c.phase="settling",c.presented=Vg(s),this._hooks.frame(c),this._settle(r)),r}cancel(e=!0){null!==this._raf&&this._clock.cancelFrame(this._raf),this._raf=null;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=Vg(t.to),this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}_settle(e){const t=this._state;t&&t.token===e&&(t.phase="settling",t.presented=Vg(t.to),this._hooks.settled(t),this._state?.token===e&&(this._state=null))}}function Jg(e,t,i){const n=e.querySelector("ha-card");if(!n)return null;const r=n.getBoundingClientRect(),o=t.getBoundingClientRect().top-r.top,s=i?0:Math.min(Math.max(r.top,0),120),a=Math.round(o+s);return a>=0?a:null}const Qg=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])}),ef=84,tf=10,nf=4,rf=4;function of(e){return[e.rotDeg,e.tiltDeg,e.xyScale,e.zScale,e.origin[0],e.origin[1]].every(Number.isFinite)&&Math.abs(e.xyScale)>1e-12&&Math.abs(Math.cos(e.tiltDeg*Math.PI/180))>1e-12}function sf(e,t,i=Qg){if(!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");return function(e,t){if(!Number.isFinite(e[0])||!Number.isFinite(e[1])||!t.every(Number.isFinite))throw new Error("invalid isometric affine input");const[i,n,r,o,s,a]=t;return[i*e[0]+r*e[1]+s,n*e[0]+o*e[1]+a]}(e,lf(t,i))}function af(e,t=Qg){if(!of(t)||!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=(e[0]-t.origin[0])/t.xyScale,o=(e[1]-t.origin[1])/(t.xyScale*Math.cos(n));return[t.origin[0]+r*Math.cos(i)+o*Math.sin(i),t.origin[1]-r*Math.sin(i)+o*Math.cos(i)]}function lf(e=0,t=Qg){if(!of(t)||!Number.isFinite(e))throw new Error("invalid isometric camera");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=t.xyScale*Math.cos(i),o=-t.xyScale*Math.sin(i),s=t.xyScale*Math.sin(i)*Math.cos(n),a=t.xyScale*Math.cos(i)*Math.cos(n);return[r,s,o,a,t.origin[0]-r*t.origin[0]-o*t.origin[1],t.origin[1]-s*t.origin[0]-a*t.origin[1]-e*t.zScale*Math.sin(n)]}function cf(e=Qg){return function(e=0,t=Qg){return`matrix(${lf(e,t).map(e=>Number(e.toFixed(12))).join(" ")})`}(0,e)}function hf(e,t=Qg){const{rect:i,wallHeight:n}=e,r=e.openingHeight??n,o=e.floorDepth??0,s=e.raisedHeight??n;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o)||!Number.isFinite(s)||n<0||r<0||o<0||s<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],l=Math.max(n,r,s),c=a.flatMap(e=>[sf(e,-o,t),sf(e,l,t)]),h=c.map(e=>e[0]),d=c.map(e=>e[1]),u=Math.min(...h),p=Math.min(...d);return{x:u,y:p,w:Math.max(...h)-u,h:Math.max(...d)-p}}const df=[".dev",".vacpuck",".oplock",".op-hit",".opening",".rlgo","a","button","input","select","textarea",'[contenteditable]:not([contenteditable="false"])',"[data-room-fit-block]",'[role="link"]','[role="button"]'].join(","),uf=(e,t)=>{try{return"function"==typeof e?.matches&&e.matches(t)}catch{return!1}};function pf(e){for(const t of e){const e=t;if(uf(e,".roomlabel[data-id]")){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(uf(e,df))return{kind:"interactive"};if(uf(e,'[data-hp="room"][data-id]')){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(uf(e,".stage"))return{kind:"background"}}return{kind:"outside"}}function _f(e){const t=pf(e);return"room"===t.kind?t.roomId:null}class mf{constructor(){this.pointer=null,this.sequence=null}clear(){this.pointer=null,this.sequence=null}clearOutside(e){let t={kind:"outside"};try{t=pf(e.composedPath())}catch{}"outside"===t.kind&&this.clear()}pointerDown(e,t,i){let n={kind:"outside"};try{n=pf(e.composedPath())}catch{}this.pointer=function(e){const t="mouse"===(i=e.pointerType)||"touch"===i||"pen"===i?i:null;var i;return t&&"view"===e.mode&&"background"===e.owner.kind&&!e.blocked&&e.isPrimary&&0===e.button&&Number.isFinite(e.x)&&Number.isFinite(e.y)?{pointerId:e.pointerId,spaceId:e.spaceId,modality:t,x:e.x,y:e.y}:null}({pointerId:e.pointerId,pointerType:e.pointerType,isPrimary:e.isPrimary,button:e.button,spaceId:t,mode:i?"view":"blocked",owner:n,blocked:!i,x:e.clientX,y:e.clientY}),this.pointer||(this.sequence=null)}pointerUp(e,t,i,n,r=Date.now()){let o={kind:"outside"};try{o=pf(e.composedPath())}catch{}const s=function(e,t,i){if(!t||"view"!==i.mode||"background"!==i.owner.kind||i.blocked||t.pointerId!==i.pointerId||t.spaceId!==i.spaceId||!Number.isFinite(i.x)||!Number.isFinite(i.y)||!Number.isFinite(i.now)||Math.abs(i.x-t.x)+Math.abs(i.y-t.y)>=8)return{sequence:null,trigger:!1};const n=e?i.now-e.at:Number.POSITIVE_INFINITY;return e&&e.spaceId===i.spaceId&&e.modality===t.modality&&n>=0&&n<=350?{sequence:null,trigger:!0}:{sequence:{at:i.now,spaceId:i.spaceId,modality:t.modality},trigger:!1}}(this.sequence,this.pointer,{pointerId:e.pointerId,spaceId:t,mode:i?"view":"blocked",owner:o,blocked:n||!i,x:e.clientX,y:e.clientY,now:r});return this.pointer=null,this.sequence=s.sequence,s.trigger}}const gf=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function ff(e){return!!e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&e.w>0&&Number.isFinite(e.h)&&e.h>0}function vf(e,t=0){if(!e.length||!Number.isFinite(t)||t<0||!e.every(gf))return null;let i=1/0,n=1/0,r=-1/0,o=-1/0;for(const t of e)i=Math.min(i,t[0]),n=Math.min(n,t[1]),r=Math.max(r,t[0]),o=Math.max(o,t[1]);const s=r-i,a=o-n;return s>0&&a>0?{x:i-t,y:n-t,w:s+2*t,h:a+2*t}:null}function yf(e,t,i){const n="string"!=typeof t||"invalid"!==t&&"no-borders"!==t&&"unverified"!==t&&!/^[a-z0-9]{1,8}$/i.test(t)?"redacted":t;return Object.freeze({kind:e,fingerprint:n,terminal:!!i})}function bf(e,t){return`${e("editor.load_failed")} ${e(t.terminal?"editor.refresh_advice":"editor.retry_advice")}`}class wf extends Error{}class kf{constructor(e){this.options=e,this._state="idle",this._inFlight=null}get state(){return this._state}ensure(){return"ready"===this._state?Promise.resolve(!0):"failed"===this._state?Promise.resolve(!1):(this._inFlight||(this._setState("loading"),this._inFlight=this._loadWithRetry().finally(()=>{this._inFlight=null})),this._inFlight)}async _loadWithRetry(){let e=new Error("Editor runtime did not load"),t=!1;for(const i of[0,1])try{const e=await this.options.load(i);if(e.fingerprint!==this.options.expectedFingerprint)throw new wf(`Editor runtime fingerprint mismatch: expected ${this.options.expectedFingerprint}, got ${e.fingerprint}`);const t=e.create();return this.options.install(t),this._setState("ready"),!0}catch(i){e=i,i instanceof wf&&(t=!0)}return this._setState(t?"failed":"idle"),this.options.failed?.(e,{terminal:t}),!1}_setState(e){e!==this._state&&(this._state=e,this.options.stateChanged?.(e))}}const xf=(e,t)=>{if(!e.has(t))return{hit:!1};const i=e.get(t);return e.delete(t),e.set(t,i),{hit:!0,value:i}},Sf=(e,t,i,n)=>{for(e.delete(t),e.set(t,i);e.size>n;){const t=e.keys().next().value;if(void 0===t)break;e.delete(t)}},$f=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Mf=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`,Rf="houseplan_card_alpha_v1",Cf=Object.freeze([Object.freeze({id:"iso",issue:89,summary:"Volumetric plan renderer"})]);function Tf(e){return/^[a-z][a-z0-9-]*$/.test(e.id)&&Number.isInteger(e.issue)&&e.issue>0&&!!e.summary.trim()}function Df(e){const t=String(e||"").replace(/^#/,"");return new URLSearchParams(t)}function Af(e){return Df(e).get("space")||""}function Pf(e,t,i=Cf){const n=function(e){const t=new Set;for(const i of e){if(!Tf(i)||t.has(i.id))return!1;t.add(i.id)}return!0}(i),r=function(e){let t,i=!1;const n=e=>{for(const n of e.getAll("hp_alpha"))i=!0,"1"===n?t=!0:"0"===n&&(t=!1)};return n(new URLSearchParams(String(e.search||"").replace(/^\?/,""))),n(Df(e.hash)),{present:i,value:t}}(e),o=void 0!==r.value,s="1"===t,a=o?!0===r.value:!r.present&&s,l=n&&a;return{alpha:l,active:Object.freeze(l?i.map(e=>e.id).sort():[]),space:Af(e.hash),persist:n&&o?l?"1":"0":void 0,knownUrlOperation:o}}let Ff={alpha:!1,active:Object.freeze([]),space:""},zf=!1,If="";const Of=new Set;function Ef(){if("undefined"==typeof window)return Ff;const e=Pf(window.location,function(){try{return window.localStorage.getItem(Rf)}catch{return null}}());void 0!==e.persist&&function(e){try{window.localStorage.setItem(Rf,e)}catch{}}(e.persist),Ff={alpha:e.alpha,active:e.active,space:e.space},window.__hpAlpha=e.alpha,window.__hpLabs=e.active;for(const e of Of)e(Ff);return Ff}function Nf(){Ef()}function Hf(){if("undefined"==typeof window)return Ff;if(!zf){zf=!0,window.__hpLabsListenerCleanup?.(),window.addEventListener("hashchange",Nf),window.addEventListener("popstate",Nf);const e=()=>{window.removeEventListener("hashchange",Nf),window.removeEventListener("popstate",Nf),window.__hpLabsListenerCleanup===e&&delete window.__hpLabsListenerCleanup};window.__hpLabsListenerCleanup=e}return Ef()}const Lf={window:120,door:90,passage:90,gate:300};function Bf(e){return Lf[e]}function qf(e,t){return{type:e,lengthCm:Bf(e),flipH:!1,flipV:!1,revision:t}}function jf(e,t){const i=Math.max(0,e.renderedLength)/2,n=Math.max(0,e.target.physicalHalfWidth),r=n+.18*Math.max(0,t),o=e=>({x1:e,y1:-r,x2:e,y2:r});return{rect:{x:-i,y:n?-n:0,width:2*i,height:2*n},boundaries:[o(-i),o(i)]}}function Wf(e,t){const i=[e[0],e[1]],n=[t[0],t[1]];return function(e,t){return e[0]-t[0]||e[1]-t[1]}(i,n)<=0?{a:i,b:n}:{a:n,b:i}}function Uf(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const n=Wf(e.a,e.b);if(Math.hypot(n.b[0]-n.a[0],n.b[1]-n.a[1])<=1e-9)return;const r=function(e,t){const i=e=>(Math.abs(e)<=5e-10?0:Math.round(1e6*e)/1e6).toFixed(6);return`${i(e[0])},${i(e[1])}>${i(t[0])},${i(t[1])}`}(n.a,n.b),o=t.get(r);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,e.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(e.partitionHost&&(o.partitionHost&&o.partitionHost.id!==e.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=e.partitionHost));t.set(r,{segmentKey:r,a:n.a,b:n.b,physicalHalfWidth:Math.max(0,e.half||0),sourceOrder:i,...e.partitionHost?{partitionHost:e.partitionHost}:{}})}),[...t.values()]}function Gf(e,t){if(Math.abs(e.distance-t.distance)>1e-9)return e.distance-t.distance;if(Math.abs(e.perpendicular-t.perpendicular)>1e-9)return e.perpendicular-t.perpendicular;return(e.target.segmentKeyt.target.segmentKey?1:0)||e.target.sourceOrder-t.target.sourceOrder}function Vf(e){const t=Uf(e.intervals).map(t=>{const i=function(e,t){const i=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,a=(e[0]-t.a[0])*o+(e[1]-t.a[1])*s,l=Math.max(0,Math.min(r,a)),c=t.a[0]+l*o,h=t.a[1]+l*s;return{along:l,length:r,x:c,y:h,distance:Math.hypot(e[0]-c,e[1]-h),perpendicular:Math.abs((e[0]-t.a[0])*s-(e[1]-t.a[1])*o)}}(e.pointer,t);return{target:t,...i,envelope:Math.max(e.baseTolerance,t.physicalHalfWidth+e.bodyPointerPadding)}}).filter(e=>e.distance<=e.envelope+1e-9).filter(t=>!function(e,t,i,n,r){const o=t.b[0]-t.a[0],s=t.b[1]-t.a[1],a=Math.hypot(o,s);if(!(a>1e-9))return!1;const l=o/a,c=s/a;for(const o of i){if(!o.open&&o.kind)continue;const i=Wf(o.a,o.b),s=i.b[0]-i.a[0],a=i.b[1]-i.a[1],h=Math.hypot(s,a);if(!(h>1e-9))continue;const d=s/h,u=a/h;if(Math.abs(l*u-c*d)>1e-6)continue;if(Math.abs((i.a[0]-t.a[0])*c-(i.a[1]-t.a[1])*l)>r)continue;const p=(e[0]-i.a[0])*d+(e[1]-i.a[1])*u,_=1e-9;if(!(p<=_||p>=h-_)&&Math.abs((e[0]-i.a[0])*u-(e[1]-i.a[1])*d)<=n+1e-9)return!0}return!1}(e.pointer,t.target,e.intervals,t.envelope,Math.max(1e-9,Math.min(e.baseTolerance,.04*e.gridStep)))),i=t.filter(t=>!!t.target.partitionHost&&e.renderedLength+2*t.target.physicalHalfWidth>t.length+1e-9).sort(Gf),n=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(Gf);let r=n[0];if(!r)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=n.filter(e=>Math.abs(e.distance-r.distance)<=1e-9&&Math.abs(e.perpendicular-r.perpendicular)<=1e-9),s=o.filter(e=>e.target.partitionHost);if(s.length){if(1!==new Set(s.map(e=>e.target.partitionHost.id)).size||s.some(e=>e.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const e=s[0],t=e.target.b[0]-e.target.a[0],i=e.target.b[1]-e.target.a[1],n=Math.hypot(t,i),a=t/n,l=i/n;if(!o.every(t=>{const i=t.target.b[0]-t.target.a[0],n=t.target.b[1]-t.target.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,c=Math.abs(a*s-l*o)<=1e-6,h=Math.abs((t.target.a[0]-e.target.a[0])*l-(t.target.a[1]-e.target.a[1])*a);return c&&h<=1e-9}))return{candidate:null,jambBlockedTarget:null};r=e}if(r.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:a,length:l}=r,c=a.b[0]-a.a[0],h=a.b[1]-a.a[1],d=c/l,u=h/l,p=a.partitionHost?a.physicalHalfWidth:0,_=Math.min(Math.max(0,e.renderedLength)/2+p,l/2);let m=r.along;const g=Math.max(e.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=a.a[0]+d*m,y=a.a[1]+u*m,b=Math.max(0,e.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),S=Math.max(0,l-k),$=[a.a[0]+d*(w-x/2),a.a[1]+u*(w-x/2)],M=[a.a[0]+d*(k+S/2),a.a[1]+u*(k+S/2)];let R=180*Math.atan2(h,c)/Math.PI;R>=90?R-=180:R<-90&&(R+=180);const C=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:e.preset.revision,geometryRevision:e.geometryRevision,pointer:[e.pointer[0],e.pointer[1]],type:e.preset.type,lengthCm:e.preset.lengthCm,flipH:e.preset.flipH,flipV:e.preset.flipV,x:v,y:y,angle:R,renderedLength:e.renderedLength,target:a,...a.partitionHost?{host:{...a.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:$},{distance:S,midpoint:M}],guide:C?{x:v,y:y,angle:R}:null}},jambBlockedTarget:null}}function Kf(e,t,i,n,r=1e-6){return e.presetRevision===i&&e.geometryRevision===n&&Math.hypot(e.pointer[0]-t[0],e.pointer[1]-t[1])<=r}function Yf(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}class Xf{constructor(e,t,i){this.loader=e,this.host=t,this.adopted=i,this.attachment=null}connect(){if(this.runtime)return void this.runtime.connect();this.attachment?.cancel();const e=this.loader.attach(this.host,e=>this.adopt(e));this.runtime||(this.attachment=e)}disconnect(){this.attachment?.cancel(),this.attachment=null,this.runtime?.disconnect()}adopt(e){this.attachment=null,this.runtime||(this.runtime=e,this.adopted(e))}}const Zf=new class{constructor(e){this.load=e,this.factory=null,this.pending=null}get warm(){return null!==this.factory}create(e){return this.factory?this.factory(e):null}attach(e,t){let i=!0;const n={cancel:()=>{i=!1}},r=this.create(e);return r?(t(r),n):(this.ensure().then(n=>{i&&t(n(e))},()=>{}),n)}ensure(){return this.factory?Promise.resolve(this.factory):(this.pending||(this.pending=this.load().then(e=>(this.factory=e,this.pending=null,e),e=>{throw this.pending=null,e})),this.pending)}reset(){this.factory=null,this.pending=null}}(()=>import("./summary-panel-runtime-loaded-BcKBuVQ7.js").then(function(e){return e.e}).then(({LoadedSummaryPanelRuntime:e})=>t=>new e(t)));function Jf(e){const t=globalThis.__HP_VERSION_OVERRIDE__;return"string"==typeof t&&t.length>0?t:e}let Qf=0;const ev="1.76.0-beta.3",tv="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e",iv=1500,nv=new Map;let rv=0,ov=1e4;const sv="houseplan_card_layout_v1",av="houseplan_card_cfg_v1",lv="houseplan_card_zoom_v1",cv="houseplan_card_nav_v1",hv="houseplan_card_view_v1",dv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",uv=1e3,pv=(e,t)=>{const i=Math.min(e.x,t.x),n=Math.min(e.y,t.y);return{x:i,y:n,w:Math.max(e.x+e.w,t.x+t.w)-i,h:Math.max(e.y+e.h,t.y+t.h)-n}},_v=(e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)},mv=e=>{history.pushState(null,"",e),_v(window,"location-changed",{replace:!1})},gv=(e,t)=>{let i,n=null;const r=(...r)=>{clearTimeout(i),n=r,i=window.setTimeout(()=>{i=void 0;const t=n;n=null,t&&e(...t)},t)};return r.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const t=n;n=null,t&&e(...t)},r.cancel=()=>{clearTimeout(i),i=void 0,n=null},r.pending=()=>void 0!==i,r},fv=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}},vv=["edges","corners"];class yv extends he{constructor(){var e;super(...arguments),this._editorRuntime=null,this._liveRt=null,this._onboardingRuntime=null,this._editorRuntimeLoadingVisible=!1,this._backdropGuard=null,this._editorModeRequest=0,this._warmModeRequest=0,this._editorRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./houseplan-editor-runtime-BNMtEwiN.js"):await import((()=>{const e=new URL("./houseplan-editor-runtime-BNMtEwiN.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.EDITOR_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanEditorRuntime(this)}},install:e=>{this._editorRuntime=e},stateChanged:e=>this._editorRuntimeStateChanged(e),failed:(e,t)=>{console.error("[houseplan] unable to load editor runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(bf(e=>this._t(e),t))}}),this._onboardingRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./houseplan-onboarding-runtime-D2XH4RQC.js"):await import((()=>{const e=new URL("./houseplan-onboarding-runtime-D2XH4RQC.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.ONBOARDING_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanOnboardingRuntime(this)}},install:e=>{this._onboardingRuntime=e},failed:(e,t)=>{console.error("[houseplan] unable to load onboarding runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(bf(e=>this._t(e),t))}}),this._isoSceneRuntime=null,this._isoSceneRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./iso-scene-render-ceJKJKhC.js"):await import((()=>{const e=new URL("./iso-scene-render-ceJKJKhC.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.ISO_SCENE_RUNTIME_FINGERPRINT,create:()=>t}},install:e=>{const t=this._effectiveProjection();this._isoSceneRuntime=e,this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i),this.isConnected&&this.requestUpdate()},failed:(e,t)=>{console.warn("[houseplan] hidden isometric runtime diagnostic",yf("runtime-load","unverified",t.terminal)),this.isConnected&&this.requestUpdate()}}),this._pdfRuntime=null,this._pdfRuntimeLoader=new kf({expectedFingerprint:tv,load:async e=>{const t=0===e?await import("./pdf-export-BAtsOfAV.js"):await import((()=>{const e=new URL("./pdf-export-BAtsOfAV.js",import.meta.url);return e.searchParams.set("hp_retry",`${ev}-${++Qf}`),e.href})());return{fingerprint:t.PDF_EXPORT_FINGERPRINT,create:()=>new t.PdfExportRuntime}},install:e=>{this._pdfRuntime=e,this.isConnected&&this.requestUpdate()},failed:(e,t)=>{if(console.error("[houseplan] unable to load PDF export runtime",e),!t.terminal||!this._versionRecovery.hasCurrentMismatchNotice){const e=bf(e=>this._t(e),t),i=this._t("editor.load_failed"),n=e.startsWith(i)?e.slice(i.length).trim():e;this._showToast(`${this._t("pdf.failed")} ${n}`.trim())}}}),this.panelHost=!1,this.narrow=null,this._space="f1",this._adoption=new Lu((e,t)=>this.requestUpdate(e,t)),this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._configReloadAuthority=new Wu,this._virtualLights=Eh(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._areaRelocationIds=new Set,this._areaSnapshotCleanupCandidates=new Map,this._areaRelocationSyncKey="",this._areaRelocationWrite=Promise.resolve(),this._tip=null,this._hoverRoom=null,this._pointerModality=new rg(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...xr},this._decorStyleSeeded=!1,this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._decorImagePalette=null,this._decorAssetCatalog=[],this._decorAssets=new Map,this._decorAssetBusy=!1,this._furnCategory=null,this._furnPreviewInput=null,this._furnTouchPending=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this._cancelDevicePressFeedback(),e.matches&&this._cancelCameraTransition(!0),e.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:e.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this._syncVersionRecovery(),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new jg({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._cameraTransitionFit=null,this._cameraTransition=new Zg({frame:e=>this._applyCameraTransitionFrame(e),settled:e=>this._settleCameraTransition(e)}),this._editorSecondaryCopy={groupActive:(e,t)=>this._t("editor.group_active",{group:e,item:t}),openGroup:e=>this._t("editor.open_group",{group:e}),disabledAction:(e,t)=>this._t("editor.disabled_action",{action:e,reason:t})},this._tool="draw",this._geometryHistory=new _g(50),this._devicePositionHistory=new _g(50),this._devicePositionBusy=!1,this._wallDialog=null,this._drawWallField=null,this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainRedo=[],this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._renderIsoScene=null,this._isoProjectionSnapshot=null,this._isoStructuralBuildCount=0,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowRuntimeState=vm(),this._glowRuntimeHost={window:()=>this.ownerDocument.defaultView||window,isConnected:()=>this.isConnected,requestUpdate:()=>this.requestUpdate(),reducedMotion:()=>this._reducedMotion},this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszLimitViolation=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempMin="",this._roomTempMax="",this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._roomFocus=null,this._roomPointer=null,this._doubleFit=new mf,this._deviceHits=new yc,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._viewportGestureDirty=!1,this._touchContacts=new Map,this._touchClickGuard=new dc,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:e=>this._guardTouchGesture(e)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._dangerConfirm=null,this._dangerConfirmController=new ze(e=>{this._dangerConfirm=e}),this._confirmDanger=e=>this._config&&this.hass?"warm"===this._syncDangerConfirmLocaleGate()||this._dangerConfirmMissingSpace()?Promise.resolve(!1):this._dangerConfirmController.confirm(e):Promise.resolve(!1),this._cancelDangerConfirm=()=>{this._dangerConfirmController.cancel()},this._onDangerConfirmDecision=e=>{this._dangerConfirmController.resolve(e.detail.token,e.detail.accepted)},this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._versionRecovery=(e=this,new yg({clock:{setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e)},storage:()=>e.ownerDocument.defaultView?.sessionStorage??null,safety:()=>kg(e),reload:()=>e._reloadDocument(),changed:()=>{e.requestUpdate()}})),this._haSupportApi=null,this._haDecorAssetsApi=null,this._haSummaryPanelApi=null,this._haRadarStage1Api=null,this._radarLive=new Tg(this),this._decorAssetSyncToken=0,this._alignDialog=null,this._settingsDialog=null,this._pdfDialog=!1,this._supportDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=e=>this._onKey(e),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++rv,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={alpha:!1,active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._summarySlot=new Xf(Zf,this,e=>{this._summary=e,this._capturedSnapshotSequence=-1,this.isConnected&&(e.connect(),this.hasUpdated&&this.requestUpdate())}),this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),this._summary?.visibility(e.kind),"hidden"===e.kind)return this._radarLive.stop(),this._editorRuntime?._cancelRadarSetup(),this._clearRoomFocus(!0),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._cancelCameraTransition(!0),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,this._syncRadarLive(),!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+Qm)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._onLabsSnapshot=e=>{const t=this._effectiveProjection();this._labs=e,this._isoProjectionSnapshot=null,this._labsIso&&this._ensureIsoSceneRuntime();const i=this._effectiveProjection();this._convertProjectionView(t,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const e=this._hashSpace();if(e&&this._model.find(t=>t.id===e)&&e!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._deviceDrag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._cfgEpochPreservedConfig=null,this._terminalFrame=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._renderLife=new xg,this._liveEditorPaintCount=0,this._onHaRegistryUpdate=()=>{const e=td(this.hass);e.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=e.revision,this._renderLife.invalidate(),this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,ed(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new hc(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=gv(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=vo(this._layout[t]);e&&(this._layout={...this._layout,[t]:e},this._sentPos.set(t,e),this.hass.callWS({type:"houseplan/layout/update",device_id:t,pos:e}).then(e=>this._noteLayoutRev(e)).catch(e=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))).finally(()=>{this._sentPos.get(t)===e&&this._sentPos.delete(t)}))}this._cacheSnapshot()}else this._persistLocalLayout()},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>this._editorRuntimeOrThrow()._undoGeometry(),this._redoGeometry=()=>this._editorRuntimeOrThrow()._redoGeometry(),this._saveConfigDebounced=gv(()=>{this._serverCfg&&this._writeConfig().catch(e=>{const t=!0===e?.physicalGeometryRolledBack;"geometry-unsafe"!==e?.code&&("wall_model_client_outdated"===e?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===e?.code?(this._showToast(this._t("toast.conflict")),t||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)})),t&&this._reloadRejectedPhysicalWrite())})},500),this._wallChainSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>this._editorRuntimeOrThrow()._savePhysicalDialog(),this._deletePhysicalSelection=()=>this._editorRuntimeOrThrow()._deletePhysicalSelection(),this._confirmPartitionDelete=()=>this._editorRuntimeOrThrow()._confirmPartitionDelete(),this._confirmRoomDelete=e=>this._editorRuntimeOrThrow()._confirmRoomDelete(e),this._rebindPartitionOpening=()=>this._editorRuntimeOrThrow()._rebindPartitionOpening(),this._keepClosedAsPartitions=()=>this._editorRuntimeOrThrow()._keepClosedAsPartitions(),this._toggleServerPlans=async()=>this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._toggleServerPlans():this._editorRuntimeOrThrow()._toggleServerPlans(),this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=ar(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(this._editorRuntime)return this._editorRuntime._openSettingsDialog();this._ensureEditorRuntime().then(e=>{e&&this._openSettingsDialog()})},this._openSupportDialog=()=>{this._editorRuntime?this._editorRuntime._openSupportDialog():this._ensureEditorRuntime().then(e=>{e&&this._openSupportDialog()})},this._openPdfDialog=()=>{this._pdfRuntimeLoader.ensure().then(e=>{e&&(this._pdfDialog=!0,this.requestUpdate())})},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._editorRuntimeOrThrow()._openAlignDialog(),this._toggleOptimizeLivePositions=()=>this._editorRuntimeOrThrow()._toggleOptimizeLivePositions(),this._optimizeUndoBusy=!1,this._openBackupExport=()=>this._editorRuntimeOrThrow()._openBackupExport(),this._openRulesDialog=()=>this._editorRuntimeOrThrow()._openRulesDialog(),this._climateCache=null,this._gearPtCache=new WeakMap}requestUpdate(e,t,i){if("hass"===e&&this.hass&&this._liveRt){const e=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;if(!this._liveRt.hass(t,this.hass,e?{entityIds:e.entityIds}:null,()=>Sg(this))&&!this._summary?.observeHassComposition())return}void 0!==e&&(this._terminalFrame=0),this._editorRuntime?._routeLiveEditorUpdate(e,t)||(this._liveRt?.clear(),super.requestUpdate(e,t,i))}_editorRuntimeOrThrow(){if(!this._editorRuntime)throw new Error("Houseplan editor runtime is not loaded");return this._editorRuntime}async _ensureEditorRuntime(){return this._editorRuntimeLoader.ensure()}async _ensureOnboardingRuntime(){return this._onboardingRuntimeLoader.ensure()}async _ensureIsoSceneRuntime(){return this._isoSceneRuntimeLoader.ensure()}_editorRuntimeStateChanged(e){clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,"loading"!==e?(this._editorRuntimeLoadingVisible=!1,this.requestUpdate()):this._editorRuntimeLoadingTimer=window.setTimeout(()=>{this._editorRuntimeLoadingVisible=!0,this.requestUpdate()},150)}async _requestMode(e,t=!0,i=!1){const n=++this._editorModeRequest;if(i&&(this._warmModeRequest=n,this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null),"view"===e||await this._ensureEditorRuntime()){if(n===this._editorModeRequest&&this.isConnected)return i?(this._adoptMode(e),this._warmRevivePending&&(clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmReviveDialog()),this.requestUpdate(),void this.updateComplete.then(()=>requestAnimationFrame(()=>requestAnimationFrame(()=>{if(this._warmModeRequest!==n||n!==this._editorModeRequest)return;const e=this._stageEl;this._lastValidStageSize=e&&e.clientWidth>0&&e.clientHeight>0?[e.clientWidth,e.clientHeight]:null,this._pendingRefitSize=null,this._warmModeRequest=0})))):void this._setMode(e,t);this._warmModeRequest===n&&(this._warmModeRequest=0)}else this._warmModeRequest===n&&(this._warmModeRequest=0)}get _layout(){return this._adoption.layout}set _layout(e){this._adoption.stageLocalLayout(e)}get _layoutRev(){return this._adoption.layoutRev}set _layoutRev(e){this._adoption.seedIdentity({layoutRev:e})}get _layoutContentFingerprint(){return this._adoption.layoutFingerprint}set _layoutContentFingerprint(e){this._adoption.seedIdentity({layoutFingerprint:e})}get _serverCfg(){return this._adoption.config}set _serverCfg(e){this._adoption.stageLocalConfig(e)}get _cfgRev(){return this._adoption.configRev}set _cfgRev(e){this._adoption.seedIdentity({configRev:e})}get _cfgContentFingerprint(){return this._adoption.configFingerprint}set _cfgContentFingerprint(e){this._adoption.seedIdentity({configFingerprint:e})}_seedDecorStyle(e){var t,i;if(t=Al,i=this,Cl(e,Nl)&&"pending"===t.state()&&(t.art("",i),t.ensure()),this._decorStyleSeeded||!e)return;this._decorStyleSeeded=!0;const n=e.settings?.decor_default_style;n&&(this._decorStyle=function(e,t){if(!e||"object"!=typeof e)return{...t};const i=e,n="string"==typeof i.color&&i.color?i.color:t.color,r="string"==typeof i.fill_color&&i.fill_color?i.fill_color:t.fillColor,o=Number(i.width_cm);return{color:n,opacity:Sr(i.opacity,t.opacity),widthCm:Number.isFinite(o)&&o>0?Math.max(.1,Math.min(100,o)):t.widthCm,fill:"boolean"==typeof i.fill?i.fill:t.fill,fillColor:r,fillOpacity:Sr(i.fill_opacity,t.fillOpacity)}}(n,xr))}get _canManageConfiguration(){return null!==this._serverCanWrite?this._serverCanWrite:!0===this.hass?.user?.is_admin}get _canEdit(){return this._norm&&this._canManageConfiguration}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}get _doubleFitEnabled(){return!("view"!==this._mode||this._vacFit||this._modeTransitionBusy||this._touchSequenceMultitouch||"steady"!==this._continuity.state||this._continuity.overlayBlocksInteraction)}_cameraState(){const e=this._viewOr(this._baseVb());return{zoom:this._zoom,viewBox:{...e}}}_normalizeCameraState(e){const t=this._cameraTransitionFit||Oi(this._baseVb(),this._stageAspect());return{zoom:Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,e.zoom)),viewBox:this._clampView({...e.viewBox},t)}}_applyCameraTransitionFrame(e){const t=this._normalizeCameraState(e.presented);e.presented=t,this._zoom=t.zoom,this._view={...t.viewBox},this._liveVp(!0)}_settleCameraTransition(e){const t=this._normalizeCameraState(e.to);this._zoom=t.zoom,this._view={...t.viewBox},this._cameraTransitionFit=null,"room"!==e.reason&&this._saveZoom(),this.requestUpdate()}_cancelCameraTransition(e=!1,t=!1){const i=this._cameraTransition.state?.reason,n=t&&this._cameraTransition.active?this._cameraTransition.presented?.zoom:void 0;this._cameraTransition.cancel(e),this._cameraTransitionFit=null,void 0!==n&&"room"!==i&&this._saveZoom()}_prepareCameraCommand(){this._bootSoftCancel(),this._modeTransitionBusy&&this._cancelModeTransition(!0),"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1))}_startCameraTransition(e,t,i,n){const r=this._cameraState(),o=this._cameraTransition.target;return(!o||!Kg(o,e))&&(Kg(r,e)?(this._cancelCameraTransition(!1),!1):(this._cameraTransitionFit={...t},this._cameraTransition.start(r,e,i,this._reducedMotion?0:n),!0))}_cssColor(e,t){const i=String(e||"").trim();if(!i)return t;const n=document.createElement("span");n.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(n);const r=getComputedStyle(n).color||t;return n.remove(),r}_currentModeVisual(e=this._mode){const t=this._modeTransition.presented||this._modeTransitionVisual;if(t)return{...t,viewport:{...t.viewport,viewBox:{...t.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const n=this.renderRoot.querySelector(".editorchrome"),r=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),s=this.renderRoot.querySelector(".hp-backdrop"),a=this.renderRoot.querySelector(".zoomwrap"),l=a?getComputedStyle(a).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:e,editorChromeHeight:"view"===e?0:n?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Hg(r,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===e?.35:1,backdropOpacity:s&&Number(getComputedStyle(s).opacity)||1,viewWeight:"view"===e?1:0,editorWeight:"view"===e?0:1,toolbarContentOpacity:"view"===e?0:1}}_viewForModeTarget(e,t,i,n,r){const o=Oi(this._baseVb(),n/r),s=Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,e)),a=o.w/s,l=o.h/s,c=t??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-a/2,y:h-l/2,w:a,h:l},o)}_targetStageColor(e){return"view"!==e?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(e){return"view"===e&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(e){return 1}_applyModeTransitionFrame(e){e.targetMode===this._mode&&(this._modeTransitionVisual=e.presented,this._view={...e.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(e){if(e.targetMode!==this._mode)return;const t=this._modeTransitionRequest;this._view={...e.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[e.to.stageWidth,e.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._modeTransitionBusy||e.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-e.to.stageWidth)>.5||Math.abs(i.clientHeight-e.to.stageHeight)>.5)){const e=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,e?e.x+e.w/2:void 0,e?e.y+e.h/2:void 0),this.requestUpdate()}const n=this.renderRoot.activeElement;(!n||!n.isConnected||!!n.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(e=!0){this._cancelCameraTransition(!1);const t=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(e),e&&t||(this._modeTransitionVisual=null)}_adoptMode(e){e!==this._mode&&(this._clearRoomFocus(!0),this._resetDeviceHitState()),this._cancelModeTransition(!1),this._mode=e,this._isoProjectionSnapshot=null,"view"!==e&&(this._editorChromeMode=e)}_commitViewModeAtomic(e,t,i,n){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=t,e){const r=this._stageEl?.clientWidth||e.stageWidth,o=Math.max(1,e.stageHeight+e.editorChromeHeight);this._view=this._viewForModeTarget(t,i,n,r,o),this._lastValidStageSize=[r,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(e,t,i,n,r,o){this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._mode!==i)return void(e===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const s=this.renderRoot.querySelector(".editorchrome-inner"),a="view"===i?0:s?.scrollHeight||0,l=Math.max(1,(this.panelHost?this.clientHeight:innerHeight)-Jg(this.renderRoot,this._stageEl,this.panelHost)),c=this._stageEl?.clientWidth||t.stageWidth,h=this._viewForModeTarget(n,r,o,c,l),d={presentedMode:i,editorChromeHeight:a,stageWidth:c,stageHeight:l,viewport:Hg(h,c),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const u=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,d,i,this._reducedMotion||u?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(e=this._model,t=this._loadOk){const i=this._config?.floor,n=function(e){if(!e.hasFloor)return{kind:"absent"};const t=e.floor;if("string"==typeof t)return t.length?e.spaceIds.includes(t)?{kind:"valid",id:t,source:"id"}:{kind:"invalid",reason:"unknown-id",value:t}:{kind:"invalid",reason:"empty-id",value:t};if("number"==typeof t){if(!Number.isFinite(t))return{kind:"invalid",reason:"non-finite-index",value:t};if(!Number.isInteger(t))return{kind:"invalid",reason:"fractional-index",value:t};if(t<0)return{kind:"invalid",reason:"negative-index",value:t};const i=e.spaceIds[t];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:t}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:t}}({spaceIds:e.map(e=>e.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||t?n:"number"==typeof i?"valid"===n.kind||"invalid"===n.kind&&"out-of-range-index"===n.reason?{kind:"pending",value:i}:n:"valid"===n.kind||"invalid"===n.kind&&"unknown-id"!==n.reason?n:{kind:"pending",value:i}}_canCommitSpace(e,t=!1){if(t||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===e}_commitSpace(e,t=!1){return!!this._canCommitSpace(e,t)&&(e!==this._space&&(this._clearRoomFocus(!0),this._resetDeviceHitState(),this._cancelDangerConfirm(),this._cancelCameraTransition(!1),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._editorRuntime?._clearFurniturePreview()),this._space=e,this._isoProjectionSnapshot=null,!0)}_slideTo(e,t){if(e===this._space)return!0;if(!this._canCommitSpace(e))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary?.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,this._restoreZoom(),i||(this._slide=t,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Yf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){Yf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(fv(e),this._tabDragRelease=e=>this._tabPointerUp(e),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:t,pointerId:e.pointerId,x:e.clientX,y:e.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(e,t,i){const n=this._model.map(e=>e.id),r=n.indexOf(i);if(r<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const s of o){const o=s.dataset.id||"";if(!o||o===i)continue;const a=s.getBoundingClientRect();if(ea.right||ta.bottom)continue;const l=n.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,n;const r=this._tabDropTargetAt(e.clientX,e.clientY,t.id);t.moved&&t.targetId===r?.targetId&&t.placement===r?.placement||(this._tabDrag={...t,moved:!0,targetId:r?.targetId||null,placement:r?.placement||null})}_tabPointerUp(e){const t=this._tabDrag;if(t&&t.pointerId!==e.pointerId)return;const i="pointerup"===e.type&&t?.moved?this._tabDropTargetAt(e.clientX,e.clientY,t.id):null;"pointerup"===e.type&&t?.moved&&this._suppressNextTabClick(),this._endTabDrag(),t?.moved&&i&&this._commitTabOrder(t.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(e){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(e)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(e,t){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const n=this._model.map(e=>e.id),r=function(e,t,i){const n=e.indexOf(t),r=e.indexOf(i);if(n<0||r<0||n===r)return e;const o=e.slice();return o.splice(n,1),o.splice(r,0,t),o}(n,e,t);if(r===n)return;const o=new Map(this._devices.map(e=>[String(e.id),String(e.area||"")])),s=function(e,t,i,n=()=>""){if(!i)return[];const r=[];for(const o of e){if(!o||!0===o.removed)continue;const e="string"==typeof o.id?o.id:"";if(!e)continue;if("string"==typeof o.space&&o.space)continue;const s=("string"==typeof o.area?o.area:"")||n(e)||"";s&&t[s]||r.push({id:e,space:i})}return r}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),n[0]||"",e=>o.get(e)||"");if(s.length){const e=new Map(s.map(e=>[e.id,e.space]));for(const t of i.markers||[]){const i=e.get(String(t.id));i&&(t.space=i)}}i.spaces=function(e,t){const i=new Map(t.map((e,t)=>[e,t]));return e.map((e,t)=>({space:e,index:t})).sort((e,t)=>(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)||e.index-t.index).map(e=>e.space)}(i.spaces||[],r),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(e){if(this._endTabDrag(),e===this._space)return;const t=this._model.map(e=>e.id),i=t.indexOf(this._space),n=t.indexOf(e);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(e,i>=0&&n0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const e=this._model.map(e=>e.id),t=e.indexOf(this._space);this._slideTo(e[(t+1)%e.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(e){this._wallUnionCacheValue=e,null===e&&this._wallUnionPool.clear()}get _glowClipCache(){return this._glowRuntimeState.clipCache}get _glowGeometryWarnings(){return this._glowRuntimeState.geometryWarnings}get _glowFeatherUnits(){return this._glowRuntimeState.featherUnits}set _glowFeatherUnits(e){this._glowRuntimeState.featherUnits=e}get _glowRenderedSources(){return this._glowRuntimeState.renderedSources}get _glowLastAppearance(){return this._glowRuntimeState.lastAppearance}get _glowFeatherSuspendUntil(){return this._glowRuntimeState.featherSuspendUntil}set _glowFeatherSuspendUntil(e){this._glowRuntimeState.featherSuspendUntil=e}get _glowFeatherResumeTimer(){return this._glowRuntimeState.featherResumeTimer}set _glowFeatherResumeTimer(e){this._glowRuntimeState.featherResumeTimer=e}get _glowSourceSeq(){return this._glowRuntimeState.sourceSeq}set _glowSourceSeq(e){this._glowRuntimeState.sourceSeq=e}get _touchSequenceMultitouch(){return this._touchClickGuard.sequenceMultitouch}_syncDangerConfirmLocaleGate(){return this._config&&this.hass?cp(this,_p,bp(this.hass,this._config.language)):"ready"}_dangerConfirmMissingSpace(){const e=this._model;if(!e.length)return!1;const t=this._fixedFloorState(e);return"pending"!==t.kind&&"invalid"!==t.kind&&!this._spaceModel()}_syncVersionRecovery(){this._versionRecovery.update({frontendVersion:Jf(ev),backendVersion:this._haIntegrationVersion,kiosk:!0===this._config?.kiosk,reducedMotion:this._reducedMotion})}_newContinuityController(){return new sc(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(hv,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(e){const t=this._view;if(!t)return null;const i=[t.x+t.w/2,t.y+t.h/2],n="iso"===e?af(i):i;return{x:n[0],y:n[1]}}_convertProjectionView(e,t){if(e===t)return;this._clearRoomFocus(!0);const i=this._logicalViewCenter(e);this._view=null;const n=i?"iso"===t?sf([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,n?.[0],n?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(e){if(!this._labsIso||"view"!==this._mode)return;const t=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:e},"iso"===e){this._ensureIsoSceneRuntime();const e=this._isoSceneKey();e&&this._isoFallback.delete(e),this._isoFallback.delete(`${this._space}|no-borders`),this._clearIsoInvalidFallback()}this._saveViewPreference(),this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i)}_hashSpace(){return Af(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,this._configReloadAuthority.observeContext(Uu(this)),window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const e=cg(this.ownerDocument);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=rc(this.ownerDocument,this._pageVisibility),this._languageFailureUnsub?.(),this._languageFailureUnsub=function(...e){return()=>{for(const t of e)t()}}((t=()=>{this._showToast(this._t("toast.locale_load_failed"))},pp.add(t),()=>pp.delete(t)),function(e){return Dl.add(e),()=>{Dl.delete(e)}}(()=>this._showToast(this._t("toast.furniture_art_load_failed")))),super.connectedCallback(),this._summarySlot.connect(),this._ensureLiveRuntime().catch(()=>this.requestUpdate()),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{let t=!1;for(const i of e){for(const e of i.addedNodes)this._syncPointerHoverSubtree(e);const e=e=>{if(e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e;return t.matches(".devlayer, .devlayer *")||!!t.querySelector?.(".devlayer")};(e(i.target)||[...i.addedNodes,...i.removedNodes].some(e))&&(t=!0)}t&&this._invalidateDeviceHitGeometry()}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","data-id"]})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._syncVersionRecovery(),this._versionRecovery.connect(),lg(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>this._referencedContentUrls()),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(e){Of.add(e);const t=Hf();return"undefined"==typeof window&&e(t),()=>{Of.delete(e)}}(this._onLabsSnapshot),this._labsIso&&this._ensureIsoSceneRuntime(),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},iv)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._versionRecovery.disconnect(),this._configReloadAuthority.invalidateLifecycle(),this._liveRt?.dispose(),this._radarLive.stop(),this._editorRuntime?._disposeLiveEditor(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._languageFailureUnsub?.(),this._languageFailureUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._warmModeRequest=0,this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._summarySlot.disconnect(),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const e of this._activityRt.values())clearTimeout(e.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,this._editorRuntimeLoadingVisible=!1,this._modeTransition.dispose(),this._cameraTransition.dispose(),this._cameraTransitionFit=null,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),this._cancelDeviceDrag(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer),Am(this._glowRuntimeState,this._glowRuntimeHost),this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._touchContacts.clear(),this._touchClickGuard.reset(),this._resetDeviceHitState(),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary?.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(e){if("Escape"===e.key&&this._vacFit){if(this._vacFit.busy)return;return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void e.stopPropagation()}if("Escape"===e.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm.busy||(this._vacCalConfirm=null));if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._pdfDialog)return void(this._pdfDialog=!1);if(this._supportDialog)return void this._editorRuntime?._closeSupportDialog();if(this._settingsDialog)return void(this._settingsDialog=null);if(this._summary?.closeDialogIfIdle())return;if(this._markerDialog)return void this._closeMarkerDialog();if(this._deviceInbox)return void(this._deviceInbox=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary?.hasOpenGroup)return e.preventDefault(),void this._editorSecondary?.closeGroup(!0)}const t=e.composedPath?.()||[e.target],i=t.some(e=>e?.matches?.('input, textarea, select, [contenteditable="true"]')),n=t.some(e=>e?.classList?.contains?.("editor-secondary")),r=e.ctrlKey||e.metaKey,o=e.key.toLowerCase(),s=/^[a-z]$/.test(o),a="z"===o||!s&&"KeyZ"===e.code,l="y"===o||!s&&"KeyY"===e.code,c=r&&(a&&e.shiftKey||l),h=r&&a&&!e.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry();if(("Delete"===e.key||"Backspace"===e.key)&&this._decorSel&&!i&&!n)return e.preventDefault(),void this._decorDeleteSel();const t="ArrowLeft"===e.key?[-this._gridPitch,0]:"ArrowRight"===e.key?[this._gridPitch,0]:"ArrowUp"===e.key?[0,-this._gridPitch]:"ArrowDown"===e.key?[0,this._gridPitch]:null;return!t||r||e.altKey||"select"!==this._decorTool||!this._decorSel||!this._decorList.some(e=>e.id===this._decorSel)||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag||i||n||this._editorSecondaryDialogBlocked?void("Escape"===e.key&&(e.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._furnPalette=null,this._furnCategory=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(e.preventDefault(),void this._decorNudge(t[0],t[1]))}if("devices"===this._mode){if((h||c)&&i)return;return c?(e.preventDefault(),void this._redoDevicePosition()):h?(e.preventDefault(),void this._undoDevicePosition()):void("Escape"===e.key&&this._deviceDrag&&(e.preventDefault(),this._cancelDeviceDrag()))}if(this._markup&&(!h&&!c||!i)){if(("Delete"===e.key||"Backspace"===e.key)&&this._physicalSel&&!i&&!n)return e.preventDefault(),void this._deletePhysicalSelection();if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===e.key)return this._physicalDrag||this._physicalRotate?(e.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(e.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(e.preventDefault(),void this._finishWallChain()):this._physicalSel?(e.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():("exit-tool"===this._resize?.escapeIdle()&&(this._tool="draw"),void this.requestUpdate())):"split"===this._tool?(e.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(e.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(e.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(e.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length)return this._contourClosed?(this._path=this._path.slice(0,-1),void(this._closingWallCm=null)):void(this._activeWallChainPartitionIds.length&&this._path.length>1?this._undoActiveWallPoint():this._path=this._path.slice(0,-1))}_undoActiveWallPoint(){const e=[...this._activeWallChainPartitionIds],t=e[e.length-1],i=this._spaceModel()?.partitions.find(e=>e.id===t),n=this._path[0]?[...this._path[0]]:null,r=this._path.slice(0,-1).map(e=>[...e]),o=this._wallChainSegmentCms.slice(0,-1),s=this._geometryHistory.undo();if(!s)return this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._wallChainRedo=[],void(this._path=n?[n]:[]);this._applyGeometryState(s.before,!0)?(this._activeWallChainId||=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=e.slice(0,-1),this._path=r.length?r:n?[n]:[],this._wallChainSegmentCms=o,i&&this._wallChainRedo.push({id:i.id,point:[...i.b],cm:i.cm}),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:s.name}))):this._geometryHistory.clear()}static async getConfigElement(){return await import("./editor-C5Zq-3aA.js"),document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of nv.values())for(const t of e)clearTimeout(t.evict);nv.clear(),ov=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const n of nv.values())for(const r of n)e++,r.dlg&&(t++,i.push(r.dlg.kind));return{keys:nv.size,slots:e,dlgs:t,drafts:i}}setConfig(e){const t=this._config,i=!!t&&Object.prototype.hasOwnProperty.call(t,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...e};(i!==this._hasFixedFloor||t?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&e.default_floor&&this._commitSpace(e.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(lv)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(hv)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}if(this._labs=Hf(),this.isConnected&&this._labsIso&&this._ensureIsoSceneRuntime(),!this._summary?.applyLocalScaleForCurrentIdentity())try{const e=JSON.parse(localStorage.getItem("houseplan_card_kiosk_v1")||"null");this._kioskScale={icon:Bn(e?.icon),font:Bn(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(av)||"null");this._adoption.restoreCached(e)&&(this._seedDecorStyle(this._serverCfg),this._cfgEpoch++,this._virtualLights=Eh(e.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1),this._syncVersionRecovery()}_warmAdopt(){if(this._config?.kiosk)return;const e=Mf(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),n=nv.get(e);if(!n||!n.length)return;const r=n.find(e=>e.owner===this._warmGen);if(r)return this._warmLongReturn=!!r.freed&&Date.now()-r.freed>=tc,clearTimeout(r.evict),r.evict=0,r.freed=0,r.live=!0,this._warmSlot=r,this._warmKey=e,r.frameFingerprint&&this._continuity.adoptCompleteFrame(r.frameFingerprint),void(!this._devices.length&&r.devices?.length&&(this._devices=[...r.devices]));const{slot:o,sure:s}=((e,t,i,n)=>{const r=e=>{const t=!!i&&e.place?.deref()===i;return t&&e.idx===n?4:e.live?0:t?3:2};let o=null,s=0,a=0,l=null;for(const i of e){if(i.owner===t)continue;l=i;const e=r(i);e<=0||(e>s?(o=i,s=e,a=1):e===s&&a++)}return!o||a>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(n,this._warmGen,t,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=tc,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},iv)),this._warmKey=e,s?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=t?new WeakRef(t):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},n.push(this._warmSlot),this._warmTrim(n)))}_warmIdx(e){const t=e?.children;if(!t)return-1;for(let e=0;e4;){const t=e.findIndex(e=>!e.live);if(t<0)break;clearTimeout(e[t].evict),e.splice(t,1)}}_warmScheduleEvict(e,t){if(clearTimeout(e.evict),!(e.dlg||e.vp&&"view"!==e.vp.mode))return;const i=e.freed,n=e.owner;e.evict=window.setTimeout(()=>{if(e.evict=0,e.freed!==i||e.owner!==n)return;var r;e.dlg=null,e.vp=(r=e.vp)&&"view"!==r.mode?{...r,mode:"view",zoom:r.snap?.space===r.space?r.snap.zoom:r.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:r,e.frameFingerprint="";const o=nv.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},ov+250)}_warmAdoptViewport(e){const t=this._warmVp;if(!t||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(e=>e.id===t.space)||"valid"===i.kind&&i.id!==t.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(t.space,!0),this._navApplied=!0;const n="view"!==t.mode&&this._canEdit&&!e.kiosk?t.mode:"view";this._adoptMode("view"),this._pendingNavMode="view"===t.mode||this._canEdit||e.kiosk?null:t.mode,this._zoom=t.zoom;const r=this._effectiveProjection(),o=r===t.projection&&this._labsIso===t.activeLabsIso;if(this._view=o&&t.view?{...t.view}:null,this._viewModeSnap=o&&t.snap?{...t.snap}:null,!o&&t.logicalCenter){const e="iso"===r?sf([t.logicalCenter.x,t.logicalCenter.y],0):[t.logicalCenter.x,t.logicalCenter.y];this._applyView(t.zoom,e[0],e[1])}var s;this._tool="opening"===(s=function(e){return"partition"===e?"draw":e}(s=t.tool))?"draw":"string"==typeof s&&$f.has(s)?s:"draw",this._decorTool=t.decorTool,this._showHidden=t.showHidden,this._showFar!==t.showFar&&(this._showFar=t.showFar,this._frame=null),this._selId=t.selId,this._resize?.restoreSelection(t.rszSel),this._decorSel=t.decorSel,this._warmVpArmed=!0,"view"!==n&&this._requestMode(n,!1,!0)}_warmPatch(e,t=!1){if(this._config?.kiosk)return;const i=Mf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!t)return;const e=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:this._warmIdx(e),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const n=nv.get(i)||[];for(n.push(this._warmSlot),nv.set(i,n),this._warmTrim(n);nv.size>8;){const e=nv.keys().next().value;if(void 0===e||e===i)break;for(const t of nv.get(e)||[])clearTimeout(t.evict);nv.delete(e)}}Object.assign(this._warmSlot,e)}}_warmViewportState(){const e=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:e,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(e),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._resize?.selectedRoomId,decorSel:this._decorSel}}_warmDialogState(){const e=(e,t)=>({kind:e,space:this._space,mode:this._mode,data:t});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?e("openingInfo",this._openingInfo.id):this._infoCard?e("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:e("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:e("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:e("marker",this._markerDialog):this._openingDialog?e("opening",this._openingDialog):this._backdropDialog?e("backdrop",this._backdropDialog):this._decorShapeDialog?e("decorShape",this._decorShapeDialog):this._decorTextDialog?e("decorText",this._decorTextDialog):this._roomDialog?e("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempMin:this._roomTempMin,tempMax:this._roomTempMax,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:e("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const e={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices,hdrH:this._hdrH};if(this._warmRevivePending||(e.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const t=this.parentNode;e.place=t?new WeakRef(t):null,e.idx=this._warmIdx(t)}this._warmPatch(e)}_warmReviveDialog(){const e=this._warmSlot;if(this._warmReviveTimer=void 0,!e||!e.dlg)return void(this._warmRevivePending=!1);const t=e.dlg,i=e.freed;if(t.mode===this._mode||"view"===t.mode||this._warmVp?.mode!==t.mode||this._editorRuntime){if(this._warmRevivePending=!1,e.dlg=null,e.freed=0,clearTimeout(e.evict),e.evict=0,i&&!(Date.now()-i>ov)&&t.space===this._space&&t.mode===this._mode){switch(t.kind){case"space":this._spaceDialog={...t.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...t.data,busy:!1};break;case"settings":this._settingsDialog={...t.data,busy:!1};break;case"rules":this._rulesDialog={...t.data,busy:!1};break;case"opening":this._openingDialog={...t.data};break;case"backdrop":this._backdropDialog={...t.data};break;case"decorShape":this._decorShapeDialog={...t.data};break;case"decorText":{this._decorTextDialog={...t.data};const e=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:e,end:e};break}case"room":{const e=t.data;this._roomEditId=e.editId,this._roomFill=e.fill,this._roomCustomFill=e.customFill||null,this._roomTempMin=e.tempMin||"",this._roomTempMax=e.tempMax||"",this._roomTempSrc=e.tempSrc,this._roomHumSrc=e.humSrc,this._roomSrcOpen=e.srcOpen,this._roomSrcFilter=e.srcFilter,this._roomNameScale=e.nameScale,this._roomLabelScale=e.labelScale,this._areaSel=e.areaSel,this._nameSel=e.nameSel,this._pendingSplit=e.pendingSplit,this._wallFaceBatch=e.wallFaceBatch||null,this._path=e.path,this._wallFaceBatch&&(this._activeWallChainId=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=[...this._wallFaceBatch.activePartitionIds],this._wallChainSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const e=this._devices.find(e=>e.id===t.data);e&&(this._infoCard=e);break}case"openingInfo":{const e=(this._curSpaceCfg?.openings||[]).find(e=>e.id===t.data);e&&(this._openingInfo=e);break}}this.requestUpdate()}}else this._warmRevivePending=!0}_cacheSnapshot(){if(this._serverCfg)try{this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const n=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(Lh).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>n.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev);const e=this._adoption.snapshot(function(e){return{rev:e.rev,config_rev:e.configRev,off:[...e.off].sort()}}(this._virtualLights));e&&localStorage.setItem(av,JSON.stringify(e))}catch{}}_beginContinuityCandidate(e,t,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(e,i))}_continuityStageValid(){const e=this._stageEl;return!!e&&e.clientWidth>0&&e.clientHeight>0}_versionReloadSafetySnapshot(){return kg(this)}_continuityAssetsReady(){if(!this._model.length)return!1;const e=this._model.length?this._spaceModel():null;return!e?.bg?.href||this._signer.isReady(this.hass,e.bg.href)}_initialSpaceSelection(e,t=this._loadOk){const i=this._fixedFloorState(e,t);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(e){const t=new Set(e.spaceIds.filter(e=>!!e));if(!t.size)return{id:null,source:"none"};const i=[["hash",!1===e.acceptHash?null:e.hashSpace],["current",e.preserveCurrent?e.currentSpace:null],["saved",e.savedSpace],["default",e.defaultSpace],["first",e.spaceIds[0]]];for(const[e,n]of i)if(n&&t.has(n))return{id:n,source:e};return{id:null,source:"none"}}({spaceIds:e.map(e=>e.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(e,t=this._loadOk){const i=this._initialSpaceSelection(e,t);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(e,t=this._space){const i=Ya(e),n=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==n.kind)return"";const r=this._initialSpaceSelection(i,!0).id||(i.some(e=>e.id===t)?t:i[0]?.id);return i.find(e=>e.id===r)?.bg?.href||""}_visualFrameFingerprint(){const e=this._stageEl,t=e?[e.clientWidth,e.clientHeight]:[0,0];return lc([this._cfgRev,this._adoption.currentConfigFingerprint(),this._layoutRev,this._adoption.currentLayoutFingerprint(),this._space,this._mode,this._view,t,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const e=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==e)return this._stagedDeviceSnapshotToken=e,void this.requestUpdate();this._continuityPaintToken!==e&&(this._continuityPaintToken=e,this._continuity.candidateReady(e)&&this._continuity.commitAfterPaint(e,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(e,t){this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const e="connection"===this._continuity.recoveryReason;return j`
    "houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const _g=o`:host{--hp-editor-tray-bg-fallback:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 94%,var(--hp-line));--hp-editor-tray-bg:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 86%,transparent);--hp-editor-tray-border:color-mix(in srgb,var(--hp-line) 82%,var(--hp-accent));--hp-editor-tray-blur:8px;--hp-editor-tray-shadow:var(--shadow-2);}.editor-secondary-host{position:absolute;inset:var(--sp-2) var(--sp-4) auto;z-index:70;display:flex;justify-content:flex-end;pointer-events:none;}.editor-secondary-host.kind-palette,.editor-secondary-host.kind-group{justify-content:flex-start;}.editor-secondary{pointer-events:none;max-width:100%;display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);color:var(--hp-txt);background:var(--card-background-color,var(--hp-bg));background:var(--hp-editor-tray-bg-fallback);border:1px solid var(--hp-line);border-color:var(--hp-editor-tray-border);border-radius:var(--rad-l);box-shadow:var(--hp-editor-tray-shadow);opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity 0.1s ease,transform 0.1s cubic-bezier(0.2,0.7,0.2,1),visibility 0s linear 0.1s;touch-action:auto;}.editor-secondary-host.open .editor-secondary{pointer-events:auto;opacity:1;visibility:visible;transform:translateY(0);transition-duration:0.14s,0.14s,0s;transition-delay:0s;}.editor-secondary-host.blocked .editor-secondary{pointer-events:none;}@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.editor-secondary{background:var(--hp-editor-tray-bg);-webkit-backdrop-filter:blur(var(--hp-editor-tray-blur));backdrop-filter:blur(var(--hp-editor-tray-blur));}}.editor-secondary-content,.editor-group-items{display:flex;align-items:center;gap:var(--sp-3);min-width:0;}.editor-context-label{max-width:14rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-inline-end:var(--sp-4);border-inline-end:1px solid var(--hp-line);color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary.kind-palette{width:min(760px,100%);align-items:stretch;padding:0;overflow:hidden;}.editor-secondary.kind-palette .editor-secondary-content,.editor-secondary.kind-palette .furnpalette{width:100%;}.editor-secondary.kind-palette .furnpalette{max-height:38vh;border:0;background:transparent;}.editor-group-launcher .group-chevron{--mdc-icon-size:16px;transition:transform 0.14s ease;}.editor-group-launcher[aria-expanded="true"] .group-chevron{transform:rotate(180deg);}.editor-secondary .bdhint{font-size:var(--fs-s);color:var(--hp-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.editor-secondary .dfill{display:inline-flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-s);cursor:pointer;}.editor-secondary .dfill input[type="checkbox"]{width:16px;height:16px;flex:none;margin:0;padding:0;}.editor-secondary hp-color-opacity{flex:0 0 auto;}.editor-secondary input{width:74px;background:transparent;border:1px solid var(--hp-line);color:var(--hp-txt);border-radius:var(--rad-s);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-m);}.editor-secondary label,.editor-secondary .hint{color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary .drawwall{display:inline-flex;align-items:center;gap:var(--sp-3);white-space:nowrap;}.editor-secondary .drawwall input{width:4.2em;}.editor-secondary .drawwall .opl{color:var(--hp-muted);font-size:var(--fs-s);}@container (min-width:560px) and (max-width:899px){.editor-secondary-content,.editor-group-items{flex-wrap:wrap;justify-content:flex-end;}}@container (max-width:559px){.editor-secondary-host{inset-inline:var(--sp-4);}.editor-secondary{max-width:100%;}.editor-secondary-content,.editor-group-items{overflow-x:auto;scrollbar-width:thin;}.editor-secondary-content>*,.editor-group-items>*{flex:none;}.editor-context-label{display:none;}}@media (prefers-reduced-motion:reduce){.editor-secondary{transition:none;}.editor-group-launcher .group-chevron{transition:none;}}`;class mg{constructor(e=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(e))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(e){this._undo.push(e),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const e=this._undo.pop()??null;return e&&this._redo.push(e),e}redo(){const e=this._redo.pop()??null;return e&&this._undo.push(e),e}removeWhere(e){const t=this._undo.length,i=this._redo.length;return this._undo=this._undo.filter(t=>!e(t)),this._redo=this._redo.filter(t=>!e(t)),t+i-this._undo.length-this._redo.length}clear(){this._undo=[],this._redo=[]}}function gg(e,t){const i=e[t];return i&&Number.isFinite(i.x)&&Number.isFinite(i.y)?{x:i.x,y:i.y,..."string"==typeof i.s?{s:i.s}:{}}:null}function fg(e,t,i){if(null===i){if(!(t in e))return e;const i={...e};return delete i[t],i}const n={...e[t]||{}};delete n.x,delete n.y,delete n.s;const r={...n,x:i.x,y:i.y,...void 0!==i.s?{s:i.s}:{}};return{...e,[t]:r}}const vg="houseplan-card:version-reload-target:v1";function yg(e){if("string"!=typeof e)return null;return e.trim()||null}class bg{constructor(e){this.hooks=e,this._input={frontendVersion:null,backendVersion:null,kiosk:!1,reducedMotion:!1},this._relation={kind:"unknown"},this._banner=null,this._connected=!1,this._attemptTarget=null,this._attemptState=null,this._noticeToken=0}get relation(){return this._relation}get banner(){return this._banner}get hasCurrentMismatchNotice(){return"mismatch"===this._relation.kind&&"visible"===this._banner?.phase}connect(){this._connected||(this._connected=!0,this._attemptTarget=null,this._attemptState=null,this._reconcile())}disconnect(){(this._connected||this._banner)&&(this._connected=!1,this._cancelTimer(),this._banner&&(this._banner=null,this.hooks.changed()))}update(e){const t={frontendVersion:yg(e.frontendVersion),backendVersion:yg(e.backendVersion),kiosk:!0===e.kiosk,reducedMotion:!0===e.reducedMotion},i=function(e,t){const i=yg(e),n=yg(t);return i&&n?i===n?{kind:"equal",frontend:i,backend:n}:{kind:"mismatch",frontend:i,backend:n}:{kind:"unknown"}}(t.frontendVersion,t.backendVersion),n=!((e,t)=>e.frontendVersion===t.frontendVersion&&e.backendVersion===t.backendVersion&&e.kiosk===t.kiosk&&e.reducedMotion===t.reducedMotion)(this._input,t)||!((e,t)=>e.kind===t.kind&&("unknown"===e.kind||"unknown"!==t.kind&&e.frontend===t.frontend&&e.backend===t.backend))(this._relation,i);this._input=t,this._relation=i,n&&this._reconcile()}finishBannerExit(e){this._banner&&"leaving"===this._banner.phase&&this._banner.token===e&&(this._banner=null,this.hooks.changed())}_reconcile(){if(this._cancelTimer(),!this._connected||"mismatch"!==this._relation.kind)return this._attemptTarget=null,this._attemptState=null,void this._hideBanner();if(!this._input.kiosk)return this._attemptTarget=null,this._attemptState=null,void this._showBanner(this._relation.frontend,this._relation.backend);const e=this._relation.backend;if(this._attemptTarget===e&&null!==this._attemptState||(this._attemptTarget=e,this._attemptState=function(e,t){try{const i=e();return i?i.getItem(vg)===t?"attempted":"fresh":"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e)),"fresh"===this._attemptState)return this._hideBanner(),void this._armTimer();this._showBanner(this._relation.frontend,e)}_armTimer(){this._connected&&void 0===this._timer&&"mismatch"===this._relation.kind&&this._input.kiosk&&"fresh"===this._attemptState&&(this._timer=this.hooks.clock.setTimeout(()=>{this._timer=void 0,this._tick()},250))}_cancelTimer(){void 0!==this._timer&&(this.hooks.clock.clearTimeout(this._timer),this._timer=void 0)}_tick(){if(!this._connected||"mismatch"!==this._relation.kind||!this._input.kiosk||"fresh"!==this._attemptState)return;if(!function(e){return e.connected&&e.initialFrameSettled&&e.viewOnly&&e.surfacesIdle&&e.configWritesIdle&&e.physicalWritesIdle&&e.layoutWritesIdle&&e.gesturesIdle&&e.interactionPauseElapsed&&e.baseZoom}(this.hooks.safety()))return void this._armTimer();const e=this._relation.backend,t=function(e,t){try{const i=e();return i?i.getItem(vg)===t?"attempted":(i.setItem(vg,t),"claimed"):"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e);if(this._attemptTarget=e,this._attemptState="claimed"===t?"attempted":t,"claimed"===t){this._showBanner(this._relation.frontend,e);try{this.hooks.reload()}catch{}}else this._showBanner(this._relation.frontend,e)}_showBanner(e,t){"visible"===this._banner?.phase&&this._banner.frontend===e&&this._banner.backend===t||(this._banner={frontend:e,backend:t,phase:"visible",token:++this._noticeToken},this.hooks.changed())}_hideBanner(){if(this._banner)return this._input.reducedMotion?(this._banner=null,void this.hooks.changed()):void("leaving"!==this._banner.phase&&(this._banner={...this._banner,phase:"leaving",token:++this._noticeToken},this.hooks.changed()))}}const wg=1;function kg(e,t){const i=t&&"object"==typeof t?t:{};e._haIntegrationVersion=yg(i.integration_version);const n=i.support_api;e._haSupportApi="number"==typeof n&&Number.isSafeInteger(n)?n:null,e._haDecorAssetsApi=1===i.decor_assets_api?1:null,e._haSummaryPanelApi=1===i.summary_panel_api?1:null,e._haRadarStage1Api=1===i.radar_stage1_api?1:null,e._syncVersionRecovery()}function xg(e){const t=e._stageEl,i=e._loadOk&&!e._loading&&e._continuityDataReady&&!e._resumeSettling&&!e._connectionWasLost&&!e._booting&&!e._bootFading&&!e._bootSettling&&!e._bootSoft&&e._continuity.hasCompleteFrame&&"steady"===e._continuity.state&&!e._continuity.overlayBlocksInteraction&&!!t&&t.clientWidth>0&&t.clientHeight>0,n=!(0!==e._pointers.size||0!==e._touchContacts.size||e._touchSequenceMultitouch||e._roomPointer||e._panStart||e._panLock||e._pinchStart||e._swipeStart||e._tabDrag||e._tabDragRelease||e._drag||e._deviceDrag||e._rlResize||e._resize?.dragging||e._physicalDrag||e._physicalRotate||e._opDrag||e._decorDraft||e._decorMove||e._dtDrag||e._bdDrag||e._furnTouchPending||e._compassDrag||e._viewportGestureDirty||e._devicePositionBusy||e._modeTransitionBusy||e._cameraTransition.active||e._slide||0!==e._warmModeRequest),r=!(e._editorSecondaryDialogBlocked||e._partitionDeleteDialog||e._roomDeleteDialog||e._backdropGuard||e._vacFit||e._editorSecondary?.hasOpenGroup||e._furnPalette||e._decorImagePalette);return{connected:e.isConnected,initialFrameSettled:i,viewOnly:!0===e._config?.kiosk&&"view"===e._mode&&!e._editing,surfacesIdle:r,configWritesIdle:0===e._writesPending&&!e._saveConfigDebounced.pending(),physicalWritesIdle:0===e._pendingPhysicalWrites.size,layoutWritesIdle:!e._persistLayout.pending()&&0===e._dirtyPos.size&&0===e._sentPos.size&&!e._devicePositionBusy,gesturesIdle:n,interactionPauseElapsed:Date.now()>=e._cyclePausedUntil,baseZoom:e._zoom<=1.001}}class Sg{constructor(){this.seen=null,this.diagnosticsCache=null}observe(e,t,i,n){this.invalidateDiagnosticsForHass(e,t,i),this.intake(t,n)}intake(e,t){e&&this.seen!==e&&(this.seen=e,t())}invalidate(){this.diagnosticsCache=null}invalidateDiagnosticsForHass(e,t,i){this.diagnosticsCache&&(e?.entities!==t?.entities||e?.devices!==t?.devices||[...i?.entityIds||[]].some(i=>!!e?.states?.[i]!=!!t?.states?.[i]))&&this.invalidate()}diagnostics(e,t,i){if(this.diagnosticsCache)return this.diagnosticsCache;const n={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of t)e.removed||"virtual"===e.binding||n[i(e.binding).kind]++;return this.diagnosticsCache={registry:dd(e),bindings:n},this.diagnosticsCache}}function $g(e){const t=e;t._hassSequence++,t._renderSnapshotAt=Date.now(),t._continuity.note("hass-snapshot"),t._ensureHaRegistryAuthority(),t._planHassMemo=null,t._hookConnection(),!t._loadOk&&!t._loading&&t._loadTries<8&&t._loadFromServer(),t._maybeRebuildDevices(),t._vacTick(),t._activityTick()}function Mg(e){return!!e&&"object"==typeof e&&1===e.version}function Rg(e,t){const i=e.radar;return e.space===t&&!0!==e.hidden&&!0!==e.removed&&Mg(i)&&!0===i.enabled&&!1!==i.show_live}const Cg={ok:"radar.health_ok",off:"radar.health_off",stale:"radar.health_stale",partial:"radar.health_partial",restricted:"radar.health_restricted",incomplete:"radar.health_incomplete",position_unavailable:"radar.health_position_unavailable",unavailable:"radar.health_unavailable",needs_setup:"radar.health_needs_setup",inconsistent:"radar.health_inconsistent",unknown:"radar.health_unknown"};const Tg=e=>"number"==typeof e&&Number.isFinite(e);class Dg{constructor(e){this.host=e,this.frames=new Map,this.connection=null,this.space="",this.generation=0,this.expiryTimer=0,this.deadlines=new Map}sync(e,t){const i=this.host.hass?.connection;if(!t||!i||!this.host.isConnected)return void this.stop();if(this.unsubscribe&&this.connection===i&&this.space===e)return;this.stop(),this.connection=i,this.space=e;const n=++this.generation,r=i.subscribeMessage?.bind(i);"function"==typeof r&&Promise.resolve(r(e=>{if(n!==this.generation||!this.host.isConnected)return;const t=function(e){if(!e||"object"!=typeof e)return null;const t=e;if("string"!=typeof t.marker_id||"string"!=typeof t.server_session_id||!Number.isSafeInteger(t.seq)||"string"!=typeof t.health)return null;const i=Array.isArray(t.targets)?t.targets.slice(0,256).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;return"string"==typeof t.slot&&Tg(t.x)&&Tg(t.y)&&Tg(t.expires_at)&&Tg(t.reported_at)&&("bounded_latest"===t.pair_quality||"coherent"===t.pair_quality)?[{...t,included:!0===t.included,smooth:!0===t.smooth}]:[]}):[],n=Array.isArray(t.ranges)?t.ranges.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if(!("string"==typeof t.id&&Tg(t.x)&&Tg(t.y)&&Tg(t.radius)&&Tg(t.expires_at)&&Tg(t.reported_at)))return[];const i=Array.isArray(t.segments)?t.segments.slice(0,64).flatMap(e=>{if(!Array.isArray(e))return[];const t=e.slice(0,181).flatMap(e=>Array.isArray(e)&&2===e.length&&Tg(e[0])&&Tg(e[1])?[[e[0],e[1]]]:[]);return t.length>=2?[t]:[]}):void 0;return[{...t,...i?{segments:i}:{}}]}):[],r=Array.isArray(t.zones)?t.zones.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if("string"!=typeof t.id)return[];const i=t.state;if(null!==i&&"boolean"!=typeof i&&!Tg(i))return[];const n=Array.isArray(t.polygon)?t.polygon.slice(0,64).flatMap(e=>Array.isArray(e)&&2===e.length&&Tg(e[0])&&Tg(e[1])?[[e[0],e[1]]]:[]):[];return[{id:t.id,state:i,...n.length>=3?{polygon:n}:{}}]}):[];return{server_session_id:t.server_session_id,marker_id:t.marker_id,source_generation:"string"==typeof t.source_generation?t.source_generation:void 0,calibration_revision:"string"==typeof t.calibration_revision?t.calibration_revision:void 0,seq:t.seq,reported_at:Tg(t.reported_at)?t.reported_at:void 0,expires_at:Tg(t.expires_at)?t.expires_at:void 0,health:t.health,reported_presence:"boolean"==typeof t.reported_presence?t.reported_presence:null,complete:!0===t.complete,targets:i,ranges:n,zones:r}}(e);if(!t)return;if(!function(e,t){return!e||t.server_session_id!==e.server_session_id||t.source_generation!==e.source_generation||t.calibration_revision!==e.calibration_revision||t.seq>e.seq}(this.frames.get(t.marker_id),t))return;const i=function(e,t=Date.now()){if(!Tg(e.expires_at))return null;if(!Tg(e.reported_at))return Math.max(0,1e3*e.expires_at-t);const i=Math.max(0,1e3*(e.expires_at-e.reported_at)),n=Math.max(0,t-1e3*e.reported_at);return Math.max(0,i-n)}(t);"restricted"===t.health||"disabled"===t.health||0===i?(this.frames.delete(t.marker_id),this.deadlines.delete(t.marker_id)):(this.frames.set(t.marker_id,t),null==i?this.deadlines.delete(t.marker_id):this.deadlines.set(t.marker_id,this.monotonicNow()+i)),this.armExpiry(),this.host.requestUpdate()},{type:"houseplan/radar/subscribe",space_id:e})).then(e=>{n===this.generation&&this.host.isConnected?"function"==typeof e&&(this.unsubscribe=e):"function"==typeof e&&e()}).catch(()=>{n===this.generation&&this.stop()})}stop(){this.generation++,this.unsubscribe?.(),this.unsubscribe=void 0,this.connection=null,this.space="",clearTimeout(this.expiryTimer),this.expiryTimer=0,this.frames.size&&(this.frames.clear(),this.host.isConnected&&this.host.requestUpdate()),this.deadlines.clear()}armExpiry(){clearTimeout(this.expiryTimer);const e=this.monotonicNow(),t=[...this.deadlines.values()].filter(t=>t>e);if(!t.length)return;const i=Math.max(20,Math.min(...t)-e+10);this.expiryTimer=window.setTimeout(()=>{this.expiryTimer=0;let e=!1;const t=this.monotonicNow();for(const[i,n]of this.deadlines)n>t||(this.deadlines.delete(i),this.frames.delete(i),e=!0);this.armExpiry(),e&&this.host.isConnected&&this.host.requestUpdate()},i)}monotonicNow(){return globalThis.performance?.now?.()??Date.now()}}const Ag=Object.freeze({enabled:!1,z2mBaseTopics:Object.freeze([])});function Pg(e){if("string"!=typeof e)return null;const t=e.trim().replace(/^\/+|\/+$/g,"").replace(/\/{2,}/g,"/");return!t||t.length>180||/[#+\u0000-\u001f\u007f]/.test(t)?null:t}function Fg(e){const t=e?.zigbee_topology;if(!t||"object"!=typeof t)return Ag;const i=t,n=Array.isArray(i.z2m_base_topics)?i.z2m_base_topics:Array.isArray(i.z2mBaseTopics)?i.z2mBaseTopics:[],r=new Set,o=[];for(const e of n){const t=Pg(e);if(t&&!r.has(t)&&(r.add(t),o.push(t),8===o.length))break}return{enabled:!0===i.enabled,z2mBaseTopics:o}}function zg(e,t){const i={...e},n=t.z2mBaseTopics.map(Pg).filter(Boolean);return t.enabled||n.length?i.zigbee_topology={enabled:!0===t.enabled,z2m_base_topics:[...new Set(n)].slice(0,8)}:delete i.zigbee_topology,i}const Ig={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Og=e=>Math.max(0,Math.min(1,e)),Eg=(e,t,i)=>e+(t-e)*i,Ng=(e,t,i)=>{const n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},Hg=e=>{const t=Og(e);if(0===t||1===t)return t;let i=0,n=1,r=t;for(let e=0;e<12;e++)r=(i+n)/2,Ng(r,.2,.2)0&&e.w>0?t/e.w:1,viewBox:{...e}}}function Bg(e,t,i){const n=Math.max(1e-9,e.pixelsPerUnit),r=Math.max(1e-9,t/n),o=Math.max(1e-9,i/n);return{x:e.centerX-r/2,y:e.centerY-o/2,w:r,h:o}}function qg(e){const t=e.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(t);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const n=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t)?.[1];return n?[parseInt(n.slice(0,2),16),parseInt(n.slice(2,4),16),parseInt(n.slice(4,6),16),8===n.length?parseInt(n.slice(6,8),16)/255:1]:null}function jg(e,t,i){const n=qg(e),r=qg(t);if(!n||!r)return i<.5?e:t;const o=Og(i);return`rgba(${Math.round(Eg(n[0],r[0],o))}, ${Math.round(Eg(n[1],r[1],o))}, ${Math.round(Eg(n[2],r[2],o))}, ${Eg(n[3],r[3],o).toFixed(3)})`}class Wg{constructor(e,t=Ig){this._hooks=e,this._clock=t,this._token=0,this._raf=0,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase||"preparing"===this._state?.phase}get presented(){return this._state?.presented||null}start(e,t,i,n=220){this.cancel(!1);const r=++this._token,o=this._clock.now();if(this._state={token:r,phase:n<=0?"settling":"running",from:e,to:t,presented:n<=0?t:e,startedAt:o,duration:Math.max(0,n),targetMode:i},n<=0)return this._hooks.frame(this._state),this._hooks.settled(this._state),this._state=null,r;this._hooks.frame(this._state);const s=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Og((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:function(e,t,i){const n=Hg(i),r=Eg(e.stageWidth,t.stageWidth,n),o=Eg(e.stageHeight,t.stageHeight,n),s=Math.max(1e-9,e.viewport.pixelsPerUnit),a=Math.max(1e-9,t.viewport.pixelsPerUnit),l={centerX:Eg(e.viewport.centerX,t.viewport.centerX,n),centerY:Eg(e.viewport.centerY,t.viewport.centerY,n),pixelsPerUnit:Math.exp(Eg(Math.log(s),Math.log(a),n))};return{presentedMode:n<.5?e.presentedMode:t.presentedMode,editorChromeHeight:Eg(e.editorChromeHeight,t.editorChromeHeight,n),stageWidth:r,stageHeight:o,viewport:{...l,viewBox:Bg(l,r,o)},stageColor:jg(e.stageColor,t.stageColor,n),paperColor:jg(e.paperColor,t.paperColor,n),sceneBrightness:Eg(e.sceneBrightness,t.sceneBrightness,n),architectureOpacity:Eg(e.architectureOpacity,t.architectureOpacity,n),backdropOpacity:Eg(e.backdropOpacity,t.backdropOpacity,n),viewWeight:Eg(e.viewWeight,t.viewWeight,n),editorWeight:Eg(e.editorWeight,t.editorWeight,n),toolbarContentOpacity:Eg(e.toolbarContentOpacity,t.toolbarContentOpacity,n)}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i<1?this._raf=this._clock.requestFrame(s):(this._raf=0,this._hooks.settled(t),this._state?.token===r&&(this._state=null))};return this._raf=this._clock.requestFrame(s),r}cancel(e=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=t.to,this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}}const Ug={now:()=>"undefined"!=typeof performance?performance.now():Date.now(),requestFrame:e=>"function"==typeof requestAnimationFrame?requestAnimationFrame(e):null,cancelFrame:e=>{"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e)}},Gg=e=>Number.isFinite(e);function Vg(e){return!!e&&Gg(e.zoom)&&e.zoom>0&&Gg(e.viewBox.x)&&Gg(e.viewBox.y)&&Gg(e.viewBox.w)&&e.viewBox.w>0&&Gg(e.viewBox.h)&&e.viewBox.h>0}function Kg(e){return{zoom:e.zoom,viewBox:{...e.viewBox}}}function Yg(e,t){return Math.abs(e.zoom-t.zoom)<1e-9&&Math.abs(e.viewBox.x-t.viewBox.x)<1e-6&&Math.abs(e.viewBox.y-t.viewBox.y)<1e-6&&Math.abs(e.viewBox.w-t.viewBox.w)<1e-6&&Math.abs(e.viewBox.h-t.viewBox.h)<1e-6}const Xg=(e,t,i)=>e+(t-e)*i,Zg=(e,t,i)=>Math.exp(Xg(Math.log(e),Math.log(t),i));class Jg{constructor(e,t=Ug){this._hooks=e,this._clock=t,this._token=0,this._raf=null,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase}get presented(){return this._state?.presented||null}get target(){return this._state?.to||null}start(e,t,i,n){this.cancel(!1);const r=++this._token,o=Kg(e),s=Kg(t),a=n>0&&Vg(o)&&Vg(s),l=this._clock.now(),c={token:r,phase:a?"running":"settling",from:o,to:s,presented:Kg(a?o:s),startedAt:l,duration:a?n:0,reason:i};if(this._state=c,this._hooks.frame(c),!a)return this._settle(r),r;const h=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Math.max(0,Math.min(1,(e-t.startedAt)/t.duration));if(t.presented=i>=1?Kg(t.to):function(e,t,i){if(!Vg(e))return Kg(t);if(!Vg(t))return Kg(e);const n=Hg(i);if(n<=0)return Kg(e);if(n>=1)return Kg(t);const r=e.viewBox.x+e.viewBox.w/2,o=e.viewBox.y+e.viewBox.h/2,s=t.viewBox.x+t.viewBox.w/2,a=t.viewBox.y+t.viewBox.h/2,l=Zg(e.viewBox.w,t.viewBox.w,n),c=Zg(e.viewBox.h,t.viewBox.h,n),h=Xg(r,s,n),d=Xg(o,a,n);return{zoom:Zg(e.zoom,t.zoom,n),viewBox:{x:h-l/2,y:d-c/2,w:l,h:c}}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i>=1)return this._raf=null,void this._settle(r);this._raf=this._clock.requestFrame(h),null===this._raf&&this._settle(r)};return this._raf=this._clock.requestFrame(h),null===this._raf&&(c.phase="settling",c.presented=Kg(s),this._hooks.frame(c),this._settle(r)),r}cancel(e=!0){null!==this._raf&&this._clock.cancelFrame(this._raf),this._raf=null;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=Kg(t.to),this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}_settle(e){const t=this._state;t&&t.token===e&&(t.phase="settling",t.presented=Kg(t.to),this._hooks.settled(t),this._state?.token===e&&(this._state=null))}}function Qg(e,t,i){const n=e.querySelector("ha-card");if(!n)return null;const r=n.getBoundingClientRect(),o=t.getBoundingClientRect().top-r.top,s=i?0:Math.min(Math.max(r.top,0),120),a=Math.round(o+s);return a>=0?a:null}const ef=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])}),tf=84,nf=10,rf=4,of=4;function sf(e){return[e.rotDeg,e.tiltDeg,e.xyScale,e.zScale,e.origin[0],e.origin[1]].every(Number.isFinite)&&Math.abs(e.xyScale)>1e-12&&Math.abs(Math.cos(e.tiltDeg*Math.PI/180))>1e-12}function af(e,t,i=ef){if(!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");return function(e,t){if(!Number.isFinite(e[0])||!Number.isFinite(e[1])||!t.every(Number.isFinite))throw new Error("invalid isometric affine input");const[i,n,r,o,s,a]=t;return[i*e[0]+r*e[1]+s,n*e[0]+o*e[1]+a]}(e,cf(t,i))}function lf(e,t=ef){if(!sf(t)||!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=(e[0]-t.origin[0])/t.xyScale,o=(e[1]-t.origin[1])/(t.xyScale*Math.cos(n));return[t.origin[0]+r*Math.cos(i)+o*Math.sin(i),t.origin[1]-r*Math.sin(i)+o*Math.cos(i)]}function cf(e=0,t=ef){if(!sf(t)||!Number.isFinite(e))throw new Error("invalid isometric camera");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=t.xyScale*Math.cos(i),o=-t.xyScale*Math.sin(i),s=t.xyScale*Math.sin(i)*Math.cos(n),a=t.xyScale*Math.cos(i)*Math.cos(n);return[r,s,o,a,t.origin[0]-r*t.origin[0]-o*t.origin[1],t.origin[1]-s*t.origin[0]-a*t.origin[1]-e*t.zScale*Math.sin(n)]}function hf(e=ef){return function(e=0,t=ef){return`matrix(${cf(e,t).map(e=>Number(e.toFixed(12))).join(" ")})`}(0,e)}function df(e,t=ef){const{rect:i,wallHeight:n}=e,r=e.openingHeight??n,o=e.floorDepth??0,s=e.raisedHeight??n;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o)||!Number.isFinite(s)||n<0||r<0||o<0||s<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],l=Math.max(n,r,s),c=a.flatMap(e=>[af(e,-o,t),af(e,l,t)]),h=c.map(e=>e[0]),d=c.map(e=>e[1]),u=Math.min(...h),p=Math.min(...d);return{x:u,y:p,w:Math.max(...h)-u,h:Math.max(...d)-p}}const uf=[".dev",".vacpuck",".oplock",".op-hit",".opening",".rlgo","a","button","input","select","textarea",'[contenteditable]:not([contenteditable="false"])',"[data-room-fit-block]",'[role="link"]','[role="button"]'].join(","),pf=(e,t)=>{try{return"function"==typeof e?.matches&&e.matches(t)}catch{return!1}};function _f(e){for(const t of e){const e=t;if(pf(e,".roomlabel[data-id]")){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(pf(e,uf))return{kind:"interactive"};if(pf(e,'[data-hp="room"][data-id]')){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(pf(e,".stage"))return{kind:"background"}}return{kind:"outside"}}function mf(e){const t=_f(e);return"room"===t.kind?t.roomId:null}class gf{constructor(){this.pointer=null,this.sequence=null}clear(){this.pointer=null,this.sequence=null}clearOutside(e){let t={kind:"outside"};try{t=_f(e.composedPath())}catch{}"outside"===t.kind&&this.clear()}pointerDown(e,t,i){let n={kind:"outside"};try{n=_f(e.composedPath())}catch{}this.pointer=function(e){const t="mouse"===(i=e.pointerType)||"touch"===i||"pen"===i?i:null;var i;return t&&"view"===e.mode&&"background"===e.owner.kind&&!e.blocked&&e.isPrimary&&0===e.button&&Number.isFinite(e.x)&&Number.isFinite(e.y)?{pointerId:e.pointerId,spaceId:e.spaceId,modality:t,x:e.x,y:e.y}:null}({pointerId:e.pointerId,pointerType:e.pointerType,isPrimary:e.isPrimary,button:e.button,spaceId:t,mode:i?"view":"blocked",owner:n,blocked:!i,x:e.clientX,y:e.clientY}),this.pointer||(this.sequence=null)}pointerUp(e,t,i,n,r=Date.now()){let o={kind:"outside"};try{o=_f(e.composedPath())}catch{}const s=function(e,t,i){if(!t||"view"!==i.mode||"background"!==i.owner.kind||i.blocked||t.pointerId!==i.pointerId||t.spaceId!==i.spaceId||!Number.isFinite(i.x)||!Number.isFinite(i.y)||!Number.isFinite(i.now)||Math.abs(i.x-t.x)+Math.abs(i.y-t.y)>=8)return{sequence:null,trigger:!1};const n=e?i.now-e.at:Number.POSITIVE_INFINITY;return e&&e.spaceId===i.spaceId&&e.modality===t.modality&&n>=0&&n<=350?{sequence:null,trigger:!0}:{sequence:{at:i.now,spaceId:i.spaceId,modality:t.modality},trigger:!1}}(this.sequence,this.pointer,{pointerId:e.pointerId,spaceId:t,mode:i?"view":"blocked",owner:o,blocked:n||!i,x:e.clientX,y:e.clientY,now:r});return this.pointer=null,this.sequence=s.sequence,s.trigger}}const ff=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function vf(e){return!!e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&e.w>0&&Number.isFinite(e.h)&&e.h>0}function yf(e,t=0){if(!e.length||!Number.isFinite(t)||t<0||!e.every(ff))return null;let i=1/0,n=1/0,r=-1/0,o=-1/0;for(const t of e)i=Math.min(i,t[0]),n=Math.min(n,t[1]),r=Math.max(r,t[0]),o=Math.max(o,t[1]);const s=r-i,a=o-n;return s>0&&a>0?{x:i-t,y:n-t,w:s+2*t,h:a+2*t}:null}function bf(e,t,i){const n="string"!=typeof t||"invalid"!==t&&"no-borders"!==t&&"unverified"!==t&&!/^[a-z0-9]{1,8}$/i.test(t)?"redacted":t;return Object.freeze({kind:e,fingerprint:n,terminal:!!i})}function wf(e,t){return`${e("editor.load_failed")} ${e(t.terminal?"editor.refresh_advice":"editor.retry_advice")}`}class kf extends Error{}class xf{constructor(e){this.options=e,this._state="idle",this._inFlight=null}get state(){return this._state}ensure(){return"ready"===this._state?Promise.resolve(!0):"failed"===this._state?Promise.resolve(!1):(this._inFlight||(this._setState("loading"),this._inFlight=this._loadWithRetry().finally(()=>{this._inFlight=null})),this._inFlight)}async _loadWithRetry(){let e=new Error("Editor runtime did not load"),t=!1;for(const i of[0,1])try{const e=await this.options.load(i);if(e.fingerprint!==this.options.expectedFingerprint)throw new kf(`Editor runtime fingerprint mismatch: expected ${this.options.expectedFingerprint}, got ${e.fingerprint}`);const t=e.create();return this.options.install(t),this._setState("ready"),!0}catch(i){e=i,i instanceof kf&&(t=!0)}return this._setState(t?"failed":"idle"),this.options.failed?.(e,{terminal:t}),!1}_setState(e){e!==this._state&&(this._state=e,this.options.stateChanged?.(e))}}const Sf=(e,t)=>{if(!e.has(t))return{hit:!1};const i=e.get(t);return e.delete(t),e.set(t,i),{hit:!0,value:i}},$f=(e,t,i,n)=>{for(e.delete(t),e.set(t,i);e.size>n;){const t=e.keys().next().value;if(void 0===t)break;e.delete(t)}},Mf=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Rf=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`,Cf="houseplan_card_alpha_v1",Tf=Object.freeze([Object.freeze({id:"iso",issue:89,summary:"Volumetric plan renderer"})]);function Df(e){return/^[a-z][a-z0-9-]*$/.test(e.id)&&Number.isInteger(e.issue)&&e.issue>0&&!!e.summary.trim()}function Af(e){const t=String(e||"").replace(/^#/,"");return new URLSearchParams(t)}function Pf(e){return Af(e).get("space")||""}function Ff(e,t,i=Tf){const n=function(e){const t=new Set;for(const i of e){if(!Df(i)||t.has(i.id))return!1;t.add(i.id)}return!0}(i),r=function(e){let t,i=!1;const n=e=>{for(const n of e.getAll("hp_alpha"))i=!0,"1"===n?t=!0:"0"===n&&(t=!1)};return n(new URLSearchParams(String(e.search||"").replace(/^\?/,""))),n(Af(e.hash)),{present:i,value:t}}(e),o=void 0!==r.value,s="1"===t,a=o?!0===r.value:!r.present&&s,l=n&&a;return{alpha:l,active:Object.freeze(l?i.map(e=>e.id).sort():[]),space:Pf(e.hash),persist:n&&o?l?"1":"0":void 0,knownUrlOperation:o}}let zf={alpha:!1,active:Object.freeze([]),space:""},If=!1,Of="";const Ef=new Set;function Nf(){if("undefined"==typeof window)return zf;const e=Ff(window.location,function(){try{return window.localStorage.getItem(Cf)}catch{return null}}());void 0!==e.persist&&function(e){try{window.localStorage.setItem(Cf,e)}catch{}}(e.persist),zf={alpha:e.alpha,active:e.active,space:e.space},window.__hpAlpha=e.alpha,window.__hpLabs=e.active;for(const e of Ef)e(zf);return zf}function Hf(){Nf()}function Lf(){if("undefined"==typeof window)return zf;if(!If){If=!0,window.__hpLabsListenerCleanup?.(),window.addEventListener("hashchange",Hf),window.addEventListener("popstate",Hf);const e=()=>{window.removeEventListener("hashchange",Hf),window.removeEventListener("popstate",Hf),window.__hpLabsListenerCleanup===e&&delete window.__hpLabsListenerCleanup};window.__hpLabsListenerCleanup=e}return Nf()}const Bf={window:120,door:90,passage:90,gate:300};function qf(e){return Bf[e]}function jf(e,t){return{type:e,lengthCm:qf(e),flipH:!1,flipV:!1,revision:t}}function Wf(e,t){const i=Math.max(0,e.renderedLength)/2,n=Math.max(0,e.target.physicalHalfWidth),r=n+.18*Math.max(0,t),o=e=>({x1:e,y1:-r,x2:e,y2:r});return{rect:{x:-i,y:n?-n:0,width:2*i,height:2*n},boundaries:[o(-i),o(i)]}}function Uf(e,t){const i=[e[0],e[1]],n=[t[0],t[1]];return function(e,t){return e[0]-t[0]||e[1]-t[1]}(i,n)<=0?{a:i,b:n}:{a:n,b:i}}function Gf(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const n=Uf(e.a,e.b);if(Math.hypot(n.b[0]-n.a[0],n.b[1]-n.a[1])<=1e-9)return;const r=function(e,t){const i=e=>(Math.abs(e)<=5e-10?0:Math.round(1e6*e)/1e6).toFixed(6);return`${i(e[0])},${i(e[1])}>${i(t[0])},${i(t[1])}`}(n.a,n.b),o=t.get(r);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,e.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(e.partitionHost&&(o.partitionHost&&o.partitionHost.id!==e.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=e.partitionHost));t.set(r,{segmentKey:r,a:n.a,b:n.b,physicalHalfWidth:Math.max(0,e.half||0),sourceOrder:i,...e.partitionHost?{partitionHost:e.partitionHost}:{}})}),[...t.values()]}function Vf(e,t){if(Math.abs(e.distance-t.distance)>1e-9)return e.distance-t.distance;if(Math.abs(e.perpendicular-t.perpendicular)>1e-9)return e.perpendicular-t.perpendicular;return(e.target.segmentKeyt.target.segmentKey?1:0)||e.target.sourceOrder-t.target.sourceOrder}function Kf(e){const t=Gf(e.intervals).map(t=>{const i=function(e,t){const i=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,a=(e[0]-t.a[0])*o+(e[1]-t.a[1])*s,l=Math.max(0,Math.min(r,a)),c=t.a[0]+l*o,h=t.a[1]+l*s;return{along:l,length:r,x:c,y:h,distance:Math.hypot(e[0]-c,e[1]-h),perpendicular:Math.abs((e[0]-t.a[0])*s-(e[1]-t.a[1])*o)}}(e.pointer,t);return{target:t,...i,envelope:Math.max(e.baseTolerance,t.physicalHalfWidth+e.bodyPointerPadding)}}).filter(e=>e.distance<=e.envelope+1e-9).filter(t=>!function(e,t,i,n,r){const o=t.b[0]-t.a[0],s=t.b[1]-t.a[1],a=Math.hypot(o,s);if(!(a>1e-9))return!1;const l=o/a,c=s/a;for(const o of i){if(!o.open&&o.kind)continue;const i=Uf(o.a,o.b),s=i.b[0]-i.a[0],a=i.b[1]-i.a[1],h=Math.hypot(s,a);if(!(h>1e-9))continue;const d=s/h,u=a/h;if(Math.abs(l*u-c*d)>1e-6)continue;if(Math.abs((i.a[0]-t.a[0])*c-(i.a[1]-t.a[1])*l)>r)continue;const p=(e[0]-i.a[0])*d+(e[1]-i.a[1])*u,_=1e-9;if(!(p<=_||p>=h-_)&&Math.abs((e[0]-i.a[0])*u-(e[1]-i.a[1])*d)<=n+1e-9)return!0}return!1}(e.pointer,t.target,e.intervals,t.envelope,Math.max(1e-9,Math.min(e.baseTolerance,.04*e.gridStep)))),i=t.filter(t=>!!t.target.partitionHost&&e.renderedLength+2*t.target.physicalHalfWidth>t.length+1e-9).sort(Vf),n=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(Vf);let r=n[0];if(!r)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=n.filter(e=>Math.abs(e.distance-r.distance)<=1e-9&&Math.abs(e.perpendicular-r.perpendicular)<=1e-9),s=o.filter(e=>e.target.partitionHost);if(s.length){if(1!==new Set(s.map(e=>e.target.partitionHost.id)).size||s.some(e=>e.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const e=s[0],t=e.target.b[0]-e.target.a[0],i=e.target.b[1]-e.target.a[1],n=Math.hypot(t,i),a=t/n,l=i/n;if(!o.every(t=>{const i=t.target.b[0]-t.target.a[0],n=t.target.b[1]-t.target.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,c=Math.abs(a*s-l*o)<=1e-6,h=Math.abs((t.target.a[0]-e.target.a[0])*l-(t.target.a[1]-e.target.a[1])*a);return c&&h<=1e-9}))return{candidate:null,jambBlockedTarget:null};r=e}if(r.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:a,length:l}=r,c=a.b[0]-a.a[0],h=a.b[1]-a.a[1],d=c/l,u=h/l,p=a.partitionHost?a.physicalHalfWidth:0,_=Math.min(Math.max(0,e.renderedLength)/2+p,l/2);let m=r.along;const g=Math.max(e.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=a.a[0]+d*m,y=a.a[1]+u*m,b=Math.max(0,e.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),S=Math.max(0,l-k),$=[a.a[0]+d*(w-x/2),a.a[1]+u*(w-x/2)],M=[a.a[0]+d*(k+S/2),a.a[1]+u*(k+S/2)];let R=180*Math.atan2(h,c)/Math.PI;R>=90?R-=180:R<-90&&(R+=180);const C=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:e.preset.revision,geometryRevision:e.geometryRevision,pointer:[e.pointer[0],e.pointer[1]],type:e.preset.type,lengthCm:e.preset.lengthCm,flipH:e.preset.flipH,flipV:e.preset.flipV,x:v,y:y,angle:R,renderedLength:e.renderedLength,target:a,...a.partitionHost?{host:{...a.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:$},{distance:S,midpoint:M}],guide:C?{x:v,y:y,angle:R}:null}},jambBlockedTarget:null}}function Yf(e,t,i,n,r=1e-6){return e.presetRevision===i&&e.geometryRevision===n&&Math.hypot(e.pointer[0]-t[0],e.pointer[1]-t[1])<=r}function Xf(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}class Zf{constructor(e,t,i){this.loader=e,this.host=t,this.adopted=i,this.attachment=null}connect(){if(this.runtime)return void this.runtime.connect();this.attachment?.cancel();const e=this.loader.attach(this.host,e=>this.adopt(e));this.runtime||(this.attachment=e)}disconnect(){this.attachment?.cancel(),this.attachment=null,this.runtime?.disconnect()}adopt(e){this.attachment=null,this.runtime||(this.runtime=e,this.adopted(e))}}const Jf=new class{constructor(e){this.load=e,this.factory=null,this.pending=null}get warm(){return null!==this.factory}create(e){return this.factory?this.factory(e):null}attach(e,t){let i=!0;const n={cancel:()=>{i=!1}},r=this.create(e);return r?(t(r),n):(this.ensure().then(n=>{i&&t(n(e))},()=>{}),n)}ensure(){return this.factory?Promise.resolve(this.factory):(this.pending||(this.pending=this.load().then(e=>(this.factory=e,this.pending=null,e),e=>{throw this.pending=null,e})),this.pending)}reset(){this.factory=null,this.pending=null}}(()=>import("./summary-panel-runtime-loaded-CNpqraog.js").then(function(e){return e.e}).then(({LoadedSummaryPanelRuntime:e})=>t=>new e(t)));function Qf(e){const t=globalThis.__HP_VERSION_OVERRIDE__;return"string"==typeof t&&t.length>0?t:e}let ev=0;const tv="1.76.0-beta.3",iv="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33",nv=1500,rv=new Map;let ov=0,sv=1e4;const av="houseplan_card_layout_v1",lv="houseplan_card_cfg_v1",cv="houseplan_card_zoom_v1",hv="houseplan_card_nav_v1",dv="houseplan_card_view_v1",uv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",pv=1e3,_v=(e,t)=>{const i=Math.min(e.x,t.x),n=Math.min(e.y,t.y);return{x:i,y:n,w:Math.max(e.x+e.w,t.x+t.w)-i,h:Math.max(e.y+e.h,t.y+t.h)-n}},mv=(e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)},gv=e=>{history.pushState(null,"",e),mv(window,"location-changed",{replace:!1})},fv=(e,t)=>{let i,n=null;const r=(...r)=>{clearTimeout(i),n=r,i=window.setTimeout(()=>{i=void 0;const t=n;n=null,t&&e(...t)},t)};return r.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const t=n;n=null,t&&e(...t)},r.cancel=()=>{clearTimeout(i),i=void 0,n=null},r.pending=()=>void 0!==i,r},vv=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}},yv=["edges","corners"];class bv extends he{constructor(){var e;super(...arguments),this._editorRuntime=null,this._liveRt=null,this._onboardingRuntime=null,this._editorRuntimeLoadingVisible=!1,this._backdropGuard=null,this._editorModeRequest=0,this._warmModeRequest=0,this._editorRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./houseplan-editor-runtime-dzTrOQhv.js"):await import((()=>{const e=new URL("./houseplan-editor-runtime-dzTrOQhv.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.EDITOR_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanEditorRuntime(this)}},install:e=>{this._editorRuntime=e},stateChanged:e=>this._editorRuntimeStateChanged(e),failed:(e,t)=>{console.error("[houseplan] unable to load editor runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(wf(e=>this._t(e),t))}}),this._onboardingRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./houseplan-onboarding-runtime-BLRnH1D6.js"):await import((()=>{const e=new URL("./houseplan-onboarding-runtime-BLRnH1D6.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.ONBOARDING_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanOnboardingRuntime(this)}},install:e=>{this._onboardingRuntime=e},failed:(e,t)=>{console.error("[houseplan] unable to load onboarding runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(wf(e=>this._t(e),t))}}),this._isoSceneRuntime=null,this._isoSceneRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./iso-scene-render-BIRwzucU.js"):await import((()=>{const e=new URL("./iso-scene-render-BIRwzucU.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.ISO_SCENE_RUNTIME_FINGERPRINT,create:()=>t}},install:e=>{const t=this._effectiveProjection();this._isoSceneRuntime=e,this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i),this.isConnected&&this.requestUpdate()},failed:(e,t)=>{console.warn("[houseplan] hidden isometric runtime diagnostic",bf("runtime-load","unverified",t.terminal)),this.isConnected&&this.requestUpdate()}}),this._pdfRuntime=null,this._pdfRuntimeLoader=new xf({expectedFingerprint:iv,load:async e=>{const t=0===e?await import("./pdf-export-B2sbsWvc.js"):await import((()=>{const e=new URL("./pdf-export-B2sbsWvc.js",import.meta.url);return e.searchParams.set("hp_retry",`${tv}-${++ev}`),e.href})());return{fingerprint:t.PDF_EXPORT_FINGERPRINT,create:()=>new t.PdfExportRuntime}},install:e=>{this._pdfRuntime=e,this.isConnected&&this.requestUpdate()},failed:(e,t)=>{if(console.error("[houseplan] unable to load PDF export runtime",e),!t.terminal||!this._versionRecovery.hasCurrentMismatchNotice){const e=wf(e=>this._t(e),t),i=this._t("editor.load_failed"),n=e.startsWith(i)?e.slice(i.length).trim():e;this._showToast(`${this._t("pdf.failed")} ${n}`.trim())}}}),this.panelHost=!1,this.narrow=null,this._space="f1",this._adoption=new Bu((e,t)=>this.requestUpdate(e,t)),this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._configReloadAuthority=new Uu,this._virtualLights=Nh(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._areaRelocationIds=new Set,this._areaSnapshotCleanupCandidates=new Map,this._areaRelocationSyncKey="",this._areaRelocationWrite=Promise.resolve(),this._tip=null,this._hoverRoom=null,this._pointerModality=new og(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Sr},this._decorStyleSeeded=!1,this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._decorImagePalette=null,this._decorAssetCatalog=[],this._decorAssets=new Map,this._decorAssetBusy=!1,this._furnCategory=null,this._furnPreviewInput=null,this._furnTouchPending=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this._cancelDevicePressFeedback(),e.matches&&this._cancelCameraTransition(!0),e.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:e.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this._syncVersionRecovery(),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new Wg({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._cameraTransitionFit=null,this._cameraTransition=new Jg({frame:e=>this._applyCameraTransitionFrame(e),settled:e=>this._settleCameraTransition(e)}),this._editorSecondaryCopy={groupActive:(e,t)=>this._t("editor.group_active",{group:e,item:t}),openGroup:e=>this._t("editor.open_group",{group:e}),disabledAction:(e,t)=>this._t("editor.disabled_action",{action:e,reason:t})},this._tool="draw",this._geometryHistory=new mg(50),this._devicePositionHistory=new mg(50),this._devicePositionBusy=!1,this._wallDialog=null,this._drawWallField=null,this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainRedo=[],this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._renderIsoScene=null,this._isoProjectionSnapshot=null,this._isoStructuralBuildCount=0,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowRuntimeState=ym(),this._glowRuntimeHost={window:()=>this.ownerDocument.defaultView||window,isConnected:()=>this.isConnected,requestUpdate:()=>this.requestUpdate(),reducedMotion:()=>this._reducedMotion},this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszLimitViolation=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempMin="",this._roomTempMax="",this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._roomFocus=null,this._roomPointer=null,this._doubleFit=new gf,this._deviceHits=new bc,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._viewportGestureDirty=!1,this._touchContacts=new Map,this._touchClickGuard=new uc,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:e=>this._guardTouchGesture(e)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._dangerConfirm=null,this._dangerConfirmController=new ze(e=>{this._dangerConfirm=e}),this._confirmDanger=e=>this._config&&this.hass?"warm"===this._syncDangerConfirmLocaleGate()||this._dangerConfirmMissingSpace()?Promise.resolve(!1):this._dangerConfirmController.confirm(e):Promise.resolve(!1),this._cancelDangerConfirm=()=>{this._dangerConfirmController.cancel()},this._onDangerConfirmDecision=e=>{this._dangerConfirmController.resolve(e.detail.token,e.detail.accepted)},this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._versionRecovery=(e=this,new bg({clock:{setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e)},storage:()=>e.ownerDocument.defaultView?.sessionStorage??null,safety:()=>xg(e),reload:()=>e._reloadDocument(),changed:()=>{e.requestUpdate()}})),this._haSupportApi=null,this._haDecorAssetsApi=null,this._haSummaryPanelApi=null,this._haRadarStage1Api=null,this._radarLive=new Dg(this),this._decorAssetSyncToken=0,this._alignDialog=null,this._settingsDialog=null,this._pdfDialog=!1,this._supportDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=e=>this._onKey(e),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++ov,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={alpha:!1,active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._summarySlot=new Zf(Jf,this,e=>{this._summary=e,this._capturedSnapshotSequence=-1,this.isConnected&&(e.connect(),this.hasUpdated&&this.requestUpdate())}),this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),this._summary?.visibility(e.kind),"hidden"===e.kind)return this._radarLive.stop(),this._editorRuntime?._cancelRadarSetup(),this._clearRoomFocus(!0),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._cancelCameraTransition(!0),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,this._syncRadarLive(),!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+eg)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._onLabsSnapshot=e=>{const t=this._effectiveProjection();this._labs=e,this._isoProjectionSnapshot=null,this._labsIso&&this._ensureIsoSceneRuntime();const i=this._effectiveProjection();this._convertProjectionView(t,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const e=this._hashSpace();if(e&&this._model.find(t=>t.id===e)&&e!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._deviceDrag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._cfgEpochPreservedConfig=null,this._terminalFrame=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._renderLife=new Sg,this._liveEditorPaintCount=0,this._onHaRegistryUpdate=()=>{const e=id(this.hass);e.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=e.revision,this._renderLife.invalidate(),this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,td(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new dc(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=fv(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=yo(this._layout[t]);e&&(this._layout={...this._layout,[t]:e},this._sentPos.set(t,e),this.hass.callWS({type:"houseplan/layout/update",device_id:t,pos:e}).then(e=>this._noteLayoutRev(e)).catch(e=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))).finally(()=>{this._sentPos.get(t)===e&&this._sentPos.delete(t)}))}this._cacheSnapshot()}else this._persistLocalLayout()},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>this._editorRuntimeOrThrow()._undoGeometry(),this._redoGeometry=()=>this._editorRuntimeOrThrow()._redoGeometry(),this._saveConfigDebounced=fv(()=>{this._serverCfg&&this._writeConfig().catch(e=>{const t=!0===e?.physicalGeometryRolledBack;"geometry-unsafe"!==e?.code&&("wall_model_client_outdated"===e?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===e?.code?(this._showToast(this._t("toast.conflict")),t||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)})),t&&this._reloadRejectedPhysicalWrite())})},500),this._wallChainSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>this._editorRuntimeOrThrow()._savePhysicalDialog(),this._deletePhysicalSelection=()=>this._editorRuntimeOrThrow()._deletePhysicalSelection(),this._confirmPartitionDelete=()=>this._editorRuntimeOrThrow()._confirmPartitionDelete(),this._confirmRoomDelete=e=>this._editorRuntimeOrThrow()._confirmRoomDelete(e),this._rebindPartitionOpening=()=>this._editorRuntimeOrThrow()._rebindPartitionOpening(),this._keepClosedAsPartitions=()=>this._editorRuntimeOrThrow()._keepClosedAsPartitions(),this._toggleServerPlans=async()=>this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._toggleServerPlans():this._editorRuntimeOrThrow()._toggleServerPlans(),this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=ar(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(this._editorRuntime)return this._editorRuntime._openSettingsDialog();this._ensureEditorRuntime().then(e=>{e&&this._openSettingsDialog()})},this._openSupportDialog=()=>{this._editorRuntime?this._editorRuntime._openSupportDialog():this._ensureEditorRuntime().then(e=>{e&&this._openSupportDialog()})},this._openPdfDialog=()=>{this._pdfRuntimeLoader.ensure().then(e=>{e&&(this._pdfDialog=!0,this.requestUpdate())})},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._editorRuntimeOrThrow()._openAlignDialog(),this._toggleOptimizeLivePositions=()=>this._editorRuntimeOrThrow()._toggleOptimizeLivePositions(),this._optimizeUndoBusy=!1,this._openBackupExport=()=>this._editorRuntimeOrThrow()._openBackupExport(),this._openRulesDialog=()=>this._editorRuntimeOrThrow()._openRulesDialog(),this._climateCache=null,this._gearPtCache=new WeakMap}requestUpdate(e,t,i){if("hass"===e&&this.hass&&this._liveRt){const e=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;if(!this._liveRt.hass(t,this.hass,e?{entityIds:e.entityIds}:null,()=>$g(this))&&!this._summary?.observeHassComposition())return}void 0!==e&&(this._terminalFrame=0),this._editorRuntime?._routeLiveEditorUpdate(e,t)||(this._liveRt?.clear(),super.requestUpdate(e,t,i))}_editorRuntimeOrThrow(){if(!this._editorRuntime)throw new Error("Houseplan editor runtime is not loaded");return this._editorRuntime}async _ensureEditorRuntime(){return this._editorRuntimeLoader.ensure()}async _ensureOnboardingRuntime(){return this._onboardingRuntimeLoader.ensure()}async _ensureIsoSceneRuntime(){return this._isoSceneRuntimeLoader.ensure()}_editorRuntimeStateChanged(e){clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,"loading"!==e?(this._editorRuntimeLoadingVisible=!1,this.requestUpdate()):this._editorRuntimeLoadingTimer=window.setTimeout(()=>{this._editorRuntimeLoadingVisible=!0,this.requestUpdate()},150)}async _requestMode(e,t=!0,i=!1){const n=++this._editorModeRequest;if(i&&(this._warmModeRequest=n,this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null),"view"===e||await this._ensureEditorRuntime()){if(n===this._editorModeRequest&&this.isConnected)return i?(this._adoptMode(e),this._warmRevivePending&&(clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmReviveDialog()),this.requestUpdate(),void this.updateComplete.then(()=>requestAnimationFrame(()=>requestAnimationFrame(()=>{if(this._warmModeRequest!==n||n!==this._editorModeRequest)return;const e=this._stageEl;this._lastValidStageSize=e&&e.clientWidth>0&&e.clientHeight>0?[e.clientWidth,e.clientHeight]:null,this._pendingRefitSize=null,this._warmModeRequest=0})))):void this._setMode(e,t);this._warmModeRequest===n&&(this._warmModeRequest=0)}else this._warmModeRequest===n&&(this._warmModeRequest=0)}get _layout(){return this._adoption.layout}set _layout(e){this._adoption.stageLocalLayout(e)}get _layoutRev(){return this._adoption.layoutRev}set _layoutRev(e){this._adoption.seedIdentity({layoutRev:e})}get _layoutContentFingerprint(){return this._adoption.layoutFingerprint}set _layoutContentFingerprint(e){this._adoption.seedIdentity({layoutFingerprint:e})}get _serverCfg(){return this._adoption.config}set _serverCfg(e){this._adoption.stageLocalConfig(e)}get _cfgRev(){return this._adoption.configRev}set _cfgRev(e){this._adoption.seedIdentity({configRev:e})}get _cfgContentFingerprint(){return this._adoption.configFingerprint}set _cfgContentFingerprint(e){this._adoption.seedIdentity({configFingerprint:e})}_seedDecorStyle(e){var t,i;if(t=Pl,i=this,Tl(e,Hl)&&"pending"===t.state()&&(t.art("",i),t.ensure()),this._decorStyleSeeded||!e)return;this._decorStyleSeeded=!0;const n=e.settings?.decor_default_style;n&&(this._decorStyle=function(e,t){if(!e||"object"!=typeof e)return{...t};const i=e,n="string"==typeof i.color&&i.color?i.color:t.color,r="string"==typeof i.fill_color&&i.fill_color?i.fill_color:t.fillColor,o=Number(i.width_cm);return{color:n,opacity:$r(i.opacity,t.opacity),widthCm:Number.isFinite(o)&&o>0?Math.max(.1,Math.min(100,o)):t.widthCm,fill:"boolean"==typeof i.fill?i.fill:t.fill,fillColor:r,fillOpacity:$r(i.fill_opacity,t.fillOpacity)}}(n,Sr))}get _canManageConfiguration(){return null!==this._serverCanWrite?this._serverCanWrite:!0===this.hass?.user?.is_admin}get _canEdit(){return this._norm&&this._canManageConfiguration}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}get _doubleFitEnabled(){return!("view"!==this._mode||this._vacFit||this._modeTransitionBusy||this._touchSequenceMultitouch||"steady"!==this._continuity.state||this._continuity.overlayBlocksInteraction)}_cameraState(){const e=this._viewOr(this._baseVb());return{zoom:this._zoom,viewBox:{...e}}}_normalizeCameraState(e){const t=this._cameraTransitionFit||Oi(this._baseVb(),this._stageAspect());return{zoom:Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,e.zoom)),viewBox:this._clampView({...e.viewBox},t)}}_applyCameraTransitionFrame(e){const t=this._normalizeCameraState(e.presented);e.presented=t,this._zoom=t.zoom,this._view={...t.viewBox},this._liveVp(!0)}_settleCameraTransition(e){const t=this._normalizeCameraState(e.to);this._zoom=t.zoom,this._view={...t.viewBox},this._cameraTransitionFit=null,"room"!==e.reason&&this._saveZoom(),this.requestUpdate()}_cancelCameraTransition(e=!1,t=!1){const i=this._cameraTransition.state?.reason,n=t&&this._cameraTransition.active?this._cameraTransition.presented?.zoom:void 0;this._cameraTransition.cancel(e),this._cameraTransitionFit=null,void 0!==n&&"room"!==i&&this._saveZoom()}_prepareCameraCommand(){this._bootSoftCancel(),this._modeTransitionBusy&&this._cancelModeTransition(!0),"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1))}_startCameraTransition(e,t,i,n){const r=this._cameraState(),o=this._cameraTransition.target;return(!o||!Yg(o,e))&&(Yg(r,e)?(this._cancelCameraTransition(!1),!1):(this._cameraTransitionFit={...t},this._cameraTransition.start(r,e,i,this._reducedMotion?0:n),!0))}_cssColor(e,t){const i=String(e||"").trim();if(!i)return t;const n=document.createElement("span");n.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(n);const r=getComputedStyle(n).color||t;return n.remove(),r}_currentModeVisual(e=this._mode){const t=this._modeTransition.presented||this._modeTransitionVisual;if(t)return{...t,viewport:{...t.viewport,viewBox:{...t.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const n=this.renderRoot.querySelector(".editorchrome"),r=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),s=this.renderRoot.querySelector(".hp-backdrop"),a=this.renderRoot.querySelector(".zoomwrap"),l=a?getComputedStyle(a).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:e,editorChromeHeight:"view"===e?0:n?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Lg(r,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===e?.35:1,backdropOpacity:s&&Number(getComputedStyle(s).opacity)||1,viewWeight:"view"===e?1:0,editorWeight:"view"===e?0:1,toolbarContentOpacity:"view"===e?0:1}}_viewForModeTarget(e,t,i,n,r){const o=Oi(this._baseVb(),n/r),s=Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,e)),a=o.w/s,l=o.h/s,c=t??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-a/2,y:h-l/2,w:a,h:l},o)}_targetStageColor(e){return"view"!==e?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(e){return"view"===e&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(e){return 1}_applyModeTransitionFrame(e){e.targetMode===this._mode&&(this._modeTransitionVisual=e.presented,this._view={...e.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(e){if(e.targetMode!==this._mode)return;const t=this._modeTransitionRequest;this._view={...e.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[e.to.stageWidth,e.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._modeTransitionBusy||e.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-e.to.stageWidth)>.5||Math.abs(i.clientHeight-e.to.stageHeight)>.5)){const e=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,e?e.x+e.w/2:void 0,e?e.y+e.h/2:void 0),this.requestUpdate()}const n=this.renderRoot.activeElement;(!n||!n.isConnected||!!n.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(e=!0){this._cancelCameraTransition(!1);const t=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(e),e&&t||(this._modeTransitionVisual=null)}_adoptMode(e){e!==this._mode&&(this._clearRoomFocus(!0),this._resetDeviceHitState()),this._cancelModeTransition(!1),this._mode=e,this._isoProjectionSnapshot=null,"view"!==e&&(this._editorChromeMode=e)}_commitViewModeAtomic(e,t,i,n){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=t,e){const r=this._stageEl?.clientWidth||e.stageWidth,o=Math.max(1,e.stageHeight+e.editorChromeHeight);this._view=this._viewForModeTarget(t,i,n,r,o),this._lastValidStageSize=[r,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(e,t,i,n,r,o){this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._mode!==i)return void(e===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const s=this.renderRoot.querySelector(".editorchrome-inner"),a="view"===i?0:s?.scrollHeight||0,l=Math.max(1,(this.panelHost?this.clientHeight:innerHeight)-Qg(this.renderRoot,this._stageEl,this.panelHost)),c=this._stageEl?.clientWidth||t.stageWidth,h=this._viewForModeTarget(n,r,o,c,l),d={presentedMode:i,editorChromeHeight:a,stageWidth:c,stageHeight:l,viewport:Lg(h,c),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const u=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,d,i,this._reducedMotion||u?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(e=this._model,t=this._loadOk){const i=this._config?.floor,n=function(e){if(!e.hasFloor)return{kind:"absent"};const t=e.floor;if("string"==typeof t)return t.length?e.spaceIds.includes(t)?{kind:"valid",id:t,source:"id"}:{kind:"invalid",reason:"unknown-id",value:t}:{kind:"invalid",reason:"empty-id",value:t};if("number"==typeof t){if(!Number.isFinite(t))return{kind:"invalid",reason:"non-finite-index",value:t};if(!Number.isInteger(t))return{kind:"invalid",reason:"fractional-index",value:t};if(t<0)return{kind:"invalid",reason:"negative-index",value:t};const i=e.spaceIds[t];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:t}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:t}}({spaceIds:e.map(e=>e.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||t?n:"number"==typeof i?"valid"===n.kind||"invalid"===n.kind&&"out-of-range-index"===n.reason?{kind:"pending",value:i}:n:"valid"===n.kind||"invalid"===n.kind&&"unknown-id"!==n.reason?n:{kind:"pending",value:i}}_canCommitSpace(e,t=!1){if(t||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===e}_commitSpace(e,t=!1){return!!this._canCommitSpace(e,t)&&(e!==this._space&&(this._clearRoomFocus(!0),this._resetDeviceHitState(),this._cancelDangerConfirm(),this._cancelCameraTransition(!1),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._editorRuntime?._clearFurniturePreview()),this._space=e,this._isoProjectionSnapshot=null,!0)}_slideTo(e,t){if(e===this._space)return!0;if(!this._canCommitSpace(e))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary?.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,this._restoreZoom(),i||(this._slide=t,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Xf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){Xf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(vv(e),this._tabDragRelease=e=>this._tabPointerUp(e),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:t,pointerId:e.pointerId,x:e.clientX,y:e.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(e,t,i){const n=this._model.map(e=>e.id),r=n.indexOf(i);if(r<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const s of o){const o=s.dataset.id||"";if(!o||o===i)continue;const a=s.getBoundingClientRect();if(ea.right||ta.bottom)continue;const l=n.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,n;const r=this._tabDropTargetAt(e.clientX,e.clientY,t.id);t.moved&&t.targetId===r?.targetId&&t.placement===r?.placement||(this._tabDrag={...t,moved:!0,targetId:r?.targetId||null,placement:r?.placement||null})}_tabPointerUp(e){const t=this._tabDrag;if(t&&t.pointerId!==e.pointerId)return;const i="pointerup"===e.type&&t?.moved?this._tabDropTargetAt(e.clientX,e.clientY,t.id):null;"pointerup"===e.type&&t?.moved&&this._suppressNextTabClick(),this._endTabDrag(),t?.moved&&i&&this._commitTabOrder(t.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(e){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(e)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(e,t){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const n=this._model.map(e=>e.id),r=function(e,t,i){const n=e.indexOf(t),r=e.indexOf(i);if(n<0||r<0||n===r)return e;const o=e.slice();return o.splice(n,1),o.splice(r,0,t),o}(n,e,t);if(r===n)return;const o=new Map(this._devices.map(e=>[String(e.id),String(e.area||"")])),s=function(e,t,i,n=()=>""){if(!i)return[];const r=[];for(const o of e){if(!o||!0===o.removed)continue;const e="string"==typeof o.id?o.id:"";if(!e)continue;if("string"==typeof o.space&&o.space)continue;const s=("string"==typeof o.area?o.area:"")||n(e)||"";s&&t[s]||r.push({id:e,space:i})}return r}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),n[0]||"",e=>o.get(e)||"");if(s.length){const e=new Map(s.map(e=>[e.id,e.space]));for(const t of i.markers||[]){const i=e.get(String(t.id));i&&(t.space=i)}}i.spaces=function(e,t){const i=new Map(t.map((e,t)=>[e,t]));return e.map((e,t)=>({space:e,index:t})).sort((e,t)=>(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)||e.index-t.index).map(e=>e.space)}(i.spaces||[],r),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(e){if(this._endTabDrag(),e===this._space)return;const t=this._model.map(e=>e.id),i=t.indexOf(this._space),n=t.indexOf(e);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(e,i>=0&&n0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const e=this._model.map(e=>e.id),t=e.indexOf(this._space);this._slideTo(e[(t+1)%e.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(e){this._wallUnionCacheValue=e,null===e&&this._wallUnionPool.clear()}get _glowClipCache(){return this._glowRuntimeState.clipCache}get _glowGeometryWarnings(){return this._glowRuntimeState.geometryWarnings}get _glowFeatherUnits(){return this._glowRuntimeState.featherUnits}set _glowFeatherUnits(e){this._glowRuntimeState.featherUnits=e}get _glowRenderedSources(){return this._glowRuntimeState.renderedSources}get _glowLastAppearance(){return this._glowRuntimeState.lastAppearance}get _glowFeatherSuspendUntil(){return this._glowRuntimeState.featherSuspendUntil}set _glowFeatherSuspendUntil(e){this._glowRuntimeState.featherSuspendUntil=e}get _glowFeatherResumeTimer(){return this._glowRuntimeState.featherResumeTimer}set _glowFeatherResumeTimer(e){this._glowRuntimeState.featherResumeTimer=e}get _glowSourceSeq(){return this._glowRuntimeState.sourceSeq}set _glowSourceSeq(e){this._glowRuntimeState.sourceSeq=e}get _touchSequenceMultitouch(){return this._touchClickGuard.sequenceMultitouch}_syncDangerConfirmLocaleGate(){return this._config&&this.hass?hp(this,mp,wp(this.hass,this._config.language)):"ready"}_dangerConfirmMissingSpace(){const e=this._model;if(!e.length)return!1;const t=this._fixedFloorState(e);return"pending"!==t.kind&&"invalid"!==t.kind&&!this._spaceModel()}_syncVersionRecovery(){this._versionRecovery.update({frontendVersion:Qf(tv),backendVersion:this._haIntegrationVersion,kiosk:!0===this._config?.kiosk,reducedMotion:this._reducedMotion})}_newContinuityController(){return new ac(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(dv,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(e){const t=this._view;if(!t)return null;const i=[t.x+t.w/2,t.y+t.h/2],n="iso"===e?lf(i):i;return{x:n[0],y:n[1]}}_convertProjectionView(e,t){if(e===t)return;this._clearRoomFocus(!0);const i=this._logicalViewCenter(e);this._view=null;const n=i?"iso"===t?af([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,n?.[0],n?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(e){if(!this._labsIso||"view"!==this._mode)return;const t=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:e},"iso"===e){this._ensureIsoSceneRuntime();const e=this._isoSceneKey();e&&this._isoFallback.delete(e),this._isoFallback.delete(`${this._space}|no-borders`),this._clearIsoInvalidFallback()}this._saveViewPreference(),this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i)}_hashSpace(){return Pf(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,this._configReloadAuthority.observeContext(Gu(this)),window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const e=hg(this.ownerDocument);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=oc(this.ownerDocument,this._pageVisibility),this._languageFailureUnsub?.(),this._languageFailureUnsub=function(...e){return()=>{for(const t of e)t()}}((t=()=>{this._showToast(this._t("toast.locale_load_failed"))},_p.add(t),()=>_p.delete(t)),function(e){return Al.add(e),()=>{Al.delete(e)}}(()=>this._showToast(this._t("toast.furniture_art_load_failed")))),super.connectedCallback(),this._summarySlot.connect(),this._ensureLiveRuntime().catch(()=>this.requestUpdate()),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{let t=!1;for(const i of e){for(const e of i.addedNodes)this._syncPointerHoverSubtree(e);const e=e=>{if(e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e;return t.matches(".devlayer, .devlayer *")||!!t.querySelector?.(".devlayer")};(e(i.target)||[...i.addedNodes,...i.removedNodes].some(e))&&(t=!0)}t&&this._invalidateDeviceHitGeometry()}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","data-id"]})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._syncVersionRecovery(),this._versionRecovery.connect(),cg(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>this._referencedContentUrls()),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(e){Ef.add(e);const t=Lf();return"undefined"==typeof window&&e(t),()=>{Ef.delete(e)}}(this._onLabsSnapshot),this._labsIso&&this._ensureIsoSceneRuntime(),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},nv)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._versionRecovery.disconnect(),this._configReloadAuthority.invalidateLifecycle(),this._liveRt?.dispose(),this._radarLive.stop(),this._editorRuntime?._disposeLiveEditor(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._languageFailureUnsub?.(),this._languageFailureUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._warmModeRequest=0,this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._summarySlot.disconnect(),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const e of this._activityRt.values())clearTimeout(e.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,this._editorRuntimeLoadingVisible=!1,this._modeTransition.dispose(),this._cameraTransition.dispose(),this._cameraTransitionFit=null,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),this._cancelDeviceDrag(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer),Pm(this._glowRuntimeState,this._glowRuntimeHost),this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._touchContacts.clear(),this._touchClickGuard.reset(),this._resetDeviceHitState(),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary?.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(e){if("Escape"===e.key&&this._vacFit){if(this._vacFit.busy)return;return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void e.stopPropagation()}if("Escape"===e.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm.busy||(this._vacCalConfirm=null));if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._pdfDialog)return void(this._pdfDialog=!1);if(this._supportDialog)return void this._editorRuntime?._closeSupportDialog();if(this._settingsDialog)return void(this._settingsDialog=null);if(this._summary?.closeDialogIfIdle())return;if(this._markerDialog)return void this._closeMarkerDialog();if(this._deviceInbox)return void(this._deviceInbox=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary?.hasOpenGroup)return e.preventDefault(),void this._editorSecondary?.closeGroup(!0)}const t=e.composedPath?.()||[e.target],i=t.some(e=>e?.matches?.('input, textarea, select, [contenteditable="true"]')),n=t.some(e=>e?.classList?.contains?.("editor-secondary")),r=e.ctrlKey||e.metaKey,o=e.key.toLowerCase(),s=/^[a-z]$/.test(o),a="z"===o||!s&&"KeyZ"===e.code,l="y"===o||!s&&"KeyY"===e.code,c=r&&(a&&e.shiftKey||l),h=r&&a&&!e.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry();if(("Delete"===e.key||"Backspace"===e.key)&&this._decorSel&&!i&&!n)return e.preventDefault(),void this._decorDeleteSel();const t="ArrowLeft"===e.key?[-this._gridPitch,0]:"ArrowRight"===e.key?[this._gridPitch,0]:"ArrowUp"===e.key?[0,-this._gridPitch]:"ArrowDown"===e.key?[0,this._gridPitch]:null;return!t||r||e.altKey||"select"!==this._decorTool||!this._decorSel||!this._decorList.some(e=>e.id===this._decorSel)||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag||i||n||this._editorSecondaryDialogBlocked?void("Escape"===e.key&&(e.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._furnPalette=null,this._furnCategory=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(e.preventDefault(),void this._decorNudge(t[0],t[1]))}if("devices"===this._mode){if((h||c)&&i)return;return c?(e.preventDefault(),void this._redoDevicePosition()):h?(e.preventDefault(),void this._undoDevicePosition()):void("Escape"===e.key&&this._deviceDrag&&(e.preventDefault(),this._cancelDeviceDrag()))}if(this._markup&&(!h&&!c||!i)){if(("Delete"===e.key||"Backspace"===e.key)&&this._physicalSel&&!i&&!n)return e.preventDefault(),void this._deletePhysicalSelection();if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===e.key)return this._physicalDrag||this._physicalRotate?(e.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(e.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(e.preventDefault(),void this._finishWallChain()):this._physicalSel?(e.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():("exit-tool"===this._resize?.escapeIdle()&&(this._tool="draw"),void this.requestUpdate())):"split"===this._tool?(e.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(e.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(e.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(e.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length)return this._contourClosed?(this._path=this._path.slice(0,-1),void(this._closingWallCm=null)):void(this._activeWallChainPartitionIds.length&&this._path.length>1?this._undoActiveWallPoint():this._path=this._path.slice(0,-1))}_undoActiveWallPoint(){const e=[...this._activeWallChainPartitionIds],t=e[e.length-1],i=this._spaceModel()?.partitions.find(e=>e.id===t),n=this._path[0]?[...this._path[0]]:null,r=this._path.slice(0,-1).map(e=>[...e]),o=this._wallChainSegmentCms.slice(0,-1),s=this._geometryHistory.undo();if(!s)return this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._wallChainRedo=[],void(this._path=n?[n]:[]);this._applyGeometryState(s.before,!0)?(this._activeWallChainId||=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=e.slice(0,-1),this._path=r.length?r:n?[n]:[],this._wallChainSegmentCms=o,i&&this._wallChainRedo.push({id:i.id,point:[...i.b],cm:i.cm}),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:s.name}))):this._geometryHistory.clear()}static async getConfigElement(){return await import("./editor-DCXyMNgY.js"),document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of rv.values())for(const t of e)clearTimeout(t.evict);rv.clear(),sv=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const n of rv.values())for(const r of n)e++,r.dlg&&(t++,i.push(r.dlg.kind));return{keys:rv.size,slots:e,dlgs:t,drafts:i}}setConfig(e){const t=this._config,i=!!t&&Object.prototype.hasOwnProperty.call(t,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...e};(i!==this._hasFixedFloor||t?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&e.default_floor&&this._commitSpace(e.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(cv)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(dv)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}if(this._labs=Lf(),this.isConnected&&this._labsIso&&this._ensureIsoSceneRuntime(),!this._summary?.applyLocalScaleForCurrentIdentity())try{const e=JSON.parse(localStorage.getItem("houseplan_card_kiosk_v1")||"null");this._kioskScale={icon:Bn(e?.icon),font:Bn(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(lv)||"null");this._adoption.restoreCached(e)&&(this._seedDecorStyle(this._serverCfg),this._cfgEpoch++,this._virtualLights=Nh(e.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1),this._syncVersionRecovery()}_warmAdopt(){if(this._config?.kiosk)return;const e=Rf(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),n=rv.get(e);if(!n||!n.length)return;const r=n.find(e=>e.owner===this._warmGen);if(r)return this._warmLongReturn=!!r.freed&&Date.now()-r.freed>=ic,clearTimeout(r.evict),r.evict=0,r.freed=0,r.live=!0,this._warmSlot=r,this._warmKey=e,r.frameFingerprint&&this._continuity.adoptCompleteFrame(r.frameFingerprint),void(!this._devices.length&&r.devices?.length&&(this._devices=[...r.devices]));const{slot:o,sure:s}=((e,t,i,n)=>{const r=e=>{const t=!!i&&e.place?.deref()===i;return t&&e.idx===n?4:e.live?0:t?3:2};let o=null,s=0,a=0,l=null;for(const i of e){if(i.owner===t)continue;l=i;const e=r(i);e<=0||(e>s?(o=i,s=e,a=1):e===s&&a++)}return!o||a>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(n,this._warmGen,t,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=ic,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},nv)),this._warmKey=e,s?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=t?new WeakRef(t):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},n.push(this._warmSlot),this._warmTrim(n)))}_warmIdx(e){const t=e?.children;if(!t)return-1;for(let e=0;e4;){const t=e.findIndex(e=>!e.live);if(t<0)break;clearTimeout(e[t].evict),e.splice(t,1)}}_warmScheduleEvict(e,t){if(clearTimeout(e.evict),!(e.dlg||e.vp&&"view"!==e.vp.mode))return;const i=e.freed,n=e.owner;e.evict=window.setTimeout(()=>{if(e.evict=0,e.freed!==i||e.owner!==n)return;var r;e.dlg=null,e.vp=(r=e.vp)&&"view"!==r.mode?{...r,mode:"view",zoom:r.snap?.space===r.space?r.snap.zoom:r.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:r,e.frameFingerprint="";const o=rv.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},sv+250)}_warmAdoptViewport(e){const t=this._warmVp;if(!t||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(e=>e.id===t.space)||"valid"===i.kind&&i.id!==t.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(t.space,!0),this._navApplied=!0;const n="view"!==t.mode&&this._canEdit&&!e.kiosk?t.mode:"view";this._adoptMode("view"),this._pendingNavMode="view"===t.mode||this._canEdit||e.kiosk?null:t.mode,this._zoom=t.zoom;const r=this._effectiveProjection(),o=r===t.projection&&this._labsIso===t.activeLabsIso;if(this._view=o&&t.view?{...t.view}:null,this._viewModeSnap=o&&t.snap?{...t.snap}:null,!o&&t.logicalCenter){const e="iso"===r?af([t.logicalCenter.x,t.logicalCenter.y],0):[t.logicalCenter.x,t.logicalCenter.y];this._applyView(t.zoom,e[0],e[1])}var s;this._tool="opening"===(s=function(e){return"partition"===e?"draw":e}(s=t.tool))?"draw":"string"==typeof s&&Mf.has(s)?s:"draw",this._decorTool=t.decorTool,this._showHidden=t.showHidden,this._showFar!==t.showFar&&(this._showFar=t.showFar,this._frame=null),this._selId=t.selId,this._resize?.restoreSelection(t.rszSel),this._decorSel=t.decorSel,this._warmVpArmed=!0,"view"!==n&&this._requestMode(n,!1,!0)}_warmPatch(e,t=!1){if(this._config?.kiosk)return;const i=Rf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!t)return;const e=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:this._warmIdx(e),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const n=rv.get(i)||[];for(n.push(this._warmSlot),rv.set(i,n),this._warmTrim(n);rv.size>8;){const e=rv.keys().next().value;if(void 0===e||e===i)break;for(const t of rv.get(e)||[])clearTimeout(t.evict);rv.delete(e)}}Object.assign(this._warmSlot,e)}}_warmViewportState(){const e=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:e,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(e),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._resize?.selectedRoomId,decorSel:this._decorSel}}_warmDialogState(){const e=(e,t)=>({kind:e,space:this._space,mode:this._mode,data:t});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?e("openingInfo",this._openingInfo.id):this._infoCard?e("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:e("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:e("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:e("marker",this._markerDialog):this._openingDialog?e("opening",this._openingDialog):this._backdropDialog?e("backdrop",this._backdropDialog):this._decorShapeDialog?e("decorShape",this._decorShapeDialog):this._decorTextDialog?e("decorText",this._decorTextDialog):this._roomDialog?e("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempMin:this._roomTempMin,tempMax:this._roomTempMax,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:e("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const e={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices,hdrH:this._hdrH};if(this._warmRevivePending||(e.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const t=this.parentNode;e.place=t?new WeakRef(t):null,e.idx=this._warmIdx(t)}this._warmPatch(e)}_warmReviveDialog(){const e=this._warmSlot;if(this._warmReviveTimer=void 0,!e||!e.dlg)return void(this._warmRevivePending=!1);const t=e.dlg,i=e.freed;if(t.mode===this._mode||"view"===t.mode||this._warmVp?.mode!==t.mode||this._editorRuntime){if(this._warmRevivePending=!1,e.dlg=null,e.freed=0,clearTimeout(e.evict),e.evict=0,i&&!(Date.now()-i>sv)&&t.space===this._space&&t.mode===this._mode){switch(t.kind){case"space":this._spaceDialog={...t.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...t.data,busy:!1};break;case"settings":this._settingsDialog={...t.data,busy:!1};break;case"rules":this._rulesDialog={...t.data,busy:!1};break;case"opening":this._openingDialog={...t.data};break;case"backdrop":this._backdropDialog={...t.data};break;case"decorShape":this._decorShapeDialog={...t.data};break;case"decorText":{this._decorTextDialog={...t.data};const e=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:e,end:e};break}case"room":{const e=t.data;this._roomEditId=e.editId,this._roomFill=e.fill,this._roomCustomFill=e.customFill||null,this._roomTempMin=e.tempMin||"",this._roomTempMax=e.tempMax||"",this._roomTempSrc=e.tempSrc,this._roomHumSrc=e.humSrc,this._roomSrcOpen=e.srcOpen,this._roomSrcFilter=e.srcFilter,this._roomNameScale=e.nameScale,this._roomLabelScale=e.labelScale,this._areaSel=e.areaSel,this._nameSel=e.nameSel,this._pendingSplit=e.pendingSplit,this._wallFaceBatch=e.wallFaceBatch||null,this._path=e.path,this._wallFaceBatch&&(this._activeWallChainId=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=[...this._wallFaceBatch.activePartitionIds],this._wallChainSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const e=this._devices.find(e=>e.id===t.data);e&&(this._infoCard=e);break}case"openingInfo":{const e=(this._curSpaceCfg?.openings||[]).find(e=>e.id===t.data);e&&(this._openingInfo=e);break}}this.requestUpdate()}}else this._warmRevivePending=!0}_cacheSnapshot(){if(this._serverCfg)try{this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const n=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(Bh).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>n.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev);const e=this._adoption.snapshot(function(e){return{rev:e.rev,config_rev:e.configRev,off:[...e.off].sort()}}(this._virtualLights));e&&localStorage.setItem(lv,JSON.stringify(e))}catch{}}_beginContinuityCandidate(e,t,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(e,i))}_continuityStageValid(){const e=this._stageEl;return!!e&&e.clientWidth>0&&e.clientHeight>0}_versionReloadSafetySnapshot(){return xg(this)}_continuityAssetsReady(){if(!this._model.length)return!1;const e=this._model.length?this._spaceModel():null;return!e?.bg?.href||this._signer.isReady(this.hass,e.bg.href)}_initialSpaceSelection(e,t=this._loadOk){const i=this._fixedFloorState(e,t);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(e){const t=new Set(e.spaceIds.filter(e=>!!e));if(!t.size)return{id:null,source:"none"};const i=[["hash",!1===e.acceptHash?null:e.hashSpace],["current",e.preserveCurrent?e.currentSpace:null],["saved",e.savedSpace],["default",e.defaultSpace],["first",e.spaceIds[0]]];for(const[e,n]of i)if(n&&t.has(n))return{id:n,source:e};return{id:null,source:"none"}}({spaceIds:e.map(e=>e.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(e,t=this._loadOk){const i=this._initialSpaceSelection(e,t);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(e,t=this._space){const i=Xa(e),n=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==n.kind)return"";const r=this._initialSpaceSelection(i,!0).id||(i.some(e=>e.id===t)?t:i[0]?.id);return i.find(e=>e.id===r)?.bg?.href||""}_visualFrameFingerprint(){const e=this._stageEl,t=e?[e.clientWidth,e.clientHeight]:[0,0];return cc([this._cfgRev,this._adoption.currentConfigFingerprint(),this._layoutRev,this._adoption.currentLayoutFingerprint(),this._space,this._mode,this._view,t,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const e=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==e)return this._stagedDeviceSnapshotToken=e,void this.requestUpdate();this._continuityPaintToken!==e&&(this._continuityPaintToken=e,this._continuity.candidateReady(e)&&this._continuity.commitAfterPaint(e,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(e,t){this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const e="connection"===this._continuity.recoveryReason;return j`
    e.stopPropagation()} @click=${e=>e.stopPropagation()} @@ -356,7 +356,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 aria-label=${this._t("editor.loading_aria")}> ${this._t("editor.loading")} -
    `:G}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}getGridOptions(){return{columns:"full"}}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],n=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(n?n[0]+"/"+n[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Ya(e).map((t,i)=>{const n=e.spaces[i]?.plan_url;return t.bg&&n?{...t,bg:{...t.bg,href:n}}:t})}_spaceModel(){return this._hasFixedFloor?bc(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return bc(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0,this._clearRoomFocus(!0);for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._deviceDrag=null,this._resetDeviceHitState(),this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary?.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit))return;const e=this._serverCfg,t=Jd({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const n of t){const t="h"+n.slice(n.indexOf(":")+1);e.markers.push({id:t,binding:n,hidden:!0}),i.push(n.slice(n.indexOf(":")+1))}const n={...e.settings||{},filter_seeded:!0};delete n.show_all,i.length&&Array.isArray(n.new_device_ids)&&(n.new_device_ids=n.new_device_ids.filter(e=>!i.includes(e))),e.settings=n,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Ee(e)),this._rulesCompiled}get _fillColors(){return gn(this._settings)}get _excluded(){return su(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,this._summary?.willUpdate(),e.has("hass")&&this._configReloadAuthority.observeContext(Uu(this)),e.has("_serverCfg")){const e=this._cfgEpochPreservedConfig===this._serverCfg;this._cfgEpochPreservedConfig=null,e||this._cfgEpoch++,this._renderLife.invalidate()}if(this._syncEmptySpaceState(),this._dangerConfirm&&(this._dangerConfirmMissingSpace()||"warm"===this._syncDangerConfirmLocaleGate())&&this._cancelDangerConfirm(),e.has("hass")&&this.hass){const t=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;this._renderLife.observe(e.get("hass"),this.hass,t?{entityIds:t.entityIds}:null,()=>Sg(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._summary?.updated(),this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._syncRadarLive(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>{this._invalidateDeviceHitGeometry(),this._refitView(),requestAnimationFrame(()=>this._summary?.resized())}),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=Jg(this.renderRoot,e,this.panelHost);null!==t&&(t>=0&&t!==this._hdrH&&(this._hdrH=t),t>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:t,stageH:e.clientHeight}))};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary?.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&this._canManageConfiguration&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,n=t.level??1e9;return i!==n?i-n:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptConfigCapabilities(e){wg(this,e)}_syncRadarLive(){const e=this._serverCfg?.settings?.radar,t=(this._serverCfg?.markers||[]).some(e=>Mg(e,this._space));this._radarLive.sync(this._space,1===this._haRadarStage1Api&&"view"===this._mode&&!1!==e?.show_live&&t&&"hidden"!==this.ownerDocument.visibilityState)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await hm(this.hass,am(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptAuthoritative(e){return Bu(this,e)}_rollbackOptimistic(e){const t=this._adoption.rollbackOptimistic(e);return t&&this.requestUpdate(),t}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}_getAuthoritativeConfig(){return e=this,async function(e,t){const i=await e();return t(i),i}(()=>e.hass.callWS({type:"houseplan/config/get"}),t=>wg(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;let i=!1;const n=()=>{i=!0,this._regSignature="",this._maybeRebuildDevices()};try{const[i,r]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this._adoptAuthoritative({cfgResp:i,layResp:r,reason:"structural-response",profile:"reload",beforeAdopt:()=>{this._connectionWasLost=!1,this._serverStorage=!0},afterAdopt:()=>{this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,n()}})).status)return;this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(sv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,i||n(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],n=(n,r,o,s)=>{n()||i.push(async()=>{const i=await e.subscribeEvents(s,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!n()?r(i):i?.()})};if(n(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),n(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),n(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),n(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=qh(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const r=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=r,r.finally(()=>{this._liveSyncAttempt===r&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){return Gu(this,e,t)}_scheduleLoadRetry(e=!1){if(void 0!==this._loadRetryTimer)return;const t=Math.min(8e3,500*2**Math.min(4,Math.max(1,this._loadTries-7)));this._loadRetryTimer=window.setTimeout(()=>{this._loadRetryTimer=void 0,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}async _ensureLiveRuntime(){if(this._liveRt)return;const e=await import("./live-interaction-runtime-CxW-k-p_.js");this._liveRt=new e.LiveRuntime(this),this.isConnected&&this.requestUpdate()}_liveVp(e=!1){this._liveRt?this._liveRt.viewport(e):this.requestUpdate()}_syncLiveHover(){this._liveRt?this._liveRt.hover():this.requestUpdate()}_flushHa(){this._liveRt?.take()&&(this._terminalFrame=2,super.requestUpdate())}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._renderLife.invalidate(),this._areaSnapshotCleanupCandidates.clear(),this._planHassMemo=null,this._haRegistryRelease=Qh(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return td(this.hass)}get _planHass(){const e=this._haRegistry,t=nd(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=od(this.hass,e),r=sd(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:n,full:r},n}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+Qm)>e?1:0)).join("|"),i=Hh(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const n=this._planHass,r=new Map,o=new Map,s=new Set(["sun.sun"]);for(const e of this._summary?.entityIds()||[])s.add(e);this._vacFit?.source&&s.add(this._vacFit.source);const a=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void s.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?a.add(n):"entity"===i&&s.add(n)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of ui(t))s.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Ki(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,Qi(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!Xd(n,e,Yd(this._markers))))}const h=Id(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(m_(e.id,t),d_(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,n),i=t?qc(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=sh(e.id,e.marker?.vacuum??null,e.space,t),a=lh({routes:s,observed:ch(s,[t],t=>this._vacObservedMapId(e,t,n)),spaceIds:new Set(this._model.map(e=>e.id))});o.set(`vacuum:${e.id}`,{source:t,telemetry:i,routes:s,resolution:a,mapId:i?this._vacMapId(e,i,n):null,runtime:r?{trail:r.trail,lastTs:r.lastTs,moving:r.moving,jump:r.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=__({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,positions:(u=this._model.length>0,p=this._devices,_=e=>this._livePos(e),u?new Map(p.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:s,deviceIds:a,areaIds:l});var u,p,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _renderVacuumDevices(){return this._renderDeviceSnapshot?.vacuumDevices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return cd(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const{registry:e,bindings:t}=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e));return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&mv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else mv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_referencedContentUrls(){const e=On(this._serverCfg);for(const t of this._decorAssets.values())e.add(t.url);return e}_resign(){this._signer.resign(this.hass,this._referencedContentUrls())}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){this._adoption.noteLayoutRevision(e?.rev)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,n]of e)null===n?delete i[t]:i[t]=n;this._adoption.adoptMergedLayout(i,t,()=>{this._cancelDeviceDrag(),this._devicePositionHistory.clear()}),this._canOptimizeUndo=!!t?.can_optimize_undo,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_persistLocalLayout(){this._layout=yo(no(this._layout)),localStorage.setItem(sv,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=nd(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+bp(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const n=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=eu({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const r=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+r.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const n of r)i.set(n,cd(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=ld(),i=Date.now();for(const[n,r]of e)"active"===r.kind?t[n]={kind:"active",ts:i}:"ha_disabled"===r.kind&&(t[n]={kind:"ha_disabled",reason:r.reason,ts:i});const n=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Vh=n;try{localStorage.setItem(Gh,JSON.stringify(n))}catch{}}(i),this._haBindingCacheKey=o}let s=null;if(t.authoritative&&(s=this._resolveAreaRelocations(t),this._areaRelocationIds=new Set(s.relocateIds),this._areaRelocationIds.size)){this._cancelDeviceDrag();const e=this._areaRelocationIds;this._devicePositionHistory.removeWhere(({before:t,after:i})=>e.has(t.deviceId)||e.has(i.deviceId));const t=this._markerDialog;if(t?.devId&&!t.roomTouched&&this._areaRelocationIds.has(t.devId)){const e=this._devices.find(e=>e.id===t.devId);e&&(this._markerDialog={...t,room:e.marker?.room_id?`${e.space}#@${e.marker.room_id}`:e.space&&e.area?`${e.space}#${e.area}`:""})}}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),s&&this._syncAreaRelocations(s),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const l=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==n.get(e.id));l&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._deviceDrag&&"ha_disabled"===this._devices.find(e=>e.id===this._deviceDrag.id)?.bindingStatus?.kind&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear()),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(_v(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=Z_(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])X_(t)&&Number.isFinite(r)&&i.has(t)&&n.set(t,r);const r=new Set,o=new Set;for(const t of e.markers||[])t.removed||(Y_(t.id)&&r.add(t.id),X_(t.binding)&&o.add(t.binding));const s=new Set(Object.keys(e.registryDevices||{})),a=new Set(Object.keys(e.registryEntities||{})),l=new Set(Object.keys(e.liveStates||{})),c=new Map;for(const[e,i]of Object.entries(t)){const t=c.get(i.binding)||[];t.push(e),c.set(i.binding,t)}const h=new Set;let d=!1;for(const[t,i]of c){const[c,u]=im(t);if(o.has(t)||i.some(e=>r.has(e))||("device"===c?s.has(u):a.has(u)||l.has(u))){n.delete(t);continue}const p="device"===c?s.size>0:a.size>0;if(!e.authoritative||!p)continue;const _=n.get(t);if(void 0!==_){if(_!==e.revision)for(const e of i)h.add(e)}else n.set(t,e.revision),d=!0}return{removeIds:h,candidates:n,needsConfirmationRefresh:d}}({snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,revision:e.revision,registryDevices:e.devices,registryEntities:e.entities,liveStates:this.hass?.states,markers:this._markers,previousCandidates:this._areaSnapshotCleanupCandidates});return this._areaSnapshotCleanupCandidates=t.candidates,t.needsConfirmationRefresh&&this._canEdit&&ed(this.hass),nm({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:uv})}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:n,known:r}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),n=e.filter(e=>!i.has(e));return{fresh:n,known:n.length?[...t,...n]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||n.length){const e=[...new Set([...i.new_device_ids||[],...n])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:r,new_device_ids:e}},this._saveConfig()}}_syncAreaRelocations(e){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit&&this._haRegistry.authoritative))return;const t=e.decisions.filter(e=>e.updateSnapshot||e.removeSnapshot);if(!t.length)return;const i=ac({snapshot:Z_(this._settings.marker_area_snapshot),decisions:t});i!==this._areaRelocationSyncKey&&(this._areaRelocationSyncKey=i,this._areaRelocationWrite=this._areaRelocationWrite.catch(()=>{}).then(async()=>{if(!this._serverCfg||!this._haRegistry.authoritative)return;const e=this._resolveAreaRelocations();this._areaRelocationIds=new Set(e.relocateIds);const t=new Set,i=new Map;let n=!1;for(const r of e.decisions){if(!r.relocate)continue;const e=mg(this._layout,r.id);try{await this._persistDevicePlacement(r.id,null),t.add(r.id),e&&i.set(r.id,e),this._areaRelocationIds.delete(r.id)}catch(t){n=!0,this._layout=gg(this._layout,r.id,e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}}const r=this._settings,o=function(e,t,i=new Set){const n=Z_(e);for(const e of t.decisions)e.removeSnapshot?delete n[e.id]:e.updateSnapshot&&e.binding&&e.area&&(e.relocate&&!i.has(e.id)||(n[e.id]={binding:e.binding,area:e.area}));return n}(r.marker_area_snapshot,e,t),s=[...new Set([...Array.isArray(r.new_device_ids)?r.new_device_ids:[],...t])],a=ac(o)!==ac(Z_(r.marker_area_snapshot)),l=ac(s)!==ac(Array.isArray(r.new_device_ids)?r.new_device_ids:[]);if(a||l){const e=r.marker_area_snapshot,n=r.new_device_ids,a={...this._serverCfg,settings:{...r,marker_area_snapshot:o,...l?{new_device_ids:s}:{}}};this._setAreaLifecycleConfig(a);try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.cancel(),await this._writeConfig()}catch(r){const a=this._settings;if(ac(a.marker_area_snapshot)===ac(o)&&ac(a.new_device_ids)===ac(l?s:n)){const t={...a};void 0===e?delete t.marker_area_snapshot:t.marker_area_snapshot=e,void 0===n?delete t.new_device_ids:t.new_device_ids=n;const i={...this._serverCfg,settings:t};this._setAreaLifecycleConfig(i),this._adoption.refreshConfigFingerprint()}for(const e of t)this._areaRelocationIds.add(e);const c=new Set;for(const[e,t]of i)try{await this._persistDevicePlacement(e,t)}catch(t){c.add(e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}this._areaRelocationSyncKey="",this._regSignature="";if("conflict"===(r&&"object"==typeof r&&"code"in r?r.code:void 0)?(this._showToast(this._t("toast.conflict")),await this._reloadConfigOnly(!0)):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(r)})),c.size&&this._serverCfg){const e=this._settings,t=[...new Set([...Array.isArray(e.new_device_ids)?e.new_device_ids:[],...c])],i={...this._serverCfg,settings:{...e,new_device_ids:t}};this._setAreaLifecycleConfig(i);try{await this._writeConfig()}catch(e){this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)}))}}}}n&&(this._areaRelocationSyncKey=""),this.requestUpdate()}))}get _newIds(){const e=this._settings.new_device_ids;return new Set([...Array.isArray(e)?e:[],...this._areaRelocationIds])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const n=Nd(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return Ii(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),n=Math.min(...t),r=Math.min(...i);return{x:n,y:r,w:Math.max(...t)-n,h:Math.max(...i)-r}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const n=t/100*wl(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const r=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!r.length)continue;const o=this._roomBounds(t),s=.1*Math.min(o.w,o.h),a=o.w-2*s,l=o.h-2*s,c=Math.max(1,Math.round(Math.sqrt(r.length*a/Math.max(l,1)))),h=Math.ceil(r.length/c),d=a/c,u=l/Math.max(h,1),p=r.map((e,t)=>({x:o.x+s+d*(t%c+.5),y:o.y+s+u*(Math.floor(t/c)+.5)}));Ei(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=il(p[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._areaRelocationIds.has(e.id)?void 0:this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*uv,y:i.y*uv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?il(bl(t)):{x:500,y:500}}_devicePlacementForCanvas(e,t,i){if(!this._norm)return{x:Math.round(t),y:Math.round(i)};const n=this._gridPitch,r=Math.round(t/n)*n,o=Math.round(i/n)*n;return{s:e.space,x:rl(r/uv),y:rl(o/uv)}}_previewDevicePlacement(e,t){this._layout=gg(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null,this._deviceHits.cancel(e.pointerId);try{e.source?.hasPointerCapture?.(e.pointerId)&&e.source.releasePointerCapture(e.pointerId)}catch{}return this._previewDevicePlacement(e.id,e.before),!0}async _persistDevicePlacement(e,t){if(this._layout=gg(this._layout,e,t),this._serverStorage){let i=null,n=!1;try{let r;if(null===t)i=null,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/delete",device_id:e});else{const t=vo(this._layout[e]);ac(t)!==ac(this._layout[e])&&(this._layout={...this._layout,[e]:t}),i=t,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t})}this._noteLayoutRev(r),this._adoption.refreshLayoutFingerprint(),this._cacheSnapshot()}finally{n&&this._sentPos.get(e)===i&&this._sentPos.delete(e)}return}this._persistLocalLayout()}_devicePositionStateValid(e){const t=this._devices.find(t=>t.id===e.deviceId);return!!t&&t.space===e.spaceId&&"ha_disabled"!==t.bindingStatus?.kind&&!!this._spaceModelById(e.spaceId)}async _runDevicePositionHistory(e){if(this._cancelDeviceDrag()||this._devicePositionBusy)return;const t="undo"===e?this._devicePositionHistory.undo():this._devicePositionHistory.redo();if(!t)return;const i="undo"===e?t.before:t.after;if(!this._devicePositionStateValid(i))return this._devicePositionHistory.clear(),this._showToast(this._t("history.device_stale")),void this.requestUpdate();const n=mg(this._layout,i.deviceId);i.spaceId!==this._space&&(this._commitSpace(i.spaceId),this._restoreZoom()),this._devicePositionBusy=!0,this._previewDevicePlacement(i.deviceId,i.placement);try{await this._persistDevicePlacement(i.deviceId,i.placement),this._showToast(this._t("undo"===e?"history.undone":"history.redone",{name:t.name}))}catch(t){this._previewDevicePlacement(i.deviceId,n),"undo"===e?this._devicePositionHistory.redo():this._devicePositionHistory.undo(),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}finally{this._devicePositionBusy=!1,this.requestUpdate()}}_undoDevicePosition(){this._runDevicePositionHistory("undo")}_redoDevicePosition(){this._runDevicePositionHistory("redo")}_savePos(e,t,i){this._spaceModelById(e.space)&&(this._layout=gg(this._layout,e.id,this._devicePlacementForCanvas(e,t,i)),this._dirtyPos.add(e.id),this._persistLayout())}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const n=i?null:this._renderDeviceSnapshot?.presentations.get(m_(e.id,t));return n||d_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,h_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=Ld(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Hd(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Vn(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._kiosk&&(this._cyclePausedUntil=Math.max(this._cyclePausedUntil,Date.now()+6e4)),this._nativeMoreInfoEntity=e,_v(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._roomPointer=null,this._doubleFit.clear(),this._deviceHits.clearPointers()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_invalidateDeviceHitGeometry(){this._deviceHits.invalidate()}_resetDeviceHitState(){this._deviceHits.reset(this.renderRoot)}_deviceHitOwnerAt(e,t){return"view"!==this._mode&&"devices"!==this._mode?null:this._deviceHits.at(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForPointerEvent(e,t){return this._deviceHits.pointer(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForClickEvent(e,t){return this._deviceHits.click(this.renderRoot,this._renderDevices,this._space,e,t)}_showDeviceTip(e,t){this._liveRt?this._liveRt.devicePointerTip(e,t):this._ensureLiveRuntime().then(()=>this._liveRt?.devicePointerTip(e,t))}_showDeviceFocusTip(e,t){const i=e.currentTarget;this._liveRt?this._liveRt.deviceFocusTip(i,t):this._ensureLiveRuntime().then(()=>this._liveRt?.deviceFocusTip(i,t))}_hideDeviceFocusTip(e){this._liveRt?.deviceBlur(e)}_clearPointerHover(){this._liveRt?this._liveRt.pointerLeave():this._clearTransientHover()}_ctxDevice(e,t){"view"===this._mode&&(t=this._deviceForPointerEvent(e,t),e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if(e.stopPropagation(),t=this._deviceForClickEvent(e,t),this._deviceDrag?.moved||this._suppressClick||this._holdFired)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const n=Ru(i.tapAction,i.primary?.split(".")[0]);if("none"===n)return;const r=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===n){const e=this._toggleIntent(i);if(!e)return;if(!Fu(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Fu(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=qh(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:n}=t;this._startDevicePressFeedback(i.id),this.hass.callService(n.domain,n.service,n.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},n=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const r=this._toggleConfirmationLines(e);if(!r.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:n}),lines:r,initialIntent:e,deviceId:i.id,exec:()=>{const n=this._devices.find(e=>e.id===i.id),r=n?this._toggleIntent(n):null;r&&!Fu(r)&&this._showUnavailableToggleTargets(r)||(r&&Iu(e,r)?t(r):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===n)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===n){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),n=this.hass.states[e];if(!t||!n)return void this._showToast(this._t("toast.run_target_missing"));const o=n.attributes?.friendly_name||e;return void r(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===n&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Fu(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!zu.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!zu.has(n.reason))continue;const e=String(n.name||n.entityId||n.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const n=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),r=Number.isFinite(n)?Math.max(.95,Math.min(1,n)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(r)},{scale:"0.95",offset:.5},{scale:"1"}],s=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,s);const a=()=>{this._devicePressAnimations.get(e)===s&&this._devicePressAnimations.delete(e)};s.addEventListener("finish",a,{once:!0}),s.addEventListener("cancel",a,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return wp(bp(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex"),confirm:this._t("color_picker.confirm")}}_help(e){return this._editorRuntimeOrThrow()._help(e)}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const n=this._pos(i);t.push({minX:n.x,minY:n.y,maxX:n.x,maxY:n.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,n=Math.cos(i)*e.rlen/2,r=Math.sin(i)*e.rlen/2,o=ll([[e.rx-n,e.ry-r],[e.rx+n,e.ry+r]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){if("image"===e.kind&&!this._decorAssets.has(e.asset_id)&&"decor"!==this._mode)continue;const n=ll("line"===e.kind?[[e.x1*uv,e.y1*i],[e.x2*uv,e.y2*i]]:"text"===e.kind?[[e.x*uv,e.y*i]]:Fr({x:e.x*uv,y:e.y*i,w:e.w*uv,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=ll(i);e&&t.push(e)}}return pl(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:uv,h:uv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const n=fl(this._contentItems(e));let r=n.all||yl(e),o=this._showFar?r:n.core||yl(e);return t&&t.id===e.id&&i&&t.grow&&(o=pv(t.rect,o),r=pv(t.all,r)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:r,outliers:n.outliers},this._frame}_isoSource(){const e=this._isoSceneRuntime;if(!e)return null;const t=this._spaceModel();if(!t)return null;const i=this._spaceWalls,n=this._openCuts(),r=this._openingsR;return e.createIsoStructuralSource({space:t,walls:i,openCuts:n,openings:r,partitionCuts:()=>this._partitionOpeningCuts(t),roomOpenings:()=>this._roomWallOpeningInputs(r,t),cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,coordinateScale:uv,onBuild:()=>{this._isoStructuralBuildCount+=1}})}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return this._isoInvalidKey()}}_isoInvalidKey(){return`${this._space}|invalid|${this._cfgEpoch}`}_clearIsoInvalidFallback(e){const t=`${this._space}|invalid|`;for(const i of this._isoFallback)i.startsWith(t)&&i!==e&&this._isoFallback.delete(i)}_isoScene(e=this._isoSource()){const t=this._isoSceneRuntime;if(!t||!e)return null;let i=this._frameOf().rect;const n=this._spaceDisplayForRender(),r=this._spaceModel();if(r&&n.showNames)for(const e of r.rooms)if(e.name){const t=this._labelPos(e,r.id);i=pv(i,{x:t.x,y:t.y,w:0,h:0})}const o=t.resolveIsoScene({source:e,cache:this._isoGeometryCache,cellCm:this._cellCm,liveFrame:i});if(!r||!n.showBorders)return o;const s=this._config?.icon_size??2.5,a=s>8?2.5:s,l=this._stageEl?.getBoundingClientRect?.()??null,c=l?.height?l.width/l.height:o.frame.w/o.frame.h,h=Oi([o.frame.x,o.frame.y,o.frame.w,o.frame.h],c),d=this._isoOverlayScene(r,this._renderDevices.filter(e=>e.space===r.id&&!e.hidden),h,n,t.resolveIsoDecorationLayers(n),o,a,w_(a),n.showLqi??this._config?.show_signal??!0,!1),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>Oi([e.x,e.y,e.w,e.h],c)});return u?{...o,frame:u.bounds,overlayFitEntries:d.entries}:o}_latchIsoFallback(e,t){if(this._isoFallback.has(e))return;this._isoFallback.add(e);const i=e.includes("|invalid|")?"invalid":e.split("|").pop()||"invalid";console.warn("HOUSEPLAN ISO FALLBACK: #89/#160",yf("structural",i,!0))}_effectiveProjection(){if(this._isoProjectionSnapshot)return this._isoProjectionSnapshot;const e=e=>this._isoProjectionSnapshot=e,t=()=>("iso"===this._renderProjection&&(this._cancelCameraTransition(!1),this._view=null,this._viewModeSnap=null),e("flat"));if(this._renderIsoScene=null,"iso"!==this._desiredProjection||!this._model.length||!this._isoSceneRuntime)return e("flat");if(!this._spaceDisplayForRender().showBorders)return this._isoFallback.has(`${this._space}|no-borders`)?t():e("iso");let i=this._isoInvalidKey();if(this._clearIsoInvalidFallback(i),this._isoFallback.has(i))return t();try{const n=this._isoSource();if(!n)return e("flat");if(i=n.key,this._isoFallback.has(i))return t();const r=this._isoScene(n);return r?this._isoFallback.has(r.key)?t():(this._renderIsoScene=r,e("iso")):e("flat")}catch(e){return this._latchIsoFallback(i,e),t()}}_scenePoint(e){return"iso"===this._renderProjection?sf(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=af([e.x,e.y]),i=af([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_isoOverlayScene(e,t,i,n,r,o,s,a,l,c=!0){const h=this._isoSceneRuntime;return h&&r?.structural&&o?h.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,wallSilhouettes:o.wallSilhouettes,resolveCollisions:c,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:"view"===this._mode?this._kioskScale.icon:1,kioskFontScale:"view"===this._mode?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),positionOf:e=>this._pos(e),presentationOf:(e,t)=>this._devicePresentation(e,t),labelPositionOf:(e,t)=>this._labelPos(e,t),labelScaleOf:e=>this._labelScale(e),openingEntityAvailable:e=>this._renderOpeningEntityAvailable(e),openingWallIndex:()=>this._openingWallIndexFor(e,this._openCuts()).value}):null}_baseVb(e=this._effectiveProjection(),t=this._renderIsoScene){if("iso"===e){if(!this._spaceDisplayForRender().showBorders){const e=hf({rect:this._frameOf().rect,wallHeight:0});return[e.x,e.y,e.w,e.h]}const e=t?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const i=this._frameOf().rect;return[i.x,i.y,i.w,i.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom()}_clearRoomFocus(e=!1){this._doubleFit.clear(),this._roomFocus=null,e&&(this._roomPointer=null)}_roomFitBounds(e,t){const i=ni(e);if(!i||!e.id)return null;const n=this._spaceWalls,r=this._openCuts(),o=this._wallUnionGeometry(),s=n.length&&this._innerRoomContour(t,e.id,r,o?.roomGeom,o?.multiWallNodes)||i,a=this._spaceDisplayForRender();let l=[];if(a.showBorders&&n.length){const i=Cs(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,uv);i&&(l=ia(i.poly,i.offsets,o?.multiWallNodes)||i.poly)}const c=this._effectiveProjection();return function(e){const t=e.floor,i=e.wall||[],n=e.padding??0;if(!t.length||!t.every(gf)||!i.every(gf)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return vf([...t,...i],n);const r=e.wallHeight??0,o=e.floorDepth??0;if(!Number.isFinite(r)||r<0||!Number.isFinite(o)||o<0)return null;try{const e=[];for(const i of t){const t=[i[0],i[1]];e.push(sf(t,0)),o>0&&e.push(sf(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(sf(i,0)),r>0&&e.push(sf(i,r))}return vf(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?Ha(84,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?Ha(10,this._cellCm):0,padding:a.showBorders?Ha(1.25,this._cellCm):0})}_fitRoom(e,t=!0){if("view"!==this._mode)return!1;this._doubleFit.clear();const i=this._spaceModel(),n=i?.rooms.find(t=>t.id===e);if(!i||!n)return this._clearRoomFocus(),!1;let r=this._roomFitBounds(n,i);if(!r)return this._clearRoomFocus(),!1;this._roomFocus={spaceId:i.id,roomId:e};const o=this._stageEl;if(!o||o.clientWidth<=0||o.clientHeight<=0)return!0;const s=Oi(this._baseVb(),o.clientWidth/o.clientHeight),a=e=>function(e){const t=e.safeFraction??.8,{bounds:i,baseFit:n,stageWidth:r,stageHeight:o,minZoom:s,maxZoom:a}=e;if(!ff(i)||!ff(n)||!Number.isFinite(r)||r<=0||!Number.isFinite(o)||o<=0||!Number.isFinite(s)||s<=0||!Number.isFinite(a)||a1)return null;const l=r/o,c=Math.max(i.w/t,i.h/t*l);if(!Number.isFinite(c)||c<=0)return null;const h=Math.min(a,Math.max(s,n.w/c)),d=n.w/h,u=d/l;return{zoom:h,viewBox:{x:i.x+i.w/2-d/2,y:i.y+i.h/2-u/2,w:d,h:u}}}({bounds:e,baseFit:s,stageWidth:o.clientWidth,stageHeight:o.clientHeight,minZoom:yv.ZOOM_MIN,maxZoom:yv.ZOOM_MAX});let l=a(r);const c=this._isoSceneRuntime,h=this._renderIsoScene?.overlayFitEntries;if(l&&"iso"===this._effectiveProjection()&&c&&h?.length){const e=c.resolveIsoOverlayFitEnvelope({baseBounds:r,entries:h,ownerId:n.id,stageSize:{width:o.clientWidth,height:o.clientHeight},targetView:e=>a(e)?.viewBox??null});e&&(r=e.bounds,l=a(r))}if(!l)return this._clearRoomFocus(),!1;const d=this._cameraState(),u=function(e,t,i,n){const r=[e,t,i,n],o=Math.min(...r.map(e=>e.x)),s=Math.min(...r.map(e=>e.y));return{x:o,y:s,w:Math.max(...r.map(e=>e.x+e.w))-o,h:Math.max(...r.map(e=>e.y+e.h))-s}}(s,d.viewBox,l.viewBox,r);return l.viewBox=this._clampView(l.viewBox,u),t?(this._prepareCameraCommand(),this._startCameraTransition(l,u,"room",220),!0):(this._cancelCameraTransition(!1),Kg(d,l)||(this._zoom=l.zoom,this._view={...l.viewBox},this.requestUpdate()),!0)}_fitAll(e="fit"){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom(e)}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:j`
    +
    `:G}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}getGridOptions(){return{columns:"full"}}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],n=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(n?n[0]+"/"+n[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return Xa(e).map((t,i)=>{const n=e.spaces[i]?.plan_url;return t.bg&&n?{...t,bg:{...t.bg,href:n}}:t})}_spaceModel(){return this._hasFixedFloor?wc(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return wc(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0,this._clearRoomFocus(!0);for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._deviceDrag=null,this._resetDeviceHitState(),this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary?.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit))return;const e=this._serverCfg,t=Qd({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const n of t){const t="h"+n.slice(n.indexOf(":")+1);e.markers.push({id:t,binding:n,hidden:!0}),i.push(n.slice(n.indexOf(":")+1))}const n={...e.settings||{},filter_seeded:!0};delete n.show_all,i.length&&Array.isArray(n.new_device_ids)&&(n.new_device_ids=n.new_device_ids.filter(e=>!i.includes(e))),e.settings=n,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Ee(e)),this._rulesCompiled}get _fillColors(){return gn(this._settings)}get _excluded(){return au(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,this._summary?.willUpdate(),e.has("hass")&&this._configReloadAuthority.observeContext(Gu(this)),e.has("_serverCfg")){const e=this._cfgEpochPreservedConfig===this._serverCfg;this._cfgEpochPreservedConfig=null,e||this._cfgEpoch++,this._renderLife.invalidate()}if(this._syncEmptySpaceState(),this._dangerConfirm&&(this._dangerConfirmMissingSpace()||"warm"===this._syncDangerConfirmLocaleGate())&&this._cancelDangerConfirm(),e.has("hass")&&this.hass){const t=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;this._renderLife.observe(e.get("hass"),this.hass,t?{entityIds:t.entityIds}:null,()=>$g(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._summary?.updated(),this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._syncRadarLive(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>{this._invalidateDeviceHitGeometry(),this._refitView(),requestAnimationFrame(()=>this._summary?.resized())}),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=Qg(this.renderRoot,e,this.panelHost);null!==t&&(t>=0&&t!==this._hdrH&&(this._hdrH=t),t>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:t,stageH:e.clientHeight}))};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary?.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&this._canManageConfiguration&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,n=t.level??1e9;return i!==n?i-n:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptConfigCapabilities(e){kg(this,e)}_syncRadarLive(){const e=this._serverCfg?.settings?.radar,t=(this._serverCfg?.markers||[]).some(e=>Rg(e,this._space));this._radarLive.sync(this._space,1===this._haRadarStage1Api&&"view"===this._mode&&!1!==e?.show_live&&t&&"hidden"!==this.ownerDocument.visibilityState)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await dm(this.hass,lm(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptAuthoritative(e){return qu(this,e)}_rollbackOptimistic(e){const t=this._adoption.rollbackOptimistic(e);return t&&this.requestUpdate(),t}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}_getAuthoritativeConfig(){return e=this,async function(e,t){const i=await e();return t(i),i}(()=>e.hass.callWS({type:"houseplan/config/get"}),t=>kg(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;let i=!1;const n=()=>{i=!0,this._regSignature="",this._maybeRebuildDevices()};try{const[i,r]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this._adoptAuthoritative({cfgResp:i,layResp:r,reason:"structural-response",profile:"reload",beforeAdopt:()=>{this._connectionWasLost=!1,this._serverStorage=!0},afterAdopt:()=>{this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,n()}})).status)return;this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(av)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,i||n(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],n=(n,r,o,s)=>{n()||i.push(async()=>{const i=await e.subscribeEvents(s,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!n()?r(i):i?.()})};if(n(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),n(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),n(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),n(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=jh(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const r=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=r,r.finally(()=>{this._liveSyncAttempt===r&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){return Vu(this,e,t)}_scheduleLoadRetry(e=!1){if(void 0!==this._loadRetryTimer)return;const t=Math.min(8e3,500*2**Math.min(4,Math.max(1,this._loadTries-7)));this._loadRetryTimer=window.setTimeout(()=>{this._loadRetryTimer=void 0,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}async _ensureLiveRuntime(){if(this._liveRt)return;const e=await import("./live-interaction-runtime-AJRZAUON.js");this._liveRt=new e.LiveRuntime(this),this.isConnected&&this.requestUpdate()}_liveVp(e=!1){this._liveRt?this._liveRt.viewport(e):this.requestUpdate()}_syncLiveHover(){this._liveRt?this._liveRt.hover():this.requestUpdate()}_flushHa(){this._liveRt?.take()&&(this._terminalFrame=2,super.requestUpdate())}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._renderLife.invalidate(),this._areaSnapshotCleanupCandidates.clear(),this._planHassMemo=null,this._haRegistryRelease=ed(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return id(this.hass)}get _planHass(){const e=this._haRegistry,t=rd(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=sd(this.hass,e),r=ad(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:n,full:r},n}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+eg)>e?1:0)).join("|"),i=Lh(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const n=this._planHass,r=new Map,o=new Map,s=new Set(["sun.sun"]);for(const e of this._summary?.entityIds()||[])s.add(e);this._vacFit?.source&&s.add(this._vacFit.source);const a=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void s.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?a.add(n):"entity"===i&&s.add(n)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of ui(t))s.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Ki(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,Qi(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!Zd(n,e,Xd(this._markers))))}const h=Od(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(g_(e.id,t),u_(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,n),i=t?jc(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=ah(e.id,e.marker?.vacuum??null,e.space,t),a=ch({routes:s,observed:hh(s,[t],t=>this._vacObservedMapId(e,t,n)),spaceIds:new Set(this._model.map(e=>e.id))});o.set(`vacuum:${e.id}`,{source:t,telemetry:i,routes:s,resolution:a,mapId:i?this._vacMapId(e,i,n):null,runtime:r?{trail:r.trail,lastTs:r.lastTs,moving:r.moving,jump:r.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=m_({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,positions:(u=this._model.length>0,p=this._devices,_=e=>this._livePos(e),u?new Map(p.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:s,deviceIds:a,areaIds:l});var u,p,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _renderVacuumDevices(){return this._renderDeviceSnapshot?.vacuumDevices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return hd(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const{registry:e,bindings:t}=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e));return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&gv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else gv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_referencedContentUrls(){const e=On(this._serverCfg);for(const t of this._decorAssets.values())e.add(t.url);return e}_resign(){this._signer.resign(this.hass,this._referencedContentUrls())}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){this._adoption.noteLayoutRevision(e?.rev)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,n]of e)null===n?delete i[t]:i[t]=n;this._adoption.adoptMergedLayout(i,t,()=>{this._cancelDeviceDrag(),this._devicePositionHistory.clear()}),this._canOptimizeUndo=!!t?.can_optimize_undo,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_persistLocalLayout(){this._layout=bo(ro(this._layout)),localStorage.setItem(av,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=rd(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+wp(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const n=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=tu({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const r=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+r.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const n of r)i.set(n,hd(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=cd(),i=Date.now();for(const[n,r]of e)"active"===r.kind?t[n]={kind:"active",ts:i}:"ha_disabled"===r.kind&&(t[n]={kind:"ha_disabled",reason:r.reason,ts:i});const n=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Kh=n;try{localStorage.setItem(Vh,JSON.stringify(n))}catch{}}(i),this._haBindingCacheKey=o}let s=null;if(t.authoritative&&(s=this._resolveAreaRelocations(t),this._areaRelocationIds=new Set(s.relocateIds),this._areaRelocationIds.size)){this._cancelDeviceDrag();const e=this._areaRelocationIds;this._devicePositionHistory.removeWhere(({before:t,after:i})=>e.has(t.deviceId)||e.has(i.deviceId));const t=this._markerDialog;if(t?.devId&&!t.roomTouched&&this._areaRelocationIds.has(t.devId)){const e=this._devices.find(e=>e.id===t.devId);e&&(this._markerDialog={...t,room:e.marker?.room_id?`${e.space}#@${e.marker.room_id}`:e.space&&e.area?`${e.space}#${e.area}`:""})}}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),s&&this._syncAreaRelocations(s),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const l=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==n.get(e.id));l&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._deviceDrag&&"ha_disabled"===this._devices.find(e=>e.id===this._deviceDrag.id)?.bindingStatus?.kind&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear()),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(mv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=J_(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])Z_(t)&&Number.isFinite(r)&&i.has(t)&&n.set(t,r);const r=new Set,o=new Set;for(const t of e.markers||[])t.removed||(X_(t.id)&&r.add(t.id),Z_(t.binding)&&o.add(t.binding));const s=new Set(Object.keys(e.registryDevices||{})),a=new Set(Object.keys(e.registryEntities||{})),l=new Set(Object.keys(e.liveStates||{})),c=new Map;for(const[e,i]of Object.entries(t)){const t=c.get(i.binding)||[];t.push(e),c.set(i.binding,t)}const h=new Set;let d=!1;for(const[t,i]of c){const[c,u]=nm(t);if(o.has(t)||i.some(e=>r.has(e))||("device"===c?s.has(u):a.has(u)||l.has(u))){n.delete(t);continue}const p="device"===c?s.size>0:a.size>0;if(!e.authoritative||!p)continue;const _=n.get(t);if(void 0!==_){if(_!==e.revision)for(const e of i)h.add(e)}else n.set(t,e.revision),d=!0}return{removeIds:h,candidates:n,needsConfirmationRefresh:d}}({snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,revision:e.revision,registryDevices:e.devices,registryEntities:e.entities,liveStates:this.hass?.states,markers:this._markers,previousCandidates:this._areaSnapshotCleanupCandidates});return this._areaSnapshotCleanupCandidates=t.candidates,t.needsConfirmationRefresh&&this._canEdit&&td(this.hass),rm({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:pv})}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:n,known:r}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),n=e.filter(e=>!i.has(e));return{fresh:n,known:n.length?[...t,...n]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||n.length){const e=[...new Set([...i.new_device_ids||[],...n])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:r,new_device_ids:e}},this._saveConfig()}}_syncAreaRelocations(e){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit&&this._haRegistry.authoritative))return;const t=e.decisions.filter(e=>e.updateSnapshot||e.removeSnapshot);if(!t.length)return;const i=lc({snapshot:J_(this._settings.marker_area_snapshot),decisions:t});i!==this._areaRelocationSyncKey&&(this._areaRelocationSyncKey=i,this._areaRelocationWrite=this._areaRelocationWrite.catch(()=>{}).then(async()=>{if(!this._serverCfg||!this._haRegistry.authoritative)return;const e=this._resolveAreaRelocations();this._areaRelocationIds=new Set(e.relocateIds);const t=new Set,i=new Map;let n=!1;for(const r of e.decisions){if(!r.relocate)continue;const e=gg(this._layout,r.id);try{await this._persistDevicePlacement(r.id,null),t.add(r.id),e&&i.set(r.id,e),this._areaRelocationIds.delete(r.id)}catch(t){n=!0,this._layout=fg(this._layout,r.id,e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}}const r=this._settings,o=function(e,t,i=new Set){const n=J_(e);for(const e of t.decisions)e.removeSnapshot?delete n[e.id]:e.updateSnapshot&&e.binding&&e.area&&(e.relocate&&!i.has(e.id)||(n[e.id]={binding:e.binding,area:e.area}));return n}(r.marker_area_snapshot,e,t),s=[...new Set([...Array.isArray(r.new_device_ids)?r.new_device_ids:[],...t])],a=lc(o)!==lc(J_(r.marker_area_snapshot)),l=lc(s)!==lc(Array.isArray(r.new_device_ids)?r.new_device_ids:[]);if(a||l){const e=r.marker_area_snapshot,n=r.new_device_ids,a={...this._serverCfg,settings:{...r,marker_area_snapshot:o,...l?{new_device_ids:s}:{}}};this._setAreaLifecycleConfig(a);try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.cancel(),await this._writeConfig()}catch(r){const a=this._settings;if(lc(a.marker_area_snapshot)===lc(o)&&lc(a.new_device_ids)===lc(l?s:n)){const t={...a};void 0===e?delete t.marker_area_snapshot:t.marker_area_snapshot=e,void 0===n?delete t.new_device_ids:t.new_device_ids=n;const i={...this._serverCfg,settings:t};this._setAreaLifecycleConfig(i),this._adoption.refreshConfigFingerprint()}for(const e of t)this._areaRelocationIds.add(e);const c=new Set;for(const[e,t]of i)try{await this._persistDevicePlacement(e,t)}catch(t){c.add(e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}this._areaRelocationSyncKey="",this._regSignature="";if("conflict"===(r&&"object"==typeof r&&"code"in r?r.code:void 0)?(this._showToast(this._t("toast.conflict")),await this._reloadConfigOnly(!0)):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(r)})),c.size&&this._serverCfg){const e=this._settings,t=[...new Set([...Array.isArray(e.new_device_ids)?e.new_device_ids:[],...c])],i={...this._serverCfg,settings:{...e,new_device_ids:t}};this._setAreaLifecycleConfig(i);try{await this._writeConfig()}catch(e){this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)}))}}}}n&&(this._areaRelocationSyncKey=""),this.requestUpdate()}))}get _newIds(){const e=this._settings.new_device_ids;return new Set([...Array.isArray(e)?e:[],...this._areaRelocationIds])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const n=Hd(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return Ii(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),n=Math.min(...t),r=Math.min(...i);return{x:n,y:r,w:Math.max(...t)-n,h:Math.max(...i)-r}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const n=t/100*kl(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const r=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!r.length)continue;const o=this._roomBounds(t),s=.1*Math.min(o.w,o.h),a=o.w-2*s,l=o.h-2*s,c=Math.max(1,Math.round(Math.sqrt(r.length*a/Math.max(l,1)))),h=Math.ceil(r.length/c),d=a/c,u=l/Math.max(h,1),p=r.map((e,t)=>({x:o.x+s+d*(t%c+.5),y:o.y+s+u*(Math.floor(t/c)+.5)}));Ei(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=nl(p[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._areaRelocationIds.has(e.id)?void 0:this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*pv,y:i.y*pv}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?nl(wl(t)):{x:500,y:500}}_devicePlacementForCanvas(e,t,i){if(!this._norm)return{x:Math.round(t),y:Math.round(i)};const n=this._gridPitch,r=Math.round(t/n)*n,o=Math.round(i/n)*n;return{s:e.space,x:ol(r/pv),y:ol(o/pv)}}_previewDevicePlacement(e,t){this._layout=fg(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null,this._deviceHits.cancel(e.pointerId);try{e.source?.hasPointerCapture?.(e.pointerId)&&e.source.releasePointerCapture(e.pointerId)}catch{}return this._previewDevicePlacement(e.id,e.before),!0}async _persistDevicePlacement(e,t){if(this._layout=fg(this._layout,e,t),this._serverStorage){let i=null,n=!1;try{let r;if(null===t)i=null,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/delete",device_id:e});else{const t=yo(this._layout[e]);lc(t)!==lc(this._layout[e])&&(this._layout={...this._layout,[e]:t}),i=t,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t})}this._noteLayoutRev(r),this._adoption.refreshLayoutFingerprint(),this._cacheSnapshot()}finally{n&&this._sentPos.get(e)===i&&this._sentPos.delete(e)}return}this._persistLocalLayout()}_devicePositionStateValid(e){const t=this._devices.find(t=>t.id===e.deviceId);return!!t&&t.space===e.spaceId&&"ha_disabled"!==t.bindingStatus?.kind&&!!this._spaceModelById(e.spaceId)}async _runDevicePositionHistory(e){if(this._cancelDeviceDrag()||this._devicePositionBusy)return;const t="undo"===e?this._devicePositionHistory.undo():this._devicePositionHistory.redo();if(!t)return;const i="undo"===e?t.before:t.after;if(!this._devicePositionStateValid(i))return this._devicePositionHistory.clear(),this._showToast(this._t("history.device_stale")),void this.requestUpdate();const n=gg(this._layout,i.deviceId);i.spaceId!==this._space&&(this._commitSpace(i.spaceId),this._restoreZoom()),this._devicePositionBusy=!0,this._previewDevicePlacement(i.deviceId,i.placement);try{await this._persistDevicePlacement(i.deviceId,i.placement),this._showToast(this._t("undo"===e?"history.undone":"history.redone",{name:t.name}))}catch(t){this._previewDevicePlacement(i.deviceId,n),"undo"===e?this._devicePositionHistory.redo():this._devicePositionHistory.undo(),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}finally{this._devicePositionBusy=!1,this.requestUpdate()}}_undoDevicePosition(){this._runDevicePositionHistory("undo")}_redoDevicePosition(){this._runDevicePositionHistory("redo")}_savePos(e,t,i){this._spaceModelById(e.space)&&(this._layout=fg(this._layout,e.id,this._devicePlacementForCanvas(e,t,i)),this._dirtyPos.add(e.id),this._persistLayout())}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const n=i?null:this._renderDeviceSnapshot?.presentations.get(g_(e.id,t));return n||u_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,d_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=Bd(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Ld(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Vn(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._kiosk&&(this._cyclePausedUntil=Math.max(this._cyclePausedUntil,Date.now()+6e4)),this._nativeMoreInfoEntity=e,mv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._roomPointer=null,this._doubleFit.clear(),this._deviceHits.clearPointers()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_invalidateDeviceHitGeometry(){this._deviceHits.invalidate()}_resetDeviceHitState(){this._deviceHits.reset(this.renderRoot)}_deviceHitOwnerAt(e,t){return"view"!==this._mode&&"devices"!==this._mode?null:this._deviceHits.at(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForPointerEvent(e,t){return this._deviceHits.pointer(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForClickEvent(e,t){return this._deviceHits.click(this.renderRoot,this._renderDevices,this._space,e,t)}_showDeviceTip(e,t){this._liveRt?this._liveRt.devicePointerTip(e,t):this._ensureLiveRuntime().then(()=>this._liveRt?.devicePointerTip(e,t))}_showDeviceFocusTip(e,t){const i=e.currentTarget;this._liveRt?this._liveRt.deviceFocusTip(i,t):this._ensureLiveRuntime().then(()=>this._liveRt?.deviceFocusTip(i,t))}_hideDeviceFocusTip(e){this._liveRt?.deviceBlur(e)}_clearPointerHover(){this._liveRt?this._liveRt.pointerLeave():this._clearTransientHover()}_ctxDevice(e,t){"view"===this._mode&&(t=this._deviceForPointerEvent(e,t),e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if(e.stopPropagation(),t=this._deviceForClickEvent(e,t),this._deviceDrag?.moved||this._suppressClick||this._holdFired)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const n=Cu(i.tapAction,i.primary?.split(".")[0]);if("none"===n)return;const r=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===n){const e=this._toggleIntent(i);if(!e)return;if(!zu(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=zu(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=jh(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:n}=t;this._startDevicePressFeedback(i.id),this.hass.callService(n.domain,n.service,n.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},n=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const r=this._toggleConfirmationLines(e);if(!r.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:n}),lines:r,initialIntent:e,deviceId:i.id,exec:()=>{const n=this._devices.find(e=>e.id===i.id),r=n?this._toggleIntent(n):null;r&&!zu(r)&&this._showUnavailableToggleTargets(r)||(r&&Ou(e,r)?t(r):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===n)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===n){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),n=this.hass.states[e];if(!t||!n)return void this._showToast(this._t("toast.run_target_missing"));const o=n.attributes?.friendly_name||e;return void r(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===n&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||zu(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Iu.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!Iu.has(n.reason))continue;const e=String(n.name||n.entityId||n.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const n=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),r=Number.isFinite(n)?Math.max(.95,Math.min(1,n)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(r)},{scale:"0.95",offset:.5},{scale:"1"}],s=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,s);const a=()=>{this._devicePressAnimations.get(e)===s&&this._devicePressAnimations.delete(e)};s.addEventListener("finish",a,{once:!0}),s.addEventListener("cancel",a,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return kp(wp(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex"),confirm:this._t("color_picker.confirm")}}_help(e){return this._editorRuntimeOrThrow()._help(e)}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const n=this._pos(i);t.push({minX:n.x,minY:n.y,maxX:n.x,maxY:n.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,n=Math.cos(i)*e.rlen/2,r=Math.sin(i)*e.rlen/2,o=cl([[e.rx-n,e.ry-r],[e.rx+n,e.ry+r]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){if("image"===e.kind&&!this._decorAssets.has(e.asset_id)&&"decor"!==this._mode)continue;const n=cl("line"===e.kind?[[e.x1*pv,e.y1*i],[e.x2*pv,e.y2*i]]:"text"===e.kind?[[e.x*pv,e.y*i]]:zr({x:e.x*pv,y:e.y*i,w:e.w*pv,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=cl(i);e&&t.push(e)}}return _l(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:pv,h:pv};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const n=vl(this._contentItems(e));let r=n.all||bl(e),o=this._showFar?r:n.core||bl(e);return t&&t.id===e.id&&i&&t.grow&&(o=_v(t.rect,o),r=_v(t.all,r)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:r,outliers:n.outliers},this._frame}_isoSource(){const e=this._isoSceneRuntime;if(!e)return null;const t=this._spaceModel();if(!t)return null;const i=this._spaceWalls,n=this._openCuts(),r=this._openingsR;return e.createIsoStructuralSource({space:t,walls:i,openCuts:n,openings:r,partitionCuts:()=>this._partitionOpeningCuts(t),roomOpenings:()=>this._roomWallOpeningInputs(r,t),cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,coordinateScale:pv,onBuild:()=>{this._isoStructuralBuildCount+=1}})}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return this._isoInvalidKey()}}_isoInvalidKey(){return`${this._space}|invalid|${this._cfgEpoch}`}_clearIsoInvalidFallback(e){const t=`${this._space}|invalid|`;for(const i of this._isoFallback)i.startsWith(t)&&i!==e&&this._isoFallback.delete(i)}_isoScene(e=this._isoSource()){const t=this._isoSceneRuntime;if(!t||!e)return null;let i=this._frameOf().rect;const n=this._spaceDisplayForRender(),r=this._spaceModel();if(r&&n.showNames)for(const e of r.rooms)if(e.name){const t=this._labelPos(e,r.id);i=_v(i,{x:t.x,y:t.y,w:0,h:0})}const o=t.resolveIsoScene({source:e,cache:this._isoGeometryCache,cellCm:this._cellCm,liveFrame:i});if(!r||!n.showBorders)return o;const s=this._config?.icon_size??2.5,a=s>8?2.5:s,l=this._stageEl?.getBoundingClientRect?.()??null,c=l?.height?l.width/l.height:o.frame.w/o.frame.h,h=Oi([o.frame.x,o.frame.y,o.frame.w,o.frame.h],c),d=this._isoOverlayScene(r,this._renderDevices.filter(e=>e.space===r.id&&!e.hidden),h,n,t.resolveIsoDecorationLayers(n),o,a,k_(a),n.showLqi??this._config?.show_signal??!0,!1),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>Oi([e.x,e.y,e.w,e.h],c)});return u?{...o,frame:u.bounds,overlayFitEntries:d.entries}:o}_latchIsoFallback(e,t){if(this._isoFallback.has(e))return;this._isoFallback.add(e);const i=e.includes("|invalid|")?"invalid":e.split("|").pop()||"invalid";console.warn("HOUSEPLAN ISO FALLBACK: #89/#160",bf("structural",i,!0))}_effectiveProjection(){if(this._isoProjectionSnapshot)return this._isoProjectionSnapshot;const e=e=>this._isoProjectionSnapshot=e,t=()=>("iso"===this._renderProjection&&(this._cancelCameraTransition(!1),this._view=null,this._viewModeSnap=null),e("flat"));if(this._renderIsoScene=null,"iso"!==this._desiredProjection||!this._model.length||!this._isoSceneRuntime)return e("flat");if(!this._spaceDisplayForRender().showBorders)return this._isoFallback.has(`${this._space}|no-borders`)?t():e("iso");let i=this._isoInvalidKey();if(this._clearIsoInvalidFallback(i),this._isoFallback.has(i))return t();try{const n=this._isoSource();if(!n)return e("flat");if(i=n.key,this._isoFallback.has(i))return t();const r=this._isoScene(n);return r?this._isoFallback.has(r.key)?t():(this._renderIsoScene=r,e("iso")):e("flat")}catch(e){return this._latchIsoFallback(i,e),t()}}_scenePoint(e){return"iso"===this._renderProjection?af(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=lf([e.x,e.y]),i=lf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_isoOverlayScene(e,t,i,n,r,o,s,a,l,c=!0){const h=this._isoSceneRuntime;return h&&r?.structural&&o?h.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,wallSilhouettes:o.wallSilhouettes,resolveCollisions:c,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:"view"===this._mode?this._kioskScale.icon:1,kioskFontScale:"view"===this._mode?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),positionOf:e=>this._pos(e),presentationOf:(e,t)=>this._devicePresentation(e,t),labelPositionOf:(e,t)=>this._labelPos(e,t),labelScaleOf:e=>this._labelScale(e),openingEntityAvailable:e=>this._renderOpeningEntityAvailable(e),openingWallIndex:()=>this._openingWallIndexFor(e,this._openCuts()).value}):null}_baseVb(e=this._effectiveProjection(),t=this._renderIsoScene){if("iso"===e){if(!this._spaceDisplayForRender().showBorders){const e=df({rect:this._frameOf().rect,wallHeight:0});return[e.x,e.y,e.w,e.h]}const e=t?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const i=this._frameOf().rect;return[i.x,i.y,i.w,i.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom()}_clearRoomFocus(e=!1){this._doubleFit.clear(),this._roomFocus=null,e&&(this._roomPointer=null)}_roomFitBounds(e,t){const i=ni(e);if(!i||!e.id)return null;const n=this._spaceWalls,r=this._openCuts(),o=this._wallUnionGeometry(),s=n.length&&this._innerRoomContour(t,e.id,r,o?.roomGeom,o?.multiWallNodes)||i,a=this._spaceDisplayForRender();let l=[];if(a.showBorders&&n.length){const i=Ts(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,pv);i&&(l=na(i.poly,i.offsets,o?.multiWallNodes)||i.poly)}const c=this._effectiveProjection();return function(e){const t=e.floor,i=e.wall||[],n=e.padding??0;if(!t.length||!t.every(ff)||!i.every(ff)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return yf([...t,...i],n);const r=e.wallHeight??0,o=e.floorDepth??0;if(!Number.isFinite(r)||r<0||!Number.isFinite(o)||o<0)return null;try{const e=[];for(const i of t){const t=[i[0],i[1]];e.push(af(t,0)),o>0&&e.push(af(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(af(i,0)),r>0&&e.push(af(i,r))}return yf(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?La(84,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?La(10,this._cellCm):0,padding:a.showBorders?La(1.25,this._cellCm):0})}_fitRoom(e,t=!0){if("view"!==this._mode)return!1;this._doubleFit.clear();const i=this._spaceModel(),n=i?.rooms.find(t=>t.id===e);if(!i||!n)return this._clearRoomFocus(),!1;let r=this._roomFitBounds(n,i);if(!r)return this._clearRoomFocus(),!1;this._roomFocus={spaceId:i.id,roomId:e};const o=this._stageEl;if(!o||o.clientWidth<=0||o.clientHeight<=0)return!0;const s=Oi(this._baseVb(),o.clientWidth/o.clientHeight),a=e=>function(e){const t=e.safeFraction??.8,{bounds:i,baseFit:n,stageWidth:r,stageHeight:o,minZoom:s,maxZoom:a}=e;if(!vf(i)||!vf(n)||!Number.isFinite(r)||r<=0||!Number.isFinite(o)||o<=0||!Number.isFinite(s)||s<=0||!Number.isFinite(a)||a1)return null;const l=r/o,c=Math.max(i.w/t,i.h/t*l);if(!Number.isFinite(c)||c<=0)return null;const h=Math.min(a,Math.max(s,n.w/c)),d=n.w/h,u=d/l;return{zoom:h,viewBox:{x:i.x+i.w/2-d/2,y:i.y+i.h/2-u/2,w:d,h:u}}}({bounds:e,baseFit:s,stageWidth:o.clientWidth,stageHeight:o.clientHeight,minZoom:bv.ZOOM_MIN,maxZoom:bv.ZOOM_MAX});let l=a(r);const c=this._isoSceneRuntime,h=this._renderIsoScene?.overlayFitEntries;if(l&&"iso"===this._effectiveProjection()&&c&&h?.length){const e=c.resolveIsoOverlayFitEnvelope({baseBounds:r,entries:h,ownerId:n.id,stageSize:{width:o.clientWidth,height:o.clientHeight},targetView:e=>a(e)?.viewBox??null});e&&(r=e.bounds,l=a(r))}if(!l)return this._clearRoomFocus(),!1;const d=this._cameraState(),u=function(e,t,i,n){const r=[e,t,i,n],o=Math.min(...r.map(e=>e.x)),s=Math.min(...r.map(e=>e.y));return{x:o,y:s,w:Math.max(...r.map(e=>e.x+e.w))-o,h:Math.max(...r.map(e=>e.y+e.h))-s}}(s,d.viewBox,l.viewBox,r);return l.viewBox=this._clampView(l.viewBox,u),t?(this._prepareCameraCommand(),this._startCameraTransition(l,u,"room",220),!0):(this._cancelCameraTransition(!1),Yg(d,l)||(this._zoom=l.zoom,this._view={...l.viewBox},this.requestUpdate()),!0)}_fitAll(e="fit"){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom(e)}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:j`
    ${this._t("canvas.far_objects",{n:this._outliers})} @@ -364,7 +364,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 style="left:${a.toFixed(1)}%;top:${l.toFixed(1)}%" @click=${e=>{e.stopPropagation(),this._fitAll("home")}}> - `}_stageAspect(e=this._baseVb()){const t=this._stageEl;return t&&t.clientHeight?t.clientWidth/t.clientHeight:e[2]/e[3]}_viewOr(e){return this._view&&this._view.w?this._view:Oi(e,this._stageAspect(e))}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._viewModeSnap;if(t?.space===this._space&&t.w)return t.w*t.zoom/this._zoom;const i=this._stageEl,n=this.renderRoot.querySelector(".editorchrome");if(!i?.clientWidth||!i.clientHeight)return e.w;const r=i.clientHeight+(n?.offsetHeight||0);return this._viewForModeTarget(this._zoom,void 0,void 0,i.clientWidth,r).w}_screenToVb(e,t){const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i?.clientWidth||1,o=i?.clientHeight||1;return[n.x+e/r*n.w,n.y+t/o*n.h]}_clampView(e,t){const i=(e,t,i,n)=>{const r=1*Math.max(t,n),o=i-r,s=i+n-t+r;return Math.max(Math.min(o,s),Math.min(Math.max(o,s),e))};return{w:e.w,h:e.h,x:i(e.x,e.w,t.x,t.w),y:i(e.y,e.h,t.y,t.h)}}_applyView(e,t,i){this._cancelCameraTransition(!1);const n=this._baseVb(),r=Oi(n,this._stageAspect()),o=Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,e)),s=r.w/o,a=r.h/o,l=this._viewOr(n),c=t??l.x+l.w/2,h=i??l.y+l.h/2,d=this._clampView({x:c-s/2,y:h-a/2,w:s,h:a},r);return!(this._view&&Math.abs(this._zoom-o)<1e-9&&Math.abs(this._view.x-d.x)<1e-6&&Math.abs(this._view.y-d.y)<1e-6&&Math.abs(this._view.w-d.w)<1e-6&&Math.abs(this._view.h-d.h)<1e-6)&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=o,this._view=d,this._liveVp(),!0)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const e=()=>{if(!this._booting)return;const t=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=t);const n=t-this._bootStart;var r,o,s;n>=1200||n>=700&&i>0&&t-this._bootLastChange>=250&&(r=Al,o=this._serverCfg,s=Nl,"pending"!==r.state()||!Cl(o,s))?this._bootSettled():this._bootTimer=window.setTimeout(e,100)};this._bootTimer=window.setTimeout(e,100)}_bootSettled(){this._booting&&!this._bootSettling&&(this._bootSettling=!0,this._refitView(),this._bootSettleRaf=requestAnimationFrame(()=>{this._bootSettleRaf=0,this._finishBootSettled()}))}_finishBootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1,this._bootSettling=!1;const e=this._stageEl?.clientHeight??0;!this._config?.kiosk&&e>0&&this._warmPatch({hdrH:this._hdrH,stageH:e,vp:this._warmViewportState()},!0),this._bootFading=!0,this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220),this._bootSoft=!0,clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},iv)}_bootSoftCancel(){if(!this._bootSoft)return;clearTimeout(this._bootSoftTimer),this._bootSoft=!1;const e=function(e,t,i,n){if(!t)return null;const r=Jg(e,t,i);return i||n||null===r||(t.style.height=`calc(100dvh - ${r}px)`),t.classList.remove("hpsettle"),t.getBoundingClientRect(),t.clientWidth<=0||t.clientHeight<=0?null:{headerHeight:r,size:[t.clientWidth,t.clientHeight]}}(this.renderRoot,this._stageEl,this.panelHost,this._kiosk);if(!e)return;null!==e.headerHeight&&(this._hdrH=e.headerHeight),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null,this._lastValidStageSize=e.size;const t=this._view;t&&this._applyView(this._zoom,t.x+t.w/2,t.y+t.h/2)}_beginResumeSettle(){this._booting||this._resumeSettling||(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0),this._viewportInvalidAt=0,this._beginContinuityCandidate("warm-resume",!1),this._loading?this.requestUpdate():this._loadFromServer())}_refitView(){if(this._modeTransitionBusy||this._warmModeRequest)return;const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return this._cancelCameraTransition(!1),void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight];if(this._bootSoft&&this._warmVp)return this._lastValidStageSize=t,void(this._pendingRefitSize=null);const i=this._lastValidStageSize,n=!!i&&Math.abs(i[0]-t[0])<=.5&&Math.abs(i[1]-t[1])<=.5,r=this._viewportInvalidAt?Date.now()-this._viewportInvalidAt:0;if(this._viewportInvalidAt=0,n)this._pendingRefitSize=null;else{if(this._cancelCameraTransition(!1),!i)return this._lastValidStageSize=t,void(this._roomFocus?.spaceId===this._space?this._fitRoom(this._roomFocus.roomId,!1):this._view||this._applyView(this._zoom));this._pendingRefitSize=t,this._refitRaf||(this._refitRaf=requestAnimationFrame(()=>{this._refitRaf=0;const e=this._pendingRefitSize;this._pendingRefitSize=null;const t=this._stageEl;if(!e||!t||t.clientWidth<=0||t.clientHeight<=0)return;if(Math.abs(t.clientWidth-e[0])>.5||Math.abs(t.clientHeight-e[1])>.5)return void this._refitView();const i=this._lastValidStageSize;if(i&&Math.abs(i[0]-e[0])<=.5&&Math.abs(i[1]-e[1])<=.5)return;this._lastValidStageSize=e;const n=this._view;r>=tc?this._beginContinuityCandidate("stage-size-restored",!0,"stage-size"):this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._roomFocus?.spaceId!==this._space?this._applyView(this._zoom,n?n.x+n.w/2:void 0,n?n.y+n.h/2:void 0):this._fitRoom(this._roomFocus.roomId,!1)}))}}_cameraTargetAt(e,t,i,n=!1){const r=this._stageEl;if(!r||r.clientWidth<=0||r.clientHeight<=0)return null;const o=Oi(this._baseVb(),this._stageAspect()),s=Math.min(yv.ZOOM_MAX,Math.max(yv.ZOOM_MIN,i)),a=function(e,t,i,n,r,o,s){if(!Gg(e)||!Gg({zoom:t,viewBox:i})||!Ug(n)||n<=0||!Ug(r)||r<=0||!Ug(o)||!Ug(s))return null;const a=o/n,l=s/r,c=e.viewBox.x+a*e.viewBox.w,h=e.viewBox.y+l*e.viewBox.h,d=i.w/t,u=i.h/t;return{zoom:t,viewBox:{x:c-a*d,y:h-l*u,w:d,h:u}}}(n&&this._cameraTransition.target||this._cameraState(),s,o,r.clientWidth,r.clientHeight,e,t);return a?(a.viewBox=this._clampView(a.viewBox,o),{target:a,fit:o}):null}_zoomAt(e,t,i){this._clearRoomFocus(),this._cancelCameraTransition(!1);const n=this._cameraTargetAt(e,t,i);n&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=n.target.zoom,this._view={...n.target.viewBox},this._liveVp())}_onWheel(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;e.preventDefault();const i=t.getBoundingClientRect(),n=e.deltaY<0?1.15:1/1.15,r=this._cameraTransition.target?.zoom??this._zoom,o=this._cameraTargetAt(e.clientX-i.left,e.clientY-i.top,r*n,!0);o&&this._startCameraTransition(o.target,o.fit,"wheel",160)}_stepZoom(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;const i=this._cameraTransition.target?.zoom??this._zoom,n=this._cameraTargetAt(t.clientWidth/2,t.clientHeight/2,i*(e>0?1.4:1/1.4),!0);n&&this._startCameraTransition(n.target,n.fit,"button",180)}_resetZoom(e="fit"){this._clearRoomFocus(),this._prepareCameraCommand();const t=Oi(this._baseVb(),this._stageAspect());this._startCameraTransition({zoom:1,viewBox:{...t}},t,e,220)}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem(lv,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){this._clearRoomFocus(!0),this._cancelCameraTransition(!1);const e=this._zoomBySpace[this._space]||1;this._zoom=e;const t=this._stageEl;if(t&&t.clientHeight){const t=this._baseVb();return this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const t=this._baseVb();this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),this.requestUpdate()})}_stagePointerDown(e){this._bootSoftCancel();const t=e.isPrimary&&0===e.button&&"view"===this._mode?_f(e.composedPath()):null;if(this._roomPointer=t?{pointerId:e.pointerId,spaceId:this._space,roomId:t}:null,this._doubleFit.pointerDown(e,this._space,this._doubleFitEnabled),this._cancelCameraTransition(!1,!0),this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:e.clientX,y:e.clientY,id:e.pointerId},e.target.closest?.(".dev, .roomlabel, .oplock")||(clearTimeout(this._kioskHoldTimer),this._kioskHoldTimer=window.setTimeout(()=>{this._roomPointer=null,this._doubleFit.clear(),this._kioskDialog=!0,this._swipeStart=null},3e3))):(this._swipeStart=null,clearTimeout(this._kioskHoldTimer))),this._drag||this._deviceDrag)return;if(this._markup&&e.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&e.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(e))return;this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY});const i=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:e.clientX,sy:e.clientY,vx:i.x,vy:i.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y);this._pinchStart={dist:t,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return!this._hasFixedFloor&&this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(e){if(this._physicalRotate?.pid!==e.pointerId)if(this._physicalDrag?.pid!==e.pointerId)if(this._dtDrag?.pid!==e.pointerId)if(this._bdDrag?.pid!==e.pointerId){if(this._decorDraft?.pid===e.pointerId){const t=this._decorDraft;let i=this._decorSnap(this._svgPoint(e),e.pointerType);if(e.shiftKey&&("rect"===t.kind||"ellipse"===t.kind)){const e=i[0]-t.a[0],n=i[1]-t.a[1],r=Math.max(Math.abs(e),Math.abs(n));i=this._snap([t.a[0]+(e<0?-r:r),t.a[1]+(n<0?-r:r)])}return void(this._decorDraft={...t,b:i})}if(this._decorMove?.pid!==e.pointerId){if("decor"!==this._mode||"furniture"!==this._decorTool&&"image"!==this._decorTool||!this._editorRuntime||(this._notePointer(e),!this._editorRuntime._furnPointerMove(e,this._pointerModality.hoverEnabled)))if(this._pointers.has(e.pointerId)){if(this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(e),this._pinchStart&&this._pointers.size>=2){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),n=(e[0].x+e[1].x)/2-i.left,r=(e[0].y+e[1].y)/2-i.top;this._zoomAt(n,r,this._pinchStart.zoom*t),this._viewportGestureDirty=!0,this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const t=e.clientX-this._panStart.sx,i=e.clientY-this._panStart.sy;Math.abs(t)+Math.abs(i)>4&&(this._roomPointer=null,this._doubleFit.clear(),this._suppressClick=!0,clearTimeout(this._holdTimer),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover()),null===this._panLock&&Math.abs(t)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(t)>1.5*Math.abs(i)?"swipe":"pan","pan"===this._panLock&&this._clearRoomFocus());const n=this._stageEl;if("pan"===this._panLock&&n){const e=this._baseVb(),r=this._viewOr(e),o=Oi(e,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-t/(n.clientWidth||1)*r.w,y:this._panStart.vy-i/(n.clientHeight||1)*r.h,w:r.w,h:r.h},o),this._viewportGestureDirty=!0,this._liveVp()}}}else this._markupMove(e)}else this._decorMoveUpdate(e)}else this._bdMove(e);else this._dtMove(e);else this._physicalMove(e);else this._physicalRotateMove(e)}_stagePointerLeave(e){this._editorRuntime?._cancelPointerMove("markup-hover"),"decor"===this._mode&&this._editorRuntime?._furnPointerLeave(e),this._markup&&("opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover())}_stagePointerUp(e){this._deviceHits.release(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover");const t=(i=this._roomPointer,n=e.pointerId,r=this._space,o=this._roomPointer&&"view"===this._mode?_f(e.composedPath()):null,s=this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired||this._touchSequenceMultitouch,!i||s||i.pointerId!==n||i.spaceId!==r||i.roomId!==o?null:i.roomId);var i,n,r,o,s;this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null);if(this._doubleFit.pointerUp(e,this._space,this._doubleFitEnabled,this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired)&&this._fitAll("double-tap"),this._kiosk){clearTimeout(this._kioskHoldTimer);const i=this._swipeStart;if(this._swipeStart=null,!t&&i&&i.id===e.pointerId){const t=e.clientX-i.x,n=e.clientY-i.y,r="pan"===this._panLock?null:function(e,t,i,n,r,o=60){if(i>1.001||n.length<2)return null;if(Math.abs(e)e.id),this._space);r&&this._slideTo(r,t<0?"left":"right")&&(this._saveNav(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._showKioskDots())}}this._physicalDrag?.pid!==e.pointerId?this._physicalRotate?.pid!==e.pointerId?this._dtDrag?.pid!==e.pointerId?this._bdDrag?.pid!==e.pointerId?this._decorDraft?.pid!==e.pointerId?this._decorMove?.pid!==e.pointerId?this._editorRuntime?._furnPointerUp(e)||(this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._suppressClick&&setTimeout(()=>this._suppressClick=!1,0)),this._viewportGestureDirty&&0===this._pointers.size&&!t&&(this._viewportGestureDirty=!1,this.requestUpdate()),t&&this._fitRoom(t)):this._editorRuntimeOrThrow()._dmUp():this._decorCommitDraft():this._bdUp():this._dtUp():this._physicalRotateUp(e):this._physicalUp(e)}_clickRoom(e){!this._suppressClick&&e.area&&mv("/config/areas/area/"+e.area)}_roomLabelKey(e,t){"view"!==this._mode||"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),e.stopPropagation(),this._fitRoom(t))}_pointerDown(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if("view"===this._mode&&"touch"===e.pointerType&&this._touchSequenceMultitouch)return;if(t=this._deviceHits.begin(this.renderRoot,this._renderDevices,this._space,e,t),"view"===this._mode){this._holdFired=!1,clearTimeout(this._holdTimer);const i=e.pointerId,n=e.currentTarget;return void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._interruptViewGesture(i,n),this._infoCard=t},600))}if("ha_disabled"===t.bindingStatus?.kind||this._devicePositionBusy)return;if(this._deviceDrag)return void(this._deviceDrag.pointerId!==e.pointerId&&this._cancelDeviceDrag());e.preventDefault();const i=this._pos(t);this._deviceDrag={id:t.id,spaceId:t.space,displayName:t.name,pointerId:e.pointerId,source:e.currentTarget,sx:e.clientX,sy:e.clientY,ox:i.x,oy:i.y,moved:!1,before:mg(this._layout,t.id),start:this._devicePlacementForCanvas(t,i.x,i.y)},fv(e),this._tip=null,this._syncLiveHover()}_pointerMove(e,t){if("view"!==this._mode&&"devices"!==this._mode)return null;if(t=this._deviceForPointerEvent(e,t),"devices"!==this._mode)return t;const i=this._deviceDrag;return i&&i.id===t.id&&i.pointerId===e.pointerId?(this._editorRuntimeOrThrow()._queuePointerMove("device",()=>this._pointerMoveNow(e,t)),t):t}_pointerMoveNow(e,t){if("devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;const n=this.renderRoot.querySelector(".stage");if(!n)return;const r=this._baseVb(),o=n.getBoundingClientRect(),s=this._viewOr(r),a=(e.clientX-i.sx)/o.width*s.w,l=(e.clientY-i.sy)/o.height*s.h;Math.abs(e.clientX-i.sx)+Math.abs(e.clientY-i.sy)>3&&(i.moved=!0,clearTimeout(this._holdTimer));const c=nl(i.ox+a),h=nl(i.oy+l);this._previewDevicePlacement(t.id,this._devicePlacementForCanvas(t,c,h))}_pointerUp(e,t){if(t=this._deviceForPointerEvent(e,t),this._deviceHits.release(e.pointerId),clearTimeout(this._holdTimer),"devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;this._editorRuntimeOrThrow()._flushPointerMove("device"),this._deviceDrag=null;const n=mg(this._layout,t.id);var r,o;i.moved&&null!==n&&(r=n,o=i.start,null===r||null===o?r!==o:r.x!==o.x||r.y!==o.y||r.s!==o.s)?(this._selId=t.id,this._suppressClick=!0,window.setTimeout(()=>{this._suppressClick=!1},0),this._devicePositionBusy=!0,this.requestUpdate(),this._persistDevicePlacement(t.id,n).then(()=>{const e=this._t("history.device_move",{name:i.displayName});this._devicePositionHistory.push({name:e,before:{deviceId:i.id,spaceId:i.spaceId,placement:i.before},after:{deviceId:i.id,spaceId:i.spaceId,placement:n}})}).catch(e=>{this._previewDevicePlacement(t.id,i.before),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))}).finally(()=>{this._devicePositionBusy=!1,this.requestUpdate()})):this._previewDevicePlacement(t.id,i.before)}_pointerCancel(e,t){t=this._deviceForPointerEvent(e,t),this._deviceHits.cancel(e.pointerId),this._deviceDrag?.id===t.id&&this._deviceDrag.pointerId===e.pointerId&&this._cancelDeviceDrag()}_showToast(e){for(const e of this.renderRoot.querySelectorAll("hp-dialog"))e.closeTransientOverlays("toast");this._toast=e,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}_syncPointerHoverTargets(){const e=this._pointerModality.hoverEnabled;for(const t of this.renderRoot.querySelectorAll(dv))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(dv)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(dv))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),this._liveRt?.clearDeviceFocus(),this._deviceHits.hover(this.renderRoot,null),this._tip&&(this._tip=null),this._hoverRoom&&(this._hoverRoom=null),this._syncLiveHover()}_notePointer(e){const t=this._pointerModality.modality,i=this._pointerModality.note(e);"touch"!==i&&"pen"!==i||t===i&&!this._tip&&!this._hoverRoom||this._clearTransientHover()}_guardTouchGesture(e){if(this._editorSecondary?.handleOutsideDismiss(e))return;if(this._touchClickGuard.handleActivation(e,this._suppressClick))return;const t=e;if(this._notePointer(t),"pointercancel"===e.type||"lostpointercapture"===e.type?this._doubleFit.clear():"pointerdown"===e.type&&this._doubleFit.clearOutside(t),"pointerdown"===e.type&&this._touchClickGuard.pointerDown(t.pointerId,t.pointerType),"touch"!==t.pointerType)return;if("pointerdown"===e.type){if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._deviceHits.clearPointers(),this._clearRoomFocus(!0),this._clearTransientHover(),clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),this._swipeStart=null;const e=[...this._touchContacts.values()];if("view"===this._mode&&!this._vacFit&&e.every(e=>e.inStage)){this._pointers=new Map([...this._touchContacts].map(([e,t])=>[e,{x:t.x,y:t.y}]));const[t,i]=e;this._pinchStart={dist:Math.hypot(t.x-i.x,t.y-i.y),zoom:this._zoom},this._panStart=null,this._panLock=null}else this._vacFit&&(this._pointers.clear(),this._pinchStart=null,this._panStart=null,this._panLock=null)}return}if("pointermove"===e.type){const e=this._touchContacts.get(t.pointerId);if(!e)return;const i={...e,x:t.clientX,y:t.clientY};if(this._touchContacts.set(t.pointerId,i),this._touchSequenceMultitouch&&"view"===this._mode&&!this._vacFit&&this._pinchStart&&[...this._touchContacts.values()].every(e=>e.inStage)){this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=[...this._touchContacts.values()];if(e.length>=2&&this._stageEl){const[t,i]=e,n=Math.hypot(t.x-i.x,t.y-i.y)/(this._pinchStart.dist||1),r=this._stageEl.getBoundingClientRect();this._zoomAt((t.x+i.x)/2-r.left,(t.y+i.y)/2-r.top,this._pinchStart.zoom*n),this._saveZoom()}}return}if("pointerup"!==e.type&&"pointercancel"!==e.type&&"lostpointercapture"!==e.type)return;const i=this._touchClickGuard.pointerTerminal(t.pointerId,t.pointerType);if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),i){if(this._pointers.delete(t.pointerId),!this._vacFit&&this._pointers.size>=2){const[e,t]=[...this._pointers.values()];this._pinchStart={dist:Math.hypot(e.x-t.x,e.y-t.y),zoom:this._zoom}}else this._pinchStart=null;0===this._pointers.size&&(this._panStart=null,this._panLock=null)}}_showTip(e,t,i,n,r,o,s=!1){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||this._deviceDrag||s&&this._liveRt?.deviceFocusActive()||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:n,temp:r,hum:o,room:s,source:"pointer"},this._syncLiveHover()))}_roomTipEnabledForPointer(e){return"view"===this._mode&&(this._notePointer(e),!!_n(this._settings)||(this._tip?.room&&(this._tip=null,this._syncLiveHover()),!1))}get _gridPitch(){return Qa}get _cellCm(){const e=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(e)&&e>0?e:5}_fmtLen(e,t){const i=function(e,t,i,n){return Math.hypot(t[0]-e[0],t[1]-e[1])/i*n}(e,t,this._gridPitch,this._cellCm);return ti(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const e=this._resize?.preview;return e&&e.space===this._space?e.sp:this._serverCfg?.spaces.find(e=>e.id===this._space)}get _renderCfg(){const e=this._resize?.preview;return e&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(t=>t.id===e.space?e.sp:t)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,uv}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return oi(e?.rooms||[]).map(e=>[e[0]*uv,e[1]*t,e[2]*uv,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(cv)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(cv,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,this._configReloadAuthority.invalidateLifecycle(),this._summary?.leaveRoute(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._drawWallField=null,this._showHidden=!1,this._tapConfirm=null,this._vacCalConfirm=null,this._decorEraseConfirm=null,this._openingInfo=null,this._closeInfoCard(),this._rulesDialog=null,this._alignDialog=null,this._preflightClipboardFallback=null,this._backupImportDialog=null,this._backupExportDialog=null,this._pdfDialog=!1,this._supportDialog?.preview?.token&&this._editorRuntime?._discardSupportPreview(this._supportDialog.preview.token),this._supportDialog=null,this._settingsDialog=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._openingDialog=null,this._physicalDialog=null,this._wallDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._mergeDialog=null,this._roomDialog=!1,this._spaceDialog=null,this._importDialog=null;const e=this._warmSlot;e?.owner===this._warmGen&&(e.vp=this._warmViewportState(),e.dlg=null,e.frameFingerprint="",clearTimeout(e.evict),e.evict=0),this._saveNav()}_setMode(e,t=!0){return e!==this._mode&&(this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._resetDeviceHitState(),this._clearTransientHover(!0)),this._warmModeRequest=0,this._editorRuntime?this._editorRuntime._setMode(e,t):"view"===e?void this._editorModeRequest++:void this._requestMode(e,t)}_primeDrawWallField(){return this._editorRuntimeOrThrow()._primeDrawWallField()}get _drawWallFieldValue(){return null===this._drawWallField?Do(15,this._imperial):this._drawWallField}get _drawWallCm(){const e=(e=>{const t=String(e??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(t))return null;const i=Number(t);return Number.isFinite(i)?i:null})(this._drawWallFieldValue);if(null==e||e<0)return null;const t=this._imperial?2.54*e:e,i="column"===this._tool?ua:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?ua:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){return this._editorRuntimeOrThrow()._showPhysicalRange(e,t)}_mergeSpacePartitions(e,t){return this._editorRuntimeOrThrow()._mergeSpacePartitions(e,t)}_finishWallChain(){return this._editorRuntimeOrThrow()._finishWallChain()}_activateMarkupTool(e){return this._editorRuntimeOrThrow()._activateMarkupTool(e)}_limitReached(e){return this._editorRuntimeOrThrow()._limitReached(e)}_svgPoint(e){return this._editorRuntimeOrThrow()._svgPoint(e)}_snap(e){return this._editorRuntimeOrThrow()._snap(e)}_snapDrawPoint(e,t=!1){return this._editorRuntimeOrThrow()._snapDrawPoint(e,t)}_planSnapOpeningCuts(e,t){return this._editorRuntimeOrThrow()._planSnapOpeningCuts(e,t)}_planSnapGeometrySnapshot(){return this._editorRuntimeOrThrow()._planSnapGeometrySnapshot()}_hiddenWallDiagnosticSnapshot(){return this._editorRuntimeOrThrow()._hiddenWallDiagnosticSnapshot()}_planStructuralGeometrySnapshot(){return this._editorRuntimeOrThrow()._planStructuralGeometrySnapshot()}_planSnapContextKey(e){return this._editorRuntimeOrThrow()._planSnapContextKey(e)}_resolvePlanDrawPoint(e,t){return this._editorRuntimeOrThrow()._resolvePlanDrawPoint(e,t)}get _activePlanSnapCandidate(){if(!this._markup||"draw"!==this._tool)return null;const e=this._planSnapHover;if(!e)return null;const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.candidate:null}get _activePlanSnapConflicts(){if(!this._markup||"draw"!==this._tool)return[];const e=this._planSnapHover;if(!e)return[];const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.conflicts:[]}_clearPlanSnapHover(e=!0){return this._editorRuntime?this._editorRuntimeOrThrow()._clearPlanSnapHover(e):(this._planSnapHover=null,void(e&&(this._cursorPt=null)))}_samePt(e,t){return _i(e,t)}_dropLegacySegments(){return this._editorRuntimeOrThrow()._dropLegacySegments()}_rollbackRejectedPhysicalWrites(e){return this._editorRuntimeOrThrow()._rollbackRejectedPhysicalWrites(e)}async _reloadRejectedPhysicalWrite(){return this._editorRuntimeOrThrow()._reloadRejectedPhysicalWrite()}get _cfgWriting(){return this._writesPending>0}async _sendConfigCandidate(e){const t=bo(e),i=await this.hass.callWS({type:"houseplan/config/set",config:t,expected_rev:this._cfgRev});this._adoption.acceptConfigWrite(t,i)}_writeConfig(){if(this._editorRuntime)return this._editorRuntime._writeConfig();this._writesPending++,this._writeChain=Eu(this._writeChain,async()=>{if(!this._serverCfg)return;const e=bo(this._serverCfg);this._adoption.stageConfigCandidate(e),await this._sendConfigCandidate(e)});return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_geometrySnapshotFromConfig(e,t){return this._editorRuntimeOrThrow()._geometrySnapshotFromConfig(e,t)}_geometrySnapshot(e=this._space){return this._editorRuntimeOrThrow()._geometrySnapshot(e)}_recordGeometry(e,t){return this._editorRuntimeOrThrow()._recordGeometry(e,t)}_restoreGeometryStateInConfig(e,t,i=!1){return this._editorRuntimeOrThrow()._restoreGeometryStateInConfig(e,t,i)}_restoreGeometryStateLocal(e){return this._editorRuntimeOrThrow()._restoreGeometryStateLocal(e)}_wallModelBlockerLabel(e){return this._editorRuntimeOrThrow()._wallModelBlockerLabel(e)}_hasLegacyZeroWallFields(e=this._serverCfg){return this._editorRuntimeOrThrow()._hasLegacyZeroWallFields(e)}_showWallModelMigrationBlocked(e){return this._editorRuntimeOrThrow()._showWallModelMigrationBlocked(e)}_limitSegmentsOf(e){return this._editorRuntimeOrThrow()._limitSegmentsOf(e)}_junctionLimitViolations(e,t,i,n){return this._editorRuntimeOrThrow()._junctionLimitViolations(e,t,i,n)}_junctionLimitLabel(e){return this._editorRuntimeOrThrow()._junctionLimitLabel(e)}_junctionLimitsIntroduced(e,t,i){return this._editorRuntimeOrThrow()._junctionLimitsIntroduced(e,t,i)}_commitPhysicalGeometry(e,t,i=[]){return this._editorRuntimeOrThrow()._commitPhysicalGeometry(e,t,i)}_clearGeometryGesture(){return this._editorRuntime?this._editorRuntimeOrThrow()._clearGeometryGesture():(this._path=[],this._planSnapHover=null,this._cursorPt=null,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingPreset=null,this._openingRebindId=null,this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._roomDeleteDialog=null,this._wallDialog=null,this._physicalDialog=null,this._physicalSel=null,this._physicalDrag=null,this._physicalRotate=null,this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._openingDialog=null,this._resize?.reset(),this._decorDraft=null,this._decorMove=null,this._dtDrag=null,void(this._bdDrag=null))}_stagePointerCancel(e){if(this._deviceHits.cancel(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover"),this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null),this._doubleFit.clear(),this._editorRuntime)return this._editorRuntime._stagePointerCancel(e);this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._swipeStart=null),this._viewportGestureDirty&&0===this._pointers.size&&(this._viewportGestureDirty=!1,this.requestUpdate())}_applyGeometryState(e,t=!1){return this._editorRuntimeOrThrow()._applyGeometryState(e,t)}_roomAt(e){return this._editorRuntimeOrThrow()._roomAt(e)}_overlapRoom(e){return this._editorRuntimeOrThrow()._overlapRoom(e)}_pointInRoom(e,t){return t.poly?mi(e,t.poly):null!=t.x&&e[0]>=t.x&&e[0]<=t.x+t.w&&e[1]>=t.y&&e[1]<=t.y+t.h}_contourSelfIntersects(e){return this._editorRuntimeOrThrow()._contourSelfIntersects(e)}_canAppendWallPoint(){return this._editorRuntimeOrThrow()._canAppendWallPoint()}_markupClick(e){if(this._editorRuntime)return this._editorRuntime._markupClick(e)}_activeWallSourceKey(e){return this._editorRuntimeOrThrow()._activeWallSourceKey(e)}_wallGraphSources(e){return this._editorRuntimeOrThrow()._wallGraphSources(e)}_wallFaceGraph(e,t){return this._editorRuntimeOrThrow()._wallFaceGraph(e,t)}_offerWallFaces(e,t=this._path.length-2,i){return this._editorRuntimeOrThrow()._offerWallFaces(e,t,i)}_beginWallFaceBatch(e){return this._editorRuntimeOrThrow()._beginWallFaceBatch(e)}_offerExistingWallFace(e){return this._editorRuntimeOrThrow()._offerExistingWallFace(e)}_columnClick(e){return this._editorRuntimeOrThrow()._columnClick(e)}_openPhysicalDialog(e,t){return this._editorRuntimeOrThrow()._openPhysicalDialog(e,t)}_physicalDown(e,t,i){return this._editorRuntimeOrThrow()._physicalDown(e,t,i)}_clampPhysicalDelta(e,t,i){return this._editorRuntimeOrThrow()._clampPhysicalDelta(e,t,i)}_physicalMove(e){return this._editorRuntimeOrThrow()._physicalMove(e)}_physicalUp(e){return this._editorRuntimeOrThrow()._physicalUp(e)}_registerPhysicalTap(e,t){return this._editorRuntimeOrThrow()._registerPhysicalTap(e,t)}_cancelPhysicalGesture(){return this._editorRuntimeOrThrow()._cancelPhysicalGesture()}_physicalRotateDown(e,t){return this._editorRuntimeOrThrow()._physicalRotateDown(e,t)}_physicalRotateMove(e){return this._editorRuntimeOrThrow()._physicalRotateMove(e)}_physicalRotateUp(e){return this._editorRuntimeOrThrow()._physicalRotateUp(e)}_rszRooms(){return this._editorRuntimeOrThrow()._rszRooms()}_rszOpenings(){return this._editorRuntimeOrThrow()._rszOpenings()}_rszObstacles(){return this._editorRuntimeOrThrow()._rszObstacles()}_rszOptsFor(e,t){return this._editorRuntimeOrThrow()._rszOptsFor(e,t)}_rszResolution(e,t,i){return this._editorRuntimeOrThrow()._rszResolution(e,t,i)}_rszSnapshot(){return this._editorRuntimeOrThrow()._rszSnapshot()}_rszResetController(){return this._editorRuntimeOrThrow()._rszResetController()}_rszProjectPreview(e,t,i,n,r){return this._editorRuntimeOrThrow()._rszProjectPreview(e,t,i,n,r)}_rszAcceptPreview(e,t){return this._editorRuntimeOrThrow()._rszAcceptPreview(e,t)}_rszSpaceCandidateGeometry(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateGeometry(e,t)}_rszSpaceCandidateRenderable(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateRenderable(e,t)}_rszCandidateRenderable(e){return this._editorRuntimeOrThrow()._rszCandidateRenderable(e)}_rszEdgeDown(e,t,i){return this._editorRuntimeOrThrow()._rszEdgeDown(e,t,i)}_rszReasonText(e){return this._editorRuntimeOrThrow()._rszReasonText(e)}_rszDisabledActivate(e,t){return this._editorRuntimeOrThrow()._rszDisabledActivate(e,t)}_rszDisabledKey(e,t){return this._editorRuntimeOrThrow()._rszDisabledKey(e,t)}_rszMove(e){return this._editorRuntimeOrThrow()._rszMove(e)}_rszUp(e){return this._editorRuntimeOrThrow()._rszUp(e)}_rszCancelDrag(e){return this._editorRuntimeOrThrow()._rszCancelDrag(e)}_rszPointerCancel(e){return this._editorRuntimeOrThrow()._rszPointerCancel(e)}_rszEdgeLabels(e,t,i=this._resize?.rooms){return this._editorRuntimeOrThrow()._rszEdgeLabels(e,t,i)}_rszInnerSpanCms(e,t,i){return this._editorRuntimeOrThrow()._rszInnerSpanCms(e,t,i)}_renderResizeMeasurements(){return this._editorRuntimeOrThrow()._renderResizeMeasurements()}_renderResizeLayer(e,t){return this._editorRuntimeOrThrow()._renderResizeLayer(e,t)}get _openingsR(){const e=this._curSpaceCfg,t=this._spaceH,i=this._spaceModel();return i?(e?.openings||[]).flatMap(e=>{const n={...e,rx:e.x*uv,ry:e.y*t,rlen:e.length*uv};if(!e.host||"wall"===e.host.kind)return[n];const r=Xu(e,i.partitions,uv,this._cellCm,this._gridPitch);if(!r.resolved)return"plan"===this._mode?[{...n,orphanReason:r.reason||"invalid-host"}]:[];let[o,s]=r.resolved.center;const a=this._physicalDrag;return a?.moved&&"partition"===a.kind&&a.id===e.host.id&&(o+=a.delta[0],s+=a.delta[1]),[{...e,rx:o,ry:s,rlen:r.resolved.length,angle:r.resolved.angle,partitionHost:r.resolved}]}):[]}_partitionOpeningCuts(e=this._spaceModel(),t=()=>!0){if(!e)return[];return W_(j_(this._curSpaceCfg?.id===e.id?this._curSpaceCfg:null,e,this._cellCm,this._gridPitch,uv),t)}_roomWallOpeningInputs(e=this._openingsR,t=this._spaceModel()){if(!t)return[];const i=this._openCuts();return U_(e,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,uv)}_openingFace(e,t,i){return e.partitionHost?ep(e.partitionHost,i):la(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen,flip_v:i})}_cmToUnits(e){return e/this._cellCm*this._gridPitch}get _decorList(){const e=this._curSpaceCfg;return Array.isArray(e?.decor)?e.decor:[]}get _decorH(){return uv}_decorResolvedStyle(e){return function(e,t,i,n=xr){const r="rect"===e?.kind||"ellipse"===e?.kind,o=e,s=Kt(o?.color,n.color);return{color:s,opacity:Sr(o?.opacity,n.opacity),widthCm:Dr(e,t,i,n.widthCm),fill:!!r&&!0===o?.fill,fillColor:Kt(o?.fill_color,o?.fill?s:n.fillColor),fillOpacity:r&&o?.fill?Sr(o?.fill_opacity,.25):n.fillOpacity}}(e,this._cellCm,this._gridPitch,xr)}_decorWidthUnits(e){return((e,t,i,n=xr.widthCm)=>{const r=Number(e?.width_cm);if(Number.isFinite(r)&&r>0)return Cr(r,t,i);const o=Number(e?.width);return Number.isFinite(o)&&o>0?o:Cr(n,t,i)})(e,this._cellCm,this._gridPitch,xr.widthCm)}_decorTextSizeCm(e){if("text"===e?.kind){const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?t:Tr(20*tn(e),this._cellCm,this._gridPitch)}return Tr(20,this._cellCm,this._gridPitch)}_decorTextUnits(e){if("text"!==e.kind)return 20;const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?Cr(t,this._cellCm,this._gridPitch):20*tn(e)}_decorSmallField(e){return Math.round(100*(this._imperial?e/2.54:e))/100}_decorSmallCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(100,t)):.1}_decorTextCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(2e3,t)):.1}_decorLargeField(e){return Math.round(100*(this._imperial?e/30.48:e/100))/100}_decorLargeCm(e){const t=this._imperial?30.48*e:100*e;return Number.isFinite(t)?Math.max(.1,Math.min(Xa*this._cellCm,t)):.1}_angleField(e){const t=Number(e);return Number.isFinite(t)?String(Number(t.toFixed(3))):"0"}_decorBoxOf(e){return"rect"!==e.kind&&"ellipse"!==e.kind&&"furniture"!==e.kind&&"image"!==e.kind?null:{x:e.x*uv,y:e.y*this._decorH,w:e.w*uv,h:e.h*this._decorH,angle:$r(e.angle)||void 0}}_decorSnapGeometry(e){return this._editorRuntimeOrThrow()._decorSnapGeometry(e)}_decorSnap(e,t="mouse",i){return this._editorRuntimeOrThrow()._decorSnap(e,t,i)}_replaceDecor(e,t){return this._editorRuntimeOrThrow()._replaceDecor(e,t)}_cancelDecorGesture(){return this._editorRuntimeOrThrow()._cancelDecorGesture()}_decorPointerDown(e){return this._editorRuntimeOrThrow()._decorPointerDown(e)}_decorCommitDraft(){return this._editorRuntimeOrThrow()._decorCommitDraft()}_decorShapeDown(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDown(e,t)}_decorMoveUpdate(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-move",()=>this._editorRuntimeOrThrow()._decorMoveUpdate(e))}_decorNudge(e,t){if("decor"!==this._mode||"select"!==this._decorTool||!this._decorSel||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag)return!1;const i=this._decorList.find(e=>e.id===this._decorSel),n=this._curSpaceCfg;if(!i||!n)return!1;const r=function(e,t,i,n,r,o){if(!([t,i,n,r,o].every(Number.isFinite)&&r>0))return null;let s;if(s="line"===e.kind?[[e.x1,e.y1],[e.x2,e.y2]]:"text"===e.kind?[[e.x,e.y]]:Fr(e),!s.length||s.some(e=>!e.slice(0,2).every(Number.isFinite)))return null;const a=s.map(e=>e[0]),l=s.map(e=>e[1]),c=Math.min(...a),h=Math.max(...a),d=Math.min(...l),u=Math.max(...l),p=t/n,_=i/r,m=p>0?Math.min(p,Math.max(0,o-h)):Math.max(p,Math.min(0,-o-c)),g=_>0?Math.min(_,Math.max(0,o-u)):Math.max(_,Math.min(0,-o-d));return m||g?"line"===e.kind?{...e,x1:e.x1+m,y1:e.y1+g,x2:e.x2+m,y2:e.y2+g}:{...e,x:e.x+m,y:e.y+g}:null}(i,e,t,uv,this._decorH,Xa);if(!r)return!1;const o=this._geometrySnapshot();return n.decor=this._decorList.map(e=>e.id===i.id?r:e),this._recordGeometry(this._t("history.decor_move"),o),this._saveConfig(),this.requestUpdate(),!0}_decorShapeDbl(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDbl(e,t)}_openDecorProperties(e){return this._editorRuntimeOrThrow()._openDecorProperties(e)}_decorOpenText(e){return this._editorRuntimeOrThrow()._decorOpenText(e)}_decorRememberTextSelection(e){return this._editorRuntimeOrThrow()._decorRememberTextSelection(e)}_decorInsertLiveVariable(e){return this._editorRuntimeOrThrow()._decorInsertLiveVariable(e)}_decorSaveText(){return this._editorRuntimeOrThrow()._decorSaveText()}_decorSaveShape(){return this._editorRuntimeOrThrow()._decorSaveShape()}get _dtSel(){return"decor"===this._mode&&"select"===this._decorTool&&this._decorSel&&this._decorList.find(e=>e.id===this._decorSel)||null}_dtPivot(e){return this._editorRuntimeOrThrow()._dtPivot(e)}_dtApply(e,t){return this._editorRuntimeOrThrow()._dtApply(e,t)}_dtStart(e,t,i,n){return this._editorRuntimeOrThrow()._dtStart(e,t,i,n)}_dtMove(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-transform",()=>this._editorRuntimeOrThrow()._dtMove(e))}_dtUp(){return this._editorRuntimeOrThrow()._flushPointerMove("decor-transform"),this._editorRuntimeOrThrow()._dtUp()}_dtMeasure(){return this._editorRuntimeOrThrow()._dtMeasure()}_deleteDecor(e){return this._editorRuntimeOrThrow()._deleteDecor(e)}_decorDeleteSel(){return this._editorRuntimeOrThrow()._decorDeleteSel()}_confirmDecorErase(){return this._editorRuntimeOrThrow()._confirmDecorErase()}get _bdBase(){const e=this._curSpaceCfg;return e?.plan_url?{...Wa(e.plan_aspect,uv)}:null}get _bdRect(){const e=this._curSpaceCfg;return e?.plan_url?Va(e,uv):null}get _bdParams(){const e=this._curSpaceCfg,t=Number(e?.plan_x),i=Number(e?.plan_y),n=Number(e?.plan_scale),r=Number(e?.plan_scale_x),o=Number(e?.plan_scale_y),s=Number.isFinite(n)&&n>0?n:1;return{dx:Number.isFinite(t)?t:0,dy:Number.isFinite(i)?i:0,sx:Number.isFinite(r)&&r>0?r:s,sy:Number.isFinite(o)&&o>0?o:s,angle:$r(e?.plan_angle)}}_openBackdropDialog(e){if(this._editorRuntime)return this._editorRuntime._openBackdropDialog(e)}_saveBackdropDialog(){return this._editorRuntimeOrThrow()._saveBackdropDialog()}get _bdActive(){return"decor"===this._mode&&!!this._bdRect&&"backdrop"===this._decorTool}get _bdMovable(){return"decor"===this._mode&&"backdrop"===this._decorTool&&!!this._bdRect}_bdApply(e,t,i,n,r){return this._editorRuntimeOrThrow()._bdApply(e,t,i,n,r)}_bdStart(e,t,i=!1){return this._editorRuntimeOrThrow()._bdStart(e,t,i)}_bdMove(e){return this._editorRuntimeOrThrow()._bdMove(e)}get _bdMoved(){if("decor"!==this._mode||!this._bdRect)return!1;const e=this._bdParams;return 0!==e.dx||0!==e.dy||1!==e.sx||1!==e.sy||0!==e.angle}_bdReset(){return this._editorRuntimeOrThrow()._bdReset()}_bdUp(){return this._editorRuntimeOrThrow()._bdUp()}get _bdLive(){if(!this._bdDrag)return null;const e=this._bdRect;return e?{x:e.x+e.w/2,y:e.y+e.h/2,text:`${this._fmtLen([0,0],[e.w,0])} × ${this._fmtLen([0,0],[0,e.h])}`}:null}_renderBackdropFrame(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderBackdropFrame(e):G}_renderTextFrame(e){const t=this._dtSel;if(!t)return G;if("text"===t.kind&&this._dtBox?.id!==t.id)return G;const i="text"===t.kind?this._dtBox:this._decorBoxOf(t);if("line"!==t.kind&&!i)return G;const n=.018*Math.max(e.w,e.h),r=n/4;if("line"===t.kind){const e=[t.x1*uv,t.y1*this._decorH],i=[t.x2*uv,t.y2*this._decorH];return W` + `}_stageAspect(e=this._baseVb()){const t=this._stageEl;return t&&t.clientHeight?t.clientWidth/t.clientHeight:e[2]/e[3]}_viewOr(e){return this._view&&this._view.w?this._view:Oi(e,this._stageAspect(e))}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._viewModeSnap;if(t?.space===this._space&&t.w)return t.w*t.zoom/this._zoom;const i=this._stageEl,n=this.renderRoot.querySelector(".editorchrome");if(!i?.clientWidth||!i.clientHeight)return e.w;const r=i.clientHeight+(n?.offsetHeight||0);return this._viewForModeTarget(this._zoom,void 0,void 0,i.clientWidth,r).w}_screenToVb(e,t){const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i?.clientWidth||1,o=i?.clientHeight||1;return[n.x+e/r*n.w,n.y+t/o*n.h]}_clampView(e,t){const i=(e,t,i,n)=>{const r=1*Math.max(t,n),o=i-r,s=i+n-t+r;return Math.max(Math.min(o,s),Math.min(Math.max(o,s),e))};return{w:e.w,h:e.h,x:i(e.x,e.w,t.x,t.w),y:i(e.y,e.h,t.y,t.h)}}_applyView(e,t,i){this._cancelCameraTransition(!1);const n=this._baseVb(),r=Oi(n,this._stageAspect()),o=Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,e)),s=r.w/o,a=r.h/o,l=this._viewOr(n),c=t??l.x+l.w/2,h=i??l.y+l.h/2,d=this._clampView({x:c-s/2,y:h-a/2,w:s,h:a},r);return!(this._view&&Math.abs(this._zoom-o)<1e-9&&Math.abs(this._view.x-d.x)<1e-6&&Math.abs(this._view.y-d.y)<1e-6&&Math.abs(this._view.w-d.w)<1e-6&&Math.abs(this._view.h-d.h)<1e-6)&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=o,this._view=d,this._liveVp(),!0)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const e=()=>{if(!this._booting)return;const t=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=t);const n=t-this._bootStart;var r,o,s;n>=1200||n>=700&&i>0&&t-this._bootLastChange>=250&&(r=Pl,o=this._serverCfg,s=Hl,"pending"!==r.state()||!Tl(o,s))?this._bootSettled():this._bootTimer=window.setTimeout(e,100)};this._bootTimer=window.setTimeout(e,100)}_bootSettled(){this._booting&&!this._bootSettling&&(this._bootSettling=!0,this._refitView(),this._bootSettleRaf=requestAnimationFrame(()=>{this._bootSettleRaf=0,this._finishBootSettled()}))}_finishBootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1,this._bootSettling=!1;const e=this._stageEl?.clientHeight??0;!this._config?.kiosk&&e>0&&this._warmPatch({hdrH:this._hdrH,stageH:e,vp:this._warmViewportState()},!0),this._bootFading=!0,this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220),this._bootSoft=!0,clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},nv)}_bootSoftCancel(){if(!this._bootSoft)return;clearTimeout(this._bootSoftTimer),this._bootSoft=!1;const e=function(e,t,i,n){if(!t)return null;const r=Qg(e,t,i);return i||n||null===r||(t.style.height=`calc(100dvh - ${r}px)`),t.classList.remove("hpsettle"),t.getBoundingClientRect(),t.clientWidth<=0||t.clientHeight<=0?null:{headerHeight:r,size:[t.clientWidth,t.clientHeight]}}(this.renderRoot,this._stageEl,this.panelHost,this._kiosk);if(!e)return;null!==e.headerHeight&&(this._hdrH=e.headerHeight),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null,this._lastValidStageSize=e.size;const t=this._view;t&&this._applyView(this._zoom,t.x+t.w/2,t.y+t.h/2)}_beginResumeSettle(){this._booting||this._resumeSettling||(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0),this._viewportInvalidAt=0,this._beginContinuityCandidate("warm-resume",!1),this._loading?this.requestUpdate():this._loadFromServer())}_refitView(){if(this._modeTransitionBusy||this._warmModeRequest)return;const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return this._cancelCameraTransition(!1),void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight];if(this._bootSoft&&this._warmVp)return this._lastValidStageSize=t,void(this._pendingRefitSize=null);const i=this._lastValidStageSize,n=!!i&&Math.abs(i[0]-t[0])<=.5&&Math.abs(i[1]-t[1])<=.5,r=this._viewportInvalidAt?Date.now()-this._viewportInvalidAt:0;if(this._viewportInvalidAt=0,n)this._pendingRefitSize=null;else{if(this._cancelCameraTransition(!1),!i)return this._lastValidStageSize=t,void(this._roomFocus?.spaceId===this._space?this._fitRoom(this._roomFocus.roomId,!1):this._view||this._applyView(this._zoom));this._pendingRefitSize=t,this._refitRaf||(this._refitRaf=requestAnimationFrame(()=>{this._refitRaf=0;const e=this._pendingRefitSize;this._pendingRefitSize=null;const t=this._stageEl;if(!e||!t||t.clientWidth<=0||t.clientHeight<=0)return;if(Math.abs(t.clientWidth-e[0])>.5||Math.abs(t.clientHeight-e[1])>.5)return void this._refitView();const i=this._lastValidStageSize;if(i&&Math.abs(i[0]-e[0])<=.5&&Math.abs(i[1]-e[1])<=.5)return;this._lastValidStageSize=e;const n=this._view;r>=ic?this._beginContinuityCandidate("stage-size-restored",!0,"stage-size"):this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._roomFocus?.spaceId!==this._space?this._applyView(this._zoom,n?n.x+n.w/2:void 0,n?n.y+n.h/2:void 0):this._fitRoom(this._roomFocus.roomId,!1)}))}}_cameraTargetAt(e,t,i,n=!1){const r=this._stageEl;if(!r||r.clientWidth<=0||r.clientHeight<=0)return null;const o=Oi(this._baseVb(),this._stageAspect()),s=Math.min(bv.ZOOM_MAX,Math.max(bv.ZOOM_MIN,i)),a=function(e,t,i,n,r,o,s){if(!Vg(e)||!Vg({zoom:t,viewBox:i})||!Gg(n)||n<=0||!Gg(r)||r<=0||!Gg(o)||!Gg(s))return null;const a=o/n,l=s/r,c=e.viewBox.x+a*e.viewBox.w,h=e.viewBox.y+l*e.viewBox.h,d=i.w/t,u=i.h/t;return{zoom:t,viewBox:{x:c-a*d,y:h-l*u,w:d,h:u}}}(n&&this._cameraTransition.target||this._cameraState(),s,o,r.clientWidth,r.clientHeight,e,t);return a?(a.viewBox=this._clampView(a.viewBox,o),{target:a,fit:o}):null}_zoomAt(e,t,i){this._clearRoomFocus(),this._cancelCameraTransition(!1);const n=this._cameraTargetAt(e,t,i);n&&("opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1)),this._zoom=n.target.zoom,this._view={...n.target.viewBox},this._liveVp())}_onWheel(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;e.preventDefault();const i=t.getBoundingClientRect(),n=e.deltaY<0?1.15:1/1.15,r=this._cameraTransition.target?.zoom??this._zoom,o=this._cameraTargetAt(e.clientX-i.left,e.clientY-i.top,r*n,!0);o&&this._startCameraTransition(o.target,o.fit,"wheel",160)}_stepZoom(e){this._clearRoomFocus(),this._prepareCameraCommand();const t=this._stageEl;if(!t)return;const i=this._cameraTransition.target?.zoom??this._zoom,n=this._cameraTargetAt(t.clientWidth/2,t.clientHeight/2,i*(e>0?1.4:1/1.4),!0);n&&this._startCameraTransition(n.target,n.fit,"button",180)}_resetZoom(e="fit"){this._clearRoomFocus(),this._prepareCameraCommand();const t=Oi(this._baseVb(),this._stageAspect());this._startCameraTransition({zoom:1,viewBox:{...t}},t,e,220)}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem(cv,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){this._clearRoomFocus(!0),this._cancelCameraTransition(!1);const e=this._zoomBySpace[this._space]||1;this._zoom=e;const t=this._stageEl;if(t&&t.clientHeight){const t=this._baseVb();return this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const t=this._baseVb();this._applyView(e,t[0]+t[2]/2,t[1]+t[3]/2),this.requestUpdate()})}_stagePointerDown(e){this._bootSoftCancel();const t=e.isPrimary&&0===e.button&&"view"===this._mode?mf(e.composedPath()):null;if(this._roomPointer=t?{pointerId:e.pointerId,spaceId:this._space,roomId:t}:null,this._doubleFit.pointerDown(e,this._space,this._doubleFitEnabled),this._cancelCameraTransition(!1,!0),this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:e.clientX,y:e.clientY,id:e.pointerId},e.target.closest?.(".dev, .roomlabel, .oplock")||(clearTimeout(this._kioskHoldTimer),this._kioskHoldTimer=window.setTimeout(()=>{this._roomPointer=null,this._doubleFit.clear(),this._kioskDialog=!0,this._swipeStart=null},3e3))):(this._swipeStart=null,clearTimeout(this._kioskHoldTimer))),this._drag||this._deviceDrag)return;if(this._markup&&e.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&e.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(e))return;this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY});const i=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:e.clientX,sy:e.clientY,vx:i.x,vy:i.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y);this._pinchStart={dist:t,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return!this._hasFixedFloor&&this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(e){if(this._physicalRotate?.pid!==e.pointerId)if(this._physicalDrag?.pid!==e.pointerId)if(this._dtDrag?.pid!==e.pointerId)if(this._bdDrag?.pid!==e.pointerId){if(this._decorDraft?.pid===e.pointerId){const t=this._decorDraft;let i=this._decorSnap(this._svgPoint(e),e.pointerType);if(e.shiftKey&&("rect"===t.kind||"ellipse"===t.kind)){const e=i[0]-t.a[0],n=i[1]-t.a[1],r=Math.max(Math.abs(e),Math.abs(n));i=this._snap([t.a[0]+(e<0?-r:r),t.a[1]+(n<0?-r:r)])}return void(this._decorDraft={...t,b:i})}if(this._decorMove?.pid!==e.pointerId){if("decor"!==this._mode||"furniture"!==this._decorTool&&"image"!==this._decorTool||!this._editorRuntime||(this._notePointer(e),!this._editorRuntime._furnPointerMove(e,this._pointerModality.hoverEnabled)))if(this._pointers.has(e.pointerId)){if(this._pointers.set(e.pointerId,{x:e.clientX,y:e.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(e),this._pinchStart&&this._pointers.size>=2){this._clearRoomFocus(!0),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover();const e=[...this._pointers.values()],t=Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),n=(e[0].x+e[1].x)/2-i.left,r=(e[0].y+e[1].y)/2-i.top;this._zoomAt(n,r,this._pinchStart.zoom*t),this._viewportGestureDirty=!0,this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const t=e.clientX-this._panStart.sx,i=e.clientY-this._panStart.sy;Math.abs(t)+Math.abs(i)>4&&(this._roomPointer=null,this._doubleFit.clear(),this._suppressClick=!0,clearTimeout(this._holdTimer),"opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover()),null===this._panLock&&Math.abs(t)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(t)>1.5*Math.abs(i)?"swipe":"pan","pan"===this._panLock&&this._clearRoomFocus());const n=this._stageEl;if("pan"===this._panLock&&n){const e=this._baseVb(),r=this._viewOr(e),o=Oi(e,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-t/(n.clientWidth||1)*r.w,y:this._panStart.vy-i/(n.clientHeight||1)*r.h,w:r.w,h:r.h},o),this._viewportGestureDirty=!0,this._liveVp()}}}else this._markupMove(e)}else this._decorMoveUpdate(e)}else this._bdMove(e);else this._dtMove(e);else this._physicalMove(e);else this._physicalRotateMove(e)}_stagePointerLeave(e){this._editorRuntime?._cancelPointerMove("markup-hover"),"decor"===this._mode&&this._editorRuntime?._furnPointerLeave(e),this._markup&&("opening"===this._tool?(this._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this._tool&&this._clearPlanSnapHover())}_stagePointerUp(e){this._deviceHits.release(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover");const t=(i=this._roomPointer,n=e.pointerId,r=this._space,o=this._roomPointer&&"view"===this._mode?mf(e.composedPath()):null,s=this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired||this._touchSequenceMultitouch,!i||s||i.pointerId!==n||i.spaceId!==r||i.roomId!==o?null:i.roomId);var i,n,r,o,s;this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null);if(this._doubleFit.pointerUp(e,this._space,this._doubleFitEnabled,this._suppressClick||!!this._pinchStart||null!==this._panLock||this._holdFired)&&this._fitAll("double-tap"),this._kiosk){clearTimeout(this._kioskHoldTimer);const i=this._swipeStart;if(this._swipeStart=null,!t&&i&&i.id===e.pointerId){const t=e.clientX-i.x,n=e.clientY-i.y,r="pan"===this._panLock?null:function(e,t,i,n,r,o=60){if(i>1.001||n.length<2)return null;if(Math.abs(e)e.id),this._space);r&&this._slideTo(r,t<0?"left":"right")&&(this._saveNav(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._showKioskDots())}}this._physicalDrag?.pid!==e.pointerId?this._physicalRotate?.pid!==e.pointerId?this._dtDrag?.pid!==e.pointerId?this._bdDrag?.pid!==e.pointerId?this._decorDraft?.pid!==e.pointerId?this._decorMove?.pid!==e.pointerId?this._editorRuntime?._furnPointerUp(e)||(this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._suppressClick&&setTimeout(()=>this._suppressClick=!1,0)),this._viewportGestureDirty&&0===this._pointers.size&&!t&&(this._viewportGestureDirty=!1,this.requestUpdate()),t&&this._fitRoom(t)):this._editorRuntimeOrThrow()._dmUp():this._decorCommitDraft():this._bdUp():this._dtUp():this._physicalRotateUp(e):this._physicalUp(e)}_clickRoom(e){!this._suppressClick&&e.area&&gv("/config/areas/area/"+e.area)}_roomLabelKey(e,t){"view"!==this._mode||"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),e.stopPropagation(),this._fitRoom(t))}_pointerDown(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if("view"===this._mode&&"touch"===e.pointerType&&this._touchSequenceMultitouch)return;if(t=this._deviceHits.begin(this.renderRoot,this._renderDevices,this._space,e,t),"view"===this._mode){this._holdFired=!1,clearTimeout(this._holdTimer);const i=e.pointerId,n=e.currentTarget;return void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._interruptViewGesture(i,n),this._infoCard=t},600))}if("ha_disabled"===t.bindingStatus?.kind||this._devicePositionBusy)return;if(this._deviceDrag)return void(this._deviceDrag.pointerId!==e.pointerId&&this._cancelDeviceDrag());e.preventDefault();const i=this._pos(t);this._deviceDrag={id:t.id,spaceId:t.space,displayName:t.name,pointerId:e.pointerId,source:e.currentTarget,sx:e.clientX,sy:e.clientY,ox:i.x,oy:i.y,moved:!1,before:gg(this._layout,t.id),start:this._devicePlacementForCanvas(t,i.x,i.y)},vv(e),this._tip=null,this._syncLiveHover()}_pointerMove(e,t){if("view"!==this._mode&&"devices"!==this._mode)return null;if(t=this._deviceForPointerEvent(e,t),"devices"!==this._mode)return t;const i=this._deviceDrag;return i&&i.id===t.id&&i.pointerId===e.pointerId?(this._editorRuntimeOrThrow()._queuePointerMove("device",()=>this._pointerMoveNow(e,t)),t):t}_pointerMoveNow(e,t){if("devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;const n=this.renderRoot.querySelector(".stage");if(!n)return;const r=this._baseVb(),o=n.getBoundingClientRect(),s=this._viewOr(r),a=(e.clientX-i.sx)/o.width*s.w,l=(e.clientY-i.sy)/o.height*s.h;Math.abs(e.clientX-i.sx)+Math.abs(e.clientY-i.sy)>3&&(i.moved=!0,clearTimeout(this._holdTimer));const c=rl(i.ox+a),h=rl(i.oy+l);this._previewDevicePlacement(t.id,this._devicePlacementForCanvas(t,c,h))}_pointerUp(e,t){if(t=this._deviceForPointerEvent(e,t),this._deviceHits.release(e.pointerId),clearTimeout(this._holdTimer),"devices"!==this._mode)return;const i=this._deviceDrag;if(!i||i.id!==t.id||i.pointerId!==e.pointerId)return;this._editorRuntimeOrThrow()._flushPointerMove("device"),this._deviceDrag=null;const n=gg(this._layout,t.id);var r,o;i.moved&&null!==n&&(r=n,o=i.start,null===r||null===o?r!==o:r.x!==o.x||r.y!==o.y||r.s!==o.s)?(this._selId=t.id,this._suppressClick=!0,window.setTimeout(()=>{this._suppressClick=!1},0),this._devicePositionBusy=!0,this.requestUpdate(),this._persistDevicePlacement(t.id,n).then(()=>{const e=this._t("history.device_move",{name:i.displayName});this._devicePositionHistory.push({name:e,before:{deviceId:i.id,spaceId:i.spaceId,placement:i.before},after:{deviceId:i.id,spaceId:i.spaceId,placement:n}})}).catch(e=>{this._previewDevicePlacement(t.id,i.before),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))}).finally(()=>{this._devicePositionBusy=!1,this.requestUpdate()})):this._previewDevicePlacement(t.id,i.before)}_pointerCancel(e,t){t=this._deviceForPointerEvent(e,t),this._deviceHits.cancel(e.pointerId),this._deviceDrag?.id===t.id&&this._deviceDrag.pointerId===e.pointerId&&this._cancelDeviceDrag()}_showToast(e){for(const e of this.renderRoot.querySelectorAll("hp-dialog"))e.closeTransientOverlays("toast");this._toast=e,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}_syncPointerHoverTargets(){const e=this._pointerModality.hoverEnabled;for(const t of this.renderRoot.querySelectorAll(uv))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(uv)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(uv))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),this._liveRt?.clearDeviceFocus(),this._deviceHits.hover(this.renderRoot,null),this._tip&&(this._tip=null),this._hoverRoom&&(this._hoverRoom=null),this._syncLiveHover()}_notePointer(e){const t=this._pointerModality.modality,i=this._pointerModality.note(e);"touch"!==i&&"pen"!==i||t===i&&!this._tip&&!this._hoverRoom||this._clearTransientHover()}_guardTouchGesture(e){if(this._editorSecondary?.handleOutsideDismiss(e))return;if(this._touchClickGuard.handleActivation(e,this._suppressClick))return;const t=e;if(this._notePointer(t),"pointercancel"===e.type||"lostpointercapture"===e.type?this._doubleFit.clear():"pointerdown"===e.type&&this._doubleFit.clearOutside(t),"pointerdown"===e.type&&this._touchClickGuard.pointerDown(t.pointerId,t.pointerType),"touch"!==t.pointerType)return;if("pointerdown"===e.type){if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._deviceHits.clearPointers(),this._clearRoomFocus(!0),this._clearTransientHover(),clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),this._swipeStart=null;const e=[...this._touchContacts.values()];if("view"===this._mode&&!this._vacFit&&e.every(e=>e.inStage)){this._pointers=new Map([...this._touchContacts].map(([e,t])=>[e,{x:t.x,y:t.y}]));const[t,i]=e;this._pinchStart={dist:Math.hypot(t.x-i.x,t.y-i.y),zoom:this._zoom},this._panStart=null,this._panLock=null}else this._vacFit&&(this._pointers.clear(),this._pinchStart=null,this._panStart=null,this._panLock=null)}return}if("pointermove"===e.type){const e=this._touchContacts.get(t.pointerId);if(!e)return;const i={...e,x:t.clientX,y:t.clientY};if(this._touchContacts.set(t.pointerId,i),this._touchSequenceMultitouch&&"view"===this._mode&&!this._vacFit&&this._pinchStart&&[...this._touchContacts.values()].every(e=>e.inStage)){this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=[...this._touchContacts.values()];if(e.length>=2&&this._stageEl){const[t,i]=e,n=Math.hypot(t.x-i.x,t.y-i.y)/(this._pinchStart.dist||1),r=this._stageEl.getBoundingClientRect();this._zoomAt((t.x+i.x)/2-r.left,(t.y+i.y)/2-r.top,this._pinchStart.zoom*n),this._saveZoom()}}return}if("pointerup"!==e.type&&"pointercancel"!==e.type&&"lostpointercapture"!==e.type)return;const i=this._touchClickGuard.pointerTerminal(t.pointerId,t.pointerType);if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),i){if(this._pointers.delete(t.pointerId),!this._vacFit&&this._pointers.size>=2){const[e,t]=[...this._pointers.values()];this._pinchStart={dist:Math.hypot(e.x-t.x,e.y-t.y),zoom:this._zoom}}else this._pinchStart=null;0===this._pointers.size&&(this._panStart=null,this._panLock=null)}}_showTip(e,t,i,n,r,o,s=!1){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||this._deviceDrag||s&&this._liveRt?.deviceFocusActive()||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:n,temp:r,hum:o,room:s,source:"pointer"},this._syncLiveHover()))}_roomTipEnabledForPointer(e){return"view"===this._mode&&(this._notePointer(e),!!_n(this._settings)||(this._tip?.room&&(this._tip=null,this._syncLiveHover()),!1))}get _gridPitch(){return el}get _cellCm(){const e=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(e)&&e>0?e:5}_fmtLen(e,t){const i=function(e,t,i,n){return Math.hypot(t[0]-e[0],t[1]-e[1])/i*n}(e,t,this._gridPitch,this._cellCm);return ti(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const e=this._resize?.preview;return e&&e.space===this._space?e.sp:this._serverCfg?.spaces.find(e=>e.id===this._space)}get _renderCfg(){const e=this._resize?.preview;return e&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(t=>t.id===e.space?e.sp:t)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,pv}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return oi(e?.rooms||[]).map(e=>[e[0]*pv,e[1]*t,e[2]*pv,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(hv)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(hv,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,this._configReloadAuthority.invalidateLifecycle(),this._summary?.leaveRoute(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._drawWallField=null,this._showHidden=!1,this._tapConfirm=null,this._vacCalConfirm=null,this._decorEraseConfirm=null,this._openingInfo=null,this._closeInfoCard(),this._rulesDialog=null,this._alignDialog=null,this._preflightClipboardFallback=null,this._backupImportDialog=null,this._backupExportDialog=null,this._pdfDialog=!1,this._supportDialog?.preview?.token&&this._editorRuntime?._discardSupportPreview(this._supportDialog.preview.token),this._supportDialog=null,this._settingsDialog=null,this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._openingDialog=null,this._physicalDialog=null,this._wallDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._mergeDialog=null,this._roomDialog=!1,this._spaceDialog=null,this._importDialog=null;const e=this._warmSlot;e?.owner===this._warmGen&&(e.vp=this._warmViewportState(),e.dlg=null,e.frameFingerprint="",clearTimeout(e.evict),e.evict=0),this._saveNav()}_setMode(e,t=!0){return e!==this._mode&&(this._clearRoomFocus(!0),this._cancelDangerConfirm(),this._resetDeviceHitState(),this._clearTransientHover(!0)),this._warmModeRequest=0,this._editorRuntime?this._editorRuntime._setMode(e,t):"view"===e?void this._editorModeRequest++:void this._requestMode(e,t)}_primeDrawWallField(){return this._editorRuntimeOrThrow()._primeDrawWallField()}get _drawWallFieldValue(){return null===this._drawWallField?Ao(15,this._imperial):this._drawWallField}get _drawWallCm(){const e=(e=>{const t=String(e??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(t))return null;const i=Number(t);return Number.isFinite(i)?i:null})(this._drawWallFieldValue);if(null==e||e<0)return null;const t=this._imperial?2.54*e:e,i="column"===this._tool?pa:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?pa:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){return this._editorRuntimeOrThrow()._showPhysicalRange(e,t)}_mergeSpacePartitions(e,t){return this._editorRuntimeOrThrow()._mergeSpacePartitions(e,t)}_finishWallChain(){return this._editorRuntimeOrThrow()._finishWallChain()}_activateMarkupTool(e){return this._editorRuntimeOrThrow()._activateMarkupTool(e)}_limitReached(e){return this._editorRuntimeOrThrow()._limitReached(e)}_svgPoint(e){return this._editorRuntimeOrThrow()._svgPoint(e)}_snap(e){return this._editorRuntimeOrThrow()._snap(e)}_snapDrawPoint(e,t=!1){return this._editorRuntimeOrThrow()._snapDrawPoint(e,t)}_planSnapOpeningCuts(e,t){return this._editorRuntimeOrThrow()._planSnapOpeningCuts(e,t)}_planSnapGeometrySnapshot(){return this._editorRuntimeOrThrow()._planSnapGeometrySnapshot()}_hiddenWallDiagnosticSnapshot(){return this._editorRuntimeOrThrow()._hiddenWallDiagnosticSnapshot()}_planStructuralGeometrySnapshot(){return this._editorRuntimeOrThrow()._planStructuralGeometrySnapshot()}_planSnapContextKey(e){return this._editorRuntimeOrThrow()._planSnapContextKey(e)}_resolvePlanDrawPoint(e,t){return this._editorRuntimeOrThrow()._resolvePlanDrawPoint(e,t)}get _activePlanSnapCandidate(){if(!this._markup||"draw"!==this._tool)return null;const e=this._planSnapHover;if(!e)return null;const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.candidate:null}get _activePlanSnapConflicts(){if(!this._markup||"draw"!==this._tool)return[];const e=this._planSnapHover;if(!e)return[];const t=this._planSnapGeometrySnapshot();return e.contextKey===this._planSnapContextKey(t.key)?e.conflicts:[]}_clearPlanSnapHover(e=!0){return this._editorRuntime?this._editorRuntimeOrThrow()._clearPlanSnapHover(e):(this._planSnapHover=null,void(e&&(this._cursorPt=null)))}_samePt(e,t){return _i(e,t)}_dropLegacySegments(){return this._editorRuntimeOrThrow()._dropLegacySegments()}_rollbackRejectedPhysicalWrites(e){return this._editorRuntimeOrThrow()._rollbackRejectedPhysicalWrites(e)}async _reloadRejectedPhysicalWrite(){return this._editorRuntimeOrThrow()._reloadRejectedPhysicalWrite()}get _cfgWriting(){return this._writesPending>0}async _sendConfigCandidate(e){const t=wo(e),i=await this.hass.callWS({type:"houseplan/config/set",config:t,expected_rev:this._cfgRev});this._adoption.acceptConfigWrite(t,i)}_writeConfig(){if(this._editorRuntime)return this._editorRuntime._writeConfig();this._writesPending++,this._writeChain=Nu(this._writeChain,async()=>{if(!this._serverCfg)return;const e=wo(this._serverCfg);this._adoption.stageConfigCandidate(e),await this._sendConfigCandidate(e)});return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_geometrySnapshotFromConfig(e,t){return this._editorRuntimeOrThrow()._geometrySnapshotFromConfig(e,t)}_geometrySnapshot(e=this._space){return this._editorRuntimeOrThrow()._geometrySnapshot(e)}_recordGeometry(e,t){return this._editorRuntimeOrThrow()._recordGeometry(e,t)}_restoreGeometryStateInConfig(e,t,i=!1){return this._editorRuntimeOrThrow()._restoreGeometryStateInConfig(e,t,i)}_restoreGeometryStateLocal(e){return this._editorRuntimeOrThrow()._restoreGeometryStateLocal(e)}_wallModelBlockerLabel(e){return this._editorRuntimeOrThrow()._wallModelBlockerLabel(e)}_hasLegacyZeroWallFields(e=this._serverCfg){return this._editorRuntimeOrThrow()._hasLegacyZeroWallFields(e)}_showWallModelMigrationBlocked(e){return this._editorRuntimeOrThrow()._showWallModelMigrationBlocked(e)}_limitSegmentsOf(e){return this._editorRuntimeOrThrow()._limitSegmentsOf(e)}_junctionLimitViolations(e,t,i,n){return this._editorRuntimeOrThrow()._junctionLimitViolations(e,t,i,n)}_junctionLimitLabel(e){return this._editorRuntimeOrThrow()._junctionLimitLabel(e)}_junctionLimitsIntroduced(e,t,i){return this._editorRuntimeOrThrow()._junctionLimitsIntroduced(e,t,i)}_commitPhysicalGeometry(e,t,i=[]){return this._editorRuntimeOrThrow()._commitPhysicalGeometry(e,t,i)}_clearGeometryGesture(){return this._editorRuntime?this._editorRuntimeOrThrow()._clearGeometryGesture():(this._path=[],this._planSnapHover=null,this._cursorPt=null,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingPreset=null,this._openingRebindId=null,this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._roomDeleteDialog=null,this._wallDialog=null,this._physicalDialog=null,this._physicalSel=null,this._physicalDrag=null,this._physicalRotate=null,this._activeWallChainId=null,this._wallChainSegmentCms=[],this._closingWallCm=null,this._openingDialog=null,this._resize?.reset(),this._decorDraft=null,this._decorMove=null,this._dtDrag=null,void(this._bdDrag=null))}_stagePointerCancel(e){if(this._deviceHits.cancel(e.pointerId),this._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover"),this._roomPointer?.pointerId===e.pointerId&&(this._roomPointer=null),this._doubleFit.clear(),this._editorRuntime)return this._editorRuntime._stagePointerCancel(e);this._pointers.delete(e.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,this._swipeStart=null),this._viewportGestureDirty&&0===this._pointers.size&&(this._viewportGestureDirty=!1,this.requestUpdate())}_applyGeometryState(e,t=!1){return this._editorRuntimeOrThrow()._applyGeometryState(e,t)}_roomAt(e){return this._editorRuntimeOrThrow()._roomAt(e)}_overlapRoom(e){return this._editorRuntimeOrThrow()._overlapRoom(e)}_pointInRoom(e,t){return t.poly?mi(e,t.poly):null!=t.x&&e[0]>=t.x&&e[0]<=t.x+t.w&&e[1]>=t.y&&e[1]<=t.y+t.h}_contourSelfIntersects(e){return this._editorRuntimeOrThrow()._contourSelfIntersects(e)}_canAppendWallPoint(){return this._editorRuntimeOrThrow()._canAppendWallPoint()}_markupClick(e){if(this._editorRuntime)return this._editorRuntime._markupClick(e)}_activeWallSourceKey(e){return this._editorRuntimeOrThrow()._activeWallSourceKey(e)}_wallGraphSources(e){return this._editorRuntimeOrThrow()._wallGraphSources(e)}_wallFaceGraph(e,t){return this._editorRuntimeOrThrow()._wallFaceGraph(e,t)}_offerWallFaces(e,t=this._path.length-2,i){return this._editorRuntimeOrThrow()._offerWallFaces(e,t,i)}_beginWallFaceBatch(e){return this._editorRuntimeOrThrow()._beginWallFaceBatch(e)}_offerExistingWallFace(e){return this._editorRuntimeOrThrow()._offerExistingWallFace(e)}_columnClick(e){return this._editorRuntimeOrThrow()._columnClick(e)}_openPhysicalDialog(e,t){return this._editorRuntimeOrThrow()._openPhysicalDialog(e,t)}_physicalDown(e,t,i){return this._editorRuntimeOrThrow()._physicalDown(e,t,i)}_clampPhysicalDelta(e,t,i){return this._editorRuntimeOrThrow()._clampPhysicalDelta(e,t,i)}_physicalMove(e){return this._editorRuntimeOrThrow()._physicalMove(e)}_physicalUp(e){return this._editorRuntimeOrThrow()._physicalUp(e)}_registerPhysicalTap(e,t){return this._editorRuntimeOrThrow()._registerPhysicalTap(e,t)}_cancelPhysicalGesture(){return this._editorRuntimeOrThrow()._cancelPhysicalGesture()}_physicalRotateDown(e,t){return this._editorRuntimeOrThrow()._physicalRotateDown(e,t)}_physicalRotateMove(e){return this._editorRuntimeOrThrow()._physicalRotateMove(e)}_physicalRotateUp(e){return this._editorRuntimeOrThrow()._physicalRotateUp(e)}_rszRooms(){return this._editorRuntimeOrThrow()._rszRooms()}_rszOpenings(){return this._editorRuntimeOrThrow()._rszOpenings()}_rszObstacles(){return this._editorRuntimeOrThrow()._rszObstacles()}_rszOptsFor(e,t){return this._editorRuntimeOrThrow()._rszOptsFor(e,t)}_rszResolution(e,t,i){return this._editorRuntimeOrThrow()._rszResolution(e,t,i)}_rszSnapshot(){return this._editorRuntimeOrThrow()._rszSnapshot()}_rszResetController(){return this._editorRuntimeOrThrow()._rszResetController()}_rszProjectPreview(e,t,i,n,r){return this._editorRuntimeOrThrow()._rszProjectPreview(e,t,i,n,r)}_rszAcceptPreview(e,t){return this._editorRuntimeOrThrow()._rszAcceptPreview(e,t)}_rszSpaceCandidateGeometry(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateGeometry(e,t)}_rszSpaceCandidateRenderable(e,t){return this._editorRuntimeOrThrow()._rszSpaceCandidateRenderable(e,t)}_rszCandidateRenderable(e){return this._editorRuntimeOrThrow()._rszCandidateRenderable(e)}_rszEdgeDown(e,t,i){return this._editorRuntimeOrThrow()._rszEdgeDown(e,t,i)}_rszReasonText(e){return this._editorRuntimeOrThrow()._rszReasonText(e)}_rszDisabledActivate(e,t){return this._editorRuntimeOrThrow()._rszDisabledActivate(e,t)}_rszDisabledKey(e,t){return this._editorRuntimeOrThrow()._rszDisabledKey(e,t)}_rszMove(e){return this._editorRuntimeOrThrow()._rszMove(e)}_rszUp(e){return this._editorRuntimeOrThrow()._rszUp(e)}_rszCancelDrag(e){return this._editorRuntimeOrThrow()._rszCancelDrag(e)}_rszPointerCancel(e){return this._editorRuntimeOrThrow()._rszPointerCancel(e)}_rszEdgeLabels(e,t,i=this._resize?.rooms){return this._editorRuntimeOrThrow()._rszEdgeLabels(e,t,i)}_rszInnerSpanCms(e,t,i){return this._editorRuntimeOrThrow()._rszInnerSpanCms(e,t,i)}_renderResizeMeasurements(){return this._editorRuntimeOrThrow()._renderResizeMeasurements()}_renderResizeLayer(e,t){return this._editorRuntimeOrThrow()._renderResizeLayer(e,t)}get _openingsR(){const e=this._curSpaceCfg,t=this._spaceH,i=this._spaceModel();return i?(e?.openings||[]).flatMap(e=>{const n={...e,rx:e.x*pv,ry:e.y*t,rlen:e.length*pv};if(!e.host||"wall"===e.host.kind)return[n];const r=Zu(e,i.partitions,pv,this._cellCm,this._gridPitch);if(!r.resolved)return"plan"===this._mode?[{...n,orphanReason:r.reason||"invalid-host"}]:[];let[o,s]=r.resolved.center;const a=this._physicalDrag;return a?.moved&&"partition"===a.kind&&a.id===e.host.id&&(o+=a.delta[0],s+=a.delta[1]),[{...e,rx:o,ry:s,rlen:r.resolved.length,angle:r.resolved.angle,partitionHost:r.resolved}]}):[]}_partitionOpeningCuts(e=this._spaceModel(),t=()=>!0){if(!e)return[];return U_(W_(this._curSpaceCfg?.id===e.id?this._curSpaceCfg:null,e,this._cellCm,this._gridPitch,pv),t)}_roomWallOpeningInputs(e=this._openingsR,t=this._spaceModel()){if(!t)return[];const i=this._openCuts();return G_(e,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,pv)}_openingFace(e,t,i){return e.partitionHost?tp(e.partitionHost,i):ca(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen,flip_v:i})}_cmToUnits(e){return e/this._cellCm*this._gridPitch}get _decorList(){const e=this._curSpaceCfg;return Array.isArray(e?.decor)?e.decor:[]}get _decorH(){return pv}_decorResolvedStyle(e){return function(e,t,i,n=Sr){const r="rect"===e?.kind||"ellipse"===e?.kind,o=e,s=Kt(o?.color,n.color);return{color:s,opacity:$r(o?.opacity,n.opacity),widthCm:Ar(e,t,i,n.widthCm),fill:!!r&&!0===o?.fill,fillColor:Kt(o?.fill_color,o?.fill?s:n.fillColor),fillOpacity:r&&o?.fill?$r(o?.fill_opacity,.25):n.fillOpacity}}(e,this._cellCm,this._gridPitch,Sr)}_decorWidthUnits(e){return((e,t,i,n=Sr.widthCm)=>{const r=Number(e?.width_cm);if(Number.isFinite(r)&&r>0)return Tr(r,t,i);const o=Number(e?.width);return Number.isFinite(o)&&o>0?o:Tr(n,t,i)})(e,this._cellCm,this._gridPitch,Sr.widthCm)}_decorTextSizeCm(e){if("text"===e?.kind){const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?t:Dr(20*tn(e),this._cellCm,this._gridPitch)}return Dr(20,this._cellCm,this._gridPitch)}_decorTextUnits(e){if("text"!==e.kind)return 20;const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?Tr(t,this._cellCm,this._gridPitch):20*tn(e)}_decorSmallField(e){return Math.round(100*(this._imperial?e/2.54:e))/100}_decorSmallCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(100,t)):.1}_decorTextCm(e){const t=this._imperial?2.54*e:e;return Number.isFinite(t)?Math.max(.1,Math.min(2e3,t)):.1}_decorLargeField(e){return Math.round(100*(this._imperial?e/30.48:e/100))/100}_decorLargeCm(e){const t=this._imperial?30.48*e:100*e;return Number.isFinite(t)?Math.max(.1,Math.min(Za*this._cellCm,t)):.1}_angleField(e){const t=Number(e);return Number.isFinite(t)?String(Number(t.toFixed(3))):"0"}_decorBoxOf(e){return"rect"!==e.kind&&"ellipse"!==e.kind&&"furniture"!==e.kind&&"image"!==e.kind?null:{x:e.x*pv,y:e.y*this._decorH,w:e.w*pv,h:e.h*this._decorH,angle:Mr(e.angle)||void 0}}_decorSnapGeometry(e){return this._editorRuntimeOrThrow()._decorSnapGeometry(e)}_decorSnap(e,t="mouse",i){return this._editorRuntimeOrThrow()._decorSnap(e,t,i)}_replaceDecor(e,t){return this._editorRuntimeOrThrow()._replaceDecor(e,t)}_cancelDecorGesture(){return this._editorRuntimeOrThrow()._cancelDecorGesture()}_decorPointerDown(e){return this._editorRuntimeOrThrow()._decorPointerDown(e)}_decorCommitDraft(){return this._editorRuntimeOrThrow()._decorCommitDraft()}_decorShapeDown(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDown(e,t)}_decorMoveUpdate(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-move",()=>this._editorRuntimeOrThrow()._decorMoveUpdate(e))}_decorNudge(e,t){if("decor"!==this._mode||"select"!==this._decorTool||!this._decorSel||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag)return!1;const i=this._decorList.find(e=>e.id===this._decorSel),n=this._curSpaceCfg;if(!i||!n)return!1;const r=function(e,t,i,n,r,o){if(!([t,i,n,r,o].every(Number.isFinite)&&r>0))return null;let s;if(s="line"===e.kind?[[e.x1,e.y1],[e.x2,e.y2]]:"text"===e.kind?[[e.x,e.y]]:zr(e),!s.length||s.some(e=>!e.slice(0,2).every(Number.isFinite)))return null;const a=s.map(e=>e[0]),l=s.map(e=>e[1]),c=Math.min(...a),h=Math.max(...a),d=Math.min(...l),u=Math.max(...l),p=t/n,_=i/r,m=p>0?Math.min(p,Math.max(0,o-h)):Math.max(p,Math.min(0,-o-c)),g=_>0?Math.min(_,Math.max(0,o-u)):Math.max(_,Math.min(0,-o-d));return m||g?"line"===e.kind?{...e,x1:e.x1+m,y1:e.y1+g,x2:e.x2+m,y2:e.y2+g}:{...e,x:e.x+m,y:e.y+g}:null}(i,e,t,pv,this._decorH,Za);if(!r)return!1;const o=this._geometrySnapshot();return n.decor=this._decorList.map(e=>e.id===i.id?r:e),this._recordGeometry(this._t("history.decor_move"),o),this._saveConfig(),this.requestUpdate(),!0}_decorShapeDbl(e,t){if(this._editorRuntime)return this._editorRuntime._decorShapeDbl(e,t)}_openDecorProperties(e){return this._editorRuntimeOrThrow()._openDecorProperties(e)}_decorOpenText(e){return this._editorRuntimeOrThrow()._decorOpenText(e)}_decorRememberTextSelection(e){return this._editorRuntimeOrThrow()._decorRememberTextSelection(e)}_decorInsertLiveVariable(e){return this._editorRuntimeOrThrow()._decorInsertLiveVariable(e)}_decorSaveText(){return this._editorRuntimeOrThrow()._decorSaveText()}_decorSaveShape(){return this._editorRuntimeOrThrow()._decorSaveShape()}get _dtSel(){return"decor"===this._mode&&"select"===this._decorTool&&this._decorSel&&this._decorList.find(e=>e.id===this._decorSel)||null}_dtPivot(e){return this._editorRuntimeOrThrow()._dtPivot(e)}_dtApply(e,t){return this._editorRuntimeOrThrow()._dtApply(e,t)}_dtStart(e,t,i,n){return this._editorRuntimeOrThrow()._dtStart(e,t,i,n)}_dtMove(e){this._editorRuntimeOrThrow()._queuePointerMove("decor-transform",()=>this._editorRuntimeOrThrow()._dtMove(e))}_dtUp(){return this._editorRuntimeOrThrow()._flushPointerMove("decor-transform"),this._editorRuntimeOrThrow()._dtUp()}_dtMeasure(){return this._editorRuntimeOrThrow()._dtMeasure()}_deleteDecor(e){return this._editorRuntimeOrThrow()._deleteDecor(e)}_decorDeleteSel(){return this._editorRuntimeOrThrow()._decorDeleteSel()}_confirmDecorErase(){return this._editorRuntimeOrThrow()._confirmDecorErase()}get _bdBase(){const e=this._curSpaceCfg;return e?.plan_url?{...Ua(e.plan_aspect,pv)}:null}get _bdRect(){const e=this._curSpaceCfg;return e?.plan_url?Ka(e,pv):null}get _bdParams(){const e=this._curSpaceCfg,t=Number(e?.plan_x),i=Number(e?.plan_y),n=Number(e?.plan_scale),r=Number(e?.plan_scale_x),o=Number(e?.plan_scale_y),s=Number.isFinite(n)&&n>0?n:1;return{dx:Number.isFinite(t)?t:0,dy:Number.isFinite(i)?i:0,sx:Number.isFinite(r)&&r>0?r:s,sy:Number.isFinite(o)&&o>0?o:s,angle:Mr(e?.plan_angle)}}_openBackdropDialog(e){if(this._editorRuntime)return this._editorRuntime._openBackdropDialog(e)}_saveBackdropDialog(){return this._editorRuntimeOrThrow()._saveBackdropDialog()}get _bdActive(){return"decor"===this._mode&&!!this._bdRect&&"backdrop"===this._decorTool}get _bdMovable(){return"decor"===this._mode&&"backdrop"===this._decorTool&&!!this._bdRect}_bdApply(e,t,i,n,r){return this._editorRuntimeOrThrow()._bdApply(e,t,i,n,r)}_bdStart(e,t,i=!1){return this._editorRuntimeOrThrow()._bdStart(e,t,i)}_bdMove(e){return this._editorRuntimeOrThrow()._bdMove(e)}get _bdMoved(){if("decor"!==this._mode||!this._bdRect)return!1;const e=this._bdParams;return 0!==e.dx||0!==e.dy||1!==e.sx||1!==e.sy||0!==e.angle}_bdReset(){return this._editorRuntimeOrThrow()._bdReset()}_bdUp(){return this._editorRuntimeOrThrow()._bdUp()}get _bdLive(){if(!this._bdDrag)return null;const e=this._bdRect;return e?{x:e.x+e.w/2,y:e.y+e.h/2,text:`${this._fmtLen([0,0],[e.w,0])} × ${this._fmtLen([0,0],[0,e.h])}`}:null}_renderBackdropFrame(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderBackdropFrame(e):G}_renderTextFrame(e){const t=this._dtSel;if(!t)return G;if("text"===t.kind&&this._dtBox?.id!==t.id)return G;const i="text"===t.kind?this._dtBox:this._decorBoxOf(t);if("line"!==t.kind&&!i)return G;const n=.018*Math.max(e.w,e.h),r=n/4;if("line"===t.kind){const e=[t.x1*pv,t.y1*this._decorH],i=[t.x2*pv,t.y2*this._decorH];return W` ${[e,i].map((e,t)=>W`this._dtStart(e,"scale",void 0,t)}> @@ -375,13 +375,13 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 this._dtStart(e,"rotate")}> - ${vv.map(e=>"edges"===e?d.map(([e,t,o])=>{const s=e<0?i.x:e>0?i.x+i.w:i.x+i.w/2,a=t<0?i.y:t>0?i.y+i.h:i.y+i.h/2;return W`"edges"===e?d.map(([e,t,o])=>{const s=e<0?i.x:e>0?i.x+i.w:i.x+i.w/2,a=t<0?i.y:t>0?i.y+i.h:i.y+i.h/2;return W`this._dtStart(i,"scale",[e,t])}> `}):l.map(([e,t,o])=>W`this._dtStart(i,"scale",[e,t])}>`))} - `}_renderDecorLayer(e,t=this._viewOr(this._baseVb())){const i=uv,n=this._decorH,r="decor"===this._mode,o=r&&"erase"===this._decorTool,s=this._stageEl,a="iso"===this._renderProjection?1:function(e,t,i,n){const r=Number(e),o=Number(t),s=Number(i),a=Number(n);if(![r,o,s,a].every(e=>Number.isFinite(e)&&e>0))return 1;const l=Math.min(r/s,o/a);return Number.isFinite(l)&&l>0?l:1}(s?.clientWidth,s?.clientHeight,t.w,t.h),l=this._decorList.filter(t=>void 0===e||t.id===e).map(e=>{const t="dshape"+(r&&this._decorSel===e.id?" dsel":""),s=this._decorResolvedStyle(e),l=this._decorWidthUnits(e),c=t=>this._decorShapeDown(t,e),h=t=>this._decorShapeDbl(t,e);if("line"===e.kind)return W``}_renderDecorLayer(e,t=this._viewOr(this._baseVb())){const i=pv,n=this._decorH,r="decor"===this._mode,o=r&&"erase"===this._decorTool,s=this._stageEl,a="iso"===this._renderProjection?1:function(e,t,i,n){const r=Number(e),o=Number(t),s=Number(i),a=Number(n);if(![r,o,s,a].every(e=>Number.isFinite(e)&&e>0))return 1;const l=Math.min(r/s,o/a);return Number.isFinite(l)&&l>0?l:1}(s?.clientWidth,s?.clientHeight,t.w,t.h),l=this._decorList.filter(t=>void 0===e||t.id===e).map(e=>{const t="dshape"+(r&&this._decorSel===e.id?" dsel":""),s=this._decorResolvedStyle(e),l=this._decorWidthUnits(e),c=t=>this._decorShapeDown(t,e),h=t=>this._decorShapeDbl(t,e);if("line"===e.kind)return W``:G}`;if("rect"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=$r(e.angle);return W``:G}`;if("rect"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=Mr(e.angle);return W``:G}`}if("ellipse"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=$r(e.angle);return W``:G}`}if("ellipse"===e.kind){const r=(e.x+e.w/2)*i,a=(e.y+e.h/2)*n,d=Mr(e.angle);return W``:G}`}if("image"===e.kind){const s=lm(e,i,n);if(!s)return G;const[a,l,d,u,p,_]=s,m=this._decorAssets.get(e.asset_id);if(!m)return r&&this._editorRuntime?this._editorRuntime._renderMissingDecorImage(e,t,_,a,l,d,u,c,h):G;const g=this._display(m.url);return g?W``:G}`}if("image"===e.kind){const s=cm(e,i,n);if(!s)return G;const[a,l,d,u,p,_]=s,m=this._decorAssets.get(e.asset_id);if(!m)return r&&this._editorRuntime?this._editorRuntime._renderMissingDecorImage(e,t,_,a,l,d,u,c,h):G;const g=this._display(m.url);return g?W`this._signer.markLoaded(this._renderPlanHass,m.url,g)} @pointerdown=${c} @dblclick=${h}> ${o?W``:G}`:G}if("furniture"===e.kind){const d=Vl(e.symbol,this);if(!d)return G;const u=Jl(e,i,n,d.viewW,d.viewH),p=Kl(l,a),_=Kl(l+Cr(20,this._cellCm,this._gridPitch),a);return W``:G}`:G}if("furniture"===e.kind){const d=Kl(e.symbol,this);if(!d)return G;const u=Ql(e,i,n,d.viewW,d.viewH),p=Yl(l,a),_=Yl(l+Tr(20,this._cellCm,this._gridPitch),a);return W`this._renderEntityAvailable(e))),l=e.x*i,d=e.y*n,u=Number(e.angle)||0,p=d-(a.length-1)*r*1.2/2;return W`${a.map((e,t)=>W`${e}`)}`}return G});let c=G;const h=this._decorDraft;if(h){const e=this._decorStyle,t=Cr(e.widthCm,this._cellCm,this._gridPitch);if("line"===h.kind)c=W`${a.map((e,t)=>W`${e}`)}`}return G});let c=G;const h=this._decorDraft;if(h){const e=this._decorStyle,t=Tr(e.widthCm,this._cellCm,this._gridPitch);if("line"===h.kind)c=W``;else{const i=Math.min(h.a[0],h.b[0]),n=Math.min(h.a[1],h.b[1]),r=Math.abs(h.b[0]-h.a[0]),o=Math.abs(h.b[1]-h.a[1]);c="rect"===h.kind?W``:W``}}return W`${l}${c}${this._editorRuntime?._renderFurniturePlacementPreview(a)??G}${this._editorRuntime?._renderDecorImagePlacementPreview()??G}`}get _editorToolbarGroups(){return"plan"!==this._mode?[]:[{id:"opening",label:this._t("markup.opening"),icon:"mdi:door",activeItemId:"opening"===this._tool?this._openingPreset?.type:void 0,items:[{id:"window",label:this._t("opening.window"),icon:"mdi:window-closed-variant",role:"tool",invoke:()=>this._activateOpeningPlacement("window")},{id:"door",label:this._t("opening.door"),icon:"mdi:door-open",role:"tool",invoke:()=>this._activateOpeningPlacement("door")},{id:"passage",label:this._t("opening.passage"),icon:"mdi:arch",role:"tool",invoke:()=>this._activateOpeningPlacement("passage")},{id:"gate",label:this._t("opening.gate"),icon:"mdi:gate",role:"tool",invoke:()=>this._activateOpeningPlacement("gate")}]}]}_renderEditorGroupLauncher(e){return this._editorRuntimeOrThrow()._renderEditorGroupLauncher(e)}get _editorSecondaryContextId(){const e=`editor:${this._mode}:${this._space}:${this._cfgEpoch}`,t=this._editorSecondary?.activeGroup(this._editorToolbarGroups);if(t)return`${e}:group:${t.id}:${this._editorSecondary?.groupGeneration}`;if("plan"===this._mode){const t=this._physicalSel;return t?`${e}:selection:${t.kind}:${t.id}`:`${e}:tool:${this._tool}:${this._path.length}`}return"decor"===this._mode?"furniture"===this._decorTool?`${e}:palette:furniture:${this._furnPalette?.symbol||"none"}`:"image"===this._decorTool?`${e}:palette:image:${this._decorImagePalette?.asset_id||"none"}`:"select"===this._decorTool&&this._decorSel?`${e}:selection:decor:${this._decorSel}`:`${e}:tool:${this._decorTool}:${this._bdMoved?1:0}:${this._bdDrag?1:0}`:`${e}:none`}_runEditorContext(e,t){return this._editorRuntimeOrThrow()._runEditorContext(e,t)}_renderEditorGroupModel(e){return this._editorRuntimeOrThrow()._renderEditorGroupModel(e)}_renderDrawWallControl(){return this._editorRuntimeOrThrow()._renderDrawWallControl()}_renderPlanSecondary(){return this._editorRuntimeOrThrow()._renderPlanSecondary()}_renderDecorSecondary(){return this._editorRuntimeOrThrow()._renderDecorSecondary()}_withBackdropReset(e){return this._editorRuntimeOrThrow()._withBackdropReset(e)}get _editorSecondaryDialogBlocked(){return!!(this._dangerConfirm||this._tapConfirm||this._vacCalConfirm||this._roomDialog||this._mergeDialog||this._openingDialog||this._physicalDialog||this._openingInfo||this._decorTextDialog||this._decorShapeDialog||this._backdropDialog||this._decorEraseConfirm||this._spaceDialog||this._markerDialog||this._deviceInbox||this._infoCard||this._rulesDialog||this._settingsDialog||this._supportDialog||this._alignDialog||this._importDialog||this._kioskDialog||this._summary?.blocksOtherDialogs()||this._backupExportDialog||this._backupImportDialog||this._wallDialog)}_renderEditorSecondary(){return this._editorRuntimeOrThrow()._renderEditorSecondary()}_renderDecorBar(){return this._editorRuntimeOrThrow()._renderDecorBar()}_renderDecorEraseConfirm(){return this._editorRuntimeOrThrow()._renderDecorEraseConfirm()}_renderDecorTextDialog(){return this._editorRuntimeOrThrow()._renderDecorTextDialog()}_renderDecorShapeDialog(){return this._editorRuntimeOrThrow()._renderDecorShapeDialog()}_renderBackdropDialog(){return this._editorRuntimeOrThrow()._renderBackdropDialog()}_cssPxToRender(e){return this._editorRuntimeOrThrow()._cssPxToRender(e)}_renderZeroWalls(e){if(e&&!e.showBorders&&!this._editing)return W``;const t=this._zeroWalls();if(!t.lines.length)return W``;const i=e?.color||"var(--hp-muted)";return W` ${t.lines.map(e=>W``)} - `}_zeroWalls(){const e=this._spaceModel();return e?E_(this._curSpaceCfg,e,uv,.02*this._gridPitch):{style:F_(this._curSpaceCfg),lines:[],contour:[],barriers:[],transmissive:[]}}_openCuts(){return this._zeroWalls().contour}_deleteRoomClick(e){return this._editorRuntimeOrThrow()._deleteRoomClick(e)}get _wallKeyPitch(){return el}get _spaceWalls(){const e=this._curSpaceCfg?.walls;return Array.isArray(e)?e:[]}_intervalCm(e){const t=this._spaceModel();return t?Ps(t.rooms,this._spaceWalls,this._openCuts(),e,this._wallKeyPitch,this._cellCm,this._gridPitch,uv):0}_normalizeWalls(e,t){const i=this._spaceModel();if(!i)return[];return Uo(As(i.rooms,e,t,this._wallKeyPitch,this._cellCm,this._gridPitch,uv),this._curSpaceCfg?.rooms||[],el,1,t.map(e=>[e[0]/uv,e[1]/uv,e[2]/uv,e[3]/uv]))}_paperShapes(e){if(!this._spaceWalls.length)return ri(e);const t=this._wallUnionGeometry();return t?.paperD?[{path:t.paperD}]:ri(e)}_wallUnionGeometry(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._physicalBodiesR();if(!t.length&&!i.length)return null;const n=`${this._space}|${this._cfgEpoch}|${e.rooms.length}`;if(!this._wallUnionCache||this._wallUnionCache.key!==n){const r=xf(this._wallUnionPool,n);if(r.hit)this._wallUnionCache=r.value;else{const r=this._openCuts(),o=this._roomWallOpeningInputs(),s=Js(e.rooms,t,r,o,this._wallKeyPitch,this._cellCm,this._gridPitch,uv,i);s&&Object.defineProperty(s,"sourceFingerprint",{value:ac([this._curSpaceCfg,this._cellCm,this._gridPitch]),enumerable:!1});const a={key:n,value:s};Sf(this._wallUnionPool,n,a,8),this._wallUnionCache=a}}return this._wallUnionCache.value}_thickWallCuts(){const e=this._spaceModel();if(!e)return[];const t=this._spaceWalls;if(!t.length)return[];const i=this._openCuts();return ea(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,uv).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]])}_innerRoomContour(e,t,i=this._openCuts(),n=this._wallUnionGeometry()?.roomGeom,r=this._wallUnionGeometry()?.multiWallNodes){const o=i.map(e=>e.join(",")).join(";"),s=`${e.id}|${this._cfgEpoch}|${t}|${o}`,a=xf(this._innerContourCache,s);if(a.hit)return a.value;const l=Is(e.rooms,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,uv,n,r);return Sf(this._innerContourCache,s,l,600),l}_wallThickHit(e){return this._editorRuntimeOrThrow()._wallThickHit(e)}get _wallThickHover(){if(!this._markup||"wallthick"!==this._tool||!this._cursorPt||this._wallDialog)return null;const e=this._wallThickHit(this._cursorPt);if(!e)return null;const t=function(e,t,i){const n=Number.isFinite(e)&&e>0?e:0,r=Number.isFinite(t)&&t>0?t:5,o=Number.isFinite(i)&&i>0?i:0;return n>0?Ao(n,r,o)/2:Ha(1.5*o,r)}(e.cm,this._cellCm,this._gridPitch);let i="";for(const n of e.segs)i+=(i?" ":"")+as([[n[0],n[1]],[n[2],n[3]]],t,!1);return{segs:e.segs,open:e.open,d:i}}_wallThickClick(e){return this._editorRuntimeOrThrow()._wallThickClick(e)}_wallThickApply(e){return this._editorRuntimeOrThrow()._wallThickApply(e)}_wallHatchDefs(e){const t=Ro(this._cellCm);return W` + `}_zeroWalls(){const e=this._spaceModel();return e?N_(this._curSpaceCfg,e,pv,.02*this._gridPitch):{style:z_(this._curSpaceCfg),lines:[],contour:[],barriers:[],transmissive:[]}}_openCuts(){return this._zeroWalls().contour}_deleteRoomClick(e){return this._editorRuntimeOrThrow()._deleteRoomClick(e)}get _wallKeyPitch(){return tl}get _spaceWalls(){const e=this._curSpaceCfg?.walls;return Array.isArray(e)?e:[]}_intervalCm(e){const t=this._spaceModel();return t?Fs(t.rooms,this._spaceWalls,this._openCuts(),e,this._wallKeyPitch,this._cellCm,this._gridPitch,pv):0}_normalizeWalls(e,t){const i=this._spaceModel();if(!i)return[];return Go(Ps(i.rooms,e,t,this._wallKeyPitch,this._cellCm,this._gridPitch,pv),this._curSpaceCfg?.rooms||[],tl,1,t.map(e=>[e[0]/pv,e[1]/pv,e[2]/pv,e[3]/pv]))}_paperShapes(e){if(!this._spaceWalls.length)return ri(e);const t=this._wallUnionGeometry();return t?.paperD?[{path:t.paperD}]:ri(e)}_wallUnionGeometry(){const e=this._spaceModel();if(!e)return null;const t=this._spaceWalls,i=this._physicalBodiesR();if(!t.length&&!i.length)return null;const n=`${this._space}|${this._cfgEpoch}|${e.rooms.length}`;if(!this._wallUnionCache||this._wallUnionCache.key!==n){const r=Sf(this._wallUnionPool,n);if(r.hit)this._wallUnionCache=r.value;else{const r=this._openCuts(),o=this._roomWallOpeningInputs(),s=Qs(e.rooms,t,r,o,this._wallKeyPitch,this._cellCm,this._gridPitch,pv,i);s&&Object.defineProperty(s,"sourceFingerprint",{value:lc([this._curSpaceCfg,this._cellCm,this._gridPitch]),enumerable:!1});const a={key:n,value:s};$f(this._wallUnionPool,n,a,8),this._wallUnionCache=a}}return this._wallUnionCache.value}_thickWallCuts(){const e=this._spaceModel();if(!e)return[];const t=this._spaceWalls;if(!t.length)return[];const i=this._openCuts();return ta(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,pv).map(e=>[e.a[0],e.a[1],e.b[0],e.b[1]])}_innerRoomContour(e,t,i=this._openCuts(),n=this._wallUnionGeometry()?.roomGeom,r=this._wallUnionGeometry()?.multiWallNodes){const o=i.map(e=>e.join(",")).join(";"),s=`${e.id}|${this._cfgEpoch}|${t}|${o}`,a=Sf(this._innerContourCache,s);if(a.hit)return a.value;const l=Os(e.rooms,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,pv,n,r);return $f(this._innerContourCache,s,l,600),l}_wallThickHit(e){return this._editorRuntimeOrThrow()._wallThickHit(e)}get _wallThickHover(){if(!this._markup||"wallthick"!==this._tool||!this._cursorPt||this._wallDialog)return null;const e=this._wallThickHit(this._cursorPt);if(!e)return null;const t=function(e,t,i){const n=Number.isFinite(e)&&e>0?e:0,r=Number.isFinite(t)&&t>0?t:5,o=Number.isFinite(i)&&i>0?i:0;return n>0?Po(n,r,o)/2:La(1.5*o,r)}(e.cm,this._cellCm,this._gridPitch);let i="";for(const n of e.segs)i+=(i?" ":"")+ls([[n[0],n[1]],[n[2],n[3]]],t,!1);return{segs:e.segs,open:e.open,d:i}}_wallThickClick(e){return this._editorRuntimeOrThrow()._wallThickClick(e)}_wallThickApply(e){return this._editorRuntimeOrThrow()._wallThickApply(e)}_wallHatchDefs(e){const t=Co(this._cellCm);return W` - `}_resolvedRoomFills(e,t){const i=new Map,n=new Map;for(const r of e.rooms){const e=this._roomDialog&&r.id===this._roomEditId?this._roomFill||t.fill:Nn(t.fill,r),o=this._roomDialog&&r.id===this._roomEditId?this._roomCustomFill||t.customFill:hn(t.customFill,r),s=Rc(t.tempMin,t.tempMax,r,this._roomTempMin,this._roomTempMax,this._roomDialog&&r.id===this._roomEditId),a=vn(e,"lqi"===e&&r.area?this._roomLqi(r.area):null,"light"===e?Ed(Id(this._renderPlanHass,this._renderDevices,r,this._virtualLights)):"none","temp"===e?this._roomTemp(r):null,s.min,s.max,this._fillColors,o);i.set(r,a),r.id&&n.set(r.id,a)}return{byRoom:i,byId:n}}_spaceDisplayForRender(){const e=un(this._curSpaceCfg),t=this._spaceDialog;return t&&"edit"===t.mode&&t.spaceId===this._space?{...e,showBorders:t.showBorders,showNames:t.showNames,hideDecor:t.hideDecor,hideOpenings:t.hideOpenings,color:t.roomColor,opacity:t.roomOpacity,fill:t.fillMode,customFill:t.customFill?cn(t.customFill):ln,glow:t.glowEnabled,tempMin:t.tempMin,tempMax:t.tempMax,showLqi:t.showLqi,cardFontScale:t.cardFontScale,labelTemp:t.labelTemp,labelHum:t.labelHum,labelLqi:t.labelLqi,labelLight:t.labelLight}:e}_openingWallIndexFor(e,t){const i=e.rooms.map(e=>`${e.id}:${e.poly?.map(e=>e.join(",")).join("/")||`${e.x},${e.y},${e.w},${e.h}`}`).join(";"),n=this._spaceWalls.map(e=>`${e.key}:${e.a?.join(",")||""}:${e.b?.join(",")||""}:${e.cm}`).join(";"),r=t.map(e=>e.join(",")).join(";"),o=[e.id,this._cfgEpoch,this._wallKeyPitch,this._cellCm,this._gridPitch,i,n,r].join("|");let s=this._openingWallIndexCache.get(o);return s||(s=na(e.rooms,this._spaceWalls,t,this._wallKeyPitch,this._cellCm,this._gridPitch,uv)),Sf(this._openingWallIndexCache,o,s,4),{key:o,value:s}}_renderOpeningTunnelFills(e,t,i="data"){if(this._markup||!this._spaceWalls.length||!this._openingsR.length)return W``;if("glow-base"===i&&![...t.byRoom.values()].some(Boolean))return W``;const n=this._openCuts(),r=this._openingsR.map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=r.map(e=>`${e.x},${e.y},${e.angle},${e.length}`).join(";"),s=this._openingWallIndexFor(e,n),a=`${s.key}|${o}`;return this._openingTunnelCache&&this._openingTunnelCache.key===a||(this._openingTunnelCache={key:a,value:da(s.value,r)}),k_({openings:this._openingsR,geometries:this._openingTunnelCache.value,fillsByRoomId:t.byId,idPrefix:`${e.id}-${i}`,groupClass:"data"===i?"opening-tunnels":"opening-tunnels glow-base-tunnels",dataLayer:i})}_resolvedGlowBase(e,t,i){const n=new Map,r=new Map,o=this._fillColors.glow_base;for(const s of e.rooms){const e=i.byRoom.get(s),a=Hn(t.glow,s)&&(!e||e.opacity<=0)?{color:o.c,opacity:o.a,mode:"glow"}:null;n.set(s,a),s.id&&r.set(s.id,a)}return{byRoom:n,byId:r}}_renderGlowBaseRooms(e,t){if(this._markup||![...t.byRoom.values()].some(Boolean))return W``;const i=new Map(e.rooms.map(e=>[e,ni(e)])),n=this._openCuts(),r=this._wallUnionGeometry()?.roomGeom,o=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z",s=e.rooms.map(s=>{const a=t.byRoom.get(s)||null,l=i.get(s)||null;if(!a||!l)return G;const c=this._spaceWalls.length&&s.id&&this._innerRoomContour(e,s.id,n,r)||l,h=Ri(c,e.rooms.filter(e=>e!==s).map(e=>i.get(e)).filter(e=>!!e)),d=this._cleanFloor(s,c,e).path;return d||h.length?W``}_resolvedRoomFills(e,t){const i=new Map,n=new Map;for(const r of e.rooms){const e=this._roomDialog&&r.id===this._roomEditId?this._roomFill||t.fill:Nn(t.fill,r),o=this._roomDialog&&r.id===this._roomEditId?this._roomCustomFill||t.customFill:hn(t.customFill,r),s=Cc(t.tempMin,t.tempMax,r,this._roomTempMin,this._roomTempMax,this._roomDialog&&r.id===this._roomEditId),a=vn(e,"lqi"===e&&r.area?this._roomLqi(r.area):null,"light"===e?Nd(Od(this._renderPlanHass,this._renderDevices,r,this._virtualLights)):"none","temp"===e?this._roomTemp(r):null,s.min,s.max,this._fillColors,o);i.set(r,a),r.id&&n.set(r.id,a)}return{byRoom:i,byId:n}}_spaceDisplayForRender(){const e=un(this._curSpaceCfg),t=this._spaceDialog;return t&&"edit"===t.mode&&t.spaceId===this._space?{...e,showBorders:t.showBorders,showNames:t.showNames,hideDecor:t.hideDecor,hideOpenings:t.hideOpenings,color:t.roomColor,opacity:t.roomOpacity,fill:t.fillMode,customFill:t.customFill?cn(t.customFill):ln,glow:t.glowEnabled,tempMin:t.tempMin,tempMax:t.tempMax,showLqi:t.showLqi,cardFontScale:t.cardFontScale,labelTemp:t.labelTemp,labelHum:t.labelHum,labelLqi:t.labelLqi,labelLight:t.labelLight}:e}_openingWallIndexFor(e,t){const i=e.rooms.map(e=>`${e.id}:${e.poly?.map(e=>e.join(",")).join("/")||`${e.x},${e.y},${e.w},${e.h}`}`).join(";"),n=this._spaceWalls.map(e=>`${e.key}:${e.a?.join(",")||""}:${e.b?.join(",")||""}:${e.cm}`).join(";"),r=t.map(e=>e.join(",")).join(";"),o=[e.id,this._cfgEpoch,this._wallKeyPitch,this._cellCm,this._gridPitch,i,n,r].join("|");let s=this._openingWallIndexCache.get(o);return s||(s=ra(e.rooms,this._spaceWalls,t,this._wallKeyPitch,this._cellCm,this._gridPitch,pv)),$f(this._openingWallIndexCache,o,s,4),{key:o,value:s}}_renderOpeningTunnelFills(e,t,i="data"){if(this._markup||!this._spaceWalls.length||!this._openingsR.length)return W``;if("glow-base"===i&&![...t.byRoom.values()].some(Boolean))return W``;const n=this._openCuts(),r=this._openingsR.map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=r.map(e=>`${e.x},${e.y},${e.angle},${e.length}`).join(";"),s=this._openingWallIndexFor(e,n),a=`${s.key}|${o}`;return this._openingTunnelCache&&this._openingTunnelCache.key===a||(this._openingTunnelCache={key:a,value:ua(s.value,r)}),x_({openings:this._openingsR,geometries:this._openingTunnelCache.value,fillsByRoomId:t.byId,idPrefix:`${e.id}-${i}`,groupClass:"data"===i?"opening-tunnels":"opening-tunnels glow-base-tunnels",dataLayer:i})}_resolvedGlowBase(e,t,i){const n=new Map,r=new Map,o=this._fillColors.glow_base;for(const s of e.rooms){const e=i.byRoom.get(s),a=Hn(t.glow,s)&&(!e||e.opacity<=0)?{color:o.c,opacity:o.a,mode:"glow"}:null;n.set(s,a),s.id&&r.set(s.id,a)}return{byRoom:n,byId:r}}_renderGlowBaseRooms(e,t){if(this._markup||![...t.byRoom.values()].some(Boolean))return W``;const i=new Map(e.rooms.map(e=>[e,ni(e)])),n=this._openCuts(),r=this._wallUnionGeometry()?.roomGeom,o=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z",s=e.rooms.map(s=>{const a=t.byRoom.get(s)||null,l=i.get(s)||null;if(!a||!l)return G;const c=this._spaceWalls.length&&s.id&&this._innerRoomContour(e,s.id,n,r)||l,h=Ri(c,e.rooms.filter(e=>e!==s).map(e=>i.get(e)).filter(e=>!!e)),d=this._cleanFloor(s,c,e).path;return d||h.length?W``:s.poly||c!==l?W``:W``});return W``}_renderWallBodies(e){if("iso"===this._renderProjection)return W``;if(e&&!e.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const t=this._wallUnionGeometry();if(!t)return W``;const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i&&i.clientWidth&&n.w?i.clientWidth/n.w:1,o=e?.color||"#607d8b",s=Mo(t.depthUnits,r)||Co(Ro(this._cellCm),r),a=this._fillColors.wall_fill;return W` + fill=${a.color} fill-opacity=${a.opacity} pointer-events="none">`});return W``}_renderWallBodies(e){if("iso"===this._renderProjection)return W``;if(e&&!e.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const t=this._wallUnionGeometry();if(!t)return W``;const i=this._stageEl,n=this._viewOr(this._baseVb()),r=i&&i.clientWidth&&n.w?i.clientWidth/n.w:1,o=e?.color||"#607d8b",s=Ro(t.depthUnits,r)||To(Co(this._cellCm),r),a=this._fillColors.wall_fill;return W` ${t.paths.map(e=>W` `)} - `}_roomHoverPaths(e){const t=this._hoverRoom;if("view"!==this._mode||!t||t.space!==e.id)return null;const i=e.rooms.find(e=>e===t.room||!!e.id&&e.id===t.room.id);if(!i)return null;const n=ni(i);if(!n)return null;const r=e.rooms.filter(e=>e!==i).map(e=>({room:e,poly:ni(e)})).filter(e=>!!e.poly),o=Ri(n,r.map(e=>e.poly)),s=this._openCuts(),a=.02*this._gridPitch,l=s.filter(e=>{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return n.some((e,i)=>Un(t,[e[0],e[1],...n[(i+1)%n.length]])<=4*a)}),c=this._spaceWalls,h=this._wallUnionGeometry()?.roomGeom,d=c.length&&i.id&&this._innerRoomContour(e,i.id,s,h)||n,u=[{axis:n,face:d}];for(const t of o){const i=r.find(e=>e.poly===t)?.room;let n=t;if(c.length&&i?.id){const r=Cs(e.rooms,i.id,c,s,this._wallKeyPitch,this._cellCm,this._gridPitch,uv);r&&(n=ia(r.poly,r.offsets)||t)}u.push({axis:t,face:n})}const p=this._roomWallOpeningInputs(this._openingsR,e).map(e=>{const t=e.angle*Math.PI/180,i=Math.cos(t)*e.length/2,n=Math.sin(t)*e.length/2;return[e.x-i,e.y-n,e.x+i,e.y+n]}),_=l.concat(p),m=u.map(({axis:e,face:t})=>{const i=_.map(i=>((e,t,i)=>{const n=e[2]-e[0],r=e[3]-e[1],o=Math.hypot(n,r);if(o.05)&&Un([c,h],[i[0],i[1],n[0],n[1]])<=4*a){d=!0;break}}if(!d)return null;let u=null;for(let e=0;e.05)continue;const p=Un([c,h],[t[0],t[1],n[0],n[1]]);(!u||p!!e);return i.length?Fn(t,i,a).map(e=>`M ${e[0]} ${e[1]} L ${e[2]} ${e[3]}`).join(" "):`M ${t.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`}).filter(Boolean).join(" ");if(!m)return null;const g=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`;return{fillD:[this._cleanFloor(i,d,e).path||g(d),...o.map(g)].join(" "),outlineD:m}}_renderRoomHoverFill(e){return W` + `}_roomHoverPaths(e){const t=this._hoverRoom;if("view"!==this._mode||!t||t.space!==e.id)return null;const i=e.rooms.find(e=>e===t.room||!!e.id&&e.id===t.room.id);if(!i)return null;const n=ni(i);if(!n)return null;const r=e.rooms.filter(e=>e!==i).map(e=>({room:e,poly:ni(e)})).filter(e=>!!e.poly),o=Ri(n,r.map(e=>e.poly)),s=this._openCuts(),a=.02*this._gridPitch,l=s.filter(e=>{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return n.some((e,i)=>Un(t,[e[0],e[1],...n[(i+1)%n.length]])<=4*a)}),c=this._spaceWalls,h=this._wallUnionGeometry()?.roomGeom,d=c.length&&i.id&&this._innerRoomContour(e,i.id,s,h)||n,u=[{axis:n,face:d}];for(const t of o){const i=r.find(e=>e.poly===t)?.room;let n=t;if(c.length&&i?.id){const r=Ts(e.rooms,i.id,c,s,this._wallKeyPitch,this._cellCm,this._gridPitch,pv);r&&(n=na(r.poly,r.offsets)||t)}u.push({axis:t,face:n})}const p=this._roomWallOpeningInputs(this._openingsR,e).map(e=>{const t=e.angle*Math.PI/180,i=Math.cos(t)*e.length/2,n=Math.sin(t)*e.length/2;return[e.x-i,e.y-n,e.x+i,e.y+n]}),_=l.concat(p),m=u.map(({axis:e,face:t})=>{const i=_.map(i=>((e,t,i)=>{const n=e[2]-e[0],r=e[3]-e[1],o=Math.hypot(n,r);if(o.05)&&Un([c,h],[i[0],i[1],n[0],n[1]])<=4*a){d=!0;break}}if(!d)return null;let u=null;for(let e=0;e.05)continue;const p=Un([c,h],[t[0],t[1],n[0],n[1]]);(!u||p!!e);return i.length?Fn(t,i,a).map(e=>`M ${e[0]} ${e[1]} L ${e[2]} ${e[3]}`).join(" "):`M ${t.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`}).filter(Boolean).join(" ");if(!m)return null;const g=e=>`M ${e.map(e=>`${e[0]} ${e[1]}`).join(" L ")} Z`;return{fillD:[this._cleanFloor(i,d,e).path||g(d),...o.map(g)].join(" "),outlineD:m}}_renderRoomHoverFill(e){return W` `}_renderRoomHoverOutline(e){return W` @@ -473,23 +473,23 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 d="${e?.outlineD||""}" ?hidden=${!e}> - `}_renderWallThickUi(){return this._editorRuntime?this._editorRuntimeOrThrow()._renderWallThickUi():W``}_renderWallThickDialog(){return this._editorRuntimeOrThrow()._renderWallThickDialog()}_openingAt(e){return this._editorRuntimeOrThrow()._openingAt(e)}_resolveOpeningPlacement(e){return this._editorRuntimeOrThrow()._resolveOpeningPlacement(e)}_activateOpeningPlacement(e){return this._editorRuntimeOrThrow()._activateOpeningPlacement(e)}_clearOpeningPlacement(e){return this._editorRuntime?this._editorRuntimeOrThrow()._clearOpeningPlacement(e):(this._openingHoverCandidate=null,this._openingJambBlockCm=null,void(e&&(this._openingPreset=null,this._openingRebindId=null)))}_openingClick(e){return this._editorRuntimeOrThrow()._openingClick(e)}_editOpening(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._editOpening(e)}_opPointerDown(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerDown(e,t)}_opPointerMove(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerMove(e,t)}_opRuler(e,t){return this._editorRuntimeOrThrow()._opRuler(e,t)}_opPointerUp(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerUp(e,t)}_opClick(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opClick(e,t)}_saveOpening(){return this._editorRuntimeOrThrow()._saveOpening()}_deleteOpening(){return this._editorRuntimeOrThrow()._deleteOpening()}_contactCandidates(){return this._editorRuntimeOrThrow()._contactCandidates()}_lockCandidates(){return this._editorRuntimeOrThrow()._lockCandidates()}_toggleOpeningEntityPicker(e){return this._editorRuntimeOrThrow()._toggleOpeningEntityPicker(e)}_filterOpeningEntities(e,t){return this._editorRuntimeOrThrow()._filterOpeningEntities(e,t)}_selectOpeningEntity(e,t){return this._editorRuntimeOrThrow()._selectOpeningEntity(e,t)}_mergeClick(e){return this._editorRuntimeOrThrow()._mergeClick(e)}_commitMerge(){return this._editorRuntimeOrThrow()._commitMerge()}_splitClick(e){return this._editorRuntimeOrThrow()._splitClick(e)}get _contourClosed(){return this._path.length>=4&&this._samePt(this._path[0],this._path[this._path.length-1])&&(null!=this._closingWallCm||!this._activeWallChainId)}_markupMove(e){this._markup&&this._editorRuntime&&this._editorRuntimeOrThrow()._queuePointerMove("markup-hover",()=>this._editorRuntime._markupMove(e))}get _openingPreview(){const e=this._openingPreset;if("opening"!==this._tool||!e||!this._cursorPt)return null;const t=this._cursorPt,i=this._openingHoverCandidate;if(i&&Kf(i,[t[0],t[1]],e.revision,this._cfgEpoch))return i;if(this._openingAt(t))return this._openingHoverCandidate=null,null;const n=this._resolveOpeningPlacement(t);return this._openingHoverCandidate=n,n}get _opMeasureView(){return this._opMeasure||this._openingPreview?.measure||null}_saveRoom(){return this._editorRuntimeOrThrow()._saveRoom()}_decideWallFace(e){return this._editorRuntimeOrThrow()._decideWallFace(e)}_wallSourceCmAt(e,t,i){return this._editorRuntimeOrThrow()._wallSourceCmAt(e,t,i)}_activePathWithRepair(e,t){return this._editorRuntimeOrThrow()._activePathWithRepair(e,t)}_validateWallRepair(e,t){return this._editorRuntimeOrThrow()._validateWallRepair(e,t)}_applyWallRepair(e,t){return this._editorRuntimeOrThrow()._applyWallRepair(e,t)}_applyWallFaceBatch(){return this._editorRuntimeOrThrow()._applyWallFaceBatch()}_commitRoom(){return this._editorRuntimeOrThrow()._commitRoom()}_cancelPath(){return this._editorRuntimeOrThrow()._cancelPath()}_roomDialogCancel(){return this._editorRuntimeOrThrow()._roomDialogCancel()}get _freeAreas(){const e=new Set;for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area&&e.add(i.area);for(const t of this._wallFaceBatch?.decisions||[])t.create&&t.area&&e.add(t.area);return Object.values(this.hass?.areas||{}).filter(t=>!e.has(t.area_id)).sort((e,t)=>(e.name||"").localeCompare(t.name||""))}_openDeviceInbox(){return this._editorRuntimeOrThrow()._openDeviceInbox()}_closeMarkerDialog(){return this._editorRuntimeOrThrow()._closeMarkerDialog()}_deviceInboxCandidates(e){return this._editorRuntimeOrThrow()._deviceInboxCandidates(e)}_deviceInboxRows(){return this._editorRuntimeOrThrow()._deviceInboxRows()}_deviceForInboxRow(e){return this._editorRuntimeOrThrow()._deviceForInboxRow(e)}_openInboxMarker(e,t=!1){return this._editorRuntimeOrThrow()._openInboxMarker(e,t)}async _setInboxHidden(e,t){return this._editorRuntimeOrThrow()._setInboxHidden(e,t)}_findInboxDevice(e){return this._editorRuntimeOrThrow()._findInboxDevice(e)}_deviceInboxTabKey(e){return this._editorRuntimeOrThrow()._deviceInboxTabKey(e)}_openMarkerDialog(e){if(this._editorRuntime)return this._editorRuntime._openMarkerDialog(e);this._ensureEditorRuntime().then(t=>{t&&this._openMarkerDialog(e)})}_runCandidates(){return this._editorRuntimeOrThrow()._runCandidates()}_bindingCandidates(){return this._editorRuntimeOrThrow()._bindingCandidates()}_physicalBodiesR(e=this._spaceModel()){if(!e)return[];const t=`${e.id}|${this._cfgEpoch}|${this._cellCm}|${this._gridPitch}`;if(this._physicalBodiesCache?.key===t)return this._physicalBodiesCache.all;const i=$a(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e));return this._physicalBodiesCache={key:t,...i},i.all}_rawPhysicalBodiesR(e=this._spaceModel()){if(!e)return[];this._physicalBodiesR(e);const t=this._physicalBodiesCache;return t?[...t.partitions,...t.columns]:[]}_cleanFloor(e,t,i=this._spaceModel()){if(!i)return{floor:t,geom:null,path:"",area:Aa([[[...t,t[0]]]])};const n=e.id||`#${i.rooms.indexOf(e)}`,r=`${i.id}|${this._cfgEpoch}|${n}`;if(!this._resize?.preview){const e=xf(this._cleanFloorCache,r);if(e.hit)return e.value}const o=t.map(e=>e[0]),s=t.map(e=>e[1]),a=[Math.min(...o),Math.min(...s),Math.max(...o),Math.max(...s)],l=this._physicalBodiesR(i).filter(e=>{const t=e.map(e=>e[0]),i=e.map(e=>e[1]);return Math.max(...t)>=a[0]&&Math.min(...t)<=a[2]&&Math.max(...i)>=a[1]&&Math.min(...i)<=a[3]}),c=l.length?Da(t,l):null,h={floor:t,geom:c,path:c?ya(c):"",area:Aa(c||[[[...t,t[0]]]])};return this._resize?.preview||Sf(this._cleanFloorCache,r,h,600),h}_autoIconForBinding(e){if("virtual"===e)return"mdi:map-marker";const[t,i]=e.split(":");if(!i)return"";const n=this._fullRegistryHass,r=this._bindingStatus(e),o="active"===r.kind?r.enabledEntityIds:r.allEntityIds;if("device"===t){const e=n.devices?.[i];if(!e)return"mdi:help-circle";const t=o;return t.some(e=>e.startsWith("lock."))?"mdi:lock":Wd(n,e.name_by_user||e.name||"",e.model,t,this._iconRules)}if("entity"===t){const e=n.entities?.[i],t=this.hass.states?.[i],r=e?.name||t?.attributes?.friendly_name||i;return i.startsWith("lock.")?"mdi:lock":Wd(n,r,"",[i],this._iconRules)}return""}_allRoomsFlat(){const e=[];for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area?e.push({value:t.id+"#"+i.area,label:(t.title||t.id)+" · "+i.name}):i.id&&e.push({value:t.id+"#@"+i.id,label:(t.title||t.id)+" · "+i.name+" · "+this._t("marker.subarea")});return e}_errText(e){if(!e)return this._t("err.unknown");if("string"==typeof e)return e;if("invalid_passage_fields"===e.code){const t=String(e.message||e.error||"");let i="",n=[];try{const e=JSON.parse(t);i=String(e.space??""),n=Array.isArray(e.fields)?e.fields.map(String):[]}catch{const e=t.match(/space=([^;]*);\s*opening=([^;]*);\s*fields=([^;]*)/);e&&(i=e[1],n=e[3].split(",").filter(Boolean))}if(i||n.length){const e=this._serverCfg?.spaces?.find(e=>String(e.id)===i),t={contact:"opening.contact_label",lock:"opening.lock_label",invert:"opening.invert",flip_h:"opening.flip_h",flip_v:"opening.flip_v"},r=n.map(e=>t[e]?this._t(t[e]):e).join(", ");return this._t("opening.invalid_passage_fields",{room:e?.title||i,fields:r})}}if("invalid_partition_opening_jamb_margin"===e.code){const t=String(e.message||e.error||"");let i=NaN;try{i=Number(JSON.parse(t).margin_cm)}catch{const e=t.match(/margin_cm=([^;}"]*)/);i=e?Number(e[1]):NaN}if(Number.isFinite(i))return this._t("opening.partition_jamb_margin",{distance:ti(i,this._imperial)})}if(null!=e.code){const t=`backup.error.${e.code}`,i=this._t(t);return e.message&&console.warn("[houseplan] backend error",e.code,e.message),i!==t?i:this._t("err.code",{code:e.code})}if(e.message)return e.message;if(e.error)return e.error;try{return JSON.stringify(e)}catch{return String(e)}}_backupErrorText(e){return this._editorRuntimeOrThrow()._backupErrorText(e)}async _pickMarkerFiles(e){return this._editorRuntimeOrThrow()._pickMarkerFiles(e)}_removeMarkerPdf(e){return this._editorRuntimeOrThrow()._removeMarkerPdf(e)}_markerLightFields(e){return this._editorRuntimeOrThrow()._markerLightFields(e)}_markerTapActionFields(e){return this._editorRuntimeOrThrow()._markerTapActionFields(e)}_markerToggleEntityFields(e){return this._editorRuntimeOrThrow()._markerToggleEntityFields(e)}async _saveMarker(){return this._editorRuntimeOrThrow()._saveMarker()}async _deleteMarker(){return this._editorRuntimeOrThrow()._deleteMarker()}_normPos(e,t,i){return{s:e,x:t/uv,y:i/uv}}_spaceDialogUsesOnboardingRuntime(e){return"create"===e&&!this._editorRuntime&&(!!this._onboardingRuntime||0===(this._serverCfg?.spaces.length||0)||this._importTotal>0||this._importQueue.length>0)}_spaceRuntimeOrThrow(){if(!this._onboardingRuntime)throw new Error("Houseplan onboarding runtime is not loaded");return this._onboardingRuntime}_openSpaceDialog(e,t){return this._spaceDialogUsesOnboardingRuntime(e)?this._onboardingRuntime?void this._onboardingRuntime._openSpaceDialog(e,t):void this._ensureOnboardingRuntime().then(i=>{i&&this._spaceRuntimeOrThrow()._openSpaceDialog(e,t)}):this._editorRuntime?this._editorRuntime._openSpaceDialog(e,t):void this._ensureEditorRuntime().then(i=>{i&&this._openSpaceDialog(e,t)})}async _pickPlanFile(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._pickPlanFile(e):this._editorRuntimeOrThrow()._pickPlanFile(e)}_useServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._useServerPlan(e):this._editorRuntimeOrThrow()._useServerPlan(e)}async _readPlanAspect(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._readPlanAspect(e):this._editorRuntimeOrThrow()._readPlanAspect(e)}async _deleteServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._deleteServerPlan(e):this._editorRuntimeOrThrow()._deleteServerPlan(e)}_renderServerPlans(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime(e.mode)?this._onboardingRuntime._renderServerPlans(e):this._editorRuntimeOrThrow()._renderServerPlans(e)}async _saveSpaceDialog(){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._saveSpaceDialog():this._editorRuntimeOrThrow()._saveSpaceDialog()}async _deleteSpace(){return this._editorRuntimeOrThrow()._deleteSpace()}async _saveConfigNow(){return this._editorRuntimeOrThrow()._saveConfigNow()}_startImport(){return this._onboardingRuntime?this._onboardingRuntime._startImport():this._editorRuntimeOrThrow()._startImport()}_openNextImport(){return this._onboardingRuntime?this._onboardingRuntime._openNextImport():this._editorRuntimeOrThrow()._openNextImport()}_skipImport(){return this._onboardingRuntime?this._onboardingRuntime._skipImport():this._editorRuntimeOrThrow()._skipImport()}_renderImportDialog(){return this._onboardingRuntime?this._onboardingRuntime._renderImportDialog():this._editorRuntimeOrThrow()._renderImportDialog()}_sunGlobal(){const e=this._settingsDialog;return e?{...this._settings,north_deg:e.northDeg??void 0,bg_mode:e.bgMode,sun_rays:e.sunRays}:this._settings}_sunSpace(){const e=this._spaceDialog,t=this._curSpaceCfg?.settings||{};return e&&"edit"===e.mode&&e.spaceId===this._space?{...t,north_deg:e.northDeg??void 0,bg_mode:e.bgMode??void 0,sun_rays:e.sunRays??void 0}:t}_effNorth(){return gr(this._sunGlobal(),this._sunSpace())}_effBgMode(){return fr(this._sunGlobal(),this._sunSpace())}_dayCycleState(e=new Date){return(this._modeTransitionVisual?.viewWeight??("view"===this._mode?1:0))<=0||"daynight"!==this._effBgMode()?null:sr(this._renderPlanHass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?ar(e):"";const t="clock"===e?.source&&"hidden"!==this.ownerDocument.visibilityState&&this.isConnected;t&&!this._dayCycleTimer?this._dayCycleTimer=window.setInterval(this._dayCycleTick,3e4):!t&&this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_dayCycleVisibility(e){"hidden"!==e.kind?(this._dayCycleTick(),this._syncDayCycleClock()):this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_effSunRays(){return vr(this._sunGlobal(),this._sunSpace())}_sunNow(){return null!==this._effNorth()?yr(this._renderPlanHass):null}_renderSunRays(e){const t=W``,i=this._modeTransitionVisual?.viewWeight??0;if(this._editing&&i<=0||!this._effSunRays())return this._sunFadeReset(),t;const n=this._effNorth(),r=null!==n?yr(this._renderPlanHass):null;if(!r||r.elevation<=0)return this._sunFadeReset(),t;if(o=r.elevation,Number(o)>=3)this._sunOutTimer&&(clearTimeout(this._sunOutTimer),this._sunOutTimer=0),this._sunOut=!1,this._sunShown=!0;else{if(!this._sunShown)return t;this._sunOut||(this._sunOut=!0,this._sunOutTimer=window.setTimeout(()=>{this._sunOutTimer=0,this._sunShown=!1,this._sunOut=!1,this.requestUpdate()},2e3))}var o;const s=this._zeroWalls(),a=s.barriers.map(e=>e.join(",")).join(";"),l=`${e.id}|${r.azimuth}|${r.elevation}|${n}|${this._cfgEpoch}|${s.style}|${a}`;if(!this._sunRaysCache||this._sunRaysCache.key!==l){const t=e.rooms.map(e=>({id:e.id||"",poly:ni(e)})).filter(e=>!!e.id&&!!e.poly),i=this._openingsR.filter(e=>"window"===e.type&&"partition"!==e.host?.kind).map(e=>({id:e.id,x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=this._spaceWalls,a=this._openCuts(),c=this._openingWallIndexFor(e,a).value,h={},d={},u=this._wallUnionGeometry()?.roomGeom;if(o.length){for(const i of t){const t=this._innerRoomContour(e,i.id,a,u);t&&(h[i.id]=t)}for(const e of i){const t=la(c,{x:e.x,y:e.y,angle:e.angle,length:e.length});t.cm>0&&(d[e.id]=Ao(t.cm,this._cellCm,this._gridPitch))}}let p=_r(t,i,r.azimuth,r.elevation,n,o.length?h:void 0,o.length?d:void 0);const _=[...this._physicalBodiesR(e),...s.barriers.map(e=>[[e[0],e[1]],[e[2],e[3]]])];_.length&&(p=p.map(e=>{const t=function(e,t,i){return i>0?e.map(e=>function(e){const t=[...e].sort((e,t)=>e[0]-t[0]||e[1]-t[1]);if(t.length<=2)return t;const i=(e,t,i)=>(t[0]-e[0])*(i[1]-e[1])-(t[1]-e[1])*(i[0]-e[0]),n=[];for(const e of t){for(;n.length>=2&&i(n[n.length-2],n[n.length-1],e)<=0;)n.pop();n.push(e)}const r=[];for(let e=t.length-1;e>=0;e--){const n=t[e];for(;r.length>=2&&i(r[r.length-2],r[r.length-1],n)<=0;)r.pop();r.push(n)}return n.slice(0,-1).concat(r.slice(0,-1))}([...e,...e.map(e=>[e[0]+t[0]*i,e[1]+t[1]*i])])).filter(e=>e.length>=3):e}(_,e.dir,e.len),i=e.polys.map(e=>Da(e,t));return{...e,paths:i.map(ya).filter(Boolean),polys:i.flatMap(Fa)}}).filter(e=>e.paths?.length||e.polys.length)),this._sunRaysCache={key:l,rays:p,rims:p.map(e=>function(e,t=1e-4){const[i,n]=e.dir,r=-n,o=i,s=[];for(const a of[e.a,e.b]){const l=[];for(const s of e.polys)for(let e=0;et)continue;if(Math.abs((h[0]-a[0])*r+(h[1]-a[1])*o)>t)continue;const d=(c[0]-a[0])*i+(c[1]-a[1])*n,u=(h[0]-a[0])*i+(h[1]-a[1])*n;Math.abs(u-d)<=t||l.push(de[0]-t[0]);const c=[];for(const e of l){const i=c[c.length-1];i&&e[0]<=i[1]+t?i[1]=Math.max(i[1],e[1]):c.push([e[0],e[1]])}for(const[e,t]of c)s.push([[a[0]+i*e,a[1]+n*e],[a[0]+i*t,a[1]+n*t]])}return s}(e))}}const c=this._sunRaysCache.rays,h=this._sunRaysCache.rims;if(!c.length)return t;const d=(u=function(e){const t=Math.min(90,Math.max(-90,Number(e)||0));let i=lr[lr.length-1][1];for(let e=1;e - ${c.map((e,t)=>{const i=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2,r=i+e.normal[0]*e.depth,o=n+e.normal[1]*e.depth;return W``}_renderWallThickUi(){return this._editorRuntime?this._editorRuntimeOrThrow()._renderWallThickUi():W``}_renderWallThickDialog(){return this._editorRuntimeOrThrow()._renderWallThickDialog()}_openingAt(e){return this._editorRuntimeOrThrow()._openingAt(e)}_resolveOpeningPlacement(e){return this._editorRuntimeOrThrow()._resolveOpeningPlacement(e)}_activateOpeningPlacement(e){return this._editorRuntimeOrThrow()._activateOpeningPlacement(e)}_clearOpeningPlacement(e){return this._editorRuntime?this._editorRuntimeOrThrow()._clearOpeningPlacement(e):(this._openingHoverCandidate=null,this._openingJambBlockCm=null,void(e&&(this._openingPreset=null,this._openingRebindId=null)))}_openingClick(e){return this._editorRuntimeOrThrow()._openingClick(e)}_editOpening(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._editOpening(e)}_opPointerDown(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerDown(e,t)}_opPointerMove(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerMove(e,t)}_opRuler(e,t){return this._editorRuntimeOrThrow()._opRuler(e,t)}_opPointerUp(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opPointerUp(e,t)}_opClick(e,t){if(this._editorRuntime)return this._editorRuntimeOrThrow()._opClick(e,t)}_saveOpening(){return this._editorRuntimeOrThrow()._saveOpening()}_deleteOpening(){return this._editorRuntimeOrThrow()._deleteOpening()}_contactCandidates(){return this._editorRuntimeOrThrow()._contactCandidates()}_lockCandidates(){return this._editorRuntimeOrThrow()._lockCandidates()}_toggleOpeningEntityPicker(e){return this._editorRuntimeOrThrow()._toggleOpeningEntityPicker(e)}_filterOpeningEntities(e,t){return this._editorRuntimeOrThrow()._filterOpeningEntities(e,t)}_selectOpeningEntity(e,t){return this._editorRuntimeOrThrow()._selectOpeningEntity(e,t)}_mergeClick(e){return this._editorRuntimeOrThrow()._mergeClick(e)}_commitMerge(){return this._editorRuntimeOrThrow()._commitMerge()}_splitClick(e){return this._editorRuntimeOrThrow()._splitClick(e)}get _contourClosed(){return this._path.length>=4&&this._samePt(this._path[0],this._path[this._path.length-1])&&(null!=this._closingWallCm||!this._activeWallChainId)}_markupMove(e){this._markup&&this._editorRuntime&&this._editorRuntimeOrThrow()._queuePointerMove("markup-hover",()=>this._editorRuntime._markupMove(e))}get _openingPreview(){const e=this._openingPreset;if("opening"!==this._tool||!e||!this._cursorPt)return null;const t=this._cursorPt,i=this._openingHoverCandidate;if(i&&Yf(i,[t[0],t[1]],e.revision,this._cfgEpoch))return i;if(this._openingAt(t))return this._openingHoverCandidate=null,null;const n=this._resolveOpeningPlacement(t);return this._openingHoverCandidate=n,n}get _opMeasureView(){return this._opMeasure||this._openingPreview?.measure||null}_saveRoom(){return this._editorRuntimeOrThrow()._saveRoom()}_decideWallFace(e){return this._editorRuntimeOrThrow()._decideWallFace(e)}_wallSourceCmAt(e,t,i){return this._editorRuntimeOrThrow()._wallSourceCmAt(e,t,i)}_activePathWithRepair(e,t){return this._editorRuntimeOrThrow()._activePathWithRepair(e,t)}_validateWallRepair(e,t){return this._editorRuntimeOrThrow()._validateWallRepair(e,t)}_applyWallRepair(e,t){return this._editorRuntimeOrThrow()._applyWallRepair(e,t)}_applyWallFaceBatch(){return this._editorRuntimeOrThrow()._applyWallFaceBatch()}_commitRoom(){return this._editorRuntimeOrThrow()._commitRoom()}_cancelPath(){return this._editorRuntimeOrThrow()._cancelPath()}_roomDialogCancel(){return this._editorRuntimeOrThrow()._roomDialogCancel()}get _freeAreas(){const e=new Set;for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area&&e.add(i.area);for(const t of this._wallFaceBatch?.decisions||[])t.create&&t.area&&e.add(t.area);return Object.values(this.hass?.areas||{}).filter(t=>!e.has(t.area_id)).sort((e,t)=>(e.name||"").localeCompare(t.name||""))}_openDeviceInbox(){return this._editorRuntimeOrThrow()._openDeviceInbox()}_closeMarkerDialog(){return this._editorRuntimeOrThrow()._closeMarkerDialog()}_deviceInboxCandidates(e){return this._editorRuntimeOrThrow()._deviceInboxCandidates(e)}_deviceInboxRows(){return this._editorRuntimeOrThrow()._deviceInboxRows()}_deviceForInboxRow(e){return this._editorRuntimeOrThrow()._deviceForInboxRow(e)}_openInboxMarker(e,t=!1){return this._editorRuntimeOrThrow()._openInboxMarker(e,t)}async _setInboxHidden(e,t){return this._editorRuntimeOrThrow()._setInboxHidden(e,t)}_findInboxDevice(e){return this._editorRuntimeOrThrow()._findInboxDevice(e)}_deviceInboxTabKey(e){return this._editorRuntimeOrThrow()._deviceInboxTabKey(e)}_openMarkerDialog(e){if(this._editorRuntime)return this._editorRuntime._openMarkerDialog(e);this._ensureEditorRuntime().then(t=>{t&&this._openMarkerDialog(e)})}_runCandidates(){return this._editorRuntimeOrThrow()._runCandidates()}_bindingCandidates(){return this._editorRuntimeOrThrow()._bindingCandidates()}_physicalBodiesR(e=this._spaceModel()){if(!e)return[];const t=`${e.id}|${this._cfgEpoch}|${this._cellCm}|${this._gridPitch}`;if(this._physicalBodiesCache?.key===t)return this._physicalBodiesCache.all;const i=Ma(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(e));return this._physicalBodiesCache={key:t,...i},i.all}_rawPhysicalBodiesR(e=this._spaceModel()){if(!e)return[];this._physicalBodiesR(e);const t=this._physicalBodiesCache;return t?[...t.partitions,...t.columns]:[]}_cleanFloor(e,t,i=this._spaceModel()){if(!i)return{floor:t,geom:null,path:"",area:Pa([[[...t,t[0]]]])};const n=e.id||`#${i.rooms.indexOf(e)}`,r=`${i.id}|${this._cfgEpoch}|${n}`;if(!this._resize?.preview){const e=Sf(this._cleanFloorCache,r);if(e.hit)return e.value}const o=t.map(e=>e[0]),s=t.map(e=>e[1]),a=[Math.min(...o),Math.min(...s),Math.max(...o),Math.max(...s)],l=this._physicalBodiesR(i).filter(e=>{const t=e.map(e=>e[0]),i=e.map(e=>e[1]);return Math.max(...t)>=a[0]&&Math.min(...t)<=a[2]&&Math.max(...i)>=a[1]&&Math.min(...i)<=a[3]}),c=l.length?Aa(t,l):null,h={floor:t,geom:c,path:c?ba(c):"",area:Pa(c||[[[...t,t[0]]]])};return this._resize?.preview||$f(this._cleanFloorCache,r,h,600),h}_autoIconForBinding(e){if("virtual"===e)return"mdi:map-marker";const[t,i]=e.split(":");if(!i)return"";const n=this._fullRegistryHass,r=this._bindingStatus(e),o="active"===r.kind?r.enabledEntityIds:r.allEntityIds;if("device"===t){const e=n.devices?.[i];if(!e)return"mdi:help-circle";const t=o;return t.some(e=>e.startsWith("lock."))?"mdi:lock":Ud(n,e.name_by_user||e.name||"",e.model,t,this._iconRules)}if("entity"===t){const e=n.entities?.[i],t=this.hass.states?.[i],r=e?.name||t?.attributes?.friendly_name||i;return i.startsWith("lock.")?"mdi:lock":Ud(n,r,"",[i],this._iconRules)}return""}_allRoomsFlat(){const e=[];for(const t of this._serverCfg?.spaces||[])for(const i of t.rooms||[])i.area?e.push({value:t.id+"#"+i.area,label:(t.title||t.id)+" · "+i.name}):i.id&&e.push({value:t.id+"#@"+i.id,label:(t.title||t.id)+" · "+i.name+" · "+this._t("marker.subarea")});return e}_errText(e){if(!e)return this._t("err.unknown");if("string"==typeof e)return e;if("invalid_passage_fields"===e.code){const t=String(e.message||e.error||"");let i="",n=[];try{const e=JSON.parse(t);i=String(e.space??""),n=Array.isArray(e.fields)?e.fields.map(String):[]}catch{const e=t.match(/space=([^;]*);\s*opening=([^;]*);\s*fields=([^;]*)/);e&&(i=e[1],n=e[3].split(",").filter(Boolean))}if(i||n.length){const e=this._serverCfg?.spaces?.find(e=>String(e.id)===i),t={contact:"opening.contact_label",lock:"opening.lock_label",invert:"opening.invert",flip_h:"opening.flip_h",flip_v:"opening.flip_v"},r=n.map(e=>t[e]?this._t(t[e]):e).join(", ");return this._t("opening.invalid_passage_fields",{room:e?.title||i,fields:r})}}if("invalid_partition_opening_jamb_margin"===e.code){const t=String(e.message||e.error||"");let i=NaN;try{i=Number(JSON.parse(t).margin_cm)}catch{const e=t.match(/margin_cm=([^;}"]*)/);i=e?Number(e[1]):NaN}if(Number.isFinite(i))return this._t("opening.partition_jamb_margin",{distance:ti(i,this._imperial)})}if(null!=e.code){const t=`backup.error.${e.code}`,i=this._t(t);return e.message&&console.warn("[houseplan] backend error",e.code,e.message),i!==t?i:this._t("err.code",{code:e.code})}if(e.message)return e.message;if(e.error)return e.error;try{return JSON.stringify(e)}catch{return String(e)}}_backupErrorText(e){return this._editorRuntimeOrThrow()._backupErrorText(e)}async _pickMarkerFiles(e){return this._editorRuntimeOrThrow()._pickMarkerFiles(e)}_removeMarkerPdf(e){return this._editorRuntimeOrThrow()._removeMarkerPdf(e)}_markerLightFields(e){return this._editorRuntimeOrThrow()._markerLightFields(e)}_markerTapActionFields(e){return this._editorRuntimeOrThrow()._markerTapActionFields(e)}_markerToggleEntityFields(e){return this._editorRuntimeOrThrow()._markerToggleEntityFields(e)}async _saveMarker(){return this._editorRuntimeOrThrow()._saveMarker()}async _deleteMarker(){return this._editorRuntimeOrThrow()._deleteMarker()}_normPos(e,t,i){return{s:e,x:t/pv,y:i/pv}}_spaceDialogUsesOnboardingRuntime(e){return"create"===e&&!this._editorRuntime&&(!!this._onboardingRuntime||0===(this._serverCfg?.spaces.length||0)||this._importTotal>0||this._importQueue.length>0)}_spaceRuntimeOrThrow(){if(!this._onboardingRuntime)throw new Error("Houseplan onboarding runtime is not loaded");return this._onboardingRuntime}_openSpaceDialog(e,t){return this._spaceDialogUsesOnboardingRuntime(e)?this._onboardingRuntime?void this._onboardingRuntime._openSpaceDialog(e,t):void this._ensureOnboardingRuntime().then(i=>{i&&this._spaceRuntimeOrThrow()._openSpaceDialog(e,t)}):this._editorRuntime?this._editorRuntime._openSpaceDialog(e,t):void this._ensureEditorRuntime().then(i=>{i&&this._openSpaceDialog(e,t)})}async _pickPlanFile(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._pickPlanFile(e):this._editorRuntimeOrThrow()._pickPlanFile(e)}_useServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._useServerPlan(e):this._editorRuntimeOrThrow()._useServerPlan(e)}async _readPlanAspect(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._readPlanAspect(e):this._editorRuntimeOrThrow()._readPlanAspect(e)}async _deleteServerPlan(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._deleteServerPlan(e):this._editorRuntimeOrThrow()._deleteServerPlan(e)}_renderServerPlans(e){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime(e.mode)?this._onboardingRuntime._renderServerPlans(e):this._editorRuntimeOrThrow()._renderServerPlans(e)}async _saveSpaceDialog(){return this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._saveSpaceDialog():this._editorRuntimeOrThrow()._saveSpaceDialog()}async _deleteSpace(){return this._editorRuntimeOrThrow()._deleteSpace()}async _saveConfigNow(){return this._editorRuntimeOrThrow()._saveConfigNow()}_startImport(){return this._onboardingRuntime?this._onboardingRuntime._startImport():this._editorRuntimeOrThrow()._startImport()}_openNextImport(){return this._onboardingRuntime?this._onboardingRuntime._openNextImport():this._editorRuntimeOrThrow()._openNextImport()}_skipImport(){return this._onboardingRuntime?this._onboardingRuntime._skipImport():this._editorRuntimeOrThrow()._skipImport()}_renderImportDialog(){return this._onboardingRuntime?this._onboardingRuntime._renderImportDialog():this._editorRuntimeOrThrow()._renderImportDialog()}_sunGlobal(){const e=this._settingsDialog;return e?{...this._settings,north_deg:e.northDeg??void 0,bg_mode:e.bgMode,sun_rays:e.sunRays,sun_ray_origin:e.sunRayOrigin}:this._settings}_sunSpace(){const e=this._spaceDialog,t=this._curSpaceCfg?.settings||{};return e&&"edit"===e.mode&&e.spaceId===this._space?{...t,north_deg:e.northDeg??void 0,bg_mode:e.bgMode??void 0,sun_rays:e.sunRays??void 0}:t}_effNorth(){return gr(this._sunGlobal(),this._sunSpace())}_effBgMode(){return vr(this._sunGlobal(),this._sunSpace())}_dayCycleState(e=new Date){return(this._modeTransitionVisual?.viewWeight??("view"===this._mode?1:0))<=0||"daynight"!==this._effBgMode()?null:sr(this._renderPlanHass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?ar(e):"";const t="clock"===e?.source&&"hidden"!==this.ownerDocument.visibilityState&&this.isConnected;t&&!this._dayCycleTimer?this._dayCycleTimer=window.setInterval(this._dayCycleTick,3e4):!t&&this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_dayCycleVisibility(e){"hidden"!==e.kind?(this._dayCycleTick(),this._syncDayCycleClock()):this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_effSunRays(){return yr(this._sunGlobal(),this._sunSpace())}_effSunRayOrigin(){return fr(this._sunGlobal())}_sunNow(){return null!==this._effNorth()?br(this._renderPlanHass):null}_renderSunRays(e){const t=W``,i=this._modeTransitionVisual?.viewWeight??0;if(this._editing&&i<=0||!this._effSunRays())return this._sunFadeReset(),t;const n=this._effNorth(),r=null!==n?br(this._renderPlanHass):null;if(!r||r.elevation<=0)return this._sunFadeReset(),t;if(o=r.elevation,Number(o)>=3)this._sunOutTimer&&(clearTimeout(this._sunOutTimer),this._sunOutTimer=0),this._sunOut=!1,this._sunShown=!0;else{if(!this._sunShown)return t;this._sunOut||(this._sunOut=!0,this._sunOutTimer=window.setTimeout(()=>{this._sunOutTimer=0,this._sunShown=!1,this._sunOut=!1,this.requestUpdate()},2e3))}var o;const s=this._zeroWalls(),a=s.barriers.map(e=>e.join(",")).join(";"),l=this._effSunRayOrigin(),c=`${e.id}|${r.azimuth}|${r.elevation}|${n}|${l}|${this._cfgEpoch}|${s.style}|${a}`;if(!this._sunRaysCache||this._sunRaysCache.key!==c){const t=e.rooms.map(e=>({id:e.id||"",poly:ni(e)})).filter(e=>!!e.id&&!!e.poly),i=this._openingsR.filter(e=>"window"===e.type&&"partition"!==e.host?.kind).map(e=>({id:e.id,x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),o=this._spaceWalls,a=this._openCuts(),h=this._openingWallIndexFor(e,a).value,d={},u={},p=this._wallUnionGeometry()?.roomGeom;if(o.length){for(const i of t){const t=this._innerRoomContour(e,i.id,a,p);t&&(d[i.id]=t)}for(const e of i){const t=ca(h,{x:e.x,y:e.y,angle:e.angle,length:e.length});t.cm>0&&(u[e.id]=Po(t.cm,this._cellCm,this._gridPitch))}}let _=_r(t,i,r.azimuth,r.elevation,n,o.length?d:void 0,o.length?u:void 0,l);const m=[...this._physicalBodiesR(e),...s.barriers.map(e=>[[e[0],e[1]],[e[2],e[3]]])];m.length&&(_=_.map(e=>{const t=function(e,t,i){return i>0?e.map(e=>function(e){const t=[...e].sort((e,t)=>e[0]-t[0]||e[1]-t[1]);if(t.length<=2)return t;const i=(e,t,i)=>(t[0]-e[0])*(i[1]-e[1])-(t[1]-e[1])*(i[0]-e[0]),n=[];for(const e of t){for(;n.length>=2&&i(n[n.length-2],n[n.length-1],e)<=0;)n.pop();n.push(e)}const r=[];for(let e=t.length-1;e>=0;e--){const n=t[e];for(;r.length>=2&&i(r[r.length-2],r[r.length-1],n)<=0;)r.pop();r.push(n)}return n.slice(0,-1).concat(r.slice(0,-1))}([...e,...e.map(e=>[e[0]+t[0]*i,e[1]+t[1]*i])])).filter(e=>e.length>=3):e}(m,e.dir,e.len),i=e.polys.map(e=>Aa(e,t));return{...e,paths:i.map(ba).filter(Boolean),polys:i.flatMap(za)}}).filter(e=>e.paths?.length||e.polys.length)),this._sunRaysCache={key:c,rays:_,rims:_.map(e=>function(e,t=1e-4){const[i,n]=e.dir,r=-n,o=i,s=[];for(const a of[e.a,e.b]){const l=[];for(const s of e.polys)for(let e=0;et)continue;if(Math.abs((h[0]-a[0])*r+(h[1]-a[1])*o)>t)continue;const d=(c[0]-a[0])*i+(c[1]-a[1])*n,u=(h[0]-a[0])*i+(h[1]-a[1])*n;Math.abs(u-d)<=t||l.push(de[0]-t[0]);const c=[];for(const e of l){const i=c[c.length-1];i&&e[0]<=i[1]+t?i[1]=Math.max(i[1],e[1]):c.push([e[0],e[1]])}for(const[e,t]of c)s.push([[a[0]+i*e,a[1]+n*e],[a[0]+i*t,a[1]+n*t]])}return s}(e))}}const h=this._sunRaysCache.rays,d=this._sunRaysCache.rims;if(!h.length)return t;const u=(p=function(e){const t=Math.min(90,Math.max(-90,Number(e)||0));let i=lr[lr.length-1][1];for(let e=1;e + ${h.map((e,t)=>{const i=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2,r=i+e.normal[0]*e.depth,o=n+e.normal[1]*e.depth;return W` - ${p.map(([e,t])=>W``)} + ${_.map(([e,t])=>W``)} - ${_.map(([e,t])=>W`W``)} `})} - ${c.map((e,t)=>e.paths?.length?e.paths.map(e=>W``):e.polys.map(e=>W`e.paths?.length?e.paths.map(e=>W``):e.polys.map(e=>W``))} - ${c.map((e,t)=>(h[t]||[]).map(e=>W`(d[t]||[]).map(e=>W``))} @@ -507,7 +507,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this._t("gs.north_letter")} ${null===e?"—":e+"°"} - `}_stageBg(e){const t=this._settingsDialog,i=this._spaceDialog,n=t?t.bgColor||"":pn(this._settings,{bgColor:null});return(i&&"edit"===i.mode&&i.spaceId===this._space?i.bgColor||"":e.bgColor||"")||n}_stageBgHex(){const e=this._stageEl;if(e){const t=getComputedStyle(e).backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(t)return"#"+t.slice(1,4).map(e=>(+e).toString(16).padStart(2,"0")).join("")}return"#111111"}_renderPdfDialog(){const e=this._pdfRuntime,t=this._spaceModel(),i=this._curSpaceCfg;if(!(e&&t&&i&&this._serverCfg))return G;const n=new Map;for(const[e,t]of this._decorAssets)n.set(e,{url:this._display(t.url),mime:t.mime});const r=this._wallUnionGeometry(),o=this._openCuts(),s=new Map(t.rooms.flatMap(e=>e.id?[[e.id,e]]:[]));return e.render({config:this._serverCfg,rawSpace:i,space:t,layout:this._layout,imperial:this._imperial,cardTitle:this._config?.title||this._t("card.title"),version:Jf(ev),hass:this.hass,backdropUrl:t.bg?this._display(t.bg.href):"",decorAssets:n,sharedWallGeometry:r,resolveInnerContour:e=>this._innerRoomContour(t,e,o,r?.roomGeom,r?.multiWallNodes),resolveRoomArea:(e,i)=>{const n=s.get(e);return n?this._cleanFloor(n,i,t).area:void 0},t:(e,t)=>this._t(e,t),toast:e=>this._showToast(e),close:()=>{this._pdfDialog=!1,this.requestUpdate()}})}_preflightDiagnostics(e,t){return this._editorRuntimeOrThrow()._preflightDiagnostics(e,t)}_reportPreflightFailure(e,t){return this._editorRuntimeOrThrow()._reportPreflightFailure(e,t)}_preflightVersionsDiffer(){return this._editorRuntimeOrThrow()._preflightVersionsDiffer()}async _copyPreflightDiagnostics(){return this._editorRuntimeOrThrow()._copyPreflightDiagnostics()}_checkOptimizeGeometry(e){return this._editorRuntimeOrThrow()._checkOptimizeGeometryImpl(e)}_checkSpacePhysicalGeometry(e,t,i){return this._editorRuntimeOrThrow()._checkSpacePhysicalGeometryImpl(e,t,i)}_optimizeReferenceContext(e){return this._editorRuntimeOrThrow()._optimizeReferenceContext(e)}_previewAlignDialog(e){return this._editorRuntimeOrThrow()._previewAlignDialog(e)}async _runAlignToGrid(){return this._editorRuntimeOrThrow()._runAlignToGrid()}async _undoPlanOptimization(){return this._editorRuntimeOrThrow()._undoPlanOptimization()}async _runBackupExport(){return this._editorRuntimeOrThrow()._runBackupExport()}async _pickBackupImport(e){return this._editorRuntimeOrThrow()._pickBackupImport(e)}async _setBackupDuplicatePolicy(e){return this._editorRuntimeOrThrow()._setBackupDuplicatePolicy(e)}async _applyBackupImport(){return this._editorRuntimeOrThrow()._applyBackupImport()}_renderBackupExportDialog(){return this._editorRuntimeOrThrow()._renderBackupExportDialog()}_renderBackupImportDialog(){return this._editorRuntimeOrThrow()._renderBackupImportDialog()}_setFillColor(e,t){return this._editorRuntimeOrThrow()._setFillColor(e,t)}async _saveSettingsDialog(){return this._editorRuntimeOrThrow()._saveSettingsDialog()}_boolInput(e,t,i=!1){return this._editorRuntimeOrThrow()._boolInput(e,t,i)}_rangeInput(e,t,i,n,r,o=!1,s){return this._editorRuntimeOrThrow()._rangeInput(e,t,i,n,r,o,s)}_renderColorRow(e,t){return this._editorRuntimeOrThrow()._renderColorRow(e,t)}get _glowRadiusCm(){const e=Number(this._settings.glow_radius_cm);return Number.isFinite(e)&&e>0?e:300}get _imperial(){return"mi"===this.hass?.config?.unit_system?.length}get _glowRadiusPlaceholder(){const e=this._glowRadiusCm;return this._imperial?String(Math.round(e/30.48*10)/10):String(e/100)}_glowTransition(e,t){return Rm(this._glowRuntimeState,this._glowRuntimeHost,e,t)}_forgetGlowSource(e){Cm(this._glowRuntimeState,this._glowRuntimeHost,e)}_forgetGlowSpace(e){Tm(this._glowRuntimeState,this._glowRuntimeHost,e)}_warnGlowGeometryFallback(e,t,i,n){Pm(this._glowRuntimeState,e,t,i,n)}_lightBarriers(e,t){const i=km({rawSpaceConfig:this._curSpaceCfg,space:e,openings:this._openingsR,cellCm:this._cellCm,gridPitch:this._gridPitch,openingAmount:e=>this._openingAmt(e)}),n=`${e.id}|${i.fingerprint}`,r=xf(this._lightBarrierPool,n);if(r.hit)return this._lightBarrierCache=r.value,r.value.value;const o=xm({space:e,revision:i,walls:this._spaceWalls,zeroWalls:this._zeroWalls(),wallKeyPitch:this._wallKeyPitch,cellCm:this._cellCm,gridPitch:this._gridPitch,coordScale:uv,sharedWallGeometry:this._wallUnionGeometry(),physicalBodies:(t,i)=>(this._lightPhysicalBodiesCache?.key!==i&&(this._lightPhysicalBodiesCache={key:i,all:$a(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,t).all}),this._lightPhysicalBodiesCache.all)}),s={key:n,value:o};return Sf(this._lightBarrierPool,n,s,8),this._lightBarrierCache=s,o}_renderGlowLayer(e,t,i=this._viewOr(this._baseVb())){const n=this._fillColors,r=this._glowRadiusCm/this._cellCm*this._gridPitch,o=e.rooms.map(e=>({r:e,poly:ni(e)})).filter(e=>!!e.poly),s=o.filter(({r:e})=>Hn(t.glow,e));if(!s.length)return this._forgetGlowSpace(e.id),W``;const a=this._lightBarriers(e,o),l=wm({hass:this._renderPlanHass,devices:this._renderDevices,virtualLights:this._virtualLights,spaceId:e.id,defaultColor:n.glow_light.c,paletteAlpha:n.glow_light.a,defaultRadiusUnits:r,cellCm:this._cellCm,gridPitch:this._gridPitch,position:e=>this._pos(e)}),c=[],h=new Set;for(const t of l){const{key:i,pos:n}=t;if(h.add(i),$m(n,a)){this._forgetGlowSource(i);continue}const r=this._glowTransition(i,!!t.appearance);if(!r)continue;t.appearance&&this._glowLastAppearance.set(i,t.appearance);const s=this._glowLastAppearance.get(i);if(!s)continue;let l=null;const d=`${e.id}|${a.fingerprint}|${n.x.toFixed(4)},${n.y.toFixed(4)}|${t.radius.toFixed(4)}`,u=ym(this._glowRuntimeState,d);u.hit?l=u.value:(l=Sm({spaceId:e.id,source:n,radius:t.radius,scene:a,polygons:o.map(({r:e,poly:t})=>({room:e,poly:t})),onBoundsFailure:(t,i)=>this._warnGlowGeometryFallback(e.id,a.fingerprint,t,i)}),bm(this._glowRuntimeState,d,l)),c.push({key:i,sourceEid:t.sourceEid,domId:r.domId,entering:r.entering,leaving:r.leaving,pos:n,c:s.c,alpha:s.alpha,geometry:l,r:t.radius})}if(Dm(this._glowRuntimeState,this._glowRuntimeHost,e.id,h),!c.length)return W``;const d=this._spaceWalls,u=s.length===o.length?[]:this._openCuts(),p=this._wallUnionGeometry()?.roomGeom,_=s.length===o.length?null:s.map(({r:t,poly:i})=>{const n=d.length&&t.id&&this._innerRoomContour(e,t.id,u,p)||i,r=this._cleanFloor(t,n,e).path,s=Ri(n,o.filter(e=>e.r!==t).map(e=>e.poly)),a=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z";return[r||a(n),...s.map(a)].join(" ")}),m=this._stageEl?.clientWidth&&i.w?this._stageEl.clientWidth/i.w:1,g=!this._pinchStart&&!this._panStart&&!this._cameraTransition.active,f=Fm(this._glowRuntimeState,m,g);return zm({spots:c,enabledClip:_,feather:f.feather,featherEnabled:f.enabled,screenBlend:this._glowScreenBlend})}_renderAlignDialog(){return this._editorRuntimeOrThrow()._renderAlignDialog()}_renderSettingsDialog(){return this._editorRuntimeOrThrow()._renderSettingsDialog()}_renderSupportDialog(){return this._editorRuntimeOrThrow()._renderSupportDialog()}_rulesSet(e){return this._editorRuntimeOrThrow()._rulesSet(e)}async _saveRules(){return this._editorRuntimeOrThrow()._saveRules()}_renderRulesDialog(){return this._editorRuntimeOrThrow()._renderRulesDialog()}_saveKioskScale(e){this._summary?.saveScale(e)}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>{const n=Math.round(100*e[t]);return j` + `}_stageBg(e){const t=this._settingsDialog,i=this._spaceDialog,n=t?t.bgColor||"":pn(this._settings,{bgColor:null});return(i&&"edit"===i.mode&&i.spaceId===this._space?i.bgColor||"":e.bgColor||"")||n}_stageBgHex(){const e=this._stageEl;if(e){const t=getComputedStyle(e).backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(t)return"#"+t.slice(1,4).map(e=>(+e).toString(16).padStart(2,"0")).join("")}return"#111111"}_renderPdfDialog(){const e=this._pdfRuntime,t=this._spaceModel(),i=this._curSpaceCfg;if(!(e&&t&&i&&this._serverCfg))return G;const n=new Map;for(const[e,t]of this._decorAssets)n.set(e,{url:this._display(t.url),mime:t.mime});const r=this._wallUnionGeometry(),o=this._openCuts(),s=new Map(t.rooms.flatMap(e=>e.id?[[e.id,e]]:[]));return e.render({config:this._serverCfg,rawSpace:i,space:t,layout:this._layout,imperial:this._imperial,cardTitle:this._config?.title||this._t("card.title"),version:Qf(tv),hass:this.hass,backdropUrl:t.bg?this._display(t.bg.href):"",decorAssets:n,sharedWallGeometry:r,resolveInnerContour:e=>this._innerRoomContour(t,e,o,r?.roomGeom,r?.multiWallNodes),resolveRoomArea:(e,i)=>{const n=s.get(e);return n?this._cleanFloor(n,i,t).area:void 0},t:(e,t)=>this._t(e,t),toast:e=>this._showToast(e),close:()=>{this._pdfDialog=!1,this.requestUpdate()}})}_preflightDiagnostics(e,t){return this._editorRuntimeOrThrow()._preflightDiagnostics(e,t)}_reportPreflightFailure(e,t){return this._editorRuntimeOrThrow()._reportPreflightFailure(e,t)}_preflightVersionsDiffer(){return this._editorRuntimeOrThrow()._preflightVersionsDiffer()}async _copyPreflightDiagnostics(){return this._editorRuntimeOrThrow()._copyPreflightDiagnostics()}_checkOptimizeGeometry(e){return this._editorRuntimeOrThrow()._checkOptimizeGeometryImpl(e)}_checkSpacePhysicalGeometry(e,t,i){return this._editorRuntimeOrThrow()._checkSpacePhysicalGeometryImpl(e,t,i)}_optimizeReferenceContext(e){return this._editorRuntimeOrThrow()._optimizeReferenceContext(e)}_previewAlignDialog(e){return this._editorRuntimeOrThrow()._previewAlignDialog(e)}async _runAlignToGrid(){return this._editorRuntimeOrThrow()._runAlignToGrid()}async _undoPlanOptimization(){return this._editorRuntimeOrThrow()._undoPlanOptimization()}async _runBackupExport(){return this._editorRuntimeOrThrow()._runBackupExport()}async _pickBackupImport(e){return this._editorRuntimeOrThrow()._pickBackupImport(e)}async _setBackupDuplicatePolicy(e){return this._editorRuntimeOrThrow()._setBackupDuplicatePolicy(e)}async _applyBackupImport(){return this._editorRuntimeOrThrow()._applyBackupImport()}_renderBackupExportDialog(){return this._editorRuntimeOrThrow()._renderBackupExportDialog()}_renderBackupImportDialog(){return this._editorRuntimeOrThrow()._renderBackupImportDialog()}_setFillColor(e,t){return this._editorRuntimeOrThrow()._setFillColor(e,t)}async _saveSettingsDialog(){return this._editorRuntimeOrThrow()._saveSettingsDialog()}_boolInput(e,t,i=!1){return this._editorRuntimeOrThrow()._boolInput(e,t,i)}_rangeInput(e,t,i,n,r,o=!1,s){return this._editorRuntimeOrThrow()._rangeInput(e,t,i,n,r,o,s)}_renderColorRow(e,t){return this._editorRuntimeOrThrow()._renderColorRow(e,t)}get _glowRadiusCm(){const e=Number(this._settings.glow_radius_cm);return Number.isFinite(e)&&e>0?e:300}get _imperial(){return"mi"===this.hass?.config?.unit_system?.length}get _glowRadiusPlaceholder(){const e=this._glowRadiusCm;return this._imperial?String(Math.round(e/30.48*10)/10):String(e/100)}_glowTransition(e,t){return Cm(this._glowRuntimeState,this._glowRuntimeHost,e,t)}_forgetGlowSource(e){Tm(this._glowRuntimeState,this._glowRuntimeHost,e)}_forgetGlowSpace(e){Dm(this._glowRuntimeState,this._glowRuntimeHost,e)}_warnGlowGeometryFallback(e,t,i,n){Fm(this._glowRuntimeState,e,t,i,n)}_lightBarriers(e,t){const i=xm({rawSpaceConfig:this._curSpaceCfg,space:e,openings:this._openingsR,cellCm:this._cellCm,gridPitch:this._gridPitch,openingAmount:e=>this._openingAmt(e)}),n=`${e.id}|${i.fingerprint}`,r=Sf(this._lightBarrierPool,n);if(r.hit)return this._lightBarrierCache=r.value,r.value.value;const o=Sm({space:e,revision:i,walls:this._spaceWalls,zeroWalls:this._zeroWalls(),wallKeyPitch:this._wallKeyPitch,cellCm:this._cellCm,gridPitch:this._gridPitch,coordScale:pv,sharedWallGeometry:this._wallUnionGeometry(),physicalBodies:(t,i)=>(this._lightPhysicalBodiesCache?.key!==i&&(this._lightPhysicalBodiesCache={key:i,all:Ma(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,t).all}),this._lightPhysicalBodiesCache.all)}),s={key:n,value:o};return $f(this._lightBarrierPool,n,s,8),this._lightBarrierCache=s,o}_renderGlowLayer(e,t,i=this._viewOr(this._baseVb())){const n=this._fillColors,r=this._glowRadiusCm/this._cellCm*this._gridPitch,o=e.rooms.map(e=>({r:e,poly:ni(e)})).filter(e=>!!e.poly),s=o.filter(({r:e})=>Hn(t.glow,e));if(!s.length)return this._forgetGlowSpace(e.id),W``;const a=this._lightBarriers(e,o),l=km({hass:this._renderPlanHass,devices:this._renderDevices,virtualLights:this._virtualLights,spaceId:e.id,defaultColor:n.glow_light.c,paletteAlpha:n.glow_light.a,defaultRadiusUnits:r,cellCm:this._cellCm,gridPitch:this._gridPitch,position:e=>this._pos(e)}),c=[],h=new Set;for(const t of l){const{key:i,pos:n}=t;if(h.add(i),Mm(n,a)){this._forgetGlowSource(i);continue}const r=this._glowTransition(i,!!t.appearance);if(!r)continue;t.appearance&&this._glowLastAppearance.set(i,t.appearance);const s=this._glowLastAppearance.get(i);if(!s)continue;let l=null;const d=`${e.id}|${a.fingerprint}|${n.x.toFixed(4)},${n.y.toFixed(4)}|${t.radius.toFixed(4)}`,u=bm(this._glowRuntimeState,d);u.hit?l=u.value:(l=$m({spaceId:e.id,source:n,radius:t.radius,scene:a,polygons:o.map(({r:e,poly:t})=>({room:e,poly:t})),onBoundsFailure:(t,i)=>this._warnGlowGeometryFallback(e.id,a.fingerprint,t,i)}),wm(this._glowRuntimeState,d,l)),c.push({key:i,sourceEid:t.sourceEid,domId:r.domId,entering:r.entering,leaving:r.leaving,pos:n,c:s.c,alpha:s.alpha,geometry:l,r:t.radius})}if(Am(this._glowRuntimeState,this._glowRuntimeHost,e.id,h),!c.length)return W``;const d=this._spaceWalls,u=s.length===o.length?[]:this._openCuts(),p=this._wallUnionGeometry()?.roomGeom,_=s.length===o.length?null:s.map(({r:t,poly:i})=>{const n=d.length&&t.id&&this._innerRoomContour(e,t.id,u,p)||i,r=this._cleanFloor(t,n,e).path,s=Ri(n,o.filter(e=>e.r!==t).map(e=>e.poly)),a=e=>"M "+e.map(e=>e[0]+" "+e[1]).join(" L ")+" Z";return[r||a(n),...s.map(a)].join(" ")}),m=this._stageEl?.clientWidth&&i.w?this._stageEl.clientWidth/i.w:1,g=!this._pinchStart&&!this._panStart&&!this._cameraTransition.active,f=zm(this._glowRuntimeState,m,g);return Im({spots:c,enabledClip:_,feather:f.feather,featherEnabled:f.enabled,screenBlend:this._glowScreenBlend})}_renderAlignDialog(){return this._editorRuntimeOrThrow()._renderAlignDialog()}_renderSettingsDialog(){return this._editorRuntimeOrThrow()._renderSettingsDialog()}_renderSupportDialog(){return this._editorRuntimeOrThrow()._renderSupportDialog()}_rulesSet(e){return this._editorRuntimeOrThrow()._rulesSet(e)}async _saveRules(){return this._editorRuntimeOrThrow()._saveRules()}_renderRulesDialog(){return this._editorRuntimeOrThrow()._renderRulesDialog()}_saveKioskScale(e){this._summary?.saveScale(e)}_renderKioskDialog(){const e=this._kioskScale,t=(t,i)=>{const n=Math.round(100*e[t]);return j`
    {const i=Number(e.target.value);Number.isFinite(i)&&this._saveKioskScale({[t]:i/100})}} aria-label=${i} /> @@ -528,7 +528,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 .request=${this._dangerConfirm.request} .token=${this._dangerConfirm.token} @hp-confirm-decision=${this._onDangerConfirmDecision}> - `:G}_renderRoot(e){return j`${e}${this._renderVersionBanner()}${this._renderDangerConfirm()}`}render(){const e=this._renderBody();return e===G?e:this._renderRoot(e)}_renderBody(){if(!this._config||!this.hass)return G;const e=this._terminalFrame;if(this._terminalFrame=0,1===e)return U;const t=this._syncDangerConfirmLocaleGate();if("cold"===t)return hp();if("warm"===t)return U;const i=!!this._importDialog||!(!this._spaceDialog||!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)),n="view"!==this._mode||!!(this._roomDialog||this._mergeDialog||this._openingDialog||this._physicalDialog||this._partitionDeleteDialog||this._roomDeleteDialog||this._decorTextDialog||this._decorShapeDialog||this._backdropDialog||this._decorEraseConfirm||this._spaceDialog&&!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)||this._deviceInbox||this._markerDialog||this._rulesDialog||this._settingsDialog||this._supportDialog||this._alignDialog||this._backupExportDialog||this._backupImportDialog||this._kioskDialog||this._vacFit||this._vacCalConfirm);i&&!this._onboardingRuntime&&this._ensureOnboardingRuntime(),n&&!this._editorRuntime&&this._ensureEditorRuntime();const r=this._model,o=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e)),s=this._fixedFloorState(r);if("pending"===s.kind)return j` + `:G}_renderRoot(e){return j`${e}${this._renderVersionBanner()}${this._renderDangerConfirm()}`}render(){const e=this._renderBody();return e===G?e:this._renderRoot(e)}_renderBody(){if(!this._config||!this.hass)return G;const e=this._terminalFrame;if(this._terminalFrame=0,1===e)return U;const t=this._syncDangerConfirmLocaleGate();if("cold"===t)return dp();if("warm"===t)return U;const i=!!this._importDialog||!(!this._spaceDialog||!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)),n="view"!==this._mode||!!(this._roomDialog||this._mergeDialog||this._openingDialog||this._physicalDialog||this._partitionDeleteDialog||this._roomDeleteDialog||this._decorTextDialog||this._decorShapeDialog||this._backdropDialog||this._decorEraseConfirm||this._spaceDialog&&!this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)||this._deviceInbox||this._markerDialog||this._rulesDialog||this._settingsDialog||this._supportDialog||this._alignDialog||this._backupExportDialog||this._backupImportDialog||this._kioskDialog||this._vacFit||this._vacCalConfirm);i&&!this._onboardingRuntime&&this._ensureOnboardingRuntime(),n&&!this._editorRuntime&&this._ensureEditorRuntime();const r=this._model,o=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e)),s=this._fixedFloorState(r);if("pending"===s.kind)return j` ${this.panelHost?G:j`
    ${this._config.title||this._t("card.title")}
    `} @@ -571,7 +571,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this._spaceDialog&&(this._onboardingRuntime||this._editorRuntime)?this._renderSpaceDialog():G} ${this._importDialog&&this._onboardingRuntime?this._renderImportDialog():G} ${this._toast?j``:G} -
    `;const a=this._spaceModel();if(!a)return G;const l="valid"===s.kind?[a]:r,c=a.vb;let h=this._effectiveProjection();this._renderProjection=h,this._labs.active.length&&function(){const e=Ff,t=e.alpha?e.active.join(","):"";if(!t||t===If)return;If=t;const i=new Map(Cf.map(e=>[e.id,e])),n=e.active.map(e=>`${e} (#${i.get(e).issue})`).join(", ");console.info(`HOUSEPLAN ALPHA: hp_alpha=1; ${n}`)}();let d="iso"===h;const u=d?this._isoSceneRuntime:null,p="devices"===this._mode&&this._showAll,_=this._renderDevices.filter(e=>e.space===a.id&&(!e.hidden||p)),m=this._renderDeviceSnapshot,g=this._spaceDisplayForRender(),f=this._resolvedRoomFills(a,g),v=this._resolvedGlowBase(a,g,f),y=g.showLqi??this._config.show_signal??!0,b=this._config.icon_size??2.5,w=b>8?2.5:b,k=w_(w);let x=d?this._renderIsoScene:null,S=this._viewOr(this._baseVb(h,x)),$=null;try{$=u?.resolveIsoFramePresentation({projection:h,display:g,scene:x,openings:this._openingsR,amountOf:e=>this._openingAmt(e),cellCm:this._cellCm,overlays:e=>this._isoOverlayScene(a,_,S,g,e,x,w,k,y)})??null}catch(e){this._latchIsoFallback(g.showBorders?x?.key||this._isoInvalidKey():`${a.id}|no-borders`,e),this._cancelCameraTransition(!1),h="flat",d=!1,x=null,$=null,this._renderProjection="flat",this._renderIsoScene=null,this._isoProjectionSnapshot="flat",this._view=null,this._viewModeSnap=null,S=this._viewOr(this._baseVb("flat",null))}const M=$?.layers??null,R=$?.overlays??null,C=this._editing?"":this._stageBg(g),T=this._opMeasureView,D="view"===this._mode?this._editorChromeMode:this._mode,A=this._roomHoverPaths(a),P=a.bg?this._display(a.bg.href):"",F=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,z=this._modeTransitionVisual,I=this._dayCycleState(),O=z?.viewWeight??("view"===this._mode?1:0),E=this._modeTransition.state?.from.presentedMode,N=!this._markup||!!z&&("view"===z.presentedMode||"devices"===z.presentedMode||"view"===E||"devices"===E),H=z?.stageColor||C,L=z?.sceneBrightness??1;return j` +
    `;const a=this._spaceModel();if(!a)return G;const l="valid"===s.kind?[a]:r,c=a.vb;let h=this._effectiveProjection();this._renderProjection=h,this._labs.active.length&&function(){const e=zf,t=e.alpha?e.active.join(","):"";if(!t||t===Of)return;Of=t;const i=new Map(Tf.map(e=>[e.id,e])),n=e.active.map(e=>`${e} (#${i.get(e).issue})`).join(", ");console.info(`HOUSEPLAN ALPHA: hp_alpha=1; ${n}`)}();let d="iso"===h;const u=d?this._isoSceneRuntime:null,p="devices"===this._mode&&this._showAll,_=this._renderDevices.filter(e=>e.space===a.id&&(!e.hidden||p)),m=this._renderDeviceSnapshot,g=this._spaceDisplayForRender(),f=this._resolvedRoomFills(a,g),v=this._resolvedGlowBase(a,g,f),y=g.showLqi??this._config.show_signal??!0,b=this._config.icon_size??2.5,w=b>8?2.5:b,k=k_(w);let x=d?this._renderIsoScene:null,S=this._viewOr(this._baseVb(h,x)),$=null;try{$=u?.resolveIsoFramePresentation({projection:h,display:g,scene:x,openings:this._openingsR,amountOf:e=>this._openingAmt(e),cellCm:this._cellCm,overlays:e=>this._isoOverlayScene(a,_,S,g,e,x,w,k,y)})??null}catch(e){this._latchIsoFallback(g.showBorders?x?.key||this._isoInvalidKey():`${a.id}|no-borders`,e),this._cancelCameraTransition(!1),h="flat",d=!1,x=null,$=null,this._renderProjection="flat",this._renderIsoScene=null,this._isoProjectionSnapshot="flat",this._view=null,this._viewModeSnap=null,S=this._viewOr(this._baseVb("flat",null))}const M=$?.layers??null,R=$?.overlays??null,C=this._editing?"":this._stageBg(g),T=this._opMeasureView,D="view"===this._mode?this._editorChromeMode:this._mode,A=this._roomHoverPaths(a),P=a.bg?this._display(a.bg.href):"",F=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,z=this._modeTransitionVisual,I=this._dayCycleState(),O=z?.viewWeight??("view"===this._mode?1:0),E=this._modeTransition.state?.from.presentedMode,N=!this._markup||!!z&&("view"===z.presentedMode||"devices"===z.presentedMode||"view"===E||"devices"===E),H=z?.stageColor||C,L=z?.sceneBrightness??1;return j` this._markupClick(e)} @wheel=${e=>this._onWheel(e)} @pointerdown=${e=>{this._notePointer(e),this._stagePointerDown(e)}} @@ -683,7 +683,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointerleave=${e=>this._stagePointerLeave(e)} @pointerup=${e=>this._stagePointerUp(e)} @pointercancel=${e=>this._stagePointerCancel(e)}> - ${kr(I,O)} + ${xr(I,O)} ${this._editorRuntime?this._renderEditorSecondary():G}
    + transform=${d?hf():G}> ${""} ${this._wallHatchDefs(g.color)}${W`${this._paperShapes(a.rooms).map(e=>"path"in e?W``:"poly"in e?W``:W``)}`} ${this._editing?this._renderMarkupDefs(c):G} @@ -792,20 +792,20 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${$?.raised??G} `:G)} ${""} -
    +
    ${function(e,t,i){const n=[...e];if(!n.length)return G;const r=[],o=[],s=[];for(const e of n){for(const t of e.zones){if(!(!0===t.state||"number"==typeof t.state&&t.state>0)||!t.polygon)continue;const e=t.polygon.map(e=>i([1e3*e[0],1e3*e[1]]));s.push(W``${e[0]},${e[1]}`).join(" ")}>`)}for(const t of e.ranges)if(t.segments)for(const e of t.segments){const t=e.map(e=>i([1e3*e[0],1e3*e[1]]));o.push(W``${e[0]},${e[1]}`).join(" ")}>`)}for(const n of e.targets){if(!n.included)continue;const o=i([1e3*n.x,1e3*n.y]),s=(o[0]-t.x)/t.w*100,a=(o[1]-t.y)/t.h*100;r.push(j``)}}return o.length||s.length||r.length?j`${o.length||s.length?W``:G}${r}`:G}([...this._radarLive.frames.values()].filter(e=>{const t=this._serverCfg?.markers.find(t=>t.id===e.marker_id);return!!t&&Mg(t,this._space)}),S,e=>this._scenePoint(e))} + aria-hidden="true">${s}${o}`:G}${r}`:G}([...this._radarLive.frames.values()].filter(e=>{const t=this._serverCfg?.markers.find(t=>t.id===e.marker_id);return!!t&&Rg(t,this._space)}),S,e=>this._scenePoint(e))} ${Re(a.id,Te(_,e=>e.id,e=>this._renderDevice(e,S,y,R?.devices.get(e.id))))} ${this._renderVacuums(this._renderVacuumDevices,S,a.id)} ${this._renderVacFit(S)} ${this._renderOpeningLocks(S,R?.locks)} ${g.showNames||this._markup?a.rooms.map(e=>this._renderRoomLabel(e,a,S,g,R?.rooms.get(e))):G} ${this._markup?a.rooms.map(e=>this._renderRoomGear(e,a,S)):G} - ${B={hass:this.hass,settings:this._settings,devices:this._renderDevices,registry:this._haRegistry,currentSpace:a.id,spaces:this._serverCfg?.spaces,viewKey:S,view:"view"===this._mode,kiosk:this._kiosk},B.view&&!B.kiosk&&!0===B.hass?.user?.is_admin&&Pg(B.settings).enabled?(import("./hp-zigbee-topology-overlay-D3IWAxB8.js"),j``):G}
    @@ -903,16 +903,16 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 `:G} ${this._toast?j``:G} - `;var B}_vacCandidateStatus(e,t,i=this._planHass){const n=this._bindingStatus("entity:"+e);if("ha_disabled"===n.kind)return"disabled";if("orphaned"===n.kind)return"missing";if("unverified"===n.kind)return"unverified";const r=i?.states?.[e];return"unavailable"===r?.state?"unavailable":t?.hasPosition?"ok":"unsupported"}_vacOpenAllCameras(e){const t=this._haRegistry.entities||{},i=[];for(const[e,n]of Object.entries(this.hass?.states||{})){if(!e.startsWith("camera."))continue;const r=Uc(e,n,t[e]);r&&i.push(r)}this._vacAllCameraCache={devId:e.id,candidates:i},this._vacAllCamerasFor=e.id}_vacSourceResolution(e,t=!1,i=this._planHass){const n=e.marker?.vacuum,r="string"==typeof n?.source&&!!n.source,o=new Set(e.entities||[]),s=new Set(o);r&&s.add(n.source);const a=i?.entities||{},l=[];for(const e of s){const t=i?.states?.[e],o=Uc(e,t,a[e]);o?l.push(o):r&&e===n.source&&l.push({entityId:e,name:String(t?.attributes?.friendly_name||e),platform:a[e]?.platform?String(a[e].platform):null,category:e.startsWith("camera.")?"camera":"partial",hasPosition:!1,hasRooms:!1,hasPath:!1,hasMapId:!1,score:0})}if(t&&this._vacAllCameraCache?.devId===e.id){const e=new Set(l.map(e=>e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,n){const r="string"==typeof e&&e.length>0,o=new Set(t),s=Array.from(i).sort((t,i)=>r&&t.entityId===e?-1:r&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(r){const t=s.find(t=>t.entityId===e);return{entityId:e,status:n[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:s}}const a=s.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===n[e.entityId]);return a?{entityId:a.entityId,status:"ok",pinned:!1,candidates:s}:{entityId:null,status:"none",pinned:!1,candidates:s}}(n?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=Id(this._planHass,this._devices,null,this._virtualLights)){const i=s_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:c_(this._planHass,e,i)}}_stampActivity(e,t,i){let n=this._activityRt.get(e);n||(n=eg(i||"",[]),this._activityRt.set(e,n)),null!=i&&(n.sources=i),ig(n,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=Id(this._planHass,this._devices,null,this._virtualLights);for(const n of this._devices){if(n.hidden)continue;if("icon_ripple"!==Li(n.marker?.display))continue;t.add(n.id);const r=this._activitySnapshot(n,i);e.set(n.id,r);const{samples:o,sourceKey:s}=r;let a=this._activityRt.get(n.id);a?a.sources!==s&&tg(a,s,o,window.clearTimeout.bind(window)):(a=eg(s,o),this._activityRt.set(n.id,a))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Li(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:n,sourceKey:r}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==r)continue;const s=ng(o,n,window.clearTimeout.bind(window));s&&this._stampActivity(t.id,s,r)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Li(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),n=Xc(this.hass.states[i||""]?.state),r=qc(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),n&&!o.moving&&(o.trail=[],o.lastPos=null);const s="never"!==ih(e.marker?.vacuum)&&!r?.path.length;!n&&o.moving&&(o.endedTs=Date.now(),s&&o.lastPos&&(o.trail=Yc(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=n;const a=r?.pos;if(n&&a){const e=a.x+":"+a.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,s&&o.lastPos&&(o.trail=Yc(o.trail,o.lastPos,40)),o.lastPos=[a.x,a.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const n={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(n),n}_renderVacSection(e){return this._editorRuntimeOrThrow()._renderVacSection(e)}_vacMapId(e,t,i=this._planHass){const n=this._vacEntity(e),r=n?i?.states?.[n]?.attributes?.selected_map:null;return o=t.mapId,s=r,"default"!==o?o:null!=s?String(s):"default";var o,s}_vacObservedMapId(e,t,i=this._planHass){const n=qc(i?.states?.[t]?.attributes);return n?this._vacMapId(e,n,i):void 0}_vacSaveMatrix(e,t,i,n,r=""){return this._editorRuntimeOrThrow()._vacSaveMatrix(e,t,i,n,r)}_vacPlanRoomAnchors(e){return this._editorRuntimeOrThrow()._vacPlanRoomAnchors(e)}_vacAutoCalibrate(e){return this._editorRuntimeOrThrow()._vacAutoCalibrate(e)}_vacApplyCalibrationProposal(e){return this._editorRuntimeOrThrow()._vacApplyCalibrationProposal(e)}_vacStartFit(e){return this._editorRuntimeOrThrow()._vacStartFit(e)}_vacFitSave(){return this._editorRuntimeOrThrow()._vacFitSave()}_vacFitTurn(e){return this._editorRuntimeOrThrow()._vacFitTurn(e)}_vacGhostCentre(e){return this._editorRuntimeOrThrow()._vacGhostCentre(e)}_vacDelta(e,t,i){return this._editorRuntimeOrThrow()._vacDelta(e,t,i)}_vacFitPointer(e,t){return this._editorRuntimeOrThrow()._vacFitPointer(e,t)}_renderVacFit(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderVacFit(e):G}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,n=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!n.length)return void(this._vacRaf=0);const r=t.getBoundingClientRect();for(const t of n){const n=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),s=i.x+(o.left+o.width/2-r.left)/r.width*i.w,a=i.y+(o.top+o.height/2-r.top)/r.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${n}"]`))t.setAttribute("x2",s.toFixed(1)),t.setAttribute("y2",a.toFixed(1))}this._vacRafLoop()})}_vacTrailPathD(e,t){const i=e.map(e=>e.map(([e,i])=>Ac(t,e,i))),n=function(e,t,i=console.warn){if(!Number.isFinite(t)||t<=0)return[];const n=[];let r=0;for(const i of e){if(!i.every(Lc)){r++;continue}const e=i.filter((e,t)=>0===t||!Bc(e,i[t-1]));if(e.length<2)continue;const o=[{kind:"move",point:e[0]}];if(2!==e.length){for(let i=1;i0&&i(`[houseplan] vacuum trail: ${r} segment(s) dropped — non-finite point (check map calibration)`),n}(i,this._cmToUnits(17.5)),r=e=>{const t=this._scenePoint(e);return`${t[0].toFixed(1)} ${t[1].toFixed(1)}`};return n.map(e=>e.map(e=>"move"===e.kind?`M ${r(e.point)}`:"line"===e.kind?`L ${r(e.point)}`:`Q ${r(e.control)} ${r(e.point)}`).join(" ")).join(" ")}_renderVacuums(e,t,i){if(this._markup||"decor"===this._mode)return G;const n=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,r=this._vacJumpOnce||n!==this._vacViewKey;this._vacViewKey=n,this._vacJumpOnce=!1;const o=[],s=[];for(const n of e){if(n.hidden||!this._isVacDev(n))continue;if("static_icon"===Li(n.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${n.id}`),a=e?.source??this._vacSource(n,this._renderPlanHass);if(!a)continue;const l=e?.telemetry??qc(this._renderPlanHass?.states[a]?.attributes);if(!l)continue;const c=e?.routes??sh(n.id,n.marker?.vacuum??null,n.space,a),h=e?.resolution??lh({routes:c,observed:ch(c,[a],e=>this._vacObservedMapId(n,e)),spaceIds:new Set(this._model.map(e=>e.id))}),d=e?.server??this._vacSrvTrails[n.id],u=dh({resolution:h,routes:c,renderSpace:i,rootSource:n.marker?.vacuum?.source??null,serverCurrent:d?.current??null,serverPrevious:d?.previous??null,explicitRoutes:Array.isArray(n.marker?.vacuum?.map_routes)});if(!u.live&&!u.previous)continue;const p=u.live,_=e?.runtime??this._vacRt.get(n.id),m=_?.moving??!1,g=ih(n.marker?.vacuum),f="always"===g||"cleaning"===g&&m,v=d,y=u.currentRunMatches&&Array.isArray(v?.current?.points)?v.current:null,b=u.previous&&Array.isArray(v?.previous?.points)?v.previous:null;if("always"===g&&b&&u.previous){const e=Ec(b.points),t=this._vacTrailPathD(e,u.previous);t&&s.push(W``)}if(f&&p){const e=Nc(l,y,_?.trail||[]),t=!m||"integration"!==e.source&&"server"!==e.source?e.path:Hc(e.path);if(t.length){const e=this._vacTrailPathD(t,p);e&&s.push(W``);const i=t[t.length-1];if(m&&i?.length>=2){const e=i[i.length-1],[t,r]=Ac(p,e[0],e[1]),o=this._scenePoint([t,r]),a=o[0].toFixed(1),l=o[1].toFixed(1);s.push(W``)}}}if(!m||!l.pos||!p)continue;const[w,k]=Ac(p,l.pos.x,l.pos.y),x=this._scenePoint([w,k]),S=(x[0]-t.x)/t.w*100,$=(x[1]-t.y)/t.h*100,M=_&&_.lastTs>0&&Date.now()-_.lastTs>6e4,R=n.marker?.icon||n.icon||"mdi:robot-vacuum";o.push(j`
    e.entityId));for(const t of this._vacAllCameraCache.candidates)e.has(t.entityId)||l.push(t)}const c={};for(const e of l)c[e.entityId]=this._vacCandidateStatus(e.entityId,e,i);return function(e,t,i,n){const r="string"==typeof e&&e.length>0,o=new Set(t),s=Array.from(i).sort((t,i)=>r&&t.entityId===e?-1:r&&i.entityId===e?1:i.score-t.score||t.entityId.localeCompare(i.entityId));if(r){const t=s.find(t=>t.entityId===e);return{entityId:e,status:n[e]||(t?.hasPosition?"ok":"unverified"),pinned:!0,candidates:s}}const a=s.find(e=>o.has(e.entityId)&&e.hasPosition&&"ok"===n[e.entityId]);return a?{entityId:a.entityId,status:"ok",pinned:!1,candidates:s}:{entityId:null,status:"none",pinned:!1,candidates:s}}(n?.source,o,l,c)}_vacSource(e,t=this._planHass){if(!1===e.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(e,!1,t);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(e){return e.primary?.startsWith("vacuum.")?e.primary:(e.entities||[]).find(e=>e.startsWith("vacuum."))||null}_isVacDev(e){return!!this._vacEntity(e)}_activitySourceKey(e){return this._activitySnapshot(e).sourceKey}_activitySnapshot(e,t=Od(this._planHass,this._devices,null,this._virtualLights)){const i=a_(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:h_(this._planHass,e,i)}}_stampActivity(e,t,i){let n=this._activityRt.get(e);n||(n=tg(i||"",[]),this._activityRt.set(e,n)),null!=i&&(n.sources=i),ng(n,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivityRuntime(){const e=new Map;if(!this.hass)return e;if(!1===this._config?.live_states){for(const e of this._activityRt.values())clearTimeout(e.timer);return this._activityRt.clear(),e}const t=new Set,i=Od(this._planHass,this._devices,null,this._virtualLights);for(const n of this._devices){if(n.hidden)continue;if("icon_ripple"!==Li(n.marker?.display))continue;t.add(n.id);const r=this._activitySnapshot(n,i);e.set(n.id,r);const{samples:o,sourceKey:s}=r;let a=this._activityRt.get(n.id);a?a.sources!==s&&ig(a,s,o,window.clearTimeout.bind(window)):(a=tg(s,o),this._activityRt.set(n.id,a))}for(const[e,i]of this._activityRt)t.has(e)||(clearTimeout(i.timer),this._activityRt.delete(e));return e}_activityTick(){if(!this.hass)return;const e=this._syncActivityRuntime();for(const t of this._devices){if(t.hidden)continue;if("icon_ripple"!==Li(t.marker?.display))continue;const i=e.get(t.id)||this._activitySnapshot(t),{samples:n,sourceKey:r}=i,o=this._activityRt.get(t.id);if(!o||o.sources!==r)continue;const s=rg(o,n,window.clearTimeout.bind(window));s&&this._stampActivity(t.id,s,r)}}_vacTick(){if(this.hass)for(const e of this._devices){if(e.hidden||!this._isVacDev(e))continue;if("static_icon"===Li(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),n=Zc(this.hass.states[i||""]?.state),r=jc(this.hass.states[t]?.attributes);let o=this._vacRt.get(e.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(e.id,o)),n&&!o.moving&&(o.trail=[],o.lastPos=null);const s="never"!==nh(e.marker?.vacuum)&&!r?.path.length;!n&&o.moving&&(o.endedTs=Date.now(),s&&o.lastPos&&(o.trail=Xc(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=n;const a=r?.pos;if(n&&a){const e=a.x+":"+a.y;if(e!==o.lastKey){const t=Date.now();o.jump=o.lastTs>0&&t-o.lastTs>1e4,o.lastKey=e,o.lastTs=t,s&&o.lastPos&&(o.trail=Xc(o.trail,o.lastPos,40)),o.lastPos=[a.x,a.y]}}}}_vacEnsureMarker(e){const t=this._serverCfg;if(!t)return null;t.markers=t.markers||[];const i=t.markers.find(t=>t.id===e.id);if(i)return i;if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return null;const n={id:e.id,binding:e.bindingKind+":"+e.bindingRef,space:e.space||null,area:e.area||null,hidden:!!e.hidden};return t.markers.push(n),n}_renderVacSection(e){return this._editorRuntimeOrThrow()._renderVacSection(e)}_vacMapId(e,t,i=this._planHass){const n=this._vacEntity(e),r=n?i?.states?.[n]?.attributes?.selected_map:null;return o=t.mapId,s=r,"default"!==o?o:null!=s?String(s):"default";var o,s}_vacObservedMapId(e,t,i=this._planHass){const n=jc(i?.states?.[t]?.attributes);return n?this._vacMapId(e,n,i):void 0}_vacSaveMatrix(e,t,i,n,r=""){return this._editorRuntimeOrThrow()._vacSaveMatrix(e,t,i,n,r)}_vacPlanRoomAnchors(e){return this._editorRuntimeOrThrow()._vacPlanRoomAnchors(e)}_vacAutoCalibrate(e){return this._editorRuntimeOrThrow()._vacAutoCalibrate(e)}_vacApplyCalibrationProposal(e){return this._editorRuntimeOrThrow()._vacApplyCalibrationProposal(e)}_vacStartFit(e){return this._editorRuntimeOrThrow()._vacStartFit(e)}_vacFitSave(){return this._editorRuntimeOrThrow()._vacFitSave()}_vacFitTurn(e){return this._editorRuntimeOrThrow()._vacFitTurn(e)}_vacGhostCentre(e){return this._editorRuntimeOrThrow()._vacGhostCentre(e)}_vacDelta(e,t,i){return this._editorRuntimeOrThrow()._vacDelta(e,t,i)}_vacFitPointer(e,t){return this._editorRuntimeOrThrow()._vacFitPointer(e,t)}_renderVacFit(e){return this._editorRuntime?this._editorRuntimeOrThrow()._renderVacFit(e):G}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const e=this.renderRoot,t=this._stageEl,i=this._vacLastView,n=e?.querySelectorAll?.(".vacpuck")||[];if(!t||!i||!n.length)return void(this._vacRaf=0);const r=t.getBoundingClientRect();for(const t of n){const n=t.getAttribute("data-mid"),o=t.getBoundingClientRect(),s=i.x+(o.left+o.width/2-r.left)/r.width*i.w,a=i.y+(o.top+o.height/2-r.top)/r.height*i.h;for(const t of e.querySelectorAll(`line.tip[data-mid="${n}"]`))t.setAttribute("x2",s.toFixed(1)),t.setAttribute("y2",a.toFixed(1))}this._vacRafLoop()})}_vacTrailPathD(e,t){const i=e.map(e=>e.map(([e,i])=>Pc(t,e,i))),n=function(e,t,i=console.warn){if(!Number.isFinite(t)||t<=0)return[];const n=[];let r=0;for(const i of e){if(!i.every(Bc)){r++;continue}const e=i.filter((e,t)=>0===t||!qc(e,i[t-1]));if(e.length<2)continue;const o=[{kind:"move",point:e[0]}];if(2!==e.length){for(let i=1;i0&&i(`[houseplan] vacuum trail: ${r} segment(s) dropped — non-finite point (check map calibration)`),n}(i,this._cmToUnits(17.5)),r=e=>{const t=this._scenePoint(e);return`${t[0].toFixed(1)} ${t[1].toFixed(1)}`};return n.map(e=>e.map(e=>"move"===e.kind?`M ${r(e.point)}`:"line"===e.kind?`L ${r(e.point)}`:`Q ${r(e.control)} ${r(e.point)}`).join(" ")).join(" ")}_renderVacuums(e,t,i){if(this._markup||"decor"===this._mode)return G;const n=this._space+"|"+t.x+"|"+t.y+"|"+t.w+"|"+t.h,r=this._vacJumpOnce||n!==this._vacViewKey;this._vacViewKey=n,this._vacJumpOnce=!1;const o=[],s=[];for(const n of e){if(n.hidden||!this._isVacDev(n))continue;if("static_icon"===Li(n.marker?.display))continue;const e=this._renderDeviceSnapshot?.facts.get(`vacuum:${n.id}`),a=e?.source??this._vacSource(n,this._renderPlanHass);if(!a)continue;const l=e?.telemetry??jc(this._renderPlanHass?.states[a]?.attributes);if(!l)continue;const c=e?.routes??ah(n.id,n.marker?.vacuum??null,n.space,a),h=e?.resolution??ch({routes:c,observed:hh(c,[a],e=>this._vacObservedMapId(n,e)),spaceIds:new Set(this._model.map(e=>e.id))}),d=e?.server??this._vacSrvTrails[n.id],u=uh({resolution:h,routes:c,renderSpace:i,rootSource:n.marker?.vacuum?.source??null,serverCurrent:d?.current??null,serverPrevious:d?.previous??null,explicitRoutes:Array.isArray(n.marker?.vacuum?.map_routes)});if(!u.live&&!u.previous)continue;const p=u.live,_=e?.runtime??this._vacRt.get(n.id),m=_?.moving??!1,g=nh(n.marker?.vacuum),f="always"===g||"cleaning"===g&&m,v=d,y=u.currentRunMatches&&Array.isArray(v?.current?.points)?v.current:null,b=u.previous&&Array.isArray(v?.previous?.points)?v.previous:null;if("always"===g&&b&&u.previous){const e=Nc(b.points),t=this._vacTrailPathD(e,u.previous);t&&s.push(W``)}if(f&&p){const e=Hc(l,y,_?.trail||[]),t=!m||"integration"!==e.source&&"server"!==e.source?e.path:Lc(e.path);if(t.length){const e=this._vacTrailPathD(t,p);e&&s.push(W``);const i=t[t.length-1];if(m&&i?.length>=2){const e=i[i.length-1],[t,r]=Pc(p,e[0],e[1]),o=this._scenePoint([t,r]),a=o[0].toFixed(1),l=o[1].toFixed(1);s.push(W``)}}}if(!m||!l.pos||!p)continue;const[w,k]=Pc(p,l.pos.x,l.pos.y),x=this._scenePoint([w,k]),S=(x[0]-t.x)/t.w*100,$=(x[1]-t.y)/t.h*100,M=_&&_.lastTs>0&&Date.now()-_.lastTs>6e4,R=n.marker?.icon||n.icon||"mdi:robot-vacuum";o.push(j`
    {e.stopPropagation();const t=this._vacEntity(n);t&&this._openMoreInfo(t)}}>
    `)}return this._vacLastView=t,o.length&&!this._vacRaf&&this._vacRafLoop(),o.length||s.length?j` ${s.length?W`${s}`:G} - ${o}`:G}_renderDevice(e,t,i=!0,n){const r=this._pos(e),o=n?.visualScene??this._scenePoint([r.x,r.y]),s=(o[0]-t.x)/t.w*100,a=(o[1]-t.y)/t.h*100,l=this._devicePresentation(e,i),c=[`left:${s}%`,`top:${a}%`,...v_(l)],h=l.disabledReason,d=l.haDisabled?this._t(`marker.ha_disabled_${h}`):e.userHidden?this._t("marker.hidden_ghost"):e.name,u=e_(l),p="view"===this._mode||"devices"===this._mode,_=Qp([d,l.haDisabled?"":this._t(`marker.state_a11y_${u}`),"none"!==l.pulse.kind?this._t(`marker.pulse_a11y_${l.pulse.reason}`):"",l.valueFullText||l.valueText||"",Pp(l.valueBadge),null!=l.lqiText&&l.lqiBand?this._t(`marker.lqi_a11y_${l.lqiBand}`,{value:l.lqiText}):""]);return j`
    this._clickDevice(t,e)} @keydown=${t=>this._keyDevice(t,e)} @@ -945,10 +945,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointercancel=${t=>this._pointerCancel(t,e)} @lostpointercapture=${t=>this._pointerCancel(t,e)} > - ${b_(l,{newDevice:this._newIds.has(e.id),newDeviceTitle:this._t("device.new"),disabledTitle:l.haDisabled?d:""})} + ${w_(l,{newDevice:this._newIds.has(e.id),newDeviceTitle:this._t("device.new"),disabledTitle:l.haDisabled?d:""})} ${this._vacRouteBadge(e)}
    `}_vacRouteBadge(e){if(!this._isVacDev(e)||e.hidden)return G;if("static_icon"===Li(e.marker?.display))return G;const t=this._renderDeviceSnapshot?.facts.get(`vacuum:${e.id}`),i=function(e,t){if(!t||!e)return null;switch(e.kind){case"unmapped":case"needs_calibration":case"ambiguous":case"missing_space":return e.kind;default:return null}}(t?.resolution,this._vacRt.get(e.id)?.moving??!1);if(!i)return G;const n=this._t(`vac.route_warn_${i}`);return j` - `}_roomArea(e){const t=ni(e);if(!t)return null;const i=this._spaceModel();if(!i)return null;const n=this._spaceWalls.length&&e.id&&this._innerRoomContour(i,e.id)||t,r=this._cleanFloor(e,n),o=this._cellCm/this._gridPitch;return Xn(r.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source,i=ru(this._spaceModel()?.id,e);return t?iu(this._renderPlanHass,t,"temp",this._markers):i?this._climate().get(i)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source,i=ru(this._spaceModel()?.id,e);return t?iu(this._renderPlanHass,t,"hum",this._markers):i?this._climate().get(i)?.hum??null:null}_climate(){const e=this._serverCfg?.markers,t=this._renderPlanHass,i=this._climateCache,n=this._settings.exclude_integrations;if(i&&i.h===t&&i.r===this._iconRules&&i.mk===e&&i.ex===n)return i.m;const r=au(t,this._iconRules,e,this._excluded);return this._climateCache={h:t,r:this._iconRules,mk:e,ex:n,m:r},r}_resetRoomDialogFields(){return this._editorRuntimeOrThrow()._resetRoomDialogFields()}_openRoomEdit(e){return this._editorRuntimeOrThrow()._openRoomEdit(e)}_roomSettingsFromDialog(){return this._editorRuntimeOrThrow()._roomSettingsFromDialog()}_saveRoomEdit(){return this._editorRuntimeOrThrow()._saveRoomEdit()}_roomSrcCandidates(){return this._editorRuntimeOrThrow()._roomSrcCandidates()}_roomSrcLabel(e){return this._editorRuntimeOrThrow()._roomSrcLabel(e)}_labelPos(e,t){const i=this._layout["rl_"+(e.id||"")];if(i&&i.s===t)return{x:i.x*uv,y:i.y*uv};const n=this._roomCenter(e),r=this._gridPitch;return{x:nl(Qt(n[0],r)),y:nl(Qt(n[1],r))}}_labelDown(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelDown(e,t,i)}_labelMove(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelMove(e,t,i)}_labelUp(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelUp(e)}_labelScale(e){const t=this._layout["rl_"+(e.id||"")]?.k;return"number"==typeof t&&Number.isFinite(t)?Math.min(3,Math.max(.5,t)):1}_rlResizeDown(e,t,i){return this._editorRuntimeOrThrow()._rlResizeDown(e,t,i)}_rlResizeMove(e){return this._editorRuntimeOrThrow()._rlResizeMove(e)}_rlResizeUp(){return this._editorRuntimeOrThrow()._rlResizeUp()}_renderRoomGear(e,t,i){return this._editorRuntimeOrThrow()._renderRoomGear(e,t,i)}_renderRoomLabel(e,t,i,n,r){if(!e.name&&!this._markup)return G;const o=this._labelPos(e,t.id),s=r?.visualScene??this._scenePoint([o.x,o.y]),a=(s[0]-i.x)/i.w*100,l=(s[1]-i.y)/i.h*100,c=Math.min(1,n.opacity+.25),h=this._labelScale(e),d=[];if(n.labelTemp||n.labelHum||n.labelLqi&&e.area||n.labelLight){if(n.labelTemp){const t=this._roomTemp(e);null!=t&&d.push(j`${t}°`)}if(n.labelHum){const t=this._roomHum(e);null!=t&&d.push(j`${t}%`)}if(n.labelLqi&&e.area){const t=this._roomLqi(e.area);null!=t&&d.push(j`${t}`)}if(n.labelLight){const t=(u=Id(this._renderPlanHass,this._renderDevices,e,this._virtualLights)).length?{on:u.filter(e=>e.on).length,total:u.length}:null;if(t){const e=0===t.on?this._t("roomcard.light_off"):t.on===t.total?this._t("roomcard.light_on"):this._t("roomcard.light_partial",{on:t.on,total:t.total});d.push(j`${e}`)}}}var u;const p=!!e.area,_=!this._markup;return j`
    `}_roomArea(e){const t=ni(e);if(!t)return null;const i=this._spaceModel();if(!i)return null;const n=this._spaceWalls.length&&e.id&&this._innerRoomContour(i,e.id)||t,r=this._cleanFloor(e,n),o=this._cellCm/this._gridPitch;return Xn(r.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source,i=ou(this._spaceModel()?.id,e);return t?nu(this._renderPlanHass,t,"temp",this._markers):i?this._climate().get(i)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source,i=ou(this._spaceModel()?.id,e);return t?nu(this._renderPlanHass,t,"hum",this._markers):i?this._climate().get(i)?.hum??null:null}_climate(){const e=this._serverCfg?.markers,t=this._renderPlanHass,i=this._climateCache,n=this._settings.exclude_integrations;if(i&&i.h===t&&i.r===this._iconRules&&i.mk===e&&i.ex===n)return i.m;const r=lu(t,this._iconRules,e,this._excluded);return this._climateCache={h:t,r:this._iconRules,mk:e,ex:n,m:r},r}_resetRoomDialogFields(){return this._editorRuntimeOrThrow()._resetRoomDialogFields()}_openRoomEdit(e){return this._editorRuntimeOrThrow()._openRoomEdit(e)}_roomSettingsFromDialog(){return this._editorRuntimeOrThrow()._roomSettingsFromDialog()}_saveRoomEdit(){return this._editorRuntimeOrThrow()._saveRoomEdit()}_roomSrcCandidates(){return this._editorRuntimeOrThrow()._roomSrcCandidates()}_roomSrcLabel(e){return this._editorRuntimeOrThrow()._roomSrcLabel(e)}_labelPos(e,t){const i=this._layout["rl_"+(e.id||"")];if(i&&i.s===t)return{x:i.x*pv,y:i.y*pv};const n=this._roomCenter(e),r=this._gridPitch;return{x:rl(Qt(n[0],r)),y:rl(Qt(n[1],r))}}_labelDown(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelDown(e,t,i)}_labelMove(e,t,i){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelMove(e,t,i)}_labelUp(e){if(this._editorRuntime)return this._editorRuntimeOrThrow()._labelUp(e)}_labelScale(e){const t=this._layout["rl_"+(e.id||"")]?.k;return"number"==typeof t&&Number.isFinite(t)?Math.min(3,Math.max(.5,t)):1}_rlResizeDown(e,t,i){return this._editorRuntimeOrThrow()._rlResizeDown(e,t,i)}_rlResizeMove(e){return this._editorRuntimeOrThrow()._rlResizeMove(e)}_rlResizeUp(){return this._editorRuntimeOrThrow()._rlResizeUp()}_renderRoomGear(e,t,i){return this._editorRuntimeOrThrow()._renderRoomGear(e,t,i)}_renderRoomLabel(e,t,i,n,r){if(!e.name&&!this._markup)return G;const o=this._labelPos(e,t.id),s=r?.visualScene??this._scenePoint([o.x,o.y]),a=(s[0]-i.x)/i.w*100,l=(s[1]-i.y)/i.h*100,c=Math.min(1,n.opacity+.25),h=this._labelScale(e),d=[];if(n.labelTemp||n.labelHum||n.labelLqi&&e.area||n.labelLight){if(n.labelTemp){const t=this._roomTemp(e);null!=t&&d.push(j`${t}°`)}if(n.labelHum){const t=this._roomHum(e);null!=t&&d.push(j`${t}%`)}if(n.labelLqi&&e.area){const t=this._roomLqi(e.area);null!=t&&d.push(j`${t}`)}if(n.labelLight){const t=(u=Od(this._renderPlanHass,this._renderDevices,e,this._virtualLights)).length?{on:u.filter(e=>e.on).length,total:u.length}:null;if(t){const e=0===t.on?this._t("roomcard.light_off"):t.on===t.total?this._t("roomcard.light_on"):this._t("roomcard.light_partial",{on:t.on,total:t.total});d.push(j`${e}`)}}}var u;const p=!!e.area,_=!this._markup;return j`
    ${r.text}
    `:G} `}get _measureAnchor(){return this._markup&&this._cursorPt?"draw"===this._tool&&this._path.length&&!this._contourClosed?this._path[this._path.length-1]:"split"===this._tool&&this._splitSel?.pts?.length?this._splitSel.pts[this._splitSel.pts.length-1]:null:null}_renderMeasureLabel(e){const t=this._measureAnchor,i=this._cursorPt,n=(i[0]-e.x)/e.w*100,r=(i[1]-e.y)/e.h*100,o=jn(t,i),s=Math.round(10*o)/10,a=function(e,t,i=.001){if(e.length<2||t.length<2)return!1;const n=Math.abs(t[0]-e[0]),r=Math.abs(t[1]-e[1]);if(!Number.isFinite(n)||!Number.isFinite(r)||Math.hypot(n,r)<=i)return!1;const o=Math.max(n,r,1);return n<=i*o||r<=i*o||Math.abs(n-r)<=i*o}(t,i,2e-4*this._gridPitch);return j`
    - ${this._fmtLen(t,i)} · ${s}°
    `}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[n,r]=e.b;if(Math.abs(t-n)<1e-6&&Math.abs(i-r)<1e-6)return null;const o=(t+n)/2,s=(i+r)/2;if("line"===e.kind){const t=jn(e.a,e.b);return{x:o,y:s,on45:Wn(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const a=this._fmtLen([t,i],[n,i]),l=this._fmtLen([n,i],[n,r]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(n-t)/2,0]),a=this._fmtLen([0,0],[0,Math.abs(r-i)/2]);return{x:o,y:s,on45:!1,text:Math.abs(Math.abs(n-t)-Math.abs(r-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${a}`}}return{x:o,y:s,on45:!1,text:`${a} × ${l} · ${Xn(Tr(Math.abs(n-t),this._cellCm,this._gridPitch)*Tr(Math.abs(r-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._deviceDrag?.moved){const e=this._devices.find(e=>e.id===this._deviceDrag.id);return e?(()=>{const t=this._livePos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=uv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){return this._editorRuntimeOrThrow()._alignCandidates()}_renderAlignGuides(){return this._editorRuntime?._renderAlignGuides()??G}_renderOpeningCenterTick(e){return this._editorRuntimeOrThrow()._renderOpeningCenterTick(e)}_renderOpeningDimensionGuides(e){return this._editorRuntimeOrThrow()._renderOpeningDimensionGuides(e)}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]:null;return ci(e.type,t?.state,!!e.invert,t?.attributes?.current_position)}_planEntityAvailable(e){return!!e&&(!Xd(this._fullRegistryHass,e,Yd(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!Xd(this._renderPlanHass,e,Yd(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=td(e)){return!!t&&"active"===cd(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){return this._editorRuntimeOrThrow()._renderOpeningPlacementPreview()}_renderOpenings(e,t){const i=t?this._openingsR.filter(e=>t.includes(e.id)):this._openingsR;if(!i.length)return W``;const n=this._spaceModel();if(!n)return W``;const r=e.color,o=this._spaceWalls,s=this._openCuts(),a=this._openingWallIndexFor(n,s).value;return W`${Re(n.id,Te(i,e=>e.id,e=>{if(e.orphanReason)return W``}get _decorMeasure(){const e=this._decorDraft;if(!e||"decor"!==this._mode)return null;const[t,i]=e.a,[n,r]=e.b;if(Math.abs(t-n)<1e-6&&Math.abs(i-r)<1e-6)return null;const o=(t+n)/2,s=(i+r)/2;if("line"===e.kind){const t=jn(e.a,e.b);return{x:o,y:s,on45:Wn(t),text:`${this._fmtLen(e.a,e.b)} · ${Math.round(10*t)/10}°`}}const a=this._fmtLen([t,i],[n,i]),l=this._fmtLen([n,i],[n,r]);if("ellipse"===e.kind){const e=this._fmtLen([0,0],[Math.abs(n-t)/2,0]),a=this._fmtLen([0,0],[0,Math.abs(r-i)/2]);return{x:o,y:s,on45:!1,text:Math.abs(Math.abs(n-t)-Math.abs(r-i))<1e-6?`R ${e}`:`Rx ${e} × Ry ${a}`}}return{x:o,y:s,on45:!1,text:`${a} × ${l} · ${Xn(Dr(Math.abs(n-t),this._cellCm,this._gridPitch)*Dr(Math.abs(r-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const e=this._drag.id.slice(3),t=this._spaceModel()?.rooms.find(t=>t.id===e);return t?(()=>{const e=this._labelPos(t,this._space);return[e.x,e.y]})():null}return null}if("devices"===this._mode&&this._deviceDrag?.moved){const e=this._devices.find(e=>e.id===this._deviceDrag.id);return e?(()=>{const t=this._livePos(e);return[t.x,t.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const e=this._decorList.find(e=>e.id===this._decorMove.id);if(!e)return null;const t=pv,i=this._decorH;return"line"===e.kind?[e.x1*t,e.y1*i]:[e.x*t,e.y*i]}return null}return null}_alignCandidates(){return this._editorRuntimeOrThrow()._alignCandidates()}_renderAlignGuides(){return this._editorRuntime?._renderAlignGuides()??G}_renderOpeningCenterTick(e){return this._editorRuntimeOrThrow()._renderOpeningCenterTick(e)}_renderOpeningDimensionGuides(e){return this._editorRuntimeOrThrow()._renderOpeningDimensionGuides(e)}_roomCenter(e){if(e.poly){const t=e.poly.length;return[e.poly.reduce((e,t)=>e+t[0],0)/t,e.poly.reduce((e,t)=>e+t[1],0)/t]}return[e.x+e.w/2,e.y+.1*Math.min(e.w,e.h)]}_openingAmt(e){const t=e.contact&&this._renderOpeningEntityAvailable(e.contact)?this._renderPlanHass.states[e.contact]:null;return ci(e.type,t?.state,!!e.invert,t?.attributes?.current_position)}_planEntityAvailable(e){return!!e&&(!Zd(this._fullRegistryHass,e,Xd(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!Zd(this._renderPlanHass,e,Xd(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=id(e)){return!!t&&"active"===hd(e,`entity:${t}`,i).kind}(this.hass,e,this._haRegistry)}_renderOpeningEntityAvailable(e){return t=this._renderPlanHass,!!(i=e)&&!!t?.states?.[i];var t,i}_renderOpeningPlacementPreview(){return this._editorRuntimeOrThrow()._renderOpeningPlacementPreview()}_renderOpenings(e,t){const i=t?this._openingsR.filter(e=>t.includes(e.id)):this._openingsR;if(!i.length)return W``;const n=this._spaceModel();if(!n)return W``;const r=e.color,o=this._spaceWalls,s=this._openCuts(),a=this._openingWallIndexFor(n,s).value;return W`${Re(n.id,Te(i,e=>e.id,e=>{if(e.orphanReason)return W`{t.stopPropagation(),this._editOpening(e)}}> - + ! - `;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":r,n="gate"===e.type?!e.flip_v:e.flip_v,s=e.partitionHost||o.length||"gate"===e.type?this._openingFace(e,a,!!n):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:r,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:s},{half:c,outlineHalf:h,hitHalf:d}=$p(l),u=Ha(10,this._cellCm),p=Ha(12,this._cellCm);return W``;const t=this._openingAmt(e),i=t>0&&!!e.contact&&this._renderOpeningEntityAvailable(e.contact)?"var(--hp-open)":r,n="gate"===e.type?!e.flip_v:e.flip_v,s=e.partitionHost||o.length||"gate"===e.type?this._openingFace(e,a,!!n):{ox:0,oy:0,cm:0,side:-1},l={type:e.type,length:e.rlen,angle:e.angle,amount:t,flipH:!!e.flip_h,flipV:!!e.flip_v,base:r,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:s},{half:c,outlineHalf:h,hitHalf:d}=Mp(l),u=La(10,this._cellCm),p=La(12,this._cellCm);return W` - ${Dp(l)} + ${Ap(l)} + rx="${La(6,this._cellCm)}"> this._opClick(t,e)} @@ -1011,7 +1011,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointermove=${t=>this._opPointerMove(t,e)} @pointerup=${t=>this._opPointerUp(t,e)} @pointercancel=${t=>this._opPointerUp(t,e)}> - `}))}`}_renderOpeningLocks(e,t){const i=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!i.length)return j``;const n=this._spaceModel();if(!n)return j``;const r=this._openCuts(),o=this._openingWallIndexFor(n,r).value;return j`${i.map(i=>{const n=this._renderPlanHass.states[i.lock]?.state,r="locked"===n,s=r||["unlocked","open","opening","unlocking","locking"].includes(String(n)),a="gate"===i.type?this._openingFace(i,o,!i.flip_v):null,l=Sp({x:i.rx,y:i.ry,angle:i.angle,flipV:!!i.flip_v,gateFace:a},this._cellCm)[0],c=t?.get(String(i.id)),h=c?.visualScene??this._scenePoint(l),d=(h[0]-e.x)/e.w*100,u=(h[1]-e.y)/e.h*100;return j`
    `}))}`}_renderOpeningLocks(e,t){const i=this._openingsR.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&e.lock&&this._renderOpeningEntityAvailable(e.lock));if(!i.length)return j``;const n=this._spaceModel();if(!n)return j``;const r=this._openCuts(),o=this._openingWallIndexFor(n,r).value;return j`${i.map(i=>{const n=this._renderPlanHass.states[i.lock]?.state,r="locked"===n,s=r||["unlocked","open","opening","unlocking","locking"].includes(String(n)),a="gate"===i.type?this._openingFace(i,o,!i.flip_v):null,l=$p({x:i.rx,y:i.ry,angle:i.angle,flipV:!!i.flip_v,gateFace:a},this._cellCm)[0],c=t?.get(String(i.id)),h=c?.visualScene??this._scenePoint(l),d=(h[0]-e.x)/e.w*100,u=(h[1]-e.y)/e.h*100;return j`
    this._openingInfo=null}>${this._t("btn.close")}
    - `}_renderOpeningDialog(){return this._editorRuntimeOrThrow()._renderOpeningDialog()}_gridLevels(){return this._editorRuntimeOrThrow()._gridLevels()}_renderMarkupDefs(e){return this._editorRuntimeOrThrow()._renderMarkupDefs(e)}_renderPhysicalEditorLayer(){return this._editorRuntimeOrThrow()._renderPhysicalEditorLayer()}_renderHiddenWallDiagnosticOverlay(){return this._editorRuntimeOrThrow()._renderHiddenWallDiagnosticOverlay()}_renderPlanSnapOverlay(){return this._editorRuntimeOrThrow()._renderPlanSnapOverlay()}_syncPlanSnapActiveMarker(e){return this._editorRuntimeOrThrow()._syncPlanSnapActiveMarker(e)}_syncPlanSnapConflictMarkers(e){return this._editorRuntimeOrThrow()._syncPlanSnapConflictMarkers(e)}_planSnapPhysicalSegment(e){return this._editorRuntimeOrThrow()._planSnapPhysicalSegment(e)}_drawPreviewJoinPatchD(e,t){return this._editorRuntimeOrThrow()._drawPreviewJoinPatchD(e,t)}_renderMarkupLayer(e){return this._editorRuntimeOrThrow()._renderMarkupLayer(e)}_renderActiveChainInk(){return this._editorRuntimeOrThrow()._renderActiveChainInk()}_renderPartitionDeleteDialog(){return this._editorRuntimeOrThrow()._renderPartitionDeleteDialog()}_renderRoomDeleteDialog(){return this._editorRuntimeOrThrow()._renderRoomDeleteDialog()}_renderPhysicalDialog(){return this._editorRuntimeOrThrow()._renderPhysicalDialog()}_renderMarkupBar(){return this._editorRuntimeOrThrow()._renderMarkupBar()}_renderDevicesBar(){return this._editorRuntimeOrThrow()._renderDevicesBar()}_renderDeviceInbox(){return this._editorRuntimeOrThrow()._renderDeviceInbox()}_cardEntities(e){const t=this._planHass,i=[],n=new Set,r=e=>{if(!e||n.has(e)||!t.states[e])return;const r=t.entities[e];if("config"===r?.entity_category||"diagnostic"===r?.entity_category)return;n.add(e);const o=e.split(".")[0];["light","switch","fan","humidifier","siren","input_boolean"].includes(o)?i.push({eid:e,kind:"toggle"}):["cover","valve","lock","climate","media_player","vacuum","water_heater"].includes(o)?i.push({eid:e,kind:"open"}):["sensor","binary_sensor","number","select"].includes(o)&&i.push({eid:e,kind:"value"})};for(const i of Id(t,this._devices,null,this._virtualLights))if(i.device.id===e.id)for(const e of[...i.serviceEids,...i.stateEids])r(e);e.primary&&r(e.primary);for(const t of e.entities)r(t);return i.slice(0,12)}_cardToggle(e){const t=e.split(".")[0];"lock"!==t&&"alarm_control_panel"!==t&&this._planEntityAvailable(e)&&this.hass.callService("homeassistant","toggle",{entity_id:e}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))}_renderInfoCard(){const e=this._infoCard,t=e.primary?this.hass.states[e.primary]:void 0,i=t?Xi(this.hass,e.primary)?.text??t.state:null,n=$g(e.marker?.radar)?e.marker.radar:null,r=n?this._radarLive.frames.get(e.marker?.id||e.id):null,o=n?function(e,t){return!0!==e.enabled?"radar.health_disabled":Rg[t||""]||"radar.health_unknown"}(n,r?.health):null,s=(e.controls??e.marker?.controls??[]).filter(Dn).filter(e=>this._planEntityAvailable(e));return j``}_renderOpeningDialog(){return this._editorRuntimeOrThrow()._renderOpeningDialog()}_gridLevels(){return this._editorRuntimeOrThrow()._gridLevels()}_renderMarkupDefs(e){return this._editorRuntimeOrThrow()._renderMarkupDefs(e)}_renderPhysicalEditorLayer(){return this._editorRuntimeOrThrow()._renderPhysicalEditorLayer()}_renderHiddenWallDiagnosticOverlay(){return this._editorRuntimeOrThrow()._renderHiddenWallDiagnosticOverlay()}_renderPlanSnapOverlay(){return this._editorRuntimeOrThrow()._renderPlanSnapOverlay()}_syncPlanSnapActiveMarker(e){return this._editorRuntimeOrThrow()._syncPlanSnapActiveMarker(e)}_syncPlanSnapConflictMarkers(e){return this._editorRuntimeOrThrow()._syncPlanSnapConflictMarkers(e)}_planSnapPhysicalSegment(e){return this._editorRuntimeOrThrow()._planSnapPhysicalSegment(e)}_drawPreviewJoinPatchD(e,t){return this._editorRuntimeOrThrow()._drawPreviewJoinPatchD(e,t)}_renderMarkupLayer(e){return this._editorRuntimeOrThrow()._renderMarkupLayer(e)}_renderActiveChainInk(){return this._editorRuntimeOrThrow()._renderActiveChainInk()}_renderPartitionDeleteDialog(){return this._editorRuntimeOrThrow()._renderPartitionDeleteDialog()}_renderRoomDeleteDialog(){return this._editorRuntimeOrThrow()._renderRoomDeleteDialog()}_renderPhysicalDialog(){return this._editorRuntimeOrThrow()._renderPhysicalDialog()}_renderMarkupBar(){return this._editorRuntimeOrThrow()._renderMarkupBar()}_renderDevicesBar(){return this._editorRuntimeOrThrow()._renderDevicesBar()}_renderDeviceInbox(){return this._editorRuntimeOrThrow()._renderDeviceInbox()}_cardEntities(e){const t=this._planHass,i=[],n=new Set,r=e=>{if(!e||n.has(e)||!t.states[e])return;const r=t.entities[e];if("config"===r?.entity_category||"diagnostic"===r?.entity_category)return;n.add(e);const o=e.split(".")[0];["light","switch","fan","humidifier","siren","input_boolean"].includes(o)?i.push({eid:e,kind:"toggle"}):["cover","valve","lock","climate","media_player","vacuum","water_heater"].includes(o)?i.push({eid:e,kind:"open"}):["sensor","binary_sensor","number","select"].includes(o)&&i.push({eid:e,kind:"value"})};for(const i of Od(t,this._devices,null,this._virtualLights))if(i.device.id===e.id)for(const e of[...i.serviceEids,...i.stateEids])r(e);e.primary&&r(e.primary);for(const t of e.entities)r(t);return i.slice(0,12)}_cardToggle(e){const t=e.split(".")[0];"lock"!==t&&"alarm_control_panel"!==t&&this._planEntityAvailable(e)&&this.hass.callService("homeassistant","toggle",{entity_id:e}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))}_renderInfoCard(){const e=this._infoCard,t=e.primary?this.hass.states[e.primary]:void 0,i=t?Xi(this.hass,e.primary)?.text??t.state:null,n=Mg(e.marker?.radar)?e.marker.radar:null,r=n?this._radarLive.frames.get(e.marker?.id||e.id):null,o=n?function(e,t){return!0!==e.enabled?"radar.health_disabled":Cg[t||""]||"radar.health_unknown"}(n,r?.health):null,s=(e.controls??e.marker?.controls??[]).filter(Dn).filter(e=>this._planEntityAvailable(e));return j`
    @@ -1086,7 +1086,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    -
    `}_markerValueBadgeFields(e){return this._editorRuntimeOrThrow()._markerValueBadgeFields(e)}_markerDraft(e){return this._editorRuntimeOrThrow()._markerDraft(e)}_markerPreviewDevice(e){return this._editorRuntimeOrThrow()._markerPreviewDevice(e)}_markerPreviewDevices(e){return this._editorRuntimeOrThrow()._markerPreviewDevices(e)}_toggleIntent(e,t=this._devices){return Au({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){return this._editorRuntimeOrThrow()._toggleIntentForDialog(e)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const n={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return n?this._t(n):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!Fu(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,n=i?e.targets.filter(e=>"on"===e.state).length:0,r=i?0===n?t.groupAllOff():t.groupCurrent(n,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(r),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){return this._editorRuntimeOrThrow()._toggleHintLines(e)}_effectiveStoredTapAction(e,t){return this._editorRuntimeOrThrow()._effectiveStoredTapAction(e,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._editorRuntimeOrThrow()._effectiveMarkerTapAction(e,t)}_announceToggleDraft(e){return this._editorRuntimeOrThrow()._announceToggleDraft(e)}_valueBadgeForBinding(e,t){return this._editorRuntimeOrThrow()._valueBadgeForBinding(e,t)}_markerSpatialSource(e){return this._editorRuntimeOrThrow()._markerSpatialSource(e)}_markerAutoHasSpatialSource(e){return this._editorRuntimeOrThrow()._markerAutoHasSpatialSource(e)}_setMarkerLightRole(e){return this._editorRuntimeOrThrow()._setMarkerLightRole(e)}_controlRefInfo(e){return this._editorRuntimeOrThrow()._controlRefInfo(e)}_valueBadgeCandidateLabel(e){return this._editorRuntimeOrThrow()._valueBadgeCandidateLabel(e)}_controlCandidates(e){return this._editorRuntimeOrThrow()._controlCandidates(e)}_addControlRef(e,t){return this._editorRuntimeOrThrow()._addControlRef(e,t)}_setMarkerGlowMode(e){return this._editorRuntimeOrThrow()._setMarkerGlowMode(e)}_renderMarkerDialog(){return this._editorRuntimeOrThrow()._renderMarkerDialog()}_renderSpaceDialog(){return this._onboardingRuntime&&this._spaceDialog&&this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)?this._onboardingRuntime._renderSpaceDialog():this._editorRuntimeOrThrow()._renderSpaceDialog()}_renderMergeDialog(){return this._editorRuntimeOrThrow()._renderMergeDialog()}_renderCardPreview(e,t,i){const n=18*e;return j`
    + `}_markerValueBadgeFields(e){return this._editorRuntimeOrThrow()._markerValueBadgeFields(e)}_markerDraft(e){return this._editorRuntimeOrThrow()._markerDraft(e)}_markerPreviewDevice(e){return this._editorRuntimeOrThrow()._markerPreviewDevice(e)}_markerPreviewDevices(e){return this._editorRuntimeOrThrow()._markerPreviewDevices(e)}_toggleIntent(e,t=this._devices){return Pu({hass:this._planHass,registryHass:this._fullRegistryHass,devices:t,device:e,virtualLights:this._virtualLights})}_toggleIntentForDialog(e){return this._editorRuntimeOrThrow()._toggleIntentForDialog(e)}_toggleStateText(e,t){const i=this._planHass?.states?.[e]||this.hass?.states?.[e];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):t}catch{return t}}_toggleConfirmationStateText(e){const t=String(e.state||"unknown"),i=e.entityId?this._toggleStateText(e.entityId,t):t;if(i.trim().toLocaleLowerCase()!==t.trim().toLocaleLowerCase())return i;const n={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[t];return n?this._t(n):t.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(e){const t={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(e,t){if(!zu(e)||!e.nextEffect||!e.targets.length)return[];const i="group"===e.kind,n=i?e.targets.filter(e=>"on"===e.state).length:0,r=i?0===n?t.groupAllOff():t.groupCurrent(n,e.targets.length):t.state(e.targets[0]);let o;return o="toggle"===e.nextEffect?t.expectedByHa():i&&"turn-on"===e.nextEffect?t.groupAllOn():i&&"turn-off"===e.nextEffect?t.groupAllOff():t.effect(e.nextEffect),[t.current(r),t.expected(o),...e.skippedTargets.length?[t.unavailable(e.skippedTargets.length)]:[]]}(e,{state:e=>this._toggleConfirmationStateText(e),current:e=>this._t("confirm.current_state",{state:e}),expected:e=>this._t("confirm.expected_state",{state:e}),groupCurrent:(e,t)=>this._t("confirm.group_current",{on:e,total:t}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:e=>this._t("confirm.unavailable_targets",{count:e}),effect:e=>this._t(t[e]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(e){return this._editorRuntimeOrThrow()._toggleHintLines(e)}_effectiveStoredTapAction(e,t){return this._editorRuntimeOrThrow()._effectiveStoredTapAction(e,t)}_effectiveMarkerTapAction(e,t=this._markerPreviewDevice(e)){return this._editorRuntimeOrThrow()._effectiveMarkerTapAction(e,t)}_announceToggleDraft(e){return this._editorRuntimeOrThrow()._announceToggleDraft(e)}_valueBadgeForBinding(e,t){return this._editorRuntimeOrThrow()._valueBadgeForBinding(e,t)}_markerSpatialSource(e){return this._editorRuntimeOrThrow()._markerSpatialSource(e)}_markerAutoHasSpatialSource(e){return this._editorRuntimeOrThrow()._markerAutoHasSpatialSource(e)}_setMarkerLightRole(e){return this._editorRuntimeOrThrow()._setMarkerLightRole(e)}_controlRefInfo(e){return this._editorRuntimeOrThrow()._controlRefInfo(e)}_valueBadgeCandidateLabel(e){return this._editorRuntimeOrThrow()._valueBadgeCandidateLabel(e)}_controlCandidates(e){return this._editorRuntimeOrThrow()._controlCandidates(e)}_addControlRef(e,t){return this._editorRuntimeOrThrow()._addControlRef(e,t)}_setMarkerGlowMode(e){return this._editorRuntimeOrThrow()._setMarkerGlowMode(e)}_renderMarkerDialog(){return this._editorRuntimeOrThrow()._renderMarkerDialog()}_renderSpaceDialog(){return this._onboardingRuntime&&this._spaceDialog&&this._spaceDialogUsesOnboardingRuntime(this._spaceDialog.mode)?this._onboardingRuntime._renderSpaceDialog():this._editorRuntimeOrThrow()._renderSpaceDialog()}_renderMergeDialog(){return this._editorRuntimeOrThrow()._renderMergeDialog()}_renderCardPreview(e,t,i){const n=18*e;return j`
    ${this._t("preview.room_name")} @@ -1094,4 +1094,4 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 45% · ${this._t("roomcard.light_partial",{on:1,total:3})} -
    `}_renderRoomSource(e){return this._editorRuntimeOrThrow()._renderRoomSource(e)}_renderRoomDialog(){return this._editorRuntimeOrThrow()._renderRoomDialog()}}yv.properties={_tabDrag:{state:!0},_hdrH:{state:!0},_booting:{state:!0},_bootFading:{state:!0},_bootSoft:{state:!0},_continuityEpoch:{state:!0},_editorRuntimeLoadingVisible:{state:!0},_backdropGuard:{state:!0},_tapConfirm:{state:!0},_dangerConfirm:{state:!0},hass:{attribute:!1},panelHost:{type:Boolean,attribute:"panel-host",reflect:!0},narrow:{attribute:!1},_config:{state:!0},_space:{state:!0},_devices:{state:!0},_selId:{state:!0},_toast:{state:!0},_mode:{state:!0},_tool:{state:!0},_wallDialog:{state:!0},_drawWallField:{state:!0},_activeWallChainId:{state:!0},_physicalSel:{state:!0},_physicalDialog:{state:!0},_partitionDeleteDialog:{state:!0},_roomDeleteDialog:{state:!0},_physicalDrag:{state:!0},_physicalRotate:{state:!0},_duplicateColumnId:{state:!0},_opMeasure:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_mergeSel:{state:!0},_openingPreset:{state:!0},_openingDialog:{state:!0},_openingInfo:{state:!0},_mergeDialog:{state:!0},_splitSel:{state:!0},_decorTool:{state:!0},_decorStyle:{state:!0},_decorDraft:{state:!0},_decorSel:{state:!0},_decorEraseConfirm:{state:!0},_decorTextDialog:{state:!0},_decorShapeDialog:{state:!0},_backdropDialog:{state:!0},_furnPalette:{state:!0},_decorImagePalette:{state:!0},_decorAssetCatalog:{state:!0},_decorAssetBusy:{state:!0},_furnCategory:{state:!0},_furnPreviewInput:{state:!0},_bdDrag:{state:!0},_dtBox:{state:!0},_dtDrag:{state:!0},_kioskDialog:{state:!0},_vacFit:{state:!0},_vacAllCamerasFor:{state:!0},_vacCalConfirm:{state:!0},_kioskDots:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_roomEditId:{state:!0},_roomFill:{state:!0},_roomCustomFill:{state:!0},_roomTempMin:{state:!0},_roomTempMax:{state:!0},_roomTempSrc:{state:!0},_roomHumSrc:{state:!0},_roomSrcOpen:{state:!0},_roomSrcFilter:{state:!0},_roomNameScale:{state:!0},_roomLabelScale:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_deviceInbox:{state:!0},_rulesDialog:{state:!0},_settingsDialog:{state:!0},_pdfDialog:{state:!0},_supportDialog:{state:!0},_alignDialog:{state:!0},_preflightClipboardFallback:{state:!0},_backupExportDialog:{state:!0},_backupImportDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0}},yv.ZOOM_MAX=8,yv.ZOOM_MIN=1/3,yv.styles=[op,pg],customElements.get("houseplan-card")||customElements.define("houseplan-card",yv),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-card"===e.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info(`%c HOUSEPLAN-CARD %c v${ev} `,"background:#3ea6ff;color:#04121f;font-weight:700","");export{Wl as $,G as A,Pp as B,b_ as C,le as D,U as E,Ag as F,wi as G,Lr as H,$i as I,Mi as J,Ut as K,Ci as L,el as M,ja as N,wo as O,ni as P,Oo as Q,M_ as R,R_ as S,ys as T,io as U,Go as V,_i as W,Wo as X,L_ as Y,El as Z,rl as _,sh as a,fr as a$,Bl as a0,Cs as a1,ds as a2,Rs as a3,Zs as a4,Is as a5,Mc as a6,$c as a7,si as a8,Ja as a9,Yd as aA,Xd as aB,$g as aC,ti as aD,oi as aE,Pn as aF,Un as aG,dm as aH,Cr as aI,cm as aJ,Pl as aK,Hl as aL,Ql as aM,Xa as aN,ec as aO,Vl as aP,gs as aQ,ea as aR,es as aS,ua as aT,Oa as aU,N_ as aV,_a as aW,Ds as aX,Pg as aY,_n as aZ,vr as a_,Xu as aa,rp as ab,Ts as ac,ko as ad,ip as ae,Ku as af,Zo as ag,As as ah,Zu as ai,na as aj,sa as ak,fo as al,yo as am,Jr as an,O_ as ao,Ko as ap,Qa as aq,Uo as ar,Ua as as,Ga as at,en as au,tn as av,Ki as aw,Yi as ax,Ya as ay,ac as az,eh as b,li as b$,gr as b0,pn as b1,Oe as b2,kp as b3,sf as b4,Do as b5,nl as b6,Qt as b7,ei as b8,Br as b9,Nr as bA,Er as bB,Tr as bC,$r as bD,Rr as bE,Pr as bF,jn as bG,Sr as bH,Mr as bI,Xl as bJ,Ir as bK,Zl as bL,Ul as bM,Ll as bN,Jl as bO,Kl as bP,Yl as bQ,rm as bR,Jo as bS,$p as bT,tp as bU,Vf as bV,ep as bW,la as bX,qf as bY,Kf as bZ,C_ as b_,ma as ba,bc as bb,E_ as bc,bo as bd,Eu as be,q_ as bf,yi as bg,mi as bh,Fi as bi,za as bj,wa as bk,ba as bl,Yo as bm,Xo as bn,Qs as bo,kl as bp,Aa as bq,Da as br,Yn as bs,Xn as bt,ki as bu,ms as bv,_s as bw,j_ as bx,W_ as by,zr as bz,j as c,Sl as c$,Ju as c0,np as c1,Di as c2,fi as c3,ai as c4,vi as c5,Qo as c6,zi as c7,Mn as c8,Wp as c9,B_ as cA,Ar as cB,mn as cC,Fg as cD,so as cE,yr as cF,Ee as cG,qe as cH,Ne as cI,qc as cJ,Vc as cK,ih as cL,Ic as cM,Kc as cN,jc as cO,Wc as cP,th as cQ,Jc as cR,Ac as cS,Cc as cT,Bn as cU,Tc as cV,qn as cW,ci as cX,jf as cY,Dp as cZ,Bf as c_,Up as ca,wd as cb,Ru as cc,Li as cd,Ui as ce,Kn as cf,Ln as cg,Gd as ch,J_ as ci,vo as cj,Kd as ck,Ud as cl,un as cm,cn,ln as co,Ba as cp,F_ as cq,an as cr,sn as cs,on as ct,rn as cu,La as cv,kc as cw,wc as cx,Jf as cy,K_ as cz,ta as d,Rl as d$,Ps as d0,ss as d1,as as d2,Ie as d3,su as d4,Gp as d5,Vp as d6,tu as d7,Ou as d8,Od as d9,eu as dA,Za as dB,Al as dC,Dc as dD,Qg as dE,ef as dF,xp as dG,nf as dH,wl as dI,tf as dJ,rf as dK,$a as dL,Vs as dM,Sp as dN,Ri as dO,f_ as dP,xf as dQ,Sf as dR,hf as dS,y_ as dT,Na as dU,Hr as dV,Pa as dW,aa as dX,Dr as dY,Fr as dZ,Fa as d_,Id as da,Ad as db,xd as dc,Dn as dd,bd as de,Vd as df,Rn as dg,d_ as dh,zp as di,Pd as dj,Fd as dk,Sd as dl,ku as dm,Bi as dn,Hi as dp,Ip as dq,Ni as dr,xc as ds,qa as dt,Sc as du,qi as dv,ji as dw,xo as dx,pi as dy,Jd as dz,pe as e,U_ as e0,Ia as e1,lm as e2,yp as e3,cp as e4,_p as e5,hp as e6,Jt as e7,bg as e8,G_ as e9,Xi as ea,Zi as eb,Wt as ec,yv as ed,Qc as f,Mo as g,Co as h,_e as i,Ro as j,Ha as k,bp as l,Ao as m,rh as n,ch as o,o as p,he as q,lh as r,nn as s,Kt as t,op as u,wp as v,W as w,Yp as x,g_ as y,v_ as z}; +
    `}_renderRoomSource(e){return this._editorRuntimeOrThrow()._renderRoomSource(e)}_renderRoomDialog(){return this._editorRuntimeOrThrow()._renderRoomDialog()}}bv.properties={_tabDrag:{state:!0},_hdrH:{state:!0},_booting:{state:!0},_bootFading:{state:!0},_bootSoft:{state:!0},_continuityEpoch:{state:!0},_editorRuntimeLoadingVisible:{state:!0},_backdropGuard:{state:!0},_tapConfirm:{state:!0},_dangerConfirm:{state:!0},hass:{attribute:!1},panelHost:{type:Boolean,attribute:"panel-host",reflect:!0},narrow:{attribute:!1},_config:{state:!0},_space:{state:!0},_devices:{state:!0},_selId:{state:!0},_toast:{state:!0},_mode:{state:!0},_tool:{state:!0},_wallDialog:{state:!0},_drawWallField:{state:!0},_activeWallChainId:{state:!0},_physicalSel:{state:!0},_physicalDialog:{state:!0},_partitionDeleteDialog:{state:!0},_roomDeleteDialog:{state:!0},_physicalDrag:{state:!0},_physicalRotate:{state:!0},_duplicateColumnId:{state:!0},_opMeasure:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_mergeSel:{state:!0},_openingPreset:{state:!0},_openingDialog:{state:!0},_openingInfo:{state:!0},_mergeDialog:{state:!0},_splitSel:{state:!0},_decorTool:{state:!0},_decorStyle:{state:!0},_decorDraft:{state:!0},_decorSel:{state:!0},_decorEraseConfirm:{state:!0},_decorTextDialog:{state:!0},_decorShapeDialog:{state:!0},_backdropDialog:{state:!0},_furnPalette:{state:!0},_decorImagePalette:{state:!0},_decorAssetCatalog:{state:!0},_decorAssetBusy:{state:!0},_furnCategory:{state:!0},_furnPreviewInput:{state:!0},_bdDrag:{state:!0},_dtBox:{state:!0},_dtDrag:{state:!0},_kioskDialog:{state:!0},_vacFit:{state:!0},_vacAllCamerasFor:{state:!0},_vacCalConfirm:{state:!0},_kioskDots:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_roomEditId:{state:!0},_roomFill:{state:!0},_roomCustomFill:{state:!0},_roomTempMin:{state:!0},_roomTempMax:{state:!0},_roomTempSrc:{state:!0},_roomHumSrc:{state:!0},_roomSrcOpen:{state:!0},_roomSrcFilter:{state:!0},_roomNameScale:{state:!0},_roomLabelScale:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_deviceInbox:{state:!0},_rulesDialog:{state:!0},_settingsDialog:{state:!0},_pdfDialog:{state:!0},_supportDialog:{state:!0},_alignDialog:{state:!0},_preflightClipboardFallback:{state:!0},_backupExportDialog:{state:!0},_backupImportDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0}},bv.ZOOM_MAX=8,bv.ZOOM_MIN=1/3,bv.styles=[sp,_g],customElements.get("houseplan-card")||customElements.define("houseplan-card",bv),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-card"===e.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info(`%c HOUSEPLAN-CARD %c v${tv} `,"background:#3ea6ff;color:#04121f;font-weight:700","");export{Ul as $,G as A,Fp as B,w_ as C,le as D,U as E,Pg as F,wi as G,Br as H,$i as I,Mi as J,Ut as K,Ci as L,tl as M,Wa as N,ko as O,ni as P,Eo as Q,R_ as R,C_ as S,bs as T,no as U,Vo as V,_i as W,Uo as X,B_ as Y,Nl as Z,ol as _,ah as a,yr as a$,ql as a0,Ts as a1,us as a2,Cs as a3,Js as a4,Os as a5,Rc as a6,Mc as a7,si as a8,Qa as a9,Xd as aA,Zd as aB,Mg as aC,ti as aD,oi as aE,Pn as aF,Un as aG,um as aH,Tr as aI,hm as aJ,Fl as aK,Ll as aL,ec as aM,Za as aN,tc as aO,Kl as aP,fs as aQ,ta as aR,ts as aS,pa as aT,Ea as aU,H_ as aV,ma as aW,As as aX,Fg as aY,_n as aZ,fr as a_,Zu as aa,op as ab,Ds as ac,xo as ad,np as ae,Yu as af,Jo as ag,Ps as ah,Ju as ai,ra as aj,aa as ak,vo as al,bo as am,Qr as an,E_ as ao,Yo as ap,el as aq,Go as ar,Ga as as,Va as at,en as au,tn as av,Ki as aw,Yi as ax,Xa as ay,lc as az,th as b,T_ as b$,vr as b0,gr as b1,pn as b2,Oe as b3,xp as b4,af as b5,Ao as b6,rl as b7,Qt as b8,ei as b9,Ir as bA,Hr as bB,Nr as bC,Dr as bD,Mr as bE,Cr as bF,Fr as bG,jn as bH,$r as bI,Rr as bJ,Zl as bK,Or as bL,Jl as bM,Gl as bN,Bl as bO,Ql as bP,Yl as bQ,Xl as bR,om as bS,Qo as bT,Mp as bU,ip as bV,Kf as bW,tp as bX,ca as bY,jf as bZ,Yf as b_,qr as ba,ga as bb,wc as bc,N_ as bd,wo as be,Nu as bf,j_ as bg,yi as bh,mi as bi,Fi as bj,Ia as bk,ka as bl,wa as bm,Xo as bn,Zo as bo,ea as bp,xl as bq,Pa as br,Aa as bs,Yn as bt,Xn as bu,ki as bv,gs as bw,ms as bx,W_ as by,U_ as bz,j as c,qf as c$,li as c0,Qu as c1,rp as c2,Di as c3,fi as c4,ai as c5,vi as c6,es as c7,zi as c8,Mn as c9,Y_ as cA,q_ as cB,Pr as cC,mn as cD,zg as cE,ao as cF,br as cG,Ee as cH,qe as cI,Ne as cJ,jc as cK,Kc as cL,nh as cM,Oc as cN,Yc as cO,Wc as cP,Uc as cQ,ih as cR,Qc as cS,Pc as cT,Tc as cU,Bn as cV,Dc as cW,qn as cX,ci as cY,Wf as cZ,Ap as c_,Up as ca,Gp as cb,kd as cc,Cu as cd,Li as ce,Ui as cf,Kn as cg,Ln as ch,Vd as ci,Q_ as cj,yo as ck,Yd as cl,Gd as cm,un as cn,cn as co,ln as cp,qa as cq,z_ as cr,an as cs,sn as ct,on as cu,rn as cv,Ba as cw,xc as cx,kc as cy,Qf as cz,ia as d,za as d$,$l as d0,Fs as d1,as as d2,ls as d3,Ie as d4,au as d5,Vp as d6,Kp as d7,iu as d8,Eu as d9,Qd as dA,tu as dB,Ja as dC,Pl as dD,Ac as dE,ef as dF,tf as dG,Sp as dH,rf as dI,kl as dJ,nf as dK,of as dL,Ma as dM,Ks as dN,$p as dO,Ri as dP,v_ as dQ,Sf as dR,$f as dS,df as dT,b_ as dU,Ha as dV,Lr as dW,Fa as dX,la as dY,Ar as dZ,zr as d_,Ed as da,Od as db,Pd as dc,Sd as dd,Dn as de,wd as df,Kd as dg,Rn as dh,u_ as di,Ip as dj,Fd as dk,zd as dl,$d as dm,xu as dn,Bi as dp,Hi as dq,Op as dr,Ni as ds,Sc as dt,ja as du,$c as dv,qi as dw,ji as dx,So as dy,pi as dz,pe as e,Cl as e0,G_ as e1,Oa as e2,cm as e3,bp as e4,hp as e5,mp as e6,dp as e7,Jt as e8,wg as e9,V_ as ea,Xi as eb,Zi as ec,Wt as ed,bv as ee,eh as f,Ro as g,To as h,_e as i,Co as j,La as k,wp as l,Po as m,oh as n,hh as o,o as p,he as q,ch as r,nn as s,Kt as t,sp as u,kp as v,W as w,Xp as x,f_ as y,y_ as z}; diff --git a/dist/houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js b/dist/houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js similarity index 80% rename from dist/houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js rename to dist/houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js index f695edc6..b9755ddf 100644 --- a/dist/houseplan-assets/houseplan-editor-runtime-BNMtEwiN.js +++ b/dist/houseplan-assets/houseplan-editor-runtime-dzTrOQhv.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{e as t,i as e,E as s,s as i,a as o,n as a,f as n,b as r,l,o as h,r as c,A as d,c as p,D as u,w as _,N as m,d as g,g as f,h as b,j as v,k as y,m as $,p as w,q as k,t as x,u as S,v as M,x as C,y as P,z as D,B as I,C as T,F as z,G as R,H as A,I as F,J as N,K as E,L as H,M as O,O as L,P as B,Q as W,R as j,S as G,T as q,U,V as K,W as V,X as J,Y,Z as X,_ as Z,$ as Q,a0 as tt,a1 as et,a2 as st,a3 as it,a4 as ot,a5 as at,a6 as nt,a7 as rt,a8 as lt,a9 as ht,aa as ct,ab as dt,ac as pt,ad as ut,ae as _t,af as mt,ag as gt,ah as ft,ai as bt,aj as vt,ak as yt,al as $t,am as wt,an as kt,ao as xt,ap as St,aq as Mt,ar as Ct,as as Pt,at as Dt,au as It,av as Tt,aw as zt,ax as Rt,ay as At,az as Ft,aA as Nt,aB as Et,aC as Ht,aD as Ot,aE as Lt,aF as Bt,aG as Wt,aH as jt,aI as Gt,aJ as qt,aK as Ut,aL as Kt,aM as Vt,aN as Jt,aO as Yt,aP as Xt,aQ as Zt,aR as Qt,aS as te,aT as ee,aU as se,aV as ie,aW as oe,aX as ae,aY as ne,aZ as re,a_ as le,a$ as he,b0 as ce,b1 as de,b2 as pe,b3 as ue,b4 as _e,b5 as me,b6 as ge,b7 as fe,b8 as be,b9 as ve,ba as ye,bb as $e,bc as we,bd as ke,be as xe,bf as Se,bg as Me,bh as Ce,bi as Pe,bj as De,bk as Ie,bl as Te,bm as ze,bn as Re,bo as Ae,bp as Fe,bq as Ne,br as Ee,bs as He,bt as Oe,bu as Le,bv as Be,bw as We,bx as je,by as Ge,bz as qe,bA as Ue,bB as Ke,bC as Ve,bD as Je,bE as Ye,bF as Xe,bG as Ze,bH as Qe,bI as ts,bJ as es,bK as ss,bL as is,bM as os,bN as as,bO as ns,bP as rs,bQ as ls,bR as hs,bS as cs,bT as ds,bU as ps,bV as us,bW as _s,bX as ms,bY as gs,bZ as fs,b_ as bs,b$ as vs,c0 as ys,c1 as $s,c2 as ws,c3 as ks,c4 as xs,c5 as Ss,c6 as Ms,c7 as Cs,c8 as Ps,c9 as Ds,ca as Is,cb as Ts,cc as zs,cd as Rs,ce as As,cf as Fs,cg as Ns,ch as Es,ci as Hs,cj as Os,ck as Ls,cl as Bs,cm as Ws,cn as js,co as Gs,cp as qs,cq as Us,cr as Ks,cs as Vs,ct as Js,cu as Ys,cv as Xs,cw as Zs,cx as Qs,cy as ti,cz as ei,cA as si,cB as ii,cC as oi,cD as ai,cE as ni,cF as ri,cG as li,cH as hi,cI as ci,cJ as di,cK as pi,cL as ui,cM as _i,cN as mi,cO as gi,cP as fi,cQ as bi,cR as vi,cS as yi,cT as $i,cU as wi,cV as ki,cW as xi,cX as Si,cY as Mi,cZ as Ci,c_ as Pi,c$ as Di,d0 as Ii,d1 as Ti,d2 as zi,d3 as Ri,d4 as Ai,d5 as Fi,d6 as Ni,d7 as Ei,d8 as Hi,d9 as Oi,da as Li,db as Bi,dc as Wi,dd as ji,de as Gi,df as qi,dg as Ui,dh as Ki,di as Vi,dj as Ji,dk as Yi,dl as Xi,dm as Zi,dn as Qi,dp as to,dq as eo,dr as so,ds as io,dt as oo,du as ao,dv as no,dw as ro,dx as lo,dy as ho,dz as co,dA as po,dB as uo,dC as _o}from"./houseplan-card-BCGpvbDT.js";import{F as mo,f as go,p as fo,c as bo,e as vo,r as yo,a as $o,s as wo}from"./backdrop-pick-Caayxvt2.js";import{t as ko,h as xo,m as So,T as Mo}from"./zigbee-topology-DlU7AXvw.js";import{GENERATED_FURNITURE_ART as Co,FURNITURE_ART_FINGERPRINT as Po}from"./furniture-plan-art.generated-MsQg9zvn.js";const Do={},Io=t(class extends e{constructor(){super(...arguments),this.ot=Do}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return s}else if(this.ot===e)return s;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}});var To={"gs.hint":"Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.","gs.show_room_tooltip":"Show the room information window on hover","support.about_group":"About the card","support.guide_group":"Documentation","support.guide":"User guide","support.form_group":"Send a report or suggestion","support.contact":"Contact details (email/tg/WhatsApp), optional.","support.message":"Message","support.attach":"Attach anonymized information from your plan","support.attach_hint":"Includes only allowed plan geometry, settings and bounded runtime facts. Excludes names, Home Assistant IDs, live states, URLs, files, and your message/contact.","support.geometry_warning":"The package contains no names or Home Assistant IDs, but it does contain the exact geometry and dimensions of your home.","support.close_busy_title":"Stop the current operation?","support.close_busy_body":"House Plan is preparing or sending the report. Closing now stops waiting for the result.","support.building":"Preparing anonymized data…","support.preview_summary":"Package v{version} · {spaces} spaces · {size} KiB","support.prepared":"Snapshot prepared {n} min ago","support.show_data":"Show data","support.download":"Download JSON","support.refresh":"Refresh snapshot","support.privacy":"When you send, your message, optional contact and, if selected, exact geometry leave your Home Assistant through the House Plan project relay and are visible to maintainers. The project node keeps the report for up to 30 days. Network infrastructure sees your HA server address, but House Plan does not retain it raw; rate-limit and idempotency metadata is kept for up to 24 hours.","support.error_title":"The report was not sent","support.manual_recovery":"You can keep the message and attachment and continue manually:","support.copy_message":"Copy message","support.success":"Report sent: {id}. Save this number when contacting support.","support.copy_id":"Copy ID","support.sending":"Sending…","support.retry":"Retry","support.send":"Send","support.update_required":"Update the House Plan card and integration to compatible versions to send reports.","support.message_copied":"Message copied","support.id_copied":"Report ID copied","support.copy_failed":"Could not access the clipboard. Select and copy the text manually.","support.validation.message_required":"Enter a message.","support.validation.message_too_long":"The message must contain no more than 10,000 characters.","support.validation.contact_too_long":"Contact details must contain no more than 320 characters.","support.validation.preview_missing":"Wait for the attachment preview or turn the attachment off.","support.validation.preview_expired":"The attachment preview expired. Refresh the snapshot.","support.error.support_invalid_message":"Check the message and try again.","support.error.support_preview_expired":"The attachment preview expired or is no longer available. Refresh the snapshot.","support.error.support_package_too_large":"The anonymized package exceeds the 8 MiB limit.","support.error.support_rate_limited":"Too many reports or previews were requested. Try again later.","support.error.support_unavailable":"The private support service is temporarily unavailable. Your draft remains here.","support.error.support_rejected":"The report did not pass the support service validation.","support.error.unauthorized":"You do not have permission to send this report.","vac.routes_section":"Maps and floors","vac.routes_current_map":"Current map","vac.routes_no_map":"no telemetry","vac.routes_status":"Routing","vac.routes_state_ready":"map assigned and calibrated","vac.routes_state_needs_calibration":"map assigned, calibration needed","vac.routes_state_unmapped":"current map is not assigned to a floor","vac.routes_state_ambiguous":"two maps are indistinguishable — no floor is chosen","vac.routes_state_missing_space":"the map's space was deleted","vac.routes_state_none":"no map data","vac.routes_empty":"No map is assigned to a floor yet.","vac.route_map_default":"no map id","vac.route_active":"Active","vac.route_space":"Space","vac.route_space_none":"not selected","vac.route_status_ready":"ready","vac.route_status_needs_calibration":"needs calibration","vac.route_status_ambiguous":"ambiguous","vac.route_status_missing_space":"space deleted","vac.route_missing_space_group":"Deleted space","vac.route_add_current":"Add current map","vac.route_delete":"Remove map","vac.route_delete_title":"Remove the map from its floor?","vac.route_delete_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_delete_confirm":"Remove","vac.route_space_title":"Move the map to another space?","vac.route_space_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_space_confirm":"Move","vac.route_missing_space_hint":"One of the maps points at a deleted space: pick a new one or remove the map. Until then the robot is not drawn for that map.","vac.route_default_hint":"The source reports no stable map id. Several floors cannot be told apart without another source or the robot's own selected map.","vac.route_target_hint":"The dock stays in the “{space}” space regardless of the current map.","vac.route_add_source":"Add a map source","vac.route_add_source_hint":"For integrations that give each map its own camera. The “All cameras” section above widens this list.","vac.route_source_no_map":"no map reported"};const zo={en:To,ru:{"gs.hint":"Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.","gs.show_room_tooltip":"Показывать окно с информацией при наведении на комнату","support.about_group":"О карточке","support.guide_group":"Документация","support.guide":"Руководство пользователя","support.form_group":"Отправить репорт или предложение","support.contact":"Контакт для связи (email/tg/WhatsApp), необязательно.","support.message":"Сообщение","support.attach":"Прикрепить обезличенную информацию из вашего плана","support.attach_hint":"В пакет входят только разрешённые геометрия, настройки и ограниченные сведения о среде. Не входят имена, HA id, текущие состояния, URL, файлы, сообщение и контакт.","support.geometry_warning":"Пакет не содержит имён и HA id, но содержит точную геометрию и размеры дома.","support.close_busy_title":"Прервать текущую операцию?","support.close_busy_body":"House Plan подготавливает или отправляет репорт. При закрытии ожидание результата прекратится.","support.building":"Подготавливаем обезличенные данные…","support.preview_summary":"Пакет v{version} · пространств: {spaces} · {size} КиБ","support.prepared":"Снимок подготовлен {n} мин назад","support.show_data":"Показать данные","support.download":"Скачать JSON","support.refresh":"Обновить снимок","support.privacy":"При отправке сообщение, необязательный контакт и, если выбран пакет, точная геометрия покидают ваш Home Assistant через relay проекта House Plan и доступны мейнтейнерам. Узел проекта хранит репорт до 30 дней. Сетевая инфраструктура видит адрес сервера HA, но House Plan не сохраняет его в исходном виде; метаданные лимитов и идемпотентности хранятся до 24 часов.","support.error_title":"Репорт не отправлен","support.manual_recovery":"Сообщение и вложение можно сохранить и продолжить вручную:","support.copy_message":"Копировать сообщение","support.success":"Репорт отправлен: {id}. Сохраните номер для связи с поддержкой.","support.copy_id":"Копировать ID","support.sending":"Отправляем…","support.retry":"Повторить","support.send":"Отправить","support.update_required":"Обновите карточку и интеграцию House Plan до совместимых версий, чтобы отправлять репорты.","support.message_copied":"Сообщение скопировано","support.id_copied":"ID репорта скопирован","support.copy_failed":"Не удалось получить доступ к буферу обмена. Выделите и скопируйте текст вручную.","support.validation.message_required":"Введите сообщение.","support.validation.message_too_long":"Сообщение должно содержать не более 10 000 символов.","support.validation.contact_too_long":"Контакт должен содержать не более 320 символов.","support.validation.preview_missing":"Дождитесь предпросмотра вложения или отключите его.","support.validation.preview_expired":"Предпросмотр вложения истёк. Обновите снимок.","support.error.support_invalid_message":"Проверьте сообщение и повторите попытку.","support.error.support_preview_expired":"Предпросмотр вложения истёк или больше недоступен. Обновите снимок.","support.error.support_package_too_large":"Обезличенный пакет превышает лимит 8 МиБ.","support.error.support_rate_limited":"Запрошено слишком много репортов или предпросмотров. Повторите позже.","support.error.support_unavailable":"Закрытая служба поддержки временно недоступна. Черновик сохранён в этом окне.","support.error.support_rejected":"Репорт не прошёл проверку службы поддержки.","support.error.unauthorized":"У вас нет прав на отправку этого репорта.","vac.routes_section":"Карты и этажи","vac.routes_current_map":"Текущая карта","vac.routes_no_map":"источник молчит","vac.routes_status":"Маршрутизация","vac.routes_state_ready":"карта сопоставлена и откалибрована","vac.routes_state_needs_calibration":"карта сопоставлена, нужна калибровка","vac.routes_state_unmapped":"текущая карта не сопоставлена этажу","vac.routes_state_ambiguous":"две карты неразличимы — этаж не выбирается","vac.routes_state_missing_space":"пространство карты удалено","vac.routes_state_none":"нет данных о карте","vac.routes_empty":"Ни одна карта ещё не сопоставлена этажу.","vac.route_map_default":"без идентификатора","vac.route_active":"Текущая","vac.route_space":"Пространство","vac.route_space_none":"не выбрано","vac.route_status_ready":"готова","vac.route_status_needs_calibration":"нужна калибровка","vac.route_status_ambiguous":"неоднозначна","vac.route_status_missing_space":"пространство удалено","vac.route_missing_space_group":"Пространство удалено","vac.route_add_current":"Добавить текущую карту","vac.route_delete":"Удалить карту","vac.route_delete_title":"Удалить карту с этажа?","vac.route_delete_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_delete_confirm":"Удалить","vac.route_space_title":"Перенести карту в другое пространство?","vac.route_space_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_space_confirm":"Перенести","vac.route_missing_space_hint":"Одна из карт ссылается на удалённое пространство: выберите новое или удалите карту. Пока ссылка не исправлена, робот на этой карте не рисуется.","vac.route_default_hint":"Источник не сообщает стабильный идентификатор карты. Несколько этажей нельзя различить без другого источника или собственной карты робота.","vac.route_target_hint":"Док остаётся в пространстве «{space}» независимо от текущей карты.","vac.route_add_source":"Добавить источник карты","vac.route_add_source_hint":"Для интеграций, где у каждой карты своя камера. Список расширяется разделом «Все камеры» выше.","vac.route_source_no_map":"карта не читается"},de:{"gs.hint":"Füllfarben gelten für jeden Bereich; jede Farbe hat ihre eigene Deckkraft. Der Füllmodus wird in den Einstellungen des jeweiligen Bereichs festgelegt.","gs.show_room_tooltip":"Rauminformationen beim Darüberfahren anzeigen","support.about_group":"Über die Karte","support.guide_group":"Dokumentation","support.guide":"Benutzerhandbuch","support.form_group":"Bericht oder Vorschlag senden","support.contact":"Kontakt (E-Mail/tg/WhatsApp), optional.","support.message":"Nachricht","support.attach":"Anonymisierte Informationen aus dem Plan anhängen","support.attach_hint":"Enthält nur erlaubte Plangeometrie, Einstellungen und begrenzte Laufzeitdaten. Namen, Home-Assistant-IDs, Live-Zustände, URLs, Dateien, Nachricht und Kontakt werden ausgeschlossen.","support.geometry_warning":"Das Paket enthält keine Namen oder Home-Assistant-IDs, aber die exakte Geometrie und die Maße Ihres Hauses.","support.close_busy_title":"Aktuellen Vorgang abbrechen?","support.close_busy_body":"House Plan bereitet den Bericht vor oder sendet ihn. Beim Schließen wird nicht weiter auf das Ergebnis gewartet.","support.building":"Anonymisierte Daten werden vorbereitet…","support.preview_summary":"Paket v{version} · {spaces} Bereiche · {size} KiB","support.prepared":"Schnappschuss vor {n} Min. erstellt","support.show_data":"Daten anzeigen","support.download":"JSON herunterladen","support.refresh":"Schnappschuss aktualisieren","support.privacy":"Beim Senden verlassen Ihre Nachricht, der optionale Kontakt und, falls ausgewählt, die exakte Geometrie Ihren Home Assistant über das House-Plan-Projektrelay und sind für die Maintainer sichtbar. Der Projektserver speichert den Bericht bis zu 30 Tage. Die Netzwerkinfrastruktur sieht die Adresse Ihres HA-Servers, House Plan speichert sie jedoch nicht im Rohformat; Limit- und Idempotenzdaten bleiben bis zu 24 Stunden erhalten.","support.error_title":"Der Bericht wurde nicht gesendet","support.manual_recovery":"Nachricht und Anhang können gespeichert und manuell weitergegeben werden:","support.copy_message":"Nachricht kopieren","support.success":"Bericht gesendet: {id}. Bewahren Sie diese Nummer für den Support auf.","support.copy_id":"ID kopieren","support.sending":"Wird gesendet…","support.retry":"Erneut versuchen","support.send":"Senden","support.update_required":"Aktualisieren Sie House-Plan-Karte und Integration auf kompatible Versionen, um Berichte zu senden.","support.message_copied":"Nachricht kopiert","support.id_copied":"Berichts-ID kopiert","support.copy_failed":"Kein Zugriff auf die Zwischenablage. Markieren und kopieren Sie den Text manuell.","support.validation.message_required":"Geben Sie eine Nachricht ein.","support.validation.message_too_long":"Die Nachricht darf höchstens 10.000 Zeichen enthalten.","support.validation.contact_too_long":"Der Kontakt darf höchstens 320 Zeichen enthalten.","support.validation.preview_missing":"Warten Sie auf die Vorschau oder deaktivieren Sie den Anhang.","support.validation.preview_expired":"Die Anhangsvorschau ist abgelaufen. Aktualisieren Sie den Schnappschuss.","support.error.support_invalid_message":"Prüfen Sie die Nachricht und versuchen Sie es erneut.","support.error.support_preview_expired":"Die Anhangsvorschau ist abgelaufen oder nicht mehr verfügbar. Aktualisieren Sie den Schnappschuss.","support.error.support_package_too_large":"Das anonymisierte Paket überschreitet das Limit von 8 MiB.","support.error.support_rate_limited":"Zu viele Berichte oder Vorschauen wurden angefordert. Versuchen Sie es später erneut.","support.error.support_unavailable":"Der private Supportdienst ist vorübergehend nicht verfügbar. Der Entwurf bleibt in diesem Fenster erhalten.","support.error.support_rejected":"Der Bericht hat die Prüfung des Supportdienstes nicht bestanden.","support.error.unauthorized":"Sie dürfen diesen Bericht nicht senden.","vac.routes_section":"Karten und Etagen","vac.routes_current_map":"Aktuelle Karte","vac.routes_no_map":"keine Telemetrie","vac.routes_status":"Zuordnung","vac.routes_state_ready":"Karte zugeordnet und kalibriert","vac.routes_state_needs_calibration":"Karte zugeordnet, Kalibrierung nötig","vac.routes_state_unmapped":"aktuelle Karte keiner Etage zugeordnet","vac.routes_state_ambiguous":"zwei Karten nicht unterscheidbar — keine Etage gewählt","vac.routes_state_missing_space":"der Raum der Karte wurde gelöscht","vac.routes_state_none":"keine Kartendaten","vac.routes_empty":"Noch keine Karte einer Etage zugeordnet.","vac.route_map_default":"ohne Karten-ID","vac.route_active":"Aktiv","vac.route_space":"Raum","vac.route_space_none":"nicht gewählt","vac.route_status_ready":"bereit","vac.route_status_needs_calibration":"Kalibrierung nötig","vac.route_status_ambiguous":"mehrdeutig","vac.route_status_missing_space":"Raum gelöscht","vac.route_missing_space_group":"Gelöschter Bereich","vac.route_add_current":"Aktuelle Karte hinzufügen","vac.route_delete":"Karte entfernen","vac.route_delete_title":"Karte von der Etage entfernen?","vac.route_delete_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_delete_confirm":"Entfernen","vac.route_space_title":"Karte in einen anderen Raum verschieben?","vac.route_space_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_space_confirm":"Verschieben","vac.route_missing_space_hint":"Eine Karte verweist auf einen gelöschten Raum: neuen wählen oder Karte entfernen. Bis dahin wird der Roboter für diese Karte nicht gezeichnet.","vac.route_default_hint":"Die Quelle meldet keine stabile Karten-ID. Mehrere Etagen lassen sich ohne andere Quelle oder die vom Roboter gewählte Karte nicht unterscheiden.","vac.route_target_hint":"Die Station bleibt unabhängig von der aktuellen Karte im Raum „{space}“.","vac.route_add_source":"Kartenquelle hinzufügen","vac.route_add_source_hint":"Für Integrationen, die jeder Karte eine eigene Kamera geben. Der Abschnitt „Alle Kameras“ oben erweitert diese Liste.","vac.route_source_no_map":"keine Karte gemeldet"},fr:{"gs.hint":"Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.","gs.show_room_tooltip":"Afficher les informations de la pièce au survol","support.about_group":"À propos de la carte","support.guide_group":"Documentation d’aide","support.guide":"Guide utilisateur","support.form_group":"Envoyer un rapport ou une suggestion","support.contact":"Contact (e-mail/tg/WhatsApp), facultatif.","support.message":"Votre message","support.attach":"Joindre des informations anonymisées de votre plan","support.attach_hint":"Inclut uniquement la géométrie, les réglages autorisés et des données d’exécution limitées. Exclut les noms, identifiants Home Assistant, états en direct, URL, fichiers, message et contact.","support.geometry_warning":"Le paquet ne contient ni noms ni identifiants Home Assistant, mais il contient la géométrie et les dimensions exactes de votre logement.","support.close_busy_title":"Interrompre l’opération en cours ?","support.close_busy_body":"House Plan prépare ou envoie le rapport. Fermer maintenant arrête l’attente du résultat.","support.building":"Préparation des données anonymisées…","support.preview_summary":"Paquet v{version} · {spaces} espaces · {size} Kio","support.prepared":"Instantané préparé il y a {n} min","support.show_data":"Afficher les données","support.download":"Télécharger le JSON","support.refresh":"Actualiser l’instantané","support.privacy":"Lors de l’envoi, votre message, le contact facultatif et, si elle est sélectionnée, la géométrie exacte quittent votre Home Assistant via le relais du projet House Plan et sont visibles par les mainteneurs. Le serveur du projet conserve le rapport jusqu’à 30 jours. L’infrastructure réseau voit l’adresse de votre serveur HA, mais House Plan ne la conserve pas en clair ; les métadonnées de limitation et d’idempotence sont gardées jusqu’à 24 heures.","support.error_title":"Le rapport n’a pas été envoyé","support.manual_recovery":"Vous pouvez conserver le message et la pièce jointe puis continuer manuellement :","support.copy_message":"Copier le message","support.success":"Rapport envoyé : {id}. Conservez ce numéro pour contacter l’assistance.","support.copy_id":"Copier l’ID","support.sending":"Envoi…","support.retry":"Réessayer","support.send":"Envoyer","support.update_required":"Mettez à jour la carte et l’intégration House Plan vers des versions compatibles pour envoyer des rapports.","support.message_copied":"Message copié","support.id_copied":"ID du rapport copié","support.copy_failed":"Impossible d’accéder au presse-papiers. Sélectionnez et copiez le texte manuellement.","support.validation.message_required":"Saisissez un message.","support.validation.message_too_long":"Le message ne doit pas dépasser 10 000 caractères.","support.validation.contact_too_long":"Le contact ne doit pas dépasser 320 caractères.","support.validation.preview_missing":"Attendez l’aperçu de la pièce jointe ou désactivez-la.","support.validation.preview_expired":"L’aperçu de la pièce jointe a expiré. Actualisez l’instantané.","support.error.support_invalid_message":"Vérifiez le message et réessayez.","support.error.support_preview_expired":"L’aperçu de la pièce jointe a expiré ou n’est plus disponible. Actualisez l’instantané.","support.error.support_package_too_large":"Le paquet anonymisé dépasse la limite de 8 Mio.","support.error.support_rate_limited":"Trop de rapports ou d’aperçus ont été demandés. Réessayez plus tard.","support.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible. Le brouillon reste dans cette fenêtre.","support.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","support.error.unauthorized":"Vous n’êtes pas autorisé à envoyer ce rapport.","vac.routes_section":"Cartes et étages","vac.routes_current_map":"Carte actuelle","vac.routes_no_map":"aucune télémétrie","vac.routes_status":"Routage","vac.routes_state_ready":"carte assignée et calibrée","vac.routes_state_needs_calibration":"carte assignée, calibrage requis","vac.routes_state_unmapped":"carte actuelle non assignée à un étage","vac.routes_state_ambiguous":"deux cartes indiscernables — aucun étage choisi","vac.routes_state_missing_space":"l'espace de la carte a été supprimé","vac.routes_state_none":"aucune donnée de carte","vac.routes_empty":"Aucune carte n'est encore assignée à un étage.","vac.route_map_default":"sans identifiant","vac.route_active":"Active","vac.route_space":"Espace","vac.route_space_none":"non sélectionné","vac.route_status_ready":"prête","vac.route_status_needs_calibration":"calibrage requis","vac.route_status_ambiguous":"ambiguë","vac.route_status_missing_space":"espace supprimé","vac.route_missing_space_group":"Espace supprimé","vac.route_add_current":"Ajouter la carte actuelle","vac.route_delete":"Supprimer la carte","vac.route_delete_title":"Retirer la carte de son étage ?","vac.route_delete_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_delete_confirm":"Supprimer","vac.route_space_title":"Déplacer la carte vers un autre espace ?","vac.route_space_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_space_confirm":"Déplacer","vac.route_missing_space_hint":"Une carte pointe vers un espace supprimé : choisissez-en un autre ou supprimez la carte. D'ici là, le robot n'est pas dessiné pour cette carte.","vac.route_default_hint":"La source ne fournit pas d'identifiant de carte stable. Plusieurs étages ne peuvent pas être distingués sans une autre source ou la carte sélectionnée du robot.","vac.route_target_hint":"La station reste dans l'espace « {space} » quelle que soit la carte actuelle.","vac.route_add_source":"Ajouter une source de carte","vac.route_add_source_hint":"Pour les intégrations qui donnent à chaque carte sa propre caméra. La section « Toutes les caméras » ci-dessus élargit cette liste.","vac.route_source_no_map":"aucune carte signalée"}};function Ro(t,e,s){return i(zo[t]?.[e]??To[e]??e,s)}function Ao(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function Fo(t,e,s){return{...t,space:s.has(e)?e:""}}function No(t,e=Math.random){const s=new Set(t);for(let t=0;t<64;t+=1){const t="vr_"+Math.floor(16777215*e()).toString(36).padStart(5,"0");if(!s.has(t))return t}return"vr_"+Date.now().toString(36)}function Eo(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const Ho=new WeakMap,Oo=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function Lo(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>Ro(n,t,e),u=e.marker?.vacuum||{},_=Array.isArray(u.map_routes),m=i._vacSource(e)||"",g=o(e.id,u,e.space,m),f=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),b=new Set(f.map(t=>t.id)),v=h(g,[m],t=>i._vacObservedMapId(e,t)),y=c({routes:g,observed:v,spaceIds:b}),$="ready"===y.kind||"needs_calibration"===y.kind||"missing_space"===y.kind?y.route.id:"",w=m?v[m]:void 0,k=async s=>{let o=_?u.map_routes??null:null;if(!o&&(o=function(t,e,s,i){if(!s)return null;const o=t?.calibration;if(!o||"object"!=typeof o)return null;const n=new Set,r=[];for(const t of Object.keys(o)){const l=a(o[t]);if(!l)continue;const h=i(n);n.add(h),r.push({id:h,source:s,map_id:t,space:e,calibration:l})}return r.length?r:null}(u,e.space,m,t=>No(t))??[],!m&&Object.keys(u.calibration||{}).length))return!1;const n=s(o);return!!n&&(async s=>{const o=i._serverCfg;if(!o)return!1;const a=JSON.parse(JSON.stringify(o));a.markers=a.markers||[];let n=a.markers.find(t=>t.id===e.id);if(!n){if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return!1;n={id:e.id,binding:`${e.bindingKind}:${e.bindingRef}`,space:e.space||null,area:e.area||null,hidden:!!e.hidden},a.markers.push(n)}n.vacuum={...n.vacuum||{},map_routes:s},delete n.vacuum.calibration;const r=i._adoption.beginOptimistic(o,a);i._adoption.stageLocalConfig(a),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return i._rollbackOptimistic(r),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},x=s.candidates.filter(t=>t.entityId!==m&&!g.some(e=>e.source===t.entityId)),S=async(t,e)=>{if(!e||e===t.space)return;await i._confirmDanger({key:"vacuum_route_space",kind:"warning",title:r("vac.route_space_title"),message:r("vac.route_space_body"),objectName:t.map_id||r("vac.route_map_default"),confirmLabel:r("vac.route_space_confirm"),cancelLabel:i._t("btn.cancel")})&&await k(s=>function(t,e,s,i){return t.map(t=>t.id===e?{...t,id:i,space:s,calibration:null}:t)}(s,t.id,e,No(new Set(g.map(t=>t.id)))))},M=new Map(f.map((t,e)=>[t.id,e])),C=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),P=g.filter(t=>b.has(t.space)).sort((t,e)=>(M.get(t.space)??0)-(M.get(e.space)??0)||C(t,e)),D=g.filter(t=>!b.has(t.space)).sort(C),I=[...P,...D],T=!!m&&void 0!==w&&!g.some(t=>t.source===m&&t.map_id===w);let z=Ho.get(t);const R=z?.source||"",A=z?.mapId||"",F=!!z&&g.some(t=>t.source===R&&t.map_id===A);z&&(z.markerId!==e.id||i._vacObservedMapId(e,z.source)!==z.mapId||F&&!z.saving)&&(Ho.delete(t),z=void 0),z?.space&&!b.has(z.space)&&(z=Fo(z,"",b),Ho.set(t,z));const N=s=>p` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{e as t,i as e,E as s,s as i,a as o,n as a,f as n,b as r,l,o as h,r as c,A as d,c as p,D as u,w as _,N as m,d as g,g as f,h as b,j as v,k as y,m as $,p as w,q as k,t as x,u as S,v as M,x as C,y as P,z as D,B as I,C as T,F as R,G as z,H as A,I as F,J as N,K as E,L as H,M as O,O as L,P as B,Q as W,R as j,S as G,T as q,U,V as K,W as V,X as J,Y,Z as X,_ as Z,$ as Q,a0 as tt,a1 as et,a2 as st,a3 as it,a4 as ot,a5 as at,a6 as nt,a7 as rt,a8 as lt,a9 as ht,aa as ct,ab as dt,ac as pt,ad as ut,ae as _t,af as mt,ag as gt,ah as ft,ai as bt,aj as vt,ak as yt,al as $t,am as wt,an as kt,ao as xt,ap as St,aq as Mt,ar as Ct,as as Pt,at as Dt,au as It,av as Tt,aw as Rt,ax as zt,ay as At,az as Ft,aA as Nt,aB as Et,aC as Ht,aD as Ot,aE as Lt,aF as Bt,aG as Wt,aH as jt,aI as Gt,aJ as qt,aK as Ut,aL as Kt,aM as Vt,aN as Jt,aO as Yt,aP as Xt,aQ as Zt,aR as Qt,aS as te,aT as ee,aU as se,aV as ie,aW as oe,aX as ae,aY as ne,aZ as re,a_ as le,a$ as he,b0 as ce,b1 as de,b2 as pe,b3 as ue,b4 as _e,b5 as me,b6 as ge,b7 as fe,b8 as be,b9 as ve,ba as ye,bb as $e,bc as we,bd as ke,be as xe,bf as Se,bg as Me,bh as Ce,bi as Pe,bj as De,bk as Ie,bl as Te,bm as Re,bn as ze,bo as Ae,bp as Fe,bq as Ne,br as Ee,bs as He,bt as Oe,bu as Le,bv as Be,bw as We,bx as je,by as Ge,bz as qe,bA as Ue,bB as Ke,bC as Ve,bD as Je,bE as Ye,bF as Xe,bG as Ze,bH as Qe,bI as ts,bJ as es,bK as ss,bL as is,bM as os,bN as as,bO as ns,bP as rs,bQ as ls,bR as hs,bS as cs,bT as ds,bU as ps,bV as us,bW as _s,bX as ms,bY as gs,bZ as fs,b_ as bs,b$ as vs,c0 as ys,c1 as $s,c2 as ws,c3 as ks,c4 as xs,c5 as Ss,c6 as Ms,c7 as Cs,c8 as Ps,c9 as Ds,ca as Is,cb as Ts,cc as Rs,cd as zs,ce as As,cf as Fs,cg as Ns,ch as Es,ci as Hs,cj as Os,ck as Ls,cl as Bs,cm as Ws,cn as js,co as Gs,cp as qs,cq as Us,cr as Ks,cs as Vs,ct as Js,cu as Ys,cv as Xs,cw as Zs,cx as Qs,cy as ti,cz as ei,cA as si,cB as ii,cC as oi,cD as ai,cE as ni,cF as ri,cG as li,cH as hi,cI as ci,cJ as di,cK as pi,cL as ui,cM as _i,cN as mi,cO as gi,cP as fi,cQ as bi,cR as vi,cS as yi,cT as $i,cU as wi,cV as ki,cW as xi,cX as Si,cY as Mi,cZ as Ci,c_ as Pi,c$ as Di,d0 as Ii,d1 as Ti,d2 as Ri,d3 as zi,d4 as Ai,d5 as Fi,d6 as Ni,d7 as Ei,d8 as Hi,d9 as Oi,da as Li,db as Bi,dc as Wi,dd as ji,de as Gi,df as qi,dg as Ui,dh as Ki,di as Vi,dj as Ji,dk as Yi,dl as Xi,dm as Zi,dn as Qi,dp as to,dq as eo,dr as so,ds as io,dt as oo,du as ao,dv as no,dw as ro,dx as lo,dy as ho,dz as co,dA as po,dB as uo,dC as _o,dD as mo}from"./houseplan-card-Di_izZTU.js";import{F as go,f as fo,p as bo,c as vo,e as yo,r as $o,a as wo,s as ko}from"./backdrop-pick-CXmKHH6_.js";import{t as xo,h as So,m as Mo,T as Co}from"./zigbee-topology-Ba2URGlk.js";import{GENERATED_FURNITURE_ART as Po,FURNITURE_ART_FINGERPRINT as Do}from"./furniture-plan-art.generated-D_9nJ3h5.js";const Io={},To=t(class extends e{constructor(){super(...arguments),this.ot=Io}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return s}else if(this.ot===e)return s;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}});var Ro={"gs.hint":"Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.","gs.show_room_tooltip":"Show the room information window on hover","support.about_group":"About the card","support.guide_group":"Documentation","support.guide":"User guide","support.form_group":"Send a report or suggestion","support.contact":"Contact details (email/tg/WhatsApp), optional.","support.message":"Message","support.attach":"Attach anonymized information from your plan","support.attach_hint":"Includes only allowed plan geometry, settings and bounded runtime facts. Excludes names, Home Assistant IDs, live states, URLs, files, and your message/contact.","support.geometry_warning":"The package contains no names or Home Assistant IDs, but it does contain the exact geometry and dimensions of your home.","support.close_busy_title":"Stop the current operation?","support.close_busy_body":"House Plan is preparing or sending the report. Closing now stops waiting for the result.","support.building":"Preparing anonymized data…","support.preview_summary":"Package v{version} · {spaces} spaces · {size} KiB","support.prepared":"Snapshot prepared {n} min ago","support.show_data":"Show data","support.download":"Download JSON","support.refresh":"Refresh snapshot","support.privacy":"When you send, your message, optional contact and, if selected, exact geometry leave your Home Assistant through the House Plan project relay and are visible to maintainers. The project node keeps the report for up to 30 days. Network infrastructure sees your HA server address, but House Plan does not retain it raw; rate-limit and idempotency metadata is kept for up to 24 hours.","support.error_title":"The report was not sent","support.manual_recovery":"You can keep the message and attachment and continue manually:","support.copy_message":"Copy message","support.success":"Report sent: {id}. Save this number when contacting support.","support.copy_id":"Copy ID","support.sending":"Sending…","support.retry":"Retry","support.send":"Send","support.update_required":"Update the House Plan card and integration to compatible versions to send reports.","support.message_copied":"Message copied","support.id_copied":"Report ID copied","support.copy_failed":"Could not access the clipboard. Select and copy the text manually.","support.validation.message_required":"Enter a message.","support.validation.message_too_long":"The message must contain no more than 10,000 characters.","support.validation.contact_too_long":"Contact details must contain no more than 320 characters.","support.validation.preview_missing":"Wait for the attachment preview or turn the attachment off.","support.validation.preview_expired":"The attachment preview expired. Refresh the snapshot.","support.error.support_invalid_message":"Check the message and try again.","support.error.support_preview_expired":"The attachment preview expired or is no longer available. Refresh the snapshot.","support.error.support_package_too_large":"The anonymized package exceeds the 8 MiB limit.","support.error.support_rate_limited":"Too many reports or previews were requested. Try again later.","support.error.support_unavailable":"The private support service is temporarily unavailable. Your draft remains here.","support.error.support_rejected":"The report did not pass the support service validation.","support.error.unauthorized":"You do not have permission to send this report.","vac.routes_section":"Maps and floors","vac.routes_current_map":"Current map","vac.routes_no_map":"no telemetry","vac.routes_status":"Routing","vac.routes_state_ready":"map assigned and calibrated","vac.routes_state_needs_calibration":"map assigned, calibration needed","vac.routes_state_unmapped":"current map is not assigned to a floor","vac.routes_state_ambiguous":"two maps are indistinguishable — no floor is chosen","vac.routes_state_missing_space":"the map's space was deleted","vac.routes_state_none":"no map data","vac.routes_empty":"No map is assigned to a floor yet.","vac.route_map_default":"no map id","vac.route_active":"Active","vac.route_space":"Space","vac.route_space_none":"not selected","vac.route_status_ready":"ready","vac.route_status_needs_calibration":"needs calibration","vac.route_status_ambiguous":"ambiguous","vac.route_status_missing_space":"space deleted","vac.route_missing_space_group":"Deleted space","vac.route_add_current":"Add current map","vac.route_delete":"Remove map","vac.route_delete_title":"Remove the map from its floor?","vac.route_delete_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_delete_confirm":"Remove","vac.route_space_title":"Move the map to another space?","vac.route_space_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_space_confirm":"Move","vac.route_missing_space_hint":"One of the maps points at a deleted space: pick a new one or remove the map. Until then the robot is not drawn for that map.","vac.route_default_hint":"The source reports no stable map id. Several floors cannot be told apart without another source or the robot's own selected map.","vac.route_target_hint":"The dock stays in the “{space}” space regardless of the current map.","vac.route_add_source":"Add a map source","vac.route_add_source_hint":"For integrations that give each map its own camera. The “All cameras” section above widens this list.","vac.route_source_no_map":"no map reported"};const zo={en:Ro,ru:{"gs.hint":"Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.","gs.show_room_tooltip":"Показывать окно с информацией при наведении на комнату","support.about_group":"О карточке","support.guide_group":"Документация","support.guide":"Руководство пользователя","support.form_group":"Отправить репорт или предложение","support.contact":"Контакт для связи (email/tg/WhatsApp), необязательно.","support.message":"Сообщение","support.attach":"Прикрепить обезличенную информацию из вашего плана","support.attach_hint":"В пакет входят только разрешённые геометрия, настройки и ограниченные сведения о среде. Не входят имена, HA id, текущие состояния, URL, файлы, сообщение и контакт.","support.geometry_warning":"Пакет не содержит имён и HA id, но содержит точную геометрию и размеры дома.","support.close_busy_title":"Прервать текущую операцию?","support.close_busy_body":"House Plan подготавливает или отправляет репорт. При закрытии ожидание результата прекратится.","support.building":"Подготавливаем обезличенные данные…","support.preview_summary":"Пакет v{version} · пространств: {spaces} · {size} КиБ","support.prepared":"Снимок подготовлен {n} мин назад","support.show_data":"Показать данные","support.download":"Скачать JSON","support.refresh":"Обновить снимок","support.privacy":"При отправке сообщение, необязательный контакт и, если выбран пакет, точная геометрия покидают ваш Home Assistant через relay проекта House Plan и доступны мейнтейнерам. Узел проекта хранит репорт до 30 дней. Сетевая инфраструктура видит адрес сервера HA, но House Plan не сохраняет его в исходном виде; метаданные лимитов и идемпотентности хранятся до 24 часов.","support.error_title":"Репорт не отправлен","support.manual_recovery":"Сообщение и вложение можно сохранить и продолжить вручную:","support.copy_message":"Копировать сообщение","support.success":"Репорт отправлен: {id}. Сохраните номер для связи с поддержкой.","support.copy_id":"Копировать ID","support.sending":"Отправляем…","support.retry":"Повторить","support.send":"Отправить","support.update_required":"Обновите карточку и интеграцию House Plan до совместимых версий, чтобы отправлять репорты.","support.message_copied":"Сообщение скопировано","support.id_copied":"ID репорта скопирован","support.copy_failed":"Не удалось получить доступ к буферу обмена. Выделите и скопируйте текст вручную.","support.validation.message_required":"Введите сообщение.","support.validation.message_too_long":"Сообщение должно содержать не более 10 000 символов.","support.validation.contact_too_long":"Контакт должен содержать не более 320 символов.","support.validation.preview_missing":"Дождитесь предпросмотра вложения или отключите его.","support.validation.preview_expired":"Предпросмотр вложения истёк. Обновите снимок.","support.error.support_invalid_message":"Проверьте сообщение и повторите попытку.","support.error.support_preview_expired":"Предпросмотр вложения истёк или больше недоступен. Обновите снимок.","support.error.support_package_too_large":"Обезличенный пакет превышает лимит 8 МиБ.","support.error.support_rate_limited":"Запрошено слишком много репортов или предпросмотров. Повторите позже.","support.error.support_unavailable":"Закрытая служба поддержки временно недоступна. Черновик сохранён в этом окне.","support.error.support_rejected":"Репорт не прошёл проверку службы поддержки.","support.error.unauthorized":"У вас нет прав на отправку этого репорта.","vac.routes_section":"Карты и этажи","vac.routes_current_map":"Текущая карта","vac.routes_no_map":"источник молчит","vac.routes_status":"Маршрутизация","vac.routes_state_ready":"карта сопоставлена и откалибрована","vac.routes_state_needs_calibration":"карта сопоставлена, нужна калибровка","vac.routes_state_unmapped":"текущая карта не сопоставлена этажу","vac.routes_state_ambiguous":"две карты неразличимы — этаж не выбирается","vac.routes_state_missing_space":"пространство карты удалено","vac.routes_state_none":"нет данных о карте","vac.routes_empty":"Ни одна карта ещё не сопоставлена этажу.","vac.route_map_default":"без идентификатора","vac.route_active":"Текущая","vac.route_space":"Пространство","vac.route_space_none":"не выбрано","vac.route_status_ready":"готова","vac.route_status_needs_calibration":"нужна калибровка","vac.route_status_ambiguous":"неоднозначна","vac.route_status_missing_space":"пространство удалено","vac.route_missing_space_group":"Пространство удалено","vac.route_add_current":"Добавить текущую карту","vac.route_delete":"Удалить карту","vac.route_delete_title":"Удалить карту с этажа?","vac.route_delete_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_delete_confirm":"Удалить","vac.route_space_title":"Перенести карту в другое пространство?","vac.route_space_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_space_confirm":"Перенести","vac.route_missing_space_hint":"Одна из карт ссылается на удалённое пространство: выберите новое или удалите карту. Пока ссылка не исправлена, робот на этой карте не рисуется.","vac.route_default_hint":"Источник не сообщает стабильный идентификатор карты. Несколько этажей нельзя различить без другого источника или собственной карты робота.","vac.route_target_hint":"Док остаётся в пространстве «{space}» независимо от текущей карты.","vac.route_add_source":"Добавить источник карты","vac.route_add_source_hint":"Для интеграций, где у каждой карты своя камера. Список расширяется разделом «Все камеры» выше.","vac.route_source_no_map":"карта не читается"},de:{"gs.hint":"Füllfarben gelten für jeden Bereich; jede Farbe hat ihre eigene Deckkraft. Der Füllmodus wird in den Einstellungen des jeweiligen Bereichs festgelegt.","gs.show_room_tooltip":"Rauminformationen beim Darüberfahren anzeigen","support.about_group":"Über die Karte","support.guide_group":"Dokumentation","support.guide":"Benutzerhandbuch","support.form_group":"Bericht oder Vorschlag senden","support.contact":"Kontakt (E-Mail/tg/WhatsApp), optional.","support.message":"Nachricht","support.attach":"Anonymisierte Informationen aus dem Plan anhängen","support.attach_hint":"Enthält nur erlaubte Plangeometrie, Einstellungen und begrenzte Laufzeitdaten. Namen, Home-Assistant-IDs, Live-Zustände, URLs, Dateien, Nachricht und Kontakt werden ausgeschlossen.","support.geometry_warning":"Das Paket enthält keine Namen oder Home-Assistant-IDs, aber die exakte Geometrie und die Maße Ihres Hauses.","support.close_busy_title":"Aktuellen Vorgang abbrechen?","support.close_busy_body":"House Plan bereitet den Bericht vor oder sendet ihn. Beim Schließen wird nicht weiter auf das Ergebnis gewartet.","support.building":"Anonymisierte Daten werden vorbereitet…","support.preview_summary":"Paket v{version} · {spaces} Bereiche · {size} KiB","support.prepared":"Schnappschuss vor {n} Min. erstellt","support.show_data":"Daten anzeigen","support.download":"JSON herunterladen","support.refresh":"Schnappschuss aktualisieren","support.privacy":"Beim Senden verlassen Ihre Nachricht, der optionale Kontakt und, falls ausgewählt, die exakte Geometrie Ihren Home Assistant über das House-Plan-Projektrelay und sind für die Maintainer sichtbar. Der Projektserver speichert den Bericht bis zu 30 Tage. Die Netzwerkinfrastruktur sieht die Adresse Ihres HA-Servers, House Plan speichert sie jedoch nicht im Rohformat; Limit- und Idempotenzdaten bleiben bis zu 24 Stunden erhalten.","support.error_title":"Der Bericht wurde nicht gesendet","support.manual_recovery":"Nachricht und Anhang können gespeichert und manuell weitergegeben werden:","support.copy_message":"Nachricht kopieren","support.success":"Bericht gesendet: {id}. Bewahren Sie diese Nummer für den Support auf.","support.copy_id":"ID kopieren","support.sending":"Wird gesendet…","support.retry":"Erneut versuchen","support.send":"Senden","support.update_required":"Aktualisieren Sie House-Plan-Karte und Integration auf kompatible Versionen, um Berichte zu senden.","support.message_copied":"Nachricht kopiert","support.id_copied":"Berichts-ID kopiert","support.copy_failed":"Kein Zugriff auf die Zwischenablage. Markieren und kopieren Sie den Text manuell.","support.validation.message_required":"Geben Sie eine Nachricht ein.","support.validation.message_too_long":"Die Nachricht darf höchstens 10.000 Zeichen enthalten.","support.validation.contact_too_long":"Der Kontakt darf höchstens 320 Zeichen enthalten.","support.validation.preview_missing":"Warten Sie auf die Vorschau oder deaktivieren Sie den Anhang.","support.validation.preview_expired":"Die Anhangsvorschau ist abgelaufen. Aktualisieren Sie den Schnappschuss.","support.error.support_invalid_message":"Prüfen Sie die Nachricht und versuchen Sie es erneut.","support.error.support_preview_expired":"Die Anhangsvorschau ist abgelaufen oder nicht mehr verfügbar. Aktualisieren Sie den Schnappschuss.","support.error.support_package_too_large":"Das anonymisierte Paket überschreitet das Limit von 8 MiB.","support.error.support_rate_limited":"Zu viele Berichte oder Vorschauen wurden angefordert. Versuchen Sie es später erneut.","support.error.support_unavailable":"Der private Supportdienst ist vorübergehend nicht verfügbar. Der Entwurf bleibt in diesem Fenster erhalten.","support.error.support_rejected":"Der Bericht hat die Prüfung des Supportdienstes nicht bestanden.","support.error.unauthorized":"Sie dürfen diesen Bericht nicht senden.","vac.routes_section":"Karten und Etagen","vac.routes_current_map":"Aktuelle Karte","vac.routes_no_map":"keine Telemetrie","vac.routes_status":"Zuordnung","vac.routes_state_ready":"Karte zugeordnet und kalibriert","vac.routes_state_needs_calibration":"Karte zugeordnet, Kalibrierung nötig","vac.routes_state_unmapped":"aktuelle Karte keiner Etage zugeordnet","vac.routes_state_ambiguous":"zwei Karten nicht unterscheidbar — keine Etage gewählt","vac.routes_state_missing_space":"der Raum der Karte wurde gelöscht","vac.routes_state_none":"keine Kartendaten","vac.routes_empty":"Noch keine Karte einer Etage zugeordnet.","vac.route_map_default":"ohne Karten-ID","vac.route_active":"Aktiv","vac.route_space":"Raum","vac.route_space_none":"nicht gewählt","vac.route_status_ready":"bereit","vac.route_status_needs_calibration":"Kalibrierung nötig","vac.route_status_ambiguous":"mehrdeutig","vac.route_status_missing_space":"Raum gelöscht","vac.route_missing_space_group":"Gelöschter Bereich","vac.route_add_current":"Aktuelle Karte hinzufügen","vac.route_delete":"Karte entfernen","vac.route_delete_title":"Karte von der Etage entfernen?","vac.route_delete_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_delete_confirm":"Entfernen","vac.route_space_title":"Karte in einen anderen Raum verschieben?","vac.route_space_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_space_confirm":"Verschieben","vac.route_missing_space_hint":"Eine Karte verweist auf einen gelöschten Raum: neuen wählen oder Karte entfernen. Bis dahin wird der Roboter für diese Karte nicht gezeichnet.","vac.route_default_hint":"Die Quelle meldet keine stabile Karten-ID. Mehrere Etagen lassen sich ohne andere Quelle oder die vom Roboter gewählte Karte nicht unterscheiden.","vac.route_target_hint":"Die Station bleibt unabhängig von der aktuellen Karte im Raum „{space}“.","vac.route_add_source":"Kartenquelle hinzufügen","vac.route_add_source_hint":"Für Integrationen, die jeder Karte eine eigene Kamera geben. Der Abschnitt „Alle Kameras“ oben erweitert diese Liste.","vac.route_source_no_map":"keine Karte gemeldet"},fr:{"gs.hint":"Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.","gs.show_room_tooltip":"Afficher les informations de la pièce au survol","support.about_group":"À propos de la carte","support.guide_group":"Documentation d’aide","support.guide":"Guide utilisateur","support.form_group":"Envoyer un rapport ou une suggestion","support.contact":"Contact (e-mail/tg/WhatsApp), facultatif.","support.message":"Votre message","support.attach":"Joindre des informations anonymisées de votre plan","support.attach_hint":"Inclut uniquement la géométrie, les réglages autorisés et des données d’exécution limitées. Exclut les noms, identifiants Home Assistant, états en direct, URL, fichiers, message et contact.","support.geometry_warning":"Le paquet ne contient ni noms ni identifiants Home Assistant, mais il contient la géométrie et les dimensions exactes de votre logement.","support.close_busy_title":"Interrompre l’opération en cours ?","support.close_busy_body":"House Plan prépare ou envoie le rapport. Fermer maintenant arrête l’attente du résultat.","support.building":"Préparation des données anonymisées…","support.preview_summary":"Paquet v{version} · {spaces} espaces · {size} Kio","support.prepared":"Instantané préparé il y a {n} min","support.show_data":"Afficher les données","support.download":"Télécharger le JSON","support.refresh":"Actualiser l’instantané","support.privacy":"Lors de l’envoi, votre message, le contact facultatif et, si elle est sélectionnée, la géométrie exacte quittent votre Home Assistant via le relais du projet House Plan et sont visibles par les mainteneurs. Le serveur du projet conserve le rapport jusqu’à 30 jours. L’infrastructure réseau voit l’adresse de votre serveur HA, mais House Plan ne la conserve pas en clair ; les métadonnées de limitation et d’idempotence sont gardées jusqu’à 24 heures.","support.error_title":"Le rapport n’a pas été envoyé","support.manual_recovery":"Vous pouvez conserver le message et la pièce jointe puis continuer manuellement :","support.copy_message":"Copier le message","support.success":"Rapport envoyé : {id}. Conservez ce numéro pour contacter l’assistance.","support.copy_id":"Copier l’ID","support.sending":"Envoi…","support.retry":"Réessayer","support.send":"Envoyer","support.update_required":"Mettez à jour la carte et l’intégration House Plan vers des versions compatibles pour envoyer des rapports.","support.message_copied":"Message copié","support.id_copied":"ID du rapport copié","support.copy_failed":"Impossible d’accéder au presse-papiers. Sélectionnez et copiez le texte manuellement.","support.validation.message_required":"Saisissez un message.","support.validation.message_too_long":"Le message ne doit pas dépasser 10 000 caractères.","support.validation.contact_too_long":"Le contact ne doit pas dépasser 320 caractères.","support.validation.preview_missing":"Attendez l’aperçu de la pièce jointe ou désactivez-la.","support.validation.preview_expired":"L’aperçu de la pièce jointe a expiré. Actualisez l’instantané.","support.error.support_invalid_message":"Vérifiez le message et réessayez.","support.error.support_preview_expired":"L’aperçu de la pièce jointe a expiré ou n’est plus disponible. Actualisez l’instantané.","support.error.support_package_too_large":"Le paquet anonymisé dépasse la limite de 8 Mio.","support.error.support_rate_limited":"Trop de rapports ou d’aperçus ont été demandés. Réessayez plus tard.","support.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible. Le brouillon reste dans cette fenêtre.","support.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","support.error.unauthorized":"Vous n’êtes pas autorisé à envoyer ce rapport.","vac.routes_section":"Cartes et étages","vac.routes_current_map":"Carte actuelle","vac.routes_no_map":"aucune télémétrie","vac.routes_status":"Routage","vac.routes_state_ready":"carte assignée et calibrée","vac.routes_state_needs_calibration":"carte assignée, calibrage requis","vac.routes_state_unmapped":"carte actuelle non assignée à un étage","vac.routes_state_ambiguous":"deux cartes indiscernables — aucun étage choisi","vac.routes_state_missing_space":"l'espace de la carte a été supprimé","vac.routes_state_none":"aucune donnée de carte","vac.routes_empty":"Aucune carte n'est encore assignée à un étage.","vac.route_map_default":"sans identifiant","vac.route_active":"Active","vac.route_space":"Espace","vac.route_space_none":"non sélectionné","vac.route_status_ready":"prête","vac.route_status_needs_calibration":"calibrage requis","vac.route_status_ambiguous":"ambiguë","vac.route_status_missing_space":"espace supprimé","vac.route_missing_space_group":"Espace supprimé","vac.route_add_current":"Ajouter la carte actuelle","vac.route_delete":"Supprimer la carte","vac.route_delete_title":"Retirer la carte de son étage ?","vac.route_delete_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_delete_confirm":"Supprimer","vac.route_space_title":"Déplacer la carte vers un autre espace ?","vac.route_space_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_space_confirm":"Déplacer","vac.route_missing_space_hint":"Une carte pointe vers un espace supprimé : choisissez-en un autre ou supprimez la carte. D'ici là, le robot n'est pas dessiné pour cette carte.","vac.route_default_hint":"La source ne fournit pas d'identifiant de carte stable. Plusieurs étages ne peuvent pas être distingués sans une autre source ou la carte sélectionnée du robot.","vac.route_target_hint":"La station reste dans l'espace « {space} » quelle que soit la carte actuelle.","vac.route_add_source":"Ajouter une source de carte","vac.route_add_source_hint":"Pour les intégrations qui donnent à chaque carte sa propre caméra. La section « Toutes les caméras » ci-dessus élargit cette liste.","vac.route_source_no_map":"aucune carte signalée"}};function Ao(t,e,s){return i(zo[t]?.[e]??Ro[e]??e,s)}function Fo(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function No(t,e,s){return{...t,space:s.has(e)?e:""}}function Eo(t,e=Math.random){const s=new Set(t);for(let t=0;t<64;t+=1){const t="vr_"+Math.floor(16777215*e()).toString(36).padStart(5,"0");if(!s.has(t))return t}return"vr_"+Date.now().toString(36)}function Ho(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const Oo=new WeakMap,Lo=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function Bo(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>Ao(n,t,e),u=e.marker?.vacuum||{},_=Array.isArray(u.map_routes),m=i._vacSource(e)||"",g=o(e.id,u,e.space,m),f=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),b=new Set(f.map(t=>t.id)),v=h(g,[m],t=>i._vacObservedMapId(e,t)),y=c({routes:g,observed:v,spaceIds:b}),$="ready"===y.kind||"needs_calibration"===y.kind||"missing_space"===y.kind?y.route.id:"",w=m?v[m]:void 0,k=async s=>{let o=_?u.map_routes??null:null;if(!o&&(o=function(t,e,s,i){if(!s)return null;const o=t?.calibration;if(!o||"object"!=typeof o)return null;const n=new Set,r=[];for(const t of Object.keys(o)){const l=a(o[t]);if(!l)continue;const h=i(n);n.add(h),r.push({id:h,source:s,map_id:t,space:e,calibration:l})}return r.length?r:null}(u,e.space,m,t=>Eo(t))??[],!m&&Object.keys(u.calibration||{}).length))return!1;const n=s(o);return!!n&&(async s=>{const o=i._serverCfg;if(!o)return!1;const a=JSON.parse(JSON.stringify(o));a.markers=a.markers||[];let n=a.markers.find(t=>t.id===e.id);if(!n){if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return!1;n={id:e.id,binding:`${e.bindingKind}:${e.bindingRef}`,space:e.space||null,area:e.area||null,hidden:!!e.hidden},a.markers.push(n)}n.vacuum={...n.vacuum||{},map_routes:s},delete n.vacuum.calibration;const r=i._adoption.beginOptimistic(o,a);i._adoption.stageLocalConfig(a),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return i._rollbackOptimistic(r),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},x=s.candidates.filter(t=>t.entityId!==m&&!g.some(e=>e.source===t.entityId)),S=async(t,e)=>{if(!e||e===t.space)return;await i._confirmDanger({key:"vacuum_route_space",kind:"warning",title:r("vac.route_space_title"),message:r("vac.route_space_body"),objectName:t.map_id||r("vac.route_map_default"),confirmLabel:r("vac.route_space_confirm"),cancelLabel:i._t("btn.cancel")})&&await k(s=>function(t,e,s,i){return t.map(t=>t.id===e?{...t,id:i,space:s,calibration:null}:t)}(s,t.id,e,Eo(new Set(g.map(t=>t.id)))))},M=new Map(f.map((t,e)=>[t.id,e])),C=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),P=g.filter(t=>b.has(t.space)).sort((t,e)=>(M.get(t.space)??0)-(M.get(e.space)??0)||C(t,e)),D=g.filter(t=>!b.has(t.space)).sort(C),I=[...P,...D],T=!!m&&void 0!==w&&!g.some(t=>t.source===m&&t.map_id===w);let R=Oo.get(t);const z=R?.source||"",A=R?.mapId||"",F=!!R&&g.some(t=>t.source===z&&t.map_id===A);R&&(R.markerId!==e.id||i._vacObservedMapId(e,R.source)!==R.mapId||F&&!R.saving)&&(Oo.delete(t),R=void 0),R?.space&&!b.has(R.space)&&(R=No(R,"",b),Oo.set(t,R));const N=s=>p`
  • ${s.map_id||r("vac.route_map_default")} @@ -27,26 +27,26 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${r("vac.routes_current_map")}${void 0===w?r("vac.routes_no_map"):w||r("vac.route_map_default")}
    ${r("vac.routes_status")}${r(`vac.routes_state_${y.kind}`)}
    - ${P.length||z?p`
      - ${z?p` + ${P.length||R?p`
        + ${R?p`
      • -
        ${z.mapId||r("vac.route_map_default")}
        - ${z.source} +
        ${R.mapId||r("vac.route_map_default")}
        + ${R.source}
        - + + ?disabled=${!!R.saving||!b.has(R.space)} + @click=${()=>{(async()=>{const e=Oo.get(t);if(!e||e.saving||!b.has(e.space))return;Oo.set(t,{...e,saving:!0}),i.requestUpdate();const s=await k(t=>function(t,e,s,i){return e.source&&s.has(e.space)&&!t.some(t=>t.source===e.source&&t.map_id===e.mapId)?function(t,e,s){return[...t,{...e,id:s,calibration:e.calibration??null}]}(t,{source:e.source,map_id:e.mapId,space:e.space},i):null}(t,e,b,Eo(new Set(t.map(t=>t.id))))),o=Oo.get(t);o?.markerId===e.markerId&&o.source===e.source&&o.mapId===e.mapId&&(s?Oo.delete(t):Oo.set(t,e)),i.requestUpdate()})()}}>${i._t("btn.save")}
      • `:d} ${P.map(N)} @@ -59,18 +59,18 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
          ${D.map(N)}
        `:d} - ${I.length||z?d:p`
        ${r("vac.routes_empty")}
        `} + ${I.length||R?d:p`
        ${r("vac.routes_empty")}
        `}
        - +
        ${x.length?p`
        ${r("vac.route_add_source")}
        ${r("vac.route_add_source_hint")}
        ${x.map(s=>{const o=i._vacObservedMapId(e,s.entityId);return p``})} @@ -80,8 +80,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
        ${r("vac.route_missing_space_hint")}
        `:d} ${g.some(t=>"default"===t.map_id)?p`
        ${r("vac.route_default_hint")}
        `:d} - ${I.length?p`
        ${r("vac.route_target_hint",{space:Oo(i,e.space)})}
        `:d} -
        `}const Bo=new WeakMap;function Wo(t,e,s){let i=Bo.get(t);i||(i=new Map,Bo.set(t,i));const o=i.get(e);if(o)return void(o.run=s);const a={run:s};i.set(e,a),queueMicrotask(()=>{i.get(e)===a&&(i.delete(e),a.run())})}function jo(t,e){const s=Bo.get(t),i=s?.get(e);i&&(s.delete(e),i.run())}function Go(t,e){const s=Bo.get(t);if(!s)return;const i=e?[...s].filter(([t])=>t===e):[...s];for(const[t]of i)s.delete(t);s.size||Bo.delete(t)}const qo=new WeakMap,Uo=new Set(["_cursorPt","_opMeasure","_physicalDrag","_physicalRotate","_decorDraft","_dtBox","_dtDrag","_bdDrag","_furnPreviewInput","_layout"]),Ko=new Set(["_cursorPt","_opMeasure","_furnPreviewInput"]),Vo=new Set(["_physicalDrag","_physicalRotate","_decorDraft","_dtDrag","_bdDrag"]),Jo=t=>{let e=qo.get(t);return e||(e={raf:0,requestedRevision:0,paintedRevision:0,waiters:[],hidden:[],transparent:[],dimmed:[]},qo.set(t,e)),e},Yo=(t,e)=>{t.paintedRevision=Math.max(t.paintedRevision,e);const s=t.waiters.filter(e=>e.revision<=t.paintedRevision);t.waiters=t.waiters.filter(e=>e.revision>t.paintedRevision);for(const t of s)t.resolve()},Xo=t=>!!("view"!==t._mode&&(t._deviceDrag||t._physicalDrag||t._physicalRotate||t._decorDraft||t._decorMove||t._dtDrag||t._bdDrag||t._opDrag||t._resize?.dragging));function Zo(t,e,s){const i=t;if(!i?.isConnected||"view"===i._mode)return!1;const o=void 0!==e&&Uo.has(e);if("_layout"===e&&!i._deviceDrag)return!1;if("_dtBox"===e&&!i._dtDrag)return!1;if(void 0!==e&&Vo.has(e)&&null==s&&null!=i[e]&&Xo(i))return!1;if(void 0!==e&&Vo.has(e)&&null==i[e])return!1;if(void 0!==e&&Ko.has(e)&&null==i[e])return!1;return!!(o&&(Ko.has(e)||Xo(i))||void 0===e&&Xo(i))&&(function(t){const e=Jo(t);if(e.requestedRevision++,e.raf||"function"!=typeof requestAnimationFrame)return;e.raf=requestAnimationFrame(()=>{e.raf=0;const s=e.requestedRevision;!function(t){const e=t,s=e.renderRoot;if(!s)return;const i=Jo(e);ea(i),oa(e,s);const o=s.querySelector("[data-hp-live-editor]");if(!o)return;if(ta(i,s,".hp-editor-only-layer:not(.hp-plan-snap-layer)"),"plan"===e._mode)e._opDrag&&Qo(i,s,".wallbodies"),e._resize?.dragging&&(ra(i,s,".wallbodies"),ta(i,s,".resize-layer"),na(i,s,e._resize.plan?.movingOpeningIds||[])),e._opDrag&&ta(i,s,".openinglayer");else if("decor"===e._mode){const t=e._dtDrag?.id||e._decorMove?.id;t&&aa(i,s,t),ta(i,s,".dtframe, .backdropframe")}u(ia(e),o);const a=s.querySelector("[data-hp-live-editor-html]");if(a){const t=e._viewOr(e._baseVb());u(e._renderLiveEditorMeasurements(t),a)}e._liveEditorPaintCount=(e._liveEditorPaintCount||0)+1}(t),Yo(e,s)})}(i),!0)}const Qo=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"hidden"!==i.style.visibility&&(i.style.visibility="hidden",t.hidden.push(i))},ta=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},ea=t=>{for(const e of t.hidden)e.style.removeProperty("visibility");t.hidden.length=0;for(const e of t.transparent)e.style.removeProperty("opacity");t.transparent.length=0;for(const e of t.dimmed)e.style.removeProperty("opacity");t.dimmed.length=0},sa=(t,e,s=[])=>{if("iso"===t._renderProjection)return _``;const i=t._spaceModel();if(!i)return _``;const o=new Set(s),a=(i.rooms||[]).filter(t=>!!t.id&&o.has(t.id)).flatMap(t=>{const e=t.poly||[];return e.map((t,s)=>[t,e[(s+1)%e.length]])}),n=(t,e)=>{const[s,i]=e,o=i[0]-s[0],a=i[1]-s[1],n=o*o+a*a;if(!(n>0))return!1;const r=((t[0]-s[0])*o+(t[1]-s[1])*a)/n,l=Math.max(0,Math.min(1,r));return Math.hypot(t[0]-s[0]-o*l,t[1]-s[1]-a*l)<1e-4},r=[...t._spaceWalls.filter(t=>{const e=(t.a||[]).map(t=>t*m),s=(t.b||[]).map(t=>t*m);return a.some(t=>n(e,t)&&n(s,t))}).map((e,s)=>((e,s,i,o)=>{const a=Math.hypot(s[0]-e[0],s[1]-e[1]);if(!(a>1e-9&&i>0))return null;const n=$(i,t._cellCm,t._gridPitch)/2,r=-(s[1]-e[1])/a*n,l=(s[0]-e[0])/a*n;return{key:o,kind:"outer",cm:i,a:e,b:s,depthUnits:2*n,quad:[[e[0]+r,e[1]+l],[s[0]+r,s[1]+l],[s[0]-r,s[1]-l],[e[0]-r,e[1]-l]]}})((e.a||[]).map(t=>t*m),(e.b||[]).map(t=>t*m),e.cm,e.key||`wall-${s}`))].filter(t=>!!t),l=t._openingsR.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),h=r.map(t=>g(t,l)).filter(Boolean);if(!h.length)return _``;const c=Math.max(...r.map(t=>t.depthUnits),0),d=t._viewOr(t._baseVb()),p=t._stageEl?.clientWidth&&d.w?t._stageEl.clientWidth/d.w:1,u=f(c,p)||b(v(t._cellCm),p),w=e?.color||"#607d8b",k=t._fillColors.wall_fill,x=h.join(" ");return _`${r("vac.route_target_hint",{space:Lo(i,e.space)})}
  • `:d} +
    `}const Wo=new WeakMap;function jo(t,e,s){let i=Wo.get(t);i||(i=new Map,Wo.set(t,i));const o=i.get(e);if(o)return void(o.run=s);const a={run:s};i.set(e,a),queueMicrotask(()=>{i.get(e)===a&&(i.delete(e),a.run())})}function Go(t,e){const s=Wo.get(t),i=s?.get(e);i&&(s.delete(e),i.run())}function qo(t,e){const s=Wo.get(t);if(!s)return;const i=e?[...s].filter(([t])=>t===e):[...s];for(const[t]of i)s.delete(t);s.size||Wo.delete(t)}const Uo=new WeakMap,Ko=new Set(["_cursorPt","_opMeasure","_physicalDrag","_physicalRotate","_decorDraft","_dtBox","_dtDrag","_bdDrag","_furnPreviewInput","_layout"]),Vo=new Set(["_cursorPt","_opMeasure","_furnPreviewInput"]),Jo=new Set(["_physicalDrag","_physicalRotate","_decorDraft","_dtDrag","_bdDrag"]),Yo=t=>{let e=Uo.get(t);return e||(e={raf:0,requestedRevision:0,paintedRevision:0,waiters:[],hidden:[],transparent:[],dimmed:[]},Uo.set(t,e)),e},Xo=(t,e)=>{t.paintedRevision=Math.max(t.paintedRevision,e);const s=t.waiters.filter(e=>e.revision<=t.paintedRevision);t.waiters=t.waiters.filter(e=>e.revision>t.paintedRevision);for(const t of s)t.resolve()},Zo=t=>!!("view"!==t._mode&&(t._deviceDrag||t._physicalDrag||t._physicalRotate||t._decorDraft||t._decorMove||t._dtDrag||t._bdDrag||t._opDrag||t._resize?.dragging));function Qo(t,e,s){const i=t;if(!i?.isConnected||"view"===i._mode)return!1;const o=void 0!==e&&Ko.has(e);if("_layout"===e&&!i._deviceDrag)return!1;if("_dtBox"===e&&!i._dtDrag)return!1;if(void 0!==e&&Jo.has(e)&&null==s&&null!=i[e]&&Zo(i))return!1;if(void 0!==e&&Jo.has(e)&&null==i[e])return!1;if(void 0!==e&&Vo.has(e)&&null==i[e])return!1;return!!(o&&(Vo.has(e)||Zo(i))||void 0===e&&Zo(i))&&(function(t){const e=Yo(t);if(e.requestedRevision++,e.raf||"function"!=typeof requestAnimationFrame)return;e.raf=requestAnimationFrame(()=>{e.raf=0;const s=e.requestedRevision;!function(t){const e=t,s=e.renderRoot;if(!s)return;const i=Yo(e);sa(i),aa(e,s);const o=s.querySelector("[data-hp-live-editor]");if(!o)return;if(ea(i,s,".hp-editor-only-layer:not(.hp-plan-snap-layer)"),"plan"===e._mode)e._opDrag&&ta(i,s,".wallbodies"),e._resize?.dragging&&(la(i,s,".wallbodies"),ea(i,s,".resize-layer"),ra(i,s,e._resize.plan?.movingOpeningIds||[])),e._opDrag&&ea(i,s,".openinglayer");else if("decor"===e._mode){const t=e._dtDrag?.id||e._decorMove?.id;t&&na(i,s,t),ea(i,s,".dtframe, .backdropframe")}u(oa(e),o);const a=s.querySelector("[data-hp-live-editor-html]");if(a){const t=e._viewOr(e._baseVb());u(e._renderLiveEditorMeasurements(t),a)}e._liveEditorPaintCount=(e._liveEditorPaintCount||0)+1}(t),Xo(e,s)})}(i),!0)}const ta=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"hidden"!==i.style.visibility&&(i.style.visibility="hidden",t.hidden.push(i))},ea=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},sa=t=>{for(const e of t.hidden)e.style.removeProperty("visibility");t.hidden.length=0;for(const e of t.transparent)e.style.removeProperty("opacity");t.transparent.length=0;for(const e of t.dimmed)e.style.removeProperty("opacity");t.dimmed.length=0},ia=(t,e,s=[])=>{if("iso"===t._renderProjection)return _``;const i=t._spaceModel();if(!i)return _``;const o=new Set(s),a=(i.rooms||[]).filter(t=>!!t.id&&o.has(t.id)).flatMap(t=>{const e=t.poly||[];return e.map((t,s)=>[t,e[(s+1)%e.length]])}),n=(t,e)=>{const[s,i]=e,o=i[0]-s[0],a=i[1]-s[1],n=o*o+a*a;if(!(n>0))return!1;const r=((t[0]-s[0])*o+(t[1]-s[1])*a)/n,l=Math.max(0,Math.min(1,r));return Math.hypot(t[0]-s[0]-o*l,t[1]-s[1]-a*l)<1e-4},r=[...t._spaceWalls.filter(t=>{const e=(t.a||[]).map(t=>t*m),s=(t.b||[]).map(t=>t*m);return a.some(t=>n(e,t)&&n(s,t))}).map((e,s)=>((e,s,i,o)=>{const a=Math.hypot(s[0]-e[0],s[1]-e[1]);if(!(a>1e-9&&i>0))return null;const n=$(i,t._cellCm,t._gridPitch)/2,r=-(s[1]-e[1])/a*n,l=(s[0]-e[0])/a*n;return{key:o,kind:"outer",cm:i,a:e,b:s,depthUnits:2*n,quad:[[e[0]+r,e[1]+l],[s[0]+r,s[1]+l],[s[0]-r,s[1]-l],[e[0]-r,e[1]-l]]}})((e.a||[]).map(t=>t*m),(e.b||[]).map(t=>t*m),e.cm,e.key||`wall-${s}`))].filter(t=>!!t),l=t._openingsR.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),h=r.map(t=>g(t,l)).filter(Boolean);if(!h.length)return _``;const c=Math.max(...r.map(t=>t.depthUnits),0),d=t._viewOr(t._baseVb()),p=t._stageEl?.clientWidth&&d.w?t._stageEl.clientWidth/d.w:1,u=f(c,p)||b(v(t._cellCm),p),w=e?.color||"#607d8b",k=t._fillColors.wall_fill,x=h.join(" ");return _` @@ -89,8 +89,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 data-id="preview" data-kind="preview" d=${x} fill=${u?"none":"url(#hp-wall-hatch)"} fill-rule="nonzero" stroke=${w} stroke-width=${y(.6,t._cellCm)}> - `},ia=t=>{if("plan"===t._mode)return(t=>{const e=t._baseVb(),s=t._viewOr(e),i=t._opMeasureView;if(t._resize?.dragging){const e=t._spaceDisplayForRender(),i=t._resize.plan;return _``},oa=t=>{if("plan"===t._mode)return(t=>{const e=t._baseVb(),s=t._viewOr(e),i=t._opMeasureView;if(t._resize?.dragging){const e=t._spaceDisplayForRender(),i=t._resize.plan;return _``}return _``},oa=(t,e)=>{const s=t._deviceDrag;if(!s)return;const i=t._devices.find(t=>t.id===s.id),o=[...e.querySelectorAll('[data-hp="device"]')].find(t=>t.dataset.id===s.id);if(!i||!o)return;const a=t._livePos(i),n=t._scenePoint([a.x,a.y]),r=t._viewOr(t._baseVb());o.style.left=(n[0]-r.x)/r.w*100+"%",o.style.top=(n[1]-r.y)/r.h*100+"%"},aa=(t,e,s)=>{for(const i of e.querySelectorAll('.decorlayer [data-hp="decor"]'))i.closest("[data-hp-live-editor]")||i.dataset.id!==s||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},na=(t,e,s)=>{const i=new Set(s);for(const s of e.querySelectorAll('.openinglayer [data-hp="opening"]'))!s.closest("[data-hp-live-editor]")&&i.has(s.dataset.id||"")&&(s.style.opacity="0",t.transparent.push(s))},ra=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||(i.style.opacity="0.35",t.dimmed.push(i))};const la=(t,e,s)=>Math.min(s,Math.max(e,Number.isFinite(t)?t:e));function ha(t){return Number.isFinite(t)?(t%360+360)%360:0}function ca(t){if("string"!=typeof t)return null;const e=t.trim().replace(/^#/,""),s=/^[0-9a-fA-F]{3}$/.test(e)?e.split("").map(t=>`${t}${t}`).join(""):e;return/^[0-9a-fA-F]{6}$/.test(s)?`#${s.toLowerCase()}`:null}function da(t){const e=ca(t);return e?{r:Number.parseInt(e.slice(1,3),16),g:Number.parseInt(e.slice(3,5),16),b:Number.parseInt(e.slice(5,7),16)}:null}function pa(t){const e=la(t.r,0,255)/255,s=la(t.g,0,255)/255,i=la(t.b,0,255)/255,o=Math.max(e,s,i),a=o-Math.min(e,s,i);let n=0;return a>0&&(n=o===e?(s-i)/a%6*60:o===s?60*((i-e)/a+2):60*((e-s)/a+4)),{h:ha(n),s:0===o?0:a/o*100,v:100*o}}function ua(t){return function(t){const e=t=>Math.round(la(t,0,255)).toString(16).padStart(2,"0");return`#${e(t.r)}${e(t.g)}${e(t.b)}`}(function(t){const e=ha(t.h),s=la(t.s,0,100)/100,i=la(t.v,0,100)/100,o=i*s,a=o*(1-Math.abs(e/60%2-1)),n=i-o;let r;return r=e<60?[o,a,0]:e<120?[a,o,0]:e<180?[0,o,a]:e<240?[0,a,o]:e<300?[a,0,o]:[o,0,a],{r:Math.round(255*(r[0]+n)),g:Math.round(255*(r[1]+n)),b:Math.round(255*(r[2]+n))}}(t))}const _a={title:"Color picker",hue:"Hue",saturation:"Saturation",value:"Brightness",hex:"Hex color",invalidHex:"Enter a 3- or 6-digit hex color",confirm:"OK"};class ma extends k{constructor(){super(...arguments),this.label="",this.opacityLabel="Opacity",this.color="#607d8b",this.opacity=1,this.disabled=!1,this.showOpacity=!0,this.pickerLabels=_a,this._open=!1,this._pickerRaf=0,this._emitRaf=0,this._forceFallback=!1,this._overlayDispose=null,this._hue=0,this._saturation=0,this._value=0,this._hexDraft="#607d8b",this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor="#607d8b",this._activePointerId=null,this._outsidePointerDown=t=>{if(!this._open)return;const e=t.composedPath();this._floating.containsPath(e)||this._closePicker(!1,"outside")},this._keyDown=t=>{this._open&&"Escape"===t.key&&(t.preventDefault(),t.stopImmediatePropagation(),this._closePicker(this._floating.ownsActiveElement(),"escape"))},this._floating=new mo(this,"color-opacity",this._keyDown),this._queuePickerPosition=()=>{if(!this._open)return;this._pickerRaf&&cancelAnimationFrame(this._pickerRaf);const t=this._window();t&&(this._pickerRaf=t.requestAnimationFrame(()=>{this._pickerRaf=0,this._positionPicker()||this._closePicker()}))}}connectedCallback(){super.connectedCallback(),this._syncFromColor(this.color,!1),this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.addEventListener("resize",this._queuePickerPosition),t?.addEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.addEventListener("resize",this._queuePickerPosition),t?.visualViewport?.addEventListener("scroll",this._queuePickerPosition),this.addEventListener("keydown",this._keyDown,!0)}disconnectedCallback(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.removeEventListener("resize",this._queuePickerPosition),t?.removeEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.removeEventListener("resize",this._queuePickerPosition),t?.visualViewport?.removeEventListener("scroll",this._queuePickerPosition),this.removeEventListener("keydown",this._keyDown,!0),this._pickerRaf&&cancelAnimationFrame(this._pickerRaf),this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._pickerRaf=0,this._emitRaf=0,this._closePicker(!1,"disconnect"),super.disconnectedCallback()}updated(t){if(t.has("color")){const t=ca(this.color);t&&t!==this._lastValidColor&&this._syncFromColor(t,this._open)}this.disabled&&this._open?this._closePicker():this._open&&(this._supportsPopover()||this._renderFallback(),(t.has("color")||t.has("opacity")||t.has("showOpacity")||t.has("label")||t.has("opacityLabel")||t.has("pickerLabels"))&&this._queuePickerPosition())}_window(){return this._floating.window()}_supportsPopover(){return this._floating.usesPopover(this._forceFallback)}_dialog(){return this._floating.dialog()}async _toggle(){this.disabled||(this._open?this._closePicker():(this._forceFallback=!1,this._syncFromColor(this.color,!1),this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._activePointerId=null,this._open=!0,await this.updateComplete,this._open&&(this._supportsPopover()||this._renderFallback(),this._positionPicker()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:t=>this._closePicker("escape"===t&&this._floating.ownsActiveElement(),t)})||null:this._closePicker())))}_closePicker(t=!1,e="exclusive"){if(!this._open&&!this._floating.hasFallback)return;const s=this._overlayDispose;this._overlayDispose=null,s?.();const i=this.renderRoot.querySelector(".picker");if(i?.hidePopover)try{i.matches(":popover-open")&&i.hidePopover()}catch{}this._open=!1,this._cancelQueuedEmit(),this._activePointerId=null,this._floating.destroy(),t&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_surface(){return this._floating.surface(".picker",this._supportsPopover())}_renderFallback(){const t=ma.styles.cssText;this._floating.renderFallback(this._pickerTemplate(!1),t)}_positionPicker(){if(!this._open)return!1;const t=this._window(),e=this.renderRoot.querySelector(".trigger");let s=this._surface();if(!t||!e?.isConnected||!s?.isConnected)return!1;const i=go(t);if(s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden",this._supportsPopover()&&s.showPopover)try{s.matches(":popover-open")||s.showPopover()}catch{if(this._forceFallback=!0,this._renderFallback(),s=this._surface(),!s?.isConnected)return!1;s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden"}const o=e.getBoundingClientRect(),a=s.getBoundingClientRect();if(!(o.width&&o.height&&a.width&&a.height))return!1;const n=fo(o,a,i);return s.style.left=`${n.left}px`,s.style.top=`${n.top}px`,s.dataset.side=n.side,s.style.visibility="",!0}_labels(){const t=this.pickerLabels||_a;return{title:t.title||_a.title,hue:t.hue||_a.hue,saturation:t.saturation||_a.saturation,value:t.value||_a.value,hex:t.hex||_a.hex,invalidHex:t.invalidHex||_a.invalidHex,confirm:t.confirm||_a.confirm}}_syncFromColor(t,e){const s=ca(x(t,"#607d8b"))||"#607d8b",i=da(s);if(!i)return;const o=pa(i);(!e||o.s>1e-4)&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._hexDraft=s,this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor=s}_cancelQueuedEmit(t=!1){this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._emitRaf=0,t&&this._syncFromColor(this._lastValidColor,!0)}_queueHsvEmit(){if(this._emitRaf)return;const t=this._window();t?this._emitRaf=t.requestAnimationFrame(()=>{this._emitRaf=0,this._emitHsv()}):this._emitHsv()}_emitHsv(){this._emit(ua({h:this._hue,s:this._saturation,v:this._value}),this.opacity)}_setHue(t){this._hue=Math.min(359,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setSaturation(t){this._saturation=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setValue(t){this._value=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setOpacity(t){this._emit(this._lastValidColor,t)}_shiftRangeKey(t,e,s,i,o){if(!t.shiftKey)return;const a="ArrowRight"===t.key||"ArrowUp"===t.key?10:"ArrowLeft"===t.key||"ArrowDown"===t.key?-10:0;a&&(t.preventDefault(),t.stopPropagation(),o(Math.min(i,Math.max(s,e+a))))}_setSvFromPointer(t,e){const s=t.currentTarget.getBoundingClientRect();s.width&&s.height&&(this._saturation=Math.min(100,Math.max(0,(t.clientX-s.left)/s.width*100)),this._value=Math.min(100,Math.max(0,100*(1-(t.clientY-s.top)/s.height))),e?(this._cancelQueuedEmit(),this._emitHsv()):this._queueHsvEmit())}_svPointerDown(t){if(t.preventDefault(),t.stopPropagation(),null===this._activePointerId){this._activePointerId=t.pointerId;try{t.currentTarget.setPointerCapture(t.pointerId)}catch{}this._setSvFromPointer(t,!0)}}_svPointerMove(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!1))}_svPointerUp(t){if(t.pointerId===this._activePointerId){t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!0),this._activePointerId=null;try{t.currentTarget.releasePointerCapture(t.pointerId)}catch{}}}_svPointerCancel(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._activePointerId=null,this._cancelQueuedEmit(!0))}_svLostPointerCapture(t){t.pointerId===this._activePointerId&&(this._activePointerId=null,this._cancelQueuedEmit(!0))}_hexInput(t){const e=t.target.value;this._hexDraft=e;const s=ca(e),i=s?da(s):null;if(!s||!i)return void(this._hexInvalid=this._hexNeedsValidInput);this._hexNeedsValidInput=!1,this._hexInvalid=!1;const o=pa(i);o.s>1e-4&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._emit(s,this.opacity,!0)}_commitHex(){const t=ca(this._hexDraft);if(!t)return this._hexDraft=this._lastValidColor,this._hexInvalid=!0,void(this._hexNeedsValidInput=!0);this._hexDraft=t,this._hexNeedsValidInput?this._hexInvalid=!0:(this._hexInvalid=!1,t!==this._lastValidColor&&this._emit(t,this.opacity))}_confirm(t){t.preventDefault(),t.stopPropagation(),this._commitHex(),this._hexInvalid||this._hexNeedsValidInput?this.updateComplete.then(()=>{this._surface()?.querySelector('input[type="text"]')?.focus()}):this._closePicker(!0)}_hexKeyDown(t){"Enter"===t.key&&(t.preventDefault(),t.stopPropagation(),this._commitHex())}_emit(t,e,s=!1){const i=ca(t)||this._lastValidColor,o=Number.isFinite(e)?e:Number(this.opacity)||0,a=Math.min(1,Math.max(0,o));this.color=i,this.opacity=a,this._lastValidColor=i,s||(this._hexDraft=i),this._hexInvalid=this._hexNeedsValidInput,this.dispatchEvent(new CustomEvent("hp-color-opacity-change",{detail:{color:i,opacity:a},bubbles:!0,composed:!0}))}_pickerTemplate(t){const e=Math.round(100*Math.min(1,Math.max(0,Number(this.opacity)||0))),s=ua({h:this._hue,s:this._saturation,v:this._value}),i=ua({h:this._hue,s:100,v:100}),o=this._labels(),a=Math.round(this._hue),n=Math.round(this._saturation),r=Math.round(this._value);return p` + `},aa=(t,e)=>{const s=t._deviceDrag;if(!s)return;const i=t._devices.find(t=>t.id===s.id),o=[...e.querySelectorAll('[data-hp="device"]')].find(t=>t.dataset.id===s.id);if(!i||!o)return;const a=t._livePos(i),n=t._scenePoint([a.x,a.y]),r=t._viewOr(t._baseVb());o.style.left=(n[0]-r.x)/r.w*100+"%",o.style.top=(n[1]-r.y)/r.h*100+"%"},na=(t,e,s)=>{for(const i of e.querySelectorAll('.decorlayer [data-hp="decor"]'))i.closest("[data-hp-live-editor]")||i.dataset.id!==s||"0"!==i.style.opacity&&(i.style.opacity="0",t.transparent.push(i))},ra=(t,e,s)=>{const i=new Set(s);for(const s of e.querySelectorAll('.openinglayer [data-hp="opening"]'))!s.closest("[data-hp-live-editor]")&&i.has(s.dataset.id||"")&&(s.style.opacity="0",t.transparent.push(s))},la=(t,e,s)=>{for(const i of e.querySelectorAll(s))i.closest("[data-hp-live-editor]")||(i.style.opacity="0.35",t.dimmed.push(i))};const ha=(t,e,s)=>Math.min(s,Math.max(e,Number.isFinite(t)?t:e));function ca(t){return Number.isFinite(t)?(t%360+360)%360:0}function da(t){if("string"!=typeof t)return null;const e=t.trim().replace(/^#/,""),s=/^[0-9a-fA-F]{3}$/.test(e)?e.split("").map(t=>`${t}${t}`).join(""):e;return/^[0-9a-fA-F]{6}$/.test(s)?`#${s.toLowerCase()}`:null}function pa(t){const e=da(t);return e?{r:Number.parseInt(e.slice(1,3),16),g:Number.parseInt(e.slice(3,5),16),b:Number.parseInt(e.slice(5,7),16)}:null}function ua(t){const e=ha(t.r,0,255)/255,s=ha(t.g,0,255)/255,i=ha(t.b,0,255)/255,o=Math.max(e,s,i),a=o-Math.min(e,s,i);let n=0;return a>0&&(n=o===e?(s-i)/a%6*60:o===s?60*((i-e)/a+2):60*((e-s)/a+4)),{h:ca(n),s:0===o?0:a/o*100,v:100*o}}function _a(t){return function(t){const e=t=>Math.round(ha(t,0,255)).toString(16).padStart(2,"0");return`#${e(t.r)}${e(t.g)}${e(t.b)}`}(function(t){const e=ca(t.h),s=ha(t.s,0,100)/100,i=ha(t.v,0,100)/100,o=i*s,a=o*(1-Math.abs(e/60%2-1)),n=i-o;let r;return r=e<60?[o,a,0]:e<120?[a,o,0]:e<180?[0,o,a]:e<240?[0,a,o]:e<300?[a,0,o]:[o,0,a],{r:Math.round(255*(r[0]+n)),g:Math.round(255*(r[1]+n)),b:Math.round(255*(r[2]+n))}}(t))}const ma={title:"Color picker",hue:"Hue",saturation:"Saturation",value:"Brightness",hex:"Hex color",invalidHex:"Enter a 3- or 6-digit hex color",confirm:"OK"};class ga extends k{constructor(){super(...arguments),this.label="",this.opacityLabel="Opacity",this.color="#607d8b",this.opacity=1,this.disabled=!1,this.showOpacity=!0,this.pickerLabels=ma,this._open=!1,this._pickerRaf=0,this._emitRaf=0,this._forceFallback=!1,this._overlayDispose=null,this._hue=0,this._saturation=0,this._value=0,this._hexDraft="#607d8b",this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor="#607d8b",this._activePointerId=null,this._outsidePointerDown=t=>{if(!this._open)return;const e=t.composedPath();this._floating.containsPath(e)||this._closePicker(!1,"outside")},this._keyDown=t=>{this._open&&"Escape"===t.key&&(t.preventDefault(),t.stopImmediatePropagation(),this._closePicker(this._floating.ownsActiveElement(),"escape"))},this._floating=new go(this,"color-opacity",this._keyDown),this._queuePickerPosition=()=>{if(!this._open)return;this._pickerRaf&&cancelAnimationFrame(this._pickerRaf);const t=this._window();t&&(this._pickerRaf=t.requestAnimationFrame(()=>{this._pickerRaf=0,this._positionPicker()||this._closePicker()}))}}connectedCallback(){super.connectedCallback(),this._syncFromColor(this.color,!1),this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.addEventListener("resize",this._queuePickerPosition),t?.addEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.addEventListener("resize",this._queuePickerPosition),t?.visualViewport?.addEventListener("scroll",this._queuePickerPosition),this.addEventListener("keydown",this._keyDown,!0)}disconnectedCallback(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("scroll",this._queuePickerPosition,!0);const t=this.ownerDocument.defaultView;t?.removeEventListener("resize",this._queuePickerPosition),t?.removeEventListener("orientationchange",this._queuePickerPosition),t?.visualViewport?.removeEventListener("resize",this._queuePickerPosition),t?.visualViewport?.removeEventListener("scroll",this._queuePickerPosition),this.removeEventListener("keydown",this._keyDown,!0),this._pickerRaf&&cancelAnimationFrame(this._pickerRaf),this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._pickerRaf=0,this._emitRaf=0,this._closePicker(!1,"disconnect"),super.disconnectedCallback()}updated(t){if(t.has("color")){const t=da(this.color);t&&t!==this._lastValidColor&&this._syncFromColor(t,this._open)}this.disabled&&this._open?this._closePicker():this._open&&(this._supportsPopover()||this._renderFallback(),(t.has("color")||t.has("opacity")||t.has("showOpacity")||t.has("label")||t.has("opacityLabel")||t.has("pickerLabels"))&&this._queuePickerPosition())}_window(){return this._floating.window()}_supportsPopover(){return this._floating.usesPopover(this._forceFallback)}_dialog(){return this._floating.dialog()}async _toggle(){this.disabled||(this._open?this._closePicker():(this._forceFallback=!1,this._syncFromColor(this.color,!1),this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._activePointerId=null,this._open=!0,await this.updateComplete,this._open&&(this._supportsPopover()||this._renderFallback(),this._positionPicker()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:t=>this._closePicker("escape"===t&&this._floating.ownsActiveElement(),t)})||null:this._closePicker())))}_closePicker(t=!1,e="exclusive"){if(!this._open&&!this._floating.hasFallback)return;const s=this._overlayDispose;this._overlayDispose=null,s?.();const i=this.renderRoot.querySelector(".picker");if(i?.hidePopover)try{i.matches(":popover-open")&&i.hidePopover()}catch{}this._open=!1,this._cancelQueuedEmit(),this._activePointerId=null,this._floating.destroy(),t&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_surface(){return this._floating.surface(".picker",this._supportsPopover())}_renderFallback(){const t=ga.styles.cssText;this._floating.renderFallback(this._pickerTemplate(!1),t)}_positionPicker(){if(!this._open)return!1;const t=this._window(),e=this.renderRoot.querySelector(".trigger");let s=this._surface();if(!t||!e?.isConnected||!s?.isConnected)return!1;const i=fo(t);if(s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden",this._supportsPopover()&&s.showPopover)try{s.matches(":popover-open")||s.showPopover()}catch{if(this._forceFallback=!0,this._renderFallback(),s=this._surface(),!s?.isConnected)return!1;s.style.maxWidth=`${Math.max(0,i.width-16)}px`,s.style.maxHeight=`${Math.max(0,i.height-16)}px`,s.style.visibility="hidden"}const o=e.getBoundingClientRect(),a=s.getBoundingClientRect();if(!(o.width&&o.height&&a.width&&a.height))return!1;const n=bo(o,a,i);return s.style.left=`${n.left}px`,s.style.top=`${n.top}px`,s.dataset.side=n.side,s.style.visibility="",!0}_labels(){const t=this.pickerLabels||ma;return{title:t.title||ma.title,hue:t.hue||ma.hue,saturation:t.saturation||ma.saturation,value:t.value||ma.value,hex:t.hex||ma.hex,invalidHex:t.invalidHex||ma.invalidHex,confirm:t.confirm||ma.confirm}}_syncFromColor(t,e){const s=da(x(t,"#607d8b"))||"#607d8b",i=pa(s);if(!i)return;const o=ua(i);(!e||o.s>1e-4)&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._hexDraft=s,this._hexInvalid=!1,this._hexNeedsValidInput=!1,this._lastValidColor=s}_cancelQueuedEmit(t=!1){this._emitRaf&&cancelAnimationFrame(this._emitRaf),this._emitRaf=0,t&&this._syncFromColor(this._lastValidColor,!0)}_queueHsvEmit(){if(this._emitRaf)return;const t=this._window();t?this._emitRaf=t.requestAnimationFrame(()=>{this._emitRaf=0,this._emitHsv()}):this._emitHsv()}_emitHsv(){this._emit(_a({h:this._hue,s:this._saturation,v:this._value}),this.opacity)}_setHue(t){this._hue=Math.min(359,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setSaturation(t){this._saturation=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setValue(t){this._value=Math.min(100,Math.max(0,Number.isFinite(t)?t:0)),this._emitHsv()}_setOpacity(t){this._emit(this._lastValidColor,t)}_shiftRangeKey(t,e,s,i,o){if(!t.shiftKey)return;const a="ArrowRight"===t.key||"ArrowUp"===t.key?10:"ArrowLeft"===t.key||"ArrowDown"===t.key?-10:0;a&&(t.preventDefault(),t.stopPropagation(),o(Math.min(i,Math.max(s,e+a))))}_setSvFromPointer(t,e){const s=t.currentTarget.getBoundingClientRect();s.width&&s.height&&(this._saturation=Math.min(100,Math.max(0,(t.clientX-s.left)/s.width*100)),this._value=Math.min(100,Math.max(0,100*(1-(t.clientY-s.top)/s.height))),e?(this._cancelQueuedEmit(),this._emitHsv()):this._queueHsvEmit())}_svPointerDown(t){if(t.preventDefault(),t.stopPropagation(),null===this._activePointerId){this._activePointerId=t.pointerId;try{t.currentTarget.setPointerCapture(t.pointerId)}catch{}this._setSvFromPointer(t,!0)}}_svPointerMove(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!1))}_svPointerUp(t){if(t.pointerId===this._activePointerId){t.preventDefault(),t.stopPropagation(),this._setSvFromPointer(t,!0),this._activePointerId=null;try{t.currentTarget.releasePointerCapture(t.pointerId)}catch{}}}_svPointerCancel(t){t.pointerId===this._activePointerId&&(t.preventDefault(),t.stopPropagation(),this._activePointerId=null,this._cancelQueuedEmit(!0))}_svLostPointerCapture(t){t.pointerId===this._activePointerId&&(this._activePointerId=null,this._cancelQueuedEmit(!0))}_hexInput(t){const e=t.target.value;this._hexDraft=e;const s=da(e),i=s?pa(s):null;if(!s||!i)return void(this._hexInvalid=this._hexNeedsValidInput);this._hexNeedsValidInput=!1,this._hexInvalid=!1;const o=ua(i);o.s>1e-4&&(this._hue=o.h),this._saturation=o.s,this._value=o.v,this._emit(s,this.opacity,!0)}_commitHex(){const t=da(this._hexDraft);if(!t)return this._hexDraft=this._lastValidColor,this._hexInvalid=!0,void(this._hexNeedsValidInput=!0);this._hexDraft=t,this._hexNeedsValidInput?this._hexInvalid=!0:(this._hexInvalid=!1,t!==this._lastValidColor&&this._emit(t,this.opacity))}_confirm(t){t.preventDefault(),t.stopPropagation(),this._commitHex(),this._hexInvalid||this._hexNeedsValidInput?this.updateComplete.then(()=>{this._surface()?.querySelector('input[type="text"]')?.focus()}):this._closePicker(!0)}_hexKeyDown(t){"Enter"===t.key&&(t.preventDefault(),t.stopPropagation(),this._commitHex())}_emit(t,e,s=!1){const i=da(t)||this._lastValidColor,o=Number.isFinite(e)?e:Number(this.opacity)||0,a=Math.min(1,Math.max(0,o));this.color=i,this.opacity=a,this._lastValidColor=i,s||(this._hexDraft=i),this._hexInvalid=this._hexNeedsValidInput,this.dispatchEvent(new CustomEvent("hp-color-opacity-change",{detail:{color:i,opacity:a},bubbles:!0,composed:!0}))}_pickerTemplate(t){const e=Math.round(100*Math.min(1,Math.max(0,Number(this.opacity)||0))),s=_a({h:this._hue,s:this._saturation,v:this._value}),i=_a({h:this._hue,s:100,v:100}),o=this._labels(),a=Math.round(this._hue),n=Math.round(this._saturation),r=Math.round(this._value);return p` `}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),s=this._renderedContext,i=e?.dataset.contextId||"";if(i&&s&&i!==s&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=i,s&&i!==s&&this._focusOwned){const s=i?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");s?.focus?.(),this._focusOwned=!!i}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const o=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);o&&null!==o.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(_c(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const s=_c(t,t=>t.classList.contains("editor-secondary")),i=_c(t,t=>!!t.dataset.editorGroup),o=_c(t,t=>!!t.dataset.editorPalette),a=_c(t,t=>t.classList.contains("stage"));if(!(s||i||o||"stay-open-on-canvas"===e?.dismissPolicy&&a))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,s){if(t.id!==this._openGroupId)return;const i=t.items.find(t=>t.id===e);if(!i||i.disabled)return;const o="toggle"===i.role&&"stay-open"===i.closePolicy,a=0===s.detail;o||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),i.invoke(),!o&&a&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const s=e.indexOf(this.host.root().activeElement),i="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?s<=0?e.length-1:s-1:(s+1)%e.length;e[i]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const gc=t=>t.stopPropagation(),fc=new WeakSet,bc=t=>{t._regSignature="",t._maybeRebuildDevices(),t.requestUpdate()};async function vc(t,e,s,i,o,a=""){const n=t.host,r=n._serverCfg;if(!r)return!1;let l=JSON.parse(JSON.stringify(r));l.markers=l.markers||[];let h=l.markers.find(t=>t.id===e);if(!h){const t=n._devices.find(t=>t.id===e);if(!t||"device"!==t.bindingKind&&"entity"!==t.bindingKind||!t.bindingRef)return!1;h={id:t.id,binding:`${t.bindingKind}:${t.bindingRef}`,space:t.space||null,area:t.area||null,hidden:!!t.hidden},l.markers.push(h)}h.vacuum=function(t,e){const s=e.matrix.map(t=>Number(t.toFixed(6))),i=t?.map_routes;if(Array.isArray(i)&&i.length){const o=i.find(t=>t.id===e.routeId)||i.find(t=>t.source===e.source&&t.map_id===e.mapId);if(o)return{...t,map_routes:Eo(i,o.id,s)}}return{...t,source:e.source,calibration:{...t?.calibration||{},[e.mapId]:s}}}(h.vacuum||{},{source:s,mapId:i,routeId:a,matrix:o}),l=t._prepareConfigCandidate(l);const c=n._adoption.beginOptimistic(r,l);n._adoption.stageLocalConfig(l),bc(n),n._saveConfigDebounced.pending()&&n._saveConfigDebounced.cancel();try{return await t._saveConfigNow(c),!0}catch(t){return n._rollbackOptimistic(c),bc(n),n._showToast(n._t("toast.cfg_save_failed",{err:n._errText(t)})),!1}}function yc(t){return 1===t}function $c(t){return`${t}-${globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`}function wc(t){const e=function(t){return JSON.stringify({message:t.message.trim(),contact:t.contact.trim(),previewToken:t.attach&&t.preview?t.preview.token:""})}(t);return{idempotencyKey:t.submissionFingerprint&&t.submissionFingerprint!==e?$c("report"):t.idempotencyKey,fingerprint:e}}function kc(t){return[...t].length}function xc(t,e=Date.now()){const s=t.message.trim();return s?kc(s)>1e4?"message_too_long":kc(t.contact.trim())>320?"contact_too_long":t.attach&&!t.preview?"preview_missing":t.attach&&t.preview.expiresAt<=e?"preview_expired":null:"message_required"}function Sc(t,e=Date.now()){return"building"!==t.status&&"sending"!==t.status&&"success"!==t.status&&null===xc(t,e)}function Mc(t){const e=function(t){const e=/Firefox\/(\d+)/i.exec(t);if(e)return{family:"firefox",major:Number(e[1])||0};const s=/(?:Chrome|Chromium|Edg)\/(\d+)/i.exec(t);if(s)return{family:"chromium",major:Number(s[1])||0};const i=/Version\/(\d+).+Safari\//i.exec(t);return i?{family:"webkit",major:Number(i[1])||0}:{family:"unknown",major:0}}(t.userAgent??globalThis.navigator?.userAgent??""),s=t.now??Date.now(),i=Number(t.registryLastSuccess||0),o=i<=0?"unknown":s-i<=6e5?"fresh":"stale",a=["en","ru","de","fr"].includes(t.language)?t.language:"en",n=globalThis.matchMedia?.bind(globalThis);return{browser_family:e.family,browser_major:Math.max(0,Math.min(999,e.major)),language:a,coarse_pointer:t.coarsePointer??!!n?.("(pointer: coarse)").matches,hover_capable:t.hoverCapable??!!n?.("(hover: hover)").matches,registry_access:"full"===t.registryAccess?"full":"limited"===t.registryAccess?"partial":"unavailable",registry_age_bucket:o}}function Cc(t){const e=t&&"object"==typeof t&&"code"in t?String(t.code||""):"";return new Set(["support_invalid_message","support_preview_expired","support_package_too_large","support_rate_limited","support_unavailable","support_rejected","unauthorized"]).has(e)?e:"support_unavailable"}const Pc=[{id:"air_conditioner",group:"appliance",art:{d:"M20.5 39h69a2.5 2.5 0 0 1 2.5 2.5V69a2.5 2.5 0 0 1-2.5 2.5h-69A2.5 2.5 0 0 1 18 69V41.5a2.5 2.5 0 0 1 2.5-2.5 M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v8.5H25z M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v3.5H25z",viewW:110,viewH:110}},{id:"armchair",group:"furniture",art:{d:"M42.5 29h25a10 10 0 0 1 10 10v26.5a10 10 0 0 1-10 10h-25a10 10 0 0 1-10-10V39a10 10 0 0 1 10-10 M77.5 48.5a6 6 0 0 1 2 11.657V71.5a4 4 0 0 1-4 4H34a4 4 0 0 1-4-4V60.157A6.001 6.001 0 0 1 32 48.5a6 6 0 0 1 5.419 3.424A4 4 0 0 1 38 54v7h33.5v-6.5q0-.107.005-.213A6 6 0 0 1 77.5 48.5 M42.75 57h24.5A4.75 4.75 0 0 1 72 61.75a4.75 4.75 0 0 1-4.75 4.75h-24.5A4.75 4.75 0 0 1 38 61.75 4.75 4.75 0 0 1 42.75 57M36.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 41.392 82H38a1.5 1.5 0 0 1-1.5-1.5zm36 0h-8l1.674 5.441A1.5 1.5 0 0 0 67.608 82H71a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"bathtub",group:"sanitary",art:{d:"M28 75h8l-1.674 5.441a1.5 1.5 0 0 1-1.434 1.059H29.5A1.5 1.5 0 0 1 28 80zm53 0h-8l1.674 5.441a1.5 1.5 0 0 0 1.434 1.059H79.5A1.5 1.5 0 0 0 81 80zM19.5 46.5H90a2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5H19.5A2.5 2.5 0 0 1 17 49a2.5 2.5 0 0 1 2.5-2.5 M19.5 51.5H90L86.633 68a10 10 0 0 1-9.798 8h-44.17a10 10 0 0 1-9.798-8zM30 36v-2a5 5 0 1 0-10 0v12.5",viewW:110,viewH:110}},{id:"bed",group:"furniture",art:{d:"M16 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 20.892 82H17.5a1.5 1.5 0 0 1-1.5-1.5zm78.5 0h-8l1.674 5.441A1.5 1.5 0 0 0 89.608 82H93a1.5 1.5 0 0 0 1.5-1.5zM25 29h60.5a2.5 2.5 0 0 1 2.5 2.5V68a2.5 2.5 0 0 1-2.5 2.5H25a2.5 2.5 0 0 1-2.5-2.5V31.5A2.5 2.5 0 0 1 25 29 M16 59.5c0-5.523 4.477-10 10-10h58.5c5.523 0 10 4.477 10 10v6H16zm-1 6h80.5a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H15a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1m15.5-20a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4h-21zm28.5 0a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4H59z",viewW:110,viewH:110}},{id:"bidet",group:"sanitary",art:{d:"M36 57.5c0 5.523 4.477 10 10 10h18.5c5.523 0 10-4.477 10-10V53H36zm8.5 22a1 1 0 0 0 1 1H65a1 1 0 0 0 1-1v-12H44.5zm-8.5-32a1 1 0 0 1 1-1h36.5a1 1 0 0 1 1 1V53H36zM50.5 41a1 1 0 0 1 1-1H59a1 1 0 0 1 1 1v5.5h-9.5zM53 30a1 1 0 0 1 1-1h2.5a1 1 0 0 1 1 1v10H53zm-4 6a1 1 0 0 1-1-1v-2.5a1 1 0 0 1 1-1h4V36z",viewW:110,viewH:110}},{id:"boiler",group:"appliance",art:{d:"M46.5 81.5h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zm12.5 0h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zM44 23h22.5a8 8 0 0 1 8 8v42.5a8 8 0 0 1-8 8H44a8 8 0 0 1-8-8V31a8 8 0 0 1 8-8 M36 31a8 8 0 0 1 8-8h22.5a8 8 0 0 1 8 8v42H36z M48.5 42.5a7 7 0 1 0 14 0 7 7 0 1 0-14 0m6.5 0 3.5-3.5",viewW:110,viewH:110}},{id:"chair",group:"furniture",art:{d:"M40.5 39.5C40.5 32.596 46.096 27 53 27h4c6.904 0 12.5 5.596 12.5 12.5v13a5 5 0 0 1-5 5h-19a5 5 0 0 1-5-5z M41.25 54h27.5A3.25 3.25 0 0 1 72 57.25a3.25 3.25 0 0 1-3.25 3.25h-27.5A3.25 3.25 0 0 1 38 57.25 3.25 3.25 0 0 1 41.25 54m28.25 6.5H64l1.88 21.63a1.5 1.5 0 0 0 1.495 1.37H68a1.5 1.5 0 0 0 1.5-1.5zm-29 0H46l-1.88 21.63a1.5 1.5 0 0 1-1.495 1.37H42a1.5 1.5 0 0 1-1.5-1.5z",viewW:110,viewH:110}},{id:"coffee_table",group:"furniture",art:{d:"M25 51h5.238l-1.534 15.646A1.5 1.5 0 0 1 27.211 68H26.5a1.5 1.5 0 0 1-1.5-1.5zm60.238 0H80l1.534 15.646A1.5 1.5 0 0 0 83.027 68h.711a1.5 1.5 0 0 0 1.5-1.5z M24.34 43.485A2.5 2.5 0 0 1 26.625 42h56.75a2.5 2.5 0 0 1 2.285 1.485l2.715 6.109A1 1 0 0 1 87.461 51H22.54a1 1 0 0 1-.914-1.406z M87.5 51h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"computer",group:"appliance",art:{d:"M24.5 38h40a2.5 2.5 0 0 1 2.5 2.5v22a2.5 2.5 0 0 1-2.5 2.5h-40a2.5 2.5 0 0 1-2.5-2.5v-22a2.5 2.5 0 0 1 2.5-2.5m50 0h11a2.5 2.5 0 0 1 2.5 2.5v29a2.5 2.5 0 0 1-2.5 2.5h-11a2.5 2.5 0 0 1-2.5-2.5v-29a2.5 2.5 0 0 1 2.5-2.5M43 65h5v7h-5zm-6 7h16m23-12h8m-8-17h8 M35 56V46h5m-5 7h5 M39.5 53a3.5 3.5 0 1 0 0-7m15.036 8.536a5 5 0 1 1 0-7.071",viewW:110,viewH:110}},{id:"cooktop",group:"appliance",art:{d:"M27.5 29h55a2.5 2.5 0 0 1 2.5 2.5v47a2.5 2.5 0 0 1-2.5 2.5h-55a2.5 2.5 0 0 1-2.5-2.5v-47a2.5 2.5 0 0 1 2.5-2.5 M33.5 66.5a8 8 0 1 0 16 0 8 8 0 1 0-16 0m26.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0m3 23a5 5 0 1 0 10 0 5 5 0 1 0-10 0m-29.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0",viewW:110,viewH:110}},{id:"dining_table",group:"furniture",art:{d:"M83.5 43H78l6.742 30.82A1.5 1.5 0 0 0 86.207 75h.54a1.5 1.5 0 0 0 1.482-1.732zm-56 0H33l-6.742 30.82A1.5 1.5 0 0 1 24.793 75h-.54a1.5 1.5 0 0 1-1.482-1.732zm-2.62-7.406A2.5 2.5 0 0 1 27.21 34h56.58a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044A1 1 0 0 1 87.538 43H23.462a1 1 0 0 1-.932-1.362z M88.5 43h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"dishwasher",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5M43 42h24m-1.5-11a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"dryer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5 M55.994 55.5s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m5.979-11s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m-8.519-11s-.886 1.81-.986 3.143c-.132 1.761 1.066 2.554.986 4.321-.067 1.479-.986 3.536-.986 3.536",viewW:110,viewH:110}},{id:"exercise",group:"other",art:{d:"m60.752 62.03-5.379-2.312 11.066-25.75a1.5 1.5 0 0 1 1.97-.786l2.624 1.127a1.5 1.5 0 0 1 .786 1.97zm-18.648-4.512-4.353 1.189-4.474-16.382a1.5 1.5 0 0 1 1.052-1.842l1.459-.398a1.5 1.5 0 0 1 1.842 1.052z M41.297 38.173a2.215 2.215 0 0 1 0 4.43H29.781a2.215 2.215 0 0 1 0-4.43zm33.219 38.091a2.657 2.657 0 1 1 0 5.315H28.453a2.657 2.657 0 1 1 0-5.315zm8.641-51.366a1.795 1.795 0 0 1 .68 2.41l-3.03 5.59a5 5 0 0 1-4.396 2.618H65.657a1.772 1.772 0 1 1 0-3.544h9.61a3 3 0 0 0 2.598-1.5l2.84-4.917a1.795 1.795 0 0 1 2.452-.657M29.339 65.787c0-6.699 6.457-11.503 12.873-9.579l24.291 7.288a10 10 0 0 1 7.127 9.578v3.19H29.339zm0 15.852h7.086l-1.394 3.486a1.5 1.5 0 0 1-1.393.943h-2.8a1.5 1.5 0 0 1-1.5-1.5zm44.291 0h-7.087l1.395 3.486a1.5 1.5 0 0 0 1.392.943h2.8a1.5 1.5 0 0 0 1.5-1.5z M35.54 66.077a4.872 4.872 0 1 0 9.743 0 4.872 4.872 0 1 0-9.744 0",viewW:110,viewH:110}},{id:"fireplace",group:"other",art:{d:"M26.672 34.425h55.99v39.47h-55.99Z M23 74.894a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v5.802a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zM23 29a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v4.425a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zm15.145 21.44a5 5 0 0 1 5-5h23.043a5 5 0 0 1 5 5v23.454H38.145z M44.57 65.633a2.754 2.754 0 0 1 2.754-2.753H62.01v5.507H47.324a2.754 2.754 0 0 1-2.754-2.754m20.194 5.507a2.754 2.754 0 0 0-2.754-2.753H47.324v5.507H62.01a2.754 2.754 0 0 0 2.754-2.754 M44.57 71.14a2.754 2.754 0 1 0 5.508 0 2.754 2.754 0 1 0-5.508 0m14.688-5.507a2.754 2.754 0 1 0 5.507 0 2.754 2.754 0 1 0-5.507 0",viewW:110,viewH:110}},{id:"fridge",group:"appliance",art:{d:"M35.5 18H75a2.5 2.5 0 0 1 2.5 2.5v64A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5v-64a2.5 2.5 0 0 1 2.5-2.5 M33 46.5h44.5v38A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5zm2.5 44a1 1 0 0 0 1 1h37a1 1 0 0 0 1-1V87h-39zm3-49.5v-9.5m0 30.5v-9.5",viewW:110,viewH:110}},{id:"hood",group:"appliance",art:{d:"M44.308 57h21.384L83 69H27zM44 37.5a2.5 2.5 0 0 1 2.5-2.5h17a2.5 2.5 0 0 1 2.5 2.5V57H44zM80.5 74h-51a2.5 2.5 0 0 1-2.5-2.5V70a1 1 0 0 1 1-1h54a1 1 0 0 1 1 1v1.5a2.5 2.5 0 0 1-2.5 2.5",viewW:110,viewH:110}},{id:"kitchen_cabinet",group:"furniture",art:{d:"M38 88a1 1 0 0 0 1 1h32a1 1 0 0 0 1-1v-3H38zm17-68h16.5a2.5 2.5 0 0 1 2.5 2.5v17a2.5 2.5 0 0 1-2.5 2.5H55zm-19 2.5a2.5 2.5 0 0 1 2.5-2.5H55v22H38.5a2.5 2.5 0 0 1-2.5-2.5zM59 33v5m-8-5v5m4 47h16.5a2.5 2.5 0 0 0 2.5-2.5v-17a2.5 2.5 0 0 0-2.5-2.5H55zm-19-2.5a2.5 2.5 0 0 0 2.5 2.5H55V63H38.5a2.5 2.5 0 0 0-2.5 2.5zM67 67h-5m-14 0h-5",viewW:110,viewH:110}},{id:"kitchen_sink",group:"sanitary",art:{d:"M21.5 84h68a2.5 2.5 0 0 0 2.5-2.5v-35a2.5 2.5 0 0 0-2.5-2.5h-68a2.5 2.5 0 0 0-2.5 2.5v35a2.5 2.5 0 0 0 2.5 2.5 M26 78h26.5a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H26a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m23-24v5m9.5 19H85a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H58.5a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m-6-39.5a1 1 0 0 0-1-1H44a1 1 0 0 0-1 1V44h9.5zM58 33v-2a5 5 0 1 0-10 0v6.5M62 54v5",viewW:110,viewH:110}},{id:"nightstand",group:"furniture",art:{d:"M76.5 73.5h-8l1.674 5.441A1.5 1.5 0 0 0 71.608 80H75a1.5 1.5 0 0 0 1.5-1.5zm-42.5 0h8l-1.674 5.441A1.5 1.5 0 0 1 38.892 80H35.5a1.5 1.5 0 0 1-1.5-1.5z M34.5 30.5h41A2.5 2.5 0 0 1 78 33v40.5a2.5 2.5 0 0 1-2.5 2.5h-41a2.5 2.5 0 0 1-2.5-2.5V33a2.5 2.5 0 0 1 2.5-2.5 M32 39.5h46v18H32Zm18.5 9H60M50.5 66H60",viewW:110,viewH:110}},{id:"oven",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5 M40.5 47h29a2.5 2.5 0 0 1 2.5 2.5v20a2.5 2.5 0 0 1-2.5 2.5h-29a2.5 2.5 0 0 1-2.5-2.5v-20a2.5 2.5 0 0 1 2.5-2.5m25-16a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5M43 42h24",viewW:110,viewH:110}},{id:"plant",group:"other",art:{d:"M45.952 75.849a2.5 2.5 0 0 0 2.485 2.231H63.43a2.5 2.5 0 0 0 2.485-2.231l1.571-14.532H44.381zM60.236 44.78C58.423 36.174 66.805 29.605 77 31.87c0 8.155-8.609 16.763-16.763 12.912m-9.761 5.147c1.517-8.665-7.085-14.943-17.195-12.33.28 8.15 9.178 16.458 17.195 12.33 M55.706 55.88v-2.944m0 0c1.133-5.89 7.09-10.956 12.912-15.404M55.706 52.936c-4.938-4.146-7.982-6.16-14.044-9.061m1.453 12.005h25.636a1 1 0 0 1 1 1v3.437a1 1 0 0 1-1 1H43.115a1 1 0 0 1-1-1v-3.436a1 1 0 0 1 1-1",viewW:110,viewH:110}},{id:"rug",group:"other",art:{d:"M90.27 33.874h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.154h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20M28.12 32h54.025a2.5 2.5 0 0 1 2.5 2.5v40.439a2.5 2.5 0 0 1-2.5 2.5H28.12a2.5 2.5 0 0 1-2.5-2.5V34.5a2.5 2.5 0 0 1 2.5-2.5 M25.62 34.5a2.5 2.5 0 0 1 2.5-2.5h1.717v45.439H28.12a2.5 2.5 0 0 1-2.5-2.5zm59.026 0a2.5 2.5 0 0 0-2.5-2.5H80.43v45.439h1.716a2.5 2.5 0 0 0 2.5-2.5zM37.8 54.485l17.801-8.432 17.801 8.432-17.8 8.432z",viewW:110,viewH:110}},{id:"shelving",group:"furniture",art:{d:"M28 58.5h53V39H28Z M64 58.5h5V47a1 1 0 0 0-1-1h-3a1 1 0 0 0-1 1zM52.5 39h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-12 0h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-5 29.5V71a1 1 0 0 1 1 1H49a1 1 0 0 1 1-1v-2.5a1 1 0 0 1-1-1H36.5a1 1 0 0 1-1 1m33.5-10h7v-14a1 1 0 0 0-1-1h-5a1 1 0 0 0-1 1zM47.5 39h-7V25a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1zm-12 34v4a1 1 0 0 1 1 1h14a1 1 0 0 1 1-1v-4a1 1 0 0 1-1-1h-14a1 1 0 0 1-1 1M28 78h53v7H28Z M28 89.5V23a2.5 2.5 0 0 1 2.5-2.5h48A2.5 2.5 0 0 1 81 23v66.5",viewW:110,viewH:110}},{id:"shower",group:"sanitary",art:{d:"M31 84h49a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H31a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1m31.5-47.6v-4.686a11.7 11.7 0 0 0-3.441-8.283A11.77 11.77 0 0 0 50.75 20a11.77 11.77 0 0 0-8.309 3.431A11.7 11.7 0 0 0 39 31.714V84 M72 39.25a10.25 10.25 0 1 0-20.5 0zm-17.25 5v2.5m7.25-2.5v2.5m7.25-2.5v2.5m-14.5 3.75V53M62 50.5V53m7.25-2.5V53m-14.5 3.75v2.5m7.25-2.5v2.5m7.25-2.5v2.5M54.75 63v2.5M62 63v2.5m7.25-2.5v2.5",viewW:110,viewH:110}},{id:"sink",group:"sanitary",art:{d:"M30 57c0 5.523 4.477 10 10 10h29.5c5.523 0 10-4.477 10-10v-6.5A2.5 2.5 0 0 0 77 48H32.5a2.5 2.5 0 0 0-2.5 2.5zm14 22a1 1 0 0 0 1 1h19.5a1 1 0 0 0 1-1V67H44zm6-36.5a1 1 0 0 1 1-1h7.5a1 1 0 0 1 1 1V48H50zM45 37v-2a5 5 0 1 1 10 0v6.5",viewW:110,viewH:110}},{id:"sofa",group:"furniture",art:{d:"M59.5 29h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5m-34 0h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5 M18.5 44a5 5 0 0 1 5 5v12H86V49a5 5 0 0 1 5-5h.5a5 5 0 0 1 5 5v21.5a5 5 0 0 1-5 5H18a5 5 0 0 1-5-5V49a5 5 0 0 1 5-5z M25.25 57h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 25.25 57m34 0h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 59.25 57M18.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 23.392 82H20a1.5 1.5 0 0 1-1.5-1.5zm72 0h-8l1.674 5.441A1.5 1.5 0 0 0 85.608 82H89a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"stairs",group:"other",art:{d:"M73.47 46.365v-17.62m-10.571 25.55V36.674M52.326 61.783V45.484M42.193 69.273v-15.86M28.979 77.761a1 1 0 0 1 1-1h53.624v6.489a1 1 0 0 1-1 1H29.98a1 1 0 0 1-1-1z M26.777 57.497a1 1 0 0 1 1-1h2.846a1 1 0 0 1 1 1V83.25a1 1 0 0 1-1 1h-2.846a1 1 0 0 1-1-1z m73.113 28.633-41.492 32.93v-4.405l39.9-32.007a.7.7 0 0 1 .428-.151h3.724a1.762 1.762 0 1 1 0 3.524h-2.248a.5.5 0 0 0-.312.109M25.895 53.414a3.084 3.084 0 1 0 6.167 0 3.084 3.084 0 1 0-6.167 0m14.978 16.859a1 1 0 0 1 1-1h41.73v7.488h-42.73zm10.131-7.489a1 1 0 0 1 1-1h31.598v7.488H51.004z M61.576 55.294a1 1 0 0 1 1-1h21.026v7.49H61.576z M72.15 47.806a1 1 0 0 1 1-1h9.454a1 1 0 0 1 1 1v6.489H72.15z",viewW:110,viewH:110}},{id:"toilet",group:"sanitary",art:{d:"M32 26.5a2.5 2.5 0 0 1 2.5-2.5H45a2.5 2.5 0 0 1 2.5 2.5V57H32zM47.5 52h29a2.5 2.5 0 0 1 2.5 2.5V57H47.5zm17.037 20.102C73.95 70.288 79 62.01 79 57H32c.5 7.5 8.072 7 7 11l-2.342 16.862a1 1 0 0 0 .99 1.138H66.72a1 1 0 0 0 .97-1.243z",viewW:110,viewH:110}},{id:"tv",group:"appliance",art:{d:"M23.5 31H86a2.5 2.5 0 0 1 2.5 2.5v34A2.5 2.5 0 0 1 86 70H23.5a2.5 2.5 0 0 1-2.5-2.5v-34a2.5 2.5 0 0 1 2.5-2.5M50 70h9.5v8H50Zm-10 8h30M42.5 45.5h5m5 0h-5m0 0v9.75 m56.75 45.5 5 10 5-10",viewW:110,viewH:110}},{id:"wardrobe",group:"furniture",art:{d:"M28 23a2.5 2.5 0 0 1 2.5-2.5h24V85h-24a2.5 2.5 0 0 1-2.5-2.5zm2 65.5a1 1 0 0 0 1 1h47a1 1 0 0 0 1-1V85H30zM81 23a2.5 2.5 0 0 0-2.5-2.5h-24V85h24a2.5 2.5 0 0 0 2.5-2.5zM50.5 48v9.5m8-9.5v9.5",viewW:110,viewH:110}},{id:"washer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"work_table",group:"furniture",art:{d:"M88.5 47h-20v14h20zm-12 4h4m7.984-8h-66v4h66zm-66 4h4v26.5a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5z M24.866 35.597A2.5 2.5 0 0 1 27.197 34h56.577a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044a1 1 0 0 1-.93 1.362H23.46a1 1 0 0 1-.933-1.361zM88.5 61h-20v12.5A1.5 1.5 0 0 0 70 75h17a1.5 1.5 0 0 0 1.5-1.5zm-12 4h4",viewW:110,viewH:110}}];class Dc{constructor(t,e){this.host=t,this.hooks=e}place(t,e="mouse"){const s=this.host._decorImagePalette,i=this.host._curSpaceCfg;if(!s||!i)return;const o=this.hooks.decorSnap(t,e),a=jt(s.width,s.height),n=Gt(a.w,this.host._cellCm,this.host._gridPitch)/m,r=Gt(a.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,l="di"+Date.now().toString(36)+Math.random().toString(36).slice(2,5),h=this.hooks.geometrySnapshot();i.decor=[...this.host._decorList,{id:l,kind:"image",asset_id:s.asset_id,x:Z(o[0]/m-n/2),y:Z(o[1]/this.host._decorH-r/2),w:n,h:r,opacity:1}],this.host._decorSel=l,this.host._decorTool="select",this.host._decorImagePalette=null,this.hooks.clearFurniturePreview(),this.hooks.recordGeometry(this.host._t("history.decor_add"),h),this.hooks.saveConfig(),this.host.requestUpdate()}renderPlacementPreview(){const t=this.host._furnPreviewInput,e=this.host._decorImagePalette;if(!t||!e||"decor"!==this.host._mode||"image"!==this.host._decorTool||!this.host._pointerModality.hoverEnabled)return d;const s=this.hooks.decorSnap(t.raw,"mouse"),i=jt(e.width,e.height),o=Gt(i.w,this.host._cellCm,this.host._gridPitch)/m,a=Gt(i.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,n=this.host._display(e.url);return n?_``}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),s=this._renderedContext,i=e?.dataset.contextId||"";if(i&&s&&i!==s&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=i,s&&i!==s&&this._focusOwned){const s=i?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");s?.focus?.(),this._focusOwned=!!i}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const o=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);o&&null!==o.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(mc(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const s=mc(t,t=>t.classList.contains("editor-secondary")),i=mc(t,t=>!!t.dataset.editorGroup),o=mc(t,t=>!!t.dataset.editorPalette),a=mc(t,t=>t.classList.contains("stage"));if(!(s||i||o||"stay-open-on-canvas"===e?.dismissPolicy&&a))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,s){if(t.id!==this._openGroupId)return;const i=t.items.find(t=>t.id===e);if(!i||i.disabled)return;const o="toggle"===i.role&&"stay-open"===i.closePolicy,a=0===s.detail;o||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),i.invoke(),!o&&a&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const s=e.indexOf(this.host.root().activeElement),i="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?s<=0?e.length-1:s-1:(s+1)%e.length;e[i]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const fc=t=>t.stopPropagation(),bc=new WeakSet,vc=t=>{t._regSignature="",t._maybeRebuildDevices(),t.requestUpdate()};async function yc(t,e,s,i,o,a=""){const n=t.host,r=n._serverCfg;if(!r)return!1;let l=JSON.parse(JSON.stringify(r));l.markers=l.markers||[];let h=l.markers.find(t=>t.id===e);if(!h){const t=n._devices.find(t=>t.id===e);if(!t||"device"!==t.bindingKind&&"entity"!==t.bindingKind||!t.bindingRef)return!1;h={id:t.id,binding:`${t.bindingKind}:${t.bindingRef}`,space:t.space||null,area:t.area||null,hidden:!!t.hidden},l.markers.push(h)}h.vacuum=function(t,e){const s=e.matrix.map(t=>Number(t.toFixed(6))),i=t?.map_routes;if(Array.isArray(i)&&i.length){const o=i.find(t=>t.id===e.routeId)||i.find(t=>t.source===e.source&&t.map_id===e.mapId);if(o)return{...t,map_routes:Ho(i,o.id,s)}}return{...t,source:e.source,calibration:{...t?.calibration||{},[e.mapId]:s}}}(h.vacuum||{},{source:s,mapId:i,routeId:a,matrix:o}),l=t._prepareConfigCandidate(l);const c=n._adoption.beginOptimistic(r,l);n._adoption.stageLocalConfig(l),vc(n),n._saveConfigDebounced.pending()&&n._saveConfigDebounced.cancel();try{return await t._saveConfigNow(c),!0}catch(t){return n._rollbackOptimistic(c),vc(n),n._showToast(n._t("toast.cfg_save_failed",{err:n._errText(t)})),!1}}function $c(t){return 1===t}function wc(t){return`${t}-${globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`}function kc(t){const e=function(t){return JSON.stringify({message:t.message.trim(),contact:t.contact.trim(),previewToken:t.attach&&t.preview?t.preview.token:""})}(t);return{idempotencyKey:t.submissionFingerprint&&t.submissionFingerprint!==e?wc("report"):t.idempotencyKey,fingerprint:e}}function xc(t){return[...t].length}function Sc(t,e=Date.now()){const s=t.message.trim();return s?xc(s)>1e4?"message_too_long":xc(t.contact.trim())>320?"contact_too_long":t.attach&&!t.preview?"preview_missing":t.attach&&t.preview.expiresAt<=e?"preview_expired":null:"message_required"}function Mc(t,e=Date.now()){return"building"!==t.status&&"sending"!==t.status&&"success"!==t.status&&null===Sc(t,e)}function Cc(t){const e=function(t){const e=/Firefox\/(\d+)/i.exec(t);if(e)return{family:"firefox",major:Number(e[1])||0};const s=/(?:Chrome|Chromium|Edg)\/(\d+)/i.exec(t);if(s)return{family:"chromium",major:Number(s[1])||0};const i=/Version\/(\d+).+Safari\//i.exec(t);return i?{family:"webkit",major:Number(i[1])||0}:{family:"unknown",major:0}}(t.userAgent??globalThis.navigator?.userAgent??""),s=t.now??Date.now(),i=Number(t.registryLastSuccess||0),o=i<=0?"unknown":s-i<=6e5?"fresh":"stale",a=["en","ru","de","fr"].includes(t.language)?t.language:"en",n=globalThis.matchMedia?.bind(globalThis);return{browser_family:e.family,browser_major:Math.max(0,Math.min(999,e.major)),language:a,coarse_pointer:t.coarsePointer??!!n?.("(pointer: coarse)").matches,hover_capable:t.hoverCapable??!!n?.("(hover: hover)").matches,registry_access:"full"===t.registryAccess?"full":"limited"===t.registryAccess?"partial":"unavailable",registry_age_bucket:o}}function Pc(t){const e=t&&"object"==typeof t&&"code"in t?String(t.code||""):"";return new Set(["support_invalid_message","support_preview_expired","support_package_too_large","support_rate_limited","support_unavailable","support_rejected","unauthorized"]).has(e)?e:"support_unavailable"}const Dc=[{id:"air_conditioner",group:"appliance",art:{d:"M20.5 39h69a2.5 2.5 0 0 1 2.5 2.5V69a2.5 2.5 0 0 1-2.5 2.5h-69A2.5 2.5 0 0 1 18 69V41.5a2.5 2.5 0 0 1 2.5-2.5 M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v8.5H25z M25 63a2.5 2.5 0 0 1 2.5-2.5h55A2.5 2.5 0 0 1 85 63v3.5H25z",viewW:110,viewH:110}},{id:"armchair",group:"furniture",art:{d:"M42.5 29h25a10 10 0 0 1 10 10v26.5a10 10 0 0 1-10 10h-25a10 10 0 0 1-10-10V39a10 10 0 0 1 10-10 M77.5 48.5a6 6 0 0 1 2 11.657V71.5a4 4 0 0 1-4 4H34a4 4 0 0 1-4-4V60.157A6.001 6.001 0 0 1 32 48.5a6 6 0 0 1 5.419 3.424A4 4 0 0 1 38 54v7h33.5v-6.5q0-.107.005-.213A6 6 0 0 1 77.5 48.5 M42.75 57h24.5A4.75 4.75 0 0 1 72 61.75a4.75 4.75 0 0 1-4.75 4.75h-24.5A4.75 4.75 0 0 1 38 61.75 4.75 4.75 0 0 1 42.75 57M36.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 41.392 82H38a1.5 1.5 0 0 1-1.5-1.5zm36 0h-8l1.674 5.441A1.5 1.5 0 0 0 67.608 82H71a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"bathtub",group:"sanitary",art:{d:"M28 75h8l-1.674 5.441a1.5 1.5 0 0 1-1.434 1.059H29.5A1.5 1.5 0 0 1 28 80zm53 0h-8l1.674 5.441a1.5 1.5 0 0 0 1.434 1.059H79.5A1.5 1.5 0 0 0 81 80zM19.5 46.5H90a2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5H19.5A2.5 2.5 0 0 1 17 49a2.5 2.5 0 0 1 2.5-2.5 M19.5 51.5H90L86.633 68a10 10 0 0 1-9.798 8h-44.17a10 10 0 0 1-9.798-8zM30 36v-2a5 5 0 1 0-10 0v12.5",viewW:110,viewH:110}},{id:"bed",group:"furniture",art:{d:"M16 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 20.892 82H17.5a1.5 1.5 0 0 1-1.5-1.5zm78.5 0h-8l1.674 5.441A1.5 1.5 0 0 0 89.608 82H93a1.5 1.5 0 0 0 1.5-1.5zM25 29h60.5a2.5 2.5 0 0 1 2.5 2.5V68a2.5 2.5 0 0 1-2.5 2.5H25a2.5 2.5 0 0 1-2.5-2.5V31.5A2.5 2.5 0 0 1 25 29 M16 59.5c0-5.523 4.477-10 10-10h58.5c5.523 0 10 4.477 10 10v6H16zm-1 6h80.5a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H15a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1m15.5-20a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4h-21zm28.5 0a5 5 0 0 1 5-5h11a5 5 0 0 1 5 5v4H59z",viewW:110,viewH:110}},{id:"bidet",group:"sanitary",art:{d:"M36 57.5c0 5.523 4.477 10 10 10h18.5c5.523 0 10-4.477 10-10V53H36zm8.5 22a1 1 0 0 0 1 1H65a1 1 0 0 0 1-1v-12H44.5zm-8.5-32a1 1 0 0 1 1-1h36.5a1 1 0 0 1 1 1V53H36zM50.5 41a1 1 0 0 1 1-1H59a1 1 0 0 1 1 1v5.5h-9.5zM53 30a1 1 0 0 1 1-1h2.5a1 1 0 0 1 1 1v10H53zm-4 6a1 1 0 0 1-1-1v-2.5a1 1 0 0 1 1-1h4V36z",viewW:110,viewH:110}},{id:"boiler",group:"appliance",art:{d:"M46.5 81.5h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zm12.5 0h5V86a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1zM44 23h22.5a8 8 0 0 1 8 8v42.5a8 8 0 0 1-8 8H44a8 8 0 0 1-8-8V31a8 8 0 0 1 8-8 M36 31a8 8 0 0 1 8-8h22.5a8 8 0 0 1 8 8v42H36z M48.5 42.5a7 7 0 1 0 14 0 7 7 0 1 0-14 0m6.5 0 3.5-3.5",viewW:110,viewH:110}},{id:"chair",group:"furniture",art:{d:"M40.5 39.5C40.5 32.596 46.096 27 53 27h4c6.904 0 12.5 5.596 12.5 12.5v13a5 5 0 0 1-5 5h-19a5 5 0 0 1-5-5z M41.25 54h27.5A3.25 3.25 0 0 1 72 57.25a3.25 3.25 0 0 1-3.25 3.25h-27.5A3.25 3.25 0 0 1 38 57.25 3.25 3.25 0 0 1 41.25 54m28.25 6.5H64l1.88 21.63a1.5 1.5 0 0 0 1.495 1.37H68a1.5 1.5 0 0 0 1.5-1.5zm-29 0H46l-1.88 21.63a1.5 1.5 0 0 1-1.495 1.37H42a1.5 1.5 0 0 1-1.5-1.5z",viewW:110,viewH:110}},{id:"coffee_table",group:"furniture",art:{d:"M25 51h5.238l-1.534 15.646A1.5 1.5 0 0 1 27.211 68H26.5a1.5 1.5 0 0 1-1.5-1.5zm60.238 0H80l1.534 15.646A1.5 1.5 0 0 0 83.027 68h.711a1.5 1.5 0 0 0 1.5-1.5z M24.34 43.485A2.5 2.5 0 0 1 26.625 42h56.75a2.5 2.5 0 0 1 2.285 1.485l2.715 6.109A1 1 0 0 1 87.461 51H22.54a1 1 0 0 1-.914-1.406z M87.5 51h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"computer",group:"appliance",art:{d:"M24.5 38h40a2.5 2.5 0 0 1 2.5 2.5v22a2.5 2.5 0 0 1-2.5 2.5h-40a2.5 2.5 0 0 1-2.5-2.5v-22a2.5 2.5 0 0 1 2.5-2.5m50 0h11a2.5 2.5 0 0 1 2.5 2.5v29a2.5 2.5 0 0 1-2.5 2.5h-11a2.5 2.5 0 0 1-2.5-2.5v-29a2.5 2.5 0 0 1 2.5-2.5M43 65h5v7h-5zm-6 7h16m23-12h8m-8-17h8 M35 56V46h5m-5 7h5 M39.5 53a3.5 3.5 0 1 0 0-7m15.036 8.536a5 5 0 1 1 0-7.071",viewW:110,viewH:110}},{id:"cooktop",group:"appliance",art:{d:"M27.5 29h55a2.5 2.5 0 0 1 2.5 2.5v47a2.5 2.5 0 0 1-2.5 2.5h-55a2.5 2.5 0 0 1-2.5-2.5v-47a2.5 2.5 0 0 1 2.5-2.5 M33.5 66.5a8 8 0 1 0 16 0 8 8 0 1 0-16 0m26.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0m3 23a5 5 0 1 0 10 0 5 5 0 1 0-10 0m-29.5-23a8 8 0 1 0 16 0 8 8 0 1 0-16 0",viewW:110,viewH:110}},{id:"dining_table",group:"furniture",art:{d:"M83.5 43H78l6.742 30.82A1.5 1.5 0 0 0 86.207 75h.54a1.5 1.5 0 0 0 1.482-1.732zm-56 0H33l-6.742 30.82A1.5 1.5 0 0 1 24.793 75h-.54a1.5 1.5 0 0 1-1.482-1.732zm-2.62-7.406A2.5 2.5 0 0 1 27.21 34h56.58a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044A1 1 0 0 1 87.538 43H23.462a1 1 0 0 1-.932-1.362z M88.5 43h-66v3a1 1 0 0 0 1 1h64a1 1 0 0 0 1-1z",viewW:110,viewH:110}},{id:"dishwasher",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5M43 42h24m-1.5-11a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"dryer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5 M55.994 55.5s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m5.979-11s-1.329 1.81-1.479 3.143c-.198 1.761 1.599 2.554 1.48 4.321-.1 1.479-1.48 3.536-1.48 3.536m-8.519-11s-.886 1.81-.986 3.143c-.132 1.761 1.066 2.554.986 4.321-.067 1.479-.986 3.536-.986 3.536",viewW:110,viewH:110}},{id:"exercise",group:"other",art:{d:"m60.752 62.03-5.379-2.312 11.066-25.75a1.5 1.5 0 0 1 1.97-.786l2.624 1.127a1.5 1.5 0 0 1 .786 1.97zm-18.648-4.512-4.353 1.189-4.474-16.382a1.5 1.5 0 0 1 1.052-1.842l1.459-.398a1.5 1.5 0 0 1 1.842 1.052z M41.297 38.173a2.215 2.215 0 0 1 0 4.43H29.781a2.215 2.215 0 0 1 0-4.43zm33.219 38.091a2.657 2.657 0 1 1 0 5.315H28.453a2.657 2.657 0 1 1 0-5.315zm8.641-51.366a1.795 1.795 0 0 1 .68 2.41l-3.03 5.59a5 5 0 0 1-4.396 2.618H65.657a1.772 1.772 0 1 1 0-3.544h9.61a3 3 0 0 0 2.598-1.5l2.84-4.917a1.795 1.795 0 0 1 2.452-.657M29.339 65.787c0-6.699 6.457-11.503 12.873-9.579l24.291 7.288a10 10 0 0 1 7.127 9.578v3.19H29.339zm0 15.852h7.086l-1.394 3.486a1.5 1.5 0 0 1-1.393.943h-2.8a1.5 1.5 0 0 1-1.5-1.5zm44.291 0h-7.087l1.395 3.486a1.5 1.5 0 0 0 1.392.943h2.8a1.5 1.5 0 0 0 1.5-1.5z M35.54 66.077a4.872 4.872 0 1 0 9.743 0 4.872 4.872 0 1 0-9.744 0",viewW:110,viewH:110}},{id:"fireplace",group:"other",art:{d:"M26.672 34.425h55.99v39.47h-55.99Z M23 74.894a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v5.802a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zM23 29a1 1 0 0 1 1-1h61.334a1 1 0 0 1 1 1v4.425a1 1 0 0 1-1 1H24a1 1 0 0 1-1-1zm15.145 21.44a5 5 0 0 1 5-5h23.043a5 5 0 0 1 5 5v23.454H38.145z M44.57 65.633a2.754 2.754 0 0 1 2.754-2.753H62.01v5.507H47.324a2.754 2.754 0 0 1-2.754-2.754m20.194 5.507a2.754 2.754 0 0 0-2.754-2.753H47.324v5.507H62.01a2.754 2.754 0 0 0 2.754-2.754 M44.57 71.14a2.754 2.754 0 1 0 5.508 0 2.754 2.754 0 1 0-5.508 0m14.688-5.507a2.754 2.754 0 1 0 5.507 0 2.754 2.754 0 1 0-5.507 0",viewW:110,viewH:110}},{id:"fridge",group:"appliance",art:{d:"M35.5 18H75a2.5 2.5 0 0 1 2.5 2.5v64A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5v-64a2.5 2.5 0 0 1 2.5-2.5 M33 46.5h44.5v38A2.5 2.5 0 0 1 75 87H35.5a2.5 2.5 0 0 1-2.5-2.5zm2.5 44a1 1 0 0 0 1 1h37a1 1 0 0 0 1-1V87h-39zm3-49.5v-9.5m0 30.5v-9.5",viewW:110,viewH:110}},{id:"hood",group:"appliance",art:{d:"M44.308 57h21.384L83 69H27zM44 37.5a2.5 2.5 0 0 1 2.5-2.5h17a2.5 2.5 0 0 1 2.5 2.5V57H44zM80.5 74h-51a2.5 2.5 0 0 1-2.5-2.5V70a1 1 0 0 1 1-1h54a1 1 0 0 1 1 1v1.5a2.5 2.5 0 0 1-2.5 2.5",viewW:110,viewH:110}},{id:"kitchen_cabinet",group:"furniture",art:{d:"M38 88a1 1 0 0 0 1 1h32a1 1 0 0 0 1-1v-3H38zm17-68h16.5a2.5 2.5 0 0 1 2.5 2.5v17a2.5 2.5 0 0 1-2.5 2.5H55zm-19 2.5a2.5 2.5 0 0 1 2.5-2.5H55v22H38.5a2.5 2.5 0 0 1-2.5-2.5zM59 33v5m-8-5v5m4 47h16.5a2.5 2.5 0 0 0 2.5-2.5v-17a2.5 2.5 0 0 0-2.5-2.5H55zm-19-2.5a2.5 2.5 0 0 0 2.5 2.5H55V63H38.5a2.5 2.5 0 0 0-2.5 2.5zM67 67h-5m-14 0h-5",viewW:110,viewH:110}},{id:"kitchen_sink",group:"sanitary",art:{d:"M21.5 84h68a2.5 2.5 0 0 0 2.5-2.5v-35a2.5 2.5 0 0 0-2.5-2.5h-68a2.5 2.5 0 0 0-2.5 2.5v35a2.5 2.5 0 0 0 2.5 2.5 M26 78h26.5a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H26a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m23-24v5m9.5 19H85a1 1 0 0 0 1-1V51a1 1 0 0 0-1-1H58.5a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1m-6-39.5a1 1 0 0 0-1-1H44a1 1 0 0 0-1 1V44h9.5zM58 33v-2a5 5 0 1 0-10 0v6.5M62 54v5",viewW:110,viewH:110}},{id:"nightstand",group:"furniture",art:{d:"M76.5 73.5h-8l1.674 5.441A1.5 1.5 0 0 0 71.608 80H75a1.5 1.5 0 0 0 1.5-1.5zm-42.5 0h8l-1.674 5.441A1.5 1.5 0 0 1 38.892 80H35.5a1.5 1.5 0 0 1-1.5-1.5z M34.5 30.5h41A2.5 2.5 0 0 1 78 33v40.5a2.5 2.5 0 0 1-2.5 2.5h-41a2.5 2.5 0 0 1-2.5-2.5V33a2.5 2.5 0 0 1 2.5-2.5 M32 39.5h46v18H32Zm18.5 9H60M50.5 66H60",viewW:110,viewH:110}},{id:"oven",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v36a2.5 2.5 0 0 1-2.5 2.5h-47A2.5 2.5 0 0 1 29 76V40a2.5 2.5 0 0 1 2.5-2.5 M40.5 47h29a2.5 2.5 0 0 1 2.5 2.5v20a2.5 2.5 0 0 1-2.5 2.5h-29a2.5 2.5 0 0 1-2.5-2.5v-20a2.5 2.5 0 0 1 2.5-2.5m25-16a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5M43 42h24",viewW:110,viewH:110}},{id:"plant",group:"other",art:{d:"M45.952 75.849a2.5 2.5 0 0 0 2.485 2.231H63.43a2.5 2.5 0 0 0 2.485-2.231l1.571-14.532H44.381zM60.236 44.78C58.423 36.174 66.805 29.605 77 31.87c0 8.155-8.609 16.763-16.763 12.912m-9.761 5.147c1.517-8.665-7.085-14.943-17.195-12.33.28 8.15 9.178 16.458 17.195 12.33 M55.706 55.88v-2.944m0 0c1.133-5.89 7.09-10.956 12.912-15.404M55.706 52.936c-4.938-4.146-7.982-6.16-14.044-9.061m1.453 12.005h25.636a1 1 0 0 1 1 1v3.437a1 1 0 0 1-1 1H43.115a1 1 0 0 1-1-1v-3.436a1 1 0 0 1 1-1",viewW:110,viewH:110}},{id:"rug",group:"other",art:{d:"M90.27 33.874h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.154h-5.622m-59.028 0H20m70.27 5.152h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20m70.27 5.153h-5.622m-59.028 0H20M28.12 32h54.025a2.5 2.5 0 0 1 2.5 2.5v40.439a2.5 2.5 0 0 1-2.5 2.5H28.12a2.5 2.5 0 0 1-2.5-2.5V34.5a2.5 2.5 0 0 1 2.5-2.5 M25.62 34.5a2.5 2.5 0 0 1 2.5-2.5h1.717v45.439H28.12a2.5 2.5 0 0 1-2.5-2.5zm59.026 0a2.5 2.5 0 0 0-2.5-2.5H80.43v45.439h1.716a2.5 2.5 0 0 0 2.5-2.5zM37.8 54.485l17.801-8.432 17.801 8.432-17.8 8.432z",viewW:110,viewH:110}},{id:"shelving",group:"furniture",art:{d:"M28 58.5h53V39H28Z M64 58.5h5V47a1 1 0 0 0-1-1h-3a1 1 0 0 0-1 1zM52.5 39h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-12 0h-5V27.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zm-5 29.5V71a1 1 0 0 1 1 1H49a1 1 0 0 1 1-1v-2.5a1 1 0 0 1-1-1H36.5a1 1 0 0 1-1 1m33.5-10h7v-14a1 1 0 0 0-1-1h-5a1 1 0 0 0-1 1zM47.5 39h-7V25a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1zm-12 34v4a1 1 0 0 1 1 1h14a1 1 0 0 1 1-1v-4a1 1 0 0 1-1-1h-14a1 1 0 0 1-1 1M28 78h53v7H28Z M28 89.5V23a2.5 2.5 0 0 1 2.5-2.5h48A2.5 2.5 0 0 1 81 23v66.5",viewW:110,viewH:110}},{id:"shower",group:"sanitary",art:{d:"M31 84h49a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H31a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1m31.5-47.6v-4.686a11.7 11.7 0 0 0-3.441-8.283A11.77 11.77 0 0 0 50.75 20a11.77 11.77 0 0 0-8.309 3.431A11.7 11.7 0 0 0 39 31.714V84 M72 39.25a10.25 10.25 0 1 0-20.5 0zm-17.25 5v2.5m7.25-2.5v2.5m7.25-2.5v2.5m-14.5 3.75V53M62 50.5V53m7.25-2.5V53m-14.5 3.75v2.5m7.25-2.5v2.5m7.25-2.5v2.5M54.75 63v2.5M62 63v2.5m7.25-2.5v2.5",viewW:110,viewH:110}},{id:"sink",group:"sanitary",art:{d:"M30 57c0 5.523 4.477 10 10 10h29.5c5.523 0 10-4.477 10-10v-6.5A2.5 2.5 0 0 0 77 48H32.5a2.5 2.5 0 0 0-2.5 2.5zm14 22a1 1 0 0 0 1 1h19.5a1 1 0 0 0 1-1V67H44zm6-36.5a1 1 0 0 1 1-1h7.5a1 1 0 0 1 1 1V48H50zM45 37v-2a5 5 0 1 1 10 0v6.5",viewW:110,viewH:110}},{id:"sofa",group:"furniture",art:{d:"M59.5 29h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5m-34 0h24a5 5 0 0 1 5 5v32a5 5 0 0 1-5 5h-24a5 5 0 0 1-5-5V34a5 5 0 0 1 5-5 M18.5 44a5 5 0 0 1 5 5v12H86V49a5 5 0 0 1 5-5h.5a5 5 0 0 1 5 5v21.5a5 5 0 0 1-5 5H18a5 5 0 0 1-5-5V49a5 5 0 0 1 5-5z M25.25 57h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 25.25 57m34 0h24.5a4.75 4.75 0 0 1 4.75 4.75 4.75 4.75 0 0 1-4.75 4.75h-24.5a4.75 4.75 0 0 1-4.75-4.75A4.75 4.75 0 0 1 59.25 57M18.5 75.5h8l-1.674 5.441A1.5 1.5 0 0 1 23.392 82H20a1.5 1.5 0 0 1-1.5-1.5zm72 0h-8l1.674 5.441A1.5 1.5 0 0 0 85.608 82H89a1.5 1.5 0 0 0 1.5-1.5z",viewW:110,viewH:110}},{id:"stairs",group:"other",art:{d:"M73.47 46.365v-17.62m-10.571 25.55V36.674M52.326 61.783V45.484M42.193 69.273v-15.86M28.979 77.761a1 1 0 0 1 1-1h53.624v6.489a1 1 0 0 1-1 1H29.98a1 1 0 0 1-1-1z M26.777 57.497a1 1 0 0 1 1-1h2.846a1 1 0 0 1 1 1V83.25a1 1 0 0 1-1 1h-2.846a1 1 0 0 1-1-1z m73.113 28.633-41.492 32.93v-4.405l39.9-32.007a.7.7 0 0 1 .428-.151h3.724a1.762 1.762 0 1 1 0 3.524h-2.248a.5.5 0 0 0-.312.109M25.895 53.414a3.084 3.084 0 1 0 6.167 0 3.084 3.084 0 1 0-6.167 0m14.978 16.859a1 1 0 0 1 1-1h41.73v7.488h-42.73zm10.131-7.489a1 1 0 0 1 1-1h31.598v7.488H51.004z M61.576 55.294a1 1 0 0 1 1-1h21.026v7.49H61.576z M72.15 47.806a1 1 0 0 1 1-1h9.454a1 1 0 0 1 1 1v6.489H72.15z",viewW:110,viewH:110}},{id:"toilet",group:"sanitary",art:{d:"M32 26.5a2.5 2.5 0 0 1 2.5-2.5H45a2.5 2.5 0 0 1 2.5 2.5V57H32zM47.5 52h29a2.5 2.5 0 0 1 2.5 2.5V57H47.5zm17.037 20.102C73.95 70.288 79 62.01 79 57H32c.5 7.5 8.072 7 7 11l-2.342 16.862a1 1 0 0 0 .99 1.138H66.72a1 1 0 0 0 .97-1.243z",viewW:110,viewH:110}},{id:"tv",group:"appliance",art:{d:"M23.5 31H86a2.5 2.5 0 0 1 2.5 2.5v34A2.5 2.5 0 0 1 86 70H23.5a2.5 2.5 0 0 1-2.5-2.5v-34a2.5 2.5 0 0 1 2.5-2.5M50 70h9.5v8H50Zm-10 8h30M42.5 45.5h5m5 0h-5m0 0v9.75 m56.75 45.5 5 10 5-10",viewW:110,viewH:110}},{id:"wardrobe",group:"furniture",art:{d:"M28 23a2.5 2.5 0 0 1 2.5-2.5h24V85h-24a2.5 2.5 0 0 1-2.5-2.5zm2 65.5a1 1 0 0 0 1 1h47a1 1 0 0 0 1-1V85H30zM81 23a2.5 2.5 0 0 0-2.5-2.5h-24V85h24a2.5 2.5 0 0 0 2.5-2.5zM50.5 48v9.5m8-9.5v9.5",viewW:110,viewH:110}},{id:"washer",group:"appliance",art:{d:"M31.5 25h47a2.5 2.5 0 0 1 2.5 2.5v55a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5v-55a2.5 2.5 0 0 1 2.5-2.5 M31.5 37.5h47A2.5 2.5 0 0 1 81 40v42.5a2.5 2.5 0 0 1-2.5 2.5h-47a2.5 2.5 0 0 1-2.5-2.5V40a2.5 2.5 0 0 1 2.5-2.5 M38 60.5a17 17 0 1 0 34 0 17 17 0 1 0-34 0 M43.5 60.5a11.5 11.5 0 1 0 23 0 11.5 11.5 0 1 0-23 0m22-29.5a2 2 0 1 0 4 0 2 2 0 1 0-4 0m7.5 0a2 2 0 1 0 4 0 2 2 0 1 0-4 0m-37.25 0h9.5",viewW:110,viewH:110}},{id:"work_table",group:"furniture",art:{d:"M88.5 47h-20v14h20zm-12 4h4m7.984-8h-66v4h66zm-66 4h4v26.5a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5z M24.866 35.597A2.5 2.5 0 0 1 27.197 34h56.577a2.5 2.5 0 0 1 2.33 1.594l2.35 6.044a1 1 0 0 1-.93 1.362H23.46a1 1 0 0 1-.933-1.361zM88.5 61h-20v12.5A1.5 1.5 0 0 0 70 75h17a1.5 1.5 0 0 0 1.5-1.5zm-12 4h4",viewW:110,viewH:110}}];class Ic{constructor(t,e){this.host=t,this.hooks=e}place(t,e="mouse"){const s=this.host._decorImagePalette,i=this.host._curSpaceCfg;if(!s||!i)return;const o=this.hooks.decorSnap(t,e),a=jt(s.width,s.height),n=Gt(a.w,this.host._cellCm,this.host._gridPitch)/m,r=Gt(a.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,l="di"+Date.now().toString(36)+Math.random().toString(36).slice(2,5),h=this.hooks.geometrySnapshot();i.decor=[...this.host._decorList,{id:l,kind:"image",asset_id:s.asset_id,x:Z(o[0]/m-n/2),y:Z(o[1]/this.host._decorH-r/2),w:n,h:r,opacity:1}],this.host._decorSel=l,this.host._decorTool="select",this.host._decorImagePalette=null,this.hooks.clearFurniturePreview(),this.hooks.recordGeometry(this.host._t("history.decor_add"),h),this.hooks.saveConfig(),this.host.requestUpdate()}renderPlacementPreview(){const t=this.host._furnPreviewInput,e=this.host._decorImagePalette;if(!t||!e||"decor"!==this.host._mode||"image"!==this.host._decorTool||!this.host._pointerModality.hoverEnabled)return d;const s=this.hooks.decorSnap(t.raw,"mouse"),i=jt(e.width,e.height),o=Gt(i.w,this.host._cellCm,this.host._gridPitch)/m,a=Gt(i.h,this.host._cellCm,this.host._gridPitch)/this.host._decorH,n=this.host._display(e.url);return n?_``:d}renderMissing(t,e,s,i,o,a,n,r,l){const h=i+a/2,c=o+n/2;return _`${this.host._t("decor.image_unavailable")} - `}async uploadFromInput(t,e=!1){const s=t.target,i=s.files?.[0];if(s.value="",!i||this.host._decorAssetBusy)return;let o;try{o=await bo(i,2097152)}catch{return void this.host._showToast(this.host._t("backup.error.invalid_image"))}if("reject"!==o.kind)return"guard"===o.kind?(this.hooks.setGuardReplace(e),void(this.host._backdropGuard=o.state)):void await this.upload(i,i.name,e);this.host._showToast(this.host._t("toast.plan_formats"))}async upload(t,e,s){if(!this.host._decorAssetBusy){this.host._decorAssetBusy=!0;try{const i=new FormData;i.append("file",t,e);const o=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth("/api/houseplan/assets/upload",{method:"POST",body:i}):await fetch("/api/houseplan/assets/upload",{method:"POST",body:i,headers:this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}),a=await o.json().catch(()=>({}));if(!o.ok||a.error||!a.asset){const t={invalid_format:"backup.error.invalid_image",invalid_image:"backup.error.invalid_image",unsupported_image:"backup.error.unsupported_image",too_large:"backdrop.too_large_title",capacity_exceeded:"decor.image_error_capacity"};throw new Error(this.host._t(t[String(a.error)]||"backup.error.io_error"))}const n=qt({assets:[a.asset]}).values().next().value;if(!n)throw new Error(this.host._t("backup.error.io_error"));this.host._decorAssets=new Map(this.host._decorAssets).set(n.asset_id,n),this.host._decorAssetCatalog=[n,...this.host._decorAssetCatalog.filter(t=>t.asset_id!==n.asset_id)],s&&"image"===this.host._decorShapeDialog?.kind?this.host._decorShapeDialog={...this.host._decorShapeDialog,assetId:n.asset_id}:this.host._decorImagePalette=n,this.host.requestUpdate()}catch(t){this.host._showToast(this.host._t("decor.image_upload_failed",{err:this.host._errText(t)}))}finally{this.host._decorAssetBusy=!1}}}async delete(t){if(t.used_by?.length)return void this.host._showToast(this.host._t("decor.image_in_use"));if(await this.host._confirmDanger({key:`delete-decor-asset:${t.asset_id}`,kind:"destructive",title:this.host._t("decor.image_delete_title"),message:this.host._t("decor.image_delete_message",{name:t.name}),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}))try{await this.host.hass.callWS({type:"houseplan/assets/delete",asset_id:t.asset_id}),this.host._decorAssetCatalog=this.host._decorAssetCatalog.filter(e=>e.asset_id!==t.asset_id),this.host._decorAssets.delete(t.asset_id),this.host._decorImagePalette?.asset_id===t.asset_id&&(this.host._decorImagePalette=null),this.host.requestUpdate()}catch(t){this.host._showToast("in_use"===t?.code?this.host._t("decor.image_in_use"):this.host._t("backup.error.io_error"))}}async loadCatalog(){try{const t=await this.host.hass.callWS({type:"houseplan/assets/list"}),e=qt(t);this.host._decorAssetCatalog=[...e.values()],this.host._decorAssets=new Map([...this.host._decorAssets,...e]),this.host.requestUpdate()}catch{this.host._showToast(this.host._t("backup.error.io_error"))}}renderImagePalette(){const t=this.host._decorImagePalette;return p``}renderFurniturePalette(){const t=this.host._furnPalette,e=this.host._furnCategory,s=Ut.flatMap(t=>Kt(t)),i=Pc.filter(t=>s.some(e=>e.category===t.id)),o=i.find(t=>t.id===e)||null,a=o?s.filter(t=>t.category===o.id):[],n=this.host._t(this.host._imperial?"gs.unit_ft":"gs.unit_m");return p`
    t.stopPropagation()}> +
    `}renderFurniturePalette(){const t=this.host._furnPalette,e=this.host._furnCategory,s=Ut.flatMap(t=>Kt(t)),i=Dc.filter(t=>s.some(e=>e.category===t.id)),o=i.find(t=>t.id===e)||null,a=o?s.filter(t=>t.category===o.id):[],n=this.host._t(this.host._imperial?"gs.unit_ft":"gs.unit_m");return p`
    t.stopPropagation()}>
    ${this.host._t("furn.title")} @@ -646,7 +646,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 {this.host._drawWallField=t.target.value}} title=${this.host._t("draw"===this.host._tool?"markup.draw_wall_title":"physical.column_size_title")} /> ${this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")} - ${this.host._t("physical.allowed_range",{min:me(t,this.host._imperial),max:me(this.host._drawWallMaxCm,this.host._imperial),unit:this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")})} + ${this.host._t("physical.allowed_range",{min:ge(t,this.host._imperial),max:ge(this.host._drawWallMaxCm,this.host._imperial),unit:this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")})} `}_renderPlanSecondary(){const t=this.host._editorSecondaryContextId,e=this.host._physicalSel;if(e){if(!("partition"===e.kind?!!this.host._curSpaceCfg.partitions?.some(t=>t.id===e.id):!!this.host._curSpaceCfg.wall_columns?.some(t=>t.id===e.id)))return null;const s="partition"===e.kind?this.host._t("markup.partition"):"column"===e.kind?this.host._t("markup.column"):this.host._t("markup.add");return{contextId:t,kind:"selection",ariaLabel:this.host._t("editor.context_actions",{object:s}),visibleLabel:s,content:p` `;return t?{...t,kind:"selection"===t.kind?"mixed":t.kind,content:p`${t.content}${s}`}:{contextId:e,kind:"tool",ariaLabel:this.host._t("editor.tool_options",{tool:this.host._t("decor.backdrop")}),content:s}}_renderEditorSecondary(){if(!this.host._editing)return d;const t=this.host._editorSecondary.activeGroup(this.host._editorToolbarGroups),e=t?this._renderEditorGroupModel(t):"plan"===this.host._mode?this._renderPlanSecondary():"decor"===this.host._mode?this._withBackdropReset(this._renderDecorSecondary()):null;return this.host._editorSecondary.render(e,this.host._editorSecondaryDialogBlocked)}_renderDecorBar(){const t=[["select","mdi:cursor-default-outline","decor.select"],...this.host._bdRect?[["backdrop","mdi:image-move","decor.backdrop"]]:[],["line","mdi:vector-line","decor.line"],["rect","mdi:rectangle-outline","decor.rect"],["ellipse","mdi:ellipse-outline","decor.ellipse"],["text","mdi:format-text","decor.text"],["furniture","mdi:sofa-outline","decor.furniture"],...this.host._haDecorAssetsApi===hs?[["image","mdi:image-plus-outline","decor.image"]]:[],["erase","mdi:eraser","decor.erase"]],e=this.host._geometryHistory.undoName,s=this.host._geometryHistory.redoName;return p`
    + `;return t?{...t,kind:"selection"===t.kind?"mixed":t.kind,content:p`${t.content}${s}`}:{contextId:e,kind:"tool",ariaLabel:this.host._t("editor.tool_options",{tool:this.host._t("decor.backdrop")}),content:s}}_renderEditorSecondary(){if(!this.host._editing)return d;const t=this.host._editorSecondary.activeGroup(this.host._editorToolbarGroups),e=t?this._renderEditorGroupModel(t):"plan"===this.host._mode?this._renderPlanSecondary():"decor"===this.host._mode?this._withBackdropReset(this._renderDecorSecondary()):null;return this.host._editorSecondary.render(e,this.host._editorSecondaryDialogBlocked)}_renderDecorBar(){const t=[["select","mdi:cursor-default-outline","decor.select"],...this.host._bdRect?[["backdrop","mdi:image-move","decor.backdrop"]]:[],["line","mdi:vector-line","decor.line"],["rect","mdi:rectangle-outline","decor.rect"],["ellipse","mdi:ellipse-outline","decor.ellipse"],["text","mdi:format-text","decor.text"],["furniture","mdi:sofa-outline","decor.furniture"],...this.host._haDecorAssetsApi===cs?[["image","mdi:image-plus-outline","decor.image"]]:[],["erase","mdi:eraser","decor.erase"]],e=this.host._geometryHistory.undoName,s=this.host._geometryHistory.redoName;return p`
    ${t.map(([t,e,s])=>p`
    @@ -938,10 +938,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    - `}_cssPxToRender(t){const e=this.host._stageEl,s=this.host._viewOr(this.host._baseVb());return e?.clientWidth&&e.clientHeight?Math.max(s.w/e.clientWidth,s.h/e.clientHeight)*t:this.host._gridPitch/8*t}_deleteRoomClick(t){const e=this.host._spaceModel();if(!e)return;const s=[...e.rooms].reverse().find(e=>this._pointInRoom(t,e));s?s.id&&(this.host._roomDeleteDialog={roomId:s.id,name:s.name}):this.host._showToast(this.host._t("toast.delete_room_pick"))}_wallThickHit(t){const e=this.host._spaceModel();if(!e)return null;const s=6*this.host._gridPitch,i=this.host._openCuts();let o=null;const a=(t,e,i)=>{e>s||(!o||e100)return void this._showPhysicalRange(100);if("room"!==e.source.kind){const t=this._geometrySnapshot(),i=(s.partitions||[]).find(t=>t.id===e.source.id);if(!i)return;if(0===n&&ie(s.openings,{kind:"partition",id:i.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));i.cm=n,this.host._wallDialog=null;return this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),t)&&this.host._showToast(this.host._t("toast.wallthick_set")),void this.host.requestUpdate()}const r=this._geometrySnapshot(),l=n>0?n:null;if(0===n){const i=.02*this.host._gridPitch,o=[e.a[0],e.a[1],e.b[0],e.b[1]],a=(s.rooms||[]).find(t=>t.id===e.roomId),n=new Set(t&&a&&Array.isArray(a.wall_ids)?a.wall_ids:(s.wall_segments||[]).filter(t=>{const e=[Number(t.a?.[0])*sd,Number(t.a?.[1])*sd],s=[Number(t.b?.[0])*sd,Number(t.b?.[1])*sd];return Wt(e,o)<=i&&Wt(s,o)<=i}).map(t=>String(t.id))),r=(s.openings||[]).some(t=>{if("partition"===t.host?.kind)return!1;if("wall"===t.host?.kind&&n.has(t.host.id))return!0;if(t.host)return!1;const e=[Number(t.x)*sd,Number(t.y)*sd];return e.every(Number.isFinite)&&Wt(e,o)<=i});if(r)return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"))}let h,c=this.host._openCuts();if(n>0&&c.length){const o=[];if(t&&e.roomId){const t=(s.rooms||[]).find(t=>t.id===e.roomId),a=new Set(Array.isArray(t?.wall_ids)?t.wall_ids:[]);for(const t of s.wall_segments||[])a.has(t.id)&&o.push([Number(t.a?.[0])*sd,Number(t.a?.[1])*sd,Number(t.b?.[0])*sd,Number(t.b?.[1])*sd]);if(!o.length){const t=i.rooms.find(t=>t.id===e.roomId),s=t?B(t):null;for(let t=0;s&&t!o.some(e=>Wt([t[0],t[1]],e)<=a&&Wt([t[2],t[3]],e)<=a&&Wt([e[0],e[1]],t)<=a&&Wt([e[2],e[3]],t)<=a))}h=t&&e.roomId?cs(s.walls,i.rooms,e.roomId,l,this.host._wallKeyPitch,c,sd):gt(s.walls,e.a,e.b,l,this.host._wallKeyPitch,sd),h=this.host._normalizeWalls(h,c);for(const t of s.wall_segments||[])t.cm=J(h,t.a,t.b,O,1);h.length?s.walls=h:delete s.walls,this.host._wallDialog=null,this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),r)&&this.host._showToast(this.host._t(0===n?"toast.wallthick_cleared":"toast.wallthick_set")),this.host.requestUpdate()}_wallHatchDefs(t){if(!this.host._spaceWalls.length&&!this.host._physicalBodiesR().length&&!this.host._markup)return _``;const e=v(this.host._cellCm);return _` + `}_cssPxToRender(t){const e=this.host._stageEl,s=this.host._viewOr(this.host._baseVb());return e?.clientWidth&&e.clientHeight?Math.max(s.w/e.clientWidth,s.h/e.clientHeight)*t:this.host._gridPitch/8*t}_deleteRoomClick(t){const e=this.host._spaceModel();if(!e)return;const s=[...e.rooms].reverse().find(e=>this._pointInRoom(t,e));s?s.id&&(this.host._roomDeleteDialog={roomId:s.id,name:s.name}):this.host._showToast(this.host._t("toast.delete_room_pick"))}_wallThickHit(t){const e=this.host._spaceModel();if(!e)return null;const s=6*this.host._gridPitch,i=this.host._openCuts();let o=null;const a=(t,e,i)=>{e>s||(!o||e100)return void this._showPhysicalRange(100);if("room"!==e.source.kind){const t=this._geometrySnapshot(),i=(s.partitions||[]).find(t=>t.id===e.source.id);if(!i)return;if(0===n&&ie(s.openings,{kind:"partition",id:i.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));i.cm=n,this.host._wallDialog=null;return this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),t)&&this.host._showToast(this.host._t("toast.wallthick_set")),void this.host.requestUpdate()}const r=this._geometrySnapshot(),l=n>0?n:null;if(0===n){const i=.02*this.host._gridPitch,o=[e.a[0],e.a[1],e.b[0],e.b[1]],a=(s.rooms||[]).find(t=>t.id===e.roomId),n=new Set(t&&a&&Array.isArray(a.wall_ids)?a.wall_ids:(s.wall_segments||[]).filter(t=>{const e=[Number(t.a?.[0])*id,Number(t.a?.[1])*id],s=[Number(t.b?.[0])*id,Number(t.b?.[1])*id];return Wt(e,o)<=i&&Wt(s,o)<=i}).map(t=>String(t.id))),r=(s.openings||[]).some(t=>{if("partition"===t.host?.kind)return!1;if("wall"===t.host?.kind&&n.has(t.host.id))return!0;if(t.host)return!1;const e=[Number(t.x)*id,Number(t.y)*id];return e.every(Number.isFinite)&&Wt(e,o)<=i});if(r)return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"))}let h,c=this.host._openCuts();if(n>0&&c.length){const o=[];if(t&&e.roomId){const t=(s.rooms||[]).find(t=>t.id===e.roomId),a=new Set(Array.isArray(t?.wall_ids)?t.wall_ids:[]);for(const t of s.wall_segments||[])a.has(t.id)&&o.push([Number(t.a?.[0])*id,Number(t.a?.[1])*id,Number(t.b?.[0])*id,Number(t.b?.[1])*id]);if(!o.length){const t=i.rooms.find(t=>t.id===e.roomId),s=t?B(t):null;for(let t=0;s&&t!o.some(e=>Wt([t[0],t[1]],e)<=a&&Wt([t[2],t[3]],e)<=a&&Wt([e[0],e[1]],t)<=a&&Wt([e[2],e[3]],t)<=a))}h=t&&e.roomId?ds(s.walls,i.rooms,e.roomId,l,this.host._wallKeyPitch,c,id):gt(s.walls,e.a,e.b,l,this.host._wallKeyPitch,id),h=this.host._normalizeWalls(h,c);for(const t of s.wall_segments||[])t.cm=J(h,t.a,t.b,O,1);h.length?s.walls=h:delete s.walls,this.host._wallDialog=null,this._commitPhysicalGeometry(this.host._t("history.wall_thickness"),r)&&this.host._showToast(this.host._t(0===n?"toast.wallthick_cleared":"toast.wallthick_set")),this.host.requestUpdate()}_wallHatchDefs(t){if(!this.host._spaceWalls.length&&!this.host._physicalBodiesR().length&&!this.host._markup)return _``;const e=v(this.host._cellCm);return _` - + `}_renderWallThickUi(){const t=this.host._wallThickHover;return t&&t.d?_``:_``}_renderWallThickDialog(){const t=this.host._wallDialog;return t?p`
    -
    `:p``}_openingAt(t){if(!this.host._openingsR.length)return null;const e=this.host._openingsR.flatMap(e=>{const s=e.angle*Math.PI/180,i=t[0]-e.rx,o=t[1]-e.ry,a=i*Math.cos(s)+o*Math.sin(s);return Math.abs(a)>e.rlen/2+y(12,this.host._cellCm)?[]:[{o:e,localY:-i*Math.sin(s)+o*Math.cos(s)}]});if(!e.length)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i).value;return e.find(({o:t,localY:e})=>{const s="gate"===t.type?!t.flip_v:t.flip_v,i=t.partitionHost||this.host._spaceWalls.length||"gate"===t.type?this.host._openingFace(t,o,!!s):{ox:0,oy:0,cm:0,side:-1},a=ds({type:t.type,length:t.rlen,angle:t.angle,amount:this.host._openingAmt(t),flipH:!!t.flip_h,flipV:!!t.flip_v,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:i});return Math.abs(e)<=a.hitHalf})?.o||null}_resolveOpeningPlacement(t){const e=this.host._openingPreset;if("opening"!==this.host._tool||!e)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i),a=`${o.key}|partitions:${this.host._cfgEpoch}`;this.host._openingPlacementIntervalsCache&&this.host._openingPlacementIntervalsCache.key===a||(this.host._openingPlacementIntervalsCache={key:a,value:[...pt(s.rooms,this.host._spaceWalls,i,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd),...ps(s.partitions,this.host._cellCm,this.host._gridPitch)]}),this.host._openingDimensionContextCache&&this.host._openingDimensionContextCache.key===a||(this.host._openingDimensionContextCache={key:a,value:Ec({rooms:s.rooms,walls:this.host._spaceWalls,openCuts:i,partitions:s.partitions,roomOpenings:this.host._roomWallOpeningInputs(),partitionCuts:this._partitionOpeningCuts(s),pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:sd,epsilon:2e-4*this.host._gridPitch})});const n=us({pointer:[t[0],t[1]],preset:e,geometryRevision:this.host._cfgEpoch,renderedLength:this.host._cmToUnits(e.lengthCm),intervals:this.host._openingPlacementIntervalsCache.value,baseTolerance:1.5*this.host._gridPitch,bodyPointerPadding:this._cssPxToRender("touch"===this.host._pointerModality.modality||"pen"===this.host._pointerModality.modality?10:6),gridStep:this.host._gridPitch});this.host._openingJambBlockCm=n.jambBlockedTarget?n.jambBlockedTarget.physicalHalfWidth/this.host._gridPitch*this.host._cellCm:null;const r=n.candidate;if(!r)return null;const l="gate"===r.type?!r.flipV:r.flipV;let h;if(r.host){const t=ct({id:"preview",type:r.type,x:r.x/sd,y:r.y/sd,angle:r.angle,length:r.renderedLength/sd,host:r.host},s.partitions,sd,this.host._cellCm,this.host._gridPitch).resolved;h=t?_s(t,l):{ox:0,oy:0,cm:0,side:-1}}else h=ms(o.value,{x:r.x,y:r.y,angle:r.angle,length:r.renderedLength,flip_v:l});const c="mi"===this.host.hass?.config?.unit_system?.length,d=Gc(r,this.host._openingDimensionContextCache.value).map(t=>({x:t.label[0],y:t.label[1],text:Ot(t.distance/this.host._gridPitch*this.host._cellCm,c),dimension:t}));return{...r,face:h,measure:{labels:d,guide:r.measure.guide}}}_activateOpeningPlacement(t){this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingPreset=gs(t,++this.host._openingPresetRevision),this.host._openingHoverCandidate=null,this.host._cursorPt=null)}_clearOpeningPlacement(t){this.host._openingHoverCandidate=null,this.host._openingJambBlockCm=null,t&&(this.host._openingPreset=null,this.host._openingRebindId=null)}_openingClick(t){const e=this.host._spaceModel();if(!e)return;const s=this.host._openingRebindId?null:this._openingAt(t);if(s)return void this._editOpening(s);const i=this.host._openingPreset;if(!i)return;const o=this.host._openingHoverCandidate,a=o&&fs(o,[t[0],t[1]],i.revision,this.host._cfgEpoch)?o:this._resolveOpeningPlacement(t);if(!a){if(null!=this.host._openingJambBlockCm)return void this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(this.host._openingJambBlockCm,this.host._imperial)}));const s=1.5*this.host._gridPitch,i=lt(t,e.rooms,s);return i&&bs(i.x,i.y,i.angle,this.host._openCuts(),s)?void this.host._showToast(this.host._t("toast.opening_on_zero_wall")):void this.host._showToast(this.host._t("toast.opening_no_wall"))}const n=this.host._openingRebindId?this.host._curSpaceCfg?.openings?.find(t=>t.id===this.host._openingRebindId):null;this.host._openingDialog={...n?{id:n.id,type:n.type,lengthCm:Math.round(n.length*sd/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:n.contact||"",lock:n.lock||"",invert:!!n.invert,flipH:!!n.flip_h,flipV:!!n.flip_v}:{type:a.type,lengthCm:a.lengthCm,contact:"",lock:"",invert:!1,flipH:a.flipH,flipV:a.flipV},...a.host?{host:a.host}:{},x:a.x,y:a.y,angle:a.angle},this.host._openingRebindId=null,this.host._openingHoverCandidate=null,this.host._cursorPt=null}_editOpening(t){this.host._openingDialog={id:t.id,type:t.type,lengthCm:Math.round(t.rlen/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:t.contact||"",lock:t.lock||"",invert:!!t.invert,flipH:!!t.flip_h,flipV:!!t.flip_v,..."partition"===t.host?.kind?{host:{...t.host}}:{},x:t.rx,y:t.ry,angle:t.angle}}_opPointerDown(t,e){if("plan"===this.host._mode&&this.host._spaceModel()&&"resize"!==this.host._tool){t.preventDefault(),t.stopPropagation();try{od(t)}catch{}this.host._opDrag={id:e.id,moved:!1,sx:t.clientX,sy:t.clientY,dirty:!1,before:this._geometrySnapshot()}}}_opPointerMove(t,e){Wo(this.host,"opening",()=>this._opPointerMoveNow(t,e))}_opPointerMoveNow(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;if(Math.abs(t.clientX-this.host._opDrag.sx)+Math.abs(t.clientY-this.host._opDrag.sy)<=3)return;const s=this.host._spaceModel();if(!s)return;const i=this._svgPoint(t),o=this.host._curSpaceCfg,a=o?.openings?.find(t=>t.id===e.id);if(!a)return;if("partition"===a.host?.kind){const t=s.partitions.find(t=>t.id===a.host.id);if(!t)return;const e=t.b[0]-t.a[0],o=t.b[1]-t.a[1],n=Math.hypot(e,o);if(!(n>1e-9))return;const r=e/n,l=o/n;if(Math.abs((i[0]-t.a[0])*l-(i[1]-t.a[1])*r)>4*this.host._gridPitch)return;const h=a.length*sd/2+mt(t,this.host._cellCm,this.host._gridPitch);let c=(i[0]-t.a[0])*r+(i[1]-t.a[1])*l;if(c=Math.round(c/this.host._gridPitch)*this.host._gridPitch,c=Math.max(h,Math.min(n-h,c)),n<2*h-1e-9)return;const d=c/n,p=(t.a[0]+r*c)/sd,u=(t.a[1]+l*c)/this.host._spaceH;let _=180*Math.atan2(o,e)/Math.PI;_>=90?_-=180:_<-90&&(_+=180);const m=a.host.t!==d||a.x!==p||a.y!==u||a.angle!==_;return this.host._opDrag.moved=!0,m&&(this.host._opDrag.dirty=!0),a.host={...a.host,t:d},a.x=p,a.y=u,a.angle=_,this.host._opMeasure=null,m&&this.host._cfgEpoch++,void this.host.requestUpdate()}const n=lt(i,s.rooms,4*this.host._gridPitch);if(!n)return;this.host._opDrag.moved=!0;const r=this._opRuler(n,a.length*sd);this.host._opMeasure=r.measure;const l=r.x/sd,h=r.y/this.host._spaceH,c=a.x!==l||a.y!==h||a.angle!==n.angle;if(c&&(this.host._opDrag.dirty=!0),a.x=l,a.y=h,a.angle=n.angle,Number(this.host._serverCfg?.model_version||0)>=9){const t=Hn(a,o?.wall_segments||[]);t?a.host=t:delete a.host}c&&this.host._cfgEpoch++,this.host.requestUpdate()}_opRuler(t,e){const s=this.host._spaceModel()?.rooms||[],i=this.host._gridPitch/2;let o=t.x,a=t.y,n=vs([o,a],t.angle,e,s,i);if(n&&n.centered&&(o!==n.wallCenter[0]||a!==n.wallCenter[1]))[o,a]=n.wallCenter,n=vs([o,a],t.angle,e,s,i);else if(n){const[r,l]=n.wallA,[h,c]=n.wallB,d=h-r,p=c-l,u=Math.hypot(d,p);if(u>0){const h=this.host._gridPitch,c=Math.min(e/2,u/2);let _=Math.round(((o-r)*d+(a-l)*p)/u/h)*h;_=Math.max(c,Math.min(u-c,_)),o=r+_/u*d,a=l+_/u*p,n=vs([o,a],t.angle,e,s,i)||n}}if(!n)return{x:o,y:a,angle:t.angle,measure:null};const r="mi"===this.host.hass?.config?.unit_system?.length,l=(t,e)=>({x:e[0],y:e[1],text:Ot(t/this.host._gridPitch*this.host._cellCm,r)});return{x:o,y:a,angle:t.angle,measure:{labels:[l(n.sideA,n.midA),l(n.sideB,n.midB)],guide:n.centered?{x:n.wallCenter[0],y:n.wallCenter[1],angle:t.angle}:null}}}_opPointerUp(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;jo(this.host,"opening");const s=this.host._opDrag,i=s.moved;this.host._opMeasure=null,i&&s.dirty&&this._commitPhysicalGeometry(this.host._t("history.move_opening"),s.before);const o=()=>{this.host._opDrag=null,this.host.requestUpdate()};i?window.setTimeout(o,0):o()}_opClick(t,e){"plan"===this.host._mode&&"resize"===this.host._tool||(t.stopPropagation(),this.host._opDrag?.moved||"plan"===this.host._mode&&this._editOpening(e))}_saveOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=this._geometrySnapshot(),o=this.host._spaceH,a=(e.openings||[]).find(e=>e.id===t.id),n={...a||{},id:t.id||"o"+Date.now().toString(36),type:t.type,x:t.x/sd,y:t.y/o,angle:t.angle,length:a&&!t.lengthTouched?a.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/sd,...t.host?{host:{...t.host}}:{}};if("partition"===n.host?.kind){const t=ys(a,n)?bt(n,s.partitions,sd,this.host._cellCm,this.host._gridPitch):ct(n,s.partitions,sd,this.host._cellCm,this.host._gridPitch);if(!t.resolved){const e=s.partitions.find(t=>t.id===n.host.id);if("does-not-fit-jamb"===t.reason&&e){const t=mt(e,this.host._cellCm,this.host._gridPitch);this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(t/this.host._gridPitch*this.host._cellCm,this.host._imperial)}))}else this.host._showToast(this.host._t("opening.partition_orphan"));return}const i=(e.openings||[]).flatMap(t=>{if(!t.host||t.id===n.id)return[];const e=ct(t,s.partitions,sd,this.host._cellCm,this.host._gridPitch).resolved;return e?[e]:[]});if($s(t.resolved,i))return void this.host._showToast(this.host._t("toast.opening_no_wall"));Object.assign(n,dt(n,t.resolved,sd))}else if(Number(this.host._serverCfg?.model_version||0)>=9){const t=Hn(n,e.wall_segments||[]);if(!t)return void this.host._showToast(this.host._t("toast.opening_no_wall"));n.host=t}else delete n.host;"passage"===t.type?(delete n.contact,delete n.lock,delete n.invert,delete n.flip_h,delete n.flip_v):(n.contact=t.contact||null,n.lock=("door"===t.type||"gate"===t.type)&&t.lock||null,n.invert=t.invert||void 0,n.flip_h="gate"!==t.type&&t.flipH||void 0,n.flip_v=t.flipV||void 0),e.openings=e.openings||[];const r=e.openings.findIndex(t=>t.id===n.id);r>=0?e.openings[r]=n:e.openings.push(n),this._commitPhysicalGeometry(this.host._t(t.id?"history.edit_opening":"history.add_opening"),i),this.host._openingDialog=null,this.host.requestUpdate()}_deleteOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg;if(!t?.id||!e?.openings)return;const s=this._geometrySnapshot();e.openings=e.openings.filter(e=>e.id!==t.id),this._commitPhysicalGeometry(this.host._t("history.delete_opening"),s),this.host._openingDialog=null,this.host.requestUpdate()}_contactCandidates(){const t=[];for(const e of Object.keys(this.host.hass.states)){if(!this.host._openingEntityAvailable(e))continue;const s=e.split(".")[0];if("binary_sensor"!==s&&"cover"!==s)continue;const i=this.host.hass.states[e],o=["door","window","opening","garage_door","garage"].includes(i?.attributes?.device_class||"");("cover"!==s||o)&&t.push([e,i?.attributes?.friendly_name||e,o?0:1])}return t.sort((t,e)=>t[2]-e[2]||t[1].localeCompare(e[1])).map(([t,e])=>({value:t,label:e}))}_lockCandidates(){return Object.keys(this.host.hass.states).filter(t=>t.startsWith("lock.")&&this.host._openingEntityAvailable(t)).map(t=>({value:t,label:this.host.hass.states[t]?.attributes?.friendly_name||t})).sort((t,e)=>t.label.localeCompare(e.label))}_toggleOpeningEntityPicker(t){const e=this.host._openingDialog;if(!e)return;const s="contact"===t?!e.contactOpen:!e.lockOpen;this.host._openingDialog={...e,contactOpen:"contact"===t&&s,lockOpen:"lock"===t&&s}}_filterOpeningEntities(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contactFilter:e}:{...s,lockFilter:e})}_selectOpeningEntity(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contact:e,contactOpen:!1,contactFilter:""}:{...s,lock:e,lockOpen:!1,lockFilter:""})}_mergeClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms,i=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!i?.id)return;const o=i.id;if(!this.host._mergeSel||this.host._mergeSel===o)return void(this.host._mergeSel=this.host._mergeSel===o?null:o);const a=s.find(t=>t.id===this.host._mergeSel),n=a?B(a):null,r=B(i),l=n&&r?ws(n,r):null;if(!l)return this.host._showToast(this.host._t("toast.merge_not_adjacent")),void(this.host._mergeSel=null);this.host._mergeDialog={aId:this.host._mergeSel,bId:o,poly:l,pick:"a"},this.host._mergeSel=null}_commitMerge(){const t=this.host._mergeDialog,e=this.host._curSpaceCfg;if(!t||!e||!this.host._spaceModel())return;const s=this._geometrySnapshot(),i=this.host._spaceH,o="a"===t.pick?t.aId:t.bId,a="a"===t.pick?t.bId:t.aId,n=Jc(this.host._serverCfg?.markers||[],{kind:"merge",dropId:a,keepId:o});s&&n.changed&&(s.roomReferences=n.before);const r=e.rooms.find(t=>t.id===o);if(!r)return void(this.host._mergeDialog=null);r.poly=t.poly.map(t=>[t[0]/sd,t[1]/i]),delete r.x,delete r.y,delete r.w,delete r.h,e.rooms=e.rooms.filter(t=>t.id!==a),n.changed&&this.host._serverCfg&&(this.host._serverCfg.markers=n.markers);const l=this._commitPhysicalGeometry(this.host._t("history.merge_rooms"),s);this.host._mergeDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),l&&this.host._showToast(this.host._t("toast.rooms_merged",{name:r.name||""}))}_splitClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms;if(!this.host._splitSel){const e=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!e?.id)return;return void(this.host._splitSel={roomId:e.id,pts:[]})}const i=s.find(t=>t.id===this.host._splitSel.roomId),o=i?B(i):null;if(!i||!o)return void(this.host._splitSel=null);const a=.02*this.host._gridPitch,n=6*this.host._gridPitch,r=ks(t,o),l=r&&xs(r,o,this.host._gridPitch)||r,h=r&&l&&Math.hypot(r[0]-t[0],r[1]-t[1])<=n?l:null,c=!!h&&Ss(h,o,a),d=this.host._splitSel.pts;if(!d.length)return c?void(this.host._splitSel={...this.host._splitSel,pts:[h]}):void this.host._showToast(this.host._t("toast.split_pick_wall"));if(!c){const e=this._snap(t);return Me(e,o,a)?void(this.host._splitSel={...this.host._splitSel,pts:[...d,e]}):void this.host._showToast(this.host._t("toast.split_pick_inside"))}const p=Pe(o,[...d,h],a);if(!p)return void this.host._showToast(this.host._t("toast.split_bad_cut"));this._resetRoomDialogFields();const[u,_]=p,m=H(u)>=H(_)?u:_,g=m===u?_:u;this.host._pendingSplit={roomId:i.id,mainPoly:m,newPoly:g},this.host._cursorPt=null,this.host._nameSel="",this.host._areaSel="",this.host._roomDialog=!0}_markupMove(t){if(!this.host._markup)return;if("column"===this.host._tool)return void(this.host._cursorPt=this._snap(this._svgPoint(t)));if("opening"===this.host._tool||"wallthick"===this.host._tool)return void(this.host._cursorPt=this._svgPoint(t));const e="draw"===this.host._tool&&!this.host._contourClosed,s="split"===this.host._tool&&!!this.host._splitSel?.pts?.length;if(!e&&!s)return;const i=this._svgPoint(t);if(e){const e=this._resolvePlanDrawPoint(i,t.shiftKey);if(this.host._planSnapHover={contextKey:e.contextKey,candidate:e.candidate,conflicts:e.conflicts},this._syncPlanSnapConflictMarkers(e.conflicts),this._syncPlanSnapActiveMarker(e.candidate),!this.host._path.length)return;return void(this.host._cursorPt=e.point)}this.host._cursorPt=this._snap(i)}_saveRoom(){(this.host._areaSel||this.host._nameSel.trim())&&nt(this.host._roomTempMin,this.host._roomTempMax).valid&&(this.host._wallFaceBatch?this._decideWallFace(!0):this._commitRoom())}_decideWallFace(t){const e=this.host._wallFaceBatch;if(!e)return;const s=e.candidates[e.index];if(!s)return;if(!t&&(s.existing||s.repair)&&1===e.candidates.length)return this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate();const i=t?{candidate:s,create:!0,name:this.host._nameSel.trim(),area:this.host._areaSel||null,settings:this._roomSettingsFromDialog()?JSON.parse(JSON.stringify(this._roomSettingsFromDialog())):null}:{candidate:s,create:!1},o=[...e.decisions,i],a=e.index+1;if(a"number"==typeof t&&Number.isFinite(t)&&t>=0?t:null,o=.02*this.host._gridPitch,a=this.host._spaceModel();if(!a)return ut;for(const e of this._planSnapGeometrySnapshot().value.segments)if(!("room"===e.sourceKind||Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])>o)&&"partition"===e.sourceKind)return i(a.partitions.find(t=>t.id===e.sourceId)?.cm)??ut;const n=Rh(Math.max(0,e.length-1),s,this.host._drawWallCm,ut);for(let s=0;s+1[...t]);if(!e)return s;const i=this.host._activeWallChainPartitionIds.findIndex((t,s)=>this._activeWallSourceKey(s)===e.sourceKey),o=i>=0?i+("b"===e.endpoint?1:0):-1;return o>=0&&oe.key===t.sourceKey),a=i.find(e=>e.key===t.targetSourceKey);if(!o||!a)return!1;const n="a"===t.endpoint?o.a:o.b;return!(Math.hypot(n[0]-t.from[0],n[1]-t.from[1])>s)&&(!(Wt(t.to,[a.a[0],a.a[1],a.b[0],a.b[1]])>s)&&!function(t,e){if(!t.sourceKey.startsWith("static:partition|"))return!1;const s=t.sourceKey.slice(17).split("|")[0];return!!s&&e.some(t=>"partition"===t.host?.kind&&t.host.id===s)}(t,this.host._curSpaceCfg?.openings||[]))}_applyWallRepair(t,e){const s=this.host._curSpaceCfg;if(!s||!this._validateWallRepair(t,e.activePath))return!1;if(!t.sourceKey.startsWith("static:"))return!1;const[i,o]=t.sourceKey.slice(7).split("|");if("partition"===i){const i=(s.partitions||[]).find(t=>t.id===o);if(!i)return!1;const a=[i.a[0]*sd,i.a[1]*sd],n=[i.b[0]*sd,i.b[1]*sd],r=Math.hypot(a[0]-t.from[0],a[1]-t.from[1])<=2e-4*this.host._gridPitch?i.a:Math.hypot(n[0]-t.from[0],n[1]-t.from[1])<=2e-4*this.host._gridPitch?i.b:null;if(!r)return!1;(e=>{e[0]=t.to[0]/sd,e[1]=t.to[1]/sd})(r);const l=e.activePartitionIds.indexOf(o);if(l>=0){const s=l+("b"===t.endpoint?1:0);e.activePath[s]&&(e.activePath[s]=[...t.to])}return!0}return!1}_applyWallFaceBatch(){const t=this.host._wallFaceBatch,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=(t,e)=>{this.host._showToast(this.host._t(t,e)),this._roomDialogCancel()},o=t.decisions.filter(t=>t.create),a=o.map(t=>t.candidate.ring),n=s.rooms;for(let t=0;ts.id!==e&&!!B(s)&&N(a[t],B(s)));if(s)return void i("toast.room_overlap",{name:s.name||""})}if((e.rooms||[]).length+o.length>400)return void i("toast.physical_limit");if(o.some(t=>t.candidate.split&&!e.rooms.some(e=>e.id===t.candidate.split.roomId)))return void i("toast.contour_cannot_close");const r=o.map(t=>t.candidate.repair).filter(t=>!!t);if(r.length>1||r[0]&&!this._validateWallRepair(r[0],t.activePath))return void i("toast.wall_repair_changed");if(this._activePathWithRepair(t.activePath,r[0]),!o.length){if(!this._finalizeWallChainPartitions(t.activePartitionIds))return;return this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host.requestUpdate(),void this.host._showToast(this.host._t("toast.wall_chain_saved"))}const l=new Set(t.activePartitionIds),h=2e-4*this.host._gridPitch,c=o.map(t=>t.candidate.ring.map((t,e,i)=>{const o=i[(e+1)%i.length],a=s.partitions.filter(e=>{const s=Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1]);if(!(s>h))return!1;const i=(e.b[0]-e.a[0])/s,a=(e.b[1]-e.a[1])/s,n=t=>(t[0]-e.a[0])*i+(t[1]-e.a[1])*a;return Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&Wt(o,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&n(t)>=-h&&n(t)<=s+h&&n(o)>=-h&&n(o)<=s+h});return a.sort((t,e)=>Number(l.has(e.id))-Number(l.has(t.id))||Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])-Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1])||t.id.localeCompare(e.id)),a[0]?.id||""})),d=this._geometrySnapshot();if(!d)return void i("toast.geometry_unsafe");const p=()=>{this._restoreGeometryStateLocal(d),i("toast.geometry_unsafe")};if(r[0]&&!this._applyWallRepair(r[0],t))return void i("toast.wall_repair_changed");const u=o.some(t=>!!t.candidate.split),_=u?ae(s.rooms,e.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd):null,m=u&&Array.isArray(e.walls)?e.walls:null;for(const t of o){const s=t.candidate.split;if(!s)continue;const i=e.rooms.find(t=>t.id===s.roomId);if(!i)return void p();i.poly=s.mainPoly.map(t=>[t[0]/sd,t[1]/this.host._spaceH]),delete i.x,delete i.y,delete i.w,delete i.h}const g=Date.now().toString(36),f=[];if(o.forEach((t,s)=>{const i=t.area?this.host.hass.areas[t.area]?.name:"",o={id:`r${g}-${s}`,name:t.name||i||this.host._t("room.default_name"),area:t.area||null,poly:t.candidate.ring.map(t=>[t[0]/sd,t[1]/this.host._spaceH]),...c[s].some(Boolean)?{wall_ids:c[s]}:{},...t.settings?{settings:JSON.parse(JSON.stringify(t.settings))}:{}};e.rooms.push(o),f.push({room:o,decision:t})}),u){const t=this.host._normalizeWalls(_,this.host._openCuts());t.length?e.walls=t:m?.length?e.walls=m:delete e.walls}if(f.length){this.host._cfgEpoch++;const s=this.host._openCuts(),i=this.host._spaceModel();if(!i)return void p();let o=e.walls;for(const{room:e,decision:a}of f){const n=a.candidate.ring,r=this._wallSourceCmAt(n[0],t.activePath,t.activeCms);o=Ms(o,i.rooms,e.id,r,this.host._wallKeyPitch,s,sd);for(const a of pt(i.rooms,o,s,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd)){if(a.roomId!==e.id||"outer"!==a.kind)continue;const s=[(a.a[0]+a.b[0])/2,(a.a[1]+a.b[1])/2];o=gt(o,a.a,a.b,this._wallSourceCmAt(s,t.activePath,t.activeCms),this.host._wallKeyPitch,sd)}}const a=this.host._normalizeWalls(o,s);a.length?e.walls=a:delete e.walls,this.host._cfgEpoch++;const n=this.host._spaceModel();if(!n)return void p();const r=wl(e,n,e.walls,s,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:sd,allowCoincidentPartitions:!0});r.walls.length?e.walls=r.walls:delete e.walls,r.partitions.length?e.partitions=r.partitions:delete e.partitions,r.openings.length?e.openings=r.openings:delete e.openings}if(!this._commitPhysicalGeometry(this.host._t("history.wall_face_batch"),d))return;this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host._regSignature="",this.host._maybeRebuildDevices();const b=new Set(o.map(t=>t.area).filter(t=>!!t));if(b.size){const t={...this.host._layout};for(const e of this.host._devices){if(!b.has(e.area||"")||e.space!==this.host._space)continue;if(this.host._layout[e.id])continue;const s=this.host._defPos[e.id];s&&(t[e.id]={s:this.host._space,x:s.x/sd,y:s.y/sd},this.host._dirtyPos.add(e.id))}this.host._layout=t,this.host._persistLayout()}this.host._showToast(this.host._t(o.length?"toast.wall_rooms_saved":"toast.wall_chain_saved",{n:o.length}))}_commitRoom(){const t=this.host._curSpaceCfg,e=this.host._spaceModel();if(!t||!e)return;const s=this._geometrySnapshot();if(!s)return;const i=()=>{this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe"))},o=this.host._spaceH,a=!!this.host._pendingSplit,n=a?ae(e.rooms,t.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd):null,r=a&&Array.isArray(t.walls)?t.walls:null;let l;if(this.host._pendingSplit){const e=t.rooms.find(t=>t.id===this.host._pendingSplit.roomId);if(!e)return this.host._pendingSplit=null,this.host._splitSel=null,void(this.host._roomDialog=!1);e.poly=this.host._pendingSplit.mainPoly.map(t=>[t[0]/sd,t[1]/o]),delete e.x,delete e.y,delete e.w,delete e.h,l=this.host._pendingSplit.newPoly}else{if(!this.host._contourClosed)return;l=this.host._path.slice(0,-1)}const h=this.host._areaSel?this.host.hass.areas[this.host._areaSel]?.name:"",c={id:"r"+Date.now().toString(36),name:this.host._nameSel||h||this.host._t("room.default_name"),area:this.host._areaSel||null,poly:l.map(t=>[t[0]/sd,t[1]/o]),...this._roomSettingsFromDialog()?{settings:this._roomSettingsFromDialog()}:{}};if(t.rooms.push(c),a){const e=this.host._normalizeWalls(n,this.host._openCuts());e.length?t.walls=e:r?.length?t.walls=r:delete t.walls}if(!a){const e=Rh(l.length,[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,ut),s=e[0];if(null!=s){this.host._cfgEpoch++;const o=this.host._openCuts(),a=this.host._spaceModel();if(!a)return void i();let n=Ms(t.walls,a.rooms,c.id,s,this.host._wallKeyPitch,o,sd);for(const t of pt(a.rooms,n,o,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd)){if(t.roomId!==c.id||"outer"!==t.kind)continue;const s=[(t.a[0]+t.b[0])/2,(t.a[1]+t.b[1])/2],i=l.findIndex((t,e)=>{const i=l[(e+1)%l.length];return Wt(s,[t[0],t[1],i[0],i[1]])<=.02*this.host._gridPitch});i>=0&&(n=gt(n,t.a,t.b,e[i],this.host._wallKeyPitch,sd))}n=this.host._normalizeWalls(n,o),n.length?t.walls=n:delete t.walls;const r=this.host._spaceModel();if(!r)return void i();const h=wl(t,r,t.walls,o,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:sd,allowCoincidentPartitions:!0});h.walls.length?t.walls=h.walls:delete t.walls,h.partitions.length?t.partitions=h.partitions:delete t.partitions,h.openings.length?t.openings=h.openings:delete t.openings}}const d=this._commitPhysicalGeometry(this.host._t(a?"history.split_room":"history.add_room"),s);this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._pendingSplit=null,this.host._splitSel=null;const p=this.host._areaSel;if(this.host._areaSel="",this.host._nameSel="",this.host._roomDialog=!1,this.host._regSignature="",this.host._maybeRebuildDevices(),!d)return;let u=0;if(p){const t=sd,e={...this.host._layout};for(const s of this.host._devices){if(s.area!==p||s.space!==this.host._space)continue;if(u++,this.host._layout[s.id])continue;const i=this.host._defPos[s.id];i&&(e[s.id]={s:this.host._space,x:i.x/sd,y:i.y/t},this.host._dirtyPos.add(s.id))}this.host._layout=e,this.host._persistLayout()}const _=this.host._model.find(t=>t.id===this.host._space)?.rooms.length||0;this.host._showToast(p?this.host._t("toast.room_saved",{n:_,added:u}):this.host._t("toast.room_saved_no_area",{n:_}))}_cancelPath(){this.host._wallRepairDiagnostic=null,this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),this.host._roomDialog=!1,this.host._pendingSplit=null,this.host._wallFaceBatch=null,this.host._splitSel=null,this.host._mergeSel=null,this.host._mergeDialog=null,this.host._physicalSel=null,this.host._physicalDrag=null,this.host._physicalRotate=null,this._clearOpeningPlacement(!0)}_roomDialogCancel(){if(this.host._roomDialog=!1,this.host._roomEditId)return this.host._roomEditId=null,this.host._nameSel="",void(this.host._areaSel="");if(this.host._wallFaceBatch){const t=this.host._wallFaceBatch;return this.host._wallFaceBatch=null,this.host._path=t.activePath.map(t=>[...t]),this.host._wallChainSegmentCms=[...t.activeCms],this.host._activeWallChainPartitionIds=[...t.activePartitionIds],this.host._activeWallChainId||=`chain-${Date.now().toString(36)}`,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate()}if(this.host._pendingSplit)return this.host._pendingSplit=null,void(this.host._splitSel=null);this.host._undoPoint()}_openDeviceInbox(){this.host._deviceInboxReturn=null,this.host._deviceInbox=this.host._deviceInbox||{tab:"on_plan",search:"",showEntities:!1,onlyNew:!1,limit:100}}_closeMarkerDialog(){this._radarSetup.isDirty()?this._closeMarkerDialogGuarded():(this._radarSetup.reset(),function(t){if(t._markerDialog=null,!t._deviceInboxReturn)return;const e={...t._deviceInboxReturn};t._deviceInbox=e,t._deviceInboxReturn=null,e.anchor&&t.updateComplete.then(()=>requestAnimationFrame(()=>{const s=`.device-inbox-row[data-binding="${CSS.escape(e.anchor)}"]`;t.renderRoot.querySelector(s)?.scrollIntoView({block:"nearest"})}))}(this.host))}async _closeMarkerDialogGuarded(){if(!await this._radarSetup.discardIfAllowed())return await this.host.updateComplete,void this.host.renderRoot.querySelector("#marker-dialog")?.rejectClose();this._closeMarkerDialog()}_deviceInboxCandidates(t){return Yl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:t,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}})}_deviceInboxRows(){const t=this.host._deviceInbox||this.host._deviceInboxReturn,e=!!t?.showEntities,s=[this.host._haRegistry.revision,this.host._cfgRev,this.host._cfgEpoch,this.host._regSignature,this.host._newSyncKey,e?1:0,this.host._showAll?1:0,l(this.host.hass,this.host._config?.language)].join("|");if(this.host._deviceInboxMemo?.key===s)return this.host._deviceInboxMemo.rows;const i=this._deviceInboxCandidates(e),o=new Set(i.map(t=>t.value));for(const t of this.host._markers)t.binding&&"virtual"!==t.binding&&o.add(t.binding);for(const t of this.host._devices)t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&o.add(`${t.bindingKind}:${t.bindingRef}`);const a=new Map;for(const t of o)a.set(t,this.host._bindingStatus(t));const n=this.host._areaToSpace,r={};for(const[t,e]of Object.entries(this.host.hass?.areas||{}))r[t]=n[t]?.room?.name||e?.name||t;for(const[t,e]of Object.entries(n))r[t]=e.room.name||r[t]||t;const h=Object.fromEntries(this.host._model.map(t=>[t.id,t.title])),c=Object.fromEntries(Object.entries(n).map(([t,e])=>[t,e.space])),d={},p=new Map;for(const[t,e]of Object.entries(this.host._fullRegistryHass.entities||{})){const s=String(e?.platform||"").trim();if(s&&(d[`entity:${t}`]=s),s&&e?.device_id){const t=p.get(e.device_id)||new Set;t.add(s),p.set(e.device_id,t)}}for(const[t,e]of p)d[`device:${t}`]=[...e].sort().join(", ");const u={};for(const[t,e]of Object.entries(this.host._fullRegistryHass.devices||{})){const s=`device:${t}`,i=p.get(t)||new Set,o=Array.isArray(e?.identifiers?.[0])?String(e.identifiers[0][0]||""):"";o&&!d[s]&&(d[s]=o);const a=[o,...i].some(t=>this.host._excluded.has(t));"service"===e?.entry_type?u[s]="service_entry":a?u[s]="excluded_integration":"Group"===e?.model?u[s]="grouped_light":/scene/i.test(e?.model||"")?u[s]="excluded_domain":(/bridge/i.test(`${e?.model||""}${e?.name||""}`)||"myheat"===o&&e?.via_device_id)&&(u[s]="represented_by_parent")}const _=function(t){const{devices:e,markers:s,candidates:i,statuses:o,newDeviceIds:a,showHiddenOnPlan:n,areaNames:r={},spaceNames:l={},spaceByArea:h={},integrationByBinding:c={},reasonByBinding:d={}}=t,p=new Map;for(const t of e)!t.virtual&&t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&p.set(`${t.bindingKind}:${t.bindingRef}`,t);const u=new Map,_=new Map;for(const t of s)t?.binding&&"virtual"!==t.binding&&(t.removed?_.set(t.binding,t):u.set(t.binding,t));const m=new Map(i.map(t=>[t.value,t])),g=new Set([...p.keys(),...u.keys(),...m.keys(),...[..._.keys()].filter(t=>m.has(t))]),f=[];for(const t of g){const e=p.get(t),s=u.get(t),i=s?void 0:_.get(t),g=m.get(t);let b;if(i&&g)b="readd";else if(!0===s?.hidden)b="hidden";else if(e||s)b="on_plan";else{if(!g)continue;b="available"}const v=e?.bindingStatus||o.get(t)||Xl,y=s||i,$=Zl(t),w=e?.area||g?.areaId||y?.area||"",k=e?.space||y?.space||h[w]||"",x=e?.name||y?.name||g?.label||t,S=e?.model||y?.model||g?.model||"",M=!!g?.parentDeviceId&&p.has(`device:${g.parentDeviceId}`),C="readd"===b?"removed":"hidden"===b?s&&Ql(s)?d[t]||"automatic_hidden":"manual_hidden":"on_plan"===b?s?"visible_explicit":"visible_auto":d[t]||(M?"represented_by_parent":w&&k?"available":"no_bound_room"),P=!!e&&(!e.hidden||n),D="active"===v.kind,I=P&&(D||"ha_disabled"===v.kind&&n),T=[x,S,c[t],r[w],l[k],t,g?.sub].filter(Boolean).join(" ").toLocaleLowerCase();f.push({key:t,binding:t,category:b,status:v,reason:C,deviceId:e?.id,markerId:y?.id,name:x,icon:e?.icon||y?.icon||("entity"===$?"mdi:code-braces":"mdi:devices"),model:S,integration:c[t]||"",areaId:w,areaName:r[w]||"",spaceId:k,spaceName:l[k]||"",kind:$,isNew:!!e&&a.has(e.id),searchText:T,canFind:I,canEdit:!!e||!!s,canHide:"on_plan"===b&&D,canShow:"hidden"===b&&D,canAdd:("available"===b||"readd"===b)&&D})}const b=t=>"active"===t.status.kind?1:0;return f.sort((t,e)=>t.category.localeCompare(e.category)||Number(e.isNew)-Number(t.isNew)||b(t)-b(e)||t.name.localeCompare(e.name)||t.binding.localeCompare(e.binding))}({devices:this.host._devices,markers:this.host._markers,candidates:i,statuses:a,newDeviceIds:this.host._newIds,showHiddenOnPlan:this.host._showAll,areaNames:r,spaceNames:h,spaceByArea:c,integrationByBinding:d,reasonByBinding:u});return this.host._deviceInboxMemo={key:s,rows:_},_}_deviceForInboxRow(t){const e=t.deviceId?this.host._devices.find(e=>e.id===t.deviceId):null;if(e)return e;const s=t.markerId?this.host._markers.find(e=>e.id===t.markerId):null;return!s||s.removed?null:{id:s.id,name:t.name,model:t.model,area:t.areaId,space:t.spaceId||this.host._space,hidden:!0===s.hidden||"ha_disabled"===t.status.kind,userHidden:!0===s.hidden,bindingStatus:t.status,icon:t.icon,entities:"active"===t.status.kind?t.status.enabledEntityIds:[],allEntities:t.status.allEntityIds,primary:"active"===t.status.kind?t.status.enabledEntityIds[0]:void 0,marker:s,bindingKind:t.kind,bindingRef:t.binding.slice(t.binding.indexOf(":")+1),pdfs:s.pdfs||[]}}_openInboxMarker(t,e=!1){const s=this.host._deviceInbox;if(s){if(this.host._deviceInboxReturn={...s,anchor:t.key},this.host._deviceInbox=null,!e){const e=this._deviceForInboxRow(t);return void(e?this._openMarkerDialog(e):this._closeMarkerDialog())}this._openMarkerDialog(),this.host._markerDialog?this.host._markerDialog={...this.host._markerDialog,bindingMode:"ha",binding:t.binding,bindingOpen:!1,showEntities:"entity"===t.kind,name:""}:this._closeMarkerDialog()}}async _setInboxHidden(t,e){const s=this.host._deviceInbox,i=this.host._serverCfg;if(!s||!i||s.busy||"active"!==t.status.kind)return;const o=i.markers||[],a=o.find(e=>!e.removed&&e.binding===t.binding);if(!e&&!a)return;const n=a?.id||Cs(t.binding,t.markerId,()=>`m_${Date.now().toString(36)}`),r=a?{...a,hidden:e}:{id:n,binding:t.binding,hidden:!0};i.markers=[...o.filter(e=>e.id!==n&&(e.binding!==t.binding||!0===e.removed)),r],this.host._deviceInbox={...s,busy:t.key,anchor:t.key};try{await this._saveConfigNow(),this.host._regSignature="",this.host._deviceInboxMemo=null,this.host._maybeRebuildDevices(),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("device_inbox.saved"))}catch(t){this.host._serverCfg===i&&(i.markers=o),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_findInboxDevice(t){if(!t.canFind)return;const e=this._deviceForInboxRow(t);if(!e)return;if(this.host._deviceInbox=null,e.space&&e.space!==this.host._space){if(!this.host._commitSpace(e.space))return;this.host._restoreZoom()}const s=()=>{const t=this.host._devices.find(t=>t.id===e.id)||e,s=this.host._pos(t);this.host._applyView(this.host._zoom,s.x,s.y),this.host._selId=t.id,this.host.requestUpdate(),window.setTimeout(()=>{this.host._selId===t.id&&(this.host._selId=null,this.host.requestUpdate())},1500)};requestAnimationFrame(()=>requestAnimationFrame(s))}_openMarkerDialog(t){if(this.host._vacAllCamerasFor=null,this.host._vacAllCameraCache=null,t&&this.host._ackNewDevice(t.id),this.host._norm)if(t){const e=t.marker,s=Object.prototype.hasOwnProperty.call(e||{},"is_light"),i=Object.prototype.hasOwnProperty.call(e||{},"light_entity"),o=Object.prototype.hasOwnProperty.call(e||{},"glow_color"),a=Object.prototype.hasOwnProperty.call(e||{},"value_badge"),n=Object.prototype.hasOwnProperty.call(e||{},"value_source"),r=Object.prototype.hasOwnProperty.call(e||{},"tap_action"),l=Object.prototype.hasOwnProperty.call(e||{},"toggle_entity"),h=Ps(e?.glow_color),c=this.host._devicePresentation(t,!0).valueBadge,d=Ds(this.host._planHass,t,this.host._devices),p=Is(this.host._planHass,t,d),u=nh(t,this.host._fullRegistryHass),_=this.host._spaceModelById(t.space)||this.host._spaceModel(),m=this.host._pos(t),g=_?lh(t,_,[m.x,m.y],this.host._fullRegistryHass):null;this.host._markerDialog={devId:t.id,name:t.name,binding:"virtual"===t.bindingKind?"virtual":t.bindingKind+":"+t.bindingRef,bindingMode:"virtual"===t.bindingKind?"virtual":"ha",bindingOpen:!1,showEntities:"entity"===t.bindingKind&&!!this.host._fullRegistryHass.entities[t.bindingRef||""]?.device_id,bindingFilter:"",icon:t.marker?.icon||"",autoIcon:t.icon||"",display:Rs(t.marker?.display),rippleColor:x(t.marker?.ripple_color,""),rippleSize:Number(t.marker?.ripple_size)>0?Number(t.marker.ripple_size):1.5,size:Number(t.marker?.size)>0?Number(t.marker.size):1,angle:Number(t.marker?.angle)||0,tapAction:zs(t.marker?.tap_action,t.primary?.split(".")[0]),tapActionTouched:!1,originalHasTapAction:r,originalTapAction:t.marker?.tap_action,tapHintAnnouncement:"",toggleEntity:e?.toggle_entity||"",toggleEntityTouched:!1,originalHasToggleEntity:l,originalToggleEntity:e?.toggle_entity,tapTarget:t.marker?.tap_target||"",tapConfirm:!0===t.marker?.tap_confirm,runFilter:"",controls:Ts(t.marker?.binding,t.marker?.controls,t.entities),controlsFilter:"",lightRole:!0===e?.is_light?"always":!1===e?.is_light?"never":"auto",lightRoleTouched:!1,originalHasIsLight:s,originalIsLight:e?.is_light,lightEntity:e?.light_entity||"",lightEntityTouched:!1,originalHasLightEntity:i,originalLightEntity:e?.light_entity,glowMode:null!=h?.bri?"fixed":h?"color":"auto",glowColor:h?.c||this.host._fillColors.glow_light.c,glowBrightness:Math.max(1,Math.round(100*(h?.bri??1))),glowColorDrafted:!!h,glowBrightnessDrafted:null!=h?.bri,glowTouched:!1,originalHasGlowColor:o&&(!!h||null===e?.glow_color),originalGlowColor:h||(null===e?.glow_color?null:void 0),valueBadgeEnabled:a?!0===e?.value_badge?.enabled:!!c,valueBadgeSource:e?.value_badge?.source||c?.source||p,valueBadgePosition:e?.value_badge?.position||c?.position||"right",valueBadgeTouched:!1,originalHasValueBadge:a,originalValueBadge:e?.value_badge,valueSource:e?.value_source||null,valueSourceTouched:!1,originalHasValueSource:n,originalValueSource:e?.value_source,useClimateTemp:!0===t.marker?.use_climate_temp,glowRadius:Number(t.marker?.glow_radius_cm)>0?String(this.host._imperial?Math.round(Number(t.marker.glow_radius_cm)/30.48*10)/10:Math.round(Number(t.marker.glow_radius_cm))/100):"",model:t.model||"",link:t.link||"",description:t.description||"",pdfs:[...t.pdfs||[]],room:t.marker?.room_id?t.space+"#@"+t.marker.room_id:t.space&&t.area?t.space+"#"+t.area:"",roomTouched:!1,radar:g,radarEligible:u.eligible,radarTouched:!1,radarRemove:!1,hideFromPlan:!0===t.marker?.hidden,busy:!1}}else this.host._markerDialog={name:"",binding:"virtual",bindingMode:"virtual",bindingOpen:!1,showEntities:!1,bindingFilter:"",icon:"",autoIcon:"",display:"badge",rippleColor:"",rippleSize:1.5,size:1,angle:0,tapAction:"info",tapActionTouched:!1,originalHasTapAction:!1,originalTapAction:void 0,tapHintAnnouncement:"",toggleEntity:"",toggleEntityTouched:!1,originalHasToggleEntity:!1,originalToggleEntity:void 0,tapTarget:"",tapConfirm:!1,runFilter:"",controls:[],controlsFilter:"",lightRole:"auto",lightRoleTouched:!1,originalHasIsLight:!1,originalIsLight:void 0,lightEntity:"",lightEntityTouched:!1,originalHasLightEntity:!1,originalLightEntity:void 0,glowMode:"auto",glowColor:this.host._fillColors.glow_light.c,glowBrightness:100,glowColorDrafted:!1,glowBrightnessDrafted:!1,glowTouched:!1,originalHasGlowColor:!1,originalGlowColor:void 0,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgePosition:"right",valueBadgeTouched:!1,originalHasValueBadge:!1,originalValueBadge:void 0,valueSource:null,valueSourceTouched:!1,originalHasValueSource:!1,originalValueSource:void 0,useClimateTemp:!1,glowRadius:"",model:"",link:"",description:"",pdfs:[],room:"",roomTouched:!1,radar:null,radarEligible:!1,radarTouched:!1,radarRemove:!1,hideFromPlan:!1,busy:!1,uploadId:"up_"+Date.now().toString(36)+Math.random().toString(36).slice(2,6)};else this.host._showToast(this.host._t("toast.marker_needs_server"))}_runCandidates(){const t=[];for(const e of As)for(const[s,i]of Object.entries(this.host.hass.states))s.startsWith(e+".")&&this.host._planEntityAvailable(s)&&t.push({value:s,label:i?.attributes?.friendly_name||s,sub:this.host._t("run."+e)});return t.sort((t,e)=>t.sub.localeCompare(e.sub)||t.label.localeCompare(e.label))}_bindingCandidates(){const t=Yl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:!!this.host._markerDialog?.showEntities,currentBinding:this.host._markerDialog?.binding,currentDeviceId:this.host._markerDialog?.devId,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}}),e=(this.host._markerDialog?.bindingFilter||"").toLowerCase().trim(),s=e?t.filter(t=>(t.label+" "+t.sub+" "+t.value).toLowerCase().includes(e)):t;return s.sort((t,e)=>t.label.localeCompare(e.label)),s.slice(0,200)}_backupErrorText(t){const e=t?.code??t?.error;if("string"==typeof e){const t=`backup.error.${e}`,s=this.host._t(t);if(s!==t)return s}return this.host._errText(t)}async _pickMarkerFiles(t){const e=t.target,s=e.files?[...e.files]:[];if(e.value="",!s.length||!this.host._markerDialog)return;const i=this.host._markerDialog.uploadId||this.host._markerDialog.devId||"new",o=[];for(const t of s)try{const e=new FormData;e.append("marker_id",i),e.append("file",t,t.name);const s=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth("/api/houseplan/upload",{method:"POST",body:e}):await fetch("/api/houseplan/upload",{method:"POST",body:e,headers:this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}),a=await s.json().catch(()=>({}));if(!s.ok||a.error){const t={too_large:this.host._t("err.too_large",{mb:a.max_mb||50}),bad_ext:this.host._t("err.bad_ext"),unauthorized:this.host._t("err.unauthorized")};throw new Error(t[a.error]||a.error||"HTTP "+s.status)}o.push({name:a.name||t.name,url:a.url})}catch(e){this.host._showToast(this.host._t("toast.file_failed",{name:t.name,err:this.host._errText(e)}))}o.length&&this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:[...this.host._markerDialog.pdfs,...o]},this.host._showToast(this.host._t("toast.files_attached",{n:o.length})))}_removeMarkerPdf(t){this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:this.host._markerDialog.pdfs.filter(e=>e.url!==t)})}_markerLightFields(t){const e={};if(t.lightRoleTouched?"always"===t.lightRole?e.is_light=!0:"never"===t.lightRole&&(e.is_light=!1):t.originalHasIsLight&&(e.is_light=t.originalIsLight??null),t.lightEntityTouched?t.lightEntity&&(e.light_entity=t.lightEntity):t.originalHasLightEntity&&(e.light_entity=t.originalLightEntity??null),t.glowTouched){if("auto"!==t.glowMode){const s={c:x(t.glowColor,this.host._fillColors.glow_light.c)};"fixed"===t.glowMode&&(s.bri=Math.max(.01,Math.min(1,Math.round(t.glowBrightness)/100))),e.glow_color=s}}else t.originalHasGlowColor&&(e.glow_color=t.originalGlowColor??null);return e}_markerTapActionFields(t){return t.tapActionTouched?{tap_action:t.tapAction||null}:t.originalHasTapAction?{tap_action:t.originalTapAction??null}:{}}_markerToggleEntityFields(t){return(e={touched:t.toggleEntityTouched,originalHas:t.originalHasToggleEntity,original:t.originalToggleEntity,value:t.toggleEntity}).touched?e.value?{toggle_entity:e.value}:{}:e.originalHas?{toggle_entity:e.original??null}:{};var e}async _saveMarker(){const t=this.host._markerDialog;if(!t||t.busy)return;const e=this._effectiveMarkerTapAction(t);if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return;if("virtual"===t.binding&&!t.name.trim())return void this.host._showToast(this.host._t("toast.virtual_name_required"));if("run"===e&&!t.tapTarget)return void this.host._showToast(this.host._t("toast.run_target_required"));if(t.valueBadgeTouched&&t.valueBadgeEnabled&&!t.valueBadgeSource)return void this.host._showToast(this.host._t("toast.value_badge_source_required"));if("ha"===t.bindingMode){const e=this.host._bindingStatus(t.binding),s=t.devId?this.host._markers.find(e=>e.id===t.devId):null,i=!s||s.binding!==t.binding;if("active"!==e.kind&&i)return void this.host._showToast(this.host._t("ha_disabled"===e.kind?"toast.ha_disabled_add":"toast.ha_binding_unverified"));if("ha_disabled"===e.kind&&!0===s?.hidden&&!t.hideFromPlan)return this.host._markerDialog={...t,hideFromPlan:!0},void this.host._showToast(this.host._t("entity"===e.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device"))}const s=this.host._serverCfg;if(!s)return;const i=this.host._cfgRev,o=Ft(s);let a=JSON.parse(JSON.stringify(s));const n=a.markers||[],r=Cs(t.binding,t.devId,()=>"v_"+Date.now().toString(36)),l=t.devId,h=l?this.host._devices.find(t=>t.id===l):null,c=l?n.find(t=>t.id===l):null,d=!!c&&("string"==typeof c.area&&c.area.length>0||null===c.area&&!!c.space&&!!c.room_id),p="virtual"===t.binding||t.roomTouched||d,u="virtual"===t.binding||t.roomTouched?Fs(t.room):null;let _=d&&!t.roomTouched?c?.space||null:u?.space||null;const m=d&&!t.roomTouched?c?.area||null:u?.area||null,g=d&&!t.roomTouched?c?.room_id||null:u?.roomId||null,f=_||h?.space||null,b=f?this.host._spaceModelById(f):this.host._spaceModel();if(!b)return;const v=b.id;"virtual"!==t.binding||_||(_=v);let y={};if(t.radarTouched){if(t.radarRemove)y={radar:null};else if(t.radar){const e=dh(t.radar,b.cellCm||5);if(!e)return void this.host._showToast(this.host._t("radar.invalid"));y={radar:e}}}else c&&Object.prototype.hasOwnProperty.call(c,"radar")&&(y={radar:c.radar});this.host._markerDialog={...t,busy:!0};let $=null,w=!1;try{const c="virtual"===t.binding?[]:n.filter(e=>e.removed&&e.binding===t.binding).map(t=>t.id),d=c.length>0,u=Ts(t.binding,t.controls,this.host._bindingEntities(t.binding)),f=n.find(t=>t.id===r||t.id===l)?.vacuum||null,k={id:r,vacuum:f,...y,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle?t.angle:null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===e&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:u.length?u:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:!!t.hideFromPlan};p&&(k.space=_,k.area=m,k.room_id=g);const x=h?.marker?.room_id??null,S=t.roomTouched&&null!=h&&(h.space!==_||h.area!==m||x!==g);let M=!1;const C=t.uploadId||l;if(C&&C!==r&&k.pdfs?.length)try{const t=await this.host.hass.callWS({type:"houseplan/files/migrate",from_id:C,to_id:r}),e=t?.mapping||{};k.pdfs=Ns(k.pdfs,C,r,e),M=Object.keys(e).length>0}catch(t){this.host._showToast(this.host._t("toast.files_migrate_failed",{err:this.host._errText(t)}))}a.markers=n,l&&l!==r&&(a.markers=Es(a.markers,l,r)),l&&l!==r&&"derived_marker_state"===k.value_badge?.source?.kind&&k.value_badge.source.ref===`marker:${l}`&&(k.value_badge.source={kind:"derived_marker_state",ref:`marker:${r}`}),l&&l!==r&&"derived_marker_state"===k.value_source?.kind&&k.value_source.ref===`marker:${l}`&&(k.value_source={kind:"derived_marker_state",ref:`marker:${r}`}),a.markers=a.markers.filter(t=>t.id!==r&&t.id!==l&&("virtual"===k.binding||t.binding!==k.binding)),a.markers.push(k);const P=new Set(c);l&&l!==r&&P.add(l),P.delete(r),P.size&&a.settings?.marker_area_snapshot&&(a.settings={...a.settings,marker_area_snapshot:Hs(a.settings.marker_area_snapshot,P)});let D=null;const I=l?this.host._layout[l]:null,T=I?{s:I.s||h?.space||this.host._space,x:I.x,y:I.y}:l&&h&&this.host._defPos[l]?this.host._normPos(h.space,this.host._defPos[l].x,this.host._defPos[l].y):null;if(!d&&T&&T.s===v)r===l&&this.host._layout[r]&&!S||(D={s:T.s,x:T.x,y:T.y});else if(d||!this.host._layout[r]||S){let t=b.vb[0]+b.vb[2]/2,e=b.vb[1]+b.vb[3]/2;const s=g?b.rooms.find(t=>t.id===g):m?b.rooms.find(t=>t.area===m):void 0;s&&([t,e]=this.host._roomCenter(s)),D=this.host._normPos(v,t,e)}if(this.host._serverCfg!==s||this.host._cfgRev!==i||Ft(s)!==o)return this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),void this.host._showToast(this.host._t("toast.conflict"));if(a=this._prepareConfigCandidate(a),$=this.host._adoption.beginOptimistic(s,a),this.host._serverCfg=a,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate(),this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.cancel(),await this._saveConfigNow($),w=!0,D){const t=Os(D);this.host._layout={...this.host._layout,[r]:t},this.host._noteLayoutRev(await this.host.hass.callWS({type:"houseplan/layout/update",device_id:r,pos:t}))}const z=new Set(c);l&&l!==r&&z.add(l),z.delete(r);for(const t of z)delete this.host._layout[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{});M&&C&&await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:C}).catch(()=>{}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_saved"))}catch(t){!w&&$&&(this.host._rollbackOptimistic($),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteMarker(){const t=this.host._markerDialog;if(!t||t.busy||!t.devId)return;const e=t.devId?this.host._devices.find(e=>e.id===t.devId):null,s=this.host._markers.find(e=>e.id===t.devId);if(!e&&!s)return;const i=e?"virtual"===e.bindingKind?"virtual":e.bindingKind&&e.bindingRef?`${e.bindingKind}:${e.bindingRef}`:"":s.binding;if(!i)return;const o=t.name||this.host._t("device.fallback"),a=t.devId,n=await this.host._confirmDanger({key:"remove-marker",kind:"destructive",title:this.host._t("confirm.remove_marker_title"),message:this.host._t("confirm.remove_marker_body"),objectName:o,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._markerDialog;if(!n||!r||r.busy||r.devId!==a)return;const l=this.host._devices.find(t=>t.id===a),h=this.host._markers.find(t=>t.id===a);if(!l&&!h)return;const c=this.host._serverCfg;if(!c)return;c.markers=c.markers||[];const d=c.markers,p=l?"virtual"===l.bindingKind?"virtual":l.bindingKind&&l.bindingRef?`${l.bindingKind}:${l.bindingRef}`:"":h.binding;if(!p||p!==i)return;const u=Ls(c.markers,a,p,"virtual"===p);c.markers=Bs(u.markers,u.cleanupIds);const _=u.cleanupIds;_.size&&c.settings?.marker_area_snapshot&&(c.settings={...c.settings,marker_area_snapshot:Hs(c.settings.marker_area_snapshot,_)}),this.host._markerDialog={...r,busy:!0};try{await this._saveConfigNow();for(const t of _){delete this.host._layout[t],delete this.host._defPos[t],this.host._dirtyPos.delete(t),this.host._sentPos.delete(t);const e=this.host._activityRt.get(t);e&&clearTimeout(e.timer),this.host._activityRt.delete(t),this.host._vacRt.delete(t),delete this.host._vacSrvTrails[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:t}).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/trail/delete",marker_id:t}).catch(()=>{})}this.host._deviceInboxReturn&&(this.host._deviceInboxReturn={...this.host._deviceInboxReturn,tab:"readd",anchor:p}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._infoCard?.id===a&&this.host._closeInfoCard(),this.host._selId===a&&(this.host._selId=null),this.host._drag?.id===a&&(this.host._drag=null),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_removed"))}catch(t){this.host._serverCfg===c&&(c.markers=d),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_openSpaceDialog(t,e){if(this.host._serverStorage&&this.host._serverCfg)if("edit"===t){const s=this.host._serverCfg.spaces.find(t=>t.id===e);if(!s)return;const i=Ws(s),o=s.settings?.custom_fill&&"object"==typeof s.settings.custom_fill?js(s.settings.custom_fill):null,a="none"===i.fill?{...o||Gs,a:0}:o;this.host._spaceDialog={mode:t,spaceId:e,title:s.title,planUrl:s.plan_url||null,planFile:null,source:s.plan_url?"file":"draw",showBorders:i.showBorders,showNames:i.showNames,zeroWallStyle:Us(s),displayTouched:!0,hideDecor:i.hideDecor,hideOpenings:i.hideOpenings,roomColor:i.color,roomOpacity:i.opacity,fillMode:"none"===i.fill?"custom":i.fill,customFill:a,glowEnabled:i.glow,bgColor:i.bgColor,bgMode:"static"===s.settings?.bg_mode||"daynight"===s.settings?.bg_mode?s.settings.bg_mode:null,northDeg:ce({},s.settings),sunRays:"boolean"==typeof s.settings?.sun_rays?s.settings.sun_rays:null,tempMin:i.tempMin,tempMax:i.tempMax,showLqi:i.showLqi??this.host._config?.show_signal??!0,cardFontScale:i.cardFontScale,labelTemp:i.labelTemp,labelHum:i.labelHum,labelLqi:i.labelLqi,labelLight:i.labelLight,cellCm:Number(s.cell_cm)>0?Number(s.cell_cm):5,cellCmInput:qs(Number(s.cell_cm)>0?Number(s.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1}}else this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...Zs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Ys,roomOpacity:Js,fillMode:"custom",customFill:{...Gs,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Vs,tempMax:Ks,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Xs(this.host._imperial),cellCmInput:qs(Xs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1};else this.host._showToast(this.host._t("toast.integration_missing"))}async _pickPlanFile(t){const e=t.target,s=e.files?.[0];if(!s||!this.host._spaceDialog)return;e.value="",this._decorAssetGuardReplace=null;const i=await bo(s);if("reject"===i.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===i.kind)return void(this.host._backdropGuard=i.state);const o=await vo(s,i.ext,s.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:o})}_renderBackdropGuard(){const t=this._decorAssetGuardReplace;return null!==t?yo(this.host,()=>{},()=>{this.host._backdropGuard=null,this._decorAssetGuardReplace=null},this.host.hass,(e,s)=>this._uploadDecorImage(e,s,t),(this.host._backdropGuard?.file.size||0)<=2097152)??d:yo(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??d}_useServerPlan(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let e=0;e<40;e++){const e=this.host._display(t);if(e){const s=await new Promise(t=>{const s=new Image;s.onload=()=>t(s.naturalWidth&&s.naturalHeight?s.naturalWidth/s.naturalHeight:0),s.onerror=()=>t(0),s.src=e}),i=this.host._spaceDialog;return i&&i.planUrl===t&&Number.isFinite(s)&&s>0?(this.host._spaceDialog={...i,savedAspect:s},s):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const e=this.host._spaceDialog,s=e?.saved?.find(e=>e.name===t);if(!e||!s||s.used_by.length||s.url===e.planUrl)return;const i=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),o=this.host._spaceDialog,a=o?.saved?.find(e=>e.name===t);if(i&&o&&a&&a.url===s.url&&a.modified===s.modified&&!a.used_by.length&&a.url!==o.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const e=this.host._spaceDialog;e?.saved&&(this.host._spaceDialog={...e,saved:e.saved.filter(e=>e.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return p`
    ${this.host._t("space.loading")}
    `;const e=t.saved||[];if(!e.length)return p`
    ${this.host._t("space.no_saved")}
    `;return p`
    +
    `:p``}_openingAt(t){if(!this.host._openingsR.length)return null;const e=this.host._openingsR.flatMap(e=>{const s=e.angle*Math.PI/180,i=t[0]-e.rx,o=t[1]-e.ry,a=i*Math.cos(s)+o*Math.sin(s);return Math.abs(a)>e.rlen/2+y(12,this.host._cellCm)?[]:[{o:e,localY:-i*Math.sin(s)+o*Math.cos(s)}]});if(!e.length)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i).value;return e.find(({o:t,localY:e})=>{const s="gate"===t.type?!t.flip_v:t.flip_v,i=t.partitionHost||this.host._spaceWalls.length||"gate"===t.type?this.host._openingFace(t,o,!!s):{ox:0,oy:0,cm:0,side:-1},a=ps({type:t.type,length:t.rlen,angle:t.angle,amount:this.host._openingAmt(t),flipH:!!t.flip_h,flipV:!!t.flip_v,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:i});return Math.abs(e)<=a.hitHalf})?.o||null}_resolveOpeningPlacement(t){const e=this.host._openingPreset;if("opening"!==this.host._tool||!e)return null;const s=this.host._spaceModel();if(!s)return null;const i=this.host._openCuts(),o=this.host._openingWallIndexFor(s,i),a=`${o.key}|partitions:${this.host._cfgEpoch}`;this.host._openingPlacementIntervalsCache&&this.host._openingPlacementIntervalsCache.key===a||(this.host._openingPlacementIntervalsCache={key:a,value:[...pt(s.rooms,this.host._spaceWalls,i,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id),...us(s.partitions,this.host._cellCm,this.host._gridPitch)]}),this.host._openingDimensionContextCache&&this.host._openingDimensionContextCache.key===a||(this.host._openingDimensionContextCache={key:a,value:Hc({rooms:s.rooms,walls:this.host._spaceWalls,openCuts:i,partitions:s.partitions,roomOpenings:this.host._roomWallOpeningInputs(),partitionCuts:this._partitionOpeningCuts(s),pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:id,epsilon:2e-4*this.host._gridPitch})});const n=_s({pointer:[t[0],t[1]],preset:e,geometryRevision:this.host._cfgEpoch,renderedLength:this.host._cmToUnits(e.lengthCm),intervals:this.host._openingPlacementIntervalsCache.value,baseTolerance:1.5*this.host._gridPitch,bodyPointerPadding:this._cssPxToRender("touch"===this.host._pointerModality.modality||"pen"===this.host._pointerModality.modality?10:6),gridStep:this.host._gridPitch});this.host._openingJambBlockCm=n.jambBlockedTarget?n.jambBlockedTarget.physicalHalfWidth/this.host._gridPitch*this.host._cellCm:null;const r=n.candidate;if(!r)return null;const l="gate"===r.type?!r.flipV:r.flipV;let h;if(r.host){const t=ct({id:"preview",type:r.type,x:r.x/id,y:r.y/id,angle:r.angle,length:r.renderedLength/id,host:r.host},s.partitions,id,this.host._cellCm,this.host._gridPitch).resolved;h=t?ms(t,l):{ox:0,oy:0,cm:0,side:-1}}else h=gs(o.value,{x:r.x,y:r.y,angle:r.angle,length:r.renderedLength,flip_v:l});const c="mi"===this.host.hass?.config?.unit_system?.length,d=qc(r,this.host._openingDimensionContextCache.value).map(t=>({x:t.label[0],y:t.label[1],text:Ot(t.distance/this.host._gridPitch*this.host._cellCm,c),dimension:t}));return{...r,face:h,measure:{labels:d,guide:r.measure.guide}}}_activateOpeningPlacement(t){this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingPreset=fs(t,++this.host._openingPresetRevision),this.host._openingHoverCandidate=null,this.host._cursorPt=null)}_clearOpeningPlacement(t){this.host._openingHoverCandidate=null,this.host._openingJambBlockCm=null,t&&(this.host._openingPreset=null,this.host._openingRebindId=null)}_openingClick(t){const e=this.host._spaceModel();if(!e)return;const s=this.host._openingRebindId?null:this._openingAt(t);if(s)return void this._editOpening(s);const i=this.host._openingPreset;if(!i)return;const o=this.host._openingHoverCandidate,a=o&&bs(o,[t[0],t[1]],i.revision,this.host._cfgEpoch)?o:this._resolveOpeningPlacement(t);if(!a){if(null!=this.host._openingJambBlockCm)return void this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(this.host._openingJambBlockCm,this.host._imperial)}));const s=1.5*this.host._gridPitch,i=lt(t,e.rooms,s);return i&&vs(i.x,i.y,i.angle,this.host._openCuts(),s)?void this.host._showToast(this.host._t("toast.opening_on_zero_wall")):void this.host._showToast(this.host._t("toast.opening_no_wall"))}const n=this.host._openingRebindId?this.host._curSpaceCfg?.openings?.find(t=>t.id===this.host._openingRebindId):null;this.host._openingDialog={...n?{id:n.id,type:n.type,lengthCm:Math.round(n.length*id/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:n.contact||"",lock:n.lock||"",invert:!!n.invert,flipH:!!n.flip_h,flipV:!!n.flip_v}:{type:a.type,lengthCm:a.lengthCm,contact:"",lock:"",invert:!1,flipH:a.flipH,flipV:a.flipV},...a.host?{host:a.host}:{},x:a.x,y:a.y,angle:a.angle},this.host._openingRebindId=null,this.host._openingHoverCandidate=null,this.host._cursorPt=null}_editOpening(t){this.host._openingDialog={id:t.id,type:t.type,lengthCm:Math.round(t.rlen/this.host._gridPitch*this.host._cellCm),lengthTouched:!1,contact:t.contact||"",lock:t.lock||"",invert:!!t.invert,flipH:!!t.flip_h,flipV:!!t.flip_v,..."partition"===t.host?.kind?{host:{...t.host}}:{},x:t.rx,y:t.ry,angle:t.angle}}_opPointerDown(t,e){if("plan"===this.host._mode&&this.host._spaceModel()&&"resize"!==this.host._tool){t.preventDefault(),t.stopPropagation();try{ad(t)}catch{}this.host._opDrag={id:e.id,moved:!1,sx:t.clientX,sy:t.clientY,dirty:!1,before:this._geometrySnapshot()}}}_opPointerMove(t,e){jo(this.host,"opening",()=>this._opPointerMoveNow(t,e))}_opPointerMoveNow(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;if(Math.abs(t.clientX-this.host._opDrag.sx)+Math.abs(t.clientY-this.host._opDrag.sy)<=3)return;const s=this.host._spaceModel();if(!s)return;const i=this._svgPoint(t),o=this.host._curSpaceCfg,a=o?.openings?.find(t=>t.id===e.id);if(!a)return;if("partition"===a.host?.kind){const t=s.partitions.find(t=>t.id===a.host.id);if(!t)return;const e=t.b[0]-t.a[0],o=t.b[1]-t.a[1],n=Math.hypot(e,o);if(!(n>1e-9))return;const r=e/n,l=o/n;if(Math.abs((i[0]-t.a[0])*l-(i[1]-t.a[1])*r)>4*this.host._gridPitch)return;const h=a.length*id/2+mt(t,this.host._cellCm,this.host._gridPitch);let c=(i[0]-t.a[0])*r+(i[1]-t.a[1])*l;if(c=Math.round(c/this.host._gridPitch)*this.host._gridPitch,c=Math.max(h,Math.min(n-h,c)),n<2*h-1e-9)return;const d=c/n,p=(t.a[0]+r*c)/id,u=(t.a[1]+l*c)/this.host._spaceH;let _=180*Math.atan2(o,e)/Math.PI;_>=90?_-=180:_<-90&&(_+=180);const m=a.host.t!==d||a.x!==p||a.y!==u||a.angle!==_;return this.host._opDrag.moved=!0,m&&(this.host._opDrag.dirty=!0),a.host={...a.host,t:d},a.x=p,a.y=u,a.angle=_,this.host._opMeasure=null,m&&this.host._cfgEpoch++,void this.host.requestUpdate()}const n=lt(i,s.rooms,4*this.host._gridPitch);if(!n)return;this.host._opDrag.moved=!0;const r=this._opRuler(n,a.length*id);this.host._opMeasure=r.measure;const l=r.x/id,h=r.y/this.host._spaceH,c=a.x!==l||a.y!==h||a.angle!==n.angle;if(c&&(this.host._opDrag.dirty=!0),a.x=l,a.y=h,a.angle=n.angle,Number(this.host._serverCfg?.model_version||0)>=9){const t=On(a,o?.wall_segments||[]);t?a.host=t:delete a.host}c&&this.host._cfgEpoch++,this.host.requestUpdate()}_opRuler(t,e){const s=this.host._spaceModel()?.rooms||[],i=this.host._gridPitch/2;let o=t.x,a=t.y,n=ys([o,a],t.angle,e,s,i);if(n&&n.centered&&(o!==n.wallCenter[0]||a!==n.wallCenter[1]))[o,a]=n.wallCenter,n=ys([o,a],t.angle,e,s,i);else if(n){const[r,l]=n.wallA,[h,c]=n.wallB,d=h-r,p=c-l,u=Math.hypot(d,p);if(u>0){const h=this.host._gridPitch,c=Math.min(e/2,u/2);let _=Math.round(((o-r)*d+(a-l)*p)/u/h)*h;_=Math.max(c,Math.min(u-c,_)),o=r+_/u*d,a=l+_/u*p,n=ys([o,a],t.angle,e,s,i)||n}}if(!n)return{x:o,y:a,angle:t.angle,measure:null};const r="mi"===this.host.hass?.config?.unit_system?.length,l=(t,e)=>({x:e[0],y:e[1],text:Ot(t/this.host._gridPitch*this.host._cellCm,r)});return{x:o,y:a,angle:t.angle,measure:{labels:[l(n.sideA,n.midA),l(n.sideB,n.midB)],guide:n.centered?{x:n.wallCenter[0],y:n.wallCenter[1],angle:t.angle}:null}}}_opPointerUp(t,e){if(!this.host._opDrag||this.host._opDrag.id!==e.id)return;Go(this.host,"opening");const s=this.host._opDrag,i=s.moved;this.host._opMeasure=null,i&&s.dirty&&this._commitPhysicalGeometry(this.host._t("history.move_opening"),s.before);const o=()=>{this.host._opDrag=null,this.host.requestUpdate()};i?window.setTimeout(o,0):o()}_opClick(t,e){"plan"===this.host._mode&&"resize"===this.host._tool||(t.stopPropagation(),this.host._opDrag?.moved||"plan"===this.host._mode&&this._editOpening(e))}_saveOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=this._geometrySnapshot(),o=this.host._spaceH,a=(e.openings||[]).find(e=>e.id===t.id),n={...a||{},id:t.id||"o"+Date.now().toString(36),type:t.type,x:t.x/id,y:t.y/o,angle:t.angle,length:a&&!t.lengthTouched?a.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/id,...t.host?{host:{...t.host}}:{}};if("partition"===n.host?.kind){const t=$s(a,n)?bt(n,s.partitions,id,this.host._cellCm,this.host._gridPitch):ct(n,s.partitions,id,this.host._cellCm,this.host._gridPitch);if(!t.resolved){const e=s.partitions.find(t=>t.id===n.host.id);if("does-not-fit-jamb"===t.reason&&e){const t=mt(e,this.host._cellCm,this.host._gridPitch);this.host._showToast(this.host._t("opening.partition_jamb_margin",{distance:Ot(t/this.host._gridPitch*this.host._cellCm,this.host._imperial)}))}else this.host._showToast(this.host._t("opening.partition_orphan"));return}const i=(e.openings||[]).flatMap(t=>{if(!t.host||t.id===n.id)return[];const e=ct(t,s.partitions,id,this.host._cellCm,this.host._gridPitch).resolved;return e?[e]:[]});if(ws(t.resolved,i))return void this.host._showToast(this.host._t("toast.opening_no_wall"));Object.assign(n,dt(n,t.resolved,id))}else if(Number(this.host._serverCfg?.model_version||0)>=9){const t=On(n,e.wall_segments||[]);if(!t)return void this.host._showToast(this.host._t("toast.opening_no_wall"));n.host=t}else delete n.host;"passage"===t.type?(delete n.contact,delete n.lock,delete n.invert,delete n.flip_h,delete n.flip_v):(n.contact=t.contact||null,n.lock=("door"===t.type||"gate"===t.type)&&t.lock||null,n.invert=t.invert||void 0,n.flip_h="gate"!==t.type&&t.flipH||void 0,n.flip_v=t.flipV||void 0),e.openings=e.openings||[];const r=e.openings.findIndex(t=>t.id===n.id);r>=0?e.openings[r]=n:e.openings.push(n),this._commitPhysicalGeometry(this.host._t(t.id?"history.edit_opening":"history.add_opening"),i),this.host._openingDialog=null,this.host.requestUpdate()}_deleteOpening(){const t=this.host._openingDialog,e=this.host._curSpaceCfg;if(!t?.id||!e?.openings)return;const s=this._geometrySnapshot();e.openings=e.openings.filter(e=>e.id!==t.id),this._commitPhysicalGeometry(this.host._t("history.delete_opening"),s),this.host._openingDialog=null,this.host.requestUpdate()}_contactCandidates(){const t=[];for(const e of Object.keys(this.host.hass.states)){if(!this.host._openingEntityAvailable(e))continue;const s=e.split(".")[0];if("binary_sensor"!==s&&"cover"!==s)continue;const i=this.host.hass.states[e],o=["door","window","opening","garage_door","garage"].includes(i?.attributes?.device_class||"");("cover"!==s||o)&&t.push([e,i?.attributes?.friendly_name||e,o?0:1])}return t.sort((t,e)=>t[2]-e[2]||t[1].localeCompare(e[1])).map(([t,e])=>({value:t,label:e}))}_lockCandidates(){return Object.keys(this.host.hass.states).filter(t=>t.startsWith("lock.")&&this.host._openingEntityAvailable(t)).map(t=>({value:t,label:this.host.hass.states[t]?.attributes?.friendly_name||t})).sort((t,e)=>t.label.localeCompare(e.label))}_toggleOpeningEntityPicker(t){const e=this.host._openingDialog;if(!e)return;const s="contact"===t?!e.contactOpen:!e.lockOpen;this.host._openingDialog={...e,contactOpen:"contact"===t&&s,lockOpen:"lock"===t&&s}}_filterOpeningEntities(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contactFilter:e}:{...s,lockFilter:e})}_selectOpeningEntity(t,e){const s=this.host._openingDialog;s&&(this.host._openingDialog="contact"===t?{...s,contact:e,contactOpen:!1,contactFilter:""}:{...s,lock:e,lockOpen:!1,lockFilter:""})}_mergeClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms,i=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!i?.id)return;const o=i.id;if(!this.host._mergeSel||this.host._mergeSel===o)return void(this.host._mergeSel=this.host._mergeSel===o?null:o);const a=s.find(t=>t.id===this.host._mergeSel),n=a?B(a):null,r=B(i),l=n&&r?ks(n,r):null;if(!l)return this.host._showToast(this.host._t("toast.merge_not_adjacent")),void(this.host._mergeSel=null);this.host._mergeDialog={aId:this.host._mergeSel,bId:o,poly:l,pick:"a"},this.host._mergeSel=null}_commitMerge(){const t=this.host._mergeDialog,e=this.host._curSpaceCfg;if(!t||!e||!this.host._spaceModel())return;const s=this._geometrySnapshot(),i=this.host._spaceH,o="a"===t.pick?t.aId:t.bId,a="a"===t.pick?t.bId:t.aId,n=Yc(this.host._serverCfg?.markers||[],{kind:"merge",dropId:a,keepId:o});s&&n.changed&&(s.roomReferences=n.before);const r=e.rooms.find(t=>t.id===o);if(!r)return void(this.host._mergeDialog=null);r.poly=t.poly.map(t=>[t[0]/id,t[1]/i]),delete r.x,delete r.y,delete r.w,delete r.h,e.rooms=e.rooms.filter(t=>t.id!==a),n.changed&&this.host._serverCfg&&(this.host._serverCfg.markers=n.markers);const l=this._commitPhysicalGeometry(this.host._t("history.merge_rooms"),s);this.host._mergeDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),l&&this.host._showToast(this.host._t("toast.rooms_merged",{name:r.name||""}))}_splitClick(t){const e=this.host._spaceModel();if(!e)return;const s=e.rooms;if(!this.host._splitSel){const e=[...s].reverse().find(e=>this._pointInRoom(t,e));if(!e?.id)return;return void(this.host._splitSel={roomId:e.id,pts:[]})}const i=s.find(t=>t.id===this.host._splitSel.roomId),o=i?B(i):null;if(!i||!o)return void(this.host._splitSel=null);const a=.02*this.host._gridPitch,n=6*this.host._gridPitch,r=xs(t,o),l=r&&Ss(r,o,this.host._gridPitch)||r,h=r&&l&&Math.hypot(r[0]-t[0],r[1]-t[1])<=n?l:null,c=!!h&&Ms(h,o,a),d=this.host._splitSel.pts;if(!d.length)return c?void(this.host._splitSel={...this.host._splitSel,pts:[h]}):void this.host._showToast(this.host._t("toast.split_pick_wall"));if(!c){const e=this._snap(t);return Ce(e,o,a)?void(this.host._splitSel={...this.host._splitSel,pts:[...d,e]}):void this.host._showToast(this.host._t("toast.split_pick_inside"))}const p=De(o,[...d,h],a);if(!p)return void this.host._showToast(this.host._t("toast.split_bad_cut"));this._resetRoomDialogFields();const[u,_]=p,m=H(u)>=H(_)?u:_,g=m===u?_:u;this.host._pendingSplit={roomId:i.id,mainPoly:m,newPoly:g},this.host._cursorPt=null,this.host._nameSel="",this.host._areaSel="",this.host._roomDialog=!0}_markupMove(t){if(!this.host._markup)return;if("column"===this.host._tool)return void(this.host._cursorPt=this._snap(this._svgPoint(t)));if("opening"===this.host._tool||"wallthick"===this.host._tool)return void(this.host._cursorPt=this._svgPoint(t));const e="draw"===this.host._tool&&!this.host._contourClosed,s="split"===this.host._tool&&!!this.host._splitSel?.pts?.length;if(!e&&!s)return;const i=this._svgPoint(t);if(e){const e=this._resolvePlanDrawPoint(i,t.shiftKey);if(this.host._planSnapHover={contextKey:e.contextKey,candidate:e.candidate,conflicts:e.conflicts},this._syncPlanSnapConflictMarkers(e.conflicts),this._syncPlanSnapActiveMarker(e.candidate),!this.host._path.length)return;return void(this.host._cursorPt=e.point)}this.host._cursorPt=this._snap(i)}_saveRoom(){(this.host._areaSel||this.host._nameSel.trim())&&nt(this.host._roomTempMin,this.host._roomTempMax).valid&&(this.host._wallFaceBatch?this._decideWallFace(!0):this._commitRoom())}_decideWallFace(t){const e=this.host._wallFaceBatch;if(!e)return;const s=e.candidates[e.index];if(!s)return;if(!t&&(s.existing||s.repair)&&1===e.candidates.length)return this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate();const i=t?{candidate:s,create:!0,name:this.host._nameSel.trim(),area:this.host._areaSel||null,settings:this._roomSettingsFromDialog()?JSON.parse(JSON.stringify(this._roomSettingsFromDialog())):null}:{candidate:s,create:!1},o=[...e.decisions,i],a=e.index+1;if(a"number"==typeof t&&Number.isFinite(t)&&t>=0?t:null,o=.02*this.host._gridPitch,a=this.host._spaceModel();if(!a)return ut;for(const e of this._planSnapGeometrySnapshot().value.segments)if(!("room"===e.sourceKind||Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])>o)&&"partition"===e.sourceKind)return i(a.partitions.find(t=>t.id===e.sourceId)?.cm)??ut;const n=Ah(Math.max(0,e.length-1),s,this.host._drawWallCm,ut);for(let s=0;s+1[...t]);if(!e)return s;const i=this.host._activeWallChainPartitionIds.findIndex((t,s)=>this._activeWallSourceKey(s)===e.sourceKey),o=i>=0?i+("b"===e.endpoint?1:0):-1;return o>=0&&oe.key===t.sourceKey),a=i.find(e=>e.key===t.targetSourceKey);if(!o||!a)return!1;const n="a"===t.endpoint?o.a:o.b;return!(Math.hypot(n[0]-t.from[0],n[1]-t.from[1])>s)&&(!(Wt(t.to,[a.a[0],a.a[1],a.b[0],a.b[1]])>s)&&!function(t,e){if(!t.sourceKey.startsWith("static:partition|"))return!1;const s=t.sourceKey.slice(17).split("|")[0];return!!s&&e.some(t=>"partition"===t.host?.kind&&t.host.id===s)}(t,this.host._curSpaceCfg?.openings||[]))}_applyWallRepair(t,e){const s=this.host._curSpaceCfg;if(!s||!this._validateWallRepair(t,e.activePath))return!1;if(!t.sourceKey.startsWith("static:"))return!1;const[i,o]=t.sourceKey.slice(7).split("|");if("partition"===i){const i=(s.partitions||[]).find(t=>t.id===o);if(!i)return!1;const a=[i.a[0]*id,i.a[1]*id],n=[i.b[0]*id,i.b[1]*id],r=Math.hypot(a[0]-t.from[0],a[1]-t.from[1])<=2e-4*this.host._gridPitch?i.a:Math.hypot(n[0]-t.from[0],n[1]-t.from[1])<=2e-4*this.host._gridPitch?i.b:null;if(!r)return!1;(e=>{e[0]=t.to[0]/id,e[1]=t.to[1]/id})(r);const l=e.activePartitionIds.indexOf(o);if(l>=0){const s=l+("b"===t.endpoint?1:0);e.activePath[s]&&(e.activePath[s]=[...t.to])}return!0}return!1}_applyWallFaceBatch(){const t=this.host._wallFaceBatch,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=(t,e)=>{this.host._showToast(this.host._t(t,e)),this._roomDialogCancel()},o=t.decisions.filter(t=>t.create),a=o.map(t=>t.candidate.ring),n=s.rooms;for(let t=0;ts.id!==e&&!!B(s)&&N(a[t],B(s)));if(s)return void i("toast.room_overlap",{name:s.name||""})}if((e.rooms||[]).length+o.length>400)return void i("toast.physical_limit");if(o.some(t=>t.candidate.split&&!e.rooms.some(e=>e.id===t.candidate.split.roomId)))return void i("toast.contour_cannot_close");const r=o.map(t=>t.candidate.repair).filter(t=>!!t);if(r.length>1||r[0]&&!this._validateWallRepair(r[0],t.activePath))return void i("toast.wall_repair_changed");if(this._activePathWithRepair(t.activePath,r[0]),!o.length){if(!this._finalizeWallChainPartitions(t.activePartitionIds))return;return this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host.requestUpdate(),void this.host._showToast(this.host._t("toast.wall_chain_saved"))}const l=new Set(t.activePartitionIds),h=2e-4*this.host._gridPitch,c=o.map(t=>t.candidate.ring.map((t,e,i)=>{const o=i[(e+1)%i.length],a=s.partitions.filter(e=>{const s=Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1]);if(!(s>h))return!1;const i=(e.b[0]-e.a[0])/s,a=(e.b[1]-e.a[1])/s,n=t=>(t[0]-e.a[0])*i+(t[1]-e.a[1])*a;return Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&Wt(o,[e.a[0],e.a[1],e.b[0],e.b[1]])<=h&&n(t)>=-h&&n(t)<=s+h&&n(o)>=-h&&n(o)<=s+h});return a.sort((t,e)=>Number(l.has(e.id))-Number(l.has(t.id))||Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])-Math.hypot(e.b[0]-e.a[0],e.b[1]-e.a[1])||t.id.localeCompare(e.id)),a[0]?.id||""})),d=this._geometrySnapshot();if(!d)return void i("toast.geometry_unsafe");const p=()=>{this._restoreGeometryStateLocal(d),i("toast.geometry_unsafe")};if(r[0]&&!this._applyWallRepair(r[0],t))return void i("toast.wall_repair_changed");const u=o.some(t=>!!t.candidate.split),_=u?ae(s.rooms,e.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id):null,m=u&&Array.isArray(e.walls)?e.walls:null;for(const t of o){const s=t.candidate.split;if(!s)continue;const i=e.rooms.find(t=>t.id===s.roomId);if(!i)return void p();i.poly=s.mainPoly.map(t=>[t[0]/id,t[1]/this.host._spaceH]),delete i.x,delete i.y,delete i.w,delete i.h}const g=Date.now().toString(36),f=[];if(o.forEach((t,s)=>{const i=t.area?this.host.hass.areas[t.area]?.name:"",o={id:`r${g}-${s}`,name:t.name||i||this.host._t("room.default_name"),area:t.area||null,poly:t.candidate.ring.map(t=>[t[0]/id,t[1]/this.host._spaceH]),...c[s].some(Boolean)?{wall_ids:c[s]}:{},...t.settings?{settings:JSON.parse(JSON.stringify(t.settings))}:{}};e.rooms.push(o),f.push({room:o,decision:t})}),u){const t=this.host._normalizeWalls(_,this.host._openCuts());t.length?e.walls=t:m?.length?e.walls=m:delete e.walls}if(f.length){this.host._cfgEpoch++;const s=this.host._openCuts(),i=this.host._spaceModel();if(!i)return void p();let o=e.walls;for(const{room:e,decision:a}of f){const n=a.candidate.ring,r=this._wallSourceCmAt(n[0],t.activePath,t.activeCms);o=Cs(o,i.rooms,e.id,r,this.host._wallKeyPitch,s,id);for(const a of pt(i.rooms,o,s,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id)){if(a.roomId!==e.id||"outer"!==a.kind)continue;const s=[(a.a[0]+a.b[0])/2,(a.a[1]+a.b[1])/2];o=gt(o,a.a,a.b,this._wallSourceCmAt(s,t.activePath,t.activeCms),this.host._wallKeyPitch,id)}}const a=this.host._normalizeWalls(o,s);a.length?e.walls=a:delete e.walls,this.host._cfgEpoch++;const n=this.host._spaceModel();if(!n)return void p();const r=kl(e,n,e.walls,s,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:id,allowCoincidentPartitions:!0});r.walls.length?e.walls=r.walls:delete e.walls,r.partitions.length?e.partitions=r.partitions:delete e.partitions,r.openings.length?e.openings=r.openings:delete e.openings}if(!this._commitPhysicalGeometry(this.host._t("history.wall_face_batch"),d))return;this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._wallFaceBatch=null,this.host._roomDialog=!1,this.host._nameSel="",this.host._areaSel="",this.host._regSignature="",this.host._maybeRebuildDevices();const b=new Set(o.map(t=>t.area).filter(t=>!!t));if(b.size){const t={...this.host._layout};for(const e of this.host._devices){if(!b.has(e.area||"")||e.space!==this.host._space)continue;if(this.host._layout[e.id])continue;const s=this.host._defPos[e.id];s&&(t[e.id]={s:this.host._space,x:s.x/id,y:s.y/id},this.host._dirtyPos.add(e.id))}this.host._layout=t,this.host._persistLayout()}this.host._showToast(this.host._t(o.length?"toast.wall_rooms_saved":"toast.wall_chain_saved",{n:o.length}))}_commitRoom(){const t=this.host._curSpaceCfg,e=this.host._spaceModel();if(!t||!e)return;const s=this._geometrySnapshot();if(!s)return;const i=()=>{this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe"))},o=this.host._spaceH,a=!!this.host._pendingSplit,n=a?ae(e.rooms,t.walls,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id):null,r=a&&Array.isArray(t.walls)?t.walls:null;let l;if(this.host._pendingSplit){const e=t.rooms.find(t=>t.id===this.host._pendingSplit.roomId);if(!e)return this.host._pendingSplit=null,this.host._splitSel=null,void(this.host._roomDialog=!1);e.poly=this.host._pendingSplit.mainPoly.map(t=>[t[0]/id,t[1]/o]),delete e.x,delete e.y,delete e.w,delete e.h,l=this.host._pendingSplit.newPoly}else{if(!this.host._contourClosed)return;l=this.host._path.slice(0,-1)}const h=this.host._areaSel?this.host.hass.areas[this.host._areaSel]?.name:"",c={id:"r"+Date.now().toString(36),name:this.host._nameSel||h||this.host._t("room.default_name"),area:this.host._areaSel||null,poly:l.map(t=>[t[0]/id,t[1]/o]),...this._roomSettingsFromDialog()?{settings:this._roomSettingsFromDialog()}:{}};if(t.rooms.push(c),a){const e=this.host._normalizeWalls(n,this.host._openCuts());e.length?t.walls=e:r?.length?t.walls=r:delete t.walls}if(!a){const e=Ah(l.length,[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,ut),s=e[0];if(null!=s){this.host._cfgEpoch++;const o=this.host._openCuts(),a=this.host._spaceModel();if(!a)return void i();let n=Cs(t.walls,a.rooms,c.id,s,this.host._wallKeyPitch,o,id);for(const t of pt(a.rooms,n,o,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id)){if(t.roomId!==c.id||"outer"!==t.kind)continue;const s=[(t.a[0]+t.b[0])/2,(t.a[1]+t.b[1])/2],i=l.findIndex((t,e)=>{const i=l[(e+1)%l.length];return Wt(s,[t[0],t[1],i[0],i[1]])<=.02*this.host._gridPitch});i>=0&&(n=gt(n,t.a,t.b,e[i],this.host._wallKeyPitch,id))}n=this.host._normalizeWalls(n,o),n.length?t.walls=n:delete t.walls;const r=this.host._spaceModel();if(!r)return void i();const h=kl(t,r,t.walls,o,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:id,allowCoincidentPartitions:!0});h.walls.length?t.walls=h.walls:delete t.walls,h.partitions.length?t.partitions=h.partitions:delete t.partitions,h.openings.length?t.openings=h.openings:delete t.openings}}const d=this._commitPhysicalGeometry(this.host._t(a?"history.split_room":"history.add_room"),s);this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._pendingSplit=null,this.host._splitSel=null;const p=this.host._areaSel;if(this.host._areaSel="",this.host._nameSel="",this.host._roomDialog=!1,this.host._regSignature="",this.host._maybeRebuildDevices(),!d)return;let u=0;if(p){const t=id,e={...this.host._layout};for(const s of this.host._devices){if(s.area!==p||s.space!==this.host._space)continue;if(u++,this.host._layout[s.id])continue;const i=this.host._defPos[s.id];i&&(e[s.id]={s:this.host._space,x:i.x/id,y:i.y/t},this.host._dirtyPos.add(s.id))}this.host._layout=e,this.host._persistLayout()}const _=this.host._model.find(t=>t.id===this.host._space)?.rooms.length||0;this.host._showToast(p?this.host._t("toast.room_saved",{n:_,added:u}):this.host._t("toast.room_saved_no_area",{n:_}))}_cancelPath(){this.host._wallRepairDiagnostic=null,this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),this.host._roomDialog=!1,this.host._pendingSplit=null,this.host._wallFaceBatch=null,this.host._splitSel=null,this.host._mergeSel=null,this.host._mergeDialog=null,this.host._physicalSel=null,this.host._physicalDrag=null,this.host._physicalRotate=null,this._clearOpeningPlacement(!0)}_roomDialogCancel(){if(this.host._roomDialog=!1,this.host._roomEditId)return this.host._roomEditId=null,this.host._nameSel="",void(this.host._areaSel="");if(this.host._wallFaceBatch){const t=this.host._wallFaceBatch;return this.host._wallFaceBatch=null,this.host._path=t.activePath.map(t=>[...t]),this.host._wallChainSegmentCms=[...t.activeCms],this.host._activeWallChainPartitionIds=[...t.activePartitionIds],this.host._activeWallChainId||=`chain-${Date.now().toString(36)}`,this.host._nameSel="",this.host._areaSel="",void this.host.requestUpdate()}if(this.host._pendingSplit)return this.host._pendingSplit=null,void(this.host._splitSel=null);this.host._undoPoint()}_openDeviceInbox(){this.host._deviceInboxReturn=null,this.host._deviceInbox=this.host._deviceInbox||{tab:"on_plan",search:"",showEntities:!1,onlyNew:!1,limit:100}}_closeMarkerDialog(){this._radarSetup.isDirty()?this._closeMarkerDialogGuarded():(this._radarSetup.reset(),function(t){if(t._markerDialog=null,!t._deviceInboxReturn)return;const e={...t._deviceInboxReturn};t._deviceInbox=e,t._deviceInboxReturn=null,e.anchor&&t.updateComplete.then(()=>requestAnimationFrame(()=>{const s=`.device-inbox-row[data-binding="${CSS.escape(e.anchor)}"]`;t.renderRoot.querySelector(s)?.scrollIntoView({block:"nearest"})}))}(this.host))}async _closeMarkerDialogGuarded(){if(!await this._radarSetup.discardIfAllowed())return await this.host.updateComplete,void this.host.renderRoot.querySelector("#marker-dialog")?.rejectClose();this._closeMarkerDialog()}_deviceInboxCandidates(t){return Xl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:t,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}})}_deviceInboxRows(){const t=this.host._deviceInbox||this.host._deviceInboxReturn,e=!!t?.showEntities,s=[this.host._haRegistry.revision,this.host._cfgRev,this.host._cfgEpoch,this.host._regSignature,this.host._newSyncKey,e?1:0,this.host._showAll?1:0,l(this.host.hass,this.host._config?.language)].join("|");if(this.host._deviceInboxMemo?.key===s)return this.host._deviceInboxMemo.rows;const i=this._deviceInboxCandidates(e),o=new Set(i.map(t=>t.value));for(const t of this.host._markers)t.binding&&"virtual"!==t.binding&&o.add(t.binding);for(const t of this.host._devices)t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&o.add(`${t.bindingKind}:${t.bindingRef}`);const a=new Map;for(const t of o)a.set(t,this.host._bindingStatus(t));const n=this.host._areaToSpace,r={};for(const[t,e]of Object.entries(this.host.hass?.areas||{}))r[t]=n[t]?.room?.name||e?.name||t;for(const[t,e]of Object.entries(n))r[t]=e.room.name||r[t]||t;const h=Object.fromEntries(this.host._model.map(t=>[t.id,t.title])),c=Object.fromEntries(Object.entries(n).map(([t,e])=>[t,e.space])),d={},p=new Map;for(const[t,e]of Object.entries(this.host._fullRegistryHass.entities||{})){const s=String(e?.platform||"").trim();if(s&&(d[`entity:${t}`]=s),s&&e?.device_id){const t=p.get(e.device_id)||new Set;t.add(s),p.set(e.device_id,t)}}for(const[t,e]of p)d[`device:${t}`]=[...e].sort().join(", ");const u={};for(const[t,e]of Object.entries(this.host._fullRegistryHass.devices||{})){const s=`device:${t}`,i=p.get(t)||new Set,o=Array.isArray(e?.identifiers?.[0])?String(e.identifiers[0][0]||""):"";o&&!d[s]&&(d[s]=o);const a=[o,...i].some(t=>this.host._excluded.has(t));"service"===e?.entry_type?u[s]="service_entry":a?u[s]="excluded_integration":"Group"===e?.model?u[s]="grouped_light":/scene/i.test(e?.model||"")?u[s]="excluded_domain":(/bridge/i.test(`${e?.model||""}${e?.name||""}`)||"myheat"===o&&e?.via_device_id)&&(u[s]="represented_by_parent")}const _=function(t){const{devices:e,markers:s,candidates:i,statuses:o,newDeviceIds:a,showHiddenOnPlan:n,areaNames:r={},spaceNames:l={},spaceByArea:h={},integrationByBinding:c={},reasonByBinding:d={}}=t,p=new Map;for(const t of e)!t.virtual&&t.bindingKind&&"virtual"!==t.bindingKind&&t.bindingRef&&p.set(`${t.bindingKind}:${t.bindingRef}`,t);const u=new Map,_=new Map;for(const t of s)t?.binding&&"virtual"!==t.binding&&(t.removed?_.set(t.binding,t):u.set(t.binding,t));const m=new Map(i.map(t=>[t.value,t])),g=new Set([...p.keys(),...u.keys(),...m.keys(),...[..._.keys()].filter(t=>m.has(t))]),f=[];for(const t of g){const e=p.get(t),s=u.get(t),i=s?void 0:_.get(t),g=m.get(t);let b;if(i&&g)b="readd";else if(!0===s?.hidden)b="hidden";else if(e||s)b="on_plan";else{if(!g)continue;b="available"}const v=e?.bindingStatus||o.get(t)||Zl,y=s||i,$=Ql(t),w=e?.area||g?.areaId||y?.area||"",k=e?.space||y?.space||h[w]||"",x=e?.name||y?.name||g?.label||t,S=e?.model||y?.model||g?.model||"",M=!!g?.parentDeviceId&&p.has(`device:${g.parentDeviceId}`),C="readd"===b?"removed":"hidden"===b?s&&th(s)?d[t]||"automatic_hidden":"manual_hidden":"on_plan"===b?s?"visible_explicit":"visible_auto":d[t]||(M?"represented_by_parent":w&&k?"available":"no_bound_room"),P=!!e&&(!e.hidden||n),D="active"===v.kind,I=P&&(D||"ha_disabled"===v.kind&&n),T=[x,S,c[t],r[w],l[k],t,g?.sub].filter(Boolean).join(" ").toLocaleLowerCase();f.push({key:t,binding:t,category:b,status:v,reason:C,deviceId:e?.id,markerId:y?.id,name:x,icon:e?.icon||y?.icon||("entity"===$?"mdi:code-braces":"mdi:devices"),model:S,integration:c[t]||"",areaId:w,areaName:r[w]||"",spaceId:k,spaceName:l[k]||"",kind:$,isNew:!!e&&a.has(e.id),searchText:T,canFind:I,canEdit:!!e||!!s,canHide:"on_plan"===b&&D,canShow:"hidden"===b&&D,canAdd:("available"===b||"readd"===b)&&D})}const b=t=>"active"===t.status.kind?1:0;return f.sort((t,e)=>t.category.localeCompare(e.category)||Number(e.isNew)-Number(t.isNew)||b(t)-b(e)||t.name.localeCompare(e.name)||t.binding.localeCompare(e.binding))}({devices:this.host._devices,markers:this.host._markers,candidates:i,statuses:a,newDeviceIds:this.host._newIds,showHiddenOnPlan:this.host._showAll,areaNames:r,spaceNames:h,spaceByArea:c,integrationByBinding:d,reasonByBinding:u});return this.host._deviceInboxMemo={key:s,rows:_},_}_deviceForInboxRow(t){const e=t.deviceId?this.host._devices.find(e=>e.id===t.deviceId):null;if(e)return e;const s=t.markerId?this.host._markers.find(e=>e.id===t.markerId):null;return!s||s.removed?null:{id:s.id,name:t.name,model:t.model,area:t.areaId,space:t.spaceId||this.host._space,hidden:!0===s.hidden||"ha_disabled"===t.status.kind,userHidden:!0===s.hidden,bindingStatus:t.status,icon:t.icon,entities:"active"===t.status.kind?t.status.enabledEntityIds:[],allEntities:t.status.allEntityIds,primary:"active"===t.status.kind?t.status.enabledEntityIds[0]:void 0,marker:s,bindingKind:t.kind,bindingRef:t.binding.slice(t.binding.indexOf(":")+1),pdfs:s.pdfs||[]}}_openInboxMarker(t,e=!1){const s=this.host._deviceInbox;if(s){if(this.host._deviceInboxReturn={...s,anchor:t.key},this.host._deviceInbox=null,!e){const e=this._deviceForInboxRow(t);return void(e?this._openMarkerDialog(e):this._closeMarkerDialog())}this._openMarkerDialog(),this.host._markerDialog?this.host._markerDialog={...this.host._markerDialog,bindingMode:"ha",binding:t.binding,bindingOpen:!1,showEntities:"entity"===t.kind,name:""}:this._closeMarkerDialog()}}async _setInboxHidden(t,e){const s=this.host._deviceInbox,i=this.host._serverCfg;if(!s||!i||s.busy||"active"!==t.status.kind)return;const o=i.markers||[],a=o.find(e=>!e.removed&&e.binding===t.binding);if(!e&&!a)return;const n=a?.id||Ps(t.binding,t.markerId,()=>`m_${Date.now().toString(36)}`),r=a?{...a,hidden:e}:{id:n,binding:t.binding,hidden:!0};i.markers=[...o.filter(e=>e.id!==n&&(e.binding!==t.binding||!0===e.removed)),r],this.host._deviceInbox={...s,busy:t.key,anchor:t.key};try{await this._saveConfigNow(),this.host._regSignature="",this.host._deviceInboxMemo=null,this.host._maybeRebuildDevices(),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("device_inbox.saved"))}catch(t){this.host._serverCfg===i&&(i.markers=o),this.host._deviceInbox&&(this.host._deviceInbox={...this.host._deviceInbox,busy:void 0}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_findInboxDevice(t){if(!t.canFind)return;const e=this._deviceForInboxRow(t);if(!e)return;if(this.host._deviceInbox=null,e.space&&e.space!==this.host._space){if(!this.host._commitSpace(e.space))return;this.host._restoreZoom()}const s=()=>{const t=this.host._devices.find(t=>t.id===e.id)||e,s=this.host._pos(t);this.host._applyView(this.host._zoom,s.x,s.y),this.host._selId=t.id,this.host.requestUpdate(),window.setTimeout(()=>{this.host._selId===t.id&&(this.host._selId=null,this.host.requestUpdate())},1500)};requestAnimationFrame(()=>requestAnimationFrame(s))}_openMarkerDialog(t){if(this.host._vacAllCamerasFor=null,this.host._vacAllCameraCache=null,t&&this.host._ackNewDevice(t.id),this.host._norm)if(t){const e=t.marker,s=Object.prototype.hasOwnProperty.call(e||{},"is_light"),i=Object.prototype.hasOwnProperty.call(e||{},"light_entity"),o=Object.prototype.hasOwnProperty.call(e||{},"glow_color"),a=Object.prototype.hasOwnProperty.call(e||{},"value_badge"),n=Object.prototype.hasOwnProperty.call(e||{},"value_source"),r=Object.prototype.hasOwnProperty.call(e||{},"tap_action"),l=Object.prototype.hasOwnProperty.call(e||{},"toggle_entity"),h=Ds(e?.glow_color),c=this.host._devicePresentation(t,!0).valueBadge,d=Is(this.host._planHass,t,this.host._devices),p=Ts(this.host._planHass,t,d),u=rh(t,this.host._fullRegistryHass),_=this.host._spaceModelById(t.space)||this.host._spaceModel(),m=this.host._pos(t),g=_?hh(t,_,[m.x,m.y],this.host._fullRegistryHass):null;this.host._markerDialog={devId:t.id,name:t.name,binding:"virtual"===t.bindingKind?"virtual":t.bindingKind+":"+t.bindingRef,bindingMode:"virtual"===t.bindingKind?"virtual":"ha",bindingOpen:!1,showEntities:"entity"===t.bindingKind&&!!this.host._fullRegistryHass.entities[t.bindingRef||""]?.device_id,bindingFilter:"",icon:t.marker?.icon||"",autoIcon:t.icon||"",display:As(t.marker?.display),rippleColor:x(t.marker?.ripple_color,""),rippleSize:Number(t.marker?.ripple_size)>0?Number(t.marker.ripple_size):1.5,size:Number(t.marker?.size)>0?Number(t.marker.size):1,angle:Number(t.marker?.angle)||0,tapAction:zs(t.marker?.tap_action,t.primary?.split(".")[0]),tapActionTouched:!1,originalHasTapAction:r,originalTapAction:t.marker?.tap_action,tapHintAnnouncement:"",toggleEntity:e?.toggle_entity||"",toggleEntityTouched:!1,originalHasToggleEntity:l,originalToggleEntity:e?.toggle_entity,tapTarget:t.marker?.tap_target||"",tapConfirm:!0===t.marker?.tap_confirm,runFilter:"",controls:Rs(t.marker?.binding,t.marker?.controls,t.entities),controlsFilter:"",lightRole:!0===e?.is_light?"always":!1===e?.is_light?"never":"auto",lightRoleTouched:!1,originalHasIsLight:s,originalIsLight:e?.is_light,lightEntity:e?.light_entity||"",lightEntityTouched:!1,originalHasLightEntity:i,originalLightEntity:e?.light_entity,glowMode:null!=h?.bri?"fixed":h?"color":"auto",glowColor:h?.c||this.host._fillColors.glow_light.c,glowBrightness:Math.max(1,Math.round(100*(h?.bri??1))),glowColorDrafted:!!h,glowBrightnessDrafted:null!=h?.bri,glowTouched:!1,originalHasGlowColor:o&&(!!h||null===e?.glow_color),originalGlowColor:h||(null===e?.glow_color?null:void 0),valueBadgeEnabled:a?!0===e?.value_badge?.enabled:!!c,valueBadgeSource:e?.value_badge?.source||c?.source||p,valueBadgePosition:e?.value_badge?.position||c?.position||"right",valueBadgeTouched:!1,originalHasValueBadge:a,originalValueBadge:e?.value_badge,valueSource:e?.value_source||null,valueSourceTouched:!1,originalHasValueSource:n,originalValueSource:e?.value_source,useClimateTemp:!0===t.marker?.use_climate_temp,glowRadius:Number(t.marker?.glow_radius_cm)>0?String(this.host._imperial?Math.round(Number(t.marker.glow_radius_cm)/30.48*10)/10:Math.round(Number(t.marker.glow_radius_cm))/100):"",model:t.model||"",link:t.link||"",description:t.description||"",pdfs:[...t.pdfs||[]],room:t.marker?.room_id?t.space+"#@"+t.marker.room_id:t.space&&t.area?t.space+"#"+t.area:"",roomTouched:!1,radar:g,radarEligible:u.eligible,radarTouched:!1,radarRemove:!1,hideFromPlan:!0===t.marker?.hidden,busy:!1}}else this.host._markerDialog={name:"",binding:"virtual",bindingMode:"virtual",bindingOpen:!1,showEntities:!1,bindingFilter:"",icon:"",autoIcon:"",display:"badge",rippleColor:"",rippleSize:1.5,size:1,angle:0,tapAction:"info",tapActionTouched:!1,originalHasTapAction:!1,originalTapAction:void 0,tapHintAnnouncement:"",toggleEntity:"",toggleEntityTouched:!1,originalHasToggleEntity:!1,originalToggleEntity:void 0,tapTarget:"",tapConfirm:!1,runFilter:"",controls:[],controlsFilter:"",lightRole:"auto",lightRoleTouched:!1,originalHasIsLight:!1,originalIsLight:void 0,lightEntity:"",lightEntityTouched:!1,originalHasLightEntity:!1,originalLightEntity:void 0,glowMode:"auto",glowColor:this.host._fillColors.glow_light.c,glowBrightness:100,glowColorDrafted:!1,glowBrightnessDrafted:!1,glowTouched:!1,originalHasGlowColor:!1,originalGlowColor:void 0,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgePosition:"right",valueBadgeTouched:!1,originalHasValueBadge:!1,originalValueBadge:void 0,valueSource:null,valueSourceTouched:!1,originalHasValueSource:!1,originalValueSource:void 0,useClimateTemp:!1,glowRadius:"",model:"",link:"",description:"",pdfs:[],room:"",roomTouched:!1,radar:null,radarEligible:!1,radarTouched:!1,radarRemove:!1,hideFromPlan:!1,busy:!1,uploadId:"up_"+Date.now().toString(36)+Math.random().toString(36).slice(2,6)};else this.host._showToast(this.host._t("toast.marker_needs_server"))}_runCandidates(){const t=[];for(const e of Fs)for(const[s,i]of Object.entries(this.host.hass.states))s.startsWith(e+".")&&this.host._planEntityAvailable(s)&&t.push({value:s,label:i?.attributes?.friendly_name||s,sub:this.host._t("run."+e)});return t.sort((t,e)=>t.sub.localeCompare(e.sub)||t.label.localeCompare(e.label))}_bindingCandidates(){const t=Xl({hass:this.host._planHass,devices:this.host._devices,markers:this.host._markers,showEntities:!!this.host._markerDialog?.showEntities,currentBinding:this.host._markerDialog?.binding,currentDeviceId:this.host._markerDialog?.devId,labels:{device:this.host._t("marker.sub_device"),z2mGroup:this.host._t("marker.sub_z2m_group"),group:this.host._t("marker.sub_group"),helper:this.host._t("marker.sub_helper"),entity:this.host._t("marker.sub_entity")}}),e=(this.host._markerDialog?.bindingFilter||"").toLowerCase().trim(),s=e?t.filter(t=>(t.label+" "+t.sub+" "+t.value).toLowerCase().includes(e)):t;return s.sort((t,e)=>t.label.localeCompare(e.label)),s.slice(0,200)}_backupErrorText(t){const e=t?.code??t?.error;if("string"==typeof e){const t=`backup.error.${e}`,s=this.host._t(t);if(s!==t)return s}return this.host._errText(t)}async _pickMarkerFiles(t){const e=t.target,s=e.files?[...e.files]:[];if(e.value="",!s.length||!this.host._markerDialog)return;const i=this.host._markerDialog.uploadId||this.host._markerDialog.devId||"new",o=[];for(const t of s)try{const e=new FormData;e.append("marker_id",i),e.append("file",t,t.name);const s=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth("/api/houseplan/upload",{method:"POST",body:e}):await fetch("/api/houseplan/upload",{method:"POST",body:e,headers:this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}),a=await s.json().catch(()=>({}));if(!s.ok||a.error){const t={too_large:this.host._t("err.too_large",{mb:a.max_mb||50}),bad_ext:this.host._t("err.bad_ext"),unauthorized:this.host._t("err.unauthorized")};throw new Error(t[a.error]||a.error||"HTTP "+s.status)}o.push({name:a.name||t.name,url:a.url})}catch(e){this.host._showToast(this.host._t("toast.file_failed",{name:t.name,err:this.host._errText(e)}))}o.length&&this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:[...this.host._markerDialog.pdfs,...o]},this.host._showToast(this.host._t("toast.files_attached",{n:o.length})))}_removeMarkerPdf(t){this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,pdfs:this.host._markerDialog.pdfs.filter(e=>e.url!==t)})}_markerLightFields(t){const e={};if(t.lightRoleTouched?"always"===t.lightRole?e.is_light=!0:"never"===t.lightRole&&(e.is_light=!1):t.originalHasIsLight&&(e.is_light=t.originalIsLight??null),t.lightEntityTouched?t.lightEntity&&(e.light_entity=t.lightEntity):t.originalHasLightEntity&&(e.light_entity=t.originalLightEntity??null),t.glowTouched){if("auto"!==t.glowMode){const s={c:x(t.glowColor,this.host._fillColors.glow_light.c)};"fixed"===t.glowMode&&(s.bri=Math.max(.01,Math.min(1,Math.round(t.glowBrightness)/100))),e.glow_color=s}}else t.originalHasGlowColor&&(e.glow_color=t.originalGlowColor??null);return e}_markerTapActionFields(t){return t.tapActionTouched?{tap_action:t.tapAction||null}:t.originalHasTapAction?{tap_action:t.originalTapAction??null}:{}}_markerToggleEntityFields(t){return(e={touched:t.toggleEntityTouched,originalHas:t.originalHasToggleEntity,original:t.originalToggleEntity,value:t.toggleEntity}).touched?e.value?{toggle_entity:e.value}:{}:e.originalHas?{toggle_entity:e.original??null}:{};var e}async _saveMarker(){const t=this.host._markerDialog;if(!t||t.busy)return;const e=this._effectiveMarkerTapAction(t);if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return;if("virtual"===t.binding&&!t.name.trim())return void this.host._showToast(this.host._t("toast.virtual_name_required"));if("run"===e&&!t.tapTarget)return void this.host._showToast(this.host._t("toast.run_target_required"));if(t.valueBadgeTouched&&t.valueBadgeEnabled&&!t.valueBadgeSource)return void this.host._showToast(this.host._t("toast.value_badge_source_required"));if("ha"===t.bindingMode){const e=this.host._bindingStatus(t.binding),s=t.devId?this.host._markers.find(e=>e.id===t.devId):null,i=!s||s.binding!==t.binding;if("active"!==e.kind&&i)return void this.host._showToast(this.host._t("ha_disabled"===e.kind?"toast.ha_disabled_add":"toast.ha_binding_unverified"));if("ha_disabled"===e.kind&&!0===s?.hidden&&!t.hideFromPlan)return this.host._markerDialog={...t,hideFromPlan:!0},void this.host._showToast(this.host._t("entity"===e.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device"))}const s=this.host._serverCfg;if(!s)return;const i=this.host._cfgRev,o=Ft(s);let a=JSON.parse(JSON.stringify(s));const n=a.markers||[],r=Ps(t.binding,t.devId,()=>"v_"+Date.now().toString(36)),l=t.devId,h=l?this.host._devices.find(t=>t.id===l):null,c=l?n.find(t=>t.id===l):null,d=!!c&&("string"==typeof c.area&&c.area.length>0||null===c.area&&!!c.space&&!!c.room_id),p="virtual"===t.binding||t.roomTouched||d,u="virtual"===t.binding||t.roomTouched?Ns(t.room):null;let _=d&&!t.roomTouched?c?.space||null:u?.space||null;const m=d&&!t.roomTouched?c?.area||null:u?.area||null,g=d&&!t.roomTouched?c?.room_id||null:u?.roomId||null,f=_||h?.space||null,b=f?this.host._spaceModelById(f):this.host._spaceModel();if(!b)return;const v=b.id;"virtual"!==t.binding||_||(_=v);let y={};if(t.radarTouched){if(t.radarRemove)y={radar:null};else if(t.radar){const e=ph(t.radar,b.cellCm||5);if(!e)return void this.host._showToast(this.host._t("radar.invalid"));y={radar:e}}}else c&&Object.prototype.hasOwnProperty.call(c,"radar")&&(y={radar:c.radar});this.host._markerDialog={...t,busy:!0};let $=null,w=!1;try{const c="virtual"===t.binding?[]:n.filter(e=>e.removed&&e.binding===t.binding).map(t=>t.id),d=c.length>0,u=Rs(t.binding,t.controls,this.host._bindingEntities(t.binding)),f=n.find(t=>t.id===r||t.id===l)?.vacuum||null,k={id:r,vacuum:f,...y,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle?t.angle:null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===e&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:u.length?u:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:!!t.hideFromPlan};p&&(k.space=_,k.area=m,k.room_id=g);const x=h?.marker?.room_id??null,S=t.roomTouched&&null!=h&&(h.space!==_||h.area!==m||x!==g);let M=!1;const C=t.uploadId||l;if(C&&C!==r&&k.pdfs?.length)try{const t=await this.host.hass.callWS({type:"houseplan/files/migrate",from_id:C,to_id:r}),e=t?.mapping||{};k.pdfs=Es(k.pdfs,C,r,e),M=Object.keys(e).length>0}catch(t){this.host._showToast(this.host._t("toast.files_migrate_failed",{err:this.host._errText(t)}))}a.markers=n,l&&l!==r&&(a.markers=Hs(a.markers,l,r)),l&&l!==r&&"derived_marker_state"===k.value_badge?.source?.kind&&k.value_badge.source.ref===`marker:${l}`&&(k.value_badge.source={kind:"derived_marker_state",ref:`marker:${r}`}),l&&l!==r&&"derived_marker_state"===k.value_source?.kind&&k.value_source.ref===`marker:${l}`&&(k.value_source={kind:"derived_marker_state",ref:`marker:${r}`}),a.markers=a.markers.filter(t=>t.id!==r&&t.id!==l&&("virtual"===k.binding||t.binding!==k.binding)),a.markers.push(k);const P=new Set(c);l&&l!==r&&P.add(l),P.delete(r),P.size&&a.settings?.marker_area_snapshot&&(a.settings={...a.settings,marker_area_snapshot:Os(a.settings.marker_area_snapshot,P)});let D=null;const I=l?this.host._layout[l]:null,T=I?{s:I.s||h?.space||this.host._space,x:I.x,y:I.y}:l&&h&&this.host._defPos[l]?this.host._normPos(h.space,this.host._defPos[l].x,this.host._defPos[l].y):null;if(!d&&T&&T.s===v)r===l&&this.host._layout[r]&&!S||(D={s:T.s,x:T.x,y:T.y});else if(d||!this.host._layout[r]||S){let t=b.vb[0]+b.vb[2]/2,e=b.vb[1]+b.vb[3]/2;const s=g?b.rooms.find(t=>t.id===g):m?b.rooms.find(t=>t.area===m):void 0;s&&([t,e]=this.host._roomCenter(s)),D=this.host._normPos(v,t,e)}if(this.host._serverCfg!==s||this.host._cfgRev!==i||Ft(s)!==o)return this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),void this.host._showToast(this.host._t("toast.conflict"));if(a=this._prepareConfigCandidate(a),$=this.host._adoption.beginOptimistic(s,a),this.host._serverCfg=a,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate(),this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.cancel(),await this._saveConfigNow($),w=!0,D){const t=Ls(D);this.host._layout={...this.host._layout,[r]:t},this.host._noteLayoutRev(await this.host.hass.callWS({type:"houseplan/layout/update",device_id:r,pos:t}))}const R=new Set(c);l&&l!==r&&R.add(l),R.delete(r);for(const t of R)delete this.host._layout[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{});M&&C&&await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:C}).catch(()=>{}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_saved"))}catch(t){!w&&$&&(this.host._rollbackOptimistic($),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteMarker(){const t=this.host._markerDialog;if(!t||t.busy||!t.devId)return;const e=t.devId?this.host._devices.find(e=>e.id===t.devId):null,s=this.host._markers.find(e=>e.id===t.devId);if(!e&&!s)return;const i=e?"virtual"===e.bindingKind?"virtual":e.bindingKind&&e.bindingRef?`${e.bindingKind}:${e.bindingRef}`:"":s.binding;if(!i)return;const o=t.name||this.host._t("device.fallback"),a=t.devId,n=await this.host._confirmDanger({key:"remove-marker",kind:"destructive",title:this.host._t("confirm.remove_marker_title"),message:this.host._t("confirm.remove_marker_body"),objectName:o,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._markerDialog;if(!n||!r||r.busy||r.devId!==a)return;const l=this.host._devices.find(t=>t.id===a),h=this.host._markers.find(t=>t.id===a);if(!l&&!h)return;const c=this.host._serverCfg;if(!c)return;c.markers=c.markers||[];const d=c.markers,p=l?"virtual"===l.bindingKind?"virtual":l.bindingKind&&l.bindingRef?`${l.bindingKind}:${l.bindingRef}`:"":h.binding;if(!p||p!==i)return;const u=Bs(c.markers,a,p,"virtual"===p);c.markers=Ws(u.markers,u.cleanupIds);const _=u.cleanupIds;_.size&&c.settings?.marker_area_snapshot&&(c.settings={...c.settings,marker_area_snapshot:Os(c.settings.marker_area_snapshot,_)}),this.host._markerDialog={...r,busy:!0};try{await this._saveConfigNow();for(const t of _){delete this.host._layout[t],delete this.host._defPos[t],this.host._dirtyPos.delete(t),this.host._sentPos.delete(t);const e=this.host._activityRt.get(t);e&&clearTimeout(e.timer),this.host._activityRt.delete(t),this.host._vacRt.delete(t),delete this.host._vacSrvTrails[t],await this.host.hass.callWS({type:"houseplan/layout/delete",device_id:t}).then(t=>this.host._noteLayoutRev(t)).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/files/cleanup",marker_id:t}).catch(()=>{}),await this.host.hass.callWS({type:"houseplan/trail/delete",marker_id:t}).catch(()=>{})}this.host._deviceInboxReturn&&(this.host._deviceInboxReturn={...this.host._deviceInboxReturn,tab:"readd",anchor:p}),this._closeMarkerDialog(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._infoCard?.id===a&&this.host._closeInfoCard(),this.host._selId===a&&(this.host._selId=null),this.host._drag?.id===a&&(this.host._drag=null),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.marker_removed"))}catch(t){this.host._serverCfg===c&&(c.markers=d),this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_openSpaceDialog(t,e){if(this.host._serverStorage&&this.host._serverCfg)if("edit"===t){const s=this.host._serverCfg.spaces.find(t=>t.id===e);if(!s)return;const i=js(s),o=s.settings?.custom_fill&&"object"==typeof s.settings.custom_fill?Gs(s.settings.custom_fill):null,a="none"===i.fill?{...o||qs,a:0}:o;this.host._spaceDialog={mode:t,spaceId:e,title:s.title,planUrl:s.plan_url||null,planFile:null,source:s.plan_url?"file":"draw",showBorders:i.showBorders,showNames:i.showNames,zeroWallStyle:Ks(s),displayTouched:!0,hideDecor:i.hideDecor,hideOpenings:i.hideOpenings,roomColor:i.color,roomOpacity:i.opacity,fillMode:"none"===i.fill?"custom":i.fill,customFill:a,glowEnabled:i.glow,bgColor:i.bgColor,bgMode:"static"===s.settings?.bg_mode||"daynight"===s.settings?.bg_mode?s.settings.bg_mode:null,northDeg:de({},s.settings),sunRays:"boolean"==typeof s.settings?.sun_rays?s.settings.sun_rays:null,tempMin:i.tempMin,tempMax:i.tempMax,showLqi:i.showLqi??this.host._config?.show_signal??!0,cardFontScale:i.cardFontScale,labelTemp:i.labelTemp,labelHum:i.labelHum,labelLqi:i.labelLqi,labelLight:i.labelLight,cellCm:Number(s.cell_cm)>0?Number(s.cell_cm):5,cellCmInput:Us(Number(s.cell_cm)>0?Number(s.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1}}else this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...Qs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Xs,roomOpacity:Ys,fillMode:"custom",customFill:{...qs,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Js,tempMax:Vs,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Zs(this.host._imperial),cellCmInput:Us(Zs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1};else this.host._showToast(this.host._t("toast.integration_missing"))}async _pickPlanFile(t){const e=t.target,s=e.files?.[0];if(!s||!this.host._spaceDialog)return;e.value="",this._decorAssetGuardReplace=null;const i=await vo(s);if("reject"===i.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===i.kind)return void(this.host._backdropGuard=i.state);const o=await yo(s,i.ext,s.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:o})}_renderBackdropGuard(){const t=this._decorAssetGuardReplace;return null!==t?$o(this.host,()=>{},()=>{this.host._backdropGuard=null,this._decorAssetGuardReplace=null},this.host.hass,(e,s)=>this._uploadDecorImage(e,s,t),(this.host._backdropGuard?.file.size||0)<=2097152)??d:$o(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??d}_useServerPlan(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let e=0;e<40;e++){const e=this.host._display(t);if(e){const s=await new Promise(t=>{const s=new Image;s.onload=()=>t(s.naturalWidth&&s.naturalHeight?s.naturalWidth/s.naturalHeight:0),s.onerror=()=>t(0),s.src=e}),i=this.host._spaceDialog;return i&&i.planUrl===t&&Number.isFinite(s)&&s>0?(this.host._spaceDialog={...i,savedAspect:s},s):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const e=this.host._spaceDialog,s=e?.saved?.find(e=>e.name===t);if(!e||!s||s.used_by.length||s.url===e.planUrl)return;const i=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),o=this.host._spaceDialog,a=o?.saved?.find(e=>e.name===t);if(i&&o&&a&&a.url===s.url&&a.modified===s.modified&&!a.used_by.length&&a.url!==o.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const e=this.host._spaceDialog;e?.saved&&(this.host._spaceDialog={...e,saved:e.saved.filter(e=>e.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return p`
    ${this.host._t("space.loading")}
    `;const e=t.saved||[];if(!e.length)return p`
    ${this.host._t("space.no_saved")}
    `;return p`
    ${e.map(e=>{return p`
    @@ -980,7 +980,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    `;var s})} -
    `}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const e="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const s="create"===t.mode?"s"+Date.now().toString(36):t.spaceId;let i=null;if("file"===t.source&&t.planFile){i={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:s,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let o=t.savedAspect||null;!i&&"file"===t.source&&t.planUrl&&!o&&this.host._aspectJob&&(o=await this.host._aspectJob||null);const a=this.host._serverCfg;let n;if("create"===t.mode)n=Qs(s,t.title.trim()),a.spaces.push(n);else{if(n=a.spaces.find(t=>t.id===s),!n)throw new Error("space "+s+" is gone from the config");n.title=t.title.trim()}i?(n.plan_url=i.url,n.plan_aspect=i.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==n.plan_url&&(n.plan_url=t.planUrl,n.plan_aspect=o),"draw"===t.source&&(n.plan_url=null,n.plan_aspect=null,delete n.plan_x,delete n.plan_y,delete n.plan_scale,delete n.plan_scale_x,delete n.plan_scale_y,delete n.plan_angle),n.settings={...n.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):Vs,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):Ks,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},n.zero_wall_style=t.zeroWallStyle,n.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(td,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(n.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length?this._openNextImport():e||this.host._importTotal>0?(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._showToast(this.host._t(e&&!this.host._importTotal?"toast.space_added_onboard":"import.done"))):(this.host._showToast("create"===t.mode?this.host._t("toast.space_added"):this.host._t("toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?this._setMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._saveNav())))}catch(t){"conflict"!==t?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const e=this.host._serverCfg;if(!e)return;const s=e.spaces.find(e=>e.id===t.spaceId),i=$o(e,this.host._layout||{},t.spaceId||""),o=1===e.spaces.length&&e.spaces[0]?.id===t.spaceId;if(i.count&&!o)return void(this.host._spaceDialog={...t,deleteBlockers:i.count});if(!s)return;const a=t.spaceId,n=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:wo(this.host._t("confirm.delete_space_body"),this.host._t("confirm.delete_space_vac_routes"),i.routeCount),objectName:s.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._spaceDialog,l=this.host._serverCfg;if(!n||!r||"edit"!==r.mode||r.busy||r.spaceId!==a||!l)return;if(!l.spaces.find(t=>t.id===a))return;const h=$o(l,this.host._layout||{},a),c=1===l.spaces.length&&l.spaces[0]?.id===a;if(!h.count||c){this.host._spaceDialog={...r,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:a,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,e]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:e,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...r,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===a&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){"conflict"!==t?.code&&"space_in_use"!==t?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=$o(e,this.host._layout||{},a),s=1===e.spaces.length&&e.spaces[0]?.id===a;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...r,deleteBlockers:h.count}}async _saveConfigNow(t=null){this.host._cfgEpoch++;try{await this._writeConfig(t)}catch(t){throw t?.physicalGeometryRolledBack?await this._reloadRejectedPhysicalWrite():"conflict"===t?.code&&await this.host._reloadConfigOnly(),t}}_saveSpaceCopy(){return Vl(this.host,{clearGeometryGesture:()=>this._clearGeometryGesture(),optimizeReferenceContext:()=>this._optimizeReferenceContext(!1),reportPreflightFailure:(t,e)=>this._reportPreflightFailure(t,e),saveConfigNow:t=>this._saveConfigNow(t),setMode:()=>this._setMode("plan"),showWallModelMigrationBlocked:t=>this._showWallModelMigrationBlocked(t)})}_startImport(){const t=this.host._importDialog;if(!t)return;const e=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,e.length?(this.host._importQueue=e,this.host._importTotal=e.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();void 0!==t&&(this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...Zs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Ys,roomOpacity:Js,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Vs,tempMax:Ks,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Xs(this.host._imperial),cellCmInput:qs(Xs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1})}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._showToast(this.host._t("import.done")))}_renderImportDialog(){const t=this.host._importDialog,e=t.floors.filter(t=>t.checked).length;return p``}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const e="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const s="create"===t.mode?"s"+Date.now().toString(36):t.spaceId;let i=null;if("file"===t.source&&t.planFile){i={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:s,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let o=t.savedAspect||null;!i&&"file"===t.source&&t.planUrl&&!o&&this.host._aspectJob&&(o=await this.host._aspectJob||null);const a=this.host._serverCfg;let n;if("create"===t.mode)n=ti(s,t.title.trim()),a.spaces.push(n);else{if(n=a.spaces.find(t=>t.id===s),!n)throw new Error("space "+s+" is gone from the config");n.title=t.title.trim()}i?(n.plan_url=i.url,n.plan_aspect=i.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==n.plan_url&&(n.plan_url=t.planUrl,n.plan_aspect=o),"draw"===t.source&&(n.plan_url=null,n.plan_aspect=null,delete n.plan_x,delete n.plan_y,delete n.plan_scale,delete n.plan_scale_x,delete n.plan_scale_y,delete n.plan_angle),n.settings={...n.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):Js,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):Vs,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},n.zero_wall_style=t.zeroWallStyle,n.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(ed,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(n.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length?this._openNextImport():e||this.host._importTotal>0?(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._showToast(this.host._t(e&&!this.host._importTotal?"toast.space_added_onboard":"import.done"))):(this.host._showToast("create"===t.mode?this.host._t("toast.space_added"):this.host._t("toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?this._setMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this._primeDrawWallField(),this.host._saveNav())))}catch(t){"conflict"!==t?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const e=this.host._serverCfg;if(!e)return;const s=e.spaces.find(e=>e.id===t.spaceId),i=wo(e,this.host._layout||{},t.spaceId||""),o=1===e.spaces.length&&e.spaces[0]?.id===t.spaceId;if(i.count&&!o)return void(this.host._spaceDialog={...t,deleteBlockers:i.count});if(!s)return;const a=t.spaceId,n=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:ko(this.host._t("confirm.delete_space_body"),this.host._t("confirm.delete_space_vac_routes"),i.routeCount),objectName:s.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),r=this.host._spaceDialog,l=this.host._serverCfg;if(!n||!r||"edit"!==r.mode||r.busy||r.spaceId!==a||!l)return;if(!l.spaces.find(t=>t.id===a))return;const h=wo(l,this.host._layout||{},a),c=1===l.spaces.length&&l.spaces[0]?.id===a;if(!h.count||c){this.host._spaceDialog={...r,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:a,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,e]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:e,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...r,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===a&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){"conflict"!==t?.code&&"space_in_use"!==t?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=wo(e,this.host._layout||{},a),s=1===e.spaces.length&&e.spaces[0]?.id===a;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...r,deleteBlockers:h.count}}async _saveConfigNow(t=null){this.host._cfgEpoch++;try{await this._writeConfig(t)}catch(t){throw t?.physicalGeometryRolledBack?await this._reloadRejectedPhysicalWrite():"conflict"===t?.code&&await this.host._reloadConfigOnly(),t}}_saveSpaceCopy(){return Jl(this.host,{clearGeometryGesture:()=>this._clearGeometryGesture(),optimizeReferenceContext:()=>this._optimizeReferenceContext(!1),reportPreflightFailure:(t,e)=>this._reportPreflightFailure(t,e),saveConfigNow:t=>this._saveConfigNow(t),setMode:()=>this._setMode("plan"),showWallModelMigrationBlocked:t=>this._showWallModelMigrationBlocked(t)})}_startImport(){const t=this.host._importDialog;if(!t)return;const e=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,e.length?(this.host._importQueue=e,this.host._importTotal=e.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();void 0!==t&&(this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...Qs(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:Xs,roomOpacity:Ys,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:Js,tempMax:Vs,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:Zs(this.host._imperial),cellCmInput:Us(Zs(this.host._imperial),this.host._imperial),cellCmTouched:!1,busy:!1})}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this._setMode("plan"),this.host._showToast(this.host._t("import.done")))}_renderImportDialog(){const t=this.host._importDialog,e=t.floors.filter(t=>t.checked).length;return p`this.host._importDialog=null}>
    ${this.host._t("import.hint")}
    @@ -1000,13 +1000,13 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("import.start",{n:e})}
    -
    `}_supportPatch(t,e){const s=this.host._supportDialog;if(!s||s.draftId!==t)return null;const i={...s,...e};return this.host._supportDialog=i,i}async _focusSupport(t){await this.host.updateComplete,this.host.renderRoot.querySelector(t)?.focus({preventScroll:!0})}_updateSupportDraft(t,e){const s=this.host._supportDialog;if(!s||"building"===s.status||"sending"===s.status||"success"===s.status)return;const i={...s,[t]:e},o=xc({...i,attach:!1,preview:null});"message_required"===o&&"validation.message_required"===s.errorCode||"message_too_long"===o||"contact_too_long"===o?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:`validation.${o}`}):i.attach&&i.preview&&i.preview.expiresAt<=Date.now()?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:"support_preview_expired"}):this._supportPatch(s.draftId,{[t]:e,status:i.attach&&i.preview?"ready":"idle",errorCode:""})}async _discardSupportPreview(t){if(t)try{await this.host.hass.callWS({type:"houseplan/support/preview/discard",token:t})}catch{}}async _closeSupportDialog(){const t=this.host._supportDialog;if(t){if("building"===t.status||"sending"===t.status){const t=l(this.host.hass,this.host._config?.language);if(!await this.host._confirmDanger({key:"close-support-busy",kind:"warning",title:Ro(t,"support.close_busy_title"),message:Ro(t,"support.close_busy_body"),confirmLabel:this.host._t("btn.close"),cancelLabel:this.host._t("btn.cancel")}))return await this.host.updateComplete,void this.host.renderRoot.querySelector("#support-dialog")?.rejectClose()}clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this.host._supportDialog=null,t.preview?.token&&"success"!==t.status&&this._discardSupportPreview(t.preview.token)}}_scheduleSupportExpiry(t,e){clearTimeout(this._supportExpiryTimer);const s=Math.max(0,e.expiresAt-Date.now());this._supportExpiryTimer=window.setTimeout(()=>{const s=this.host._supportDialog;s&&s.draftId===t&&s.preview?.token===e.token&&s.attach&&"success"!==s.status&&"sending"!==s.status&&this._supportPatch(t,{status:"error",errorCode:"support_preview_expired"})},Math.min(s+20,2147483647))}_supportFacts(){const t=this.host._haRegistry;return Mc({userAgent:globalThis.navigator?.userAgent||"",language:l(this.host.hass,this.host._config?.language),registryAccess:t.access,registryLastSuccess:t.lastSuccess})}_supportPreviewRequestIsCurrent(t,e){const s=this.host._supportDialog;return e===this._supportPreviewGeneration&&s?.draftId===t&&s.attach}async _buildSupportPreview(t){const e=this.host._supportDialog;if(!e||e.draftId!==t||!e.attach||!yc(this.host._haSupportApi))return;const s=++this._supportPreviewGeneration;this._supportPatch(t,{status:"building",errorCode:""});let i="";try{const e=await this.host.hass.callWS({type:"houseplan/support/preview",card_version:ti(Yc),...this._supportFacts(),draft_id:t}),o=e&&"object"==typeof e?e:{},a=Date.now(),n="string"==typeof o.text?o.text:"",r=Number(o.size),l=Number(o.expires_in),h=Number(o.spaces),c=String(o.token||"");/^[0-9a-f]{48}$/.test(c)&&(i=c);const d=String(o.sha256||""),p=Number(o.version),u=String(o.format||""),_=(new TextEncoder).encode(n).byteLength;if(!/^[0-9a-f]{48}$/.test(c)||!/^[0-9a-f]{64}$/.test(d)||"houseplan-support-package"!==u||1!==p||!Number.isInteger(r)||r!==_||!Number.isInteger(h)||h<0||!Number.isFinite(l)||l<=0||l>600||!n.endsWith("\n"))throw{code:"support_rejected"};const m={token:c,expiresAt:a+1e3*l,size:r,sha256:d,spaces:h,format:u,version:p,text:n,preparedAt:a};if(!this._supportPreviewRequestIsCurrent(t,s))return i="",void this._discardSupportPreview(c);if(!this._supportPatch(t,{status:"ready",preview:m,errorCode:"",rawOpen:!1}))return i="",void this._discardSupportPreview(c);i="",this._scheduleSupportExpiry(t,m)}catch(e){if(i){const t=i;i="",this._discardSupportPreview(t)}if(!this._supportPreviewRequestIsCurrent(t,s))return;if(!this._supportPatch(t,{status:"error",errorCode:Cc(e)}))return;this._focusSupport("#support-error")}}async _setSupportAttachment(t){const e=this.host._supportDialog;if(!e||"sending"===e.status||"success"===e.status)return;const s=e.preview?.token||"";if(!t)return this._supportPreviewGeneration+=1,clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPatch(e.draftId,{attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:""}),void(s&&this._discardSupportPreview(s));this._supportPatch(e.draftId,{attach:!0,errorCode:""}),await this._buildSupportPreview(e.draftId)}async _refreshSupportPreview(){const t=this.host._supportDialog;t&&t.attach&&"building"!==t.status&&"sending"!==t.status&&await this._buildSupportPreview(t.draftId)}_downloadSupportPreview(){const t=this.host._supportDialog?.preview;if(!t)return;const e=new Blob([t.text],{type:"application/json;charset=utf-8"}),s=URL.createObjectURL(e),i=document.createElement("a");i.href=s,i.download=`houseplan-support-${t.sha256.slice(0,12)}.json`,i.style.display="none",document.body.append(i),i.click(),i.remove(),window.setTimeout(()=>URL.revokeObjectURL(s),0)}async _copySupportText(t,e){const s=l(this.host.hass,this.host._config?.language);try{await navigator.clipboard.writeText(t),this.host._showToast(Ro(s,e))}catch{this.host._showToast(Ro(s,"support.copy_failed"))}}async _submitSupport(){const t=this.host._supportDialog;if(!t||!yc(this.host._haSupportApi))return;const e=xc(t);if(e)return this._supportPatch(t.draftId,{status:"error",errorCode:`validation.${e}`}),void this._focusSupport("#support-message");if(!Sc(t))return;const s=wc(t),i=this._supportPatch(t.draftId,{status:"sending",errorCode:"",idempotencyKey:s.idempotencyKey,submissionFingerprint:s.fingerprint});if(i)try{const e=await this.host.hass.callWS({type:"houseplan/support/submit",message:i.message.trim(),contact:i.contact.trim(),...i.attach&&i.preview?{preview_token:i.preview.token}:{},idempotency_key:i.idempotencyKey}),s=e&&"object"==typeof e&&"report_id"in e?String(e.report_id||""):"";if(!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(s))throw{code:"support_unavailable"};if(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,!this._supportPatch(t.draftId,{status:"success",reportId:s,errorCode:""}))return;this._focusSupport("#support-receipt")}catch(e){if(!this._supportPatch(t.draftId,{status:"error",errorCode:Cc(e)}))return;this._focusSupport("#support-error")}}_supportErrorText(t){const e=l(this.host.hass,this.host._config?.language);if(t.errorCode.startsWith("validation.")){return Ro(e,`support.validation.${t.errorCode.slice(11)}`)}return Ro(e,`support.error.${t.errorCode||"support_unavailable"}`)}_supportMessageKeydown(t){"Enter"===t.key&&(t.ctrlKey||t.metaKey)&&(t.preventDefault(),this._submitSupport())}_renderSupportDialog(){const t=this.host._supportDialog,e=l(this.host.hass,this.host._config?.language),s="ru"===e?"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.ru.md":"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.md",i=yc(this.host._haSupportApi),o=(t,s)=>Ro(e,t,s),a="building"===t.status||"sending"===t.status,n=xc(t),r=t.preview?Math.max(0,Math.floor((Date.now()-t.preview.preparedAt)/6e4)):0,h="error"===t.status&&!t.errorCode.startsWith("validation."),c="validation.contact_too_long"===t.errorCode,u="validation.message_required"===t.errorCode||"validation.message_too_long"===t.errorCode;return p``}_supportPatch(t,e){const s=this.host._supportDialog;if(!s||s.draftId!==t)return null;const i={...s,...e};return this.host._supportDialog=i,i}async _focusSupport(t){await this.host.updateComplete,this.host.renderRoot.querySelector(t)?.focus({preventScroll:!0})}_updateSupportDraft(t,e){const s=this.host._supportDialog;if(!s||"building"===s.status||"sending"===s.status||"success"===s.status)return;const i={...s,[t]:e},o=Sc({...i,attach:!1,preview:null});"message_required"===o&&"validation.message_required"===s.errorCode||"message_too_long"===o||"contact_too_long"===o?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:`validation.${o}`}):i.attach&&i.preview&&i.preview.expiresAt<=Date.now()?this._supportPatch(s.draftId,{[t]:e,status:"error",errorCode:"support_preview_expired"}):this._supportPatch(s.draftId,{[t]:e,status:i.attach&&i.preview?"ready":"idle",errorCode:""})}async _discardSupportPreview(t){if(t)try{await this.host.hass.callWS({type:"houseplan/support/preview/discard",token:t})}catch{}}async _closeSupportDialog(){const t=this.host._supportDialog;if(t){if("building"===t.status||"sending"===t.status){const t=l(this.host.hass,this.host._config?.language);if(!await this.host._confirmDanger({key:"close-support-busy",kind:"warning",title:Ao(t,"support.close_busy_title"),message:Ao(t,"support.close_busy_body"),confirmLabel:this.host._t("btn.close"),cancelLabel:this.host._t("btn.cancel")}))return await this.host.updateComplete,void this.host.renderRoot.querySelector("#support-dialog")?.rejectClose()}clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this.host._supportDialog=null,t.preview?.token&&"success"!==t.status&&this._discardSupportPreview(t.preview.token)}}_scheduleSupportExpiry(t,e){clearTimeout(this._supportExpiryTimer);const s=Math.max(0,e.expiresAt-Date.now());this._supportExpiryTimer=window.setTimeout(()=>{const s=this.host._supportDialog;s&&s.draftId===t&&s.preview?.token===e.token&&s.attach&&"success"!==s.status&&"sending"!==s.status&&this._supportPatch(t,{status:"error",errorCode:"support_preview_expired"})},Math.min(s+20,2147483647))}_supportFacts(){const t=this.host._haRegistry;return Cc({userAgent:globalThis.navigator?.userAgent||"",language:l(this.host.hass,this.host._config?.language),registryAccess:t.access,registryLastSuccess:t.lastSuccess})}_supportPreviewRequestIsCurrent(t,e){const s=this.host._supportDialog;return e===this._supportPreviewGeneration&&s?.draftId===t&&s.attach}async _buildSupportPreview(t){const e=this.host._supportDialog;if(!e||e.draftId!==t||!e.attach||!$c(this.host._haSupportApi))return;const s=++this._supportPreviewGeneration;this._supportPatch(t,{status:"building",errorCode:""});let i="";try{const e=await this.host.hass.callWS({type:"houseplan/support/preview",card_version:ei(Xc),...this._supportFacts(),draft_id:t}),o=e&&"object"==typeof e?e:{},a=Date.now(),n="string"==typeof o.text?o.text:"",r=Number(o.size),l=Number(o.expires_in),h=Number(o.spaces),c=String(o.token||"");/^[0-9a-f]{48}$/.test(c)&&(i=c);const d=String(o.sha256||""),p=Number(o.version),u=String(o.format||""),_=(new TextEncoder).encode(n).byteLength;if(!/^[0-9a-f]{48}$/.test(c)||!/^[0-9a-f]{64}$/.test(d)||"houseplan-support-package"!==u||1!==p||!Number.isInteger(r)||r!==_||!Number.isInteger(h)||h<0||!Number.isFinite(l)||l<=0||l>600||!n.endsWith("\n"))throw{code:"support_rejected"};const m={token:c,expiresAt:a+1e3*l,size:r,sha256:d,spaces:h,format:u,version:p,text:n,preparedAt:a};if(!this._supportPreviewRequestIsCurrent(t,s))return i="",void this._discardSupportPreview(c);if(!this._supportPatch(t,{status:"ready",preview:m,errorCode:"",rawOpen:!1}))return i="",void this._discardSupportPreview(c);i="",this._scheduleSupportExpiry(t,m)}catch(e){if(i){const t=i;i="",this._discardSupportPreview(t)}if(!this._supportPreviewRequestIsCurrent(t,s))return;if(!this._supportPatch(t,{status:"error",errorCode:Pc(e)}))return;this._focusSupport("#support-error")}}async _setSupportAttachment(t){const e=this.host._supportDialog;if(!e||"sending"===e.status||"success"===e.status)return;const s=e.preview?.token||"";if(!t)return this._supportPreviewGeneration+=1,clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPatch(e.draftId,{attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:""}),void(s&&this._discardSupportPreview(s));this._supportPatch(e.draftId,{attach:!0,errorCode:""}),await this._buildSupportPreview(e.draftId)}async _refreshSupportPreview(){const t=this.host._supportDialog;t&&t.attach&&"building"!==t.status&&"sending"!==t.status&&await this._buildSupportPreview(t.draftId)}_downloadSupportPreview(){const t=this.host._supportDialog?.preview;if(!t)return;const e=new Blob([t.text],{type:"application/json;charset=utf-8"}),s=URL.createObjectURL(e),i=document.createElement("a");i.href=s,i.download=`houseplan-support-${t.sha256.slice(0,12)}.json`,i.style.display="none",document.body.append(i),i.click(),i.remove(),window.setTimeout(()=>URL.revokeObjectURL(s),0)}async _copySupportText(t,e){const s=l(this.host.hass,this.host._config?.language);try{await navigator.clipboard.writeText(t),this.host._showToast(Ao(s,e))}catch{this.host._showToast(Ao(s,"support.copy_failed"))}}async _submitSupport(){const t=this.host._supportDialog;if(!t||!$c(this.host._haSupportApi))return;const e=Sc(t);if(e)return this._supportPatch(t.draftId,{status:"error",errorCode:`validation.${e}`}),void this._focusSupport("#support-message");if(!Mc(t))return;const s=kc(t),i=this._supportPatch(t.draftId,{status:"sending",errorCode:"",idempotencyKey:s.idempotencyKey,submissionFingerprint:s.fingerprint});if(i)try{const e=await this.host.hass.callWS({type:"houseplan/support/submit",message:i.message.trim(),contact:i.contact.trim(),...i.attach&&i.preview?{preview_token:i.preview.token}:{},idempotency_key:i.idempotencyKey}),s=e&&"object"==typeof e&&"report_id"in e?String(e.report_id||""):"";if(!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(s))throw{code:"support_unavailable"};if(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,!this._supportPatch(t.draftId,{status:"success",reportId:s,errorCode:""}))return;this._focusSupport("#support-receipt")}catch(e){if(!this._supportPatch(t.draftId,{status:"error",errorCode:Pc(e)}))return;this._focusSupport("#support-error")}}_supportErrorText(t){const e=l(this.host.hass,this.host._config?.language);if(t.errorCode.startsWith("validation.")){return Ao(e,`support.validation.${t.errorCode.slice(11)}`)}return Ao(e,`support.error.${t.errorCode||"support_unavailable"}`)}_supportMessageKeydown(t){"Enter"===t.key&&(t.ctrlKey||t.metaKey)&&(t.preventDefault(),this._submitSupport())}_renderSupportDialog(){const t=this.host._supportDialog,e=l(this.host.hass,this.host._config?.language),s="ru"===e?"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.ru.md":"https://github.com/Matysh/houseplan-card/blob/main/docs/USER-GUIDE.md",i=$c(this.host._haSupportApi),o=(t,s)=>Ao(e,t,s),a="building"===t.status||"sending"===t.status,n=Sc(t),r=t.preview?Math.max(0,Math.floor((Date.now()-t.preview.preparedAt)/6e4)):0,h="error"===t.status&&!t.errorCode.startsWith("validation."),c="validation.contact_too_long"===t.errorCode,u="validation.message_required"===t.errorCode||"validation.message_too_long"===t.errorCode;return p`{this._closeSupportDialog()}}>

    ${o("support.about_group")}

    -
    ${this.host._t("gs.about_version",{v:ti(Yc)})}
    +
    ${this.host._t("gs.about_version",{v:ei(Xc)})}
    - `;var _}_preflightDiagnostics(t,e){const s=new Map((e?.spaces||[]).map(t=>[String(t?.id||""),t]));return{kind:"houseplan-optimize-preflight",origin:"runtime",cardVersion:ti(Yc),checkedAt:(new Date).toISOString(),preflightFingerprint:t.fingerprint,failures:t.failures.map(t=>({spaceId:t.spaceId,displayName:t.displayName,reason:t.reason,detail:t.detail??null,spaceGeometryFingerprint:s.has(t.spaceId)?Y(s.get(t.spaceId)):null}))}}_reportPreflightFailure(t,e){t.ok||t.fingerprint===this.host._reportedPreflightFingerprint||(this.host._reportedPreflightFingerprint=t.fingerprint,console.warn("[houseplan] optimize preflight failed",this._preflightDiagnostics(t,e)))}_preflightVersionsDiffer(){const t=this.host._haIntegrationVersion;return"string"==typeof t&&t.length>0&&t!==ti(Yc)}async _copyPreflightDiagnostics(){const t=this.host._alignDialog?.preflight;if(!t||t.ok)return;const e=JSON.stringify(this._preflightDiagnostics(t,this.host._alignDialog?.config??null),null,2);try{await navigator.clipboard.writeText(e),this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.preflight_copied"))}catch{this.host._preflightClipboardFallback=e}}_checkOptimizeGeometryImpl(t){return ei(t,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)})})}_checkSpacePhysicalGeometryImpl(t,e,s){return si(t,e,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)}),captureWallGeometry:s?(t,e)=>s(e):void 0})}_optimizeReferenceContext(t){const e=this.host._haRegistry,s=this.host._fullRegistryHass,i={},o=(...t)=>{for(const e of t){const t=String(e||"").trim();if(t)return t}return""};for(const[t,s]of Object.entries(e.devices||{}))i[t]=o(s?.name_by_user,s?.name,s?.model);for(const[t,s]of Object.entries(e.entities||{}))i[`lg_${t}`]=o(this.host.hass?.states?.[t]?.attributes?.friendly_name,s?.name,s?.original_name);for(const t of this.host._devices)i[t.id]=o(t.name,i[t.id]);for(const t of this.host._serverCfg?.markers||[]){const e=String(t.binding||"").indexOf(":"),a=e>0?t.binding.slice(0,e):"",n=e>0?t.binding.slice(e+1):"",r="device"===a?s?.devices?.[n]:"entity"===a?s?.entities?.[n]:null;i[t.id]=o(t.name,"device"===a?r?.name_by_user:null,r?.name,"entity"===a?this.host.hass?.states?.[n]?.attributes?.friendly_name:null,i[t.id])}return{effectiveAreaByMarker:Object.fromEntries(this.host._devices.filter(t=>!t.virtual&&!!t.area).map(t=>[t.id,t.area])),ownerRoster:{authoritative:e.authoritative,deviceIds:Object.keys(e.devices||{}),entityIds:[...new Set([...Object.keys(e.entities||{}),...Object.keys(this.host.hass?.states||{})])],names:i},removeLiveMissingPositions:t}}_previewAlignDialog(t){if(!this.host._norm||!this.host._serverCfg)return;const e=this.host._serverCfg.spaces||[];let s;try{s=Al(this.host._serverCfg,this.host._layout||{},this._optimizeReferenceContext(t))}catch(t){return void this._showWallModelMigrationBlocked(t)}const i=s.changed?this.host._checkOptimizeGeometry(s.config):null;i&&this._reportPreflightFailure(i,s.config);const o=Math.ceil(10*s.report.maxShiftCm)/10,a=e.find(t=>null!=t?.id&&String(t.id)===s.report.maxSpace),n=e.length>1&&a?String(a.title||a.id):"";this.host._preflightClipboardFallback=null,this.host._alignDialog={report:s.report,config:s.config,layout:s.layout,cm:o,where:n,preflight:i,changed:s.changed,busy:!1,removeLiveMissingPositions:t}}async _runAlignToGrid(){let t=this.host._alignDialog;if(!t||t.busy||!this.host._serverCfg||!t.changed||!t.preflight?.ok)return;const e=Ft(t.config);if(t.preflight.fingerprint!==e){const e=this.host._checkOptimizeGeometry(t.config);if(this._reportPreflightFailure(e,t.config),t={...t,preflight:e},this.host._alignDialog=t,!e.ok)return}this._clearGeometryGesture(),this.host._alignDialog={...t,busy:!0};try{await qr(this.host,t.config,t.layout),this.host._alignDialog=null,this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.align_done",{n:String(t.report.moved),m:String(t.report.migrated+t.report.canonicalized+t.report.coordsCanonicalized+t.report.latticeCoordinatesCanonicalized+t.report.wallsMerged+t.report.spansMerged+t.report.partitionsMerged+t.report.partitionsReconciled+t.report.openingsRehosted+t.report.wallsStraightened),r:String(t.report.spaceRefsRemapped+t.report.roomRefsRemapped+t.report.positionsRemapped+t.report.markersDetached+t.report.orphanRoomLabelsRemoved+t.report.orphanDevicePositionsRemoved+t.report.orphanGroupPositionsRemoved)}))}catch(t){if(this.host._alignDialog&&(this.host._alignDialog={...this.host._alignDialog,busy:!1}),"wall_model_client_outdated"===t?.code)return void this.host._showToast(this.host._t("toast.wall_model_client_outdated"));"conflict"===t?.code&&await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _undoPlanOptimization(){if(!this.host._canOptimizeUndo||this.host._optimizeUndoBusy)return;const t=this.host._undoKind;this._clearGeometryGesture(),this.host._optimizeUndoBusy=!0,this.host.requestUpdate();try{await this.host.hass.callWS({type:"houseplan/plan/optimize_undo",expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[e,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:e,layResp:s,reason:"optimize-undo",profile:"post-write"})).status)return;this.host._geometryHistory.clear(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._cacheSnapshot(),this.host.requestUpdate(),this.host._showToast(this.host._t("import"===t?"backup.import_undone":"gs.optimize_undone"))}catch(t){this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}finally{this.host._optimizeUndoBusy=!1,this.host.requestUpdate()}}async _runBackupExport(){const t=this.host._backupExportDialog;if(t&&!t.busy){this.host._backupExportDialog={...t,busy:!0,error:""};try{const e=await this.host.hass.callWS({type:"houseplan/export/create",kind:t.kind,space_id:"space"===t.kind?this.host._space:void 0,..."space"===t.kind&&t.planOnly?{plan_only:!0}:{},card_version:ti(Yc)}),s=new Blob([JSON.stringify(e.document,null,2)+"\n"],{type:"application/json;charset=utf-8"}),i=URL.createObjectURL(s),o=document.createElement("a");o.href=i,o.download=e.filename||`houseplan-${t.kind}.json`,o.style.display="none",document.body.append(o),o.click(),o.remove(),window.setTimeout(()=>URL.revokeObjectURL(i),0),this.host._backupExportDialog=null,this.host._showToast(this.host._t("backup.export_done"))}catch(t){this.host._backupExportDialog&&(this.host._backupExportDialog={...this.host._backupExportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _pickBackupImport(t){const e=t.target,s=e.files?.[0];if(e.value="",s){this.host._settingsDialog=null,this.host._backupImportDialog={filename:s.name,size:s.size,token:"",preview:null,expectedConfigRev:this.host._cfgRev,expectedLayoutRev:this.host._layoutRev,duplicatePolicy:"skip",confirmMissing:!1,busy:!0,error:""};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),await this.host._writeChain,this.host._persistLayout.pending()&&this.host._persistLayout.flush();const t="/api/houseplan/import/preview?duplicate_policy=skip",e={method:"POST",body:s,headers:{"content-type":"application/json"}},i=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth(t,e):await fetch(t,{...e,headers:{...e.headers,...this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}}),o=await i.json().catch(()=>({}));if(!i.ok||o.error)throw Object.assign(new Error(o.message||o.error||`HTTP ${i.status}`),{code:o.error});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,token:o.token,preview:o.preview,expectedConfigRev:o.expected_config_rev,expectedLayoutRev:o.expected_layout_rev,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _setBackupDuplicatePolicy(t){const e=this.host._backupImportDialog;if(e&&!e.busy&&e.token&&t!==e.duplicatePolicy){this.host._backupImportDialog={...e,duplicatePolicy:t,busy:!0,error:""};try{const s=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:e.token,duplicate_policy:t});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,preview:{...e.preview,...s.preview},expectedConfigRev:s.expected_config_rev,expectedLayoutRev:s.expected_layout_rev,confirmMissing:!1,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,duplicatePolicy:e.duplicatePolicy,preview:e.preview,confirmMissing:e.confirmMissing,busy:!1,error:this._backupErrorText(t)})}}}async _applyBackupImport(){const t=this.host._backupImportDialog;if(!t||t.busy||!t.token||!t.preview)return;if(t.preview.confirmation_required&&!t.confirmMissing)return;this.host._backupImportDialog={...t,busy:!0,error:""};const e=this.host._space;try{const s=await this.host.hass.callWS({type:"houseplan/import/apply",token:t.token,expected_config_rev:t.expectedConfigRev,expected_layout_rev:t.expectedLayoutRev,duplicate_policy:t.duplicatePolicy,confirm_missing_content:t.confirmMissing}),[i,o]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:i,layResp:o,reason:"import-apply",profile:"post-write"})).status)return this.host._backupImportDialog={...t,busy:!1,error:""},void this.host.requestUpdate();this.host._geometryHistory.clear(),this.host._dirtyPos.clear(),this.host._sentPos.clear(),this.host._defPos={},this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._visibleDeviceSnapshot=null,this.host._candidateDeviceSnapshot=null,this.host._stagedDeviceSnapshotToken=-1,this.host._capturedSnapshotConfigEpoch=-1,this.host._regSignature="",this.host._signer.invalidate(this.host.hass),this.host._resign(),this.host._maybeRebuildDevices();const a=this.host._serverCfg?.spaces||[],n="space"===s.kind&&s.space_id?s.space_id:a.some(t=>t.id===e)?e:a[0]?.id||this.host._space;this.host._hasFixedFloor?this.host._adoptInitialSpace(this.host._model,!0):this.host._commitSpace(n),this.host._backupImportDialog=null,this.host._cacheSnapshot(),this.host.requestUpdate();const r="space"===s.kind?t.preview.counts:s.counts;this.host._showToast(this.host._t("space"===s.kind?"backup.space_done":"backup.full_done",{spaces:String(r?.spaces||0),rooms:String(r?.rooms||0),markers:String(r?.markers||0),refs:String(s.repaired_target_refs||0)}))}catch(t){if("conflict"===t?.code&&this.host._backupImportDialog?.token)try{const t=this.host._backupImportDialog,e=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:t.token,duplicate_policy:t.duplicatePolicy});return void(this.host._backupImportDialog={...t,preview:{...t.preview,...e.preview},expectedConfigRev:e.expected_config_rev,expectedLayoutRev:e.expected_layout_rev,confirmMissing:!1,busy:!1,error:this.host._t("backup.revalidated")})}catch(e){t=e}this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}_renderBackupExportDialog(){const t=this.host._backupExportDialog,e=(this.host._serverCfg?.spaces||[]).find(t=>t.id===this.host._space);return p``;var _}_preflightDiagnostics(t,e){const s=new Map((e?.spaces||[]).map(t=>[String(t?.id||""),t]));return{kind:"houseplan-optimize-preflight",origin:"runtime",cardVersion:ei(Xc),checkedAt:(new Date).toISOString(),preflightFingerprint:t.fingerprint,failures:t.failures.map(t=>({spaceId:t.spaceId,displayName:t.displayName,reason:t.reason,detail:t.detail??null,spaceGeometryFingerprint:s.has(t.spaceId)?Y(s.get(t.spaceId)):null}))}}_reportPreflightFailure(t,e){t.ok||t.fingerprint===this.host._reportedPreflightFingerprint||(this.host._reportedPreflightFingerprint=t.fingerprint,console.warn("[houseplan] optimize preflight failed",this._preflightDiagnostics(t,e)))}_preflightVersionsDiffer(){const t=this.host._haIntegrationVersion;return"string"==typeof t&&t.length>0&&t!==ei(Xc)}async _copyPreflightDiagnostics(){const t=this.host._alignDialog?.preflight;if(!t||t.ok)return;const e=JSON.stringify(this._preflightDiagnostics(t,this.host._alignDialog?.config??null),null,2);try{await navigator.clipboard.writeText(e),this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.preflight_copied"))}catch{this.host._preflightClipboardFallback=e}}_checkOptimizeGeometryImpl(t){return si(t,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)})})}_checkSpacePhysicalGeometryImpl(t,e,s){return ii(t,e,{fallbackSpaceName:t=>this.host._t("gs.align_preflight_space",{n:String(t)}),captureWallGeometry:s?(t,e)=>s(e):void 0})}_optimizeReferenceContext(t){const e=this.host._haRegistry,s=this.host._fullRegistryHass,i={},o=(...t)=>{for(const e of t){const t=String(e||"").trim();if(t)return t}return""};for(const[t,s]of Object.entries(e.devices||{}))i[t]=o(s?.name_by_user,s?.name,s?.model);for(const[t,s]of Object.entries(e.entities||{}))i[`lg_${t}`]=o(this.host.hass?.states?.[t]?.attributes?.friendly_name,s?.name,s?.original_name);for(const t of this.host._devices)i[t.id]=o(t.name,i[t.id]);for(const t of this.host._serverCfg?.markers||[]){const e=String(t.binding||"").indexOf(":"),a=e>0?t.binding.slice(0,e):"",n=e>0?t.binding.slice(e+1):"",r="device"===a?s?.devices?.[n]:"entity"===a?s?.entities?.[n]:null;i[t.id]=o(t.name,"device"===a?r?.name_by_user:null,r?.name,"entity"===a?this.host.hass?.states?.[n]?.attributes?.friendly_name:null,i[t.id])}return{effectiveAreaByMarker:Object.fromEntries(this.host._devices.filter(t=>!t.virtual&&!!t.area).map(t=>[t.id,t.area])),ownerRoster:{authoritative:e.authoritative,deviceIds:Object.keys(e.devices||{}),entityIds:[...new Set([...Object.keys(e.entities||{}),...Object.keys(this.host.hass?.states||{})])],names:i},removeLiveMissingPositions:t}}_previewAlignDialog(t){if(!this.host._norm||!this.host._serverCfg)return;const e=this.host._serverCfg.spaces||[];let s;try{s=Fl(this.host._serverCfg,this.host._layout||{},this._optimizeReferenceContext(t))}catch(t){return void this._showWallModelMigrationBlocked(t)}const i=s.changed?this.host._checkOptimizeGeometry(s.config):null;i&&this._reportPreflightFailure(i,s.config);const o=Math.ceil(10*s.report.maxShiftCm)/10,a=e.find(t=>null!=t?.id&&String(t.id)===s.report.maxSpace),n=e.length>1&&a?String(a.title||a.id):"";this.host._preflightClipboardFallback=null,this.host._alignDialog={report:s.report,config:s.config,layout:s.layout,cm:o,where:n,preflight:i,changed:s.changed,busy:!1,removeLiveMissingPositions:t}}async _runAlignToGrid(){let t=this.host._alignDialog;if(!t||t.busy||!this.host._serverCfg||!t.changed||!t.preflight?.ok)return;const e=Ft(t.config);if(t.preflight.fingerprint!==e){const e=this.host._checkOptimizeGeometry(t.config);if(this._reportPreflightFailure(e,t.config),t={...t,preflight:e},this.host._alignDialog=t,!e.ok)return}this._clearGeometryGesture(),this.host._alignDialog={...t,busy:!0};try{await Ur(this.host,t.config,t.layout),this.host._alignDialog=null,this.host._preflightClipboardFallback=null,this.host._showToast(this.host._t("gs.align_done",{n:String(t.report.moved),m:String(t.report.migrated+t.report.canonicalized+t.report.coordsCanonicalized+t.report.latticeCoordinatesCanonicalized+t.report.wallsMerged+t.report.spansMerged+t.report.partitionsMerged+t.report.partitionsReconciled+t.report.openingsRehosted+t.report.wallsStraightened),r:String(t.report.spaceRefsRemapped+t.report.roomRefsRemapped+t.report.positionsRemapped+t.report.markersDetached+t.report.orphanRoomLabelsRemoved+t.report.orphanDevicePositionsRemoved+t.report.orphanGroupPositionsRemoved)}))}catch(t){if(this.host._alignDialog&&(this.host._alignDialog={...this.host._alignDialog,busy:!1}),"wall_model_client_outdated"===t?.code)return void this.host._showToast(this.host._t("toast.wall_model_client_outdated"));"conflict"===t?.code&&await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _undoPlanOptimization(){if(!this.host._canOptimizeUndo||this.host._optimizeUndoBusy)return;const t=this.host._undoKind;this._clearGeometryGesture(),this.host._optimizeUndoBusy=!0,this.host.requestUpdate();try{await this.host.hass.callWS({type:"houseplan/plan/optimize_undo",expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[e,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:e,layResp:s,reason:"optimize-undo",profile:"post-write"})).status)return;this.host._geometryHistory.clear(),this.host._cancelDeviceDrag(),this.host._devicePositionHistory.clear(),this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._cacheSnapshot(),this.host.requestUpdate(),this.host._showToast(this.host._t("import"===t?"backup.import_undone":"gs.optimize_undone"))}catch(t){this.host._canOptimizeUndo=!1,this.host._undoKind=null,this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}finally{this.host._optimizeUndoBusy=!1,this.host.requestUpdate()}}async _runBackupExport(){const t=this.host._backupExportDialog;if(t&&!t.busy){this.host._backupExportDialog={...t,busy:!0,error:""};try{const e=await this.host.hass.callWS({type:"houseplan/export/create",kind:t.kind,space_id:"space"===t.kind?this.host._space:void 0,..."space"===t.kind&&t.planOnly?{plan_only:!0}:{},card_version:ei(Xc)}),s=new Blob([JSON.stringify(e.document,null,2)+"\n"],{type:"application/json;charset=utf-8"}),i=URL.createObjectURL(s),o=document.createElement("a");o.href=i,o.download=e.filename||`houseplan-${t.kind}.json`,o.style.display="none",document.body.append(o),o.click(),o.remove(),window.setTimeout(()=>URL.revokeObjectURL(i),0),this.host._backupExportDialog=null,this.host._showToast(this.host._t("backup.export_done"))}catch(t){this.host._backupExportDialog&&(this.host._backupExportDialog={...this.host._backupExportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _pickBackupImport(t){const e=t.target,s=e.files?.[0];if(e.value="",s){this.host._settingsDialog=null,this.host._backupImportDialog={filename:s.name,size:s.size,token:"",preview:null,expectedConfigRev:this.host._cfgRev,expectedLayoutRev:this.host._layoutRev,duplicatePolicy:"skip",confirmMissing:!1,busy:!0,error:""};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),await this.host._writeChain,this.host._persistLayout.pending()&&this.host._persistLayout.flush();const t="/api/houseplan/import/preview?duplicate_policy=skip",e={method:"POST",body:s,headers:{"content-type":"application/json"}},i=this.host.hass?.fetchWithAuth?await this.host.hass.fetchWithAuth(t,e):await fetch(t,{...e,headers:{...e.headers,...this.host.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.host.hass.auth.data.access_token}`}:{}}}),o=await i.json().catch(()=>({}));if(!i.ok||o.error)throw Object.assign(new Error(o.message||o.error||`HTTP ${i.status}`),{code:o.error});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,token:o.token,preview:o.preview,expectedConfigRev:o.expected_config_rev,expectedLayoutRev:o.expected_layout_rev,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _setBackupDuplicatePolicy(t){const e=this.host._backupImportDialog;if(e&&!e.busy&&e.token&&t!==e.duplicatePolicy){this.host._backupImportDialog={...e,duplicatePolicy:t,busy:!0,error:""};try{const s=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:e.token,duplicate_policy:t});this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,preview:{...e.preview,...s.preview},expectedConfigRev:s.expected_config_rev,expectedLayoutRev:s.expected_layout_rev,confirmMissing:!1,busy:!1})}catch(t){this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,duplicatePolicy:e.duplicatePolicy,preview:e.preview,confirmMissing:e.confirmMissing,busy:!1,error:this._backupErrorText(t)})}}}async _applyBackupImport(){const t=this.host._backupImportDialog;if(!t||t.busy||!t.token||!t.preview)return;if(t.preview.confirmation_required&&!t.confirmMissing)return;this.host._backupImportDialog={...t,busy:!0,error:""};const e=this.host._space;try{const s=await this.host.hass.callWS({type:"houseplan/import/apply",token:t.token,expected_config_rev:t.expectedConfigRev,expected_layout_rev:t.expectedLayoutRev,duplicate_policy:t.duplicatePolicy,confirm_missing_content:t.confirmMissing}),[i,o]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:i,layResp:o,reason:"import-apply",profile:"post-write"})).status)return this.host._backupImportDialog={...t,busy:!1,error:""},void this.host.requestUpdate();this.host._geometryHistory.clear(),this.host._dirtyPos.clear(),this.host._sentPos.clear(),this.host._defPos={},this.host._cfgEpoch++,this.host._modelCache=null,this.host._frame=null,this.host._visibleDeviceSnapshot=null,this.host._candidateDeviceSnapshot=null,this.host._stagedDeviceSnapshotToken=-1,this.host._capturedSnapshotConfigEpoch=-1,this.host._regSignature="",this.host._signer.invalidate(this.host.hass),this.host._resign(),this.host._maybeRebuildDevices();const a=this.host._serverCfg?.spaces||[],n="space"===s.kind&&s.space_id?s.space_id:a.some(t=>t.id===e)?e:a[0]?.id||this.host._space;this.host._hasFixedFloor?this.host._adoptInitialSpace(this.host._model,!0):this.host._commitSpace(n),this.host._backupImportDialog=null,this.host._cacheSnapshot(),this.host.requestUpdate();const r="space"===s.kind?t.preview.counts:s.counts;this.host._showToast(this.host._t("space"===s.kind?"backup.space_done":"backup.full_done",{spaces:String(r?.spaces||0),rooms:String(r?.rooms||0),markers:String(r?.markers||0),refs:String(s.repaired_target_refs||0)}))}catch(t){if("conflict"===t?.code&&this.host._backupImportDialog?.token)try{const t=this.host._backupImportDialog,e=await this.host.hass.callWS({type:"houseplan/import/revalidate",token:t.token,duplicate_policy:t.duplicatePolicy});return void(this.host._backupImportDialog={...t,preview:{...t.preview,...e.preview},expectedConfigRev:e.expected_config_rev,expectedLayoutRev:e.expected_layout_rev,confirmMissing:!1,busy:!1,error:this.host._t("backup.revalidated")})}catch(e){t=e}this.host._backupImportDialog&&(this.host._backupImportDialog={...this.host._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}_renderBackupExportDialog(){const t=this.host._backupExportDialog,e=(this.host._serverCfg?.spaces||[]).find(t=>t.id===this.host._space);return p`this.host._backupExportDialog=null}>
    ${this.host._t("backup.export_hint")}
    @@ -1217,7 +1217,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${t.busy?"…":this.host._t("full"===e.kind?"backup.replace":"backup.add")} `:d}
    -
    `}_setFillColor(t,e){const s=this.host._settingsDialog;this.host._settingsDialog={...s,colors:{...s.colors,[t]:{...s.colors[t],...e}}}}_updateDecorStyle(t){this.host._decorStyle=t,null!==this._decorStylePersistTimer&&window.clearTimeout(this._decorStylePersistTimer),this._decorStylePersistTimer=window.setTimeout(()=>{this._decorStylePersistTimer=null,this._persistDecorStyle()},1e3)}_persistDecorStyle(){const t=this.host._serverCfg;if(!t)return;const e=ii(this.host._decorStyle),s={...t.settings},i=JSON.stringify(s.decor_default_style??null);e?s.decor_default_style=e:delete s.decor_default_style,JSON.stringify(s.decor_default_style??null)!==i&&(this.host._serverCfg={...t,settings:s},this._saveConfig())}async _saveSettingsDialog(){const t=this.host._settingsDialog;if(!t||t.busy)return;this.host._settingsDialog={...t,busy:!0};let e=null;try{const s=this.host._serverCfg,i=JSON.stringify(t.colors)===JSON.stringify(oi);let o={...s.settings};i?delete o.fill_colors:o.fill_colors=t.colors;const a=this.host._imperial?30.48*t.glowRadius:100*t.glowRadius;Number.isFinite(a)&&a>0&&300!==Math.round(a)?o.glow_radius_cm=Math.round(a):delete o.glow_radius_cm,t.bgColor?o.bg_color=t.bgColor:delete o.bg_color,null!==t.northDeg&&Number.isInteger(t.northDeg)&&t.northDeg>=0&&t.northDeg<=359?o.north_deg=t.northDeg:delete o.north_deg,o.bg_mode=t.bgMode,t.sunRays?o.sun_rays=!0:delete o.sun_rays,t.showRoomTooltip?delete o.show_room_tooltip:o.show_room_tooltip=!1;const n=o.radar;n&&null!=n.version&&1!==n.version||(o.radar={...n||{},version:1},t.radarShowLive?delete o.radar.show_live:o.radar.show_live=!1),o=ai(o,t.zigbeeTopology),delete o.weather_entity;const r={...s,settings:o};e=this.host._adoption.beginOptimistic(s,r),this.host._serverCfg=r,await this._saveConfigNow(e),!t.showRoomTooltip&&this.host._tip?.room&&(this.host._tip=null),this.host._settingsDialog=null,this.host.requestUpdate(),this.host._showToast(this.host._t("gs.saved"))}catch(t){e&&this.host._rollbackOptimistic(e),this.host._settingsDialog&&(this.host._settingsDialog={...this.host._settingsDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_boolInput(t,e,s=!1){const i=t=>e(!!t.target.checked);return customElements.get("ha-switch")?p``:p``}_rangeInput(t,e,s,i,o,a=!1,n){const r=t=>{const e=Number(t.target.value);Number.isFinite(e)&&o(e)};return customElements.get("ha-slider")?p``}_setFillColor(t,e){const s=this.host._settingsDialog;this.host._settingsDialog={...s,colors:{...s.colors,[t]:{...s.colors[t],...e}}}}_updateDecorStyle(t){this.host._decorStyle=t,null!==this._decorStylePersistTimer&&window.clearTimeout(this._decorStylePersistTimer),this._decorStylePersistTimer=window.setTimeout(()=>{this._decorStylePersistTimer=null,this._persistDecorStyle()},1e3)}_persistDecorStyle(){const t=this.host._serverCfg;if(!t)return;const e=oi(this.host._decorStyle),s={...t.settings},i=JSON.stringify(s.decor_default_style??null);e?s.decor_default_style=e:delete s.decor_default_style,JSON.stringify(s.decor_default_style??null)!==i&&(this.host._serverCfg={...t,settings:s},this._saveConfig())}async _saveSettingsDialog(){const t=this.host._settingsDialog;if(!t||t.busy)return;this.host._settingsDialog={...t,busy:!0};let e=null;try{const s=this.host._serverCfg,i=JSON.stringify(t.colors)===JSON.stringify(ai);let o={...s.settings};i?delete o.fill_colors:o.fill_colors=t.colors;const a=this.host._imperial?30.48*t.glowRadius:100*t.glowRadius;Number.isFinite(a)&&a>0&&300!==Math.round(a)?o.glow_radius_cm=Math.round(a):delete o.glow_radius_cm,t.bgColor?o.bg_color=t.bgColor:delete o.bg_color,null!==t.northDeg&&Number.isInteger(t.northDeg)&&t.northDeg>=0&&t.northDeg<=359?o.north_deg=t.northDeg:delete o.north_deg,o.bg_mode=t.bgMode,t.sunRays?o.sun_rays=!0:delete o.sun_rays,o.sun_ray_origin=t.sunRayOrigin,t.showRoomTooltip?delete o.show_room_tooltip:o.show_room_tooltip=!1;const n=o.radar;n&&null!=n.version&&1!==n.version||(o.radar={...n||{},version:1},t.radarShowLive?delete o.radar.show_live:o.radar.show_live=!1),o=ni(o,t.zigbeeTopology),delete o.weather_entity;const r={...s,settings:o};e=this.host._adoption.beginOptimistic(s,r),this.host._serverCfg=r,await this._saveConfigNow(e),!t.showRoomTooltip&&this.host._tip?.room&&(this.host._tip=null),this.host._settingsDialog=null,this.host.requestUpdate(),this.host._showToast(this.host._t("gs.saved"))}catch(t){e&&this.host._rollbackOptimistic(e),this.host._settingsDialog&&(this.host._settingsDialog={...this.host._settingsDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_boolInput(t,e,s=!1){const i=t=>e(!!t.target.checked);return customElements.get("ha-switch")?p``:p``}_rangeInput(t,e,s,i,o,a=!1,n){const r=t=>{const e=Number(t.target.value);Number.isFinite(e)&&o(e)};return customElements.get("ha-slider")?p``:p``}_renderColorRow(t,e){const s=this.host._settingsDialog.colors[t];return p`
    ${this.host._t("gs.align_count",{n:String(e.moved),total:String(e.total),cm:String(t.cm)})}

    `:d} ${e.latticeCoordinatesCanonicalized?p` -

    ${this.host._t("gs.optimize_lattice_summary",{n:String(e.latticeCoordinatesCanonicalized),cm:ni(e.latticeMaxShiftCm)})}

    +

    ${this.host._t("gs.optimize_lattice_summary",{n:String(e.latticeCoordinatesCanonicalized),cm:ri(e.latticeMaxShiftCm)})}

    ${e.latticeSpaces.map(t=>p`

    ${this.host._t("gs.optimize_lattice_space",{space:t.space,n:String(t.canonicalized),far:String(t.far)})}

    `)} `:d} ${t.where?p`

    ${this.host._t("gs.align_where",{s:t.where})}

    `:d} @@ -1306,10 +1306,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 `}_renderSettingsDialog(){return p`this.host._settingsDialog=null}>
    -
    ${Ro(l(this.host.hass,this.host._config?.language),"gs.hint")}
    +
    ${Ao(l(this.host.hass,this.host._config?.language),"gs.hint")}
    `:d} - ${ri(this.host.hass)?d:p`
    ${this.host._t("gs.sun_missing")}
    `} + ${li(this.host.hass)?d:p`
    ${this.host._t("gs.sun_missing")}
    `}
    ${this.host._renderCompass()}
    @@ -1381,6 +1381,14 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this._boolInput(this.host._settingsDialog.sunRays,t=>this.host._settingsDialog={...this.host._settingsDialog,sunRays:t})} ${this.host._t("gs.sun_rays")} + ${t=this.host._settingsDialog.sunRayOrigin,e=t=>this.host._t(t),s=t=>this.host._settingsDialog={...this.host._settingsDialog,sunRayOrigin:t},p`
    + + +
    `} ${this.host._canEdit?p`
    ${this.host._t("gs.backup_hint")}
    @@ -1415,7 +1423,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    `:d}
    - @@ -1424,7 +1432,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._settingsDialog.busy?"…":this.host._t("btn.save")}
    -
    `}_rulesSet(t){this.host._rulesDialog={...this.host._rulesDialog,rules:t}}async _saveRules(){const t=this.host._rulesDialog;if(!t||t.busy)return;const e=t.rules.filter(t=>t.pattern.trim()&&t.icon.trim());this.host._rulesDialog={...t,busy:!0};try{const t=this.host._serverCfg,s=JSON.stringify(e)===JSON.stringify(pe),i={...t.settings};s?delete i.icon_rules:i.icon_rules=e,this.host._serverCfg={...t,settings:i},await this._saveConfigNow(),this.host._rulesDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("rules.saved"))}catch(t){this.host._rulesDialog&&(this.host._rulesDialog={...this.host._rulesDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_renderRulesDialog(){const t=this.host._rulesDialog,e=li(t.rules),s=t.test.trim()?hi(t.test,"",e):null,i=(e,s)=>{const i=[...t.rules],o=e+s;o<0||o>=i.length||([i[e],i[o]]=[i[o],i[e]],this._rulesSet(i))};return p``;var t,e,s}_rulesSet(t){this.host._rulesDialog={...this.host._rulesDialog,rules:t}}async _saveRules(){const t=this.host._rulesDialog;if(!t||t.busy)return;const e=t.rules.filter(t=>t.pattern.trim()&&t.icon.trim());this.host._rulesDialog={...t,busy:!0};try{const t=this.host._serverCfg,s=JSON.stringify(e)===JSON.stringify(ue),i={...t.settings};s?delete i.icon_rules:i.icon_rules=e,this.host._serverCfg={...t,settings:i},await this._saveConfigNow(),this.host._rulesDialog=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("rules.saved"))}catch(t){this.host._rulesDialog&&(this.host._rulesDialog={...this.host._rulesDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}_renderRulesDialog(){const t=this.host._rulesDialog,e=hi(t.rules),s=t.test.trim()?ci(t.test,"",e):null,i=(e,s)=>{const i=[...t.rules],o=e+s;o<0||o>=i.length||([i[e],i[o]]=[i[o],i[e]],this._rulesSet(i))};return p`this.host._rulesDialog=null}>
    ${this.host._t("rules.hint")}
    @@ -1434,7 +1442,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @input=${e=>this.host._rulesDialog={...t,test:e.target.value}} /> ${s?p`${s}`:d}
    - ${t.rules.map((e,s)=>{const o=""!==e.pattern.trim()&&!ci(e.pattern);return p`
    + ${t.rules.map((e,s)=>{const o=""!==e.pattern.trim()&&!di(e.pattern);return p`
    - @@ -1481,7 +1489,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    - `}_renderVacSection(t){const e=this.host._devices.find(e=>e.id===t.devId);if(!e||!this.host._isVacDev(e))return d;const s=e.marker?.vacuum||{},o=this.host._vacAllCamerasFor===e.id,a=this.host._vacSourceResolution(e,o),n=a.entityId,r=a.candidates.find(t=>t.entityId===n)||null,l=n?di(this.host.hass?.states[n]?.attributes):null,h=!1!==s.live&&("ok"===a.status||"unsupported"===a.status),c=this._vacPlanRoomAnchors(e.space),u=l?pi(l.rooms,c.map(t=>t.name)):0,_=!!(h&&l&&u>=3),m=t=>{const s=this.host._vacEnsureMarker(e);s&&(s.vacuum={...s.vacuum||{},...t},this.host._regSignature="",this.host._maybeRebuildDevices(),this._saveConfig(),this.host.requestUpdate())},g=new Set(e.entities||[]),f=a.candidates.filter(t=>g.has(t.entityId)||t.entityId===s.source),b=o?a.candidates.filter(t=>t.entityId.startsWith("camera.")&&!f.some(e=>e.entityId===t.entityId)):[],v=t=>[t.hasPosition?this.host._t("vac.cap_position"):"",t.hasRooms?this.host._t("vac.cap_rooms_short"):"",t.hasPath?this.host._t("vac.cap_path"):"",t.hasMapId?this.host._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this.host._t("vac.cap_none"),y=t=>p` + `}_renderVacSection(t){const e=this.host._devices.find(e=>e.id===t.devId);if(!e||!this.host._isVacDev(e))return d;const s=e.marker?.vacuum||{},o=this.host._vacAllCamerasFor===e.id,a=this.host._vacSourceResolution(e,o),n=a.entityId,r=a.candidates.find(t=>t.entityId===n)||null,l=n?pi(this.host.hass?.states[n]?.attributes):null,h=!1!==s.live&&("ok"===a.status||"unsupported"===a.status),c=this._vacPlanRoomAnchors(e.space),u=l?ui(l.rooms,c.map(t=>t.name)):0,_=!!(h&&l&&u>=3),m=t=>{const s=this.host._vacEnsureMarker(e);s&&(s.vacuum={...s.vacuum||{},...t},this.host._regSignature="",this.host._maybeRebuildDevices(),this._saveConfig(),this.host.requestUpdate())},g=new Set(e.entities||[]),f=a.candidates.filter(t=>g.has(t.entityId)||t.entityId===s.source),b=o?a.candidates.filter(t=>t.entityId.startsWith("camera.")&&!f.some(e=>e.entityId===t.entityId)):[],v=t=>[t.hasPosition?this.host._t("vac.cap_position"):"",t.hasRooms?this.host._t("vac.cap_rooms_short"):"",t.hasPath?this.host._t("vac.cap_path"):"",t.hasMapId?this.host._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this.host._t("vac.cap_none"),y=t=>p`
    `}_vacMapId(t,e,s=this.host._planHass){return this.host._vacMapId(t,e,s)}_vacSaveMatrix(t,e,s,i,o=""){return vc(this,t,e,s,i,o)}_vacPlanRoomAnchors(t){return(this.host._spaceModelById(t)?.rooms||[]).map(t=>({room:t,poly:B(t)})).filter(({room:t,poly:e})=>t.name&&e).map(({room:t,poly:e})=>{const s=_i(e);return s?{name:String(t.name),cx:s[0],cy:s[1]}:null}).filter(Boolean)}async _vacAutoCalibrate(t){if(this.host._markerDialog?.busy)return;const e=this.host._vacSource(t),s=e?di(this.host.hass?.states[e]?.attributes):null;if(!e||!s||s.rooms.length<3)return void this.host._showToast(this.host._t("vac.autocal_no_rooms"));const i=this._vacMapId(t,s),a=function(t,e,s,i,a){const n=o(t,e,s,i).find(t=>t.source===i&&t.map_id===a);return{space:n?.space||s,routeId:n?.id||""}}(t.id,t.marker?.vacuum??null,t.space,e,i),n=mi(s.rooms,this._vacPlanRoomAnchors(a.space));if(!n)return void this.host._showToast(this.host._t("vac.autocal_no_match"));const r=this.host._serverCfg?.spaces?.find(t=>t.id===a.space),l=Number(r?.cell_cm),h=Number.isFinite(l)&&l>0?l:5,c=gi(n.residual,this.host._gridPitch,h);c>fi?this.host._vacCalConfirm={markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length,error:Ot(c,"mi"===this.host.hass?.config?.unit_system?.length)}:await async function(t,e){if(fc.has(t))return;fc.add(t);const s=t.host,i=s._markerDialog,o=i?{...i,busy:!0}:null;o&&(s._markerDialog=o,s.requestUpdate());try{await vc(t,e.markerId,e.source,e.mapId,e.matrix,e.routeId)&&s._showToast(s._t("vac.autocal_done",{rooms:String(e.rooms)}))}finally{fc.delete(t),o&&s._markerDialog===o&&(s._markerDialog={...o,busy:!1},s.requestUpdate())}}(this,{markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length})}_vacApplyCalibrationProposal(t){return async function(t,e){const s=t.host,i=s._vacCalConfirm;if(!i||i.busy)return;if(e){const t=s._devices.find(t=>t.id===i.markerId),e=n(i.matrix);if(!t||!e)return;const o=i.space||t.space;if(o!==s._space&&!s._commitSpace(o))return;return s._vacCalConfirm=null,s._markerDialog=null,void(s._vacFit={markerId:i.markerId,source:i.source,routeId:i.routeId,mapId:i.mapId,p:e,drag:null})}const o={...i,busy:!0};s._vacCalConfirm=o,s.requestUpdate();const a=await vc(t,i.markerId,i.source,i.mapId,i.matrix,i.routeId);s._vacCalConfirm===o&&(s._vacCalConfirm=a?null:{...i,busy:!1},s.requestUpdate()),a&&s._showToast(s._t("vac.autocal_done",{rooms:String(i.rooms)}))}(this,t)}_vacStartFit(t,e=""){if(this.host._markerDialog?.busy)return;const s=this.host._vacSource(t),i=s?di(this.host.hass?.states[s]?.attributes):null;if(!s||!i)return void this.host._showToast(this.host._t("vac.cal_need_pos"));const l=this._vacMapId(t,i),h=function(t,e,s){const i=o(t,e,s.dockSpace,s.source),l=i.find(t=>t.id===s.routeId)||i.find(t=>t.source===s.source&&t.map_id===s.mapId)||null,h=l?.space||s.dockSpace,c=s.viewBoxOf(h);if(!c)return null;const d=a(l?l.calibration:e?.calibration?.[s.mapId]),p=d&&n(d)||r(s.rooms,c);return{space:h,routeId:l?.id||"",params:p}}(t.id,t.marker?.vacuum??null,{routeId:e,source:s,mapId:l,dockSpace:t.space,rooms:i.rooms,viewBoxOf:t=>this.host._spaceModelById(t)?.vb??null});h&&(this.host._markerDialog=null,(h.space===this.host._space||this.host._commitSpace(h.space))&&(this.host._vacFit={markerId:t.id,source:s,mapId:l,routeId:h.routeId,p:h.params,drag:null}))}_vacFitSave(){return async function(t,e){const s=t.host,i=s._vacFit;if(!i||i.busy)return;const o={...i,busy:!0,drag:null};s._vacFit=o,s.requestUpdate();const a=await vc(t,i.markerId,i.source,i.mapId,e(i.p),i.routeId);s._vacFit===o&&(s._vacFit=a?null:{...i,busy:!1,drag:null},s.requestUpdate()),a&&s._showToast(s._t("vac.cal_done"))}(this,vi)}_vacFitTurn(t){const e=this.host._vacFit;if(!e||e.busy)return;const s=di(this.host.hass?.states[e.source]?.attributes),i=this._vacGhostCentre(s?.rooms||[]),o={...e.p,...t};this.host._vacFit={...e,p:bi(o,e.p,i[0],i[1])}}_vacGhostCentre(t){const e=[],s=[];for(const i of t)e.push(i.x0??i.cx,i.x1??i.cx),s.push(i.y0??i.cy,i.y1??i.cy);return e.length?[(Math.min(...e)+Math.max(...e))/2,(Math.min(...s)+Math.max(...s))/2]:[0,0]}_vacDelta(t,e,s){const i=this.host._stageEl,o=i?.clientWidth||1,a=i?.clientHeight||1;return[e/o*t.w,s/a*t.h]}_vacFitPointer(t,e){const s=this.host._vacFit;if(!s)return;if(t.stopPropagation(),s.busy)return;if("pointerdown"===t.type){const e=t.target,i=e.getAttribute?.("data-corner");try{t.currentTarget.setPointerCapture?.(t.pointerId)}catch{}return void(this.host._vacFit={...s,drag:i?{kind:"scale",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:Number(i.split(",")[0]),fy:Number(i.split(",")[1])}:{kind:"move",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:0,fy:0}})}const i=s.drag;if(i){if("pointermove"===t.type){const[o,a]=this._vacDelta(e,t.clientX-i.sx,t.clientY-i.sy);if("move"===i.kind)this.host._vacFit={...s,p:{...i.p0,ox:i.p0.ox+o,oy:i.p0.oy+a}};else{const t=di(this.host.hass?.states[s.source]?.attributes),e=this._vacGhostCentre(t?.rooms||[]),n=vi(i.p0),[r,l]=yi(n,e[0],e[1]),[h,c]=yi(n,i.fx,i.fy),d=Math.hypot(r-h,l-c)||1,[p,u]=[2*r-h,2*l-c],_=Math.hypot(p+2*o-h,u+2*a-c)/2,m=Math.max(.05,_/d),g={...i.p0,s:i.p0.s*m};this.host._vacFit={...s,p:bi(g,i.p0,i.fx,i.fy)}}return}"pointerup"!==t.type&&"pointercancel"!==t.type||(this.host._vacFit={...s,drag:null})}}_renderVacFit(t){const e=this.host._vacFit;if(!e)return d;const s=di(this.host._renderPlanHass?.states?.[e.source]?.attributes);if(!s)return d;const i=vi(e.p),o=[],a=[],n=[];for(const t of s.rooms){if(null==t.x0)continue;const e=[[t.x0,t.y0],[t.x1,t.y0],[t.x1,t.y1],[t.x0,t.y1]].map(([t,e])=>yi(i,t,e));e.forEach(([t,e])=>{a.push(t),n.push(e)});const[s,r]=yi(i,t.cx,t.cy);o.push(_` - ${t.name}`)}let r=d;if(s.pos){const[e,o]=yi(i,s.pos.x,s.pos.y);r=_``}const l=[];if(a.length){const e=(()=>{const t=i[0]*i[4]-i[1]*i[3];return(e,s)=>[(i[4]*(e-i[2])-i[1]*(s-i[5]))/t,(-i[3]*(e-i[2])+i[0]*(s-i[5]))/t]})(),s=Math.min(...a),o=Math.max(...a),r=Math.min(...n),h=Math.max(...n),c=.022*t.w,d=c/4;for(const[t,i,a,n]of[[s,r,o,h],[o,r,s,h],[o,h,s,r],[s,h,o,r]]){const s=e(a,n);l.push(_``}_vacMapId(t,e,s=this.host._planHass){return this.host._vacMapId(t,e,s)}_vacSaveMatrix(t,e,s,i,o=""){return yc(this,t,e,s,i,o)}_vacPlanRoomAnchors(t){return(this.host._spaceModelById(t)?.rooms||[]).map(t=>({room:t,poly:B(t)})).filter(({room:t,poly:e})=>t.name&&e).map(({room:t,poly:e})=>{const s=mi(e);return s?{name:String(t.name),cx:s[0],cy:s[1]}:null}).filter(Boolean)}async _vacAutoCalibrate(t){if(this.host._markerDialog?.busy)return;const e=this.host._vacSource(t),s=e?pi(this.host.hass?.states[e]?.attributes):null;if(!e||!s||s.rooms.length<3)return void this.host._showToast(this.host._t("vac.autocal_no_rooms"));const i=this._vacMapId(t,s),a=function(t,e,s,i,a){const n=o(t,e,s,i).find(t=>t.source===i&&t.map_id===a);return{space:n?.space||s,routeId:n?.id||""}}(t.id,t.marker?.vacuum??null,t.space,e,i),n=gi(s.rooms,this._vacPlanRoomAnchors(a.space));if(!n)return void this.host._showToast(this.host._t("vac.autocal_no_match"));const r=this.host._serverCfg?.spaces?.find(t=>t.id===a.space),l=Number(r?.cell_cm),h=Number.isFinite(l)&&l>0?l:5,c=fi(n.residual,this.host._gridPitch,h);c>bi?this.host._vacCalConfirm={markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length,error:Ot(c,"mi"===this.host.hass?.config?.unit_system?.length)}:await async function(t,e){if(bc.has(t))return;bc.add(t);const s=t.host,i=s._markerDialog,o=i?{...i,busy:!0}:null;o&&(s._markerDialog=o,s.requestUpdate());try{await yc(t,e.markerId,e.source,e.mapId,e.matrix,e.routeId)&&s._showToast(s._t("vac.autocal_done",{rooms:String(e.rooms)}))}finally{bc.delete(t),o&&s._markerDialog===o&&(s._markerDialog={...o,busy:!1},s.requestUpdate())}}(this,{markerId:t.id,source:e,mapId:i,routeId:a.routeId,space:a.space,matrix:n.matrix,rooms:n.matched.length})}_vacApplyCalibrationProposal(t){return async function(t,e){const s=t.host,i=s._vacCalConfirm;if(!i||i.busy)return;if(e){const t=s._devices.find(t=>t.id===i.markerId),e=n(i.matrix);if(!t||!e)return;const o=i.space||t.space;if(o!==s._space&&!s._commitSpace(o))return;return s._vacCalConfirm=null,s._markerDialog=null,void(s._vacFit={markerId:i.markerId,source:i.source,routeId:i.routeId,mapId:i.mapId,p:e,drag:null})}const o={...i,busy:!0};s._vacCalConfirm=o,s.requestUpdate();const a=await yc(t,i.markerId,i.source,i.mapId,i.matrix,i.routeId);s._vacCalConfirm===o&&(s._vacCalConfirm=a?null:{...i,busy:!1},s.requestUpdate()),a&&s._showToast(s._t("vac.autocal_done",{rooms:String(i.rooms)}))}(this,t)}_vacStartFit(t,e=""){if(this.host._markerDialog?.busy)return;const s=this.host._vacSource(t),i=s?pi(this.host.hass?.states[s]?.attributes):null;if(!s||!i)return void this.host._showToast(this.host._t("vac.cal_need_pos"));const l=this._vacMapId(t,i),h=function(t,e,s){const i=o(t,e,s.dockSpace,s.source),l=i.find(t=>t.id===s.routeId)||i.find(t=>t.source===s.source&&t.map_id===s.mapId)||null,h=l?.space||s.dockSpace,c=s.viewBoxOf(h);if(!c)return null;const d=a(l?l.calibration:e?.calibration?.[s.mapId]),p=d&&n(d)||r(s.rooms,c);return{space:h,routeId:l?.id||"",params:p}}(t.id,t.marker?.vacuum??null,{routeId:e,source:s,mapId:l,dockSpace:t.space,rooms:i.rooms,viewBoxOf:t=>this.host._spaceModelById(t)?.vb??null});h&&(this.host._markerDialog=null,(h.space===this.host._space||this.host._commitSpace(h.space))&&(this.host._vacFit={markerId:t.id,source:s,mapId:l,routeId:h.routeId,p:h.params,drag:null}))}_vacFitSave(){return async function(t,e){const s=t.host,i=s._vacFit;if(!i||i.busy)return;const o={...i,busy:!0,drag:null};s._vacFit=o,s.requestUpdate();const a=await yc(t,i.markerId,i.source,i.mapId,e(i.p),i.routeId);s._vacFit===o&&(s._vacFit=a?null:{...i,busy:!1,drag:null},s.requestUpdate()),a&&s._showToast(s._t("vac.cal_done"))}(this,yi)}_vacFitTurn(t){const e=this.host._vacFit;if(!e||e.busy)return;const s=pi(this.host.hass?.states[e.source]?.attributes),i=this._vacGhostCentre(s?.rooms||[]),o={...e.p,...t};this.host._vacFit={...e,p:vi(o,e.p,i[0],i[1])}}_vacGhostCentre(t){const e=[],s=[];for(const i of t)e.push(i.x0??i.cx,i.x1??i.cx),s.push(i.y0??i.cy,i.y1??i.cy);return e.length?[(Math.min(...e)+Math.max(...e))/2,(Math.min(...s)+Math.max(...s))/2]:[0,0]}_vacDelta(t,e,s){const i=this.host._stageEl,o=i?.clientWidth||1,a=i?.clientHeight||1;return[e/o*t.w,s/a*t.h]}_vacFitPointer(t,e){const s=this.host._vacFit;if(!s)return;if(t.stopPropagation(),s.busy)return;if("pointerdown"===t.type){const e=t.target,i=e.getAttribute?.("data-corner");try{t.currentTarget.setPointerCapture?.(t.pointerId)}catch{}return void(this.host._vacFit={...s,drag:i?{kind:"scale",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:Number(i.split(",")[0]),fy:Number(i.split(",")[1])}:{kind:"move",sx:t.clientX,sy:t.clientY,p0:{...s.p},fx:0,fy:0}})}const i=s.drag;if(i){if("pointermove"===t.type){const[o,a]=this._vacDelta(e,t.clientX-i.sx,t.clientY-i.sy);if("move"===i.kind)this.host._vacFit={...s,p:{...i.p0,ox:i.p0.ox+o,oy:i.p0.oy+a}};else{const t=pi(this.host.hass?.states[s.source]?.attributes),e=this._vacGhostCentre(t?.rooms||[]),n=yi(i.p0),[r,l]=$i(n,e[0],e[1]),[h,c]=$i(n,i.fx,i.fy),d=Math.hypot(r-h,l-c)||1,[p,u]=[2*r-h,2*l-c],_=Math.hypot(p+2*o-h,u+2*a-c)/2,m=Math.max(.05,_/d),g={...i.p0,s:i.p0.s*m};this.host._vacFit={...s,p:vi(g,i.p0,i.fx,i.fy)}}return}"pointerup"!==t.type&&"pointercancel"!==t.type||(this.host._vacFit={...s,drag:null})}}_renderVacFit(t){const e=this.host._vacFit;if(!e)return d;const s=pi(this.host._renderPlanHass?.states?.[e.source]?.attributes);if(!s)return d;const i=yi(e.p),o=[],a=[],n=[];for(const t of s.rooms){if(null==t.x0)continue;const e=[[t.x0,t.y0],[t.x1,t.y0],[t.x1,t.y1],[t.x0,t.y1]].map(([t,e])=>$i(i,t,e));e.forEach(([t,e])=>{a.push(t),n.push(e)});const[s,r]=$i(i,t.cx,t.cy);o.push(_` + ${t.name}`)}let r=d;if(s.pos){const[e,o]=$i(i,s.pos.x,s.pos.y);r=_``}const l=[];if(a.length){const e=(()=>{const t=i[0]*i[4]-i[1]*i[3];return(e,s)=>[(i[4]*(e-i[2])-i[1]*(s-i[5]))/t,(-i[3]*(e-i[2])+i[0]*(s-i[5]))/t]})(),s=Math.min(...a),o=Math.max(...a),r=Math.min(...n),h=Math.max(...n),c=.022*t.w,d=c/4;for(const[t,i,a,n]of[[s,r,o,h],[o,r,s,h],[o,h,s,r],[s,h,o,r]]){const s=e(a,n);l.push(_` `)}}return p`this._vacFitPointer(e,t)} @pointermove=${e=>this._vacFitPointer(e,t)} @pointerup=${e=>this._vacFitPointer(e,t)} - @pointercancel=${e=>this._vacFitPointer(e,t)}>${o}${r}${l}`}_resetRoomDialogFields(){this.host._roomEditId=null,this.host._roomFill="",this.host._roomCustomFill=null,this.host._roomTempMin="",this.host._roomTempMax="",this.host._roomTempSrc="",this.host._roomHumSrc="",this.host._roomSrcOpen=null,this.host._roomSrcFilter="",this.host._roomNameScale=1,this.host._roomLabelScale=1}_openRoomEdit(t){if(!t.id)return;this.host._roomEditId=t.id,this.host._nameSel=t.name||"",this.host._areaSel=t.area||"",this.host._roomFill="glow"===t.settings?.fill_mode?"":t.settings?.fill_mode||"";const e=t.settings?.custom_fill;this.host._roomCustomFill=e&&"object"==typeof e?js(e,Ws(this.host._curSpaceCfg).customFill):null,[this.host._roomTempMin,this.host._roomTempMax]=$i(t.settings),this.host._roomTempSrc=t.settings?.temp_source||"",this.host._roomHumSrc=t.settings?.hum_source||"",this.host._roomNameScale=wi(t.settings?.name_scale),this.host._roomLabelScale=wi(t.settings?.label_scale),this.host._roomSrcOpen=null,this.host._roomSrcFilter="",this.host._roomDialog=!0}_roomSettingsFromDialog(){const t={};return this.host._roomFill&&(t.fill_mode=this.host._roomFill),this.host._roomCustomFill&&(t.custom_fill=this.host._roomCustomFill),this.host._roomTempSrc&&(t.temp_source=this.host._roomTempSrc),this.host._roomHumSrc&&(t.hum_source=this.host._roomHumSrc),ki(t,this.host._roomTempMin,this.host._roomTempMax),1!==this.host._roomNameScale&&(t.name_scale=this.host._roomNameScale),1!==this.host._roomLabelScale&&(t.label_scale=this.host._roomLabelScale),Object.keys(t).length?t:null}_saveRoomEdit(){const t=this.host._curSpaceCfg,e=t?.rooms.find(t=>t.id===this.host._roomEditId);if(!e)return this.host._roomDialog=!1,void(this.host._roomEditId=null);e.name=this.host._nameSel.trim()||e.name,e.area=this.host._areaSel||null;const s=e.settings||{},i={...s};ki(i,this.host._roomTempMin,this.host._roomTempMax)&&(this.host._roomFill?i.fill_mode=this.host._roomFill:delete i.fill_mode,this.host._roomCustomFill?i.custom_fill=this.host._roomCustomFill:delete i.custom_fill,"glow"===s.fill_mode&&"boolean"!=typeof s.glow&&(i.glow=!0),this.host._roomTempSrc?i.temp_source=this.host._roomTempSrc:delete i.temp_source,this.host._roomHumSrc?i.hum_source=this.host._roomHumSrc:delete i.hum_source,1!==this.host._roomNameScale?i.name_scale=this.host._roomNameScale:delete i.name_scale,1!==this.host._roomLabelScale?i.label_scale=this.host._roomLabelScale:delete i.label_scale,Object.keys(i).length?e.settings=i:delete e.settings,this._saveConfig(),this.host._roomDialog=!1,this.host._roomEditId=null,this.host._nameSel="",this.host._areaSel="",this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate(),this.host._showToast(this.host._t("toast.room_updated")))}_roomSrcCandidates(){const t=this.host._planHass,e=Nt(this.host._markers),s=this.host._roomSrcFilter.trim().toLowerCase(),i=[];for(const o of Object.values(t.devices)){if("service"===o.entry_type)continue;if(e.devices.has(o.id))continue;const t=(o.name_by_user||o.name||o.id).trim();s&&!t.toLowerCase().includes(s)||i.push({value:"device:"+o.id,label:t,sub:o.model||this.host._t("marker.sub_device")})}for(const[o,a]of Object.entries(t.entities)){if(!o.startsWith("sensor.")||a.hidden)continue;if(Et(t,o,e))continue;const n=a.name||t.states[o]?.attributes?.friendly_name||o;s&&!(n+" "+o).toLowerCase().includes(s)||i.push({value:"entity:"+o,label:n,sub:o})}return i.sort((t,e)=>t.label.localeCompare(e.label)),i.slice(0,200)}_roomSrcLabel(t){const e=t.indexOf(":"),s=t.slice(0,e),i=t.slice(e+1);return"device"===s?this.host._fullRegistryHass.devices[i]?.name_by_user||this.host._fullRegistryHass.devices[i]?.name||i:this.host._fullRegistryHass.entities[i]?.name||this.host.hass.states[i]?.attributes?.friendly_name||i}_labelPos(t,e){const s=this.host._layout["rl_"+(t.id||"")];if(s&&s.s===e)return{x:s.x*sd,y:s.y*sd};const i=this._snap(this.host._roomCenter(t));return{x:i[0],y:i[1]}}_labelDown(t,e,s){if("plan"!==this.host._mode)return;t.preventDefault(),t.stopPropagation();const i=this._labelPos(e,s);this.host._drag={id:"rl_"+(e.id||""),sx:t.clientX,sy:t.clientY,ox:i.x,oy:i.y,moved:!1},od(t),this.host._tip=null}_labelMove(t,e,s){const i="rl_"+(e.id||"");if(!this.host._drag||this.host._drag.id!==i)return;const o=this.host._stageEl;if(!o)return;const a=this.host._spaceModelById(s);if(!a)return;const n=a.vb,r=o.getBoundingClientRect(),l=this.host._viewOr(n),h=(t.clientX-this.host._drag.sx)/r.width*l.w,c=(t.clientY-this.host._drag.sy)/r.height*l.h;Math.abs(t.clientX-this.host._drag.sx)+Math.abs(t.clientY-this.host._drag.sy)>3&&(this.host._drag.moved=!0);const d=ge(this.host._drag.ox+h),p=ge(this.host._drag.oy+c);this.host._savePos({id:i,space:s},d,p)}_labelUp(t){const e="rl_"+(t.id||"");if(!this.host._drag||this.host._drag.id!==e)return;const s=this.host._drag.moved;this.host._drag=s?this.host._drag:null,s&&window.setTimeout(()=>this.host._drag=null,0)}_labelScale(t){const e=this.host._layout["rl_"+(t.id||"")]?.k;return"number"==typeof e&&Number.isFinite(e)?Math.min(3,Math.max(.5,e)):1}_rlResizeDown(t,e,s){if("plan"!==this.host._mode)return;t.preventDefault(),t.stopPropagation();const i=t.target.closest(".roomlabel");if(!i)return;const o=i.getBoundingClientRect(),a=o.left+o.width/2,n=o.top+o.height/2,r=Math.max(8,Math.hypot(t.clientX-a,t.clientY-n));this.host._rlResize={id:"rl_"+(e.id||""),space:s,k0:this._labelScale(e),cx:a,cy:n,d0:r},od(t)}_rlResizeMove(t){const e=this.host._rlResize;if(!e)return;t.stopPropagation();const s=Math.max(8,Math.hypot(t.clientX-e.cx,t.clientY-e.cy)),i=Math.min(3,Math.max(.5,e.k0*(s/e.d0))),o=this.host._layout[e.id];if(o)this.host._layout={...this.host._layout,[e.id]:{...o,k:i}};else{const t=e.id.slice(3),s=this.host._spaceModelById(e.space);if(!s)return;const o=s.rooms.find(e=>e.id===t);if(!o)return;const a=this._labelPos(o,e.space);this.host._layout={...this.host._layout,[e.id]:{s:e.space,x:a.x/sd,y:a.y/sd,k:i}}}this.host._dirtyPos.add(e.id)}_rlResizeUp(){this.host._rlResize&&(this.host._rlResize=null,this.host._persistLayout())}_renderRoomGear(t,e,s){if(!t.id)return d;let i=null;if(t.poly?(i=this.host._gearPtCache.get(t.poly)||null,i||(i=Le(t.poly),this.host._gearPtCache.set(t.poly,i))):null!=t.x&&null!=t.y&&(i=[t.x+(t.w||0)/2,t.y+(t.h||0)/2]),!i)return d;const o=(i[0]-s.x)/s.w*100,a=(i[1]-s.y)/s.h*100;return p``}_alignCandidates(){const t=[],e=this.host._spaceModel();if(this.host._markup){if(!e)return t;if(this.host._drag?.id.startsWith("rl_")){const s=this.host._drag.id.slice(3);for(const i of e.rooms){if(!i.name||i.id===s)continue;const e=this._labelPos(i,this.host._space);t.push([e.x,e.y])}return t}for(const s of e.rooms){const e=B(s);if(e)for(const s of e)t.push(s)}if("draw"===this.host._tool)for(const e of this.host._path)t.push(e);if("split"===this.host._tool&&this.host._splitSel?.pts)for(const e of this.host._splitSel.pts)t.push(e);return t}if("devices"===this.host._mode){const e=this.host._deviceDrag?.id??this.host._drag?.id;for(const s of this.host._devices){if(s.space!==this.host._space||s.id===e||"ha_disabled"===s.bindingStatus?.kind)continue;const i=this.host._pos(s);t.push([i.x,i.y])}return t}if("decor"===this.host._mode){const e=this.host._decorMove?.id;return t.push(...this._decorSnapGeometry(e).points),this.host._decorDraft&&t.push(this.host._decorDraft.a),t}return t}_renderAlignGuides(){const t=this.host._alignPoint;if(!t)return _``;const e=this.host._drag?.id.startsWith("rl_")?.5*this.host._gridPitch:.05*this.host._gridPitch,s=xi(t,this._alignCandidates(),e);if(!s.length)return _``;const i=this.host._gridPitch,o=1.5*i;return _` + `}_alignCandidates(){const t=[],e=this.host._spaceModel();if(this.host._markup){if(!e)return t;if(this.host._drag?.id.startsWith("rl_")){const s=this.host._drag.id.slice(3);for(const i of e.rooms){if(!i.name||i.id===s)continue;const e=this._labelPos(i,this.host._space);t.push([e.x,e.y])}return t}for(const s of e.rooms){const e=B(s);if(e)for(const s of e)t.push(s)}if("draw"===this.host._tool)for(const e of this.host._path)t.push(e);if("split"===this.host._tool&&this.host._splitSel?.pts)for(const e of this.host._splitSel.pts)t.push(e);return t}if("devices"===this.host._mode){const e=this.host._deviceDrag?.id??this.host._drag?.id;for(const s of this.host._devices){if(s.space!==this.host._space||s.id===e||"ha_disabled"===s.bindingStatus?.kind)continue;const i=this.host._pos(s);t.push([i.x,i.y])}return t}if("decor"===this.host._mode){const e=this.host._decorMove?.id;return t.push(...this._decorSnapGeometry(e).points),this.host._decorDraft&&t.push(this.host._decorDraft.a),t}return t}_renderAlignGuides(){const t=this.host._alignPoint;if(!t)return _``;const e=this.host._drag?.id.startsWith("rl_")?.5*this.host._gridPitch:.05*this.host._gridPitch,s=Si(t,this._alignCandidates(),e);if(!s.length)return _``;const i=this.host._gridPitch,o=1.5*i;return _` ${s.map(e=>{const[s,a,n,r]="x"===e.axis?[e.at,e.from[1],e.at,t[1]+Math.sign(t[1]-e.from[1])*o]:[e.from[0],e.at,t[0]+Math.sign(t[0]-e.from[0])*o,e.at];return _` `})} @@ -1577,7 +1585,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 x2=${t.to[0]} y2=${t.to[1]}> ${o(t.from,"from")}${o(t.to,"to")} `})} - `}_renderOpeningPlacementPreview(){const t=this.host._openingPreview;if(!t)return _``;const e={type:t.type,length:t.renderedLength,angle:t.angle,amount:Si(t.type,null),flipH:t.flipH,flipV:t.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:t.face},s="passage"===t.type?Mi(t,y(this.host._gridPitch,this.host._cellCm)):null;return _``}_renderOpeningPlacementPreview(){const t=this.host._openingPreview;if(!t)return _``;const e={type:t.type,length:t.renderedLength,angle:t.angle,amount:Mi(t.type,null),flipH:t.flipH,flipV:t.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,face:t.face},s="passage"===t.type?Ci(t,y(this.host._gridPitch,this.host._cellCm)):null;return _` `}_renderOpeningDialog(){const t=this.host._openingDialog,e=this.host._spaceModel()?.partitions||[],s=t.id?this.host._curSpaceCfg?.openings?.find(e=>e.id===t.id):null,i={id:t.id||"preview",type:t.type,x:t.x/sd,y:t.y/this.host._spaceH,angle:t.angle,length:s&&!t.lengthTouched?s.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/sd,...t.host?{host:t.host}:{}},o=ys(s,i),a=t.host?o?bt(i,e,sd,this.host._cellCm,this.host._gridPitch):ct(i,e,sd,this.host._cellCm,this.host._gridPitch):null,n="does-not-fit-jamb"===a?.reason,r=t.host?e.find(e=>e.id===t.host.id):null,l=r?Ot(r.cm/2,this.host._imperial):"",h=!!t.host&&!a?.resolved&&!n,c="gate"===t.type?"mdi:gate":"window"===t.type?"mdi:window-closed-variant":"passage"===t.type?"mdi:arch":"mdi:door",u=(e,s)=>{const i="contact"===e?t.contact:t.lock,o="contact"===e?!!t.contactOpen:!!t.lockOpen,a="contact"===e?t.contactFilter||"":t.lockFilter||"",n=s.find(t=>t.value===i),r=n?.label||this.host.hass.states[i]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[i]?.name||i,l=ho(s,a);return p` + r=${y(.18*this.host._gridPitch,this.host._cellCm)}>`}_renderOpeningDialog(){const t=this.host._openingDialog,e=this.host._spaceModel()?.partitions||[],s=t.id?this.host._curSpaceCfg?.openings?.find(e=>e.id===t.id):null,i={id:t.id||"preview",type:t.type,x:t.x/id,y:t.y/this.host._spaceH,angle:t.angle,length:s&&!t.lengthTouched?s.length:this.host._cmToUnits(Math.max(20,t.lengthCm))/id,...t.host?{host:t.host}:{}},o=$s(s,i),a=t.host?o?bt(i,e,id,this.host._cellCm,this.host._gridPitch):ct(i,e,id,this.host._cellCm,this.host._gridPitch):null,n="does-not-fit-jamb"===a?.reason,r=t.host?e.find(e=>e.id===t.host.id):null,l=r?Ot(r.cm/2,this.host._imperial):"",h=!!t.host&&!a?.resolved&&!n,c="gate"===t.type?"mdi:gate":"window"===t.type?"mdi:window-closed-variant":"passage"===t.type?"mdi:arch":"mdi:door",u=(e,s)=>{const i="contact"===e?t.contact:t.lock,o="contact"===e?!!t.contactOpen:!!t.lockOpen,a="contact"===e?t.contactFilter||"":t.lockFilter||"",n=s.find(t=>t.value===i),r=n?.label||this.host.hass.states[i]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[i]?.name||i,l=co(s,a);return p`
    `:d} @@ -1680,7 +1688,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    - `}_gridLevels(){const t=this.host._stageEl,e=this.host._viewOr(this.host._baseVb()),s=t&&t.clientWidth&&e.w?t.clientWidth/e.w:1;return Di(this.host._gridPitch,s)}_renderMarkupDefs(t){const e=this._gridLevels();if(!e)return _``;const s=this.host._gridPitch*e.fine,i=this.host._gridPitch*e.coarse,o=this.host._gridPitch*e.fine*.14;return _` + `}_gridLevels(){const t=this.host._stageEl,e=this.host._viewOr(this.host._baseVb()),s=t&&t.clientWidth&&e.w?t.clientWidth/e.w:1;return Ii(this.host._gridPitch,s)}_renderMarkupDefs(t){const e=this._gridLevels();if(!e)return _``;const s=this.host._gridPitch*e.fine,i=this.host._gridPitch*e.coarse,o=this.host._gridPitch*e.fine*.14;return _` @@ -1694,7 +1702,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 - `}_renderPhysicalEditorLayer(){const t=this.host._spaceModel();if(!t)return _``;const e=this.host._gridPitch,s=this.host._viewOr(this.host._baseVb()),i=this.host._stageEl,o=i?.clientWidth?s.w/i.clientWidth:e/8,a=Math.max(.22*e,8*o),n=Math.max(a,12*o),r=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`,l=(t,e)=>this.host._physicalSel?.kind===t&&this.host._physicalSel.id===e||"column"===t&&this.host._duplicateColumnId===e,h=(t.partitions||[]).map(t=>{const e=Te(t.a,t.b,t.cm,this.host._cellCm,this.host._gridPitch);return e?_``}_renderPhysicalEditorLayer(){const t=this.host._spaceModel();if(!t)return _``;const e=this.host._gridPitch,s=this.host._viewOr(this.host._baseVb()),i=this.host._stageEl,o=i?.clientWidth?s.w/i.clientWidth:e/8,a=Math.max(.22*e,8*o),n=Math.max(a,12*o),r=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`,l=(t,e)=>this.host._physicalSel?.kind===t&&this.host._physicalSel.id===e||"column"===t&&this.host._duplicateColumnId===e,h=(t.partitions||[]).map(t=>{const e=Re(t.a,t.b,t.cm,this.host._cellCm,this.host._gridPitch);return e?_`this._physicalDown(e,"partition",t.id)} @@ -1705,7 +1713,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 stroke-width=${24} vector-effect="non-scaling-stroke" @pointerdown=${e=>this._physicalDown(e,"partition",t.id)} @pointermove=${t=>this._physicalMove(t)} - @pointerup=${t=>this._physicalUp(t)}>`}),c=(t.wall_columns||[]).map(t=>{const e=this.host._physicalRotate?.id===t.id?{...t,angle:this.host._physicalRotate.angle}:t,s=Ie(e,this.host._cellCm,this.host._gridPitch);return _`this._physicalUp(t)}>`}),c=(t.wall_columns||[]).map(t=>{const e=this.host._physicalRotate?.id===t.id?{...t,angle:this.host._physicalRotate.angle}:t,s=Te(e,this.host._cellCm,this.host._gridPitch);return _`this._physicalDown(e,"column",t.id)} @@ -1713,17 +1721,17 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @pointerup=${t=>this._physicalUp(t)}>`}),p=this.host._physicalDrag,u=(()=>{if(!p?.moved)return d;if("partition"===p.kind&&0===Number(p.base.cm)){const t=p.base;return _``}const t="partition"===p.kind?Te(p.base.a,p.base.b,p.base.cm,this.host._cellCm,this.host._gridPitch):Ie(p.base,this.host._cellCm,this.host._gridPitch);return t?_``:d})(),m=(()=>{const s=this.host._physicalSel;if(!s)return d;if("partition"===s.kind){const e=t.partitions.find(t=>t.id===s.id);if(!e)return d;const i=Te(e.a,e.b,e.cm,this.host._cellCm,this.host._gridPitch),o=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2;return _` + transform="translate(${p.delta[0]} ${p.delta[1]})">`}const t="partition"===p.kind?Re(p.base.a,p.base.b,p.base.cm,this.host._cellCm,this.host._gridPitch):Te(p.base,this.host._cellCm,this.host._gridPitch);return t?_``:d})(),m=(()=>{const s=this.host._physicalSel;if(!s)return d;if("partition"===s.kind){const e=t.partitions.find(t=>t.id===s.id);if(!e)return d;const i=Re(e.a,e.b,e.cm,this.host._cellCm,this.host._gridPitch),o=(e.a[0]+e.b[0])/2,n=(e.a[1]+e.b[1])/2;return _` ${i?_``:_``} - `}const i=t.wall_columns.find(t=>t.id===s.id);if(!i)return d;const l=this.host._physicalRotate?.id===i.id?{...i,angle:this.host._physicalRotate.angle}:i,h=Ie(l,this.host._cellCm,this.host._gridPitch);if("square"!==l.shape)return _` + `}const i=t.wall_columns.find(t=>t.id===s.id);if(!i)return d;const l=this.host._physicalRotate?.id===i.id?{...i,angle:this.host._physicalRotate.angle}:i,h=Te(l,this.host._cellCm,this.host._gridPitch);if("square"!==l.shape)return _` - `;const c=$(l.cm,this.host._cellCm,this.host._gridPitch),p=ye(l.angle)*Math.PI/180,u=Math.sin(p),m=-Math.cos(p),g=[l.center[0]+u*c/2,l.center[1]+m*c/2],f=[g[0]+u*Math.max(e,24*o),g[1]+m*Math.max(e,24*o)];return _` + `;const c=$(l.cm,this.host._cellCm,this.host._gridPitch),p=$e(l.angle)*Math.PI/180,u=Math.sin(p),m=-Math.cos(p),g=[l.center[0]+u*c/2,l.center[1]+m*c/2],f=[g[0]+u*Math.max(e,24*o),g[1]+m*Math.max(e,24*o)];return _` @@ -1749,7 +1757,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 data-segment-count=${t.segments.length} data-endpoint-count=${t.endpoints.length} aria-hidden="true" pointer-events="none"> - ${Io([t,i,[...s].sort().join("|")],()=>_` + ${To([t,i,[...s].sort().join("|")],()=>_` ${t.segments.map(t=>_` - `}_syncPlanSnapActiveMarker(t){const e=this.host.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(e){if(e.setAttribute("class",`plan-snap-node${t?" active":""}${"line"===t?.kind?" dynamic":""}`),e.setAttribute("data-active",t?"true":"false"),e.setAttribute("visibility",t?"visible":"hidden"),!t)return e.removeAttribute("data-kind"),void e.removeAttribute("data-key");e.setAttribute("data-kind",t.kind),e.setAttribute("data-key",t.key),e.setAttribute("cx",String(t.point[0])),e.setAttribute("cy",String(t.point[1])),e.setAttribute("r",String($(10,this.host._cellCm,this.host._gridPitch)))}}_syncPlanSnapConflictMarkers(t){const e=new Set(t.map(t=>t.key));for(const t of this.host.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])t.setAttribute("class","plan-snap-node"+(e.has(t.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(t){let e=0;const s=this.host._spaceModel();return s?(e="partition"===t.sourceKind?Number(s.partitions.find(e=>e.id===t.sourceId)?.cm)||0:Ii(s.rooms,this.host._spaceWalls,this.host._openCuts(),[t.a[0],t.a[1],t.b[0],t.b[1]],this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,sd),e>0?{a:[...t.a],b:[...t.b],halfDepth:$(e,this.host._cellCm,this.host._gridPitch)/2}:null):null}_drawPreviewJoinPatchD(t,e){if(t.length<2)return"";const s=[];for(let i=0;i+10&&s.push({a:t[i],b:t[i+1],halfDepth:e[i]});if(!s.length)return"";const i=2e-4*this.host._gridPitch,o=this._planSnapGeometrySnapshot().value.segments.filter(e=>t.some(t=>Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=i)).map(t=>this._planSnapPhysicalSegment(t)).filter(t=>!!t);return Ti([...s,...o],i).map(t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(t){const e=this.host._openCuts(),s=this.host._thickWallCuts(),i=e.concat(s),o=i.length?Bt(this.host._segments,i,.02*this.host._gridPitch):this.host._segments,a=this.host._path,n=this.host._gridPitch,r=this.host._viewOr(this.host._baseVb()),l="draw"===this.host._tool?this.host._drawWallCm:null,h=(()=>"draw"===this.host._tool&&a.length&&null!=l?this.host._contourClosed?a:this.host._cursorPt?[...a,this.host._cursorPt]:a.length>=2?a:null:null)(),c=h?Rh(h.length-1,this.host._contourClosed?[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0]:this.host._wallChainSegmentCms,l,ut).map(t=>$(t,this.host._cellCm,this.host._gridPitch)/2):[],p=h?zi(h,$(l,this.host._cellCm,this.host._gridPitch)/2,this.host._contourClosed,c):"",u=h?this._drawPreviewJoinPatchD(h,c):"",m=this.host._wallFaceBatch?.candidates[this.host._wallFaceBatch.index]?.repair||this.host._wallRepairDiagnostic;return _` + `}_syncPlanSnapActiveMarker(t){const e=this.host.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(e){if(e.setAttribute("class",`plan-snap-node${t?" active":""}${"line"===t?.kind?" dynamic":""}`),e.setAttribute("data-active",t?"true":"false"),e.setAttribute("visibility",t?"visible":"hidden"),!t)return e.removeAttribute("data-kind"),void e.removeAttribute("data-key");e.setAttribute("data-kind",t.kind),e.setAttribute("data-key",t.key),e.setAttribute("cx",String(t.point[0])),e.setAttribute("cy",String(t.point[1])),e.setAttribute("r",String($(10,this.host._cellCm,this.host._gridPitch)))}}_syncPlanSnapConflictMarkers(t){const e=new Set(t.map(t=>t.key));for(const t of this.host.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])t.setAttribute("class","plan-snap-node"+(e.has(t.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(t){let e=0;const s=this.host._spaceModel();return s?(e="partition"===t.sourceKind?Number(s.partitions.find(e=>e.id===t.sourceId)?.cm)||0:Ti(s.rooms,this.host._spaceWalls,this.host._openCuts(),[t.a[0],t.a[1],t.b[0],t.b[1]],this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,id),e>0?{a:[...t.a],b:[...t.b],halfDepth:$(e,this.host._cellCm,this.host._gridPitch)/2}:null):null}_drawPreviewJoinPatchD(t,e){if(t.length<2)return"";const s=[];for(let i=0;i+10&&s.push({a:t[i],b:t[i+1],halfDepth:e[i]});if(!s.length)return"";const i=2e-4*this.host._gridPitch,o=this._planSnapGeometrySnapshot().value.segments.filter(e=>t.some(t=>Wt(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=i)).map(t=>this._planSnapPhysicalSegment(t)).filter(t=>!!t);return Ri([...s,...o],i).map(t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(t){const e=this.host._openCuts(),s=this.host._thickWallCuts(),i=e.concat(s),o=i.length?Bt(this.host._segments,i,.02*this.host._gridPitch):this.host._segments,a=this.host._path,n=this.host._gridPitch,r=this.host._viewOr(this.host._baseVb()),l="draw"===this.host._tool?this.host._drawWallCm:null,h=(()=>"draw"===this.host._tool&&a.length&&null!=l?this.host._contourClosed?a:this.host._cursorPt?[...a,this.host._cursorPt]:a.length>=2?a:null:null)(),c=h?Ah(h.length-1,this.host._contourClosed?[...this.host._wallChainSegmentCms,this.host._closingWallCm??void 0]:this.host._wallChainSegmentCms,l,ut).map(t=>$(t,this.host._cellCm,this.host._gridPitch)/2):[],p=h?zi(h,$(l,this.host._cellCm,this.host._gridPitch)/2,this.host._contourClosed,c):"",u=h?this._drawPreviewJoinPatchD(h,c):"",m=this.host._wallFaceBatch?.candidates[this.host._wallFaceBatch.index]?.repair||this.host._wallRepairDiagnostic;return _` ${this._gridLevels()?_``:d} ${o.map(t=>_``)} ${this._renderPhysicalEditorLayer()} - ${"column"===this.host._tool&&this.host._cursorPt&&this.host._drawWallCm?_`{const t={shape:"square",center:this.host._cursorPt,cm:this.host._drawWallCm};return`M ${Ie(t,this.host._cellCm,this.host._gridPitch).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`})()}>`:d} + ${"column"===this.host._tool&&this.host._cursorPt&&this.host._drawWallCm?_`{const t={shape:"square",center:this.host._cursorPt,cm:this.host._drawWallCm};return`M ${Te(t,this.host._cellCm,this.host._gridPitch).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`})()}>`:d} ${p?_` `:d} - ${h&&0===l?_`t.join(",")).join(" ")}>`:d} ${u?_` `:d} @@ -1800,7 +1808,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623

    ${this.host._t("confirm.delete_partition_openings_body",{count:t.openings.length})}

      - ${t.openings.map(t=>p`
    • ${this.host._t("confirm.delete_partition_openings_item",{type:this.host._t(`opening.${t.type}`),length:Ot(t.length*sd/this.host._gridPitch*this.host._cellCm,e)})}
    • `)} + ${t.openings.map(t=>p`
    • ${this.host._t("confirm.delete_partition_openings_item",{type:this.host._t(`opening.${t.type}`),length:Ot(t.length*id/this.host._gridPitch*this.host._cellCm,e)})}
    • `)}
    @@ -1843,8 +1851,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 `:d}
    this.host._physicalDialog={...t,cm:e.target.value}} /> ${this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")}
    ${e&&"square"===t.shape?p` @@ -1967,7 +1975,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    -
    `}_discoveryFilterState(t){const e=this.host._settings,s=void 0!==t.draftGroupLights?t.draftGroupLights:!1!==e.group_lights,i=e.exclude_integrations,o=void 0!==t.draftExcluded?null===t.draftExcluded?[...Ri]:t.draftExcluded:i?[...i]:[...Ri],a=void 0!==t.draftExcluded?null===t.draftExcluded:!i,n=void 0!==t.draftGroupLights||void 0!==t.draftExcluded;return{groupLights:s,excluded:o.sort(),usesProductList:a,dirty:n}}_registryIntegrations(){const t=new Set,e=this.host._fullRegistryHass;for(const s of Object.values(e?.entities||{}))s?.platform&&t.add(String(s.platform));for(const s of Object.values(e?.devices||{})){const e=s?.identifiers?.[0],i=Array.isArray(e)?e[0]:null;i&&t.add(String(i))}return[...t].sort()}_discoveryFilterPreview(t){const e=this._discoveryFilterState(t),s=[e.groupLights?1:0,e.usesProductList?"p":e.excluded.join(","),this.host._cfgEpoch,this.host._regSignature].join("|");if(this._discoveryPreviewMemo?.key===s)return this._discoveryPreviewMemo.value;const i={hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),markers:this.host._markers,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||"",loc:t=>this.host._t(t),iconRules:this.host._iconRules},o=(t,e)=>new Set(co({...i,settings:t,excluded:e})),a=(t,e)=>new Set(po({...i,settings:t,excluded:e}).map(t=>t.bindingRef||t.id)),n=Ai(this.host._settings),r={...this.host._settings,group_lights:e.groupLights},l=new Set(e.excluded),h=o(this.host._settings,n),c=o(r,l),d=a(this.host._settings,n),p=a(r,l);let u=0,_=0,m=0;const g=t=>t.includes("light.");for(const t of h)c.has(t)||(u++,g(t)&&m++);for(const t of c)h.has(t)||(_++,g(t)&&m++);for(const t of p)d.has(t)||(u++,g(t)&&m++);for(const t of d)p.has(t)||(_++,g(t)&&m++);const f={appear:u,hide:_,lights:m};return this._discoveryPreviewMemo={key:s,value:f},f}async _saveDiscoveryFilters(t){const e=this.host._serverCfg;if(!e)return;const s=this._discoveryFilterState(t),i={...e.settings};s.groupLights?delete i.group_lights:i.group_lights=!1,s.usesProductList?delete i.exclude_integrations:i.exclude_integrations=s.excluded,this.host._serverCfg={...e,settings:i},this.host._deviceInboxMemo=null,this._discoveryPreviewMemo=null,this.host._regSignature="",this.host._deviceInbox&&(this.host._deviceInbox={...t,draftGroupLights:void 0,draftExcluded:void 0}),this._saveConfig(),this.host._maybeRebuildDevices(),this.host.requestUpdate()}_renderDiscoveryFilters(t){const e=this._discoveryFilterState(t),s=e=>this.host._deviceInbox={...t,...e},i=t.filtersOpen&&e.dirty?this._discoveryFilterPreview(t):null,o=this._registryIntegrations().filter(t=>!e.excluded.includes(t));return p`
    `}_discoveryFilterState(t){const e=this.host._settings,s=void 0!==t.draftGroupLights?t.draftGroupLights:!1!==e.group_lights,i=e.exclude_integrations,o=void 0!==t.draftExcluded?null===t.draftExcluded?[...Ai]:t.draftExcluded:i?[...i]:[...Ai],a=void 0!==t.draftExcluded?null===t.draftExcluded:!i,n=void 0!==t.draftGroupLights||void 0!==t.draftExcluded;return{groupLights:s,excluded:o.sort(),usesProductList:a,dirty:n}}_registryIntegrations(){const t=new Set,e=this.host._fullRegistryHass;for(const s of Object.values(e?.entities||{}))s?.platform&&t.add(String(s.platform));for(const s of Object.values(e?.devices||{})){const e=s?.identifiers?.[0],i=Array.isArray(e)?e[0]:null;i&&t.add(String(i))}return[...t].sort()}_discoveryFilterPreview(t){const e=this._discoveryFilterState(t),s=[e.groupLights?1:0,e.usesProductList?"p":e.excluded.join(","),this.host._cfgEpoch,this.host._regSignature].join("|");if(this._discoveryPreviewMemo?.key===s)return this._discoveryPreviewMemo.value;const i={hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),markers:this.host._markers,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||"",loc:t=>this.host._t(t),iconRules:this.host._iconRules},o=(t,e)=>new Set(po({...i,settings:t,excluded:e})),a=(t,e)=>new Set(uo({...i,settings:t,excluded:e}).map(t=>t.bindingRef||t.id)),n=Fi(this.host._settings),r={...this.host._settings,group_lights:e.groupLights},l=new Set(e.excluded),h=o(this.host._settings,n),c=o(r,l),d=a(this.host._settings,n),p=a(r,l);let u=0,_=0,m=0;const g=t=>t.includes("light.");for(const t of h)c.has(t)||(u++,g(t)&&m++);for(const t of c)h.has(t)||(_++,g(t)&&m++);for(const t of p)d.has(t)||(u++,g(t)&&m++);for(const t of d)p.has(t)||(_++,g(t)&&m++);const f={appear:u,hide:_,lights:m};return this._discoveryPreviewMemo={key:s,value:f},f}async _saveDiscoveryFilters(t){const e=this.host._serverCfg;if(!e)return;const s=this._discoveryFilterState(t),i={...e.settings};s.groupLights?delete i.group_lights:i.group_lights=!1,s.usesProductList?delete i.exclude_integrations:i.exclude_integrations=s.excluded,this.host._serverCfg={...e,settings:i},this.host._deviceInboxMemo=null,this._discoveryPreviewMemo=null,this.host._regSignature="",this.host._deviceInbox&&(this.host._deviceInbox={...t,draftGroupLights:void 0,draftExcluded:void 0}),this._saveConfig(),this.host._maybeRebuildDevices(),this.host.requestUpdate()}_renderDiscoveryFilters(t){const e=this._discoveryFilterState(t),s=e=>this.host._deviceInbox={...t,...e},i=t.filtersOpen&&e.dirty?this._discoveryFilterPreview(t):null,o=this._registryIntegrations().filter(t=>!e.excluded.includes(t));return p`
    s({filtersOpen:t.target.open})}> ${this.host._t("device_inbox.filters_title")}
    - `}_markerValueBadgeFields(t){return Fi({touched:t.valueBadgeTouched,originalHas:t.originalHasValueBadge,original:t.originalValueBadge,enabled:t.valueBadgeEnabled,source:t.valueBadgeSource,position:t.valueBadgePosition})}_markerValueSourceFields(t){return Ni({touched:t.valueSourceTouched,originalHas:t.originalHasValueSource,original:t.originalValueSource,source:t.valueSource})}_markerDraft(t){if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return null;const e=Fs(t.room),s=Cs(t.binding,t.devId,()=>"__hp_device_preview__"),i=this.host._markers.find(e=>e.id===s||e.id===t.devId),o=Ts(t.binding,t.controls,this.host._bindingEntities(t.binding)),a=this._effectiveStoredTapAction(t),n={id:s,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle||null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===a&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:o.length?o:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:t.hideFromPlan,vacuum:i?.vacuum||null},r=!!i&&("string"==typeof i.area&&i.area.length>0||null===i.area&&!!i.space&&!!i.room_id);return"virtual"===t.binding||t.roomTouched?(n.space=e?.space||("virtual"===t.binding?this.host._space:null),n.area=e?.area||null,n.room_id=e?.roomId||null):r&&(n.space=i.space,n.area=i.area,n.room_id=i.room_id),n}_markerPreviewDevice(t){const e=this._markerDraft(t);if(!e)return null;const s=`${this.host._haRegistry.revision}\n${Ft(this.host._markers)}\n${JSON.stringify(e)}`;if(this.host._markerPreviewMemo?.key===s)return this.host._markerPreviewMemo.device;const i=Ei({hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),marker:e,siblingMarkers:this.host._markers,settings:this.host._settings,excluded:this.host._excluded,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||this.host._space,loc:t=>this.host._t(t),iconRules:this.host._iconRules});return this.host._markerPreviewMemo={key:s,device:i},i}_markerPreviewDevices(t){const e=this.host._markerPreviewDevicesMemo;if(e?.base===this.host._devices&&e.preview===t)return e.devices;const s=[...this.host._devices.filter(e=>e.id!==t.id),t];return this.host._markerPreviewDevicesMemo={base:this.host._devices,preview:t,devices:s},s}_toggleIntent(t,e=this.host._devices){return this.host._toggleIntent(t,e)}_toggleIntentForDialog(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s=this._markerPreviewDevices(e);return this._toggleIntent(e,s)}_toggleStateText(t,e){return this.host._toggleStateText(t,e)}_toggleConfirmationStateText(t){return this.host._toggleConfirmationStateText(t)}_toggleConfirmationLines(t){return this.host._toggleConfirmationLines(t)}_toggleHintLines(t){if(!t)return[];const e=t=>this.host._t(`marker.toggle_effect_${t.replace("-","_")}`),s=t=>this.host._t(`marker.toggle_skip_${t.replace("-","_")}`);return Hi(t,{single:t=>{if("via"in t&&"virtual-light"===t.via)return this.host._t("marker.virtual_light_target",{name:t.name});const e=t.entityId||("ref"in t?t.ref:""),s=t.name||e;return this.host._t("marker.toggle_hint_single",{name:s,id:e})},group:t=>this.host._t("marker.toggle_hint_group",{count:t.length,names:t.map(t=>`${t.name} (${t.entityId})`).join(", ")}),currentNext:(t,s)=>"virtual-light"===t.via?this.host._t("marker.virtual_light_current",{state:this.host._t("on"===t.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:e(s)}):this.host._t("marker.toggle_hint_current",{state:this._toggleStateText(t.entityId,t.state),effect:e(s)}),groupCurrentNext:(t,s)=>this.host._t("marker.toggle_hint_group_current",{on:t.filter(t=>"on"===t.state).length,count:t.length,effect:e(s)}),skipped:t=>this.host._t("marker.toggle_hint_skipped",{count:t.length,targets:t.map(t=>{const e=t.entityId||t.ref;return`${t.name||e} (${e}: ${s(t.reason)})`}).join(", ")}),none:t=>this.host._t(`marker.toggle_none_${t.replaceAll("-","_")}`)})}_effectiveStoredTapAction(t,e){return t.tapActionTouched?t.tapAction:zs(t.originalHasTapAction?t.originalTapAction:null,e)}_effectiveMarkerTapAction(t,e=this._markerPreviewDevice(t)){return this._effectiveStoredTapAction(t,e?.primary?.split(".")[0])}_announceToggleDraft(t){const e=this._markerPreviewDevice(t),s=t.tapActionTouched?t:{...t,tapAction:this._effectiveMarkerTapAction(t,e)},i="toggle"===s.tapAction?this._toggleHintLines(this._toggleIntentForDialog(s)).join(" "):"";return{...s,tapHintAnnouncement:i}}_valueBadgeForBinding(t,e){const s={...t,binding:e,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},i=this._markerPreviewDevice(s);if(!i)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const o=[...this.host._devices.filter(t=>t.id!==i.id),i],a=Ds(this.host._planHass,i,o),n=Is(this.host._planHass,i,a);return{valueBadgeEnabled:t.valueBadgeEnabled&&!!n,valueBadgeSource:n,valueBadgeTouched:!0}}_markerSpatialSource(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s={...e,hidden:!1};return Oi(Li(this.host._planHass,[...this.host._devices.filter(t=>t.id!==s.id),s],null,this.host._virtualLights).filter(t=>t.device.id===s.id))}_markerAutoHasSpatialSource(t){const e={...t,lightRole:"auto",lightRoleTouched:!0},s=this._markerPreviewDevice(e);return!!s&&Bi(this.host._planHass,{...s})}_setMarkerLightRole(t){const e=this.host._markerDialog;e&&(this.host._markerDialog={...e,lightRole:t,lightRoleTouched:!0})}_controlRefInfo(t){if(!t.startsWith("marker:"))return{label:this.host.hass.states[t]?.attributes?.friendly_name||t,sub:t,icon:t.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this.host._planEntityAvailable(t)};const e=t.slice(7),s=this.host._markers.find(t=>t.id===e),i=this.host._devices.find(t=>t.id===e);if(!s||s.removed||!0!==s.is_light)return{label:this.host._t("marker.control_missing_label"),sub:`${this.host._t("marker.control_broken")} (${t})`,icon:"mdi:alert-outline",warning:!0};const o=this.host._serverCfg?.spaces.find(t=>t.id===(i?.space||s.space)),a=!!i&&Wi(i).length>0;return{label:s.name||i?.name||e,sub:[o?.title||i?.space||s.space,s.room_id||i?.area,a?"":this.host._t("marker.control_passive")].filter(Boolean).join(" · "),icon:s.icon||i?.icon||"mdi:lightbulb-outline",warning:!0===s.hidden||!0===i?.hidden}}_valueBadgeCandidateLabel(t){const e=t.source;if("derived_lqi"===e.kind)return this.host._t("marker.value_badge_lqi");if("derived_marker_state"===e.kind)return this.host._t("marker.value_badge_marker_state",{name:t.label});if("entity_state"===e.kind)return this.host._t("marker.value_badge_state",{name:t.label});const s=this.host.hass.states[e.entity_id]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[e.entity_id]?.name||e.entity_id;return this.host._t(`marker.value_badge_attr_${e.attribute}`,{name:s})}_controlCandidates(t){const e=this._markerDraft(t)?.id||t.devId||"",s=[],i=new Set;for(const t of this.host._markers){if(t.id===e||t.removed||t.hidden||!0!==t.is_light)continue;if("virtual"!==t.binding&&"active"!==this.host._bindingStatus(t.binding).kind)continue;const o=this.host._devices.find(e=>e.id===t.id);if(!o||o.hidden)continue;const a=this._controlRefInfo(`marker:${t.id}`);for(const t of Wi(o))i.add(t);s.push({value:`marker:${t.id}`,label:a.label,sub:a.sub,icon:a.icon,search:`${a.label} ${a.sub} ${t.id} ${Wi(o).join(" ")}`.toLowerCase()})}const o=Object.keys(this.host.hass.states||{}).filter(e=>ji(e)&&!i.has(e)&&Gi(t.binding,[e],this.host._bindingEntities(t.binding)).length>0&&this.host._planEntityAvailable(e)).map(t=>{const e=this._controlRefInfo(t);return{value:t,label:e.label,sub:t,icon:e.icon,search:`${e.label} ${t}`.toLowerCase()}}),a=t.controlsFilter.trim().toLowerCase();return[...s,...o].filter(e=>!t.controls.includes(e.value)&&(!a||e.search.includes(a))).slice(0,12).map(({search:t,...e})=>e)}_addControlRef(t,e){if(e.startsWith("marker:")){const s=this._markerDraft(t)?.id||t.devId||"";if(!s)return void this.host._showToast(this.host._t("toast.marker_binding_required"));const i=e.slice(7),o=this._markerDraft(t),a=o?[...this.host._markers.filter(t=>t.id!==s),o]:this.host._markers;if(qi(a,s,i))return void this.host._showToast(this.host._t("toast.marker_control_cycle"))}this.host._markerDialog=this._announceToggleDraft({...t,controls:[...t.controls,e],controlsFilter:""})}_setMarkerGlowMode(t){const e=this.host._markerDialog;if(!e)return;if("auto"===t)return void(this.host._markerDialog={...e,glowMode:t,glowTouched:!0});const s=this._markerSpatialSource(e),i=Ui(s?this.host._planHass.states[s.eid]:void 0,null,this.host._fillColors.glow_light.c),o=!e.glowColorDrafted,a="fixed"===t&&!e.glowBrightnessDrafted;this.host._markerDialog={...e,glowMode:t,glowColor:o?i.c:e.glowColor,glowBrightness:a?Math.max(1,Math.round(100*i.bri)):e.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:e.glowBrightnessDrafted||"fixed"===t,glowTouched:!0}}_renderRadarSection(t,e,s="main"){return ph({dialog:t,device:e,registryHass:this.host._fullRegistryHass,planHass:this.host._planHass,hass:this.host.hass,spaceModelById:t=>this.host._spaceModelById(t),currentSpace:()=>this.host._spaceModel(),position:t=>this.host._pos(t),updateDialog:t=>{this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,...t})},dialogDeviceId:()=>this.host._markerDialog?.devId,t:(t,e)=>this.host._t(t,e),help:t=>this._help(t),boolInput:(t,e)=>this._boolInput(t,e),toast:t=>this.host._showToast(t),setup:this._radarSetup,configRev:this.host._cfgRev},s)}_renderMarkerDialog(){const t=this.host._markerDialog,e="virtual"===t.bindingMode,s=this._bindingCandidates();this.host._bindingEntities(t.binding);const i=e?null:this.host._bindingStatus(t.binding),o=!e&&this.host._bindingHasHaPage(t.binding),a=this._markerPreviewDevice(t),n=this._effectiveMarkerTapAction(t,a),r=a?Ws(this.host._serverCfg?.spaces.find(t=>t.id===a.space)):null,l=a?this._markerPreviewDevices(a):this.host._devices,h="toggle"===n&&a?this._toggleIntent(a,l):null,c=this._toggleHintLines(h),u=a?Ki(this.host._planHass,a,{liveStates:!1!==this.host._config?.live_states,showTemperature:!1!==this.host._config?.show_temperature,showSignal:r?.showLqi??!1!==this.host._config?.show_signal,designPreview:!0,activityRuntime:this.host._activityRt.get(a.id),lightDevices:l,registryHass:this.host._fullRegistryHass,reducedMotion:this.host._reducedMotion}):null,_=a?Ds(this.host._planHass,a,l):[],m=a?Is(this.host._planHass,a,_):null,g=t.valueBadgeTouched?t.valueBadgeEnabled:!!u?.valueBadge,f=t.valueBadgeTouched?t.valueBadgeSource:u?.valueBadge?.source||t.valueBadgeSource,b=t.valueBadgeTouched?t.valueBadgePosition:u?.valueBadge?.position||t.valueBadgePosition,v=Vi(f),y=!!f&&!_.some(t=>t.key===v),$=_.find(t=>t.key===v),w=Vi(t.valueSource),k=!(!t.valueSource||w&&_.some(t=>t.key===w)),x=_.find(t=>t.key===w),S=u?.valueSource?.sourceKey||"",M=this._markerAutoHasSpatialSource(t),C=!!a&&Ji(this.host._planHass,{...a}),P=Yi(t.lightRole,M,C,t.glowMode),D=!P.sourceExists,I=!P.fromSourceEnabled,T=P.passive,z=P.effectiveMode,R="never"===t.lightRole?this.host._t("marker.glow_disabled_never"):"auto"!==t.lightRole||M?T?this.host._t("marker.glow_passive_hint"):this.host._t("marker.glow_disabled_no_entity"):this.host._t("marker.glow_disabled_auto"),A=a?Wi(a):[],F=a&&Xi(a)||"",N=!!t.lightEntity&&!A.includes(t.lightEntity),E=a?Zi(a):[],H=!!t.toggleEntity&&!E.includes(t.toggleEntity),O="toggle"===n?this._toggleIntentForDialog({...t,toggleEntity:"",toggleEntityTouched:!0}):null,L=O?[...O.targets,...O.skippedTargets].map(t=>t.entityId||("ref"in t?t.ref:"")).filter(Boolean).join(", "):"",B=(()=>{if(e)return null;const i=s.find(e=>e.value===t.binding);if(i)return i.label;const[o,a]=t.binding.split(":");return"device"===o?this.host._fullRegistryHass.devices[a]?.name_by_user||this.host._fullRegistryHass.devices[a]?.name||a:this.host._fullRegistryHass.entities[a]?.name||this.host.hass.states[a]?.attributes?.friendly_name||a})();return p``}_markerValueBadgeFields(t){return Ni({touched:t.valueBadgeTouched,originalHas:t.originalHasValueBadge,original:t.originalValueBadge,enabled:t.valueBadgeEnabled,source:t.valueBadgeSource,position:t.valueBadgePosition})}_markerValueSourceFields(t){return Ei({touched:t.valueSourceTouched,originalHas:t.originalHasValueSource,original:t.originalValueSource,source:t.valueSource})}_markerDraft(t){if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return null;const e=Ns(t.room),s=Ps(t.binding,t.devId,()=>"__hp_device_preview__"),i=this.host._markers.find(e=>e.id===s||e.id===t.devId),o=Rs(t.binding,t.controls,this.host._bindingEntities(t.binding)),a=this._effectiveStoredTapAction(t),n={id:s,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle||null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===a&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:o.length?o:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),...this._markerValueSourceFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=rt(t.glowRadius);return null==e||e<=0?null:Math.round(this.host._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:t.hideFromPlan,vacuum:i?.vacuum||null},r=!!i&&("string"==typeof i.area&&i.area.length>0||null===i.area&&!!i.space&&!!i.room_id);return"virtual"===t.binding||t.roomTouched?(n.space=e?.space||("virtual"===t.binding?this.host._space:null),n.area=e?.area||null,n.room_id=e?.roomId||null):r&&(n.space=i.space,n.area=i.area,n.room_id=i.room_id),n}_markerPreviewDevice(t){const e=this._markerDraft(t);if(!e)return null;const s=`${this.host._haRegistry.revision}\n${Ft(this.host._markers)}\n${JSON.stringify(e)}`;if(this.host._markerPreviewMemo?.key===s)return this.host._markerPreviewMemo.device;const i=Hi({hass:this.host.hass,registry:this.host._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this.host._areaToSpace).map(([t,e])=>[t,e.space])),marker:e,siblingMarkers:this.host._markers,settings:this.host._settings,excluded:this.host._excluded,showAll:this.host._showAll,firstSpaceId:this.host._model[0]?.id||this.host._space,loc:t=>this.host._t(t),iconRules:this.host._iconRules});return this.host._markerPreviewMemo={key:s,device:i},i}_markerPreviewDevices(t){const e=this.host._markerPreviewDevicesMemo;if(e?.base===this.host._devices&&e.preview===t)return e.devices;const s=[...this.host._devices.filter(e=>e.id!==t.id),t];return this.host._markerPreviewDevicesMemo={base:this.host._devices,preview:t,devices:s},s}_toggleIntent(t,e=this.host._devices){return this.host._toggleIntent(t,e)}_toggleIntentForDialog(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s=this._markerPreviewDevices(e);return this._toggleIntent(e,s)}_toggleStateText(t,e){return this.host._toggleStateText(t,e)}_toggleConfirmationStateText(t){return this.host._toggleConfirmationStateText(t)}_toggleConfirmationLines(t){return this.host._toggleConfirmationLines(t)}_toggleHintLines(t){if(!t)return[];const e=t=>this.host._t(`marker.toggle_effect_${t.replace("-","_")}`),s=t=>this.host._t(`marker.toggle_skip_${t.replace("-","_")}`);return Oi(t,{single:t=>{if("via"in t&&"virtual-light"===t.via)return this.host._t("marker.virtual_light_target",{name:t.name});const e=t.entityId||("ref"in t?t.ref:""),s=t.name||e;return this.host._t("marker.toggle_hint_single",{name:s,id:e})},group:t=>this.host._t("marker.toggle_hint_group",{count:t.length,names:t.map(t=>`${t.name} (${t.entityId})`).join(", ")}),currentNext:(t,s)=>"virtual-light"===t.via?this.host._t("marker.virtual_light_current",{state:this.host._t("on"===t.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:e(s)}):this.host._t("marker.toggle_hint_current",{state:this._toggleStateText(t.entityId,t.state),effect:e(s)}),groupCurrentNext:(t,s)=>this.host._t("marker.toggle_hint_group_current",{on:t.filter(t=>"on"===t.state).length,count:t.length,effect:e(s)}),skipped:t=>this.host._t("marker.toggle_hint_skipped",{count:t.length,targets:t.map(t=>{const e=t.entityId||t.ref;return`${t.name||e} (${e}: ${s(t.reason)})`}).join(", ")}),none:t=>this.host._t(`marker.toggle_none_${t.replaceAll("-","_")}`)})}_effectiveStoredTapAction(t,e){return t.tapActionTouched?t.tapAction:zs(t.originalHasTapAction?t.originalTapAction:null,e)}_effectiveMarkerTapAction(t,e=this._markerPreviewDevice(t)){return this._effectiveStoredTapAction(t,e?.primary?.split(".")[0])}_announceToggleDraft(t){const e=this._markerPreviewDevice(t),s=t.tapActionTouched?t:{...t,tapAction:this._effectiveMarkerTapAction(t,e)},i="toggle"===s.tapAction?this._toggleHintLines(this._toggleIntentForDialog(s)).join(" "):"";return{...s,tapHintAnnouncement:i}}_valueBadgeForBinding(t,e){const s={...t,binding:e,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},i=this._markerPreviewDevice(s);if(!i)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const o=[...this.host._devices.filter(t=>t.id!==i.id),i],a=Is(this.host._planHass,i,o),n=Ts(this.host._planHass,i,a);return{valueBadgeEnabled:t.valueBadgeEnabled&&!!n,valueBadgeSource:n,valueBadgeTouched:!0}}_markerSpatialSource(t){const e=this._markerPreviewDevice(t);if(!e)return null;const s={...e,hidden:!1};return Li(Bi(this.host._planHass,[...this.host._devices.filter(t=>t.id!==s.id),s],null,this.host._virtualLights).filter(t=>t.device.id===s.id))}_markerAutoHasSpatialSource(t){const e={...t,lightRole:"auto",lightRoleTouched:!0},s=this._markerPreviewDevice(e);return!!s&&Wi(this.host._planHass,{...s})}_setMarkerLightRole(t){const e=this.host._markerDialog;e&&(this.host._markerDialog={...e,lightRole:t,lightRoleTouched:!0})}_controlRefInfo(t){if(!t.startsWith("marker:"))return{label:this.host.hass.states[t]?.attributes?.friendly_name||t,sub:t,icon:t.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this.host._planEntityAvailable(t)};const e=t.slice(7),s=this.host._markers.find(t=>t.id===e),i=this.host._devices.find(t=>t.id===e);if(!s||s.removed||!0!==s.is_light)return{label:this.host._t("marker.control_missing_label"),sub:`${this.host._t("marker.control_broken")} (${t})`,icon:"mdi:alert-outline",warning:!0};const o=this.host._serverCfg?.spaces.find(t=>t.id===(i?.space||s.space)),a=!!i&&ji(i).length>0;return{label:s.name||i?.name||e,sub:[o?.title||i?.space||s.space,s.room_id||i?.area,a?"":this.host._t("marker.control_passive")].filter(Boolean).join(" · "),icon:s.icon||i?.icon||"mdi:lightbulb-outline",warning:!0===s.hidden||!0===i?.hidden}}_valueBadgeCandidateLabel(t){const e=t.source;if("derived_lqi"===e.kind)return this.host._t("marker.value_badge_lqi");if("derived_marker_state"===e.kind)return this.host._t("marker.value_badge_marker_state",{name:t.label});if("entity_state"===e.kind)return this.host._t("marker.value_badge_state",{name:t.label});const s=this.host.hass.states[e.entity_id]?.attributes?.friendly_name||this.host._fullRegistryHass.entities[e.entity_id]?.name||e.entity_id;return this.host._t(`marker.value_badge_attr_${e.attribute}`,{name:s})}_controlCandidates(t){const e=this._markerDraft(t)?.id||t.devId||"",s=[],i=new Set;for(const t of this.host._markers){if(t.id===e||t.removed||t.hidden||!0!==t.is_light)continue;if("virtual"!==t.binding&&"active"!==this.host._bindingStatus(t.binding).kind)continue;const o=this.host._devices.find(e=>e.id===t.id);if(!o||o.hidden)continue;const a=this._controlRefInfo(`marker:${t.id}`);for(const t of ji(o))i.add(t);s.push({value:`marker:${t.id}`,label:a.label,sub:a.sub,icon:a.icon,search:`${a.label} ${a.sub} ${t.id} ${ji(o).join(" ")}`.toLowerCase()})}const o=Object.keys(this.host.hass.states||{}).filter(e=>Gi(e)&&!i.has(e)&&qi(t.binding,[e],this.host._bindingEntities(t.binding)).length>0&&this.host._planEntityAvailable(e)).map(t=>{const e=this._controlRefInfo(t);return{value:t,label:e.label,sub:t,icon:e.icon,search:`${e.label} ${t}`.toLowerCase()}}),a=t.controlsFilter.trim().toLowerCase();return[...s,...o].filter(e=>!t.controls.includes(e.value)&&(!a||e.search.includes(a))).slice(0,12).map(({search:t,...e})=>e)}_addControlRef(t,e){if(e.startsWith("marker:")){const s=this._markerDraft(t)?.id||t.devId||"";if(!s)return void this.host._showToast(this.host._t("toast.marker_binding_required"));const i=e.slice(7),o=this._markerDraft(t),a=o?[...this.host._markers.filter(t=>t.id!==s),o]:this.host._markers;if(Ui(a,s,i))return void this.host._showToast(this.host._t("toast.marker_control_cycle"))}this.host._markerDialog=this._announceToggleDraft({...t,controls:[...t.controls,e],controlsFilter:""})}_setMarkerGlowMode(t){const e=this.host._markerDialog;if(!e)return;if("auto"===t)return void(this.host._markerDialog={...e,glowMode:t,glowTouched:!0});const s=this._markerSpatialSource(e),i=Ki(s?this.host._planHass.states[s.eid]:void 0,null,this.host._fillColors.glow_light.c),o=!e.glowColorDrafted,a="fixed"===t&&!e.glowBrightnessDrafted;this.host._markerDialog={...e,glowMode:t,glowColor:o?i.c:e.glowColor,glowBrightness:a?Math.max(1,Math.round(100*i.bri)):e.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:e.glowBrightnessDrafted||"fixed"===t,glowTouched:!0}}_renderRadarSection(t,e,s="main"){return uh({dialog:t,device:e,registryHass:this.host._fullRegistryHass,planHass:this.host._planHass,hass:this.host.hass,spaceModelById:t=>this.host._spaceModelById(t),currentSpace:()=>this.host._spaceModel(),position:t=>this.host._pos(t),updateDialog:t=>{this.host._markerDialog&&(this.host._markerDialog={...this.host._markerDialog,...t})},dialogDeviceId:()=>this.host._markerDialog?.devId,t:(t,e)=>this.host._t(t,e),help:t=>this._help(t),boolInput:(t,e)=>this._boolInput(t,e),toast:t=>this.host._showToast(t),setup:this._radarSetup,configRev:this.host._cfgRev},s)}_renderMarkerDialog(){const t=this.host._markerDialog,e="virtual"===t.bindingMode,s=this._bindingCandidates();this.host._bindingEntities(t.binding);const i=e?null:this.host._bindingStatus(t.binding),o=!e&&this.host._bindingHasHaPage(t.binding),a=this._markerPreviewDevice(t),n=this._effectiveMarkerTapAction(t,a),r=a?js(this.host._serverCfg?.spaces.find(t=>t.id===a.space)):null,l=a?this._markerPreviewDevices(a):this.host._devices,h="toggle"===n&&a?this._toggleIntent(a,l):null,c=this._toggleHintLines(h),u=a?Vi(this.host._planHass,a,{liveStates:!1!==this.host._config?.live_states,showTemperature:!1!==this.host._config?.show_temperature,showSignal:r?.showLqi??!1!==this.host._config?.show_signal,designPreview:!0,activityRuntime:this.host._activityRt.get(a.id),lightDevices:l,registryHass:this.host._fullRegistryHass,reducedMotion:this.host._reducedMotion}):null,_=a?Is(this.host._planHass,a,l):[],m=a?Ts(this.host._planHass,a,_):null,g=t.valueBadgeTouched?t.valueBadgeEnabled:!!u?.valueBadge,f=t.valueBadgeTouched?t.valueBadgeSource:u?.valueBadge?.source||t.valueBadgeSource,b=t.valueBadgeTouched?t.valueBadgePosition:u?.valueBadge?.position||t.valueBadgePosition,v=Ji(f),y=!!f&&!_.some(t=>t.key===v),$=_.find(t=>t.key===v),w=Ji(t.valueSource),k=!(!t.valueSource||w&&_.some(t=>t.key===w)),x=_.find(t=>t.key===w),S=u?.valueSource?.sourceKey||"",M=this._markerAutoHasSpatialSource(t),C=!!a&&Yi(this.host._planHass,{...a}),P=Xi(t.lightRole,M,C,t.glowMode),D=!P.sourceExists,I=!P.fromSourceEnabled,T=P.passive,R=P.effectiveMode,z="never"===t.lightRole?this.host._t("marker.glow_disabled_never"):"auto"!==t.lightRole||M?T?this.host._t("marker.glow_passive_hint"):this.host._t("marker.glow_disabled_no_entity"):this.host._t("marker.glow_disabled_auto"),A=a?ji(a):[],F=a&&Zi(a)||"",N=!!t.lightEntity&&!A.includes(t.lightEntity),E=a?Qi(a):[],H=!!t.toggleEntity&&!E.includes(t.toggleEntity),O="toggle"===n?this._toggleIntentForDialog({...t,toggleEntity:"",toggleEntityTouched:!0}):null,L=O?[...O.targets,...O.skippedTargets].map(t=>t.entityId||("ref"in t?t.ref:"")).filter(Boolean).join(", "):"",B=(()=>{if(e)return null;const i=s.find(e=>e.value===t.binding);if(i)return i.label;const[o,a]=t.binding.split(":");return"device"===o?this.host._fullRegistryHass.devices[a]?.name_by_user||this.host._fullRegistryHass.devices[a]?.name||a:this.host._fullRegistryHass.entities[a]?.name||this.host.hass.states[a]?.attributes?.friendly_name||a})();return p`this._closeMarkerDialog()}>
    @@ -2123,7 +2131,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    @@ -2148,7 +2156,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 @input=${e=>this.host._markerDialog={...t,bindingFilter:e.target.value}} />
    ${s.map(e=>p`
    {if(e.value===t.binding)return void(this.host._markerDialog={...t,bindingOpen:!1});const s={...t,binding:e.value,bindingOpen:!1,controls:Ts(e.value,t.controls,this.host._bindingEntities(e.value)),autoIcon:this.host._autoIconForBinding(e.value),...sh(t.radar,t.radarTouched,t.radarRemove)};this.host._markerDialog=this._announceToggleDraft({...s,...this._valueBadgeForBinding(s,e.value),valueSource:null,valueSourceTouched:!0})}}> + @click=${()=>{if(e.value===t.binding)return void(this.host._markerDialog={...t,bindingOpen:!1});const s={...t,binding:e.value,bindingOpen:!1,controls:Rs(e.value,t.controls,this.host._bindingEntities(e.value)),autoIcon:this.host._autoIconForBinding(e.value),...ih(t.radar,t.radarTouched,t.radarRemove)};this.host._markerDialog=this._announceToggleDraft({...s,...this._valueBadgeForBinding(s,e.value),valueSource:null,valueSourceTouched:!0})}}> ${e.label}${e.sub}
    `)} ${s.length?d:p`
    ${this.host._t("marker.nothing_found")}
    `} @@ -2158,7 +2166,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 {const s={...t,tapAction:e.target.value,tapActionTouched:!0};this.host._markerDialog=this._announceToggleDraft(s)}}> - ${Qi.map(t=>[t,"tap."+t.replace("-","_")]).map(([t,e])=>p``)} @@ -2285,30 +2293,30 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("marker.glow_color_label")}${this._help("marker.glow_mode.help")}
    - ${"auto"!==z?p`
    + ${"auto"!==R?p`
    {this.host._markerDialog={...t,glowMode:z,glowColor:e.detail.color,glowColorDrafted:!0,glowTouched:!0}}}> - ${"fixed"===z?p` + @hp-color-opacity-change=${e=>{this.host._markerDialog={...t,glowMode:R,glowColor:e.detail.color,glowColorDrafted:!0,glowTouched:!0}}}> + ${"fixed"===R?p` ${this.host._t("marker.glow_brightness")} - ${this._rangeInput(1,100,1,t.glowBrightness,e=>{this.host._markerDialog={...t,glowMode:z,glowBrightness:e,glowBrightnessDrafted:!0,glowTouched:!0}},D,this.host._t("marker.glow_brightness"))} + ${this._rangeInput(1,100,1,t.glowBrightness,e=>{this.host._markerDialog={...t,glowMode:R,glowBrightness:e,glowBrightnessDrafted:!0,glowTouched:!0}},D,this.host._t("marker.glow_brightness"))} ${Math.round(t.glowBrightness)}%`:d}
    `:d} @@ -2327,7 +2335,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${D||T?p`

    - ${R} + ${z}

    `:d} @@ -2347,19 +2355,19 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 -

    ${this.host._t(Zc[t.display])}

    +

    ${this.host._t(Qc[t.display])}

    ${"value"===t.display?p`
    ${this._help("marker.value_source.help")}
    this.host._markerDialog={...t,valueBadgeSource:eo(e.target.value),valueBadgeEnabled:!0,valueBadgeTouched:!0}}> + @change=${e=>this.host._markerDialog={...t,valueBadgeSource:so(e.target.value),valueBadgeEnabled:!0,valueBadgeTouched:!0}}> ${y?p``:d} @@ -2481,7 +2489,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${t.pdfs.map(t=>p` - ${t.name} + ${t.name} this._removeMarkerPdf(t.url)}>`)}
    this.host._spaceDialog={...t,fillMode:e}} /> ${this.host._t(s)} @@ -2703,8 +2711,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 .label=${this.host._t("space.custom_fill")} .opacityLabel=${this.host._t("space.opacity")} .pickerLabels=${this.host._colorPickerLabels} - .color=${(t.customFill||Gs).c} - .opacity=${(t.customFill||Gs).a} + .color=${(t.customFill||qs).c} + .opacity=${(t.customFill||qs).a} @hp-color-opacity-change=${e=>{this.host._spaceDialog={...t,customFill:{c:e.detail.color,a:e.detail.opacity}}}}> ${t.customFill?p`
    `)}
    -
    `:d}`:d}`}_renderRoomDialog(){const t=!!this.host._roomEditId,e=t?null:this.host._wallFaceBatch,s=e&&e.candidates.length>1?this.host._t("room.queue_progress",{current:e.index+1,total:e.candidates.length}):"",i=Ws(this.host._curSpaceCfg),o=this.host._roomFill||i.fill,a=this.host._roomCustomFill||i.customFill,n=nt(this.host._roomTempMin,this.host._roomTempMax).valid,r=(!!this.host._areaSel||!!this.host._nameSel.trim())&&n,l=[...this.host._freeAreas];if(t&&this.host._areaSel&&!l.some(t=>t.area_id===this.host._areaSel)){const t=this.host.hass.areas[this.host._areaSel];t&&l.unshift(t)}return p``:d}`:d}`}_renderRoomDialog(){const t=!!this.host._roomEditId,e=t?null:this.host._wallFaceBatch,s=e&&e.candidates.length>1?this.host._t("room.queue_progress",{current:e.index+1,total:e.candidates.length}):"",i=js(this.host._curSpaceCfg),o=this.host._roomFill||i.fill,a=this.host._roomCustomFill||i.customFill,n=nt(this.host._roomTempMin,this.host._roomTempMax).valid,r=(!!this.host._areaSel||!!this.host._nameSel.trim())&&n,l=[...this.host._freeAreas];if(t&&this.host._areaSel&&!l.some(t=>t.area_id===this.host._areaSel)){const t=this.host.hass.areas[this.host._areaSel];t&&l.unshift(t)}return p`this._roomDialogCancel()}>
    @@ -2803,7 +2811,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 - ${[["","fill.inherit"],...ro.map(t=>[t,"fill."+t])].map(([t,e])=>p`
    - ${this.host._renderCardPreview(Ws(this.host._curSpaceCfg).cardFontScale,this.host._roomNameScale,this.host._roomLabelScale)} + ${this.host._renderCardPreview(js(this.host._curSpaceCfg).cardFontScale,this.host._roomNameScale,this.host._roomLabelScale)}
    @@ -2868,4 +2876,4 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("btn.save")} `}
    -
    `}}export{ad as EDITOR_RUNTIME_FINGERPRINT,nd as HouseplanEditorRuntime}; +
    `}}export{nd as EDITOR_RUNTIME_FINGERPRINT,rd as HouseplanEditorRuntime}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js b/dist/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js similarity index 82% rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js rename to dist/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js index fde24f47..92ed0a1b 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-D2XH4RQC.js +++ b/dist/houseplan-assets/houseplan-onboarding-runtime-BLRnH1D6.js @@ -1,6 +1,6 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{l as t,b3 as s,A as e,v as a,c as o,cm as l,cn as i,co as h,cp as c,b0 as n,cq as r,cv as p,cr as d,cs as _,ct as u,cu as g,cw as m,cx as b,ds as $,dt as v,du as f,a$ as y,b1 as w,dv as D}from"./houseplan-card-BCGpvbDT.js";import{c as k,e as S,r as C,a as M}from"./backdrop-pick-Caayxvt2.js";const F=1e3,x=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},T="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";class L{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_help(l){const i=`${l}.aria`,h=t(this.host.hass,this.host._config?.language);return s(h,l)&&s(h,i)?o``:e}_openSpaceDialog(t,s){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===t){const e=this.host._serverCfg.spaces.find(t=>t.id===s);if(!e)return;const a=l(e),o=e.settings?.custom_fill&&"object"==typeof e.settings.custom_fill?i(e.settings.custom_fill):null,p="none"===a.fill?{...o||h,a:0}:o;return void(this.host._spaceDialog={mode:t,spaceId:s,title:e.title,planUrl:e.plan_url||null,planFile:null,source:e.plan_url?"file":"draw",showBorders:a.showBorders,showNames:a.showNames,zeroWallStyle:r(e),displayTouched:!0,hideDecor:a.hideDecor,hideOpenings:a.hideOpenings,roomColor:a.color,roomOpacity:a.opacity,fillMode:"none"===a.fill?"custom":a.fill,customFill:p,glowEnabled:a.glow,bgColor:a.bgColor,bgMode:"static"===e.settings?.bg_mode||"daynight"===e.settings?.bg_mode?e.settings.bg_mode:null,northDeg:n({},e.settings),sunRays:"boolean"==typeof e.settings?.sun_rays?e.settings.sun_rays:null,tempMin:a.tempMin,tempMax:a.tempMax,showLqi:a.showLqi??this.host._config?.show_signal??!0,cardFontScale:a.cardFontScale,labelTemp:a.labelTemp,labelHum:a.labelHum,labelLqi:a.labelLqi,labelLight:a.labelLight,cellCm:Number(e.cell_cm)>0?Number(e.cell_cm):5,cellCmInput:c(Number(e.cell_cm)>0?Number(e.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const e=p(this.host._imperial);this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:{...h,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:e,cellCmInput:c(e,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const a=await k(e);if("reject"===a.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===a.kind)return void(this.host._backdropGuard=a.state);const o=await S(e,a.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:o})}_renderBackdropGuard(){return C(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??e}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),a=this.host._spaceDialog;return a&&a.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...a,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const s=this.host._spaceDialog,e=s?.saved?.find(s=>s.name===t);if(!s||!e||e.used_by.length||e.url===s.planUrl)return;const a=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),o=this.host._spaceDialog,l=o?.saved?.find(s=>s.name===t);if(a&&o&&l&&l.url===e.url&&l.modified===e.modified&&!l.used_by.length&&l.url!==o.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return o`
    ${this.host._t("space.loading")}
    `;const s=t.saved||[];if(!s.length)return o`
    ${this.host._t("space.no_saved")}
    `;return o`
    - ${s.map(s=>{return o` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{l as t,b4 as s,A as e,v as o,c as a,cn as l,co as i,cp as h,cq as c,b1 as n,cr as r,cw as p,cs as d,ct as _,cu as u,cv as g,cx as m,cy as b,dt as $,du as f,dv as v,b0 as y,b2 as w,dw as D}from"./houseplan-card-Di_izZTU.js";import{c as k,e as S,r as C,a as M}from"./backdrop-pick-CXmKHH6_.js";const F=1e3,x=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},T="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";class L{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_help(l){const i=`${l}.aria`,h=t(this.host.hass,this.host._config?.language);return s(h,l)&&s(h,i)?a``:e}_openSpaceDialog(t,s){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===t){const e=this.host._serverCfg.spaces.find(t=>t.id===s);if(!e)return;const o=l(e),a=e.settings?.custom_fill&&"object"==typeof e.settings.custom_fill?i(e.settings.custom_fill):null,p="none"===o.fill?{...a||h,a:0}:a;return void(this.host._spaceDialog={mode:t,spaceId:s,title:e.title,planUrl:e.plan_url||null,planFile:null,source:e.plan_url?"file":"draw",showBorders:o.showBorders,showNames:o.showNames,zeroWallStyle:r(e),displayTouched:!0,hideDecor:o.hideDecor,hideOpenings:o.hideOpenings,roomColor:o.color,roomOpacity:o.opacity,fillMode:"none"===o.fill?"custom":o.fill,customFill:p,glowEnabled:o.glow,bgColor:o.bgColor,bgMode:"static"===e.settings?.bg_mode||"daynight"===e.settings?.bg_mode?e.settings.bg_mode:null,northDeg:n({},e.settings),sunRays:"boolean"==typeof e.settings?.sun_rays?e.settings.sun_rays:null,tempMin:o.tempMin,tempMax:o.tempMax,showLqi:o.showLqi??this.host._config?.show_signal??!0,cardFontScale:o.cardFontScale,labelTemp:o.labelTemp,labelHum:o.labelHum,labelLqi:o.labelLqi,labelLight:o.labelLight,cellCm:Number(e.cell_cm)>0?Number(e.cell_cm):5,cellCmInput:c(Number(e.cell_cm)>0?Number(e.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const e=p(this.host._imperial);this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:{...h,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:e,cellCmInput:c(e,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await k(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await S(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return C(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??e}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const s=this.host._spaceDialog,e=s?.saved?.find(s=>s.name===t);if(!s||!e||e.used_by.length||e.url===s.planUrl)return;const o=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._spaceDialog,l=a?.saved?.find(s=>s.name===t);if(o&&a&&l&&l.url===e.url&&l.modified===e.modified&&!l.used_by.length&&l.url!==a.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return a`
    ${this.host._t("space.loading")}
    `;const s=t.saved||[];if(!s.length)return a`
    ${this.host._t("space.no_saved")}
    `;return a`
    + ${s.map(s=>{return a`
    @@ -16,16 +16,16 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    `;var e})} -
    `}async _saveConfigNow(){this.host._cfgEpoch++;try{await this.host._writeConfig()}catch(t){const s=t;throw s?.physicalGeometryRolledBack?await this.host._reloadRejectedPhysicalWrite():"conflict"===s?.code&&await this.host._reloadConfigOnly(),t}}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const s="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const e="create"===t.mode?`s${Date.now().toString(36)}`:t.spaceId;let a=null;if("file"===t.source&&t.planFile){a={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:e,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let o=t.savedAspect||null;!a&&"file"===t.source&&t.planUrl&&!o&&this.host._aspectJob&&(o=await this.host._aspectJob||null);const l=this.host._serverCfg;let i=l.spaces.find(t=>t.id===e);if("create"===t.mode)i=b(e,t.title.trim()),l.spaces.push(i);else{if(!i)throw new Error(`space ${e} is gone from the config`);i.title=t.title.trim()}if(!i)throw new Error(`space ${e} is unavailable`);if(a?(i.plan_url=a.url,i.plan_aspect=a.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==i.plan_url&&(i.plan_url=t.planUrl,i.plan_aspect=o),"draw"===t.source&&(i.plan_url=null,i.plan_aspect=null,delete i.plan_x,delete i.plan_y,delete i.plan_scale,delete i.plan_scale_x,delete i.plan_scale_y,delete i.plan_angle),i.settings={...i.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):_,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):d,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},i.zero_wall_style=t.zeroWallStyle,i.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(F,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(i.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length)this._openNextImport();else if(s||this.host._importTotal>0){const t=this.host._importTotal>0;this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),await this.host._requestMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._showToast(this.host._t(s&&!t?"toast.space_added_onboard":"import.done"))}else this.host._showToast(this.host._t("create"===t.mode?"toast.space_added":"toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?await this.host._requestMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._saveNav()))}catch(t){const s=t;"conflict"!==s?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const s=this.host._serverCfg;if(!s)return;const e=s.spaces.find(s=>s.id===t.spaceId);if(!e)return;const a=M(s,this.host._layout||{},t.spaceId||""),o=1===s.spaces.length&&s.spaces[0]?.id===t.spaceId;if(a.count&&!o)return void(this.host._spaceDialog={...t,deleteBlockers:a.count});const l=t.spaceId,i=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:this.host._t("confirm.delete_space_body"),objectName:e.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),h=this.host._spaceDialog,c=this.host._serverCfg;if(!i||!h||"edit"!==h.mode||h.busy||h.spaceId!==l||!c)return;if(!c.spaces.find(t=>t.id===l))return;const n=M(c,this.host._layout||{},l),r=1===c.spaces.length&&c.spaces[0]?.id===l;if(!n.count||r){this.host._spaceDialog={...h,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:l,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:s,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...h,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===l&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){const s=t;"conflict"!==s?.code&&"space_in_use"!==s?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=M(e,this.host._layout||{},l),s=1===e.spaces.length&&e.spaces[0]?.id===l;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...h,deleteBlockers:n.count}}_startImport(){const t=this.host._importDialog;if(!t)return;const s=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,s.length?(this.host._importQueue=s,this.host._importTotal=s.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();if(void 0===t)return;const s=p(this.host._imperial);this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:s,cellCmInput:c(s,this.host._imperial),cellCmTouched:!1,busy:!1}}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this.host._requestMode("plan").then(()=>{this.host._showToast(this.host._t("import.done"))}))}_renderImportDialog(){const t=this.host._importDialog,s=t.floors.filter(t=>t.checked).length;return o``}async _saveConfigNow(){this.host._cfgEpoch++;try{await this.host._writeConfig()}catch(t){const s=t;throw s?.physicalGeometryRolledBack?await this.host._reloadRejectedPhysicalWrite():"conflict"===s?.code&&await this.host._reloadConfigOnly(),t}}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const s="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const e="create"===t.mode?`s${Date.now().toString(36)}`:t.spaceId;let o=null;if("file"===t.source&&t.planFile){o={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:e,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let a=t.savedAspect||null;!o&&"file"===t.source&&t.planUrl&&!a&&this.host._aspectJob&&(a=await this.host._aspectJob||null);const l=this.host._serverCfg;let i=l.spaces.find(t=>t.id===e);if("create"===t.mode)i=b(e,t.title.trim()),l.spaces.push(i);else{if(!i)throw new Error(`space ${e} is gone from the config`);i.title=t.title.trim()}if(!i)throw new Error(`space ${e} is unavailable`);if(o?(i.plan_url=o.url,i.plan_aspect=o.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==i.plan_url&&(i.plan_url=t.planUrl,i.plan_aspect=a),"draw"===t.source&&(i.plan_url=null,i.plan_aspect=null,delete i.plan_x,delete i.plan_y,delete i.plan_scale,delete i.plan_scale_x,delete i.plan_scale_y,delete i.plan_angle),i.settings={...i.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):_,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):d,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},i.zero_wall_style=t.zeroWallStyle,i.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(.1,Math.min(F,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(i.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length)this._openNextImport();else if(s||this.host._importTotal>0){const t=this.host._importTotal>0;this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),await this.host._requestMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._showToast(this.host._t(s&&!t?"toast.space_added_onboard":"import.done"))}else this.host._showToast(this.host._t("create"===t.mode?"toast.space_added":"toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?await this.host._requestMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._saveNav()))}catch(t){const s=t;"conflict"!==s?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const s=this.host._serverCfg;if(!s)return;const e=s.spaces.find(s=>s.id===t.spaceId);if(!e)return;const o=M(s,this.host._layout||{},t.spaceId||""),a=1===s.spaces.length&&s.spaces[0]?.id===t.spaceId;if(o.count&&!a)return void(this.host._spaceDialog={...t,deleteBlockers:o.count});const l=t.spaceId,i=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:this.host._t("confirm.delete_space_body"),objectName:e.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),h=this.host._spaceDialog,c=this.host._serverCfg;if(!i||!h||"edit"!==h.mode||h.busy||h.spaceId!==l||!c)return;if(!c.spaces.find(t=>t.id===l))return;const n=M(c,this.host._layout||{},l),r=1===c.spaces.length&&c.spaces[0]?.id===l;if(!n.count||r){this.host._spaceDialog={...h,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:l,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:s,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...h,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===l&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){const s=t;"conflict"!==s?.code&&"space_in_use"!==s?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=M(e,this.host._layout||{},l),s=1===e.spaces.length&&e.spaces[0]?.id===l;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...h,deleteBlockers:n.count}}_startImport(){const t=this.host._importDialog;if(!t)return;const s=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,s.length?(this.host._importQueue=s,this.host._importTotal=s.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();if(void 0===t)return;const s=p(this.host._imperial);this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:s,cellCmInput:c(s,this.host._imperial),cellCmTouched:!1,busy:!1}}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this.host._requestMode("plan").then(()=>{this.host._showToast(this.host._t("import.done"))}))}_renderImportDialog(){const t=this.host._importDialog,s=t.floors.filter(t=>t.checked).length;return a`this.host._importDialog=null}>
    ${this.host._t("import.hint")}
    - ${t.floors.map((s,a)=>o`
    @@ -36,11 +36,11 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623 ${this.host._t("import.start",{n:s})}
    -
    `}_boolInput(t,s){return o`s(t.target.checked)} />`}_rangeInput(t,s,e,a,l){return o`l(Number(t.target.value))} />`}_renderSpaceDialog(){return this._renderSpaceDialogBody(this.host._spaceDialog)}_renderSpaceDialogBody(t){const s=this.host._importTotal>0&&"create"===t.mode?this.host._t("import.progress",{i:this.host._importTotal-this.host._importQueue.length,n:this.host._importTotal}):"",a=()=>{this.host._spaceDialog=null,this.host._importQueue=[],this.host._importTotal=0};return o``}_boolInput(t,s){return a`s(t.target.checked)} />`}_rangeInput(t,s,e,o,l){return a`l(Number(t.target.value))} />`}_renderSpaceDialog(){return this._renderSpaceDialogBody(this.host._spaceDialog)}_renderSpaceDialogBody(t){const s=this.host._importTotal>0&&"create"===t.mode?this.host._t("import.progress",{i:this.host._importTotal-this.host._importQueue.length,n:this.host._importTotal}):"",o=()=>{this.host._spaceDialog=null,this.host._importQueue=[],this.host._importTotal=0};return a` + icon="mdi:floor-plan" wide @hp-close=${o}>
    ${this.host._t("space.source_file")} - ${"file"===t.source?o`
    - ${t.planFile?o`${t.planFile.name}`:t.planUrl?o`${this.host._t("space.plan_alt")}`:o`${this.host._t("space.no_plan")}`} + ${"file"===t.source?a`
    + ${t.planFile?a`${t.planFile.name}`:t.planUrl?a`${this.host._t("space.plan_alt")}`:a`${this.host._t("space.no_plan")}`}
    @@ -107,7 +107,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f9623
    ${this.host._t("space.hide_openings_tip")}
    - ${[["labelTemp","space.label_temp"],["labelHum","space.label_hum"],["labelLqi","space.label_lqi"],["labelLight","space.label_light"]].map(([s,e])=>o`
    - ${D.map(t=>[t,`fill.${t}`]).map(([s,a])=>o` - ${t.deleteBlockers?o` `}renderDialog(){return this.dialog&&this.editorRenderer?(this.dialog.localOnly||this.refreshEntityIndex(),this.editorRenderer({host:this.host,dialog:this.dialog,local:this.local,storageUnavailable:this.storageUnavailable,problems:this.problems(this.dialog),entityIndex:this.entityIndex||O({},null),setDialog:e=>{this.dialog=e,this.host.requestUpdate()},saveLocal:e=>this.saveLocal(e),mutate:e=>this.mutate(e),deleteBlock:e=>{this.deleteBlock(e)},dragStart:(e,t)=>this.dragStart(e,t),drop:(e,t)=>this.drop(e,t),sourceToken:e=>this.sourceToken(e),openSource:(e,t)=>this.openSource(e,t),closeSource:e=>this.closeSource(e),setSource:(e,t,s)=>this.setSource(e,t,s),save:()=>{this.saveDialog()},reload:()=>{this.reloadDialog()},close:()=>this.closeDialogIfIdle(),t:e=>this.t(e)})):t}t(e){return e.startsWith("summary.")?function(e,t){const s=e.toLowerCase().split("-")[0];return(T[s]||T.en)[t]||T.en[t]||t}(r(this.host.hass,this.host._config?.language),e):this.host._t(e)}ensureStyle(){const e=this.host.renderRoot;if(this.styleSheet&&e.adoptedStyleSheets.includes(this.styleSheet))return;const t=this.host.ownerDocument.defaultView?.CSSStyleSheet;if(t&&"adoptedStyleSheets"in e){const s=new t;return s.replaceSync(M),this.styleSheet=s,void(e.adoptedStyleSheets=[...e.adoptedStyleSheets,s])}if(e.querySelector("style[data-hp-summary]"))return;const s=this.host.ownerDocument.createElement("style");s.dataset.hpSummary="true",s.textContent=M,e.insertBefore(s,e.firstChild)}ensureDialogStyle(){const e=this.host.renderRoot.querySelector('hp-dialog[data-kind="summary"]')?.shadowRoot;if(!e||this.styledDialogRoots.has(e))return;const t=this.host.ownerDocument.defaultView?.CSSStyleSheet;if(t&&"adoptedStyleSheets"in e)this.dialogStyleSheet||(this.dialogStyleSheet=new t,this.dialogStyleSheet.replaceSync($)),e.adoptedStyleSheets=[...e.adoptedStyleSheets,this.dialogStyleSheet];else{const t=this.host.ownerDocument.createElement("style");t.dataset.hpSummaryShell="true",t.textContent=$,e.appendChild(t)}this.styledDialogRoots.add(e)}placementSlot(){return N(this.host)}preferenceKey(){return function(e){const t=l(e.userId),s=l(e.slot);return t&&s?`houseplan.summary-panel.v1:${[t,l(e.path)||"/",l(e.host)||"card",s].map(e=>encodeURIComponent(e)).join(":")}`:null}({userId:this.host.hass?.user?.id||this.host.hass?.user?.name,path:location.pathname,host:this.host.panelHost?"panel":"lovelace",slot:this.placementSlot()})}identity(){return JSON.stringify({key:this.preferenceKey(),user:this.host.hass?.user?.id||this.host.hass?.user?.name||"",route:location.pathname,host:this.host.panelHost?"panel":"lovelace",slot:this.placementSlot(),kiosk:this.host._kiosk,canManage:this.host._canManageConfiguration})}syncLifecycle(){const e=this.identity();this.lifecycleIdentity&&e!==this.lifecycleIdentity&&this.resetLifecycle(),this.lifecycleIdentity=e}resetLifecycle(){this.presentation.reset(),this.lifecycleGeneration++,this.dialog=null,this.entityIndex=null,this.deviceMemo=null,this.areaMemo=null,this.clockContext="",this.storageKey=null,this.storageUnavailable=!1,this.local={version:1,show:!1,icon_scale:1,font_scale:1},this.clockTimer&&clearTimeout(this.clockTimer),this.clockTimer=0,this.lifecycleIdentity=this.connected?this.identity():"",this.host.requestUpdate()}current(e){return this.connected&&e===this.lifecycleGeneration&&this.lifecycleIdentity===this.identity()}refreshEntityIndex(){this.entityIndex=O(this.host.hass?.states,this.entityIndex)}syncNativeNarrow(){if(this.host.panelHost)return;let e=this.host;for(let t=0;e&&t<12;t++){const t=e.getRootNode();if(e=e.parentNode||(t instanceof ShadowRoot?t.host:null),!e||e===this.host)continue;const s=e.narrow;if("boolean"==typeof s)return void(this.host.narrow!==s&&(this.host.narrow=s))}}loadLocal(){const e=this.preferenceKey();if(!e||e===this.storageKey)return;let t=null,s=null,r=!0;try{t=JSON.parse(localStorage.getItem(e)||"null")}catch{r=!1}try{s=JSON.parse(localStorage.getItem("houseplan_card_kiosk_v1")||"null")}catch{r=!1}this.storageKey=e,this.storageUnavailable=!r,this.local=function(e,t){const s=e&&"object"==typeof e?e:{},r=t&&"object"==typeof t?t:{};return{version:1,show:!0===s.show,icon_scale:v(m(s,"icon_scale")?s.icon_scale:r.icon),font_scale:v(m(s,"font_scale")?s.font_scale:r.font)}}(t,s),this.host._kioskScale={icon:this.local.icon_scale,font:this.local.font_scale}}saveLocal(e){this.local={...this.local,...e,version:1,icon_scale:v(e.icon_scale??this.local.icon_scale),font_scale:v(e.font_scale??this.local.font_scale)},this.host._kioskScale={icon:this.local.icon_scale,font:this.local.font_scale},this.storageKey||=this.preferenceKey();let t=!1;try{this.storageKey&&(localStorage.setItem(this.storageKey,JSON.stringify(this.local)),t=!0)}catch{}this.storageUnavailable=!t,t||this.host._showToast?.(this.t("summary.storage_unavailable")),this.host.requestUpdate()}config(){return function(e,t){const s=e?.summary_panel;return void 0===s?{config:d(t),derived:!0,unsupported:!1}:h(s)?{config:s,derived:!1,unsupported:!1}:{config:null,derived:!1,unsupported:!0}}(this.host._settings,this.translate)}async openDialog(){const e=this.lifecycleGeneration;this.loadLocal();try{this.editorLoad||=import("./summary-panel-editor-BDoONUEa.js").then(e=>e.renderSummaryPanelEditor),this.editorRenderer=await this.editorLoad}catch(t){if(this.editorLoad=null,!this.current(e))return;return void this.host._showToast?.(`${this.t("summary.load_failed")} ${this.host._errText(t)}`)}if(!this.current(e))return;const t=this.config(),s=t.config||d(this.translate),r=this.host._haSummaryPanelApi!==i,a=t.unsupported?"summary.unsupported_schema":r&&this.host._canManageConfiguration?"summary.backend_required":"summary.local_only";this.dialog={draft:y(s),base:y(s),baseRevision:this.host._cfgRev,localShow:this.local.show,baseLocalShow:this.local.show,localOnly:this.host._kiosk||!this.host._canManageConfiguration||r||t.unsupported,localOnlyHint:a,busy:!1,attempted:!1,entityFilter:"",activeSource:null,error:"",conflict:!1},this.dialog.localOnly||this.refreshEntityIndex(),this.host.requestUpdate()}problems(e=this.dialog){return!e||e.localOnly?[]:g(f(e.draft),e.base,new Set(this.host._model.map(e=>e.id)),new Set(Object.keys(this.host.hass?.states||{})))}mutate(e){if(!this.dialog||this.dialog.busy||this.dialog.localOnly)return;const t=y(this.dialog.draft);e(t);const s=this.dialog.activeSource,r=!s||t.blocks.some(e=>e.id===s.blockId&&e.values.some(e=>e.id===s.valueId));this.dialog={...this.dialog,draft:t,error:"",conflict:!1,activeSource:r?s:null,entityFilter:r?this.dialog.entityFilter:""},this.host.requestUpdate()}async deleteBlock(e){const t=this.dialog?.draft.blocks[e];if(!t)return;const s=this.lifecycleGeneration;if(t.values.length){if(!await this.host._confirmDanger({key:"summary-block",kind:"warning",title:this.t("summary.delete_block_title"),message:this.t("summary.delete_block_body"),objectName:t.title,confirmLabel:this.t("btn.delete"),cancelLabel:this.t("btn.cancel")})||!this.current(s))return}this.mutate(e=>{const s=e.blocks.findIndex(e=>e.id===t.id);s>=0&&e.blocks.splice(s,1)})}sourceToken(e){return"system"===e.type?`system:${e.key}`:`entity:${e.entity_id}`}openSource(e,t){!this.dialog||this.dialog.busy||this.dialog.localOnly||(this.refreshEntityIndex(),this.dialog={...this.dialog,activeSource:{blockId:e,valueId:t},entityFilter:""},this.host.requestUpdate(),this.host.updateComplete.then(()=>{this.dialog?.activeSource?.blockId===e&&this.dialog.activeSource.valueId===t&&this.host.renderRoot.querySelector("[data-summary-picker-search]")?.focus()}))}closeSource(e=!1){const t=this.dialog?.activeSource;this.dialog&&t&&(this.dialog={...this.dialog,activeSource:null,entityFilter:""},this.host.requestUpdate(),e&&this.focusSource(t.blockId,t.valueId))}async focusSource(e,t){await this.host.updateComplete;const s=`${e}\n${t}`,r=this.host.renderRoot.querySelectorAll("[data-summary-source-owner]");[...r].find(e=>e.dataset.summarySourceOwner===s)?.focus()}setSource(e,t,s){this.mutate(r=>{const i=r.blocks.find(t=>t.id===e)?.values.find(e=>e.id===t);if(i)if(s.startsWith("system:")){const e=s.slice(7);(e=>"device_count"===e||"total_area"===e||"datetime"===e)(e)&&(i.source={type:"system",key:e})}else i.source={type:"entity",entity_id:s.startsWith("entity:")?s.slice(7):s}}),this.dialog&&(this.dialog={...this.dialog,activeSource:null,entityFilter:""}),this.host.requestUpdate(),this.focusSource(e,t)}dragStart(e,t){e.dataTransfer?.setData("text/x-houseplan-summary",t),e.dataTransfer&&(e.dataTransfer.effectAllowed="move")}drop(e,t){e.preventDefault(),e.stopPropagation();const s=e.dataTransfer?.getData("text/x-houseplan-summary")||"",r=s.split(":").map(Number),i=t.split(":").map(Number);s.startsWith("block:")&&t.startsWith("block:")?this.mutate(e=>{e.blocks=w(e.blocks,r[1],i[1])}):s.startsWith("value:")&&t.startsWith("value:")&&r[1]===i[1]&&this.mutate(e=>{e.blocks[r[1]].values=w(e.blocks[r[1]].values,r[2],i[2])})}async saveDialog(){const e=this.dialog;if(!e||e.busy)return;const t=this.lifecycleGeneration,s=f(e.draft);if((e.localOnly?[]:g(s,e.base,new Set(this.host._model.map(e=>e.id)),new Set(Object.keys(this.host.hass?.states||{})))).some(e=>"error"===e.kind))return this.dialog={...e,draft:s,attempted:!0},this.host.requestUpdate(),await this.host.updateComplete,void this.host.renderRoot.querySelector('[data-summary-error="true"]')?.focus?.();this.dialog={...e,draft:s,busy:!0,attempted:!1,error:"",conflict:!1},this.host.requestUpdate();try{if(!e.localOnly&&!_(s,e.base)){this.host._writesPending++;const r=a(this.host._writeChain,async()=>{if(!this.current(t))return;if(!this.host._serverCfg)throw new Error(this.t("summary.save_failed"));if(this.host._cfgRev!==e.baseRevision)throw new Error(this.t("summary.conflict"));const r=o({...this.host._serverCfg,settings:{...this.host._serverCfg.settings||{},summary_panel:s}});let i=!1;try{if(await this.host._sendConfigCandidate(r),!this.current(t))return}catch(e){if(!this.current(t))throw e;try{const r=await this.host._getAuthoritativeConfig();if(!this.current(t))throw e;const a=function(e,t){if(!c(e))return null;const s=e.config,r=e.rev;if(!c(s)||!Array.isArray(s.spaces)||"number"!=typeof r||!Number.isSafeInteger(r)||r<0)return null;const i=c(s.settings)?s.settings:null,a=i?.summary_panel;return h(a)&&_(a,t)?{config:s,rev:r}:null}(r,s);if(!a)throw e;const o=await this.host._adoptAuthoritative({cfgResp:r,reason:"summary-recovery",profile:"reload"});if("adopted"!==o.status)throw e;o.spaceChanged&&this.host._restoreZoom(),this.host._regSignature="",this.host._maybeRebuildDevices(),i=!0}catch{throw e}}if(!i){if(!this.current(t))return;this.host._adoption.stageConfigCandidate(r),this.host._cacheSnapshot()}});this.host._writeChain=r,await r.finally(()=>{this.host._writesPending--})}if(!this.current(t))return;this.saveLocal({show:e.localShow}),this.dialog=null}catch(s){if(!this.current(t))return;const r="conflict"===s?.code||this.host._cfgRev!==e.baseRevision;this.dialog={...this.dialog||e,busy:!1,conflict:r,error:r?this.t("summary.conflict"):this.host._errText(s)}}this.current(t)&&this.host.requestUpdate()}async reloadDialog(){const e=this.dialog;if(!e||e.busy)return;const t=this.lifecycleGeneration;this.dialog={...e,busy:!0,error:"",conflict:!1},this.host.requestUpdate();try{if(await this.host._reloadConfigOnly(!0),!this.current(t))return;if(e.conflict&&this.host._cfgRev===e.baseRevision)throw new Error(this.t("summary.load_failed"));const s=this.config().config||d(this.translate);this.dialog={...e,draft:y(s),base:y(s),baseRevision:this.host._cfgRev,busy:!1,attempted:!1,error:"",conflict:!1}}catch(s){if(!this.current(t))return;this.dialog={...e,busy:!1,error:this.host._errText(s),conflict:!0}}this.current(t)&&this.host.requestUpdate()}metricsFresh(){return!!this.deviceMemo&&!!this.areaMemo&&this.deviceMemo.cfgEpoch===this.host._cfgEpoch&&this.deviceMemo.layoutRev===this.host._layoutRev&&this.deviceMemo.registryRev===this.host._haRegistry.revision&&this.areaMemo.cfgEpoch===this.host._cfgEpoch}scheduleMetrics(){if(this.metricsRefresh||!this.metricsModule||this.metricsFresh())return;const e=this.lifecycleGeneration,t="undefined"==typeof window?void 0:window,s=()=>{if(this.metricsRefresh=0,!this.current(e))return;const t=this.advanceMetrics(8);this.host.requestUpdate(),t||this.scheduleMetrics()};this.metricsRefresh=t?.setTimeout(()=>{"function"==typeof t.requestAnimationFrame?t.requestAnimationFrame(()=>t.setTimeout(s,0)):s()},0)||0}advanceMetrics(e=8){const t=this.metricsModule;if(!t)return!0;if(this.computeDeviceCount(),!this.host._serverCfg)return this.areaMemo={cfgEpoch:this.host._cfgEpoch,value:null},!0;if(this.areaMemo&&this.areaMemo.cfgEpoch===this.host._cfgEpoch)return!0;this.areaSteps&&this.areaStepsEpoch===this.host._cfgEpoch||(this.areaSteps=t.cleanFloorAreaSteps(this.host._serverCfg,this.host._model),this.areaStepsEpoch=this.host._cfgEpoch);const s=Date.now();let r=this.areaSteps.next();for(;!r.done&&Date.now()-s[e,t.space])),spaceIds:new Set(this.host._model.map(e=>e.id)),firstSpaceId:this.host._model[0]?.id||"",markers:this.host._markers});this.deviceMemo={cfgEpoch:this.host._cfgEpoch,layoutRev:this.host._layoutRev,registryRev:this.host._haRegistry.revision,value:t?.size??null}}}computeMetrics(){for(;!this.advanceMetrics(Number.POSITIVE_INFINITY););}metrics(){return{deviceCount:this.deviceMemo?this.deviceMemo.value:null,areaM2:this.areaMemo?this.areaMemo.value:null,now:this.clock}}valueState(e){const t=this.metricsModule;if(!t)return{kind:"pending"};if("entity"===e.source.type){const s=t.summaryEntityValue(this.host.hass,e.source.entity_id);return null===s?{kind:"unavailable"}:{kind:"ready",text:s}}const s="device_count"===e.source.key||"total_area"===e.source.key,i="device_count"===e.source.key?this.deviceMemo:this.areaMemo;if(s&&!i)return this.scheduleMetrics(),{kind:"pending"};s&&this.scheduleMetrics();const a=t.summarySystemValue(e.source,this.metrics(),this.host.hass,r(this.host.hass,this.host._config?.language));return null===a?{kind:"unavailable"}:{kind:"ready",text:a}}value(e){const t=this.valueState(e);return"ready"===t.kind?t.text:this.t("summary.unavailable")}ensureMetrics(){if(this.metricsModule||this.metricsLoad)return;const e=this.lifecycleGeneration;this.metricsLoad=import("./summary-panel-metrics-O-xxtEs5.js"),this.metricsLoad.then(t=>{this.metricsModule=t,this.current(e)&&this.host.requestUpdate()}).catch(()=>{}).finally(()=>{this.metricsLoad=null})}layout(){return function(e){const t=Math.max(0,Number(e.width)||0),s=Math.max(0,Number(e.height)||0),r=t>=s?"right":"bottom",i=Math.max(0,e.safeLeft||0)+12,a=Math.max(0,e.safeRight||0)+12,o=Math.max(Math.max(0,e.safeTop||0)+12,e.controlTop||0),n=Math.max(Math.max(0,e.safeBottom||0)+12,e.controlBottom||0),l=Math.max(0,t-i-a),m=Math.max(0,s-o-n),c="bottom"===r?Math.min(.6*s,m):m;return{side:r,fits:t>0&&s>0&&l>=280&&c>=Math.max(0,e.minimumHeight),availableWidth:l,heightCap:c,top:o,bottom:n}}({width:this.stage.width,height:this.stage.height,...this.safeInsets(),controlTop:this.host._kiosk?this.stage.controlTop:0,minimumHeight:this.stage.minimumHeight})}syncPresentation(e=!1){const t=this.config().config,s=this.layout(),r=!!t&&"view"===this.host._mode&&s.fits&&b({view:!0,localShow:!0,showOnMobile:t.show_on_mobile,narrow:this.host.narrow,fits:!0});this.presentation.sync(r&&this.local.show,s.side,e||!r||"hidden"===this.host.ownerDocument.visibilityState)}measureLayout(){const e=this.host._stageEl;if(!e)return;const t=this.host.renderRoot.querySelector(".summary-measure"),s=this.host.renderRoot.querySelector(".summary-control.kiosk"),r=e.getBoundingClientRect(),i=s?.getBoundingClientRect(),a={width:Math.round(e.clientWidth),height:Math.round(e.clientHeight),minimumHeight:Math.max(162,Math.ceil(t?.getBoundingClientRect().height||0)),controlTop:i?Math.max(0,Math.ceil(i.bottom-r.top+12)):0};a.width===this.stage.width&&a.height===this.stage.height&&a.minimumHeight===this.stage.minimumHeight&&a.controlTop===this.stage.controlTop||(this.stage=a,this.host.requestUpdate())}safeInsets(){const e=this.host.renderRoot.querySelector(".summary-safe-probe");if(!e)return{safeLeft:0,safeRight:0,safeTop:0,safeBottom:0};const t=this.host.ownerDocument.defaultView?.getComputedStyle(e);if(!t)return{safeLeft:0,safeRight:0,safeTop:0,safeBottom:0};const s=e=>Number.parseFloat(e)||0;return{safeLeft:s(t.paddingLeft),safeRight:s(t.paddingRight),safeTop:s(t.paddingTop),safeBottom:s(t.paddingBottom)}}hasVisibleClock(){const e=this.config().config;return!("hidden"===this.host.ownerDocument.visibilityState||!e)&&(!!b({view:"view"===this.host._mode,localShow:this.local.show,showOnMobile:e.show_on_mobile,narrow:this.host.narrow,fits:this.layout().fits})&&p(e,this.host._space).some(e=>e.values.some(e=>"system"===e.source.type&&"datetime"===e.source.key)))}syncClock(){const e=`${r(this.host.hass,this.host._config?.language)}\n${this.host.hass?.config?.time_zone||""}`;e!==this.clockContext&&(this.clockContext=e,this.clock=new Date);const t=this.hasVisibleClock();if(t&&!this.clockTimer){this.clock=new Date;const e=()=>{this.clock=new Date,this.clockTimer=0,this.host.requestUpdate(),this.syncClock()};this.clockTimer=window.setTimeout(e,6e4-Date.now()%6e4+25)}else!t&&this.clockTimer&&(clearTimeout(this.clockTimer),this.clockTimer=0)}}});export{C as a,U as b,k as c,x as d,j as e,w as m,f as n,_ as s}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-DlU7AXvw.js b/dist/houseplan-assets/zigbee-topology-Ba2URGlk.js similarity index 95% rename from custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-DlU7AXvw.js rename to dist/houseplan-assets/zigbee-topology-Ba2URGlk.js index 75902f0d..885c9315 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-DlU7AXvw.js +++ b/dist/houseplan-assets/zigbee-topology-Ba2URGlk.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{s as e,F as n}from"./houseplan-card-BCGpvbDT.js";var t={title:"Zigbee links",toggle:"Show Zigbee links when hovering over a device",hint:"Shows observed direct neighbours only. Nothing is fetched while you hover.",help:"Shows which Zigbee devices each device talks to directly. Line colour is link quality (LQI) on the same scale as the device's LQI reading: red at 40 and below, green at 180 and above. A dashed line means quality was not reported. An arrow points to the next device on the way to the coordinator: one arrow leads out, incoming arrows are the devices that route through this one. A line without an arrow is a spare neighbour. This is the route tree House Plan builds, not the path a packet takes right now: a label at the end of an arrow means its target is not on this plan, and no arrow at all means the route is unknown. Data comes from the last load and goes stale; links are shown with a mouse only.",help_aria:"Help: Zigbee links",admin_only:"Topology data is available to Home Assistant administrators only.",save_first:"Save this setting before loading topology data.",zha:"ZHA",zha_read:"Read ZHA data",zha_hint:"Reads ZHA's cached topology; it does not start a radio scan.",z2m:"Zigbee2MQTT",z2m_topics:"Base topics (one per line)",z2m_update:"Update map",z2m_warning:"A network-map scan can take 10 seconds to 2 minutes and may temporarily reduce Zigbee responsiveness.",status_idle:"Data not loaded",status_loading:"Loading…",status_ready:"Received {time}",status_stale:"Received {time} · stale",status_partial:"Received {time} · some nodes were omitted",status_no_links:"Received {time} · no observed links found",error_permission:"Administrator permission is required.",error_unsupported:"This provider or Home Assistant API is unavailable.",error_timeout:"The provider did not respond in time.",error_invalid_topic:"Check the Zigbee2MQTT base topic.",error_invalid_payload:"The provider returned unsupported topology data.",error_provider:"Topology data could not be loaded.",remote_count:"+{n} in other spaces",route_device_not_on_plan:"device is not on the plan",route_coordinator_not_on_plan:"coordinator is not on the plan",route_other_space:"another space"};const i={en:t,ru:{title:"Связи Zigbee",toggle:"Показывать связи Zigbee при наведении на устройство",hint:"Показываются только наблюдаемые прямые соседи. Наведение ничего не запрашивает.",help:"Показывает, с какими устройствами Zigbee каждое связано напрямую. Цвет линии — качество связи (LQI) по той же шкале, что у показателя LQI устройства: красный при 40 и ниже, зелёный при 180 и выше. Пунктир — качество не сообщено. Стрелка ведёт к следующему устройству по пути к координатору: исходящая одна, входящие — те, кто ходит через это устройство. Линия без стрелки — запасной сосед. Это дерево маршрутов, которое строит House Plan, а не путь пакета в эту секунду: подпись на конце стрелки значит, что цель не на этом плане, а отсутствие стрелки — что путь неизвестен. Данные из последней загрузки и устаревают, связи видны только при работе мышью.",help_aria:"Справка: связи Zigbee",admin_only:"Данные топологии доступны только администраторам Home Assistant.",save_first:"Сохраните настройку перед загрузкой данных топологии.",zha:"ZHA",zha_read:"Прочитать данные ZHA",zha_hint:"Читает сохранённую топологию ZHA и не запускает радио-сканирование.",z2m:"Zigbee2MQTT",z2m_topics:"Базовые топики (по одному в строке)",z2m_update:"Обновить карту",z2m_warning:"Сканирование карты сети занимает от 10 секунд до 2 минут и временно может снизить отзывчивость Zigbee.",status_idle:"Данные не загружены",status_loading:"Загрузка…",status_ready:"Получено: {time}",status_stale:"Получено: {time} · данные устарели",status_partial:"Получено: {time} · часть узлов не показана",status_no_links:"Получено: {time} · наблюдаемые связи не найдены",error_permission:"Нужны права администратора.",error_unsupported:"Провайдер или API Home Assistant недоступен.",error_timeout:"Провайдер не ответил вовремя.",error_invalid_topic:"Проверьте базовый топик Zigbee2MQTT.",error_invalid_payload:"Провайдер вернул неподдерживаемые данные топологии.",error_provider:"Не удалось загрузить данные топологии.",remote_count:"+{n} в других пространствах",route_device_not_on_plan:"устройства нет на плане",route_coordinator_not_on_plan:"координатора нет на плане",route_other_space:"другое пространство"},de:{title:"Zigbee-Verbindungen",toggle:"Zigbee-Verbindungen beim Darüberfahren über ein Gerät anzeigen",hint:"Es werden nur beobachtete direkte Nachbarn angezeigt. Beim Darüberfahren werden keine Daten abgerufen.",help:"Zeigt, mit welchen Zigbee-Geräten jedes Gerät direkt verbunden ist. Die Linienfarbe ist die Verbindungsqualität (LQI) auf derselben Skala wie der LQI-Wert des Geräts: rot bei 40 und darunter, grün bei 180 und darüber. Eine gestrichelte Linie bedeutet, dass die Qualität nicht gemeldet wurde. Ein Pfeil zeigt auf das nächste Gerät auf dem Weg zum Koordinator: ein Pfeil führt hinaus, eingehende Pfeile sind die Geräte, die über dieses Gerät routen. Eine Linie ohne Pfeil ist ein Ersatznachbar. Das ist der Routenbaum, den House Plan bildet, nicht der Weg eines Pakets in diesem Moment: eine Beschriftung am Pfeilende bedeutet, dass das Ziel nicht auf diesem Plan liegt, und ein fehlender Pfeil, dass die Route unbekannt ist. Die Daten stammen aus dem letzten Laden und veralten; Verbindungen sind nur mit der Maus sichtbar.",help_aria:"Hilfe: Zigbee-Verbindungen",admin_only:"Topologiedaten sind nur für Home-Assistant-Administratoren verfügbar.",save_first:"Speichere diese Einstellung, bevor Topologiedaten geladen werden.",zha:"ZHA",zha_read:"ZHA-Daten lesen",zha_hint:"Liest den ZHA-Topologiecache; es wird kein Funkscan gestartet.",z2m:"Zigbee2MQTT",z2m_topics:"Basistopics (eines pro Zeile)",z2m_update:"Karte aktualisieren",z2m_warning:"Ein Netzwerkscan kann 10 Sekunden bis 2 Minuten dauern und Zigbee vorübergehend verlangsamen.",status_idle:"Daten nicht geladen",status_loading:"Wird geladen…",status_ready:"Empfangen: {time}",status_stale:"Empfangen: {time} · veraltet",status_partial:"Empfangen: {time} · einige Knoten fehlen",status_no_links:"Empfangen: {time} · keine beobachteten Verbindungen gefunden",error_permission:"Administratorrechte sind erforderlich.",error_unsupported:"Dieser Anbieter oder die Home-Assistant-API ist nicht verfügbar.",error_timeout:"Der Anbieter hat nicht rechtzeitig geantwortet.",error_invalid_topic:"Prüfe das Zigbee2MQTT-Basistopic.",error_invalid_payload:"Der Anbieter hat nicht unterstützte Topologiedaten geliefert.",error_provider:"Topologiedaten konnten nicht geladen werden.",remote_count:"+{n} in anderen Bereichen",route_device_not_on_plan:"Gerät ist nicht im Plan",route_coordinator_not_on_plan:"Koordinator ist nicht im Plan",route_other_space:"anderer Bereich"},fr:{title:"Liens Zigbee",toggle:"Afficher les liens Zigbee au survol d’un appareil",hint:"Seuls les voisins directs observés sont affichés. Le survol ne lance aucune requête.",help:"Montre avec quels appareils Zigbee chaque appareil communique directement. La couleur de la ligne est la qualité du lien (LQI) sur la même échelle que l'indicateur LQI de l'appareil : rouge à 40 et en dessous, vert à 180 et au-dessus. Une ligne pointillée signifie que la qualité n'a pas été communiquée. Une flèche pointe vers l'appareil suivant sur le chemin du coordinateur : une flèche part, les flèches entrantes sont les appareils qui passent par celui-ci. Une ligne sans flèche est un voisin de secours. C'est l'arbre de routes que construit House Plan, pas le trajet d'un paquet à cet instant : une étiquette au bout d'une flèche signifie que sa cible n'est pas sur ce plan, et l'absence de flèche que la route est inconnue. Les données proviennent du dernier chargement et vieillissent ; les liens ne sont visibles qu'à la souris.",help_aria:"Aide : liens Zigbee",admin_only:"Les données de topologie sont réservées aux administrateurs Home Assistant.",save_first:"Enregistrez ce réglage avant de charger les données de topologie.",zha:"ZHA",zha_read:"Lire les données ZHA",zha_hint:"Lit la topologie en cache de ZHA sans lancer d’analyse radio.",z2m:"Zigbee2MQTT",z2m_topics:"Topics de base (un par ligne)",z2m_update:"Actualiser la carte",z2m_warning:"L’analyse de la carte réseau peut durer de 10 secondes à 2 minutes et réduire temporairement la réactivité de Zigbee.",status_idle:"Données non chargées",status_loading:"Chargement…",status_ready:"Reçu : {time}",status_stale:"Reçu : {time} · obsolète",status_partial:"Reçu : {time} · certains nœuds sont omis",status_no_links:"Reçu : {time} · aucun lien observé trouvé",error_permission:"Les droits administrateur sont requis.",error_unsupported:"Ce fournisseur ou l’API Home Assistant n’est pas disponible.",error_timeout:"Le fournisseur n’a pas répondu à temps.",error_invalid_topic:"Vérifiez le topic de base Zigbee2MQTT.",error_invalid_payload:"Le fournisseur a renvoyé des données de topologie non prises en charge.",error_provider:"Impossible de charger les données de topologie.",remote_count:"+{n} dans d’autres espaces",route_device_not_on_plan:"appareil absent du plan",route_coordinator_not_on_plan:"coordinateur absent du plan",route_other_space:"autre espace"}};function r(e,n){const r=i[e]?.[n]??t[n];return"string"==typeof r&&r.trim().length>0}function o(n,r,o){return e(i[n]?.[r]??t[r]??r,o)}const s=3e5,a=2097152,d=6e3;function l(e){return null!==e&&"object"==typeof e?e:null}function u(e){if("string"!=typeof e&&"number"!=typeof e)return null;let n=String(e).trim().toLowerCase();return n=/^0x[0-9a-f]{16}$/.test(n)?n.slice(2):n.replace(/[:-]/g,""),/^[0-9a-f]{16}$/.test(n)?n:null}function c(e,n,t){return`${e}:${n}:${t}`}function p(e){const n=String(e||"").toLowerCase().replace(/[ _-]/g,"");return n.includes("coordinator")?"coordinator":n.includes("router")?"router":n.includes("enddevice")||"end"===n?"end":"unknown"}const h=["parent","child","sibling","none","previous_child"];function g(e){const n=l(e),t=function(e){const n=Number(e);return Number.isFinite(n)&&n>=0&&n<=255?Math.round(n):void 0}(n?.lqi??n?.linkquality??n?.link_quality),i=function(e){if("number"==typeof e)return h[e];if("string"!=typeof e)return;const n=e.trim().toLowerCase().replace(/[\s_-]+/g,"");return"previouschild"===n?"previous_child":n.slice(0,40)||void 0}(n?.relationship);return{...void 0===t?{}:{lqi:t},...i?{relationship:i}:{}}}function f(e,n){return Array.isArray(e)&&e.length<=n?e:null}function _(e){if("string"==typeof e)return e.length<=a;try{return JSON.stringify(e).length<=a}catch{return!1}}function m(e,n,t,i,r){if(t===i)return void n.push({code:"self_link",nodeKey:t});const o=t=d){t.push({code:"invalid_payload"});break}const n=l(e),i=u(n?.ieee??n?.ieee_address);if(!i){t.push({code:"invalid_payload",nodeKey:s});continue}const a=c("zha","zha",i);r.has(a)||r.set(a,{key:a,ieee:i,role:p(n?.device_type)}),m(o,t,s,a,e)}else null!=n?.neighbors&&t.push({code:"invalid_payload",nodeKey:s})}return{provider:"zha",instanceId:"zha",obtainedAt:n,freshness:"provider-cache",nodes:[...r.values()],links:[...o.values()],warnings:t}}function v(e,n){const t=l(e),i=u(t?.ieeeAddr??t?.ieee_address??t?.ieee??e);if(i)return i;for(const i of[t?.id,t?.networkAddress,t?.network_address,e])if(null!=i){const e=n.get(String(i));if(e)return e}return null}function y(e,t,i=Date.now()){const r=[],o=n(t)||"invalid",s=_(e)?function(e){let n=e;if("string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}const t=l(n),i=l(t?.data);if(n=i?.value??t?.value??t?.data??n,"string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}return n}(e):null,h=l(s),g=f(h?.nodes,1e3),b=f(h?.links,d);if(!g||!b)return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[],links:[],warnings:[{code:"invalid_payload"}]};const y=new Map,k=new Map;for(const e of g){const n=l(e),t=u(n?.ieeeAddr??n?.ieee_address??n?.ieee);if(!t){r.push({code:"invalid_payload"});continue}const i=c("z2m",o,t);y.set(i,{key:i,ieee:t,role:p(n?.type??n?.device_type),..."boolean"==typeof n?.failed?{available:!n.failed}:{}});for(const e of[n?.id,n?.networkAddress,n?.network_address])null!=e&&k.set(String(e),t)}const w=new Map;for(const e of b){const n=l(e),t=u(n?.sourceIeeeAddr)??v(n?.source,k),i=u(n?.targetIeeeAddr)??v(n?.target,k);if(!t||!i){r.push({code:"invalid_payload"});continue}const s=c("z2m",o,t),a=c("z2m",o,i);y.has(s)||y.set(s,{key:s,ieee:t,role:"unknown"}),y.has(a)||y.set(a,{key:a,ieee:i,role:"unknown"}),m(w,r,s,a,e)}return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[...y.values()],links:[...w.values()],warnings:r}}function k(e){if("string"!=typeof e)return null;const n=u(e);if(n)return n;const t=e.toLowerCase().match(/^zigbee2mqtt(?:_bridge)?_(.+)$/);return t?u(t[1]):null}function w(e,n){if(e.deviceId&&n.devices[e.deviceId])return[e.deviceId];const t=new Set;for(const[i,r]of Object.entries(n.devices)){const n=l(r);(Array.isArray(n?.identifiers)?n.identifiers:[]).some(n=>Array.isArray(n)&&k(n[1])===e.ieee)&&t.add(i)}if(t.size)return[...t];for(const i of Object.values(n.entities)){const n=l(i);"string"==typeof n?.device_id&&"string"==typeof n.unique_id&&(k(n.unique_id)===e.ieee&&t.add(n.device_id))}return[...t]}function z(e){return!e.hidden&&!e.virtual&&"ha_disabled"!==e.bindingStatus?.kind&&"orphaned"!==e.bindingStatus?.kind&&"unverified"!==e.bindingStatus?.kind}function A(e){const n=new Map,t=new Map,i=e.nodes.filter(e=>"coordinator"===e.role).map(e=>e.key).sort();if(1!==i.length)return{distances:n,parents:t};const r=i[0],o=function(e){const n=new Set(e.nodes.map(e=>e.key)),t=new Map;for(const e of[...n].sort())t.set(e,[]);for(const i of[...e.links].sort((e,n)=>`${e.a}\0${e.b}`.localeCompare(`${n.a}\0${n.b}`)))n.has(i.a)&&n.has(i.b)&&(t.get(i.a).push({neighborKey:i.b,observation:i.aToB}),t.get(i.b).push({neighborKey:i.a,observation:i.bToA}));for(const e of t.values())e.sort((e,n)=>e.neighborKey.localeCompare(n.neighborKey));return t}(e);if(!o.has(r))return{distances:n,parents:t};n.set(r,0);const s=[r];for(let e=0;en.get(e)===i-1).sort((e,n)=>{const t="parent"===e.observation?.relationship?1:0,i="parent"===n.observation?.relationship?1:0;if(t!==i)return i-t;const r=e.observation?.lqi??-1;return(n.observation?.lqi??-1)-r||e.neighborKey.localeCompare(n.neighborKey)});r[0]&&t.set(e,r[0].neighborKey)}return{coordinatorKey:r,distances:n,parents:t}}function Z(e,n,t){const i=new Map,r=[];for(const o of e.nodes){if(!1===o.available){r.push({code:"provider_scan_failure",nodeKey:o.key});continue}const e=w(o,t);if(1!==e.length){r.push({code:"unmatched_device",nodeKey:o.key});continue}const s=e[0];let a=n.filter(e=>z(e)&&"device"===e.bindingKind&&e.bindingRef===s);a.length||(a=n.filter(e=>z(e)&&"entity"===e.bindingKind&&!!e.bindingRef&&t.entities[e.bindingRef]?.device_id===s)),1===a.length?i.set(o.key,{markerId:a[0].id,space:a[0].space}):r.push({code:a.length>1?"ambiguous_placement":"unmatched_device",nodeKey:o.key})}return{placements:i,warnings:r}}function T(e,n,t){return e.map(e=>({topology:e,placements:Z(e,n,t).placements,routes:A(e)}))}function q(e,n,t){const i=new Map,r=new Set,o=new Map;let s=0;for(const{topology:a,placements:d,routes:l}of e){const e=new Set([...d].filter(([,e])=>e.markerId===t&&e.space===n).map(([e])=>e));if(e.size){for(const t of e){const e=l.parents.get(t);if(!e)continue;const i=d.get(e);if(i?.space===n)continue;let r;r=i?{kind:"remote-space",spaceId:i.space}:"coordinator"===a.nodes.find(n=>n.key===e)?.role?{kind:"unplaced-coordinator"}:{kind:"unplaced-device"};const s="remote-space"===r.kind?`${r.kind}:${r.spaceId}`:r.kind;o.set(s,r)}for(const o of a.links){const a=e.has(o.a),u=e.has(o.b);if(!a&&!u)continue;const c=a?o.a:o.b,p=a?o.b:o.a,h=d.get(p);if(!h||h.markerId===t){s++;continue}const g=l.parents.get(c)===p;if(h.space!==n){g||r.add(h.markerId);continue}const f=a?o.aToB:o.bToA,_=g?"toward-neighbor":l.parents.get(p)===c?"toward-origin":void 0,m=i.get(h.markerId);m?(void 0===m.line.lqi&&void 0!==f?.lqi&&(m.line.lqi=f.lqi),_&&m.directions.add(_)):i.set(h.markerId,{line:{neighborMarkerId:h.markerId,lqi:f?.lqi},directions:new Set(_?[_]:[])})}}}return{lines:[...i.values()].map(({line:e,directions:n})=>1===n.size?{...e,routeDirection:[...n][0]}:e),remoteCount:r.size,omittedCount:s,parentTargets:[...o.values()]}}export{s as T,T as a,y as b,r as h,Z as m,b as n,q as r,o as t}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{s as e,F as n}from"./houseplan-card-Di_izZTU.js";var t={title:"Zigbee links",toggle:"Show Zigbee links when hovering over a device",hint:"Shows observed direct neighbours only. Nothing is fetched while you hover.",help:"Shows which Zigbee devices each device talks to directly. Line colour is link quality (LQI) on the same scale as the device's LQI reading: red at 40 and below, green at 180 and above. A dashed line means quality was not reported. An arrow points to the next device on the way to the coordinator: one arrow leads out, incoming arrows are the devices that route through this one. A line without an arrow is a spare neighbour. This is the route tree House Plan builds, not the path a packet takes right now: a label at the end of an arrow means its target is not on this plan, and no arrow at all means the route is unknown. Data comes from the last load and goes stale; links are shown with a mouse only.",help_aria:"Help: Zigbee links",admin_only:"Topology data is available to Home Assistant administrators only.",save_first:"Save this setting before loading topology data.",zha:"ZHA",zha_read:"Read ZHA data",zha_hint:"Reads ZHA's cached topology; it does not start a radio scan.",z2m:"Zigbee2MQTT",z2m_topics:"Base topics (one per line)",z2m_update:"Update map",z2m_warning:"A network-map scan can take 10 seconds to 2 minutes and may temporarily reduce Zigbee responsiveness.",status_idle:"Data not loaded",status_loading:"Loading…",status_ready:"Received {time}",status_stale:"Received {time} · stale",status_partial:"Received {time} · some nodes were omitted",status_no_links:"Received {time} · no observed links found",error_permission:"Administrator permission is required.",error_unsupported:"This provider or Home Assistant API is unavailable.",error_timeout:"The provider did not respond in time.",error_invalid_topic:"Check the Zigbee2MQTT base topic.",error_invalid_payload:"The provider returned unsupported topology data.",error_provider:"Topology data could not be loaded.",remote_count:"+{n} in other spaces",route_device_not_on_plan:"device is not on the plan",route_coordinator_not_on_plan:"coordinator is not on the plan",route_other_space:"another space"};const i={en:t,ru:{title:"Связи Zigbee",toggle:"Показывать связи Zigbee при наведении на устройство",hint:"Показываются только наблюдаемые прямые соседи. Наведение ничего не запрашивает.",help:"Показывает, с какими устройствами Zigbee каждое связано напрямую. Цвет линии — качество связи (LQI) по той же шкале, что у показателя LQI устройства: красный при 40 и ниже, зелёный при 180 и выше. Пунктир — качество не сообщено. Стрелка ведёт к следующему устройству по пути к координатору: исходящая одна, входящие — те, кто ходит через это устройство. Линия без стрелки — запасной сосед. Это дерево маршрутов, которое строит House Plan, а не путь пакета в эту секунду: подпись на конце стрелки значит, что цель не на этом плане, а отсутствие стрелки — что путь неизвестен. Данные из последней загрузки и устаревают, связи видны только при работе мышью.",help_aria:"Справка: связи Zigbee",admin_only:"Данные топологии доступны только администраторам Home Assistant.",save_first:"Сохраните настройку перед загрузкой данных топологии.",zha:"ZHA",zha_read:"Прочитать данные ZHA",zha_hint:"Читает сохранённую топологию ZHA и не запускает радио-сканирование.",z2m:"Zigbee2MQTT",z2m_topics:"Базовые топики (по одному в строке)",z2m_update:"Обновить карту",z2m_warning:"Сканирование карты сети занимает от 10 секунд до 2 минут и временно может снизить отзывчивость Zigbee.",status_idle:"Данные не загружены",status_loading:"Загрузка…",status_ready:"Получено: {time}",status_stale:"Получено: {time} · данные устарели",status_partial:"Получено: {time} · часть узлов не показана",status_no_links:"Получено: {time} · наблюдаемые связи не найдены",error_permission:"Нужны права администратора.",error_unsupported:"Провайдер или API Home Assistant недоступен.",error_timeout:"Провайдер не ответил вовремя.",error_invalid_topic:"Проверьте базовый топик Zigbee2MQTT.",error_invalid_payload:"Провайдер вернул неподдерживаемые данные топологии.",error_provider:"Не удалось загрузить данные топологии.",remote_count:"+{n} в других пространствах",route_device_not_on_plan:"устройства нет на плане",route_coordinator_not_on_plan:"координатора нет на плане",route_other_space:"другое пространство"},de:{title:"Zigbee-Verbindungen",toggle:"Zigbee-Verbindungen beim Darüberfahren über ein Gerät anzeigen",hint:"Es werden nur beobachtete direkte Nachbarn angezeigt. Beim Darüberfahren werden keine Daten abgerufen.",help:"Zeigt, mit welchen Zigbee-Geräten jedes Gerät direkt verbunden ist. Die Linienfarbe ist die Verbindungsqualität (LQI) auf derselben Skala wie der LQI-Wert des Geräts: rot bei 40 und darunter, grün bei 180 und darüber. Eine gestrichelte Linie bedeutet, dass die Qualität nicht gemeldet wurde. Ein Pfeil zeigt auf das nächste Gerät auf dem Weg zum Koordinator: ein Pfeil führt hinaus, eingehende Pfeile sind die Geräte, die über dieses Gerät routen. Eine Linie ohne Pfeil ist ein Ersatznachbar. Das ist der Routenbaum, den House Plan bildet, nicht der Weg eines Pakets in diesem Moment: eine Beschriftung am Pfeilende bedeutet, dass das Ziel nicht auf diesem Plan liegt, und ein fehlender Pfeil, dass die Route unbekannt ist. Die Daten stammen aus dem letzten Laden und veralten; Verbindungen sind nur mit der Maus sichtbar.",help_aria:"Hilfe: Zigbee-Verbindungen",admin_only:"Topologiedaten sind nur für Home-Assistant-Administratoren verfügbar.",save_first:"Speichere diese Einstellung, bevor Topologiedaten geladen werden.",zha:"ZHA",zha_read:"ZHA-Daten lesen",zha_hint:"Liest den ZHA-Topologiecache; es wird kein Funkscan gestartet.",z2m:"Zigbee2MQTT",z2m_topics:"Basistopics (eines pro Zeile)",z2m_update:"Karte aktualisieren",z2m_warning:"Ein Netzwerkscan kann 10 Sekunden bis 2 Minuten dauern und Zigbee vorübergehend verlangsamen.",status_idle:"Daten nicht geladen",status_loading:"Wird geladen…",status_ready:"Empfangen: {time}",status_stale:"Empfangen: {time} · veraltet",status_partial:"Empfangen: {time} · einige Knoten fehlen",status_no_links:"Empfangen: {time} · keine beobachteten Verbindungen gefunden",error_permission:"Administratorrechte sind erforderlich.",error_unsupported:"Dieser Anbieter oder die Home-Assistant-API ist nicht verfügbar.",error_timeout:"Der Anbieter hat nicht rechtzeitig geantwortet.",error_invalid_topic:"Prüfe das Zigbee2MQTT-Basistopic.",error_invalid_payload:"Der Anbieter hat nicht unterstützte Topologiedaten geliefert.",error_provider:"Topologiedaten konnten nicht geladen werden.",remote_count:"+{n} in anderen Bereichen",route_device_not_on_plan:"Gerät ist nicht im Plan",route_coordinator_not_on_plan:"Koordinator ist nicht im Plan",route_other_space:"anderer Bereich"},fr:{title:"Liens Zigbee",toggle:"Afficher les liens Zigbee au survol d’un appareil",hint:"Seuls les voisins directs observés sont affichés. Le survol ne lance aucune requête.",help:"Montre avec quels appareils Zigbee chaque appareil communique directement. La couleur de la ligne est la qualité du lien (LQI) sur la même échelle que l'indicateur LQI de l'appareil : rouge à 40 et en dessous, vert à 180 et au-dessus. Une ligne pointillée signifie que la qualité n'a pas été communiquée. Une flèche pointe vers l'appareil suivant sur le chemin du coordinateur : une flèche part, les flèches entrantes sont les appareils qui passent par celui-ci. Une ligne sans flèche est un voisin de secours. C'est l'arbre de routes que construit House Plan, pas le trajet d'un paquet à cet instant : une étiquette au bout d'une flèche signifie que sa cible n'est pas sur ce plan, et l'absence de flèche que la route est inconnue. Les données proviennent du dernier chargement et vieillissent ; les liens ne sont visibles qu'à la souris.",help_aria:"Aide : liens Zigbee",admin_only:"Les données de topologie sont réservées aux administrateurs Home Assistant.",save_first:"Enregistrez ce réglage avant de charger les données de topologie.",zha:"ZHA",zha_read:"Lire les données ZHA",zha_hint:"Lit la topologie en cache de ZHA sans lancer d’analyse radio.",z2m:"Zigbee2MQTT",z2m_topics:"Topics de base (un par ligne)",z2m_update:"Actualiser la carte",z2m_warning:"L’analyse de la carte réseau peut durer de 10 secondes à 2 minutes et réduire temporairement la réactivité de Zigbee.",status_idle:"Données non chargées",status_loading:"Chargement…",status_ready:"Reçu : {time}",status_stale:"Reçu : {time} · obsolète",status_partial:"Reçu : {time} · certains nœuds sont omis",status_no_links:"Reçu : {time} · aucun lien observé trouvé",error_permission:"Les droits administrateur sont requis.",error_unsupported:"Ce fournisseur ou l’API Home Assistant n’est pas disponible.",error_timeout:"Le fournisseur n’a pas répondu à temps.",error_invalid_topic:"Vérifiez le topic de base Zigbee2MQTT.",error_invalid_payload:"Le fournisseur a renvoyé des données de topologie non prises en charge.",error_provider:"Impossible de charger les données de topologie.",remote_count:"+{n} dans d’autres espaces",route_device_not_on_plan:"appareil absent du plan",route_coordinator_not_on_plan:"coordinateur absent du plan",route_other_space:"autre espace"}};function r(e,n){const r=i[e]?.[n]??t[n];return"string"==typeof r&&r.trim().length>0}function o(n,r,o){return e(i[n]?.[r]??t[r]??r,o)}const s=3e5,a=2097152,d=6e3;function l(e){return null!==e&&"object"==typeof e?e:null}function u(e){if("string"!=typeof e&&"number"!=typeof e)return null;let n=String(e).trim().toLowerCase();return n=/^0x[0-9a-f]{16}$/.test(n)?n.slice(2):n.replace(/[:-]/g,""),/^[0-9a-f]{16}$/.test(n)?n:null}function c(e,n,t){return`${e}:${n}:${t}`}function p(e){const n=String(e||"").toLowerCase().replace(/[ _-]/g,"");return n.includes("coordinator")?"coordinator":n.includes("router")?"router":n.includes("enddevice")||"end"===n?"end":"unknown"}const h=["parent","child","sibling","none","previous_child"];function g(e){const n=l(e),t=function(e){const n=Number(e);return Number.isFinite(n)&&n>=0&&n<=255?Math.round(n):void 0}(n?.lqi??n?.linkquality??n?.link_quality),i=function(e){if("number"==typeof e)return h[e];if("string"!=typeof e)return;const n=e.trim().toLowerCase().replace(/[\s_-]+/g,"");return"previouschild"===n?"previous_child":n.slice(0,40)||void 0}(n?.relationship);return{...void 0===t?{}:{lqi:t},...i?{relationship:i}:{}}}function f(e,n){return Array.isArray(e)&&e.length<=n?e:null}function _(e){if("string"==typeof e)return e.length<=a;try{return JSON.stringify(e).length<=a}catch{return!1}}function b(e,n,t,i,r){if(t===i)return void n.push({code:"self_link",nodeKey:t});const o=t=d){t.push({code:"invalid_payload"});break}const n=l(e),i=u(n?.ieee??n?.ieee_address);if(!i){t.push({code:"invalid_payload",nodeKey:s});continue}const a=c("zha","zha",i);r.has(a)||r.set(a,{key:a,ieee:i,role:p(n?.device_type)}),b(o,t,s,a,e)}else null!=n?.neighbors&&t.push({code:"invalid_payload",nodeKey:s})}return{provider:"zha",instanceId:"zha",obtainedAt:n,freshness:"provider-cache",nodes:[...r.values()],links:[...o.values()],warnings:t}}function v(e,n){const t=l(e),i=u(t?.ieeeAddr??t?.ieee_address??t?.ieee??e);if(i)return i;for(const i of[t?.id,t?.networkAddress,t?.network_address,e])if(null!=i){const e=n.get(String(i));if(e)return e}return null}function y(e,t,i=Date.now()){const r=[],o=n(t)||"invalid",s=_(e)?function(e){let n=e;if("string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}const t=l(n),i=l(t?.data);if(n=i?.value??t?.value??t?.data??n,"string"==typeof n){if(n.length>a)return null;try{n=JSON.parse(n)}catch{return null}}return n}(e):null,h=l(s),g=f(h?.nodes,1e3),m=f(h?.links,d);if(!g||!m)return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[],links:[],warnings:[{code:"invalid_payload"}]};const y=new Map,k=new Map;for(const e of g){const n=l(e),t=u(n?.ieeeAddr??n?.ieee_address??n?.ieee);if(!t){r.push({code:"invalid_payload"});continue}const i=c("z2m",o,t);y.set(i,{key:i,ieee:t,role:p(n?.type??n?.device_type),..."boolean"==typeof n?.failed?{available:!n.failed}:{}});for(const e of[n?.id,n?.networkAddress,n?.network_address])null!=e&&k.set(String(e),t)}const w=new Map;for(const e of m){const n=l(e),t=u(n?.sourceIeeeAddr)??v(n?.source,k),i=u(n?.targetIeeeAddr)??v(n?.target,k);if(!t||!i){r.push({code:"invalid_payload"});continue}const s=c("z2m",o,t),a=c("z2m",o,i);y.has(s)||y.set(s,{key:s,ieee:t,role:"unknown"}),y.has(a)||y.set(a,{key:a,ieee:i,role:"unknown"}),b(w,r,s,a,e)}return{provider:"z2m",instanceId:o,obtainedAt:i,freshness:"fresh-scan",nodes:[...y.values()],links:[...w.values()],warnings:r}}function k(e){if("string"!=typeof e)return null;const n=u(e);if(n)return n;const t=e.toLowerCase().match(/^zigbee2mqtt(?:_bridge)?_(.+)$/);return t?u(t[1]):null}function w(e,n){if(e.deviceId&&n.devices[e.deviceId])return[e.deviceId];const t=new Set;for(const[i,r]of Object.entries(n.devices)){const n=l(r);(Array.isArray(n?.identifiers)?n.identifiers:[]).some(n=>Array.isArray(n)&&k(n[1])===e.ieee)&&t.add(i)}if(t.size)return[...t];for(const i of Object.values(n.entities)){const n=l(i);"string"==typeof n?.device_id&&"string"==typeof n.unique_id&&(k(n.unique_id)===e.ieee&&t.add(n.device_id))}return[...t]}function z(e){return!e.hidden&&!e.virtual&&"ha_disabled"!==e.bindingStatus?.kind&&"orphaned"!==e.bindingStatus?.kind&&"unverified"!==e.bindingStatus?.kind}function A(e){const n=new Map,t=new Map,i=e.nodes.filter(e=>"coordinator"===e.role).map(e=>e.key).sort();if(1!==i.length)return{distances:n,parents:t};const r=i[0],o=function(e){const n=new Set(e.nodes.map(e=>e.key)),t=new Map;for(const e of[...n].sort())t.set(e,[]);for(const i of[...e.links].sort((e,n)=>`${e.a}\0${e.b}`.localeCompare(`${n.a}\0${n.b}`)))n.has(i.a)&&n.has(i.b)&&(t.get(i.a).push({neighborKey:i.b,observation:i.aToB}),t.get(i.b).push({neighborKey:i.a,observation:i.bToA}));for(const e of t.values())e.sort((e,n)=>e.neighborKey.localeCompare(n.neighborKey));return t}(e);if(!o.has(r))return{distances:n,parents:t};n.set(r,0);const s=[r];for(let e=0;en.get(e)===i-1).sort((e,n)=>{const t="parent"===e.observation?.relationship?1:0,i="parent"===n.observation?.relationship?1:0;if(t!==i)return i-t;const r=e.observation?.lqi??-1;return(n.observation?.lqi??-1)-r||e.neighborKey.localeCompare(n.neighborKey)});r[0]&&t.set(e,r[0].neighborKey)}return{coordinatorKey:r,distances:n,parents:t}}function Z(e,n,t){const i=new Map,r=[];for(const o of e.nodes){if(!1===o.available){r.push({code:"provider_scan_failure",nodeKey:o.key});continue}const e=w(o,t);if(1!==e.length){r.push({code:"unmatched_device",nodeKey:o.key});continue}const s=e[0];let a=n.filter(e=>z(e)&&"device"===e.bindingKind&&e.bindingRef===s);a.length||(a=n.filter(e=>z(e)&&"entity"===e.bindingKind&&!!e.bindingRef&&t.entities[e.bindingRef]?.device_id===s)),1===a.length?i.set(o.key,{markerId:a[0].id,space:a[0].space}):r.push({code:a.length>1?"ambiguous_placement":"unmatched_device",nodeKey:o.key})}return{placements:i,warnings:r}}function T(e,n,t){return e.map(e=>({topology:e,placements:Z(e,n,t).placements,routes:A(e)}))}function q(e,n,t){const i=new Map,r=new Set,o=new Map;let s=0;for(const{topology:a,placements:d,routes:l}of e){const e=new Set([...d].filter(([,e])=>e.markerId===t&&e.space===n).map(([e])=>e));if(e.size){for(const t of e){const e=l.parents.get(t);if(!e)continue;const i=d.get(e);if(i?.space===n)continue;let r;r=i?{kind:"remote-space",spaceId:i.space}:"coordinator"===a.nodes.find(n=>n.key===e)?.role?{kind:"unplaced-coordinator"}:{kind:"unplaced-device"};const s="remote-space"===r.kind?`${r.kind}:${r.spaceId}`:r.kind;o.set(s,r)}for(const o of a.links){const a=e.has(o.a),u=e.has(o.b);if(!a&&!u)continue;const c=a?o.a:o.b,p=a?o.b:o.a,h=d.get(p);if(!h||h.markerId===t){s++;continue}const g=l.parents.get(c)===p;if(h.space!==n){g||r.add(h.markerId);continue}const f=a?o.aToB:o.bToA,_=g?"toward-neighbor":l.parents.get(p)===c?"toward-origin":void 0,b=i.get(h.markerId);b?(void 0===b.line.lqi&&void 0!==f?.lqi&&(b.line.lqi=f.lqi),_&&b.directions.add(_)):i.set(h.markerId,{line:{neighborMarkerId:h.markerId,lqi:f?.lqi},directions:new Set(_?[_]:[])})}}}return{lines:[...i.values()].map(({line:e,directions:n})=>1===n.size?{...e,routeDirection:[...n][0]}:e),remoteCount:r.size,omittedCount:s,parentTargets:[...o.values()]}}export{s as T,T as a,y as b,r as h,Z as m,m as n,q as r,o as t}; diff --git a/dist/houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js b/dist/houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js similarity index 93% rename from dist/houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js rename to dist/houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js index 2c569cdb..8eadc5bd 100644 --- a/dist/houseplan-assets/zigbee-topology-runtime-CWcX1vcd.js +++ b/dist/houseplan-assets/zigbee-topology-runtime-BZVl6ukN.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";import{n as t,b as n}from"./zigbee-topology-DlU7AXvw.js";import{F as e}from"./houseplan-card-BCGpvbDT.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__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";import{n as t,b as n}from"./zigbee-topology-Ba2URGlk.js";import{F as e}from"./houseplan-card-Di_izZTU.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}; diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js index 7309dba8..122a7e21 100644 --- a/dist/houseplan-card.js +++ b/dist/houseplan-card.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";try{await import("./houseplan-assets/houseplan-card-BCGpvbDT.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__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";try{await import("./houseplan-assets/houseplan-card-Di_izZTU.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)} diff --git a/dist/houseplan-panel.js b/dist/houseplan-panel.js index 182b7bc1..a2188bd9 100644 --- a/dist/houseplan-panel.js +++ b/dist/houseplan-panel.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0aa07f15a35e57da89774909bc60ec4f962331aec1df3963cc08462a0c3abf5e";try{await import("./houseplan-assets/houseplan-card-BCGpvbDT.js")}catch(e){if(!customElements.get("houseplan-panel")){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-panel",class extends HTMLElement{connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;min-height:100%;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-panel.js: the card implementation chunk is unavailable",e)}const e=["panel","hass","narrow","route"];class n extends HTMLElement{constructor(){super(),this._narrow=!1,this.attachShadow({mode:"open"}),this._adoptPreUpgradeProperties()}connectedCallback(){this._adoptPreUpgradeProperties(),this._ensureShell()}_adoptPreUpgradeProperties(){for(const n of e){if(!Object.prototype.hasOwnProperty.call(this,n))continue;const e=this[n];delete this[n],this[n]=e}}get hass(){return this._hass}set hass(e){this._hass=e,this._ensureShell(),this._card&&(this._card.hass=e),this._syncMenuLabel()}get narrow(){return this._narrow}set narrow(e){this._narrow=Boolean(e),this.toggleAttribute("narrow",this._narrow),this._card&&(this._card.narrow=this._narrow)}get route(){return this._route}set route(e){this._route=e}get panel(){return this._panel}set panel(e){this._panel=e}_ensureShell(){if(this._card||!this.shadowRoot)return;const e=document.createElement("style");e.textContent="\n :host {\n display: block;\n width: 100%;\n /* HA mounts a custom panel inside , a block with\n * safe-area padding and NO height, so a percentage here resolves to\n * auto and the stage collapses to 0 px (#488). Take the viewport\n * like HA's own iframe panels do, minus the insets HA pads with. */\n height: 100vh;\n height: calc(100dvh - var(--safe-area-inset-top, 0px) - var(--safe-area-inset-bottom, 0px));\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n color: var(--primary-text-color);\n background: var(--primary-background-color);\n }\n .page {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n overflow: hidden;\n }\n .appbar {\n box-sizing: border-box;\n min-width: 0;\n min-height: var(--header-height, 56px);\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 0 16px;\n background: var(--app-header-background-color, var(--primary-background-color));\n color: var(--app-header-text-color, var(--primary-text-color));\n border-bottom: 1px solid var(--divider-color);\n z-index: 1;\n }\n .toolbar {\n min-width: 0;\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .menu {\n box-sizing: border-box;\n width: 44px;\n height: 44px;\n min-width: 44px;\n min-height: 44px;\n margin: 0;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 50%;\n color: inherit;\n background: transparent;\n cursor: pointer;\n }\n .menu:focus-visible {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n }\n @media (hover: hover) {\n .menu:hover { background: var(--secondary-background-color); }\n }\n .menu ha-icon { --mdc-icon-size: 24px; }\n .title {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 20px;\n font-weight: 500;\n line-height: 1.2;\n }\n .title ha-icon {\n --mdc-icon-size: 24px;\n color: var(--primary-color);\n }\n .content {\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n }\n houseplan-card {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n }\n ";const n=document.createElement("div");n.className="page";const t=document.createElement("header");t.className="appbar";const a=document.createElement("div");a.className="toolbar",a.setAttribute("role","toolbar");const o=document.createElement("button");o.className="menu",o.dataset.hp="panel-menu",o.type="button",o.innerHTML='',o.addEventListener("click",()=>{o.dispatchEvent(new CustomEvent("hass-toggle-menu",{bubbles:!0,composed:!0}))}),this._menuButton=o;const i=document.createElement("div");i.className="title",i.dataset.hp="panel-title",i.setAttribute("role","heading"),i.setAttribute("aria-level","1"),i.innerHTML='House Plan',a.append(o,i),t.append(a);const r=document.createElement("main");r.className="content";const s=document.createElement("houseplan-card");s.panelHost=!0,s.narrow=this._narrow,s.setConfig({type:"custom:houseplan-card"}),void 0!==this._hass&&(s.hass=this._hass),r.append(s),n.append(t,r),this.shadowRoot.append(e,n),this._card=s,this._syncMenuLabel()}_syncMenuLabel(){if(!this._menuButton)return;const e=this._hass?.localize?.("ui.common.menu")||this._hass?.localize?.("ui.panel.lovelace.menu")||"Menu";this._menuButton.setAttribute("aria-label",e),this._menuButton.title=e}}customElements.get("houseplan-panel")||customElements.define("houseplan-panel",n);export{n as HouseplanPanel}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="530ccf77162ec68ef4b53a77b8f84ff0fffe489fa26b18459248ce23d527db33";try{await import("./houseplan-assets/houseplan-card-Di_izZTU.js")}catch(e){if(!customElements.get("houseplan-panel")){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-panel",class extends HTMLElement{connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;min-height:100%;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-panel.js: the card implementation chunk is unavailable",e)}const e=["panel","hass","narrow","route"];class n extends HTMLElement{constructor(){super(),this._narrow=!1,this.attachShadow({mode:"open"}),this._adoptPreUpgradeProperties()}connectedCallback(){this._adoptPreUpgradeProperties(),this._ensureShell()}_adoptPreUpgradeProperties(){for(const n of e){if(!Object.prototype.hasOwnProperty.call(this,n))continue;const e=this[n];delete this[n],this[n]=e}}get hass(){return this._hass}set hass(e){this._hass=e,this._ensureShell(),this._card&&(this._card.hass=e),this._syncMenuLabel()}get narrow(){return this._narrow}set narrow(e){this._narrow=Boolean(e),this.toggleAttribute("narrow",this._narrow),this._card&&(this._card.narrow=this._narrow)}get route(){return this._route}set route(e){this._route=e}get panel(){return this._panel}set panel(e){this._panel=e}_ensureShell(){if(this._card||!this.shadowRoot)return;const e=document.createElement("style");e.textContent="\n :host {\n display: block;\n width: 100%;\n /* HA mounts a custom panel inside , a block with\n * safe-area padding and NO height, so a percentage here resolves to\n * auto and the stage collapses to 0 px (#488). Take the viewport\n * like HA's own iframe panels do, minus the insets HA pads with. */\n height: 100vh;\n height: calc(100dvh - var(--safe-area-inset-top, 0px) - var(--safe-area-inset-bottom, 0px));\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n color: var(--primary-text-color);\n background: var(--primary-background-color);\n }\n .page {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n overflow: hidden;\n }\n .appbar {\n box-sizing: border-box;\n min-width: 0;\n min-height: var(--header-height, 56px);\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 0 16px;\n background: var(--app-header-background-color, var(--primary-background-color));\n color: var(--app-header-text-color, var(--primary-text-color));\n border-bottom: 1px solid var(--divider-color);\n z-index: 1;\n }\n .toolbar {\n min-width: 0;\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .menu {\n box-sizing: border-box;\n width: 44px;\n height: 44px;\n min-width: 44px;\n min-height: 44px;\n margin: 0;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 50%;\n color: inherit;\n background: transparent;\n cursor: pointer;\n }\n .menu:focus-visible {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n }\n @media (hover: hover) {\n .menu:hover { background: var(--secondary-background-color); }\n }\n .menu ha-icon { --mdc-icon-size: 24px; }\n .title {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 20px;\n font-weight: 500;\n line-height: 1.2;\n }\n .title ha-icon {\n --mdc-icon-size: 24px;\n color: var(--primary-color);\n }\n .content {\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n }\n houseplan-card {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n }\n ";const n=document.createElement("div");n.className="page";const t=document.createElement("header");t.className="appbar";const a=document.createElement("div");a.className="toolbar",a.setAttribute("role","toolbar");const o=document.createElement("button");o.className="menu",o.dataset.hp="panel-menu",o.type="button",o.innerHTML='',o.addEventListener("click",()=>{o.dispatchEvent(new CustomEvent("hass-toggle-menu",{bubbles:!0,composed:!0}))}),this._menuButton=o;const i=document.createElement("div");i.className="title",i.dataset.hp="panel-title",i.setAttribute("role","heading"),i.setAttribute("aria-level","1"),i.innerHTML='House Plan',a.append(o,i),t.append(a);const r=document.createElement("main");r.className="content";const s=document.createElement("houseplan-card");s.panelHost=!0,s.narrow=this._narrow,s.setConfig({type:"custom:houseplan-card"}),void 0!==this._hass&&(s.hass=this._hass),r.append(s),n.append(t,r),this.shadowRoot.append(e,n),this._card=s,this._syncMenuLabel()}_syncMenuLabel(){if(!this._menuButton)return;const e=this._hass?.localize?.("ui.common.menu")||this._hass?.localize?.("ui.panel.lovelace.menu")||"Menu";this._menuButton.setAttribute("aria-label",e),this._menuButton.title=e}}customElements.get("houseplan-panel")||customElements.define("houseplan-panel",n);export{n as HouseplanPanel}; diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 10686521..63a03cee 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +- General settings now let window sunlight start at either the inner window + corners (the existing default) or the outer window corners. The outer mode + carries the visible shaft only through the physical window tunnel before it + reaches the room; sun direction, reach, colour and shadows are unchanged + ([#577](https://github.com/Matysh/houseplan-card/issues/577)). + - Pinch-zooming in the Home Assistant Companion app no longer repeatedly moves the plan between compositor paths while the fingers are still down. Walls, floors, fills, hatching and lighting now remain continuously painted across diff --git a/docs/CHANGELOG.ru.md b/docs/CHANGELOG.ru.md index e70d44b5..0ec7cf42 100755 --- a/docs/CHANGELOG.ru.md +++ b/docs/CHANGELOG.ru.md @@ -8,6 +8,12 @@ ## Не выпущено +- В общих настройках теперь можно выбрать, от каких углов окна начинаются + солнечные лучи: от внутренних (прежнее поведение по умолчанию) или от + внешних. Во внешнем режиме видимая часть луча проходит к комнате только + через физический оконный тоннель; направление, длина, цвет и тени не меняются + ([#577](https://github.com/Matysh/houseplan-card/issues/577)). + - При масштабировании щипком в приложении Home Assistant план больше не переключается между режимами композитинга, пока пальцы остаются на экране. Стены, пол, заливки, штриховка и свет теперь остаются непрерывно видимыми при diff --git a/docs/CONFIG-COMPATIBILITY.md b/docs/CONFIG-COMPATIBILITY.md index 365a8faa..0e13e896 100644 --- a/docs/CONFIG-COMPATIBILITY.md +++ b/docs/CONFIG-COMPATIBILITY.md @@ -97,6 +97,20 @@ new frontend restores the disabled behavior after upgrade. Full backup/import preserves the setting and the privacy-safe support projection includes only a validated boolean. +## Sun-ray window face (#577) + +`settings.sun_ray_origin` is an optional global enum: `inner` or `outer`. +Absence and an unknown read-side value resolve to `inner`, preserving the exact +pre-#577 source geometry without rewriting an existing configuration. Saving +General settings materialises a valid value; new installations start with +`inner`. Backend writes reject every other value. There is deliberately no +per-space override and no model/store version bump. + +Full backup/import preserves the enum. The privacy-safe support projection +includes only a validated `inner`/`outer` scalar. Older frontends ignore a +preserved value and temporarily render the historical inner mode; a current +frontend restores the selected mode after upgrade. + ## Summary panel namespace (#437) `settings.summary_panel` is an optional shared versioned object. Absence means diff --git a/docs/SUN.md b/docs/SUN.md index 864a4446..31f442fd 100644 --- a/docs/SUN.md +++ b/docs/SUN.md @@ -204,17 +204,24 @@ when BOTH hold: perpendicular depth (`len · cos`, see «Dissolving») would be thinner than the wall it came through. -The wedge is a PARALLELOGRAM: the window's full **room-side span**, from -one inner corner of the opening to the other, extruded by the same +The wedge is a PARALLELOGRAM. The global `settings.sun_ray_origin` enum selects +its full source span: `inner` starts at the two room-side corners (the default +and the exact pre-#577 behaviour), while `outer` starts at the two exterior +corners. Missing or unknown values resolve to `inner`; this setting has no +per-space override. The selected span is extruded by the same length along the direction AWAY from the sun (light falls inward), so its far edge is parallel to the wall, clipped by the receiving room's **inner contour** when wall thickness is set (`inset` of the polygon by half the wall thickness — see `docs/WALL-THICKNESS.md`); otherwise by -the room polygon (`polyclip` intersection). With wall depth `d`, the -source span is translated from the wall centreline by `d/2` along the -inward normal. Thus both crisp side edges begin exactly at the two inner -corners of the opening at every incidence angle (`d = 0` keeps the -previous centreline/full-span geometry). Its length +the room polygon (`polyclip` intersection). In `outer`, the clip also includes +only the physical rectangular window tunnel between the exterior span and the +clean-floor contour; the surrounding wall body and outside facade remain +occluders. With wall depth `d`, `inner` translates the source from the +centreline by `+d/2` along the inward normal and `outer` by `-d/2`. Thus both +crisp side edges begin exactly at the selected two corners at every incidence +angle (`d = 0` makes both modes identical). The nominal length and gradient +start at that selected span rather than adding the wall depth to the old reach. +Its length is `k(elevation)` in window lengths: ~1.75 at sunrise/sunset tapering to ~0.56 at the zenith (`0.56 + 1.19·(1 − elevation/90)^1.6` — the v1.56 curve `0.8 + 1.7·(1 − elevation/90)^1.6` times `RAY_LENGTH_K` = 0.7, owner @@ -245,10 +252,10 @@ Two rounds with the owner on the same day: wedge, which feathered the SIDES too. Wrong: a shaft of sunlight through a window has crisp sides. Only its reach fades. -So the falloff is one-dimensional: **along the ray, from the room-side opening +So the falloff is one-dimensional: **along the ray, from the selected opening inward, and nothing else.** Three invariants have to hold at once: -1. the whole room-side opening is at peak alpha — light does not start out +1. the whole selected opening span is at peak alpha — light does not start out half-dark at one end of the window; 2. every ray fades over the same distance, its own `len`; 3. the wedge's far edge lies exactly on an iso-alpha line, so the shaft @@ -257,21 +264,21 @@ inward, and nothing else.** Three invariants have to hold at once: **The axis of the fade is the wall's INWARD NORMAL, not the ray.** The light is a bundle of PARALLEL rays, so the distance a point has -travelled from the room-side source span is `depth / cos`, where `depth` +travelled from the selected source span is `depth / cos`, where `depth` is its perpendicular distance from that span and `cos = dir·normal` is fixed for the whole wedge. That is an affine function of the point, and its level sets are straight lines PARALLEL TO THE WALL. A linear gradient whose axis is the normal therefore describes the travelled distance exactly: -- `x1,y1` = the middle of the room-side window span (any point of that span — +- `x1,y1` = the middle of the selected window span (any point of that span — they all have depth 0); - `x2,y2` = that point plus `normal · len · cos` — `SunRay.depth`, the perpendicular depth a ray reaches after running the full `len`; - a point `source + dir·u` lands on offset `u / len`, whichever ray it rode in on. -Hence: the inner opening span is all at offset 0 (invariant 1), the alpha at any +Hence: the selected opening span is all at offset 0 (invariant 1), the alpha at any point is a function of how far its own ray has run (invariant 2), and the parallelogram's far edge — parallel to the wall — IS the gradient's last iso-alpha line (invariant 3). The «30 % shorter» reach is then a @@ -319,7 +326,7 @@ of its cheap half, verbatim: «тонкая (1px) чёрная граница п The contract: - **Two side edges only.** The rim runs along the two edges that leave - the inner opening corners and travel inward with the ray — `a → a+dir·len` + the selected opening corners and travel inward with the ray — `a → a+dir·len` and `b → b+dir·len`. Never the source edge `a-b` (that is the source, not a boundary) and never the far edge (there is nothing left to outline there — the fill is already at zero, see below). @@ -331,7 +338,7 @@ The contract: `x1,y1,x2,y2`** (the wall's inward normal, `depth` long) and **the same normalised curve** — `rimStops()` returns `rayStops()` by identity, not by copy, so the two can never drift apart. Only the colour and the peak - differ: `RIM_MAX_ALPHA` = 0.42 at the inner opening, tuned on the demo rig + differ: `RIM_MAX_ALPHA` = 0.42 at the selected opening, tuned on the demo rig against both extremes (below ~0.3 the line vanishes on paper at kiosk scale, above ~0.5 it reads as an ink contour over the dark glow canvas). Zero from `RAY_FADE_END` = 85 % on, like the fill. diff --git a/docs/TESTING.md b/docs/TESTING.md index 5b138abc..d085c9d8 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -2848,6 +2848,21 @@ require hands on real hardware — they remain for the human pass. corners of the window opening (the full span translated inward by half the wall depth), including at an oblique sun angle; no edge starts on the wall centreline [auto: unit `sun.test.mjs` + `smoke_wall_thickness`] +- [ ] **Window face (#577):** General settings always shows the global + `inner`/`outer` selector, even when rays are off; save/reopen preserves it. + Missing/invalid read-side values resolve to `inner`, backend writes reject + invalid values, full export/import and support projection preserve only a + valid enum [auto: `smoke_sun`, `sun.test.mjs`, + `config-schema-parity.test.mjs`, `test_validation.py`, + `test_ha_import_export.py`, `test_support_package.py`] +- [ ] In `outer`, a thick-wall ray starts at both exterior window corners and + reaches the clean floor only through the physical opening tunnel; wall + body and exterior space never light up. Direction, nominal reach, fade, + colour, thresholds and shadows are identical to `inner`; at `d = 0` the + two results are byte-identical. Switching the pending dialog value + invalidates the geometry memo without waiting for a server revision + [auto: `sun.test.mjs`, `smoke_sun`; golden regression: existing inner + sun scenarios] - [ ] Brightness + the 3° threshold (2026-08-03): wedges are visibly brighter (peak alpha 0.30, was 0.18) yet still readable over white paper AND the dark glow canvas; there is NO gradual ramp near the horizon — below 3° diff --git a/docs/USER-GUIDE.ru.md b/docs/USER-GUIDE.ru.md index ac2d1ff0..bc5e0cb3 100644 --- a/docs/USER-GUIDE.ru.md +++ b/docs/USER-GUIDE.ru.md @@ -908,9 +908,9 @@ YAML-сущность без `unique_id` и строки в Entity Registry: п Флаг «Открывается в другую сторону» меняет только направление створок: у двери и окна зеркалит их относительно оси, а у ворот меняет направление 10° поворота. Положение символа не сдвигается к грани стены. Свет проходит через дверь, -ворота или открытый проём по ширине -внутреннего тоннеля и отсекается откосами. Солнечный луч начинается из -внутренних углов оконного тоннеля. +ворота или открытый проём по ширине внутреннего тоннеля и отсекается откосами. +Солнечный луч начинается из внутренних или внешних углов оконного тоннеля — +режим выбирается в общих настройках, по умолчанию используются внутренние. В компактной Static-карточке открытый проём также разрывает тело стены и продолжает текущую заливку/Glow-base через тоннель. Отображение уже существующих @@ -1638,7 +1638,10 @@ WebP и безопасный SVG; лимит 2 МиБ относится к со компаса. Стрелка N должна буквально указывать туда, где на рисунке находится истинный север; это не обратная поправка на поворот плана. 3. При необходимости включите **Солнечный свет через окна**. -4. Для отдельного этажа задайте локальный север/режим/включение либо оставьте наследование. +4. В поле **Лучи солнца** выберите начало от внутренних углов окна (прежнее + поведение по умолчанию) или от внешних углов. Это общая настройка для всех + пространств; она доступна и тогда, когда сами лучи временно выключены. +5. Для отдельного этажа задайте локальный север/режим/включение либо оставьте наследование. Если раньше вы зеркально выставляли компас, чтобы компенсировать ошибочное направление лучей, после обновления верните стрелку N к реальному северу. @@ -1652,7 +1655,9 @@ WebP и безопасный SVG; лимит 2 МиБ относится к со | Переход через 3° | Слой плавно появляется/исчезает за 2 секунды | | Окно внутреннее | Луча нет | | Окно не смотрит на солнце | Луча нет | -| Толстая внешняя стена | Луч начинается из внутренних углов тоннеля окна | +| Толстая внешняя стена, режим «внутренние углы» | Луч начинается с комнатной стороны оконного тоннеля | +| Толстая внешняя стена, режим «внешние углы» | Луч начинается с фасадной стороны и проходит к комнате только внутри оконного тоннеля | +| Стена нулевой толщины | Оба режима выглядят одинаково | | «Скрыть проёмы» включено | Символ окна скрыт, луч продолжает работать | | Белый план | По бокам луча есть тонкая 1px тёмная кромка для читаемости | | Любая погода, включая дождь и снег | Погода не влияет на лучи | diff --git a/docs/WALL-THICKNESS.md b/docs/WALL-THICKNESS.md index 1af72812..7c16da52 100644 --- a/docs/WALL-THICKNESS.md +++ b/docs/WALL-THICKNESS.md @@ -7,7 +7,7 @@ Status: **implemented / evolving** (post beta.4 redesign). Visual reference: Owner intent: thick walls form one continuous hatched body (seamless L and T), grow both ways from the room centreline, fills/light stay inside the inner contour, displayed area is the clean floor, and sun wedges start at the two -room-side corners of an opening. +corners of the globally selected inner or outer opening face. Code: `src/wall-thickness.ts`, render in `src/houseplan-card.ts` / `src/space-render.ts`. Sun: `src/sun.ts`. Tests: `test/wall-thickness.test.mjs`, @@ -369,11 +369,14 @@ invoke it. ## 5. Sun -Wedges do not draw through wall bodies. Their full source span is translated -from the centreline by half the wall depth along the receiving room's inward -normal, so both side rays begin at the two room-side corners of the window -opening. Clip to the receiving room's inner contour. `d = 0` keeps the previous -centreline/full-span wedge. `hide_openings` hides the symbol only. +Wedges do not draw through wall bodies. The global `settings.sun_ray_origin` +selects their source face. `inner` (default and legacy fallback) translates the +full span from the centreline by `+d/2` along the receiving room's inward +normal, so both sides begin at the room-side corners. `outer` translates it by +`-d/2` and includes only the rectangular physical window tunnel before the +receiving room's inner contour; adjacent wall and exterior space stay clipped. +The nominal length and gradient begin at the selected span. `d = 0` makes both +modes identical. `hide_openings` hides the symbol only. ## 6. Tool / hooks / i18n @@ -446,8 +449,8 @@ handle and cannot split or re-key their atomic records `demo/smoke_resize_wall_thickness.mjs`); an eligible uniformly thick exact wall moves through the fixed-topology safe pipeline and Undo restores its source (`demo/smoke_room_resize.mjs`); -the zero-wall preview paints above the real body; sun starts at the room-side -opening corners; nav mode restores after `can_write`; a 1 cm body uses +the zero-wall preview paints above the real body; sun starts at the selected +inner/outer opening corners; nav mode restores after `can_write`; a 1 cm body uses solid-only in both full and static cards while a 20 cm body keeps its hatch; door/window/gate tunnels repeat outer/shared room fills without an axis seam (`demo/smoke_opening_tunnel_fill.mjs`); corner Split keeps the same facade in diff --git a/docs/images/screenshots.json b/docs/images/screenshots.json index c7a763d2..a7f740df 100644 --- a/docs/images/screenshots.json +++ b/docs/images/screenshots.json @@ -3,7 +3,7 @@ "fixture": "synthetic-only", "chromium": "151.0.7922.34", "oxipng": "oxipng 10.2.0", - "sourceFingerprint": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceFingerprint": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "captureScriptSha256": "9e4b0ae533407fe003a129078aec020f2c83d67cdb6fc6da696ce3d829beaeb5", "command": "npm run build && node demo/docs/capture.mjs", "scenarios": { @@ -15,7 +15,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "76c35a87810e3dc6890bda7b43da133f57d8860031204a62cda7115c15950090" }, "view-touch": { @@ -26,7 +26,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "795585acb09488236ebb8028a7fcbd918404c5fe01560bb9b4559de13d441625" }, "space-create": { @@ -37,7 +37,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "9f0970de09772674c3156b9fc5b2d49de0ceb22be11ecf8b136047d37d100a84" }, "room-contour-close": { @@ -48,7 +48,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "0c354a79f9c3660788b6c5e889a27b6bd78b1f209dc0eef6bb43e2c1344028c4" }, "plan-context-tray": { @@ -59,7 +59,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "64169c543291bc4df806dcf8ff484b42c8ea55eb343323d945344e0e28f2ce97" }, "device-editor": { @@ -70,7 +70,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "3c8703175605fcf0387d654cd30783ecfd33e21743e70b45190a5ae1a8d355c2" }, "device-display-preview": { @@ -81,7 +81,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "5d6193202102f5e6d85567f1111fa105895b933979fbf369c6ba0b1029deb823" }, "background-editor": { @@ -92,7 +92,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "375900a29aa62632883ede6727b7dbb8b48cabe9d7d0e16425f9779c837f3dd9" }, "room-card": { @@ -103,7 +103,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "3d85424676c823ddca3fa7dab3cce089b6030e48c05d16d2d48d922c66c0cbd2" }, "device-info": { @@ -114,7 +114,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "ac962820f8e1c5cb5b042d39b18dc95905fa840cb2d4749060d991be4f6977c2" }, "pdf-export": { @@ -125,7 +125,7 @@ }, "theme": "light", "language": "en", - "sourceSha256": "58a0c82061aeaa744df96d8f089d2048469e69743920a6d9d67d4c0b84029d87", + "sourceSha256": "1104398c6aa8885020c8f8b714582b66f586c9cb845846d52813990d87f94454", "imageSha256": "4537692fd57a3ed95528eddd748eee5cb6e456ffab7cc49169853d62459252cd" } }, diff --git a/scripts/bundle-budget.mjs b/scripts/bundle-budget.mjs index 292198da..6c5377b1 100644 --- a/scripts/bundle-budget.mjs +++ b/scripts/bundle-budget.mjs @@ -263,8 +263,13 @@ export const LOW_HEADROOM_WARNING_BYTES = 15_000; * отдельный модуль; механизм обязан быть синхронным на первом касании и потому * не может жить в lazy editor graph. Измеренный факт 290 181 Б оставляет 719 Б * сверху и 1 281 Б до нижней границы полосы. + * + * 2026-09-15, #577: потолок перецентрирован 290 900 → 291 300 без изменения + * общего бюджета. Выбор внутренней или внешней грани окна относится к + * синхронной геометрии лучей в initial View. Измеренный факт 290 629 Б + * оставляет 671 Б сверху и 1 329 Б до нижней границы полосы. */ -export const INITIAL_VIEW_GZIP_CEILING = 290_900; +export const INITIAL_VIEW_GZIP_CEILING = 291_300; export const INITIAL_VIEW_CEILING_BAND = 2_000; /** diff --git a/scripts/config-field-registry.mjs b/scripts/config-field-registry.mjs index 16f18ffe..986aeb79 100644 --- a/scripts/config-field-registry.mjs +++ b/scripts/config-field-registry.mjs @@ -7,6 +7,21 @@ * field whose key is still current but whose old value is compatibility-only. */ export const CONFIG_FIELD_REGISTRY = Object.freeze([ + { + id: 'settings.sun_ray_origin', + enforcedBy: 'sun.ts + validation.py + config-schema parity; #577', + selector: { path: ['settings', 'sun_ray_origin'] }, + storage: 'House Plan server config', + type: "'inner' | 'outer'", + default: "unset (= 'inner', the pre-#577 geometry)", + level: 'global', + ui: 'General settings → Sun → Sun rays', + runtime: 'selects the physical window face used as the source span', + introduced: '#577', + status: 'current', + migration: "none — old configs stay on 'inner'; new settings saves materialise the enum", + compatibility: "unknown values fail backend writes and fall back to 'inner' in the frontend", + }, { id: 'settings.summary_panel', enforcedBy: 'summary-panel.ts + validation.py change-aware reference validation; #437', diff --git a/scripts/config-schema.json b/scripts/config-schema.json index 6bb030c7..30f6269f 100644 --- a/scripts/config-schema.json +++ b/scripts/config-schema.json @@ -442,6 +442,13 @@ } ] }, + "config.settings.sun_ray_origin": { + "enum": [ + "inner", + "outer" + ], + "required": false + }, "config.settings.sun_rays": { "required": false, "type": "bool" diff --git a/scripts/mutation-registry.mjs b/scripts/mutation-registry.mjs index 19148b68..504398db 100644 --- a/scripts/mutation-registry.mjs +++ b/scripts/mutation-registry.mjs @@ -5329,6 +5329,63 @@ const MUTANT_DEFINITIONS = [ replace: "{ id: 'openings-filled-tunnel-dark', fixture: 'visual', space: 'golden-lighting', mode: 'view',\n fillMode: 'none', customFill: { c: '#66717c', a: 0.55 }, glowEnabled: false,", }], }, + { + id: 'sun-ray-origin-outer-ignored', + guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs ' + + '&& node --test --test-name-pattern="#577: outer rays" test/sun.test.mjs', + because: 'если внешний режим снова использует внутреннюю грань, геометрия остаётся ' + + 'визуально прежней; unit-защита #577 обязана увидеть обе фасадные точки и тоннель', + patches: [{ + file: 'src/sun.ts', + find: " const side = origin === 'outer' ? -1 : 1;", + replace: ' const side = 1; // mutant: ignore outer source face', + }], + }, + { + id: 'sun-ray-origin-cache-ignored', + guard: 'node demo/smoke_sun.mjs', + because: 'переключение в открытом диалоге не меняет config epoch; без origin в ключе ' + + 'пользователь до следующей записи видит закэшированную старую геометрию (#577)', + patches: [{ + file: 'src/houseplan-card.ts', + find: '`${space.id}|${sun.azimuth}|${sun.elevation}|${north}|${origin}|${this._cfgEpoch}`', + replace: '`${space.id}|${sun.azimuth}|${sun.elevation}|${north}|${this._cfgEpoch}`', + }], + }, + { + id: 'sun-ray-origin-save-forced-inner', + guard: 'node demo/smoke_sun.mjs', + because: 'селектор без сохранения — ложная функция; браузерный round-trip обязан ' + + 'увидеть outer после Save и при повторном открытии общих настроек (#577)', + patches: [{ + file: 'src/houseplan-editor-runtime.ts', + find: ' settings.sun_ray_origin = d.sunRayOrigin;', + replace: " settings.sun_ray_origin = 'inner'; // mutant: discard the selected face", + }], + }, + { + id: 'sun-ray-origin-backend-allows-any-string', + guard: 'node scripts/backend-test-guard.mjs test_sun_settings_global tests_backend/test_validation.py', + because: 'backend обязан отвергать неизвестный enum, иначе сохранённая опечатка расходится ' + + 'с UI и молча читается как inner; строгий validation-тест #577 должен покраснеть', + patches: [{ + file: 'custom_components/houseplan/validation.py', + find: '_SUN_RAY_ORIGIN = vol.In(["inner", "outer"])', + replace: '_SUN_RAY_ORIGIN = str # mutant: accept any string', + }], + }, + { + id: 'sun-ray-origin-support-leaks-invalid', + guard: 'node scripts/backend-test-guard.mjs ' + + 'test_projection_helpers_fail_closed_on_malformed_shapes tests_backend/test_support_package.py', + because: 'support package переносит только безопасный известный enum; неизвестная строка ' + + 'не должна попадать в диагностический архив (#577)', + patches: [{ + file: 'custom_components/houseplan/support_package.py', + find: ' if sun_ray_origin in ("inner", "outer"):', + replace: ' if isinstance(sun_ray_origin, str): # mutant: leak unknown strings', + }], + }, { id: 'sun-north-subtraction-restored', guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs ' diff --git a/src/houseplan-card.ts b/src/houseplan-card.ts index 2d254f32..f5811fb7 100755 --- a/src/houseplan-card.ts +++ b/src/houseplan-card.ts @@ -65,10 +65,10 @@ import { type ResizeAreaPlacement, } from './resize-labels'; import { - computeSunRays, dayPhase, northDegOf, bgModeOf, sunRaysOn, + computeSunRays, dayPhase, northDegOf, bgModeOf, sunRaysOn, sunRayOriginOf, sunStateOf, rayPeakAlpha, raysVisible, rayColor, RAY_FADE_MS, type SunRay, rayStops, resolveDayCycle, dayCycleFingerprint, type DayCycleState, - rayRimEdges, rimStops, rimPeakAlpha, RIM_COLOR, + rayRimEdges, rimStops, rimPeakAlpha, RIM_COLOR, type SunRayOrigin, } from './sun'; import { dayCycleStageVars, renderDayCycleEnvironment } from './day-cycle-render'; import { @@ -2202,7 +2202,7 @@ export class HouseplanCard extends LitElement { private _settingsDialog: { colors: FillColors; glowRadius: number; bgColor: string | null; /** sun on the plan (docs/SUN.md) */ - northDeg: number | null; bgMode: 'static' | 'daynight'; sunRays: boolean; + northDeg: number | null; bgMode: 'static' | 'daynight'; sunRays: boolean; sunRayOrigin: SunRayOrigin; showRoomTooltip: boolean; zigbeeTopology: import('./zigbee-topology-settings').ZigbeeTopologySettings; radarShowLive: boolean; busy: boolean; @@ -10372,6 +10372,7 @@ export class HouseplanCard extends LitElement { north_deg: gd.northDeg ?? undefined, bg_mode: gd.bgMode, sun_rays: gd.sunRays, + sun_ray_origin: gd.sunRayOrigin, }; } @@ -10445,6 +10446,8 @@ export class HouseplanCard extends LitElement { return sunRaysOn(this._sunGlobal(), this._sunSpace()); } + private _effSunRayOrigin(): SunRayOrigin { return sunRayOriginOf(this._sunGlobal()); } + /** sun.sun, but only when the feature is armed (north_deg set somewhere). */ private _sunNow(): { azimuth: number; elevation: number } | null { return this._effNorth() !== null ? sunStateOf(this._renderPlanHass) : null; @@ -10498,7 +10501,8 @@ export class HouseplanCard extends LitElement { // during the whole write window (and forever if the write failed). const zeroWalls = this._zeroWalls(); const zeroKey = zeroWalls.barriers.map((line) => line.join(',')).join(';'); - const key = `${space.id}|${sun.azimuth}|${sun.elevation}|${north}|${this._cfgEpoch}` + const origin = this._effSunRayOrigin(); + const key = `${space.id}|${sun.azimuth}|${sun.elevation}|${north}|${origin}|${this._cfgEpoch}` + `|${zeroWalls.style}|${zeroKey}`; if (!this._sunRaysCache || this._sunRaysCache.key !== key) { const rooms = space.rooms @@ -10534,6 +10538,7 @@ export class HouseplanCard extends LitElement { rooms, windows, sun.azimuth, sun.elevation, north!, walls.length ? innerByRoom : undefined, walls.length ? wallDepthByOpening : undefined, + origin, ); const physical = this._physicalBodiesR(space); // A two-point body has zero area at rest, but its extrusion along the @@ -10576,11 +10581,11 @@ export class HouseplanCard extends LitElement { // side of a wall. // // DEV-EB173-01: the axis runs along the wall's INWARD NORMAL, from the - // room-side opening face inward, and is `r.depth` = `len·cos` long — NOT + // selected opening face inward, and is `r.depth` = `len·cos` long — NOT // along the ray. For parallel rays, distance from the source span is an // affine function of the point, so its iso-alpha lines are parallel to the // wall; with this axis every point `source + dir·u` lands at offset - // `u/len`. Whole inner opening at peak alpha, identical fade distance along every + // `u/len`. Whole selected opening at peak alpha, identical fade distance along every // ray, and the parallelogram's far edge exactly on the gradient's end. // // THE RIM (owner 2026-08-04, docs/SUN.md «The rim»): a 1 px black hairline diff --git a/src/houseplan-editor-runtime.ts b/src/houseplan-editor-runtime.ts index e290b30e..7800f250 100644 --- a/src/houseplan-editor-runtime.ts +++ b/src/houseplan-editor-runtime.ts @@ -74,12 +74,13 @@ import { type ResizeAreaPlacement, } from './resize-labels'; import { - computeSunRays, dayPhase, northDegOf, bgModeOf, sunRaysOn, + computeSunRays, dayPhase, northDegOf, bgModeOf, sunRaysOn, sunRayOriginOf, sunStateOf, rayPeakAlpha, raysVisible, rayColor, RAY_FADE_MS, type SunRay, rayStops, resolveDayCycle, dayCycleFingerprint, type DayCycleState, - rayRimEdges, rimStops, rimPeakAlpha, RIM_COLOR, + rayRimEdges, rimStops, rimPeakAlpha, RIM_COLOR, type SunRayOrigin, } from './sun'; import { dayCycleStageVars, renderDayCycleEnvironment } from './day-cycle-render'; +import { renderSunRayOriginSelect } from './sun-settings-view'; import { furnitureDefaultCm, furnitureGraphic, furnitureCorners, @@ -1113,9 +1114,9 @@ export interface HouseplanEditorHostPort { _sentPos: Map; _serverCfg: ServerConfig | null; _serverStorage: boolean; - _settings: { exclude_integrations?: string[]; group_lights?: boolean; show_all?: boolean; filter_seeded?: boolean; icon_rules?: { pattern: string; icon: string; }[]; show_room_tooltip?: boolean; zigbee_topology?: { enabled?: boolean; z2m_base_topics?: string[] }; radar?: { version?: 1; show_live?: boolean; [key: string]: unknown }; }; + _settings: { exclude_integrations?: string[]; group_lights?: boolean; show_all?: boolean; filter_seeded?: boolean; icon_rules?: { pattern: string; icon: string; }[]; show_room_tooltip?: boolean; sun_ray_origin?: SunRayOrigin; zigbee_topology?: { enabled?: boolean; z2m_base_topics?: string[] }; radar?: { version?: 1; show_live?: boolean; [key: string]: unknown }; }; _terminalFrame: 0 | 1 | 2; - _settingsDialog: { colors: FillColors; glowRadius: number; bgColor: string | null; northDeg: number | null; bgMode: "static" | "daynight"; sunRays: boolean; showRoomTooltip: boolean; zigbeeTopology: ZigbeeTopologySettings; radarShowLive: boolean; busy: boolean; } | null; + _settingsDialog: { colors: FillColors; glowRadius: number; bgColor: string | null; northDeg: number | null; bgMode: "static" | "daynight"; sunRays: boolean; sunRayOrigin: SunRayOrigin; showRoomTooltip: boolean; zigbeeTopology: ZigbeeTopologySettings; radarShowLive: boolean; busy: boolean; } | null; _supportDialog: SupportDialogState | null; _showAll: boolean; _showHidden: boolean; @@ -8837,6 +8838,7 @@ public _openSettingsDialog = (): void => { northDeg: northDegOf(this.host._settings, {}), bgMode: bgModeOf(this.host._settings, {}), sunRays: sunRaysOn(this.host._settings, {}), + sunRayOrigin: sunRayOriginOf(this.host._settings), radarShowLive: this.host._settings.radar?.show_live !== false, showRoomTooltip: showRoomTooltipOf(this.host._settings), zigbeeTopology: zigbeeTopologySettingsOf(this.host._settings), busy: false, }; @@ -10032,6 +10034,7 @@ public _updateDecorStyle(next: DecorStyle): void { settings.bg_mode = d.bgMode; if (d.sunRays) settings.sun_rays = true; else delete settings.sun_rays; + settings.sun_ray_origin = d.sunRayOrigin; if (d.showRoomTooltip) delete settings.show_room_tooltip; else settings.show_room_tooltip = false; const radarSettings = settings.radar; @@ -10444,6 +10447,7 @@ public _renderSettingsDialog(): TemplateResult { (this.host._settingsDialog = { ...this.host._settingsDialog!, sunRays: v }))} ${this.host._t('gs.sun_rays')} + ${renderSunRayOriginSelect(this.host._settingsDialog!.sunRayOrigin, (key) => this.host._t(key), (sunRayOrigin) => (this.host._settingsDialog = { ...this.host._settingsDialog!, sunRayOrigin }))} ${this.host._canEdit ? html`
    ${this.host._t('gs.backup_hint')}
    @@ -10480,7 +10484,7 @@ public _renderSettingsDialog(): TemplateResult {
    diff --git a/src/i18n/de.json b/src/i18n/de.json index 82fae422..c0159327 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -994,6 +994,9 @@ "gs.north_clear": "Löschen", "gs.north_letter": "N", "gs.sun_rays": "Sonnenlicht durch Fenster", + "gs.sun_ray_origin": "Sonnenstrahlen", + "gs.sun_ray_origin.inner": "Von den inneren Fensterecken", + "gs.sun_ray_origin.outer": "Von den äußeren Fensterecken", "gs.about_version": "House Plan Card v{v}", "gs.about_github": "GitHub · Dokumentation & Probleme", "gs.about_telegram": "Telegram-Chat", diff --git a/src/i18n/en.json b/src/i18n/en.json index 42ba475f..9b317c1e 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -994,6 +994,9 @@ "gs.north_clear": "Clear", "gs.north_letter": "N", "gs.sun_rays": "Sunlight through windows", + "gs.sun_ray_origin": "Sun rays", + "gs.sun_ray_origin.inner": "From the inner window corners", + "gs.sun_ray_origin.outer": "From the outer window corners", "gs.about_version": "Houseplan Card v{v}", "gs.about_github": "GitHub · docs & issues", "gs.about_telegram": "Telegram chat", diff --git a/src/i18n/fr.json b/src/i18n/fr.json index dff4543a..a27bb045 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -994,6 +994,9 @@ "gs.north_clear": "Effacer", "gs.north_letter": "N", "gs.sun_rays": "Lumière du soleil à travers les fenêtres", + "gs.sun_ray_origin": "Rayons du soleil", + "gs.sun_ray_origin.inner": "Depuis les angles intérieurs des fenêtres", + "gs.sun_ray_origin.outer": "Depuis les angles extérieurs des fenêtres", "gs.about_version": "Houseplan Card v{v}", "gs.about_github": "GitHub · documentation et problèmes", "gs.about_telegram": "Discussion Telegram", diff --git a/src/i18n/ru.json b/src/i18n/ru.json index e6356dcd..6f01e4cf 100644 --- a/src/i18n/ru.json +++ b/src/i18n/ru.json @@ -994,6 +994,9 @@ "gs.north_clear": "Сбросить", "gs.north_letter": "С", "gs.sun_rays": "Солнце в окнах", + "gs.sun_ray_origin": "Лучи солнца", + "gs.sun_ray_origin.inner": "От внутренних углов окон", + "gs.sun_ray_origin.outer": "От внешних углов окон", "gs.about_version": "Houseplan Card v{v}", "gs.about_github": "GitHub · документация и issues", "gs.about_telegram": "Чат в Telegram", diff --git a/src/sun-settings-view.ts b/src/sun-settings-view.ts new file mode 100644 index 00000000..3d0deff7 --- /dev/null +++ b/src/sun-settings-view.ts @@ -0,0 +1,20 @@ +import { html, type TemplateResult } from 'lit'; +import type { I18nKey } from './i18n'; +import type { SunRayOrigin } from './sun'; + +export function renderSunRayOriginSelect( + value: SunRayOrigin, + translate: (key: I18nKey) => string, + changed: (value: SunRayOrigin) => void, +): TemplateResult { + return html`
    + + +
    `; +} diff --git a/src/sun.ts b/src/sun.ts index 1c200a7b..af70931e 100644 --- a/src/sun.ts +++ b/src/sun.ts @@ -366,7 +366,7 @@ export interface SunRay { polys: number[][][]; /** Optional even-odd polygons after physical-obstacle subtraction. */ paths?: string[]; - /** Room-side opening corners (the bright end of the gradient). */ + /** Selected opening corners (inner or outer; the bright end of the gradient). */ a: number[]; b: number[]; /** Direction the light travels (AWAY from the sun), unit vector. */ @@ -396,8 +396,8 @@ export interface SunRay { * * `innerByRoom` (optional): when wall thickness is set, clip wedges to each * room's inner contour. `wallDepthByOpening` moves the full window span from - * the wall centreline to its room-side face, so the two side rays start at the - * opening's two inner corners (docs/WALL-THICKNESS.md §5). + * the wall centreline to the selected inner or outer face, so the two side + * rays start at that face's corners (docs/WALL-THICKNESS.md §5). */ export function computeSunRays( rooms: SunRoom[], @@ -407,6 +407,7 @@ export function computeSunRays( northDeg: number, innerByRoom?: Record, wallDepthByOpening?: Record, + origin: SunRayOrigin = 'inner', ): SunRay[] { if (!(elevation > 0)) return []; const toSun = sunDirOnPlan(azimuth, northDeg); @@ -424,17 +425,29 @@ export function computeSunRays( const half = w.length / 2; const normal: [number, number] = [-info.normal[0], -info.normal[1]]; const d = Math.max(0, wallDepthByOpening?.[w.id] || 0); - // A wall grows ±½ from its centreline. Start the whole light span on the - // room-side face: its endpoints are the two inner corners of the opening, - // independent of the sun's incidence angle. - const sourceX = w.x + normal[0] * d / 2; - const sourceY = w.y + normal[1] * d / 2; const hx = Math.cos(rad) * half; const hy = Math.sin(rad) * half; + // A wall grows ±½ from its centreline. The compatibility default starts + // at the room-side face. `outer` starts at the exterior face and admits + // only the physical window tunnel before joining the clean room floor. + const side = origin === 'outer' ? -1 : 1; + const sourceX = w.x + normal[0] * d * side / 2; + const sourceY = w.y + normal[1] * d * side / 2; const a = [sourceX - hx, sourceY - hy]; const b = [sourceX + hx, sourceY + hy]; const len = k * w.length; - const polys = clipToRoom(rayQuad(a, b, away, len), clipPoly); + const quad = rayQuad(a, b, away, len); + const polys = clipToRoom(quad, clipPoly); + if (origin === 'outer' && d > 0) { + const innerX = w.x + normal[0] * d / 2; + const innerY = w.y + normal[1] * d / 2; + polys.push(...clipToRoom(quad, [ + [sourceX - hx, sourceY - hy], + [sourceX + hx, sourceY + hy], + [innerX + hx, innerY + hy], + [innerX - hx, innerY - hy], + ])); + } if (!polys.length) continue; // inward normal + how deep the ray gets: cos of the incidence angle, // which windowLit() has already found to be above RAY_MIN_COS @@ -498,13 +511,13 @@ export const RAY_FADE_END = 0.85; /** * Gradient stops along the shaft: `[offset 0..1, share of the peak alpha]`. - * Convex ease-out — bright at the inner opening, half gone by a third of the way, + * Convex ease-out — bright at the selected opening face, half gone by a third of the way, * a whisper at two thirds, nothing from RAY_FADE_END on. Consumed by the card * as SVG s over the FULL wedge length, so the geometry and the gradient * always describe the same shaft (docs/SUN.md). * * This gradient is the ONLY thing that dissolves a wedge: the falloff runs - * along the ray, from the inner opening inward, and the sides of the shaft keep the + * along the ray, from the selected opening face inward, and the sides of the shaft keep the * hard edge light actually has (owner 2026-08-04: «не надо размывать их * боковые грани»). No blur is involved anywhere. */ @@ -536,7 +549,7 @@ export function rayStops(): [number, number][] { * * Contract (docs/SUN.md, «The rim»): * - * - only the two SIDE edges — the ones running from the inner opening corners + * - only the two SIDE edges — the ones running from the selected opening corners * along `dir`. Never the source edge (a-b) and never the far edge: those are * not boundaries of the beam, they are its source and its end; * - one screen pixel at any zoom (`vector-effect: non-scaling-stroke`); @@ -549,7 +562,7 @@ export function rayStops(): [number, number][] { */ /** - * Peak rim opacity at the inner opening. Visually tuned on the + * Peak rim opacity at the selected opening face. Visually tuned on the * demo rig at both extremes: it has to make the shaft legible on white paper * (the whole point) yet not read as an ink outline over the dark glow canvas. * Below ~0.3 the line disappears on paper at kiosk scale; above ~0.5 it turns @@ -673,6 +686,14 @@ export function northDegOf(settings: any, spaceSettings: any): number | null { export const BG_MODES = ['static', 'daynight'] as const; // #33 parity export type BgMode = (typeof BG_MODES)[number]; +export const SUN_RAY_ORIGINS = ['inner', 'outer'] as const; // #577 parity +export type SunRayOrigin = (typeof SUN_RAY_ORIGINS)[number]; + +/** Global window-light source; unknown/legacy values preserve the old geometry. */ +export function sunRayOriginOf(settings: any): SunRayOrigin { + return settings?.sun_ray_origin === 'outer' ? 'outer' : 'inner'; +} + /** Effective background mode; anything unknown falls back to 'static'. */ export function bgModeOf(settings: any, spaceSettings: any): BgMode { const pick = (v: any): BgMode | null => (v === 'static' || v === 'daynight' ? v : null); diff --git a/src/types.ts b/src/types.ts index a3952db0..9878109d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -301,6 +301,11 @@ export interface ServerConfig { icon_rules?: { pattern: string; icon: string }[]; /** Only an explicit false hides the room hover information window. */ show_room_tooltip?: boolean; + north_deg?: number; + bg_mode?: 'static' | 'daynight'; + sun_rays?: boolean; + /** Global source face for window sunlight; absent keeps the legacy inner face. */ + sun_ray_origin?: 'inner' | 'outer'; /** Opt-in, admin-only contextual Zigbee diagnostics (#54). */ zigbee_topology?: { enabled?: boolean; z2m_base_topics?: string[] }; /** Read-only grouped values shown over the plan (#437). */ diff --git a/test/config-schema-parity.test.mjs b/test/config-schema-parity.test.mjs index 164d362a..738fec19 100644 --- a/test/config-schema-parity.test.mjs +++ b/test/config-schema-parity.test.mjs @@ -9,7 +9,7 @@ import { import { OPENING_TYPES, VACUUM_TRAIL_MODES, ZERO_WALL_STYLES, } from '../test-build/types.js'; -import { BG_MODES } from '../test-build/sun.js'; +import { BG_MODES, SUN_RAY_ORIGINS } from '../test-build/sun.js'; const manifest = JSON.parse(readFileSync( new URL('../scripts/config-schema.json', import.meta.url), 'utf8')).fields; @@ -38,6 +38,7 @@ const PAIRS = [ { pair: 'vacuum.trail_mode', path: 'config.markers[].vacuum.trail_mode', front: VACUUM_TRAIL_MODES }, { pair: 'space.zero_wall_style', path: 'config.spaces[].zero_wall_style', front: ZERO_WALL_STYLES }, { pair: 'settings.bg_mode', path: 'config.settings.bg_mode', front: BG_MODES }, + { pair: 'settings.sun_ray_origin', path: 'config.settings.sun_ray_origin', front: SUN_RAY_ORIGINS }, ]; test('#33 AC2: backend and frontend enums agree, divergences only via the allow-list', () => { diff --git a/test/sun.test.mjs b/test/sun.test.mjs index 48791e4c..5dd4233e 100644 --- a/test/sun.test.mjs +++ b/test/sun.test.mjs @@ -9,7 +9,7 @@ import { RAY_LENGTH_K, RAY_FADE_END, rayStops, RAY_MIN_COS, rimStops, rimPeakAlpha, rayRimEdges, RIM_MAX_ALPHA, RIM_COLOR, SKY_SNAP_DEG, skyNeedsSnap, skyElevation, - northDegOf, bgModeOf, sunRaysOn, sunStateOf, + northDegOf, bgModeOf, sunRaysOn, sunRayOriginOf, SUN_RAY_ORIGINS, sunStateOf, DAY_CYCLE_PALETTES, dayCycleSunOf, dayCyclePhaseFromSun, dayCyclePhaseFromMinutes, dayCyclePositionFromSun, dayCyclePositionFromMinutes, resolveDayCycle, dayCycleFingerprint, @@ -465,6 +465,47 @@ test('computeSunRays: a thick-wall ray starts at both room-side opening corners' } }); +test('#577: outer rays start at the exterior corners and cross only the window tunnel', () => { + const win = { id: 'wW', x: 100, y: 300, angle: 90, length: 80 }; + const inner = { r1: [[110, 110], [490, 110], [490, 490], [110, 490]] }; + const [inside] = computeSunRays(ROOMS, [win], 270, 60, 0, inner, { wW: 20 }, 'inner'); + const [outside] = computeSunRays(ROOMS, [win], 270, 60, 0, inner, { wW: 20 }, 'outer'); + + assert.ok(inside && outside, 'the west window is lit in both modes'); + assert.deepEqual(outside.a, [90, 260]); + assert.deepEqual(outside.b, [90, 340]); + assert.deepEqual(inside.a, [110, 260]); + assert.deepEqual(inside.b, [110, 340]); + assert.equal(outside.len, inside.len, 'origin selection does not change nominal reach'); + assert.deepEqual(outside.dir, inside.dir, 'origin selection does not change direction'); + assert.deepEqual(outside.normal, inside.normal, 'origin selection does not change fade axis'); + assert.equal(outside.depth, inside.depth, 'origin selection does not change fade depth'); + + const points = outside.polys.flat(); + assert.ok(points.some(([x]) => near(x, 90, 1e-6)), 'the visible shaft reaches the outer face'); + assert.ok(points.some(([x]) => x > 110 + 1e-6), 'the shaft continues from the tunnel into the room'); + for (const [x, y] of points) { + if (x < 110 - 1e-6) { + assert.ok(y >= 260 - 1e-6 && y <= 340 + 1e-6, + 'outside the clean floor, light exists only inside the physical opening tunnel'); + } + } +}); + +test('#577: zero-depth walls are identical and invalid values preserve the legacy inner default', () => { + assert.deepEqual(SUN_RAY_ORIGINS, ['inner', 'outer']); + assert.equal(sunRayOriginOf({}), 'inner'); + assert.equal(sunRayOriginOf({ sun_ray_origin: 'inner' }), 'inner'); + assert.equal(sunRayOriginOf({ sun_ray_origin: 'outer' }), 'outer'); + for (const invalid of [null, '', 'outside', 1, true, {}]) { + assert.equal(sunRayOriginOf({ sun_ray_origin: invalid }), 'inner'); + } + + const inner = computeSunRays(ROOMS, [WIN.west], 270, 60, 0, undefined, undefined, 'inner'); + const outer = computeSunRays(ROOMS, [WIN.west], 270, 60, 0, undefined, undefined, 'outer'); + assert.deepEqual(outer, inner, 'without wall depth the two source faces coincide exactly'); +}); + test('grazing sun: the auditor\'s repro, fixed by a normal-axis fade (DEV-EB173-01)', () => { // The report's browser probe: a WEST window 80 render units long, elevation // 90 (so the nominal reach is 0.56 · 80 = 44.8 — «на 30 % короче»), azimuth diff --git a/tests_backend/test_ha_import_export.py b/tests_backend/test_ha_import_export.py index 41a8dc81..cc74a45e 100644 --- a/tests_backend/test_ha_import_export.py +++ b/tests_backend/test_ha_import_export.py @@ -527,6 +527,7 @@ def test_issue_225_backup_with_an_attachment_survives_a_full_round_trip( def test_background_defaults_and_store_migration_preserve_legacy_view() -> None: assert DEFAULT_CONFIG["settings"]["bg_mode"] == "daynight" + assert DEFAULT_CONFIG["settings"]["sun_ray_origin"] == "inner" legacy = { "config": { @@ -588,6 +589,19 @@ def test_background_mode_is_materialized_across_export_and_legacy_import(tmp_pat assert merged["spaces"][-1]["settings"]["bg_mode"] == "static" +def test_issue_577_full_export_preserves_sun_ray_origin(tmp_path: Path) -> None: + runtime = SimpleNamespace(instance_id="instance-a") + config = _config() + config["settings"]["sun_ray_origin"] = "outer" + document, _ = create_export( + runtime, {"config": config}, {"layout": {}}, + kind="full", space_id=None, card_version="1.76.0", config_root=tmp_path, + ) + assert document["payload"]["config"]["settings"]["sun_ray_origin"] == "outer" + parsed = parse_document(json.dumps(document).encode()) + assert parsed["payload"]["config"]["settings"]["sun_ray_origin"] == "outer" + + @pytest.mark.parametrize( ("kind", "plan_only"), [("full", False), ("space", False), ("space", True)], diff --git a/tests_backend/test_support_package.py b/tests_backend/test_support_package.py index 09a96b48..60cda2c2 100644 --- a/tests_backend/test_support_package.py +++ b/tests_backend/test_support_package.py @@ -215,6 +215,7 @@ def test_rich_plan_projection_preserves_safe_structure_and_drops_unknown_values( "model_version": 9, "settings": { "north_deg": 30, + "sun_ray_origin": "outer", "show_room_tooltip": False, "zigbee_topology": { "enabled": True, @@ -315,6 +316,7 @@ def test_rich_plan_projection_preserves_safe_structure_and_drops_unknown_values( assert plan["settings"]["fill_colors"] == {"temp_hot": {"a": 0.5, "c": "#ffaa00"}} assert b"private-owner" not in raw and b"example.test" not in raw assert plan["settings"]["show_room_tooltip"] is False + assert plan["settings"]["sun_ray_origin"] == "outer" assert "zigbee_topology" not in plan["settings"] assert b"private/site/zigbee2mqtt" not in raw assert plan["settings"]["decor_default_style"] == {"color": "#123456", "width_cm": 2} @@ -363,6 +365,7 @@ def test_projection_helpers_fail_closed_on_malformed_shapes(): assert support_package._custom_fill(None) is None assert support_package._global_settings(None) == {} assert support_package._global_settings({"show_room_tooltip": "false"}) == {} + assert support_package._global_settings({"sun_ray_origin": "invalid"}) == {} assert support_package._room_settings(ids, None) == {} assert support_package._project_layout(ids, None) == {} assert support_package._summary(None, None)["spaces"] == 0 diff --git a/tests_backend/test_validation.py b/tests_backend/test_validation.py index 80c164d2..00d71f34 100644 --- a/tests_backend/test_validation.py +++ b/tests_backend/test_validation.py @@ -497,9 +497,12 @@ def test_all_persisted_color_fields_share_the_strict_hex_contract(): def test_sun_settings_global(): """Active sun settings plus the accepted-but-ignored legacy weather field.""" v.CONFIG_SCHEMA({"spaces": [], "settings": { - "north_deg": 0, "bg_mode": "daynight", "sun_rays": True, "weather_entity": "weather.home", + "north_deg": 0, "bg_mode": "daynight", "sun_rays": True, + "sun_ray_origin": "outer", "weather_entity": "weather.home", + }}) + v.CONFIG_SCHEMA({"spaces": [], "settings": { + "north_deg": 359, "bg_mode": "static", "sun_ray_origin": "inner", }}) - v.CONFIG_SCHEMA({"spaces": [], "settings": {"north_deg": 359, "bg_mode": "static"}}) v.CONFIG_SCHEMA({"spaces": [], "settings": {"weather_entity": None}}) for bad in (360, -1, 1.5, "90", True, None): with pytest.raises(vol.Invalid): @@ -508,6 +511,9 @@ def test_sun_settings_global(): v.CONFIG_SCHEMA({"spaces": [], "settings": {"bg_mode": "disco"}}) with pytest.raises(vol.Invalid): v.CONFIG_SCHEMA({"spaces": [], "settings": {"sun_rays": "yes"}}) + for bad in (None, "inside", "", 0, True, [], {}): + with pytest.raises(vol.Invalid): + v.CONFIG_SCHEMA({"spaces": [], "settings": {"sun_ray_origin": bad}}) with pytest.raises(vol.Invalid): v.CONFIG_SCHEMA({"spaces": [], "settings": {"weather_entity": {"e": 1}}})