@camstack/addon-agent-ui 1.2.350 → 1.2.352
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 +12 -0
- package/dist/.bundle-modules.json +4 -4
- package/dist/addon.js +82 -105
- package/dist/assets/{MotionZonesSettings-DCz-FuB6.js → MotionZonesSettings-7pE3DTkM.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-CUncW4bi.js → PrivacyMaskSettings-BWTRWlKw.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-BVNmu1O7.js → SceneMonitorEditor-fTChcs-G.js} +1 -1
- package/dist/assets/index-BePyQ_Ek.js +145 -0
- package/dist/index.html +1 -1
- package/package.json +2 -2
- package/dist/assets/index-DIZdNkiY.js +0 -145
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.352] - 2026-11-09
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Rebuilt against updated dependencies.
|
|
15
|
+
|
|
16
|
+
## [1.2.351] - 2026-11-09
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Rebuilt against updated dependencies.
|
|
21
|
+
|
|
10
22
|
## [1.2.350] - 2026-11-08
|
|
11
23
|
|
|
12
24
|
### Changed
|
|
@@ -367,14 +367,14 @@
|
|
|
367
367
|
"server/server/packages/addon-agent-ui/src/updates-panel.tsx": "ec6b5b3701322bbb68dbe581703409cd373418cf9227ce829ea0945e70e60d54",
|
|
368
368
|
"server/server/packages/addon-agent-ui/src/use-pairing-status.ts": "46193a1e83a64250dfff75d417448d74ba0159465e710861b996e903b03e427a",
|
|
369
369
|
"server/server/packages/sdk/dist/index.js": "89409bfb9632c46ed63ee4882c70b7994c1ff90c67d27a5d4b86b0990c41a131",
|
|
370
|
-
"server/server/packages/types/dist/client.mjs": "
|
|
370
|
+
"server/server/packages/types/dist/client.mjs": "ab4b63f8faa3c0cef26052a407d63509d0104362261c2b9631b2ea211d618c93",
|
|
371
371
|
"server/server/packages/types/dist/composition-CXCX78IR.mjs": "3c34431544a6b88404f5f7c855c84ebbf2e5736ad300d4d4dfa2417759f30d46",
|
|
372
372
|
"server/server/packages/types/dist/convert-BAzH15HU.mjs": "baa969d99051a3b05b2620e8b8e776a6f5539ac74ee9f9dbee1cc6b6a3a892a0",
|
|
373
373
|
"server/server/packages/types/dist/device-type-CbDhVwFP.mjs": "94089ac4e225fbd1a8109ff7d5db680acff824c0745d60a1ccf52b4e2717451d",
|
|
374
374
|
"server/server/packages/types/dist/event-category-78tcBemo.mjs": "767f1bb576027d9ee79ec036367001330203d84842c2c2111fa465fa434045e2",
|
|
375
|
-
"server/server/packages/types/dist/index.mjs": "
|
|
375
|
+
"server/server/packages/types/dist/index.mjs": "c81ce138f6e772774cbf59eca26247d111c9dd956e9295c83accf7bdc5be1087",
|
|
376
376
|
"server/server/packages/types/dist/node-color.mjs": "942e663074f0a4ed2f8643848ec139eba4b5fd16d0d01c8a23e08a4819a8843b",
|
|
377
|
-
"server/server/packages/types/dist/sleep-
|
|
377
|
+
"server/server/packages/types/dist/sleep-CkinsFFb.mjs": "ad13e74a69ba822ea871380a133cb56ecbcfcd844c2276a8fe5783c0ed113de3",
|
|
378
378
|
"server/server/packages/ui-library/src/composites/adaptive-downlink.ts": "6e9698e97721461b72a3750f930dd7214d049be865491bfb5a64b87c032b0e22",
|
|
379
379
|
"server/server/packages/ui-library/src/composites/camera-stream-player.tsx": "c04809229b4e091fed09e2bcfe643d6b36cb3a39e294229b49f8a095e4e6ebd3",
|
|
380
380
|
"server/server/packages/ui-library/src/composites/cap-settings/CameraGridLayoutEditor.tsx": "fae93899c4903183e1b78db39e58bd52a3dd4dc2c11ce85d64e6d2a2bab7516d",
|
|
@@ -486,7 +486,7 @@
|
|
|
486
486
|
"server/server/packages/ui-library/src/contexts/vod-playback.tsx": "c07bc3ecc786182ef2f27d13bec3f520288e0b47367edd7ddf1c2e7b4a2bbaee",
|
|
487
487
|
"server/server/packages/ui-library/src/contexts/widget-registry.tsx": "71a2815c645abe96821a9e9e5668e321187527d569414f5ca197d615856cc17a",
|
|
488
488
|
"server/server/packages/ui-library/src/contexts/zone-editing.tsx": "275f680304ab09dd747fd9e859dc5aa0535df33eb2d33eb669a6de66bdd848d0",
|
|
489
|
-
"server/server/packages/ui-library/src/generated/system-hooks.ts": "
|
|
489
|
+
"server/server/packages/ui-library/src/generated/system-hooks.ts": "f1242a45e5897fbc5318df28fe19dd1c0a72b6ac59b3a07362869cd5851f8eb8",
|
|
490
490
|
"server/server/packages/ui-library/src/hooks/turn-server-cache.ts": "fab22f069c3761e0d268449e056d9c499b6ea63b879684a40023735b34bad061",
|
|
491
491
|
"server/server/packages/ui-library/src/hooks/use-device-capability.ts": "b74ede60be8039c45f6c712a407ee838ab208610435870ddabaa8598cb7cd7f3",
|
|
492
492
|
"server/server/packages/ui-library/src/hooks/use-device-detections.ts": "61cc54cf2e7f53864e5aa533c05679e4c204c4004a0296f63ab169b003888611",
|
package/dist/addon.js
CHANGED
|
@@ -5880,7 +5880,7 @@ var ZodIssueCode = {
|
|
|
5880
5880
|
var ZodFirstPartyTypeKind;
|
|
5881
5881
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5882
5882
|
//#endregion
|
|
5883
|
-
//#region ../types/dist/sleep-
|
|
5883
|
+
//#region ../types/dist/sleep-CkinsFFb.mjs
|
|
5884
5884
|
/**
|
|
5885
5885
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5886
5886
|
* window to float samples (D455).
|
|
@@ -8011,16 +8011,6 @@ var BaseAddon = class {
|
|
|
8011
8011
|
return null;
|
|
8012
8012
|
}
|
|
8013
8013
|
/**
|
|
8014
|
-
* The form schema of ONE integration instance, or `null` to use the scoped form.
|
|
8015
|
-
*
|
|
8016
|
-
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
8017
|
-
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
8018
|
-
* SHAPE of the form only — the values live on the instance record.
|
|
8019
|
-
*/
|
|
8020
|
-
async integrationFormSchema(_instance) {
|
|
8021
|
-
return null;
|
|
8022
|
-
}
|
|
8023
|
-
/**
|
|
8024
8014
|
* D986 scoped settings: the form shape of the CLUSTER-wide settings one capability this addon
|
|
8025
8015
|
* provides owns, or `null` when it has none. `cap` is a capability name the addon's manifest
|
|
8026
8016
|
* declares. Stored as `addon-settings` rows `<addonId>.<field>`. The keys of this schema, of
|
|
@@ -8048,8 +8038,7 @@ var BaseAddon = class {
|
|
|
8048
8038
|
}
|
|
8049
8039
|
/**
|
|
8050
8040
|
* The host's read of the scoped declarations: the schema one capability declares for `scope`,
|
|
8051
|
-
* or `null`.
|
|
8052
|
-
* host asks this method.
|
|
8041
|
+
* or `null`. The hook is protected, the host asks this method.
|
|
8053
8042
|
*/
|
|
8054
8043
|
async getScopedSettingsSchema(scope, cap) {
|
|
8055
8044
|
switch (scope) {
|
|
@@ -8217,22 +8206,6 @@ var BaseAddon = class {
|
|
|
8217
8206
|
return Object.fromEntries([...collectHydratedFieldValues(form)].filter(([, value]) => value !== void 0));
|
|
8218
8207
|
}
|
|
8219
8208
|
/**
|
|
8220
|
-
* What the create wizard and the integration edit page render for one instance: the addon's
|
|
8221
|
-
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
8222
|
-
*/
|
|
8223
|
-
async getIntegrationFormSchema(instance, nodeId) {
|
|
8224
|
-
const scoped = await this.integrationFormSchema(instance);
|
|
8225
|
-
if (scoped === null) return this.scopedForm(nodeId);
|
|
8226
|
-
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
8227
|
-
}
|
|
8228
|
-
/** The form of the scoped schemas this addon declared, hydrated from its store. */
|
|
8229
|
-
async scopedForm(nodeId) {
|
|
8230
|
-
await this.loadScopedSchemas();
|
|
8231
|
-
const schema = this.scopedFormSchema();
|
|
8232
|
-
if (!schema) return { sections: [] };
|
|
8233
|
-
return hydrateSchema(schema, await this.readRawProjectedStore(nodeId), { inlineSecretsAsViews: true });
|
|
8234
|
-
}
|
|
8235
|
-
/**
|
|
8236
8209
|
* The raw addon store PROJECTED onto the target node's bare per-node keys:
|
|
8237
8210
|
* every `perNode: true` field carries THAT node's scoped value on its bare
|
|
8238
8211
|
* key (absent scoped key ⇒ key absent, so the schema `default` wins — no
|
|
@@ -8419,12 +8392,6 @@ var BaseAddon = class {
|
|
|
8419
8392
|
this._nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
8420
8393
|
this._addonSecretTree = null;
|
|
8421
8394
|
}
|
|
8422
|
-
/** The form of an addon's scoped schemas: their sections, each shown once. */
|
|
8423
|
-
scopedFormSchema(cap) {
|
|
8424
|
-
const byId = /* @__PURE__ */ new Map();
|
|
8425
|
-
for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
|
|
8426
|
-
return byId.size === 0 ? null : { sections: [...byId.values()] };
|
|
8427
|
-
}
|
|
8428
8395
|
/** Every loaded scoped schema of `cap`, or of every loaded capability. */
|
|
8429
8396
|
loadedScopedSchemas(cap) {
|
|
8430
8397
|
if (cap !== void 0) return this._scopedByCap.get(cap) ?? [];
|
|
@@ -9014,6 +8981,10 @@ function normalizeAddonInitResult(result) {
|
|
|
9014
8981
|
if (Array.isArray(result)) return { providers: result };
|
|
9015
8982
|
return result;
|
|
9016
8983
|
}
|
|
8984
|
+
object({
|
|
8985
|
+
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
8986
|
+
params: record(string(), union([string(), number$1()])).optional()
|
|
8987
|
+
});
|
|
9017
8988
|
object({
|
|
9018
8989
|
field: string().min(1),
|
|
9019
8990
|
on: literal("advance")
|
|
@@ -9090,12 +9061,6 @@ function systemMethod(input, output, options) {
|
|
|
9090
9061
|
systemOnly: true
|
|
9091
9062
|
};
|
|
9092
9063
|
}
|
|
9093
|
-
/**
|
|
9094
|
-
* A method a SOURCE of a collection cap may legitimately not serve — OPTIONAL
|
|
9095
|
-
* on `InferProvider`. The `providerOptional: true` literal is what
|
|
9096
|
-
* `InferProvider` keys on; see {@link CapabilityMethodSchema.providerOptional}
|
|
9097
|
-
* for when this is the honest answer and when it is a soft stub.
|
|
9098
|
-
*/
|
|
9099
9064
|
function optionalMethod(input, output, options) {
|
|
9100
9065
|
return {
|
|
9101
9066
|
...method(input, output, options),
|
|
@@ -16318,10 +16283,6 @@ Object.freeze({
|
|
|
16318
16283
|
"uploadDataset": 72e5
|
|
16319
16284
|
}
|
|
16320
16285
|
});
|
|
16321
|
-
object({
|
|
16322
|
-
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
16323
|
-
params: record(string(), union([string(), number$1()])).optional()
|
|
16324
|
-
});
|
|
16325
16286
|
//#endregion
|
|
16326
16287
|
//#region ../types/dist/composition-CXCX78IR.mjs
|
|
16327
16288
|
/**
|
|
@@ -18033,25 +17994,6 @@ var RequiredAddonUpdateSchema = object({
|
|
|
18033
17994
|
installed: string().nullable()
|
|
18034
17995
|
});
|
|
18035
17996
|
/**
|
|
18036
|
-
* Which integration instance a settings form is for. An addon that serves several instances
|
|
18037
|
-
* (`instanceMode: multiple`) can show a different form per instance — an NVR integration
|
|
18038
|
-
* needs its connection, the default integration needs the addon's own sections.
|
|
18039
|
-
*
|
|
18040
|
-
* - `integrationId` is `null` in the create wizard: nothing exists yet, the operator is
|
|
18041
|
-
* setting up a NEW instance.
|
|
18042
|
-
* - `mode` is the wizard mode of the integration type (`getAvailableTypes`).
|
|
18043
|
-
* - `candidateStableId` is the discovery candidate a wizard was seeded from, if any.
|
|
18044
|
-
*/
|
|
18045
|
-
var IntegrationInstanceRefSchema = object({
|
|
18046
|
-
integrationId: string().nullable(),
|
|
18047
|
-
mode: _enum([
|
|
18048
|
-
"standalone",
|
|
18049
|
-
"account",
|
|
18050
|
-
"broker"
|
|
18051
|
-
]),
|
|
18052
|
-
candidateStableId: string().optional()
|
|
18053
|
-
});
|
|
18054
|
-
/**
|
|
18055
17997
|
* notification-output — canonical, capability-gated notification delivery.
|
|
18056
17998
|
*
|
|
18057
17999
|
* Apprise-derived model (see
|
|
@@ -44137,10 +44079,6 @@ method(object({
|
|
|
44137
44079
|
scope: ScopedSettingsScopeSchema,
|
|
44138
44080
|
nodeId: string().optional()
|
|
44139
44081
|
}), record(string(), unknown()).nullable()), method(object({
|
|
44140
|
-
addonId: string(),
|
|
44141
|
-
nodeId: string().optional(),
|
|
44142
|
-
instance: IntegrationInstanceRefSchema
|
|
44143
|
-
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
44144
44082
|
addonId: string(),
|
|
44145
44083
|
nodeId: string().optional()
|
|
44146
44084
|
}), object({ keys: array(string()) }).nullable(), { auth: "admin" }), method(object({
|
|
@@ -46148,7 +46086,14 @@ var CalendarInfoSchema = object({
|
|
|
46148
46086
|
id: string().min(1),
|
|
46149
46087
|
name: string().min(1),
|
|
46150
46088
|
source: CalendarSourceKindSchema,
|
|
46151
|
-
enabled: boolean()
|
|
46089
|
+
enabled: boolean(),
|
|
46090
|
+
/**
|
|
46091
|
+
* The `integration-instances` record that owns this calendar (the record the switch writes).
|
|
46092
|
+
* Every source stamps it from the record it read the calendar from, so a consumer joins on
|
|
46093
|
+
* it instead of rebuilding an id from form values. Optional on the wire so a source addon
|
|
46094
|
+
* that predates the field still lists its calendars: such a row simply has no switch.
|
|
46095
|
+
*/
|
|
46096
|
+
instanceId: string().min(1).optional()
|
|
46152
46097
|
});
|
|
46153
46098
|
/**
|
|
46154
46099
|
* Time contract of {@link CalendarEvent}.
|
|
@@ -48144,8 +48089,12 @@ var RemoteSourceSchema = discriminatedUnion("kind", [
|
|
|
48144
48089
|
object({
|
|
48145
48090
|
...sourceBase,
|
|
48146
48091
|
kind: literal("ir"),
|
|
48147
|
-
/**
|
|
48148
|
-
|
|
48092
|
+
/**
|
|
48093
|
+
* The `ir-transmitter` device the code is sent through. Absent = the remote's
|
|
48094
|
+
* `defaultTransmitterId` at run time (a source stored before this field was
|
|
48095
|
+
* optional keeps the emitter it names).
|
|
48096
|
+
*/
|
|
48097
|
+
transmitterId: number$1().int().nonnegative().optional(),
|
|
48149
48098
|
/** The code itself; whether a transmitter could send it is `irSourceProblem`. */
|
|
48150
48099
|
payload: IrPayloadSchema
|
|
48151
48100
|
})
|
|
@@ -54496,6 +54445,12 @@ var IntegrationWithStateSchema = object({
|
|
|
54496
54445
|
name: string(),
|
|
54497
54446
|
/** A projection of the instance body's switch (`setInstanceEnabled` is the only writer). */
|
|
54498
54447
|
enabled: boolean(),
|
|
54448
|
+
/**
|
|
54449
|
+
* True when the addon that holds the switch did not answer (down, failed, or keeps no record for
|
|
54450
|
+
* this row): `enabled` is then the stored registry flag, a stale value, not the state. A reader
|
|
54451
|
+
* must not draw it as on or off (D315).
|
|
54452
|
+
*/
|
|
54453
|
+
switchUnknown: literal(true).optional(),
|
|
54499
54454
|
info: record(string(), unknown()).readonly(),
|
|
54500
54455
|
/** The discovery candidate this integration was set up from (D984). */
|
|
54501
54456
|
originStableId: string().optional(),
|
|
@@ -54509,6 +54464,12 @@ var IntegrationLiteSchema = object({
|
|
|
54509
54464
|
name: string(),
|
|
54510
54465
|
/** A projection of the instance body's switch (`setInstanceEnabled` is the only writer). */
|
|
54511
54466
|
enabled: boolean(),
|
|
54467
|
+
/**
|
|
54468
|
+
* True when the addon that holds the switch did not answer (down, failed, or keeps no record for
|
|
54469
|
+
* this row): `enabled` is then the stored registry flag, a stale value, not the state. A reader
|
|
54470
|
+
* must not draw it as on or off (D315).
|
|
54471
|
+
*/
|
|
54472
|
+
switchUnknown: literal(true).optional(),
|
|
54512
54473
|
info: record(string(), unknown()).readonly(),
|
|
54513
54474
|
/** The discovery candidate this integration was set up from (D984). */
|
|
54514
54475
|
originStableId: string().optional(),
|
|
@@ -54607,9 +54568,9 @@ var UpdateIntegrationInputSchema = object({
|
|
|
54607
54568
|
id: string(),
|
|
54608
54569
|
name: string().optional(),
|
|
54609
54570
|
/**
|
|
54610
|
-
*
|
|
54611
|
-
*
|
|
54612
|
-
*
|
|
54571
|
+
* Honoured ONLY for a fixed builtin (`info.fixed`), whose switch is the hub's own registry flag
|
|
54572
|
+
* and works while its addon is down. Any other row is refused (a typed `BAD_REQUEST`): its
|
|
54573
|
+
* switch is `integration-instances.setInstanceEnabled`.
|
|
54613
54574
|
*/
|
|
54614
54575
|
enabled: boolean().optional(),
|
|
54615
54576
|
info: record(string(), unknown()).optional()
|
|
@@ -54643,6 +54604,12 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
54643
54604
|
* the form as a `SecretFieldView`, never text (D789). A patch value omitted, `''`
|
|
54644
54605
|
* or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
|
|
54645
54606
|
* clears it.
|
|
54607
|
+
*
|
|
54608
|
+
* Who may call (epic #440): every method but `describe` and `instanceFormSchema` is open to any
|
|
54609
|
+
* session (`caller: 'scoped'`) and default-denies. An admin passes everywhere. A non-admin passes
|
|
54610
|
+
* only on a call pinned to one addon whose `describe().userScoped` is true, and that provider
|
|
54611
|
+
* filters every row on the `caller` the router injected (a notification target is somebody's
|
|
54612
|
+
* phone: a user sees and changes only their own). An addon that says nothing keeps the admin door.
|
|
54646
54613
|
*/
|
|
54647
54614
|
var ConfigSchemaPassthrough$2 = custom();
|
|
54648
54615
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
@@ -54756,7 +54723,15 @@ var IntegrationInstanceDescriptionSchema = object({
|
|
|
54756
54723
|
*/
|
|
54757
54724
|
mintsId: boolean().optional(),
|
|
54758
54725
|
/** The links to other instances the provider's kinds declare; absent means none. */
|
|
54759
|
-
links: array(IntegrationInstanceLinkSchema).optional()
|
|
54726
|
+
links: array(IntegrationInstanceLinkSchema).optional(),
|
|
54727
|
+
/**
|
|
54728
|
+
* The rows belong to individual users (a notification target is somebody's phone). The router
|
|
54729
|
+
* then opens `listInstances`, `getInstance`, `createInstance`, `updateInstance`,
|
|
54730
|
+
* `setInstanceEnabled`, `deleteInstance` and `testInstance` to a NON-admin session on a call
|
|
54731
|
+
* pinned to this addon, and hands the provider the `caller` so it keeps a user to their own rows.
|
|
54732
|
+
* Absent means admin only, as it always was.
|
|
54733
|
+
*/
|
|
54734
|
+
userScoped: boolean().optional()
|
|
54760
54735
|
});
|
|
54761
54736
|
var IntegrationInstanceStatusSchema = object({
|
|
54762
54737
|
state: _enum([
|
|
@@ -54806,7 +54781,13 @@ method(_void(), IntegrationInstanceDescriptionSchema, { auth: "admin" }), method
|
|
|
54806
54781
|
]).optional(),
|
|
54807
54782
|
/** The discovery candidate the wizard was seeded from (`stableId`), if any. */
|
|
54808
54783
|
candidateStableId: string().min(1).optional()
|
|
54809
|
-
}), ConfigSchemaPassthrough$2, { auth: "admin" }), method(
|
|
54784
|
+
}), ConfigSchemaPassthrough$2, { auth: "admin" }), method(looseObject({}), array(IntegrationInstanceSchema).readonly(), {
|
|
54785
|
+
auth: "protected",
|
|
54786
|
+
caller: "scoped"
|
|
54787
|
+
}), method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), {
|
|
54788
|
+
auth: "protected",
|
|
54789
|
+
caller: "scoped"
|
|
54790
|
+
}), method(object({
|
|
54810
54791
|
id: IntegrationInstanceIdSchema.optional(),
|
|
54811
54792
|
name: string().min(1),
|
|
54812
54793
|
kind: string().min(1).optional(),
|
|
@@ -54828,19 +54809,23 @@ method(_void(), IntegrationInstanceDescriptionSchema, { auth: "admin" }), method
|
|
|
54828
54809
|
seed: object({ info: record(string(), unknown()) }).optional()
|
|
54829
54810
|
}), object({ id: string() }), {
|
|
54830
54811
|
kind: "mutation",
|
|
54831
|
-
auth: "
|
|
54812
|
+
auth: "protected",
|
|
54813
|
+
caller: "scoped"
|
|
54832
54814
|
}), method(IntegrationInstancePatchSchema, object({ ok: literal(true) }), {
|
|
54833
54815
|
kind: "mutation",
|
|
54834
|
-
auth: "
|
|
54816
|
+
auth: "protected",
|
|
54817
|
+
caller: "scoped"
|
|
54835
54818
|
}), method(object({
|
|
54836
54819
|
id: IntegrationInstanceIdSchema,
|
|
54837
54820
|
enabled: boolean()
|
|
54838
54821
|
}), object({ ok: literal(true) }), {
|
|
54839
54822
|
kind: "mutation",
|
|
54840
|
-
auth: "
|
|
54823
|
+
auth: "protected",
|
|
54824
|
+
caller: "scoped"
|
|
54841
54825
|
}), method(object({ id: IntegrationInstanceIdSchema }), object({ ok: literal(true) }), {
|
|
54842
54826
|
kind: "mutation",
|
|
54843
|
-
auth: "
|
|
54827
|
+
auth: "protected",
|
|
54828
|
+
caller: "scoped"
|
|
54844
54829
|
}), optionalMethod(object({
|
|
54845
54830
|
id: IntegrationInstanceIdSchema.nullable(),
|
|
54846
54831
|
values: record(string(), unknown()),
|
|
@@ -54848,7 +54833,8 @@ method(_void(), IntegrationInstanceDescriptionSchema, { auth: "admin" }), method
|
|
|
54848
54833
|
kind: string().min(1).optional()
|
|
54849
54834
|
}), TestConnectionResultSchema, {
|
|
54850
54835
|
kind: "mutation",
|
|
54851
|
-
auth: "
|
|
54836
|
+
auth: "protected",
|
|
54837
|
+
caller: "scoped"
|
|
54852
54838
|
});
|
|
54853
54839
|
/**
|
|
54854
54840
|
* Two-way audio / talk-back cap. Clients open a WebRTC audio-only
|
|
@@ -71309,7 +71295,6 @@ var RemoteCustomButtonSchema = object({
|
|
|
71309
71295
|
/** What the operator calls it, and what a voice command may name. */
|
|
71310
71296
|
name: string().min(1).max(60)
|
|
71311
71297
|
});
|
|
71312
|
-
var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
|
|
71313
71298
|
/**
|
|
71314
71299
|
* The source rules: every step role is bound, ids and names are unique, a
|
|
71315
71300
|
* channel number belongs to one `digits` source, and no name or id is another
|
|
@@ -71390,7 +71375,6 @@ var RemoteConfigSchema = object({
|
|
|
71390
71375
|
sources: array(RemoteSourceSchema).max(200).default([]),
|
|
71391
71376
|
/** The pause between two steps of a source: the television's receiver, not a repeat. */
|
|
71392
71377
|
stepDelayMs: number$1().int().min(100).max(REMOTE_STEP_DELAY_MAX_MS).default(500),
|
|
71393
|
-
power: object({ mode: RemotePowerModeSchema }),
|
|
71394
71378
|
/**
|
|
71395
71379
|
* READ-ONLY: sources a stored configuration carries that no longer parse,
|
|
71396
71380
|
* left out of `sources` with the reason (`readStoredRemoteConfig`). Never
|
|
@@ -71494,6 +71478,11 @@ var RemoteLayoutButtonSchema = object({
|
|
|
71494
71478
|
/** Absent = the plain rendering every layout had before shapes existed. */
|
|
71495
71479
|
shape: RemoteButtonShapeSchema.optional(),
|
|
71496
71480
|
tone: RemoteButtonToneSchema.optional(),
|
|
71481
|
+
/**
|
|
71482
|
+
* Draw the label on a colour-toned key. A colour key shows only its colour
|
|
71483
|
+
* by default; a remote whose plastic prints letters on them (A B C D) sets it.
|
|
71484
|
+
*/
|
|
71485
|
+
showLegend: boolean().optional(),
|
|
71497
71486
|
/** The group this button belongs to; it must lie inside that group's rectangle. */
|
|
71498
71487
|
groupId: string().min(1).max(40).optional()
|
|
71499
71488
|
});
|
|
@@ -71631,7 +71620,6 @@ var RemoteBoundCommandSchema = object({
|
|
|
71631
71620
|
});
|
|
71632
71621
|
var RemoteCommandListSchema = object({
|
|
71633
71622
|
layoutTemplateId: string().nullable(),
|
|
71634
|
-
power: object({ mode: RemotePowerModeSchema }),
|
|
71635
71623
|
/** Only the roles that are BOUND — the ones a press can reach. */
|
|
71636
71624
|
commands: array(RemoteBoundCommandSchema),
|
|
71637
71625
|
/** The sources the operator declared; empty when none (planning#460). */
|
|
@@ -71644,7 +71632,8 @@ var RemoteRefusalReasonSchema = _enum([
|
|
|
71644
71632
|
"unknown-source",
|
|
71645
71633
|
"unbound-step",
|
|
71646
71634
|
"undeclared-channel",
|
|
71647
|
-
"press-timeout"
|
|
71635
|
+
"press-timeout",
|
|
71636
|
+
"no-transmitter"
|
|
71648
71637
|
]);
|
|
71649
71638
|
var RemoteSendResultSchema = discriminatedUnion("status", [
|
|
71650
71639
|
object({
|
|
@@ -71737,7 +71726,8 @@ var RemoteComponentButtonSchema = object({
|
|
|
71737
71726
|
icon: string().min(1).max(60).optional(),
|
|
71738
71727
|
label: string().min(1).max(40).optional(),
|
|
71739
71728
|
shape: RemoteButtonShapeSchema.optional(),
|
|
71740
|
-
tone: RemoteButtonToneSchema.optional()
|
|
71729
|
+
tone: RemoteButtonToneSchema.optional(),
|
|
71730
|
+
showLegend: boolean().optional()
|
|
71741
71731
|
});
|
|
71742
71732
|
var RemoteLayoutComponentSchema = object({
|
|
71743
71733
|
id: string().max(80).regex(COMPONENT_ID_RE, { message: "<namespace>:<name>, lowercase" }),
|
|
@@ -72692,6 +72682,11 @@ var SendEmailResultSchema = object({
|
|
|
72692
72682
|
var SmtpStatusSchema = object({
|
|
72693
72683
|
/** True iff the addon has successfully verified the relay. */
|
|
72694
72684
|
ready: boolean(),
|
|
72685
|
+
/**
|
|
72686
|
+
* The tri-state behind `ready` (D315): true when the last send worked, false when it failed,
|
|
72687
|
+
* ABSENT when the relay has not sent yet (unknown, never "not verified").
|
|
72688
|
+
*/
|
|
72689
|
+
verified: boolean().optional(),
|
|
72695
72690
|
/** Operator-visible host string (no credentials). */
|
|
72696
72691
|
host: string(),
|
|
72697
72692
|
/** Last error message reported by the relay, when not ready. */
|
|
@@ -72703,10 +72698,6 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
|
|
|
72703
72698
|
kind: "mutation",
|
|
72704
72699
|
auth: "admin",
|
|
72705
72700
|
access: "create"
|
|
72706
|
-
}), method(RelayPinSchema, SmtpStatusSchema, {
|
|
72707
|
-
kind: "mutation",
|
|
72708
|
-
auth: "admin",
|
|
72709
|
-
access: "view"
|
|
72710
72701
|
}), method(RelayPinSchema, SmtpStatusSchema, { auth: "admin" });
|
|
72711
72702
|
/**
|
|
72712
72703
|
* A single device snapshot returned as base64 JPEG/PNG.
|
|
@@ -79375,13 +79366,6 @@ Object.freeze({
|
|
|
79375
79366
|
access: "view",
|
|
79376
79367
|
role: "admin"
|
|
79377
79368
|
},
|
|
79378
|
-
"addonSettings.getIntegrationFormSchema": {
|
|
79379
|
-
capName: "addon-settings",
|
|
79380
|
-
capScope: "system",
|
|
79381
|
-
addonId: null,
|
|
79382
|
-
access: "view",
|
|
79383
|
-
role: "admin"
|
|
79384
|
-
},
|
|
79385
79369
|
"addonSettings.getScopedSettings": {
|
|
79386
79370
|
capName: "addon-settings",
|
|
79387
79371
|
capScope: "system",
|
|
@@ -87404,13 +87388,6 @@ Object.freeze({
|
|
|
87404
87388
|
access: "create",
|
|
87405
87389
|
role: "admin"
|
|
87406
87390
|
},
|
|
87407
|
-
"smtpProvider.verify": {
|
|
87408
|
-
capName: "smtp-provider",
|
|
87409
|
-
capScope: "system",
|
|
87410
|
-
addonId: null,
|
|
87411
|
-
access: "view",
|
|
87412
|
-
role: "admin"
|
|
87413
|
-
},
|
|
87414
87391
|
"snapshot.applyDeviceSettingsPatch": {
|
|
87415
87392
|
capName: "snapshot",
|
|
87416
87393
|
capScope: "device",
|
|
@@ -93786,7 +93763,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
93786
93763
|
capability: adminUiCapability,
|
|
93787
93764
|
provider: {
|
|
93788
93765
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
93789
|
-
getVersion: async () => ({ version: "1.2.
|
|
93766
|
+
getVersion: async () => ({ version: "1.2.352" })
|
|
93790
93767
|
}
|
|
93791
93768
|
}];
|
|
93792
93769
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{T as a,_ as o,c as s,d as c,l,p as u,t as d}from"./index-
|
|
1
|
+
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{T as a,_ as o,c as s,d as c,l,p as u,t as d}from"./index-BePyQ_Ek.js";import{MaskShapeCanvas as f}from"./MaskShapeCanvas-BTvl6Rin.js";var p=a(`grid-2x2`,[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`path`,{d:`M3 12h18`,key:`1i2n21`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),m=n(i(),1),h=n(e(),1),g=110,_=`motion-zones`,v=0,y=[1,2,3],b=1,x=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,S=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function C(e,t,n){let r=t*n,i=Array.from({length:r});for(let t=0;t<r;t+=1)i[t]=e[t]===!0;return i}function w(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}function T(e,t){return Math.ceil(e/t)}function E(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function D(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+E(n,t,i)]=!0)}return o}function O(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+E(n,t,i)]===!0}return o}function k({deviceId:e}){let n=t(),i=c(o().trpcClient,e),[a,E]=(0,m.useState)(null),[k,A]=(0,m.useState)(!1),[j,M]=(0,m.useState)(null),[N,P]=(0,m.useState)(null),[F,I]=(0,m.useState)(b),[L,R]=(0,m.useState)(!1),[z,B]=(0,m.useState)(!1),V=(0,m.useRef)(!1);(0,m.useEffect)(()=>{if(!i)return;let e=!1;return V.current=!1,E(null),A(!1),M(null),P(null),I(b),B(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(E(t),V.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);V.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=C(r?r.shape.cells:[],t.grid.width,t.grid.height);P(a),M(D(a,t.grid.width,t.grid.height,b))}catch(t){if(e)return;l(t)?A(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let H=a?a.grid.width:0,U=a?a.grid.height:0,W=T(H,F),G=T(U,F),K=(0,m.useMemo)(()=>j&&a?O(j,H,U,F):null,[j,a,H,U,F]),q=(0,m.useMemo)(()=>K!==null&&N!==null&&!w(K,N),[K,N]),J=(0,m.useMemo)(()=>K?K.reduce((e,t)=>t?e+1:e,0):0,[K]),Y=H*U,X=W*G,Z=(0,m.useCallback)(e=>{X>0&&M(Array.from({length:X},()=>e))},[X]),ee=(0,m.useCallback)(()=>{M(e=>e&&e.map(e=>!e))},[]),te=(0,m.useCallback)(()=>{N&&a&&M(D(N,H,U,F))},[N,a,H,U,F]),ne=(0,m.useCallback)(e=>{e===F||!a||M(t=>{if(!t)return I(e),t;let n=D(O(t,H,U,F),H,U,e);return I(e),n})},[F,a,H,U]),Q=(0,m.useMemo)(()=>a&&j?[{id:v,shape:{kind:`grid`,gridWidth:W,gridHeight:G,cells:[...j]}}]:[],[a,j,W,G]),$=(0,m.useCallback)((e,t)=>{t.kind===`grid`&&M(t.cells)},[]),re=(0,m.useCallback)(async()=>{if(!(!i||!j||!a)){R(!0);try{let e=O(j,a.grid.width,a.grid.height,F),t={kind:`grid`,gridWidth:a.grid.width,gridHeight:a.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:v,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=C(e?e.shape.cells:[],a.grid.width,a.grid.height);P(t),M(D(t,a.grid.width,a.grid.height,F))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{R(!1)}}},[i,j,a,F]);d((0,m.useMemo)(()=>z&&!k&&a&&j?{id:_,order:g,node:(0,h.jsx)(f,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:W,height:G},selectedId:v,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[z,k,a,j,Q,$,W,G]));let ie=!k&&a!==null&&j!==null;return i?(0,h.jsx)(u,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,h.jsx)(p,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsx)(`div`,{className:`flex flex-col gap-3`,children:k?(0,h.jsx)(`p`,{className:`${s} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${s} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.motionZones.intro`,fallback:`Toggle <0>Edit grid</0> to paint the region directly on the live frame, then <1>Save</1> to push the mask to the camera. Pick a bigger <2>Cell size</2> for quicker, broad-stroke painting — it's resampled to the camera's native {{width}}×{{height}} grid on save (×1 is the finest).`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`e`),(0,h.jsx)(`strong`,{className:`text-foreground`},`s`),(0,h.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:a.grid.width,height:a.grid.height}})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:()=>B(e=>!e),disabled:L,"aria-pressed":z,className:z?S:x,children:z?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!0),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!1),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,h.jsx)(`button`,{type:`button`,onClick:ee,disabled:L,className:x,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,h.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,h.jsx)(`span`,{className:`${s} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),y.map(e=>(0,h.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:L,"aria-pressed":F===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:H,height:U}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:T(H,e),height:T(U,e),factor:e}),className:F===e?S:x,children:[`×`,e]},e))]}),(0,h.jsxs)(`span`,{className:`${s} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:J,total:Y,width:a.grid.width,height:a.grid.height}),F===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:W,height:G})]}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:te,disabled:L||!q,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:n(`uiLibrary.motionZones.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:L||!q,className:S,children:L?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,h.jsx)(`p`,{className:`${s} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{k as MotionZonesSettings};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{C as ee,T as a,_ as te,c as o,d as ne,l as s,p as c,t as re,v as l,x as u,y as d}from"./index-DIZdNkiY.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=a(`hexagon`,[[`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`,key:`yt0hxn`}]]),oe=a(`mic-off`,[[`path`,{d:`M12 19v3`,key:`npa21l`}],[`path`,{d:`M15 9.34V5a3 3 0 0 0-5.68-1.33`,key:`1gzdoj`}],[`path`,{d:`M16.95 16.95A7 7 0 0 1 5 12v-2`,key:`cqa7eg`}],[`path`,{d:`M18.89 13.23A7 7 0 0 0 19 12v-2`,key:`16hl24`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M9 9v3a3 3 0 0 0 5.12 2.12`,key:`r2i35w`}]]),f=n(i(),1),p=`Microphone`,m=`The camera encodes no audio at all — live view, recordings, exports and the audio analyzer are all silent.`;function se(e){let t=e.supportsAudioMute===!0,n=t?e.audioEnabled:null,r=e.pendingOn??null;return{label:p,supported:t,on:n===null?null:r??n,available:t&&n!==null,costWhenOff:m}}function ce(e){return!e.available||e.on===null?null:{enabled:!e.on}}var h=n(e(),1),le=120,ue=`privacy-mask`,g=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,_=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function v(e){return e.kind===`rect`||e.kind===`polygon`?e:null}function de(e){let t=new Set(e.map(e=>e.id)),n=0;for(;t.has(n);)n+=1;return n}function fe(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(JSON.stringify(e[n])!==JSON.stringify(t[n]))return!1;return!0}function y({deviceId:e}){let n=t(),i=ne(te().trpcClient,e),[a,p]=(0,f.useState)(null),[m,y]=(0,f.useState)(!1),[b,x]=(0,f.useState)(!1),[S,C]=(0,f.useState)(null),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(!1),[O,k]=(0,f.useState)(!1),[A,j]=(0,f.useState)(null),[M,N]=(0,f.useState)(null),[pe,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(null),z=(0,f.useRef)(!1);(0,f.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,p(null),y(!1),x(!1),C(null),T(null),k(!1),j(null),N(null),P(null),I(null),R(null),(async()=>{try{let t=await i.privacyMask?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(p(t),z.current)return;let n=await i.privacyMask?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);if(n.regions===null){x(!0),P(n.audioEnabled);return}z.current=!0;let r={enabled:n.enabled,regions:n.regions};T(r),C(r),P(n.audioEnabled)}catch(t){if(e)return;s(t)?y(!0):console.error(`Privacy Mask load failed`,t)}})(),()=>{e=!0}},[i]);let B=(0,f.useMemo)(()=>S!==null&&w!==null&&(S.enabled!==w.enabled||!fe(S.regions,w.regions)),[S,w]),V=S?S.regions.length:0,H=a?a.maxRegions:0,U=(0,f.useRef)(0);(0,f.useEffect)(()=>{U.current=H},[H]);let W=H>0&&V>=H,me=(0,f.useCallback)(()=>{C(e=>e&&{...e,enabled:!e.enabled})},[]),G=(0,f.useCallback)(e=>{j(typeof e==`number`?e:null)},[]),K=(0,f.useMemo)(()=>S?S.regions.map(e=>({id:e.id,shape:e.shape,enabled:e.enabled,label:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})})):[],[S,n]),q=(0,f.useCallback)((e,t)=>{let n=v(t);n&&C(t=>t&&{...t,regions:t.regions.map(t=>t.id===e?{...t,shape:n}:t)})},[]),J=(0,f.useCallback)(e=>{let t=v(e);t&&(N(null),C(e=>{if(!e)return e;let n=U.current;if(n>0&&e.regions.length>=n)return e;let r=de(e.regions),i={id:r,enabled:!0,shape:t};return j(r),{...e,regions:[...e.regions,i]}}))},[]),Y=(0,f.useCallback)(e=>{k(!0),j(null),N(e)},[]),he=(0,f.useCallback)(e=>{k(!0),N(null),j(e)},[]),ge=(0,f.useCallback)(e=>{j(t=>t===e?null:t),C(t=>t&&{...t,regions:t.regions.filter(t=>t.id!==e)})},[]),_e=(0,f.useCallback)(()=>{N(null),j(null),w&&C({enabled:w.enabled,regions:w.regions})},[w]),X=(0,f.useCallback)(async()=>{if(!(!i||!S)){D(!0);try{await i.privacyMask?.setMask({patch:{enabled:S.enabled,regions:[...S.regions]}});let e=await i.privacyMask?.getStatus({});if(e&&e.regions!==null){let t={enabled:e.enabled,regions:e.regions};T(t),C(t)}}catch(e){console.error(`Privacy Mask save failed`,e)}finally{D(!1)}}},[i,S]),Z=se({supportsAudioMute:a===null?null:a.supportsAudioMute,audioEnabled:pe,pendingOn:F}),ve=(0,f.useCallback)(async()=>{let e=ce(Z);if(!(!i||e===null)){I(e.enabled),R(null);try{await i.privacyMask?.setAudioEnabled(e);let t=await i.privacyMask?.getStatus({});t&&P(t.audioEnabled)}catch(e){console.error(`Privacy microphone write failed — reverting`,e),R(e instanceof Error?e.message:String(e))}finally{I(null)}}},[i,Z]),ye=(0,f.useCallback)(()=>{k(e=>(e&&(N(null),j(null)),!e))},[]),Q=a?.supportedShapes??[];re((0,f.useMemo)(()=>O&&!m&&a&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:a.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,a,S,K,Q,A,G,q,J,M]));let be=a?.supportedShapes.includes(`rect`)??!1,xe=a?.supportedShapes.includes(`polygon`)??!1,$=a!==null&&(a.maxRegions<=0||a.supportedShapes.length===0),Se=!m&&!$&&!b&&a!==null&&S!==null;return i?(0,h.jsx)(c,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(ee,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[m||$?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unsupported`,`This camera doesn't support an on-board privacy mask.`)}):b?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unreadable`,`This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.`)}):Se?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.privacyMaskSettings.help`,fallback:`Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`edit`),(0,h.jsx)(`strong`,{className:`text-foreground`},`save`)]})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:ye,disabled:E,"aria-pressed":O,className:O?_:g,children:O?n(`uiLibrary.privacyMaskSettings.doneEditing`,`Done editing`):n(`uiLibrary.privacyMaskSettings.editMask`,`Edit mask`)}),(0,h.jsx)(`button`,{type:`button`,onClick:me,disabled:E,"aria-pressed":S.enabled,className:S.enabled?_:g,children:S.enabled?n(`uiLibrary.privacyMaskSettings.maskOn`,`Mask on`):n(`uiLibrary.privacyMaskSettings.maskOff`,`Mask off`)}),be&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`rect`),disabled:E||W,"aria-pressed":M===`rect`,className:M===`rect`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addRect`,`Add a rectangle zone`),children:n(`uiLibrary.privacyMaskSettings.rectButton`,`+ Rect`)}),xe&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`polygon`),disabled:E||W,"aria-pressed":M===`polygon`,className:M===`polygon`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addPolygon`,`Add a polygon zone`),children:n(`uiLibrary.privacyMaskSettings.polygonButton`,`+ Polygon`)}),(0,h.jsx)(`span`,{className:`${o} ml-1 tabular-nums`,children:n(`uiLibrary.privacyMaskSettings.zoneCount`,`{{active}} / {{max}} zones`,{active:V,max:H})}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:_e,disabled:E||!B,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:n(`uiLibrary.privacyMaskSettings.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void X(),disabled:E||!B,className:_,children:E?n(`uiLibrary.privacyMaskSettings.saving`,`Saving…`):n(`uiLibrary.privacyMaskSettings.save`,`Save`)})]}),V>0?(0,h.jsx)(`div`,{className:`flex flex-col gap-1`,children:S.regions.map(e=>{let t=A===e.id,r=e.shape.kind===`polygon`?ae:d;return(0,h.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t?`border-primary/50 bg-primary/10`:`border-border bg-surface`}`,children:[(0,h.jsxs)(`button`,{type:`button`,onClick:()=>he(e.id),disabled:E,className:`flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors`,children:[(0,h.jsx)(r,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})}),(0,h.jsx)(`span`,{className:`text-foreground-faint capitalize`,children:e.shape.kind})]}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>ge(e.id),disabled:E,"aria-label":n(`uiLibrary.privacyMaskSettings.deleteZoneN`,`Delete zone {{id}}`,{id:e.id}),title:n(`uiLibrary.privacyMaskSettings.deleteZone`,`Delete zone`),className:`inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors`,children:(0,h.jsx)(l,{className:`h-3.5 w-3.5`})})]},e.id)})}):null]}):(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.loading`,`Loading the camera's privacy mask…`)}),Z.supported&&(0,h.jsxs)(`div`,{className:`flex items-start gap-3 rounded-md border border-border bg-surface px-2 py-2`,children:[(0,h.jsx)(`button`,{type:`button`,role:`switch`,"aria-label":Z.label,"aria-checked":Z.on===!0,disabled:!Z.available||F!==null,onClick:()=>void ve(),title:Z.on===null?n(`uiLibrary.privacyMaskSettings.micTitleUnknown`,`Microphone — state unknown; the camera did not answer.`):Z.on?n(`uiLibrary.privacyMaskSettings.micTitleOn`,`The camera is capturing sound. Turning it off: {{cost}}`,{cost:Z.costWhenOff}):n(`uiLibrary.privacyMaskSettings.micTitleOff`,`The camera is silent. {{cost}}`,{cost:Z.costWhenOff}),className:Z.on===!1||Z.on===null?g:_,children:(0,h.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[Z.on===!1?(0,h.jsx)(oe,{className:`h-3.5 w-3.5`}):(0,h.jsx)(u,{className:`h-3.5 w-3.5`}),Z.on===null?n(`uiLibrary.privacyMaskSettings.micUnknown`,`Microphone unknown`):Z.on?n(`uiLibrary.privacyMaskSettings.micOn`,`Microphone on`):n(`uiLibrary.privacyMaskSettings.micOff`,`Microphone off`)]})}),(0,h.jsx)(`p`,{className:`text-[10px] text-foreground-subtle flex-1 leading-relaxed`,children:L===null?Z.on===null?n(`uiLibrary.privacyMaskSettings.micNotReported`,`The camera did not report its microphone, so this state is unknown.`):Z.costWhenOff:n(`uiLibrary.privacyMaskSettings.writeFailed`,`Write failed: {{reason}}`,{reason:L})})]})]})}):null}export{y as PrivacyMaskSettings};
|
|
1
|
+
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{C as ee,T as a,_ as te,c as o,d as ne,l as s,p as c,t as re,v as l,x as u,y as d}from"./index-BePyQ_Ek.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=a(`hexagon`,[[`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`,key:`yt0hxn`}]]),oe=a(`mic-off`,[[`path`,{d:`M12 19v3`,key:`npa21l`}],[`path`,{d:`M15 9.34V5a3 3 0 0 0-5.68-1.33`,key:`1gzdoj`}],[`path`,{d:`M16.95 16.95A7 7 0 0 1 5 12v-2`,key:`cqa7eg`}],[`path`,{d:`M18.89 13.23A7 7 0 0 0 19 12v-2`,key:`16hl24`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M9 9v3a3 3 0 0 0 5.12 2.12`,key:`r2i35w`}]]),f=n(i(),1),p=`Microphone`,m=`The camera encodes no audio at all — live view, recordings, exports and the audio analyzer are all silent.`;function se(e){let t=e.supportsAudioMute===!0,n=t?e.audioEnabled:null,r=e.pendingOn??null;return{label:p,supported:t,on:n===null?null:r??n,available:t&&n!==null,costWhenOff:m}}function ce(e){return!e.available||e.on===null?null:{enabled:!e.on}}var h=n(e(),1),le=120,ue=`privacy-mask`,g=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,_=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function v(e){return e.kind===`rect`||e.kind===`polygon`?e:null}function de(e){let t=new Set(e.map(e=>e.id)),n=0;for(;t.has(n);)n+=1;return n}function fe(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(JSON.stringify(e[n])!==JSON.stringify(t[n]))return!1;return!0}function y({deviceId:e}){let n=t(),i=ne(te().trpcClient,e),[a,p]=(0,f.useState)(null),[m,y]=(0,f.useState)(!1),[b,x]=(0,f.useState)(!1),[S,C]=(0,f.useState)(null),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(!1),[O,k]=(0,f.useState)(!1),[A,j]=(0,f.useState)(null),[M,N]=(0,f.useState)(null),[pe,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(null),z=(0,f.useRef)(!1);(0,f.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,p(null),y(!1),x(!1),C(null),T(null),k(!1),j(null),N(null),P(null),I(null),R(null),(async()=>{try{let t=await i.privacyMask?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(p(t),z.current)return;let n=await i.privacyMask?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);if(n.regions===null){x(!0),P(n.audioEnabled);return}z.current=!0;let r={enabled:n.enabled,regions:n.regions};T(r),C(r),P(n.audioEnabled)}catch(t){if(e)return;s(t)?y(!0):console.error(`Privacy Mask load failed`,t)}})(),()=>{e=!0}},[i]);let B=(0,f.useMemo)(()=>S!==null&&w!==null&&(S.enabled!==w.enabled||!fe(S.regions,w.regions)),[S,w]),V=S?S.regions.length:0,H=a?a.maxRegions:0,U=(0,f.useRef)(0);(0,f.useEffect)(()=>{U.current=H},[H]);let W=H>0&&V>=H,me=(0,f.useCallback)(()=>{C(e=>e&&{...e,enabled:!e.enabled})},[]),G=(0,f.useCallback)(e=>{j(typeof e==`number`?e:null)},[]),K=(0,f.useMemo)(()=>S?S.regions.map(e=>({id:e.id,shape:e.shape,enabled:e.enabled,label:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})})):[],[S,n]),q=(0,f.useCallback)((e,t)=>{let n=v(t);n&&C(t=>t&&{...t,regions:t.regions.map(t=>t.id===e?{...t,shape:n}:t)})},[]),J=(0,f.useCallback)(e=>{let t=v(e);t&&(N(null),C(e=>{if(!e)return e;let n=U.current;if(n>0&&e.regions.length>=n)return e;let r=de(e.regions),i={id:r,enabled:!0,shape:t};return j(r),{...e,regions:[...e.regions,i]}}))},[]),Y=(0,f.useCallback)(e=>{k(!0),j(null),N(e)},[]),he=(0,f.useCallback)(e=>{k(!0),N(null),j(e)},[]),ge=(0,f.useCallback)(e=>{j(t=>t===e?null:t),C(t=>t&&{...t,regions:t.regions.filter(t=>t.id!==e)})},[]),_e=(0,f.useCallback)(()=>{N(null),j(null),w&&C({enabled:w.enabled,regions:w.regions})},[w]),X=(0,f.useCallback)(async()=>{if(!(!i||!S)){D(!0);try{await i.privacyMask?.setMask({patch:{enabled:S.enabled,regions:[...S.regions]}});let e=await i.privacyMask?.getStatus({});if(e&&e.regions!==null){let t={enabled:e.enabled,regions:e.regions};T(t),C(t)}}catch(e){console.error(`Privacy Mask save failed`,e)}finally{D(!1)}}},[i,S]),Z=se({supportsAudioMute:a===null?null:a.supportsAudioMute,audioEnabled:pe,pendingOn:F}),ve=(0,f.useCallback)(async()=>{let e=ce(Z);if(!(!i||e===null)){I(e.enabled),R(null);try{await i.privacyMask?.setAudioEnabled(e);let t=await i.privacyMask?.getStatus({});t&&P(t.audioEnabled)}catch(e){console.error(`Privacy microphone write failed — reverting`,e),R(e instanceof Error?e.message:String(e))}finally{I(null)}}},[i,Z]),ye=(0,f.useCallback)(()=>{k(e=>(e&&(N(null),j(null)),!e))},[]),Q=a?.supportedShapes??[];re((0,f.useMemo)(()=>O&&!m&&a&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:a.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,a,S,K,Q,A,G,q,J,M]));let be=a?.supportedShapes.includes(`rect`)??!1,xe=a?.supportedShapes.includes(`polygon`)??!1,$=a!==null&&(a.maxRegions<=0||a.supportedShapes.length===0),Se=!m&&!$&&!b&&a!==null&&S!==null;return i?(0,h.jsx)(c,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(ee,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[m||$?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unsupported`,`This camera doesn't support an on-board privacy mask.`)}):b?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unreadable`,`This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.`)}):Se?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.privacyMaskSettings.help`,fallback:`Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`edit`),(0,h.jsx)(`strong`,{className:`text-foreground`},`save`)]})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:ye,disabled:E,"aria-pressed":O,className:O?_:g,children:O?n(`uiLibrary.privacyMaskSettings.doneEditing`,`Done editing`):n(`uiLibrary.privacyMaskSettings.editMask`,`Edit mask`)}),(0,h.jsx)(`button`,{type:`button`,onClick:me,disabled:E,"aria-pressed":S.enabled,className:S.enabled?_:g,children:S.enabled?n(`uiLibrary.privacyMaskSettings.maskOn`,`Mask on`):n(`uiLibrary.privacyMaskSettings.maskOff`,`Mask off`)}),be&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`rect`),disabled:E||W,"aria-pressed":M===`rect`,className:M===`rect`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addRect`,`Add a rectangle zone`),children:n(`uiLibrary.privacyMaskSettings.rectButton`,`+ Rect`)}),xe&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`polygon`),disabled:E||W,"aria-pressed":M===`polygon`,className:M===`polygon`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addPolygon`,`Add a polygon zone`),children:n(`uiLibrary.privacyMaskSettings.polygonButton`,`+ Polygon`)}),(0,h.jsx)(`span`,{className:`${o} ml-1 tabular-nums`,children:n(`uiLibrary.privacyMaskSettings.zoneCount`,`{{active}} / {{max}} zones`,{active:V,max:H})}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:_e,disabled:E||!B,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:n(`uiLibrary.privacyMaskSettings.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void X(),disabled:E||!B,className:_,children:E?n(`uiLibrary.privacyMaskSettings.saving`,`Saving…`):n(`uiLibrary.privacyMaskSettings.save`,`Save`)})]}),V>0?(0,h.jsx)(`div`,{className:`flex flex-col gap-1`,children:S.regions.map(e=>{let t=A===e.id,r=e.shape.kind===`polygon`?ae:d;return(0,h.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t?`border-primary/50 bg-primary/10`:`border-border bg-surface`}`,children:[(0,h.jsxs)(`button`,{type:`button`,onClick:()=>he(e.id),disabled:E,className:`flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors`,children:[(0,h.jsx)(r,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})}),(0,h.jsx)(`span`,{className:`text-foreground-faint capitalize`,children:e.shape.kind})]}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>ge(e.id),disabled:E,"aria-label":n(`uiLibrary.privacyMaskSettings.deleteZoneN`,`Delete zone {{id}}`,{id:e.id}),title:n(`uiLibrary.privacyMaskSettings.deleteZone`,`Delete zone`),className:`inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors`,children:(0,h.jsx)(l,{className:`h-3.5 w-3.5`})})]},e.id)})}):null]}):(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.loading`,`Loading the camera's privacy mask…`)}),Z.supported&&(0,h.jsxs)(`div`,{className:`flex items-start gap-3 rounded-md border border-border bg-surface px-2 py-2`,children:[(0,h.jsx)(`button`,{type:`button`,role:`switch`,"aria-label":Z.label,"aria-checked":Z.on===!0,disabled:!Z.available||F!==null,onClick:()=>void ve(),title:Z.on===null?n(`uiLibrary.privacyMaskSettings.micTitleUnknown`,`Microphone — state unknown; the camera did not answer.`):Z.on?n(`uiLibrary.privacyMaskSettings.micTitleOn`,`The camera is capturing sound. Turning it off: {{cost}}`,{cost:Z.costWhenOff}):n(`uiLibrary.privacyMaskSettings.micTitleOff`,`The camera is silent. {{cost}}`,{cost:Z.costWhenOff}),className:Z.on===!1||Z.on===null?g:_,children:(0,h.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[Z.on===!1?(0,h.jsx)(oe,{className:`h-3.5 w-3.5`}):(0,h.jsx)(u,{className:`h-3.5 w-3.5`}),Z.on===null?n(`uiLibrary.privacyMaskSettings.micUnknown`,`Microphone unknown`):Z.on?n(`uiLibrary.privacyMaskSettings.micOn`,`Microphone on`):n(`uiLibrary.privacyMaskSettings.micOff`,`Microphone off`)]})}),(0,h.jsx)(`p`,{className:`text-[10px] text-foreground-subtle flex-1 leading-relaxed`,children:L===null?Z.on===null?n(`uiLibrary.privacyMaskSettings.micNotReported`,`The camera did not report its microphone, so this state is unknown.`):Z.costWhenOff:n(`uiLibrary.privacyMaskSettings.writeFailed`,`Write failed: {{reason}}`,{reason:L})})]})]})}):null}export{y as PrivacyMaskSettings};
|