@matter-server/dashboard 0.2.5 → 0.2.7-alpha.0-20260118-993a1c7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +16 -0
  2. package/dist/esm/client/models/descriptions.js +1754 -1754
  3. package/dist/esm/components/dialogs/binding/node-binding-dialog.d.ts.map +1 -1
  4. package/dist/esm/components/dialogs/binding/node-binding-dialog.js +8 -4
  5. package/dist/esm/components/dialogs/binding/node-binding-dialog.js.map +1 -1
  6. package/dist/esm/entrypoint/main.d.ts +1 -1
  7. package/dist/esm/entrypoint/main.d.ts.map +1 -1
  8. package/dist/esm/entrypoint/main.js +1 -0
  9. package/dist/esm/entrypoint/main.js.map +1 -1
  10. package/dist/esm/pages/components/header.d.ts +8 -0
  11. package/dist/esm/pages/components/header.d.ts.map +1 -1
  12. package/dist/esm/pages/components/header.js +56 -6
  13. package/dist/esm/pages/components/header.js.map +1 -1
  14. package/dist/esm/pages/components/node-details.d.ts.map +1 -1
  15. package/dist/esm/pages/components/node-details.js +27 -8
  16. package/dist/esm/pages/components/node-details.js.map +2 -2
  17. package/dist/esm/pages/matter-cluster-view.d.ts.map +1 -1
  18. package/dist/esm/pages/matter-cluster-view.js +3 -2
  19. package/dist/esm/pages/matter-cluster-view.js.map +1 -1
  20. package/dist/esm/pages/matter-dashboard-app.d.ts +6 -1
  21. package/dist/esm/pages/matter-dashboard-app.d.ts.map +1 -1
  22. package/dist/esm/pages/matter-dashboard-app.js +119 -24
  23. package/dist/esm/pages/matter-dashboard-app.js.map +1 -1
  24. package/dist/esm/pages/matter-endpoint-view.d.ts.map +1 -1
  25. package/dist/esm/pages/matter-endpoint-view.js +2 -1
  26. package/dist/esm/pages/matter-endpoint-view.js.map +1 -1
  27. package/dist/esm/util/format_hex.d.ts +17 -0
  28. package/dist/esm/util/format_hex.d.ts.map +1 -0
  29. package/dist/esm/util/format_hex.js +18 -0
  30. package/dist/esm/util/format_hex.js.map +6 -0
  31. package/dist/esm/util/theme-service.d.ts +27 -0
  32. package/dist/esm/util/theme-service.d.ts.map +1 -0
  33. package/dist/esm/util/theme-service.js +71 -0
  34. package/dist/esm/util/theme-service.js.map +6 -0
  35. package/dist/web/index.html +35 -0
  36. package/dist/web/js/{commission-node-dialog-30lGnJcb.js → commission-node-dialog-DGw5qDgH.js} +5 -5
  37. package/dist/web/js/{commission-node-existing-RgaziosB.js → commission-node-existing-CHyyeC8y.js} +4 -4
  38. package/dist/web/js/{commission-node-thread-CJn6OYQX.js → commission-node-thread-iRDSlidy.js} +4 -4
  39. package/dist/web/js/{commission-node-wifi-CCBBvBEh.js → commission-node-wifi-C4YNR3bG.js} +4 -4
  40. package/dist/web/js/{dialog-box-CFO9GMyG.js → dialog-box-ag-xOaYh.js} +2 -2
  41. package/dist/web/js/{fire_event-CdvT7FSP.js → fire_event-BeiEbHcE.js} +1 -1
  42. package/dist/web/js/main.js +140 -8
  43. package/dist/web/js/{matter-dashboard-app-DwI2RvT1.js → matter-dashboard-app-BxQ4W_uT.js} +3652 -3483
  44. package/dist/web/js/{node-binding-dialog-CmTgtqz1.js → node-binding-dialog-ClziphM0.js} +11 -7
  45. package/dist/web/js/{outlined-text-field-DeeCilzP.js → outlined-text-field-B-CiqgEJ.js} +2 -2
  46. package/dist/web/js/{prevent_default--haJaAsZ.js → prevent_default-Bs2sUnny.js} +1 -1
  47. package/package.json +3 -3
  48. package/src/client/models/descriptions.ts +1754 -1754
  49. package/src/components/dialogs/binding/node-binding-dialog.ts +8 -4
  50. package/src/entrypoint/main.ts +1 -0
  51. package/src/pages/components/header.ts +57 -8
  52. package/src/pages/components/node-details.ts +33 -8
  53. package/src/pages/matter-cluster-view.ts +3 -2
  54. package/src/pages/matter-dashboard-app.ts +123 -26
  55. package/src/pages/matter-endpoint-view.ts +2 -1
  56. package/src/util/format_hex.ts +30 -0
  57. package/src/util/theme-service.ts +98 -0
@@ -23,6 +23,7 @@ import { customElement, property } from "lit/decorators.js";
23
23
  import { guard } from "lit/directives/guard.js";
24
24
  import { clusters, device_types } from "../client/models/descriptions.js";
25
25
  import "../components/ha-svg-icon";
26
+ import { formatHex } from "../util/format_hex.js";
26
27
  function getUniqueClusters(node, endpoint) {
27
28
  return Array.from(
28
29
  new Set(
@@ -83,7 +84,7 @@ let MatterEndpointView = class extends LitElement {
83
84
  href=${`#node/${this.node.node_id}/${this.endpoint}/${cluster}`}
84
85
  >
85
86
  <div slot="headline">${clusters[cluster]?.label || "Custom/Unknown Cluster"}</div>
86
- <div slot="supporting-text">ClusterId ${cluster} (0x00${cluster.toString(16)})</div>
87
+ <div slot="supporting-text">ClusterId ${cluster} (${formatHex(cluster)})</div>
87
88
  <ha-svg-icon slot="end" .path=${mdiChevronRight}></ha-svg-icon>
88
89
  </md-list-item>
89
90
  `;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/pages/matter-endpoint-view.ts"],
4
- "mappings": ";;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AAEP,SAAS,uBAAuB;AAChC,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AACxC,SAAS,aAAa;AACtB,SAAqB,UAAU,oBAAoB;AACnD,OAAO;AAQP,SAAS,kBAAkB,MAAkB,UAAkB;AAC3D,SAAO,MAAM;AAAA,IACT,IAAI;AAAA,MACA,OAAO,KAAK,KAAK,UAAU,EACtB,OAAO,SAAO,IAAI,WAAW,GAAG,SAAS,SAAS,CAAC,GAAG,CAAC,EACvD,IAAI,SAAO,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AAAA,IAC7C;AAAA,EACJ,EAAE,KAAK,CAAC,GAAG,MAAM;AACb,WAAO,IAAI;AAAA,EACf,CAAC;AACL;AAEO,SAAS,uBAAuB,MAAkB,UAAgC;AACrF,QAAM,YAAY,KAAK,WAAW,GAAG,QAAQ,OAAO;AACpD,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,SAAO,UAAU,IAAI,cAAY;AAC7B,UAAM,KAAK,SAAS,GAAG,KAAK,SAAS,YAAY;AACjD,WAAO,aAAa,EAAE,KAAK,EAAE,IAAI,MAAM,IAAI,OAAO,wBAAwB,EAAE,KAAK,UAAU,CAAC,EAAE;AAAA,EAClG,CAAC;AACL;AAGA,IAAM,qBAAN,cAAiC,WAAW;AAAA,EAS/B,SAAS;AACd,QAAI,CAAC,KAAK,QAAQ,KAAK,YAAY,QAAW;AAC1C,aAAO;AAAA;AAAA,iCAEc,KAAK,OAAO;AAAA;AAAA,IAErC;AAEA,WAAO;AAAA;AAAA,yBAEU,QAAQ,KAAK,KAAK,OAAO,iBAAiB,KAAK,QAAQ,EAAE;AAAA,8BACpD,SAAS,KAAK,KAAK,OAAO,EAAE;AAAA,0BAChC,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,sCAKC,KAAK,IAAI,YAAY,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAQhB,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,8BAIrC,uBAAuB,KAAK,MAAM,KAAK,QAAQ,EAC5C,IAAI,gBAAc;AACf,aAAO,WAAW;AAAA,IACtB,CAAC,EACA,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,sBAGtB;AAAA,MAAM,CAAC,KAAK,MAAM,WAAW,MAAM;AAAA,MAAG,MACpC,kBAAkB,KAAK,MAAO,KAAK,QAAS,EAAE,IAAI,aAAW;AACzD,eAAO;AAAA;AAAA;AAAA,2CAGQ,SAAS,KAAK,KAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,EAAE;AAAA;AAAA,2DAEzC,SAAS,OAAO,GAAG,SAAS,wBAAwB;AAAA,4EACnC,OAAO,SAAS,QAAQ,SAAS,EAAE,CAAC;AAAA,oEAC5C,eAAe;AAAA;AAAA;AAAA,MAG3D,CAAC;AAAA,IACL,CAAC;AAAA;AAAA;AAAA;AAAA,EAIjB;AAAA,EAEQ,UAAU;AACd,YAAQ,KAAK;AAAA,EACjB;AAuCJ;AAzGM,mBAoEc,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAhElB;AAAA,EADN,SAAS;AAAA,GAHR,mBAIK;AAGA;AAAA,EADN,SAAS;AAAA,GANR,mBAOK;AAPL,qBAAN;AAAA,EADC,cAAc,sBAAsB;AAAA,GAC/B;",
4
+ "mappings": ";;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AAEP,SAAS,uBAAuB;AAChC,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AACxC,SAAS,aAAa;AACtB,SAAqB,UAAU,oBAAoB;AACnD,OAAO;AACP,SAAS,iBAAiB;AAQ1B,SAAS,kBAAkB,MAAkB,UAAkB;AAC3D,SAAO,MAAM;AAAA,IACT,IAAI;AAAA,MACA,OAAO,KAAK,KAAK,UAAU,EACtB,OAAO,SAAO,IAAI,WAAW,GAAG,SAAS,SAAS,CAAC,GAAG,CAAC,EACvD,IAAI,SAAO,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AAAA,IAC7C;AAAA,EACJ,EAAE,KAAK,CAAC,GAAG,MAAM;AACb,WAAO,IAAI;AAAA,EACf,CAAC;AACL;AAEO,SAAS,uBAAuB,MAAkB,UAAgC;AACrF,QAAM,YAAY,KAAK,WAAW,GAAG,QAAQ,OAAO;AACpD,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,SAAO,UAAU,IAAI,cAAY;AAC7B,UAAM,KAAK,SAAS,GAAG,KAAK,SAAS,YAAY;AACjD,WAAO,aAAa,EAAE,KAAK,EAAE,IAAI,MAAM,IAAI,OAAO,wBAAwB,EAAE,KAAK,UAAU,CAAC,EAAE;AAAA,EAClG,CAAC;AACL;AAGA,IAAM,qBAAN,cAAiC,WAAW;AAAA,EAS/B,SAAS;AACd,QAAI,CAAC,KAAK,QAAQ,KAAK,YAAY,QAAW;AAC1C,aAAO;AAAA;AAAA,iCAEc,KAAK,OAAO;AAAA;AAAA,IAErC;AAEA,WAAO;AAAA;AAAA,yBAEU,QAAQ,KAAK,KAAK,OAAO,iBAAiB,KAAK,QAAQ,EAAE;AAAA,8BACpD,SAAS,KAAK,KAAK,OAAO,EAAE;AAAA,0BAChC,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,sCAKC,KAAK,IAAI,YAAY,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAQhB,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,8BAIrC,uBAAuB,KAAK,MAAM,KAAK,QAAQ,EAC5C,IAAI,gBAAc;AACf,aAAO,WAAW;AAAA,IACtB,CAAC,EACA,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,sBAGtB;AAAA,MAAM,CAAC,KAAK,MAAM,WAAW,MAAM;AAAA,MAAG,MACpC,kBAAkB,KAAK,MAAO,KAAK,QAAS,EAAE,IAAI,aAAW;AACzD,eAAO;AAAA;AAAA;AAAA,2CAGQ,SAAS,KAAK,KAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,EAAE;AAAA;AAAA,2DAEzC,SAAS,OAAO,GAAG,SAAS,wBAAwB;AAAA,4EACnC,OAAO,KAAK,UAAU,OAAO,CAAC;AAAA,oEACtC,eAAe;AAAA;AAAA;AAAA,MAG3D,CAAC;AAAA,IACL,CAAC;AAAA;AAAA;AAAA;AAAA,EAIjB;AAAA,EAEQ,UAAU;AACd,YAAQ,KAAK;AAAA,EACjB;AAuCJ;AAzGM,mBAoEc,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAhElB;AAAA,EADN,SAAS;AAAA,GAHR,mBAIK;AAGA;AAAA,EADN,SAAS;AAAA,GANR,mBAOK;AAPL,qBAAN;AAAA,EADC,cAAc,sBAAsB;AAAA,GAC/B;",
5
5
  "names": []
6
6
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025-2026 Open Home Foundation
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Format a number as a hex string with 0x prefix.
8
+ * Ensures even number of digits with a minimum of 4 digits.
9
+ *
10
+ * Examples:
11
+ * 0 -> "0x0000"
12
+ * 255 -> "0x00FF"
13
+ * 65535 -> "0xFFFF"
14
+ * 65536 -> "0x010000"
15
+ */
16
+ export declare function formatHex(value: number): string;
17
+ //# sourceMappingURL=format_hex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format_hex.d.ts","sourceRoot":"","sources":["../../../src/util/format_hex.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAa/C"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025-2026 Open Home Foundation
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ function formatHex(value) {
7
+ let hex = value.toString(16).toUpperCase();
8
+ if (hex.length < 4) {
9
+ hex = hex.padStart(4, "0");
10
+ } else if (hex.length % 2 !== 0) {
11
+ hex = "0" + hex;
12
+ }
13
+ return `0x${hex}`;
14
+ }
15
+ export {
16
+ formatHex
17
+ };
18
+ //# sourceMappingURL=format_hex.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/util/format_hex.ts"],
4
+ "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAgBO,SAAS,UAAU,OAAuB;AAC7C,MAAI,MAAM,MAAM,SAAS,EAAE,EAAE,YAAY;AAGzC,MAAI,IAAI,SAAS,GAAG;AAChB,UAAM,IAAI,SAAS,GAAG,GAAG;AAAA,EAC7B,WAES,IAAI,SAAS,MAAM,GAAG;AAC3B,UAAM,MAAM;AAAA,EAChB;AAEA,SAAO,KAAK,GAAG;AACnB;",
5
+ "names": []
6
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025-2026 Open Home Foundation
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Theme service for managing dark/light mode preferences.
8
+ * Supports three modes: light, dark, and system (auto-detect from OS).
9
+ */
10
+ export type ThemePreference = "light" | "dark" | "system";
11
+ export type EffectiveTheme = "light" | "dark";
12
+ declare class ThemeServiceImpl {
13
+ private _preference;
14
+ private _mediaQuery;
15
+ private _listeners;
16
+ constructor();
17
+ get preference(): ThemePreference;
18
+ get effectiveTheme(): EffectiveTheme;
19
+ setPreference(pref: ThemePreference): void;
20
+ cycleTheme(): ThemePreference;
21
+ subscribe(callback: (theme: EffectiveTheme) => void): () => void;
22
+ private _loadPreference;
23
+ private _applyTheme;
24
+ }
25
+ export declare const ThemeService: ThemeServiceImpl;
26
+ export {};
27
+ //# sourceMappingURL=theme-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-service.d.ts","sourceRoot":"","sources":["../../../src/util/theme-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AAEH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAC1D,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,CAAC;AAI9C,cAAM,gBAAgB;IAClB,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,UAAU,CAAmD;;IASrE,IAAI,UAAU,IAAI,eAAe,CAEhC;IAED,IAAI,cAAc,IAAI,cAAc,CAKnC;IAED,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAM1C,UAAU,IAAI,eAAe;IAQ7B,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAKhE,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,WAAW;CAYtB;AAED,eAAO,MAAM,YAAY,kBAAyB,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025-2026 Open Home Foundation
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ const STORAGE_KEY = "matterTheme";
7
+ class ThemeServiceImpl {
8
+ constructor() {
9
+ this._preference = "system";
10
+ this._listeners = /* @__PURE__ */ new Set();
11
+ this._mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
12
+ this._mediaQuery.addEventListener("change", () => this._applyTheme());
13
+ this._loadPreference();
14
+ this._applyTheme();
15
+ }
16
+ get preference() {
17
+ return this._preference;
18
+ }
19
+ get effectiveTheme() {
20
+ if (this._preference === "system") {
21
+ return this._mediaQuery.matches ? "dark" : "light";
22
+ }
23
+ return this._preference;
24
+ }
25
+ setPreference(pref) {
26
+ this._preference = pref;
27
+ localStorage.setItem(STORAGE_KEY, pref);
28
+ this._applyTheme();
29
+ }
30
+ cycleTheme() {
31
+ const cycle = ["light", "dark", "system"];
32
+ const currentIndex = cycle.indexOf(this._preference);
33
+ const nextIndex = (currentIndex + 1) % cycle.length;
34
+ this.setPreference(cycle[nextIndex]);
35
+ return this._preference;
36
+ }
37
+ subscribe(callback) {
38
+ this._listeners.add(callback);
39
+ return () => this._listeners.delete(callback);
40
+ }
41
+ _loadPreference() {
42
+ const urlParams = new URLSearchParams(window.location.search);
43
+ const themeParam = urlParams.get("theme");
44
+ if (themeParam && ["light", "dark", "system"].includes(themeParam)) {
45
+ this._preference = themeParam;
46
+ localStorage.setItem(STORAGE_KEY, themeParam);
47
+ urlParams.delete("theme");
48
+ const newUrl = urlParams.toString() ? `${window.location.pathname}?${urlParams.toString()}${window.location.hash}` : `${window.location.pathname}${window.location.hash}`;
49
+ history.replaceState({}, "", newUrl);
50
+ return;
51
+ }
52
+ const stored = localStorage.getItem(STORAGE_KEY);
53
+ if (stored && ["light", "dark", "system"].includes(stored)) {
54
+ this._preference = stored;
55
+ }
56
+ }
57
+ _applyTheme() {
58
+ const effective = this.effectiveTheme;
59
+ document.documentElement.classList.toggle("dark-theme", effective === "dark");
60
+ const metaThemeColor = document.querySelector('meta[name="theme-color"]');
61
+ if (metaThemeColor) {
62
+ metaThemeColor.setAttribute("content", effective === "dark" ? "#1e1e1e" : "#03a9f4");
63
+ }
64
+ this._listeners.forEach((cb) => cb(effective));
65
+ }
66
+ }
67
+ const ThemeService = new ThemeServiceImpl();
68
+ export {
69
+ ThemeService
70
+ };
71
+ //# sourceMappingURL=theme-service.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/util/theme-service.ts"],
4
+ "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,MAAM,cAAc;AAEpB,MAAM,iBAAiB;AAAA,EAKnB,cAAc;AAJd,SAAQ,cAA+B;AAEvC,SAAQ,aAAmD,oBAAI,IAAI;AAG/D,SAAK,cAAc,OAAO,WAAW,8BAA8B;AACnE,SAAK,YAAY,iBAAiB,UAAU,MAAM,KAAK,YAAY,CAAC;AACpE,SAAK,gBAAgB;AACrB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,IAAI,aAA8B;AAC9B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,iBAAiC;AACjC,QAAI,KAAK,gBAAgB,UAAU;AAC/B,aAAO,KAAK,YAAY,UAAU,SAAS;AAAA,IAC/C;AACA,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,cAAc,MAA6B;AACvC,SAAK,cAAc;AACnB,iBAAa,QAAQ,aAAa,IAAI;AACtC,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,aAA8B;AAC1B,UAAM,QAA2B,CAAC,SAAS,QAAQ,QAAQ;AAC3D,UAAM,eAAe,MAAM,QAAQ,KAAK,WAAW;AACnD,UAAM,aAAa,eAAe,KAAK,MAAM;AAC7C,SAAK,cAAc,MAAM,SAAS,CAAC;AACnC,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAU,UAAuD;AAC7D,SAAK,WAAW,IAAI,QAAQ;AAC5B,WAAO,MAAM,KAAK,WAAW,OAAO,QAAQ;AAAA,EAChD;AAAA,EAEQ,kBAAwB;AAE5B,UAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,UAAM,aAAa,UAAU,IAAI,OAAO;AACxC,QAAI,cAAc,CAAC,SAAS,QAAQ,QAAQ,EAAE,SAAS,UAAU,GAAG;AAEhE,WAAK,cAAc;AACnB,mBAAa,QAAQ,aAAa,UAAU;AAE5C,gBAAU,OAAO,OAAO;AACxB,YAAM,SAAS,UAAU,SAAS,IAC5B,GAAG,OAAO,SAAS,QAAQ,IAAI,UAAU,SAAS,CAAC,GAAG,OAAO,SAAS,IAAI,KAC1E,GAAG,OAAO,SAAS,QAAQ,GAAG,OAAO,SAAS,IAAI;AACxD,cAAQ,aAAa,CAAC,GAAG,IAAI,MAAM;AACnC;AAAA,IACJ;AAGA,UAAM,SAAS,aAAa,QAAQ,WAAW;AAC/C,QAAI,UAAU,CAAC,SAAS,QAAQ,QAAQ,EAAE,SAAS,MAAM,GAAG;AACxD,WAAK,cAAc;AAAA,IACvB;AAAA,EAEJ;AAAA,EAEQ,cAAoB;AACxB,UAAM,YAAY,KAAK;AACvB,aAAS,gBAAgB,UAAU,OAAO,cAAc,cAAc,MAAM;AAG5E,UAAM,iBAAiB,SAAS,cAAc,0BAA0B;AACxE,QAAI,gBAAgB;AAChB,qBAAe,aAAa,WAAW,cAAc,SAAS,YAAY,SAAS;AAAA,IACvF;AAEA,SAAK,WAAW,QAAQ,QAAM,GAAG,SAAS,CAAC;AAAA,EAC/C;AACJ;AAEO,MAAM,eAAe,IAAI,iBAAiB;",
5
+ "names": []
6
+ }
@@ -17,11 +17,18 @@
17
17
  --md-ref-typeface-plain: var(--roboto-font);
18
18
 
19
19
  --md-sys-color-background: #f5f5f5;
20
+ --md-sys-color-on-background: #1c1b1f;
20
21
  --md-sys-color-surface: #fff;
22
+ --md-sys-color-on-surface: #1c1b1f;
23
+ --md-sys-color-on-surface-variant: #49454f;
24
+ --md-sys-color-surface-variant: #e7e0ec;
21
25
  --md-sys-color-surface-container: #fff;
26
+ --md-sys-color-surface-container-low: #f7f2fa;
22
27
  --md-sys-color-surface-container-high: #fff;
23
28
  --md-sys-color-surface-container-highest: #f5f5f5;
24
29
  --md-sys-color-secondary-container: #e0e0e0;
30
+ --md-sys-color-outline: #79747e;
31
+ --md-sys-color-outline-variant: #cac4d0;
25
32
 
26
33
  --md-sys-typescale-headline-font: var(--roboto-font);
27
34
  --md-sys-typescale-title-font: var(--roboto-font);
@@ -31,9 +38,37 @@
31
38
  font-family: var(--roboto-font);
32
39
  }
33
40
 
41
+ body {
42
+ --primary-color: var(--md-sys-color-primary);
43
+ }
44
+
34
45
  a {
35
46
  color: var(--primary-color);
36
47
  }
48
+
49
+ /* Dark theme overrides */
50
+ html.dark-theme body {
51
+ --md-sys-color-primary: #4fc3f7;
52
+ --md-sys-color-on-primary: #003544;
53
+ --md-sys-color-background: #121212;
54
+ --md-sys-color-on-background: #e6e1e5;
55
+ --md-sys-color-surface: #1e1e1e;
56
+ --md-sys-color-on-surface: #e6e1e5;
57
+ --md-sys-color-on-surface-variant: #cac4d0;
58
+ --md-sys-color-surface-variant: #49454f;
59
+ --md-sys-color-surface-container: #1e1e1e;
60
+ --md-sys-color-surface-container-low: #1a1a1a;
61
+ --md-sys-color-surface-container-high: #2b2b2b;
62
+ --md-sys-color-surface-container-highest: #363636;
63
+ --md-sys-color-secondary-container: #4a4458;
64
+ --md-sys-color-on-secondary-container: #e8def8;
65
+ --md-sys-color-outline: #938f99;
66
+ --md-sys-color-outline-variant: #49454f;
67
+ --text-color: rgba(255, 255, 255, 0.6);
68
+ --danger-color: #ff7961;
69
+ --primary-color: #4fc3f7;
70
+ color-scheme: dark;
71
+ }
37
72
  </style>
38
73
  </head>
39
74
  <body></body>
@@ -1,5 +1,5 @@
1
- import { r, n, t, i, b } from './matter-dashboard-app-DwI2RvT1.js';
2
- import { p as preventDefault } from './prevent_default--haJaAsZ.js';
1
+ import { r, n, t, i, b } from './matter-dashboard-app-BxQ4W_uT.js';
2
+ import { p as preventDefault } from './prevent_default-Bs2sUnny.js';
3
3
  import './main.js';
4
4
 
5
5
  var __defProp = Object.defineProperty;
@@ -44,18 +44,18 @@ let ComissionNodeDialog = class extends i {
44
44
  if (!this.client.serverInfo.bluetooth_enabled) {
45
45
  return;
46
46
  }
47
- import('./commission-node-wifi-CCBBvBEh.js');
47
+ import('./commission-node-wifi-C4YNR3bG.js');
48
48
  this._mode = "wifi";
49
49
  }
50
50
  _commissionThread() {
51
51
  if (!this.client.serverInfo.bluetooth_enabled) {
52
52
  return;
53
53
  }
54
- import('./commission-node-thread-CJn6OYQX.js');
54
+ import('./commission-node-thread-iRDSlidy.js');
55
55
  this._mode = "thread";
56
56
  }
57
57
  _commissionExisting() {
58
- import('./commission-node-existing-RgaziosB.js');
58
+ import('./commission-node-existing-CHyyeC8y.js');
59
59
  this._mode = "existing";
60
60
  }
61
61
  _nodeCommissioned(ev) {
@@ -1,8 +1,8 @@
1
- import { r, c, n, d as clientContext, e, t, i, A, b } from './matter-dashboard-app-DwI2RvT1.js';
2
- import { f as fireEvent } from './fire_event-CdvT7FSP.js';
3
- import './outlined-text-field-DeeCilzP.js';
1
+ import { r, c, n, d as clientContext, e, t, i, A, b } from './matter-dashboard-app-BxQ4W_uT.js';
2
+ import { f as fireEvent } from './fire_event-BeiEbHcE.js';
3
+ import './outlined-text-field-B-CiqgEJ.js';
4
4
  import './main.js';
5
- import './prevent_default--haJaAsZ.js';
5
+ import './prevent_default-Bs2sUnny.js';
6
6
 
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1,8 +1,8 @@
1
- import { r, c, n, d as clientContext, e, t, i, A, b } from './matter-dashboard-app-DwI2RvT1.js';
2
- import { f as fireEvent } from './fire_event-CdvT7FSP.js';
3
- import './outlined-text-field-DeeCilzP.js';
1
+ import { r, c, n, d as clientContext, e, t, i, A, b } from './matter-dashboard-app-BxQ4W_uT.js';
2
+ import { f as fireEvent } from './fire_event-BeiEbHcE.js';
3
+ import './outlined-text-field-B-CiqgEJ.js';
4
4
  import './main.js';
5
- import './prevent_default--haJaAsZ.js';
5
+ import './prevent_default-Bs2sUnny.js';
6
6
 
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1,8 +1,8 @@
1
- import { r, c, n, d as clientContext, e, t, i, A, b } from './matter-dashboard-app-DwI2RvT1.js';
2
- import { f as fireEvent } from './fire_event-CdvT7FSP.js';
3
- import './outlined-text-field-DeeCilzP.js';
1
+ import { r, c, n, d as clientContext, e, t, i, A, b } from './matter-dashboard-app-BxQ4W_uT.js';
2
+ import { f as fireEvent } from './fire_event-BeiEbHcE.js';
3
+ import './outlined-text-field-B-CiqgEJ.js';
4
4
  import './main.js';
5
- import './prevent_default--haJaAsZ.js';
5
+ import './prevent_default-Bs2sUnny.js';
6
6
 
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1,5 +1,5 @@
1
- import { n, t, i, b } from './matter-dashboard-app-DwI2RvT1.js';
2
- import { p as preventDefault } from './prevent_default--haJaAsZ.js';
1
+ import { n, t, i, b } from './matter-dashboard-app-BxQ4W_uT.js';
2
+ import { p as preventDefault } from './prevent_default-Bs2sUnny.js';
3
3
  import './main.js';
4
4
 
5
5
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- import { m as mixinDelegatesAria, i, _ as __decorate, n, f as e, A, b, a as i$1, t } from './matter-dashboard-app-DwI2RvT1.js';
1
+ import { m as mixinDelegatesAria, i, _ as __decorate, n, f as e, A, b, a as i$1, t } from './matter-dashboard-app-BxQ4W_uT.js';
2
2
 
3
3
  /**
4
4
  * @license
@@ -31,13 +31,77 @@ function toBigIntAwareJson(value, spaces) {
31
31
  return result;
32
32
  }
33
33
  function parseBigIntAwareJson(json) {
34
- const processed = json.replace(/([:,[])\s*(\d{15,})(?=[,}\]\s])/g, (match, prefix, number) => {
35
- const num = BigInt(number);
36
- if (num > Number.MAX_SAFE_INTEGER) {
37
- return `${prefix}"${BIGINT_MARKER}${number}"`;
34
+ const result = [];
35
+ let i = 0;
36
+ let inString = false;
37
+ while (i < json.length) {
38
+ const char = json[i];
39
+ if (inString) {
40
+ if (char === "\\") {
41
+ result.push(char);
42
+ i++;
43
+ if (i < json.length) {
44
+ result.push(json[i]);
45
+ i++;
46
+ }
47
+ } else if (char === '"') {
48
+ result.push(char);
49
+ inString = false;
50
+ i++;
51
+ } else {
52
+ result.push(char);
53
+ i++;
54
+ }
55
+ } else {
56
+ if (char === '"') {
57
+ result.push(char);
58
+ inString = true;
59
+ i++;
60
+ } else if (char >= "0" && char <= "9") {
61
+ const hasMinus = result.length > 0 && result[result.length - 1] === "-";
62
+ if (hasMinus) {
63
+ result.pop();
64
+ }
65
+ const start = i;
66
+ while (i < json.length && json[i] >= "0" && json[i] <= "9") {
67
+ i++;
68
+ }
69
+ let isFloat = false;
70
+ if (i < json.length && json[i] === ".") {
71
+ isFloat = true;
72
+ i++;
73
+ while (i < json.length && json[i] >= "0" && json[i] <= "9") {
74
+ i++;
75
+ }
76
+ }
77
+ if (i < json.length && (json[i] === "e" || json[i] === "E")) {
78
+ isFloat = true;
79
+ i++;
80
+ if (i < json.length && (json[i] === "+" || json[i] === "-")) {
81
+ i++;
82
+ }
83
+ while (i < json.length && json[i] >= "0" && json[i] <= "9") {
84
+ i++;
85
+ }
86
+ }
87
+ const numberStr = (hasMinus ? "-" : "") + json.slice(start, i);
88
+ if (!isFloat && numberStr.length - (hasMinus ? 1 : 0) >= 15) {
89
+ const num = BigInt(numberStr);
90
+ if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
91
+ result.push(`"${BIGINT_MARKER}${numberStr}"`);
92
+ } else {
93
+ result.push(numberStr);
94
+ }
95
+ } else {
96
+ result.push(numberStr);
97
+ }
98
+ } else {
99
+ result.push(char);
100
+ i++;
101
+ }
38
102
  }
39
- return match;
40
- });
103
+ }
104
+ const processed = result.join("");
41
105
  return JSON.parse(processed, (_key, value) => {
42
106
  if (typeof value === "string" && value.startsWith(BIGINT_MARKER)) {
43
107
  return BigInt(value.slice(BIGINT_MARKER.length));
@@ -503,13 +567,81 @@ class MatterClient {
503
567
  onRawEvent(_event) {}
504
568
  }
505
569
 
570
+ /**
571
+ * @license
572
+ * Copyright 2025-2026 Open Home Foundation
573
+ * SPDX-License-Identifier: Apache-2.0
574
+ */
575
+ const STORAGE_KEY = "matterTheme";
576
+ class ThemeServiceImpl {
577
+ constructor() {
578
+ this._preference = "system";
579
+ this._listeners = /* @__PURE__ */new Set();
580
+ this._mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
581
+ this._mediaQuery.addEventListener("change", () => this._applyTheme());
582
+ this._loadPreference();
583
+ this._applyTheme();
584
+ }
585
+ get preference() {
586
+ return this._preference;
587
+ }
588
+ get effectiveTheme() {
589
+ if (this._preference === "system") {
590
+ return this._mediaQuery.matches ? "dark" : "light";
591
+ }
592
+ return this._preference;
593
+ }
594
+ setPreference(pref) {
595
+ this._preference = pref;
596
+ localStorage.setItem(STORAGE_KEY, pref);
597
+ this._applyTheme();
598
+ }
599
+ cycleTheme() {
600
+ const cycle = ["light", "dark", "system"];
601
+ const currentIndex = cycle.indexOf(this._preference);
602
+ const nextIndex = (currentIndex + 1) % cycle.length;
603
+ this.setPreference(cycle[nextIndex]);
604
+ return this._preference;
605
+ }
606
+ subscribe(callback) {
607
+ this._listeners.add(callback);
608
+ return () => this._listeners.delete(callback);
609
+ }
610
+ _loadPreference() {
611
+ const urlParams = new URLSearchParams(window.location.search);
612
+ const themeParam = urlParams.get("theme");
613
+ if (themeParam && ["light", "dark", "system"].includes(themeParam)) {
614
+ this._preference = themeParam;
615
+ localStorage.setItem(STORAGE_KEY, themeParam);
616
+ urlParams.delete("theme");
617
+ const newUrl = urlParams.toString() ? `${window.location.pathname}?${urlParams.toString()}${window.location.hash}` : `${window.location.pathname}${window.location.hash}`;
618
+ history.replaceState({}, "", newUrl);
619
+ return;
620
+ }
621
+ const stored = localStorage.getItem(STORAGE_KEY);
622
+ if (stored && ["light", "dark", "system"].includes(stored)) {
623
+ this._preference = stored;
624
+ }
625
+ }
626
+ _applyTheme() {
627
+ const effective = this.effectiveTheme;
628
+ document.documentElement.classList.toggle("dark-theme", effective === "dark");
629
+ const metaThemeColor = document.querySelector('meta[name="theme-color"]');
630
+ if (metaThemeColor) {
631
+ metaThemeColor.setAttribute("content", effective === "dark" ? "#1e1e1e" : "#03a9f4");
632
+ }
633
+ this._listeners.forEach(cb => cb(effective));
634
+ }
635
+ }
636
+ const ThemeService = new ThemeServiceImpl();
637
+
506
638
  /**
507
639
  * @license
508
640
  * Copyright 2025-2026 Open Home Foundation
509
641
  * SPDX-License-Identifier: Apache-2.0
510
642
  */
511
643
  async function main() {
512
- import('./matter-dashboard-app-DwI2RvT1.js').then(function (n) { return n.s; });
644
+ import('./matter-dashboard-app-BxQ4W_uT.js').then(function (n) { return n.s; });
513
645
  let url = "";
514
646
  const isProductionServer = location.origin.includes(":5580") || location.href.includes("hassio_ingress") || location.href.includes("/api/ingress/");
515
647
  if (!isProductionServer) {
@@ -544,4 +676,4 @@ async function main() {
544
676
  }
545
677
  main();
546
678
 
547
- export { toBigIntAwareJson as t };
679
+ export { ThemeService as T, toBigIntAwareJson as t };