@camstack/addon-model-studio 1.1.191 → 1.1.192

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 (18) hide show
  1. package/dist/{MotionZonesSettings-BPTwSN9l.mjs → MotionZonesSettings-BBODQ0dB.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-BUeTedM4.mjs → PrivacyMaskSettings-CqiTF-2X.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-WRXqYE4X.mjs → SceneMonitorEditor-DcYaKpvm.mjs} +3 -3
  4. package/dist/_stub.js +11 -11
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DajnZUDj.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Cc6rCqyx.mjs} +3 -3
  6. package/dist/{_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-VZy4YTrJ.mjs → _virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CGjkGfIU.mjs} +1 -1
  7. package/dist/addon-model-studio.css +1 -1
  8. package/dist/{hostInit-BSJgrQAJ.mjs → hostInit-BQBcsc6U.mjs} +2 -2
  9. package/dist/model-studio.addon.js +57 -23
  10. package/dist/model-studio.addon.mjs +57 -23
  11. package/dist/{player-overlays-BcG6COgL.mjs → player-overlays-EemE9lDR.mjs} +1 -1
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-CYpgwv3g.mjs → responsive-9xEjT9Rn.mjs} +1 -1
  14. package/dist/{scene-monitor-copy-DvrdS2az.mjs → scene-monitor-copy-CQL1Jnuu.mjs} +1 -1
  15. package/dist/{square-BRARfL3C.mjs → square-CkSXetzj.mjs} +1 -1
  16. package/dist/{trash-2-DLomxTVm.mjs → trash-2-D_jyXGlQ.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DFLwncq5.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-Dxbqt7XV.mjs} +1 -1
  18. package/package.json +1 -1
@@ -32023,28 +32023,29 @@ DeviceType.Camera, method(object({
32023
32023
  *
32024
32024
  * This cap owns the other half: a per-(camera, slot) BINDING that says
32025
32025
  * which value feeds the slot, how it is formatted, and under which
32026
- * conditions it is shown at all. One addon renders every binding on every
32027
- * camera, so a new source costs zero driver code.
32028
- *
32029
- * Three deliberate choices, each with a rejected alternative:
32030
- *
32031
- * 1. A source is `(capName, valuePath)` over the kernel's device
32032
- * runtime-state mirror — NOT a closed enum of source kinds. Every
32033
- * cap-keyed slice a device publishes is bindable the day the cap
32034
- * ships. The rejected alternative (one enum member per source, with
32035
- * a resolver branch each) is what makes "add the humidity too" a
32036
- * code change.
32037
- * 2. The display gate reuses `NcConditionsSchema` verbatim — the
32038
- * notification centre's condition vocabulary — rather than a parallel
32039
- * model. An operator who has learned one condition editor has learned
32040
- * both.
32041
- * 3. Because the renderer's facts are device STATE and not a detection
32042
- * record, only a SUBSET of that vocabulary can be answered here.
32043
- * `setSlotBinding` REJECTS the rest at write time (see
32044
- * `getConditionSupport`). It does not accept-then-fail-closed: a
32045
- * condition that can never be true renders a permanently blank
32046
- * overlay, and a blank overlay looks exactly like a broken camera.
32026
+ * conditions it is shown at all. Named TEMPLATES combine many device
32027
+ * fields into one overlay string (Scrypted OSD Manager parity).
32047
32028
  */
32029
+ /** One field reference inside a named multi-device template. */
32030
+ var OsdTemplateFieldSchema = object({
32031
+ deviceId: number().int(),
32032
+ capName: string().min(1).max(64),
32033
+ valuePath: string().min(1).max(64),
32034
+ /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
32035
+ displayUnit: string().max(16).optional(),
32036
+ maxDecimals: number().int().min(0).max(4).default(1)
32037
+ });
32038
+ /**
32039
+ * A named template: several device fields → one parser string with
32040
+ * `{deviceId.capName.valuePath}` tokens (Scrypted `{deviceId.sensorId}`).
32041
+ */
32042
+ var OsdNamedTemplateSchema = object({
32043
+ id: string().min(1).max(64),
32044
+ name: string().min(1).max(64),
32045
+ fields: array(OsdTemplateFieldSchema).max(32).default([]),
32046
+ /** Parser with multi-token placeholders, e.g. `T {12.thermometer.value}°`. */
32047
+ parser: string().max(256).default("")
32048
+ });
32048
32049
  /** Where a slot's value comes from. */
32049
32050
  var OsdSourceSchema = discriminatedUnion("kind", [
32050
32051
  object({
@@ -32063,11 +32064,17 @@ var OsdSourceSchema = discriminatedUnion("kind", [
32063
32064
  deviceId: number().int().optional(),
32064
32065
  capName: string().min(1).max(64),
32065
32066
  /** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
32066
- valuePath: string().min(1).max(64)
32067
+ valuePath: string().min(1).max(64),
32068
+ /** Convert TO this unit at render. Absent = no conversion. */
32069
+ displayUnit: string().max(16).optional()
32067
32070
  }),
32068
32071
  object({
32069
32072
  kind: literal("latest-recognition"),
32070
32073
  recognition: _enum(["person", "plate"])
32074
+ }),
32075
+ object({
32076
+ kind: literal("template"),
32077
+ templateId: string().min(1).max(64)
32071
32078
  })
32072
32079
  ]);
32073
32080
  var OsdSlotBindingSchema = object({
@@ -32083,7 +32090,10 @@ var OsdSlotBindingSchema = object({
32083
32090
  * documented workaround for firmwares that reject `.` in overlay text.
32084
32091
  */
32085
32092
  maxDecimals: number().int().min(0).max(4).default(1),
32086
- /** Appended via `${unit}`. The state mirror does not carry units. */
32093
+ /**
32094
+ * Appended via `${unit}` when no unit conversion produces a label.
32095
+ * Prefer `source.displayUnit` for converted device-state values.
32096
+ */
32087
32097
  unitLabel: string().max(8).optional(),
32088
32098
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
32089
32099
  valueMap: record(string(), string()).optional(),
@@ -32192,6 +32202,12 @@ method(object({ deviceId: number().int() }), object({
32192
32202
  }), method(object({ deviceId: number().int() }), object({ results: array(OsdRenderResultSchema) }), {
32193
32203
  kind: "mutation",
32194
32204
  auth: "admin"
32205
+ }), method(object({}), object({ templates: array(OsdNamedTemplateSchema) }), { auth: "admin" }), method(object({ template: OsdNamedTemplateSchema }), object({ template: OsdNamedTemplateSchema }), {
32206
+ kind: "mutation",
32207
+ auth: "admin"
32208
+ }), method(object({ templateId: string().min(1).max(64) }), object({ success: literal(true) }), {
32209
+ kind: "mutation",
32210
+ auth: "admin"
32195
32211
  });
32196
32212
  /**
32197
32213
  * Feeder connectivity / power status — mirrors the HA petkit device-status
@@ -41424,6 +41440,12 @@ Object.freeze({
41424
41440
  addonId: null,
41425
41441
  access: "create"
41426
41442
  },
41443
+ "osdManager.deleteTemplate": {
41444
+ capName: "osd-manager",
41445
+ capScope: "system",
41446
+ addonId: null,
41447
+ access: "delete"
41448
+ },
41427
41449
  "osdManager.getConditionSupport": {
41428
41450
  capName: "osd-manager",
41429
41451
  capScope: "system",
@@ -41442,6 +41464,12 @@ Object.freeze({
41442
41464
  addonId: null,
41443
41465
  access: "view"
41444
41466
  },
41467
+ "osdManager.listTemplates": {
41468
+ capName: "osd-manager",
41469
+ capScope: "system",
41470
+ addonId: null,
41471
+ access: "view"
41472
+ },
41445
41473
  "osdManager.previewSlot": {
41446
41474
  capName: "osd-manager",
41447
41475
  capScope: "system",
@@ -41460,6 +41488,12 @@ Object.freeze({
41460
41488
  addonId: null,
41461
41489
  access: "create"
41462
41490
  },
41491
+ "osdManager.upsertTemplate": {
41492
+ capName: "osd-manager",
41493
+ capScope: "system",
41494
+ addonId: null,
41495
+ access: "create"
41496
+ },
41463
41497
  "petFeeder.callPet": {
41464
41498
  capName: "pet-feeder",
41465
41499
  capScope: "device",
@@ -32002,28 +32002,29 @@ DeviceType.Camera, method(object({
32002
32002
  *
32003
32003
  * This cap owns the other half: a per-(camera, slot) BINDING that says
32004
32004
  * which value feeds the slot, how it is formatted, and under which
32005
- * conditions it is shown at all. One addon renders every binding on every
32006
- * camera, so a new source costs zero driver code.
32007
- *
32008
- * Three deliberate choices, each with a rejected alternative:
32009
- *
32010
- * 1. A source is `(capName, valuePath)` over the kernel's device
32011
- * runtime-state mirror — NOT a closed enum of source kinds. Every
32012
- * cap-keyed slice a device publishes is bindable the day the cap
32013
- * ships. The rejected alternative (one enum member per source, with
32014
- * a resolver branch each) is what makes "add the humidity too" a
32015
- * code change.
32016
- * 2. The display gate reuses `NcConditionsSchema` verbatim — the
32017
- * notification centre's condition vocabulary — rather than a parallel
32018
- * model. An operator who has learned one condition editor has learned
32019
- * both.
32020
- * 3. Because the renderer's facts are device STATE and not a detection
32021
- * record, only a SUBSET of that vocabulary can be answered here.
32022
- * `setSlotBinding` REJECTS the rest at write time (see
32023
- * `getConditionSupport`). It does not accept-then-fail-closed: a
32024
- * condition that can never be true renders a permanently blank
32025
- * overlay, and a blank overlay looks exactly like a broken camera.
32005
+ * conditions it is shown at all. Named TEMPLATES combine many device
32006
+ * fields into one overlay string (Scrypted OSD Manager parity).
32026
32007
  */
32008
+ /** One field reference inside a named multi-device template. */
32009
+ var OsdTemplateFieldSchema = object({
32010
+ deviceId: number().int(),
32011
+ capName: string().min(1).max(64),
32012
+ valuePath: string().min(1).max(64),
32013
+ /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
32014
+ displayUnit: string().max(16).optional(),
32015
+ maxDecimals: number().int().min(0).max(4).default(1)
32016
+ });
32017
+ /**
32018
+ * A named template: several device fields → one parser string with
32019
+ * `{deviceId.capName.valuePath}` tokens (Scrypted `{deviceId.sensorId}`).
32020
+ */
32021
+ var OsdNamedTemplateSchema = object({
32022
+ id: string().min(1).max(64),
32023
+ name: string().min(1).max(64),
32024
+ fields: array(OsdTemplateFieldSchema).max(32).default([]),
32025
+ /** Parser with multi-token placeholders, e.g. `T {12.thermometer.value}°`. */
32026
+ parser: string().max(256).default("")
32027
+ });
32027
32028
  /** Where a slot's value comes from. */
32028
32029
  var OsdSourceSchema = discriminatedUnion("kind", [
32029
32030
  object({
@@ -32042,11 +32043,17 @@ var OsdSourceSchema = discriminatedUnion("kind", [
32042
32043
  deviceId: number().int().optional(),
32043
32044
  capName: string().min(1).max(64),
32044
32045
  /** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
32045
- valuePath: string().min(1).max(64)
32046
+ valuePath: string().min(1).max(64),
32047
+ /** Convert TO this unit at render. Absent = no conversion. */
32048
+ displayUnit: string().max(16).optional()
32046
32049
  }),
32047
32050
  object({
32048
32051
  kind: literal("latest-recognition"),
32049
32052
  recognition: _enum(["person", "plate"])
32053
+ }),
32054
+ object({
32055
+ kind: literal("template"),
32056
+ templateId: string().min(1).max(64)
32050
32057
  })
32051
32058
  ]);
32052
32059
  var OsdSlotBindingSchema = object({
@@ -32062,7 +32069,10 @@ var OsdSlotBindingSchema = object({
32062
32069
  * documented workaround for firmwares that reject `.` in overlay text.
32063
32070
  */
32064
32071
  maxDecimals: number().int().min(0).max(4).default(1),
32065
- /** Appended via `${unit}`. The state mirror does not carry units. */
32072
+ /**
32073
+ * Appended via `${unit}` when no unit conversion produces a label.
32074
+ * Prefer `source.displayUnit` for converted device-state values.
32075
+ */
32066
32076
  unitLabel: string().max(8).optional(),
32067
32077
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
32068
32078
  valueMap: record(string(), string()).optional(),
@@ -32171,6 +32181,12 @@ method(object({ deviceId: number().int() }), object({
32171
32181
  }), method(object({ deviceId: number().int() }), object({ results: array(OsdRenderResultSchema) }), {
32172
32182
  kind: "mutation",
32173
32183
  auth: "admin"
32184
+ }), method(object({}), object({ templates: array(OsdNamedTemplateSchema) }), { auth: "admin" }), method(object({ template: OsdNamedTemplateSchema }), object({ template: OsdNamedTemplateSchema }), {
32185
+ kind: "mutation",
32186
+ auth: "admin"
32187
+ }), method(object({ templateId: string().min(1).max(64) }), object({ success: literal(true) }), {
32188
+ kind: "mutation",
32189
+ auth: "admin"
32174
32190
  });
32175
32191
  /**
32176
32192
  * Feeder connectivity / power status — mirrors the HA petkit device-status
@@ -41403,6 +41419,12 @@ Object.freeze({
41403
41419
  addonId: null,
41404
41420
  access: "create"
41405
41421
  },
41422
+ "osdManager.deleteTemplate": {
41423
+ capName: "osd-manager",
41424
+ capScope: "system",
41425
+ addonId: null,
41426
+ access: "delete"
41427
+ },
41406
41428
  "osdManager.getConditionSupport": {
41407
41429
  capName: "osd-manager",
41408
41430
  capScope: "system",
@@ -41421,6 +41443,12 @@ Object.freeze({
41421
41443
  addonId: null,
41422
41444
  access: "view"
41423
41445
  },
41446
+ "osdManager.listTemplates": {
41447
+ capName: "osd-manager",
41448
+ capScope: "system",
41449
+ addonId: null,
41450
+ access: "view"
41451
+ },
41424
41452
  "osdManager.previewSlot": {
41425
41453
  capName: "osd-manager",
41426
41454
  capScope: "system",
@@ -41439,6 +41467,12 @@ Object.freeze({
41439
41467
  addonId: null,
41440
41468
  access: "create"
41441
41469
  },
41470
+ "osdManager.upsertTemplate": {
41471
+ capName: "osd-manager",
41472
+ capScope: "system",
41473
+ addonId: null,
41474
+ access: "create"
41475
+ },
41442
41476
  "petFeeder.callPet": {
41443
41477
  capName: "pet-feeder",
41444
41478
  capScope: "device",
@@ -1,5 +1,5 @@
1
1
  import { h as e, l as t, u as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { o as i, s as a } from "./responsive-CYpgwv3g.mjs";
2
+ import { o as i, s as a } from "./responsive-9xEjT9Rn.mjs";
3
3
  import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
4
4
  var l = a("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DFLwncq5.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-Dxbqt7XV.mjs";
2
2
  export { t as get, e as init };
@@ -1,6 +1,6 @@
1
1
  import { c as e, g as t, h as n, l as r, n as i, p as a, r as o, t as s, u as c, y as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.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 { i as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-VZy4YTrJ.mjs";
3
+ import { i as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CGjkGfIU.mjs";
4
4
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
5
5
  l();
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,5 +1,5 @@
1
1
  import { c as e, h as t, p as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { s as i } from "./responsive-CYpgwv3g.mjs";
2
+ import { s as i } from "./responsive-9xEjT9Rn.mjs";
3
3
  var a = i("camera", [["path", {
4
4
  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",
5
5
  key: "18u6gg"
@@ -1,4 +1,4 @@
1
- import { s as e } from "./responsive-CYpgwv3g.mjs";
1
+ import { s as e } from "./responsive-9xEjT9Rn.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 { s as e } from "./responsive-CYpgwv3g.mjs";
1
+ import { s as e } from "./responsive-9xEjT9Rn.mjs";
2
2
  var t = e("trash-2", [
3
3
  ["path", {
4
4
  d: "M10 11v6",
@@ -2753,7 +2753,7 @@ async function rr(e) {
2753
2753
  }
2754
2754
  }
2755
2755
  async function ir() {
2756
- return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DajnZUDj.mjs")).catch((e) => {
2756
+ return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Cc6rCqyx.mjs")).catch((e) => {
2757
2757
  throw tr = void 0, e;
2758
2758
  }), tr;
2759
2759
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-model-studio",
3
- "version": "1.1.191",
3
+ "version": "1.1.192",
4
4
  "description": "Custom detection model registry, conversion & distribution for CamStack",
5
5
  "keywords": [
6
6
  "camstack",