@camstack/addon-pipeline 1.2.217 → 1.2.218

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 (121) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/{default-detection-model-BwNEV8Wl.mjs → default-detection-model-AJyhoTLF.mjs} +1 -1
  4. package/dist/{default-detection-model-DzzuINe-.js → default-detection-model-Bf45EQ98.js} +1 -1
  5. package/dist/detection-pipeline/index.js +5 -5
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-D7hxiBnC.js → dist-BbvtiBNc.js} +41 -4
  8. package/dist/{dist-DgeXZfwn.mjs → dist-Dl6GntEh.mjs} +41 -4
  9. package/dist/{lazy-sharp-BSkbiuz5.js → lazy-sharp-L9Lcr62v.js} +1 -1
  10. package/dist/motion-wasm/index.js +2 -2
  11. package/dist/motion-wasm/index.mjs +1 -1
  12. package/dist/{node-C9GcBrwk.mjs → node-CEyw52D2.mjs} +1 -1
  13. package/dist/{node-DDhmPcOx.js → node-CbCVHEvJ.js} +1 -1
  14. package/dist/pipeline-runner/index.js +13 -6
  15. package/dist/pipeline-runner/index.mjs +12 -5
  16. package/dist/{process-memory-ENqmiiis.js → process-memory-DBxdiCSF.js} +1 -1
  17. package/dist/{process-memory-Dw3CGS3D.mjs → process-memory-Du00R6-e.mjs} +1 -1
  18. package/dist/recorder/index.js +92 -14
  19. package/dist/recorder/index.mjs +92 -14
  20. package/dist/{segment-demux-js-BGbKlotF.mjs → segment-demux-js-B278aBtB.mjs} +1 -1
  21. package/dist/{segment-demux-js-sLs8mbZQ.js → segment-demux-js-D7bjzY8M.js} +1 -1
  22. package/dist/session-decode/decode-worker-child.js +2 -2
  23. package/dist/session-decode/decode-worker-child.mjs +1 -1
  24. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BULotDCb.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BnmbfnAd.mjs} +3 -3
  25. package/dist/stream-broker/demux-worker-child.js +1 -1
  26. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  27. package/dist/stream-broker/{hostInit-_RQxF72h.mjs → hostInit-MIKQqs86.mjs} +3 -3
  28. package/dist/stream-broker/index.js +3 -3
  29. package/dist/stream-broker/index.mjs +3 -3
  30. package/dist/stream-broker/remoteEntry.js +1 -1
  31. package/dist/{worker-protocol-SzmaLNnP.mjs → worker-protocol-BEbD5adq.mjs} +1 -1
  32. package/dist/{worker-protocol-DGql9R4g.js → worker-protocol-C4rh5uiS.js} +1 -1
  33. package/package.json +1 -1
  34. package/python/__pycache__/inference_pool.cpython-312.pyc +0 -0
  35. package/python/__pycache__/inference_pool.cpython-313.pyc +0 -0
  36. package/python/__pycache__/inference_pool.cpython-314.pyc +0 -0
  37. package/python/__pycache__/test_inference_pool_backpressure.cpython-312-pytest-9.1.1.pyc +0 -0
  38. package/python/__pycache__/test_inference_pool_backpressure.cpython-312.pyc +0 -0
  39. package/python/__pycache__/test_inference_pool_backpressure.cpython-314.pyc +0 -0
  40. package/python/__pycache__/test_inference_pool_coreml_cache.cpython-312-pytest-9.1.1.pyc +0 -0
  41. package/python/__pycache__/test_inference_pool_coreml_cache.cpython-312.pyc +0 -0
  42. package/python/__pycache__/test_inference_pool_coreml_cache.cpython-314.pyc +0 -0
  43. package/python/__pycache__/test_inference_pool_deadline.cpython-314.pyc +0 -0
  44. package/python/__pycache__/test_inference_pool_device_selection.cpython-312-pytest-9.1.1.pyc +0 -0
  45. package/python/__pycache__/test_inference_pool_device_selection.cpython-312.pyc +0 -0
  46. package/python/__pycache__/test_inference_pool_device_selection.cpython-314.pyc +0 -0
  47. package/python/__pycache__/test_inference_pool_layout.cpython-312-pytest-9.1.1.pyc +0 -0
  48. package/python/__pycache__/test_inference_pool_layout.cpython-314.pyc +0 -0
  49. package/python/__pycache__/test_inference_pool_memstats.cpython-312-pytest-9.1.1.pyc +0 -0
  50. package/python/__pycache__/test_inference_pool_memstats.cpython-312.pyc +0 -0
  51. package/python/__pycache__/test_inference_pool_memstats.cpython-314.pyc +0 -0
  52. package/python/__pycache__/test_inference_pool_ov_ppp.cpython-312-pytest-9.1.1.pyc +0 -0
  53. package/python/__pycache__/test_inference_pool_ov_ppp.cpython-312.pyc +0 -0
  54. package/python/__pycache__/test_inference_pool_ov_ppp.cpython-314.pyc +0 -0
  55. package/python/__pycache__/test_inference_pool_preprocess.cpython-312-pytest-9.1.1.pyc +0 -0
  56. package/python/__pycache__/test_inference_pool_preprocess.cpython-314.pyc +0 -0
  57. package/python/__pycache__/test_inference_pool_reconfigure.cpython-314.pyc +0 -0
  58. package/python/__pycache__/test_inference_pool_static_batch.cpython-312-pytest-9.1.1.pyc +0 -0
  59. package/python/__pycache__/test_inference_pool_static_batch.cpython-312.pyc +0 -0
  60. package/python/__pycache__/test_inference_pool_static_batch.cpython-314.pyc +0 -0
  61. package/python/__pycache__/yamnet_audio.cpython-314.pyc +0 -0
  62. package/python/postprocessors/__pycache__/__init__.cpython-312.pyc +0 -0
  63. package/python/postprocessors/__pycache__/__init__.cpython-313.pyc +0 -0
  64. package/python/postprocessors/__pycache__/__init__.cpython-314.pyc +0 -0
  65. package/python/postprocessors/__pycache__/_safety.cpython-313.pyc +0 -0
  66. package/python/postprocessors/__pycache__/arcface.cpython-312.pyc +0 -0
  67. package/python/postprocessors/__pycache__/arcface.cpython-313.pyc +0 -0
  68. package/python/postprocessors/__pycache__/arcface.cpython-314.pyc +0 -0
  69. package/python/postprocessors/__pycache__/clip.cpython-312.pyc +0 -0
  70. package/python/postprocessors/__pycache__/clip.cpython-313.pyc +0 -0
  71. package/python/postprocessors/__pycache__/clip.cpython-314.pyc +0 -0
  72. package/python/postprocessors/__pycache__/ctc.cpython-312.pyc +0 -0
  73. package/python/postprocessors/__pycache__/ctc.cpython-313.pyc +0 -0
  74. package/python/postprocessors/__pycache__/ctc.cpython-314.pyc +0 -0
  75. package/python/postprocessors/__pycache__/plate_slots.cpython-312.pyc +0 -0
  76. package/python/postprocessors/__pycache__/plate_slots.cpython-314.pyc +0 -0
  77. package/python/postprocessors/__pycache__/rfdetr.cpython-312.pyc +0 -0
  78. package/python/postprocessors/__pycache__/rfdetr.cpython-314.pyc +0 -0
  79. package/python/postprocessors/__pycache__/saliency.cpython-312.pyc +0 -0
  80. package/python/postprocessors/__pycache__/saliency.cpython-313.pyc +0 -0
  81. package/python/postprocessors/__pycache__/saliency.cpython-314.pyc +0 -0
  82. package/python/postprocessors/__pycache__/scrfd.cpython-312.pyc +0 -0
  83. package/python/postprocessors/__pycache__/scrfd.cpython-313.pyc +0 -0
  84. package/python/postprocessors/__pycache__/scrfd.cpython-314.pyc +0 -0
  85. package/python/postprocessors/__pycache__/softmax.cpython-312.pyc +0 -0
  86. package/python/postprocessors/__pycache__/softmax.cpython-313.pyc +0 -0
  87. package/python/postprocessors/__pycache__/softmax.cpython-314.pyc +0 -0
  88. package/python/postprocessors/__pycache__/ssd.cpython-312.pyc +0 -0
  89. package/python/postprocessors/__pycache__/ssd.cpython-313.pyc +0 -0
  90. package/python/postprocessors/__pycache__/ssd.cpython-314.pyc +0 -0
  91. package/python/postprocessors/__pycache__/test_clip.cpython-312-pytest-9.1.1.pyc +0 -0
  92. package/python/postprocessors/__pycache__/test_clip.cpython-313-pytest-9.1.1.pyc +0 -0
  93. package/python/postprocessors/__pycache__/test_ctc.cpython-312-pytest-9.1.1.pyc +0 -0
  94. package/python/postprocessors/__pycache__/test_ctc.cpython-312.pyc +0 -0
  95. package/python/postprocessors/__pycache__/test_ctc.cpython-313-pytest-9.1.1.pyc +0 -0
  96. package/python/postprocessors/__pycache__/test_ctc.cpython-313.pyc +0 -0
  97. package/python/postprocessors/__pycache__/test_ctc.cpython-314.pyc +0 -0
  98. package/python/postprocessors/__pycache__/test_plate_slots.cpython-312-pytest-9.1.1.pyc +0 -0
  99. package/python/postprocessors/__pycache__/test_rfdetr.cpython-312-pytest-9.1.1.pyc +0 -0
  100. package/python/postprocessors/__pycache__/test_rfdetr.cpython-314.pyc +0 -0
  101. package/python/postprocessors/__pycache__/test_saliency.cpython-312-pytest-9.1.1.pyc +0 -0
  102. package/python/postprocessors/__pycache__/test_saliency.cpython-313-pytest-9.1.1.pyc +0 -0
  103. package/python/postprocessors/__pycache__/test_saliency.cpython-314.pyc +0 -0
  104. package/python/postprocessors/__pycache__/test_softmax.cpython-312-pytest-9.1.1.pyc +0 -0
  105. package/python/postprocessors/__pycache__/test_softmax.cpython-314.pyc +0 -0
  106. package/python/postprocessors/__pycache__/test_yolo_nms.cpython-312-pytest-9.1.1.pyc +0 -0
  107. package/python/postprocessors/__pycache__/test_yolo_nms.cpython-314.pyc +0 -0
  108. package/python/postprocessors/__pycache__/test_yolo_nms.cpython-39.pyc +0 -0
  109. package/python/postprocessors/__pycache__/test_yolonas.cpython-312-pytest-9.1.1.pyc +0 -0
  110. package/python/postprocessors/__pycache__/yamnet.cpython-312.pyc +0 -0
  111. package/python/postprocessors/__pycache__/yamnet.cpython-313.pyc +0 -0
  112. package/python/postprocessors/__pycache__/yamnet.cpython-314.pyc +0 -0
  113. package/python/postprocessors/__pycache__/yolo.cpython-312.pyc +0 -0
  114. package/python/postprocessors/__pycache__/yolo.cpython-313.pyc +0 -0
  115. package/python/postprocessors/__pycache__/yolo.cpython-314.pyc +0 -0
  116. package/python/postprocessors/__pycache__/yolo.cpython-39.pyc +0 -0
  117. package/python/postprocessors/__pycache__/yolo_seg.cpython-312.pyc +0 -0
  118. package/python/postprocessors/__pycache__/yolo_seg.cpython-313.pyc +0 -0
  119. package/python/postprocessors/__pycache__/yolo_seg.cpython-314.pyc +0 -0
  120. package/python/postprocessors/__pycache__/yolonas.cpython-312.pyc +0 -0
  121. package/python/postprocessors/__pycache__/yolonas.cpython-314.pyc +0 -0
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-D7hxiBnC.js");
6
- const require_process_memory = require("../process-memory-ENqmiiis.js");
5
+ const require_dist = require("../dist-BbvtiBNc.js");
6
+ const require_process_memory = require("../process-memory-DBxdiCSF.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_dist.__toESM(node_fs);
9
9
  let node_path = require("node:path");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { Dt as resolvePoolMemoryPolicy, It as errMsg, Jt as hydrateSchema, M as audioAnalyzerCapability, S as PoolMemoryWatchdog, Ut as BaseAddon, j as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL } from "../dist-DgeXZfwn.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Dw3CGS3D.mjs";
2
+ import { Dt as resolvePoolMemoryPolicy, It as errMsg, Jt as hydrateSchema, M as audioAnalyzerCapability, S as PoolMemoryWatchdog, Ut as BaseAddon, j as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL } from "../dist-Dl6GntEh.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Du00R6-e.mjs";
4
4
  import * as fs from "node:fs";
5
5
  import * as path$1 from "node:path";
6
6
  import { downloadFile } from "@camstack/system/addon-utils";
@@ -1,4 +1,4 @@
1
- import { N as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-DgeXZfwn.mjs";
1
+ import { N as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-Dl6GntEh.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-D7hxiBnC.js");
1
+ const require_dist = require("./dist-BbvtiBNc.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -2,11 +2,11 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-D7hxiBnC.js");
6
- const require_node = require("../node-DDhmPcOx.js");
7
- const require_default_detection_model = require("../default-detection-model-DzzuINe-.js");
8
- const require_lazy_sharp = require("../lazy-sharp-BSkbiuz5.js");
9
- const require_process_memory = require("../process-memory-ENqmiiis.js");
5
+ const require_dist = require("../dist-BbvtiBNc.js");
6
+ const require_node = require("../node-CbCVHEvJ.js");
7
+ const require_default_detection_model = require("../default-detection-model-Bf45EQ98.js");
8
+ const require_lazy_sharp = require("../lazy-sharp-L9Lcr62v.js");
9
+ const require_process_memory = require("../process-memory-DBxdiCSF.js");
10
10
  let node_os = require("node:os");
11
11
  node_os = require_dist.__toESM(node_os);
12
12
  let node_fs = require("node:fs");
@@ -1,9 +1,9 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $t as parseJsonUnknown, B as defaultDeviceFor$1, Dt as resolvePoolMemoryPolicy, G as detectionPipelineCapability, It as errMsg, J as enumerateInferenceDevices, Jt as hydrateSchema, Pt as supportedRuntimes$1, Qt as nodePin, S as PoolMemoryWatchdog, Ut as BaseAddon, X as evaluateZoneRules, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as EventCategory, ht as pickClusterStepModels, in as array, it as loadContributionCapability, k as YAMNET_TO_MACRO, kt as runtimeDevices$1, l as DEFAULT_CLUSTER_STEP_SETTINGS, m as DEVICE_BACKEND_TO_FORMAT, mn as union, nn as sleep, nt as inferModelProvider, pn as string, pt as overlayClusterStepSettings, qt as createEvent, t as APPLE_SA_TO_MACRO, un as object, wt as resolveClusterStepModelId, yt as pipelineExecutorCapability } from "../dist-DgeXZfwn.mjs";
3
- import { o as readProcessCost } from "../node-C9GcBrwk.mjs";
4
- import { a as ALL_PIPELINE_STEPS, c as getStep, d as landmarkPrecisionVerdict, l as getStepDefinition, n as resolveDefaultDetectionModel, o as ALL_STEPS, r as localFrameRegistry, s as getDefaultModelForFormat, u as resolveModelForFormat } from "../default-detection-model-BwNEV8Wl.mjs";
2
+ import { $t as parseJsonUnknown, B as defaultDeviceFor$1, Dt as resolvePoolMemoryPolicy, G as detectionPipelineCapability, It as errMsg, J as enumerateInferenceDevices, Jt as hydrateSchema, Pt as supportedRuntimes$1, Qt as nodePin, S as PoolMemoryWatchdog, Ut as BaseAddon, X as evaluateZoneRules, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as EventCategory, ht as pickClusterStepModels, in as array, it as loadContributionCapability, k as YAMNET_TO_MACRO, kt as runtimeDevices$1, l as DEFAULT_CLUSTER_STEP_SETTINGS, m as DEVICE_BACKEND_TO_FORMAT, mn as union, nn as sleep, nt as inferModelProvider, pn as string, pt as overlayClusterStepSettings, qt as createEvent, t as APPLE_SA_TO_MACRO, un as object, wt as resolveClusterStepModelId, yt as pipelineExecutorCapability } from "../dist-Dl6GntEh.mjs";
3
+ import { o as readProcessCost } from "../node-CEyw52D2.mjs";
4
+ import { a as ALL_PIPELINE_STEPS, c as getStep, d as landmarkPrecisionVerdict, l as getStepDefinition, n as resolveDefaultDetectionModel, o as ALL_STEPS, r as localFrameRegistry, s as getDefaultModelForFormat, u as resolveModelForFormat } from "../default-detection-model-AJyhoTLF.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Dw3CGS3D.mjs";
6
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Du00R6-e.mjs";
7
7
  import * as os from "node:os";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
@@ -22284,7 +22284,17 @@ var EventDensityBucketSchema = object({
22284
22284
  bucketStart: number(),
22285
22285
  motion: number().int(),
22286
22286
  object: number().int(),
22287
- audio: number().int()
22287
+ audio: number().int(),
22288
+ /**
22289
+ * Energy-weighted mean dBFS of the audio events in this bucket — the LEVEL,
22290
+ * as opposed to `audio`, which is their COUNT (D431).
22291
+ *
22292
+ * ABSENT when the bucket holds no audio event. Absence means "nothing was
22293
+ * measured", which is not the same claim as silence, and a lane that cannot
22294
+ * tell them apart paints a quiet hour at full scale — which is exactly what
22295
+ * the count-on-a-level-meter did.
22296
+ */
22297
+ audioDbfs: number().optional()
22288
22298
  });
22289
22299
  /**
22290
22300
  * One camera's row in a `getEventDensityBatch` answer.
@@ -30816,7 +30826,23 @@ var RecordingRangeSchema = object({
30816
30826
  });
30817
30827
  var RecordingAvailabilitySchema = object({
30818
30828
  deviceId: number(),
30819
- ranges: array(RecordingRangeSchema)
30829
+ ranges: array(RecordingRangeSchema),
30830
+ /**
30831
+ * Every profile this camera has footage in — not only the one `ranges`
30832
+ * describes (D433).
30833
+ *
30834
+ * `ranges` answers for ONE profile by design: the timeline is a single bar,
30835
+ * and enumerating all of them triples the directory reads for a bar that
30836
+ * would look identical. But the answer used to say nothing about that, so a
30837
+ * caller asking "what can I export?" read the single preferred profile as
30838
+ * the only one that exists — on this deployment every camera records `high`
30839
+ * AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
30840
+ * UI could not see it.
30841
+ *
30842
+ * Cheap: it is the same shallow directory read the profile CHOICE already
30843
+ * makes. Ask for a specific profile's ranges with the `profile` input.
30844
+ */
30845
+ profilesWithFootage: array(string())
30820
30846
  });
30821
30847
  var RecordingDaysSchema = object({
30822
30848
  deviceId: number(),
@@ -30842,7 +30868,11 @@ var RecordingDaysSchema = object({
30842
30868
  var RecordingAvailabilityForDeviceSchema = object({
30843
30869
  deviceId: number(),
30844
30870
  read: _enum(["read", "unreadable"]),
30845
- ranges: array(RecordingRangeSchema).readonly()
30871
+ ranges: array(RecordingRangeSchema).readonly(),
30872
+ /** Same field, same meaning, as the singular answer (D433). A row that
30873
+ * dropped it would tell a grid caller the archive holds one profile.
30874
+ * Empty on an `'unreadable'` row: nobody looked. */
30875
+ profilesWithFootage: array(string()).readonly()
30846
30876
  });
30847
30877
  /**
30848
30878
  * One camera's row in a `getDaysWithRecordingsBatch` answer. Same rule as
@@ -31142,7 +31172,14 @@ var recordingCapability = {
31142
31172
  getAvailability: method(object({
31143
31173
  deviceId: number(),
31144
31174
  fromMs: number(),
31145
- toMs: number()
31175
+ toMs: number(),
31176
+ /**
31177
+ * Answer for THIS profile instead of the preferred one (D433). Absent
31178
+ * keeps the timeline's behaviour — one bar, one profile, one set of
31179
+ * reads. `profilesWithFootage` on the answer says what may be asked
31180
+ * for.
31181
+ */
31182
+ profile: string().optional()
31146
31183
  }), RecordingAvailabilitySchema, {
31147
31184
  kind: "query",
31148
31185
  auth: "protected"
@@ -22261,7 +22261,17 @@ var EventDensityBucketSchema = object({
22261
22261
  bucketStart: number(),
22262
22262
  motion: number().int(),
22263
22263
  object: number().int(),
22264
- audio: number().int()
22264
+ audio: number().int(),
22265
+ /**
22266
+ * Energy-weighted mean dBFS of the audio events in this bucket — the LEVEL,
22267
+ * as opposed to `audio`, which is their COUNT (D431).
22268
+ *
22269
+ * ABSENT when the bucket holds no audio event. Absence means "nothing was
22270
+ * measured", which is not the same claim as silence, and a lane that cannot
22271
+ * tell them apart paints a quiet hour at full scale — which is exactly what
22272
+ * the count-on-a-level-meter did.
22273
+ */
22274
+ audioDbfs: number().optional()
22265
22275
  });
22266
22276
  /**
22267
22277
  * One camera's row in a `getEventDensityBatch` answer.
@@ -30793,7 +30803,23 @@ var RecordingRangeSchema = object({
30793
30803
  });
30794
30804
  var RecordingAvailabilitySchema = object({
30795
30805
  deviceId: number(),
30796
- ranges: array(RecordingRangeSchema)
30806
+ ranges: array(RecordingRangeSchema),
30807
+ /**
30808
+ * Every profile this camera has footage in — not only the one `ranges`
30809
+ * describes (D433).
30810
+ *
30811
+ * `ranges` answers for ONE profile by design: the timeline is a single bar,
30812
+ * and enumerating all of them triples the directory reads for a bar that
30813
+ * would look identical. But the answer used to say nothing about that, so a
30814
+ * caller asking "what can I export?" read the single preferred profile as
30815
+ * the only one that exists — on this deployment every camera records `high`
30816
+ * AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
30817
+ * UI could not see it.
30818
+ *
30819
+ * Cheap: it is the same shallow directory read the profile CHOICE already
30820
+ * makes. Ask for a specific profile's ranges with the `profile` input.
30821
+ */
30822
+ profilesWithFootage: array(string())
30797
30823
  });
30798
30824
  var RecordingDaysSchema = object({
30799
30825
  deviceId: number(),
@@ -30819,7 +30845,11 @@ var RecordingDaysSchema = object({
30819
30845
  var RecordingAvailabilityForDeviceSchema = object({
30820
30846
  deviceId: number(),
30821
30847
  read: _enum(["read", "unreadable"]),
30822
- ranges: array(RecordingRangeSchema).readonly()
30848
+ ranges: array(RecordingRangeSchema).readonly(),
30849
+ /** Same field, same meaning, as the singular answer (D433). A row that
30850
+ * dropped it would tell a grid caller the archive holds one profile.
30851
+ * Empty on an `'unreadable'` row: nobody looked. */
30852
+ profilesWithFootage: array(string()).readonly()
30823
30853
  });
30824
30854
  /**
30825
30855
  * One camera's row in a `getDaysWithRecordingsBatch` answer. Same rule as
@@ -31119,7 +31149,14 @@ var recordingCapability = {
31119
31149
  getAvailability: method(object({
31120
31150
  deviceId: number(),
31121
31151
  fromMs: number(),
31122
- toMs: number()
31152
+ toMs: number(),
31153
+ /**
31154
+ * Answer for THIS profile instead of the preferred one (D433). Absent
31155
+ * keeps the timeline's behaviour — one bar, one profile, one set of
31156
+ * reads. `profilesWithFootage` on the answer says what may be asked
31157
+ * for.
31158
+ */
31159
+ profile: string().optional()
31123
31160
  }), RecordingAvailabilitySchema, {
31124
31161
  kind: "query",
31125
31162
  auth: "protected"
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-D7hxiBnC.js");
1
+ const require_dist = require("./dist-BbvtiBNc.js");
2
2
  let node_path = require("node:path");
3
3
  node_path = require_dist.__toESM(node_path);
4
4
  let node_url = require("node:url");
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-D7hxiBnC.js");
6
- const require_lazy_sharp = require("../lazy-sharp-BSkbiuz5.js");
5
+ const require_dist = require("../dist-BbvtiBNc.js");
6
+ const require_lazy_sharp = require("../lazy-sharp-L9Lcr62v.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
9
9
  //#region src/motion-wasm/region-grouping.ts
@@ -1,4 +1,4 @@
1
- import { Jt as hydrateSchema, Kt as DeviceType, Ut as BaseAddon, X as evaluateZoneRules, ft as motionDetectionCapability } from "../dist-DgeXZfwn.mjs";
1
+ import { Jt as hydrateSchema, Kt as DeviceType, Ut as BaseAddon, X as evaluateZoneRules, ft as motionDetectionCapability } from "../dist-Dl6GntEh.mjs";
2
2
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -1,4 +1,4 @@
1
- import { It as errMsg, Rt as Fmp4BoxSplitter, Vt as isSoftwareDecode, zt as buildFfmpegArgs } from "./dist-DgeXZfwn.mjs";
1
+ import { It as errMsg, Rt as Fmp4BoxSplitter, Vt as isSoftwareDecode, zt as buildFfmpegArgs } from "./dist-Dl6GntEh.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { realpathSync } from "node:fs";
4
4
  import path from "node:path";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-D7hxiBnC.js");
1
+ const require_dist = require("./dist-BbvtiBNc.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  let node_fs = require("node:fs");
4
4
  node_fs = require_dist.__toESM(node_fs, 1);
@@ -2,12 +2,12 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-D7hxiBnC.js");
6
- const require_node = require("../node-DDhmPcOx.js");
7
- const require_default_detection_model = require("../default-detection-model-DzzuINe-.js");
8
- const require_worker_protocol = require("../worker-protocol-DGql9R4g.js");
5
+ const require_dist = require("../dist-BbvtiBNc.js");
6
+ const require_node = require("../node-CbCVHEvJ.js");
7
+ const require_default_detection_model = require("../default-detection-model-Bf45EQ98.js");
8
+ const require_worker_protocol = require("../worker-protocol-C4rh5uiS.js");
9
9
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
10
- const require_lazy_sharp = require("../lazy-sharp-BSkbiuz5.js");
10
+ const require_lazy_sharp = require("../lazy-sharp-L9Lcr62v.js");
11
11
  const require_restream_intent = require("../restream-intent-B1Difcnq.js");
12
12
  const require_remote_restream = require("../remote-restream-CO36Sr30.js");
13
13
  let node_os = require("node:os");
@@ -9868,7 +9868,13 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
9868
9868
  recipe,
9869
9869
  ms: Date.now() - started,
9870
9870
  now,
9871
- classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`)
9871
+ classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`),
9872
+ boxes: fused.slice(result.detections.length).map((d) => ({
9873
+ x: Math.round(d.bbox.x),
9874
+ y: Math.round(d.bbox.y),
9875
+ w: Math.round(d.bbox.width),
9876
+ h: Math.round(d.bbox.height)
9877
+ }))
9872
9878
  });
9873
9879
  return added > 0 ? {
9874
9880
  ...result,
@@ -9958,6 +9964,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
9958
9964
  crops: sample.crops,
9959
9965
  recovered: sample.recovered,
9960
9966
  classes: sample.classes,
9967
+ boxes: sample.boxes,
9961
9968
  ms: sample.ms
9962
9969
  }
9963
9970
  });
@@ -1,7 +1,7 @@
1
- import { $ as failureContributionCapability, It as errMsg, Qt as nodePin, R as customAction, U as deriveDetailCropRect, Ut as BaseAddon, V as defineCustomActions, _ as FailureCounters, _t as pickDetailCropConvention, an as boolean, bt as pipelineRunnerCapability, cn as literal, hn as EventCategory, in as array, it as loadContributionCapability, ln as number, m as DEVICE_BACKEND_TO_FORMAT, p as DEFAULT_NATIVE_LEASE_SETTINGS, pn as string, qt as createEvent, rn as _enum, sn as lazy, u as DEFAULT_DETAIL_CROP_CONVENTION, un as object, vt as pickNativeLeaseOverride } from "../dist-DgeXZfwn.mjs";
2
- import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-C9GcBrwk.mjs";
3
- import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-BwNEV8Wl.mjs";
4
- import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-SzmaLNnP.mjs";
1
+ import { $ as failureContributionCapability, It as errMsg, Qt as nodePin, R as customAction, U as deriveDetailCropRect, Ut as BaseAddon, V as defineCustomActions, _ as FailureCounters, _t as pickDetailCropConvention, an as boolean, bt as pipelineRunnerCapability, cn as literal, hn as EventCategory, in as array, it as loadContributionCapability, ln as number, m as DEVICE_BACKEND_TO_FORMAT, p as DEFAULT_NATIVE_LEASE_SETTINGS, pn as string, qt as createEvent, rn as _enum, sn as lazy, u as DEFAULT_DETAIL_CROP_CONVENTION, un as object, vt as pickNativeLeaseOverride } from "../dist-Dl6GntEh.mjs";
2
+ import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-CEyw52D2.mjs";
3
+ import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-AJyhoTLF.mjs";
4
+ import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-BEbD5adq.mjs";
5
5
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
6
6
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
7
7
  import { a as preRollRequestOf, o as withDetectionIntent, t as DETECTION_PRE_ROLL_REQUEST_MS } from "../restream-intent-DWe2kInY.mjs";
@@ -9861,7 +9861,13 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
9861
9861
  recipe,
9862
9862
  ms: Date.now() - started,
9863
9863
  now,
9864
- classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`)
9864
+ classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`),
9865
+ boxes: fused.slice(result.detections.length).map((d) => ({
9866
+ x: Math.round(d.bbox.x),
9867
+ y: Math.round(d.bbox.y),
9868
+ w: Math.round(d.bbox.width),
9869
+ h: Math.round(d.bbox.height)
9870
+ }))
9865
9871
  });
9866
9872
  return added > 0 ? {
9867
9873
  ...result,
@@ -9951,6 +9957,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
9951
9957
  crops: sample.crops,
9952
9958
  recovered: sample.recovered,
9953
9959
  classes: sample.classes,
9960
+ boxes: sample.boxes,
9954
9961
  ms: sample.ms
9955
9962
  }
9956
9963
  });
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-D7hxiBnC.js");
1
+ const require_dist = require("./dist-BbvtiBNc.js");
2
2
  let node_fs = require("node:fs");
3
3
  node_fs = require_dist.__toESM(node_fs);
4
4
  let node_child_process = require("node:child_process");
@@ -1,4 +1,4 @@
1
- import { mt as parseProcStatus } from "./dist-DgeXZfwn.mjs";
1
+ import { mt as parseProcStatus } from "./dist-Dl6GntEh.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import { execFile } from "node:child_process";
4
4
  //#region src/shared/node-topology-platform.ts
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-D7hxiBnC.js");
6
- const require_node = require("../node-DDhmPcOx.js");
5
+ const require_dist = require("../dist-BbvtiBNc.js");
6
+ const require_node = require("../node-CbCVHEvJ.js");
7
7
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
8
8
  const require_restream_intent = require("../restream-intent-B1Difcnq.js");
9
9
  const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
@@ -3817,6 +3817,40 @@ async function segmentsOfHour(root, deviceId, profile, hourStartMs) {
3817
3817
  * the directory route serve the profile the client asked for when it exists,
3818
3818
  * and fall back to the availability pick when it does not.
3819
3819
  */
3820
+ /**
3821
+ * EVERY profile this camera holds footage in, across every root.
3822
+ *
3823
+ * {@link availabilityProfile} deliberately returns ONE — the timeline is a
3824
+ * single bar. That is right for the bar and wrong for the ANSWER: on
3825
+ * 2026-09-10 `getAvailability` reported twenty `high` ranges for camera 615
3826
+ * and the conclusion drawn was that this deployment records no `low` at all,
3827
+ * while `/media-fast/recordingsLow/615/low/` held 14 GB on a different
3828
+ * location (D433).
3829
+ *
3830
+ * Unions across roots for exactly that reason: `high` and `low` do not share a
3831
+ * location here, so a per-root answer sees one of them.
3832
+ *
3833
+ * Non-emptiness, not existence — the same rule {@link availabilityProfile}
3834
+ * keeps, so a directory left behind by a config change is not offered. And
3835
+ * only {@link KNOWN_PROFILES}: the camera dir also hosts `events/` and the
3836
+ * retired `strips/` trees, which a walker that trusts readdir would present as
3837
+ * playable.
3838
+ *
3839
+ * `list` is injectable for the test; production passes the module's own
3840
+ * directory read.
3841
+ */
3842
+ async function profilesWithFootage(roots, deviceId, list = listDir) {
3843
+ const found = /* @__PURE__ */ new Set();
3844
+ for (const root of roots) {
3845
+ const entries = await list(node_path.default.join(root, String(deviceId)));
3846
+ for (const entry of entries) {
3847
+ if (!KNOWN_PROFILES$1.has(entry)) continue;
3848
+ if (found.has(entry)) continue;
3849
+ if ((await list(node_path.default.join(root, String(deviceId), entry))).length > 0) found.add(entry);
3850
+ }
3851
+ }
3852
+ return [...found].sort();
3853
+ }
3820
3854
  async function profileHasFootage(root, deviceId, profile) {
3821
3855
  return (await listDir(node_path.default.join(root, String(deviceId), profile))).length > 0;
3822
3856
  }
@@ -3938,6 +3972,8 @@ var CalendarIndex = class {
3938
3972
  segsReadAt = /* @__PURE__ */ new Map();
3939
3973
  /** The profile availability reads from, resolved once per device. */
3940
3974
  profileFor = /* @__PURE__ */ new Map();
3975
+ profilesFor = /* @__PURE__ */ new Map();
3976
+ profilesInFlight = /* @__PURE__ */ new Map();
3941
3977
  /** `deviceId:profile` → whether the device records that profile, resolved
3942
3978
  * once. Same stability trade as {@link profileFor}: a config change that
3943
3979
  * adds a profile mid-session is picked up on restart, not on a timer. */
@@ -4220,6 +4256,31 @@ var CalendarIndex = class {
4220
4256
  * reads at a time and they ALL ask for the profile before the first answer
4221
4257
  * lands, so a cache alone let the pick run eight times. Parallelism found it.
4222
4258
  */
4259
+ /**
4260
+ * Every profile this camera holds footage in, across every root — cached
4261
+ * like the pick, because it is the same shallow read (D433).
4262
+ *
4263
+ * {@link availabilityProfileFor} answers with ONE; this says what the one
4264
+ * was chosen FROM, so a caller cannot mistake the timeline's single bar for
4265
+ * the whole archive.
4266
+ */
4267
+ async profilesWithFootageFor(deviceId) {
4268
+ const cached = this.profilesFor.get(deviceId);
4269
+ if (cached !== void 0) return cached;
4270
+ const running = this.profilesInFlight.get(deviceId);
4271
+ if (running) return running;
4272
+ const resolve = (async () => {
4273
+ const found = await profilesWithFootage(this.deps.roots(), deviceId);
4274
+ this.profilesFor.set(deviceId, found);
4275
+ return found;
4276
+ })();
4277
+ this.profilesInFlight.set(deviceId, resolve);
4278
+ try {
4279
+ return await resolve;
4280
+ } finally {
4281
+ if (this.profilesInFlight.get(deviceId) === resolve) this.profilesInFlight.delete(deviceId);
4282
+ }
4283
+ }
4223
4284
  async availabilityProfileFor(deviceId) {
4224
4285
  const cached = this.profileFor.get(deviceId);
4225
4286
  if (cached !== void 0) return cached;
@@ -5864,6 +5925,8 @@ var TIME_RE = /time=(\d+):(\d+):(\d+(?:\.\d+)?)/;
5864
5925
  * whatever ffmpeg build is installed.
5865
5926
  */
5866
5927
  var EXPORT_MIN_PLAUSIBLE_BYTES = 1024;
5928
+ /** ffmpeg's own announcement of that pass — the only signal it gives. */
5929
+ var FASTSTART_RE = /Starting second pass: moving the moov atom/i;
5867
5930
  /** Expected OUTPUT duration (seconds) for progress scaling. */
5868
5931
  function expectedOutSeconds(rec) {
5869
5932
  const rangeSec = Math.max(.001, (rec.toMs - rec.fromMs) / 1e3);
@@ -6173,6 +6236,7 @@ var ExportEngine = class {
6173
6236
  args
6174
6237
  } });
6175
6238
  const stallMs = this.deps.stallMs ?? 9e4;
6239
+ const faststartStallMs = this.deps.faststartStallMs ?? 9e5;
6176
6240
  return new Promise((resolve) => {
6177
6241
  const proc = this.deps.spawn(this.deps.ffmpegPath ?? "ffmpeg", args);
6178
6242
  this.active.set(id, proc);
@@ -6184,14 +6248,16 @@ var ExportEngine = class {
6184
6248
  stallTimer = null;
6185
6249
  }
6186
6250
  };
6251
+ let budgetMs = stallMs;
6187
6252
  const armStall = () => {
6188
6253
  clearStall();
6254
+ const armedFor = budgetMs;
6189
6255
  stallTimer = setTimeout(() => {
6190
- stderrTail.push(`ffmpeg stalled: no progress for ${stallMs}ms`);
6256
+ stderrTail.push(`ffmpeg stalled: no progress for ${armedFor}ms`);
6191
6257
  try {
6192
6258
  proc.kill("SIGKILL");
6193
6259
  } catch {}
6194
- }, stallMs);
6260
+ }, armedFor);
6195
6261
  };
6196
6262
  armStall();
6197
6263
  proc.stderr?.on("data", (chunk) => {
@@ -6202,6 +6268,10 @@ var ExportEngine = class {
6202
6268
  stderrTail.push(trimmed);
6203
6269
  if (stderrTail.length > STDERR_TAIL_LINES$1) stderrTail.shift();
6204
6270
  }
6271
+ if (FASTSTART_RE.test(line)) {
6272
+ budgetMs = faststartStallMs;
6273
+ armStall();
6274
+ }
6205
6275
  const m = TIME_RE.exec(line);
6206
6276
  if (m) {
6207
6277
  armStall();
@@ -7379,13 +7449,15 @@ function buildRecordingProvider(deps) {
7379
7449
  * and by the batch alike — the batch collapses the TRANSPORT, and sharing the
7380
7450
  * function is what makes that literally true instead of aspirational.
7381
7451
  */
7382
- const availabilityFor = async (deviceId, fromMs, toMs) => {
7452
+ const availabilityFor = async (deviceId, fromMs, toMs, requestedProfile) => {
7383
7453
  const calendar = deps.calendar;
7384
7454
  if (calendar) {
7385
- const profile = await calendar.availabilityProfileFor(deviceId);
7455
+ const profilesWithFootage = await calendar.profilesWithFootageFor(deviceId);
7456
+ const profile = await calendar.servedProfileFor(deviceId, requestedProfile);
7386
7457
  if (profile === null) return {
7387
7458
  deviceId,
7388
- ranges: []
7459
+ ranges: [],
7460
+ profilesWithFootage: [...profilesWithFootage]
7389
7461
  };
7390
7462
  const ranges = [];
7391
7463
  for (const r of await calendar.rangesIn(deviceId, profile, fromMs, toMs)) ranges.push({
@@ -7395,16 +7467,20 @@ function buildRecordingProvider(deps) {
7395
7467
  });
7396
7468
  return {
7397
7469
  deviceId,
7398
- ranges
7470
+ ranges,
7471
+ profilesWithFootage: [...profilesWithFootage]
7399
7472
  };
7400
7473
  }
7474
+ const profiles = new Set(deps.index.segments(deviceId).map((s) => s.profile));
7475
+ const asked = requestedProfile !== void 0 && profiles.has(requestedProfile);
7401
7476
  return {
7402
7477
  deviceId,
7403
- ranges: [...new Set(deps.index.segments(deviceId).map((s) => s.profile))].flatMap((profile) => deps.index.ranges(deviceId, profile, fromMs, toMs, RANGE_MERGE_GAP_MS).map((r) => ({
7478
+ ranges: [...profiles].filter((p) => !asked || p === requestedProfile).flatMap((profile) => deps.index.ranges(deviceId, profile, fromMs, toMs, RANGE_MERGE_GAP_MS).map((r) => ({
7404
7479
  profile,
7405
7480
  startMs: r.startMs,
7406
7481
  endMs: r.endMs
7407
- })))
7482
+ }))),
7483
+ profilesWithFootage: [...profiles].sort()
7408
7484
  };
7409
7485
  };
7410
7486
  /** The per-camera day read. Same rule as {@link availabilityFor}: one body. */
@@ -7434,7 +7510,7 @@ function buildRecordingProvider(deps) {
7434
7510
  getStatus: async ({ deviceId }) => {
7435
7511
  return statusFor(deps, deviceId, await loadDeviceConfig(deps.configStore, deviceId));
7436
7512
  },
7437
- getAvailability: ({ deviceId, fromMs, toMs }) => availabilityFor(deviceId, fromMs, toMs),
7513
+ getAvailability: ({ deviceId, fromMs, toMs, profile }) => availabilityFor(deviceId, fromMs, toMs, profile),
7438
7514
  /**
7439
7515
  * `getAvailability` for a SET of cameras. Same body per camera, run
7440
7516
  * concurrently; only the transport collapses.
@@ -7448,11 +7524,12 @@ function buildRecordingProvider(deps) {
7448
7524
  refuseOverCap("getAvailabilityBatch", deviceIds.length);
7449
7525
  return Promise.all(deviceIds.map(async (deviceId) => {
7450
7526
  try {
7451
- const { ranges } = await availabilityFor(deviceId, fromMs, toMs);
7527
+ const { ranges, profilesWithFootage } = await availabilityFor(deviceId, fromMs, toMs);
7452
7528
  return {
7453
7529
  deviceId,
7454
7530
  read: "read",
7455
- ranges
7531
+ ranges,
7532
+ profilesWithFootage
7456
7533
  };
7457
7534
  } catch (err) {
7458
7535
  deps.logger.warn("recording availability could not be read", {
@@ -7466,7 +7543,8 @@ function buildRecordingProvider(deps) {
7466
7543
  return {
7467
7544
  deviceId,
7468
7545
  read: "unreadable",
7469
- ranges: []
7546
+ ranges: [],
7547
+ profilesWithFootage: []
7470
7548
  };
7471
7549
  }
7472
7550
  }));