diff --git a/www/community/Filament-Card/filament-card.js b/www/community/Filament-Card/filament-card.js new file mode 100644 index 00000000..379e9cfc --- /dev/null +++ b/www/community/Filament-Card/filament-card.js @@ -0,0 +1,2576 @@ +var At = Object.defineProperty; +var wt = (a, t, e) => t in a ? At(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e; +var j = (a, t, e) => wt(a, typeof t != "symbol" ? t + "" : t, e); +const J = "filament-card", Q = "filament-card-editor", S = { + preset: "spoolman", + title: "Filament", + group_by: "material", + group_sort_by: "name", + group_sort_direction: "asc", + group_order: [], + group_icon: "mdi:printer-3d-nozzle", + group_title_actions: {}, + group_title_icons: {}, + group_title_colors: {}, + max_weight: 1e3, + hide_archived: !0, + sort_by: "remaining_weight", + sort_direction: "asc", + bar_direction: "vertical", + name_position: "bottom", + show_name: !0, + show_group_title: !0, + value_position: "center", + use_filament_color: !0, + // Custom mode + custom_attribute_entities: [], + custom_items: [], + custom_max_value: 1e3, + custom_unit: "g", + custom_label_id: "", + tap_action: { + action: "more-info" + }, + double_tap_action: { + action: "none" + }, + hold_action: { + action: "none" + }, + spool_actions: {} +}, St = ` +ha-card { + padding: 16px; +} + +.title { + font-size: 20px; + font-weight: 600; + margin-bottom: 16px; +} + +.heading { + display: flex; + align-items: center; + gap: 8px; + font-size: 18px; + font-weight: 600; + margin: 18px 0 10px; +} + +.heading:first-child { + margin-top: 0; +} + +.heading ha-icon { + --mdc-icon-size: 20px; + color: var(--secondary-text-color); +} + +.heading.clickable { + cursor: pointer; + user-select: none; +} + +.heading.clickable:hover { + opacity: 0.85; +} + +.spools { + display: flex; + gap: 0; + overflow-x: auto; + align-items: flex-end; + padding-bottom: 4px; +} + +.spools.horizontal { + flex-direction: column; + align-items: stretch; + gap: 6px; +} + +.spool { + width: 70px; + min-width: 70px; + text-align: center; + cursor: pointer; + padding: 8px 4px; + box-sizing: border-box; +} + +.spool.vertical { + width: 70px; + min-width: 70px; +} + +.spool.vertical.name-top { + display: flex; + flex-direction: column; +} + +.spool.vertical.name-top .name { + order: -1; + margin-top: 0; + margin-bottom: 6px; +} + +.spool.horizontal { + width: 100%; + min-width: 160px; + display: grid; + grid-template-columns: 1fr; +} + +.spool.horizontal.name-left, +.spool.horizontal.name-right { + display: grid; + grid-template-columns: auto 1fr; + align-items: center; + gap: 8px; +} + +.spool.horizontal.name-right { + grid-template-columns: 1fr auto; +} + +.spool.horizontal.name-left .name, +.spool.horizontal.name-right .name { + margin-top: 0; + white-space: nowrap; +} + +.bar { + height: 200px; + border-radius: 10px; + background: var(--divider-color); + position: relative; + overflow: hidden; +} + +.spool.horizontal .bar { + height: 28px; +} + +.fill { + position: absolute; + left: 0; + bottom: 0; + background: var(--primary-color); +} + +.spool.vertical .fill { + width: 100%; + height: 0; + border-radius: 10px 10px 0 0; +} + +.spool.horizontal .fill { + top: 0; + bottom: 0; + height: 100%; + width: 0; + border-radius: 10px 0 0 10px; +} + +.value { + position: absolute; + z-index: 2; + left: 0; + right: 0; + bottom: 20px; + font-size: 15px; + font-weight: 700; + text-align: center; + text-shadow: 0 1px 2px rgba(0,0,0,.25); +} + +.spool.vertical.value-top .value { + top: 12px; + bottom: auto; +} + +.spool.vertical.value-center .value { + top: 50%; + bottom: auto; + transform: translateY(-50%); +} + +.spool.vertical.value-bottom .value { + bottom: 20px; +} + +.spool.horizontal .value { + top: 50%; + bottom: auto; + transform: translateY(-50%); +} + +.spool.horizontal.value-left .value { + left: 10px; + right: auto; + text-align: left; +} + +.spool.horizontal.value-center .value { + left: 0; + right: 0; + text-align: center; +} + +.spool.horizontal.value-right .value { + left: auto; + right: 10px; + text-align: right; +} + +.name { + font-size: 12px; + font-weight: bold; + margin-top: 6px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.spool.horizontal .name { + text-align: left; + margin-top: 4px; +} + +.empty { + color: var(--secondary-text-color); + padding: 8px 0; +} + +.expandable-section { + border: 1px solid var(--divider-color); + border-radius: 8px; + overflow: hidden; +} + +.expandable-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 12px; + cursor: pointer; + user-select: none; + font-weight: 500; + background: var(--secondary-background-color); +} + +.expandable-header:hover { + filter: brightness(1.03); +} + +.expandable-content { + display: grid; + gap: 12px; + padding: 12px; +} +`; +function Ct(a) { + return a ? a.startsWith("#") ? a : `#${a}` : "#999999"; +} +function A(a) { + if (!a || a.startsWith("var(")) + return "var(--primary-text-color)"; + const t = a.replace("#", ""); + if (t.length !== 6) + return "var(--primary-text-color)"; + const e = parseInt(t.substring(0, 2), 16), n = parseInt(t.substring(2, 4), 16), i = parseInt(t.substring(4, 6), 16); + return (e * 299 + n * 587 + i * 114) / 1e3 > 140 ? "black" : "white"; +} +function Et(a, t, e) { + const n = a.value_position || "center"; + return a.use_filament_color ? a.bar_direction === "horizontal" ? n === "left" && e >= 15 || n === "center" && e >= 50 || n === "right" && e >= 85 ? A(t) : "var(--primary-text-color)" : a.bar_direction === "vertical" && (n === "bottom" && e >= 15 || n === "center" && e >= 50 || n === "top" && e >= 85) ? A(t) : "var(--primary-text-color)" : "var(--primary-text-color)"; +} +function Tt(a, t, e) { + return a.bar_direction === "horizontal" ? `width:${t}%; background:${e};` : `height:${t}%; background:${e};`; +} +function C(a, t) { + const e = t.state.attributes; + return a.group_by === "color" ? e.filament_name || e.filament_color_hex || "unknown" : a.group_by === "material" ? e.filament_material || "unknown" : a.group_by === "vendor" ? e.filament_vendor_name || "unknown" : "all"; +} +function B(a, t, e) { + const n = a.sort_by, i = a.sort_direction === "desc" ? -1 : 1, r = t.state.attributes[n] ?? t.state.state ?? "", s = e.state.attributes[n] ?? e.state.state ?? "", o = Number(r), l = Number(s); + return !Number.isNaN(o) && !Number.isNaN(l) ? (o - l) * i : String(r).localeCompare(String(s), void 0, { numeric: !0 }) * i; +} +function Nt(a, t, e, n) { + const i = a.group_sort_direction === "desc" ? -1 : 1, r = n.filter((o) => C(a, o) === t), s = n.filter((o) => C(a, o) === e); + switch (a.group_sort_by) { + case "total_remaining_weight": { + const o = r.reduce((c, h) => c + Number(h.state.attributes.remaining_weight || 0), 0), l = s.reduce((c, h) => c + Number(h.state.attributes.remaining_weight || 0), 0); + return (o - l) * i; + } + case "max_remaining_weight": { + const o = Math.max(...r.map((c) => Number(c.state.attributes.remaining_weight || 0))), l = Math.max(...s.map((c) => Number(c.state.attributes.remaining_weight || 0))); + return (o - l) * i; + } + case "spool_count": + return (r.length - s.length) * i; + case "name": + default: + return String(t).localeCompare(String(e), void 0, { numeric: !0 }) * i; + } +} +function gt(a, t, e) { + var n; + if ((n = a.group_order) != null && n.length) { + const i = a.group_order.map((r) => String(r)); + return t.sort((r, s) => { + const o = i.indexOf(String(r)), l = i.indexOf(String(s)), c = o !== -1, h = l !== -1; + return c && h ? o - l : c ? -1 : h ? 1 : String(r).localeCompare(String(s), void 0, { numeric: !0 }); + }); + } + return t.sort((i, r) => Nt(a, i, r, e)); +} +class Ot extends HTMLElement { + static getConfigElement() { + return document.createElement(Q); + } + static getStubConfig() { + return { ...S }; + } + setConfig(t) { + this.config = { + ...S, + group_by: t.group_by ?? (t.group_by_material === !1 ? "none" : "material"), + group_order: t.group_order ?? t.materials ?? S.group_order, + ...t + }, this.shadowRoot || this.attachShadow({ mode: "open" }); + } + set hass(t) { + const e = this._spoolSignature; + this._hass = t, this._spoolSignature = this.createSpoolSignature(t), (!e || e !== this._spoolSignature) && this.render(); + } + createSpoolSignature(t) { + var n; + const e = ((n = this.config) == null ? void 0 : n.preset) || "spoolman"; + if (e === "custom_attributes") + return (this.config.custom_attribute_entities || []).map((i) => { + const r = t.states[i]; + if (!r) return `${i}|missing`; + const s = r.attributes || {}; + return [ + i, + r.state, + s.value, + s.remaining_weight, + s.max_value, + s.max, + s.name, + s.friendly_name, + s.group, + s.material, + s.vendor, + s.color, + s.filament_color_hex, + s.unit + ].join("|"); + }).sort().join(";"); + if (e === "custom_entities") + return (this.config.custom_items || []).map((i, r) => { + const s = [ + i.value_entity, + i.max_entity, + i.color_entity, + i.group_entity, + i.vendor_entity, + i.name_entity + ].filter(Boolean); + return [ + r, + i.name, + i.group, + i.vendor, + i.color, + i.max, + i.max_value, + i.unit, + ...s.map((o) => { + var c; + const l = t.states[o]; + return l ? `${o}|${l.state}|${((c = l.attributes) == null ? void 0 : c.friendly_name) || ""}` : `${o}|missing`; + }) + ].join("|"); + }).sort().join(";"); + if (e === "custom_label") { + const i = this.config.custom_label_id; + return !i || !t.entities ? "" : Object.entries(t.entities).filter(([, r]) => { + var s; + return (s = r.labels) == null ? void 0 : s.includes(i); + }).map(([r]) => { + const s = t.states[r]; + if (!s) return `${r}|missing`; + const o = s.attributes || {}; + return [ + r, + s.state, + o.value, + o.remaining_weight, + o.max_value, + o.max, + o.name, + o.friendly_name, + o.group, + o.material, + o.vendor, + o.color, + o.filament_color_hex, + o.unit + ].join("|"); + }).sort().join(";"); + } + return Object.entries(t.states).filter(([, i]) => { + var r; + return (r = i.attributes) == null ? void 0 : r.filament_material; + }).map(([i, r]) => { + const s = r.attributes; + return [ + i, + r.state, + s.remaining_weight, + s.filament_weight, + s.archived, + s.filament_material, + s.filament_name, + s.filament_color_hex, + s.filament_vendor_name + ].join("|"); + }).sort().join(";"); + } + render() { + if (!this._hass || !this.config) return; + const t = this.getItems(); + this._actionConfigsByEntity = Object.fromEntries( + t.map((i) => [i.entity_id, this.getActionConfigsForItem(i)]) + ); + const e = Math.max( + ...t.map( + (i) => Number(i.state.attributes.filament_weight || i.state.attributes.remaining_weight || 0) + ), + Number(this.config.max_weight || 0), + 1e3 + ), n = this.config.group_by === "none" ? this.renderFlat(t, e) : this.renderGrouped(t, e); + this.shadowRoot.innerHTML = ` + + + + ${this.config.title ? `
${this.config.title}
` : ""} + ${n} +
+ `, this.attachActionHandlers(), this.attachGroupTitleActionHandlers(); + } + getItems() { + const t = this.config.preset || "spoolman"; + let e; + return t === "custom_attributes" ? e = this.getCustomAttributeItems() : t === "custom_entities" ? e = this.getCustomEntityItems() : t === "custom_label" ? e = this.getCustomLabelItems() : e = this.getSpoolmanItems(), this.applyFilters(e); + } + applyFilters(t) { + if (this.config.group_by === "none") + return t; + const e = this.config.filters || {}, n = this.normalizeFilterValues(e.include), i = this.normalizeFilterValues(e.exclude); + return !n.length && !i.length ? t : t.filter((r) => { + const s = C(this.config, r), o = this.normalizeFilterValue(s); + return !(n.length && !n.includes(o) || i.includes(o)); + }); + } + normalizeFilterValues(t) { + return Array.isArray(t) ? t.map((e) => this.normalizeFilterValue(e)).filter(Boolean) : []; + } + normalizeFilterValue(t) { + return String(t ?? "").trim().toLocaleLowerCase(); + } + getSpoolmanItems() { + return Object.entries(this._hass.states).map(([t, e]) => ({ entity_id: t, state: e })).filter(({ state: t }) => { + var e; + return (e = t.attributes) == null ? void 0 : e.filament_material; + }).filter(({ state: t }) => !this.config.hide_archived || t.attributes.archived === !1).sort((t, e) => B(this.config, t, e)); + } + getCustomAttributeItems() { + const t = this.config.custom_attribute_entities || [], e = Number(this.config.custom_max_value || 1e3), n = this.config.custom_unit || "g"; + return t.map((i) => { + const r = this._hass.states[i]; + if (!r) return null; + const s = r.attributes || {}, o = Number(s.value ?? s.remaining_weight ?? r.state); + return Number.isNaN(o) ? null : this.createVirtualItem({ + entity_id: i, + value: o, + max: Number(s.max_value ?? s.max ?? e), + name: s.name || s.friendly_name || i, + group: s.group || s.material || "Custom", + vendor: s.vendor || "", + color: s.color || s.filament_color_hex, + unit: s.unit || n, + tap_action: s.tap_action, + double_tap_action: s.double_tap_action, + hold_action: s.hold_action + }); + }).filter(Boolean).sort((i, r) => B(this.config, i, r)); + } + getCustomEntityItems() { + const t = this.config.custom_items || [], e = Number(this.config.custom_max_value || 1e3), n = this.config.custom_unit || "g"; + return t.map((i, r) => { + var m, g, N, O, P, H; + const s = this._hass.states[i.value_entity]; + if (!s) return null; + const o = Number(s.state); + if (Number.isNaN(o)) return null; + const l = i.max_entity ? Number(((m = this._hass.states[i.max_entity]) == null ? void 0 : m.state) ?? e) : Number(i.max ?? i.max_value ?? e), c = i.color_entity ? (g = this._hass.states[i.color_entity]) == null ? void 0 : g.state : i.color, h = i.group_entity ? (N = this._hass.states[i.group_entity]) == null ? void 0 : N.state : i.group, d = i.vendor_entity ? (O = this._hass.states[i.vendor_entity]) == null ? void 0 : O.state : i.vendor, _ = i.name_entity ? (P = this._hass.states[i.name_entity]) == null ? void 0 : P.state : i.name; + return this.createVirtualItem({ + entity_id: i.value_entity || `custom_item_${r}`, + value: o, + max: Number.isNaN(l) ? e : l, + name: _ || ((H = s.attributes) == null ? void 0 : H.friendly_name) || i.value_entity, + group: h || "Custom", + vendor: d || "", + color: c, + unit: i.unit || n, + tap_action: i.tap_action, + double_tap_action: i.double_tap_action, + hold_action: i.hold_action + }); + }).filter(Boolean).sort((i, r) => B(this.config, i, r)); + } + getCustomLabelItems() { + var n; + const t = this.config.custom_label_id; + if (!t || !((n = this._hass) != null && n.entities)) return []; + const e = Object.entries(this._hass.entities).filter(([, i]) => { + var r; + return (r = i.labels) == null ? void 0 : r.includes(t); + }).map(([i]) => i); + return this.config.custom_attribute_entities = e, this.getCustomAttributeItems(); + } + getActionConfigsForItem(t) { + var r, s; + const e = t.entity_id, n = ((r = t.state) == null ? void 0 : r.attributes) || {}, i = ((s = this.config.spool_actions) == null ? void 0 : s[e]) || {}; + return { + tap: n.tap_action || t.tap_action || i.tap_action || this.config.tap_action, + double_tap: n.double_tap_action || t.double_tap_action || i.double_tap_action || this.config.double_tap_action, + hold: n.hold_action || t.hold_action || i.hold_action || this.config.hold_action + }; + } + getGroupTitleActionConfigs(t) { + var n, i; + const e = ((n = this.config.group_title_actions) == null ? void 0 : n[t]) || ((i = this.config.group_actions) == null ? void 0 : i[t]) || {}; + return { + tap: e.tap_action || { action: "none" }, + double_tap: e.double_tap_action || { action: "none" }, + hold: e.hold_action || { action: "none" } + }; + } + getGroupTitleIcon(t) { + var e, n; + return ((e = this.config.group_title_icons) == null ? void 0 : e[t]) || ((n = this.config.group_icons) == null ? void 0 : n[t]) || this.config.group_icon; + } + getGroupTitleColor(t) { + var e, n; + return ((e = this.config.group_title_colors) == null ? void 0 : e[t]) || ((n = this.config.group_colors) == null ? void 0 : n[t]); + } + attachGroupTitleActionHandlers() { + this.shadowRoot.querySelectorAll(".heading[data-group]").forEach((t) => { + const e = t.dataset.group; + if (!e) return; + const n = this.getGroupTitleActionConfigs(e); + t.addEventListener("click", (i) => { + i.stopPropagation(), this.handleTap(e, n); + }), t.addEventListener("dblclick", (i) => { + i.stopPropagation(), this.handleDoubleTap(e, n); + }), t.addEventListener( + "pointerdown", + () => this.handleHoldStart(e, n) + ), t.addEventListener("pointerup", () => this.handleHoldEnd()), t.addEventListener("pointerleave", () => this.handleHoldEnd()), t.addEventListener("pointercancel", () => this.handleHoldEnd()); + }); + } + createVirtualItem({ + entity_id: t, + value: e, + max: n, + name: i, + group: r, + vendor: s, + color: o, + unit: l, + tap_action: c, + double_tap_action: h, + hold_action: d + }) { + return { + entity_id: t, + tap_action: c, + double_tap_action: h, + hold_action: d, + state: { + state: String(e), + attributes: { + friendly_name: i, + remaining_weight: e, + filament_weight: n, + filament_material: r, + filament_name: i, + filament_vendor_name: s, + filament_color_hex: o, + archived: !1, + custom_unit: l, + tap_action: c, + double_tap_action: h, + hold_action: d + } + } + }; + } + fireHassAction(t, e, n) { + this.dispatchEvent( + new CustomEvent("hass-action", { + detail: { + config: { + entity: t, + tap_action: e.tap || { action: "more-info" }, + double_tap_action: e.double_tap || { action: "none" }, + hold_action: e.hold || { action: "none" } + }, + action: n + }, + bubbles: !0, + composed: !0 + }) + ); + } + handleTap(t, e) { + if (this._holdFired) { + this._holdFired = !1; + return; + } + clearTimeout(this._tapTimer), this._tapTimer = setTimeout(() => { + this.fireHassAction(t, e, "tap"); + }, 250); + } + handleDoubleTap(t, e) { + clearTimeout(this._tapTimer), this.fireHassAction(t, e, "double_tap"); + } + handleHoldStart(t, e) { + this._holdFired = !1, clearTimeout(this._holdTimer), this._holdTimer = setTimeout(() => { + this._holdFired = !0, this.fireHassAction(t, e, "hold"); + }, 500); + } + handleHoldEnd() { + clearTimeout(this._holdTimer); + } + attachActionHandlers() { + this.shadowRoot.querySelectorAll(".spool").forEach((t) => { + var i; + const e = t.dataset.entity; + if (!e) return; + const n = ((i = this._actionConfigsByEntity) == null ? void 0 : i[e]) || { + tap: this.config.tap_action, + double_tap: this.config.double_tap_action, + hold: this.config.hold_action + }; + t.addEventListener("click", (r) => { + r.stopPropagation(), this.handleTap(e, n); + }), t.addEventListener("dblclick", (r) => { + r.stopPropagation(), this.handleDoubleTap(e, n); + }), t.addEventListener( + "pointerdown", + () => this.handleHoldStart(e, n) + ), t.addEventListener("pointerup", () => this.handleHoldEnd()), t.addEventListener("pointerleave", () => this.handleHoldEnd()), t.addEventListener("pointercancel", () => this.handleHoldEnd()); + }); + } + renderGrouped(t, e) { + let n = [...new Set(t.map((i) => C(this.config, i)))]; + return n = gt(this.config, n, t), n.map((i) => { + const r = this.getGroupTitleIcon(i), s = this.getGroupTitleColor(i); + this.getGroupTitleActionConfigs(i); + const o = t.filter((l) => C(this.config, l) === i); + return o.length ? ` + ${this.config.show_group_title ? ` +
+ ${r !== "none" ? `` : ""} + + ${i} + +
+ ` : ""} + +
+ ${o.map((l) => this.renderSpool(l, e)).join("")} +
+ ` : ""; + }).join(""); + } + renderFlat(t, e) { + return t.length ? ` +
+ ${t.map((n) => this.renderSpool(n, e)).join("")} +
+ ` : '
Keine Filamente gefunden.
'; + } + renderSpool({ entity_id: t, state: e }, n) { + const i = e.attributes, r = Number(i.remaining_weight ?? e.state ?? 0), s = Number(i.filament_weight || n || 1e3), o = Math.max(0, Math.min(100, r / s * 100)), l = this.config.use_filament_color ? Ct(i.filament_color_hex) : "var(--primary-color)", c = Et(this.config, l, o), h = this.config.group_by === "color" ? i.filament_material || i.friendly_name || t : i.filament_name || i.friendly_name || t; + return ` +
+ ${this.config.show_name && ["top", "left"].includes(this.config.name_position) ? `
${h}
` : ""} + +
+
+
${r.toFixed(1)}${i.custom_unit || "g"}
+
+ + ${this.config.show_name && ["bottom", "right"].includes(this.config.name_position) ? `
${h}
` : ""} +
+ `; + } + getCardSize() { + return 4; + } +} +customElements.get(J) || customElements.define(J, Ot); +/** + * @license + * Copyright 2019 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const M = globalThis, tt = M.ShadowRoot && (M.ShadyCSS === void 0 || M.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, et = Symbol(), nt = /* @__PURE__ */ new WeakMap(); +let ft = class { + constructor(t, e, n) { + if (this._$cssResult$ = !0, n !== et) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); + this.cssText = t, this.t = e; + } + get styleSheet() { + let t = this.o; + const e = this.t; + if (tt && t === void 0) { + const n = e !== void 0 && e.length === 1; + n && (t = nt.get(e)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), n && nt.set(e, t)); + } + return t; + } + toString() { + return this.cssText; + } +}; +const Pt = (a) => new ft(typeof a == "string" ? a : a + "", void 0, et), Ht = (a, ...t) => { + const e = a.length === 1 ? a[0] : t.reduce((n, i, r) => n + ((s) => { + if (s._$cssResult$ === !0) return s.cssText; + if (typeof s == "number") return s; + throw Error("Value passed to 'css' function must be a 'css' function result: " + s + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); + })(i) + a[r + 1], a[0]); + return new ft(e, a, et); +}, It = (a, t) => { + if (tt) a.adoptedStyleSheets = t.map((e) => e instanceof CSSStyleSheet ? e : e.styleSheet); + else for (const e of t) { + const n = document.createElement("style"), i = M.litNonce; + i !== void 0 && n.setAttribute("nonce", i), n.textContent = e.cssText, a.appendChild(n); + } +}, rt = tt ? (a) => a : (a) => a instanceof CSSStyleSheet ? ((t) => { + let e = ""; + for (const n of t.cssRules) e += n.cssText; + return Pt(e); +})(a) : a; +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const { is: kt, defineProperty: Vt, getOwnPropertyDescriptor: Gt, getOwnPropertyNames: zt, getOwnPropertySymbols: Ft, getPrototypeOf: Ut } = Object, v = globalThis, st = v.trustedTypes, Lt = st ? st.emptyScript : "", W = v.reactiveElementPolyfillSupport, k = (a, t) => a, X = { toAttribute(a, t) { + switch (t) { + case Boolean: + a = a ? Lt : null; + break; + case Object: + case Array: + a = a == null ? a : JSON.stringify(a); + } + return a; +}, fromAttribute(a, t) { + let e = a; + switch (t) { + case Boolean: + e = a !== null; + break; + case Number: + e = a === null ? null : Number(a); + break; + case Object: + case Array: + try { + e = JSON.parse(a); + } catch { + e = null; + } + } + return e; +} }, vt = (a, t) => !kt(a, t), ot = { attribute: !0, type: String, converter: X, reflect: !1, useDefault: !1, hasChanged: vt }; +Symbol.metadata ?? (Symbol.metadata = Symbol("metadata")), v.litPropertyMetadata ?? (v.litPropertyMetadata = /* @__PURE__ */ new WeakMap()); +let w = class extends HTMLElement { + static addInitializer(t) { + this._$Ei(), (this.l ?? (this.l = [])).push(t); + } + static get observedAttributes() { + return this.finalize(), this._$Eh && [...this._$Eh.keys()]; + } + static createProperty(t, e = ot) { + if (e.state && (e.attribute = !1), this._$Ei(), this.prototype.hasOwnProperty(t) && ((e = Object.create(e)).wrapped = !0), this.elementProperties.set(t, e), !e.noAccessor) { + const n = Symbol(), i = this.getPropertyDescriptor(t, n, e); + i !== void 0 && Vt(this.prototype, t, i); + } + } + static getPropertyDescriptor(t, e, n) { + const { get: i, set: r } = Gt(this.prototype, t) ?? { get() { + return this[e]; + }, set(s) { + this[e] = s; + } }; + return { get: i, set(s) { + const o = i == null ? void 0 : i.call(this); + r == null || r.call(this, s), this.requestUpdate(t, o, n); + }, configurable: !0, enumerable: !0 }; + } + static getPropertyOptions(t) { + return this.elementProperties.get(t) ?? ot; + } + static _$Ei() { + if (this.hasOwnProperty(k("elementProperties"))) return; + const t = Ut(this); + t.finalize(), t.l !== void 0 && (this.l = [...t.l]), this.elementProperties = new Map(t.elementProperties); + } + static finalize() { + if (this.hasOwnProperty(k("finalized"))) return; + if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(k("properties"))) { + const e = this.properties, n = [...zt(e), ...Ft(e)]; + for (const i of n) this.createProperty(i, e[i]); + } + const t = this[Symbol.metadata]; + if (t !== null) { + const e = litPropertyMetadata.get(t); + if (e !== void 0) for (const [n, i] of e) this.elementProperties.set(n, i); + } + this._$Eh = /* @__PURE__ */ new Map(); + for (const [e, n] of this.elementProperties) { + const i = this._$Eu(e, n); + i !== void 0 && this._$Eh.set(i, e); + } + this.elementStyles = this.finalizeStyles(this.styles); + } + static finalizeStyles(t) { + const e = []; + if (Array.isArray(t)) { + const n = new Set(t.flat(1 / 0).reverse()); + for (const i of n) e.unshift(rt(i)); + } else t !== void 0 && e.push(rt(t)); + return e; + } + static _$Eu(t, e) { + const n = e.attribute; + return n === !1 ? void 0 : typeof n == "string" ? n : typeof t == "string" ? t.toLowerCase() : void 0; + } + constructor() { + super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev(); + } + _$Ev() { + var t; + this._$ES = new Promise((e) => this.enableUpdating = e), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), (t = this.constructor.l) == null || t.forEach((e) => e(this)); + } + addController(t) { + var e; + (this._$EO ?? (this._$EO = /* @__PURE__ */ new Set())).add(t), this.renderRoot !== void 0 && this.isConnected && ((e = t.hostConnected) == null || e.call(t)); + } + removeController(t) { + var e; + (e = this._$EO) == null || e.delete(t); + } + _$E_() { + const t = /* @__PURE__ */ new Map(), e = this.constructor.elementProperties; + for (const n of e.keys()) this.hasOwnProperty(n) && (t.set(n, this[n]), delete this[n]); + t.size > 0 && (this._$Ep = t); + } + createRenderRoot() { + const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); + return It(t, this.constructor.elementStyles), t; + } + connectedCallback() { + var t; + this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this.enableUpdating(!0), (t = this._$EO) == null || t.forEach((e) => { + var n; + return (n = e.hostConnected) == null ? void 0 : n.call(e); + }); + } + enableUpdating(t) { + } + disconnectedCallback() { + var t; + (t = this._$EO) == null || t.forEach((e) => { + var n; + return (n = e.hostDisconnected) == null ? void 0 : n.call(e); + }); + } + attributeChangedCallback(t, e, n) { + this._$AK(t, n); + } + _$ET(t, e) { + var r; + const n = this.constructor.elementProperties.get(t), i = this.constructor._$Eu(t, n); + if (i !== void 0 && n.reflect === !0) { + const s = (((r = n.converter) == null ? void 0 : r.toAttribute) !== void 0 ? n.converter : X).toAttribute(e, n.type); + this._$Em = t, s == null ? this.removeAttribute(i) : this.setAttribute(i, s), this._$Em = null; + } + } + _$AK(t, e) { + var r, s; + const n = this.constructor, i = n._$Eh.get(t); + if (i !== void 0 && this._$Em !== i) { + const o = n.getPropertyOptions(i), l = typeof o.converter == "function" ? { fromAttribute: o.converter } : ((r = o.converter) == null ? void 0 : r.fromAttribute) !== void 0 ? o.converter : X; + this._$Em = i; + const c = l.fromAttribute(e, o.type); + this[i] = c ?? ((s = this._$Ej) == null ? void 0 : s.get(i)) ?? c, this._$Em = null; + } + } + requestUpdate(t, e, n, i = !1, r) { + var s; + if (t !== void 0) { + const o = this.constructor; + if (i === !1 && (r = this[t]), n ?? (n = o.getPropertyOptions(t)), !((n.hasChanged ?? vt)(r, e) || n.useDefault && n.reflect && r === ((s = this._$Ej) == null ? void 0 : s.get(t)) && !this.hasAttribute(o._$Eu(t, n)))) return; + this.C(t, e, n); + } + this.isUpdatePending === !1 && (this._$ES = this._$EP()); + } + C(t, e, { useDefault: n, reflect: i, wrapped: r }, s) { + n && !(this._$Ej ?? (this._$Ej = /* @__PURE__ */ new Map())).has(t) && (this._$Ej.set(t, s ?? e ?? this[t]), r !== !0 || s !== void 0) || (this._$AL.has(t) || (this.hasUpdated || n || (e = void 0), this._$AL.set(t, e)), i === !0 && this._$Em !== t && (this._$Eq ?? (this._$Eq = /* @__PURE__ */ new Set())).add(t)); + } + async _$EP() { + this.isUpdatePending = !0; + try { + await this._$ES; + } catch (e) { + Promise.reject(e); + } + const t = this.scheduleUpdate(); + return t != null && await t, !this.isUpdatePending; + } + scheduleUpdate() { + return this.performUpdate(); + } + performUpdate() { + var n; + if (!this.isUpdatePending) return; + if (!this.hasUpdated) { + if (this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this._$Ep) { + for (const [r, s] of this._$Ep) this[r] = s; + this._$Ep = void 0; + } + const i = this.constructor.elementProperties; + if (i.size > 0) for (const [r, s] of i) { + const { wrapped: o } = s, l = this[r]; + o !== !0 || this._$AL.has(r) || l === void 0 || this.C(r, void 0, s, l); + } + } + let t = !1; + const e = this._$AL; + try { + t = this.shouldUpdate(e), t ? (this.willUpdate(e), (n = this._$EO) == null || n.forEach((i) => { + var r; + return (r = i.hostUpdate) == null ? void 0 : r.call(i); + }), this.update(e)) : this._$EM(); + } catch (i) { + throw t = !1, this._$EM(), i; + } + t && this._$AE(e); + } + willUpdate(t) { + } + _$AE(t) { + var e; + (e = this._$EO) == null || e.forEach((n) => { + var i; + return (i = n.hostUpdated) == null ? void 0 : i.call(n); + }), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t)), this.updated(t); + } + _$EM() { + this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = !1; + } + get updateComplete() { + return this.getUpdateComplete(); + } + getUpdateComplete() { + return this._$ES; + } + shouldUpdate(t) { + return !0; + } + update(t) { + this._$Eq && (this._$Eq = this._$Eq.forEach((e) => this._$ET(e, this[e]))), this._$EM(); + } + updated(t) { + } + firstUpdated(t) { + } +}; +w.elementStyles = [], w.shadowRootOptions = { mode: "open" }, w[k("elementProperties")] = /* @__PURE__ */ new Map(), w[k("finalized")] = /* @__PURE__ */ new Map(), W == null || W({ ReactiveElement: w }), (v.reactiveElementVersions ?? (v.reactiveElementVersions = [])).push("2.1.2"); +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const V = globalThis, at = (a) => a, D = V.trustedTypes, lt = D ? D.createPolicy("lit-html", { createHTML: (a) => a }) : void 0, bt = "$lit$", f = `lit$${Math.random().toFixed(9).slice(2)}$`, $t = "?" + f, Mt = `<${$t}>`, x = document, z = () => x.createComment(""), F = (a) => a === null || typeof a != "object" && typeof a != "function", it = Array.isArray, Dt = (a) => it(a) || typeof (a == null ? void 0 : a[Symbol.iterator]) == "function", q = `[ +\f\r]`, I = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, ct = /-->/g, ut = />/g, b = RegExp(`>|${q}(?:([^\\s"'>=/]+)(${q}*=${q}*(?:[^ +\f\r"'\`<>=]|("|')|))|$)`, "g"), ht = /'/g, dt = /"/g, yt = /^(?:script|style|textarea|title)$/i, Rt = (a) => (t, ...e) => ({ _$litType$: a, strings: t, values: e }), u = Rt(1), E = Symbol.for("lit-noChange"), p = Symbol.for("lit-nothing"), pt = /* @__PURE__ */ new WeakMap(), $ = x.createTreeWalker(x, 129); +function xt(a, t) { + if (!it(a) || !a.hasOwnProperty("raw")) throw Error("invalid template strings array"); + return lt !== void 0 ? lt.createHTML(t) : t; +} +const jt = (a, t) => { + const e = a.length - 1, n = []; + let i, r = t === 2 ? "" : t === 3 ? "" : "", s = I; + for (let o = 0; o < e; o++) { + const l = a[o]; + let c, h, d = -1, _ = 0; + for (; _ < l.length && (s.lastIndex = _, h = s.exec(l), h !== null); ) _ = s.lastIndex, s === I ? h[1] === "!--" ? s = ct : h[1] !== void 0 ? s = ut : h[2] !== void 0 ? (yt.test(h[2]) && (i = RegExp("" ? (s = i ?? I, d = -1) : h[1] === void 0 ? d = -2 : (d = s.lastIndex - h[2].length, c = h[1], s = h[3] === void 0 ? b : h[3] === '"' ? dt : ht) : s === dt || s === ht ? s = b : s === ct || s === ut ? s = I : (s = b, i = void 0); + const m = s === b && a[o + 1].startsWith("/>") ? " " : ""; + r += s === I ? l + Mt : d >= 0 ? (n.push(c), l.slice(0, d) + bt + l.slice(d) + f + m) : l + f + (d === -2 ? o : m); + } + return [xt(a, r + (a[e] || "") + (t === 2 ? "" : t === 3 ? "" : "")), n]; +}; +class U { + constructor({ strings: t, _$litType$: e }, n) { + let i; + this.parts = []; + let r = 0, s = 0; + const o = t.length - 1, l = this.parts, [c, h] = jt(t, e); + if (this.el = U.createElement(c, n), $.currentNode = this.el.content, e === 2 || e === 3) { + const d = this.el.content.firstChild; + d.replaceWith(...d.childNodes); + } + for (; (i = $.nextNode()) !== null && l.length < o; ) { + if (i.nodeType === 1) { + if (i.hasAttributes()) for (const d of i.getAttributeNames()) if (d.endsWith(bt)) { + const _ = h[s++], m = i.getAttribute(d).split(f), g = /([.?@])?(.*)/.exec(_); + l.push({ type: 1, index: r, name: g[2], strings: m, ctor: g[1] === "." ? Wt : g[1] === "?" ? qt : g[1] === "@" ? Yt : R }), i.removeAttribute(d); + } else d.startsWith(f) && (l.push({ type: 6, index: r }), i.removeAttribute(d)); + if (yt.test(i.tagName)) { + const d = i.textContent.split(f), _ = d.length - 1; + if (_ > 0) { + i.textContent = D ? D.emptyScript : ""; + for (let m = 0; m < _; m++) i.append(d[m], z()), $.nextNode(), l.push({ type: 2, index: ++r }); + i.append(d[_], z()); + } + } + } else if (i.nodeType === 8) if (i.data === $t) l.push({ type: 2, index: r }); + else { + let d = -1; + for (; (d = i.data.indexOf(f, d + 1)) !== -1; ) l.push({ type: 7, index: r }), d += f.length - 1; + } + r++; + } + } + static createElement(t, e) { + const n = x.createElement("template"); + return n.innerHTML = t, n; + } +} +function T(a, t, e = a, n) { + var s, o; + if (t === E) return t; + let i = n !== void 0 ? (s = e._$Co) == null ? void 0 : s[n] : e._$Cl; + const r = F(t) ? void 0 : t._$litDirective$; + return (i == null ? void 0 : i.constructor) !== r && ((o = i == null ? void 0 : i._$AO) == null || o.call(i, !1), r === void 0 ? i = void 0 : (i = new r(a), i._$AT(a, e, n)), n !== void 0 ? (e._$Co ?? (e._$Co = []))[n] = i : e._$Cl = i), i !== void 0 && (t = T(a, i._$AS(a, t.values), i, n)), t; +} +class Bt { + constructor(t, e) { + this._$AV = [], this._$AN = void 0, this._$AD = t, this._$AM = e; + } + get parentNode() { + return this._$AM.parentNode; + } + get _$AU() { + return this._$AM._$AU; + } + u(t) { + const { el: { content: e }, parts: n } = this._$AD, i = ((t == null ? void 0 : t.creationScope) ?? x).importNode(e, !0); + $.currentNode = i; + let r = $.nextNode(), s = 0, o = 0, l = n[0]; + for (; l !== void 0; ) { + if (s === l.index) { + let c; + l.type === 2 ? c = new L(r, r.nextSibling, this, t) : l.type === 1 ? c = new l.ctor(r, l.name, l.strings, this, t) : l.type === 6 && (c = new Zt(r, this, t)), this._$AV.push(c), l = n[++o]; + } + s !== (l == null ? void 0 : l.index) && (r = $.nextNode(), s++); + } + return $.currentNode = x, i; + } + p(t) { + let e = 0; + for (const n of this._$AV) n !== void 0 && (n.strings !== void 0 ? (n._$AI(t, n, e), e += n.strings.length - 2) : n._$AI(t[e])), e++; + } +} +class L { + get _$AU() { + var t; + return ((t = this._$AM) == null ? void 0 : t._$AU) ?? this._$Cv; + } + constructor(t, e, n, i) { + this.type = 2, this._$AH = p, this._$AN = void 0, this._$AA = t, this._$AB = e, this._$AM = n, this.options = i, this._$Cv = (i == null ? void 0 : i.isConnected) ?? !0; + } + get parentNode() { + let t = this._$AA.parentNode; + const e = this._$AM; + return e !== void 0 && (t == null ? void 0 : t.nodeType) === 11 && (t = e.parentNode), t; + } + get startNode() { + return this._$AA; + } + get endNode() { + return this._$AB; + } + _$AI(t, e = this) { + t = T(this, t, e), F(t) ? t === p || t == null || t === "" ? (this._$AH !== p && this._$AR(), this._$AH = p) : t !== this._$AH && t !== E && this._(t) : t._$litType$ !== void 0 ? this.$(t) : t.nodeType !== void 0 ? this.T(t) : Dt(t) ? this.k(t) : this._(t); + } + O(t) { + return this._$AA.parentNode.insertBefore(t, this._$AB); + } + T(t) { + this._$AH !== t && (this._$AR(), this._$AH = this.O(t)); + } + _(t) { + this._$AH !== p && F(this._$AH) ? this._$AA.nextSibling.data = t : this.T(x.createTextNode(t)), this._$AH = t; + } + $(t) { + var r; + const { values: e, _$litType$: n } = t, i = typeof n == "number" ? this._$AC(t) : (n.el === void 0 && (n.el = U.createElement(xt(n.h, n.h[0]), this.options)), n); + if (((r = this._$AH) == null ? void 0 : r._$AD) === i) this._$AH.p(e); + else { + const s = new Bt(i, this), o = s.u(this.options); + s.p(e), this.T(o), this._$AH = s; + } + } + _$AC(t) { + let e = pt.get(t.strings); + return e === void 0 && pt.set(t.strings, e = new U(t)), e; + } + k(t) { + it(this._$AH) || (this._$AH = [], this._$AR()); + const e = this._$AH; + let n, i = 0; + for (const r of t) i === e.length ? e.push(n = new L(this.O(z()), this.O(z()), this, this.options)) : n = e[i], n._$AI(r), i++; + i < e.length && (this._$AR(n && n._$AB.nextSibling, i), e.length = i); + } + _$AR(t = this._$AA.nextSibling, e) { + var n; + for ((n = this._$AP) == null ? void 0 : n.call(this, !1, !0, e); t !== this._$AB; ) { + const i = at(t).nextSibling; + at(t).remove(), t = i; + } + } + setConnected(t) { + var e; + this._$AM === void 0 && (this._$Cv = t, (e = this._$AP) == null || e.call(this, t)); + } +} +class R { + get tagName() { + return this.element.tagName; + } + get _$AU() { + return this._$AM._$AU; + } + constructor(t, e, n, i, r) { + this.type = 1, this._$AH = p, this._$AN = void 0, this.element = t, this.name = e, this._$AM = i, this.options = r, n.length > 2 || n[0] !== "" || n[1] !== "" ? (this._$AH = Array(n.length - 1).fill(new String()), this.strings = n) : this._$AH = p; + } + _$AI(t, e = this, n, i) { + const r = this.strings; + let s = !1; + if (r === void 0) t = T(this, t, e, 0), s = !F(t) || t !== this._$AH && t !== E, s && (this._$AH = t); + else { + const o = t; + let l, c; + for (t = r[0], l = 0; l < r.length - 1; l++) c = T(this, o[n + l], e, l), c === E && (c = this._$AH[l]), s || (s = !F(c) || c !== this._$AH[l]), c === p ? t = p : t !== p && (t += (c ?? "") + r[l + 1]), this._$AH[l] = c; + } + s && !i && this.j(t); + } + j(t) { + t === p ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t ?? ""); + } +} +class Wt extends R { + constructor() { + super(...arguments), this.type = 3; + } + j(t) { + this.element[this.name] = t === p ? void 0 : t; + } +} +class qt extends R { + constructor() { + super(...arguments), this.type = 4; + } + j(t) { + this.element.toggleAttribute(this.name, !!t && t !== p); + } +} +class Yt extends R { + constructor(t, e, n, i, r) { + super(t, e, n, i, r), this.type = 5; + } + _$AI(t, e = this) { + if ((t = T(this, t, e, 0) ?? p) === E) return; + const n = this._$AH, i = t === p && n !== p || t.capture !== n.capture || t.once !== n.once || t.passive !== n.passive, r = t !== p && (n === p || i); + i && this.element.removeEventListener(this.name, this, n), r && this.element.addEventListener(this.name, this, t), this._$AH = t; + } + handleEvent(t) { + var e; + typeof this._$AH == "function" ? this._$AH.call(((e = this.options) == null ? void 0 : e.host) ?? this.element, t) : this._$AH.handleEvent(t); + } +} +class Zt { + constructor(t, e, n) { + this.element = t, this.type = 6, this._$AN = void 0, this._$AM = e, this.options = n; + } + get _$AU() { + return this._$AM._$AU; + } + _$AI(t) { + T(this, t); + } +} +const Y = V.litHtmlPolyfillSupport; +Y == null || Y(U, L), (V.litHtmlVersions ?? (V.litHtmlVersions = [])).push("3.3.3"); +const Jt = (a, t, e) => { + const n = (e == null ? void 0 : e.renderBefore) ?? t; + let i = n._$litPart$; + if (i === void 0) { + const r = (e == null ? void 0 : e.renderBefore) ?? null; + n._$litPart$ = i = new L(t.insertBefore(z(), r), r, void 0, e ?? {}); + } + return i._$AI(a), i; +}; +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const y = globalThis; +class G extends w { + constructor() { + super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0; + } + createRenderRoot() { + var e; + const t = super.createRenderRoot(); + return (e = this.renderOptions).renderBefore ?? (e.renderBefore = t.firstChild), t; + } + update(t) { + const e = this.render(); + this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t), this._$Do = Jt(e, this.renderRoot, this.renderOptions); + } + connectedCallback() { + var t; + super.connectedCallback(), (t = this._$Do) == null || t.setConnected(!0); + } + disconnectedCallback() { + var t; + super.disconnectedCallback(), (t = this._$Do) == null || t.setConnected(!1); + } + render() { + return E; + } +} +var _t; +G._$litElement$ = !0, G.finalized = !0, (_t = y.litElementHydrateSupport) == null || _t.call(y, { LitElement: G }); +const Z = y.litElementPolyfillSupport; +Z == null || Z({ LitElement: G }); +(y.litElementVersions ?? (y.litElementVersions = [])).push("4.2.2"); +const mt = [ + ["more-info", "More info"], + ["navigate", "Navigate"], + ["url", "URL"], + ["call-service", "Call service"], + ["assist", "Assist"], + ["none", "None"] +]; +class K extends G { + setConfig(t) { + this._config = { + ...S, + ...t + }, this._openSections || (this._openSections = { + general: !0, + preset: !0, + grouping: !1, + filters: !1, + groupTitleOverrides: !1, + sorting: !1, + appearance: !1, + actions: !1 + }); + } + render() { + if (!this._config) return u``; + const t = this._config.preset || "spoolman"; + return u` +
+ ${this.renderExpandableSection( + "general", + "General", + this.renderGeneralSection(t), + !0 + )} + + ${t === "spoolman" ? this.renderSpoolmanOptions() : ""} + ${t === "custom_attributes" ? this.renderCustomAttributeOptions() : ""} + ${t === "custom_entities" ? this.renderCustomEntityOptions() : ""} + ${t === "custom_label" ? this.renderCustomLabelOptions() : ""} + + ${this.renderExpandableSection( + "appearance", + "Appearance", + this.renderAppearanceOptions(), + !0 + )} + + ${this.renderExpandableSection( + "actions", + "Actions", + this.renderActionOptions(), + !1 + )} +
+ `; + } + toggleSection(t) { + var e; + this._openSections = { + ...this._openSections || {}, + [t]: !((e = this._openSections) != null && e[t]) + }; + } + renderExpandableSection(t, e, n, i = !1) { + var s; + const r = ((s = this._openSections) == null ? void 0 : s[t]) ?? i; + return u` +
+
this.toggleSection(t)} + > + ${e} + +
+ + ${r ? u` +
+ ${n} +
+ ` : ""} +
+ `; + } + renderGeneralSection(t) { + return u` +
General
+ + ${this.renderSelect( + t, + "Choose Preset", + [ + ["spoolman", "Spoolman"], + ["custom_attributes", "Custom: Attributes"], + ["custom_entities", "Custom: Multiple entities"], + ["custom_label", "Custom: HA Label"] + ], + (e) => this.updatePreset(e) + )} + + ${this.renderPresetHint(t)} + + ${this.renderTextField("title", "Title")} + `; + } + renderSpoolmanOptions() { + return u` + ${this.renderExpandableSection( + "grouping", + "Grouping", + u` + ${this.renderSelect( + this._config.group_by || "material", + "Group by", + [ + ["material", "Material"], + ["color", "Color"], + ["vendor", "Vendor"], + ["none", "Don't group"] + ], + (t) => this.updateGroupBy(t) + )} + + ${this.renderGroupingDetails("Spool count")} + ${this.renderGroupFilters()} + ${this.renderGroupTitleOverrides()} + `, + !0 + )} + + ${this.renderExpandableSection( + "sorting", + "Sorting", + u` + ${this.renderSelect( + this._config.sort_by || "remaining_weight", + "Sort by", + [ + ["remaining_weight", "Remaining weight"], + ["filament_name", "Filament name"], + ["filament_material", "Material"], + ["filament_vendor_name", "Vendor"], + ["filament_color_hex", "Color"] + ], + (t) => this.updateConfigValue("sort_by", t) + )} + + ${this.renderSortDirection()} + + ${this.renderNumberField("max_weight", "Max weight fallback")} + ${this.renderHint("Used only if no filament weight is available.")} + + ${this.renderSwitch("hide_archived", "Hide archived spools")} + ${this.renderSwitch("use_filament_color", "Use filament color")} + `, + !0 + )} + `; + } + renderCustomAttributeOptions() { + return u` + ${this.renderExpandableSection( + "preset", + "Custom Attributes", + u` + ${this.renderEntityPicker( + this._config.custom_attribute_entities || [], + "Entities with attributes", + (t) => this.updateConfigValue("custom_attribute_entities", t), + !0 + )} + + ${this.renderHint( + "Each selected entity should provide attributes like group, vendor, color, max_value and unit." + )} + + ${this.renderCustomDefaults()} + `, + !0 + )} + + ${this.renderCustomSharedOptions()} + `; + } + renderCustomEntityOptions() { + const t = this._config.custom_items || []; + return u` + ${this.renderExpandableSection( + "preset", + "Custom Multiple Entities", + u` + ${this.renderHint( + "Create one item per spool. Each item can use separate entities for value, max value, color, group and vendor." + )} + + ${t.map((e, n) => this.renderCustomItem(e, n))} + + + + ${this.renderCustomDefaults()} + `, + !0 + )} + + ${this.renderCustomSharedOptions()} + `; + } + renderCustomItem(t, e) { + return u` +
+
Spool ${e + 1}
+ + ${this.renderTextForm( + t.name || "", + "Name", + (n) => this.updateCustomItem(e, "name", n) + )} + + ${this.renderEntityPicker( + t.value_entity || "", + "Value entity", + (n) => this.updateCustomItem(e, "value_entity", n) + )} + + ${this.renderEntityPicker( + t.max_entity || "", + "Max entity", + (n) => this.updateCustomItem(e, "max_entity", n) + )} + + ${this.renderEntityPicker( + t.color_entity || "", + "Color entity", + (n) => this.updateCustomItem(e, "color_entity", n) + )} + + ${this.renderEntityPicker( + t.group_entity || "", + "Group entity", + (n) => this.updateCustomItem(e, "group_entity", n) + )} + + ${this.renderEntityPicker( + t.vendor_entity || "", + "Vendor entity", + (n) => this.updateCustomItem(e, "vendor_entity", n) + )} + + ${this.renderEntityPicker( + t.name_entity || "", + "Name entity", + (n) => this.updateCustomItem(e, "name_entity", n) + )} + + ${this.renderTextForm( + t.unit || this._config.custom_unit || "g", + "Unit", + (n) => this.updateCustomItem(e, "unit", n) + )} + + +
+ `; + } + renderCustomLabelOptions() { + return u` + ${this.renderExpandableSection( + "preset", + "Custom HA Label", + u` + ${this.renderHint( + "All entities with the selected Home Assistant label will be used automatically. They should provide the same attributes as Custom Attributes." + )} + + ${this.renderLabelPicker( + this._config.custom_label_id || "", + "HA Label", + (t) => this.updateConfigValue("custom_label_id", t) + )} + + ${this.renderCustomDefaults()} + `, + !0 + )} + + ${this.renderCustomSharedOptions()} + `; + } + renderCustomDefaults() { + return u` + ${this.renderTextForm( + this._config.custom_max_value ?? 1e3, + "Default max value", + (t) => this.updateConfigValue("custom_max_value", Number(t)) + )} + + ${this.renderHint("Used when an item does not provide its own maximum value.")} + + ${this.renderTextForm( + this._config.custom_unit || "g", + "Default unit", + (t) => this.updateConfigValue("custom_unit", t) + )} + `; + } + renderCustomSharedOptions() { + return u` + ${this.renderExpandableSection( + "grouping", + "Grouping", + u` + ${this.renderSelect( + this._config.group_by || "material", + "Group by", + [ + ["material", "Group"], + ["color", "Color"], + ["vendor", "Vendor"], + ["none", "Don't group"] + ], + (t) => this.updateGroupBy(t) + )} + + ${this.renderGroupingDetails("Item count")} + ${this.renderGroupFilters()} + ${this.renderGroupTitleOverrides()} + `, + !0 + )} + + ${this.renderExpandableSection( + "sorting", + "Sorting", + u` + ${this.renderSelect( + this._config.sort_by || "remaining_weight", + "Sort by", + [ + ["remaining_weight", "Value"], + ["filament_name", "Name"], + ["filament_material", "Group"], + ["filament_vendor_name", "Vendor"], + ["filament_color_hex", "Color"] + ], + (t) => this.updateConfigValue("sort_by", t) + )} + + ${this.renderSortDirection()} + + ${this.renderSwitch("use_filament_color", "Use item color")} + `, + !0 + )} + `; + } + renderGroupFilters() { + var r, s; + if (this._config.group_by === "none") + return u``; + const t = this.getAvailableGroups(); + if (!t.length) + return this.renderExpandableSection( + "filters", + "Filters", + u` + ${this.renderHint( + "No filter values found yet. Values will appear once matching entities are available." + )} + `, + !1 + ); + const e = Array.isArray((r = this._config.filters) == null ? void 0 : r.include) ? this._config.filters.include : [], n = Array.isArray((s = this._config.filters) == null ? void 0 : s.exclude) ? this._config.filters.exclude : [], i = this.getFilterTypeLabel(); + return this.renderExpandableSection( + "filters", + "Filters", + u` + ${this.renderHint( + `Filter the card by the currently selected grouping: ${i}.` + )} + + ${this.renderMultiSelect( + e, + `Include only ${i}`, + t.map((o) => [o, o]), + (o) => this.updateFilterValues("include", o) + )} + + ${this.renderHint( + "When values are selected here, only matching items are displayed." + )} + + ${this.renderMultiSelect( + n, + `Exclude ${i}`, + t.map((o) => [o, o]), + (o) => this.updateFilterValues("exclude", o) + )} + + ${this.renderHint( + "Excluded values are hidden. The visual editor automatically removes them from the include list." + )} + `, + !1 + ); + } + renderGroupTitleOverrides() { + if (this._config.group_by === "none") return u``; + const t = this.getAvailableGroups(); + return t.length ? this.renderExpandableSection( + "groupTitleOverrides", + "Group Title Overrides", + u` + ${this.renderHint( + "Configure individual icons, colors and actions for specific group titles." + )} + + ${t.map((e) => this.renderGroupTitleOverride(e))} + `, + !1 + ) : this.renderExpandableSection( + "groupTitleOverrides", + "Group Title Overrides", + u` + ${this.renderHint( + "No groups found yet. Groups will appear here once matching entities are available." + )} + `, + !1 + ); + } + getFilterTypeLabel() { + return { + material: "materials", + vendor: "vendors", + color: "colors" + }[this._config.group_by] || "groups"; + } + getAvailableGroups() { + if (!this.hass || !this._config || this._config.group_by === "none") + return []; + const t = this._config.preset || "spoolman", e = this.getPreviewItemsForGroups(t); + let n = [...new Set( + e.map((r) => C(this._config, r)).filter(Boolean) + )]; + n = gt(this._config, n, e); + const i = Array.isArray(this._config.group_order) ? this._config.group_order : []; + return [ + ...i.filter((r) => n.includes(r)), + ...n.filter((r) => !i.includes(r)) + ]; + } + getPreviewItemsForGroups(t) { + return t === "custom_entities" ? this.getCustomEntityPreviewItems() : t === "custom_attributes" || t === "custom_label" ? this.getCustomAttributePreviewItems(t) : this.getSpoolmanPreviewItems(); + } + getSpoolmanPreviewItems() { + return Object.entries(this.hass.states).map(([t, e]) => ({ entity_id: t, state: e })).filter(({ state: t }) => { + var e; + return (e = t.attributes) == null ? void 0 : e.filament_material; + }); + } + getCustomAttributePreviewItems(t) { + const e = t === "custom_label" ? this.getEntitiesFromSelectedLabel() : this._config.custom_attribute_entities || [], n = Number(this._config.custom_max_value || 1e3), i = this._config.custom_unit || "g"; + return e.map((r) => { + const s = this.hass.states[r]; + if (!s) return null; + const o = s.attributes || {}, l = Number(o.value ?? o.remaining_weight ?? s.state); + return Number.isNaN(l) ? null : this.createPreviewItem({ + entity_id: r, + value: l, + max: Number(o.max_value ?? o.max ?? n), + name: o.name || o.friendly_name || r, + group: o.group || o.material || "Custom", + vendor: o.vendor || "", + color: o.color || o.filament_color_hex, + unit: o.unit || i + }); + }).filter(Boolean); + } + getCustomEntityPreviewItems() { + const t = this._config.custom_items || [], e = Number(this._config.custom_max_value || 1e3), n = this._config.custom_unit || "g"; + return t.map((i, r) => { + var m, g, N, O, P, H; + const s = this.hass.states[i.value_entity]; + if (!s) return null; + const o = Number(s.state); + if (Number.isNaN(o)) return null; + const l = i.max_entity ? Number(((m = this.hass.states[i.max_entity]) == null ? void 0 : m.state) ?? e) : Number(i.max ?? i.max_value ?? e), c = i.color_entity ? (g = this.hass.states[i.color_entity]) == null ? void 0 : g.state : i.color, h = i.group_entity ? (N = this.hass.states[i.group_entity]) == null ? void 0 : N.state : i.group, d = i.vendor_entity ? (O = this.hass.states[i.vendor_entity]) == null ? void 0 : O.state : i.vendor, _ = i.name_entity ? (P = this.hass.states[i.name_entity]) == null ? void 0 : P.state : i.name; + return this.createPreviewItem({ + entity_id: i.value_entity || `custom_item_${r}`, + value: o, + max: Number.isNaN(l) ? e : l, + name: _ || ((H = s.attributes) == null ? void 0 : H.friendly_name) || i.value_entity, + group: h || "Custom", + vendor: d || "", + color: c, + unit: i.unit || n + }); + }).filter(Boolean); + } + getEntitiesFromSelectedLabel() { + var e; + const t = this._config.custom_label_id; + return !t || !((e = this.hass) != null && e.entities) ? [] : Object.entries(this.hass.entities).filter(([, n]) => { + var i; + return (i = n.labels) == null ? void 0 : i.includes(t); + }).map(([n]) => n); + } + createPreviewItem({ entity_id: t, value: e, max: n, name: i, group: r, vendor: s, color: o, unit: l }) { + return { + entity_id: t, + state: { + state: String(e), + attributes: { + friendly_name: i, + remaining_weight: e, + filament_weight: n, + filament_material: r, + filament_name: i, + filament_vendor_name: s, + filament_color_hex: o, + archived: !1, + custom_unit: l + } + } + }; + } + renderGroupTitleOverride(t) { + var i, r; + const e = ((i = this._config.group_title_icons) == null ? void 0 : i[t]) || "", n = ((r = this._config.group_title_colors) == null ? void 0 : r[t]) || ""; + return u` +
+
${t}
+ + ${this.renderIconPicker( + e, + "Group title icon", + (s) => this.updateGroupTitleValue("group_title_icons", t, s) + )} + + ${this.renderTextForm( + n, + "Group title color", + (s) => this.updateGroupTitleValue("group_title_colors", t, s) + )} + + ${this.renderGroupTitleActionFields(t, "tap_action", "Tap action")} + ${this.renderGroupTitleActionFields(t, "double_tap_action", "Double tap action")} + ${this.renderGroupTitleActionFields(t, "hold_action", "Hold action")} +
+ `; + } + renderGroupingDetails(t) { + return this._config.group_by === "none" ? u`` : u` + ${this.renderHint(this.groupOrderHint())} + + + + ${this.renderSelect( + this._config.group_sort_by || "name", + "Group sort by", + [ + ["name", "Name"], + ["total_remaining_weight", "Total remaining weight"], + ["max_remaining_weight", "Max remaining weight"], + ["spool_count", t] + ], + (e) => this.updateConfigValue("group_sort_by", e) + )} + + ${this.renderSelect( + this._config.group_sort_direction || "asc", + "Group sort direction", + [ + ["asc", "Ascending"], + ["desc", "Descending"] + ], + (e) => this.updateConfigValue("group_sort_direction", e) + )} + + ${this.renderSwitchValue( + this._config.group_icon !== "none", + "Show group icon", + (e) => this.updateGroupIconVisibility(e) + )} + + ${this._config.group_icon !== "none" ? this.renderIconPicker( + this._config.group_icon || "mdi:printer-3d-nozzle", + "Group icon", + (e) => this.updateConfigValue("group_icon", e || "none") + ) : ""} + + ${this.renderSwitch("show_group_title", "Show group title")} + `; + } + renderGroupTitleActionFields(t, e, n) { + var o, l; + const r = (((o = this._config.group_title_actions) == null ? void 0 : o[t]) || {})[e] || { action: "none" }, s = r.action || "none"; + return u` + ${this.renderSelect( + s, + n, + mt, + (c) => { + const h = { action: c }; + c === "assist" && (h.pipeline_id = "preferred", h.start_listening = !0), this.updateGroupTitleAction(t, e, h); + } + )} + + ${s === "navigate" ? this.renderTextForm( + r.navigation_path || "", + "Navigation path", + (c) => this.updateGroupTitleAction(t, e, { + ...r, + action: s, + navigation_path: c + }) + ) : ""} + + ${s === "url" ? this.renderTextForm( + r.url_path || "", + "URL path", + (c) => this.updateGroupTitleAction(t, e, { + ...r, + action: s, + url_path: c + }) + ) : ""} + + ${s === "call-service" ? u` +
Service
+ + this.updateGroupTitleAction(t, e, { + ...r, + action: s, + service: c.detail.value + })} + > + +
Target entity
+ + this.updateGroupTitleAction(t, e, { + ...r, + action: s, + target: c.detail.value ? { entity_id: c.detail.value } : void 0 + })} + > + ` : ""} + + ${s === "assist" ? u` + ${this.renderTextForm( + r.pipeline_id || "preferred", + "Pipeline ID", + (c) => this.updateGroupTitleAction(t, e, { + ...r, + action: s, + pipeline_id: c + }) + )} + + ${this.renderSwitchValue( + r.start_listening !== !1, + "Start listening", + (c) => this.updateGroupTitleAction(t, e, { + ...r, + action: s, + start_listening: c + }) + )} + ` : ""} + `; + } + renderSortDirection() { + return this.renderSelect( + this._config.sort_direction || "asc", + "Sort direction", + [ + ["asc", "Ascending"], + ["desc", "Descending"] + ], + (t) => this.updateConfigValue("sort_direction", t) + ); + } + renderAppearanceOptions() { + return u` + + ${this.renderSelect( + this._config.bar_direction || "vertical", + "Bar direction", + [ + ["vertical", "Vertical"], + ["horizontal", "Horizontal"] + ], + (t) => { + const e = { + ...this._config, + bar_direction: t + }; + this.normalizePositions(e), this.setAndDispatchConfig(e); + } + )} + + ${this.renderSelect( + this._config.name_position || "bottom", + "Name position", + this.namePositionOptions(), + (t) => this.updateConfigValue("name_position", t) + )} + + ${this.renderSelect( + this._config.value_position || "center", + "Value position", + this.valuePositionOptions(), + (t) => this.updateConfigValue("value_position", t) + )} + + ${this.renderSwitch("show_name", "Show name")} + + `; + } + renderActionOptions() { + return u` + + ${this.renderActionSelect("tap_action", "Tap action", "more-info")} + ${this.renderActionSelect("double_tap_action", "Double tap action", "none")} + ${this.renderActionSelect("hold_action", "Hold action", "none")} + `; + } + renderActionSelect(t, e, n) { + const i = this._config[t] || {}, r = i.action || n; + return u` + ${this.renderSelect( + r, + e, + mt, + (s) => { + const o = { action: s }; + s === "assist" && (o.pipeline_id = "preferred", o.start_listening = !0), this.updateConfigValue(t, o); + } + )} + + ${this.renderActionExtraFields(t, i, r)} + `; + } + renderActionExtraFields(t, e, n) { + var i; + return n === "navigate" ? this.renderTextForm( + e.navigation_path || "", + "Navigation path", + (r) => this.updateActionConfigValue(t, "navigation_path", r) + ) : n === "url" ? this.renderTextForm( + e.url_path || "", + "URL path", + (r) => this.updateActionConfigValue(t, "url_path", r) + ) : n === "call-service" ? u` +
Service
+ + this.updateActionConfigValue(t, "service", r.detail.value)} + > + +
Target entity
+ + this.updateActionTargetEntity(t, r.detail.value)} + > + ` : n === "assist" ? u` + ${this.renderTextForm( + e.pipeline_id || "preferred", + "Pipeline ID", + (r) => this.updateActionConfigValue(t, "pipeline_id", r) + )} + + ${this.renderSwitchValue( + e.start_listening !== !1, + "Start listening", + (r) => this.updateActionConfigValue(t, "start_listening", r) + )} + ` : u``; + } + updateGroupTitleValue(t, e, n) { + const i = { ...this._config }, r = { ...i[t] || {} }; + n ? r[e] = n : delete r[e], i[t] = r, this.setAndDispatchConfig(i); + } + updateGroupTitleAction(t, e, n) { + const i = { ...this._config }, r = { ...i.group_title_actions || {} }, s = { ...r[t] || {} }; + !n || n.action === "none" ? delete s[e] : s[e] = n, Object.keys(s).length ? r[t] = s : delete r[t], i.group_title_actions = r, this.setAndDispatchConfig(i); + } + updateActionConfigValue(t, e, n) { + const i = { ...this._config }, r = { ...i[t] || {} }, s = typeof n == "string" ? n.trim() : n; + s ? r[e] = s : delete r[e], i[t] = r, this.setAndDispatchConfig(i); + } + updateActionTargetEntity(t, e) { + const n = { ...this._config }, i = { ...n[t] || {} }; + e ? i.target = { + ...i.target || {}, + entity_id: e + } : delete i.target, n[t] = i, this.setAndDispatchConfig(n); + } + renderPresetHint(t) { + const e = { + spoolman: "Automatically discovers Spoolman filament entities.", + custom_attributes: "Use entities that provide all display data through attributes.", + custom_entities: "Build each spool from multiple Home Assistant entities.", + custom_label: "Automatically use entities assigned to a Home Assistant label." + }; + return this.renderHint(e[t] || ""); + } + renderHint(t) { + return t ? u` +
${t}
+ ` : u``; + } + renderTextField(t, e) { + return u` + this.updateConfigValue(t, n.target.value)} + > + `; + } + renderNumberField(t, e) { + return u` + this.updateConfigValue(t, Number(n.target.value))} + > + `; + } + renderTextForm(t, e, n) { + const i = [ + { + name: "value", + selector: { + text: {} + } + } + ]; + return u` + e} + @value-changed=${(r) => { + var s; + n(((s = r.detail.value) == null ? void 0 : s.value) ?? ""); + }} + > + `; + } + renderSelect(t, e, n, i) { + const r = [ + { + name: "value", + selector: { + select: { + mode: "dropdown", + options: n.map(([s, o]) => ({ + value: s, + label: o + })) + } + } + } + ]; + return u` + e} + @value-changed=${(s) => { + var l; + const o = (l = s.detail.value) == null ? void 0 : l.value; + o !== void 0 && o !== t && i(o); + }} + > + `; + } + renderMultiSelect(t, e, n, i) { + const r = Array.isArray(t) ? t : [], s = [ + { + name: "value", + selector: { + select: { + multiple: !0, + mode: "dropdown", + options: n.map(([o, l]) => ({ + value: o, + label: l + })) + } + } + } + ]; + return u` + e} + @value-changed=${(o) => { + var c; + const l = (c = o.detail.value) == null ? void 0 : c.value; + i(Array.isArray(l) ? l : []); + }} + > + `; + } + renderEntityPicker(t, e, n, i = !1) { + const r = [ + { + name: "value", + selector: { + entity: { + multiple: i + } + } + } + ]; + return u` + e} + @value-changed=${(s) => { + var o; + n(((o = s.detail.value) == null ? void 0 : o.value) || (i ? [] : "")); + }} + > + `; + } + renderLabelPicker(t, e, n) { + const i = [ + { + name: "value", + selector: { + label: {} + } + } + ]; + return u` + e} + @value-changed=${(r) => { + var s; + n(((s = r.detail.value) == null ? void 0 : s.value) || ""); + }} + > + `; + } + renderIconPicker(t, e, n) { + const i = [ + { + name: "value", + selector: { + icon: {} + } + } + ]; + return u` + e} + @value-changed=${(r) => { + var s; + n(((s = r.detail.value) == null ? void 0 : s.value) || ""); + }} + > + `; + } + renderSwitch(t, e, n = null) { + const i = this._config[t] !== !1; + return u` +
+ { + n ? n(r.target.checked) : this.updateConfigValue(t, r.target.checked); + }} + > + ${e} +
+ `; + } + renderSwitchValue(t, e, n) { + return u` +
+ n(i.target.checked)} + > + ${e} +
+ `; + } + updatePreset(t) { + const e = { + ...this._config, + preset: t + }; + t === "spoolman" && (delete e.custom_attribute_entities, delete e.custom_items, delete e.custom_label_id, delete e.custom_max_value, delete e.custom_unit), t === "custom_attributes" && (delete e.custom_items, delete e.custom_label_id), t === "custom_entities" && (delete e.custom_attribute_entities, delete e.custom_label_id), t === "custom_label" && (delete e.custom_attribute_entities, delete e.custom_items), this.setAndDispatchConfig(e); + } + updateConfigValue(t, e) { + const n = { + ...this._config, + [t]: e + }; + this.setAndDispatchConfig(n); + } + updateCustomItem(t, e, n) { + const i = [...this._config.custom_items || []]; + i[t] = { + ...i[t], + [e]: n + }, this.updateConfigValue("custom_items", i); + } + updateGroupIconVisibility(t) { + const e = { + ...this._config, + group_icon: t ? "mdi:printer-3d-nozzle" : "none" + }; + this.setAndDispatchConfig(e); + } + updateGroupBy(t) { + const e = { + ...this._config, + group_by: t + }; + delete e.filters, this.setAndDispatchConfig(e); + } + updateFilterValues(t, e) { + var l, c; + const n = Array.isArray(e) ? [...new Set(e.filter(Boolean))] : [], i = t === "include" ? "exclude" : "include", r = { + ...this._config.filters || {}, + [t]: n + }, s = Array.isArray(r[i]) ? r[i] : []; + r[i] = s.filter( + (h) => !n.includes(h) + ), (l = r.include) != null && l.length || delete r.include, (c = r.exclude) != null && c.length || delete r.exclude; + const o = { + ...this._config + }; + Object.keys(r).length ? o.filters = r : delete o.filters, this.setAndDispatchConfig(o); + } + addCustomItem() { + const t = [ + ...this._config.custom_items || [], + { + name: "", + value_entity: "", + max_entity: "", + color_entity: "", + group_entity: "", + vendor_entity: "", + name_entity: "", + unit: this._config.custom_unit || "g" + } + ]; + this.updateConfigValue("custom_items", t); + } + removeCustomItem(t) { + const e = [...this._config.custom_items || []]; + e.splice(t, 1), this.updateConfigValue("custom_items", e); + } + handleGroupOrderChanged(t) { + const e = t.target.value.split(` +`).map((n) => n.trim()).filter(Boolean); + this.setAndDispatchConfig({ + ...this._config, + group_order: e + }); + } + groupOrderValue() { + return Array.isArray(this._config.group_order) ? this._config.group_order.join(` +`) : ""; + } + groupOrderHint() { + return this._config.group_by === "color" ? "One color per line. Unknown colors are appended automatically." : this._config.group_by === "vendor" ? "One vendor per line. Unknown vendors are appended automatically." : "One group per line. Unknown groups are appended automatically."; + } + namePositionOptions() { + return this._config.bar_direction === "horizontal" ? [ + ["top", "Top"], + ["bottom", "Bottom"], + ["left", "Left"], + ["right", "Right"] + ] : [ + ["top", "Top"], + ["bottom", "Bottom"] + ]; + } + valuePositionOptions() { + return this._config.bar_direction === "horizontal" ? [ + ["left", "Left"], + ["center", "Center"], + ["right", "Right"] + ] : [ + ["top", "Top"], + ["center", "Center"], + ["bottom", "Bottom"] + ]; + } + normalizePositions(t) { + t.bar_direction === "vertical" && (["top", "bottom"].includes(t.name_position) || (t.name_position = "bottom"), ["top", "center", "bottom"].includes(t.value_position) || (t.value_position = "center")), t.bar_direction === "horizontal" && (["top", "bottom", "left", "right"].includes(t.name_position) || (t.name_position = "bottom"), ["left", "center", "right"].includes(t.value_position) || (t.value_position = "center")); + } + setAndDispatchConfig(t) { + this._config = t, this.dispatchEvent( + new CustomEvent("config-changed", { + detail: { config: t }, + bubbles: !0, + composed: !0 + }) + ); + } +} +j(K, "properties", { + hass: { attribute: !1 }, + _config: { state: !0 }, + _openSections: { state: !0 } +}), j(K, "styles", Ht` + .editor { + display: grid; + gap: 16px; + padding: 16px; + } + + .section-title { + margin-top: 12px; + font-size: 16px; + font-weight: 500; + } + + .section-title:first-child { + margin-top: 0; + } + + .hint { + color: var(--secondary-text-color); + font-size: 12px; + line-height: 1.4; + margin-top: -6px; + } + + ha-textfield, + ha-select { + width: 100%; + } + + textarea { + width: 100%; + min-height: 80px; + box-sizing: border-box; + padding: 10px; + border-radius: 4px; + border: 1px solid var(--divider-color); + background: var(--card-background-color); + color: var(--primary-text-color); + font: inherit; + resize: vertical; + } + + .switch-row { + display: flex; + align-items: center; + gap: 12px; + } + + .switch-label { + font-size: 14px; + } + + .custom-item { + display: grid; + gap: 12px; + padding: 12px; + border: 1px solid var(--divider-color); + border-radius: 8px; + } + + .button-row { + display: flex; + gap: 8px; + } + + .editor-button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + width: fit-content; + padding: 8px 14px; + border: none; + border-radius: 4px; + background: var(--primary-color); + color: var(--text-primary-color); + font: inherit; + font-weight: 500; + cursor: pointer; + user-select: none; + } + + .editor-button:hover { + filter: brightness(1.08); + } + + .editor-button.secondary { + background: var(--secondary-background-color); + color: var(--primary-text-color); + border: 1px solid var(--divider-color); + } + + .editor-button.danger { + background: var(--error-color); + color: var(--text-primary-color); + } + + .expandable-section { + border: 1px solid var(--divider-color); + border-radius: 8px; + overflow: hidden; + } + + .expandable-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 12px; + cursor: pointer; + user-select: none; + font-weight: 500; + background: var(--secondary-background-color); + } + + .expandable-header:hover { + filter: brightness(1.03); + } + + .expandable-content { + display: grid; + gap: 12px; + padding: 12px; + } + + `); +customElements.get(Q) || customElements.define(Q, K); +window.customCards = window.customCards || []; +window.customCards.push({ + type: J, + name: "Filament Card", + description: "Shows filament stock grouped by material, color, or vendor." +}); diff --git a/zigbee2mqtt/state.json b/zigbee2mqtt/state.json index adf83a4e..b6c1c1cc 100644 --- a/zigbee2mqtt/state.json +++ b/zigbee2mqtt/state.json @@ -4,7 +4,7 @@ "state": "ON", "led_brightness": 100, "countdown_to_turn_off": 0, - "voltage": 120, + "voltage": 120.2, "countdown_to_turn_on": 0, "ac_frequency": 60, "power_factor": 0.14, @@ -27,7 +27,7 @@ "led_brightness": 100, "countdown_to_turn_off": 0, "countdown_to_turn_on": 0, - "power": 2, + "power": 1.9, "current": 0.09, "energy": 54.08, "power_factor": 0.2, @@ -45,7 +45,7 @@ "state": "ON", "led_brightness": 100, "countdown_to_turn_off": 0, - "voltage": 119.6, + "voltage": 119.8, "countdown_to_turn_on": 0, "energy": 103.94, "power_factor": 0.2, @@ -74,13 +74,13 @@ "led_brightness": 100, "countdown_to_turn_off": 0, "countdown_to_turn_on": 0, - "voltage": 118.5, + "voltage": 118.2, "state": "ON", "ac_frequency": 60, - "energy": 211.16, - "power": 0.8, - "current": 0.87, - "power_factor": 0.75, + "energy": 211.17, + "power": 109.4, + "current": 0.92, + "power_factor": 0.94, "update": { "state": "idle", "installed_version": 268513381, @@ -95,10 +95,10 @@ "led_brightness": 100, "countdown_to_turn_off": 0, "countdown_to_turn_on": 0, - "voltage": 120, + "voltage": 120.2, "energy": 100.79, "state": "ON", - "power": 10.2, + "power": 12.7, "current": 0.18, "ac_frequency": 60, "power_factor": 0.51, @@ -119,7 +119,7 @@ "energy": 14.23, "current": 0.01, "power": 0.1, - "power_factor": 0.16, + "power_factor": 0.11, "linkquality": 116, "update": { "state": "idle", @@ -136,13 +136,13 @@ "0xffffb40e0608864e": { "led_brightness": 100, "countdown_to_turn_off": 0, - "voltage": 120.3, + "voltage": 120.6, "energy": 34.53, "countdown_to_turn_on": 0, "state": "ON", "current": 0.02, "ac_frequency": 60, - "power": 0.3, + "power": 0.4, "power_factor": 0.14, "update": { "state": "idle",