@camstack/types 1.2.304 → 1.2.305

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -12460,7 +12460,7 @@ var detectionPipelineCapability = {
12460
12460
  * This matters here more than anywhere else in the repo, because every provider
12461
12461
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
12462
12462
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
12463
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
12463
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
12464
12464
  * camera's own page will ask for its own login. That is correct, and pre-
12465
12465
  * filling it is the operator's business, not ours.
12466
12466
  *
@@ -20504,8 +20504,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20504
20504
  disabledTargetIds: zod.z.array(zod.z.string()).default([])
20505
20505
  });
20506
20506
  /**
20507
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20508
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20507
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20508
+ * report a still-true state. `addons` is the crash-looped addons only and
20509
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20509
20510
  * job is not an open state, and the alarm stays instant.
20510
20511
  */
20511
20512
  var NcStateSummarySectionIdSchema = zod.z.enum([
@@ -20517,6 +20518,7 @@ var NcStateSummarySectionIdSchema = zod.z.enum([
20517
20518
  "detection-blind",
20518
20519
  "nodes",
20519
20520
  "addons",
20521
+ "addon-updates",
20520
20522
  "updates"
20521
20523
  ]);
20522
20524
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -21555,7 +21557,19 @@ var NcAlarmModeDelaysSchema = zod.z.object({
21555
21557
  * When this mode may be armed. Absent / null = always allowed (same as a
21556
21558
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
21557
21559
  */
21558
- schedule: NcScheduleSchema.optional()
21560
+ schedule: NcScheduleSchema.optional(),
21561
+ /**
21562
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
21563
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
21564
+ * only one, and the matches ride the triggered notification's mosaic (D705).
21565
+ */
21566
+ notifyDuringEntryDelay: zod.z.boolean().optional(),
21567
+ /**
21568
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
21569
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
21570
+ * is the one that starts the entry delay — the entry-delay notification already names it.
21571
+ */
21572
+ notifySensorRewatched: zod.z.boolean().optional()
21559
21573
  });
21560
21574
  var NcAlarmModeDelaysListSchema = zod.z.array(NcAlarmModeDelaysSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
21561
21575
  /**
@@ -21570,7 +21584,11 @@ var NcAlarmModeDelaysEditSchema = zod.z.object({
21570
21584
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
21571
21585
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
21572
21586
  /** Set a schedule, or `null` to clear (mode always allowed again). */
21573
- schedule: NcScheduleSchema.nullable().optional()
21587
+ schedule: NcScheduleSchema.nullable().optional(),
21588
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21589
+ notifyDuringEntryDelay: zod.z.boolean().nullable().optional(),
21590
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21591
+ notifySensorRewatched: zod.z.boolean().nullable().optional()
21574
21592
  });
21575
21593
  var NcAlarmModeDelaysEditListSchema = zod.z.array(NcAlarmModeDelaysEditSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
21576
21594
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
@@ -26801,6 +26819,22 @@ var MotionSourceEnum = zod.z.enum([
26801
26819
  "device-activity"
26802
26820
  ]);
26803
26821
  /**
26822
+ * What opened an on-motion detection SESSION: the motion source that passed the
26823
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
26824
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
26825
+ * device name as the orchestrator's camera-sensors resolution last read it;
26826
+ * absent when unknown or when the camera itself triggered.
26827
+ *
26828
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
26829
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
26830
+ * runner never decides anything on it.
26831
+ */
26832
+ var SessionTriggerSchema = zod.z.object({
26833
+ source: MotionSourceEnum,
26834
+ triggeredBy: MotionTriggeredBySchema,
26835
+ sensorName: zod.z.string().optional()
26836
+ });
26837
+ /**
26804
26838
  * List of motion sources active on a camera. Empty array is valid:
26805
26839
  * "no source" — happens for battery cams without firmware motion when
26806
26840
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -27057,6 +27091,14 @@ var RunnerCameraConfigSchema = zod.z.object({
27057
27091
  */
27058
27092
  motionSources: MotionSourcesSchema.default(["analyzer"]),
27059
27093
  /**
27094
+ * What opened this attach, on a SESSION attach only (see
27095
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
27096
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
27097
+ * behind it, and every attach from an orchestrator older than the field — the
27098
+ * runner then names no source on the phase event.
27099
+ */
27100
+ sessionTrigger: SessionTriggerSchema.optional(),
27101
+ /**
27060
27102
  * WHICH root detector runs for this camera. The detection counterpart of
27061
27103
  * {@link motionSources}, same shape and same discipline: a per-camera list
27062
27104
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32212,6 +32254,122 @@ var CLIP_PLAYBACK_OPTIONS = {
32212
32254
  }
32213
32255
  };
32214
32256
  //#endregion
32257
+ //#region src/capabilities/viewer-link-url.ts
32258
+ /** The central link domain the viewer app claims (Universal Links / App Links). */
32259
+ var CAMSTACK_APP_LINK_ORIGIN = "https://camstack.zentik.app";
32260
+ /** Where the hub serves the viewer SPA. */
32261
+ var HUB_VIEWER_MOUNT = "/viewer/camstack";
32262
+ /** True when `baseUrl` names the CamStack app link rather than a hub address. */
32263
+ function isAppLinkBase(baseUrl) {
32264
+ if (baseUrl === null || baseUrl === void 0 || baseUrl === "") return false;
32265
+ try {
32266
+ return new URL(baseUrl).origin === CAMSTACK_APP_LINK_ORIGIN;
32267
+ } catch {
32268
+ return false;
32269
+ }
32270
+ }
32271
+ /**
32272
+ * The base a viewer link is built on, from the flagged notification address:
32273
+ * the effective address is the explicit choice, else AUTO's `resolved`. The
32274
+ * one reading of that answer — the NC's tap and the Network page's preview
32275
+ * both go through it.
32276
+ */
32277
+ function viewerLinkBaseOf(endpoint) {
32278
+ const flagged = endpoint.baseUrl ?? endpoint.resolved;
32279
+ return isAppLinkBase(flagged) ? {
32280
+ form: "app",
32281
+ hubBaseUrl: endpoint.appLinkHub ?? null
32282
+ } : {
32283
+ form: "hub",
32284
+ hubBaseUrl: flagged
32285
+ };
32286
+ }
32287
+ /**
32288
+ * Reduce a base URL to the bare origin the central page accepts as `hub=`,
32289
+ * or `null` when it cannot be one: not http(s), carries credentials, or does
32290
+ * not parse. A path/query/fragment is dropped — the central page mounts the
32291
+ * viewer under the origin itself.
32292
+ */
32293
+ function toAppLinkHubOrigin(baseUrl) {
32294
+ let parsed;
32295
+ try {
32296
+ parsed = new URL(baseUrl);
32297
+ } catch {
32298
+ return null;
32299
+ }
32300
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
32301
+ if (parsed.username !== "" || parsed.password !== "") return null;
32302
+ if (parsed.hostname === "") return null;
32303
+ return parsed.origin;
32304
+ }
32305
+ /**
32306
+ * The hub address an app link carries as `hub=`, chosen from the hub's OWN
32307
+ * advertised palette so it always agrees with what the Network page lists:
32308
+ * the public tunnel first, then the mesh (Tailscale MagicDNS) — HTTPS only,
32309
+ * because the app and the hosted viewer reach it from off the LAN. `null`
32310
+ * when the hub advertises neither.
32311
+ */
32312
+ function pickAppLinkHub(endpoints) {
32313
+ const rank = (e) => {
32314
+ if (e.kind !== "public" || !e.baseUrl.startsWith("https://")) return null;
32315
+ if (e.interfaceKind === "public") return 0;
32316
+ if (e.interfaceKind === "vpn") return 1;
32317
+ return null;
32318
+ };
32319
+ return endpoints.flatMap((e) => {
32320
+ const r = rank(e);
32321
+ const origin = toAppLinkHubOrigin(e.baseUrl);
32322
+ return r === null || origin === null ? [] : [{
32323
+ r,
32324
+ p: e.priority,
32325
+ origin
32326
+ }];
32327
+ }).toSorted((a, b) => a.r - b.r || a.p - b.p)[0]?.origin ?? null;
32328
+ }
32329
+ /** The viewer route for a destination, or null when it names nothing. */
32330
+ function viewerRoute(destination) {
32331
+ switch (destination.kind) {
32332
+ case "camera": {
32333
+ if (!Number.isInteger(destination.deviceId) || destination.deviceId <= 0) return null;
32334
+ const at = destination.atMs;
32335
+ return {
32336
+ path: `/camera/${String(destination.deviceId)}`,
32337
+ query: at !== void 0 && Number.isFinite(at) ? [["at", String(Math.trunc(at))]] : []
32338
+ };
32339
+ }
32340
+ case "events": return {
32341
+ path: "/events",
32342
+ query: []
32343
+ };
32344
+ case "notifications": return {
32345
+ path: "/notifications",
32346
+ query: []
32347
+ };
32348
+ }
32349
+ }
32350
+ function encodeQuery(query) {
32351
+ if (query.length === 0) return "";
32352
+ return `?${query.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&")}`;
32353
+ }
32354
+ /**
32355
+ * The link for a viewer destination, or `null` when none can be minted: an
32356
+ * unknown destination, or the `hub` form with no reachable base (a dead link
32357
+ * is worse than none).
32358
+ */
32359
+ function buildViewerLink(input) {
32360
+ const route = viewerRoute(input.destination);
32361
+ if (route === null) return null;
32362
+ const raw = input.base.hubBaseUrl;
32363
+ const base = raw === null ? "" : raw.replace(/\/+$/, "");
32364
+ if (input.base.form === "app") {
32365
+ const origin = base === "" ? null : toAppLinkHubOrigin(base);
32366
+ const query = origin === null ? route.query : [...route.query, ["hub", origin]];
32367
+ return `${CAMSTACK_APP_LINK_ORIGIN}${route.path}${encodeQuery(query)}`;
32368
+ }
32369
+ if (base === "" || isAppLinkBase(base)) return null;
32370
+ return `${base}${HUB_VIEWER_MOUNT}${route.path}${encodeQuery(route.query)}`;
32371
+ }
32372
+ //#endregion
32215
32373
  //#region src/capabilities/webrtc-session.cap.ts
32216
32374
  /**
32217
32375
  * Optional client-side hints sent at session creation to help the provider
@@ -37085,7 +37243,7 @@ var LocalInterfaceSchema = zod.z.object({
37085
37243
  name: zod.z.string(),
37086
37244
  family: zod.z.enum(["IPv4", "IPv6"]),
37087
37245
  address: zod.z.string(),
37088
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
37246
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
37089
37247
  cidr: zod.z.string(),
37090
37248
  /** OS netmask. Stable across calls so the SDK can hash on it. */
37091
37249
  netmask: zod.z.string(),
@@ -37139,7 +37297,8 @@ var ConnectionEndpointSchema = zod.z.object({
37139
37297
  "lan-ipv4",
37140
37298
  "lan-ipv6",
37141
37299
  "public",
37142
- "loopback"
37300
+ "loopback",
37301
+ "app-link"
37143
37302
  ]),
37144
37303
  /**
37145
37304
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -37208,15 +37367,27 @@ var GetConnectionEndpointsResultSchema = zod.z.object({
37208
37367
  localPort: AdvertisedLocalPortSchema
37209
37368
  });
37210
37369
  /**
37211
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
37212
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
37213
- * what AUTO currently picks, so the UI can show the effective value either way.
37370
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
37371
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
37372
+ * so the UI can show it either way.
37214
37373
  */
37215
37374
  var NotificationEndpointSchema = zod.z.object({
37216
37375
  /** The operator's explicit choice, or null for AUTO. */
37217
37376
  baseUrl: zod.z.string().nullable(),
37218
- /** What the ranking currently resolves to (null when nothing is reachable). */
37219
- resolved: zod.z.string().nullable()
37377
+ /**
37378
+ * The effective flagged address: the explicit choice, else (AUTO) the
37379
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
37380
+ * answered the public tunnel / mesh here, or null.
37381
+ */
37382
+ resolved: zod.z.string().nullable(),
37383
+ /**
37384
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
37385
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
37386
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
37387
+ * hub advertises neither; the app link is then minted without `hub=`.
37388
+ * Absent on a pre-D709 hub.
37389
+ */
37390
+ appLinkHub: zod.z.string().nullable()
37220
37391
  });
37221
37392
  /**
37222
37393
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -37284,7 +37455,7 @@ var localNetworkCapability = {
37284
37455
  * every client a second authority on a socket only the hub binds. A viewer
37285
37456
  * configured with a port-less public URL (`https://camstack.example.top`)
37286
37457
  * infers 443 from the scheme, asks with 443, and was handed
37287
- * `https://192.168.x.x:443` for a hub listening on 4443. That candidate
37458
+ * `https://192.168.10.9:443` for a hub listening on 4443. That candidate
37288
37459
  * cannot ever answer, and losing its race reads in the log exactly like
37289
37460
  * "the LAN was tried and it was slower" — so an operator sitting on his own
37290
37461
  * WiFi stayed on the public tunnel for weeks, with the LAN candidate born
@@ -37317,13 +37488,21 @@ var localNetworkCapability = {
37317
37488
  * Pass `'https'` when the caller is itself loaded over HTTPS
37318
37489
  * to avoid mixed-content blocks in the browser. The public
37319
37490
  * tunnel always emits `https://` regardless. */
37320
- scheme: zod.z.enum(["http", "https"]).optional()
37491
+ scheme: zod.z.enum(["http", "https"]).optional(),
37492
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
37493
+ * an address notification links can be flagged with, not a hub
37494
+ * route. Default `false`: racers and rankers never see it. */
37495
+ includeAppLink: zod.z.boolean().optional()
37321
37496
  }), GetConnectionEndpointsResultSchema),
37322
37497
  /**
37323
- * The endpoint OUTBOUND artifacts must be addressed by — notification
37324
- * attachment links and deep links. `baseUrl: null` means AUTO: the first
37325
- * public candidate (a configured origin, then a connected tunnel, then the
37326
- * LAN), never loopback.
37498
+ * The address notification links are flagged with. `baseUrl: null` means
37499
+ * AUTO, which is the CamStack app link (D709): viewer taps go through
37500
+ * `https://camstack.zentik.app/…?hub=<appLinkHub>` and open the app. Any
37501
+ * hub address the palette lists can be flagged instead; then viewer taps,
37502
+ * attachment links and action buttons all use it. Signed media and
37503
+ * buttons never use the app link — with it flagged (or AUTO) they keep
37504
+ * the ranked hub ladder (a configured origin, a connected tunnel, then
37505
+ * the LAN), never loopback.
37327
37506
  *
37328
37507
  * Why an explicit marker: the automatic ranking cannot know which of
37329
37508
  * several reachable addresses the RECIPIENT can actually open. A link is
@@ -37743,7 +37922,7 @@ var MeshPeerSchema = zod.z.object({
37743
37922
  tags: zod.z.array(zod.z.string()).readonly(),
37744
37923
  /** True when the peer advertises itself as an exit-node candidate. */
37745
37924
  exitNodeOption: zod.z.boolean(),
37746
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
37925
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
37747
37926
  advertisedRoutes: zod.z.array(zod.z.string()).readonly(),
37748
37927
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
37749
37928
  userLogin: zod.z.string().nullable(),
@@ -66902,12 +67081,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
66902
67081
  {
66903
67082
  id: "addons",
66904
67083
  family: "system",
66905
- label: "Addons",
66906
- kinds: [
66907
- "addon-crash-loop",
66908
- "addon-update-available",
66909
- "addon-updated"
66910
- ]
67084
+ label: "Addons stopped",
67085
+ kinds: ["addon-crash-loop"]
67086
+ },
67087
+ {
67088
+ id: "addon-updates",
67089
+ family: "system",
67090
+ label: "Addon updates",
67091
+ kinds: ["addon-update-available", "addon-updated"]
66911
67092
  },
66912
67093
  {
66913
67094
  id: "updates",
@@ -67754,6 +67935,26 @@ var NC_ALARM_DELAY_FIELDS = [
67754
67935
  "triggeredDurationSec"
67755
67936
  ];
67756
67937
  /**
67938
+ * The STOCK after-trigger duration a panel seeds and every mode inherits unless it sets its
67939
+ * own (D706: 30 s, was 10 s under D701). Only the seed: a persisted value is never rewritten.
67940
+ * The panel's defaults, its one-shot migration and the admin UI's "pick a timed action" fill
67941
+ * all read this one constant.
67942
+ */
67943
+ var NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = 30;
67944
+ var NC_ALARM_NOTIFY_FIELDS = ["notifyDuringEntryDelay", "notifySensorRewatched"];
67945
+ /**
67946
+ * The switches `mode` runs on. There is no global value: absent is OFF (operator decision
67947
+ * 2026-10-06 — the entry-delay notification is the only one by default, and "watched again"
67948
+ * is not sent). An answer from an older hub carries no switch and reads as off.
67949
+ */
67950
+ function resolveModeNotifyPolicy(settings, mode) {
67951
+ const entry = (settings.modeDelays ?? []).find((e) => e.mode === mode);
67952
+ return {
67953
+ notifyDuringEntryDelay: entry?.notifyDuringEntryDelay === true,
67954
+ notifySensorRewatched: entry?.notifySensorRewatched === true
67955
+ };
67956
+ }
67957
+ /**
67757
67958
  * Derive the post-triggered action from a stored blob that may predate the field:
67758
67959
  * a positive duration meant re-arm; zero/absent meant stay triggered.
67759
67960
  */
@@ -67802,6 +68003,10 @@ function editedAction(current, edit) {
67802
68003
  if (edit === void 0) return current;
67803
68004
  return edit === null ? void 0 : edit;
67804
68005
  }
68006
+ function editedFlag(current, edit) {
68007
+ if (edit === void 0) return current;
68008
+ return edit === null ? void 0 : edit;
68009
+ }
67805
68010
  function editedSchedule(current, edit) {
67806
68011
  if (edit === void 0) return current;
67807
68012
  return edit === null ? void 0 : edit;
@@ -67836,15 +68041,19 @@ function applyModeDelaysEdits(current, edits) {
67836
68041
  const triggered = edited(base.triggeredDurationSec, edit.triggeredDurationSec);
67837
68042
  const action = editedAction(base.postTriggeredAction, edit.postTriggeredAction);
67838
68043
  const schedule = editedSchedule(base.schedule, edit.schedule);
68044
+ const duringEntry = editedFlag(base.notifyDuringEntryDelay, edit.notifyDuringEntryDelay);
68045
+ const rewatched = editedFlag(base.notifySensorRewatched, edit.notifySensorRewatched);
67839
68046
  if (exit !== void 0) next.exitDelaySec = exit;
67840
68047
  if (entry !== void 0) next.entryDelaySec = entry;
67841
68048
  if (triggered !== void 0) next.triggeredDurationSec = triggered;
67842
68049
  if (action !== void 0) next.postTriggeredAction = action;
67843
68050
  if (schedule !== void 0) next.schedule = schedule;
68051
+ if (duringEntry !== void 0) next.notifyDuringEntryDelay = duringEntry;
68052
+ if (rewatched !== void 0) next.notifySensorRewatched = rewatched;
67844
68053
  if (at >= 0) out[at] = next;
67845
68054
  else out.push(next);
67846
68055
  }
67847
- return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0 || e.postTriggeredAction !== void 0 || e.schedule !== void 0);
68056
+ 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);
67848
68057
  }
67849
68058
  /**
67850
68059
  * Put ONE device on, or take it off, ONE mode's device-id list. A no-op answers
@@ -67989,6 +68198,12 @@ function alarmPatchLanded(patch, returned) {
67989
68198
  const got = entry?.postTriggeredAction;
67990
68199
  if (edit.postTriggeredAction === null ? got !== void 0 : got !== edit.postTriggeredAction) return false;
67991
68200
  }
68201
+ for (const field of NC_ALARM_NOTIFY_FIELDS) {
68202
+ const want = edit[field];
68203
+ if (want === void 0) continue;
68204
+ const got = entry?.[field];
68205
+ if (want === null ? got !== void 0 : got !== want) return false;
68206
+ }
67992
68207
  if (edit.schedule !== void 0) {
67993
68208
  const got = entry?.schedule;
67994
68209
  if (edit.schedule === null ? got !== void 0 : !sameSchedule(got, edit.schedule)) return false;
@@ -68385,13 +68600,15 @@ var STATE_SUMMARY_SECTION_VARS = [
68385
68600
  },
68386
68601
  {
68387
68602
  name: "summaryAddons",
68388
- label: "Summary: addons",
68389
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
68390
- kinds: [
68391
- "addon-crash-loop",
68392
- "addon-update-available",
68393
- "addon-updated"
68394
- ]
68603
+ label: "Summary: addons stopped",
68604
+ example: "hub — recorder stopped after repeated crashes",
68605
+ kinds: ["addon-crash-loop"]
68606
+ },
68607
+ {
68608
+ name: "summaryAddonUpdates",
68609
+ label: "Summary: addon updates",
68610
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
68611
+ kinds: ["addon-update-available", "addon-updated"]
68395
68612
  },
68396
68613
  {
68397
68614
  name: "summaryUpdates",
@@ -68732,6 +68949,16 @@ var NC_TEMPLATE_VARS = [
68732
68949
  kinds: ["system"],
68733
68950
  systemEventKinds: [...DEVICE_EVENTS]
68734
68951
  },
68952
+ {
68953
+ name: "locations",
68954
+ label: "Intrusion locations",
68955
+ example: "Ingresso, Corridoio, Salone",
68956
+ group: "system",
68957
+ families: ["rule"],
68958
+ fields: [...RULE_TEXT],
68959
+ kinds: ["system"],
68960
+ systemEventKinds: [...COMBINED_ALARM]
68961
+ },
68735
68962
  {
68736
68963
  name: "deviceId",
68737
68964
  label: "Device id",
@@ -69448,7 +69675,7 @@ function sendTimesForEditor(schedule) {
69448
69675
  approximated: times.length > 0
69449
69676
  };
69450
69677
  }
69451
- var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|Updates)\s*\}\}/;
69678
+ var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|AddonUpdates|Updates)\s*\}\}/;
69452
69679
  /**
69453
69680
  * Does a custom BODY carry the summary's content (`{{summaryText}}` or a
69454
69681
  * section variable)? A body that does not would send a summary with nothing
@@ -72662,6 +72889,7 @@ exports.CAMERA_SENSORS_SETTINGS_KEY = CAMERA_SENSORS_SETTINGS_KEY;
72662
72889
  exports.CAMERA_SWITCH_CATALOG = CAMERA_SWITCH_CATALOG;
72663
72890
  exports.CAMERA_SWITCH_ORDER = CAMERA_SWITCH_ORDER;
72664
72891
  exports.CAMERA_TRIGGER = CAMERA_TRIGGER;
72892
+ exports.CAMSTACK_APP_LINK_ORIGIN = CAMSTACK_APP_LINK_ORIGIN;
72665
72893
  exports.CAM_PROFILE_ORDER = require_sleep.CAM_PROFILE_ORDER;
72666
72894
  exports.CAPABILITY_NAMES = CAPABILITY_NAMES;
72667
72895
  exports.CAPABILITY_ROUTER_KEYS = CAPABILITY_ROUTER_KEYS;
@@ -73098,6 +73326,7 @@ exports.HAP_KEYFRAME_INTERVAL_SEC = HAP_KEYFRAME_INTERVAL_SEC;
73098
73326
  exports.HF_BASE_URL = HF_BASE_URL;
73099
73327
  exports.HF_REPO = HF_REPO;
73100
73328
  exports.HOURS_PER_DAY = HOURS_PER_DAY;
73329
+ exports.HUB_VIEWER_MOUNT = HUB_VIEWER_MOUNT;
73101
73330
  exports.HWACCEL_OPTIONS = HWACCEL_OPTIONS;
73102
73331
  exports.HealthStatusSchema = HealthStatusSchema;
73103
73332
  exports.HfModelResolutionSchema = HfModelResolutionSchema;
@@ -73315,9 +73544,11 @@ exports.NAVIGATION_LIGHT_LEVEL_MIN = NAVIGATION_LIGHT_LEVEL_MIN;
73315
73544
  exports.NC_ALARM_CONTROLLABLE_CAPS = NC_ALARM_CONTROLLABLE_CAPS;
73316
73545
  exports.NC_ALARM_DEFAULT_PROFILE_ID = NC_ALARM_DEFAULT_PROFILE_ID;
73317
73546
  exports.NC_ALARM_DEFAULT_PROFILE_NAME = NC_ALARM_DEFAULT_PROFILE_NAME;
73547
+ exports.NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC;
73318
73548
  exports.NC_ALARM_DELAY_FIELDS = NC_ALARM_DELAY_FIELDS;
73319
73549
  exports.NC_ALARM_DELAY_MAX_SEC = NC_ALARM_DELAY_MAX_SEC;
73320
73550
  exports.NC_ALARM_NONBLOCKING_MAX = NC_ALARM_NONBLOCKING_MAX;
73551
+ exports.NC_ALARM_NOTIFY_FIELDS = NC_ALARM_NOTIFY_FIELDS;
73321
73552
  exports.NC_ALARM_OPENING_EVENT_KINDS = NC_ALARM_OPENING_EVENT_KINDS;
73322
73553
  exports.NC_ALARM_SENSORS_MAX = NC_ALARM_SENSORS_MAX;
73323
73554
  exports.NC_ALARM_SYSTEM_DEFAULT_DELAYS = NC_ALARM_SYSTEM_DEFAULT_DELAYS;
@@ -73793,6 +74024,7 @@ exports.ServerUpdateActionResultSchema = ServerUpdateActionResultSchema;
73793
74024
  exports.ServerUpdateCheckResultSchema = ServerUpdateCheckResultSchema;
73794
74025
  exports.ServerUpdateOutcomeSchema = ServerUpdateOutcomeSchema;
73795
74026
  exports.ServerUpdateStateSchema = ServerUpdateStateSchema;
74027
+ exports.SessionTriggerSchema = SessionTriggerSchema;
73796
74028
  exports.SetCameraSensorsInputSchema = SetCameraSensorsInputSchema;
73797
74029
  exports.SetLoggingSettingsInputSchema = SetLoggingSettingsInputSchema;
73798
74030
  exports.SetSiteLocationInputSchema = SetSiteLocationInputSchema;
@@ -74076,6 +74308,7 @@ exports.buildNcTaxonomy = buildNcTaxonomy;
74076
74308
  exports.buildRoleScopes = buildRoleScopes;
74077
74309
  exports.buildStreamParamsConfigSchema = buildStreamParamsConfigSchema;
74078
74310
  exports.buildVideoArgs = require_composition.buildVideoArgs;
74311
+ exports.buildViewerLink = buildViewerLink;
74079
74312
  exports.builtCapabilityBlockers = builtCapabilityBlockers;
74080
74313
  exports.buttonCapability = buttonCapability;
74081
74314
  exports.calendarSourceCapability = calendarSourceCapability;
@@ -74305,6 +74538,7 @@ exports.invertPresetFeature = invertPresetFeature;
74305
74538
  exports.invocationFromEncodeProfile = require_composition.invocationFromEncodeProfile;
74306
74539
  exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
74307
74540
  exports.isAlarmControllableCap = isAlarmControllableCap;
74541
+ exports.isAppLinkBase = isAppLinkBase;
74308
74542
  exports.isArrayOutputSchema = isArrayOutputSchema;
74309
74543
  exports.isAudioChunkFormat = require_sleep.isAudioChunkFormat;
74310
74544
  exports.isAudioClassName = isAudioClassName;
@@ -74451,6 +74685,7 @@ exports.parseStreamParamsFormPatch = parseStreamParamsFormPatch;
74451
74685
  exports.patchAudio = patchAudio;
74452
74686
  exports.petFeederCapability = petFeederCapability;
74453
74687
  exports.pickAccessoryControl = pickAccessoryControl;
74688
+ exports.pickAppLinkHub = pickAppLinkHub;
74454
74689
  exports.pickClusterStepModels = pickClusterStepModels;
74455
74690
  exports.pickClusterStepSettings = pickClusterStepSettings;
74456
74691
  exports.pickDetailCropConvention = pickDetailCropConvention;
@@ -74530,6 +74765,7 @@ exports.resolveLocationIcon = resolveLocationIcon;
74530
74765
  exports.resolveLocationMode = resolveLocationMode;
74531
74766
  exports.resolveMethodAuth = resolveMethodAuth;
74532
74767
  exports.resolveModeDelays = resolveModeDelays;
74768
+ exports.resolveModeNotifyPolicy = resolveModeNotifyPolicy;
74533
74769
  exports.resolveMutate = resolveMutate;
74534
74770
  exports.resolvePoolMemoryPolicy = resolvePoolMemoryPolicy;
74535
74771
  exports.resolveRecordingProfiles = resolveRecordingProfiles;
@@ -74638,6 +74874,7 @@ exports.templateVarsFor = templateVarsFor;
74638
74874
  exports.terminalSessionCapability = terminalSessionCapability;
74639
74875
  exports.textToHtml = textToHtml;
74640
74876
  exports.timeOfDayToMinutes = timeOfDayToMinutes;
74877
+ exports.toAppLinkHubOrigin = toAppLinkHubOrigin;
74641
74878
  exports.toDeviceSummary = toDeviceSummary;
74642
74879
  exports.toExpressionValue = require_composition.toExpressionValue;
74643
74880
  exports.toNodeId = require_sleep.toNodeId;
@@ -74665,6 +74902,7 @@ exports.vectorIndexDimConflictError = vectorIndexDimConflictError;
74665
74902
  exports.vectorStoreCapability = vectorStoreCapability;
74666
74903
  exports.vibrationCapability = vibrationCapability;
74667
74904
  exports.videoclipsCapability = videoclipsCapability;
74905
+ exports.viewerLinkBaseOf = viewerLinkBaseOf;
74668
74906
  exports.viewerUiCapability = require_sleep.viewerUiCapability;
74669
74907
  exports.waterHeaterCapability = waterHeaterCapability;
74670
74908
  exports.weatherCapability = weatherCapability;