diff --git a/docs/_docs/floorplan/floorplan-examples.js b/docs/_docs/floorplan/floorplan-examples.js
index eb46db41..c63e1e3e 100644
--- a/docs/_docs/floorplan/floorplan-examples.js
+++ b/docs/_docs/floorplan/floorplan-examples.js
@@ -122,7 +122,7 @@ const ie=e=>t=>"function"==typeof t?((e,t)=>(customElements.define(e,t),t))(e,t)
.debug {
color: #000000;
}
- `}clearLog(){this.logElement.querySelector("#log ul").innerHTML=""}updated(e){const t=Object.create(null,{updated:{get:()=>super.updated}});return Mn(this,void 0,void 0,(function*(){t.updated.call(this,e),e.has("_config")&&(yield this._configChanged(),yield this.hassChanged()),e.has("hass")&&(yield this.hassChanged())}))}_configChanged(){return Mn(this,void 0,void 0,(function*(){this._config&&(yield this.init())}))}hassChanged(){return Mn(this,void 0,void 0,(function*(){if(!this.hass||!this.config||!this.svg)return;const e=cn.deviceId();this.hass.states[`sensor.ha_floorplan_${e}`]={entity_id:`sensor.ha_floorplan_${e}`,state:"on",last_changed:(new Date).toString(),last_updated:(new Date).toString(),attributes:{device_class:"ha-floorplan",friendly_name:"ha-floorplan - Floorplan for Home Assistant",icon:"mdi:floor-plan",assumed_state:!1,hidden:!0},context:{}},this.isRulesLoaded?this.handleEntities():(this.initFloorplanRules(this.svg,this.config),this.isRulesLoaded=!0,yield this.handleEntities(!0))}))}get floorplanElement(){var e;return null===(e=this.shadowRoot)||void 0===e?void 0:e.getElementById("floorplan")}get logElement(){var e;return null===(e=this.shadowRoot)||void 0===e?void 0:e.getElementById("log")}init(){return Mn(this,void 0,void 0,(function*(){try{const e=yield this.loadConfig(this._config,!1);if(this.isShowLog=void 0!==e.log_level,this.logger=new On(this.logElement,e.log_level,e.console_log_level),this.logInfo("INIT","Floorplan for Home Assistant (ha-floorplan) v1.0.45"),!this.validateConfig(e))return;this.config=e,this.config.pages?yield this.initMultiPage():yield this.initSinglePage(),this.initEventListeners()}catch(e){this.handleError(e)}}))}initMultiPage(){return Mn(this,void 0,void 0,(function*(){try{yield this.loadPages(),this.initPageDisplay(),this.initVariables(),this.initStartupActions()}catch(e){this.handleError(e)}}))}initSinglePage(){return Mn(this,void 0,void 0,(function*(){try{yield this.loadStyleSheet(this.config.stylesheet);const e=this.getBestImage(this.config);this.svg=yield this.loadFloorplanSvg(e),this.initPageDisplay(),this.initVariables(),this.initStartupActions()}catch(e){this.handleError(e)}}))}loadConfig(e,t){return Mn(this,void 0,void 0,(function*(){if("string"==typeof e){let i;try{i=yield cn.fetchText(e,this.isDemo,this.examplespath,t)}catch(t){throw this.logError("CONFIG",`Error loading config: ${e}`),t}return an.load(i)}return JSON.parse(JSON.stringify(e))}))}loadScript(e,t){return e?new Promise(((i,n)=>{var r;const s=document.createElement("script");s.src=t?e:cn.cacheBuster(e),s.onload=()=>i(),s.onerror=e=>{n(new URIError(`${e.target.src}`))},null===(r=this.shadowRoot)||void 0===r||r.appendChild(s)})):Promise.resolve()}loadPages(){return Mn(this,void 0,void 0,(function*(){for(const e of this.config.pages)yield this.loadPageConfig(e,this.config.pages.indexOf(e));const e=Object.keys(this.pageInfos).map((e=>this.pageInfos[e]));e.sort(((e,t)=>e.index-t.index));const t=e.find((e=>void 0!==e.config.master_page));if(!t)throw new Error("A master page is required");t.isMaster=!0;const i=e.find((e=>void 0===e.config.master_page));i&&(i.isDefault=!0),yield this.loadPageFloorplanSvg(t,t);const n=e.filter((e=>e!==t));for(const e of n)yield this.loadPageFloorplanSvg(e,t);this.svg=t.svg}))}loadPageConfig(e,t){return Mn(this,void 0,void 0,(function*(){const i=yield this.loadConfig(e,!1),n=this.createPageInfo(i);return n.index=t,n}))}loadPageFloorplanSvg(e,t){return Mn(this,void 0,void 0,(function*(){const i=this.getBestImage(e.config),n=yield this.loadFloorplanSvg(i,e,t);n.id=e.config.page_id,e.svg=n,yield this.loadStyleSheet(e.config.stylesheet),this.initFloorplanRules(e.svg,e.config)}))}getBestImage(e){var t;let i="",n=!0;if("string"==typeof e.image)i=cn.isMobile&&"string"==typeof e.image_mobile?e.image_mobile:e.image;else if(null===(t=e.image)||void 0===t?void 0:t.sizes){e.image.sizes.sort(((e,t)=>t.min_width-e.min_width));for(const t of e.image.sizes)if(screen.width>=t.min_width){i=t.location,n=!0===t.cache;break}}else cn.isMobile&&e.image_mobile?(i=e.image_mobile.location,n=!0===e.image_mobile.cache):(i=e.image.location,n=!0===e.image.cache);return{location:i,cache:n}}createPageInfo(e){const t={config:e};return t.config.rules&&this.config.rules&&(t.config.rules=t.config.rules.concat(this.config.rules)),this.pageInfos[t.config.page_id]=t,t}loadStyleSheet(e){return Mn(this,void 0,void 0,(function*(){const t="string"==typeof e?e:e.location,i="string"!=typeof e&&!0===e.cache;if(!t)return;let n;try{n=yield cn.fetchText(t,this.isDemo,this.examplespath,i)}catch(e){throw this.logError("STYLESHEET",`Error loading stylesheet: ${t}`),e}const r=document.createElement("style"),s=()=>{var e;r.innerHTML=n,null===(e=this.shadowRoot)||void 0===e||e.appendChild(r)};try{yield cn.waitForChildNodes(r,s,1e4)}catch(e){this.logError("STYLESHEET","Error loading stylesheet")}const a=this.getCssRules(r);this.cssRules=this.cssRules.concat(a)}))}getCssRules(e){var t,i,n,r,s,a;let o;if(e.sheet)o=null!==(i=null===(t=e.sheet)||void 0===t?void 0:t.cssRules)&&void 0!==i?i:null===(n=e.sheet)||void 0===n?void 0:n.rules;else{const t=e;t.styleSheet&&(o=null!==(s=null===(r=t.styleSheet)||void 0===r?void 0:r.cssRules)&&void 0!==s?s:null===(a=t.styleSheet)||void 0===a?void 0:a.rules)}return o?cn.getArray(o):[]}loadFloorplanSvg(e,t,i){return Mn(this,void 0,void 0,(function*(){let n;try{n=yield cn.fetchText(e.location,this.isDemo,this.examplespath,e.cache)}catch(t){throw this.logError("IMAGE",`Error loading image: ${e.location}`),t}const r=document.createElement("div");r.innerHTML=n;const s=r.querySelector("svg");if(t&&s.setAttribute("id",t.config.page_id),s.setAttribute("height","100%"),s.setAttribute("width","100%"),s.style.height="100%",s.style.width="100%",s.style.margin="auto",s.style.cursor="default",s.style.opacity="0",s.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),t&&i){const e=i.config.page_id,n=i.config.master_page.content_element;if(t.config.page_id===e)this.floorplanElement&&this.replaceChildrenUtil(this.floorplanElement,s);else{const e=this.floorplanElement.querySelector("#"+n),t=Number.parseFloat(s.getAttribute("height")),i=Number.parseFloat(s.getAttribute("width"));s.getAttribute("viewBox")||s.setAttribute("viewBox",`0 0 ${i} ${t}`),s.setAttribute("preserveAspectRatio","xMinYMin meet"),s.setAttribute("height",e.getAttribute("height")),s.setAttribute("width",e.getAttribute("width")),s.setAttribute("x",e.getAttribute("x")),s.setAttribute("y",e.getAttribute("y")),(null==e?void 0:e.parentElement)&&this.replaceChildrenUtil(e.parentElement,s)}}else this.floorplanElement&&this.replaceChildrenUtil(this.floorplanElement,s);return s}))}replaceChildrenUtil(e,t){return Mn(this,void 0,void 0,(function*(){if(null==e?void 0:e.replaceChildren)e.replaceChildren(t);else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(t)}}))}loadImage(e,t,i,n,r){return Mn(this,void 0,void 0,(function*(){return e.toLowerCase().includes(".svg")||"svg"===t.svgElement.nodeName||t.svgElement.querySelector("svg")?yield this.loadSvgImage(e,t,i,n,r):yield this.loadBitmapImage(e,t,i,n,r)}))}loadBitmapImage(e,t,i,n,r){return Mn(this,void 0,void 0,(function*(){e=r?e:cn.cacheBuster(e),this.logDebug("IMAGE",`${i} (setting image: ${e})`);let s=t.svgElement;return"image"!==s.nodeName&&(s=this.createImageElement(t.originalSvgElement),t.svgElement=this.replaceElement(t.svgElement,s),this.attachClickHandlers(s,t,i,void 0,n),s.onmouseover=()=>{this.handleEntityIdSetHoverOver(i,t)}),s.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",e),s}))}loadSvgImage(e,t,i,n,r){return Mn(this,void 0,void 0,(function*(){let s;if(null==e?void 0:e.trim().length)try{s=yield cn.fetchText(e,this.isDemo,this.examplespath,r)}catch(t){throw this.logError("IMAGE",`Error loading image: ${e}`),t}else{const e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("viewBox","0 0 0 0"),s=e.outerHTML}this.logDebug("IMAGE",`${i} (setting image: ${e})`);const a="g"===t.svgElement.nodeName?t.svgElement:document.createElement("div");a.innerHTML=s;const o=a.querySelector("svg"),c=Number.parseFloat(o.getAttribute("height")),l=Number.parseFloat(o.getAttribute("width"));if(o.getAttribute("viewBox")||o.setAttribute("viewBox",`0 0 ${l} ${c}`),o.id=t.svgElement.id,o.setAttribute("preserveAspectRatio","xMinYMin meet"),null!==t.originalBBox&&(o.setAttribute("height",t.originalBBox.height.toString()),o.setAttribute("width",t.originalBBox.width.toString()),o.setAttribute("x",t.originalBBox.x.toString()),o.setAttribute("y",t.originalBBox.y.toString())),"g"!==t.svgElement.nodeName){const e=t.svgElement.getAttribute("transform");e&&o.setAttribute("transform",e),t.svgElement=this.replaceElement(t.svgElement,o)}return this.attachClickHandlers(o,t,i,void 0,n),t.svgElement.onmouseover=()=>{this.handleEntityIdSetHoverOver(i,t)},o}))}_querySelectorAll(e,t=void 0,i){let n=t?Array.from(e.querySelectorAll(t).values()):[];return n=i?[e].concat(n):n,n}replaceElement(e,t){const i=e.parentElement;for(const i of Array.from(e.classList))t.classList.add(i);return this._querySelectorAll(e,"*",!0).forEach((e=>{Ln.off(e,"click"),Ln.off(e,"longClick"),e.remove()})),e.remove(),null==i||i.appendChild(t),t}initPageDisplay(){if(this.config.pages)for(const e of Object.values(this.pageInfos))e.svg.style.opacity="1",e.svg.style.display=e.isMaster||e.isDefault?"initial":"none";else this.svg.style.opacity="1",this.svg.style.display="block"}initVariables(){if(this.config.variables)for(const e of this.config.variables)this.initVariable(e);if(this.config.pages)for(const e of Object.values(this.pageInfos))if(e.config.variables)for(const t of e.config.variables)this.initVariable(t)}initVariable(e){let t,i;if("string"==typeof e?t=e:(t=e.name,i=e.value,e.value&&(i=this.evaluate(e.value,t,void 0))),!this.entityInfos[t]){const e={entityId:t,ruleInfos:[],lastState:void 0};this.entityInfos[t]=e}this.hass.states[t]||(this.hass.states[t]={entity_id:t,state:i,last_changed:(new Date).toString(),last_updated:(new Date).toString(),attributes:{},context:{}}),this.setVariable(t,i,{},!0)}getActionConfigs(e){var t,i;if(null==e)return[];if(Array.isArray(e)){for(const i of e)i.action=null!==(t=i.action)&&void 0!==t?t:"call-service";return e}return"object"==typeof e?(e.action=null!==(i=e.action)&&void 0!==i?i:"call-service",[e]):"string"==typeof e?e.includes(".")?[{action:"call-service",service:e}]:[{action:e}]:[]}initEventListeners(){this.addEventListener(Tn,this.handleEventActionCall)}initStartupActions(){if(this.handleActions(this.config.startup_action,void 0,void 0,void 0),this.config.pages)for(const e of Object.values(this.pageInfos))this.handleActions(e.config.startup_action,void 0,void 0,void 0)}initFloorplanRules(e,t){if(!t.rules)return;const i=this._querySelectorAll(e,"*",!0);for(const e of i)e.id&&(this.svgElements[e.id]=e);this.initRules(t,e,i)}initRules(e,t,i){if(e.functions&&(this.functions=this.evaluate(e.functions)),e.defaults){const t=e.defaults;for(const i of e.rules)i.hover_action=void 0===i.hover_action?t.hover_action:i.hover_action,i.tap_action=void 0===i.tap_action?t.tap_action:i.tap_action,i.hold_action=void 0===i.hold_action?t.hold_action:i.hold_action,i.hover_info_filter=void 0===i.hover_info_filter?t.hover_info_filter:i.hover_info_filter}for(const n of e.rules)n.entity||n.entities?this.initEntityRule(n,t,i):(n.element||n.elements)&&this.initElementRule(n,t,i)}initEntityRule(e,t,i){const n=this.initGetEntityRuleEntities(e);for(const r of n){const n=r.entityId;let s=this.entityInfos[n];s||(s={entityId:n,ruleInfos:[],lastState:void 0},this.entityInfos[n]=s);const a=new dn(e);s.ruleInfos.push(a);for(const e of r.elementIds){const r=i.find((t=>t.id===e));if(!r){this.logWarning("CONFIG",`Cannot find element '${e}' in SVG file`);continue}const o=this.addSvgElementToRule(t,r,a);o.svgElement=r,r.querySelector("title")||r.appendChild(document.createElementNS("http://www.w3.org/2000/svg","title")),r.onmouseenter=()=>{this.handleEntitySetHoverOver(s,o)},r.onmouseleave=()=>{this.handleEntitySetHoverOver(s,o)},this.attachClickHandlers(r,o,n,void 0,a)}}}initGetEntityRuleEntities(e){const t=[];e.groups=e.groups?e.groups:[];for(const i of e.groups){const e=this.hass.states[i];if(e)for(const i of e.attributes.entity_id)this.addTargetEntity(i,[i],t);else this.logWarning("CONFIG",`Cannot find '${i}' in Home Assistant groups`)}e.entities=e.entities?e.entities:[],e.entities=e.entity?e.entities.concat(e.entity):e.entities;const i=e.entities.filter((e=>"string"==typeof e));for(const n of i){let i=[];e.elements?i=i.concat(e.elements):e.element?i=i.concat(this.evaluate(e.element,n,void 0)):null!==e.element&&(i=i.concat(n)),this.addTargetEntity(n,i,t)}const n=e.entities.filter((e=>"string"!=typeof e));for(const e of n){const i=e;this.addTargetEntity(i.entity,[i.element],t)}return t}addTargetEntity(e,t,i){const n=this.hass.states[e],r="floorplan"===e.split(".")[0];n||r?i.push({entityId:e,elementIds:t}):this.logWarning("CONFIG",`Cannot find '${e}' in Home Assistant entities`)}initElementRule(e,t,i){if(e.element||e.elements){e.elements=e.elements?e.elements:[],e.elements=e.element?e.elements.concat(e.element):e.elements;for(const n of e.elements){const r=i.find((e=>e.id===n));if(r){let i=this.elementInfos[n];i||(i={ruleInfos:[],lastState:void 0},this.elementInfos[n]=i);const s=new dn(e);i.ruleInfos.push(s);const a=this.addSvgElementToRule(t,r,s);this.attachClickHandlers(r,a,void 0,n,s)}else this.logWarning("CONFIG",`Cannot find '${n}' in SVG file`)}}}attachClickHandlers(e,t,i,n,r){this._querySelectorAll(e,void 0,!0).forEach((s=>{const a=s,o=s===e;if(a.querySelector("title")||a.appendChild(document.createElementNS("http://www.w3.org/2000/svg","title")),r.rule.tap_action||r.rule.double_tap_action){const e=!!r.rule.tap_action&&this.getActionConfigs(r.rule.tap_action),s=!!r.rule.double_tap_action&&this.getActionConfigs(r.rule.double_tap_action),c=!!e&&new fn(this,i,n,t,r,e);if(e&&!s&&Ln.on(a,"click",this.onClick.bind(c)),s){const o=!!s&&new fn(this,i,n,t,r,s);In.observe(a),e&&Ln.on(a,"singleClick",this.onClick.bind(c)),Ln.on(a,"doubleClick",this.onLongClick.bind(o))}a.style&&(a.style.cursor="pointer"),cn.addClass(a,"floorplan-click"+(o?"":"-child"))}if(r.rule.hold_action){const e=this.getActionConfigs(r.rule.hold_action),s=new fn(this,i,n,t,r,e);En.observe(a),Ln.on(a,"longClick",this.onLongClick.bind(s)),a.style&&(a.style.cursor="pointer"),cn.addClass(a,"floorplan-long-click"+(o?"":"-child"))}}))}addSvgElementToRule(e,t,i){const n=t.getBBox?t.getBBox():null,r=new pn(t.id,t,t,n);return i.svgElementInfos[t.id]=r,r}createImageElement(e){const t=document.createElementNS("http://www.w3.org/2000/svg","image");return t.setAttribute("id",e.getAttribute("id")),t.setAttribute("x",e.getAttribute("x")),t.setAttribute("y",e.getAttribute("y")),t.setAttribute("height",e.getAttribute("height")),t.setAttribute("width",e.getAttribute("width")),t}handleEntities(e=!1){return Mn(this,void 0,void 0,(function*(){this.handleElements();const t=this.getChangedEntities(e);for(const e of Object.keys(this.variables))t.add(e);if(t.size)for(const e of t)yield this.handleEntity(e)}))}getChangedEntities(e){const t=new Set,i=Object.keys(this.hass.states),n=cn.deviceId();for(const r of i)if(r!==`sensor.ha_floorplan_${n}`||t.has(r)){const i=this.entityInfos[r];if(i){const n=this.hass.states[r];if(e)this.logDebug("STATE",`${r}: ${n.state} (initial load)`),t.has(r)||t.add(r);else if(i.lastState){const e=n.state;n.last_changed!==i.lastState.last_changed?(this.logDebug("STATE",`${r}: ${e} (last changed ${cn.formatDate(i.lastState.last_changed)})`),t.has(r)||t.add(r)):cn.equal(i.lastState.attributes,n.attributes)||(this.logDebug("STATE",`${r}: attributes (last updated ${cn.formatDate(i.lastState.last_changed)})`),t.has(r)||t.add(r))}}}else t.add(r);return t}handleEntity(e){return Mn(this,void 0,void 0,(function*(){const t=this.hass.states[e],i=this.entityInfos[e];if(i){i.lastState=Object.assign({},t);for(const e of i.ruleInfos){const t=Object.values(e.svgElementInfos);if(t.length)for(const n of t)n.svgElement&&this.handleActions(e.rule.state_action,i.entityId,n,e);else this.handleActions(e.rule.state_action,i.entityId,void 0,e)}}}))}handleElements(){return Mn(this,void 0,void 0,(function*(){for(const e of Object.values(this.elementInfos))for(const t of e.ruleInfos)for(const e of Object.values(t.svgElementInfos))this.handleActions(t.rule.state_action,void 0,e,t)}))}handleEntityIdSetHoverOver(e,t){const i=this.entityInfos[e];i&&this.handleEntitySetHoverOver(i,t)}handleEntitySetHoverOver(e,t){const i=e.entityId,n=this.hass.states[i];for(const i of e.ruleInfos)if(i.rule.hover_action){let r="string"==typeof i.rule.hover_action&&"hover-info"===i.rule.hover_action;if(r=r||"object"==typeof i.rule.hover_action&&"hover-info"===i.rule.hover_action.action,r=r||Array.isArray(i.rule.hover_action)&&i.rule.hover_action.some((e=>"hover-info"===e.action)),r){const e=new Set(i.rule.hover_info_filter);for(const t of Object.values(i.svgElementInfos))cn.addClass(t.svgElement,"floorplan-hover"),t.svgElement.style.cursor="pointer",t.svgElement.querySelectorAll("title").forEach((t=>{let i=`${n.attributes.friendly_name}\n`;i+=`State: ${n.state}\n\n`,Object.keys(n.attributes).map((t=>{e.has(t)||(i+=`${t}: ${n.attributes[t]}\n`)})),i+="\n",i+=`Last changed: ${ge.timeago(n.last_changed)}\n`,i+=`Last updated: ${ge.timeago(n.last_updated)}`,t.textContent=i}))}else i.rule.hover_action&&this.handleActions(i.rule.hover_action,e.entityId,t,i)}}isOptionEnabled(e){return null===e||void 0!==e}validateConfig(e){let t=!0;if(e.pages||e.rules)if(e.pages)e.pages.length||this.logWarning("CONFIG","The 'pages' section must contain one or more pages in floorplan configuration");else{e.rules||this.logWarning("CONFIG","Cannot find 'rules' in floorplan configuration");let i=e.rules.filter((e=>e.entities&&e.elements));i.length&&(this.logError("CONFIG","A rule cannot contain both 'entities' and 'elements' in floorplan configuration"),t=!1),i=e.rules.filter((e=>!(e.entity||e.entities||e.element||e.elements))),i.length&&(this.logError("CONFIG","A rule must contain either 'entities' or 'elements' in floorplan configuration"),t=!1)}else this.logWarning("CONFIG","Cannot find 'pages' nor 'rules' in floorplan configuration");return t}evaluate(e,t,i,n,r){if("string"!=typeof e||!Pn.isCode(e))return e;try{return Pn.evaluate(e,this.hass,this.config,t,i,this.svgElements,this.functions,n,r)}catch(n){return this.handleError(n,{expression:e,entityId:t,hass:this.hass,svgElement:i})}}onClick(e){e.stopPropagation(),e.preventDefault();const t=this;t.instance.handleActions(t.actions,t.entityId,t.svgElementInfo,t.ruleInfo)}onLongClick(e){e.stopPropagation(),e.preventDefault();const t=this,i=t.instance;setTimeout((()=>{i.handleActions(t.actions,t.entityId,t.svgElementInfo,t.ruleInfo)}),300)}handleActions(e,t,i,n){var r;const s=this.getActionConfigs(e);for(const e of s){if(e.confirmation&&(!e.confirmation.exemptions||!e.confirmation.exemptions.some((e=>e.user===this.hass.user.id)))&&!confirm(e.confirmation.text||`Are you sure you want to ${e.action}?`))return;switch(e.action){case"more-info":this.isDemo?this.notify(`Performing action: ${e.action} ${t}`):hn(this,"hass-more-info",{entityId:t});break;case"navigate":if(this.isDemo)this.notify(`Performing action: ${e.action} ${e.navigation_path}`);else{const n=this.evaluate(e.navigation_path,t,null==i?void 0:i.svgElement);un(0,n,null!==(r=e.navigation_replace)&&void 0!==r&&r)}break;case"url":if(this.isDemo)this.notify(`Performing action: ${e.action} ${e.url_path}`);else{const n=e.same_tab?"_self":"_blank",r=this.evaluate(e.url_path,t,null==i?void 0:i.svgElement);window.open(r,n)}break;case"toggle":if(t){const e={action:"call-service",service:"homeassistant.toggle",service_data:{entity_id:t}};this.callService(e,t,i,n)}break;case"call-service":if(!e.service)return;this.callService(e,t,i,n);break;case"fire-dom-event":hn(this,"ll-custom",e)}}}getSvgElementsFromServiceData(e,t){let i=[],n=[];if(Array.isArray(null==e?void 0:e.elements)&&(n=n.concat(null==e?void 0:e.elements)),"string"==typeof(null==e?void 0:e.element)&&(n=n.concat([null==e?void 0:e.element])),n.length)for(const e of n)i=i.concat(this._querySelectorAll(this.svg,`#${e.replace(/\./g,"\\.")}`,!1));else t&&(i=[t]);return i}getServiceData(e,t,i){let n={};if("object"==typeof e.service_data)for(const r of Object.keys(e.service_data))n[r]=this.evaluate(e.service_data[r],t,i);else if("string"==typeof e.service_data){const r=this.evaluate(e.service_data,t,i);n="string"==typeof r&&r.trim().startsWith("{")?JSON.parse(r):r}else void 0!==e.service_data&&(n=e.service_data);return n}executeServiceData(e,t,i,n,r){try{if("object"==typeof e.service_data)for(const s of Object.keys(e.service_data))this.evaluate(e.service_data[s],t,i,n,r);else"string"==typeof e.service_data?this.evaluate(e.service_data,t,i,n,r):void 0!==e.service_data&&this.logWarning("CONFIG","Invalid execution data");return!0}catch(e){return this.logWarning("CONFIG","Error thrown while executing service"),!1}}callService(e,t,i,n){const r=this.evaluate(e.service,t,null==i?void 0:i.svgElement),[s,a]=r.split(".",2);"floorplan"===s?this.callFloorplanService(s,a,e,t,i,n):this.callHomeAssistantService(s,a,e,t,i)}callFloorplanService(e,t,i,n,r,s){var a,o,c;const l=null!==(a=null==r?void 0:r.svgElement)&&void 0!==a?a:void 0;let h,u,p,d,f,m,g,v,y,b=[],x=null;switch(x=["execute"].includes(t)?{}:this.getServiceData(i,n,l),t){case"class_toggle":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),p="string"==typeof x?x:x.class,cn.toggleClass(e,p);break;case"class_set":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),p="string"==typeof x?x:x.class,cn.setClass(e,p);break;case"dataset_set":{let e,t;if("string"==typeof x){const i=x.split(":");if(i.length<2){this.logError("FLOORPLAN_ACTION",`Service data "${x}" is not a valid dataset key value pair.`);break}e=i[1],t=i[0]}else e=x.value,t=x.key;b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const s of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,s)),cn.datasetSet(s,t,e);break}case"style_set":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),d="string"==typeof x?x:x.style,cn.setStyle(e,d);break;case"text_set":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b){y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),v="string"==typeof x?x:x.text;const t=(null===(o=i.service_data)||void 0===o?void 0:o.shift_y_axis)?null===(c=i.service_data)||void 0===c?void 0:c.shift_y_axis:"1em";cn.setText(e,v,t)}break;case"image_set":r&&s&&(x=this.getServiceData(i,n,null==r?void 0:r.svgElement),f="string"==typeof x?x:x.image,m="object"==typeof x?x.image_refresh_interval:0,g=!(m>0||"object"==typeof x&&!0!==x.cache),s.imageLoader&&clearInterval(s.imageLoader),m&&(s.imageLoader=setInterval(this.loadImage.bind(this),1e3*m,f,r,n,s,g)),this.loadImage(f,r,n,s,g));break;case"page_navigate":x=this.getServiceData(i,n,null==r?void 0:r.svgElement),h=x.page_id,u=h?this.pageInfos[h]:void 0,u&&(Object.keys(this.pageInfos).map((e=>{const t=this.pageInfos[e];t.isMaster||"none"===t.svg.style.display||(t.svg.style.display="none")})),u.svg.style.display="block");break;case"variable_set":if(x=this.getServiceData(i,n,null==r?void 0:r.svgElement),x.variable){const e={};if(x.attributes){const t=x.attributes;for(const i of Object.keys(t))e[i]=this.getActionValue(t[i],n,l)}const t=x,i=this.getActionValue(t,n,l);this.setVariable(x.variable,i,e,!1)}break;case"execute":this.executeServiceData(i,n,null==r?void 0:r.svgElement,r,s);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||this.executeServiceData(i,n,e,r,s)}}getActionValue(e,t,i){let n=e.value;return e.value&&(n=this.evaluate(e.value,t,i)),n}setVariable(e,t,i,n){if(this.variables[e]=t,this.hass.states[e]){this.hass.states[e].state=t.toString();for(const t of Object.keys(i))this.hass.states[e].attributes[t]=i[t]}for(const e of Object.keys(this.variables)){const t=this.hass.states[e];t&&(t.last_changed=(new Date).toString())}n||this.handleEntities()}callHomeAssistantService(e,t,i,n,r){const s=this.getServiceData(i,n,null==r?void 0:r.svgElement);"object"==typeof s&&(null===s.entity_id||Array.isArray(s.entity_id)&&!s.entity_id.length||!s.entity_id&&n&&(s.entity_id=n)),this.hass.callService(e,t,s),this.isDemo&&this.notify(`Calling service: ${e}.${t} (${s.entity_id})`)}handleEventActionCall(e){const t=e,{actionConfig:i,entityId:n,svgElementInfo:r,ruleInfo:s}=t.detail;this.handleActions(i,n,r,s)}handleWindowError(e,t,i,n,r){if(e.toLowerCase().includes("script error"))this.logError("SCRIPT","Script error: See browser console for detail");else{const s=[e,"URL: "+t,"Line: "+i+", column: "+n,"Error: "+JSON.stringify(r)].join("
");this.logError("ERROR",s)}return!1}handleError(e,t){console.error(e,t);let i="Error";"string"==typeof e&&(i=e),e.message?i=`${e.message} (See console for more info)`:e.stack&&(i=`${e.stack}`),this.logger.log("error",i)}logError(e,t){this.logger.log("error",`${e} ${t}`)}logWarning(e,t){this.logger.log("warning",`${e} ${t}`)}logInfo(e,t){this.logger.log("info",`${e} ${t}`)}logDebug(e,t){this.logger.log("debug",`${e} ${t}`)}};Nn([re({type:String})],Dn.prototype,"examplespath",void 0),Nn([re({type:Object})],Dn.prototype,"hass",void 0),Nn([re({type:String||Object})],Dn.prototype,"_config",void 0),Nn([re({type:Boolean})],Dn.prototype,"isDemo",void 0),Nn([re({type:Boolean})],Dn.prototype,"isShowLog",void 0),Nn([re({type:Function})],Dn.prototype,"notify",void 0),Dn=Nn([ie("floorplan-element")],Dn);
+ `}clearLog(){this.logElement.querySelector("#log ul").innerHTML=""}updated(e){const t=Object.create(null,{updated:{get:()=>super.updated}});return Mn(this,void 0,void 0,(function*(){t.updated.call(this,e),e.has("_config")&&(yield this._configChanged(),yield this.hassChanged()),e.has("hass")&&(yield this.hassChanged())}))}_configChanged(){return Mn(this,void 0,void 0,(function*(){this._config&&(yield this.init())}))}hassChanged(){return Mn(this,void 0,void 0,(function*(){if(!this.hass||!this.config||!this.svg)return;const e=cn.deviceId();this.hass.states[`sensor.ha_floorplan_${e}`]={entity_id:`sensor.ha_floorplan_${e}`,state:"on",last_changed:(new Date).toString(),last_updated:(new Date).toString(),attributes:{device_class:"ha-floorplan",friendly_name:"ha-floorplan - Floorplan for Home Assistant",icon:"mdi:floor-plan",assumed_state:!1,hidden:!0},context:{}},this.isRulesLoaded?this.handleEntities():(this.initFloorplanRules(this.svg,this.config),this.isRulesLoaded=!0,yield this.handleEntities(!0))}))}get floorplanElement(){var e;return null===(e=this.shadowRoot)||void 0===e?void 0:e.getElementById("floorplan")}get logElement(){var e;return null===(e=this.shadowRoot)||void 0===e?void 0:e.getElementById("log")}init(){return Mn(this,void 0,void 0,(function*(){try{const e=yield this.loadConfig(this._config,!1);if(this.isShowLog=void 0!==e.log_level,this.logger=new On(this.logElement,e.log_level,e.console_log_level),this.logInfo("INIT","Floorplan for Home Assistant (ha-floorplan) v1.0.45"),!this.validateConfig(e))return;this.config=e,this.config.pages?yield this.initMultiPage():yield this.initSinglePage(),this.initEventListeners()}catch(e){this.handleError(e)}}))}initMultiPage(){return Mn(this,void 0,void 0,(function*(){try{yield this.loadPages(),this.initPageDisplay(),this.initVariables(),this.initStartupActions()}catch(e){this.handleError(e)}}))}initSinglePage(){return Mn(this,void 0,void 0,(function*(){try{yield this.loadStyleSheet(this.config.stylesheet);const e=this.getBestImage(this.config);this.svg=yield this.loadFloorplanSvg(e),this.initPageDisplay(),this.initVariables(),this.initStartupActions()}catch(e){this.handleError(e)}}))}loadConfig(e,t){return Mn(this,void 0,void 0,(function*(){if("string"==typeof e){let i;try{i=yield cn.fetchText(e,this.isDemo,this.examplespath,t)}catch(t){throw this.logError("CONFIG",`Error loading config: ${e}`),t}return an.load(i)}return JSON.parse(JSON.stringify(e))}))}loadScript(e,t){return e?new Promise(((i,n)=>{var r;const s=document.createElement("script");s.src=t?e:cn.cacheBuster(e),s.onload=()=>i(),s.onerror=e=>{n(new URIError(`${e.target.src}`))},null===(r=this.shadowRoot)||void 0===r||r.appendChild(s)})):Promise.resolve()}loadPages(){return Mn(this,void 0,void 0,(function*(){for(const e of this.config.pages)yield this.loadPageConfig(e,this.config.pages.indexOf(e));const e=Object.keys(this.pageInfos).map((e=>this.pageInfos[e]));e.sort(((e,t)=>e.index-t.index));const t=e.find((e=>void 0!==e.config.master_page));if(!t)throw new Error("A master page is required");t.isMaster=!0;const i=e.find((e=>void 0===e.config.master_page));i&&(i.isDefault=!0),yield this.loadPageFloorplanSvg(t,t);const n=e.filter((e=>e!==t));for(const e of n)yield this.loadPageFloorplanSvg(e,t);this.svg=t.svg}))}loadPageConfig(e,t){return Mn(this,void 0,void 0,(function*(){const i=yield this.loadConfig(e,!1),n=this.createPageInfo(i);return n.index=t,n}))}loadPageFloorplanSvg(e,t){return Mn(this,void 0,void 0,(function*(){const i=this.getBestImage(e.config),n=yield this.loadFloorplanSvg(i,e,t);n.id=e.config.page_id,e.svg=n,yield this.loadStyleSheet(e.config.stylesheet),this.initFloorplanRules(e.svg,e.config)}))}getBestImage(e){var t;let i="",n=!0;if("string"==typeof e.image)i=cn.isMobile&&"string"==typeof e.image_mobile?e.image_mobile:e.image;else if(null===(t=e.image)||void 0===t?void 0:t.sizes){e.image.sizes.sort(((e,t)=>t.min_width-e.min_width));for(const t of e.image.sizes)if(screen.width>=t.min_width){i=t.location,n=!0===t.cache;break}}else cn.isMobile&&e.image_mobile?(i=e.image_mobile.location,n=!0===e.image_mobile.cache):(i=e.image.location,n=!0===e.image.cache);return{location:i,cache:n}}createPageInfo(e){const t={config:e};return t.config.rules&&this.config.rules&&(t.config.rules=t.config.rules.concat(this.config.rules)),this.pageInfos[t.config.page_id]=t,t}loadStyleSheet(e){return Mn(this,void 0,void 0,(function*(){const t="string"==typeof e?e:e.location,i="string"!=typeof e&&!0===e.cache;if(!t)return;let n;try{n=yield cn.fetchText(t,this.isDemo,this.examplespath,i)}catch(e){throw this.logError("STYLESHEET",`Error loading stylesheet: ${t}`),e}const r=document.createElement("style"),s=()=>{var e;r.innerHTML=n,null===(e=this.shadowRoot)||void 0===e||e.appendChild(r)};try{yield cn.waitForChildNodes(r,s,1e4)}catch(e){this.logError("STYLESHEET","Error loading stylesheet")}const a=this.getCssRules(r);this.cssRules=this.cssRules.concat(a)}))}getCssRules(e){var t,i,n,r,s,a;let o;if(e.sheet)o=null!==(i=null===(t=e.sheet)||void 0===t?void 0:t.cssRules)&&void 0!==i?i:null===(n=e.sheet)||void 0===n?void 0:n.rules;else{const t=e;t.styleSheet&&(o=null!==(s=null===(r=t.styleSheet)||void 0===r?void 0:r.cssRules)&&void 0!==s?s:null===(a=t.styleSheet)||void 0===a?void 0:a.rules)}return o?cn.getArray(o):[]}loadFloorplanSvg(e,t,i){return Mn(this,void 0,void 0,(function*(){let n;try{n=yield cn.fetchText(e.location,this.isDemo,this.examplespath,e.cache)}catch(t){throw this.logError("IMAGE",`Error loading image: ${e.location}`),t}const r=document.createElement("div");r.innerHTML=n;const s=r.querySelector("svg");if(t&&s.setAttribute("id",t.config.page_id),s.setAttribute("height","100%"),s.setAttribute("width","100%"),s.style.height="100%",s.style.width="100%",s.style.margin="auto",s.style.cursor="default",s.style.opacity="0",s.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),t&&i){const e=i.config.page_id,n=i.config.master_page.content_element;if(t.config.page_id===e)this.floorplanElement&&this.replaceChildrenUtil(this.floorplanElement,s);else{const e=this.floorplanElement.querySelector("#"+n),t=Number.parseFloat(s.getAttribute("height")),i=Number.parseFloat(s.getAttribute("width"));s.getAttribute("viewBox")||s.setAttribute("viewBox",`0 0 ${i} ${t}`),s.setAttribute("preserveAspectRatio","xMinYMin meet"),s.setAttribute("height",e.getAttribute("height")),s.setAttribute("width",e.getAttribute("width")),s.setAttribute("x",e.getAttribute("x")),s.setAttribute("y",e.getAttribute("y")),(null==e?void 0:e.parentElement)&&this.replaceChildrenUtil(e.parentElement,s)}}else this.floorplanElement&&this.replaceChildrenUtil(this.floorplanElement,s);return s}))}replaceChildrenUtil(e,t){return Mn(this,void 0,void 0,(function*(){if(null==e?void 0:e.replaceChildren)e.replaceChildren(t);else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(t)}}))}loadImage(e,t,i,n,r){return Mn(this,void 0,void 0,(function*(){return e.toLowerCase().includes(".svg")||"svg"===t.svgElement.nodeName||t.svgElement.querySelector("svg")?yield this.loadSvgImage(e,t,i,n,r):yield this.loadBitmapImage(e,t,i,n,r)}))}loadBitmapImage(e,t,i,n,r){return Mn(this,void 0,void 0,(function*(){e=r?e:cn.cacheBuster(e),this.logDebug("IMAGE",`${i} (setting image: ${e})`);let s=t.svgElement;return"image"!==s.nodeName&&(s=this.createImageElement(t.originalSvgElement),t.svgElement=this.replaceElement(t.svgElement,s),this.attachClickHandlers(s,t,i,void 0,n),s.onmouseover=()=>{this.handleEntityIdSetHoverOver(i,t)}),s.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",e),s}))}loadSvgImage(e,t,i,n,r){return Mn(this,void 0,void 0,(function*(){let s;if(null==e?void 0:e.trim().length)try{s=yield cn.fetchText(e,this.isDemo,this.examplespath,r)}catch(t){throw this.logError("IMAGE",`Error loading image: ${e}`),t}else{const e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("viewBox","0 0 0 0"),s=e.outerHTML}this.logDebug("IMAGE",`${i} (setting image: ${e})`);const a="g"===t.svgElement.nodeName?t.svgElement:document.createElement("div");a.innerHTML=s;const o=a.querySelector("svg"),c=Number.parseFloat(o.getAttribute("height")),l=Number.parseFloat(o.getAttribute("width"));if(o.getAttribute("viewBox")||o.setAttribute("viewBox",`0 0 ${l} ${c}`),o.id=t.svgElement.id,o.setAttribute("preserveAspectRatio","xMinYMin meet"),null!==t.originalBBox&&(o.setAttribute("height",t.originalBBox.height.toString()),o.setAttribute("width",t.originalBBox.width.toString()),o.setAttribute("x",t.originalBBox.x.toString()),o.setAttribute("y",t.originalBBox.y.toString())),"g"!==t.svgElement.nodeName){const e=t.svgElement.getAttribute("transform");e&&o.setAttribute("transform",e),t.svgElement=this.replaceElement(t.svgElement,o)}return this.attachClickHandlers(o,t,i,void 0,n),t.svgElement.onmouseover=()=>{this.handleEntityIdSetHoverOver(i,t)},o}))}_querySelectorAll(e,t=void 0,i){let n=t?Array.from(e.querySelectorAll(t).values()):[];return n=i?[e].concat(n):n,n}replaceElement(e,t){const i=e.parentElement;for(const i of Array.from(e.classList))t.classList.add(i);return this._querySelectorAll(e,"*",!0).forEach((e=>{Ln.off(e,"click"),Ln.off(e,"longClick"),e.remove()})),e.remove(),null==i||i.appendChild(t),t}initPageDisplay(){if(this.config.pages)for(const e of Object.values(this.pageInfos))e.svg.style.opacity="1",e.svg.style.display=e.isMaster||e.isDefault?"initial":"none";else this.svg.style.opacity="1",this.svg.style.display="block"}initVariables(){if(this.config.variables)for(const e of this.config.variables)this.initVariable(e);if(this.config.pages)for(const e of Object.values(this.pageInfos))if(e.config.variables)for(const t of e.config.variables)this.initVariable(t)}initVariable(e){let t,i;if("string"==typeof e?t=e:(t=e.name,i=e.value,e.value&&(i=this.evaluate(e.value,t,void 0))),!this.entityInfos[t]){const e={entityId:t,ruleInfos:[],lastState:void 0};this.entityInfos[t]=e}this.hass.states[t]||(this.hass.states[t]={entity_id:t,state:i,last_changed:(new Date).toString(),last_updated:(new Date).toString(),attributes:{},context:{}}),this.setVariable(t,i,{},!0)}getActionConfigs(e){var t,i;if(null==e)return[];if(Array.isArray(e)){for(const i of e)i.action=null!==(t=i.action)&&void 0!==t?t:"call-service";return e}return"object"==typeof e?(e.action=null!==(i=e.action)&&void 0!==i?i:"call-service",[e]):"string"==typeof e?e.includes(".")?[{action:"call-service",service:e}]:[{action:e}]:[]}initEventListeners(){this.addEventListener(Tn,this.handleEventActionCall)}initStartupActions(){if(this.handleActions(this.config.startup_action,void 0,void 0,void 0),this.config.pages)for(const e of Object.values(this.pageInfos))this.handleActions(e.config.startup_action,void 0,void 0,void 0)}initFloorplanRules(e,t){if(!t.rules)return;const i=this._querySelectorAll(e,"*",!0);for(const e of i)e.id&&(this.svgElements[e.id]=e);this.initRules(t,e,i)}initRules(e,t,i){if(e.functions&&(this.functions=this.evaluate(e.functions)),e.defaults){const t=e.defaults;for(const i of e.rules)i.hover_action=void 0===i.hover_action?t.hover_action:i.hover_action,i.tap_action=void 0===i.tap_action?t.tap_action:i.tap_action,i.hold_action=void 0===i.hold_action?t.hold_action:i.hold_action,i.hover_info_filter=void 0===i.hover_info_filter?t.hover_info_filter:i.hover_info_filter}for(const n of e.rules)n.entity||n.entities?this.initEntityRule(n,t,i):(n.element||n.elements)&&this.initElementRule(n,t,i)}initEntityRule(e,t,i){const n=this.initGetEntityRuleEntities(e);for(const r of n){const n=r.entityId;let s=this.entityInfos[n];s||(s={entityId:n,ruleInfos:[],lastState:void 0},this.entityInfos[n]=s);const a=new dn(e);s.ruleInfos.push(a);for(const e of r.elementIds){const r=i.find((t=>t.id===e));if(!r){this.logWarning("CONFIG",`Cannot find element '${e}' in SVG file`);continue}const o=this.addSvgElementToRule(t,r,a);o.svgElement=r,r.querySelector("title")||r.appendChild(document.createElementNS("http://www.w3.org/2000/svg","title")),r.onmouseenter=()=>{this.handleEntitySetHoverOver(s,o)},r.onmouseleave=()=>{this.handleEntitySetHoverOver(s,o)},this.attachClickHandlers(r,o,n,void 0,a)}}}initGetEntityRuleEntities(e){const t=[];e.groups=e.groups?e.groups:[];for(const i of e.groups){const e=this.hass.states[i];if(e)for(const i of e.attributes.entity_id)this.addTargetEntity(i,[i],t);else this.logWarning("CONFIG",`Cannot find '${i}' in Home Assistant groups`)}e.entities=e.entities?e.entities:[],e.entities=e.entity?e.entities.concat(e.entity):e.entities;const i=e.entities.filter((e=>"string"==typeof e));for(const n of i){let i=[];e.elements?i=i.concat(e.elements):e.element?i=i.concat(this.evaluate(e.element,n,void 0)):null!==e.element&&(i=i.concat(n)),n&&"*"===n||this.addTargetEntity(n,i,t)}const n=e.entities.filter((e=>"string"!=typeof e));for(const e of n){const i=e;this.addTargetEntity(i.entity,[i.element],t)}return t}addTargetEntity(e,t,i){const n=this.hass.states[e],r="floorplan"===e.split(".")[0];n||r?i.push({entityId:e,elementIds:t}):this.logWarning("CONFIG",`Cannot find '${e}' in Home Assistant entities`)}initElementRule(e,t,i){if(e.element||e.elements){e.elements=e.elements?e.elements:[],e.elements=e.element?e.elements.concat(e.element):e.elements;for(const n of e.elements){const r=i.find((e=>e.id===n));if(r){let i=this.elementInfos[n];i||(i={ruleInfos:[],lastState:void 0},this.elementInfos[n]=i);const s=new dn(e);i.ruleInfos.push(s);const a=this.addSvgElementToRule(t,r,s);this.attachClickHandlers(r,a,void 0,n,s)}else this.logWarning("CONFIG",`Cannot find '${n}' in SVG file`)}}}attachClickHandlers(e,t,i,n,r){this._querySelectorAll(e,void 0,!0).forEach((s=>{const a=s,o=s===e;if(a.querySelector("title")||a.appendChild(document.createElementNS("http://www.w3.org/2000/svg","title")),r.rule.tap_action||r.rule.double_tap_action){const e=!!r.rule.tap_action&&this.getActionConfigs(r.rule.tap_action),s=!!r.rule.double_tap_action&&this.getActionConfigs(r.rule.double_tap_action),c=!!e&&new fn(this,i,n,t,r,e);if(e&&!s&&Ln.on(a,"click",this.onClick.bind(c)),s){const o=!!s&&new fn(this,i,n,t,r,s);In.observe(a),e&&Ln.on(a,"singleClick",this.onClick.bind(c)),Ln.on(a,"doubleClick",this.onLongClick.bind(o))}a.style&&(a.style.cursor="pointer"),cn.addClass(a,"floorplan-click"+(o?"":"-child"))}if(r.rule.hold_action){const e=this.getActionConfigs(r.rule.hold_action),s=new fn(this,i,n,t,r,e);En.observe(a),Ln.on(a,"longClick",this.onLongClick.bind(s)),a.style&&(a.style.cursor="pointer"),cn.addClass(a,"floorplan-long-click"+(o?"":"-child"))}}))}addSvgElementToRule(e,t,i){const n=t.getBBox?t.getBBox():null,r=new pn(t.id,t,t,n);return i.svgElementInfos[t.id]=r,r}createImageElement(e){const t=document.createElementNS("http://www.w3.org/2000/svg","image");return t.setAttribute("id",e.getAttribute("id")),t.setAttribute("x",e.getAttribute("x")),t.setAttribute("y",e.getAttribute("y")),t.setAttribute("height",e.getAttribute("height")),t.setAttribute("width",e.getAttribute("width")),t}handleEntities(e=!1){return Mn(this,void 0,void 0,(function*(){this.handleElements();const t=this.getChangedEntities(e);for(const e of Object.keys(this.variables))t.add(e);if(t.size)for(const e of t)yield this.handleEntity(e)}))}getChangedEntities(e){const t=new Set,i=Object.keys(this.hass.states),n=cn.deviceId();for(const r of i)if(r!==`sensor.ha_floorplan_${n}`||t.has(r)){const i=this.entityInfos[r];if(i){const n=this.hass.states[r];if(e)this.logDebug("STATE",`${r}: ${n.state} (initial load)`),t.has(r)||t.add(r);else if(i.lastState){const e=n.state;n.last_changed!==i.lastState.last_changed?(this.logDebug("STATE",`${r}: ${e} (last changed ${cn.formatDate(i.lastState.last_changed)})`),t.has(r)||t.add(r)):cn.equal(i.lastState.attributes,n.attributes)||(this.logDebug("STATE",`${r}: attributes (last updated ${cn.formatDate(i.lastState.last_changed)})`),t.has(r)||t.add(r))}}}else t.add(r);return t}handleEntity(e){return Mn(this,void 0,void 0,(function*(){const t=this.hass.states[e],i=this.entityInfos[e];if(i){i.lastState=Object.assign({},t);for(const e of i.ruleInfos){const t=Object.values(e.svgElementInfos);if(t.length)for(const n of t)n.svgElement&&this.handleActions(e.rule.state_action,i.entityId,n,e);else this.handleActions(e.rule.state_action,i.entityId,void 0,e)}}}))}handleElements(){return Mn(this,void 0,void 0,(function*(){for(const e of Object.values(this.elementInfos))for(const t of e.ruleInfos)for(const e of Object.values(t.svgElementInfos))this.handleActions(t.rule.state_action,void 0,e,t)}))}handleEntityIdSetHoverOver(e,t){const i=this.entityInfos[e];i&&this.handleEntitySetHoverOver(i,t)}handleEntitySetHoverOver(e,t){const i=e.entityId,n=this.hass.states[i];for(const i of e.ruleInfos)if(i.rule.hover_action){let r="string"==typeof i.rule.hover_action&&"hover-info"===i.rule.hover_action;if(r=r||"object"==typeof i.rule.hover_action&&"hover-info"===i.rule.hover_action.action,r=r||Array.isArray(i.rule.hover_action)&&i.rule.hover_action.some((e=>"hover-info"===e.action)),r){const e=new Set(i.rule.hover_info_filter);for(const t of Object.values(i.svgElementInfos))cn.addClass(t.svgElement,"floorplan-hover"),t.svgElement.style.cursor="pointer",t.svgElement.querySelectorAll("title").forEach((t=>{let i=`${n.attributes.friendly_name}\n`;i+=`State: ${n.state}\n\n`,Object.keys(n.attributes).map((t=>{e.has(t)||(i+=`${t}: ${n.attributes[t]}\n`)})),i+="\n",i+=`Last changed: ${ge.timeago(n.last_changed)}\n`,i+=`Last updated: ${ge.timeago(n.last_updated)}`,t.textContent=i}))}else i.rule.hover_action&&this.handleActions(i.rule.hover_action,e.entityId,t,i)}}isOptionEnabled(e){return null===e||void 0!==e}validateConfig(e){let t=!0;if(e.pages||e.rules)if(e.pages)e.pages.length||this.logWarning("CONFIG","The 'pages' section must contain one or more pages in floorplan configuration");else{e.rules||this.logWarning("CONFIG","Cannot find 'rules' in floorplan configuration");let i=e.rules.filter((e=>e.entities&&e.elements));i.length&&(this.logError("CONFIG","A rule cannot contain both 'entities' and 'elements' in floorplan configuration"),t=!1),i=e.rules.filter((e=>!(e.entity||e.entities||e.element||e.elements))),i.length&&(this.logError("CONFIG","A rule must contain either 'entities' or 'elements' in floorplan configuration"),t=!1)}else this.logWarning("CONFIG","Cannot find 'pages' nor 'rules' in floorplan configuration");return t}evaluate(e,t,i,n,r){if("string"!=typeof e||!Pn.isCode(e))return e;try{return Pn.evaluate(e,this.hass,this.config,t,i,this.svgElements,this.functions,n,r)}catch(n){return this.handleError(n,{expression:e,entityId:t,hass:this.hass,svgElement:i})}}onClick(e){e.stopPropagation(),e.preventDefault();const t=this;t.instance.handleActions(t.actions,t.entityId,t.svgElementInfo,t.ruleInfo)}onLongClick(e){e.stopPropagation(),e.preventDefault();const t=this,i=t.instance;setTimeout((()=>{i.handleActions(t.actions,t.entityId,t.svgElementInfo,t.ruleInfo)}),300)}handleActions(e,t,i,n){var r;const s=this.getActionConfigs(e);for(const e of s){if(e.confirmation&&(!e.confirmation.exemptions||!e.confirmation.exemptions.some((e=>e.user===this.hass.user.id)))&&!confirm(e.confirmation.text||`Are you sure you want to ${e.action}?`))return;switch(e.action){case"more-info":this.isDemo?this.notify(`Performing action: ${e.action} ${t}`):hn(this,"hass-more-info",{entityId:t});break;case"navigate":if(this.isDemo)this.notify(`Performing action: ${e.action} ${e.navigation_path}`);else{const n=this.evaluate(e.navigation_path,t,null==i?void 0:i.svgElement);un(0,n,null!==(r=e.navigation_replace)&&void 0!==r&&r)}break;case"url":if(this.isDemo)this.notify(`Performing action: ${e.action} ${e.url_path}`);else{const n=e.same_tab?"_self":"_blank",r=this.evaluate(e.url_path,t,null==i?void 0:i.svgElement);window.open(r,n)}break;case"toggle":if(t){const e={action:"call-service",service:"homeassistant.toggle",service_data:{entity_id:t}};this.callService(e,t,i,n)}break;case"call-service":if(!e.service)return;this.callService(e,t,i,n);break;case"fire-dom-event":hn(this,"ll-custom",e)}}}getSvgElementsFromServiceData(e,t){let i=[],n=[];if(Array.isArray(null==e?void 0:e.elements)&&(n=n.concat(null==e?void 0:e.elements)),"string"==typeof(null==e?void 0:e.element)&&(n=n.concat([null==e?void 0:e.element])),n.length)for(const e of n)i=i.concat(this._querySelectorAll(this.svg,`#${e.replace(/\./g,"\\.")}`,!1));else t&&(i=[t]);return i}getServiceData(e,t,i){let n={};if("object"==typeof e.service_data)for(const r of Object.keys(e.service_data))n[r]=this.evaluate(e.service_data[r],t,i);else if("string"==typeof e.service_data){const r=this.evaluate(e.service_data,t,i);n="string"==typeof r&&r.trim().startsWith("{")?JSON.parse(r):r}else void 0!==e.service_data&&(n=e.service_data);return n}executeServiceData(e,t,i,n,r){try{if("object"==typeof e.service_data)for(const s of Object.keys(e.service_data))this.evaluate(e.service_data[s],t,i,n,r);else"string"==typeof e.service_data?this.evaluate(e.service_data,t,i,n,r):void 0!==e.service_data&&this.logWarning("CONFIG","Invalid execution data");return!0}catch(e){return this.logWarning("CONFIG","Error thrown while executing service"),!1}}callService(e,t,i,n){const r=this.evaluate(e.service,t,null==i?void 0:i.svgElement),[s,a]=r.split(".",2);"floorplan"===s?this.callFloorplanService(s,a,e,t,i,n):this.callHomeAssistantService(s,a,e,t,i)}callFloorplanService(e,t,i,n,r,s){var a,o,c;const l=null!==(a=null==r?void 0:r.svgElement)&&void 0!==a?a:void 0;let h,u,p,d,f,m,g,v,y,b=[],x=null;switch(x=["execute"].includes(t)?{}:this.getServiceData(i,n,l),t){case"class_toggle":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),p="string"==typeof x?x:x.class,cn.toggleClass(e,p);break;case"class_set":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),p="string"==typeof x?x:x.class,cn.setClass(e,p);break;case"dataset_set":{let e,t;if("string"==typeof x){const i=x.split(":");if(i.length<2){this.logError("FLOORPLAN_ACTION",`Service data "${x}" is not a valid dataset key value pair.`);break}e=i[1],t=i[0]}else e=x.value,t=x.key;b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const s of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,s)),cn.datasetSet(s,t,e);break}case"style_set":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),d="string"==typeof x?x:x.style,cn.setStyle(e,d);break;case"text_set":b=this.getSvgElementsFromServiceData(x,null==r?void 0:r.svgElement);for(const e of b){y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||(x=this.getServiceData(i,n,e)),v="string"==typeof x?x:x.text;const t=(null===(o=i.service_data)||void 0===o?void 0:o.shift_y_axis)?null===(c=i.service_data)||void 0===c?void 0:c.shift_y_axis:"1em";cn.setText(e,v,t)}break;case"image_set":r&&s&&(x=this.getServiceData(i,n,null==r?void 0:r.svgElement),f="string"==typeof x?x:x.image,m="object"==typeof x?x.image_refresh_interval:0,g=!(m>0||"object"==typeof x&&!0!==x.cache),s.imageLoader&&clearInterval(s.imageLoader),m&&(s.imageLoader=setInterval(this.loadImage.bind(this),1e3*m,f,r,n,s,g)),this.loadImage(f,r,n,s,g));break;case"page_navigate":x=this.getServiceData(i,n,null==r?void 0:r.svgElement),h=x.page_id,u=h?this.pageInfos[h]:void 0,u&&(Object.keys(this.pageInfos).map((e=>{const t=this.pageInfos[e];t.isMaster||"none"===t.svg.style.display||(t.svg.style.display="none")})),u.svg.style.display="block");break;case"variable_set":if(x=this.getServiceData(i,n,null==r?void 0:r.svgElement),x.variable){const e={};if(x.attributes){const t=x.attributes;for(const i of Object.keys(t))e[i]=this.getActionValue(t[i],n,l)}const t=x,i=this.getActionValue(t,n,l);this.setVariable(x.variable,i,e,!1)}break;case"execute":this.executeServiceData(i,n,null==r?void 0:r.svgElement,r,s);for(const e of b)y=1===b.length&&b[0]===(null==r?void 0:r.svgElement),y||this.executeServiceData(i,n,e,r,s)}}getActionValue(e,t,i){let n=e.value;return e.value&&(n=this.evaluate(e.value,t,i)),n}setVariable(e,t,i,n){if(this.variables[e]=t,this.hass.states[e]){this.hass.states[e].state=t.toString();for(const t of Object.keys(i))this.hass.states[e].attributes[t]=i[t]}for(const e of Object.keys(this.variables)){const t=this.hass.states[e];t&&(t.last_changed=(new Date).toString())}n||this.handleEntities()}callHomeAssistantService(e,t,i,n,r){const s=this.getServiceData(i,n,null==r?void 0:r.svgElement);"object"==typeof s&&(null===s.entity_id||Array.isArray(s.entity_id)&&!s.entity_id.length||!s.entity_id&&n&&(s.entity_id=n)),this.hass.callService(e,t,s),this.isDemo&&this.notify(`Calling service: ${e}.${t} (${s.entity_id})`)}handleEventActionCall(e){const t=e,{actionConfig:i,entityId:n,svgElementInfo:r,ruleInfo:s}=t.detail;this.handleActions(i,n,r,s)}handleWindowError(e,t,i,n,r){if(e.toLowerCase().includes("script error"))this.logError("SCRIPT","Script error: See browser console for detail");else{const s=[e,"URL: "+t,"Line: "+i+", column: "+n,"Error: "+JSON.stringify(r)].join("
");this.logError("ERROR",s)}return!1}handleError(e,t){console.error(e,t);let i="Error";"string"==typeof e&&(i=e),e.message?i=`${e.message} (See console for more info)`:e.stack&&(i=`${e.stack}`),this.logger.log("error",i)}logError(e,t){this.logger.log("error",`${e} ${t}`)}logWarning(e,t){this.logger.log("warning",`${e} ${t}`)}logInfo(e,t){this.logger.log("info",`${e} ${t}`)}logDebug(e,t){this.logger.log("debug",`${e} ${t}`)}};Nn([re({type:String})],Dn.prototype,"examplespath",void 0),Nn([re({type:Object})],Dn.prototype,"hass",void 0),Nn([re({type:String||Object})],Dn.prototype,"_config",void 0),Nn([re({type:Boolean})],Dn.prototype,"isDemo",void 0),Nn([re({type:Boolean})],Dn.prototype,"isShowLog",void 0),Nn([re({type:Function})],Dn.prototype,"notify",void 0),Dn=Nn([ie("floorplan-element")],Dn);
/**
* @license
* Copyright 2017 Google LLC