camstack 1.2.177 → 1.2.179
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.
|
@@ -24024,9 +24024,9 @@ var require_zod = __commonJS({
|
|
|
24024
24024
|
}
|
|
24025
24025
|
});
|
|
24026
24026
|
|
|
24027
|
-
// ../system/dist/dist-
|
|
24028
|
-
var
|
|
24029
|
-
"../system/dist/dist-
|
|
24027
|
+
// ../system/dist/dist-DePB7uwU.js
|
|
24028
|
+
var require_dist_DePB7uwU = __commonJS({
|
|
24029
|
+
"../system/dist/dist-DePB7uwU.js"(exports) {
|
|
24030
24030
|
"use strict";
|
|
24031
24031
|
var zod = require_zod();
|
|
24032
24032
|
__require("crypto");
|
|
@@ -29287,11 +29287,11 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
29287
29287
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
29288
29288
|
precision: zod.z.enum(["fp32", "int8"]).optional(),
|
|
29289
29289
|
/**
|
|
29290
|
-
*
|
|
29291
|
-
*
|
|
29292
|
-
*
|
|
29290
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
29291
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
29292
|
+
* label is "Test".
|
|
29293
29293
|
*/
|
|
29294
|
-
optimization: zod.z.enum(["standard", "
|
|
29294
|
+
optimization: zod.z.enum(["standard", "test"]).optional(),
|
|
29295
29295
|
/**
|
|
29296
29296
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
29297
29297
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -37878,7 +37878,7 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
37878
37878
|
mode: "singleton",
|
|
37879
37879
|
internal: true,
|
|
37880
37880
|
methods: { distributeModel: method(zod.z.object({
|
|
37881
|
-
|
|
37881
|
+
targetNodeId: zod.z.string(),
|
|
37882
37882
|
modelId: zod.z.string(),
|
|
37883
37883
|
format: zod.z.enum(MODEL_FORMATS),
|
|
37884
37884
|
entry: ModelCatalogEntrySchema
|
|
@@ -39852,6 +39852,7 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
39852
39852
|
"detection-blind",
|
|
39853
39853
|
"nodes",
|
|
39854
39854
|
"addons",
|
|
39855
|
+
"addon-updates",
|
|
39855
39856
|
"updates"
|
|
39856
39857
|
]);
|
|
39857
39858
|
var NcStateSummaryPreviewSectionSchema = zod.z.object({
|
|
@@ -40238,7 +40239,19 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
40238
40239
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
40239
40240
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
40240
40241
|
*/
|
|
40241
|
-
schedule: NcScheduleSchema.optional()
|
|
40242
|
+
schedule: NcScheduleSchema.optional(),
|
|
40243
|
+
/**
|
|
40244
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
40245
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
40246
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
40247
|
+
*/
|
|
40248
|
+
notifyDuringEntryDelay: zod.z.boolean().optional(),
|
|
40249
|
+
/**
|
|
40250
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
40251
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
40252
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
40253
|
+
*/
|
|
40254
|
+
notifySensorRewatched: zod.z.boolean().optional()
|
|
40242
40255
|
});
|
|
40243
40256
|
var NcAlarmModeDelaysListSchema = zod.z.array(NcAlarmModeDelaysSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
40244
40257
|
var NcAlarmModeDelaysEditSchema = zod.z.object({
|
|
@@ -40248,7 +40261,11 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
40248
40261
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
40249
40262
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
40250
40263
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
40251
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
40264
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
40265
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
40266
|
+
notifyDuringEntryDelay: zod.z.boolean().nullable().optional(),
|
|
40267
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
40268
|
+
notifySensorRewatched: zod.z.boolean().nullable().optional()
|
|
40252
40269
|
});
|
|
40253
40270
|
var NcAlarmModeDelaysEditListSchema = zod.z.array(NcAlarmModeDelaysEditSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
40254
40271
|
var NcAlarmNonBlockingEditSchema = zod.z.object({
|
|
@@ -41088,39 +41105,19 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
41088
41105
|
label: "Face recognition model",
|
|
41089
41106
|
defaultModelId: "auraface-r100",
|
|
41090
41107
|
indexName: "the enrolled face gallery",
|
|
41091
|
-
options: [
|
|
41092
|
-
|
|
41093
|
-
|
|
41094
|
-
|
|
41095
|
-
},
|
|
41096
|
-
{
|
|
41097
|
-
id: "arcface-r100",
|
|
41098
|
-
label: "ArcFace (ResNet34)"
|
|
41099
|
-
},
|
|
41100
|
-
{
|
|
41101
|
-
id: "inception-resnet-v1",
|
|
41102
|
-
label: "Inception ResNet V1"
|
|
41103
|
-
}
|
|
41104
|
-
]
|
|
41108
|
+
options: [{
|
|
41109
|
+
id: "auraface-r100",
|
|
41110
|
+
label: "AuraFace R100"
|
|
41111
|
+
}]
|
|
41105
41112
|
}, {
|
|
41106
41113
|
stepId: "clip-embedding",
|
|
41107
41114
|
label: "Semantic search model",
|
|
41108
|
-
defaultModelId: "
|
|
41115
|
+
defaultModelId: "siglip2-b16-224",
|
|
41109
41116
|
indexName: "the object semantic-search index",
|
|
41110
|
-
options: [
|
|
41111
|
-
|
|
41112
|
-
|
|
41113
|
-
|
|
41114
|
-
},
|
|
41115
|
-
{
|
|
41116
|
-
id: "mobileclip-s2",
|
|
41117
|
-
label: "MobileCLIP S2"
|
|
41118
|
-
},
|
|
41119
|
-
{
|
|
41120
|
-
id: "siglip2-b16-224",
|
|
41121
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
41122
|
-
}
|
|
41123
|
-
]
|
|
41117
|
+
options: [{
|
|
41118
|
+
id: "siglip2-b16-224",
|
|
41119
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
41120
|
+
}]
|
|
41124
41121
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
41125
41122
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
41126
41123
|
stepId: "face-embedding",
|
|
@@ -44238,6 +44235,11 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
44238
44235
|
"analyzer",
|
|
44239
44236
|
"device-activity"
|
|
44240
44237
|
]);
|
|
44238
|
+
var SessionTriggerSchema = zod.z.object({
|
|
44239
|
+
source: MotionSourceEnum,
|
|
44240
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
44241
|
+
sensorName: zod.z.string().optional()
|
|
44242
|
+
});
|
|
44241
44243
|
var MotionSourcesSchema = zod.z.array(MotionSourceEnum);
|
|
44242
44244
|
var MOTION_SOURCE_LABELS = {
|
|
44243
44245
|
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
@@ -44385,6 +44387,14 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
44385
44387
|
*/
|
|
44386
44388
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
44387
44389
|
/**
|
|
44390
|
+
* What opened this attach, on a SESSION attach only (see
|
|
44391
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
44392
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
44393
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
44394
|
+
* runner then names no source on the phase event.
|
|
44395
|
+
*/
|
|
44396
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
44397
|
+
/**
|
|
44388
44398
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
44389
44399
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
44390
44400
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -48125,6 +48135,36 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
48125
48135
|
})
|
|
48126
48136
|
}
|
|
48127
48137
|
};
|
|
48138
|
+
var CAMSTACK_APP_LINK_ORIGIN = "https://camstack.zentik.app";
|
|
48139
|
+
function toAppLinkHubOrigin(baseUrl) {
|
|
48140
|
+
let parsed;
|
|
48141
|
+
try {
|
|
48142
|
+
parsed = new URL(baseUrl);
|
|
48143
|
+
} catch {
|
|
48144
|
+
return null;
|
|
48145
|
+
}
|
|
48146
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
|
|
48147
|
+
if (parsed.username !== "" || parsed.password !== "") return null;
|
|
48148
|
+
if (parsed.hostname === "") return null;
|
|
48149
|
+
return parsed.origin;
|
|
48150
|
+
}
|
|
48151
|
+
function pickAppLinkHub(endpoints) {
|
|
48152
|
+
const rank2 = (e) => {
|
|
48153
|
+
if (e.kind !== "public" || !e.baseUrl.startsWith("https://")) return null;
|
|
48154
|
+
if (e.interfaceKind === "public") return 0;
|
|
48155
|
+
if (e.interfaceKind === "vpn") return 1;
|
|
48156
|
+
return null;
|
|
48157
|
+
};
|
|
48158
|
+
return endpoints.flatMap((e) => {
|
|
48159
|
+
const r = rank2(e);
|
|
48160
|
+
const origin = toAppLinkHubOrigin(e.baseUrl);
|
|
48161
|
+
return r === null || origin === null ? [] : [{
|
|
48162
|
+
r,
|
|
48163
|
+
p: e.priority,
|
|
48164
|
+
origin
|
|
48165
|
+
}];
|
|
48166
|
+
}).toSorted((a, b) => a.r - b.r || a.p - b.p)[0]?.origin ?? null;
|
|
48167
|
+
}
|
|
48128
48168
|
var webrtcClientHintsSchema = zod.z.object({
|
|
48129
48169
|
viewportWidth: zod.z.number().int().positive().optional(),
|
|
48130
48170
|
viewportHeight: zod.z.number().int().positive().optional(),
|
|
@@ -51967,7 +52007,7 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
51967
52007
|
name: zod.z.string(),
|
|
51968
52008
|
family: zod.z.enum(["IPv4", "IPv6"]),
|
|
51969
52009
|
address: zod.z.string(),
|
|
51970
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
52010
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
51971
52011
|
cidr: zod.z.string(),
|
|
51972
52012
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
51973
52013
|
netmask: zod.z.string(),
|
|
@@ -52016,7 +52056,8 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
52016
52056
|
"lan-ipv4",
|
|
52017
52057
|
"lan-ipv6",
|
|
52018
52058
|
"public",
|
|
52019
|
-
"loopback"
|
|
52059
|
+
"loopback",
|
|
52060
|
+
"app-link"
|
|
52020
52061
|
]),
|
|
52021
52062
|
/**
|
|
52022
52063
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -52081,8 +52122,20 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
52081
52122
|
var NotificationEndpointSchema = zod.z.object({
|
|
52082
52123
|
/** The operator's explicit choice, or null for AUTO. */
|
|
52083
52124
|
baseUrl: zod.z.string().nullable(),
|
|
52084
|
-
/**
|
|
52085
|
-
|
|
52125
|
+
/**
|
|
52126
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
52127
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
52128
|
+
* answered the public tunnel / mesh here, or null.
|
|
52129
|
+
*/
|
|
52130
|
+
resolved: zod.z.string().nullable(),
|
|
52131
|
+
/**
|
|
52132
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
52133
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
52134
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
52135
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
52136
|
+
* Absent on a pre-D709 hub.
|
|
52137
|
+
*/
|
|
52138
|
+
appLinkHub: zod.z.string().nullable()
|
|
52086
52139
|
});
|
|
52087
52140
|
var ViewerEndpointsSchema = zod.z.object({
|
|
52088
52141
|
/** The operator's explicit race set, or empty for AUTO. */
|
|
@@ -52146,7 +52199,7 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
52146
52199
|
* every client a second authority on a socket only the hub binds. A viewer
|
|
52147
52200
|
* configured with a port-less public URL (`https://camstack.example.top`)
|
|
52148
52201
|
* infers 443 from the scheme, asks with 443, and was handed
|
|
52149
|
-
* `https://192.168.
|
|
52202
|
+
* `https://192.168.10.9:443` for a hub listening on 4443. That candidate
|
|
52150
52203
|
* cannot ever answer, and losing its race reads in the log exactly like
|
|
52151
52204
|
* "the LAN was tried and it was slower" — so an operator sitting on his own
|
|
52152
52205
|
* WiFi stayed on the public tunnel for weeks, with the LAN candidate born
|
|
@@ -52179,13 +52232,21 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
52179
52232
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
52180
52233
|
* to avoid mixed-content blocks in the browser. The public
|
|
52181
52234
|
* tunnel always emits `https://` regardless. */
|
|
52182
|
-
scheme: zod.z.enum(["http", "https"]).optional()
|
|
52235
|
+
scheme: zod.z.enum(["http", "https"]).optional(),
|
|
52236
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
52237
|
+
* an address notification links can be flagged with, not a hub
|
|
52238
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
52239
|
+
includeAppLink: zod.z.boolean().optional()
|
|
52183
52240
|
}), GetConnectionEndpointsResultSchema),
|
|
52184
52241
|
/**
|
|
52185
|
-
* The
|
|
52186
|
-
*
|
|
52187
|
-
*
|
|
52188
|
-
*
|
|
52242
|
+
* The address notification links are flagged with. `baseUrl: null` means
|
|
52243
|
+
* AUTO, which is the CamStack app link (D709): viewer taps go through
|
|
52244
|
+
* `https://camstack.zentik.app/…?hub=<appLinkHub>` and open the app. Any
|
|
52245
|
+
* hub address the palette lists can be flagged instead; then viewer taps,
|
|
52246
|
+
* attachment links and action buttons all use it. Signed media and
|
|
52247
|
+
* buttons never use the app link — with it flagged (or AUTO) they keep
|
|
52248
|
+
* the ranked hub ladder (a configured origin, a connected tunnel, then
|
|
52249
|
+
* the LAN), never loopback.
|
|
52189
52250
|
*
|
|
52190
52251
|
* Why an explicit marker: the automatic ranking cannot know which of
|
|
52191
52252
|
* several reachable addresses the RECIPIENT can actually open. A link is
|
|
@@ -52544,7 +52605,7 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
52544
52605
|
tags: zod.z.array(zod.z.string()).readonly(),
|
|
52545
52606
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
52546
52607
|
exitNodeOption: zod.z.boolean(),
|
|
52547
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
52608
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
52548
52609
|
advertisedRoutes: zod.z.array(zod.z.string()).readonly(),
|
|
52549
52610
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
52550
52611
|
userLogin: zod.z.string().nullable(),
|
|
@@ -53693,7 +53754,13 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
53693
53754
|
*/
|
|
53694
53755
|
availablePositions: zod.z.array(OsdPositionEnum).readonly(),
|
|
53695
53756
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
53696
|
-
readOnly: zod.z.boolean().optional()
|
|
53757
|
+
readOnly: zod.z.boolean().optional(),
|
|
53758
|
+
/**
|
|
53759
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
53760
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
53761
|
+
* copy on the binding.
|
|
53762
|
+
*/
|
|
53763
|
+
maxCharacters: zod.z.number().int().positive().optional()
|
|
53697
53764
|
});
|
|
53698
53765
|
var OsdStatusSchema = zod.z.object({ overlays: zod.z.array(OsdOverlaySchema).readonly() });
|
|
53699
53766
|
var OsdOverlayPatchSchema = zod.z.object({
|
|
@@ -53781,7 +53848,9 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
53781
53848
|
valuePath: zod.z.string().min(1).max(64),
|
|
53782
53849
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
53783
53850
|
displayUnit: zod.z.string().max(16).optional(),
|
|
53784
|
-
maxDecimals: zod.z.number().int().min(0).max(4).default(1)
|
|
53851
|
+
maxDecimals: zod.z.number().int().min(0).max(4).default(1),
|
|
53852
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
53853
|
+
valueMap: zod.z.record(zod.z.string(), zod.z.string()).optional()
|
|
53785
53854
|
});
|
|
53786
53855
|
var OsdNamedTemplateSchema = zod.z.object({
|
|
53787
53856
|
id: zod.z.string().min(1).max(64),
|
|
@@ -53826,18 +53895,11 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
53826
53895
|
source: OsdSourceSchema,
|
|
53827
53896
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
53828
53897
|
template: zod.z.string().max(96).default("${value}"),
|
|
53829
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
53830
|
-
maxCharacters: zod.z.number().int().min(4).max(64).optional(),
|
|
53831
53898
|
/**
|
|
53832
53899
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
53833
53900
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
53834
53901
|
*/
|
|
53835
53902
|
maxDecimals: zod.z.number().int().min(0).max(4).default(1),
|
|
53836
|
-
/**
|
|
53837
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
53838
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
53839
|
-
*/
|
|
53840
|
-
unitLabel: zod.z.string().max(8).optional(),
|
|
53841
53903
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
53842
53904
|
valueMap: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
53843
53905
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -53846,9 +53908,7 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
53846
53908
|
* Display gate, in the notification centre's condition vocabulary.
|
|
53847
53909
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
53848
53910
|
*/
|
|
53849
|
-
conditions: NcConditionsSchema.optional()
|
|
53850
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
53851
|
-
fallbackText: zod.z.string().max(64).default("")
|
|
53911
|
+
conditions: NcConditionsSchema.optional()
|
|
53852
53912
|
});
|
|
53853
53913
|
var OsdSlotViewSchema = zod.z.object({
|
|
53854
53914
|
slotId: zod.z.string(),
|
|
@@ -72213,12 +72273,14 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
72213
72273
|
{
|
|
72214
72274
|
id: "addons",
|
|
72215
72275
|
family: "system",
|
|
72216
|
-
label: "Addons",
|
|
72217
|
-
kinds: [
|
|
72218
|
-
|
|
72219
|
-
|
|
72220
|
-
|
|
72221
|
-
|
|
72276
|
+
label: "Addons stopped",
|
|
72277
|
+
kinds: ["addon-crash-loop"]
|
|
72278
|
+
},
|
|
72279
|
+
{
|
|
72280
|
+
id: "addon-updates",
|
|
72281
|
+
family: "system",
|
|
72282
|
+
label: "Addon updates",
|
|
72283
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
72222
72284
|
},
|
|
72223
72285
|
{
|
|
72224
72286
|
id: "updates",
|
|
@@ -72348,13 +72410,15 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
72348
72410
|
},
|
|
72349
72411
|
{
|
|
72350
72412
|
name: "summaryAddons",
|
|
72351
|
-
label: "Summary: addons",
|
|
72352
|
-
example: "
|
|
72353
|
-
kinds: [
|
|
72354
|
-
|
|
72355
|
-
|
|
72356
|
-
|
|
72357
|
-
|
|
72413
|
+
label: "Summary: addons stopped",
|
|
72414
|
+
example: "hub \u2014 recorder stopped after repeated crashes",
|
|
72415
|
+
kinds: ["addon-crash-loop"]
|
|
72416
|
+
},
|
|
72417
|
+
{
|
|
72418
|
+
name: "summaryAddonUpdates",
|
|
72419
|
+
label: "Summary: addon updates",
|
|
72420
|
+
example: "hub:\n\u2022 @camstack/addon-recorder 1.2.3 \u2192 1.2.4",
|
|
72421
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
72358
72422
|
},
|
|
72359
72423
|
{
|
|
72360
72424
|
name: "summaryUpdates",
|
|
@@ -72438,6 +72502,7 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
72438
72502
|
[...RULE_BODY_ONLY],
|
|
72439
72503
|
[...RULE_TEXT],
|
|
72440
72504
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
72505
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
72441
72506
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
72442
72507
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
72443
72508
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -72478,6 +72543,8 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
72478
72543
|
[...RULE_TEXT],
|
|
72479
72544
|
[...RULE_TEXT],
|
|
72480
72545
|
[...RULE_TEXT],
|
|
72546
|
+
[...RULE_TEXT],
|
|
72547
|
+
[...RULE_TEXT],
|
|
72481
72548
|
...STATE_SUMMARY_VARS
|
|
72482
72549
|
];
|
|
72483
72550
|
var TimelapseTemplateSchema = zod.z.object({
|
|
@@ -72887,6 +72954,12 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
72887
72954
|
return CAMERA_SWITCH_ORDER;
|
|
72888
72955
|
}
|
|
72889
72956
|
});
|
|
72957
|
+
Object.defineProperty(exports, "CAMSTACK_APP_LINK_ORIGIN", {
|
|
72958
|
+
enumerable: true,
|
|
72959
|
+
get: function() {
|
|
72960
|
+
return CAMSTACK_APP_LINK_ORIGIN;
|
|
72961
|
+
}
|
|
72962
|
+
});
|
|
72890
72963
|
Object.defineProperty(exports, "CAP_NAMES_WITH_STATUS", {
|
|
72891
72964
|
enumerable: true,
|
|
72892
72965
|
get: function() {
|
|
@@ -73721,6 +73794,12 @@ var require_dist_DeGPW01G = __commonJS({
|
|
|
73721
73794
|
return parseStreamParamsFormPatch;
|
|
73722
73795
|
}
|
|
73723
73796
|
});
|
|
73797
|
+
Object.defineProperty(exports, "pickAppLinkHub", {
|
|
73798
|
+
enumerable: true,
|
|
73799
|
+
get: function() {
|
|
73800
|
+
return pickAppLinkHub;
|
|
73801
|
+
}
|
|
73802
|
+
});
|
|
73724
73803
|
Object.defineProperty(exports, "planComposition", {
|
|
73725
73804
|
enumerable: true,
|
|
73726
73805
|
get: function() {
|
|
@@ -73949,7 +74028,7 @@ var require_alerts_addon = __commonJS({
|
|
|
73949
74028
|
[Symbol.toStringTag]: { value: "Module" }
|
|
73950
74029
|
});
|
|
73951
74030
|
require_chunk_Cek0wNdY();
|
|
73952
|
-
var require_dist10 =
|
|
74031
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
73953
74032
|
function deviceLabelFromEventData(data) {
|
|
73954
74033
|
const name = stringNonEmpty(data["name"]) ?? stringNonEmpty(data["deviceName"]);
|
|
73955
74034
|
if (name !== void 0) return name;
|
|
@@ -74773,7 +74852,7 @@ var require_calendars_addon = __commonJS({
|
|
|
74773
74852
|
[Symbol.toStringTag]: { value: "Module" }
|
|
74774
74853
|
});
|
|
74775
74854
|
require_chunk_Cek0wNdY();
|
|
74776
|
-
var require_dist10 =
|
|
74855
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
74777
74856
|
var require_settle_sources = require_settle_sources_Bhsy57y();
|
|
74778
74857
|
var zod = require_zod();
|
|
74779
74858
|
var CALENDAR_COLOR_PALETTE = [
|
|
@@ -74987,11 +75066,11 @@ var require_calendars = __commonJS({
|
|
|
74987
75066
|
}
|
|
74988
75067
|
});
|
|
74989
75068
|
|
|
74990
|
-
// ../system/dist/composition-sources-
|
|
74991
|
-
var
|
|
74992
|
-
"../system/dist/composition-sources-
|
|
75069
|
+
// ../system/dist/composition-sources-0nuWOdNd.js
|
|
75070
|
+
var require_composition_sources_0nuWOdNd = __commonJS({
|
|
75071
|
+
"../system/dist/composition-sources-0nuWOdNd.js"(exports) {
|
|
74993
75072
|
"use strict";
|
|
74994
|
-
var require_dist10 =
|
|
75073
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
74995
75074
|
function normalizedNativeOwner(owner) {
|
|
74996
75075
|
const trimmed = owner?.trim();
|
|
74997
75076
|
return trimmed ? trimmed : null;
|
|
@@ -75106,8 +75185,8 @@ var require_composer_addon = __commonJS({
|
|
|
75106
75185
|
[Symbol.toStringTag]: { value: "Module" }
|
|
75107
75186
|
});
|
|
75108
75187
|
require_chunk_Cek0wNdY();
|
|
75109
|
-
var require_dist10 =
|
|
75110
|
-
var require_composition_sources =
|
|
75188
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
75189
|
+
var require_composition_sources = require_composition_sources_0nuWOdNd();
|
|
75111
75190
|
var zod = require_zod();
|
|
75112
75191
|
function isRecord$2(value) {
|
|
75113
75192
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -76157,6 +76236,10 @@ var require_composer_addon = __commonJS({
|
|
|
76157
76236
|
value: outcome.value
|
|
76158
76237
|
};
|
|
76159
76238
|
}
|
|
76239
|
+
function hasObservedRoseLevel(memory) {
|
|
76240
|
+
for (const call of memory.calls.values()) if (call.kind === "rose" && call.priorLevel !== void 0) return true;
|
|
76241
|
+
return false;
|
|
76242
|
+
}
|
|
76160
76243
|
function strictFiniteAdvance(previous, next) {
|
|
76161
76244
|
return typeof next === "number" && Number.isFinite(next) && (previous === null || next > previous);
|
|
76162
76245
|
}
|
|
@@ -76196,7 +76279,7 @@ var require_composer_addon = __commonJS({
|
|
|
76196
76279
|
const record = next.get(key);
|
|
76197
76280
|
if (record === void 0) continue;
|
|
76198
76281
|
const candidateMemory = require_dist10.cloneStatefulExpressionMemory(record.expressionMemory);
|
|
76199
|
-
if (record.outcome?.state === "unavailable") require_dist10.disarmRoseMemory(candidateMemory);
|
|
76282
|
+
if (record.outcome?.state === "unavailable" && hasObservedRoseLevel(record.expressionMemory)) require_dist10.disarmRoseMemory(candidateMemory);
|
|
76200
76283
|
const outcome = require_dist10.evaluateCompositionField({
|
|
76201
76284
|
source: record.plan.source,
|
|
76202
76285
|
read,
|
|
@@ -78890,7 +78973,7 @@ var require_console_logging = __commonJS({
|
|
|
78890
78973
|
[Symbol.toStringTag]: { value: "Module" }
|
|
78891
78974
|
});
|
|
78892
78975
|
require_chunk_Cek0wNdY();
|
|
78893
|
-
var require_dist10 =
|
|
78976
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
78894
78977
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
78895
78978
|
var LEVEL_RANK = {
|
|
78896
78979
|
debug: 0,
|
|
@@ -82959,8 +83042,8 @@ var require_core_blocks_addon = __commonJS({
|
|
|
82959
83042
|
"use strict";
|
|
82960
83043
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
82961
83044
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
82962
|
-
var require_dist10 =
|
|
82963
|
-
var require_composition_sources =
|
|
83045
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
83046
|
+
var require_composition_sources = require_composition_sources_0nuWOdNd();
|
|
82964
83047
|
var node_crypto = __require("crypto");
|
|
82965
83048
|
var _camstack_types_node = require_node();
|
|
82966
83049
|
var node_fs_promises = __require("fs/promises");
|
|
@@ -84832,11 +84915,11 @@ var require_core_blocks = __commonJS({
|
|
|
84832
84915
|
}
|
|
84833
84916
|
});
|
|
84834
84917
|
|
|
84835
|
-
// ../system/dist/retired-settings-keys-
|
|
84836
|
-
var
|
|
84837
|
-
"../system/dist/retired-settings-keys-
|
|
84918
|
+
// ../system/dist/retired-settings-keys-BTKZdPn6.js
|
|
84919
|
+
var require_retired_settings_keys_BTKZdPn6 = __commonJS({
|
|
84920
|
+
"../system/dist/retired-settings-keys-BTKZdPn6.js"(exports) {
|
|
84838
84921
|
"use strict";
|
|
84839
|
-
var require_dist10 =
|
|
84922
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
84840
84923
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
84841
84924
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
84842
84925
|
return raw === "" || raw === "hub";
|
|
@@ -85125,8 +85208,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
85125
85208
|
[Symbol.toStringTag]: { value: "Module" }
|
|
85126
85209
|
});
|
|
85127
85210
|
require_chunk_Cek0wNdY();
|
|
85128
|
-
var require_dist10 =
|
|
85129
|
-
var require_retired_settings_keys =
|
|
85211
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
85212
|
+
var require_retired_settings_keys = require_retired_settings_keys_BTKZdPn6();
|
|
85130
85213
|
var zod = require_zod();
|
|
85131
85214
|
var node_crypto = __require("crypto");
|
|
85132
85215
|
var _camstack_types_node = require_node();
|
|
@@ -93321,7 +93404,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
93321
93404
|
[Symbol.toStringTag]: { value: "Module" }
|
|
93322
93405
|
});
|
|
93323
93406
|
require_chunk_Cek0wNdY();
|
|
93324
|
-
var require_dist10 =
|
|
93407
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
93325
93408
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
93326
93409
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
93327
93410
|
var HubForwarderDestination = class {
|
|
@@ -93458,7 +93541,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
93458
93541
|
"use strict";
|
|
93459
93542
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
93460
93543
|
require_chunk_Cek0wNdY();
|
|
93461
|
-
var require_dist10 =
|
|
93544
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
93462
93545
|
var NO_DEVICES = "liveness:no-devices";
|
|
93463
93546
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
93464
93547
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -93674,7 +93757,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
93674
93757
|
[Symbol.toStringTag]: { value: "Module" }
|
|
93675
93758
|
});
|
|
93676
93759
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
93677
|
-
var require_dist10 =
|
|
93760
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
93678
93761
|
var node_crypto = __require("crypto");
|
|
93679
93762
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
93680
93763
|
var crypto$1 = __require("crypto");
|
|
@@ -101528,7 +101611,7 @@ var require_loki_logging = __commonJS({
|
|
|
101528
101611
|
[Symbol.toStringTag]: { value: "Module" }
|
|
101529
101612
|
});
|
|
101530
101613
|
require_chunk_Cek0wNdY();
|
|
101531
|
-
var require_dist10 =
|
|
101614
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
101532
101615
|
function sanitizeLabelName(raw) {
|
|
101533
101616
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
101534
101617
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -102231,7 +102314,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
102231
102314
|
[Symbol.toStringTag]: { value: "Module" }
|
|
102232
102315
|
});
|
|
102233
102316
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
102234
|
-
var require_dist10 =
|
|
102317
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
102235
102318
|
var require_proc_stat = require_proc_stat_DL_WUOhl();
|
|
102236
102319
|
var node_fs_promises = __require("fs/promises");
|
|
102237
102320
|
var node_os = __require("os");
|
|
@@ -105071,7 +105154,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
105071
105154
|
[Symbol.toStringTag]: { value: "Module" }
|
|
105072
105155
|
});
|
|
105073
105156
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
105074
|
-
var require_dist10 =
|
|
105157
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
105075
105158
|
var node_crypto = __require("crypto");
|
|
105076
105159
|
var node_fs_promises = __require("fs/promises");
|
|
105077
105160
|
var node_path = __require("path");
|
|
@@ -106353,8 +106436,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
106353
106436
|
[Symbol.toStringTag]: { value: "Module" }
|
|
106354
106437
|
});
|
|
106355
106438
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
106356
|
-
var require_dist10 =
|
|
106357
|
-
var require_retired_settings_keys =
|
|
106439
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
106440
|
+
var require_retired_settings_keys = require_retired_settings_keys_BTKZdPn6();
|
|
106358
106441
|
var require_sqlite_snapshot_protocol = require_sqlite_snapshot_protocol_B9OndqZv();
|
|
106359
106442
|
var require_wal_checkpoint_policy = require_wal_checkpoint_policy_d2z2qPqx();
|
|
106360
106443
|
var node_crypto = __require("crypto");
|
|
@@ -109550,7 +109633,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
109550
109633
|
[Symbol.toStringTag]: { value: "Module" }
|
|
109551
109634
|
});
|
|
109552
109635
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
109553
|
-
var require_dist10 =
|
|
109636
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
109554
109637
|
var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
|
|
109555
109638
|
var zod = require_zod();
|
|
109556
109639
|
var node_crypto = __require("crypto");
|
|
@@ -113277,7 +113360,7 @@ var require_system_config_addon = __commonJS({
|
|
|
113277
113360
|
[Symbol.toStringTag]: { value: "Module" }
|
|
113278
113361
|
});
|
|
113279
113362
|
require_chunk_Cek0wNdY();
|
|
113280
|
-
var require_dist10 =
|
|
113363
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
113281
113364
|
var SECTION_TITLES = {
|
|
113282
113365
|
server: "Server",
|
|
113283
113366
|
auth: "Authentication"
|
|
@@ -131338,7 +131421,7 @@ var require_winston_logging = __commonJS({
|
|
|
131338
131421
|
[Symbol.toStringTag]: { value: "Module" }
|
|
131339
131422
|
});
|
|
131340
131423
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
131341
|
-
var require_dist10 =
|
|
131424
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
131342
131425
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
131343
131426
|
var node_path = __require("path");
|
|
131344
131427
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -148227,8 +148310,7 @@ var require_addon = __commonJS({
|
|
|
148227
148310
|
"setSlotBinding": { "binding": { "__nested__": {
|
|
148228
148311
|
"enabled": true,
|
|
148229
148312
|
"template": "${value}",
|
|
148230
|
-
"maxDecimals": 1
|
|
148231
|
-
"fallbackText": ""
|
|
148313
|
+
"maxDecimals": 1
|
|
148232
148314
|
} } },
|
|
148233
148315
|
"upsertTemplate": { "template": { "__nested__": {
|
|
148234
148316
|
"bindings": [],
|
|
@@ -155004,12 +155086,12 @@ var require_dist2 = __commonJS({
|
|
|
155004
155086
|
}
|
|
155005
155087
|
});
|
|
155006
155088
|
|
|
155007
|
-
// ../system/dist/child-cap-dispatch-
|
|
155008
|
-
var
|
|
155009
|
-
"../system/dist/child-cap-dispatch-
|
|
155089
|
+
// ../system/dist/child-cap-dispatch-CRqYKHAb.js
|
|
155090
|
+
var require_child_cap_dispatch_CRqYKHAb = __commonJS({
|
|
155091
|
+
"../system/dist/child-cap-dispatch-CRqYKHAb.js"(exports) {
|
|
155010
155092
|
"use strict";
|
|
155011
155093
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
155012
|
-
var require_dist10 =
|
|
155094
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
155013
155095
|
var require_proc_stat = require_proc_stat_DL_WUOhl();
|
|
155014
155096
|
require_hub_cap_forward_DmHNjbB0();
|
|
155015
155097
|
var node_crypto = __require("crypto");
|
|
@@ -169548,7 +169630,7 @@ var require_dist3 = __commonJS({
|
|
|
169548
169630
|
"use strict";
|
|
169549
169631
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
169550
169632
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
169551
|
-
var require_dist10 =
|
|
169633
|
+
var require_dist10 = require_dist_DePB7uwU();
|
|
169552
169634
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
169553
169635
|
require_alerts();
|
|
169554
169636
|
var require_builtins_calendars_calendars_addon = require_calendars_addon();
|
|
@@ -169579,7 +169661,7 @@ var require_dist3 = __commonJS({
|
|
|
169579
169661
|
var require_builtins_winston_logging_index = require_winston_logging();
|
|
169580
169662
|
var require_event_loop_stall_monitor = require_event_loop_stall_monitor_ey4mbofz();
|
|
169581
169663
|
var require_tls$1 = require_tls_ue_Xefmv();
|
|
169582
|
-
var require_child_cap_dispatch =
|
|
169664
|
+
var require_child_cap_dispatch = require_child_cap_dispatch_CRqYKHAb();
|
|
169583
169665
|
var require_resource_monitor = require_resource_monitor_BgWGRxN5();
|
|
169584
169666
|
var require_custom_action_registry = require_custom_action_registry_acBY3mHA();
|
|
169585
169667
|
var zod = require_zod();
|
|
@@ -169894,6 +169976,29 @@ var require_dist3 = __commonJS({
|
|
|
169894
169976
|
function canServeDataPlane(state) {
|
|
169895
169977
|
return state.hasEntry && state.isForked && state.childKnown;
|
|
169896
169978
|
}
|
|
169979
|
+
function edgeOwnedResponseHeaders(upRes, clientRes) {
|
|
169980
|
+
const out = {};
|
|
169981
|
+
for (const [name2, value] of Object.entries(upRes.headers)) {
|
|
169982
|
+
if (value === void 0) continue;
|
|
169983
|
+
const lower = name2.toLowerCase();
|
|
169984
|
+
if (lower.startsWith("access-control-")) continue;
|
|
169985
|
+
out[lower] = value;
|
|
169986
|
+
}
|
|
169987
|
+
const edgeVary = clientRes.getHeader("vary");
|
|
169988
|
+
const upVary = out["vary"];
|
|
169989
|
+
if (typeof edgeVary === "string" && edgeVary.length > 0 && upVary !== void 0) {
|
|
169990
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
169991
|
+
const merged = [];
|
|
169992
|
+
for (const part of [edgeVary, String(upVary)].join(",").split(",")) {
|
|
169993
|
+
const token2 = part.trim();
|
|
169994
|
+
if (token2.length === 0 || tokens.has(token2.toLowerCase())) continue;
|
|
169995
|
+
tokens.add(token2.toLowerCase());
|
|
169996
|
+
merged.push(token2);
|
|
169997
|
+
}
|
|
169998
|
+
out["vary"] = merged.join(", ");
|
|
169999
|
+
}
|
|
170000
|
+
return out;
|
|
170001
|
+
}
|
|
169897
170002
|
function proxyToUpstream(opts) {
|
|
169898
170003
|
const { baseUrl, secret, upstreamPath, clientReq, clientRes, replayBody } = opts;
|
|
169899
170004
|
const base = new URL(baseUrl);
|
|
@@ -169911,17 +170016,11 @@ var require_dist3 = __commonJS({
|
|
|
169911
170016
|
path: upstreamPath,
|
|
169912
170017
|
headers
|
|
169913
170018
|
}, (upRes) => {
|
|
169914
|
-
clientRes.writeHead(upRes.statusCode ?? 502,
|
|
169915
|
-
"access-control-allow-origin": "*",
|
|
169916
|
-
...upRes.headers
|
|
169917
|
-
});
|
|
170019
|
+
clientRes.writeHead(upRes.statusCode ?? 502, edgeOwnedResponseHeaders(upRes, clientRes));
|
|
169918
170020
|
upRes.pipe(clientRes);
|
|
169919
170021
|
});
|
|
169920
170022
|
upstream.on("error", (err) => {
|
|
169921
|
-
if (!clientRes.headersSent) clientRes.writeHead(502, {
|
|
169922
|
-
"content-type": "application/json",
|
|
169923
|
-
"access-control-allow-origin": "*"
|
|
169924
|
-
});
|
|
170023
|
+
if (!clientRes.headersSent) clientRes.writeHead(502, { "content-type": "application/json" });
|
|
169925
170024
|
clientRes.end(JSON.stringify({
|
|
169926
170025
|
error: "data-plane upstream error",
|
|
169927
170026
|
detail: String(err)
|
|
@@ -176159,10 +176258,19 @@ var require_dist3 = __commonJS({
|
|
|
176159
176258
|
};
|
|
176160
176259
|
}
|
|
176161
176260
|
var DEFAULT_DATA_PATH = "camstack-data";
|
|
176261
|
+
var originListSchema = zod.z.preprocess((value) => typeof value === "string" ? value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0) : value, zod.z.array(zod.z.string()));
|
|
176162
176262
|
var serverSchema = zod.z.object({
|
|
176163
176263
|
port: zod.z.number().default(4443),
|
|
176164
176264
|
host: zod.z.string().default("0.0.0.0"),
|
|
176165
|
-
dataPath: zod.z.string().default(DEFAULT_DATA_PATH)
|
|
176265
|
+
dataPath: zod.z.string().default(DEFAULT_DATA_PATH),
|
|
176266
|
+
/**
|
|
176267
|
+
* EXTRA browser origins allowed to call this hub cross-origin (D707), on
|
|
176268
|
+
* top of the built-ins: the hub's own origin, the hosted viewer PWA and the
|
|
176269
|
+
* native app's opaque `null` origin. Bootstrap-owned on purpose — widening
|
|
176270
|
+
* who may read hub responses in a browser is a security decision, and the
|
|
176271
|
+
* policy is live from the first request, before the settings store exists.
|
|
176272
|
+
*/
|
|
176273
|
+
corsOrigins: originListSchema.default([])
|
|
176166
176274
|
});
|
|
176167
176275
|
var authSchema = zod.z.object({
|
|
176168
176276
|
jwtSecret: zod.z.string().nullable().default(null),
|
|
@@ -178632,7 +178740,8 @@ var require_dist3 = __commonJS({
|
|
|
178632
178740
|
CAMSTACK_DATA: "server.dataPath",
|
|
178633
178741
|
CAMSTACK_JWT_SECRET: "auth.jwtSecret",
|
|
178634
178742
|
CAMSTACK_ADMIN_USER: "auth.adminUsername",
|
|
178635
|
-
CAMSTACK_ADMIN_PASS: "auth.adminPassword"
|
|
178743
|
+
CAMSTACK_ADMIN_PASS: "auth.adminPassword",
|
|
178744
|
+
CAMSTACK_CORS_ORIGINS: "server.corsOrigins"
|
|
178636
178745
|
};
|
|
178637
178746
|
function loadBootstrapConfig(configPath) {
|
|
178638
178747
|
const merged = applyEnvOverrides((0, _camstack_types_addon.asJsonObject)(loadYaml(configPath)) ?? {});
|
|
@@ -254255,7 +254364,7 @@ var require_dist4 = __commonJS({
|
|
|
254255
254364
|
}
|
|
254256
254365
|
function variantLabel(precision, optimization) {
|
|
254257
254366
|
const parts = [];
|
|
254258
|
-
if (optimization === "
|
|
254367
|
+
if (optimization === "test") parts.push("Test");
|
|
254259
254368
|
parts.push(precision === "int8" ? "Int8" : "Standard");
|
|
254260
254369
|
return parts.join(" \xB7 ");
|
|
254261
254370
|
}
|
|
@@ -254305,7 +254414,7 @@ var require_dist4 = __commonJS({
|
|
|
254305
254414
|
};
|
|
254306
254415
|
}).toSorted((a, b) => {
|
|
254307
254416
|
if (a.resolution !== b.resolution) return (b.resolution ?? Infinity) - (a.resolution ?? Infinity);
|
|
254308
|
-
if (a.optimization !== b.optimization) return a.optimization === "
|
|
254417
|
+
if (a.optimization !== b.optimization) return a.optimization === "test" ? 1 : -1;
|
|
254309
254418
|
return PRECISION_ORDER.indexOf(a.precision) - PRECISION_ORDER.indexOf(b.precision);
|
|
254310
254419
|
});
|
|
254311
254420
|
const base = options.find((o) => o.precision === "fp32" && o.optimization === "standard") ?? options[0];
|
|
@@ -254441,11 +254550,11 @@ var require_dist4 = __commonJS({
|
|
|
254441
254550
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
254442
254551
|
precision: zod.z.enum(["fp32", "int8"]).optional(),
|
|
254443
254552
|
/**
|
|
254444
|
-
*
|
|
254445
|
-
*
|
|
254446
|
-
*
|
|
254553
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
254554
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
254555
|
+
* label is "Test".
|
|
254447
254556
|
*/
|
|
254448
|
-
optimization: zod.z.enum(["standard", "
|
|
254557
|
+
optimization: zod.z.enum(["standard", "test"]).optional(),
|
|
254449
254558
|
/**
|
|
254450
254559
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
254451
254560
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -263788,7 +263897,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
263788
263897
|
}) }
|
|
263789
263898
|
};
|
|
263790
263899
|
var ModelDistributeInputSchema = zod.z.object({
|
|
263791
|
-
|
|
263900
|
+
targetNodeId: zod.z.string(),
|
|
263792
263901
|
modelId: zod.z.string(),
|
|
263793
263902
|
format: zod.z.enum(MODEL_FORMATS),
|
|
263794
263903
|
entry: ModelCatalogEntrySchema
|
|
@@ -266149,6 +266258,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
266149
266258
|
"detection-blind",
|
|
266150
266259
|
"nodes",
|
|
266151
266260
|
"addons",
|
|
266261
|
+
"addon-updates",
|
|
266152
266262
|
"updates"
|
|
266153
266263
|
]);
|
|
266154
266264
|
var NcStateSummaryPreviewSectionSchema = zod.z.object({
|
|
@@ -267071,7 +267181,19 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
267071
267181
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
267072
267182
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
267073
267183
|
*/
|
|
267074
|
-
schedule: NcScheduleSchema.optional()
|
|
267184
|
+
schedule: NcScheduleSchema.optional(),
|
|
267185
|
+
/**
|
|
267186
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
267187
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
267188
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
267189
|
+
*/
|
|
267190
|
+
notifyDuringEntryDelay: zod.z.boolean().optional(),
|
|
267191
|
+
/**
|
|
267192
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
267193
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
267194
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
267195
|
+
*/
|
|
267196
|
+
notifySensorRewatched: zod.z.boolean().optional()
|
|
267075
267197
|
});
|
|
267076
267198
|
var NcAlarmModeDelaysListSchema = zod.z.array(NcAlarmModeDelaysSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
267077
267199
|
var NcAlarmModeDelaysEditSchema = zod.z.object({
|
|
@@ -267081,7 +267203,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
267081
267203
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
267082
267204
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
267083
267205
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
267084
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
267206
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
267207
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
267208
|
+
notifyDuringEntryDelay: zod.z.boolean().nullable().optional(),
|
|
267209
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
267210
|
+
notifySensorRewatched: zod.z.boolean().nullable().optional()
|
|
267085
267211
|
});
|
|
267086
267212
|
var NcAlarmModeDelaysEditListSchema = zod.z.array(NcAlarmModeDelaysEditSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
267087
267213
|
var NcAlarmNonBlockingEditSchema = zod.z.object({
|
|
@@ -267939,39 +268065,19 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
267939
268065
|
label: "Face recognition model",
|
|
267940
268066
|
defaultModelId: "auraface-r100",
|
|
267941
268067
|
indexName: "the enrolled face gallery",
|
|
267942
|
-
options: [
|
|
267943
|
-
|
|
267944
|
-
|
|
267945
|
-
|
|
267946
|
-
},
|
|
267947
|
-
{
|
|
267948
|
-
id: "arcface-r100",
|
|
267949
|
-
label: "ArcFace (ResNet34)"
|
|
267950
|
-
},
|
|
267951
|
-
{
|
|
267952
|
-
id: "inception-resnet-v1",
|
|
267953
|
-
label: "Inception ResNet V1"
|
|
267954
|
-
}
|
|
267955
|
-
]
|
|
268068
|
+
options: [{
|
|
268069
|
+
id: "auraface-r100",
|
|
268070
|
+
label: "AuraFace R100"
|
|
268071
|
+
}]
|
|
267956
268072
|
}, {
|
|
267957
268073
|
stepId: "clip-embedding",
|
|
267958
268074
|
label: "Semantic search model",
|
|
267959
|
-
defaultModelId: "
|
|
268075
|
+
defaultModelId: "siglip2-b16-224",
|
|
267960
268076
|
indexName: "the object semantic-search index",
|
|
267961
|
-
options: [
|
|
267962
|
-
|
|
267963
|
-
|
|
267964
|
-
|
|
267965
|
-
},
|
|
267966
|
-
{
|
|
267967
|
-
id: "mobileclip-s2",
|
|
267968
|
-
label: "MobileCLIP S2"
|
|
267969
|
-
},
|
|
267970
|
-
{
|
|
267971
|
-
id: "siglip2-b16-224",
|
|
267972
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
267973
|
-
}
|
|
267974
|
-
]
|
|
268077
|
+
options: [{
|
|
268078
|
+
id: "siglip2-b16-224",
|
|
268079
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
268080
|
+
}]
|
|
267975
268081
|
}];
|
|
267976
268082
|
var CLUSTER_MODEL_SECTION_ID = "cluster-step-models";
|
|
267977
268083
|
function clusterModelSettingKey(stepId) {
|
|
@@ -271188,6 +271294,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
271188
271294
|
"analyzer",
|
|
271189
271295
|
"device-activity"
|
|
271190
271296
|
]);
|
|
271297
|
+
var SessionTriggerSchema = zod.z.object({
|
|
271298
|
+
source: MotionSourceEnum,
|
|
271299
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
271300
|
+
sensorName: zod.z.string().optional()
|
|
271301
|
+
});
|
|
271191
271302
|
var MotionSourcesSchema = zod.z.array(MotionSourceEnum);
|
|
271192
271303
|
var MOTION_SOURCE_LABELS = {
|
|
271193
271304
|
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
@@ -271339,6 +271450,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
271339
271450
|
*/
|
|
271340
271451
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
271341
271452
|
/**
|
|
271453
|
+
* What opened this attach, on a SESSION attach only (see
|
|
271454
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
271455
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
271456
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
271457
|
+
* runner then names no source on the phase event.
|
|
271458
|
+
*/
|
|
271459
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
271460
|
+
/**
|
|
271342
271461
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
271343
271462
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
271344
271463
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -275351,6 +275470,94 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
275351
275470
|
rates: CLIP_BROKER_PACED_RATES
|
|
275352
275471
|
}
|
|
275353
275472
|
};
|
|
275473
|
+
var CAMSTACK_APP_LINK_ORIGIN = "https://camstack.zentik.app";
|
|
275474
|
+
var HUB_VIEWER_MOUNT = "/viewer/camstack";
|
|
275475
|
+
function isAppLinkBase(baseUrl) {
|
|
275476
|
+
if (baseUrl === null || baseUrl === void 0 || baseUrl === "") return false;
|
|
275477
|
+
try {
|
|
275478
|
+
return new URL(baseUrl).origin === CAMSTACK_APP_LINK_ORIGIN;
|
|
275479
|
+
} catch {
|
|
275480
|
+
return false;
|
|
275481
|
+
}
|
|
275482
|
+
}
|
|
275483
|
+
function viewerLinkBaseOf(endpoint) {
|
|
275484
|
+
const flagged = endpoint.baseUrl ?? endpoint.resolved;
|
|
275485
|
+
return isAppLinkBase(flagged) ? {
|
|
275486
|
+
form: "app",
|
|
275487
|
+
hubBaseUrl: endpoint.appLinkHub ?? null
|
|
275488
|
+
} : {
|
|
275489
|
+
form: "hub",
|
|
275490
|
+
hubBaseUrl: flagged
|
|
275491
|
+
};
|
|
275492
|
+
}
|
|
275493
|
+
function toAppLinkHubOrigin(baseUrl) {
|
|
275494
|
+
let parsed;
|
|
275495
|
+
try {
|
|
275496
|
+
parsed = new URL(baseUrl);
|
|
275497
|
+
} catch {
|
|
275498
|
+
return null;
|
|
275499
|
+
}
|
|
275500
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
|
|
275501
|
+
if (parsed.username !== "" || parsed.password !== "") return null;
|
|
275502
|
+
if (parsed.hostname === "") return null;
|
|
275503
|
+
return parsed.origin;
|
|
275504
|
+
}
|
|
275505
|
+
function pickAppLinkHub(endpoints) {
|
|
275506
|
+
const rank2 = (e) => {
|
|
275507
|
+
if (e.kind !== "public" || !e.baseUrl.startsWith("https://")) return null;
|
|
275508
|
+
if (e.interfaceKind === "public") return 0;
|
|
275509
|
+
if (e.interfaceKind === "vpn") return 1;
|
|
275510
|
+
return null;
|
|
275511
|
+
};
|
|
275512
|
+
return endpoints.flatMap((e) => {
|
|
275513
|
+
const r = rank2(e);
|
|
275514
|
+
const origin = toAppLinkHubOrigin(e.baseUrl);
|
|
275515
|
+
return r === null || origin === null ? [] : [{
|
|
275516
|
+
r,
|
|
275517
|
+
p: e.priority,
|
|
275518
|
+
origin
|
|
275519
|
+
}];
|
|
275520
|
+
}).toSorted((a, b) => a.r - b.r || a.p - b.p)[0]?.origin ?? null;
|
|
275521
|
+
}
|
|
275522
|
+
function viewerRoute(destination) {
|
|
275523
|
+
switch (destination.kind) {
|
|
275524
|
+
case "camera": {
|
|
275525
|
+
if (!Number.isInteger(destination.deviceId) || destination.deviceId <= 0) return null;
|
|
275526
|
+
const at = destination.atMs;
|
|
275527
|
+
return {
|
|
275528
|
+
path: `/camera/${String(destination.deviceId)}`,
|
|
275529
|
+
query: at !== void 0 && Number.isFinite(at) ? [["at", String(Math.trunc(at))]] : []
|
|
275530
|
+
};
|
|
275531
|
+
}
|
|
275532
|
+
case "events":
|
|
275533
|
+
return {
|
|
275534
|
+
path: "/events",
|
|
275535
|
+
query: []
|
|
275536
|
+
};
|
|
275537
|
+
case "notifications":
|
|
275538
|
+
return {
|
|
275539
|
+
path: "/notifications",
|
|
275540
|
+
query: []
|
|
275541
|
+
};
|
|
275542
|
+
}
|
|
275543
|
+
}
|
|
275544
|
+
function encodeQuery(query) {
|
|
275545
|
+
if (query.length === 0) return "";
|
|
275546
|
+
return `?${query.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&")}`;
|
|
275547
|
+
}
|
|
275548
|
+
function buildViewerLink(input) {
|
|
275549
|
+
const route = viewerRoute(input.destination);
|
|
275550
|
+
if (route === null) return null;
|
|
275551
|
+
const raw = input.base.hubBaseUrl;
|
|
275552
|
+
const base = raw === null ? "" : raw.replace(/\/+$/, "");
|
|
275553
|
+
if (input.base.form === "app") {
|
|
275554
|
+
const origin = base === "" ? null : toAppLinkHubOrigin(base);
|
|
275555
|
+
const query = origin === null ? route.query : [...route.query, ["hub", origin]];
|
|
275556
|
+
return `${CAMSTACK_APP_LINK_ORIGIN}${route.path}${encodeQuery(query)}`;
|
|
275557
|
+
}
|
|
275558
|
+
if (base === "" || isAppLinkBase(base)) return null;
|
|
275559
|
+
return `${base}${HUB_VIEWER_MOUNT}${route.path}${encodeQuery(route.query)}`;
|
|
275560
|
+
}
|
|
275354
275561
|
var webrtcClientHintsSchema = zod.z.object({
|
|
275355
275562
|
viewportWidth: zod.z.number().int().positive().optional(),
|
|
275356
275563
|
viewportHeight: zod.z.number().int().positive().optional(),
|
|
@@ -279212,7 +279419,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
279212
279419
|
name: zod.z.string(),
|
|
279213
279420
|
family: zod.z.enum(["IPv4", "IPv6"]),
|
|
279214
279421
|
address: zod.z.string(),
|
|
279215
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
279422
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
279216
279423
|
cidr: zod.z.string(),
|
|
279217
279424
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
279218
279425
|
netmask: zod.z.string(),
|
|
@@ -279261,7 +279468,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
279261
279468
|
"lan-ipv4",
|
|
279262
279469
|
"lan-ipv6",
|
|
279263
279470
|
"public",
|
|
279264
|
-
"loopback"
|
|
279471
|
+
"loopback",
|
|
279472
|
+
"app-link"
|
|
279265
279473
|
]),
|
|
279266
279474
|
/**
|
|
279267
279475
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -279326,8 +279534,20 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
279326
279534
|
var NotificationEndpointSchema = zod.z.object({
|
|
279327
279535
|
/** The operator's explicit choice, or null for AUTO. */
|
|
279328
279536
|
baseUrl: zod.z.string().nullable(),
|
|
279329
|
-
/**
|
|
279330
|
-
|
|
279537
|
+
/**
|
|
279538
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
279539
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
279540
|
+
* answered the public tunnel / mesh here, or null.
|
|
279541
|
+
*/
|
|
279542
|
+
resolved: zod.z.string().nullable(),
|
|
279543
|
+
/**
|
|
279544
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
279545
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
279546
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
279547
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
279548
|
+
* Absent on a pre-D709 hub.
|
|
279549
|
+
*/
|
|
279550
|
+
appLinkHub: zod.z.string().nullable()
|
|
279331
279551
|
});
|
|
279332
279552
|
var ViewerEndpointsSchema = zod.z.object({
|
|
279333
279553
|
/** The operator's explicit race set, or empty for AUTO. */
|
|
@@ -279391,7 +279611,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
279391
279611
|
* every client a second authority on a socket only the hub binds. A viewer
|
|
279392
279612
|
* configured with a port-less public URL (`https://camstack.example.top`)
|
|
279393
279613
|
* infers 443 from the scheme, asks with 443, and was handed
|
|
279394
|
-
* `https://192.168.
|
|
279614
|
+
* `https://192.168.10.9:443` for a hub listening on 4443. That candidate
|
|
279395
279615
|
* cannot ever answer, and losing its race reads in the log exactly like
|
|
279396
279616
|
* "the LAN was tried and it was slower" — so an operator sitting on his own
|
|
279397
279617
|
* WiFi stayed on the public tunnel for weeks, with the LAN candidate born
|
|
@@ -279424,13 +279644,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
279424
279644
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
279425
279645
|
* to avoid mixed-content blocks in the browser. The public
|
|
279426
279646
|
* tunnel always emits `https://` regardless. */
|
|
279427
|
-
scheme: zod.z.enum(["http", "https"]).optional()
|
|
279647
|
+
scheme: zod.z.enum(["http", "https"]).optional(),
|
|
279648
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
279649
|
+
* an address notification links can be flagged with, not a hub
|
|
279650
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
279651
|
+
includeAppLink: zod.z.boolean().optional()
|
|
279428
279652
|
}), GetConnectionEndpointsResultSchema),
|
|
279429
279653
|
/**
|
|
279430
|
-
* The
|
|
279431
|
-
*
|
|
279432
|
-
*
|
|
279433
|
-
*
|
|
279654
|
+
* The address notification links are flagged with. `baseUrl: null` means
|
|
279655
|
+
* AUTO, which is the CamStack app link (D709): viewer taps go through
|
|
279656
|
+
* `https://camstack.zentik.app/…?hub=<appLinkHub>` and open the app. Any
|
|
279657
|
+
* hub address the palette lists can be flagged instead; then viewer taps,
|
|
279658
|
+
* attachment links and action buttons all use it. Signed media and
|
|
279659
|
+
* buttons never use the app link — with it flagged (or AUTO) they keep
|
|
279660
|
+
* the ranked hub ladder (a configured origin, a connected tunnel, then
|
|
279661
|
+
* the LAN), never loopback.
|
|
279434
279662
|
*
|
|
279435
279663
|
* Why an explicit marker: the automatic ranking cannot know which of
|
|
279436
279664
|
* several reachable addresses the RECIPIENT can actually open. A link is
|
|
@@ -279789,7 +280017,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
279789
280017
|
tags: zod.z.array(zod.z.string()).readonly(),
|
|
279790
280018
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
279791
280019
|
exitNodeOption: zod.z.boolean(),
|
|
279792
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
280020
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
279793
280021
|
advertisedRoutes: zod.z.array(zod.z.string()).readonly(),
|
|
279794
280022
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
279795
280023
|
userLogin: zod.z.string().nullable(),
|
|
@@ -281077,7 +281305,13 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
281077
281305
|
*/
|
|
281078
281306
|
availablePositions: zod.z.array(OsdPositionEnum).readonly(),
|
|
281079
281307
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
281080
|
-
readOnly: zod.z.boolean().optional()
|
|
281308
|
+
readOnly: zod.z.boolean().optional(),
|
|
281309
|
+
/**
|
|
281310
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
281311
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
281312
|
+
* copy on the binding.
|
|
281313
|
+
*/
|
|
281314
|
+
maxCharacters: zod.z.number().int().positive().optional()
|
|
281081
281315
|
});
|
|
281082
281316
|
var OsdStatusSchema = zod.z.object({ overlays: zod.z.array(OsdOverlaySchema).readonly() });
|
|
281083
281317
|
var OsdOverlayPatchSchema = zod.z.object({
|
|
@@ -281165,7 +281399,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
281165
281399
|
valuePath: zod.z.string().min(1).max(64),
|
|
281166
281400
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
281167
281401
|
displayUnit: zod.z.string().max(16).optional(),
|
|
281168
|
-
maxDecimals: zod.z.number().int().min(0).max(4).default(1)
|
|
281402
|
+
maxDecimals: zod.z.number().int().min(0).max(4).default(1),
|
|
281403
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
281404
|
+
valueMap: zod.z.record(zod.z.string(), zod.z.string()).optional()
|
|
281169
281405
|
});
|
|
281170
281406
|
var OsdNamedTemplateSchema = zod.z.object({
|
|
281171
281407
|
id: zod.z.string().min(1).max(64),
|
|
@@ -281210,18 +281446,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
281210
281446
|
source: OsdSourceSchema,
|
|
281211
281447
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
281212
281448
|
template: zod.z.string().max(96).default("${value}"),
|
|
281213
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
281214
|
-
maxCharacters: zod.z.number().int().min(4).max(64).optional(),
|
|
281215
281449
|
/**
|
|
281216
281450
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
281217
281451
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
281218
281452
|
*/
|
|
281219
281453
|
maxDecimals: zod.z.number().int().min(0).max(4).default(1),
|
|
281220
|
-
/**
|
|
281221
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
281222
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
281223
|
-
*/
|
|
281224
|
-
unitLabel: zod.z.string().max(8).optional(),
|
|
281225
281454
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
281226
281455
|
valueMap: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
281227
281456
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -281230,9 +281459,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
281230
281459
|
* Display gate, in the notification centre's condition vocabulary.
|
|
281231
281460
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
281232
281461
|
*/
|
|
281233
|
-
conditions: NcConditionsSchema.optional()
|
|
281234
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
281235
|
-
fallbackText: zod.z.string().max(64).default("")
|
|
281462
|
+
conditions: NcConditionsSchema.optional()
|
|
281236
281463
|
});
|
|
281237
281464
|
var OsdSlotViewSchema = zod.z.object({
|
|
281238
281465
|
slotId: zod.z.string(),
|
|
@@ -305299,12 +305526,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
305299
305526
|
{
|
|
305300
305527
|
id: "addons",
|
|
305301
305528
|
family: "system",
|
|
305302
|
-
label: "Addons",
|
|
305303
|
-
kinds: [
|
|
305304
|
-
|
|
305305
|
-
|
|
305306
|
-
|
|
305307
|
-
|
|
305529
|
+
label: "Addons stopped",
|
|
305530
|
+
kinds: ["addon-crash-loop"]
|
|
305531
|
+
},
|
|
305532
|
+
{
|
|
305533
|
+
id: "addon-updates",
|
|
305534
|
+
family: "system",
|
|
305535
|
+
label: "Addon updates",
|
|
305536
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
305308
305537
|
},
|
|
305309
305538
|
{
|
|
305310
305539
|
id: "updates",
|
|
@@ -305914,6 +306143,15 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
305914
306143
|
"entryDelaySec",
|
|
305915
306144
|
"triggeredDurationSec"
|
|
305916
306145
|
];
|
|
306146
|
+
var NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = 30;
|
|
306147
|
+
var NC_ALARM_NOTIFY_FIELDS = ["notifyDuringEntryDelay", "notifySensorRewatched"];
|
|
306148
|
+
function resolveModeNotifyPolicy(settings, mode) {
|
|
306149
|
+
const entry = (settings.modeDelays ?? []).find((e) => e.mode === mode);
|
|
306150
|
+
return {
|
|
306151
|
+
notifyDuringEntryDelay: entry?.notifyDuringEntryDelay === true,
|
|
306152
|
+
notifySensorRewatched: entry?.notifySensorRewatched === true
|
|
306153
|
+
};
|
|
306154
|
+
}
|
|
305917
306155
|
function derivePostTriggeredAction(action, triggeredDurationSec) {
|
|
305918
306156
|
if (action !== void 0) return action;
|
|
305919
306157
|
return triggeredDurationSec > 0 ? "rearmAfter" : "doNothing";
|
|
@@ -305956,6 +306194,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
305956
306194
|
if (edit === void 0) return current;
|
|
305957
306195
|
return edit === null ? void 0 : edit;
|
|
305958
306196
|
}
|
|
306197
|
+
function editedFlag(current, edit) {
|
|
306198
|
+
if (edit === void 0) return current;
|
|
306199
|
+
return edit === null ? void 0 : edit;
|
|
306200
|
+
}
|
|
305959
306201
|
function editedSchedule(current, edit) {
|
|
305960
306202
|
if (edit === void 0) return current;
|
|
305961
306203
|
return edit === null ? void 0 : edit;
|
|
@@ -305986,15 +306228,19 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
305986
306228
|
const triggered = edited(base.triggeredDurationSec, edit.triggeredDurationSec);
|
|
305987
306229
|
const action = editedAction(base.postTriggeredAction, edit.postTriggeredAction);
|
|
305988
306230
|
const schedule = editedSchedule(base.schedule, edit.schedule);
|
|
306231
|
+
const duringEntry = editedFlag(base.notifyDuringEntryDelay, edit.notifyDuringEntryDelay);
|
|
306232
|
+
const rewatched = editedFlag(base.notifySensorRewatched, edit.notifySensorRewatched);
|
|
305989
306233
|
if (exit !== void 0) next.exitDelaySec = exit;
|
|
305990
306234
|
if (entry !== void 0) next.entryDelaySec = entry;
|
|
305991
306235
|
if (triggered !== void 0) next.triggeredDurationSec = triggered;
|
|
305992
306236
|
if (action !== void 0) next.postTriggeredAction = action;
|
|
305993
306237
|
if (schedule !== void 0) next.schedule = schedule;
|
|
306238
|
+
if (duringEntry !== void 0) next.notifyDuringEntryDelay = duringEntry;
|
|
306239
|
+
if (rewatched !== void 0) next.notifySensorRewatched = rewatched;
|
|
305994
306240
|
if (at >= 0) out[at] = next;
|
|
305995
306241
|
else out.push(next);
|
|
305996
306242
|
}
|
|
305997
|
-
return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0 || e.postTriggeredAction !== void 0 || e.schedule !== void 0);
|
|
306243
|
+
return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0 || e.postTriggeredAction !== void 0 || e.schedule !== void 0 || e.notifyDuringEntryDelay !== void 0 || e.notifySensorRewatched !== void 0);
|
|
305998
306244
|
}
|
|
305999
306245
|
function applyModeDeviceListEdit(lists, edit) {
|
|
306000
306246
|
const copy2 = lists.map((l) => ({
|
|
@@ -306121,6 +306367,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
306121
306367
|
const got = entry?.postTriggeredAction;
|
|
306122
306368
|
if (edit.postTriggeredAction === null ? got !== void 0 : got !== edit.postTriggeredAction) return false;
|
|
306123
306369
|
}
|
|
306370
|
+
for (const field of NC_ALARM_NOTIFY_FIELDS) {
|
|
306371
|
+
const want = edit[field];
|
|
306372
|
+
if (want === void 0) continue;
|
|
306373
|
+
const got = entry?.[field];
|
|
306374
|
+
if (want === null ? got !== void 0 : got !== want) return false;
|
|
306375
|
+
}
|
|
306124
306376
|
if (edit.schedule !== void 0) {
|
|
306125
306377
|
const got = entry?.schedule;
|
|
306126
306378
|
if (edit.schedule === null ? got !== void 0 : !sameSchedule(got, edit.schedule)) return false;
|
|
@@ -306459,13 +306711,15 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
306459
306711
|
},
|
|
306460
306712
|
{
|
|
306461
306713
|
name: "summaryAddons",
|
|
306462
|
-
label: "Summary: addons",
|
|
306463
|
-
example: "
|
|
306464
|
-
kinds: [
|
|
306465
|
-
|
|
306466
|
-
|
|
306467
|
-
|
|
306468
|
-
|
|
306714
|
+
label: "Summary: addons stopped",
|
|
306715
|
+
example: "hub \u2014 recorder stopped after repeated crashes",
|
|
306716
|
+
kinds: ["addon-crash-loop"]
|
|
306717
|
+
},
|
|
306718
|
+
{
|
|
306719
|
+
name: "summaryAddonUpdates",
|
|
306720
|
+
label: "Summary: addon updates",
|
|
306721
|
+
example: "hub:\n\u2022 @camstack/addon-recorder 1.2.3 \u2192 1.2.4",
|
|
306722
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
306469
306723
|
},
|
|
306470
306724
|
{
|
|
306471
306725
|
name: "summaryUpdates",
|
|
@@ -306806,6 +307060,16 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
306806
307060
|
kinds: ["system"],
|
|
306807
307061
|
systemEventKinds: [...DEVICE_EVENTS]
|
|
306808
307062
|
},
|
|
307063
|
+
{
|
|
307064
|
+
name: "locations",
|
|
307065
|
+
label: "Intrusion locations",
|
|
307066
|
+
example: "Ingresso, Corridoio, Salone",
|
|
307067
|
+
group: "system",
|
|
307068
|
+
families: ["rule"],
|
|
307069
|
+
fields: [...RULE_TEXT],
|
|
307070
|
+
kinds: ["system"],
|
|
307071
|
+
systemEventKinds: [...COMBINED_ALARM]
|
|
307072
|
+
},
|
|
306809
307073
|
{
|
|
306810
307074
|
name: "deviceId",
|
|
306811
307075
|
label: "Device id",
|
|
@@ -306895,7 +307159,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
306895
307159
|
{
|
|
306896
307160
|
name: "devices",
|
|
306897
307161
|
label: "Devices",
|
|
306898
|
-
description: "node-inference-unavailable: the affected cameras, comma-joined. Alarm arm / refusal: HOW MANY devices are armed (or open).",
|
|
307162
|
+
description: "node-inference-unavailable: the affected cameras, comma-joined. Alarm arm / arming / refusal: HOW MANY devices are armed (or open).",
|
|
306899
307163
|
example: "Ingresso, Garage",
|
|
306900
307164
|
group: "system",
|
|
306901
307165
|
families: ["rule"],
|
|
@@ -306904,6 +307168,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
306904
307168
|
systemEventKinds: [
|
|
306905
307169
|
"node-inference-unavailable",
|
|
306906
307170
|
"alarm-armed",
|
|
307171
|
+
"alarm-arming",
|
|
306907
307172
|
"alarm-arm-refused"
|
|
306908
307173
|
]
|
|
306909
307174
|
},
|
|
@@ -307124,18 +307389,18 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
307124
307389
|
{
|
|
307125
307390
|
name: "rules",
|
|
307126
307391
|
label: "Covering rules",
|
|
307127
|
-
description: "How many enabled rules the armed mode gates.",
|
|
307392
|
+
description: "How many enabled rules the armed / arming mode gates.",
|
|
307128
307393
|
example: "2",
|
|
307129
307394
|
group: "system",
|
|
307130
307395
|
families: ["rule"],
|
|
307131
307396
|
fields: [...RULE_TEXT],
|
|
307132
307397
|
kinds: ["system"],
|
|
307133
|
-
systemEventKinds: ["alarm-armed"]
|
|
307398
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
307134
307399
|
},
|
|
307135
307400
|
{
|
|
307136
307401
|
name: "names",
|
|
307137
307402
|
label: "Device names",
|
|
307138
|
-
description: "Armed: the devices
|
|
307403
|
+
description: "Armed / arming: the Active devices (or every skipped name when none are Active). Refusal: the open sensors.",
|
|
307139
307404
|
example: "Ingresso, Garage",
|
|
307140
307405
|
group: "system",
|
|
307141
307406
|
families: ["rule"],
|
|
@@ -307156,7 +307421,29 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
307156
307421
|
families: ["rule"],
|
|
307157
307422
|
fields: [...RULE_TEXT],
|
|
307158
307423
|
kinds: ["system"],
|
|
307159
|
-
systemEventKinds: ["alarm-armed"]
|
|
307424
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
307425
|
+
},
|
|
307426
|
+
{
|
|
307427
|
+
name: "active",
|
|
307428
|
+
label: "Active count",
|
|
307429
|
+
description: "How many named devices the armed / arming mode is watching (title: n attivi / n active).",
|
|
307430
|
+
example: "3",
|
|
307431
|
+
group: "system",
|
|
307432
|
+
families: ["rule"],
|
|
307433
|
+
fields: [...RULE_TEXT],
|
|
307434
|
+
kinds: ["system"],
|
|
307435
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
307436
|
+
},
|
|
307437
|
+
{
|
|
307438
|
+
name: "skipped",
|
|
307439
|
+
label: "Skipped count",
|
|
307440
|
+
description: "How many named devices the mode cannot arm \u2014 muted, detection off, offline (title: m saltati).",
|
|
307441
|
+
example: "1",
|
|
307442
|
+
group: "system",
|
|
307443
|
+
families: ["rule"],
|
|
307444
|
+
fields: [...RULE_TEXT],
|
|
307445
|
+
kinds: ["system"],
|
|
307446
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
307160
307447
|
},
|
|
307161
307448
|
{
|
|
307162
307449
|
name: "bypassedNames",
|
|
@@ -307405,7 +307692,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
307405
307692
|
approximated: times.length > 0
|
|
307406
307693
|
};
|
|
307407
307694
|
}
|
|
307408
|
-
var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|Updates)\s*\}\}/;
|
|
307695
|
+
var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|AddonUpdates|Updates)\s*\}\}/;
|
|
307409
307696
|
function templateCarriesSummary(body) {
|
|
307410
307697
|
if (body === void 0 || body.trim().length === 0) return true;
|
|
307411
307698
|
return SUMMARY_CONTENT_VAR.test(body);
|
|
@@ -309773,6 +310060,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
309773
310060
|
exports.CAMERA_SWITCH_CATALOG = CAMERA_SWITCH_CATALOG;
|
|
309774
310061
|
exports.CAMERA_SWITCH_ORDER = CAMERA_SWITCH_ORDER;
|
|
309775
310062
|
exports.CAMERA_TRIGGER = CAMERA_TRIGGER;
|
|
310063
|
+
exports.CAMSTACK_APP_LINK_ORIGIN = CAMSTACK_APP_LINK_ORIGIN;
|
|
309776
310064
|
exports.CAM_PROFILE_ORDER = require_sleep.CAM_PROFILE_ORDER;
|
|
309777
310065
|
exports.CAPABILITY_NAMES = CAPABILITY_NAMES;
|
|
309778
310066
|
exports.CAPABILITY_ROUTER_KEYS = CAPABILITY_ROUTER_KEYS;
|
|
@@ -310209,6 +310497,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
310209
310497
|
exports.HF_BASE_URL = HF_BASE_URL;
|
|
310210
310498
|
exports.HF_REPO = HF_REPO;
|
|
310211
310499
|
exports.HOURS_PER_DAY = HOURS_PER_DAY;
|
|
310500
|
+
exports.HUB_VIEWER_MOUNT = HUB_VIEWER_MOUNT;
|
|
310212
310501
|
exports.HWACCEL_OPTIONS = HWACCEL_OPTIONS;
|
|
310213
310502
|
exports.HealthStatusSchema = HealthStatusSchema;
|
|
310214
310503
|
exports.HfModelResolutionSchema = HfModelResolutionSchema;
|
|
@@ -310426,9 +310715,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
310426
310715
|
exports.NC_ALARM_CONTROLLABLE_CAPS = NC_ALARM_CONTROLLABLE_CAPS;
|
|
310427
310716
|
exports.NC_ALARM_DEFAULT_PROFILE_ID = NC_ALARM_DEFAULT_PROFILE_ID;
|
|
310428
310717
|
exports.NC_ALARM_DEFAULT_PROFILE_NAME = NC_ALARM_DEFAULT_PROFILE_NAME;
|
|
310718
|
+
exports.NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC;
|
|
310429
310719
|
exports.NC_ALARM_DELAY_FIELDS = NC_ALARM_DELAY_FIELDS;
|
|
310430
310720
|
exports.NC_ALARM_DELAY_MAX_SEC = NC_ALARM_DELAY_MAX_SEC;
|
|
310431
310721
|
exports.NC_ALARM_NONBLOCKING_MAX = NC_ALARM_NONBLOCKING_MAX;
|
|
310722
|
+
exports.NC_ALARM_NOTIFY_FIELDS = NC_ALARM_NOTIFY_FIELDS;
|
|
310432
310723
|
exports.NC_ALARM_OPENING_EVENT_KINDS = NC_ALARM_OPENING_EVENT_KINDS;
|
|
310433
310724
|
exports.NC_ALARM_SENSORS_MAX = NC_ALARM_SENSORS_MAX;
|
|
310434
310725
|
exports.NC_ALARM_SYSTEM_DEFAULT_DELAYS = NC_ALARM_SYSTEM_DEFAULT_DELAYS;
|
|
@@ -310904,6 +311195,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
310904
311195
|
exports.ServerUpdateCheckResultSchema = ServerUpdateCheckResultSchema;
|
|
310905
311196
|
exports.ServerUpdateOutcomeSchema = ServerUpdateOutcomeSchema;
|
|
310906
311197
|
exports.ServerUpdateStateSchema = ServerUpdateStateSchema;
|
|
311198
|
+
exports.SessionTriggerSchema = SessionTriggerSchema;
|
|
310907
311199
|
exports.SetCameraSensorsInputSchema = SetCameraSensorsInputSchema;
|
|
310908
311200
|
exports.SetLoggingSettingsInputSchema = SetLoggingSettingsInputSchema;
|
|
310909
311201
|
exports.SetSiteLocationInputSchema = SetSiteLocationInputSchema;
|
|
@@ -311187,6 +311479,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
311187
311479
|
exports.buildRoleScopes = buildRoleScopes;
|
|
311188
311480
|
exports.buildStreamParamsConfigSchema = buildStreamParamsConfigSchema;
|
|
311189
311481
|
exports.buildVideoArgs = require_composition.buildVideoArgs;
|
|
311482
|
+
exports.buildViewerLink = buildViewerLink;
|
|
311190
311483
|
exports.builtCapabilityBlockers = builtCapabilityBlockers;
|
|
311191
311484
|
exports.buttonCapability = buttonCapability;
|
|
311192
311485
|
exports.calendarSourceCapability = calendarSourceCapability;
|
|
@@ -311416,6 +311709,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
311416
311709
|
exports.invocationFromEncodeProfile = require_composition.invocationFromEncodeProfile;
|
|
311417
311710
|
exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
|
|
311418
311711
|
exports.isAlarmControllableCap = isAlarmControllableCap;
|
|
311712
|
+
exports.isAppLinkBase = isAppLinkBase;
|
|
311419
311713
|
exports.isArrayOutputSchema = isArrayOutputSchema;
|
|
311420
311714
|
exports.isAudioChunkFormat = require_sleep.isAudioChunkFormat;
|
|
311421
311715
|
exports.isAudioClassName = isAudioClassName;
|
|
@@ -311562,6 +311856,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
311562
311856
|
exports.patchAudio = patchAudio;
|
|
311563
311857
|
exports.petFeederCapability = petFeederCapability;
|
|
311564
311858
|
exports.pickAccessoryControl = pickAccessoryControl;
|
|
311859
|
+
exports.pickAppLinkHub = pickAppLinkHub;
|
|
311565
311860
|
exports.pickClusterStepModels = pickClusterStepModels;
|
|
311566
311861
|
exports.pickClusterStepSettings = pickClusterStepSettings;
|
|
311567
311862
|
exports.pickDetailCropConvention = pickDetailCropConvention;
|
|
@@ -311641,6 +311936,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
311641
311936
|
exports.resolveLocationMode = resolveLocationMode;
|
|
311642
311937
|
exports.resolveMethodAuth = resolveMethodAuth;
|
|
311643
311938
|
exports.resolveModeDelays = resolveModeDelays;
|
|
311939
|
+
exports.resolveModeNotifyPolicy = resolveModeNotifyPolicy;
|
|
311644
311940
|
exports.resolveMutate = resolveMutate;
|
|
311645
311941
|
exports.resolvePoolMemoryPolicy = resolvePoolMemoryPolicy;
|
|
311646
311942
|
exports.resolveRecordingProfiles = resolveRecordingProfiles;
|
|
@@ -311749,6 +312045,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
311749
312045
|
exports.terminalSessionCapability = terminalSessionCapability;
|
|
311750
312046
|
exports.textToHtml = textToHtml;
|
|
311751
312047
|
exports.timeOfDayToMinutes = timeOfDayToMinutes;
|
|
312048
|
+
exports.toAppLinkHubOrigin = toAppLinkHubOrigin;
|
|
311752
312049
|
exports.toDeviceSummary = toDeviceSummary;
|
|
311753
312050
|
exports.toExpressionValue = require_composition.toExpressionValue;
|
|
311754
312051
|
exports.toNodeId = require_sleep.toNodeId;
|
|
@@ -311776,6 +312073,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
311776
312073
|
exports.vectorStoreCapability = vectorStoreCapability;
|
|
311777
312074
|
exports.vibrationCapability = vibrationCapability;
|
|
311778
312075
|
exports.videoclipsCapability = videoclipsCapability;
|
|
312076
|
+
exports.viewerLinkBaseOf = viewerLinkBaseOf;
|
|
311779
312077
|
exports.viewerUiCapability = require_sleep.viewerUiCapability;
|
|
311780
312078
|
exports.waterHeaterCapability = waterHeaterCapability;
|
|
311781
312079
|
exports.weatherCapability = weatherCapability;
|
|
@@ -468362,8 +468660,8 @@ var require_model_distributor = __commonJS({
|
|
|
468362
468660
|
});
|
|
468363
468661
|
}
|
|
468364
468662
|
async function distributeModelWith(seam, input) {
|
|
468365
|
-
const {
|
|
468366
|
-
if (
|
|
468663
|
+
const { targetNodeId, modelId, format: format2, entry } = input;
|
|
468664
|
+
if (targetNodeId === "hub") {
|
|
468367
468665
|
return { ok: true, sha256: "", bytes: 0, path: seam.modelsDir };
|
|
468368
468666
|
}
|
|
468369
468667
|
if (!seam.isPresent(entry, format2)) {
|
|
@@ -468375,7 +468673,7 @@ var require_model_distributor = __commonJS({
|
|
|
468375
468673
|
}
|
|
468376
468674
|
const tgz = await seam.tar(files);
|
|
468377
468675
|
const source = seam.stage(tgz);
|
|
468378
|
-
const res = await seam.callAgent(
|
|
468676
|
+
const res = await seam.callAgent(targetNodeId, { modelId, format: format2, source });
|
|
468379
468677
|
return { ok: true, sha256: source.sha256, bytes: source.bytes, path: res.path ?? "" };
|
|
468380
468678
|
}
|
|
468381
468679
|
function buildModelDistributorProvider(moleculer, loggingService) {
|
|
@@ -468401,7 +468699,7 @@ var require_model_distributor = __commonJS({
|
|
|
468401
468699
|
return {
|
|
468402
468700
|
distributeModel: async (input) => {
|
|
468403
468701
|
logger.info("Distributing model to node", {
|
|
468404
|
-
meta: { modelId: input.modelId, format: input.format, nodeId: input.
|
|
468702
|
+
meta: { modelId: input.modelId, format: input.format, nodeId: input.targetNodeId }
|
|
468405
468703
|
});
|
|
468406
468704
|
return distributeModelWith(seam, input);
|
|
468407
468705
|
}
|
|
@@ -469430,6 +469728,224 @@ var require_frame_policy = __commonJS({
|
|
|
469430
469728
|
}
|
|
469431
469729
|
});
|
|
469432
469730
|
|
|
469731
|
+
// ../../server/backend/dist/api/cors/cors-policy.js
|
|
469732
|
+
var require_cors_policy = __commonJS({
|
|
469733
|
+
"../../server/backend/dist/api/cors/cors-policy.js"(exports) {
|
|
469734
|
+
"use strict";
|
|
469735
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
469736
|
+
exports.CORS_PREFLIGHT_MAX_AGE_SEC = exports.CORS_EXPOSED_HEADERS = exports.CORS_ALLOWED_HEADERS = exports.CORS_ALLOWED_METHODS = exports.OPAQUE_ORIGIN = exports.VIEWER_PWA_ORIGIN = void 0;
|
|
469737
|
+
exports.normalizeOrigin = normalizeOrigin;
|
|
469738
|
+
exports.parseConfiguredOrigins = parseConfiguredOrigins;
|
|
469739
|
+
exports.builtInOrigins = builtInOrigins;
|
|
469740
|
+
exports.judgeCorsOrigin = judgeCorsOrigin;
|
|
469741
|
+
exports.corsResponseHeaders = corsResponseHeaders;
|
|
469742
|
+
exports.appendVary = appendVary;
|
|
469743
|
+
exports.VIEWER_PWA_ORIGIN = "https://camstack.zentik.app";
|
|
469744
|
+
exports.OPAQUE_ORIGIN = "null";
|
|
469745
|
+
exports.CORS_ALLOWED_METHODS = "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS";
|
|
469746
|
+
exports.CORS_ALLOWED_HEADERS = "authorization, content-type, range, if-range, if-none-match, cache-control, trpc-accept, x-trpc-source, x-trpc-batch-mode";
|
|
469747
|
+
exports.CORS_EXPOSED_HEADERS = "content-range, accept-ranges, content-length, content-disposition, etag, retry-after, x-camstack-reason, x-camstack-reason-code, x-camstack-disposition";
|
|
469748
|
+
exports.CORS_PREFLIGHT_MAX_AGE_SEC = 7200;
|
|
469749
|
+
function normalizeOrigin(raw) {
|
|
469750
|
+
const trimmed = raw.trim();
|
|
469751
|
+
if (trimmed === exports.OPAQUE_ORIGIN)
|
|
469752
|
+
return exports.OPAQUE_ORIGIN;
|
|
469753
|
+
let url;
|
|
469754
|
+
try {
|
|
469755
|
+
url = new URL(trimmed);
|
|
469756
|
+
} catch {
|
|
469757
|
+
return null;
|
|
469758
|
+
}
|
|
469759
|
+
if (url.protocol !== "https:" && url.protocol !== "http:")
|
|
469760
|
+
return null;
|
|
469761
|
+
if (url.username !== "" || url.password !== "")
|
|
469762
|
+
return null;
|
|
469763
|
+
if (url.pathname !== "/" && url.pathname !== "" || url.search !== "" || url.hash !== "") {
|
|
469764
|
+
return null;
|
|
469765
|
+
}
|
|
469766
|
+
return url.origin;
|
|
469767
|
+
}
|
|
469768
|
+
function parseConfiguredOrigins(value) {
|
|
469769
|
+
if (!Array.isArray(value))
|
|
469770
|
+
return { origins: [], rejected: [] };
|
|
469771
|
+
const origins = [];
|
|
469772
|
+
const rejected = [];
|
|
469773
|
+
for (const entry of value) {
|
|
469774
|
+
if (typeof entry !== "string") {
|
|
469775
|
+
rejected.push(String(entry));
|
|
469776
|
+
continue;
|
|
469777
|
+
}
|
|
469778
|
+
const normalized = normalizeOrigin(entry);
|
|
469779
|
+
if (normalized === null)
|
|
469780
|
+
rejected.push(entry);
|
|
469781
|
+
else
|
|
469782
|
+
origins.push(normalized);
|
|
469783
|
+
}
|
|
469784
|
+
return { origins, rejected };
|
|
469785
|
+
}
|
|
469786
|
+
function builtInOrigins(publicOrigin) {
|
|
469787
|
+
const entries = [exports.VIEWER_PWA_ORIGIN, exports.OPAQUE_ORIGIN];
|
|
469788
|
+
const pub = publicOrigin !== void 0 ? normalizeOrigin(publicOrigin) : null;
|
|
469789
|
+
if (pub !== null && pub !== exports.OPAQUE_ORIGIN)
|
|
469790
|
+
entries.push(pub);
|
|
469791
|
+
return entries;
|
|
469792
|
+
}
|
|
469793
|
+
function firstHost(value) {
|
|
469794
|
+
if (value === void 0)
|
|
469795
|
+
return null;
|
|
469796
|
+
const first = value.split(",")[0]?.trim().toLowerCase() ?? "";
|
|
469797
|
+
return first.length > 0 ? first : null;
|
|
469798
|
+
}
|
|
469799
|
+
function hostOfOrigin(origin) {
|
|
469800
|
+
if (origin === exports.OPAQUE_ORIGIN)
|
|
469801
|
+
return null;
|
|
469802
|
+
try {
|
|
469803
|
+
return new URL(origin).host.toLowerCase();
|
|
469804
|
+
} catch {
|
|
469805
|
+
return null;
|
|
469806
|
+
}
|
|
469807
|
+
}
|
|
469808
|
+
function judgeCorsOrigin(facts, listed) {
|
|
469809
|
+
const raw = facts.origin;
|
|
469810
|
+
if (raw === void 0 || raw.length === 0)
|
|
469811
|
+
return { kind: "no-origin" };
|
|
469812
|
+
const normalized = normalizeOrigin(raw);
|
|
469813
|
+
if (normalized === null)
|
|
469814
|
+
return { kind: "denied", origin: raw };
|
|
469815
|
+
if (listed.has(normalized))
|
|
469816
|
+
return { kind: "allowed", origin: raw, reason: "listed" };
|
|
469817
|
+
const originHost = hostOfOrigin(normalized);
|
|
469818
|
+
if (originHost !== null) {
|
|
469819
|
+
const ownHosts = [firstHost(facts.host), firstHost(facts.forwardedHost)];
|
|
469820
|
+
if (ownHosts.includes(originHost))
|
|
469821
|
+
return { kind: "allowed", origin: raw, reason: "own-host" };
|
|
469822
|
+
}
|
|
469823
|
+
return { kind: "denied", origin: raw };
|
|
469824
|
+
}
|
|
469825
|
+
function corsResponseHeaders(origin, preflight) {
|
|
469826
|
+
const base = {
|
|
469827
|
+
"access-control-allow-origin": origin,
|
|
469828
|
+
"access-control-expose-headers": exports.CORS_EXPOSED_HEADERS
|
|
469829
|
+
};
|
|
469830
|
+
if (preflight === null)
|
|
469831
|
+
return base;
|
|
469832
|
+
return {
|
|
469833
|
+
...base,
|
|
469834
|
+
"access-control-allow-methods": exports.CORS_ALLOWED_METHODS,
|
|
469835
|
+
"access-control-allow-headers": exports.CORS_ALLOWED_HEADERS,
|
|
469836
|
+
"access-control-max-age": String(exports.CORS_PREFLIGHT_MAX_AGE_SEC),
|
|
469837
|
+
// A public origin (the PWA) calling a LAN hub is a "private network"
|
|
469838
|
+
// request to Chromium; its preflight must be answered explicitly.
|
|
469839
|
+
...preflight.requestPrivateNetwork ? { "access-control-allow-private-network": "true" } : {}
|
|
469840
|
+
};
|
|
469841
|
+
}
|
|
469842
|
+
function appendVary(existing, token2) {
|
|
469843
|
+
if (existing === void 0 || existing.trim().length === 0)
|
|
469844
|
+
return token2;
|
|
469845
|
+
const parts = existing.split(",").map((p) => p.trim().toLowerCase());
|
|
469846
|
+
if (parts.includes("*") || parts.includes(token2.toLowerCase()))
|
|
469847
|
+
return existing;
|
|
469848
|
+
return `${existing}, ${token2}`;
|
|
469849
|
+
}
|
|
469850
|
+
}
|
|
469851
|
+
});
|
|
469852
|
+
|
|
469853
|
+
// ../../server/backend/dist/api/cors/register-cors-policy.js
|
|
469854
|
+
var require_register_cors_policy = __commonJS({
|
|
469855
|
+
"../../server/backend/dist/api/cors/register-cors-policy.js"(exports) {
|
|
469856
|
+
"use strict";
|
|
469857
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
469858
|
+
exports.createCorsPolicy = createCorsPolicy;
|
|
469859
|
+
exports.registerCorsPolicy = registerCorsPolicy;
|
|
469860
|
+
exports.refuseForeignWsUpgrade = refuseForeignWsUpgrade;
|
|
469861
|
+
var cors_policy_js_1 = require_cors_policy();
|
|
469862
|
+
var MAX_LOGGED_DENIALS = 256;
|
|
469863
|
+
function headerValue(value) {
|
|
469864
|
+
if (Array.isArray(value))
|
|
469865
|
+
return value[0];
|
|
469866
|
+
return value;
|
|
469867
|
+
}
|
|
469868
|
+
function varyText(value) {
|
|
469869
|
+
if (typeof value === "string")
|
|
469870
|
+
return value;
|
|
469871
|
+
if (Array.isArray(value))
|
|
469872
|
+
return value.filter((v) => typeof v === "string").join(", ");
|
|
469873
|
+
return void 0;
|
|
469874
|
+
}
|
|
469875
|
+
function createCorsPolicy(deps) {
|
|
469876
|
+
const builtIns = (0, cors_policy_js_1.builtInOrigins)(deps.publicOrigin);
|
|
469877
|
+
let lastConfigured = /* @__PURE__ */ Symbol("unset");
|
|
469878
|
+
let listed = new Set(builtIns);
|
|
469879
|
+
const loggedDenials = /* @__PURE__ */ new Set();
|
|
469880
|
+
const currentList = () => {
|
|
469881
|
+
const configured = deps.configuredOrigins();
|
|
469882
|
+
if (configured === lastConfigured)
|
|
469883
|
+
return listed;
|
|
469884
|
+
lastConfigured = configured;
|
|
469885
|
+
const parsed = (0, cors_policy_js_1.parseConfiguredOrigins)(configured);
|
|
469886
|
+
if (parsed.rejected.length > 0) {
|
|
469887
|
+
deps.logger.warn("cors: ignored configured origins that are not http(s) origins", {
|
|
469888
|
+
meta: { rejected: parsed.rejected, setting: "server.corsOrigins" }
|
|
469889
|
+
});
|
|
469890
|
+
}
|
|
469891
|
+
listed = /* @__PURE__ */ new Set([...builtIns, ...parsed.origins]);
|
|
469892
|
+
return listed;
|
|
469893
|
+
};
|
|
469894
|
+
return {
|
|
469895
|
+
judge(headers) {
|
|
469896
|
+
const verdict = (0, cors_policy_js_1.judgeCorsOrigin)({
|
|
469897
|
+
origin: headerValue(headers.origin),
|
|
469898
|
+
host: headerValue(headers.host),
|
|
469899
|
+
forwardedHost: headerValue(headers["x-forwarded-host"])
|
|
469900
|
+
}, currentList());
|
|
469901
|
+
if (verdict.kind === "denied" && !loggedDenials.has(verdict.origin)) {
|
|
469902
|
+
if (loggedDenials.size < MAX_LOGGED_DENIALS)
|
|
469903
|
+
loggedDenials.add(verdict.origin);
|
|
469904
|
+
deps.logger.warn("cors: refused a cross-origin caller not on the allowlist", {
|
|
469905
|
+
meta: {
|
|
469906
|
+
origin: verdict.origin,
|
|
469907
|
+
host: headerValue(headers.host) ?? null,
|
|
469908
|
+
hint: "add it to server.corsOrigins (config.yaml) or CAMSTACK_CORS_ORIGINS"
|
|
469909
|
+
}
|
|
469910
|
+
});
|
|
469911
|
+
}
|
|
469912
|
+
return verdict;
|
|
469913
|
+
}
|
|
469914
|
+
};
|
|
469915
|
+
}
|
|
469916
|
+
function registerCorsPolicy(fastify, policy) {
|
|
469917
|
+
fastify.addHook("onRequest", async (request, reply) => {
|
|
469918
|
+
const vary = (0, cors_policy_js_1.appendVary)(varyText(reply.getHeader("vary")), "Origin");
|
|
469919
|
+
reply.header("vary", vary);
|
|
469920
|
+
reply.raw.setHeader("vary", vary);
|
|
469921
|
+
const verdict = policy.judge(request.headers);
|
|
469922
|
+
const isPreflight = request.method === "OPTIONS" && request.headers["access-control-request-method"] !== void 0;
|
|
469923
|
+
if (verdict.kind === "allowed") {
|
|
469924
|
+
const headers = (0, cors_policy_js_1.corsResponseHeaders)(verdict.origin, isPreflight ? {
|
|
469925
|
+
requestPrivateNetwork: headerValue(request.headers["access-control-request-private-network"]) === "true"
|
|
469926
|
+
} : null);
|
|
469927
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
469928
|
+
reply.header(name, value);
|
|
469929
|
+
reply.raw.setHeader(name, value);
|
|
469930
|
+
}
|
|
469931
|
+
}
|
|
469932
|
+
if (request.method === "OPTIONS") {
|
|
469933
|
+
return reply.code(204).send();
|
|
469934
|
+
}
|
|
469935
|
+
return void 0;
|
|
469936
|
+
});
|
|
469937
|
+
}
|
|
469938
|
+
function refuseForeignWsUpgrade(policy, headers, socket) {
|
|
469939
|
+
const verdict = policy.judge(headers);
|
|
469940
|
+
if (verdict.kind !== "denied")
|
|
469941
|
+
return false;
|
|
469942
|
+
socket.write("HTTP/1.1 403 Forbidden\r\nConnection: close\r\nContent-Length: 0\r\n\r\n");
|
|
469943
|
+
socket.destroy();
|
|
469944
|
+
return true;
|
|
469945
|
+
}
|
|
469946
|
+
}
|
|
469947
|
+
});
|
|
469948
|
+
|
|
469433
469949
|
// ../../server/backend/dist/boot/integration-id-backfill.js
|
|
469434
469950
|
var require_integration_id_backfill = __commonJS({
|
|
469435
469951
|
"../../server/backend/dist/boot/integration-id-backfill.js"(exports) {
|
|
@@ -485915,16 +486431,6 @@ var require_manual_boot = __commonJS({
|
|
|
485915
486431
|
getHttpAdapter() {
|
|
485916
486432
|
return { getInstance: () => fastify };
|
|
485917
486433
|
},
|
|
485918
|
-
enableCors() {
|
|
485919
|
-
fastify.addHook("onRequest", async (request, reply) => {
|
|
485920
|
-
reply.header("access-control-allow-origin", "*");
|
|
485921
|
-
reply.header("access-control-allow-methods", "GET,POST,PUT,DELETE,OPTIONS,PATCH");
|
|
485922
|
-
reply.header("access-control-allow-headers", "content-type,authorization");
|
|
485923
|
-
if (request.method === "OPTIONS") {
|
|
485924
|
-
reply.status(204).send();
|
|
485925
|
-
}
|
|
485926
|
-
});
|
|
485927
|
-
},
|
|
485928
486434
|
enableShutdownHooks() {
|
|
485929
486435
|
if (shutdownHooksRegistered)
|
|
485930
486436
|
return;
|
|
@@ -486035,6 +486541,7 @@ var require_main4 = __commonJS({
|
|
|
486035
486541
|
var spa_static_1 = require_spa_static();
|
|
486036
486542
|
var spa_mount_1 = require_spa_mount();
|
|
486037
486543
|
var frame_policy_1 = require_frame_policy();
|
|
486544
|
+
var register_cors_policy_1 = require_register_cors_policy();
|
|
486038
486545
|
var cap_providers_1 = require_cap_providers();
|
|
486039
486546
|
var logging_settings_1 = require_logging_settings();
|
|
486040
486547
|
var request_census_settings_1 = require_request_census_settings();
|
|
@@ -486201,8 +486708,14 @@ var require_main4 = __commonJS({
|
|
|
486201
486708
|
const fastifyOpts = tlsOptions ? { https: tlsOptions } : {};
|
|
486202
486709
|
const app = await (0, manual_boot_1.bootManual)({ infra, fastifyOpts });
|
|
486203
486710
|
app.enableShutdownHooks();
|
|
486204
|
-
app.enableCors();
|
|
486205
486711
|
const fastify = app.getHttpAdapter().getInstance();
|
|
486712
|
+
const corsConfig = app.get(config_service_1.ConfigService);
|
|
486713
|
+
const corsPolicy = (0, register_cors_policy_1.createCorsPolicy)({
|
|
486714
|
+
configuredOrigins: () => corsConfig.get("server.corsOrigins"),
|
|
486715
|
+
publicOrigin: process.env.CAMSTACK_PUBLIC_ORIGIN,
|
|
486716
|
+
logger: app.get(logging_service_1.LoggingService).createLogger("cors")
|
|
486717
|
+
});
|
|
486718
|
+
(0, register_cors_policy_1.registerCorsPolicy)(fastify, corsPolicy);
|
|
486206
486719
|
await fastify.register(cookie_1.default);
|
|
486207
486720
|
(0, frame_policy_1.registerFramePolicy)(fastify);
|
|
486208
486721
|
fastify.addHook("onRequest", async (request) => {
|
|
@@ -486785,6 +487298,8 @@ var require_main4 = __commonJS({
|
|
|
486785
487298
|
httpServer.on("upgrade", (request, socket, head) => {
|
|
486786
487299
|
const pathname = (request.url ?? "").split("?")[0];
|
|
486787
487300
|
if (pathname === "/trpc") {
|
|
487301
|
+
if ((0, register_cors_policy_1.refuseForeignWsUpgrade)(corsPolicy, request.headers, socket))
|
|
487302
|
+
return;
|
|
486788
487303
|
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
486789
487304
|
wss.emit("connection", ws, request);
|
|
486790
487305
|
});
|