diff --git a/dist/index.js b/dist/index.js index 7d1b3f7..6a17282 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,2 +1,2 @@ -var e,t=(e=require("fecha"))&&"object"==typeof e&&"default"in e?e.default:e;function a(e){var t=e.split(":").map(Number);return 3600*t[0]+60*t[1]+t[2]}var r=function(){try{(new Date).toLocaleDateString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleDateString(t,{year:"numeric",month:"long",day:"numeric"})}:function(e){return t.format(e,"mediumDate")},n=function(){try{(new Date).toLocaleString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleString(t,{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"haDateTime")},s=function(){try{(new Date).toLocaleTimeString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleTimeString(t,{hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"shortTime")},o=[60,60,24,7],i=["second","minute","hour","day"],c=function(e){return e<10?"0"+e:e};function u(e){return e.substr(0,e.indexOf("."))}function l(e){var t=e.language||"en";return e.translationMetadata.translations[t]&&e.translationMetadata.translations[t].isRTL||!1}function h(e){return u(e.entity_id)}var m="hass:bookmark",p=["closed","locked","off"],f=new Set(["fan","input_boolean","light","switch","group","automation"]),d=function(e,t,a,r){r=r||{},a=null==a?{}:a;var n=new Event(t,{bubbles:void 0===r.bubbles||r.bubbles,cancelable:Boolean(r.cancelable),composed:void 0===r.composed||r.composed});return n.detail=a,e.dispatchEvent(n),n},g=new Set(["call-service","divider","section","weblink","cast","select"]),v={alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"},_={alert:"hass:alert",automation:"hass:playlist-play",calendar:"hass:calendar",camera:"hass:video",climate:"hass:thermostat",configurator:"hass:settings",conversation:"hass:text-to-speech",device_tracker:"hass:account",fan:"hass:fan",group:"hass:google-circles-communities",history_graph:"hass:chart-line",homeassistant:"hass:home-assistant",homekit:"hass:home-automation",image_processing:"hass:image-filter-frames",input_boolean:"hass:drawing",input_datetime:"hass:calendar-clock",input_number:"hass:ray-vertex",input_select:"hass:format-list-bulleted",input_text:"hass:textbox",light:"hass:lightbulb",mailbox:"hass:mailbox",notify:"hass:comment-alert",person:"hass:account",plant:"hass:flower",proximity:"hass:apple-safari",remote:"hass:remote",scene:"hass:google-pages",script:"hass:file-document",sensor:"hass:eye",simple_alarm:"hass:bell",sun:"hass:white-balance-sunny",switch:"hass:flash",timer:"hass:timer",updater:"hass:cloud-upload",vacuum:"hass:robot-vacuum",water_heater:"hass:thermometer",weblink:"hass:open-in-new"};function b(e,t){if(e in _)return _[e];switch(e){case"alarm_control_panel":switch(t){case"armed_home":return"hass:bell-plus";case"armed_night":return"hass:bell-sleep";case"disarmed":return"hass:bell-outline";case"triggered":return"hass:bell-ring";default:return"hass:bell"}case"binary_sensor":return t&&"off"===t?"hass:radiobox-blank":"hass:checkbox-marked-circle";case"cover":return"closed"===t?"hass:window-closed":"hass:window-open";case"lock":return t&&"unlocked"===t?"hass:lock-open":"hass:lock";case"media_player":return t&&"off"!==t&&"idle"!==t?"hass:cast-connected":"hass:cast";case"zwave":switch(t){case"dead":return"hass:emoticon-dead";case"sleeping":return"hass:sleep";case"initializing":return"hass:timer-sand";default:return"hass:z-wave"}default:return console.warn("Unable to find icon for domain "+e+" ("+t+")"),m}}var y=function(e){d(window,"haptic",e)},w=function(e,t,a){void 0===a&&(a=!1),a?history.replaceState(null,"",t):history.pushState(null,"",t),d(window,"location-changed",{replace:a})},x=function(e,t,a){void 0===a&&(a=!0);var r,n=u(t),s="group"===n?"homeassistant":n;switch(n){case"lock":r=a?"unlock":"lock";break;case"cover":r=a?"open_cover":"close_cover";break;default:r=a?"turn_on":"turn_off"}return e.callService(s,r,{entity_id:t})},k=function(e,t){var a=p.includes(e.states[t].state);return x(e,t,a)},S=function(e,t,a,r){if(r||(r={action:"more-info"}),!r.confirmation||r.confirmation.exemptions&&r.confirmation.exemptions.some(function(e){return e.user===t.user.id})||(y("warning"),confirm(r.confirmation.text||"Are you sure you want to "+r.action+"?")))switch(r.action){case"more-info":(a.entity||a.camera_image)&&d(e,"hass-more-info",{entityId:a.entity?a.entity:a.camera_image});break;case"navigate":r.navigation_path&&w(0,r.navigation_path);break;case"url":r.url_path&&window.open(r.url_path);break;case"toggle":a.entity&&(k(t,a.entity),y("success"));break;case"call-service":if(!r.service)return void y("failure");var n=r.service.split(".",2);t.callService(n[0],n[1],r.service_data),y("success");break;case"fire-dom-event":d(e,"ll-custom",r)}},D={humidity:"hass:water-percent",illuminance:"hass:brightness-5",temperature:"hass:thermometer",pressure:"hass:gauge",power:"hass:flash",signal_strength:"hass:wifi"},T={binary_sensor:function(e){var t=e.state&&"off"===e.state;switch(e.attributes.device_class){case"battery":return t?"hass:battery":"hass:battery-outline";case"cold":return t?"hass:thermometer":"hass:snowflake";case"connectivity":return t?"hass:server-network-off":"hass:server-network";case"door":return t?"hass:door-closed":"hass:door-open";case"garage_door":return t?"hass:garage":"hass:garage-open";case"gas":case"power":case"problem":case"safety":case"smoke":return t?"hass:shield-check":"hass:alert";case"heat":return t?"hass:thermometer":"hass:fire";case"light":return t?"hass:brightness-5":"hass:brightness-7";case"lock":return t?"hass:lock":"hass:lock-open";case"moisture":return t?"hass:water-off":"hass:water";case"motion":return t?"hass:walk":"hass:run";case"occupancy":return t?"hass:home-outline":"hass:home";case"opening":return t?"hass:square":"hass:square-outline";case"plug":return t?"hass:power-plug-off":"hass:power-plug";case"presence":return t?"hass:home-outline":"hass:home";case"sound":return t?"hass:music-note-off":"hass:music-note";case"vibration":return t?"hass:crop-portrait":"hass:vibrate";case"window":return t?"hass:window-closed":"hass:window-open";default:return t?"hass:radiobox-blank":"hass:checkbox-marked-circle"}},cover:function(e){var t="closed"!==e.state;switch(e.attributes.device_class){case"garage":return t?"hass:garage-open":"hass:garage";case"door":return t?"hass:door-open":"hass:door-closed";case"shutter":return t?"hass:window-shutter-open":"hass:window-shutter";case"blind":return t?"hass:blinds-open":"hass:blinds";case"window":return t?"hass:window-open":"hass:window-closed";default:return b("cover",e.state)}},sensor:function(e){var t=e.attributes.device_class;if(t&&t in D)return D[t];if("battery"===t){var a=Number(e.state);if(isNaN(a))return"hass:battery-unknown";var r=10*Math.round(a/10);return r>=100?"hass:battery":r<=0?"hass:battery-alert":"hass:battery-"+r}var n=e.attributes.unit_of_measurement;return"°C"===n||"°F"===n?"hass:thermometer":b("sensor")},input_datetime:function(e){return e.attributes.has_date?e.attributes.has_time?b("input_datetime"):"hass:calendar":"hass:clock"}};exports.durationToSeconds=a,exports.formatDate=r,exports.formatDateTime=n,exports.formatTime=s,exports.relativeTime=function(e,t,a){void 0===a&&(a={});var r,n=((a.compareTime||new Date).getTime()-e.getTime())/1e3,s=n>=0?"past":"future";n=Math.abs(n);for(var c=0;c0?t+":"+c(a)+":"+c(r):a>0?a+":"+c(r):r>0?""+r:null},exports.timerTimeRemaining=function(e){var t=a(e.attributes.remaining);if("active"===e.state){var r=(new Date).getTime(),n=new Date(e.last_changed).getTime();t=Math.max(t-(r-n)/1e3,0)}return t},exports.applyThemesOnElement=function(e,t,a,r){void 0===r&&(r=!1),e._themes||(e._themes={});var n=t.default_theme;("default"===a||a&&t.themes[a])&&(n=a);var s=Object.assign({},e._themes);if("default"!==n){var o=t.themes[n];Object.keys(o).forEach(function(t){var a="--"+t;e._themes[a]="",s[a]=o[t]})}if(e.updateStyles?e.updateStyles(s):window.ShadyCSS&&window.ShadyCSS.styleSubtree(e,s),r){var i=document.querySelector("meta[name=theme-color]");if(i){i.hasAttribute("default-content")||i.setAttribute("default-content",i.getAttribute("content"));var c=s["--primary-color"]||i.getAttribute("default-content");i.setAttribute("content",c)}}},exports.computeCardSize=function(e){return"function"==typeof e.getCardSize?e.getCardSize():4},exports.computeDomain=u,exports.computeEntity=function(e){return e.substr(e.indexOf(".")+1)},exports.computeRTL=l,exports.computeRTLDirection=function(e){return l(e)?"rtl":"ltr"},exports.computeStateDisplay=function(e,t,a){if("unknown"===t.state||"unavailable"===t.state)return e("state.default."+t.state);if(t.attributes.unit_of_measurement)return t.state+" "+t.attributes.unit_of_measurement;var o=h(t);if("input_datetime"===o){var i;if(!t.attributes.has_time)return i=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day),r(i,a);if(!t.attributes.has_date){var c=new Date;return i=new Date(c.getFullYear(),c.getMonth(),c.getDay(),t.attributes.hour,t.attributes.minute),s(i,a)}return i=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day,t.attributes.hour,t.attributes.minute),n(i,a)}return t.attributes.device_class&&e("component."+o+".state."+t.attributes.device_class+"."+t.state)||e("component."+o+".state._."+t.state)||t.state},exports.computeStateDomain=h,exports.DEFAULT_DOMAIN_ICON=m,exports.DEFAULT_PANEL="lovelace",exports.DOMAINS_WITH_CARD=["climate","cover","configurator","input_select","input_number","input_text","lock","media_player","scene","script","timer","vacuum","water_heater","weblink"],exports.DOMAINS_WITH_MORE_INFO=["alarm_control_panel","automation","camera","climate","configurator","cover","fan","group","history_graph","input_datetime","light","lock","media_player","script","sun","updater","vacuum","water_heater","weather"],exports.DOMAINS_HIDE_MORE_INFO=["input_number","input_select","input_text","scene","weblink"],exports.DOMAINS_MORE_INFO_NO_HISTORY=["camera","configurator","history_graph","scene"],exports.STATES_OFF=p,exports.DOMAINS_TOGGLE=f,exports.UNIT_C="°C",exports.UNIT_F="°F",exports.DEFAULT_VIEW_ENTITY_ID="group.default_view",exports.createThing=function(e,t){void 0===t&&(t=!1);var a=function(e,t){return r("hui-error-card",{type:"error",error:e,config:t})},r=function(e,t){var r=window.document.createElement(e);try{r.setConfig(t)}catch(r){return console.error(e,r),a(r.message,t)}return r};if(!e||"object"!=typeof e||!t&&!e.type)return a("No type defined",e);var n=e.type;if(n&&n.startsWith("custom:"))n=n.substr("custom:".length);else if(t)if(g.has(n))n="hui-"+n+"-row";else{if(!e.entity)return a("Invalid config given.",e);var s=e.entity.split(".",1)[0];n="hui-"+(v[s]||"text")+"-entity-row"}else n="hui-"+n+"-card";if(customElements.get(n))return r(n,e);var o=a("Custom element doesn't exist: "+e.type+".",e);o.style.display="None";var i=setTimeout(function(){o.style.display=""},2e3);return customElements.whenDefined(e.type).then(function(){clearTimeout(i),d(o,"ll-rebuild",{},o)}),o},exports.debounce=function(e,t,a){var r;return void 0===a&&(a=!1),function(){for(var n=[],s=arguments.length;s--;)n[s]=arguments[s];var o=this,i=a&&!r;clearTimeout(r),r=setTimeout(function(){r=null,a||e.apply(o,n)},t),i&&e.apply(o,n)}},exports.fixedIcons=_,exports.domainIcon=b,exports.evaluateFilter=function(e,t){var a=t.value||t,r=t.attribute?e.attributes[t.attribute]:e.state;switch(t.operator||"=="){case"==":return r===a;case"<=":return r<=a;case"<":return r=":return r>=a;case">":return r>a;case"!=":return r!==a;case"regex":return r.match(a);default:return!1}},exports.fireEvent=d,exports.formatNumber=function(e,t,a){return Number.isNaN=Number.isNaN||function e(t){return"number"==typeof t&&e(t)},!Number.isNaN(Number(e))&&Intl?new Intl.NumberFormat(t,function(e,t){var a=t||{};if("string"!=typeof e)return a;if(!t||!t.minimumFractionDigits&&!t.maximumFractionDigits){var r=e.indexOf(".")>-1?e.split(".")[1].length:0;a.minimumFractionDigits=r,a.maximumFractionDigits=r}return a}(e,a)).format(Number(e)):e.toString()},exports.handleActionConfig=S,exports.handleAction=function(e,t,a,r){var n;"double_tap"===r&&a.double_tap_action?n=a.double_tap_action:"hold"===r&&a.hold_action?n=a.hold_action:"tap"===r&&a.tap_action&&(n=a.tap_action),S(e,t,a,n)},exports.handleClick=function(e,t,a,r,n){var s;if(n&&a.double_tap_action?s=a.double_tap_action:r&&a.hold_action?s=a.hold_action:!r&&a.tap_action&&(s=a.tap_action),s||(s={action:"more-info"}),!s.confirmation||s.confirmation.exemptions&&s.confirmation.exemptions.some(function(e){return e.user===t.user.id})||confirm(s.confirmation.text||"Are you sure you want to "+s.action+"?"))switch(s.action){case"more-info":(s.entity||a.entity||a.camera_image)&&(d(e,"hass-more-info",{entityId:s.entity?s.entity:a.entity?a.entity:a.camera_image}),s.haptic&&y(s.haptic));break;case"navigate":s.navigation_path&&(w(0,s.navigation_path),s.haptic&&y(s.haptic));break;case"url":s.url_path&&window.open(s.url_path),s.haptic&&y(s.haptic);break;case"toggle":a.entity&&(k(t,a.entity),s.haptic&&y(s.haptic));break;case"call-service":if(!s.service)return;var o=s.service.split(".",2),i=o[0],c=o[1],u=Object.assign({},s.service_data);"entity"===u.entity_id&&(u.entity_id=a.entity),t.callService(i,c,u),s.haptic&&y(s.haptic)}},exports.forwardHaptic=y,exports.hasAction=function(e){return void 0!==e&&"none"!==e.action},exports.hasConfigOrEntityChanged=function(e,t,a){if(t.has("config")||a)return!0;if(e.config.entity){var r=t.get("hass");return!r||r.states[e.config.entity]!==e.hass.states[e.config.entity]}return!1},exports.hasDoubleClick=function(e){return void 0!==e&&"none"!==e.action},exports.navigate=w,exports.toggleEntity=k,exports.turnOnOffEntities=function(e,t,a){void 0===a&&(a=!0);var r={};t.forEach(function(t){if(p.includes(e.states[t].state)===a){var n=u(t),s=["cover","lock"].includes(n)?n:"homeassistant";s in r||(r[s]=[]),r[s].push(t)}}),Object.keys(r).forEach(function(t){var n;switch(t){case"lock":n=a?"unlock":"lock";break;case"cover":n=a?"open_cover":"close_cover";break;default:n=a?"turn_on":"turn_off"}e.callService(t,n,{entity_id:r[t]})})},exports.turnOnOffEntity=x,exports.getLovelace=function(){var e=document.querySelector("home-assistant");if(e=(e=(e=(e=(e=(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root")){var t=e.lovelace;return t.current_view=e.___curView,t}return null},exports.stateIcon=function(e){if(!e)return m;if(e.attributes.icon)return e.attributes.icon;var t=u(e.entity_id);return t in T?T[t](e):b(t,e.state)}; +var e,t=(e=require("fecha"))&&"object"==typeof e&&"default"in e?e.default:e;function a(e){var t=e.split(":").map(Number);return 3600*t[0]+60*t[1]+t[2]}var r=function(){try{(new Date).toLocaleDateString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleDateString(t,{year:"numeric",month:"long",day:"numeric"})}:function(e){return t.format(e,"mediumDate")},n=function(){try{(new Date).toLocaleString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleString(t,{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"haDateTime")},s=function(){try{(new Date).toLocaleTimeString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleTimeString(t,{hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"shortTime")},o=[60,60,24,7],i=["second","minute","hour","day"],c=function(e){return e<10?"0"+e:e};function u(e){return e.substr(0,e.indexOf("."))}function l(e){var t=e.language||"en";return e.translationMetadata.translations[t]&&e.translationMetadata.translations[t].isRTL||!1}function h(e){return u(e.entity_id)}var m="hass:bookmark",p=["closed","locked","off"],f=new Set(["fan","input_boolean","light","switch","group","automation"]),d=function(e,t,a,r){r=r||{},a=null==a?{}:a;var n=new Event(t,{bubbles:void 0===r.bubbles||r.bubbles,cancelable:Boolean(r.cancelable),composed:void 0===r.composed||r.composed});return n.detail=a,e.dispatchEvent(n),n},g=new Set(["call-service","divider","section","weblink","cast","select"]),v={alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"},b={alert:"hass:alert",automation:"hass:playlist-play",calendar:"hass:calendar",camera:"hass:video",climate:"hass:thermostat",configurator:"hass:settings",conversation:"hass:text-to-speech",device_tracker:"hass:account",fan:"hass:fan",group:"hass:google-circles-communities",history_graph:"hass:chart-line",homeassistant:"hass:home-assistant",homekit:"hass:home-automation",image_processing:"hass:image-filter-frames",input_boolean:"hass:drawing",input_datetime:"hass:calendar-clock",input_number:"hass:ray-vertex",input_select:"hass:format-list-bulleted",input_text:"hass:textbox",light:"hass:lightbulb",mailbox:"hass:mailbox",notify:"hass:comment-alert",person:"hass:account",plant:"hass:flower",proximity:"hass:apple-safari",remote:"hass:remote",scene:"hass:google-pages",script:"hass:file-document",sensor:"hass:eye",simple_alarm:"hass:bell",sun:"hass:white-balance-sunny",switch:"hass:flash",timer:"hass:timer",updater:"hass:cloud-upload",vacuum:"hass:robot-vacuum",water_heater:"hass:thermometer",weblink:"hass:open-in-new"};function _(e,t){if(e in b)return b[e];switch(e){case"alarm_control_panel":switch(t){case"armed_home":return"hass:bell-plus";case"armed_night":return"hass:bell-sleep";case"disarmed":return"hass:bell-outline";case"triggered":return"hass:bell-ring";default:return"hass:bell"}case"binary_sensor":return t&&"off"===t?"hass:radiobox-blank":"hass:checkbox-marked-circle";case"cover":return"closed"===t?"hass:window-closed":"hass:window-open";case"lock":return t&&"unlocked"===t?"hass:lock-open":"hass:lock";case"media_player":return t&&"off"!==t&&"idle"!==t?"hass:cast-connected":"hass:cast";case"zwave":switch(t){case"dead":return"hass:emoticon-dead";case"sleeping":return"hass:sleep";case"initializing":return"hass:timer-sand";default:return"hass:z-wave"}default:return console.warn("Unable to find icon for domain "+e+" ("+t+")"),m}}var y=function(e){d(window,"haptic",e)},w=function(e,t,a){void 0===a&&(a=!1),a?history.replaceState(null,"",t):history.pushState(null,"",t),d(window,"location-changed",{replace:a})},x=function(e,t,a){void 0===a&&(a=!0);var r,n=u(t),s="group"===n?"homeassistant":n;switch(n){case"lock":r=a?"unlock":"lock";break;case"cover":r=a?"open_cover":"close_cover";break;default:r=a?"turn_on":"turn_off"}return e.callService(s,r,{entity_id:t})},k=function(e,t){var a=p.includes(e.states[t].state);return x(e,t,a)},S=function(e,t,a,r){if(r||(r={action:"more-info"}),!r.confirmation||r.confirmation.exemptions&&r.confirmation.exemptions.some(function(e){return e.user===t.user.id})||(y("warning"),confirm(r.confirmation.text||"Are you sure you want to "+r.action+"?")))switch(r.action){case"more-info":(a.entity||a.camera_image)&&d(e,"hass-more-info",{entityId:a.entity?a.entity:a.camera_image});break;case"navigate":r.navigation_path&&w(0,r.navigation_path);break;case"url":r.url_path&&window.open(r.url_path);break;case"toggle":a.entity&&(k(t,a.entity),y("success"));break;case"call-service":if(!r.service)return void y("failure");var n=r.service.split(".",2);t.callService(n[0],n[1],r.service_data),y("success");break;case"fire-dom-event":d(e,"ll-custom",r)}},D={humidity:"hass:water-percent",illuminance:"hass:brightness-5",temperature:"hass:thermometer",pressure:"hass:gauge",power:"hass:flash",signal_strength:"hass:wifi"},T={binary_sensor:function(e){var t=e.state&&"off"===e.state;switch(e.attributes.device_class){case"battery":return t?"hass:battery":"hass:battery-outline";case"cold":return t?"hass:thermometer":"hass:snowflake";case"connectivity":return t?"hass:server-network-off":"hass:server-network";case"door":return t?"hass:door-closed":"hass:door-open";case"garage_door":return t?"hass:garage":"hass:garage-open";case"gas":case"power":case"problem":case"safety":case"smoke":return t?"hass:shield-check":"hass:alert";case"heat":return t?"hass:thermometer":"hass:fire";case"light":return t?"hass:brightness-5":"hass:brightness-7";case"lock":return t?"hass:lock":"hass:lock-open";case"moisture":return t?"hass:water-off":"hass:water";case"motion":return t?"hass:walk":"hass:run";case"occupancy":return t?"hass:home-outline":"hass:home";case"opening":return t?"hass:square":"hass:square-outline";case"plug":return t?"hass:power-plug-off":"hass:power-plug";case"presence":return t?"hass:home-outline":"hass:home";case"sound":return t?"hass:music-note-off":"hass:music-note";case"vibration":return t?"hass:crop-portrait":"hass:vibrate";case"window":return t?"hass:window-closed":"hass:window-open";default:return t?"hass:radiobox-blank":"hass:checkbox-marked-circle"}},cover:function(e){var t="closed"!==e.state;switch(e.attributes.device_class){case"garage":return t?"hass:garage-open":"hass:garage";case"door":return t?"hass:door-open":"hass:door-closed";case"shutter":return t?"hass:window-shutter-open":"hass:window-shutter";case"blind":return t?"hass:blinds-open":"hass:blinds";case"window":return t?"hass:window-open":"hass:window-closed";default:return _("cover",e.state)}},sensor:function(e){var t=e.attributes.device_class;if(t&&t in D)return D[t];if("battery"===t){var a=Number(e.state);if(isNaN(a))return"hass:battery-unknown";var r=10*Math.round(a/10);return r>=100?"hass:battery":r<=0?"hass:battery-alert":"hass:battery-"+r}var n=e.attributes.unit_of_measurement;return"°C"===n||"°F"===n?"hass:thermometer":_("sensor")},input_datetime:function(e){return e.attributes.has_date?e.attributes.has_time?_("input_datetime"):"hass:calendar":"hass:clock"}};exports.durationToSeconds=a,exports.formatDate=r,exports.formatDateTime=n,exports.formatTime=s,exports.relativeTime=function(e,t,a){void 0===a&&(a={});var r,n=((a.compareTime||new Date).getTime()-e.getTime())/1e3,s=n>=0?"past":"future";n=Math.abs(n);for(var c=0;c0?t+":"+c(a)+":"+c(r):a>0?a+":"+c(r):r>0?""+r:null},exports.timerTimeRemaining=function(e){var t=a(e.attributes.remaining);if("active"===e.state){var r=(new Date).getTime(),n=new Date(e.last_changed).getTime();t=Math.max(t-(r-n)/1e3,0)}return t},exports.applyThemesOnElement=function(e,t,a,r){void 0===r&&(r=!1),e._themes||(e._themes={});var n=t.default_theme;("default"===a||a&&t.themes[a])&&(n=a);var s=Object.assign({},e._themes);if("default"!==n){var o=t.themes[n];Object.keys(o).forEach(function(t){var a="--"+t;e._themes[a]="",s[a]=o[t]})}if(e.updateStyles?e.updateStyles(s):window.ShadyCSS&&window.ShadyCSS.styleSubtree(e,s),r){var i=document.querySelector("meta[name=theme-color]");if(i){i.hasAttribute("default-content")||i.setAttribute("default-content",i.getAttribute("content"));var c=s["--primary-color"]||i.getAttribute("default-content");i.setAttribute("content",c)}}},exports.computeCardSize=function(e){return"function"==typeof e.getCardSize?e.getCardSize():4},exports.computeDomain=u,exports.computeEntity=function(e){return e.substr(e.indexOf(".")+1)},exports.computeRTL=l,exports.computeRTLDirection=function(e){return l(e)?"rtl":"ltr"},exports.computeStateDisplay=function(e,t,a){if("unknown"===t.state||"unavailable"===t.state)return e("state.default."+t.state);if(t.attributes.unit_of_measurement)return t.state+" "+t.attributes.unit_of_measurement;var o=h(t);if("input_datetime"===o){var i;if(!t.attributes.has_time)return i=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day),r(i,a);if(!t.attributes.has_date){var c=new Date;return i=new Date(c.getFullYear(),c.getMonth(),c.getDay(),t.attributes.hour,t.attributes.minute),s(i,a)}return i=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day,t.attributes.hour,t.attributes.minute),n(i,a)}return t.attributes.device_class&&e("component."+o+".state."+t.attributes.device_class+"."+t.state)||e("component."+o+".state._."+t.state)||t.state},exports.computeStateDomain=h,exports.DEFAULT_DOMAIN_ICON=m,exports.DEFAULT_PANEL="lovelace",exports.DOMAINS_WITH_CARD=["climate","cover","configurator","input_select","input_number","input_text","lock","media_player","scene","script","timer","vacuum","water_heater","weblink"],exports.DOMAINS_WITH_MORE_INFO=["alarm_control_panel","automation","camera","climate","configurator","cover","fan","group","history_graph","input_datetime","light","lock","media_player","script","sun","updater","vacuum","water_heater","weather"],exports.DOMAINS_HIDE_MORE_INFO=["input_number","input_select","input_text","scene","weblink"],exports.DOMAINS_MORE_INFO_NO_HISTORY=["camera","configurator","history_graph","scene"],exports.STATES_OFF=p,exports.DOMAINS_TOGGLE=f,exports.UNIT_C="°C",exports.UNIT_F="°F",exports.DEFAULT_VIEW_ENTITY_ID="group.default_view",exports.createThing=function(e,t){void 0===t&&(t=!1);var a=function(e,t){return r("hui-error-card",{type:"error",error:e,config:t})},r=function(e,t){var r=window.document.createElement(e);try{r.setConfig(t)}catch(r){return console.error(e,r),a(r.message,t)}return r};if(!e||"object"!=typeof e||!t&&!e.type)return a("No type defined",e);var n=e.type;if(n&&n.startsWith("custom:"))n=n.substr("custom:".length);else if(t)if(g.has(n))n="hui-"+n+"-row";else{if(!e.entity)return a("Invalid config given.",e);var s=e.entity.split(".",1)[0];n="hui-"+(v[s]||"text")+"-entity-row"}else n="hui-"+n+"-card";if(customElements.get(n))return r(n,e);var o=a("Custom element doesn't exist: "+e.type+".",e);o.style.display="None";var i=setTimeout(function(){o.style.display=""},2e3);return customElements.whenDefined(e.type).then(function(){clearTimeout(i),d(o,"ll-rebuild",{},o)}),o},exports.debounce=function(e,t,a){var r;return void 0===a&&(a=!1),function(){for(var n=[],s=arguments.length;s--;)n[s]=arguments[s];var o=this,i=a&&!r;clearTimeout(r),r=setTimeout(function(){r=null,a||e.apply(o,n)},t),i&&e.apply(o,n)}},exports.fixedIcons=b,exports.domainIcon=_,exports.evaluateFilter=function(e,t){var a=t.value||t,r=t.attribute?e.attributes[t.attribute]:e.state;switch(t.operator||"=="){case"==":return r===a;case"<=":return r<=a;case"<":return r=":return r>=a;case">":return r>a;case"!=":return r!==a;case"regex":return r.match(a);default:return!1}},exports.fireEvent=d,exports.formatNumber=function(e,t,a){return Number.isNaN=Number.isNaN||function e(t){return"number"==typeof t&&e(t)},!Number.isNaN(Number(e))&&Intl?new Intl.NumberFormat(t,function(e,t){var a=t||{};if("string"!=typeof e)return a;if(!t||!t.minimumFractionDigits&&!t.maximumFractionDigits){var r=e.indexOf(".")>-1?e.split(".")[1].length:0;a.minimumFractionDigits=r,a.maximumFractionDigits=r}return a}(e,a)).format(Number(e)):e.toString()},exports.handleActionConfig=S,exports.handleAction=function(e,t,a,r){var n;"double_tap"===r&&a.double_tap_action?n=a.double_tap_action:"hold"===r&&a.hold_action?n=a.hold_action:"tap"===r&&a.tap_action&&(n=a.tap_action),S(e,t,a,n)},exports.handleClick=function(e,t,a,r,n){var s;if(n&&a.double_tap_action?s=a.double_tap_action:r&&a.hold_action?s=a.hold_action:!r&&a.tap_action&&(s=a.tap_action),s||(s={action:"more-info"}),!s.confirmation||s.confirmation.exemptions&&s.confirmation.exemptions.some(function(e){return e.user===t.user.id})||confirm(s.confirmation.text||"Are you sure you want to "+s.action+"?"))switch(s.action){case"more-info":(s.entity||a.entity||a.camera_image)&&(d(e,"hass-more-info",{entityId:s.entity?s.entity:a.entity?a.entity:a.camera_image}),s.haptic&&y(s.haptic));break;case"navigate":s.navigation_path&&(w(0,s.navigation_path),s.haptic&&y(s.haptic));break;case"url":s.url_path&&window.open(s.url_path),s.haptic&&y(s.haptic);break;case"toggle":a.entity&&(k(t,a.entity),s.haptic&&y(s.haptic));break;case"call-service":if(!s.service)return;var o=s.service.split(".",2),i=o[0],c=o[1],u=Object.assign({},s.service_data);"entity"===u.entity_id&&(u.entity_id=a.entity),t.callService(i,c,u),s.haptic&&y(s.haptic);break;case"fire-dom-event":d(e,"ll-custom",s),s.haptic&&y(s.haptic)}},exports.forwardHaptic=y,exports.hasAction=function(e){return void 0!==e&&"none"!==e.action},exports.hasConfigOrEntityChanged=function(e,t,a){if(t.has("config")||a)return!0;if(e.config.entity){var r=t.get("hass");return!r||r.states[e.config.entity]!==e.hass.states[e.config.entity]}return!1},exports.hasDoubleClick=function(e){return void 0!==e&&"none"!==e.action},exports.navigate=w,exports.toggleEntity=k,exports.turnOnOffEntities=function(e,t,a){void 0===a&&(a=!0);var r={};t.forEach(function(t){if(p.includes(e.states[t].state)===a){var n=u(t),s=["cover","lock"].includes(n)?n:"homeassistant";s in r||(r[s]=[]),r[s].push(t)}}),Object.keys(r).forEach(function(t){var n;switch(t){case"lock":n=a?"unlock":"lock";break;case"cover":n=a?"open_cover":"close_cover";break;default:n=a?"turn_on":"turn_off"}e.callService(t,n,{entity_id:r[t]})})},exports.turnOnOffEntity=x,exports.getLovelace=function(){var e=document.querySelector("home-assistant");if(e=(e=(e=(e=(e=(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root")){var t=e.lovelace;return t.current_view=e.___curView,t}return null},exports.stateIcon=function(e){if(!e)return m;if(e.attributes.icon)return e.attributes.icon;var t=u(e.entity_id);return t in T?T[t](e):_(t,e.state)}; //# sourceMappingURL=index.js.map diff --git a/dist/index.js.map b/dist/index.js.map index 2aa654d..7de5e8e 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/datetime/duration_to_seconds.ts","../src/datetime/format_date.ts","../src/datetime/format_date_time.ts","../src/datetime/format_time.ts","../src/datetime/relative_time.ts","../src/datetime/seconds_to_duration.ts","../src/compute-domain.ts","../src/compute-rtl.ts","../src/compute-state-domain.ts","../src/const.ts","../src/fire-event.ts","../src/create-thing.ts","../src/domain_icons.ts","../src/haptic.ts","../src/navigate.ts","../src/turn-on-off-entity.ts","../src/toggle-entity.ts","../src/handle-action.ts","../src/sensor_icon.ts","../src/state_icon.ts","../src/binary_sensor_icon.ts","../src/cover_icon.ts","../src/input_datetime_icon.ts","../src/datetime/timer_time_remaining.ts","../src/apply_themes_on_element.ts","../src/compute-card-size.ts","../src/compute-entity.ts","../src/compute-state-display.ts","../src/debounce.ts","../src/evaluate-filter.ts","../src/format-number.ts","../src/handle-click.ts","../src/has-action.ts","../src/has-changed.ts","../src/has-double-click.ts","../src/turn-on-off-entities.ts","../src/get-lovelace.ts"],"sourcesContent":["export function durationToSeconds(duration: string): number {\n const parts = duration.split(\":\").map(Number);\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n}\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleDateStringSupportsOptions() {\n try {\n new Date().toLocaleDateString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDate = (toLocaleDateStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleDateString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"mediumDate\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleStringSupportsOptions() {\n try {\n new Date().toLocaleString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDateTime = (toLocaleStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"haDateTime\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleTimeStringSupportsOptions() {\n try {\n new Date().toLocaleTimeString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatTime = (toLocaleTimeStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleTimeString(locales, {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"shortTime\"));\n","import { LocalizeFunc } from \"../translations/localize\";\n\n/**\n * Calculate a string representing a date object as relative time from now.\n *\n * Example output: 5 minutes ago, in 3 days.\n */\nconst tests = [60, 60, 24, 7];\nconst langKey = [\"second\", \"minute\", \"hour\", \"day\"];\n\nexport function relativeTime(\n dateObj: Date,\n localize: LocalizeFunc,\n options: {\n compareTime?: Date;\n includeTense?: boolean;\n } = {}\n): string {\n const compareTime = options.compareTime || new Date();\n let delta = (compareTime.getTime() - dateObj.getTime()) / 1000;\n const tense = delta >= 0 ? \"past\" : \"future\";\n delta = Math.abs(delta);\n\n let timeDesc;\n\n for (let i = 0; i < tests.length; i++) {\n if (delta < tests[i]) {\n delta = Math.floor(delta);\n timeDesc = localize(\n `ui.components.relative_time.duration.${langKey[i]}`,\n \"count\",\n delta\n );\n break;\n }\n\n delta /= tests[i];\n }\n\n if (timeDesc === undefined) {\n delta = Math.floor(delta);\n timeDesc = localize(\n \"ui.components.relative_time.duration.week\",\n \"count\",\n delta\n );\n }\n\n return options.includeTense === false\n ? timeDesc\n : localize(`ui.components.relative_time.${tense}`, \"time\", timeDesc);\n}\n","const leftPad = (num: number) => (num < 10 ? `0${num}` : num);\n\nexport function secondsToDuration(d: number) {\n const h = Math.floor(d / 3600);\n const m = Math.floor((d % 3600) / 60);\n const s = Math.floor((d % 3600) % 60);\n\n if (h > 0) {\n return `${h}:${leftPad(m)}:${leftPad(s)}`;\n }\n if (m > 0) {\n return `${m}:${leftPad(s)}`;\n }\n if (s > 0) {\n return \"\" + s;\n }\n return null;\n}\n","export function computeDomain(entityId: string): string {\n return entityId.substr(0, entityId.indexOf(\".\"));\n}\n","import { HomeAssistant } from \"./types\";\n\nexport function computeRTL(hass: HomeAssistant) {\n const lang = hass.language || \"en\";\n if (hass.translationMetadata.translations[lang]) {\n return hass.translationMetadata.translations[lang].isRTL || false;\n }\n return false;\n}\n\nexport function computeRTLDirection(hass: HomeAssistant) {\n return computeRTL(hass) ? \"rtl\" : \"ltr\";\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport function computeStateDomain(stateObj: HassEntity) {\n return computeDomain(stateObj.entity_id);\n}\n","/** Constants to be used in the frontend. */\n\n// Constants should be alphabetically sorted by name.\n// Arrays with values should be alphabetically sorted if order doesn't matter.\n// Each constant should have a description what it is supposed to be used for.\n\n/** Icon to use when no icon specified for domain. */\nexport const DEFAULT_DOMAIN_ICON = \"hass:bookmark\";\n\n/** Panel to show when no panel is picked. */\nexport const DEFAULT_PANEL = \"lovelace\";\n\n/** Domains that have a state card. */\nexport const DOMAINS_WITH_CARD = [\n \"climate\",\n \"cover\",\n \"configurator\",\n \"input_select\",\n \"input_number\",\n \"input_text\",\n \"lock\",\n \"media_player\",\n \"scene\",\n \"script\",\n \"timer\",\n \"vacuum\",\n \"water_heater\",\n \"weblink\"\n];\n\n/** Domains with separate more info dialog. */\nexport const DOMAINS_WITH_MORE_INFO = [\n \"alarm_control_panel\",\n \"automation\",\n \"camera\",\n \"climate\",\n \"configurator\",\n \"cover\",\n \"fan\",\n \"group\",\n \"history_graph\",\n \"input_datetime\",\n \"light\",\n \"lock\",\n \"media_player\",\n \"script\",\n \"sun\",\n \"updater\",\n \"vacuum\",\n \"water_heater\",\n \"weather\"\n];\n\n/** Domains that show no more info dialog. */\nexport const DOMAINS_HIDE_MORE_INFO = [\n \"input_number\",\n \"input_select\",\n \"input_text\",\n \"scene\",\n \"weblink\"\n];\n\n/** Domains that should have the history hidden in the more info dialog. */\nexport const DOMAINS_MORE_INFO_NO_HISTORY = [\n \"camera\",\n \"configurator\",\n \"history_graph\",\n \"scene\"\n];\n\n/** States that we consider \"off\". */\nexport const STATES_OFF = [\"closed\", \"locked\", \"off\"];\n\n/** Domains where we allow toggle in Lovelace. */\nexport const DOMAINS_TOGGLE = new Set([\n \"fan\",\n \"input_boolean\",\n \"light\",\n \"switch\",\n \"group\",\n \"automation\"\n]);\n\n/** Temperature units. */\nexport const UNIT_C = \"°C\";\nexport const UNIT_F = \"°F\";\n\n/** Entity ID of the default view. */\nexport const DEFAULT_VIEW_ENTITY_ID = \"group.default_view\";\n","// Polymer legacy event helpers used courtesy of the Polymer project.\n//\n// Copyright (c) 2017 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\ndeclare global {\n // tslint:disable-next-line\n interface HASSDomEvents {}\n}\n\nexport type ValidHassDomEvent = keyof HASSDomEvents;\n\nexport interface HASSDomEvent extends Event {\n detail: T;\n}\n\n/**\n * Dispatches a custom event with an optional detail value.\n *\n * @param {string} type Name of event type.\n * @param {*=} detail Detail value containing event-specific\n * payload.\n * @param {{ bubbles: (boolean|undefined),\n * cancelable: (boolean|undefined),\n * composed: (boolean|undefined) }=}\n * options Object specifying options. These may include:\n * `bubbles` (boolean, defaults to `true`),\n * `cancelable` (boolean, defaults to false), and\n * `node` on which to fire the event (HTMLElement, defaults to `this`).\n * @return {Event} The new event that was fired.\n */\nexport const fireEvent = (\n node: HTMLElement | Window,\n type: HassEvent,\n detail?: HASSDomEvents[HassEvent],\n options?: {\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n }\n) => {\n options = options || {};\n // @ts-ignore\n detail = detail === null || detail === undefined ? {} : detail;\n const event = new Event(type, {\n bubbles: options.bubbles === undefined ? true : options.bubbles,\n cancelable: Boolean(options.cancelable),\n composed: options.composed === undefined ? true : options.composed\n });\n (event as any).detail = detail;\n node.dispatchEvent(event);\n return event;\n};\n","import { fireEvent } from \"./fire-event\";\n\nconst SPECIAL_TYPES = new Set([\n \"call-service\",\n \"divider\",\n \"section\",\n \"weblink\",\n \"cast\",\n \"select\"\n]);\nconst DOMAIN_TO_ELEMENT_TYPE = {\n alert: \"toggle\",\n automation: \"toggle\",\n climate: \"climate\",\n cover: \"cover\",\n fan: \"toggle\",\n group: \"group\",\n input_boolean: \"toggle\",\n input_number: \"input-number\",\n input_select: \"input-select\",\n input_text: \"input-text\",\n light: \"toggle\",\n lock: \"lock\",\n media_player: \"media-player\",\n remote: \"toggle\",\n scene: \"scene\",\n script: \"script\",\n sensor: \"sensor\",\n timer: \"timer\",\n switch: \"toggle\",\n vacuum: \"toggle\",\n // Temporary. Once climate is rewritten,\n // water heater should get it's own row.\n water_heater: \"climate\",\n input_datetime: \"input-datetime\"\n};\n\nexport const createThing = (cardConfig, isRow = false) => {\n const _createError = (error, config) => {\n return _createThing(\n \"hui-error-card\",\n {\n type: \"error\",\n error,\n config\n }\n );\n };\n\n const _createThing = (tag, config) => {\n const element = window.document.createElement(tag);\n try {\n element.setConfig(config);\n } catch (err) {\n console.error(tag, err);\n return _createError(err.message, config);\n }\n return element;\n };\n\n if (!cardConfig || typeof cardConfig !== \"object\" || (!isRow && !cardConfig.type))\n return _createError(\"No type defined\", cardConfig);\n let tag = cardConfig.type;\n if (tag && tag.startsWith(\"custom:\")) {\n tag = tag.substr(\"custom:\".length);\n } else if (isRow) {\n if (SPECIAL_TYPES.has(tag)) {\n tag = `hui-${tag}-row`;\n } else {\n if (!cardConfig.entity) {\n return _createError(\"Invalid config given.\", cardConfig);\n }\n \n const domain = cardConfig.entity.split(\".\", 1)[0];\n tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || \"text\"}-entity-row`;\n }\n } else {\n tag = `hui-${tag}-card`;\n }\n\n if (customElements.get(tag)) return _createThing(tag, cardConfig);\n\n // If element doesn't exist (yet) create an error\n const element = _createError(\n `Custom element doesn't exist: ${cardConfig.type}.`,\n cardConfig\n );\n element.style.display = \"None\";\n const timer = setTimeout(() => {\n element.style.display = \"\";\n }, 2000);\n // Remove error if element is defined later\n customElements.whenDefined(cardConfig.type).then(() => {\n clearTimeout(timer);\n fireEvent(element, \"ll-rebuild\", {}, element);\n });\n\n return element;\n};\n","/**\n * Return the icon to be used for a domain.\n *\n * Optionally pass in a state to influence the domain icon.\n */\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\n\nexport const fixedIcons = {\n alert: \"hass:alert\",\n automation: \"hass:playlist-play\",\n calendar: \"hass:calendar\",\n camera: \"hass:video\",\n climate: \"hass:thermostat\",\n configurator: \"hass:settings\",\n conversation: \"hass:text-to-speech\",\n device_tracker: \"hass:account\",\n fan: \"hass:fan\",\n group: \"hass:google-circles-communities\",\n history_graph: \"hass:chart-line\",\n homeassistant: \"hass:home-assistant\",\n homekit: \"hass:home-automation\",\n image_processing: \"hass:image-filter-frames\",\n input_boolean: \"hass:drawing\",\n input_datetime: \"hass:calendar-clock\",\n input_number: \"hass:ray-vertex\",\n input_select: \"hass:format-list-bulleted\",\n input_text: \"hass:textbox\",\n light: \"hass:lightbulb\",\n mailbox: \"hass:mailbox\",\n notify: \"hass:comment-alert\",\n person: \"hass:account\",\n plant: \"hass:flower\",\n proximity: \"hass:apple-safari\",\n remote: \"hass:remote\",\n scene: \"hass:google-pages\",\n script: \"hass:file-document\",\n sensor: \"hass:eye\",\n simple_alarm: \"hass:bell\",\n sun: \"hass:white-balance-sunny\",\n switch: \"hass:flash\",\n timer: \"hass:timer\",\n updater: \"hass:cloud-upload\",\n vacuum: \"hass:robot-vacuum\",\n water_heater: \"hass:thermometer\",\n weblink: \"hass:open-in-new\"\n};\n\nexport function domainIcon(domain: string, state?: string): string {\n if (domain in fixedIcons) {\n return fixedIcons[domain];\n }\n\n switch (domain) {\n case \"alarm_control_panel\":\n switch (state) {\n case \"armed_home\":\n return \"hass:bell-plus\";\n case \"armed_night\":\n return \"hass:bell-sleep\";\n case \"disarmed\":\n return \"hass:bell-outline\";\n case \"triggered\":\n return \"hass:bell-ring\";\n default:\n return \"hass:bell\";\n }\n\n case \"binary_sensor\":\n return state && state === \"off\"\n ? \"hass:radiobox-blank\"\n : \"hass:checkbox-marked-circle\";\n\n case \"cover\":\n return state === \"closed\" ? \"hass:window-closed\" : \"hass:window-open\";\n\n case \"lock\":\n return state && state === \"unlocked\" ? \"hass:lock-open\" : \"hass:lock\";\n\n case \"media_player\":\n return state && state !== \"off\" && state !== \"idle\"\n ? \"hass:cast-connected\"\n : \"hass:cast\";\n\n case \"zwave\":\n switch (state) {\n case \"dead\":\n return \"hass:emoticon-dead\";\n case \"sleeping\":\n return \"hass:sleep\";\n case \"initializing\":\n return \"hass:timer-sand\";\n default:\n return \"hass:z-wave\";\n }\n\n default:\n // tslint:disable-next-line\n console.warn(\n \"Unable to find icon for domain \" + domain + \" (\" + state + \")\"\n );\n return DEFAULT_DOMAIN_ICON;\n }\n}\n","import { HASSDomEvent, fireEvent } from \"./fire-event\";\n\n/**\n * Broadcast haptic feedback requests\n */\n\n\n// Allowed types are from iOS HIG.\n// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics\n// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible.\nexport type HapticType =\n | \"success\"\n | \"warning\"\n | \"failure\"\n | \"light\"\n | \"medium\"\n | \"heavy\"\n | \"selection\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n haptic: HapticType;\n }\n\n interface GlobalEventHandlersEventMap {\n haptic: HASSDomEvent;\n }\n}\n\nexport const forwardHaptic = (hapticType: HapticType) => {\n fireEvent(window, \"haptic\", hapticType);\n};\n","import { fireEvent } from \"./fire-event\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n \"location-changed\": {\n replace: boolean;\n };\n }\n}\n\nexport const navigate = (\n _node: any,\n path: string,\n replace: boolean = false\n) => {\n if (replace) {\n history.replaceState(null, \"\", path);\n } else {\n history.pushState(null, \"\", path);\n }\n fireEvent(window, \"location-changed\", {\n replace\n });\n};\n","import { HomeAssistant } from \"./types\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntity = (\n hass: HomeAssistant,\n entityId: string,\n turnOn = true\n): Promise => {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = stateDomain === \"group\" ? \"homeassistant\" : stateDomain;\n\n let service;\n switch (stateDomain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n return hass.callService(serviceDomain, service, { entity_id: entityId });\n};\n","import { STATES_OFF } from \"./const\";\nimport { turnOnOffEntity } from \"./turn-on-off-entity\";\nimport { HomeAssistant } from \"./types\";\n\nexport const toggleEntity = (\n hass: HomeAssistant,\n entityId: string\n): Promise => {\n const turnOn = STATES_OFF.includes(hass.states[entityId].state);\n return turnOnOffEntity(hass, entityId, turnOn);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { forwardHaptic } from \"./haptic\";\nimport { fireEvent } from \"./fire-event\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleActionConfig = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n actionConfig: ActionConfig | undefined\n): void => {\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\",\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n (e) => e.user === hass!.user!.id\n ))\n ) {\n forwardHaptic(\"warning\");\n\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: config.entity ? config.entity : config.camera_image!,\n });\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n }\n break;\n case \"url\":\n if (actionConfig.url_path) {\n window.open(actionConfig.url_path);\n }\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n forwardHaptic(\"success\");\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n forwardHaptic(\"failure\");\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n hass.callService(domain, service, actionConfig.service_data);\n forwardHaptic(\"success\");\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n }\n }\n};\n\nexport const handleAction = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n action: string\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (action === \"double_tap\" && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (action === \"hold\" && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (action === \"tap\" && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n handleActionConfig(node, hass, config, actionConfig);\n};\n","/** Return an icon representing a sensor state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { UNIT_C, UNIT_F } from \"./const\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst fixedDeviceClassIcons = {\n humidity: \"hass:water-percent\",\n illuminance: \"hass:brightness-5\",\n temperature: \"hass:thermometer\",\n pressure: \"hass:gauge\",\n power: \"hass:flash\",\n signal_strength: \"hass:wifi\",\n};\n\nexport const sensorIcon = (state: HassEntity) => {\n const dclass = state.attributes.device_class;\n\n if (dclass && dclass in fixedDeviceClassIcons) {\n return fixedDeviceClassIcons[dclass];\n }\n if (dclass === \"battery\") {\n const battery = Number(state.state);\n if (isNaN(battery)) {\n return \"hass:battery-unknown\";\n }\n const batteryRound = Math.round(battery / 10) * 10;\n if (batteryRound >= 100) {\n return \"hass:battery\";\n }\n if (batteryRound <= 0) {\n return \"hass:battery-alert\";\n }\n // Will return one of the following icons: (listed so extractor picks up)\n // hass:battery-10\n // hass:battery-20\n // hass:battery-30\n // hass:battery-40\n // hass:battery-50\n // hass:battery-60\n // hass:battery-70\n // hass:battery-80\n // hass:battery-90\n // We obscure 'hass' in iconname so this name does not get picked up\n return `${\"hass\"}:battery-${batteryRound}`;\n }\n\n const unit = state.attributes.unit_of_measurement;\n if (unit === UNIT_C || unit === UNIT_F) {\n return \"hass:thermometer\";\n }\n return domainIcon(\"sensor\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\nimport { binarySensorIcon } from \"./binary_sensor_icon\";\nimport { coverIcon } from \"./cover_icon\";\nimport { sensorIcon } from \"./sensor_icon\";\nimport { inputDateTimeIcon } from \"./input_datetime_icon\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst domainIcons = {\n binary_sensor: binarySensorIcon,\n cover: coverIcon,\n sensor: sensorIcon,\n input_datetime: inputDateTimeIcon,\n};\n\nexport const stateIcon = (state: HassEntity) => {\n if (!state) {\n return DEFAULT_DOMAIN_ICON;\n }\n if (state.attributes.icon) {\n return state.attributes.icon;\n }\n\n const domain = computeDomain(state.entity_id);\n\n if (domain in domainIcons) {\n return domainIcons[domain](state);\n }\n return domainIcon(domain, state.state);\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\n/** Return an icon representing a binary sensor state. */\n\nexport const binarySensorIcon = (state: HassEntity) => {\n const activated = state.state && state.state === \"off\";\n switch (state.attributes.device_class) {\n case \"battery\":\n return activated ? \"hass:battery\" : \"hass:battery-outline\";\n case \"cold\":\n return activated ? \"hass:thermometer\" : \"hass:snowflake\";\n case \"connectivity\":\n return activated ? \"hass:server-network-off\" : \"hass:server-network\";\n case \"door\":\n return activated ? \"hass:door-closed\" : \"hass:door-open\";\n case \"garage_door\":\n return activated ? \"hass:garage\" : \"hass:garage-open\";\n case \"gas\":\n case \"power\":\n case \"problem\":\n case \"safety\":\n case \"smoke\":\n return activated ? \"hass:shield-check\" : \"hass:alert\";\n case \"heat\":\n return activated ? \"hass:thermometer\" : \"hass:fire\";\n case \"light\":\n return activated ? \"hass:brightness-5\" : \"hass:brightness-7\";\n case \"lock\":\n return activated ? \"hass:lock\" : \"hass:lock-open\";\n case \"moisture\":\n return activated ? \"hass:water-off\" : \"hass:water\";\n case \"motion\":\n return activated ? \"hass:walk\" : \"hass:run\";\n case \"occupancy\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"opening\":\n return activated ? \"hass:square\" : \"hass:square-outline\";\n case \"plug\":\n return activated ? \"hass:power-plug-off\" : \"hass:power-plug\";\n case \"presence\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"sound\":\n return activated ? \"hass:music-note-off\" : \"hass:music-note\";\n case \"vibration\":\n return activated ? \"hass:crop-portrait\" : \"hass:vibrate\";\n case \"window\":\n return activated ? \"hass:window-closed\" : \"hass:window-open\";\n default:\n return activated ? \"hass:radiobox-blank\" : \"hass:checkbox-marked-circle\";\n }\n};\n","/** Return an icon representing a cover state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { domainIcon } from \"./domain_icons\";\n\nexport const coverIcon = (state: HassEntity): string => {\n const open = state.state !== \"closed\";\n switch (state.attributes.device_class) {\n case \"garage\":\n return open ? \"hass:garage-open\" : \"hass:garage\";\n case \"door\":\n return open ? \"hass:door-open\" : \"hass:door-closed\";\n case \"shutter\":\n return open ? \"hass:window-shutter-open\" : \"hass:window-shutter\";\n case \"blind\":\n return open ? \"hass:blinds-open\" : \"hass:blinds\";\n case \"window\":\n return open ? \"hass:window-open\" : \"hass:window-closed\";\n default:\n return domainIcon(\"cover\", state.state);\n }\n};\n","/** Return an icon representing an input datetime state. */\nimport { domainIcon } from \"./domain_icons\";\nimport { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const inputDateTimeIcon = (state: HassEntity): string => {\n if (!state.attributes.has_date) {\n return \"hass:clock\";\n }\n if (!state.attributes.has_time) {\n return \"hass:calendar\";\n }\n return domainIcon(\"input_datetime\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { durationToSeconds } from \"../datetime/duration_to_seconds\";\n\nexport function timerTimeRemaining(stateObj: HassEntity) {\n let timeRemaining = durationToSeconds(stateObj.attributes.remaining);\n\n if (stateObj.state === \"active\") {\n const now = new Date().getTime();\n const madeActive = new Date(stateObj.last_changed).getTime();\n timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);\n }\n\n return timeRemaining;\n}\n","/**\n * Apply a theme to an element by setting the CSS variables on it.\n *\n * element: Element to apply theme on.\n * themes: HASS Theme information\n * localTheme: selected theme.\n * updateMeta: boolean if we should update the theme-color meta element.\n */\nexport const applyThemesOnElement = (\n element,\n themes,\n localTheme,\n updateMeta = false\n) => {\n if (!element._themes) {\n element._themes = {};\n }\n let themeName = themes.default_theme;\n if (localTheme === \"default\" || (localTheme && themes.themes[localTheme])) {\n themeName = localTheme;\n }\n const styles = { ...element._themes };\n if (themeName !== \"default\") {\n const theme = themes.themes[themeName];\n Object.keys(theme).forEach((key) => {\n const prefixedKey = \"--\" + key;\n element._themes[prefixedKey] = \"\";\n styles[prefixedKey] = theme[key];\n });\n }\n if (element.updateStyles) {\n element.updateStyles(styles);\n } else if ((window as any).ShadyCSS) {\n // implement updateStyles() method of Polemer elements\n (window as any).ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ (element), styles);\n }\n\n if (!updateMeta) {\n return;\n }\n\n const meta = document.querySelector(\"meta[name=theme-color]\");\n if (meta) {\n if (!meta.hasAttribute(\"default-content\")) {\n meta.setAttribute(\"default-content\", meta.getAttribute(\"content\")!);\n }\n const themeColor =\n styles[\"--primary-color\"] || meta.getAttribute(\"default-content\");\n meta.setAttribute(\"content\", themeColor);\n }\n}\n","import { LovelaceCard } from \"./types\";\n\nexport const computeCardSize = (card: LovelaceCard): number | Promise => {\n return typeof card.getCardSize === \"function\" ? card.getCardSize() : 4;\n};","export function computeEntity(entityId: string): string {\n return entityId.substr(entityId.indexOf(\".\") + 1);\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { formatDateTime } from \"./datetime/format_date_time\";\nimport { formatDate } from \"./datetime/format_date\";\nimport { formatTime } from \"./datetime/format_time\";\nimport { LocalizeFunc } from \"./translations/localize\";\nimport { computeStateDomain } from \"./compute-state-domain\";\n\nexport function computeStateDisplay(\n localize: LocalizeFunc,\n stateObj: HassEntity,\n language: string\n): string {\n if (stateObj.state === \"unknown\" || stateObj.state === \"unavailable\") {\n return localize(`state.default.${stateObj.state}`);\n }\n\n if (stateObj.attributes.unit_of_measurement) {\n return `${stateObj.state} ${stateObj.attributes.unit_of_measurement}`;\n }\n\n const domain = computeStateDomain(stateObj);\n\n if (domain === \"input_datetime\") {\n let date: Date;\n if (!stateObj.attributes.has_time) {\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day\n );\n return formatDate(date, language);\n }\n if (!stateObj.attributes.has_date) {\n const now = new Date();\n date = new Date(\n // Due to bugs.chromium.org/p/chromium/issues/detail?id=797548\n // don't use artificial 1970 year.\n now.getFullYear(),\n now.getMonth(),\n now.getDay(),\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatTime(date, language);\n }\n\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day,\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatDateTime(date, language);\n }\n\n return (\n // Return device class translation\n (stateObj.attributes.device_class &&\n localize(\n `component.${domain}.state.${stateObj.attributes.device_class}.${stateObj.state}`\n )) ||\n // Return default translation\n localize(`component.${domain}.state._.${stateObj.state}`) ||\n // We don't know! Return the raw state.\n stateObj.state\n );\n}\n","/**\r\n * Returns a function, that, as long as it continues to be invoked, will not be triggered. It will be called after it stops being called for `wait` ms.\r\n * This can be usefull for ResizeObservers for example.\r\n * @param func The function you want to debounce\r\n * @param wait Period to wait in ms\r\n * @param immediate Triggering on the leading edge instead of the trailing\r\n * @returns Debounced Function\r\n */\r\n// eslint-disable-next-line: ban-types\r\nexport const debounce = unknown>(\r\n func: T,\r\n wait: number,\r\n immediate = false\r\n): T => {\r\n let timeout;\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n return function (...args) {\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n const later = () => {\r\n timeout = null;\r\n if (!immediate) {\r\n func.apply(context, args);\r\n }\r\n };\r\n const callNow = immediate && !timeout;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(later, wait);\r\n if (callNow) {\r\n func.apply(context, args);\r\n }\r\n };\r\n};\r\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {\n const operator = filter.operator || \"==\";\n const value = filter.value || filter;\n const state = filter.attribute\n ? stateObj.attributes[filter.attribute]\n : stateObj.state;\n\n switch (operator) {\n case \"==\":\n return state === value;\n case \"<=\":\n return state <= value;\n case \"<\":\n return state < value;\n case \">=\":\n return state >= value;\n case \">\":\n return state > value;\n case \"!=\":\n return state !== value;\n case \"regex\": {\n return state.match(value);\n }\n default:\n return false;\n }\n};\n","/**\r\n * Formats a number based on the specified language with thousands separator(s) and decimal character for better legibility.\r\n * @param num The number to format\r\n * @param language The language to use when formatting the number\r\n */\r\nexport const formatNumber = (\r\n num: string | number,\r\n language: string,\r\n options?: Intl.NumberFormatOptions\r\n): string => {\r\n // Polyfill for Number.isNaN, which is more reliable than the global isNaN()\r\n Number.isNaN =\r\n Number.isNaN ||\r\n function isNaN(input) {\r\n return typeof input === \"number\" && isNaN(input);\r\n };\r\n\r\n if (!Number.isNaN(Number(num)) && Intl) {\r\n return new Intl.NumberFormat(\r\n language,\r\n getDefaultFormatOptions(num, options)\r\n ).format(Number(num));\r\n }\r\n return num.toString();\r\n};\r\n\r\n/**\r\n * Generates default options for Intl.NumberFormat\r\n * @param num The number to be formatted\r\n * @param options The Intl.NumberFormatOptions that should be included in the returned options\r\n */\r\nconst getDefaultFormatOptions = (\r\n num: string | number,\r\n options?: Intl.NumberFormatOptions\r\n): Intl.NumberFormatOptions => {\r\n const defaultOptions: Intl.NumberFormatOptions = options || {};\r\n\r\n if (typeof num !== \"string\") {\r\n return defaultOptions;\r\n }\r\n\r\n // Keep decimal trailing zeros if they are present in a string numeric value\r\n if (\r\n !options ||\r\n (!options.minimumFractionDigits && !options.maximumFractionDigits)\r\n ) {\r\n const digits = num.indexOf(\".\") > -1 ? num.split(\".\")[1].length : 0;\r\n defaultOptions.minimumFractionDigits = digits;\r\n defaultOptions.maximumFractionDigits = digits;\r\n }\r\n\r\n return defaultOptions;\r\n};\r\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { fireEvent } from \"./fire-event\";\nimport { forwardHaptic } from \"./haptic\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleClick = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n hold: boolean,\n dblClick: boolean\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (dblClick && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (hold && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (!hold && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\"\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n e => e.user === hass!.user!.id\n ))\n ) {\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (actionConfig.entity || config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: actionConfig.entity\n ? actionConfig.entity\n : config.entity\n ? config.entity\n : config.camera_image\n });\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"url\":\n actionConfig.url_path && window.open(actionConfig.url_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n const serviceData = { ...actionConfig.service_data };\n if (serviceData.entity_id === \"entity\") {\n serviceData.entity_id = config.entity;\n }\n hass.callService(domain, service, serviceData);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n }\n};\n","import { ActionConfig } from \"./types\";\n\nexport function hasAction(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}\n","import { PropertyValues } from \"lit-element\";\n\nimport { HomeAssistant } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasConfigOrEntityChanged(\n element: any,\n changedProps: PropertyValues,\n forceUpdate: Boolean,\n): boolean {\n if (changedProps.has('config') || forceUpdate) {\n return true;\n }\n\n if (element.config!.entity) {\n const oldHass = changedProps.get('hass') as HomeAssistant | undefined;\n if (oldHass) {\n return (\n oldHass.states[element.config!.entity]\n !== element.hass!.states[element.config!.entity]\n );\n }\n return true;\n } else {\n return false;\n }\n}","import { ActionConfig } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasDoubleClick(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}","import { HomeAssistant } from \"./types\";\nimport { STATES_OFF } from \"./const\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntities = (\n hass: HomeAssistant,\n entityIds: string[],\n turnOn = true\n): void => {\n const domainsToCall = {};\n entityIds.forEach((entityId) => {\n if (STATES_OFF.includes(hass.states[entityId].state) === turnOn) {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = [\"cover\", \"lock\"].includes(stateDomain)\n ? stateDomain\n : \"homeassistant\";\n\n if (!(serviceDomain in domainsToCall)) {\n domainsToCall[serviceDomain] = [];\n }\n domainsToCall[serviceDomain].push(entityId);\n }\n });\n\n Object.keys(domainsToCall).forEach((domain) => {\n let service;\n switch (domain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n const entities = domainsToCall[domain];\n hass.callService(domain, service, { entity_id: entities });\n });\n};\n","export const getLovelace = () => {\n let root: any = document.querySelector('home-assistant');\n root = root && root.shadowRoot;\n root = root && root.querySelector('home-assistant-main');\n root = root && root.shadowRoot;\n root = root && root.querySelector('app-drawer-layout partial-panel-resolver');\n root = root && root.shadowRoot || root;\n root = root && root.querySelector('ha-panel-lovelace');\n root = root && root.shadowRoot;\n root = root && root.querySelector('hui-root');\n if (root) {\n const ll = root.lovelace;\n ll.current_view = root.___curView;\n return ll;\n }\n return null;\n}\n"],"names":["durationToSeconds","duration","parts","split","map","Number","formatDate","Date","toLocaleDateString","e","name","toLocaleDateStringSupportsOptions","dateObj","locales","year","month","day","fecha","format","formatDateTime","toLocaleString","toLocaleStringSupportsOptions","hour","minute","formatTime","toLocaleTimeString","toLocaleTimeStringSupportsOptions","tests","langKey","leftPad","num","computeDomain","entityId","substr","indexOf","computeRTL","hass","lang","language","translationMetadata","translations","isRTL","computeStateDomain","stateObj","entity_id","DEFAULT_DOMAIN_ICON","STATES_OFF","DOMAINS_TOGGLE","Set","fireEvent","node","type","detail","options","event","Event","bubbles","undefined","cancelable","Boolean","composed","dispatchEvent","SPECIAL_TYPES","DOMAIN_TO_ELEMENT_TYPE","alert","automation","climate","cover","fan","group","input_boolean","input_number","input_select","input_text","light","lock","media_player","remote","scene","script","sensor","timer","switch","vacuum","water_heater","input_datetime","fixedIcons","calendar","camera","configurator","conversation","device_tracker","history_graph","homeassistant","homekit","image_processing","mailbox","notify","person","plant","proximity","simple_alarm","sun","updater","weblink","domainIcon","domain","state","console","warn","forwardHaptic","hapticType","window","navigate","_node","path","replace","history","replaceState","pushState","turnOnOffEntity","turnOn","service","stateDomain","serviceDomain","callService","toggleEntity","includes","states","handleActionConfig","config","actionConfig","action","confirmation","exemptions","some","user","id","confirm","text","entity","camera_image","navigation_path","url_path","open","service_data","fixedDeviceClassIcons","humidity","illuminance","temperature","pressure","power","signal_strength","domainIcons","binary_sensor","activated","attributes","device_class","dclass","battery","isNaN","batteryRound","Math","round","unit","unit_of_measurement","has_date","has_time","localize","timeDesc","delta","compareTime","getTime","tense","abs","let","i","length","floor","includeTense","d","h","m","s","timeRemaining","remaining","now","madeActive","last_changed","max","element","themes","localTheme","updateMeta","_themes","themeName","default_theme","styles","Object","theme","keys","forEach","key","prefixedKey","updateStyles","ShadyCSS","styleSubtree","meta","document","querySelector","hasAttribute","setAttribute","getAttribute","themeColor","card","getCardSize","date","getFullYear","getMonth","getDay","cardConfig","isRow","_createError","error","_createThing","tag","createElement","setConfig","err","message","startsWith","has","customElements","get","style","display","setTimeout","whenDefined","then","clearTimeout","func","wait","immediate","timeout","context","this","callNow","apply","args","filter","value","attribute","operator","match","input","Intl","NumberFormat","defaultOptions","minimumFractionDigits","maximumFractionDigits","digits","getDefaultFormatOptions","toString","double_tap_action","hold_action","tap_action","hold","dblClick","haptic","serviceData","changedProps","forceUpdate","oldHass","entityIds","domainsToCall","push","root","shadowRoot","ll","lovelace","current_view","___curView","icon"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/datetime/duration_to_seconds.ts","../src/datetime/format_date.ts","../src/datetime/format_date_time.ts","../src/datetime/format_time.ts","../src/datetime/relative_time.ts","../src/datetime/seconds_to_duration.ts","../src/compute-domain.ts","../src/compute-rtl.ts","../src/compute-state-domain.ts","../src/const.ts","../src/fire-event.ts","../src/create-thing.ts","../src/domain_icons.ts","../src/haptic.ts","../src/navigate.ts","../src/turn-on-off-entity.ts","../src/toggle-entity.ts","../src/handle-action.ts","../src/sensor_icon.ts","../src/state_icon.ts","../src/binary_sensor_icon.ts","../src/cover_icon.ts","../src/input_datetime_icon.ts","../src/datetime/timer_time_remaining.ts","../src/apply_themes_on_element.ts","../src/compute-card-size.ts","../src/compute-entity.ts","../src/compute-state-display.ts","../src/debounce.ts","../src/evaluate-filter.ts","../src/format-number.ts","../src/handle-click.ts","../src/has-action.ts","../src/has-changed.ts","../src/has-double-click.ts","../src/turn-on-off-entities.ts","../src/get-lovelace.ts"],"sourcesContent":["export function durationToSeconds(duration: string): number {\n const parts = duration.split(\":\").map(Number);\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n}\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleDateStringSupportsOptions() {\n try {\n new Date().toLocaleDateString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDate = (toLocaleDateStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleDateString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"mediumDate\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleStringSupportsOptions() {\n try {\n new Date().toLocaleString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDateTime = (toLocaleStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"haDateTime\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleTimeStringSupportsOptions() {\n try {\n new Date().toLocaleTimeString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatTime = (toLocaleTimeStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleTimeString(locales, {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"shortTime\"));\n","import { LocalizeFunc } from \"../translations/localize\";\n\n/**\n * Calculate a string representing a date object as relative time from now.\n *\n * Example output: 5 minutes ago, in 3 days.\n */\nconst tests = [60, 60, 24, 7];\nconst langKey = [\"second\", \"minute\", \"hour\", \"day\"];\n\nexport function relativeTime(\n dateObj: Date,\n localize: LocalizeFunc,\n options: {\n compareTime?: Date;\n includeTense?: boolean;\n } = {}\n): string {\n const compareTime = options.compareTime || new Date();\n let delta = (compareTime.getTime() - dateObj.getTime()) / 1000;\n const tense = delta >= 0 ? \"past\" : \"future\";\n delta = Math.abs(delta);\n\n let timeDesc;\n\n for (let i = 0; i < tests.length; i++) {\n if (delta < tests[i]) {\n delta = Math.floor(delta);\n timeDesc = localize(\n `ui.components.relative_time.duration.${langKey[i]}`,\n \"count\",\n delta\n );\n break;\n }\n\n delta /= tests[i];\n }\n\n if (timeDesc === undefined) {\n delta = Math.floor(delta);\n timeDesc = localize(\n \"ui.components.relative_time.duration.week\",\n \"count\",\n delta\n );\n }\n\n return options.includeTense === false\n ? timeDesc\n : localize(`ui.components.relative_time.${tense}`, \"time\", timeDesc);\n}\n","const leftPad = (num: number) => (num < 10 ? `0${num}` : num);\n\nexport function secondsToDuration(d: number) {\n const h = Math.floor(d / 3600);\n const m = Math.floor((d % 3600) / 60);\n const s = Math.floor((d % 3600) % 60);\n\n if (h > 0) {\n return `${h}:${leftPad(m)}:${leftPad(s)}`;\n }\n if (m > 0) {\n return `${m}:${leftPad(s)}`;\n }\n if (s > 0) {\n return \"\" + s;\n }\n return null;\n}\n","export function computeDomain(entityId: string): string {\n return entityId.substr(0, entityId.indexOf(\".\"));\n}\n","import { HomeAssistant } from \"./types\";\n\nexport function computeRTL(hass: HomeAssistant) {\n const lang = hass.language || \"en\";\n if (hass.translationMetadata.translations[lang]) {\n return hass.translationMetadata.translations[lang].isRTL || false;\n }\n return false;\n}\n\nexport function computeRTLDirection(hass: HomeAssistant) {\n return computeRTL(hass) ? \"rtl\" : \"ltr\";\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport function computeStateDomain(stateObj: HassEntity) {\n return computeDomain(stateObj.entity_id);\n}\n","/** Constants to be used in the frontend. */\n\n// Constants should be alphabetically sorted by name.\n// Arrays with values should be alphabetically sorted if order doesn't matter.\n// Each constant should have a description what it is supposed to be used for.\n\n/** Icon to use when no icon specified for domain. */\nexport const DEFAULT_DOMAIN_ICON = \"hass:bookmark\";\n\n/** Panel to show when no panel is picked. */\nexport const DEFAULT_PANEL = \"lovelace\";\n\n/** Domains that have a state card. */\nexport const DOMAINS_WITH_CARD = [\n \"climate\",\n \"cover\",\n \"configurator\",\n \"input_select\",\n \"input_number\",\n \"input_text\",\n \"lock\",\n \"media_player\",\n \"scene\",\n \"script\",\n \"timer\",\n \"vacuum\",\n \"water_heater\",\n \"weblink\"\n];\n\n/** Domains with separate more info dialog. */\nexport const DOMAINS_WITH_MORE_INFO = [\n \"alarm_control_panel\",\n \"automation\",\n \"camera\",\n \"climate\",\n \"configurator\",\n \"cover\",\n \"fan\",\n \"group\",\n \"history_graph\",\n \"input_datetime\",\n \"light\",\n \"lock\",\n \"media_player\",\n \"script\",\n \"sun\",\n \"updater\",\n \"vacuum\",\n \"water_heater\",\n \"weather\"\n];\n\n/** Domains that show no more info dialog. */\nexport const DOMAINS_HIDE_MORE_INFO = [\n \"input_number\",\n \"input_select\",\n \"input_text\",\n \"scene\",\n \"weblink\"\n];\n\n/** Domains that should have the history hidden in the more info dialog. */\nexport const DOMAINS_MORE_INFO_NO_HISTORY = [\n \"camera\",\n \"configurator\",\n \"history_graph\",\n \"scene\"\n];\n\n/** States that we consider \"off\". */\nexport const STATES_OFF = [\"closed\", \"locked\", \"off\"];\n\n/** Domains where we allow toggle in Lovelace. */\nexport const DOMAINS_TOGGLE = new Set([\n \"fan\",\n \"input_boolean\",\n \"light\",\n \"switch\",\n \"group\",\n \"automation\"\n]);\n\n/** Temperature units. */\nexport const UNIT_C = \"°C\";\nexport const UNIT_F = \"°F\";\n\n/** Entity ID of the default view. */\nexport const DEFAULT_VIEW_ENTITY_ID = \"group.default_view\";\n","// Polymer legacy event helpers used courtesy of the Polymer project.\n//\n// Copyright (c) 2017 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\ndeclare global {\n // tslint:disable-next-line\n interface HASSDomEvents {}\n}\n\nexport type ValidHassDomEvent = keyof HASSDomEvents;\n\nexport interface HASSDomEvent extends Event {\n detail: T;\n}\n\n/**\n * Dispatches a custom event with an optional detail value.\n *\n * @param {string} type Name of event type.\n * @param {*=} detail Detail value containing event-specific\n * payload.\n * @param {{ bubbles: (boolean|undefined),\n * cancelable: (boolean|undefined),\n * composed: (boolean|undefined) }=}\n * options Object specifying options. These may include:\n * `bubbles` (boolean, defaults to `true`),\n * `cancelable` (boolean, defaults to false), and\n * `node` on which to fire the event (HTMLElement, defaults to `this`).\n * @return {Event} The new event that was fired.\n */\nexport const fireEvent = (\n node: HTMLElement | Window,\n type: HassEvent,\n detail?: HASSDomEvents[HassEvent],\n options?: {\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n }\n) => {\n options = options || {};\n // @ts-ignore\n detail = detail === null || detail === undefined ? {} : detail;\n const event = new Event(type, {\n bubbles: options.bubbles === undefined ? true : options.bubbles,\n cancelable: Boolean(options.cancelable),\n composed: options.composed === undefined ? true : options.composed\n });\n (event as any).detail = detail;\n node.dispatchEvent(event);\n return event;\n};\n","import { fireEvent } from \"./fire-event\";\n\nconst SPECIAL_TYPES = new Set([\n \"call-service\",\n \"divider\",\n \"section\",\n \"weblink\",\n \"cast\",\n \"select\"\n]);\nconst DOMAIN_TO_ELEMENT_TYPE = {\n alert: \"toggle\",\n automation: \"toggle\",\n climate: \"climate\",\n cover: \"cover\",\n fan: \"toggle\",\n group: \"group\",\n input_boolean: \"toggle\",\n input_number: \"input-number\",\n input_select: \"input-select\",\n input_text: \"input-text\",\n light: \"toggle\",\n lock: \"lock\",\n media_player: \"media-player\",\n remote: \"toggle\",\n scene: \"scene\",\n script: \"script\",\n sensor: \"sensor\",\n timer: \"timer\",\n switch: \"toggle\",\n vacuum: \"toggle\",\n // Temporary. Once climate is rewritten,\n // water heater should get it's own row.\n water_heater: \"climate\",\n input_datetime: \"input-datetime\"\n};\n\nexport const createThing = (cardConfig, isRow = false) => {\n const _createError = (error, config) => {\n return _createThing(\n \"hui-error-card\",\n {\n type: \"error\",\n error,\n config\n }\n );\n };\n\n const _createThing = (tag, config) => {\n const element = window.document.createElement(tag);\n try {\n element.setConfig(config);\n } catch (err) {\n console.error(tag, err);\n return _createError(err.message, config);\n }\n return element;\n };\n\n if (!cardConfig || typeof cardConfig !== \"object\" || (!isRow && !cardConfig.type))\n return _createError(\"No type defined\", cardConfig);\n let tag = cardConfig.type;\n if (tag && tag.startsWith(\"custom:\")) {\n tag = tag.substr(\"custom:\".length);\n } else if (isRow) {\n if (SPECIAL_TYPES.has(tag)) {\n tag = `hui-${tag}-row`;\n } else {\n if (!cardConfig.entity) {\n return _createError(\"Invalid config given.\", cardConfig);\n }\n \n const domain = cardConfig.entity.split(\".\", 1)[0];\n tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || \"text\"}-entity-row`;\n }\n } else {\n tag = `hui-${tag}-card`;\n }\n\n if (customElements.get(tag)) return _createThing(tag, cardConfig);\n\n // If element doesn't exist (yet) create an error\n const element = _createError(\n `Custom element doesn't exist: ${cardConfig.type}.`,\n cardConfig\n );\n element.style.display = \"None\";\n const timer = setTimeout(() => {\n element.style.display = \"\";\n }, 2000);\n // Remove error if element is defined later\n customElements.whenDefined(cardConfig.type).then(() => {\n clearTimeout(timer);\n fireEvent(element, \"ll-rebuild\", {}, element);\n });\n\n return element;\n};\n","/**\n * Return the icon to be used for a domain.\n *\n * Optionally pass in a state to influence the domain icon.\n */\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\n\nexport const fixedIcons = {\n alert: \"hass:alert\",\n automation: \"hass:playlist-play\",\n calendar: \"hass:calendar\",\n camera: \"hass:video\",\n climate: \"hass:thermostat\",\n configurator: \"hass:settings\",\n conversation: \"hass:text-to-speech\",\n device_tracker: \"hass:account\",\n fan: \"hass:fan\",\n group: \"hass:google-circles-communities\",\n history_graph: \"hass:chart-line\",\n homeassistant: \"hass:home-assistant\",\n homekit: \"hass:home-automation\",\n image_processing: \"hass:image-filter-frames\",\n input_boolean: \"hass:drawing\",\n input_datetime: \"hass:calendar-clock\",\n input_number: \"hass:ray-vertex\",\n input_select: \"hass:format-list-bulleted\",\n input_text: \"hass:textbox\",\n light: \"hass:lightbulb\",\n mailbox: \"hass:mailbox\",\n notify: \"hass:comment-alert\",\n person: \"hass:account\",\n plant: \"hass:flower\",\n proximity: \"hass:apple-safari\",\n remote: \"hass:remote\",\n scene: \"hass:google-pages\",\n script: \"hass:file-document\",\n sensor: \"hass:eye\",\n simple_alarm: \"hass:bell\",\n sun: \"hass:white-balance-sunny\",\n switch: \"hass:flash\",\n timer: \"hass:timer\",\n updater: \"hass:cloud-upload\",\n vacuum: \"hass:robot-vacuum\",\n water_heater: \"hass:thermometer\",\n weblink: \"hass:open-in-new\"\n};\n\nexport function domainIcon(domain: string, state?: string): string {\n if (domain in fixedIcons) {\n return fixedIcons[domain];\n }\n\n switch (domain) {\n case \"alarm_control_panel\":\n switch (state) {\n case \"armed_home\":\n return \"hass:bell-plus\";\n case \"armed_night\":\n return \"hass:bell-sleep\";\n case \"disarmed\":\n return \"hass:bell-outline\";\n case \"triggered\":\n return \"hass:bell-ring\";\n default:\n return \"hass:bell\";\n }\n\n case \"binary_sensor\":\n return state && state === \"off\"\n ? \"hass:radiobox-blank\"\n : \"hass:checkbox-marked-circle\";\n\n case \"cover\":\n return state === \"closed\" ? \"hass:window-closed\" : \"hass:window-open\";\n\n case \"lock\":\n return state && state === \"unlocked\" ? \"hass:lock-open\" : \"hass:lock\";\n\n case \"media_player\":\n return state && state !== \"off\" && state !== \"idle\"\n ? \"hass:cast-connected\"\n : \"hass:cast\";\n\n case \"zwave\":\n switch (state) {\n case \"dead\":\n return \"hass:emoticon-dead\";\n case \"sleeping\":\n return \"hass:sleep\";\n case \"initializing\":\n return \"hass:timer-sand\";\n default:\n return \"hass:z-wave\";\n }\n\n default:\n // tslint:disable-next-line\n console.warn(\n \"Unable to find icon for domain \" + domain + \" (\" + state + \")\"\n );\n return DEFAULT_DOMAIN_ICON;\n }\n}\n","import { HASSDomEvent, fireEvent } from \"./fire-event\";\n\n/**\n * Broadcast haptic feedback requests\n */\n\n\n// Allowed types are from iOS HIG.\n// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics\n// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible.\nexport type HapticType =\n | \"success\"\n | \"warning\"\n | \"failure\"\n | \"light\"\n | \"medium\"\n | \"heavy\"\n | \"selection\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n haptic: HapticType;\n }\n\n interface GlobalEventHandlersEventMap {\n haptic: HASSDomEvent;\n }\n}\n\nexport const forwardHaptic = (hapticType: HapticType) => {\n fireEvent(window, \"haptic\", hapticType);\n};\n","import { fireEvent } from \"./fire-event\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n \"location-changed\": {\n replace: boolean;\n };\n }\n}\n\nexport const navigate = (\n _node: any,\n path: string,\n replace: boolean = false\n) => {\n if (replace) {\n history.replaceState(null, \"\", path);\n } else {\n history.pushState(null, \"\", path);\n }\n fireEvent(window, \"location-changed\", {\n replace\n });\n};\n","import { HomeAssistant } from \"./types\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntity = (\n hass: HomeAssistant,\n entityId: string,\n turnOn = true\n): Promise => {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = stateDomain === \"group\" ? \"homeassistant\" : stateDomain;\n\n let service;\n switch (stateDomain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n return hass.callService(serviceDomain, service, { entity_id: entityId });\n};\n","import { STATES_OFF } from \"./const\";\nimport { turnOnOffEntity } from \"./turn-on-off-entity\";\nimport { HomeAssistant } from \"./types\";\n\nexport const toggleEntity = (\n hass: HomeAssistant,\n entityId: string\n): Promise => {\n const turnOn = STATES_OFF.includes(hass.states[entityId].state);\n return turnOnOffEntity(hass, entityId, turnOn);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { forwardHaptic } from \"./haptic\";\nimport { fireEvent } from \"./fire-event\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleActionConfig = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n actionConfig: ActionConfig | undefined\n): void => {\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\",\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n (e) => e.user === hass!.user!.id\n ))\n ) {\n forwardHaptic(\"warning\");\n\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: config.entity ? config.entity : config.camera_image!,\n });\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n }\n break;\n case \"url\":\n if (actionConfig.url_path) {\n window.open(actionConfig.url_path);\n }\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n forwardHaptic(\"success\");\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n forwardHaptic(\"failure\");\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n hass.callService(domain, service, actionConfig.service_data);\n forwardHaptic(\"success\");\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n }\n }\n};\n\nexport const handleAction = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n action: string\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (action === \"double_tap\" && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (action === \"hold\" && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (action === \"tap\" && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n handleActionConfig(node, hass, config, actionConfig);\n};\n","/** Return an icon representing a sensor state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { UNIT_C, UNIT_F } from \"./const\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst fixedDeviceClassIcons = {\n humidity: \"hass:water-percent\",\n illuminance: \"hass:brightness-5\",\n temperature: \"hass:thermometer\",\n pressure: \"hass:gauge\",\n power: \"hass:flash\",\n signal_strength: \"hass:wifi\",\n};\n\nexport const sensorIcon = (state: HassEntity) => {\n const dclass = state.attributes.device_class;\n\n if (dclass && dclass in fixedDeviceClassIcons) {\n return fixedDeviceClassIcons[dclass];\n }\n if (dclass === \"battery\") {\n const battery = Number(state.state);\n if (isNaN(battery)) {\n return \"hass:battery-unknown\";\n }\n const batteryRound = Math.round(battery / 10) * 10;\n if (batteryRound >= 100) {\n return \"hass:battery\";\n }\n if (batteryRound <= 0) {\n return \"hass:battery-alert\";\n }\n // Will return one of the following icons: (listed so extractor picks up)\n // hass:battery-10\n // hass:battery-20\n // hass:battery-30\n // hass:battery-40\n // hass:battery-50\n // hass:battery-60\n // hass:battery-70\n // hass:battery-80\n // hass:battery-90\n // We obscure 'hass' in iconname so this name does not get picked up\n return `${\"hass\"}:battery-${batteryRound}`;\n }\n\n const unit = state.attributes.unit_of_measurement;\n if (unit === UNIT_C || unit === UNIT_F) {\n return \"hass:thermometer\";\n }\n return domainIcon(\"sensor\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\nimport { binarySensorIcon } from \"./binary_sensor_icon\";\nimport { coverIcon } from \"./cover_icon\";\nimport { sensorIcon } from \"./sensor_icon\";\nimport { inputDateTimeIcon } from \"./input_datetime_icon\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst domainIcons = {\n binary_sensor: binarySensorIcon,\n cover: coverIcon,\n sensor: sensorIcon,\n input_datetime: inputDateTimeIcon,\n};\n\nexport const stateIcon = (state: HassEntity) => {\n if (!state) {\n return DEFAULT_DOMAIN_ICON;\n }\n if (state.attributes.icon) {\n return state.attributes.icon;\n }\n\n const domain = computeDomain(state.entity_id);\n\n if (domain in domainIcons) {\n return domainIcons[domain](state);\n }\n return domainIcon(domain, state.state);\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\n/** Return an icon representing a binary sensor state. */\n\nexport const binarySensorIcon = (state: HassEntity) => {\n const activated = state.state && state.state === \"off\";\n switch (state.attributes.device_class) {\n case \"battery\":\n return activated ? \"hass:battery\" : \"hass:battery-outline\";\n case \"cold\":\n return activated ? \"hass:thermometer\" : \"hass:snowflake\";\n case \"connectivity\":\n return activated ? \"hass:server-network-off\" : \"hass:server-network\";\n case \"door\":\n return activated ? \"hass:door-closed\" : \"hass:door-open\";\n case \"garage_door\":\n return activated ? \"hass:garage\" : \"hass:garage-open\";\n case \"gas\":\n case \"power\":\n case \"problem\":\n case \"safety\":\n case \"smoke\":\n return activated ? \"hass:shield-check\" : \"hass:alert\";\n case \"heat\":\n return activated ? \"hass:thermometer\" : \"hass:fire\";\n case \"light\":\n return activated ? \"hass:brightness-5\" : \"hass:brightness-7\";\n case \"lock\":\n return activated ? \"hass:lock\" : \"hass:lock-open\";\n case \"moisture\":\n return activated ? \"hass:water-off\" : \"hass:water\";\n case \"motion\":\n return activated ? \"hass:walk\" : \"hass:run\";\n case \"occupancy\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"opening\":\n return activated ? \"hass:square\" : \"hass:square-outline\";\n case \"plug\":\n return activated ? \"hass:power-plug-off\" : \"hass:power-plug\";\n case \"presence\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"sound\":\n return activated ? \"hass:music-note-off\" : \"hass:music-note\";\n case \"vibration\":\n return activated ? \"hass:crop-portrait\" : \"hass:vibrate\";\n case \"window\":\n return activated ? \"hass:window-closed\" : \"hass:window-open\";\n default:\n return activated ? \"hass:radiobox-blank\" : \"hass:checkbox-marked-circle\";\n }\n};\n","/** Return an icon representing a cover state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { domainIcon } from \"./domain_icons\";\n\nexport const coverIcon = (state: HassEntity): string => {\n const open = state.state !== \"closed\";\n switch (state.attributes.device_class) {\n case \"garage\":\n return open ? \"hass:garage-open\" : \"hass:garage\";\n case \"door\":\n return open ? \"hass:door-open\" : \"hass:door-closed\";\n case \"shutter\":\n return open ? \"hass:window-shutter-open\" : \"hass:window-shutter\";\n case \"blind\":\n return open ? \"hass:blinds-open\" : \"hass:blinds\";\n case \"window\":\n return open ? \"hass:window-open\" : \"hass:window-closed\";\n default:\n return domainIcon(\"cover\", state.state);\n }\n};\n","/** Return an icon representing an input datetime state. */\nimport { domainIcon } from \"./domain_icons\";\nimport { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const inputDateTimeIcon = (state: HassEntity): string => {\n if (!state.attributes.has_date) {\n return \"hass:clock\";\n }\n if (!state.attributes.has_time) {\n return \"hass:calendar\";\n }\n return domainIcon(\"input_datetime\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { durationToSeconds } from \"../datetime/duration_to_seconds\";\n\nexport function timerTimeRemaining(stateObj: HassEntity) {\n let timeRemaining = durationToSeconds(stateObj.attributes.remaining);\n\n if (stateObj.state === \"active\") {\n const now = new Date().getTime();\n const madeActive = new Date(stateObj.last_changed).getTime();\n timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);\n }\n\n return timeRemaining;\n}\n","/**\n * Apply a theme to an element by setting the CSS variables on it.\n *\n * element: Element to apply theme on.\n * themes: HASS Theme information\n * localTheme: selected theme.\n * updateMeta: boolean if we should update the theme-color meta element.\n */\nexport const applyThemesOnElement = (\n element,\n themes,\n localTheme,\n updateMeta = false\n) => {\n if (!element._themes) {\n element._themes = {};\n }\n let themeName = themes.default_theme;\n if (localTheme === \"default\" || (localTheme && themes.themes[localTheme])) {\n themeName = localTheme;\n }\n const styles = { ...element._themes };\n if (themeName !== \"default\") {\n const theme = themes.themes[themeName];\n Object.keys(theme).forEach((key) => {\n const prefixedKey = \"--\" + key;\n element._themes[prefixedKey] = \"\";\n styles[prefixedKey] = theme[key];\n });\n }\n if (element.updateStyles) {\n element.updateStyles(styles);\n } else if ((window as any).ShadyCSS) {\n // implement updateStyles() method of Polemer elements\n (window as any).ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ (element), styles);\n }\n\n if (!updateMeta) {\n return;\n }\n\n const meta = document.querySelector(\"meta[name=theme-color]\");\n if (meta) {\n if (!meta.hasAttribute(\"default-content\")) {\n meta.setAttribute(\"default-content\", meta.getAttribute(\"content\")!);\n }\n const themeColor =\n styles[\"--primary-color\"] || meta.getAttribute(\"default-content\");\n meta.setAttribute(\"content\", themeColor);\n }\n}\n","import { LovelaceCard } from \"./types\";\n\nexport const computeCardSize = (card: LovelaceCard): number | Promise => {\n return typeof card.getCardSize === \"function\" ? card.getCardSize() : 4;\n};","export function computeEntity(entityId: string): string {\n return entityId.substr(entityId.indexOf(\".\") + 1);\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { formatDateTime } from \"./datetime/format_date_time\";\nimport { formatDate } from \"./datetime/format_date\";\nimport { formatTime } from \"./datetime/format_time\";\nimport { LocalizeFunc } from \"./translations/localize\";\nimport { computeStateDomain } from \"./compute-state-domain\";\n\nexport function computeStateDisplay(\n localize: LocalizeFunc,\n stateObj: HassEntity,\n language: string\n): string {\n if (stateObj.state === \"unknown\" || stateObj.state === \"unavailable\") {\n return localize(`state.default.${stateObj.state}`);\n }\n\n if (stateObj.attributes.unit_of_measurement) {\n return `${stateObj.state} ${stateObj.attributes.unit_of_measurement}`;\n }\n\n const domain = computeStateDomain(stateObj);\n\n if (domain === \"input_datetime\") {\n let date: Date;\n if (!stateObj.attributes.has_time) {\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day\n );\n return formatDate(date, language);\n }\n if (!stateObj.attributes.has_date) {\n const now = new Date();\n date = new Date(\n // Due to bugs.chromium.org/p/chromium/issues/detail?id=797548\n // don't use artificial 1970 year.\n now.getFullYear(),\n now.getMonth(),\n now.getDay(),\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatTime(date, language);\n }\n\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day,\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatDateTime(date, language);\n }\n\n return (\n // Return device class translation\n (stateObj.attributes.device_class &&\n localize(\n `component.${domain}.state.${stateObj.attributes.device_class}.${stateObj.state}`\n )) ||\n // Return default translation\n localize(`component.${domain}.state._.${stateObj.state}`) ||\n // We don't know! Return the raw state.\n stateObj.state\n );\n}\n","/**\r\n * Returns a function, that, as long as it continues to be invoked, will not be triggered. It will be called after it stops being called for `wait` ms.\r\n * This can be usefull for ResizeObservers for example.\r\n * @param func The function you want to debounce\r\n * @param wait Period to wait in ms\r\n * @param immediate Triggering on the leading edge instead of the trailing\r\n * @returns Debounced Function\r\n */\r\n// eslint-disable-next-line: ban-types\r\nexport const debounce = unknown>(\r\n func: T,\r\n wait: number,\r\n immediate = false\r\n): T => {\r\n let timeout;\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n return function (...args) {\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n const later = () => {\r\n timeout = null;\r\n if (!immediate) {\r\n func.apply(context, args);\r\n }\r\n };\r\n const callNow = immediate && !timeout;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(later, wait);\r\n if (callNow) {\r\n func.apply(context, args);\r\n }\r\n };\r\n};\r\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {\n const operator = filter.operator || \"==\";\n const value = filter.value || filter;\n const state = filter.attribute\n ? stateObj.attributes[filter.attribute]\n : stateObj.state;\n\n switch (operator) {\n case \"==\":\n return state === value;\n case \"<=\":\n return state <= value;\n case \"<\":\n return state < value;\n case \">=\":\n return state >= value;\n case \">\":\n return state > value;\n case \"!=\":\n return state !== value;\n case \"regex\": {\n return state.match(value);\n }\n default:\n return false;\n }\n};\n","/**\r\n * Formats a number based on the specified language with thousands separator(s) and decimal character for better legibility.\r\n * @param num The number to format\r\n * @param language The language to use when formatting the number\r\n */\r\nexport const formatNumber = (\r\n num: string | number,\r\n language: string,\r\n options?: Intl.NumberFormatOptions\r\n): string => {\r\n // Polyfill for Number.isNaN, which is more reliable than the global isNaN()\r\n Number.isNaN =\r\n Number.isNaN ||\r\n function isNaN(input) {\r\n return typeof input === \"number\" && isNaN(input);\r\n };\r\n\r\n if (!Number.isNaN(Number(num)) && Intl) {\r\n return new Intl.NumberFormat(\r\n language,\r\n getDefaultFormatOptions(num, options)\r\n ).format(Number(num));\r\n }\r\n return num.toString();\r\n};\r\n\r\n/**\r\n * Generates default options for Intl.NumberFormat\r\n * @param num The number to be formatted\r\n * @param options The Intl.NumberFormatOptions that should be included in the returned options\r\n */\r\nconst getDefaultFormatOptions = (\r\n num: string | number,\r\n options?: Intl.NumberFormatOptions\r\n): Intl.NumberFormatOptions => {\r\n const defaultOptions: Intl.NumberFormatOptions = options || {};\r\n\r\n if (typeof num !== \"string\") {\r\n return defaultOptions;\r\n }\r\n\r\n // Keep decimal trailing zeros if they are present in a string numeric value\r\n if (\r\n !options ||\r\n (!options.minimumFractionDigits && !options.maximumFractionDigits)\r\n ) {\r\n const digits = num.indexOf(\".\") > -1 ? num.split(\".\")[1].length : 0;\r\n defaultOptions.minimumFractionDigits = digits;\r\n defaultOptions.maximumFractionDigits = digits;\r\n }\r\n\r\n return defaultOptions;\r\n};\r\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { fireEvent } from \"./fire-event\";\nimport { forwardHaptic } from \"./haptic\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleClick = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n hold: boolean,\n dblClick: boolean\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (dblClick && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (hold && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (!hold && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\"\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n e => e.user === hass!.user!.id\n ))\n ) {\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (actionConfig.entity || config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: actionConfig.entity\n ? actionConfig.entity\n : config.entity\n ? config.entity\n : config.camera_image\n });\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"url\":\n actionConfig.url_path && window.open(actionConfig.url_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n const serviceData = { ...actionConfig.service_data };\n if (serviceData.entity_id === \"entity\") {\n serviceData.entity_id = config.entity;\n }\n hass.callService(domain, service, serviceData);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n }\n }\n};\n","import { ActionConfig } from \"./types\";\n\nexport function hasAction(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}\n","import { PropertyValues } from \"lit-element\";\n\nimport { HomeAssistant } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasConfigOrEntityChanged(\n element: any,\n changedProps: PropertyValues,\n forceUpdate: Boolean,\n): boolean {\n if (changedProps.has('config') || forceUpdate) {\n return true;\n }\n\n if (element.config!.entity) {\n const oldHass = changedProps.get('hass') as HomeAssistant | undefined;\n if (oldHass) {\n return (\n oldHass.states[element.config!.entity]\n !== element.hass!.states[element.config!.entity]\n );\n }\n return true;\n } else {\n return false;\n }\n}","import { ActionConfig } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasDoubleClick(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}","import { HomeAssistant } from \"./types\";\nimport { STATES_OFF } from \"./const\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntities = (\n hass: HomeAssistant,\n entityIds: string[],\n turnOn = true\n): void => {\n const domainsToCall = {};\n entityIds.forEach((entityId) => {\n if (STATES_OFF.includes(hass.states[entityId].state) === turnOn) {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = [\"cover\", \"lock\"].includes(stateDomain)\n ? stateDomain\n : \"homeassistant\";\n\n if (!(serviceDomain in domainsToCall)) {\n domainsToCall[serviceDomain] = [];\n }\n domainsToCall[serviceDomain].push(entityId);\n }\n });\n\n Object.keys(domainsToCall).forEach((domain) => {\n let service;\n switch (domain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n const entities = domainsToCall[domain];\n hass.callService(domain, service, { entity_id: entities });\n });\n};\n","export const getLovelace = () => {\n let root: any = document.querySelector('home-assistant');\n root = root && root.shadowRoot;\n root = root && root.querySelector('home-assistant-main');\n root = root && root.shadowRoot;\n root = root && root.querySelector('app-drawer-layout partial-panel-resolver');\n root = root && root.shadowRoot || root;\n root = root && root.querySelector('ha-panel-lovelace');\n root = root && root.shadowRoot;\n root = root && root.querySelector('hui-root');\n if (root) {\n const ll = root.lovelace;\n ll.current_view = root.___curView;\n return ll;\n }\n return null;\n}\n"],"names":["durationToSeconds","duration","parts","split","map","Number","formatDate","Date","toLocaleDateString","e","name","toLocaleDateStringSupportsOptions","dateObj","locales","year","month","day","fecha","format","formatDateTime","toLocaleString","toLocaleStringSupportsOptions","hour","minute","formatTime","toLocaleTimeString","toLocaleTimeStringSupportsOptions","tests","langKey","leftPad","num","computeDomain","entityId","substr","indexOf","computeRTL","hass","lang","language","translationMetadata","translations","isRTL","computeStateDomain","stateObj","entity_id","DEFAULT_DOMAIN_ICON","STATES_OFF","DOMAINS_TOGGLE","Set","fireEvent","node","type","detail","options","event","Event","bubbles","undefined","cancelable","Boolean","composed","dispatchEvent","SPECIAL_TYPES","DOMAIN_TO_ELEMENT_TYPE","alert","automation","climate","cover","fan","group","input_boolean","input_number","input_select","input_text","light","lock","media_player","remote","scene","script","sensor","timer","switch","vacuum","water_heater","input_datetime","fixedIcons","calendar","camera","configurator","conversation","device_tracker","history_graph","homeassistant","homekit","image_processing","mailbox","notify","person","plant","proximity","simple_alarm","sun","updater","weblink","domainIcon","domain","state","console","warn","forwardHaptic","hapticType","window","navigate","_node","path","replace","history","replaceState","pushState","turnOnOffEntity","turnOn","service","stateDomain","serviceDomain","callService","toggleEntity","includes","states","handleActionConfig","config","actionConfig","action","confirmation","exemptions","some","user","id","confirm","text","entity","camera_image","navigation_path","url_path","open","service_data","fixedDeviceClassIcons","humidity","illuminance","temperature","pressure","power","signal_strength","domainIcons","binary_sensor","activated","attributes","device_class","dclass","battery","isNaN","batteryRound","Math","round","unit","unit_of_measurement","has_date","has_time","localize","timeDesc","delta","compareTime","getTime","tense","abs","let","i","length","floor","includeTense","d","h","m","s","timeRemaining","remaining","now","madeActive","last_changed","max","element","themes","localTheme","updateMeta","_themes","themeName","default_theme","styles","Object","theme","keys","forEach","key","prefixedKey","updateStyles","ShadyCSS","styleSubtree","meta","document","querySelector","hasAttribute","setAttribute","getAttribute","themeColor","card","getCardSize","date","getFullYear","getMonth","getDay","cardConfig","isRow","_createError","error","_createThing","tag","createElement","setConfig","err","message","startsWith","has","customElements","get","style","display","setTimeout","whenDefined","then","clearTimeout","func","wait","immediate","timeout","context","this","callNow","apply","args","filter","value","attribute","operator","match","input","Intl","NumberFormat","defaultOptions","minimumFractionDigits","maximumFractionDigits","digits","getDefaultFormatOptions","toString","double_tap_action","hold_action","tap_action","hold","dblClick","haptic","serviceData","changedProps","forceUpdate","oldHass","entityIds","domainsToCall","push","root","shadowRoot","ll","lovelace","current_view","___curView","icon"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.m.js b/dist/index.m.js index b8cb74b..dc8d616 100644 --- a/dist/index.m.js +++ b/dist/index.m.js @@ -1,2 +1,2 @@ -import e from"fecha";function t(e){var t=e.split(":").map(Number);return 3600*t[0]+60*t[1]+t[2]}var a=function(){try{(new Date).toLocaleDateString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleDateString(t,{year:"numeric",month:"long",day:"numeric"})}:function(t){return e.format(t,"mediumDate")},r=function(){try{(new Date).toLocaleString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleString(t,{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}:function(t){return e.format(t,"haDateTime")},n=function(){try{(new Date).toLocaleTimeString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleTimeString(t,{hour:"numeric",minute:"2-digit"})}:function(t){return e.format(t,"shortTime")},s=[60,60,24,7],i=["second","minute","hour","day"];function o(e,t,a){void 0===a&&(a={});var r,n=((a.compareTime||new Date).getTime()-e.getTime())/1e3,o=n>=0?"past":"future";n=Math.abs(n);for(var c=0;c0?t+":"+c(a)+":"+c(r):a>0?a+":"+c(r):r>0?""+r:null}function l(e){var a=t(e.attributes.remaining);if("active"===e.state){var r=(new Date).getTime(),n=new Date(e.last_changed).getTime();a=Math.max(a-(r-n)/1e3,0)}return a}var h=function(e,t,a,r){void 0===r&&(r=!1),e._themes||(e._themes={});var n=t.default_theme;("default"===a||a&&t.themes[a])&&(n=a);var s=Object.assign({},e._themes);if("default"!==n){var i=t.themes[n];Object.keys(i).forEach(function(t){var a="--"+t;e._themes[a]="",s[a]=i[t]})}if(e.updateStyles?e.updateStyles(s):window.ShadyCSS&&window.ShadyCSS.styleSubtree(e,s),r){var o=document.querySelector("meta[name=theme-color]");if(o){o.hasAttribute("default-content")||o.setAttribute("default-content",o.getAttribute("content"));var c=s["--primary-color"]||o.getAttribute("default-content");o.setAttribute("content",c)}}},m=function(e){return"function"==typeof e.getCardSize?e.getCardSize():4};function f(e){return e.substr(0,e.indexOf("."))}function d(e){return e.substr(e.indexOf(".")+1)}function p(e){var t=e.language||"en";return e.translationMetadata.translations[t]&&e.translationMetadata.translations[t].isRTL||!1}function g(e){return p(e)?"rtl":"ltr"}function v(e){return f(e.entity_id)}function b(e,t,s){if("unknown"===t.state||"unavailable"===t.state)return e("state.default."+t.state);if(t.attributes.unit_of_measurement)return t.state+" "+t.attributes.unit_of_measurement;var i=v(t);if("input_datetime"===i){var o;if(!t.attributes.has_time)return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day),a(o,s);if(!t.attributes.has_date){var c=new Date;return o=new Date(c.getFullYear(),c.getMonth(),c.getDay(),t.attributes.hour,t.attributes.minute),n(o,s)}return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day,t.attributes.hour,t.attributes.minute),r(o,s)}return t.attributes.device_class&&e("component."+i+".state."+t.attributes.device_class+"."+t.state)||e("component."+i+".state._."+t.state)||t.state}var _="hass:bookmark",y="lovelace",w=["climate","cover","configurator","input_select","input_number","input_text","lock","media_player","scene","script","timer","vacuum","water_heater","weblink"],k=["alarm_control_panel","automation","camera","climate","configurator","cover","fan","group","history_graph","input_datetime","light","lock","media_player","script","sun","updater","vacuum","water_heater","weather"],x=["input_number","input_select","input_text","scene","weblink"],S=["camera","configurator","history_graph","scene"],D=["closed","locked","off"],N=new Set(["fan","input_boolean","light","switch","group","automation"]),T="°C",E="°F",M="group.default_view",q=function(e,t,a,r){r=r||{},a=null==a?{}:a;var n=new Event(t,{bubbles:void 0===r.bubbles||r.bubbles,cancelable:Boolean(r.cancelable),composed:void 0===r.composed||r.composed});return n.detail=a,e.dispatchEvent(n),n},C=new Set(["call-service","divider","section","weblink","cast","select"]),F={alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"},R=function(e,t){void 0===t&&(t=!1);var a=function(e,t){return r("hui-error-card",{type:"error",error:e,config:t})},r=function(e,t){var r=window.document.createElement(e);try{r.setConfig(t)}catch(r){return console.error(e,r),a(r.message,t)}return r};if(!e||"object"!=typeof e||!t&&!e.type)return a("No type defined",e);var n=e.type;if(n&&n.startsWith("custom:"))n=n.substr("custom:".length);else if(t)if(C.has(n))n="hui-"+n+"-row";else{if(!e.entity)return a("Invalid config given.",e);var s=e.entity.split(".",1)[0];n="hui-"+(F[s]||"text")+"-entity-row"}else n="hui-"+n+"-card";if(customElements.get(n))return r(n,e);var i=a("Custom element doesn't exist: "+e.type+".",e);i.style.display="None";var o=setTimeout(function(){i.style.display=""},2e3);return customElements.whenDefined(e.type).then(function(){clearTimeout(o),q(i,"ll-rebuild",{},i)}),i},A=function(e,t,a){var r;return void 0===a&&(a=!1),function(){for(var n=[],s=arguments.length;s--;)n[s]=arguments[s];var i=this,o=a&&!r;clearTimeout(r),r=setTimeout(function(){r=null,a||e.apply(i,n)},t),o&&e.apply(i,n)}},L={alert:"hass:alert",automation:"hass:playlist-play",calendar:"hass:calendar",camera:"hass:video",climate:"hass:thermostat",configurator:"hass:settings",conversation:"hass:text-to-speech",device_tracker:"hass:account",fan:"hass:fan",group:"hass:google-circles-communities",history_graph:"hass:chart-line",homeassistant:"hass:home-assistant",homekit:"hass:home-automation",image_processing:"hass:image-filter-frames",input_boolean:"hass:drawing",input_datetime:"hass:calendar-clock",input_number:"hass:ray-vertex",input_select:"hass:format-list-bulleted",input_text:"hass:textbox",light:"hass:lightbulb",mailbox:"hass:mailbox",notify:"hass:comment-alert",person:"hass:account",plant:"hass:flower",proximity:"hass:apple-safari",remote:"hass:remote",scene:"hass:google-pages",script:"hass:file-document",sensor:"hass:eye",simple_alarm:"hass:bell",sun:"hass:white-balance-sunny",switch:"hass:flash",timer:"hass:timer",updater:"hass:cloud-upload",vacuum:"hass:robot-vacuum",water_heater:"hass:thermometer",weblink:"hass:open-in-new"};function O(e,t){if(e in L)return L[e];switch(e){case"alarm_control_panel":switch(t){case"armed_home":return"hass:bell-plus";case"armed_night":return"hass:bell-sleep";case"disarmed":return"hass:bell-outline";case"triggered":return"hass:bell-ring";default:return"hass:bell"}case"binary_sensor":return t&&"off"===t?"hass:radiobox-blank":"hass:checkbox-marked-circle";case"cover":return"closed"===t?"hass:window-closed":"hass:window-open";case"lock":return t&&"unlocked"===t?"hass:lock-open":"hass:lock";case"media_player":return t&&"off"!==t&&"idle"!==t?"hass:cast-connected":"hass:cast";case"zwave":switch(t){case"dead":return"hass:emoticon-dead";case"sleeping":return"hass:sleep";case"initializing":return"hass:timer-sand";default:return"hass:z-wave"}default:return console.warn("Unable to find icon for domain "+e+" ("+t+")"),_}}var j=function(e,t){var a=t.value||t,r=t.attribute?e.attributes[t.attribute]:e.state;switch(t.operator||"=="){case"==":return r===a;case"<=":return r<=a;case"<":return r=":return r>=a;case">":return r>a;case"!=":return r!==a;case"regex":return r.match(a);default:return!1}},z=function(e,t,a){return Number.isNaN=Number.isNaN||function e(t){return"number"==typeof t&&e(t)},!Number.isNaN(Number(e))&&Intl?new Intl.NumberFormat(t,I(e,a)).format(Number(e)):e.toString()},I=function(e,t){var a=t||{};if("string"!=typeof e)return a;if(!t||!t.minimumFractionDigits&&!t.maximumFractionDigits){var r=e.indexOf(".")>-1?e.split(".")[1].length:0;a.minimumFractionDigits=r,a.maximumFractionDigits=r}return a},B=function(e){q(window,"haptic",e)},U=function(e,t,a){void 0===a&&(a=!1),a?history.replaceState(null,"",t):history.pushState(null,"",t),q(window,"location-changed",{replace:a})},V=function(e,t,a){void 0===a&&(a=!0);var r,n=f(t),s="group"===n?"homeassistant":n;switch(n){case"lock":r=a?"unlock":"lock";break;case"cover":r=a?"open_cover":"close_cover";break;default:r=a?"turn_on":"turn_off"}return e.callService(s,r,{entity_id:t})},W=function(e,t){var a=D.includes(e.states[t].state);return V(e,t,a)},Y=function(e,t,a,r){if(r||(r={action:"more-info"}),!r.confirmation||r.confirmation.exemptions&&r.confirmation.exemptions.some(function(e){return e.user===t.user.id})||(B("warning"),confirm(r.confirmation.text||"Are you sure you want to "+r.action+"?")))switch(r.action){case"more-info":(a.entity||a.camera_image)&&q(e,"hass-more-info",{entityId:a.entity?a.entity:a.camera_image});break;case"navigate":r.navigation_path&&U(0,r.navigation_path);break;case"url":r.url_path&&window.open(r.url_path);break;case"toggle":a.entity&&(W(t,a.entity),B("success"));break;case"call-service":if(!r.service)return void B("failure");var n=r.service.split(".",2);t.callService(n[0],n[1],r.service_data),B("success");break;case"fire-dom-event":q(e,"ll-custom",r)}},G=function(e,t,a,r){var n;"double_tap"===r&&a.double_tap_action?n=a.double_tap_action:"hold"===r&&a.hold_action?n=a.hold_action:"tap"===r&&a.tap_action&&(n=a.tap_action),Y(e,t,a,n)},H=function(e,t,a,r,n){var s;if(n&&a.double_tap_action?s=a.double_tap_action:r&&a.hold_action?s=a.hold_action:!r&&a.tap_action&&(s=a.tap_action),s||(s={action:"more-info"}),!s.confirmation||s.confirmation.exemptions&&s.confirmation.exemptions.some(function(e){return e.user===t.user.id})||confirm(s.confirmation.text||"Are you sure you want to "+s.action+"?"))switch(s.action){case"more-info":(s.entity||a.entity||a.camera_image)&&(q(e,"hass-more-info",{entityId:s.entity?s.entity:a.entity?a.entity:a.camera_image}),s.haptic&&B(s.haptic));break;case"navigate":s.navigation_path&&(U(0,s.navigation_path),s.haptic&&B(s.haptic));break;case"url":s.url_path&&window.open(s.url_path),s.haptic&&B(s.haptic);break;case"toggle":a.entity&&(W(t,a.entity),s.haptic&&B(s.haptic));break;case"call-service":if(!s.service)return;var i=s.service.split(".",2),o=i[0],c=i[1],u=Object.assign({},s.service_data);"entity"===u.entity_id&&(u.entity_id=a.entity),t.callService(o,c,u),s.haptic&&B(s.haptic)}};function J(e){return void 0!==e&&"none"!==e.action}function K(e,t,a){if(t.has("config")||a)return!0;if(e.config.entity){var r=t.get("hass");return!r||r.states[e.config.entity]!==e.hass.states[e.config.entity]}return!1}function P(e){return void 0!==e&&"none"!==e.action}var Q=function(e,t,a){void 0===a&&(a=!0);var r={};t.forEach(function(t){if(D.includes(e.states[t].state)===a){var n=f(t),s=["cover","lock"].includes(n)?n:"homeassistant";s in r||(r[s]=[]),r[s].push(t)}}),Object.keys(r).forEach(function(t){var n;switch(t){case"lock":n=a?"unlock":"lock";break;case"cover":n=a?"open_cover":"close_cover";break;default:n=a?"turn_on":"turn_off"}e.callService(t,n,{entity_id:r[t]})})},X=function(){var e=document.querySelector("home-assistant");if(e=(e=(e=(e=(e=(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root")){var t=e.lovelace;return t.current_view=e.___curView,t}return null},Z={humidity:"hass:water-percent",illuminance:"hass:brightness-5",temperature:"hass:thermometer",pressure:"hass:gauge",power:"hass:flash",signal_strength:"hass:wifi"},$={binary_sensor:function(e){var t=e.state&&"off"===e.state;switch(e.attributes.device_class){case"battery":return t?"hass:battery":"hass:battery-outline";case"cold":return t?"hass:thermometer":"hass:snowflake";case"connectivity":return t?"hass:server-network-off":"hass:server-network";case"door":return t?"hass:door-closed":"hass:door-open";case"garage_door":return t?"hass:garage":"hass:garage-open";case"gas":case"power":case"problem":case"safety":case"smoke":return t?"hass:shield-check":"hass:alert";case"heat":return t?"hass:thermometer":"hass:fire";case"light":return t?"hass:brightness-5":"hass:brightness-7";case"lock":return t?"hass:lock":"hass:lock-open";case"moisture":return t?"hass:water-off":"hass:water";case"motion":return t?"hass:walk":"hass:run";case"occupancy":return t?"hass:home-outline":"hass:home";case"opening":return t?"hass:square":"hass:square-outline";case"plug":return t?"hass:power-plug-off":"hass:power-plug";case"presence":return t?"hass:home-outline":"hass:home";case"sound":return t?"hass:music-note-off":"hass:music-note";case"vibration":return t?"hass:crop-portrait":"hass:vibrate";case"window":return t?"hass:window-closed":"hass:window-open";default:return t?"hass:radiobox-blank":"hass:checkbox-marked-circle"}},cover:function(e){var t="closed"!==e.state;switch(e.attributes.device_class){case"garage":return t?"hass:garage-open":"hass:garage";case"door":return t?"hass:door-open":"hass:door-closed";case"shutter":return t?"hass:window-shutter-open":"hass:window-shutter";case"blind":return t?"hass:blinds-open":"hass:blinds";case"window":return t?"hass:window-open":"hass:window-closed";default:return O("cover",e.state)}},sensor:function(e){var t=e.attributes.device_class;if(t&&t in Z)return Z[t];if("battery"===t){var a=Number(e.state);if(isNaN(a))return"hass:battery-unknown";var r=10*Math.round(a/10);return r>=100?"hass:battery":r<=0?"hass:battery-alert":"hass:battery-"+r}var n=e.attributes.unit_of_measurement;return"°C"===n||"°F"===n?"hass:thermometer":O("sensor")},input_datetime:function(e){return e.attributes.has_date?e.attributes.has_time?O("input_datetime"):"hass:calendar":"hass:clock"}},ee=function(e){if(!e)return _;if(e.attributes.icon)return e.attributes.icon;var t=f(e.entity_id);return t in $?$[t](e):O(t,e.state)};export{t as durationToSeconds,a as formatDate,r as formatDateTime,n as formatTime,o as relativeTime,u as secondsToDuration,l as timerTimeRemaining,h as applyThemesOnElement,m as computeCardSize,f as computeDomain,d as computeEntity,p as computeRTL,g as computeRTLDirection,b as computeStateDisplay,v as computeStateDomain,_ as DEFAULT_DOMAIN_ICON,y as DEFAULT_PANEL,w as DOMAINS_WITH_CARD,k as DOMAINS_WITH_MORE_INFO,x as DOMAINS_HIDE_MORE_INFO,S as DOMAINS_MORE_INFO_NO_HISTORY,D as STATES_OFF,N as DOMAINS_TOGGLE,T as UNIT_C,E as UNIT_F,M as DEFAULT_VIEW_ENTITY_ID,R as createThing,A as debounce,L as fixedIcons,O as domainIcon,j as evaluateFilter,q as fireEvent,z as formatNumber,Y as handleActionConfig,G as handleAction,H as handleClick,B as forwardHaptic,J as hasAction,K as hasConfigOrEntityChanged,P as hasDoubleClick,U as navigate,W as toggleEntity,Q as turnOnOffEntities,V as turnOnOffEntity,X as getLovelace,ee as stateIcon}; +import e from"fecha";function t(e){var t=e.split(":").map(Number);return 3600*t[0]+60*t[1]+t[2]}var a=function(){try{(new Date).toLocaleDateString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleDateString(t,{year:"numeric",month:"long",day:"numeric"})}:function(t){return e.format(t,"mediumDate")},r=function(){try{(new Date).toLocaleString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleString(t,{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}:function(t){return e.format(t,"haDateTime")},n=function(){try{(new Date).toLocaleTimeString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleTimeString(t,{hour:"numeric",minute:"2-digit"})}:function(t){return e.format(t,"shortTime")},s=[60,60,24,7],i=["second","minute","hour","day"];function o(e,t,a){void 0===a&&(a={});var r,n=((a.compareTime||new Date).getTime()-e.getTime())/1e3,o=n>=0?"past":"future";n=Math.abs(n);for(var c=0;c0?t+":"+c(a)+":"+c(r):a>0?a+":"+c(r):r>0?""+r:null}function l(e){var a=t(e.attributes.remaining);if("active"===e.state){var r=(new Date).getTime(),n=new Date(e.last_changed).getTime();a=Math.max(a-(r-n)/1e3,0)}return a}var h=function(e,t,a,r){void 0===r&&(r=!1),e._themes||(e._themes={});var n=t.default_theme;("default"===a||a&&t.themes[a])&&(n=a);var s=Object.assign({},e._themes);if("default"!==n){var i=t.themes[n];Object.keys(i).forEach(function(t){var a="--"+t;e._themes[a]="",s[a]=i[t]})}if(e.updateStyles?e.updateStyles(s):window.ShadyCSS&&window.ShadyCSS.styleSubtree(e,s),r){var o=document.querySelector("meta[name=theme-color]");if(o){o.hasAttribute("default-content")||o.setAttribute("default-content",o.getAttribute("content"));var c=s["--primary-color"]||o.getAttribute("default-content");o.setAttribute("content",c)}}},m=function(e){return"function"==typeof e.getCardSize?e.getCardSize():4};function f(e){return e.substr(0,e.indexOf("."))}function d(e){return e.substr(e.indexOf(".")+1)}function p(e){var t=e.language||"en";return e.translationMetadata.translations[t]&&e.translationMetadata.translations[t].isRTL||!1}function g(e){return p(e)?"rtl":"ltr"}function v(e){return f(e.entity_id)}function b(e,t,s){if("unknown"===t.state||"unavailable"===t.state)return e("state.default."+t.state);if(t.attributes.unit_of_measurement)return t.state+" "+t.attributes.unit_of_measurement;var i=v(t);if("input_datetime"===i){var o;if(!t.attributes.has_time)return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day),a(o,s);if(!t.attributes.has_date){var c=new Date;return o=new Date(c.getFullYear(),c.getMonth(),c.getDay(),t.attributes.hour,t.attributes.minute),n(o,s)}return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day,t.attributes.hour,t.attributes.minute),r(o,s)}return t.attributes.device_class&&e("component."+i+".state."+t.attributes.device_class+"."+t.state)||e("component."+i+".state._."+t.state)||t.state}var _="hass:bookmark",y="lovelace",w=["climate","cover","configurator","input_select","input_number","input_text","lock","media_player","scene","script","timer","vacuum","water_heater","weblink"],k=["alarm_control_panel","automation","camera","climate","configurator","cover","fan","group","history_graph","input_datetime","light","lock","media_player","script","sun","updater","vacuum","water_heater","weather"],x=["input_number","input_select","input_text","scene","weblink"],S=["camera","configurator","history_graph","scene"],D=["closed","locked","off"],N=new Set(["fan","input_boolean","light","switch","group","automation"]),T="°C",E="°F",M="group.default_view",q=function(e,t,a,r){r=r||{},a=null==a?{}:a;var n=new Event(t,{bubbles:void 0===r.bubbles||r.bubbles,cancelable:Boolean(r.cancelable),composed:void 0===r.composed||r.composed});return n.detail=a,e.dispatchEvent(n),n},C=new Set(["call-service","divider","section","weblink","cast","select"]),F={alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"},R=function(e,t){void 0===t&&(t=!1);var a=function(e,t){return r("hui-error-card",{type:"error",error:e,config:t})},r=function(e,t){var r=window.document.createElement(e);try{r.setConfig(t)}catch(r){return console.error(e,r),a(r.message,t)}return r};if(!e||"object"!=typeof e||!t&&!e.type)return a("No type defined",e);var n=e.type;if(n&&n.startsWith("custom:"))n=n.substr("custom:".length);else if(t)if(C.has(n))n="hui-"+n+"-row";else{if(!e.entity)return a("Invalid config given.",e);var s=e.entity.split(".",1)[0];n="hui-"+(F[s]||"text")+"-entity-row"}else n="hui-"+n+"-card";if(customElements.get(n))return r(n,e);var i=a("Custom element doesn't exist: "+e.type+".",e);i.style.display="None";var o=setTimeout(function(){i.style.display=""},2e3);return customElements.whenDefined(e.type).then(function(){clearTimeout(o),q(i,"ll-rebuild",{},i)}),i},A=function(e,t,a){var r;return void 0===a&&(a=!1),function(){for(var n=[],s=arguments.length;s--;)n[s]=arguments[s];var i=this,o=a&&!r;clearTimeout(r),r=setTimeout(function(){r=null,a||e.apply(i,n)},t),o&&e.apply(i,n)}},L={alert:"hass:alert",automation:"hass:playlist-play",calendar:"hass:calendar",camera:"hass:video",climate:"hass:thermostat",configurator:"hass:settings",conversation:"hass:text-to-speech",device_tracker:"hass:account",fan:"hass:fan",group:"hass:google-circles-communities",history_graph:"hass:chart-line",homeassistant:"hass:home-assistant",homekit:"hass:home-automation",image_processing:"hass:image-filter-frames",input_boolean:"hass:drawing",input_datetime:"hass:calendar-clock",input_number:"hass:ray-vertex",input_select:"hass:format-list-bulleted",input_text:"hass:textbox",light:"hass:lightbulb",mailbox:"hass:mailbox",notify:"hass:comment-alert",person:"hass:account",plant:"hass:flower",proximity:"hass:apple-safari",remote:"hass:remote",scene:"hass:google-pages",script:"hass:file-document",sensor:"hass:eye",simple_alarm:"hass:bell",sun:"hass:white-balance-sunny",switch:"hass:flash",timer:"hass:timer",updater:"hass:cloud-upload",vacuum:"hass:robot-vacuum",water_heater:"hass:thermometer",weblink:"hass:open-in-new"};function O(e,t){if(e in L)return L[e];switch(e){case"alarm_control_panel":switch(t){case"armed_home":return"hass:bell-plus";case"armed_night":return"hass:bell-sleep";case"disarmed":return"hass:bell-outline";case"triggered":return"hass:bell-ring";default:return"hass:bell"}case"binary_sensor":return t&&"off"===t?"hass:radiobox-blank":"hass:checkbox-marked-circle";case"cover":return"closed"===t?"hass:window-closed":"hass:window-open";case"lock":return t&&"unlocked"===t?"hass:lock-open":"hass:lock";case"media_player":return t&&"off"!==t&&"idle"!==t?"hass:cast-connected":"hass:cast";case"zwave":switch(t){case"dead":return"hass:emoticon-dead";case"sleeping":return"hass:sleep";case"initializing":return"hass:timer-sand";default:return"hass:z-wave"}default:return console.warn("Unable to find icon for domain "+e+" ("+t+")"),_}}var j=function(e,t){var a=t.value||t,r=t.attribute?e.attributes[t.attribute]:e.state;switch(t.operator||"=="){case"==":return r===a;case"<=":return r<=a;case"<":return r=":return r>=a;case">":return r>a;case"!=":return r!==a;case"regex":return r.match(a);default:return!1}},z=function(e,t,a){return Number.isNaN=Number.isNaN||function e(t){return"number"==typeof t&&e(t)},!Number.isNaN(Number(e))&&Intl?new Intl.NumberFormat(t,I(e,a)).format(Number(e)):e.toString()},I=function(e,t){var a=t||{};if("string"!=typeof e)return a;if(!t||!t.minimumFractionDigits&&!t.maximumFractionDigits){var r=e.indexOf(".")>-1?e.split(".")[1].length:0;a.minimumFractionDigits=r,a.maximumFractionDigits=r}return a},B=function(e){q(window,"haptic",e)},U=function(e,t,a){void 0===a&&(a=!1),a?history.replaceState(null,"",t):history.pushState(null,"",t),q(window,"location-changed",{replace:a})},V=function(e,t,a){void 0===a&&(a=!0);var r,n=f(t),s="group"===n?"homeassistant":n;switch(n){case"lock":r=a?"unlock":"lock";break;case"cover":r=a?"open_cover":"close_cover";break;default:r=a?"turn_on":"turn_off"}return e.callService(s,r,{entity_id:t})},W=function(e,t){var a=D.includes(e.states[t].state);return V(e,t,a)},Y=function(e,t,a,r){if(r||(r={action:"more-info"}),!r.confirmation||r.confirmation.exemptions&&r.confirmation.exemptions.some(function(e){return e.user===t.user.id})||(B("warning"),confirm(r.confirmation.text||"Are you sure you want to "+r.action+"?")))switch(r.action){case"more-info":(a.entity||a.camera_image)&&q(e,"hass-more-info",{entityId:a.entity?a.entity:a.camera_image});break;case"navigate":r.navigation_path&&U(0,r.navigation_path);break;case"url":r.url_path&&window.open(r.url_path);break;case"toggle":a.entity&&(W(t,a.entity),B("success"));break;case"call-service":if(!r.service)return void B("failure");var n=r.service.split(".",2);t.callService(n[0],n[1],r.service_data),B("success");break;case"fire-dom-event":q(e,"ll-custom",r)}},G=function(e,t,a,r){var n;"double_tap"===r&&a.double_tap_action?n=a.double_tap_action:"hold"===r&&a.hold_action?n=a.hold_action:"tap"===r&&a.tap_action&&(n=a.tap_action),Y(e,t,a,n)},H=function(e,t,a,r,n){var s;if(n&&a.double_tap_action?s=a.double_tap_action:r&&a.hold_action?s=a.hold_action:!r&&a.tap_action&&(s=a.tap_action),s||(s={action:"more-info"}),!s.confirmation||s.confirmation.exemptions&&s.confirmation.exemptions.some(function(e){return e.user===t.user.id})||confirm(s.confirmation.text||"Are you sure you want to "+s.action+"?"))switch(s.action){case"more-info":(s.entity||a.entity||a.camera_image)&&(q(e,"hass-more-info",{entityId:s.entity?s.entity:a.entity?a.entity:a.camera_image}),s.haptic&&B(s.haptic));break;case"navigate":s.navigation_path&&(U(0,s.navigation_path),s.haptic&&B(s.haptic));break;case"url":s.url_path&&window.open(s.url_path),s.haptic&&B(s.haptic);break;case"toggle":a.entity&&(W(t,a.entity),s.haptic&&B(s.haptic));break;case"call-service":if(!s.service)return;var i=s.service.split(".",2),o=i[0],c=i[1],u=Object.assign({},s.service_data);"entity"===u.entity_id&&(u.entity_id=a.entity),t.callService(o,c,u),s.haptic&&B(s.haptic);break;case"fire-dom-event":q(e,"ll-custom",s),s.haptic&&B(s.haptic)}};function J(e){return void 0!==e&&"none"!==e.action}function K(e,t,a){if(t.has("config")||a)return!0;if(e.config.entity){var r=t.get("hass");return!r||r.states[e.config.entity]!==e.hass.states[e.config.entity]}return!1}function P(e){return void 0!==e&&"none"!==e.action}var Q=function(e,t,a){void 0===a&&(a=!0);var r={};t.forEach(function(t){if(D.includes(e.states[t].state)===a){var n=f(t),s=["cover","lock"].includes(n)?n:"homeassistant";s in r||(r[s]=[]),r[s].push(t)}}),Object.keys(r).forEach(function(t){var n;switch(t){case"lock":n=a?"unlock":"lock";break;case"cover":n=a?"open_cover":"close_cover";break;default:n=a?"turn_on":"turn_off"}e.callService(t,n,{entity_id:r[t]})})},X=function(){var e=document.querySelector("home-assistant");if(e=(e=(e=(e=(e=(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root")){var t=e.lovelace;return t.current_view=e.___curView,t}return null},Z={humidity:"hass:water-percent",illuminance:"hass:brightness-5",temperature:"hass:thermometer",pressure:"hass:gauge",power:"hass:flash",signal_strength:"hass:wifi"},$={binary_sensor:function(e){var t=e.state&&"off"===e.state;switch(e.attributes.device_class){case"battery":return t?"hass:battery":"hass:battery-outline";case"cold":return t?"hass:thermometer":"hass:snowflake";case"connectivity":return t?"hass:server-network-off":"hass:server-network";case"door":return t?"hass:door-closed":"hass:door-open";case"garage_door":return t?"hass:garage":"hass:garage-open";case"gas":case"power":case"problem":case"safety":case"smoke":return t?"hass:shield-check":"hass:alert";case"heat":return t?"hass:thermometer":"hass:fire";case"light":return t?"hass:brightness-5":"hass:brightness-7";case"lock":return t?"hass:lock":"hass:lock-open";case"moisture":return t?"hass:water-off":"hass:water";case"motion":return t?"hass:walk":"hass:run";case"occupancy":return t?"hass:home-outline":"hass:home";case"opening":return t?"hass:square":"hass:square-outline";case"plug":return t?"hass:power-plug-off":"hass:power-plug";case"presence":return t?"hass:home-outline":"hass:home";case"sound":return t?"hass:music-note-off":"hass:music-note";case"vibration":return t?"hass:crop-portrait":"hass:vibrate";case"window":return t?"hass:window-closed":"hass:window-open";default:return t?"hass:radiobox-blank":"hass:checkbox-marked-circle"}},cover:function(e){var t="closed"!==e.state;switch(e.attributes.device_class){case"garage":return t?"hass:garage-open":"hass:garage";case"door":return t?"hass:door-open":"hass:door-closed";case"shutter":return t?"hass:window-shutter-open":"hass:window-shutter";case"blind":return t?"hass:blinds-open":"hass:blinds";case"window":return t?"hass:window-open":"hass:window-closed";default:return O("cover",e.state)}},sensor:function(e){var t=e.attributes.device_class;if(t&&t in Z)return Z[t];if("battery"===t){var a=Number(e.state);if(isNaN(a))return"hass:battery-unknown";var r=10*Math.round(a/10);return r>=100?"hass:battery":r<=0?"hass:battery-alert":"hass:battery-"+r}var n=e.attributes.unit_of_measurement;return"°C"===n||"°F"===n?"hass:thermometer":O("sensor")},input_datetime:function(e){return e.attributes.has_date?e.attributes.has_time?O("input_datetime"):"hass:calendar":"hass:clock"}},ee=function(e){if(!e)return _;if(e.attributes.icon)return e.attributes.icon;var t=f(e.entity_id);return t in $?$[t](e):O(t,e.state)};export{t as durationToSeconds,a as formatDate,r as formatDateTime,n as formatTime,o as relativeTime,u as secondsToDuration,l as timerTimeRemaining,h as applyThemesOnElement,m as computeCardSize,f as computeDomain,d as computeEntity,p as computeRTL,g as computeRTLDirection,b as computeStateDisplay,v as computeStateDomain,_ as DEFAULT_DOMAIN_ICON,y as DEFAULT_PANEL,w as DOMAINS_WITH_CARD,k as DOMAINS_WITH_MORE_INFO,x as DOMAINS_HIDE_MORE_INFO,S as DOMAINS_MORE_INFO_NO_HISTORY,D as STATES_OFF,N as DOMAINS_TOGGLE,T as UNIT_C,E as UNIT_F,M as DEFAULT_VIEW_ENTITY_ID,R as createThing,A as debounce,L as fixedIcons,O as domainIcon,j as evaluateFilter,q as fireEvent,z as formatNumber,Y as handleActionConfig,G as handleAction,H as handleClick,B as forwardHaptic,J as hasAction,K as hasConfigOrEntityChanged,P as hasDoubleClick,U as navigate,W as toggleEntity,Q as turnOnOffEntities,V as turnOnOffEntity,X as getLovelace,ee as stateIcon}; //# sourceMappingURL=index.m.js.map diff --git a/dist/index.m.js.map b/dist/index.m.js.map index 87adc4e..61284cd 100644 --- a/dist/index.m.js.map +++ b/dist/index.m.js.map @@ -1 +1 @@ -{"version":3,"file":"index.m.js","sources":["../src/datetime/duration_to_seconds.ts","../src/datetime/format_date.ts","../src/datetime/format_date_time.ts","../src/datetime/format_time.ts","../src/datetime/relative_time.ts","../src/datetime/seconds_to_duration.ts","../src/datetime/timer_time_remaining.ts","../src/apply_themes_on_element.ts","../src/compute-card-size.ts","../src/compute-domain.ts","../src/compute-entity.ts","../src/compute-rtl.ts","../src/compute-state-domain.ts","../src/compute-state-display.ts","../src/const.ts","../src/fire-event.ts","../src/create-thing.ts","../src/debounce.ts","../src/domain_icons.ts","../src/evaluate-filter.ts","../src/format-number.ts","../src/haptic.ts","../src/navigate.ts","../src/turn-on-off-entity.ts","../src/toggle-entity.ts","../src/handle-action.ts","../src/handle-click.ts","../src/has-action.ts","../src/has-changed.ts","../src/has-double-click.ts","../src/turn-on-off-entities.ts","../src/get-lovelace.ts","../src/sensor_icon.ts","../src/state_icon.ts","../src/binary_sensor_icon.ts","../src/cover_icon.ts","../src/input_datetime_icon.ts"],"sourcesContent":["export function durationToSeconds(duration: string): number {\n const parts = duration.split(\":\").map(Number);\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n}\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleDateStringSupportsOptions() {\n try {\n new Date().toLocaleDateString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDate = (toLocaleDateStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleDateString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"mediumDate\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleStringSupportsOptions() {\n try {\n new Date().toLocaleString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDateTime = (toLocaleStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"haDateTime\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleTimeStringSupportsOptions() {\n try {\n new Date().toLocaleTimeString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatTime = (toLocaleTimeStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleTimeString(locales, {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"shortTime\"));\n","import { LocalizeFunc } from \"../translations/localize\";\n\n/**\n * Calculate a string representing a date object as relative time from now.\n *\n * Example output: 5 minutes ago, in 3 days.\n */\nconst tests = [60, 60, 24, 7];\nconst langKey = [\"second\", \"minute\", \"hour\", \"day\"];\n\nexport function relativeTime(\n dateObj: Date,\n localize: LocalizeFunc,\n options: {\n compareTime?: Date;\n includeTense?: boolean;\n } = {}\n): string {\n const compareTime = options.compareTime || new Date();\n let delta = (compareTime.getTime() - dateObj.getTime()) / 1000;\n const tense = delta >= 0 ? \"past\" : \"future\";\n delta = Math.abs(delta);\n\n let timeDesc;\n\n for (let i = 0; i < tests.length; i++) {\n if (delta < tests[i]) {\n delta = Math.floor(delta);\n timeDesc = localize(\n `ui.components.relative_time.duration.${langKey[i]}`,\n \"count\",\n delta\n );\n break;\n }\n\n delta /= tests[i];\n }\n\n if (timeDesc === undefined) {\n delta = Math.floor(delta);\n timeDesc = localize(\n \"ui.components.relative_time.duration.week\",\n \"count\",\n delta\n );\n }\n\n return options.includeTense === false\n ? timeDesc\n : localize(`ui.components.relative_time.${tense}`, \"time\", timeDesc);\n}\n","const leftPad = (num: number) => (num < 10 ? `0${num}` : num);\n\nexport function secondsToDuration(d: number) {\n const h = Math.floor(d / 3600);\n const m = Math.floor((d % 3600) / 60);\n const s = Math.floor((d % 3600) % 60);\n\n if (h > 0) {\n return `${h}:${leftPad(m)}:${leftPad(s)}`;\n }\n if (m > 0) {\n return `${m}:${leftPad(s)}`;\n }\n if (s > 0) {\n return \"\" + s;\n }\n return null;\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { durationToSeconds } from \"../datetime/duration_to_seconds\";\n\nexport function timerTimeRemaining(stateObj: HassEntity) {\n let timeRemaining = durationToSeconds(stateObj.attributes.remaining);\n\n if (stateObj.state === \"active\") {\n const now = new Date().getTime();\n const madeActive = new Date(stateObj.last_changed).getTime();\n timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);\n }\n\n return timeRemaining;\n}\n","/**\n * Apply a theme to an element by setting the CSS variables on it.\n *\n * element: Element to apply theme on.\n * themes: HASS Theme information\n * localTheme: selected theme.\n * updateMeta: boolean if we should update the theme-color meta element.\n */\nexport const applyThemesOnElement = (\n element,\n themes,\n localTheme,\n updateMeta = false\n) => {\n if (!element._themes) {\n element._themes = {};\n }\n let themeName = themes.default_theme;\n if (localTheme === \"default\" || (localTheme && themes.themes[localTheme])) {\n themeName = localTheme;\n }\n const styles = { ...element._themes };\n if (themeName !== \"default\") {\n const theme = themes.themes[themeName];\n Object.keys(theme).forEach((key) => {\n const prefixedKey = \"--\" + key;\n element._themes[prefixedKey] = \"\";\n styles[prefixedKey] = theme[key];\n });\n }\n if (element.updateStyles) {\n element.updateStyles(styles);\n } else if ((window as any).ShadyCSS) {\n // implement updateStyles() method of Polemer elements\n (window as any).ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ (element), styles);\n }\n\n if (!updateMeta) {\n return;\n }\n\n const meta = document.querySelector(\"meta[name=theme-color]\");\n if (meta) {\n if (!meta.hasAttribute(\"default-content\")) {\n meta.setAttribute(\"default-content\", meta.getAttribute(\"content\")!);\n }\n const themeColor =\n styles[\"--primary-color\"] || meta.getAttribute(\"default-content\");\n meta.setAttribute(\"content\", themeColor);\n }\n}\n","import { LovelaceCard } from \"./types\";\n\nexport const computeCardSize = (card: LovelaceCard): number | Promise => {\n return typeof card.getCardSize === \"function\" ? card.getCardSize() : 4;\n};","export function computeDomain(entityId: string): string {\n return entityId.substr(0, entityId.indexOf(\".\"));\n}\n","export function computeEntity(entityId: string): string {\n return entityId.substr(entityId.indexOf(\".\") + 1);\n}\n","import { HomeAssistant } from \"./types\";\n\nexport function computeRTL(hass: HomeAssistant) {\n const lang = hass.language || \"en\";\n if (hass.translationMetadata.translations[lang]) {\n return hass.translationMetadata.translations[lang].isRTL || false;\n }\n return false;\n}\n\nexport function computeRTLDirection(hass: HomeAssistant) {\n return computeRTL(hass) ? \"rtl\" : \"ltr\";\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport function computeStateDomain(stateObj: HassEntity) {\n return computeDomain(stateObj.entity_id);\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { formatDateTime } from \"./datetime/format_date_time\";\nimport { formatDate } from \"./datetime/format_date\";\nimport { formatTime } from \"./datetime/format_time\";\nimport { LocalizeFunc } from \"./translations/localize\";\nimport { computeStateDomain } from \"./compute-state-domain\";\n\nexport function computeStateDisplay(\n localize: LocalizeFunc,\n stateObj: HassEntity,\n language: string\n): string {\n if (stateObj.state === \"unknown\" || stateObj.state === \"unavailable\") {\n return localize(`state.default.${stateObj.state}`);\n }\n\n if (stateObj.attributes.unit_of_measurement) {\n return `${stateObj.state} ${stateObj.attributes.unit_of_measurement}`;\n }\n\n const domain = computeStateDomain(stateObj);\n\n if (domain === \"input_datetime\") {\n let date: Date;\n if (!stateObj.attributes.has_time) {\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day\n );\n return formatDate(date, language);\n }\n if (!stateObj.attributes.has_date) {\n const now = new Date();\n date = new Date(\n // Due to bugs.chromium.org/p/chromium/issues/detail?id=797548\n // don't use artificial 1970 year.\n now.getFullYear(),\n now.getMonth(),\n now.getDay(),\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatTime(date, language);\n }\n\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day,\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatDateTime(date, language);\n }\n\n return (\n // Return device class translation\n (stateObj.attributes.device_class &&\n localize(\n `component.${domain}.state.${stateObj.attributes.device_class}.${stateObj.state}`\n )) ||\n // Return default translation\n localize(`component.${domain}.state._.${stateObj.state}`) ||\n // We don't know! Return the raw state.\n stateObj.state\n );\n}\n","/** Constants to be used in the frontend. */\n\n// Constants should be alphabetically sorted by name.\n// Arrays with values should be alphabetically sorted if order doesn't matter.\n// Each constant should have a description what it is supposed to be used for.\n\n/** Icon to use when no icon specified for domain. */\nexport const DEFAULT_DOMAIN_ICON = \"hass:bookmark\";\n\n/** Panel to show when no panel is picked. */\nexport const DEFAULT_PANEL = \"lovelace\";\n\n/** Domains that have a state card. */\nexport const DOMAINS_WITH_CARD = [\n \"climate\",\n \"cover\",\n \"configurator\",\n \"input_select\",\n \"input_number\",\n \"input_text\",\n \"lock\",\n \"media_player\",\n \"scene\",\n \"script\",\n \"timer\",\n \"vacuum\",\n \"water_heater\",\n \"weblink\"\n];\n\n/** Domains with separate more info dialog. */\nexport const DOMAINS_WITH_MORE_INFO = [\n \"alarm_control_panel\",\n \"automation\",\n \"camera\",\n \"climate\",\n \"configurator\",\n \"cover\",\n \"fan\",\n \"group\",\n \"history_graph\",\n \"input_datetime\",\n \"light\",\n \"lock\",\n \"media_player\",\n \"script\",\n \"sun\",\n \"updater\",\n \"vacuum\",\n \"water_heater\",\n \"weather\"\n];\n\n/** Domains that show no more info dialog. */\nexport const DOMAINS_HIDE_MORE_INFO = [\n \"input_number\",\n \"input_select\",\n \"input_text\",\n \"scene\",\n \"weblink\"\n];\n\n/** Domains that should have the history hidden in the more info dialog. */\nexport const DOMAINS_MORE_INFO_NO_HISTORY = [\n \"camera\",\n \"configurator\",\n \"history_graph\",\n \"scene\"\n];\n\n/** States that we consider \"off\". */\nexport const STATES_OFF = [\"closed\", \"locked\", \"off\"];\n\n/** Domains where we allow toggle in Lovelace. */\nexport const DOMAINS_TOGGLE = new Set([\n \"fan\",\n \"input_boolean\",\n \"light\",\n \"switch\",\n \"group\",\n \"automation\"\n]);\n\n/** Temperature units. */\nexport const UNIT_C = \"°C\";\nexport const UNIT_F = \"°F\";\n\n/** Entity ID of the default view. */\nexport const DEFAULT_VIEW_ENTITY_ID = \"group.default_view\";\n","// Polymer legacy event helpers used courtesy of the Polymer project.\n//\n// Copyright (c) 2017 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\ndeclare global {\n // tslint:disable-next-line\n interface HASSDomEvents {}\n}\n\nexport type ValidHassDomEvent = keyof HASSDomEvents;\n\nexport interface HASSDomEvent extends Event {\n detail: T;\n}\n\n/**\n * Dispatches a custom event with an optional detail value.\n *\n * @param {string} type Name of event type.\n * @param {*=} detail Detail value containing event-specific\n * payload.\n * @param {{ bubbles: (boolean|undefined),\n * cancelable: (boolean|undefined),\n * composed: (boolean|undefined) }=}\n * options Object specifying options. These may include:\n * `bubbles` (boolean, defaults to `true`),\n * `cancelable` (boolean, defaults to false), and\n * `node` on which to fire the event (HTMLElement, defaults to `this`).\n * @return {Event} The new event that was fired.\n */\nexport const fireEvent = (\n node: HTMLElement | Window,\n type: HassEvent,\n detail?: HASSDomEvents[HassEvent],\n options?: {\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n }\n) => {\n options = options || {};\n // @ts-ignore\n detail = detail === null || detail === undefined ? {} : detail;\n const event = new Event(type, {\n bubbles: options.bubbles === undefined ? true : options.bubbles,\n cancelable: Boolean(options.cancelable),\n composed: options.composed === undefined ? true : options.composed\n });\n (event as any).detail = detail;\n node.dispatchEvent(event);\n return event;\n};\n","import { fireEvent } from \"./fire-event\";\n\nconst SPECIAL_TYPES = new Set([\n \"call-service\",\n \"divider\",\n \"section\",\n \"weblink\",\n \"cast\",\n \"select\"\n]);\nconst DOMAIN_TO_ELEMENT_TYPE = {\n alert: \"toggle\",\n automation: \"toggle\",\n climate: \"climate\",\n cover: \"cover\",\n fan: \"toggle\",\n group: \"group\",\n input_boolean: \"toggle\",\n input_number: \"input-number\",\n input_select: \"input-select\",\n input_text: \"input-text\",\n light: \"toggle\",\n lock: \"lock\",\n media_player: \"media-player\",\n remote: \"toggle\",\n scene: \"scene\",\n script: \"script\",\n sensor: \"sensor\",\n timer: \"timer\",\n switch: \"toggle\",\n vacuum: \"toggle\",\n // Temporary. Once climate is rewritten,\n // water heater should get it's own row.\n water_heater: \"climate\",\n input_datetime: \"input-datetime\"\n};\n\nexport const createThing = (cardConfig, isRow = false) => {\n const _createError = (error, config) => {\n return _createThing(\n \"hui-error-card\",\n {\n type: \"error\",\n error,\n config\n }\n );\n };\n\n const _createThing = (tag, config) => {\n const element = window.document.createElement(tag);\n try {\n element.setConfig(config);\n } catch (err) {\n console.error(tag, err);\n return _createError(err.message, config);\n }\n return element;\n };\n\n if (!cardConfig || typeof cardConfig !== \"object\" || (!isRow && !cardConfig.type))\n return _createError(\"No type defined\", cardConfig);\n let tag = cardConfig.type;\n if (tag && tag.startsWith(\"custom:\")) {\n tag = tag.substr(\"custom:\".length);\n } else if (isRow) {\n if (SPECIAL_TYPES.has(tag)) {\n tag = `hui-${tag}-row`;\n } else {\n if (!cardConfig.entity) {\n return _createError(\"Invalid config given.\", cardConfig);\n }\n \n const domain = cardConfig.entity.split(\".\", 1)[0];\n tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || \"text\"}-entity-row`;\n }\n } else {\n tag = `hui-${tag}-card`;\n }\n\n if (customElements.get(tag)) return _createThing(tag, cardConfig);\n\n // If element doesn't exist (yet) create an error\n const element = _createError(\n `Custom element doesn't exist: ${cardConfig.type}.`,\n cardConfig\n );\n element.style.display = \"None\";\n const timer = setTimeout(() => {\n element.style.display = \"\";\n }, 2000);\n // Remove error if element is defined later\n customElements.whenDefined(cardConfig.type).then(() => {\n clearTimeout(timer);\n fireEvent(element, \"ll-rebuild\", {}, element);\n });\n\n return element;\n};\n","/**\r\n * Returns a function, that, as long as it continues to be invoked, will not be triggered. It will be called after it stops being called for `wait` ms.\r\n * This can be usefull for ResizeObservers for example.\r\n * @param func The function you want to debounce\r\n * @param wait Period to wait in ms\r\n * @param immediate Triggering on the leading edge instead of the trailing\r\n * @returns Debounced Function\r\n */\r\n// eslint-disable-next-line: ban-types\r\nexport const debounce = unknown>(\r\n func: T,\r\n wait: number,\r\n immediate = false\r\n): T => {\r\n let timeout;\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n return function (...args) {\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n const later = () => {\r\n timeout = null;\r\n if (!immediate) {\r\n func.apply(context, args);\r\n }\r\n };\r\n const callNow = immediate && !timeout;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(later, wait);\r\n if (callNow) {\r\n func.apply(context, args);\r\n }\r\n };\r\n};\r\n","/**\n * Return the icon to be used for a domain.\n *\n * Optionally pass in a state to influence the domain icon.\n */\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\n\nexport const fixedIcons = {\n alert: \"hass:alert\",\n automation: \"hass:playlist-play\",\n calendar: \"hass:calendar\",\n camera: \"hass:video\",\n climate: \"hass:thermostat\",\n configurator: \"hass:settings\",\n conversation: \"hass:text-to-speech\",\n device_tracker: \"hass:account\",\n fan: \"hass:fan\",\n group: \"hass:google-circles-communities\",\n history_graph: \"hass:chart-line\",\n homeassistant: \"hass:home-assistant\",\n homekit: \"hass:home-automation\",\n image_processing: \"hass:image-filter-frames\",\n input_boolean: \"hass:drawing\",\n input_datetime: \"hass:calendar-clock\",\n input_number: \"hass:ray-vertex\",\n input_select: \"hass:format-list-bulleted\",\n input_text: \"hass:textbox\",\n light: \"hass:lightbulb\",\n mailbox: \"hass:mailbox\",\n notify: \"hass:comment-alert\",\n person: \"hass:account\",\n plant: \"hass:flower\",\n proximity: \"hass:apple-safari\",\n remote: \"hass:remote\",\n scene: \"hass:google-pages\",\n script: \"hass:file-document\",\n sensor: \"hass:eye\",\n simple_alarm: \"hass:bell\",\n sun: \"hass:white-balance-sunny\",\n switch: \"hass:flash\",\n timer: \"hass:timer\",\n updater: \"hass:cloud-upload\",\n vacuum: \"hass:robot-vacuum\",\n water_heater: \"hass:thermometer\",\n weblink: \"hass:open-in-new\"\n};\n\nexport function domainIcon(domain: string, state?: string): string {\n if (domain in fixedIcons) {\n return fixedIcons[domain];\n }\n\n switch (domain) {\n case \"alarm_control_panel\":\n switch (state) {\n case \"armed_home\":\n return \"hass:bell-plus\";\n case \"armed_night\":\n return \"hass:bell-sleep\";\n case \"disarmed\":\n return \"hass:bell-outline\";\n case \"triggered\":\n return \"hass:bell-ring\";\n default:\n return \"hass:bell\";\n }\n\n case \"binary_sensor\":\n return state && state === \"off\"\n ? \"hass:radiobox-blank\"\n : \"hass:checkbox-marked-circle\";\n\n case \"cover\":\n return state === \"closed\" ? \"hass:window-closed\" : \"hass:window-open\";\n\n case \"lock\":\n return state && state === \"unlocked\" ? \"hass:lock-open\" : \"hass:lock\";\n\n case \"media_player\":\n return state && state !== \"off\" && state !== \"idle\"\n ? \"hass:cast-connected\"\n : \"hass:cast\";\n\n case \"zwave\":\n switch (state) {\n case \"dead\":\n return \"hass:emoticon-dead\";\n case \"sleeping\":\n return \"hass:sleep\";\n case \"initializing\":\n return \"hass:timer-sand\";\n default:\n return \"hass:z-wave\";\n }\n\n default:\n // tslint:disable-next-line\n console.warn(\n \"Unable to find icon for domain \" + domain + \" (\" + state + \")\"\n );\n return DEFAULT_DOMAIN_ICON;\n }\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {\n const operator = filter.operator || \"==\";\n const value = filter.value || filter;\n const state = filter.attribute\n ? stateObj.attributes[filter.attribute]\n : stateObj.state;\n\n switch (operator) {\n case \"==\":\n return state === value;\n case \"<=\":\n return state <= value;\n case \"<\":\n return state < value;\n case \">=\":\n return state >= value;\n case \">\":\n return state > value;\n case \"!=\":\n return state !== value;\n case \"regex\": {\n return state.match(value);\n }\n default:\n return false;\n }\n};\n","/**\r\n * Formats a number based on the specified language with thousands separator(s) and decimal character for better legibility.\r\n * @param num The number to format\r\n * @param language The language to use when formatting the number\r\n */\r\nexport const formatNumber = (\r\n num: string | number,\r\n language: string,\r\n options?: Intl.NumberFormatOptions\r\n): string => {\r\n // Polyfill for Number.isNaN, which is more reliable than the global isNaN()\r\n Number.isNaN =\r\n Number.isNaN ||\r\n function isNaN(input) {\r\n return typeof input === \"number\" && isNaN(input);\r\n };\r\n\r\n if (!Number.isNaN(Number(num)) && Intl) {\r\n return new Intl.NumberFormat(\r\n language,\r\n getDefaultFormatOptions(num, options)\r\n ).format(Number(num));\r\n }\r\n return num.toString();\r\n};\r\n\r\n/**\r\n * Generates default options for Intl.NumberFormat\r\n * @param num The number to be formatted\r\n * @param options The Intl.NumberFormatOptions that should be included in the returned options\r\n */\r\nconst getDefaultFormatOptions = (\r\n num: string | number,\r\n options?: Intl.NumberFormatOptions\r\n): Intl.NumberFormatOptions => {\r\n const defaultOptions: Intl.NumberFormatOptions = options || {};\r\n\r\n if (typeof num !== \"string\") {\r\n return defaultOptions;\r\n }\r\n\r\n // Keep decimal trailing zeros if they are present in a string numeric value\r\n if (\r\n !options ||\r\n (!options.minimumFractionDigits && !options.maximumFractionDigits)\r\n ) {\r\n const digits = num.indexOf(\".\") > -1 ? num.split(\".\")[1].length : 0;\r\n defaultOptions.minimumFractionDigits = digits;\r\n defaultOptions.maximumFractionDigits = digits;\r\n }\r\n\r\n return defaultOptions;\r\n};\r\n","import { HASSDomEvent, fireEvent } from \"./fire-event\";\n\n/**\n * Broadcast haptic feedback requests\n */\n\n\n// Allowed types are from iOS HIG.\n// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics\n// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible.\nexport type HapticType =\n | \"success\"\n | \"warning\"\n | \"failure\"\n | \"light\"\n | \"medium\"\n | \"heavy\"\n | \"selection\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n haptic: HapticType;\n }\n\n interface GlobalEventHandlersEventMap {\n haptic: HASSDomEvent;\n }\n}\n\nexport const forwardHaptic = (hapticType: HapticType) => {\n fireEvent(window, \"haptic\", hapticType);\n};\n","import { fireEvent } from \"./fire-event\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n \"location-changed\": {\n replace: boolean;\n };\n }\n}\n\nexport const navigate = (\n _node: any,\n path: string,\n replace: boolean = false\n) => {\n if (replace) {\n history.replaceState(null, \"\", path);\n } else {\n history.pushState(null, \"\", path);\n }\n fireEvent(window, \"location-changed\", {\n replace\n });\n};\n","import { HomeAssistant } from \"./types\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntity = (\n hass: HomeAssistant,\n entityId: string,\n turnOn = true\n): Promise => {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = stateDomain === \"group\" ? \"homeassistant\" : stateDomain;\n\n let service;\n switch (stateDomain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n return hass.callService(serviceDomain, service, { entity_id: entityId });\n};\n","import { STATES_OFF } from \"./const\";\nimport { turnOnOffEntity } from \"./turn-on-off-entity\";\nimport { HomeAssistant } from \"./types\";\n\nexport const toggleEntity = (\n hass: HomeAssistant,\n entityId: string\n): Promise => {\n const turnOn = STATES_OFF.includes(hass.states[entityId].state);\n return turnOnOffEntity(hass, entityId, turnOn);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { forwardHaptic } from \"./haptic\";\nimport { fireEvent } from \"./fire-event\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleActionConfig = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n actionConfig: ActionConfig | undefined\n): void => {\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\",\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n (e) => e.user === hass!.user!.id\n ))\n ) {\n forwardHaptic(\"warning\");\n\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: config.entity ? config.entity : config.camera_image!,\n });\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n }\n break;\n case \"url\":\n if (actionConfig.url_path) {\n window.open(actionConfig.url_path);\n }\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n forwardHaptic(\"success\");\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n forwardHaptic(\"failure\");\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n hass.callService(domain, service, actionConfig.service_data);\n forwardHaptic(\"success\");\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n }\n }\n};\n\nexport const handleAction = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n action: string\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (action === \"double_tap\" && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (action === \"hold\" && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (action === \"tap\" && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n handleActionConfig(node, hass, config, actionConfig);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { fireEvent } from \"./fire-event\";\nimport { forwardHaptic } from \"./haptic\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleClick = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n hold: boolean,\n dblClick: boolean\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (dblClick && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (hold && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (!hold && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\"\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n e => e.user === hass!.user!.id\n ))\n ) {\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (actionConfig.entity || config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: actionConfig.entity\n ? actionConfig.entity\n : config.entity\n ? config.entity\n : config.camera_image\n });\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"url\":\n actionConfig.url_path && window.open(actionConfig.url_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n const serviceData = { ...actionConfig.service_data };\n if (serviceData.entity_id === \"entity\") {\n serviceData.entity_id = config.entity;\n }\n hass.callService(domain, service, serviceData);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n }\n};\n","import { ActionConfig } from \"./types\";\n\nexport function hasAction(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}\n","import { PropertyValues } from \"lit-element\";\n\nimport { HomeAssistant } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasConfigOrEntityChanged(\n element: any,\n changedProps: PropertyValues,\n forceUpdate: Boolean,\n): boolean {\n if (changedProps.has('config') || forceUpdate) {\n return true;\n }\n\n if (element.config!.entity) {\n const oldHass = changedProps.get('hass') as HomeAssistant | undefined;\n if (oldHass) {\n return (\n oldHass.states[element.config!.entity]\n !== element.hass!.states[element.config!.entity]\n );\n }\n return true;\n } else {\n return false;\n }\n}","import { ActionConfig } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasDoubleClick(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}","import { HomeAssistant } from \"./types\";\nimport { STATES_OFF } from \"./const\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntities = (\n hass: HomeAssistant,\n entityIds: string[],\n turnOn = true\n): void => {\n const domainsToCall = {};\n entityIds.forEach((entityId) => {\n if (STATES_OFF.includes(hass.states[entityId].state) === turnOn) {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = [\"cover\", \"lock\"].includes(stateDomain)\n ? stateDomain\n : \"homeassistant\";\n\n if (!(serviceDomain in domainsToCall)) {\n domainsToCall[serviceDomain] = [];\n }\n domainsToCall[serviceDomain].push(entityId);\n }\n });\n\n Object.keys(domainsToCall).forEach((domain) => {\n let service;\n switch (domain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n const entities = domainsToCall[domain];\n hass.callService(domain, service, { entity_id: entities });\n });\n};\n","export const getLovelace = () => {\n let root: any = document.querySelector('home-assistant');\n root = root && root.shadowRoot;\n root = root && root.querySelector('home-assistant-main');\n root = root && root.shadowRoot;\n root = root && root.querySelector('app-drawer-layout partial-panel-resolver');\n root = root && root.shadowRoot || root;\n root = root && root.querySelector('ha-panel-lovelace');\n root = root && root.shadowRoot;\n root = root && root.querySelector('hui-root');\n if (root) {\n const ll = root.lovelace;\n ll.current_view = root.___curView;\n return ll;\n }\n return null;\n}\n","/** Return an icon representing a sensor state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { UNIT_C, UNIT_F } from \"./const\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst fixedDeviceClassIcons = {\n humidity: \"hass:water-percent\",\n illuminance: \"hass:brightness-5\",\n temperature: \"hass:thermometer\",\n pressure: \"hass:gauge\",\n power: \"hass:flash\",\n signal_strength: \"hass:wifi\",\n};\n\nexport const sensorIcon = (state: HassEntity) => {\n const dclass = state.attributes.device_class;\n\n if (dclass && dclass in fixedDeviceClassIcons) {\n return fixedDeviceClassIcons[dclass];\n }\n if (dclass === \"battery\") {\n const battery = Number(state.state);\n if (isNaN(battery)) {\n return \"hass:battery-unknown\";\n }\n const batteryRound = Math.round(battery / 10) * 10;\n if (batteryRound >= 100) {\n return \"hass:battery\";\n }\n if (batteryRound <= 0) {\n return \"hass:battery-alert\";\n }\n // Will return one of the following icons: (listed so extractor picks up)\n // hass:battery-10\n // hass:battery-20\n // hass:battery-30\n // hass:battery-40\n // hass:battery-50\n // hass:battery-60\n // hass:battery-70\n // hass:battery-80\n // hass:battery-90\n // We obscure 'hass' in iconname so this name does not get picked up\n return `${\"hass\"}:battery-${batteryRound}`;\n }\n\n const unit = state.attributes.unit_of_measurement;\n if (unit === UNIT_C || unit === UNIT_F) {\n return \"hass:thermometer\";\n }\n return domainIcon(\"sensor\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\nimport { binarySensorIcon } from \"./binary_sensor_icon\";\nimport { coverIcon } from \"./cover_icon\";\nimport { sensorIcon } from \"./sensor_icon\";\nimport { inputDateTimeIcon } from \"./input_datetime_icon\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst domainIcons = {\n binary_sensor: binarySensorIcon,\n cover: coverIcon,\n sensor: sensorIcon,\n input_datetime: inputDateTimeIcon,\n};\n\nexport const stateIcon = (state: HassEntity) => {\n if (!state) {\n return DEFAULT_DOMAIN_ICON;\n }\n if (state.attributes.icon) {\n return state.attributes.icon;\n }\n\n const domain = computeDomain(state.entity_id);\n\n if (domain in domainIcons) {\n return domainIcons[domain](state);\n }\n return domainIcon(domain, state.state);\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\n/** Return an icon representing a binary sensor state. */\n\nexport const binarySensorIcon = (state: HassEntity) => {\n const activated = state.state && state.state === \"off\";\n switch (state.attributes.device_class) {\n case \"battery\":\n return activated ? \"hass:battery\" : \"hass:battery-outline\";\n case \"cold\":\n return activated ? \"hass:thermometer\" : \"hass:snowflake\";\n case \"connectivity\":\n return activated ? \"hass:server-network-off\" : \"hass:server-network\";\n case \"door\":\n return activated ? \"hass:door-closed\" : \"hass:door-open\";\n case \"garage_door\":\n return activated ? \"hass:garage\" : \"hass:garage-open\";\n case \"gas\":\n case \"power\":\n case \"problem\":\n case \"safety\":\n case \"smoke\":\n return activated ? \"hass:shield-check\" : \"hass:alert\";\n case \"heat\":\n return activated ? \"hass:thermometer\" : \"hass:fire\";\n case \"light\":\n return activated ? \"hass:brightness-5\" : \"hass:brightness-7\";\n case \"lock\":\n return activated ? \"hass:lock\" : \"hass:lock-open\";\n case \"moisture\":\n return activated ? \"hass:water-off\" : \"hass:water\";\n case \"motion\":\n return activated ? \"hass:walk\" : \"hass:run\";\n case \"occupancy\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"opening\":\n return activated ? \"hass:square\" : \"hass:square-outline\";\n case \"plug\":\n return activated ? \"hass:power-plug-off\" : \"hass:power-plug\";\n case \"presence\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"sound\":\n return activated ? \"hass:music-note-off\" : \"hass:music-note\";\n case \"vibration\":\n return activated ? \"hass:crop-portrait\" : \"hass:vibrate\";\n case \"window\":\n return activated ? \"hass:window-closed\" : \"hass:window-open\";\n default:\n return activated ? \"hass:radiobox-blank\" : \"hass:checkbox-marked-circle\";\n }\n};\n","/** Return an icon representing a cover state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { domainIcon } from \"./domain_icons\";\n\nexport const coverIcon = (state: HassEntity): string => {\n const open = state.state !== \"closed\";\n switch (state.attributes.device_class) {\n case \"garage\":\n return open ? \"hass:garage-open\" : \"hass:garage\";\n case \"door\":\n return open ? \"hass:door-open\" : \"hass:door-closed\";\n case \"shutter\":\n return open ? \"hass:window-shutter-open\" : \"hass:window-shutter\";\n case \"blind\":\n return open ? \"hass:blinds-open\" : \"hass:blinds\";\n case \"window\":\n return open ? \"hass:window-open\" : \"hass:window-closed\";\n default:\n return domainIcon(\"cover\", state.state);\n }\n};\n","/** Return an icon representing an input datetime state. */\nimport { domainIcon } from \"./domain_icons\";\nimport { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const inputDateTimeIcon = (state: HassEntity): string => {\n if (!state.attributes.has_date) {\n return \"hass:clock\";\n }\n if (!state.attributes.has_time) {\n return \"hass:calendar\";\n }\n return domainIcon(\"input_datetime\");\n};\n"],"names":["durationToSeconds","duration","parts","split","map","Number","formatDate","Date","toLocaleDateString","e","name","toLocaleDateStringSupportsOptions","dateObj","locales","year","month","day","fecha","format","formatDateTime","toLocaleString","toLocaleStringSupportsOptions","hour","minute","formatTime","toLocaleTimeString","toLocaleTimeStringSupportsOptions","tests","langKey","relativeTime","localize","options","timeDesc","delta","compareTime","getTime","tense","Math","abs","let","i","length","floor","undefined","includeTense","const","leftPad","num","secondsToDuration","d","h","m","s","timerTimeRemaining","stateObj","timeRemaining","attributes","remaining","state","now","madeActive","last_changed","max","applyThemesOnElement","element","themes","localTheme","updateMeta","_themes","themeName","default_theme","styles","Object","theme","keys","forEach","key","prefixedKey","updateStyles","window","ShadyCSS","styleSubtree","meta","document","querySelector","hasAttribute","setAttribute","getAttribute","themeColor","computeCardSize","card","getCardSize","computeDomain","entityId","substr","indexOf","computeEntity","computeRTL","hass","lang","language","translationMetadata","translations","isRTL","computeRTLDirection","computeStateDomain","entity_id","computeStateDisplay","unit_of_measurement","domain","date","has_time","has_date","getFullYear","getMonth","getDay","device_class","DEFAULT_DOMAIN_ICON","DEFAULT_PANEL","DOMAINS_WITH_CARD","DOMAINS_WITH_MORE_INFO","DOMAINS_HIDE_MORE_INFO","DOMAINS_MORE_INFO_NO_HISTORY","STATES_OFF","DOMAINS_TOGGLE","Set","UNIT_C","UNIT_F","DEFAULT_VIEW_ENTITY_ID","fireEvent","node","type","detail","event","Event","bubbles","cancelable","Boolean","composed","dispatchEvent","SPECIAL_TYPES","DOMAIN_TO_ELEMENT_TYPE","alert","automation","climate","cover","fan","group","input_boolean","input_number","input_select","input_text","light","lock","media_player","remote","scene","script","sensor","timer","switch","vacuum","water_heater","input_datetime","createThing","cardConfig","isRow","_createError","error","config","_createThing","tag","createElement","setConfig","err","console","message","startsWith","has","entity","customElements","get","style","display","setTimeout","whenDefined","then","clearTimeout","debounce","func","wait","immediate","timeout","context","this","callNow","apply","args","fixedIcons","calendar","camera","configurator","conversation","device_tracker","history_graph","homeassistant","homekit","image_processing","mailbox","notify","person","plant","proximity","simple_alarm","sun","updater","weblink","domainIcon","warn","evaluateFilter","filter","value","attribute","operator","match","formatNumber","isNaN","input","Intl","NumberFormat","getDefaultFormatOptions","toString","defaultOptions","minimumFractionDigits","maximumFractionDigits","digits","forwardHaptic","hapticType","navigate","_node","path","replace","history","replaceState","pushState","turnOnOffEntity","turnOn","service","stateDomain","serviceDomain","callService","toggleEntity","includes","states","handleActionConfig","actionConfig","action","confirmation","exemptions","some","user","id","confirm","text","camera_image","navigation_path","url_path","open","service_data","handleAction","double_tap_action","hold_action","tap_action","handleClick","hold","dblClick","haptic","serviceData","hasAction","hasConfigOrEntityChanged","changedProps","forceUpdate","oldHass","hasDoubleClick","turnOnOffEntities","entityIds","domainsToCall","push","getLovelace","root","shadowRoot","ll","lovelace","current_view","___curView","fixedDeviceClassIcons","humidity","illuminance","temperature","pressure","power","signal_strength","domainIcons","binary_sensor","activated","dclass","battery","batteryRound","round","unit","stateIcon","icon"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.m.js","sources":["../src/datetime/duration_to_seconds.ts","../src/datetime/format_date.ts","../src/datetime/format_date_time.ts","../src/datetime/format_time.ts","../src/datetime/relative_time.ts","../src/datetime/seconds_to_duration.ts","../src/datetime/timer_time_remaining.ts","../src/apply_themes_on_element.ts","../src/compute-card-size.ts","../src/compute-domain.ts","../src/compute-entity.ts","../src/compute-rtl.ts","../src/compute-state-domain.ts","../src/compute-state-display.ts","../src/const.ts","../src/fire-event.ts","../src/create-thing.ts","../src/debounce.ts","../src/domain_icons.ts","../src/evaluate-filter.ts","../src/format-number.ts","../src/haptic.ts","../src/navigate.ts","../src/turn-on-off-entity.ts","../src/toggle-entity.ts","../src/handle-action.ts","../src/handle-click.ts","../src/has-action.ts","../src/has-changed.ts","../src/has-double-click.ts","../src/turn-on-off-entities.ts","../src/get-lovelace.ts","../src/sensor_icon.ts","../src/state_icon.ts","../src/binary_sensor_icon.ts","../src/cover_icon.ts","../src/input_datetime_icon.ts"],"sourcesContent":["export function durationToSeconds(duration: string): number {\n const parts = duration.split(\":\").map(Number);\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n}\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleDateStringSupportsOptions() {\n try {\n new Date().toLocaleDateString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDate = (toLocaleDateStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleDateString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"mediumDate\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleStringSupportsOptions() {\n try {\n new Date().toLocaleString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDateTime = (toLocaleStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"haDateTime\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleTimeStringSupportsOptions() {\n try {\n new Date().toLocaleTimeString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatTime = (toLocaleTimeStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleTimeString(locales, {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"shortTime\"));\n","import { LocalizeFunc } from \"../translations/localize\";\n\n/**\n * Calculate a string representing a date object as relative time from now.\n *\n * Example output: 5 minutes ago, in 3 days.\n */\nconst tests = [60, 60, 24, 7];\nconst langKey = [\"second\", \"minute\", \"hour\", \"day\"];\n\nexport function relativeTime(\n dateObj: Date,\n localize: LocalizeFunc,\n options: {\n compareTime?: Date;\n includeTense?: boolean;\n } = {}\n): string {\n const compareTime = options.compareTime || new Date();\n let delta = (compareTime.getTime() - dateObj.getTime()) / 1000;\n const tense = delta >= 0 ? \"past\" : \"future\";\n delta = Math.abs(delta);\n\n let timeDesc;\n\n for (let i = 0; i < tests.length; i++) {\n if (delta < tests[i]) {\n delta = Math.floor(delta);\n timeDesc = localize(\n `ui.components.relative_time.duration.${langKey[i]}`,\n \"count\",\n delta\n );\n break;\n }\n\n delta /= tests[i];\n }\n\n if (timeDesc === undefined) {\n delta = Math.floor(delta);\n timeDesc = localize(\n \"ui.components.relative_time.duration.week\",\n \"count\",\n delta\n );\n }\n\n return options.includeTense === false\n ? timeDesc\n : localize(`ui.components.relative_time.${tense}`, \"time\", timeDesc);\n}\n","const leftPad = (num: number) => (num < 10 ? `0${num}` : num);\n\nexport function secondsToDuration(d: number) {\n const h = Math.floor(d / 3600);\n const m = Math.floor((d % 3600) / 60);\n const s = Math.floor((d % 3600) % 60);\n\n if (h > 0) {\n return `${h}:${leftPad(m)}:${leftPad(s)}`;\n }\n if (m > 0) {\n return `${m}:${leftPad(s)}`;\n }\n if (s > 0) {\n return \"\" + s;\n }\n return null;\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { durationToSeconds } from \"../datetime/duration_to_seconds\";\n\nexport function timerTimeRemaining(stateObj: HassEntity) {\n let timeRemaining = durationToSeconds(stateObj.attributes.remaining);\n\n if (stateObj.state === \"active\") {\n const now = new Date().getTime();\n const madeActive = new Date(stateObj.last_changed).getTime();\n timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);\n }\n\n return timeRemaining;\n}\n","/**\n * Apply a theme to an element by setting the CSS variables on it.\n *\n * element: Element to apply theme on.\n * themes: HASS Theme information\n * localTheme: selected theme.\n * updateMeta: boolean if we should update the theme-color meta element.\n */\nexport const applyThemesOnElement = (\n element,\n themes,\n localTheme,\n updateMeta = false\n) => {\n if (!element._themes) {\n element._themes = {};\n }\n let themeName = themes.default_theme;\n if (localTheme === \"default\" || (localTheme && themes.themes[localTheme])) {\n themeName = localTheme;\n }\n const styles = { ...element._themes };\n if (themeName !== \"default\") {\n const theme = themes.themes[themeName];\n Object.keys(theme).forEach((key) => {\n const prefixedKey = \"--\" + key;\n element._themes[prefixedKey] = \"\";\n styles[prefixedKey] = theme[key];\n });\n }\n if (element.updateStyles) {\n element.updateStyles(styles);\n } else if ((window as any).ShadyCSS) {\n // implement updateStyles() method of Polemer elements\n (window as any).ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ (element), styles);\n }\n\n if (!updateMeta) {\n return;\n }\n\n const meta = document.querySelector(\"meta[name=theme-color]\");\n if (meta) {\n if (!meta.hasAttribute(\"default-content\")) {\n meta.setAttribute(\"default-content\", meta.getAttribute(\"content\")!);\n }\n const themeColor =\n styles[\"--primary-color\"] || meta.getAttribute(\"default-content\");\n meta.setAttribute(\"content\", themeColor);\n }\n}\n","import { LovelaceCard } from \"./types\";\n\nexport const computeCardSize = (card: LovelaceCard): number | Promise => {\n return typeof card.getCardSize === \"function\" ? card.getCardSize() : 4;\n};","export function computeDomain(entityId: string): string {\n return entityId.substr(0, entityId.indexOf(\".\"));\n}\n","export function computeEntity(entityId: string): string {\n return entityId.substr(entityId.indexOf(\".\") + 1);\n}\n","import { HomeAssistant } from \"./types\";\n\nexport function computeRTL(hass: HomeAssistant) {\n const lang = hass.language || \"en\";\n if (hass.translationMetadata.translations[lang]) {\n return hass.translationMetadata.translations[lang].isRTL || false;\n }\n return false;\n}\n\nexport function computeRTLDirection(hass: HomeAssistant) {\n return computeRTL(hass) ? \"rtl\" : \"ltr\";\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport function computeStateDomain(stateObj: HassEntity) {\n return computeDomain(stateObj.entity_id);\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { formatDateTime } from \"./datetime/format_date_time\";\nimport { formatDate } from \"./datetime/format_date\";\nimport { formatTime } from \"./datetime/format_time\";\nimport { LocalizeFunc } from \"./translations/localize\";\nimport { computeStateDomain } from \"./compute-state-domain\";\n\nexport function computeStateDisplay(\n localize: LocalizeFunc,\n stateObj: HassEntity,\n language: string\n): string {\n if (stateObj.state === \"unknown\" || stateObj.state === \"unavailable\") {\n return localize(`state.default.${stateObj.state}`);\n }\n\n if (stateObj.attributes.unit_of_measurement) {\n return `${stateObj.state} ${stateObj.attributes.unit_of_measurement}`;\n }\n\n const domain = computeStateDomain(stateObj);\n\n if (domain === \"input_datetime\") {\n let date: Date;\n if (!stateObj.attributes.has_time) {\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day\n );\n return formatDate(date, language);\n }\n if (!stateObj.attributes.has_date) {\n const now = new Date();\n date = new Date(\n // Due to bugs.chromium.org/p/chromium/issues/detail?id=797548\n // don't use artificial 1970 year.\n now.getFullYear(),\n now.getMonth(),\n now.getDay(),\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatTime(date, language);\n }\n\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day,\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatDateTime(date, language);\n }\n\n return (\n // Return device class translation\n (stateObj.attributes.device_class &&\n localize(\n `component.${domain}.state.${stateObj.attributes.device_class}.${stateObj.state}`\n )) ||\n // Return default translation\n localize(`component.${domain}.state._.${stateObj.state}`) ||\n // We don't know! Return the raw state.\n stateObj.state\n );\n}\n","/** Constants to be used in the frontend. */\n\n// Constants should be alphabetically sorted by name.\n// Arrays with values should be alphabetically sorted if order doesn't matter.\n// Each constant should have a description what it is supposed to be used for.\n\n/** Icon to use when no icon specified for domain. */\nexport const DEFAULT_DOMAIN_ICON = \"hass:bookmark\";\n\n/** Panel to show when no panel is picked. */\nexport const DEFAULT_PANEL = \"lovelace\";\n\n/** Domains that have a state card. */\nexport const DOMAINS_WITH_CARD = [\n \"climate\",\n \"cover\",\n \"configurator\",\n \"input_select\",\n \"input_number\",\n \"input_text\",\n \"lock\",\n \"media_player\",\n \"scene\",\n \"script\",\n \"timer\",\n \"vacuum\",\n \"water_heater\",\n \"weblink\"\n];\n\n/** Domains with separate more info dialog. */\nexport const DOMAINS_WITH_MORE_INFO = [\n \"alarm_control_panel\",\n \"automation\",\n \"camera\",\n \"climate\",\n \"configurator\",\n \"cover\",\n \"fan\",\n \"group\",\n \"history_graph\",\n \"input_datetime\",\n \"light\",\n \"lock\",\n \"media_player\",\n \"script\",\n \"sun\",\n \"updater\",\n \"vacuum\",\n \"water_heater\",\n \"weather\"\n];\n\n/** Domains that show no more info dialog. */\nexport const DOMAINS_HIDE_MORE_INFO = [\n \"input_number\",\n \"input_select\",\n \"input_text\",\n \"scene\",\n \"weblink\"\n];\n\n/** Domains that should have the history hidden in the more info dialog. */\nexport const DOMAINS_MORE_INFO_NO_HISTORY = [\n \"camera\",\n \"configurator\",\n \"history_graph\",\n \"scene\"\n];\n\n/** States that we consider \"off\". */\nexport const STATES_OFF = [\"closed\", \"locked\", \"off\"];\n\n/** Domains where we allow toggle in Lovelace. */\nexport const DOMAINS_TOGGLE = new Set([\n \"fan\",\n \"input_boolean\",\n \"light\",\n \"switch\",\n \"group\",\n \"automation\"\n]);\n\n/** Temperature units. */\nexport const UNIT_C = \"°C\";\nexport const UNIT_F = \"°F\";\n\n/** Entity ID of the default view. */\nexport const DEFAULT_VIEW_ENTITY_ID = \"group.default_view\";\n","// Polymer legacy event helpers used courtesy of the Polymer project.\n//\n// Copyright (c) 2017 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\ndeclare global {\n // tslint:disable-next-line\n interface HASSDomEvents {}\n}\n\nexport type ValidHassDomEvent = keyof HASSDomEvents;\n\nexport interface HASSDomEvent extends Event {\n detail: T;\n}\n\n/**\n * Dispatches a custom event with an optional detail value.\n *\n * @param {string} type Name of event type.\n * @param {*=} detail Detail value containing event-specific\n * payload.\n * @param {{ bubbles: (boolean|undefined),\n * cancelable: (boolean|undefined),\n * composed: (boolean|undefined) }=}\n * options Object specifying options. These may include:\n * `bubbles` (boolean, defaults to `true`),\n * `cancelable` (boolean, defaults to false), and\n * `node` on which to fire the event (HTMLElement, defaults to `this`).\n * @return {Event} The new event that was fired.\n */\nexport const fireEvent = (\n node: HTMLElement | Window,\n type: HassEvent,\n detail?: HASSDomEvents[HassEvent],\n options?: {\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n }\n) => {\n options = options || {};\n // @ts-ignore\n detail = detail === null || detail === undefined ? {} : detail;\n const event = new Event(type, {\n bubbles: options.bubbles === undefined ? true : options.bubbles,\n cancelable: Boolean(options.cancelable),\n composed: options.composed === undefined ? true : options.composed\n });\n (event as any).detail = detail;\n node.dispatchEvent(event);\n return event;\n};\n","import { fireEvent } from \"./fire-event\";\n\nconst SPECIAL_TYPES = new Set([\n \"call-service\",\n \"divider\",\n \"section\",\n \"weblink\",\n \"cast\",\n \"select\"\n]);\nconst DOMAIN_TO_ELEMENT_TYPE = {\n alert: \"toggle\",\n automation: \"toggle\",\n climate: \"climate\",\n cover: \"cover\",\n fan: \"toggle\",\n group: \"group\",\n input_boolean: \"toggle\",\n input_number: \"input-number\",\n input_select: \"input-select\",\n input_text: \"input-text\",\n light: \"toggle\",\n lock: \"lock\",\n media_player: \"media-player\",\n remote: \"toggle\",\n scene: \"scene\",\n script: \"script\",\n sensor: \"sensor\",\n timer: \"timer\",\n switch: \"toggle\",\n vacuum: \"toggle\",\n // Temporary. Once climate is rewritten,\n // water heater should get it's own row.\n water_heater: \"climate\",\n input_datetime: \"input-datetime\"\n};\n\nexport const createThing = (cardConfig, isRow = false) => {\n const _createError = (error, config) => {\n return _createThing(\n \"hui-error-card\",\n {\n type: \"error\",\n error,\n config\n }\n );\n };\n\n const _createThing = (tag, config) => {\n const element = window.document.createElement(tag);\n try {\n element.setConfig(config);\n } catch (err) {\n console.error(tag, err);\n return _createError(err.message, config);\n }\n return element;\n };\n\n if (!cardConfig || typeof cardConfig !== \"object\" || (!isRow && !cardConfig.type))\n return _createError(\"No type defined\", cardConfig);\n let tag = cardConfig.type;\n if (tag && tag.startsWith(\"custom:\")) {\n tag = tag.substr(\"custom:\".length);\n } else if (isRow) {\n if (SPECIAL_TYPES.has(tag)) {\n tag = `hui-${tag}-row`;\n } else {\n if (!cardConfig.entity) {\n return _createError(\"Invalid config given.\", cardConfig);\n }\n \n const domain = cardConfig.entity.split(\".\", 1)[0];\n tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || \"text\"}-entity-row`;\n }\n } else {\n tag = `hui-${tag}-card`;\n }\n\n if (customElements.get(tag)) return _createThing(tag, cardConfig);\n\n // If element doesn't exist (yet) create an error\n const element = _createError(\n `Custom element doesn't exist: ${cardConfig.type}.`,\n cardConfig\n );\n element.style.display = \"None\";\n const timer = setTimeout(() => {\n element.style.display = \"\";\n }, 2000);\n // Remove error if element is defined later\n customElements.whenDefined(cardConfig.type).then(() => {\n clearTimeout(timer);\n fireEvent(element, \"ll-rebuild\", {}, element);\n });\n\n return element;\n};\n","/**\r\n * Returns a function, that, as long as it continues to be invoked, will not be triggered. It will be called after it stops being called for `wait` ms.\r\n * This can be usefull for ResizeObservers for example.\r\n * @param func The function you want to debounce\r\n * @param wait Period to wait in ms\r\n * @param immediate Triggering on the leading edge instead of the trailing\r\n * @returns Debounced Function\r\n */\r\n// eslint-disable-next-line: ban-types\r\nexport const debounce = unknown>(\r\n func: T,\r\n wait: number,\r\n immediate = false\r\n): T => {\r\n let timeout;\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n return function (...args) {\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n const later = () => {\r\n timeout = null;\r\n if (!immediate) {\r\n func.apply(context, args);\r\n }\r\n };\r\n const callNow = immediate && !timeout;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(later, wait);\r\n if (callNow) {\r\n func.apply(context, args);\r\n }\r\n };\r\n};\r\n","/**\n * Return the icon to be used for a domain.\n *\n * Optionally pass in a state to influence the domain icon.\n */\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\n\nexport const fixedIcons = {\n alert: \"hass:alert\",\n automation: \"hass:playlist-play\",\n calendar: \"hass:calendar\",\n camera: \"hass:video\",\n climate: \"hass:thermostat\",\n configurator: \"hass:settings\",\n conversation: \"hass:text-to-speech\",\n device_tracker: \"hass:account\",\n fan: \"hass:fan\",\n group: \"hass:google-circles-communities\",\n history_graph: \"hass:chart-line\",\n homeassistant: \"hass:home-assistant\",\n homekit: \"hass:home-automation\",\n image_processing: \"hass:image-filter-frames\",\n input_boolean: \"hass:drawing\",\n input_datetime: \"hass:calendar-clock\",\n input_number: \"hass:ray-vertex\",\n input_select: \"hass:format-list-bulleted\",\n input_text: \"hass:textbox\",\n light: \"hass:lightbulb\",\n mailbox: \"hass:mailbox\",\n notify: \"hass:comment-alert\",\n person: \"hass:account\",\n plant: \"hass:flower\",\n proximity: \"hass:apple-safari\",\n remote: \"hass:remote\",\n scene: \"hass:google-pages\",\n script: \"hass:file-document\",\n sensor: \"hass:eye\",\n simple_alarm: \"hass:bell\",\n sun: \"hass:white-balance-sunny\",\n switch: \"hass:flash\",\n timer: \"hass:timer\",\n updater: \"hass:cloud-upload\",\n vacuum: \"hass:robot-vacuum\",\n water_heater: \"hass:thermometer\",\n weblink: \"hass:open-in-new\"\n};\n\nexport function domainIcon(domain: string, state?: string): string {\n if (domain in fixedIcons) {\n return fixedIcons[domain];\n }\n\n switch (domain) {\n case \"alarm_control_panel\":\n switch (state) {\n case \"armed_home\":\n return \"hass:bell-plus\";\n case \"armed_night\":\n return \"hass:bell-sleep\";\n case \"disarmed\":\n return \"hass:bell-outline\";\n case \"triggered\":\n return \"hass:bell-ring\";\n default:\n return \"hass:bell\";\n }\n\n case \"binary_sensor\":\n return state && state === \"off\"\n ? \"hass:radiobox-blank\"\n : \"hass:checkbox-marked-circle\";\n\n case \"cover\":\n return state === \"closed\" ? \"hass:window-closed\" : \"hass:window-open\";\n\n case \"lock\":\n return state && state === \"unlocked\" ? \"hass:lock-open\" : \"hass:lock\";\n\n case \"media_player\":\n return state && state !== \"off\" && state !== \"idle\"\n ? \"hass:cast-connected\"\n : \"hass:cast\";\n\n case \"zwave\":\n switch (state) {\n case \"dead\":\n return \"hass:emoticon-dead\";\n case \"sleeping\":\n return \"hass:sleep\";\n case \"initializing\":\n return \"hass:timer-sand\";\n default:\n return \"hass:z-wave\";\n }\n\n default:\n // tslint:disable-next-line\n console.warn(\n \"Unable to find icon for domain \" + domain + \" (\" + state + \")\"\n );\n return DEFAULT_DOMAIN_ICON;\n }\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {\n const operator = filter.operator || \"==\";\n const value = filter.value || filter;\n const state = filter.attribute\n ? stateObj.attributes[filter.attribute]\n : stateObj.state;\n\n switch (operator) {\n case \"==\":\n return state === value;\n case \"<=\":\n return state <= value;\n case \"<\":\n return state < value;\n case \">=\":\n return state >= value;\n case \">\":\n return state > value;\n case \"!=\":\n return state !== value;\n case \"regex\": {\n return state.match(value);\n }\n default:\n return false;\n }\n};\n","/**\r\n * Formats a number based on the specified language with thousands separator(s) and decimal character for better legibility.\r\n * @param num The number to format\r\n * @param language The language to use when formatting the number\r\n */\r\nexport const formatNumber = (\r\n num: string | number,\r\n language: string,\r\n options?: Intl.NumberFormatOptions\r\n): string => {\r\n // Polyfill for Number.isNaN, which is more reliable than the global isNaN()\r\n Number.isNaN =\r\n Number.isNaN ||\r\n function isNaN(input) {\r\n return typeof input === \"number\" && isNaN(input);\r\n };\r\n\r\n if (!Number.isNaN(Number(num)) && Intl) {\r\n return new Intl.NumberFormat(\r\n language,\r\n getDefaultFormatOptions(num, options)\r\n ).format(Number(num));\r\n }\r\n return num.toString();\r\n};\r\n\r\n/**\r\n * Generates default options for Intl.NumberFormat\r\n * @param num The number to be formatted\r\n * @param options The Intl.NumberFormatOptions that should be included in the returned options\r\n */\r\nconst getDefaultFormatOptions = (\r\n num: string | number,\r\n options?: Intl.NumberFormatOptions\r\n): Intl.NumberFormatOptions => {\r\n const defaultOptions: Intl.NumberFormatOptions = options || {};\r\n\r\n if (typeof num !== \"string\") {\r\n return defaultOptions;\r\n }\r\n\r\n // Keep decimal trailing zeros if they are present in a string numeric value\r\n if (\r\n !options ||\r\n (!options.minimumFractionDigits && !options.maximumFractionDigits)\r\n ) {\r\n const digits = num.indexOf(\".\") > -1 ? num.split(\".\")[1].length : 0;\r\n defaultOptions.minimumFractionDigits = digits;\r\n defaultOptions.maximumFractionDigits = digits;\r\n }\r\n\r\n return defaultOptions;\r\n};\r\n","import { HASSDomEvent, fireEvent } from \"./fire-event\";\n\n/**\n * Broadcast haptic feedback requests\n */\n\n\n// Allowed types are from iOS HIG.\n// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics\n// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible.\nexport type HapticType =\n | \"success\"\n | \"warning\"\n | \"failure\"\n | \"light\"\n | \"medium\"\n | \"heavy\"\n | \"selection\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n haptic: HapticType;\n }\n\n interface GlobalEventHandlersEventMap {\n haptic: HASSDomEvent;\n }\n}\n\nexport const forwardHaptic = (hapticType: HapticType) => {\n fireEvent(window, \"haptic\", hapticType);\n};\n","import { fireEvent } from \"./fire-event\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n \"location-changed\": {\n replace: boolean;\n };\n }\n}\n\nexport const navigate = (\n _node: any,\n path: string,\n replace: boolean = false\n) => {\n if (replace) {\n history.replaceState(null, \"\", path);\n } else {\n history.pushState(null, \"\", path);\n }\n fireEvent(window, \"location-changed\", {\n replace\n });\n};\n","import { HomeAssistant } from \"./types\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntity = (\n hass: HomeAssistant,\n entityId: string,\n turnOn = true\n): Promise => {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = stateDomain === \"group\" ? \"homeassistant\" : stateDomain;\n\n let service;\n switch (stateDomain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n return hass.callService(serviceDomain, service, { entity_id: entityId });\n};\n","import { STATES_OFF } from \"./const\";\nimport { turnOnOffEntity } from \"./turn-on-off-entity\";\nimport { HomeAssistant } from \"./types\";\n\nexport const toggleEntity = (\n hass: HomeAssistant,\n entityId: string\n): Promise => {\n const turnOn = STATES_OFF.includes(hass.states[entityId].state);\n return turnOnOffEntity(hass, entityId, turnOn);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { forwardHaptic } from \"./haptic\";\nimport { fireEvent } from \"./fire-event\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleActionConfig = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n actionConfig: ActionConfig | undefined\n): void => {\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\",\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n (e) => e.user === hass!.user!.id\n ))\n ) {\n forwardHaptic(\"warning\");\n\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: config.entity ? config.entity : config.camera_image!,\n });\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n }\n break;\n case \"url\":\n if (actionConfig.url_path) {\n window.open(actionConfig.url_path);\n }\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n forwardHaptic(\"success\");\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n forwardHaptic(\"failure\");\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n hass.callService(domain, service, actionConfig.service_data);\n forwardHaptic(\"success\");\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n }\n }\n};\n\nexport const handleAction = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n action: string\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (action === \"double_tap\" && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (action === \"hold\" && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (action === \"tap\" && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n handleActionConfig(node, hass, config, actionConfig);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { fireEvent } from \"./fire-event\";\nimport { forwardHaptic } from \"./haptic\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleClick = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n hold: boolean,\n dblClick: boolean\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (dblClick && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (hold && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (!hold && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\"\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n e => e.user === hass!.user!.id\n ))\n ) {\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (actionConfig.entity || config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: actionConfig.entity\n ? actionConfig.entity\n : config.entity\n ? config.entity\n : config.camera_image\n });\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"url\":\n actionConfig.url_path && window.open(actionConfig.url_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n const serviceData = { ...actionConfig.service_data };\n if (serviceData.entity_id === \"entity\") {\n serviceData.entity_id = config.entity;\n }\n hass.callService(domain, service, serviceData);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n }\n }\n};\n","import { ActionConfig } from \"./types\";\n\nexport function hasAction(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}\n","import { PropertyValues } from \"lit-element\";\n\nimport { HomeAssistant } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasConfigOrEntityChanged(\n element: any,\n changedProps: PropertyValues,\n forceUpdate: Boolean,\n): boolean {\n if (changedProps.has('config') || forceUpdate) {\n return true;\n }\n\n if (element.config!.entity) {\n const oldHass = changedProps.get('hass') as HomeAssistant | undefined;\n if (oldHass) {\n return (\n oldHass.states[element.config!.entity]\n !== element.hass!.states[element.config!.entity]\n );\n }\n return true;\n } else {\n return false;\n }\n}","import { ActionConfig } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasDoubleClick(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}","import { HomeAssistant } from \"./types\";\nimport { STATES_OFF } from \"./const\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntities = (\n hass: HomeAssistant,\n entityIds: string[],\n turnOn = true\n): void => {\n const domainsToCall = {};\n entityIds.forEach((entityId) => {\n if (STATES_OFF.includes(hass.states[entityId].state) === turnOn) {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = [\"cover\", \"lock\"].includes(stateDomain)\n ? stateDomain\n : \"homeassistant\";\n\n if (!(serviceDomain in domainsToCall)) {\n domainsToCall[serviceDomain] = [];\n }\n domainsToCall[serviceDomain].push(entityId);\n }\n });\n\n Object.keys(domainsToCall).forEach((domain) => {\n let service;\n switch (domain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n const entities = domainsToCall[domain];\n hass.callService(domain, service, { entity_id: entities });\n });\n};\n","export const getLovelace = () => {\n let root: any = document.querySelector('home-assistant');\n root = root && root.shadowRoot;\n root = root && root.querySelector('home-assistant-main');\n root = root && root.shadowRoot;\n root = root && root.querySelector('app-drawer-layout partial-panel-resolver');\n root = root && root.shadowRoot || root;\n root = root && root.querySelector('ha-panel-lovelace');\n root = root && root.shadowRoot;\n root = root && root.querySelector('hui-root');\n if (root) {\n const ll = root.lovelace;\n ll.current_view = root.___curView;\n return ll;\n }\n return null;\n}\n","/** Return an icon representing a sensor state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { UNIT_C, UNIT_F } from \"./const\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst fixedDeviceClassIcons = {\n humidity: \"hass:water-percent\",\n illuminance: \"hass:brightness-5\",\n temperature: \"hass:thermometer\",\n pressure: \"hass:gauge\",\n power: \"hass:flash\",\n signal_strength: \"hass:wifi\",\n};\n\nexport const sensorIcon = (state: HassEntity) => {\n const dclass = state.attributes.device_class;\n\n if (dclass && dclass in fixedDeviceClassIcons) {\n return fixedDeviceClassIcons[dclass];\n }\n if (dclass === \"battery\") {\n const battery = Number(state.state);\n if (isNaN(battery)) {\n return \"hass:battery-unknown\";\n }\n const batteryRound = Math.round(battery / 10) * 10;\n if (batteryRound >= 100) {\n return \"hass:battery\";\n }\n if (batteryRound <= 0) {\n return \"hass:battery-alert\";\n }\n // Will return one of the following icons: (listed so extractor picks up)\n // hass:battery-10\n // hass:battery-20\n // hass:battery-30\n // hass:battery-40\n // hass:battery-50\n // hass:battery-60\n // hass:battery-70\n // hass:battery-80\n // hass:battery-90\n // We obscure 'hass' in iconname so this name does not get picked up\n return `${\"hass\"}:battery-${batteryRound}`;\n }\n\n const unit = state.attributes.unit_of_measurement;\n if (unit === UNIT_C || unit === UNIT_F) {\n return \"hass:thermometer\";\n }\n return domainIcon(\"sensor\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\nimport { binarySensorIcon } from \"./binary_sensor_icon\";\nimport { coverIcon } from \"./cover_icon\";\nimport { sensorIcon } from \"./sensor_icon\";\nimport { inputDateTimeIcon } from \"./input_datetime_icon\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst domainIcons = {\n binary_sensor: binarySensorIcon,\n cover: coverIcon,\n sensor: sensorIcon,\n input_datetime: inputDateTimeIcon,\n};\n\nexport const stateIcon = (state: HassEntity) => {\n if (!state) {\n return DEFAULT_DOMAIN_ICON;\n }\n if (state.attributes.icon) {\n return state.attributes.icon;\n }\n\n const domain = computeDomain(state.entity_id);\n\n if (domain in domainIcons) {\n return domainIcons[domain](state);\n }\n return domainIcon(domain, state.state);\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\n/** Return an icon representing a binary sensor state. */\n\nexport const binarySensorIcon = (state: HassEntity) => {\n const activated = state.state && state.state === \"off\";\n switch (state.attributes.device_class) {\n case \"battery\":\n return activated ? \"hass:battery\" : \"hass:battery-outline\";\n case \"cold\":\n return activated ? \"hass:thermometer\" : \"hass:snowflake\";\n case \"connectivity\":\n return activated ? \"hass:server-network-off\" : \"hass:server-network\";\n case \"door\":\n return activated ? \"hass:door-closed\" : \"hass:door-open\";\n case \"garage_door\":\n return activated ? \"hass:garage\" : \"hass:garage-open\";\n case \"gas\":\n case \"power\":\n case \"problem\":\n case \"safety\":\n case \"smoke\":\n return activated ? \"hass:shield-check\" : \"hass:alert\";\n case \"heat\":\n return activated ? \"hass:thermometer\" : \"hass:fire\";\n case \"light\":\n return activated ? \"hass:brightness-5\" : \"hass:brightness-7\";\n case \"lock\":\n return activated ? \"hass:lock\" : \"hass:lock-open\";\n case \"moisture\":\n return activated ? \"hass:water-off\" : \"hass:water\";\n case \"motion\":\n return activated ? \"hass:walk\" : \"hass:run\";\n case \"occupancy\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"opening\":\n return activated ? \"hass:square\" : \"hass:square-outline\";\n case \"plug\":\n return activated ? \"hass:power-plug-off\" : \"hass:power-plug\";\n case \"presence\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"sound\":\n return activated ? \"hass:music-note-off\" : \"hass:music-note\";\n case \"vibration\":\n return activated ? \"hass:crop-portrait\" : \"hass:vibrate\";\n case \"window\":\n return activated ? \"hass:window-closed\" : \"hass:window-open\";\n default:\n return activated ? \"hass:radiobox-blank\" : \"hass:checkbox-marked-circle\";\n }\n};\n","/** Return an icon representing a cover state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { domainIcon } from \"./domain_icons\";\n\nexport const coverIcon = (state: HassEntity): string => {\n const open = state.state !== \"closed\";\n switch (state.attributes.device_class) {\n case \"garage\":\n return open ? \"hass:garage-open\" : \"hass:garage\";\n case \"door\":\n return open ? \"hass:door-open\" : \"hass:door-closed\";\n case \"shutter\":\n return open ? \"hass:window-shutter-open\" : \"hass:window-shutter\";\n case \"blind\":\n return open ? \"hass:blinds-open\" : \"hass:blinds\";\n case \"window\":\n return open ? \"hass:window-open\" : \"hass:window-closed\";\n default:\n return domainIcon(\"cover\", state.state);\n }\n};\n","/** Return an icon representing an input datetime state. */\nimport { domainIcon } from \"./domain_icons\";\nimport { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const inputDateTimeIcon = (state: HassEntity): string => {\n if (!state.attributes.has_date) {\n return \"hass:clock\";\n }\n if (!state.attributes.has_time) {\n return \"hass:calendar\";\n }\n return domainIcon(\"input_datetime\");\n};\n"],"names":["durationToSeconds","duration","parts","split","map","Number","formatDate","Date","toLocaleDateString","e","name","toLocaleDateStringSupportsOptions","dateObj","locales","year","month","day","fecha","format","formatDateTime","toLocaleString","toLocaleStringSupportsOptions","hour","minute","formatTime","toLocaleTimeString","toLocaleTimeStringSupportsOptions","tests","langKey","relativeTime","localize","options","timeDesc","delta","compareTime","getTime","tense","Math","abs","let","i","length","floor","undefined","includeTense","const","leftPad","num","secondsToDuration","d","h","m","s","timerTimeRemaining","stateObj","timeRemaining","attributes","remaining","state","now","madeActive","last_changed","max","applyThemesOnElement","element","themes","localTheme","updateMeta","_themes","themeName","default_theme","styles","Object","theme","keys","forEach","key","prefixedKey","updateStyles","window","ShadyCSS","styleSubtree","meta","document","querySelector","hasAttribute","setAttribute","getAttribute","themeColor","computeCardSize","card","getCardSize","computeDomain","entityId","substr","indexOf","computeEntity","computeRTL","hass","lang","language","translationMetadata","translations","isRTL","computeRTLDirection","computeStateDomain","entity_id","computeStateDisplay","unit_of_measurement","domain","date","has_time","has_date","getFullYear","getMonth","getDay","device_class","DEFAULT_DOMAIN_ICON","DEFAULT_PANEL","DOMAINS_WITH_CARD","DOMAINS_WITH_MORE_INFO","DOMAINS_HIDE_MORE_INFO","DOMAINS_MORE_INFO_NO_HISTORY","STATES_OFF","DOMAINS_TOGGLE","Set","UNIT_C","UNIT_F","DEFAULT_VIEW_ENTITY_ID","fireEvent","node","type","detail","event","Event","bubbles","cancelable","Boolean","composed","dispatchEvent","SPECIAL_TYPES","DOMAIN_TO_ELEMENT_TYPE","alert","automation","climate","cover","fan","group","input_boolean","input_number","input_select","input_text","light","lock","media_player","remote","scene","script","sensor","timer","switch","vacuum","water_heater","input_datetime","createThing","cardConfig","isRow","_createError","error","config","_createThing","tag","createElement","setConfig","err","console","message","startsWith","has","entity","customElements","get","style","display","setTimeout","whenDefined","then","clearTimeout","debounce","func","wait","immediate","timeout","context","this","callNow","apply","args","fixedIcons","calendar","camera","configurator","conversation","device_tracker","history_graph","homeassistant","homekit","image_processing","mailbox","notify","person","plant","proximity","simple_alarm","sun","updater","weblink","domainIcon","warn","evaluateFilter","filter","value","attribute","operator","match","formatNumber","isNaN","input","Intl","NumberFormat","getDefaultFormatOptions","toString","defaultOptions","minimumFractionDigits","maximumFractionDigits","digits","forwardHaptic","hapticType","navigate","_node","path","replace","history","replaceState","pushState","turnOnOffEntity","turnOn","service","stateDomain","serviceDomain","callService","toggleEntity","includes","states","handleActionConfig","actionConfig","action","confirmation","exemptions","some","user","id","confirm","text","camera_image","navigation_path","url_path","open","service_data","handleAction","double_tap_action","hold_action","tap_action","handleClick","hold","dblClick","haptic","serviceData","hasAction","hasConfigOrEntityChanged","changedProps","forceUpdate","oldHass","hasDoubleClick","turnOnOffEntities","entityIds","domainsToCall","push","getLovelace","root","shadowRoot","ll","lovelace","current_view","___curView","fixedDeviceClassIcons","humidity","illuminance","temperature","pressure","power","signal_strength","domainIcons","binary_sensor","activated","dclass","battery","batteryRound","round","unit","stateIcon","icon"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.umd.js b/dist/index.umd.js index ffbe249..bb9657c 100644 --- a/dist/index.umd.js +++ b/dist/index.umd.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("fecha")):"function"==typeof define&&define.amd?define(["exports","fecha"],t):t(e.customCardHelpers={},e.fecha)}(this,function(e,t){function a(e){var t=e.split(":").map(Number);return 3600*t[0]+60*t[1]+t[2]}t=t&&t.hasOwnProperty("default")?t.default:t;var r=function(){try{(new Date).toLocaleDateString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleDateString(t,{year:"numeric",month:"long",day:"numeric"})}:function(e){return t.format(e,"mediumDate")},n=function(){try{(new Date).toLocaleString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleString(t,{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"haDateTime")},s=function(){try{(new Date).toLocaleTimeString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleTimeString(t,{hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"shortTime")},i=[60,60,24,7],o=["second","minute","hour","day"],c=function(e){return e<10?"0"+e:e};function u(e){return e.substr(0,e.indexOf("."))}function l(e){var t=e.language||"en";return e.translationMetadata.translations[t]&&e.translationMetadata.translations[t].isRTL||!1}function h(e){return u(e.entity_id)}var m="hass:bookmark",f=["closed","locked","off"],d=new Set(["fan","input_boolean","light","switch","group","automation"]),p=function(e,t,a,r){r=r||{},a=null==a?{}:a;var n=new Event(t,{bubbles:void 0===r.bubbles||r.bubbles,cancelable:Boolean(r.cancelable),composed:void 0===r.composed||r.composed});return n.detail=a,e.dispatchEvent(n),n},g=new Set(["call-service","divider","section","weblink","cast","select"]),_={alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"},b={alert:"hass:alert",automation:"hass:playlist-play",calendar:"hass:calendar",camera:"hass:video",climate:"hass:thermostat",configurator:"hass:settings",conversation:"hass:text-to-speech",device_tracker:"hass:account",fan:"hass:fan",group:"hass:google-circles-communities",history_graph:"hass:chart-line",homeassistant:"hass:home-assistant",homekit:"hass:home-automation",image_processing:"hass:image-filter-frames",input_boolean:"hass:drawing",input_datetime:"hass:calendar-clock",input_number:"hass:ray-vertex",input_select:"hass:format-list-bulleted",input_text:"hass:textbox",light:"hass:lightbulb",mailbox:"hass:mailbox",notify:"hass:comment-alert",person:"hass:account",plant:"hass:flower",proximity:"hass:apple-safari",remote:"hass:remote",scene:"hass:google-pages",script:"hass:file-document",sensor:"hass:eye",simple_alarm:"hass:bell",sun:"hass:white-balance-sunny",switch:"hass:flash",timer:"hass:timer",updater:"hass:cloud-upload",vacuum:"hass:robot-vacuum",water_heater:"hass:thermometer",weblink:"hass:open-in-new"};function v(e,t){if(e in b)return b[e];switch(e){case"alarm_control_panel":switch(t){case"armed_home":return"hass:bell-plus";case"armed_night":return"hass:bell-sleep";case"disarmed":return"hass:bell-outline";case"triggered":return"hass:bell-ring";default:return"hass:bell"}case"binary_sensor":return t&&"off"===t?"hass:radiobox-blank":"hass:checkbox-marked-circle";case"cover":return"closed"===t?"hass:window-closed":"hass:window-open";case"lock":return t&&"unlocked"===t?"hass:lock-open":"hass:lock";case"media_player":return t&&"off"!==t&&"idle"!==t?"hass:cast-connected":"hass:cast";case"zwave":switch(t){case"dead":return"hass:emoticon-dead";case"sleeping":return"hass:sleep";case"initializing":return"hass:timer-sand";default:return"hass:z-wave"}default:return console.warn("Unable to find icon for domain "+e+" ("+t+")"),m}}var y=function(e){p(window,"haptic",e)},w=function(e,t,a){void 0===a&&(a=!1),a?history.replaceState(null,"",t):history.pushState(null,"",t),p(window,"location-changed",{replace:a})},k=function(e,t,a){void 0===a&&(a=!0);var r,n=u(t),s="group"===n?"homeassistant":n;switch(n){case"lock":r=a?"unlock":"lock";break;case"cover":r=a?"open_cover":"close_cover";break;default:r=a?"turn_on":"turn_off"}return e.callService(s,r,{entity_id:t})},S=function(e,t){var a=f.includes(e.states[t].state);return k(e,t,a)},D=function(e,t,a,r){if(r||(r={action:"more-info"}),!r.confirmation||r.confirmation.exemptions&&r.confirmation.exemptions.some(function(e){return e.user===t.user.id})||(y("warning"),confirm(r.confirmation.text||"Are you sure you want to "+r.action+"?")))switch(r.action){case"more-info":(a.entity||a.camera_image)&&p(e,"hass-more-info",{entityId:a.entity?a.entity:a.camera_image});break;case"navigate":r.navigation_path&&w(0,r.navigation_path);break;case"url":r.url_path&&window.open(r.url_path);break;case"toggle":a.entity&&(S(t,a.entity),y("success"));break;case"call-service":if(!r.service)return void y("failure");var n=r.service.split(".",2);t.callService(n[0],n[1],r.service_data),y("success");break;case"fire-dom-event":p(e,"ll-custom",r)}},T={humidity:"hass:water-percent",illuminance:"hass:brightness-5",temperature:"hass:thermometer",pressure:"hass:gauge",power:"hass:flash",signal_strength:"hass:wifi"},x={binary_sensor:function(e){var t=e.state&&"off"===e.state;switch(e.attributes.device_class){case"battery":return t?"hass:battery":"hass:battery-outline";case"cold":return t?"hass:thermometer":"hass:snowflake";case"connectivity":return t?"hass:server-network-off":"hass:server-network";case"door":return t?"hass:door-closed":"hass:door-open";case"garage_door":return t?"hass:garage":"hass:garage-open";case"gas":case"power":case"problem":case"safety":case"smoke":return t?"hass:shield-check":"hass:alert";case"heat":return t?"hass:thermometer":"hass:fire";case"light":return t?"hass:brightness-5":"hass:brightness-7";case"lock":return t?"hass:lock":"hass:lock-open";case"moisture":return t?"hass:water-off":"hass:water";case"motion":return t?"hass:walk":"hass:run";case"occupancy":return t?"hass:home-outline":"hass:home";case"opening":return t?"hass:square":"hass:square-outline";case"plug":return t?"hass:power-plug-off":"hass:power-plug";case"presence":return t?"hass:home-outline":"hass:home";case"sound":return t?"hass:music-note-off":"hass:music-note";case"vibration":return t?"hass:crop-portrait":"hass:vibrate";case"window":return t?"hass:window-closed":"hass:window-open";default:return t?"hass:radiobox-blank":"hass:checkbox-marked-circle"}},cover:function(e){var t="closed"!==e.state;switch(e.attributes.device_class){case"garage":return t?"hass:garage-open":"hass:garage";case"door":return t?"hass:door-open":"hass:door-closed";case"shutter":return t?"hass:window-shutter-open":"hass:window-shutter";case"blind":return t?"hass:blinds-open":"hass:blinds";case"window":return t?"hass:window-open":"hass:window-closed";default:return v("cover",e.state)}},sensor:function(e){var t=e.attributes.device_class;if(t&&t in T)return T[t];if("battery"===t){var a=Number(e.state);if(isNaN(a))return"hass:battery-unknown";var r=10*Math.round(a/10);return r>=100?"hass:battery":r<=0?"hass:battery-alert":"hass:battery-"+r}var n=e.attributes.unit_of_measurement;return"°C"===n||"°F"===n?"hass:thermometer":v("sensor")},input_datetime:function(e){return e.attributes.has_date?e.attributes.has_time?v("input_datetime"):"hass:calendar":"hass:clock"}};e.durationToSeconds=a,e.formatDate=r,e.formatDateTime=n,e.formatTime=s,e.relativeTime=function(e,t,a){void 0===a&&(a={});var r,n=((a.compareTime||new Date).getTime()-e.getTime())/1e3,s=n>=0?"past":"future";n=Math.abs(n);for(var c=0;c0?t+":"+c(a)+":"+c(r):a>0?a+":"+c(r):r>0?""+r:null},e.timerTimeRemaining=function(e){var t=a(e.attributes.remaining);if("active"===e.state){var r=(new Date).getTime(),n=new Date(e.last_changed).getTime();t=Math.max(t-(r-n)/1e3,0)}return t},e.applyThemesOnElement=function(e,t,a,r){void 0===r&&(r=!1),e._themes||(e._themes={});var n=t.default_theme;("default"===a||a&&t.themes[a])&&(n=a);var s=Object.assign({},e._themes);if("default"!==n){var i=t.themes[n];Object.keys(i).forEach(function(t){var a="--"+t;e._themes[a]="",s[a]=i[t]})}if(e.updateStyles?e.updateStyles(s):window.ShadyCSS&&window.ShadyCSS.styleSubtree(e,s),r){var o=document.querySelector("meta[name=theme-color]");if(o){o.hasAttribute("default-content")||o.setAttribute("default-content",o.getAttribute("content"));var c=s["--primary-color"]||o.getAttribute("default-content");o.setAttribute("content",c)}}},e.computeCardSize=function(e){return"function"==typeof e.getCardSize?e.getCardSize():4},e.computeDomain=u,e.computeEntity=function(e){return e.substr(e.indexOf(".")+1)},e.computeRTL=l,e.computeRTLDirection=function(e){return l(e)?"rtl":"ltr"},e.computeStateDisplay=function(e,t,a){if("unknown"===t.state||"unavailable"===t.state)return e("state.default."+t.state);if(t.attributes.unit_of_measurement)return t.state+" "+t.attributes.unit_of_measurement;var i=h(t);if("input_datetime"===i){var o;if(!t.attributes.has_time)return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day),r(o,a);if(!t.attributes.has_date){var c=new Date;return o=new Date(c.getFullYear(),c.getMonth(),c.getDay(),t.attributes.hour,t.attributes.minute),s(o,a)}return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day,t.attributes.hour,t.attributes.minute),n(o,a)}return t.attributes.device_class&&e("component."+i+".state."+t.attributes.device_class+"."+t.state)||e("component."+i+".state._."+t.state)||t.state},e.computeStateDomain=h,e.DEFAULT_DOMAIN_ICON=m,e.DEFAULT_PANEL="lovelace",e.DOMAINS_WITH_CARD=["climate","cover","configurator","input_select","input_number","input_text","lock","media_player","scene","script","timer","vacuum","water_heater","weblink"],e.DOMAINS_WITH_MORE_INFO=["alarm_control_panel","automation","camera","climate","configurator","cover","fan","group","history_graph","input_datetime","light","lock","media_player","script","sun","updater","vacuum","water_heater","weather"],e.DOMAINS_HIDE_MORE_INFO=["input_number","input_select","input_text","scene","weblink"],e.DOMAINS_MORE_INFO_NO_HISTORY=["camera","configurator","history_graph","scene"],e.STATES_OFF=f,e.DOMAINS_TOGGLE=d,e.UNIT_C="°C",e.UNIT_F="°F",e.DEFAULT_VIEW_ENTITY_ID="group.default_view",e.createThing=function(e,t){void 0===t&&(t=!1);var a=function(e,t){return r("hui-error-card",{type:"error",error:e,config:t})},r=function(e,t){var r=window.document.createElement(e);try{r.setConfig(t)}catch(r){return console.error(e,r),a(r.message,t)}return r};if(!e||"object"!=typeof e||!t&&!e.type)return a("No type defined",e);var n=e.type;if(n&&n.startsWith("custom:"))n=n.substr("custom:".length);else if(t)if(g.has(n))n="hui-"+n+"-row";else{if(!e.entity)return a("Invalid config given.",e);var s=e.entity.split(".",1)[0];n="hui-"+(_[s]||"text")+"-entity-row"}else n="hui-"+n+"-card";if(customElements.get(n))return r(n,e);var i=a("Custom element doesn't exist: "+e.type+".",e);i.style.display="None";var o=setTimeout(function(){i.style.display=""},2e3);return customElements.whenDefined(e.type).then(function(){clearTimeout(o),p(i,"ll-rebuild",{},i)}),i},e.debounce=function(e,t,a){var r;return void 0===a&&(a=!1),function(){for(var n=[],s=arguments.length;s--;)n[s]=arguments[s];var i=this,o=a&&!r;clearTimeout(r),r=setTimeout(function(){r=null,a||e.apply(i,n)},t),o&&e.apply(i,n)}},e.fixedIcons=b,e.domainIcon=v,e.evaluateFilter=function(e,t){var a=t.value||t,r=t.attribute?e.attributes[t.attribute]:e.state;switch(t.operator||"=="){case"==":return r===a;case"<=":return r<=a;case"<":return r=":return r>=a;case">":return r>a;case"!=":return r!==a;case"regex":return r.match(a);default:return!1}},e.fireEvent=p,e.formatNumber=function(e,t,a){return Number.isNaN=Number.isNaN||function e(t){return"number"==typeof t&&e(t)},!Number.isNaN(Number(e))&&Intl?new Intl.NumberFormat(t,function(e,t){var a=t||{};if("string"!=typeof e)return a;if(!t||!t.minimumFractionDigits&&!t.maximumFractionDigits){var r=e.indexOf(".")>-1?e.split(".")[1].length:0;a.minimumFractionDigits=r,a.maximumFractionDigits=r}return a}(e,a)).format(Number(e)):e.toString()},e.handleActionConfig=D,e.handleAction=function(e,t,a,r){var n;"double_tap"===r&&a.double_tap_action?n=a.double_tap_action:"hold"===r&&a.hold_action?n=a.hold_action:"tap"===r&&a.tap_action&&(n=a.tap_action),D(e,t,a,n)},e.handleClick=function(e,t,a,r,n){var s;if(n&&a.double_tap_action?s=a.double_tap_action:r&&a.hold_action?s=a.hold_action:!r&&a.tap_action&&(s=a.tap_action),s||(s={action:"more-info"}),!s.confirmation||s.confirmation.exemptions&&s.confirmation.exemptions.some(function(e){return e.user===t.user.id})||confirm(s.confirmation.text||"Are you sure you want to "+s.action+"?"))switch(s.action){case"more-info":(s.entity||a.entity||a.camera_image)&&(p(e,"hass-more-info",{entityId:s.entity?s.entity:a.entity?a.entity:a.camera_image}),s.haptic&&y(s.haptic));break;case"navigate":s.navigation_path&&(w(0,s.navigation_path),s.haptic&&y(s.haptic));break;case"url":s.url_path&&window.open(s.url_path),s.haptic&&y(s.haptic);break;case"toggle":a.entity&&(S(t,a.entity),s.haptic&&y(s.haptic));break;case"call-service":if(!s.service)return;var i=s.service.split(".",2),o=i[0],c=i[1],u=Object.assign({},s.service_data);"entity"===u.entity_id&&(u.entity_id=a.entity),t.callService(o,c,u),s.haptic&&y(s.haptic)}},e.forwardHaptic=y,e.hasAction=function(e){return void 0!==e&&"none"!==e.action},e.hasConfigOrEntityChanged=function(e,t,a){if(t.has("config")||a)return!0;if(e.config.entity){var r=t.get("hass");return!r||r.states[e.config.entity]!==e.hass.states[e.config.entity]}return!1},e.hasDoubleClick=function(e){return void 0!==e&&"none"!==e.action},e.navigate=w,e.toggleEntity=S,e.turnOnOffEntities=function(e,t,a){void 0===a&&(a=!0);var r={};t.forEach(function(t){if(f.includes(e.states[t].state)===a){var n=u(t),s=["cover","lock"].includes(n)?n:"homeassistant";s in r||(r[s]=[]),r[s].push(t)}}),Object.keys(r).forEach(function(t){var n;switch(t){case"lock":n=a?"unlock":"lock";break;case"cover":n=a?"open_cover":"close_cover";break;default:n=a?"turn_on":"turn_off"}e.callService(t,n,{entity_id:r[t]})})},e.turnOnOffEntity=k,e.getLovelace=function(){var e=document.querySelector("home-assistant");if(e=(e=(e=(e=(e=(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root")){var t=e.lovelace;return t.current_view=e.___curView,t}return null},e.stateIcon=function(e){if(!e)return m;if(e.attributes.icon)return e.attributes.icon;var t=u(e.entity_id);return t in x?x[t](e):v(t,e.state)}}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("fecha")):"function"==typeof define&&define.amd?define(["exports","fecha"],t):t(e.customCardHelpers={},e.fecha)}(this,function(e,t){function a(e){var t=e.split(":").map(Number);return 3600*t[0]+60*t[1]+t[2]}t=t&&t.hasOwnProperty("default")?t.default:t;var r=function(){try{(new Date).toLocaleDateString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleDateString(t,{year:"numeric",month:"long",day:"numeric"})}:function(e){return t.format(e,"mediumDate")},n=function(){try{(new Date).toLocaleString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleString(t,{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"haDateTime")},s=function(){try{(new Date).toLocaleTimeString("i")}catch(e){return"RangeError"===e.name}return!1}()?function(e,t){return e.toLocaleTimeString(t,{hour:"numeric",minute:"2-digit"})}:function(e){return t.format(e,"shortTime")},i=[60,60,24,7],o=["second","minute","hour","day"],c=function(e){return e<10?"0"+e:e};function u(e){return e.substr(0,e.indexOf("."))}function l(e){var t=e.language||"en";return e.translationMetadata.translations[t]&&e.translationMetadata.translations[t].isRTL||!1}function h(e){return u(e.entity_id)}var m="hass:bookmark",f=["closed","locked","off"],d=new Set(["fan","input_boolean","light","switch","group","automation"]),p=function(e,t,a,r){r=r||{},a=null==a?{}:a;var n=new Event(t,{bubbles:void 0===r.bubbles||r.bubbles,cancelable:Boolean(r.cancelable),composed:void 0===r.composed||r.composed});return n.detail=a,e.dispatchEvent(n),n},g=new Set(["call-service","divider","section","weblink","cast","select"]),b={alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"},v={alert:"hass:alert",automation:"hass:playlist-play",calendar:"hass:calendar",camera:"hass:video",climate:"hass:thermostat",configurator:"hass:settings",conversation:"hass:text-to-speech",device_tracker:"hass:account",fan:"hass:fan",group:"hass:google-circles-communities",history_graph:"hass:chart-line",homeassistant:"hass:home-assistant",homekit:"hass:home-automation",image_processing:"hass:image-filter-frames",input_boolean:"hass:drawing",input_datetime:"hass:calendar-clock",input_number:"hass:ray-vertex",input_select:"hass:format-list-bulleted",input_text:"hass:textbox",light:"hass:lightbulb",mailbox:"hass:mailbox",notify:"hass:comment-alert",person:"hass:account",plant:"hass:flower",proximity:"hass:apple-safari",remote:"hass:remote",scene:"hass:google-pages",script:"hass:file-document",sensor:"hass:eye",simple_alarm:"hass:bell",sun:"hass:white-balance-sunny",switch:"hass:flash",timer:"hass:timer",updater:"hass:cloud-upload",vacuum:"hass:robot-vacuum",water_heater:"hass:thermometer",weblink:"hass:open-in-new"};function _(e,t){if(e in v)return v[e];switch(e){case"alarm_control_panel":switch(t){case"armed_home":return"hass:bell-plus";case"armed_night":return"hass:bell-sleep";case"disarmed":return"hass:bell-outline";case"triggered":return"hass:bell-ring";default:return"hass:bell"}case"binary_sensor":return t&&"off"===t?"hass:radiobox-blank":"hass:checkbox-marked-circle";case"cover":return"closed"===t?"hass:window-closed":"hass:window-open";case"lock":return t&&"unlocked"===t?"hass:lock-open":"hass:lock";case"media_player":return t&&"off"!==t&&"idle"!==t?"hass:cast-connected":"hass:cast";case"zwave":switch(t){case"dead":return"hass:emoticon-dead";case"sleeping":return"hass:sleep";case"initializing":return"hass:timer-sand";default:return"hass:z-wave"}default:return console.warn("Unable to find icon for domain "+e+" ("+t+")"),m}}var y=function(e){p(window,"haptic",e)},w=function(e,t,a){void 0===a&&(a=!1),a?history.replaceState(null,"",t):history.pushState(null,"",t),p(window,"location-changed",{replace:a})},k=function(e,t,a){void 0===a&&(a=!0);var r,n=u(t),s="group"===n?"homeassistant":n;switch(n){case"lock":r=a?"unlock":"lock";break;case"cover":r=a?"open_cover":"close_cover";break;default:r=a?"turn_on":"turn_off"}return e.callService(s,r,{entity_id:t})},S=function(e,t){var a=f.includes(e.states[t].state);return k(e,t,a)},D=function(e,t,a,r){if(r||(r={action:"more-info"}),!r.confirmation||r.confirmation.exemptions&&r.confirmation.exemptions.some(function(e){return e.user===t.user.id})||(y("warning"),confirm(r.confirmation.text||"Are you sure you want to "+r.action+"?")))switch(r.action){case"more-info":(a.entity||a.camera_image)&&p(e,"hass-more-info",{entityId:a.entity?a.entity:a.camera_image});break;case"navigate":r.navigation_path&&w(0,r.navigation_path);break;case"url":r.url_path&&window.open(r.url_path);break;case"toggle":a.entity&&(S(t,a.entity),y("success"));break;case"call-service":if(!r.service)return void y("failure");var n=r.service.split(".",2);t.callService(n[0],n[1],r.service_data),y("success");break;case"fire-dom-event":p(e,"ll-custom",r)}},T={humidity:"hass:water-percent",illuminance:"hass:brightness-5",temperature:"hass:thermometer",pressure:"hass:gauge",power:"hass:flash",signal_strength:"hass:wifi"},x={binary_sensor:function(e){var t=e.state&&"off"===e.state;switch(e.attributes.device_class){case"battery":return t?"hass:battery":"hass:battery-outline";case"cold":return t?"hass:thermometer":"hass:snowflake";case"connectivity":return t?"hass:server-network-off":"hass:server-network";case"door":return t?"hass:door-closed":"hass:door-open";case"garage_door":return t?"hass:garage":"hass:garage-open";case"gas":case"power":case"problem":case"safety":case"smoke":return t?"hass:shield-check":"hass:alert";case"heat":return t?"hass:thermometer":"hass:fire";case"light":return t?"hass:brightness-5":"hass:brightness-7";case"lock":return t?"hass:lock":"hass:lock-open";case"moisture":return t?"hass:water-off":"hass:water";case"motion":return t?"hass:walk":"hass:run";case"occupancy":return t?"hass:home-outline":"hass:home";case"opening":return t?"hass:square":"hass:square-outline";case"plug":return t?"hass:power-plug-off":"hass:power-plug";case"presence":return t?"hass:home-outline":"hass:home";case"sound":return t?"hass:music-note-off":"hass:music-note";case"vibration":return t?"hass:crop-portrait":"hass:vibrate";case"window":return t?"hass:window-closed":"hass:window-open";default:return t?"hass:radiobox-blank":"hass:checkbox-marked-circle"}},cover:function(e){var t="closed"!==e.state;switch(e.attributes.device_class){case"garage":return t?"hass:garage-open":"hass:garage";case"door":return t?"hass:door-open":"hass:door-closed";case"shutter":return t?"hass:window-shutter-open":"hass:window-shutter";case"blind":return t?"hass:blinds-open":"hass:blinds";case"window":return t?"hass:window-open":"hass:window-closed";default:return _("cover",e.state)}},sensor:function(e){var t=e.attributes.device_class;if(t&&t in T)return T[t];if("battery"===t){var a=Number(e.state);if(isNaN(a))return"hass:battery-unknown";var r=10*Math.round(a/10);return r>=100?"hass:battery":r<=0?"hass:battery-alert":"hass:battery-"+r}var n=e.attributes.unit_of_measurement;return"°C"===n||"°F"===n?"hass:thermometer":_("sensor")},input_datetime:function(e){return e.attributes.has_date?e.attributes.has_time?_("input_datetime"):"hass:calendar":"hass:clock"}};e.durationToSeconds=a,e.formatDate=r,e.formatDateTime=n,e.formatTime=s,e.relativeTime=function(e,t,a){void 0===a&&(a={});var r,n=((a.compareTime||new Date).getTime()-e.getTime())/1e3,s=n>=0?"past":"future";n=Math.abs(n);for(var c=0;c0?t+":"+c(a)+":"+c(r):a>0?a+":"+c(r):r>0?""+r:null},e.timerTimeRemaining=function(e){var t=a(e.attributes.remaining);if("active"===e.state){var r=(new Date).getTime(),n=new Date(e.last_changed).getTime();t=Math.max(t-(r-n)/1e3,0)}return t},e.applyThemesOnElement=function(e,t,a,r){void 0===r&&(r=!1),e._themes||(e._themes={});var n=t.default_theme;("default"===a||a&&t.themes[a])&&(n=a);var s=Object.assign({},e._themes);if("default"!==n){var i=t.themes[n];Object.keys(i).forEach(function(t){var a="--"+t;e._themes[a]="",s[a]=i[t]})}if(e.updateStyles?e.updateStyles(s):window.ShadyCSS&&window.ShadyCSS.styleSubtree(e,s),r){var o=document.querySelector("meta[name=theme-color]");if(o){o.hasAttribute("default-content")||o.setAttribute("default-content",o.getAttribute("content"));var c=s["--primary-color"]||o.getAttribute("default-content");o.setAttribute("content",c)}}},e.computeCardSize=function(e){return"function"==typeof e.getCardSize?e.getCardSize():4},e.computeDomain=u,e.computeEntity=function(e){return e.substr(e.indexOf(".")+1)},e.computeRTL=l,e.computeRTLDirection=function(e){return l(e)?"rtl":"ltr"},e.computeStateDisplay=function(e,t,a){if("unknown"===t.state||"unavailable"===t.state)return e("state.default."+t.state);if(t.attributes.unit_of_measurement)return t.state+" "+t.attributes.unit_of_measurement;var i=h(t);if("input_datetime"===i){var o;if(!t.attributes.has_time)return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day),r(o,a);if(!t.attributes.has_date){var c=new Date;return o=new Date(c.getFullYear(),c.getMonth(),c.getDay(),t.attributes.hour,t.attributes.minute),s(o,a)}return o=new Date(t.attributes.year,t.attributes.month-1,t.attributes.day,t.attributes.hour,t.attributes.minute),n(o,a)}return t.attributes.device_class&&e("component."+i+".state."+t.attributes.device_class+"."+t.state)||e("component."+i+".state._."+t.state)||t.state},e.computeStateDomain=h,e.DEFAULT_DOMAIN_ICON=m,e.DEFAULT_PANEL="lovelace",e.DOMAINS_WITH_CARD=["climate","cover","configurator","input_select","input_number","input_text","lock","media_player","scene","script","timer","vacuum","water_heater","weblink"],e.DOMAINS_WITH_MORE_INFO=["alarm_control_panel","automation","camera","climate","configurator","cover","fan","group","history_graph","input_datetime","light","lock","media_player","script","sun","updater","vacuum","water_heater","weather"],e.DOMAINS_HIDE_MORE_INFO=["input_number","input_select","input_text","scene","weblink"],e.DOMAINS_MORE_INFO_NO_HISTORY=["camera","configurator","history_graph","scene"],e.STATES_OFF=f,e.DOMAINS_TOGGLE=d,e.UNIT_C="°C",e.UNIT_F="°F",e.DEFAULT_VIEW_ENTITY_ID="group.default_view",e.createThing=function(e,t){void 0===t&&(t=!1);var a=function(e,t){return r("hui-error-card",{type:"error",error:e,config:t})},r=function(e,t){var r=window.document.createElement(e);try{r.setConfig(t)}catch(r){return console.error(e,r),a(r.message,t)}return r};if(!e||"object"!=typeof e||!t&&!e.type)return a("No type defined",e);var n=e.type;if(n&&n.startsWith("custom:"))n=n.substr("custom:".length);else if(t)if(g.has(n))n="hui-"+n+"-row";else{if(!e.entity)return a("Invalid config given.",e);var s=e.entity.split(".",1)[0];n="hui-"+(b[s]||"text")+"-entity-row"}else n="hui-"+n+"-card";if(customElements.get(n))return r(n,e);var i=a("Custom element doesn't exist: "+e.type+".",e);i.style.display="None";var o=setTimeout(function(){i.style.display=""},2e3);return customElements.whenDefined(e.type).then(function(){clearTimeout(o),p(i,"ll-rebuild",{},i)}),i},e.debounce=function(e,t,a){var r;return void 0===a&&(a=!1),function(){for(var n=[],s=arguments.length;s--;)n[s]=arguments[s];var i=this,o=a&&!r;clearTimeout(r),r=setTimeout(function(){r=null,a||e.apply(i,n)},t),o&&e.apply(i,n)}},e.fixedIcons=v,e.domainIcon=_,e.evaluateFilter=function(e,t){var a=t.value||t,r=t.attribute?e.attributes[t.attribute]:e.state;switch(t.operator||"=="){case"==":return r===a;case"<=":return r<=a;case"<":return r=":return r>=a;case">":return r>a;case"!=":return r!==a;case"regex":return r.match(a);default:return!1}},e.fireEvent=p,e.formatNumber=function(e,t,a){return Number.isNaN=Number.isNaN||function e(t){return"number"==typeof t&&e(t)},!Number.isNaN(Number(e))&&Intl?new Intl.NumberFormat(t,function(e,t){var a=t||{};if("string"!=typeof e)return a;if(!t||!t.minimumFractionDigits&&!t.maximumFractionDigits){var r=e.indexOf(".")>-1?e.split(".")[1].length:0;a.minimumFractionDigits=r,a.maximumFractionDigits=r}return a}(e,a)).format(Number(e)):e.toString()},e.handleActionConfig=D,e.handleAction=function(e,t,a,r){var n;"double_tap"===r&&a.double_tap_action?n=a.double_tap_action:"hold"===r&&a.hold_action?n=a.hold_action:"tap"===r&&a.tap_action&&(n=a.tap_action),D(e,t,a,n)},e.handleClick=function(e,t,a,r,n){var s;if(n&&a.double_tap_action?s=a.double_tap_action:r&&a.hold_action?s=a.hold_action:!r&&a.tap_action&&(s=a.tap_action),s||(s={action:"more-info"}),!s.confirmation||s.confirmation.exemptions&&s.confirmation.exemptions.some(function(e){return e.user===t.user.id})||confirm(s.confirmation.text||"Are you sure you want to "+s.action+"?"))switch(s.action){case"more-info":(s.entity||a.entity||a.camera_image)&&(p(e,"hass-more-info",{entityId:s.entity?s.entity:a.entity?a.entity:a.camera_image}),s.haptic&&y(s.haptic));break;case"navigate":s.navigation_path&&(w(0,s.navigation_path),s.haptic&&y(s.haptic));break;case"url":s.url_path&&window.open(s.url_path),s.haptic&&y(s.haptic);break;case"toggle":a.entity&&(S(t,a.entity),s.haptic&&y(s.haptic));break;case"call-service":if(!s.service)return;var i=s.service.split(".",2),o=i[0],c=i[1],u=Object.assign({},s.service_data);"entity"===u.entity_id&&(u.entity_id=a.entity),t.callService(o,c,u),s.haptic&&y(s.haptic);break;case"fire-dom-event":p(e,"ll-custom",s),s.haptic&&y(s.haptic)}},e.forwardHaptic=y,e.hasAction=function(e){return void 0!==e&&"none"!==e.action},e.hasConfigOrEntityChanged=function(e,t,a){if(t.has("config")||a)return!0;if(e.config.entity){var r=t.get("hass");return!r||r.states[e.config.entity]!==e.hass.states[e.config.entity]}return!1},e.hasDoubleClick=function(e){return void 0!==e&&"none"!==e.action},e.navigate=w,e.toggleEntity=S,e.turnOnOffEntities=function(e,t,a){void 0===a&&(a=!0);var r={};t.forEach(function(t){if(f.includes(e.states[t].state)===a){var n=u(t),s=["cover","lock"].includes(n)?n:"homeassistant";s in r||(r[s]=[]),r[s].push(t)}}),Object.keys(r).forEach(function(t){var n;switch(t){case"lock":n=a?"unlock":"lock";break;case"cover":n=a?"open_cover":"close_cover";break;default:n=a?"turn_on":"turn_off"}e.callService(t,n,{entity_id:r[t]})})},e.turnOnOffEntity=k,e.getLovelace=function(){var e=document.querySelector("home-assistant");if(e=(e=(e=(e=(e=(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root")){var t=e.lovelace;return t.current_view=e.___curView,t}return null},e.stateIcon=function(e){if(!e)return m;if(e.attributes.icon)return e.attributes.icon;var t=u(e.entity_id);return t in x?x[t](e):_(t,e.state)}}); //# sourceMappingURL=index.umd.js.map diff --git a/dist/index.umd.js.map b/dist/index.umd.js.map index 8da272d..627832d 100644 --- a/dist/index.umd.js.map +++ b/dist/index.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"index.umd.js","sources":["../src/datetime/duration_to_seconds.ts","../src/datetime/format_date.ts","../src/datetime/format_date_time.ts","../src/datetime/format_time.ts","../src/datetime/relative_time.ts","../src/datetime/seconds_to_duration.ts","../src/compute-domain.ts","../src/compute-rtl.ts","../src/compute-state-domain.ts","../src/const.ts","../src/fire-event.ts","../src/create-thing.ts","../src/domain_icons.ts","../src/haptic.ts","../src/navigate.ts","../src/turn-on-off-entity.ts","../src/toggle-entity.ts","../src/handle-action.ts","../src/sensor_icon.ts","../src/state_icon.ts","../src/binary_sensor_icon.ts","../src/cover_icon.ts","../src/input_datetime_icon.ts","../src/datetime/timer_time_remaining.ts","../src/apply_themes_on_element.ts","../src/compute-card-size.ts","../src/compute-entity.ts","../src/compute-state-display.ts","../src/debounce.ts","../src/evaluate-filter.ts","../src/format-number.ts","../src/handle-click.ts","../src/has-action.ts","../src/has-changed.ts","../src/has-double-click.ts","../src/turn-on-off-entities.ts","../src/get-lovelace.ts"],"sourcesContent":["export function durationToSeconds(duration: string): number {\n const parts = duration.split(\":\").map(Number);\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n}\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleDateStringSupportsOptions() {\n try {\n new Date().toLocaleDateString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDate = (toLocaleDateStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleDateString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"mediumDate\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleStringSupportsOptions() {\n try {\n new Date().toLocaleString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDateTime = (toLocaleStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"haDateTime\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleTimeStringSupportsOptions() {\n try {\n new Date().toLocaleTimeString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatTime = (toLocaleTimeStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleTimeString(locales, {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"shortTime\"));\n","import { LocalizeFunc } from \"../translations/localize\";\n\n/**\n * Calculate a string representing a date object as relative time from now.\n *\n * Example output: 5 minutes ago, in 3 days.\n */\nconst tests = [60, 60, 24, 7];\nconst langKey = [\"second\", \"minute\", \"hour\", \"day\"];\n\nexport function relativeTime(\n dateObj: Date,\n localize: LocalizeFunc,\n options: {\n compareTime?: Date;\n includeTense?: boolean;\n } = {}\n): string {\n const compareTime = options.compareTime || new Date();\n let delta = (compareTime.getTime() - dateObj.getTime()) / 1000;\n const tense = delta >= 0 ? \"past\" : \"future\";\n delta = Math.abs(delta);\n\n let timeDesc;\n\n for (let i = 0; i < tests.length; i++) {\n if (delta < tests[i]) {\n delta = Math.floor(delta);\n timeDesc = localize(\n `ui.components.relative_time.duration.${langKey[i]}`,\n \"count\",\n delta\n );\n break;\n }\n\n delta /= tests[i];\n }\n\n if (timeDesc === undefined) {\n delta = Math.floor(delta);\n timeDesc = localize(\n \"ui.components.relative_time.duration.week\",\n \"count\",\n delta\n );\n }\n\n return options.includeTense === false\n ? timeDesc\n : localize(`ui.components.relative_time.${tense}`, \"time\", timeDesc);\n}\n","const leftPad = (num: number) => (num < 10 ? `0${num}` : num);\n\nexport function secondsToDuration(d: number) {\n const h = Math.floor(d / 3600);\n const m = Math.floor((d % 3600) / 60);\n const s = Math.floor((d % 3600) % 60);\n\n if (h > 0) {\n return `${h}:${leftPad(m)}:${leftPad(s)}`;\n }\n if (m > 0) {\n return `${m}:${leftPad(s)}`;\n }\n if (s > 0) {\n return \"\" + s;\n }\n return null;\n}\n","export function computeDomain(entityId: string): string {\n return entityId.substr(0, entityId.indexOf(\".\"));\n}\n","import { HomeAssistant } from \"./types\";\n\nexport function computeRTL(hass: HomeAssistant) {\n const lang = hass.language || \"en\";\n if (hass.translationMetadata.translations[lang]) {\n return hass.translationMetadata.translations[lang].isRTL || false;\n }\n return false;\n}\n\nexport function computeRTLDirection(hass: HomeAssistant) {\n return computeRTL(hass) ? \"rtl\" : \"ltr\";\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport function computeStateDomain(stateObj: HassEntity) {\n return computeDomain(stateObj.entity_id);\n}\n","/** Constants to be used in the frontend. */\n\n// Constants should be alphabetically sorted by name.\n// Arrays with values should be alphabetically sorted if order doesn't matter.\n// Each constant should have a description what it is supposed to be used for.\n\n/** Icon to use when no icon specified for domain. */\nexport const DEFAULT_DOMAIN_ICON = \"hass:bookmark\";\n\n/** Panel to show when no panel is picked. */\nexport const DEFAULT_PANEL = \"lovelace\";\n\n/** Domains that have a state card. */\nexport const DOMAINS_WITH_CARD = [\n \"climate\",\n \"cover\",\n \"configurator\",\n \"input_select\",\n \"input_number\",\n \"input_text\",\n \"lock\",\n \"media_player\",\n \"scene\",\n \"script\",\n \"timer\",\n \"vacuum\",\n \"water_heater\",\n \"weblink\"\n];\n\n/** Domains with separate more info dialog. */\nexport const DOMAINS_WITH_MORE_INFO = [\n \"alarm_control_panel\",\n \"automation\",\n \"camera\",\n \"climate\",\n \"configurator\",\n \"cover\",\n \"fan\",\n \"group\",\n \"history_graph\",\n \"input_datetime\",\n \"light\",\n \"lock\",\n \"media_player\",\n \"script\",\n \"sun\",\n \"updater\",\n \"vacuum\",\n \"water_heater\",\n \"weather\"\n];\n\n/** Domains that show no more info dialog. */\nexport const DOMAINS_HIDE_MORE_INFO = [\n \"input_number\",\n \"input_select\",\n \"input_text\",\n \"scene\",\n \"weblink\"\n];\n\n/** Domains that should have the history hidden in the more info dialog. */\nexport const DOMAINS_MORE_INFO_NO_HISTORY = [\n \"camera\",\n \"configurator\",\n \"history_graph\",\n \"scene\"\n];\n\n/** States that we consider \"off\". */\nexport const STATES_OFF = [\"closed\", \"locked\", \"off\"];\n\n/** Domains where we allow toggle in Lovelace. */\nexport const DOMAINS_TOGGLE = new Set([\n \"fan\",\n \"input_boolean\",\n \"light\",\n \"switch\",\n \"group\",\n \"automation\"\n]);\n\n/** Temperature units. */\nexport const UNIT_C = \"°C\";\nexport const UNIT_F = \"°F\";\n\n/** Entity ID of the default view. */\nexport const DEFAULT_VIEW_ENTITY_ID = \"group.default_view\";\n","// Polymer legacy event helpers used courtesy of the Polymer project.\n//\n// Copyright (c) 2017 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\ndeclare global {\n // tslint:disable-next-line\n interface HASSDomEvents {}\n}\n\nexport type ValidHassDomEvent = keyof HASSDomEvents;\n\nexport interface HASSDomEvent extends Event {\n detail: T;\n}\n\n/**\n * Dispatches a custom event with an optional detail value.\n *\n * @param {string} type Name of event type.\n * @param {*=} detail Detail value containing event-specific\n * payload.\n * @param {{ bubbles: (boolean|undefined),\n * cancelable: (boolean|undefined),\n * composed: (boolean|undefined) }=}\n * options Object specifying options. These may include:\n * `bubbles` (boolean, defaults to `true`),\n * `cancelable` (boolean, defaults to false), and\n * `node` on which to fire the event (HTMLElement, defaults to `this`).\n * @return {Event} The new event that was fired.\n */\nexport const fireEvent = (\n node: HTMLElement | Window,\n type: HassEvent,\n detail?: HASSDomEvents[HassEvent],\n options?: {\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n }\n) => {\n options = options || {};\n // @ts-ignore\n detail = detail === null || detail === undefined ? {} : detail;\n const event = new Event(type, {\n bubbles: options.bubbles === undefined ? true : options.bubbles,\n cancelable: Boolean(options.cancelable),\n composed: options.composed === undefined ? true : options.composed\n });\n (event as any).detail = detail;\n node.dispatchEvent(event);\n return event;\n};\n","import { fireEvent } from \"./fire-event\";\n\nconst SPECIAL_TYPES = new Set([\n \"call-service\",\n \"divider\",\n \"section\",\n \"weblink\",\n \"cast\",\n \"select\"\n]);\nconst DOMAIN_TO_ELEMENT_TYPE = {\n alert: \"toggle\",\n automation: \"toggle\",\n climate: \"climate\",\n cover: \"cover\",\n fan: \"toggle\",\n group: \"group\",\n input_boolean: \"toggle\",\n input_number: \"input-number\",\n input_select: \"input-select\",\n input_text: \"input-text\",\n light: \"toggle\",\n lock: \"lock\",\n media_player: \"media-player\",\n remote: \"toggle\",\n scene: \"scene\",\n script: \"script\",\n sensor: \"sensor\",\n timer: \"timer\",\n switch: \"toggle\",\n vacuum: \"toggle\",\n // Temporary. Once climate is rewritten,\n // water heater should get it's own row.\n water_heater: \"climate\",\n input_datetime: \"input-datetime\"\n};\n\nexport const createThing = (cardConfig, isRow = false) => {\n const _createError = (error, config) => {\n return _createThing(\n \"hui-error-card\",\n {\n type: \"error\",\n error,\n config\n }\n );\n };\n\n const _createThing = (tag, config) => {\n const element = window.document.createElement(tag);\n try {\n element.setConfig(config);\n } catch (err) {\n console.error(tag, err);\n return _createError(err.message, config);\n }\n return element;\n };\n\n if (!cardConfig || typeof cardConfig !== \"object\" || (!isRow && !cardConfig.type))\n return _createError(\"No type defined\", cardConfig);\n let tag = cardConfig.type;\n if (tag && tag.startsWith(\"custom:\")) {\n tag = tag.substr(\"custom:\".length);\n } else if (isRow) {\n if (SPECIAL_TYPES.has(tag)) {\n tag = `hui-${tag}-row`;\n } else {\n if (!cardConfig.entity) {\n return _createError(\"Invalid config given.\", cardConfig);\n }\n \n const domain = cardConfig.entity.split(\".\", 1)[0];\n tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || \"text\"}-entity-row`;\n }\n } else {\n tag = `hui-${tag}-card`;\n }\n\n if (customElements.get(tag)) return _createThing(tag, cardConfig);\n\n // If element doesn't exist (yet) create an error\n const element = _createError(\n `Custom element doesn't exist: ${cardConfig.type}.`,\n cardConfig\n );\n element.style.display = \"None\";\n const timer = setTimeout(() => {\n element.style.display = \"\";\n }, 2000);\n // Remove error if element is defined later\n customElements.whenDefined(cardConfig.type).then(() => {\n clearTimeout(timer);\n fireEvent(element, \"ll-rebuild\", {}, element);\n });\n\n return element;\n};\n","/**\n * Return the icon to be used for a domain.\n *\n * Optionally pass in a state to influence the domain icon.\n */\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\n\nexport const fixedIcons = {\n alert: \"hass:alert\",\n automation: \"hass:playlist-play\",\n calendar: \"hass:calendar\",\n camera: \"hass:video\",\n climate: \"hass:thermostat\",\n configurator: \"hass:settings\",\n conversation: \"hass:text-to-speech\",\n device_tracker: \"hass:account\",\n fan: \"hass:fan\",\n group: \"hass:google-circles-communities\",\n history_graph: \"hass:chart-line\",\n homeassistant: \"hass:home-assistant\",\n homekit: \"hass:home-automation\",\n image_processing: \"hass:image-filter-frames\",\n input_boolean: \"hass:drawing\",\n input_datetime: \"hass:calendar-clock\",\n input_number: \"hass:ray-vertex\",\n input_select: \"hass:format-list-bulleted\",\n input_text: \"hass:textbox\",\n light: \"hass:lightbulb\",\n mailbox: \"hass:mailbox\",\n notify: \"hass:comment-alert\",\n person: \"hass:account\",\n plant: \"hass:flower\",\n proximity: \"hass:apple-safari\",\n remote: \"hass:remote\",\n scene: \"hass:google-pages\",\n script: \"hass:file-document\",\n sensor: \"hass:eye\",\n simple_alarm: \"hass:bell\",\n sun: \"hass:white-balance-sunny\",\n switch: \"hass:flash\",\n timer: \"hass:timer\",\n updater: \"hass:cloud-upload\",\n vacuum: \"hass:robot-vacuum\",\n water_heater: \"hass:thermometer\",\n weblink: \"hass:open-in-new\"\n};\n\nexport function domainIcon(domain: string, state?: string): string {\n if (domain in fixedIcons) {\n return fixedIcons[domain];\n }\n\n switch (domain) {\n case \"alarm_control_panel\":\n switch (state) {\n case \"armed_home\":\n return \"hass:bell-plus\";\n case \"armed_night\":\n return \"hass:bell-sleep\";\n case \"disarmed\":\n return \"hass:bell-outline\";\n case \"triggered\":\n return \"hass:bell-ring\";\n default:\n return \"hass:bell\";\n }\n\n case \"binary_sensor\":\n return state && state === \"off\"\n ? \"hass:radiobox-blank\"\n : \"hass:checkbox-marked-circle\";\n\n case \"cover\":\n return state === \"closed\" ? \"hass:window-closed\" : \"hass:window-open\";\n\n case \"lock\":\n return state && state === \"unlocked\" ? \"hass:lock-open\" : \"hass:lock\";\n\n case \"media_player\":\n return state && state !== \"off\" && state !== \"idle\"\n ? \"hass:cast-connected\"\n : \"hass:cast\";\n\n case \"zwave\":\n switch (state) {\n case \"dead\":\n return \"hass:emoticon-dead\";\n case \"sleeping\":\n return \"hass:sleep\";\n case \"initializing\":\n return \"hass:timer-sand\";\n default:\n return \"hass:z-wave\";\n }\n\n default:\n // tslint:disable-next-line\n console.warn(\n \"Unable to find icon for domain \" + domain + \" (\" + state + \")\"\n );\n return DEFAULT_DOMAIN_ICON;\n }\n}\n","import { HASSDomEvent, fireEvent } from \"./fire-event\";\n\n/**\n * Broadcast haptic feedback requests\n */\n\n\n// Allowed types are from iOS HIG.\n// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics\n// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible.\nexport type HapticType =\n | \"success\"\n | \"warning\"\n | \"failure\"\n | \"light\"\n | \"medium\"\n | \"heavy\"\n | \"selection\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n haptic: HapticType;\n }\n\n interface GlobalEventHandlersEventMap {\n haptic: HASSDomEvent;\n }\n}\n\nexport const forwardHaptic = (hapticType: HapticType) => {\n fireEvent(window, \"haptic\", hapticType);\n};\n","import { fireEvent } from \"./fire-event\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n \"location-changed\": {\n replace: boolean;\n };\n }\n}\n\nexport const navigate = (\n _node: any,\n path: string,\n replace: boolean = false\n) => {\n if (replace) {\n history.replaceState(null, \"\", path);\n } else {\n history.pushState(null, \"\", path);\n }\n fireEvent(window, \"location-changed\", {\n replace\n });\n};\n","import { HomeAssistant } from \"./types\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntity = (\n hass: HomeAssistant,\n entityId: string,\n turnOn = true\n): Promise => {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = stateDomain === \"group\" ? \"homeassistant\" : stateDomain;\n\n let service;\n switch (stateDomain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n return hass.callService(serviceDomain, service, { entity_id: entityId });\n};\n","import { STATES_OFF } from \"./const\";\nimport { turnOnOffEntity } from \"./turn-on-off-entity\";\nimport { HomeAssistant } from \"./types\";\n\nexport const toggleEntity = (\n hass: HomeAssistant,\n entityId: string\n): Promise => {\n const turnOn = STATES_OFF.includes(hass.states[entityId].state);\n return turnOnOffEntity(hass, entityId, turnOn);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { forwardHaptic } from \"./haptic\";\nimport { fireEvent } from \"./fire-event\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleActionConfig = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n actionConfig: ActionConfig | undefined\n): void => {\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\",\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n (e) => e.user === hass!.user!.id\n ))\n ) {\n forwardHaptic(\"warning\");\n\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: config.entity ? config.entity : config.camera_image!,\n });\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n }\n break;\n case \"url\":\n if (actionConfig.url_path) {\n window.open(actionConfig.url_path);\n }\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n forwardHaptic(\"success\");\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n forwardHaptic(\"failure\");\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n hass.callService(domain, service, actionConfig.service_data);\n forwardHaptic(\"success\");\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n }\n }\n};\n\nexport const handleAction = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n action: string\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (action === \"double_tap\" && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (action === \"hold\" && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (action === \"tap\" && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n handleActionConfig(node, hass, config, actionConfig);\n};\n","/** Return an icon representing a sensor state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { UNIT_C, UNIT_F } from \"./const\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst fixedDeviceClassIcons = {\n humidity: \"hass:water-percent\",\n illuminance: \"hass:brightness-5\",\n temperature: \"hass:thermometer\",\n pressure: \"hass:gauge\",\n power: \"hass:flash\",\n signal_strength: \"hass:wifi\",\n};\n\nexport const sensorIcon = (state: HassEntity) => {\n const dclass = state.attributes.device_class;\n\n if (dclass && dclass in fixedDeviceClassIcons) {\n return fixedDeviceClassIcons[dclass];\n }\n if (dclass === \"battery\") {\n const battery = Number(state.state);\n if (isNaN(battery)) {\n return \"hass:battery-unknown\";\n }\n const batteryRound = Math.round(battery / 10) * 10;\n if (batteryRound >= 100) {\n return \"hass:battery\";\n }\n if (batteryRound <= 0) {\n return \"hass:battery-alert\";\n }\n // Will return one of the following icons: (listed so extractor picks up)\n // hass:battery-10\n // hass:battery-20\n // hass:battery-30\n // hass:battery-40\n // hass:battery-50\n // hass:battery-60\n // hass:battery-70\n // hass:battery-80\n // hass:battery-90\n // We obscure 'hass' in iconname so this name does not get picked up\n return `${\"hass\"}:battery-${batteryRound}`;\n }\n\n const unit = state.attributes.unit_of_measurement;\n if (unit === UNIT_C || unit === UNIT_F) {\n return \"hass:thermometer\";\n }\n return domainIcon(\"sensor\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\nimport { binarySensorIcon } from \"./binary_sensor_icon\";\nimport { coverIcon } from \"./cover_icon\";\nimport { sensorIcon } from \"./sensor_icon\";\nimport { inputDateTimeIcon } from \"./input_datetime_icon\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst domainIcons = {\n binary_sensor: binarySensorIcon,\n cover: coverIcon,\n sensor: sensorIcon,\n input_datetime: inputDateTimeIcon,\n};\n\nexport const stateIcon = (state: HassEntity) => {\n if (!state) {\n return DEFAULT_DOMAIN_ICON;\n }\n if (state.attributes.icon) {\n return state.attributes.icon;\n }\n\n const domain = computeDomain(state.entity_id);\n\n if (domain in domainIcons) {\n return domainIcons[domain](state);\n }\n return domainIcon(domain, state.state);\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\n/** Return an icon representing a binary sensor state. */\n\nexport const binarySensorIcon = (state: HassEntity) => {\n const activated = state.state && state.state === \"off\";\n switch (state.attributes.device_class) {\n case \"battery\":\n return activated ? \"hass:battery\" : \"hass:battery-outline\";\n case \"cold\":\n return activated ? \"hass:thermometer\" : \"hass:snowflake\";\n case \"connectivity\":\n return activated ? \"hass:server-network-off\" : \"hass:server-network\";\n case \"door\":\n return activated ? \"hass:door-closed\" : \"hass:door-open\";\n case \"garage_door\":\n return activated ? \"hass:garage\" : \"hass:garage-open\";\n case \"gas\":\n case \"power\":\n case \"problem\":\n case \"safety\":\n case \"smoke\":\n return activated ? \"hass:shield-check\" : \"hass:alert\";\n case \"heat\":\n return activated ? \"hass:thermometer\" : \"hass:fire\";\n case \"light\":\n return activated ? \"hass:brightness-5\" : \"hass:brightness-7\";\n case \"lock\":\n return activated ? \"hass:lock\" : \"hass:lock-open\";\n case \"moisture\":\n return activated ? \"hass:water-off\" : \"hass:water\";\n case \"motion\":\n return activated ? \"hass:walk\" : \"hass:run\";\n case \"occupancy\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"opening\":\n return activated ? \"hass:square\" : \"hass:square-outline\";\n case \"plug\":\n return activated ? \"hass:power-plug-off\" : \"hass:power-plug\";\n case \"presence\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"sound\":\n return activated ? \"hass:music-note-off\" : \"hass:music-note\";\n case \"vibration\":\n return activated ? \"hass:crop-portrait\" : \"hass:vibrate\";\n case \"window\":\n return activated ? \"hass:window-closed\" : \"hass:window-open\";\n default:\n return activated ? \"hass:radiobox-blank\" : \"hass:checkbox-marked-circle\";\n }\n};\n","/** Return an icon representing a cover state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { domainIcon } from \"./domain_icons\";\n\nexport const coverIcon = (state: HassEntity): string => {\n const open = state.state !== \"closed\";\n switch (state.attributes.device_class) {\n case \"garage\":\n return open ? \"hass:garage-open\" : \"hass:garage\";\n case \"door\":\n return open ? \"hass:door-open\" : \"hass:door-closed\";\n case \"shutter\":\n return open ? \"hass:window-shutter-open\" : \"hass:window-shutter\";\n case \"blind\":\n return open ? \"hass:blinds-open\" : \"hass:blinds\";\n case \"window\":\n return open ? \"hass:window-open\" : \"hass:window-closed\";\n default:\n return domainIcon(\"cover\", state.state);\n }\n};\n","/** Return an icon representing an input datetime state. */\nimport { domainIcon } from \"./domain_icons\";\nimport { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const inputDateTimeIcon = (state: HassEntity): string => {\n if (!state.attributes.has_date) {\n return \"hass:clock\";\n }\n if (!state.attributes.has_time) {\n return \"hass:calendar\";\n }\n return domainIcon(\"input_datetime\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { durationToSeconds } from \"../datetime/duration_to_seconds\";\n\nexport function timerTimeRemaining(stateObj: HassEntity) {\n let timeRemaining = durationToSeconds(stateObj.attributes.remaining);\n\n if (stateObj.state === \"active\") {\n const now = new Date().getTime();\n const madeActive = new Date(stateObj.last_changed).getTime();\n timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);\n }\n\n return timeRemaining;\n}\n","/**\n * Apply a theme to an element by setting the CSS variables on it.\n *\n * element: Element to apply theme on.\n * themes: HASS Theme information\n * localTheme: selected theme.\n * updateMeta: boolean if we should update the theme-color meta element.\n */\nexport const applyThemesOnElement = (\n element,\n themes,\n localTheme,\n updateMeta = false\n) => {\n if (!element._themes) {\n element._themes = {};\n }\n let themeName = themes.default_theme;\n if (localTheme === \"default\" || (localTheme && themes.themes[localTheme])) {\n themeName = localTheme;\n }\n const styles = { ...element._themes };\n if (themeName !== \"default\") {\n const theme = themes.themes[themeName];\n Object.keys(theme).forEach((key) => {\n const prefixedKey = \"--\" + key;\n element._themes[prefixedKey] = \"\";\n styles[prefixedKey] = theme[key];\n });\n }\n if (element.updateStyles) {\n element.updateStyles(styles);\n } else if ((window as any).ShadyCSS) {\n // implement updateStyles() method of Polemer elements\n (window as any).ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ (element), styles);\n }\n\n if (!updateMeta) {\n return;\n }\n\n const meta = document.querySelector(\"meta[name=theme-color]\");\n if (meta) {\n if (!meta.hasAttribute(\"default-content\")) {\n meta.setAttribute(\"default-content\", meta.getAttribute(\"content\")!);\n }\n const themeColor =\n styles[\"--primary-color\"] || meta.getAttribute(\"default-content\");\n meta.setAttribute(\"content\", themeColor);\n }\n}\n","import { LovelaceCard } from \"./types\";\n\nexport const computeCardSize = (card: LovelaceCard): number | Promise => {\n return typeof card.getCardSize === \"function\" ? card.getCardSize() : 4;\n};","export function computeEntity(entityId: string): string {\n return entityId.substr(entityId.indexOf(\".\") + 1);\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { formatDateTime } from \"./datetime/format_date_time\";\nimport { formatDate } from \"./datetime/format_date\";\nimport { formatTime } from \"./datetime/format_time\";\nimport { LocalizeFunc } from \"./translations/localize\";\nimport { computeStateDomain } from \"./compute-state-domain\";\n\nexport function computeStateDisplay(\n localize: LocalizeFunc,\n stateObj: HassEntity,\n language: string\n): string {\n if (stateObj.state === \"unknown\" || stateObj.state === \"unavailable\") {\n return localize(`state.default.${stateObj.state}`);\n }\n\n if (stateObj.attributes.unit_of_measurement) {\n return `${stateObj.state} ${stateObj.attributes.unit_of_measurement}`;\n }\n\n const domain = computeStateDomain(stateObj);\n\n if (domain === \"input_datetime\") {\n let date: Date;\n if (!stateObj.attributes.has_time) {\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day\n );\n return formatDate(date, language);\n }\n if (!stateObj.attributes.has_date) {\n const now = new Date();\n date = new Date(\n // Due to bugs.chromium.org/p/chromium/issues/detail?id=797548\n // don't use artificial 1970 year.\n now.getFullYear(),\n now.getMonth(),\n now.getDay(),\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatTime(date, language);\n }\n\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day,\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatDateTime(date, language);\n }\n\n return (\n // Return device class translation\n (stateObj.attributes.device_class &&\n localize(\n `component.${domain}.state.${stateObj.attributes.device_class}.${stateObj.state}`\n )) ||\n // Return default translation\n localize(`component.${domain}.state._.${stateObj.state}`) ||\n // We don't know! Return the raw state.\n stateObj.state\n );\n}\n","/**\r\n * Returns a function, that, as long as it continues to be invoked, will not be triggered. It will be called after it stops being called for `wait` ms.\r\n * This can be usefull for ResizeObservers for example.\r\n * @param func The function you want to debounce\r\n * @param wait Period to wait in ms\r\n * @param immediate Triggering on the leading edge instead of the trailing\r\n * @returns Debounced Function\r\n */\r\n// eslint-disable-next-line: ban-types\r\nexport const debounce = unknown>(\r\n func: T,\r\n wait: number,\r\n immediate = false\r\n): T => {\r\n let timeout;\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n return function (...args) {\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n const later = () => {\r\n timeout = null;\r\n if (!immediate) {\r\n func.apply(context, args);\r\n }\r\n };\r\n const callNow = immediate && !timeout;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(later, wait);\r\n if (callNow) {\r\n func.apply(context, args);\r\n }\r\n };\r\n};\r\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {\n const operator = filter.operator || \"==\";\n const value = filter.value || filter;\n const state = filter.attribute\n ? stateObj.attributes[filter.attribute]\n : stateObj.state;\n\n switch (operator) {\n case \"==\":\n return state === value;\n case \"<=\":\n return state <= value;\n case \"<\":\n return state < value;\n case \">=\":\n return state >= value;\n case \">\":\n return state > value;\n case \"!=\":\n return state !== value;\n case \"regex\": {\n return state.match(value);\n }\n default:\n return false;\n }\n};\n","/**\r\n * Formats a number based on the specified language with thousands separator(s) and decimal character for better legibility.\r\n * @param num The number to format\r\n * @param language The language to use when formatting the number\r\n */\r\nexport const formatNumber = (\r\n num: string | number,\r\n language: string,\r\n options?: Intl.NumberFormatOptions\r\n): string => {\r\n // Polyfill for Number.isNaN, which is more reliable than the global isNaN()\r\n Number.isNaN =\r\n Number.isNaN ||\r\n function isNaN(input) {\r\n return typeof input === \"number\" && isNaN(input);\r\n };\r\n\r\n if (!Number.isNaN(Number(num)) && Intl) {\r\n return new Intl.NumberFormat(\r\n language,\r\n getDefaultFormatOptions(num, options)\r\n ).format(Number(num));\r\n }\r\n return num.toString();\r\n};\r\n\r\n/**\r\n * Generates default options for Intl.NumberFormat\r\n * @param num The number to be formatted\r\n * @param options The Intl.NumberFormatOptions that should be included in the returned options\r\n */\r\nconst getDefaultFormatOptions = (\r\n num: string | number,\r\n options?: Intl.NumberFormatOptions\r\n): Intl.NumberFormatOptions => {\r\n const defaultOptions: Intl.NumberFormatOptions = options || {};\r\n\r\n if (typeof num !== \"string\") {\r\n return defaultOptions;\r\n }\r\n\r\n // Keep decimal trailing zeros if they are present in a string numeric value\r\n if (\r\n !options ||\r\n (!options.minimumFractionDigits && !options.maximumFractionDigits)\r\n ) {\r\n const digits = num.indexOf(\".\") > -1 ? num.split(\".\")[1].length : 0;\r\n defaultOptions.minimumFractionDigits = digits;\r\n defaultOptions.maximumFractionDigits = digits;\r\n }\r\n\r\n return defaultOptions;\r\n};\r\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { fireEvent } from \"./fire-event\";\nimport { forwardHaptic } from \"./haptic\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleClick = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n hold: boolean,\n dblClick: boolean\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (dblClick && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (hold && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (!hold && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\"\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n e => e.user === hass!.user!.id\n ))\n ) {\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (actionConfig.entity || config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: actionConfig.entity\n ? actionConfig.entity\n : config.entity\n ? config.entity\n : config.camera_image\n });\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"url\":\n actionConfig.url_path && window.open(actionConfig.url_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n const serviceData = { ...actionConfig.service_data };\n if (serviceData.entity_id === \"entity\") {\n serviceData.entity_id = config.entity;\n }\n hass.callService(domain, service, serviceData);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n }\n};\n","import { ActionConfig } from \"./types\";\n\nexport function hasAction(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}\n","import { PropertyValues } from \"lit-element\";\n\nimport { HomeAssistant } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasConfigOrEntityChanged(\n element: any,\n changedProps: PropertyValues,\n forceUpdate: Boolean,\n): boolean {\n if (changedProps.has('config') || forceUpdate) {\n return true;\n }\n\n if (element.config!.entity) {\n const oldHass = changedProps.get('hass') as HomeAssistant | undefined;\n if (oldHass) {\n return (\n oldHass.states[element.config!.entity]\n !== element.hass!.states[element.config!.entity]\n );\n }\n return true;\n } else {\n return false;\n }\n}","import { ActionConfig } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasDoubleClick(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}","import { HomeAssistant } from \"./types\";\nimport { STATES_OFF } from \"./const\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntities = (\n hass: HomeAssistant,\n entityIds: string[],\n turnOn = true\n): void => {\n const domainsToCall = {};\n entityIds.forEach((entityId) => {\n if (STATES_OFF.includes(hass.states[entityId].state) === turnOn) {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = [\"cover\", \"lock\"].includes(stateDomain)\n ? stateDomain\n : \"homeassistant\";\n\n if (!(serviceDomain in domainsToCall)) {\n domainsToCall[serviceDomain] = [];\n }\n domainsToCall[serviceDomain].push(entityId);\n }\n });\n\n Object.keys(domainsToCall).forEach((domain) => {\n let service;\n switch (domain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n const entities = domainsToCall[domain];\n hass.callService(domain, service, { entity_id: entities });\n });\n};\n","export const getLovelace = () => {\n let root: any = document.querySelector('home-assistant');\n root = root && root.shadowRoot;\n root = root && root.querySelector('home-assistant-main');\n root = root && root.shadowRoot;\n root = root && root.querySelector('app-drawer-layout partial-panel-resolver');\n root = root && root.shadowRoot || root;\n root = root && root.querySelector('ha-panel-lovelace');\n root = root && root.shadowRoot;\n root = root && root.querySelector('hui-root');\n if (root) {\n const ll = root.lovelace;\n ll.current_view = root.___curView;\n return ll;\n }\n return null;\n}\n"],"names":["durationToSeconds","duration","parts","split","map","Number","formatDate","Date","toLocaleDateString","e","name","toLocaleDateStringSupportsOptions","dateObj","locales","year","month","day","fecha","format","formatDateTime","toLocaleString","toLocaleStringSupportsOptions","hour","minute","formatTime","toLocaleTimeString","toLocaleTimeStringSupportsOptions","tests","langKey","leftPad","num","computeDomain","entityId","substr","indexOf","computeRTL","hass","lang","language","translationMetadata","translations","isRTL","computeStateDomain","stateObj","entity_id","DEFAULT_DOMAIN_ICON","STATES_OFF","DOMAINS_TOGGLE","Set","fireEvent","node","type","detail","options","event","Event","bubbles","undefined","cancelable","Boolean","composed","dispatchEvent","SPECIAL_TYPES","DOMAIN_TO_ELEMENT_TYPE","alert","automation","climate","cover","fan","group","input_boolean","input_number","input_select","input_text","light","lock","media_player","remote","scene","script","sensor","timer","switch","vacuum","water_heater","input_datetime","fixedIcons","calendar","camera","configurator","conversation","device_tracker","history_graph","homeassistant","homekit","image_processing","mailbox","notify","person","plant","proximity","simple_alarm","sun","updater","weblink","domainIcon","domain","state","console","warn","forwardHaptic","hapticType","window","navigate","_node","path","replace","history","replaceState","pushState","turnOnOffEntity","turnOn","service","stateDomain","serviceDomain","callService","toggleEntity","includes","states","handleActionConfig","config","actionConfig","action","confirmation","exemptions","some","user","id","confirm","text","entity","camera_image","navigation_path","url_path","open","service_data","fixedDeviceClassIcons","humidity","illuminance","temperature","pressure","power","signal_strength","domainIcons","binary_sensor","activated","attributes","device_class","dclass","battery","isNaN","batteryRound","Math","round","unit","unit_of_measurement","has_date","has_time","localize","timeDesc","delta","compareTime","getTime","tense","abs","let","i","length","floor","includeTense","d","h","m","s","timeRemaining","remaining","now","madeActive","last_changed","max","element","themes","localTheme","updateMeta","_themes","themeName","default_theme","styles","Object","theme","keys","forEach","key","prefixedKey","updateStyles","ShadyCSS","styleSubtree","meta","document","querySelector","hasAttribute","setAttribute","getAttribute","themeColor","card","getCardSize","date","getFullYear","getMonth","getDay","cardConfig","isRow","_createError","error","_createThing","tag","createElement","setConfig","err","message","startsWith","has","customElements","get","style","display","setTimeout","whenDefined","then","clearTimeout","func","wait","immediate","timeout","context","this","callNow","apply","args","filter","value","attribute","operator","match","input","Intl","NumberFormat","defaultOptions","minimumFractionDigits","maximumFractionDigits","digits","getDefaultFormatOptions","toString","double_tap_action","hold_action","tap_action","hold","dblClick","haptic","serviceData","changedProps","forceUpdate","oldHass","entityIds","domainsToCall","push","root","shadowRoot","ll","lovelace","current_view","___curView","icon"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.umd.js","sources":["../src/datetime/duration_to_seconds.ts","../src/datetime/format_date.ts","../src/datetime/format_date_time.ts","../src/datetime/format_time.ts","../src/datetime/relative_time.ts","../src/datetime/seconds_to_duration.ts","../src/compute-domain.ts","../src/compute-rtl.ts","../src/compute-state-domain.ts","../src/const.ts","../src/fire-event.ts","../src/create-thing.ts","../src/domain_icons.ts","../src/haptic.ts","../src/navigate.ts","../src/turn-on-off-entity.ts","../src/toggle-entity.ts","../src/handle-action.ts","../src/sensor_icon.ts","../src/state_icon.ts","../src/binary_sensor_icon.ts","../src/cover_icon.ts","../src/input_datetime_icon.ts","../src/datetime/timer_time_remaining.ts","../src/apply_themes_on_element.ts","../src/compute-card-size.ts","../src/compute-entity.ts","../src/compute-state-display.ts","../src/debounce.ts","../src/evaluate-filter.ts","../src/format-number.ts","../src/handle-click.ts","../src/has-action.ts","../src/has-changed.ts","../src/has-double-click.ts","../src/turn-on-off-entities.ts","../src/get-lovelace.ts"],"sourcesContent":["export function durationToSeconds(duration: string): number {\n const parts = duration.split(\":\").map(Number);\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n}\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleDateStringSupportsOptions() {\n try {\n new Date().toLocaleDateString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDate = (toLocaleDateStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleDateString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"mediumDate\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleStringSupportsOptions() {\n try {\n new Date().toLocaleString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatDateTime = (toLocaleStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleString(locales, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"haDateTime\"));\n","import fecha from \"fecha\";\n\n// Check for support of native locale string options\nfunction toLocaleTimeStringSupportsOptions() {\n try {\n new Date().toLocaleTimeString(\"i\");\n } catch (e) {\n return e.name === \"RangeError\";\n }\n return false;\n}\n\nexport const formatTime = (toLocaleTimeStringSupportsOptions()\n ? (dateObj: Date, locales: string) =>\n dateObj.toLocaleTimeString(locales, {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n : (dateObj: Date) => fecha.format(dateObj, \"shortTime\"));\n","import { LocalizeFunc } from \"../translations/localize\";\n\n/**\n * Calculate a string representing a date object as relative time from now.\n *\n * Example output: 5 minutes ago, in 3 days.\n */\nconst tests = [60, 60, 24, 7];\nconst langKey = [\"second\", \"minute\", \"hour\", \"day\"];\n\nexport function relativeTime(\n dateObj: Date,\n localize: LocalizeFunc,\n options: {\n compareTime?: Date;\n includeTense?: boolean;\n } = {}\n): string {\n const compareTime = options.compareTime || new Date();\n let delta = (compareTime.getTime() - dateObj.getTime()) / 1000;\n const tense = delta >= 0 ? \"past\" : \"future\";\n delta = Math.abs(delta);\n\n let timeDesc;\n\n for (let i = 0; i < tests.length; i++) {\n if (delta < tests[i]) {\n delta = Math.floor(delta);\n timeDesc = localize(\n `ui.components.relative_time.duration.${langKey[i]}`,\n \"count\",\n delta\n );\n break;\n }\n\n delta /= tests[i];\n }\n\n if (timeDesc === undefined) {\n delta = Math.floor(delta);\n timeDesc = localize(\n \"ui.components.relative_time.duration.week\",\n \"count\",\n delta\n );\n }\n\n return options.includeTense === false\n ? timeDesc\n : localize(`ui.components.relative_time.${tense}`, \"time\", timeDesc);\n}\n","const leftPad = (num: number) => (num < 10 ? `0${num}` : num);\n\nexport function secondsToDuration(d: number) {\n const h = Math.floor(d / 3600);\n const m = Math.floor((d % 3600) / 60);\n const s = Math.floor((d % 3600) % 60);\n\n if (h > 0) {\n return `${h}:${leftPad(m)}:${leftPad(s)}`;\n }\n if (m > 0) {\n return `${m}:${leftPad(s)}`;\n }\n if (s > 0) {\n return \"\" + s;\n }\n return null;\n}\n","export function computeDomain(entityId: string): string {\n return entityId.substr(0, entityId.indexOf(\".\"));\n}\n","import { HomeAssistant } from \"./types\";\n\nexport function computeRTL(hass: HomeAssistant) {\n const lang = hass.language || \"en\";\n if (hass.translationMetadata.translations[lang]) {\n return hass.translationMetadata.translations[lang].isRTL || false;\n }\n return false;\n}\n\nexport function computeRTLDirection(hass: HomeAssistant) {\n return computeRTL(hass) ? \"rtl\" : \"ltr\";\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport function computeStateDomain(stateObj: HassEntity) {\n return computeDomain(stateObj.entity_id);\n}\n","/** Constants to be used in the frontend. */\n\n// Constants should be alphabetically sorted by name.\n// Arrays with values should be alphabetically sorted if order doesn't matter.\n// Each constant should have a description what it is supposed to be used for.\n\n/** Icon to use when no icon specified for domain. */\nexport const DEFAULT_DOMAIN_ICON = \"hass:bookmark\";\n\n/** Panel to show when no panel is picked. */\nexport const DEFAULT_PANEL = \"lovelace\";\n\n/** Domains that have a state card. */\nexport const DOMAINS_WITH_CARD = [\n \"climate\",\n \"cover\",\n \"configurator\",\n \"input_select\",\n \"input_number\",\n \"input_text\",\n \"lock\",\n \"media_player\",\n \"scene\",\n \"script\",\n \"timer\",\n \"vacuum\",\n \"water_heater\",\n \"weblink\"\n];\n\n/** Domains with separate more info dialog. */\nexport const DOMAINS_WITH_MORE_INFO = [\n \"alarm_control_panel\",\n \"automation\",\n \"camera\",\n \"climate\",\n \"configurator\",\n \"cover\",\n \"fan\",\n \"group\",\n \"history_graph\",\n \"input_datetime\",\n \"light\",\n \"lock\",\n \"media_player\",\n \"script\",\n \"sun\",\n \"updater\",\n \"vacuum\",\n \"water_heater\",\n \"weather\"\n];\n\n/** Domains that show no more info dialog. */\nexport const DOMAINS_HIDE_MORE_INFO = [\n \"input_number\",\n \"input_select\",\n \"input_text\",\n \"scene\",\n \"weblink\"\n];\n\n/** Domains that should have the history hidden in the more info dialog. */\nexport const DOMAINS_MORE_INFO_NO_HISTORY = [\n \"camera\",\n \"configurator\",\n \"history_graph\",\n \"scene\"\n];\n\n/** States that we consider \"off\". */\nexport const STATES_OFF = [\"closed\", \"locked\", \"off\"];\n\n/** Domains where we allow toggle in Lovelace. */\nexport const DOMAINS_TOGGLE = new Set([\n \"fan\",\n \"input_boolean\",\n \"light\",\n \"switch\",\n \"group\",\n \"automation\"\n]);\n\n/** Temperature units. */\nexport const UNIT_C = \"°C\";\nexport const UNIT_F = \"°F\";\n\n/** Entity ID of the default view. */\nexport const DEFAULT_VIEW_ENTITY_ID = \"group.default_view\";\n","// Polymer legacy event helpers used courtesy of the Polymer project.\n//\n// Copyright (c) 2017 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\ndeclare global {\n // tslint:disable-next-line\n interface HASSDomEvents {}\n}\n\nexport type ValidHassDomEvent = keyof HASSDomEvents;\n\nexport interface HASSDomEvent extends Event {\n detail: T;\n}\n\n/**\n * Dispatches a custom event with an optional detail value.\n *\n * @param {string} type Name of event type.\n * @param {*=} detail Detail value containing event-specific\n * payload.\n * @param {{ bubbles: (boolean|undefined),\n * cancelable: (boolean|undefined),\n * composed: (boolean|undefined) }=}\n * options Object specifying options. These may include:\n * `bubbles` (boolean, defaults to `true`),\n * `cancelable` (boolean, defaults to false), and\n * `node` on which to fire the event (HTMLElement, defaults to `this`).\n * @return {Event} The new event that was fired.\n */\nexport const fireEvent = (\n node: HTMLElement | Window,\n type: HassEvent,\n detail?: HASSDomEvents[HassEvent],\n options?: {\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n }\n) => {\n options = options || {};\n // @ts-ignore\n detail = detail === null || detail === undefined ? {} : detail;\n const event = new Event(type, {\n bubbles: options.bubbles === undefined ? true : options.bubbles,\n cancelable: Boolean(options.cancelable),\n composed: options.composed === undefined ? true : options.composed\n });\n (event as any).detail = detail;\n node.dispatchEvent(event);\n return event;\n};\n","import { fireEvent } from \"./fire-event\";\n\nconst SPECIAL_TYPES = new Set([\n \"call-service\",\n \"divider\",\n \"section\",\n \"weblink\",\n \"cast\",\n \"select\"\n]);\nconst DOMAIN_TO_ELEMENT_TYPE = {\n alert: \"toggle\",\n automation: \"toggle\",\n climate: \"climate\",\n cover: \"cover\",\n fan: \"toggle\",\n group: \"group\",\n input_boolean: \"toggle\",\n input_number: \"input-number\",\n input_select: \"input-select\",\n input_text: \"input-text\",\n light: \"toggle\",\n lock: \"lock\",\n media_player: \"media-player\",\n remote: \"toggle\",\n scene: \"scene\",\n script: \"script\",\n sensor: \"sensor\",\n timer: \"timer\",\n switch: \"toggle\",\n vacuum: \"toggle\",\n // Temporary. Once climate is rewritten,\n // water heater should get it's own row.\n water_heater: \"climate\",\n input_datetime: \"input-datetime\"\n};\n\nexport const createThing = (cardConfig, isRow = false) => {\n const _createError = (error, config) => {\n return _createThing(\n \"hui-error-card\",\n {\n type: \"error\",\n error,\n config\n }\n );\n };\n\n const _createThing = (tag, config) => {\n const element = window.document.createElement(tag);\n try {\n element.setConfig(config);\n } catch (err) {\n console.error(tag, err);\n return _createError(err.message, config);\n }\n return element;\n };\n\n if (!cardConfig || typeof cardConfig !== \"object\" || (!isRow && !cardConfig.type))\n return _createError(\"No type defined\", cardConfig);\n let tag = cardConfig.type;\n if (tag && tag.startsWith(\"custom:\")) {\n tag = tag.substr(\"custom:\".length);\n } else if (isRow) {\n if (SPECIAL_TYPES.has(tag)) {\n tag = `hui-${tag}-row`;\n } else {\n if (!cardConfig.entity) {\n return _createError(\"Invalid config given.\", cardConfig);\n }\n \n const domain = cardConfig.entity.split(\".\", 1)[0];\n tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || \"text\"}-entity-row`;\n }\n } else {\n tag = `hui-${tag}-card`;\n }\n\n if (customElements.get(tag)) return _createThing(tag, cardConfig);\n\n // If element doesn't exist (yet) create an error\n const element = _createError(\n `Custom element doesn't exist: ${cardConfig.type}.`,\n cardConfig\n );\n element.style.display = \"None\";\n const timer = setTimeout(() => {\n element.style.display = \"\";\n }, 2000);\n // Remove error if element is defined later\n customElements.whenDefined(cardConfig.type).then(() => {\n clearTimeout(timer);\n fireEvent(element, \"ll-rebuild\", {}, element);\n });\n\n return element;\n};\n","/**\n * Return the icon to be used for a domain.\n *\n * Optionally pass in a state to influence the domain icon.\n */\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\n\nexport const fixedIcons = {\n alert: \"hass:alert\",\n automation: \"hass:playlist-play\",\n calendar: \"hass:calendar\",\n camera: \"hass:video\",\n climate: \"hass:thermostat\",\n configurator: \"hass:settings\",\n conversation: \"hass:text-to-speech\",\n device_tracker: \"hass:account\",\n fan: \"hass:fan\",\n group: \"hass:google-circles-communities\",\n history_graph: \"hass:chart-line\",\n homeassistant: \"hass:home-assistant\",\n homekit: \"hass:home-automation\",\n image_processing: \"hass:image-filter-frames\",\n input_boolean: \"hass:drawing\",\n input_datetime: \"hass:calendar-clock\",\n input_number: \"hass:ray-vertex\",\n input_select: \"hass:format-list-bulleted\",\n input_text: \"hass:textbox\",\n light: \"hass:lightbulb\",\n mailbox: \"hass:mailbox\",\n notify: \"hass:comment-alert\",\n person: \"hass:account\",\n plant: \"hass:flower\",\n proximity: \"hass:apple-safari\",\n remote: \"hass:remote\",\n scene: \"hass:google-pages\",\n script: \"hass:file-document\",\n sensor: \"hass:eye\",\n simple_alarm: \"hass:bell\",\n sun: \"hass:white-balance-sunny\",\n switch: \"hass:flash\",\n timer: \"hass:timer\",\n updater: \"hass:cloud-upload\",\n vacuum: \"hass:robot-vacuum\",\n water_heater: \"hass:thermometer\",\n weblink: \"hass:open-in-new\"\n};\n\nexport function domainIcon(domain: string, state?: string): string {\n if (domain in fixedIcons) {\n return fixedIcons[domain];\n }\n\n switch (domain) {\n case \"alarm_control_panel\":\n switch (state) {\n case \"armed_home\":\n return \"hass:bell-plus\";\n case \"armed_night\":\n return \"hass:bell-sleep\";\n case \"disarmed\":\n return \"hass:bell-outline\";\n case \"triggered\":\n return \"hass:bell-ring\";\n default:\n return \"hass:bell\";\n }\n\n case \"binary_sensor\":\n return state && state === \"off\"\n ? \"hass:radiobox-blank\"\n : \"hass:checkbox-marked-circle\";\n\n case \"cover\":\n return state === \"closed\" ? \"hass:window-closed\" : \"hass:window-open\";\n\n case \"lock\":\n return state && state === \"unlocked\" ? \"hass:lock-open\" : \"hass:lock\";\n\n case \"media_player\":\n return state && state !== \"off\" && state !== \"idle\"\n ? \"hass:cast-connected\"\n : \"hass:cast\";\n\n case \"zwave\":\n switch (state) {\n case \"dead\":\n return \"hass:emoticon-dead\";\n case \"sleeping\":\n return \"hass:sleep\";\n case \"initializing\":\n return \"hass:timer-sand\";\n default:\n return \"hass:z-wave\";\n }\n\n default:\n // tslint:disable-next-line\n console.warn(\n \"Unable to find icon for domain \" + domain + \" (\" + state + \")\"\n );\n return DEFAULT_DOMAIN_ICON;\n }\n}\n","import { HASSDomEvent, fireEvent } from \"./fire-event\";\n\n/**\n * Broadcast haptic feedback requests\n */\n\n\n// Allowed types are from iOS HIG.\n// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics\n// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible.\nexport type HapticType =\n | \"success\"\n | \"warning\"\n | \"failure\"\n | \"light\"\n | \"medium\"\n | \"heavy\"\n | \"selection\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n haptic: HapticType;\n }\n\n interface GlobalEventHandlersEventMap {\n haptic: HASSDomEvent;\n }\n}\n\nexport const forwardHaptic = (hapticType: HapticType) => {\n fireEvent(window, \"haptic\", hapticType);\n};\n","import { fireEvent } from \"./fire-event\";\n\ndeclare global {\n // for fire event\n interface HASSDomEvents {\n \"location-changed\": {\n replace: boolean;\n };\n }\n}\n\nexport const navigate = (\n _node: any,\n path: string,\n replace: boolean = false\n) => {\n if (replace) {\n history.replaceState(null, \"\", path);\n } else {\n history.pushState(null, \"\", path);\n }\n fireEvent(window, \"location-changed\", {\n replace\n });\n};\n","import { HomeAssistant } from \"./types\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntity = (\n hass: HomeAssistant,\n entityId: string,\n turnOn = true\n): Promise => {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = stateDomain === \"group\" ? \"homeassistant\" : stateDomain;\n\n let service;\n switch (stateDomain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n return hass.callService(serviceDomain, service, { entity_id: entityId });\n};\n","import { STATES_OFF } from \"./const\";\nimport { turnOnOffEntity } from \"./turn-on-off-entity\";\nimport { HomeAssistant } from \"./types\";\n\nexport const toggleEntity = (\n hass: HomeAssistant,\n entityId: string\n): Promise => {\n const turnOn = STATES_OFF.includes(hass.states[entityId].state);\n return turnOnOffEntity(hass, entityId, turnOn);\n};\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { forwardHaptic } from \"./haptic\";\nimport { fireEvent } from \"./fire-event\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleActionConfig = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n actionConfig: ActionConfig | undefined\n): void => {\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\",\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n (e) => e.user === hass!.user!.id\n ))\n ) {\n forwardHaptic(\"warning\");\n\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: config.entity ? config.entity : config.camera_image!,\n });\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n }\n break;\n case \"url\":\n if (actionConfig.url_path) {\n window.open(actionConfig.url_path);\n }\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n forwardHaptic(\"success\");\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n forwardHaptic(\"failure\");\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n hass.callService(domain, service, actionConfig.service_data);\n forwardHaptic(\"success\");\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n }\n }\n};\n\nexport const handleAction = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n action: string\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (action === \"double_tap\" && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (action === \"hold\" && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (action === \"tap\" && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n handleActionConfig(node, hass, config, actionConfig);\n};\n","/** Return an icon representing a sensor state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { UNIT_C, UNIT_F } from \"./const\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst fixedDeviceClassIcons = {\n humidity: \"hass:water-percent\",\n illuminance: \"hass:brightness-5\",\n temperature: \"hass:thermometer\",\n pressure: \"hass:gauge\",\n power: \"hass:flash\",\n signal_strength: \"hass:wifi\",\n};\n\nexport const sensorIcon = (state: HassEntity) => {\n const dclass = state.attributes.device_class;\n\n if (dclass && dclass in fixedDeviceClassIcons) {\n return fixedDeviceClassIcons[dclass];\n }\n if (dclass === \"battery\") {\n const battery = Number(state.state);\n if (isNaN(battery)) {\n return \"hass:battery-unknown\";\n }\n const batteryRound = Math.round(battery / 10) * 10;\n if (batteryRound >= 100) {\n return \"hass:battery\";\n }\n if (batteryRound <= 0) {\n return \"hass:battery-alert\";\n }\n // Will return one of the following icons: (listed so extractor picks up)\n // hass:battery-10\n // hass:battery-20\n // hass:battery-30\n // hass:battery-40\n // hass:battery-50\n // hass:battery-60\n // hass:battery-70\n // hass:battery-80\n // hass:battery-90\n // We obscure 'hass' in iconname so this name does not get picked up\n return `${\"hass\"}:battery-${batteryRound}`;\n }\n\n const unit = state.attributes.unit_of_measurement;\n if (unit === UNIT_C || unit === UNIT_F) {\n return \"hass:thermometer\";\n }\n return domainIcon(\"sensor\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { computeDomain } from \"./compute-domain\";\nimport { DEFAULT_DOMAIN_ICON } from \"./const\";\nimport { binarySensorIcon } from \"./binary_sensor_icon\";\nimport { coverIcon } from \"./cover_icon\";\nimport { sensorIcon } from \"./sensor_icon\";\nimport { inputDateTimeIcon } from \"./input_datetime_icon\";\nimport { domainIcon } from \"./domain_icons\";\n\nconst domainIcons = {\n binary_sensor: binarySensorIcon,\n cover: coverIcon,\n sensor: sensorIcon,\n input_datetime: inputDateTimeIcon,\n};\n\nexport const stateIcon = (state: HassEntity) => {\n if (!state) {\n return DEFAULT_DOMAIN_ICON;\n }\n if (state.attributes.icon) {\n return state.attributes.icon;\n }\n\n const domain = computeDomain(state.entity_id);\n\n if (domain in domainIcons) {\n return domainIcons[domain](state);\n }\n return domainIcon(domain, state.state);\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\n/** Return an icon representing a binary sensor state. */\n\nexport const binarySensorIcon = (state: HassEntity) => {\n const activated = state.state && state.state === \"off\";\n switch (state.attributes.device_class) {\n case \"battery\":\n return activated ? \"hass:battery\" : \"hass:battery-outline\";\n case \"cold\":\n return activated ? \"hass:thermometer\" : \"hass:snowflake\";\n case \"connectivity\":\n return activated ? \"hass:server-network-off\" : \"hass:server-network\";\n case \"door\":\n return activated ? \"hass:door-closed\" : \"hass:door-open\";\n case \"garage_door\":\n return activated ? \"hass:garage\" : \"hass:garage-open\";\n case \"gas\":\n case \"power\":\n case \"problem\":\n case \"safety\":\n case \"smoke\":\n return activated ? \"hass:shield-check\" : \"hass:alert\";\n case \"heat\":\n return activated ? \"hass:thermometer\" : \"hass:fire\";\n case \"light\":\n return activated ? \"hass:brightness-5\" : \"hass:brightness-7\";\n case \"lock\":\n return activated ? \"hass:lock\" : \"hass:lock-open\";\n case \"moisture\":\n return activated ? \"hass:water-off\" : \"hass:water\";\n case \"motion\":\n return activated ? \"hass:walk\" : \"hass:run\";\n case \"occupancy\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"opening\":\n return activated ? \"hass:square\" : \"hass:square-outline\";\n case \"plug\":\n return activated ? \"hass:power-plug-off\" : \"hass:power-plug\";\n case \"presence\":\n return activated ? \"hass:home-outline\" : \"hass:home\";\n case \"sound\":\n return activated ? \"hass:music-note-off\" : \"hass:music-note\";\n case \"vibration\":\n return activated ? \"hass:crop-portrait\" : \"hass:vibrate\";\n case \"window\":\n return activated ? \"hass:window-closed\" : \"hass:window-open\";\n default:\n return activated ? \"hass:radiobox-blank\" : \"hass:checkbox-marked-circle\";\n }\n};\n","/** Return an icon representing a cover state. */\nimport { HassEntity } from \"home-assistant-js-websocket\";\nimport { domainIcon } from \"./domain_icons\";\n\nexport const coverIcon = (state: HassEntity): string => {\n const open = state.state !== \"closed\";\n switch (state.attributes.device_class) {\n case \"garage\":\n return open ? \"hass:garage-open\" : \"hass:garage\";\n case \"door\":\n return open ? \"hass:door-open\" : \"hass:door-closed\";\n case \"shutter\":\n return open ? \"hass:window-shutter-open\" : \"hass:window-shutter\";\n case \"blind\":\n return open ? \"hass:blinds-open\" : \"hass:blinds\";\n case \"window\":\n return open ? \"hass:window-open\" : \"hass:window-closed\";\n default:\n return domainIcon(\"cover\", state.state);\n }\n};\n","/** Return an icon representing an input datetime state. */\nimport { domainIcon } from \"./domain_icons\";\nimport { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const inputDateTimeIcon = (state: HassEntity): string => {\n if (!state.attributes.has_date) {\n return \"hass:clock\";\n }\n if (!state.attributes.has_time) {\n return \"hass:calendar\";\n }\n return domainIcon(\"input_datetime\");\n};\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { durationToSeconds } from \"../datetime/duration_to_seconds\";\n\nexport function timerTimeRemaining(stateObj: HassEntity) {\n let timeRemaining = durationToSeconds(stateObj.attributes.remaining);\n\n if (stateObj.state === \"active\") {\n const now = new Date().getTime();\n const madeActive = new Date(stateObj.last_changed).getTime();\n timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);\n }\n\n return timeRemaining;\n}\n","/**\n * Apply a theme to an element by setting the CSS variables on it.\n *\n * element: Element to apply theme on.\n * themes: HASS Theme information\n * localTheme: selected theme.\n * updateMeta: boolean if we should update the theme-color meta element.\n */\nexport const applyThemesOnElement = (\n element,\n themes,\n localTheme,\n updateMeta = false\n) => {\n if (!element._themes) {\n element._themes = {};\n }\n let themeName = themes.default_theme;\n if (localTheme === \"default\" || (localTheme && themes.themes[localTheme])) {\n themeName = localTheme;\n }\n const styles = { ...element._themes };\n if (themeName !== \"default\") {\n const theme = themes.themes[themeName];\n Object.keys(theme).forEach((key) => {\n const prefixedKey = \"--\" + key;\n element._themes[prefixedKey] = \"\";\n styles[prefixedKey] = theme[key];\n });\n }\n if (element.updateStyles) {\n element.updateStyles(styles);\n } else if ((window as any).ShadyCSS) {\n // implement updateStyles() method of Polemer elements\n (window as any).ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ (element), styles);\n }\n\n if (!updateMeta) {\n return;\n }\n\n const meta = document.querySelector(\"meta[name=theme-color]\");\n if (meta) {\n if (!meta.hasAttribute(\"default-content\")) {\n meta.setAttribute(\"default-content\", meta.getAttribute(\"content\")!);\n }\n const themeColor =\n styles[\"--primary-color\"] || meta.getAttribute(\"default-content\");\n meta.setAttribute(\"content\", themeColor);\n }\n}\n","import { LovelaceCard } from \"./types\";\n\nexport const computeCardSize = (card: LovelaceCard): number | Promise => {\n return typeof card.getCardSize === \"function\" ? card.getCardSize() : 4;\n};","export function computeEntity(entityId: string): string {\n return entityId.substr(entityId.indexOf(\".\") + 1);\n}\n","import { HassEntity } from \"home-assistant-js-websocket\";\nimport { formatDateTime } from \"./datetime/format_date_time\";\nimport { formatDate } from \"./datetime/format_date\";\nimport { formatTime } from \"./datetime/format_time\";\nimport { LocalizeFunc } from \"./translations/localize\";\nimport { computeStateDomain } from \"./compute-state-domain\";\n\nexport function computeStateDisplay(\n localize: LocalizeFunc,\n stateObj: HassEntity,\n language: string\n): string {\n if (stateObj.state === \"unknown\" || stateObj.state === \"unavailable\") {\n return localize(`state.default.${stateObj.state}`);\n }\n\n if (stateObj.attributes.unit_of_measurement) {\n return `${stateObj.state} ${stateObj.attributes.unit_of_measurement}`;\n }\n\n const domain = computeStateDomain(stateObj);\n\n if (domain === \"input_datetime\") {\n let date: Date;\n if (!stateObj.attributes.has_time) {\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day\n );\n return formatDate(date, language);\n }\n if (!stateObj.attributes.has_date) {\n const now = new Date();\n date = new Date(\n // Due to bugs.chromium.org/p/chromium/issues/detail?id=797548\n // don't use artificial 1970 year.\n now.getFullYear(),\n now.getMonth(),\n now.getDay(),\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatTime(date, language);\n }\n\n date = new Date(\n stateObj.attributes.year,\n stateObj.attributes.month - 1,\n stateObj.attributes.day,\n stateObj.attributes.hour,\n stateObj.attributes.minute\n );\n return formatDateTime(date, language);\n }\n\n return (\n // Return device class translation\n (stateObj.attributes.device_class &&\n localize(\n `component.${domain}.state.${stateObj.attributes.device_class}.${stateObj.state}`\n )) ||\n // Return default translation\n localize(`component.${domain}.state._.${stateObj.state}`) ||\n // We don't know! Return the raw state.\n stateObj.state\n );\n}\n","/**\r\n * Returns a function, that, as long as it continues to be invoked, will not be triggered. It will be called after it stops being called for `wait` ms.\r\n * This can be usefull for ResizeObservers for example.\r\n * @param func The function you want to debounce\r\n * @param wait Period to wait in ms\r\n * @param immediate Triggering on the leading edge instead of the trailing\r\n * @returns Debounced Function\r\n */\r\n// eslint-disable-next-line: ban-types\r\nexport const debounce = unknown>(\r\n func: T,\r\n wait: number,\r\n immediate = false\r\n): T => {\r\n let timeout;\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n return function (...args) {\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n const later = () => {\r\n timeout = null;\r\n if (!immediate) {\r\n func.apply(context, args);\r\n }\r\n };\r\n const callNow = immediate && !timeout;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(later, wait);\r\n if (callNow) {\r\n func.apply(context, args);\r\n }\r\n };\r\n};\r\n","import { HassEntity } from \"home-assistant-js-websocket\";\n\nexport const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {\n const operator = filter.operator || \"==\";\n const value = filter.value || filter;\n const state = filter.attribute\n ? stateObj.attributes[filter.attribute]\n : stateObj.state;\n\n switch (operator) {\n case \"==\":\n return state === value;\n case \"<=\":\n return state <= value;\n case \"<\":\n return state < value;\n case \">=\":\n return state >= value;\n case \">\":\n return state > value;\n case \"!=\":\n return state !== value;\n case \"regex\": {\n return state.match(value);\n }\n default:\n return false;\n }\n};\n","/**\r\n * Formats a number based on the specified language with thousands separator(s) and decimal character for better legibility.\r\n * @param num The number to format\r\n * @param language The language to use when formatting the number\r\n */\r\nexport const formatNumber = (\r\n num: string | number,\r\n language: string,\r\n options?: Intl.NumberFormatOptions\r\n): string => {\r\n // Polyfill for Number.isNaN, which is more reliable than the global isNaN()\r\n Number.isNaN =\r\n Number.isNaN ||\r\n function isNaN(input) {\r\n return typeof input === \"number\" && isNaN(input);\r\n };\r\n\r\n if (!Number.isNaN(Number(num)) && Intl) {\r\n return new Intl.NumberFormat(\r\n language,\r\n getDefaultFormatOptions(num, options)\r\n ).format(Number(num));\r\n }\r\n return num.toString();\r\n};\r\n\r\n/**\r\n * Generates default options for Intl.NumberFormat\r\n * @param num The number to be formatted\r\n * @param options The Intl.NumberFormatOptions that should be included in the returned options\r\n */\r\nconst getDefaultFormatOptions = (\r\n num: string | number,\r\n options?: Intl.NumberFormatOptions\r\n): Intl.NumberFormatOptions => {\r\n const defaultOptions: Intl.NumberFormatOptions = options || {};\r\n\r\n if (typeof num !== \"string\") {\r\n return defaultOptions;\r\n }\r\n\r\n // Keep decimal trailing zeros if they are present in a string numeric value\r\n if (\r\n !options ||\r\n (!options.minimumFractionDigits && !options.maximumFractionDigits)\r\n ) {\r\n const digits = num.indexOf(\".\") > -1 ? num.split(\".\")[1].length : 0;\r\n defaultOptions.minimumFractionDigits = digits;\r\n defaultOptions.maximumFractionDigits = digits;\r\n }\r\n\r\n return defaultOptions;\r\n};\r\n","import { HomeAssistant, ActionConfig } from \"./types\";\nimport { fireEvent } from \"./fire-event\";\nimport { forwardHaptic } from \"./haptic\";\nimport { navigate } from \"./navigate\";\nimport { toggleEntity } from \"./toggle-entity\";\n\nexport const handleClick = (\n node: HTMLElement,\n hass: HomeAssistant,\n config: {\n entity?: string;\n camera_image?: string;\n hold_action?: ActionConfig;\n tap_action?: ActionConfig;\n double_tap_action?: ActionConfig;\n },\n hold: boolean,\n dblClick: boolean\n): void => {\n let actionConfig: ActionConfig | undefined;\n\n if (dblClick && config.double_tap_action) {\n actionConfig = config.double_tap_action;\n } else if (hold && config.hold_action) {\n actionConfig = config.hold_action;\n } else if (!hold && config.tap_action) {\n actionConfig = config.tap_action;\n }\n\n if (!actionConfig) {\n actionConfig = {\n action: \"more-info\"\n };\n }\n\n if (\n actionConfig.confirmation &&\n (!actionConfig.confirmation.exemptions ||\n !actionConfig.confirmation.exemptions.some(\n e => e.user === hass!.user!.id\n ))\n ) {\n if (\n !confirm(\n actionConfig.confirmation.text ||\n `Are you sure you want to ${actionConfig.action}?`\n )\n ) {\n return;\n }\n }\n\n switch (actionConfig.action) {\n case \"more-info\":\n if (actionConfig.entity || config.entity || config.camera_image) {\n fireEvent(node, \"hass-more-info\", {\n entityId: actionConfig.entity\n ? actionConfig.entity\n : config.entity\n ? config.entity\n : config.camera_image\n });\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"navigate\":\n if (actionConfig.navigation_path) {\n navigate(node, actionConfig.navigation_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"url\":\n actionConfig.url_path && window.open(actionConfig.url_path);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n case \"toggle\":\n if (config.entity) {\n toggleEntity(hass, config.entity!);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n }\n break;\n case \"call-service\": {\n if (!actionConfig.service) {\n return;\n }\n const [domain, service] = actionConfig.service.split(\".\", 2);\n const serviceData = { ...actionConfig.service_data };\n if (serviceData.entity_id === \"entity\") {\n serviceData.entity_id = config.entity;\n }\n hass.callService(domain, service, serviceData);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n }\n case \"fire-dom-event\": {\n fireEvent(node, \"ll-custom\", actionConfig);\n if (actionConfig.haptic) forwardHaptic(actionConfig.haptic);\n break;\n }\n }\n};\n","import { ActionConfig } from \"./types\";\n\nexport function hasAction(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}\n","import { PropertyValues } from \"lit-element\";\n\nimport { HomeAssistant } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasConfigOrEntityChanged(\n element: any,\n changedProps: PropertyValues,\n forceUpdate: Boolean,\n): boolean {\n if (changedProps.has('config') || forceUpdate) {\n return true;\n }\n\n if (element.config!.entity) {\n const oldHass = changedProps.get('hass') as HomeAssistant | undefined;\n if (oldHass) {\n return (\n oldHass.states[element.config!.entity]\n !== element.hass!.states[element.config!.entity]\n );\n }\n return true;\n } else {\n return false;\n }\n}","import { ActionConfig } from \"./types\";\n\n// Check if config or Entity changed\nexport function hasDoubleClick(config?: ActionConfig): boolean {\n return config !== undefined && config.action !== \"none\";\n}","import { HomeAssistant } from \"./types\";\nimport { STATES_OFF } from \"./const\";\nimport { computeDomain } from \"./compute-domain\";\n\nexport const turnOnOffEntities = (\n hass: HomeAssistant,\n entityIds: string[],\n turnOn = true\n): void => {\n const domainsToCall = {};\n entityIds.forEach((entityId) => {\n if (STATES_OFF.includes(hass.states[entityId].state) === turnOn) {\n const stateDomain = computeDomain(entityId);\n const serviceDomain = [\"cover\", \"lock\"].includes(stateDomain)\n ? stateDomain\n : \"homeassistant\";\n\n if (!(serviceDomain in domainsToCall)) {\n domainsToCall[serviceDomain] = [];\n }\n domainsToCall[serviceDomain].push(entityId);\n }\n });\n\n Object.keys(domainsToCall).forEach((domain) => {\n let service;\n switch (domain) {\n case \"lock\":\n service = turnOn ? \"unlock\" : \"lock\";\n break;\n case \"cover\":\n service = turnOn ? \"open_cover\" : \"close_cover\";\n break;\n default:\n service = turnOn ? \"turn_on\" : \"turn_off\";\n }\n\n const entities = domainsToCall[domain];\n hass.callService(domain, service, { entity_id: entities });\n });\n};\n","export const getLovelace = () => {\n let root: any = document.querySelector('home-assistant');\n root = root && root.shadowRoot;\n root = root && root.querySelector('home-assistant-main');\n root = root && root.shadowRoot;\n root = root && root.querySelector('app-drawer-layout partial-panel-resolver');\n root = root && root.shadowRoot || root;\n root = root && root.querySelector('ha-panel-lovelace');\n root = root && root.shadowRoot;\n root = root && root.querySelector('hui-root');\n if (root) {\n const ll = root.lovelace;\n ll.current_view = root.___curView;\n return ll;\n }\n return null;\n}\n"],"names":["durationToSeconds","duration","parts","split","map","Number","formatDate","Date","toLocaleDateString","e","name","toLocaleDateStringSupportsOptions","dateObj","locales","year","month","day","fecha","format","formatDateTime","toLocaleString","toLocaleStringSupportsOptions","hour","minute","formatTime","toLocaleTimeString","toLocaleTimeStringSupportsOptions","tests","langKey","leftPad","num","computeDomain","entityId","substr","indexOf","computeRTL","hass","lang","language","translationMetadata","translations","isRTL","computeStateDomain","stateObj","entity_id","DEFAULT_DOMAIN_ICON","STATES_OFF","DOMAINS_TOGGLE","Set","fireEvent","node","type","detail","options","event","Event","bubbles","undefined","cancelable","Boolean","composed","dispatchEvent","SPECIAL_TYPES","DOMAIN_TO_ELEMENT_TYPE","alert","automation","climate","cover","fan","group","input_boolean","input_number","input_select","input_text","light","lock","media_player","remote","scene","script","sensor","timer","switch","vacuum","water_heater","input_datetime","fixedIcons","calendar","camera","configurator","conversation","device_tracker","history_graph","homeassistant","homekit","image_processing","mailbox","notify","person","plant","proximity","simple_alarm","sun","updater","weblink","domainIcon","domain","state","console","warn","forwardHaptic","hapticType","window","navigate","_node","path","replace","history","replaceState","pushState","turnOnOffEntity","turnOn","service","stateDomain","serviceDomain","callService","toggleEntity","includes","states","handleActionConfig","config","actionConfig","action","confirmation","exemptions","some","user","id","confirm","text","entity","camera_image","navigation_path","url_path","open","service_data","fixedDeviceClassIcons","humidity","illuminance","temperature","pressure","power","signal_strength","domainIcons","binary_sensor","activated","attributes","device_class","dclass","battery","isNaN","batteryRound","Math","round","unit","unit_of_measurement","has_date","has_time","localize","timeDesc","delta","compareTime","getTime","tense","abs","let","i","length","floor","includeTense","d","h","m","s","timeRemaining","remaining","now","madeActive","last_changed","max","element","themes","localTheme","updateMeta","_themes","themeName","default_theme","styles","Object","theme","keys","forEach","key","prefixedKey","updateStyles","ShadyCSS","styleSubtree","meta","document","querySelector","hasAttribute","setAttribute","getAttribute","themeColor","card","getCardSize","date","getFullYear","getMonth","getDay","cardConfig","isRow","_createError","error","_createThing","tag","createElement","setConfig","err","message","startsWith","has","customElements","get","style","display","setTimeout","whenDefined","then","clearTimeout","func","wait","immediate","timeout","context","this","callNow","apply","args","filter","value","attribute","operator","match","input","Intl","NumberFormat","defaultOptions","minimumFractionDigits","maximumFractionDigits","digits","getDefaultFormatOptions","toString","double_tap_action","hold_action","tap_action","hold","dblClick","haptic","serviceData","changedProps","forceUpdate","oldHass","entityIds","domainsToCall","push","root","shadowRoot","ll","lovelace","current_view","___curView","icon"],"mappings":"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"} \ No newline at end of file diff --git a/docs/interfaces/_fire_event_.hassdomevent.html b/docs/interfaces/_fire_event_.hassdomevent.html index 00db635..56ec3f6 100644 --- a/docs/interfaces/_fire_event_.hassdomevent.html +++ b/docs/interfaces/_fire_event_.hassdomevent.html @@ -329,7 +329,7 @@

detail

detail: T
diff --git a/docs/interfaces/_haptic_.__global.globaleventhandlerseventmap.html b/docs/interfaces/_haptic_.__global.globaleventhandlerseventmap.html index 7776da3..dfeb5f3 100644 --- a/docs/interfaces/_haptic_.__global.globaleventhandlerseventmap.html +++ b/docs/interfaces/_haptic_.__global.globaleventhandlerseventmap.html @@ -101,7 +101,7 @@

haptic

diff --git a/docs/interfaces/_haptic_.__global.hassdomevents.html b/docs/interfaces/_haptic_.__global.hassdomevents.html index a75efa7..26f84ad 100644 --- a/docs/interfaces/_haptic_.__global.hassdomevents.html +++ b/docs/interfaces/_haptic_.__global.hassdomevents.html @@ -101,7 +101,7 @@

haptic

haptic: HapticType
diff --git a/docs/interfaces/_navigate_.__global.hassdomevents.html b/docs/interfaces/_navigate_.__global.hassdomevents.html index e8fcfb7..7fb48c9 100644 --- a/docs/interfaces/_navigate_.__global.hassdomevents.html +++ b/docs/interfaces/_navigate_.__global.hassdomevents.html @@ -101,7 +101,7 @@

location-changed

location-changed: { replace: boolean }
diff --git a/docs/interfaces/_translations_localize_.formatstype.html b/docs/interfaces/_translations_localize_.formatstype.html index dcdcf99..7464efc 100644 --- a/docs/interfaces/_translations_localize_.formatstype.html +++ b/docs/interfaces/_translations_localize_.formatstype.html @@ -100,7 +100,7 @@

date

@@ -110,7 +110,7 @@

number

number: FormatType
@@ -120,7 +120,7 @@

time

diff --git a/docs/interfaces/_types_.__global.hassdomevents.html b/docs/interfaces/_types_.__global.hassdomevents.html index 5c08d40..f0c1671 100644 --- a/docs/interfaces/_types_.__global.hassdomevents.html +++ b/docs/interfaces/_types_.__global.hassdomevents.html @@ -109,7 +109,7 @@

action

action: { action: string }
@@ -127,7 +127,7 @@

config-changed

config-changed: { config: any }
@@ -145,7 +145,7 @@

hass-more-info

hass-more-info: { entityId: string | null }
@@ -163,7 +163,7 @@

ll-custom

ll-custom: {}
@@ -178,7 +178,7 @@

ll-rebuild

ll-rebuild: {}
@@ -193,7 +193,7 @@

location-changed

location-changed: { replace: boolean }
@@ -211,7 +211,7 @@

show-dialog

show-dialog: {}
@@ -226,7 +226,7 @@

undefined

undefined: any
@@ -236,7 +236,7 @@

value-changed

value-changed: { value: unknown }
diff --git a/docs/interfaces/_types_.actionhandlerdetail.html b/docs/interfaces/_types_.actionhandlerdetail.html index 74e5306..1000581 100644 --- a/docs/interfaces/_types_.actionhandlerdetail.html +++ b/docs/interfaces/_types_.actionhandlerdetail.html @@ -98,7 +98,7 @@

action

action: string
diff --git a/docs/interfaces/_types_.actionhandleroptions.html b/docs/interfaces/_types_.actionhandleroptions.html index 64e0ef4..c38bed1 100644 --- a/docs/interfaces/_types_.actionhandleroptions.html +++ b/docs/interfaces/_types_.actionhandleroptions.html @@ -99,7 +99,7 @@

Optional hasDoubleCl
hasDoubleClick: boolean
@@ -109,7 +109,7 @@

Optional hasHold

hasHold: boolean
diff --git a/docs/interfaces/_types_.baseactionconfig.html b/docs/interfaces/_types_.baseactionconfig.html index c4cc45e..de6af19 100644 --- a/docs/interfaces/_types_.baseactionconfig.html +++ b/docs/interfaces/_types_.baseactionconfig.html @@ -124,7 +124,7 @@

Optional confirmation

diff --git a/docs/interfaces/_types_.callserviceactionconfig.html b/docs/interfaces/_types_.callserviceactionconfig.html index 580df2b..1f2d621 100644 --- a/docs/interfaces/_types_.callserviceactionconfig.html +++ b/docs/interfaces/_types_.callserviceactionconfig.html @@ -108,7 +108,7 @@

action

action: "call-service"
@@ -119,7 +119,7 @@

Optional confirmation

@@ -129,7 +129,7 @@

Optional haptic

haptic: HapticType
@@ -139,7 +139,7 @@

Optional repeat

repeat: number
@@ -149,7 +149,7 @@

service

service: string
@@ -159,7 +159,7 @@

Optional service_data

service_data: { entity_id?: string | [string] }
diff --git a/docs/interfaces/_types_.confirmationrestrictionconfig.html b/docs/interfaces/_types_.confirmationrestrictionconfig.html index d6e465a..2d4db2f 100644 --- a/docs/interfaces/_types_.confirmationrestrictionconfig.html +++ b/docs/interfaces/_types_.confirmationrestrictionconfig.html @@ -99,7 +99,7 @@

Optional exemptions

exemptions: RestrictionConfig[]
@@ -109,7 +109,7 @@

Optional text

text: string
diff --git a/docs/interfaces/_types_.credential.html b/docs/interfaces/_types_.credential.html index 7458c7e..9a3c0da 100644 --- a/docs/interfaces/_types_.credential.html +++ b/docs/interfaces/_types_.credential.html @@ -99,7 +99,7 @@

auth_provider_id

auth_provider_id: string
@@ -109,7 +109,7 @@

auth_provider_type

auth_provider_type: string
diff --git a/docs/interfaces/_types_.currentuser.html b/docs/interfaces/_types_.currentuser.html index d93ec39..dd50962 100644 --- a/docs/interfaces/_types_.currentuser.html +++ b/docs/interfaces/_types_.currentuser.html @@ -103,7 +103,7 @@

credentials

credentials: Credential[]
@@ -113,7 +113,7 @@

id

id: string
@@ -123,7 +123,7 @@

is_admin

is_admin: boolean
@@ -133,7 +133,7 @@

is_owner

is_owner: boolean
@@ -143,7 +143,7 @@

mfa_modules

mfa_modules: MFAModule[]
@@ -153,7 +153,7 @@

name

name: string
diff --git a/docs/interfaces/_types_.customactionconfig.html b/docs/interfaces/_types_.customactionconfig.html index 9136f8c..bea7f70 100644 --- a/docs/interfaces/_types_.customactionconfig.html +++ b/docs/interfaces/_types_.customactionconfig.html @@ -106,7 +106,7 @@

action

action: "fire-dom-event"
@@ -117,7 +117,7 @@

Optional confirmation

@@ -127,7 +127,7 @@

Optional haptic

haptic: HapticType
@@ -137,7 +137,7 @@

Optional repeat

repeat: number
diff --git a/docs/interfaces/_types_.entitiescardentityconfig.html b/docs/interfaces/_types_.entitiescardentityconfig.html index 7373a2b..99b290e 100644 --- a/docs/interfaces/_types_.entitiescardentityconfig.html +++ b/docs/interfaces/_types_.entitiescardentityconfig.html @@ -118,7 +118,7 @@

Optional action_name

action_name: string
@@ -128,7 +128,7 @@

Optional double_tap_
double_tap_action: ActionConfig
@@ -139,7 +139,7 @@

entity

@@ -149,7 +149,7 @@

Optional hold_action

hold_action: ActionConfig
@@ -160,7 +160,7 @@

Optional icon

@@ -171,7 +171,7 @@

Optional image

@@ -182,7 +182,7 @@

Optional name

@@ -192,7 +192,7 @@

Optional secondary_infosecondary_info: "entity-id" | "last-changed" | "last-triggered" | "last-updated" | "position" | "tilt-position" | "brightness"

@@ -202,7 +202,7 @@

Optional service

service: string
@@ -212,7 +212,7 @@

Optional service_data

service_data: Record<string, unknown>
@@ -222,7 +222,7 @@

Optional show_icon

show_icon: boolean
@@ -232,7 +232,7 @@

Optional show_name

show_name: boolean
@@ -242,7 +242,7 @@

Optional state_color

state_color: boolean
@@ -252,7 +252,7 @@

Optional tap_action

tap_action: ActionConfig
@@ -263,7 +263,7 @@

Optional type

@@ -273,7 +273,7 @@

Optional url

url: string
diff --git a/docs/interfaces/_types_.entityconfig.html b/docs/interfaces/_types_.entityconfig.html index d06e3c3..644999a 100644 --- a/docs/interfaces/_types_.entityconfig.html +++ b/docs/interfaces/_types_.entityconfig.html @@ -107,7 +107,7 @@

entity

entity: string
@@ -117,7 +117,7 @@

Optional icon

icon: string
@@ -127,7 +127,7 @@

Optional image

image: string
@@ -137,7 +137,7 @@

Optional name

name: string
@@ -147,7 +147,7 @@

Optional type

type: string
diff --git a/docs/interfaces/_types_.homeassistant.html b/docs/interfaces/_types_.homeassistant.html index bfb1fd6..16a1aaa 100644 --- a/docs/interfaces/_types_.homeassistant.html +++ b/docs/interfaces/_types_.homeassistant.html @@ -120,7 +120,7 @@

auth

auth: Auth
@@ -130,7 +130,7 @@

callApi

callApi: <T>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, parameters?: {}) => Promise<T>
@@ -178,7 +178,7 @@

callService

callService: (domain: string, service: string, serviceData?: {}) => Promise<void>
@@ -220,7 +220,7 @@

callWS

callWS: <T>(msg: MessageBase) => Promise<T>
@@ -257,7 +257,7 @@

config

config: HassConfig
@@ -267,7 +267,7 @@

connected

connected: boolean
@@ -277,7 +277,7 @@

connection

connection: Connection
@@ -287,7 +287,7 @@

dockedSidebar

dockedSidebar: boolean
@@ -297,7 +297,7 @@

fetchWithAuth

fetchWithAuth: (path: string, init?: {}) => Promise<Response>
@@ -336,7 +336,7 @@

language

language: string
@@ -346,7 +346,7 @@

localize

localize: LocalizeFunc
@@ -356,7 +356,7 @@

moreInfoEntityId

moreInfoEntityId: string
@@ -366,7 +366,7 @@

panelUrl

panelUrl: string
@@ -376,7 +376,7 @@

panels

panels: Panels
@@ -386,7 +386,7 @@

resources

resources: Resources
@@ -396,7 +396,7 @@

selectedLanguage

selectedLanguage: string
@@ -406,7 +406,7 @@

Optional selectedThemeselectedTheme: string | null

@@ -416,7 +416,7 @@

sendWS

sendWS: (msg: MessageBase) => Promise<void>
@@ -447,7 +447,7 @@

services

services: HassServices
@@ -457,7 +457,7 @@

states

states: HassEntities
@@ -467,7 +467,7 @@

themes

themes: Themes
@@ -477,7 +477,7 @@

translationMetadata

translationMetadata: { fragments: string[]; translations: {} }
@@ -503,7 +503,7 @@

user

diff --git a/docs/interfaces/_types_.lovelacebadgeconfig.html b/docs/interfaces/_types_.lovelacebadgeconfig.html index 8901e63..ce5dbc9 100644 --- a/docs/interfaces/_types_.lovelacebadgeconfig.html +++ b/docs/interfaces/_types_.lovelacebadgeconfig.html @@ -102,7 +102,7 @@

Optional type

type: string
diff --git a/docs/interfaces/_types_.lovelacecard.html b/docs/interfaces/_types_.lovelacecard.html index 698aaec..c157ca8 100644 --- a/docs/interfaces/_types_.lovelacecard.html +++ b/docs/interfaces/_types_.lovelacecard.html @@ -898,7 +898,7 @@

Optional editMode

editMode: boolean
@@ -940,7 +940,7 @@

Optional hass

@@ -1037,7 +1037,7 @@

Optional isPanel

isPanel: boolean
@@ -3659,7 +3659,7 @@

getCardSize

  • Returns number | Promise<number>

    @@ -5135,7 +5135,7 @@

    setConfig

  • Parameters

    diff --git a/docs/interfaces/_types_.lovelacecardconfig.html b/docs/interfaces/_types_.lovelacecardconfig.html index 610c8ea..ac87aa2 100644 --- a/docs/interfaces/_types_.lovelacecardconfig.html +++ b/docs/interfaces/_types_.lovelacecardconfig.html @@ -104,7 +104,7 @@

    Optional index

    index: number
    @@ -114,7 +114,7 @@

    type

    type: string
    @@ -124,7 +124,7 @@

    Optional view_index

    view_index: number
    diff --git a/docs/interfaces/_types_.lovelacecardeditor.html b/docs/interfaces/_types_.lovelacecardeditor.html index 4497805..8840bf9 100644 --- a/docs/interfaces/_types_.lovelacecardeditor.html +++ b/docs/interfaces/_types_.lovelacecardeditor.html @@ -928,7 +928,7 @@

    Optional hass

    @@ -1084,7 +1084,7 @@

    Optional lovelace

    lovelace: LovelaceConfig
    @@ -5106,7 +5106,7 @@

    setConfig

  • Parameters

    diff --git a/docs/interfaces/_types_.lovelaceconfig.html b/docs/interfaces/_types_.lovelaceconfig.html index 9e42df6..5114fe9 100644 --- a/docs/interfaces/_types_.lovelaceconfig.html +++ b/docs/interfaces/_types_.lovelaceconfig.html @@ -100,7 +100,7 @@

    Optional background

    background: string
    @@ -110,7 +110,7 @@

    Optional title

    title: string
    @@ -120,7 +120,7 @@

    views

    diff --git a/docs/interfaces/_types_.lovelaceelementconfigbase.html b/docs/interfaces/_types_.lovelaceelementconfigbase.html index 3e9d64f..b952147 100644 --- a/docs/interfaces/_types_.lovelaceelementconfigbase.html +++ b/docs/interfaces/_types_.lovelaceelementconfigbase.html @@ -99,7 +99,7 @@

    style

    style: Record<string, string>
    @@ -109,7 +109,7 @@

    type

    type: string
    diff --git a/docs/interfaces/_types_.lovelaceviewconfig.html b/docs/interfaces/_types_.lovelaceviewconfig.html index 02bd457..cec9d12 100644 --- a/docs/interfaces/_types_.lovelaceviewconfig.html +++ b/docs/interfaces/_types_.lovelaceviewconfig.html @@ -107,7 +107,7 @@

    Optional background

    background: string
    @@ -117,7 +117,7 @@

    Optional badges

    badges: Array<string | LovelaceBadgeConfig>
    @@ -127,7 +127,7 @@

    Optional cards

    @@ -137,7 +137,7 @@

    Optional icon

    icon: string
    @@ -147,7 +147,7 @@

    Optional index

    index: number
    @@ -157,7 +157,7 @@

    Optional panel

    panel: boolean
    @@ -167,7 +167,7 @@

    Optional path

    path: string
    @@ -177,7 +177,7 @@

    Optional theme

    theme: string
    @@ -187,7 +187,7 @@

    Optional title

    title: string
    @@ -197,7 +197,7 @@

    Optional visible

    visible: boolean | ShowViewConfig[]
    diff --git a/docs/interfaces/_types_.mfamodule.html b/docs/interfaces/_types_.mfamodule.html index fcddaa0..7718455 100644 --- a/docs/interfaces/_types_.mfamodule.html +++ b/docs/interfaces/_types_.mfamodule.html @@ -100,7 +100,7 @@

    enabled

    enabled: boolean
    @@ -110,7 +110,7 @@

    id

    id: string
    @@ -120,7 +120,7 @@

    name

    name: string
    diff --git a/docs/interfaces/_types_.moreinfoactionconfig.html b/docs/interfaces/_types_.moreinfoactionconfig.html index da3ab48..975eca4 100644 --- a/docs/interfaces/_types_.moreinfoactionconfig.html +++ b/docs/interfaces/_types_.moreinfoactionconfig.html @@ -107,7 +107,7 @@

    action

    action: "more-info"
    @@ -118,7 +118,7 @@

    Optional confirmation

    @@ -128,7 +128,7 @@

    Optional entity

    entity: string
    @@ -138,7 +138,7 @@

    Optional haptic

    haptic: HapticType
    @@ -148,7 +148,7 @@

    Optional repeat

    repeat: number
    diff --git a/docs/interfaces/_types_.navigateactionconfig.html b/docs/interfaces/_types_.navigateactionconfig.html index 33521c9..fff3e52 100644 --- a/docs/interfaces/_types_.navigateactionconfig.html +++ b/docs/interfaces/_types_.navigateactionconfig.html @@ -107,7 +107,7 @@

    action

    action: "navigate"
    @@ -118,7 +118,7 @@

    Optional confirmation

    @@ -128,7 +128,7 @@

    Optional haptic

    haptic: HapticType
    @@ -138,7 +138,7 @@

    navigation_path

    navigation_path: string
    @@ -148,7 +148,7 @@

    Optional repeat

    repeat: number
    diff --git a/docs/interfaces/_types_.noactionconfig.html b/docs/interfaces/_types_.noactionconfig.html index 1f008bd..9dd5f07 100644 --- a/docs/interfaces/_types_.noactionconfig.html +++ b/docs/interfaces/_types_.noactionconfig.html @@ -106,7 +106,7 @@

    action

    action: "none"
    @@ -117,7 +117,7 @@

    Optional confirmation

    @@ -127,7 +127,7 @@

    Optional haptic

    haptic: HapticType
    @@ -137,7 +137,7 @@

    Optional repeat

    repeat: number
    diff --git a/docs/interfaces/_types_.panel.html b/docs/interfaces/_types_.panel.html index 250e5c8..d416f64 100644 --- a/docs/interfaces/_types_.panel.html +++ b/docs/interfaces/_types_.panel.html @@ -102,7 +102,7 @@

    component_name

    component_name: string
    @@ -112,7 +112,7 @@

    config

    config: {} | null
    @@ -122,7 +122,7 @@

    icon

    icon: string | null
    @@ -132,7 +132,7 @@

    title

    title: string | null
    @@ -142,7 +142,7 @@

    url_path

    url_path: string
    diff --git a/docs/interfaces/_types_.restrictionconfig.html b/docs/interfaces/_types_.restrictionconfig.html index f7f1ee4..622b4a1 100644 --- a/docs/interfaces/_types_.restrictionconfig.html +++ b/docs/interfaces/_types_.restrictionconfig.html @@ -98,7 +98,7 @@

    user

    user: string
    diff --git a/docs/interfaces/_types_.showviewconfig.html b/docs/interfaces/_types_.showviewconfig.html index 5c35e7b..ad1d61f 100644 --- a/docs/interfaces/_types_.showviewconfig.html +++ b/docs/interfaces/_types_.showviewconfig.html @@ -98,7 +98,7 @@

    Optional user

    user: string
    diff --git a/docs/interfaces/_types_.theme.html b/docs/interfaces/_types_.theme.html index ce91c91..ff3a6c0 100644 --- a/docs/interfaces/_types_.theme.html +++ b/docs/interfaces/_types_.theme.html @@ -100,7 +100,7 @@

    accent-color

    accent-color: string
    @@ -110,7 +110,7 @@

    primary-color

    primary-color: string
    @@ -120,7 +120,7 @@

    text-primary-color

    text-primary-color: string
    diff --git a/docs/interfaces/_types_.themes.html b/docs/interfaces/_types_.themes.html index 6119af4..d6118f0 100644 --- a/docs/interfaces/_types_.themes.html +++ b/docs/interfaces/_types_.themes.html @@ -99,7 +99,7 @@

    default_theme

    default_theme: string
    @@ -109,7 +109,7 @@

    themes

    themes: {}
    diff --git a/docs/interfaces/_types_.toggleactionconfig.html b/docs/interfaces/_types_.toggleactionconfig.html index d5e0971..832f6f4 100644 --- a/docs/interfaces/_types_.toggleactionconfig.html +++ b/docs/interfaces/_types_.toggleactionconfig.html @@ -106,7 +106,7 @@

    action

    action: "toggle"
    @@ -117,7 +117,7 @@

    Optional confirmation

    @@ -127,7 +127,7 @@

    Optional haptic

    haptic: HapticType
    @@ -137,7 +137,7 @@

    Optional repeat

    repeat: number
    diff --git a/docs/interfaces/_types_.togglemenuactionconfig.html b/docs/interfaces/_types_.togglemenuactionconfig.html index f387fc0..fc62f8d 100644 --- a/docs/interfaces/_types_.togglemenuactionconfig.html +++ b/docs/interfaces/_types_.togglemenuactionconfig.html @@ -106,7 +106,7 @@

    action

    action: "toggle-menu"
    @@ -117,7 +117,7 @@

    Optional confirmation

    @@ -127,7 +127,7 @@

    Optional haptic

    haptic: HapticType
    @@ -137,7 +137,7 @@

    Optional repeat

    repeat: number
    diff --git a/docs/interfaces/_types_.translation.html b/docs/interfaces/_types_.translation.html index 356dcec..4ffb4fe 100644 --- a/docs/interfaces/_types_.translation.html +++ b/docs/interfaces/_types_.translation.html @@ -100,7 +100,7 @@

    fingerprints

    fingerprints: {}
    @@ -118,7 +118,7 @@

    isRTL

    isRTL: boolean
    @@ -128,7 +128,7 @@

    nativeName

    nativeName: string
    diff --git a/docs/interfaces/_types_.urlactionconfig.html b/docs/interfaces/_types_.urlactionconfig.html index 21a16dd..13e187f 100644 --- a/docs/interfaces/_types_.urlactionconfig.html +++ b/docs/interfaces/_types_.urlactionconfig.html @@ -107,7 +107,7 @@

    action

    action: "url"
    @@ -118,7 +118,7 @@

    Optional confirmation

    @@ -128,7 +128,7 @@

    Optional haptic

    haptic: HapticType
    @@ -138,7 +138,7 @@

    Optional repeat

    repeat: number
    @@ -148,7 +148,7 @@

    url_path

    url_path: string
    diff --git a/docs/interfaces/_types_.window.html b/docs/interfaces/_types_.window.html index f7ef383..21a4644 100644 --- a/docs/interfaces/_types_.window.html +++ b/docs/interfaces/_types_.window.html @@ -99,7 +99,7 @@

    ShadyCSS

    ShadyCSS: { nativeCss: boolean; nativeShadow: boolean; getComputedStyleValue: any; prepareTemplate: any; styleDocument: any; styleElement: any; styleSubtree: any }
    @@ -120,7 +120,7 @@
    getComputedStyleValue:

    Parameters

    @@ -145,7 +145,7 @@
    prepareTemplate: function

    Parameters

    @@ -173,7 +173,7 @@
    styleDocument: function
  • Parameters

    @@ -195,7 +195,7 @@
    styleElement: function
  • Parameters

    @@ -217,7 +217,7 @@
    styleSubtree: function
  • Parameters

    @@ -242,7 +242,7 @@

    customPanelJS

    customPanelJS: string
    diff --git a/docs/modules/_apply_themes_on_element_.html b/docs/modules/_apply_themes_on_element_.html index 73f74d2..ee5fa2e 100644 --- a/docs/modules/_apply_themes_on_element_.html +++ b/docs/modules/_apply_themes_on_element_.html @@ -91,7 +91,7 @@

    Const applyThemesOnElem
  • diff --git a/docs/modules/_binary_sensor_icon_.html b/docs/modules/_binary_sensor_icon_.html index 125a111..f004ad1 100644 --- a/docs/modules/_binary_sensor_icon_.html +++ b/docs/modules/_binary_sensor_icon_.html @@ -91,7 +91,7 @@

    Const binarySensorIcon<
  • diff --git a/docs/modules/_compute_card_size_.html b/docs/modules/_compute_card_size_.html index 6f3c567..de0e15a 100644 --- a/docs/modules/_compute_card_size_.html +++ b/docs/modules/_compute_card_size_.html @@ -91,7 +91,7 @@

    Const computeCardSize

    Parameters

    diff --git a/docs/modules/_compute_domain_.html b/docs/modules/_compute_domain_.html index aa3d095..dae9910 100644 --- a/docs/modules/_compute_domain_.html +++ b/docs/modules/_compute_domain_.html @@ -91,7 +91,7 @@

    computeDomain

  • Parameters

    diff --git a/docs/modules/_compute_entity_.html b/docs/modules/_compute_entity_.html index 624000a..5054d45 100644 --- a/docs/modules/_compute_entity_.html +++ b/docs/modules/_compute_entity_.html @@ -91,7 +91,7 @@

    computeEntity

  • Parameters

    diff --git a/docs/modules/_compute_rtl_.html b/docs/modules/_compute_rtl_.html index 0589909..df6131c 100644 --- a/docs/modules/_compute_rtl_.html +++ b/docs/modules/_compute_rtl_.html @@ -92,7 +92,7 @@

    computeRTL

  • Parameters

    @@ -115,7 +115,7 @@

    computeRTLDirection

  • Parameters

    diff --git a/docs/modules/_compute_state_display_.html b/docs/modules/_compute_state_display_.html index 2597f39..a89c67c 100644 --- a/docs/modules/_compute_state_display_.html +++ b/docs/modules/_compute_state_display_.html @@ -91,7 +91,7 @@

    computeStateDisplay

  • Parameters

    diff --git a/docs/modules/_compute_state_domain_.html b/docs/modules/_compute_state_domain_.html index 8d2a0e8..2bde1bb 100644 --- a/docs/modules/_compute_state_domain_.html +++ b/docs/modules/_compute_state_domain_.html @@ -91,7 +91,7 @@

    computeStateDomain

  • Parameters

    diff --git a/docs/modules/_const_.html b/docs/modules/_const_.html index f63c8e0..0b65e7a 100644 --- a/docs/modules/_const_.html +++ b/docs/modules/_const_.html @@ -104,7 +104,7 @@

    Const DEFAULT_DOMAIN_IC
    DEFAULT_DOMAIN_ICON: "hass:bookmark" = "hass:bookmark"
    @@ -119,7 +119,7 @@

    Const DEFAULT_PANEL

    DEFAULT_PANEL: "lovelace" = "lovelace"
    @@ -134,7 +134,7 @@

    Const DEFAULT_VIEW_ENTI
    DEFAULT_VIEW_ENTITY_ID: "group.default_view" = "group.default_view"
    @@ -149,7 +149,7 @@

    Const DOMAINS_HIDE_MORE
    DOMAINS_HIDE_MORE_INFO: string[] = ["input_number","input_select","input_text","scene","weblink"]
    @@ -164,7 +164,7 @@

    Const DOMAINS_MORE_INFO
    DOMAINS_MORE_INFO_NO_HISTORY: string[] = ["camera","configurator","history_graph","scene"]
    @@ -179,7 +179,7 @@

    Const DOMAINS_TOGGLE

    DOMAINS_TOGGLE: Set<string> = new Set(["fan","input_boolean","light","switch","group","automation"])
    @@ -194,7 +194,7 @@

    Const DOMAINS_WITH_CARD
    DOMAINS_WITH_CARD: string[] = ["climate","cover","configurator","input_select","input_number","input_text","lock","media_player","scene","script","timer","vacuum","water_heater","weblink"]
    @@ -209,7 +209,7 @@

    Const DOMAINS_WITH_MORE
    DOMAINS_WITH_MORE_INFO: string[] = ["alarm_control_panel","automation","camera","climate","configurator","cover","fan","group","history_graph","input_datetime","light","lock","media_player","script","sun","updater","vacuum","water_heater","weather"]
    @@ -224,7 +224,7 @@

    Const STATES_OFF

    STATES_OFF: string[] = ["closed", "locked", "off"]
    @@ -239,7 +239,7 @@

    Const UNIT_C

    UNIT_C: "°C" = "°C"
    @@ -254,7 +254,7 @@

    Const UNIT_F

    UNIT_F: "°F" = "°F"
    diff --git a/docs/modules/_cover_icon_.html b/docs/modules/_cover_icon_.html index 40301c7..566ed96 100644 --- a/docs/modules/_cover_icon_.html +++ b/docs/modules/_cover_icon_.html @@ -91,7 +91,7 @@

    Const coverIcon

  • Parameters

    diff --git a/docs/modules/_create_thing_.html b/docs/modules/_create_thing_.html index 75d6aa7..9baa3e2 100644 --- a/docs/modules/_create_thing_.html +++ b/docs/modules/_create_thing_.html @@ -99,7 +99,7 @@

    Const SPECIAL_TYPES

    SPECIAL_TYPES: Set<string> = new Set(["call-service","divider","section","weblink","cast","select"])
    @@ -116,7 +116,7 @@

    Const createThing

  • Parameters

    @@ -141,7 +141,7 @@

    Const DOMAIN_TO_ELEMENT
    DOMAIN_TO_ELEMENT_TYPE: object
    @@ -150,7 +150,7 @@

    alert

    alert: string = "toggle"
    @@ -160,7 +160,7 @@

    automation

    automation: string = "toggle"
    @@ -170,7 +170,7 @@

    climate

    climate: string = "climate"
    @@ -180,7 +180,7 @@

    cover

    cover: string = "cover"
    @@ -190,7 +190,7 @@

    fan

    fan: string = "toggle"
    @@ -200,7 +200,7 @@

    group

    group: string = "group"
    @@ -210,7 +210,7 @@

    input_boolean

    input_boolean: string = "toggle"
    @@ -220,7 +220,7 @@

    input_datetime

    input_datetime: string = "input-datetime"
    @@ -230,7 +230,7 @@

    input_number

    input_number: string = "input-number"
    @@ -240,7 +240,7 @@

    input_select

    input_select: string = "input-select"
    @@ -250,7 +250,7 @@

    input_text

    input_text: string = "input-text"
    @@ -260,7 +260,7 @@

    light

    light: string = "toggle"
    @@ -270,7 +270,7 @@

    lock

    lock: string = "lock"
    @@ -280,7 +280,7 @@

    media_player

    media_player: string = "media-player"
    @@ -290,7 +290,7 @@

    remote

    remote: string = "toggle"
    @@ -300,7 +300,7 @@

    scene

    scene: string = "scene"
    @@ -310,7 +310,7 @@

    script

    script: string = "script"
    @@ -320,7 +320,7 @@

    sensor

    sensor: string = "sensor"
    @@ -330,7 +330,7 @@

    switch

    switch: string = "toggle"
    @@ -340,7 +340,7 @@

    timer

    timer: string = "timer"
    @@ -350,7 +350,7 @@

    vacuum

    vacuum: string = "toggle"
    @@ -360,7 +360,7 @@

    water_heater

    water_heater: string = "climate"
    diff --git a/docs/modules/_datetime_duration_to_seconds_.html b/docs/modules/_datetime_duration_to_seconds_.html index a735817..141bfac 100644 --- a/docs/modules/_datetime_duration_to_seconds_.html +++ b/docs/modules/_datetime_duration_to_seconds_.html @@ -91,7 +91,7 @@

    durationToSeconds

  • Parameters

    diff --git a/docs/modules/_datetime_format_date_.html b/docs/modules/_datetime_format_date_.html index 287b617..63ebf51 100644 --- a/docs/modules/_datetime_format_date_.html +++ b/docs/modules/_datetime_format_date_.html @@ -93,7 +93,7 @@

    Const formatDate

    formatDate: (Anonymous function) = (toLocaleDateStringSupportsOptions()? (dateObj: Date, locales: string) =>dateObj.toLocaleDateString(locales, {year: "numeric",month: "long",day: "numeric",}): (dateObj: Date) => fecha.format(dateObj, "mediumDate"))
    @@ -110,7 +110,7 @@

    toLocaleDateStringSupportsOptions

  • Returns boolean

    diff --git a/docs/modules/_datetime_format_date_time_.html b/docs/modules/_datetime_format_date_time_.html index 6098008..0246b31 100644 --- a/docs/modules/_datetime_format_date_time_.html +++ b/docs/modules/_datetime_format_date_time_.html @@ -93,7 +93,7 @@

    Const formatDateTimeformatDateTime: (Anonymous function) = (toLocaleStringSupportsOptions()? (dateObj: Date, locales: string) =>dateObj.toLocaleString(locales, {year: "numeric",month: "long",day: "numeric",hour: "numeric",minute: "2-digit",}): (dateObj: Date) => fecha.format(dateObj, "haDateTime"))

  • @@ -110,7 +110,7 @@

    toLocaleStringSupportsOptions

  • Returns boolean

    diff --git a/docs/modules/_datetime_format_time_.html b/docs/modules/_datetime_format_time_.html index bfedf9e..3fe33c7 100644 --- a/docs/modules/_datetime_format_time_.html +++ b/docs/modules/_datetime_format_time_.html @@ -93,7 +93,7 @@

    Const formatTime

    formatTime: (Anonymous function) = (toLocaleTimeStringSupportsOptions()? (dateObj: Date, locales: string) =>dateObj.toLocaleTimeString(locales, {hour: "numeric",minute: "2-digit",}): (dateObj: Date) => fecha.format(dateObj, "shortTime"))
    @@ -110,7 +110,7 @@

    toLocaleTimeStringSupportsOptions

  • Returns boolean

    diff --git a/docs/modules/_datetime_relative_time_.html b/docs/modules/_datetime_relative_time_.html index bc4af50..f90bed4 100644 --- a/docs/modules/_datetime_relative_time_.html +++ b/docs/modules/_datetime_relative_time_.html @@ -94,7 +94,7 @@

    Const langKey

    langKey: string[] = ["second", "minute", "hour", "day"]
    @@ -104,7 +104,7 @@

    Const tests

    tests: number[] = [60, 60, 24, 7]
    @@ -127,7 +127,7 @@

    relativeTime

  • Parameters

    diff --git a/docs/modules/_datetime_seconds_to_duration_.html b/docs/modules/_datetime_seconds_to_duration_.html index 4330b73..6724022 100644 --- a/docs/modules/_datetime_seconds_to_duration_.html +++ b/docs/modules/_datetime_seconds_to_duration_.html @@ -92,7 +92,7 @@

    Const leftPad

  • Parameters

    @@ -115,7 +115,7 @@

    secondsToDuration

  • Parameters

    diff --git a/docs/modules/_datetime_timer_time_remaining_.html b/docs/modules/_datetime_timer_time_remaining_.html index b10aaf5..61d3a48 100644 --- a/docs/modules/_datetime_timer_time_remaining_.html +++ b/docs/modules/_datetime_timer_time_remaining_.html @@ -91,7 +91,7 @@

    timerTimeRemaining

  • Parameters

    diff --git a/docs/modules/_debounce_.html b/docs/modules/_debounce_.html index c618198..b79a97f 100644 --- a/docs/modules/_debounce_.html +++ b/docs/modules/_debounce_.html @@ -91,7 +91,7 @@

    Const debounce

  • diff --git a/docs/modules/_domain_icons_.html b/docs/modules/_domain_icons_.html index b35da5a..fae6c8c 100644 --- a/docs/modules/_domain_icons_.html +++ b/docs/modules/_domain_icons_.html @@ -97,7 +97,7 @@

    domainIcon

  • Parameters

    @@ -122,7 +122,7 @@

    Const fixedIcons

    fixedIcons: object
    @@ -131,7 +131,7 @@

    alert

    alert: string = "hass:alert"
    @@ -141,7 +141,7 @@

    automation

    automation: string = "hass:playlist-play"
    @@ -151,7 +151,7 @@

    calendar

    calendar: string = "hass:calendar"
    @@ -161,7 +161,7 @@

    camera

    camera: string = "hass:video"
    @@ -171,7 +171,7 @@

    climate

    climate: string = "hass:thermostat"
    @@ -181,7 +181,7 @@

    configurator

    configurator: string = "hass:settings"
    @@ -191,7 +191,7 @@

    conversation

    conversation: string = "hass:text-to-speech"
    @@ -201,7 +201,7 @@

    device_tracker

    device_tracker: string = "hass:account"
    @@ -211,7 +211,7 @@

    fan

    fan: string = "hass:fan"
    @@ -221,7 +221,7 @@

    group

    group: string = "hass:google-circles-communities"
    @@ -231,7 +231,7 @@

    history_graph

    history_graph: string = "hass:chart-line"
    @@ -241,7 +241,7 @@

    homeassistant

    homeassistant: string = "hass:home-assistant"
    @@ -251,7 +251,7 @@

    homekit

    homekit: string = "hass:home-automation"
    @@ -261,7 +261,7 @@

    image_processing

    image_processing: string = "hass:image-filter-frames"
    @@ -271,7 +271,7 @@

    input_boolean

    input_boolean: string = "hass:drawing"
    @@ -281,7 +281,7 @@

    input_datetime

    input_datetime: string = "hass:calendar-clock"
    @@ -291,7 +291,7 @@

    input_number

    input_number: string = "hass:ray-vertex"
    @@ -301,7 +301,7 @@

    input_select

    input_select: string = "hass:format-list-bulleted"
    @@ -311,7 +311,7 @@

    input_text

    input_text: string = "hass:textbox"
    @@ -321,7 +321,7 @@

    light

    light: string = "hass:lightbulb"
    @@ -331,7 +331,7 @@

    mailbox

    mailbox: string = "hass:mailbox"
    @@ -341,7 +341,7 @@

    notify

    notify: string = "hass:comment-alert"
    @@ -351,7 +351,7 @@

    person

    person: string = "hass:account"
    @@ -361,7 +361,7 @@

    plant

    plant: string = "hass:flower"
    @@ -371,7 +371,7 @@

    proximity

    proximity: string = "hass:apple-safari"
    @@ -381,7 +381,7 @@

    remote

    remote: string = "hass:remote"
    @@ -391,7 +391,7 @@

    scene

    scene: string = "hass:google-pages"
    @@ -401,7 +401,7 @@

    script

    script: string = "hass:file-document"
    @@ -411,7 +411,7 @@

    sensor

    sensor: string = "hass:eye"
    @@ -421,7 +421,7 @@

    simple_alarm

    simple_alarm: string = "hass:bell"
    @@ -431,7 +431,7 @@

    sun

    sun: string = "hass:white-balance-sunny"
    @@ -441,7 +441,7 @@

    switch

    switch: string = "hass:flash"
    @@ -451,7 +451,7 @@

    timer

    timer: string = "hass:timer"
    @@ -461,7 +461,7 @@

    updater

    updater: string = "hass:cloud-upload"
    @@ -471,7 +471,7 @@

    vacuum

    vacuum: string = "hass:robot-vacuum"
    @@ -481,7 +481,7 @@

    water_heater

    water_heater: string = "hass:thermometer"
    @@ -491,7 +491,7 @@

    weblink

    weblink: string = "hass:open-in-new"
    diff --git a/docs/modules/_evaluate_filter_.html b/docs/modules/_evaluate_filter_.html index 71988aa..b80ec4a 100644 --- a/docs/modules/_evaluate_filter_.html +++ b/docs/modules/_evaluate_filter_.html @@ -91,7 +91,7 @@

    Const evaluateFilter

  • Parameters

    diff --git a/docs/modules/_fire_event_.html b/docs/modules/_fire_event_.html index ea8416c..5c5f88a 100644 --- a/docs/modules/_fire_event_.html +++ b/docs/modules/_fire_event_.html @@ -105,7 +105,7 @@

    ValidHassDomEvent

    ValidHassDomEvent: keyof HASSDomEvents
    @@ -122,7 +122,7 @@

    Const fireEvent

  • diff --git a/docs/modules/_format_number_.html b/docs/modules/_format_number_.html index de89d7d..53a476d 100644 --- a/docs/modules/_format_number_.html +++ b/docs/modules/_format_number_.html @@ -92,7 +92,7 @@

    Const formatNumber

  • @@ -136,7 +136,7 @@

    Const getDefaultFormat<
  • diff --git a/docs/modules/_get_lovelace_.html b/docs/modules/_get_lovelace_.html index 711224a..05b7c47 100644 --- a/docs/modules/_get_lovelace_.html +++ b/docs/modules/_get_lovelace_.html @@ -91,7 +91,7 @@

    Const getLovelace

  • Returns any

    diff --git a/docs/modules/_handle_action_.html b/docs/modules/_handle_action_.html index 3ed4237..7085c98 100644 --- a/docs/modules/_handle_action_.html +++ b/docs/modules/_handle_action_.html @@ -92,7 +92,7 @@

    Const handleAction

  • Parameters

    @@ -141,7 +141,7 @@

    Const handleActionConfi
  • Parameters

    diff --git a/docs/modules/_handle_click_.html b/docs/modules/_handle_click_.html index bfee04a..ecf60f6 100644 --- a/docs/modules/_handle_click_.html +++ b/docs/modules/_handle_click_.html @@ -91,7 +91,7 @@

    Const handleClick

  • Parameters

    diff --git a/docs/modules/_haptic_.html b/docs/modules/_haptic_.html index f624b19..1b0eb4e 100644 --- a/docs/modules/_haptic_.html +++ b/docs/modules/_haptic_.html @@ -99,7 +99,7 @@

    HapticType

    HapticType: "success" | "warning" | "failure" | "light" | "medium" | "heavy" | "selection"
    @@ -121,7 +121,7 @@

    Const forwardHaptic

  • Parameters

    diff --git a/docs/modules/_has_action_.html b/docs/modules/_has_action_.html index 88958c2..baf0895 100644 --- a/docs/modules/_has_action_.html +++ b/docs/modules/_has_action_.html @@ -91,7 +91,7 @@

    hasAction

  • Parameters

    diff --git a/docs/modules/_has_changed_.html b/docs/modules/_has_changed_.html index 77f2cdc..9cfeec7 100644 --- a/docs/modules/_has_changed_.html +++ b/docs/modules/_has_changed_.html @@ -91,7 +91,7 @@

    hasConfigOrEntityChanged

  • Parameters

    diff --git a/docs/modules/_has_double_click_.html b/docs/modules/_has_double_click_.html index b41e6aa..fbbad01 100644 --- a/docs/modules/_has_double_click_.html +++ b/docs/modules/_has_double_click_.html @@ -91,7 +91,7 @@

    hasDoubleClick

  • Parameters

    diff --git a/docs/modules/_input_datetime_icon_.html b/docs/modules/_input_datetime_icon_.html index 74e23d0..4c5055f 100644 --- a/docs/modules/_input_datetime_icon_.html +++ b/docs/modules/_input_datetime_icon_.html @@ -91,7 +91,7 @@

    Const inputDateTime

    Parameters

    diff --git a/docs/modules/_navigate_.html b/docs/modules/_navigate_.html index 5840292..b9d1a04 100644 --- a/docs/modules/_navigate_.html +++ b/docs/modules/_navigate_.html @@ -97,7 +97,7 @@

    Const navigate

  • Parameters

    diff --git a/docs/modules/_scroll_to_target_.html b/docs/modules/_scroll_to_target_.html index 375c7a4..0292cd5 100644 --- a/docs/modules/_scroll_to_target_.html +++ b/docs/modules/_scroll_to_target_.html @@ -91,7 +91,7 @@

    scrollToTarget

  • diff --git a/docs/modules/_sensor_icon_.html b/docs/modules/_sensor_icon_.html index 4a98138..59b2df3 100644 --- a/docs/modules/_sensor_icon_.html +++ b/docs/modules/_sensor_icon_.html @@ -97,7 +97,7 @@

    Const sensorIcon

  • Parameters

    @@ -119,7 +119,7 @@

    Const fixedDeviceClass<
    fixedDeviceClassIcons: object
    @@ -128,7 +128,7 @@

    humidity

    humidity: string = "hass:water-percent"
    @@ -138,7 +138,7 @@

    illuminance

    illuminance: string = "hass:brightness-5"
    @@ -148,7 +148,7 @@

    power

    power: string = "hass:flash"
    @@ -158,7 +158,7 @@

    pressure

    pressure: string = "hass:gauge"
    @@ -168,7 +168,7 @@

    signal_strength

    signal_strength: string = "hass:wifi"
    @@ -178,7 +178,7 @@

    temperature

    temperature: string = "hass:thermometer"
    diff --git a/docs/modules/_state_icon_.html b/docs/modules/_state_icon_.html index aa769c0..ace2a65 100644 --- a/docs/modules/_state_icon_.html +++ b/docs/modules/_state_icon_.html @@ -97,7 +97,7 @@

    Const stateIcon

  • Parameters

    @@ -119,7 +119,7 @@

    Const domainIcons

    domainIcons: object
    @@ -128,7 +128,7 @@

    binary_sensor

    binary_sensor: binarySensorIcon = binarySensorIcon
    @@ -138,7 +138,7 @@

    cover

    cover: coverIcon = coverIcon
    @@ -148,7 +148,7 @@

    input_datetime

    input_datetime: inputDateTimeIcon = inputDateTimeIcon
    @@ -158,7 +158,7 @@

    sensor

    sensor: sensorIcon = sensorIcon
    diff --git a/docs/modules/_toggle_entity_.html b/docs/modules/_toggle_entity_.html index 9f3a6df..e527c6e 100644 --- a/docs/modules/_toggle_entity_.html +++ b/docs/modules/_toggle_entity_.html @@ -91,7 +91,7 @@

    Const toggleEntity

  • Parameters

    diff --git a/docs/modules/_translations_localize_.html b/docs/modules/_translations_localize_.html index c4ddc4c..893b3cd 100644 --- a/docs/modules/_translations_localize_.html +++ b/docs/modules/_translations_localize_.html @@ -101,7 +101,7 @@

    LocalizeFunc

    LocalizeFunc: (key: string, ...args: any[]) => string
    @@ -142,7 +142,7 @@

    Const computeLocalize

  • @@ -184,7 +184,7 @@

    Const localizeKey

  • diff --git a/docs/modules/_turn_on_off_entities_.html b/docs/modules/_turn_on_off_entities_.html index cf0e601..f67d91a 100644 --- a/docs/modules/_turn_on_off_entities_.html +++ b/docs/modules/_turn_on_off_entities_.html @@ -91,7 +91,7 @@

    Const turnOnOffEntities
  • Parameters

    diff --git a/docs/modules/_turn_on_off_entity_.html b/docs/modules/_turn_on_off_entity_.html index 294cae5..ad09925 100644 --- a/docs/modules/_turn_on_off_entity_.html +++ b/docs/modules/_turn_on_off_entity_.html @@ -91,7 +91,7 @@

    Const turnOnOffEntity

    Parameters

    diff --git a/docs/modules/_types_.html b/docs/modules/_types_.html index 9606b51..8f11aaf 100644 --- a/docs/modules/_types_.html +++ b/docs/modules/_types_.html @@ -135,7 +135,7 @@

    ActionConfig

    @@ -145,7 +145,7 @@

    ActionHandlerEvent

    ActionHandlerEvent: HASSDomEvent<ActionHandlerDetail>
    @@ -155,7 +155,7 @@

    LocalizeFunc

    LocalizeFunc: (key: string, ...args: any[]) => string
    @@ -189,7 +189,7 @@

    ValidHassDomEvent

    ValidHassDomEvent: keyof HASSDomEvents
    diff --git a/package.json b/package.json index 3d992d1..7e55b69 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "custom-card-helpers", - "version": "1.6.9", + "version": "1.7.0", "description": "Set of helpful functions and types for Custom Card creators", "main": "dist/index.js", "umd:main": "dist/index.umd.js",