@camstack/system 1.2.477 → 1.2.478

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 (88) hide show
  1. package/assets/display-palette/icon.svg +7 -0
  2. package/dist/{agent-https-vpf_D97z.mjs → agent-https-CXMsY05a.mjs} +1 -1
  3. package/dist/{agent-https-DkXBXEvz.js → agent-https-D6a1IRPK.js} +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  8. package/dist/builtins/alerts/alerts.addon.js +1 -1
  9. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  10. package/dist/builtins/autotrack/index.js +1 -1
  11. package/dist/builtins/autotrack/index.mjs +1 -1
  12. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  14. package/dist/builtins/calendars/calendars.addon.js +1 -1
  15. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  16. package/dist/builtins/camera-grid/index.js +1 -1
  17. package/dist/builtins/camera-grid/index.mjs +1 -1
  18. package/dist/builtins/composer/composer.addon.js +3 -3
  19. package/dist/builtins/composer/composer.addon.mjs +3 -3
  20. package/dist/builtins/console-logging/index.js +1 -1
  21. package/dist/builtins/console-logging/index.mjs +1 -1
  22. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  23. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  24. package/dist/builtins/device-history/device-history.addon.js +2 -2
  25. package/dist/builtins/device-history/device-history.addon.mjs +2 -2
  26. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  27. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  28. package/dist/builtins/display-palette/display-palette.addon.d.ts +12 -0
  29. package/dist/builtins/display-palette/display-palette.addon.js +85 -0
  30. package/dist/builtins/display-palette/display-palette.addon.mjs +79 -0
  31. package/dist/builtins/display-palette/index.d.ts +1 -0
  32. package/dist/builtins/display-palette/index.js +8 -0
  33. package/dist/builtins/display-palette/index.mjs +2 -0
  34. package/dist/builtins/hub-forwarder/index.js +1 -1
  35. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  36. package/dist/builtins/keychain/index.js +3 -3
  37. package/dist/builtins/keychain/index.mjs +3 -3
  38. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  39. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  40. package/dist/builtins/local-auth/local-auth.addon.js +2 -2
  41. package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
  42. package/dist/builtins/local-network/local-network.addon.js +2 -2
  43. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  44. package/dist/builtins/loki-logging/index.js +1 -1
  45. package/dist/builtins/loki-logging/index.mjs +1 -1
  46. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  47. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  48. package/dist/builtins/platform-probe/index.js +1 -1
  49. package/dist/builtins/platform-probe/index.mjs +1 -1
  50. package/dist/builtins/record-entries/index.js +1 -1
  51. package/dist/builtins/record-entries/index.mjs +1 -1
  52. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  53. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  54. package/dist/builtins/snapshot/index.js +1 -1
  55. package/dist/builtins/snapshot/index.mjs +1 -1
  56. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  57. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  58. package/dist/builtins/sqlite-storage/index.js +1 -1
  59. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  60. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
  61. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
  62. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  63. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  64. package/dist/builtins/system-config/system-config.addon.js +3 -3
  65. package/dist/builtins/system-config/system-config.addon.mjs +3 -3
  66. package/dist/builtins/winston-logging/index.js +1 -1
  67. package/dist/builtins/winston-logging/index.mjs +1 -1
  68. package/dist/{composition-sources-B5nK7pHt.mjs → composition-sources-CQcYYZxL.mjs} +1 -1
  69. package/dist/{composition-sources-BNOP9mFp.js → composition-sources-yfxjp3qV.js} +1 -1
  70. package/dist/{constants-D4VigrMM.js → constants-D--JWd55.js} +1 -1
  71. package/dist/{constants-jbhoFV7w.mjs → constants-lWkcQxVE.mjs} +1 -1
  72. package/dist/{device-ca-DhyQeXsa.js → device-ca-D0KnLHMw.js} +1 -1
  73. package/dist/{device-ca-CvBZeyVX.mjs → device-ca-J9ZsyoFw.mjs} +1 -1
  74. package/dist/{dist-B_V9r61Z.mjs → dist-OC-L50JY.mjs} +751 -70
  75. package/dist/{dist-CNU7cdFf.js → dist-iVUkxljP.js} +792 -69
  76. package/dist/file-host-worker.js +1 -1
  77. package/dist/file-host-worker.mjs +1 -1
  78. package/dist/{hub-mdns-ciao-DFidf52M.js → hub-mdns-ciao-BDKiKV75.js} +2 -2
  79. package/dist/{hub-mdns-ciao-BuUg0gpI.mjs → hub-mdns-ciao-CvXWbJub.mjs} +2 -2
  80. package/dist/index.js +7 -7
  81. package/dist/index.mjs +7 -7
  82. package/dist/{restore-archive-CDo4Zlmx.mjs → restore-archive-D1Uzojhc.mjs} +1 -1
  83. package/dist/{restore-archive-BtCheeWu.js → restore-archive-DxkdJpWd.js} +1 -1
  84. package/dist/{retention-1QA8e4o0.js → retention-B3z_lBP1.js} +1 -1
  85. package/dist/{retention-lPgwLane.mjs → retention-DdVnmXXS.mjs} +1 -1
  86. package/dist/{wal-maintenance-DItlr0Yu.mjs → wal-maintenance-DuO0D2H3.mjs} +0 -0
  87. package/dist/{wal-maintenance-B7xBeIFi.js → wal-maintenance-o9TyZeYp.js} +0 -0
  88. package/package.json +19 -1
@@ -44870,6 +44870,652 @@ var _macroLookup = /* @__PURE__ */ new Map();
44870
44870
  for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
44871
44871
  for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
44872
44872
  /**
44873
+ * Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
44874
+ * not entries. `heatmapScrub` is a mark, not an event kind.
44875
+ */
44876
+ var PALETTE_ENTRY_IDS = [
44877
+ "motion",
44878
+ "audio",
44879
+ "recording",
44880
+ "live",
44881
+ "heatmapScrub",
44882
+ "person",
44883
+ "vehicle",
44884
+ "animal",
44885
+ "package",
44886
+ "sensor",
44887
+ "control",
44888
+ "face",
44889
+ "plate",
44890
+ "car",
44891
+ "truck",
44892
+ "bus",
44893
+ "motorcycle",
44894
+ "bicycle",
44895
+ "airplane",
44896
+ "boat",
44897
+ "train",
44898
+ "bird",
44899
+ "dog",
44900
+ "cat",
44901
+ "horse",
44902
+ "sheep",
44903
+ "cow",
44904
+ "elephant",
44905
+ "bear",
44906
+ "zebra",
44907
+ "giraffe",
44908
+ "package-delivered",
44909
+ "package-picked-up",
44910
+ "suitcase",
44911
+ "backpack",
44912
+ "handbag",
44913
+ "contact",
44914
+ "motion-sensor",
44915
+ "smoke",
44916
+ "flood",
44917
+ "gas",
44918
+ "carbon-monoxide",
44919
+ "vibration",
44920
+ "tamper",
44921
+ "presence",
44922
+ "enum-sensor",
44923
+ "device-event",
44924
+ "lock",
44925
+ "cover",
44926
+ "switch",
44927
+ "siren",
44928
+ "button",
44929
+ "doorbell"
44930
+ ];
44931
+ var AUDIO_ENTRY_ID = "audio";
44932
+ /** Six rungs, quiet → loud. The opaque end is the entry's hex. */
44933
+ var AUDIO_GRADIENT_ALPHAS = [
44934
+ .3,
44935
+ .42,
44936
+ .55,
44937
+ .7,
44938
+ .85,
44939
+ 1
44940
+ ];
44941
+ var PALETTE_PRESET_IDS = [
44942
+ "camstack",
44943
+ "high-contrast",
44944
+ "okabe-ito"
44945
+ ];
44946
+ function isPaletteEntryId(id) {
44947
+ return PALETTE_ENTRY_IDS.includes(id);
44948
+ }
44949
+ function isPalettePresetId(id) {
44950
+ return PALETTE_PRESET_IDS.includes(id);
44951
+ }
44952
+ /**
44953
+ * CIEDE2000 and WCAG contrast for the display palette (D939).
44954
+ *
44955
+ * One implementation, shared by the hub validator, the admin editor and
44956
+ * (phase 2) the viewer. The arithmetic matches the viewer's `src/theme/cie.ts`.
44957
+ */
44958
+ /** Page backgrounds the contrast rule is measured against. */
44959
+ var PALETTE_BACKGROUNDS = {
44960
+ dark: "#0c0a09",
44961
+ light: "#fafaf9"
44962
+ };
44963
+ /** Marks that are not event kinds and share the raised distance floor. */
44964
+ var PALETTE_MARK_PAIR = ["live", "heatmapScrub"];
44965
+ var HEX = /^#[0-9a-fA-F]{6}$/;
44966
+ function srgbChannel(hex, start) {
44967
+ return Number.parseInt(hex.slice(start, start + 2), 16);
44968
+ }
44969
+ function srgbToLin(channel) {
44970
+ const x = channel / 255;
44971
+ return x <= .04045 ? x / 12.92 : ((x + .055) / 1.055) ** 2.4;
44972
+ }
44973
+ function relativeLuminance(hex) {
44974
+ const r = srgbToLin(srgbChannel(hex, 1));
44975
+ const g = srgbToLin(srgbChannel(hex, 3));
44976
+ const b = srgbToLin(srgbChannel(hex, 5));
44977
+ return .2126 * r + .7152 * g + .0722 * b;
44978
+ }
44979
+ /** WCAG contrast ratio of two `#rrggbb` colours. Non-hex returns 0. */
44980
+ function contrastRatio(a, b) {
44981
+ if (!HEX.test(a) || !HEX.test(b)) return 0;
44982
+ const hi = Math.max(relativeLuminance(a), relativeLuminance(b));
44983
+ const lo = Math.min(relativeLuminance(a), relativeLuminance(b));
44984
+ return (hi + .05) / (lo + .05);
44985
+ }
44986
+ function xyzToLab(hex) {
44987
+ const r = srgbToLin(srgbChannel(hex, 1));
44988
+ const g = srgbToLin(srgbChannel(hex, 3));
44989
+ const bl = srgbToLin(srgbChannel(hex, 5));
44990
+ const x = .4124564 * r + .3575761 * g + .1804375 * bl;
44991
+ const y = .2126729 * r + .7151522 * g + .072175 * bl;
44992
+ const z = .0193339 * r + .119192 * g + .9503041 * bl;
44993
+ const f = (t) => t > .008856 ? Math.cbrt(t) : 7.787 * t + 16 / 116;
44994
+ const fx = f(x / .95047);
44995
+ const fy = f(y);
44996
+ const fz = f(z / 1.08883);
44997
+ return {
44998
+ L: 116 * fy - 16,
44999
+ a: 500 * (fx - fy),
45000
+ b: 200 * (fy - fz)
45001
+ };
45002
+ }
45003
+ function hueDeg(ap, b) {
45004
+ if (ap === 0 && b === 0) return 0;
45005
+ const ang = Math.atan2(b, ap) * 180 / Math.PI;
45006
+ return ang < 0 ? ang + 360 : ang;
45007
+ }
45008
+ /** CIEDE2000. Non-hex returns 0 so a bad swatch fails the distinctness rule. */
45009
+ function deltaE00(hex1, hex2) {
45010
+ if (!HEX.test(hex1) || !HEX.test(hex2)) return 0;
45011
+ const lab1 = xyzToLab(hex1);
45012
+ const lab2 = xyzToLab(hex2);
45013
+ const cab7 = ((Math.hypot(lab1.a, lab1.b) + Math.hypot(lab2.a, lab2.b)) / 2) ** 7;
45014
+ const g = .5 * (1 - Math.sqrt(cab7 / (cab7 + 25 ** 7)));
45015
+ const a1p = (1 + g) * lab1.a;
45016
+ const a2p = (1 + g) * lab2.a;
45017
+ const c1p = Math.hypot(a1p, lab1.b);
45018
+ const c2p = Math.hypot(a2p, lab2.b);
45019
+ const h1p = hueDeg(a1p, lab1.b);
45020
+ const h2p = hueDeg(a2p, lab2.b);
45021
+ let dhp = 0;
45022
+ if (c1p * c2p !== 0) {
45023
+ dhp = h2p - h1p;
45024
+ if (dhp > 180) dhp -= 360;
45025
+ else if (dhp < -180) dhp += 360;
45026
+ }
45027
+ const dHp = 2 * Math.sqrt(c1p * c2p) * Math.sin(dhp * Math.PI / 360);
45028
+ const lbp = (lab1.L + lab2.L) / 2;
45029
+ const cbp = (c1p + c2p) / 2;
45030
+ let hbp = h1p + h2p;
45031
+ if (c1p * c2p !== 0) {
45032
+ if (Math.abs(h1p - h2p) > 180) hbp += hbp < 360 ? 360 : -360;
45033
+ hbp /= 2;
45034
+ }
45035
+ const t = 1 - .17 * Math.cos((hbp - 30) * Math.PI / 180) + .24 * Math.cos(2 * hbp * Math.PI / 180) + .32 * Math.cos((3 * hbp + 6) * Math.PI / 180) - .2 * Math.cos((4 * hbp - 63) * Math.PI / 180);
45036
+ const dTheta = 30 * Math.exp(-(((hbp - 275) / 25) ** 2));
45037
+ const cbp7 = cbp ** 7;
45038
+ const rc = 2 * Math.sqrt(cbp7 / (cbp7 + 25 ** 7));
45039
+ const sl = 1 + .015 * (lbp - 50) ** 2 / Math.sqrt(20 + (lbp - 50) ** 2);
45040
+ const sc = 1 + .045 * cbp;
45041
+ const sh = 1 + .015 * cbp * t;
45042
+ const rt = -Math.sin(2 * dTheta * Math.PI / 180) * rc;
45043
+ const dLp = lab2.L - lab1.L;
45044
+ const dCp = c2p - c1p;
45045
+ return Math.sqrt((dLp / sl) ** 2 + (dCp / sc) ** 2 + (dHp / sh) ** 2 + rt * (dCp / sc) * (dHp / sh));
45046
+ }
45047
+ /** Frozen palette tables (D939). The spec refuses a table that breaks the rule. */
45048
+ var CAMSTACK_HEX = {
45049
+ motion: "#d946ef",
45050
+ audio: "#059eb8",
45051
+ recording: "#ef4444",
45052
+ live: "#8d7a00",
45053
+ heatmapScrub: "#4b32ff",
45054
+ person: "#11a64c",
45055
+ vehicle: "#3b82f6",
45056
+ animal: "#ea6a09",
45057
+ package: "#924667",
45058
+ sensor: "#624bbc",
45059
+ control: "#944d24",
45060
+ face: "#ed4f8d",
45061
+ plate: "#4b7027",
45062
+ car: "#9684cf",
45063
+ truck: "#0f9b89",
45064
+ bus: "#a734a9",
45065
+ motorcycle: "#c1133a",
45066
+ bicycle: "#0e6a9b",
45067
+ airplane: "#7c9928",
45068
+ boat: "#b17933",
45069
+ train: "#ad6ca3",
45070
+ bird: "#0f7c55",
45071
+ dog: "#c82700",
45072
+ cat: "#7268f2",
45073
+ horse: "#cb795e",
45074
+ sheep: "#b8636b",
45075
+ cow: "#cb2969",
45076
+ elephant: "#1158d2",
45077
+ bear: "#8d5e00",
45078
+ zebra: "#0097d6",
45079
+ giraffe: "#8f61bb",
45080
+ "package-delivered": "#cd3f9b",
45081
+ "package-picked-up": "#388a08",
45082
+ suitcase: "#666800",
45083
+ backpack: "#ec5022",
45084
+ handbag: "#a76ef8",
45085
+ contact: "#ab5a49",
45086
+ "motion-sensor": "#b95d1a",
45087
+ smoke: "#dd3858",
45088
+ flood: "#b31e7d",
45089
+ gas: "#5b70b5",
45090
+ "carbon-monoxide": "#7b4e8e",
45091
+ vibration: "#e65bba",
45092
+ tamper: "#98464b",
45093
+ presence: "#3a9468",
45094
+ "enum-sensor": "#7885f8",
45095
+ "device-event": "#8c43c8",
45096
+ lock: "#649653",
45097
+ cover: "#c67597",
45098
+ switch: "#7a812a",
45099
+ siren: "#ac5d7f",
45100
+ button: "#b276cd",
45101
+ doorbell: "#0087ab"
45102
+ };
45103
+ var CAMSTACK_FALLBACK = [
45104
+ "#b34dc7",
45105
+ "#1d7d34",
45106
+ "#db6b6c",
45107
+ "#a43d29",
45108
+ "#0e6ee6",
45109
+ "#29a10b",
45110
+ "#a98731",
45111
+ "#0181c6"
45112
+ ];
45113
+ var HIGH_CONTRAST_HEX = {
45114
+ motion: "#964360",
45115
+ audio: "#23a132",
45116
+ recording: "#2494ca",
45117
+ live: "#bd7e2b",
45118
+ heatmapScrub: "#ad6eea",
45119
+ person: "#62611e",
45120
+ vehicle: "#f4534c",
45121
+ animal: "#1556cd",
45122
+ package: "#9c4415",
45123
+ sensor: "#066c48",
45124
+ control: "#f2479f",
45125
+ face: "#139d8a",
45126
+ plate: "#909024",
45127
+ car: "#8e35ab",
45128
+ truck: "#bd0b2b",
45129
+ bus: "#7a88ca",
45130
+ motorcycle: "#e26725",
45131
+ bicycle: "#a6679b",
45132
+ airplane: "#7c5720",
45133
+ boat: "#467a1b",
45134
+ train: "#6f65a4",
45135
+ bird: "#cb717f",
45136
+ dog: "#c62490",
45137
+ cat: "#b36850",
45138
+ horse: "#1872ac",
45139
+ sheep: "#927939",
45140
+ cow: "#428a5c",
45141
+ elephant: "#d41160",
45142
+ bear: "#799453",
45143
+ zebra: "#a85455",
45144
+ giraffe: "#746be8",
45145
+ "package-delivered": "#824a80",
45146
+ "package-picked-up": "#614ac1",
45147
+ suitcase: "#2f77f3",
45148
+ backpack: "#fa476d",
45149
+ handbag: "#c14cbe",
45150
+ contact: "#c83921",
45151
+ "motion-sensor": "#a07ebd",
45152
+ smoke: "#a25b13",
45153
+ flood: "#526bab",
45154
+ gas: "#924938",
45155
+ "carbon-monoxide": "#bb7e53",
45156
+ vibration: "#b66182",
45157
+ tamper: "#3c6931",
45158
+ presence: "#6c851d",
45159
+ "enum-sensor": "#ad2d48",
45160
+ "device-event": "#5e9b04",
45161
+ lock: "#00a062",
45162
+ cover: "#ad8624",
45163
+ switch: "#d05259",
45164
+ siren: "#cd67b3",
45165
+ button: "#c9746a",
45166
+ doorbell: "#338eeb"
45167
+ };
45168
+ var HIGH_CONTRAST_FALLBACK = [
45169
+ "#817f3b",
45170
+ "#a0733e",
45171
+ "#8658b2",
45172
+ "#956301",
45173
+ "#bc652d",
45174
+ "#647331",
45175
+ "#a14c9e",
45176
+ "#d14e71"
45177
+ ];
45178
+ var OKABE_ITO_HEX = {
45179
+ motion: "#b88128",
45180
+ audio: "#1096c8",
45181
+ recording: "#009e73",
45182
+ live: "#9c8c22",
45183
+ heatmapScrub: "#0072b2",
45184
+ person: "#d55e00",
45185
+ vehicle: "#c0739f",
45186
+ animal: "#226d18",
45187
+ package: "#91446c",
45188
+ sensor: "#217b56",
45189
+ control: "#648647",
45190
+ face: "#c22998",
45191
+ plate: "#fa4575",
45192
+ car: "#956301",
45193
+ truck: "#2f77f3",
45194
+ bus: "#7a4e86",
45195
+ motorcycle: "#f54597",
45196
+ bicycle: "#bb3e75",
45197
+ airplane: "#e054c0",
45198
+ boat: "#457942",
45199
+ train: "#867afa",
45200
+ bird: "#88914c",
45201
+ dog: "#1556cd",
45202
+ cat: "#71702c",
45203
+ horse: "#9b4fa4",
45204
+ sheep: "#c0559d",
45205
+ cow: "#d14f65",
45206
+ elephant: "#98470f",
45207
+ bear: "#595896",
45208
+ zebra: "#96790e",
45209
+ giraffe: "#cb717b",
45210
+ "package-delivered": "#139d8a",
45211
+ "package-picked-up": "#906ead",
45212
+ suitcase: "#d02939",
45213
+ backpack: "#d41160",
45214
+ handbag: "#f64f54",
45215
+ contact: "#7258d2",
45216
+ "motion-sensor": "#b66182",
45217
+ smoke: "#627abb",
45218
+ flood: "#b86ae4",
45219
+ gas: "#a95261",
45220
+ "carbon-monoxide": "#c65d3c",
45221
+ vibration: "#7a40b7",
45222
+ tamper: "#914b34",
45223
+ presence: "#9481c3",
45224
+ "enum-sensor": "#ac6d47",
45225
+ "device-event": "#7b6fce",
45226
+ lock: "#c67662",
45227
+ cover: "#a6564d",
45228
+ switch: "#ad2c4e",
45229
+ siren: "#348e08",
45230
+ button: "#d27303",
45231
+ doorbell: "#55770f"
45232
+ };
45233
+ var OKABE_ITO_FALLBACK = [
45234
+ "#9a3784",
45235
+ "#a7392c",
45236
+ "#409d50",
45237
+ "#6987e7",
45238
+ "#ee5b3d",
45239
+ "#c0430d",
45240
+ "#af79b3",
45241
+ "#4b6628"
45242
+ ];
45243
+ /**
45244
+ * The display palette (D939). One table of colours, three presets, one
45245
+ * validator. Taxonomy colours and every consumer read this — there is no
45246
+ * second hex table.
45247
+ */
45248
+ var paletteHexSchema = z.string().regex(/^#[0-9a-f]{6}$/);
45249
+ var paletteSolidSchema = z.object({
45250
+ form: z.literal("solid"),
45251
+ hex: paletteHexSchema
45252
+ });
45253
+ var paletteGradientSchema = z.object({
45254
+ form: z.literal("gradient"),
45255
+ hex: paletteHexSchema,
45256
+ alphas: z.array(z.number().gt(0).lte(1)).length(AUDIO_GRADIENT_ALPHAS.length)
45257
+ });
45258
+ var paletteSwatchSchema = z.discriminatedUnion("form", [paletteSolidSchema, paletteGradientSchema]);
45259
+ var paletteReadySchema = z.object({
45260
+ status: z.literal("ready"),
45261
+ presetId: z.enum(PALETTE_PRESET_IDS),
45262
+ customized: z.boolean(),
45263
+ source: z.enum(["stored", "unconfigured"]),
45264
+ swatches: z.record(z.string(), paletteSwatchSchema),
45265
+ fallbacks: z.array(paletteHexSchema).length(8)
45266
+ });
45267
+ var paletteUnknownSchema = z.object({
45268
+ status: z.literal("unknown"),
45269
+ reason: z.string()
45270
+ });
45271
+ var paletteResultSchema = z.discriminatedUnion("status", [paletteReadySchema, paletteUnknownSchema]);
45272
+ var setPaletteInputSchema = z.union([z.object({ presetId: z.string() }), z.object({
45273
+ presetId: z.string(),
45274
+ overrides: z.record(z.string(), paletteSwatchSchema)
45275
+ })]);
45276
+ var storedPaletteSchema = z.object({
45277
+ presetId: z.string(),
45278
+ overrides: z.record(z.string(), paletteSwatchSchema)
45279
+ });
45280
+ function solid(hex) {
45281
+ return {
45282
+ form: "solid",
45283
+ hex
45284
+ };
45285
+ }
45286
+ function audioGradient(hex) {
45287
+ return {
45288
+ form: "gradient",
45289
+ hex,
45290
+ alphas: [...AUDIO_GRADIENT_ALPHAS]
45291
+ };
45292
+ }
45293
+ function swatchesFrom(hexes) {
45294
+ const out = {};
45295
+ for (const id of PALETTE_ENTRY_IDS) {
45296
+ const hex = hexes[id];
45297
+ if (hex === void 0) throw new Error(`palette table missing ${id}`);
45298
+ out[id] = id === "audio" ? audioGradient(hex) : solid(hex);
45299
+ }
45300
+ return out;
45301
+ }
45302
+ function preset(id, name, hexes, fallbacks) {
45303
+ return {
45304
+ id,
45305
+ name,
45306
+ swatches: swatchesFrom(hexes),
45307
+ fallbacks
45308
+ };
45309
+ }
45310
+ var DISPLAY_PRESETS = [
45311
+ preset("camstack", "CamStack", CAMSTACK_HEX, CAMSTACK_FALLBACK),
45312
+ preset("high-contrast", "High contrast", HIGH_CONTRAST_HEX, HIGH_CONTRAST_FALLBACK),
45313
+ preset("okabe-ito", "Colour-blind safe", OKABE_ITO_HEX, OKABE_ITO_FALLBACK)
45314
+ ];
45315
+ function presetById(id) {
45316
+ return DISPLAY_PRESETS.find((item) => item.id === id);
45317
+ }
45318
+ function bundledCamstack() {
45319
+ const presetRow = presetById("camstack");
45320
+ if (presetRow === void 0) throw new Error("CamStack preset missing");
45321
+ return readyOf(presetRow, "unconfigured", false);
45322
+ }
45323
+ function readyOf(row, source, customized) {
45324
+ return {
45325
+ status: "ready",
45326
+ presetId: row.id,
45327
+ customized,
45328
+ source,
45329
+ swatches: row.swatches,
45330
+ fallbacks: [...row.fallbacks]
45331
+ };
45332
+ }
45333
+ function namedColours(swatches, fallbacks) {
45334
+ const rows = [];
45335
+ for (const id of PALETTE_ENTRY_IDS) {
45336
+ const swatch = swatches[id];
45337
+ if (swatch !== void 0) rows.push({
45338
+ name: id,
45339
+ hex: swatch.hex
45340
+ });
45341
+ }
45342
+ fallbacks.forEach((hex, index) => {
45343
+ rows.push({
45344
+ name: `fallback-${index}`,
45345
+ hex
45346
+ });
45347
+ });
45348
+ return rows;
45349
+ }
45350
+ function gradientViolations(swatches) {
45351
+ const audio = swatches[AUDIO_ENTRY_ID];
45352
+ if (audio === void 0) return [];
45353
+ if (audio.form !== "gradient") return [{
45354
+ code: "bad-gradient",
45355
+ entry: AUDIO_ENTRY_ID
45356
+ }];
45357
+ return AUDIO_GRADIENT_ALPHAS.every((alpha, index) => audio.alphas[index] === alpha) ? [] : [{
45358
+ code: "bad-gradient",
45359
+ entry: AUDIO_ENTRY_ID
45360
+ }];
45361
+ }
45362
+ function isMarkPair(left, right) {
45363
+ const marks = PALETTE_MARK_PAIR;
45364
+ return marks.includes(left) && marks.includes(right);
45365
+ }
45366
+ /** Refuse a palette whose entries are not pairwise distinct on both themes. */
45367
+ function validatePalette(swatches, fallbacks) {
45368
+ const violations = [];
45369
+ for (const id of PALETTE_ENTRY_IDS) if (swatches[id] === void 0) violations.push({
45370
+ code: "missing-entry",
45371
+ entry: id
45372
+ });
45373
+ for (const key of Object.keys(swatches)) if (!isPaletteEntryId(key)) violations.push({
45374
+ code: "unknown-entry",
45375
+ entry: key
45376
+ });
45377
+ if (fallbacks.length !== 8) violations.push({ code: "bad-fallbacks" });
45378
+ violations.push(...gradientViolations(swatches));
45379
+ const rows = namedColours(swatches, fallbacks);
45380
+ for (let i = 0; i < rows.length; i++) for (let j = i + 1; j < rows.length; j++) {
45381
+ const left = rows[i];
45382
+ const right = rows[j];
45383
+ if (left === void 0 || right === void 0) continue;
45384
+ const deltaE = deltaE00(left.hex, right.hex);
45385
+ if (deltaE < (isMarkPair(left.name, right.name) ? 20 : 7)) violations.push({
45386
+ code: "too-close",
45387
+ left: left.name,
45388
+ right: right.name,
45389
+ deltaE
45390
+ });
45391
+ }
45392
+ for (const row of rows) for (const background of ["dark", "light"]) {
45393
+ const contrast = contrastRatio(row.hex, PALETTE_BACKGROUNDS[background]);
45394
+ if (contrast < 3) violations.push({
45395
+ code: "low-contrast",
45396
+ entry: row.name,
45397
+ background,
45398
+ contrast
45399
+ });
45400
+ }
45401
+ return violations.length === 0 ? { ok: true } : {
45402
+ ok: false,
45403
+ violations
45404
+ };
45405
+ }
45406
+ function formatPaletteViolation(violation) {
45407
+ switch (violation.code) {
45408
+ case "too-close": return `${violation.left} vs ${violation.right} (ΔE ${violation.deltaE.toFixed(1)})`;
45409
+ case "low-contrast": return `${violation.entry} on ${violation.background} (${violation.contrast.toFixed(1)}:1)`;
45410
+ case "missing-entry": return `${violation.entry} is missing`;
45411
+ case "unknown-entry": return `${violation.entry} is not a palette entry`;
45412
+ case "bad-gradient": return `${violation.entry} gradient is not the six canonical steps`;
45413
+ case "bad-fallbacks": return "fallback list must hold eight colours";
45414
+ case "unknown-preset": return `${violation.presetId} is not a preset`;
45415
+ }
45416
+ }
45417
+ function formatPaletteViolations(violations) {
45418
+ return violations.map(formatPaletteViolation).join("; ");
45419
+ }
45420
+ var PaletteRejectedError = class extends Error {
45421
+ violations;
45422
+ constructor(violations) {
45423
+ super(formatPaletteViolations(violations));
45424
+ this.name = "PaletteRejectedError";
45425
+ this.violations = violations;
45426
+ }
45427
+ };
45428
+ function hashFallback(kind, fallbacks) {
45429
+ let hash = 0;
45430
+ for (let i = 0; i < kind.length; i++) hash = hash * 31 + (kind.codePointAt(i) ?? 0) >>> 0;
45431
+ const hex = fallbacks[hash % fallbacks.length];
45432
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
45433
+ return hex;
45434
+ }
45435
+ /** Colour a kind paints with. Audio leaves share the audio gradient's hex. */
45436
+ function paintHex(swatches, fallbacks, kind) {
45437
+ const key = kind.trim().toLowerCase();
45438
+ if (key.startsWith("audio-")) {
45439
+ const audio = swatches[AUDIO_ENTRY_ID];
45440
+ return audio !== void 0 ? audio.hex : hashFallback(key, fallbacks);
45441
+ }
45442
+ const direct = swatches[key];
45443
+ if (direct !== void 0) return direct.hex;
45444
+ return hashFallback(key, fallbacks);
45445
+ }
45446
+ function mergeOverrides(base, overrides) {
45447
+ return {
45448
+ ...base,
45449
+ ...overrides
45450
+ };
45451
+ }
45452
+ function overridesOf(input) {
45453
+ return "overrides" in input ? input.overrides : {};
45454
+ }
45455
+ /** The palette a `setPalette` input would store. Invalid input is a refusal. */
45456
+ function paletteFromInput(input) {
45457
+ const row = presetById(input.presetId);
45458
+ if (row === void 0 || !isPalettePresetId(input.presetId)) throw new PaletteRejectedError([{
45459
+ code: "unknown-preset",
45460
+ presetId: input.presetId
45461
+ }]);
45462
+ const overrides = overridesOf(input);
45463
+ const swatches = mergeOverrides(row.swatches, overrides);
45464
+ const verdict = validatePalette(swatches, row.fallbacks);
45465
+ if (!verdict.ok) throw new PaletteRejectedError(verdict.violations);
45466
+ const customized = Object.keys(overrides).length > 0;
45467
+ return {
45468
+ status: "ready",
45469
+ presetId: row.id,
45470
+ customized,
45471
+ source: "stored",
45472
+ swatches,
45473
+ fallbacks: [...row.fallbacks]
45474
+ };
45475
+ }
45476
+ function isEmptyRecord(value) {
45477
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length === 0;
45478
+ }
45479
+ /**
45480
+ * Interpret a settings blob. A missing row is the bundled preset and says so.
45481
+ * A blob that does not parse, names an unknown preset, or fails the rule is
45482
+ * `unknown` — never the default wearing the stored preset's name.
45483
+ */
45484
+ function paletteFromStored(value) {
45485
+ if (value === void 0 || value === null || isEmptyRecord(value)) return bundledCamstack();
45486
+ const parsed = storedPaletteSchema.safeParse(value);
45487
+ if (!parsed.success) return {
45488
+ status: "unknown",
45489
+ reason: "stored palette is unreadable"
45490
+ };
45491
+ const row = presetById(parsed.data.presetId);
45492
+ if (row === void 0) return {
45493
+ status: "unknown",
45494
+ reason: `unknown preset ${parsed.data.presetId}`
45495
+ };
45496
+ const swatches = mergeOverrides(row.swatches, parsed.data.overrides);
45497
+ const verdict = validatePalette(swatches, row.fallbacks);
45498
+ if (!verdict.ok) return {
45499
+ status: "unknown",
45500
+ reason: formatPaletteViolations(verdict.violations)
45501
+ };
45502
+ const customized = Object.keys(parsed.data.overrides).length > 0;
45503
+ return {
45504
+ status: "ready",
45505
+ presetId: row.id,
45506
+ customized,
45507
+ source: "stored",
45508
+ swatches,
45509
+ fallbacks: [...row.fallbacks]
45510
+ };
45511
+ }
45512
+ function storedFromReady(ready, overrides) {
45513
+ return {
45514
+ presetId: ready.presetId,
45515
+ overrides: { ...overrides }
45516
+ };
45517
+ }
45518
+ /**
44873
45519
  * Unified event-kind taxonomy — THE single source of truth for
44874
45520
  * `kind → { parentKind, category, level, color, iconId, labelKey, label,
44875
45521
  * icon }`.
@@ -44883,109 +45529,88 @@ for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set
44883
45529
  * - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
44884
45530
  * - the COCO / audio class maps (macro ↔ sub relationships)
44885
45531
  *
44886
- * The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
44887
- * `@camstack/types`. The UI-side mapping `iconId → lucide component` and
44888
- * `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
44889
- * color or an icon: they read this dictionary (server descriptors carry the
44890
- * fields inline; the client resolves color/icon/label from `iconId`/`kind`).
45532
+ * The DATA (serializable — parentKind / iconId / labelKey) lives here in
45533
+ * `@camstack/types`. Colour is NOT a second table: each entry's `color` is
45534
+ * the bundled CamStack display palette (D939). The effective cluster palette
45535
+ * is the `display-palette` capability. The UI-side mapping `iconId → lucide
45536
+ * component` and `labelKey → t()` lives in `@camstack/ui-library`.
44891
45537
  *
44892
45538
  * Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
44893
45539
  */
44894
- var TAXONOMY_COLORS = {
44895
- motion: "#f59e0b",
44896
- audio: "#06b6d4",
44897
- person: "#22c55e",
44898
- vehicle: "#3b82f6",
44899
- animal: "#f97316",
44900
- package: "#a855f7",
44901
- sensor: "#8b5cf6",
44902
- control: "#10b981",
44903
- genericDetection: "#64748b"
44904
- };
44905
- var DETECTION_SUB_COLORS = {
44906
- car: "#f59e0b",
44907
- truck: "#d97706",
44908
- bus: "#b45309",
44909
- motorcycle: "#eab308",
44910
- bicycle: "#ca8a04",
44911
- airplane: "#60a5fa",
44912
- boat: "#2563eb",
44913
- train: "#1d4ed8",
44914
- bird: "#14b8a6",
44915
- dog: "#84cc16",
44916
- cat: "#f97316",
44917
- horse: "#a16207",
44918
- sheep: "#a3a3a3",
44919
- cow: "#78716c",
44920
- elephant: "#6b7280",
44921
- bear: "#7c2d12",
44922
- zebra: "#404040",
44923
- giraffe: "#d4a373"
44924
- };
45540
+ var BUNDLED_PALETTE = bundledCamstack();
45541
+ function kindColor(kind) {
45542
+ return paintHex(BUNDLED_PALETTE.swatches, BUNDLED_PALETTE.fallbacks, kind);
45543
+ }
45544
+ function firstFallback(fallbacks) {
45545
+ const hex = fallbacks[0];
45546
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
45547
+ return hex;
45548
+ }
45549
+ firstFallback(BUNDLED_PALETTE.fallbacks);
44925
45550
  function titleCase(id) {
44926
45551
  return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
44927
45552
  }
44928
45553
  var entries = /* @__PURE__ */ new Map();
44929
- function macro(kind, category, color, iconId, label) {
45554
+ function macro(kind, category, iconId, label) {
44930
45555
  entries.set(kind, {
44931
45556
  kind,
44932
45557
  parentKind: null,
44933
45558
  level: "macro",
44934
45559
  category,
44935
- color,
45560
+ color: kindColor(kind),
44936
45561
  iconId,
44937
45562
  labelKey: `eventKind.${kind}`,
44938
45563
  label
44939
45564
  });
44940
45565
  }
44941
- function sub(kind, parentKind, category, color, iconId, label) {
45566
+ function sub(kind, parentKind, category, iconId, label) {
44942
45567
  entries.set(kind, {
44943
45568
  kind,
44944
45569
  parentKind,
44945
45570
  level: "sub",
44946
45571
  category,
44947
- color,
45572
+ color: kindColor(kind),
44948
45573
  iconId,
44949
45574
  labelKey: `eventKind.${kind}`,
44950
45575
  label
44951
45576
  });
44952
45577
  }
44953
- macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
44954
- macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
44955
- macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
44956
- macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
44957
- macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
44958
- macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
44959
- macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
44960
- macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
45578
+ macro("motion", "motion", "motion", "Motion");
45579
+ macro("audio", "audio", "audio", "Audio");
45580
+ macro("person", "detection", "person", "Person");
45581
+ macro("vehicle", "detection", "vehicle", "Vehicle");
45582
+ macro("animal", "detection", "animal", "Animal");
45583
+ macro("package", "package", "package", "Package");
45584
+ macro("sensor", "sensor", "sensor", "Sensor");
45585
+ macro("control", "control", "control", "Control");
44961
45586
  for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
44962
45587
  if (macroClass !== "vehicle" && macroClass !== "animal") continue;
44963
45588
  if (entries.has(cocoClass)) continue;
44964
- sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
45589
+ sub(cocoClass, macroClass, "detection", cocoClass, titleCase(cocoClass));
44965
45590
  }
44966
- sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
44967
- sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
44968
- sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
44969
- sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
44970
- sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
44971
- sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
44972
- sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
44973
- sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
44974
- sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
44975
- sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
44976
- sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
44977
- sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
44978
- sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
44979
- sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
44980
- sub("cover", "control", "control", "#0ea5e9", "door", "Cover");
44981
- sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
44982
- sub("siren", "control", "control", "#dc2626", "siren", "Siren");
44983
- sub("button", "control", "control", "#10b981", "button", "Button");
44984
- sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
45591
+ sub("package-delivered", "package", "package", "package", "Package delivered");
45592
+ sub("package-picked-up", "package", "package", "package", "Package picked up");
45593
+ sub("contact", "sensor", "sensor", "door", "Contact");
45594
+ sub("motion-sensor", "sensor", "sensor", "pir", "Motion sensor");
45595
+ sub("smoke", "sensor", "sensor", "smoke", "Smoke");
45596
+ sub("flood", "sensor", "sensor", "water", "Water leak");
45597
+ sub("gas", "sensor", "sensor", "gas", "Gas");
45598
+ sub("carbon-monoxide", "sensor", "sensor", "smoke", "Carbon monoxide");
45599
+ sub("vibration", "sensor", "sensor", "vibration", "Vibration");
45600
+ sub("tamper", "sensor", "sensor", "tamper", "Tamper");
45601
+ sub("presence", "sensor", "sensor", "presence", "Presence");
45602
+ sub("enum-sensor", "sensor", "sensor", "generic", "Sensor state");
45603
+ sub("device-event", "sensor", "sensor", "button", "Device event");
45604
+ sub("lock", "control", "control", "lock", "Lock");
45605
+ sub("cover", "control", "control", "door", "Cover");
45606
+ sub("switch", "control", "control", "switch", "Switch");
45607
+ sub("siren", "control", "control", "siren", "Siren");
45608
+ sub("button", "control", "control", "button", "Button");
45609
+ sub("doorbell", "control", "control", "doorbell", "Doorbell");
44985
45610
  for (const l of AUDIO_MACRO_LABELS) {
44986
45611
  const kind = `audio-${l.id}`;
44987
45612
  if (entries.has(kind)) continue;
44988
- sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
45613
+ sub(kind, "audio", "audio", kind, l.name);
44989
45614
  }
44990
45615
  /** The complete taxonomy dictionary, keyed by kind. */
44991
45616
  var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
@@ -61980,6 +62605,39 @@ var dayNightCapability = {
61980
62605
  volatileStateFields: ["lastFetchedAt"]
61981
62606
  };
61982
62607
  /**
62608
+ * display-palette — the cluster's one colour table (D939).
62609
+ *
62610
+ * Hub singleton. `getPalette` reports `unknown` when the settings store
62611
+ * cannot be read; it does not pretend the bundled preset was stored.
62612
+ * `setPalette` refuses a palette that fails the ΔE / contrast rule and names
62613
+ * the pairs.
62614
+ */
62615
+ var presetSummarySchema = z.object({
62616
+ id: z.string(),
62617
+ name: z.string(),
62618
+ swatches: z.record(z.string(), paletteSwatchSchema),
62619
+ fallbacks: z.array(z.string())
62620
+ });
62621
+ var displayPaletteCapability = {
62622
+ name: "display-palette",
62623
+ scope: "system",
62624
+ mode: "singleton",
62625
+ methods: {
62626
+ getPalette: method(z.void(), paletteResultSchema, {
62627
+ auth: "protected",
62628
+ role: "viewer"
62629
+ }),
62630
+ listPresets: method(z.void(), z.array(presetSummarySchema).readonly(), {
62631
+ auth: "protected",
62632
+ role: "viewer"
62633
+ }),
62634
+ setPalette: method(setPaletteInputSchema, paletteReadySchema, {
62635
+ kind: "mutation",
62636
+ auth: "admin"
62637
+ })
62638
+ }
62639
+ };
62640
+ /**
61983
62641
  * Generic device-level status snapshot. Auto-registered by `BaseDevice`
61984
62642
  * for every device, regardless of provider — the kernel needs a uniform
61985
62643
  * cap-keyed slice for the basic device flags every consumer expects to
@@ -78969,6 +79627,27 @@ var METHOD_ACCESS_MAP = Object.freeze({
78969
79627
  access: "create",
78970
79628
  role: "viewer"
78971
79629
  },
79630
+ "displayPalette.getPalette": {
79631
+ capName: "display-palette",
79632
+ capScope: "system",
79633
+ addonId: null,
79634
+ access: "view",
79635
+ role: "viewer"
79636
+ },
79637
+ "displayPalette.listPresets": {
79638
+ capName: "display-palette",
79639
+ capScope: "system",
79640
+ addonId: null,
79641
+ access: "view",
79642
+ role: "viewer"
79643
+ },
79644
+ "displayPalette.setPalette": {
79645
+ capName: "display-palette",
79646
+ capScope: "system",
79647
+ addonId: null,
79648
+ access: "create",
79649
+ role: "admin"
79650
+ },
78972
79651
  "doorbell.getStatus": {
78973
79652
  capName: "doorbell",
78974
79653
  capScope: "device",
@@ -89425,6 +90104,7 @@ var SYSTEM_CAP_VOCABULARY = {
89425
90104
  "device-provider": system(INTERNAL),
89426
90105
  "device-removal-hook": system(INTERNAL),
89427
90106
  "device-state": system("the runtime-state mirror every trigger already reads through"),
90107
+ "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
89428
90108
  "embedding-encoder": system(ML),
89429
90109
  "face-gallery": system("the face gallery — curated on its own page"),
89430
90110
  "failure-contribution": system(INTERNAL),
@@ -89689,6 +90369,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
89689
90369
  deviceStateCapability,
89690
90370
  deviceStatusCapability,
89691
90371
  dishwasherCapability,
90372
+ displayPaletteCapability,
89692
90373
  doorbellCapability,
89693
90374
  embeddingEncoderCapability,
89694
90375
  enumSensorCapability,
@@ -95007,4 +95688,4 @@ function armRemovalReconcile(opts) {
95007
95688
  return () => clearInterval(timer);
95008
95689
  }
95009
95690
  //#endregion
95010
- export { PreferenceDeviceIdSchema as $, hydrateSchema as $i, planComposition as $n, DeviceType as $r, deviceExtensionCapability as $t, DEVICE_SAN_USER_PREFIX as A, TransactRefusedError as Ai, keychainAdminCapability as An, streamQualityLabel as Ar, buildDeviceSignatureMessage as At, HISTORY_ITEM_CATALOG as B, collectSecretConfigKeys as Bi, mayReadLocation as Bn, buildFfmpegArgs as Br, coreBlockComposition as Bt, DATA_STORE_DATABASES as C, toNodeId as Ca, RecordKindDeclarationSchema as Ci, isCollectionArrayMethod as Cn, splitTranslationRef as Cr, armRemovalReconcile as Ct, DEVICE_HISTORY_ENERGY_KEY as D, withoutCallerStamp as Da, RevConflictError as Di, isObjectInput as Dn, storageOccupancyCapability as Dr, batteryCapability as Dt, DEVICE_ENROLLMENT_TTL_MS as E, userError as Ea, RecordUniqueViolationError as Ei, isLocationEnabled as En, storageMigrationCapability as Er, bareAddonId as Et, DeviceTombstoneSchema as F, asNumber as Fi, localNetworkCapability as Fn, vectorDimFromBase64 as Fr, checkRoleAddress as Ft, KeychainResetRecordSchema as G, customAction as Gi, motionCapability as Gn, compositionItemFieldPath as Gr, dataStoreProviderCapability as Gt, HUB_MDNS_TXT_KEYS as H, collectSecretMarkerRefs as Hi, memoizePinnedFfmpeg as Hn, composedDeviceRef as Hr, coreBlockSourceKind as Ht, FIRST_LEVEL_MACRO_CLASSES as I, asString$1 as Ii, locationIconKey as In, vectorIndexDimConflictError as Ir, composerCapability as It, METHOD_ACCESS_MAP as J, emitDownForOwnedCaps as Ji, objectInputDeclaresAddonId as Jn, createStatefulExpressionMemory as Jr, decodeVectorBase64 as Jt, LOG_LEVEL_RANK as K, defineCustomActions as Ki, normalizeCoreBlockWrite as Kn, compositionSliceKey as Kr, databaseSnapshotCapability as Kt, FieldClaimModeSchema as L, assertTransactScope as Li, logDestinationCapability as Ln, vectorStoreCapability as Lr, compositionFieldKey as Lt, DataStoreDatabaseSchema as M, UnknownRecordKindError as Mi, legacyAutoLinkIds as Mn, userManagementCapability as Mr, calendarsCapability as Mt, DeclaredDevices as N, WELL_KNOWN_TAB_MAP as Ni, legacyModeOf as Nn, validateComposition as Nr, cameraGridLayoutCapability as Nt, DEVICE_NONCE_TTL_MS as O, EventCategory as Oa, SECRET_CLEAR as Oi, isVoidInput as On, storageProviderCapability as Or, buildCapabilityLookup as Ot, DeviceStatusSchema as P, asJsonObject as Pi, lifecycleJobSchema as Pn, validateCustomAddress as Pr, canonicalIconKey as Pt, PREFERENCES_MAX_VALUE_BYTES as Q, historyItemFieldPath as Qi, pickAppLinkHub as Qn, DeviceRole as Qr, deviceCredentialsCapability as Qt, FieldClaimSchema as R, assertValidDeclaration as Ri, logLevelAtMost as Rn, withLocationMode as Rr, compositionSourceRefs as Rt, DATABASE_SNAPSHOT_TIMEOUT_MS as S, sleep as Sa, ReadinessTimeoutError as Si, isArrayOutputSchema as Sn, snapshotCapability as Sr, alertsCapability as St, DERIVED_CAMERA_SILENCED_CAP_NAMES as T, transformSecretWrite as Ta, RecordTooLargeError as Ti, isDefaultAppConnectionEndpoint as Tn, storageCapability as Tr, backupCapability as Tt, KEYCHAIN_RESET_TRIGGER_ACTOR as U, collectZodSecretPaths as Ui, metricsProviderCapability as Un, composedDeviceStableId as Ur, coreBlocksCapability as Ut, HUB_MDNS_SERVICE_TYPE as V, collectSecretLeaves as Vi, mayWriteToLocation as Vn, cloneStatefulExpressionMemory as Vr, coreBlockIdFromAddonId as Vt, KeychainAuditEntrySchema as W, createEvent as Wi, modeMayWrite as Wn, compositionFeatureEnabled as Wr, createDeviceExtensionProvider as Wt, MOTION_CLOSE_AFTER_MS as X, expandCapMethods as Xi, parseAcceleratorFactsJson as Xn, toExpressionValue as Xr, deriveBatteryPresence as Xt, MINUTES_PER_DAY as Y, emitReadiness as Yi, objectInputDeclaresRequiredDeviceId as Yn, disarmRoseMemory as Yr, defineExtensionSlotProvider as Yt, NetworkTunnelStartedDataSchema as Z, formatSecretScope as Zi, parseStreamParamsFormPatch as Zn, DeviceFeature as Zr, describeComposableCaps as Zt, CatalogFileSchema as _, resolveCapMount as _a, RECORD_SWEEP_INTERVAL_MS as _i, gbToBytes as _n, scopesAllowDeviceCap as _r, addonPagesCapability as _t, BaseDevice as a, isSecretMarkerLike as aa, DEVICE_SETTINGS_CONTRIBUTION_METHODS as ai, enumerateInferenceDevices as an, reducePoints as ar, STORAGE_ACCESS_FALLBACK as at, DATABASE_SNAPSHOT_PARTIAL_SUFFIX as b, secretTreeFromPaths as ba, RUNTIME_DEFAULTS as bi, isAlertEpisodeSeverity as bn, shortHostname as br, alertEpisodeId as bt, CAMSTACK_APP_LINK_ORIGIN as c, mapSecretLeaves as ca, FilterRequiredError as ci, evaluateCompositionField as cn, resolveBucketMs as cr, ServerNameSchema as ct, COMPOSED_ITEM_FIXED_FIELDS as d, normalizeSecretOwner as da, InvalidRecordError as di, expressionContainsBuiltinCall as dn, resolveHubAddressRoles as dr, StorageLocationModeSchema as dt, isDeviceConfigCap as ea, errMsg as ei, deviceHistoryCapability as en, platformProbeCapability as er, PreferenceNamespaceSchema as et, COMPOSER_RUNNER_ID as f, parseJsonObject as fa, NoCallerError as fi, extractNestedAddonId as fn, resolveLocationMode as fr, StorageLocationTypeSchema as ft, CalendarPreferencesSchema as g, recordSecretRef as ga, RECORD_DELETE_BATCH as gi, formatMinutes as gn, scopesAllowAddon as gr, UserRecordSchema as gt, CREDENTIAL_TOKEN_AUDIENCE as h, readinessKey as ha, RECORD_BATCH_MAX_BYTES as hi, formatDeviceRevoker as hn, runtimeStatePolicyFor as hr, UNATTRIBUTED_BUCKET_KEY as ht, AlertSchema as i, isSecretMarker as ia, DATAPLANE_SECRET_HEADER as ii, deviceStatusCapability as in, recordsCapability as ir, RecordingStatusSchema as it, DEVICE_TOMBSTONE_RETENTION_MS as j, UnindexedFilterError as ji, keychainCapability as jn, supportedRuntimes as jr, buildStreamParamsConfigSchema as jt, DEVICE_SAN_CREDENTIAL_PREFIX as k, StoredRecordKindDeclarationSchema as ki, kebabToCamel as kn, streamCatalogCapability as kr, buildDeviceEnrollmentLink as kt, CAP_NAMES_WITH_STATUS as l, nodePin as la, ForeignSecretMarkerError as li, evictionPolicyOfLocation as ln, resolveCoreBlockEntry as lr, SsoBridgeClaimsSchema as lt, CORE_BLOCK_ADDON_PREFIX as m, parseSecretRef as ma, RECORD_BATCH_MAX as mi, foldSnapshotByFunction as mn, resolveNotificationTapAddress as mr, TokenScopeSchema as mt, AGENT_MDNS_TXT_KEYS as n, isKeychainStoredField as na, BatchTooLargeError as ni, deviceRemovalHookCapability as nn, ptzAutotrackCapability as nr, RECORDING_SOURCE_CAMSTACK_ADDON as nt, BatteryStatusSchema as o, isSecretRefOwnedBy as oa, DEVICE_STATUS_METHOD as oi, enumerateItemArrayFields as on, replacedFieldKeys as or, STREAM_PROFILE_META as ot, CORE_BLOCKS_ADDON_ID as p, parseJsonUnknown as pa, PlaintextSecretError as pi, filesystemBrowseCapability as pn, resolveMethodAuth as pr, StorageMigrationJobSchema as pt, LegacyStorageLocationDefaultSchema as q, defineRecordKinds as qi, normalizeUnit as qn, compositionSourceKey as qr, declarationOwnerNodeId as qt, ALL_CAPABILITY_DEFINITIONS as r, isSecretClear as ra, CALLER_STAMPED_CAPABILITIES as ri, deviceStateCapability as rn, recordEntriesCapability as rr, ROOT_BUCKET_KEY as rt, CAMERA_SWITCH_ORDER as s, makeSecretMarker as sa, DeclarationRefusedError as si, enumerateSchemaFields as sn, resolveAppConnections as sr, ScopedTokenSchema as st, AGENT_MDNS_SERVICE_TYPE as t, isEvent as ta, BaseAddon as ti, deviceManagerCapability as tn, procedureAuthKey as tr, PreferenceValueSchema as tt, CATALOG_LANGS as u, normalizeNodeId as ua, HISTORY_DEFAULT_MIN_INTERVAL_MS as ui, expandContainer as un, resolveCoreBlockFiles as ur, StorageCleanupJobSchema as ut, CoreBlockSchema as v, resolveSecretMarkers as va, REDACTED_SECRET as vi, interpolate as vn, scoreRuntimes as vr, addonSettingsCapability as vt, DAY_NAMES as w, toSecretFieldView as wa, RecordNotFoundError as wi, isCredentialTokenPayload as wn, storageAdminCapability as wr, authProviderCapability as wt, DATABASE_SNAPSHOT_SUFFIX as x, secretTreeFromSchema as xa, ReadinessRegistry as xi, isAppLinkBase as xn, siteZoneKey as xr, alertEpisodePayload as xt, CredentialTokenClaimsSchema as y, scopeKey as ya, REMOVE_LEAF as yi, isAlertEpisodeOpen as yn, settingsStoreCapability as yr, addonWidgetsCapability as yt, HISTORY_CATALOG as z, buildSecretRef as zi, looseSchema as zn, COMPOSER_ADDON_ID as zr, coreBlockAddonId as zt };
95691
+ export { PREFERENCES_MAX_VALUE_BYTES as $, defineCustomActions as $i, objectInputDeclaresRequiredDeviceId as $n, compositionSliceKey as $r, deriveBatteryPresence as $t, DEVICE_SAN_USER_PREFIX as A, toNodeId as Aa, RecordKindDeclarationSchema as Ai, isLocationEnabled as An, storageAdminCapability as Ar, buildCapabilityLookup as At, HISTORY_CATALOG as B, WELL_KNOWN_TAB_MAP as Bi, locationIconKey as Bn, validateComposition as Br, compositionFieldKey as Bt, DATA_STORE_DATABASES as C, recordSecretRef as Ca, RECORD_DELETE_BATCH as Ci, isAlertEpisodeOpen as Cn, scopesAllowDeviceCap as Cr, alertEpisodePayload as Ct, DEVICE_HISTORY_ENERGY_KEY as D, secretTreeFromPaths as Da, RUNTIME_DEFAULTS as Di, isCollectionArrayMethod as Dn, siteZoneKey as Dr, backupCapability as Dt, DEVICE_ENROLLMENT_TTL_MS as E, scopeKey as Ea, REMOVE_LEAF as Ei, isArrayOutputSchema as En, shortHostname as Er, authProviderCapability as Et, DeviceStatusSchema as F, EventCategory as Fa, SECRET_CLEAR as Fi, keychainCapability as Fn, storedFromReady as Fr, calendarsCapability as Ft, KeychainAuditEntrySchema as G, assertValidDeclaration as Gi, mayWriteToLocation as Gn, withLocationMode as Gr, coreBlockSourceKind as Gt, HUB_MDNS_SERVICE_TYPE as H, asNumber as Hi, logLevelAtMost as Hn, vectorDimFromBase64 as Hr, coreBlockAddonId as Ht, DeviceTombstoneSchema as I, StoredRecordKindDeclarationSchema as Ii, legacyAutoLinkIds as In, streamCatalogCapability as Ir, cameraGridLayoutCapability as It, LegacyStorageLocationDefaultSchema as J, collectSecretLeaves as Ji, modeMayWrite as Jn, cloneStatefulExpressionMemory as Jr, dataStoreProviderCapability as Jt, KeychainResetRecordSchema as K, buildSecretRef as Ki, memoizePinnedFfmpeg as Kn, COMPOSER_ADDON_ID as Kr, coreBlocksCapability as Kt, FIRST_LEVEL_MACRO_CLASSES as L, TransactRefusedError as Li, legacyModeOf as Ln, streamQualityLabel as Lr, canonicalIconKey as Lt, DISPLAY_PRESETS as M, transformSecretWrite as Ma, RecordTooLargeError as Mi, isVoidInput as Mn, storageMigrationCapability as Mr, buildDeviceSignatureMessage as Mt, DataStoreDatabaseSchema as N, userError as Na, RecordUniqueViolationError as Ni, kebabToCamel as Nn, storageOccupancyCapability as Nr, buildStreamParamsConfigSchema as Nt, DEVICE_NONCE_TTL_MS as O, secretTreeFromSchema as Oa, ReadinessRegistry as Oi, isCredentialTokenPayload as On, snapshotCapability as Or, bareAddonId as Ot, DeclaredDevices as P, withoutCallerStamp as Pa, RevConflictError as Pi, keychainAdminCapability as Pn, storageProviderCapability as Pr, bundledCamstack as Pt, NetworkTunnelStartedDataSchema as Q, customAction as Qi, objectInputDeclaresAddonId as Qn, compositionItemFieldPath as Qr, defineExtensionSlotProvider as Qt, FieldClaimModeSchema as R, UnindexedFilterError as Ri, lifecycleJobSchema as Rn, supportedRuntimes as Rr, checkRoleAddress as Rt, DATABASE_SNAPSHOT_TIMEOUT_MS as S, readinessKey as Sa, RECORD_BATCH_MAX_BYTES as Si, interpolate as Sn, scopesAllowAddon as Sr, alertEpisodeId as St, DERIVED_CAMERA_SILENCED_CAP_NAMES as T, resolveSecretMarkers as Ta, REDACTED_SECRET as Ti, isAppLinkBase as Tn, settingsStoreCapability as Tr, armRemovalReconcile as Tt, HUB_MDNS_TXT_KEYS as U, asString$1 as Ui, looseSchema as Un, vectorIndexDimConflictError as Ur, coreBlockComposition as Ut, HISTORY_ITEM_CATALOG as V, asJsonObject as Vi, logDestinationCapability as Vn, validateCustomAddress as Vr, compositionSourceRefs as Vt, KEYCHAIN_RESET_TRIGGER_ACTOR as W, assertTransactScope as Wi, mayReadLocation as Wn, vectorStoreCapability as Wr, coreBlockIdFromAddonId as Wt, MINUTES_PER_DAY as X, collectZodSecretPaths as Xi, normalizeCoreBlockWrite as Xn, composedDeviceStableId as Xr, declarationOwnerNodeId as Xt, METHOD_ACCESS_MAP as Y, collectSecretMarkerRefs as Yi, motionCapability as Yn, composedDeviceRef as Yr, databaseSnapshotCapability as Yt, MOTION_CLOSE_AFTER_MS as Z, createEvent as Zi, normalizeUnit as Zn, compositionFeatureEnabled as Zr, decodeVectorBase64 as Zt, CatalogFileSchema as _, normalizeNodeId as _a, HISTORY_DEFAULT_MIN_INTERVAL_MS as _i, filesystemBrowseCapability as _n, resolveHubAddressRoles as _r, UNATTRIBUTED_BUCKET_KEY as _t, BaseDevice as a, historyItemFieldPath as aa, DeviceRole as ai, deviceRemovalHookCapability as an, planComposition as ar, ROOT_BUCKET_KEY as at, DATABASE_SNAPSHOT_PARTIAL_SUFFIX as b, parseJsonUnknown as ba, PlaintextSecretError as bi, formatMinutes as bn, resolveNotificationTapAddress as br, addonSettingsCapability as bt, CAMSTACK_APP_LINK_ORIGIN as c, isEvent as ca, BaseAddon as ci, displayPaletteCapability as cn, ptzAutotrackCapability as cr, STREAM_PROFILE_META as ct, COMPOSED_ITEM_FIXED_FIELDS as d, isSecretMarker as da, DATAPLANE_SECRET_HEADER as di, enumerateSchemaFields as dn, reducePoints as dr, SsoBridgeClaimsSchema as dt, defineRecordKinds as ea, compositionSourceKey as ei, describeComposableCaps as en, paletteFromInput as er, PaletteRejectedError as et, COMPOSER_RUNNER_ID as f, isSecretMarkerLike as fa, DEVICE_SETTINGS_CONTRIBUTION_METHODS as fi, evaluateCompositionField as fn, replacedFieldKeys as fr, StorageCleanupJobSchema as ft, CalendarPreferencesSchema as g, nodePin as ga, ForeignSecretMarkerError as gi, extractNestedAddonId as gn, resolveCoreBlockFiles as gr, TokenScopeSchema as gt, CREDENTIAL_TOKEN_AUDIENCE as h, mapSecretLeaves as ha, FilterRequiredError as hi, expressionContainsBuiltinCall as hn, resolveCoreBlockEntry as hr, StorageMigrationJobSchema as ht, AlertSchema as i, formatSecretScope as ia, DeviceFeature as ii, deviceManagerCapability as in, pickAppLinkHub as ir, RECORDING_SOURCE_CAMSTACK_ADDON as it, DEVICE_TOMBSTONE_RETENTION_MS as j, toSecretFieldView as ja, RecordNotFoundError as ji, isObjectInput as jn, storageCapability as jr, buildDeviceEnrollmentLink as jt, DEVICE_SAN_CREDENTIAL_PREFIX as k, sleep as ka, ReadinessTimeoutError as ki, isDefaultAppConnectionEndpoint as kn, splitTranslationRef as kr, batteryCapability as kt, CAP_NAMES_WITH_STATUS as l, isKeychainStoredField as la, BatchTooLargeError as li, enumerateInferenceDevices as ln, recordEntriesCapability as lr, ScopedTokenSchema as lt, CORE_BLOCK_ADDON_PREFIX as m, makeSecretMarker as ma, DeclarationRefusedError as mi, expandContainer as mn, resolveBucketMs as mr, StorageLocationTypeSchema as mt, AGENT_MDNS_TXT_KEYS as n, emitReadiness as na, disarmRoseMemory as ni, deviceExtensionCapability as nn, parseAcceleratorFactsJson as nr, PreferenceNamespaceSchema as nt, BatteryStatusSchema as o, hydrateSchema as oa, DeviceType as oi, deviceStateCapability as on, platformProbeCapability as or, RecordingStatusSchema as ot, CORE_BLOCKS_ADDON_ID as p, isSecretRefOwnedBy as pa, DEVICE_STATUS_METHOD as pi, evictionPolicyOfLocation as pn, resolveAppConnections as pr, StorageLocationModeSchema as pt, LOG_LEVEL_RANK as q, collectSecretConfigKeys as qi, metricsProviderCapability as qn, buildFfmpegArgs as qr, createDeviceExtensionProvider as qt, ALL_CAPABILITY_DEFINITIONS as r, expandCapMethods as ra, toExpressionValue as ri, deviceHistoryCapability as rn, parseStreamParamsFormPatch as rr, PreferenceValueSchema as rt, CAMERA_SWITCH_ORDER as s, isDeviceConfigCap as sa, errMsg as si, deviceStatusCapability as sn, procedureAuthKey as sr, STORAGE_ACCESS_FALLBACK as st, AGENT_MDNS_SERVICE_TYPE as t, emitDownForOwnedCaps as ta, createStatefulExpressionMemory as ti, deviceCredentialsCapability as tn, paletteFromStored as tr, PreferenceDeviceIdSchema as tt, CATALOG_LANGS as u, isSecretClear as ua, CALLER_STAMPED_CAPABILITIES as ui, enumerateItemArrayFields as un, recordsCapability as ur, ServerNameSchema as ut, CoreBlockSchema as v, normalizeSecretOwner as va, InvalidRecordError as vi, foldSnapshotByFunction as vn, resolveLocationMode as vr, UserRecordSchema as vt, DAY_NAMES as w, resolveCapMount as wa, RECORD_SWEEP_INTERVAL_MS as wi, isAlertEpisodeSeverity as wn, scoreRuntimes as wr, alertsCapability as wt, DATABASE_SNAPSHOT_SUFFIX as x, parseSecretRef as xa, RECORD_BATCH_MAX as xi, gbToBytes as xn, runtimeStatePolicyFor as xr, addonWidgetsCapability as xt, CredentialTokenClaimsSchema as y, parseJsonObject as ya, NoCallerError as yi, formatDeviceRevoker as yn, resolveMethodAuth as yr, addonPagesCapability as yt, FieldClaimSchema as z, UnknownRecordKindError as zi, localNetworkCapability as zn, userManagementCapability as zr, composerCapability as zt };