@camstack/addon-model-studio 1.1.317 → 1.1.319

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 (20) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{MotionZonesSettings-CMwAQd-Y.mjs → MotionZonesSettings-Dc4Kv4_B.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-wx9DyDgK.mjs → PrivacyMaskSettings-QuXzMphU.mjs} +4 -4
  4. package/dist/{SceneMonitorEditor-jDNxVNGw.mjs → SceneMonitorEditor-DTMWWxoE.mjs} +3 -3
  5. package/dist/_stub.js +1649 -1585
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CsVbgmDJ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BEwAo6V7.mjs} +3 -3
  7. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-COf25W99.mjs +26 -0
  8. package/dist/addon-model-studio.css +1 -1
  9. package/dist/{hostInit-l8UwwnTV.mjs → hostInit-C5q4H84T.mjs} +2 -2
  10. package/dist/model-studio.addon.js +490 -11
  11. package/dist/model-studio.addon.mjs +490 -11
  12. package/dist/{player-overlays-B0MiJ5R6.mjs → player-overlays-CGbBkJ3j.mjs} +1 -1
  13. package/dist/remoteEntry.js +1 -1
  14. package/dist/{responsive-BHzVDMt-.mjs → responsive-Cw4YAdTr.mjs} +1 -1
  15. package/dist/{scene-monitor-copy-CBNkkNvs.mjs → scene-monitor-copy-Dz9xLx8-.mjs} +1 -1
  16. package/dist/{square-SIMvtgyo.mjs → square-Dyvwj3m5.mjs} +1 -1
  17. package/dist/{trash-2-CTpwDufe.mjs → trash-2-CPAMsWG5.mjs} +1 -1
  18. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CkwPjS5o.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DWDyoPcG.mjs} +1 -1
  19. package/package.json +1 -1
  20. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cxz43vtF.mjs +0 -26
@@ -5816,7 +5816,7 @@ var ZodIssueCode = {
5816
5816
  var ZodFirstPartyTypeKind;
5817
5817
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5818
5818
  //#endregion
5819
- //#region ../types/dist/sleep-BAvUCi_2.mjs
5819
+ //#region ../types/dist/sleep-C_u6cEAJ.mjs
5820
5820
  /**
5821
5821
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5822
5822
  * window to float samples (D455).
@@ -9060,6 +9060,7 @@ var CAP_NAMES = Object.freeze([
9060
9060
  "network-link",
9061
9061
  "network-quality",
9062
9062
  "node-certificates",
9063
+ "node-removal-hook",
9063
9064
  "nodes",
9064
9065
  "notification-output",
9065
9066
  "notification-rules",
@@ -9090,6 +9091,7 @@ var CAP_NAMES = Object.freeze([
9090
9091
  "recording-onboard",
9091
9092
  "recording-signal",
9092
9093
  "records",
9094
+ "remote",
9093
9095
  "running-state",
9094
9096
  "scene-monitor",
9095
9097
  "script-runner",
@@ -9113,6 +9115,7 @@ var CAP_NAMES = Object.freeze([
9113
9115
  "system",
9114
9116
  "tamper",
9115
9117
  "temperature-sensor",
9118
+ "template",
9116
9119
  "terminal-session",
9117
9120
  "toast",
9118
9121
  "training",
@@ -10053,6 +10056,11 @@ Object.freeze({
10053
10056
  "standby"
10054
10057
  ]
10055
10058
  },
10059
+ {
10060
+ "path": "stateSource",
10061
+ "valueType": "enum",
10062
+ "enumValues": ["reported", "assumed"]
10063
+ },
10056
10064
  {
10057
10065
  "path": "volumeLevel",
10058
10066
  "valueType": "number"
@@ -10328,6 +10336,18 @@ Object.freeze({
10328
10336
  {
10329
10337
  "path": "volume",
10330
10338
  "valueType": "number"
10339
+ },
10340
+ {
10341
+ "path": "lastFeedGrams",
10342
+ "valueType": "number"
10343
+ },
10344
+ {
10345
+ "path": "lastFeedHopper1",
10346
+ "valueType": "number"
10347
+ },
10348
+ {
10349
+ "path": "lastFeedHopper2",
10350
+ "valueType": "number"
10331
10351
  }
10332
10352
  ],
10333
10353
  "power-meter": [
@@ -11219,7 +11239,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
11219
11239
  return DeviceRole;
11220
11240
  }({});
11221
11241
  //#endregion
11222
- //#region ../types/dist/composition-DpFv_J6D.mjs
11242
+ //#region ../types/dist/composition-bIBW5_13.mjs
11223
11243
  /**
11224
11244
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11225
11245
  *
@@ -42966,6 +42986,14 @@ method(object({
42966
42986
  kind: "mutation",
42967
42987
  auth: "admin"
42968
42988
  });
42989
+ method(object({
42990
+ nodeId: string().min(1),
42991
+ /** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
42992
+ removedAt: number()
42993
+ }), object({ counts: record(string(), number().int().nonnegative()) }), {
42994
+ kind: "mutation",
42995
+ auth: "admin"
42996
+ });
42969
42997
  /**
42970
42998
  * `device-removal-hook` — the reliable way an addon learns a device was DELETED,
42971
42999
  * so it can delete what it keeps for that device (D865).
@@ -57984,6 +58012,318 @@ DeviceType.Light, method(object({
57984
58012
  level: number().min(0).max(100),
57985
58013
  lastChangedAt: number()
57986
58014
  });
58015
+ /**
58016
+ * The role vocabulary of a remote (D963): what a button MEANS, independent of
58017
+ * how it is wired. A layout template places buttons by role; a device binds a
58018
+ * role to an action; an exporter asks for a role by name. Roles are shared so
58019
+ * one layout fits every appliance and one voice command fits every binding.
58020
+ *
58021
+ * A role outside this list is `custom:<key>` — the operator's own button (a
58022
+ * SmartIR source, a channel preset). The key is a lowercase slug.
58023
+ */
58024
+ var REMOTE_KNOWN_ROLES = [
58025
+ "power",
58026
+ "power_on",
58027
+ "power_off",
58028
+ "volume_up",
58029
+ "volume_down",
58030
+ "mute",
58031
+ "channel_up",
58032
+ "channel_down",
58033
+ "up",
58034
+ "down",
58035
+ "left",
58036
+ "right",
58037
+ "ok",
58038
+ "back",
58039
+ "home",
58040
+ "menu",
58041
+ "info",
58042
+ "guide",
58043
+ "exit",
58044
+ "input",
58045
+ "play",
58046
+ "pause",
58047
+ "play_pause",
58048
+ "stop",
58049
+ "next",
58050
+ "previous",
58051
+ "fast_forward",
58052
+ "rewind",
58053
+ "digit_0",
58054
+ "digit_1",
58055
+ "digit_2",
58056
+ "digit_3",
58057
+ "digit_4",
58058
+ "digit_5",
58059
+ "digit_6",
58060
+ "digit_7",
58061
+ "digit_8",
58062
+ "digit_9"
58063
+ ];
58064
+ var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
58065
+ var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
58066
+ function isRemoteKnownRole(value) {
58067
+ return KNOWN_ROLES.has(value);
58068
+ }
58069
+ function isRemoteCustomKey(key) {
58070
+ return CUSTOM_KEY_RE.test(key);
58071
+ }
58072
+ /** The key of a `custom:<key>` role, or null for any other string. */
58073
+ function customKeyOfRole(role) {
58074
+ if (!role.startsWith("custom:")) return null;
58075
+ const key = role.slice(7);
58076
+ return isRemoteCustomKey(key) ? key : null;
58077
+ }
58078
+ function isRemoteRole(value) {
58079
+ return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
58080
+ }
58081
+ var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
58082
+ var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
58083
+ var RemoteCustomButtonSchema = object({
58084
+ /** The slug after `custom:` in the role. */
58085
+ key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
58086
+ /** What the operator calls it, and what a voice command may name. */
58087
+ name: string().min(1).max(60)
58088
+ });
58089
+ var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
58090
+ var RemoteConfigSchema = object({
58091
+ layoutTemplateId: string().min(1).nullable(),
58092
+ /**
58093
+ * The transmitter device new bindings and an import send through. A binding
58094
+ * names its own device, so one command may override it.
58095
+ */
58096
+ defaultTransmitterId: number().int().nonnegative().nullable().default(null),
58097
+ /** Keyed by role. A role with no entry falls back to the native cap. */
58098
+ bindings: record(string(), RemoteBindingSchema),
58099
+ customButtons: array(RemoteCustomButtonSchema).max(100),
58100
+ power: object({ mode: RemotePowerModeSchema })
58101
+ }).superRefine((config, ctx) => {
58102
+ const roles = Object.keys(config.bindings);
58103
+ if (roles.length > 200) ctx.addIssue({
58104
+ code: "custom",
58105
+ message: "too many bindings",
58106
+ path: ["bindings"]
58107
+ });
58108
+ for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
58109
+ code: "custom",
58110
+ message: `"${role}" is not a role`,
58111
+ path: ["bindings", role]
58112
+ });
58113
+ const keys = /* @__PURE__ */ new Set();
58114
+ config.customButtons.forEach((button, index) => {
58115
+ if (keys.has(button.key)) ctx.addIssue({
58116
+ code: "custom",
58117
+ message: `custom button "${button.key}" is listed twice`,
58118
+ path: [
58119
+ "customButtons",
58120
+ index,
58121
+ "key"
58122
+ ]
58123
+ });
58124
+ keys.add(button.key);
58125
+ });
58126
+ for (const role of roles) {
58127
+ const key = customKeyOfRole(role);
58128
+ if (key !== null && !keys.has(key)) ctx.addIssue({
58129
+ code: "custom",
58130
+ message: `${role} is bound but has no entry in customButtons`,
58131
+ path: ["bindings", role]
58132
+ });
58133
+ }
58134
+ });
58135
+ object({
58136
+ power: object({
58137
+ state: _enum(["on", "off"]),
58138
+ at: number()
58139
+ }).nullable(),
58140
+ muted: object({
58141
+ value: boolean(),
58142
+ at: number()
58143
+ }).nullable()
58144
+ });
58145
+ var RemoteLayoutButtonSchema = object({
58146
+ id: string().min(1).max(40),
58147
+ /** 0-based grid position. */
58148
+ row: number().int().min(0).max(24),
58149
+ col: number().int().min(0).max(24),
58150
+ rowSpan: number().int().min(1).max(24),
58151
+ colSpan: number().int().min(1).max(24),
58152
+ icon: string().min(1).max(60).optional(),
58153
+ label: string().min(1).max(40).optional(),
58154
+ role: RemoteRoleSchema
58155
+ });
58156
+ object({
58157
+ columns: number().int().min(1).max(24),
58158
+ rows: number().int().min(1).max(24),
58159
+ buttons: array(RemoteLayoutButtonSchema).max(200)
58160
+ }).superRefine((grid, ctx) => {
58161
+ const ids = /* @__PURE__ */ new Set();
58162
+ const taken = /* @__PURE__ */ new Map();
58163
+ grid.buttons.forEach((button, index) => {
58164
+ if (ids.has(button.id)) ctx.addIssue({
58165
+ code: "custom",
58166
+ message: `button id "${button.id}" is used twice`,
58167
+ path: [
58168
+ "buttons",
58169
+ index,
58170
+ "id"
58171
+ ]
58172
+ });
58173
+ ids.add(button.id);
58174
+ if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
58175
+ ctx.addIssue({
58176
+ code: "custom",
58177
+ message: `button "${button.id}" leaves the grid`,
58178
+ path: ["buttons", index]
58179
+ });
58180
+ return;
58181
+ }
58182
+ for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
58183
+ const cell = `${r}:${c}`;
58184
+ const other = taken.get(cell);
58185
+ if (other !== void 0) {
58186
+ ctx.addIssue({
58187
+ code: "custom",
58188
+ message: `buttons "${other}" and "${button.id}" overlap`,
58189
+ path: ["buttons", index]
58190
+ });
58191
+ return;
58192
+ }
58193
+ taken.set(cell, button.id);
58194
+ }
58195
+ });
58196
+ });
58197
+ var RemoteBoundCommandSchema = object({
58198
+ role: RemoteRoleSchema,
58199
+ /** The operator's name for a custom button; absent for a known role. */
58200
+ label: string().optional(),
58201
+ custom: boolean()
58202
+ });
58203
+ var RemoteCommandListSchema = object({
58204
+ layoutTemplateId: string().nullable(),
58205
+ power: object({ mode: RemotePowerModeSchema }),
58206
+ /** Only the roles that are BOUND — the ones a press can reach. */
58207
+ commands: array(RemoteBoundCommandSchema)
58208
+ });
58209
+ var RemoteRefusalReasonSchema = _enum([
58210
+ "no-remote",
58211
+ "unbound-role",
58212
+ "action-failed"
58213
+ ]);
58214
+ var RemoteSendResultSchema = discriminatedUnion("status", [
58215
+ object({
58216
+ status: literal("sent"),
58217
+ /** How many times the action ran. */
58218
+ sends: number().int().min(1)
58219
+ }),
58220
+ object({
58221
+ status: literal("skipped"),
58222
+ reason: literal("already-in-state")
58223
+ }),
58224
+ object({
58225
+ status: literal("refused"),
58226
+ reason: RemoteRefusalReasonSchema,
58227
+ detail: string().optional()
58228
+ })
58229
+ ]);
58230
+ var RemoteMediaCommandSchema = _enum([
58231
+ "play",
58232
+ "pause",
58233
+ "stop",
58234
+ "next",
58235
+ "previous",
58236
+ "setMute",
58237
+ "selectSource"
58238
+ ]);
58239
+ /** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
58240
+ var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
58241
+ var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
58242
+ status: literal("refused"),
58243
+ reason: _enum(["unknown-template", "not-a-media-player"]),
58244
+ detail: string()
58245
+ })]);
58246
+ var deviceInput = object({ deviceId: number().int().nonnegative() });
58247
+ DeviceType.MediaPlayer;
58248
+ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
58249
+ kind: "mutation",
58250
+ auth: "admin"
58251
+ }), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
58252
+ role: RemoteRoleSchema,
58253
+ /** Sends in a row (volume steps). */
58254
+ repeat: number().int().min(1).max(50).default(1)
58255
+ }), RemoteSendResultSchema, {
58256
+ kind: "mutation",
58257
+ auth: "protected"
58258
+ }), method(deviceInput.extend({
58259
+ command: RemoteMediaCommandSchema,
58260
+ muted: boolean().optional(),
58261
+ source: string().optional(),
58262
+ repeat: number().int().min(1).max(50).default(1)
58263
+ }), RemoteMediaCommandResultSchema, {
58264
+ kind: "mutation",
58265
+ auth: "protected"
58266
+ });
58267
+ var TemplateKindSchema = _enum(["remote"]);
58268
+ /**
58269
+ * template — the generic store of reusable, named operator data (D963). A
58270
+ * record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
58271
+ * button grid of a remote) and the schema each payload must satisfy are
58272
+ * declared by the system in `template-kinds.ts`. Nothing here is specific to a
58273
+ * kind: the engine validates a payload against its kind's schema and, on a
58274
+ * delete, asks the kind's owner whether anything still points at the record.
58275
+ *
58276
+ * Every refusal is a typed result — a UI says "unknown kind" or names the
58277
+ * devices that still use a template, without parsing text.
58278
+ */
58279
+ var TemplateRecordSchema = object({
58280
+ id: string().min(1),
58281
+ kind: TemplateKindSchema,
58282
+ name: string().min(1).max(120),
58283
+ /** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
58284
+ payload: unknown(),
58285
+ createdAt: number(),
58286
+ updatedAt: number()
58287
+ });
58288
+ var TemplateWriteResultSchema = discriminatedUnion("status", [object({
58289
+ status: literal("saved"),
58290
+ template: TemplateRecordSchema
58291
+ }), object({
58292
+ status: literal("refused"),
58293
+ reason: _enum(["invalid-payload", "not-found"]),
58294
+ detail: string()
58295
+ })]);
58296
+ /** A device still pointing at a template. */
58297
+ var TemplateUserSchema = object({
58298
+ deviceId: number().int().nonnegative(),
58299
+ name: string()
58300
+ });
58301
+ var TemplateDeleteResultSchema = discriminatedUnion("status", [
58302
+ object({ status: literal("deleted") }),
58303
+ object({ status: literal("not-found") }),
58304
+ object({
58305
+ status: literal("in-use"),
58306
+ devices: array(TemplateUserSchema).min(1)
58307
+ })
58308
+ ]);
58309
+ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
58310
+ kind: TemplateKindSchema,
58311
+ name: string().min(1).max(120),
58312
+ payload: unknown()
58313
+ }), TemplateWriteResultSchema, {
58314
+ kind: "mutation",
58315
+ auth: "admin"
58316
+ }), method(object({
58317
+ id: string().min(1),
58318
+ name: string().min(1).max(120).optional(),
58319
+ payload: unknown().optional()
58320
+ }), TemplateWriteResultSchema, {
58321
+ kind: "mutation",
58322
+ auth: "admin"
58323
+ }), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
58324
+ kind: "mutation",
58325
+ auth: "admin"
58326
+ });
57987
58327
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
57988
58328
  kind: "mutation",
57989
58329
  auth: "protected"
@@ -60733,9 +61073,35 @@ var MediaInfoSchema = object({
60733
61073
  /** Optional cover-art / thumbnail URL. */
60734
61074
  imageUrl: string().optional()
60735
61075
  });
61076
+ /**
61077
+ * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
61078
+ * the device said so. `assumed`: the driver has no feedback (infrared) and
61079
+ * tracks what it last SENT; it moves only after a send was accepted, and a
61080
+ * human at the real remote makes it wrong. A UI shows an assumed value as a
61081
+ * guess, never as a reading.
61082
+ */
61083
+ var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
61084
+ /** The fields of a media-player status a driver can only guess. */
61085
+ var MediaPlayerAssumedFieldSchema = _enum([
61086
+ "state",
61087
+ "volumeLevel",
61088
+ "isMuted",
61089
+ "source"
61090
+ ]);
60736
61091
  object({
60737
61092
  /** Playback lifecycle state. */
60738
61093
  state: MediaPlayerStateSchema,
61094
+ /**
61095
+ * Whether the state fields are readings or the driver's own bookkeeping.
61096
+ * A slice written before this field existed parses as `reported`.
61097
+ */
61098
+ stateSource: MediaPlayerStateSourceSchema.default("reported"),
61099
+ /**
61100
+ * Which fields are the driver's own guess. `stateSource` is `assumed` when
61101
+ * this is not empty; a field not listed here is a reading even then (power
61102
+ * from a running-state source, mute guessed from the last send).
61103
+ */
61104
+ assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
60739
61105
  /** Volume as 0..100 inclusive. Null when the device has no volume
60740
61106
  * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
60741
61107
  volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -62176,6 +62542,14 @@ object({
62176
62542
  feedSound: boolean(),
62177
62543
  /** Speaker / prompt volume level (device-scaled integer). */
62178
62544
  volume: number().meta(readingMeta("none")),
62545
+ /** Portion (grams) of the last manual feed sent from a single-hopper
62546
+ * stepper — the default the next manual feed starts from. Persisted per
62547
+ * device by the provider; null until a manual feed has been sent. */
62548
+ lastFeedGrams: gramsPortion.nullable(),
62549
+ /** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
62550
+ lastFeedHopper1: gramsPortion.nullable(),
62551
+ /** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
62552
+ lastFeedHopper2: gramsPortion.nullable(),
62179
62553
  /** Ms epoch when the slice was last refreshed from the cloud. */
62180
62554
  lastFetchedAt: number()
62181
62555
  });
@@ -66817,9 +67191,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
66817
67191
  kind: "mutation",
66818
67192
  auth: "admin"
66819
67193
  });
67194
+ discriminatedUnion("kind", [object({
67195
+ kind: literal("raw"),
67196
+ timings: array(number().int()),
67197
+ settings: TransmitSettingsSchema.optional()
67198
+ }), object({
67199
+ kind: literal("pronto"),
67200
+ code: string()
67201
+ })]);
66820
67202
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
66821
67203
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
66822
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
67204
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
66823
67205
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
66824
67206
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
66825
67207
  new Set(CAP_NAMES);
@@ -71768,6 +72150,13 @@ Object.freeze({
71768
72150
  access: "create",
71769
72151
  role: "admin"
71770
72152
  },
72153
+ "nodeRemovalHook.onNodeRemoved": {
72154
+ capName: "node-removal-hook",
72155
+ capScope: "system",
72156
+ addonId: null,
72157
+ access: "create",
72158
+ role: "admin"
72159
+ },
71771
72160
  "nodes.clusterAddonStatus": {
71772
72161
  capName: "nodes",
71773
72162
  capScope: "system",
@@ -74659,6 +75048,41 @@ Object.freeze({
74659
75048
  access: "create",
74660
75049
  role: "admin"
74661
75050
  },
75051
+ "remote.getConfig": {
75052
+ capName: "remote",
75053
+ capScope: "system",
75054
+ addonId: null,
75055
+ access: "view",
75056
+ role: "admin"
75057
+ },
75058
+ "remote.listCommands": {
75059
+ capName: "remote",
75060
+ capScope: "system",
75061
+ addonId: null,
75062
+ access: "view",
75063
+ role: "admin"
75064
+ },
75065
+ "remote.sendCommand": {
75066
+ capName: "remote",
75067
+ capScope: "system",
75068
+ addonId: null,
75069
+ access: "create",
75070
+ role: "admin"
75071
+ },
75072
+ "remote.sendMediaCommand": {
75073
+ capName: "remote",
75074
+ capScope: "system",
75075
+ addonId: null,
75076
+ access: "create",
75077
+ role: "admin"
75078
+ },
75079
+ "remote.setConfig": {
75080
+ capName: "remote",
75081
+ capScope: "system",
75082
+ addonId: null,
75083
+ access: "create",
75084
+ role: "admin"
75085
+ },
74662
75086
  "runningState.getStatus": {
74663
75087
  capName: "running-state",
74664
75088
  capScope: "device",
@@ -75849,6 +76273,41 @@ Object.freeze({
75849
76273
  access: "view",
75850
76274
  role: "viewer"
75851
76275
  },
76276
+ "template.create": {
76277
+ capName: "template",
76278
+ capScope: "system",
76279
+ addonId: null,
76280
+ access: "create",
76281
+ role: "admin"
76282
+ },
76283
+ "template.delete": {
76284
+ capName: "template",
76285
+ capScope: "system",
76286
+ addonId: null,
76287
+ access: "delete",
76288
+ role: "admin"
76289
+ },
76290
+ "template.get": {
76291
+ capName: "template",
76292
+ capScope: "system",
76293
+ addonId: null,
76294
+ access: "view",
76295
+ role: "admin"
76296
+ },
76297
+ "template.list": {
76298
+ capName: "template",
76299
+ capScope: "system",
76300
+ addonId: null,
76301
+ access: "view",
76302
+ role: "admin"
76303
+ },
76304
+ "template.update": {
76305
+ capName: "template",
76306
+ capScope: "system",
76307
+ addonId: null,
76308
+ access: "create",
76309
+ role: "admin"
76310
+ },
75852
76311
  "terminalSession.adoptLegacyMonitor": {
75853
76312
  capName: "terminal-session",
75854
76313
  capScope: "system",
@@ -80641,6 +81100,7 @@ var SYSTEM_CAP_VOCABULARY = {
80641
81100
  "device-manager": system("the device registry itself — rename, move and remove are administration"),
80642
81101
  "device-provider": system(INTERNAL),
80643
81102
  "device-removal-hook": system(INTERNAL),
81103
+ "node-removal-hook": system(INTERNAL),
80644
81104
  "device-state": system("the runtime-state mirror every trigger already reads through"),
80645
81105
  "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
80646
81106
  "embedding-encoder": system(ML),
@@ -80680,6 +81140,7 @@ var SYSTEM_CAP_VOCABULARY = {
80680
81140
  "recording-archive": system(STORAGE),
80681
81141
  "recording-export": system("recording exports — requested from the timeline, not an automation step"),
80682
81142
  records: system(INTERNAL),
81143
+ remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
80683
81144
  "server-management": system(CLUSTER),
80684
81145
  "settings-store": system(INTERNAL),
80685
81146
  "smtp-provider": system(INTERNAL),
@@ -80692,6 +81153,7 @@ var SYSTEM_CAP_VOCABULARY = {
80692
81153
  "storage-provider": system(STORAGE),
80693
81154
  "stream-broker": system(PIPELINE),
80694
81155
  system: system(CLUSTER),
81156
+ template: system("operator-authored templates — edited in their own editor, never actuated"),
80695
81157
  "terminal-session": system(CLUSTER),
80696
81158
  toast: system(UI_PLUMBING),
80697
81159
  training: system(ML),
@@ -83118,6 +83580,31 @@ Object.freeze({
83118
83580
  form: "single",
83119
83581
  optional: true
83120
83582
  }],
83583
+ "remote.getConfig": [{
83584
+ name: "deviceId",
83585
+ form: "single",
83586
+ optional: false
83587
+ }],
83588
+ "remote.listCommands": [{
83589
+ name: "deviceId",
83590
+ form: "single",
83591
+ optional: false
83592
+ }],
83593
+ "remote.sendCommand": [{
83594
+ name: "deviceId",
83595
+ form: "single",
83596
+ optional: false
83597
+ }],
83598
+ "remote.sendMediaCommand": [{
83599
+ name: "deviceId",
83600
+ form: "single",
83601
+ optional: false
83602
+ }],
83603
+ "remote.setConfig": [{
83604
+ name: "deviceId",
83605
+ form: "single",
83606
+ optional: false
83607
+ }],
83121
83608
  "runningState.getStatus": [{
83122
83609
  name: "deviceId",
83123
83610
  form: "single",
@@ -84926,14 +85413,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
84926
85413
  String.raw`(?<=^|["'(\s>,\[{])`;
84927
85414
  var MB = 1024 * 1024;
84928
85415
  1024 * MB, 3072 * MB;
84929
- discriminatedUnion("kind", [object({
84930
- kind: literal("raw"),
84931
- timings: array(number().int()),
84932
- settings: TransmitSettingsSchema.optional()
84933
- }), object({
84934
- kind: literal("pronto"),
84935
- code: string()
84936
- })]);
84937
85416
  object({
84938
85417
  manufacturer: string().optional(),
84939
85418
  supportedModels: array(string()).optional(),
@@ -1,6 +1,6 @@
1
1
  import { S as e, d as t, u as n, v as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DMBKVIH7.mjs";
2
2
  import { n as i, r as a, t as o } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
- import { _ as s, g as c } from "./responsive-BHzVDMt-.mjs";
3
+ import { _ as s, g as c } from "./responsive-Cw4YAdTr.mjs";
4
4
  var l = s("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",
6
6
  key: "qrunsl"
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CkwPjS5o.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DWDyoPcG.mjs";
2
2
  export { t as get, e as init };
@@ -1,6 +1,6 @@
1
1
  import { S as e, d as t, g as n, i as r, l as i, n as a, r as o, u as s, v as c, y as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DMBKVIH7.mjs";
2
2
  import "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
- import { S as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cxz43vtF.mjs";
3
+ import { S as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-COf25W99.mjs";
4
4
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
5
5
  e();
6
6
  var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), f = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), p = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), m = (e) => {
@@ -1,7 +1,7 @@
1
1
  import { S as e, g as t, l as n, u as r, v as i } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DMBKVIH7.mjs";
2
2
  import "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
3
  import { n as a } from "./ui-text-BqZa5BNK.mjs";
4
- import { _ as o, g as s } from "./responsive-BHzVDMt-.mjs";
4
+ import { _ as o, g as s } from "./responsive-Cw4YAdTr.mjs";
5
5
  var c = o("camera", [["path", {
6
6
  d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",
7
7
  key: "18u6gg"
@@ -1,4 +1,4 @@
1
- import { _ as e } from "./responsive-BHzVDMt-.mjs";
1
+ import { _ as e } from "./responsive-Cw4YAdTr.mjs";
2
2
  var t = e("eye-off", [
3
3
  ["path", {
4
4
  d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",
@@ -1,4 +1,4 @@
1
- import { _ as e } from "./responsive-BHzVDMt-.mjs";
1
+ import { _ as e } from "./responsive-Cw4YAdTr.mjs";
2
2
  var t = e("trash-2", [
3
3
  ["path", {
4
4
  d: "M10 11v6",