mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
fix: attach a warm summary runtime before the first render (#506)
Every card instance attached its summary-panel runtime through import().then(), even when the chunk had loaded long ago. The first render therefore measured a header without summary controls; the controls arrived a beat later, the stage shrank, the deferred refit opened a `stage-resize` continuity candidate and the first HA tick paid three extra render passes (Full Performance: blend stateUpdate1 50 → 130 ms, overlay 217 → 809 ms; locally 4 performUpdate per tick instead of 1). summary-runtime-loader.ts separates the summary code from its state: the loaded factory is cached per page, every host builds its own runtime from it (no shared preferences, drafts, subscriptions, timers or DOM). A warm factory yields the runtime synchronously in connectedCallback, before the first Lit render; a cold mount still pays one lazy import, concurrent cold mounts share the pending import, a failed import is forgotten so the next connection retries, and a disconnect cancels the pending attachment of that connection. SummaryRuntimeSlot owns the per-host lifecycle so the card core stays under its line ceiling. Witnesses: loader unit tests (distinct instances, shared pending import, cancelled attachment, retry after failure); demo/smoke_summary_warm_attach (warm replacement and cold-key instance on a warm page own the runtime before the first render, header/stage stable from the first frame, no stage-resize, one performUpdate per geometry-neutral tick, a real viewport resize still opens stage-resize); mutant summary-runtime-attaches-after- first-render. smoke_summary_panel waited for `_summary` as a readiness proxy; it now waits for the server config load, which stays asynchronous. Local paired glow benchmarks (4× CPU throttle): blend 159.7 → 49.9 ms and overlay 326.7 → 120.4 ms at stateUpdate1 with renders 4 → 1; the isometric load loses the three summary-owned long tasks. Docs screenshots: all 11 frames decode pixel-identical to the committed ones; the manifest carries only the new source fingerprint. Initial View ceiling recentred 299 100 → 299 600 for the +299 B loader. Issue: #506 User-Visible: yes
This commit is contained in:
@@ -1,309 +1,309 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c",
|
||||
"fingerprint": "95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74",
|
||||
"entry": "houseplan-card.js",
|
||||
"panelEntry": "houseplan-panel.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 298592,
|
||||
"initialViewGzipBytes": 298891,
|
||||
"initialPanelFiles": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-card.js",
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelGzipBytes": 300898,
|
||||
"initialPanelGzipBytes": 301193,
|
||||
"initialPanelOnlyFiles": [
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelOnlyGzipBytes": 2306,
|
||||
"initialPanelOnlyGzipBytes": 2302,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/de-BeD9SIYF.js",
|
||||
"houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"houseplan-assets/fr-CNfLzzDS.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-DgPgbQG8.js",
|
||||
"houseplan-assets/iso-scene-render-9PxxIEfq.js",
|
||||
"houseplan-assets/live-interaction-runtime-OETM7GZm.js",
|
||||
"houseplan-assets/pdf-export-B6G-AgbE.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/de-IBWzSVOj.js",
|
||||
"houseplan-assets/editor-DKd1NGbT.js",
|
||||
"houseplan-assets/fr-T10CV6-a.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-HyXCDpzQ.js",
|
||||
"houseplan-assets/iso-scene-render-miMf0jvt.js",
|
||||
"houseplan-assets/live-interaction-runtime-Dahsj-4y.js",
|
||||
"houseplan-assets/pdf-export-DpHlViMV.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js"
|
||||
],
|
||||
"lazyGzipBytes": 417382,
|
||||
"lazyGzipBytes": 417329,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/editor-DKd1NGbT.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 205653,
|
||||
"lazyEditorGzipBytes": 205633,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14155,
|
||||
"lazyOnboardingGzipBytes": 14148,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-BeD9SIYF.js",
|
||||
"houseplan-assets/fr-CNfLzzDS.js"
|
||||
"houseplan-assets/de-IBWzSVOj.js",
|
||||
"houseplan-assets/fr-T10CV6-a.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 54861,
|
||||
"lazyLocaleGzipBytes": 54843,
|
||||
"lazyIsometricFiles": [
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/iso-scene-render-9PxxIEfq.js"
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/iso-scene-render-miMf0jvt.js"
|
||||
],
|
||||
"lazyIsometricGzipBytes": 13462,
|
||||
"lazyIsometricGzipBytes": 13452,
|
||||
"lazyFurnitureArtFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js"
|
||||
],
|
||||
"lazyFurnitureArtGzipBytes": 10250,
|
||||
"lazyFurnitureArtGzipBytes": 10253,
|
||||
"lazyPdfFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/pdf-export-B6G-AgbE.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/pdf-export-DpHlViMV.js"
|
||||
],
|
||||
"lazyPdfGzipBytes": 120364,
|
||||
"lazyPdfGzipBytes": 120367,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"sha256": "650f25935f5a935e0f1c301b3bd03bb094331d1916c1094ea63c6f53866b8c45",
|
||||
"path": "houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"sha256": "a4abe8807d8c404a7ce9f65b0a72ca3d8f8d4d5bf38fa8220915818f9238c0db",
|
||||
"rawBytes": 21134,
|
||||
"gzipBytes": 7149,
|
||||
"gzipBytes": 7144,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-BeD9SIYF.js",
|
||||
"sha256": "7d09210471855559b0fea7e7648794d75d120a32628c5d77811e9e7c7e6d9e08",
|
||||
"path": "houseplan-assets/de-IBWzSVOj.js",
|
||||
"sha256": "cf031fb380b4b056c116e14a8cb26729ae4d0b275991b07989917f884f8841ff",
|
||||
"rawBytes": 91441,
|
||||
"gzipBytes": 27713,
|
||||
"gzipBytes": 27705,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"sha256": "8b59adf27c503ef36a00c2eb0a04395bfd6f5c2eac107e6ba12bc2fdc0c01d56",
|
||||
"path": "houseplan-assets/editor-DKd1NGbT.js",
|
||||
"sha256": "e62e388db3b39eaa5f0e8f9b9676b7a6e30c453f84d22d530740f9be093512d1",
|
||||
"rawBytes": 3837,
|
||||
"gzipBytes": 1586,
|
||||
"gzipBytes": 1585,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-CNfLzzDS.js",
|
||||
"sha256": "b1e8ed99400065e906fcc31a1d1f44940f981fb50c2d09a2ff74cdac10dc689e",
|
||||
"path": "houseplan-assets/fr-T10CV6-a.js",
|
||||
"sha256": "b602e1137a8395f963be744ed43d2054e472093502f687e40e6bd3e7a25a8794",
|
||||
"rawBytes": 93719,
|
||||
"gzipBytes": 27148,
|
||||
"gzipBytes": 27138,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"sha256": "0c81d49c5e4c9d0b138090a99ca124361f75309ed582f05d07c69fc1b6b92d7f",
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"sha256": "1e26cad8d04b459f4b1140e705a02a1d380b8c49a84f92b8ea2ce3e684544800",
|
||||
"rawBytes": 33655,
|
||||
"gzipBytes": 10250,
|
||||
"gzipBytes": 10253,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"sha256": "2a75558ea50a3c91ab270154441b18f7d392989faae049db00c9af57b206e2c4",
|
||||
"path": "houseplan-assets/guard-7S6iRB0N.js",
|
||||
"sha256": "67f95421a21516a66157d8fdc0129c2d1280cee31a3621a81039c88835d1c0f8",
|
||||
"rawBytes": 518,
|
||||
"gzipBytes": 371,
|
||||
"gzipBytes": 368,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"sha256": "9202eb087cecb9012efd1360898e3687b53b6729f65605978a8b52d1ed177721",
|
||||
"rawBytes": 1075388,
|
||||
"gzipBytes": 297788,
|
||||
"path": "houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"sha256": "dea85ab6dfeebcb263bd672270041e34473d40b9db24e69259e55d42e5ff44d4",
|
||||
"rawBytes": 1076387,
|
||||
"gzipBytes": 298088,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-BeD9SIYF.js",
|
||||
"houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"houseplan-assets/fr-CNfLzzDS.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-DgPgbQG8.js",
|
||||
"houseplan-assets/iso-scene-render-9PxxIEfq.js",
|
||||
"houseplan-assets/live-interaction-runtime-OETM7GZm.js",
|
||||
"houseplan-assets/pdf-export-B6G-AgbE.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js"
|
||||
"houseplan-assets/de-IBWzSVOj.js",
|
||||
"houseplan-assets/editor-DKd1NGbT.js",
|
||||
"houseplan-assets/fr-T10CV6-a.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-HyXCDpzQ.js",
|
||||
"houseplan-assets/iso-scene-render-miMf0jvt.js",
|
||||
"houseplan-assets/live-interaction-runtime-Dahsj-4y.js",
|
||||
"houseplan-assets/pdf-export-DpHlViMV.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"sha256": "bd9b6667a2f78549c03e5293959a5ce7dd5ab215eee62420f58f3226d06e6109",
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"sha256": "bc5163222924f68e6279b412b16a53f28a76b5b4d80d4a03e7fe28c4cce77a39",
|
||||
"rawBytes": 671972,
|
||||
"gzipBytes": 178865,
|
||||
"gzipBytes": 178859,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js"
|
||||
"houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js",
|
||||
"sha256": "8d2b5ba0b169d463192e7b8531c396f89512117701c7deaa6b2e0c83491504a7",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js",
|
||||
"sha256": "31ea22267928606938b34c47f1ac8ecc2041048bc8c045a411d7108d353de849",
|
||||
"rawBytes": 28237,
|
||||
"gzipBytes": 7006,
|
||||
"gzipBytes": 7004,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-DgPgbQG8.js",
|
||||
"sha256": "ac3c9b34db5772235b1879861640c4be53b912a9e468a274276cf4d0bb8beb02",
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-HyXCDpzQ.js",
|
||||
"sha256": "0e18deb183cb473c2a96fb689c91c68a3729b8ad56fb8907b01c30810585dbec",
|
||||
"rawBytes": 11034,
|
||||
"gzipBytes": 3730,
|
||||
"gzipBytes": 3731,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/iso-scene-render-9PxxIEfq.js",
|
||||
"sha256": "673ec1ceddb36f8f7db22c1038222726f4227ed84e9f355783c7fe2d037ddfdb",
|
||||
"path": "houseplan-assets/iso-scene-render-miMf0jvt.js",
|
||||
"sha256": "00fd101b4e5469f6d289b77eab3056bedf98082520af9139a1afff5823fcb025",
|
||||
"rawBytes": 38562,
|
||||
"gzipBytes": 13091,
|
||||
"gzipBytes": 13084,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/live-interaction-runtime-OETM7GZm.js",
|
||||
"sha256": "5934f78ad823a530f1bb2c3cd08e053ebfdd0594f23fddadb9e57067388a3c12",
|
||||
"path": "houseplan-assets/live-interaction-runtime-Dahsj-4y.js",
|
||||
"sha256": "631b277aae71d9977fabb3f330c4a9cdf38e47ec51259584540b747d9c9444df",
|
||||
"rawBytes": 5196,
|
||||
"gzipBytes": 2129,
|
||||
"gzipBytes": 2124,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/pdf-export-B6G-AgbE.js",
|
||||
"sha256": "d02cb2b142ed3d4e40f64993eff91e7a81ac5ed1eac8ce9c3edb9c4298e5a98d",
|
||||
"path": "houseplan-assets/pdf-export-DpHlViMV.js",
|
||||
"sha256": "48b07b9ecfbbf2c1a8de53edce8bc32b1217e2c2f20eb5ceb24af75999870d8a",
|
||||
"rawBytes": 237254,
|
||||
"gzipBytes": 110114,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-editor-Dme32gxk.js",
|
||||
"sha256": "d434810c15653a8ca694ce41c03cd47f60b9e3ce9f3213f11a333386695658d2",
|
||||
"path": "houseplan-assets/summary-panel-editor-DOpNDtK_.js",
|
||||
"sha256": "4ed28cc81b7f0ccac46e0fb6ac37856ddbdf7813040585447089bf4a0a61805f",
|
||||
"rawBytes": 14811,
|
||||
"gzipBytes": 3390,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-metrics-JJMWCHbb.js",
|
||||
"sha256": "39d084074a8865a58dc2875ea6a9baaa77b271cca9c9b27029421ca6f2112fcf",
|
||||
"path": "houseplan-assets/summary-panel-metrics-DXF83oAy.js",
|
||||
"sha256": "51953d004b76561a842f67b9455985cceac2663c52499d1e1acc3a3cdfdaded9",
|
||||
"rawBytes": 2195,
|
||||
"gzipBytes": 1124,
|
||||
"gzipBytes": 1121,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js",
|
||||
"sha256": "c609232a40013bce973b3b61c0b9ce3f248bb097481d437ab16ae971d5f201c4",
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js",
|
||||
"sha256": "7598bcc5d26d8d2f9a15cc154c32a0b836ba0ac53b7b5f9b65f3c2c2bc0287d1",
|
||||
"rawBytes": 69530,
|
||||
"gzipBytes": 19035,
|
||||
"gzipBytes": 19034,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/summary-panel-editor-Dme32gxk.js",
|
||||
"houseplan-assets/summary-panel-metrics-JJMWCHbb.js"
|
||||
"houseplan-assets/summary-panel-editor-DOpNDtK_.js",
|
||||
"houseplan-assets/summary-panel-metrics-DXF83oAy.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-r_7fRPfa.js",
|
||||
"sha256": "8267766cadbaf205251335d92caa66bd52ffa045e30e6e5cf1c756416a4e37d7",
|
||||
"path": "houseplan-assets/zigbee-topology-DOkBU6gZ.js",
|
||||
"sha256": "0176688590ae76a8766ee735de892e37f29211a042c27f5a2992eda0cc8ef8d9",
|
||||
"rawBytes": 18961,
|
||||
"gzipBytes": 7432,
|
||||
"gzipBytes": 7424,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js",
|
||||
"sha256": "db59921337f4f57b8514031b320f97a435a5de52bfb4ec1e83855e10701102a9",
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js",
|
||||
"sha256": "6b43a567d3686249519d43ef6f04bb9596529d99d04f745944c0e561c0e3034e",
|
||||
"rawBytes": 3941,
|
||||
"gzipBytes": 1763,
|
||||
"gzipBytes": 1762,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "af03812bb65afed2afaeaca3bac52eedbcf2d6683218b28e5f53cf78224721ba",
|
||||
"sha256": "b8095427f52e7413e84d3202953d15765fbd43d4536226beff01ba7ff692ae2e",
|
||||
"rawBytes": 1205,
|
||||
"gzipBytes": 804,
|
||||
"gzipBytes": 803,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-panel.js",
|
||||
"sha256": "b7fcfa42f2b03ab3a356197655d34118879732907391b0e40c6b3b85c0e5ca7b",
|
||||
"sha256": "f0a1709a58213029c08e73da2ed81b217827c8f5cdbf96e082385cfb608eabcc",
|
||||
"rawBytes": 6124,
|
||||
"gzipBytes": 2306,
|
||||
"gzipBytes": 2302,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-card.js"
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{t as e,l as o,x as t,e5 as s,A as a,e6 as i,e7 as l,e8 as n,dV as r,b as c}from"./houseplan-card-mOz0zLlc.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{t as e,l as o,x as t,e4 as s,A as a,e5 as i,e6 as l,e7 as n,dV as r,b as c}from"./houseplan-card-Bj6mVEeM.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{dT as r,dU as e,dV as t}from"./houseplan-card-Bj6mVEeM.js";const s={},a=r(class extends e{constructor(){super(...arguments),this.ot=s}render(r,e){return e()}update(r,[e,s]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((r,e)=>r===this.ot[e]))return t}else if(this.ot===e)return t;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,s)}});export{a as i};
|
||||
@@ -1 +0,0 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{dT as r,dU as t,dV as s}from"./houseplan-card-mOz0zLlc.js";const e={},a=r(class extends t{constructor(){super(...arguments),this.ot=e}render(r,t){return t()}update(r,[t,e]){if(Array.isArray(t)){if(Array.isArray(this.ot)&&this.ot.length===t.length&&t.every((r,t)=>r===this.ot[t]))return s}else if(this.ot===t)return s;return this.ot=Array.isArray(t)?Array.from(t):t,this.render(t,e)}});export{a as i};
|
||||
+17
-17
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
+28
-28
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+8
-8
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{b as a,A as e}from"./houseplan-card-mOz0zLlc.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-0R-S6cIO.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{b as a,A as e}from"./houseplan-card-Bj6mVEeM.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-2X-IAkWu.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
<span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong>
|
||||
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
|
||||
<input id="summary-local-show" data-summary-local-show type="checkbox"
|
||||
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{az as e,ea as t,eb as n,bs as i,ec as r,P as a,a5 as s,M as o,aq as c,N as l,bq as d,bp as u,ed as f}from"./houseplan-card-mOz0zLlc.js";function g(t){if(!t.registry.authoritative)return null;const n=new Set,i=e(t.markers);for(const e of Object.values(t.registry.devices||{}))e?.id&&"service"!==e.entry_type&&!i.devices.has(e.id)&&e.area_id&&t.areaToSpace[e.area_id]&&n.add(e.id);for(const e of t.markers||[]){if(e.removed||"virtual"===e.binding)continue;const r=String(e.binding||"").indexOf(":");if(r<1)continue;const a=e.binding.slice(0,r),s=e.binding.slice(r+1),o="device"===a?t.registry.devices?.[s]:null,c="entity"===a?t.registry.entities?.[s]:null,l="device"===a?s:c?.device_id,d="device"===a?o?.area_id:c?.area_id||l&&t.registry.devices?.[l]?.area_id,u="string"==typeof e.room_id&&e.room_id.length>0&&null===e.area?"":e.area||d||"",f=u&&t.areaToSpace[u]||e.space||t.firstSpaceId;l&&t.registry.devices?.[l]&&t.spaceIds.has(f)&&(!i.devices.has(l)||"entity"===a&&i.liveEntities.has(s))&&n.add(l)}return n}function m(e,t){return e?.length?t?.length?f(e,t):e:t}function v(e,t){try{let n=0;for(const i of t){const t=e.spaces.find(e=>String(e?.id)===i.id);if(!t)continue;const f=r(t,i);let g=null;for(const e of i.rooms){if(!e.id)continue;const t=a(e);if(!t)continue;const n=s(i.rooms,e.id,f.walls,f.openCuts,o,f.cellCm,c,l)||t;g=m(g,d(n,f.physicalBodies))}const v=f.cellCm/c;n+=u(g)*v*v/1e4}return n}catch{return null}}function y(e,t,n,r){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:i(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(r||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function _(e,i){const r=e?.states?.[i];if(!r)return null;const a=t(e,i);return a?n(a,String(r.attributes?.unit_of_measurement||"")):null}export{g as representedHaDeviceIds,_ as summaryEntityValue,y as summarySystemValue,v as totalCleanFloorAreaM2};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{az as e,ea as t,eb as n,bs as i,ec as r,P as a,a5 as s,M as o,aq as c,N as l,bq as d,bp as u,ed as f}from"./houseplan-card-Bj6mVEeM.js";function g(t){if(!t.registry.authoritative)return null;const n=new Set,i=e(t.markers);for(const e of Object.values(t.registry.devices||{}))e?.id&&"service"!==e.entry_type&&!i.devices.has(e.id)&&e.area_id&&t.areaToSpace[e.area_id]&&n.add(e.id);for(const e of t.markers||[]){if(e.removed||"virtual"===e.binding)continue;const r=String(e.binding||"").indexOf(":");if(r<1)continue;const a=e.binding.slice(0,r),s=e.binding.slice(r+1),o="device"===a?t.registry.devices?.[s]:null,c="entity"===a?t.registry.entities?.[s]:null,l="device"===a?s:c?.device_id,d="device"===a?o?.area_id:c?.area_id||l&&t.registry.devices?.[l]?.area_id,u="string"==typeof e.room_id&&e.room_id.length>0&&null===e.area?"":e.area||d||"",f=u&&t.areaToSpace[u]||e.space||t.firstSpaceId;l&&t.registry.devices?.[l]&&t.spaceIds.has(f)&&(!i.devices.has(l)||"entity"===a&&i.liveEntities.has(s))&&n.add(l)}return n}function m(e,t){return e?.length?t?.length?f(e,t):e:t}function v(e,t){try{let n=0;for(const i of t){const t=e.spaces.find(e=>String(e?.id)===i.id);if(!t)continue;const f=r(t,i);let g=null;for(const e of i.rooms){if(!e.id)continue;const t=a(e);if(!t)continue;const n=s(i.rooms,e.id,f.walls,f.openCuts,o,f.cellCm,c,l)||t;g=m(g,d(n,f.physicalBodies))}const v=f.cellCm/c;n+=u(g)*v*v/1e4}return n}catch{return null}}function y(e,t,n,r){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:i(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(r||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function _(e,i){const r=e?.states?.[i];if(!r)return null;const a=t(e,i);return a?n(a,String(r.attributes?.unit_of_measurement||"")):null}export{g as representedHaDeviceIds,_ as summaryEntityValue,y as summarySystemValue,v as totalCleanFloorAreaM2};
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{n as t,b as n}from"./zigbee-topology-r_7fRPfa.js";import{F as e}from"./houseplan-card-mOz0zLlc.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function p(t){if(!0!==t?.user?.is_admin)throw a("permission")}function f(n){const e=i(n);return e?c(e,"zha",async()=>{if(p(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function g(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function m(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(p(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,f=null,m=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{f=t,m=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const p=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&f?.(n):c&&m?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof p&&b.push(p),await g(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await g(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{f as readZhaTopology,m as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{n as t,b as n}from"./zigbee-topology-DOkBU6gZ.js";import{F as e}from"./houseplan-card-Bj6mVEeM.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function p(t){if(!0!==t?.user?.is_admin)throw a("permission")}function f(n){const e=i(n);return e?c(e,"zha",async()=>{if(p(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function g(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function m(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(p(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,f=null,m=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{f=t,m=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const p=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&f?.(n):c&&m?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof p&&b.push(p),await g(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await g(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{f as readZhaTopology,m as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";try{await import("./houseplan-assets/houseplan-card-mOz0zLlc.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";try{await import("./houseplan-assets/houseplan-card-Bj6mVEeM.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -137,7 +137,9 @@ const pickerWitnessSetup = await page.evaluate(async () => {
|
||||
extra.hass = card.hass;
|
||||
extra.setConfig({ ...(card._config || {}), type: 'custom:houseplan-card' });
|
||||
document.body.append(extra);
|
||||
for (let attempt = 0; attempt < 100 && !extra._summary; attempt++) {
|
||||
// #506: the warm summary runtime now exists synchronously; the readiness
|
||||
// this witness needs is the server config load, which stays asynchronous.
|
||||
for (let attempt = 0; attempt < 400 && !(extra._summary && extra._loadOk); attempt++) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5));
|
||||
}
|
||||
extra._serverCfg = structuredClone(card._serverCfg);
|
||||
|
||||
Executable
+153
@@ -0,0 +1,153 @@
|
||||
// #506: a card instance created on a page whose summary chunk is already
|
||||
// loaded must own its summary runtime BEFORE the first render. Otherwise the
|
||||
// first header measurement sees no summary controls, the controls arrive a
|
||||
// beat later, the stage shrinks and the deferred refit opens a `stage-resize`
|
||||
// continuity candidate with three render passes on top of the first HA tick
|
||||
// (Full Performance: blend stateUpdate1 50 → 130 ms, overlay 217 → 809 ms).
|
||||
//
|
||||
// Three instances on one 780×669 page with a long title (the soft-layout
|
||||
// fixture of test/boot-soft-layout.test.mjs):
|
||||
// c1 — cold page (launchPanelCold): the chunk is imported once, lazily;
|
||||
// c2 — warm replacement of c1 (same config key, warm memo): AC4;
|
||||
// c3 — a cold-key instance (new title) on the warm page: AC4 second half;
|
||||
// then AC5: one geometry-neutral HA tick on c3 costs one performUpdate and no
|
||||
// stage-resize; then AC6: a real container resize DOES open stage-resize.
|
||||
// FAILS on the build before #506 (runtime attached via import().then()).
|
||||
import { launchPanelCold, check, finish } from './serve.mjs';
|
||||
|
||||
const LONG_TITLE = 'A deliberately long House Plan title that wraps the header onto a second line at 780 px';
|
||||
|
||||
// A page without any card yet: the summary chunk is provably cold for c1.
|
||||
const { page, browser } = await launchPanelCold({ width: 780, height: 669 });
|
||||
await page.evaluate(() => import('/assets/houseplan-card.js'));
|
||||
await page.waitForFunction(() => !!customElements.get('houseplan-card'));
|
||||
|
||||
const res = await page.evaluate(async ({ longTitle }) => {
|
||||
const out = {};
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
const Card = customElements.get('houseplan-card');
|
||||
Card._warmBootReset?.();
|
||||
localStorage.removeItem('houseplan_card_nav_v1');
|
||||
|
||||
const wrap = document.createElement('div');
|
||||
wrap.style.cssText = 'position:fixed;left:0;top:0;width:780px;height:669px;z-index:99;background:#000';
|
||||
document.body.appendChild(wrap);
|
||||
const sr = (c) => c.shadowRoot || c.renderRoot;
|
||||
const candidates = (c) => {
|
||||
const seen = [];
|
||||
const original = c._continuity.beginCandidate.bind(c._continuity);
|
||||
c._continuity.beginCandidate = (reason, recovery) => { seen.push(reason); return original(reason, recovery); };
|
||||
return seen;
|
||||
};
|
||||
const mk = (title) => {
|
||||
const c = document.createElement('houseplan-card');
|
||||
c.setConfig({ type: 'custom:houseplan-card', title });
|
||||
c.hass = window.__mkHass();
|
||||
wrap.appendChild(c);
|
||||
return c;
|
||||
};
|
||||
const settle = async (c) => {
|
||||
const t0 = performance.now();
|
||||
while ((c._booting || !c._loadOk || !(c._devices?.length > 0)) && performance.now() - t0 < 4000) await sleep(30);
|
||||
await c.updateComplete;
|
||||
await sleep(350);
|
||||
};
|
||||
const controls = (c) => sr(c).querySelectorAll('.summary-control').length;
|
||||
/** Per-frame header/stage sizes for ~600 ms after mount. */
|
||||
const sample = async (c) => {
|
||||
const frames = [];
|
||||
const t1 = performance.now();
|
||||
await new Promise((done) => {
|
||||
const step = () => {
|
||||
const stage = sr(c).querySelector('.stage');
|
||||
if (stage) frames.push({ t: Math.round(performance.now() - t1), hdrH: c._hdrH, stageH: stage.clientHeight, summary: !!c._summary });
|
||||
if (performance.now() - t1 < 600) requestAnimationFrame(step); else done();
|
||||
};
|
||||
requestAnimationFrame(step);
|
||||
});
|
||||
return frames;
|
||||
};
|
||||
|
||||
// ---- c1: the cold page pays the import once ----
|
||||
const c1 = mk(longTitle);
|
||||
out.coldHasNoRuntimeSynchronously = !c1._summary; // the lazy boundary is intact
|
||||
await settle(c1);
|
||||
out.coldRuntimeArrived = !!c1._summary;
|
||||
const finalHdr = c1._hdrH;
|
||||
const finalStage = sr(c1).querySelector('.stage').clientHeight;
|
||||
out.coldHeaderWraps = finalHdr > 60 ? true : `hdrH=${finalHdr}`;
|
||||
c1.remove();
|
||||
await sleep(30);
|
||||
|
||||
// ---- c2: warm replacement (same key) — AC4 ----
|
||||
const c2 = mk(longTitle);
|
||||
out.warmReplacementRuntimeBeforeFirstRender = !!c2._summary && !c2.hasUpdated;
|
||||
const seen2 = candidates(c2);
|
||||
const frames2 = await sample(c2);
|
||||
await settle(c2);
|
||||
out.warmReplacementFramesSampled = frames2.length > 10;
|
||||
const bad2 = frames2.filter((f) => Math.abs(f.hdrH - finalHdr) > 1 || Math.abs(f.stageH - finalStage) > 2);
|
||||
out.warmReplacementHeaderStableFromFirstFrame = bad2.length === 0
|
||||
? true : `final=${finalHdr}/${finalStage}; frame=${JSON.stringify(bad2[0])}`;
|
||||
out.warmReplacementNoStageResize = !seen2.includes('stage-resize') ? true : JSON.stringify(seen2);
|
||||
out.warmReplacementDistinctRuntime = c2._summary !== c1._summary;
|
||||
c2.remove();
|
||||
await sleep(30);
|
||||
|
||||
// ---- c3: cold key on a warm page (the benchmark's per-sample card) — AC4 ----
|
||||
const c3 = mk(`${longTitle} #${Date.now()}`);
|
||||
out.coldKeyRuntimeBeforeFirstRender = !!c3._summary && !c3.hasUpdated;
|
||||
const seen3 = candidates(c3);
|
||||
const frames3 = await sample(c3);
|
||||
await settle(c3);
|
||||
out.coldKeyFramesSampled = frames3.length > 10;
|
||||
const hdr3 = c3._hdrH;
|
||||
const stage3 = sr(c3).querySelector('.stage').clientHeight;
|
||||
// The first frame that has a stage already has the final header and stage.
|
||||
const settled3 = frames3.filter((f) => f.stageH > 0);
|
||||
const bad3 = settled3.filter((f) => Math.abs(f.hdrH - hdr3) > 1 || Math.abs(f.stageH - stage3) > 2);
|
||||
out.coldKeyHeaderStableFromFirstFrame = bad3.length === 0
|
||||
? true : `final=${hdr3}/${stage3}; frame=${JSON.stringify(bad3[0])} of ${settled3.length}`;
|
||||
out.coldKeyNoStageResize = !seen3.includes('stage-resize') ? true : JSON.stringify(seen3);
|
||||
out.coldKeyControlsRendered = controls(c3) > 0 ? true : 'no summary controls in the header';
|
||||
|
||||
// ---- AC5: a geometry-neutral HA tick after startup costs one render ----
|
||||
seen3.length = 0;
|
||||
let renders = 0;
|
||||
const originalUpdate = c3.performUpdate.bind(c3);
|
||||
c3.performUpdate = () => { renders++; return originalUpdate(); };
|
||||
const hass = window.__mkHass();
|
||||
const ceiling = hass.states['light.ceiling'];
|
||||
c3.hass = { ...hass, states: { ...hass.states, 'light.ceiling': {
|
||||
...ceiling, attributes: { ...ceiling.attributes, brightness: 200 },
|
||||
} } };
|
||||
await c3.updateComplete;
|
||||
await new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)));
|
||||
await sleep(120);
|
||||
out.firstTickSingleRender = renders === 1 ? true : `performUpdate ×${renders}`;
|
||||
out.firstTickNoStageResize = !seen3.includes('stage-resize') ? true : JSON.stringify(seen3);
|
||||
|
||||
window.__c3 = c3;
|
||||
window.__seen3 = seen3;
|
||||
return out;
|
||||
}, { longTitle: LONG_TITLE });
|
||||
for (const [k, v] of Object.entries(res)) check(k, v);
|
||||
|
||||
// ---- AC6: a real viewport resize still owns the stage (positive witness) ----
|
||||
await page.setViewportSize({ width: 780, height: 600 });
|
||||
const rez = await page.evaluate(async () => {
|
||||
const out = {};
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
const c3 = window.__c3;
|
||||
const seen3 = window.__seen3;
|
||||
seen3.length = 0;
|
||||
await sleep(400);
|
||||
out.realResizeOpensStageResize = seen3.includes('stage-resize') ? true : JSON.stringify(seen3);
|
||||
const stage = (c3.shadowRoot || c3.renderRoot).querySelector('.stage').clientHeight;
|
||||
out.realResizeStageFollows = Math.abs(stage - (600 - c3._hdrH)) < 4 ? true : `stage=${stage} hdr=${c3._hdrH}`;
|
||||
c3.remove();
|
||||
document.querySelectorAll('div[style*="z-index:99"]').forEach((el) => el.remove());
|
||||
return out;
|
||||
});
|
||||
for (const [k, v] of Object.entries(rez)) check(k, v);
|
||||
await finish(browser, { ...res, ...rez });
|
||||
Vendored
+140
-140
@@ -1,309 +1,309 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c",
|
||||
"fingerprint": "95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74",
|
||||
"entry": "houseplan-card.js",
|
||||
"panelEntry": "houseplan-panel.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 298592,
|
||||
"initialViewGzipBytes": 298891,
|
||||
"initialPanelFiles": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-card.js",
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelGzipBytes": 300898,
|
||||
"initialPanelGzipBytes": 301193,
|
||||
"initialPanelOnlyFiles": [
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelOnlyGzipBytes": 2306,
|
||||
"initialPanelOnlyGzipBytes": 2302,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/de-BeD9SIYF.js",
|
||||
"houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"houseplan-assets/fr-CNfLzzDS.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-DgPgbQG8.js",
|
||||
"houseplan-assets/iso-scene-render-9PxxIEfq.js",
|
||||
"houseplan-assets/live-interaction-runtime-OETM7GZm.js",
|
||||
"houseplan-assets/pdf-export-B6G-AgbE.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/de-IBWzSVOj.js",
|
||||
"houseplan-assets/editor-DKd1NGbT.js",
|
||||
"houseplan-assets/fr-T10CV6-a.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-HyXCDpzQ.js",
|
||||
"houseplan-assets/iso-scene-render-miMf0jvt.js",
|
||||
"houseplan-assets/live-interaction-runtime-Dahsj-4y.js",
|
||||
"houseplan-assets/pdf-export-DpHlViMV.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js"
|
||||
],
|
||||
"lazyGzipBytes": 417382,
|
||||
"lazyGzipBytes": 417329,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/editor-DKd1NGbT.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 205653,
|
||||
"lazyEditorGzipBytes": 205633,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14155,
|
||||
"lazyOnboardingGzipBytes": 14148,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-BeD9SIYF.js",
|
||||
"houseplan-assets/fr-CNfLzzDS.js"
|
||||
"houseplan-assets/de-IBWzSVOj.js",
|
||||
"houseplan-assets/fr-T10CV6-a.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 54861,
|
||||
"lazyLocaleGzipBytes": 54843,
|
||||
"lazyIsometricFiles": [
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/iso-scene-render-9PxxIEfq.js"
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/iso-scene-render-miMf0jvt.js"
|
||||
],
|
||||
"lazyIsometricGzipBytes": 13462,
|
||||
"lazyIsometricGzipBytes": 13452,
|
||||
"lazyFurnitureArtFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js"
|
||||
],
|
||||
"lazyFurnitureArtGzipBytes": 10250,
|
||||
"lazyFurnitureArtGzipBytes": 10253,
|
||||
"lazyPdfFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/pdf-export-B6G-AgbE.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/pdf-export-DpHlViMV.js"
|
||||
],
|
||||
"lazyPdfGzipBytes": 120364,
|
||||
"lazyPdfGzipBytes": 120367,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"sha256": "650f25935f5a935e0f1c301b3bd03bb094331d1916c1094ea63c6f53866b8c45",
|
||||
"path": "houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"sha256": "a4abe8807d8c404a7ce9f65b0a72ca3d8f8d4d5bf38fa8220915818f9238c0db",
|
||||
"rawBytes": 21134,
|
||||
"gzipBytes": 7149,
|
||||
"gzipBytes": 7144,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-BeD9SIYF.js",
|
||||
"sha256": "7d09210471855559b0fea7e7648794d75d120a32628c5d77811e9e7c7e6d9e08",
|
||||
"path": "houseplan-assets/de-IBWzSVOj.js",
|
||||
"sha256": "cf031fb380b4b056c116e14a8cb26729ae4d0b275991b07989917f884f8841ff",
|
||||
"rawBytes": 91441,
|
||||
"gzipBytes": 27713,
|
||||
"gzipBytes": 27705,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"sha256": "8b59adf27c503ef36a00c2eb0a04395bfd6f5c2eac107e6ba12bc2fdc0c01d56",
|
||||
"path": "houseplan-assets/editor-DKd1NGbT.js",
|
||||
"sha256": "e62e388db3b39eaa5f0e8f9b9676b7a6e30c453f84d22d530740f9be093512d1",
|
||||
"rawBytes": 3837,
|
||||
"gzipBytes": 1586,
|
||||
"gzipBytes": 1585,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-CNfLzzDS.js",
|
||||
"sha256": "b1e8ed99400065e906fcc31a1d1f44940f981fb50c2d09a2ff74cdac10dc689e",
|
||||
"path": "houseplan-assets/fr-T10CV6-a.js",
|
||||
"sha256": "b602e1137a8395f963be744ed43d2054e472093502f687e40e6bd3e7a25a8794",
|
||||
"rawBytes": 93719,
|
||||
"gzipBytes": 27148,
|
||||
"gzipBytes": 27138,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"sha256": "0c81d49c5e4c9d0b138090a99ca124361f75309ed582f05d07c69fc1b6b92d7f",
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"sha256": "1e26cad8d04b459f4b1140e705a02a1d380b8c49a84f92b8ea2ce3e684544800",
|
||||
"rawBytes": 33655,
|
||||
"gzipBytes": 10250,
|
||||
"gzipBytes": 10253,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"sha256": "2a75558ea50a3c91ab270154441b18f7d392989faae049db00c9af57b206e2c4",
|
||||
"path": "houseplan-assets/guard-7S6iRB0N.js",
|
||||
"sha256": "67f95421a21516a66157d8fdc0129c2d1280cee31a3621a81039c88835d1c0f8",
|
||||
"rawBytes": 518,
|
||||
"gzipBytes": 371,
|
||||
"gzipBytes": 368,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"sha256": "9202eb087cecb9012efd1360898e3687b53b6729f65605978a8b52d1ed177721",
|
||||
"rawBytes": 1075388,
|
||||
"gzipBytes": 297788,
|
||||
"path": "houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"sha256": "dea85ab6dfeebcb263bd672270041e34473d40b9db24e69259e55d42e5ff44d4",
|
||||
"rawBytes": 1076387,
|
||||
"gzipBytes": 298088,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-BeD9SIYF.js",
|
||||
"houseplan-assets/editor-C7LQ7Tds.js",
|
||||
"houseplan-assets/fr-CNfLzzDS.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-DgPgbQG8.js",
|
||||
"houseplan-assets/iso-scene-render-9PxxIEfq.js",
|
||||
"houseplan-assets/live-interaction-runtime-OETM7GZm.js",
|
||||
"houseplan-assets/pdf-export-B6G-AgbE.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js"
|
||||
"houseplan-assets/de-IBWzSVOj.js",
|
||||
"houseplan-assets/editor-DKd1NGbT.js",
|
||||
"houseplan-assets/fr-T10CV6-a.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-HyXCDpzQ.js",
|
||||
"houseplan-assets/iso-scene-render-miMf0jvt.js",
|
||||
"houseplan-assets/live-interaction-runtime-Dahsj-4y.js",
|
||||
"houseplan-assets/pdf-export-DpHlViMV.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BIh9fgX7.js",
|
||||
"sha256": "bd9b6667a2f78549c03e5293959a5ce7dd5ab215eee62420f58f3226d06e6109",
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-DJMGYUqW.js",
|
||||
"sha256": "bc5163222924f68e6279b412b16a53f28a76b5b4d80d4a03e7fe28c4cce77a39",
|
||||
"rawBytes": 671972,
|
||||
"gzipBytes": 178865,
|
||||
"gzipBytes": 178859,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js"
|
||||
"houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-B6gvpoQT.js",
|
||||
"sha256": "8d2b5ba0b169d463192e7b8531c396f89512117701c7deaa6b2e0c83491504a7",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-Cdd3N5hN.js",
|
||||
"sha256": "31ea22267928606938b34c47f1ac8ecc2041048bc8c045a411d7108d353de849",
|
||||
"rawBytes": 28237,
|
||||
"gzipBytes": 7006,
|
||||
"gzipBytes": 7004,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CE5VSDDA.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/backdrop-pick-CXOE1u8Z.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-DgPgbQG8.js",
|
||||
"sha256": "ac3c9b34db5772235b1879861640c4be53b912a9e468a274276cf4d0bb8beb02",
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-HyXCDpzQ.js",
|
||||
"sha256": "0e18deb183cb473c2a96fb689c91c68a3729b8ad56fb8907b01c30810585dbec",
|
||||
"rawBytes": 11034,
|
||||
"gzipBytes": 3730,
|
||||
"gzipBytes": 3731,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/iso-scene-render-9PxxIEfq.js",
|
||||
"sha256": "673ec1ceddb36f8f7db22c1038222726f4227ed84e9f355783c7fe2d037ddfdb",
|
||||
"path": "houseplan-assets/iso-scene-render-miMf0jvt.js",
|
||||
"sha256": "00fd101b4e5469f6d289b77eab3056bedf98082520af9139a1afff5823fcb025",
|
||||
"rawBytes": 38562,
|
||||
"gzipBytes": 13091,
|
||||
"gzipBytes": 13084,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/guard-Cxp8QKxn.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/guard-7S6iRB0N.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/live-interaction-runtime-OETM7GZm.js",
|
||||
"sha256": "5934f78ad823a530f1bb2c3cd08e053ebfdd0594f23fddadb9e57067388a3c12",
|
||||
"path": "houseplan-assets/live-interaction-runtime-Dahsj-4y.js",
|
||||
"sha256": "631b277aae71d9977fabb3f330c4a9cdf38e47ec51259584540b747d9c9444df",
|
||||
"rawBytes": 5196,
|
||||
"gzipBytes": 2129,
|
||||
"gzipBytes": 2124,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/pdf-export-B6G-AgbE.js",
|
||||
"sha256": "d02cb2b142ed3d4e40f64993eff91e7a81ac5ed1eac8ce9c3edb9c4298e5a98d",
|
||||
"path": "houseplan-assets/pdf-export-DpHlViMV.js",
|
||||
"sha256": "48b07b9ecfbbf2c1a8de53edce8bc32b1217e2c2f20eb5ceb24af75999870d8a",
|
||||
"rawBytes": 237254,
|
||||
"gzipBytes": 110114,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/furniture-plan-art.generated-CxZ67Ud8.js",
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-C-yj8ZTi.js",
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-editor-Dme32gxk.js",
|
||||
"sha256": "d434810c15653a8ca694ce41c03cd47f60b9e3ce9f3213f11a333386695658d2",
|
||||
"path": "houseplan-assets/summary-panel-editor-DOpNDtK_.js",
|
||||
"sha256": "4ed28cc81b7f0ccac46e0fb6ac37856ddbdf7813040585447089bf4a0a61805f",
|
||||
"rawBytes": 14811,
|
||||
"gzipBytes": 3390,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-metrics-JJMWCHbb.js",
|
||||
"sha256": "39d084074a8865a58dc2875ea6a9baaa77b271cca9c9b27029421ca6f2112fcf",
|
||||
"path": "houseplan-assets/summary-panel-metrics-DXF83oAy.js",
|
||||
"sha256": "51953d004b76561a842f67b9455985cceac2663c52499d1e1acc3a3cdfdaded9",
|
||||
"rawBytes": 2195,
|
||||
"gzipBytes": 1124,
|
||||
"gzipBytes": 1121,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-0R-S6cIO.js",
|
||||
"sha256": "c609232a40013bce973b3b61c0b9ce3f248bb097481d437ab16ae971d5f201c4",
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-2X-IAkWu.js",
|
||||
"sha256": "7598bcc5d26d8d2f9a15cc154c32a0b836ba0ac53b7b5f9b65f3c2c2bc0287d1",
|
||||
"rawBytes": 69530,
|
||||
"gzipBytes": 19035,
|
||||
"gzipBytes": 19034,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/summary-panel-editor-Dme32gxk.js",
|
||||
"houseplan-assets/summary-panel-metrics-JJMWCHbb.js"
|
||||
"houseplan-assets/summary-panel-editor-DOpNDtK_.js",
|
||||
"houseplan-assets/summary-panel-metrics-DXF83oAy.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-r_7fRPfa.js",
|
||||
"sha256": "8267766cadbaf205251335d92caa66bd52ffa045e30e6e5cf1c756416a4e37d7",
|
||||
"path": "houseplan-assets/zigbee-topology-DOkBU6gZ.js",
|
||||
"sha256": "0176688590ae76a8766ee735de892e37f29211a042c27f5a2992eda0cc8ef8d9",
|
||||
"rawBytes": 18961,
|
||||
"gzipBytes": 7432,
|
||||
"gzipBytes": 7424,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-DzxOfpWb.js",
|
||||
"sha256": "db59921337f4f57b8514031b320f97a435a5de52bfb4ec1e83855e10701102a9",
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-CiDfY5zA.js",
|
||||
"sha256": "6b43a567d3686249519d43ef6f04bb9596529d99d04f745944c0e561c0e3034e",
|
||||
"rawBytes": 3941,
|
||||
"gzipBytes": 1763,
|
||||
"gzipBytes": 1762,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js",
|
||||
"houseplan-assets/zigbee-topology-r_7fRPfa.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js",
|
||||
"houseplan-assets/zigbee-topology-DOkBU6gZ.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "af03812bb65afed2afaeaca3bac52eedbcf2d6683218b28e5f53cf78224721ba",
|
||||
"sha256": "b8095427f52e7413e84d3202953d15765fbd43d4536226beff01ba7ff692ae2e",
|
||||
"rawBytes": 1205,
|
||||
"gzipBytes": 804,
|
||||
"gzipBytes": 803,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-mOz0zLlc.js"
|
||||
"houseplan-assets/houseplan-card-Bj6mVEeM.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-panel.js",
|
||||
"sha256": "b7fcfa42f2b03ab3a356197655d34118879732907391b0e40c6b3b85c0e5ca7b",
|
||||
"sha256": "f0a1709a58213029c08e73da2ed81b217827c8f5cdbf96e082385cfb608eabcc",
|
||||
"rawBytes": 6124,
|
||||
"gzipBytes": 2306,
|
||||
"gzipBytes": 2302,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-card.js"
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{t as e,l as o,x as t,e5 as s,A as a,e6 as i,e7 as l,e8 as n,dV as r,b as c}from"./houseplan-card-mOz0zLlc.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{t as e,l as o,x as t,e4 as s,A as a,e5 as i,e6 as l,e7 as n,dV as r,b as c}from"./houseplan-card-Bj6mVEeM.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{dT as r,dU as e,dV as t}from"./houseplan-card-Bj6mVEeM.js";const s={},a=r(class extends e{constructor(){super(...arguments),this.ot=s}render(r,e){return e()}update(r,[e,s]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((r,e)=>r===this.ot[e]))return t}else if(this.ot===e)return t;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,s)}});export{a as i};
|
||||
-1
@@ -1 +0,0 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{dT as r,dU as t,dV as s}from"./houseplan-card-mOz0zLlc.js";const e={},a=r(class extends t{constructor(){super(...arguments),this.ot=e}render(r,t){return t()}update(r,[t,e]){if(Array.isArray(t)){if(Array.isArray(this.ot)&&this.ot.length===t.length&&t.every((r,t)=>r===this.ot[t]))return s}else if(this.ot===t)return s;return this.ot=Array.isArray(t)?Array.from(t):t,this.render(t,e)}});export{a as i};
|
||||
Vendored
+17
-17
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
+28
-28
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+8
-8
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{b as a,A as e}from"./houseplan-card-mOz0zLlc.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-0R-S6cIO.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{b as a,A as e}from"./houseplan-card-Bj6mVEeM.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-2X-IAkWu.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
<span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong>
|
||||
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
|
||||
<input id="summary-local-show" data-summary-local-show type="checkbox"
|
||||
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{az as e,ea as t,eb as n,bs as i,ec as r,P as a,a5 as s,M as o,aq as c,N as l,bq as d,bp as u,ed as f}from"./houseplan-card-mOz0zLlc.js";function g(t){if(!t.registry.authoritative)return null;const n=new Set,i=e(t.markers);for(const e of Object.values(t.registry.devices||{}))e?.id&&"service"!==e.entry_type&&!i.devices.has(e.id)&&e.area_id&&t.areaToSpace[e.area_id]&&n.add(e.id);for(const e of t.markers||[]){if(e.removed||"virtual"===e.binding)continue;const r=String(e.binding||"").indexOf(":");if(r<1)continue;const a=e.binding.slice(0,r),s=e.binding.slice(r+1),o="device"===a?t.registry.devices?.[s]:null,c="entity"===a?t.registry.entities?.[s]:null,l="device"===a?s:c?.device_id,d="device"===a?o?.area_id:c?.area_id||l&&t.registry.devices?.[l]?.area_id,u="string"==typeof e.room_id&&e.room_id.length>0&&null===e.area?"":e.area||d||"",f=u&&t.areaToSpace[u]||e.space||t.firstSpaceId;l&&t.registry.devices?.[l]&&t.spaceIds.has(f)&&(!i.devices.has(l)||"entity"===a&&i.liveEntities.has(s))&&n.add(l)}return n}function m(e,t){return e?.length?t?.length?f(e,t):e:t}function v(e,t){try{let n=0;for(const i of t){const t=e.spaces.find(e=>String(e?.id)===i.id);if(!t)continue;const f=r(t,i);let g=null;for(const e of i.rooms){if(!e.id)continue;const t=a(e);if(!t)continue;const n=s(i.rooms,e.id,f.walls,f.openCuts,o,f.cellCm,c,l)||t;g=m(g,d(n,f.physicalBodies))}const v=f.cellCm/c;n+=u(g)*v*v/1e4}return n}catch{return null}}function y(e,t,n,r){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:i(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(r||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function _(e,i){const r=e?.states?.[i];if(!r)return null;const a=t(e,i);return a?n(a,String(r.attributes?.unit_of_measurement||"")):null}export{g as representedHaDeviceIds,_ as summaryEntityValue,y as summarySystemValue,v as totalCleanFloorAreaM2};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{az as e,ea as t,eb as n,bs as i,ec as r,P as a,a5 as s,M as o,aq as c,N as l,bq as d,bp as u,ed as f}from"./houseplan-card-Bj6mVEeM.js";function g(t){if(!t.registry.authoritative)return null;const n=new Set,i=e(t.markers);for(const e of Object.values(t.registry.devices||{}))e?.id&&"service"!==e.entry_type&&!i.devices.has(e.id)&&e.area_id&&t.areaToSpace[e.area_id]&&n.add(e.id);for(const e of t.markers||[]){if(e.removed||"virtual"===e.binding)continue;const r=String(e.binding||"").indexOf(":");if(r<1)continue;const a=e.binding.slice(0,r),s=e.binding.slice(r+1),o="device"===a?t.registry.devices?.[s]:null,c="entity"===a?t.registry.entities?.[s]:null,l="device"===a?s:c?.device_id,d="device"===a?o?.area_id:c?.area_id||l&&t.registry.devices?.[l]?.area_id,u="string"==typeof e.room_id&&e.room_id.length>0&&null===e.area?"":e.area||d||"",f=u&&t.areaToSpace[u]||e.space||t.firstSpaceId;l&&t.registry.devices?.[l]&&t.spaceIds.has(f)&&(!i.devices.has(l)||"entity"===a&&i.liveEntities.has(s))&&n.add(l)}return n}function m(e,t){return e?.length?t?.length?f(e,t):e:t}function v(e,t){try{let n=0;for(const i of t){const t=e.spaces.find(e=>String(e?.id)===i.id);if(!t)continue;const f=r(t,i);let g=null;for(const e of i.rooms){if(!e.id)continue;const t=a(e);if(!t)continue;const n=s(i.rooms,e.id,f.walls,f.openCuts,o,f.cellCm,c,l)||t;g=m(g,d(n,f.physicalBodies))}const v=f.cellCm/c;n+=u(g)*v*v/1e4}return n}catch{return null}}function y(e,t,n,r){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:i(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(r||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function _(e,i){const r=e?.states?.[i];if(!r)return null;const a=t(e,i);return a?n(a,String(r.attributes?.unit_of_measurement||"")):null}export{g as representedHaDeviceIds,_ as summaryEntityValue,y as summarySystemValue,v as totalCleanFloorAreaM2};
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";import{n as t,b as n}from"./zigbee-topology-r_7fRPfa.js";import{F as e}from"./houseplan-card-mOz0zLlc.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function p(t){if(!0!==t?.user?.is_admin)throw a("permission")}function f(n){const e=i(n);return e?c(e,"zha",async()=>{if(p(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function g(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function m(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(p(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,f=null,m=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{f=t,m=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const p=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&f?.(n):c&&m?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof p&&b.push(p),await g(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await g(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{f as readZhaTopology,m as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";import{n as t,b as n}from"./zigbee-topology-DOkBU6gZ.js";import{F as e}from"./houseplan-card-Bj6mVEeM.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function p(t){if(!0!==t?.user?.is_admin)throw a("permission")}function f(n){const e=i(n);return e?c(e,"zha",async()=>{if(p(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function g(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function m(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(p(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,f=null,m=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{f=t,m=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const p=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&f?.(n):c&&m?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof p&&b.push(p),await g(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await g(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{f as readZhaTopology,m as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="807c2621b5e1c592548244ff5adb94281d1799a1481ada113e6938b375396c5c";try{await import("./houseplan-assets/houseplan-card-mOz0zLlc.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="95d32c120d1ca37feb5a930e4a20e5ec2c460f82a52d88a41fe0d143f697ae74";try{await import("./houseplan-assets/houseplan-card-Bj6mVEeM.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1966,6 +1966,20 @@ imported only after the settings button is pressed. It edits one draft; a
|
||||
successful revision-checked shared write precedes application of the draft
|
||||
local show choice.
|
||||
|
||||
`summary-runtime-loader.ts` (#506) separates the summary *code* from its
|
||||
*state*. The loaded factory is remembered per page; every host builds its own
|
||||
runtime from it — preferences, drafts, subscriptions, timers and DOM are never
|
||||
shared between card instances. Once the factory is warm, a new instance
|
||||
(a warm remount or a cold card on a warm page) receives its runtime
|
||||
synchronously in `connectedCallback`, before the first Lit render, so the
|
||||
first header measurement already includes the summary controls and no late
|
||||
summary-driven refit or `stage-resize` continuity candidate follows. The chunk
|
||||
itself stays lazy: the first cold mount pays one dynamic import, concurrent
|
||||
cold mounts share that pending import, a failed import is forgotten so the next
|
||||
connection may retry, and a disconnect cancels the pending attachment of that
|
||||
connection so a late resolution cannot connect a runtime to a host that has
|
||||
left the tree. A same-node reconnect keeps its instance.
|
||||
|
||||
The #505 designer-aligned surface stays in the lazy summary graph. Its sheet
|
||||
includes the settings-only composition from `summary-panel-editor-style.ts`.
|
||||
The runtime installs `summary-panel-dialog-style.ts` in each summary dialog's
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Reopening the plan on a page that has already loaded the summary panel no
|
||||
longer triggers a late header re-measurement and an extra round of heavy
|
||||
redraws right after the first frame: the panel's controls are part of the
|
||||
first frame, so the first device/glow update lands on a stable stage
|
||||
([#506](https://github.com/Matysh/houseplan-card/issues/506)).
|
||||
|
||||
## v1.73.0 — 2026-09-09
|
||||
|
||||
- House Plan opens from its own page in the Home Assistant sidebar, without
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- Повторное открытие плана на странице, где сводная панель уже загружена,
|
||||
больше не вызывает позднего перемера шапки и лишнего круга тяжёлых
|
||||
перерисовок сразу после первого кадра: элементы панели входят в первый кадр,
|
||||
и первое обновление устройств/свечения ложится на стабильную сцену
|
||||
([#506](https://github.com/Matysh/houseplan-card/issues/506)).
|
||||
|
||||
## v1.73.0 — 2026-09-09
|
||||
|
||||
- House Plan открывается с собственной страницы в боковом меню Home Assistant;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"fixture": "synthetic-only",
|
||||
"chromium": "151.0.7922.34",
|
||||
"oxipng": "oxipng 10.2.0",
|
||||
"sourceFingerprint": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceFingerprint": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"captureScriptSha256": "9e4b0ae533407fe003a129078aec020f2c83d67cdb6fc6da696ce3d829beaeb5",
|
||||
"command": "npm run build && node demo/docs/capture.mjs",
|
||||
"scenarios": {
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "76c35a87810e3dc6890bda7b43da133f57d8860031204a62cda7115c15950090"
|
||||
},
|
||||
"view-touch": {
|
||||
@@ -26,7 +26,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "795585acb09488236ebb8028a7fcbd918404c5fe01560bb9b4559de13d441625"
|
||||
},
|
||||
"space-create": {
|
||||
@@ -37,7 +37,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "9f0970de09772674c3156b9fc5b2d49de0ceb22be11ecf8b136047d37d100a84"
|
||||
},
|
||||
"room-contour-close": {
|
||||
@@ -48,7 +48,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "0c354a79f9c3660788b6c5e889a27b6bd78b1f209dc0eef6bb43e2c1344028c4"
|
||||
},
|
||||
"plan-context-tray": {
|
||||
@@ -59,7 +59,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "64169c543291bc4df806dcf8ff484b42c8ea55eb343323d945344e0e28f2ce97"
|
||||
},
|
||||
"device-editor": {
|
||||
@@ -70,7 +70,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "3c8703175605fcf0387d654cd30783ecfd33e21743e70b45190a5ae1a8d355c2"
|
||||
},
|
||||
"device-display-preview": {
|
||||
@@ -81,7 +81,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "5d6193202102f5e6d85567f1111fa105895b933979fbf369c6ba0b1029deb823"
|
||||
},
|
||||
"background-editor": {
|
||||
@@ -92,7 +92,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "375900a29aa62632883ede6727b7dbb8b48cabe9d7d0e16425f9779c837f3dd9"
|
||||
},
|
||||
"room-card": {
|
||||
@@ -103,7 +103,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "3d85424676c823ddca3fa7dab3cce089b6030e48c05d16d2d48d922c66c0cbd2"
|
||||
},
|
||||
"device-info": {
|
||||
@@ -114,7 +114,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "ac962820f8e1c5cb5b042d39b18dc95905fa840cb2d4749060d991be4f6977c2"
|
||||
},
|
||||
"pdf-export": {
|
||||
@@ -125,7 +125,7 @@
|
||||
},
|
||||
"theme": "light",
|
||||
"language": "en",
|
||||
"sourceSha256": "81bd8a01a7ec4bbe2a4058b42025c7e153cc51d99a108a575750160578d4ec39",
|
||||
"sourceSha256": "4c472e043fa69a664ba9778200ff67b223e2f23b4eeb29c84688c14d93956de7",
|
||||
"imageSha256": "4537692fd57a3ed95528eddd748eee5cb6e456ffab7cc49169853d62459252cd"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -200,8 +200,14 @@ export const LOW_HEADROOM_WARNING_BYTES = 15_000;
|
||||
* that ceiling. A 299.1 kB ceiling restores the required >500 B noise margin
|
||||
* on both sides of the existing 2 kB ratchet band. The overall 301 066 B
|
||||
* budget is unchanged.
|
||||
*
|
||||
* 2026-09-09, #506: потолок перецентрирован 299 100 → 299 600. В initial View
|
||||
* вошёл `summary-runtime-loader.ts` — кеш фабрики кода сводной панели и слот
|
||||
* подключения на экземпляр (+299 Б gzip); сам runtime панели остаётся
|
||||
* ленивым чанком. Измеренный факт 298 891 Б оставляет 709 Б сверху и 1 291 Б
|
||||
* до нижней границы полосы; общий бюджет 301 066 Б и долг #367 не меняются.
|
||||
*/
|
||||
export const INITIAL_VIEW_GZIP_CEILING = 299_100;
|
||||
export const INITIAL_VIEW_GZIP_CEILING = 299_600;
|
||||
export const INITIAL_VIEW_CEILING_BAND = 2_000;
|
||||
|
||||
/**
|
||||
|
||||
@@ -8087,6 +8087,22 @@ const MUTANT_DEFINITIONS = [
|
||||
+ ' # The store is the durable authority (#335): a drop that\n',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'summary-runtime-attaches-after-first-render',
|
||||
guard: 'node demo/smoke_summary_warm_attach.mjs',
|
||||
because: 'a warm summary chunk must hand the new instance its runtime synchronously in '
|
||||
+ 'connectedCallback; deferring even a warm factory to a promise lets the first header '
|
||||
+ 'measurement miss the controls and a late refit follows (#506 AC4/AC5)',
|
||||
patches: [{
|
||||
file: 'src/summary-runtime-loader.ts',
|
||||
find: ' const warm = this.create(host);\n'
|
||||
+ ' if (warm) {\n'
|
||||
+ ' ready(warm);\n'
|
||||
+ ' return attachment;\n'
|
||||
+ ' }\n',
|
||||
replace: ' // mutant: the warm factory is deferred like a cold import\n',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'quota-counts-the-staged-upload-twice',
|
||||
guard: 'node scripts/backend-test-guard.mjs '
|
||||
|
||||
@@ -408,6 +408,7 @@ import {
|
||||
} from './space-order';
|
||||
import { applyOpeningMoves, mergeCollinearPartitions, spaceMergeGeometry } from './wall-merge';
|
||||
import type { MarkerRoomReferenceSnapshot } from './room-reference-transaction';
|
||||
import { SummaryRuntimeSlot, summaryRuntimeLoader } from './summary-runtime-loader';
|
||||
|
||||
const CARD_VERSION = '1.73.0';
|
||||
const ENTRY_BUILD_FINGERPRINT = '__HOUSEPLAN_SOURCE_FINGERPRINT__';
|
||||
@@ -2294,7 +2295,7 @@ export class HouseplanCard extends LitElement {
|
||||
private _renderProjection: 'flat' | 'iso' = 'flat';
|
||||
// ---- kiosk (wall device) mode ----
|
||||
private _kioskScale: { icon: number; font: number } = { icon: 1, font: 1 }; private _kioskDialog = false;
|
||||
private _summary?: import('./summary-panel-runtime-loaded').LoadedSummaryPanelRuntime;
|
||||
private _summary?: import('./summary-panel-runtime-loaded').LoadedSummaryPanelRuntime; private readonly _summarySlot = new SummaryRuntimeSlot(summaryRuntimeLoader, this, (runtime) => { this._summary = runtime; this._capturedSnapshotSequence = -1; /* summary entities (re)join the live subscription */ if (this.isConnected) { runtime.connect(); if (this.hasUpdated) this.requestUpdate(); } }); // #506: warm code attaches before the first render
|
||||
/**
|
||||
* Previous entity states + the short event/terminal-transition window for
|
||||
* every marker. The map lives outside Lit state: hass ticks update it, one
|
||||
@@ -2625,7 +2626,7 @@ export class HouseplanCard extends LitElement {
|
||||
this._showToast(this._t('toast.locale_load_failed'));
|
||||
}), subscribeFurnitureArtLoadFailures(() => this._showToast(this._t('toast.furniture_art_load_failed')))); // #474
|
||||
super.connectedCallback();
|
||||
if (this._summary) this._summary.connect(); else void import('./summary-panel-runtime-loaded').then(({ LoadedSummaryPanelRuntime }) => { this._summary ||= new LoadedSummaryPanelRuntime(this); this._capturedSnapshotSequence = -1; if (this.isConnected) this._summary.connect(); this.requestUpdate(); }).catch(() => undefined);
|
||||
this._summarySlot.connect();
|
||||
void this._ensureLiveRuntime().catch(() => this.requestUpdate());
|
||||
this._pointerModality.connect(this.ownerDocument.defaultView);
|
||||
const PointerHoverObserver = this.ownerDocument.defaultView?.MutationObserver;
|
||||
@@ -2719,7 +2720,7 @@ export class HouseplanCard extends LitElement {
|
||||
if (this._vacRaf) { cancelAnimationFrame(this._vacRaf); this._vacRaf = 0; }
|
||||
if (this._refitRaf) { cancelAnimationFrame(this._refitRaf); this._refitRaf = 0; }
|
||||
this._warmModeRequest = 0;
|
||||
if (this._dayCycleTimer) { clearInterval(this._dayCycleTimer); this._dayCycleTimer = 0; } this._summary?.disconnect();
|
||||
if (this._dayCycleTimer) { clearInterval(this._dayCycleTimer); this._dayCycleTimer = 0; } this._summarySlot.disconnect();
|
||||
this._dayCycleClockKey = '';
|
||||
if (this._bootSettleRaf) { cancelAnimationFrame(this._bootSettleRaf); this._bootSettleRaf = 0; }
|
||||
this._bootSettling = false;
|
||||
@@ -12205,7 +12206,6 @@ export class HouseplanCard extends LitElement {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HP-1540-01: an auto-discovered vacuum has NO config marker until the first
|
||||
* general Save of its dialog, yet the «Живая позиция» section is already
|
||||
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Page-level cache of the summary runtime *code*; state stays per host (#506).
|
||||
*
|
||||
* The summary panel is a lazy chunk. Before #506 every card instance — even a
|
||||
* warm remount on a page whose chunk had loaded long ago — attached its
|
||||
* runtime through `import().then()`, i.e. after Lit's first render. The first
|
||||
* header measurement therefore saw a header without summary controls; the
|
||||
* controls arrived a beat later, the stage shrank, and the deferred refit
|
||||
* opened a `stage-resize` continuity candidate with three more render passes
|
||||
* on top of the first HA tick.
|
||||
*
|
||||
* The loader keeps exactly one thing across instances: the factory that
|
||||
* builds a runtime for a host. Once it is warm, `create()` hands a fresh
|
||||
* runtime to a new host synchronously — inside `connectedCallback`, before
|
||||
* the first render — so the first frame already carries the full header.
|
||||
* Nothing else is shared: every host gets its own runtime with its own
|
||||
* preferences, drafts, subscriptions, timers and DOM.
|
||||
*
|
||||
* A pending import is shared by concurrent cold mounts (one network round
|
||||
* trip) but never its result-instance. A failed import is forgotten, so the
|
||||
* next `attach` may try again; there are no background retries.
|
||||
*/
|
||||
export type SummaryRuntimeFactory<Host, Runtime> = (host: Host) => Runtime;
|
||||
|
||||
export interface SummaryRuntimeAttachment {
|
||||
/** Forget this attempt: a later resolution must not touch the host. */
|
||||
cancel(): void;
|
||||
}
|
||||
|
||||
export class SummaryRuntimeLoader<Host, Runtime> {
|
||||
private factory: SummaryRuntimeFactory<Host, Runtime> | null = null;
|
||||
private pending: Promise<SummaryRuntimeFactory<Host, Runtime>> | null = null;
|
||||
|
||||
public constructor(private readonly load: () => Promise<SummaryRuntimeFactory<Host, Runtime>>) {}
|
||||
|
||||
/** The code is on the page: `create()` will succeed synchronously. */
|
||||
public get warm(): boolean {
|
||||
return this.factory !== null;
|
||||
}
|
||||
|
||||
/** A fresh runtime for `host`, or null while the code is still cold. */
|
||||
public create(host: Host): Runtime | null {
|
||||
return this.factory ? this.factory(host) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the runtime for `host` as soon as the code is available. When it is
|
||||
* warm, `ready` runs before this returns. Otherwise the shared import is
|
||||
* awaited and `ready` runs once — unless the attachment was cancelled
|
||||
* meanwhile (host disconnected, or a newer attach superseded this one).
|
||||
*/
|
||||
public attach(host: Host, ready: (runtime: Runtime) => void): SummaryRuntimeAttachment {
|
||||
let live = true;
|
||||
const attachment = { cancel: () => { live = false; } };
|
||||
const warm = this.create(host);
|
||||
if (warm) {
|
||||
ready(warm);
|
||||
return attachment;
|
||||
}
|
||||
void this.ensure().then((factory) => {
|
||||
if (live) ready(factory(host));
|
||||
}, () => undefined);
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/** Share one in-flight import; a rejection clears it so a retry is possible. */
|
||||
public ensure(): Promise<SummaryRuntimeFactory<Host, Runtime>> {
|
||||
if (this.factory) return Promise.resolve(this.factory);
|
||||
if (this.pending) return this.pending;
|
||||
this.pending = this.load().then((factory) => {
|
||||
this.factory = factory;
|
||||
this.pending = null;
|
||||
return factory;
|
||||
}, (error: unknown) => {
|
||||
this.pending = null;
|
||||
throw error;
|
||||
});
|
||||
return this.pending;
|
||||
}
|
||||
|
||||
/** Test seam: a page that wants to model a cold chunk again. */
|
||||
public reset(): void {
|
||||
this.factory = null;
|
||||
this.pending = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** What one host's slot needs from its runtime. */
|
||||
export interface SummaryRuntimeLike {
|
||||
connect(): void;
|
||||
disconnect(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* One host's summary runtime and the pending attachment of its current
|
||||
* connection. `connect()` follows the host's `connectedCallback`, `disconnect()`
|
||||
* its `disconnectedCallback`; the runtime instance survives a same-node
|
||||
* reconnect, a pending cold attach does not survive a disconnect.
|
||||
*/
|
||||
export class SummaryRuntimeSlot<Host, Runtime extends SummaryRuntimeLike> {
|
||||
public runtime: Runtime | undefined;
|
||||
private attachment: SummaryRuntimeAttachment | null = null;
|
||||
|
||||
public constructor(
|
||||
private readonly loader: SummaryRuntimeLoader<Host, Runtime>,
|
||||
private readonly host: Host,
|
||||
/** Runs once per instance, right after adoption; connects when the host is in the tree. */
|
||||
private readonly adopted: (runtime: Runtime) => void,
|
||||
) {}
|
||||
|
||||
public connect(): void {
|
||||
if (this.runtime) { this.runtime.connect(); return; }
|
||||
this.attachment?.cancel();
|
||||
const attachment = this.loader.attach(this.host, (runtime) => this.adopt(runtime));
|
||||
// Warm code has already run `adopt`; only a cold attach stays pending.
|
||||
if (!this.runtime) this.attachment = attachment;
|
||||
}
|
||||
|
||||
public disconnect(): void {
|
||||
this.attachment?.cancel();
|
||||
this.attachment = null;
|
||||
this.runtime?.disconnect();
|
||||
}
|
||||
|
||||
private adopt(runtime: Runtime): void {
|
||||
this.attachment = null;
|
||||
if (this.runtime) return;
|
||||
this.runtime = runtime;
|
||||
this.adopted(runtime);
|
||||
}
|
||||
}
|
||||
|
||||
type LoadedSummaryPanelRuntime = import('./summary-panel-runtime-loaded').LoadedSummaryPanelRuntime;
|
||||
|
||||
/**
|
||||
* The page's one summary code cache. The chunk stays lazy: the first cold
|
||||
* mount pays the import; every later instance builds its runtime synchronously.
|
||||
*/
|
||||
export const summaryRuntimeLoader = new SummaryRuntimeLoader<unknown, LoadedSummaryPanelRuntime>(
|
||||
() => import('./summary-panel-runtime-loaded').then(
|
||||
({ LoadedSummaryPanelRuntime }) => (host) => new LoadedSummaryPanelRuntime(host),
|
||||
),
|
||||
);
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
// #506: the summary chunk's code is cached per page, its runtime is per host.
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { SummaryRuntimeLoader } from '../test-build/summary-runtime-loader.js';
|
||||
|
||||
const deferred = () => {
|
||||
let resolve;
|
||||
let reject;
|
||||
const promise = new Promise((ok, fail) => { resolve = ok; reject = fail; });
|
||||
return { promise, resolve, reject };
|
||||
};
|
||||
|
||||
const tick = () => new Promise((done) => setTimeout(done, 0));
|
||||
|
||||
class Runtime {
|
||||
constructor(host) { this.host = host; this.connected = 0; }
|
||||
}
|
||||
|
||||
test('#506 AC1: a warm factory builds a distinct runtime for every host, synchronously', async () => {
|
||||
let loads = 0;
|
||||
const loader = new SummaryRuntimeLoader(async () => { loads++; return (host) => new Runtime(host); });
|
||||
assert.equal(loader.warm, false);
|
||||
assert.equal(loader.create({ id: 'cold' }), null, 'cold code cannot be created synchronously');
|
||||
|
||||
await loader.ensure();
|
||||
assert.equal(loader.warm, true);
|
||||
const hostA = { id: 'a' };
|
||||
const hostB = { id: 'b' };
|
||||
const readyA = [];
|
||||
const readyB = [];
|
||||
loader.attach(hostA, (runtime) => readyA.push(runtime));
|
||||
loader.attach(hostB, (runtime) => readyB.push(runtime));
|
||||
assert.equal(readyA.length, 1, 'warm attach runs ready before returning');
|
||||
assert.equal(readyB.length, 1);
|
||||
assert.notEqual(readyA[0], readyB[0], 'no runtime instance is shared between hosts');
|
||||
assert.equal(readyA[0].host, hostA);
|
||||
assert.equal(readyB[0].host, hostB);
|
||||
assert.equal(loads, 1, 'the code was loaded once for the page');
|
||||
});
|
||||
|
||||
test('#506 AC2: concurrent cold mounts share one import but not one instance', async () => {
|
||||
const pending = deferred();
|
||||
let loads = 0;
|
||||
const loader = new SummaryRuntimeLoader(() => { loads++; return pending.promise; });
|
||||
const seen = [];
|
||||
loader.attach({ id: 'a' }, (runtime) => seen.push(runtime));
|
||||
loader.attach({ id: 'b' }, (runtime) => seen.push(runtime));
|
||||
assert.equal(loads, 1);
|
||||
assert.equal(seen.length, 0, 'nothing is attached before the import lands');
|
||||
pending.resolve((host) => new Runtime(host));
|
||||
await tick();
|
||||
assert.equal(seen.length, 2);
|
||||
assert.notEqual(seen[0], seen[1]);
|
||||
assert.deepEqual(seen.map((runtime) => runtime.host.id), ['a', 'b']);
|
||||
assert.equal(loader.warm, true);
|
||||
});
|
||||
|
||||
test('#506 AC2: a cancelled attachment never reaches its host; a reconnect attaches once', async () => {
|
||||
const pending = deferred();
|
||||
const loader = new SummaryRuntimeLoader(() => pending.promise);
|
||||
const host = { id: 'reconnecting' };
|
||||
const stale = [];
|
||||
const fresh = [];
|
||||
const first = loader.attach(host, (runtime) => stale.push(runtime));
|
||||
first.cancel(); // disconnected while the chunk was still loading
|
||||
const second = loader.attach(host, (runtime) => fresh.push(runtime));
|
||||
pending.resolve((h) => new Runtime(h));
|
||||
await tick();
|
||||
assert.deepEqual(stale, [], 'the cancelled attempt must not run its side effects');
|
||||
assert.equal(fresh.length, 1, 'the live attempt attaches exactly once');
|
||||
assert.equal(fresh[0].host, host);
|
||||
second.cancel(); // cancelling a completed attachment is a no-op
|
||||
assert.equal(fresh.length, 1);
|
||||
});
|
||||
|
||||
test('#506 AC2: a failed import is forgotten so the next attach may retry', async () => {
|
||||
const attempts = [];
|
||||
const loader = new SummaryRuntimeLoader(() => {
|
||||
const attempt = deferred();
|
||||
attempts.push(attempt);
|
||||
return attempt.promise;
|
||||
});
|
||||
const seen = [];
|
||||
loader.attach({ id: 'first' }, (runtime) => seen.push(runtime));
|
||||
attempts[0].reject(new Error('network'));
|
||||
await tick();
|
||||
assert.equal(seen.length, 0);
|
||||
assert.equal(loader.warm, false, 'a failure is not cached as the page state');
|
||||
|
||||
loader.attach({ id: 'second' }, (runtime) => seen.push(runtime));
|
||||
assert.equal(attempts.length, 2, 'the next attach starts a fresh import');
|
||||
attempts[1].resolve((host) => new Runtime(host));
|
||||
await tick();
|
||||
assert.equal(seen.length, 1);
|
||||
assert.equal(seen[0].host.id, 'second');
|
||||
assert.equal(loader.warm, true);
|
||||
});
|
||||
|
||||
test('#506: ensure() rejects to its caller and a reset returns the page to cold', async () => {
|
||||
let fail = true;
|
||||
const loader = new SummaryRuntimeLoader(async () => {
|
||||
if (fail) throw new Error('chunk missing');
|
||||
return (host) => new Runtime(host);
|
||||
});
|
||||
await assert.rejects(loader.ensure(), /chunk missing/);
|
||||
fail = false;
|
||||
await loader.ensure();
|
||||
assert.equal(loader.warm, true);
|
||||
loader.reset();
|
||||
assert.equal(loader.warm, false);
|
||||
assert.equal(loader.create({}), null);
|
||||
});
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"include": [
|
||||
"src/color.ts", "src/styles.ts", "src/styles/*.styles.ts", "src/logic.ts", "src/i18n.ts", "src/i18n/registry.ts", "src/i18n/language-runtime.ts", "src/glow-blend.ts", "src/grid-scale.ts", "src/device-visual.ts", "src/device-pulse.ts", "src/device-presentation.ts", "src/device-marker-geometry.ts",
|
||||
"src/device-face.ts", "src/device-toggle.ts", "src/marker-toggle-entity.ts", "src/activity-runtime.ts", "src/device-area-relocation.ts",
|
||||
"src/device-face.ts", "src/device-toggle.ts", "src/marker-toggle-entity.ts", "src/activity-runtime.ts", "src/summary-runtime-loader.ts", "src/device-area-relocation.ts",
|
||||
"src/ha-binding-status.ts",
|
||||
"src/zigbee-topology-settings.ts", "src/zigbee-topology.ts", "src/zigbee-topology-geometry.ts", "src/zigbee-topology-runtime.ts",
|
||||
"src/radar-model.ts", "src/radar-editor.ts", "src/radar-geometry.ts", "src/radar-setup.ts", "src/radar-render.ts",
|
||||
|
||||
Reference in New Issue
Block a user