Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af46d2a9b4 | ||
|
|
51657831e6 |
@@ -1,113 +1,113 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a",
|
||||
"fingerprint": "92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js",
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 273551,
|
||||
"initialViewGzipBytes": 273581,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/de-nY6CPgRE.js",
|
||||
"houseplan-assets/editor-Btuj24RH.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-CztWrxSd.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/de-DMfFz19N.js",
|
||||
"houseplan-assets/editor-36HAh3Je.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BuN48ldr.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js"
|
||||
],
|
||||
"lazyGzipBytes": 168764,
|
||||
"lazyGzipBytes": 168780,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/editor-Btuj24RH.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-CztWrxSd.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/editor-36HAh3Je.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BuN48ldr.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 139471,
|
||||
"lazyEditorGzipBytes": 139483,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 9453,
|
||||
"lazyOnboardingGzipBytes": 9456,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-nY6CPgRE.js"
|
||||
"houseplan-assets/de-DMfFz19N.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 22796,
|
||||
"lazyLocaleGzipBytes": 22799,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"sha256": "db0d4c348fee148aff02781bfb2c1d0fa4afb50b7f7c7670768b748675f5389a",
|
||||
"path": "houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"sha256": "bca0256fc222b1c3f6045a97d7a773f499701c1b9b3dcc8498c40cdd26de403b",
|
||||
"rawBytes": 6967,
|
||||
"gzipBytes": 2956,
|
||||
"gzipBytes": 2958,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-nY6CPgRE.js",
|
||||
"sha256": "1ea533abc21c2d2585941122c21212deeec234adf5099ae8afce611bc3a6cd49",
|
||||
"path": "houseplan-assets/de-DMfFz19N.js",
|
||||
"sha256": "307982665ac112914972383bbed35da47ce8e917009daa792e29119dfbe263ec",
|
||||
"rawBytes": 74836,
|
||||
"gzipBytes": 22796,
|
||||
"gzipBytes": 22799,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-Btuj24RH.js",
|
||||
"sha256": "e462de3e6a34cce0b93fabf0804a430ce81bcfd2fe6c26e65557ec65504cd964",
|
||||
"path": "houseplan-assets/editor-36HAh3Je.js",
|
||||
"sha256": "c0a8bb4c6cd7868ae5ad78b8d2ecca80e9a449f1d3c03b5c0eadb20a791a8285",
|
||||
"rawBytes": 3831,
|
||||
"gzipBytes": 1585,
|
||||
"gzipBytes": 1586,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-z66sNkRH.js",
|
||||
"sha256": "33ee209a395a96a13e293ca1d48c2a5af686141b094bb92966d369f9dbcc8813",
|
||||
"rawBytes": 963751,
|
||||
"gzipBytes": 272797,
|
||||
"path": "houseplan-assets/houseplan-card-7JITXtyy.js",
|
||||
"sha256": "663801a4536057db0e907a740e0cc96d01feabc475a3e7a9b60567259aef7fb2",
|
||||
"rawBytes": 963878,
|
||||
"gzipBytes": 272826,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-nY6CPgRE.js",
|
||||
"houseplan-assets/editor-Btuj24RH.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-CztWrxSd.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js"
|
||||
"houseplan-assets/de-DMfFz19N.js",
|
||||
"houseplan-assets/editor-36HAh3Je.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BuN48ldr.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-CztWrxSd.js",
|
||||
"sha256": "ac4ed4d1f057b7bae3ca52141d71beb81fd0ff971fc81e28d71073ad9bd5a5b2",
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BuN48ldr.js",
|
||||
"sha256": "e05365fb1ce4c1d97cacba2b243d07b9ecb4203d79596ba022096de3356eda5d",
|
||||
"rawBytes": 522033,
|
||||
"gzipBytes": 134930,
|
||||
"gzipBytes": 134939,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js",
|
||||
"sha256": "9094f910509b9881e8d7882a9ad1855e39610da15a2a163088af4d1e96c8687f",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js",
|
||||
"sha256": "cf09b5cf51ed2220e4afd6b9523a66d013764eb0a68d1be1bbce8083fd5516d9",
|
||||
"rawBytes": 26195,
|
||||
"gzipBytes": 6497,
|
||||
"gzipBytes": 6498,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "cdd74054b0eda637b8e8184c96291b395fd558678f8e55af673931615e01b085",
|
||||
"sha256": "2c76779b5485023d77e090cee3a9a59a5c558c60e30c7b25ed0b3bb3e34fa05e",
|
||||
"rawBytes": 1089,
|
||||
"gzipBytes": 754,
|
||||
"gzipBytes": 755,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";import{c as e,l as o,t,cZ as s,A as a,c_ as i,c$ as l,d0 as n,E as r,b as c}from"./houseplan-card-z66sNkRH.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__="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";import{c as e,l as o,t,cZ as s,A as a,c_ as i,c$ as l,d0 as n,E as r,b as c}from"./houseplan-card-7JITXtyy.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";import{bT as t,bU as s,bV as e,bW as o,aq as a,bX as l,c0 as i,bY as h,bZ as c,b_ as n,b$ as r,A as p,b as _,cR as d,ap as u,ar as g,cS as m}from"./houseplan-card-z66sNkRH.js";import{i as b,c as $,e as v,r as f,a as y,b as w,s as D,t as S}from"./backdrop-pick-Tyu0BfFF.js";const k=1e3,C=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},M="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";class F{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_openSpaceDialog(p,_){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===p){const i=this.host._serverCfg.spaces.find(t=>t.id===_);if(!i)return;const h=t(i),c=i.settings?.custom_fill&&"object"==typeof i.settings.custom_fill?s(i.settings.custom_fill):null,n="none"===h.fill?{...c||e,a:0}:c;return void(this.host._spaceDialog={mode:p,spaceId:_,title:i.title,planUrl:i.plan_url||null,planFile:null,source:i.plan_url?"file":"draw",showBorders:h.showBorders,showNames:h.showNames,zeroWallStyle:l(i),displayTouched:!0,hideDecor:h.hideDecor,hideOpenings:h.hideOpenings,roomColor:h.color,roomOpacity:h.opacity,fillMode:"none"===h.fill?"custom":h.fill,customFill:n,glowEnabled:h.glow,bgColor:h.bgColor,bgMode:"static"===i.settings?.bg_mode||"daynight"===i.settings?.bg_mode?i.settings.bg_mode:null,northDeg:a({},i.settings),sunRays:"boolean"==typeof i.settings?.sun_rays?i.settings.sun_rays:null,tempMin:h.tempMin,tempMax:h.tempMax,showLqi:h.showLqi??this.host._config?.show_signal??!0,cardFontScale:h.cardFontScale,labelTemp:h.labelTemp,labelHum:h.labelHum,labelLqi:h.labelLqi,labelLight:h.labelLight,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,cellCmInput:o(Number(i.cell_cm)>0?Number(i.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const d=i(this.host._imperial);this.host._spaceDialog={mode:p,title:"",planUrl:null,planFile:null,...b(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:r,roomOpacity:n,fillMode:"custom",customFill:{...e,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:c,tempMax:h,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:d,cellCmInput:o(d,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await $(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await v(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return f(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??p}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){if(confirm(this.host._t("confirm.delete_plan",{name:t})))try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return _`<div class="savedplans muted">${this.host._t("space.loading")}</div>`;const s=t.saved||[];if(!s.length)return _`<div class="savedplans muted">${this.host._t("space.no_saved")}</div>`;return _`<div class="savedplans">
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";import{bT as t,bU as s,bV as e,bW as o,aq as a,bX as l,c0 as i,bY as h,bZ as c,b_ as n,b$ as r,A as p,b as _,cR as d,ap as u,ar as g,cS as m}from"./houseplan-card-7JITXtyy.js";import{i as b,c as $,e as v,r as f,a as y,b as w,s as D,t as S}from"./backdrop-pick-B3oldFOv.js";const k=1e3,C=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},M="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";class F{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_openSpaceDialog(p,_){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===p){const i=this.host._serverCfg.spaces.find(t=>t.id===_);if(!i)return;const h=t(i),c=i.settings?.custom_fill&&"object"==typeof i.settings.custom_fill?s(i.settings.custom_fill):null,n="none"===h.fill?{...c||e,a:0}:c;return void(this.host._spaceDialog={mode:p,spaceId:_,title:i.title,planUrl:i.plan_url||null,planFile:null,source:i.plan_url?"file":"draw",showBorders:h.showBorders,showNames:h.showNames,zeroWallStyle:l(i),displayTouched:!0,hideDecor:h.hideDecor,hideOpenings:h.hideOpenings,roomColor:h.color,roomOpacity:h.opacity,fillMode:"none"===h.fill?"custom":h.fill,customFill:n,glowEnabled:h.glow,bgColor:h.bgColor,bgMode:"static"===i.settings?.bg_mode||"daynight"===i.settings?.bg_mode?i.settings.bg_mode:null,northDeg:a({},i.settings),sunRays:"boolean"==typeof i.settings?.sun_rays?i.settings.sun_rays:null,tempMin:h.tempMin,tempMax:h.tempMax,showLqi:h.showLqi??this.host._config?.show_signal??!0,cardFontScale:h.cardFontScale,labelTemp:h.labelTemp,labelHum:h.labelHum,labelLqi:h.labelLqi,labelLight:h.labelLight,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,cellCmInput:o(Number(i.cell_cm)>0?Number(i.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const d=i(this.host._imperial);this.host._spaceDialog={mode:p,title:"",planUrl:null,planFile:null,...b(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:r,roomOpacity:n,fillMode:"custom",customFill:{...e,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:c,tempMax:h,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:d,cellCmInput:o(d,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await $(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await v(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return f(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??p}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){if(confirm(this.host._t("confirm.delete_plan",{name:t})))try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return _`<div class="savedplans muted">${this.host._t("space.loading")}</div>`;const s=t.saved||[];if(!s.length)return _`<div class="savedplans muted">${this.host._t("space.no_saved")}</div>`;return _`<div class="savedplans">
|
||||
${s.map(s=>{return _`
|
||||
<div class="savedplan ${s.url===t.planUrl?"cur":""}">
|
||||
<img src=${this.host._display(s.url)} alt="" loading="lazy" decoding="async" />
|
||||
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";try{await import("./houseplan-assets/houseplan-card-z66sNkRH.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).":"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 entry: the main chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";try{await import("./houseplan-assets/houseplan-card-7JITXtyy.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).":"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 entry: the main chunk is unavailable",e)}
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a",
|
||||
"fingerprint": "92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js",
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 273551,
|
||||
"initialViewGzipBytes": 273581,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/de-nY6CPgRE.js",
|
||||
"houseplan-assets/editor-Btuj24RH.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-CztWrxSd.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/de-DMfFz19N.js",
|
||||
"houseplan-assets/editor-36HAh3Je.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BuN48ldr.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js"
|
||||
],
|
||||
"lazyGzipBytes": 168764,
|
||||
"lazyGzipBytes": 168780,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/editor-Btuj24RH.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-CztWrxSd.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/editor-36HAh3Je.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BuN48ldr.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 139471,
|
||||
"lazyEditorGzipBytes": 139483,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 9453,
|
||||
"lazyOnboardingGzipBytes": 9456,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-nY6CPgRE.js"
|
||||
"houseplan-assets/de-DMfFz19N.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 22796,
|
||||
"lazyLocaleGzipBytes": 22799,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"sha256": "db0d4c348fee148aff02781bfb2c1d0fa4afb50b7f7c7670768b748675f5389a",
|
||||
"path": "houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"sha256": "bca0256fc222b1c3f6045a97d7a773f499701c1b9b3dcc8498c40cdd26de403b",
|
||||
"rawBytes": 6967,
|
||||
"gzipBytes": 2956,
|
||||
"gzipBytes": 2958,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-nY6CPgRE.js",
|
||||
"sha256": "1ea533abc21c2d2585941122c21212deeec234adf5099ae8afce611bc3a6cd49",
|
||||
"path": "houseplan-assets/de-DMfFz19N.js",
|
||||
"sha256": "307982665ac112914972383bbed35da47ce8e917009daa792e29119dfbe263ec",
|
||||
"rawBytes": 74836,
|
||||
"gzipBytes": 22796,
|
||||
"gzipBytes": 22799,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-Btuj24RH.js",
|
||||
"sha256": "e462de3e6a34cce0b93fabf0804a430ce81bcfd2fe6c26e65557ec65504cd964",
|
||||
"path": "houseplan-assets/editor-36HAh3Je.js",
|
||||
"sha256": "c0a8bb4c6cd7868ae5ad78b8d2ecca80e9a449f1d3c03b5c0eadb20a791a8285",
|
||||
"rawBytes": 3831,
|
||||
"gzipBytes": 1585,
|
||||
"gzipBytes": 1586,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-z66sNkRH.js",
|
||||
"sha256": "33ee209a395a96a13e293ca1d48c2a5af686141b094bb92966d369f9dbcc8813",
|
||||
"rawBytes": 963751,
|
||||
"gzipBytes": 272797,
|
||||
"path": "houseplan-assets/houseplan-card-7JITXtyy.js",
|
||||
"sha256": "663801a4536057db0e907a740e0cc96d01feabc475a3e7a9b60567259aef7fb2",
|
||||
"rawBytes": 963878,
|
||||
"gzipBytes": 272826,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-nY6CPgRE.js",
|
||||
"houseplan-assets/editor-Btuj24RH.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-CztWrxSd.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js"
|
||||
"houseplan-assets/de-DMfFz19N.js",
|
||||
"houseplan-assets/editor-36HAh3Je.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BuN48ldr.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-CztWrxSd.js",
|
||||
"sha256": "ac4ed4d1f057b7bae3ca52141d71beb81fd0ff971fc81e28d71073ad9bd5a5b2",
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BuN48ldr.js",
|
||||
"sha256": "e05365fb1ce4c1d97cacba2b243d07b9ecb4203d79596ba022096de3356eda5d",
|
||||
"rawBytes": 522033,
|
||||
"gzipBytes": 134930,
|
||||
"gzipBytes": 134939,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-G4p88P9H.js",
|
||||
"sha256": "9094f910509b9881e8d7882a9ad1855e39610da15a2a163088af4d1e96c8687f",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-DB_uoFX7.js",
|
||||
"sha256": "cf09b5cf51ed2220e4afd6b9523a66d013764eb0a68d1be1bbce8083fd5516d9",
|
||||
"rawBytes": 26195,
|
||||
"gzipBytes": 6497,
|
||||
"gzipBytes": 6498,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Tyu0BfFF.js",
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/backdrop-pick-B3oldFOv.js",
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "cdd74054b0eda637b8e8184c96291b395fd558678f8e55af673931615e01b085",
|
||||
"sha256": "2c76779b5485023d77e090cee3a9a59a5c558c60e30c7b25ed0b3bb3e34fa05e",
|
||||
"rawBytes": 1089,
|
||||
"gzipBytes": 754,
|
||||
"gzipBytes": 755,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-z66sNkRH.js"
|
||||
"houseplan-assets/houseplan-card-7JITXtyy.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";import{c as e,l as o,t,cZ as s,A as a,c_ as i,c$ as l,d0 as n,E as r,b as c}from"./houseplan-card-z66sNkRH.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__="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";import{c as e,l as o,t,cZ as s,A as a,c_ as i,c$ as l,d0 as n,E as r,b as c}from"./houseplan-card-7JITXtyy.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";import{bT as t,bU as s,bV as e,bW as o,aq as a,bX as l,c0 as i,bY as h,bZ as c,b_ as n,b$ as r,A as p,b as _,cR as d,ap as u,ar as g,cS as m}from"./houseplan-card-z66sNkRH.js";import{i as b,c as $,e as v,r as f,a as y,b as w,s as D,t as S}from"./backdrop-pick-Tyu0BfFF.js";const k=1e3,C=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},M="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";class F{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_openSpaceDialog(p,_){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===p){const i=this.host._serverCfg.spaces.find(t=>t.id===_);if(!i)return;const h=t(i),c=i.settings?.custom_fill&&"object"==typeof i.settings.custom_fill?s(i.settings.custom_fill):null,n="none"===h.fill?{...c||e,a:0}:c;return void(this.host._spaceDialog={mode:p,spaceId:_,title:i.title,planUrl:i.plan_url||null,planFile:null,source:i.plan_url?"file":"draw",showBorders:h.showBorders,showNames:h.showNames,zeroWallStyle:l(i),displayTouched:!0,hideDecor:h.hideDecor,hideOpenings:h.hideOpenings,roomColor:h.color,roomOpacity:h.opacity,fillMode:"none"===h.fill?"custom":h.fill,customFill:n,glowEnabled:h.glow,bgColor:h.bgColor,bgMode:"static"===i.settings?.bg_mode||"daynight"===i.settings?.bg_mode?i.settings.bg_mode:null,northDeg:a({},i.settings),sunRays:"boolean"==typeof i.settings?.sun_rays?i.settings.sun_rays:null,tempMin:h.tempMin,tempMax:h.tempMax,showLqi:h.showLqi??this.host._config?.show_signal??!0,cardFontScale:h.cardFontScale,labelTemp:h.labelTemp,labelHum:h.labelHum,labelLqi:h.labelLqi,labelLight:h.labelLight,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,cellCmInput:o(Number(i.cell_cm)>0?Number(i.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const d=i(this.host._imperial);this.host._spaceDialog={mode:p,title:"",planUrl:null,planFile:null,...b(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:r,roomOpacity:n,fillMode:"custom",customFill:{...e,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:c,tempMax:h,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:d,cellCmInput:o(d,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await $(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await v(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return f(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??p}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){if(confirm(this.host._t("confirm.delete_plan",{name:t})))try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return _`<div class="savedplans muted">${this.host._t("space.loading")}</div>`;const s=t.saved||[];if(!s.length)return _`<div class="savedplans muted">${this.host._t("space.no_saved")}</div>`;return _`<div class="savedplans">
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";import{bT as t,bU as s,bV as e,bW as o,aq as a,bX as l,c0 as i,bY as h,bZ as c,b_ as n,b$ as r,A as p,b as _,cR as d,ap as u,ar as g,cS as m}from"./houseplan-card-7JITXtyy.js";import{i as b,c as $,e as v,r as f,a as y,b as w,s as D,t as S}from"./backdrop-pick-B3oldFOv.js";const k=1e3,C=t=>{if(!t.trim())return null;const s=Number(t.replace(",","."));return Number.isFinite(s)?s:null},M="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";class F{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_openSpaceDialog(p,_){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===p){const i=this.host._serverCfg.spaces.find(t=>t.id===_);if(!i)return;const h=t(i),c=i.settings?.custom_fill&&"object"==typeof i.settings.custom_fill?s(i.settings.custom_fill):null,n="none"===h.fill?{...c||e,a:0}:c;return void(this.host._spaceDialog={mode:p,spaceId:_,title:i.title,planUrl:i.plan_url||null,planFile:null,source:i.plan_url?"file":"draw",showBorders:h.showBorders,showNames:h.showNames,zeroWallStyle:l(i),displayTouched:!0,hideDecor:h.hideDecor,hideOpenings:h.hideOpenings,roomColor:h.color,roomOpacity:h.opacity,fillMode:"none"===h.fill?"custom":h.fill,customFill:n,glowEnabled:h.glow,bgColor:h.bgColor,bgMode:"static"===i.settings?.bg_mode||"daynight"===i.settings?.bg_mode?i.settings.bg_mode:null,northDeg:a({},i.settings),sunRays:"boolean"==typeof i.settings?.sun_rays?i.settings.sun_rays:null,tempMin:h.tempMin,tempMax:h.tempMax,showLqi:h.showLqi??this.host._config?.show_signal??!0,cardFontScale:h.cardFontScale,labelTemp:h.labelTemp,labelHum:h.labelHum,labelLqi:h.labelLqi,labelLight:h.labelLight,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,cellCmInput:o(Number(i.cell_cm)>0?Number(i.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const d=i(this.host._imperial);this.host._spaceDialog={mode:p,title:"",planUrl:null,planFile:null,...b(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:r,roomOpacity:n,fillMode:"custom",customFill:{...e,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:c,tempMax:h,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:d,cellCmInput:o(d,this.host._imperial),cellCmTouched:!1,busy:!1}}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await $(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await v(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return f(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??p}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){if(confirm(this.host._t("confirm.delete_plan",{name:t})))try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return _`<div class="savedplans muted">${this.host._t("space.loading")}</div>`;const s=t.saved||[];if(!s.length)return _`<div class="savedplans muted">${this.host._t("space.no_saved")}</div>`;return _`<div class="savedplans">
|
||||
${s.map(s=>{return _`
|
||||
<div class="savedplan ${s.url===t.planUrl?"cur":""}">
|
||||
<img src=${this.host._display(s.url)} alt="" loading="lazy" decoding="async" />
|
||||
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2f53621bc0d0f8ce3e04153700c0c17286b37d4dae42519acf74d6023333442a";try{await import("./houseplan-assets/houseplan-card-z66sNkRH.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).":"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 entry: the main chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="92b6c0d37be41565c819aabf24176ece7969b13a5fd56613d47138f26080f773";try{await import("./houseplan-assets/houseplan-card-7JITXtyy.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).":"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 entry: the main chunk is unavailable",e)}
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- A gate or door bound to a position-reporting cover no longer stutters the
|
||||
whole card while it moves: the light cut through the opening now steps on a
|
||||
5% grid, cutting the heavy geometry recomputes from about a hundred per
|
||||
cycle to at most twenty
|
||||
([#366](https://github.com/Matysh/houseplan-card/issues/366)).
|
||||
|
||||
- Furniture outline width now follows plan zoom like the same physical width
|
||||
on lines and shapes, while independent width/depth resizing still keeps
|
||||
horizontal, vertical and diagonal strokes equally thick
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- Ворота или дверь на cover-сущности с позицией больше не дёргают карточку
|
||||
во время движения: световой вырез проёма ступает по сетке 5%, и тяжёлых
|
||||
пересчётов геометрии вместо ~сотни за цикл — не больше двадцати
|
||||
([#366](https://github.com/Matysh/houseplan-card/issues/366)).
|
||||
|
||||
- Толщина контура мебели теперь меняется вместе с масштабом плана, как та же
|
||||
физическая толщина у линий и фигур, а независимое изменение ширины и глубины
|
||||
предмета по-прежнему не искажает горизонтальные, вертикальные и диагональные
|
||||
|
||||
@@ -139,7 +139,10 @@ pass over the layer costs a fifth of one blurred mask per source.
|
||||
## Caching
|
||||
|
||||
Barriers are keyed by their geometry fingerprint plus a compact, sorted
|
||||
signature of bound interior door/gate opening amounts, never by `_cfgEpoch`:
|
||||
signature of bound interior door/gate opening amounts (quantised to the
|
||||
0.05 grid of `OPENING_LIGHT_AMOUNT_QUANTUM`, #366 — a moving cover steps the
|
||||
light in 5% increments instead of forcing a recompute per percent), never by
|
||||
`_cfgEpoch`:
|
||||
the epoch lags behind geometry edited in place, and a stale barrier set is
|
||||
invisible — the plan simply keeps lighting through a wall or closed door that
|
||||
now exists. Unrelated HA updates preserve the signature and hit the bounded
|
||||
|
||||
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 343 KiB |
|
Before Width: | Height: | Size: 327 KiB After Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 289 KiB After Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 317 KiB |
|
Before Width: | Height: | Size: 290 KiB After Width: | Height: | Size: 296 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 141 KiB |
@@ -3,7 +3,7 @@
|
||||
"fixture": "synthetic-only",
|
||||
"chromium": "151.0.7922.34",
|
||||
"oxipng": null,
|
||||
"sourceFingerprint": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"sourceFingerprint": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"captureScriptSha256": "fe76c8e2e27501e9a377d7aa15dd6cba6a018d55c07deb602dbee097f0a0a5ba",
|
||||
"command": "npm run build && node demo/docs/capture.mjs",
|
||||
"scenarios": {
|
||||
@@ -15,8 +15,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "36223106c073f07d8cc3ecf8eaab37192ebb2687daba65c5c21047d0b7890de0"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "0ca982495a7749907c48ebbddfd089c54385a4347f79f64e94af2c5a8d5c03eb"
|
||||
},
|
||||
"view-touch": {
|
||||
"file": "02-view-touch.png",
|
||||
@@ -26,8 +26,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "a4aa3af48578ee41594a9b1a6e98b4d39f3324a949a9fd9e63d5854576d5db85"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "3be239a5a494f6776540a9c0049694ee6f9d2ba927c8bcb4b26ee5a69a228a7d"
|
||||
},
|
||||
"space-create": {
|
||||
"file": "03-space-create.png",
|
||||
@@ -37,8 +37,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "0dc024726327f60f4a9ceaf3044381691f81f1090af81d1812e870f22d9343ba"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "a55b463055a565892ca139014e314a8f63fb5301c87fff2e48d7e69210fe9b6c"
|
||||
},
|
||||
"room-contour-close": {
|
||||
"file": "04-room-contour-close.png",
|
||||
@@ -48,8 +48,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "44cfaa95bd51e2cd628400e28db0ad8b2f0cd904385845bd402494f3f5c0d93c"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "dfad9a27371cfa397a3fd8dce7005f42d24649743f5322105ee894067d3a9f16"
|
||||
},
|
||||
"plan-context-tray": {
|
||||
"file": "05-plan-context-tray.png",
|
||||
@@ -59,8 +59,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "e0662429b423fb74151b583dcc2c8635b001b637d03bbf7a6b16aec46399c3f8"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "b75f348c632296da5c2fc142d53df613f757e1516acac315be50f5b4557729cc"
|
||||
},
|
||||
"device-editor": {
|
||||
"file": "06-device-editor.png",
|
||||
@@ -70,8 +70,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "2f861b3e0f3e09cbe462873887fc6a4412940393d37d782bcd0be58c9e82879e"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "8affadfce926fe2f6cf344c33f611c44fcbc79c1969f69c3a6935ff2e99c36c3"
|
||||
},
|
||||
"device-display-preview": {
|
||||
"file": "06-device-display-preview.png",
|
||||
@@ -81,8 +81,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "2cdabae1f89c3286e4fac0ce30f757ee1690b707ab8a5488748b7cd420626160"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "6d323b6f641b2cc7db64252f70567348bd3f2551f82e61fd3a2b4674d244918e"
|
||||
},
|
||||
"background-editor": {
|
||||
"file": "07-background-editor.png",
|
||||
@@ -92,8 +92,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "30147bb00a90eea7136b4cee30995f6e6a9217b5132f3e8d3ad7471413b1af8a"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "a1d1a905f1410f73231d2ea5d1dfbd8ae79c2fe8b0a79cff87ebb977ac7a3103"
|
||||
},
|
||||
"room-card": {
|
||||
"file": "08-room-card.png",
|
||||
@@ -103,8 +103,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "029a3e69ec647a8a370d99e6bb7f9225833c526739076022f6b52ba54bff30ea"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "48a5685039a5e0de2a28190d857b193c86e2e63606e3c7a8c40fc9d2b190da4e"
|
||||
},
|
||||
"device-info": {
|
||||
"file": "09-device-info.png",
|
||||
@@ -114,8 +114,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "efd6edaeba9496509727bec13d19495b799339bdfe2176c791d3abcee83f45a5",
|
||||
"imageSha256": "dd492f53150b7149085daada5cce9eeae9bde9e7ea1d86679a54b3041f72f517"
|
||||
"sourceSha256": "d02374a4194e4601cb0a2047dc556f70b9fdf354894bdfeea9288d74c14742d8",
|
||||
"imageSha256": "29a342811aaedaebc54ba337792d60cb454a7cf4c3063b210f6c4bafe0a4d87b"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
# CODE-REVIEW-366-r1
|
||||
|
||||
Issue: #366 · «Glow #20: движущиеся ворота на cover-сущности вызывают до ~100
|
||||
пересчётов геометрии света за одно открытие»
|
||||
Этап: code · заход r1 · блокирующих циклов 0/2 (light track — бюджет 2 цикла)
|
||||
SHA ревью: `51657831e6c0a00336a099795943b9f002f1455f` (HEAD ветки
|
||||
`issue/366-cover-glow-quantum`, диапазон `origin/dev...HEAD`)
|
||||
ТЗ: тело issue #366, ревизия 2 (принята SPEC-REVIEW-366-r2, зелёный вердикт,
|
||||
0 Medium)
|
||||
|
||||
## Скоуп
|
||||
|
||||
Один коммит, класс A+B+C+D:
|
||||
|
||||
- `src/logic.ts` — новая константа `OPENING_LIGHT_AMOUNT_QUANTUM = 0.05` и
|
||||
чистая функция `quantizeOpeningLightAmount`.
|
||||
- `src/houseplan-card.ts` — импорт функции и её применение в **единственной**
|
||||
точке сборки `passageStates` (:10381), которая питает и сигнатуру барьеров
|
||||
(:10383-10387), и длину светового выреза (:10408, :10420-10423).
|
||||
- `test/logic.test.mjs` — новый юнит на границы/зажимы/узлы + свип 0..1 через
|
||||
`openingLightStateSignature`.
|
||||
- `scripts/mutation-gate.mjs` — новый мутант `opening-light-quantum-identity`
|
||||
(квант → identity), guard `--test-name-pattern="#366"`.
|
||||
- `docs/LIGHT.md` §Caching — упоминание сетки 0.05.
|
||||
- `docs/CHANGELOG.md` / `docs/CHANGELOG.ru.md` — запись в `## Unreleased`
|
||||
в том же коммите, `User-Visible: yes` соблюдён.
|
||||
- `docs/images/*` + `screenshots.json` — пересчитанный `sourceFingerprint`
|
||||
из-за правки `src/**` (механический след check-docs, не отдельная работа).
|
||||
- `dist/**`, `custom_components/houseplan/frontend/**` — синхронный бандл.
|
||||
|
||||
Никакой геометрии комнат/стен, `layout`, `marker.space`, `open_spans` diff не
|
||||
трогает — инварианты модели (#254) на этот PR не применимы.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
Прогнано лично на этом SHA (зелёного Validate на SHA `51657831` нет):
|
||||
|
||||
| Гейт | Команда | Результат |
|
||||
|---|---|---|
|
||||
| Typecheck | `npm run typecheck` | зелёный, без вывода |
|
||||
| Юниты | `npm test` | `1534/0`, `skipped 1` — совпадает с заявленным в комментарии автора |
|
||||
| Целевой юнит | `node --test --test-name-pattern="#366" test/logic.test.mjs` | 1/1 зелёный |
|
||||
| Мутант (умеет падать) | `node scripts/mutation-gate.mjs --id=opening-light-quantum-identity` | `тест покраснел, как обязан` — AC5 подтверждён исполнением, не начитыванием |
|
||||
| Сборка | `npm run build` | зелёная |
|
||||
| Синхронность бандла | `npm run bundle:sync` затем `git status --porcelain` | пусто — `dist`, `custom_components/houseplan/frontend`, `demo/srv/assets` совпадают байт-в-байт с уже закоммиченным |
|
||||
| Документация | `node scripts/check-docs.mjs` | `Documentation checks passed (7 files, 10 external links)` — обязателен, т.к. diff трогает `src/**` |
|
||||
| Выбор смоков | `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | «Прямое совпадение (2)»: `smoke_opening_binding.mjs`, `smoke_registryless_opening.mjs` (символ `_openingAmt`) |
|
||||
| Смок (AC4, названный автором) | `node demo/smoke_glow.mjs` | зелёный, все проверки `true`/`OK` |
|
||||
| Смок (прямое совпадение) | `node demo/smoke_opening_binding.mjs` | зелёный |
|
||||
| Смок (прямое совпадение) | `node demo/smoke_registryless_opening.mjs` | зелёный |
|
||||
| Видимый рендер | `npm run golden:verify` (после свежего build+bundle:sync) | все сценарии `passed`, 0 упоминаний fail; включая `lighting-opaque-glow-two-doorways-dark`, где `cover.golden_door_half` стоит на `current_position: 50` — точный узел сетки 0.05, изображение не сдвинулось |
|
||||
| Single-source-numbers | `node --test test/single-source-numbers.test.mjs` | зелёный (не относится напрямую к правке, но затронутое число — amount, видимое дважды — проверено ниже отдельно) |
|
||||
|
||||
Не прогонял и почему:
|
||||
- **Полный набор `demo/smoke_*.mjs`** — smoke-select не назвал ничего сверх
|
||||
двух прямых совпадений плюс явно названный автором `smoke_glow.mjs`; diff —
|
||||
одна точка применения чистой функции, не новая подсистема. Все три
|
||||
релевантных смока зелёные.
|
||||
- **`npm run invariants`** — diff не трогает рёбра/толщину/layout/ссылки.
|
||||
- **`python -m pytest tests_backend`** — diff не трогает `custom_components/**/*.py`
|
||||
(единственный неродственный провал в моей среде — `backend-test-guard.mjs`
|
||||
внутри полного прогона mutation-gate, `No module named pytest`; это
|
||||
окружение без backend-venv, не относится к этой задаче, диагностировано и
|
||||
отброшено).
|
||||
- **`performance_smoke`** — не назван в AC, задача не меняет измеряемый в нём
|
||||
путь напрямую (только уменьшает частоту его срабатывания); предрелизный
|
||||
гейт прогонит его на полном наборе.
|
||||
- Полный `node scripts/mutation-gate.mjs` (без `--id=`) не гонял целиком —
|
||||
дорогой предрелизный гейт; целевой мутант прогнан отдельно и это то, что
|
||||
доказывает AC5.
|
||||
|
||||
## Находки
|
||||
|
||||
Ни одной. High: 0, Medium: 0.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
**К1 (один квант, один источник).** `quantizeOpeningLightAmount` — чистая
|
||||
функция: `NaN`→0 (через `Number.isFinite` guard), зажим в `[0,1]` до и после
|
||||
округления, округление к ближайшему узлу сетки 0.05. 0 и 1 — точные узлы
|
||||
арифметически (`0/0.05=0`, `1/0.05=20` — целые), не требуют отдельного кейса.
|
||||
Применена **ровно в одной** точке — `houseplan-card.ts:10381`, при сборке
|
||||
`passageStates`; это единственный производитель, который читает и сигнатура
|
||||
(:10383-10387), и вырез (:10408 `openingLightApertureLength`, :10420-10423
|
||||
`lightPartitionCuts`) — по построению не могут разойтись (single-source
|
||||
принцип соблюдён: amount виден дважды — в сигнатуре кэша и в геометрии, — но
|
||||
у обоих ровно один источник, сама переменная `amount` в замыкании
|
||||
`flatMap`). Другие потребители `_openingAmt` — `:8835` (изометрия),
|
||||
`:12494`, `:12615` (рендер створки/подписи) — не квантуются, что и требовал
|
||||
контракт («анимация створки остаётся плавной»); проверено чтением всех
|
||||
вызовов `_openingAmt` в файле (4 сайта, один изменён).
|
||||
|
||||
**К2 (≤21 сигнатура).** Математически: узлов сетки 0.05 на `[0,1]` ровно 21
|
||||
(0, 0.05, …, 1.00). Юнит-свип шагом 0.001 подтверждает исполнением, не
|
||||
только по построению.
|
||||
|
||||
**AC1** — юнит на границы/зажимы/узлы — присутствует и зелёный, воспроизвёл
|
||||
локально.
|
||||
|
||||
**AC2** — свип-юнит на ≤21 сигнатуру — присутствует, зелёный, воспроизвёл;
|
||||
дополнительно проверил, что мутант «квант→identity» красит именно этот
|
||||
ассерт (`тест покраснел, как обязан`).
|
||||
|
||||
**AC3** (binary-двери байт-в-байт) — юнит фиксирует точные строки
|
||||
`door:0.000` / `door:1.000` и то, что `quantizeOpeningLightAmount(1)` даёт ту
|
||||
же сигнатуру, что и неквантованная `1`. Формат сигнатуры (`toFixed(3)`,
|
||||
`logic.ts:371`) не менялся.
|
||||
|
||||
**AC4** (существующие смоки/golden #20 зелёные без правки ассертов) —
|
||||
`smoke_glow.mjs`, `golden:verify` (полный набор, включая сценарий с cover на
|
||||
50%) зелёные; ни один ассерт в этих файлах не тронут diff'ом (проверено —
|
||||
diff не касается `demo/**` кроме `mutation-gate.mjs`).
|
||||
|
||||
**AC5** (мутант красит юнит) — прогнан лично, поймано 1/1.
|
||||
|
||||
**Трейлеры и changelog.** `Issue: #366`, `User-Visible: yes` на коммите;
|
||||
`docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md` правлены в этом же коммите —
|
||||
требование §Commits соблюдено. Формулировки на пользовательском языке («не
|
||||
дёргают карточку», «ступает по сетке 5%») без утечки реализации.
|
||||
|
||||
**docs/LIGHT.md** — Low из спек-ревью (r1-L2/r2-L2′: сетка квантования
|
||||
должна попасть в LIGHT.md тем же коммитом) закрыт: §Caching описывает сетку
|
||||
0.05 и ссылку на #366.
|
||||
|
||||
**Продуктовая рамка.** Правка обслуживает J1 (живой обзор состояния дома) —
|
||||
устраняет визуальные подёргивания всей карточки на wall-планшете во время
|
||||
движения ворот, что прямо противоречит "at a glance" ценности продукта.
|
||||
Скоуп не расширен: чистая квантовая функция в одной точке конвейера, ничего
|
||||
геометрического или конфигурационного не тронуто. Решение (квант 0.05, а не
|
||||
debounce) — принятое предположение спек-ревью r1-M2, с ценой отката в одну
|
||||
константу; реализация не отступает от контракта ТЗ.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Ручного тестирования на реальном wall-планшете нет (не входит в цикл ревью);
|
||||
визуальная неразличимость шага 5% принята как предположение ещё на этапе
|
||||
спеки (r1-M2), не переоценивается здесь заново — это продуктовый вопрос,
|
||||
а не технический.
|
||||
- Не мерил фактическое число пересчётов на живом cover со стрим-обновлениями
|
||||
позиции (нет интеграционного стенда HA) — К2 доказан математически и
|
||||
юнит-свипом, что признано в ТЗ достаточным доказательством (юнит вместо
|
||||
browser-профиля).
|
||||
- Полный `demo/smoke_*.mjs` (201 файл) и `performance_smoke` — не прогонял,
|
||||
обоснование выше в разделе «Как проверялось».
|
||||
- `tests_backend` — не прогонял, diff не трогает Python.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. Технический контракт реализован ровно как специфицирован в ревизии
|
||||
2 ТЗ, все AC доказаны исполнением (не только чтением), затронутые смоки и
|
||||
golden зелёные, трейлеры и changelog на месте, бандл синхронен.
|
||||
@@ -680,6 +680,18 @@ const MUTANT_DEFINITIONS = [
|
||||
replace: ' this._languageFailureUnsub = undefined;',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'opening-light-quantum-identity',
|
||||
guard: 'node --test --test-name-pattern="#366" test/logic.test.mjs',
|
||||
because: 'an identity quantum brings back ~100 barrier recomputes per moving-gate cycle — '
|
||||
+ 'the sweep unit must bound distinct signatures to the 0.05 grid (#366)',
|
||||
patches: [{
|
||||
file: 'src/logic.ts',
|
||||
find: ' return Math.min(1, Math.max(0,\n'
|
||||
+ ' Math.round(safe / OPENING_LIGHT_AMOUNT_QUANTUM) * OPENING_LIGHT_AMOUNT_QUANTUM));',
|
||||
replace: ' return safe;',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'backdrop-probe-always-safe',
|
||||
guard: 'node demo/smoke_backdrop_guard.mjs',
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
pointOnBoundary, mergeRooms, splitRoomPath, polygonArea, closestPointOnBoundary, pointStrictlyInside as ptInside, islandsOf, sharedBoundary, distToSegment, outlineWithout, cutSegments, alignGuides, segmentAngle, is45, isExact45Vector, type AlignGuide, swipeTarget, clampScale, migratePdfUrls, roomFillModeOf, roomGlowOf, contentUrl,
|
||||
snapToWall, snapPointAlongPoly, openingAmount, openingShoulders, interiorPoint,
|
||||
isInteriorLightOpeningType, openingLightApertureLength, openingLightStateSignature,
|
||||
quantizeOpeningLightAmount,
|
||||
openingEntityReferences, filterOpeningEntityCandidates,
|
||||
poleOfInaccessibility, subst,
|
||||
averageLqi, fitView, declump, safeUrl, floorsOf, type FloorInfo,
|
||||
@@ -10375,7 +10376,9 @@ export class HouseplanCard extends LitElement {
|
||||
const ny = Math.cos(rad);
|
||||
const interior = onFloor([o.rx + nx * probe, o.ry + ny * probe])
|
||||
&& onFloor([o.rx - nx * probe, o.ry - ny * probe]);
|
||||
return interior ? [{ opening: o, amount: this._openingAmt(o) }] : [];
|
||||
// #366: the light pipeline consumes the quantised amount — the door
|
||||
// LEAF animation stays smooth (_openingAmt elsewhere), only light steps.
|
||||
return interior ? [{ opening: o, amount: quantizeOpeningLightAmount(this._openingAmt(o)) }] : [];
|
||||
});
|
||||
const openingStateSignature = openingLightStateSignature(
|
||||
passageStates.map(({ opening, amount }) => ({
|
||||
|
||||
@@ -342,6 +342,22 @@ export interface OpeningLightStateEntry {
|
||||
amount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* #366: one grid for the light pipeline's aperture amount. A moving cover
|
||||
* publishes current_position by the percent; unquantised it forces a full
|
||||
* barrier recompute per tick (~100 per gate cycle). Both the signature AND
|
||||
* the cut geometry consume the same quantised value, so the cache key and
|
||||
* the drawn aperture agree by construction. 0 and 1 are exact grid nodes —
|
||||
* binary contact doors are byte-identical to the pre-#366 behaviour.
|
||||
*/
|
||||
export const OPENING_LIGHT_AMOUNT_QUANTUM = 0.05;
|
||||
|
||||
export function quantizeOpeningLightAmount(amount: number): number {
|
||||
const safe = Number.isFinite(amount) ? Math.max(0, Math.min(1, amount)) : 0;
|
||||
return Math.min(1, Math.max(0,
|
||||
Math.round(safe / OPENING_LIGHT_AMOUNT_QUANTUM) * OPENING_LIGHT_AMOUNT_QUANTUM));
|
||||
}
|
||||
|
||||
/** State-only identity for interior light apertures. Structural geometry is
|
||||
* fingerprinted separately, so unrelated HA updates cannot evict barriers. */
|
||||
export function openingLightStateSignature(
|
||||
|
||||
@@ -24,7 +24,9 @@ import {
|
||||
normalizeDeviceDisplay, isAlarmCapable,
|
||||
liveText, liveTextValue, liveTextReference, liveTextToken,
|
||||
hassValue, valueWithUnit, decorTextScale, decorTextLines,
|
||||
LIVE_TEXT_DASH, LIVE_TEXT_VALUE_MAX, DECOR_TEXT_SCALE_MIN, DECOR_TEXT_SCALE_MAX } from '../test-build/logic.js';
|
||||
LIVE_TEXT_DASH, LIVE_TEXT_VALUE_MAX, DECOR_TEXT_SCALE_MIN, DECOR_TEXT_SCALE_MAX,
|
||||
quantizeOpeningLightAmount,
|
||||
} from '../test-build/logic.js';
|
||||
import {
|
||||
iconFor, compileIconRules, isValidPattern, iconFromDeviceClasses,
|
||||
} from '../test-build/rules.js';
|
||||
@@ -1530,3 +1532,37 @@ test('liveTextValue: a formatter that omits the unit still gets one (the demo st
|
||||
assert.equal(liveTextValue(h, { entity: 'sensor.tank' }), '68 %',
|
||||
'formatEntityState returning a bare state must not cost the label its unit');
|
||||
});
|
||||
|
||||
test('квант amount света: границы, узлы и ≤21 сигнатура за полный ход (#366)', () => {
|
||||
// AC1: точные узлы и зажимы
|
||||
assert.equal(quantizeOpeningLightAmount(0), 0);
|
||||
assert.equal(quantizeOpeningLightAmount(1), 1);
|
||||
assert.equal(quantizeOpeningLightAmount(NaN), 0);
|
||||
assert.equal(quantizeOpeningLightAmount(-1), 0);
|
||||
assert.equal(quantizeOpeningLightAmount(2), 1);
|
||||
assert.equal(quantizeOpeningLightAmount(0.30), quantizeOpeningLightAmount(0.31), 'один узел');
|
||||
assert.notEqual(quantizeOpeningLightAmount(0.30), quantizeOpeningLightAmount(0.33), 'разные узлы');
|
||||
|
||||
// AC2: свип 0..1 шагом 0.001 через сигнатуру — не больше 21 различной
|
||||
const signatures = new Set();
|
||||
for (let step = 0; step <= 1000; step++) {
|
||||
const amount = quantizeOpeningLightAmount(step / 1000);
|
||||
signatures.add(openingLightStateSignature([
|
||||
{ id: 'gate', type: 'gate', contact: 'cover.gate', amount },
|
||||
]));
|
||||
}
|
||||
assert.ok(signatures.size <= 21, `сигнатур ${signatures.size}, ожидалось ≤21`);
|
||||
|
||||
// конечные положения совпадают с неквантованными (binary-регресс, AC3)
|
||||
const closed = openingLightStateSignature([
|
||||
{ id: 'door', type: 'door', contact: 'binary_sensor.d', amount: 0 },
|
||||
]);
|
||||
const open = openingLightStateSignature([
|
||||
{ id: 'door', type: 'door', contact: 'binary_sensor.d', amount: 1 },
|
||||
]);
|
||||
assert.equal(closed, 'door:0.000');
|
||||
assert.equal(open, 'door:1.000');
|
||||
assert.equal(openingLightStateSignature([
|
||||
{ id: 'door', type: 'door', contact: 'binary_sensor.d', amount: quantizeOpeningLightAmount(1) },
|
||||
]), open, 'квант единицы байт-в-байт');
|
||||
});
|
||||
|
||||