@camstack/addon-pipeline 1.1.53 → 1.1.55

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.
Files changed (35) hide show
  1. package/dist/audio-analyzer/index.js +1 -1
  2. package/dist/audio-analyzer/index.mjs +1 -1
  3. package/dist/detection-pipeline/index.js +289 -1469
  4. package/dist/detection-pipeline/index.mjs +269 -1449
  5. package/dist/{dist-DWb62H5U.js → dist-DI57FC8K.js} +167 -8
  6. package/dist/{dist-BalxNwOt.mjs → dist-RWGGPwVx.mjs} +167 -8
  7. package/dist/motion-wasm/index.js +1 -1
  8. package/dist/motion-wasm/index.mjs +1 -1
  9. package/dist/pipeline-runner/index.js +772 -21
  10. package/dist/pipeline-runner/index.mjs +772 -22
  11. package/dist/recorder/index.js +1 -1
  12. package/dist/recorder/index.mjs +1 -1
  13. package/dist/{remote-source-plane-CZpzIVro.js → remote-source-plane-CHgvzzA6.js} +1 -1
  14. package/dist/{remote-source-plane-BCJW5CvF.mjs → remote-source-plane-DU0aRSPv.mjs} +1 -1
  15. package/dist/session-decode/decode-worker-child.js +538 -35
  16. package/dist/session-decode/decode-worker-child.mjs +538 -35
  17. package/dist/step-definitions-CNBFKjZe.js +1514 -0
  18. package/dist/step-definitions-CP9kVSml.mjs +1479 -0
  19. package/dist/stream-broker/_stub.js +2 -2
  20. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DIN3CcRP.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-mDCPzmT3.mjs} +3 -3
  21. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B3gTdHEh.mjs +26 -0
  22. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-C9fwKMfg.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Dn_pxzP-.mjs} +1 -1
  23. package/dist/stream-broker/{hostInit-CGUEq--X.mjs → hostInit-GM_CI22k.mjs} +3 -3
  24. package/dist/stream-broker/index.js +2 -2
  25. package/dist/stream-broker/index.mjs +2 -2
  26. package/dist/stream-broker/remoteEntry.js +1 -1
  27. package/dist/{worker-protocol-pk7qdYXt.mjs → worker-protocol-CyVJTZEO.mjs} +7 -0
  28. package/dist/{worker-protocol-BCfO8gUF.js → worker-protocol-PP4jKHHJ.js} +7 -0
  29. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-CqOe8eYa.js → MaskShapeCanvas-DI4BY7W2-BChW0ntM.js} +1 -1
  30. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-CZyLeUnd.js → MotionZonesSettings-NcxxQN8r-DDzqEbSe.js} +1 -1
  31. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-Cn0hGZnu.js → PrivacyMaskSettings-APgPLF7p-B879GXaf.js} +1 -1
  32. package/embed-dist/assets/{index-DRl4XYjA.js → index-CNjQ5rAE.js} +10 -10
  33. package/embed-dist/index.html +1 -1
  34. package/package.json +1 -1
  35. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-o4tu_xuc.mjs +0 -26
@@ -0,0 +1,1479 @@
1
+ import { S as hfModelUrl, a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS } from "./dist-RWGGPwVx.mjs";
2
+ //#region src/detection-pipeline/registry/model-catalogs.ts
3
+ var HF_REPO = "camstack/camstack-models";
4
+ var HF_SCRYPTED = "scrypted/plugin-models";
5
+ var hf = (path) => hfModelUrl(HF_REPO, path);
6
+ var hfScrypted = (path) => hfModelUrl(HF_SCRYPTED, path);
7
+ /**
8
+ * Build an OpenVINO format entry (always python runtime).
9
+ *
10
+ * OpenVINO IR is a two-file bundle: a `.xml` topology + a sibling `.bin`
11
+ * weights file with the same basename. We declare the `.bin` in `files` so
12
+ * the (format-agnostic) downloader fetches it alongside the `.xml` — without
13
+ * the weights, OpenVINO compile fails with "Empty weights data in bin file".
14
+ * A plain `.onnx` run through the OpenVINO runtime (e.g. yamnet) has no
15
+ * sibling, so none is added.
16
+ */
17
+ var ovFormat = (url, sizeMB) => {
18
+ const base = url.split("/").pop() ?? "";
19
+ const files = base.endsWith(".xml") ? [base.replace(/\.xml$/, ".bin")] : void 0;
20
+ return {
21
+ url,
22
+ sizeMB,
23
+ runtimes: ["python"],
24
+ ...files ? { files } : {}
25
+ };
26
+ };
27
+ /**
28
+ * Build a precision-variant catalog entry (OpenVINO-only) derived from a base
29
+ * detection model. fp16 halves the weights (Intel iGPU/NPU sweet spot); int8 is
30
+ * NNCF post-training-quantized (~4× smaller, fastest on CPU/iGPU at a small
31
+ * accuracy cost). The IRs live next to the base `.xml` on HF as
32
+ * `camstack-<id>-<precision>.xml`. Lets an operator scale the model to the node
33
+ * (e.g. yolo26x-int8 on a 265K, yolo26n-int8 on an N100).
34
+ */
35
+ var ovPrecisionVariant = (baseId, ovDir, baseName, precision, sizeMB, legacy = false) => ({
36
+ id: `${baseId}-${precision}`,
37
+ name: `${baseName} (${precision.toUpperCase()})`,
38
+ description: `${baseName} — OpenVINO ${precision.toUpperCase()} variant for Intel iGPU/NPU; scale by hardware`,
39
+ inputSize: {
40
+ width: 640,
41
+ height: 640
42
+ },
43
+ labels: [],
44
+ preprocessMode: "letterbox",
45
+ formats: { openvino: ovFormat(hf(`${ovDir}/camstack-${baseId}-${precision}.xml`), sizeMB) },
46
+ ...legacy ? { legacy: true } : {},
47
+ ...precision === "int8" ? { group: {
48
+ family: baseId.slice(0, -1),
49
+ tier: baseId.slice(-1),
50
+ precision: "int8"
51
+ } } : {}
52
+ });
53
+ var MLPACKAGE_FILES = [
54
+ "Manifest.json",
55
+ "Data/com.apple.CoreML/model.mlmodel",
56
+ "Data/com.apple.CoreML/weights/weight.bin"
57
+ ];
58
+ var YOLO26_TIER_NAME = {
59
+ n: "Nano",
60
+ s: "Small",
61
+ m: "Medium",
62
+ l: "Large"
63
+ };
64
+ /**
65
+ * Reduced-input YOLO26 variants (2026-07-11). A lower square input (320 / 256)
66
+ * is the biggest, cheapest latency lever measured across every runtime — Mac
67
+ * ANE, Intel Ultra NPU, and especially the N100 — at a small-object accuracy
68
+ * cost. Each resolution ships a base (fp32) entry (onnx + coreml + openvino)
69
+ * grouped under `{family, tier, resolution}`, plus an OpenVINO INT8 entry (best
70
+ * on Intel/N100) grouped with `precision:'int8'`. The grouped selector surfaces
71
+ * `resolution` as a variant axis alongside precision.
72
+ */
73
+ var yolo26Reduced = (tier, res, sizes) => {
74
+ const name = YOLO26_TIER_NAME[tier] ?? tier.toUpperCase();
75
+ return [{
76
+ id: `yolo26${tier}-${res}`,
77
+ group: {
78
+ family: "yolo26",
79
+ tier,
80
+ resolution: res
81
+ },
82
+ name: `YOLO26 ${name} @${res}`,
83
+ description: `YOLO26 ${name}, reduced ${res}×${res} input — faster on ANE / hub NPU / N100 at a small-object accuracy cost`,
84
+ inputSize: {
85
+ width: res,
86
+ height: res
87
+ },
88
+ labels: [],
89
+ preprocessMode: "letterbox",
90
+ formats: {
91
+ onnx: {
92
+ url: hf(`objectDetection/yolo26/onnx/camstack-yolo26${tier}-${res}.onnx`),
93
+ sizeMB: sizes.onnx
94
+ },
95
+ coreml: {
96
+ url: hf(`objectDetection/yolo26/coreml/camstack-yolo26${tier}-${res}.mlpackage`),
97
+ sizeMB: sizes.coreml,
98
+ isDirectory: true,
99
+ files: [...MLPACKAGE_FILES],
100
+ runtimes: ["python"]
101
+ },
102
+ openvino: ovFormat(hf(`objectDetection/yolo26/openvino/camstack-yolo26${tier}-${res}.xml`), sizes.ovFp32)
103
+ }
104
+ }, {
105
+ id: `yolo26${tier}-${res}-int8`,
106
+ group: {
107
+ family: "yolo26",
108
+ tier,
109
+ precision: "int8",
110
+ resolution: res
111
+ },
112
+ name: `YOLO26 ${name} @${res} (INT8)`,
113
+ description: `YOLO26 ${name} @${res} — OpenVINO INT8 for Intel iGPU/CPU; the N100's fastest config`,
114
+ inputSize: {
115
+ width: res,
116
+ height: res
117
+ },
118
+ labels: [],
119
+ preprocessMode: "letterbox",
120
+ formats: { openvino: ovFormat(hf(`objectDetection/yolo26/openvino/camstack-yolo26${tier}-${res}-int8.xml`), sizes.ovInt8) }
121
+ }];
122
+ };
123
+ var OBJECT_DETECTION_MODELS = [
124
+ {
125
+ id: "yolov9t",
126
+ legacy: true,
127
+ name: "YOLOv9 Tiny",
128
+ description: "YOLOv9 Tiny — ultra-lightweight next-gen detector",
129
+ inputSize: {
130
+ width: 640,
131
+ height: 640
132
+ },
133
+ labels: [],
134
+ preprocessMode: "letterbox",
135
+ formats: {
136
+ onnx: {
137
+ url: hf("objectDetection/yolov9/onnx/camstack-yolov9t.onnx"),
138
+ sizeMB: 8
139
+ },
140
+ coreml: {
141
+ url: hf("objectDetection/yolov9/coreml/camstack-yolov9t.mlpackage"),
142
+ sizeMB: 4,
143
+ isDirectory: true,
144
+ files: [...MLPACKAGE_FILES],
145
+ runtimes: ["python"]
146
+ },
147
+ openvino: ovFormat(hf("objectDetection/yolov9/openvino/camstack-yolov9t.xml"), 6)
148
+ }
149
+ },
150
+ {
151
+ id: "yolov9s",
152
+ legacy: true,
153
+ name: "YOLOv9 Small",
154
+ description: "YOLOv9 Small — improved efficiency over YOLOv8s",
155
+ inputSize: {
156
+ width: 640,
157
+ height: 640
158
+ },
159
+ labels: [],
160
+ preprocessMode: "letterbox",
161
+ formats: {
162
+ onnx: {
163
+ url: hf("objectDetection/yolov9/onnx/camstack-yolov9s.onnx"),
164
+ sizeMB: 28
165
+ },
166
+ coreml: {
167
+ url: hf("objectDetection/yolov9/coreml/camstack-yolov9s.mlpackage"),
168
+ sizeMB: 14,
169
+ isDirectory: true,
170
+ files: [...MLPACKAGE_FILES],
171
+ runtimes: ["python"]
172
+ },
173
+ openvino: ovFormat(hf("objectDetection/yolov9/openvino/camstack-yolov9s.xml"), 16)
174
+ }
175
+ },
176
+ {
177
+ id: "yolov9c",
178
+ legacy: true,
179
+ name: "YOLOv9 C",
180
+ description: "YOLOv9 C — high-accuracy compact model",
181
+ inputSize: {
182
+ width: 640,
183
+ height: 640
184
+ },
185
+ labels: [],
186
+ preprocessMode: "letterbox",
187
+ formats: {
188
+ onnx: {
189
+ url: hf("objectDetection/yolov9/onnx/camstack-yolov9c.onnx"),
190
+ sizeMB: 97
191
+ },
192
+ coreml: {
193
+ url: hf("objectDetection/yolov9/coreml/camstack-yolov9c.mlpackage"),
194
+ sizeMB: 48,
195
+ isDirectory: true,
196
+ files: [...MLPACKAGE_FILES],
197
+ runtimes: ["python"]
198
+ },
199
+ openvino: ovFormat(hf("objectDetection/yolov9/openvino/camstack-yolov9c.xml"), 49)
200
+ }
201
+ },
202
+ {
203
+ id: "yolo26n",
204
+ group: {
205
+ family: "yolo26",
206
+ tier: "n"
207
+ },
208
+ name: "YOLO26 Nano",
209
+ description: "YOLO26 Nano — latest generation ultra-lightweight detector with attention mechanism",
210
+ inputSize: {
211
+ width: 640,
212
+ height: 640
213
+ },
214
+ labels: [],
215
+ preprocessMode: "letterbox",
216
+ formats: {
217
+ onnx: {
218
+ url: hf("objectDetection/yolo26/onnx/camstack-yolo26n.onnx"),
219
+ sizeMB: 10
220
+ },
221
+ coreml: {
222
+ url: hf("objectDetection/yolo26/coreml/camstack-yolo26n.mlpackage"),
223
+ sizeMB: 5,
224
+ isDirectory: true,
225
+ files: [...MLPACKAGE_FILES],
226
+ runtimes: ["python"]
227
+ },
228
+ openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26n.xml"), 9)
229
+ }
230
+ },
231
+ {
232
+ id: "yolo26s",
233
+ group: {
234
+ family: "yolo26",
235
+ tier: "s"
236
+ },
237
+ name: "YOLO26 Small",
238
+ description: "YOLO26 Small — balanced speed/accuracy with attention-based architecture",
239
+ inputSize: {
240
+ width: 640,
241
+ height: 640
242
+ },
243
+ labels: [],
244
+ preprocessMode: "letterbox",
245
+ formats: {
246
+ onnx: {
247
+ url: hf("objectDetection/yolo26/onnx/camstack-yolo26s.onnx"),
248
+ sizeMB: 37
249
+ },
250
+ coreml: {
251
+ url: hf("objectDetection/yolo26/coreml/camstack-yolo26s.mlpackage"),
252
+ sizeMB: 18,
253
+ isDirectory: true,
254
+ files: [...MLPACKAGE_FILES],
255
+ runtimes: ["python"]
256
+ },
257
+ openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26s.xml"), 36)
258
+ }
259
+ },
260
+ {
261
+ id: "yolo26m",
262
+ group: {
263
+ family: "yolo26",
264
+ tier: "m"
265
+ },
266
+ name: "YOLO26 Medium",
267
+ description: "YOLO26 Medium — high accuracy general-purpose detector",
268
+ inputSize: {
269
+ width: 640,
270
+ height: 640
271
+ },
272
+ labels: [],
273
+ preprocessMode: "letterbox",
274
+ formats: {
275
+ onnx: {
276
+ url: hf("objectDetection/yolo26/onnx/camstack-yolo26m.onnx"),
277
+ sizeMB: 78
278
+ },
279
+ coreml: {
280
+ url: hf("objectDetection/yolo26/coreml/camstack-yolo26m.mlpackage"),
281
+ sizeMB: 39,
282
+ isDirectory: true,
283
+ files: [...MLPACKAGE_FILES],
284
+ runtimes: ["python"]
285
+ },
286
+ openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26m.xml"), 78)
287
+ }
288
+ },
289
+ {
290
+ id: "yolo26l",
291
+ group: {
292
+ family: "yolo26",
293
+ tier: "l"
294
+ },
295
+ name: "YOLO26 Large",
296
+ description: "YOLO26 Large — maximum accuracy for demanding deployments",
297
+ inputSize: {
298
+ width: 640,
299
+ height: 640
300
+ },
301
+ labels: [],
302
+ preprocessMode: "letterbox",
303
+ formats: {
304
+ onnx: {
305
+ url: hf("objectDetection/yolo26/onnx/camstack-yolo26l.onnx"),
306
+ sizeMB: 95
307
+ },
308
+ coreml: {
309
+ url: hf("objectDetection/yolo26/coreml/camstack-yolo26l.mlpackage"),
310
+ sizeMB: 48,
311
+ isDirectory: true,
312
+ files: [...MLPACKAGE_FILES],
313
+ runtimes: ["python"]
314
+ },
315
+ openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26l.xml"), 95)
316
+ }
317
+ },
318
+ {
319
+ id: "yolo26x",
320
+ legacy: true,
321
+ name: "YOLO26 XLarge",
322
+ description: "YOLO26 XLarge — highest accuracy, attention-based architecture",
323
+ inputSize: {
324
+ width: 640,
325
+ height: 640
326
+ },
327
+ labels: [],
328
+ preprocessMode: "letterbox",
329
+ formats: {
330
+ onnx: {
331
+ url: hf("objectDetection/yolo26/onnx/camstack-yolo26x.onnx"),
332
+ sizeMB: 213
333
+ },
334
+ coreml: {
335
+ url: hf("objectDetection/yolo26/coreml/camstack-yolo26x.mlpackage"),
336
+ sizeMB: 107,
337
+ isDirectory: true,
338
+ files: [...MLPACKAGE_FILES],
339
+ runtimes: ["python"]
340
+ },
341
+ openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26x.xml"), 213)
342
+ }
343
+ },
344
+ {
345
+ id: "scrypted-yolov9t-relu",
346
+ legacy: true,
347
+ name: "YOLOv9 Tiny ReLU",
348
+ description: "YOLOv9t ReLU — optimized for int8 quantization",
349
+ inputSize: {
350
+ width: 320,
351
+ height: 320
352
+ },
353
+ labels: [],
354
+ preprocessMode: "letterbox",
355
+ formats: {
356
+ onnx: {
357
+ url: hfScrypted("onnx/scrypted_yolov9t_relu/scrypted_yolov9t_relu.onnx"),
358
+ sizeMB: 8.1
359
+ },
360
+ coreml: {
361
+ url: hfScrypted("coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage"),
362
+ sizeMB: 4,
363
+ isDirectory: true,
364
+ files: [...MLPACKAGE_FILES],
365
+ runtimes: ["python"]
366
+ },
367
+ openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9t_relu.xml"), 6)
368
+ }
369
+ },
370
+ {
371
+ id: "scrypted-yolov9s-relu",
372
+ legacy: true,
373
+ name: "YOLOv9 Small ReLU",
374
+ description: "YOLOv9s ReLU — improved efficiency, int8 ready",
375
+ inputSize: {
376
+ width: 320,
377
+ height: 320
378
+ },
379
+ labels: [],
380
+ preprocessMode: "letterbox",
381
+ formats: {
382
+ onnx: {
383
+ url: hfScrypted("onnx/scrypted_yolov9s_relu/scrypted_yolov9s_relu.onnx"),
384
+ sizeMB: 27.9
385
+ },
386
+ coreml: {
387
+ url: hfScrypted("coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage"),
388
+ sizeMB: 14,
389
+ isDirectory: true,
390
+ files: [...MLPACKAGE_FILES],
391
+ runtimes: ["python"]
392
+ },
393
+ openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9s_relu.xml"), 16)
394
+ }
395
+ },
396
+ {
397
+ id: "scrypted-yolov9c-relu",
398
+ legacy: true,
399
+ name: "YOLOv9 C ReLU",
400
+ description: "YOLOv9c ReLU — high-accuracy, int8 ready",
401
+ inputSize: {
402
+ width: 320,
403
+ height: 320
404
+ },
405
+ labels: [],
406
+ preprocessMode: "letterbox",
407
+ formats: {
408
+ onnx: {
409
+ url: hfScrypted("onnx/scrypted_yolov9c_relu/scrypted_yolov9c_relu.onnx"),
410
+ sizeMB: 96.9
411
+ },
412
+ coreml: {
413
+ url: hfScrypted("coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage"),
414
+ sizeMB: 48,
415
+ isDirectory: true,
416
+ files: [...MLPACKAGE_FILES],
417
+ runtimes: ["python"]
418
+ },
419
+ openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9c_relu.xml"), 49)
420
+ }
421
+ },
422
+ {
423
+ id: "scrypted-yolov9m-relu",
424
+ legacy: true,
425
+ name: "YOLOv9 M ReLU",
426
+ description: "YOLOv9m ReLU — medium, int8 ready",
427
+ inputSize: {
428
+ width: 320,
429
+ height: 320
430
+ },
431
+ labels: [],
432
+ preprocessMode: "letterbox",
433
+ formats: {
434
+ onnx: {
435
+ url: hfScrypted("onnx/scrypted_yolov9m_relu/scrypted_yolov9m_relu.onnx"),
436
+ sizeMB: 76.6
437
+ },
438
+ coreml: {
439
+ url: hfScrypted("coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage"),
440
+ sizeMB: 38,
441
+ isDirectory: true,
442
+ files: [...MLPACKAGE_FILES],
443
+ runtimes: ["python"]
444
+ },
445
+ openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9m_relu.xml"), 38)
446
+ }
447
+ },
448
+ ovPrecisionVariant("yolov9t", "objectDetection/yolov9/openvino", "YOLOv9 Tiny", "fp16", 5, true),
449
+ ovPrecisionVariant("yolov9t", "objectDetection/yolov9/openvino", "YOLOv9 Tiny", "int8", 3, true),
450
+ ovPrecisionVariant("yolov9s", "objectDetection/yolov9/openvino", "YOLOv9 Small", "fp16", 15, true),
451
+ ovPrecisionVariant("yolov9s", "objectDetection/yolov9/openvino", "YOLOv9 Small", "int8", 8, true),
452
+ ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "fp16", 5, true),
453
+ ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "int8", 3),
454
+ ovPrecisionVariant("yolo26s", "objectDetection/yolo26/openvino", "YOLO26 Small", "fp16", 19, true),
455
+ ovPrecisionVariant("yolo26s", "objectDetection/yolo26/openvino", "YOLO26 Small", "int8", 10),
456
+ ovPrecisionVariant("yolo26m", "objectDetection/yolo26/openvino", "YOLO26 Medium", "fp16", 41, true),
457
+ ovPrecisionVariant("yolo26m", "objectDetection/yolo26/openvino", "YOLO26 Medium", "int8", 21),
458
+ ovPrecisionVariant("yolo26l", "objectDetection/yolo26/openvino", "YOLO26 Large", "fp16", 50, true),
459
+ ovPrecisionVariant("yolo26l", "objectDetection/yolo26/openvino", "YOLO26 Large", "int8", 25),
460
+ ...yolo26Reduced("n", 320, {
461
+ onnx: 10.47,
462
+ coreml: 5.05,
463
+ ovFp32: 10.05,
464
+ ovInt8: 3.29
465
+ }),
466
+ ...yolo26Reduced("n", 256, {
467
+ onnx: 10.47,
468
+ coreml: 5.05,
469
+ ovFp32: 10.05,
470
+ ovInt8: 3.29
471
+ }),
472
+ ...yolo26Reduced("s", 320, {
473
+ onnx: 38.82,
474
+ coreml: 19.23,
475
+ ovFp32: 38.4,
476
+ ovInt8: 10.43
477
+ }),
478
+ ...yolo26Reduced("s", 256, {
479
+ onnx: 38.82,
480
+ coreml: 19.23,
481
+ ovFp32: 38.4,
482
+ ovInt8: 10.43
483
+ }),
484
+ ...yolo26Reduced("m", 320, {
485
+ onnx: 83.31,
486
+ coreml: 41.07,
487
+ ovFp32: 82.09,
488
+ ovInt8: 21.47
489
+ }),
490
+ ...yolo26Reduced("m", 256, {
491
+ onnx: 83.31,
492
+ coreml: 41.07,
493
+ ovFp32: 82.09,
494
+ ovInt8: 21.47
495
+ }),
496
+ ...yolo26Reduced("l", 320, {
497
+ onnx: 101.74,
498
+ coreml: 49.97,
499
+ ovFp32: 99.85,
500
+ ovInt8: 26.31
501
+ }),
502
+ ...yolo26Reduced("l", 256, {
503
+ onnx: 101.74,
504
+ coreml: 49.97,
505
+ ovFp32: 99.85,
506
+ ovInt8: 26.31
507
+ }),
508
+ ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "fp16", 112, true),
509
+ ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "int8", 56, true)
510
+ ];
511
+ var FACE_DETECTION_MODELS = [{
512
+ id: "scrfd-2.5g",
513
+ name: "SCRFD 2.5G",
514
+ description: "SCRFD 2.5G — balanced face detection model",
515
+ inputSize: {
516
+ width: 640,
517
+ height: 640
518
+ },
519
+ labels: [{
520
+ id: "face",
521
+ name: "Face"
522
+ }],
523
+ preprocessMode: "letterbox",
524
+ formats: {
525
+ onnx: {
526
+ url: hf("faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx"),
527
+ sizeMB: 3.1
528
+ },
529
+ coreml: {
530
+ url: hf("faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage"),
531
+ sizeMB: 1.7,
532
+ isDirectory: true,
533
+ files: [...MLPACKAGE_FILES],
534
+ runtimes: ["python"]
535
+ },
536
+ openvino: ovFormat(hf("faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml"), 1.8)
537
+ }
538
+ }, {
539
+ id: "scrypted-yolov9t-face",
540
+ name: "YOLOv9t Face ReLU",
541
+ description: "YOLOv9t face detection — YOLO-based, fast, 320x320 ReLU",
542
+ inputSize: {
543
+ width: 320,
544
+ height: 320
545
+ },
546
+ labels: [{
547
+ id: "face",
548
+ name: "Face"
549
+ }],
550
+ preprocessMode: "letterbox",
551
+ formats: {
552
+ onnx: {
553
+ url: hfScrypted("onnx/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.onnx"),
554
+ sizeMB: 8.1
555
+ },
556
+ coreml: {
557
+ url: hfScrypted("coreml/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.mlpackage"),
558
+ sizeMB: 4,
559
+ isDirectory: true,
560
+ files: [...MLPACKAGE_FILES],
561
+ runtimes: ["python"]
562
+ },
563
+ openvino: ovFormat(hf("faceDetection/scrypted-yolov9-face/openvino/scrypted_yolov9t_relu_face.xml"), 6)
564
+ }
565
+ }];
566
+ var FACE_EMBEDDING_MODELS = [{
567
+ id: "arcface-r100",
568
+ name: "ArcFace R100",
569
+ description: "ArcFace ResNet-100 — high-accuracy face recognition embeddings (512-d)",
570
+ inputSize: {
571
+ width: 112,
572
+ height: 112
573
+ },
574
+ inputLayout: "nhwc",
575
+ labels: [{
576
+ id: "embedding",
577
+ name: "Face Embedding"
578
+ }],
579
+ preprocessMode: "resize",
580
+ faceAlignment: true,
581
+ formats: {
582
+ onnx: {
583
+ url: hf("faceRecognition/arcface/onnx/camstack-arcface-arcface.onnx"),
584
+ sizeMB: 130
585
+ },
586
+ coreml: {
587
+ url: hf("faceRecognition/arcface/coreml/camstack-arcface-r100.mlpackage"),
588
+ sizeMB: 65,
589
+ isDirectory: true,
590
+ files: [...MLPACKAGE_FILES],
591
+ runtimes: ["python"]
592
+ },
593
+ openvino: ovFormat(hf("faceRecognition/arcface/openvino/camstack-arcface-r100.xml"), 65)
594
+ }
595
+ }, {
596
+ id: "inception-resnet-v1",
597
+ name: "Inception ResNet V1",
598
+ description: "FaceNet-style face recognition embeddings (512-d) — hosted on plugin-models HF repo",
599
+ inputSize: {
600
+ width: 160,
601
+ height: 160
602
+ },
603
+ labels: [{
604
+ id: "embedding",
605
+ name: "Face Embedding"
606
+ }],
607
+ preprocessMode: "resize",
608
+ formats: {
609
+ onnx: {
610
+ url: hfScrypted("onnx/inception_resnet_v1/inception_resnet_v1.onnx"),
611
+ sizeMB: 89.6
612
+ },
613
+ coreml: {
614
+ url: hfScrypted("coreml/inception_resnet_v1/inception_resnet_v1.mlpackage"),
615
+ sizeMB: 45,
616
+ isDirectory: true,
617
+ files: [...MLPACKAGE_FILES],
618
+ runtimes: ["python"]
619
+ },
620
+ openvino: ovFormat(hf("faceRecognition/inception-resnet-v1/openvino/camstack-inception-resnet-v1.xml"), 45)
621
+ }
622
+ }];
623
+ var PLATE_DETECTION_MODELS = [{
624
+ id: "yolov8n-plate",
625
+ name: "YOLOv8 Nano — License Plate",
626
+ description: "YOLOv8 Nano fine-tuned for license plate detection",
627
+ inputSize: {
628
+ width: 640,
629
+ height: 640
630
+ },
631
+ labels: [{
632
+ id: "plate",
633
+ name: "License Plate"
634
+ }],
635
+ preprocessMode: "letterbox",
636
+ formats: {
637
+ onnx: {
638
+ url: hf("plateDetection/yolov8-plate/onnx/camstack-yolov8n-plate.onnx"),
639
+ sizeMB: 12
640
+ },
641
+ coreml: {
642
+ url: hf("plateDetection/yolov8-plate/coreml/camstack-yolov8n-plate.mlpackage"),
643
+ sizeMB: 5.9,
644
+ isDirectory: true,
645
+ files: [...MLPACKAGE_FILES],
646
+ runtimes: ["python"]
647
+ },
648
+ openvino: ovFormat(hf("plateDetection/yolov8-plate/openvino/camstack-yolov8n-plate.xml"), 6.1)
649
+ }
650
+ }];
651
+ var PLATE_OCR_MODELS = [{
652
+ id: "vgg-english-g2",
653
+ name: "VGG English G2",
654
+ description: "EasyOCR VGG English G2 — text recognition for license plates and scene text",
655
+ inputSize: {
656
+ width: 384,
657
+ height: 64
658
+ },
659
+ labels: [{
660
+ id: "text",
661
+ name: "Plate Text"
662
+ }],
663
+ preprocessMode: "resize",
664
+ formats: {
665
+ onnx: {
666
+ url: hfScrypted("onnx/vgg_english_g2/vgg_english_g2.onnx"),
667
+ sizeMB: 14.4
668
+ },
669
+ coreml: {
670
+ url: hfScrypted("coreml/vgg_english_g2/vgg_english_g2.mlpackage"),
671
+ sizeMB: 11.2,
672
+ isDirectory: true,
673
+ files: [...MLPACKAGE_FILES],
674
+ runtimes: ["python"]
675
+ },
676
+ openvino: ovFormat(hf("plateRecognition/vgg_english_g2/openvino/vgg_english_g2.xml"), 7.2)
677
+ }
678
+ }];
679
+ var ANIMAL_CLASSIFIER_MODELS = [{
680
+ id: "animals-10",
681
+ name: "Animal Classifier (10)",
682
+ description: "ViT-based animal type classifier — cat, cow, dog, dolphin, eagle, panda, horse, monkey, sheep, spider",
683
+ inputSize: {
684
+ width: 224,
685
+ height: 224
686
+ },
687
+ inputNormalization: "imagenet",
688
+ labels: [{
689
+ id: "animal-type",
690
+ name: "Animal Type"
691
+ }],
692
+ preprocessMode: "resize",
693
+ formats: {
694
+ onnx: {
695
+ url: hf("animalClassification/animals-10/onnx/camstack-animals-10.onnx"),
696
+ sizeMB: 328
697
+ },
698
+ coreml: {
699
+ url: hf("animalClassification/animals-10/coreml/camstack-animals-10.mlpackage"),
700
+ sizeMB: 164,
701
+ isDirectory: true,
702
+ files: [...MLPACKAGE_FILES],
703
+ runtimes: ["python"]
704
+ },
705
+ openvino: ovFormat(hf("animalClassification/animals-10/openvino/camstack-animals-10.xml"), 164)
706
+ }
707
+ }];
708
+ var BIRD_CLASSIFIER_MODELS = [{
709
+ id: "bird-nabirds-404",
710
+ name: "NABirds (404 species)",
711
+ description: "ResNet50 trained on NABirds — 404 North American species",
712
+ inputSize: {
713
+ width: 224,
714
+ height: 224
715
+ },
716
+ inputNormalization: "imagenet",
717
+ labels: [{
718
+ id: "species",
719
+ name: "Bird Species"
720
+ }],
721
+ preprocessMode: "resize",
722
+ formats: {
723
+ onnx: {
724
+ url: hf("animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404.onnx"),
725
+ sizeMB: 93
726
+ },
727
+ coreml: {
728
+ url: hf("animalClassification/bird-nabirds/coreml/camstack-bird-nabirds-404.mlpackage"),
729
+ sizeMB: 47,
730
+ isDirectory: true,
731
+ files: [...MLPACKAGE_FILES],
732
+ runtimes: ["python"]
733
+ },
734
+ openvino: ovFormat(hf("animalClassification/bird-nabirds/openvino/camstack-bird-nabirds-404.xml"), 47)
735
+ },
736
+ extraFiles: [{
737
+ url: hf("animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404-labels.json"),
738
+ filename: "camstack-bird-nabirds-404-labels.json",
739
+ sizeMB: .02
740
+ }]
741
+ }];
742
+ var VEHICLE_CLASSIFIER_MODELS = [{
743
+ id: "vehicle-type-efficientnet",
744
+ name: "Vehicle Type (EfficientNet)",
745
+ description: "EfficientNet-B4 vehicle make/model/year classifier — 8,949 classes from VMMRdb",
746
+ inputSize: {
747
+ width: 380,
748
+ height: 380
749
+ },
750
+ inputNormalization: "imagenet",
751
+ labels: [{
752
+ id: "vehicle-type",
753
+ name: "Vehicle Type"
754
+ }],
755
+ preprocessMode: "resize",
756
+ formats: {
757
+ onnx: {
758
+ url: hf("vehicleClassification/efficientnet/onnx/camstack-vehicle-type-efficientnet.onnx"),
759
+ sizeMB: 135
760
+ },
761
+ coreml: {
762
+ url: hf("vehicleClassification/efficientnet/coreml/camstack-vehicle-type-efficientnet.mlpackage"),
763
+ sizeMB: 10,
764
+ isDirectory: true,
765
+ files: [...MLPACKAGE_FILES],
766
+ runtimes: ["python"]
767
+ },
768
+ openvino: ovFormat(hf("vehicleClassification/efficientnet/openvino/camstack-vehicle-type-efficientnet.xml"), 68)
769
+ },
770
+ extraFiles: [{
771
+ url: hf("vehicleClassification/efficientnet/camstack-vehicle-type-labels.json"),
772
+ filename: "camstack-vehicle-type-labels.json",
773
+ sizeMB: .2
774
+ }]
775
+ }];
776
+ var SEGMENTATION_REFINER_MODELS = [{
777
+ id: "u2netp",
778
+ name: "U2-Net Portable",
779
+ description: "U2-Net-P — ultra-lightweight salient object segmentation (4.7 MB)",
780
+ inputSize: {
781
+ width: 320,
782
+ height: 320
783
+ },
784
+ labels: [{
785
+ id: "mask",
786
+ name: "Segmentation Mask"
787
+ }],
788
+ preprocessMode: "resize",
789
+ formats: {
790
+ onnx: {
791
+ url: hf("segmentationRefiner/u2netp/onnx/camstack-u2netp.onnx"),
792
+ sizeMB: 5
793
+ },
794
+ coreml: {
795
+ url: hf("segmentationRefiner/u2netp/coreml/camstack-u2netp.mlpackage"),
796
+ sizeMB: 3,
797
+ isDirectory: true,
798
+ files: [...MLPACKAGE_FILES],
799
+ runtimes: ["python"]
800
+ },
801
+ openvino: ovFormat(hf("segmentationRefiner/u2netp/openvino/camstack-u2netp.xml"), 2.5)
802
+ }
803
+ }];
804
+ var INSTANCE_SEGMENTATION_MODELS = [
805
+ {
806
+ id: "yolo26n-seg",
807
+ name: "YOLO26 Nano Seg",
808
+ description: "YOLO26 Nano Segmentation — ultra-lightweight instance segmentation with masks",
809
+ inputSize: {
810
+ width: 640,
811
+ height: 640
812
+ },
813
+ labels: [],
814
+ preprocessMode: "letterbox",
815
+ formats: {
816
+ onnx: {
817
+ url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26n-seg.onnx"),
818
+ sizeMB: 11
819
+ },
820
+ coreml: {
821
+ url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26n-seg.mlpackage"),
822
+ sizeMB: 6,
823
+ isDirectory: true,
824
+ files: [...MLPACKAGE_FILES],
825
+ runtimes: ["python"]
826
+ },
827
+ openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26n-seg.xml"), 11)
828
+ }
829
+ },
830
+ {
831
+ id: "yolo26s-seg",
832
+ name: "YOLO26 Small Seg",
833
+ description: "YOLO26 Small Segmentation — balanced instance segmentation",
834
+ inputSize: {
835
+ width: 640,
836
+ height: 640
837
+ },
838
+ labels: [],
839
+ preprocessMode: "letterbox",
840
+ formats: {
841
+ onnx: {
842
+ url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26s-seg.onnx"),
843
+ sizeMB: 40
844
+ },
845
+ coreml: {
846
+ url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26s-seg.mlpackage"),
847
+ sizeMB: 20,
848
+ isDirectory: true,
849
+ files: [...MLPACKAGE_FILES],
850
+ runtimes: ["python"]
851
+ },
852
+ openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26s-seg.xml"), 40)
853
+ }
854
+ },
855
+ {
856
+ id: "yolo26m-seg",
857
+ name: "YOLO26 Medium Seg",
858
+ description: "YOLO26 Medium Segmentation — high-accuracy instance segmentation",
859
+ inputSize: {
860
+ width: 640,
861
+ height: 640
862
+ },
863
+ labels: [],
864
+ preprocessMode: "letterbox",
865
+ formats: {
866
+ onnx: {
867
+ url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26m-seg.onnx"),
868
+ sizeMB: 90
869
+ },
870
+ coreml: {
871
+ url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26m-seg.mlpackage"),
872
+ sizeMB: 45,
873
+ isDirectory: true,
874
+ files: [...MLPACKAGE_FILES],
875
+ runtimes: ["python"]
876
+ },
877
+ openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26m-seg.xml"), 90)
878
+ }
879
+ }
880
+ ];
881
+ var CLIP_EMBEDDING_MODELS = [
882
+ {
883
+ id: "mobileclip-s0",
884
+ name: "MobileCLIP S0",
885
+ description: "MobileCLIP S0 — Apple ultra-fast CLIP vision encoder, 512-dim, 256×256 (40 MB ONNX)",
886
+ inputSize: {
887
+ width: 256,
888
+ height: 256
889
+ },
890
+ labels: [{
891
+ id: "embedding",
892
+ name: "CLIP Embedding"
893
+ }],
894
+ preprocessMode: "resize",
895
+ inputNormalization: "none",
896
+ formats: {
897
+ onnx: {
898
+ url: hf("clip/mobileclip-s0/onnx/camstack-mobileclip-s0-vision.onnx"),
899
+ sizeMB: 40
900
+ },
901
+ openvino: ovFormat(hf("clip/mobileclip-s0/openvino/camstack-mobileclip-s0-vision.xml"), 25),
902
+ coreml: {
903
+ url: hf("clip/mobileclip-s0/coreml/camstack-mobileclip-s0-vision.mlpackage"),
904
+ sizeMB: 30,
905
+ isDirectory: true,
906
+ files: [...MLPACKAGE_FILES],
907
+ runtimes: ["python"]
908
+ }
909
+ }
910
+ },
911
+ {
912
+ id: "mobileclip-s1",
913
+ name: "MobileCLIP S1",
914
+ description: "MobileCLIP S1 — Apple balanced CLIP vision encoder, 512-dim, 256×256 (90 MB ONNX)",
915
+ inputSize: {
916
+ width: 256,
917
+ height: 256
918
+ },
919
+ labels: [{
920
+ id: "embedding",
921
+ name: "CLIP Embedding"
922
+ }],
923
+ preprocessMode: "resize",
924
+ inputNormalization: "none",
925
+ formats: {
926
+ onnx: {
927
+ url: hf("clip/mobileclip-s1/onnx/camstack-mobileclip-s1-vision.onnx"),
928
+ sizeMB: 90
929
+ },
930
+ openvino: ovFormat(hf("clip/mobileclip-s1/openvino/camstack-mobileclip-s1-vision.xml"), 55),
931
+ coreml: {
932
+ url: hf("clip/mobileclip-s1/coreml/camstack-mobileclip-s1-vision.mlpackage"),
933
+ sizeMB: 65,
934
+ isDirectory: true,
935
+ files: [...MLPACKAGE_FILES],
936
+ runtimes: ["python"]
937
+ }
938
+ }
939
+ },
940
+ {
941
+ id: "mobileclip-s2",
942
+ name: "MobileCLIP S2",
943
+ description: "MobileCLIP S2 — Apple high-accuracy CLIP vision encoder, 512-dim, 256×256 (150 MB ONNX)",
944
+ inputSize: {
945
+ width: 256,
946
+ height: 256
947
+ },
948
+ labels: [{
949
+ id: "embedding",
950
+ name: "CLIP Embedding"
951
+ }],
952
+ preprocessMode: "resize",
953
+ inputNormalization: "none",
954
+ formats: {
955
+ onnx: {
956
+ url: hf("clip/mobileclip-s2/onnx/camstack-mobileclip-s2-vision.onnx"),
957
+ sizeMB: 150
958
+ },
959
+ openvino: ovFormat(hf("clip/mobileclip-s2/openvino/camstack-mobileclip-s2-vision.xml"), 90),
960
+ coreml: {
961
+ url: hf("clip/mobileclip-s2/coreml/camstack-mobileclip-s2-vision.mlpackage"),
962
+ sizeMB: 110,
963
+ isDirectory: true,
964
+ files: [...MLPACKAGE_FILES],
965
+ runtimes: ["python"]
966
+ }
967
+ }
968
+ }
969
+ ];
970
+ var AUDIO_CLASSIFIER_MODELS = [{
971
+ id: "yamnet-onnx",
972
+ name: "YAMNet",
973
+ description: "Google YAMNet — 521-class audio event classifier (3.2 MB ONNX, runs on any platform)",
974
+ inputSize: {
975
+ width: 1,
976
+ height: 16e3
977
+ },
978
+ labels: [],
979
+ preprocessMode: "resize",
980
+ formats: {
981
+ onnx: {
982
+ url: hf("audioClassification/yamnet/onnx/camstack-yamnet.onnx"),
983
+ sizeMB: 3.2
984
+ },
985
+ openvino: ovFormat(hf("audioClassification/yamnet/openvino/camstack-yamnet.xml"), 3.2),
986
+ coreml: {
987
+ url: hf("audioClassification/yamnet/onnx/camstack-yamnet.onnx"),
988
+ sizeMB: 3.2,
989
+ runtimes: ["python"]
990
+ }
991
+ }
992
+ }, {
993
+ id: "apple-soundanalysis",
994
+ name: "Apple SoundAnalysis",
995
+ description: "macOS built-in — 303 sound categories, Neural Engine accelerated, zero download",
996
+ inputSize: {
997
+ width: 1,
998
+ height: 16e3
999
+ },
1000
+ labels: [],
1001
+ preprocessMode: "resize",
1002
+ formats: { coreml: {
1003
+ url: "",
1004
+ sizeMB: 0
1005
+ } }
1006
+ }];
1007
+ //#endregion
1008
+ //#region src/detection-pipeline/registry/step-definitions.ts
1009
+ var ANIMAL_10_LABELS = [
1010
+ "cat",
1011
+ "cow",
1012
+ "dog",
1013
+ "dolphin",
1014
+ "eagle",
1015
+ "giant panda",
1016
+ "horse",
1017
+ "monkey",
1018
+ "sheep",
1019
+ "spider"
1020
+ ];
1021
+ var VGG_G2_CHARSET = ["", ..."0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("")];
1022
+ /**
1023
+ * Detail-subtree dispatch cadence a `PipelineStepBase` step gets when its
1024
+ * definition literal doesn't declare one explicitly. Conservative default
1025
+ * for the "specialized, opt-in" classifier steps that predate the cadence
1026
+ * table — dispatch once per track, cap at 3 attempts.
1027
+ */
1028
+ var DEFAULT_STEP_CADENCE = {
1029
+ trigger: "once",
1030
+ maxPerTrack: 3
1031
+ };
1032
+ var PipelineStepBase = class {
1033
+ definition;
1034
+ constructor(definition) {
1035
+ this.definition = {
1036
+ ...definition,
1037
+ cadence: definition.cadence ?? DEFAULT_STEP_CADENCE
1038
+ };
1039
+ }
1040
+ getConfigSchema() {
1041
+ return [];
1042
+ }
1043
+ };
1044
+ var ObjectDetectionStep = class {
1045
+ definition = {
1046
+ id: "object-detection",
1047
+ name: "Object Detection",
1048
+ slot: "detector",
1049
+ postprocessor: "yolo",
1050
+ extractMode: "full-frame",
1051
+ inputClasses: null,
1052
+ outputClasses: [
1053
+ "person",
1054
+ "vehicle",
1055
+ "animal"
1056
+ ],
1057
+ models: [...OBJECT_DETECTION_MODELS],
1058
+ defaultModelId: "yolo26n",
1059
+ defaultConfidence: .5,
1060
+ labels: COCO_80_LABELS.map((l) => l.id),
1061
+ classMap: COCO_TO_MACRO
1062
+ };
1063
+ getConfigSchema() {
1064
+ return [
1065
+ {
1066
+ type: "multiselect",
1067
+ key: "enabledMacroClasses",
1068
+ label: "Enabled Classes",
1069
+ description: "Which macro classes to detect (empty = all three).",
1070
+ options: [
1071
+ {
1072
+ value: "person",
1073
+ label: "Person"
1074
+ },
1075
+ {
1076
+ value: "vehicle",
1077
+ label: "Vehicle"
1078
+ },
1079
+ {
1080
+ value: "animal",
1081
+ label: "Animal"
1082
+ }
1083
+ ],
1084
+ default: [
1085
+ "person",
1086
+ "vehicle",
1087
+ "animal"
1088
+ ]
1089
+ },
1090
+ {
1091
+ type: "slider",
1092
+ key: "minConfidencePerson",
1093
+ label: "Min Confidence — Person",
1094
+ description: "Drop person predictions below this score.",
1095
+ min: 0,
1096
+ max: 1,
1097
+ step: .05,
1098
+ default: .5,
1099
+ showValue: true
1100
+ },
1101
+ {
1102
+ type: "slider",
1103
+ key: "minConfidenceVehicle",
1104
+ label: "Min Confidence — Vehicle",
1105
+ description: "Drop vehicle predictions below this score.",
1106
+ min: 0,
1107
+ max: 1,
1108
+ step: .05,
1109
+ default: .5,
1110
+ showValue: true
1111
+ },
1112
+ {
1113
+ type: "slider",
1114
+ key: "minConfidenceAnimal",
1115
+ label: "Min Confidence — Animal",
1116
+ description: "Drop animal predictions below this score.",
1117
+ min: 0,
1118
+ max: 1,
1119
+ step: .05,
1120
+ default: .5,
1121
+ showValue: true
1122
+ }
1123
+ ];
1124
+ }
1125
+ };
1126
+ var AudioClassifierStep = class {
1127
+ definition = {
1128
+ id: "audio-classifier",
1129
+ name: "Audio Classifier",
1130
+ slot: "audio-classifier",
1131
+ postprocessor: "yamnet",
1132
+ extractMode: "full-frame",
1133
+ inputClasses: null,
1134
+ outputClasses: ["audio"],
1135
+ models: [...AUDIO_CLASSIFIER_MODELS],
1136
+ defaultModelId: "yamnet-onnx",
1137
+ defaultModelIdByFormat: { coreml: "apple-soundanalysis" },
1138
+ enabledByDefault: true,
1139
+ defaultConfidence: .3
1140
+ };
1141
+ getConfigSchema() {
1142
+ return [{
1143
+ type: "multiselect",
1144
+ key: "enabledAudioClasses",
1145
+ label: "Audio Classes",
1146
+ description: "Which audio macro classes to surface (empty = all).",
1147
+ options: AUDIO_MACRO_LABELS.map((l) => ({
1148
+ value: l.id,
1149
+ label: `${l.icon ?? ""} ${l.name}`.trim()
1150
+ })),
1151
+ default: [
1152
+ "scream",
1153
+ "crying",
1154
+ "dog",
1155
+ "alarm",
1156
+ "doorbell",
1157
+ "glass_breaking",
1158
+ "gunshot",
1159
+ "siren",
1160
+ "footsteps"
1161
+ ]
1162
+ }, {
1163
+ type: "slider",
1164
+ key: "minConfidence",
1165
+ label: "Min Confidence",
1166
+ description: "Drop predictions whose score is below this threshold.",
1167
+ default: .3,
1168
+ min: 0,
1169
+ max: 1,
1170
+ step: .05,
1171
+ showValue: true
1172
+ }];
1173
+ }
1174
+ };
1175
+ var AnimalClassifierStep = class {
1176
+ definition = {
1177
+ id: "animal-classifier",
1178
+ name: "Animal Classifier",
1179
+ slot: "classifier",
1180
+ postprocessor: "softmax",
1181
+ extractMode: "crop-roi",
1182
+ inputClasses: ["animal"],
1183
+ outputClasses: ["animal-type"],
1184
+ models: [...ANIMAL_CLASSIFIER_MODELS],
1185
+ defaultModelId: "animals-10",
1186
+ enabledByDefault: false,
1187
+ defaultConfidence: .2,
1188
+ labels: [...ANIMAL_10_LABELS],
1189
+ cadence: {
1190
+ trigger: "once",
1191
+ maxPerTrack: 3,
1192
+ stickyOnConfidence: .7
1193
+ }
1194
+ };
1195
+ getConfigSchema() {
1196
+ return [{
1197
+ type: "multiselect",
1198
+ key: "enabledClasses",
1199
+ label: "Species",
1200
+ description: "Which animal species to keep (empty = all). The classifier still scores every label but only the selected classes are returned on the detection.",
1201
+ options: ANIMAL_10_LABELS.map((l) => ({
1202
+ value: l,
1203
+ label: l
1204
+ })),
1205
+ default: []
1206
+ }, {
1207
+ type: "slider",
1208
+ key: "minConfidence",
1209
+ label: "Min Confidence",
1210
+ description: "Drop classifications whose score is below this threshold.",
1211
+ default: this.definition.defaultConfidence,
1212
+ min: 0,
1213
+ max: 1,
1214
+ step: .05,
1215
+ showValue: true
1216
+ }];
1217
+ }
1218
+ };
1219
+ var ClassifierWithMinConfidence = class extends PipelineStepBase {
1220
+ getConfigSchema() {
1221
+ return [{
1222
+ type: "slider",
1223
+ key: "minConfidence",
1224
+ label: "Min Confidence",
1225
+ description: "Drop classifications whose score is below this threshold.",
1226
+ default: this.definition.defaultConfidence,
1227
+ min: 0,
1228
+ max: 1,
1229
+ step: .05,
1230
+ showValue: true
1231
+ }];
1232
+ }
1233
+ };
1234
+ var STEP_FACE_DETECTION = new PipelineStepBase({
1235
+ id: "face-detection",
1236
+ name: "Face Detection",
1237
+ slot: "cropper",
1238
+ postprocessor: "scrfd",
1239
+ extractMode: "crop-roi",
1240
+ inputClasses: ["person"],
1241
+ outputClasses: ["face"],
1242
+ models: [...FACE_DETECTION_MODELS],
1243
+ defaultModelId: "scrfd-2.5g",
1244
+ defaultConfidence: .5,
1245
+ defaultMinParentScore: .7,
1246
+ cadence: {
1247
+ trigger: "improve",
1248
+ minIntervalMs: 1e3
1249
+ }
1250
+ });
1251
+ var STEP_FACE_EMBEDDING = new PipelineStepBase({
1252
+ id: "face-embedding",
1253
+ name: "Face Embedding",
1254
+ slot: "classifier",
1255
+ postprocessor: "arcface",
1256
+ extractMode: "crop-roi",
1257
+ inputClasses: ["face"],
1258
+ outputClasses: ["identity"],
1259
+ models: [...FACE_EMBEDDING_MODELS],
1260
+ defaultModelId: "arcface-r100",
1261
+ defaultConfidence: 0,
1262
+ cadence: {
1263
+ trigger: "improve",
1264
+ minIntervalMs: 1e3,
1265
+ stickyOnConfidence: .6
1266
+ }
1267
+ });
1268
+ var STEP_CLIP_EMBEDDING = new PipelineStepBase({
1269
+ id: "clip-embedding",
1270
+ name: "CLIP Embedding",
1271
+ slot: "classifier",
1272
+ postprocessor: "clip",
1273
+ extractMode: "crop-roi",
1274
+ inputClasses: [
1275
+ "person",
1276
+ "vehicle",
1277
+ "animal"
1278
+ ],
1279
+ outputClasses: ["embedding"],
1280
+ models: [...CLIP_EMBEDDING_MODELS],
1281
+ defaultModelId: "mobileclip-s1",
1282
+ enabledByDefault: true,
1283
+ backfillIntoExistingOverrides: true,
1284
+ defaultConfidence: 0,
1285
+ defaultMinParentScore: .4,
1286
+ group: "CLIP",
1287
+ cadence: { trigger: "improve" }
1288
+ });
1289
+ var STEP_PLATE_DETECTION = new PipelineStepBase({
1290
+ id: "plate-detection",
1291
+ name: "Plate Detection",
1292
+ slot: "cropper",
1293
+ postprocessor: "yolo",
1294
+ extractMode: "crop-roi",
1295
+ inputClasses: ["vehicle"],
1296
+ outputClasses: ["plate"],
1297
+ models: [...PLATE_DETECTION_MODELS],
1298
+ defaultModelId: "yolov8n-plate",
1299
+ defaultConfidence: .5,
1300
+ defaultMinParentScore: .7,
1301
+ labels: ["plate"],
1302
+ cadence: {
1303
+ trigger: "once",
1304
+ maxPerTrack: 5
1305
+ }
1306
+ });
1307
+ var STEP_PLATE_OCR = new PipelineStepBase({
1308
+ id: "plate-ocr",
1309
+ name: "Plate OCR",
1310
+ slot: "classifier",
1311
+ postprocessor: "ctc",
1312
+ extractMode: "crop-roi",
1313
+ inputClasses: ["plate"],
1314
+ outputClasses: ["plate-text"],
1315
+ models: [...PLATE_OCR_MODELS],
1316
+ defaultModelId: "vgg-english-g2",
1317
+ defaultConfidence: 0,
1318
+ charset: [...VGG_G2_CHARSET],
1319
+ cadence: {
1320
+ trigger: "once",
1321
+ maxPerTrack: 5
1322
+ }
1323
+ });
1324
+ var STEP_BIRD_CLASSIFIER = new ClassifierWithMinConfidence({
1325
+ id: "bird-classifier",
1326
+ name: "Bird Classifier",
1327
+ slot: "classifier",
1328
+ postprocessor: "softmax",
1329
+ extractMode: "crop-roi",
1330
+ inputClasses: ["animal"],
1331
+ outputClasses: ["species"],
1332
+ models: [...BIRD_CLASSIFIER_MODELS],
1333
+ defaultModelId: "bird-nabirds-404",
1334
+ enabledByDefault: false,
1335
+ defaultConfidence: .2,
1336
+ cadence: {
1337
+ trigger: "once",
1338
+ maxPerTrack: 3,
1339
+ stickyOnConfidence: .7
1340
+ }
1341
+ });
1342
+ var STEP_VEHICLE_CLASSIFIER = new ClassifierWithMinConfidence({
1343
+ id: "vehicle-classifier",
1344
+ name: "Vehicle Classifier",
1345
+ slot: "classifier",
1346
+ postprocessor: "softmax",
1347
+ extractMode: "crop-roi",
1348
+ inputClasses: ["vehicle"],
1349
+ outputClasses: ["vehicle-type"],
1350
+ models: [...VEHICLE_CLASSIFIER_MODELS],
1351
+ defaultModelId: "vehicle-type-efficientnet",
1352
+ enabledByDefault: false,
1353
+ defaultConfidence: .3,
1354
+ cadence: {
1355
+ trigger: "once",
1356
+ maxPerTrack: 3,
1357
+ stickyOnConfidence: .7
1358
+ }
1359
+ });
1360
+ var STEP_SEGMENTATION = new PipelineStepBase({
1361
+ id: "segmentation",
1362
+ name: "Segmentation",
1363
+ slot: "refiner",
1364
+ postprocessor: "saliency",
1365
+ extractMode: "crop-roi",
1366
+ inputClasses: null,
1367
+ outputClasses: ["mask"],
1368
+ models: [...SEGMENTATION_REFINER_MODELS],
1369
+ defaultModelId: "u2netp",
1370
+ enabledByDefault: false,
1371
+ defaultConfidence: 0,
1372
+ group: "Segmentation"
1373
+ });
1374
+ new PipelineStepBase({
1375
+ id: "instance-segmentation",
1376
+ name: "Instance Segmentation",
1377
+ slot: "refiner",
1378
+ postprocessor: "yolo-seg",
1379
+ extractMode: "full-frame",
1380
+ inputClasses: null,
1381
+ outputClasses: ["mask"],
1382
+ models: [...INSTANCE_SEGMENTATION_MODELS],
1383
+ defaultModelId: "yolo26n-seg",
1384
+ enabledByDefault: false,
1385
+ defaultConfidence: .25,
1386
+ labels: COCO_80_LABELS.map((l) => l.id),
1387
+ classMap: COCO_TO_MACRO,
1388
+ group: "Segmentation"
1389
+ });
1390
+ var STEP_OBJECT_DETECTION_INSTANCE = new ObjectDetectionStep();
1391
+ var STEP_AUDIO_CLASSIFIER_INSTANCE = new AudioClassifierStep();
1392
+ var ALL_PIPELINE_STEPS = [
1393
+ STEP_OBJECT_DETECTION_INSTANCE,
1394
+ STEP_FACE_DETECTION,
1395
+ STEP_FACE_EMBEDDING,
1396
+ STEP_CLIP_EMBEDDING,
1397
+ STEP_PLATE_DETECTION,
1398
+ STEP_PLATE_OCR,
1399
+ new AnimalClassifierStep(),
1400
+ STEP_BIRD_CLASSIFIER,
1401
+ STEP_VEHICLE_CLASSIFIER,
1402
+ STEP_SEGMENTATION,
1403
+ STEP_AUDIO_CLASSIFIER_INSTANCE
1404
+ ];
1405
+ /** Compat: flat array of StepDefinition for existing consumers */
1406
+ var ALL_STEPS = ALL_PIPELINE_STEPS.map((s) => s.definition);
1407
+ var STEP_MAP = new Map(ALL_PIPELINE_STEPS.map((s) => [s.definition.id, s]));
1408
+ /**
1409
+ * Look up a pipeline step by ID (class instance with getConfigSchema).
1410
+ * @throws if the step ID is not registered.
1411
+ */
1412
+ function getStep(stepId) {
1413
+ const step = STEP_MAP.get(stepId);
1414
+ if (!step) throw new Error(`Unknown pipeline step: "${stepId}". Available: ${ALL_PIPELINE_STEPS.map((s) => s.definition.id).join(", ")}`);
1415
+ return step;
1416
+ }
1417
+ /**
1418
+ * Look up a step definition by ID (compat shortcut).
1419
+ * @throws if the step ID is not registered.
1420
+ */
1421
+ function getStepDefinition(stepId) {
1422
+ return getStep(stepId).definition;
1423
+ }
1424
+ /**
1425
+ * Get the default model ID for a step given the current model format.
1426
+ *
1427
+ * Resolution order:
1428
+ * 1. `def.defaultModelIdByFormat?.[format]` — the step's declared
1429
+ * per-format preference — if that model exists in `def.models` AND
1430
+ * has a build for `format`.
1431
+ * 2. `def.defaultModelId` — the step's plain declared default — if it
1432
+ * exists in `def.models` AND has a build for `format`.
1433
+ * 3. The smallest-by-size model among those with a `format` build
1434
+ * (legacy fallback, preserved for steps/formats with no declared
1435
+ * preference reachable).
1436
+ * 4. `def.defaultModelId` unchanged, when ZERO models have a `format`
1437
+ * build — an unloadable case flagged elsewhere, not resolved here.
1438
+ */
1439
+ function getDefaultModelForFormat(stepId, format) {
1440
+ const def = getStepDefinition(stepId);
1441
+ const hasFormatBuild = (modelId) => def.models.find((m) => m.id === modelId)?.formats[format] !== void 0;
1442
+ const declaredForFormat = def.defaultModelIdByFormat?.[format];
1443
+ if (declaredForFormat !== void 0 && hasFormatBuild(declaredForFormat)) return declaredForFormat;
1444
+ if (hasFormatBuild(def.defaultModelId)) return def.defaultModelId;
1445
+ const available = def.models.filter((m) => m.formats[format] && m.legacy !== true);
1446
+ if (available.length === 0) return def.defaultModelId;
1447
+ return [...available].toSorted((a, b) => {
1448
+ return (a.formats[format]?.sizeMB ?? Infinity) - (b.formats[format]?.sizeMB ?? Infinity);
1449
+ })[0].id;
1450
+ }
1451
+ /**
1452
+ * The single node-local authority for turning a CHOSEN model (or none) into a
1453
+ * concrete model that has a build for this node's engine `format`. Fuses the
1454
+ * two previously-duplicated decisions (orchestrator `pickDefaultModelId` +
1455
+ * provider `substituteIncompatibleModels`):
1456
+ *
1457
+ * - chosen === null → the addon's default model for `format`.
1458
+ * - chosen is a catalog model → keep it if it has a `format` build; else
1459
+ * the addon's default model for `format`
1460
+ * (a substitution — the caller surfaces it).
1461
+ * - chosen is NOT in the catalog (custom/unknown) → returned unchanged; the
1462
+ * operator owns a custom model's format compat.
1463
+ * - unknown stepId → chosen returned unchanged (never throws).
1464
+ */
1465
+ function resolveModelForFormat(stepId, chosenModelId, format) {
1466
+ let def;
1467
+ try {
1468
+ def = getStepDefinition(stepId);
1469
+ } catch {
1470
+ return chosenModelId ?? "";
1471
+ }
1472
+ if (chosenModelId === null) return getDefaultModelForFormat(stepId, format);
1473
+ const entry = def.models.find((m) => m.id === chosenModelId);
1474
+ if (!entry) return chosenModelId;
1475
+ if (entry.formats[format]) return chosenModelId;
1476
+ return getDefaultModelForFormat(stepId, format);
1477
+ }
1478
+ //#endregion
1479
+ export { getStepDefinition as a, getStep as i, ALL_STEPS as n, resolveModelForFormat as o, getDefaultModelForFormat as r, ALL_PIPELINE_STEPS as t };