From 5b5a7304f76dfcc88a34400bba514277129923e2 Mon Sep 17 00:00:00 2001
From: Cloos <36499953+Clooos@users.noreply.github.com>
Date: Thu, 28 Sep 2023 21:29:46 +0200
Subject: [PATCH] BETA 9
---
bubble-card.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bubble-card.js b/bubble-card.js
index 0f066376..4a872150 100644
--- a/bubble-card.js
+++ b/bubble-card.js
@@ -1 +1 @@
-var version="v0.0.1-beta.9";class BubbleCard extends HTMLElement{constructor(){super();const t=history.pushState;history.pushState=function(){t.apply(history,arguments),window.dispatchEvent(new Event("pushstate"))};const e=history.replaceState;history.replaceState=function(){e.apply(history,arguments),window.dispatchEvent(new Event("replacestate"))},["popstate","pushstate","replacestate","mousedown","touchstart"].forEach((t=>{window.addEventListener(t,i)}));const n=new Event("urlChanged");function i(){const t=window.location.href;t!==this.currentUrl&&(window.dispatchEvent(n),this.currentUrl=t)}const o=()=>{window.dispatchEvent(n),setTimeout((()=>{window.removeEventListener("popUpInitialized",o)}),1e3)};window.addEventListener("popUpInitialized",o)}set hass(hass){function toggleEntity(t){hass.callService("homeassistant","toggle",{entity_id:t})}this.content||(this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML='\n \n \n
\n \n ',this.card=this.shadowRoot.querySelector("ha-card"),this.content=this.shadowRoot.querySelector("div")),"?edit=1"!==window.location.search?this.editor=!1:this.editor=!0;const addStyles=function(context,styles,customStyles,state,entityId,path="",element=context.content){const customStylesEval=customStyles?eval("`"+customStyles+"`"):"";let styleAddedKey=styles+"Added";if(!context[styleAddedKey]||context.previousStyle!==customStylesEval){if(!context[styleAddedKey]){if(context.styleElement=context.content.querySelector("style"),!context.styleElement){context.styleElement=document.createElement("style");const t=path?context.content.querySelector(path):element;t.appendChild(context.styleElement)}context[styleAddedKey]=!0}context.styleElement.innerHTML=customStylesEval+styles,context.previousStyle=customStylesEval}},forwardHaptic=t=>{fireEvent(window,"haptic",t)},navigate=(t,e,n=!1)=>{n?history.replaceState(null,"",e):history.pushState(null,"",e),fireEvent(window,"location-changed",{replace:n})},handleActionConfig=(t,e,n,i)=>{if(!i.confirmation||i.confirmation.exemptions&&i.confirmation.exemptions.some((t=>t.user===e.user.id))||(forwardHaptic("warning"),confirm(i.confirmation.text||`Are you sure you want to ${i.action}?`)))switch(i.action){case"more-info":(this.config.entity||this.config.camera_image)&&fireEvent(t,"hass-more-info",{entityId:this.config.entity?this.config.entity:this.config.camera_image});break;case"navigate":i.navigation_path&&navigate(t,i.navigation_path);break;case"url":i.url_path&&window.open(i.url_path);break;case"toggle":this.config.entity&&(toggleEntity(this.config.entity),forwardHaptic("success"));break;case"call-service":{if(!i.service)return void forwardHaptic("failure");const[t,n]=i.service.split(".",2);e.callService(t,n,i.service_data,i.target),forwardHaptic("success");break}case"fire-dom-event":fireEvent(t,"ll-custom",i)}},handleAction=(t,e,n,i)=>{let o;"double_tap"===i&&this.config.double_tap_action?o=this.config.double_tap_action:"hold"===i&&this.config.hold_action?o=this.config.hold_action:"tap"===i&&this.config.tap_action?o=this.config.tap_action:"double_tap"!==i||this.config.double_tap_action?("hold"!==i||this.config.hold_action)&&("tap"!==i||this.config.tap_action)||(o={action:"more-info"}):o={action:"toggle"},handleActionConfig(t,e,n,o)},addAction=function(){let t,e;return function(n,i,o,a){o.addEventListener(n,(()=>{const i=(new Date).getTime();"click"===n?i-(e||0)<250?(clearTimeout(t),handleAction(a,hass,{},"double_tap")):t=setTimeout((()=>{handleAction(a,hass,{},"tap")}),250):handleAction(a,hass,{},"hold"),e=i}))}}();function addActions(t,e){addAction("click","tap",e,t),addAction("contextmenu","hold",e,t)}const customStyles=this.config.styles?this.config.styles:"";let entityId=this.config.entity?this.config.entity:"",icon=!this.config.icon&&this.config.entity?hass.states[entityId].attributes.icon||hass.states[entityId].attributes.entity_picture||"":this.config.icon||"",name=this.config.name?this.config.name:this.config.entity?hass.states[entityId].attributes.friendly_name:"",widthDesktop=this.config.width_desktop||"540px",widthDesktopDivided=widthDesktop?widthDesktop.match(/(\d+)(\D+)/):"",isSidebarHidden=this.config.is_sidebar_hidden||!1,state=this.config.state?hass.states[this.config.state].state:"",formatedState;switch(this.config.card_type){case"pop-up":if(this.getRootNode().host){if(!this.popUp){this.card.style.marginTop="0",this.popUp=this.getRootNode().querySelector("#root");const J=new Event("popUpInitialized");window.dispatchEvent(J)}const H=this.config.hash,Y=this.popUp,B=this.config.text||"",q=this.config.trigger_entity?this.config.trigger_entity:"",F=this.config.trigger_state?this.config.trigger_state:"",X=!!this.config.trigger_close&&this.config.trigger_close;formatedState=this.config.state?hass.formatEntityState(hass.states[this.config.state])+" "+B:B;const j=this.config.margin_top_mobile&&"0"!==this.config.margin_top_mobile?this.config.margin_top_mobile:"0px",W=this.config.margin_top_desktop&&"0"!==this.config.margin_top_desktop?this.config.margin_top_desktop:"0px",R=this.config.entity?"flex":"none";if(this.headerAdded){if(this.headerAdded){const Z=this.content.querySelector("#header-container .header-icon");if(Z.innerHTML="",hass&&hass.states&&hass.states[entityId]&&hass.states[entityId].attributes.entity_picture&&!this.config.icon){const nt=document.createElement("img");nt.setAttribute("src",hass.states[entityId].attributes.entity_picture),nt.setAttribute("class","entity-picture"),nt.setAttribute("alt","Icon"),Z.appendChild(nt)}else{const it=document.createElement("ha-icon");it.setAttribute("icon",icon),it.setAttribute("class","icon"),Z.appendChild(it)}const Q=this.content.querySelector("#header-container h2");Q.textContent=name;const tt=this.content.querySelector("#header-container p");tt.textContent=formatedState;const et=this.content.querySelector("#header-container .power-button");et.setAttribute("style",`display: ${R};`)}}else{const ot=document.createElement("div");ot.setAttribute("id","header-container");const at=document.createElement("div");ot.appendChild(at);const st=document.createElement("div");if(st.setAttribute("class","header-icon"),at.appendChild(st),hass&&hass.states&&hass.states[entityId]&&hass.states[entityId].attributes.entity_picture&&!this.config.icon){const pt=document.createElement("img");pt.setAttribute("src",hass.states[entityId].attributes.entity_picture),pt.setAttribute("class","entity-picture"),pt.setAttribute("alt","Icon"),st.appendChild(pt)}else{const ut=document.createElement("ha-icon");ut.setAttribute("icon",icon),ut.setAttribute("class","icon"),st.appendChild(ut)}addActions(this,st);const rt=document.createElement("h2");rt.textContent=name,at.appendChild(rt);const ct=document.createElement("p");ct.textContent=formatedState,at.appendChild(ct);const dt=document.createElement("ha-icon");dt.setAttribute("class","power-button"),dt.setAttribute("icon","mdi:power"),dt.setAttribute("style",`display: ${R};`),at.appendChild(dt);const lt=document.createElement("button");lt.setAttribute("class","close-pop-up"),lt.onclick=function(){history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0)},ot.appendChild(lt);const ht=document.createElement("ha-icon");ht.setAttribute("icon","mdi:close"),lt.appendChild(ht),this.content.appendChild(ot),this.header=at,this.headerAdded=!0}if(!this.eventAdded){let gt,mt;window["checkHashRef_"+H]=U,window.addEventListener("urlChanged",window["checkHashRef_"+H]),this.content.querySelector(".power-button").addEventListener("click",(()=>{toggleEntity(entityId)})),window.addEventListener("mousedown",(function(t){location.hash!==H||t.composedPath().some((t=>"HA-MORE-INFO-DIALOG"===t.nodeName))||t.composedPath().some((t=>"root"===t.id&&!t.classList.contains("close-pop-up")))||(history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0))})),window.addEventListener("keydown",(function(t){"Escape"===t.key&&(history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0))})),Y.addEventListener("touchstart",(function(t){gt=t.touches[0].clientY,mt=gt})),Y.addEventListener("touchmove",(function(t){t.touches[0].clientY-gt>300&&t.touches[0].clientY>mt&&(history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0)),mt=t.touches[0].clientY})),this.eventAdded=!0}if(q){let ft=localStorage.getItem("previousTriggerState_"+H),bt="true"===localStorage.getItem("isManuallyClosed_"+H),yt="true"===localStorage.getItem("isTriggered_"+H);(hass.states[q].state===F&&null===ft||!yt)&&(navigate("",H),yt=!0,localStorage.setItem("isTriggered_"+H,yt)),hass.states[q].state!==ft&&(bt=!1,localStorage.setItem("previousTriggerState_"+H,hass.states[q].state),localStorage.setItem("isManuallyClosed_"+H,bt)),hass.states[q].state!==F||bt?X&&Y.classList.contains("open-pop-up")&&yt&&!bt&&(history.replaceState(null,null,location.href.split("#")[0]),yt=!1,bt=!0,localStorage.setItem("isManuallyClosed_"+H,bt),localStorage.setItem("isTriggered_"+H,yt)):(navigate("",H),yt=!0,localStorage.setItem("isTriggered_"+H,yt))}if(""!==entityId){const vt=hass.states[entityId].attributes.rgb_color,_t=vt?`rgba(${vt[0]}, ${vt[1]}, ${vt[2]}, 0.5)`:"off"!==hass.states[entityId].state?"var(--accent-color)":"var(--background-color,var(--secondary-background-color))";this.header.style.backgroundColor=_t}function U(){if(!this.editor){location.hash.split("?")[0]===H?N():Y.classList.contains("open-pop-up")&&P()}}function N(){Y.classList.remove("close-pop-up"),Y.classList.add("open-pop-up")}function P(){Y.classList.remove("open-pop-up"),Y.classList.add("close-pop-up")}const K=`\n ha-card {\n margin-top: 0 !important;\n background: none !important;\n border: none !important;\n }\n .card-content {\n width: 100% !important;\n padding: 0 !important;\n }\n #root {\n position: fixed !important;\n margin: 0 -7px;\n width: 100%;\n background-color: var(--ha-card-background,var(--card-background-color));\n border-radius: 42px;\n box-sizing: border-box;\n top: calc(100% + ${j} + var(--header-height));\n grid-gap: 12px !important;\n gap: 12px !important;\n grid-auto-rows: min-content;\n padding: 18px 18px 220px 18px !important;\n height: 100% !important;\n -ms-overflow-style: none; /* for Internet Explorer, Edge */\n scrollbar-width: none; /* for Firefox */\n overflow-y: auto; \n overflow-x: hidden; \n z-index: 1 !important; /* Higher value hide the more-info panel */\n /* For older Safari but not working with Firefox */\n /* display: grid !important; */ \n }\n #root > bubble-card:first-child::after {\n content: '';\n display: block;\n position: sticky;\n top: 0;\n left: -50px;\n margin: -70px 0 -35px 0;\n width: 200%;\n height: 100px;\n background: linear-gradient(0deg, rgba(79, 69, 87, 0) 0%, var(--ha-card-background,var(--card-background-color)) 80%);\n z-index: 0;\n }\n #root::-webkit-scrollbar {\n display: none; /* for Chrome, Safari, and Opera */\n }\n #root > bubble-card:first-child {\n position: sticky;\n top: 0;\n z-index: 1;\n background: none !important;\n }\n #root.open-pop-up {\n transform: translateY(-100%);\n transition: transform .4s !important;\n }\n #root.open-pop-up > * {\n /* Block child items to overflow and if they do clip them */\n /*max-width: calc(100vw - 38px);*/\n max-width: 100% !important;\n overflow-x: clip;\n }\n #root.close-pop-up { \n transform: translateY(0%);\n transition: transform .4s !important;\n /* animation: hide 1s forwards; */\n }\n @media only screen and (min-width: 768px) {\n #root {\n top: calc(100% + ${W} + var(--header-height));\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]});\n margin: 0 !important;\n }\n } \n @media only screen and (min-width: 870px) {\n #root {\n top: calc(100% + ${W} + var(--header-height));\n width: calc(${widthDesktop}${"%"===widthDesktopDivided[2]?" - var(--mdc-drawer-width)":""}) !important;\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]} + ${!0===isSidebarHidden?"0px":"var(--mdc-drawer-width) "+("%"===widthDesktopDivided[2]?"":"/ 2")});\n margin: 0 !important;\n }\n } \n #root.editor {\n position: inherit !important;\n width: 100% !important;\n padding: 18px !important;\n }\n `,G=`\n #header-container {\n display: inline-flex;\n ${icon||name||entityId||state||B?"":"flex-direction: row-reverse;"}\n width: 100%;\n margin: 0;\n padding: 0;\n }\n #header-container > div {\n display: ${icon||name||entityId||state||B?"inline-flex":"none"};\n align-items: center;\n position: relative;\n padding: 6px;\n z-index: 1;\n flex-grow: 1;\n background-color: var(--background-color,var(--secondary-background-color));\n transition: background 1s;\n border-radius: 25px;\n margin-right: 14px;\n }\n .header-icon {\n display: inline-flex;\n width: 22px;\n height: 22px;\n padding: 8px;\n background-color: var(--card-background-color,var(--ha-card-background));\n border-radius: 100%;\n margin: 0 10px 0 0;\n cursor: ${this.config.entity||this.config.double_tap_action||this.config.tap_action||this.config.hold_action?"pointer":"default"}; \n flex-wrap: wrap;\n align-content: center;\n justify-content: center;\n overflow: hidden;\n }\n .entity-picture {\n height: calc(100% + 16px);\n width: calc(100% + 16px);\n }\n #header-container h2 {\n display: inline-flex;\n margin: 0 18px 0 0;\n /*line-height: 0px;*/\n z-index: 1;\n font-size: 20px;\n }\n #header-container p {\n display: inline-flex;\n line-height: 0px;\n font-size: 16px;\n }\n .power-button {\n cursor: pointer; \n flex-grow: inherit; \n width: 24px;\n height: 24px;\n border-radius: 12px;\n margin: 0 10px;\n background: none !important;\n justify-content: flex-end;\n background-color: var(--background-color,var(--secondary-background-color));\n }\n .close-pop-up {\n height: 50px;\n width: 50px;\n border: none;\n border-radius: 50%;\n z-index: 1;\n background: var(--background-color,var(--secondary-background-color));\n color: var(--primary-text-color);\n flex-shrink: 0;\n cursor: pointer;\n }\n `;addStyles(this,K,customStyles,state,entityId,"",Y),addStyles(this,G,customStyles,state,entityId),!0===this.editor?(Y.classList.add("editor"),Y.classList.remove("open-pop-up"),Y.classList.remove("close-pop-up")):Y.classList.remove("editor")}else!0!==this.editor&&(this.card.style.marginTop="2000px");break;case"horizontal-buttons-stack":const t=(t,e,n)=>{const i=document.createElement("button");return i.onclick=function(){navigate("",e)},i.setAttribute("class","button"),i.innerHTML=`\n ${""!==n?` `:""}\n ${""!==t?`
${t}
`:""}\n `,i},e=(t,e)=>{if(hass.states[e].attributes.rgb_color){const n=hass.states[e].attributes.rgb_color,i=`rgba(${n[0]}, ${n[1]}, ${n[2]}, 0.5)`;t.style.backgroundColor=i,t.style.border="1px solid rgba(0,0,0,0)"}else hass.states[e].attributes.rgb_color||"on"!=hass.states[e].state?(t.style.backgroundColor="rgba(0,0,0,0)",t.style.border="1px solid var(--primary-text-color)"):(t.style.backgroundColor="rgba(255,255,255,0.5)",t.style.border="1px solid rgba(0,0,0,0)")};if(!this.buttonsAdded){const xt=document.createElement("div");xt.setAttribute("class","horizontal-buttons-stack-container"),this.content.appendChild(xt),this.buttonsContainer=xt}const n=()=>{let n=[],i=1;for(;this.config[i+"_link"];){const t=i+"_",e=this.config[t+"name"]||"",o=this.config[t+"pir_sensor"];icon=this.config[t+"icon"]||"";const a=this.config[t+"link"],s=this.config[t+"entity"];n.push({button:e,pirSensor:o,icon:icon,link:a,lightEntity:s}),i++}if(this.config.auto_order&&n.sort(((t,e)=>{if(t.pirSensor&&e.pirSensor){if("on"===hass.states[t.pirSensor].state&&"on"===hass.states[e.pirSensor].state){return hass.states[t.pirSensor].last_updated{const i=t(n.button,n.link,n.icon);e[n.link]=i,this.buttonsContainer.appendChild(i)})),this.buttonsAdded=!0,this.buttons=e}this.editor?localStorage.setItem("justExitedEditor",!1):"false"===localStorage.getItem("justExitedEditor")&&localStorage.setItem("justExitedEditor",!0);let o=0,a=12;const s="true"===localStorage.getItem("editorMode")&&!this.editor;n.forEach(((t,n)=>{let i=this.buttons[t.link];if(i){let e=localStorage.getItem(`buttonWidth-${t.link}`),n=localStorage.getItem(`buttonContent-${t.link}`);(!e||"0"===e||n!==i.innerHTML||this.editor||s)&&(e=i.offsetWidth,localStorage.setItem(`buttonWidth-${t.link}`,e),localStorage.setItem(`buttonContent-${t.link}`,i.innerHTML),this.editor?a=36:s&&(a=12)),i.style.transform=`translateX(${o}px)`,o+=parseInt(e)+a}t.lightEntity&&e(i,t.lightEntity)}))};n();const i=`\n ha-card {\n border-radius: 0;\n }\n .horizontal-buttons-stack {\n width: 100%;\n margin-top: 0 !important;\n background: none !important;\n position: fixed;\n height: 51px;\n bottom: 16px;\n left: 7px;\n /* transform: translateY(200px); */\n /* animation: from-bottom 1.3s forwards; */\n z-index: 1 !important; /* Higher value hide the more-info panel */\n }\n @keyframes from-bottom {\n 0% {transform: translateY(200px);}\n 20% {transform: translateY(200px);}\n 46% {transform: translateY(-8px);}\n 56% {transform: translateY(1px);}\n 62% {transform: translateY(-2px);}\n 70% {transform: translateY(0);}\n 100% {transform: translateY(0);}\n }\n .horizontal-buttons-stack-container {\n width: max-content;\n position: relative;\n height: 51px;\n }\n .button {\n display: flex;\n position: absolute;\n /* box-sizing: border-box; */\n border: 1px solid var(--primary-text-color);\n align-items: center;\n height: 50px;\n white-space: nowrap;\n width: auto;\n border-radius: 25px;\n z-index: 1;\n padding: 16px;\n background: none;\n transition: background-color 1s, border 1s, transform 1s;\n color: var(--primary-text-color);\n }\n .icon {\n height: 24px;\n }\n .card-content {\n width: calc(100% + 18px);\n box-sizing: border-box;\n margin: 0 -36px !important;\n padding: 0 36px !important;\n overflow: scroll !important;\n -ms-overflow-style: none;\n scrollbar-width: none;\n -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 1) calc(0% + 28px), rgba(0, 0, 0, 1) calc(100% - 28px), transparent 100%);\n /* mask-image: linear-gradient(90deg, transparent 2%, rgba(0, 0, 0, 1) 6%, rgba(0, 0, 0, 1) 96%, transparent 100%); */\n /* -webkit-mask-image: linear-gradient(90deg, transparent 2%, rgba(0, 0, 0, 1) 6%, rgba(0, 0, 0, 1) 96%, transparent 100%); */\n }\n .horizontal-buttons-stack::before {\n content: '';\n position: absolute;\n top: -32px;\n left: -100%;\n display: block;\n background: linear-gradient(0deg, var(--background-color, var(--primary-background-color)) 50%, rgba(79, 69, 87, 0));\n width: 200%;\n height: 100px;\n }\n .card-content::-webkit-scrollbar {\n display: none;\n }\n @media only screen and (min-width: 768px) {\n .card-content {\n position: fixed;\n width: ${widthDesktop} !important;\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]});\n margin-left: -13px !important;\n padding: 0 26px !important;\n }\n }\n @media only screen and (min-width: 870px) {\n .card-content {\n position: fixed;\n width: calc(${widthDesktop}${"%"===widthDesktopDivided[2]?" - var(--mdc-drawer-width)":""}) !important;\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]} + ${!0===isSidebarHidden?"0px":"var(--mdc-drawer-width) "+("%"===widthDesktopDivided[2]?"":"/ 2")});\n margin-left: -13px !important;\n padding: 0 26px !important;\n }\n }\n \n .horizontal-buttons-stack.editor {\n position: relative;\n bottom: 0;\n left: 0;\n overflow: hidden;\n }\n \n .horizontal-buttons-stack.editor::before {\n top: -32px;\n left: -100%;\n background: none;\n width: 100%;\n height: 0;\n }\n \n .horizontal-buttons-stack-container.editor > .button {\n transition: background-color 0s, border 0s, transform 0s;\n }\n \n .horizontal-buttons-stack-container.editor {\n margin-left: 1px;\n }\n \n .horizontal-buttons-stack.editor > .card-content {\n position: relative;\n width: calc(100% + 26px) !important;\n left: -26px;\n margin: 0 !important;\n padding: 0;\n }\n `;addStyles(this,i,customStyles),this.editor?(this.buttonsContainer.classList.add("editor"),this.card.classList.add("editor")):(this.buttonsContainer.classList.remove("editor"),this.card.classList.remove("editor"));break;case"button":if(!this.buttonAdded){const wt=document.createElement("div");wt.setAttribute("class","button-container"),this.content.appendChild(wt)}const o=this.config.button_type||"switch";formatedState=hass.formatEntityState(hass.states[entityId]);const a=!!this.config.show_state&&this.config.show_state;let s=entityId?hass.states[entityId].attributes.brightness||0:"",r=entityId?hass.states[entityId].attributes.volume_level||0:"",c=!1,d=s,l=r,h=0,p=0,u=0,g=!1,m=null;const f=document.createElement("div");f.setAttribute("class","icon-container"),this.iconContainer=f;const b=document.createElement("div");b.setAttribute("class","name-container");const y=document.createElement("div");y.setAttribute("class","switch-button");const v=document.createElement("div");v.setAttribute("class","range-slider");const _=document.createElement("div");if(_.setAttribute("class","range-fill"),entityId&&entityId.startsWith("light.")&&"slider"===o?_.style.transform=`translateX(${s/255*100}%)`:entityId&&entityId.startsWith("media_player.")&&"slider"===o&&(_.style.transform=`translateX(${100*r}%)`),!this.buttonContainer||this.editor){if(this.editor&&this.buttonContainer){for(;this.buttonContainer.firstChild;)this.buttonContainer.removeChild(this.buttonContainer.firstChild);this.eventAdded=!1}this.buttonContainer=this.content.querySelector(".button-container"),"slider"!==o||this.buttonAdded&&!this.editor?("switch"===o||"custom"===o||this.editor)&&(this.buttonContainer.appendChild(y),y.appendChild(f),y.appendChild(b),this.switchButton=this.content.querySelector(".switch-button")):(this.buttonContainer.appendChild(v),v.appendChild(f),v.appendChild(b),v.appendChild(_),this.rangeFill=this.content.querySelector(".range-fill")),!hass.states[entityId].attributes.entity_picture&&!icon.startsWith("/api/image/")||this.config.icon?f.innerHTML=` `:f.innerHTML=` `,b.innerHTML=`\n ${name}
\n ${a?`${formatedState}
`:""}\n `,this.buttonAdded=!0}function x(t){let e=t.querySelector(".feedback-element");e||(e=document.createElement("div"),e.setAttribute("class","feedback-element"),t.appendChild(e)),e.style.animation="tap-feedback .5s",setTimeout((()=>{e.style.animation="none",t.removeChild(e)}),500)}function w(t){h=t.pageX||(t.touches?t.touches[0].pageX:0),p=t.pageY||(t.touches?t.touches[0].pageY:0),u=v.value,t.target!==f.querySelector("ha-icon")&&(c=!0,document.addEventListener("mouseup",$),document.addEventListener("touchend",$),document.addEventListener("mousemove",k),document.addEventListener("touchmove",k),m=setTimeout((()=>{I(t.pageX||t.touches[0].pageX),C(),m=null}),200))}function k(t){const e=t.pageX||(t.touches?t.touches[0].pageX:0),n=t.pageY||(t.touches?t.touches[0].pageY:0);Math.abs(n-p)>Math.abs(e-h)?(clearTimeout(m),$()):(document.removeEventListener("mousemove",k),document.removeEventListener("touchmove",k),document.addEventListener("mousemove",S),document.addEventListener("touchmove",S))}function $(){c=!1,g=!1,C(),document.removeEventListener("mouseup",$),document.removeEventListener("touchend",$),document.removeEventListener("mousemove",S),document.removeEventListener("touchmove",S)}function C(){entityId.startsWith("light.")?(s=d,hass.callService("light","turn_on",{entity_id:entityId,brightness:s})):r!==l&&entityId.startsWith("media_player.")&&(r=l,hass.callService("media_player","volume_set",{entity_id:entityId,volume_level:r}))}function S(t){const e=t.pageX||(t.touches?t.touches[0].pageX:0),n=t.pageY||(t.touches?t.touches[0].pageY:0);c&&Math.abs(e-h)>10?I(e):c&&Math.abs(n-p)>10&&(c=!1,v.value=u)}function E(t,e){if(e.buttonContainer.style.opacity="unavailable"!==t?"1":"0.5",["switch","custom"].includes(o)){const n=["on","open","cleaning","true","home","playing"].includes(t)?"var(--accent-color)":"rgba(0,0,0,0)";e.switchButton.style.backgroundColor=n}}function I(t){const e=v.getBoundingClientRect(),n=Math.min(Math.max(t-e.left,0),e.width)/e.width;entityId.startsWith("light.")?d=Math.round(255*n):entityId.startsWith("media_player.")&&(l=n),_.style.transition="none",_.style.transform=`translateX(${100*n}%)`}if(a&&(this.content.querySelector(".state").textContent=formatedState),this.eventAdded||"switch"!==o?this.eventAdded||"slider"!==o?this.eventAdded||"custom"!==o||(y.addEventListener("click",(()=>x(this.switchButton))),addActions(this,this.switchButton),this.eventAdded=!0):(v.addEventListener("mousedown",w),v.addEventListener("touchstart",w),addActions(this,this.iconContainer),this.eventAdded=!0):(y.addEventListener("click",(()=>x(this.switchButton))),y.addEventListener("click",(function(t){t.target.closest("ha-icon")||toggleEntity(entityId)})),addActions(this,this.iconContainer),this.eventAdded=!0),this.isDragging||"slider"!==o||(this.rangeFill.style.transition="all .2s",entityId.startsWith("light.")?this.rangeFill.style.transform=`translateX(${s/255*100}%)`:entityId.startsWith("media_player.")&&(this.rangeFill.style.transform=`translateX(${100*r}%)`)),E(state,this),"slider"===o)if(entityId.startsWith("light.")){const kt=hass.states[entityId].attributes.rgb_color,$t=kt?`rgba(${kt[0]}, ${kt[1]}, ${kt[2]}, 0.5)`:"rgba(255, 255, 255, 0.5)";this.rangeFill.style.backgroundColor=$t}else this.rangeFill.style.backgroundColor="var(--accent-color)";const A=`\n ha-card {\n margin-top: 0 !important;\n background: none !important;\n }\n \n .button-container {\n position: relative;\n width: 100%;\n height: 50px;\n z-index: 0;\n background-color: var(--background-color-2,var(--secondary-background-color));\n border-radius: 25px;\n mask-image: radial-gradient(white, black);\n -webkit-mask-image: radial-gradient(white, black);\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n -webkit-transform: translateZ(0);\n overflow: hidden;\n }\n \n .switch-button,\n .range-slider {\n display: inline-flex;\n position: absolute;\n height: 100%;\n width: 100%;\n transition: background-color 1.5s;\n }\n \n .range-fill {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n }\n \n .switch-button {\n cursor: pointer !important;\n }\n \n .range-slider {\n cursor: ew-resize;\n }\n \n .range-fill {\n z-index: 0;\n width: 100%;\n left: -100%;\n }\n \n .icon-container {\n position: absolute;\n z-index: 1;\n width: 38px;\n height: 38px;\n margin: 6px;\n border-radius: 50%;\n background-color: var(--card-background-color,var(--ha-card-background));\n cursor: pointer !important;\n }\n \n ha-icon {\n display: flex;\n position: absolute;\n margin: inherit;\n padding: 1px 2px;\n width: 22px; \n height: 22px;\n }\n \n .entity-picture {\n height: inherit;\n border-radius: 100%;\n }\n \n .name-container {\n position: relative;\n display: ${a?"block":"inline-flex"};\n margin-left: 58px;\n z-index: 1;\n font-weight: 600;\n align-items: center;\n line-height: ${a?"4px":"16px"};\n }\n \n .state {\n font-size: 12px;\n opacity: 0.7;\n }\n \n .feedback-element {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n width: 100%;\n height: 100%;\n background-color: rgb(0,0,0);\n }\n \n @keyframes tap-feedback {\n 0% {transform: translateX(-100%); opacity: 0;}\n 64% {transform: translateX(0); opacity: 0.1;}\n 100% {transform: translateX(100%); opacity: 0;}\n }\n `;addStyles(this,A,customStyles,state,entityId);break;case"separator":if(!this.separatorAdded||this.editor){if(this.editor&&this.separatorContainer)for(;this.separatorContainer.firstChild;)this.separatorContainer.removeChild(this.separatorContainer.firstChild);this.separatorAdded||(this.separatorContainer=document.createElement("div"),this.separatorContainer.setAttribute("class","separator-container")),this.separatorContainer.innerHTML=`\n \n \n
${name} \n \n
\n `,this.content.appendChild(this.separatorContainer),this.separatorAdded=!0}const L="\n .separator-container {\n display: inline-flex;\n width: 100%;\n }\n .separator-container div:first-child {\n display: inline-flex;\n max-width: calc(100% - 38px);\n }\n .separator-container div ha-icon{\n display: inline-flex;\n height: 24px;\n width: 24px;\n margin: 0 20px 0 8px;\n transform: translateY(-2px);\n }\n .separator-container div h4{\n display: inline-flex;\n margin: 0 20px 0 0;\n font-size: 17px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .separator-container div:last-child{\n display: inline-flex; \n border-radius: 6px; \n opacity: 0.3; \n margin-left: 10px; \n flex-grow: 1; \n height: 6px; \n align-self: center; \n background-color: var(--background-color,var(--secondary-background-color));\n ";addStyles(this,L,customStyles);break;case"cover":const D=this.config.icon_open?this.config.icon_open:"mdi:window-shutter-open",O=this.config.icon_close?this.config.icon_close:"mdi:window-shutter",T=this.config.open_service?this.config.open_service:"cover.open_cover",z=this.config.close_service?this.config.close_service:"cover.close_cover",V=this.config.stop_service?this.config.stop_service:"cover.stop_cover";if(icon="open"===hass.states[this.config.entity].state?D:O,formatedState=this.config.entity?hass.formatEntityState(hass.states[this.config.entity]):"",!this.coverAdded||this.editor){if(this.editor&&this.coverContainer)for(;this.coverContainer.firstChild;)this.coverContainer.removeChild(this.coverContainer.firstChild);this.coverContainer=document.createElement("div"),this.coverContainer.setAttribute("class","cover-container"),this.coverContainer.innerHTML=`\n \n \n \n \n \n \n \n \n \n \n \n
\n `,this.content.appendChild(this.coverContainer);const Ct=this.coverContainer.querySelector(".open"),St=this.coverContainer.querySelector(".stop"),Et=this.coverContainer.querySelector(".close");Ct.addEventListener("click",(()=>{hass.callService(T.split(".")[0],T.split(".")[1],{entity_id:entityId})})),St.addEventListener("click",(()=>{hass.callService(V.split(".")[0],V.split(".")[1],{entity_id:entityId})})),Et.addEventListener("click",(()=>{hass.callService(z.split(".")[0],z.split(".")[1],{entity_id:entityId})})),this.iconContainer=this.content.querySelector(".icon-container"),addActions(this,this.iconContainer),this.coverAdded=!0}this.iconContainer&&(this.iconContainer.innerHTML=` `,this.content.querySelector(".state").textContent=formatedState);const M="\n ha-card {\n margin-top: 0 !important;\n background: none !important;\n }\n \n .header-container {\n display: flex;\n align-items: center;\n margin-bottom: 10px;\n }\n \n .cover-container {\n display: grid;\n }\n \n .icon-container {\n display: flex;\n margin: 0 !important;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n /*z-index: 1;*/\n width: 48px;\n height: 48px;\n margin: 6px;\n border-radius: 50%;\n background-color: var(--card-background-color,var(--ha-card-background));\n border: 6px solid var(--background-color-2,var(--secondary-background-color));\n box-sizing: border-box;\n }\n \n .name-container {\n font-weight: 600;\n margin-left: 10px;\n line-height: 4px;\n }\n \n .buttons-container {\n display: grid;\n align-self: center;\n grid-auto-flow: column;\n grid-gap: 18px; \n }\n \n .state {\n font-size: 12px;\n opacity: 0.7;\n }\n \n ha-icon {\n display: flex; \n height: 24px; \n width: 24px; \n color: var(--primary-text-color);\n }\n \n .button {\n display: flex;\n background: var(--background-color-2,var(--secondary-background-color));\n height: 42px;\n border-radius: 32px;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n border: none;\n }\n ";addStyles(this,M,customStyles,state,entityId);break;case"empty-column":if(!this.emptyCollumnAdded){const It=document.createElement("div");It.setAttribute("class","empty-column"),It.innerHTML='\n \n
\n ',this.content.appendChild(It),this.emptyColumnAdded=!0}}}setConfig(t){if("pop-up"===t.card_type){if(!t.hash)throw new Error("You need to define an hash")}else if("horizontal-buttons-stack"===t.card_type){var e={};for(var n in t)if(n.match(/^\d+_icon$/)){var i=n.replace("_icon","_link");if(void 0===t[i])throw new Error("You need to define "+i);if(e[t[i]])throw new Error("You can't use "+t[i]+" twice");e[t[i]]=!0}}else if(("button"===t.card_type||"cover"===t.card_type)&&!t.entity)throw new Error("You need to define an entity");this.config=t}getCardSize(){return 1}static getConfigElement(){return document.createElement("bubble-card-editor")}}console.info(`%c Bubble Card %c ${version} `,"background-color: #555;color: #fff;padding: 3px 2px 3px 3px;border-radius: 14px 0 0 14px;font-family: DejaVu Sans,Verdana,Geneva,sans-serif;text-shadow: 0 1px 0 rgba(1, 1, 1, 0.3)","background-color: #506eac;color: #fff;padding: 3px 3px 3px 2px;border-radius: 0 14px 14px 0;font-family: DejaVu Sans,Verdana,Geneva,sans-serif;text-shadow: 0 1px 0 rgba(1, 1, 1, 0.3)"),customElements.define("bubble-card",BubbleCard);const fireEvent=(t,e,n,i)=>{i=i||{},n=null==n?{}:n;const o=new Event(e,{bubbles:void 0===i.bubbles||i.bubbles,cancelable:Boolean(i.cancelable),composed:void 0===i.composed||i.composed});return o.detail=n,t.dispatchEvent(o),o};customElements.get("ha-switch");const LitElement=Object.getPrototypeOf(customElements.get("ha-panel-lovelace")),html=LitElement.prototype.html,css=LitElement.prototype.css;class BubbleCardEditor extends LitElement{setConfig(t){this._config={...t}}static get properties(){return{hass:{},_config:{}}}get _card_type(){return this._config.card_type||""}get _button_type(){return this._config.button_type||"switch"}get _entity(){return this._config.entity||""}get _name(){return this._config.name||""}get _icon(){return this._config.icon||""}get _state(){return this._config.state||""}get _text(){return this._config.text||""}get _hash(){return this._config.hash||"#pop-up-name"}get _trigger_entity(){return this._config.trigger_entity||""}get _trigger_state(){return this._config.trigger_state||""}get _margin_top_mobile(){return this._config.margin_top_mobile||"0px"}get _margin_top_desktop(){return this._config.margin_top_desktop||"0px"}get _width_desktop(){return this._config.width_desktop||"540px"}get _is_sidebar_hidden(){return this._config.is_sidebar_hidden||!1}get _icon_open(){return this._config.icon_open||""}get _icon_close(){return this._config.icon_close||""}get _open_service(){return this._config.open_service||"cover.open_cover"}get _close_service(){return this._config.open_service||"cover.close_cover"}get _stop_service(){return this._config.open_service||"cover.stop_cover"}get _auto_order(){return this._config.auto_order||!1}get _show_state(){return this._config.show_state||!1}render(){if(!this.hass)return html``;if(!this.listsUpdated){const t=t=>({label:t,value:t});this.allEntitiesList=Object.keys(this.hass.states).map(t),this.lightList=Object.keys(this.hass.states).filter((t=>"light"===t.substr(0,t.indexOf(".")))).map(t),this.sensorList=Object.keys(this.hass.states).filter((t=>"sensor"===t.substr(0,t.indexOf(".")))).map(t),this.binarySensorList=Object.keys(this.hass.states).filter((t=>"binary_sensor"===t.substr(0,t.indexOf(".")))).map(t),this.coverList=Object.keys(this.hass.states).filter((t=>"cover"===t.substr(0,t.indexOf(".")))).map(t),this.cardTypeList=[{label:"Button",value:"button"},{label:"Cover",value:"cover"},{label:"Empty column",value:"empty-column"},{label:"Horizontal buttons stack",value:"horizontal-buttons-stack"},{label:"Pop-up",value:"pop-up"},{label:"Separator",value:"separator"}],this.buttonTypeList=[{label:"Switch",value:"switch"},{label:"Slider",value:"slider"}],this.listsUpdated=!0}const t=this.allEntitiesList,e=(this.lightList,this.sensorList,this.coverList),n=this.cardTypeList,i=this.buttonTypeList;if("pop-up"===this._config.card_type)return html` ${this.makeDropdown("Card type","card_type",n)}
Pop-up This card allows you to convert any vertical-stack into a pop-up. Each pop-up can be opened by targeting its link (e.g. '#pop-up-name'), with navigation_path or with the horizontal buttons stack that is included. It must be placed within a vertical-stack card at the top most position to function properly. The pop-up will be hidden by default until you open it. ${this.makeDropdown("Optional - Icon","icon")} ${this.makeDropdown("Optional - Entity to toggle (e.g. room light group)","entity",t)} ${this.makeDropdown("Optional - Entity state to display (e.g. room temperature)","state",t)}
Pop-up trigger This allows you to apen this pop-up based on the state of any entity, for example you can open a "Security" pop-up with a camera when a person is in front of your house. You can also create a toggle helper (input_boolean) and trigger its opening/closing in an automation. ${this.makeDropdown("Optional - Entity to open the pop-up based on its state","trigger_entity",t)}
Optional - Close when the state is different
Styling options Optional - Fix when the sidebar hidden on desktop
${this.makeVersion()}
`;if("button"===this._config.card_type)return html` ${this.makeDropdown("Card type","card_type",n)}
Button This card can be a slider or a button, allowing you to toggle your entities, control the brightness of your lights and the volume of your media players. To access color / control of an entity, simply tap on the icon. ${this.makeDropdown("slider"!==this._button_type?"Entity (toggle)":"Entity (light or media_player)","entity",t)} ${this.makeDropdown("Button type","button_type",i)}
${this.makeDropdown("Optional - Icon","icon")}
Optional - Show entity state
${this.makeVersion()}
`;if("separator"===this._config.card_type)return html` ${this.makeDropdown("Card type","card_type",n)}
Separator This card is a simple separator for dividing your pop-up into categories / sections. e.g. Lights, Devices, Covers, Settings, Automations... ${this.makeDropdown("Icon","icon")} ${this.makeVersion()} `;if("horizontal-buttons-stack"===this._config.card_type){if(!this.buttonAdded&&this.shadowRoot.querySelector("#add-button")){const t=this.shadowRoot.querySelector("#add-button");for(this.buttonIndex=0;this._config[this.buttonIndex+1+"_link"];)this.buttonIndex++;t.addEventListener("click",(()=>{this.buttonIndex++;const e=t.style.opacity,n=t.innerText;t.style.opacity="0.6",t.style.transition="opacity 1s",t.innerText="Loading...",setTimeout((()=>{t.style.opacity=e,t.innerText=n}),5e3)})),this.buttonAdded=!0}return html` ${this.makeDropdown("Card type","card_type",n)}
Horizontal buttons stack This card is the companion to the pop-up card, allowing you to open the corresponding pop-ups. It also allows you to open any page of your dashboard. In addition, you can add your motion sensors so that the order of the buttons adapts according to the room you just entered. This card is scrollable, remains visible and acts as a footer. Please note that this card may take some time to load in edit mode. Optional - Auto order (Presence/occupancy sensors needed)
${this.makeButton()}
Add Button Styling options Optional - Fix when the sidebar is hidden on desktop
${this.makeVersion()}
`}return"cover"===this._config.card_type?html` ${this.makeDropdown("Card type","card_type",n)}
Cover This card allows you to control your covers. ${this.makeDropdown("Entity","entity",e)} ${this.makeDropdown("Optional - Open icon","icon_open")} ${this.makeDropdown("Optional - Closed icon","icon_close")} ${this.makeVersion()} `:"empty-column"===this._config.card_type?html` ${this.makeDropdown("Card type","card_type",n)}
Empty column Just an empty card to fill any empty column. ${this.makeVersion()} `:this._config.card_type?void 0:html` ${this.makeDropdown("Card type","card_type",n)}
Bubble Card You need to add a card type first. ${this.makeVersion()} `}makeDropdown(t,e,n){this.hass;return t.includes("icon")||t.includes("Icon")?html`
`:html`
`}makeButton(){let t=[];for(let e=1;e<=this.buttonIndex;e++)t.push(html`
`);return t}makeVersion(){return html` Bubble Card ${version} `}removeButton(t){delete this._config[t+"_name"],delete this._config[t+"_icon"],delete this._config[t+"_link"],delete this._config[t+"_entity"],delete this._config[t+"_pir_sensor"];for(let e=t;e{window.addEventListener(t,i)}));const n=new Event("urlChanged");function i(){const t=window.location.href;t!==this.currentUrl&&(window.dispatchEvent(n),this.currentUrl=t)}const o=()=>{window.dispatchEvent(n),setTimeout((()=>{window.removeEventListener("popUpInitialized",o)}),1e3)};window.addEventListener("popUpInitialized",o)}set hass(hass){function toggleEntity(t){hass.callService("homeassistant","toggle",{entity_id:t})}this.content||(this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML='\n \n \n
\n \n ',this.card=this.shadowRoot.querySelector("ha-card"),this.content=this.shadowRoot.querySelector("div")),"?edit=1"!==window.location.search?this.editor=!1:this.editor=!0;const addStyles=function(context,styles,customStyles,state,entityId,path="",element=context.content){const customStylesEval=customStyles?eval("`"+customStyles+"`"):"";let styleAddedKey=styles+"Added";if(!context[styleAddedKey]||context.previousStyle!==customStylesEval){if(!context[styleAddedKey]){if(context.styleElement=context.content.querySelector("style"),!context.styleElement){context.styleElement=document.createElement("style");const t=path?context.content.querySelector(path):element;t.appendChild(context.styleElement)}context[styleAddedKey]=!0}context.styleElement.innerHTML=customStylesEval+styles,context.previousStyle=customStylesEval}},forwardHaptic=t=>{fireEvent(window,"haptic",t)},navigate=(t,e,n=!1)=>{n?history.replaceState(null,"",e):history.pushState(null,"",e),fireEvent(window,"location-changed",{replace:n})},handleActionConfig=(t,e,n,i)=>{if(!i.confirmation||i.confirmation.exemptions&&i.confirmation.exemptions.some((t=>t.user===e.user.id))||(forwardHaptic("warning"),confirm(i.confirmation.text||`Are you sure you want to ${i.action}?`)))switch(i.action){case"more-info":(this.config.entity||this.config.camera_image)&&fireEvent(t,"hass-more-info",{entityId:this.config.entity?this.config.entity:this.config.camera_image});break;case"navigate":i.navigation_path&&navigate(t,i.navigation_path);break;case"url":i.url_path&&window.open(i.url_path);break;case"toggle":this.config.entity&&(toggleEntity(this.config.entity),forwardHaptic("success"));break;case"call-service":{if(!i.service)return void forwardHaptic("failure");const[t,n]=i.service.split(".",2);e.callService(t,n,i.service_data,i.target),forwardHaptic("success");break}case"fire-dom-event":fireEvent(t,"ll-custom",i)}},handleAction=(t,e,n,i)=>{let o;"double_tap"===i&&this.config.double_tap_action?o=this.config.double_tap_action:"hold"===i&&this.config.hold_action?o=this.config.hold_action:"tap"===i&&this.config.tap_action?o=this.config.tap_action:"double_tap"!==i||this.config.double_tap_action?("hold"!==i||this.config.hold_action)&&("tap"!==i||this.config.tap_action)||(o={action:"more-info"}):o={action:"toggle"},handleActionConfig(t,e,n,o)},addAction=function(){let t,e;return function(n,i,o,a){o.addEventListener(n,(()=>{const i=(new Date).getTime();"click"===n?i-(e||0)<250?(clearTimeout(t),handleAction(a,hass,{},"double_tap")):t=setTimeout((()=>{handleAction(a,hass,{},"tap")}),250):handleAction(a,hass,{},"hold"),e=i}))}}();function addActions(t,e){addAction("click","tap",e,t),addAction("contextmenu","hold",e,t)}const customStyles=this.config.styles?this.config.styles:"";let entityId=this.config.entity?this.config.entity:"",icon=!this.config.icon&&this.config.entity?hass.states[entityId].attributes.icon||hass.states[entityId].attributes.entity_picture||"":this.config.icon||"",name=this.config.name?this.config.name:this.config.entity?hass.states[entityId].attributes.friendly_name:"",widthDesktop=this.config.width_desktop||"540px",widthDesktopDivided=widthDesktop?widthDesktop.match(/(\d+)(\D+)/):"",isSidebarHidden=this.config.is_sidebar_hidden||!1,state=this.config.state?hass.states[this.config.state].state:"",formatedState;switch(this.config.card_type){case"pop-up":if(this.getRootNode().host){if(!this.popUp){this.card.style.marginTop="0",this.popUp=this.getRootNode().querySelector("#root");const J=new Event("popUpInitialized");window.dispatchEvent(J)}const H=this.config.hash,Y=this.popUp,B=this.config.text||"",q=this.config.trigger_entity?this.config.trigger_entity:"",F=this.config.trigger_state?this.config.trigger_state:"",X=!!this.config.trigger_close&&this.config.trigger_close;formatedState=this.config.state?hass.formatEntityState(hass.states[this.config.state])+" "+B:B;const j=this.config.margin_top_mobile&&"0"!==this.config.margin_top_mobile?this.config.margin_top_mobile:"0px",W=this.config.margin_top_desktop&&"0"!==this.config.margin_top_desktop?this.config.margin_top_desktop:"0px",R=this.config.entity?"flex":"none";if(this.headerAdded){if(this.headerAdded){const Z=this.content.querySelector("#header-container .header-icon");if(Z.innerHTML="",hass&&hass.states&&hass.states[entityId]&&hass.states[entityId].attributes.entity_picture&&!this.config.icon){const nt=document.createElement("img");nt.setAttribute("src",hass.states[entityId].attributes.entity_picture),nt.setAttribute("class","entity-picture"),nt.setAttribute("alt","Icon"),Z.appendChild(nt)}else{const it=document.createElement("ha-icon");it.setAttribute("icon",icon),it.setAttribute("class","icon"),Z.appendChild(it)}const Q=this.content.querySelector("#header-container h2");Q.textContent=name;const tt=this.content.querySelector("#header-container p");tt.textContent=formatedState;const et=this.content.querySelector("#header-container .power-button");et.setAttribute("style",`display: ${R};`)}}else{const ot=document.createElement("div");ot.setAttribute("id","header-container");const at=document.createElement("div");ot.appendChild(at);const st=document.createElement("div");if(st.setAttribute("class","header-icon"),at.appendChild(st),hass&&hass.states&&hass.states[entityId]&&hass.states[entityId].attributes.entity_picture&&!this.config.icon){const pt=document.createElement("img");pt.setAttribute("src",hass.states[entityId].attributes.entity_picture),pt.setAttribute("class","entity-picture"),pt.setAttribute("alt","Icon"),st.appendChild(pt)}else{const ut=document.createElement("ha-icon");ut.setAttribute("icon",icon),ut.setAttribute("class","icon"),st.appendChild(ut)}addActions(this,st);const rt=document.createElement("h2");rt.textContent=name,at.appendChild(rt);const ct=document.createElement("p");ct.textContent=formatedState,at.appendChild(ct);const dt=document.createElement("ha-icon");dt.setAttribute("class","power-button"),dt.setAttribute("icon","mdi:power"),dt.setAttribute("style",`display: ${R};`),at.appendChild(dt);const lt=document.createElement("button");lt.setAttribute("class","close-pop-up"),lt.onclick=function(){history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0)},ot.appendChild(lt);const ht=document.createElement("ha-icon");ht.setAttribute("icon","mdi:close"),lt.appendChild(ht),this.content.appendChild(ot),this.header=at,this.headerAdded=!0}if(!this.eventAdded){let gt,mt;window["checkHashRef_"+H]=U,window.addEventListener("urlChanged",window["checkHashRef_"+H]),this.content.querySelector(".power-button").addEventListener("click",(()=>{toggleEntity(entityId)})),window.addEventListener("mousedown",(function(t){location.hash!==H||t.composedPath().some((t=>"HA-MORE-INFO-DIALOG"===t.nodeName))||t.composedPath().some((t=>"root"===t.id&&!t.classList.contains("close-pop-up")))||(history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0))})),window.addEventListener("keydown",(function(t){"Escape"===t.key&&(history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0))})),Y.addEventListener("touchstart",(function(t){gt=t.touches[0].clientY,mt=gt})),Y.addEventListener("touchmove",(function(t){t.touches[0].clientY-gt>300&&t.touches[0].clientY>mt&&(history.replaceState(null,null,location.href.split("#")[0]),localStorage.setItem("isManuallyClosed_"+H,!0)),mt=t.touches[0].clientY})),this.eventAdded=!0}if(q){let ft=localStorage.getItem("previousTriggerState_"+H),bt="true"===localStorage.getItem("isManuallyClosed_"+H),yt="true"===localStorage.getItem("isTriggered_"+H);(hass.states[q].state===F&&null===ft||!yt)&&(navigate("",H),yt=!0,localStorage.setItem("isTriggered_"+H,yt)),hass.states[q].state!==ft&&(bt=!1,localStorage.setItem("previousTriggerState_"+H,hass.states[q].state),localStorage.setItem("isManuallyClosed_"+H,bt)),hass.states[q].state!==F||bt?X&&Y.classList.contains("open-pop-up")&&yt&&!bt&&(history.replaceState(null,null,location.href.split("#")[0]),yt=!1,bt=!0,localStorage.setItem("isManuallyClosed_"+H,bt),localStorage.setItem("isTriggered_"+H,yt)):(navigate("",H),yt=!0,localStorage.setItem("isTriggered_"+H,yt))}if(""!==entityId){const vt=hass.states[entityId].attributes.rgb_color,_t=vt?`rgba(${vt[0]}, ${vt[1]}, ${vt[2]}, 0.5)`:"off"!==hass.states[entityId].state?"var(--accent-color)":"var(--background-color,var(--secondary-background-color))";this.header.style.backgroundColor=_t}function U(){if(!this.editor){location.hash.split("?")[0]===H?N():Y.classList.contains("open-pop-up")&&P()}}function N(){Y.classList.remove("close-pop-up"),Y.classList.add("open-pop-up")}function P(){Y.classList.remove("open-pop-up"),Y.classList.add("close-pop-up")}const K=`\n ha-card {\n margin-top: 0 !important;\n background: none !important;\n border: none !important;\n }\n .card-content {\n width: 100% !important;\n padding: 0 !important;\n }\n #root {\n position: fixed !important;\n margin: 0 -7px;\n width: 100%;\n background-color: var(--ha-card-background,var(--card-background-color));\n border-radius: 42px;\n box-sizing: border-box;\n top: calc(100% + ${j} + var(--header-height));\n grid-gap: 12px !important;\n gap: 12px !important;\n grid-auto-rows: min-content;\n padding: 18px 18px 220px 18px !important;\n height: 100% !important;\n -ms-overflow-style: none; /* for Internet Explorer, Edge */\n scrollbar-width: none; /* for Firefox */\n overflow-y: auto; \n overflow-x: hidden; \n z-index: 1 !important; /* Higher value hide the more-info panel */\n /* For older Safari but not working with Firefox */\n /* display: grid !important; */ \n }\n #root > bubble-card:first-child::after {\n content: '';\n display: block;\n position: sticky;\n top: 0;\n left: -50px;\n margin: -70px 0 -35px 0;\n width: 200%;\n height: 100px;\n background: linear-gradient(0deg, rgba(79, 69, 87, 0) 0%, var(--ha-card-background,var(--card-background-color)) 80%);\n z-index: 0;\n }\n #root::-webkit-scrollbar {\n display: none; /* for Chrome, Safari, and Opera */\n }\n #root > bubble-card:first-child {\n position: sticky;\n top: 0;\n z-index: 1;\n background: none !important;\n }\n #root.open-pop-up {\n transform: translateY(-100%);\n transition: transform .4s !important;\n }\n #root.open-pop-up > * {\n /* Block child items to overflow and if they do clip them */\n /*max-width: calc(100vw - 38px);*/\n max-width: 100% !important;\n overflow-x: clip;\n }\n #root.close-pop-up { \n transform: translateY(0%);\n transition: transform .4s !important;\n /* animation: hide 1s forwards; */\n }\n @media only screen and (min-width: 768px) {\n #root {\n top: calc(100% + ${W} + var(--header-height));\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]});\n margin: 0 !important;\n }\n } \n @media only screen and (min-width: 870px) {\n #root {\n top: calc(100% + ${W} + var(--header-height));\n width: calc(${widthDesktop}${"%"===widthDesktopDivided[2]?" - var(--mdc-drawer-width)":""}) !important;\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]} + ${!0===isSidebarHidden?"0px":"var(--mdc-drawer-width) "+("%"===widthDesktopDivided[2]?"":"/ 2")});\n margin: 0 !important;\n }\n } \n #root.editor {\n position: inherit !important;\n width: 100% !important;\n padding: 18px !important;\n }\n `,G=`\n #header-container {\n display: inline-flex;\n ${icon||name||entityId||state||B?"":"flex-direction: row-reverse;"}\n width: 100%;\n margin: 0;\n padding: 0;\n }\n #header-container > div {\n display: ${icon||name||entityId||state||B?"inline-flex":"none"};\n align-items: center;\n position: relative;\n padding: 6px;\n z-index: 1;\n flex-grow: 1;\n background-color: var(--background-color,var(--secondary-background-color));\n transition: background 1s;\n border-radius: 25px;\n margin-right: 14px;\n }\n .header-icon {\n display: inline-flex;\n width: 22px;\n height: 22px;\n padding: 8px;\n background-color: var(--card-background-color,var(--ha-card-background));\n border-radius: 100%;\n margin: 0 10px 0 0;\n cursor: ${this.config.entity||this.config.double_tap_action||this.config.tap_action||this.config.hold_action?"pointer":"default"}; \n flex-wrap: wrap;\n align-content: center;\n justify-content: center;\n overflow: hidden;\n }\n .entity-picture {\n height: calc(100% + 16px);\n width: calc(100% + 16px);\n }\n #header-container h2 {\n display: inline-flex;\n margin: 0 18px 0 0;\n /*line-height: 0px;*/\n z-index: 1;\n font-size: 20px;\n }\n #header-container p {\n display: inline-flex;\n line-height: 0px;\n font-size: 16px;\n }\n .power-button {\n cursor: pointer; \n flex-grow: inherit; \n width: 24px;\n height: 24px;\n border-radius: 12px;\n margin: 0 10px;\n background: none !important;\n justify-content: flex-end;\n background-color: var(--background-color,var(--secondary-background-color));\n }\n .close-pop-up {\n height: 50px;\n width: 50px;\n border: none;\n border-radius: 50%;\n z-index: 1;\n background: var(--background-color,var(--secondary-background-color));\n color: var(--primary-text-color);\n flex-shrink: 0;\n cursor: pointer;\n }\n `;addStyles(this,K,customStyles,state,entityId,"",Y),addStyles(this,G,customStyles,state,entityId),!0===this.editor?(Y.classList.add("editor"),Y.classList.remove("open-pop-up"),Y.classList.remove("close-pop-up")):Y.classList.remove("editor")}else!0!==this.editor&&(this.card.style.marginTop="2000px");break;case"horizontal-buttons-stack":const t=(t,e,n)=>{const i=document.createElement("button");return i.onclick=function(){navigate("",e)},i.setAttribute("class","button"),i.innerHTML=`\n ${""!==n?` `:""}\n ${""!==t?`${t}
`:""}\n `,i},e=(t,e)=>{if(hass.states[e].attributes.rgb_color){const n=hass.states[e].attributes.rgb_color,i=`rgba(${n[0]}, ${n[1]}, ${n[2]}, 0.5)`;t.style.backgroundColor=i,t.style.border="1px solid rgba(0,0,0,0)"}else hass.states[e].attributes.rgb_color||"on"!=hass.states[e].state?(t.style.backgroundColor="rgba(0,0,0,0)",t.style.border="1px solid var(--primary-text-color)"):(t.style.backgroundColor="rgba(255,255,255,0.5)",t.style.border="1px solid rgba(0,0,0,0)")};if(!this.buttonsAdded){const xt=document.createElement("div");xt.setAttribute("class","horizontal-buttons-stack-container"),this.content.appendChild(xt),this.buttonsContainer=xt}const n=()=>{let n=[],i=1;for(;this.config[i+"_link"];){const t=i+"_",e=this.config[t+"name"]||"",o=this.config[t+"pir_sensor"];icon=this.config[t+"icon"]||"";const a=this.config[t+"link"],s=this.config[t+"entity"];n.push({button:e,pirSensor:o,icon:icon,link:a,lightEntity:s}),i++}if(this.config.auto_order&&n.sort(((t,e)=>{if(t.pirSensor&&e.pirSensor){if("on"===hass.states[t.pirSensor].state&&"on"===hass.states[e.pirSensor].state){return hass.states[t.pirSensor].last_updated{const i=t(n.button,n.link,n.icon);e[n.link]=i,this.buttonsContainer.appendChild(i)})),this.buttonsAdded=!0,this.buttons=e}this.editor?localStorage.setItem("justExitedEditor",!1):"false"===localStorage.getItem("justExitedEditor")&&localStorage.setItem("justExitedEditor",!0);let o=0,a=12;const s="true"===localStorage.getItem("editorMode")&&!this.editor;n.forEach(((t,n)=>{let i=this.buttons[t.link];if(i){let e=localStorage.getItem(`buttonWidth-${t.link}`),n=localStorage.getItem(`buttonContent-${t.link}`);(!e||"0"===e||n!==i.innerHTML||this.editor||s)&&(e=i.offsetWidth,localStorage.setItem(`buttonWidth-${t.link}`,e),localStorage.setItem(`buttonContent-${t.link}`,i.innerHTML),this.editor?a=36:s&&(a=12)),i.style.transform=`translateX(${o}px)`,o+=parseInt(e)+a}t.lightEntity&&e(i,t.lightEntity)}))};n();const i=`\n ha-card {\n border-radius: 0;\n }\n .horizontal-buttons-stack {\n width: 100%;\n margin-top: 0 !important;\n background: none !important;\n position: fixed;\n height: 51px;\n bottom: 16px;\n left: 7px;\n /* transform: translateY(200px); */\n /* animation: from-bottom 1.3s forwards; */\n z-index: 1 !important; /* Higher value hide the more-info panel */\n }\n @keyframes from-bottom {\n 0% {transform: translateY(200px);}\n 20% {transform: translateY(200px);}\n 46% {transform: translateY(-8px);}\n 56% {transform: translateY(1px);}\n 62% {transform: translateY(-2px);}\n 70% {transform: translateY(0);}\n 100% {transform: translateY(0);}\n }\n .horizontal-buttons-stack-container {\n width: max-content;\n position: relative;\n height: 51px;\n }\n .button {\n display: flex;\n position: absolute;\n /* box-sizing: border-box; */\n border: 1px solid var(--primary-text-color);\n align-items: center;\n height: 50px;\n white-space: nowrap;\n width: auto;\n border-radius: 25px;\n z-index: 1;\n padding: 16px;\n background: none;\n transition: background-color 1s, border 1s, transform 1s;\n color: var(--primary-text-color);\n }\n .icon {\n height: 24px;\n }\n .card-content {\n width: calc(100% + 18px);\n box-sizing: border-box;\n margin: 0 -36px !important;\n padding: 0 36px !important;\n overflow: scroll !important;\n -ms-overflow-style: none;\n scrollbar-width: none;\n -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 1) calc(0% + 28px), rgba(0, 0, 0, 1) calc(100% - 28px), transparent 100%);\n /* mask-image: linear-gradient(90deg, transparent 2%, rgba(0, 0, 0, 1) 6%, rgba(0, 0, 0, 1) 96%, transparent 100%); */\n /* -webkit-mask-image: linear-gradient(90deg, transparent 2%, rgba(0, 0, 0, 1) 6%, rgba(0, 0, 0, 1) 96%, transparent 100%); */\n }\n .horizontal-buttons-stack::before {\n content: '';\n position: absolute;\n top: -32px;\n left: -100%;\n display: block;\n background: linear-gradient(0deg, var(--background-color, var(--primary-background-color)) 50%, rgba(79, 69, 87, 0));\n width: 200%;\n height: 100px;\n }\n .card-content::-webkit-scrollbar {\n display: none;\n }\n @media only screen and (min-width: 768px) {\n .card-content {\n position: fixed;\n width: ${widthDesktop} !important;\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]});\n margin-left: -13px !important;\n padding: 0 26px !important;\n }\n }\n @media only screen and (min-width: 870px) {\n .card-content {\n position: fixed;\n width: calc(${widthDesktop}${"%"===widthDesktopDivided[2]?" - var(--mdc-drawer-width)":""}) !important;\n left: calc(50% - ${widthDesktopDivided[1]/2}${widthDesktopDivided[2]} + ${!0===isSidebarHidden?"0px":"var(--mdc-drawer-width) "+("%"===widthDesktopDivided[2]?"":"/ 2")});\n margin-left: -13px !important;\n padding: 0 26px !important;\n }\n }\n \n .horizontal-buttons-stack.editor {\n position: relative;\n bottom: 0;\n left: 0;\n overflow: hidden;\n }\n \n .horizontal-buttons-stack.editor::before {\n top: -32px;\n left: -100%;\n background: none;\n width: 100%;\n height: 0;\n }\n \n .horizontal-buttons-stack-container.editor > .button {\n transition: background-color 0s, border 0s, transform 0s;\n }\n \n .horizontal-buttons-stack-container.editor {\n margin-left: 1px;\n }\n \n .horizontal-buttons-stack.editor > .card-content {\n position: relative;\n width: calc(100% + 26px) !important;\n left: -26px;\n margin: 0 !important;\n padding: 0;\n }\n `;addStyles(this,i,customStyles),this.editor?(this.buttonsContainer.classList.add("editor"),this.card.classList.add("editor")):(this.buttonsContainer.classList.remove("editor"),this.card.classList.remove("editor"));break;case"button":if(!this.buttonAdded){const wt=document.createElement("div");wt.setAttribute("class","button-container"),this.content.appendChild(wt)}const o=this.config.button_type||"switch";formatedState=hass.formatEntityState(hass.states[entityId]);const a=!!this.config.show_state&&this.config.show_state;let s=entityId?hass.states[entityId].attributes.brightness||0:"",r=entityId?hass.states[entityId].attributes.volume_level||0:"",c=!1,d=s,l=r,h=0,p=0,u=0,g=!1,m=null;const f=document.createElement("div");f.setAttribute("class","icon-container"),this.iconContainer=f;const b=document.createElement("div");b.setAttribute("class","name-container");const y=document.createElement("div");y.setAttribute("class","switch-button");const v=document.createElement("div");v.setAttribute("class","range-slider");const _=document.createElement("div");if(_.setAttribute("class","range-fill"),entityId&&entityId.startsWith("light.")&&"slider"===o?_.style.transform=`translateX(${s/255*100}%)`:entityId&&entityId.startsWith("media_player.")&&"slider"===o&&(_.style.transform=`translateX(${100*r}%)`),!this.buttonContainer||this.editor){if(this.editor&&this.buttonContainer){for(;this.buttonContainer.firstChild;)this.buttonContainer.removeChild(this.buttonContainer.firstChild);this.eventAdded=!1}this.buttonContainer=this.content.querySelector(".button-container"),"slider"!==o||this.buttonAdded&&!this.editor?("switch"===o||"custom"===o||this.editor)&&(this.buttonContainer.appendChild(y),y.appendChild(f),y.appendChild(b),this.switchButton=this.content.querySelector(".switch-button")):(this.buttonContainer.appendChild(v),v.appendChild(f),v.appendChild(b),v.appendChild(_),this.rangeFill=this.content.querySelector(".range-fill")),!hass.states[entityId].attributes.entity_picture&&!icon.startsWith("/api/image/")||this.config.icon?f.innerHTML=` `:f.innerHTML=` `,b.innerHTML=`\n ${name}
\n ${a?`${formatedState}
`:""}\n `,this.buttonAdded=!0}function x(t){let e=t.querySelector(".feedback-element");e||(e=document.createElement("div"),e.setAttribute("class","feedback-element"),t.appendChild(e)),e.style.animation="tap-feedback .5s",setTimeout((()=>{e.style.animation="none",t.removeChild(e)}),500)}function w(t){h=t.pageX||(t.touches?t.touches[0].pageX:0),p=t.pageY||(t.touches?t.touches[0].pageY:0),u=v.value,t.target!==f.querySelector("ha-icon")&&(c=!0,document.addEventListener("mouseup",$),document.addEventListener("touchend",$),document.addEventListener("mousemove",k),document.addEventListener("touchmove",k),m=setTimeout((()=>{I(t.pageX||t.touches[0].pageX),C(),m=null}),200))}function k(t){const e=t.pageX||(t.touches?t.touches[0].pageX:0),n=t.pageY||(t.touches?t.touches[0].pageY:0);Math.abs(n-p)>Math.abs(e-h)?(clearTimeout(m),$()):(document.removeEventListener("mousemove",k),document.removeEventListener("touchmove",k),document.addEventListener("mousemove",S),document.addEventListener("touchmove",S))}function $(){c=!1,g=!1,C(),document.removeEventListener("mouseup",$),document.removeEventListener("touchend",$),document.removeEventListener("mousemove",S),document.removeEventListener("touchmove",S)}function C(){entityId.startsWith("light.")?(s=d,hass.callService("light","turn_on",{entity_id:entityId,brightness:s})):r!==l&&entityId.startsWith("media_player.")&&(r=l,hass.callService("media_player","volume_set",{entity_id:entityId,volume_level:r}))}function S(t){const e=t.pageX||(t.touches?t.touches[0].pageX:0),n=t.pageY||(t.touches?t.touches[0].pageY:0);c&&Math.abs(e-h)>10?I(e):c&&Math.abs(n-p)>10&&(c=!1,v.value=u)}function E(t,e){if(e.buttonContainer.style.opacity="unavailable"!==t?"1":"0.5",["switch","custom"].includes(o)){const n=["on","open","cleaning","true","home","playing"].includes(t)?"var(--accent-color)":"rgba(0,0,0,0)";e.switchButton.style.backgroundColor=n}}function I(t){const e=v.getBoundingClientRect(),n=Math.min(Math.max(t-e.left,0),e.width)/e.width;entityId.startsWith("light.")?d=Math.round(255*n):entityId.startsWith("media_player.")&&(l=n),_.style.transition="none",_.style.transform=`translateX(${100*n}%)`}if(a&&(this.content.querySelector(".state").textContent=formatedState),this.eventAdded||"switch"!==o?this.eventAdded||"slider"!==o?this.eventAdded||"custom"!==o||(y.addEventListener("click",(()=>x(this.switchButton))),addActions(this,this.switchButton),this.eventAdded=!0):(v.addEventListener("mousedown",w),v.addEventListener("touchstart",w),addActions(this,this.iconContainer),this.eventAdded=!0):(y.addEventListener("click",(()=>x(this.switchButton))),y.addEventListener("click",(function(t){t.target.closest("ha-icon")||toggleEntity(entityId)})),addActions(this,this.iconContainer),this.eventAdded=!0),this.isDragging||"slider"!==o||(this.rangeFill.style.transition="all .2s",entityId.startsWith("light.")?this.rangeFill.style.transform=`translateX(${s/255*100}%)`:entityId.startsWith("media_player.")&&(this.rangeFill.style.transform=`translateX(${100*r}%)`)),E(state,this),"slider"===o)if(entityId.startsWith("light.")){const kt=hass.states[entityId].attributes.rgb_color,$t=kt?`rgba(${kt[0]}, ${kt[1]}, ${kt[2]}, 0.5)`:"rgba(255, 255, 255, 0.5)";this.rangeFill.style.backgroundColor=$t}else this.rangeFill.style.backgroundColor="var(--accent-color)";const A=`\n ha-card {\n margin-top: 0 !important;\n background: none !important;\n }\n \n .button-container {\n position: relative;\n width: 100%;\n height: 50px;\n z-index: 0;\n background-color: var(--background-color-2,var(--secondary-background-color));\n border-radius: 25px;\n mask-image: radial-gradient(white, black);\n -webkit-mask-image: radial-gradient(white, black);\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n -webkit-transform: translateZ(0);\n overflow: hidden;\n }\n \n .switch-button,\n .range-slider {\n display: inline-flex;\n position: absolute;\n height: 100%;\n width: 100%;\n transition: background-color 1.5s;\n }\n \n .range-fill {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n }\n \n .switch-button {\n cursor: pointer !important;\n }\n \n .range-slider {\n cursor: ew-resize;\n }\n \n .range-fill {\n z-index: 0;\n width: 100%;\n left: -100%;\n }\n \n .icon-container {\n position: absolute;\n z-index: 1;\n width: 38px;\n height: 38px;\n margin: 6px;\n border-radius: 50%;\n background-color: var(--card-background-color,var(--ha-card-background));\n cursor: pointer !important;\n }\n \n ha-icon {\n display: flex;\n position: absolute;\n margin: inherit;\n padding: 1px 2px;\n width: 22px; \n height: 22px;\n }\n \n .entity-picture {\n height: inherit;\n border-radius: 100%;\n }\n \n .name-container {\n position: relative;\n display: ${a?"block":"inline-flex"};\n margin-left: 58px;\n z-index: 1;\n font-weight: 600;\n align-items: center;\n line-height: ${a?"4px":"16px"};\n }\n \n .state {\n font-size: 12px;\n opacity: 0.7;\n }\n \n .feedback-element {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n width: 100%;\n height: 100%;\n background-color: rgb(0,0,0);\n }\n \n @keyframes tap-feedback {\n 0% {transform: translateX(-100%); opacity: 0;}\n 64% {transform: translateX(0); opacity: 0.1;}\n 100% {transform: translateX(100%); opacity: 0;}\n }\n `;addStyles(this,A,customStyles,state,entityId);break;case"separator":if(!this.separatorAdded||this.editor){if(this.editor&&this.separatorContainer)for(;this.separatorContainer.firstChild;)this.separatorContainer.removeChild(this.separatorContainer.firstChild);this.separatorAdded||(this.separatorContainer=document.createElement("div"),this.separatorContainer.setAttribute("class","separator-container")),this.separatorContainer.innerHTML=`\n \n \n
${name} \n \n
\n `,this.content.appendChild(this.separatorContainer),this.separatorAdded=!0}const L="\n .separator-container {\n display: inline-flex;\n width: 100%;\n }\n .separator-container div:first-child {\n display: inline-flex;\n max-width: calc(100% - 38px);\n }\n .separator-container div ha-icon{\n display: inline-flex;\n height: 24px;\n width: 24px;\n margin: 0 20px 0 8px;\n transform: translateY(-2px);\n }\n .separator-container div h4{\n display: inline-flex;\n margin: 0 20px 0 0;\n font-size: 17px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .separator-container div:last-child{\n display: inline-flex; \n border-radius: 6px; \n opacity: 0.3; \n margin-left: 10px; \n flex-grow: 1; \n height: 6px; \n align-self: center; \n background-color: var(--background-color,var(--secondary-background-color));\n ";addStyles(this,L,customStyles);break;case"cover":const D=this.config.icon_open?this.config.icon_open:"mdi:window-shutter-open",O=this.config.icon_close?this.config.icon_close:"mdi:window-shutter",T=this.config.open_service?this.config.open_service:"cover.open_cover",z=this.config.close_service?this.config.close_service:"cover.close_cover",V=this.config.stop_service?this.config.stop_service:"cover.stop_cover";if(icon="open"===hass.states[this.config.entity].state?D:O,formatedState=this.config.entity?hass.formatEntityState(hass.states[this.config.entity]):"",!this.coverAdded||this.editor){if(this.editor&&this.coverContainer)for(;this.coverContainer.firstChild;)this.coverContainer.removeChild(this.coverContainer.firstChild);this.coverContainer=document.createElement("div"),this.coverContainer.setAttribute("class","cover-container"),this.coverContainer.innerHTML=`\n \n \n \n \n \n \n \n \n \n \n \n
\n `,this.content.appendChild(this.coverContainer);const Ct=this.coverContainer.querySelector(".open"),St=this.coverContainer.querySelector(".stop"),Et=this.coverContainer.querySelector(".close");Ct.addEventListener("click",(()=>{hass.callService(T.split(".")[0],T.split(".")[1],{entity_id:entityId})})),St.addEventListener("click",(()=>{hass.callService(V.split(".")[0],V.split(".")[1],{entity_id:entityId})})),Et.addEventListener("click",(()=>{hass.callService(z.split(".")[0],z.split(".")[1],{entity_id:entityId})})),this.iconContainer=this.content.querySelector(".icon-container"),addActions(this,this.iconContainer),this.coverAdded=!0}this.iconContainer&&(this.iconContainer.innerHTML=` `,this.content.querySelector(".state").textContent=formatedState);const M="\n ha-card {\n margin-top: 0 !important;\n background: none !important;\n }\n \n .header-container {\n display: flex;\n align-items: center;\n margin-bottom: 10px;\n }\n \n .cover-container {\n display: grid;\n }\n \n .icon-container {\n display: flex;\n margin: 0 !important;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n /*z-index: 1;*/\n width: 48px;\n height: 48px;\n margin: 6px;\n border-radius: 50%;\n background-color: var(--card-background-color,var(--ha-card-background));\n border: 6px solid var(--background-color-2,var(--secondary-background-color));\n box-sizing: border-box;\n }\n \n .name-container {\n font-weight: 600;\n margin-left: 10px;\n line-height: 4px;\n }\n \n .buttons-container {\n display: grid;\n align-self: center;\n grid-auto-flow: column;\n grid-gap: 18px; \n }\n \n .state {\n font-size: 12px;\n opacity: 0.7;\n }\n \n ha-icon {\n display: flex; \n height: 24px; \n width: 24px; \n color: var(--primary-text-color);\n }\n \n .button {\n display: flex;\n background: var(--background-color-2,var(--secondary-background-color));\n height: 42px;\n border-radius: 32px;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n border: none;\n }\n ";addStyles(this,M,customStyles,state,entityId);break;case"empty-column":if(!this.emptyCollumnAdded){const It=document.createElement("div");It.setAttribute("class","empty-column"),It.innerHTML='\n \n
\n ',this.content.appendChild(It),this.emptyColumnAdded=!0}}}setConfig(t){if("pop-up"===t.card_type){if(!t.hash)throw new Error("You need to define an hash")}else if("horizontal-buttons-stack"===t.card_type){var e={};for(var n in t)if(n.match(/^\d+_icon$/)){var i=n.replace("_icon","_link");if(void 0===t[i])throw new Error("You need to define "+i);if(e[t[i]])throw new Error("You can't use "+t[i]+" twice");e[t[i]]=!0}}else if(("button"===t.card_type||"cover"===t.card_type)&&!t.entity)throw new Error("You need to define an entity");this.config=t}getCardSize(){return 1}static getConfigElement(){return document.createElement("bubble-card-editor")}}console.info(`%c Bubble Card %c ${version} `,"background-color: #555;color: #fff;padding: 3px 2px 3px 3px;border-radius: 14px 0 0 14px;font-family: DejaVu Sans,Verdana,Geneva,sans-serif;text-shadow: 0 1px 0 rgba(1, 1, 1, 0.3)","background-color: #506eac;color: #fff;padding: 3px 3px 3px 2px;border-radius: 0 14px 14px 0;font-family: DejaVu Sans,Verdana,Geneva,sans-serif;text-shadow: 0 1px 0 rgba(1, 1, 1, 0.3)"),customElements.define("bubble-card",BubbleCard);const fireEvent=(t,e,n,i)=>{i=i||{},n=null==n?{}:n;const o=new Event(e,{bubbles:void 0===i.bubbles||i.bubbles,cancelable:Boolean(i.cancelable),composed:void 0===i.composed||i.composed});return o.detail=n,t.dispatchEvent(o),o};customElements.get("ha-switch");const LitElement=Object.getPrototypeOf(customElements.get("ha-panel-lovelace")),html=LitElement.prototype.html,css=LitElement.prototype.css;class BubbleCardEditor extends LitElement{setConfig(t){this._config={...t}}static get properties(){return{hass:{},_config:{}}}get _card_type(){return this._config.card_type||""}get _button_type(){return this._config.button_type||"switch"}get _entity(){return this._config.entity||""}get _name(){return this._config.name||""}get _icon(){return this._config.icon||""}get _state(){return this._config.state||""}get _text(){return this._config.text||""}get _hash(){return this._config.hash||"#pop-up-name"}get _trigger_entity(){return this._config.trigger_entity||""}get _trigger_state(){return this._config.trigger_state||""}get _margin_top_mobile(){return this._config.margin_top_mobile||"0px"}get _margin_top_desktop(){return this._config.margin_top_desktop||"0px"}get _width_desktop(){return this._config.width_desktop||"540px"}get _is_sidebar_hidden(){return this._config.is_sidebar_hidden||!1}get _icon_open(){return this._config.icon_open||""}get _icon_close(){return this._config.icon_close||""}get _open_service(){return this._config.open_service||"cover.open_cover"}get _close_service(){return this._config.open_service||"cover.close_cover"}get _stop_service(){return this._config.open_service||"cover.stop_cover"}get _auto_order(){return this._config.auto_order||!1}get _show_state(){return this._config.show_state||!1}render(){if(!this.hass)return html``;if(!this.listsUpdated){const t=t=>({label:t,value:t});this.allEntitiesList=Object.keys(this.hass.states).map(t),this.lightList=Object.keys(this.hass.states).filter((t=>"light"===t.substr(0,t.indexOf(".")))).map(t),this.sensorList=Object.keys(this.hass.states).filter((t=>"sensor"===t.substr(0,t.indexOf(".")))).map(t),this.binarySensorList=Object.keys(this.hass.states).filter((t=>"binary_sensor"===t.substr(0,t.indexOf(".")))).map(t),this.coverList=Object.keys(this.hass.states).filter((t=>"cover"===t.substr(0,t.indexOf(".")))).map(t),this.cardTypeList=[{label:"Button",value:"button"},{label:"Cover",value:"cover"},{label:"Empty column",value:"empty-column"},{label:"Horizontal buttons stack",value:"horizontal-buttons-stack"},{label:"Pop-up",value:"pop-up"},{label:"Separator",value:"separator"}],this.buttonTypeList=[{label:"Switch",value:"switch"},{label:"Slider",value:"slider"}],this.listsUpdated=!0}const t=this.allEntitiesList,e=(this.lightList,this.sensorList,this.coverList),n=this.cardTypeList,i=this.buttonTypeList;if("pop-up"===this._config.card_type)return html` ${this.makeDropdown("Card type","card_type",n)}
Pop-up This card allows you to convert any vertical-stack into a pop-up. Each pop-up can be opened by targeting its link (e.g. '#pop-up-name'), with navigation_path or with the horizontal buttons stack that is included. It must be placed within a vertical-stack card at the top most position to function properly. The pop-up will be hidden by default until you open it. ${this.makeDropdown("Optional - Icon","icon")} ${this.makeDropdown("Optional - Entity to toggle (e.g. room light group)","entity",t)} ${this.makeDropdown("Optional - Entity state to display (e.g. room temperature)","state",t)}
Pop-up trigger This allows you to open this pop-up based on the state of any entity, for example you can open a "Security" pop-up with a camera when a person is in front of your house. You can also create a toggle helper (input_boolean) and trigger its opening/closing in an automation. ${this.makeDropdown("Optional - Entity to open the pop-up based on its state","trigger_entity",t)}
Optional - Close when the state is different
Styling options Optional - Fix when the sidebar hidden on desktop
${this.makeVersion()}
`;if("button"===this._config.card_type)return html` ${this.makeDropdown("Card type","card_type",n)}
Button This card can be a slider or a button, allowing you to toggle your entities, control the brightness of your lights and the volume of your media players. To access color / control of an entity, simply tap on the icon. ${this.makeDropdown("slider"!==this._button_type?"Entity (toggle)":"Entity (light or media_player)","entity",t)} ${this.makeDropdown("Button type","button_type",i)}
${this.makeDropdown("Optional - Icon","icon")}
Optional - Show entity state
${this.makeVersion()}
`;if("separator"===this._config.card_type)return html` ${this.makeDropdown("Card type","card_type",n)}
Separator This card is a simple separator for dividing your pop-up into categories / sections. e.g. Lights, Devices, Covers, Settings, Automations... ${this.makeDropdown("Icon","icon")} ${this.makeVersion()} `;if("horizontal-buttons-stack"===this._config.card_type){if(!this.buttonAdded&&this.shadowRoot.querySelector("#add-button")){const t=this.shadowRoot.querySelector("#add-button");for(this.buttonIndex=0;this._config[this.buttonIndex+1+"_link"];)this.buttonIndex++;t.addEventListener("click",(()=>{this.buttonIndex++;const e=t.style.opacity,n=t.innerText;t.style.opacity="0.6",t.style.transition="opacity 1s",t.innerText="Loading...",setTimeout((()=>{t.style.opacity=e,t.innerText=n}),5e3)})),this.buttonAdded=!0}return html` ${this.makeDropdown("Card type","card_type",n)}
Horizontal buttons stack This card is the companion to the pop-up card, allowing you to open the corresponding pop-ups. It also allows you to open any page of your dashboard. In addition, you can add your motion sensors so that the order of the buttons adapts according to the room you just entered. This card is scrollable, remains visible and acts as a footer. Please note that this card may take some time to load in edit mode. Optional - Auto order (Presence/occupancy sensors needed)
${this.makeButton()}
Add Button Styling options Optional - Fix when the sidebar is hidden on desktop
${this.makeVersion()}
`}return"cover"===this._config.card_type?html` ${this.makeDropdown("Card type","card_type",n)}
Cover This card allows you to control your covers. ${this.makeDropdown("Entity","entity",e)} ${this.makeDropdown("Optional - Open icon","icon_open")} ${this.makeDropdown("Optional - Closed icon","icon_close")} ${this.makeVersion()} `:"empty-column"===this._config.card_type?html` ${this.makeDropdown("Card type","card_type",n)}
Empty column Just an empty card to fill any empty column. ${this.makeVersion()} `:this._config.card_type?void 0:html` ${this.makeDropdown("Card type","card_type",n)}
Bubble Card You need to add a card type first. ${this.makeVersion()} `}makeDropdown(t,e,n){this.hass;return t.includes("icon")||t.includes("Icon")?html`
`:html`
`}makeButton(){let t=[];for(let e=1;e<=this.buttonIndex;e++)t.push(html`
`);return t}makeVersion(){return html` Bubble Card ${version} `}removeButton(t){delete this._config[t+"_name"],delete this._config[t+"_icon"],delete this._config[t+"_link"],delete this._config[t+"_entity"],delete this._config[t+"_pir_sensor"];for(let e=t;e