@camstack/addon-model-studio 1.1.323 → 1.1.324
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.
- package/CHANGELOG.md +6 -0
- package/dist/{MotionZonesSettings-CBVJdmZ_.mjs → MotionZonesSettings-BFSzpDlc.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-CFuZa1xW.mjs → PrivacyMaskSettings-bzbS1q77.mjs} +4 -4
- package/dist/{SceneMonitorEditor-DHYl0WUF.mjs → SceneMonitorEditor-5jtlWR_n.mjs} +3 -3
- package/dist/_stub.js +10 -10
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DiTB72W6.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DMLYtwXQ.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D8h8qfbd.mjs +26 -0
- package/dist/{hostInit-BL6ZxXXr.mjs → hostInit-BQhIepOe.mjs} +2 -2
- package/dist/model-studio.addon.js +285 -3
- package/dist/model-studio.addon.mjs +285 -3
- package/dist/{player-overlays-CDEmtjZg.mjs → player-overlays-DwnklNvS.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-B_pKmFhb.mjs → responsive-DFhiWOST.mjs} +1 -1
- package/dist/{scene-monitor-copy-KV9Ti6_0.mjs → scene-monitor-copy-DVaiZyk_.mjs} +1 -1
- package/dist/{square-ByW1TPIi.mjs → square-CL1GZCDy.mjs} +1 -1
- package/dist/{trash-2-9gFkA-Zu.mjs → trash-2-Bs4Zqar1.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-B880BvK0.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-B3z4_zyV.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B3TmOWWR.mjs +0 -26
|
@@ -5850,7 +5850,7 @@ var ZodIssueCode = {
|
|
|
5850
5850
|
var ZodFirstPartyTypeKind;
|
|
5851
5851
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5852
5852
|
//#endregion
|
|
5853
|
-
//#region ../types/dist/sleep-
|
|
5853
|
+
//#region ../types/dist/sleep-63gM_1JR.mjs
|
|
5854
5854
|
/**
|
|
5855
5855
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5856
5856
|
* window to float samples (D455).
|
|
@@ -9211,6 +9211,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9211
9211
|
"recording-signal",
|
|
9212
9212
|
"records",
|
|
9213
9213
|
"remote",
|
|
9214
|
+
"remote-layout-components",
|
|
9214
9215
|
"running-state",
|
|
9215
9216
|
"scene-monitor",
|
|
9216
9217
|
"script-runner",
|
|
@@ -58816,6 +58817,30 @@ object({
|
|
|
58816
58817
|
at: number()
|
|
58817
58818
|
}).nullable()
|
|
58818
58819
|
});
|
|
58820
|
+
var RemoteButtonShapeSchema = _enum([
|
|
58821
|
+
"rect",
|
|
58822
|
+
"rounded",
|
|
58823
|
+
"round",
|
|
58824
|
+
"pill"
|
|
58825
|
+
]);
|
|
58826
|
+
var RemoteButtonToneSchema = _enum([
|
|
58827
|
+
"neutral",
|
|
58828
|
+
"accent",
|
|
58829
|
+
"danger",
|
|
58830
|
+
"red",
|
|
58831
|
+
"green",
|
|
58832
|
+
"yellow",
|
|
58833
|
+
"blue"
|
|
58834
|
+
]);
|
|
58835
|
+
var RemoteGroupFrameSchema = _enum([
|
|
58836
|
+
"none",
|
|
58837
|
+
"panel",
|
|
58838
|
+
"divider",
|
|
58839
|
+
"dpad",
|
|
58840
|
+
"rocker-v",
|
|
58841
|
+
"rocker-h",
|
|
58842
|
+
"keypad"
|
|
58843
|
+
]);
|
|
58819
58844
|
var RemoteLayoutButtonSchema = object({
|
|
58820
58845
|
id: string().min(1).max(40),
|
|
58821
58846
|
/** 0-based grid position. */
|
|
@@ -58825,12 +58850,94 @@ var RemoteLayoutButtonSchema = object({
|
|
|
58825
58850
|
colSpan: number().int().min(1).max(24),
|
|
58826
58851
|
icon: string().min(1).max(60).optional(),
|
|
58827
58852
|
label: string().min(1).max(40).optional(),
|
|
58828
|
-
role: RemoteRoleSchema
|
|
58853
|
+
role: RemoteRoleSchema,
|
|
58854
|
+
/** Absent = the plain rendering every layout had before shapes existed. */
|
|
58855
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
58856
|
+
tone: RemoteButtonToneSchema.optional(),
|
|
58857
|
+
/** The group this button belongs to; it must lie inside that group's rectangle. */
|
|
58858
|
+
groupId: string().min(1).max(40).optional()
|
|
58859
|
+
});
|
|
58860
|
+
/**
|
|
58861
|
+
* A rectangle of the grid that moves as ONE thing and is drawn with a frame: a
|
|
58862
|
+
* titled panel, a section divider, a D-pad ring. `componentId` names the palette
|
|
58863
|
+
* entry it came from (informational: the layout is self-contained).
|
|
58864
|
+
*/
|
|
58865
|
+
var RemoteLayoutGroupSchema = object({
|
|
58866
|
+
id: string().min(1).max(40),
|
|
58867
|
+
componentId: string().min(1).max(80),
|
|
58868
|
+
frame: RemoteGroupFrameSchema,
|
|
58869
|
+
row: number().int().min(0).max(24),
|
|
58870
|
+
col: number().int().min(0).max(24),
|
|
58871
|
+
rowSpan: number().int().min(1).max(24),
|
|
58872
|
+
colSpan: number().int().min(1).max(24),
|
|
58873
|
+
title: string().min(1).max(40).optional()
|
|
58829
58874
|
});
|
|
58875
|
+
function rectsOverlap(a, b) {
|
|
58876
|
+
return a.row < b.row + b.rowSpan && b.row < a.row + a.rowSpan && a.col < b.col + b.colSpan && b.col < a.col + a.colSpan;
|
|
58877
|
+
}
|
|
58878
|
+
function rectContains(outer, inner) {
|
|
58879
|
+
return inner.row >= outer.row && inner.col >= outer.col && inner.row + inner.rowSpan <= outer.row + outer.rowSpan && inner.col + inner.colSpan <= outer.col + outer.colSpan;
|
|
58880
|
+
}
|
|
58881
|
+
/**
|
|
58882
|
+
* The group rules of a layout: inside the grid, no two groups overlap, a
|
|
58883
|
+
* member lies inside its group, a divider holds nothing, and a button that is
|
|
58884
|
+
* not a member never sits inside someone else's rectangle (a group moves as
|
|
58885
|
+
* one thing, so a stray key under it would be left behind).
|
|
58886
|
+
*/
|
|
58887
|
+
function refineGroups(grid, ctx) {
|
|
58888
|
+
const groups = grid.groups ?? [];
|
|
58889
|
+
const byId = /* @__PURE__ */ new Map();
|
|
58890
|
+
const fail = (message, path) => {
|
|
58891
|
+
ctx.addIssue({
|
|
58892
|
+
code: "custom",
|
|
58893
|
+
message,
|
|
58894
|
+
path
|
|
58895
|
+
});
|
|
58896
|
+
};
|
|
58897
|
+
groups.forEach((group, index) => {
|
|
58898
|
+
if (byId.has(group.id)) fail(`group id "${group.id}" is used twice`, [
|
|
58899
|
+
"groups",
|
|
58900
|
+
index,
|
|
58901
|
+
"id"
|
|
58902
|
+
]);
|
|
58903
|
+
byId.set(group.id, group);
|
|
58904
|
+
if (group.row + group.rowSpan > grid.rows || group.col + group.colSpan > grid.columns) fail(`group "${group.id}" leaves the grid`, ["groups", index]);
|
|
58905
|
+
for (let other = 0; other < index; other += 1) {
|
|
58906
|
+
const earlier = groups[other];
|
|
58907
|
+
if (earlier !== void 0 && rectsOverlap(earlier, group)) {
|
|
58908
|
+
fail(`groups "${earlier.id}" and "${group.id}" overlap`, ["groups", index]);
|
|
58909
|
+
return;
|
|
58910
|
+
}
|
|
58911
|
+
}
|
|
58912
|
+
});
|
|
58913
|
+
grid.buttons.forEach((button, index) => {
|
|
58914
|
+
if (button.groupId !== void 0) {
|
|
58915
|
+
const group = byId.get(button.groupId);
|
|
58916
|
+
if (group === void 0) {
|
|
58917
|
+
fail(`button "${button.id}" names the unknown group "${button.groupId}"`, [
|
|
58918
|
+
"buttons",
|
|
58919
|
+
index,
|
|
58920
|
+
"groupId"
|
|
58921
|
+
]);
|
|
58922
|
+
return;
|
|
58923
|
+
}
|
|
58924
|
+
if (group.frame === "divider") fail(`a divider group ("${group.id}") holds no buttons`, [
|
|
58925
|
+
"buttons",
|
|
58926
|
+
index,
|
|
58927
|
+
"groupId"
|
|
58928
|
+
]);
|
|
58929
|
+
if (!rectContains(group, button)) fail(`button "${button.id}" lies outside its group "${group.id}"`, ["buttons", index]);
|
|
58930
|
+
return;
|
|
58931
|
+
}
|
|
58932
|
+
const foreign = groups.find((group) => rectsOverlap(group, button));
|
|
58933
|
+
if (foreign !== void 0) fail(`button "${button.id}" lies inside group "${foreign.id}" but is not a member`, ["buttons", index]);
|
|
58934
|
+
});
|
|
58935
|
+
}
|
|
58830
58936
|
object({
|
|
58831
58937
|
columns: number().int().min(1).max(24),
|
|
58832
58938
|
rows: number().int().min(1).max(24),
|
|
58833
|
-
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
58939
|
+
buttons: array(RemoteLayoutButtonSchema).max(200),
|
|
58940
|
+
groups: array(RemoteLayoutGroupSchema).max(50).optional()
|
|
58834
58941
|
}).superRefine((grid, ctx) => {
|
|
58835
58942
|
const ids = /* @__PURE__ */ new Set();
|
|
58836
58943
|
const taken = /* @__PURE__ */ new Map();
|
|
@@ -58867,6 +58974,7 @@ object({
|
|
|
58867
58974
|
taken.set(cell, button.id);
|
|
58868
58975
|
}
|
|
58869
58976
|
});
|
|
58977
|
+
refineGroups(grid, ctx);
|
|
58870
58978
|
});
|
|
58871
58979
|
var RemoteBoundCommandSchema = object({
|
|
58872
58980
|
role: RemoteRoleSchema,
|
|
@@ -58998,6 +59106,91 @@ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSche
|
|
|
58998
59106
|
kind: "mutation",
|
|
58999
59107
|
auth: "admin"
|
|
59000
59108
|
});
|
|
59109
|
+
var RemoteComponentCategorySchema = _enum([
|
|
59110
|
+
"power",
|
|
59111
|
+
"navigation",
|
|
59112
|
+
"volume",
|
|
59113
|
+
"numbers",
|
|
59114
|
+
"media",
|
|
59115
|
+
"colour",
|
|
59116
|
+
"apps",
|
|
59117
|
+
"layout"
|
|
59118
|
+
]);
|
|
59119
|
+
/** `<namespace>:<name>`, both lowercase slugs — `core:dpad`, `<addonId>:<name>`. */
|
|
59120
|
+
var COMPONENT_ID_RE = /^[a-z0-9][a-z0-9_.-]*:[a-z0-9][a-z0-9_-]*$/;
|
|
59121
|
+
var RemoteComponentButtonSchema = object({
|
|
59122
|
+
/** Joined to the instance id when the component is inserted. */
|
|
59123
|
+
idSuffix: string().regex(/^[a-z0-9][a-z0-9_-]{0,19}$/, { message: "a short lowercase slug" }),
|
|
59124
|
+
row: number().int().min(0).max(24),
|
|
59125
|
+
col: number().int().min(0).max(24),
|
|
59126
|
+
rowSpan: number().int().min(1).max(24),
|
|
59127
|
+
colSpan: number().int().min(1).max(24),
|
|
59128
|
+
role: RemoteRoleSchema,
|
|
59129
|
+
icon: string().min(1).max(60).optional(),
|
|
59130
|
+
label: string().min(1).max(40).optional(),
|
|
59131
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
59132
|
+
tone: RemoteButtonToneSchema.optional()
|
|
59133
|
+
});
|
|
59134
|
+
var RemoteLayoutComponentSchema = object({
|
|
59135
|
+
id: string().max(80).regex(COMPONENT_ID_RE, { message: "<namespace>:<name>, lowercase" }),
|
|
59136
|
+
name: string().min(1).max(60),
|
|
59137
|
+
nameI18n: object({
|
|
59138
|
+
en: string().min(1).max(60),
|
|
59139
|
+
it: string().min(1).max(60)
|
|
59140
|
+
}).optional(),
|
|
59141
|
+
/** A display icon key, resolved by the UI like a button icon. */
|
|
59142
|
+
icon: string().min(1).max(60),
|
|
59143
|
+
category: RemoteComponentCategorySchema,
|
|
59144
|
+
size: object({
|
|
59145
|
+
rows: number().int().min(1).max(24),
|
|
59146
|
+
cols: number().int().min(1).max(24)
|
|
59147
|
+
}),
|
|
59148
|
+
/** The frame drawn around the whole component, or null for loose buttons. */
|
|
59149
|
+
group: object({
|
|
59150
|
+
frame: RemoteGroupFrameSchema,
|
|
59151
|
+
title: string().min(1).max(40).optional()
|
|
59152
|
+
}).nullable(),
|
|
59153
|
+
buttons: array(RemoteComponentButtonSchema).max(40)
|
|
59154
|
+
}).superRefine((component, ctx) => {
|
|
59155
|
+
const suffixes = /* @__PURE__ */ new Set();
|
|
59156
|
+
component.buttons.forEach((button, index) => {
|
|
59157
|
+
if (suffixes.has(button.idSuffix)) ctx.addIssue({
|
|
59158
|
+
code: "custom",
|
|
59159
|
+
message: `button "${button.idSuffix}" is listed twice`,
|
|
59160
|
+
path: [
|
|
59161
|
+
"buttons",
|
|
59162
|
+
index,
|
|
59163
|
+
"idSuffix"
|
|
59164
|
+
]
|
|
59165
|
+
});
|
|
59166
|
+
suffixes.add(button.idSuffix);
|
|
59167
|
+
if (button.row + button.rowSpan > component.size.rows || button.col + button.colSpan > component.size.cols) {
|
|
59168
|
+
ctx.addIssue({
|
|
59169
|
+
code: "custom",
|
|
59170
|
+
message: `button "${button.idSuffix}" leaves the component`,
|
|
59171
|
+
path: ["buttons", index]
|
|
59172
|
+
});
|
|
59173
|
+
return;
|
|
59174
|
+
}
|
|
59175
|
+
for (let other = 0; other < index; other += 1) {
|
|
59176
|
+
const earlier = component.buttons[other];
|
|
59177
|
+
if (earlier !== void 0 && rectsOverlap(earlier, button)) {
|
|
59178
|
+
ctx.addIssue({
|
|
59179
|
+
code: "custom",
|
|
59180
|
+
message: `buttons "${earlier.idSuffix}" and "${button.idSuffix}" overlap`,
|
|
59181
|
+
path: ["buttons", index]
|
|
59182
|
+
});
|
|
59183
|
+
return;
|
|
59184
|
+
}
|
|
59185
|
+
}
|
|
59186
|
+
});
|
|
59187
|
+
if (component.group?.frame === "divider" && component.buttons.length > 0) ctx.addIssue({
|
|
59188
|
+
code: "custom",
|
|
59189
|
+
message: "a divider component holds no buttons",
|
|
59190
|
+
path: ["buttons"]
|
|
59191
|
+
});
|
|
59192
|
+
});
|
|
59193
|
+
method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
|
|
59001
59194
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
59002
59195
|
kind: "mutation",
|
|
59003
59196
|
auth: "protected"
|
|
@@ -67933,6 +68126,87 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
67933
68126
|
kind: "mutation",
|
|
67934
68127
|
auth: "admin"
|
|
67935
68128
|
});
|
|
68129
|
+
var btn = (idSuffix, row, col, init) => ({
|
|
68130
|
+
idSuffix,
|
|
68131
|
+
row,
|
|
68132
|
+
col,
|
|
68133
|
+
rowSpan: 1,
|
|
68134
|
+
colSpan: 1,
|
|
68135
|
+
...init
|
|
68136
|
+
});
|
|
68137
|
+
function rocker(id, name, it, frame, title, buttons, size) {
|
|
68138
|
+
return {
|
|
68139
|
+
id,
|
|
68140
|
+
name,
|
|
68141
|
+
nameI18n: {
|
|
68142
|
+
en: name,
|
|
68143
|
+
it
|
|
68144
|
+
},
|
|
68145
|
+
icon: frame === "rocker-v" ? "chevrons-up-down" : "chevrons-left-right",
|
|
68146
|
+
category: id.includes("channel") || id.includes("volume") ? "volume" : "navigation",
|
|
68147
|
+
size,
|
|
68148
|
+
group: title === null ? { frame } : {
|
|
68149
|
+
frame,
|
|
68150
|
+
title
|
|
68151
|
+
},
|
|
68152
|
+
buttons
|
|
68153
|
+
};
|
|
68154
|
+
}
|
|
68155
|
+
btn("power", 0, 0, {
|
|
68156
|
+
role: "power",
|
|
68157
|
+
shape: "round",
|
|
68158
|
+
tone: "danger"
|
|
68159
|
+
}), btn("up", 0, 1, { role: "up" }), btn("left", 1, 0, { role: "left" }), btn("ok", 1, 1, {
|
|
68160
|
+
role: "ok",
|
|
68161
|
+
shape: "round",
|
|
68162
|
+
tone: "accent"
|
|
68163
|
+
}), btn("right", 1, 2, { role: "right" }), btn("down", 2, 1, { role: "down" }), rocker("core:rocker-volume-v", "Volume rocker", "Bilanciere volume", "rocker-v", "VOL", [btn("up", 0, 0, {
|
|
68164
|
+
role: "volume_up",
|
|
68165
|
+
shape: "pill"
|
|
68166
|
+
}), btn("down", 1, 0, {
|
|
68167
|
+
role: "volume_down",
|
|
68168
|
+
shape: "pill"
|
|
68169
|
+
})], {
|
|
68170
|
+
rows: 2,
|
|
68171
|
+
cols: 1
|
|
68172
|
+
}), rocker("core:rocker-channel-v", "Channel rocker", "Bilanciere canali", "rocker-v", "CH", [btn("up", 0, 0, {
|
|
68173
|
+
role: "channel_up",
|
|
68174
|
+
shape: "pill"
|
|
68175
|
+
}), btn("down", 1, 0, {
|
|
68176
|
+
role: "channel_down",
|
|
68177
|
+
shape: "pill"
|
|
68178
|
+
})], {
|
|
68179
|
+
rows: 2,
|
|
68180
|
+
cols: 1
|
|
68181
|
+
}), rocker("core:rocker-h", "Minus / plus rocker", "Bilanciere meno / più", "rocker-h", null, [btn("minus", 0, 0, {
|
|
68182
|
+
role: "custom:minus",
|
|
68183
|
+
label: "−",
|
|
68184
|
+
shape: "pill"
|
|
68185
|
+
}), btn("plus", 0, 1, {
|
|
68186
|
+
role: "custom:plus",
|
|
68187
|
+
label: "+",
|
|
68188
|
+
shape: "pill"
|
|
68189
|
+
})], {
|
|
68190
|
+
rows: 1,
|
|
68191
|
+
cols: 2
|
|
68192
|
+
}), [...Array.from({ length: 9 }, (_, i) => btn(`d${i + 1}`, Math.floor(i / 3), i % 3, { role: `digit_${i + 1}` })), btn("d0", 3, 1, { role: "digit_0" })], btn("red", 0, 0, {
|
|
68193
|
+
role: "custom:color_red",
|
|
68194
|
+
tone: "red"
|
|
68195
|
+
}), btn("green", 0, 1, {
|
|
68196
|
+
role: "custom:color_green",
|
|
68197
|
+
tone: "green"
|
|
68198
|
+
}), btn("yellow", 0, 2, {
|
|
68199
|
+
role: "custom:color_yellow",
|
|
68200
|
+
tone: "yellow"
|
|
68201
|
+
}), btn("blue", 0, 3, {
|
|
68202
|
+
role: "custom:color_blue",
|
|
68203
|
+
tone: "blue"
|
|
68204
|
+
}), btn("rewind", 0, 0, { role: "rewind" }), btn("play", 0, 1, { role: "play" }), btn("pause", 0, 2, { role: "pause" }), btn("forward", 0, 3, { role: "fast_forward" }), btn("stop", 0, 4, { role: "stop" }), [
|
|
68205
|
+
1,
|
|
68206
|
+
2,
|
|
68207
|
+
3,
|
|
68208
|
+
4
|
|
68209
|
+
].map((n) => btn(`app${n}`, 0, n - 1, { role: `custom:app_slot_${n}` })), btn("back", 0, 0, { role: "back" }), btn("home", 0, 1, { role: "home" }), btn("menu", 0, 2, { role: "menu" });
|
|
67936
68210
|
discriminatedUnion("kind", [object({
|
|
67937
68211
|
kind: literal("raw"),
|
|
67938
68212
|
timings: array(number().int()),
|
|
@@ -75895,6 +76169,13 @@ Object.freeze({
|
|
|
75895
76169
|
access: "create",
|
|
75896
76170
|
role: "admin"
|
|
75897
76171
|
},
|
|
76172
|
+
"remoteLayoutComponents.listComponents": {
|
|
76173
|
+
capName: "remote-layout-components",
|
|
76174
|
+
capScope: "system",
|
|
76175
|
+
addonId: null,
|
|
76176
|
+
access: "view",
|
|
76177
|
+
role: "admin"
|
|
76178
|
+
},
|
|
75898
76179
|
"runningState.getStatus": {
|
|
75899
76180
|
capName: "running-state",
|
|
75900
76181
|
capScope: "device",
|
|
@@ -82071,6 +82352,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
82071
82352
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
82072
82353
|
records: system(INTERNAL),
|
|
82073
82354
|
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
82355
|
+
"remote-layout-components": system("the palette of the remote template editor — read-only data, never actuated"),
|
|
82074
82356
|
"server-management": system(CLUSTER),
|
|
82075
82357
|
"settings-store": system(INTERNAL),
|
|
82076
82358
|
"smtp-provider": system(INTERNAL),
|
|
@@ -5824,7 +5824,7 @@ var ZodIssueCode = {
|
|
|
5824
5824
|
var ZodFirstPartyTypeKind;
|
|
5825
5825
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5826
5826
|
//#endregion
|
|
5827
|
-
//#region ../types/dist/sleep-
|
|
5827
|
+
//#region ../types/dist/sleep-63gM_1JR.mjs
|
|
5828
5828
|
/**
|
|
5829
5829
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5830
5830
|
* window to float samples (D455).
|
|
@@ -9185,6 +9185,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9185
9185
|
"recording-signal",
|
|
9186
9186
|
"records",
|
|
9187
9187
|
"remote",
|
|
9188
|
+
"remote-layout-components",
|
|
9188
9189
|
"running-state",
|
|
9189
9190
|
"scene-monitor",
|
|
9190
9191
|
"script-runner",
|
|
@@ -58790,6 +58791,30 @@ object({
|
|
|
58790
58791
|
at: number()
|
|
58791
58792
|
}).nullable()
|
|
58792
58793
|
});
|
|
58794
|
+
var RemoteButtonShapeSchema = _enum([
|
|
58795
|
+
"rect",
|
|
58796
|
+
"rounded",
|
|
58797
|
+
"round",
|
|
58798
|
+
"pill"
|
|
58799
|
+
]);
|
|
58800
|
+
var RemoteButtonToneSchema = _enum([
|
|
58801
|
+
"neutral",
|
|
58802
|
+
"accent",
|
|
58803
|
+
"danger",
|
|
58804
|
+
"red",
|
|
58805
|
+
"green",
|
|
58806
|
+
"yellow",
|
|
58807
|
+
"blue"
|
|
58808
|
+
]);
|
|
58809
|
+
var RemoteGroupFrameSchema = _enum([
|
|
58810
|
+
"none",
|
|
58811
|
+
"panel",
|
|
58812
|
+
"divider",
|
|
58813
|
+
"dpad",
|
|
58814
|
+
"rocker-v",
|
|
58815
|
+
"rocker-h",
|
|
58816
|
+
"keypad"
|
|
58817
|
+
]);
|
|
58793
58818
|
var RemoteLayoutButtonSchema = object({
|
|
58794
58819
|
id: string().min(1).max(40),
|
|
58795
58820
|
/** 0-based grid position. */
|
|
@@ -58799,12 +58824,94 @@ var RemoteLayoutButtonSchema = object({
|
|
|
58799
58824
|
colSpan: number().int().min(1).max(24),
|
|
58800
58825
|
icon: string().min(1).max(60).optional(),
|
|
58801
58826
|
label: string().min(1).max(40).optional(),
|
|
58802
|
-
role: RemoteRoleSchema
|
|
58827
|
+
role: RemoteRoleSchema,
|
|
58828
|
+
/** Absent = the plain rendering every layout had before shapes existed. */
|
|
58829
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
58830
|
+
tone: RemoteButtonToneSchema.optional(),
|
|
58831
|
+
/** The group this button belongs to; it must lie inside that group's rectangle. */
|
|
58832
|
+
groupId: string().min(1).max(40).optional()
|
|
58833
|
+
});
|
|
58834
|
+
/**
|
|
58835
|
+
* A rectangle of the grid that moves as ONE thing and is drawn with a frame: a
|
|
58836
|
+
* titled panel, a section divider, a D-pad ring. `componentId` names the palette
|
|
58837
|
+
* entry it came from (informational: the layout is self-contained).
|
|
58838
|
+
*/
|
|
58839
|
+
var RemoteLayoutGroupSchema = object({
|
|
58840
|
+
id: string().min(1).max(40),
|
|
58841
|
+
componentId: string().min(1).max(80),
|
|
58842
|
+
frame: RemoteGroupFrameSchema,
|
|
58843
|
+
row: number().int().min(0).max(24),
|
|
58844
|
+
col: number().int().min(0).max(24),
|
|
58845
|
+
rowSpan: number().int().min(1).max(24),
|
|
58846
|
+
colSpan: number().int().min(1).max(24),
|
|
58847
|
+
title: string().min(1).max(40).optional()
|
|
58803
58848
|
});
|
|
58849
|
+
function rectsOverlap(a, b) {
|
|
58850
|
+
return a.row < b.row + b.rowSpan && b.row < a.row + a.rowSpan && a.col < b.col + b.colSpan && b.col < a.col + a.colSpan;
|
|
58851
|
+
}
|
|
58852
|
+
function rectContains(outer, inner) {
|
|
58853
|
+
return inner.row >= outer.row && inner.col >= outer.col && inner.row + inner.rowSpan <= outer.row + outer.rowSpan && inner.col + inner.colSpan <= outer.col + outer.colSpan;
|
|
58854
|
+
}
|
|
58855
|
+
/**
|
|
58856
|
+
* The group rules of a layout: inside the grid, no two groups overlap, a
|
|
58857
|
+
* member lies inside its group, a divider holds nothing, and a button that is
|
|
58858
|
+
* not a member never sits inside someone else's rectangle (a group moves as
|
|
58859
|
+
* one thing, so a stray key under it would be left behind).
|
|
58860
|
+
*/
|
|
58861
|
+
function refineGroups(grid, ctx) {
|
|
58862
|
+
const groups = grid.groups ?? [];
|
|
58863
|
+
const byId = /* @__PURE__ */ new Map();
|
|
58864
|
+
const fail = (message, path) => {
|
|
58865
|
+
ctx.addIssue({
|
|
58866
|
+
code: "custom",
|
|
58867
|
+
message,
|
|
58868
|
+
path
|
|
58869
|
+
});
|
|
58870
|
+
};
|
|
58871
|
+
groups.forEach((group, index) => {
|
|
58872
|
+
if (byId.has(group.id)) fail(`group id "${group.id}" is used twice`, [
|
|
58873
|
+
"groups",
|
|
58874
|
+
index,
|
|
58875
|
+
"id"
|
|
58876
|
+
]);
|
|
58877
|
+
byId.set(group.id, group);
|
|
58878
|
+
if (group.row + group.rowSpan > grid.rows || group.col + group.colSpan > grid.columns) fail(`group "${group.id}" leaves the grid`, ["groups", index]);
|
|
58879
|
+
for (let other = 0; other < index; other += 1) {
|
|
58880
|
+
const earlier = groups[other];
|
|
58881
|
+
if (earlier !== void 0 && rectsOverlap(earlier, group)) {
|
|
58882
|
+
fail(`groups "${earlier.id}" and "${group.id}" overlap`, ["groups", index]);
|
|
58883
|
+
return;
|
|
58884
|
+
}
|
|
58885
|
+
}
|
|
58886
|
+
});
|
|
58887
|
+
grid.buttons.forEach((button, index) => {
|
|
58888
|
+
if (button.groupId !== void 0) {
|
|
58889
|
+
const group = byId.get(button.groupId);
|
|
58890
|
+
if (group === void 0) {
|
|
58891
|
+
fail(`button "${button.id}" names the unknown group "${button.groupId}"`, [
|
|
58892
|
+
"buttons",
|
|
58893
|
+
index,
|
|
58894
|
+
"groupId"
|
|
58895
|
+
]);
|
|
58896
|
+
return;
|
|
58897
|
+
}
|
|
58898
|
+
if (group.frame === "divider") fail(`a divider group ("${group.id}") holds no buttons`, [
|
|
58899
|
+
"buttons",
|
|
58900
|
+
index,
|
|
58901
|
+
"groupId"
|
|
58902
|
+
]);
|
|
58903
|
+
if (!rectContains(group, button)) fail(`button "${button.id}" lies outside its group "${group.id}"`, ["buttons", index]);
|
|
58904
|
+
return;
|
|
58905
|
+
}
|
|
58906
|
+
const foreign = groups.find((group) => rectsOverlap(group, button));
|
|
58907
|
+
if (foreign !== void 0) fail(`button "${button.id}" lies inside group "${foreign.id}" but is not a member`, ["buttons", index]);
|
|
58908
|
+
});
|
|
58909
|
+
}
|
|
58804
58910
|
object({
|
|
58805
58911
|
columns: number().int().min(1).max(24),
|
|
58806
58912
|
rows: number().int().min(1).max(24),
|
|
58807
|
-
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
58913
|
+
buttons: array(RemoteLayoutButtonSchema).max(200),
|
|
58914
|
+
groups: array(RemoteLayoutGroupSchema).max(50).optional()
|
|
58808
58915
|
}).superRefine((grid, ctx) => {
|
|
58809
58916
|
const ids = /* @__PURE__ */ new Set();
|
|
58810
58917
|
const taken = /* @__PURE__ */ new Map();
|
|
@@ -58841,6 +58948,7 @@ object({
|
|
|
58841
58948
|
taken.set(cell, button.id);
|
|
58842
58949
|
}
|
|
58843
58950
|
});
|
|
58951
|
+
refineGroups(grid, ctx);
|
|
58844
58952
|
});
|
|
58845
58953
|
var RemoteBoundCommandSchema = object({
|
|
58846
58954
|
role: RemoteRoleSchema,
|
|
@@ -58972,6 +59080,91 @@ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSche
|
|
|
58972
59080
|
kind: "mutation",
|
|
58973
59081
|
auth: "admin"
|
|
58974
59082
|
});
|
|
59083
|
+
var RemoteComponentCategorySchema = _enum([
|
|
59084
|
+
"power",
|
|
59085
|
+
"navigation",
|
|
59086
|
+
"volume",
|
|
59087
|
+
"numbers",
|
|
59088
|
+
"media",
|
|
59089
|
+
"colour",
|
|
59090
|
+
"apps",
|
|
59091
|
+
"layout"
|
|
59092
|
+
]);
|
|
59093
|
+
/** `<namespace>:<name>`, both lowercase slugs — `core:dpad`, `<addonId>:<name>`. */
|
|
59094
|
+
var COMPONENT_ID_RE = /^[a-z0-9][a-z0-9_.-]*:[a-z0-9][a-z0-9_-]*$/;
|
|
59095
|
+
var RemoteComponentButtonSchema = object({
|
|
59096
|
+
/** Joined to the instance id when the component is inserted. */
|
|
59097
|
+
idSuffix: string().regex(/^[a-z0-9][a-z0-9_-]{0,19}$/, { message: "a short lowercase slug" }),
|
|
59098
|
+
row: number().int().min(0).max(24),
|
|
59099
|
+
col: number().int().min(0).max(24),
|
|
59100
|
+
rowSpan: number().int().min(1).max(24),
|
|
59101
|
+
colSpan: number().int().min(1).max(24),
|
|
59102
|
+
role: RemoteRoleSchema,
|
|
59103
|
+
icon: string().min(1).max(60).optional(),
|
|
59104
|
+
label: string().min(1).max(40).optional(),
|
|
59105
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
59106
|
+
tone: RemoteButtonToneSchema.optional()
|
|
59107
|
+
});
|
|
59108
|
+
var RemoteLayoutComponentSchema = object({
|
|
59109
|
+
id: string().max(80).regex(COMPONENT_ID_RE, { message: "<namespace>:<name>, lowercase" }),
|
|
59110
|
+
name: string().min(1).max(60),
|
|
59111
|
+
nameI18n: object({
|
|
59112
|
+
en: string().min(1).max(60),
|
|
59113
|
+
it: string().min(1).max(60)
|
|
59114
|
+
}).optional(),
|
|
59115
|
+
/** A display icon key, resolved by the UI like a button icon. */
|
|
59116
|
+
icon: string().min(1).max(60),
|
|
59117
|
+
category: RemoteComponentCategorySchema,
|
|
59118
|
+
size: object({
|
|
59119
|
+
rows: number().int().min(1).max(24),
|
|
59120
|
+
cols: number().int().min(1).max(24)
|
|
59121
|
+
}),
|
|
59122
|
+
/** The frame drawn around the whole component, or null for loose buttons. */
|
|
59123
|
+
group: object({
|
|
59124
|
+
frame: RemoteGroupFrameSchema,
|
|
59125
|
+
title: string().min(1).max(40).optional()
|
|
59126
|
+
}).nullable(),
|
|
59127
|
+
buttons: array(RemoteComponentButtonSchema).max(40)
|
|
59128
|
+
}).superRefine((component, ctx) => {
|
|
59129
|
+
const suffixes = /* @__PURE__ */ new Set();
|
|
59130
|
+
component.buttons.forEach((button, index) => {
|
|
59131
|
+
if (suffixes.has(button.idSuffix)) ctx.addIssue({
|
|
59132
|
+
code: "custom",
|
|
59133
|
+
message: `button "${button.idSuffix}" is listed twice`,
|
|
59134
|
+
path: [
|
|
59135
|
+
"buttons",
|
|
59136
|
+
index,
|
|
59137
|
+
"idSuffix"
|
|
59138
|
+
]
|
|
59139
|
+
});
|
|
59140
|
+
suffixes.add(button.idSuffix);
|
|
59141
|
+
if (button.row + button.rowSpan > component.size.rows || button.col + button.colSpan > component.size.cols) {
|
|
59142
|
+
ctx.addIssue({
|
|
59143
|
+
code: "custom",
|
|
59144
|
+
message: `button "${button.idSuffix}" leaves the component`,
|
|
59145
|
+
path: ["buttons", index]
|
|
59146
|
+
});
|
|
59147
|
+
return;
|
|
59148
|
+
}
|
|
59149
|
+
for (let other = 0; other < index; other += 1) {
|
|
59150
|
+
const earlier = component.buttons[other];
|
|
59151
|
+
if (earlier !== void 0 && rectsOverlap(earlier, button)) {
|
|
59152
|
+
ctx.addIssue({
|
|
59153
|
+
code: "custom",
|
|
59154
|
+
message: `buttons "${earlier.idSuffix}" and "${button.idSuffix}" overlap`,
|
|
59155
|
+
path: ["buttons", index]
|
|
59156
|
+
});
|
|
59157
|
+
return;
|
|
59158
|
+
}
|
|
59159
|
+
}
|
|
59160
|
+
});
|
|
59161
|
+
if (component.group?.frame === "divider" && component.buttons.length > 0) ctx.addIssue({
|
|
59162
|
+
code: "custom",
|
|
59163
|
+
message: "a divider component holds no buttons",
|
|
59164
|
+
path: ["buttons"]
|
|
59165
|
+
});
|
|
59166
|
+
});
|
|
59167
|
+
method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
|
|
58975
59168
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
58976
59169
|
kind: "mutation",
|
|
58977
59170
|
auth: "protected"
|
|
@@ -67907,6 +68100,87 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
67907
68100
|
kind: "mutation",
|
|
67908
68101
|
auth: "admin"
|
|
67909
68102
|
});
|
|
68103
|
+
var btn = (idSuffix, row, col, init) => ({
|
|
68104
|
+
idSuffix,
|
|
68105
|
+
row,
|
|
68106
|
+
col,
|
|
68107
|
+
rowSpan: 1,
|
|
68108
|
+
colSpan: 1,
|
|
68109
|
+
...init
|
|
68110
|
+
});
|
|
68111
|
+
function rocker(id, name, it, frame, title, buttons, size) {
|
|
68112
|
+
return {
|
|
68113
|
+
id,
|
|
68114
|
+
name,
|
|
68115
|
+
nameI18n: {
|
|
68116
|
+
en: name,
|
|
68117
|
+
it
|
|
68118
|
+
},
|
|
68119
|
+
icon: frame === "rocker-v" ? "chevrons-up-down" : "chevrons-left-right",
|
|
68120
|
+
category: id.includes("channel") || id.includes("volume") ? "volume" : "navigation",
|
|
68121
|
+
size,
|
|
68122
|
+
group: title === null ? { frame } : {
|
|
68123
|
+
frame,
|
|
68124
|
+
title
|
|
68125
|
+
},
|
|
68126
|
+
buttons
|
|
68127
|
+
};
|
|
68128
|
+
}
|
|
68129
|
+
btn("power", 0, 0, {
|
|
68130
|
+
role: "power",
|
|
68131
|
+
shape: "round",
|
|
68132
|
+
tone: "danger"
|
|
68133
|
+
}), btn("up", 0, 1, { role: "up" }), btn("left", 1, 0, { role: "left" }), btn("ok", 1, 1, {
|
|
68134
|
+
role: "ok",
|
|
68135
|
+
shape: "round",
|
|
68136
|
+
tone: "accent"
|
|
68137
|
+
}), btn("right", 1, 2, { role: "right" }), btn("down", 2, 1, { role: "down" }), rocker("core:rocker-volume-v", "Volume rocker", "Bilanciere volume", "rocker-v", "VOL", [btn("up", 0, 0, {
|
|
68138
|
+
role: "volume_up",
|
|
68139
|
+
shape: "pill"
|
|
68140
|
+
}), btn("down", 1, 0, {
|
|
68141
|
+
role: "volume_down",
|
|
68142
|
+
shape: "pill"
|
|
68143
|
+
})], {
|
|
68144
|
+
rows: 2,
|
|
68145
|
+
cols: 1
|
|
68146
|
+
}), rocker("core:rocker-channel-v", "Channel rocker", "Bilanciere canali", "rocker-v", "CH", [btn("up", 0, 0, {
|
|
68147
|
+
role: "channel_up",
|
|
68148
|
+
shape: "pill"
|
|
68149
|
+
}), btn("down", 1, 0, {
|
|
68150
|
+
role: "channel_down",
|
|
68151
|
+
shape: "pill"
|
|
68152
|
+
})], {
|
|
68153
|
+
rows: 2,
|
|
68154
|
+
cols: 1
|
|
68155
|
+
}), rocker("core:rocker-h", "Minus / plus rocker", "Bilanciere meno / più", "rocker-h", null, [btn("minus", 0, 0, {
|
|
68156
|
+
role: "custom:minus",
|
|
68157
|
+
label: "−",
|
|
68158
|
+
shape: "pill"
|
|
68159
|
+
}), btn("plus", 0, 1, {
|
|
68160
|
+
role: "custom:plus",
|
|
68161
|
+
label: "+",
|
|
68162
|
+
shape: "pill"
|
|
68163
|
+
})], {
|
|
68164
|
+
rows: 1,
|
|
68165
|
+
cols: 2
|
|
68166
|
+
}), [...Array.from({ length: 9 }, (_, i) => btn(`d${i + 1}`, Math.floor(i / 3), i % 3, { role: `digit_${i + 1}` })), btn("d0", 3, 1, { role: "digit_0" })], btn("red", 0, 0, {
|
|
68167
|
+
role: "custom:color_red",
|
|
68168
|
+
tone: "red"
|
|
68169
|
+
}), btn("green", 0, 1, {
|
|
68170
|
+
role: "custom:color_green",
|
|
68171
|
+
tone: "green"
|
|
68172
|
+
}), btn("yellow", 0, 2, {
|
|
68173
|
+
role: "custom:color_yellow",
|
|
68174
|
+
tone: "yellow"
|
|
68175
|
+
}), btn("blue", 0, 3, {
|
|
68176
|
+
role: "custom:color_blue",
|
|
68177
|
+
tone: "blue"
|
|
68178
|
+
}), btn("rewind", 0, 0, { role: "rewind" }), btn("play", 0, 1, { role: "play" }), btn("pause", 0, 2, { role: "pause" }), btn("forward", 0, 3, { role: "fast_forward" }), btn("stop", 0, 4, { role: "stop" }), [
|
|
68179
|
+
1,
|
|
68180
|
+
2,
|
|
68181
|
+
3,
|
|
68182
|
+
4
|
|
68183
|
+
].map((n) => btn(`app${n}`, 0, n - 1, { role: `custom:app_slot_${n}` })), btn("back", 0, 0, { role: "back" }), btn("home", 0, 1, { role: "home" }), btn("menu", 0, 2, { role: "menu" });
|
|
67910
68184
|
discriminatedUnion("kind", [object({
|
|
67911
68185
|
kind: literal("raw"),
|
|
67912
68186
|
timings: array(number().int()),
|
|
@@ -75869,6 +76143,13 @@ Object.freeze({
|
|
|
75869
76143
|
access: "create",
|
|
75870
76144
|
role: "admin"
|
|
75871
76145
|
},
|
|
76146
|
+
"remoteLayoutComponents.listComponents": {
|
|
76147
|
+
capName: "remote-layout-components",
|
|
76148
|
+
capScope: "system",
|
|
76149
|
+
addonId: null,
|
|
76150
|
+
access: "view",
|
|
76151
|
+
role: "admin"
|
|
76152
|
+
},
|
|
75872
76153
|
"runningState.getStatus": {
|
|
75873
76154
|
capName: "running-state",
|
|
75874
76155
|
capScope: "device",
|
|
@@ -82045,6 +82326,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
82045
82326
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
82046
82327
|
records: system(INTERNAL),
|
|
82047
82328
|
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
82329
|
+
"remote-layout-components": system("the palette of the remote template editor — read-only data, never actuated"),
|
|
82048
82330
|
"server-management": system(CLUSTER),
|
|
82049
82331
|
"settings-store": system(INTERNAL),
|
|
82050
82332
|
"smtp-provider": system(INTERNAL),
|