fix: ограничить дневной контур размером экрана (#582)

Issue: #582
User-Visible: yes
This commit is contained in:
Sergey Matyunin
2026-09-15 12:17:27 +03:00
parent 292618cad0
commit a68e4c6b80
62 changed files with 3040 additions and 2642 deletions
@@ -1,295 +1,295 @@
{
"schema": 1,
"fingerprint": "241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef",
"fingerprint": "3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502",
"entry": "houseplan-card.js",
"panelEntry": "houseplan-panel.js",
"initialViewFiles": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-card.js"
],
"initialViewGzipBytes": 290805,
"initialViewGzipBytes": 290977,
"initialPanelFiles": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-panel.js"
],
"initialPanelGzipBytes": 292327,
"initialPanelGzipBytes": 292500,
"initialPanelOnlyFiles": [
"houseplan-panel.js"
],
"initialPanelOnlyGzipBytes": 2326,
"initialPanelOnlyGzipBytes": 2325,
"lazyFiles": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/de-BrzcYO-1.js",
"houseplan-assets/editor-Cfrg3iMq.js",
"houseplan-assets/fr-CLHfUBDP.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js",
"houseplan-assets/hp-zigbee-topology-overlay-jvjkBbI9.js",
"houseplan-assets/iso-scene-render-D2f0EUgN.js",
"houseplan-assets/live-interaction-runtime-BA69oN1Z.js",
"houseplan-assets/pdf-export-DeQrvN1z.js",
"houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js",
"houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/de-OKLqCJOe.js",
"houseplan-assets/editor-Bi3cJ768.js",
"houseplan-assets/fr-BjvleGPe.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js",
"houseplan-assets/hp-zigbee-topology-overlay-Bt3_AzlX.js",
"houseplan-assets/iso-scene-render-RpNlnxJ0.js",
"houseplan-assets/live-interaction-runtime-C8mBGPZT.js",
"houseplan-assets/pdf-export-CfU6W3j-.js",
"houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js",
"houseplan-assets/zigbee-topology-runtime-DvLAh834.js"
],
"lazyGzipBytes": 418772,
"lazyGzipBytes": 418768,
"lazyEditorFiles": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/editor-Cfrg3iMq.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/editor-Bi3cJ768.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js"
],
"lazyEditorGzipBytes": 204963,
"lazyEditorGzipBytes": 204957,
"lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js"
],
"lazyOnboardingGzipBytes": 13916,
"lazyOnboardingGzipBytes": 13913,
"lazyLocaleFiles": [
"houseplan-assets/de-BrzcYO-1.js",
"houseplan-assets/fr-CLHfUBDP.js"
"houseplan-assets/de-OKLqCJOe.js",
"houseplan-assets/fr-BjvleGPe.js"
],
"lazyLocaleGzipBytes": 54921,
"lazyLocaleGzipBytes": 54928,
"lazyIsometricFiles": [
"houseplan-assets/iso-scene-render-D2f0EUgN.js"
"houseplan-assets/iso-scene-render-RpNlnxJ0.js"
],
"lazyIsometricGzipBytes": 13234,
"lazyIsometricGzipBytes": 13233,
"lazyFurnitureArtFiles": [
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js"
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js"
],
"lazyFurnitureArtGzipBytes": 10255,
"lazyFurnitureArtGzipBytes": 10253,
"lazyPdfFiles": [
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/pdf-export-DeQrvN1z.js"
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/pdf-export-CfU6W3j-.js"
],
"lazyPdfGzipBytes": 120128,
"lazyPdfGzipBytes": 120126,
"files": [
{
"path": "houseplan-assets/backdrop-pick-ClLjW_UW.js",
"sha256": "5c8e9728df6ebdaad6346a26686f058ba4cce8bebd68c01d6cf18423ac67b792",
"path": "houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"sha256": "75bbf10c2e346eb00aff21123bdfc9c753efcb5a81fdb1de8735232110ad3b4b",
"rawBytes": 19956,
"gzipBytes": 6880,
"gzipBytes": 6879,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/de-BrzcYO-1.js",
"sha256": "b7488c7f186f740f02cdfde3c093aed8754e91157c0903d196a36fee4fbfef60",
"path": "houseplan-assets/de-OKLqCJOe.js",
"sha256": "c2374e47db6377fdebc46f33e501bca8c75c83a34040dc32cbdfd0d77aa970f5",
"rawBytes": 91590,
"gzipBytes": 27743,
"gzipBytes": 27746,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/editor-Cfrg3iMq.js",
"sha256": "83f9d762289e0f83a6e78730d3eb54862dbfa78408c93d410126f15988ca758c",
"path": "houseplan-assets/editor-Bi3cJ768.js",
"sha256": "856625d7c4609d8461a0a1f864c12cfe7929003add4d900affc09293d2a55ca3",
"rawBytes": 3831,
"gzipBytes": 1584,
"gzipBytes": 1582,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/fr-CLHfUBDP.js",
"sha256": "3524222b350ecbe2187351bf1730cc1d6393497104b10478cc3b7b0e5f14a9ec",
"path": "houseplan-assets/fr-BjvleGPe.js",
"sha256": "ab49a526636631678544da34495d55aa2ca181a9e89e3df4933cd4100aecdf59",
"rawBytes": 93884,
"gzipBytes": 27178,
"gzipBytes": 27182,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"sha256": "8303521f70c98617ece5cea54517760fdb808bec3fc7b68add0434ea56980dd3",
"path": "houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"sha256": "c7f2275e7fe40520b80e2bf8cf1f41677382ccfdbf49c069cf8d794c866bc44a",
"rawBytes": 33655,
"gzipBytes": 10255,
"gzipBytes": 10253,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-card-BvxqYw8A.js",
"sha256": "da77e0c3d6445d114ff496613fc8aebfb7e7ed132bdfbc5c2bc8c5a79fd8afc2",
"rawBytes": 1032746,
"gzipBytes": 290001,
"path": "houseplan-assets/houseplan-card-Cythr3Rg.js",
"sha256": "87cc46dbb29e86af1732f00d74fecf5050295c7812b429b247ecac649abdd67a",
"rawBytes": 1033369,
"gzipBytes": 290175,
"isEntry": false,
"imports": [],
"dynamicImports": [
"houseplan-assets/de-BrzcYO-1.js",
"houseplan-assets/editor-Cfrg3iMq.js",
"houseplan-assets/fr-CLHfUBDP.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js",
"houseplan-assets/hp-zigbee-topology-overlay-jvjkBbI9.js",
"houseplan-assets/iso-scene-render-D2f0EUgN.js",
"houseplan-assets/live-interaction-runtime-BA69oN1Z.js",
"houseplan-assets/pdf-export-DeQrvN1z.js",
"houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js"
"houseplan-assets/de-OKLqCJOe.js",
"houseplan-assets/editor-Bi3cJ768.js",
"houseplan-assets/fr-BjvleGPe.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js",
"houseplan-assets/hp-zigbee-topology-overlay-Bt3_AzlX.js",
"houseplan-assets/iso-scene-render-RpNlnxJ0.js",
"houseplan-assets/live-interaction-runtime-C8mBGPZT.js",
"houseplan-assets/pdf-export-CfU6W3j-.js",
"houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js"
]
},
{
"path": "houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"sha256": "0d095de08b11966dd3cb784099bba2f92d8c294f0817a49f3e3d4813ca9baa0b",
"path": "houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"sha256": "440f16ed41a7b01b15fc253209be5cb6242f4c48dec1646b07bf5e7304d3f3c4",
"rawBytes": 670150,
"gzipBytes": 178818,
"gzipBytes": 178815,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js"
],
"dynamicImports": [
"houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js"
"houseplan-assets/zigbee-topology-runtime-DvLAh834.js"
]
},
{
"path": "houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js",
"sha256": "66ec3c0650ce721de901ec5d8d175c3b76e4878da909dada0d92589b3c8da4b5",
"path": "houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js",
"sha256": "ca88d8512e071d73ced67a1eccbd13a9c63ff776589d963db173d1b6ca8aded5",
"rawBytes": 28287,
"gzipBytes": 7036,
"gzipBytes": 7034,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/hp-zigbee-topology-overlay-jvjkBbI9.js",
"sha256": "d4b6c957d4a82b979f7a71832e583fbd93852f7f8c340ce7a32fb8f773a59bc5",
"path": "houseplan-assets/hp-zigbee-topology-overlay-Bt3_AzlX.js",
"sha256": "14a73aa0d44c2d5c0ad2198dc25a2180515d6920898f3d34643f2bafe06d8158",
"rawBytes": 10756,
"gzipBytes": 3685,
"gzipBytes": 3686,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js",
"houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js",
"houseplan-assets/zigbee-topology-runtime-DvLAh834.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/iso-scene-render-D2f0EUgN.js",
"sha256": "92b77a114af62667adceacab9ecb76b631afb2ac83d9e255af206678f79cac47",
"path": "houseplan-assets/iso-scene-render-RpNlnxJ0.js",
"sha256": "95c96d30a226573c9131a94334aef2ca12a5f58a8f6ce5ff258cf0ec47fbee23",
"rawBytes": 39206,
"gzipBytes": 13234,
"gzipBytes": 13233,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/live-interaction-runtime-BA69oN1Z.js",
"sha256": "1e3130110cdb4af9dfe938444d9b8a88ef4f6c30502841f5785231894e1ed7a6",
"path": "houseplan-assets/live-interaction-runtime-C8mBGPZT.js",
"sha256": "6df6de94c668490716339ae897412d6e794d0f753584ae3d34f98f43349bc7d8",
"rawBytes": 8216,
"gzipBytes": 3207,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/pdf-export-DeQrvN1z.js",
"sha256": "11a305cbbb3772c55968cbcb502c1878e4e74522c5179e1ee281e80fb85d6f93",
"path": "houseplan-assets/pdf-export-CfU6W3j-.js",
"sha256": "28eb5327001bebfddbdf01086a7a851bbc7c04e4b7030e3b413b8dfb0a73eb3e",
"rawBytes": 236244,
"gzipBytes": 109873,
"isEntry": false,
"imports": [
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-editor-o2bn2wLY.js",
"sha256": "c253cfec20c5cef0a472b4dd42caca4276d147e48ea795f9d1b562c4a39da46e",
"path": "houseplan-assets/summary-panel-editor-CTfI9Enr.js",
"sha256": "559732b375119e7169332d1a93f7778382eb3f97a9bb0150eb2fe600448f1286",
"rawBytes": 14824,
"gzipBytes": 3401,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-metrics-CzgAvzH6.js",
"sha256": "51530c69ada90dc42a92f5e297366734969c1a91c58ae30b9ecd528978a5441e",
"path": "houseplan-assets/summary-panel-metrics-XatK0mU4.js",
"sha256": "d627d8bb01b003f47f9fbb0594c2526a8d8676d491595612239d2c8ee0e5bffe",
"rawBytes": 2610,
"gzipBytes": 1305,
"gzipBytes": 1306,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js",
"sha256": "fa463fbec81b0635b56be87906d24442eba48ed1047445e192b5eb3ec519b7c1",
"path": "houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js",
"sha256": "545cb01893ff659bcbe0fb14cd32c5656481f317a90053b25e1ff1cff2773096",
"rawBytes": 73366,
"gzipBytes": 20089,
"gzipBytes": 20087,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": [
"houseplan-assets/summary-panel-editor-o2bn2wLY.js",
"houseplan-assets/summary-panel-metrics-CzgAvzH6.js"
"houseplan-assets/summary-panel-editor-CTfI9Enr.js",
"houseplan-assets/summary-panel-metrics-XatK0mU4.js"
]
},
{
"path": "houseplan-assets/zigbee-topology-B8St6NV9.js",
"sha256": "d35d5ebeedb562a4c29709da95964080f053e4e1eb0d3f2fb7eb957b71444e9c",
"path": "houseplan-assets/zigbee-topology-CWUjtXoY.js",
"sha256": "89766dbc5817dc1889e7c30a8ad36817d2c675760c9cb82f9de2adacafb9c06c",
"rawBytes": 18961,
"gzipBytes": 7426,
"gzipBytes": 7428,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js",
"sha256": "a7774967077014e62b395dacb43dc7eb10022b03b6ac24a358ce53eee4469786",
"path": "houseplan-assets/zigbee-topology-runtime-DvLAh834.js",
"sha256": "f3a64d38e8eb5ab5983340354db8dce98db8c7b11c903699cd7cbee7a8ff3f66",
"rawBytes": 3941,
"gzipBytes": 1764,
"gzipBytes": 1763,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js"
],
"dynamicImports": []
},
{
"path": "houseplan-card.js",
"sha256": "79b31c6683afff9ca22fb99a7a855f81957a199352f0f212807444b2998ee7d1",
"sha256": "42e5ccc368c0b72a931ec124f88711c5551e3a202dbf525cb96348f0c6aec03e",
"rawBytes": 1205,
"gzipBytes": 804,
"gzipBytes": 802,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-panel.js",
"sha256": "4240e1335652c727ecf9a8868b515945f8c97b50cff332708ac302b9c0ccf6b4",
"sha256": "7e2756dab8b6fecee15843885756abc8a2bed9e49caa10fee0c393a4cd10ee1b",
"rawBytes": 6165,
"gzipBytes": 2326,
"gzipBytes": 2325,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
}
@@ -1,14 +1,14 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{q as e,l as o,v as t,e4 as s,A as a,e5 as i,e6 as l,e7 as n,E as r,c}from"./houseplan-card-BvxqYw8A.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__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{q as e,l as o,v as t,e4 as s,A as a,e5 as i,e6 as l,e7 as n,E as r,c}from"./houseplan-card-Cythr3Rg.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
.hass=${this.hass}
.data=${this._formData}
.schema=${e}
.computeLabel=${e=>h[e.name]||e.name}
.computeLabel=${e=>f[e.name]||e.name}
@value-changed=${this._valueChanged}
></ha-form>`;return c`
${d(f.slice(0,3))}
${d(h.slice(0,3))}
${_?c`<div class="default-floor-error" role="alert"
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
${t(s,"editor.default_floor_missing",{id:_})}
</div>`:a}
${d(f.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
${d(h.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{c as a,A as e}from"./houseplan-card-BvxqYw8A.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-B6w0YS6P.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__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{c as a,A as e}from"./houseplan-card-Cythr3Rg.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-BbGQ8VLD.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 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{ea as e,P as t,a5 as n,M as i,aq as r,N as o,bs as s,br as a,a4 as c,a3 as l,aA as u,eb as d,ec as f,bu as m,ed as g}from"./houseplan-card-BvxqYw8A.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=u(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const r=String(i.binding||"").indexOf(":");if(r<1)continue;const o=i.binding.slice(0,r),s=i.binding.slice(r+1),a="device"===o?e.registry.devices?.[s]:null,c="entity"===o?e.registry.entities?.[s]:null,l="device"===o?s:c?.device_id,u="device"===o?a?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,d="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||u||"",f=d&&e.areaToSpace[d]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===o&&n.liveEntities.has(s))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,r,o);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,r,o)}}function*b(c,l,u=_){try{let d=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=u(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,r,o,g.roomGeom,g.multiWallNodes)||a;v=y(v,s(c,m.physicalBodies)),yield}const _=m.cellCm/r;d+=a(v)*_*_/1e4}return d}catch{return null}}function h(e,t,n=_){const i=b(e,t,n);let r=i.next();for(;!r.done;)r=i.next();return r.value}function p(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=d(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{b as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,p as summarySystemValue,h as totalCleanFloorAreaM2};
@@ -0,0 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{ea as e,P as t,a5 as n,M as i,aq as r,N as o,bs as a,br as s,a4 as l,a3 as c,aA as d,eb as u,ec as f,bu as m,ed as g}from"./houseplan-card-Cythr3Rg.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const r=String(i.binding||"").indexOf(":");if(r<1)continue;const o=i.binding.slice(0,r),a=i.binding.slice(r+1),s="device"===o?e.registry.devices?.[a]:null,l="entity"===o?e.registry.entities?.[a]:null,c="device"===o?a:l?.device_id,d="device"===o?s?.area_id:l?.area_id||c&&e.registry.devices?.[c]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;c&&e.registry.devices?.[c]&&e.spaceIds.has(f)&&(!n.devices.has(c)||"entity"===o&&n.liveEntities.has(a))&&t.add(c)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=l(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,r,o);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:c(e.rooms,t.walls,t.openCuts,i,t.cellCm,r,o)}}function*h(l,c,d=_){try{let u=0;for(const f of c){const c=l.spaces.find(e=>String(e?.id)===f.id);if(!c)continue;const m=e(c,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const l=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,r,o,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(l,m.physicalBodies)),yield}const _=m.cellCm/r;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let r=i.next();for(;!r.done;)r=i.next();return r.value}function S(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function b(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,b as summaryEntityValue,S as summarySystemValue,p as totalCleanFloorAreaM2};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{n as t,b as n}from"./zigbee-topology-B8St6NV9.js";import{F as e}from"./houseplan-card-BvxqYw8A.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{n as t,b as n}from"./zigbee-topology-CWUjtXoY.js";import{F as e}from"./houseplan-card-Cythr3Rg.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";try{await import("./houseplan-assets/houseplan-card-BvxqYw8A.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__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";try{await import("./houseplan-assets/houseplan-card-Cythr3Rg.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
+2 -1
View File
@@ -174,7 +174,8 @@ const res = await page.evaluate(async () => {
out.staticCardSharesDawn = st?.classList.contains('phase-dawn')
&& st.querySelector('.hp-day-cycle-env')?.dataset.dayCycleSource === 'sun'
&& st.querySelector('.hp-day-cycle-bg.active')?.dataset.dayCycleLayer === 'dawn';
out.staticCardLayersStayOrdered = getComputedStyle(st.querySelector('svg')).zIndex === '1'
out.staticCardLayersStayOrdered = getComputedStyle(st.querySelector('.hp-paper-outline-svg')).zIndex === '0'
&& getComputedStyle(st.querySelector('.hp-static-plan-svg')).zIndex === '1'
&& getComputedStyle(st.querySelector('.devlayer')).zIndex === '2';
// ...and the space override beats the global there too
cfg.spaces.find((s) => s.id === c._space).settings = { bg_color: '#654321' };
+236
View File
@@ -0,0 +1,236 @@
// #582: a day-cycle outline on a physically ordinary plan stored at
// 1 cm/grid-point must allocate in screen pixels, not in the 4700×4200 local
// SVG coordinate range. HA Companion loses fixed tiles when Chromium creates
// that oversized filter/overlap graph during pinch.
import { launch, checkAll, finish } from './serve.mjs';
const { page, browser } = await launch(
{ width: 820, height: 760 }, 1, [], { hasTouch: true },
);
const cdp = await page.context().newCDPSession(page);
let latestLayers = [];
cdp.on('LayerTree.layerTreeDidChange', ({ layers }) => { latestLayers = layers; });
await cdp.send('LayerTree.enable');
const presentedFrames = [];
cdp.on('Page.screencastFrame', (event) => {
if (presentedFrames.length < 90) presentedFrames.push(event.data);
void cdp.send('Page.screencastFrameAck', { sessionId: event.sessionId });
});
const settle = () => page.evaluate(async () => {
const card = window.__card;
await card.updateComplete;
await new Promise((done) => requestAnimationFrame(() => requestAnimationFrame(done)));
});
await page.evaluate(async () => {
const card = window.__card;
const large = {
id: 'hp582-large-daycycle',
title: 'Synthetic large-coordinate floor',
plan_url: null,
view_box: [0, 0, 5, 4.5],
cell_cm: 1,
settings: { show_borders: true, fill_mode: 'custom', custom_fill: '#435468' },
rooms: [{
id: 'hp582-room', name: 'Large room', area: null,
poly: [[0.1, 0.1], [4.7, 0.1], [4.7, 4.2], [0.1, 4.2]],
}],
wall_segments: [], walls: [], partitions: [], wall_columns: [], openings: [], decor: [],
};
card._serverCfg = {
...card._serverCfg,
settings: { ...(card._serverCfg.settings || {}), bg_mode: 'daynight', glow_enabled: false },
spaces: [large],
};
card._space = large.id;
card._view = null;
card._zoom = 1;
card._cfgRev = (card._cfgRev || 0) + 1;
card.hass = { ...card.hass, states: { ...card.hass.states, 'sun.sun': {
entity_id: 'sun.sun', state: 'above_horizon',
attributes: { azimuth: 180, elevation: 40, rising: false },
} } };
card.requestUpdate();
await card.updateComplete;
});
await settle();
await cdp.send('Page.startScreencast', {
format: 'png', everyNthFrame: 1, maxWidth: 820, maxHeight: 760,
});
await page.waitForTimeout(80);
const layerSnapshot = async () => {
await page.waitForTimeout(80);
const stage = await page.evaluate(() => {
const root = window.__card.renderRoot;
const rect = root.querySelector('.stage').getBoundingClientRect();
const outline = root.querySelector('.hp-paper-outline-svg');
const paper = root.querySelector('.plan-svg .hp-paperg');
return {
width: rect.width,
height: rect.height,
outline: outline ? {
viewBox: outline.getAttribute('viewBox'),
filter: getComputedStyle(outline).filter,
willChange: getComputedStyle(outline).willChange,
pointerEvents: getComputedStyle(outline).pointerEvents,
} : null,
paper: paper ? {
bbox: (() => { const box = paper.getBBox(); return [box.width, box.height]; })(),
filter: getComputedStyle(paper).filter,
willChange: getComputedStyle(paper).willChange,
} : null,
};
});
const content = latestLayers.filter((layer) => layer.drawsContent);
const described = [];
for (const layer of content) {
let className = '';
if (layer.backendNodeId) {
try {
const { node } = await cdp.send('DOM.describeNode', { backendNodeId: layer.backendNodeId });
const attrs = node.attributes || [];
const classIndex = attrs.indexOf('class');
className = classIndex >= 0 ? attrs[classIndex + 1] : '';
} catch { /* detached between LayerTree event and inspection */ }
}
let reasons = [];
try {
({ compositingReasons: reasons } = await cdp.send('LayerTree.compositingReasons', {
layerId: layer.layerId,
}));
} catch { /* root/retired layers may have no reason record */ }
described.push({
className, width: layer.width, height: layer.height,
pixels: layer.width * layer.height, reasons,
});
}
return { stage, layers: described };
};
await page.evaluate(() => {
const stage = window.__card.renderRoot.querySelector('.stage');
const rect = stage.getBoundingClientRect();
const y = rect.top + rect.height / 2;
const cx = rect.left + rect.width / 2;
stage.setPointerCapture = () => {};
stage.releasePointerCapture = () => {};
window.__hp582Touch = (type, pointerId, x, buttons = 1) => stage.dispatchEvent(new PointerEvent(type, {
bubbles: true, composed: true, pointerId, pointerType: 'touch',
isPrimary: pointerId === 5821, button: type === 'pointerdown' ? 0 : -1,
buttons, clientX: x, clientY: y,
}));
window.__hp582Pinch = { cx };
window.__hp582Touch('pointerdown', 5821, cx - 70);
window.__hp582Touch('pointerdown', 5822, cx + 70);
});
for (const distance of [78, 92, 66, 104, 72, 98]) {
await page.evaluate((distance) => {
const { cx } = window.__hp582Pinch;
window.__hp582Touch('pointermove', 5821, cx - distance);
window.__hp582Touch('pointermove', 5822, cx + distance);
}, distance);
await page.evaluate(() => new Promise(requestAnimationFrame));
await page.waitForTimeout(25);
}
const active = await layerSnapshot();
await page.evaluate(() => {
const { cx } = window.__hp582Pinch;
window.__hp582Touch('pointerup', 5821, cx - 98, 0);
window.__hp582Touch('pointerup', 5822, cx + 98, 0);
delete window.__hp582Touch;
delete window.__hp582Pinch;
});
await settle();
await page.waitForTimeout(100);
await cdp.send('Page.stopScreencast');
const settled = await layerSnapshot();
const frameMetrics = await page.evaluate(async ({ encoded, stage }) => {
const decode = (data) => new Promise((resolve, reject) => {
const image = new Image();
image.onload = () => resolve(image);
image.onerror = reject;
image.src = `data:image/png;base64,${data}`;
});
const out = [];
for (const data of encoded) {
const image = await decode(data);
const scaleX = image.width / innerWidth;
const scaleY = image.height / innerHeight;
const sx = Math.floor(stage.x * scaleX);
const sy = Math.floor(stage.y * scaleY);
const sw = Math.max(1, Math.floor(stage.width * scaleX));
const sh = Math.max(1, Math.floor(stage.height * scaleY));
const canvas = document.createElement('canvas');
canvas.width = sw;
canvas.height = sh;
const context = canvas.getContext('2d', { willReadFrequently: true });
context.drawImage(image, sx, sy, sw, sh, 0, 0, sw, sh);
const pixels = context.getImageData(0, 0, sw, sh).data;
let sampled = 0;
let nearWhite = 0;
for (let y = Math.floor(sh * 0.25); y < sh * 0.75; y += 3) {
for (let x = Math.floor(sw * 0.25); x < sw * 0.75; x += 3) {
const offset = (y * sw + x) * 4;
sampled++;
if (pixels[offset] >= 245 && pixels[offset + 1] >= 245 && pixels[offset + 2] >= 245) {
nearWhite++;
}
}
}
out.push({ nearWhiteRatio: nearWhite / Math.max(1, sampled) });
}
return out;
}, {
encoded: presentedFrames,
stage: await page.evaluate(() => {
const rect = window.__card.renderRoot.querySelector('.stage').getBoundingClientRect();
return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
}),
});
const checks = {};
const outlineLayer = active.layers.find((layer) => layer.className.includes('hp-paper-outline-svg'));
const oversized = active.layers.filter((layer) => layer.width > 4096 || layer.height > 4096);
const activePixels = active.layers.reduce((sum, layer) => sum + layer.pixels, 0);
const screenPixels = active.stage.width * active.stage.height;
checks.largeCoordinateFixture = active.stage.paper?.bbox?.[0] > 4096
&& active.stage.paper?.bbox?.[1] > 4000;
checks.separateFilteredOutline = !!active.stage.outline
&& /drop-shadow/.test(active.stage.outline.filter)
&& active.stage.outline.pointerEvents === 'none';
checks.visiblePaperUnfiltered = active.stage.paper?.filter === 'none'
&& !/filter/.test(active.stage.paper?.willChange || '');
checks.outlineLayerIsStageBounded = !!outlineLayer
&& outlineLayer.width <= active.stage.width * 1.5 + 64
&& outlineLayer.height <= active.stage.height * 1.5 + 64;
checks.no4096ContentLayer = oversized.length === 0;
// Browser chrome/root layers add a small constant. The broken graph measured
// 78.7M px against a ~0.6M px stage; the fixed graph must stay screen-order.
checks.totalContentLayerAreaIsScreenOrder = activePixels <= screenPixels * 16;
checks.terminalFrameKeepsBudget = settled.layers.every(
(layer) => layer.width <= 4096 && layer.height <= 4096,
);
checks.capturedPresentedPinchFrames = frameMetrics.length >= 3;
checks.presentedFramesHaveNoWhiteTile = frameMetrics.every(
(frame) => frame.nearWhiteRatio < 0.01,
);
console.log(JSON.stringify({
stage: active.stage,
activePixels,
screenPixels,
ratio: Number((activePixels / screenPixels).toFixed(2)),
oversized,
activeLayers: active.layers,
settledLayers: settled.layers,
presentedFrameMetrics: frameMetrics,
}, null, 2));
checkAll(checks);
await cdp.send('LayerTree.disable');
await finish(browser, checks);
+16 -10
View File
@@ -3,11 +3,9 @@
// Владелец: «в Firefox план тормозит; со статичным цветом фона тормоза
// пропадают». Профиль подтвердил: наш JS спал 89 % времени, а в GPU-процессе
// на кадр уезжало 23 МБ текстур. Виновником оказалась не сцена плана, а
// тройной drop-shadow внешнего контура: группа .hp-paperg несёт одни бумажные
// силуэты и при ховере и панораме не меняется, но фильтр жил в общем слое
// плана — и каждая перерисовка плана заново прогоняла три прохода размытия по
// габариту всего листа. Лечится одной подсказкой will-change: filter, которая
// уводит отфильтрованную бумагу в свой композиционный слой.
// тройной drop-shadow внешнего контура. После #582 alpha-силуэт живёт в
// отдельном stage-sized SVG: это по-прежнему собственный промотированный слой,
// но уже не координатно огромная внутренняя .hp-paperg.
//
// Смок проверяет две вещи, и вторая — не время, а ОТНОШЕНИЕ: абсолютные
// миллисекунды зависят от машины и раннера, отношение «дневной цикл к
@@ -54,13 +52,17 @@ const setBackground = async (mode) => {
const outlineStyle = () => page.evaluate(() => {
const root = window.__card.shadowRoot || window.__card.renderRoot;
const stage = root.querySelector('.stage');
const group = root.querySelector('.hp-paperg');
if (!group) return null;
const style = getComputedStyle(group);
const outline = root.querySelector('.hp-paper-outline-svg');
const paper = root.querySelector('.plan-svg .hp-paperg');
if (!paper) return null;
const style = outline ? getComputedStyle(outline) : null;
return {
daycycle: stage.classList.contains('daycycle'),
filter: style.filter,
willChange: style.willChange,
outlinePresent: !!outline,
filter: style?.filter || 'none',
willChange: style?.willChange || 'auto',
paperFilter: getComputedStyle(paper).filter,
paperWillChange: getComputedStyle(paper).willChange,
};
});
@@ -112,12 +114,16 @@ const out = {};
await setBackground('daynight');
const dayStyle = await outlineStyle();
out.dayCycleClassOn = dayStyle?.daycycle === true;
out.dayCycleOutlinePresent = dayStyle?.outlinePresent === true;
out.dayCycleOutlineFiltered = /drop-shadow/.test(dayStyle?.filter || '');
out.dayCycleOutlinePromoted = /filter/.test(dayStyle?.willChange || '');
out.dayCyclePaperStaysUnfiltered = (dayStyle?.paperFilter || 'none') === 'none'
&& !/filter/.test(dayStyle?.paperWillChange || '');
await setBackground('static');
const staticStyle = await outlineStyle();
out.staticClassOff = staticStyle?.daycycle === false;
out.staticOutlineAbsent = staticStyle?.outlinePresent === false;
out.staticOutlineUnfiltered = (staticStyle?.filter || 'none') === 'none';
// Статичный фон не платит за чужую подсказку ни слоем, ни памятью.
out.staticOutlineNotPromoted = !/filter/.test(staticStyle?.willChange || '');
+131 -131
View File
@@ -1,295 +1,295 @@
{
"schema": 1,
"fingerprint": "241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef",
"fingerprint": "3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502",
"entry": "houseplan-card.js",
"panelEntry": "houseplan-panel.js",
"initialViewFiles": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-card.js"
],
"initialViewGzipBytes": 290805,
"initialViewGzipBytes": 290977,
"initialPanelFiles": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-panel.js"
],
"initialPanelGzipBytes": 292327,
"initialPanelGzipBytes": 292500,
"initialPanelOnlyFiles": [
"houseplan-panel.js"
],
"initialPanelOnlyGzipBytes": 2326,
"initialPanelOnlyGzipBytes": 2325,
"lazyFiles": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/de-BrzcYO-1.js",
"houseplan-assets/editor-Cfrg3iMq.js",
"houseplan-assets/fr-CLHfUBDP.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js",
"houseplan-assets/hp-zigbee-topology-overlay-jvjkBbI9.js",
"houseplan-assets/iso-scene-render-D2f0EUgN.js",
"houseplan-assets/live-interaction-runtime-BA69oN1Z.js",
"houseplan-assets/pdf-export-DeQrvN1z.js",
"houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js",
"houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/de-OKLqCJOe.js",
"houseplan-assets/editor-Bi3cJ768.js",
"houseplan-assets/fr-BjvleGPe.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js",
"houseplan-assets/hp-zigbee-topology-overlay-Bt3_AzlX.js",
"houseplan-assets/iso-scene-render-RpNlnxJ0.js",
"houseplan-assets/live-interaction-runtime-C8mBGPZT.js",
"houseplan-assets/pdf-export-CfU6W3j-.js",
"houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js",
"houseplan-assets/zigbee-topology-runtime-DvLAh834.js"
],
"lazyGzipBytes": 418772,
"lazyGzipBytes": 418768,
"lazyEditorFiles": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/editor-Cfrg3iMq.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/editor-Bi3cJ768.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js"
],
"lazyEditorGzipBytes": 204963,
"lazyEditorGzipBytes": 204957,
"lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js"
],
"lazyOnboardingGzipBytes": 13916,
"lazyOnboardingGzipBytes": 13913,
"lazyLocaleFiles": [
"houseplan-assets/de-BrzcYO-1.js",
"houseplan-assets/fr-CLHfUBDP.js"
"houseplan-assets/de-OKLqCJOe.js",
"houseplan-assets/fr-BjvleGPe.js"
],
"lazyLocaleGzipBytes": 54921,
"lazyLocaleGzipBytes": 54928,
"lazyIsometricFiles": [
"houseplan-assets/iso-scene-render-D2f0EUgN.js"
"houseplan-assets/iso-scene-render-RpNlnxJ0.js"
],
"lazyIsometricGzipBytes": 13234,
"lazyIsometricGzipBytes": 13233,
"lazyFurnitureArtFiles": [
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js"
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js"
],
"lazyFurnitureArtGzipBytes": 10255,
"lazyFurnitureArtGzipBytes": 10253,
"lazyPdfFiles": [
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/pdf-export-DeQrvN1z.js"
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/pdf-export-CfU6W3j-.js"
],
"lazyPdfGzipBytes": 120128,
"lazyPdfGzipBytes": 120126,
"files": [
{
"path": "houseplan-assets/backdrop-pick-ClLjW_UW.js",
"sha256": "5c8e9728df6ebdaad6346a26686f058ba4cce8bebd68c01d6cf18423ac67b792",
"path": "houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"sha256": "75bbf10c2e346eb00aff21123bdfc9c753efcb5a81fdb1de8735232110ad3b4b",
"rawBytes": 19956,
"gzipBytes": 6880,
"gzipBytes": 6879,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/de-BrzcYO-1.js",
"sha256": "b7488c7f186f740f02cdfde3c093aed8754e91157c0903d196a36fee4fbfef60",
"path": "houseplan-assets/de-OKLqCJOe.js",
"sha256": "c2374e47db6377fdebc46f33e501bca8c75c83a34040dc32cbdfd0d77aa970f5",
"rawBytes": 91590,
"gzipBytes": 27743,
"gzipBytes": 27746,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/editor-Cfrg3iMq.js",
"sha256": "83f9d762289e0f83a6e78730d3eb54862dbfa78408c93d410126f15988ca758c",
"path": "houseplan-assets/editor-Bi3cJ768.js",
"sha256": "856625d7c4609d8461a0a1f864c12cfe7929003add4d900affc09293d2a55ca3",
"rawBytes": 3831,
"gzipBytes": 1584,
"gzipBytes": 1582,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/fr-CLHfUBDP.js",
"sha256": "3524222b350ecbe2187351bf1730cc1d6393497104b10478cc3b7b0e5f14a9ec",
"path": "houseplan-assets/fr-BjvleGPe.js",
"sha256": "ab49a526636631678544da34495d55aa2ca181a9e89e3df4933cd4100aecdf59",
"rawBytes": 93884,
"gzipBytes": 27178,
"gzipBytes": 27182,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"sha256": "8303521f70c98617ece5cea54517760fdb808bec3fc7b68add0434ea56980dd3",
"path": "houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"sha256": "c7f2275e7fe40520b80e2bf8cf1f41677382ccfdbf49c069cf8d794c866bc44a",
"rawBytes": 33655,
"gzipBytes": 10255,
"gzipBytes": 10253,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-card-BvxqYw8A.js",
"sha256": "da77e0c3d6445d114ff496613fc8aebfb7e7ed132bdfbc5c2bc8c5a79fd8afc2",
"rawBytes": 1032746,
"gzipBytes": 290001,
"path": "houseplan-assets/houseplan-card-Cythr3Rg.js",
"sha256": "87cc46dbb29e86af1732f00d74fecf5050295c7812b429b247ecac649abdd67a",
"rawBytes": 1033369,
"gzipBytes": 290175,
"isEntry": false,
"imports": [],
"dynamicImports": [
"houseplan-assets/de-BrzcYO-1.js",
"houseplan-assets/editor-Cfrg3iMq.js",
"houseplan-assets/fr-CLHfUBDP.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js",
"houseplan-assets/hp-zigbee-topology-overlay-jvjkBbI9.js",
"houseplan-assets/iso-scene-render-D2f0EUgN.js",
"houseplan-assets/live-interaction-runtime-BA69oN1Z.js",
"houseplan-assets/pdf-export-DeQrvN1z.js",
"houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js"
"houseplan-assets/de-OKLqCJOe.js",
"houseplan-assets/editor-Bi3cJ768.js",
"houseplan-assets/fr-BjvleGPe.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js",
"houseplan-assets/hp-zigbee-topology-overlay-Bt3_AzlX.js",
"houseplan-assets/iso-scene-render-RpNlnxJ0.js",
"houseplan-assets/live-interaction-runtime-C8mBGPZT.js",
"houseplan-assets/pdf-export-CfU6W3j-.js",
"houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js"
]
},
{
"path": "houseplan-assets/houseplan-editor-runtime-Pkk2XGqR.js",
"sha256": "0d095de08b11966dd3cb784099bba2f92d8c294f0817a49f3e3d4813ca9baa0b",
"path": "houseplan-assets/houseplan-editor-runtime-CCYvnxhV.js",
"sha256": "440f16ed41a7b01b15fc253209be5cb6242f4c48dec1646b07bf5e7304d3f3c4",
"rawBytes": 670150,
"gzipBytes": 178818,
"gzipBytes": 178815,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js"
],
"dynamicImports": [
"houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js"
"houseplan-assets/zigbee-topology-runtime-DvLAh834.js"
]
},
{
"path": "houseplan-assets/houseplan-onboarding-runtime-BhJG-ch3.js",
"sha256": "66ec3c0650ce721de901ec5d8d175c3b76e4878da909dada0d92589b3c8da4b5",
"path": "houseplan-assets/houseplan-onboarding-runtime-BNfzBq5J.js",
"sha256": "ca88d8512e071d73ced67a1eccbd13a9c63ff776589d963db173d1b6ca8aded5",
"rawBytes": 28287,
"gzipBytes": 7036,
"gzipBytes": 7034,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-ClLjW_UW.js",
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/backdrop-pick-Bcqm2p5p.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/hp-zigbee-topology-overlay-jvjkBbI9.js",
"sha256": "d4b6c957d4a82b979f7a71832e583fbd93852f7f8c340ce7a32fb8f773a59bc5",
"path": "houseplan-assets/hp-zigbee-topology-overlay-Bt3_AzlX.js",
"sha256": "14a73aa0d44c2d5c0ad2198dc25a2180515d6920898f3d34643f2bafe06d8158",
"rawBytes": 10756,
"gzipBytes": 3685,
"gzipBytes": 3686,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js",
"houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js",
"houseplan-assets/zigbee-topology-runtime-DvLAh834.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/iso-scene-render-D2f0EUgN.js",
"sha256": "92b77a114af62667adceacab9ecb76b631afb2ac83d9e255af206678f79cac47",
"path": "houseplan-assets/iso-scene-render-RpNlnxJ0.js",
"sha256": "95c96d30a226573c9131a94334aef2ca12a5f58a8f6ce5ff258cf0ec47fbee23",
"rawBytes": 39206,
"gzipBytes": 13234,
"gzipBytes": 13233,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/live-interaction-runtime-BA69oN1Z.js",
"sha256": "1e3130110cdb4af9dfe938444d9b8a88ef4f6c30502841f5785231894e1ed7a6",
"path": "houseplan-assets/live-interaction-runtime-C8mBGPZT.js",
"sha256": "6df6de94c668490716339ae897412d6e794d0f753584ae3d34f98f43349bc7d8",
"rawBytes": 8216,
"gzipBytes": 3207,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/pdf-export-DeQrvN1z.js",
"sha256": "11a305cbbb3772c55968cbcb502c1878e4e74522c5179e1ee281e80fb85d6f93",
"path": "houseplan-assets/pdf-export-CfU6W3j-.js",
"sha256": "28eb5327001bebfddbdf01086a7a851bbc7c04e4b7030e3b413b8dfb0a73eb3e",
"rawBytes": 236244,
"gzipBytes": 109873,
"isEntry": false,
"imports": [
"houseplan-assets/furniture-plan-art.generated-7nJsC48X.js",
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/furniture-plan-art.generated-C_Z1hwSa.js",
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-editor-o2bn2wLY.js",
"sha256": "c253cfec20c5cef0a472b4dd42caca4276d147e48ea795f9d1b562c4a39da46e",
"path": "houseplan-assets/summary-panel-editor-CTfI9Enr.js",
"sha256": "559732b375119e7169332d1a93f7778382eb3f97a9bb0150eb2fe600448f1286",
"rawBytes": 14824,
"gzipBytes": 3401,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-metrics-CzgAvzH6.js",
"sha256": "51530c69ada90dc42a92f5e297366734969c1a91c58ae30b9ecd528978a5441e",
"path": "houseplan-assets/summary-panel-metrics-XatK0mU4.js",
"sha256": "d627d8bb01b003f47f9fbb0594c2526a8d8676d491595612239d2c8ee0e5bffe",
"rawBytes": 2610,
"gzipBytes": 1305,
"gzipBytes": 1306,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-runtime-loaded-B6w0YS6P.js",
"sha256": "fa463fbec81b0635b56be87906d24442eba48ed1047445e192b5eb3ec519b7c1",
"path": "houseplan-assets/summary-panel-runtime-loaded-BbGQ8VLD.js",
"sha256": "545cb01893ff659bcbe0fb14cd32c5656481f317a90053b25e1ff1cff2773096",
"rawBytes": 73366,
"gzipBytes": 20089,
"gzipBytes": 20087,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": [
"houseplan-assets/summary-panel-editor-o2bn2wLY.js",
"houseplan-assets/summary-panel-metrics-CzgAvzH6.js"
"houseplan-assets/summary-panel-editor-CTfI9Enr.js",
"houseplan-assets/summary-panel-metrics-XatK0mU4.js"
]
},
{
"path": "houseplan-assets/zigbee-topology-B8St6NV9.js",
"sha256": "d35d5ebeedb562a4c29709da95964080f053e4e1eb0d3f2fb7eb957b71444e9c",
"path": "houseplan-assets/zigbee-topology-CWUjtXoY.js",
"sha256": "89766dbc5817dc1889e7c30a8ad36817d2c675760c9cb82f9de2adacafb9c06c",
"rawBytes": 18961,
"gzipBytes": 7426,
"gzipBytes": 7428,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/zigbee-topology-runtime-BkrLGjiL.js",
"sha256": "a7774967077014e62b395dacb43dc7eb10022b03b6ac24a358ce53eee4469786",
"path": "houseplan-assets/zigbee-topology-runtime-DvLAh834.js",
"sha256": "f3a64d38e8eb5ab5983340354db8dce98db8c7b11c903699cd7cbee7a8ff3f66",
"rawBytes": 3941,
"gzipBytes": 1764,
"gzipBytes": 1763,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js",
"houseplan-assets/zigbee-topology-B8St6NV9.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js",
"houseplan-assets/zigbee-topology-CWUjtXoY.js"
],
"dynamicImports": []
},
{
"path": "houseplan-card.js",
"sha256": "79b31c6683afff9ca22fb99a7a855f81957a199352f0f212807444b2998ee7d1",
"sha256": "42e5ccc368c0b72a931ec124f88711c5551e3a202dbf525cb96348f0c6aec03e",
"rawBytes": 1205,
"gzipBytes": 804,
"gzipBytes": 802,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
},
{
"path": "houseplan-panel.js",
"sha256": "4240e1335652c727ecf9a8868b515945f8c97b50cff332708ac302b9c0ccf6b4",
"sha256": "7e2756dab8b6fecee15843885756abc8a2bed9e49caa10fee0c393a4cd10ee1b",
"rawBytes": 6165,
"gzipBytes": 2326,
"gzipBytes": 2325,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-BvxqYw8A.js"
"houseplan-assets/houseplan-card-Cythr3Rg.js"
],
"dynamicImports": []
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,14 +1,14 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{q as e,l as o,v as t,e4 as s,A as a,e5 as i,e6 as l,e7 as n,E as r,c}from"./houseplan-card-BvxqYw8A.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__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{q as e,l as o,v as t,e4 as s,A as a,e5 as i,e6 as l,e7 as n,E as r,c}from"./houseplan-card-Cythr3Rg.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
.hass=${this.hass}
.data=${this._formData}
.schema=${e}
.computeLabel=${e=>h[e.name]||e.name}
.computeLabel=${e=>f[e.name]||e.name}
@value-changed=${this._valueChanged}
></ha-form>`;return c`
${d(f.slice(0,3))}
${d(h.slice(0,3))}
${_?c`<div class="default-floor-error" role="alert"
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
${t(s,"editor.default_floor_missing",{id:_})}
</div>`:a}
${d(f.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
${d(h.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{c as a,A as e}from"./houseplan-card-BvxqYw8A.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-B6w0YS6P.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__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{c as a,A as e}from"./houseplan-card-Cythr3Rg.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-BbGQ8VLD.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 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{ea as e,P as t,a5 as n,M as i,aq as r,N as o,bs as s,br as a,a4 as c,a3 as l,aA as u,eb as d,ec as f,bu as m,ed as g}from"./houseplan-card-BvxqYw8A.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=u(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const r=String(i.binding||"").indexOf(":");if(r<1)continue;const o=i.binding.slice(0,r),s=i.binding.slice(r+1),a="device"===o?e.registry.devices?.[s]:null,c="entity"===o?e.registry.entities?.[s]:null,l="device"===o?s:c?.device_id,u="device"===o?a?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,d="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||u||"",f=d&&e.areaToSpace[d]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===o&&n.liveEntities.has(s))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,r,o);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,r,o)}}function*b(c,l,u=_){try{let d=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=u(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,r,o,g.roomGeom,g.multiWallNodes)||a;v=y(v,s(c,m.physicalBodies)),yield}const _=m.cellCm/r;d+=a(v)*_*_/1e4}return d}catch{return null}}function h(e,t,n=_){const i=b(e,t,n);let r=i.next();for(;!r.done;)r=i.next();return r.value}function p(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=d(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{b as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,p as summarySystemValue,h as totalCleanFloorAreaM2};
@@ -0,0 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{ea as e,P as t,a5 as n,M as i,aq as r,N as o,bs as a,br as s,a4 as l,a3 as c,aA as d,eb as u,ec as f,bu as m,ed as g}from"./houseplan-card-Cythr3Rg.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const r=String(i.binding||"").indexOf(":");if(r<1)continue;const o=i.binding.slice(0,r),a=i.binding.slice(r+1),s="device"===o?e.registry.devices?.[a]:null,l="entity"===o?e.registry.entities?.[a]:null,c="device"===o?a:l?.device_id,d="device"===o?s?.area_id:l?.area_id||c&&e.registry.devices?.[c]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;c&&e.registry.devices?.[c]&&e.spaceIds.has(f)&&(!n.devices.has(c)||"entity"===o&&n.liveEntities.has(a))&&t.add(c)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=l(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,r,o);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:c(e.rooms,t.walls,t.openCuts,i,t.cellCm,r,o)}}function*h(l,c,d=_){try{let u=0;for(const f of c){const c=l.spaces.find(e=>String(e?.id)===f.id);if(!c)continue;const m=e(c,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const l=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,r,o,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(l,m.physicalBodies)),yield}const _=m.cellCm/r;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let r=i.next();for(;!r.done;)r=i.next();return r.value}function S(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function b(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,b as summaryEntityValue,S as summarySystemValue,p as totalCleanFloorAreaM2};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";import{n as t,b as n}from"./zigbee-topology-B8St6NV9.js";import{F as e}from"./houseplan-card-BvxqYw8A.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";import{n as t,b as n}from"./zigbee-topology-CWUjtXoY.js";import{F as e}from"./houseplan-card-Cythr3Rg.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
+1 -1
View File
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="241ab786b7cce5c1f837e73704240f138bd3e097bfecdbb0e93046bf4a19d3ef";try{await import("./houseplan-assets/houseplan-card-BvxqYw8A.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__="3f783ed7cf5daff202a910aa89044f88f605a65af7f46794277dddf04333e502";try{await import("./houseplan-assets/houseplan-card-Cythr3Rg.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)}
+1 -1
View File
File diff suppressed because one or more lines are too long
+14 -3
View File
@@ -259,9 +259,12 @@ the same profiler available between stable promotions.
owns the constant four-layer DOM and exact palette used by full View, kiosk,
and `houseplan-space-card`; no surface copies thresholds or formulas. The
environment is a pointer-inert sibling behind the plan. The only
phase-dependent effect touching the SVG is a zero-offset filter on the one
grouped `.hp-paperg` footprint; the content tree has no brightness, tint,
opacity, or blend changes. Full and static card lifecycles arm a 30-second
phase-dependent SVG effect is a zero-offset filter on a stage-sized sibling
SVG containing an exact copy of the grouped paper footprint. The visible
`.hp-paperg` is not filtered: keeping `will-change: filter` on that inner
coordinate-space group made 1 cm/point plans exceed WebView texture budgets
(#582). The content tree has no brightness, tint, opacity, or blend changes.
Full and static card lifecycles arm a 30-second
timer only during clock fallback while visible, catch up on visibility return,
and dispose it on disconnect. Window-ray geometry remains a separate
north-gated consumer of `sun.sun`.
@@ -2011,6 +2014,14 @@ state. The coverage contract also holds when a pointer is held still between
frames: the fast frame must contain every scene pixel that a forced target
`viewBox` would contain inside `.stage`.
The day-cycle paper outline is one of those scene SVGs (#582). Its root CSS box
is stage-sized and owns the triple drop-shadow and idle `will-change: filter`;
its child is only an exact paper alpha silhouette. During a gesture the same
floor/camera projection and budgeted `viewBox` updates are applied to both the
outline root and the visible plan root. This keeps #532's isolated raster path
without promoting the inner 4700×4200-style local-coordinate footprint or the
large overlap graph that HA Companion could not tile continuously.
Neither the attribute nor an equal style property is written when its value is
unchanged: an idle frame must leave the DOM byte-identical, or the settled raster
shifts by a few colour levels and golden frames flap. `commitHouseplanViewport`
+7
View File
@@ -2,6 +2,13 @@
## Unreleased
- Large plans using the “Follows the Sun” background no longer allocate their
soft outline in the plan's full internal coordinate size. Pinch-zoom in Home
Assistant Companion now keeps those compositor surfaces screen-sized, so
walls and floors no longer develop fixed white gaps on 1 cm/grid-point
spaces; the outline appearance and static backgrounds are unchanged
([#582](https://github.com/Matysh/houseplan-card/issues/582)).
- Sun rays from the outer window corners now respect occlusion by thick-wall
jambs: at oblique angles only the part with a clear path through the complete
opening reaches the room, instead of shining through solid wall
+8
View File
@@ -8,6 +8,14 @@
## Не выпущено
- На больших планах с фоном «Следует за Солнцем» мягкий внешний контур больше
не выделяется в GPU-слой размером со все внутренние координаты плана. При
pinch-zoom в приложении Home Assistant такие слои остаются размером с экран,
поэтому на пространствах с сеткой 1 см/точку в стенах и полу больше не
появляются фиксированные белые провалы. Внешний вид контура и статичный фон
не изменились
([#582](https://github.com/Matysh/houseplan-card/issues/582)).
- Солнечные лучи от внешних углов окна теперь учитывают затенение откосами
толстой стены: при косом солнце в комнату проходит только видимая через весь
оконный проём часть луча, а не свет сквозь сплошную стену
+10 -7
View File
@@ -75,17 +75,20 @@ The public setting remains a two-value selector. `static` uses `bg_color`.
05:00→13:00→21:00 fallback arc. It has zero visible opacity at night.
- Four constant environment layers cross-fade for exactly 1100 ms with
`cubic-bezier(.22,.61,.36,1)`. Reduced motion disables the transition.
- The zero-offset outline is a filter over the grouped paper footprint, so it
is kept on its own compositing layer (`will-change: filter`, scoped to the
day-cycle stage). The group holds paper silhouettes only and does not change
while the plan is hovered or panned; without the hint every repaint of the
plan re-ran three blur passes over the whole sheet. Measured in headless
- The zero-offset outline uses an exact copy of the grouped paper footprint in
a pointer-inert sibling SVG behind the visible plan. The filter and
`will-change: filter` belong to that root SVG, whose CSS box is the stage,
not to the inner `.hp-paperg`: a 1 cm/grid-point plan may span more than
4096 local SVG units without allocating a coordinate-sized filter layer.
The sibling follows the same live viewport as the visible plan throughout a
gesture. Without its own promoted layer every repaint of the plan re-ran
three blur passes over the whole sheet. Measured in headless
Chromium (CDP tracing, summed `RasterTask`) on a demo-stand pan, that cost
about fifteen times the rasterization of a static background; the owner's
Firefox profile that opened #532 showed the same cause as 23 MB of texture
uploads per frame and about nine frames per second, without a comparable
ratio of its own. A static background carries neither the filter nor the
hint.
ratio of its own. A static background creates no outline sibling and carries
neither the filter nor the hint (#582).
- Only the environment and the zero-offset alpha-aware outline outside the
grouped plan-paper footprint change. The plan, paper, floors, room fills,
Glow/spill, devices, labels, decor/backdrop, vacuum, hover, and window rays
+7
View File
@@ -2830,6 +2830,13 @@ require hands on real hardware — they remain for the human pass.
dawn/day/dusk/night environment tokens. Only environment and outer
plan-paper outline cross-fade for 1100 ms; reduced motion is instant
[auto: `smoke_sun_live_bg`, golden `day-cycle-*`]
- [ ] A physically ordinary day-cycle plan stored at 1 cm/grid-point keeps the
outline compositor surface bounded by the visible stage during pinch;
the inner paper group is unfiltered, no content layer exceeds 4096 in
either dimension, and sampled presented frames contain no white tile.
The same isolated outline still satisfies the #532 relative raster
budget [auto: `smoke_daycycle_layer_budget`, `smoke_daycycle_raster`,
`smoke_live_pan_coverage`]
- [ ] Opaque plan paper (2026-08-03, owner): the scene background —
`bg_color` or the daynight sky — is visible ONLY around the plan and
NEVER bleeds through it, in view/kiosk/editors and on the static
+4
View File
@@ -51,6 +51,10 @@ stay on one promoted compositor path from the first movement until the terminal
frame; a budgeted redraw or an unrelated Home Assistant state update must never
flash white, become transparent or momentarily expose the stage background.
This contract applies equally to browsers and HA Companion WebViews.
`smoke_daycycle_layer_budget` additionally proves that a 1 cm/grid-point
day-cycle plan keeps compositor surfaces in screen-space bounds and samples
the compositor-presented pinch frames; the real-device beta pass remains the
field acceptance for WebView-specific tile loss (#582).
Once a second touch joins an input sequence, that whole sequence is navigation
only, whichever contact began on a device marker. Marker tap, long press,
+14
View File
@@ -2610,6 +2610,20 @@ const MUTANT_DEFINITIONS = [
replace: "const HANDLE_PAINT_ORDER = ['corners', 'edges'] as const;",
}],
},
{
id: 'daycycle-outline-promoted-on-inner-paper',
guard: 'node demo/smoke_daycycle_layer_budget.mjs',
because: '#582: promoting the inner paper group allocates in local plan coordinates; a '
+ '4700x4200 floor then creates texture-sized overlap layers and HA Companion loses tiles',
patches: [{
file: 'src/styles/plan.styles.ts',
find: ' @media (prefers-reduced-motion: reduce) {\n'
+ ' .hp-day-cycle-bg,\n',
replace: ' .stage.daycycle .hp-paperg { will-change: filter; }\n'
+ ' @media (prefers-reduced-motion: reduce) {\n'
+ ' .hp-day-cycle-bg,\n',
}],
},
{
id: 'daycycle-outline-not-promoted',
guard: 'node demo/smoke_daycycle_raster.mjs',
+10
View File
@@ -34,6 +34,16 @@ export const SMOKE_LINKS = [
+ 'the space) is observed through `.room` style variables in View and through the room-dialog '
+ 'draft; neither smoke calls the pure function by name',
},
{
symbols: ['renderPaperShapes'],
smokes: [
'smoke_daycycle_layer_budget.mjs', 'smoke_daycycle_raster.mjs',
'smoke_live_pan_coverage.mjs', 'smoke_bg_color.mjs',
],
because: '#582: production-bundle witnesses prove that the separate day-cycle paper '
+ 'silhouette remains stage-bounded at 1 cm/point, keeps the #532 raster budget and follows '
+ 'the same #579 live viewport as the visible plan; source imports cannot expose CDP layers',
},
{
symbols: [
'commitHouseplanViewport', 'isIdentityLiveLayerProjection', 'paintLiveViewport',
+13 -13
View File
@@ -71,6 +71,7 @@ import {
rayRimEdges, rimStops, rimPeakAlpha, RIM_COLOR, type SunRayOrigin,
} from './sun';
import { dayCycleStageVars, renderDayCycleEnvironment } from './day-cycle-render';
import { renderPaperShapes, type PaperShape } from './render/paper-scene';
import {
furnitureGraphic, furnitureArtIsLazy,
furniturePlanScreenScale, furnitureStrokePx,
@@ -9181,11 +9182,7 @@ export class HouseplanCard extends LitElement {
}
/** Paper under rooms, grown by shared-wall half-thickness when set. */
private _paperShapes(rooms: any[]): Array<
| { path: string }
| { poly: string }
| { rect: { x: number; y: number; w: number; h: number; rx: number } }
> {
private _paperShapes(rooms: RoomCfg[]): PaperShape[] {
const walls = this._spaceWalls;
if (!walls.length) return paperRoomShapes(rooms);
const united = this._wallUnionGeometry();
@@ -11430,6 +11427,7 @@ export class HouseplanCard extends LitElement {
const modeVisual = this._modeTransitionVisual;
const dayCycle = this._dayCycleState();
const dayCycleWeight = modeVisual?.viewWeight ?? (this._mode === 'view' ? 1 : 0);
const paperShapes = this._paperShapes(space.rooms);
const transitionFromMode = this._modeTransition.state?.from.presentedMode;
const glowLayerVisible = !this._markup || !!modeVisual && (
modeVisual.presentedMode === 'view' || modeVisual.presentedMode === 'devices'
@@ -11595,7 +11593,15 @@ export class HouseplanCard extends LitElement {
preserveAspectRatio="xMidYMid meet" aria-hidden="true" pointer-events="none">
${isoFrame?.underlay ?? nothing}
</svg>` : nothing}
<svg class=${iso ? 'plan-svg' : nothing}
${dayCycle && paperShapes.length ? svg`<svg class="hp-paper-outline-svg"
data-hp-live-viewbox=${iso ? 'camera' : 'floor'}
viewBox="${view.x} ${view.y} ${view.w} ${view.h}"
preserveAspectRatio="xMidYMid meet" aria-hidden="true" pointer-events="none">
<g transform=${iso ? isoFloorMatrixCss() : nothing}>
${renderPaperShapes(paperShapes, 'hp-paper-outline-shapes')}
</g>
</svg>` : nothing}
<svg class="plan-svg"
data-hp-live-viewbox=${iso ? 'camera' : 'floor'}
viewBox="${view.x} ${view.y} ${view.w} ${view.h}"
preserveAspectRatio="xMidYMid meet">
@@ -11617,13 +11623,7 @@ export class HouseplanCard extends LitElement {
One <g> around ALL paper shapes: the external day-cycle outline
(styles.ts) is composited once for the whole sheet, so
adjacent rooms never cast seams onto each other's paper. */}
${this._wallHatchDefs(disp.color)}${svg`<g class="hp-paperg">${this._paperShapes(space.rooms).map((sh) =>
'path' in sh
? svg`<path class="hp-paper" d="${sh.path}" fill-rule="evenodd" pointer-events="none"></path>`
: 'poly' in sh
? svg`<polygon class="hp-paper" points="${sh.poly}" pointer-events="none"></polygon>`
: svg`<rect class="hp-paper" x="${sh.rect.x}" y="${sh.rect.y}" width="${sh.rect.w}" height="${sh.rect.h}" rx="${sh.rect.rx}" pointer-events="none"></rect>`,
)}</g>`}
${this._wallHatchDefs(disp.color)}${renderPaperShapes(paperShapes)}
${this._editing ? this._renderMarkupDefs(vb) : nothing}
${''/* the grid is a property of the plane, not of a box: it follows
the VIEW so it is there wherever you pan (docs/CANVAS.md §7) */}
+22
View File
@@ -0,0 +1,22 @@
import { svg, type SVGTemplateResult } from 'lit';
export type PaperShape =
| { path: string }
| { poly: string }
| { rect: { x: number; y: number; w: number; h: number; rx: number } };
/** One shared renderer keeps the visible paper and its shadow silhouette exact. */
export function renderPaperShapes(
shapes: readonly PaperShape[],
groupClass = 'hp-paperg',
): SVGTemplateResult {
return svg`<g class=${groupClass}>${shapes.map((shape) =>
'path' in shape
? svg`<path class="hp-paper" d=${shape.path} fill-rule="evenodd" pointer-events="none"></path>`
: 'poly' in shape
? svg`<polygon class="hp-paper" points=${shape.poly} pointer-events="none"></polygon>`
: svg`<rect class="hp-paper" x=${shape.rect.x} y=${shape.rect.y}
width=${shape.rect.w} height=${shape.rect.h} rx=${shape.rect.rx}
pointer-events="none"></rect>`,
)}</g>`;
}
+5
View File
@@ -957,6 +957,11 @@ class HouseplanSpaceCard extends LitElement {
display: block;
z-index: 1;
}
.hp-static-stage .hp-paper-outline-svg {
z-index: 0;
overflow: visible;
pointer-events: none;
}
/* Opaque plan paper — the scene bg_color/day-cycle environment shows only AROUND
the plan (owner 2026-08-03). The static card keeps its historical
canvas colour: the theme card background. Drawn plans paper the room
+9 -9
View File
@@ -47,6 +47,7 @@ import { valueBadgeTitle } from './device-value-badge';
import { contentFingerprint } from './visual-continuity';
import type { VirtualLightSnapshot } from './virtual-light-state';
import { renderOpeningTunnelFills } from './render/opening-tunnels';
import { renderPaperShapes, type PaperShape } from './render/paper-scene';
import { gridVisualScale, gridVisualUnits } from './grid-scale';
import {
spaceModels, defaultPositions, markerPos, labelPos, spaceFrame, iconCqw, NORM_W,
@@ -692,7 +693,7 @@ export function renderSpaceStatic(o: StaticRenderOpts): TemplateResult | null {
dataLayer: 'glow-base',
})
: nothing;
const paperShapes = walls.length && canonicalWallGeometry?.paperD
const paperShapes: PaperShape[] = walls.length && canonicalWallGeometry?.paperD
? [{ path: canonicalWallGeometry.paperD }]
: paperRoomShapes(space.rooms);
const wallUnion = disp.showBorders ? canonicalWallGeometry : null;
@@ -898,7 +899,12 @@ export function renderSpaceStatic(o: StaticRenderOpts): TemplateResult | null {
?inert=${!!o.inert}
style="aspect-ratio:${vb[2]}/${vb[3]}${stageBg ? ';background:' + stageBg : ''};--hp-cell-visual-scale:${gridVisualScale(cellCm)};--wall-fill:${colors.wall_fill.c};--wall-fill-op:${colors.wall_fill.a}${dayCycle ? `;${dayCycleStageVars(dayCycle)}` : ''}">
${renderDayCycleEnvironment(dayCycle)}
<svg viewBox="${vb[0]} ${vb[1]} ${vb[2]} ${vb[3]}" preserveAspectRatio="xMidYMid meet">
${dayCycle && paperShapes.length ? svg`<svg class="hp-paper-outline-svg"
viewBox="${vb[0]} ${vb[1]} ${vb[2]} ${vb[3]}"
preserveAspectRatio="xMidYMid meet" aria-hidden="true" pointer-events="none">
${renderPaperShapes(paperShapes, 'hp-paper-outline-shapes')}
</svg>` : nothing}
<svg class="hp-static-plan-svg" viewBox="${vb[0]} ${vb[1]} ${vb[2]} ${vb[3]}" preserveAspectRatio="xMidYMid meet">
${wallUnion ? svg`<defs>
<pattern id="hp-wall-hatch" patternUnits="userSpaceOnUse"
width="${hatchStep}" height="${hatchStep}" patternTransform="rotate(45)">
@@ -906,13 +912,7 @@ export function renderSpaceStatic(o: StaticRenderOpts): TemplateResult | null {
stroke-width="${2 * (hatchStep / HATCH_BASE_STEP_UNITS)}"></path>
</pattern>
</defs>` : nothing}
<g class="hp-paperg">${paperShapes.map((sh) =>
'path' in sh
? svg`<path class="hp-paper" d="${sh.path}" fill-rule="evenodd"></path>`
: 'poly' in sh
? svg`<polygon class="hp-paper" points="${sh.poly}"></polygon>`
: svg`<rect class="hp-paper" x="${sh.rect.x}" y="${sh.rect.y}" width="${sh.rect.w}" height="${sh.rect.h}" rx="${sh.rect.rx}"></rect>`,
)}</g>
${renderPaperShapes(paperShapes)}
${bgHref
? svg`<image href="${bgHref}" x="${space.bg!.x}" y="${space.bg!.y}" width="${space.bg!.w}" height="${space.bg!.h}"
@load=${() => o.assetLoaded?.(space.bg!.href, bgHref)}
+13 -12
View File
@@ -86,16 +86,12 @@ export const planStyles = css`
opacity 1100ms cubic-bezier(.22, .61, .36, 1);
}
.stage.mode-transition .hp-day-cycle-env { transition: none; }
/* #532: the outline keeps its OWN compositing layer. The group holds paper
silhouettes only and does not change on hover or pan, but the filter used
to live in the plan's own layer — so every repaint of the plan re-ran
three blur passes over the whole sheet. Measured on a demo-stand pan
(Chromium, CDP, summed RasterTask): 852 ms without the hint against 28 ms
with it, where a static background costs 108 ms. The hint costs one layer
of memory, so it is scoped to .daycycle and a static background never
pays for it. */
.stage.daycycle .hp-paperg,
.hp-static-stage.daycycle .hp-paperg {
/* #532 + #582: the outline keeps its OWN compositing layer, but the
promoted element must be the stage-sized root SVG. Promoting the inner
paper group allocated in local plan coordinates (4700×4200 at
1 cm/point) and overflowed HA Companion's WebView texture budget. */
.stage.daycycle .hp-paper-outline-svg,
.hp-static-stage.daycycle .hp-paper-outline-svg {
filter:
drop-shadow(0 0 1px var(--hp-day-cycle-outline-near))
drop-shadow(0 0 5px var(--hp-day-cycle-outline-mid))
@@ -106,8 +102,8 @@ export const planStyles = css`
@media (prefers-reduced-motion: reduce) {
.hp-day-cycle-bg,
.hp-day-cycle-sun,
.stage.daycycle .hp-paperg,
.hp-static-stage.daycycle .hp-paperg {
.stage.daycycle .hp-paper-outline-svg,
.hp-static-stage.daycycle .hp-paper-outline-svg {
transition: none;
}
}
@@ -252,6 +248,11 @@ export const planStyles = css`
display: block;
}
.plan-svg { z-index: 1; }
.hp-paper-outline-svg {
z-index: 0;
overflow: visible;
pointer-events: none;
}
.iso-underlay-svg { z-index: 0; overflow: visible; }
.iso-shadows-svg { z-index: 3; overflow: visible; }
.iso-walls-svg {
+1 -1
View File
@@ -192,7 +192,7 @@ test('Stage 4 structural cache fingerprints geometry/camera/heights and excludes
test('show_borders:false keeps the exact zero-yaw floor matrix and removes every volume cue', () => {
assert.match(card, /isoLayers && !isoLayers\.floorSymbols/);
assert.match(card, /<svg class=\$\{iso \? 'plan-svg' : nothing\}[\s\S]*?data-hp-live-viewbox=\$\{iso \? 'camera' : 'floor'\}/);
assert.match(card, /<svg class="plan-svg"[\s\S]*?data-hp-live-viewbox=\$\{iso \? 'camera' : 'floor'\}/);
assert.match(card, /transform=\$\{iso \? isoFloorMatrixCss\(\) : nothing\}/);
assert.match(card,
/\$\{litCache\(iso && isoLayers\?\.structural \? svg`<svg class="iso-shadows-svg"/);
+33
View File
@@ -0,0 +1,33 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
const source = (path) => readFileSync(new URL(`../${path}`, import.meta.url), 'utf8');
test('#582 day-cycle shadow uses one shared stage-bounded paper scene', () => {
const helper = source('src/render/paper-scene.ts');
const card = source('src/houseplan-card.ts');
const staticRender = source('src/space-render.ts');
const styles = source('src/styles/plan.styles.ts');
assert.match(helper, /function renderPaperShapes/);
assert.match(helper, /pointer-events="none"/);
assert.match(card, /dayCycle && paperShapes\.length \? svg`<svg class="hp-paper-outline-svg"/);
assert.match(card, /data-hp-live-viewbox=\$\{iso \? 'camera' : 'floor'\}/);
assert.match(staticRender, /dayCycle && paperShapes\.length \? svg`<svg class="hp-paper-outline-svg"/);
assert.match(card, /renderPaperShapes\(paperShapes\)/);
assert.match(staticRender, /renderPaperShapes\(paperShapes\)/);
assert.match(styles, /\.stage\.daycycle \.hp-paper-outline-svg/);
assert.doesNotMatch(styles, /\.stage\.daycycle \.hp-paperg[\s\S]{0,300}will-change:\s*filter/);
});
test('#582 flat plan root is explicitly above the outline scene', () => {
const card = source('src/houseplan-card.ts');
const styles = source('src/styles/plan.styles.ts');
const staticCard = source('src/space-card.ts');
assert.match(card, /<svg class="plan-svg"/);
assert.match(styles, /\.plan-svg \{ z-index: 1; \}/);
assert.match(styles, /\.hp-paper-outline-svg \{[\s\S]*?z-index: 0;/);
assert.match(staticCard, /\.hp-static-stage \.hp-paper-outline-svg \{[\s\S]*?z-index: 0;/);
});