`}get _glowRadiusCm(){const t=Number(this._settings.glow_radius_cm);return Number.isFinite(t)&&t>0?t:300}get _imperial(){return"mi"===this.hass?.config?.unit_system?.length}get _glowRadiusPlaceholder(){const t=this._glowRadiusCm;return this._imperial?String(Math.round(t/30.48*10)/10):String(t/100)}_glowTransition(t,e){let i=this._glowRenderedSources.get(t);if(e){const e=this._glowFadeTimers.get(t);if(null!=e&&(clearTimeout(e),this._glowFadeTimers.delete(t)),null==i){this._suspendGlowFeatherForTransition(),i=++this._glowSourceSeq,this._glowRenderedSources.set(t,i),this._glowEnteringSources.add(t);const e=requestAnimationFrame(()=>{this._glowEnterRafs.get(t)===e&&(this._glowEnterRafs.delete(t),this._glowEnteringSources.delete(t),this.isConnected&&this.requestUpdate())});this._glowEnterRafs.set(t,e)}return{domId:i,entering:this._glowEnteringSources.has(t),leaving:!1}}if(null==i)return null;const s=this._glowEnterRafs.get(t);if(null!=s&&cancelAnimationFrame(s),this._glowEnterRafs.delete(t),this._glowEnteringSources.delete(t),!this._glowFadeTimers.has(t)){this._suspendGlowFeatherForTransition();const e=window.setTimeout(()=>{this._glowFadeTimers.get(t)===e&&(this._glowFadeTimers.delete(t),this._glowRenderedSources.delete(t),this._glowLastAppearance.delete(t),this.isConnected&&this.requestUpdate())},534);this._glowFadeTimers.set(t,e)}return{domId:i,entering:!1,leaving:!0}}_suspendGlowFeatherForTransition(){if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;this._glowFeatherSuspendUntil=Math.max(this._glowFeatherSuspendUntil,Date.now()+500),clearTimeout(this._glowFeatherResumeTimer);const t=Math.max(0,this._glowFeatherSuspendUntil-Date.now())+17,e=()=>{this._glowFeatherResumeTimer=0,Date.now()=128){const t=this._glowGeometryWarnings.values().next().value;t&&this._glowGeometryWarnings.delete(t)}this._glowGeometryWarnings.add(n),console.warn(`HOUSEPLAN GLOW GEOMETRY FALLBACK: #218, space ${t}, room ${i}, phase ${s}`)}}_lightBarriers(t,e){const i=this._openPairs().flatMap(t=>t.segs),s=[...i],n=Math.max(this._cmToUnits(10),.5*this._gridPitch),o=t=>e.some(e=>this._pointInRoom(t,e.r)),a=this._openingsR.filter(t=>{if("door"!==(e=String(t.type))&&"gate"!==e&&"passage"!==e)return!1;var e;const i=t.angle*Math.PI/180,s=-Math.sin(i),a=Math.cos(i);return o([t.rx+s*n,t.ry+a*n])&&o([t.rx-s*n,t.ry-a*n])}),r=this._roomWallOpeningInputs(a,t);for(const t of r){const e=t.angle*Math.PI/180,i=Math.cos(e)*t.length/2,n=Math.sin(e)*t.length/2;s.push([t.x-i,t.y-n,t.x+i,t.y+n])}const l=new Set(a.filter(t=>t.partitionHost).map(t=>t.id)),c=[t.id,this._cfgEpoch,this._cellCm,this._gridPitch,[...l].sort().join(",")].join("|");this._lightPhysicalBodiesCache?.key!==c&&(this._lightPhysicalBodiesCache={key:c,all:Dc(t,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(t,t=>l.has(t.id))).all});const h=this._lightPhysicalBodiesCache.all;let d=2166136261;const p=t=>{d^=Math.round(64*(Number.isFinite(t)?t:0)),d=Math.imul(d,16777619)>>>0},u=this._spaceWalls;p(this._cellCm),p(this._gridPitch),p(this._wallKeyPitch);for(const{poly:t}of e){p(t.length);for(const e of t)p(e[0]),p(e[1])}for(const t of s)for(const e of t)p(e);for(const t of h){p(t.length);for(const e of t)p(e[0]),p(e[1])}for(const t of u)p(t.cm),p(t.a?.[0]??0),p(t.a?.[1]??0),p(t.b?.[0]??0),p(t.b?.[1]??0);const _=d.toString(36),m=`${t.id}|${_}`;if(this._lightBarrierCache?.key===m)return this._lightBarrierCache.value;const g=.02*this._gridPitch,f=[],v=u.length||h.length?oc(t.rooms,u,i,r,this._wallKeyPitch,this._cellCm,this._gridPitch,mf,h):null;if(!v||"ok"!==v.status&&"degraded-extra"!==v.status)for(const t of h)f.push(...vu(t));else for(const t of v.components)for(const e of Fc(t.geom))f.push(...vu(e));for(const{poly:t}of e)for(const e of s.length?Ps(t,s,g):vu(t))f.push(e);const y={occluders:fu(f),floor:e.map(t=>t.poly),fingerprint:_,masonryGeometry:!v||"ok"!==v.status&&"degraded-extra"!==v.status?[]:v.components.flatMap(t=>t.geom),opaqueBodies:h};return this._lightBarrierCache={key:m,value:y},y}_renderGlowLayer(t,e){const i=this._fillColors,s=this._glowRadiusCm/this._cellCm*this._gridPitch,n=t.rooms.map(t=>({r:t,poly:hi(t)})).filter(t=>!!t.poly),o=n.filter(({r:t})=>Fs(e.glow,t));if(!o.length)return this._forgetGlowSpace(t.id),j``;const{occluders:a,floor:r,fingerprint:l,masonryGeometry:c,opaqueBodies:h}=this._lightBarriers(t,n),d=ho(this._renderPlanHass,this._renderDevices,null,this._virtualLights).filter(e=>e.device.space===t.id),p=new Map;for(const t of d){if(!t.device.id)continue;const e=p.get(t.device.id)||[];e.push(t),p.set(t.device.id,e)}const u=[],_=new Set;for(const e of this._renderDevices){if(e.space!==t.id)continue;const o=po(p.get(e.id)||[]);if(!o)continue;const d=`${t.id}|${e.id}`;_.add(d);const m=$s(o.passive?{state:o.on?"on":"off",attributes:{}}:this._renderPlanHass.states[o.eid],e.marker?.glow_color,i.glow_light.c),g=Number(e.marker?.glow_radius_cm),f=Number.isFinite(g)&&g>0?g/this._cellCm*this._gridPitch:s,v=this._pos(e);if(Oc([v.x,v.y],c,h)){this._forgetGlowSource(d);continue}const y=this._glowTransition(d,!!m);if(!y)continue;m&&this._glowLastAppearance.set(d,{c:m.c,alpha:Ss(m.bri,i.glow_light.a)});const b=this._glowLastAppearance.get(d);if(!b)continue;let w=null;const k=`${t.id}|${l}|${v.x.toFixed(4)},${v.y.toFixed(4)}|${f.toFixed(4)}`,x=ef(this._glowClipCache,k);if(x.hit)w=x.value;else{const e=wu([v.x,v.y],f,a,96);w={lit:e.length>=3?Ic([e],r,{onBoundsFailure:({boundIndex:e,phase:i})=>{const s=n[e]?.r;this._warnGlowGeometryFallback(t.id,l,s?.id||`#${e}`,i)}}):[]},sf(this._glowClipCache,k,w,256)}u.push({key:d,sourceEid:o.eid,domId:y.domId,entering:y.entering,leaving:y.leaving,pos:v,c:b.c,alpha:b.alpha,geometry:w,r:f})}const m=`${t.id}|`;for(const t of this._glowRenderedSources.keys())t.startsWith(m)&&!_.has(t)&&this._forgetGlowSource(t);if(!u.length)return j``;const g=this._spaceWalls,f=o.length===n.length?[]:this._openPairs().flatMap(t=>t.segs),v=this._wallUnionGeometry()?.roomGeom,y=o.length===n.length?null:o.map(({r:e,poly:i})=>{const s=g.length&&e.id&&jl(t.rooms,e.id,g,f,this._wallKeyPitch,this._cellCm,this._gridPitch,mf,v)||i,o=this._cleanFloor(e,s,t).path,a=Pi(s,n.filter(t=>t.r!==e).map(t=>t.poly)),r=t=>"M "+t.map(t=>t[0]+" "+t[1]).join(" L ")+" Z";return[o||r(s),...a.map(r)].join(" ")}),b=this._viewOr(this._baseVb()),w=this._stageEl?.clientWidth&&b.w?this._stageEl.clientWidth/b.w:1,k=1/(w>0?w:1),x=!this._pinchStart&&!this._panStart&&Date.now()>=this._glowFeatherSuspendUntil;(null==this._glowFeatherUnits||x)&&(this._glowFeatherUnits=k);const $=this._glowFeatherUnits??k,S=4*$,M=u.reduce((t,e)=>({x:Math.min(t.x,e.pos.x-e.r-S),y:Math.min(t.y,e.pos.y-e.r-S),maxX:Math.max(t.maxX,e.pos.x+e.r+S),maxY:Math.max(t.maxY,e.pos.y+e.r+S),w:0,h:0}),{x:1/0,y:1/0,maxX:-1/0,maxY:-1/0,w:0,h:0});return M.w=M.maxX-M.x,M.h=M.maxY-M.y,j`
+ `}get _glowRadiusCm(){const t=Number(this._settings.glow_radius_cm);return Number.isFinite(t)&&t>0?t:300}get _imperial(){return"mi"===this.hass?.config?.unit_system?.length}get _glowRadiusPlaceholder(){const t=this._glowRadiusCm;return this._imperial?String(Math.round(t/30.48*10)/10):String(t/100)}_glowTransition(t,e){let i=this._glowRenderedSources.get(t);if(e){const e=this._glowFadeTimers.get(t);if(null!=e&&(clearTimeout(e),this._glowFadeTimers.delete(t)),null==i){this._suspendGlowFeatherForTransition(),i=++this._glowSourceSeq,this._glowRenderedSources.set(t,i),this._glowEnteringSources.add(t);const e=requestAnimationFrame(()=>{this._glowEnterRafs.get(t)===e&&(this._glowEnterRafs.delete(t),this._glowEnteringSources.delete(t),this.isConnected&&this.requestUpdate())});this._glowEnterRafs.set(t,e)}return{domId:i,entering:this._glowEnteringSources.has(t),leaving:!1}}if(null==i)return null;const s=this._glowEnterRafs.get(t);if(null!=s&&cancelAnimationFrame(s),this._glowEnterRafs.delete(t),this._glowEnteringSources.delete(t),!this._glowFadeTimers.has(t)){this._suspendGlowFeatherForTransition();const e=window.setTimeout(()=>{this._glowFadeTimers.get(t)===e&&(this._glowFadeTimers.delete(t),this._glowRenderedSources.delete(t),this._glowLastAppearance.delete(t),this.isConnected&&this.requestUpdate())},534);this._glowFadeTimers.set(t,e)}return{domId:i,entering:!1,leaving:!0}}_suspendGlowFeatherForTransition(){if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;this._glowFeatherSuspendUntil=Math.max(this._glowFeatherSuspendUntil,Date.now()+500),clearTimeout(this._glowFeatherResumeTimer);const t=Math.max(0,this._glowFeatherSuspendUntil-Date.now())+17,e=()=>{this._glowFeatherResumeTimer=0,Date.now()=128){const t=this._glowGeometryWarnings.values().next().value;t&&this._glowGeometryWarnings.delete(t)}this._glowGeometryWarnings.add(n),console.warn(`HOUSEPLAN GLOW GEOMETRY FALLBACK: #218, space ${t}, room ${i}, phase ${s}`)}}_lightBarriers(t,e){const i=this._openPairs().flatMap(t=>t.segs),s=[...i],n=Math.max(this._cmToUnits(10),.5*this._gridPitch),o=t=>e.some(e=>this._pointInRoom(t,e.r)),a=this._openingsR.filter(t=>{if("door"!==(e=String(t.type))&&"gate"!==e&&"passage"!==e)return!1;var e;const i=t.angle*Math.PI/180,s=-Math.sin(i),a=Math.cos(i);return o([t.rx+s*n,t.ry+a*n])&&o([t.rx-s*n,t.ry-a*n])}),r=this._roomWallOpeningInputs(a,t);for(const t of r){const e=t.angle*Math.PI/180,i=Math.cos(e)*t.length/2,n=Math.sin(e)*t.length/2;s.push([t.x-i,t.y-n,t.x+i,t.y+n])}const l=new Set(a.filter(t=>t.partitionHost).map(t=>t.id)),c=[t.id,this._cfgEpoch,this._cellCm,this._gridPitch,[...l].sort().join(",")].join("|");this._lightPhysicalBodiesCache?.key!==c&&(this._lightPhysicalBodiesCache={key:c,all:Tc(t,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(t,t=>l.has(t.id))).all});const h=this._lightPhysicalBodiesCache.all;let d=2166136261;const p=t=>{d^=Math.round(64*(Number.isFinite(t)?t:0)),d=Math.imul(d,16777619)>>>0},u=this._spaceWalls;p(this._cellCm),p(this._gridPitch),p(this._wallKeyPitch);for(const{poly:t}of e){p(t.length);for(const e of t)p(e[0]),p(e[1])}for(const t of s)for(const e of t)p(e);for(const t of h){p(t.length);for(const e of t)p(e[0]),p(e[1])}for(const t of u)p(t.cm),p(t.a?.[0]??0),p(t.a?.[1]??0),p(t.b?.[0]??0),p(t.b?.[1]??0);const _=d.toString(36),m=`${t.id}|${_}`;if(this._lightBarrierCache?.key===m)return this._lightBarrierCache.value;const g=.02*this._gridPitch,f=[],v=u.length||h.length?rc(t.rooms,u,i,r,this._wallKeyPitch,this._cellCm,this._gridPitch,ff,h):null;if(!v||"ok"!==v.status&&"degraded-extra"!==v.status)for(const t of h)f.push(...bu(t));else for(const t of v.components)for(const e of Nc(t.geom))f.push(...bu(e));for(const{poly:t}of e)for(const e of s.length?Ps(t,s,g):bu(t))f.push(e);const y={occluders:yu(f),floor:e.map(t=>t.poly),fingerprint:_,masonryGeometry:!v||"ok"!==v.status&&"degraded-extra"!==v.status?[]:v.components.flatMap(t=>t.geom),opaqueBodies:h};return this._lightBarrierCache={key:m,value:y},y}_renderGlowLayer(t,e){const i=this._fillColors,s=this._glowRadiusCm/this._cellCm*this._gridPitch,n=t.rooms.map(t=>({r:t,poly:hi(t)})).filter(t=>!!t.poly),o=n.filter(({r:t})=>Fs(e.glow,t));if(!o.length)return this._forgetGlowSpace(t.id),j``;const{occluders:a,floor:r,fingerprint:l,masonryGeometry:c,opaqueBodies:h}=this._lightBarriers(t,n),d=ho(this._renderPlanHass,this._renderDevices,null,this._virtualLights).filter(e=>e.device.space===t.id),p=new Map;for(const t of d){if(!t.device.id)continue;const e=p.get(t.device.id)||[];e.push(t),p.set(t.device.id,e)}const u=[],_=new Set;for(const e of this._renderDevices){if(e.space!==t.id)continue;const o=po(p.get(e.id)||[]);if(!o)continue;const d=`${t.id}|${e.id}`;_.add(d);const m=$s(o.passive?{state:o.on?"on":"off",attributes:{}}:this._renderPlanHass.states[o.eid],e.marker?.glow_color,i.glow_light.c),g=Number(e.marker?.glow_radius_cm),f=Number.isFinite(g)&&g>0?g/this._cellCm*this._gridPitch:s,v=this._pos(e);if(Lc([v.x,v.y],c,h)){this._forgetGlowSource(d);continue}const y=this._glowTransition(d,!!m);if(!y)continue;m&&this._glowLastAppearance.set(d,{c:m.c,alpha:Ss(m.bri,i.glow_light.a)});const b=this._glowLastAppearance.get(d);if(!b)continue;let w=null;const k=`${t.id}|${l}|${v.x.toFixed(4)},${v.y.toFixed(4)}|${f.toFixed(4)}`,x=nf(this._glowClipCache,k);if(x.hit)w=x.value;else{const e=xu([v.x,v.y],f,a,96);w={lit:e.length>=3?zc([e],r,{onBoundsFailure:({boundIndex:e,phase:i})=>{const s=n[e]?.r;this._warnGlowGeometryFallback(t.id,l,s?.id||`#${e}`,i)}}):[]},of(this._glowClipCache,k,w,256)}u.push({key:d,sourceEid:o.eid,domId:y.domId,entering:y.entering,leaving:y.leaving,pos:v,c:b.c,alpha:b.alpha,geometry:w,r:f})}const m=`${t.id}|`;for(const t of this._glowRenderedSources.keys())t.startsWith(m)&&!_.has(t)&&this._forgetGlowSource(t);if(!u.length)return j``;const g=this._spaceWalls,f=o.length===n.length?[]:this._openPairs().flatMap(t=>t.segs),v=this._wallUnionGeometry()?.roomGeom,y=o.length===n.length?null:o.map(({r:e,poly:i})=>{const s=g.length&&e.id&&Ul(t.rooms,e.id,g,f,this._wallKeyPitch,this._cellCm,this._gridPitch,ff,v)||i,o=this._cleanFloor(e,s,t).path,a=Pi(s,n.filter(t=>t.r!==e).map(t=>t.poly)),r=t=>"M "+t.map(t=>t[0]+" "+t[1]).join(" L ")+" Z";return[o||r(s),...a.map(r)].join(" ")}),b=this._viewOr(this._baseVb()),w=this._stageEl?.clientWidth&&b.w?this._stageEl.clientWidth/b.w:1,k=1/(w>0?w:1),x=!this._pinchStart&&!this._panStart&&Date.now()>=this._glowFeatherSuspendUntil;(null==this._glowFeatherUnits||x)&&(this._glowFeatherUnits=k);const $=this._glowFeatherUnits??k,S=4*$,M=u.reduce((t,e)=>({x:Math.min(t.x,e.pos.x-e.r-S),y:Math.min(t.y,e.pos.y-e.r-S),maxX:Math.max(t.maxX,e.pos.x+e.r+S),maxY:Math.max(t.maxY,e.pos.y+e.r+S),w:0,h:0}),{x:1/0,y:1/0,maxX:-1/0,maxY:-1/0,w:0,h:0});return M.w=M.maxX-M.x,M.h=M.maxY-M.y,j`
${Mt(u,t=>t.key,t=>{const e=t.domId,i=t.geometry;return j`
${""}
- ${gf.map(([e,i])=>j`
+ ${vf.map(([e,i])=>j`
`)}
@@ -5574,7 +5613,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="0b4484d42e0e4f0b284f34749967b05877c9
- `}_cardEntities(t){const e=this._planHass,i=[],s=new Set,n=t=>{if(!t||s.has(t)||!e.states[t])return;const n=e.entities[t];if("config"===n?.entity_category||"diagnostic"===n?.entity_category)return;s.add(t);const o=t.split(".")[0];["light","switch","fan","humidifier","siren","input_boolean"].includes(o)?i.push({eid:t,kind:"toggle"}):["cover","valve","lock","climate","media_player","vacuum","water_heater"].includes(o)?i.push({eid:t,kind:"open"}):["sensor","binary_sensor","number","select"].includes(o)&&i.push({eid:t,kind:"value"})};for(const i of ho(e,this._devices,null,this._virtualLights))if(i.device.id===t.id)for(const t of[...i.serviceEids,...i.stateEids])n(t);t.primary&&n(t.primary);for(const e of t.entities)n(e);return i.slice(0,12)}_cardToggle(t){const e=t.split(".")[0];"lock"!==e&&"alarm_control_panel"!==e&&this._planEntityAvailable(t)&&this.hass.callService("homeassistant","toggle",{entity_id:t}).catch(t=>this._showToast(this._t("toast.error",{err:this._errText(t)})))}_renderInfoCard(){const t=this._infoCard,e=t.primary?this.hass.states[t.primary]:void 0,i=e?Xi(this.hass,t.primary)?.text??e.state:null,s=(t.controls??t.marker?.controls??[]).filter(Ms).filter(t=>this._planEntityAvailable(t));return W``}_cardEntities(t){const e=this._planHass,i=[],s=new Set,n=t=>{if(!t||s.has(t)||!e.states[t])return;const n=e.entities[t];if("config"===n?.entity_category||"diagnostic"===n?.entity_category)return;s.add(t);const o=t.split(".")[0];["light","switch","fan","humidifier","siren","input_boolean"].includes(o)?i.push({eid:t,kind:"toggle"}):["cover","valve","lock","climate","media_player","vacuum","water_heater"].includes(o)?i.push({eid:t,kind:"open"}):["sensor","binary_sensor","number","select"].includes(o)&&i.push({eid:t,kind:"value"})};for(const i of ho(e,this._devices,null,this._virtualLights))if(i.device.id===t.id)for(const t of[...i.serviceEids,...i.stateEids])n(t);t.primary&&n(t.primary);for(const e of t.entities)n(e);return i.slice(0,12)}_cardToggle(t){const e=t.split(".")[0];"lock"!==e&&"alarm_control_panel"!==e&&this._planEntityAvailable(t)&&this.hass.callService("homeassistant","toggle",{entity_id:t}).catch(t=>this._showToast(this._t("toast.error",{err:this._errText(t)})))}_renderInfoCard(){const t=this._infoCard,e=t.primary?this.hass.states[t.primary]:void 0,i=e?Ji(this.hass,t.primary)?.text??e.state:null,s=(t.controls??t.marker?.controls??[]).filter(Ms).filter(t=>this._planEntityAvailable(t));return W`