@camstack/addon-post-analysis 1.2.669 → 1.2.670
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/{clip-model-registry-BPvijtCz.mjs → clip-model-registry-7_dm-x-g.mjs} +27 -4
- package/dist/{clip-model-registry-CbzBwacH.js → clip-model-registry-B3x4Npc9.js} +32 -3
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +1 -1
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-C4QK9e1e.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BYaeszka.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bame_Xen.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-CPLvPO3K.mjs → hostInit-CNqHuab6.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +186 -40
- package/dist/pipeline-analytics/index.mjs +186 -40
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-anSYIl3S.mjs +0 -26
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_clip_model_registry = require("../clip-model-registry-
|
|
5
|
+
const require_clip_model_registry = require("../clip-model-registry-B3x4Npc9.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
node_fs = require_clip_model_registry.__toESM(node_fs, 1);
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -52541,7 +52541,7 @@ var FaceSettingsSchema = require_clip_model_registry.object({
|
|
|
52541
52541
|
* `resolveGlobalFaceEnabled` / `getDeviceSettingsContribution` (the field is
|
|
52542
52542
|
* stripped from the per-device schema).
|
|
52543
52543
|
*/
|
|
52544
|
-
|
|
52544
|
+
faceRecognitionEnabled: require_clip_model_registry.boolean().default(true),
|
|
52545
52545
|
/**
|
|
52546
52546
|
* Cosine similarity (on L2-normalized embeddings) required to match. A
|
|
52547
52547
|
* property of ONE model's cosine space: it moves with the default model.
|
|
@@ -52643,7 +52643,7 @@ function resolveFaceSettings(raw) {
|
|
|
52643
52643
|
return parsed.success ? parsed.data : FACE_DEFAULTS[key];
|
|
52644
52644
|
};
|
|
52645
52645
|
return {
|
|
52646
|
-
|
|
52646
|
+
faceRecognitionEnabled: pick("faceRecognitionEnabled"),
|
|
52647
52647
|
similarityThreshold: pick("similarityThreshold"),
|
|
52648
52648
|
margin: pick("margin"),
|
|
52649
52649
|
minFacePx: pick("minFacePx"),
|
|
@@ -56662,7 +56662,117 @@ async function migrateDeviceTemplateVariable(ports) {
|
|
|
56662
56662
|
};
|
|
56663
56663
|
}
|
|
56664
56664
|
//#endregion
|
|
56665
|
-
//#region src/migrations/
|
|
56665
|
+
//#region src/migrations/split-enabled-key.ts
|
|
56666
|
+
/**
|
|
56667
|
+
* The shared settings key `enabled` becomes two (D987, D986 §2).
|
|
56668
|
+
*
|
|
56669
|
+
* One key meant two things: "Face recognition on" and "Suppress parked objects". Toggling one
|
|
56670
|
+
* flipped the other. Each switch now has its own key. So today's behaviour does not change, the
|
|
56671
|
+
* value an install has stored under `enabled` is copied into BOTH new keys, and `enabled` is
|
|
56672
|
+
* deleted. That covers the cluster row (`addon-settings`) and every camera's own row
|
|
56673
|
+
* (`addon-device-settings`).
|
|
56674
|
+
*
|
|
56675
|
+
* A new key that already has a row is never overwritten (a seed never overwrites): it was written
|
|
56676
|
+
* by the build that reads it. The plan has nothing left to do once `enabled` is gone, so a rerun is
|
|
56677
|
+
* a no-op. A read that fails throws and nothing is written.
|
|
56678
|
+
*/
|
|
56679
|
+
var PIPELINE_ANALYTICS_ID = "pipeline-analytics";
|
|
56680
|
+
var RETIRED_ENABLED_KEY = "enabled";
|
|
56681
|
+
var NEW_KEYS = ["faceRecognitionEnabled", "stationarySuppressionEnabled"];
|
|
56682
|
+
/** The canonical settings table: one row per key, id `<addonId>.<key>`. */
|
|
56683
|
+
var SETTINGS_TABLE = "addon-settings";
|
|
56684
|
+
/** The per-device settings table: one row per field, id `<addonId>:<deviceId>.<field>`. */
|
|
56685
|
+
var DEVICE_SETTINGS_TABLE = "addon-device-settings";
|
|
56686
|
+
function clusterEdits(stored) {
|
|
56687
|
+
if (!(RETIRED_ENABLED_KEY in stored)) return [];
|
|
56688
|
+
const value = stored[RETIRED_ENABLED_KEY];
|
|
56689
|
+
const rowId = (key) => `${PIPELINE_ANALYTICS_ID}.${key}`;
|
|
56690
|
+
const missing = NEW_KEYS.filter((key) => !(key in stored));
|
|
56691
|
+
const edits = [];
|
|
56692
|
+
if (missing.length > 0) edits.push({
|
|
56693
|
+
op: "setKeys",
|
|
56694
|
+
scope: SETTINGS_TABLE,
|
|
56695
|
+
values: Object.fromEntries(missing.map((key) => [rowId(key), {
|
|
56696
|
+
addonId: PIPELINE_ANALYTICS_ID,
|
|
56697
|
+
key,
|
|
56698
|
+
value
|
|
56699
|
+
}])),
|
|
56700
|
+
precondition: require_clip_model_registry.preconditionOf(Object.fromEntries(missing.map((key) => [rowId(key), null])))
|
|
56701
|
+
});
|
|
56702
|
+
edits.push({
|
|
56703
|
+
op: "deleteKeys",
|
|
56704
|
+
scope: SETTINGS_TABLE,
|
|
56705
|
+
keys: [rowId(RETIRED_ENABLED_KEY)],
|
|
56706
|
+
precondition: require_clip_model_registry.preconditionOf({ [rowId(RETIRED_ENABLED_KEY)]: {
|
|
56707
|
+
addonId: PIPELINE_ANALYTICS_ID,
|
|
56708
|
+
key: RETIRED_ENABLED_KEY,
|
|
56709
|
+
value
|
|
56710
|
+
} })
|
|
56711
|
+
});
|
|
56712
|
+
return edits;
|
|
56713
|
+
}
|
|
56714
|
+
async function deviceEdits(ports) {
|
|
56715
|
+
const ids = await ports.listDeviceIds();
|
|
56716
|
+
if (ids.length === 0) return [];
|
|
56717
|
+
const retired = await ports.readDeviceField(ids, RETIRED_ENABLED_KEY);
|
|
56718
|
+
if (retired.size === 0) return [];
|
|
56719
|
+
const carriers = [...retired.keys()];
|
|
56720
|
+
const existing = /* @__PURE__ */ new Map();
|
|
56721
|
+
for (const key of NEW_KEYS) existing.set(key, await ports.readDeviceField(carriers, key));
|
|
56722
|
+
const rowId = (deviceId, field) => `${PIPELINE_ANALYTICS_ID}:${deviceId}.${field}`;
|
|
56723
|
+
const created = {};
|
|
56724
|
+
const retiredRows = {};
|
|
56725
|
+
for (const [deviceId, value] of retired) {
|
|
56726
|
+
for (const key of NEW_KEYS) {
|
|
56727
|
+
if (existing.get(key)?.has(deviceId) === true) continue;
|
|
56728
|
+
created[rowId(deviceId, key)] = {
|
|
56729
|
+
addonId: PIPELINE_ANALYTICS_ID,
|
|
56730
|
+
deviceId: String(deviceId),
|
|
56731
|
+
key,
|
|
56732
|
+
value
|
|
56733
|
+
};
|
|
56734
|
+
}
|
|
56735
|
+
retiredRows[rowId(deviceId, RETIRED_ENABLED_KEY)] = {
|
|
56736
|
+
addonId: PIPELINE_ANALYTICS_ID,
|
|
56737
|
+
deviceId: String(deviceId),
|
|
56738
|
+
key: RETIRED_ENABLED_KEY,
|
|
56739
|
+
value
|
|
56740
|
+
};
|
|
56741
|
+
}
|
|
56742
|
+
const edits = [];
|
|
56743
|
+
const createdIds = Object.keys(created);
|
|
56744
|
+
if (createdIds.length > 0) edits.push({
|
|
56745
|
+
op: "setKeys",
|
|
56746
|
+
scope: DEVICE_SETTINGS_TABLE,
|
|
56747
|
+
values: created,
|
|
56748
|
+
precondition: require_clip_model_registry.preconditionOf(Object.fromEntries(createdIds.map((id) => [id, null])))
|
|
56749
|
+
});
|
|
56750
|
+
edits.push({
|
|
56751
|
+
op: "deleteKeys",
|
|
56752
|
+
scope: DEVICE_SETTINGS_TABLE,
|
|
56753
|
+
keys: Object.keys(retiredRows),
|
|
56754
|
+
precondition: require_clip_model_registry.preconditionOf(retiredRows)
|
|
56755
|
+
});
|
|
56756
|
+
return edits;
|
|
56757
|
+
}
|
|
56758
|
+
/** Copy `enabled` into both new keys (cluster row and every camera's row) and delete it. */
|
|
56759
|
+
async function planSplitEnabledKey(ports) {
|
|
56760
|
+
return { edits: [...clusterEdits(await ports.readStored([RETIRED_ENABLED_KEY, ...NEW_KEYS])), ...await deviceEdits(ports)] };
|
|
56761
|
+
}
|
|
56762
|
+
/**
|
|
56763
|
+
* The port's read over an addon's three-way key read: each of `keys` that has a row, raw. A key
|
|
56764
|
+
* the store could not answer for throws, so the migration fails instead of treating a failed read
|
|
56765
|
+
* as "nothing to move".
|
|
56766
|
+
*/
|
|
56767
|
+
async function readRawKeys(read, keys) {
|
|
56768
|
+
const found = {};
|
|
56769
|
+
for (const key of keys) {
|
|
56770
|
+
const answer = await read(key);
|
|
56771
|
+
if (answer.kind === "unreadable") throw new Error(`${PIPELINE_ANALYTICS_ID}: the setting ${key} cannot be read (${answer.reason})`);
|
|
56772
|
+
if (answer.kind === "present") found[key] = answer.value;
|
|
56773
|
+
}
|
|
56774
|
+
return found;
|
|
56775
|
+
}
|
|
56666
56776
|
/** The `pipeline-analytics` catalogue (D987): offered to the engine at the hub's boot. */
|
|
56667
56777
|
var ADDON_MIGRATIONS = [{
|
|
56668
56778
|
meta: {
|
|
@@ -56679,6 +56789,21 @@ var ADDON_MIGRATIONS = [{
|
|
|
56679
56789
|
fixtureMark: "the rule name and the trigger conditions the migration does not know"
|
|
56680
56790
|
},
|
|
56681
56791
|
procedure: migrateDeviceTemplateVariable
|
|
56792
|
+
}, {
|
|
56793
|
+
meta: {
|
|
56794
|
+
id: "pipeline-analytics/2026-11-05-split-enabled-key",
|
|
56795
|
+
owner: PIPELINE_ANALYTICS_ID,
|
|
56796
|
+
level: "addon-state",
|
|
56797
|
+
seq: 2,
|
|
56798
|
+
dependsOn: [],
|
|
56799
|
+
store: "settings",
|
|
56800
|
+
scope: "cluster",
|
|
56801
|
+
onFailure: "block-owner",
|
|
56802
|
+
bodyKind: "plan",
|
|
56803
|
+
description: "Split the shared `enabled` setting into faceRecognitionEnabled and stationarySuppressionEnabled, copying the stored value into both, for the cluster and for every camera",
|
|
56804
|
+
fixtureMark: "a setting the migration does not know"
|
|
56805
|
+
},
|
|
56806
|
+
plan: planSplitEnabledKey
|
|
56682
56807
|
}];
|
|
56683
56808
|
//#endregion
|
|
56684
56809
|
//#region src/pipeline-analytics/clip-space-plan.ts
|
|
@@ -72092,7 +72217,7 @@ var SensorTransitionGate = class {
|
|
|
72092
72217
|
var StationarySettingsSchema = require_clip_model_registry.object({
|
|
72093
72218
|
/** Master switch. Off ⇒ this camera gathers no evidence and suppresses
|
|
72094
72219
|
* nothing (every parked object keeps spawning normal tracks). */
|
|
72095
|
-
|
|
72220
|
+
stationarySuppressionEnabled: require_clip_model_registry.boolean().default(true),
|
|
72096
72221
|
/** IoU at/above which a detection is the same parked object, unmoved →
|
|
72097
72222
|
* suppress its spawn. `SUPPRESS_IOU`. */
|
|
72098
72223
|
suppressIou: require_clip_model_registry.number().min(.3).max(.9).default(SUPPRESS_IOU),
|
|
@@ -72119,7 +72244,7 @@ function resolveStationarySettings(raw) {
|
|
|
72119
72244
|
return parsed.success ? parsed.data : STATIONARY_DEFAULTS[key];
|
|
72120
72245
|
};
|
|
72121
72246
|
return {
|
|
72122
|
-
|
|
72247
|
+
stationarySuppressionEnabled: pick("stationarySuppressionEnabled"),
|
|
72123
72248
|
suppressIou: pick("suppressIou"),
|
|
72124
72249
|
wakeAssocIou: pick("wakeAssocIou"),
|
|
72125
72250
|
sessionStillnessWindowMs: pick("sessionStillnessWindowMs"),
|
|
@@ -72530,10 +72655,10 @@ function buildDetectionSettingsSections() {
|
|
|
72530
72655
|
fields: [
|
|
72531
72656
|
{
|
|
72532
72657
|
type: "boolean",
|
|
72533
|
-
key: "
|
|
72658
|
+
key: "stationarySuppressionEnabled",
|
|
72534
72659
|
label: "Suppress parked objects",
|
|
72535
72660
|
description: "Promote a stopped object to a lightweight registry entry and suppress its detections from re-spawning tracks. Off = every parked object keeps spawning normal tracks on this camera.",
|
|
72536
|
-
default: STATIONARY_DEFAULTS.
|
|
72661
|
+
default: STATIONARY_DEFAULTS.stationarySuppressionEnabled
|
|
72537
72662
|
},
|
|
72538
72663
|
{
|
|
72539
72664
|
type: "slider",
|
|
@@ -72743,8 +72868,6 @@ function retagRetentionSection(sections) {
|
|
|
72743
72868
|
* model-substitution readout.
|
|
72744
72869
|
*/
|
|
72745
72870
|
var SUGGESTION_THRESHOLD_READOUT_KEY = "suggestionThresholdReadout";
|
|
72746
|
-
/** `getGlobalSettings({ cap })` scope for the face matching form. */
|
|
72747
|
-
var FACE_GALLERY_SETTINGS_CAP = "face-gallery";
|
|
72748
72871
|
var FACE_RECOGNITION_SECTION_ID = "face-recognition";
|
|
72749
72872
|
/** Percent, at most one decimal, without a trailing `.0`. Cosines here are
|
|
72750
72873
|
* two-decimal operator values; `36.0%` reads like false precision. */
|
|
@@ -72766,7 +72889,7 @@ function formatSuggestionThresholdReadout(similarityThreshold) {
|
|
|
72766
72889
|
* by each device's detection-pipeline steps, so a per-device toggle would be
|
|
72767
72890
|
* misleading. Keyed by section id → set of field keys to drop.
|
|
72768
72891
|
*/
|
|
72769
|
-
var GLOBAL_ONLY_FIELDS = { "face-recognition": new Set(["
|
|
72892
|
+
var GLOBAL_ONLY_FIELDS = { "face-recognition": new Set(["faceRecognitionEnabled", SUGGESTION_THRESHOLD_READOUT_KEY]) };
|
|
72770
72893
|
/**
|
|
72771
72894
|
* Whole sections that are cluster-wide (global page only) and must NOT appear
|
|
72772
72895
|
* in a per-device contribution (D62: a per-camera field whose reader only ever
|
|
@@ -72825,8 +72948,8 @@ function stripDeviceOnlyFields(sections) {
|
|
|
72825
72948
|
* in `BaseAddon.schema()`; the general sections below are followed by the
|
|
72826
72949
|
* detection-knob sections in the original order.
|
|
72827
72950
|
*/
|
|
72828
|
-
function buildGlobalSettingsSchema(
|
|
72829
|
-
return
|
|
72951
|
+
function buildGlobalSettingsSchema() {
|
|
72952
|
+
return { sections: [...[
|
|
72830
72953
|
{
|
|
72831
72954
|
id: "cluster-post-processing",
|
|
72832
72955
|
title: "Cluster post-processing",
|
|
@@ -73405,10 +73528,10 @@ function buildGlobalSettingsSchema(cap) {
|
|
|
73405
73528
|
fields: [
|
|
73406
73529
|
{
|
|
73407
73530
|
type: "boolean",
|
|
73408
|
-
key: "
|
|
73531
|
+
key: "faceRecognitionEnabled",
|
|
73409
73532
|
label: "Face recognition on",
|
|
73410
73533
|
description: "Off stops face matching for every camera. On by default.",
|
|
73411
|
-
default: FACE_DEFAULTS.
|
|
73534
|
+
default: FACE_DEFAULTS.faceRecognitionEnabled
|
|
73412
73535
|
},
|
|
73413
73536
|
{
|
|
73414
73537
|
type: "number",
|
|
@@ -73503,25 +73626,22 @@ function buildGlobalSettingsSchema(cap) {
|
|
|
73503
73626
|
}
|
|
73504
73627
|
]
|
|
73505
73628
|
}
|
|
73506
|
-
], ...buildDetectionSettingsSections()] }
|
|
73629
|
+
], ...buildDetectionSettingsSections()] };
|
|
73630
|
+
}
|
|
73631
|
+
/** The face matching form: the cluster form of `face-gallery`. */
|
|
73632
|
+
function buildFaceClusterSchema() {
|
|
73633
|
+
return { sections: buildGlobalSettingsSchema().sections.filter((section) => section.id === FACE_RECOGNITION_SECTION_ID) };
|
|
73634
|
+
}
|
|
73635
|
+
/** The cluster-wide knobs of `pipeline-analytics`: the sections a camera never overrides. */
|
|
73636
|
+
function buildAnalyticsClusterSchema() {
|
|
73637
|
+
return { sections: buildGlobalSettingsSchema().sections.filter((section) => GLOBAL_ONLY_SECTIONS.has(section.id)) };
|
|
73507
73638
|
}
|
|
73508
73639
|
/**
|
|
73509
|
-
* The
|
|
73510
|
-
*
|
|
73511
|
-
* → Settings asks for `face-gallery`; System → Settings omits `cap` and
|
|
73512
|
-
* still gets every section. An unknown cap is empty so this addon cannot
|
|
73513
|
-
* appear on a page that meant someone else.
|
|
73640
|
+
* The fleet defaults of `pipeline-analytics`: every knob a camera can override on its own form,
|
|
73641
|
+
* the face section excluded (it is the cluster form of `face-gallery`).
|
|
73514
73642
|
*/
|
|
73515
|
-
function
|
|
73516
|
-
|
|
73517
|
-
if (cap === FACE_GALLERY_SETTINGS_CAP) return {
|
|
73518
|
-
...schema,
|
|
73519
|
-
sections: schema.sections.filter((s) => s.id === FACE_RECOGNITION_SECTION_ID)
|
|
73520
|
-
};
|
|
73521
|
-
return {
|
|
73522
|
-
...schema,
|
|
73523
|
-
sections: []
|
|
73524
|
-
};
|
|
73643
|
+
function buildAnalyticsDeviceDefaultsSchema() {
|
|
73644
|
+
return { sections: buildGlobalSettingsSchema().sections.filter((section) => section.id !== FACE_RECOGNITION_SECTION_ID && !GLOBAL_ONLY_SECTIONS.has(section.id)) };
|
|
73525
73645
|
}
|
|
73526
73646
|
//#endregion
|
|
73527
73647
|
//#region src/pipeline-analytics/store/embedding-json-conversion.ts
|
|
@@ -124086,7 +124206,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
124086
124206
|
}
|
|
124087
124207
|
_faceGlobalEnabledState = null;
|
|
124088
124208
|
get faceGlobalEnabledState() {
|
|
124089
|
-
if (!this._faceGlobalEnabledState) this._faceGlobalEnabledState = this.state("
|
|
124209
|
+
if (!this._faceGlobalEnabledState) this._faceGlobalEnabledState = this.state("faceRecognitionEnabled", FaceSettingsSchema.shape.faceRecognitionEnabled, FACE_DEFAULTS.faceRecognitionEnabled);
|
|
124090
124210
|
return this._faceGlobalEnabledState;
|
|
124091
124211
|
}
|
|
124092
124212
|
constructor() {
|
|
@@ -124463,10 +124583,19 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
124463
124583
|
/** The addon's migration catalogue (D987), bound to the notification kinds. */
|
|
124464
124584
|
async runTemplateMigrations() {
|
|
124465
124585
|
const records = this.requireRecords();
|
|
124586
|
+
const settings = this.ctx.settings;
|
|
124587
|
+
if (settings === void 0) throw new Error("the per-device settings store is unavailable");
|
|
124466
124588
|
const ports = {
|
|
124467
124589
|
rules: records.kind(ncRecordKinds["rules"]),
|
|
124468
124590
|
timelapseRules: records.kind(ncRecordKinds["timelapse-rules"]),
|
|
124469
|
-
texts: records.kind(ncRecordKinds.texts)
|
|
124591
|
+
texts: records.kind(ncRecordKinds.texts),
|
|
124592
|
+
readStored: (keys) => readRawKeys((key) => this.readStoredGlobalKey(key), keys),
|
|
124593
|
+
listDeviceIds: () => settings.listDeviceStoreIds(),
|
|
124594
|
+
readDeviceField: async (deviceIds, field) => {
|
|
124595
|
+
const found = /* @__PURE__ */ new Map();
|
|
124596
|
+
for (const [deviceId, blob] of await settings.readDeviceStoreBatch(deviceIds)) if (field in blob) found.set(deviceId, blob[field]);
|
|
124597
|
+
return found;
|
|
124598
|
+
}
|
|
124470
124599
|
};
|
|
124471
124600
|
await this.runMigrations(require_clip_model_registry.defineAddonMigrations(ADDON_MIGRATIONS, ports));
|
|
124472
124601
|
}
|
|
@@ -127033,7 +127162,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
127033
127162
|
const stationarySettings = this.stationarySettingsFromCache(deviceId);
|
|
127034
127163
|
const packageSettings = this.packageDropSettingsFromCache(deviceId);
|
|
127035
127164
|
const packageClasses = new Set(packageSettings.packageDropClassFilter);
|
|
127036
|
-
if (planeRunsStationary(source) && this.stationaryRegistry && this.stationaryEvidence && stationarySettings.
|
|
127165
|
+
if (planeRunsStationary(source) && this.stationaryRegistry && this.stationaryEvidence && stationarySettings.stationarySuppressionEnabled) {
|
|
127037
127166
|
const evidence = this.stationaryEvidence;
|
|
127038
127167
|
for (const t of result.tracked) {
|
|
127039
127168
|
if (packageClasses.has(t.className)) continue;
|
|
@@ -129377,7 +129506,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
129377
129506
|
const registry = this.stationaryRegistry;
|
|
129378
129507
|
p.setStationaryGate({ filter: (input) => {
|
|
129379
129508
|
const s = this.stationarySettingsFromCache(deviceId);
|
|
129380
|
-
if (!s.
|
|
129509
|
+
if (!s.stationarySuppressionEnabled) return {
|
|
129381
129510
|
suppressedIndices: /* @__PURE__ */ new Set(),
|
|
129382
129511
|
continuableIndices: /* @__PURE__ */ new Set(),
|
|
129383
129512
|
confirmed: [],
|
|
@@ -132937,8 +133066,25 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
132937
133066
|
});
|
|
132938
133067
|
return await readWinningBlob(candidates, pick, readBlob);
|
|
132939
133068
|
}
|
|
132940
|
-
|
|
132941
|
-
return
|
|
133069
|
+
scopedSettingsCapabilities() {
|
|
133070
|
+
return ["pipeline-analytics", "face-gallery"];
|
|
133071
|
+
}
|
|
133072
|
+
/**
|
|
133073
|
+
* D986 M4. The face matching form is the cluster form of `face-gallery`; the cluster-wide knobs
|
|
133074
|
+
* (post-processing node, index maintenance, device alerts, prune windows) are the cluster form
|
|
133075
|
+
* of `pipeline-analytics`. A page asks for ONE capability's form, and System → Settings asks for
|
|
133076
|
+
* all of them. The schemas are static; the only live value (the derived suggestion floor) is
|
|
133077
|
+
* injected into the hydrate blob by `getGlobalSettings`.
|
|
133078
|
+
*/
|
|
133079
|
+
async clusterSettingsSchema(cap) {
|
|
133080
|
+
if (cap === "face-gallery") return this.schema(buildFaceClusterSchema());
|
|
133081
|
+
if (cap === "pipeline-analytics") return this.schema(buildAnalyticsClusterSchema());
|
|
133082
|
+
return null;
|
|
133083
|
+
}
|
|
133084
|
+
/** The knobs a camera can override: stored as the fleet default, resolved per camera. */
|
|
133085
|
+
async deviceDefaultsSchema(cap) {
|
|
133086
|
+
if (cap === "pipeline-analytics") return this.schema(buildAnalyticsDeviceDefaultsSchema());
|
|
133087
|
+
return null;
|
|
132942
133088
|
}
|
|
132943
133089
|
/**
|
|
132944
133090
|
* The only reason this is overridden: the face suggestion floor is DERIVED
|
|
@@ -132952,11 +133098,11 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
132952
133098
|
* implies and has nothing to contradict it with. Everything else about this
|
|
132953
133099
|
* call is `BaseAddon`'s.
|
|
132954
133100
|
*
|
|
132955
|
-
* (Fix round, L3.) `
|
|
133101
|
+
* (Fix round, L3.) `buildGlobalSettingsSchema()` is reused, untouched, by
|
|
132956
133102
|
* `getDeviceSettingsContribution` below to build the PER-DEVICE form —
|
|
132957
133103
|
* `trackingTape` must stay there. So the strip happens here, on the result
|
|
132958
133104
|
* THIS method actually hands to the global settings page, never inside
|
|
132959
|
-
* `
|
|
133105
|
+
* `buildGlobalSettingsSchema()` itself, which would also remove it from the
|
|
132960
133106
|
* per-device form that shares the same base sections.
|
|
132961
133107
|
*/
|
|
132962
133108
|
async getGlobalSettings(overlay, cap, nodeId) {
|
|
@@ -132978,7 +133124,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
132978
133124
|
}
|
|
132979
133125
|
async getDeviceSettingsContribution(input) {
|
|
132980
133126
|
if (!await this.isCameraDevice(input.deviceId)) return null;
|
|
132981
|
-
const schema =
|
|
133127
|
+
const schema = buildGlobalSettingsSchema();
|
|
132982
133128
|
const raw = await this.readDeviceBlob(input.deviceId);
|
|
132983
133129
|
const globalRaw = await this.rawGlobalStoreMirror.resolve();
|
|
132984
133130
|
const baseSections = schema ? hydrateWithInheritedGlobals({
|