Co-authored-by: dev_agent <dev_agent@cubecraftlabs.com> Co-committed-by: dev_agent <dev_agent@cubecraftlabs.com>
4369 lines
134 KiB
JavaScript
4369 lines
134 KiB
JavaScript
const F = globalThis, ce = F.ShadowRoot && (F.ShadyCSS === void 0 || F.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, de = /* @__PURE__ */ Symbol(), me = /* @__PURE__ */ new WeakMap();
|
||
let Fe = class {
|
||
constructor(e, t, n) {
|
||
if (this._$cssResult$ = !0, n !== de) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
|
||
this.cssText = e, this.t = t;
|
||
}
|
||
get styleSheet() {
|
||
let e = this.o;
|
||
const t = this.t;
|
||
if (ce && e === void 0) {
|
||
const n = t !== void 0 && t.length === 1;
|
||
n && (e = me.get(t)), e === void 0 && ((this.o = e = new CSSStyleSheet()).replaceSync(this.cssText), n && me.set(t, e));
|
||
}
|
||
return e;
|
||
}
|
||
toString() {
|
||
return this.cssText;
|
||
}
|
||
};
|
||
const x = (i) => new Fe(typeof i == "string" ? i : i + "", void 0, de), Ve = (i, ...e) => {
|
||
const t = i.length === 1 ? i[0] : e.reduce((n, s, a) => n + ((r) => {
|
||
if (r._$cssResult$ === !0) return r.cssText;
|
||
if (typeof r == "number") return r;
|
||
throw Error("Value passed to 'css' function must be a 'css' function result: " + r + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.");
|
||
})(s) + i[a + 1], i[0]);
|
||
return new Fe(t, i, de);
|
||
}, tt = (i, e) => {
|
||
if (ce) i.adoptedStyleSheets = e.map((t) => t instanceof CSSStyleSheet ? t : t.styleSheet);
|
||
else for (const t of e) {
|
||
const n = document.createElement("style"), s = F.litNonce;
|
||
s !== void 0 && n.setAttribute("nonce", s), n.textContent = t.cssText, i.appendChild(n);
|
||
}
|
||
}, ge = ce ? (i) => i : (i) => i instanceof CSSStyleSheet ? ((e) => {
|
||
let t = "";
|
||
for (const n of e.cssRules) t += n.cssText;
|
||
return x(t);
|
||
})(i) : i;
|
||
const { is: nt, defineProperty: it, getOwnPropertyDescriptor: st, getOwnPropertyNames: at, getOwnPropertySymbols: rt, getPrototypeOf: ot } = Object, K = globalThis, _e = K.trustedTypes, lt = _e ? _e.emptyScript : "", ct = K.reactiveElementPolyfillSupport, I = (i, e) => i, ae = { toAttribute(i, e) {
|
||
switch (e) {
|
||
case Boolean:
|
||
i = i ? lt : null;
|
||
break;
|
||
case Object:
|
||
case Array:
|
||
i = i == null ? i : JSON.stringify(i);
|
||
}
|
||
return i;
|
||
}, fromAttribute(i, e) {
|
||
let t = i;
|
||
switch (e) {
|
||
case Boolean:
|
||
t = i !== null;
|
||
break;
|
||
case Number:
|
||
t = i === null ? null : Number(i);
|
||
break;
|
||
case Object:
|
||
case Array:
|
||
try {
|
||
t = JSON.parse(i);
|
||
} catch {
|
||
t = null;
|
||
}
|
||
}
|
||
return t;
|
||
} }, Ze = (i, e) => !nt(i, e), ye = { attribute: !0, type: String, converter: ae, reflect: !1, useDefault: !1, hasChanged: Ze };
|
||
Symbol.metadata ??= /* @__PURE__ */ Symbol("metadata"), K.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap();
|
||
let z = class extends HTMLElement {
|
||
static addInitializer(e) {
|
||
this._$Ei(), (this.l ??= []).push(e);
|
||
}
|
||
static get observedAttributes() {
|
||
return this.finalize(), this._$Eh && [...this._$Eh.keys()];
|
||
}
|
||
static createProperty(e, t = ye) {
|
||
if (t.state && (t.attribute = !1), this._$Ei(), this.prototype.hasOwnProperty(e) && ((t = Object.create(t)).wrapped = !0), this.elementProperties.set(e, t), !t.noAccessor) {
|
||
const n = /* @__PURE__ */ Symbol(), s = this.getPropertyDescriptor(e, n, t);
|
||
s !== void 0 && it(this.prototype, e, s);
|
||
}
|
||
}
|
||
static getPropertyDescriptor(e, t, n) {
|
||
const { get: s, set: a } = st(this.prototype, e) ?? { get() {
|
||
return this[t];
|
||
}, set(r) {
|
||
this[t] = r;
|
||
} };
|
||
return { get: s, set(r) {
|
||
const l = s?.call(this);
|
||
a?.call(this, r), this.requestUpdate(e, l, n);
|
||
}, configurable: !0, enumerable: !0 };
|
||
}
|
||
static getPropertyOptions(e) {
|
||
return this.elementProperties.get(e) ?? ye;
|
||
}
|
||
static _$Ei() {
|
||
if (this.hasOwnProperty(I("elementProperties"))) return;
|
||
const e = ot(this);
|
||
e.finalize(), e.l !== void 0 && (this.l = [...e.l]), this.elementProperties = new Map(e.elementProperties);
|
||
}
|
||
static finalize() {
|
||
if (this.hasOwnProperty(I("finalized"))) return;
|
||
if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(I("properties"))) {
|
||
const t = this.properties, n = [...at(t), ...rt(t)];
|
||
for (const s of n) this.createProperty(s, t[s]);
|
||
}
|
||
const e = this[Symbol.metadata];
|
||
if (e !== null) {
|
||
const t = litPropertyMetadata.get(e);
|
||
if (t !== void 0) for (const [n, s] of t) this.elementProperties.set(n, s);
|
||
}
|
||
this._$Eh = /* @__PURE__ */ new Map();
|
||
for (const [t, n] of this.elementProperties) {
|
||
const s = this._$Eu(t, n);
|
||
s !== void 0 && this._$Eh.set(s, t);
|
||
}
|
||
this.elementStyles = this.finalizeStyles(this.styles);
|
||
}
|
||
static finalizeStyles(e) {
|
||
const t = [];
|
||
if (Array.isArray(e)) {
|
||
const n = new Set(e.flat(1 / 0).reverse());
|
||
for (const s of n) t.unshift(ge(s));
|
||
} else e !== void 0 && t.push(ge(e));
|
||
return t;
|
||
}
|
||
static _$Eu(e, t) {
|
||
const n = t.attribute;
|
||
return n === !1 ? void 0 : typeof n == "string" ? n : typeof e == "string" ? e.toLowerCase() : void 0;
|
||
}
|
||
constructor() {
|
||
super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev();
|
||
}
|
||
_$Ev() {
|
||
this._$ES = new Promise((e) => this.enableUpdating = e), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((e) => e(this));
|
||
}
|
||
addController(e) {
|
||
(this._$EO ??= /* @__PURE__ */ new Set()).add(e), this.renderRoot !== void 0 && this.isConnected && e.hostConnected?.();
|
||
}
|
||
removeController(e) {
|
||
this._$EO?.delete(e);
|
||
}
|
||
_$E_() {
|
||
const e = /* @__PURE__ */ new Map(), t = this.constructor.elementProperties;
|
||
for (const n of t.keys()) this.hasOwnProperty(n) && (e.set(n, this[n]), delete this[n]);
|
||
e.size > 0 && (this._$Ep = e);
|
||
}
|
||
createRenderRoot() {
|
||
const e = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
|
||
return tt(e, this.constructor.elementStyles), e;
|
||
}
|
||
connectedCallback() {
|
||
this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$EO?.forEach((e) => e.hostConnected?.());
|
||
}
|
||
enableUpdating(e) {
|
||
}
|
||
disconnectedCallback() {
|
||
this._$EO?.forEach((e) => e.hostDisconnected?.());
|
||
}
|
||
attributeChangedCallback(e, t, n) {
|
||
this._$AK(e, n);
|
||
}
|
||
_$ET(e, t) {
|
||
const n = this.constructor.elementProperties.get(e), s = this.constructor._$Eu(e, n);
|
||
if (s !== void 0 && n.reflect === !0) {
|
||
const a = (n.converter?.toAttribute !== void 0 ? n.converter : ae).toAttribute(t, n.type);
|
||
this._$Em = e, a == null ? this.removeAttribute(s) : this.setAttribute(s, a), this._$Em = null;
|
||
}
|
||
}
|
||
_$AK(e, t) {
|
||
const n = this.constructor, s = n._$Eh.get(e);
|
||
if (s !== void 0 && this._$Em !== s) {
|
||
const a = n.getPropertyOptions(s), r = typeof a.converter == "function" ? { fromAttribute: a.converter } : a.converter?.fromAttribute !== void 0 ? a.converter : ae;
|
||
this._$Em = s;
|
||
const l = r.fromAttribute(t, a.type);
|
||
this[s] = l ?? this._$Ej?.get(s) ?? l, this._$Em = null;
|
||
}
|
||
}
|
||
requestUpdate(e, t, n, s = !1, a) {
|
||
if (e !== void 0) {
|
||
const r = this.constructor;
|
||
if (s === !1 && (a = this[e]), n ??= r.getPropertyOptions(e), !((n.hasChanged ?? Ze)(a, t) || n.useDefault && n.reflect && a === this._$Ej?.get(e) && !this.hasAttribute(r._$Eu(e, n)))) return;
|
||
this.C(e, t, n);
|
||
}
|
||
this.isUpdatePending === !1 && (this._$ES = this._$EP());
|
||
}
|
||
C(e, t, { useDefault: n, reflect: s, wrapped: a }, r) {
|
||
n && !(this._$Ej ??= /* @__PURE__ */ new Map()).has(e) && (this._$Ej.set(e, r ?? t ?? this[e]), a !== !0 || r !== void 0) || (this._$AL.has(e) || (this.hasUpdated || n || (t = void 0), this._$AL.set(e, t)), s === !0 && this._$Em !== e && (this._$Eq ??= /* @__PURE__ */ new Set()).add(e));
|
||
}
|
||
async _$EP() {
|
||
this.isUpdatePending = !0;
|
||
try {
|
||
await this._$ES;
|
||
} catch (t) {
|
||
Promise.reject(t);
|
||
}
|
||
const e = this.scheduleUpdate();
|
||
return e != null && await e, !this.isUpdatePending;
|
||
}
|
||
scheduleUpdate() {
|
||
return this.performUpdate();
|
||
}
|
||
performUpdate() {
|
||
if (!this.isUpdatePending) return;
|
||
if (!this.hasUpdated) {
|
||
if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) {
|
||
for (const [s, a] of this._$Ep) this[s] = a;
|
||
this._$Ep = void 0;
|
||
}
|
||
const n = this.constructor.elementProperties;
|
||
if (n.size > 0) for (const [s, a] of n) {
|
||
const { wrapped: r } = a, l = this[s];
|
||
r !== !0 || this._$AL.has(s) || l === void 0 || this.C(s, void 0, a, l);
|
||
}
|
||
}
|
||
let e = !1;
|
||
const t = this._$AL;
|
||
try {
|
||
e = this.shouldUpdate(t), e ? (this.willUpdate(t), this._$EO?.forEach((n) => n.hostUpdate?.()), this.update(t)) : this._$EM();
|
||
} catch (n) {
|
||
throw e = !1, this._$EM(), n;
|
||
}
|
||
e && this._$AE(t);
|
||
}
|
||
willUpdate(e) {
|
||
}
|
||
_$AE(e) {
|
||
this._$EO?.forEach((t) => t.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(e)), this.updated(e);
|
||
}
|
||
_$EM() {
|
||
this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = !1;
|
||
}
|
||
get updateComplete() {
|
||
return this.getUpdateComplete();
|
||
}
|
||
getUpdateComplete() {
|
||
return this._$ES;
|
||
}
|
||
shouldUpdate(e) {
|
||
return !0;
|
||
}
|
||
update(e) {
|
||
this._$Eq &&= this._$Eq.forEach((t) => this._$ET(t, this[t])), this._$EM();
|
||
}
|
||
updated(e) {
|
||
}
|
||
firstUpdated(e) {
|
||
}
|
||
};
|
||
z.elementStyles = [], z.shadowRootOptions = { mode: "open" }, z[I("elementProperties")] = /* @__PURE__ */ new Map(), z[I("finalized")] = /* @__PURE__ */ new Map(), ct?.({ ReactiveElement: z }), (K.reactiveElementVersions ??= []).push("2.1.2");
|
||
const pe = globalThis, be = (i) => i, V = pe.trustedTypes, ve = V ? V.createPolicy("lit-html", { createHTML: (i) => i }) : void 0, Qe = "$lit$", k = `lit$${Math.random().toFixed(9).slice(2)}$`, We = "?" + k, dt = `<${We}>`, A = document, P = () => A.createComment(""), H = (i) => i === null || typeof i != "object" && typeof i != "function", he = Array.isArray, pt = (i) => he(i) || typeof i?.[Symbol.iterator] == "function", Y = `[
|
||
\f\r]`, L = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, xe = /-->/g, we = />/g, $ = RegExp(`>|${Y}(?:([^\\s"'>=/]+)(${Y}*=${Y}*(?:[^
|
||
\f\r"'\`<>=]|("|')|))|$)`, "g"), ke = /'/g, $e = /"/g, Ge = /^(?:script|style|textarea|title)$/i, Ke = (i) => (e, ...t) => ({ _$litType$: i, strings: e, values: t }), d = Ke(1), qe = Ke(2), S = /* @__PURE__ */ Symbol.for("lit-noChange"), g = /* @__PURE__ */ Symbol.for("lit-nothing"), Me = /* @__PURE__ */ new WeakMap(), M = A.createTreeWalker(A, 129);
|
||
function Je(i, e) {
|
||
if (!he(i) || !i.hasOwnProperty("raw")) throw Error("invalid template strings array");
|
||
return ve !== void 0 ? ve.createHTML(e) : e;
|
||
}
|
||
const ht = (i, e) => {
|
||
const t = i.length - 1, n = [];
|
||
let s, a = e === 2 ? "<svg>" : e === 3 ? "<math>" : "", r = L;
|
||
for (let l = 0; l < t; l++) {
|
||
const o = i[l];
|
||
let p, u, c = -1, f = 0;
|
||
for (; f < o.length && (r.lastIndex = f, u = r.exec(o), u !== null); ) f = r.lastIndex, r === L ? u[1] === "!--" ? r = xe : u[1] !== void 0 ? r = we : u[2] !== void 0 ? (Ge.test(u[2]) && (s = RegExp("</" + u[2], "g")), r = $) : u[3] !== void 0 && (r = $) : r === $ ? u[0] === ">" ? (r = s ?? L, c = -1) : u[1] === void 0 ? c = -2 : (c = r.lastIndex - u[2].length, p = u[1], r = u[3] === void 0 ? $ : u[3] === '"' ? $e : ke) : r === $e || r === ke ? r = $ : r === xe || r === we ? r = L : (r = $, s = void 0);
|
||
const h = r === $ && i[l + 1].startsWith("/>") ? " " : "";
|
||
a += r === L ? o + dt : c >= 0 ? (n.push(p), o.slice(0, c) + Qe + o.slice(c) + k + h) : o + k + (c === -2 ? l : h);
|
||
}
|
||
return [Je(i, a + (i[t] || "<?>") + (e === 2 ? "</svg>" : e === 3 ? "</math>" : "")), n];
|
||
};
|
||
class R {
|
||
constructor({ strings: e, _$litType$: t }, n) {
|
||
let s;
|
||
this.parts = [];
|
||
let a = 0, r = 0;
|
||
const l = e.length - 1, o = this.parts, [p, u] = ht(e, t);
|
||
if (this.el = R.createElement(p, n), M.currentNode = this.el.content, t === 2 || t === 3) {
|
||
const c = this.el.content.firstChild;
|
||
c.replaceWith(...c.childNodes);
|
||
}
|
||
for (; (s = M.nextNode()) !== null && o.length < l; ) {
|
||
if (s.nodeType === 1) {
|
||
if (s.hasAttributes()) for (const c of s.getAttributeNames()) if (c.endsWith(Qe)) {
|
||
const f = u[r++], h = s.getAttribute(c).split(k), m = /([.?@])?(.*)/.exec(f);
|
||
o.push({ type: 1, index: a, name: m[2], strings: h, ctor: m[1] === "." ? ft : m[1] === "?" ? mt : m[1] === "@" ? gt : J }), s.removeAttribute(c);
|
||
} else c.startsWith(k) && (o.push({ type: 6, index: a }), s.removeAttribute(c));
|
||
if (Ge.test(s.tagName)) {
|
||
const c = s.textContent.split(k), f = c.length - 1;
|
||
if (f > 0) {
|
||
s.textContent = V ? V.emptyScript : "";
|
||
for (let h = 0; h < f; h++) s.append(c[h], P()), M.nextNode(), o.push({ type: 2, index: ++a });
|
||
s.append(c[f], P());
|
||
}
|
||
}
|
||
} else if (s.nodeType === 8) if (s.data === We) o.push({ type: 2, index: a });
|
||
else {
|
||
let c = -1;
|
||
for (; (c = s.data.indexOf(k, c + 1)) !== -1; ) o.push({ type: 7, index: a }), c += k.length - 1;
|
||
}
|
||
a++;
|
||
}
|
||
}
|
||
static createElement(e, t) {
|
||
const n = A.createElement("template");
|
||
return n.innerHTML = e, n;
|
||
}
|
||
}
|
||
function T(i, e, t = i, n) {
|
||
if (e === S) return e;
|
||
let s = n !== void 0 ? t._$Co?.[n] : t._$Cl;
|
||
const a = H(e) ? void 0 : e._$litDirective$;
|
||
return s?.constructor !== a && (s?._$AO?.(!1), a === void 0 ? s = void 0 : (s = new a(i), s._$AT(i, t, n)), n !== void 0 ? (t._$Co ??= [])[n] = s : t._$Cl = s), s !== void 0 && (e = T(i, s._$AS(i, e.values), s, n)), e;
|
||
}
|
||
class ut {
|
||
constructor(e, t) {
|
||
this._$AV = [], this._$AN = void 0, this._$AD = e, this._$AM = t;
|
||
}
|
||
get parentNode() {
|
||
return this._$AM.parentNode;
|
||
}
|
||
get _$AU() {
|
||
return this._$AM._$AU;
|
||
}
|
||
u(e) {
|
||
const { el: { content: t }, parts: n } = this._$AD, s = (e?.creationScope ?? A).importNode(t, !0);
|
||
M.currentNode = s;
|
||
let a = M.nextNode(), r = 0, l = 0, o = n[0];
|
||
for (; o !== void 0; ) {
|
||
if (r === o.index) {
|
||
let p;
|
||
o.type === 2 ? p = new N(a, a.nextSibling, this, e) : o.type === 1 ? p = new o.ctor(a, o.name, o.strings, this, e) : o.type === 6 && (p = new _t(a, this, e)), this._$AV.push(p), o = n[++l];
|
||
}
|
||
r !== o?.index && (a = M.nextNode(), r++);
|
||
}
|
||
return M.currentNode = A, s;
|
||
}
|
||
p(e) {
|
||
let t = 0;
|
||
for (const n of this._$AV) n !== void 0 && (n.strings !== void 0 ? (n._$AI(e, n, t), t += n.strings.length - 2) : n._$AI(e[t])), t++;
|
||
}
|
||
}
|
||
class N {
|
||
get _$AU() {
|
||
return this._$AM?._$AU ?? this._$Cv;
|
||
}
|
||
constructor(e, t, n, s) {
|
||
this.type = 2, this._$AH = g, this._$AN = void 0, this._$AA = e, this._$AB = t, this._$AM = n, this.options = s, this._$Cv = s?.isConnected ?? !0;
|
||
}
|
||
get parentNode() {
|
||
let e = this._$AA.parentNode;
|
||
const t = this._$AM;
|
||
return t !== void 0 && e?.nodeType === 11 && (e = t.parentNode), e;
|
||
}
|
||
get startNode() {
|
||
return this._$AA;
|
||
}
|
||
get endNode() {
|
||
return this._$AB;
|
||
}
|
||
_$AI(e, t = this) {
|
||
e = T(this, e, t), H(e) ? e === g || e == null || e === "" ? (this._$AH !== g && this._$AR(), this._$AH = g) : e !== this._$AH && e !== S && this._(e) : e._$litType$ !== void 0 ? this.$(e) : e.nodeType !== void 0 ? this.T(e) : pt(e) ? this.k(e) : this._(e);
|
||
}
|
||
O(e) {
|
||
return this._$AA.parentNode.insertBefore(e, this._$AB);
|
||
}
|
||
T(e) {
|
||
this._$AH !== e && (this._$AR(), this._$AH = this.O(e));
|
||
}
|
||
_(e) {
|
||
this._$AH !== g && H(this._$AH) ? this._$AA.nextSibling.data = e : this.T(A.createTextNode(e)), this._$AH = e;
|
||
}
|
||
$(e) {
|
||
const { values: t, _$litType$: n } = e, s = typeof n == "number" ? this._$AC(e) : (n.el === void 0 && (n.el = R.createElement(Je(n.h, n.h[0]), this.options)), n);
|
||
if (this._$AH?._$AD === s) this._$AH.p(t);
|
||
else {
|
||
const a = new ut(s, this), r = a.u(this.options);
|
||
a.p(t), this.T(r), this._$AH = a;
|
||
}
|
||
}
|
||
_$AC(e) {
|
||
let t = Me.get(e.strings);
|
||
return t === void 0 && Me.set(e.strings, t = new R(e)), t;
|
||
}
|
||
k(e) {
|
||
he(this._$AH) || (this._$AH = [], this._$AR());
|
||
const t = this._$AH;
|
||
let n, s = 0;
|
||
for (const a of e) s === t.length ? t.push(n = new N(this.O(P()), this.O(P()), this, this.options)) : n = t[s], n._$AI(a), s++;
|
||
s < t.length && (this._$AR(n && n._$AB.nextSibling, s), t.length = s);
|
||
}
|
||
_$AR(e = this._$AA.nextSibling, t) {
|
||
for (this._$AP?.(!1, !0, t); e !== this._$AB; ) {
|
||
const n = be(e).nextSibling;
|
||
be(e).remove(), e = n;
|
||
}
|
||
}
|
||
setConnected(e) {
|
||
this._$AM === void 0 && (this._$Cv = e, this._$AP?.(e));
|
||
}
|
||
}
|
||
class J {
|
||
get tagName() {
|
||
return this.element.tagName;
|
||
}
|
||
get _$AU() {
|
||
return this._$AM._$AU;
|
||
}
|
||
constructor(e, t, n, s, a) {
|
||
this.type = 1, this._$AH = g, this._$AN = void 0, this.element = e, this.name = t, this._$AM = s, this.options = a, n.length > 2 || n[0] !== "" || n[1] !== "" ? (this._$AH = Array(n.length - 1).fill(new String()), this.strings = n) : this._$AH = g;
|
||
}
|
||
_$AI(e, t = this, n, s) {
|
||
const a = this.strings;
|
||
let r = !1;
|
||
if (a === void 0) e = T(this, e, t, 0), r = !H(e) || e !== this._$AH && e !== S, r && (this._$AH = e);
|
||
else {
|
||
const l = e;
|
||
let o, p;
|
||
for (e = a[0], o = 0; o < a.length - 1; o++) p = T(this, l[n + o], t, o), p === S && (p = this._$AH[o]), r ||= !H(p) || p !== this._$AH[o], p === g ? e = g : e !== g && (e += (p ?? "") + a[o + 1]), this._$AH[o] = p;
|
||
}
|
||
r && !s && this.j(e);
|
||
}
|
||
j(e) {
|
||
e === g ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, e ?? "");
|
||
}
|
||
}
|
||
class ft extends J {
|
||
constructor() {
|
||
super(...arguments), this.type = 3;
|
||
}
|
||
j(e) {
|
||
this.element[this.name] = e === g ? void 0 : e;
|
||
}
|
||
}
|
||
class mt extends J {
|
||
constructor() {
|
||
super(...arguments), this.type = 4;
|
||
}
|
||
j(e) {
|
||
this.element.toggleAttribute(this.name, !!e && e !== g);
|
||
}
|
||
}
|
||
class gt extends J {
|
||
constructor(e, t, n, s, a) {
|
||
super(e, t, n, s, a), this.type = 5;
|
||
}
|
||
_$AI(e, t = this) {
|
||
if ((e = T(this, e, t, 0) ?? g) === S) return;
|
||
const n = this._$AH, s = e === g && n !== g || e.capture !== n.capture || e.once !== n.once || e.passive !== n.passive, a = e !== g && (n === g || s);
|
||
s && this.element.removeEventListener(this.name, this, n), a && this.element.addEventListener(this.name, this, e), this._$AH = e;
|
||
}
|
||
handleEvent(e) {
|
||
typeof this._$AH == "function" ? this._$AH.call(this.options?.host ?? this.element, e) : this._$AH.handleEvent(e);
|
||
}
|
||
}
|
||
class _t {
|
||
constructor(e, t, n) {
|
||
this.element = e, this.type = 6, this._$AN = void 0, this._$AM = t, this.options = n;
|
||
}
|
||
get _$AU() {
|
||
return this._$AM._$AU;
|
||
}
|
||
_$AI(e) {
|
||
T(this, e);
|
||
}
|
||
}
|
||
const yt = { I: N }, bt = pe.litHtmlPolyfillSupport;
|
||
bt?.(R, N), (pe.litHtmlVersions ??= []).push("3.3.3");
|
||
const vt = (i, e, t) => {
|
||
const n = t?.renderBefore ?? e;
|
||
let s = n._$litPart$;
|
||
if (s === void 0) {
|
||
const a = t?.renderBefore ?? null;
|
||
n._$litPart$ = s = new N(e.insertBefore(P(), a), a, void 0, t ?? {});
|
||
}
|
||
return s._$AI(i), s;
|
||
};
|
||
const ue = globalThis;
|
||
let C = class extends z {
|
||
constructor() {
|
||
super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0;
|
||
}
|
||
createRenderRoot() {
|
||
const e = super.createRenderRoot();
|
||
return this.renderOptions.renderBefore ??= e.firstChild, e;
|
||
}
|
||
update(e) {
|
||
const t = this.render();
|
||
this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(e), this._$Do = vt(t, this.renderRoot, this.renderOptions);
|
||
}
|
||
connectedCallback() {
|
||
super.connectedCallback(), this._$Do?.setConnected(!0);
|
||
}
|
||
disconnectedCallback() {
|
||
super.disconnectedCallback(), this._$Do?.setConnected(!1);
|
||
}
|
||
render() {
|
||
return S;
|
||
}
|
||
};
|
||
C._$litElement$ = !0, C.finalized = !0, ue.litElementHydrateSupport?.({ LitElement: C });
|
||
const xt = ue.litElementPolyfillSupport;
|
||
xt?.({ LitElement: C });
|
||
(ue.litElementVersions ??= []).push("4.2.2");
|
||
const Xe = ':host{--nq-p-parchment-top: #f0e4c7;--nq-p-parchment-bottom: #ddcca3;--nq-p-parchment: radial-gradient(ellipse at 25% 10%, rgba(255,255,255,.5), transparent 55%), radial-gradient(ellipse at 85% 90%, rgba(120,86,44,.28), transparent 60%), repeating-linear-gradient(93deg, rgba(150,115,70,.05) 0 2px, transparent 2px 6px), repeating-linear-gradient(2deg, rgba(150,115,70,.04) 0 3px, transparent 3px 7px), linear-gradient(var(--nq-p-parchment-top), var(--nq-p-parchment-bottom));--nq-p-vignette: inset 0 0 200px rgba(80,52,20,.35);--nq-p-card-open: linear-gradient(#fdf7e6, #f2e7c9);--nq-p-card-done: linear-gradient(#f0e8d3, #e6dcc2);--nq-p-card-panel: linear-gradient(#fcf6e6, #f1e6ca);--nq-p-card-border: rgba(120,88,48,.38);--nq-p-panel-border: rgba(92,62,26,.4);--nq-p-card-shadow: 0 3px 0 rgba(120,88,48,.2), inset 0 1px 0 rgba(255,255,255,.7);--nq-p-panel-shadow: 0 6px 0 rgba(92,62,26,.18), inset 0 2px 0 rgba(255,255,255,.7);--nq-p-frame-outer: 2px solid rgba(92,62,26,.45);--nq-p-frame-inner: 1px solid rgba(92,62,26,.28);--nq-p-rule: 2px solid rgba(92,62,26,.35);--nq-p-ink: #2b1f14;--nq-p-ink-secondary: #5c452a;--nq-p-ink-muted: #6f6455;--nq-p-ink-away: #4d4433;--nq-p-ink-late: #8f1526;--nq-brand-blue: #3B3AB8;--nq-brand-purple: #A035CC;--nq-brand-gradient: linear-gradient(135deg, var(--nq-brand-blue), var(--nq-brand-purple));--nq-p-icon-tile: var(--nq-brand-gradient);--nq-p-icon-tile-done: rgba(92,62,26,.16);--nq-p-crest: var(--nq-brand-gradient);--nq-p-crest-away: linear-gradient(135deg, #6b6b7a, #7a7286);--nq-p-seal: radial-gradient(circle at 35% 30%, #a8283a, #6d1322);--nq-p-seal-shadow: 0 4px 10px rgba(60,10,20,.4), inset 0 0 0 4px rgba(255,255,255,.14);--nq-p-seal-size: 78px;--nq-p-dock-bg: rgba(43,31,20,.9);--nq-p-dock-ink: #f7efdb;--nq-p-dock-ink-secondary: #d8c9a6;--nq-p-dock-divider: rgba(233,220,189,.3);--nq-p-dock-height: 84px;--nq-p-font-display: "Cinzel Decorative", Cinzel, serif;--nq-p-font-heading: Cinzel, serif;--nq-p-font-body: Nunito, system-ui, sans-serif;--nq-p-size-hero: 86px;--nq-p-size-wordmark: 66px;--nq-p-size-title: 56px;--nq-p-size-name: 48px;--nq-p-size-section: 32px;--nq-p-size-quest: 30px;--nq-p-size-body: 22px;--nq-p-size-label: 21px;--nq-p-track-label: .14em;--nq-p-track-kicker: .3em;--nq-p-quest-min-height: 116px;--nq-p-quest-gap: 24px;--nq-p-quest-pad: 22px;--nq-p-tile-size: 64px;--nq-p-button-height: 72px;--nq-p-button-min-width: 150px;--nq-p-confirm-button: 108px;--nq-p-radius-card: 12px;--nq-p-radius-panel: 20px;--nq-p-radius-pill: 9999px;--nq-p-page-inset: 62px;--nq-p-frame-inset: 26px;--nq-ease-out: cubic-bezier(0, 0, .2, 1);--nq-dur-micro: .12s;--nq-dur-base: .2s;--nq-dur-modal: .35s}';
|
||
function fe(i) {
|
||
window.customCards = window.customCards ?? [], window.customCards.push(i);
|
||
}
|
||
const wt = [
|
||
"nestquest_quest_completed",
|
||
"nestquest_quest_uncompleted",
|
||
"nestquest_quest_missed",
|
||
"nestquest_child_day_complete"
|
||
], Ce = /* @__PURE__ */ new Map();
|
||
function Z(i, e) {
|
||
const t = `${i ?? "local"}|${JSON.stringify(e)}`, n = Ce.get(t);
|
||
if (n)
|
||
return n;
|
||
let s;
|
||
try {
|
||
s = new Intl.DateTimeFormat("en-US", {
|
||
...e,
|
||
...i ? { timeZone: i } : {}
|
||
});
|
||
} catch {
|
||
s = new Intl.DateTimeFormat("en-US", e);
|
||
}
|
||
return Ce.set(t, s), s;
|
||
}
|
||
function kt(i) {
|
||
const e = i?.config;
|
||
if (!e || typeof e != "object")
|
||
return;
|
||
const t = e.time_zone;
|
||
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
||
}
|
||
function ee(i, e) {
|
||
return `${Z(e, { weekday: "long" }).format(i)}, ${Z(e, { month: "short", day: "numeric" }).format(i)}`;
|
||
}
|
||
function $t(i, e) {
|
||
return Z(e, {
|
||
hour: "numeric",
|
||
minute: "2-digit",
|
||
hour12: !0
|
||
}).format(i);
|
||
}
|
||
const qt = {
|
||
"clear-night": "Clear",
|
||
cloudy: "Cloudy",
|
||
exceptional: "Clear",
|
||
fog: "Foggy",
|
||
hail: "Hail",
|
||
lightning: "Storms",
|
||
"lightning-rimmed": "Storms",
|
||
partlycloudy: "Partly cloudy",
|
||
pouring: "Heavy rain",
|
||
rainy: "Rain",
|
||
snowy: "Snow",
|
||
"snowy-rainy": "Sleet",
|
||
sunny: "Sunny",
|
||
windy: "Windy",
|
||
"windy-variant": "Windy"
|
||
}, Mt = {
|
||
"clear-night": "Clear night skies",
|
||
cloudy: "Grey skies today",
|
||
exceptional: "A striking day",
|
||
fog: "Mist on the road",
|
||
hail: "Ice from the sky",
|
||
lightning: "Storms may roll in",
|
||
"lightning-rimmed": "Storms may roll in",
|
||
partlycloudy: "Sun between clouds",
|
||
pouring: "Heavy rain outside",
|
||
rainy: "Rain on the walls",
|
||
snowy: "Snow on the peaks",
|
||
"snowy-rainy": "Sleet may fall",
|
||
sunny: "Clear skies today",
|
||
windy: "A blustery day",
|
||
"windy-variant": "A blustery day"
|
||
};
|
||
function Ae(i) {
|
||
return typeof i == "string" ? i.trim() : "";
|
||
}
|
||
function te(i, e) {
|
||
if (i == null || i === "")
|
||
return e;
|
||
const t = typeof i == "number" ? i : Number(i);
|
||
return Number.isFinite(t) ? t : e;
|
||
}
|
||
function Ct(i) {
|
||
if (i === null || typeof i != "object" || Array.isArray(i))
|
||
return "";
|
||
const e = i.slug;
|
||
return typeof e == "string" ? e.trim() : "";
|
||
}
|
||
function Se(i) {
|
||
return Number.isFinite(i) ? Math.min(100, Math.max(0, i)) : 0;
|
||
}
|
||
function ze(i) {
|
||
return Math.max(0, Math.round(i));
|
||
}
|
||
function At(i) {
|
||
return i.split(/[-_]+/).filter(Boolean).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
|
||
}
|
||
function St(i, e) {
|
||
const t = Z(e, {
|
||
year: "numeric",
|
||
month: "2-digit",
|
||
day: "2-digit",
|
||
hour: "2-digit",
|
||
minute: "2-digit",
|
||
second: "2-digit",
|
||
hourCycle: "h23"
|
||
}).formatToParts(new Date(i)), n = (a) => {
|
||
const r = t.find((l) => l.type === a);
|
||
return r ? Number(r.value) : Number.NaN;
|
||
}, s = Date.UTC(
|
||
n("year"),
|
||
n("month") - 1,
|
||
n("day"),
|
||
n("hour"),
|
||
n("minute"),
|
||
n("second")
|
||
);
|
||
return Number.isFinite(s) ? s - i : 0;
|
||
}
|
||
function zt(i, e) {
|
||
if (typeof i != "string")
|
||
return null;
|
||
const t = i.split("-");
|
||
if (t.length !== 3)
|
||
return null;
|
||
const [n, s, a] = t.map((o) => Number(o));
|
||
if (!n || !s || !a)
|
||
return null;
|
||
if (!e) {
|
||
const o = new Date(n, s - 1, a);
|
||
return Number.isNaN(o.getTime()) ? null : o;
|
||
}
|
||
const r = Date.UTC(n, s - 1, a), l = new Date(r - St(r, e));
|
||
return Number.isNaN(l.getTime()) ? null : l;
|
||
}
|
||
function Tt(i) {
|
||
const e = qt[i];
|
||
return e || i.charAt(0).toUpperCase() + i.slice(1);
|
||
}
|
||
function Et(i, e) {
|
||
return Mt[i] ?? e;
|
||
}
|
||
const Te = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Ee = "M50 3 44.5 24.1 50 26 55.5 24.1Z M100 50 75.9 44.5 74 50 75.9 55.5Z M50 97 55.5 75.9 50 74 44.5 75.9Z M0 50 24.1 55.5 26 50 24.1 44.5Z M29.1 29.1 29.7 36.3 36.3 29.7Z M70.9 29.1 63.7 29.7 70.3 36.3Z M70.9 70.9 70.3 63.7 63.7 70.3Z M29.1 70.9 36.3 70.3 29.7 63.7Z", Nt = "M50 26.5 70.4 38.2 70.4 61.8 50 73.5 29.6 61.8 29.6 38.2Z", Lt = "M29.6 38.2H70.4M29.6 61.8H70.4M50 26.5 36.5 38.2M50 26.5 63.5 38.2M50 73.5 36.5 61.8M50 73.5 63.5 61.8M36.5 38.2V61.8M63.5 38.2V61.8M29.6 38.2 36.5 61.8M36.5 38.2 29.6 61.8M70.4 38.2 63.5 61.8M63.5 38.2 70.4 61.8", Ot = d`<svg
|
||
class="monogram"
|
||
viewBox="0 0 100 100"
|
||
aria-hidden="true"
|
||
focusable="false"
|
||
>
|
||
<defs>
|
||
<linearGradient
|
||
id="nq-monogram-fill"
|
||
gradientUnits="userSpaceOnUse"
|
||
x1="0"
|
||
y1="0"
|
||
x2="100"
|
||
y2="100"
|
||
>
|
||
<stop offset="0" style="stop-color: var(--nq-brand-blue)" />
|
||
<stop offset="1" style="stop-color: var(--nq-brand-purple)" />
|
||
</linearGradient>
|
||
<mask id="nq-monogram-points-gap" maskUnits="userSpaceOnUse">
|
||
<rect width="100" height="100" fill="#fff" />
|
||
<path d=${Ee} stroke="#000" stroke-width="3.5" />
|
||
</mask>
|
||
<mask id="nq-monogram-facets" maskUnits="userSpaceOnUse">
|
||
<rect width="100" height="100" fill="#fff" />
|
||
<path d=${Lt} stroke="#000" stroke-width="1.6" />
|
||
<text
|
||
x="50"
|
||
y="59.4"
|
||
text-anchor="middle"
|
||
font-family="'Cinzel Decorative', Cinzel, serif"
|
||
font-weight="900"
|
||
font-size="25"
|
||
fill="#fff"
|
||
stroke="#000"
|
||
stroke-width="2"
|
||
paint-order="stroke"
|
||
>N</text>
|
||
</mask>
|
||
</defs>
|
||
<g fill="url(#nq-monogram-fill)">
|
||
<path d=${Ee} />
|
||
<g mask="url(#nq-monogram-points-gap)">
|
||
<circle
|
||
cx="50"
|
||
cy="50"
|
||
r="34.25"
|
||
fill="none"
|
||
stroke="url(#nq-monogram-fill)"
|
||
stroke-width="6.5"
|
||
/>
|
||
<path mask="url(#nq-monogram-facets)" d=${Nt} />
|
||
</g>
|
||
</g>
|
||
</svg>`, Bt = Ve`
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
:host {
|
||
display: block;
|
||
height: 100%;
|
||
--nq-brand-gradient-h: linear-gradient(
|
||
90deg,
|
||
var(--nq-brand-blue),
|
||
var(--nq-brand-purple)
|
||
);
|
||
}
|
||
|
||
.board {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
height: 1080px;
|
||
padding: 0;
|
||
overflow: hidden;
|
||
background: var(--nq-p-parchment);
|
||
box-shadow: var(--nq-p-vignette);
|
||
font-family: var(--nq-p-font-body);
|
||
}
|
||
|
||
.frame {
|
||
position: absolute;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.frame-outer {
|
||
inset: 26px;
|
||
border: var(--nq-p-frame-outer);
|
||
border-radius: 14px;
|
||
}
|
||
|
||
.frame-inner {
|
||
inset: 36px;
|
||
border: var(--nq-p-frame-inner);
|
||
border-radius: 8px;
|
||
}
|
||
|
||
.wordmark-row {
|
||
position: absolute;
|
||
top: 64px;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 26px;
|
||
width: 100%;
|
||
}
|
||
|
||
.rule {
|
||
flex: 1 1 0;
|
||
max-width: 340px;
|
||
height: 2px;
|
||
border-radius: 1px;
|
||
background: rgba(92, 62, 26, 0.35);
|
||
}
|
||
|
||
.monogram {
|
||
flex: none;
|
||
display: block;
|
||
width: 80px;
|
||
height: 80px;
|
||
}
|
||
|
||
.wordmark {
|
||
font-family: var(--nq-p-font-display);
|
||
font-size: var(--nq-p-size-wordmark);
|
||
font-weight: 900;
|
||
line-height: 1.15;
|
||
background: var(--nq-brand-gradient);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
-webkit-text-fill-color: transparent;
|
||
}
|
||
|
||
.kicker {
|
||
position: absolute;
|
||
top: 154px;
|
||
left: 0;
|
||
right: 0;
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
letter-spacing: var(--nq-p-track-kicker);
|
||
text-transform: uppercase;
|
||
line-height: 1.2;
|
||
text-align: center;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.plates {
|
||
position: absolute;
|
||
top: 262px;
|
||
left: 110px;
|
||
right: 110px;
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 56px;
|
||
}
|
||
|
||
.plate {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 26px;
|
||
height: 600px;
|
||
padding: 44px 28px 40px;
|
||
border: 2px solid var(--nq-p-panel-border);
|
||
border-radius: var(--nq-p-radius-panel);
|
||
background: var(--nq-p-card-panel);
|
||
box-shadow: var(--nq-p-panel-shadow);
|
||
font: inherit;
|
||
}
|
||
|
||
button.plate {
|
||
width: 100%;
|
||
color: inherit;
|
||
cursor: pointer;
|
||
-webkit-tap-highlight-color: transparent;
|
||
transition: transform var(--nq-dur-micro) var(--nq-ease-out);
|
||
}
|
||
|
||
button.plate:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
button.plate:focus-visible {
|
||
outline: 3px solid var(--nq-brand-purple);
|
||
outline-offset: 4px;
|
||
}
|
||
|
||
.plate.away {
|
||
border: 2px dashed var(--nq-p-panel-border);
|
||
background: linear-gradient(#f2ecdd, #e6dcc6);
|
||
box-shadow: none;
|
||
}
|
||
|
||
.crest {
|
||
position: relative;
|
||
flex: none;
|
||
width: 188px;
|
||
height: 214px;
|
||
padding: 4px;
|
||
clip-path: ${x(Te)};
|
||
background: rgba(255, 255, 255, 0.22);
|
||
}
|
||
|
||
.crest-face {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding-bottom: 70px;
|
||
clip-path: ${x(Te)};
|
||
background: var(--nq-p-crest);
|
||
}
|
||
|
||
.crest.away .crest-face {
|
||
background: var(--nq-p-crest-away);
|
||
}
|
||
|
||
.crest .initial {
|
||
font-family: var(--nq-p-font-display);
|
||
font-size: 82px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.name {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: var(--nq-p-size-name);
|
||
font-weight: 700;
|
||
letter-spacing: 0.02em;
|
||
line-height: 1.1;
|
||
color: var(--nq-p-ink);
|
||
}
|
||
|
||
.plate.away .name {
|
||
color: var(--nq-p-ink-away);
|
||
}
|
||
|
||
.pill {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
padding: 8px 20px;
|
||
border-radius: var(--nq-p-radius-pill);
|
||
background: rgba(22, 120, 60, 0.35);
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
line-height: 1;
|
||
color: #146b36;
|
||
}
|
||
|
||
.pill svg {
|
||
width: 22px;
|
||
height: 22px;
|
||
color: #157a3c;
|
||
}
|
||
|
||
.pill.away {
|
||
background: rgba(92, 62, 26, 0.16);
|
||
color: var(--nq-p-ink-away);
|
||
}
|
||
|
||
.pill.away svg {
|
||
color: var(--nq-p-ink-away);
|
||
}
|
||
|
||
.progress-line {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.bar {
|
||
width: 100%;
|
||
height: 16px;
|
||
border: 1px solid rgba(92, 62, 26, 0.35);
|
||
border-radius: var(--nq-p-radius-pill);
|
||
background: rgba(92, 62, 26, 0.18);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.bar .fill {
|
||
display: block;
|
||
height: 100%;
|
||
border-radius: inherit;
|
||
background: var(--nq-brand-gradient-h);
|
||
}
|
||
|
||
.hint {
|
||
position: absolute;
|
||
top: 896px;
|
||
left: 0;
|
||
right: 0;
|
||
margin: 0;
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 27px;
|
||
font-weight: 600;
|
||
line-height: 1.4;
|
||
text-align: center;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.plate.unknown {
|
||
border: 2px dashed var(--nq-p-panel-border);
|
||
background: linear-gradient(#f2ecdd, #e6dcc6);
|
||
box-shadow: none;
|
||
}
|
||
|
||
.notice-wrap {
|
||
position: absolute;
|
||
top: 262px;
|
||
left: 110px;
|
||
right: 110px;
|
||
bottom: 190px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.notice {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 20px;
|
||
width: 100%;
|
||
max-width: 980px;
|
||
padding: 56px 64px;
|
||
border: 2px solid var(--nq-p-panel-border);
|
||
border-radius: var(--nq-p-radius-panel);
|
||
background: var(--nq-p-card-panel);
|
||
box-shadow: var(--nq-p-panel-shadow);
|
||
text-align: center;
|
||
}
|
||
|
||
.notice svg {
|
||
width: 46px;
|
||
height: 46px;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.notice-headline {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 40px;
|
||
font-weight: 700;
|
||
line-height: 1.15;
|
||
color: var(--nq-p-ink);
|
||
}
|
||
|
||
.notice-body {
|
||
margin: 0;
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 24px;
|
||
font-weight: 600;
|
||
line-height: 1.4;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.spacer {
|
||
flex: 1 1 0;
|
||
}
|
||
|
||
.dock {
|
||
position: absolute;
|
||
left: 46px;
|
||
right: 46px;
|
||
bottom: 46px;
|
||
height: var(--nq-p-dock-height);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 24px;
|
||
padding: 0 40px;
|
||
border-radius: 14px;
|
||
background: var(--nq-p-dock-bg);
|
||
pointer-events: none;
|
||
user-select: none;
|
||
color: var(--nq-p-dock-ink);
|
||
}
|
||
|
||
.dock svg {
|
||
flex: none;
|
||
width: 40px;
|
||
height: 40px;
|
||
color: var(--nq-p-dock-ink);
|
||
}
|
||
|
||
.dock .divider {
|
||
flex: none;
|
||
width: 1px;
|
||
height: 40px;
|
||
background: var(--nq-p-dock-divider);
|
||
}
|
||
|
||
.dock .temp {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 38px;
|
||
font-weight: 800;
|
||
line-height: 1;
|
||
}
|
||
|
||
.dock .condition {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 26px;
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-dock-ink-secondary);
|
||
}
|
||
|
||
.dock .date {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 26px;
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-dock-ink-secondary);
|
||
}
|
||
|
||
.dock .clock {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 38px;
|
||
font-weight: 800;
|
||
line-height: 1;
|
||
}
|
||
`, It = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<circle cx="12" cy="12" r="10"></circle>
|
||
<path d="m9 12 2 2 4-4"></path>
|
||
</svg>`, Pt = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M3.5 21 12 3.5 20.5 21"></path>
|
||
<path d="M9 21l3-8 3 8"></path>
|
||
</svg>`, Ht = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<circle cx="12" cy="12" r="10"></circle>
|
||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"></polygon>
|
||
</svg>`, Rt = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path>
|
||
<path d="M12 9v4"></path>
|
||
<path d="M12 17h.01"></path>
|
||
</svg>`, Ut = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path>
|
||
<path d="m2 2 20 20"></path>
|
||
</svg>`, Ne = {
|
||
icon: Rt,
|
||
headline: "NestQuest is not set up yet",
|
||
body: "A parent needs to finish setting up NestQuest before the party can gather."
|
||
}, jt = {
|
||
icon: Ut,
|
||
headline: "The records cannot be reached",
|
||
body: "The party's records are quiet right now. NestQuest will return shortly."
|
||
}, Dt = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M12 2v2"></path>
|
||
<path d="m4.93 4.93 1.41 1.41"></path>
|
||
<path d="M20 12h2"></path>
|
||
<path d="m19.07 4.93-1.41 1.41"></path>
|
||
<path d="M15.947 12.65a4 4 0 0 0-5.925-4.128"></path>
|
||
<path d="M13 22H7a5 5 0 1 1 4.9-6H13a3 3 0 0 1 0 6Z"></path>
|
||
</svg>`, Q = class Q extends C {
|
||
constructor() {
|
||
super(...arguments), this._now = /* @__PURE__ */ new Date(), this._unsubs = [], this._subscribed = !1, this._subGeneration = 0;
|
||
}
|
||
setConfig(e) {
|
||
if (!e || typeof e != "object")
|
||
throw new Error("Invalid configuration");
|
||
this._config = e;
|
||
}
|
||
_hassConnection() {
|
||
const e = this.hass?.connection;
|
||
return !e || typeof e != "object" || typeof e.subscribeEvents != "function" ? null : e;
|
||
}
|
||
_subscribeLive() {
|
||
if (!this.isConnected || this._subscribed)
|
||
return;
|
||
const e = this._hassConnection();
|
||
if (!e)
|
||
return;
|
||
this._subscribed = !0;
|
||
const t = ++this._subGeneration, n = (s) => {
|
||
s.then((a) => {
|
||
this._subscribed && t === this._subGeneration ? this._unsubs.push(a) : a();
|
||
}).catch(() => {
|
||
t === this._subGeneration && (this._unsubscribeLive(), this._armSubscribeRetry());
|
||
});
|
||
};
|
||
for (const s of wt)
|
||
n(
|
||
e.subscribeEvents(() => this.requestUpdate(), s)
|
||
);
|
||
}
|
||
_armSubscribeRetry() {
|
||
this._retryTimer === void 0 && (this._retryTimer = window.setTimeout(() => {
|
||
this._retryTimer = void 0, this._subscribeLive();
|
||
}, 1e3));
|
||
}
|
||
_clearSubscribeRetry() {
|
||
this._retryTimer !== void 0 && (window.clearTimeout(this._retryTimer), this._retryTimer = void 0);
|
||
}
|
||
_unsubscribeLive() {
|
||
this._clearSubscribeRetry(), this._subGeneration++;
|
||
for (const e of this._unsubs)
|
||
e();
|
||
this._unsubs = [], this._subscribed = !1;
|
||
}
|
||
getCardSize() {
|
||
return 22;
|
||
}
|
||
connectedCallback() {
|
||
super.connectedCallback(), this._subscribeLive(), this._now = /* @__PURE__ */ new Date(), this._clockTimer = window.setInterval(() => {
|
||
this._now = /* @__PURE__ */ new Date();
|
||
}, 1e3);
|
||
}
|
||
updated() {
|
||
this._subscribeLive();
|
||
}
|
||
disconnectedCallback() {
|
||
this._unsubscribeLive(), this._clockTimer !== void 0 && (window.clearInterval(this._clockTimer), this._clockTimer = void 0), super.disconnectedCallback();
|
||
}
|
||
render() {
|
||
const e = this._boardNotice();
|
||
return d`
|
||
<div class="board">
|
||
<div class="frame frame-outer"></div>
|
||
<div class="frame frame-inner"></div>
|
||
<div class="wordmark-row">
|
||
<span class="rule"></span>
|
||
${Ot}
|
||
<span class="wordmark">NestQuest</span>
|
||
<span class="rule"></span>
|
||
</div>
|
||
<p class="kicker">The Party · ${ee(this._now, this._timeZone())}</p>
|
||
${e ? this._renderNotice(e) : d`
|
||
<div class="plates">
|
||
${this._plates().map((t) => this._renderPlate(t))}
|
||
</div>
|
||
<p class="hint">Tap your crest to open your Quest Log</p>
|
||
`}
|
||
<div class="spacer"></div>
|
||
${this._renderDock()}
|
||
</div>
|
||
`;
|
||
}
|
||
/** The zone the visible date and clock render in: the API's effective
|
||
* application timezone — the stored zone, or the API host's when none
|
||
* is stored (published on the household rollup by
|
||
* custom_components/nestquest/sensor.py — ``timezone``). Only when the
|
||
* rollup carries none does Home Assistant's zone (or the browser's)
|
||
* apply. */
|
||
_timeZone() {
|
||
const e = this._state("sensor.nestquest_household_quests_due_today")?.attributes?.timezone;
|
||
return typeof e == "string" && e.trim() ? e.trim() : kt(this.hass);
|
||
}
|
||
_state(e) {
|
||
const n = this.hass?.states?.[e];
|
||
return n && typeof n == "object" ? n : null;
|
||
}
|
||
_childSlugs() {
|
||
if (!this._config)
|
||
return [];
|
||
const e = this._config.child_order;
|
||
return Array.isArray(e) ? e.filter(
|
||
(t) => typeof t == "string" && t.trim().length > 0
|
||
).map((t) => t.trim()) : this._discoveredChildSlugs();
|
||
}
|
||
/** Zero-config discovery (Feature 20): the ordered child roster the
|
||
* integration publishes on the household rollup
|
||
* (custom_components/nestquest/sensor.py — ``child_roster``, the
|
||
* snapshot's sort_order, then id), each entry carrying the slug the
|
||
* per-child entity ids are built from. Consulted only when the
|
||
* config has no child_order — explicit configuration wins. */
|
||
_discoveredChildSlugs() {
|
||
const t = this._state(
|
||
"sensor.nestquest_household_quests_due_today"
|
||
)?.attributes?.child_roster;
|
||
return Array.isArray(t) ? t.map((n) => Ct(n)).filter((n) => n.length > 0) : [];
|
||
}
|
||
_plates() {
|
||
return this._childSlugs().map((e) => this._plate(e));
|
||
}
|
||
_plate(e) {
|
||
const t = this._dueSensorResolution(e), n = this._state(`sensor.nestquest_${e}_quests_due_today`), s = this._state(
|
||
`sensor.nestquest_${e}_quests_completed_today`
|
||
), a = this._state(
|
||
`sensor.nestquest_${e}_completion_pct_today`
|
||
), r = this._state(
|
||
`binary_sensor.nestquest_${e}_present_today`
|
||
), l = n?.attributes ?? {}, o = ze(te(n?.state, 0)), p = ze(te(s?.state, 0)), u = a ? te(a.state, Number.NaN) : Number.NaN, c = Number.isFinite(u) ? Se(u) : o > 0 ? Se(p / o * 100) : 0;
|
||
let f = !0;
|
||
const h = l.present;
|
||
typeof h == "boolean" ? f = h : r && (f = String(r.state ?? "").trim().toLowerCase() === "on");
|
||
let m = "";
|
||
const _ = l.child_name;
|
||
if (typeof _ == "string" && _.trim())
|
||
m = _.trim();
|
||
else {
|
||
const X = r?.attributes?.child_name;
|
||
typeof X == "string" && X.trim() && (m = X.trim());
|
||
}
|
||
m || (m = At(e));
|
||
const v = zt(
|
||
r?.attributes?.next_present,
|
||
this._timeZone()
|
||
), U = v ? `Returns ${ee(v, this._timeZone())}` : null;
|
||
return {
|
||
slug: e,
|
||
name: m,
|
||
initial: (m.charAt(0) || "?").toUpperCase(),
|
||
present: t === null ? f : !1,
|
||
completed: p,
|
||
due: o,
|
||
pct: c,
|
||
returns: U,
|
||
unresolved: t
|
||
};
|
||
}
|
||
/** "missing" when the due sensor does not exist (integration not
|
||
* configured), "stale" when it answers unavailable/unknown (backend
|
||
* unreachable or the child is absent from the snapshot), null when
|
||
* it resolves. */
|
||
_dueSensorResolution(e) {
|
||
const t = this._state(`sensor.nestquest_${e}_quests_due_today`);
|
||
if (!t)
|
||
return "missing";
|
||
const n = String(t.state ?? "").trim().toLowerCase();
|
||
return !n || n === "unavailable" || n === "unknown" ? "stale" : null;
|
||
}
|
||
_boardNotice() {
|
||
const e = this._plates();
|
||
return e.length === 0 ? Ne : e.every((t) => t.unresolved !== null) ? e.some((t) => t.unresolved === "stale") ? jt : Ne : null;
|
||
}
|
||
_renderNotice(e) {
|
||
return d`
|
||
<div class="notice-wrap">
|
||
<div class="notice" role="status">
|
||
${e.icon}
|
||
<span class="notice-headline">${e.headline}</span>
|
||
<p class="notice-body">${e.body}</p>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
_renderPlate(e) {
|
||
return e.unresolved ? d`
|
||
<div class="plate unknown">
|
||
<span class="crest away">
|
||
<span class="crest-face">
|
||
<span class="initial">${e.initial}</span>
|
||
</span>
|
||
</span>
|
||
<span class="name">${e.name}</span>
|
||
<span class="pill away">
|
||
${Ht}
|
||
<span>Unknown</span>
|
||
</span>
|
||
<span class="progress-line">—</span>
|
||
<span class="bar"></span>
|
||
</div>
|
||
` : e.present ? d`
|
||
<button
|
||
class="plate"
|
||
type="button"
|
||
aria-label="Open ${e.name}'s Quest Log"
|
||
@click=${() => this._openQuestLog(e.slug)}
|
||
>
|
||
<span class="crest">
|
||
<span class="crest-face">
|
||
<span class="initial">${e.initial}</span>
|
||
</span>
|
||
</span>
|
||
<span class="name">${e.name}</span>
|
||
<span class="pill">
|
||
${It}
|
||
<span>Home today</span>
|
||
</span>
|
||
<span class="progress-line">
|
||
${e.completed} of ${e.due} quests claimed
|
||
</span>
|
||
<span class="bar">
|
||
<span class="fill" style="width: ${e.pct}%"></span>
|
||
</span>
|
||
</button>
|
||
` : d`
|
||
<div class="plate away">
|
||
<span class="crest away">
|
||
<span class="crest-face">
|
||
<span class="initial">${e.initial}</span>
|
||
</span>
|
||
</span>
|
||
<span class="name">${e.name}</span>
|
||
<span class="pill away">
|
||
${Pt}
|
||
<span>On travels</span>
|
||
</span>
|
||
<span class="progress-line">${e.returns ?? "Returns —"}</span>
|
||
<span class="bar"></span>
|
||
</div>
|
||
`;
|
||
}
|
||
_openQuestLog(e) {
|
||
const t = Ae(this._config?.quest_log_path);
|
||
t && (window.history.pushState(null, "", `${t.replace(/\/+$/, "")}/${e}`), window.dispatchEvent(new Event("location-changed")));
|
||
}
|
||
_dockWeather() {
|
||
const e = Ae(this._config?.weather_entity);
|
||
if (!e)
|
||
return null;
|
||
const t = this._state(e);
|
||
if (!t)
|
||
return null;
|
||
const n = String(t.state ?? "").trim();
|
||
if (!n || n === "unavailable" || n === "unknown")
|
||
return null;
|
||
const s = t.attributes ?? {};
|
||
let a = null, r = null;
|
||
const l = s.forecast;
|
||
if (Array.isArray(l) && l.length > 0) {
|
||
const o = l[0];
|
||
if (o && typeof o == "object") {
|
||
const p = o;
|
||
a = this._optionalNumber(p.temperature), r = this._optionalNumber(p.templow);
|
||
}
|
||
}
|
||
return {
|
||
condition: n,
|
||
temperature: this._optionalNumber(s.temperature),
|
||
high: a,
|
||
low: r
|
||
};
|
||
}
|
||
_optionalNumber(e) {
|
||
if (e == null || e === "")
|
||
return null;
|
||
const t = typeof e == "number" ? e : Number(e);
|
||
return Number.isFinite(t) ? t : null;
|
||
}
|
||
_renderDock() {
|
||
const e = this._dockWeather();
|
||
if (!e)
|
||
return d`
|
||
<div class="dock">
|
||
<span class="date">${ee(this._now, this._timeZone())}</span>
|
||
<span class="divider"></span>
|
||
<span class="clock">${$t(this._now, this._timeZone())}</span>
|
||
</div>
|
||
`;
|
||
const t = Tt(e.condition), n = Et(e.condition, t), s = e.temperature === null ? g : d`<span class="temp">${Math.round(e.temperature)}°</span>`, a = e.high === null || e.low === null ? null : `${Math.round(e.high)}° / ${Math.round(e.low)}°`;
|
||
return d`
|
||
<div class="dock">
|
||
${Dt}
|
||
${s}
|
||
<span class="divider"></span>
|
||
<span class="condition">
|
||
${a === null ? t : `${t} · ${a}`}
|
||
</span>
|
||
<span class="divider"></span>
|
||
<span class="condition">${n}</span>
|
||
</div>
|
||
`;
|
||
}
|
||
};
|
||
Q.properties = {
|
||
hass: { attribute: !1 },
|
||
_config: { state: !0 },
|
||
_now: { state: !0 }
|
||
}, Q.styles = [x(Xe), Bt];
|
||
let re = Q;
|
||
customElements.define("nestquest-party-board-card", re);
|
||
fe({
|
||
type: "nestquest-party-board-card",
|
||
name: "NestQuest Party Board",
|
||
description: "Kids' attract screen for present and away adventurers."
|
||
});
|
||
const Ft = { CHILD: 2 }, Vt = (i) => (...e) => ({ _$litDirective$: i, values: e });
|
||
let Zt = class {
|
||
constructor(e) {
|
||
}
|
||
get _$AU() {
|
||
return this._$AM._$AU;
|
||
}
|
||
_$AT(e, t, n) {
|
||
this._$Ct = e, this._$AM = t, this._$Ci = n;
|
||
}
|
||
_$AS(e, t) {
|
||
return this.update(e, t);
|
||
}
|
||
update(e, t) {
|
||
return this.render(...t);
|
||
}
|
||
};
|
||
const { I: Qt } = yt, Le = (i) => i, Oe = () => document.createComment(""), O = (i, e, t) => {
|
||
const n = i._$AA.parentNode, s = e === void 0 ? i._$AB : e._$AA;
|
||
if (t === void 0) {
|
||
const a = n.insertBefore(Oe(), s), r = n.insertBefore(Oe(), s);
|
||
t = new Qt(a, r, i, i.options);
|
||
} else {
|
||
const a = t._$AB.nextSibling, r = t._$AM, l = r !== i;
|
||
if (l) {
|
||
let o;
|
||
t._$AQ?.(i), t._$AM = i, t._$AP !== void 0 && (o = i._$AU) !== r._$AU && t._$AP(o);
|
||
}
|
||
if (a !== s || l) {
|
||
let o = t._$AA;
|
||
for (; o !== a; ) {
|
||
const p = Le(o).nextSibling;
|
||
Le(n).insertBefore(o, s), o = p;
|
||
}
|
||
}
|
||
}
|
||
return t;
|
||
}, q = (i, e, t = i) => (i._$AI(e, t), i), Wt = {}, Gt = (i, e = Wt) => i._$AH = e, Kt = (i) => i._$AH, ne = (i) => {
|
||
i._$AR(), i._$AA.remove();
|
||
};
|
||
const Be = (i, e, t) => {
|
||
const n = /* @__PURE__ */ new Map();
|
||
for (let s = e; s <= t; s++) n.set(i[s], s);
|
||
return n;
|
||
}, Ie = Vt(class extends Zt {
|
||
constructor(i) {
|
||
if (super(i), i.type !== Ft.CHILD) throw Error("repeat() can only be used in text expressions");
|
||
}
|
||
dt(i, e, t) {
|
||
let n;
|
||
t === void 0 ? t = e : e !== void 0 && (n = e);
|
||
const s = [], a = [];
|
||
let r = 0;
|
||
for (const l of i) s[r] = n ? n(l, r) : r, a[r] = t(l, r), r++;
|
||
return { values: a, keys: s };
|
||
}
|
||
render(i, e, t) {
|
||
return this.dt(i, e, t).values;
|
||
}
|
||
update(i, [e, t, n]) {
|
||
const s = Kt(i), { values: a, keys: r } = this.dt(e, t, n);
|
||
if (!Array.isArray(s)) return this.ut = r, a;
|
||
const l = this.ut ??= [], o = [];
|
||
let p, u, c = 0, f = s.length - 1, h = 0, m = a.length - 1;
|
||
for (; c <= f && h <= m; ) if (s[c] === null) c++;
|
||
else if (s[f] === null) f--;
|
||
else if (l[c] === r[h]) o[h] = q(s[c], a[h]), c++, h++;
|
||
else if (l[f] === r[m]) o[m] = q(s[f], a[m]), f--, m--;
|
||
else if (l[c] === r[m]) o[m] = q(s[c], a[m]), O(i, o[m + 1], s[c]), c++, m--;
|
||
else if (l[f] === r[h]) o[h] = q(s[f], a[h]), O(i, s[c], s[f]), f--, h++;
|
||
else if (p === void 0 && (p = Be(r, h, m), u = Be(l, c, f)), p.has(l[c])) if (p.has(l[f])) {
|
||
const _ = u.get(r[h]), v = _ !== void 0 ? s[_] : null;
|
||
if (v === null) {
|
||
const U = O(i, s[c]);
|
||
q(U, a[h]), o[h] = U;
|
||
} else o[h] = q(v, a[h]), O(i, s[c], v), s[_] = null;
|
||
h++;
|
||
} else ne(s[f]), f--;
|
||
else ne(s[c]), c++;
|
||
for (; h <= m; ) {
|
||
const _ = O(i, o[m + 1]);
|
||
q(_, a[h]), o[h++] = _;
|
||
}
|
||
for (; c <= f; ) {
|
||
const _ = s[c++];
|
||
_ !== null && ne(_);
|
||
}
|
||
return this.ut = r, Gt(i, o), S;
|
||
}
|
||
}), Jt = [
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:bed",
|
||
name: "bed",
|
||
label: "Bed",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M2 4v16",
|
||
"M2 8h18a2 2 0 0 1 2 2v10",
|
||
"M2 17h20",
|
||
"M6 8v9"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:bath",
|
||
name: "bath",
|
||
label: "Bath",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M10 4 8 6",
|
||
"M17 19v2",
|
||
"M2 12h20",
|
||
"M7 19v2",
|
||
"M9 5 7.621 3.621A2.121 2.121 0 0 0 4 5v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:shower-head",
|
||
name: "shower-head",
|
||
label: "Shower",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"m4 4 2.5 2.5",
|
||
"M13.5 6.5a4.95 4.95 0 0 0-7 7",
|
||
"M15 5 5 15",
|
||
"M14 17v.01",
|
||
"M10 16v.01",
|
||
"M13 13v.01",
|
||
"M16 10v.01",
|
||
"M11 20v.01",
|
||
"M17 14v.01",
|
||
"M20 11v.01"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:toilet",
|
||
name: "toilet",
|
||
label: "Toilet",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M7 12h13a1 1 0 0 1 1 1 5 5 0 0 1-5 5h-.598a.5.5 0 0 0-.424.765l1.544 2.47a.5.5 0 0 1-.424.765H5.402a.5.5 0 0 1-.424-.765L7 18",
|
||
"M8 18a5 5 0 0 1-5-5V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:brush",
|
||
name: "brush",
|
||
label: "Brush",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"m11 10 3 3",
|
||
"M6.5 21A3.5 3.5 0 1 0 3 17.5a2.62 2.62 0 0 1-.708 1.792A1 1 0 0 0 3 21z",
|
||
"M9.969 17.031 21.378 5.624a1 1 0 0 0-3.002-3.002L6.967 14.031"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:smile",
|
||
name: "smile",
|
||
label: "Smile",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M15 10V9",
|
||
"M16.472 15a6 6 0 01-8.943 0",
|
||
"M9 10V9",
|
||
"M2 12a10 10 0 1 0 20 0a10 10 0 1 0 -20 0"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:shirt",
|
||
name: "shirt",
|
||
label: "Clothes",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M20.38 3.46 16 2a4 4 0 0 1-8 0L3.62 3.46a2 2 0 0 0-1.34 2.23l.58 3.47a1 1 0 0 0 .99.84H6v10c0 1.1.9 2 2 2h8a2 2 0 0 0 2-2V10h2.15a1 1 0 0 0 .99-.84l.58-3.47a2 2 0 0 0-1.34-2.23z"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:washing-machine",
|
||
name: "washing-machine",
|
||
label: "Laundry",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M3 6h3",
|
||
"M17 6h.01",
|
||
"M5 2h14a2 2 0 0 1 2 2v16a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-16a2 2 0 0 1 2 -2z",
|
||
"M7 13a5 5 0 1 0 10 0a5 5 0 1 0 -10 0",
|
||
"M12 18a2.5 2.5 0 0 0 0-5 2.5 2.5 0 0 1 0-5"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:utensils",
|
||
name: "utensils",
|
||
label: "Meal",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2",
|
||
"M7 2v20",
|
||
"M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:cooking-pot",
|
||
name: "cooking-pot",
|
||
label: "Cooking",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M2 12h20",
|
||
"M20 12v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8",
|
||
"m4 8 16-4",
|
||
"m8.86 6.78-.45-1.81a2 2 0 0 1 1.45-2.43l1.94-.48a2 2 0 0 1 2.43 1.46l.45 1.8"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:apple",
|
||
name: "apple",
|
||
label: "Snack",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M12 6.528V3a1 1 0 0 1 1-1h0",
|
||
"M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:brush-cleaning",
|
||
name: "brush-cleaning",
|
||
label: "Sweep",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"m16 22-1-4",
|
||
"M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1",
|
||
"M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233z",
|
||
"m8 22 1-4"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:spray-can",
|
||
name: "spray-can",
|
||
label: "Clean",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M3 3h.01",
|
||
"M7 5h.01",
|
||
"M11 7h.01",
|
||
"M3 7h.01",
|
||
"M7 9h.01",
|
||
"M3 11h.01",
|
||
"M15 5h4v4h-4z",
|
||
"m19 9 2 2v10c0 .6-.4 1-1 1h-6c-.6 0-1-.4-1-1V11l2-2",
|
||
"m13 14 8-2",
|
||
"m13 19 8-2"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:trash-2",
|
||
name: "trash-2",
|
||
label: "Bins",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M10 11v6",
|
||
"M14 11v6",
|
||
"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",
|
||
"M3 6h18",
|
||
"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:recycle",
|
||
name: "recycle",
|
||
label: "Recycling",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M7 19H4.815a1.83 1.83 0 0 1-1.57-.881 1.785 1.785 0 0 1-.004-1.784L7.196 9.5",
|
||
"M11 19h8.203a1.83 1.83 0 0 0 1.556-.89 1.784 1.784 0 0 0 0-1.775l-1.226-2.12",
|
||
"m14 16-3 3 3 3",
|
||
"M8.293 13.596 7.196 9.5 3.1 10.598",
|
||
"m9.344 5.811 1.093-1.892A1.83 1.83 0 0 1 11.985 3a1.784 1.784 0 0 1 1.546.888l3.943 6.843",
|
||
"m13.378 9.633 4.096 1.098 1.097-4.096"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:sofa",
|
||
name: "sofa",
|
||
label: "Tidy",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M20 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v3",
|
||
"M2 16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5a2 2 0 0 0-4 0v1.5a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5V11a2 2 0 0 0-4 0z",
|
||
"M4 18v2",
|
||
"M20 18v2",
|
||
"M12 4v9"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:house",
|
||
name: "house",
|
||
label: "Home",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",
|
||
"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:backpack",
|
||
name: "backpack",
|
||
label: "School bag",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M4 10a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z",
|
||
"M8 10h8",
|
||
"M8 18h8",
|
||
"M8 22v-6a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v6",
|
||
"M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:book-open",
|
||
name: "book-open",
|
||
label: "Reading",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M12 5v16",
|
||
"M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:pencil",
|
||
name: "pencil",
|
||
label: "Homework",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
|
||
"m15 5 4 4"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:music",
|
||
name: "music",
|
||
label: "Music",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M9 18V5l12-2v13",
|
||
"M3 18a3 3 0 1 0 6 0a3 3 0 1 0 -6 0",
|
||
"M15 16a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:dog",
|
||
name: "dog",
|
||
label: "Dog",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M11.25 16.25h1.5L12 17z",
|
||
"M16 14v.5",
|
||
"M4.42 11.247A13.152 13.152 0 0 0 4 14.556C4 18.728 7.582 21 12 21s8-2.272 8-6.444a11.702 11.702 0 0 0-.493-3.309",
|
||
"M8 14v.5",
|
||
"M8.5 8.5c-.384 1.05-1.083 2.028-2.344 2.5-1.931.722-3.576-.297-3.656-1-.113-.994 1.177-6.53 4-7 1.923-.321 3.651.845 3.651 2.235A7.497 7.497 0 0 1 14 5.277c0-1.39 1.844-2.598 3.767-2.277 2.823.47 4.113 6.006 4 7-.08.703-1.725 1.722-3.656 1-1.261-.472-1.855-1.45-2.239-2.5"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:cat",
|
||
name: "cat",
|
||
label: "Cat",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M12 5c.67 0 1.35.09 2 .26 1.78-2 5.03-2.84 6.42-2.26 1.4.58-.42 7-.42 7 .57 1.07 1 2.24 1 3.44C21 17.9 16.97 21 12 21s-9-3-9-7.56c0-1.25.5-2.4 1-3.44 0 0-1.89-6.42-.5-7 1.39-.58 4.72.23 6.5 2.23A9.04 9.04 0 0 1 12 5Z",
|
||
"M8 14v.5",
|
||
"M16 14v.5",
|
||
"M11.25 16.25h1.5L12 17l-.75-.75Z"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:fish",
|
||
name: "fish",
|
||
label: "Fish",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M6.5 12c.94-3.46 4.94-6 8.5-6 3.56 0 6.06 2.54 7 6-.94 3.47-3.44 6-7 6s-7.56-2.53-8.5-6Z",
|
||
"M18 12v.5",
|
||
"M16 17.93a9.77 9.77 0 0 1 0-11.86",
|
||
"M7 10.67C7 8 5.58 5.97 2.73 5.5c-1 1.5-1 5 .23 6.5-1.24 1.5-1.24 5-.23 6.5C5.58 18.03 7 16 7 13.33",
|
||
"M10.46 7.26C10.2 5.88 9.17 4.24 8 3h5.8a2 2 0 0 1 1.98 1.67l.23 1.4",
|
||
"m16.01 17.93-.23 1.4A2 2 0 0 1 13.8 21H9.5a5.96 5.96 0 0 0 1.49-3.98"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:sprout",
|
||
name: "sprout",
|
||
label: "Plants",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M14 9.536V7a4 4 0 0 1 4-4h1.5a.5.5 0 0 1 .5.5V5a4 4 0 0 1-4 4 4 4 0 0 0-4 4c0 2 1 3 1 5a5 5 0 0 1-1 3",
|
||
"M4 9a5 5 0 0 1 8 4 5 5 0 0 1-8-4",
|
||
"M5 21h14"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:droplets",
|
||
name: "droplets",
|
||
label: "Water",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M7 16.3c2.2 0 4-1.83 4-4.05 0-1.16-.57-2.26-1.71-3.19S7.29 6.75 7 5.3c-.29 1.45-1.14 2.84-2.29 3.76S3 11.1 3 12.25c0 2.22 1.8 4.05 4 4.05z",
|
||
"M12.56 6.6A10.97 10.97 0 0 0 14 3.02c.5 2.5 2 4.9 4 6.5s3 3.5 3 5.5a6.98 6.98 0 0 1-11.91 4.97"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:bike",
|
||
name: "bike",
|
||
label: "Bike",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M15 17.5a3.5 3.5 0 1 0 7 0a3.5 3.5 0 1 0 -7 0",
|
||
"M2 17.5a3.5 3.5 0 1 0 7 0a3.5 3.5 0 1 0 -7 0",
|
||
"M14 5a1 1 0 1 0 2 0a1 1 0 1 0 -2 0",
|
||
"M12 17.5V14l-3-3 4-3 2 3h2"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:volleyball",
|
||
name: "volleyball",
|
||
label: "Sport",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M11 7a16 16 20 0 1 10.98 4.362",
|
||
"M12 12a13 13 0 0 1-8.66 5",
|
||
"M16.83 13.634a16 16 0 0 1-9.267 7.328",
|
||
"M20.66 17A13 13 0 0 0 12 12a13 13 0 0 1 0-10",
|
||
"M8.17 15.366a16 16 0 0 1-1.713-11.69",
|
||
"M2 12a10 10 0 1 0 20 0a10 10 0 1 0 -20 0"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:gamepad-2",
|
||
name: "gamepad-2",
|
||
label: "Games",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M6 11L10 11",
|
||
"M8 9L8 13",
|
||
"M15 12L15.01 12",
|
||
"M18 10L18.01 10",
|
||
"M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:star",
|
||
name: "star",
|
||
label: "Star",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:heart",
|
||
name: "heart",
|
||
label: "Heart",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:sun",
|
||
name: "sun",
|
||
label: "Morning",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M8 12a4 4 0 1 0 8 0a4 4 0 1 0 -8 0",
|
||
"M12 2v2",
|
||
"M12 20v2",
|
||
"m4.93 4.93 1.41 1.41",
|
||
"m17.66 17.66 1.41 1.41",
|
||
"M2 12h2",
|
||
"M20 12h2",
|
||
"m6.34 17.66-1.41 1.41",
|
||
"m19.07 4.93-1.41 1.41"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:moon",
|
||
name: "moon",
|
||
label: "Bedtime",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:clock",
|
||
name: "clock",
|
||
label: "Clock",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M2 12a10 10 0 1 0 20 0a10 10 0 1 0 -20 0",
|
||
"M12 6v6l4 2"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:calendar",
|
||
name: "calendar",
|
||
label: "Calendar",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M8 2v3",
|
||
"M16 2v3",
|
||
"M5 3h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2z",
|
||
"M3 9h18"
|
||
]
|
||
},
|
||
{
|
||
kind: "lucide",
|
||
key: "lucide:list-checks",
|
||
name: "list-checks",
|
||
label: "Checklist",
|
||
viewBox: "0 0 24 24",
|
||
paths: [
|
||
"M13 5h8",
|
||
"M13 12h8",
|
||
"M13 19h8",
|
||
"m3 17 2 2 4-4",
|
||
"m3 7 2 2 4-4"
|
||
]
|
||
}
|
||
], Xt = [
|
||
{
|
||
kind: "fa",
|
||
key: "fa:broom",
|
||
name: "broom",
|
||
label: "Sweep",
|
||
viewBox: "0 0 576 512",
|
||
paths: [
|
||
"M566.6 54.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192-34.7-34.7c-4.2-4.2-10-6.6-16-6.6-12.5 0-22.6 10.1-22.6 22.6l0 29.1 108.3 108.3 29.1 0c12.5 0 22.6-10.1 22.6-22.6 0-6-2.4-11.8-6.6-16l-34.7-34.7 192-192zM341.1 353.4L222.6 234.9c-42.7-3.7-85.2 11.7-115.8 42.3l-8 8c-22.3 22.3-34.8 52.5-34.8 84 0 6.8 7.1 11.2 13.2 8.2l51.1-25.5c5-2.5 9.5 4.1 5.4 7.9L7.3 473.4C2.7 477.6 0 483.6 0 489.9 0 502.1 9.9 512 22.1 512l173.3 0c38.8 0 75.9-15.4 103.4-42.8 30.6-30.6 45.9-73.1 42.3-115.8z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:spray-can-sparkles",
|
||
name: "spray-can-sparkles",
|
||
label: "Clean",
|
||
viewBox: "0 0 576 512",
|
||
paths: [
|
||
"M160 32l0 80 128 0 0-80c0-17.7-14.3-32-32-32L192 0c-17.7 0-32 14.3-32 32zm0 128c-53 0-96 43-96 96l0 208c0 26.5 21.5 48 48 48l224 0c26.5 0 48-21.5 48-48l0-208c0-53-43-96-96-96l-128 0zm64 96a80 80 0 1 1 0 160 80 80 0 1 1 0-160zM448 48c0-1.4-1-3-2.2-3.6L416 32 403.6 2.2C403 1 401.4 0 400 0s-3 1-3.6 2.2L384 32 354.2 44.4c-1.2 .6-2.2 2.2-2.2 3.6 0 1.4 1 3 2.2 3.6L384 64 396.4 93.8C397 95 398.6 96 400 96s3-1 3.6-2.2L416 64 445.8 51.6C447 51 448 49.4 448 48zm76.4 45.8C525 95 526.6 96 528 96s3-1 3.6-2.2L544 64 573.8 51.6c1.2-.6 2.2-2.2 2.2-3.6 0-1.4-1-3-2.2-3.6L544 32 531.6 2.2C531 1 529.4 0 528 0s-3 1-3.6 2.2L512 32 482.2 44.4c-1.2 .6-2.2 2.2-2.2 3.6 0 1.4 1 3 2.2 3.6L512 64 524.4 93.8zm7.2 100.4c-.6-1.2-2.2-2.2-3.6-2.2s-3 1-3.6 2.2L512 224 482.2 236.4c-1.2 .6-2.2 2.2-2.2 3.6 0 1.4 1 3 2.2 3.6L512 256 524.4 285.8c.6 1.2 2.2 2.2 3.6 2.2s3-1 3.6-2.2L544 256 573.8 243.6c1.2-.6 2.2-2.2 2.2-3.6 0-1.4-1-3-2.2-3.6L544 224 531.6 194.2zM512 144c0-1.4-1-3-2.2-3.6L480 128 467.6 98.2C467 97 465.4 96 464 96s-3 1-3.6 2.2L448 128 418.2 140.4c-1.2 .6-2.2 2.2-2.2 3.6 0 1.4 1 3 2.2 3.6L448 160 460.4 189.8c.6 1.2 2.2 2.2 3.6 2.2s3-1 3.6-2.2L480 160 509.8 147.6c1.2-.6 2.2-2.2 2.2-3.6z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:bucket",
|
||
name: "bucket",
|
||
label: "Mop",
|
||
viewBox: "0 0 448 512",
|
||
paths: [
|
||
"M443.7 208c2.7 4.7 4.3 10.2 4.3 16 0 17.7-14.3 32-32 32l-5.1 0-22.4 213c-2.6 24.4-23.2 43-47.8 43l-233.6 0c-24.6 0-45.2-18.5-47.8-43L37.1 256 32 256c-17.7 0-32-14.3-32-32 0-5.8 1.6-11.3 4.3-16l439.4 0zM224-16c79.5 0 144 64.5 144 144l0 32-48 0 0-32c0-53-43-96-96-96s-96 43-96 96l0 32-48 0 0-32C80 48.5 144.5-16 224-16z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:soap",
|
||
name: "soap",
|
||
label: "Wash hands",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M208-32a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM320 96a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM352 0a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM96 160l112 0c0 23.8 7.4 45.9 20.1 64L160 224c-53 0-96 43-96 96s43 96 96 96l192 0c53 0 96-43 96-96 0-35.1-18.9-65.9-47-82.6 19-19.8 30.7-46.6 31-76.1 45.4 7.6 80 47.1 80 94.7l0 128c0 53-43 96-96 96L96 480c-53 0-96-43-96-96L0 256c0-53 43-96 96-96zm64 112l192 0c26.5 0 48 21.5 48 48s-21.5 48-48 48l-192 0c-26.5 0-48-21.5-48-48s21.5-48 48-48z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:sink",
|
||
name: "sink",
|
||
label: "Dishes",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M288 96c0-17.7 14.3-32 32-32s32 14.3 32 32 14.3 32 32 32 32-14.3 32-32c0-53-43-96-96-96s-96 43-96 96l0 192-64 0 0-40c0-30.9-25.1-56-56-56l-48 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l48 0c4.4 0 8 3.6 8 8l0 40-80 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l0 64c0 53 43 96 96 96l256 0c53 0 96-43 96-96l0-64c17.7 0 32-14.3 32-32s-14.3-32-32-32l-80 0 0-40c0-4.4 3.6-8 8-8l56 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-56 0c-30.9 0-56 25.1-56 56l0 40-64 0 0-192z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:jug-detergent",
|
||
name: "jug-detergent",
|
||
label: "Laundry",
|
||
viewBox: "0 0 384 512",
|
||
paths: [
|
||
"M96 24c0-13.3 10.7-24 24-24l80 0c13.3 0 24 10.7 24 24l0 24 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L88 96C74.7 96 64 85.3 64 72S74.7 48 88 48l8 0 0-24zM0 256c0-70.7 57.3-128 128-128l128 0c70.7 0 128 57.3 128 128l0 192c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 256zm256 0l0 96c0 17.7 14.3 32 32 32s32-14.3 32-32l0-96c0-17.7-14.3-32-32-32s-32 14.3-32 32z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:socks",
|
||
name: "socks",
|
||
label: "Socks",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M252.8 0L176 0c-26.5 0-48 21.5-48 48l0 16 112 0 0-16c0-17.5 4.7-33.9 12.8-48zM128 112l0 128c0 20.1-9.5 39.1-25.6 51.2l-64 48c-24.2 18.1-38.4 46.6-38.4 76.8 0 53 43 96 96 96 15.4 0 30.5-3.7 44-10.7-17.6-23.9-28-53.4-28-85.3 0-45.3 21.3-88 57.6-115.2l64-48c4-3 6.4-7.8 6.4-12.8l0-128-112 0zm160 0l0 128c0 20.1-9.5 39.1-25.6 51.2l-64 48c-24.2 18.1-38.4 46.6-38.4 76.8 0 53 43 96 96 96 20.8 0 41-6.7 57.6-19.2l115.2-86.4C461 382.2 480 344.3 480 304l0-192-192 0zM480 64l0-16c0-26.5-21.5-48-48-48L336 0c-26.5 0-48 21.5-48 48l0 16 192 0z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:shirt",
|
||
name: "shirt",
|
||
label: "Clothes",
|
||
viewBox: "0 0 640 512",
|
||
paths: [
|
||
"M320.2 112c44.2 0 80-35.8 80-80l53.5 0c17 0 33.3 6.7 45.3 18.7L617.6 169.4c12.5 12.5 12.5 32.8 0 45.3l-50.7 50.7c-12.5 12.5-32.8 12.5-45.3 0l-41.4-41.4 0 224c0 35.3-28.7 64-64 64l-192 0c-35.3 0-64-28.7-64-64l0-224-41.4 41.4c-12.5 12.5-32.8 12.5-45.3 0L22.9 214.6c-12.5-12.5-12.5-32.8 0-45.3L141.5 50.7c12-12 28.3-18.7 45.3-18.7l53.5 0c0 44.2 35.8 80 80 80z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:bed",
|
||
name: "bed",
|
||
label: "Bed",
|
||
viewBox: "0 0 576 512",
|
||
paths: [
|
||
"M32 32c17.7 0 32 14.3 32 32l0 224 224 0 0-128c0-17.7 14.3-32 32-32l160 0c53 0 96 43 96 96l0 224c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-64-448 0 0 64c0 17.7-14.3 32-32 32S0 465.7 0 448L0 64C0 46.3 14.3 32 32 32zm80 160a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:couch",
|
||
name: "couch",
|
||
label: "Tidy",
|
||
viewBox: "0 0 640 512",
|
||
paths: [
|
||
"M144 272C144 224.7 109.8 185.4 64.8 177.5 72 113.6 126.2 64 192 64l256 0c65.8 0 120 49.6 127.2 113.5-45 8-79.2 47.2-79.2 94.5l0 32-352 0 0-32zM0 384L0 272c0-26.5 21.5-48 48-48s48 21.5 48 48l0 80 448 0 0-80c0-26.5 21.5-48 48-48s48 21.5 48 48l0 112c0 35.3-28.7 64-64 64L64 448c-35.3 0-64-28.7-64-64z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:bath",
|
||
name: "bath",
|
||
label: "Bath",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M96 77.3c0-7.3 5.9-13.3 13.3-13.3 3.5 0 6.9 1.4 9.4 3.9l14.9 14.9c-3.6 9.1-5.5 18.9-5.5 29.2 0 19.9 7.2 38 19.2 52-5.3 9.2-4 21.1 3.8 29 9.4 9.4 24.6 9.4 33.9 0L289 89c9.4-9.4 9.4-24.6 0-33.9-7.8-7.9-19.8-9.1-29-3.8-14-12-32.1-19.2-52-19.2-10.3 0-20.2 2-29.2 5.5L163.9 22.6C149.4 8.1 129.7 0 109.3 0 66.6 0 32 34.6 32 77.3L32 256c-17.7 0-32 14.3-32 32s14.3 32 32 32l0 48c0 28.4 12.4 54 32 71.6L64 480c0 17.7 14.3 32 32 32s32-14.3 32-32l0-16 256 0 0 16c0 17.7 14.3 32 32 32s32-14.3 32-32l0-40.4c19.6-17.6 32-43.1 32-71.6l0-48c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 256 96 77.3z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:tooth",
|
||
name: "tooth",
|
||
label: "Teeth",
|
||
viewBox: "0 0 448 512",
|
||
paths: [
|
||
"M145 5.7L224 32 303 5.7C314.3 1.9 326 0 337.9 0 398.7 0 448 49.3 448 110.1l0 68.5c0 29.4-9.5 58.1-27.2 81.6l-1.1 1.5c-12.9 17.2-21.3 37.4-24.3 58.7L373.7 471.9c-3.3 23-23 40.1-46.2 40.1-22.8 0-42.3-16.5-46-39L261.3 351.6c-3-18.2-18.8-31.6-37.3-31.6s-34.2 13.4-37.3 31.6L166.5 473c-3.8 22.5-23.2 39-46 39-23.2 0-42.9-17.1-46.2-40.1L52.6 320.5c-3-21.3-11.4-41.5-24.3-58.7l-1.1-1.5C9.5 236.7 0 208.1 0 178.7l0-68.5C0 49.3 49.3 0 110.1 0 122 0 133.7 1.9 145 5.7z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:utensils",
|
||
name: "utensils",
|
||
label: "Meal",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M63.9 14.4C63.1 6.2 56.2 0 48 0s-15.1 6.2-16 14.3L17.9 149.7c-1.3 6-1.9 12.1-1.9 18.2 0 45.9 35.1 83.6 80 87.7L96 480c0 17.7 14.3 32 32 32s32-14.3 32-32l0-224.4c44.9-4.1 80-41.8 80-87.7 0-6.1-.6-12.2-1.9-18.2L223.9 14.3C223.1 6.2 216.2 0 208 0s-15.1 6.2-15.9 14.4L178.5 149.9c-.6 5.7-5.4 10.1-11.1 10.1-5.8 0-10.6-4.4-11.2-10.2L143.9 14.6C143.2 6.3 136.3 0 128 0s-15.2 6.3-15.9 14.6L99.8 149.8c-.5 5.8-5.4 10.2-11.2 10.2-5.8 0-10.6-4.4-11.1-10.1L63.9 14.4zM448 0C432 0 320 32 320 176l0 112c0 35.3 28.7 64 64 64l32 0 0 128c0 17.7 14.3 32 32 32s32-14.3 32-32l0-448c0-17.7-14.3-32-32-32z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:bowl-food",
|
||
name: "bowl-food",
|
||
label: "Set the table",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M0 176c0-35.3 28.7-64 64-64 .5 0 1.1 0 1.6 0 7.4-36.5 39.7-64 78.4-64 15 0 29 4.1 40.9 11.2 13.3-25.7 40.1-43.2 71.1-43.2s57.8 17.6 71.1 43.2c12-7.1 26-11.2 40.9-11.2 38.7 0 71 27.5 78.4 64 .5 0 1.1 0 1.6 0 35.3 0 64 28.7 64 64 0 11.7-3.1 22.6-8.6 32L8.6 208C3.1 198.6 0 187.7 0 176zM0 283.4C0 268.3 12.3 256 27.4 256l457.1 0c15.1 0 27.4 12.3 27.4 27.4 0 70.5-44.4 130.7-106.7 154.1L403.5 452c-2 16-15.6 28-31.8 28l-231.5 0c-16.1 0-29.8-12-31.8-28l-1.8-14.4C44.4 414.1 0 353.9 0 283.4z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:basket-shopping",
|
||
name: "basket-shopping",
|
||
label: "Groceries",
|
||
viewBox: "0 0 576 512",
|
||
paths: [
|
||
"M288 0c6.6 0 12.9 2.7 17.4 7.5l144 152 .5 .5 78.1 0c17.7 0 32 14.3 32 32 0 14.5-9.6 26.7-22.8 30.7L491.1 429.9c-6.5 29.3-32.5 50.1-62.5 50.1l-281.3 0c-30 0-56-20.8-62.5-50.1l-46-207.2c-13.2-3.9-22.8-16.2-22.8-30.7 0-17.7 14.3-32 32-32l78.1 0 .5-.5 144-152C275.1 2.7 281.4 0 288 0zm0 58.9L192.2 160 383.8 160 288 58.9zM208 264c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112zm80-24c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm128 24c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:trash-can",
|
||
name: "trash-can",
|
||
label: "Bins",
|
||
viewBox: "0 0 448 512",
|
||
paths: [
|
||
"M136.7 5.9C141.1-7.2 153.3-16 167.1-16l113.9 0c13.8 0 26 8.8 30.4 21.9L320 32 416 32c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 96C14.3 96 0 81.7 0 64S14.3 32 32 32l96 0 8.7-26.1zM32 144l384 0 0 304c0 35.3-28.7 64-64 64L96 512c-35.3 0-64-28.7-64-64l0-304zm88 64c-13.3 0-24 10.7-24 24l0 192c0 13.3 10.7 24 24 24s24-10.7 24-24l0-192c0-13.3-10.7-24-24-24zm104 0c-13.3 0-24 10.7-24 24l0 192c0 13.3 10.7 24 24 24s24-10.7 24-24l0-192c0-13.3-10.7-24-24-24zm104 0c-13.3 0-24 10.7-24 24l0 192c0 13.3 10.7 24 24 24s24-10.7 24-24l0-192c0-13.3-10.7-24-24-24z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:recycle",
|
||
name: "recycle",
|
||
label: "Recycling",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M152.3 60C198.5-20 314-20 360.2 60l37.3 64.6 27.7-16c8.4-4.9 18.9-4.2 26.6 1.7s11.1 15.9 8.6 25.3L436.9 223c-3.4 12.8-16.6 20.4-29.4 17l-87.4-23.4c-9.4-2.5-16.3-10.4-17.6-20s3.4-19.1 11.8-23.9l27.7-16-37.3-64.6c-21.6-37.3-75.4-37.3-97 0l-5.3 9.1c-8.8 15.3-28.4 20.5-43.7 11.7S138.2 84.5 147 69.1l5.3-9.1zM449.7 279.1c15.3-8.8 34.9-3.6 43.7 11.7l5.3 9.1c46.2 80-11.5 180-103.9 180l-74.6 0 0 32c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-64-64c-9.4-9.4-9.4-24.6 0-33.9l64-64c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 32 74.6 0c43.1 0 70.1-46.7 48.5-84l-5.3-9.1c-8.8-15.3-3.6-34.9 11.7-43.7zM51 235.4l-27.7-16c-8.4-4.9-13.1-14.3-11.8-23.9s8.2-17.5 17.6-20L116.5 152c12.8-3.4 26 4.2 29.4 17l23.4 87.4c2.5 9.4-.9 19.3-8.6 25.3s-18.2 6.6-26.6 1.7l-27.7-16-37.3 64.6c-21.6 37.3 5.4 84 48.5 84l10.6 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-10.6 0C25.3 480-32.4 380 13.8 300L51 235.4z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:dog",
|
||
name: "dog",
|
||
label: "Dog",
|
||
viewBox: "0 0 576 512",
|
||
paths: [
|
||
"M32 112c16.6 0 30.2 12.6 31.8 28.7l.3 6.6C65.8 163.4 79.4 176 96 176l179.1 0 140.9 60.4 0 243.6c0 17.7-14.3 32-32 32l-32 0c-17.7 0-32-14.3-32-32l0-131.3C296 361 268.8 368 240 368s-56-7-80-19.3L160 480c0 17.7-14.3 32-32 32l-32 0c-17.7 0-32-14.3-32-32l0-245.6c-37.3-13.2-64-48.6-64-90.4 0-17.7 14.3-32 32-32zM355.8-32c7.7 0 14.9 3.6 19.6 9.8L392 0 444.1 0c12.7 0 24.9 5.1 33.9 14.1L496 32 552 32c13.3 0 24 10.7 24 24l0 24c0 44.2-35.8 80-80 80l-64 0-7 28-124.7-53.4 31.6-147.2C334.3-23.9 344.2-32 355.8-32zM448 44a20 20 0 1 0 0 40 20 20 0 1 0 0-40z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:cat",
|
||
name: "cat",
|
||
label: "Cat",
|
||
viewBox: "0 0 576 512",
|
||
paths: [
|
||
"M64 96c53 0 96 43 96 96l0 85.8c29.7-44.7 77.8-76.2 133.4-84 25.6 60 85.2 102.1 154.6 102.1 10.9 0 21.6-1.1 32-3.1L480 480c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-140.8-136 108.8 56 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-144 0c-53 0-96-43-96-96l0-224c0-16.6-12.6-30.2-28.7-31.8l-6.6-.3C44.6 158.2 32 144.6 32 128 32 110.3 46.3 96 64 96zM533.8 3.2C544.2-5.5 560 1.9 560 15.5L560 128c0 61.9-50.1 112-112 112S336 189.9 336 128l0-112.5c0-13.6 15.8-21 26.2-12.3L416 48 480 48 533.8 3.2zM400 108a20 20 0 1 0 0 40 20 20 0 1 0 0-40zm96 0a20 20 0 1 0 0 40 20 20 0 1 0 0-40z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:paw",
|
||
name: "paw",
|
||
label: "Pets",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M234.5 92.9c14.3 42.9-.3 86.2-32.6 96.8s-70.1-15.6-84.4-58.5 .3-86.2 32.6-96.8 70.1 15.6 84.4 58.5zM100.4 198.6c18.9 32.4 14.3 70.1-10.2 84.1s-59.7-.9-78.5-33.3-14.3-70.1 10.2-84.1 59.7 .9 78.5 33.3zM69.2 401.2C121.6 259.9 214.7 224 256 224s134.4 35.9 186.8 177.2c3.6 9.7 5.2 20.1 5.2 30.5l0 1.6c0 25.8-20.9 46.7-46.7 46.7-11.5 0-22.9-1.4-34-4.2l-88-22c-15.3-3.8-31.3-3.8-46.6 0l-88 22c-11.1 2.8-22.5 4.2-34 4.2-25.8 0-46.7-20.9-46.7-46.7l0-1.6c0-10.4 1.6-20.8 5.2-30.5zM421.8 282.7c-24.5-14-29.1-51.7-10.2-84.1s54-47.3 78.5-33.3 29.1 51.7 10.2 84.1-54 47.3-78.5 33.3zM310.1 189.7c-32.3-10.6-46.9-53.9-32.6-96.8s52.1-69.1 84.4-58.5 46.9 53.9 32.6 96.8-52.1 69.1-84.4 58.5z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:seedling",
|
||
name: "seedling",
|
||
label: "Plants",
|
||
viewBox: "0 0 512 512",
|
||
paths: [
|
||
"M512 32C512 140.1 435.4 230.3 333.6 251.4 325.7 193.3 299.6 141 261.1 100.5 301.2 40 369.9 0 448 0l32 0c17.7 0 32 14.3 32 32zM0 96C0 78.3 14.3 64 32 64l32 0c123.7 0 224 100.3 224 224l0 192c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-160C100.3 320 0 219.7 0 96z"
|
||
]
|
||
},
|
||
{
|
||
kind: "fa",
|
||
key: "fa:book",
|
||
name: "book",
|
||
label: "Reading",
|
||
viewBox: "0 0 448 512",
|
||
paths: [
|
||
"M384 512L96 512c-53 0-96-43-96-96L0 96C0 43 43 0 96 0L400 0c26.5 0 48 21.5 48 48l0 288c0 20.9-13.4 38.7-32 45.3l0 66.7c17.7 0 32 14.3 32 32s-14.3 32-32 32l-32 0zM96 384c-17.7 0-32 14.3-32 32s14.3 32 32 32l256 0 0-64-256 0zm32-232c0 13.3 10.7 24 24 24l176 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-176 0c-13.3 0-24 10.7-24 24zm24 72c-13.3 0-24 10.7-24 24s10.7 24 24 24l176 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-176 0z"
|
||
]
|
||
}
|
||
], B = { kind: "fallback", key: null }, Yt = 8, Pe = new Map(Jt.map((i) => [i.name, i])), en = new Map(Xt.map((i) => [i.name, i]));
|
||
function tn(i) {
|
||
const e = [...i];
|
||
return e.length === 0 || e.length > Yt ? !1 : !e.some((t) => new RegExp("[\\s<>&]|\\p{Cc}", "u").test(t));
|
||
}
|
||
function nn(i) {
|
||
if (!i || !i.trim()) return B;
|
||
const e = i.indexOf(":");
|
||
if (e === -1) return Pe.get(i) ?? B;
|
||
const t = i.slice(0, e), n = i.slice(e + 1);
|
||
return t === "lucide" ? Pe.get(n) ?? B : t === "fa" ? en.get(n) ?? B : t === "emoji" && tn(n) ? { kind: "emoji", key: i, text: n } : B;
|
||
}
|
||
function sn(i, e) {
|
||
const t = nn(i);
|
||
switch (t.kind) {
|
||
case "lucide":
|
||
return d`<svg
|
||
viewBox=${t.viewBox}
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
data-icon=${t.key}
|
||
>
|
||
${t.paths.map((n) => qe`<path d=${n}></path>`)}
|
||
</svg>`;
|
||
case "fa":
|
||
return d`<svg
|
||
viewBox=${t.viewBox}
|
||
fill="currentColor"
|
||
aria-hidden="true"
|
||
data-icon=${t.key}
|
||
>
|
||
${t.paths.map((n) => qe`<path d=${n}></path>`)}
|
||
</svg>`;
|
||
case "emoji":
|
||
return d`<span class="emoji" data-icon=${t.key}>${t.text}</span>`;
|
||
case "fallback":
|
||
return e;
|
||
}
|
||
}
|
||
const an = [
|
||
"nestquest_quest_completed",
|
||
"nestquest_quest_uncompleted",
|
||
"nestquest_quest_missed",
|
||
"nestquest_child_day_complete"
|
||
], He = /* @__PURE__ */ new Map();
|
||
function E(i, e) {
|
||
const t = `${i ?? "local"}|${JSON.stringify(e)}`, n = He.get(t);
|
||
if (n)
|
||
return n;
|
||
let s;
|
||
try {
|
||
s = new Intl.DateTimeFormat("en-US", {
|
||
...e,
|
||
...i ? { timeZone: i } : {}
|
||
});
|
||
} catch {
|
||
s = new Intl.DateTimeFormat("en-US", e);
|
||
}
|
||
return He.set(t, s), s;
|
||
}
|
||
function rn(i) {
|
||
const e = i?.config;
|
||
if (!e || typeof e != "object")
|
||
return;
|
||
const t = e.time_zone;
|
||
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
||
}
|
||
function j(i, e) {
|
||
return `${E(e, { weekday: "long" }).format(i)}, ${E(e, { month: "short", day: "numeric" }).format(i)}`;
|
||
}
|
||
function on(i, e) {
|
||
return E(e, { weekday: "long" }).format(i);
|
||
}
|
||
function ln(i, e) {
|
||
const t = new Date(i);
|
||
return Number.isNaN(t.getTime()) ? "" : E(e, {
|
||
hour: "numeric",
|
||
minute: "2-digit",
|
||
hour12: !0
|
||
}).format(t);
|
||
}
|
||
function cn(i, e) {
|
||
return E(e, {
|
||
hour: "numeric",
|
||
minute: "2-digit",
|
||
hour12: !0
|
||
}).format(i);
|
||
}
|
||
function dn(i) {
|
||
if (!i)
|
||
return null;
|
||
const e = /^(\d{1,2}):(\d{2})$/.exec(i.trim());
|
||
if (!e)
|
||
return null;
|
||
const t = Number(e[1]);
|
||
if (t > 23)
|
||
return null;
|
||
const n = t >= 12 ? "PM" : "AM";
|
||
return `${t % 12 === 0 ? 12 : t % 12}:${e[2]} ${n}`;
|
||
}
|
||
function w(i) {
|
||
return typeof i == "string" ? i.trim() : "";
|
||
}
|
||
function y(i, e) {
|
||
if (i == null || i === "")
|
||
return e;
|
||
const t = typeof i == "number" ? i : Number(i);
|
||
return Number.isFinite(t) ? t : e;
|
||
}
|
||
function b(i) {
|
||
return Math.max(0, Math.round(i));
|
||
}
|
||
function ie(i) {
|
||
return i.split(/[-_]+/).filter(Boolean).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
|
||
}
|
||
function pn(i, e) {
|
||
const t = E(e, {
|
||
year: "numeric",
|
||
month: "2-digit",
|
||
day: "2-digit",
|
||
hour: "2-digit",
|
||
minute: "2-digit",
|
||
second: "2-digit",
|
||
hourCycle: "h23"
|
||
}).formatToParts(new Date(i)), n = (a) => {
|
||
const r = t.find((l) => l.type === a);
|
||
return r ? Number(r.value) : Number.NaN;
|
||
}, s = Date.UTC(
|
||
n("year"),
|
||
n("month") - 1,
|
||
n("day"),
|
||
n("hour"),
|
||
n("minute"),
|
||
n("second")
|
||
);
|
||
return Number.isFinite(s) ? s - i : 0;
|
||
}
|
||
function Re(i, e) {
|
||
if (typeof i != "string")
|
||
return null;
|
||
const t = i.split("-");
|
||
if (t.length !== 3)
|
||
return null;
|
||
const [n, s, a] = t.map((o) => Number(o));
|
||
if (!n || !s || !a)
|
||
return null;
|
||
if (!e) {
|
||
const o = new Date(n, s - 1, a);
|
||
return Number.isNaN(o.getTime()) ? null : o;
|
||
}
|
||
const r = Date.UTC(n, s - 1, a), l = new Date(r - pn(r, e));
|
||
return Number.isNaN(l.getTime()) ? null : l;
|
||
}
|
||
function hn() {
|
||
const i = window.location.pathname.split("/").filter(Boolean);
|
||
return i.length > 0 ? i[i.length - 1].toLowerCase() : "";
|
||
}
|
||
function un(i) {
|
||
if (!i || typeof i != "object")
|
||
return null;
|
||
const e = i, t = w(e.state).toLowerCase();
|
||
if (t !== "open" && t !== "completed")
|
||
return null;
|
||
const n = y(e.id, 0);
|
||
if (!n)
|
||
return null;
|
||
const s = y(e.child_id, 0);
|
||
return {
|
||
id: n,
|
||
child_id: s > 0 ? s : null,
|
||
title: w(e.title) || "Quest",
|
||
icon: w(e.icon) || null,
|
||
window: w(e.window).toLowerCase(),
|
||
due_time: w(e.due_time) || null,
|
||
state: t,
|
||
overdue: e.overdue === !0,
|
||
completed_at: w(e.completed_at) || null,
|
||
on_time: e.on_time === !0 ? !0 : e.on_time === !1 ? !1 : null
|
||
};
|
||
}
|
||
const fn = {
|
||
"clear-night": "Clear",
|
||
cloudy: "Cloudy",
|
||
exceptional: "Clear",
|
||
fog: "Foggy",
|
||
hail: "Hail",
|
||
lightning: "Storms",
|
||
"lightning-rainy": "Storms",
|
||
partlycloudy: "Partly cloudy",
|
||
pouring: "Heavy rain",
|
||
rainy: "Rain",
|
||
snowy: "Snow",
|
||
"snowy-rainy": "Sleet",
|
||
sunny: "Sunny",
|
||
windy: "Windy",
|
||
"windy-variant": "Windy"
|
||
}, mn = {
|
||
"clear-night": "Clear night skies",
|
||
cloudy: "Grey skies today",
|
||
exceptional: "A striking day",
|
||
fog: "Mist on the road",
|
||
hail: "Ice from the sky",
|
||
lightning: "Storms may roll in",
|
||
"lightning-rainy": "Storms may roll in",
|
||
partlycloudy: "Sun between clouds",
|
||
pouring: "Heavy rain outside",
|
||
rainy: "Rain on the walls",
|
||
snowy: "Snow on the peaks",
|
||
"snowy-rainy": "Sleet may fall",
|
||
sunny: "Clear skies today",
|
||
windy: "A blustery day",
|
||
"windy-variant": "A blustery day"
|
||
};
|
||
function gn(i) {
|
||
const e = fn[i];
|
||
return e || i.charAt(0).toUpperCase() + i.slice(1);
|
||
}
|
||
function _n(i, e) {
|
||
return mn[i] ?? e;
|
||
}
|
||
const Ue = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", yn = "polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%)", je = [-9, 6, -4], bn = Ve`
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
:host {
|
||
display: block;
|
||
height: 100%;
|
||
--nq-brand-gradient-h: linear-gradient(
|
||
90deg,
|
||
var(--nq-brand-blue),
|
||
var(--nq-brand-purple)
|
||
);
|
||
}
|
||
|
||
.board {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 1080px;
|
||
padding: 0;
|
||
overflow: hidden;
|
||
background: var(--nq-p-parchment);
|
||
box-shadow: var(--nq-p-vignette);
|
||
font-family: var(--nq-p-font-body);
|
||
}
|
||
|
||
.frame {
|
||
position: absolute;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.frame-outer {
|
||
inset: 26px;
|
||
border: var(--nq-p-frame-outer);
|
||
border-radius: 14px;
|
||
}
|
||
|
||
.frame-inner {
|
||
inset: 36px;
|
||
border: var(--nq-p-frame-inner);
|
||
border-radius: 8px;
|
||
}
|
||
|
||
.header {
|
||
position: absolute;
|
||
top: 56px;
|
||
left: var(--nq-p-page-inset);
|
||
right: var(--nq-p-page-inset);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 28px;
|
||
}
|
||
|
||
button.return {
|
||
flex: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 10px;
|
||
height: var(--nq-p-button-height);
|
||
padding: 0 28px 0 20px;
|
||
border: 2px solid rgba(92, 62, 26, 0.5);
|
||
border-radius: 10px;
|
||
background: rgba(92, 62, 26, 0.1);
|
||
color: var(--nq-p-ink);
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 26px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
white-space: nowrap;
|
||
cursor: pointer;
|
||
-webkit-tap-highlight-color: transparent;
|
||
transition: transform var(--nq-dur-micro) var(--nq-ease-out);
|
||
}
|
||
|
||
button.return:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
button.return svg {
|
||
width: 34px;
|
||
height: 34px;
|
||
}
|
||
|
||
.crest {
|
||
position: relative;
|
||
flex: none;
|
||
width: 96px;
|
||
height: 110px;
|
||
padding: 4px;
|
||
clip-path: ${x(Ue)};
|
||
background: rgba(255, 255, 255, 0.22);
|
||
}
|
||
|
||
.crest-face {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding-bottom: 32px;
|
||
clip-path: ${x(Ue)};
|
||
background: var(--nq-p-crest);
|
||
}
|
||
|
||
.crest .initial {
|
||
font-family: var(--nq-p-font-display);
|
||
font-size: 44px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.crest.away .crest-face {
|
||
background: var(--nq-p-crest-away);
|
||
}
|
||
|
||
.titles {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
min-width: 0;
|
||
}
|
||
|
||
.title {
|
||
margin: 0;
|
||
font-family: var(--nq-p-font-display);
|
||
font-size: var(--nq-p-size-title);
|
||
font-weight: 700;
|
||
line-height: 1.1;
|
||
color: var(--nq-p-ink);
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.sub {
|
||
margin: 0;
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.24em;
|
||
text-transform: uppercase;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.remaining {
|
||
margin-left: auto;
|
||
flex: none;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20px;
|
||
padding: 18px 28px;
|
||
border: 2px solid var(--nq-p-panel-border);
|
||
border-radius: 14px;
|
||
background: var(--nq-p-card-panel);
|
||
box-shadow: var(--nq-p-panel-shadow);
|
||
}
|
||
|
||
.d20 {
|
||
flex: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 44px;
|
||
height: 44px;
|
||
clip-path: ${x(yn)};
|
||
background: var(--nq-brand-gradient);
|
||
}
|
||
|
||
.d20-numeral {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 19px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.remaining-text {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
}
|
||
|
||
.remaining-count {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 28px;
|
||
font-weight: 700;
|
||
line-height: 1.1;
|
||
color: var(--nq-p-ink);
|
||
}
|
||
|
||
.party-line {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: var(--nq-p-size-body);
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.columns {
|
||
position: absolute;
|
||
top: 236px;
|
||
left: var(--nq-p-page-inset);
|
||
right: var(--nq-p-page-inset);
|
||
bottom: 130px;
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 34px;
|
||
}
|
||
|
||
.column {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
}
|
||
|
||
.column-head {
|
||
flex: none;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
padding-bottom: 14px;
|
||
border-bottom: var(--nq-p-rule);
|
||
}
|
||
|
||
.column-head svg {
|
||
flex: none;
|
||
width: 34px;
|
||
height: 34px;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.column-names {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
min-width: 0;
|
||
}
|
||
|
||
.column-name {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: var(--nq-p-size-section);
|
||
font-weight: 700;
|
||
line-height: 1.1;
|
||
color: var(--nq-p-ink);
|
||
}
|
||
|
||
.column-range {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: var(--nq-p-size-label);
|
||
font-weight: 600;
|
||
letter-spacing: var(--nq-p-track-label);
|
||
text-transform: uppercase;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.column-count {
|
||
margin-left: auto;
|
||
flex: none;
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 26px;
|
||
font-weight: 700;
|
||
line-height: 1.1;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.stack {
|
||
display: flex;
|
||
flex-direction: column;
|
||
flex: 1;
|
||
min-height: 0;
|
||
overflow: visible;
|
||
gap: var(--nq-p-quest-gap);
|
||
margin-top: 22px;
|
||
}
|
||
|
||
.quest {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 22px;
|
||
min-height: var(--nq-p-quest-min-height);
|
||
padding: var(--nq-p-quest-pad);
|
||
border: 1px solid var(--nq-p-card-border);
|
||
border-radius: var(--nq-p-radius-card);
|
||
background: var(--nq-p-card-open);
|
||
box-shadow: var(--nq-p-card-shadow);
|
||
-webkit-tap-highlight-color: transparent;
|
||
transition: transform var(--nq-dur-micro) var(--nq-ease-out);
|
||
}
|
||
|
||
.quest.tappable {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.quest.tappable:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
.quest.sealed {
|
||
background: var(--nq-p-card-done);
|
||
opacity: 0.82;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.tile {
|
||
flex: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: var(--nq-p-tile-size);
|
||
height: var(--nq-p-tile-size);
|
||
border-radius: 10px;
|
||
background: var(--nq-p-icon-tile);
|
||
color: #ffffff;
|
||
}
|
||
|
||
.tile svg {
|
||
width: 34px;
|
||
height: 34px;
|
||
}
|
||
|
||
.tile .emoji {
|
||
font-size: 30px;
|
||
line-height: 1;
|
||
}
|
||
|
||
.sealed .tile {
|
||
background: var(--nq-p-icon-tile-done);
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.quest .body {
|
||
flex: 1 1 0;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
}
|
||
|
||
.quest .quest-title {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: var(--nq-p-size-quest);
|
||
font-weight: 700;
|
||
line-height: 1.15;
|
||
color: var(--nq-p-ink);
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.sealed .quest-title {
|
||
color: var(--nq-p-ink-muted);
|
||
text-decoration: line-through;
|
||
}
|
||
|
||
.quest .meta {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: var(--nq-p-size-body);
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.quest .meta.late {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-weight: 700;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
color: var(--nq-p-ink-late);
|
||
}
|
||
|
||
button.complete {
|
||
flex: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 10px;
|
||
height: var(--nq-p-button-height);
|
||
min-width: var(--nq-p-button-min-width);
|
||
border: none;
|
||
border-radius: 10px;
|
||
background: var(--nq-brand-gradient);
|
||
color: #ffffff;
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
box-shadow: 0 3px 0 rgba(40, 20, 60, 0.35);
|
||
cursor: pointer;
|
||
-webkit-tap-highlight-color: transparent;
|
||
transition: transform var(--nq-dur-micro) var(--nq-ease-out);
|
||
}
|
||
|
||
button.complete:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
button.complete svg {
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
|
||
button:focus-visible {
|
||
outline: 3px solid var(--nq-brand-purple);
|
||
outline-offset: 4px;
|
||
}
|
||
|
||
.seal {
|
||
position: absolute;
|
||
right: 16px;
|
||
top: -12px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: var(--nq-p-seal-size);
|
||
height: var(--nq-p-seal-size);
|
||
border-radius: var(--nq-p-radius-pill);
|
||
background: var(--nq-p-seal);
|
||
box-shadow: var(--nq-p-seal-shadow);
|
||
color: rgba(255, 235, 235, 0.95);
|
||
transform: rotate(var(--seal-rot, 0deg));
|
||
animation: seal-in var(--nq-dur-base) var(--nq-ease-out);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.seal svg {
|
||
width: 38px;
|
||
height: 38px;
|
||
}
|
||
|
||
@keyframes seal-in {
|
||
from {
|
||
opacity: 0;
|
||
transform: scale(1.15) rotate(var(--seal-rot, 0deg));
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: scale(1) rotate(var(--seal-rot, 0deg));
|
||
}
|
||
}
|
||
|
||
.rollup {
|
||
border: 2px dashed var(--nq-p-panel-border);
|
||
border-radius: 14px;
|
||
padding: 16px 22px;
|
||
}
|
||
|
||
.rollup-label {
|
||
display: block;
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
letter-spacing: var(--nq-p-track-label);
|
||
text-transform: uppercase;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.rollup-body {
|
||
margin: 6px 0 0;
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 23px;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.notice-wrap {
|
||
position: absolute;
|
||
top: 236px;
|
||
left: var(--nq-p-page-inset);
|
||
right: var(--nq-p-page-inset);
|
||
bottom: 130px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.notice {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 20px;
|
||
width: 100%;
|
||
max-width: 980px;
|
||
padding: 56px 64px;
|
||
border: 2px solid var(--nq-p-panel-border);
|
||
border-radius: 20px;
|
||
background: var(--nq-p-card-panel);
|
||
box-shadow: var(--nq-p-panel-shadow);
|
||
text-align: center;
|
||
}
|
||
|
||
.notice svg {
|
||
width: 46px;
|
||
height: 46px;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.notice.away {
|
||
background: linear-gradient(#f2ecdd, #e6dcc6);
|
||
border-style: dashed;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.notice-headline {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 40px;
|
||
font-weight: 700;
|
||
line-height: 1.15;
|
||
color: var(--nq-p-ink);
|
||
}
|
||
|
||
.notice-body {
|
||
margin: 0;
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 24px;
|
||
font-weight: 600;
|
||
line-height: 1.4;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.notice-seal {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 78px;
|
||
height: 78px;
|
||
border-radius: var(--nq-p-radius-pill);
|
||
background: var(--nq-p-seal);
|
||
box-shadow: var(--nq-p-seal-shadow);
|
||
color: rgba(255, 235, 235, 0.95);
|
||
transform: rotate(-6deg);
|
||
}
|
||
|
||
.notice-seal svg {
|
||
width: 38px;
|
||
height: 38px;
|
||
color: rgba(255, 235, 235, 0.95);
|
||
}
|
||
|
||
.scrim {
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 10;
|
||
background: rgba(30, 20, 10, 0.62);
|
||
}
|
||
|
||
.dialog {
|
||
position: absolute;
|
||
top: 196px;
|
||
left: 460px;
|
||
width: 1000px;
|
||
border: 3px solid rgba(92, 62, 26, 0.5);
|
||
border-radius: 20px;
|
||
background: var(--nq-p-card-panel);
|
||
box-shadow: 0 26px 60px rgba(20, 10, 0, 0.5);
|
||
padding: 64px 68px 56px;
|
||
animation: dialog-in var(--nq-dur-modal) var(--nq-ease-out);
|
||
}
|
||
|
||
@keyframes dialog-in {
|
||
from {
|
||
opacity: 0;
|
||
transform: scale(0.96);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: scale(1);
|
||
}
|
||
}
|
||
|
||
.dialog-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 24px;
|
||
}
|
||
|
||
.dialog-tile {
|
||
flex: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 104px;
|
||
height: 104px;
|
||
border-radius: 12px;
|
||
background: var(--nq-p-icon-tile);
|
||
color: #ffffff;
|
||
}
|
||
|
||
.dialog-tile svg {
|
||
width: 56px;
|
||
height: 56px;
|
||
}
|
||
|
||
.dialog-titles {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
min-width: 0;
|
||
}
|
||
|
||
.dialog-kicker {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: var(--nq-p-size-label);
|
||
font-weight: 600;
|
||
letter-spacing: 0.24em;
|
||
text-transform: uppercase;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.dialog-quest-title {
|
||
font-family: var(--nq-p-font-display);
|
||
font-size: 58px;
|
||
font-weight: 700;
|
||
line-height: 1.1;
|
||
color: var(--nq-p-ink);
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.dialog-body {
|
||
margin: 28px 0 0;
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 32px;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
color: #3f2f1c;
|
||
}
|
||
|
||
.dialog-buttons {
|
||
display: flex;
|
||
gap: 24px;
|
||
margin-top: 40px;
|
||
}
|
||
|
||
button.confirm-button {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 12px;
|
||
height: var(--nq-p-confirm-button);
|
||
border-radius: 10px;
|
||
font-family: var(--nq-p-font-heading);
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
-webkit-tap-highlight-color: transparent;
|
||
transition: transform var(--nq-dur-micro) var(--nq-ease-out);
|
||
}
|
||
|
||
button.confirm-button:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
button.not-yet {
|
||
flex: 1;
|
||
border: 2px solid rgba(92, 62, 26, 0.5);
|
||
background: rgba(92, 62, 26, 0.1);
|
||
color: var(--nq-p-ink);
|
||
font-size: 30px;
|
||
}
|
||
|
||
button.not-yet svg {
|
||
width: 34px;
|
||
height: 34px;
|
||
}
|
||
|
||
button.do-complete {
|
||
flex: 2;
|
||
border: none;
|
||
background: var(--nq-brand-gradient);
|
||
color: #ffffff;
|
||
font-size: 32px;
|
||
}
|
||
|
||
button.do-complete svg {
|
||
width: 38px;
|
||
height: 38px;
|
||
}
|
||
|
||
.toast {
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: 158px;
|
||
z-index: 20;
|
||
transform: translateX(-50%);
|
||
max-width: calc(100% - 124px);
|
||
padding: 20px 32px;
|
||
border: 2px solid var(--nq-p-panel-border);
|
||
border-radius: 14px;
|
||
background: var(--nq-p-card-panel);
|
||
box-shadow: var(--nq-p-panel-shadow);
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 23px;
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
color: var(--nq-p-ink-secondary);
|
||
animation: toast-in var(--nq-dur-base) var(--nq-ease-out);
|
||
pointer-events: none;
|
||
}
|
||
|
||
@keyframes toast-in {
|
||
from {
|
||
opacity: 0;
|
||
transform: translate(-50%, 12px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translate(-50%, 0);
|
||
}
|
||
}
|
||
|
||
.complete-screen {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 96px 62px 130px;
|
||
text-align: center;
|
||
}
|
||
|
||
.complete-seal {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 168px;
|
||
height: 168px;
|
||
border-radius: var(--nq-p-radius-pill);
|
||
background: var(--nq-p-seal);
|
||
box-shadow: 0 10px 24px rgba(60, 10, 20, 0.42);
|
||
color: rgba(255, 235, 235, 0.95);
|
||
transform: rotate(-6deg);
|
||
}
|
||
|
||
.complete-seal svg {
|
||
width: 86px;
|
||
height: 86px;
|
||
}
|
||
|
||
.complete-title {
|
||
margin: 28px 0 0;
|
||
font-family: var(--nq-p-font-display);
|
||
font-size: 86px;
|
||
font-weight: 900;
|
||
line-height: 1.1;
|
||
background: var(--nq-brand-gradient-h);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
-webkit-text-fill-color: transparent;
|
||
}
|
||
|
||
.complete-sub {
|
||
margin: 16px 0 0;
|
||
max-width: 1000px;
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 34px;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
color: var(--nq-p-ink-secondary);
|
||
text-wrap: pretty;
|
||
}
|
||
|
||
.complete-countdown {
|
||
margin: 12px 0 0;
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 25px;
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.complete-stats {
|
||
position: absolute;
|
||
top: 540px;
|
||
left: 200px;
|
||
right: 200px;
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 26px;
|
||
}
|
||
|
||
.complete-stat {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
padding: 28px 16px;
|
||
border: 2px solid var(--nq-p-panel-border);
|
||
border-radius: 16px;
|
||
background: var(--nq-p-card-panel);
|
||
box-shadow: var(--nq-p-panel-shadow);
|
||
}
|
||
|
||
.complete-stat .numeral {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 58px;
|
||
font-weight: 900;
|
||
line-height: 1;
|
||
color: var(--nq-p-ink);
|
||
}
|
||
|
||
.complete-stat .label {
|
||
font-family: var(--nq-p-font-heading);
|
||
font-size: 17px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-ink-secondary);
|
||
}
|
||
|
||
.dock {
|
||
position: absolute;
|
||
left: 46px;
|
||
right: 46px;
|
||
bottom: 46px;
|
||
height: var(--nq-p-dock-height);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 24px;
|
||
padding: 0 40px;
|
||
border-radius: 14px;
|
||
background: var(--nq-p-dock-bg);
|
||
pointer-events: none;
|
||
user-select: none;
|
||
color: var(--nq-p-dock-ink);
|
||
}
|
||
|
||
.dock svg {
|
||
flex: none;
|
||
width: 40px;
|
||
height: 40px;
|
||
color: var(--nq-p-dock-ink);
|
||
}
|
||
|
||
.dock .divider {
|
||
flex: none;
|
||
width: 1px;
|
||
height: 40px;
|
||
background: var(--nq-p-dock-divider);
|
||
}
|
||
|
||
.dock .temp {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 38px;
|
||
font-weight: 800;
|
||
line-height: 1;
|
||
}
|
||
|
||
.dock .condition {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 26px;
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-dock-ink-secondary);
|
||
}
|
||
|
||
.dock .date {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 26px;
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--nq-p-dock-ink-secondary);
|
||
}
|
||
|
||
.dock .clock {
|
||
font-family: var(--nq-p-font-body);
|
||
font-size: 38px;
|
||
font-weight: 800;
|
||
line-height: 1;
|
||
}
|
||
`, D = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M20 6 9 17l-5-5"></path>
|
||
</svg>`, vn = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M18 6 6 18"></path>
|
||
<path d="m6 6 12 12"></path>
|
||
</svg>`, xn = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="m15 18-6-6 6-6"></path>
|
||
</svg>`, se = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<polygon
|
||
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26"
|
||
></polygon>
|
||
</svg>`, wn = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M12 2v8"></path>
|
||
<path d="m4.93 10.93 1.41 1.41"></path>
|
||
<path d="M2 18h2"></path>
|
||
<path d="M20 18h2"></path>
|
||
<path d="m19.07 10.93-1.41 1.41"></path>
|
||
<path d="M22 22H2"></path>
|
||
<path d="m8 6 4-4 4 4"></path>
|
||
<path d="M16 18a4 4 0 0 0-8 0"></path>
|
||
</svg>`, Ye = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<circle cx="12" cy="12" r="4"></circle>
|
||
<path d="M12 2v2"></path>
|
||
<path d="M12 20v2"></path>
|
||
<path d="m4.93 4.93 1.41 1.41"></path>
|
||
<path d="m17.66 17.66 1.41 1.41"></path>
|
||
<path d="M2 12h2"></path>
|
||
<path d="M20 12h2"></path>
|
||
<path d="m6.34 17.66-1.41 1.41"></path>
|
||
<path d="m19.07 4.93-1.41 1.41"></path>
|
||
</svg>`, kn = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path>
|
||
</svg>`, $n = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M3.5 21 12 3.5 20.5 21"></path>
|
||
<path d="M9 21l3-8 3 8"></path>
|
||
</svg>`, qn = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<circle cx="12" cy="12" r="10"></circle>
|
||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"></polygon>
|
||
</svg>`, Mn = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path>
|
||
<path d="M12 9v4"></path>
|
||
<path d="M12 17h.01"></path>
|
||
</svg>`, Cn = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path>
|
||
<path d="m2 2 20 20"></path>
|
||
</svg>`, An = d`<svg
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M13 16a3 3 0 1 1 0 6H7a5 5 0 1 1 4.9-6Z"></path>
|
||
<path d="M10.1 9A6 6 0 0 1 16 4a4.5 4.5 0 0 0 8.9 4.2v.1a6 6 0 0 1-5.2 5.7"></path>
|
||
</svg>`, Sn = {
|
||
icon: qn,
|
||
headline: "No adventurer chosen",
|
||
body: "Open The Party and tap your crest to open your quest log."
|
||
}, zn = {
|
||
icon: Mn,
|
||
headline: "NestQuest is not set up yet",
|
||
body: "A parent needs to finish setting up NestQuest."
|
||
}, Tn = {
|
||
icon: Cn,
|
||
headline: "The records cannot be reached",
|
||
body: "The party's records are quiet right now. NestQuest will return shortly."
|
||
}, De = [
|
||
{ key: "morning", name: "Morning", range: "Until 11:59 AM", icon: wn },
|
||
{ key: "afternoon", name: "Afternoon", range: "12:00–5:00 PM", icon: Ye },
|
||
{ key: "evening", name: "Evening", range: "5:00–9:00 PM", icon: kn }
|
||
], W = class W extends C {
|
||
constructor() {
|
||
super(...arguments), this._now = /* @__PURE__ */ new Date(), this._confirm = null, this._optimistic = /* @__PURE__ */ new Map(), this._toast = null, this._countdown = null, this._unsubs = [], this._subscribed = !1, this._subGeneration = 0, this._onActivity = () => {
|
||
this._logView().kind !== "complete-day" && this._armIdle(), this._confirm !== null && this._armConfirmTimer();
|
||
};
|
||
}
|
||
setConfig(e) {
|
||
if (!e || typeof e != "object")
|
||
throw new Error("Invalid configuration");
|
||
this._config = e;
|
||
}
|
||
_hassConnection() {
|
||
const e = this.hass?.connection;
|
||
return !e || typeof e != "object" || typeof e.subscribeEvents != "function" ? null : e;
|
||
}
|
||
_subscribeLive() {
|
||
if (!this.isConnected || this._subscribed)
|
||
return;
|
||
const e = this._hassConnection();
|
||
if (!e)
|
||
return;
|
||
this._subscribed = !0;
|
||
const t = ++this._subGeneration, n = (s) => {
|
||
s.then((a) => {
|
||
this._subscribed && t === this._subGeneration ? this._unsubs.push(a) : a();
|
||
}).catch(() => {
|
||
t === this._subGeneration && (this._unsubscribeLive(), this._armSubscribeRetry());
|
||
});
|
||
};
|
||
for (const s of an)
|
||
n(
|
||
e.subscribeEvents(() => this.requestUpdate(), s)
|
||
);
|
||
}
|
||
_armSubscribeRetry() {
|
||
this._retryTimer === void 0 && (this._retryTimer = window.setTimeout(() => {
|
||
this._retryTimer = void 0, this._subscribeLive();
|
||
}, 1e3));
|
||
}
|
||
_clearSubscribeRetry() {
|
||
this._retryTimer !== void 0 && (window.clearTimeout(this._retryTimer), this._retryTimer = void 0);
|
||
}
|
||
_unsubscribeLive() {
|
||
this._clearSubscribeRetry(), this._subGeneration++;
|
||
for (const e of this._unsubs)
|
||
e();
|
||
this._unsubs = [], this._subscribed = !1;
|
||
}
|
||
getCardSize() {
|
||
return 22;
|
||
}
|
||
connectedCallback() {
|
||
super.connectedCallback(), this._subscribeLive(), this._now = /* @__PURE__ */ new Date(), this._clockTimer = window.setInterval(() => {
|
||
this._now = /* @__PURE__ */ new Date();
|
||
}, 6e4), window.addEventListener("pointerdown", this._onActivity, !0), window.addEventListener("touchstart", this._onActivity, !0), window.addEventListener("keydown", this._onActivity, !0), this._armIdle(), this._logView().kind === "complete-day" && this._armCompleteTimer();
|
||
}
|
||
updated() {
|
||
this._subscribeLive(), this._logView().kind === "complete-day" ? (this._clearIdle(), this._armCompleteTimer()) : (this._clearCompleteTimer(), this._countdown = null, this._idleTimer === void 0 && this._armIdle());
|
||
}
|
||
disconnectedCallback() {
|
||
this._unsubscribeLive(), this._stopClock(), this._clearIdle(), this._clearConfirmTimer(), this._clearToastTimer(), this._clearCompleteTimer(), window.removeEventListener("pointerdown", this._onActivity, !0), window.removeEventListener("touchstart", this._onActivity, !0), window.removeEventListener("keydown", this._onActivity, !0), super.disconnectedCallback();
|
||
}
|
||
render() {
|
||
const e = this._logView();
|
||
return d`
|
||
<div class="board">
|
||
<div class="frame frame-outer"></div>
|
||
<div class="frame frame-inner"></div>
|
||
${this._renderMain(e)}
|
||
${this._renderConfirm()}
|
||
${this._renderToast()}
|
||
</div>
|
||
`;
|
||
}
|
||
_renderToast() {
|
||
return this._toast === null ? g : d`
|
||
<div class="toast" role="status">${this._toast}</div>
|
||
`;
|
||
}
|
||
_renderMain(e) {
|
||
switch (e.kind) {
|
||
case "no-adventurer":
|
||
return this._renderNotice(Sn);
|
||
case "not-set-up":
|
||
return this._renderNotice(zn);
|
||
case "unreachable":
|
||
return this._renderNotice(Tn);
|
||
case "away": {
|
||
const t = ["The quest log unlocks when they return."];
|
||
return e.returns && t.push(`Returns ${e.returns}`), d`
|
||
${this._renderHeader(e)}
|
||
<div class="notice-wrap">
|
||
<div class="notice away" role="status">
|
||
${$n}
|
||
<span class="notice-headline">${e.name} is on travels</span>
|
||
${t.map((n) => d`<p class="notice-body">${n}</p>`)}
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
case "empty-day":
|
||
return d`
|
||
${this._renderHeader(e)}
|
||
<div class="notice-wrap">
|
||
<div class="notice" role="status">
|
||
${Ye}
|
||
<span class="notice-headline">No quests today</span>
|
||
<p class="notice-body">
|
||
${`Nothing was posted for today, ${e.name}. Enjoy the day's rest!`}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
`;
|
||
case "complete-day": {
|
||
const t = this._completeStats(), n = this._countdown ?? this._completeSeconds();
|
||
return d`
|
||
<div class="complete-screen" role="status">
|
||
<span class="complete-seal" aria-hidden="true">${D}</span>
|
||
<h1 class="complete-title">Quest complete</h1>
|
||
<p class="complete-sub">${this._completeSub(e.name)}</p>
|
||
<p class="complete-countdown">
|
||
Returning to The Party in ${n} seconds
|
||
</p>
|
||
<div class="complete-stats">
|
||
<div class="complete-stat">
|
||
<span class="numeral">${t.claimed}</span>
|
||
<span class="label">Quests claimed</span>
|
||
</div>
|
||
<div class="complete-stat">
|
||
<span class="numeral">${t.onTime}</span>
|
||
<span class="label">On time</span>
|
||
</div>
|
||
<div class="complete-stat">
|
||
<span class="numeral">${t.late}</span>
|
||
<span class="label">Late</span>
|
||
</div>
|
||
<div class="complete-stat">
|
||
<span class="numeral">${t.party}</span>
|
||
<span class="label">The Party</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
${this._renderDock()}
|
||
`;
|
||
}
|
||
default:
|
||
return d`
|
||
${this._renderHeader(e)}
|
||
<div class="columns">
|
||
${De.map((t) => this._renderColumn(t))}
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
/** Resolve the log's single render state; the priority order is
|
||
* design/PANEL-EMPTY-STATES.md §2. */
|
||
_logView() {
|
||
const e = this._childSlug();
|
||
if (!e)
|
||
return { kind: "no-adventurer" };
|
||
const t = this._dueSensorResolution(e);
|
||
if (t === "missing")
|
||
return { kind: "not-set-up" };
|
||
if (t === "stale")
|
||
return { kind: "unreachable" };
|
||
const n = this._childName(e) ?? ie(e);
|
||
if (!this._childPresent(e))
|
||
return { kind: "away", name: n, returns: this._awayReturns(e) };
|
||
const s = this._state(`binary_sensor.nestquest_${e}_all_done`);
|
||
if (s && String(s.state ?? "").trim().toLowerCase() === "on")
|
||
return { kind: "complete-day", name: n };
|
||
const a = this._state(`sensor.nestquest_${e}_quests_due_today`);
|
||
return b(y(a?.state, 0)) === 0 ? { kind: "empty-day", name: n } : this._remaining() === 0 ? { kind: "complete-day", name: n } : { kind: "normal" };
|
||
}
|
||
/** "missing" when the due sensor does not exist (integration not
|
||
* configured), "stale" when it answers unavailable/unknown (backend
|
||
* unreachable or the child is absent from the snapshot), null when
|
||
* it resolves. */
|
||
_dueSensorResolution(e) {
|
||
const t = this._state(`sensor.nestquest_${e}_quests_due_today`);
|
||
if (!t)
|
||
return "missing";
|
||
const n = String(t.state ?? "").trim().toLowerCase();
|
||
return !n || n === "unavailable" || n === "unknown" ? "stale" : null;
|
||
}
|
||
_childPresent(e) {
|
||
const n = this._state(`sensor.nestquest_${e}_quests_due_today`)?.attributes?.present;
|
||
if (typeof n == "boolean")
|
||
return n;
|
||
const s = this._state(
|
||
`binary_sensor.nestquest_${e}_present_today`
|
||
);
|
||
return s ? String(s.state ?? "").trim().toLowerCase() === "on" : !0;
|
||
}
|
||
_awayReturns(e) {
|
||
const t = this._timeZone(), n = this._state(
|
||
`binary_sensor.nestquest_${e}_present_today`
|
||
), s = Re(
|
||
n?.attributes?.next_present,
|
||
t
|
||
);
|
||
return s ? j(s, t) : null;
|
||
}
|
||
_renderNotice(e) {
|
||
return d`
|
||
<div class="notice-wrap">
|
||
<div class="notice" role="status">
|
||
${e.icon}
|
||
<span class="notice-headline">${e.headline}</span>
|
||
<p class="notice-body">${e.body}</p>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
/** The zone the visible date and clock render in: the API's effective
|
||
* application timezone — the stored zone, or the API host's when none
|
||
* is stored (published on the household rollup by
|
||
* custom_components/nestquest/sensor.py — ``timezone``). Only when the
|
||
* rollup carries none does Home Assistant's zone (or the browser's)
|
||
* apply. */
|
||
_timeZone() {
|
||
const e = this._state("sensor.nestquest_household_quests_due_today")?.attributes?.timezone;
|
||
return typeof e == "string" && e.trim() ? e.trim() : rn(this.hass);
|
||
}
|
||
_state(e) {
|
||
const n = this.hass?.states?.[e];
|
||
return n && typeof n == "object" ? n : null;
|
||
}
|
||
_childSlug() {
|
||
return hn();
|
||
}
|
||
_boardPath() {
|
||
return w(this._config?.board_path).replace(/\/+$/, "");
|
||
}
|
||
_idleSeconds() {
|
||
const e = y(this._config?.idle_return_seconds, 40);
|
||
return e > 0 ? e : 40;
|
||
}
|
||
_confirmSeconds() {
|
||
const e = y(this._config?.confirm_timeout_seconds, 15);
|
||
return e > 0 ? e : 15;
|
||
}
|
||
_completeSeconds() {
|
||
const e = y(this._config?.complete_screen_seconds, 12);
|
||
return e > 0 ? e : 12;
|
||
}
|
||
_childName(e) {
|
||
if (!e)
|
||
return null;
|
||
const t = this._state(`sensor.nestquest_${e}_quests_due_today`)?.attributes?.child_name;
|
||
return typeof t == "string" && t.trim() ? t.trim() : null;
|
||
}
|
||
_childCounts(e) {
|
||
const t = this._state(`sensor.nestquest_${e}_quests_due_today`), n = this._state(
|
||
`sensor.nestquest_${e}_quests_completed_today`
|
||
), s = b(y(t?.state, 0)), a = b(y(n?.state, 0));
|
||
return { due: s, completed: a };
|
||
}
|
||
_instances() {
|
||
const e = this._childSlug();
|
||
if (!e)
|
||
return [];
|
||
const t = this._state(`sensor.nestquest_${e}_quests_due_today`)?.attributes?.instances;
|
||
if (!Array.isArray(t))
|
||
return [];
|
||
const n = t.map(un).filter((a) => a !== null);
|
||
if (this._optimistic.size === 0)
|
||
return n;
|
||
let s = !1;
|
||
for (const a of n) {
|
||
const r = this._optimistic.get(a.id);
|
||
if (r !== void 0) {
|
||
if (a.state === "completed") {
|
||
this._optimistic.delete(a.id), s = !0;
|
||
continue;
|
||
}
|
||
a.state = "completed", a.overdue = !1, a.completed_at = r;
|
||
}
|
||
}
|
||
return s && (this._optimistic = new Map(this._optimistic)), n;
|
||
}
|
||
_remaining() {
|
||
const e = this._childSlug();
|
||
if (!e)
|
||
return 0;
|
||
const t = this._state(
|
||
`sensor.nestquest_${e}_quests_remaining_today`
|
||
);
|
||
if (t)
|
||
return b(y(t.state, 0));
|
||
const { due: n, completed: s } = this._childCounts(e);
|
||
return b(n - s);
|
||
}
|
||
_partyCounts() {
|
||
const e = this._state(
|
||
"sensor.nestquest_household_quests_due_today"
|
||
), t = this._state(
|
||
"sensor.nestquest_household_quests_completed_today"
|
||
);
|
||
if (e || t)
|
||
return {
|
||
completed: b(y(t?.state, 0)),
|
||
due: b(y(e?.state, 0))
|
||
};
|
||
const n = this._childSlug(), { due: s, completed: a } = this._childCounts(n);
|
||
return { completed: a, due: s };
|
||
}
|
||
_completeStats() {
|
||
const e = this._childCounts(this._childSlug()).completed, t = this._instances().filter(
|
||
(a) => a.on_time === !0
|
||
).length, n = b(e - t), s = this._partyCounts();
|
||
return {
|
||
claimed: e,
|
||
onTime: t,
|
||
late: n,
|
||
party: `${s.completed}/${s.due}`
|
||
};
|
||
}
|
||
_completeSub(e) {
|
||
const t = j(this._now, this._timeZone()), { claimed: n, onTime: s, late: a } = this._completeStats();
|
||
return n === 0 ? `${e} sealed the day on ${t}.` : a === 0 ? `${e} claimed every quest on ${t} — all on time.` : s === 0 ? `${e} claimed every quest on ${t} — all late.` : `${e} claimed every quest on ${t} — ${s} on time, ${a} late.`;
|
||
}
|
||
_otherChildren() {
|
||
const e = this.hass?.states;
|
||
if (!e)
|
||
return [];
|
||
const t = this._childSlug(), n = this._timeZone(), s = [];
|
||
for (const a of Object.keys(e)) {
|
||
const r = /^sensor\.nestquest_(.+)_quests_due_today$/.exec(a);
|
||
if (!r || r[1] === "household" || r[1] === t)
|
||
continue;
|
||
const l = r[1], o = e[a]?.attributes ?? {};
|
||
let p = "";
|
||
typeof o.child_name == "string" && o.child_name.trim() ? p = o.child_name.trim() : p = ie(l);
|
||
let u = !0;
|
||
if (typeof o.present == "boolean")
|
||
u = o.present;
|
||
else {
|
||
const _ = this._state(
|
||
`binary_sensor.nestquest_${l}_present_today`
|
||
);
|
||
u = _ === null || String(_.state ?? "").trim().toLowerCase() !== "off";
|
||
}
|
||
const c = this._state(
|
||
`sensor.nestquest_${l}_quests_completed_today`
|
||
), f = b(y(e[a]?.state, 0)), h = b(y(c?.state, 0));
|
||
let m = null;
|
||
if (!u) {
|
||
const _ = this._state(
|
||
`binary_sensor.nestquest_${l}_present_today`
|
||
), v = Re(
|
||
_?.attributes?.next_present,
|
||
n
|
||
);
|
||
m = v ? on(v, n) : null;
|
||
}
|
||
s.push({
|
||
slug: l,
|
||
name: p,
|
||
present: u,
|
||
due: f,
|
||
completed: h,
|
||
returnsWeekday: m
|
||
});
|
||
}
|
||
return s.sort((a, r) => a.name.localeCompare(r.name));
|
||
}
|
||
_renderHeader(e) {
|
||
const t = this._childSlug(), n = e.kind === "away", s = n ? e.name : this._childName(t) ?? (t ? ie(t) : null), { due: a, completed: r } = this._childCounts(t), l = this._remaining(), o = this._partyCounts(), p = s ? `${s}'s Quest Log` : "Quest Log", u = (s?.charAt(0) || "?").toUpperCase();
|
||
return d`
|
||
<header class="header">
|
||
${this._boardPath() ? d`
|
||
<button
|
||
class="return"
|
||
type="button"
|
||
@click=${() => this._returnToBoard()}
|
||
>
|
||
${xn}
|
||
<span>The Party</span>
|
||
</button>
|
||
` : g}
|
||
<span class="crest${n ? " away" : ""}" aria-hidden="true">
|
||
<span class="crest-face">
|
||
<span class="initial">${u}</span>
|
||
</span>
|
||
</span>
|
||
<div class="titles">
|
||
<h1 class="title">${p}</h1>
|
||
<p class="sub">
|
||
${j(this._now, this._timeZone())} ·
|
||
${n ? "On travels" : `${r} of ${a} claimed`}
|
||
</p>
|
||
</div>
|
||
${n ? g : d`
|
||
<div class="remaining">
|
||
<span class="d20" aria-hidden="true">
|
||
<span class="d20-numeral">${l}</span>
|
||
</span>
|
||
<div class="remaining-text">
|
||
<span class="remaining-count">
|
||
${l} quest${l === 1 ? "" : "s"} left
|
||
</span>
|
||
<span class="party-line">
|
||
Party progress · ${o.completed} of ${o.due} today
|
||
</span>
|
||
</div>
|
||
</div>
|
||
`}
|
||
</header>
|
||
`;
|
||
}
|
||
_renderColumn(e) {
|
||
const t = this._instances().filter(
|
||
(l) => l.window === e.key
|
||
), n = t.filter((l) => l.state === "open").sort(
|
||
(l, o) => (l.due_time ?? "99:99").localeCompare(o.due_time ?? "99:99")
|
||
), s = t.filter(
|
||
(l) => l.state === "completed"
|
||
), a = t.length;
|
||
let r = g;
|
||
if (a > 0) {
|
||
const o = 644 - (e.key === "afternoon" && this._otherChildren().length > 0 ? 160 : 0), p = Math.min(
|
||
24,
|
||
Math.max(8, Math.floor((o - a * 74) / Math.max(a - 1, 1)))
|
||
), u = Math.min(
|
||
116,
|
||
Math.max(58, Math.floor((o - (a - 1) * p) / a))
|
||
), c = Math.max(56, Math.min(72, u - 2));
|
||
let f = `--nq-p-quest-gap: ${p}px; --nq-p-quest-min-height: ${u}px; --nq-p-button-height: ${c}px`;
|
||
if (a >= 5) {
|
||
const h = Math.max(0, Math.min(22, Math.floor((u - c - 2) / 2))), m = Math.max(44, Math.min(64, u - 2 * h - 2));
|
||
f += `; --nq-p-quest-pad: ${h}px; --nq-p-tile-size: ${m}px`;
|
||
}
|
||
r = f;
|
||
}
|
||
return d`
|
||
<section
|
||
class="column"
|
||
aria-label="${e.name} quests"
|
||
style=${r}
|
||
>
|
||
<div class="column-head">
|
||
${e.icon}
|
||
<div class="column-names">
|
||
<span class="column-name">${e.name}</span>
|
||
<span class="column-range">${e.range}</span>
|
||
</div>
|
||
<span class="column-count">${s.length}/${t.length}</span>
|
||
</div>
|
||
<div class="stack">
|
||
${Ie(
|
||
n,
|
||
(l) => l.id,
|
||
(l) => this._renderQuest(l, !1, 0)
|
||
)}
|
||
${Ie(
|
||
s,
|
||
(l) => l.id,
|
||
(l, o) => this._renderQuest(l, !0, o)
|
||
)}
|
||
${e.key === "afternoon" ? this._renderRollup() : g}
|
||
</div>
|
||
</section>
|
||
`;
|
||
}
|
||
_renderQuest(e, t, n) {
|
||
if (t) {
|
||
const r = je[n % je.length], l = e.completed_at ? ln(e.completed_at, this._timeZone()) : "";
|
||
return d`
|
||
<div class="quest sealed" data-instance-id=${e.id}>
|
||
<span class="tile" aria-hidden="true">${se}</span>
|
||
<div class="body">
|
||
<span class="quest-title">${e.title}</span>
|
||
<span class="meta">
|
||
${l ? `Claimed ${l}` : "Claimed"}
|
||
</span>
|
||
</div>
|
||
<span
|
||
class="seal"
|
||
aria-hidden="true"
|
||
style="--seal-rot: ${r}deg"
|
||
>
|
||
${D}
|
||
</span>
|
||
</div>
|
||
`;
|
||
}
|
||
const s = dn(e.due_time), a = e.overdue ? {
|
||
text: s ? `Overdue · due ${s}` : "Overdue",
|
||
late: !0
|
||
} : {
|
||
text: s ? `Due by ${s}` : "Due today",
|
||
late: !1
|
||
};
|
||
return d`
|
||
<div
|
||
class="quest tappable"
|
||
role="button"
|
||
tabindex="0"
|
||
data-instance-id=${e.id}
|
||
aria-label="Complete ${e.title}"
|
||
@click=${() => this._openConfirm(e.id)}
|
||
@keydown=${(r) => {
|
||
(r.key === "Enter" || r.key === " ") && (r.preventDefault(), this._openConfirm(e.id));
|
||
}}
|
||
>
|
||
<span class="tile" aria-hidden="true">${sn(e.icon, se)}</span>
|
||
<div class="body">
|
||
<span class="quest-title">${e.title}</span>
|
||
<span class="${a.late ? "meta late" : "meta"}">${a.text}</span>
|
||
</div>
|
||
<button
|
||
class="complete"
|
||
type="button"
|
||
@click=${() => this._openConfirm(e.id)}
|
||
>
|
||
${D}
|
||
<span>Complete</span>
|
||
</button>
|
||
</div>
|
||
`;
|
||
}
|
||
_renderRollup() {
|
||
const e = this._otherChildren();
|
||
if (e.length === 0)
|
||
return g;
|
||
const t = e.slice(0, 2).map((n) => n.present ? n.due > 0 && n.completed >= n.due ? `${n.name} has finished their log.` : n.due > n.completed ? `${n.name} has ${n.due - n.completed} quests left.` : `${n.name} has no quests today.` : n.returnsWeekday ? `${n.name} is on travels until ${n.returnsWeekday}.` : `${n.name} is on travels.`);
|
||
return d`
|
||
<div class="rollup">
|
||
<span class="rollup-label">Party roll-up</span>
|
||
<p class="rollup-body">${t.join(" ")}</p>
|
||
</div>
|
||
`;
|
||
}
|
||
_renderConfirm() {
|
||
if (this._confirm === null)
|
||
return g;
|
||
const e = this._instances().find(
|
||
(n) => n.id === this._confirm
|
||
);
|
||
if (!e)
|
||
return g;
|
||
const t = De.find((n) => n.key === e.window);
|
||
return d`
|
||
<div class="scrim" @click=${() => this._closeConfirm()}>
|
||
<div
|
||
class="dialog"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
@click=${(n) => n.stopPropagation()}
|
||
>
|
||
<div class="dialog-header">
|
||
<span class="dialog-tile" aria-hidden="true">${se}</span>
|
||
<div class="dialog-titles">
|
||
<span class="dialog-kicker">
|
||
${t?.name ?? "Quest"}
|
||
</span>
|
||
<span class="dialog-quest-title">${e.title}</span>
|
||
</div>
|
||
</div>
|
||
<p class="dialog-body">
|
||
Mark this quest complete? Once the seal is set, only a parent can
|
||
undo it.
|
||
</p>
|
||
<div class="dialog-buttons">
|
||
<button
|
||
class="confirm-button not-yet"
|
||
type="button"
|
||
@click=${() => this._closeConfirm()}
|
||
>
|
||
${vn}
|
||
<span>Not yet</span>
|
||
</button>
|
||
<button
|
||
class="confirm-button do-complete"
|
||
type="button"
|
||
@click=${() => this._confirmComplete()}
|
||
>
|
||
${D}
|
||
<span>Complete</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
_openConfirm(e) {
|
||
this._confirm = e, this._armConfirmTimer();
|
||
}
|
||
_closeConfirm() {
|
||
this._clearConfirmTimer(), this._confirm = null;
|
||
}
|
||
_confirmComplete() {
|
||
const e = this._confirm === null ? void 0 : this._instances().find(
|
||
(t) => t.id === this._confirm
|
||
);
|
||
this._closeConfirm(), !(!e || e.state !== "open") && this._completeQuest(e);
|
||
}
|
||
/** Seal first, ask the service second: the seal is stamped and the column
|
||
* re-sorted immediately (PANEL-SPEC §4); a service failure reverts the
|
||
* card and raises the parchment toast. */
|
||
async _completeQuest(e) {
|
||
if (this._optimistic.has(e.id))
|
||
return;
|
||
const t = (/* @__PURE__ */ new Date()).toISOString();
|
||
this._optimistic = new Map(this._optimistic).set(e.id, t);
|
||
try {
|
||
await this._callCompleteQuest(e);
|
||
} catch {
|
||
const n = new Map(this._optimistic);
|
||
n.delete(e.id), this._optimistic = n, this._showToast(
|
||
"NestQuest could not set the seal just now. Please try again."
|
||
);
|
||
}
|
||
}
|
||
async _callCompleteQuest(e) {
|
||
const t = this.hass;
|
||
if (typeof t?.callService != "function")
|
||
throw new Error("Home Assistant is not connected");
|
||
const n = this._actorChildId(e);
|
||
if (n === null)
|
||
throw new Error("The tapped adventurer is unknown");
|
||
await t.callService.call(t, "nestquest", "complete_quest", {
|
||
instance_id: e.id,
|
||
actor: "panel",
|
||
actor_child_id: n
|
||
});
|
||
}
|
||
/** The tapped profile (decision 9): the instance's own child_id, falling
|
||
* back to the due sensor's child-level attribute. */
|
||
_actorChildId(e) {
|
||
if (e.child_id !== null)
|
||
return e.child_id;
|
||
const t = this._childSlug(), n = y(
|
||
this._state(`sensor.nestquest_${t}_quests_due_today`)?.attributes?.child_id,
|
||
0
|
||
);
|
||
return n > 0 ? n : null;
|
||
}
|
||
_showToast(e) {
|
||
this._toast = e, this._clearToastTimer(), this._toastTimer = window.setTimeout(() => {
|
||
this._toastTimer = void 0, this._toast = null;
|
||
}, 6e3);
|
||
}
|
||
_clearToastTimer() {
|
||
this._toastTimer !== void 0 && (window.clearTimeout(this._toastTimer), this._toastTimer = void 0);
|
||
}
|
||
_armConfirmTimer() {
|
||
this._clearConfirmTimer(), this._confirmTimer = window.setTimeout(() => {
|
||
this._confirmTimer = void 0, this._closeConfirm();
|
||
}, this._confirmSeconds() * 1e3);
|
||
}
|
||
_clearConfirmTimer() {
|
||
this._confirmTimer !== void 0 && (window.clearTimeout(this._confirmTimer), this._confirmTimer = void 0);
|
||
}
|
||
_armIdle() {
|
||
this._clearIdle(), this._idleTimer = window.setTimeout(() => {
|
||
this._idleTimer = void 0, this._returnToBoard();
|
||
}, this._idleSeconds() * 1e3);
|
||
}
|
||
_clearIdle() {
|
||
this._idleTimer !== void 0 && (window.clearTimeout(this._idleTimer), this._idleTimer = void 0);
|
||
}
|
||
_armCompleteTimer() {
|
||
if (this._completeTimer === void 0) {
|
||
if (this._countdown === null && (this._countdown = this._completeSeconds()), this._countdown <= 0) {
|
||
this._returnToBoard();
|
||
return;
|
||
}
|
||
this._completeTimer = window.setInterval(() => {
|
||
const e = (this._countdown ?? 1) - 1;
|
||
if (e <= 0) {
|
||
this._countdown = 0, this._clearCompleteTimer(), this._returnToBoard();
|
||
return;
|
||
}
|
||
this._countdown = e;
|
||
}, 1e3);
|
||
}
|
||
}
|
||
_clearCompleteTimer() {
|
||
this._completeTimer !== void 0 && (window.clearInterval(this._completeTimer), this._completeTimer = void 0);
|
||
}
|
||
_optionalNumber(e) {
|
||
if (e == null || e === "")
|
||
return null;
|
||
const t = typeof e == "number" ? e : Number(e);
|
||
return Number.isFinite(t) ? t : null;
|
||
}
|
||
_dockWeather() {
|
||
const e = w(this._config?.weather_entity);
|
||
if (!e)
|
||
return null;
|
||
const t = this._state(e);
|
||
if (!t)
|
||
return null;
|
||
const n = String(t.state ?? "").trim();
|
||
if (!n || n === "unavailable" || n === "unknown")
|
||
return null;
|
||
const s = t.attributes ?? {};
|
||
let a = null, r = null;
|
||
const l = s.forecast;
|
||
if (Array.isArray(l) && l.length > 0) {
|
||
const o = l[0];
|
||
if (o && typeof o == "object") {
|
||
const p = o;
|
||
a = this._optionalNumber(p.temperature), r = this._optionalNumber(p.templow);
|
||
}
|
||
}
|
||
return {
|
||
condition: n,
|
||
temperature: this._optionalNumber(s.temperature),
|
||
high: a,
|
||
low: r
|
||
};
|
||
}
|
||
_renderDock() {
|
||
const e = this._dockWeather();
|
||
if (!e)
|
||
return d`
|
||
<div class="dock">
|
||
<span class="date">${j(this._now, this._timeZone())}</span>
|
||
<span class="divider"></span>
|
||
<span class="clock">${cn(this._now, this._timeZone())}</span>
|
||
</div>
|
||
`;
|
||
const t = gn(e.condition), n = _n(e.condition, t), s = e.temperature === null ? g : d`<span class="temp">${Math.round(e.temperature)}°</span>`, a = e.high === null || e.low === null ? null : `${Math.round(e.high)}° / ${Math.round(e.low)}°`;
|
||
return d`
|
||
<div class="dock">
|
||
${An}
|
||
${s}
|
||
<span class="divider"></span>
|
||
<span class="condition">
|
||
${a === null ? t : `${t} · ${a}`}
|
||
</span>
|
||
<span class="divider"></span>
|
||
<span class="condition">${n}</span>
|
||
</div>
|
||
`;
|
||
}
|
||
_returnToBoard() {
|
||
const e = this._boardPath();
|
||
e && (window.history.pushState(null, "", e), window.dispatchEvent(new Event("location-changed")));
|
||
}
|
||
_stopClock() {
|
||
this._clockTimer !== void 0 && (window.clearInterval(this._clockTimer), this._clockTimer = void 0);
|
||
}
|
||
};
|
||
W.properties = {
|
||
hass: { attribute: !1 },
|
||
_config: { state: !0 },
|
||
_now: { state: !0 },
|
||
_confirm: { state: !0 },
|
||
_optimistic: { state: !0 },
|
||
_toast: { state: !0 },
|
||
_countdown: { state: !0 }
|
||
}, W.styles = [x(Xe), bn];
|
||
let oe = W;
|
||
customElements.define("nestquest-quest-log-card", oe);
|
||
fe({
|
||
type: "nestquest-quest-log-card",
|
||
name: "NestQuest Quest Log",
|
||
description: "One child's daily quests, grouped by window."
|
||
});
|
||
const En = ":host{--nq-brand-blue: #3B3AB8;--nq-brand-purple: #A035CC;--nq-brand-gradient: linear-gradient(135deg, var(--nq-brand-blue), var(--nq-brand-purple));--nq-brand-gradient-h: linear-gradient(90deg, var(--nq-brand-blue), var(--nq-brand-purple));--nq-a-page: #F4F4F6;--nq-a-surface: #FFFFFF;--nq-a-surface-subtle: #FAFAFA;--nq-a-selected: #EBEBF8;--nq-a-border: #E4E4EA;--nq-a-divider: #EDEDF1;--nq-a-ink: #18181D;--nq-a-ink-secondary: #52525E;--nq-a-ink-tertiary: #70707E;--nq-a-success: #15803D;--nq-a-danger: #DC2626;--nq-a-danger-strong: #B91C1C;--nq-a-danger-bg: #FEE2E2;--nq-a-warning-ink: #92400E;--nq-a-warning-ink-2: #78350F;--nq-a-warning-bg: #FEF3C7;--nq-a-warning-border: rgba(217,119,6,.35);--nq-a-info-bg: #DBEAFE;--nq-a-info-ink: #1E3A8A;--nq-a-info-icon: #1D4ED8;--nq-a-reversal: #7D28A0;--nq-a-font: Nunito, system-ui, sans-serif;--nq-a-size-screen: 24px;--nq-a-size-hero: 32px;--nq-a-size-card-title: 19px;--nq-a-size-stat: 22px;--nq-a-size-row: 13.5px;--nq-a-size-meta: 11px;--nq-a-size-label: 10px;--nq-a-track-label: .1em;--nq-a-density-page-pad: 14px 16px 92px;--nq-a-density-gap: 10px;--nq-a-density-card-pad: 13px;--nq-a-density-row-pad: 11px 13px;--nq-a-density-radius: 8px;--nq-a-density-shadow: none;--nq-a-tabbar-height: 70px;--nq-a-tap-min: 44px;--nq-a-radius-pill: 9999px;--nq-a-radius-sheet: 20px 20px 0 0;--nq-a-sheet-shadow: 0 -8px 28px rgba(9,9,11,.18);--nq-a-progress-height: 6px;--nq-ease-out: cubic-bezier(0, 0, .2, 1);--nq-dur-micro: .12s;--nq-dur-base: .2s;--nq-dur-modal: .35s}", G = class G extends C {
|
||
setConfig(e) {
|
||
if (!e || typeof e != "object")
|
||
throw new Error("Invalid configuration");
|
||
this._config = e;
|
||
}
|
||
getCardSize() {
|
||
return 8;
|
||
}
|
||
render() {
|
||
return d`<div>NestQuest Admin</div>`;
|
||
}
|
||
};
|
||
G.properties = {
|
||
hass: { attribute: !1 },
|
||
_config: { state: !0 }
|
||
}, G.styles = [x(En)];
|
||
let le = G;
|
||
customElements.define("nestquest-admin-card", le);
|
||
fe({
|
||
type: "nestquest-admin-card",
|
||
name: "NestQuest Admin",
|
||
description: "Parent phone view for today, tasks, schedule, and history."
|
||
});
|
||
function et(i) {
|
||
return typeof i == "string" ? i.trim() : "";
|
||
}
|
||
function Nn(i) {
|
||
if (i === null || typeof i != "object" || Array.isArray(i))
|
||
return "";
|
||
const e = i.slug;
|
||
return typeof e == "string" ? e.trim() : "";
|
||
}
|
||
function Ln(i) {
|
||
const e = et(i.url_path).replace(/^\/+|\/+$/g, "");
|
||
return e || (window.location.pathname.split("/").filter(Boolean)[0] ?? "");
|
||
}
|
||
function On(i) {
|
||
if (i === null || typeof i != "object" || Array.isArray(i))
|
||
return "";
|
||
const e = i.name;
|
||
return typeof e == "string" ? e.trim() : "";
|
||
}
|
||
function Bn(i) {
|
||
const n = i?.states?.["sensor.nestquest_household_quests_due_today"]?.attributes?.child_roster;
|
||
return Array.isArray(n) ? n.map((s) => ({ slug: Nn(s), name: On(s) })).filter((s) => s.slug.length > 0) : [];
|
||
}
|
||
class In {
|
||
static async generate(e, t) {
|
||
const n = `/${Ln(e)}`, s = et(e.weather_entity), a = {
|
||
type: "custom:nestquest-party-board-card",
|
||
quest_log_path: n
|
||
};
|
||
s && (a.weather_entity = s);
|
||
const r = {
|
||
type: "custom:nestquest-quest-log-card",
|
||
board_path: n
|
||
};
|
||
return s && (r.weather_entity = s), {
|
||
views: [
|
||
{
|
||
path: "party",
|
||
title: "The Party",
|
||
type: "panel",
|
||
cards: [a]
|
||
},
|
||
...Bn(t).map((l) => ({
|
||
path: l.slug,
|
||
title: l.name ? `${l.name}'s Quest Log` : `${l.slug}'s Quest Log`,
|
||
type: "panel",
|
||
cards: [{ ...r }]
|
||
}))
|
||
]
|
||
};
|
||
}
|
||
}
|
||
window.customStrategies = window.customStrategies ?? {};
|
||
window.customStrategies["nestquest-party"] = In;
|
||
const Pn = "/nestquest-static/nestquest-fonts.css";
|
||
if (!document.querySelector('link[data-nq-fonts=""]')) {
|
||
const i = document.createElement("link");
|
||
i.rel = "stylesheet", i.href = Pn, i.dataset.nqFonts = "", document.head.appendChild(i);
|
||
}
|