@camstack/addon-pipeline 0.1.17 → 0.1.19
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/dist/audio-analyzer/index.js +8 -3
- package/dist/audio-analyzer/index.js.map +1 -1
- package/dist/audio-analyzer/index.mjs +8 -3
- package/dist/audio-analyzer/index.mjs.map +1 -1
- package/dist/audio-codec-nodeav/index.js +1 -1
- package/dist/audio-codec-nodeav/index.mjs +1 -1
- package/dist/decoder-nodeav/index.js +1 -1
- package/dist/decoder-nodeav/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +23 -20
- package/dist/detection-pipeline/index.js.map +1 -1
- package/dist/detection-pipeline/index.mjs +23 -20
- package/dist/detection-pipeline/index.mjs.map +1 -1
- package/dist/{index-p-6GfKOg.js → index-BbPPvoCx.js} +469 -57
- package/dist/index-BbPPvoCx.js.map +1 -0
- package/dist/{index-CVzLrojg.mjs → index-Bmlkm0Fd.mjs} +469 -57
- package/dist/index-Bmlkm0Fd.mjs.map +1 -0
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +132 -14
- package/dist/pipeline-runner/index.js.map +1 -1
- package/dist/pipeline-runner/index.mjs +133 -15
- package/dist/pipeline-runner/index.mjs.map +1 -1
- package/dist/stream-broker/@mf-types.zip +0 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-NjF4kxzW.mjs +19 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BAv_5ISf.mjs +20 -0
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-DAssX3h0.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-BsB2G7oY.mjs} +2 -1
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-DFoJJhpt.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-xrRiPUpA.mjs} +1 -1
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-x7XMEeuJ.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-C0E2yCzO.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Sx8tgpFZ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CupRlwqG.mjs} +6 -6
- package/dist/stream-broker/{client-CZXrddDR.mjs → client-NPZqorv9.mjs} +2 -2
- package/dist/stream-broker/{hostInit-D0jPgChu.mjs → hostInit-Bh4w7o5_.mjs} +12 -12
- package/dist/stream-broker/{index-C0BzaWmB.mjs → index-2Qp8vT3w.mjs} +1 -1
- package/dist/stream-broker/{index-CZNxa0ad.mjs → index-BBcZvb5t.mjs} +1 -1
- package/dist/stream-broker/index-CIJue-4t.mjs +37880 -0
- package/dist/stream-broker/{index-BvV3RVTZ.mjs → index-Cc6QBqMk.mjs} +2 -2
- package/dist/stream-broker/{index-cYW01SNH.mjs → index-D_1p2K9B.mjs} +1 -1
- package/dist/stream-broker/{index-BCEx31Mh.mjs → index-Dy2V7VOm.mjs} +3808 -3277
- package/dist/stream-broker/{index-KtR7Pp0O.mjs → index-mX3Kgiv1.mjs} +1 -1
- package/dist/stream-broker/index.js +1565 -280
- package/dist/stream-broker/index.js.map +1 -1
- package/dist/stream-broker/index.mjs +1567 -281
- package/dist/stream-broker/index.mjs.map +1 -1
- package/dist/stream-broker/{jsx-runtime-B_evVsXl.mjs → jsx-runtime-lb0mH5st.mjs} +1 -1
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/stream-broker/{schemas-ChN4Ih0h.mjs → schemas-ClCuS4qa.mjs} +151 -141
- package/package.json +1 -1
- package/dist/index-CVzLrojg.mjs.map +0 -1
- package/dist/index-p-6GfKOg.js.map +0 -1
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-d8PmLbO2.mjs +0 -19
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-B4l8Nb2y.mjs +0 -20
- package/dist/stream-broker/index-Kb4xa8FX.mjs +0 -36403
|
@@ -4779,6 +4779,16 @@ function record(keyType, valueType, params) {
|
|
|
4779
4779
|
...normalizeParams(params)
|
|
4780
4780
|
});
|
|
4781
4781
|
}
|
|
4782
|
+
function partialRecord(keyType, valueType, params) {
|
|
4783
|
+
const k = clone(keyType);
|
|
4784
|
+
k._zod.values = void 0;
|
|
4785
|
+
return new ZodRecord({
|
|
4786
|
+
type: "record",
|
|
4787
|
+
keyType: k,
|
|
4788
|
+
valueType,
|
|
4789
|
+
...normalizeParams(params)
|
|
4790
|
+
});
|
|
4791
|
+
}
|
|
4782
4792
|
const ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
|
|
4783
4793
|
$ZodEnum.init(inst, def);
|
|
4784
4794
|
ZodType.init(inst, def);
|
|
@@ -5055,6 +5065,37 @@ function _instanceof(cls, params = {}) {
|
|
|
5055
5065
|
};
|
|
5056
5066
|
return inst;
|
|
5057
5067
|
}
|
|
5068
|
+
const wiringProbeKindSchema = _enum(["singleton", "device", "widget"]);
|
|
5069
|
+
const wiringProbeResultSchema = object({
|
|
5070
|
+
capName: string(),
|
|
5071
|
+
kind: wiringProbeKindSchema,
|
|
5072
|
+
deviceId: number().optional(),
|
|
5073
|
+
reachable: boolean(),
|
|
5074
|
+
latencyMs: number(),
|
|
5075
|
+
error: string().optional()
|
|
5076
|
+
});
|
|
5077
|
+
const wiringAddonHealthSchema = object({
|
|
5078
|
+
addonId: string(),
|
|
5079
|
+
caps: array(wiringProbeResultSchema).readonly(),
|
|
5080
|
+
widgets: array(wiringProbeResultSchema).readonly()
|
|
5081
|
+
});
|
|
5082
|
+
const wiringNodeHealthSchema = object({
|
|
5083
|
+
nodeId: string(),
|
|
5084
|
+
addons: array(wiringAddonHealthSchema).readonly()
|
|
5085
|
+
});
|
|
5086
|
+
object({
|
|
5087
|
+
/** True only when every probed target is reachable. */
|
|
5088
|
+
ok: boolean(),
|
|
5089
|
+
/** True when at least one target is unreachable. */
|
|
5090
|
+
degraded: boolean(),
|
|
5091
|
+
checkedAt: string(),
|
|
5092
|
+
nodes: array(wiringNodeHealthSchema).readonly(),
|
|
5093
|
+
summary: object({
|
|
5094
|
+
total: number(),
|
|
5095
|
+
reachable: number(),
|
|
5096
|
+
unreachable: number()
|
|
5097
|
+
})
|
|
5098
|
+
});
|
|
5058
5099
|
const MODEL_FORMATS = ["onnx", "coreml", "openvino", "tflite", "pt"];
|
|
5059
5100
|
const WELL_KNOWN_TABS = [
|
|
5060
5101
|
{ id: "overview", label: "Overview", icon: "layout-dashboard", order: -10 },
|
|
@@ -6619,7 +6660,7 @@ const SpatialDetectionSchema = object({
|
|
|
6619
6660
|
bbox: BoundingBoxSchema
|
|
6620
6661
|
});
|
|
6621
6662
|
const AudioChunkInputSchema = object({
|
|
6622
|
-
data: _instanceof(
|
|
6663
|
+
data: _instanceof(Uint8Array),
|
|
6623
6664
|
sampleRate: number(),
|
|
6624
6665
|
channels: number(),
|
|
6625
6666
|
timestamp: number(),
|
|
@@ -7299,7 +7340,23 @@ const RunnerCameraConfigSchema = object({
|
|
|
7299
7340
|
* whenever its `zones` device-state slice changes, so the runner's
|
|
7300
7341
|
* copy stays in sync. Empty array → no zone filtering.
|
|
7301
7342
|
*/
|
|
7302
|
-
zones: array(ZoneSchema).readonly().default([])
|
|
7343
|
+
zones: array(ZoneSchema).readonly().default([]),
|
|
7344
|
+
/**
|
|
7345
|
+
* When true (default) and the camera's `motionSources` contains only
|
|
7346
|
+
* `'onboard'`, the runner dynamically opens the same WASM frame-diff
|
|
7347
|
+
* motion-frames subscription on each `MotionOnMotionChanged
|
|
7348
|
+
* source:'onboard'` event and tears it down after `motionCooldownMs`.
|
|
7349
|
+
* This causes `runMotionAnalysis` to emit `MotionZonesRaw` /
|
|
7350
|
+
* `MotionAnalysis` during active-motion windows without the
|
|
7351
|
+
* substream being held open continuously.
|
|
7352
|
+
*
|
|
7353
|
+
* Set to `false` to disable the dynamic analyzer for this camera
|
|
7354
|
+
* (e.g. very low-bandwidth links where the extra substream is
|
|
7355
|
+
* undesirable). Has no effect when `motionSources` already includes
|
|
7356
|
+
* `'analyzer'` — the analyzer runs continuously in that case and
|
|
7357
|
+
* this gate is bypassed.
|
|
7358
|
+
*/
|
|
7359
|
+
onboardMotionDrivesAnalyzer: boolean().default(true)
|
|
7303
7360
|
});
|
|
7304
7361
|
const RunnerLocalLoadSchema = object({
|
|
7305
7362
|
/** Moleculer node id of this runner instance. */
|
|
@@ -7439,22 +7496,68 @@ MotionTriggerStatusSchema.extend({
|
|
|
7439
7496
|
}) }
|
|
7440
7497
|
}
|
|
7441
7498
|
});
|
|
7499
|
+
const MaskPointSchema = object({
|
|
7500
|
+
x: number(),
|
|
7501
|
+
y: number()
|
|
7502
|
+
});
|
|
7503
|
+
const MaskRectShapeSchema = object({
|
|
7504
|
+
kind: literal("rect"),
|
|
7505
|
+
x: number(),
|
|
7506
|
+
y: number(),
|
|
7507
|
+
width: number(),
|
|
7508
|
+
height: number()
|
|
7509
|
+
});
|
|
7510
|
+
const MaskPolygonShapeSchema = object({
|
|
7511
|
+
kind: literal("polygon"),
|
|
7512
|
+
points: array(MaskPointSchema)
|
|
7513
|
+
});
|
|
7514
|
+
const MaskGridShapeSchema = object({
|
|
7515
|
+
kind: literal("grid"),
|
|
7516
|
+
gridWidth: number(),
|
|
7517
|
+
gridHeight: number(),
|
|
7518
|
+
cells: array(boolean())
|
|
7519
|
+
});
|
|
7520
|
+
const MaskLineShapeSchema = object({
|
|
7521
|
+
kind: literal("line"),
|
|
7522
|
+
points: array(MaskPointSchema)
|
|
7523
|
+
});
|
|
7524
|
+
discriminatedUnion("kind", [
|
|
7525
|
+
MaskRectShapeSchema,
|
|
7526
|
+
MaskPolygonShapeSchema,
|
|
7527
|
+
MaskGridShapeSchema,
|
|
7528
|
+
MaskLineShapeSchema
|
|
7529
|
+
]);
|
|
7530
|
+
const MaskShapeKindSchema = _enum(["rect", "polygon", "grid", "line"]);
|
|
7531
|
+
const MaskPolygonVerticesSchema = object({
|
|
7532
|
+
min: number(),
|
|
7533
|
+
max: number()
|
|
7534
|
+
});
|
|
7535
|
+
const MaskGridDimsSchema = object({
|
|
7536
|
+
width: number(),
|
|
7537
|
+
height: number()
|
|
7538
|
+
});
|
|
7539
|
+
const MotionZoneRegionSchema = object({
|
|
7540
|
+
id: number(),
|
|
7541
|
+
enabled: boolean(),
|
|
7542
|
+
shape: MaskGridShapeSchema
|
|
7543
|
+
});
|
|
7442
7544
|
object({
|
|
7443
7545
|
enabled: boolean(),
|
|
7444
7546
|
sensitivity: number(),
|
|
7445
|
-
/**
|
|
7446
|
-
|
|
7547
|
+
/** Grid region(s). Today exactly one `grid` shape. */
|
|
7548
|
+
regions: array(MotionZoneRegionSchema),
|
|
7447
7549
|
lastFetchedAt: number()
|
|
7448
7550
|
});
|
|
7449
7551
|
const MotionZoneOptionsSchema = object({
|
|
7450
|
-
|
|
7451
|
-
|
|
7552
|
+
maxRegions: number(),
|
|
7553
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7554
|
+
grid: MaskGridDimsSchema,
|
|
7452
7555
|
sensitivity: object({ min: number(), max: number(), step: number() })
|
|
7453
7556
|
});
|
|
7454
7557
|
const MotionZonePatchSchema = object({
|
|
7455
7558
|
enabled: boolean().optional(),
|
|
7456
7559
|
sensitivity: number().optional(),
|
|
7457
|
-
|
|
7560
|
+
regions: array(MotionZoneRegionSchema).optional()
|
|
7458
7561
|
});
|
|
7459
7562
|
({
|
|
7460
7563
|
deviceTypes: [DeviceType.Camera],
|
|
@@ -7467,6 +7570,102 @@ const MotionZonePatchSchema = object({
|
|
|
7467
7570
|
)
|
|
7468
7571
|
}
|
|
7469
7572
|
});
|
|
7573
|
+
const NativeObjectClassEnum = _enum([
|
|
7574
|
+
"person",
|
|
7575
|
+
"vehicle",
|
|
7576
|
+
"animal",
|
|
7577
|
+
"face",
|
|
7578
|
+
"package",
|
|
7579
|
+
"other"
|
|
7580
|
+
]);
|
|
7581
|
+
const NativeDetectionSchema = object({
|
|
7582
|
+
class: NativeObjectClassEnum,
|
|
7583
|
+
timestamp: number(),
|
|
7584
|
+
/** Firmware-provided confidence [0..1]. Reolink pushes don't carry it → undefined. */
|
|
7585
|
+
confidence: number().min(0).max(1).optional()
|
|
7586
|
+
});
|
|
7587
|
+
const NativeObjectDetectionStatusSchema = object({
|
|
7588
|
+
/**
|
|
7589
|
+
* Last observed instance per class. Missing entries mean the class
|
|
7590
|
+
* is supported but nothing has been seen since the provider started.
|
|
7591
|
+
*
|
|
7592
|
+
* MUST be a partial record: providers seed an empty `{}` on cold-start
|
|
7593
|
+
* and write one class at a time as detections arrive. In Zod 4
|
|
7594
|
+
* `z.record(enum, …)` is EXHAUSTIVE (requires every enum key), so a
|
|
7595
|
+
* partial write throws "expected object, received undefined" for every
|
|
7596
|
+
* unseen class. `z.partialRecord` keeps the enum-key narrowing while
|
|
7597
|
+
* allowing the sparse shape the providers actually write.
|
|
7598
|
+
*/
|
|
7599
|
+
lastByClass: partialRecord(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
7600
|
+
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
7601
|
+
supportedClasses: array(NativeObjectClassEnum).readonly(),
|
|
7602
|
+
/**
|
|
7603
|
+
* Whether forwarding of onboard AI detections is enabled for this device.
|
|
7604
|
+
* Default true (on cold-start) — detections flow unconditionally before
|
|
7605
|
+
* the toggle is saved, so defaulting true preserves existing behaviour.
|
|
7606
|
+
*/
|
|
7607
|
+
enabled: boolean()
|
|
7608
|
+
});
|
|
7609
|
+
NativeObjectDetectionStatusSchema.extend({
|
|
7610
|
+
/** Required by createRuntimeStateBridge — epoch ms of last refresh. */
|
|
7611
|
+
lastFetchedAt: number()
|
|
7612
|
+
});
|
|
7613
|
+
({
|
|
7614
|
+
deviceTypes: [DeviceType.Camera],
|
|
7615
|
+
methods: {
|
|
7616
|
+
setEnabled: method(
|
|
7617
|
+
object({ deviceId: number(), enabled: boolean() }),
|
|
7618
|
+
_void(),
|
|
7619
|
+
{ kind: "mutation", auth: "admin" }
|
|
7620
|
+
)
|
|
7621
|
+
},
|
|
7622
|
+
events: {
|
|
7623
|
+
onDetected: { data: object({
|
|
7624
|
+
deviceId: number(),
|
|
7625
|
+
detection: NativeDetectionSchema
|
|
7626
|
+
}) }
|
|
7627
|
+
}
|
|
7628
|
+
});
|
|
7629
|
+
const PrivacyMaskShapeSchema = discriminatedUnion("kind", [
|
|
7630
|
+
MaskRectShapeSchema,
|
|
7631
|
+
MaskPolygonShapeSchema
|
|
7632
|
+
]);
|
|
7633
|
+
const PrivacyMaskRegionSchema = object({
|
|
7634
|
+
/** Slot id, 0-based. Stable across read/write. */
|
|
7635
|
+
id: number(),
|
|
7636
|
+
/** Whether this zone is active (blanked out by the camera). */
|
|
7637
|
+
enabled: boolean(),
|
|
7638
|
+
shape: PrivacyMaskShapeSchema
|
|
7639
|
+
});
|
|
7640
|
+
object({
|
|
7641
|
+
enabled: boolean(),
|
|
7642
|
+
/** Active zones (normalized 0..1). Length ≤ maxRegions. */
|
|
7643
|
+
regions: array(PrivacyMaskRegionSchema),
|
|
7644
|
+
lastFetchedAt: number()
|
|
7645
|
+
});
|
|
7646
|
+
const PrivacyMaskOptionsSchema = object({
|
|
7647
|
+
/** Maximum number of supported zones. */
|
|
7648
|
+
maxRegions: number(),
|
|
7649
|
+
/** Shape kinds this camera accepts — Reolink: ['rect']; Hikvision: ['rect','polygon']. */
|
|
7650
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7651
|
+
/** Polygon vertex bounds when 'polygon' is supported (Hikvision: {min:4,max:4}). */
|
|
7652
|
+
polygonVertices: MaskPolygonVerticesSchema.optional()
|
|
7653
|
+
});
|
|
7654
|
+
const PrivacyMaskPatchSchema = object({
|
|
7655
|
+
enabled: boolean().optional(),
|
|
7656
|
+
regions: array(PrivacyMaskRegionSchema).optional()
|
|
7657
|
+
});
|
|
7658
|
+
({
|
|
7659
|
+
deviceTypes: [DeviceType.Camera],
|
|
7660
|
+
methods: {
|
|
7661
|
+
getOptions: method(object({ deviceId: number() }), PrivacyMaskOptionsSchema),
|
|
7662
|
+
setMask: method(
|
|
7663
|
+
object({ deviceId: number(), patch: PrivacyMaskPatchSchema }),
|
|
7664
|
+
_void(),
|
|
7665
|
+
{ kind: "mutation", auth: "admin" }
|
|
7666
|
+
)
|
|
7667
|
+
}
|
|
7668
|
+
});
|
|
7470
7669
|
const AutotrackTargetTypeSchema = string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
7471
7670
|
const PtzAutotrackSettingsSchema = object({
|
|
7472
7671
|
targetType: AutotrackTargetTypeSchema,
|
|
@@ -7985,7 +8184,8 @@ const SettingsUpdateResultSchema = object({
|
|
|
7985
8184
|
object({
|
|
7986
8185
|
addonId: string(),
|
|
7987
8186
|
nodeId: string().optional(),
|
|
7988
|
-
overlay: record(string(), unknown()).optional()
|
|
8187
|
+
overlay: record(string(), unknown()).optional(),
|
|
8188
|
+
cap: string().optional()
|
|
7989
8189
|
}),
|
|
7990
8190
|
SettingsSchemaWithValuesSchema.nullable()
|
|
7991
8191
|
),
|
|
@@ -8716,7 +8916,14 @@ const OauthIntegrationDescriptorSchema = object({
|
|
|
8716
8916
|
/** Allowed redirect_uri prefixes. /api/oauth2/authorize rejects any
|
|
8717
8917
|
* redirect_uri that does not start with one of these. Required —
|
|
8718
8918
|
* an empty list means the integration can never complete linking. */
|
|
8719
|
-
allowedRedirectPrefixes: array(string()).min(1)
|
|
8919
|
+
allowedRedirectPrefixes: array(string()).min(1),
|
|
8920
|
+
/** Optional public origin (no trailing slash) that this integration's
|
|
8921
|
+
* issued codes/tokens should carry as the `hubUrl` claim — typically the
|
|
8922
|
+
* operator-selected external-access endpoint resolved by the addon. When
|
|
8923
|
+
* present, /api/oauth2/authorize bakes THIS into the code instead of the
|
|
8924
|
+
* hub-global `publicHubUrl()`, so a forked exporter addon (which can't set
|
|
8925
|
+
* the hub's env) drives the claim that its cloud Lambda routes back on. */
|
|
8926
|
+
hubUrl: string().optional()
|
|
8720
8927
|
});
|
|
8721
8928
|
({
|
|
8722
8929
|
methods: {
|
|
@@ -9366,7 +9573,20 @@ const webrtcSessionCapability = {
|
|
|
9366
9573
|
object({
|
|
9367
9574
|
deviceId: number().int().nonnegative(),
|
|
9368
9575
|
target: WebrtcStreamTargetSchema,
|
|
9369
|
-
hints: webrtcClientHintsSchema.optional()
|
|
9576
|
+
hints: webrtcClientHintsSchema.optional(),
|
|
9577
|
+
/**
|
|
9578
|
+
* SERVER-INJECTED — NOT a client hint. The hub layer that holds
|
|
9579
|
+
* the tRPC request context (and therefore the client IP) sets
|
|
9580
|
+
* this to `true` when the viewer's source IP is non-LAN
|
|
9581
|
+
* (4G/CGNAT/internet). The broker then forces TURN-relay-only
|
|
9582
|
+
* ICE for the session so a CGNAT client (which can only offer a
|
|
9583
|
+
* relay candidate) gets a clean relay↔relay media path instead
|
|
9584
|
+
* of werift nominating a dead host/hairpin-srflx pair. LAN
|
|
9585
|
+
* clients leave this absent/false and keep the low-latency
|
|
9586
|
+
* direct (host/srflx) path. Clients MUST NOT send this — the
|
|
9587
|
+
* server overwrites it from the request context.
|
|
9588
|
+
*/
|
|
9589
|
+
relayOnly: boolean().optional()
|
|
9370
9590
|
}),
|
|
9371
9591
|
object({ sessionId: string(), sdpOffer: string() }),
|
|
9372
9592
|
{ kind: "mutation" }
|
|
@@ -9389,7 +9609,22 @@ const webrtcSessionCapability = {
|
|
|
9389
9609
|
deviceId: number().int().nonnegative(),
|
|
9390
9610
|
target: WebrtcStreamTargetSchema.optional(),
|
|
9391
9611
|
sdpOffer: string(),
|
|
9392
|
-
sessionId: string().optional()
|
|
9612
|
+
sessionId: string().optional(),
|
|
9613
|
+
/**
|
|
9614
|
+
* Force TURN-relay-only ICE for this session. Two kinds of caller
|
|
9615
|
+
* set it:
|
|
9616
|
+
* - A cloud peer like Alexa's RTCSessionController (reachable
|
|
9617
|
+
* only via TURN, never our host/srflx behind NAT) passes
|
|
9618
|
+
* `true` from its own trusted addon context.
|
|
9619
|
+
* - The hub injects it for browser client-offer viewers from the
|
|
9620
|
+
* request's source IP (non-LAN ⇒ true), exactly as it does for
|
|
9621
|
+
* `createSession`.
|
|
9622
|
+
* A LAN/Tailscale browser doing client-offer passthrough leaves it
|
|
9623
|
+
* absent/false so a direct host pair carries full native quality.
|
|
9624
|
+
* Untrusted browser clients MUST NOT send it — the hub overwrites
|
|
9625
|
+
* it from the request context.
|
|
9626
|
+
*/
|
|
9627
|
+
relayOnly: boolean().optional()
|
|
9393
9628
|
}),
|
|
9394
9629
|
object({ sessionId: string(), sdpAnswer: string() }),
|
|
9395
9630
|
{ kind: "mutation" }
|
|
@@ -9403,6 +9638,46 @@ const webrtcSessionCapability = {
|
|
|
9403
9638
|
_void(),
|
|
9404
9639
|
{ kind: "mutation" }
|
|
9405
9640
|
),
|
|
9641
|
+
/**
|
|
9642
|
+
* Trickle ICE — add a remote (client) ICE candidate to a live session.
|
|
9643
|
+
* Lets the client send its SDP offer/answer IMMEDIATELY (before ICE
|
|
9644
|
+
* gathering finishes) and deliver candidates as they arrive, so the
|
|
9645
|
+
* connection establishes in ~0s instead of waiting for full gathering.
|
|
9646
|
+
* The dual of `getIceCandidates`. Mirrors Scrypted's signaling.
|
|
9647
|
+
*/
|
|
9648
|
+
addIceCandidate: method(
|
|
9649
|
+
object({
|
|
9650
|
+
deviceId: number().int().nonnegative(),
|
|
9651
|
+
sessionId: string(),
|
|
9652
|
+
candidate: string(),
|
|
9653
|
+
sdpMid: string().nullable().optional(),
|
|
9654
|
+
sdpMLineIndex: number().int().nullable().optional()
|
|
9655
|
+
}),
|
|
9656
|
+
_void(),
|
|
9657
|
+
{ kind: "mutation" }
|
|
9658
|
+
),
|
|
9659
|
+
/**
|
|
9660
|
+
* Trickle ICE — poll the server's gathered ICE candidates for a session.
|
|
9661
|
+
* The server answers immediately (no gathering wait) and the client polls
|
|
9662
|
+
* this to receive host/srflx/relay candidates as werift gathers them,
|
|
9663
|
+
* adding each to its PeerConnection. Returns all candidates gathered so
|
|
9664
|
+
* far; the client dedupes. `done` flips true once gathering completes.
|
|
9665
|
+
*/
|
|
9666
|
+
getIceCandidates: method(
|
|
9667
|
+
object({
|
|
9668
|
+
deviceId: number().int().nonnegative(),
|
|
9669
|
+
sessionId: string()
|
|
9670
|
+
}),
|
|
9671
|
+
object({
|
|
9672
|
+
candidates: array(object({
|
|
9673
|
+
candidate: string(),
|
|
9674
|
+
sdpMid: string().nullable(),
|
|
9675
|
+
sdpMLineIndex: number().int().nullable()
|
|
9676
|
+
})),
|
|
9677
|
+
done: boolean()
|
|
9678
|
+
}),
|
|
9679
|
+
{ kind: "query" }
|
|
9680
|
+
),
|
|
9406
9681
|
closeSession: method(
|
|
9407
9682
|
object({
|
|
9408
9683
|
deviceId: number().int().nonnegative(),
|
|
@@ -11103,6 +11378,9 @@ const detectionPipelineCapability = {
|
|
|
11103
11378
|
exposesDeviceSettings: true,
|
|
11104
11379
|
methods: {}
|
|
11105
11380
|
};
|
|
11381
|
+
({
|
|
11382
|
+
deviceTypes: [DeviceType.Camera]
|
|
11383
|
+
});
|
|
11106
11384
|
const TrackStateSchema = _enum(["new", "entered", "left", "moving", "idle"]);
|
|
11107
11385
|
const EventKindSchema = _enum(["motion", "object", "audio"]);
|
|
11108
11386
|
const TrackPositionSchema = object({
|
|
@@ -11930,36 +12208,28 @@ const IntercomStatusSchema = object({
|
|
|
11930
12208
|
}) }
|
|
11931
12209
|
}
|
|
11932
12210
|
});
|
|
11933
|
-
const
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
object({
|
|
11948
|
-
/**
|
|
11949
|
-
* Last observed instance per class. Undefined entries mean the class
|
|
11950
|
-
* is supported but nothing has been seen since the provider started.
|
|
11951
|
-
*/
|
|
11952
|
-
lastByClass: record(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
11953
|
-
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
11954
|
-
supportedClasses: array(NativeObjectClassEnum).readonly()
|
|
12211
|
+
const CamStreamDescriptorSchema = object({
|
|
12212
|
+
camStreamId: string().min(1),
|
|
12213
|
+
kind: CamStreamKindSchema,
|
|
12214
|
+
url: string().optional(),
|
|
12215
|
+
codec: string().optional(),
|
|
12216
|
+
resolution: CamStreamResolutionSchema.optional(),
|
|
12217
|
+
fps: number().positive().optional(),
|
|
12218
|
+
label: string().optional(),
|
|
12219
|
+
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
12220
|
+
deviceFeatures: array(string()).optional(),
|
|
12221
|
+
/** Eligible for automatic profile assignment. Absent = `true`. */
|
|
12222
|
+
autoEligible: boolean().optional(),
|
|
12223
|
+
/** Transport-specific opaque metadata (e.g. rfc4571 SDP). */
|
|
12224
|
+
metadata: record(string(), unknown()).optional()
|
|
11955
12225
|
});
|
|
11956
12226
|
({
|
|
11957
12227
|
deviceTypes: [DeviceType.Camera],
|
|
11958
|
-
|
|
11959
|
-
|
|
11960
|
-
deviceId: number(),
|
|
11961
|
-
|
|
11962
|
-
|
|
12228
|
+
methods: {
|
|
12229
|
+
getCatalog: method(
|
|
12230
|
+
object({ deviceId: number().int().nonnegative() }),
|
|
12231
|
+
array(CamStreamDescriptorSchema).readonly()
|
|
12232
|
+
)
|
|
11963
12233
|
}
|
|
11964
12234
|
});
|
|
11965
12235
|
const ModelFormatSchema = _enum(MODEL_FORMATS);
|
|
@@ -12827,6 +13097,18 @@ const TopologyProcessSchema = object({
|
|
|
12827
13097
|
services: array(TopologyServiceSchema).readonly(),
|
|
12828
13098
|
groupId: string().optional()
|
|
12829
13099
|
});
|
|
13100
|
+
const TopologyCategoryAddonSchema = object({
|
|
13101
|
+
id: string(),
|
|
13102
|
+
status: string(),
|
|
13103
|
+
cpuPercent: number(),
|
|
13104
|
+
memoryRss: number()
|
|
13105
|
+
});
|
|
13106
|
+
const TopologyCategorySchema = object({
|
|
13107
|
+
category: string(),
|
|
13108
|
+
total: number(),
|
|
13109
|
+
healthy: number(),
|
|
13110
|
+
addons: array(TopologyCategoryAddonSchema).readonly()
|
|
13111
|
+
});
|
|
12830
13112
|
const TopologyNodeSchema = object({
|
|
12831
13113
|
id: string(),
|
|
12832
13114
|
name: string(),
|
|
@@ -12851,7 +13133,15 @@ const TopologyNodeSchema = object({
|
|
|
12851
13133
|
status: string()
|
|
12852
13134
|
})
|
|
12853
13135
|
).readonly(),
|
|
12854
|
-
processes: array(TopologyProcessSchema).readonly()
|
|
13136
|
+
processes: array(TopologyProcessSchema).readonly(),
|
|
13137
|
+
categories: array(TopologyCategorySchema).readonly()
|
|
13138
|
+
});
|
|
13139
|
+
const CapUsageEdgeSchema = object({
|
|
13140
|
+
callerAddonId: string(),
|
|
13141
|
+
providerAddonId: string(),
|
|
13142
|
+
capName: string(),
|
|
13143
|
+
callsPerMin: number(),
|
|
13144
|
+
lastCallAtMs: number()
|
|
12855
13145
|
});
|
|
12856
13146
|
const ClusterAddonNodeDeploymentSchema = object({
|
|
12857
13147
|
nodeId: string(),
|
|
@@ -12935,13 +13225,7 @@ const RenameNodeResultSchema = object({
|
|
|
12935
13225
|
object({
|
|
12936
13226
|
windowSeconds: number().int().positive().max(300).default(60)
|
|
12937
13227
|
}),
|
|
12938
|
-
array(
|
|
12939
|
-
callerAddonId: string(),
|
|
12940
|
-
providerAddonId: string(),
|
|
12941
|
-
capName: string(),
|
|
12942
|
-
callsPerMin: number(),
|
|
12943
|
-
lastCallAtMs: number()
|
|
12944
|
-
})).readonly(),
|
|
13228
|
+
array(CapUsageEdgeSchema).readonly(),
|
|
12945
13229
|
{ auth: "admin" }
|
|
12946
13230
|
),
|
|
12947
13231
|
/**
|
|
@@ -13153,7 +13437,8 @@ const PackageUpdateSchema = object({
|
|
|
13153
13437
|
currentVersion: string(),
|
|
13154
13438
|
latestVersion: string(),
|
|
13155
13439
|
category: _enum(["addon", "core"]),
|
|
13156
|
-
requiresRestart: boolean()
|
|
13440
|
+
requiresRestart: boolean(),
|
|
13441
|
+
isSystem: boolean()
|
|
13157
13442
|
});
|
|
13158
13443
|
const PackageVersionInfoSchema = object({
|
|
13159
13444
|
version: string(),
|
|
@@ -13186,6 +13471,42 @@ const UpdateFrameworkPackageResultSchema = object({
|
|
|
13186
13471
|
/** Ms-epoch the server scheduled its self-restart. */
|
|
13187
13472
|
restartingAt: number()
|
|
13188
13473
|
});
|
|
13474
|
+
const BulkUpdateItemStatusSchema = _enum([
|
|
13475
|
+
"queued",
|
|
13476
|
+
"updating",
|
|
13477
|
+
"done",
|
|
13478
|
+
"done-pending-restart",
|
|
13479
|
+
"failed"
|
|
13480
|
+
]);
|
|
13481
|
+
const BulkUpdateItemSchema = object({
|
|
13482
|
+
name: string(),
|
|
13483
|
+
isSystem: boolean(),
|
|
13484
|
+
fromVersion: string(),
|
|
13485
|
+
toVersion: string(),
|
|
13486
|
+
status: BulkUpdateItemStatusSchema,
|
|
13487
|
+
error: string().optional(),
|
|
13488
|
+
startedAtMs: number().optional(),
|
|
13489
|
+
completedAtMs: number().optional()
|
|
13490
|
+
});
|
|
13491
|
+
const BulkUpdatePhaseSchema = _enum([
|
|
13492
|
+
"regular",
|
|
13493
|
+
"system",
|
|
13494
|
+
"restarting",
|
|
13495
|
+
"finalizing"
|
|
13496
|
+
]);
|
|
13497
|
+
const BulkUpdateStateSchema = object({
|
|
13498
|
+
id: string(),
|
|
13499
|
+
nodeId: string(),
|
|
13500
|
+
startedAtMs: number(),
|
|
13501
|
+
completedAtMs: number().optional(),
|
|
13502
|
+
total: number(),
|
|
13503
|
+
completed: number(),
|
|
13504
|
+
failed: number(),
|
|
13505
|
+
current: string().nullable(),
|
|
13506
|
+
phase: BulkUpdatePhaseSchema,
|
|
13507
|
+
cancelled: boolean(),
|
|
13508
|
+
items: array(BulkUpdateItemSchema).readonly()
|
|
13509
|
+
});
|
|
13189
13510
|
const FrameworkPackageStatusSchema = object({
|
|
13190
13511
|
packageName: string(),
|
|
13191
13512
|
currentVersion: string(),
|
|
@@ -13323,7 +13644,7 @@ const CustomActionInputSchema = object({
|
|
|
13323
13644
|
getLastRestart: method(
|
|
13324
13645
|
_void(),
|
|
13325
13646
|
object({
|
|
13326
|
-
kind: _enum(["framework-update", "manual", "system"]),
|
|
13647
|
+
kind: _enum(["framework-update", "manual", "system", "framework-bulk-update"]),
|
|
13327
13648
|
packageName: string().optional(),
|
|
13328
13649
|
fromVersion: string().optional(),
|
|
13329
13650
|
toVersion: string().optional(),
|
|
@@ -13413,11 +13734,70 @@ const CustomActionInputSchema = object({
|
|
|
13413
13734
|
updateFrameworkPackage: method(
|
|
13414
13735
|
object({
|
|
13415
13736
|
packageName: string().min(1),
|
|
13416
|
-
version: string().optional()
|
|
13737
|
+
version: string().optional(),
|
|
13738
|
+
deferRestart: boolean().optional()
|
|
13417
13739
|
}),
|
|
13418
13740
|
UpdateFrameworkPackageResultSchema,
|
|
13419
13741
|
{ kind: "mutation", auth: "admin" }
|
|
13420
13742
|
),
|
|
13743
|
+
/**
|
|
13744
|
+
* Kicks off a server-side bulk update operation and returns the bulk
|
|
13745
|
+
* id immediately. The operation runs asynchronously; observe progress
|
|
13746
|
+
* via the `AddonsBulkUpdateProgress` event or `getBulkUpdateState`.
|
|
13747
|
+
* Items with `isSystem: true` use `deferRestart` — the hub restarts
|
|
13748
|
+
* ONCE at the end of the system phase, after all system packages are
|
|
13749
|
+
* installed.
|
|
13750
|
+
*
|
|
13751
|
+
* `items[].version` is REQUIRED — callers must pass the resolved
|
|
13752
|
+
* version from `listUpdates`. There is no `'latest'` default here
|
|
13753
|
+
* (unlike `updatePackage`) to guarantee deterministic bulk rolls.
|
|
13754
|
+
*/
|
|
13755
|
+
startBulkUpdate: method(
|
|
13756
|
+
object({
|
|
13757
|
+
nodeId: string(),
|
|
13758
|
+
items: array(object({
|
|
13759
|
+
name: string(),
|
|
13760
|
+
version: string(),
|
|
13761
|
+
isSystem: boolean()
|
|
13762
|
+
})).readonly()
|
|
13763
|
+
}),
|
|
13764
|
+
object({ id: string() }),
|
|
13765
|
+
{ kind: "mutation", auth: "admin" }
|
|
13766
|
+
),
|
|
13767
|
+
/**
|
|
13768
|
+
* Returns the current state of a bulk update by id.
|
|
13769
|
+
* Returns `null` if the id is unknown or has been auto-cleaned
|
|
13770
|
+
* (5 minutes after `completedAt` the record is evicted from memory).
|
|
13771
|
+
*/
|
|
13772
|
+
getBulkUpdateState: method(
|
|
13773
|
+
object({ id: string() }),
|
|
13774
|
+
BulkUpdateStateSchema.nullable(),
|
|
13775
|
+
{ auth: "admin" }
|
|
13776
|
+
),
|
|
13777
|
+
/**
|
|
13778
|
+
* Cancels an in-flight bulk update. The update loop exits after the
|
|
13779
|
+
* currently-processing item completes — cancellation is not
|
|
13780
|
+
* instantaneous. Has no effect once the `restarting` phase has been
|
|
13781
|
+
* entered (the hub is already shutting down at that point).
|
|
13782
|
+
* Returns `{ cancelled: false }` if the id is unknown, the operation
|
|
13783
|
+
* has already completed, or the `restarting` phase is active.
|
|
13784
|
+
*/
|
|
13785
|
+
cancelBulkUpdate: method(
|
|
13786
|
+
object({ id: string() }),
|
|
13787
|
+
object({ cancelled: boolean() }),
|
|
13788
|
+
{ kind: "mutation", auth: "admin" }
|
|
13789
|
+
),
|
|
13790
|
+
/**
|
|
13791
|
+
* Lists all currently active (non-completed) bulk updates.
|
|
13792
|
+
* If `nodeId` is provided, filters to only bulk updates targeting
|
|
13793
|
+
* that node. Useful for restoring an in-progress banner on a fresh
|
|
13794
|
+
* page load when the UI reconnects mid-operation.
|
|
13795
|
+
*/
|
|
13796
|
+
listActiveBulkUpdates: method(
|
|
13797
|
+
object({ nodeId: string().optional() }),
|
|
13798
|
+
array(BulkUpdateStateSchema).readonly(),
|
|
13799
|
+
{ auth: "admin" }
|
|
13800
|
+
),
|
|
13421
13801
|
getVersions: method(
|
|
13422
13802
|
object({ name: string() }),
|
|
13423
13803
|
array(PackageVersionInfoSchema).readonly()
|
|
@@ -13545,6 +13925,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13545
13925
|
EventCategory2["StreamBrokerOnCamStreamDemand"] = "stream-broker.onCamStreamDemand";
|
|
13546
13926
|
EventCategory2["StreamBrokerOnCamStreamIdle"] = "stream-broker.onCamStreamIdle";
|
|
13547
13927
|
EventCategory2["StreamBrokerOnRequestStreamSourceRefresh"] = "stream-broker.onRequestStreamSourceRefresh";
|
|
13928
|
+
EventCategory2["StreamParamsChanged"] = "stream-params.changed";
|
|
13548
13929
|
EventCategory2["DeviceStateChanged"] = "device.state-changed";
|
|
13549
13930
|
EventCategory2["BatteryOnStatusChanged"] = "battery.onStatusChanged";
|
|
13550
13931
|
EventCategory2["DoorbellOnPressed"] = "doorbell.onPressed";
|
|
@@ -13592,6 +13973,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13592
13973
|
EventCategory2["NetworkTunnelStarted"] = "network.tunnel.started";
|
|
13593
13974
|
EventCategory2["NetworkTunnelStopped"] = "network.tunnel.stopped";
|
|
13594
13975
|
EventCategory2["LocalNetworkChanged"] = "network.local.changed";
|
|
13976
|
+
EventCategory2["MeshNetworkChanged"] = "network.mesh.changed";
|
|
13595
13977
|
EventCategory2["BackupCompleted"] = "backup.completed";
|
|
13596
13978
|
EventCategory2["BackupRestored"] = "backup.restored";
|
|
13597
13979
|
EventCategory2["NotificationDispatched"] = "notification.dispatched";
|
|
@@ -13602,6 +13984,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13602
13984
|
EventCategory2["DeviceAwake"] = "device.awake";
|
|
13603
13985
|
EventCategory2["DeviceSleeping"] = "device.sleeping";
|
|
13604
13986
|
EventCategory2["RetentionCleanup"] = "retention.cleanup";
|
|
13987
|
+
EventCategory2["AddonsBulkUpdateProgress"] = "addons.bulk-update-progress";
|
|
13605
13988
|
return EventCategory2;
|
|
13606
13989
|
})(EventCategory || {});
|
|
13607
13990
|
function createEvent(category, source, data) {
|
|
@@ -13751,7 +14134,7 @@ class BaseAddon {
|
|
|
13751
14134
|
}
|
|
13752
14135
|
// ── Settings schemas (override to provide UI) ─────────────────────────
|
|
13753
14136
|
/** Override to provide global-level settings UI schema. */
|
|
13754
|
-
globalSettingsSchema() {
|
|
14137
|
+
globalSettingsSchema(_cap) {
|
|
13755
14138
|
return null;
|
|
13756
14139
|
}
|
|
13757
14140
|
/** Override to provide device-level settings UI schema. */
|
|
@@ -13765,8 +14148,8 @@ class BaseAddon {
|
|
|
13765
14148
|
// blob and every addon used exactly one of them; the distinction was
|
|
13766
14149
|
// never semantically load-bearing. `global` won because it was the
|
|
13767
14150
|
// widely-used one and the name reads naturally (per-node addon config).
|
|
13768
|
-
async getGlobalSettings(overlay) {
|
|
13769
|
-
const schema = this.globalSettingsSchema();
|
|
14151
|
+
async getGlobalSettings(overlay, cap) {
|
|
14152
|
+
const schema = this.globalSettingsSchema(cap);
|
|
13770
14153
|
if (!schema) return { sections: [] };
|
|
13771
14154
|
const raw = await this._ctx?.settings?.readAddonStore() ?? {};
|
|
13772
14155
|
return hydrateSchema(schema, overlay ? { ...raw, ...overlay } : raw);
|
|
@@ -14177,13 +14560,42 @@ function customAction(input, output, options) {
|
|
|
14177
14560
|
scope: options?.scope ?? { kind: "system" }
|
|
14178
14561
|
};
|
|
14179
14562
|
}
|
|
14563
|
+
const CREDENTIAL_PARAM_PATTERNS = [
|
|
14564
|
+
/^user$/i,
|
|
14565
|
+
/^usr$/i,
|
|
14566
|
+
/^username$/i,
|
|
14567
|
+
/^password$/i,
|
|
14568
|
+
/^pwd$/i,
|
|
14569
|
+
/^pass$/i,
|
|
14570
|
+
/^passwd$/i,
|
|
14571
|
+
/^secret$/i,
|
|
14572
|
+
/^token$/i,
|
|
14573
|
+
/^auth$/i,
|
|
14574
|
+
/^auth[_-]?token$/i,
|
|
14575
|
+
/^bearer$/i,
|
|
14576
|
+
/^api[_-]?key$/i,
|
|
14577
|
+
/^access[_-]?token$/i,
|
|
14578
|
+
/^refresh[_-]?token$/i
|
|
14579
|
+
];
|
|
14580
|
+
function isCredentialParam(name) {
|
|
14581
|
+
return CREDENTIAL_PARAM_PATTERNS.some((re) => re.test(name));
|
|
14582
|
+
}
|
|
14180
14583
|
function maskUrlCredentials(rawUrl) {
|
|
14181
14584
|
try {
|
|
14182
14585
|
const u = new URL(rawUrl);
|
|
14183
|
-
|
|
14184
|
-
u.username
|
|
14185
|
-
|
|
14186
|
-
|
|
14586
|
+
let touched = false;
|
|
14587
|
+
if (u.username || u.password) {
|
|
14588
|
+
u.username = "";
|
|
14589
|
+
u.password = "";
|
|
14590
|
+
touched = true;
|
|
14591
|
+
}
|
|
14592
|
+
for (const key of [...u.searchParams.keys()]) {
|
|
14593
|
+
if (isCredentialParam(key)) {
|
|
14594
|
+
u.searchParams.set(key, "***");
|
|
14595
|
+
touched = true;
|
|
14596
|
+
}
|
|
14597
|
+
}
|
|
14598
|
+
return touched ? u.toString() : rawUrl;
|
|
14187
14599
|
} catch {
|
|
14188
14600
|
return rawUrl;
|
|
14189
14601
|
}
|
|
@@ -14267,4 +14679,4 @@ exports.pipelineRunnerCapability = pipelineRunnerCapability;
|
|
|
14267
14679
|
exports.streamBrokerCapability = streamBrokerCapability;
|
|
14268
14680
|
exports.string = string;
|
|
14269
14681
|
exports.webrtcSessionCapability = webrtcSessionCapability;
|
|
14270
|
-
//# sourceMappingURL=index-
|
|
14682
|
+
//# sourceMappingURL=index-BbPPvoCx.js.map
|