From bd60edd23818eac617857de27260dc604e430bfc Mon Sep 17 00:00:00 2001 From: Sergey Matyunin Date: Sun, 6 Sep 2026 07:48:03 +0300 Subject: [PATCH] fix: address isometric stage 3 review Issue: #160 User-Visible: no --- .../houseplan/frontend/houseplan-assets.json | 184 +++++++++--------- ...-z06DVBiX.js => backdrop-pick-BdNxo7sy.js} | 2 +- .../frontend/houseplan-assets/de-9rJdVNqo.js | 2 +- .../houseplan-assets/editor-B9JBe9YT.js | 10 +- .../frontend/houseplan-assets/fr-B1YMVVHy.js | 2 +- ...DlNVdCIc.js => houseplan-card-h7CLgil-.js} | 110 +++++------ ...s => houseplan-editor-runtime-BQxfLmCJ.js} | 6 +- .../houseplan-onboarding-runtime-BkPkAgsT.js | 6 +- ...=> hp-zigbee-topology-overlay-BJvwogZl.js} | 14 +- .../iso-scene-render-BLVbTyKE.js | 82 -------- .../iso-scene-render-BacpVxOg.js | 82 ++++++++ ...s => live-interaction-runtime-CLqXDVvg.js} | 2 +- .../zigbee-topology-BPCx22ZF.js | 2 +- ...js => zigbee-topology-runtime-PXmJ-UR0.js} | 2 +- .../houseplan/frontend/houseplan-card.js | 2 +- dist/houseplan-assets.json | 184 +++++++++--------- ...-z06DVBiX.js => backdrop-pick-BdNxo7sy.js} | 2 +- .../houseplan-assets/de-9rJdVNqo.js | 2 +- .../houseplan-assets/editor-B9JBe9YT.js | 10 +- .../houseplan-assets/fr-B1YMVVHy.js | 2 +- ...DlNVdCIc.js => houseplan-card-h7CLgil-.js} | 110 +++++------ ...s => houseplan-editor-runtime-BQxfLmCJ.js} | 6 +- .../houseplan-onboarding-runtime-BkPkAgsT.js | 6 +- ...=> hp-zigbee-topology-overlay-BJvwogZl.js} | 14 +- .../iso-scene-render-BLVbTyKE.js | 82 -------- .../iso-scene-render-BacpVxOg.js | 82 ++++++++ ...s => live-interaction-runtime-CLqXDVvg.js} | 2 +- .../zigbee-topology-BPCx22ZF.js | 2 +- ...js => zigbee-topology-runtime-PXmJ-UR0.js} | 2 +- dist/houseplan-card.js | 2 +- scripts/bundle-budget.mjs | 4 +- src/houseplan-card.ts | 24 ++- src/iso-scene-render.ts | 17 +- src/opening-symbol-placement.ts | 32 +++ test/iso-openings.test.mjs | 33 +++- test/iso-overlays.test.mjs | 40 ++++ test/opening-symbol-placement.test.mjs | 26 ++- 37 files changed, 656 insertions(+), 536 deletions(-) rename custom_components/houseplan/frontend/houseplan-assets/{backdrop-pick-z06DVBiX.js => backdrop-pick-BdNxo7sy.js} (99%) rename dist/houseplan-assets/de-B9k4OTKD.js => custom_components/houseplan/frontend/houseplan-assets/de-9rJdVNqo.js (99%) rename dist/houseplan-assets/editor-CpADL-Po.js => custom_components/houseplan/frontend/houseplan-assets/editor-B9JBe9YT.js (87%) rename dist/houseplan-assets/fr-D2aMxrYb.js => custom_components/houseplan/frontend/houseplan-assets/fr-B1YMVVHy.js (99%) rename custom_components/houseplan/frontend/houseplan-assets/{houseplan-card-DlNVdCIc.js => houseplan-card-h7CLgil-.js} (94%) rename custom_components/houseplan/frontend/houseplan-assets/{houseplan-editor-runtime-B8MzWgfl.js => houseplan-editor-runtime-BQxfLmCJ.js} (99%) rename dist/houseplan-assets/houseplan-onboarding-runtime-CQWdVdoD.js => custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-BkPkAgsT.js (97%) rename custom_components/houseplan/frontend/houseplan-assets/{hp-zigbee-topology-overlay-BxvD87oe.js => hp-zigbee-topology-overlay-BJvwogZl.js} (87%) delete mode 100644 custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-BLVbTyKE.js create mode 100644 custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-BacpVxOg.js rename custom_components/houseplan/frontend/houseplan-assets/{live-interaction-runtime-DIiVVHS_.js => live-interaction-runtime-CLqXDVvg.js} (75%) rename dist/houseplan-assets/zigbee-topology-CwVLuz6S.js => custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-BPCx22ZF.js (95%) rename custom_components/houseplan/frontend/houseplan-assets/{zigbee-topology-runtime-foMTa-yu.js => zigbee-topology-runtime-PXmJ-UR0.js} (93%) rename dist/houseplan-assets/{backdrop-pick-z06DVBiX.js => backdrop-pick-BdNxo7sy.js} (99%) rename custom_components/houseplan/frontend/houseplan-assets/de-B9k4OTKD.js => dist/houseplan-assets/de-9rJdVNqo.js (99%) rename custom_components/houseplan/frontend/houseplan-assets/editor-CpADL-Po.js => dist/houseplan-assets/editor-B9JBe9YT.js (87%) rename custom_components/houseplan/frontend/houseplan-assets/fr-D2aMxrYb.js => dist/houseplan-assets/fr-B1YMVVHy.js (99%) rename dist/houseplan-assets/{houseplan-card-DlNVdCIc.js => houseplan-card-h7CLgil-.js} (94%) rename dist/houseplan-assets/{houseplan-editor-runtime-B8MzWgfl.js => houseplan-editor-runtime-BQxfLmCJ.js} (99%) rename custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-CQWdVdoD.js => dist/houseplan-assets/houseplan-onboarding-runtime-BkPkAgsT.js (97%) rename dist/houseplan-assets/{hp-zigbee-topology-overlay-BxvD87oe.js => hp-zigbee-topology-overlay-BJvwogZl.js} (87%) delete mode 100644 dist/houseplan-assets/iso-scene-render-BLVbTyKE.js create mode 100644 dist/houseplan-assets/iso-scene-render-BacpVxOg.js rename dist/houseplan-assets/{live-interaction-runtime-DIiVVHS_.js => live-interaction-runtime-CLqXDVvg.js} (75%) rename custom_components/houseplan/frontend/houseplan-assets/zigbee-topology-CwVLuz6S.js => dist/houseplan-assets/zigbee-topology-BPCx22ZF.js (95%) rename dist/houseplan-assets/{zigbee-topology-runtime-foMTa-yu.js => zigbee-topology-runtime-PXmJ-UR0.js} (93%) diff --git a/custom_components/houseplan/frontend/houseplan-assets.json b/custom_components/houseplan/frontend/houseplan-assets.json index 4cc07a2d..91577ace 100644 --- a/custom_components/houseplan/frontend/houseplan-assets.json +++ b/custom_components/houseplan/frontend/houseplan-assets.json @@ -1,199 +1,199 @@ { "schema": 1, - "fingerprint": "bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa", + "fingerprint": "ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d", "entry": "houseplan-card.js", "initialViewFiles": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js", + "houseplan-assets/houseplan-card-h7CLgil-.js", "houseplan-card.js" ], - "initialViewGzipBytes": 299464, + "initialViewGzipBytes": 299495, "lazyFiles": [ - "houseplan-assets/backdrop-pick-z06DVBiX.js", - "houseplan-assets/de-B9k4OTKD.js", - "houseplan-assets/editor-CpADL-Po.js", - "houseplan-assets/fr-D2aMxrYb.js", - "houseplan-assets/houseplan-editor-runtime-B8MzWgfl.js", - "houseplan-assets/houseplan-onboarding-runtime-CQWdVdoD.js", - "houseplan-assets/hp-zigbee-topology-overlay-BxvD87oe.js", - "houseplan-assets/iso-scene-render-BLVbTyKE.js", - "houseplan-assets/live-interaction-runtime-DIiVVHS_.js", - "houseplan-assets/zigbee-topology-CwVLuz6S.js", - "houseplan-assets/zigbee-topology-runtime-foMTa-yu.js" + "houseplan-assets/backdrop-pick-BdNxo7sy.js", + "houseplan-assets/de-9rJdVNqo.js", + "houseplan-assets/editor-B9JBe9YT.js", + "houseplan-assets/fr-B1YMVVHy.js", + "houseplan-assets/houseplan-editor-runtime-BQxfLmCJ.js", + "houseplan-assets/houseplan-onboarding-runtime-BkPkAgsT.js", + "houseplan-assets/hp-zigbee-topology-overlay-BJvwogZl.js", + "houseplan-assets/iso-scene-render-BacpVxOg.js", + "houseplan-assets/live-interaction-runtime-CLqXDVvg.js", + "houseplan-assets/zigbee-topology-BPCx22ZF.js", + "houseplan-assets/zigbee-topology-runtime-PXmJ-UR0.js" ], - "lazyGzipBytes": 263446, + "lazyGzipBytes": 263411, "lazyEditorFiles": [ - "houseplan-assets/backdrop-pick-z06DVBiX.js", - "houseplan-assets/editor-CpADL-Po.js", - "houseplan-assets/houseplan-editor-runtime-B8MzWgfl.js", - "houseplan-assets/zigbee-topology-CwVLuz6S.js" + "houseplan-assets/backdrop-pick-BdNxo7sy.js", + "houseplan-assets/editor-B9JBe9YT.js", + "houseplan-assets/houseplan-editor-runtime-BQxfLmCJ.js", + "houseplan-assets/zigbee-topology-BPCx22ZF.js" ], - "lazyEditorGzipBytes": 186624, + "lazyEditorGzipBytes": 186628, "lazyOnboardingFiles": [ - "houseplan-assets/backdrop-pick-z06DVBiX.js", - "houseplan-assets/houseplan-onboarding-runtime-CQWdVdoD.js" + "houseplan-assets/backdrop-pick-BdNxo7sy.js", + "houseplan-assets/houseplan-onboarding-runtime-BkPkAgsT.js" ], - "lazyOnboardingGzipBytes": 14324, + "lazyOnboardingGzipBytes": 14321, "lazyLocaleFiles": [ - "houseplan-assets/de-B9k4OTKD.js", - "houseplan-assets/fr-D2aMxrYb.js" + "houseplan-assets/de-9rJdVNqo.js", + "houseplan-assets/fr-B1YMVVHy.js" ], - "lazyLocaleGzipBytes": 50146, + "lazyLocaleGzipBytes": 50152, "lazyIsometricFiles": [ - "houseplan-assets/iso-scene-render-BLVbTyKE.js" + "houseplan-assets/iso-scene-render-BacpVxOg.js" ], - "lazyIsometricGzipBytes": 12083, + "lazyIsometricGzipBytes": 12043, "files": [ { - "path": "houseplan-assets/backdrop-pick-z06DVBiX.js", - "sha256": "75e6d7af19c3aba5060dfa8c5f6dc06beaab66a27c417a0de527c5b942dbfbc9", + "path": "houseplan-assets/backdrop-pick-BdNxo7sy.js", + "sha256": "85e78b3b7e19b6fbc9cd7f5f9eeabf60c143e8d84361ce4ae51dcf39eed34ca1", "rawBytes": 21592, - "gzipBytes": 7355, + "gzipBytes": 7356, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js" + "houseplan-assets/houseplan-card-h7CLgil-.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/de-B9k4OTKD.js", - "sha256": "4ada0cf6cf1f71ff8f5dc9053fe9e70dc3b74a7a87df63c8c833d2dd5053a650", + "path": "houseplan-assets/de-9rJdVNqo.js", + "sha256": "bc7a8a69292c1cbf12d063ac1c92569660679446dad3b08d783a42a3ecf0fea2", "rawBytes": 84232, - "gzipBytes": 25350, + "gzipBytes": 25353, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/editor-CpADL-Po.js", - "sha256": "d30ad5dcfbf0c604332774e7ff8213b061c214e0dab24d6752062e76dc8e3eed", + "path": "houseplan-assets/editor-B9JBe9YT.js", + "sha256": "dc1d6039050ae2135e3608e118a19065a827024e26a3f32363afa5db40f7e7ed", "rawBytes": 3831, - "gzipBytes": 1585, + "gzipBytes": 1584, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js" + "houseplan-assets/houseplan-card-h7CLgil-.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/fr-D2aMxrYb.js", - "sha256": "a74ec4c4934908ebe04a01a26626770e17ae169a7b60eeadf5b5f4ff5e78b36c", + "path": "houseplan-assets/fr-B1YMVVHy.js", + "sha256": "af1be2253d149fb4888961067211a6f77ff5d05f44bdb9dfd75f1b710962a1d8", "rawBytes": 86273, - "gzipBytes": 24796, + "gzipBytes": 24799, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/houseplan-card-DlNVdCIc.js", - "sha256": "4b15c9335ec994b8182f1d491090fdbafe5c8f1d16ccb13db9cda5e439346050", - "rawBytes": 1071991, - "gzipBytes": 298670, + "path": "houseplan-assets/houseplan-card-h7CLgil-.js", + "sha256": "2d088763554fb5194378ef7a615b1b4022a6e9eaf7c7adb6a8e2c0b32b6073a5", + "rawBytes": 1072052, + "gzipBytes": 298700, "isEntry": false, "imports": [], "dynamicImports": [ - "houseplan-assets/de-B9k4OTKD.js", - "houseplan-assets/editor-CpADL-Po.js", - "houseplan-assets/fr-D2aMxrYb.js", - "houseplan-assets/houseplan-editor-runtime-B8MzWgfl.js", - "houseplan-assets/houseplan-onboarding-runtime-CQWdVdoD.js", - "houseplan-assets/hp-zigbee-topology-overlay-BxvD87oe.js", - "houseplan-assets/iso-scene-render-BLVbTyKE.js", - "houseplan-assets/live-interaction-runtime-DIiVVHS_.js" + "houseplan-assets/de-9rJdVNqo.js", + "houseplan-assets/editor-B9JBe9YT.js", + "houseplan-assets/fr-B1YMVVHy.js", + "houseplan-assets/houseplan-editor-runtime-BQxfLmCJ.js", + "houseplan-assets/houseplan-onboarding-runtime-BkPkAgsT.js", + "houseplan-assets/hp-zigbee-topology-overlay-BJvwogZl.js", + "houseplan-assets/iso-scene-render-BacpVxOg.js", + "houseplan-assets/live-interaction-runtime-CLqXDVvg.js" ] }, { - "path": "houseplan-assets/houseplan-editor-runtime-B8MzWgfl.js", - "sha256": "06aa1e075def4eb03262e4ad308a96b500c0a73c59cf7641f9f5a3fa618cb41f", + "path": "houseplan-assets/houseplan-editor-runtime-BQxfLmCJ.js", + "sha256": "969d84a3adeb14e3f1b5ca1c1cd9dd6c0e173dba9a20577c2585eab65ac520d3", "rawBytes": 639580, - "gzipBytes": 170260, + "gzipBytes": 170264, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-z06DVBiX.js", - "houseplan-assets/houseplan-card-DlNVdCIc.js", - "houseplan-assets/zigbee-topology-CwVLuz6S.js" + "houseplan-assets/backdrop-pick-BdNxo7sy.js", + "houseplan-assets/houseplan-card-h7CLgil-.js", + "houseplan-assets/zigbee-topology-BPCx22ZF.js" ], "dynamicImports": [ - "houseplan-assets/zigbee-topology-runtime-foMTa-yu.js" + "houseplan-assets/zigbee-topology-runtime-PXmJ-UR0.js" ] }, { - "path": "houseplan-assets/houseplan-onboarding-runtime-CQWdVdoD.js", - "sha256": "fdac5dd01af4bc78089208ac7acf671a76aa05d21f1f5e1db90429bfcb3965d9", + "path": "houseplan-assets/houseplan-onboarding-runtime-BkPkAgsT.js", + "sha256": "f6da0d6184406def22e1e7e2e0aad25e60499f04a326deafc835d109c79b4c92", "rawBytes": 28071, - "gzipBytes": 6969, + "gzipBytes": 6965, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-z06DVBiX.js", - "houseplan-assets/houseplan-card-DlNVdCIc.js" + "houseplan-assets/backdrop-pick-BdNxo7sy.js", + "houseplan-assets/houseplan-card-h7CLgil-.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/hp-zigbee-topology-overlay-BxvD87oe.js", - "sha256": "d5b48f961b1e6b208bb2b1dd1343e62fabc7455f77dbb40fffc569dc540a1be7", + "path": "houseplan-assets/hp-zigbee-topology-overlay-BJvwogZl.js", + "sha256": "5ea4c8d30c1b21395080ae3cd12311a2daad0c4cd263ed00da805ab67da3a3c9", "rawBytes": 11034, - "gzipBytes": 3733, + "gzipBytes": 3734, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js", - "houseplan-assets/zigbee-topology-CwVLuz6S.js", - "houseplan-assets/zigbee-topology-runtime-foMTa-yu.js" + "houseplan-assets/houseplan-card-h7CLgil-.js", + "houseplan-assets/zigbee-topology-BPCx22ZF.js", + "houseplan-assets/zigbee-topology-runtime-PXmJ-UR0.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/iso-scene-render-BLVbTyKE.js", - "sha256": "4660a76ce22af17fce7d858e98d71bcc8b8d97b80a85e7b96926a12299283d3d", - "rawBytes": 35916, - "gzipBytes": 12083, + "path": "houseplan-assets/iso-scene-render-BacpVxOg.js", + "sha256": "6a86291c3c1399b13c0e9693bbe47be0f4f50113a8ec3f234fe25efa2cfe98b1", + "rawBytes": 35885, + "gzipBytes": 12043, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js" + "houseplan-assets/houseplan-card-h7CLgil-.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/live-interaction-runtime-DIiVVHS_.js", - "sha256": "a953a0bbe4ab2476395f4d0358c0c3d7c7ab4e19d2c49dc943f5302f35dae756", + "path": "houseplan-assets/live-interaction-runtime-CLqXDVvg.js", + "sha256": "bd74a816bde6b4327ba1a2fb3da462b3d113028540d656c1caa7f8738a4d40ab", "rawBytes": 5196, - "gzipBytes": 2127, + "gzipBytes": 2126, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js" + "houseplan-assets/houseplan-card-h7CLgil-.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/zigbee-topology-CwVLuz6S.js", - "sha256": "db18356891ee72d824847aa55361ee43089ab5a22de436590576136344b90a22", + "path": "houseplan-assets/zigbee-topology-BPCx22ZF.js", + "sha256": "32a5fef33e2255f51bdd928a999245a548a4c7a9d180bf700559235a8f2779fd", "rawBytes": 18961, "gzipBytes": 7424, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js" + "houseplan-assets/houseplan-card-h7CLgil-.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/zigbee-topology-runtime-foMTa-yu.js", - "sha256": "f92eccdb7413e3c6c03ec80043ab40811643d9c7ba60c8c0ac0e62b55ecf1174", + "path": "houseplan-assets/zigbee-topology-runtime-PXmJ-UR0.js", + "sha256": "59e3eee3dcfea4b2e02bf54391ea9617777c9a52df6602951b7f25dbe3da9abb", "rawBytes": 3941, - "gzipBytes": 1764, + "gzipBytes": 1763, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js", - "houseplan-assets/zigbee-topology-CwVLuz6S.js" + "houseplan-assets/houseplan-card-h7CLgil-.js", + "houseplan-assets/zigbee-topology-BPCx22ZF.js" ], "dynamicImports": [] }, { "path": "houseplan-card.js", - "sha256": "f0e9bac231ea537556eab041e22de408ca82bd2f3bfb5bf064cb2b5b72cb16c8", + "sha256": "8331dfd72f55bc93e145b767aa88fff0f99ef6a046d8bd48ee184b082550361f", "rawBytes": 1183, - "gzipBytes": 794, + "gzipBytes": 795, "isEntry": true, "imports": [ - "houseplan-assets/houseplan-card-DlNVdCIc.js" + "houseplan-assets/houseplan-card-h7CLgil-.js" ], "dynamicImports": [] } diff --git a/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-z06DVBiX.js b/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-BdNxo7sy.js similarity index 99% rename from custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-z06DVBiX.js rename to custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-BdNxo7sy.js index 33d29c4c..db1e34bb 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-z06DVBiX.js +++ b/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-BdNxo7sy.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa";import{D as e,c as t,A as i,u as o,v as n,ds as r}from"./houseplan-card-DlNVdCIc.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),d=Math.max(0,l-s),c=Math.min(Math.max(0,t.width),h),u=Math.min(Math.max(0,t.height),d);let p=e.left;p+c>a&&(p=e.right-c),p=Math.min(Math.max(r,p),Math.max(r,a-c));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(d)}}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 d 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-c),p=Math.min(Math.max(r,p),Math.max(r,a-c));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(d)}}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 d 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=d.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")},_=this._schema,f=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,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`h[e.name]||e.name} @value-changed=${this._valueChanged} >`;return c` - ${d(_.slice(0,3))} - ${f?c``:a} - ${d(_.slice(3))} + ${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); diff --git a/dist/houseplan-assets/fr-D2aMxrYb.js b/custom_components/houseplan/frontend/houseplan-assets/fr-B1YMVVHy.js similarity index 99% rename from dist/houseplan-assets/fr-D2aMxrYb.js rename to custom_components/houseplan/frontend/houseplan-assets/fr-B1YMVVHy.js index db76d368..46a9e3a4 100644 --- a/dist/houseplan-assets/fr-D2aMxrYb.js +++ b/custom_components/houseplan/frontend/houseplan-assets/fr-B1YMVVHy.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa";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","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, colonnes et contours enregistrés","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.draft_segment":"Ajouter un segment de brouillon de pièce","history.draft_merge":"Relier des contours de pièce inachevés","history.draft_segment_delete":"Supprimer un segment de brouillon de pièce","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.contour_to_partitions":"Convertir le contour en murs fermés","history.wall_chain_finish":"Terminer la chaîne de murs","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à","confirm.delete_draft_title":"Supprimer le contour inachevé ?","confirm.delete_draft_body":"Tout le contour de pièce inachevé sera supprimé. L’annulation ne modifie rien.","confirm.delete_draft_segment_title":"Supprimer le segment de contour ?","confirm.delete_draft_segment_body":"Ce segment de brouillon sera supprimé. Le contour restant peut se scinder en deux.","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.draft_properties":"Propriétés du segment de brouillon","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.delete_segment":"Supprimer le segment","physical.delete_draft":"Supprimer tout le contour","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.","empty.add_first":"Ajoutez le premier espace et importez un plan.","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 ; Maj verrouille à 45°. Changer d’outil ou quitter l’éditeur termine la chaîne en murs indépendants","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, un contour inachevé 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","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","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_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.","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_removed_drafts":"Contours invalides réduits par la grille et supprimés : {n}.","gs.optimize_redundant_drafts":"Chaînes de murs enregistrées masquées par des murs de pièces pleins et supprimées : {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.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.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="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa";export{e as dictionary,r as fingerprint}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d";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","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, colonnes et contours enregistrés","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.draft_segment":"Ajouter un segment de brouillon de pièce","history.draft_merge":"Relier des contours de pièce inachevés","history.draft_segment_delete":"Supprimer un segment de brouillon de pièce","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.contour_to_partitions":"Convertir le contour en murs fermés","history.wall_chain_finish":"Terminer la chaîne de murs","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à","confirm.delete_draft_title":"Supprimer le contour inachevé ?","confirm.delete_draft_body":"Tout le contour de pièce inachevé sera supprimé. L’annulation ne modifie rien.","confirm.delete_draft_segment_title":"Supprimer le segment de contour ?","confirm.delete_draft_segment_body":"Ce segment de brouillon sera supprimé. Le contour restant peut se scinder en deux.","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.draft_properties":"Propriétés du segment de brouillon","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.delete_segment":"Supprimer le segment","physical.delete_draft":"Supprimer tout le contour","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.","empty.add_first":"Ajoutez le premier espace et importez un plan.","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 ; Maj verrouille à 45°. Changer d’outil ou quitter l’éditeur termine la chaîne en murs indépendants","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, un contour inachevé 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","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","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_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.","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_removed_drafts":"Contours invalides réduits par la grille et supprimés : {n}.","gs.optimize_redundant_drafts":"Chaînes de murs enregistrées masquées par des murs de pièces pleins et supprimées : {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.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.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="ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d";export{e as dictionary,r as fingerprint}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-DlNVdCIc.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-h7CLgil-.js similarity index 94% rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-card-DlNVdCIc.js rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-card-h7CLgil-.js index b35533c3..8cfbf13f 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-DlNVdCIc.js +++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-h7CLgil-.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa";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,z=()=>D.createComment(""),A=e=>null===e||"object"!=typeof e&&"function"!=typeof e,P=Array.isArray,F="[ \t\n\f\r]",I=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,O=/-->/g,E=/>/g,H=RegExp(`>|${F}(?:([^\\s"'>=/]+)(${F}*=${F}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/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"),V=Symbol.for("lit-nothing"),G=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!P(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]?H:'"'===l[3]?L:N):s===L||s===N?s=H:s===O||s===E?s=I:(s=H,r=void 0);const d=s===H&&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;iP(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!==V&&A(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=G.get(e.strings);return void 0===t&&G.set(e.strings,t=new Z(e)),t}k(e){P(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(z()),this.O(z()),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=V}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!A(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(z(),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=new WeakMap;let pe=0;class _e extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=null,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++pe,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(){super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=ue.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),ue.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?ue.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=ue.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void ue.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__="ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d";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,z=()=>D.createComment(""),A=e=>null===e||"object"!=typeof e&&"function"!=typeof e,P=Array.isArray,F="[ \t\n\f\r]",I=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,O=/-->/g,E=/>/g,H=RegExp(`>|${F}(?:([^\\s"'>=/]+)(${F}*=${F}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/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"),V=Symbol.for("lit-nothing"),G=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!P(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]?H:'"'===l[3]?L:N):s===L||s===N?s=H:s===O||s===E?s=I:(s=H,r=void 0);const d=s===H&&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;iP(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!==V&&A(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=G.get(e.strings);return void 0===t&&G.set(e.strings,t=new Z(e)),t}k(e){P(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(z()),this.O(z()),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=V}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!A(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(z(),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=new WeakMap;let pe=0;class _e extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=null,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++pe,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(){super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=ue.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),ue.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?ue.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=ue.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void ue.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``:V} ${this.title} `;return this._usesHaDialog()?this.describedBy?j` ${null!=e.lqiText?j`${e.lqiText}`:V} - `}function kp(e){return!Number.isFinite(e)||e<=0?2.25:e/2.5*2.25}function xp({openings:e,geometries:t,fillsByRoomId:i,idPrefix:n="data",groupClass:r="opening-tunnels",dataLayer:o="data"}){const s=e.map((e,r)=>{const o=t[r];if(!o)return V;const s=o.faces.find(e=>-1===e.side),a=o.faces.find(e=>1===e.side);if(!s||!a)return V;const l=i.get(s.roomId)||null,c=i.get(a.roomId)||null;if(!l&&!c)return V;const h=`${s.d} ${a.d}`,d=!!l&&!!c&&l.color===c.color&&l.opacity===c.opacity,u=`translate(${e.rx} ${e.ry}) rotate(${e.angle})`;if(d)return W`{const o=t[r];if(!o)return V;const s=o.faces.find(e=>-1===e.side),a=o.faces.find(e=>1===e.side);if(!s||!a)return V;const l=i.get(s.roomId)||null,c=i.get(a.roomId)||null;if(!l&&!c)return V;const h=`${s.d} ${a.d}`,d=!!l&&!!c&&l.color===c.color&&l.opacity===c.opacity,u=`translate(${e.rx} ${e.ry}) rotate(${e.angle})`;if(d)return W``;const p=o.maxY-o.minY;if(!(p>0))return V;const _=`${(100*Math.max(0,Math.min(1,-o.minY/p))).toFixed(6)}%`,m=l||{color:"#000000",opacity:0},g=c||{color:"#000000",opacity:0},f=`hp-opening-tunnel-${n.replace(/[^a-zA-Z0-9_-]/g,"-")}-${r}`;return W` - `});return W``}function Sp(e,t,i){const n=i>0?i:1;return{a:[e[0]/n,e[1]/n],b:[t[0]/n,t[1]/n]}}function $p(e,t){const i=t>0?t:1;return[e.a[0]*i,e.a[1]*i,e.b[0]*i,e.b[1]*i]}function Mp(e){return Array.isArray(e)&&e.length>=2&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))}function Rp(e){if(!Array.isArray(e))return[];const t=[];for(const i of e){if(!i||"object"!=typeof i)continue;const e=i;if(!Mp(e.a)||!Mp(e.b))continue;const n=[Number(e.a[0]),Number(e.a[1])],r=[Number(e.b[0]),Number(e.b[1])];Math.hypot(r[0]-n[0],r[1]-n[1])<.001||t.push({a:n,b:r})}return t}function Cp(e,t,i,n,r=!0){const o=(e||[]).filter(e=>e?.id),s=Rp(t);if(s.length)return function(e,t,i,n){const r=Rp(e);if(!r.length)return[];const o=function(e,t){const i=[],n=(e||[]).filter(e=>e?.id);for(let e=0;e4*n||o>4*n)continue;const s=(e[0]-r)*u+(e[1]-l)*p,c=(e[2]-r)*u+(e[3]-l)*p,h=Math.max(0,Math.min(s,c)),m=Math.min(d,Math.max(s,c));if(m-he.lo-t.lo||e.hi-t.hi);const i=[];for(const e of t){const t=i[i.length-1];t&&e.lo<=t.hi+a?t.hi=Math.max(t.hi,e.hi):i.push({...e})}for(const t of i){const i=[r+u*t.lo,l+p*t.lo],n=[r+u*t.hi,l+p*t.hi];Math.hypot(n[0]-i[0],n[1]-i[1])i.pair===e&&Math.abs(i.ux*s-i.uy*o)<=1e-6&&Math.abs((t[0]-i.origin[0])*i.uy-(t[1]-i.origin[1])*i.ux)<=c&&Math.abs((t[2]-i.origin[0])*i.uy-(t[3]-i.origin[1])*i.ux)<=c);h||(h={pair:e,origin:[t[0],t[1]],ux:o,uy:s,ranges:[]},l.push(h));const d=(t[0]-h.origin[0])*h.ux+(t[1]-h.origin[1])*h.uy,u=(t[2]-h.origin[0])*h.ux+(t[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const e of l){e.ranges.sort((e,t)=>e.lo-t.lo||e.hi-t.hi);const t=[];for(const i of e.ranges){const e=t[t.length-1];e&&i.lo<=e.hi+a?e.hi=Math.max(e.hi,i.hi):t.push({...i})}for(const n of t){const t=[e.origin[0]+e.ux*n.lo,e.origin[1]+e.uy*n.lo],r=[e.origin[0]+e.ux*n.hi,e.origin[1]+e.uy*n.hi];Math.hypot(r[0]-t[0],r[1]-t[1])>=a&&h.push(Sp(t,r,i))}}return h}(s,e,i,n).map(e=>$p(e,i));if(!r)return[];const a=[],l=(e,t)=>(e.open_to||[]).includes(t.id)||(t.open_to||[]).includes(e.id);for(let e=0;er)&&Co([o[0],o[1]],[o[2],o[3]],i))return!0;return!1}const Dp=e=>Array.isArray(e)&&e.length>=2&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1])),zp=(e,t,i)=>[Number(e[0])*i,Number(e[1])*i,Number(t[0])*i,Number(t[1])*i],Ap=e=>{const t=`${Number(e[0]).toFixed(9)},${Number(e[1]).toFixed(9)}`,i=`${Number(e[2]).toFixed(9)},${Number(e[3]).toFixed(9)}`;return t<=i?`${t}|${i}`:`${i}|${t}`},Pp=e=>{const t=new Map;for(const i of e.flat())!Array.isArray(i)||i.length<4||!i.every(Number.isFinite)||Math.hypot(i[2]-i[0],i[3]-i[1])<=1e-9||t.set(Ap(i),[...i]);return[...t.values()]};function Fp(e){return"solid"===e?.zero_wall_style?"solid":"dashed"}function Ip(e,t=1,i){const n=[];for(const r of Array.isArray(e?.wall_segments)?e.wall_segments:[])0===Number(r?.cm)&&Dp(r?.a)&&Dp(r?.b)&&(i&&!i.has(String(r.id||""))||n.push(zp(r.a,r.b,t)));return Pp([n])}function Op(e,t=1){const i=[];for(const n of Array.isArray(e?.partitions)?e.partitions:[])0===Number(n?.cm)&&Dp(n?.a)&&Dp(n?.b)&&i.push(zp(n.a,n.b,t));for(const n of Array.isArray(e?.room_drafts)?e.room_drafts:[]){const e=Array.isArray(n?.points)?n.points:[];for(let r=0;r+1e?.host?.kind===t.kind&&e.host.id===t.id)}function Lp(e){return e instanceof Error?e.name||"Error":typeof e}function Bp(e){return El({id:e?.id??"",cell_cm:e?.cell_cm,rooms:e?.rooms||[],walls:e?.walls||[],wall_segments:e?.wall_segments||[],open_spans:e?.open_spans||[],openings:e?.openings||[],partitions:e?.partitions||[],room_drafts:e?.room_drafts||[],wall_columns:e?.wall_columns||[]})}function qp(e,t,i={}){const n=(Array.isArray(e?.spaces)?e.spaces:[]).find(e=>String(e?.id||"")===String(t||"")),r=Bp(n);if(!n)return{spaceId:String(t||""),displayName:"",status:"failed",reason:"prepare-exception",fingerprint:r,ok:!1};const o=Kp({...e,spaces:[n]},{...i,fingerprint:()=>r}).spaces[0]||{spaceId:String(t||""),displayName:"",status:"failed",reason:"prepare-exception"};return{...o,fingerprint:r,ok:"failed"!==o.status}}function jp(e,t,i,n=Fa,r=1e3){return(Array.isArray(e?.openings)?e.openings:[]).flatMap(e=>{const o={...e,rx:Number(e.x)*r,ry:Number(e.y)*r,rlen:Number(e.length)*r};if(!e.host||"wall"===e.host.kind)return[o];const s=Qd(e,t.partitions,r,i,n);return s.resolved?[{...e,rx:s.resolved.center[0],ry:s.resolved.center[1],rlen:s.resolved.length,angle:s.resolved.angle,partitionHost:s.resolved}]:[]})}function Wp(e,t=()=>!0){return e.flatMap(e=>e.host&&e.partitionHost&&t(e)?[iu(e.partitionHost)]:[])}function Up(e,t,i,n,r,o,s=Fa,a=1e3){const l=ds(t.rooms,[...i],n,r,o,s,a);return e.flatMap(e=>{const t={x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen};return e.host&&"wall"!==e.host.kind?e.partitionHost&&ou(e.partitionHost,l,2e-4*s)?[t]:[]:[t]})}function Vp(e,t){const i=Ia,n=Fa,r=Sa,o=Number.isFinite(Number(t.cellCm))&&Number(t.cellCm)>0?Number(t.cellCm):5,s=Array.isArray(e?.walls)?e.walls:[],a=function(e,t,i=Fa,n=1e3){return Cp(t.rooms,e?.open_spans,n,.02*i)}(e,t,n,r),l=function(e,t,i=Fa){if(!t.length)return[];const n=e.filter(e=>e?.id),r=.02*i,o=[];for(let e=0;e{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return h.some(e=>Mn(t,e)<4*r)}).map(e=>[...e]);d.length&&o.push({a:s,b:a,segs:d})}return o}(t.rooms,a,n).flatMap(e=>e.segs),c=jp(e,t,o,n,r),h=Wp(c),d=sa(t,o,n,2e-4*n,h).all;return{space:t,walls:s,openCuts:l,openings:c,roomOpenings:Up(c,t,s,l,i,o,n,r),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:n,coordScale:r}}function Gp(e,t,i){const n="string"==typeof e?.title?e.title.trim():"",r=null==e?.id?"":String(e.id).trim();return{spaceId:r,displayName:n||r||i(t+1)}}function Kp(e,t={}){const i=(t.fingerprint||El)(e),n=Array.isArray(e?.spaces)?e.spaces:[],r=t.fallbackSpaceName||(e=>`Space ${e}`),o=t.prepareSpace||Vp,s=t.wallPass||Ps,a=t.floorPass||Ts,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!u){l.push({...h,status:"not-applicable"});continue}let p=null;if(u){try{p=s(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(e){l.push({...h,status:"failed",reason:"wall-exception",detail:Lp(e)});continue}if(null==p){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===p.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===p.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}t.captureWallGeometry?.(d,p)}if(d.space.rooms.length&&null==p?.paperGeom){let e;try{e=a(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(e){l.push({...h,status:"failed",reason:"floor-exception",detail:Lp(e)});continue}if(null==e){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(e=>"failed"===e.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}const Yp=e=>"string"==typeof e&&e.length>0&&e.length<=500;function Xp(e){return Yp(e)&&(e.startsWith("device:")||e.startsWith("entity:"))&&e.indexOf(":")0||null===e.area&&"string"==typeof e.space&&e.space.length>0&&"string"==typeof e.room_id&&e.room_id.length>0)}(i)||i&&i.binding!==t?null:"entity"!==e.bindingKind||i?t:null}function e_(e,t){return e.rooms.filter(e=>{const i=function(e){if(Array.isArray(e.poly)&&e.poly.length>=3)return e.poly;const{x:t,y:i,w:n,h:r}=e;return![t,i,n,r].every(Number.isFinite)||Number(n)<=0||Number(r)<=0?null:[[t,i],[t+n,i],[t+n,i+r],[t,i+r]]}(e);return!!i&&ti(t,i)})}function t_(e,t){return{id:e,binding:null,area:null,relocate:!1,updateSnapshot:!1,removeSnapshot:!1,reason:t}}function i_(e){const t=e.indexOf(":");return[e.slice(0,t),e.slice(t+1)]}function n_(e){const t=[],i=new Set;if(!e.authoritative)return{decisions:t,relocateIds:i};const n=Zp(e.snapshot);for(const i of e.cleanupSnapshotIds||[])n[i]&&t.push({...t_(i,"registry-unverified"),removeSnapshot:!0});const r=Number.isFinite(e.coordinateScale)&&Number(e.coordinateScale)>0?Number(e.coordinateScale):1e3,o=new Map;for(const t of e.model)for(const e of t.rooms){if(!e.area)continue;const i=o.get(e.area)||[];i.push({space:t,room:e}),o.set(e.area,i)}for(const s of e.devices){const a=n[s.id],l=Qp(s);if(!l){a&&t.push({...t_(s.id,"registry-unverified"),removeSnapshot:!0});continue}const c=Yp(s.area)?s.area:null;if(!c){t.push({id:s.id,binding:l,area:null,relocate:!1,updateSnapshot:!1,removeSnapshot:!1,reason:"registry-unverified"});continue}const h=o.get(c);if(!h||1!==h.length){t.push({id:s.id,binding:l,area:c,relocate:!1,updateSnapshot:!1,removeSnapshot:!1,reason:"target-unresolved"});continue}if(a?.binding===l){const e=a.area!==c;e&&i.add(s.id),t.push({id:s.id,binding:l,area:c,relocate:e,updateSnapshot:e,removeSnapshot:!1,reason:e?"area-changed":"unchanged"});continue}const d=e.layout[s.id];if(!d){t.push({id:s.id,binding:l,area:c,relocate:!1,updateSnapshot:!0,removeSnapshot:!1,reason:"new-without-layout"});continue}const[{space:u,room:p}]=h;if(d.s&&d.s!==u.id){i.add(s.id),t.push({id:s.id,binding:l,area:c,relocate:!0,updateSnapshot:!0,removeSnapshot:!1,reason:"backfill-cross-space"});continue}if(d.s!==u.id||!Number.isFinite(d.x)||!Number.isFinite(d.y)){t.push({id:s.id,binding:l,area:c,relocate:!1,updateSnapshot:!0,removeSnapshot:!1,reason:"backfill-ambiguous"});continue}const _=e_(u,[d.x*r,d.y*r]),m=1===_.length?_[0]:null,g=m===p||!!m?.id&&!!p.id&&m.id===p.id,f=!!m?.area&&m.area!==c,v=!g&&f;v&&i.add(s.id),t.push({id:s.id,binding:l,area:c,relocate:v,updateSnapshot:!0,removeSnapshot:!1,reason:v?"backfill-stale-room":g?"backfill-same-room":"backfill-ambiguous"})}return{decisions:t,relocateIds:i}}const r_=1,o_=/^[0-9a-f]{64}$/,s_=new WeakMap;function a_(e){const t=new Set;for(const i of e?.spaces||[])for(const e of i?.decor||[])"image"===e?.kind&&o_.test(e.asset_id)&&t.add(e.asset_id);return[...t]}function l_(e,t,i){const n=Number(e.x)*t,r=Number(e.y)*i,o=Number(e.w)*t,s=Number(e.h)*i;if(![n,r,o,s].every(Number.isFinite)||o<=0||s<=0)return null;const a=n+o/2,l=r+s/2,c=sr(e.angle);return[n,r,o,s,or(e.opacity,1),`translate(${a} ${l}) rotate(${c}) scale(${e.flip_h?-1:1} ${e.flip_v?-1:1}) translate(${-a} ${-l})`]}function c_(e){const t=new Map,i=e?.assets;if(!Array.isArray(i))return t;for(const e of i){const i=e,n="image/png"===i.mime?"png":"image/jpeg"===i.mime?"jpg":"image/webp"===i.mime?"webp":"image/svg+xml"===i.mime?"svg":"",r=`/api/houseplan/content/assets/_/${i.asset_id}.${n}`;!o_.test(String(i.asset_id||""))||i.url!==r||"string"!=typeof i.name||!Number.isFinite(i.bytes)||Number(i.bytes)<1||!Number.isFinite(i.width)||!Number.isFinite(i.height)||Number(i.width)<=0||Number(i.height)<=0||t.set(i.asset_id,i)}return t}async function h_(e,t,i){const n=[...new Set(t.filter(e=>o_.test(e)))].sort(),r=e.connection||e,o=JSON.stringify([i,n]),s=s_.get(r);if(s?.[0]===o)return s[1];const a=new Map;for(let t=0;t0&&t>0?e/t:1;let n=100,r=n/i;return r>200&&(r=200,n=r*i),{w:n,h:r}}const u_=2,p_=e=>(...t)=>({_$litDirective$:e,values:t});let __=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:m_}=se,g_=e=>e,f_=()=>document.createComment(""),v_=(e,t,i)=>{const n=e._$AA.parentNode,r=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=n.insertBefore(f_(),r),o=n.insertBefore(f_(),r);i=new m_(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=g_(e).nextSibling;g_(n).insertBefore(e,r),e=t}}}return i},y_=(e,t,i=e)=>(e._$AI(t,i),e),b_={},w_=(e,t=b_)=>e._$AH=t,k_=e=>{e._$AR(),e._$AA.remove()},x_=(e,t,i)=>{const n=new Map;for(let r=t;r<=i;r++)n.set(e[r],r);return n},S_=p_(class extends __{constructor(e){if(super(e),e.type!==u_)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=(e=>e._$AH)(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]=y_(r[d],o[p]),d++,p++;else if(a[u]===s[_])l[_]=y_(r[u],o[_]),u--,_--;else if(a[d]===s[_])l[_]=y_(r[d],o[_]),v_(e,l[_+1],r[d]),d++,_--;else if(a[u]===s[p])l[p]=y_(r[u],o[p]),v_(e,r[d],r[u]),u--,p++;else if(void 0===c&&(c=x_(s,p,_),h=x_(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=v_(e,r[d]);y_(t,o[p]),l[p]=t}else l[p]=y_(i,o[p]),v_(e,r[d],i),r[t]=null;p++}else k_(r[u]),u--;else k_(r[d]),d++;for(;p<=_;){const t=v_(e,l[_+1]);y_(t,o[p]),l[p++]=t}for(;d<=u;){const e=r[d++];null!==e&&k_(e)}return this.ut=s,w_(e,l),U}}),$_=1e-5;function M_(e){const t=e.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(t[i].push(d),t[s].push(u))}}const i=[];for(let n=0;ne-t),1];for(let e=1;e{const i=t[2]-t[0],n=t[3]-t[1],r=i*i+n*n;if(!(r>0))return Math.hypot(e[0]-t[0],e[1]-t[1]);const o=Math.max(0,Math.min(1,((e[0]-t[0])*i+(e[1]-t[1])*n)/r));return Math.hypot(e[0]-(t[0]+o*i),e[1]-(t[1]+o*n))},T_=(e,t,i,n)=>{const r=n[2]-n[0],o=n[3]-n[1],s=t*o-i*r;if(Math.abs(s)<1e-12)return 1/0;const a=n[0]-e[0],l=n[1]-e[1],c=(a*o-l*r)/s;if(!(c>1e-9))return 1/0;const h=(a*i-l*t)/s;return h<-1e-9||h>1+1e-9?1/0:c};const D_=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]];function z_(){return{clipCache:new Map,geometryWarnings:new Set,featherUnits:null,renderedSources:new Map,lastAppearance:new Map,enteringSources:new Set,enterRafs:new Map,fadeTimers:new Map,featherSuspendUntil:0,featherResumeTimer:0,sourceSeq:0}}function A_(e,t){if(!e.clipCache.has(t))return{hit:!1,value:null};const i=e.clipCache.get(t)??null;return e.clipCache.delete(t),e.clipCache.set(t,i),{hit:!0,value:i}}function P_(e,t,i,n=256){for(e.clipCache.delete(t),e.clipCache.set(t,i);e.clipCache.size>n;){const t=e.clipCache.keys().next().value;if(void 0===t)break;e.clipCache.delete(t)}}function F_(e){const t=Kh(e.hass,e.devices,null,e.virtualLights).filter(t=>t.device.space===e.spaceId),i=new Map;for(const e of t){if(!e.device.id)continue;const t=i.get(e.device.id)||[];t.push(e),i.set(e.device.id,t)}const n=[];for(const t of e.devices){if(!t.id||t.space!==e.spaceId)continue;const r=Yh(i.get(t.id)||[]);if(!r)continue;const o=cn(r.passive?{state:r.on?"on":"off",attributes:{}}:e.hass.states[r.eid],t.marker?.glow_color,e.defaultColor),s=Number(t.marker?.glow_radius_cm),a=Number.isFinite(s)&&s>0?s/e.cellCm*e.gridPitch:e.defaultRadiusUnits;n.push({key:`${e.spaceId}|${t.id}`,sourceEid:r.eid,pos:e.position(t),radius:a,appearance:o?{c:o.c,alpha:hn(o.bri,e.paletteAlpha)}:null})}return n}function I_(e){const t=El([e.rawSpaceConfig,e.cellCm,e.gridPitch]),i=e.space.rooms.flatMap(e=>{const t=Nt(e);return t?[{room:e,poly:t}]:[]}),n=Math.max(10/e.cellCm*e.gridPitch,.5*e.gridPitch),r=e=>i.some(({poly:t})=>Zt(e,t)),o=e.openings.flatMap(t=>{if("door"!==(i=String(t.type))&&"gate"!==i&&"passage"!==i)return[];var i;const o=t.angle*Math.PI/180,s=-Math.sin(o),a=Math.cos(o);return r([t.rx+s*n,t.ry+a*n])&&r([t.rx-s*n,t.ry-a*n])?[{opening:t,amount:Vt(e.openingAmount(t))}]:[]});return{geometryFingerprint:t,fingerprint:El([t,o.map(({opening:e,amount:t})=>({id:e.id,type:e.type,contact:e.contact,amount:t})).filter(e=>!!e.contact&&("door"===e.type||"gate"===e.type)).map(e=>{const t=Math.max(0,Math.min(1,Number(e.amount)||0));return`${e.id}:${t.toFixed(3)}`}).sort().join("|")]),polygons:i,passageStates:o}}function O_(e){const{revision:t}=e,i=`${e.space.id}|${t.fingerprint}`,n=[...e.zeroWalls.transmissive],r=Up(t.passageStates.filter(({amount:e})=>e>0).map(({opening:e,amount:t})=>({...e,rlen:Gt(e.rlen,t)})),e.space,[...e.walls],e.zeroWalls.contour,e.wallKeyPitch,e.cellCm,e.gridPitch,e.coordScale);for(const e of r){const t=e.angle*Math.PI/180,i=Math.cos(t)*e.length/2,r=Math.sin(t)*e.length/2;n.push([e.x-i,e.y-r,e.x+i,e.y+r])}const o=t.passageStates.flatMap(({opening:e,amount:t})=>t>0&&e.partitionHost?[na(iu(e.partitionHost),t)]:[]),s=e.physicalBodies(o,i),a=[],l=e.sharedWallGeometry?.sourceFingerprint,c=(e.sharedWallGeometry&&l===t.geometryFingerprint?function(e,t=[],i=[],n={}){if("failed-core"===e.status||"not-applicable"===e.status)return null;const r=e.roomComponents?.length?e.roomComponents:ys(e.roomGeom)?[{id:"room-primary",geom:e.roomGeom}]:[];let o=r[0]?.geom||null;const s=r.slice(1).map(e=>({...e}));try{for(const i of t){if(!(i.length>0&&e.openingIndex))continue;const t=qs(e.openingIndex,i,!0);if(!t.negative&&!t.positive)continue;const n=i.angle*Math.PI/180,r=Math.cos(n),a=Math.sin(n),l=-a,c=r,h=i.length/2,d=e.openingPadUnits??1.25*Math.max(e.depthUnits,1),u=vs([[i.x-r*h-l*d,i.y-a*h-c*d],[i.x+r*h-l*d,i.y+a*h-c*d],[i.x+r*h+l*d,i.y+a*h+c*d],[i.x-r*h+l*d,i.y-a*h+c*d]]);o&&(o=Ct(o,u));for(const e of s)e.geom=Ct(e.geom,u)}const r=[...s];let a=s.length;const l=n.mergeExtra||((e,t)=>e?Mt(e,t):t);for(let e=0;ee.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]))||Math.abs(hi(t))<=1e-9){a++;continue}const n=[vs(t)];try{const t=l(o,n,e);if(!ys(t))throw new Error("invalid extra union");o=t}catch{a++,ys(n)&&r.push({id:`policy-extra-${e}`,geom:n})}}r.sort((e,t)=>Ds(e.geom).localeCompare(Ds(t.geom)));const c=o||[];return{status:a?"degraded-extra":"ok",geom:c,components:[...ys(c)?[{id:"primary",geom:c}]:[],...r.map((e,t)=>({...e,id:`isolated-${t}`}))]}}catch{return null}}(e.sharedWallGeometry,r,s):null)||(e.walls.length||s.length?Ps(e.space.rooms,[...e.walls],e.zeroWalls.contour,r,e.wallKeyPitch,e.cellCm,e.gridPitch,e.coordScale,s):null);if(!c||"ok"!==c.status&&"degraded-extra"!==c.status)for(const e of s)a.push(...R_(e));else for(const e of c.components)for(const t of pa(e.geom))a.push(...R_(t));const h=.02*e.gridPitch;for(const{poly:e}of t.polygons){const t=n.length?_n(e,n,h):R_(e);for(const e of t)a.push(e)}for(const t of e.zeroWalls.barriers)a.push(t);return{occluders:M_(a),floor:t.polygons.map(({poly:e})=>e),fingerprint:t.fingerprint,masonryGeometry:!c||"ok"!==c.status&&"degraded-extra"!==c.status?[]:c.components.flatMap(e=>e.geom),opaqueBodies:s}}function E_(e){const t=function(e,t,i,n=96){if(!(t>0&&Number.isFinite(e[0])&&Number.isFinite(e[1])))return[];const r=[];for(const n of i){if(!n||n.length<4)continue;if(![n[0],n[1],n[2],n[3]].every(Number.isFinite))continue;const i=C_(e,n);if(i<1e-7)return[];i>t||r.push(n)}const o=[],s=Math.max(12,Math.round(n));for(let e=0;ee-t);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const n=Math.cos(i),o=Math.sin(i);let s=t;for(const t of r){const i=T_(e,n,o,t);i=3?l:[]}([e.source.x,e.source.y],e.radius,e.scene.occluders,96);return{lit:t.length>=3?ha([t],e.scene.floor,{onBoundsFailure:({boundIndex:t,phase:i})=>{const n=e.polygons[t]?.room;e.onBoundsFailure?.(n?.id||`#${t}`,i)}}):[]}}function H_(e,t){return ga([e.x,e.y],t.masonryGeometry,t.opaqueBodies)}function N_(e,t){if(t.reducedMotion())return;const i=t.window();e.featherSuspendUntil=Math.max(e.featherSuspendUntil,Date.now()+500),i.clearTimeout(e.featherResumeTimer);const n=()=>{e.featherResumeTimer=0,Date.now(){e.enterRafs.get(i)===n&&(e.enterRafs.delete(i),e.enteringSources.delete(i),t.isConnected()&&t.requestUpdate())});e.enterRafs.set(i,n)}return{domId:o,entering:e.enteringSources.has(i),leaving:!1}}if(null==o)return null;const s=e.enterRafs.get(i);if(null!=s&&r.cancelAnimationFrame(s),e.enterRafs.delete(i),e.enteringSources.delete(i),!e.fadeTimers.has(i)){N_(e,t);const n=r.setTimeout(()=>{e.fadeTimers.get(i)===n&&(e.fadeTimers.delete(i),e.renderedSources.delete(i),e.lastAppearance.delete(i),t.isConnected()&&t.requestUpdate())},534);e.fadeTimers.set(i,n)}return{domId:o,entering:!1,leaving:!0}}function B_(e,t,i){const n=t.window(),r=e.fadeTimers.get(i),o=e.enterRafs.get(i);null!=r&&n.clearTimeout(r),null!=o&&n.cancelAnimationFrame(o),e.fadeTimers.delete(i),e.enterRafs.delete(i),e.enteringSources.delete(i),e.renderedSources.delete(i),e.lastAppearance.delete(i)}function q_(e,t,i){const n=`${i}|`;for(const i of[...e.renderedSources.keys()])i.startsWith(n)&&B_(e,t,i)}function j_(e,t,i,n){const r=`${i}|`;for(const i of[...e.renderedSources.keys()])i.startsWith(r)&&!n.has(i)&&B_(e,t,i)}function W_(e,t){const i=t.window();for(const t of e.fadeTimers.values())i.clearTimeout(t);for(const t of e.enterRafs.values())i.cancelAnimationFrame(t);i.clearTimeout(e.featherResumeTimer),e.clipCache.clear(),e.geometryWarnings.clear(),e.fadeTimers.clear(),e.enterRafs.clear(),e.enteringSources.clear(),e.renderedSources.clear(),e.lastAppearance.clear(),e.featherUnits=null,e.featherSuspendUntil=0,e.featherResumeTimer=0,e.sourceSeq=0}function U_(e,t,i,n,r){const o=`${t}|${i}|${n}`;if(!e.geometryWarnings.has(o)){if(e.geometryWarnings.size>=128){const t=e.geometryWarnings.values().next().value;t&&e.geometryWarnings.delete(t)}e.geometryWarnings.add(o),console.warn(`HOUSEPLAN GLOW GEOMETRY FALLBACK: #218, space ${t}, room ${n}, phase ${r}`)}}function V_(e,t,i){const n=1/(t>0?t:1),r=i&&Date.now()>=e.featherSuspendUntil;return(null==e.featherUnits||r)&&(e.featherUnits=n),{feather:e.featherUnits??n,enabled:r}}function G_(e){if(!e.spots.length)return W``;const t=4*e.feather,i=e.spots.reduce((e,i)=>({x:Math.min(e.x,i.pos.x-i.r-t),y:Math.min(e.y,i.pos.y-i.r-t),maxX:Math.max(e.maxX,i.pos.x+i.r+t),maxY:Math.max(e.maxY,i.pos.y+i.r+t),w:0,h:0}),{x:1/0,y:1/0,maxX:-1/0,maxY:-1/0,w:0,h:0});i.w=i.maxX-i.x,i.h=i.maxY-i.y;const n=e.enabledClip?.length?e.enabledClip:null;return W` - ${S_(e.spots,e=>e.key,e=>{const t=e.domId;return W` + `});return W``}function $p(e,t,i){const n=i>0?i:1;return{a:[e[0]/n,e[1]/n],b:[t[0]/n,t[1]/n]}}function Mp(e,t){const i=t>0?t:1;return[e.a[0]*i,e.a[1]*i,e.b[0]*i,e.b[1]*i]}function Rp(e){return Array.isArray(e)&&e.length>=2&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))}function Cp(e){if(!Array.isArray(e))return[];const t=[];for(const i of e){if(!i||"object"!=typeof i)continue;const e=i;if(!Rp(e.a)||!Rp(e.b))continue;const n=[Number(e.a[0]),Number(e.a[1])],r=[Number(e.b[0]),Number(e.b[1])];Math.hypot(r[0]-n[0],r[1]-n[1])<.001||t.push({a:n,b:r})}return t}function Tp(e,t,i,n,r=!0){const o=(e||[]).filter(e=>e?.id),s=Cp(t);if(s.length)return function(e,t,i,n){const r=Cp(e);if(!r.length)return[];const o=function(e,t){const i=[],n=(e||[]).filter(e=>e?.id);for(let e=0;e4*n||o>4*n)continue;const s=(e[0]-r)*u+(e[1]-l)*p,c=(e[2]-r)*u+(e[3]-l)*p,h=Math.max(0,Math.min(s,c)),m=Math.min(d,Math.max(s,c));if(m-he.lo-t.lo||e.hi-t.hi);const i=[];for(const e of t){const t=i[i.length-1];t&&e.lo<=t.hi+a?t.hi=Math.max(t.hi,e.hi):i.push({...e})}for(const t of i){const i=[r+u*t.lo,l+p*t.lo],n=[r+u*t.hi,l+p*t.hi];Math.hypot(n[0]-i[0],n[1]-i[1])i.pair===e&&Math.abs(i.ux*s-i.uy*o)<=1e-6&&Math.abs((t[0]-i.origin[0])*i.uy-(t[1]-i.origin[1])*i.ux)<=c&&Math.abs((t[2]-i.origin[0])*i.uy-(t[3]-i.origin[1])*i.ux)<=c);h||(h={pair:e,origin:[t[0],t[1]],ux:o,uy:s,ranges:[]},l.push(h));const d=(t[0]-h.origin[0])*h.ux+(t[1]-h.origin[1])*h.uy,u=(t[2]-h.origin[0])*h.ux+(t[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const e of l){e.ranges.sort((e,t)=>e.lo-t.lo||e.hi-t.hi);const t=[];for(const i of e.ranges){const e=t[t.length-1];e&&i.lo<=e.hi+a?e.hi=Math.max(e.hi,i.hi):t.push({...i})}for(const n of t){const t=[e.origin[0]+e.ux*n.lo,e.origin[1]+e.uy*n.lo],r=[e.origin[0]+e.ux*n.hi,e.origin[1]+e.uy*n.hi];Math.hypot(r[0]-t[0],r[1]-t[1])>=a&&h.push($p(t,r,i))}}return h}(s,e,i,n).map(e=>Mp(e,i));if(!r)return[];const a=[],l=(e,t)=>(e.open_to||[]).includes(t.id)||(t.open_to||[]).includes(e.id);for(let e=0;er)&&Co([o[0],o[1]],[o[2],o[3]],i))return!0;return!1}const zp=e=>Array.isArray(e)&&e.length>=2&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1])),Ap=(e,t,i)=>[Number(e[0])*i,Number(e[1])*i,Number(t[0])*i,Number(t[1])*i],Pp=e=>{const t=`${Number(e[0]).toFixed(9)},${Number(e[1]).toFixed(9)}`,i=`${Number(e[2]).toFixed(9)},${Number(e[3]).toFixed(9)}`;return t<=i?`${t}|${i}`:`${i}|${t}`},Fp=e=>{const t=new Map;for(const i of e.flat())!Array.isArray(i)||i.length<4||!i.every(Number.isFinite)||Math.hypot(i[2]-i[0],i[3]-i[1])<=1e-9||t.set(Pp(i),[...i]);return[...t.values()]};function Ip(e){return"solid"===e?.zero_wall_style?"solid":"dashed"}function Op(e,t=1,i){const n=[];for(const r of Array.isArray(e?.wall_segments)?e.wall_segments:[])0===Number(r?.cm)&&zp(r?.a)&&zp(r?.b)&&(i&&!i.has(String(r.id||""))||n.push(Ap(r.a,r.b,t)));return Fp([n])}function Ep(e,t=1){const i=[];for(const n of Array.isArray(e?.partitions)?e.partitions:[])0===Number(n?.cm)&&zp(n?.a)&&zp(n?.b)&&i.push(Ap(n.a,n.b,t));for(const n of Array.isArray(e?.room_drafts)?e.room_drafts:[]){const e=Array.isArray(n?.points)?n.points:[];for(let r=0;r+1e?.host?.kind===t.kind&&e.host.id===t.id)}function Bp(e){return e instanceof Error?e.name||"Error":typeof e}function qp(e){return El({id:e?.id??"",cell_cm:e?.cell_cm,rooms:e?.rooms||[],walls:e?.walls||[],wall_segments:e?.wall_segments||[],open_spans:e?.open_spans||[],openings:e?.openings||[],partitions:e?.partitions||[],room_drafts:e?.room_drafts||[],wall_columns:e?.wall_columns||[]})}function jp(e,t,i={}){const n=(Array.isArray(e?.spaces)?e.spaces:[]).find(e=>String(e?.id||"")===String(t||"")),r=qp(n);if(!n)return{spaceId:String(t||""),displayName:"",status:"failed",reason:"prepare-exception",fingerprint:r,ok:!1};const o=Yp({...e,spaces:[n]},{...i,fingerprint:()=>r}).spaces[0]||{spaceId:String(t||""),displayName:"",status:"failed",reason:"prepare-exception"};return{...o,fingerprint:r,ok:"failed"!==o.status}}function Wp(e,t,i,n=Fa,r=1e3){return(Array.isArray(e?.openings)?e.openings:[]).flatMap(e=>{const o={...e,rx:Number(e.x)*r,ry:Number(e.y)*r,rlen:Number(e.length)*r};if(!e.host||"wall"===e.host.kind)return[o];const s=Qd(e,t.partitions,r,i,n);return s.resolved?[{...e,rx:s.resolved.center[0],ry:s.resolved.center[1],rlen:s.resolved.length,angle:s.resolved.angle,partitionHost:s.resolved}]:[]})}function Up(e,t=()=>!0){return e.flatMap(e=>e.host&&e.partitionHost&&t(e)?[iu(e.partitionHost)]:[])}function Vp(e,t,i,n,r,o,s=Fa,a=1e3){const l=ds(t.rooms,[...i],n,r,o,s,a);return e.flatMap(e=>{const t={x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen};return e.host&&"wall"!==e.host.kind?e.partitionHost&&ou(e.partitionHost,l,2e-4*s)?[t]:[]:[t]})}function Gp(e,t){const i=Ia,n=Fa,r=Sa,o=Number.isFinite(Number(t.cellCm))&&Number(t.cellCm)>0?Number(t.cellCm):5,s=Array.isArray(e?.walls)?e.walls:[],a=function(e,t,i=Fa,n=1e3){return Tp(t.rooms,e?.open_spans,n,.02*i)}(e,t,n,r),l=function(e,t,i=Fa){if(!t.length)return[];const n=e.filter(e=>e?.id),r=.02*i,o=[];for(let e=0;e{const t=[(e[0]+e[2])/2,(e[1]+e[3])/2];return h.some(e=>Mn(t,e)<4*r)}).map(e=>[...e]);d.length&&o.push({a:s,b:a,segs:d})}return o}(t.rooms,a,n).flatMap(e=>e.segs),c=Wp(e,t,o,n,r),h=Up(c),d=sa(t,o,n,2e-4*n,h).all;return{space:t,walls:s,openCuts:l,openings:c,roomOpenings:Vp(c,t,s,l,i,o,n,r),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:n,coordScale:r}}function Kp(e,t,i){const n="string"==typeof e?.title?e.title.trim():"",r=null==e?.id?"":String(e.id).trim();return{spaceId:r,displayName:n||r||i(t+1)}}function Yp(e,t={}){const i=(t.fingerprint||El)(e),n=Array.isArray(e?.spaces)?e.spaces:[],r=t.fallbackSpaceName||(e=>`Space ${e}`),o=t.prepareSpace||Gp,s=t.wallPass||Ps,a=t.floorPass||Ts,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!u){l.push({...h,status:"not-applicable"});continue}let p=null;if(u){try{p=s(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(e){l.push({...h,status:"failed",reason:"wall-exception",detail:Bp(e)});continue}if(null==p){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===p.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===p.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}t.captureWallGeometry?.(d,p)}if(d.space.rooms.length&&null==p?.paperGeom){let e;try{e=a(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(e){l.push({...h,status:"failed",reason:"floor-exception",detail:Bp(e)});continue}if(null==e){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(e=>"failed"===e.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}const Xp=e=>"string"==typeof e&&e.length>0&&e.length<=500;function Zp(e){return Xp(e)&&(e.startsWith("device:")||e.startsWith("entity:"))&&e.indexOf(":")0||null===e.area&&"string"==typeof e.space&&e.space.length>0&&"string"==typeof e.room_id&&e.room_id.length>0)}(i)||i&&i.binding!==t?null:"entity"!==e.bindingKind||i?t:null}function t_(e,t){return e.rooms.filter(e=>{const i=function(e){if(Array.isArray(e.poly)&&e.poly.length>=3)return e.poly;const{x:t,y:i,w:n,h:r}=e;return![t,i,n,r].every(Number.isFinite)||Number(n)<=0||Number(r)<=0?null:[[t,i],[t+n,i],[t+n,i+r],[t,i+r]]}(e);return!!i&&ti(t,i)})}function i_(e,t){return{id:e,binding:null,area:null,relocate:!1,updateSnapshot:!1,removeSnapshot:!1,reason:t}}function n_(e){const t=e.indexOf(":");return[e.slice(0,t),e.slice(t+1)]}function r_(e){const t=[],i=new Set;if(!e.authoritative)return{decisions:t,relocateIds:i};const n=Jp(e.snapshot);for(const i of e.cleanupSnapshotIds||[])n[i]&&t.push({...i_(i,"registry-unverified"),removeSnapshot:!0});const r=Number.isFinite(e.coordinateScale)&&Number(e.coordinateScale)>0?Number(e.coordinateScale):1e3,o=new Map;for(const t of e.model)for(const e of t.rooms){if(!e.area)continue;const i=o.get(e.area)||[];i.push({space:t,room:e}),o.set(e.area,i)}for(const s of e.devices){const a=n[s.id],l=e_(s);if(!l){a&&t.push({...i_(s.id,"registry-unverified"),removeSnapshot:!0});continue}const c=Xp(s.area)?s.area:null;if(!c){t.push({id:s.id,binding:l,area:null,relocate:!1,updateSnapshot:!1,removeSnapshot:!1,reason:"registry-unverified"});continue}const h=o.get(c);if(!h||1!==h.length){t.push({id:s.id,binding:l,area:c,relocate:!1,updateSnapshot:!1,removeSnapshot:!1,reason:"target-unresolved"});continue}if(a?.binding===l){const e=a.area!==c;e&&i.add(s.id),t.push({id:s.id,binding:l,area:c,relocate:e,updateSnapshot:e,removeSnapshot:!1,reason:e?"area-changed":"unchanged"});continue}const d=e.layout[s.id];if(!d){t.push({id:s.id,binding:l,area:c,relocate:!1,updateSnapshot:!0,removeSnapshot:!1,reason:"new-without-layout"});continue}const[{space:u,room:p}]=h;if(d.s&&d.s!==u.id){i.add(s.id),t.push({id:s.id,binding:l,area:c,relocate:!0,updateSnapshot:!0,removeSnapshot:!1,reason:"backfill-cross-space"});continue}if(d.s!==u.id||!Number.isFinite(d.x)||!Number.isFinite(d.y)){t.push({id:s.id,binding:l,area:c,relocate:!1,updateSnapshot:!0,removeSnapshot:!1,reason:"backfill-ambiguous"});continue}const _=t_(u,[d.x*r,d.y*r]),m=1===_.length?_[0]:null,g=m===p||!!m?.id&&!!p.id&&m.id===p.id,f=!!m?.area&&m.area!==c,v=!g&&f;v&&i.add(s.id),t.push({id:s.id,binding:l,area:c,relocate:v,updateSnapshot:!0,removeSnapshot:!1,reason:v?"backfill-stale-room":g?"backfill-same-room":"backfill-ambiguous"})}return{decisions:t,relocateIds:i}}const o_=1,s_=/^[0-9a-f]{64}$/,a_=new WeakMap;function l_(e){const t=new Set;for(const i of e?.spaces||[])for(const e of i?.decor||[])"image"===e?.kind&&s_.test(e.asset_id)&&t.add(e.asset_id);return[...t]}function c_(e,t,i){const n=Number(e.x)*t,r=Number(e.y)*i,o=Number(e.w)*t,s=Number(e.h)*i;if(![n,r,o,s].every(Number.isFinite)||o<=0||s<=0)return null;const a=n+o/2,l=r+s/2,c=sr(e.angle);return[n,r,o,s,or(e.opacity,1),`translate(${a} ${l}) rotate(${c}) scale(${e.flip_h?-1:1} ${e.flip_v?-1:1}) translate(${-a} ${-l})`]}function h_(e){const t=new Map,i=e?.assets;if(!Array.isArray(i))return t;for(const e of i){const i=e,n="image/png"===i.mime?"png":"image/jpeg"===i.mime?"jpg":"image/webp"===i.mime?"webp":"image/svg+xml"===i.mime?"svg":"",r=`/api/houseplan/content/assets/_/${i.asset_id}.${n}`;!s_.test(String(i.asset_id||""))||i.url!==r||"string"!=typeof i.name||!Number.isFinite(i.bytes)||Number(i.bytes)<1||!Number.isFinite(i.width)||!Number.isFinite(i.height)||Number(i.width)<=0||Number(i.height)<=0||t.set(i.asset_id,i)}return t}async function d_(e,t,i){const n=[...new Set(t.filter(e=>s_.test(e)))].sort(),r=e.connection||e,o=JSON.stringify([i,n]),s=a_.get(r);if(s?.[0]===o)return s[1];const a=new Map;for(let t=0;t0&&t>0?e/t:1;let n=100,r=n/i;return r>200&&(r=200,n=r*i),{w:n,h:r}}const p_=2,__=e=>(...t)=>({_$litDirective$:e,values:t});let m_=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:g_}=se,f_=e=>e,v_=()=>document.createComment(""),y_=(e,t,i)=>{const n=e._$AA.parentNode,r=void 0===t?e._$AB:t._$AA;if(void 0===i){const t=n.insertBefore(v_(),r),o=n.insertBefore(v_(),r);i=new g_(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=f_(e).nextSibling;f_(n).insertBefore(e,r),e=t}}}return i},b_=(e,t,i=e)=>(e._$AI(t,i),e),w_={},k_=(e,t=w_)=>e._$AH=t,x_=e=>{e._$AR(),e._$AA.remove()},S_=(e,t,i)=>{const n=new Map;for(let r=t;r<=i;r++)n.set(e[r],r);return n},$_=__(class extends m_{constructor(e){if(super(e),e.type!==p_)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=(e=>e._$AH)(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]=b_(r[d],o[p]),d++,p++;else if(a[u]===s[_])l[_]=b_(r[u],o[_]),u--,_--;else if(a[d]===s[_])l[_]=b_(r[d],o[_]),y_(e,l[_+1],r[d]),d++,_--;else if(a[u]===s[p])l[p]=b_(r[u],o[p]),y_(e,r[d],r[u]),u--,p++;else if(void 0===c&&(c=S_(s,p,_),h=S_(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=y_(e,r[d]);b_(t,o[p]),l[p]=t}else l[p]=b_(i,o[p]),y_(e,r[d],i),r[t]=null;p++}else x_(r[u]),u--;else x_(r[d]),d++;for(;p<=_;){const t=y_(e,l[_+1]);b_(t,o[p]),l[p++]=t}for(;d<=u;){const e=r[d++];null!==e&&x_(e)}return this.ut=s,k_(e,l),U}}),M_=1e-5;function R_(e){const t=e.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(t[i].push(d),t[s].push(u))}}const i=[];for(let n=0;ne-t),1];for(let e=1;e{const i=t[2]-t[0],n=t[3]-t[1],r=i*i+n*n;if(!(r>0))return Math.hypot(e[0]-t[0],e[1]-t[1]);const o=Math.max(0,Math.min(1,((e[0]-t[0])*i+(e[1]-t[1])*n)/r));return Math.hypot(e[0]-(t[0]+o*i),e[1]-(t[1]+o*n))},D_=(e,t,i,n)=>{const r=n[2]-n[0],o=n[3]-n[1],s=t*o-i*r;if(Math.abs(s)<1e-12)return 1/0;const a=n[0]-e[0],l=n[1]-e[1],c=(a*o-l*r)/s;if(!(c>1e-9))return 1/0;const h=(a*i-l*t)/s;return h<-1e-9||h>1+1e-9?1/0:c};const z_=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]];function A_(){return{clipCache:new Map,geometryWarnings:new Set,featherUnits:null,renderedSources:new Map,lastAppearance:new Map,enteringSources:new Set,enterRafs:new Map,fadeTimers:new Map,featherSuspendUntil:0,featherResumeTimer:0,sourceSeq:0}}function P_(e,t){if(!e.clipCache.has(t))return{hit:!1,value:null};const i=e.clipCache.get(t)??null;return e.clipCache.delete(t),e.clipCache.set(t,i),{hit:!0,value:i}}function F_(e,t,i,n=256){for(e.clipCache.delete(t),e.clipCache.set(t,i);e.clipCache.size>n;){const t=e.clipCache.keys().next().value;if(void 0===t)break;e.clipCache.delete(t)}}function I_(e){const t=Kh(e.hass,e.devices,null,e.virtualLights).filter(t=>t.device.space===e.spaceId),i=new Map;for(const e of t){if(!e.device.id)continue;const t=i.get(e.device.id)||[];t.push(e),i.set(e.device.id,t)}const n=[];for(const t of e.devices){if(!t.id||t.space!==e.spaceId)continue;const r=Yh(i.get(t.id)||[]);if(!r)continue;const o=cn(r.passive?{state:r.on?"on":"off",attributes:{}}:e.hass.states[r.eid],t.marker?.glow_color,e.defaultColor),s=Number(t.marker?.glow_radius_cm),a=Number.isFinite(s)&&s>0?s/e.cellCm*e.gridPitch:e.defaultRadiusUnits;n.push({key:`${e.spaceId}|${t.id}`,sourceEid:r.eid,pos:e.position(t),radius:a,appearance:o?{c:o.c,alpha:hn(o.bri,e.paletteAlpha)}:null})}return n}function O_(e){const t=El([e.rawSpaceConfig,e.cellCm,e.gridPitch]),i=e.space.rooms.flatMap(e=>{const t=Nt(e);return t?[{room:e,poly:t}]:[]}),n=Math.max(10/e.cellCm*e.gridPitch,.5*e.gridPitch),r=e=>i.some(({poly:t})=>Zt(e,t)),o=e.openings.flatMap(t=>{if("door"!==(i=String(t.type))&&"gate"!==i&&"passage"!==i)return[];var i;const o=t.angle*Math.PI/180,s=-Math.sin(o),a=Math.cos(o);return r([t.rx+s*n,t.ry+a*n])&&r([t.rx-s*n,t.ry-a*n])?[{opening:t,amount:Vt(e.openingAmount(t))}]:[]});return{geometryFingerprint:t,fingerprint:El([t,o.map(({opening:e,amount:t})=>({id:e.id,type:e.type,contact:e.contact,amount:t})).filter(e=>!!e.contact&&("door"===e.type||"gate"===e.type)).map(e=>{const t=Math.max(0,Math.min(1,Number(e.amount)||0));return`${e.id}:${t.toFixed(3)}`}).sort().join("|")]),polygons:i,passageStates:o}}function E_(e){const{revision:t}=e,i=`${e.space.id}|${t.fingerprint}`,n=[...e.zeroWalls.transmissive],r=Vp(t.passageStates.filter(({amount:e})=>e>0).map(({opening:e,amount:t})=>({...e,rlen:Gt(e.rlen,t)})),e.space,[...e.walls],e.zeroWalls.contour,e.wallKeyPitch,e.cellCm,e.gridPitch,e.coordScale);for(const e of r){const t=e.angle*Math.PI/180,i=Math.cos(t)*e.length/2,r=Math.sin(t)*e.length/2;n.push([e.x-i,e.y-r,e.x+i,e.y+r])}const o=t.passageStates.flatMap(({opening:e,amount:t})=>t>0&&e.partitionHost?[na(iu(e.partitionHost),t)]:[]),s=e.physicalBodies(o,i),a=[],l=e.sharedWallGeometry?.sourceFingerprint,c=(e.sharedWallGeometry&&l===t.geometryFingerprint?function(e,t=[],i=[],n={}){if("failed-core"===e.status||"not-applicable"===e.status)return null;const r=e.roomComponents?.length?e.roomComponents:ys(e.roomGeom)?[{id:"room-primary",geom:e.roomGeom}]:[];let o=r[0]?.geom||null;const s=r.slice(1).map(e=>({...e}));try{for(const i of t){if(!(i.length>0&&e.openingIndex))continue;const t=qs(e.openingIndex,i,!0);if(!t.negative&&!t.positive)continue;const n=i.angle*Math.PI/180,r=Math.cos(n),a=Math.sin(n),l=-a,c=r,h=i.length/2,d=e.openingPadUnits??1.25*Math.max(e.depthUnits,1),u=vs([[i.x-r*h-l*d,i.y-a*h-c*d],[i.x+r*h-l*d,i.y+a*h-c*d],[i.x+r*h+l*d,i.y+a*h+c*d],[i.x-r*h+l*d,i.y-a*h+c*d]]);o&&(o=Ct(o,u));for(const e of s)e.geom=Ct(e.geom,u)}const r=[...s];let a=s.length;const l=n.mergeExtra||((e,t)=>e?Mt(e,t):t);for(let e=0;ee.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]))||Math.abs(hi(t))<=1e-9){a++;continue}const n=[vs(t)];try{const t=l(o,n,e);if(!ys(t))throw new Error("invalid extra union");o=t}catch{a++,ys(n)&&r.push({id:`policy-extra-${e}`,geom:n})}}r.sort((e,t)=>Ds(e.geom).localeCompare(Ds(t.geom)));const c=o||[];return{status:a?"degraded-extra":"ok",geom:c,components:[...ys(c)?[{id:"primary",geom:c}]:[],...r.map((e,t)=>({...e,id:`isolated-${t}`}))]}}catch{return null}}(e.sharedWallGeometry,r,s):null)||(e.walls.length||s.length?Ps(e.space.rooms,[...e.walls],e.zeroWalls.contour,r,e.wallKeyPitch,e.cellCm,e.gridPitch,e.coordScale,s):null);if(!c||"ok"!==c.status&&"degraded-extra"!==c.status)for(const e of s)a.push(...C_(e));else for(const e of c.components)for(const t of pa(e.geom))a.push(...C_(t));const h=.02*e.gridPitch;for(const{poly:e}of t.polygons){const t=n.length?_n(e,n,h):C_(e);for(const e of t)a.push(e)}for(const t of e.zeroWalls.barriers)a.push(t);return{occluders:R_(a),floor:t.polygons.map(({poly:e})=>e),fingerprint:t.fingerprint,masonryGeometry:!c||"ok"!==c.status&&"degraded-extra"!==c.status?[]:c.components.flatMap(e=>e.geom),opaqueBodies:s}}function H_(e){const t=function(e,t,i,n=96){if(!(t>0&&Number.isFinite(e[0])&&Number.isFinite(e[1])))return[];const r=[];for(const n of i){if(!n||n.length<4)continue;if(![n[0],n[1],n[2],n[3]].every(Number.isFinite))continue;const i=T_(e,n);if(i<1e-7)return[];i>t||r.push(n)}const o=[],s=Math.max(12,Math.round(n));for(let e=0;ee-t);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const n=Math.cos(i),o=Math.sin(i);let s=t;for(const t of r){const i=D_(e,n,o,t);i=3?l:[]}([e.source.x,e.source.y],e.radius,e.scene.occluders,96);return{lit:t.length>=3?ha([t],e.scene.floor,{onBoundsFailure:({boundIndex:t,phase:i})=>{const n=e.polygons[t]?.room;e.onBoundsFailure?.(n?.id||`#${t}`,i)}}):[]}}function N_(e,t){return ga([e.x,e.y],t.masonryGeometry,t.opaqueBodies)}function L_(e,t){if(t.reducedMotion())return;const i=t.window();e.featherSuspendUntil=Math.max(e.featherSuspendUntil,Date.now()+500),i.clearTimeout(e.featherResumeTimer);const n=()=>{e.featherResumeTimer=0,Date.now(){e.enterRafs.get(i)===n&&(e.enterRafs.delete(i),e.enteringSources.delete(i),t.isConnected()&&t.requestUpdate())});e.enterRafs.set(i,n)}return{domId:o,entering:e.enteringSources.has(i),leaving:!1}}if(null==o)return null;const s=e.enterRafs.get(i);if(null!=s&&r.cancelAnimationFrame(s),e.enterRafs.delete(i),e.enteringSources.delete(i),!e.fadeTimers.has(i)){L_(e,t);const n=r.setTimeout(()=>{e.fadeTimers.get(i)===n&&(e.fadeTimers.delete(i),e.renderedSources.delete(i),e.lastAppearance.delete(i),t.isConnected()&&t.requestUpdate())},534);e.fadeTimers.set(i,n)}return{domId:o,entering:!1,leaving:!0}}function q_(e,t,i){const n=t.window(),r=e.fadeTimers.get(i),o=e.enterRafs.get(i);null!=r&&n.clearTimeout(r),null!=o&&n.cancelAnimationFrame(o),e.fadeTimers.delete(i),e.enterRafs.delete(i),e.enteringSources.delete(i),e.renderedSources.delete(i),e.lastAppearance.delete(i)}function j_(e,t,i){const n=`${i}|`;for(const i of[...e.renderedSources.keys()])i.startsWith(n)&&q_(e,t,i)}function W_(e,t,i,n){const r=`${i}|`;for(const i of[...e.renderedSources.keys()])i.startsWith(r)&&!n.has(i)&&q_(e,t,i)}function U_(e,t){const i=t.window();for(const t of e.fadeTimers.values())i.clearTimeout(t);for(const t of e.enterRafs.values())i.cancelAnimationFrame(t);i.clearTimeout(e.featherResumeTimer),e.clipCache.clear(),e.geometryWarnings.clear(),e.fadeTimers.clear(),e.enterRafs.clear(),e.enteringSources.clear(),e.renderedSources.clear(),e.lastAppearance.clear(),e.featherUnits=null,e.featherSuspendUntil=0,e.featherResumeTimer=0,e.sourceSeq=0}function V_(e,t,i,n,r){const o=`${t}|${i}|${n}`;if(!e.geometryWarnings.has(o)){if(e.geometryWarnings.size>=128){const t=e.geometryWarnings.values().next().value;t&&e.geometryWarnings.delete(t)}e.geometryWarnings.add(o),console.warn(`HOUSEPLAN GLOW GEOMETRY FALLBACK: #218, space ${t}, room ${n}, phase ${r}`)}}function G_(e,t,i){const n=1/(t>0?t:1),r=i&&Date.now()>=e.featherSuspendUntil;return(null==e.featherUnits||r)&&(e.featherUnits=n),{feather:e.featherUnits??n,enabled:r}}function K_(e){if(!e.spots.length)return W``;const t=4*e.feather,i=e.spots.reduce((e,i)=>({x:Math.min(e.x,i.pos.x-i.r-t),y:Math.min(e.y,i.pos.y-i.r-t),maxX:Math.max(e.maxX,i.pos.x+i.r+t),maxY:Math.max(e.maxY,i.pos.y+i.r+t),w:0,h:0}),{x:1/0,y:1/0,maxX:-1/0,maxY:-1/0,w:0,h:0});i.w=i.maxX-i.x,i.h=i.maxY-i.y;const n=e.enabledClip?.length?e.enabledClip:null;return W` + ${$_(e.spots,e=>e.key,e=>{const t=e.domId;return W` - ${D_.map(([t,i])=>W` + ${z_.map(([t,i])=>W` `)} @@ -4781,7 +4781,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 data-blend=${e.screenBlend?"screen":"normal"} data-feather-px="${2}" clip-path=${n?"url(#hp-glow-enabled)":V}> - ${S_(e.spots,e=>e.key,e=>W` + ${$_(e.spots,e=>e.key,e=>W` Su(e.lang,t),iconRules:r})}function tm(e){const t=Da(e.cfg),i=t.find(t=>t.id===e.spaceId);if(!i)return null;const n=Vi(e.cfg.spaces.find(t=>t.id===e.spaceId)),r=Xi(e.cfg.settings),o=e.iconSize??2.5,s=o>8?2.5:o,a=kp(s),l=e.registry?vh(e.hass,e.registry):e.hass,c=e.registry?yh(e.hass,e.registry):e.hass,h=e.devices||em(e),d=e.areaRelocationIds||n_({devices:h,model:t,layout:e.layout,snapshot:e.cfg.settings?.marker_area_snapshot,authoritative:!0===e.registry?.authoritative,coordinateScale:Sa}).relocateIds,u=h.filter(t=>t.space===e.spaceId),p=u.filter(e=>!e.hidden),_=function(e,t,i){const n={},r=i/100*il(t)*1.3;for(const i of t.rooms){if(!i.area)continue;const t=e.filter(e=>e.area===i.area);if(!t.length)continue;const o=sl(i),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(t.length*a/Math.max(l,1)))),h=a/c,d=l/Math.max(Math.ceil(t.length/c),1),u=t.map((e,t)=>({x:o.x+s+h*(t%c+.5),y:o.y+s+d*(Math.floor(t/c)+.5)}));yi(u,o,r,.5*s),t.forEach((e,t)=>n[e.id]=Ea(u[t]))}return n}(u,i,s),m=ye(e.cfg.settings?.icon_rules?.length?e.cfg.settings.icon_rules:ve),g=bd(l,m,e.cfg.markers||[],yd(e.cfg.settings)),f=t=>{const n=t.settings?.temp_source;if(n)return md(l,n,"temp",e.cfg.markers||[]);const r=fd(i.id,t);return r?g.get(r)?.temp??null:null},v=[];for(const t of p){const i=e.layout[t.id];if(i&&i.s===e.spaceId){const e=i.x*Sa,t=i.y*Sa;v.push({minX:e,minY:t,maxX:e,maxY:t})}}const y=e.cfg.spaces.find(t=>t.id===e.spaceId)||{};if(!n.hideDecor)for(const t of y.decor||[]){if("image"!==t?.kind||!e.decorAssetUrl?.(String(t.asset_id||"")))continue;const i=Ga(t);i&&v.push(i)}const b=Array.isArray(y.walls)?y.walls:[],w=Number(y.cell_cm)>0?Number(y.cell_cm):5,k=Hp(y,i,Sa,.02*Fa),x=(y.openings||[]).flatMap(e=>{if("partition"!==e.host?.kind)return[];const t=Qd(e,i.partitions,Sa,w,Fa).resolved;return t?[t]:[]}),S=El({partitions:i.partitions,roomDrafts:i.room_drafts,columns:i.wall_columns,cellCm:w,hostedOpenings:x.map(e=>({id:e.opening.id,host:e.host,length:e.length,type:e.opening.type}))}),$=function(e,t,i,n){let r=Y_.get(e);r||(r=new Map,Y_.set(e,r));const o=r.get(t);if(o?.fingerprint===i)return o.value;const s=n();return r.set(t,{fingerprint:i,value:s}),s}(e.cfg,i.id,S,()=>sa(i,w,Fa,2e-4*Fa,x.map(iu)).all);for(const e of $){const t=e.map(e=>e[0]),i=e.map(e=>e[1]);t.length&&v.push({minX:Math.min(...t),minY:Math.min(...i),maxX:Math.max(...t),maxY:Math.max(...i)})}for(const e of k.lines)v.push({minX:Math.min(e[0],e[2]),minY:Math.min(e[1],e[3]),maxX:Math.max(e[0],e[2]),maxY:Math.max(e[1],e[3])});const M=function(e,t=1e3){const i=[];for(const[n,r]of(e||[]).entries()){if("passage"!==r?.type)continue;const e={...r,id:String(r.id||`passage-${n}`),type:"passage",rx:Number(r.x)*t,ry:Number(r.y)*t,rlen:Number(r.length)*t};[e.rx,e.ry,e.rlen,e.angle].every(Number.isFinite)&&e.rlen>0&&i.push(e)}return i}((y.openings||[]).flatMap(e=>{if(!e.host||"wall"===e.host.kind)return[e];const t=x.find(t=>t.opening.id===e.id);return t?[au(e,t,Sa)]:[]}),Sa),R=ds(i.rooms,b,k.contour,Ia,w,Fa,Sa),C=x.filter(e=>ou(e,R,2e-4*Fa)).map(e=>({x:e.center[0],y:e.center[1],angle:e.angle,length:e.length})),T=qa(e.fit),D=!!(b.length||$.length&&n.showBorders),z=D?El(M.length?{rooms:i.rooms,walls:b,extras:$,cellCm:w,zero:k.contour,passages:M.map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),hostedCompositeOpenings:C}:{rooms:i.rooms,walls:b,extras:$,cellCm:w,zero:k.contour}):"",A=D?function(e,t,i,n){let r=K_.get(e);r||(r=new Map,K_.set(e,r));const o=r.get(t);if(o?.fingerprint===i)return o.value;const s=n();return r.set(t,{fingerprint:i,value:s}),s}(e.cfg,i.id,z,()=>{const e=Fs(i.rooms,b,k.contour,[...M.filter(e=>"partition"!==e.host?.kind).map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),...C],Ia,w,Fa,Sa,$);return e&&Object.defineProperty(e,"sourceFingerprint",{value:El([y,w,Fa]),enumerable:!1}),e}):null;let P=el(i,v,e.compactTopFrame?{top:0,right:.05,bottom:.05,left:.05}:.05);if("house"===T){const e=[],t=ba(2.5,w)/2,r=ba(.6,w)/2;for(const n of i.rooms){const i=Va(n);i&&e.push(Ua(i,t))}if(n.showBorders)for(const t of A?.components||[]){const i=Wa(t.geom);i&&e.push(Ua(i,r))}if(n.showBorders)for(const t of $){const i=Wa(t);i&&e.push(Ua(i,r))}if(n.showBorders)for(const i of k.lines){const n={minX:Math.min(i[0],i[2]),minY:Math.min(i[1],i[3]),maxX:Math.max(i[0],i[2]),maxY:Math.max(i[1],i[3])};e.push(Ua(n,t))}if(!n.hideOpenings)for(const t of x){const i=t.opening,n="gate"===i.type?!i.flip_v:!!i.flip_v,r=zu({type:i.type,length:t.length,angle:t.angle,flipH:!!i.flip_h,flipV:!!i.flip_v,cellCm:w,gridPitch:Fa,face:nu(t,n)},t.center);r&&e.push(r)}P=Qa(e)||P}const F=[P.x,P.y,P.w,P.h],I=new Map(i.rooms.map(t=>{const i=yn(n.fill,t);return[t,Ji(i,"lqi"===i&&t.area?wd(l,u,t.area):null,"light"===i?Xh(Kh(l,u,t,e.virtualLights)):"none","temp"===i?f(t):null,n.tempMin,n.tempMax,r,Ui(n.customFill,t))]})),O=new Map;for(const e of i.rooms)e.id&&O.set(e.id,I.get(e)||null);const E=i.rooms.filter(e=>e.area||n.showBorders||"none"!==yn(n.fill,e)).map(e=>{let t="room "+(i.bg?"overlay":"yard"),r="";const o=yn(n.fill,e);if(n.showBorders||"none"!==o){t+=" styled";const i=[`--room-stroke:${n.color}`,`--room-stroke-op:${n.showBorders&&!k.contour.length?n.opacity:0}`],o=I.get(e)||null;o?(t+=" filled",i.push(`--room-fill:${o.color}`,`--room-fill-op:${o.opacity.toFixed(3)}`)):i.push("--room-fill:transparent","--room-fill-op:0"),r=i.join(";")}const s=e.id||V,a=e.area||V,l=e.poly?W``}const Y_=new WeakMap,X_=new WeakMap,Z_=new WeakMap,J_=new WeakMap;function Q_(e,t){const i=e.get(t);return void 0!==i&&(e.delete(t),e.set(t,i)),i}function em(e,t,i,n){for(e.delete(t),e.set(t,i);e.size>n;)e.delete(e.keys().next().value)}function tm(e){const t=Da(e.cfg),i={};for(const t of e.cfg.spaces||[])for(const e of t.rooms||[])e.area&&(i[e.area]=t.id);const n=yd(e.cfg.settings),r=ye(e.cfg.settings?.icon_rules?.length?e.cfg.settings.icon_rules:ve);return pd({hass:e.hass,registry:e.registry,areaToSpace:i,markers:e.cfg.markers||[],settings:e.cfg.settings||{},excluded:n,showAll:!!e.cfg.settings?.show_all,firstSpaceId:t[0]?.id||"",loc:t=>Su(e.lang,t),iconRules:r})}function im(e){const t=Da(e.cfg),i=t.find(t=>t.id===e.spaceId);if(!i)return null;const n=Vi(e.cfg.spaces.find(t=>t.id===e.spaceId)),r=Xi(e.cfg.settings),o=e.iconSize??2.5,s=o>8?2.5:o,a=xp(s),l=e.registry?vh(e.hass,e.registry):e.hass,c=e.registry?yh(e.hass,e.registry):e.hass,h=e.devices||tm(e),d=e.areaRelocationIds||r_({devices:h,model:t,layout:e.layout,snapshot:e.cfg.settings?.marker_area_snapshot,authoritative:!0===e.registry?.authoritative,coordinateScale:Sa}).relocateIds,u=h.filter(t=>t.space===e.spaceId),p=u.filter(e=>!e.hidden),_=function(e,t,i){const n={},r=i/100*il(t)*1.3;for(const i of t.rooms){if(!i.area)continue;const t=e.filter(e=>e.area===i.area);if(!t.length)continue;const o=sl(i),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(t.length*a/Math.max(l,1)))),h=a/c,d=l/Math.max(Math.ceil(t.length/c),1),u=t.map((e,t)=>({x:o.x+s+h*(t%c+.5),y:o.y+s+d*(Math.floor(t/c)+.5)}));yi(u,o,r,.5*s),t.forEach((e,t)=>n[e.id]=Ea(u[t]))}return n}(u,i,s),m=ye(e.cfg.settings?.icon_rules?.length?e.cfg.settings.icon_rules:ve),g=bd(l,m,e.cfg.markers||[],yd(e.cfg.settings)),f=t=>{const n=t.settings?.temp_source;if(n)return md(l,n,"temp",e.cfg.markers||[]);const r=fd(i.id,t);return r?g.get(r)?.temp??null:null},v=[];for(const t of p){const i=e.layout[t.id];if(i&&i.s===e.spaceId){const e=i.x*Sa,t=i.y*Sa;v.push({minX:e,minY:t,maxX:e,maxY:t})}}const y=e.cfg.spaces.find(t=>t.id===e.spaceId)||{};if(!n.hideDecor)for(const t of y.decor||[]){if("image"!==t?.kind||!e.decorAssetUrl?.(String(t.asset_id||"")))continue;const i=Ga(t);i&&v.push(i)}const b=Array.isArray(y.walls)?y.walls:[],w=Number(y.cell_cm)>0?Number(y.cell_cm):5,k=Np(y,i,Sa,.02*Fa),x=(y.openings||[]).flatMap(e=>{if("partition"!==e.host?.kind)return[];const t=Qd(e,i.partitions,Sa,w,Fa).resolved;return t?[t]:[]}),S=El({partitions:i.partitions,roomDrafts:i.room_drafts,columns:i.wall_columns,cellCm:w,hostedOpenings:x.map(e=>({id:e.opening.id,host:e.host,length:e.length,type:e.opening.type}))}),$=function(e,t,i,n){let r=X_.get(e);r||(r=new Map,X_.set(e,r));const o=r.get(t);if(o?.fingerprint===i)return o.value;const s=n();return r.set(t,{fingerprint:i,value:s}),s}(e.cfg,i.id,S,()=>sa(i,w,Fa,2e-4*Fa,x.map(iu)).all);for(const e of $){const t=e.map(e=>e[0]),i=e.map(e=>e[1]);t.length&&v.push({minX:Math.min(...t),minY:Math.min(...i),maxX:Math.max(...t),maxY:Math.max(...i)})}for(const e of k.lines)v.push({minX:Math.min(e[0],e[2]),minY:Math.min(e[1],e[3]),maxX:Math.max(e[0],e[2]),maxY:Math.max(e[1],e[3])});const M=function(e,t=1e3){const i=[];for(const[n,r]of(e||[]).entries()){if("passage"!==r?.type)continue;const e={...r,id:String(r.id||`passage-${n}`),type:"passage",rx:Number(r.x)*t,ry:Number(r.y)*t,rlen:Number(r.length)*t};[e.rx,e.ry,e.rlen,e.angle].every(Number.isFinite)&&e.rlen>0&&i.push(e)}return i}((y.openings||[]).flatMap(e=>{if(!e.host||"wall"===e.host.kind)return[e];const t=x.find(t=>t.opening.id===e.id);return t?[au(e,t,Sa)]:[]}),Sa),R=ds(i.rooms,b,k.contour,Ia,w,Fa,Sa),C=x.filter(e=>ou(e,R,2e-4*Fa)).map(e=>({x:e.center[0],y:e.center[1],angle:e.angle,length:e.length})),T=qa(e.fit),D=!!(b.length||$.length&&n.showBorders),z=D?El(M.length?{rooms:i.rooms,walls:b,extras:$,cellCm:w,zero:k.contour,passages:M.map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),hostedCompositeOpenings:C}:{rooms:i.rooms,walls:b,extras:$,cellCm:w,zero:k.contour}):"",A=D?function(e,t,i,n){let r=Y_.get(e);r||(r=new Map,Y_.set(e,r));const o=r.get(t);if(o?.fingerprint===i)return o.value;const s=n();return r.set(t,{fingerprint:i,value:s}),s}(e.cfg,i.id,z,()=>{const e=Fs(i.rooms,b,k.contour,[...M.filter(e=>"partition"!==e.host?.kind).map(e=>({x:e.rx,y:e.ry,angle:e.angle,length:e.rlen})),...C],Ia,w,Fa,Sa,$);return e&&Object.defineProperty(e,"sourceFingerprint",{value:El([y,w,Fa]),enumerable:!1}),e}):null;let P=el(i,v,e.compactTopFrame?{top:0,right:.05,bottom:.05,left:.05}:.05);if("house"===T){const e=[],t=ba(2.5,w)/2,r=ba(.6,w)/2;for(const n of i.rooms){const i=Va(n);i&&e.push(Ua(i,t))}if(n.showBorders)for(const t of A?.components||[]){const i=Wa(t.geom);i&&e.push(Ua(i,r))}if(n.showBorders)for(const t of $){const i=Wa(t);i&&e.push(Ua(i,r))}if(n.showBorders)for(const i of k.lines){const n={minX:Math.min(i[0],i[2]),minY:Math.min(i[1],i[3]),maxX:Math.max(i[0],i[2]),maxY:Math.max(i[1],i[3])};e.push(Ua(n,t))}if(!n.hideOpenings)for(const t of x){const i=t.opening,n="gate"===i.type?!i.flip_v:!!i.flip_v,r=Au({type:i.type,length:t.length,angle:t.angle,flipH:!!i.flip_h,flipV:!!i.flip_v,cellCm:w,gridPitch:Fa,face:nu(t,n)},t.center);r&&e.push(r)}P=Qa(e)||P}const F=[P.x,P.y,P.w,P.h],I=new Map(i.rooms.map(t=>{const i=yn(n.fill,t);return[t,Ji(i,"lqi"===i&&t.area?wd(l,u,t.area):null,"light"===i?Xh(Kh(l,u,t,e.virtualLights)):"none","temp"===i?f(t):null,n.tempMin,n.tempMax,r,Ui(n.customFill,t))]})),O=new Map;for(const e of i.rooms)e.id&&O.set(e.id,I.get(e)||null);const E=i.rooms.filter(e=>e.area||n.showBorders||"none"!==yn(n.fill,e)).map(e=>{let t="room "+(i.bg?"overlay":"yard"),r="";const o=yn(n.fill,e);if(n.showBorders||"none"!==o){t+=" styled";const i=[`--room-stroke:${n.color}`,`--room-stroke-op:${n.showBorders&&!k.contour.length?n.opacity:0}`],o=I.get(e)||null;o?(t+=" filled",i.push(`--room-fill:${o.color}`,`--room-fill-op:${o.opacity.toFixed(3)}`)):i.push("--room-fill:transparent","--room-fill-op:0"),r=i.join(";")}const s=e.id||V,a=e.area||V,l=e.poly?W``:W``;return l}),H=i.rooms.filter(e=>bn(n.glow,e)),N=H.filter(e=>{const t=I.get(e);return!t||t.opacity<=0}).map(e=>e.poly?W`
- `}let im=null,nm=null,rm=0,om=-1,sm=null,am=[];const lm=new Set,cm=(e,t)=>{"function"==typeof e&&t.push(e)};function hm(){if(im)return im;try{const e=JSON.parse(localStorage.getItem("houseplan_card_cfg_v1")||"null");if(e&&e.config&&Array.isArray(e.config.spaces)){const t=e.layout||{};return{config:e.config,rev:e.rev||0,decorAssetsApi:null,configFingerprint:e.config_fingerprint||El(e.config),layout:t,layoutRev:e.layout_rev||0,layoutFingerprint:e.layout_fingerprint||El(t),virtualLights:Yc(e.virtual_lights,e.rev||0)}}}catch{}return null}function dm(e,t=!1){if(t&&(im=null,rm++,nm))return nm.catch(()=>null).then(()=>dm(e,!1));if(im)return Promise.resolve(im);if(nm)return om!==rm?nm.catch(()=>null).then(()=>dm(e,!1)):nm;return om=rm,nm=async function(e,t){const[i,n]=await Promise.all([e.callWS({type:"houseplan/config/get"}),e.callWS({type:"houseplan/layout/get"})]),r=i?.rev??0,o=im?Xc(im.virtualLights,i?.virtual_lights,r,!!i&&"virtual_lights"in i):Yc(i?.virtual_lights,r),s={config:i?.config??null,rev:r,decorAssetsApi:1===i?.decor_assets_api?1:null,configFingerprint:El(i?.config??null),layout:n?.layout??{},layoutRev:n?.rev??0,layoutFingerprint:El(n?.layout??{}),virtualLights:o};t===rm&&(im=s);const a=e.connection;if(a?.subscribeEvents&&sm!==a){for(const e of am)e();am=[],sm=a;const e=()=>{im=null,rm++,lm.forEach(e=>e())},t=[];try{if(cm(await a.subscribeEvents(e,"houseplan_config_updated"),t),cm(await a.subscribeEvents(e,"houseplan_layout_updated"),t),cm(await a.subscribeEvents(e=>{if(im){const t=th(im.virtualLights,e?.data);if(t===im.virtualLights)return;im={...im,virtualLights:t}}else rm++;lm.forEach(e=>e())},"houseplan_virtual_light_updated"),t),sm===a)am=t;else for(const e of t)e()}catch{for(const e of t)e();sm===a&&(sm=null)}}return s}(e,rm).finally(()=>{nm=null,om=-1}),nm}const um=3300;function pm(e,t){return{sources:e,last:Object.fromEntries(t.map(e=>[e.eid,e.state])),flashTs:0,flashKind:null,timer:0,gen:0,expiresAt:0,alarmActive:"alarm"===Uc(t).status}}function _m(e,t,i,n){n(e.timer);const r=pm(t,i);Object.assign(e,r)}function mm(e,t,i,n,r){e.flashTs&&i-e.flashTs"transition"===e.activity)&&(i(e.timer),e.flashTs=0,e.flashKind=null,e.expiresAt=0);if("alarm"===Uc(t).status){e.alarmActive||(i(e.timer),e.flashTs=0,e.flashKind=null,e.expiresAt=0);for(const i of t)e.last[i.eid]=i.state;return e.alarmActive=!0,null}if(e.alarmActive){for(const i of t)e.last[i.eid]=i.state;return e.alarmActive=!1,null}let n=null;for(const i of t){const t=Vc(e.last[i.eid],i);("event"===t||!n&&t)&&(n=t),e.last[i.eid]=i.state}return n}class fm{constructor(e,t=()=>{}){this._host=e,this._onGateChange=t,this._modality="unknown",this._gate=!1,this._media=null,this._connected=!1,this._onMediaChange=()=>this._syncGate()}get modality(){return this._modality}get hoverEnabled(){return this._gate}connect(e=globalThis.window){this._connected||(this._connected=!0,this._modality="unknown",this._media="function"==typeof e?.matchMedia?e.matchMedia("(any-hover: hover) and (any-pointer: fine)"):null,this._media?.addEventListener?.("change",this._onMediaChange),this._setGate(!1))}disconnect(){this._media?.removeEventListener?.("change",this._onMediaChange),this._media=null,this._connected=!1,this._modality="unknown",this._setGate(!1)}note(e){return this._modality=function(e,t){const i="mouse"===(n=t.pointerType)||"touch"===n||"pen"===n?n:null;var n;return i?"mouse"===i&&t.sourceCapabilities?.firesTouchEvents?e:i:e}(this._modality,e),this._syncGate(),this._modality}suspend(){this._setGate(!1)}_syncGate(){var e,t;this._setGate((e=this._modality,t=!!this._media?.matches,"mouse"===e&&t))}_setGate(e){this._gate!==e&&(this._gate=e,this._host.toggleAttribute("data-pointer-hover",e),this._onGateChange(e))}}const vm=new WeakMap;const ym=(e,t,i)=>255===e[i+3]&&t.every((t,n)=>Math.abs(e[i+n]-t)<=2);async function bm(e){const t=e.defaultView;if(!t||!t.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],n=[16,64,128],r=[9,19,29],o=`\n \n \n \n \n \n `,s=t.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((e,i)=>{const n=new t.Image,r=t.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);n.onload=()=>{t.clearTimeout(r),e(n)},n.onerror=()=>{t.clearTimeout(r),i(new Error("SVG blend probe failed"))},n.src=s}),a=e.createElement("canvas");a.width=4,a.height=1;const l=a.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return ym(c,i,0)&&ym(c,function(e,t){return[0,1,2].map(i=>Math.round(255-(255-e[i])*(255-t[i])/255))}(i,n),4)&&ym(c,n,8)&&ym(c,r,12)}catch{return!1}finally{t.URL.revokeObjectURL(s)}}function wm(e){const t=vm.get(e);if(t)return t.promise;const i={promise:Promise.resolve(!1)};return i.promise=bm(e).catch(()=>!1).then(e=>(i.resolved=e,e)),vm.set(e,i),i.promise}function km(e){return vm.get(e)?.resolved}class xm extends he{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return xu(this.hass,this._config?.language)}get _schema(){const e=this._spaces||[];return[e.length?{name:"space",selector:{select:{mode:"dropdown",options:e}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"fit",selector:{select:{mode:"dropdown",options:[{value:"content",label:Su(this._lang,"editor.fit_content")},{value:"house",label:Su(this._lang,"editor.fit_house")}]}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"light_pools",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return V;const e=uu(this,fu,xu(this.hass,this._config.language));if("cold"===e)return pu();if("warm"===e)return U;this._loadSpaces();const t=this._lang,i={space:Su(t,"editor.space"),title:Su(t,"editor.title"),fit:Su(t,"editor.framing"),show_button:Su(t,"editor.show_button"),button_label:Su(t,"editor.button_label"),button_target:Su(t,"editor.button_target"),icon_size:Su(t,"editor.icon_size"),show_temperature:Su(t,"editor.show_temperature"),live_states:Su(t,"editor.live_states"),light_pools:Su(t,"editor.light_pools"),show_signal:Su(t,"editor.show_signal")};return j`{"function"==typeof e&&t.push(e)};function dm(){if(nm)return nm;try{const e=JSON.parse(localStorage.getItem("houseplan_card_cfg_v1")||"null");if(e&&e.config&&Array.isArray(e.config.spaces)){const t=e.layout||{};return{config:e.config,rev:e.rev||0,decorAssetsApi:null,configFingerprint:e.config_fingerprint||El(e.config),layout:t,layoutRev:e.layout_rev||0,layoutFingerprint:e.layout_fingerprint||El(t),virtualLights:Yc(e.virtual_lights,e.rev||0)}}}catch{}return null}function um(e,t=!1){if(t&&(nm=null,om++,rm))return rm.catch(()=>null).then(()=>um(e,!1));if(nm)return Promise.resolve(nm);if(rm)return sm!==om?rm.catch(()=>null).then(()=>um(e,!1)):rm;return sm=om,rm=async function(e,t){const[i,n]=await Promise.all([e.callWS({type:"houseplan/config/get"}),e.callWS({type:"houseplan/layout/get"})]),r=i?.rev??0,o=nm?Xc(nm.virtualLights,i?.virtual_lights,r,!!i&&"virtual_lights"in i):Yc(i?.virtual_lights,r),s={config:i?.config??null,rev:r,decorAssetsApi:1===i?.decor_assets_api?1:null,configFingerprint:El(i?.config??null),layout:n?.layout??{},layoutRev:n?.rev??0,layoutFingerprint:El(n?.layout??{}),virtualLights:o};t===om&&(nm=s);const a=e.connection;if(a?.subscribeEvents&&am!==a){for(const e of lm)e();lm=[],am=a;const e=()=>{nm=null,om++,cm.forEach(e=>e())},t=[];try{if(hm(await a.subscribeEvents(e,"houseplan_config_updated"),t),hm(await a.subscribeEvents(e,"houseplan_layout_updated"),t),hm(await a.subscribeEvents(e=>{if(nm){const t=th(nm.virtualLights,e?.data);if(t===nm.virtualLights)return;nm={...nm,virtualLights:t}}else om++;cm.forEach(e=>e())},"houseplan_virtual_light_updated"),t),am===a)lm=t;else for(const e of t)e()}catch{for(const e of t)e();am===a&&(am=null)}}return s}(e,om).finally(()=>{rm=null,sm=-1}),rm}const pm=3300;function _m(e,t){return{sources:e,last:Object.fromEntries(t.map(e=>[e.eid,e.state])),flashTs:0,flashKind:null,timer:0,gen:0,expiresAt:0,alarmActive:"alarm"===Uc(t).status}}function mm(e,t,i,n){n(e.timer);const r=_m(t,i);Object.assign(e,r)}function gm(e,t,i,n,r){e.flashTs&&i-e.flashTs"transition"===e.activity)&&(i(e.timer),e.flashTs=0,e.flashKind=null,e.expiresAt=0);if("alarm"===Uc(t).status){e.alarmActive||(i(e.timer),e.flashTs=0,e.flashKind=null,e.expiresAt=0);for(const i of t)e.last[i.eid]=i.state;return e.alarmActive=!0,null}if(e.alarmActive){for(const i of t)e.last[i.eid]=i.state;return e.alarmActive=!1,null}let n=null;for(const i of t){const t=Vc(e.last[i.eid],i);("event"===t||!n&&t)&&(n=t),e.last[i.eid]=i.state}return n}class vm{constructor(e,t=()=>{}){this._host=e,this._onGateChange=t,this._modality="unknown",this._gate=!1,this._media=null,this._connected=!1,this._onMediaChange=()=>this._syncGate()}get modality(){return this._modality}get hoverEnabled(){return this._gate}connect(e=globalThis.window){this._connected||(this._connected=!0,this._modality="unknown",this._media="function"==typeof e?.matchMedia?e.matchMedia("(any-hover: hover) and (any-pointer: fine)"):null,this._media?.addEventListener?.("change",this._onMediaChange),this._setGate(!1))}disconnect(){this._media?.removeEventListener?.("change",this._onMediaChange),this._media=null,this._connected=!1,this._modality="unknown",this._setGate(!1)}note(e){return this._modality=function(e,t){const i="mouse"===(n=t.pointerType)||"touch"===n||"pen"===n?n:null;var n;return i?"mouse"===i&&t.sourceCapabilities?.firesTouchEvents?e:i:e}(this._modality,e),this._syncGate(),this._modality}suspend(){this._setGate(!1)}_syncGate(){var e,t;this._setGate((e=this._modality,t=!!this._media?.matches,"mouse"===e&&t))}_setGate(e){this._gate!==e&&(this._gate=e,this._host.toggleAttribute("data-pointer-hover",e),this._onGateChange(e))}}const ym=new WeakMap;const bm=(e,t,i)=>255===e[i+3]&&t.every((t,n)=>Math.abs(e[i+n]-t)<=2);async function wm(e){const t=e.defaultView;if(!t||!t.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],n=[16,64,128],r=[9,19,29],o=`\n \n \n \n \n \n `,s=t.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((e,i)=>{const n=new t.Image,r=t.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);n.onload=()=>{t.clearTimeout(r),e(n)},n.onerror=()=>{t.clearTimeout(r),i(new Error("SVG blend probe failed"))},n.src=s}),a=e.createElement("canvas");a.width=4,a.height=1;const l=a.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return bm(c,i,0)&&bm(c,function(e,t){return[0,1,2].map(i=>Math.round(255-(255-e[i])*(255-t[i])/255))}(i,n),4)&&bm(c,n,8)&&bm(c,r,12)}catch{return!1}finally{t.URL.revokeObjectURL(s)}}function km(e){const t=ym.get(e);if(t)return t.promise;const i={promise:Promise.resolve(!1)};return i.promise=wm(e).catch(()=>!1).then(e=>(i.resolved=e,e)),ym.set(e,i),i.promise}function xm(e){return ym.get(e)?.resolved}class Sm extends he{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return xu(this.hass,this._config?.language)}get _schema(){const e=this._spaces||[];return[e.length?{name:"space",selector:{select:{mode:"dropdown",options:e}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"fit",selector:{select:{mode:"dropdown",options:[{value:"content",label:Su(this._lang,"editor.fit_content")},{value:"house",label:Su(this._lang,"editor.fit_house")}]}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"light_pools",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return V;const e=uu(this,fu,xu(this.hass,this._config.language));if("cold"===e)return pu();if("warm"===e)return U;this._loadSpaces();const t=this._lang,i={space:Su(t,"editor.space"),title:Su(t,"editor.title"),fit:Su(t,"editor.framing"),show_button:Su(t,"editor.show_button"),button_label:Su(t,"editor.button_label"),button_target:Su(t,"editor.button_target"),icon_size:Su(t,"editor.icon_size"),show_temperature:Su(t,"editor.show_temperature"),live_states:Su(t,"editor.live_states"),light_pools:Su(t,"editor.light_pools"),show_signal:Su(t,"editor.show_signal")};return j`i[e.name]||e.name} @value-changed=${this._valueChanged} - >`}_valueChanged(e){const t={...this._config||{},...e.detail.value};delete t.aspect_ratio;const i=new Event("config-changed",{bubbles:!0,composed:!0});i.detail={config:t},this.dispatchEvent(i)}}xm.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-space-card-editor")||customElements.define("houseplan-space-card-editor",xm);const Sm=e=>{history.pushState(null,"",e),((e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)})(window,"location-changed",{replace:!1})};class $m extends he{constructor(){super(...arguments),this._snap=null,this._loading=!1,this._reloadQueued=!1,this._forceReloadQueued=!1,this._reloadRetryTimer=0,this._dayCycleTimer=0,this._dayCycleClockKey="",this._stageWidth=0,this._pendingStageWidth=0,this._stageWidthRaf=0,this._haRegistryConnection=null,this._haRegistryRevision=-1,this._devices=[],this._areaRelocationIds=new Set,this._decorAssets=new Map,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._connHooked=null,this._connectionWasLost=!1,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotActivity="",this._capturedSnapshotVirtual="",this._activityRuntime=new Map,this._glowRuntimeState=z_(),this._glowRuntimeHost={window:()=>this.ownerDocument.defaultView||window,isConnected:()=>this.isConnected,requestUpdate:()=>this.requestUpdate(),reducedMotion:()=>this._reducedMotion},this._glowScreenBlend=!1,this._reducedMotion=!1,this._pointerModality=new fm(this),this._onMotionChange=e=>{this._reducedMotion=e.matches,this._capturedSnapshotSequence=-1,this.requestUpdate()},this._onHaRegistryUpdate=()=>{const e=_h(this.hass).revision;e!==this._haRegistryRevision&&(this._haRegistryRevision=e,this._refreshDevices(),this._capturedSnapshotSequence=-1,this.requestUpdate())},this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=qn(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),"hidden"!==e.kind){if(!e.long){const e=Date.now();let t=!1;for(const i of this._activityRuntime.values())!i.flashKind||(i.expiresAt||i.flashTs+3300)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&(this._capturedSnapshotSequence=-1,this.requestUpdate()))}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._load(!0)}else this._pointerModality.suspend()},this._onConnLost=()=>{this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost()},this._onConnReady=()=>{!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._load(!0)},this._onAssetLoaded=(e,t)=>{this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()},this._loadedOnce=!1,this._signer=new Ll(()=>this.requestUpdate()),this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._load(!0)},this._goToSpace=()=>{const e=(this._config?.button_target||"/plan-doma").replace(/#.*$/,"");Sm(`${e}#space=${encodeURIComponent(this._config.space)}`)}}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRevision=-1,this._haRegistryRelease=uh(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}_newContinuityController(){return new Ol(()=>{this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}_dayCycleState(e=new Date){const t=this._snap?.config;if(!t||!this._config)return null;const i=t.spaces?.find(e=>e.id===this._config?.space)?.settings||{};return"daynight"!==Jn(t.settings,i)?null:Bn(this._renderDeviceSnapshot?.hass||this.hass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?qn(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&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_dayCycleVisibility(e){"hidden"!==e.kind?(this._dayCycleTick(),this._syncDayCycleClock()):this._dayCycleTimer&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_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)}static getConfigElement(){return document.createElement("houseplan-space-card-editor")}static getStubConfig(e){const t=hm();return{type:"custom:houseplan-space-card",space:Da(t?.config||null)[0]?.id||"",show_button:!0,fit:"content",live_states:!0,show_temperature:!0,show_signal:!0,light_pools:!1}}setConfig(e){if(!e||!e.space)throw new Error('houseplan-space-card: "space" is required');this._config={show_button:!0,button_target:"/plan-doma",live_states:!0,show_temperature:!0,show_signal:!0,light_pools:!1,...e,fit:qa(e.fit)},!0!==this._config.light_pools?W_(this._glowRuntimeState,this._glowRuntimeHost):this.isConnected&&this._resolveGlowBlend(),this._snap=this._snap||hm()}connectedCallback(){var e;this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._resolveGlowBlend(),this.hass&&this._ensureHaRegistryAuthority(),this._continuityUnsub?.(),this._continuityUnsub=Fl(this.ownerDocument,this._pageVisibility),this._unsub=(e=()=>{this._beginContinuityCandidate("config-event",!1),this._reloadQueued=!0,this._load()},lm.add(e),()=>lm.delete(e)),this._signer.start(()=>this.hass,()=>this._referenced())}disconnectedCallback(){this._pointerModality.disconnect(),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._unsub?.(),this._unsub=void 0,window.clearTimeout(this._reloadRetryTimer),this._reloadRetryTimer=0,this._dayCycleTimer&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._stageObserver?.disconnect(),this._stageObserver=void 0,this._observedStage=void 0,this._stageWidthRaf&&cancelAnimationFrame(this._stageWidthRaf),this._stageWidthRaf=0,this._pendingStageWidth=0,this._signer.dispose(),this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null;for(const e of this._activityRuntime.values())window.clearTimeout(e.timer);this._activityRuntime.clear(),W_(this._glowRuntimeState,this._glowRuntimeHost),this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_resolveGlowBlend(){if(!this._config?.light_pools)return;const e=km(this.ownerDocument);void 0!==e&&(this._glowScreenBlend=e),wm(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())})}willUpdate(e){e.has("hass")&&this.hass&&(this._hassSequence++,this._renderSnapshotAt=Date.now(),this._continuity.note("hass-snapshot"),this._ensureHaRegistryAuthority(),this._hookConnection()),!this.hass||this._loading||this._snap&&!e.has("hass")||this._snap&&this._loadedOnce||this._load(),(e.has("hass")||e.has("_snap")||e.has("_config")||!this._devices.length)&&this._refreshDevices(),this._captureRenderDeviceSnapshot(),this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._frameFingerprint())}_stampActivity(e,t){mm(e,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivity(e,t,i=this.hass){if(!1===this._config?.live_states){for(const e of this._activityRuntime.values())window.clearTimeout(e.timer);return void this._activityRuntime.clear()}const n=new Set,r=Kh(t,e,null,this._snap?.virtualLights);for(const o of e){if(o.hidden)continue;if("icon_ripple"!==ki(o.marker?.display))continue;n.add(o.id);const s=ap(t,o,e,r,i),a=s.samples,l=hp(t,o,s);let c=this._activityRuntime.get(o.id);if(!c||c.sources!==l){c&&window.clearTimeout(c.timer),c=pm(l,a),this._activityRuntime.set(o.id,c);continue}const h=gm(c,a,window.clearTimeout.bind(window));h&&this._stampActivity(c,h)}for(const[e,t]of this._activityRuntime)n.has(e)||(window.clearTimeout(t.timer),this._activityRuntime.delete(e))}_refreshDevices(){if(!this.hass||!this._snap?.config||!this._config)return;const e=_h(this.hass),t=em({hass:this.hass,registry:e,cfg:this._snap.config,lang:this._lang});e.authoritative&&(this._areaRelocationIds=n_({devices:t,model:Da(this._snap.config),layout:this._snap.layout||{},snapshot:this._snap.config.settings?.marker_area_snapshot,authoritative:!0}).relocateIds),this._syncActivity(t,vh(this.hass,e),this.hass),this._devices=t}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRuntime.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+3300)>e?1:0)).join("|"),i=this._snap?.virtualLights?`${this._snap.virtualLights.configRev}:${this._snap.virtualLights.rev}`:"";if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotActivity===t&&this._capturedSnapshotVirtual===i)return;const n=vh(this.hass,_h(this.hass)),r=new Map,o=new Set(["sun.sun"]),s=new Set,a=new Set,l=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void o.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?s.add(n):"entity"===i&&o.add(n)},c=Da(this._snap?.config||null).find(e=>e.id===this._config?.space);for(const e of c?.rooms||[])e.area&&a.add(e.area),l(e.settings?.temp_source),l(e.settings?.hum_source);const h=this._snap?.config?.spaces?.find(e=>e.id===this._config?.space);for(const e of h?.openings||[])for(const t of Kt(e))o.add(t);const d=Kh(n,this._devices,null,this._snap?.virtualLights);for(const e of this._devices)for(const t of[!1,!0])r.set(gp(e.id,t),up(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRuntime.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:d,registryHass:this.hass,reducedMotion:this._reducedMotion}));const u=mp({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,entityIds:o,deviceIds:s,areaIds:a});this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotActivity=t,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=u:(this._visibleDeviceSnapshot=u,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}_beginContinuityCandidate(e,t,i="plan"){return this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._continuity.beginCandidate(e,i)}_backdropRaw(){return this._snap?.config&&this._config&&Da(this._snap.config).find(e=>e.id===this._config.space)?.bg?.href||""}_candidateBackdrop(e){return e&&this._config&&Da(e).find(e=>e.id===this._config.space)?.bg?.href||""}_assetsReady(){const e=this._backdropRaw();return!e||this._signer.isReady(this.hass,e)}_frameFingerprint(){const e=this._snap;return Hl([e?.rev||0,e?.configFingerprint||El(e?.config),e?.layoutRev||0,e?.layoutFingerprint||El(e?.layout),e?.virtualLights?`${e.virtualLights.configRev}:${e.virtualLights.rev}`:"",this._config?.space||"",!0===this._config?.light_pools,this._stageWidth,this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_stageValid(){const e=this._observedStage;return!!e&&e.clientWidth>0&&e.clientHeight>0}_settleContinuityFrame(){if(!this._stageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state){if(this._assetsReady())return this._renderSnapshotAt=Date.now(),void this._continuity.markCompleteFrame(this._frameFingerprint());this._beginContinuityCandidate("asset-wait",!0,"asset")}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._stageValid(),assetsReady:()=>this._assetsReady(),frameFingerprint:()=>this._frameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}updated(){const e=this.renderRoot.querySelector(".hp-static-stage")||void 0;if(e!==this._observedStage)if(this._stageObserver?.disconnect(),this._observedStage=e,e){const t=()=>{const i=e.clientWidth;if(!(i<=0||Math.abs(i-this._stageWidth)<=.5)){if(this._stageWidth<=0)return this._stageWidth=i,void this.requestUpdate();this._pendingStageWidth=i,this._stageWidthRaf||(this._stageWidthRaf=requestAnimationFrame(()=>{this._stageWidthRaf=0;const e=this._pendingStageWidth;this._pendingStageWidth=0,!e||!this._observedStage||this._observedStage.clientWidth<=0||(Math.abs(this._observedStage.clientWidth-e)>.5?t():Math.abs(e-this._stageWidth)<=.5||(this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._stageWidth=e,this.requestUpdate()))}))}};this._stageObserver=new ResizeObserver(t),this._stageObserver.observe(e),t()}else this._stageObserver=void 0;this._syncDayCycleClock(),this._settleContinuityFrame()}async _load(e=!1){if(this.hass){if(this._loading)return this._reloadQueued=!0,void(this._forceReloadQueued||=e);this._loading=!0,this._reloadQueued=!1;try{const t=await dm(this.hass,e),i=!this._snap||this._snap.configFingerprint!==t.configFingerprint,n=!this._snap||this._snap.layoutFingerprint!==t.layoutFingerprint,r=!this._snap||this._snap.virtualLights!==t.virtualLights,o=!this._snap||this._snap.decorAssetsApi!==t.decorAssetsApi;if(1!==t.decorAssetsApi&&(this._decorAssets=new Map),i&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t.config)))return this._continuity.note("asset-failed"),window.clearTimeout(this._reloadRetryTimer),void(this._reloadRetryTimer=window.setTimeout(()=>{this._load(!0)},1e3));if(window.clearTimeout(this._reloadRetryTimer),this._reloadRetryTimer=0,(i||n)&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),i||n||r||o?this._snap=t:this._snap&&(this._snap.rev=t.rev,this._snap.layoutRev=t.layoutRev),i&&this._continuity.note("config-candidate",{configRev:t.rev}),1===t.decorAssetsApi)try{this._decorAssets=await h_(this.hass,a_(t.config),t.rev)}catch{}n&&this._continuity.note("layout-candidate",{layoutRev:t.layoutRev}),r&&(this._capturedSnapshotSequence=-1),this._loadedOnce=!0,this._connectionWasLost=!1,this._continuityDataReady=!0,this._refreshDevices()}catch{}finally{if(this._loading=!1,this._continuityDataReady=!0,this.requestUpdate(),this._reloadQueued){const e=this._forceReloadQueued;this._reloadQueued=!1,this._forceReloadQueued=!1,this._load(e)}}}}get _lang(){return xu(this.hass,this._config?.language)}getCardSize(){const e=Da(this._snap?.config||null).find(e=>e.id===this._config?.space);if(e){const t=e.vb[3]/e.vb[2];return Math.max(3,Math.round(8*t))+(!1===this._config?.show_button?0:1)}return 6}_errorCard(e){return j``}_valueChanged(e){const t={...this._config||{},...e.detail.value};delete t.aspect_ratio;const i=new Event("config-changed",{bubbles:!0,composed:!0});i.detail={config:t},this.dispatchEvent(i)}}Sm.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-space-card-editor")||customElements.define("houseplan-space-card-editor",Sm);const $m=e=>{history.pushState(null,"",e),((e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)})(window,"location-changed",{replace:!1})};class Mm extends he{constructor(){super(...arguments),this._snap=null,this._loading=!1,this._reloadQueued=!1,this._forceReloadQueued=!1,this._reloadRetryTimer=0,this._dayCycleTimer=0,this._dayCycleClockKey="",this._stageWidth=0,this._pendingStageWidth=0,this._stageWidthRaf=0,this._haRegistryConnection=null,this._haRegistryRevision=-1,this._devices=[],this._areaRelocationIds=new Set,this._decorAssets=new Map,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._connHooked=null,this._connectionWasLost=!1,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotActivity="",this._capturedSnapshotVirtual="",this._activityRuntime=new Map,this._glowRuntimeState=A_(),this._glowRuntimeHost={window:()=>this.ownerDocument.defaultView||window,isConnected:()=>this.isConnected,requestUpdate:()=>this.requestUpdate(),reducedMotion:()=>this._reducedMotion},this._glowScreenBlend=!1,this._reducedMotion=!1,this._pointerModality=new vm(this),this._onMotionChange=e=>{this._reducedMotion=e.matches,this._capturedSnapshotSequence=-1,this.requestUpdate()},this._onHaRegistryUpdate=()=>{const e=_h(this.hass).revision;e!==this._haRegistryRevision&&(this._haRegistryRevision=e,this._refreshDevices(),this._capturedSnapshotSequence=-1,this.requestUpdate())},this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=qn(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._pageVisibility=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),"hidden"!==e.kind){if(!e.long){const e=Date.now();let t=!1;for(const i of this._activityRuntime.values())!i.flashKind||(i.expiresAt||i.flashTs+3300)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&(this._capturedSnapshotSequence=-1,this.requestUpdate()))}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._load(!0)}else this._pointerModality.suspend()},this._onConnLost=()=>{this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost()},this._onConnReady=()=>{!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._load(!0)},this._onAssetLoaded=(e,t)=>{this._signer.markLoaded(this.hass,e,t),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()},this._loadedOnce=!1,this._signer=new Ll(()=>this.requestUpdate()),this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._load(!0)},this._goToSpace=()=>{const e=(this._config?.button_target||"/plan-doma").replace(/#.*$/,"");$m(`${e}#space=${encodeURIComponent(this._config.space)}`)}}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRevision=-1,this._haRegistryRelease=uh(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}_newContinuityController(){return new Ol(()=>{this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}_dayCycleState(e=new Date){const t=this._snap?.config;if(!t||!this._config)return null;const i=t.spaces?.find(e=>e.id===this._config?.space)?.settings||{};return"daynight"!==Jn(t.settings,i)?null:Bn(this._renderDeviceSnapshot?.hass||this.hass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?qn(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&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_dayCycleVisibility(e){"hidden"!==e.kind?(this._dayCycleTick(),this._syncDayCycleClock()):this._dayCycleTimer&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0)}_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)}static getConfigElement(){return document.createElement("houseplan-space-card-editor")}static getStubConfig(e){const t=dm();return{type:"custom:houseplan-space-card",space:Da(t?.config||null)[0]?.id||"",show_button:!0,fit:"content",live_states:!0,show_temperature:!0,show_signal:!0,light_pools:!1}}setConfig(e){if(!e||!e.space)throw new Error('houseplan-space-card: "space" is required');this._config={show_button:!0,button_target:"/plan-doma",live_states:!0,show_temperature:!0,show_signal:!0,light_pools:!1,...e,fit:qa(e.fit)},!0!==this._config.light_pools?U_(this._glowRuntimeState,this._glowRuntimeHost):this.isConnected&&this._resolveGlowBlend(),this._snap=this._snap||dm()}connectedCallback(){var e;this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._resolveGlowBlend(),this.hass&&this._ensureHaRegistryAuthority(),this._continuityUnsub?.(),this._continuityUnsub=Fl(this.ownerDocument,this._pageVisibility),this._unsub=(e=()=>{this._beginContinuityCandidate("config-event",!1),this._reloadQueued=!0,this._load()},cm.add(e),()=>cm.delete(e)),this._signer.start(()=>this.hass,()=>this._referenced())}disconnectedCallback(){this._pointerModality.disconnect(),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._unsub?.(),this._unsub=void 0,window.clearTimeout(this._reloadRetryTimer),this._reloadRetryTimer=0,this._dayCycleTimer&&(window.clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._stageObserver?.disconnect(),this._stageObserver=void 0,this._observedStage=void 0,this._stageWidthRaf&&cancelAnimationFrame(this._stageWidthRaf),this._stageWidthRaf=0,this._pendingStageWidth=0,this._signer.dispose(),this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null;for(const e of this._activityRuntime.values())window.clearTimeout(e.timer);this._activityRuntime.clear(),U_(this._glowRuntimeState,this._glowRuntimeHost),this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_resolveGlowBlend(){if(!this._config?.light_pools)return;const e=xm(this.ownerDocument);void 0!==e&&(this._glowScreenBlend=e),km(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())})}willUpdate(e){e.has("hass")&&this.hass&&(this._hassSequence++,this._renderSnapshotAt=Date.now(),this._continuity.note("hass-snapshot"),this._ensureHaRegistryAuthority(),this._hookConnection()),!this.hass||this._loading||this._snap&&!e.has("hass")||this._snap&&this._loadedOnce||this._load(),(e.has("hass")||e.has("_snap")||e.has("_config")||!this._devices.length)&&this._refreshDevices(),this._captureRenderDeviceSnapshot(),this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._frameFingerprint())}_stampActivity(e,t){gm(e,t,Date.now(),window.clearTimeout.bind(window),e=>window.setTimeout(()=>this.requestUpdate(),e))}_syncActivity(e,t,i=this.hass){if(!1===this._config?.live_states){for(const e of this._activityRuntime.values())window.clearTimeout(e.timer);return void this._activityRuntime.clear()}const n=new Set,r=Kh(t,e,null,this._snap?.virtualLights);for(const o of e){if(o.hidden)continue;if("icon_ripple"!==ki(o.marker?.display))continue;n.add(o.id);const s=lp(t,o,e,r,i),a=s.samples,l=dp(t,o,s);let c=this._activityRuntime.get(o.id);if(!c||c.sources!==l){c&&window.clearTimeout(c.timer),c=_m(l,a),this._activityRuntime.set(o.id,c);continue}const h=fm(c,a,window.clearTimeout.bind(window));h&&this._stampActivity(c,h)}for(const[e,t]of this._activityRuntime)n.has(e)||(window.clearTimeout(t.timer),this._activityRuntime.delete(e))}_refreshDevices(){if(!this.hass||!this._snap?.config||!this._config)return;const e=_h(this.hass),t=tm({hass:this.hass,registry:e,cfg:this._snap.config,lang:this._lang});e.authoritative&&(this._areaRelocationIds=r_({devices:t,model:Da(this._snap.config),layout:this._snap.layout||{},snapshot:this._snap.config.settings?.marker_area_snapshot,authoritative:!0}).relocateIds),this._syncActivity(t,vh(this.hass,e),this.hass),this._devices=t}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRuntime.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+3300)>e?1:0)).join("|"),i=this._snap?.virtualLights?`${this._snap.virtualLights.configRev}:${this._snap.virtualLights.rev}`:"";if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotActivity===t&&this._capturedSnapshotVirtual===i)return;const n=vh(this.hass,_h(this.hass)),r=new Map,o=new Set(["sun.sun"]),s=new Set,a=new Set,l=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void o.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?s.add(n):"entity"===i&&o.add(n)},c=Da(this._snap?.config||null).find(e=>e.id===this._config?.space);for(const e of c?.rooms||[])e.area&&a.add(e.area),l(e.settings?.temp_source),l(e.settings?.hum_source);const h=this._snap?.config?.spaces?.find(e=>e.id===this._config?.space);for(const e of h?.openings||[])for(const t of Kt(e))o.add(t);const d=Kh(n,this._devices,null,this._snap?.virtualLights);for(const e of this._devices)for(const t of[!1,!0])r.set(fp(e.id,t),pp(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRuntime.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:d,registryHass:this.hass,reducedMotion:this._reducedMotion}));const u=gp({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,entityIds:o,deviceIds:s,areaIds:a});this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotActivity=t,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=u:(this._visibleDeviceSnapshot=u,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}_beginContinuityCandidate(e,t,i="plan"){return this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._continuity.beginCandidate(e,i)}_backdropRaw(){return this._snap?.config&&this._config&&Da(this._snap.config).find(e=>e.id===this._config.space)?.bg?.href||""}_candidateBackdrop(e){return e&&this._config&&Da(e).find(e=>e.id===this._config.space)?.bg?.href||""}_assetsReady(){const e=this._backdropRaw();return!e||this._signer.isReady(this.hass,e)}_frameFingerprint(){const e=this._snap;return Hl([e?.rev||0,e?.configFingerprint||El(e?.config),e?.layoutRev||0,e?.layoutFingerprint||El(e?.layout),e?.virtualLights?`${e.virtualLights.configRev}:${e.virtualLights.rev}`:"",this._config?.space||"",!0===this._config?.light_pools,this._stageWidth,this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_stageValid(){const e=this._observedStage;return!!e&&e.clientWidth>0&&e.clientHeight>0}_settleContinuityFrame(){if(!this._stageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state){if(this._assetsReady())return this._renderSnapshotAt=Date.now(),void this._continuity.markCompleteFrame(this._frameFingerprint());this._beginContinuityCandidate("asset-wait",!0,"asset")}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._stageValid(),assetsReady:()=>this._assetsReady(),frameFingerprint:()=>this._frameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}updated(){const e=this.renderRoot.querySelector(".hp-static-stage")||void 0;if(e!==this._observedStage)if(this._stageObserver?.disconnect(),this._observedStage=e,e){const t=()=>{const i=e.clientWidth;if(!(i<=0||Math.abs(i-this._stageWidth)<=.5)){if(this._stageWidth<=0)return this._stageWidth=i,void this.requestUpdate();this._pendingStageWidth=i,this._stageWidthRaf||(this._stageWidthRaf=requestAnimationFrame(()=>{this._stageWidthRaf=0;const e=this._pendingStageWidth;this._pendingStageWidth=0,!e||!this._observedStage||this._observedStage.clientWidth<=0||(Math.abs(this._observedStage.clientWidth-e)>.5?t():Math.abs(e-this._stageWidth)<=.5||(this._continuity.hasCompleteFrame&&this._beginContinuityCandidate("stage-resize",!0,"stage-size"),this._stageWidth=e,this.requestUpdate()))}))}};this._stageObserver=new ResizeObserver(t),this._stageObserver.observe(e),t()}else this._stageObserver=void 0;this._syncDayCycleClock(),this._settleContinuityFrame()}async _load(e=!1){if(this.hass){if(this._loading)return this._reloadQueued=!0,void(this._forceReloadQueued||=e);this._loading=!0,this._reloadQueued=!1;try{const t=await um(this.hass,e),i=!this._snap||this._snap.configFingerprint!==t.configFingerprint,n=!this._snap||this._snap.layoutFingerprint!==t.layoutFingerprint,r=!this._snap||this._snap.virtualLights!==t.virtualLights,o=!this._snap||this._snap.decorAssetsApi!==t.decorAssetsApi;if(1!==t.decorAssetsApi&&(this._decorAssets=new Map),i&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t.config)))return this._continuity.note("asset-failed"),window.clearTimeout(this._reloadRetryTimer),void(this._reloadRetryTimer=window.setTimeout(()=>{this._load(!0)},1e3));if(window.clearTimeout(this._reloadRetryTimer),this._reloadRetryTimer=0,(i||n)&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),i||n||r||o?this._snap=t:this._snap&&(this._snap.rev=t.rev,this._snap.layoutRev=t.layoutRev),i&&this._continuity.note("config-candidate",{configRev:t.rev}),1===t.decorAssetsApi)try{this._decorAssets=await d_(this.hass,l_(t.config),t.rev)}catch{}n&&this._continuity.note("layout-candidate",{layoutRev:t.layoutRev}),r&&(this._capturedSnapshotSequence=-1),this._loadedOnce=!0,this._connectionWasLost=!1,this._continuityDataReady=!0,this._refreshDevices()}catch{}finally{if(this._loading=!1,this._continuityDataReady=!0,this.requestUpdate(),this._reloadQueued){const e=this._forceReloadQueued;this._reloadQueued=!1,this._forceReloadQueued=!1,this._load(e)}}}}get _lang(){return xu(this.hass,this._config?.language)}getCardSize(){const e=Da(this._snap?.config||null).find(e=>e.id===this._config?.space);if(e){const t=e.vb[3]/e.vb[2];return Math.max(3,Math.round(8*t))+(!1===this._config?.show_button?0:1)}return 6}_errorCard(e){return j` ${Su(this._lang,e?"continuity.restore_connection":"continuity.restore_plan")} ${"recovery-error"===this._continuity.state?j``:V} - `}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}render(){if(!this._config||!this.hass)return V;const e=uu(this,fu,xu(this.hass,this._config.language));if("cold"===e)return pu();if("warm"===e)return U;const t=this._snap?.config;if(!t)return this._errorCard(Su(this._lang,"space_card.loading"));const i=this._config.space,n=Da(t).find(e=>e.id===i),r=void 0!==this._config.title?this._config.title:n?.title||"",o=this._renderDeviceSnapshot,s=tm({hass:o?.hass||this.hass,cfg:t,layout:this._snap?.layout||{},spaceId:i,iconSize:this._config.icon_size,fit:this._config.fit,compactTopFrame:""===this._config.title||null===this._config.title,stageWidth:this._stageWidth,lang:this._lang,displayUrl:e=>this._signer.display(this.hass,e),decorAssetUrl:e=>this._decorAssets.get(e)?.url||"",assetLoaded:this._onAssetLoaded,registry:o?{revision:o.sourceSequence,authoritative:!1,access:"limited",entities:{...o.hass.entities},devices:{...o.hass.devices},lastSuccess:o.capturedAt}:_h(this.hass),devices:[...o?.devices||this._devices],areaRelocationIds:this._areaRelocationIds,presentations:o?.presentations,activityRuntime:this._activityRuntime,reducedMotion:this._reducedMotion,virtualLights:this._snap?.virtualLights,lightPools:!0===this._config.light_pools,glowRuntime:{state:this._glowRuntimeState,host:this._glowRuntimeHost,screenBlend:this._glowScreenBlend},liveStates:!1!==this._config.live_states,showTemperature:!1!==this._config.show_temperature,showSignal:!1!==this._config.show_signal,inert:this._continuity.overlayBlocksInteraction});if(!s)return this._errorCard(Su(this._lang,"space_card.not_found",{id:i}));const a=!1!==this._config.show_button,l=this._config.button_label||Su(this._lang,"space_card.button"),c=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null;return j` + `}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}render(){if(!this._config||!this.hass)return V;const e=uu(this,fu,xu(this.hass,this._config.language));if("cold"===e)return pu();if("warm"===e)return U;const t=this._snap?.config;if(!t)return this._errorCard(Su(this._lang,"space_card.loading"));const i=this._config.space,n=Da(t).find(e=>e.id===i),r=void 0!==this._config.title?this._config.title:n?.title||"",o=this._renderDeviceSnapshot,s=im({hass:o?.hass||this.hass,cfg:t,layout:this._snap?.layout||{},spaceId:i,iconSize:this._config.icon_size,fit:this._config.fit,compactTopFrame:""===this._config.title||null===this._config.title,stageWidth:this._stageWidth,lang:this._lang,displayUrl:e=>this._signer.display(this.hass,e),decorAssetUrl:e=>this._decorAssets.get(e)?.url||"",assetLoaded:this._onAssetLoaded,registry:o?{revision:o.sourceSequence,authoritative:!1,access:"limited",entities:{...o.hass.entities},devices:{...o.hass.devices},lastSuccess:o.capturedAt}:_h(this.hass),devices:[...o?.devices||this._devices],areaRelocationIds:this._areaRelocationIds,presentations:o?.presentations,activityRuntime:this._activityRuntime,reducedMotion:this._reducedMotion,virtualLights:this._snap?.virtualLights,lightPools:!0===this._config.light_pools,glowRuntime:{state:this._glowRuntimeState,host:this._glowRuntimeHost,screenBlend:this._glowScreenBlend},liveStates:!1!==this._config.live_states,showTemperature:!1!==this._config.show_temperature,showSignal:!1!==this._config.show_signal,inert:this._continuity.overlayBlocksInteraction});if(!s)return this._errorCard(Su(this._lang,"space_card.not_found",{id:i}));const a=!1!==this._config.show_button,l=this._config.button_label||Su(this._lang,"space_card.button"),c=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null;return j` ${l} `:V} - `}}$m.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},$m.styles=[lu,o` + `}}Mm.properties={hass:{attribute:!1},_config:{state:!0},_snap:{state:!0},_continuityEpoch:{state:!0}},Mm.styles=[lu,o` .hp-static-title { font-weight: 700; padding: 10px 14px 6px; @@ -4989,7 +4989,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 text-align: center; color: var(--secondary-text-color, #9aa4ad); } - `],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",$m),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 Mm=o` + `],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",Mm),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 Rm=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); @@ -5160,7 +5160,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 .editor-secondary { transition: none; } .editor-group-launcher .group-chevron { transition: none; } } -`;function Rm(e,t){return e.catch(()=>{}).then(t)}function Cm(e,t,i,n,r){return{previous:JSON.parse(JSON.stringify(e)),previousFingerprint:i,revision:n,attempted:t,attemptedFingerprint:r(t)}}function Tm(e,t,i){const n=e._serverCfg;return!(!n||e._cfgRev!==t.revision||i(n)!==t.attemptedFingerprint)&&(e._serverCfg=t.previous,e._cfgContentFingerprint=t.previousFingerprint,e.requestUpdate(),!0)}class Dm{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 zm(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 Am(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 Pm="houseplan-card:version-reload-target:v1";function Fm(e){if("string"!=typeof e)return null;return e.trim()||null}class Im{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))}update(e){const t={frontendVersion:Fm(e.frontendVersion),backendVersion:Fm(e.backendVersion),kiosk:!0===e.kiosk,reducedMotion:!0===e.reducedMotion},i=function(e,t){const i=Fm(e),n=Fm(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(Pm)===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(Pm)===t?"attempted":(i.setItem(Pm,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()))}}function Om(e,t){const i=t&&"object"==typeof t?t:{};e._haIntegrationVersion=Fm(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._syncVersionRecovery()}function Em(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 Hm{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:xh(e),bindings:n},this.diagnosticsCache}}function Nm(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()}const Lm=Object.freeze({enabled:!1,z2mBaseTopics:Object.freeze([])});function Bm(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 qm(e){const t=e?.zigbee_topology;if(!t||"object"!=typeof t)return Lm;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=Bm(e);if(t&&!r.has(t)&&(r.add(t),o.push(t),8===o.length))break}return{enabled:!0===i.enabled,z2mBaseTopics:o}}function jm(e,t){const i={...e},n=t.z2mBaseTopics.map(Bm).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 Wm={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Um=e=>Math.max(0,Math.min(1,e)),Vm=(e,t,i)=>e+(t-e)*i,Gm=(e,t,i)=>{const n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},Km=e=>{const t=Um(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,Gm(r,.2,.2)0&&e.w>0?t/e.w:1,viewBox:{...e}}}function Xm(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 Zm(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 Jm(e,t,i){const n=Zm(e),r=Zm(t);if(!n||!r)return i<.5?e:t;const o=Um(i);return`rgba(${Math.round(Vm(n[0],r[0],o))}, ${Math.round(Vm(n[1],r[1],o))}, ${Math.round(Vm(n[2],r[2],o))}, ${Vm(n[3],r[3],o).toFixed(3)})`}class Qm{constructor(e,t=Wm){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=Um((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:function(e,t,i){const n=Km(i),r=Vm(e.stageWidth,t.stageWidth,n),o=Vm(e.stageHeight,t.stageHeight,n),s=Math.max(1e-9,e.viewport.pixelsPerUnit),a=Math.max(1e-9,t.viewport.pixelsPerUnit),l={centerX:Vm(e.viewport.centerX,t.viewport.centerX,n),centerY:Vm(e.viewport.centerY,t.viewport.centerY,n),pixelsPerUnit:Math.exp(Vm(Math.log(s),Math.log(a),n))};return{presentedMode:n<.5?e.presentedMode:t.presentedMode,editorChromeHeight:Vm(e.editorChromeHeight,t.editorChromeHeight,n),stageWidth:r,stageHeight:o,viewport:{...l,viewBox:Xm(l,r,o)},stageColor:Jm(e.stageColor,t.stageColor,n),paperColor:Jm(e.paperColor,t.paperColor,n),sceneBrightness:Vm(e.sceneBrightness,t.sceneBrightness,n),architectureOpacity:Vm(e.architectureOpacity,t.architectureOpacity,n),backdropOpacity:Vm(e.backdropOpacity,t.backdropOpacity,n),viewWeight:Vm(e.viewWeight,t.viewWeight,n),editorWeight:Vm(e.editorWeight,t.editorWeight,n),toolbarContentOpacity:Vm(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 eg={now:()=>"undefined"!=typeof performance?performance.now():Date.now(),requestFrame:e=>"function"==typeof requestAnimationFrame?requestAnimationFrame(e):null,cancelFrame:e=>{"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e)}},tg=e=>Number.isFinite(e);function ig(e){return!!e&&tg(e.zoom)&&e.zoom>0&&tg(e.viewBox.x)&&tg(e.viewBox.y)&&tg(e.viewBox.w)&&e.viewBox.w>0&&tg(e.viewBox.h)&&e.viewBox.h>0}function ng(e){return{zoom:e.zoom,viewBox:{...e.viewBox}}}function rg(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 og=(e,t,i)=>e+(t-e)*i,sg=(e,t,i)=>Math.exp(og(Math.log(e),Math.log(t),i));class ag{constructor(e,t=eg){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=ng(e),s=ng(t),a=n>0&&ig(o)&&ig(s),l=this._clock.now(),c={token:r,phase:a?"running":"settling",from:o,to:s,presented:ng(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?ng(t.to):function(e,t,i){if(!ig(e))return ng(t);if(!ig(t))return ng(e);const n=Km(i);if(n<=0)return ng(e);if(n>=1)return ng(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=sg(e.viewBox.w,t.viewBox.w,n),c=sg(e.viewBox.h,t.viewBox.h,n),h=og(r,s,n),d=og(o,a,n);return{zoom:sg(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=ng(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=ng(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=ng(t.to),this._hooks.settled(t),this._state?.token===e&&(this._state=null))}}const lg=Object.freeze({rotDeg:4,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])}),cg=64,hg=10,dg=4,ug=68;function pg(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 _g(e,t,i=lg){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,gg(t,i))}function mg(e,t=lg){if(!pg(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 gg(e=0,t=lg){if(!pg(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 fg(e=lg){return function(e=0,t=lg){return`matrix(${gg(e,t).map(e=>Number(e.toFixed(12))).join(" ")})`}(0,e)}function vg(e,t=lg){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=>[_g(e,-o,t),_g(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 yg=[".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(","),bg=(e,t)=>{try{return"function"==typeof e?.matches&&e.matches(t)}catch{return!1}};function wg(e){for(const t of e){const e=t;if(bg(e,".roomlabel[data-id]")){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(bg(e,yg))return{kind:"interactive"};if(bg(e,'[data-hp="room"][data-id]')){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(bg(e,".stage"))return{kind:"background"}}return{kind:"outside"}}function kg(e){const t=wg(e);return"room"===t.kind?t.roomId:null}class xg{constructor(){this.pointer=null,this.sequence=null}clear(){this.pointer=null,this.sequence=null}clearOutside(e){let t={kind:"outside"};try{t=wg(e.composedPath())}catch{}"outside"===t.kind&&this.clear()}pointerDown(e,t,i){let n={kind:"outside"};try{n=wg(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=wg(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 Sg=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function $g(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 Mg(e,t=0){if(!e.length||!Number.isFinite(t)||t<0||!e.every(Sg))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 Rg(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 Cg(e,t){return`${e("editor.load_failed")} ${e(t.terminal?"editor.refresh_advice":"editor.retry_advice")}`}class Tg extends Error{}class Dg{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 Tg(`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 Tg&&(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 zg=(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}},Ag=(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)}},Pg=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Fg=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`,Ig="houseplan_card_alpha_v1",Og=Object.freeze([Object.freeze({id:"iso",issue:89,summary:"Volumetric plan renderer"})]);function Eg(e){return/^[a-z][a-z0-9-]*$/.test(e.id)&&Number.isInteger(e.issue)&&e.issue>0&&!!e.summary.trim()}function Hg(e){const t=String(e||"").replace(/^#/,"");return new URLSearchParams(t)}function Ng(e){return Hg(e).get("space")||""}function Lg(e,t,i=Og){const n=function(e){const t=new Set;for(const i of e){if(!Eg(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(Hg(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:Ng(e.hash),persist:n&&o?l?"1":"0":void 0,knownUrlOperation:o}}let Bg={alpha:!1,active:Object.freeze([]),space:""},qg=!1,jg="";const Wg=new Set;function Ug(){if("undefined"==typeof window)return Bg;const e=Lg(window.location,function(){try{return window.localStorage.getItem(Ig)}catch{return null}}());void 0!==e.persist&&function(e){try{window.localStorage.setItem(Ig,e)}catch{}}(e.persist),Bg={alpha:e.alpha,active:e.active,space:e.space},window.__hpAlpha=e.alpha,window.__hpLabs=e.active;for(const e of Wg)e(Bg);return Bg}function Vg(){Ug()}function Gg(){if("undefined"==typeof window)return Bg;if(!qg){qg=!0,window.__hpLabsListenerCleanup?.(),window.addEventListener("hashchange",Vg),window.addEventListener("popstate",Vg);const e=()=>{window.removeEventListener("hashchange",Vg),window.removeEventListener("popstate",Vg),window.__hpLabsListenerCleanup===e&&delete window.__hpLabsListenerCleanup};window.__hpLabsListenerCleanup=e}return Ug()}const Kg={window:120,door:90,passage:90,gate:300};function Yg(e){return Kg[e]}function Xg(e,t){return{type:e,lengthCm:Yg(e),flipH:!1,flipV:!1,revision:t}}function Zg(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 Jg(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 Qg(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const n=Jg(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 ef(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 tf(e){const t=Qg(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=Jg(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(ef),n=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(ef);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 nf(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 rf(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}let of=0;const sf="1.72.0",af="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa",lf=1500,cf=new Map;let hf=0,df=1e4;const uf="houseplan_card_layout_v1",pf="houseplan_card_cfg_v1",_f="houseplan_card_zoom_v1",mf="houseplan_card_nav_v1",gf="houseplan_card_kiosk_v1",ff="houseplan_card_view_v1",vf="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",yf=1e3,bf=(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}},wf=(e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)},kf=e=>{history.pushState(null,"",e),wf(window,"location-changed",{replace:!1})},xf=(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},Sf=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}},$f=["edges","corners"];class Mf 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 Dg({expectedFingerprint:af,load:async e=>{const t=0===e?await import("./houseplan-editor-runtime-B8MzWgfl.js"):await import((()=>{const e=new URL("./houseplan-editor-runtime-B8MzWgfl.js",import.meta.url);return e.searchParams.set("hp_retry",`${sf}-${++of}`),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(Cg(e=>this._t(e),t))}}),this._onboardingRuntimeLoader=new Dg({expectedFingerprint:af,load:async e=>{const t=0===e?await import("./houseplan-onboarding-runtime-CQWdVdoD.js"):await import((()=>{const e=new URL("./houseplan-onboarding-runtime-CQWdVdoD.js",import.meta.url);return e.searchParams.set("hp_retry",`${sf}-${++of}`),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(Cg(e=>this._t(e),t))}}),this._isoSceneRuntime=null,this._isoSceneRuntimeLoader=new Dg({expectedFingerprint:af,load:async e=>{const t=0===e?await import("./iso-scene-render-BLVbTyKE.js"):await import((()=>{const e=new URL("./iso-scene-render-BLVbTyKE.js",import.meta.url);return e.searchParams.set("hp_retry",`${sf}-${++of}`),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",Rg("runtime-load","unverified",t.terminal)),this.isConnected&&this.requestUpdate()}}),this._space="f1",this._layout={},this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._serverCfg=null,this._cfgRev=0,this._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=Yc(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 fm(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...rr},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 Qm({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._cameraTransitionFit=null,this._cameraTransition=new ag({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 Dm(50),this._devicePositionHistory=new Dm(50),this._devicePositionBusy=!1,this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},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=z_(),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._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 xg,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._viewportGestureDirty=!1,this._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,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 ge(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 Im({clock:{setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e)},storage:()=>e.ownerDocument.defaultView?.sessionStorage??null,safety:()=>Em(e),reload:()=>e._reloadDocument(),changed:()=>{e.requestUpdate()}})),this._haSupportApi=null,this._haDecorAssetsApi=null,this._decorAssetSyncToken=0,this._alignDialog=null,this._settingsDialog=null,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=++hf,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._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),"hidden"===e.kind)return this._clearRoomFocus(!0),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._cancelCameraTransition(!0),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+um)>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._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),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 Hm,this._liveEditorPaintCount=0,this._onHaRegistryUpdate=()=>{const e=_h(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,ph(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 Ll(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=xf(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=Qr(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=xf(()=>{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._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>this._editorRuntimeOrThrow()._savePhysicalDialog(),this._deletePhysicalSelection=()=>this._editorRuntimeOrThrow()._deletePhysicalSelection(),this._confirmPartitionDelete=()=>this._editorRuntimeOrThrow()._confirmPartitionDelete(),this._deleteDraftWhole=()=>this._editorRuntimeOrThrow()._deleteDraftWhole(),this._deleteDraftSegment=()=>this._editorRuntimeOrThrow()._deleteDraftSegment(),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=qn(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._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,()=>Nm(this)))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)}_seedDecorStyle(e){if(this._decorStyleSeeded||!e)return;this._decorStyleSeeded=!0;const t=e.settings?.decor_default_style;t&&(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:or(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:or(i.fill_opacity,t.fillOpacity)}}(t,rr))}get _canEdit(){return!!this._norm&&(!0===this._serverCanWrite||!1!==this._serverCanWrite&&!0===this.hass?.user?.is_admin)}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||vi(this._baseVb(),this._stageAspect());return{zoom:Math.min(Mf.ZOOM_MAX,Math.max(Mf.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._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||!rg(o,e))&&(rg(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:Ym(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=vi(this._baseVb(),n/Math.max(1,r)),s=Math.min(Mf.ZOOM_MAX,Math.max(Mf.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._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"),a=s?.querySelector(".editorchrome-inner"),l="view"===i?0:a?.scrollHeight||a?.getBoundingClientRect().height||0,c=Math.max(1,t.stageHeight+t.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||t.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(n,r,o),void this.requestUpdate();const u=this._viewForModeTarget(n,r,o,d,h),p={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:Ym(u,d),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 _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,p,i,this._reducedMotion||_?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._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._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary?.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),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 rf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){rf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(Sf(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}_syncDangerConfirmLocaleGate(){return this._config&&this.hass?uu(this,fu,xu(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:sf,backendVersion:this._haIntegrationVersion,kiosk:!0===this._config?.kiosk,reducedMotion:this._reducedMotion})}_newContinuityController(){return new Ol(()=>{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(ff,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?mg(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?_g([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 Ng(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,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=km(this.ownerDocument);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=Fl(this.ownerDocument,this._pageVisibility),this._languageFailureUnsub?.(),this._languageFailureUnsub=(t=()=>{this._showToast(this._t("toast.locale_load_failed"))},gu.add(t),()=>gu.delete(t)),super.connectedCallback(),this._ensureLiveRuntime().catch(()=>this.requestUpdate()),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{for(const t of e)for(const e of t.addedNodes)this._syncPointerHoverSubtree(e)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._syncVersionRecovery(),this._versionRecovery.connect(),wm(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){Wg.add(e);const t=Gg();return"undefined"==typeof window&&e(t),()=>{Wg.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},lf)),!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._liveRt?.dispose(),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._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),W_(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._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,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._supportDialog)return void this._editorRuntime?._closeSupportDialog();if(this._settingsDialog)return void(this._settingsDialog=null);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._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():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){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const e=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const t=this._curSpaceCfg,i=(t.room_drafts||[]).findIndex(e=>e.id===this._activeDraftId);if(i>=0){const n=Array.isArray(t.room_drafts[i]?.segments)?t.room_drafts[i].segments:[];this._path.length<2?(t.room_drafts.splice(i,1),t.room_drafts.length||delete t.room_drafts,this._activeDraftId=null):t.room_drafts[i]={id:this._activeDraftId,points:this._path.map(e=>[e[0]/yf,e[1]/yf]),segments:this._draftSegmentCms.map((e,t)=>({...n[t]||{},cm:e}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),e)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const e=this._activeDraftId,t=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const n=e?this._spaceModel()?.room_drafts.find(t=>t.id===e):null;n?(this._activeDraftId=n.id,this._path=n.points.map(e=>[...e]),this._draftSegmentCms=this._adoptDraftCms(this._path,n.segments.map(e=>e.cm),n.id),this._resumeDraftBySpace[this._space]=n.id):(this._activeDraftId=null,this._path=t?[t]:[],this._draftSegmentCms=[],e&&this._resumeDraftBySpace[this._space]===e&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static async getConfigElement(){return await import("./editor-CpADL-Po.js"),document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of cf.values())for(const t of e)clearTimeout(t.evict);cf.clear(),df=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const n of cf.values())for(const r of n)e++,r.dlg&&(t++,i.push(r.dlg.kind));return{keys:cf.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(_f)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(ff)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}this._labs=Gg(),this.isConnected&&this._labsIso&&this._ensureIsoSceneRuntime();try{const e=JSON.parse(localStorage.getItem(gf)||"null");this._kioskScale={icon:kn(e?.icon),font:kn(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(pf)||"null");e&&e.config&&Array.isArray(e.config.spaces)&&(this._serverCfg=e.config,this._seedDecorStyle(this._serverCfg),this._cfgEpoch++,this._cfgRev=e.rev||0,this._cfgContentFingerprint=e.config_fingerprint||El(e.config),this._layout=e.layout||{},this._layoutRev=e.layout_rev||0,this._layoutContentFingerprint=e.layout_fingerprint||El(this._layout),this._virtualLights=Yc(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=Fg(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),n=cf.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>=zl,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>=zl,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},lf)),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=cf.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},df+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?_g([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&&Pg.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=Fg(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=cf.get(i)||[];for(n.push(this._warmSlot),cf.set(i,n),this._warmTrim(n);cf.size>8;){const e=cf.keys().next().value;if(void 0===e||e===i)break;for(const t of cf.get(e)||[])clearTimeout(t.evict);cf.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,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};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>df)&&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._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._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...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._cfgContentFingerprint=El(this._serverCfg),this._layoutContentFingerprint=El(this._layout),this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const n=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(Qc).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>n.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(pf,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:Zc(this._virtualLights)}))}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 Em(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=Da(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 Hl([this._cfgRev,this._cfgContentFingerprint||El(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||El(this._layout),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 V;const e="connection"===this._continuity.recoveryReason;return j`
{}).then(t)}function Tm(e,t,i,n,r){return{previous:JSON.parse(JSON.stringify(e)),previousFingerprint:i,revision:n,attempted:t,attemptedFingerprint:r(t)}}function Dm(e,t,i){const n=e._serverCfg;return!(!n||e._cfgRev!==t.revision||i(n)!==t.attemptedFingerprint)&&(e._serverCfg=t.previous,e._cfgContentFingerprint=t.previousFingerprint,e.requestUpdate(),!0)}class zm{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 Am(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 Pm(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 Fm="houseplan-card:version-reload-target:v1";function Im(e){if("string"!=typeof e)return null;return e.trim()||null}class Om{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))}update(e){const t={frontendVersion:Im(e.frontendVersion),backendVersion:Im(e.backendVersion),kiosk:!0===e.kiosk,reducedMotion:!0===e.reducedMotion},i=function(e,t){const i=Im(e),n=Im(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(Fm)===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(Fm)===t?"attempted":(i.setItem(Fm,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()))}}function Em(e,t){const i=t&&"object"==typeof t?t:{};e._haIntegrationVersion=Im(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._syncVersionRecovery()}function Hm(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 Nm{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:xh(e),bindings:n},this.diagnosticsCache}}function Lm(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()}const Bm=Object.freeze({enabled:!1,z2mBaseTopics:Object.freeze([])});function qm(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 jm(e){const t=e?.zigbee_topology;if(!t||"object"!=typeof t)return Bm;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=qm(e);if(t&&!r.has(t)&&(r.add(t),o.push(t),8===o.length))break}return{enabled:!0===i.enabled,z2mBaseTopics:o}}function Wm(e,t){const i={...e},n=t.z2mBaseTopics.map(qm).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 Um={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Vm=e=>Math.max(0,Math.min(1,e)),Gm=(e,t,i)=>e+(t-e)*i,Km=(e,t,i)=>{const n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},Ym=e=>{const t=Vm(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,Km(r,.2,.2)0&&e.w>0?t/e.w:1,viewBox:{...e}}}function Zm(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 Jm(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 Qm(e,t,i){const n=Jm(e),r=Jm(t);if(!n||!r)return i<.5?e:t;const o=Vm(i);return`rgba(${Math.round(Gm(n[0],r[0],o))}, ${Math.round(Gm(n[1],r[1],o))}, ${Math.round(Gm(n[2],r[2],o))}, ${Gm(n[3],r[3],o).toFixed(3)})`}class eg{constructor(e,t=Um){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=Vm((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:function(e,t,i){const n=Ym(i),r=Gm(e.stageWidth,t.stageWidth,n),o=Gm(e.stageHeight,t.stageHeight,n),s=Math.max(1e-9,e.viewport.pixelsPerUnit),a=Math.max(1e-9,t.viewport.pixelsPerUnit),l={centerX:Gm(e.viewport.centerX,t.viewport.centerX,n),centerY:Gm(e.viewport.centerY,t.viewport.centerY,n),pixelsPerUnit:Math.exp(Gm(Math.log(s),Math.log(a),n))};return{presentedMode:n<.5?e.presentedMode:t.presentedMode,editorChromeHeight:Gm(e.editorChromeHeight,t.editorChromeHeight,n),stageWidth:r,stageHeight:o,viewport:{...l,viewBox:Zm(l,r,o)},stageColor:Qm(e.stageColor,t.stageColor,n),paperColor:Qm(e.paperColor,t.paperColor,n),sceneBrightness:Gm(e.sceneBrightness,t.sceneBrightness,n),architectureOpacity:Gm(e.architectureOpacity,t.architectureOpacity,n),backdropOpacity:Gm(e.backdropOpacity,t.backdropOpacity,n),viewWeight:Gm(e.viewWeight,t.viewWeight,n),editorWeight:Gm(e.editorWeight,t.editorWeight,n),toolbarContentOpacity:Gm(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 tg={now:()=>"undefined"!=typeof performance?performance.now():Date.now(),requestFrame:e=>"function"==typeof requestAnimationFrame?requestAnimationFrame(e):null,cancelFrame:e=>{"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e)}},ig=e=>Number.isFinite(e);function ng(e){return!!e&&ig(e.zoom)&&e.zoom>0&&ig(e.viewBox.x)&&ig(e.viewBox.y)&&ig(e.viewBox.w)&&e.viewBox.w>0&&ig(e.viewBox.h)&&e.viewBox.h>0}function rg(e){return{zoom:e.zoom,viewBox:{...e.viewBox}}}function og(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 sg=(e,t,i)=>e+(t-e)*i,ag=(e,t,i)=>Math.exp(sg(Math.log(e),Math.log(t),i));class lg{constructor(e,t=tg){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=rg(e),s=rg(t),a=n>0&&ng(o)&&ng(s),l=this._clock.now(),c={token:r,phase:a?"running":"settling",from:o,to:s,presented:rg(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?rg(t.to):function(e,t,i){if(!ng(e))return rg(t);if(!ng(t))return rg(e);const n=Ym(i);if(n<=0)return rg(e);if(n>=1)return rg(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=ag(e.viewBox.w,t.viewBox.w,n),c=ag(e.viewBox.h,t.viewBox.h,n),h=sg(r,s,n),d=sg(o,a,n);return{zoom:ag(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=rg(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=rg(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=rg(t.to),this._hooks.settled(t),this._state?.token===e&&(this._state=null))}}const cg=Object.freeze({rotDeg:4,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])}),hg=64,dg=10,ug=4,pg=68;function _g(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 mg(e,t,i=cg){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,fg(t,i))}function gg(e,t=cg){if(!_g(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 fg(e=0,t=cg){if(!_g(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 vg(e=cg){return function(e=0,t=cg){return`matrix(${fg(e,t).map(e=>Number(e.toFixed(12))).join(" ")})`}(0,e)}function yg(e,t=cg){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=>[mg(e,-o,t),mg(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 bg=[".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(","),wg=(e,t)=>{try{return"function"==typeof e?.matches&&e.matches(t)}catch{return!1}};function kg(e){for(const t of e){const e=t;if(wg(e,".roomlabel[data-id]")){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(wg(e,bg))return{kind:"interactive"};if(wg(e,'[data-hp="room"][data-id]')){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(wg(e,".stage"))return{kind:"background"}}return{kind:"outside"}}function xg(e){const t=kg(e);return"room"===t.kind?t.roomId:null}class Sg{constructor(){this.pointer=null,this.sequence=null}clear(){this.pointer=null,this.sequence=null}clearOutside(e){let t={kind:"outside"};try{t=kg(e.composedPath())}catch{}"outside"===t.kind&&this.clear()}pointerDown(e,t,i){let n={kind:"outside"};try{n=kg(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=kg(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 $g=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function Mg(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 Rg(e,t=0){if(!e.length||!Number.isFinite(t)||t<0||!e.every($g))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 Cg(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 Tg(e,t){return`${e("editor.load_failed")} ${e(t.terminal?"editor.refresh_advice":"editor.retry_advice")}`}class Dg extends Error{}class zg{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 Dg(`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 Dg&&(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 Ag=(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}},Pg=(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)}},Fg=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Ig=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`,Og="houseplan_card_alpha_v1",Eg=Object.freeze([Object.freeze({id:"iso",issue:89,summary:"Volumetric plan renderer"})]);function Hg(e){return/^[a-z][a-z0-9-]*$/.test(e.id)&&Number.isInteger(e.issue)&&e.issue>0&&!!e.summary.trim()}function Ng(e){const t=String(e||"").replace(/^#/,"");return new URLSearchParams(t)}function Lg(e){return Ng(e).get("space")||""}function Bg(e,t,i=Eg){const n=function(e){const t=new Set;for(const i of e){if(!Hg(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(Ng(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:Lg(e.hash),persist:n&&o?l?"1":"0":void 0,knownUrlOperation:o}}let qg={alpha:!1,active:Object.freeze([]),space:""},jg=!1,Wg="";const Ug=new Set;function Vg(){if("undefined"==typeof window)return qg;const e=Bg(window.location,function(){try{return window.localStorage.getItem(Og)}catch{return null}}());void 0!==e.persist&&function(e){try{window.localStorage.setItem(Og,e)}catch{}}(e.persist),qg={alpha:e.alpha,active:e.active,space:e.space},window.__hpAlpha=e.alpha,window.__hpLabs=e.active;for(const e of Ug)e(qg);return qg}function Gg(){Vg()}function Kg(){if("undefined"==typeof window)return qg;if(!jg){jg=!0,window.__hpLabsListenerCleanup?.(),window.addEventListener("hashchange",Gg),window.addEventListener("popstate",Gg);const e=()=>{window.removeEventListener("hashchange",Gg),window.removeEventListener("popstate",Gg),window.__hpLabsListenerCleanup===e&&delete window.__hpLabsListenerCleanup};window.__hpLabsListenerCleanup=e}return Vg()}const Yg={window:120,door:90,passage:90,gate:300};function Xg(e){return Yg[e]}function Zg(e,t){return{type:e,lengthCm:Xg(e),flipH:!1,flipV:!1,revision:t}}function Jg(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 Qg(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 ef(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const n=Qg(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 tf(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 nf(e){const t=ef(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=Qg(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(tf),n=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(tf);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 rf(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 of(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}let sf=0;const af="1.72.0",lf="ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d",cf=1500,hf=new Map;let df=0,uf=1e4;const pf="houseplan_card_layout_v1",_f="houseplan_card_cfg_v1",mf="houseplan_card_zoom_v1",gf="houseplan_card_nav_v1",ff="houseplan_card_kiosk_v1",vf="houseplan_card_view_v1",yf="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",bf=1e3,wf=(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}},kf=(e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)},xf=e=>{history.pushState(null,"",e),kf(window,"location-changed",{replace:!1})},Sf=(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},$f=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}},Mf=["edges","corners"];class Rf 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 zg({expectedFingerprint:lf,load:async e=>{const t=0===e?await import("./houseplan-editor-runtime-BQxfLmCJ.js"):await import((()=>{const e=new URL("./houseplan-editor-runtime-BQxfLmCJ.js",import.meta.url);return e.searchParams.set("hp_retry",`${af}-${++sf}`),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(Tg(e=>this._t(e),t))}}),this._onboardingRuntimeLoader=new zg({expectedFingerprint:lf,load:async e=>{const t=0===e?await import("./houseplan-onboarding-runtime-BkPkAgsT.js"):await import((()=>{const e=new URL("./houseplan-onboarding-runtime-BkPkAgsT.js",import.meta.url);return e.searchParams.set("hp_retry",`${af}-${++sf}`),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(Tg(e=>this._t(e),t))}}),this._isoSceneRuntime=null,this._isoSceneRuntimeLoader=new zg({expectedFingerprint:lf,load:async e=>{const t=0===e?await import("./iso-scene-render-BacpVxOg.js"):await import((()=>{const e=new URL("./iso-scene-render-BacpVxOg.js",import.meta.url);return e.searchParams.set("hp_retry",`${af}-${++sf}`),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",Cg("runtime-load","unverified",t.terminal)),this.isConnected&&this.requestUpdate()}}),this._space="f1",this._layout={},this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._serverCfg=null,this._cfgRev=0,this._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=Yc(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 vm(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...rr},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 eg({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._cameraTransitionFit=null,this._cameraTransition=new lg({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 zm(50),this._devicePositionHistory=new zm(50),this._devicePositionBusy=!1,this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},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=A_(),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._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 Sg,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._viewportGestureDirty=!1,this._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,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 ge(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 Om({clock:{setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e)},storage:()=>e.ownerDocument.defaultView?.sessionStorage??null,safety:()=>Hm(e),reload:()=>e._reloadDocument(),changed:()=>{e.requestUpdate()}})),this._haSupportApi=null,this._haDecorAssetsApi=null,this._decorAssetSyncToken=0,this._alignDialog=null,this._settingsDialog=null,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=++df,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._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),"hidden"===e.kind)return this._clearRoomFocus(!0),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._cancelCameraTransition(!0),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+pm)>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._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),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 Nm,this._liveEditorPaintCount=0,this._onHaRegistryUpdate=()=>{const e=_h(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,ph(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 Ll(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=Sf(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=Qr(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=Sf(()=>{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._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>this._editorRuntimeOrThrow()._savePhysicalDialog(),this._deletePhysicalSelection=()=>this._editorRuntimeOrThrow()._deletePhysicalSelection(),this._confirmPartitionDelete=()=>this._editorRuntimeOrThrow()._confirmPartitionDelete(),this._deleteDraftWhole=()=>this._editorRuntimeOrThrow()._deleteDraftWhole(),this._deleteDraftSegment=()=>this._editorRuntimeOrThrow()._deleteDraftSegment(),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=qn(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._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,()=>Lm(this)))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)}_seedDecorStyle(e){if(this._decorStyleSeeded||!e)return;this._decorStyleSeeded=!0;const t=e.settings?.decor_default_style;t&&(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:or(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:or(i.fill_opacity,t.fillOpacity)}}(t,rr))}get _canEdit(){return!!this._norm&&(!0===this._serverCanWrite||!1!==this._serverCanWrite&&!0===this.hass?.user?.is_admin)}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||vi(this._baseVb(),this._stageAspect());return{zoom:Math.min(Rf.ZOOM_MAX,Math.max(Rf.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._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||!og(o,e))&&(og(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:Xm(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=vi(this._baseVb(),n/Math.max(1,r)),s=Math.min(Rf.ZOOM_MAX,Math.max(Rf.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._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"),a=s?.querySelector(".editorchrome-inner"),l="view"===i?0:a?.scrollHeight||a?.getBoundingClientRect().height||0,c=Math.max(1,t.stageHeight+t.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||t.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(n,r,o),void this.requestUpdate();const u=this._viewForModeTarget(n,r,o,d,h),p={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:Xm(u,d),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 _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,p,i,this._reducedMotion||_?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._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._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary?.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),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 of({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){of({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&($f(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}_syncDangerConfirmLocaleGate(){return this._config&&this.hass?uu(this,fu,xu(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:af,backendVersion:this._haIntegrationVersion,kiosk:!0===this._config?.kiosk,reducedMotion:this._reducedMotion})}_newContinuityController(){return new Ol(()=>{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(vf,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?gg(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?mg([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 Lg(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,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=xm(this.ownerDocument);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=Fl(this.ownerDocument,this._pageVisibility),this._languageFailureUnsub?.(),this._languageFailureUnsub=(t=()=>{this._showToast(this._t("toast.locale_load_failed"))},gu.add(t),()=>gu.delete(t)),super.connectedCallback(),this._ensureLiveRuntime().catch(()=>this.requestUpdate()),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{for(const t of e)for(const e of t.addedNodes)this._syncPointerHoverSubtree(e)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._syncVersionRecovery(),this._versionRecovery.connect(),km(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){Ug.add(e);const t=Kg();return"undefined"==typeof window&&e(t),()=>{Ug.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},cf)),!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._liveRt?.dispose(),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._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),U_(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._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,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._supportDialog)return void this._editorRuntime?._closeSupportDialog();if(this._settingsDialog)return void(this._settingsDialog=null);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._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():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){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const e=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const t=this._curSpaceCfg,i=(t.room_drafts||[]).findIndex(e=>e.id===this._activeDraftId);if(i>=0){const n=Array.isArray(t.room_drafts[i]?.segments)?t.room_drafts[i].segments:[];this._path.length<2?(t.room_drafts.splice(i,1),t.room_drafts.length||delete t.room_drafts,this._activeDraftId=null):t.room_drafts[i]={id:this._activeDraftId,points:this._path.map(e=>[e[0]/bf,e[1]/bf]),segments:this._draftSegmentCms.map((e,t)=>({...n[t]||{},cm:e}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),e)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const e=this._activeDraftId,t=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const n=e?this._spaceModel()?.room_drafts.find(t=>t.id===e):null;n?(this._activeDraftId=n.id,this._path=n.points.map(e=>[...e]),this._draftSegmentCms=this._adoptDraftCms(this._path,n.segments.map(e=>e.cm),n.id),this._resumeDraftBySpace[this._space]=n.id):(this._activeDraftId=null,this._path=t?[t]:[],this._draftSegmentCms=[],e&&this._resumeDraftBySpace[this._space]===e&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static async getConfigElement(){return await import("./editor-B9JBe9YT.js"),document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of hf.values())for(const t of e)clearTimeout(t.evict);hf.clear(),uf=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const n of hf.values())for(const r of n)e++,r.dlg&&(t++,i.push(r.dlg.kind));return{keys:hf.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(mf)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(vf)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}this._labs=Kg(),this.isConnected&&this._labsIso&&this._ensureIsoSceneRuntime();try{const e=JSON.parse(localStorage.getItem(ff)||"null");this._kioskScale={icon:kn(e?.icon),font:kn(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(_f)||"null");e&&e.config&&Array.isArray(e.config.spaces)&&(this._serverCfg=e.config,this._seedDecorStyle(this._serverCfg),this._cfgEpoch++,this._cfgRev=e.rev||0,this._cfgContentFingerprint=e.config_fingerprint||El(e.config),this._layout=e.layout||{},this._layoutRev=e.layout_rev||0,this._layoutContentFingerprint=e.layout_fingerprint||El(this._layout),this._virtualLights=Yc(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=Ig(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),n=hf.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>=zl,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>=zl,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},cf)),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=hf.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},uf+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?mg([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&&Fg.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=Ig(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=hf.get(i)||[];for(n.push(this._warmSlot),hf.set(i,n),this._warmTrim(n);hf.size>8;){const e=hf.keys().next().value;if(void 0===e||e===i)break;for(const t of hf.get(e)||[])clearTimeout(t.evict);hf.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,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};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>uf)&&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._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._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...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._cfgContentFingerprint=El(this._serverCfg),this._layoutContentFingerprint=El(this._layout),this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const n=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(Qc).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>n.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(_f,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:Zc(this._virtualLights)}))}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 Hm(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=Da(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 Hl([this._cfgRev,this._cfgContentFingerprint||El(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||El(this._layout),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 V;const e="connection"===this._continuity.recoveryReason;return j`
e.stopPropagation()} @click=${e=>e.stopPropagation()} @@ -5190,7 +5190,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 aria-label=${this._t("editor.loading_aria")}> ${this._t("editor.loading")} -
`:V}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}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 Da(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?Bl(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return Bl(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._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._resumeDraftBySpace={},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=dd({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=ye(e)),this._rulesCompiled}get _fillColors(){return Xi(this._settings)}get _excluded(){return yd(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,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,()=>Nm(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>this._refitView()),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=this.renderRoot.querySelector("ha-card");if(!t)return;const i=e.getBoundingClientRect().top-t.getBoundingClientRect().top,n=Math.min(Math.max(t.getBoundingClientRect().top,0),120),r=Math.round(i+n);r>=0&&r!==this._hdrH&&(this._hdrH=r),r>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:r,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&&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){Om(this,e)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await h_(this.hass,a_(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptStructuralResponses(e,t,i){const n=e?.config,r=n&&Array.isArray(n.spaces)?n:null,o=El(r),s=o!==(this._cfgContentFingerprint||El(this._serverCfg));if(s&&(this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._cancelDeviceDrag(),this._pendingPhysicalWrites.clear(),this._clearRoomFocus(!0),this._cancelCameraTransition(!1),this._serverCfg&&this._clearGeometryGesture(),this._serverCfg=r,this._seedDecorStyle(this._serverCfg),this._cfgContentFingerprint=o),this._cfgRev=e?.rev??this._cfgRev,e&&("virtual_lights"in e||"config"in e)){const t=Xc(this._virtualLights,e.virtual_lights,this._cfgRev,"virtual_lights"in e);Jc(t)!==Jc(this._virtualLights)&&(this._virtualLights=t,this._capturedSnapshotVirtual="")}let a=!1;if(void 0!==t||void 0!==i){const e=i??t?.layout??{},n=El(e);a=n!==(this._layoutContentFingerprint||El(this._layout)),a&&(this._cancelCameraTransition(!1),this._devicePositionHistory.clear(),this._cancelDeviceDrag(),this._layout=e,this._layoutContentFingerprint=n),this._layoutRev=t?.rev??this._layoutRev}return this._canOptimizeUndo=!(!e?.can_optimize_undo&&!t?.can_optimize_undo),this._adoptConfigCapabilities(e),this._undoKind=e?.undo_kind||t?.undo_kind||null,"boolean"==typeof e?.can_write&&(this._serverCanWrite=e.can_write),s&&this._continuity.note("config-candidate",{configRev:this._cfgRev}),a&&this._continuity.note("layout-candidate",{layoutRev:this._layoutRev}),{configChanged:s,layoutChanged:a}}_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=>Om(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;try{const[i,n]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]),r=i?.config&&Array.isArray(i.config.spaces)?i.config:null,o=El(r)!==(this._cfgContentFingerprint||El(this._serverCfg))||El(n?.layout??{})!==(this._layoutContentFingerprint||El(this._layout));if(o){if(!await this._signer.prepareImage(this.hass,this._candidateBackdrop(r)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0)}o&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),this._connectionWasLost=!1,this._serverStorage=!0,"boolean"==typeof i?.can_write&&(this._serverCanWrite=i.can_write),this._canOptimizeUndo=!(!i?.can_optimize_undo&&!n?.can_optimize_undo),this._adoptStructuralResponses(i,n),this._syncDecorAssets(r).catch(()=>{}),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,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(uf)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,this._regSignature="",this._maybeRebuildDevices(),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=th(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){if(!e){if(void 0!==t&&t<=this._cfgRev)return;if(this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(()=>this._reloadConfigOnly(!1,t),400))}this._beginContinuityCandidate("config-reload",!1);try{const e=await this._getAuthoritativeConfig(),t=e?.config&&Array.isArray(e.config.spaces)?e.config:null;if(El(t)!==(this._cfgContentFingerprint||El(this._serverCfg))&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0);const i=this._space;this._adoptStructuralResponses(e),this._syncDecorAssets(t).catch(()=>{}),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._space!==i&&this._restoreZoom(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}catch(e){this._showToast(this._t("toast.cfg_reload_failed",{err:this._errText(e)}))}finally{this._continuityDataReady=!0,this.requestUpdate()}}_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-DIiVVHS_.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=uh(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return _h(this.hass)}get _planHass(){const e=this._haRegistry,t=gh(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=vh(this.hass,e),r=yh(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+um)>e?1:0)).join("|"),i=Jc(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"]);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 Kt(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=Di(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,Ii(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!cd(n,e,ld(this._markers))))}const h=Kh(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(gp(e.id,t),up(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?ec(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=vc(e.id,e.marker?.vacuum??null,e.space,t),a=bc({routes:s,observed:wc(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=mp({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 kh(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&&kf("/config/devices/device/"+encodeURIComponent(e.device_id))}}else kf("/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=fn(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){const t=e?.rev;"number"==typeof t&&t>this._layoutRev&&(this._layoutRev=t)}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;const n=El(i);n!==El(this._layout)&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear(),this._layout=i),this._layoutContentFingerprint=n,this._layoutRev=t?.rev??this._layoutRev,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=eo(Nr(this._layout)),localStorage.setItem(uf,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=gh(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+xu(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=pd({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,kh(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=wh(),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));sh=n;try{localStorage.setItem(oh,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)&&(wf(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=Zp(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])Xp(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||(Yp(t.id)&&r.add(t.id),Xp(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]=i_(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&&ph(this.hass),n_({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:yf})}_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=El({snapshot:Zp(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=zm(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=Am(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=Zp(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=El(o)!==El(Zp(r.marker_area_snapshot)),l=El(s)!==El(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(El(a.marker_area_snapshot)===El(o)&&El(a.new_device_ids)===El(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._cfgContentFingerprint=El(this._serverCfg)}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=Zh(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return fi(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*il(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)}));yi(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=Ea(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*yf,y:i.y*yf}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?Ea(tl(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:Na(r/yf),y:Na(o/yf)}}_previewDevicePlacement(e,t){this._layout=Am(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null;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=Am(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=Qr(this._layout[e]);El(t)!==El(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._layoutContentFingerprint=El(this._layout),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=zm(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=Am(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(gp(e.id,t));return n||up(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,dp({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=Qh(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Jh(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 Cn(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,wf(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()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_ctxDevice(e,t){"view"===this._mode&&(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(),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=Ld(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(!Vd(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Vd(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=th(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&&!Vd(r)&&this._showUnavailableToggleTargets(r)||(r&&Kd(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||Vd(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Gd.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!Gd.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 Su(xu(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")}}_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=ja([[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=ja("line"===e.kind?[[e.x1*yf,e.y1*i],[e.x2*yf,e.y2*i]]:"text"===e.kind?[[e.x*yf,e.y*i]]:_r({x:e.x*yf,y:e.y*i,w:e.w*yf,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=ja(i);e&&t.push(e)}}return Ka(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:yf,h:yf};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=Ja(this._contentItems(e));let r=n.all||el(e),o=this._showFar?r:n.core||el(e);return t&&t.id===e.id&&i&&t.grow&&(o=bf(t.rect,o),r=bf(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:yf,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=bf(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=vi([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,kp(a),n.showLqi??this._config?.show_signal??!0),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>vi([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",Rg("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?_g(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=mg([e.x,e.y]),i=mg([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]}}_openingLockAnchor(e,t){const i=(e.angle+90)*Math.PI/180,n="gate"===e.type?this._openingFace(e,t,!e.flip_v):null,r=ba(16,this._cellCm),o=n?-r*n.side:r*(e.flip_v?-1:1);return[e.rx+Math.cos(i)*o,e.ry+Math.sin(i)*o]}_isoOverlayScene(e,t,i,n,r,o,s,a,l){const c=this._isoSceneRuntime;return c&&r?.structural&&o?c.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,layers:r,wallSilhouettes:o.wallSilhouettes,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:this._kiosk?this._kioskScale.icon:1,kioskFontScale:this._kiosk?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),selectedDeviceId:this._selId,focusedRoomId:this._roomFocus?.roomId,selectedOpeningId:this._openingInfo?.id,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=vg({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=Nt(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=hs(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,yf);i&&(l=Hs(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(Sg)||!i.every(Sg)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return Mg([...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(_g(t,0)),o>0&&e.push(_g(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(_g(i,0)),r>0&&e.push(_g(i,r))}return Mg(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?ba(64,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?ba(10,this._cellCm):0,padding:a.showBorders?ba(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=vi(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(!$g(i)||!$g(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:Mf.ZOOM_MIN,maxZoom:Mf.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),rg(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?V:j`
+
`:V}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}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 Da(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?Bl(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return Bl(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._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._resumeDraftBySpace={},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=dd({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=ye(e)),this._rulesCompiled}get _fillColors(){return Xi(this._settings)}get _excluded(){return yd(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,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,()=>Lm(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>this._refitView()),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=this.renderRoot.querySelector("ha-card");if(!t)return;const i=e.getBoundingClientRect().top-t.getBoundingClientRect().top,n=Math.min(Math.max(t.getBoundingClientRect().top,0),120),r=Math.round(i+n);r>=0&&r!==this._hdrH&&(this._hdrH=r),r>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:r,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&&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){Em(this,e)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await d_(this.hass,l_(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptStructuralResponses(e,t,i){const n=e?.config,r=n&&Array.isArray(n.spaces)?n:null,o=El(r),s=o!==(this._cfgContentFingerprint||El(this._serverCfg));if(s&&(this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._cancelDeviceDrag(),this._pendingPhysicalWrites.clear(),this._clearRoomFocus(!0),this._cancelCameraTransition(!1),this._serverCfg&&this._clearGeometryGesture(),this._serverCfg=r,this._seedDecorStyle(this._serverCfg),this._cfgContentFingerprint=o),this._cfgRev=e?.rev??this._cfgRev,e&&("virtual_lights"in e||"config"in e)){const t=Xc(this._virtualLights,e.virtual_lights,this._cfgRev,"virtual_lights"in e);Jc(t)!==Jc(this._virtualLights)&&(this._virtualLights=t,this._capturedSnapshotVirtual="")}let a=!1;if(void 0!==t||void 0!==i){const e=i??t?.layout??{},n=El(e);a=n!==(this._layoutContentFingerprint||El(this._layout)),a&&(this._cancelCameraTransition(!1),this._devicePositionHistory.clear(),this._cancelDeviceDrag(),this._layout=e,this._layoutContentFingerprint=n),this._layoutRev=t?.rev??this._layoutRev}return this._canOptimizeUndo=!(!e?.can_optimize_undo&&!t?.can_optimize_undo),this._adoptConfigCapabilities(e),this._undoKind=e?.undo_kind||t?.undo_kind||null,"boolean"==typeof e?.can_write&&(this._serverCanWrite=e.can_write),s&&this._continuity.note("config-candidate",{configRev:this._cfgRev}),a&&this._continuity.note("layout-candidate",{layoutRev:this._layoutRev}),{configChanged:s,layoutChanged:a}}_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=>Em(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;try{const[i,n]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]),r=i?.config&&Array.isArray(i.config.spaces)?i.config:null,o=El(r)!==(this._cfgContentFingerprint||El(this._serverCfg))||El(n?.layout??{})!==(this._layoutContentFingerprint||El(this._layout));if(o){if(!await this._signer.prepareImage(this.hass,this._candidateBackdrop(r)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0)}o&&this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._beginContinuityCandidate("structural-response",!0),this._connectionWasLost=!1,this._serverStorage=!0,"boolean"==typeof i?.can_write&&(this._serverCanWrite=i.can_write),this._canOptimizeUndo=!(!i?.can_optimize_undo&&!n?.can_optimize_undo),this._adoptStructuralResponses(i,n),this._syncDecorAssets(r).catch(()=>{}),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,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(pf)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,this._regSignature="",this._maybeRebuildDevices(),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=th(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){if(!e){if(void 0!==t&&t<=this._cfgRev)return;if(this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(()=>this._reloadConfigOnly(!1,t),400))}this._beginContinuityCandidate("config-reload",!1);try{const e=await this._getAuthoritativeConfig(),t=e?.config&&Array.isArray(e.config.spaces)?e.config:null;if(El(t)!==(this._cfgContentFingerprint||El(this._serverCfg))&&!await this._signer.prepareImage(this.hass,this._candidateBackdrop(t)))return this._continuity.note("asset-failed"),void this._scheduleLoadRetry(!0);const i=this._space;this._adoptStructuralResponses(e),this._syncDecorAssets(t).catch(()=>{}),this._adoptInitialSpace(this._model,!0),this._resumePendingNavMode(),this._cacheSnapshot(),this._space!==i&&this._restoreZoom(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}catch(e){this._showToast(this._t("toast.cfg_reload_failed",{err:this._errText(e)}))}finally{this._continuityDataReady=!0,this.requestUpdate()}}_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-CLqXDVvg.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=uh(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return _h(this.hass)}get _planHass(){const e=this._haRegistry,t=gh(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=vh(this.hass,e),r=yh(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+pm)>e?1:0)).join("|"),i=Jc(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"]);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 Kt(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=Di(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,Ii(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!cd(n,e,ld(this._markers))))}const h=Kh(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(fp(e.id,t),pp(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?ec(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=vc(e.id,e.marker?.vacuum??null,e.space,t),a=bc({routes:s,observed:wc(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=gp({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 kh(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&&xf("/config/devices/device/"+encodeURIComponent(e.device_id))}}else xf("/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=fn(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){const t=e?.rev;"number"==typeof t&&t>this._layoutRev&&(this._layoutRev=t)}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;const n=El(i);n!==El(this._layout)&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear(),this._layout=i),this._layoutContentFingerprint=n,this._layoutRev=t?.rev??this._layoutRev,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=eo(Nr(this._layout)),localStorage.setItem(pf,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=gh(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+xu(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=pd({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,kh(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=wh(),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));sh=n;try{localStorage.setItem(oh,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)&&(kf(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=Jp(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])Zp(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||(Xp(t.id)&&r.add(t.id),Zp(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]=n_(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&&ph(this.hass),r_({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:bf})}_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=El({snapshot:Jp(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=Am(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=Pm(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=Jp(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=El(o)!==El(Jp(r.marker_area_snapshot)),l=El(s)!==El(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(El(a.marker_area_snapshot)===El(o)&&El(a.new_device_ids)===El(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._cfgContentFingerprint=El(this._serverCfg)}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=Zh(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return fi(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*il(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)}));yi(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=Ea(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*bf,y:i.y*bf}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?Ea(tl(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:Na(r/bf),y:Na(o/bf)}}_previewDevicePlacement(e,t){this._layout=Pm(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null;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=Pm(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=Qr(this._layout[e]);El(t)!==El(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._layoutContentFingerprint=El(this._layout),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=Am(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=Pm(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(fp(e.id,t));return n||pp(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,up({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=Qh(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Jh(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 Cn(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,kf(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()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_ctxDevice(e,t){"view"===this._mode&&(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(),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=Ld(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(!Vd(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Vd(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=th(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&&!Vd(r)&&this._showUnavailableToggleTargets(r)||(r&&Kd(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||Vd(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Gd.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!Gd.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 Su(xu(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")}}_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=ja([[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=ja("line"===e.kind?[[e.x1*bf,e.y1*i],[e.x2*bf,e.y2*i]]:"text"===e.kind?[[e.x*bf,e.y*i]]:_r({x:e.x*bf,y:e.y*i,w:e.w*bf,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=ja(i);e&&t.push(e)}}return Ka(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:bf,h:bf};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=Ja(this._contentItems(e));let r=n.all||el(e),o=this._showFar?r:n.core||el(e);return t&&t.id===e.id&&i&&t.grow&&(o=wf(t.rect,o),r=wf(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:bf,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=wf(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=vi([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,xp(a),n.showLqi??this._config?.show_signal??!0),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>vi([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",Cg("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?mg(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=gg([e.x,e.y]),i=gg([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){const c=this._isoSceneRuntime;return c&&r?.structural&&o?c.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,layers:r,wallSilhouettes:o.wallSilhouettes,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:this._kiosk?this._kioskScale.icon:1,kioskFontScale:this._kiosk?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),selectedDeviceId:this._selId,focusedRoomId:this._roomFocus?.roomId,selectedOpeningId:this._openingInfo?.id,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=yg({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=Nt(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=hs(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,bf);i&&(l=Hs(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($g)||!i.every($g)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return Rg([...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(mg(t,0)),o>0&&e.push(mg(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(mg(i,0)),r>0&&e.push(mg(i,r))}return Rg(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?ba(64,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?ba(10,this._cellCm):0,padding:a.showBorders?ba(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=vi(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(!Mg(i)||!Mg(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:Rf.ZOOM_MIN,maxZoom:Rf.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),og(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?V:j`
${this._t("canvas.far_objects",{n:this._outliers})} @@ -5198,7 +5198,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 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:vi(e,this._stageAspect(e))}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._stageEl,i=this.renderRoot.querySelector(".editorchrome");if(!t||t.clientWidth<=0||t.clientHeight<=0)return e.w;const n=t.clientHeight+(i?.getBoundingClientRect().height||0);return n<=0?e.w:this._viewForModeTarget(this._zoom,void 0,void 0,t.clientWidth,n).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=vi(n,this._stageAspect()),o=Math.min(Mf.ZOOM_MAX,Math.max(Mf.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;n>=1200||n>=700&&i>0&&t-this._bootLastChange>=250?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},lf)}_bootSoftCancel(){this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoft=!1)}_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;this._cancelCameraTransition(!1);const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight],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,!i)return this._lastValidStageSize=t,void(this._roomFocus?.spaceId===this._space?this._fitRoom(this._roomFocus.roomId,!1):this._view||this._applyView(this._zoom));n?this._pendingRefitSize=null:(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>=zl?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=vi(this._baseVb(),this._stageAspect()),s=Math.min(Mf.ZOOM_MAX,Math.max(Mf.ZOOM_MIN,i)),a=function(e,t,i,n,r,o,s){if(!ig(e)||!ig({zoom:t,viewBox:i})||!tg(n)||n<=0||!tg(r)||r<=0||!tg(o)||!tg(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=vi(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(_f,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){const t=e.isPrimary&&0===e.button&&"view"===this._mode?kg(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=vi(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._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover");const t=(i=this._roomPointer,n=e.pointerId,r=this._space,o=this._roomPointer&&"view"===this._mode?kg(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&&kf("/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){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:zm(this._layout,t.id),start:this._devicePlacementForCanvas(t,i.x,i.y)},Sf(e),this._tip=null,this._syncLiveHover()}_pointerMove(e,t){if("devices"!==this._mode)return;const i=this._deviceDrag;i&&i.id===t.id&&i.pointerId===e.pointerId&&this._editorRuntimeOrThrow()._queuePointerMove("device",()=>this._pointerMoveNow(e,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=Ha(i.ox+a),h=Ha(i.oy+l);this._previewDevicePlacement(t.id,this._devicePlacementForCanvas(t,c,h))}_pointerUp(e,t){if(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=zm(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){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(vf))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(vf)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(vf))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),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("click"===e.type){if(!this._suppressClick&&!this._touchSequenceMultitouch&&Date.now()>this._touchClickBlockUntil)return;return e.preventDefault(),void e.stopImmediatePropagation()}const t=e;if(this._notePointer(t),"pointercancel"===e.type||"lostpointercapture"===e.type?this._doubleFit.clear():"pointerdown"===e.type&&this._doubleFit.clearOutside(t),"touch"===t.pointerType)if("pointerdown"!==e.type){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){if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),this._touchSequenceMultitouch){if(this._touchClickBlockUntil=Date.now()+500,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)}0===this._touchContacts.size&&(this._touchSequenceMultitouch=!1)}}else if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._clearRoomFocus(!0),this._clearTransientHover(),this._touchSequenceMultitouch=!0,this._touchClickBlockUntil=Number.POSITIVE_INFINITY,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)}}_showTip(e,t,i,n,r,o,s=!1){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||this._deviceDrag||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:n,temp:r,hum:o,room:s},this._syncLiveHover()))}_roomTipEnabledForPointer(e){return"view"===this._mode&&(this._notePointer(e),!!Ki(this._settings)||(this._tip?.room&&(this._tip=null,this._syncLiveHover()),!1))}get _gridPitch(){return Fa}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 Et(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,yf}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return Bt(e?.rooms||[]).map(e=>[e[0]*yf,e[1]*t,e[2]*yf,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(mf)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(mf,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,this._clearRoomFocus(!0),this._cancelDangerConfirm(),"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeDraftId=null,this._resumeDraftBySpace={},this._draftSegmentCms=[],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._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._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?uo(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?Gs:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?Gs:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){return this._editorRuntimeOrThrow()._showPhysicalRange(e,t)}_draftSegmentCount(e=this._curSpaceCfg){return this._editorRuntimeOrThrow()._draftSegmentCount(e)}_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 Xt(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=to(e),i=await this.hass.callWS({type:"houseplan/config/set",config:t,expected_rev:this._cfgRev});this._cfgRev=i?.rev??this._cfgRev+1}_writeConfig(){if(this._editorRuntime)return this._editorRuntime._writeConfig();this._writesPending++,this._writeChain=Rm(this._writeChain,async()=>{if(!this._serverCfg)return;const e=to(this._serverCfg),t=El(e);t!==El(this._serverCfg)&&(this._serverCfg=e),this._cfgContentFingerprint=t,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._activeDraftId=null,this._draftSegmentCms=[],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._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?Zt(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)}_canAppendRoomDraftPoint(){return this._editorRuntimeOrThrow()._canAppendRoomDraftPoint()}_markupClick(e){if(this._editorRuntime)return this._editorRuntime._markupClick(e)}_draftEndAt(e,t){return this._editorRuntimeOrThrow()._draftEndAt(e,t)}_mergeDraftEndpoint(e){return this._editorRuntimeOrThrow()._mergeDraftEndpoint(e)}_adoptDraftCms(e,t,i){return this._editorRuntimeOrThrow()._adoptDraftCms(e,t,i)}_draftSegmentsForPath(e,t,i){return this._editorRuntimeOrThrow()._draftSegmentsForPath(e,t,i)}_persistActiveDraftSegment(){return this._editorRuntimeOrThrow()._persistActiveDraftSegment()}_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,i){return this._editorRuntimeOrThrow()._openPhysicalDialog(e,t,i)}_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,i){return this._editorRuntimeOrThrow()._registerPhysicalTap(e,t,i)}_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*yf,ry:e.y*t,rlen:e.length*yf};if(!e.host||"wall"===e.host.kind)return[n];const r=Qd(e,i.partitions,yf,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 Wp(jp(this._curSpaceCfg?.id===e.id?this._curSpaceCfg:null,e,this._cellCm,this._gridPitch,yf),t)}_roomWallOpeningInputs(e=this._openingsR,t=this._spaceModel()){if(!t)return[];const i=this._openCuts();return Up(e,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,yf)}_openingFace(e,t,i){return e.partitionHost?nu(e.partitionHost,i):js(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 yf}_decorResolvedStyle(e){return function(e,t,i,n=rr){const r="rect"===e?.kind||"ellipse"===e?.kind,o=e,s=Dt(o?.color,n.color);return{color:s,opacity:or(o?.opacity,n.opacity),widthCm:dr(e,t,i,n.widthCm),fill:!!r&&!0===o?.fill,fillColor:Dt(o?.fill_color,o?.fill?s:n.fillColor),fillOpacity:r&&o?.fill?or(o?.fill_opacity,.25):n.fillOpacity}}(e,this._cellCm,this._gridPitch,rr)}_decorWidthUnits(e){return((e,t,i,n=rr.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,rr.widthCm)}_decorTextSizeCm(e){if("text"===e?.kind){const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?t:hr(20*Ei(e),this._cellCm,this._gridPitch)}return hr(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*Ei(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*yf,y:e.y*this._decorH,w:e.w*yf,h:e.h*this._decorH,angle:sr(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]]:_r(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,yf,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?{...$a(e.plan_aspect,yf)}:null}get _bdRect(){const e=this._curSpaceCfg;return e?.plan_url?Ca(e,yf):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:sr(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):V}_renderTextFrame(e){const t=this._dtSel;if(!t)return V;if("text"===t.kind&&this._dtBox?.id!==t.id)return V;const i="text"===t.kind?this._dtBox:this._decorBoxOf(t);if("line"!==t.kind&&!i)return V;const n=.018*Math.max(e.w,e.h),r=n/4;if("line"===t.kind){const e=[t.x1*yf,t.y1*this._decorH],i=[t.x2*yf,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:vi(e,this._stageAspect(e))}_roomLabelReferenceViewWidth(e){if(!this._markup)return e.w;const t=this._stageEl,i=this.renderRoot.querySelector(".editorchrome");if(!t||t.clientWidth<=0||t.clientHeight<=0)return e.w;const n=t.clientHeight+(i?.getBoundingClientRect().height||0);return n<=0?e.w:this._viewForModeTarget(this._zoom,void 0,void 0,t.clientWidth,n).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=vi(n,this._stageAspect()),o=Math.min(Rf.ZOOM_MAX,Math.max(Rf.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;n>=1200||n>=700&&i>0&&t-this._bootLastChange>=250?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},cf)}_bootSoftCancel(){this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoft=!1)}_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;this._cancelCameraTransition(!1);const e=this._stageEl;if(!e||"visible"!==document.visibilityState||e.clientWidth<=0||e.clientHeight<=0)return void(this._viewportInvalidAt||(this._viewportInvalidAt=Date.now()));const t=[e.clientWidth,e.clientHeight],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,!i)return this._lastValidStageSize=t,void(this._roomFocus?.spaceId===this._space?this._fitRoom(this._roomFocus.roomId,!1):this._view||this._applyView(this._zoom));n?this._pendingRefitSize=null:(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>=zl?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=vi(this._baseVb(),this._stageAspect()),s=Math.min(Rf.ZOOM_MAX,Math.max(Rf.ZOOM_MIN,i)),a=function(e,t,i,n,r,o,s){if(!ng(e)||!ng({zoom:t,viewBox:i})||!ig(n)||n<=0||!ig(r)||r<=0||!ig(o)||!ig(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=vi(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(mf,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){const t=e.isPrimary&&0===e.button&&"view"===this._mode?xg(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=vi(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._flushHa(),this._editorRuntime?._cancelPointerMove("markup-hover");const t=(i=this._roomPointer,n=e.pointerId,r=this._space,o=this._roomPointer&&"view"===this._mode?xg(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&&xf("/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){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:Am(this._layout,t.id),start:this._devicePlacementForCanvas(t,i.x,i.y)},$f(e),this._tip=null,this._syncLiveHover()}_pointerMove(e,t){if("devices"!==this._mode)return;const i=this._deviceDrag;i&&i.id===t.id&&i.pointerId===e.pointerId&&this._editorRuntimeOrThrow()._queuePointerMove("device",()=>this._pointerMoveNow(e,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=Ha(i.ox+a),h=Ha(i.oy+l);this._previewDevicePlacement(t.id,this._devicePlacementForCanvas(t,c,h))}_pointerUp(e,t){if(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=Am(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){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(yf))t.toggleAttribute("data-pointer-hover",e)}_syncPointerHoverSubtree(e){if(e.nodeType!==Node.ELEMENT_NODE)return;const t=e,i=this._pointerModality.hoverEnabled;t.matches(yf)&&t.toggleAttribute("data-pointer-hover",i);for(const e of t.querySelectorAll(yf))e.toggleAttribute("data-pointer-hover",i)}_clearTransientHover(e=!1){e&&this._pointerModality.suspend(),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("click"===e.type){if(!this._suppressClick&&!this._touchSequenceMultitouch&&Date.now()>this._touchClickBlockUntil)return;return e.preventDefault(),void e.stopImmediatePropagation()}const t=e;if(this._notePointer(t),"pointercancel"===e.type||"lostpointercapture"===e.type?this._doubleFit.clear():"pointerdown"===e.type&&this._doubleFit.clearOutside(t),"touch"===t.pointerType)if("pointerdown"!==e.type){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){if(this._clearTransientHover(),this._touchContacts.delete(t.pointerId),this._touchSequenceMultitouch){if(this._touchClickBlockUntil=Date.now()+500,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)}0===this._touchContacts.size&&(this._touchSequenceMultitouch=!1)}}else if(this._touchContacts.set(t.pointerId,{x:t.clientX,y:t.clientY,inStage:!!t.target?.closest?.(".stage")}),this._touchContacts.size>=2){this._clearRoomFocus(!0),this._clearTransientHover(),this._touchSequenceMultitouch=!0,this._touchClickBlockUntil=Number.POSITIVE_INFINITY,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)}}_showTip(e,t,i,n,r,o,s=!1){this._notePointer(e),this._pointerModality.hoverEnabled&&(this._drag||this._deviceDrag||(this._tip={x:e.clientX,y:e.clientY,title:t,meta:i,lqi:n,temp:r,hum:o,room:s},this._syncLiveHover()))}_roomTipEnabledForPointer(e){return"view"===this._mode&&(this._notePointer(e),!!Ki(this._settings)||(this._tip?.room&&(this._tip=null,this._syncLiveHover()),!1))}get _gridPitch(){return Fa}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 Et(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,bf}get _segments(){const e=this._curSpaceCfg,t=this._spaceH;return Bt(e?.rooms||[]).map(e=>[e[0]*bf,e[1]*t,e[2]*bf,e[3]*t])}_savedNav(){if(this._hasFixedFloor)return null;try{return JSON.parse(localStorage.getItem(gf)||"null")}catch{return null}}_saveNav(){if(!this._hasFixedFloor)try{localStorage.setItem(gf,JSON.stringify({space:this._space}))}catch{}}_leaveCardRoute(){if(this._routeDepartureHandled)return;this._routeDepartureHandled=!0,this._clearRoomFocus(!0),this._cancelDangerConfirm(),"view"!==this._mode&&this._setMode("view",!1),this._pendingNavMode=null,this._geometryHistory.clear(),this._activeDraftId=null,this._resumeDraftBySpace={},this._draftSegmentCms=[],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._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._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?uo(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?Gs:100;return t>=("column"===this._tool?1:0)&&t<=i?t:null}get _drawWallMaxCm(){return"column"===this._tool?Gs:100}_showPhysicalRange(e=this._drawWallMaxCm,t=0){return this._editorRuntimeOrThrow()._showPhysicalRange(e,t)}_draftSegmentCount(e=this._curSpaceCfg){return this._editorRuntimeOrThrow()._draftSegmentCount(e)}_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 Xt(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=to(e),i=await this.hass.callWS({type:"houseplan/config/set",config:t,expected_rev:this._cfgRev});this._cfgRev=i?.rev??this._cfgRev+1}_writeConfig(){if(this._editorRuntime)return this._editorRuntime._writeConfig();this._writesPending++,this._writeChain=Cm(this._writeChain,async()=>{if(!this._serverCfg)return;const e=to(this._serverCfg),t=El(e);t!==El(this._serverCfg)&&(this._serverCfg=e),this._cfgContentFingerprint=t,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._activeDraftId=null,this._draftSegmentCms=[],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._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?Zt(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)}_canAppendRoomDraftPoint(){return this._editorRuntimeOrThrow()._canAppendRoomDraftPoint()}_markupClick(e){if(this._editorRuntime)return this._editorRuntime._markupClick(e)}_draftEndAt(e,t){return this._editorRuntimeOrThrow()._draftEndAt(e,t)}_mergeDraftEndpoint(e){return this._editorRuntimeOrThrow()._mergeDraftEndpoint(e)}_adoptDraftCms(e,t,i){return this._editorRuntimeOrThrow()._adoptDraftCms(e,t,i)}_draftSegmentsForPath(e,t,i){return this._editorRuntimeOrThrow()._draftSegmentsForPath(e,t,i)}_persistActiveDraftSegment(){return this._editorRuntimeOrThrow()._persistActiveDraftSegment()}_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,i){return this._editorRuntimeOrThrow()._openPhysicalDialog(e,t,i)}_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,i){return this._editorRuntimeOrThrow()._registerPhysicalTap(e,t,i)}_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*bf,ry:e.y*t,rlen:e.length*bf};if(!e.host||"wall"===e.host.kind)return[n];const r=Qd(e,i.partitions,bf,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 Up(Wp(this._curSpaceCfg?.id===e.id?this._curSpaceCfg:null,e,this._cellCm,this._gridPitch,bf),t)}_roomWallOpeningInputs(e=this._openingsR,t=this._spaceModel()){if(!t)return[];const i=this._openCuts();return Vp(e,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,bf)}_openingFace(e,t,i){return e.partitionHost?nu(e.partitionHost,i):js(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 bf}_decorResolvedStyle(e){return function(e,t,i,n=rr){const r="rect"===e?.kind||"ellipse"===e?.kind,o=e,s=Dt(o?.color,n.color);return{color:s,opacity:or(o?.opacity,n.opacity),widthCm:dr(e,t,i,n.widthCm),fill:!!r&&!0===o?.fill,fillColor:Dt(o?.fill_color,o?.fill?s:n.fillColor),fillOpacity:r&&o?.fill?or(o?.fill_opacity,.25):n.fillOpacity}}(e,this._cellCm,this._gridPitch,rr)}_decorWidthUnits(e){return((e,t,i,n=rr.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,rr.widthCm)}_decorTextSizeCm(e){if("text"===e?.kind){const t=Number(e.size_cm);return Number.isFinite(t)&&t>0?t:hr(20*Ei(e),this._cellCm,this._gridPitch)}return hr(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*Ei(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*bf,y:e.y*this._decorH,w:e.w*bf,h:e.h*this._decorH,angle:sr(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]]:_r(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,bf,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?{...$a(e.plan_aspect,bf)}:null}get _bdRect(){const e=this._curSpaceCfg;return e?.plan_url?Ca(e,bf):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:sr(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):V}_renderTextFrame(e){const t=this._dtSel;if(!t)return V;if("text"===t.kind&&this._dtBox?.id!==t.id)return V;const i="text"===t.kind?this._dtBox:this._decorBoxOf(t);if("line"!==t.kind&&!i)return V;const n=.018*Math.max(e.w,e.h),r=n/4;if("line"===t.kind){const e=[t.x1*bf,t.y1*this._decorH],i=[t.x2*bf,t.y2*this._decorH];return W` ${[e,i].map((e,t)=>W`this._dtStart(e,"scale",void 0,t)}> @@ -5209,13 +5209,13 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 this._dtStart(e,"rotate")}> - ${$f.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=yf,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=bf,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``:V}`}if("image"===e.kind){const s=l_(e,i,n);if(!s)return V;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):V;const g=this._display(m.url);return g?W``:V}`}if("image"===e.kind){const s=c_(e,i,n);if(!s)return V;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):V;const g=this._display(m.url);return g?W`this._signer.markLoaded(this._renderPlanHass,m.url,g)} @@ -5275,12 +5275,12 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 data-zero-wall-style=${t.style} style="--zero-wall-stroke:${i}"> ${t.lines.map(e=>W``)} - `}_zeroWalls(){const e=this._spaceModel();return e?Hp(this._curSpaceCfg,e,yf,.02*this._gridPitch):{style:Fp(this._curSpaceCfg),lines:[],contour:[],barriers:[],transmissive:[]}}_openCuts(){return this._zeroWalls().contour}_deleteRoomClick(e){return this._editorRuntimeOrThrow()._deleteRoomClick(e)}get _wallKeyPitch(){return Ia}get _spaceWalls(){const e=this._curSpaceCfg?.walls;return Array.isArray(e)?e:[]}_intervalCm(e){const t=this._spaceModel();return t?_s(t.rooms,this._spaceWalls,this._openCuts(),e,this._wallKeyPitch,this._cellCm,this._gridPitch,yf):0}_normalizeWalls(e,t){const i=this._spaceModel();if(!i)return[];return Ro(ps(i.rooms,e,t,this._wallKeyPitch,this._cellCm,this._gridPitch,yf),this._curSpaceCfg?.rooms||[],Ia,1,t.map(e=>[e[0]/yf,e[1]/yf,e[2]/yf,e[3]/yf]))}_paperShapes(e){if(!this._spaceWalls.length)return Lt(e);const t=this._wallUnionGeometry();return t?.paperD?[{path:t.paperD}]:Lt(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=zg(this._wallUnionPool,n);if(r.hit)this._wallUnionCache=r.value;else{const r=this._openCuts(),o=this._roomWallOpeningInputs(),s=Fs(e.rooms,t,r,o,this._wallKeyPitch,this._cellCm,this._gridPitch,yf,i);s&&Object.defineProperty(s,"sourceFingerprint",{value:El([this._curSpaceCfg,this._cellCm,this._gridPitch]),enumerable:!1});const a={key:n,value:s};Ag(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 Os(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,yf).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=zg(this._innerContourCache,s);if(a.hit)return a.value;const l=fs(e.rooms,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,yf,n,r);return Ag(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:ba(1.5*o,r)}(e.cm,this._cellCm,this._gridPitch);let i="";for(const n of e.segs)i+=(i?" ":"")+jo([[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=lo(this._cellCm);return W` + `}_zeroWalls(){const e=this._spaceModel();return e?Np(this._curSpaceCfg,e,bf,.02*this._gridPitch):{style:Ip(this._curSpaceCfg),lines:[],contour:[],barriers:[],transmissive:[]}}_openCuts(){return this._zeroWalls().contour}_deleteRoomClick(e){return this._editorRuntimeOrThrow()._deleteRoomClick(e)}get _wallKeyPitch(){return Ia}get _spaceWalls(){const e=this._curSpaceCfg?.walls;return Array.isArray(e)?e:[]}_intervalCm(e){const t=this._spaceModel();return t?_s(t.rooms,this._spaceWalls,this._openCuts(),e,this._wallKeyPitch,this._cellCm,this._gridPitch,bf):0}_normalizeWalls(e,t){const i=this._spaceModel();if(!i)return[];return Ro(ps(i.rooms,e,t,this._wallKeyPitch,this._cellCm,this._gridPitch,bf),this._curSpaceCfg?.rooms||[],Ia,1,t.map(e=>[e[0]/bf,e[1]/bf,e[2]/bf,e[3]/bf]))}_paperShapes(e){if(!this._spaceWalls.length)return Lt(e);const t=this._wallUnionGeometry();return t?.paperD?[{path:t.paperD}]:Lt(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=Ag(this._wallUnionPool,n);if(r.hit)this._wallUnionCache=r.value;else{const r=this._openCuts(),o=this._roomWallOpeningInputs(),s=Fs(e.rooms,t,r,o,this._wallKeyPitch,this._cellCm,this._gridPitch,bf,i);s&&Object.defineProperty(s,"sourceFingerprint",{value:El([this._curSpaceCfg,this._cellCm,this._gridPitch]),enumerable:!1});const a={key:n,value:s};Pg(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 Os(e.rooms,t,i,this._wallKeyPitch,this._cellCm,this._gridPitch,bf).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=Ag(this._innerContourCache,s);if(a.hit)return a.value;const l=fs(e.rooms,t,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,bf,n,r);return Pg(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:ba(1.5*o,r)}(e.cm,this._cellCm,this._gridPitch);let i="";for(const n of e.segs)i+=(i?" ":"")+jo([[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=lo(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:yn(t.fill,r),o=this._roomDialog&&r.id===this._roomEditId?this._roomCustomFill||t.customFill:Ui(t.customFill,r),s=Ji(e,"lqi"===e&&r.area?this._roomLqi(r.area):null,"light"===e?Xh(Kh(this._renderPlanHass,this._renderDevices,r,this._virtualLights)):"none","temp"===e?this._roomTemp(r):null,t.tempMin,t.tempMax,this._fillColors,o);i.set(r,s),r.id&&n.set(r.id,s)}return{byRoom:i,byId:n}}_spaceDisplayForRender(){const e=Vi(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?Wi(t.customFill):ji,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=Ns(e.rooms,this._spaceWalls,t,this._wallKeyPitch,this._cellCm,this._gridPitch,yf)),Ag(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:Vs(s.value,r)}),xp({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=bn(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,Nt(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 V;const c=this._spaceWalls.length&&s.id&&this._innerRoomContour(e,s.id,n,r)||l,h=ci(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:yn(t.fill,r),o=this._roomDialog&&r.id===this._roomEditId?this._roomCustomFill||t.customFill:Ui(t.customFill,r),s=Ji(e,"lqi"===e&&r.area?this._roomLqi(r.area):null,"light"===e?Xh(Kh(this._renderPlanHass,this._renderDevices,r,this._virtualLights)):"none","temp"===e?this._roomTemp(r):null,t.tempMin,t.tempMax,this._fillColors,o);i.set(r,s),r.id&&n.set(r.id,s)}return{byRoom:i,byId:n}}_spaceDisplayForRender(){const e=Vi(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?Wi(t.customFill):ji,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=Ns(e.rooms,this._spaceWalls,t,this._wallKeyPitch,this._cellCm,this._gridPitch,bf)),Pg(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:Vs(s.value,r)}),Sp({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=bn(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,Nt(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 V;const c=this._spaceWalls.length&&s.id&&this._innerRoomContour(e,s.id,n,r)||l,h=ci(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``)} - `}_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=Nt(i);if(!n)return null;const r=e.rooms.filter(e=>e!==i).map(e=>({room:e,poly:Nt(e)})).filter(e=>!!e.poly),o=ci(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)=>Mn(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=hs(e.rooms,i.id,c,s,this._wallKeyPitch,this._cellCm,this._gridPitch,yf);r&&(n=Hs(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)&&Mn([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=Mn([c,h],[t[0],t[1],n[0],n[1]]);(!u||p!!e);return i.length?_n(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=Nt(i);if(!n)return null;const r=e.rooms.filter(e=>e!==i).map(e=>({room:e,poly:Nt(e)})).filter(e=>!!e.poly),o=ci(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)=>Mn(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=hs(e.rooms,i.id,c,s,this._wallKeyPitch,this._cellCm,this._gridPitch,bf);r&&(n=Hs(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)&&Mn([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=Mn([c,h],[t[0],t[1],n[0],n[1]]);(!u||p!!e);return i.length?_n(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` @@ -5307,7 +5307,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 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._activeDraftId)}_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&&nf(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()}_resumeLastDraft(){return this._editorRuntimeOrThrow()._resumeLastDraft()}_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=sa(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.drafts,...t.partitions,...t.columns]:[]}_cleanFloor(e,t,i=this._spaceModel()){if(!i)return{floor:t,geom:null,path:"",area:ua([[[...t,t[0]]]])};const n=e.id||`#${i.rooms.indexOf(e)}`,r=`${i.id}|${this._cfgEpoch}|${n}`;if(!this._resize?.preview){const e=zg(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?ea(c):"",area:ua(c||[[[...t,t[0]]]])};return this._resize?.preview||Ag(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":nd(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":nd(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:Et(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/yf,y:i/yf}}_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 Zn(this._sunGlobal(),this._sunSpace())}_effBgMode(){return Jn(this._sunGlobal(),this._sunSpace())}_dayCycleState(e=new Date){return(this._modeTransitionVisual?.viewWeight??("view"===this._mode?1:0))<=0||"daynight"!==this._effBgMode()?null:Bn(this._renderPlanHass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?qn(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 Qn(this._sunGlobal(),this._sunSpace())}_sunNow(){return null!==this._effNorth()?er(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?er(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:Nt(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=js(c,{x:e.x,y:e.y,angle:e.angle,length:e.length});t.cm>0&&(d[e.id]=po(t.cm,this._cellCm,this._gridPitch))}}let p=Yn(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(ea).filter(Boolean),polys:i.flatMap(_a)}}).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=jn[jn.length-1][1];for(let e=1;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._activeDraftId)}_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&&rf(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()}_resumeLastDraft(){return this._editorRuntimeOrThrow()._resumeLastDraft()}_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=sa(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.drafts,...t.partitions,...t.columns]:[]}_cleanFloor(e,t,i=this._spaceModel()){if(!i)return{floor:t,geom:null,path:"",area:ua([[[...t,t[0]]]])};const n=e.id||`#${i.rooms.indexOf(e)}`,r=`${i.id}|${this._cfgEpoch}|${n}`;if(!this._resize?.preview){const e=Ag(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?ea(c):"",area:ua(c||[[[...t,t[0]]]])};return this._resize?.preview||Pg(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":nd(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":nd(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:Et(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/bf,y:i/bf}}_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 Zn(this._sunGlobal(),this._sunSpace())}_effBgMode(){return Jn(this._sunGlobal(),this._sunSpace())}_dayCycleState(e=new Date){return(this._modeTransitionVisual?.viewWeight??("view"===this._mode?1:0))<=0||"daynight"!==this._effBgMode()?null:Bn(this._renderPlanHass,e)}_syncDayCycleClock(){const e=this._dayCycleState();this._dayCycleClockKey=e?qn(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 Qn(this._sunGlobal(),this._sunSpace())}_sunNow(){return null!==this._effNorth()?er(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?er(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:Nt(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=js(c,{x:e.x,y:e.y,angle:e.angle,length:e.length});t.cm>0&&(d[e.id]=po(t.cm,this._cellCm,this._gridPitch))}}let p=Yn(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(ea).filter(Boolean),polys:i.flatMap(_a)}}).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=jn[jn.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` ${p.map(([e,t])=>W`${this._t("gs.north_letter")} ${null===e?"—":e+"°"} - `}_stageBg(e){const t=this._settingsDialog,i=this._spaceDialog,n=t?t.bgColor||"":Gi(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"}_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 L_(this._glowRuntimeState,this._glowRuntimeHost,e,t)}_forgetGlowSource(e){B_(this._glowRuntimeState,this._glowRuntimeHost,e)}_forgetGlowSpace(e){q_(this._glowRuntimeState,this._glowRuntimeHost,e)}_warnGlowGeometryFallback(e,t,i,n){U_(this._glowRuntimeState,e,t,i,n)}_lightBarriers(e,t){const i=I_({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=zg(this._lightBarrierPool,n);if(r.hit)return this._lightBarrierCache=r.value,r.value.value;const o=O_({space:e,revision:i,walls:this._spaceWalls,zeroWalls:this._zeroWalls(),wallKeyPitch:this._wallKeyPitch,cellCm:this._cellCm,gridPitch:this._gridPitch,coordScale:yf,sharedWallGeometry:this._wallUnionGeometry(),physicalBodies:(t,i)=>(this._lightPhysicalBodiesCache?.key!==i&&(this._lightPhysicalBodiesCache={key:i,all:sa(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,t).all}),this._lightPhysicalBodiesCache.all)}),s={key:n,value:o};return Ag(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:Nt(e)})).filter(e=>!!e.poly),s=o.filter(({r:e})=>bn(t.glow,e));if(!s.length)return this._forgetGlowSpace(e.id),W``;const a=this._lightBarriers(e,o),l=F_({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),H_(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=A_(this._glowRuntimeState,d);u.hit?l=u.value:(l=E_({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)}),P_(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(j_(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=ci(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=V_(this._glowRuntimeState,m,g);return G_({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._kioskScale={...this._kioskScale,...e};try{localStorage.setItem(gf,JSON.stringify(this._kioskScale))}catch{}this.requestUpdate()}_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||"":Gi(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"}_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 B_(this._glowRuntimeState,this._glowRuntimeHost,e,t)}_forgetGlowSource(e){q_(this._glowRuntimeState,this._glowRuntimeHost,e)}_forgetGlowSpace(e){j_(this._glowRuntimeState,this._glowRuntimeHost,e)}_warnGlowGeometryFallback(e,t,i,n){V_(this._glowRuntimeState,e,t,i,n)}_lightBarriers(e,t){const i=O_({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=Ag(this._lightBarrierPool,n);if(r.hit)return this._lightBarrierCache=r.value,r.value.value;const o=E_({space:e,revision:i,walls:this._spaceWalls,zeroWalls:this._zeroWalls(),wallKeyPitch:this._wallKeyPitch,cellCm:this._cellCm,gridPitch:this._gridPitch,coordScale:bf,sharedWallGeometry:this._wallUnionGeometry(),physicalBodies:(t,i)=>(this._lightPhysicalBodiesCache?.key!==i&&(this._lightPhysicalBodiesCache={key:i,all:sa(e,this._cellCm,this._gridPitch,2e-4*this._gridPitch,t).all}),this._lightPhysicalBodiesCache.all)}),s={key:n,value:o};return Pg(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:Nt(e)})).filter(e=>!!e.poly),s=o.filter(({r:e})=>bn(t.glow,e));if(!s.length)return this._forgetGlowSpace(e.id),W``;const a=this._lightBarriers(e,o),l=I_({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),N_(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=P_(this._glowRuntimeState,d);u.hit?l=u.value:(l=H_({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)}),F_(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(W_(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=ci(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=G_(this._glowRuntimeState,m,g);return K_({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._kioskScale={...this._kioskScale,...e};try{localStorage.setItem(ff,JSON.stringify(this._kioskScale))}catch{}this.requestUpdate()}_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} /> @@ -5403,7 +5403,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 ${this._spaceDialog&&(this._onboardingRuntime||this._editorRuntime)?this._renderSpaceDialog():V} ${this._importDialog&&this._onboardingRuntime?this._renderImportDialog():V} ${this._toast?j``:V} - `;const a=this._spaceModel();if(!a)return V;const l="valid"===s.kind?[a]:r,c=a.vb;let h=this._effectiveProjection();this._renderProjection=h,this._labs.active.length&&function(){const e=Bg,t=e.alpha?e.active.join(","):"";if(!t||t===jg)return;jg=t;const i=new Map(Og.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=kp(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,z=this._roomHoverPaths(a),A=a.bg?this._display(a.bg.href):"",P=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,F=this._modeTransitionVisual,I=this._dayCycleState(),O=F?.viewWeight??("view"===this._mode?1:0),E=this._modeTransition.state?.from.presentedMode,H=!this._markup||!!F&&("view"===F.presentedMode||"devices"===F.presentedMode||"view"===E||"devices"===E),N=F?.stageColor||C,L=F?.sceneBrightness??1;return j` + `;const a=this._spaceModel();if(!a)return V;const l="valid"===s.kind?[a]:r,c=a.vb;let h=this._effectiveProjection();this._renderProjection=h,this._labs.active.length&&function(){const e=qg,t=e.alpha?e.active.join(","):"";if(!t||t===Wg)return;Wg=t;const i=new Map(Eg.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=xp(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,z=this._roomHoverPaths(a),A=a.bg?this._display(a.bg.href):"",P=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,F=this._modeTransitionVisual,I=this._dayCycleState(),O=F?.viewWeight??("view"===this._mode?1:0),E=this._modeTransition.state?.from.presentedMode,H=!this._markup||!!F&&("view"===F.presentedMode||"devices"===F.presentedMode||"view"===E||"devices"===E),N=F?.stageColor||C,L=F?.sceneBrightness??1;return j` + transform=${d?vg():V}> ${""} ${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):V} @@ -5619,7 +5619,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 ${this._renderOpeningLocks(S,R?.locks)} ${g.showNames||this._markup?a.rooms.map(e=>this._renderRoomLabel(e,a,S,g,R?.rooms.get(e))):V} ${this._markup?a.rooms.map(e=>this._renderRoomGear(e,a,S)):V} - ${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&&qm(B.settings).enabled?(import("./hp-zigbee-topology-overlay-BxvD87oe.js"),j``):V}
@@ -5712,16 +5712,16 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 `:V} ${this._toast?j``:V} - `;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=nc(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=nc(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=Kh(this._planHass,this._devices,null,this._virtualLights)){const i=ap(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:hp(this._planHass,e,i)}}_stampActivity(e,t,i){let n=this._activityRt.get(e);n||(n=pm(i||"",[]),this._activityRt.set(e,n)),null!=i&&(n.sources=i),mm(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=Kh(this._planHass,this._devices,null,this._virtualLights);for(const n of this._devices){if(n.hidden)continue;if("icon_ripple"!==ki(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&&_m(a,s,o,window.clearTimeout.bind(window)):(a=pm(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"!==ki(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=gm(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"===ki(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),n=lc(this.hass.states[i||""]?.state),r=ec(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"!==_c(e.marker?.vacuum)&&!r?.path.length;!n&&o.moving&&(o.endedTs=Date.now(),s&&o.lastPos&&(o.trail=ac(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=ac(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=ec(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):V}_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])=>jl(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(Jl)){r++;continue}const e=i.filter((e,t)=>0===t||!Ql(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 V;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"===ki(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??ec(this._renderPlanHass?.states[a]?.attributes);if(!l)continue;const c=e?.routes??vc(n.id,n.marker?.vacuum??null,n.space,a),h=e?.resolution??bc({routes:c,observed:wc(c,[a],e=>this._vacObservedMapId(n,e)),spaceIds:new Set(this._model.map(e=>e.id))}),d=e?.server??this._vacSrvTrails[n.id],u=xc({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=_c(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=Yl(b.points),t=this._vacTrailPathD(e,u.previous);t&&s.push(W``)}if(f&&p){const e=Xl(l,y,_?.trail||[]),t=!m||"integration"!==e.source&&"server"!==e.source?e.path:Zl(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]=jl(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]=jl(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=Kh(this._planHass,this._devices,null,this._virtualLights)){const i=lp(this._planHass,e,this._devices,t,this._fullRegistryHass);return{samples:i.samples,sourceKey:dp(this._planHass,e,i)}}_stampActivity(e,t,i){let n=this._activityRt.get(e);n||(n=_m(i||"",[]),this._activityRt.set(e,n)),null!=i&&(n.sources=i),gm(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=Kh(this._planHass,this._devices,null,this._virtualLights);for(const n of this._devices){if(n.hidden)continue;if("icon_ripple"!==ki(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&&mm(a,s,o,window.clearTimeout.bind(window)):(a=_m(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"!==ki(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=fm(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"===ki(e.marker?.display)){this._vacRt.delete(e.id);continue}const t=this._vacSource(e);if(!t)continue;const i=this._vacEntity(e),n=lc(this.hass.states[i||""]?.state),r=ec(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"!==_c(e.marker?.vacuum)&&!r?.path.length;!n&&o.moving&&(o.endedTs=Date.now(),s&&o.lastPos&&(o.trail=ac(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=ac(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=ec(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):V}_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])=>jl(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(Jl)){r++;continue}const e=i.filter((e,t)=>0===t||!Ql(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 V;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"===ki(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??ec(this._renderPlanHass?.states[a]?.attributes);if(!l)continue;const c=e?.routes??vc(n.id,n.marker?.vacuum??null,n.space,a),h=e?.resolution??bc({routes:c,observed:wc(c,[a],e=>this._vacObservedMapId(n,e)),spaceIds:new Set(this._model.map(e=>e.id))}),d=e?.server??this._vacSrvTrails[n.id],u=xc({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=_c(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=Yl(b.points),t=this._vacTrailPathD(e,u.previous);t&&s.push(W``)}if(f&&p){const e=Xl(l,y,_?.trail||[]),t=!m||"integration"!==e.source&&"server"!==e.source?e.path:Zl(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]=jl(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]=jl(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}`:V} - ${o}`:V}_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}%`,...yp(l)],h=l.disabledReason,d=l.haDisabled?this._t(`marker.ha_disabled_${h}`):e.userHidden?this._t("marker.hidden_ghost"):e.name,u=tp(l),p="view"===this._mode||"devices"===this._mode,_=[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||"",Fu(l.valueBadge),null!=l.lqiText&&l.lqiBand?this._t(`marker.lqi_a11y_${l.lqiBand}`,{value:l.lqiText}):""].filter(Boolean).join(", "),m=[e.model,l.valueBadge?.fullText||"",null!=l.lqiText?"LQI "+l.lqiText:""].filter(Boolean).join(" · ");return j`
this._clickDevice(t,e)} @keydown=${t=>this._keyDevice(t,e)} @@ -5752,10 +5752,10 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 @pointercancel=${t=>this._pointerCancel(t,e)} @lostpointercapture=${t=>this._pointerCancel(t,e)} > - ${wp(l,{newDevice:this._newIds.has(e.id),newDeviceTitle:this._t("device.new"),disabledTitle:l.haDisabled?d:""})} + ${kp(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 V;if("static_icon"===ki(e.marker?.display))return V;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 V;const n=this._t(`vac.route_warn_${i}`);return j` - `}_roomArea(e){const t=Nt(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 zn(r.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source;if(t)return md(this._renderPlanHass,t,"temp",this._markers);const i=fd(this._spaceModel()?.id,e);return i?this._climate().get(i)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source;if(t)return md(this._renderPlanHass,t,"hum",this._markers);const i=fd(this._spaceModel()?.id,e);return 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=bd(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*yf,y:i.y*yf};const n=this._roomCenter(e),r=this._gridPitch;return{x:Ha(It(n[0],r)),y:Ha(It(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 V;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=Kh(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=Nt(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 zn(r.area*o*o/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(e){const t=e.settings?.temp_source;if(t)return md(this._renderPlanHass,t,"temp",this._markers);const i=fd(this._spaceModel()?.id,e);return i?this._climate().get(i)?.temp??null:null}_roomHum(e){const t=e.settings?.hum_source;if(t)return md(this._renderPlanHass,t,"hum",this._markers);const i=fd(this._spaceModel()?.id,e);return 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=bd(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*bf,y:i.y*bf};const n=this._roomCenter(e),r=this._gridPitch;return{x:Ha(It(n[0],r)),y:Ha(It(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 V;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=Kh(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}
`:V} `}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=Sn(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=Sn(e.a,e.b);return{x:o,y:s,on45:$n(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} · ${zn(hr(Math.abs(n-t),this._cellCm,this._gridPitch)*hr(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._pos(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=yf,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._editorRuntimeOrThrow()._renderAlignGuides()}_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 Ut(e.type,t?.state,!!e.invert,t?.attributes?.current_position)}_planEntityAvailable(e){return!!e&&(!cd(this._fullRegistryHass,e,ld(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!cd(this._renderPlanHass,e,ld(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=_h(e)){return!!t&&"active"===kh(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`${i.map(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=Sn(e.a,e.b);return{x:o,y:s,on45:$n(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} · ${zn(hr(Math.abs(n-t),this._cellCm,this._gridPitch)*hr(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._pos(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=bf,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._editorRuntimeOrThrow()._renderAlignGuides()}_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 Ut(e.type,t?.state,!!e.invert,t?.attributes?.current_position)}_planEntityAvailable(e){return!!e&&(!cd(this._fullRegistryHass,e,ld(this._markers))&&"active"===this._bindingStatus("entity:"+e).kind)}_renderEntityAvailable(e){return!!e&&(!cd(this._renderPlanHass,e,ld(this._markers))&&(!!this._renderPlanHass.entities?.[e]&&!!this._renderPlanHass.states?.[e]))}_openingEntityAvailable(e){return function(e,t,i=_h(e)){return!!t&&"active"===kh(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`${i.map(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}=Ru(l),u=ba(10,this._cellCm),p=ba(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}=Cu(l),u=ba(10,this._cellCm),p=ba(12,this._cellCm);return W` - ${Au(l)} + ${Pu(l)} @@ -5818,13 +5818,13 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 @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=this._openingLockAnchor(i,o),l=t?.get(String(i.id)),c=l?.visualScene??this._scenePoint(a),h=(c[0]-e.x)/e.w*100,d=(c[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=Ru({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`
{"view"===this._mode&&(e.stopPropagation(),this._openingInfo=i)}}>
`}_renderRoomSource(e){return this._editorRuntimeOrThrow()._renderRoomSource(e)}_renderRoomDialog(){return this._editorRuntimeOrThrow()._renderRoomDialog()}}Mf.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},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_mode:{state:!0},_tool:{state:!0},_wallDialog:{state:!0},_drawWallField:{state:!0},_activeDraftId:{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},_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},_supportDialog:{state:!0},_alignDialog:{state:!0},_preflightClipboardFallback:{state:!0},_backupExportDialog:{state:!0},_backupImportDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0}},Mf.ZOOM_MAX=8,Mf.ZOOM_MIN=1/3,Mf.styles=[lu,Mm],customElements.get("houseplan-card")||customElements.define("houseplan-card",Mf),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${sf} `,"background:#3ea6ff;color:#04121f;font-weight:700","");export{Bp as $,V as A,Zu as B,fp as C,le as D,U as E,yp as F,Fu as G,wp as H,Bm as I,ni as J,wr as K,ai as L,li as M,Sa as N,Rt as O,hi as P,Ia as Q,Xt as R,io as S,Nt as T,vo as U,Rp as V,Cp as W,ts as X,Hr as Y,Co as Z,Mo as _,vc as a,ve as a$,xl as a0,Na as a1,bl as a2,fl as a3,hs as a4,Go as a5,cs as a6,Ps as a7,fs as a8,qt as a9,ld as aA,cd as aB,Bt as aC,pn as aD,Mn as aE,d_ as aF,cr as aG,c_ as aH,cl as aI,ml as aJ,Tl as aK,za as aL,Dl as aM,Jo as aN,Os as aO,Oo as aP,Gs as aQ,fa as aR,Np as aS,Ys as aT,us as aU,qm as aV,Ki as aW,Qn as aX,Jn as aY,Zn as aZ,Gi as a_,Pa as aa,Qd as ab,au as ac,ds as ad,no as ae,ou as af,Zd as ag,Po as ah,ps as ai,eu as aj,Ns as ak,qs as al,Jr as am,eo as an,Fr as ao,Ep as ap,Do as aq,Fa as ar,Ro as as,Ma as at,Ra as au,Oi as av,Ei as aw,Di as ax,zi as ay,Da as az,uc as b,ui as b$,$u as b0,_g as b1,uo as b2,Ha as b3,It as b4,Ot as b5,kr as b6,Xs as b7,Bl as b8,Hp as b9,sr as bA,lr as bB,pr as bC,Sn as bD,or as bE,ar as bF,Ml as bG,gr as bH,Rl as bI,wl as bJ,gl as bK,Cl as bL,Sl as bM,$l as bN,r_ as bO,Fo as bP,Ru as bQ,ru as bR,tf as bS,nu as bT,js as bU,Xg as bV,nf as bW,Tp as bX,Wt as bY,tu as bZ,su as b_,to as ba,Rm as bb,ti as bc,Zt as bd,mi as be,ma as bf,ia as bg,ta as bh,zo as bi,Ao as bj,Is as bk,Et as bl,nl as bm,ua as bn,da as bo,Dn as bp,zn as bq,ri as br,Zo as bs,Xo as bt,jp as bu,Wp as bv,mr as bw,yr as bx,vr as by,hr as bz,j as c,_d as c$,Qt as c0,jt as c1,ei as c2,Io as c3,gi as c4,an as c5,Vu as c6,Gu as c7,Fh as c8,Ld as c9,ye as cA,Se as cB,be as cC,ec as cD,oc as cE,_c as cF,Gl as cG,sc as cH,tc as cI,ic as cJ,pc as cK,hc as cL,jl as cM,kn as cN,xn as cO,Ut as cP,Zg as cQ,Au as cR,Yg as cS,ol as cT,_s as cU,qo as cV,jo as cW,fe as cX,yd as cY,Ku as cZ,Yu as c_,ki as ca,Ri as cb,Tn as cc,wn as cd,od as ce,Jp as cf,Qr as cg,ad as ch,rd as ci,Vi as cj,Wi as ck,ji as cl,ka as cm,Fp as cn,qi as co,Bi as cp,Li as cq,Ni as cr,wa as cs,Kp as ct,qp as cu,ur as cv,Yi as cw,jm as cx,qr as cy,er as cz,Cm as d,Yd as d0,Yh as d1,Kh as d2,Wh as d3,Oh as d4,dn as d5,Ph as d6,sd as d7,ln as d8,up as d9,sa as dA,Ts as dB,ci as dC,vp as dD,zg as dE,Ag as dF,vg as dG,bp as dH,ya as dI,ku as dJ,uu as dK,fu as dL,pu as dM,Ft as dN,Mf as dO,Ou as da,Uh as db,Vh as dc,Eh as dd,Id as de,xi as df,wi as dg,Eu as dh,bi as di,xa as dj,Si as dk,$i as dl,ro as dm,Yt as dn,dd as dp,pd as dq,Aa as dr,ql as ds,lg as dt,cg as du,Mu as dv,dg as dw,il as dx,hg as dy,ug as dz,p_ as e,dc as f,El as g,Tm as h,__ as i,Es as j,ao as k,xu as l,co as m,gc as n,wc as o,lo as p,ba as q,bc as r,Hi as s,po as t,o as u,he as v,W as w,Dt as x,lu as y,Su as z}; +
`}_renderRoomSource(e){return this._editorRuntimeOrThrow()._renderRoomSource(e)}_renderRoomDialog(){return this._editorRuntimeOrThrow()._renderRoomDialog()}}Rf.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},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_mode:{state:!0},_tool:{state:!0},_wallDialog:{state:!0},_drawWallField:{state:!0},_activeDraftId:{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},_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},_supportDialog:{state:!0},_alignDialog:{state:!0},_preflightClipboardFallback:{state:!0},_backupExportDialog:{state:!0},_backupImportDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0}},Rf.ZOOM_MAX=8,Rf.ZOOM_MIN=1/3,Rf.styles=[lu,Rm],customElements.get("houseplan-card")||customElements.define("houseplan-card",Rf),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${af} `,"background:#3ea6ff;color:#04121f;font-weight:700","");export{qp as $,V as A,Ju as B,vp as C,le as D,U as E,bp as F,Iu as G,kp as H,qm as I,ni as J,wr as K,ai as L,li as M,Sa as N,Rt as O,hi as P,Ia as Q,Xt as R,io as S,Nt as T,vo as U,Cp as V,Tp as W,ts as X,Hr as Y,Co as Z,Mo as _,vc as a,ve as a$,xl as a0,Na as a1,bl as a2,fl as a3,hs as a4,Go as a5,cs as a6,Ps as a7,fs as a8,qt as a9,ld as aA,cd as aB,Bt as aC,pn as aD,Mn as aE,u_ as aF,cr as aG,h_ as aH,cl as aI,ml as aJ,Tl as aK,za as aL,Dl as aM,Jo as aN,Os as aO,Oo as aP,Gs as aQ,fa as aR,Lp as aS,Ys as aT,us as aU,jm as aV,Ki as aW,Qn as aX,Jn as aY,Zn as aZ,Gi as a_,Pa as aa,Qd as ab,au as ac,ds as ad,no as ae,ou as af,Zd as ag,Po as ah,ps as ai,eu as aj,Ns as ak,qs as al,Jr as am,eo as an,Fr as ao,Hp as ap,Do as aq,Fa as ar,Ro as as,Ma as at,Ra as au,Oi as av,Ei as aw,Di as ax,zi as ay,Da as az,uc as b,ui as b$,$u as b0,mg as b1,uo as b2,Ha as b3,It as b4,Ot as b5,kr as b6,Xs as b7,Bl as b8,Np as b9,sr as bA,lr as bB,pr as bC,Sn as bD,or as bE,ar as bF,Ml as bG,gr as bH,Rl as bI,wl as bJ,gl as bK,Cl as bL,Sl as bM,$l as bN,o_ as bO,Fo as bP,Cu as bQ,ru as bR,nf as bS,nu as bT,js as bU,Zg as bV,rf as bW,Dp as bX,Wt as bY,tu as bZ,su as b_,to as ba,Cm as bb,ti as bc,Zt as bd,mi as be,ma as bf,ia as bg,ta as bh,zo as bi,Ao as bj,Is as bk,Et as bl,nl as bm,ua as bn,da as bo,Dn as bp,zn as bq,ri as br,Zo as bs,Xo as bt,Wp as bu,Up as bv,mr as bw,yr as bx,vr as by,hr as bz,j as c,_d as c$,Qt as c0,jt as c1,ei as c2,Io as c3,gi as c4,an as c5,Gu as c6,Ku as c7,Fh as c8,Ld as c9,ye as cA,Se as cB,be as cC,ec as cD,oc as cE,_c as cF,Gl as cG,sc as cH,tc as cI,ic as cJ,pc as cK,hc as cL,jl as cM,kn as cN,xn as cO,Ut as cP,Jg as cQ,Pu as cR,Xg as cS,ol as cT,_s as cU,qo as cV,jo as cW,fe as cX,yd as cY,Yu as cZ,Xu as c_,ki as ca,Ri as cb,Tn as cc,wn as cd,od as ce,Qp as cf,Qr as cg,ad as ch,rd as ci,Vi as cj,Wi as ck,ji as cl,ka as cm,Ip as cn,qi as co,Bi as cp,Li as cq,Ni as cr,wa as cs,Yp as ct,jp as cu,ur as cv,Yi as cw,Wm as cx,qr as cy,er as cz,Tm as d,Yd as d0,Yh as d1,Kh as d2,Wh as d3,Oh as d4,dn as d5,Ph as d6,sd as d7,ln as d8,pp as d9,sa as dA,Ts as dB,Ru as dC,ci as dD,yp as dE,Ag as dF,Pg as dG,yg as dH,wp as dI,ya as dJ,ku as dK,uu as dL,fu as dM,pu as dN,Ft as dO,Rf as dP,Eu as da,Uh as db,Vh as dc,Eh as dd,Id as de,xi as df,wi as dg,Hu as dh,bi as di,xa as dj,Si as dk,$i as dl,ro as dm,Yt as dn,dd as dp,pd as dq,Aa as dr,ql as ds,cg as dt,hg as du,Mu as dv,ug as dw,il as dx,dg as dy,pg as dz,__ as e,dc as f,El as g,Dm as h,m_ as i,Es as j,ao as k,xu as l,co as m,gc as n,wc as o,lo as p,ba as q,bc as r,Hi as s,po as t,o as u,he as v,W as w,Dt as x,lu as y,Su as z}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-B8MzWgfl.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BQxfLmCJ.js similarity index 99% rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-B8MzWgfl.js rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BQxfLmCJ.js index a9d926a4..95181916 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-B8MzWgfl.js +++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BQxfLmCJ.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa";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,g as _,h as m,D as g,w as f,N 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 D,y as C,z as P,B as I,C as T,F as z,G as R,H as A,I as F,J as N,K as H,L,M as E,O,P as B,Q as W,R as G,S as j,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 Dt,as as Ct,at as Pt,au as It,av as Tt,aw as zt,ax as Rt,ay as At,az as Ft,aA as Nt,aB as Ht,aC as Lt,aD as Et,aE as Ot,aF as Bt,aG as Wt,aH as Gt,aI as jt,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 De,bi as Ce,bj as Pe,bk as Ie,bl as Te,bm as ze,bn as Re,bo as Ae,bp as Fe,bq as Ne,br as He,bs as Le,bt as Ee,bu as Oe,bv as Be,bw as We,bx as Ge,by as je,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 Ds,c8 as Cs,c9 as Ps,ca as Is,cb as Ts,cc as zs,cd as Rs,ce as As,cf as Fs,cg as Ns,ch as Hs,ci as Ls,cj as Es,ck as Os,cl as Bs,cm as Ws,cn as Gs,co as js,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 Di,c_ as Ci,c$ as Pi,d0 as Ii,d1 as Ti,d2 as zi,d3 as Ri,d4 as Ai,d5 as Fi,d6 as Ni,d7 as Hi,d8 as Li,d9 as Ei,da as Oi,db as Bi,dc as Wi,dd as Gi,de as ji,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}from"./houseplan-card-DlNVdCIc.js";import{F as io,f as oo,p as ao,c as no,s as ro,i as lo,e as ho,r as co,a as po,b as uo,d as _o,g as mo,t as go}from"./backdrop-pick-z06DVBiX.js";import{t as fo,h as bo,m as vo,T as yo}from"./zigbee-topology-CwVLuz6S.js";const $o={},wo=t(class extends e{constructor(){super(...arguments),this.ot=$o}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 ko={"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 xo={en:ko,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 So(t,e,s){return i(xo[t]?.[e]??ko[e]??e,s)}function Mo(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function Do(t,e,s){return{...t,space:s.has(e)?e:""}}function Co(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 Po(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const Io=new WeakMap,To=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function zo(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>So(n,t,e),g=e.marker?.vacuum||{},f=Array.isArray(g.map_routes),b=i._vacSource(e)||"",v=o(e.id,g,e.space,b),y=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),$=new Set(y.map(t=>t.id)),w=h(v,[b],t=>i._vacObservedMapId(e,t)),k=c({routes:v,observed:w,spaceIds:$}),x="ready"===k.kind||"needs_calibration"===k.kind||"missing_space"===k.kind?k.route.id:"",S=b?w[b]:void 0,M=async s=>{let o=f?g.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}(g,e.space,b,t=>Co(t))??[],!b&&Object.keys(g.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=u(o,a,i._cfgContentFingerprint,i._cfgRev,_);i._serverCfg=a,i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return m(i,r,_),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},D=s.candidates.filter(t=>t.entityId!==b&&!v.some(e=>e.source===t.entityId)),C=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 M(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,Co(new Set(v.map(t=>t.id)))))},P=new Map(y.map((t,e)=>[t.id,e])),I=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),T=v.filter(t=>$.has(t.space)).sort((t,e)=>(P.get(t.space)??0)-(P.get(e.space)??0)||I(t,e)),z=v.filter(t=>!$.has(t.space)).sort(I),R=[...T,...z],A=!!b&&void 0!==S&&!v.some(t=>t.source===b&&t.map_id===S);let F=Io.get(t);const N=F?.source||"",H=F?.mapId||"",L=!!F&&v.some(t=>t.source===N&&t.map_id===H);F&&(F.markerId!==e.id||i._vacObservedMapId(e,F.source)!==F.mapId||L&&!F.saving)&&(Io.delete(t),F=void 0),F?.space&&!$.has(F.space)&&(F=Do(F,"",$),Io.set(t,F));const E=s=>p` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d";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,g as _,h as m,D as g,w as f,N 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 D,y as C,z as P,B as I,C as T,F as z,G as R,H as A,I as F,J as N,K as H,L,M as E,O,P as B,Q as W,R as G,S as j,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 Dt,as as Ct,at as Pt,au as It,av as Tt,aw as zt,ax as Rt,ay as At,az as Ft,aA as Nt,aB as Ht,aC as Lt,aD as Et,aE as Ot,aF as Bt,aG as Wt,aH as Gt,aI as jt,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 De,bi as Ce,bj as Pe,bk as Ie,bl as Te,bm as ze,bn as Re,bo as Ae,bp as Fe,bq as Ne,br as He,bs as Le,bt as Ee,bu as Oe,bv as Be,bw as We,bx as Ge,by as je,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 Ds,c8 as Cs,c9 as Ps,ca as Is,cb as Ts,cc as zs,cd as Rs,ce as As,cf as Fs,cg as Ns,ch as Hs,ci as Ls,cj as Es,ck as Os,cl as Bs,cm as Ws,cn as Gs,co as js,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 Di,c_ as Ci,c$ as Pi,d0 as Ii,d1 as Ti,d2 as zi,d3 as Ri,d4 as Ai,d5 as Fi,d6 as Ni,d7 as Hi,d8 as Li,d9 as Ei,da as Oi,db as Bi,dc as Wi,dd as Gi,de as ji,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}from"./houseplan-card-h7CLgil-.js";import{F as io,f as oo,p as ao,c as no,s as ro,i as lo,e as ho,r as co,a as po,b as uo,d as _o,g as mo,t as go}from"./backdrop-pick-BdNxo7sy.js";import{t as fo,h as bo,m as vo,T as yo}from"./zigbee-topology-BPCx22ZF.js";const $o={},wo=t(class extends e{constructor(){super(...arguments),this.ot=$o}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 ko={"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 xo={en:ko,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 So(t,e,s){return i(xo[t]?.[e]??ko[e]??e,s)}function Mo(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function Do(t,e,s){return{...t,space:s.has(e)?e:""}}function Co(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 Po(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const Io=new WeakMap,To=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function zo(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>So(n,t,e),g=e.marker?.vacuum||{},f=Array.isArray(g.map_routes),b=i._vacSource(e)||"",v=o(e.id,g,e.space,b),y=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),$=new Set(y.map(t=>t.id)),w=h(v,[b],t=>i._vacObservedMapId(e,t)),k=c({routes:v,observed:w,spaceIds:$}),x="ready"===k.kind||"needs_calibration"===k.kind||"missing_space"===k.kind?k.route.id:"",S=b?w[b]:void 0,M=async s=>{let o=f?g.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}(g,e.space,b,t=>Co(t))??[],!b&&Object.keys(g.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=u(o,a,i._cfgContentFingerprint,i._cfgRev,_);i._serverCfg=a,i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return m(i,r,_),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},D=s.candidates.filter(t=>t.entityId!==b&&!v.some(e=>e.source===t.entityId)),C=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 M(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,Co(new Set(v.map(t=>t.id)))))},P=new Map(y.map((t,e)=>[t.id,e])),I=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),T=v.filter(t=>$.has(t.space)).sort((t,e)=>(P.get(t.space)??0)-(P.get(e.space)??0)||I(t,e)),z=v.filter(t=>!$.has(t.space)).sort(I),R=[...T,...z],A=!!b&&void 0!==S&&!v.some(t=>t.source===b&&t.map_id===S);let F=Io.get(t);const N=F?.source||"",H=F?.mapId||"",L=!!F&&v.some(t=>t.source===N&&t.map_id===H);F&&(F.markerId!==e.id||i._vacObservedMapId(e,F.source)!==F.mapId||L&&!F.saving)&&(Io.delete(t),F=void 0),F?.space&&!$.has(F.space)&&(F=Do(F,"",$),Io.set(t,F));const E=s=>p`
  • ${s.map_id||r("vac.route_map_default")} @@ -554,7 +554,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 .previewfacts > div { grid-template-columns: minmax(0, 1fr); gap: 2px; } } `],customElements.get("hp-device-preview")||customElements.define("hp-device-preview",fa);const ba={revision:0,topologies:[],states:{}};class va extends M{constructor(){super(...arguments),this.value={enabled:!1,z2mBaseTopics:[]},this.savedEnabled=!1,this.devices=[],this._runtime=null,this._snapshot=ba,this._topicText="zigbee2mqtt",this._invalidTopic=!1}disconnectedCallback(){this._release?.(),this._release=void 0,super.disconnectedCallback()}updated(t){t.has("hass")&&(this._release?.(),this._release=void 0,this._runtime=null,this._snapshot=ba),this.savedEnabled&&this._admin&&this._ensureRuntime()}willUpdate(t){t.has("value")&&(this._topicText=(this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]).join("\n"),this._invalidTopic=!1)}get _admin(){return!0===this.hass?.user?.is_admin}_t(t,e){return fo(l(this.hass),t,e)}_help(){const t=l(this.hass);return bo(t,"help")&&bo(t,"help_aria")?p``:d}async _ensureRuntime(){return this._runtime||(this._runtime=await import("./zigbee-topology-runtime-foMTa-yu.js"),this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this._release=this._runtime.subscribeZigbeeTopology(this.hass,()=>{this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this.requestUpdate()}),this.requestUpdate()),this._runtime}_emit(t){this._admin&&this.dispatchEvent(new CustomEvent("hp-topology-settings-change",{detail:t,bubbles:!0,composed:!0}))}_topics(){return this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]}_editTopics(t){this._topicText=t;const e=t.split(/[\r\n,]+/).map(t=>t.trim()).filter(Boolean),s=e.map(F).filter(Boolean);this._invalidTopic=s.length!==e.length,this._invalidTopic?this.requestUpdate():this._emit({...this.value,z2mBaseTopics:[...new Set(s)].slice(0,8)})}_status(t){const e=this._snapshot.states[t];if(!e)return this._t("status_idle");if("loading"===e.phase)return this._t("status_loading");if("error"===e.phase)return this._t(`error_${e.error||"provider"}`);if("ready"!==e.phase||!e.obtainedAt)return this._t("status_idle");const s=new Date(e.obtainedAt).toLocaleTimeString(l(this.hass),{hour:"2-digit",minute:"2-digit"}),i=this._snapshot.topologies.find(e=>"zha"===t?"zha"===e.provider:`z2m:${e.instanceId}`===t),o=!!i&&!!this.registry&&vo(i,this.devices,this.registry).warnings.length>0;return e.partial||o?this._t("status_partial",{time:s}):i&&!i.links.length?this._t("status_no_links",{time:s}):this._t(Date.now()-e.obtainedAt>yo?"status_stale":"status_ready",{time:s})}_busy(t){return"loading"===this._snapshot.states[t]?.phase}async _readZha(){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).readZhaTopology(this.hass)}async _refreshZ2m(t){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).refreshZ2mTopology(this.hass,t)}render(){const t=this._admin,e=this.value.enabled,s=t&&this.savedEnabled,i=this._topics();return p` + .ariaLabel=${this._t("help_aria")}>`:d}async _ensureRuntime(){return this._runtime||(this._runtime=await import("./zigbee-topology-runtime-PXmJ-UR0.js"),this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this._release=this._runtime.subscribeZigbeeTopology(this.hass,()=>{this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this.requestUpdate()}),this.requestUpdate()),this._runtime}_emit(t){this._admin&&this.dispatchEvent(new CustomEvent("hp-topology-settings-change",{detail:t,bubbles:!0,composed:!0}))}_topics(){return this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]}_editTopics(t){this._topicText=t;const e=t.split(/[\r\n,]+/).map(t=>t.trim()).filter(Boolean),s=e.map(F).filter(Boolean);this._invalidTopic=s.length!==e.length,this._invalidTopic?this.requestUpdate():this._emit({...this.value,z2mBaseTopics:[...new Set(s)].slice(0,8)})}_status(t){const e=this._snapshot.states[t];if(!e)return this._t("status_idle");if("loading"===e.phase)return this._t("status_loading");if("error"===e.phase)return this._t(`error_${e.error||"provider"}`);if("ready"!==e.phase||!e.obtainedAt)return this._t("status_idle");const s=new Date(e.obtainedAt).toLocaleTimeString(l(this.hass),{hour:"2-digit",minute:"2-digit"}),i=this._snapshot.topologies.find(e=>"zha"===t?"zha"===e.provider:`z2m:${e.instanceId}`===t),o=!!i&&!!this.registry&&vo(i,this.devices,this.registry).warnings.length>0;return e.partial||o?this._t("status_partial",{time:s}):i&&!i.links.length?this._t("status_no_links",{time:s}):this._t(Date.now()-e.obtainedAt>yo?"status_stale":"status_ready",{time:s})}_busy(t){return"loading"===this._snapshot.states[t]?.phase}async _readZha(){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).readZhaTopology(this.hass)}async _refreshZ2m(t){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).refreshZ2mTopology(this.hass,t)}render(){const t=this._admin,e=this.value.enabled,s=t&&this.savedEnabled,i=this._topics();return p`
    ${this._t("title")}${this._help()}
    - `}}const oc=(t,e)=>t[0]*e[1]-t[1]*e[0],ac=(t,e)=>t[0]*e[0]+t[1]*e[1],nc=(t,e)=>[t[0]-e[0],t[1]-e[1]],rc=(t,e,s)=>[t[0]+e[0]*s,t[1]+e[1]*s];function lc(t,e,s){return Math.abs(oc(t,e))<=s}function hc(t,e,s){return Math.abs(oc(nc(t,e),s))}function cc(t,e,s,i,o){const a=e[0]-t[0],n=e[1]-t[1],r=Math.hypot(a,n);if(!(r>o&&s>0))return[];const l=[a/r,n/r];return function(t,e,s){const i=e.map(([e,s])=>[Math.max(0,Math.min(e,s)),Math.min(t,Math.max(e,s))]).filter(([t,e])=>e>t+s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of i){const e=o[o.length-1];!e||t[0]>e[1]+s?o.push([...t]):e[1]=Math.max(e[1],t[1])}const a=[];let n=0;for(const[t,e]of o)t>n+s&&a.push([n,t]),n=Math.max(n,e);return t>n+s&&a.push([n,t]),a}(r,i.flatMap(e=>{const i=e.b[0]-e.a[0],a=e.b[1]-e.a[1],n=Math.hypot(i,a);if(!(n>o&&lc(l,[i/n,a/n],1e-6)))return[];if(hc(e.a,t,l)>1.1*Math.max(s,o)||hc(e.b,t,l)>1.1*Math.max(s,o))return[];return[[ac(nc(e.a,t),l),ac(nc(e.b,t),l)]]}),o).flatMap(([e,i])=>{const o=Xt({a:rc(t,l,e),b:rc(t,l,i),halfDepth:s});return o?[o]:[]})}function dc(t){const e=t.coordScale??1,s=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),i=[];for(const s of t.rooms||[]){if(!s?.id)continue;const o=ot(t.rooms,s.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!o||o.poly.length<3)continue;const a=Jt(o.poly,o.offsets);!a||a.length<3||i.push({roomId:s.id,profile:o,inner:a})}i.sort((t,e)=>t.roomId.localeCompare(e.roomId));const o=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,s=[Math.cos(e),Math.sin(e)],i=Math.max(0,t.length)/2;return{a:rc([t.x,t.y],s,-i),b:rc([t.x,t.y],s,i)}}),a=[];for(const i of Yt(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of cc(i.a,i.b,i.depthUnits/2,o,s))a.push({body:t});const n=new Map;for(const e of t.partitionCuts||[]){const t=n.get(e.hostId)||[];t.push(e),n.set(e.hostId,t)}for(const e of t.partitions||[]){const i=x(e.cm,t.cellCm,t.gridPitch)/2;for(const t of cc(e.a,e.b,i,n.get(e.id)||[],s))a.push({body:t,partitionId:e.id})}return{rooms:i,boundaries:a,epsilon:s}}function pc(t,e,s,i){const o=t.profile.offsets[e];if(!(o>0))return null;const a=function(t,e){const s=t[e],i=t[(e+1)%t.length],o=i[0]-s[0],a=i[1]-s[1],n=Math.hypot(o,a)||1;return function(t){let e=0;for(let s=0;s=0?[-a/n,o/n]:[a/n,-o/n]}(t.profile.poly,e),n=rc(s.center,a,o),r=[];for(let e=0;ei&&lc(s.axis,[l[0]/h,l[1]/h],1e-6)))continue;if(hc(o,n,s.axis)>i||hc(a,n,s.axis)>i)continue;const c=ac(nc(o,n),s.axis),d=ac(nc(a,n),s.axis);r.push([Math.min(c,d),Math.max(c,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const s=[];for(const i of t){const t=s[s.length-1];!t||i[0]>t[1]+e?s.push([...i]):t[1]=Math.max(t[1],i[1])}return s}(r,i).find(([t,e])=>t<=i&&e>=-i);if(!l)return null;const[h,c]=l,d=rc(n,s.axis,-s.half),p=rc(n,s.axis,s.half),u=Math.max(0,-s.half-h),_=Math.max(0,c-s.half),m=u>0?rc(n,s.axis,h):d,g=_>0?rc(n,s.axis,c):p,f=ac(a,s.normal)>=0?1:-1,b=(e,i,o)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:s.axis,labelNormal:a,distance:o,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:b(d,m,u),right:b(p,g,_)}}function uc(t){const e=rc(t.center,t.axis,-t.half),s=rc(t.center,t.axis,t.half),i=rc(t.center,t.axis,Math.min(-t.half,t.targetLo)),o=rc(t.center,t.axis,Math.max(t.half,t.targetHi)),a=(e,s)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(s[0]-e[0],s[1]-e[1]),source:"host-end"});return[a(e,i),a(s,o)]}function _c(t,e,s,i){const o=nc(s,e),a=ac(o,o);if(!(a>i*i))return Math.hypot(...nc(t,e))<=i;const n=ac(nc(t,e),o)/a;if(n<-i||n>1+i)return!1;const r=rc(e,o,Math.max(0,Math.min(1,n)));return Math.hypot(...nc(t,r))<=i}function mc(t,e,s){let i=!1;for(let o=0,a=e.length-1;ot[1]!=h>t[1]&&t[0]<(l-n)*(t[1]-r)/(h-r)+n&&(i=!i)}return i}function gc(t,e,s,i,o,a){const n=nc(i,s),r=oc(e,n);if(Math.abs(r)<=a)return null;const l=nc(s,t),h=oc(l,n)/r,c=oc(l,e)/r;return h<-a||h>o+a||c<-a||c>1+a?null:Math.max(0,Math.min(o,h))}function fc(t,e,s){const i=uc(s),o="partition"===t.host?.kind?t.host.id:void 0;return[{base:i[0],direction:[-s.axis[0],-s.axis[1]]},{base:i[1],direction:s.axis}].map(({base:t,direction:s})=>{const i=t.distance,a=function(t,e,s,i,o,a){let n=null;for(const r of i)if(!o||r.partitionId!==o){if(mc(t,r.body,a))return 0;for(let i=0;iac(nc(t,o),s));return{center:o,axis:s,normal:i,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...a),targetHi:Math.max(...a)}}(t),i=e.rooms.flatMap(t=>{const i=function(t,e,s){const{profile:i}=t;let o=null;for(let t=0;t0))continue;const a=i.poly[t],n=i.poly[(t+1)%i.poly.length],r=nc(n,a),l=Math.hypot(r[0],r[1]);if(!(l>s&&lc(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(hc(a,e.center,e.axis)>s||hc(n,e.center,e.axis)>s)continue;const h=ac(nc(a,e.center),e.axis),c=ac(nc(n,e.center),e.axis),d=Math.min(h,c),p=Math.max(h,c);if(d>-e.half+s||p0?d:p<0?-p:0);(!o||u2)return uc(s);if(i.length){const t=i.map(({room:t,edge:i})=>pc(t,i,s,e.epsilon));if(t.some(t=>!t))return uc(s);const o=t;return[...o.map(t=>t.left),...o.map(t=>t.right)]}return fc(t,e,s)}const vc="1.72.0",yc={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},$c={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},wc=2e3,kc=1e3,xc=(t,e,s,i)=>{for(t.delete(e),t.set(e,s);t.size>i;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Sc=1e3,Mc=2e3,Dc=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}},Cc="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa";class Pc{constructor(t){this.host=t,this._junctionBaselineCache=new WeakMap,this._resizePreviewNodes=null,this._resizeBaselineLimits=[],this._resizeBaseFrameStable=!0,this._supportPreviewGeneration=0,this._decorAssetGuardReplace=null,this._undoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this.host._showToast(this.host._t("history.undone",{name:t.name})):this.host._geometryHistory.clear())},this._redoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this.host._showToast(this.host._t("history.redone",{name:t.name})):this.host._geometryHistory.clear())},this._savePhysicalDialog=()=>{const t=this.host._physicalDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=ro(t.cm);if(null==i)return void this._showPhysicalRange("column"===t.kind?Zt:100,"column"===t.kind?1:0);const o=this.host._imperial?2.54*i:i,a="column"===t.kind?Zt:100,n="column"===t.kind?1:0;if(!Number.isFinite(o)||oa)return void this._showPhysicalRange(a,n);if("column"===t.kind){const e=s.wall_columns.find(e=>e.id===t.id);if(!e)return;const i=ro(t.angle||"0");if("circle"!==t.shape&&(null==i||i<0||i>=90))return void this.host._showToast(this.host._t("toast.physical_angle"));const a="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:o}:{id:t.id,shape:"square",center:e.center,cm:o,angle:i};if(s.wall_columns.some(e=>e.id!==t.id&&Qt(e,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const s=(e.partitions||[]).find(e=>e.id===t.id);if(s&&0===o&&te(e.openings,{kind:"partition",id:t.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));s&&(s.cm=o)}else if("column"===t.kind){const s=(e.wall_columns||[]).find(e=>e.id===t.id);s&&(s.cm=ee(o),s.shape="circle"===t.shape?"circle":"square","square"===s.shape?s.angle=ro(t.angle||"0"):delete s.angle)}else{const s=(e.room_drafts||[]).find(e=>e.id===t.id);s?.segments?.[t.segment||0]&&(s.segments[t.segment||0].cm=o)}const l=this._commitPhysicalGeometry(this.host._t("history.physical_edit"),r);this.host._physicalDialog=null,l||this.host.requestUpdate()},this._deletePhysicalSelection=async()=>{const t=this.host._physicalSel,e=this.host._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void await this._deleteDraftWhole();const s=this._geometrySnapshot();if("partition"===t.kind){const s=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(s.length)return void(this.host._partitionDeleteDialog={id:t.id,openings:s.map(t=>JSON.parse(JSON.stringify(t)))})}const i="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[i]=(e[i]||[]).filter(e=>e.id!==t.id),e[i].length||delete e[i],this.host._activeDraftId===t.id&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._confirmPartitionDelete=()=>{const t=this.host._partitionDeleteDialog,e=this.host._curSpaceCfg;if(!t||!e)return;const s=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this.host._partitionDeleteDialog=null,this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._deleteDraftWhole=async()=>{const t="draft"===this.host._physicalDialog?.kind?this.host._physicalDialog.id:"draft"===this.host._physicalSel?.kind?this.host._physicalSel.id:null,e=this.host._space;if(!t||!this.host._curSpaceCfg)return;if(!await this.host._confirmDanger({key:"delete-draft",kind:"destructive",title:this.host._t("confirm.delete_draft_title"),message:this.host._t("confirm.delete_draft_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")})||this.host._space!==e)return;const s=this.host._curSpaceCfg;if(!s||!(s.room_drafts||[]).some(e=>e.id===t))return;const i=this._geometrySnapshot();s.room_drafts=(s.room_drafts||[]).filter(e=>e.id!==t),s.room_drafts.length||delete s.room_drafts,this.host._activeDraftId===t&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),i)},this._deleteDraftSegment=async()=>{const t=this.host._physicalDialog,e=this.host._space;if(!t||"draft"!==t.kind||!this.host._curSpaceCfg)return;const s=t.id,i=t.segment||0,o=await this.host._confirmDanger({key:"delete-draft-segment",kind:"destructive",title:this.host._t("confirm.delete_draft_segment_title"),message:this.host._t("confirm.delete_draft_segment_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._physicalDialog;if(!o||this.host._space!==e||"draft"!==a?.kind||a.id!==s||(a.segment||0)!==i)return;const n=this.host._curSpaceCfg;if(!n)return;const r=(n.room_drafts||[]).findIndex(t=>t.id===s);if(r<0)return;const l=n.room_drafts[r];if(!Array.isArray(l.segments)||!Number.isInteger(i)||i<0||i>=l.segments.length)return;const h=i,c=[],d=l.points.slice(0,h+1),p=l.points.slice(h+1);if(d.length>=2&&c.push({id:l.id,points:d,segments:l.segments.slice(0,h)}),p.length>=2&&c.push({id:c.length?`${l.id}-${Date.now().toString(36)}`:l.id,points:p,segments:l.segments.slice(h+1)}),2===c.length&&n.room_drafts.length>=200)return void this.host._showToast(this.host._t("toast.physical_limit"));const u=this._geometrySnapshot();n.room_drafts.splice(r,1,...c),n.room_drafts.length||delete n.room_drafts,this.host._activeDraftId===l.id&&this._cancelPath(),this.host._physicalDialog=null,this.host._physicalSel=c.length?{kind:"draft",id:c[0].id}:null,this._commitPhysicalGeometry(this.host._t("history.draft_segment_delete"),u)},this._furnShiftListener=t=>{if("Shift"!==t.key)return;const e=this.host._furnPreviewInput;if(!e)return;const s="keydown"===t.type;e.free!==s&&(this.host._furnPreviewInput={...e,free:s},this.host.requestUpdate())},this._furnShiftAttached=!1,this._confirmRoomDelete=t=>{const e=this.host._roomDeleteDialog,s=this.host._curSpaceCfg,i=this.host._spaceModel();if(!e||!s||!i)return;const o=i.rooms.find(t=>t.id===e.roomId);if(!o)return void(this.host._roomDeleteDialog=null);const a=this.host._openCuts(),n=Rh(ut(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc).filter(t=>t.roomId===o.id),i.partitions,this.host._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this.host._gridPitch),r=new Set(n.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(s.partitions||[]).length+r>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const l=this._geometrySnapshot(),h=se(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc);if(t){s.partitions||=[];const t=new Map,e=new Map,i=t=>{const e=(s.wall_segments||[]).find(e=>{const s=[Number(e.a?.[0])*Sc,Number(e.a?.[1])*Sc],i=[Number(e.b?.[0])*Sc,Number(e.b?.[1])*Sc];return this._samePt(t.a,s)&&this._samePt(t.b,i)||this._samePt(t.a,i)&&this._samePt(t.b,s)});return"string"==typeof e?.id&&e.id?e.id:null},o=Date.now().toString(36);for(const a of n.materialize){let n=a.reusePartitionId?s.partitions.find(t=>t.id===a.reusePartitionId):e.get(a.interval.key);n||(n={id:i(a.interval)||`partition-room-${o}-${e.size}`,a:[a.interval.a[0]/Sc,a.interval.a[1]/Sc],b:[a.interval.b[0]/Sc,a.interval.b[1]/Sc],cm:a.interval.cm},s.partitions.push(n),e.set(a.interval.key,n)),t.set(a.interval.key,n)}for(const e of s.openings||[]){const s=n.openingIntervals.get(e.id),i=s?t.get(s):null,o=this.host._openingsR.find(t=>t.id===e.id);if(!i||!o)continue;const a={a:[i.a[0]*Sc,i.a[1]*Sc],b:[i.b[0]*Sc,i.b[1]*Sc]};e.host={kind:"partition",id:i.id,t:Ah([o.rx,o.ry],a)}}}else if(n.removeOpeningIds.length){const t=new Set(n.removeOpeningIds);s.openings=(s.openings||[]).filter(e=>!t.has(e.id)),s.openings.length||delete s.openings}s.rooms=s.rooms.filter(t=>t.id!==o.id),this.host._cfgEpoch++;const c=this.host._normalizeWalls(h,this.host._openCuts());c.length?s.walls=c:delete s.walls,this.host._roomDeleteDialog=null,this._commitPhysicalGeometry(this.host._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this.host._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingRebindId=e,this.host._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this.host._openingPresetRevision},this.host._openingDialog=null,this.host._openingHoverCandidate=null)},this._deviceInboxTabKey=t=>{if("ArrowLeft"!==t.key&&"ArrowRight"!==t.key)return;const e=this.host._deviceInbox;if(!e)return;const s=["on_plan","available","hidden","readd"],i="ArrowRight"===t.key?1:-1,o=(s.indexOf(e.tab)+i+s.length)%s.length;this.host._deviceInbox={...e,tab:s[o],limit:100,onlyNew:!1},t.preventDefault()},this._keepClosedAsPartitions=()=>{if(this.host._wallFaceBatch)return void this._decideWallFace(!1);if(!this.host._contourClosed||this.host._pendingSplit||!this.host._curSpaceCfg)return;const t=this.host._curSpaceCfg,e=this.host._path.slice(0,-1);if((t.partitions||[]).length+e.length>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const s=this._geometrySnapshot(),i=nh(e.length,[...this.host._draftSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,_t);t.partitions||=[];const o=Date.now().toString(36),a=this.host._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this.host._activeDraftId):null,n=this._draftSegmentsForPath(this.host._path,a,i);for(let s=0;st.id!==this.host._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this.host._t("history.contour_to_partitions"),s),this.host._roomDialog=!1,this.host._path=[],delete this.host._resumeDraftBySpace[this.host._space],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null},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"}),e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}},this._openSettingsDialog=()=>{if(!this.host._norm)return;const t=this.host._glowRadiusCm,e=this.host._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this.host._settingsDialog={colors:JSON.parse(JSON.stringify(this.host._fillColors)),glowRadius:e,bgColor:le(this.host._settings,{bgColor:null})||null,northDeg:re(this.host._settings,{}),bgMode:ne(this.host._settings,{}),sunRays:ae(this.host._settings,{}),showRoomTooltip:oe(this.host._settings),zigbeeTopology:ie(this.host._settings),busy:!1}},this._openSupportDialog=()=>{this.host._norm&&this.host._canEdit&&(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPreviewGeneration+=1,this.host._supportDialog={draftId:Jh("draft"),idempotencyKey:Jh("report"),submissionFingerprint:"",contact:"",message:"",attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:"",reportId:""})},this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this.host._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._openBackupExport=()=>{this.host._settingsDialog=null,this.host._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._decorStylePersistTimer=null,this._openRulesDialog=()=>{if(!this.host._norm)return;const t=this.host._settings.icon_rules,e=(t&&t.length?t:he).map(t=>({...t}));this.host._rulesDialog={rules:e,test:"",busy:!1}},this._discoveryPreviewMemo=null,this._decorImages=new ic(t,{decorSnap:(t,e)=>this._decorSnap(t,e),geometrySnapshot:()=>this._geometrySnapshot(),clearFurniturePreview:()=>this._clearFurniturePreview(),recordGeometry:(t,e)=>this._recordGeometry(t,e),saveConfig:()=>this._saveConfig(),saveShape:()=>this._decorSaveShape(),setGuardReplace:t=>{this._decorAssetGuardReplace=t},furnShiftDetach:()=>this._furnShiftDetach(),furnPick:t=>this._furnPick(t),furnFieldValue:t=>this._furnFieldValue(t),furnFieldToCm:t=>this._furnFieldToCm(t)}),t._editorSecondary=new Gh({root:()=>t.renderRoot,requestUpdate:()=>t.requestUpdate(),updateComplete:()=>t.updateComplete,clearTip:()=>{t._tip=null}}),t._resize=new tn}_routeLiveEditorUpdate(t,e){const s=jo(this.host,t,e);return!s&&this.host._resize.preview&&(this._resizeBaseFrameStable=!1),s}_commitLiveEditor(){!function(t){const e=t,s=Bo(t);s.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(s.raf),s.raf=0,Ko(s);const i=e.renderRoot?.querySelector("[data-hp-live-editor]");i&&g(d,i);const o=e.renderRoot?.querySelector("[data-hp-live-editor-html]");if(o){const t=e._viewOr(e._baseVb());g(e._renderLiveEditorMeasurements(t),o)}Wo(s,s.requestedRevision)}(this.host)}_disposeLiveEditor(){!function(t){No(t);const e=Ho.get(t);e&&(e.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e.raf),Ko(e),Wo(e,e.requestedRevision),Ho.delete(t))}(this.host)}async _whenLiveEditorSettled(){await this.host.updateComplete,await function(t){const e=Ho.get(t);if(!e||!e.raf||e.paintedRevision>=e.requestedRevision)return Promise.resolve();const s=e.requestedRevision;return new Promise(t=>e.waiters.push({revision:s,resolve:t}))}(this.host)}_queuePointerMove(t,e){Ao(this.host,t,e)}_flushPointerMove(t){Fo(this.host,t)}_cancelPointerMove(t){No(this.host,t)}_help(t){const e=`${t}.aria`,s=l(this.host.hass,this.host._config?.language);return ce(s,t)&&ce(s,e)?p``}}const oc=(t,e)=>t[0]*e[1]-t[1]*e[0],ac=(t,e)=>t[0]*e[0]+t[1]*e[1],nc=(t,e)=>[t[0]-e[0],t[1]-e[1]],rc=(t,e,s)=>[t[0]+e[0]*s,t[1]+e[1]*s];function lc(t,e,s){return Math.abs(oc(t,e))<=s}function hc(t,e,s){return Math.abs(oc(nc(t,e),s))}function cc(t,e,s,i,o){const a=e[0]-t[0],n=e[1]-t[1],r=Math.hypot(a,n);if(!(r>o&&s>0))return[];const l=[a/r,n/r];return function(t,e,s){const i=e.map(([e,s])=>[Math.max(0,Math.min(e,s)),Math.min(t,Math.max(e,s))]).filter(([t,e])=>e>t+s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of i){const e=o[o.length-1];!e||t[0]>e[1]+s?o.push([...t]):e[1]=Math.max(e[1],t[1])}const a=[];let n=0;for(const[t,e]of o)t>n+s&&a.push([n,t]),n=Math.max(n,e);return t>n+s&&a.push([n,t]),a}(r,i.flatMap(e=>{const i=e.b[0]-e.a[0],a=e.b[1]-e.a[1],n=Math.hypot(i,a);if(!(n>o&&lc(l,[i/n,a/n],1e-6)))return[];if(hc(e.a,t,l)>1.1*Math.max(s,o)||hc(e.b,t,l)>1.1*Math.max(s,o))return[];return[[ac(nc(e.a,t),l),ac(nc(e.b,t),l)]]}),o).flatMap(([e,i])=>{const o=Xt({a:rc(t,l,e),b:rc(t,l,i),halfDepth:s});return o?[o]:[]})}function dc(t){const e=t.coordScale??1,s=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),i=[];for(const s of t.rooms||[]){if(!s?.id)continue;const o=ot(t.rooms,s.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!o||o.poly.length<3)continue;const a=Jt(o.poly,o.offsets);!a||a.length<3||i.push({roomId:s.id,profile:o,inner:a})}i.sort((t,e)=>t.roomId.localeCompare(e.roomId));const o=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,s=[Math.cos(e),Math.sin(e)],i=Math.max(0,t.length)/2;return{a:rc([t.x,t.y],s,-i),b:rc([t.x,t.y],s,i)}}),a=[];for(const i of Yt(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of cc(i.a,i.b,i.depthUnits/2,o,s))a.push({body:t});const n=new Map;for(const e of t.partitionCuts||[]){const t=n.get(e.hostId)||[];t.push(e),n.set(e.hostId,t)}for(const e of t.partitions||[]){const i=x(e.cm,t.cellCm,t.gridPitch)/2;for(const t of cc(e.a,e.b,i,n.get(e.id)||[],s))a.push({body:t,partitionId:e.id})}return{rooms:i,boundaries:a,epsilon:s}}function pc(t,e,s,i){const o=t.profile.offsets[e];if(!(o>0))return null;const a=function(t,e){const s=t[e],i=t[(e+1)%t.length],o=i[0]-s[0],a=i[1]-s[1],n=Math.hypot(o,a)||1;return function(t){let e=0;for(let s=0;s=0?[-a/n,o/n]:[a/n,-o/n]}(t.profile.poly,e),n=rc(s.center,a,o),r=[];for(let e=0;ei&&lc(s.axis,[l[0]/h,l[1]/h],1e-6)))continue;if(hc(o,n,s.axis)>i||hc(a,n,s.axis)>i)continue;const c=ac(nc(o,n),s.axis),d=ac(nc(a,n),s.axis);r.push([Math.min(c,d),Math.max(c,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const s=[];for(const i of t){const t=s[s.length-1];!t||i[0]>t[1]+e?s.push([...i]):t[1]=Math.max(t[1],i[1])}return s}(r,i).find(([t,e])=>t<=i&&e>=-i);if(!l)return null;const[h,c]=l,d=rc(n,s.axis,-s.half),p=rc(n,s.axis,s.half),u=Math.max(0,-s.half-h),_=Math.max(0,c-s.half),m=u>0?rc(n,s.axis,h):d,g=_>0?rc(n,s.axis,c):p,f=ac(a,s.normal)>=0?1:-1,b=(e,i,o)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:s.axis,labelNormal:a,distance:o,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:b(d,m,u),right:b(p,g,_)}}function uc(t){const e=rc(t.center,t.axis,-t.half),s=rc(t.center,t.axis,t.half),i=rc(t.center,t.axis,Math.min(-t.half,t.targetLo)),o=rc(t.center,t.axis,Math.max(t.half,t.targetHi)),a=(e,s)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(s[0]-e[0],s[1]-e[1]),source:"host-end"});return[a(e,i),a(s,o)]}function _c(t,e,s,i){const o=nc(s,e),a=ac(o,o);if(!(a>i*i))return Math.hypot(...nc(t,e))<=i;const n=ac(nc(t,e),o)/a;if(n<-i||n>1+i)return!1;const r=rc(e,o,Math.max(0,Math.min(1,n)));return Math.hypot(...nc(t,r))<=i}function mc(t,e,s){let i=!1;for(let o=0,a=e.length-1;ot[1]!=h>t[1]&&t[0]<(l-n)*(t[1]-r)/(h-r)+n&&(i=!i)}return i}function gc(t,e,s,i,o,a){const n=nc(i,s),r=oc(e,n);if(Math.abs(r)<=a)return null;const l=nc(s,t),h=oc(l,n)/r,c=oc(l,e)/r;return h<-a||h>o+a||c<-a||c>1+a?null:Math.max(0,Math.min(o,h))}function fc(t,e,s){const i=uc(s),o="partition"===t.host?.kind?t.host.id:void 0;return[{base:i[0],direction:[-s.axis[0],-s.axis[1]]},{base:i[1],direction:s.axis}].map(({base:t,direction:s})=>{const i=t.distance,a=function(t,e,s,i,o,a){let n=null;for(const r of i)if(!o||r.partitionId!==o){if(mc(t,r.body,a))return 0;for(let i=0;iac(nc(t,o),s));return{center:o,axis:s,normal:i,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...a),targetHi:Math.max(...a)}}(t),i=e.rooms.flatMap(t=>{const i=function(t,e,s){const{profile:i}=t;let o=null;for(let t=0;t0))continue;const a=i.poly[t],n=i.poly[(t+1)%i.poly.length],r=nc(n,a),l=Math.hypot(r[0],r[1]);if(!(l>s&&lc(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(hc(a,e.center,e.axis)>s||hc(n,e.center,e.axis)>s)continue;const h=ac(nc(a,e.center),e.axis),c=ac(nc(n,e.center),e.axis),d=Math.min(h,c),p=Math.max(h,c);if(d>-e.half+s||p0?d:p<0?-p:0);(!o||u2)return uc(s);if(i.length){const t=i.map(({room:t,edge:i})=>pc(t,i,s,e.epsilon));if(t.some(t=>!t))return uc(s);const o=t;return[...o.map(t=>t.left),...o.map(t=>t.right)]}return fc(t,e,s)}const vc="1.72.0",yc={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},$c={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},wc=2e3,kc=1e3,xc=(t,e,s,i)=>{for(t.delete(e),t.set(e,s);t.size>i;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Sc=1e3,Mc=2e3,Dc=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}},Cc="ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d";class Pc{constructor(t){this.host=t,this._junctionBaselineCache=new WeakMap,this._resizePreviewNodes=null,this._resizeBaselineLimits=[],this._resizeBaseFrameStable=!0,this._supportPreviewGeneration=0,this._decorAssetGuardReplace=null,this._undoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this.host._showToast(this.host._t("history.undone",{name:t.name})):this.host._geometryHistory.clear())},this._redoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this.host._showToast(this.host._t("history.redone",{name:t.name})):this.host._geometryHistory.clear())},this._savePhysicalDialog=()=>{const t=this.host._physicalDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=ro(t.cm);if(null==i)return void this._showPhysicalRange("column"===t.kind?Zt:100,"column"===t.kind?1:0);const o=this.host._imperial?2.54*i:i,a="column"===t.kind?Zt:100,n="column"===t.kind?1:0;if(!Number.isFinite(o)||oa)return void this._showPhysicalRange(a,n);if("column"===t.kind){const e=s.wall_columns.find(e=>e.id===t.id);if(!e)return;const i=ro(t.angle||"0");if("circle"!==t.shape&&(null==i||i<0||i>=90))return void this.host._showToast(this.host._t("toast.physical_angle"));const a="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:o}:{id:t.id,shape:"square",center:e.center,cm:o,angle:i};if(s.wall_columns.some(e=>e.id!==t.id&&Qt(e,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const s=(e.partitions||[]).find(e=>e.id===t.id);if(s&&0===o&&te(e.openings,{kind:"partition",id:t.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));s&&(s.cm=o)}else if("column"===t.kind){const s=(e.wall_columns||[]).find(e=>e.id===t.id);s&&(s.cm=ee(o),s.shape="circle"===t.shape?"circle":"square","square"===s.shape?s.angle=ro(t.angle||"0"):delete s.angle)}else{const s=(e.room_drafts||[]).find(e=>e.id===t.id);s?.segments?.[t.segment||0]&&(s.segments[t.segment||0].cm=o)}const l=this._commitPhysicalGeometry(this.host._t("history.physical_edit"),r);this.host._physicalDialog=null,l||this.host.requestUpdate()},this._deletePhysicalSelection=async()=>{const t=this.host._physicalSel,e=this.host._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void await this._deleteDraftWhole();const s=this._geometrySnapshot();if("partition"===t.kind){const s=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(s.length)return void(this.host._partitionDeleteDialog={id:t.id,openings:s.map(t=>JSON.parse(JSON.stringify(t)))})}const i="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[i]=(e[i]||[]).filter(e=>e.id!==t.id),e[i].length||delete e[i],this.host._activeDraftId===t.id&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._confirmPartitionDelete=()=>{const t=this.host._partitionDeleteDialog,e=this.host._curSpaceCfg;if(!t||!e)return;const s=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this.host._partitionDeleteDialog=null,this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._deleteDraftWhole=async()=>{const t="draft"===this.host._physicalDialog?.kind?this.host._physicalDialog.id:"draft"===this.host._physicalSel?.kind?this.host._physicalSel.id:null,e=this.host._space;if(!t||!this.host._curSpaceCfg)return;if(!await this.host._confirmDanger({key:"delete-draft",kind:"destructive",title:this.host._t("confirm.delete_draft_title"),message:this.host._t("confirm.delete_draft_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")})||this.host._space!==e)return;const s=this.host._curSpaceCfg;if(!s||!(s.room_drafts||[]).some(e=>e.id===t))return;const i=this._geometrySnapshot();s.room_drafts=(s.room_drafts||[]).filter(e=>e.id!==t),s.room_drafts.length||delete s.room_drafts,this.host._activeDraftId===t&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),i)},this._deleteDraftSegment=async()=>{const t=this.host._physicalDialog,e=this.host._space;if(!t||"draft"!==t.kind||!this.host._curSpaceCfg)return;const s=t.id,i=t.segment||0,o=await this.host._confirmDanger({key:"delete-draft-segment",kind:"destructive",title:this.host._t("confirm.delete_draft_segment_title"),message:this.host._t("confirm.delete_draft_segment_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._physicalDialog;if(!o||this.host._space!==e||"draft"!==a?.kind||a.id!==s||(a.segment||0)!==i)return;const n=this.host._curSpaceCfg;if(!n)return;const r=(n.room_drafts||[]).findIndex(t=>t.id===s);if(r<0)return;const l=n.room_drafts[r];if(!Array.isArray(l.segments)||!Number.isInteger(i)||i<0||i>=l.segments.length)return;const h=i,c=[],d=l.points.slice(0,h+1),p=l.points.slice(h+1);if(d.length>=2&&c.push({id:l.id,points:d,segments:l.segments.slice(0,h)}),p.length>=2&&c.push({id:c.length?`${l.id}-${Date.now().toString(36)}`:l.id,points:p,segments:l.segments.slice(h+1)}),2===c.length&&n.room_drafts.length>=200)return void this.host._showToast(this.host._t("toast.physical_limit"));const u=this._geometrySnapshot();n.room_drafts.splice(r,1,...c),n.room_drafts.length||delete n.room_drafts,this.host._activeDraftId===l.id&&this._cancelPath(),this.host._physicalDialog=null,this.host._physicalSel=c.length?{kind:"draft",id:c[0].id}:null,this._commitPhysicalGeometry(this.host._t("history.draft_segment_delete"),u)},this._furnShiftListener=t=>{if("Shift"!==t.key)return;const e=this.host._furnPreviewInput;if(!e)return;const s="keydown"===t.type;e.free!==s&&(this.host._furnPreviewInput={...e,free:s},this.host.requestUpdate())},this._furnShiftAttached=!1,this._confirmRoomDelete=t=>{const e=this.host._roomDeleteDialog,s=this.host._curSpaceCfg,i=this.host._spaceModel();if(!e||!s||!i)return;const o=i.rooms.find(t=>t.id===e.roomId);if(!o)return void(this.host._roomDeleteDialog=null);const a=this.host._openCuts(),n=Rh(ut(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc).filter(t=>t.roomId===o.id),i.partitions,this.host._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this.host._gridPitch),r=new Set(n.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(s.partitions||[]).length+r>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const l=this._geometrySnapshot(),h=se(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc);if(t){s.partitions||=[];const t=new Map,e=new Map,i=t=>{const e=(s.wall_segments||[]).find(e=>{const s=[Number(e.a?.[0])*Sc,Number(e.a?.[1])*Sc],i=[Number(e.b?.[0])*Sc,Number(e.b?.[1])*Sc];return this._samePt(t.a,s)&&this._samePt(t.b,i)||this._samePt(t.a,i)&&this._samePt(t.b,s)});return"string"==typeof e?.id&&e.id?e.id:null},o=Date.now().toString(36);for(const a of n.materialize){let n=a.reusePartitionId?s.partitions.find(t=>t.id===a.reusePartitionId):e.get(a.interval.key);n||(n={id:i(a.interval)||`partition-room-${o}-${e.size}`,a:[a.interval.a[0]/Sc,a.interval.a[1]/Sc],b:[a.interval.b[0]/Sc,a.interval.b[1]/Sc],cm:a.interval.cm},s.partitions.push(n),e.set(a.interval.key,n)),t.set(a.interval.key,n)}for(const e of s.openings||[]){const s=n.openingIntervals.get(e.id),i=s?t.get(s):null,o=this.host._openingsR.find(t=>t.id===e.id);if(!i||!o)continue;const a={a:[i.a[0]*Sc,i.a[1]*Sc],b:[i.b[0]*Sc,i.b[1]*Sc]};e.host={kind:"partition",id:i.id,t:Ah([o.rx,o.ry],a)}}}else if(n.removeOpeningIds.length){const t=new Set(n.removeOpeningIds);s.openings=(s.openings||[]).filter(e=>!t.has(e.id)),s.openings.length||delete s.openings}s.rooms=s.rooms.filter(t=>t.id!==o.id),this.host._cfgEpoch++;const c=this.host._normalizeWalls(h,this.host._openCuts());c.length?s.walls=c:delete s.walls,this.host._roomDeleteDialog=null,this._commitPhysicalGeometry(this.host._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this.host._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingRebindId=e,this.host._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this.host._openingPresetRevision},this.host._openingDialog=null,this.host._openingHoverCandidate=null)},this._deviceInboxTabKey=t=>{if("ArrowLeft"!==t.key&&"ArrowRight"!==t.key)return;const e=this.host._deviceInbox;if(!e)return;const s=["on_plan","available","hidden","readd"],i="ArrowRight"===t.key?1:-1,o=(s.indexOf(e.tab)+i+s.length)%s.length;this.host._deviceInbox={...e,tab:s[o],limit:100,onlyNew:!1},t.preventDefault()},this._keepClosedAsPartitions=()=>{if(this.host._wallFaceBatch)return void this._decideWallFace(!1);if(!this.host._contourClosed||this.host._pendingSplit||!this.host._curSpaceCfg)return;const t=this.host._curSpaceCfg,e=this.host._path.slice(0,-1);if((t.partitions||[]).length+e.length>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const s=this._geometrySnapshot(),i=nh(e.length,[...this.host._draftSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,_t);t.partitions||=[];const o=Date.now().toString(36),a=this.host._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this.host._activeDraftId):null,n=this._draftSegmentsForPath(this.host._path,a,i);for(let s=0;st.id!==this.host._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this.host._t("history.contour_to_partitions"),s),this.host._roomDialog=!1,this.host._path=[],delete this.host._resumeDraftBySpace[this.host._space],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null},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"}),e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}},this._openSettingsDialog=()=>{if(!this.host._norm)return;const t=this.host._glowRadiusCm,e=this.host._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this.host._settingsDialog={colors:JSON.parse(JSON.stringify(this.host._fillColors)),glowRadius:e,bgColor:le(this.host._settings,{bgColor:null})||null,northDeg:re(this.host._settings,{}),bgMode:ne(this.host._settings,{}),sunRays:ae(this.host._settings,{}),showRoomTooltip:oe(this.host._settings),zigbeeTopology:ie(this.host._settings),busy:!1}},this._openSupportDialog=()=>{this.host._norm&&this.host._canEdit&&(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPreviewGeneration+=1,this.host._supportDialog={draftId:Jh("draft"),idempotencyKey:Jh("report"),submissionFingerprint:"",contact:"",message:"",attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:"",reportId:""})},this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this.host._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._openBackupExport=()=>{this.host._settingsDialog=null,this.host._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._decorStylePersistTimer=null,this._openRulesDialog=()=>{if(!this.host._norm)return;const t=this.host._settings.icon_rules,e=(t&&t.length?t:he).map(t=>({...t}));this.host._rulesDialog={rules:e,test:"",busy:!1}},this._discoveryPreviewMemo=null,this._decorImages=new ic(t,{decorSnap:(t,e)=>this._decorSnap(t,e),geometrySnapshot:()=>this._geometrySnapshot(),clearFurniturePreview:()=>this._clearFurniturePreview(),recordGeometry:(t,e)=>this._recordGeometry(t,e),saveConfig:()=>this._saveConfig(),saveShape:()=>this._decorSaveShape(),setGuardReplace:t=>{this._decorAssetGuardReplace=t},furnShiftDetach:()=>this._furnShiftDetach(),furnPick:t=>this._furnPick(t),furnFieldValue:t=>this._furnFieldValue(t),furnFieldToCm:t=>this._furnFieldToCm(t)}),t._editorSecondary=new Gh({root:()=>t.renderRoot,requestUpdate:()=>t.requestUpdate(),updateComplete:()=>t.updateComplete,clearTip:()=>{t._tip=null}}),t._resize=new tn}_routeLiveEditorUpdate(t,e){const s=jo(this.host,t,e);return!s&&this.host._resize.preview&&(this._resizeBaseFrameStable=!1),s}_commitLiveEditor(){!function(t){const e=t,s=Bo(t);s.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(s.raf),s.raf=0,Ko(s);const i=e.renderRoot?.querySelector("[data-hp-live-editor]");i&&g(d,i);const o=e.renderRoot?.querySelector("[data-hp-live-editor-html]");if(o){const t=e._viewOr(e._baseVb());g(e._renderLiveEditorMeasurements(t),o)}Wo(s,s.requestedRevision)}(this.host)}_disposeLiveEditor(){!function(t){No(t);const e=Ho.get(t);e&&(e.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e.raf),Ko(e),Wo(e,e.requestedRevision),Ho.delete(t))}(this.host)}async _whenLiveEditorSettled(){await this.host.updateComplete,await function(t){const e=Ho.get(t);if(!e||!e.raf||e.paintedRevision>=e.requestedRevision)return Promise.resolve();const s=e.requestedRevision;return new Promise(t=>e.waiters.push({revision:s,resolve:t}))}(this.host)}_queuePointerMove(t,e){Ao(this.host,t,e)}_flushPointerMove(t){Fo(this.host,t)}_cancelPointerMove(t){No(this.host,t)}_help(t){const e=`${t}.aria`,s=l(this.host.hass,this.host._config?.language);return ce(s,t)&&ce(s,e)?p``:d}_setMode(t,e=!0){t!==this.host._mode&&this.host._cancelDangerConfirm(),this.host._endTabDrag(),this._clearFurniturePreview(),this.host._pendingNavMode=null;const s=this.host._spaceModel();if(!s)return this.host._cancelModeTransition(!1),void(this.host._mode="view");if(this.host._kiosk&&"view"!==t)return;if(this.host._mode===t){if(!e&&"view"===t&&this.host._modeTransitionBusy){const e=this.host._currentModeVisual(t),s=this.host._modeTransitionTargetZoom,i=this.host._modeTransitionTargetCenterX,o=this.host._modeTransitionTargetCenterY;this.host._cancelModeTransition(!1),this.host._commitViewModeAtomic(e,s,i,o)}return}if("devices"===this.host._mode&&this.host._cancelDeviceDrag(),this.host._bootSoftCancel(),("plan"===t||"decor"===t)&&!this.host._norm)return void this.host._showToast(this.host._t("toast.markup_needs_server"));if(this.host._wallFaceBatch&&this._roomDialogCancel(),"plan"===this.host._mode&&"draw"===this.host._tool&&!this._finishWallChain())return;this.host._clearTransientHover(!0),this.host._cancelDevicePressFeedback();const i=this.host._mode,o=this.host._effectiveProjection(),a=this.host._currentModeVisual(i),n=this.host._modeTransitionBusy,r=a&&"view"!==i&&"view"!==t?{...a,toolbarContentOpacity:this.host._reducedMotion?1:.35}:a;this.host._cancelModeTransition(!1),this.host._editorSecondary.closeForNavigation(),(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)&&this._cancelDecorGesture();const l=!s.bg&&"view"===t!=("view"===i),h=n&&"view"===i&&"view"!==t?this.host._modeTransitionEditorCamera:null;let c=h?.zoom??(n?this.host._modeTransitionTargetZoom:this.host._zoom),d=h?h.centerX:n?this.host._modeTransitionTargetCenterX:r?.viewport.centerX,p=h?h.centerY:n?this.host._modeTransitionTargetCenterY:r?.viewport.centerY;if("view"===i&&"view"!==t&&!n){const e=this.host._view;if(this.host._viewModeSnap={space:this.host._space,zoom:this.host._zoom,cx:e?this.host._logicalViewCenter(o)?.x:void 0,cy:e?this.host._logicalViewCenter(o)?.y:void 0},"iso"===o){const e=this.host._logicalViewCenter("iso");d=e?.x,p=e?.y,this.host._view=null,this.host._mode=t,this.host._applyView(this.host._zoom,e?.x,e?.y)}l&&(c=1,d=void 0,p=void 0)}if("plan"===i&&this.host._activeDraftId&&(this.host._resumeDraftBySpace[this.host._space]=this.host._activeDraftId),this.host._mode=t,"devices"===i&&"devices"!==t&&(this.host._showHidden=!1,this.host._deviceInbox=null,this.host._deviceInboxReturn=null,this.host._deviceInboxMemo=null),this.host._editorChromeMode="view"===t?i:t,"view"===t){"view"===i||n||(this.host._modeTransitionEditorCamera={zoom:this.host._zoom,centerX:r?.viewport.centerX,centerY:r?.viewport.centerY});const t=this.host._viewModeSnap;if(t&&t.space===this.host._space){c=t.zoom;const e=this.host._labsIso&&"iso"===this.host._viewPreference[this.host._space]?"iso":"flat",s=null!=t.cx&&null!=t.cy&&"iso"===e?de([t.cx,t.cy],0):null;d=s?.[0]??t.cx,p=s?.[1]??t.cy}else t&&(c=this.host._zoomBySpace[this.host._space]||1,d=void 0,p=void 0)}else this.host._modeTransitionEditorCamera={zoom:c,centerX:d,centerY:p};this.host._modeTransitionTargetZoom=c,this.host._modeTransitionTargetCenterX=d,this.host._modeTransitionTargetCenterY=p,("iso"===o||"view"===t&&this.host._labsIso&&"iso"===this.host._viewPreference[this.host._space])&&(this.host._modeTransitionForceAtomic=!0);const u=++this.host._modeTransitionRequest;e?r?(this.host._modeTransitionPreparing=!0,this.host._modeTransitionVisual=r,this.host._prepareModeTransition(u,r,t,c,d,p)):(this.host._modeTransitionPreparing=!1,this.host._modeTransitionVisual=null,this.host._zoom=c,this.host._view=null,requestAnimationFrame(()=>{this.host.isConnected&&u===this.host._modeTransitionRequest&&this.host._mode===t&&(this.host._applyView(c,d,p),"view"===t&&(this.host._viewModeSnap=null,this.host._modeTransitionEditorCamera=null),this.host.requestUpdate())})):"view"===t&&this.host._commitViewModeAtomic(r,c,d,p),this.host._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this.host._tool="draw",this.host._mergeSel=null,this.host._mergeDialog=null,this.host._splitSel=null,this.host._pendingSplit=null,this.host._selId=null,this.host._physicalSel=null,this.host._physicalDialog=null,this.host._physicalDrag=null,this._rszResetController(),this.host._tip=null,this.host._hoverRoom=null,this.host._decorDraft=null,this.host._decorSel=null,this.host._decorMove=null,this.host._backdropDialog=null,this.host._decorTool="select",this.host._bdDrag=null,this.host._dtDrag=null,this.host._dtBox=null,"plan"===t&&(this._primeDrawWallField(),this._resumeLastDraft()),this.host._saveNav()}_primeDrawWallField(){null===this.host._drawWallField&&(this.host._drawWallField=pe(_t,this.host._imperial))}_showPhysicalRange(t=this.host._drawWallMaxCm,e=0){this.host._showToast(this.host._t("toast.physical_range",{min:pe(e,this.host._imperial),max:pe(t,this.host._imperial),unit:this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")}))}_draftSegmentCount(t=this.host._curSpaceCfg){return(t?.room_drafts||[]).reduce((t,e)=>t+(Array.isArray(e.segments)?e.segments.length:0),0)}_mergeSpacePartitions(t,e){const s=t?.partitions||[];if(s.length<2)return 0;const i=Vr(s,{pitch:W,seedIds:e,geometry:Yr(t,{excludeDraftId:this.host._activeDraftId})});return i.merged?(t.partitions=i.partitions,Jr(t.openings,t.partitions,i.openingMoves,{coordScale:Sc,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch}),i.merged):0}_finishWallChain(){if("draw"!==this.host._tool||this.host._wallFaceBatch||this.host._roomDialog)return!0;const t=this.host._curSpaceCfg;if(!t||this.host._path.length<2)return this.host._path=[],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),!0;const e=rh(this.host._path,nh(this.host._path.length-1,this.host._draftSegmentCms,this.host._drawWallCm,_t)),s=e.length;if((t.partitions||[]).length+s>Mc)return this.host._showToast(this.host._t("toast.physical_limit")),!1;const i=this._geometrySnapshot();t.partitions||=[];const o=Date.now().toString(36),a=[],n=this.host._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this.host._activeDraftId):null,r=this._draftSegmentsForPath(this.host._path,n,e.map(t=>t.cm));for(let i=0;it.id!==this.host._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this.host._t("history.wall_chain_finish"),i),delete this.host._resumeDraftBySpace[this.host._space],this.host._path=[],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),!0}_activateMarkupTool(t){t!==this.host._tool&&(this.host._wallFaceBatch&&this._roomDialogCancel(),("draw"!==this.host._tool||this._finishWallChain())&&(this._cancelPath(),"resize"===this.host._tool&&(this.host._resize.dragging?this._rszCancelDrag():this.host._resize.reset()),this.host._tool=t,"draw"===t&&this._resumeLastDraft(),"resize"===t&&this.host._resize.selectRoom(null),"wallthick"===t&&(this.host._wallDialog=null)))}_limitReached(t){const e=this.host._curSpaceCfg;if(!e)return!0;const s="draft"===t?(e.room_drafts||[]).length>=200:"partition"===t?(e.partitions||[]).length>=Mc:(e.wall_columns||[]).length>=500;return s&&this.host._showToast(this.host._t("toast.physical_limit")),s}_svgPoint(t){const e=this.host.renderRoot.querySelector(".stage").getBoundingClientRect();return this.host._screenToVb(t.clientX-e.left,t.clientY-e.top)}_snap(t){const e=this.host._gridPitch;return[ue(_e(t[0],e)),ue(_e(t[1],e))]}_snapDrawPoint(t,e=!1){const s=this.host._path[this.host._path.length-1],i=e&&s?me(s,t,this.host._gridPitch,so):t;return this._snap(i)}_planSnapOpeningCuts(t,e){if(!this.host._openingsR.length)return[];const s=this.host._openingWallIndexFor(t,e).value,i=[];for(const e of this.host._roomWallOpeningInputs(this.host._openingsR,t)){const t=$t(s,e);if(!t.negative&&!t.positive)continue;const o=e.angle*Math.PI/180,a=Math.cos(o)*e.length/2,n=Math.sin(o)*e.length/2;i.push([e.x-a,e.y-n,e.x+a,e.y+n])}return i}_planSnapGeometrySnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|empty`,value:{segments:[],endpoints:[]}};const e=[this.host._space,this.host._cfgEpoch,this.host._activeDraftId||"",t.rooms.length,t.room_drafts.length,t.partitions.length].join("|");if(this.host._planSnapGeometryCache?.key===e)return this.host._planSnapGeometryCache;const s=this.host._openCuts(),i=Zl({space:t,activeDraftId:this.host._activeDraftId,roomCuts:this._planSnapOpeningCuts(t,s),partitionCuts:this._partitionOpeningCuts(t),epsilon:2e-4*this.host._gridPitch});return this.host._planSnapGeometryCache={key:e,value:i},this.host._planSnapGeometryCache}_hiddenWallDiagnosticSnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|hidden-empty`,value:{segments:[],endpoints:[]}};const e=["hidden",this.host._space,this.host._cfgEpoch,this.host._activeDraftId||"",t.rooms.length,t.room_drafts.length,t.partitions.length].join("|");if(this.host._hiddenWallDiagnosticCache?.key===e)return this.host._hiddenWallDiagnosticCache;const s=Xl({space:t,activeDraftId:this.host._activeDraftId,epsilon:2e-4*this.host._gridPitch});return this.host._hiddenWallDiagnosticCache={key:e,value:s},this.host._hiddenWallDiagnosticCache}_planStructuralGeometrySnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|structural-empty`,value:{segments:[],endpoints:[]}};const e=["structural",this.host._space,this.host._cfgEpoch,this.host._activeDraftId||"",t.rooms.length,t.room_drafts.length,t.partitions.length].join("|");if(this.host._planStructuralGeometryCache?.key===e)return this.host._planStructuralGeometryCache;const s=Zl({space:t,activeDraftId:this.host._activeDraftId,epsilon:2e-4*this.host._gridPitch});return this.host._planStructuralGeometryCache={key:e,value:s},this.host._planStructuralGeometryCache}_planSnapContextKey(t){const e=this.host._path[0],s=this.host._path[this.host._path.length-1];return[t,this.host._tool,this.host._path.length,e?`${e[0]},${e[1]}`:"",s?`${s[0]},${s[1]}`:""].join("|")}_resolvePlanDrawPoint(t,e){const s=this._planSnapGeometrySnapshot(),i=this.host._path[this.host._path.length-1],o="draw"===this.host._tool&&this.host._path.length>=3?[{point:this.host._path[0],key:"closure:first-point"}]:[],a={tolerance:this._cssPxToRender(12),distinguishTolerance:this._cssPxToRender(8),gridStep:this.host._gridPitch,excludePoints:i?[i]:[],extraEndpoints:o,epsilon:2e-4*this.host._gridPitch},n=e&&i?oh(s.value,t,{...a,anchor:i}):function(t,e,s){if(!(Gl(e)&&s.tolerance>=0))return{kind:"none",candidate:null,conflicts:[]};const i=s.epsilon??Wl,o=s.excludePoints||[],a=sh(eh(t,e,s),s.distinguishTolerance||0);if(a)return a;let n=null;for(const a of t.segments){const t=[a.a[0],a.a[1],a.b[0],a.b[1]],r=Ot([e[0],e[1]],t);if(r>s.tolerance)continue;const l=ih(a,e,s.gridStep);!Ql(l,o,i)&&th(r,a.key,n)&&(n={kind:"line",point:l,key:a.key,distance:r,segment:a})}return n?{kind:"resolved",candidate:n,conflicts:[]}:{kind:"none",candidate:null,conflicts:[]}}(s.value,t,a),r="resolved"===n.kind?n.candidate:null,l=r?[...r.point]:this._snapDrawPoint(t,e),h=i?ge(i,l):l;return{point:h,candidate:r&&G(h,r.point)?r:null,conflicts:"ambiguous"===n.kind?n.conflicts:[],ambiguous:"ambiguous"===n.kind,contextKey:this._planSnapContextKey(s.key)}}_clearPlanSnapHover(t=!0){this.host._planSnapHover=null,this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers([]),t&&(this.host._cursorPt=null)}_samePt(t,e){return G(t,e)}_dropLegacySegments(t=this.host._serverCfg){for(const e of t?.markers||[])"ripple"===e.display&&(e.display="icon_ripple");for(const e of t?.spaces||[]){delete e.segments;const t=new Set,s=e=>"string"==typeof e&&e.length>=1&&e.length<=64&&!t.has(e),i=e=>(t.add(e),!0),o=t=>Array.isArray(t)&&2===t.length&&t.every(t=>Number.isFinite(Number(t))&&Math.abs(Number(t))<=Kt);if(Array.isArray(e.partitions)&&(e.partitions=e.partitions.filter(t=>t&&s(t.id)&&o(t.a)&&o(t.b)&&Math.hypot(t.a[0]-t.b[0],t.a[1]-t.b[1])>1e-9&&i(t.id)).map(t=>({...t,cm:Number.isFinite(Number(t.cm))?Math.max(0,Math.min(100,Number(t.cm))):15})),e.partitions.length||delete e.partitions),Array.isArray(e.wall_columns)&&(e.wall_columns=e.wall_columns.filter(t=>t&&s(t.id)&&o(t.center)&&i(t.id)).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[Number(t.center[0]),Number(t.center[1])],cm:ee(Number(t.cm)||15),..."circle"===t.shape?{}:{angle:fe(t.angle)}})),e.wall_columns.length||delete e.wall_columns),Array.isArray(e.room_drafts)&&(e.room_drafts=e.room_drafts.filter(t=>t&&s(t.id)&&Array.isArray(t.points)&&t.points.length>=2&&t.points.every(o)&&i(t.id)).map(t=>{const e=bn(t);return{id:t.id,...e}}).filter(t=>t.points.length>=2),e.room_drafts.length||delete e.room_drafts),Array.isArray(e.walls)){const t=be(Ft({spaces:[e]}),e.id),s=t?ve(e,t,Sc,.02*Dt).contour.map(t=>t.map(t=>t/Sc)):K(e.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]);e.walls=Ct(e.walls,e.rooms||[],W,1,s),e.walls.length||delete e.walls}}}_rollbackRejectedPhysicalWrites(t){if(!this.host._serverCfg||!t.length)return!1;let e=!1;for(const[s]of t){const t=this.host._pendingPhysicalWrites.get(s);t&&(e=this._restoreGeometryStateInConfig(this.host._serverCfg,t.before)||e,this.host._pendingPhysicalWrites.delete(s))}return!!e&&(this._clearGeometryGesture(),this.host._geometryHistory.clear(),this.host._cfgEpoch++,this.host._modelCache=null,this.host._wallUnionCache=null,this.host._physicalBodiesCache=null,this.host._frame=null,this.host._regSignature="",this.host._cfgContentFingerprint=_(this.host._serverCfg),this.host._maybeRebuildDevices(),this.host.requestUpdate(),!0)}async _reloadRejectedPhysicalWrite(){const t=this.host._writeChain;await t.catch(()=>{}),await this.host._reloadConfigOnly(!0)}_prepareConfigCandidate(t){return this._dropLegacySegments(t),ye(t)}_writeConfig(t=null){this.host._writesPending++,this.host._writeChain=$e(this.host._writeChain,async()=>{if(!this.host._serverCfg)return;const e=_(this.host._serverCfg),s=this._prepareConfigCandidate(this.host._serverCfg),i=_(s);t&&e===t.attemptedFingerprint&&Object.assign(t,{revision:this.host._cfgRev,attempted:s,attemptedFingerprint:i});const o=[...this.host._pendingPhysicalWrites.entries()];for(const[t,e]of o){const i=s.spaces.find(e=>e.id===t),o=Q(i);if(o===e.fingerprint)continue;let a=!1;try{a=this.host._checkSpacePhysicalGeometry(s,t).ok}catch{a=!1}if(!a)throw this._restoreGeometryStateLocal(e.before),this.host._pendingPhysicalWrites.delete(t),this.host._geometryHistory.clear(),this.host._showToast(this.host._t("toast.geometry_unsafe")),Object.assign(new Error("unsafe wall geometry"),{code:"geometry-unsafe"});e.fingerprint=o}i!==_(this.host._serverCfg)&&(this.host._serverCfg=s),this.host._cfgContentFingerprint=i;try{await this.host._sendConfigCandidate(s)}catch(t){if(!this._rollbackRejectedPhysicalWrites(o))throw t;const e=t&&"object"==typeof t?t:Object.assign(new Error(String(t)),{cause:t});throw e.physicalGeometryRolledBack=!0,e}for(const[t,e]of o)this.host._pendingPhysicalWrites.get(t)?.fingerprint===e.fingerprint&&this.host._pendingPhysicalWrites.delete(t)});return this.host._writeChain.finally(()=>{this.host._writesPending--})}_saveConfig(){this.host._cfgEpoch++,this.host._saveConfigDebounced()}_geometrySnapshotFromConfig(t,e){const s=t?.spaces?.find(t=>t.id===e);if(!s)return null;const i=t=>JSON.parse(JSON.stringify(t)),o={};for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==s[t]&&(o[t]=s[t]);return{spaceId:e,rooms:i(s.rooms||[]),...Array.isArray(s.openings)?{openings:i(s.openings)}:{},...Array.isArray(s.walls)?{walls:i(s.walls)}:{},...Array.isArray(s.wall_segments)?{wall_segments:i(s.wall_segments)}:{},...Array.isArray(s.open_spans)?{open_spans:i(s.open_spans)}:{},...Array.isArray(s.room_drafts)?{room_drafts:i(s.room_drafts)}:{},...Array.isArray(s.partitions)?{partitions:i(s.partitions)}:{},...Array.isArray(s.wall_columns)?{wall_columns:i(s.wall_columns)}:{},...Array.isArray(s.decor)?{decor:i(s.decor)}:{},plan_transform:o}}_geometrySnapshot(t=this.host._space){return this._geometrySnapshotFromConfig(this.host._serverCfg,t)}_recordGeometry(t,e){if(!e)return;const s=this._geometrySnapshot(e.spaceId);s&&JSON.stringify(e)!==JSON.stringify(s)&&(this.host._geometryHistory.push({name:t,before:e,after:s}),this.host.requestUpdate())}_restoreGeometryStateInConfig(t,e,s=!1){const i=t?.spaces?.find(t=>t.id===e.spaceId);if(!i)return!1;const o=t=>JSON.parse(JSON.stringify(t)),a=new Map((i.rooms||[]).map(t=>[t.id,t]));if(i.rooms=o(e.rooms),s)for(const t of i.rooms){const e=a.get(t.id);!Array.isArray(t.wall_ids)&&Array.isArray(e?.wall_ids)&&e.wall_ids.length===t.poly?.length&&(t.wall_ids=o(e.wall_ids))}const n=(t,e)=>{void 0!==e?i[t]=o(e):s&&"wall_segments"===t||delete i[t]},r=new Map((i.openings||[]).map(t=>[t.id,t])),l=new Map((i.room_drafts||[]).map(t=>[t.id,t]));if(n("openings",e.openings),n("walls",e.walls),n("wall_segments",e.wall_segments),n("open_spans",e.open_spans),n("room_drafts",e.room_drafts),n("partitions",e.partitions),n("wall_columns",e.wall_columns),n("decor",e.decor),s){for(const t of i.openings||[]){const e=r.get(t.id);t.host||"wall"!==e?.host?.kind||(t.host=o(e.host))}for(const t of i.room_drafts||[]){const e=l.get(t.id);for(let s=0;s<(t.segments||[]).length;s++)!t.segments[s]?.id&&e?.segments?.[s]?.id&&(t.segments[s].id=e.segments[s].id)}}for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])delete i[t];return Object.assign(i,o(e.plan_transform||{})),!0}_restoreGeometryStateLocal(t){return!!this._restoreGeometryStateInConfig(this.host._serverCfg,t)&&(this.host._cfgEpoch++,this.host._modelCache=null,this.host._wallUnionCache=null,this.host._physicalBodiesCache=null,this.host._frame=null,this.host.requestUpdate(),!0)}_wallModelBlockerLabel(t){const e=t instanceof cn?t.reason:"invalid-room";return this.host._t(`wall_model.reason.${e}`)}_hasLegacyZeroWallFields(t=this.host._serverCfg){return(t?.spaces||[]).some(t=>Array.isArray(t?.open_spans)&&t.open_spans.length>0||(t?.rooms||[]).some(t=>Array.isArray(t?.open_to)&&t.open_to.length>0))}_showWallModelMigrationBlocked(t){const e=this._hasLegacyZeroWallFields()?"toast.zero_wall_migration_blocked":"toast.wall_model_migration_blocked";this.host._showToast(this.host._t(e,{reason:this._wallModelBlockerLabel(t)}))}_limitSegmentsOf(t){const e=[];for(const s of t?.wall_segments||[])s?.a&&s?.b&&e.push({id:String(s.id||""),a:s.a,b:s.b,cm:Number(s.cm)});for(const s of t?.partitions||[])s?.a&&s?.b&&e.push({id:String(s.id||""),a:s.a,b:s.b,cm:Number(s.cm)});for(const s of t?.room_drafts||[]){const t=Array.isArray(s?.points)?s.points:[],i=Array.isArray(s?.segments)?s.segments:[];for(let o=0;o+1t?.id===e);return o?function(t,e,s,i,o){const a=(t?.spaces||[]).find(t=>t?.id===e);if(!a)return[];const n=Number(a.cell_cm)>0?Number(a.cell_cm):5,r=[...wr(s),...Dr(s,n,W),...Pr(s,n,W)];let l=i?.multiWallNodes||null;if(!l)try{l=nt(a.rooms||[],a.walls||[],[],W,n,W,1)}catch{l=null}const h=i&&"lightweight"!==i.status?i:null;let c="ok"===h?.status||"degraded-extra"===h?.status?h.roomGeom:null;const d=null===i||"lightweight"===i?.status;if(!c&&!d&&l?.nodes.length)try{const t=rt(a.rooms||[],a.walls||[],[],[],W,n,W,1);c="ok"===t?.status||"degraded-extra"===t?.status?t.roomGeom:null}catch{c=null}for(const t of a.rooms||[]){const e=String(t?.id||"");if(!e||o&&!o.has(e))continue;let s=null;try{s=lt(a.rooms||[],e,a.walls||[],[],W,n,W,1,d?null:c??void 0,l)}catch{s=null}r.push(...Ir(e,s,n,W))}return r}(t,e,this._limitSegmentsOf(o),s,i):[]}_junctionLimitLabel(t){const e=t=>String(Math.round(10*t)/10);return this.host._t(`junction.limit_${t.rule}`,{actual:e(t.actual),limit:e(t.limit)})}_junctionLimitsIntroduced(t,e,s,i,o){const a=o?.length?new Set(o):void 0;let n;const r=(e.spaces||[]).find(t=>t?.id===s);let l="";try{l=Q(r)}catch{l=""}const h=!a&&e&&"object"==typeof e?this._junctionBaselineCache.get(e):void 0;if(h&&l&&h.fingerprint===l&&h.spaceId===s&&(n=h.violations),!n){try{const t=Number(e?.model_version||0)>=9?e:Fn(e).config;n=this.host._junctionLimitViolations(t,s,a?null:void 0,a)}catch{return[]}!a&&e&&"object"==typeof e&&l&&this._junctionBaselineCache.set(e,{spaceId:s,fingerprint:l,violations:n})}let c=[],d=n;try{c=this.host._junctionLimitViolations(t,s,i,a),a&&(d=n.filter(t=>"clearance"!==t.rule||a.has(t.subject)))}catch{return[{rule:"check_failed",subject:s,actual:0,limit:0}]}return Tr(c,d)}_commitPhysicalGeometry(t,e,s=[]){if(!e||!this.host._serverCfg)return!1;const i=this.host._serverCfg,o=this._geometrySnapshotFromConfig(i,e.spaceId),a=i.spaces.find(t=>t.id===e.spaceId);if(!a||Q(e)===Q(a))return!1;let n,r=!1;try{r=this.host._checkSpacePhysicalGeometry(i,e.spaceId).ok}catch{r=!1}if(!r)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;let l=e;try{if(Number(i.model_version||0)<9){const t=JSON.parse(JSON.stringify(i));if(!this._restoreGeometryStateInConfig(t,e))throw new cn("invalid-room",e.spaceId);const s=Fn(t).config;l=this._geometrySnapshotFromConfig(s,e.spaceId)||e;const a=JSON.parse(JSON.stringify(s));if(!o||!this._restoreGeometryStateInConfig(a,o,!0))throw new cn("invalid-room",e.spaceId);const r=s.spaces.find(t=>t.id===e.spaceId),h=a.spaces.find(t=>t.id===e.spaceId);if(!Array.isArray(o.wall_segments)&&JSON.stringify(e.rooms)===JSON.stringify(o.rooms))for(const t of h?.wall_segments||[])t.cm=Z(o.walls,t.a,t.b,W,1);const c=((t,e,s)=>{const i=new Map,o=new Map((t?.rooms||[]).map(t=>[t.id,t])),a=new Map((e||[]).map(t=>[t.id,t])),{rooms:n}=In(s,Cn(t));for(const t of n){const e=a.get(t.id),n=o.get(t.id),r=q(e),l=(s.rooms||[]).find(e=>e.id===t.id),h=q(l),c=q(n);if(r&&h&&c&&r.length===h.length&&c.length===n?.wall_ids?.length&&t.poly.length===t.wall_ids.length)for(let e=0;e{const o=[];for(let a=0;ahn||$n(r,s,i)>hn)continue;const l=yn(n,s,i),h=yn(r,s,i);l<-1e-9||h>1+hn||h<=l+hn||o.push({start:l,id:e[a]})}return o.sort((t,e)=>t.start-e.start)},o=s(c,n.wall_ids,r[e],r[(e+1)%r.length]),a=s(t.poly,t.wall_ids,h[e],h[(e+1)%h.length]);if(o.length&&o.length===a.length)for(let t=0;tt.id===e.spaceId),i=this.host._path.length>=2?this.host._path.map(t=>[t[0]/Sc,t[1]/Sc]):[];i.push(...s.map(t=>[t[0],t[1]])),h=vn(t)<=vn(l,i)&&this.host._checkSpacePhysicalGeometry(n,e.spaceId).ok}catch{h=!1}if(!h)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;const c=JSON.parse(JSON.stringify(i));this._restoreGeometryStateInConfig(c,e);const d=this._junctionLimitsIntroduced(n,c,e.spaceId);if(d.length)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this._junctionLimitLabel(d[0])),!1;Hn(i,n),this._recordGeometry(t,l);const p=i.spaces.find(t=>t.id===e.spaceId),u=this.host._pendingPhysicalWrites.get(e.spaceId);return this.host._pendingPhysicalWrites.set(e.spaceId,{before:u?.before||l,fingerprint:Q(p)}),this._saveConfig(),!0}_clearGeometryGesture(){this._clearFurniturePreview(),this.host._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!1),this.host._mergeSel=null,this.host._mergeDialog=null,this.host._splitSel=null,this.host._pendingSplit=null,this.host._wallFaceBatch=null,this.host._wallRepairDiagnostic=null,this.host._roomDeleteDialog=null,this.host._wallDialog=null,this.host._physicalDialog=null,this.host._physicalSel=null,this.host._physicalDrag=null,this.host._physicalRotate=null,this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null,this.host._openingDialog=null,this._rszResetController(),this.host._decorDraft=null,this.host._decorMove=null,this.host._dtDrag=null,this.host._bdDrag=null}_stagePointerCancel(t){return clearTimeout(this.host._kioskHoldTimer),this.host._swipeStart?.id===t.pointerId&&(this.host._swipeStart=null),this.host._furnTouchPending?.pid===t.pointerId?(this._clearFurniturePreview(),this.host._pointers.delete(t.pointerId),void this.host.requestUpdate()):this.host._physicalDrag?.pid!==t.pointerId&&this.host._physicalRotate?.pid!==t.pointerId?this.host._decorDraft?.pid===t.pointerId?(this.host._decorDraft=null,void this.host.requestUpdate()):void(this.host._decorMove?.pid!==t.pointerId&&this.host._dtDrag?.pid!==t.pointerId&&this.host._bdDrag?.pid!==t.pointerId?("opening"===this.host._tool?(this.host._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this.host._tool&&this._clearPlanSnapHover(),this.host._pointers.delete(t.pointerId),this.host._pointers.size<2&&(this.host._pinchStart=null),0===this.host._pointers.size&&(this.host._panStart=null,this.host._panLock=null),this.host._viewportGestureDirty&&0===this.host._pointers.size&&(this.host._viewportGestureDirty=!1,this.host.requestUpdate())):this._cancelDecorGesture()):void this._cancelPhysicalGesture()}_applyGeometryState(t,e=!1){if(!this.host._canCommitSpace(t.spaceId))return!1;const s=this._geometrySnapshot(t.spaceId);if(!s||!this._restoreGeometryStateLocal(t))return!1;const i=this.host._serverCfg,o=Q(s)!==Q(t);if(o){let o=!1;try{const s=i?this.host._checkSpacePhysicalGeometry(i,t.spaceId):null;o=!!s?.ok||!(!e||"wall-degraded-extra"!==s?.reason)}catch{o=!1}if(!o)return this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1}let a;try{a=Fn(i).config}catch(t){return this._restoreGeometryStateLocal(s),this._showWallModelMigrationBlocked(t),!1}if(o){let o=!1;try{const s=a?this.host._checkSpacePhysicalGeometry(a,t.spaceId):null;o=!!s?.ok||!(!e||"wall-degraded-extra"!==s?.reason)}catch{o=!1}if(!o)return this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;Hn(i,a);const n=i?.spaces.find(e=>e.id===t.spaceId),r=this.host._pendingPhysicalWrites.get(t.spaceId);this.host._pendingPhysicalWrites.set(t.spaceId,{before:r?.before||s,fingerprint:Q(n)})}else Hn(i,a);return this._clearGeometryGesture(),this.host._space!==t.spaceId&&(this.host._commitSpace(t.spaceId),this.host._saveNav(),this.host._restoreZoom()),this.host._modelCache=null,this.host._frame=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this._saveConfig(),this.host.requestUpdate(),!0}_roomAt(t){return this.host._spaceModel()?.rooms.find(e=>{const s=q(e);return!!s&&we(t,s)})}_overlapRoom(t){return this.host._spaceModel()?.rooms.find(e=>{const s=q(e);return!!s&&E(t,s)})}_pointInRoom(t,e){return e.poly?ke(t,e.poly):null!=e.x&&t[0]>=e.x&&t[0]<=e.x+e.w&&t[1]>=e.y&&t[1]<=e.y+e.h}_contourSelfIntersects(t){if(!Da(t))return!0;const e=t.length,s=.001;for(let i=0;i=500)return this.host._showToast(this.host._t("toast.physical_limit")),!1;const t=this.host._curSpaceCfg;return!(!this.host._activeDraftId&&(t?.room_drafts||[]).length>=200||this._draftSegmentCount(t)>=2e3||(t?.partitions||[]).length+this.host._path.length>Mc)||(this.host._showToast(this.host._t("toast.physical_limit")),!1)}_markupClick(t){if(this.host._vacFit)return;if(!this.host._markup)return;const e=this.host._spaceModel();if(!e)return void this._clearGeometryGesture();if(this.host._suppressClick)return;if(this.host._drag||this.host._rlResize)return;const s=t.composedPath?.()||[];if(s.some(t=>t?.classList?.contains?.("roomlabel")||t?.classList?.contains?.("rlhandle")))return;if(s.some(t=>t?.classList?.contains?.("physical-hit")))return;const i=this._svgPoint(t);if("select"===this.host._tool)return void(this.host._physicalSel=null);if("resize"===this.host._tool){if(this.host._resize.dragging||s.some(t=>t?.classList?.contains?.("rszhandle")))return;const t=[...e.rooms].reverse().find(t=>this._pointInRoom(i,t));return this.host._resize.selectRoom(t?.id||null),void this.host.requestUpdate()}if("delroom"===this.host._tool)return void this._deleteRoomClick(i);if("opening"===this.host._tool)return void this._openingClick(i);if("merge"===this.host._tool)return void this._mergeClick(i);if("wallthick"===this.host._tool)return void this._wallThickClick(i);if("split"===this.host._tool)return void this._splitClick(i);if("column"===this.host._tool)return void this._columnClick(i);this.host._wallRepairDiagnostic=null;const o=this._resolvePlanDrawPoint(i,t.shiftKey);if(o.ambiguous)return this.host._planSnapHover={contextKey:o.contextKey,candidate:null,conflicts:o.conflicts},this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers(o.conflicts),void this.host._showToast(this.host._t("toast.plan_snap_ambiguous"));let a=o.point;if(t.ctrlKey||t.metaKey){if(t.preventDefault(),this.host._path.length<3)return;a=ge(this.host._path[this.host._path.length-1],this.host._path[0])}if(!this.host._path.length){if(!t.shiftKey&&!o.candidate&&this._offerExistingWallFace(i))return;const e=this._draftEndAt(a);return e?(this.host._activeDraftId=e.draft.id,this.host._resumeDraftBySpace[this.host._space]=e.draft.id,this.host._path=e.reverse?[...e.draft.points].reverse().map(t=>[...t]):e.draft.points.map(t=>[...t]),void(this.host._draftSegmentCms=this._adoptDraftCms(this.host._path,e.reverse?[...e.draft.segments].reverse().map(t=>t.cm):e.draft.segments.map(t=>t.cm),e.draft.id))):(this.host._activeDraftId=null,this.host._draftSegmentCms=[],void(this.host._path=[a]))}const n=this.host._path[this.host._path.length-1];if(this._samePt(a,n))return;const r=this._draftEndAt(a,this.host._activeDraftId||void 0);if(r)return void this._mergeDraftEndpoint(r);if(!this._canAppendRoomDraftPoint())return;const l=this.host._drawWallCm;if(null==l)return void this._showPhysicalRange(100);const h=this.host._path.map(t=>[...t]);this.host._path=[...this.host._path,a],this.host._draftSegmentCms=[...this.host._draftSegmentCms,l],this._persistActiveDraftSegment(),this._offerWallFaces(h)}_draftEndAt(t,e){const s=this.host._spaceModel();if(!s)return null;const i=this.host._viewOr(this.host._baseVb()),o=Math.max(.15*this.host._gridPitch,this.host._stageEl?.clientWidth?i.w/this.host._stageEl.clientWidth*12:0);for(const i of s.room_drafts||[]){if(i.id===e)continue;if(i.points.length<2)continue;const s=i.points[0],a=i.points[i.points.length-1];if(Math.hypot(t[0]-a[0],t[1]-a[1])<=o)return{draft:i,reverse:!1};if(Math.hypot(t[0]-s[0],t[1]-s[1])<=o)return{draft:i,reverse:!0}}return null}_mergeDraftEndpoint(t){const e=this.host._curSpaceCfg;if(!e||!this.host._path.length)return;const s=this.host._path.map(t=>[...t]),i=this._wallGraphSources(s),o=Array.isArray(e.room_drafts)?e.room_drafts:[],a=this.host._activeDraftId?o.find(t=>t.id===this.host._activeDraftId):null,n=o.find(e=>e.id===t.draft.id);if(!n)return;const r=t.reverse?t.draft.points.map(t=>[...t]):[...t.draft.points].reverse().map(t=>[...t]),l=t.reverse?(n.segments||[]).map(t=>({...t})):[...n.segments||[]].reverse().map(t=>({...t})),h=this.host._path[this.host._path.length-1],c=this._samePt(h,r[0]),d=c?null:this.host._drawWallCm;if(!c&&null==d)return void this._showPhysicalRange(100);const p=this._draftSegmentsForPath(this.host._path,a,this.host._draftSegmentCms),u=[...this.host._path.map(t=>[...t]),...c?r.slice(1):r],_=[...p,...null==d?[]:[{cm:d}],...l],m=u.length>=4&&this._samePt(u[0],u[u.length-1]),g=u,f=_;if(g.length>500)return void this.host._showToast(this.host._t("toast.physical_limit"));const b=(a?.segments?.length||0)+(n.segments?.length||0);if(this._draftSegmentCount(e)-b+f.length>2e3)return void this.host._showToast(this.host._t("toast.physical_limit"));if(m){const t=g.slice(0,-1);if(this._contourSelfIntersects(t)||B(t)<=1e-6)return void this.host._showToast(this.host._t("toast.contour_cannot_close"));const e=this._overlapRoom(t);if(e)return void this.host._showToast(this.host._t("toast.room_overlap",{name:e.name||""}))}const v=this._geometrySnapshot(),y=this.host._activeDraftId||t.draft.id,$={...a||n,id:y,points:g.map(t=>[t[0]/Sc,t[1]/Sc]),segments:f};e.room_drafts=o.filter(e=>e.id!==t.draft.id&&(!this.host._activeDraftId||e.id!==this.host._activeDraftId)),e.room_drafts.push($),this.host._activeDraftId=y,this.host._resumeDraftBySpace[this.host._space]=y,this.host._path=g,this.host._draftSegmentCms=this._adoptDraftCms(g,f.map(t=>Number(t.cm)),y),this.host._physicalSel=null,this._commitPhysicalGeometry(this.host._t("history.draft_merge"),v),null!=d&&this._offerWallFaces(s,s.length-1,i)}_adoptDraftCms(t,e,s){const i=Math.max(0,t.length-1),o=nh(i,e,this.host._drawWallCm,_t);return e.length!==i&&console.debug(`[houseplan] draft ${s??"?"}: восстановлено толщин ${i-e.length} (#234)`),o}_draftSegmentsForPath(t,e,s){const i=Array.isArray(e?.points)?e.points.map(t=>[Number(t?.[0])*Sc,Number(t?.[1])*Sc]):[],o=Array.isArray(e?.segments)?e.segments:[];return nh(Math.max(0,t.length-1),s,this.host._drawWallCm,_t).map((e,s)=>{const a=t[s],n=t[s+1],r=i.findIndex((t,e)=>{if(e+1>=i.length)return!1;const s=i[e+1];return this._samePt(a,t)&&this._samePt(n,s)||this._samePt(a,s)&&this._samePt(n,t)});return{...r>=0?o[r]:{},cm:e}})}_persistActiveDraftSegment(){if(this.host._path.length<2||!this.host._curSpaceCfg)return;const t=this._geometrySnapshot(),e=this.host._curSpaceCfg;e.room_drafts||=[],this.host._activeDraftId||(this.host._activeDraftId="draft-"+Date.now().toString(36)),this.host._resumeDraftBySpace[this.host._space]=this.host._activeDraftId;const s=e.room_drafts.findIndex(t=>t.id===this.host._activeDraftId),i={...s>=0?e.room_drafts[s]:{},id:this.host._activeDraftId,points:this.host._path.map(t=>[t[0]/Sc,t[1]/Sc]),segments:this._draftSegmentsForPath(this.host._path,s>=0?e.room_drafts[s]:null,this.host._draftSegmentCms)};s>=0?e.room_drafts[s]=i:e.room_drafts.push(i),sr(this,this.host._t("history.draft_segment"),t)}_activeWallSourceKey(t){return`active:${this.host._activeDraftId||"session"}:${t}`}_wallGraphSources(t){const e=this._planStructuralGeometrySnapshot().value.segments.map(t=>({a:t.a,b:t.b,key:`static:${t.key}`}));for(let s=0;s+1t.key===s);if(i>=0){const[t]=this.host._wallFaceGraphCache.splice(i,1);return this.host._wallFaceGraphCache.push(t),t.value}const o=Ph(t,e);return this.host._wallFaceGraphCache.push({key:s,value:o}),this.host._wallFaceGraphCache.length>4&&this.host._wallFaceGraphCache.shift(),o}_offerWallFaces(t,e=this.host._path.length-2,s){if(this.host._path.length<2||this.host._wallFaceBatch||this.host._roomDialog)return;const i=this.host._spaceModel();if(!i)return;const o=this._activeWallSourceKey(e),a=2e-4*this.host._gridPitch;let n,r;try{const e=s||this._wallGraphSources(t);r=this._wallGraphSources(this.host._path),n=function(t,e,s){const i=new Set(t.faces.map(t=>t.key));return e.faces.filter(t=>!i.has(t.key)&&t.sourceKeys.includes(s))}(this._wallFaceGraph(e,a),this._wallFaceGraph(r,a),o)}catch{return}if(!n.length){const t=Bh(r,{requiredSourceKey:o,maxDistance:x(2,this.host._cellCm,this.host._gridPitch),gridStep:this.host._gridPitch,epsilon:a});return"ambiguous"===t.kind?(this.host._wallRepairDiagnostic=t.proposals[0]||null,void this.host._showToast(this.host._t(0===this.host._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous"))):void("repair"!==t.kind||this._overlapRoom(t.face.ring)||this._beginWallFaceBatch([{...t.face,repair:t.proposal}]))}for(const t of i.rooms){const e=q(t);if(!t.id||!e)continue;const s=xe(e,this.host._path,.02*this.host._gridPitch);if(!s)continue;const[i,o]=s,a=B(i)>=B(o)?i:o,r=a===i?o:i,l=[...n].sort((t,e)=>Math.abs(t.area-B(r))-Math.abs(e.area-B(r))||t.key.localeCompare(e.key))[0];if(!l)return;return void this._beginWallFaceBatch([{...l,ring:r.map(t=>[t[0],t[1]]),split:{roomId:t.id,mainPoly:a,newPoly:r},consumeAllActive:!0}])}const l=n.filter(t=>!(t.ring.length<3||this._contourSelfIntersects(t.ring))&&!this._overlapRoom(t.ring));l.length&&this._beginWallFaceBatch(l)}_beginWallFaceBatch(t){this.host._wallRepairDiagnostic=null,this.host._wallFaceBatch={candidates:[...t].sort((t,e)=>t.area-e.area||t.key.localeCompare(e.key)),index:0,decisions:[],activePath:this.host._path.map(t=>[...t]),activeCms:[...this.host._draftSegmentCms],activeDraftId:this.host._activeDraftId},this._clearPlanSnapHover(),this.host._nameSel="",this.host._areaSel="",this._resetRoomDialogFields(),this.host._roomDialog=!0}_offerExistingWallFace(t){if(this.host._path.length||this.host._wallFaceBatch||this.host._roomDialog)return!1;const e=2e-4*this.host._gridPitch;try{let s,i=Ih(this._wallFaceGraph(this._wallGraphSources([]),e),t,e);if(!i){const o=Bh(this._wallGraphSources([]),{point:t,maxDistance:x(2,this.host._cellCm,this.host._gridPitch),gridStep:this.host._gridPitch,epsilon:e});if("ambiguous"===o.kind)return this.host._wallRepairDiagnostic=o.proposals[0]||null,this.host._showToast(this.host._t(0===this.host._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous")),!0;if("repair"===o.kind)i=o.face,s=o.proposal;else if("none"===o.kind){const s=Bh(this._wallGraphSources([]),{point:t,maxDistance:this._cssPxToRender(12),gridStep:this.host._gridPitch,epsilon:e});if("repair"===s.kind)return this.host._wallRepairDiagnostic=s.proposal,this.host._showToast(this.host._t("toast.wall_repair_too_large")),!0}}return!(!i||i.ring.length<3||this._contourSelfIntersects(i.ring)||this._overlapRoom(i.ring))&&(this._beginWallFaceBatch([{...i,existing:!s,repair:s}]),!0)}catch{return!1}}_columnClick(t){const e=this._snap(t),s=this.host._drawWallCm;if(null==s)return void this._showPhysicalRange(Zt,1);if(!this.host._curSpaceCfg||this._limitReached("column"))return;const i=this.host._spaceModel();if(!i)return;const o={id:"column-"+Date.now().toString(36),shape:"square",center:e,cm:ee(s),angle:0},a=(i.wall_columns||[]).find(t=>Qt(t,o,.02*this.host._gridPitch));if(a)return clearTimeout(this.host._duplicateColumnTimer),this.host._duplicateColumnId=a.id,this.host._duplicateColumnTimer=window.setTimeout(()=>{this.host._duplicateColumnId=null},900),void this.host._showToast(this.host._t("toast.column_duplicate"));const n=this._geometrySnapshot(),r=this.host._curSpaceCfg;r.wall_columns||=[],r.wall_columns.push({...o,center:[e[0]/Sc,e[1]/Sc]}),this._commitPhysicalGeometry(this.host._t("history.column_add"),n)}_openPhysicalDialog(t,e,s){const i=this.host._spaceModel();if(i)if("partition"===t){const s=i.partitions.find(t=>t.id===e);s&&(this.host._physicalDialog={kind:t,id:e,cm:pe(s.cm,this.host._imperial),length:this.host._fmtLen(s.a,s.b)})}else if("column"===t){const s=i.wall_columns.find(t=>t.id===e);s&&(this.host._physicalDialog={kind:t,id:e,cm:pe(s.cm,this.host._imperial),shape:s.shape,angle:this.host._angleField("square"===s.shape?fe(s.angle):0)})}else{const o=i.room_drafts.find(t=>t.id===e),a=Math.max(0,Math.min(o?.segments.length?o.segments.length-1:0,s||0));o?.segments[a]&&(this.host._physicalDialog={kind:t,id:e,segment:a,cm:pe(o.segments[a].cm,this.host._imperial),length:this.host._fmtLen(o.points[a],o.points[a+1])})}}_physicalDown(t,e,s){const i=this.host._spaceModel();if(!i)return;t.stopPropagation(),Dc(t);const o=this._svgPoint(t),a=[];for(const t of[...i.wall_columns].reverse())Se(o,Me(t,this.host._cellCm,this.host._gridPitch))&&a.push({kind:"column",id:t.id});for(const t of[...i.partitions].reverse()){const e=De(t.a,t.b,t.cm,this.host._cellCm,this.host._gridPitch);e&&Se(o,e)&&a.push({kind:"partition",id:t.id})}a.some(t=>t.kind===e&&t.id===s)||a.unshift({kind:e,id:s});const n=a.map(t=>`${t.kind}:${t.id}`).sort().join("|"),r=performance.now(),l=this.host._physicalPickCycle,h=a.length>1&&l?.signature===n&&r-l.at>380&&r-l.at<=1200&&Math.hypot(t.clientX-l.x,t.clientY-l.y)<=10?(l.index+1)%a.length:Math.max(0,a.findIndex(t=>t.kind===e&&t.id===s));this.host._physicalPickCycle={signature:n,index:h,x:t.clientX,y:t.clientY,at:r},e=a[h].kind,s=a[h].id;const c="partition"===e?i.partitions.find(t=>t.id===s):i.wall_columns.find(t=>t.id===s);c&&(this.host._physicalSel={kind:e,id:s},this.host._physicalDrag={pid:t.pointerId,kind:e,id:s,start:this._svgPoint(t),startClient:[t.clientX,t.clientY],before:this._geometrySnapshot(),moved:!1,base:JSON.parse(JSON.stringify(c)),delta:[0,0]})}_clampPhysicalDelta(t,e,s){const i="partition"===t?[e.a,e.b]:[e.center],o=i.map(t=>t[0]),a=i.map(t=>t[1]);return[Math.max(-Kt*Sc-Math.min(...o),Math.min(Kt*Sc-Math.max(...o),s[0])),Math.max(-Kt*Sc-Math.min(...a),Math.min(Kt*Sc-Math.max(...a),s[1]))]}_physicalMove(t){t.stopPropagation(),Ao(this.host,"physical",()=>this._physicalMoveNow(t))}_physicalMoveNow(t){const e=this.host._physicalDrag;if(!e||e.pid!==t.pointerId)return;t.stopPropagation();const s=this._svgPoint(t),i="partition"===e.kind?e.base.a:e.base.center,o=this._snap([i[0]+s[0]-e.start[0],i[1]+s[1]-e.start[1]]),a=this._clampPhysicalDelta(e.kind,e.base,[o[0]-i[0],o[1]-i[1]]);this.host._physicalDrag={...e,delta:a,moved:e.moved||Math.hypot(t.clientX-e.startClient[0],t.clientY-e.startClient[1])>=5}}_physicalUp(t){Fo(this.host,"physical");const e=this.host._physicalDrag;if(!e||e.pid!==t.pointerId)return;if(t.stopPropagation(),this.host._physicalDrag=null,!e.moved)return void this._registerPhysicalTap(e.kind,e.id);const s=this.host._spaceModel();if(!this.host._curSpaceCfg||!s)return;const i=this.host._curSpaceCfg;if("partition"===e.kind){const t=(i.partitions||[]).find(t=>t.id===e.id),s=e.base;if(t){const o={...s,a:[s.a[0]+e.delta[0],s.a[1]+e.delta[1]],b:[s.b[0]+e.delta[0],s.b[1]+e.delta[1]]};t.a=[o.a[0]/Sc,o.a[1]/Sc],t.b=[o.b[0]/Sc,o.b[1]/Sc];for(const t of i.openings||[]){if("partition"!==t.host?.kind||t.host.id!==e.id)continue;const s=dt(t,[o],Sc,this.host._cellCm,this.host._gridPitch).resolved;s&&Object.assign(t,pt(t,s,Sc))}}}else{const t=(i.wall_columns||[]).find(t=>t.id===e.id),o=e.base,a={...o,center:[o.center[0]+e.delta[0],o.center[1]+e.delta[1]]};if(s.wall_columns.some(t=>t.id!==e.id&&Qt(t,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"));t&&(t.center=[(o.center[0]+e.delta[0])/Sc,(o.center[1]+e.delta[1])/Sc])}this._commitPhysicalGeometry(this.host._t("history.physical_move"),e.before)}_registerPhysicalTap(t,e,s){const i=performance.now(),o=this.host._physicalLastTap?.kind===t&&this.host._physicalLastTap.id===e&&this.host._physicalLastTap.segment===s&&i-this.host._physicalLastTap.at<=360;this.host._physicalLastTap={kind:t,id:e,segment:s,at:i},o&&(this.host._physicalLastTap=null,this._openPhysicalDialog(t,e,s))}_cancelPhysicalGesture(){No(this.host,"physical"),No(this.host,"physical-rotate"),this.host._physicalDrag=null,this.host._physicalRotate=null,this.host.requestUpdate()}_physicalRotateDown(t,e){if("square"!==e.shape||!this.host._spaceModel())return;t.preventDefault(),t.stopPropagation(),Dc(t);const s=this._svgPoint(t);this.host._physicalSel={kind:"column",id:e.id},this.host._physicalRotate={pid:t.pointerId,id:e.id,center:[...e.center],startAngle:180*Math.atan2(s[1]-e.center[1],s[0]-e.center[0])/Math.PI,baseAngle:fe(e.angle),angle:fe(e.angle),before:this._geometrySnapshot(),moved:!1}}_physicalRotateMove(t){t.preventDefault(),t.stopPropagation(),Ao(this.host,"physical-rotate",()=>this._physicalRotateMoveNow(t))}_physicalRotateMoveNow(t){const e=this.host._physicalRotate;if(!e||e.pid!==t.pointerId)return;t.preventDefault(),t.stopPropagation();const s=this._svgPoint(t),i=180*Math.atan2(s[1]-e.center[1],s[0]-e.center[0])/Math.PI,o=e.baseAngle+i-e.startAngle,a=fe(t.shiftKey?o:5*Math.round(o/5));this.host._physicalRotate={...e,angle:a,moved:e.moved||Math.abs(o-e.baseAngle)>=.5}}_physicalRotateUp(t){Fo(this.host,"physical-rotate");const e=this.host._physicalRotate;if(!e||e.pid!==t.pointerId)return;t.preventDefault(),t.stopPropagation(),this.host._physicalRotate=null;const s=this.host._spaceModel();if(!e.moved||!this.host._curSpaceCfg||!s)return;const i=s.wall_columns.find(t=>t.id===e.id);if(!i||"square"!==i.shape)return;const o={...i,angle:e.angle};if(s.wall_columns.some(t=>t.id!==e.id&&Qt(t,o,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"));const a=this.host._curSpaceCfg.wall_columns?.find(t=>t.id===e.id);a&&(a.angle=e.angle,this._commitPhysicalGeometry(this.host._t("history.physical_edit"),e.before))}_rszRooms(){const t=[],e=this.host._spaceModel();if(!e)return t;for(const s of e.rooms){const e=s.id?q(s):null;e&&t.push({id:s.id,poly:e,wall_ids:Array.isArray(s.wall_ids)?[...s.wall_ids]:void 0})}return s=t,i=Math.max(1e-12,1e-12*this.host._gridPitch),s.map(t=>{if(!Array.isArray(t.wall_ids)||t.wall_ids.length!==t.poly.length)return{...t,poly:t.poly.map(t=>[...t])};const e=t.poly.map(t=>[...t]);let s=!0;for(;s&&e.length>3;){s=!1;for(let t=0;t0){e.splice(t,1),s=!0;break}}}return{...t,poly:e}});var s,i}_rszOpenings(){return this.host._openingsR.map(t=>({id:t.id,x:t.rx,y:t.ry,length:t.rlen,hosted:!!t.host,angle:t.angle,type:t.type}))}_rszObstacles(){const t=this.host._spaceModel();if(!t)return[];const e=[];for(const s of t.partitions||[])e.push({kind:"segment",a:[...s.a],b:[...s.b],half:x(s.cm,this.host._cellCm,this.host._gridPitch)/2});for(const s of t.room_drafts||[])for(let t=0;t+1Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2).map(t=>({wall:t,a:[t.a[0]*Sc,t.a[1]*this.host._spaceH],b:[t.b[0]*Sc,t.b[1]*this.host._spaceH]})),o=Math.abs(t[0]-e[0])<=.05*this.host._gridPitch?"v":Math.abs(t[1]-e[1])<=.05*this.host._gridPitch?"h":null,a=i.filter(s=>!!o&&("h"===o?!(Math.abs(s.a[1]-t[1])>.05*this.host._gridPitch||Math.abs(s.b[1]-t[1])>.05*this.host._gridPitch)&&Math.min(Math.max(t[0],e[0]),Math.max(s.a[0],s.b[0]))-Math.max(Math.min(t[0],e[0]),Math.min(s.a[0],s.b[0]))>.05*this.host._gridPitch:!(Math.abs(s.a[0]-t[0])>.05*this.host._gridPitch||Math.abs(s.b[0]-t[0])>.05*this.host._gridPitch)&&Math.min(Math.max(t[1],e[1]),Math.max(s.a[1],s.b[1]))-Math.max(Math.min(t[1],e[1]),Math.min(s.a[1],s.b[1]))>.05*this.host._gridPitch)),n=new Set(a.map(t=>Number(t.wall.cm)).filter(t=>t>0));return{minDim:this.host._cmToUnits(30),eps:.05*this.host._gridPitch,step:this.host._gridPitch,movingHalf:s>0?x(s,this.host._cellCm,this.host._gridPitch)/2:0,obstacles:this._rszObstacles(),thicknessConflict:n.size>1}}_rszResolution(t,e,s){const i=this.host._resize.snapshotIdentity||s||this._rszSnapshot(),o=`${this.host._space}|${this.host._cellCm}|${this.host._gridPitch}|${i}`,a=`${t}:${e}`;return this.host._resize.resolve(o,a,()=>{const s=[...this.host._resize.rooms||this._rszRooms()],i=s.find(e=>e.id===t),o=i?.poly?.[e]||[0,0],a=i?.poly?.[(e+1)%(i?.poly?.length||1)]||[0,0];return function(t,e,s,i,o){const{eps:a}=o,n=t.find(t=>t.id===s);if(!n||i<0||i>=(n.poly?.length||0)||n.poly.length<4||!Da(n.poly))return{enabled:!1,reason:"invalid-geometry"};const r=n.poly[i],l=n.poly[(i+1)%n.poly.length],h=Ta(r,l,a);if(!h)return{enabled:!1,reason:"diagonal"};if(!Fa(n.poly,i,h,a))return{enabled:!1,reason:"side-angle"};if(o.thicknessConflict)return{enabled:!1,reason:"thickness-conflict"};for(const t of o.obstacles||[])if(La(t,r,l,o))return{enabled:!1,reason:"duplicate-physical-wall"};const c=ka(ya(l,r)),d=[],p=new Set;let u=!1,_=!1;for(const e of t)if(e.id!==s)for(let t=0;t1||d.length>1)return{enabled:!1,reason:"multiple-rooms"};const m={[s]:i},g=[s];if(1===d.length){const t=d[0];if(!Da(t.room.poly))return{enabled:!1,reason:"invalid-geometry"};if(!Fa(t.room.poly,t.edge,h,a))return{enabled:!1,reason:"side-angle"};g.push(t.room.id),m[t.room.id]=t.edge}const f=[];for(const t of e)if(!(Sa([t.x,t.y],r,l)>2*a)){if(t.hosted||t.length>c+2*a)return{enabled:!1,reason:"opening-conflict"};f.push(t.id)}const b=Object.fromEntries(g.map(e=>[e,t.find(t=>t.id===e).poly.length])),v=[];for(const e of g){const s=t.find(t=>t.id===e),i=m[e],o=(i-1+s.poly.length)%s.poly.length,n=(i+1)%s.poly.length,r=Ba(t,e,o,1,a),l=Ba(t,e,n,0,a);if(!r||!l)return{enabled:!1,reason:"partial-shared"};v.push(r,l)}const y={roomId:s,edge:i,a:[...r],b:[...l],n:Ma(n.poly,i),roomIds:g,edgeByRoom:m,topology:b,movingOpeningIds:f,sideOwnership:v};if(!Va(t,e,y,0,o))return{enabled:!1,reason:"invalid-geometry"};const $=Math.abs(Number(o.step));if(Number.isFinite($)&&$>a){const s=[-$,$];if(!s.some(s=>Va(t,e,y,s,o))){if(!s.some(s=>ja(qa(t,e,y,s),y,a)))return{enabled:!1,reason:"partial-shared"};const i={...o,obstacles:[]};return s.some(s=>Va(t,e,y,s,i))?{enabled:!1,reason:"duplicate-physical-wall"}:e.length&&s.some(e=>Va(t,[],y,e,o))?{enabled:!1,reason:"opening-conflict"}:{enabled:!1,reason:"invalid-geometry"}}}return{enabled:!0,plan:y}}(s,[...this.host._resize.openings||this._rszOpenings()],t,e,this._rszOptsFor(o,a))})}_rszSnapshot(){return JSON.stringify(this._geometrySnapshot()||{spaceId:this.host._space,rooms:[],openings:[],walls:[],open_spans:[]})}_rszResetController(){const t=null!==this.host._resize.preview;this.host._resize.reset(),t&&this.host._cfgEpoch++}_rszProjectPreview(t,e,s,i,o){this.host._rszLimitViolation=null;const a=this.host._serverCfg?.spaces.find(t=>t.id===this.host._space);if(!a||!this.host._serverCfg)return{ok:!1,reason:"missing-context"};const n=JSON.parse(t),r={...a,rooms:n.rooms,openings:n.openings||[]};for(const t of["walls","wall_segments","open_spans","room_drafts","partitions","wall_columns","decor"])void 0!==n[t]?r[t]=n[t]:delete r[t];for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==n.plan_transform?.[t]?r[t]=n.plan_transform[t]:delete r[t];const l=this.host._spaceH;for(const[t,s]of Object.entries(e)){const e=r.rooms.find(e=>e.id===t);e&&(e.poly=s.map(t=>[t[0]/Sc,t[1]/l]),delete e.x,delete e.y,delete e.w,delete e.h)}for(const[t,e]of Object.entries(s)){const s=(r.openings||[]).find(e=>e.id===t);s&&(s.x=e[0]/Sc,s.y=e[1]/l)}const h=[],c=[];for(const t of i){const e=o.find(e=>e.id===t),s=r.rooms.find(e=>e.id===t);if(!e||!s?.poly)continue;const i=s.poly.map(t=>[t[0]*Sc,t[1]*l]);if(e.poly.length!==i.length)continue;const a=Array.isArray(e.wall_ids)?e.wall_ids:[];for(let t=0;tt.id===s):null;o&&(o.a=[i[t][0]/Sc,i[t][1]/Sc],o.b=[i[(t+1)%i.length][0]/Sc,i[(t+1)%i.length][1]/Sc])}}if(h.length&&Array.isArray(r.walls)&&r.walls.length){const t=Ce(r.walls,h,c,this.host._wallKeyPitch,Sc,"fixed-topology");if(t.rejected)return{ok:!1,reason:"wall-metadata"};r.walls=t.walls}const d=[];for(const t of r.rooms||[]){const e=q(t);if(e&&!(e.length<2))for(let t=0;tJSON.stringify([t?.key,t?.cm,t?.a,t?.b]),u=new Map;for(const t of n.walls||[]){const e=p(t);u.set(e,(u.get(e)||0)+1)}const _=[];for(const t of r.walls||[]){const e=p(t),s=u.get(e)||0;s?u.set(e,s-1):_.push(t)}if(Pe(_,d,this.host._wallKeyPitch,Sc,n.walls||[]).length)return{ok:!1,reason:"wall-metadata"};const m=function(t,e,s=1e-8){const i=sn(t),o=new Set(e),a=i.flatMap(t=>{if(!o.has(String(t.id||"")))return[];const e=rn(nn(t));return e?[e]:[]});return i.flatMap(t=>{const e=String(t.id||""),i=rn(nn(t)),n=!!i&&a.some(t=>i.minX<=t.maxX+s&&i.maxX+s>=t.minX&&i.minY<=t.maxY+s&&i.maxY+s>=t.minY);return e&&(o.has(e)||n)?[e]:[]})}(r.rooms||[],i),g=ln(r,m);if(!g||!this._rszSpaceCandidateGeometry(this.host._space,g).ok)return{ok:!1,reason:"physical-geometry"};const f={...this.host._serverCfg,spaces:(this.host._serverCfg?.spaces||[]).map(t=>t?.id===this.host._space?r:t)};try{this._resizePreviewNodes=nt(g.rooms,g.walls,[],W,this.host._cellCm,this.host._gridPitch,Sc)}catch{this._resizePreviewNodes=null}let b;try{const t=new Set(i),e=this.host._junctionLimitViolations(f,this.host._space,{status:"lightweight",multiWallNodes:this._resizePreviewNodes},t);b=Tr(e,this._resizeBaselineLimits.filter(e=>"clearance"!==e.rule||t.has(e.subject)))}catch{b=[{rule:"check_failed",subject:this.host._space,actual:0,limit:0}]}return b.length?(this.host._rszLimitViolation=b[0],{ok:!1,reason:"junction-limit"}):{ok:!0,value:{preview:{space:this.host._space,sp:r},beforeWalls:n.walls||[],afterWalls:r.walls||[],artifact:null}}}_rszAcceptPreview(t,e){if(this.host._cfgEpoch++,this.host._physicalBodiesCache&&(this.host._physicalBodiesCache.key=`${this.host._space}|${this.host._cfgEpoch}|${this.host._cellCm}|${this.host._gridPitch}`),!t||!e)return;const s=Ie(e);if(!s)return;const i=`${this.host._space}|${this.host._cfgEpoch}|${t.sp.rooms.length}`;Object.defineProperty(s,"sourceFingerprint",{value:_([t.sp,this.host._cellCm,this.host._gridPitch]),enumerable:!1});const o={key:i,value:s};xc(this.host._wallUnionPool,i,o,8),this.host._wallUnionCache=o}_rszSpaceCandidateGeometry(t,e){if(!this.host._serverCfg)return{ok:!1,wallGeometry:null};const s={...this.host._serverCfg,spaces:this.host._serverCfg.spaces.map(s=>s.id===t?e:s)};let i=null;try{return{ok:this.host._checkSpacePhysicalGeometry(s,t,t=>{i=t}).ok,wallGeometry:i}}catch{return{ok:!1,wallGeometry:null}}}_rszSpaceCandidateRenderable(t,e){if(!this.host._serverCfg)return!1;try{const s={...this.host._serverCfg,spaces:this.host._serverCfg.spaces.map(s=>s.id===t?e:s)};return this.host._checkSpacePhysicalGeometry(s,t).ok}catch{return!1}}_rszCandidateRenderable(t){return!!t&&t.space===this.host._space&&this._rszSpaceCandidateRenderable(t.space,t.sp)}_rszEdgeDown(t,e,s){if("resize"!==this.host._tool||this.host._resize.dragging)return;this._resizeBaseFrameStable=!0,t.stopPropagation(),t.preventDefault();const i=this._rszRooms(),o=this._rszResolution(e,s);if(!o.enabled)return void this.host._showToast(this._rszReasonText(o.reason));Dc(t);const a=o.plan;try{this._resizeBaselineLimits=this.host._junctionLimitViolations(this.host._serverCfg,this.host._space,null,new Set(a.roomIds))}catch{this._resizeBaselineLimits=[]}const n=this._svgPoint(t),r=`${this.host._space}|${this.host._cfgEpoch}|${i.length}`,l=this.host._wallUnionCache?.key===r?this.host._wallUnionCache.value:null,h=this._rszSnapshot();this.host._resize.begin({pointerId:t.pointerId,start:[n[0],n[1]],roomId:e,plan:a,options:this._rszOptsFor(a.a,a.b),rooms:i,openings:this._rszOpenings(),snapshotIdentity:h,before:JSON.parse(h),wallUnionBefore:l,epochBefore:this.host._cfgEpoch})}_rszReasonText(t){return this.host._t(`resize.disabled.${t}`)}_rszDisabledActivate(t,e){t.stopPropagation(),t.preventDefault(),this.host._showToast(this._rszReasonText(e))}_rszDisabledKey(t,e){"Enter"!==t.key&&" "!==t.key||this._rszDisabledActivate(t,e)}_rszMove(t){this.host._resize.ownsPointer(t.pointerId)&&(t.stopPropagation(),Ao(this.host,"resize",()=>this._rszMoveNow(t)))}_rszMoveNow(t){if(!this.host._resize.ownsPointer(t.pointerId))return;t.stopPropagation();const e=this._svgPoint(t),s=this.host._resize.move({pointerId:t.pointerId,point:[e[0],e[1]],step:this.host._gridPitch,snap:t=>{const e=this._snap(t);return[e[0],e[1]]},project:(t,e,s,i,o)=>this._rszProjectPreview(t,e,s,i,o),publish:(t,e)=>this._rszAcceptPreview(t,e),measure:(t,e)=>this._rszEdgeLabels(t,e)});if("rejected"===s.kind)return s.notify&&this.host._showToast(this.host._rszLimitViolation?`${this.host._t("resize.limit_stopped")} — `+this._junctionLimitLabel(this.host._rszLimitViolation):this.host._t("resize.preview_failed")),void this.host.requestUpdate();"accepted"===s.kind&&this.host.requestUpdate()}_rszUp(t){if(Fo(this.host,"resize"),!this.host._resize.ownsPointer(t.pointerId))return;t.stopPropagation();const e=this.host._resize.finish({pointerId:t.pointerId,currentSnapshotIdentity:this._rszSnapshot(),validatePreview:t=>this._rszCandidateRenderable(t)});if("no-op"===e.kind)return this.host._cfgEpoch++,void this.host.requestUpdate();if("rejected"===e.kind)return this.host._cfgEpoch++,this.host._showToast(this.host._t("resize.commit_failed")),void this.host.requestUpdate();const s=e.preview,i=this.host._serverCfg?.spaces.find(t=>t.id===s.space);i&&(i.rooms=s.sp.rooms,i.openings=s.sp.openings,Array.isArray(s.sp.walls)&&(s.sp.walls.length?i.walls=s.sp.walls:delete i.walls),Array.isArray(s.sp.wall_segments)&&(i.wall_segments=s.sp.wall_segments)),this.host._suppressClick=!0,setTimeout(()=>this.host._suppressClick=!1,0),this._commitPhysicalGeometry(this.host._t("history.resize_room"),e.before),this.host.requestUpdate()}_rszCancelDrag(t){No(this.host,"resize");const e=this.host._resize.cancel(this._rszSnapshot(),t);if("no-op"!==e.kind){if(null!==e.restoreEpoch?this.host._cfgEpoch=e.restoreEpoch:this.host._cfgEpoch++,this.host._physicalBodiesCache&&(this.host._physicalBodiesCache.key=`${this.host._space}|${this.host._cfgEpoch}|${this.host._cellCm}|${this.host._gridPitch}`),e.restoreWallUnion){const t=this.host._spaceModel();if(t){const s=`${this.host._space}|${this.host._cfgEpoch}|${t.rooms.length}`,i={key:s,value:e.restoreWallUnion};xc(this.host._wallUnionPool,s,i,8),this.host._wallUnionCache=i}}null!==e.restoreEpoch&&"plan"===this.host._mode&&this._resizeBaseFrameStable&&(this.host._terminalFrame=1),this.host.requestUpdate()}}_rszPointerCancel(t){this.host._resize.ownsPointer(t.pointerId)&&(t.stopPropagation(),this._rszCancelDrag(t.pointerId))}_rszEdgeLabels(t,e,s=this.host._resize.rooms){const i=s,o=[],a=t.polys[e.roomId]||i?.find(t=>t.id===e.roomId).poly;if(!a||!i)return o;const n=a.length,r=this._rszInnerSpanCms(e.roomId,a,t.polys);for(const t of function(t,e){const s=t.length;return[(e-1+s)%s,(e+1)%s]}(a,e.edge)){const e=a[t],s=a[(t+1)%n],i=r?.[t];o.push({kind:"length",x:(e[0]+s[0])/2,y:(e[1]+s[1])/2,text:null==i?this.host._fmtLen(e,s):Te(i,"mi"===this.host.hass?.config?.unit_system?.length),edge:{a:[e[0],e[1]],b:[s[0],s[1]]}})}const l="mi"===this.host.hass?.config?.unit_system?.length,h=e.roomIds,c=this.host._spaceWalls,d=this.host._physicalBodiesR(),p=this.host._baseVb(),u=this.host._view&&this.host._view.w>0&&this.host._view.h>0?this.host._view:{x:p[0],y:p[1],w:p[2],h:p[3]},[_,m]=this.host._lastValidStageSize||[u.w,u.h],g={...u,stageWidth:Math.max(1,_),stageHeight:Math.max(1,m)},f=this.host._spaceModel(),b=this.host._config?.icon_size??2.5,v=f?ze(b>8?2.5:b,f,u.w,this.host._kiosk?this.host._kioskScale.icon:1)*g.stageWidth/100:24,y=Math.max(10,.77*v),$=this.host._t("room.settings_short"),w=y*(1.457+.66*Math.max(1,$.length)*.42);for(const s of h){const a=t.polys[s]||i.find(t=>t.id===s).poly,n=c.length&&f&<(f.rooms,s,c,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc,null,this._resizePreviewNodes)||a,r=d.length?Re(Ae(n,d))*Math.pow(this.host._cellCm/this.host._gridPitch,2)/1e4:Fe(n,this.host._gridPitch,this.host._cellCm),h=Ne(r,l),p=or({poly:a,edge:e.edgeByRoom[s],text:h,view:g,gearCenter:He(a),gearWidthPx:w,gearHeightPx:y});o.push({kind:"area",roomId:s,x:p.anchor[0],y:p.anchor[1],text:h,placement:p})}return o}_rszInnerSpanCms(t,e,s){const i=Object.keys(s).length?Object.entries(s).map(([t,e])=>({id:t,poly:e})):this.host._spaceModel()?.rooms;if(!i?.length)return null;const o=this.host._spaceWalls;if(!o.length)return null;const a=this.host._openCuts(),n=Le(i,t,o,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc);if(!n||n.length!==e.length)return null;const r=this.host._cellCm/this.host._gridPitch;return e.map((t,s)=>Ee(e,s,n)*r)}_renderResizeMeasurements(){const t=this.host._resize.liveLabels;if(!t?.length)return d;const e=t.filter(t=>"length"===t.kind),s=t.filter(t=>"area"===t.kind);return f`
  • ${s.map_id||r("vac.route_map_default")} @@ -554,7 +554,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bb91e548ad4161d1eec31d88569f3a77e478 .previewfacts > div { grid-template-columns: minmax(0, 1fr); gap: 2px; } } `],customElements.get("hp-device-preview")||customElements.define("hp-device-preview",fa);const ba={revision:0,topologies:[],states:{}};class va extends M{constructor(){super(...arguments),this.value={enabled:!1,z2mBaseTopics:[]},this.savedEnabled=!1,this.devices=[],this._runtime=null,this._snapshot=ba,this._topicText="zigbee2mqtt",this._invalidTopic=!1}disconnectedCallback(){this._release?.(),this._release=void 0,super.disconnectedCallback()}updated(t){t.has("hass")&&(this._release?.(),this._release=void 0,this._runtime=null,this._snapshot=ba),this.savedEnabled&&this._admin&&this._ensureRuntime()}willUpdate(t){t.has("value")&&(this._topicText=(this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]).join("\n"),this._invalidTopic=!1)}get _admin(){return!0===this.hass?.user?.is_admin}_t(t,e){return fo(l(this.hass),t,e)}_help(){const t=l(this.hass);return bo(t,"help")&&bo(t,"help_aria")?p``:d}async _ensureRuntime(){return this._runtime||(this._runtime=await import("./zigbee-topology-runtime-foMTa-yu.js"),this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this._release=this._runtime.subscribeZigbeeTopology(this.hass,()=>{this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this.requestUpdate()}),this.requestUpdate()),this._runtime}_emit(t){this._admin&&this.dispatchEvent(new CustomEvent("hp-topology-settings-change",{detail:t,bubbles:!0,composed:!0}))}_topics(){return this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]}_editTopics(t){this._topicText=t;const e=t.split(/[\r\n,]+/).map(t=>t.trim()).filter(Boolean),s=e.map(F).filter(Boolean);this._invalidTopic=s.length!==e.length,this._invalidTopic?this.requestUpdate():this._emit({...this.value,z2mBaseTopics:[...new Set(s)].slice(0,8)})}_status(t){const e=this._snapshot.states[t];if(!e)return this._t("status_idle");if("loading"===e.phase)return this._t("status_loading");if("error"===e.phase)return this._t(`error_${e.error||"provider"}`);if("ready"!==e.phase||!e.obtainedAt)return this._t("status_idle");const s=new Date(e.obtainedAt).toLocaleTimeString(l(this.hass),{hour:"2-digit",minute:"2-digit"}),i=this._snapshot.topologies.find(e=>"zha"===t?"zha"===e.provider:`z2m:${e.instanceId}`===t),o=!!i&&!!this.registry&&vo(i,this.devices,this.registry).warnings.length>0;return e.partial||o?this._t("status_partial",{time:s}):i&&!i.links.length?this._t("status_no_links",{time:s}):this._t(Date.now()-e.obtainedAt>yo?"status_stale":"status_ready",{time:s})}_busy(t){return"loading"===this._snapshot.states[t]?.phase}async _readZha(){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).readZhaTopology(this.hass)}async _refreshZ2m(t){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).refreshZ2mTopology(this.hass,t)}render(){const t=this._admin,e=this.value.enabled,s=t&&this.savedEnabled,i=this._topics();return p` + .ariaLabel=${this._t("help_aria")}>`:d}async _ensureRuntime(){return this._runtime||(this._runtime=await import("./zigbee-topology-runtime-PXmJ-UR0.js"),this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this._release=this._runtime.subscribeZigbeeTopology(this.hass,()=>{this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this.requestUpdate()}),this.requestUpdate()),this._runtime}_emit(t){this._admin&&this.dispatchEvent(new CustomEvent("hp-topology-settings-change",{detail:t,bubbles:!0,composed:!0}))}_topics(){return this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]}_editTopics(t){this._topicText=t;const e=t.split(/[\r\n,]+/).map(t=>t.trim()).filter(Boolean),s=e.map(F).filter(Boolean);this._invalidTopic=s.length!==e.length,this._invalidTopic?this.requestUpdate():this._emit({...this.value,z2mBaseTopics:[...new Set(s)].slice(0,8)})}_status(t){const e=this._snapshot.states[t];if(!e)return this._t("status_idle");if("loading"===e.phase)return this._t("status_loading");if("error"===e.phase)return this._t(`error_${e.error||"provider"}`);if("ready"!==e.phase||!e.obtainedAt)return this._t("status_idle");const s=new Date(e.obtainedAt).toLocaleTimeString(l(this.hass),{hour:"2-digit",minute:"2-digit"}),i=this._snapshot.topologies.find(e=>"zha"===t?"zha"===e.provider:`z2m:${e.instanceId}`===t),o=!!i&&!!this.registry&&vo(i,this.devices,this.registry).warnings.length>0;return e.partial||o?this._t("status_partial",{time:s}):i&&!i.links.length?this._t("status_no_links",{time:s}):this._t(Date.now()-e.obtainedAt>yo?"status_stale":"status_ready",{time:s})}_busy(t){return"loading"===this._snapshot.states[t]?.phase}async _readZha(){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).readZhaTopology(this.hass)}async _refreshZ2m(t){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).refreshZ2mTopology(this.hass,t)}render(){const t=this._admin,e=this.value.enabled,s=t&&this.savedEnabled,i=this._topics();return p`
    ${this._t("title")}${this._help()}
    - `}}const oc=(t,e)=>t[0]*e[1]-t[1]*e[0],ac=(t,e)=>t[0]*e[0]+t[1]*e[1],nc=(t,e)=>[t[0]-e[0],t[1]-e[1]],rc=(t,e,s)=>[t[0]+e[0]*s,t[1]+e[1]*s];function lc(t,e,s){return Math.abs(oc(t,e))<=s}function hc(t,e,s){return Math.abs(oc(nc(t,e),s))}function cc(t,e,s,i,o){const a=e[0]-t[0],n=e[1]-t[1],r=Math.hypot(a,n);if(!(r>o&&s>0))return[];const l=[a/r,n/r];return function(t,e,s){const i=e.map(([e,s])=>[Math.max(0,Math.min(e,s)),Math.min(t,Math.max(e,s))]).filter(([t,e])=>e>t+s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of i){const e=o[o.length-1];!e||t[0]>e[1]+s?o.push([...t]):e[1]=Math.max(e[1],t[1])}const a=[];let n=0;for(const[t,e]of o)t>n+s&&a.push([n,t]),n=Math.max(n,e);return t>n+s&&a.push([n,t]),a}(r,i.flatMap(e=>{const i=e.b[0]-e.a[0],a=e.b[1]-e.a[1],n=Math.hypot(i,a);if(!(n>o&&lc(l,[i/n,a/n],1e-6)))return[];if(hc(e.a,t,l)>1.1*Math.max(s,o)||hc(e.b,t,l)>1.1*Math.max(s,o))return[];return[[ac(nc(e.a,t),l),ac(nc(e.b,t),l)]]}),o).flatMap(([e,i])=>{const o=Xt({a:rc(t,l,e),b:rc(t,l,i),halfDepth:s});return o?[o]:[]})}function dc(t){const e=t.coordScale??1,s=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),i=[];for(const s of t.rooms||[]){if(!s?.id)continue;const o=ot(t.rooms,s.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!o||o.poly.length<3)continue;const a=Jt(o.poly,o.offsets);!a||a.length<3||i.push({roomId:s.id,profile:o,inner:a})}i.sort((t,e)=>t.roomId.localeCompare(e.roomId));const o=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,s=[Math.cos(e),Math.sin(e)],i=Math.max(0,t.length)/2;return{a:rc([t.x,t.y],s,-i),b:rc([t.x,t.y],s,i)}}),a=[];for(const i of Yt(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of cc(i.a,i.b,i.depthUnits/2,o,s))a.push({body:t});const n=new Map;for(const e of t.partitionCuts||[]){const t=n.get(e.hostId)||[];t.push(e),n.set(e.hostId,t)}for(const e of t.partitions||[]){const i=x(e.cm,t.cellCm,t.gridPitch)/2;for(const t of cc(e.a,e.b,i,n.get(e.id)||[],s))a.push({body:t,partitionId:e.id})}return{rooms:i,boundaries:a,epsilon:s}}function pc(t,e,s,i){const o=t.profile.offsets[e];if(!(o>0))return null;const a=function(t,e){const s=t[e],i=t[(e+1)%t.length],o=i[0]-s[0],a=i[1]-s[1],n=Math.hypot(o,a)||1;return function(t){let e=0;for(let s=0;s=0?[-a/n,o/n]:[a/n,-o/n]}(t.profile.poly,e),n=rc(s.center,a,o),r=[];for(let e=0;ei&&lc(s.axis,[l[0]/h,l[1]/h],1e-6)))continue;if(hc(o,n,s.axis)>i||hc(a,n,s.axis)>i)continue;const c=ac(nc(o,n),s.axis),d=ac(nc(a,n),s.axis);r.push([Math.min(c,d),Math.max(c,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const s=[];for(const i of t){const t=s[s.length-1];!t||i[0]>t[1]+e?s.push([...i]):t[1]=Math.max(t[1],i[1])}return s}(r,i).find(([t,e])=>t<=i&&e>=-i);if(!l)return null;const[h,c]=l,d=rc(n,s.axis,-s.half),p=rc(n,s.axis,s.half),u=Math.max(0,-s.half-h),_=Math.max(0,c-s.half),m=u>0?rc(n,s.axis,h):d,g=_>0?rc(n,s.axis,c):p,f=ac(a,s.normal)>=0?1:-1,b=(e,i,o)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:s.axis,labelNormal:a,distance:o,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:b(d,m,u),right:b(p,g,_)}}function uc(t){const e=rc(t.center,t.axis,-t.half),s=rc(t.center,t.axis,t.half),i=rc(t.center,t.axis,Math.min(-t.half,t.targetLo)),o=rc(t.center,t.axis,Math.max(t.half,t.targetHi)),a=(e,s)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(s[0]-e[0],s[1]-e[1]),source:"host-end"});return[a(e,i),a(s,o)]}function _c(t,e,s,i){const o=nc(s,e),a=ac(o,o);if(!(a>i*i))return Math.hypot(...nc(t,e))<=i;const n=ac(nc(t,e),o)/a;if(n<-i||n>1+i)return!1;const r=rc(e,o,Math.max(0,Math.min(1,n)));return Math.hypot(...nc(t,r))<=i}function mc(t,e,s){let i=!1;for(let o=0,a=e.length-1;ot[1]!=h>t[1]&&t[0]<(l-n)*(t[1]-r)/(h-r)+n&&(i=!i)}return i}function gc(t,e,s,i,o,a){const n=nc(i,s),r=oc(e,n);if(Math.abs(r)<=a)return null;const l=nc(s,t),h=oc(l,n)/r,c=oc(l,e)/r;return h<-a||h>o+a||c<-a||c>1+a?null:Math.max(0,Math.min(o,h))}function fc(t,e,s){const i=uc(s),o="partition"===t.host?.kind?t.host.id:void 0;return[{base:i[0],direction:[-s.axis[0],-s.axis[1]]},{base:i[1],direction:s.axis}].map(({base:t,direction:s})=>{const i=t.distance,a=function(t,e,s,i,o,a){let n=null;for(const r of i)if(!o||r.partitionId!==o){if(mc(t,r.body,a))return 0;for(let i=0;iac(nc(t,o),s));return{center:o,axis:s,normal:i,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...a),targetHi:Math.max(...a)}}(t),i=e.rooms.flatMap(t=>{const i=function(t,e,s){const{profile:i}=t;let o=null;for(let t=0;t0))continue;const a=i.poly[t],n=i.poly[(t+1)%i.poly.length],r=nc(n,a),l=Math.hypot(r[0],r[1]);if(!(l>s&&lc(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(hc(a,e.center,e.axis)>s||hc(n,e.center,e.axis)>s)continue;const h=ac(nc(a,e.center),e.axis),c=ac(nc(n,e.center),e.axis),d=Math.min(h,c),p=Math.max(h,c);if(d>-e.half+s||p0?d:p<0?-p:0);(!o||u2)return uc(s);if(i.length){const t=i.map(({room:t,edge:i})=>pc(t,i,s,e.epsilon));if(t.some(t=>!t))return uc(s);const o=t;return[...o.map(t=>t.left),...o.map(t=>t.right)]}return fc(t,e,s)}const vc="1.72.0",yc={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},$c={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},wc=2e3,kc=1e3,xc=(t,e,s,i)=>{for(t.delete(e),t.set(e,s);t.size>i;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Sc=1e3,Mc=2e3,Dc=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}},Cc="bb91e548ad4161d1eec31d88569f3a77e47865846e524dd99d718a3ecd348caa";class Pc{constructor(t){this.host=t,this._junctionBaselineCache=new WeakMap,this._resizePreviewNodes=null,this._resizeBaselineLimits=[],this._resizeBaseFrameStable=!0,this._supportPreviewGeneration=0,this._decorAssetGuardReplace=null,this._undoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this.host._showToast(this.host._t("history.undone",{name:t.name})):this.host._geometryHistory.clear())},this._redoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this.host._showToast(this.host._t("history.redone",{name:t.name})):this.host._geometryHistory.clear())},this._savePhysicalDialog=()=>{const t=this.host._physicalDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=ro(t.cm);if(null==i)return void this._showPhysicalRange("column"===t.kind?Zt:100,"column"===t.kind?1:0);const o=this.host._imperial?2.54*i:i,a="column"===t.kind?Zt:100,n="column"===t.kind?1:0;if(!Number.isFinite(o)||oa)return void this._showPhysicalRange(a,n);if("column"===t.kind){const e=s.wall_columns.find(e=>e.id===t.id);if(!e)return;const i=ro(t.angle||"0");if("circle"!==t.shape&&(null==i||i<0||i>=90))return void this.host._showToast(this.host._t("toast.physical_angle"));const a="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:o}:{id:t.id,shape:"square",center:e.center,cm:o,angle:i};if(s.wall_columns.some(e=>e.id!==t.id&&Qt(e,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const s=(e.partitions||[]).find(e=>e.id===t.id);if(s&&0===o&&te(e.openings,{kind:"partition",id:t.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));s&&(s.cm=o)}else if("column"===t.kind){const s=(e.wall_columns||[]).find(e=>e.id===t.id);s&&(s.cm=ee(o),s.shape="circle"===t.shape?"circle":"square","square"===s.shape?s.angle=ro(t.angle||"0"):delete s.angle)}else{const s=(e.room_drafts||[]).find(e=>e.id===t.id);s?.segments?.[t.segment||0]&&(s.segments[t.segment||0].cm=o)}const l=this._commitPhysicalGeometry(this.host._t("history.physical_edit"),r);this.host._physicalDialog=null,l||this.host.requestUpdate()},this._deletePhysicalSelection=async()=>{const t=this.host._physicalSel,e=this.host._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void await this._deleteDraftWhole();const s=this._geometrySnapshot();if("partition"===t.kind){const s=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(s.length)return void(this.host._partitionDeleteDialog={id:t.id,openings:s.map(t=>JSON.parse(JSON.stringify(t)))})}const i="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[i]=(e[i]||[]).filter(e=>e.id!==t.id),e[i].length||delete e[i],this.host._activeDraftId===t.id&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._confirmPartitionDelete=()=>{const t=this.host._partitionDeleteDialog,e=this.host._curSpaceCfg;if(!t||!e)return;const s=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this.host._partitionDeleteDialog=null,this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._deleteDraftWhole=async()=>{const t="draft"===this.host._physicalDialog?.kind?this.host._physicalDialog.id:"draft"===this.host._physicalSel?.kind?this.host._physicalSel.id:null,e=this.host._space;if(!t||!this.host._curSpaceCfg)return;if(!await this.host._confirmDanger({key:"delete-draft",kind:"destructive",title:this.host._t("confirm.delete_draft_title"),message:this.host._t("confirm.delete_draft_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")})||this.host._space!==e)return;const s=this.host._curSpaceCfg;if(!s||!(s.room_drafts||[]).some(e=>e.id===t))return;const i=this._geometrySnapshot();s.room_drafts=(s.room_drafts||[]).filter(e=>e.id!==t),s.room_drafts.length||delete s.room_drafts,this.host._activeDraftId===t&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),i)},this._deleteDraftSegment=async()=>{const t=this.host._physicalDialog,e=this.host._space;if(!t||"draft"!==t.kind||!this.host._curSpaceCfg)return;const s=t.id,i=t.segment||0,o=await this.host._confirmDanger({key:"delete-draft-segment",kind:"destructive",title:this.host._t("confirm.delete_draft_segment_title"),message:this.host._t("confirm.delete_draft_segment_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._physicalDialog;if(!o||this.host._space!==e||"draft"!==a?.kind||a.id!==s||(a.segment||0)!==i)return;const n=this.host._curSpaceCfg;if(!n)return;const r=(n.room_drafts||[]).findIndex(t=>t.id===s);if(r<0)return;const l=n.room_drafts[r];if(!Array.isArray(l.segments)||!Number.isInteger(i)||i<0||i>=l.segments.length)return;const h=i,c=[],d=l.points.slice(0,h+1),p=l.points.slice(h+1);if(d.length>=2&&c.push({id:l.id,points:d,segments:l.segments.slice(0,h)}),p.length>=2&&c.push({id:c.length?`${l.id}-${Date.now().toString(36)}`:l.id,points:p,segments:l.segments.slice(h+1)}),2===c.length&&n.room_drafts.length>=200)return void this.host._showToast(this.host._t("toast.physical_limit"));const u=this._geometrySnapshot();n.room_drafts.splice(r,1,...c),n.room_drafts.length||delete n.room_drafts,this.host._activeDraftId===l.id&&this._cancelPath(),this.host._physicalDialog=null,this.host._physicalSel=c.length?{kind:"draft",id:c[0].id}:null,this._commitPhysicalGeometry(this.host._t("history.draft_segment_delete"),u)},this._furnShiftListener=t=>{if("Shift"!==t.key)return;const e=this.host._furnPreviewInput;if(!e)return;const s="keydown"===t.type;e.free!==s&&(this.host._furnPreviewInput={...e,free:s},this.host.requestUpdate())},this._furnShiftAttached=!1,this._confirmRoomDelete=t=>{const e=this.host._roomDeleteDialog,s=this.host._curSpaceCfg,i=this.host._spaceModel();if(!e||!s||!i)return;const o=i.rooms.find(t=>t.id===e.roomId);if(!o)return void(this.host._roomDeleteDialog=null);const a=this.host._openCuts(),n=Rh(ut(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc).filter(t=>t.roomId===o.id),i.partitions,this.host._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this.host._gridPitch),r=new Set(n.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(s.partitions||[]).length+r>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const l=this._geometrySnapshot(),h=se(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc);if(t){s.partitions||=[];const t=new Map,e=new Map,i=t=>{const e=(s.wall_segments||[]).find(e=>{const s=[Number(e.a?.[0])*Sc,Number(e.a?.[1])*Sc],i=[Number(e.b?.[0])*Sc,Number(e.b?.[1])*Sc];return this._samePt(t.a,s)&&this._samePt(t.b,i)||this._samePt(t.a,i)&&this._samePt(t.b,s)});return"string"==typeof e?.id&&e.id?e.id:null},o=Date.now().toString(36);for(const a of n.materialize){let n=a.reusePartitionId?s.partitions.find(t=>t.id===a.reusePartitionId):e.get(a.interval.key);n||(n={id:i(a.interval)||`partition-room-${o}-${e.size}`,a:[a.interval.a[0]/Sc,a.interval.a[1]/Sc],b:[a.interval.b[0]/Sc,a.interval.b[1]/Sc],cm:a.interval.cm},s.partitions.push(n),e.set(a.interval.key,n)),t.set(a.interval.key,n)}for(const e of s.openings||[]){const s=n.openingIntervals.get(e.id),i=s?t.get(s):null,o=this.host._openingsR.find(t=>t.id===e.id);if(!i||!o)continue;const a={a:[i.a[0]*Sc,i.a[1]*Sc],b:[i.b[0]*Sc,i.b[1]*Sc]};e.host={kind:"partition",id:i.id,t:Ah([o.rx,o.ry],a)}}}else if(n.removeOpeningIds.length){const t=new Set(n.removeOpeningIds);s.openings=(s.openings||[]).filter(e=>!t.has(e.id)),s.openings.length||delete s.openings}s.rooms=s.rooms.filter(t=>t.id!==o.id),this.host._cfgEpoch++;const c=this.host._normalizeWalls(h,this.host._openCuts());c.length?s.walls=c:delete s.walls,this.host._roomDeleteDialog=null,this._commitPhysicalGeometry(this.host._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this.host._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingRebindId=e,this.host._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this.host._openingPresetRevision},this.host._openingDialog=null,this.host._openingHoverCandidate=null)},this._deviceInboxTabKey=t=>{if("ArrowLeft"!==t.key&&"ArrowRight"!==t.key)return;const e=this.host._deviceInbox;if(!e)return;const s=["on_plan","available","hidden","readd"],i="ArrowRight"===t.key?1:-1,o=(s.indexOf(e.tab)+i+s.length)%s.length;this.host._deviceInbox={...e,tab:s[o],limit:100,onlyNew:!1},t.preventDefault()},this._keepClosedAsPartitions=()=>{if(this.host._wallFaceBatch)return void this._decideWallFace(!1);if(!this.host._contourClosed||this.host._pendingSplit||!this.host._curSpaceCfg)return;const t=this.host._curSpaceCfg,e=this.host._path.slice(0,-1);if((t.partitions||[]).length+e.length>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const s=this._geometrySnapshot(),i=nh(e.length,[...this.host._draftSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,_t);t.partitions||=[];const o=Date.now().toString(36),a=this.host._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this.host._activeDraftId):null,n=this._draftSegmentsForPath(this.host._path,a,i);for(let s=0;st.id!==this.host._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this.host._t("history.contour_to_partitions"),s),this.host._roomDialog=!1,this.host._path=[],delete this.host._resumeDraftBySpace[this.host._space],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null},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"}),e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}},this._openSettingsDialog=()=>{if(!this.host._norm)return;const t=this.host._glowRadiusCm,e=this.host._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this.host._settingsDialog={colors:JSON.parse(JSON.stringify(this.host._fillColors)),glowRadius:e,bgColor:le(this.host._settings,{bgColor:null})||null,northDeg:re(this.host._settings,{}),bgMode:ne(this.host._settings,{}),sunRays:ae(this.host._settings,{}),showRoomTooltip:oe(this.host._settings),zigbeeTopology:ie(this.host._settings),busy:!1}},this._openSupportDialog=()=>{this.host._norm&&this.host._canEdit&&(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPreviewGeneration+=1,this.host._supportDialog={draftId:Jh("draft"),idempotencyKey:Jh("report"),submissionFingerprint:"",contact:"",message:"",attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:"",reportId:""})},this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this.host._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._openBackupExport=()=>{this.host._settingsDialog=null,this.host._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._decorStylePersistTimer=null,this._openRulesDialog=()=>{if(!this.host._norm)return;const t=this.host._settings.icon_rules,e=(t&&t.length?t:he).map(t=>({...t}));this.host._rulesDialog={rules:e,test:"",busy:!1}},this._discoveryPreviewMemo=null,this._decorImages=new ic(t,{decorSnap:(t,e)=>this._decorSnap(t,e),geometrySnapshot:()=>this._geometrySnapshot(),clearFurniturePreview:()=>this._clearFurniturePreview(),recordGeometry:(t,e)=>this._recordGeometry(t,e),saveConfig:()=>this._saveConfig(),saveShape:()=>this._decorSaveShape(),setGuardReplace:t=>{this._decorAssetGuardReplace=t},furnShiftDetach:()=>this._furnShiftDetach(),furnPick:t=>this._furnPick(t),furnFieldValue:t=>this._furnFieldValue(t),furnFieldToCm:t=>this._furnFieldToCm(t)}),t._editorSecondary=new Gh({root:()=>t.renderRoot,requestUpdate:()=>t.requestUpdate(),updateComplete:()=>t.updateComplete,clearTip:()=>{t._tip=null}}),t._resize=new tn}_routeLiveEditorUpdate(t,e){const s=jo(this.host,t,e);return!s&&this.host._resize.preview&&(this._resizeBaseFrameStable=!1),s}_commitLiveEditor(){!function(t){const e=t,s=Bo(t);s.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(s.raf),s.raf=0,Ko(s);const i=e.renderRoot?.querySelector("[data-hp-live-editor]");i&&g(d,i);const o=e.renderRoot?.querySelector("[data-hp-live-editor-html]");if(o){const t=e._viewOr(e._baseVb());g(e._renderLiveEditorMeasurements(t),o)}Wo(s,s.requestedRevision)}(this.host)}_disposeLiveEditor(){!function(t){No(t);const e=Ho.get(t);e&&(e.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e.raf),Ko(e),Wo(e,e.requestedRevision),Ho.delete(t))}(this.host)}async _whenLiveEditorSettled(){await this.host.updateComplete,await function(t){const e=Ho.get(t);if(!e||!e.raf||e.paintedRevision>=e.requestedRevision)return Promise.resolve();const s=e.requestedRevision;return new Promise(t=>e.waiters.push({revision:s,resolve:t}))}(this.host)}_queuePointerMove(t,e){Ao(this.host,t,e)}_flushPointerMove(t){Fo(this.host,t)}_cancelPointerMove(t){No(this.host,t)}_help(t){const e=`${t}.aria`,s=l(this.host.hass,this.host._config?.language);return ce(s,t)&&ce(s,e)?p``}}const oc=(t,e)=>t[0]*e[1]-t[1]*e[0],ac=(t,e)=>t[0]*e[0]+t[1]*e[1],nc=(t,e)=>[t[0]-e[0],t[1]-e[1]],rc=(t,e,s)=>[t[0]+e[0]*s,t[1]+e[1]*s];function lc(t,e,s){return Math.abs(oc(t,e))<=s}function hc(t,e,s){return Math.abs(oc(nc(t,e),s))}function cc(t,e,s,i,o){const a=e[0]-t[0],n=e[1]-t[1],r=Math.hypot(a,n);if(!(r>o&&s>0))return[];const l=[a/r,n/r];return function(t,e,s){const i=e.map(([e,s])=>[Math.max(0,Math.min(e,s)),Math.min(t,Math.max(e,s))]).filter(([t,e])=>e>t+s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of i){const e=o[o.length-1];!e||t[0]>e[1]+s?o.push([...t]):e[1]=Math.max(e[1],t[1])}const a=[];let n=0;for(const[t,e]of o)t>n+s&&a.push([n,t]),n=Math.max(n,e);return t>n+s&&a.push([n,t]),a}(r,i.flatMap(e=>{const i=e.b[0]-e.a[0],a=e.b[1]-e.a[1],n=Math.hypot(i,a);if(!(n>o&&lc(l,[i/n,a/n],1e-6)))return[];if(hc(e.a,t,l)>1.1*Math.max(s,o)||hc(e.b,t,l)>1.1*Math.max(s,o))return[];return[[ac(nc(e.a,t),l),ac(nc(e.b,t),l)]]}),o).flatMap(([e,i])=>{const o=Xt({a:rc(t,l,e),b:rc(t,l,i),halfDepth:s});return o?[o]:[]})}function dc(t){const e=t.coordScale??1,s=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),i=[];for(const s of t.rooms||[]){if(!s?.id)continue;const o=ot(t.rooms,s.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!o||o.poly.length<3)continue;const a=Jt(o.poly,o.offsets);!a||a.length<3||i.push({roomId:s.id,profile:o,inner:a})}i.sort((t,e)=>t.roomId.localeCompare(e.roomId));const o=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,s=[Math.cos(e),Math.sin(e)],i=Math.max(0,t.length)/2;return{a:rc([t.x,t.y],s,-i),b:rc([t.x,t.y],s,i)}}),a=[];for(const i of Yt(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of cc(i.a,i.b,i.depthUnits/2,o,s))a.push({body:t});const n=new Map;for(const e of t.partitionCuts||[]){const t=n.get(e.hostId)||[];t.push(e),n.set(e.hostId,t)}for(const e of t.partitions||[]){const i=x(e.cm,t.cellCm,t.gridPitch)/2;for(const t of cc(e.a,e.b,i,n.get(e.id)||[],s))a.push({body:t,partitionId:e.id})}return{rooms:i,boundaries:a,epsilon:s}}function pc(t,e,s,i){const o=t.profile.offsets[e];if(!(o>0))return null;const a=function(t,e){const s=t[e],i=t[(e+1)%t.length],o=i[0]-s[0],a=i[1]-s[1],n=Math.hypot(o,a)||1;return function(t){let e=0;for(let s=0;s=0?[-a/n,o/n]:[a/n,-o/n]}(t.profile.poly,e),n=rc(s.center,a,o),r=[];for(let e=0;ei&&lc(s.axis,[l[0]/h,l[1]/h],1e-6)))continue;if(hc(o,n,s.axis)>i||hc(a,n,s.axis)>i)continue;const c=ac(nc(o,n),s.axis),d=ac(nc(a,n),s.axis);r.push([Math.min(c,d),Math.max(c,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const s=[];for(const i of t){const t=s[s.length-1];!t||i[0]>t[1]+e?s.push([...i]):t[1]=Math.max(t[1],i[1])}return s}(r,i).find(([t,e])=>t<=i&&e>=-i);if(!l)return null;const[h,c]=l,d=rc(n,s.axis,-s.half),p=rc(n,s.axis,s.half),u=Math.max(0,-s.half-h),_=Math.max(0,c-s.half),m=u>0?rc(n,s.axis,h):d,g=_>0?rc(n,s.axis,c):p,f=ac(a,s.normal)>=0?1:-1,b=(e,i,o)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:s.axis,labelNormal:a,distance:o,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:b(d,m,u),right:b(p,g,_)}}function uc(t){const e=rc(t.center,t.axis,-t.half),s=rc(t.center,t.axis,t.half),i=rc(t.center,t.axis,Math.min(-t.half,t.targetLo)),o=rc(t.center,t.axis,Math.max(t.half,t.targetHi)),a=(e,s)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(s[0]-e[0],s[1]-e[1]),source:"host-end"});return[a(e,i),a(s,o)]}function _c(t,e,s,i){const o=nc(s,e),a=ac(o,o);if(!(a>i*i))return Math.hypot(...nc(t,e))<=i;const n=ac(nc(t,e),o)/a;if(n<-i||n>1+i)return!1;const r=rc(e,o,Math.max(0,Math.min(1,n)));return Math.hypot(...nc(t,r))<=i}function mc(t,e,s){let i=!1;for(let o=0,a=e.length-1;ot[1]!=h>t[1]&&t[0]<(l-n)*(t[1]-r)/(h-r)+n&&(i=!i)}return i}function gc(t,e,s,i,o,a){const n=nc(i,s),r=oc(e,n);if(Math.abs(r)<=a)return null;const l=nc(s,t),h=oc(l,n)/r,c=oc(l,e)/r;return h<-a||h>o+a||c<-a||c>1+a?null:Math.max(0,Math.min(o,h))}function fc(t,e,s){const i=uc(s),o="partition"===t.host?.kind?t.host.id:void 0;return[{base:i[0],direction:[-s.axis[0],-s.axis[1]]},{base:i[1],direction:s.axis}].map(({base:t,direction:s})=>{const i=t.distance,a=function(t,e,s,i,o,a){let n=null;for(const r of i)if(!o||r.partitionId!==o){if(mc(t,r.body,a))return 0;for(let i=0;iac(nc(t,o),s));return{center:o,axis:s,normal:i,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...a),targetHi:Math.max(...a)}}(t),i=e.rooms.flatMap(t=>{const i=function(t,e,s){const{profile:i}=t;let o=null;for(let t=0;t0))continue;const a=i.poly[t],n=i.poly[(t+1)%i.poly.length],r=nc(n,a),l=Math.hypot(r[0],r[1]);if(!(l>s&&lc(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(hc(a,e.center,e.axis)>s||hc(n,e.center,e.axis)>s)continue;const h=ac(nc(a,e.center),e.axis),c=ac(nc(n,e.center),e.axis),d=Math.min(h,c),p=Math.max(h,c);if(d>-e.half+s||p0?d:p<0?-p:0);(!o||u2)return uc(s);if(i.length){const t=i.map(({room:t,edge:i})=>pc(t,i,s,e.epsilon));if(t.some(t=>!t))return uc(s);const o=t;return[...o.map(t=>t.left),...o.map(t=>t.right)]}return fc(t,e,s)}const vc="1.72.0",yc={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},$c={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},wc=2e3,kc=1e3,xc=(t,e,s,i)=>{for(t.delete(e),t.set(e,s);t.size>i;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Sc=1e3,Mc=2e3,Dc=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}},Cc="ee07f194e535fbbe6bcab60998a32b7bd32025914663740939ae9f7942b5cd0d";class Pc{constructor(t){this.host=t,this._junctionBaselineCache=new WeakMap,this._resizePreviewNodes=null,this._resizeBaselineLimits=[],this._resizeBaseFrameStable=!0,this._supportPreviewGeneration=0,this._decorAssetGuardReplace=null,this._undoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this.host._showToast(this.host._t("history.undone",{name:t.name})):this.host._geometryHistory.clear())},this._redoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this.host._showToast(this.host._t("history.redone",{name:t.name})):this.host._geometryHistory.clear())},this._savePhysicalDialog=()=>{const t=this.host._physicalDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=ro(t.cm);if(null==i)return void this._showPhysicalRange("column"===t.kind?Zt:100,"column"===t.kind?1:0);const o=this.host._imperial?2.54*i:i,a="column"===t.kind?Zt:100,n="column"===t.kind?1:0;if(!Number.isFinite(o)||oa)return void this._showPhysicalRange(a,n);if("column"===t.kind){const e=s.wall_columns.find(e=>e.id===t.id);if(!e)return;const i=ro(t.angle||"0");if("circle"!==t.shape&&(null==i||i<0||i>=90))return void this.host._showToast(this.host._t("toast.physical_angle"));const a="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:o}:{id:t.id,shape:"square",center:e.center,cm:o,angle:i};if(s.wall_columns.some(e=>e.id!==t.id&&Qt(e,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const s=(e.partitions||[]).find(e=>e.id===t.id);if(s&&0===o&&te(e.openings,{kind:"partition",id:t.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));s&&(s.cm=o)}else if("column"===t.kind){const s=(e.wall_columns||[]).find(e=>e.id===t.id);s&&(s.cm=ee(o),s.shape="circle"===t.shape?"circle":"square","square"===s.shape?s.angle=ro(t.angle||"0"):delete s.angle)}else{const s=(e.room_drafts||[]).find(e=>e.id===t.id);s?.segments?.[t.segment||0]&&(s.segments[t.segment||0].cm=o)}const l=this._commitPhysicalGeometry(this.host._t("history.physical_edit"),r);this.host._physicalDialog=null,l||this.host.requestUpdate()},this._deletePhysicalSelection=async()=>{const t=this.host._physicalSel,e=this.host._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void await this._deleteDraftWhole();const s=this._geometrySnapshot();if("partition"===t.kind){const s=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(s.length)return void(this.host._partitionDeleteDialog={id:t.id,openings:s.map(t=>JSON.parse(JSON.stringify(t)))})}const i="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[i]=(e[i]||[]).filter(e=>e.id!==t.id),e[i].length||delete e[i],this.host._activeDraftId===t.id&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._confirmPartitionDelete=()=>{const t=this.host._partitionDeleteDialog,e=this.host._curSpaceCfg;if(!t||!e)return;const s=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this.host._partitionDeleteDialog=null,this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._deleteDraftWhole=async()=>{const t="draft"===this.host._physicalDialog?.kind?this.host._physicalDialog.id:"draft"===this.host._physicalSel?.kind?this.host._physicalSel.id:null,e=this.host._space;if(!t||!this.host._curSpaceCfg)return;if(!await this.host._confirmDanger({key:"delete-draft",kind:"destructive",title:this.host._t("confirm.delete_draft_title"),message:this.host._t("confirm.delete_draft_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")})||this.host._space!==e)return;const s=this.host._curSpaceCfg;if(!s||!(s.room_drafts||[]).some(e=>e.id===t))return;const i=this._geometrySnapshot();s.room_drafts=(s.room_drafts||[]).filter(e=>e.id!==t),s.room_drafts.length||delete s.room_drafts,this.host._activeDraftId===t&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),i)},this._deleteDraftSegment=async()=>{const t=this.host._physicalDialog,e=this.host._space;if(!t||"draft"!==t.kind||!this.host._curSpaceCfg)return;const s=t.id,i=t.segment||0,o=await this.host._confirmDanger({key:"delete-draft-segment",kind:"destructive",title:this.host._t("confirm.delete_draft_segment_title"),message:this.host._t("confirm.delete_draft_segment_body"),confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._physicalDialog;if(!o||this.host._space!==e||"draft"!==a?.kind||a.id!==s||(a.segment||0)!==i)return;const n=this.host._curSpaceCfg;if(!n)return;const r=(n.room_drafts||[]).findIndex(t=>t.id===s);if(r<0)return;const l=n.room_drafts[r];if(!Array.isArray(l.segments)||!Number.isInteger(i)||i<0||i>=l.segments.length)return;const h=i,c=[],d=l.points.slice(0,h+1),p=l.points.slice(h+1);if(d.length>=2&&c.push({id:l.id,points:d,segments:l.segments.slice(0,h)}),p.length>=2&&c.push({id:c.length?`${l.id}-${Date.now().toString(36)}`:l.id,points:p,segments:l.segments.slice(h+1)}),2===c.length&&n.room_drafts.length>=200)return void this.host._showToast(this.host._t("toast.physical_limit"));const u=this._geometrySnapshot();n.room_drafts.splice(r,1,...c),n.room_drafts.length||delete n.room_drafts,this.host._activeDraftId===l.id&&this._cancelPath(),this.host._physicalDialog=null,this.host._physicalSel=c.length?{kind:"draft",id:c[0].id}:null,this._commitPhysicalGeometry(this.host._t("history.draft_segment_delete"),u)},this._furnShiftListener=t=>{if("Shift"!==t.key)return;const e=this.host._furnPreviewInput;if(!e)return;const s="keydown"===t.type;e.free!==s&&(this.host._furnPreviewInput={...e,free:s},this.host.requestUpdate())},this._furnShiftAttached=!1,this._confirmRoomDelete=t=>{const e=this.host._roomDeleteDialog,s=this.host._curSpaceCfg,i=this.host._spaceModel();if(!e||!s||!i)return;const o=i.rooms.find(t=>t.id===e.roomId);if(!o)return void(this.host._roomDeleteDialog=null);const a=this.host._openCuts(),n=Rh(ut(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc).filter(t=>t.roomId===o.id),i.partitions,this.host._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this.host._gridPitch),r=new Set(n.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(s.partitions||[]).length+r>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const l=this._geometrySnapshot(),h=se(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc);if(t){s.partitions||=[];const t=new Map,e=new Map,i=t=>{const e=(s.wall_segments||[]).find(e=>{const s=[Number(e.a?.[0])*Sc,Number(e.a?.[1])*Sc],i=[Number(e.b?.[0])*Sc,Number(e.b?.[1])*Sc];return this._samePt(t.a,s)&&this._samePt(t.b,i)||this._samePt(t.a,i)&&this._samePt(t.b,s)});return"string"==typeof e?.id&&e.id?e.id:null},o=Date.now().toString(36);for(const a of n.materialize){let n=a.reusePartitionId?s.partitions.find(t=>t.id===a.reusePartitionId):e.get(a.interval.key);n||(n={id:i(a.interval)||`partition-room-${o}-${e.size}`,a:[a.interval.a[0]/Sc,a.interval.a[1]/Sc],b:[a.interval.b[0]/Sc,a.interval.b[1]/Sc],cm:a.interval.cm},s.partitions.push(n),e.set(a.interval.key,n)),t.set(a.interval.key,n)}for(const e of s.openings||[]){const s=n.openingIntervals.get(e.id),i=s?t.get(s):null,o=this.host._openingsR.find(t=>t.id===e.id);if(!i||!o)continue;const a={a:[i.a[0]*Sc,i.a[1]*Sc],b:[i.b[0]*Sc,i.b[1]*Sc]};e.host={kind:"partition",id:i.id,t:Ah([o.rx,o.ry],a)}}}else if(n.removeOpeningIds.length){const t=new Set(n.removeOpeningIds);s.openings=(s.openings||[]).filter(e=>!t.has(e.id)),s.openings.length||delete s.openings}s.rooms=s.rooms.filter(t=>t.id!==o.id),this.host._cfgEpoch++;const c=this.host._normalizeWalls(h,this.host._openCuts());c.length?s.walls=c:delete s.walls,this.host._roomDeleteDialog=null,this._commitPhysicalGeometry(this.host._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this.host._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingRebindId=e,this.host._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this.host._openingPresetRevision},this.host._openingDialog=null,this.host._openingHoverCandidate=null)},this._deviceInboxTabKey=t=>{if("ArrowLeft"!==t.key&&"ArrowRight"!==t.key)return;const e=this.host._deviceInbox;if(!e)return;const s=["on_plan","available","hidden","readd"],i="ArrowRight"===t.key?1:-1,o=(s.indexOf(e.tab)+i+s.length)%s.length;this.host._deviceInbox={...e,tab:s[o],limit:100,onlyNew:!1},t.preventDefault()},this._keepClosedAsPartitions=()=>{if(this.host._wallFaceBatch)return void this._decideWallFace(!1);if(!this.host._contourClosed||this.host._pendingSplit||!this.host._curSpaceCfg)return;const t=this.host._curSpaceCfg,e=this.host._path.slice(0,-1);if((t.partitions||[]).length+e.length>Mc)return void this.host._showToast(this.host._t("toast.physical_limit"));const s=this._geometrySnapshot(),i=nh(e.length,[...this.host._draftSegmentCms,this.host._closingWallCm??void 0],this.host._drawWallCm,_t);t.partitions||=[];const o=Date.now().toString(36),a=this.host._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this.host._activeDraftId):null,n=this._draftSegmentsForPath(this.host._path,a,i);for(let s=0;st.id!==this.host._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this.host._t("history.contour_to_partitions"),s),this.host._roomDialog=!1,this.host._path=[],delete this.host._resumeDraftBySpace[this.host._space],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null},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"}),e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}},this._openSettingsDialog=()=>{if(!this.host._norm)return;const t=this.host._glowRadiusCm,e=this.host._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this.host._settingsDialog={colors:JSON.parse(JSON.stringify(this.host._fillColors)),glowRadius:e,bgColor:le(this.host._settings,{bgColor:null})||null,northDeg:re(this.host._settings,{}),bgMode:ne(this.host._settings,{}),sunRays:ae(this.host._settings,{}),showRoomTooltip:oe(this.host._settings),zigbeeTopology:ie(this.host._settings),busy:!1}},this._openSupportDialog=()=>{this.host._norm&&this.host._canEdit&&(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPreviewGeneration+=1,this.host._supportDialog={draftId:Jh("draft"),idempotencyKey:Jh("report"),submissionFingerprint:"",contact:"",message:"",attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:"",reportId:""})},this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this.host._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._openBackupExport=()=>{this.host._settingsDialog=null,this.host._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._decorStylePersistTimer=null,this._openRulesDialog=()=>{if(!this.host._norm)return;const t=this.host._settings.icon_rules,e=(t&&t.length?t:he).map(t=>({...t}));this.host._rulesDialog={rules:e,test:"",busy:!1}},this._discoveryPreviewMemo=null,this._decorImages=new ic(t,{decorSnap:(t,e)=>this._decorSnap(t,e),geometrySnapshot:()=>this._geometrySnapshot(),clearFurniturePreview:()=>this._clearFurniturePreview(),recordGeometry:(t,e)=>this._recordGeometry(t,e),saveConfig:()=>this._saveConfig(),saveShape:()=>this._decorSaveShape(),setGuardReplace:t=>{this._decorAssetGuardReplace=t},furnShiftDetach:()=>this._furnShiftDetach(),furnPick:t=>this._furnPick(t),furnFieldValue:t=>this._furnFieldValue(t),furnFieldToCm:t=>this._furnFieldToCm(t)}),t._editorSecondary=new Gh({root:()=>t.renderRoot,requestUpdate:()=>t.requestUpdate(),updateComplete:()=>t.updateComplete,clearTip:()=>{t._tip=null}}),t._resize=new tn}_routeLiveEditorUpdate(t,e){const s=jo(this.host,t,e);return!s&&this.host._resize.preview&&(this._resizeBaseFrameStable=!1),s}_commitLiveEditor(){!function(t){const e=t,s=Bo(t);s.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(s.raf),s.raf=0,Ko(s);const i=e.renderRoot?.querySelector("[data-hp-live-editor]");i&&g(d,i);const o=e.renderRoot?.querySelector("[data-hp-live-editor-html]");if(o){const t=e._viewOr(e._baseVb());g(e._renderLiveEditorMeasurements(t),o)}Wo(s,s.requestedRevision)}(this.host)}_disposeLiveEditor(){!function(t){No(t);const e=Ho.get(t);e&&(e.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e.raf),Ko(e),Wo(e,e.requestedRevision),Ho.delete(t))}(this.host)}async _whenLiveEditorSettled(){await this.host.updateComplete,await function(t){const e=Ho.get(t);if(!e||!e.raf||e.paintedRevision>=e.requestedRevision)return Promise.resolve();const s=e.requestedRevision;return new Promise(t=>e.waiters.push({revision:s,resolve:t}))}(this.host)}_queuePointerMove(t,e){Ao(this.host,t,e)}_flushPointerMove(t){Fo(this.host,t)}_cancelPointerMove(t){No(this.host,t)}_help(t){const e=`${t}.aria`,s=l(this.host.hass,this.host._config?.language);return ce(s,t)&&ce(s,e)?p``:d}_setMode(t,e=!0){t!==this.host._mode&&this.host._cancelDangerConfirm(),this.host._endTabDrag(),this._clearFurniturePreview(),this.host._pendingNavMode=null;const s=this.host._spaceModel();if(!s)return this.host._cancelModeTransition(!1),void(this.host._mode="view");if(this.host._kiosk&&"view"!==t)return;if(this.host._mode===t){if(!e&&"view"===t&&this.host._modeTransitionBusy){const e=this.host._currentModeVisual(t),s=this.host._modeTransitionTargetZoom,i=this.host._modeTransitionTargetCenterX,o=this.host._modeTransitionTargetCenterY;this.host._cancelModeTransition(!1),this.host._commitViewModeAtomic(e,s,i,o)}return}if("devices"===this.host._mode&&this.host._cancelDeviceDrag(),this.host._bootSoftCancel(),("plan"===t||"decor"===t)&&!this.host._norm)return void this.host._showToast(this.host._t("toast.markup_needs_server"));if(this.host._wallFaceBatch&&this._roomDialogCancel(),"plan"===this.host._mode&&"draw"===this.host._tool&&!this._finishWallChain())return;this.host._clearTransientHover(!0),this.host._cancelDevicePressFeedback();const i=this.host._mode,o=this.host._effectiveProjection(),a=this.host._currentModeVisual(i),n=this.host._modeTransitionBusy,r=a&&"view"!==i&&"view"!==t?{...a,toolbarContentOpacity:this.host._reducedMotion?1:.35}:a;this.host._cancelModeTransition(!1),this.host._editorSecondary.closeForNavigation(),(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)&&this._cancelDecorGesture();const l=!s.bg&&"view"===t!=("view"===i),h=n&&"view"===i&&"view"!==t?this.host._modeTransitionEditorCamera:null;let c=h?.zoom??(n?this.host._modeTransitionTargetZoom:this.host._zoom),d=h?h.centerX:n?this.host._modeTransitionTargetCenterX:r?.viewport.centerX,p=h?h.centerY:n?this.host._modeTransitionTargetCenterY:r?.viewport.centerY;if("view"===i&&"view"!==t&&!n){const e=this.host._view;if(this.host._viewModeSnap={space:this.host._space,zoom:this.host._zoom,cx:e?this.host._logicalViewCenter(o)?.x:void 0,cy:e?this.host._logicalViewCenter(o)?.y:void 0},"iso"===o){const e=this.host._logicalViewCenter("iso");d=e?.x,p=e?.y,this.host._view=null,this.host._mode=t,this.host._applyView(this.host._zoom,e?.x,e?.y)}l&&(c=1,d=void 0,p=void 0)}if("plan"===i&&this.host._activeDraftId&&(this.host._resumeDraftBySpace[this.host._space]=this.host._activeDraftId),this.host._mode=t,"devices"===i&&"devices"!==t&&(this.host._showHidden=!1,this.host._deviceInbox=null,this.host._deviceInboxReturn=null,this.host._deviceInboxMemo=null),this.host._editorChromeMode="view"===t?i:t,"view"===t){"view"===i||n||(this.host._modeTransitionEditorCamera={zoom:this.host._zoom,centerX:r?.viewport.centerX,centerY:r?.viewport.centerY});const t=this.host._viewModeSnap;if(t&&t.space===this.host._space){c=t.zoom;const e=this.host._labsIso&&"iso"===this.host._viewPreference[this.host._space]?"iso":"flat",s=null!=t.cx&&null!=t.cy&&"iso"===e?de([t.cx,t.cy],0):null;d=s?.[0]??t.cx,p=s?.[1]??t.cy}else t&&(c=this.host._zoomBySpace[this.host._space]||1,d=void 0,p=void 0)}else this.host._modeTransitionEditorCamera={zoom:c,centerX:d,centerY:p};this.host._modeTransitionTargetZoom=c,this.host._modeTransitionTargetCenterX=d,this.host._modeTransitionTargetCenterY=p,("iso"===o||"view"===t&&this.host._labsIso&&"iso"===this.host._viewPreference[this.host._space])&&(this.host._modeTransitionForceAtomic=!0);const u=++this.host._modeTransitionRequest;e?r?(this.host._modeTransitionPreparing=!0,this.host._modeTransitionVisual=r,this.host._prepareModeTransition(u,r,t,c,d,p)):(this.host._modeTransitionPreparing=!1,this.host._modeTransitionVisual=null,this.host._zoom=c,this.host._view=null,requestAnimationFrame(()=>{this.host.isConnected&&u===this.host._modeTransitionRequest&&this.host._mode===t&&(this.host._applyView(c,d,p),"view"===t&&(this.host._viewModeSnap=null,this.host._modeTransitionEditorCamera=null),this.host.requestUpdate())})):"view"===t&&this.host._commitViewModeAtomic(r,c,d,p),this.host._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this.host._tool="draw",this.host._mergeSel=null,this.host._mergeDialog=null,this.host._splitSel=null,this.host._pendingSplit=null,this.host._selId=null,this.host._physicalSel=null,this.host._physicalDialog=null,this.host._physicalDrag=null,this._rszResetController(),this.host._tip=null,this.host._hoverRoom=null,this.host._decorDraft=null,this.host._decorSel=null,this.host._decorMove=null,this.host._backdropDialog=null,this.host._decorTool="select",this.host._bdDrag=null,this.host._dtDrag=null,this.host._dtBox=null,"plan"===t&&(this._primeDrawWallField(),this._resumeLastDraft()),this.host._saveNav()}_primeDrawWallField(){null===this.host._drawWallField&&(this.host._drawWallField=pe(_t,this.host._imperial))}_showPhysicalRange(t=this.host._drawWallMaxCm,e=0){this.host._showToast(this.host._t("toast.physical_range",{min:pe(e,this.host._imperial),max:pe(t,this.host._imperial),unit:this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")}))}_draftSegmentCount(t=this.host._curSpaceCfg){return(t?.room_drafts||[]).reduce((t,e)=>t+(Array.isArray(e.segments)?e.segments.length:0),0)}_mergeSpacePartitions(t,e){const s=t?.partitions||[];if(s.length<2)return 0;const i=Vr(s,{pitch:W,seedIds:e,geometry:Yr(t,{excludeDraftId:this.host._activeDraftId})});return i.merged?(t.partitions=i.partitions,Jr(t.openings,t.partitions,i.openingMoves,{coordScale:Sc,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch}),i.merged):0}_finishWallChain(){if("draw"!==this.host._tool||this.host._wallFaceBatch||this.host._roomDialog)return!0;const t=this.host._curSpaceCfg;if(!t||this.host._path.length<2)return this.host._path=[],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),!0;const e=rh(this.host._path,nh(this.host._path.length-1,this.host._draftSegmentCms,this.host._drawWallCm,_t)),s=e.length;if((t.partitions||[]).length+s>Mc)return this.host._showToast(this.host._t("toast.physical_limit")),!1;const i=this._geometrySnapshot();t.partitions||=[];const o=Date.now().toString(36),a=[],n=this.host._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this.host._activeDraftId):null,r=this._draftSegmentsForPath(this.host._path,n,e.map(t=>t.cm));for(let i=0;it.id!==this.host._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this.host._t("history.wall_chain_finish"),i),delete this.host._resumeDraftBySpace[this.host._space],this.host._path=[],this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),!0}_activateMarkupTool(t){t!==this.host._tool&&(this.host._wallFaceBatch&&this._roomDialogCancel(),("draw"!==this.host._tool||this._finishWallChain())&&(this._cancelPath(),"resize"===this.host._tool&&(this.host._resize.dragging?this._rszCancelDrag():this.host._resize.reset()),this.host._tool=t,"draw"===t&&this._resumeLastDraft(),"resize"===t&&this.host._resize.selectRoom(null),"wallthick"===t&&(this.host._wallDialog=null)))}_limitReached(t){const e=this.host._curSpaceCfg;if(!e)return!0;const s="draft"===t?(e.room_drafts||[]).length>=200:"partition"===t?(e.partitions||[]).length>=Mc:(e.wall_columns||[]).length>=500;return s&&this.host._showToast(this.host._t("toast.physical_limit")),s}_svgPoint(t){const e=this.host.renderRoot.querySelector(".stage").getBoundingClientRect();return this.host._screenToVb(t.clientX-e.left,t.clientY-e.top)}_snap(t){const e=this.host._gridPitch;return[ue(_e(t[0],e)),ue(_e(t[1],e))]}_snapDrawPoint(t,e=!1){const s=this.host._path[this.host._path.length-1],i=e&&s?me(s,t,this.host._gridPitch,so):t;return this._snap(i)}_planSnapOpeningCuts(t,e){if(!this.host._openingsR.length)return[];const s=this.host._openingWallIndexFor(t,e).value,i=[];for(const e of this.host._roomWallOpeningInputs(this.host._openingsR,t)){const t=$t(s,e);if(!t.negative&&!t.positive)continue;const o=e.angle*Math.PI/180,a=Math.cos(o)*e.length/2,n=Math.sin(o)*e.length/2;i.push([e.x-a,e.y-n,e.x+a,e.y+n])}return i}_planSnapGeometrySnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|empty`,value:{segments:[],endpoints:[]}};const e=[this.host._space,this.host._cfgEpoch,this.host._activeDraftId||"",t.rooms.length,t.room_drafts.length,t.partitions.length].join("|");if(this.host._planSnapGeometryCache?.key===e)return this.host._planSnapGeometryCache;const s=this.host._openCuts(),i=Zl({space:t,activeDraftId:this.host._activeDraftId,roomCuts:this._planSnapOpeningCuts(t,s),partitionCuts:this._partitionOpeningCuts(t),epsilon:2e-4*this.host._gridPitch});return this.host._planSnapGeometryCache={key:e,value:i},this.host._planSnapGeometryCache}_hiddenWallDiagnosticSnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|hidden-empty`,value:{segments:[],endpoints:[]}};const e=["hidden",this.host._space,this.host._cfgEpoch,this.host._activeDraftId||"",t.rooms.length,t.room_drafts.length,t.partitions.length].join("|");if(this.host._hiddenWallDiagnosticCache?.key===e)return this.host._hiddenWallDiagnosticCache;const s=Xl({space:t,activeDraftId:this.host._activeDraftId,epsilon:2e-4*this.host._gridPitch});return this.host._hiddenWallDiagnosticCache={key:e,value:s},this.host._hiddenWallDiagnosticCache}_planStructuralGeometrySnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|structural-empty`,value:{segments:[],endpoints:[]}};const e=["structural",this.host._space,this.host._cfgEpoch,this.host._activeDraftId||"",t.rooms.length,t.room_drafts.length,t.partitions.length].join("|");if(this.host._planStructuralGeometryCache?.key===e)return this.host._planStructuralGeometryCache;const s=Zl({space:t,activeDraftId:this.host._activeDraftId,epsilon:2e-4*this.host._gridPitch});return this.host._planStructuralGeometryCache={key:e,value:s},this.host._planStructuralGeometryCache}_planSnapContextKey(t){const e=this.host._path[0],s=this.host._path[this.host._path.length-1];return[t,this.host._tool,this.host._path.length,e?`${e[0]},${e[1]}`:"",s?`${s[0]},${s[1]}`:""].join("|")}_resolvePlanDrawPoint(t,e){const s=this._planSnapGeometrySnapshot(),i=this.host._path[this.host._path.length-1],o="draw"===this.host._tool&&this.host._path.length>=3?[{point:this.host._path[0],key:"closure:first-point"}]:[],a={tolerance:this._cssPxToRender(12),distinguishTolerance:this._cssPxToRender(8),gridStep:this.host._gridPitch,excludePoints:i?[i]:[],extraEndpoints:o,epsilon:2e-4*this.host._gridPitch},n=e&&i?oh(s.value,t,{...a,anchor:i}):function(t,e,s){if(!(Gl(e)&&s.tolerance>=0))return{kind:"none",candidate:null,conflicts:[]};const i=s.epsilon??Wl,o=s.excludePoints||[],a=sh(eh(t,e,s),s.distinguishTolerance||0);if(a)return a;let n=null;for(const a of t.segments){const t=[a.a[0],a.a[1],a.b[0],a.b[1]],r=Ot([e[0],e[1]],t);if(r>s.tolerance)continue;const l=ih(a,e,s.gridStep);!Ql(l,o,i)&&th(r,a.key,n)&&(n={kind:"line",point:l,key:a.key,distance:r,segment:a})}return n?{kind:"resolved",candidate:n,conflicts:[]}:{kind:"none",candidate:null,conflicts:[]}}(s.value,t,a),r="resolved"===n.kind?n.candidate:null,l=r?[...r.point]:this._snapDrawPoint(t,e),h=i?ge(i,l):l;return{point:h,candidate:r&&G(h,r.point)?r:null,conflicts:"ambiguous"===n.kind?n.conflicts:[],ambiguous:"ambiguous"===n.kind,contextKey:this._planSnapContextKey(s.key)}}_clearPlanSnapHover(t=!0){this.host._planSnapHover=null,this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers([]),t&&(this.host._cursorPt=null)}_samePt(t,e){return G(t,e)}_dropLegacySegments(t=this.host._serverCfg){for(const e of t?.markers||[])"ripple"===e.display&&(e.display="icon_ripple");for(const e of t?.spaces||[]){delete e.segments;const t=new Set,s=e=>"string"==typeof e&&e.length>=1&&e.length<=64&&!t.has(e),i=e=>(t.add(e),!0),o=t=>Array.isArray(t)&&2===t.length&&t.every(t=>Number.isFinite(Number(t))&&Math.abs(Number(t))<=Kt);if(Array.isArray(e.partitions)&&(e.partitions=e.partitions.filter(t=>t&&s(t.id)&&o(t.a)&&o(t.b)&&Math.hypot(t.a[0]-t.b[0],t.a[1]-t.b[1])>1e-9&&i(t.id)).map(t=>({...t,cm:Number.isFinite(Number(t.cm))?Math.max(0,Math.min(100,Number(t.cm))):15})),e.partitions.length||delete e.partitions),Array.isArray(e.wall_columns)&&(e.wall_columns=e.wall_columns.filter(t=>t&&s(t.id)&&o(t.center)&&i(t.id)).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[Number(t.center[0]),Number(t.center[1])],cm:ee(Number(t.cm)||15),..."circle"===t.shape?{}:{angle:fe(t.angle)}})),e.wall_columns.length||delete e.wall_columns),Array.isArray(e.room_drafts)&&(e.room_drafts=e.room_drafts.filter(t=>t&&s(t.id)&&Array.isArray(t.points)&&t.points.length>=2&&t.points.every(o)&&i(t.id)).map(t=>{const e=bn(t);return{id:t.id,...e}}).filter(t=>t.points.length>=2),e.room_drafts.length||delete e.room_drafts),Array.isArray(e.walls)){const t=be(Ft({spaces:[e]}),e.id),s=t?ve(e,t,Sc,.02*Dt).contour.map(t=>t.map(t=>t/Sc)):K(e.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]);e.walls=Ct(e.walls,e.rooms||[],W,1,s),e.walls.length||delete e.walls}}}_rollbackRejectedPhysicalWrites(t){if(!this.host._serverCfg||!t.length)return!1;let e=!1;for(const[s]of t){const t=this.host._pendingPhysicalWrites.get(s);t&&(e=this._restoreGeometryStateInConfig(this.host._serverCfg,t.before)||e,this.host._pendingPhysicalWrites.delete(s))}return!!e&&(this._clearGeometryGesture(),this.host._geometryHistory.clear(),this.host._cfgEpoch++,this.host._modelCache=null,this.host._wallUnionCache=null,this.host._physicalBodiesCache=null,this.host._frame=null,this.host._regSignature="",this.host._cfgContentFingerprint=_(this.host._serverCfg),this.host._maybeRebuildDevices(),this.host.requestUpdate(),!0)}async _reloadRejectedPhysicalWrite(){const t=this.host._writeChain;await t.catch(()=>{}),await this.host._reloadConfigOnly(!0)}_prepareConfigCandidate(t){return this._dropLegacySegments(t),ye(t)}_writeConfig(t=null){this.host._writesPending++,this.host._writeChain=$e(this.host._writeChain,async()=>{if(!this.host._serverCfg)return;const e=_(this.host._serverCfg),s=this._prepareConfigCandidate(this.host._serverCfg),i=_(s);t&&e===t.attemptedFingerprint&&Object.assign(t,{revision:this.host._cfgRev,attempted:s,attemptedFingerprint:i});const o=[...this.host._pendingPhysicalWrites.entries()];for(const[t,e]of o){const i=s.spaces.find(e=>e.id===t),o=Q(i);if(o===e.fingerprint)continue;let a=!1;try{a=this.host._checkSpacePhysicalGeometry(s,t).ok}catch{a=!1}if(!a)throw this._restoreGeometryStateLocal(e.before),this.host._pendingPhysicalWrites.delete(t),this.host._geometryHistory.clear(),this.host._showToast(this.host._t("toast.geometry_unsafe")),Object.assign(new Error("unsafe wall geometry"),{code:"geometry-unsafe"});e.fingerprint=o}i!==_(this.host._serverCfg)&&(this.host._serverCfg=s),this.host._cfgContentFingerprint=i;try{await this.host._sendConfigCandidate(s)}catch(t){if(!this._rollbackRejectedPhysicalWrites(o))throw t;const e=t&&"object"==typeof t?t:Object.assign(new Error(String(t)),{cause:t});throw e.physicalGeometryRolledBack=!0,e}for(const[t,e]of o)this.host._pendingPhysicalWrites.get(t)?.fingerprint===e.fingerprint&&this.host._pendingPhysicalWrites.delete(t)});return this.host._writeChain.finally(()=>{this.host._writesPending--})}_saveConfig(){this.host._cfgEpoch++,this.host._saveConfigDebounced()}_geometrySnapshotFromConfig(t,e){const s=t?.spaces?.find(t=>t.id===e);if(!s)return null;const i=t=>JSON.parse(JSON.stringify(t)),o={};for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==s[t]&&(o[t]=s[t]);return{spaceId:e,rooms:i(s.rooms||[]),...Array.isArray(s.openings)?{openings:i(s.openings)}:{},...Array.isArray(s.walls)?{walls:i(s.walls)}:{},...Array.isArray(s.wall_segments)?{wall_segments:i(s.wall_segments)}:{},...Array.isArray(s.open_spans)?{open_spans:i(s.open_spans)}:{},...Array.isArray(s.room_drafts)?{room_drafts:i(s.room_drafts)}:{},...Array.isArray(s.partitions)?{partitions:i(s.partitions)}:{},...Array.isArray(s.wall_columns)?{wall_columns:i(s.wall_columns)}:{},...Array.isArray(s.decor)?{decor:i(s.decor)}:{},plan_transform:o}}_geometrySnapshot(t=this.host._space){return this._geometrySnapshotFromConfig(this.host._serverCfg,t)}_recordGeometry(t,e){if(!e)return;const s=this._geometrySnapshot(e.spaceId);s&&JSON.stringify(e)!==JSON.stringify(s)&&(this.host._geometryHistory.push({name:t,before:e,after:s}),this.host.requestUpdate())}_restoreGeometryStateInConfig(t,e,s=!1){const i=t?.spaces?.find(t=>t.id===e.spaceId);if(!i)return!1;const o=t=>JSON.parse(JSON.stringify(t)),a=new Map((i.rooms||[]).map(t=>[t.id,t]));if(i.rooms=o(e.rooms),s)for(const t of i.rooms){const e=a.get(t.id);!Array.isArray(t.wall_ids)&&Array.isArray(e?.wall_ids)&&e.wall_ids.length===t.poly?.length&&(t.wall_ids=o(e.wall_ids))}const n=(t,e)=>{void 0!==e?i[t]=o(e):s&&"wall_segments"===t||delete i[t]},r=new Map((i.openings||[]).map(t=>[t.id,t])),l=new Map((i.room_drafts||[]).map(t=>[t.id,t]));if(n("openings",e.openings),n("walls",e.walls),n("wall_segments",e.wall_segments),n("open_spans",e.open_spans),n("room_drafts",e.room_drafts),n("partitions",e.partitions),n("wall_columns",e.wall_columns),n("decor",e.decor),s){for(const t of i.openings||[]){const e=r.get(t.id);t.host||"wall"!==e?.host?.kind||(t.host=o(e.host))}for(const t of i.room_drafts||[]){const e=l.get(t.id);for(let s=0;s<(t.segments||[]).length;s++)!t.segments[s]?.id&&e?.segments?.[s]?.id&&(t.segments[s].id=e.segments[s].id)}}for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])delete i[t];return Object.assign(i,o(e.plan_transform||{})),!0}_restoreGeometryStateLocal(t){return!!this._restoreGeometryStateInConfig(this.host._serverCfg,t)&&(this.host._cfgEpoch++,this.host._modelCache=null,this.host._wallUnionCache=null,this.host._physicalBodiesCache=null,this.host._frame=null,this.host.requestUpdate(),!0)}_wallModelBlockerLabel(t){const e=t instanceof cn?t.reason:"invalid-room";return this.host._t(`wall_model.reason.${e}`)}_hasLegacyZeroWallFields(t=this.host._serverCfg){return(t?.spaces||[]).some(t=>Array.isArray(t?.open_spans)&&t.open_spans.length>0||(t?.rooms||[]).some(t=>Array.isArray(t?.open_to)&&t.open_to.length>0))}_showWallModelMigrationBlocked(t){const e=this._hasLegacyZeroWallFields()?"toast.zero_wall_migration_blocked":"toast.wall_model_migration_blocked";this.host._showToast(this.host._t(e,{reason:this._wallModelBlockerLabel(t)}))}_limitSegmentsOf(t){const e=[];for(const s of t?.wall_segments||[])s?.a&&s?.b&&e.push({id:String(s.id||""),a:s.a,b:s.b,cm:Number(s.cm)});for(const s of t?.partitions||[])s?.a&&s?.b&&e.push({id:String(s.id||""),a:s.a,b:s.b,cm:Number(s.cm)});for(const s of t?.room_drafts||[]){const t=Array.isArray(s?.points)?s.points:[],i=Array.isArray(s?.segments)?s.segments:[];for(let o=0;o+1t?.id===e);return o?function(t,e,s,i,o){const a=(t?.spaces||[]).find(t=>t?.id===e);if(!a)return[];const n=Number(a.cell_cm)>0?Number(a.cell_cm):5,r=[...wr(s),...Dr(s,n,W),...Pr(s,n,W)];let l=i?.multiWallNodes||null;if(!l)try{l=nt(a.rooms||[],a.walls||[],[],W,n,W,1)}catch{l=null}const h=i&&"lightweight"!==i.status?i:null;let c="ok"===h?.status||"degraded-extra"===h?.status?h.roomGeom:null;const d=null===i||"lightweight"===i?.status;if(!c&&!d&&l?.nodes.length)try{const t=rt(a.rooms||[],a.walls||[],[],[],W,n,W,1);c="ok"===t?.status||"degraded-extra"===t?.status?t.roomGeom:null}catch{c=null}for(const t of a.rooms||[]){const e=String(t?.id||"");if(!e||o&&!o.has(e))continue;let s=null;try{s=lt(a.rooms||[],e,a.walls||[],[],W,n,W,1,d?null:c??void 0,l)}catch{s=null}r.push(...Ir(e,s,n,W))}return r}(t,e,this._limitSegmentsOf(o),s,i):[]}_junctionLimitLabel(t){const e=t=>String(Math.round(10*t)/10);return this.host._t(`junction.limit_${t.rule}`,{actual:e(t.actual),limit:e(t.limit)})}_junctionLimitsIntroduced(t,e,s,i,o){const a=o?.length?new Set(o):void 0;let n;const r=(e.spaces||[]).find(t=>t?.id===s);let l="";try{l=Q(r)}catch{l=""}const h=!a&&e&&"object"==typeof e?this._junctionBaselineCache.get(e):void 0;if(h&&l&&h.fingerprint===l&&h.spaceId===s&&(n=h.violations),!n){try{const t=Number(e?.model_version||0)>=9?e:Fn(e).config;n=this.host._junctionLimitViolations(t,s,a?null:void 0,a)}catch{return[]}!a&&e&&"object"==typeof e&&l&&this._junctionBaselineCache.set(e,{spaceId:s,fingerprint:l,violations:n})}let c=[],d=n;try{c=this.host._junctionLimitViolations(t,s,i,a),a&&(d=n.filter(t=>"clearance"!==t.rule||a.has(t.subject)))}catch{return[{rule:"check_failed",subject:s,actual:0,limit:0}]}return Tr(c,d)}_commitPhysicalGeometry(t,e,s=[]){if(!e||!this.host._serverCfg)return!1;const i=this.host._serverCfg,o=this._geometrySnapshotFromConfig(i,e.spaceId),a=i.spaces.find(t=>t.id===e.spaceId);if(!a||Q(e)===Q(a))return!1;let n,r=!1;try{r=this.host._checkSpacePhysicalGeometry(i,e.spaceId).ok}catch{r=!1}if(!r)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;let l=e;try{if(Number(i.model_version||0)<9){const t=JSON.parse(JSON.stringify(i));if(!this._restoreGeometryStateInConfig(t,e))throw new cn("invalid-room",e.spaceId);const s=Fn(t).config;l=this._geometrySnapshotFromConfig(s,e.spaceId)||e;const a=JSON.parse(JSON.stringify(s));if(!o||!this._restoreGeometryStateInConfig(a,o,!0))throw new cn("invalid-room",e.spaceId);const r=s.spaces.find(t=>t.id===e.spaceId),h=a.spaces.find(t=>t.id===e.spaceId);if(!Array.isArray(o.wall_segments)&&JSON.stringify(e.rooms)===JSON.stringify(o.rooms))for(const t of h?.wall_segments||[])t.cm=Z(o.walls,t.a,t.b,W,1);const c=((t,e,s)=>{const i=new Map,o=new Map((t?.rooms||[]).map(t=>[t.id,t])),a=new Map((e||[]).map(t=>[t.id,t])),{rooms:n}=In(s,Cn(t));for(const t of n){const e=a.get(t.id),n=o.get(t.id),r=q(e),l=(s.rooms||[]).find(e=>e.id===t.id),h=q(l),c=q(n);if(r&&h&&c&&r.length===h.length&&c.length===n?.wall_ids?.length&&t.poly.length===t.wall_ids.length)for(let e=0;e{const o=[];for(let a=0;ahn||$n(r,s,i)>hn)continue;const l=yn(n,s,i),h=yn(r,s,i);l<-1e-9||h>1+hn||h<=l+hn||o.push({start:l,id:e[a]})}return o.sort((t,e)=>t.start-e.start)},o=s(c,n.wall_ids,r[e],r[(e+1)%r.length]),a=s(t.poly,t.wall_ids,h[e],h[(e+1)%h.length]);if(o.length&&o.length===a.length)for(let t=0;tt.id===e.spaceId),i=this.host._path.length>=2?this.host._path.map(t=>[t[0]/Sc,t[1]/Sc]):[];i.push(...s.map(t=>[t[0],t[1]])),h=vn(t)<=vn(l,i)&&this.host._checkSpacePhysicalGeometry(n,e.spaceId).ok}catch{h=!1}if(!h)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;const c=JSON.parse(JSON.stringify(i));this._restoreGeometryStateInConfig(c,e);const d=this._junctionLimitsIntroduced(n,c,e.spaceId);if(d.length)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this._junctionLimitLabel(d[0])),!1;Hn(i,n),this._recordGeometry(t,l);const p=i.spaces.find(t=>t.id===e.spaceId),u=this.host._pendingPhysicalWrites.get(e.spaceId);return this.host._pendingPhysicalWrites.set(e.spaceId,{before:u?.before||l,fingerprint:Q(p)}),this._saveConfig(),!0}_clearGeometryGesture(){this._clearFurniturePreview(),this.host._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!1),this.host._mergeSel=null,this.host._mergeDialog=null,this.host._splitSel=null,this.host._pendingSplit=null,this.host._wallFaceBatch=null,this.host._wallRepairDiagnostic=null,this.host._roomDeleteDialog=null,this.host._wallDialog=null,this.host._physicalDialog=null,this.host._physicalSel=null,this.host._physicalDrag=null,this.host._physicalRotate=null,this.host._activeDraftId=null,this.host._draftSegmentCms=[],this.host._closingWallCm=null,this.host._openingDialog=null,this._rszResetController(),this.host._decorDraft=null,this.host._decorMove=null,this.host._dtDrag=null,this.host._bdDrag=null}_stagePointerCancel(t){return clearTimeout(this.host._kioskHoldTimer),this.host._swipeStart?.id===t.pointerId&&(this.host._swipeStart=null),this.host._furnTouchPending?.pid===t.pointerId?(this._clearFurniturePreview(),this.host._pointers.delete(t.pointerId),void this.host.requestUpdate()):this.host._physicalDrag?.pid!==t.pointerId&&this.host._physicalRotate?.pid!==t.pointerId?this.host._decorDraft?.pid===t.pointerId?(this.host._decorDraft=null,void this.host.requestUpdate()):void(this.host._decorMove?.pid!==t.pointerId&&this.host._dtDrag?.pid!==t.pointerId&&this.host._bdDrag?.pid!==t.pointerId?("opening"===this.host._tool?(this.host._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this.host._tool&&this._clearPlanSnapHover(),this.host._pointers.delete(t.pointerId),this.host._pointers.size<2&&(this.host._pinchStart=null),0===this.host._pointers.size&&(this.host._panStart=null,this.host._panLock=null),this.host._viewportGestureDirty&&0===this.host._pointers.size&&(this.host._viewportGestureDirty=!1,this.host.requestUpdate())):this._cancelDecorGesture()):void this._cancelPhysicalGesture()}_applyGeometryState(t,e=!1){if(!this.host._canCommitSpace(t.spaceId))return!1;const s=this._geometrySnapshot(t.spaceId);if(!s||!this._restoreGeometryStateLocal(t))return!1;const i=this.host._serverCfg,o=Q(s)!==Q(t);if(o){let o=!1;try{const s=i?this.host._checkSpacePhysicalGeometry(i,t.spaceId):null;o=!!s?.ok||!(!e||"wall-degraded-extra"!==s?.reason)}catch{o=!1}if(!o)return this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1}let a;try{a=Fn(i).config}catch(t){return this._restoreGeometryStateLocal(s),this._showWallModelMigrationBlocked(t),!1}if(o){let o=!1;try{const s=a?this.host._checkSpacePhysicalGeometry(a,t.spaceId):null;o=!!s?.ok||!(!e||"wall-degraded-extra"!==s?.reason)}catch{o=!1}if(!o)return this._restoreGeometryStateLocal(s),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;Hn(i,a);const n=i?.spaces.find(e=>e.id===t.spaceId),r=this.host._pendingPhysicalWrites.get(t.spaceId);this.host._pendingPhysicalWrites.set(t.spaceId,{before:r?.before||s,fingerprint:Q(n)})}else Hn(i,a);return this._clearGeometryGesture(),this.host._space!==t.spaceId&&(this.host._commitSpace(t.spaceId),this.host._saveNav(),this.host._restoreZoom()),this.host._modelCache=null,this.host._frame=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this._saveConfig(),this.host.requestUpdate(),!0}_roomAt(t){return this.host._spaceModel()?.rooms.find(e=>{const s=q(e);return!!s&&we(t,s)})}_overlapRoom(t){return this.host._spaceModel()?.rooms.find(e=>{const s=q(e);return!!s&&E(t,s)})}_pointInRoom(t,e){return e.poly?ke(t,e.poly):null!=e.x&&t[0]>=e.x&&t[0]<=e.x+e.w&&t[1]>=e.y&&t[1]<=e.y+e.h}_contourSelfIntersects(t){if(!Da(t))return!0;const e=t.length,s=.001;for(let i=0;i=500)return this.host._showToast(this.host._t("toast.physical_limit")),!1;const t=this.host._curSpaceCfg;return!(!this.host._activeDraftId&&(t?.room_drafts||[]).length>=200||this._draftSegmentCount(t)>=2e3||(t?.partitions||[]).length+this.host._path.length>Mc)||(this.host._showToast(this.host._t("toast.physical_limit")),!1)}_markupClick(t){if(this.host._vacFit)return;if(!this.host._markup)return;const e=this.host._spaceModel();if(!e)return void this._clearGeometryGesture();if(this.host._suppressClick)return;if(this.host._drag||this.host._rlResize)return;const s=t.composedPath?.()||[];if(s.some(t=>t?.classList?.contains?.("roomlabel")||t?.classList?.contains?.("rlhandle")))return;if(s.some(t=>t?.classList?.contains?.("physical-hit")))return;const i=this._svgPoint(t);if("select"===this.host._tool)return void(this.host._physicalSel=null);if("resize"===this.host._tool){if(this.host._resize.dragging||s.some(t=>t?.classList?.contains?.("rszhandle")))return;const t=[...e.rooms].reverse().find(t=>this._pointInRoom(i,t));return this.host._resize.selectRoom(t?.id||null),void this.host.requestUpdate()}if("delroom"===this.host._tool)return void this._deleteRoomClick(i);if("opening"===this.host._tool)return void this._openingClick(i);if("merge"===this.host._tool)return void this._mergeClick(i);if("wallthick"===this.host._tool)return void this._wallThickClick(i);if("split"===this.host._tool)return void this._splitClick(i);if("column"===this.host._tool)return void this._columnClick(i);this.host._wallRepairDiagnostic=null;const o=this._resolvePlanDrawPoint(i,t.shiftKey);if(o.ambiguous)return this.host._planSnapHover={contextKey:o.contextKey,candidate:null,conflicts:o.conflicts},this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers(o.conflicts),void this.host._showToast(this.host._t("toast.plan_snap_ambiguous"));let a=o.point;if(t.ctrlKey||t.metaKey){if(t.preventDefault(),this.host._path.length<3)return;a=ge(this.host._path[this.host._path.length-1],this.host._path[0])}if(!this.host._path.length){if(!t.shiftKey&&!o.candidate&&this._offerExistingWallFace(i))return;const e=this._draftEndAt(a);return e?(this.host._activeDraftId=e.draft.id,this.host._resumeDraftBySpace[this.host._space]=e.draft.id,this.host._path=e.reverse?[...e.draft.points].reverse().map(t=>[...t]):e.draft.points.map(t=>[...t]),void(this.host._draftSegmentCms=this._adoptDraftCms(this.host._path,e.reverse?[...e.draft.segments].reverse().map(t=>t.cm):e.draft.segments.map(t=>t.cm),e.draft.id))):(this.host._activeDraftId=null,this.host._draftSegmentCms=[],void(this.host._path=[a]))}const n=this.host._path[this.host._path.length-1];if(this._samePt(a,n))return;const r=this._draftEndAt(a,this.host._activeDraftId||void 0);if(r)return void this._mergeDraftEndpoint(r);if(!this._canAppendRoomDraftPoint())return;const l=this.host._drawWallCm;if(null==l)return void this._showPhysicalRange(100);const h=this.host._path.map(t=>[...t]);this.host._path=[...this.host._path,a],this.host._draftSegmentCms=[...this.host._draftSegmentCms,l],this._persistActiveDraftSegment(),this._offerWallFaces(h)}_draftEndAt(t,e){const s=this.host._spaceModel();if(!s)return null;const i=this.host._viewOr(this.host._baseVb()),o=Math.max(.15*this.host._gridPitch,this.host._stageEl?.clientWidth?i.w/this.host._stageEl.clientWidth*12:0);for(const i of s.room_drafts||[]){if(i.id===e)continue;if(i.points.length<2)continue;const s=i.points[0],a=i.points[i.points.length-1];if(Math.hypot(t[0]-a[0],t[1]-a[1])<=o)return{draft:i,reverse:!1};if(Math.hypot(t[0]-s[0],t[1]-s[1])<=o)return{draft:i,reverse:!0}}return null}_mergeDraftEndpoint(t){const e=this.host._curSpaceCfg;if(!e||!this.host._path.length)return;const s=this.host._path.map(t=>[...t]),i=this._wallGraphSources(s),o=Array.isArray(e.room_drafts)?e.room_drafts:[],a=this.host._activeDraftId?o.find(t=>t.id===this.host._activeDraftId):null,n=o.find(e=>e.id===t.draft.id);if(!n)return;const r=t.reverse?t.draft.points.map(t=>[...t]):[...t.draft.points].reverse().map(t=>[...t]),l=t.reverse?(n.segments||[]).map(t=>({...t})):[...n.segments||[]].reverse().map(t=>({...t})),h=this.host._path[this.host._path.length-1],c=this._samePt(h,r[0]),d=c?null:this.host._drawWallCm;if(!c&&null==d)return void this._showPhysicalRange(100);const p=this._draftSegmentsForPath(this.host._path,a,this.host._draftSegmentCms),u=[...this.host._path.map(t=>[...t]),...c?r.slice(1):r],_=[...p,...null==d?[]:[{cm:d}],...l],m=u.length>=4&&this._samePt(u[0],u[u.length-1]),g=u,f=_;if(g.length>500)return void this.host._showToast(this.host._t("toast.physical_limit"));const b=(a?.segments?.length||0)+(n.segments?.length||0);if(this._draftSegmentCount(e)-b+f.length>2e3)return void this.host._showToast(this.host._t("toast.physical_limit"));if(m){const t=g.slice(0,-1);if(this._contourSelfIntersects(t)||B(t)<=1e-6)return void this.host._showToast(this.host._t("toast.contour_cannot_close"));const e=this._overlapRoom(t);if(e)return void this.host._showToast(this.host._t("toast.room_overlap",{name:e.name||""}))}const v=this._geometrySnapshot(),y=this.host._activeDraftId||t.draft.id,$={...a||n,id:y,points:g.map(t=>[t[0]/Sc,t[1]/Sc]),segments:f};e.room_drafts=o.filter(e=>e.id!==t.draft.id&&(!this.host._activeDraftId||e.id!==this.host._activeDraftId)),e.room_drafts.push($),this.host._activeDraftId=y,this.host._resumeDraftBySpace[this.host._space]=y,this.host._path=g,this.host._draftSegmentCms=this._adoptDraftCms(g,f.map(t=>Number(t.cm)),y),this.host._physicalSel=null,this._commitPhysicalGeometry(this.host._t("history.draft_merge"),v),null!=d&&this._offerWallFaces(s,s.length-1,i)}_adoptDraftCms(t,e,s){const i=Math.max(0,t.length-1),o=nh(i,e,this.host._drawWallCm,_t);return e.length!==i&&console.debug(`[houseplan] draft ${s??"?"}: восстановлено толщин ${i-e.length} (#234)`),o}_draftSegmentsForPath(t,e,s){const i=Array.isArray(e?.points)?e.points.map(t=>[Number(t?.[0])*Sc,Number(t?.[1])*Sc]):[],o=Array.isArray(e?.segments)?e.segments:[];return nh(Math.max(0,t.length-1),s,this.host._drawWallCm,_t).map((e,s)=>{const a=t[s],n=t[s+1],r=i.findIndex((t,e)=>{if(e+1>=i.length)return!1;const s=i[e+1];return this._samePt(a,t)&&this._samePt(n,s)||this._samePt(a,s)&&this._samePt(n,t)});return{...r>=0?o[r]:{},cm:e}})}_persistActiveDraftSegment(){if(this.host._path.length<2||!this.host._curSpaceCfg)return;const t=this._geometrySnapshot(),e=this.host._curSpaceCfg;e.room_drafts||=[],this.host._activeDraftId||(this.host._activeDraftId="draft-"+Date.now().toString(36)),this.host._resumeDraftBySpace[this.host._space]=this.host._activeDraftId;const s=e.room_drafts.findIndex(t=>t.id===this.host._activeDraftId),i={...s>=0?e.room_drafts[s]:{},id:this.host._activeDraftId,points:this.host._path.map(t=>[t[0]/Sc,t[1]/Sc]),segments:this._draftSegmentsForPath(this.host._path,s>=0?e.room_drafts[s]:null,this.host._draftSegmentCms)};s>=0?e.room_drafts[s]=i:e.room_drafts.push(i),sr(this,this.host._t("history.draft_segment"),t)}_activeWallSourceKey(t){return`active:${this.host._activeDraftId||"session"}:${t}`}_wallGraphSources(t){const e=this._planStructuralGeometrySnapshot().value.segments.map(t=>({a:t.a,b:t.b,key:`static:${t.key}`}));for(let s=0;s+1t.key===s);if(i>=0){const[t]=this.host._wallFaceGraphCache.splice(i,1);return this.host._wallFaceGraphCache.push(t),t.value}const o=Ph(t,e);return this.host._wallFaceGraphCache.push({key:s,value:o}),this.host._wallFaceGraphCache.length>4&&this.host._wallFaceGraphCache.shift(),o}_offerWallFaces(t,e=this.host._path.length-2,s){if(this.host._path.length<2||this.host._wallFaceBatch||this.host._roomDialog)return;const i=this.host._spaceModel();if(!i)return;const o=this._activeWallSourceKey(e),a=2e-4*this.host._gridPitch;let n,r;try{const e=s||this._wallGraphSources(t);r=this._wallGraphSources(this.host._path),n=function(t,e,s){const i=new Set(t.faces.map(t=>t.key));return e.faces.filter(t=>!i.has(t.key)&&t.sourceKeys.includes(s))}(this._wallFaceGraph(e,a),this._wallFaceGraph(r,a),o)}catch{return}if(!n.length){const t=Bh(r,{requiredSourceKey:o,maxDistance:x(2,this.host._cellCm,this.host._gridPitch),gridStep:this.host._gridPitch,epsilon:a});return"ambiguous"===t.kind?(this.host._wallRepairDiagnostic=t.proposals[0]||null,void this.host._showToast(this.host._t(0===this.host._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous"))):void("repair"!==t.kind||this._overlapRoom(t.face.ring)||this._beginWallFaceBatch([{...t.face,repair:t.proposal}]))}for(const t of i.rooms){const e=q(t);if(!t.id||!e)continue;const s=xe(e,this.host._path,.02*this.host._gridPitch);if(!s)continue;const[i,o]=s,a=B(i)>=B(o)?i:o,r=a===i?o:i,l=[...n].sort((t,e)=>Math.abs(t.area-B(r))-Math.abs(e.area-B(r))||t.key.localeCompare(e.key))[0];if(!l)return;return void this._beginWallFaceBatch([{...l,ring:r.map(t=>[t[0],t[1]]),split:{roomId:t.id,mainPoly:a,newPoly:r},consumeAllActive:!0}])}const l=n.filter(t=>!(t.ring.length<3||this._contourSelfIntersects(t.ring))&&!this._overlapRoom(t.ring));l.length&&this._beginWallFaceBatch(l)}_beginWallFaceBatch(t){this.host._wallRepairDiagnostic=null,this.host._wallFaceBatch={candidates:[...t].sort((t,e)=>t.area-e.area||t.key.localeCompare(e.key)),index:0,decisions:[],activePath:this.host._path.map(t=>[...t]),activeCms:[...this.host._draftSegmentCms],activeDraftId:this.host._activeDraftId},this._clearPlanSnapHover(),this.host._nameSel="",this.host._areaSel="",this._resetRoomDialogFields(),this.host._roomDialog=!0}_offerExistingWallFace(t){if(this.host._path.length||this.host._wallFaceBatch||this.host._roomDialog)return!1;const e=2e-4*this.host._gridPitch;try{let s,i=Ih(this._wallFaceGraph(this._wallGraphSources([]),e),t,e);if(!i){const o=Bh(this._wallGraphSources([]),{point:t,maxDistance:x(2,this.host._cellCm,this.host._gridPitch),gridStep:this.host._gridPitch,epsilon:e});if("ambiguous"===o.kind)return this.host._wallRepairDiagnostic=o.proposals[0]||null,this.host._showToast(this.host._t(0===this.host._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous")),!0;if("repair"===o.kind)i=o.face,s=o.proposal;else if("none"===o.kind){const s=Bh(this._wallGraphSources([]),{point:t,maxDistance:this._cssPxToRender(12),gridStep:this.host._gridPitch,epsilon:e});if("repair"===s.kind)return this.host._wallRepairDiagnostic=s.proposal,this.host._showToast(this.host._t("toast.wall_repair_too_large")),!0}}return!(!i||i.ring.length<3||this._contourSelfIntersects(i.ring)||this._overlapRoom(i.ring))&&(this._beginWallFaceBatch([{...i,existing:!s,repair:s}]),!0)}catch{return!1}}_columnClick(t){const e=this._snap(t),s=this.host._drawWallCm;if(null==s)return void this._showPhysicalRange(Zt,1);if(!this.host._curSpaceCfg||this._limitReached("column"))return;const i=this.host._spaceModel();if(!i)return;const o={id:"column-"+Date.now().toString(36),shape:"square",center:e,cm:ee(s),angle:0},a=(i.wall_columns||[]).find(t=>Qt(t,o,.02*this.host._gridPitch));if(a)return clearTimeout(this.host._duplicateColumnTimer),this.host._duplicateColumnId=a.id,this.host._duplicateColumnTimer=window.setTimeout(()=>{this.host._duplicateColumnId=null},900),void this.host._showToast(this.host._t("toast.column_duplicate"));const n=this._geometrySnapshot(),r=this.host._curSpaceCfg;r.wall_columns||=[],r.wall_columns.push({...o,center:[e[0]/Sc,e[1]/Sc]}),this._commitPhysicalGeometry(this.host._t("history.column_add"),n)}_openPhysicalDialog(t,e,s){const i=this.host._spaceModel();if(i)if("partition"===t){const s=i.partitions.find(t=>t.id===e);s&&(this.host._physicalDialog={kind:t,id:e,cm:pe(s.cm,this.host._imperial),length:this.host._fmtLen(s.a,s.b)})}else if("column"===t){const s=i.wall_columns.find(t=>t.id===e);s&&(this.host._physicalDialog={kind:t,id:e,cm:pe(s.cm,this.host._imperial),shape:s.shape,angle:this.host._angleField("square"===s.shape?fe(s.angle):0)})}else{const o=i.room_drafts.find(t=>t.id===e),a=Math.max(0,Math.min(o?.segments.length?o.segments.length-1:0,s||0));o?.segments[a]&&(this.host._physicalDialog={kind:t,id:e,segment:a,cm:pe(o.segments[a].cm,this.host._imperial),length:this.host._fmtLen(o.points[a],o.points[a+1])})}}_physicalDown(t,e,s){const i=this.host._spaceModel();if(!i)return;t.stopPropagation(),Dc(t);const o=this._svgPoint(t),a=[];for(const t of[...i.wall_columns].reverse())Se(o,Me(t,this.host._cellCm,this.host._gridPitch))&&a.push({kind:"column",id:t.id});for(const t of[...i.partitions].reverse()){const e=De(t.a,t.b,t.cm,this.host._cellCm,this.host._gridPitch);e&&Se(o,e)&&a.push({kind:"partition",id:t.id})}a.some(t=>t.kind===e&&t.id===s)||a.unshift({kind:e,id:s});const n=a.map(t=>`${t.kind}:${t.id}`).sort().join("|"),r=performance.now(),l=this.host._physicalPickCycle,h=a.length>1&&l?.signature===n&&r-l.at>380&&r-l.at<=1200&&Math.hypot(t.clientX-l.x,t.clientY-l.y)<=10?(l.index+1)%a.length:Math.max(0,a.findIndex(t=>t.kind===e&&t.id===s));this.host._physicalPickCycle={signature:n,index:h,x:t.clientX,y:t.clientY,at:r},e=a[h].kind,s=a[h].id;const c="partition"===e?i.partitions.find(t=>t.id===s):i.wall_columns.find(t=>t.id===s);c&&(this.host._physicalSel={kind:e,id:s},this.host._physicalDrag={pid:t.pointerId,kind:e,id:s,start:this._svgPoint(t),startClient:[t.clientX,t.clientY],before:this._geometrySnapshot(),moved:!1,base:JSON.parse(JSON.stringify(c)),delta:[0,0]})}_clampPhysicalDelta(t,e,s){const i="partition"===t?[e.a,e.b]:[e.center],o=i.map(t=>t[0]),a=i.map(t=>t[1]);return[Math.max(-Kt*Sc-Math.min(...o),Math.min(Kt*Sc-Math.max(...o),s[0])),Math.max(-Kt*Sc-Math.min(...a),Math.min(Kt*Sc-Math.max(...a),s[1]))]}_physicalMove(t){t.stopPropagation(),Ao(this.host,"physical",()=>this._physicalMoveNow(t))}_physicalMoveNow(t){const e=this.host._physicalDrag;if(!e||e.pid!==t.pointerId)return;t.stopPropagation();const s=this._svgPoint(t),i="partition"===e.kind?e.base.a:e.base.center,o=this._snap([i[0]+s[0]-e.start[0],i[1]+s[1]-e.start[1]]),a=this._clampPhysicalDelta(e.kind,e.base,[o[0]-i[0],o[1]-i[1]]);this.host._physicalDrag={...e,delta:a,moved:e.moved||Math.hypot(t.clientX-e.startClient[0],t.clientY-e.startClient[1])>=5}}_physicalUp(t){Fo(this.host,"physical");const e=this.host._physicalDrag;if(!e||e.pid!==t.pointerId)return;if(t.stopPropagation(),this.host._physicalDrag=null,!e.moved)return void this._registerPhysicalTap(e.kind,e.id);const s=this.host._spaceModel();if(!this.host._curSpaceCfg||!s)return;const i=this.host._curSpaceCfg;if("partition"===e.kind){const t=(i.partitions||[]).find(t=>t.id===e.id),s=e.base;if(t){const o={...s,a:[s.a[0]+e.delta[0],s.a[1]+e.delta[1]],b:[s.b[0]+e.delta[0],s.b[1]+e.delta[1]]};t.a=[o.a[0]/Sc,o.a[1]/Sc],t.b=[o.b[0]/Sc,o.b[1]/Sc];for(const t of i.openings||[]){if("partition"!==t.host?.kind||t.host.id!==e.id)continue;const s=dt(t,[o],Sc,this.host._cellCm,this.host._gridPitch).resolved;s&&Object.assign(t,pt(t,s,Sc))}}}else{const t=(i.wall_columns||[]).find(t=>t.id===e.id),o=e.base,a={...o,center:[o.center[0]+e.delta[0],o.center[1]+e.delta[1]]};if(s.wall_columns.some(t=>t.id!==e.id&&Qt(t,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"));t&&(t.center=[(o.center[0]+e.delta[0])/Sc,(o.center[1]+e.delta[1])/Sc])}this._commitPhysicalGeometry(this.host._t("history.physical_move"),e.before)}_registerPhysicalTap(t,e,s){const i=performance.now(),o=this.host._physicalLastTap?.kind===t&&this.host._physicalLastTap.id===e&&this.host._physicalLastTap.segment===s&&i-this.host._physicalLastTap.at<=360;this.host._physicalLastTap={kind:t,id:e,segment:s,at:i},o&&(this.host._physicalLastTap=null,this._openPhysicalDialog(t,e,s))}_cancelPhysicalGesture(){No(this.host,"physical"),No(this.host,"physical-rotate"),this.host._physicalDrag=null,this.host._physicalRotate=null,this.host.requestUpdate()}_physicalRotateDown(t,e){if("square"!==e.shape||!this.host._spaceModel())return;t.preventDefault(),t.stopPropagation(),Dc(t);const s=this._svgPoint(t);this.host._physicalSel={kind:"column",id:e.id},this.host._physicalRotate={pid:t.pointerId,id:e.id,center:[...e.center],startAngle:180*Math.atan2(s[1]-e.center[1],s[0]-e.center[0])/Math.PI,baseAngle:fe(e.angle),angle:fe(e.angle),before:this._geometrySnapshot(),moved:!1}}_physicalRotateMove(t){t.preventDefault(),t.stopPropagation(),Ao(this.host,"physical-rotate",()=>this._physicalRotateMoveNow(t))}_physicalRotateMoveNow(t){const e=this.host._physicalRotate;if(!e||e.pid!==t.pointerId)return;t.preventDefault(),t.stopPropagation();const s=this._svgPoint(t),i=180*Math.atan2(s[1]-e.center[1],s[0]-e.center[0])/Math.PI,o=e.baseAngle+i-e.startAngle,a=fe(t.shiftKey?o:5*Math.round(o/5));this.host._physicalRotate={...e,angle:a,moved:e.moved||Math.abs(o-e.baseAngle)>=.5}}_physicalRotateUp(t){Fo(this.host,"physical-rotate");const e=this.host._physicalRotate;if(!e||e.pid!==t.pointerId)return;t.preventDefault(),t.stopPropagation(),this.host._physicalRotate=null;const s=this.host._spaceModel();if(!e.moved||!this.host._curSpaceCfg||!s)return;const i=s.wall_columns.find(t=>t.id===e.id);if(!i||"square"!==i.shape)return;const o={...i,angle:e.angle};if(s.wall_columns.some(t=>t.id!==e.id&&Qt(t,o,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"));const a=this.host._curSpaceCfg.wall_columns?.find(t=>t.id===e.id);a&&(a.angle=e.angle,this._commitPhysicalGeometry(this.host._t("history.physical_edit"),e.before))}_rszRooms(){const t=[],e=this.host._spaceModel();if(!e)return t;for(const s of e.rooms){const e=s.id?q(s):null;e&&t.push({id:s.id,poly:e,wall_ids:Array.isArray(s.wall_ids)?[...s.wall_ids]:void 0})}return s=t,i=Math.max(1e-12,1e-12*this.host._gridPitch),s.map(t=>{if(!Array.isArray(t.wall_ids)||t.wall_ids.length!==t.poly.length)return{...t,poly:t.poly.map(t=>[...t])};const e=t.poly.map(t=>[...t]);let s=!0;for(;s&&e.length>3;){s=!1;for(let t=0;t0){e.splice(t,1),s=!0;break}}}return{...t,poly:e}});var s,i}_rszOpenings(){return this.host._openingsR.map(t=>({id:t.id,x:t.rx,y:t.ry,length:t.rlen,hosted:!!t.host,angle:t.angle,type:t.type}))}_rszObstacles(){const t=this.host._spaceModel();if(!t)return[];const e=[];for(const s of t.partitions||[])e.push({kind:"segment",a:[...s.a],b:[...s.b],half:x(s.cm,this.host._cellCm,this.host._gridPitch)/2});for(const s of t.room_drafts||[])for(let t=0;t+1Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2).map(t=>({wall:t,a:[t.a[0]*Sc,t.a[1]*this.host._spaceH],b:[t.b[0]*Sc,t.b[1]*this.host._spaceH]})),o=Math.abs(t[0]-e[0])<=.05*this.host._gridPitch?"v":Math.abs(t[1]-e[1])<=.05*this.host._gridPitch?"h":null,a=i.filter(s=>!!o&&("h"===o?!(Math.abs(s.a[1]-t[1])>.05*this.host._gridPitch||Math.abs(s.b[1]-t[1])>.05*this.host._gridPitch)&&Math.min(Math.max(t[0],e[0]),Math.max(s.a[0],s.b[0]))-Math.max(Math.min(t[0],e[0]),Math.min(s.a[0],s.b[0]))>.05*this.host._gridPitch:!(Math.abs(s.a[0]-t[0])>.05*this.host._gridPitch||Math.abs(s.b[0]-t[0])>.05*this.host._gridPitch)&&Math.min(Math.max(t[1],e[1]),Math.max(s.a[1],s.b[1]))-Math.max(Math.min(t[1],e[1]),Math.min(s.a[1],s.b[1]))>.05*this.host._gridPitch)),n=new Set(a.map(t=>Number(t.wall.cm)).filter(t=>t>0));return{minDim:this.host._cmToUnits(30),eps:.05*this.host._gridPitch,step:this.host._gridPitch,movingHalf:s>0?x(s,this.host._cellCm,this.host._gridPitch)/2:0,obstacles:this._rszObstacles(),thicknessConflict:n.size>1}}_rszResolution(t,e,s){const i=this.host._resize.snapshotIdentity||s||this._rszSnapshot(),o=`${this.host._space}|${this.host._cellCm}|${this.host._gridPitch}|${i}`,a=`${t}:${e}`;return this.host._resize.resolve(o,a,()=>{const s=[...this.host._resize.rooms||this._rszRooms()],i=s.find(e=>e.id===t),o=i?.poly?.[e]||[0,0],a=i?.poly?.[(e+1)%(i?.poly?.length||1)]||[0,0];return function(t,e,s,i,o){const{eps:a}=o,n=t.find(t=>t.id===s);if(!n||i<0||i>=(n.poly?.length||0)||n.poly.length<4||!Da(n.poly))return{enabled:!1,reason:"invalid-geometry"};const r=n.poly[i],l=n.poly[(i+1)%n.poly.length],h=Ta(r,l,a);if(!h)return{enabled:!1,reason:"diagonal"};if(!Fa(n.poly,i,h,a))return{enabled:!1,reason:"side-angle"};if(o.thicknessConflict)return{enabled:!1,reason:"thickness-conflict"};for(const t of o.obstacles||[])if(La(t,r,l,o))return{enabled:!1,reason:"duplicate-physical-wall"};const c=ka(ya(l,r)),d=[],p=new Set;let u=!1,_=!1;for(const e of t)if(e.id!==s)for(let t=0;t1||d.length>1)return{enabled:!1,reason:"multiple-rooms"};const m={[s]:i},g=[s];if(1===d.length){const t=d[0];if(!Da(t.room.poly))return{enabled:!1,reason:"invalid-geometry"};if(!Fa(t.room.poly,t.edge,h,a))return{enabled:!1,reason:"side-angle"};g.push(t.room.id),m[t.room.id]=t.edge}const f=[];for(const t of e)if(!(Sa([t.x,t.y],r,l)>2*a)){if(t.hosted||t.length>c+2*a)return{enabled:!1,reason:"opening-conflict"};f.push(t.id)}const b=Object.fromEntries(g.map(e=>[e,t.find(t=>t.id===e).poly.length])),v=[];for(const e of g){const s=t.find(t=>t.id===e),i=m[e],o=(i-1+s.poly.length)%s.poly.length,n=(i+1)%s.poly.length,r=Ba(t,e,o,1,a),l=Ba(t,e,n,0,a);if(!r||!l)return{enabled:!1,reason:"partial-shared"};v.push(r,l)}const y={roomId:s,edge:i,a:[...r],b:[...l],n:Ma(n.poly,i),roomIds:g,edgeByRoom:m,topology:b,movingOpeningIds:f,sideOwnership:v};if(!Va(t,e,y,0,o))return{enabled:!1,reason:"invalid-geometry"};const $=Math.abs(Number(o.step));if(Number.isFinite($)&&$>a){const s=[-$,$];if(!s.some(s=>Va(t,e,y,s,o))){if(!s.some(s=>ja(qa(t,e,y,s),y,a)))return{enabled:!1,reason:"partial-shared"};const i={...o,obstacles:[]};return s.some(s=>Va(t,e,y,s,i))?{enabled:!1,reason:"duplicate-physical-wall"}:e.length&&s.some(e=>Va(t,[],y,e,o))?{enabled:!1,reason:"opening-conflict"}:{enabled:!1,reason:"invalid-geometry"}}}return{enabled:!0,plan:y}}(s,[...this.host._resize.openings||this._rszOpenings()],t,e,this._rszOptsFor(o,a))})}_rszSnapshot(){return JSON.stringify(this._geometrySnapshot()||{spaceId:this.host._space,rooms:[],openings:[],walls:[],open_spans:[]})}_rszResetController(){const t=null!==this.host._resize.preview;this.host._resize.reset(),t&&this.host._cfgEpoch++}_rszProjectPreview(t,e,s,i,o){this.host._rszLimitViolation=null;const a=this.host._serverCfg?.spaces.find(t=>t.id===this.host._space);if(!a||!this.host._serverCfg)return{ok:!1,reason:"missing-context"};const n=JSON.parse(t),r={...a,rooms:n.rooms,openings:n.openings||[]};for(const t of["walls","wall_segments","open_spans","room_drafts","partitions","wall_columns","decor"])void 0!==n[t]?r[t]=n[t]:delete r[t];for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==n.plan_transform?.[t]?r[t]=n.plan_transform[t]:delete r[t];const l=this.host._spaceH;for(const[t,s]of Object.entries(e)){const e=r.rooms.find(e=>e.id===t);e&&(e.poly=s.map(t=>[t[0]/Sc,t[1]/l]),delete e.x,delete e.y,delete e.w,delete e.h)}for(const[t,e]of Object.entries(s)){const s=(r.openings||[]).find(e=>e.id===t);s&&(s.x=e[0]/Sc,s.y=e[1]/l)}const h=[],c=[];for(const t of i){const e=o.find(e=>e.id===t),s=r.rooms.find(e=>e.id===t);if(!e||!s?.poly)continue;const i=s.poly.map(t=>[t[0]*Sc,t[1]*l]);if(e.poly.length!==i.length)continue;const a=Array.isArray(e.wall_ids)?e.wall_ids:[];for(let t=0;tt.id===s):null;o&&(o.a=[i[t][0]/Sc,i[t][1]/Sc],o.b=[i[(t+1)%i.length][0]/Sc,i[(t+1)%i.length][1]/Sc])}}if(h.length&&Array.isArray(r.walls)&&r.walls.length){const t=Ce(r.walls,h,c,this.host._wallKeyPitch,Sc,"fixed-topology");if(t.rejected)return{ok:!1,reason:"wall-metadata"};r.walls=t.walls}const d=[];for(const t of r.rooms||[]){const e=q(t);if(e&&!(e.length<2))for(let t=0;tJSON.stringify([t?.key,t?.cm,t?.a,t?.b]),u=new Map;for(const t of n.walls||[]){const e=p(t);u.set(e,(u.get(e)||0)+1)}const _=[];for(const t of r.walls||[]){const e=p(t),s=u.get(e)||0;s?u.set(e,s-1):_.push(t)}if(Pe(_,d,this.host._wallKeyPitch,Sc,n.walls||[]).length)return{ok:!1,reason:"wall-metadata"};const m=function(t,e,s=1e-8){const i=sn(t),o=new Set(e),a=i.flatMap(t=>{if(!o.has(String(t.id||"")))return[];const e=rn(nn(t));return e?[e]:[]});return i.flatMap(t=>{const e=String(t.id||""),i=rn(nn(t)),n=!!i&&a.some(t=>i.minX<=t.maxX+s&&i.maxX+s>=t.minX&&i.minY<=t.maxY+s&&i.maxY+s>=t.minY);return e&&(o.has(e)||n)?[e]:[]})}(r.rooms||[],i),g=ln(r,m);if(!g||!this._rszSpaceCandidateGeometry(this.host._space,g).ok)return{ok:!1,reason:"physical-geometry"};const f={...this.host._serverCfg,spaces:(this.host._serverCfg?.spaces||[]).map(t=>t?.id===this.host._space?r:t)};try{this._resizePreviewNodes=nt(g.rooms,g.walls,[],W,this.host._cellCm,this.host._gridPitch,Sc)}catch{this._resizePreviewNodes=null}let b;try{const t=new Set(i),e=this.host._junctionLimitViolations(f,this.host._space,{status:"lightweight",multiWallNodes:this._resizePreviewNodes},t);b=Tr(e,this._resizeBaselineLimits.filter(e=>"clearance"!==e.rule||t.has(e.subject)))}catch{b=[{rule:"check_failed",subject:this.host._space,actual:0,limit:0}]}return b.length?(this.host._rszLimitViolation=b[0],{ok:!1,reason:"junction-limit"}):{ok:!0,value:{preview:{space:this.host._space,sp:r},beforeWalls:n.walls||[],afterWalls:r.walls||[],artifact:null}}}_rszAcceptPreview(t,e){if(this.host._cfgEpoch++,this.host._physicalBodiesCache&&(this.host._physicalBodiesCache.key=`${this.host._space}|${this.host._cfgEpoch}|${this.host._cellCm}|${this.host._gridPitch}`),!t||!e)return;const s=Ie(e);if(!s)return;const i=`${this.host._space}|${this.host._cfgEpoch}|${t.sp.rooms.length}`;Object.defineProperty(s,"sourceFingerprint",{value:_([t.sp,this.host._cellCm,this.host._gridPitch]),enumerable:!1});const o={key:i,value:s};xc(this.host._wallUnionPool,i,o,8),this.host._wallUnionCache=o}_rszSpaceCandidateGeometry(t,e){if(!this.host._serverCfg)return{ok:!1,wallGeometry:null};const s={...this.host._serverCfg,spaces:this.host._serverCfg.spaces.map(s=>s.id===t?e:s)};let i=null;try{return{ok:this.host._checkSpacePhysicalGeometry(s,t,t=>{i=t}).ok,wallGeometry:i}}catch{return{ok:!1,wallGeometry:null}}}_rszSpaceCandidateRenderable(t,e){if(!this.host._serverCfg)return!1;try{const s={...this.host._serverCfg,spaces:this.host._serverCfg.spaces.map(s=>s.id===t?e:s)};return this.host._checkSpacePhysicalGeometry(s,t).ok}catch{return!1}}_rszCandidateRenderable(t){return!!t&&t.space===this.host._space&&this._rszSpaceCandidateRenderable(t.space,t.sp)}_rszEdgeDown(t,e,s){if("resize"!==this.host._tool||this.host._resize.dragging)return;this._resizeBaseFrameStable=!0,t.stopPropagation(),t.preventDefault();const i=this._rszRooms(),o=this._rszResolution(e,s);if(!o.enabled)return void this.host._showToast(this._rszReasonText(o.reason));Dc(t);const a=o.plan;try{this._resizeBaselineLimits=this.host._junctionLimitViolations(this.host._serverCfg,this.host._space,null,new Set(a.roomIds))}catch{this._resizeBaselineLimits=[]}const n=this._svgPoint(t),r=`${this.host._space}|${this.host._cfgEpoch}|${i.length}`,l=this.host._wallUnionCache?.key===r?this.host._wallUnionCache.value:null,h=this._rszSnapshot();this.host._resize.begin({pointerId:t.pointerId,start:[n[0],n[1]],roomId:e,plan:a,options:this._rszOptsFor(a.a,a.b),rooms:i,openings:this._rszOpenings(),snapshotIdentity:h,before:JSON.parse(h),wallUnionBefore:l,epochBefore:this.host._cfgEpoch})}_rszReasonText(t){return this.host._t(`resize.disabled.${t}`)}_rszDisabledActivate(t,e){t.stopPropagation(),t.preventDefault(),this.host._showToast(this._rszReasonText(e))}_rszDisabledKey(t,e){"Enter"!==t.key&&" "!==t.key||this._rszDisabledActivate(t,e)}_rszMove(t){this.host._resize.ownsPointer(t.pointerId)&&(t.stopPropagation(),Ao(this.host,"resize",()=>this._rszMoveNow(t)))}_rszMoveNow(t){if(!this.host._resize.ownsPointer(t.pointerId))return;t.stopPropagation();const e=this._svgPoint(t),s=this.host._resize.move({pointerId:t.pointerId,point:[e[0],e[1]],step:this.host._gridPitch,snap:t=>{const e=this._snap(t);return[e[0],e[1]]},project:(t,e,s,i,o)=>this._rszProjectPreview(t,e,s,i,o),publish:(t,e)=>this._rszAcceptPreview(t,e),measure:(t,e)=>this._rszEdgeLabels(t,e)});if("rejected"===s.kind)return s.notify&&this.host._showToast(this.host._rszLimitViolation?`${this.host._t("resize.limit_stopped")} — `+this._junctionLimitLabel(this.host._rszLimitViolation):this.host._t("resize.preview_failed")),void this.host.requestUpdate();"accepted"===s.kind&&this.host.requestUpdate()}_rszUp(t){if(Fo(this.host,"resize"),!this.host._resize.ownsPointer(t.pointerId))return;t.stopPropagation();const e=this.host._resize.finish({pointerId:t.pointerId,currentSnapshotIdentity:this._rszSnapshot(),validatePreview:t=>this._rszCandidateRenderable(t)});if("no-op"===e.kind)return this.host._cfgEpoch++,void this.host.requestUpdate();if("rejected"===e.kind)return this.host._cfgEpoch++,this.host._showToast(this.host._t("resize.commit_failed")),void this.host.requestUpdate();const s=e.preview,i=this.host._serverCfg?.spaces.find(t=>t.id===s.space);i&&(i.rooms=s.sp.rooms,i.openings=s.sp.openings,Array.isArray(s.sp.walls)&&(s.sp.walls.length?i.walls=s.sp.walls:delete i.walls),Array.isArray(s.sp.wall_segments)&&(i.wall_segments=s.sp.wall_segments)),this.host._suppressClick=!0,setTimeout(()=>this.host._suppressClick=!1,0),this._commitPhysicalGeometry(this.host._t("history.resize_room"),e.before),this.host.requestUpdate()}_rszCancelDrag(t){No(this.host,"resize");const e=this.host._resize.cancel(this._rszSnapshot(),t);if("no-op"!==e.kind){if(null!==e.restoreEpoch?this.host._cfgEpoch=e.restoreEpoch:this.host._cfgEpoch++,this.host._physicalBodiesCache&&(this.host._physicalBodiesCache.key=`${this.host._space}|${this.host._cfgEpoch}|${this.host._cellCm}|${this.host._gridPitch}`),e.restoreWallUnion){const t=this.host._spaceModel();if(t){const s=`${this.host._space}|${this.host._cfgEpoch}|${t.rooms.length}`,i={key:s,value:e.restoreWallUnion};xc(this.host._wallUnionPool,s,i,8),this.host._wallUnionCache=i}}null!==e.restoreEpoch&&"plan"===this.host._mode&&this._resizeBaseFrameStable&&(this.host._terminalFrame=1),this.host.requestUpdate()}}_rszPointerCancel(t){this.host._resize.ownsPointer(t.pointerId)&&(t.stopPropagation(),this._rszCancelDrag(t.pointerId))}_rszEdgeLabels(t,e,s=this.host._resize.rooms){const i=s,o=[],a=t.polys[e.roomId]||i?.find(t=>t.id===e.roomId).poly;if(!a||!i)return o;const n=a.length,r=this._rszInnerSpanCms(e.roomId,a,t.polys);for(const t of function(t,e){const s=t.length;return[(e-1+s)%s,(e+1)%s]}(a,e.edge)){const e=a[t],s=a[(t+1)%n],i=r?.[t];o.push({kind:"length",x:(e[0]+s[0])/2,y:(e[1]+s[1])/2,text:null==i?this.host._fmtLen(e,s):Te(i,"mi"===this.host.hass?.config?.unit_system?.length),edge:{a:[e[0],e[1]],b:[s[0],s[1]]}})}const l="mi"===this.host.hass?.config?.unit_system?.length,h=e.roomIds,c=this.host._spaceWalls,d=this.host._physicalBodiesR(),p=this.host._baseVb(),u=this.host._view&&this.host._view.w>0&&this.host._view.h>0?this.host._view:{x:p[0],y:p[1],w:p[2],h:p[3]},[_,m]=this.host._lastValidStageSize||[u.w,u.h],g={...u,stageWidth:Math.max(1,_),stageHeight:Math.max(1,m)},f=this.host._spaceModel(),b=this.host._config?.icon_size??2.5,v=f?ze(b>8?2.5:b,f,u.w,this.host._kiosk?this.host._kioskScale.icon:1)*g.stageWidth/100:24,y=Math.max(10,.77*v),$=this.host._t("room.settings_short"),w=y*(1.457+.66*Math.max(1,$.length)*.42);for(const s of h){const a=t.polys[s]||i.find(t=>t.id===s).poly,n=c.length&&f&<(f.rooms,s,c,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc,null,this._resizePreviewNodes)||a,r=d.length?Re(Ae(n,d))*Math.pow(this.host._cellCm/this.host._gridPitch,2)/1e4:Fe(n,this.host._gridPitch,this.host._cellCm),h=Ne(r,l),p=or({poly:a,edge:e.edgeByRoom[s],text:h,view:g,gearCenter:He(a),gearWidthPx:w,gearHeightPx:y});o.push({kind:"area",roomId:s,x:p.anchor[0],y:p.anchor[1],text:h,placement:p})}return o}_rszInnerSpanCms(t,e,s){const i=Object.keys(s).length?Object.entries(s).map(([t,e])=>({id:t,poly:e})):this.host._spaceModel()?.rooms;if(!i?.length)return null;const o=this.host._spaceWalls;if(!o.length)return null;const a=this.host._openCuts(),n=Le(i,t,o,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,Sc);if(!n||n.length!==e.length)return null;const r=this.host._cellCm/this.host._gridPitch;return e.map((t,s)=>Ee(e,s,n)*r)}_renderResizeMeasurements(){const t=this.host._resize.liveLabels;if(!t?.length)return d;const e=t.filter(t=>"length"===t.kind),s=t.filter(t=>"area"===t.kind);return f`