@camstack/addon-post-analysis 1.2.663 → 1.2.665

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 (16) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/{clip-model-registry-CwXJyrLg.mjs → clip-model-registry-DZTzG2p4.mjs} +377 -132
  3. package/dist/{clip-model-registry-Cz8LWYwU.js → clip-model-registry-nn_STiGt.js} +382 -131
  4. package/dist/embedding-encoder/index.js +1 -1
  5. package/dist/embedding-encoder/index.mjs +1 -1
  6. package/dist/pipeline-analytics/_stub.js +2 -2
  7. package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-jPBj20ez.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Hy74pMMo.mjs} +2 -2
  8. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BXTAZYaJ.mjs +26 -0
  9. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Br6eWzp_.mjs +26 -0
  10. package/dist/pipeline-analytics/{hostInit-DOdK6KJ5.mjs → hostInit-BAYLsfoZ.mjs} +2 -2
  11. package/dist/pipeline-analytics/index.js +438 -61
  12. package/dist/pipeline-analytics/index.mjs +438 -61
  13. package/dist/pipeline-analytics/remoteEntry.js +1 -1
  14. package/package.json +2 -2
  15. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Be6bZvOS.mjs +0 -26
  16. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B5Bw-VHt.mjs +0 -26
@@ -1,4 +1,4 @@
1
- import { $ as MAX_TRACK_RELATIONS, $i as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, $n as bundledCamstack, $r as normalizeNcAction, $t as NcTemplateVarDescriptorSchema, A as DETECTION_MACRO_CLASSES, Aa as strictObject, Ai as sceneMonitorCapability, An as TrackPuritySchema, Ar as isAlertEpisodeOpen, At as NcAlarmConfigSchema, B as EXPORT_DENSE_MAX_RANGES, Bi as sunTimes, Bn as alertEpisodeKind, Br as isLabelSupplyStepId, Bt as NcRuleSchema, C as COCO_TO_MACRO, Ca as discriminatedUnion, Ci as retrainRevisionConflictMessage, Cn as SetTrackRelationInputSchema, Cr as eventKindLabel, Ct as NC_GROUPING_MIN_SEC, D as DEFAULT_DETAIL_CROP_CONVENTION, Da as object, Di as ruleDeviceCompatCapQueries, Dn as TimelapseRulePatchSchema, Dr as gifDeriveSpeed, Dt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, E as CoverStateSchema, Ea as number, Ei as ruleBelongsToAlarm$1, En as TimelapseRuleInputSchema, Er as failureContributionCapability, Et as NC_STATE_SUMMARY_SECTION_IDS, F as EMBEDDING_REQUIREMENTS_FAILED, Fa as unknown, Fi as storageOccupancyCapability, Fn as activateAlarmProfile, Fr as isDetectionMacroClass, Ft as NcConditionDescriptorSchema, G as LabelAttributionSchema, Gi as systemEventSummaryScheduleOf, Gn as applySecureOnArmEdit, Gr as isSystemDelivery, Gt as NcSnoozeInputSchema, H as FULL_IMAGE_BBOX, Hi as systemEventDeliveryProblems, Hn as applyBlockingEdit, Hr as isRetiredClearKey, Ht as NcRuleUpdateInputSchema, I as EMBEDDING_REQUIREMENTS_UNAVAILABLE, Ia as DeviceType, Ii as subKindsOf, In as addonWidgetsSourceCapability, Ir as isDrawableSubjectPath, It as NcConditionsSchema, J as LockStateSchema, Ji as templateVarsFor, Jn as audioMetricsCapability, Jr as kebabToCamel, Jt as NcStateSummarySectionIdSchema, K as ListTrackRelationsInputSchema, Ki as systemEventSummarySplitOf, Kn as armRemovalReconcile, Kr as isSystemEventSummaryRule, Kt as NcSnoozeSchema, L as EVENT_DENSITY_BATCH_MAX, La as errMsg, Li as subjectPathSampleFromBox, Ln as alarmDeviceSecureOnArm, Lr as isEventKindLabelKey, Lt as NcRuleActionSchema, M as DeclaredDevices, Ma as templateLiteral, Mi as sensorRaisedOf, Mn as TrackRelationSchema, Mr as isAppLinkBase, Mt as NcAlarmSensorsInputSchema, N as DetectionSourceSchema, Na as tuple, Ni as servedTemplateVars, Nn as TrackSideSchema, Nr as isAudioClassName, Nt as NcAlarmSensorsSchema, O as DEFAULT_EVENT_COLOR, Oa as partialRecord, Oi as ruleGroupingApplies, On as TimelapseRuleSchema, Or as gifFromMp4Args, Ot as NC_TAXONOMY, P as EMBEDDING_MODEL_FAILED, Pa as union, Pi as startMoverUnderClearance, Pn as TrackSourceSchema, Pr as isDefaultAlarmProfileId, Pt as NcAlarmSettingsPatchSchema, Q as MAX_TRACK_PURITIES, Qi as zoneAnalyticsCapability, Qn as buildViewerLink, Qr as ncMediaPolicyError, Qt as NcTemplatePreviewSchema, R as EVENT_KIND_BY_CAP, Ra as EventCategory, Ri as subjectPathSvgPoints, Rn as alarmPanelCapability, Rr as isEventOwnerType, Rt as NcRuleInputSchema, S as BucketAccumulator, Sa as boolean, Sn as SetTrackPurityResultSchema, Sr as ensureAlarmProfiles, St as NC_GROUPING_MAX_SEC, T as ClearTrackRelationResultSchema, Ta as looseObject, Ti as ruleAutoTriggersAlarm, Tn as TRACK_RELATIONS_DEFAULT_LIMIT, Tr as faceGalleryCapability, Tt as NC_SNOOZE_MAX_MINUTES, U as FailureCounters, Ui as systemEventFamilyProblems, Un as applyModeDelaysEdits, Ur as isRootSuppliableStepId, Ut as NcScheduleSchema, V as FIRST_LEVEL_MACRO_CLASSES, Vi as syncActiveAlarmProfileSettings, Vn as alertEpisodePayload, Vr as isMediaOwnerType, Vt as NcRuleTargetSchema, W as LABEL_SUPPLY_MACRO, Wi as systemEventFilterApplies, Wn as applyNonBlockingEdit, Wr as isScheduleActive, Wt as NcSharedSequenceSchema, X as MAX_BIRTH_DECISION_RECORDS, Xi as viewerLinkBaseOf, Xn as buildEventKindDescriptor, Xr as mayWriteToLocation, Xt as NcTaxonomySchema, Y as MAX_ARCHIVED_DEBUG_NOTES, Yi as vectorDimFromBase64, Yn as audioModeOf, Yr as linkedStepOf, Yt as NcSystemEventKindSchema, Z as MAX_BIRTH_LATENCY_PROXY_MS, Zi as withSystemEventClasses, Zn as buildSubjectPath, Zr as memoizePinnedFfmpeg, Zt as NcTemplatePreviewInputSchema, _ as AlarmArmModeSchema, _i as resolveDeliveryParams, _n as SCENE_DEFAULT_UNCOVERED_POLICY, _t as NC_CONFIRM_DEFAULT_TIMEOUT_MS, a as CLIP_EMBEDDING_STEP_ID, aa as CamProfileSchema, ai as paletteResultSchema, an as RECORDING_SOURCE_CAMSTACK_ADDON, ar as coreBlockIdFromAddonId, at as NC_ALARM_DELAY_FIELDS, b as BaseDevice, ba as _enum, bi as resolveModeNotifyPolicy, bn as SceneMonitorSchema, bt as NC_DEFAULT_SNOOZE_MINUTES, c as readClusterModelPinStrict, ca as RECORD_QUERY_MAX, ci as pickFaceRescoreIntervalMinutes, cn as RetrainOriginSchema, cr as deleteAlarmProfile, ct as NC_ALARM_SYSTEM_EVENT_KINDS, d as APPEARANCE_BIN_COUNT, da as defineAddonMigrations, di as projectSubjectPath, dn as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, dr as deriveRecordingMode, dt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, ea as canonicalHash, ei as normalizeNcCapTarget, en as OPS_LOG_DEFAULT_LIMIT, er as calendarEventLocalSpan, et as MOTION_CLOSE_AFTER_MS, f as APPEARANCE_BLOCKS, fa as defineCustomActions, fi as readDeviceStateFrom, fn as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, fr as describeSystemEventDeliveryProblem, ft as NC_CLIP_POST_ROLL_DEFAULT_SEC, g as ActionTargetResolver, ga as nodePin, gi as resolveClipSearchMinScore, gn as SCENE_DEFAULT_QUIET_SECONDS, gt as NC_CONFIRM_DEFAULT_MAX_IMAGE_PX, h as AUDIO_MACRO_LABELS, ha as isDeviceScopedCap, hi as renameAlarmProfile, hn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, hr as deviceRemovalHookCapability, ht as NC_CONDITION_CATALOG, ia as CAP_ADVANCE_FIELDS, ii as paintHex, in as RECORDING_EXPORT_MAX_READ_BYTES, ir as consumableLowPercentOf, it as NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC, j as DETECTION_PIPELINE_CAP_NAME, ja as string, ji as secureActuationFor, jn as TrackRelationKindSchema, jr as isAlertEpisodeSeverity, jt as NcAlarmPostTriggeredActionSchema, k as DEFAULT_TIMELAPSE_PREVIEW_TEXT, ka as record, ki as ruleKindOf, kn as TrackPlacementSchema, kr as isAlarmControllableCap, kt as NC_TEMPLATE_VARS, l as resolveClusterModelPin, la as createEvent, li as pipelineAnalyticsCapability, ln as RetrainStatusSchema, lr as deriveDetailCropRect, lt as NC_ALARM_TRIGGERED_MAX_SEC, m as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, ma as hydrateSchema, mi as readTimelapseGeneratedAt, mn as SCENE_DEFAULT_CHECK_INTERVAL_SEC, mr as deviceAttentionKind, mt as NC_CLIP_RETENTION_MAX_SEC, na as isSourceCap, ni as notificationRulesCapability, nn as PackageLlmVerdictSchema, nr as cloneAlarmSettings, nt as MotionTriggeredBySchema, o as CLUSTER_MODEL_OWNER_ADDON_ID, oa as InvalidRecordError, oi as parseAlertEpisodePayload, on as RebuildObjectEmbeddingsRefusalSchema, or as cosineSimilarity$1, ot as NC_ALARM_DELAY_MAX_SEC, p as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, pa as defineRecordKinds, pi as readMotionTriggeredBy, pn as SCENE_DEFAULT_ANCHOR_THRESHOLD, pr as describeSystemEventFamilyProblem, pt as NC_CLIP_PRE_ROLL_DEFAULT_SEC, q as ListTrackRelationsResultSchema, qi as templateCarriesSummary, qn as assertTimelapseCadences, qr as isVectorIndexDimConflict, qt as NcSnoozeSuppressedSchema, ra as BaseAddon, ri as occupancyScope, rr as consumableFormOf, rt as NC_ALARM_DEFAULT_PROFILE_ID, s as FACE_EMBEDDING_STEP_ID, sa as RECORD_MAX_DATA_BYTES, sn as RetrainDismissedSchema, sr as createAlarmProfile, st as NC_ALARM_NOTIFY_FIELDS, t as BUILTIN_CLIP_MODELS, ta as evaluateSensorEdge, ti as normalizeNcMediaPolicy, tn as OpsLogEntrySchema, tr as classifyRetrainReview, tt as MediaFileKindEnum, u as ACTION_TARGET_INVALIDATION_EVENTS, ua as customAction, ui as plateGalleryCapability, un as RetrainVerdictSubjectSchema, ur as derivePostTriggeredAction, ut as NC_AUDIO_CONFIRM_HITS_DEFAULT, v as ArchivedDebugNoteSchema, va as sleep$1, vi as resolveLocationMode, vn as SCENE_DIVERGED, vr as embeddingRefusalOf, vt as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, w as ClearTrackRelationInputSchema, wa as literal, wi as rootSupplyServes, wn as TIMELAPSE_DENSE_FLOOR_SEC, wr as evictionPolicyOfLocation, wt as NC_SENSOR_TRANSITION_KINDS, x as BirthDecisionRecordSchema, xa as array, xi as resolveNcMediaImage, xn as SetTrackPurityInputSchema, xr as encodeVectorBase64, xt as NC_GROUPING_DEFAULT_SEC, y as BIRTH_DECISION_DEFAULT_LIMIT, ya as ZodObject, yi as resolveModeDelays, yn as SCENE_RESET_RECAPTURES, yt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, z as EVENT_OWNER_TYPES, zi as summarizeReview, zn as alertEpisodeId, zr as isKnownTemplateVar, zt as NcRulePatchSchema } from "../clip-model-registry-CwXJyrLg.mjs";
1
+ import { $ as MAX_TRACK_RELATIONS, $i as zoneAnalyticsCapability, $n as buildViewerLink, $r as ncMediaPolicyError, $t as NcTemplatePreviewSchema, A as DETECTION_MACRO_CLASSES, Aa as record, Ai as ruleKindOf, An as TrackPlacementSchema, Ar as isAlarmControllableCap, At as NcAlarmConfigSchema, B as EXPORT_DENSE_MAX_RANGES, Bi as summarizeReview, Bn as alertEpisodeId, Br as isKnownTemplateVar, Bt as NcRuleSchema, C as COCO_TO_MACRO, Ca as boolean, Cn as SetTrackPurityResultSchema, Cr as ensureAlarmProfiles, Ct as NC_GROUPING_MIN_SEC, D as DEFAULT_DETAIL_CROP_CONVENTION, Da as number, Di as ruleBelongsToAlarm$1, Dn as TimelapseRuleInputSchema, Dr as failureContributionCapability, Dt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, E as CoverStateSchema, Ea as looseObject, Ei as ruleAutoTriggersAlarm, En as TRACK_RELATIONS_DEFAULT_LIMIT, Er as faceGalleryCapability, Et as NC_STATE_SUMMARY_SECTION_IDS, F as EMBEDDING_REQUIREMENTS_FAILED, Fa as union, Fi as startMoverUnderClearance, Fn as TrackSourceSchema, Fr as isDefaultAlarmProfileId, Ft as NcConditionDescriptorSchema, G as LabelAttributionSchema, Gi as systemEventFilterApplies, Gn as applyNonBlockingEdit, Gr as isScheduleActive, Gt as NcSnoozeInputSchema, H as FULL_IMAGE_BBOX, Hi as syncActiveAlarmProfileSettings, Hn as alertEpisodePayload, Hr as isMediaOwnerType, Ht as NcRuleUpdateInputSchema, I as EMBEDDING_REQUIREMENTS_UNAVAILABLE, Ia as unknown, Ii as storageOccupancyCapability, In as activateAlarmProfile, Ir as isDetectionMacroClass, It as NcConditionsSchema, J as LockStateSchema, Ji as templateCarriesSummary, Jn as assertTimelapseCadences, Jr as isVectorIndexDimConflict, Jt as NcStateSummarySectionIdSchema, K as ListTrackRelationsInputSchema, Ki as systemEventSummaryScheduleOf, Kn as applySecureOnArmEdit, Kr as isSystemDelivery, Kt as NcSnoozeSchema, L as EVENT_DENSITY_BATCH_MAX, La as DeviceType, Li as subKindsOf, Ln as addonWidgetsSourceCapability, Lr as isDrawableSubjectPath, Lt as NcRuleActionSchema, M as DeclaredDevices, Ma as string, Mi as secureActuationFor, Mn as TrackRelationKindSchema, Mr as isAlertEpisodeSeverity, Mt as NcAlarmSensorsInputSchema, N as DetectionSourceSchema, Na as templateLiteral, Ni as sensorRaisedOf, Nn as TrackRelationSchema, Nr as isAppLinkBase, Nt as NcAlarmSensorsSchema, O as DEFAULT_EVENT_COLOR, Oa as object, Oi as ruleDeviceCompatCapQueries, On as TimelapseRulePatchSchema, Or as gifDeriveSpeed, Ot as NC_TAXONOMY, P as EMBEDDING_MODEL_FAILED, Pa as tuple, Pi as servedTemplateVars, Pn as TrackSideSchema, Pr as isAudioClassName, Pt as NcAlarmSettingsPatchSchema, Q as MAX_TRACK_PURITIES, Qi as withSystemEventClasses, Qn as buildSubjectPath, Qr as memoizePinnedFfmpeg, Qt as NcTemplatePreviewInputSchema, R as EVENT_KIND_BY_CAP, Ra as errMsg, Ri as subjectPathSampleFromBox, Rn as alarmDeviceSecureOnArm, Rr as isEventKindLabelKey, Rt as NcRuleInputSchema, S as BucketAccumulator, Sa as array, Si as resolveNcMediaImage, Sn as SetTrackPurityInputSchema, Sr as encodeVectorBase64, St as NC_GROUPING_MAX_SEC, T as ClearTrackRelationResultSchema, Ta as literal, Ti as rootSupplyServes, Tn as TIMELAPSE_DENSE_FLOOR_SEC, Tr as evictionPolicyOfLocation, Tt as NC_SNOOZE_MAX_MINUTES, U as FailureCounters, Ui as systemEventDeliveryProblems, Un as applyBlockingEdit, Ur as isRetiredClearKey, Ut as NcScheduleSchema, V as FIRST_LEVEL_MACRO_CLASSES, Vi as sunTimes, Vn as alertEpisodeKind, Vr as isLabelSupplyStepId, Vt as NcRuleTargetSchema, W as LABEL_SUPPLY_MACRO, Wi as systemEventFamilyProblems, Wn as applyModeDelaysEdits, Wr as isRootSuppliableStepId, Wt as NcSharedSequenceSchema, X as MAX_BIRTH_DECISION_RECORDS, Xi as vectorDimFromBase64, Xn as audioModeOf, Xr as linkedStepOf, Xt as NcTaxonomySchema, Y as MAX_ARCHIVED_DEBUG_NOTES, Yi as templateVarsFor, Yn as audioMetricsCapability, Yr as kebabToCamel, Yt as NcSystemEventKindSchema, Z as MAX_BIRTH_LATENCY_PROXY_MS, Zi as viewerLinkBaseOf, Zn as buildEventKindDescriptor, Zr as mayWriteToLocation, Zt as NcTemplateDefaultSchema, _ as AlarmArmModeSchema, _a as nodePin, _i as resolveClipSearchMinScore, _n as SCENE_DEFAULT_QUIET_SECONDS, _t as NC_CONFIRM_DEFAULT_TIMEOUT_MS, a as CLIP_EMBEDDING_STEP_ID, aa as CAP_ADVANCE_FIELDS, ai as paintHex, an as RECORDING_EXPORT_MAX_READ_BYTES, ar as consumableLowPercentOf, at as NC_ALARM_DELAY_FIELDS, b as BaseDevice, ba as ZodObject, bi as resolveModeDelays, bn as SCENE_RESET_RECAPTURES, bt as NC_DEFAULT_SNOOZE_MINUTES, c as readClusterModelPinStrict, ca as RECORD_MAX_DATA_BYTES, cn as RetrainDismissedSchema, cr as createAlarmProfile, ct as NC_ALARM_SYSTEM_EVENT_KINDS, d as APPEARANCE_BIN_COUNT, da as customAction, di as plateGalleryCapability, dn as RetrainVerdictSubjectSchema, dr as derivePostTriggeredAction, dt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, ea as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, ei as normalizeNcAction, en as NcTemplateVarDescriptorSchema, er as bundledCamstack, et as MOTION_CLOSE_AFTER_MS, f as APPEARANCE_BLOCKS, fa as defineAddonMigrations, fi as projectSubjectPath, fn as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, fr as deriveRecordingMode, ft as NC_CLIP_POST_ROLL_DEFAULT_SEC, g as ActionTargetResolver, ga as isDeviceScopedCap, gi as renameAlarmProfile, gn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, gr as deviceRemovalHookCapability, gt as NC_CONFIRM_DEFAULT_MAX_IMAGE_PX, h as AUDIO_MACRO_LABELS, ha as hydrateSchema, hi as readTimelapseGeneratedAt, hn as SCENE_DEFAULT_CHECK_INTERVAL_SEC, hr as deviceAttentionKind, ht as NC_CONDITION_CATALOG, ia as BaseAddon, ii as occupancyScope, ir as consumableFormOf, it as NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC, j as DETECTION_PIPELINE_CAP_NAME, ja as strictObject, ji as sceneMonitorCapability, jn as TrackPuritySchema, jr as isAlertEpisodeOpen, jt as NcAlarmPostTriggeredActionSchema, k as DEFAULT_TIMELAPSE_PREVIEW_TEXT, ka as partialRecord, ki as ruleGroupingApplies, kn as TimelapseRuleSchema, kr as gifFromMp4Args, kt as NC_TEMPLATE_VARS, l as resolveClusterModelPin, la as RECORD_QUERY_MAX, li as pickFaceRescoreIntervalMinutes, ln as RetrainOriginSchema, lr as deleteAlarmProfile, lt as NC_ALARM_TRIGGERED_MAX_SEC, m as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, ma as defineRecordKinds, mi as readMotionTriggeredBy, mn as SCENE_DEFAULT_ANCHOR_THRESHOLD, mr as describeSystemEventFamilyProblem, mt as NC_CLIP_RETENTION_MAX_SEC, na as evaluateSensorEdge, ni as normalizeNcMediaPolicy, nn as OpsLogEntrySchema, nr as classifyRetrainReview, nt as MotionTriggeredBySchema, o as CLUSTER_MODEL_OWNER_ADDON_ID, oa as CamProfileSchema, oi as paletteResultSchema, on as RECORDING_SOURCE_CAMSTACK_ADDON, or as coreBlockIdFromAddonId, ot as NC_ALARM_DELAY_MAX_SEC, p as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, pa as defineCustomActions, pi as readDeviceStateFrom, pn as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, pr as describeSystemEventDeliveryProblem, pt as NC_CLIP_PRE_ROLL_DEFAULT_SEC, q as ListTrackRelationsResultSchema, qi as systemEventSummarySplitOf, qn as armRemovalReconcile, qr as isSystemEventSummaryRule, qt as NcSnoozeSuppressedSchema, ra as isSourceCap, ri as notificationRulesCapability, rn as PackageLlmVerdictSchema, rr as cloneAlarmSettings, rt as NC_ALARM_DEFAULT_PROFILE_ID, s as FACE_EMBEDDING_STEP_ID, sa as InvalidRecordError, si as parseAlertEpisodePayload, sn as RebuildObjectEmbeddingsRefusalSchema, sr as cosineSimilarity$1, st as NC_ALARM_NOTIFY_FIELDS, t as BUILTIN_CLIP_MODELS, ta as canonicalHash, ti as normalizeNcCapTarget, tn as OPS_LOG_DEFAULT_LIMIT, tr as calendarEventLocalSpan, tt as MediaFileKindEnum, u as ACTION_TARGET_INVALIDATION_EVENTS, ua as createEvent, ui as pipelineAnalyticsCapability, un as RetrainStatusSchema, ur as deriveDetailCropRect, ut as NC_AUDIO_CONFIRM_HITS_DEFAULT, v as ArchivedDebugNoteSchema, vi as resolveDeliveryParams, vn as SCENE_DEFAULT_UNCOVERED_POLICY, vt as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, w as ClearTrackRelationInputSchema, wa as discriminatedUnion, wi as retrainRevisionConflictMessage, wn as SetTrackRelationInputSchema, wr as eventKindLabel, wt as NC_SENSOR_TRANSITION_KINDS, x as BirthDecisionRecordSchema, xa as _enum, xi as resolveModeNotifyPolicy, xn as SceneMonitorSchema, xt as NC_GROUPING_DEFAULT_SEC, y as BIRTH_DECISION_DEFAULT_LIMIT, ya as sleep$1, yi as resolveLocationMode, yn as SCENE_DIVERGED, yr as embeddingRefusalOf, yt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, z as EVENT_OWNER_TYPES, za as EventCategory, zi as subjectPathSvgPoints, zn as alarmPanelCapability, zr as isEventOwnerType, zt as NcRulePatchSchema } from "../clip-model-registry-DZTzG2p4.mjs";
2
2
  import { t as __exportAll } from "../embedding-encoder/index.mjs";
3
3
  import * as fs$1 from "node:fs";
4
4
  import { createWriteStream, promises } from "node:fs";
@@ -12276,6 +12276,16 @@ var NcStateSummaryTestSchema = object({
12276
12276
  }))
12277
12277
  });
12278
12278
  //#endregion
12279
+ //#region src/notification-center/template-defaults.ts
12280
+ function servedTemplateDefaults(texts) {
12281
+ return [{
12282
+ id: "appliance-cycle",
12283
+ kind: "sensor",
12284
+ title: texts.raw("appliance.finished.title") ?? "",
12285
+ body: texts.raw("appliance.finished.body") ?? ""
12286
+ }];
12287
+ }
12288
+ //#endregion
12279
12289
  //#region src/notification-center/clock-text.ts
12280
12290
  /**
12281
12291
  * `{{time}}` — hours and minutes in the NOTIFICATION language.
@@ -13659,7 +13669,10 @@ var ncActions = defineCustomActions({
13659
13669
  catalog: array(NcConditionDescriptorSchema),
13660
13670
  taxonomy: NcTaxonomySchema
13661
13671
  })),
13662
- "nc.getTemplateCatalog": customAction(object({}), object({ vars: array(NcTemplateVarDescriptorSchema) })),
13672
+ "nc.getTemplateCatalog": customAction(object({}), object({
13673
+ vars: array(NcTemplateVarDescriptorSchema),
13674
+ defaults: array(NcTemplateDefaultSchema)
13675
+ })),
13663
13676
  "nc.previewTemplate": customAction(NcTemplatePreviewInputSchema, NcTemplatePreviewSchema, { kind: "mutation" }),
13664
13677
  "nc.createRule": customAction(object({ rule: NcRuleInputSchema }), object({ rule: NcRuleSchema }), {
13665
13678
  kind: "mutation",
@@ -14439,7 +14452,10 @@ function makeNcActionHandlers(deps) {
14439
14452
  catalog: [...NC_CONDITION_CATALOG],
14440
14453
  taxonomy: NC_TAXONOMY
14441
14454
  }),
14442
- "nc.getTemplateCatalog": async () => ({ vars: servedTemplateVars() }),
14455
+ "nc.getTemplateCatalog": async () => ({
14456
+ vars: servedTemplateVars(),
14457
+ defaults: deps.previewTexts === void 0 ? [] : servedTemplateDefaults(deps.previewTexts)
14458
+ }),
14443
14459
  "nc.previewTemplate": async (input) => {
14444
14460
  const texts = deps.previewTexts;
14445
14461
  if (texts === void 0) throw new Error("nc.previewTemplate: text catalog not wired");
@@ -49856,7 +49872,7 @@ async function encodeRgbCropToJpeg(bytes, width, height) {
49856
49872
  * what lets the caller stop base64-ing purely to be understood.
49857
49873
  */
49858
49874
  async function decodeJpegToRgb(jpeg) {
49859
- const { data, info } = await sharp(typeof jpeg === "string" ? Buffer.from(jpeg, "base64") : jpeg).raw().toBuffer({ resolveWithObject: true });
49875
+ const { data, info } = await sharp(typeof jpeg === "string" ? Buffer.from(jpeg, "base64") : jpeg).removeAlpha().toColourspace("srgb").raw().toBuffer({ resolveWithObject: true });
49860
49876
  return {
49861
49877
  bytes: data,
49862
49878
  width: info.width,
@@ -52942,6 +52958,42 @@ function collectPackageZoneIds(rules) {
52942
52958
  }
52943
52959
  return ids;
52944
52960
  }
52961
+ /**
52962
+ * How much the package zone box grows on every side when asking whether motion
52963
+ * reached it. Mirrors the D144 dilation of the pipeline's burst trigger
52964
+ * (`PACKAGE_ZONE_DILATION` in addon-pipeline, not importable from here): about
52965
+ * one adult's width beside a doormat, the place a courier stands.
52966
+ */
52967
+ var PACKAGE_ZONE_MOTION_DILATION = .5;
52968
+ /**
52969
+ * A motion region covering more than this fraction of the frame is a light
52970
+ * change or the weather, not a person: it never counts as a deliverer.
52971
+ */
52972
+ var PACKAGE_ZONE_MOTION_MAX_REGION_FRAC = .8;
52973
+ /**
52974
+ * Did analyzer motion reach the dilated package zone with a person-sized
52975
+ * region? Unknown geometry answers false: this stamp only ever BACKS the open
52976
+ * of a candidate, so failing closed keeps the light-wedge guard intact.
52977
+ */
52978
+ function delivererMotionNearPackageZone(input) {
52979
+ const { zoneRect, frameWidth, frameHeight } = input;
52980
+ if (zoneRect === null || frameWidth <= 0 || frameHeight <= 0) return false;
52981
+ const dx = zoneRect.w * PACKAGE_ZONE_MOTION_DILATION;
52982
+ const dy = zoneRect.h * PACKAGE_ZONE_MOTION_DILATION;
52983
+ const left = Math.max(0, zoneRect.x - dx);
52984
+ const top = Math.max(0, zoneRect.y - dy);
52985
+ const right = Math.min(1, zoneRect.x + zoneRect.w + dx);
52986
+ const bottom = Math.min(1, zoneRect.y + zoneRect.h + dy);
52987
+ for (const region of input.regions) {
52988
+ const x = region.bbox.x / frameWidth;
52989
+ const y = region.bbox.y / frameHeight;
52990
+ const w = region.bbox.w / frameWidth;
52991
+ const h = region.bbox.h / frameHeight;
52992
+ if (w * h > PACKAGE_ZONE_MOTION_MAX_REGION_FRAC) continue;
52993
+ if (x < right && left < x + w && y < bottom && top < y + h) return true;
52994
+ }
52995
+ return false;
52996
+ }
52945
52997
  //#endregion
52946
52998
  //#region src/pipeline-analytics/pipeline/package/package-collector-mirror.ts
52947
52999
  /**
@@ -53887,6 +53939,15 @@ var PACKAGE_STILLNESS_TTL_MS = 5 * 6e4;
53887
53939
  */
53888
53940
  var PACKAGE_STILLNESS_ASSOC_IOU = .3;
53889
53941
  /**
53942
+ * Lowest score of a below-threshold box that may CONTINUE an open candidate
53943
+ * (D665: a box under the floor may continue, never open). Observed on a real
53944
+ * parcel after the day to IR flip: 0.35 to 0.50.
53945
+ */
53946
+ var PACKAGE_STILLNESS_CONTINUATION_MIN_SCORE = .3;
53947
+ /** Above-floor sightings a candidate needs before a sub-floor box may count:
53948
+ * one confident look plus a doormat-shaped reading is not a parcel. */
53949
+ var PACKAGE_CONTINUATION_MIN_REAL_HITS = 2;
53950
+ /**
53890
53951
  * Two absence reads closer than this are ONE look, not two. A settle burst
53891
53952
  * runs the package step 5 s apart and a poll 45 s apart, so a real second
53892
53953
  * look is always further away; two frames of one moment (a re-dispatch, a
@@ -53936,6 +53997,7 @@ var PackageStillnessTracker = class {
53936
53997
  const next = [...this.byDevice.get(input.deviceId) ?? []];
53937
53998
  const consumed = /* @__PURE__ */ new Set();
53938
53999
  const promoted = [];
54000
+ const continuedLog = [];
53939
54001
  for (const s of input.sightings) {
53940
54002
  const index = this.bestMatch(next, s, consumed);
53941
54003
  if (index < 0) {
@@ -53948,17 +54010,33 @@ var PackageStillnessTracker = class {
53948
54010
  if (prev === void 0) continue;
53949
54011
  consumed.add(prev.id);
53950
54012
  const updated = confirm(prev, input, s);
53951
- const minHits = input.minHits ?? this.config.minHits;
53952
- if (!(updated.promotedAt === null && updated.activityBackedAtOpen && updated.hits >= minHits && input.timestamp - updated.firstSeenAt >= input.minDwellMs)) {
53953
- next[index] = updated;
53954
- continue;
53955
- }
53956
- const parked = {
53957
- ...updated,
53958
- promotedAt: input.timestamp
54013
+ const parked = this.promoteWhenReady(updated, input);
54014
+ next[index] = parked ?? updated;
54015
+ if (parked !== null) promoted.push(toEntry(parked));
54016
+ }
54017
+ if (input.looked === true && input.continuationBoxes !== void 0) for (let i = 0; i < next.length; i += 1) {
54018
+ const c = next[i];
54019
+ if (c === void 0 || c.promotedAt !== null || consumed.has(c.id)) continue;
54020
+ if (c.realHits < PACKAGE_CONTINUATION_MIN_REAL_HITS) continue;
54021
+ const box = this.continuationFor(c, input.continuationBoxes);
54022
+ if (box === null) continue;
54023
+ consumed.add(c.id);
54024
+ const continued = {
54025
+ ...c,
54026
+ lastSeenAt: input.timestamp,
54027
+ hits: c.hits + 1,
54028
+ absenceReads: [],
54029
+ lastLook: "present",
54030
+ earlyUnbackedReported: false
53959
54031
  };
53960
- next[index] = parked;
53961
- promoted.push(toEntry(parked));
54032
+ continuedLog.push({
54033
+ id: c.id,
54034
+ hits: continued.hits,
54035
+ score: box.score
54036
+ });
54037
+ const parked = this.promoteWhenReady(continued, input);
54038
+ next[i] = parked ?? continued;
54039
+ if (parked !== null) promoted.push(toEntry(parked));
53962
54040
  }
53963
54041
  const present = input.rawPackageBoxes !== void 0 ? withRawPresence(next, consumed, input.rawPackageBoxes, input.timestamp, this.config.assocIou) : next;
53964
54042
  const looked = input.looked === true && input.rawPackageBoxes !== void 0 ? withLook(present, consumed, input, input.rawPackageBoxes, this.config.assocIou) : present;
@@ -53994,7 +54072,8 @@ var PackageStillnessTracker = class {
53994
54072
  ...input.lastActivityAt !== void 0 ? { lastActivityAt: input.lastActivityAt } : {}
53995
54073
  }),
53996
54074
  earlyDepartureIds: [...early],
53997
- earlyEvidenceUnbacked: unbacked
54075
+ earlyEvidenceUnbacked: unbacked,
54076
+ continued: continuedLog
53998
54077
  };
53999
54078
  }
54000
54079
  /** Why complete early evidence may NOT conclude, or null when it may. */
@@ -54021,7 +54100,8 @@ var PackageStillnessTracker = class {
54021
54100
  ...input.lastActivityAt !== void 0 ? { lastActivityAt: input.lastActivityAt } : {}
54022
54101
  }),
54023
54102
  earlyDepartureIds: [],
54024
- earlyEvidenceUnbacked: []
54103
+ earlyEvidenceUnbacked: [],
54104
+ continued: []
54025
54105
  };
54026
54106
  }
54027
54107
  /** The devices holding a candidate — what a sweep has to visit. */
@@ -54085,6 +54165,43 @@ var PackageStillnessTracker = class {
54085
54165
  /** Best same-class candidate over the association floor, ignoring any already
54086
54166
  * consumed by an earlier sighting in THIS frame (two boxes never collapse
54087
54167
  * into one parcel). */
54168
+ continuationFor(c, boxes) {
54169
+ let best = null;
54170
+ let bestIou = this.config.assocIou;
54171
+ for (const b of boxes) {
54172
+ if (b.score < PACKAGE_STILLNESS_CONTINUATION_MIN_SCORE) continue;
54173
+ const overlap = iou$2(c.bbox, b.bbox);
54174
+ if (overlap >= bestIou) {
54175
+ bestIou = overlap;
54176
+ best = b;
54177
+ }
54178
+ }
54179
+ return best;
54180
+ }
54181
+ promoteWhenReady(candidate, input) {
54182
+ const updated = this.backedLate(candidate, input);
54183
+ const minHits = input.minHits ?? this.config.minHits;
54184
+ return updated.promotedAt === null && updated.activityBackedAtOpen && updated.hits >= minHits && input.timestamp - updated.firstSeenAt >= input.minDwellMs ? {
54185
+ ...updated,
54186
+ promotedAt: input.timestamp
54187
+ } : null;
54188
+ }
54189
+ /**
54190
+ * Zone motion learned AFTER the open still backs the candidate when its stamp
54191
+ * lies in the window around the FIRST sighting (the same slack a pick-up
54192
+ * gets): the backing stays anchored at the open, a later passer-by never
54193
+ * validates scenery (D1003).
54194
+ */
54195
+ backedLate(c, input) {
54196
+ if (c.activityBackedAtOpen || c.promotedAt !== null) return c;
54197
+ const at = input.lastDelivererMotionAt;
54198
+ const windowMs = input.activityWindowMs ?? 0;
54199
+ if (at === void 0 || windowMs <= 0) return c;
54200
+ return at >= c.firstSeenAt - windowMs && at <= c.firstSeenAt + this.config.roundGapMs ? {
54201
+ ...c,
54202
+ activityBackedAtOpen: true
54203
+ } : c;
54204
+ }
54088
54205
  bestMatch(candidates, s, consumed) {
54089
54206
  let bestIndex = -1;
54090
54207
  let bestIou = this.config.assocIou;
@@ -54101,7 +54218,7 @@ var PackageStillnessTracker = class {
54101
54218
  }
54102
54219
  openCandidate(input, s) {
54103
54220
  const windowMs = input.activityWindowMs ?? 0;
54104
- const activityBackedAtOpen = windowMs <= 0 || input.lastActivityAt !== void 0 && input.timestamp - input.lastActivityAt <= windowMs;
54221
+ const activityBackedAtOpen = windowMs <= 0 || input.lastActivityAt !== void 0 && input.timestamp - input.lastActivityAt <= windowMs || input.lastDelivererMotionAt !== void 0 && input.timestamp - input.lastDelivererMotionAt <= windowMs;
54105
54222
  return {
54106
54223
  id: this.newId(),
54107
54224
  deviceId: input.deviceId,
@@ -54112,6 +54229,7 @@ var PackageStillnessTracker = class {
54112
54229
  firstSeenAt: input.timestamp,
54113
54230
  lastSeenAt: input.timestamp,
54114
54231
  hits: 1,
54232
+ realHits: 1,
54115
54233
  promotedAt: null,
54116
54234
  absenceReads: [],
54117
54235
  lastLook: null,
@@ -54134,6 +54252,7 @@ function confirm(prev, input, s) {
54134
54252
  frameHeight: input.frameHeight,
54135
54253
  lastSeenAt: input.timestamp,
54136
54254
  hits: prev.hits + 1,
54255
+ realHits: prev.realHits + 1,
54137
54256
  absenceReads: [],
54138
54257
  lastLook: "present",
54139
54258
  earlyUnbackedReported: false,
@@ -54670,6 +54789,9 @@ var FrameState = class {
54670
54789
  * which would let the streetlight wedge vouch for its own delivery.
54671
54790
  */
54672
54791
  lastNonPackageActivityAt = /* @__PURE__ */ new Map();
54792
+ /** Last analyzer motion near a package drop-off zone, per device (D1003).
54793
+ * Backs the OPEN of a candidate only; never a pick-up witness. */
54794
+ lastPackageZoneMotionAt = /* @__PURE__ */ new Map();
54673
54795
  /**
54674
54796
  * WHO was in the drop-off zone, and when (D404). The pick-up is CONCLUDED
54675
54797
  * minutes after the fact, so the collector must be remembered while it is
@@ -58029,6 +58151,7 @@ function nextPackageLookDropEpisodes(previous, drops) {
58029
58151
  //#region src/pipeline-analytics/pipeline/package/package-look-evidence.ts
58030
58152
  function packageLookEvidence(input) {
58031
58153
  const raw = [];
58154
+ const continuation = [];
58032
58155
  for (const d of input.frame.detections) {
58033
58156
  if (d.kind !== "first-level" || !input.packageClasses.has(d.macroClass)) continue;
58034
58157
  raw.push({
@@ -58041,11 +58164,16 @@ function packageLookEvidence(input) {
58041
58164
  for (const d of input.frame.discarded ?? []) {
58042
58165
  if (!input.packageClasses.has(d.macroClass)) continue;
58043
58166
  const [x1, y1, x2, y2] = d.bbox;
58044
- raw.push({
58167
+ const box = {
58045
58168
  x: x1,
58046
58169
  y: y1,
58047
58170
  w: x2 - x1,
58048
58171
  h: y2 - y1
58172
+ };
58173
+ raw.push(box);
58174
+ if (d.reason === "below-threshold") continuation.push({
58175
+ bbox: box,
58176
+ score: d.score
58049
58177
  });
58050
58178
  }
58051
58179
  return {
@@ -58057,6 +58185,7 @@ function packageLookEvidence(input) {
58057
58185
  h: t.bbox.h
58058
58186
  })),
58059
58187
  rawPackageBoxes: raw,
58188
+ continuationBoxes: continuation,
58060
58189
  earlyPickup: input.earlyPickupEnabled
58061
58190
  };
58062
58191
  }
@@ -58244,6 +58373,13 @@ function clamp01(value) {
58244
58373
  }
58245
58374
  //#endregion
58246
58375
  //#region src/pipeline-analytics/pipeline/package/package-scene-diff.ts
58376
+ /**
58377
+ * Zone-crop scene difference for a packages rule (D931).
58378
+ *
58379
+ * A uniform brightness shift is removed by subtracting the median luma delta,
58380
+ * so a shadow that lifts the whole crop leaves no blob. What remains is a
58381
+ * connected region. The package model is not consulted here.
58382
+ */
58247
58383
  /** Residual, after the median shift, that counts as a changed pixel. */
58248
58384
  var PACKAGE_SCENE_DIFF_LUMA_THRESHOLD = 28;
58249
58385
  /** A changed region this large, relative to the zone, is the zone itself. */
@@ -58258,12 +58394,26 @@ var PACKAGE_SCENE_DIFF_SETTLE_MS = 3e3;
58258
58394
  var PACKAGE_SCENE_DIFF_LOOK_GAP_MS = 2e3;
58259
58395
  /** Confidence stamped on a scene-diff sighting the model did not box. */
58260
58396
  var PACKAGE_SCENE_DIFF_CONFIDENCE = .5;
58397
+ /** True when the crop was shot in infrared (no colour). */
58398
+ function isIrCrop(crop) {
58399
+ return crop.chromaSpread < IR_CHROMA_THRESHOLD;
58400
+ }
58261
58401
  function diffZoneLuma(input) {
58262
58402
  const { before, after } = input;
58263
58403
  if (before.width !== after.width || before.height !== after.height || before.luma.length !== after.luma.length) return {
58264
58404
  blobs: [],
58265
58405
  rejections: [{ reason: "crop-mismatch" }]
58266
58406
  };
58407
+ if (isIrCrop(before) !== isIrCrop(after)) return {
58408
+ blobs: [],
58409
+ rejections: [{
58410
+ reason: "lighting-mode-changed",
58411
+ chroma: {
58412
+ before: before.chromaSpread,
58413
+ after: after.chromaSpread
58414
+ }
58415
+ }]
58416
+ };
58267
58417
  const median = medianDelta(before.luma, after.luma);
58268
58418
  const mask = residualMask(before.luma, after.luma, median);
58269
58419
  const zonePx = before.width * before.height;
@@ -58478,6 +58628,7 @@ function okCrop(rgb, width, height, jpeg) {
58478
58628
  width,
58479
58629
  height,
58480
58630
  luma: lumaFromRgb(rgb, width, height),
58631
+ chromaSpread: chromaSpreadFromRgb(rgb, width, height),
58481
58632
  jpeg: new Uint8Array(jpeg)
58482
58633
  };
58483
58634
  }
@@ -58494,6 +58645,46 @@ function lumaFromRgb(bytes, width, height) {
58494
58645
  }
58495
58646
  return luma;
58496
58647
  }
58648
+ /** The grid `IR_CHROMA_THRESHOLD` was calibrated on (`chromaSpread`, scene-crop.ts). */
58649
+ var CHROMA_GRID = 32;
58650
+ /**
58651
+ * Mean of max(r,g,b) - min(r,g,b), 0..255, measured on a 32x32 box-averaged
58652
+ * copy of the crop: the same measure and grid as `chromaSpread` in
58653
+ * `scene-crop.ts` (which needs sharp), so `IR_CHROMA_THRESHOLD` means the same
58654
+ * thing. Averaging first matters: sensor noise and JPEG chroma speckle on an IR
58655
+ * frame cancel out, where per-pixel they read as colour.
58656
+ */
58657
+ function chromaSpreadFromRgb(bytes, width, height) {
58658
+ if (width <= 0 || height <= 0 || bytes.length < width * height * 3) return 0;
58659
+ const gw = Math.min(CHROMA_GRID, width);
58660
+ const gh = Math.min(CHROMA_GRID, height);
58661
+ const sum = new Float64Array(gw * gh * 3);
58662
+ const count = new Float64Array(gw * gh);
58663
+ for (let y = 0; y < height; y++) {
58664
+ const cy = Math.min(gh - 1, Math.floor(y * gh / height));
58665
+ for (let x = 0; x < width; x++) {
58666
+ const cx = Math.min(gw - 1, Math.floor(x * gw / width));
58667
+ const cell = cy * gw + cx;
58668
+ const o = (y * width + x) * 3;
58669
+ sum[cell * 3] = (sum[cell * 3] ?? 0) + (bytes[o] ?? 0);
58670
+ sum[cell * 3 + 1] = (sum[cell * 3 + 1] ?? 0) + (bytes[o + 1] ?? 0);
58671
+ sum[cell * 3 + 2] = (sum[cell * 3 + 2] ?? 0) + (bytes[o + 2] ?? 0);
58672
+ count[cell] = (count[cell] ?? 0) + 1;
58673
+ }
58674
+ }
58675
+ let total = 0;
58676
+ let cells = 0;
58677
+ for (let cell = 0; cell < gw * gh; cell++) {
58678
+ const n = count[cell] ?? 0;
58679
+ if (n === 0) continue;
58680
+ const r = (sum[cell * 3] ?? 0) / n;
58681
+ const g = (sum[cell * 3 + 1] ?? 0) / n;
58682
+ const b = (sum[cell * 3 + 2] ?? 0) / n;
58683
+ total += Math.max(r, g, b) - Math.min(r, g, b);
58684
+ cells += 1;
58685
+ }
58686
+ return cells === 0 ? 0 : total / cells;
58687
+ }
58497
58688
  //#endregion
58498
58689
  //#region src/pipeline-analytics/pipeline/package/package-scene-step.ts
58499
58690
  /**
@@ -58593,6 +58784,14 @@ function compareAfterLeave(prev, input) {
58593
58784
  minAreaFrac: input.minAreaFrac,
58594
58785
  occluders: input.occluders
58595
58786
  });
58787
+ if (diff.rejections.some((r) => r.reason === "lighting-mode-changed")) return {
58788
+ state: {
58789
+ ...rememberClear(prev, input).state,
58790
+ lastDiffAt: input.timestamp
58791
+ },
58792
+ sightings: [],
58793
+ rejections: diff.rejections
58794
+ };
58596
58795
  const blocked = diff.rejections.some((r) => r.reason === "overlaps-person" || r.reason === "overlaps-vehicle");
58597
58796
  if (diff.blobs.length === 0) {
58598
58797
  if (blocked) return {
@@ -58636,6 +58835,20 @@ function confirmPending(prev, input) {
58636
58835
  sightings: [],
58637
58836
  rejections: []
58638
58837
  };
58838
+ if (isIrCrop(prev.after) !== isIrCrop(input.crop)) return {
58839
+ state: {
58840
+ ...rememberClear(prev, input).state,
58841
+ lastDiffAt: input.timestamp
58842
+ },
58843
+ sightings: [],
58844
+ rejections: [{
58845
+ reason: "lighting-mode-changed",
58846
+ chroma: {
58847
+ before: prev.after.chromaSpread,
58848
+ after: input.crop.chromaSpread
58849
+ }
58850
+ }]
58851
+ };
58639
58852
  const sightings = [];
58640
58853
  const rejections = [];
58641
58854
  const still = [];
@@ -58682,7 +58895,7 @@ function judgeBlob(prev, input, blob) {
58682
58895
  bbox: blob.bbox
58683
58896
  } };
58684
58897
  const stable = meanAbsInBox(after, crop, blob.bbox) <= PACKAGE_SCENE_DIFF_STABLE_MEAN;
58685
- const present = meanAbsInBox(before, crop, blob.bbox) >= PACKAGE_SCENE_DIFF_LUMA_THRESHOLD;
58898
+ const present = isIrCrop(before) !== isIrCrop(crop) || meanAbsInBox(before, crop, blob.bbox) >= PACKAGE_SCENE_DIFF_LUMA_THRESHOLD;
58686
58899
  if (!stable || !present) return { rejection: {
58687
58900
  reason: "unstable",
58688
58901
  bbox: blob.bbox,
@@ -58850,7 +59063,8 @@ var PackageSceneCoordinator = class {
58850
59063
  const crop = {
58851
59064
  width: fetched.width,
58852
59065
  height: fetched.height,
58853
- luma: fetched.luma
59066
+ luma: fetched.luma,
59067
+ chromaSpread: fetched.chromaSpread
58854
59068
  };
58855
59069
  const stepped = stepPackageScene({
58856
59070
  deviceId,
@@ -58916,6 +59130,10 @@ var PackageSceneCoordinator = class {
58916
59130
  tags: { deviceId },
58917
59131
  meta: {
58918
59132
  reason: rejection.reason,
59133
+ ...rejection.chroma !== void 0 ? {
59134
+ chromaBefore: Number(rejection.chroma.before.toFixed(2)),
59135
+ chromaAfter: Number(rejection.chroma.after.toFixed(2))
59136
+ } : {},
58919
59137
  ...rejection.areaFrac !== void 0 ? { areaFrac: Number(rejection.areaFrac.toFixed(5)) } : {}
58920
59138
  }
58921
59139
  });
@@ -59024,14 +59242,8 @@ function planPackageSceneFrame(deviceId, input) {
59024
59242
  frameWidth: input.frameWidth,
59025
59243
  frameHeight: input.frameHeight
59026
59244
  });
59027
- const sceneRect = sceneZones.size === 0 ? null : packageZoneCropRect({
59028
- zones: input.zones,
59029
- packageZoneIds: sceneZones,
59030
- frameWidth: input.frameWidth,
59031
- frameHeight: input.frameHeight
59032
- });
59033
59245
  return {
59034
- sightings: sceneRect === null ? input.sightings : withoutSceneCenters(input, sceneRect),
59246
+ sightings: input.sightings,
59035
59247
  note: {
59036
59248
  deviceId,
59037
59249
  timestamp: input.timestamp,
@@ -59074,15 +59286,6 @@ function occludersOf(tracked) {
59074
59286
  }
59075
59287
  return out;
59076
59288
  }
59077
- function withoutSceneCenters(input, rect) {
59078
- if (input.frameWidth <= 0 || input.frameHeight <= 0) return input.sightings;
59079
- return input.sightings.filter((sighting) => !centerInside(sighting.bbox, rect, input));
59080
- }
59081
- function centerInside(bbox, rect, input) {
59082
- const cx = (bbox.x + bbox.w / 2) / input.frameWidth;
59083
- const cy = (bbox.y + bbox.h / 2) / input.frameHeight;
59084
- return cx >= rect.x && cx < rect.x + rect.w && cy >= rect.y && cy < rect.y + rect.h;
59085
- }
59086
59289
  //#endregion
59087
59290
  //#region src/pipeline-analytics/pipeline/package/package-llm-confirm.ts
59088
59291
  /**
@@ -59243,56 +59446,143 @@ function sweepOne(deps, deviceId) {
59243
59446
  }
59244
59447
  //#endregion
59245
59448
  //#region src/pipeline-analytics/pipeline/package/package-still-capture.ts
59246
- /** A held look frame older than this is not the parcel's picture any more. */
59247
- var PACKAGE_LOOK_FRAME_MAX_AGE_MS = 15e3;
59449
+ /**
59450
+ * The runner's native lease on a look frame (holdFrames 8) is released about
59451
+ * 100 ms after inference, so a handle older than this answers `native-miss` or
59452
+ * `preview-only` — promotion runs seconds to minutes after the look (D60).
59453
+ */
59454
+ var PACKAGE_NATIVE_HANDLE_MAX_AGE_MS = 1e3;
59455
+ /** Total time a promotion may spend landing its still before it ships without (D60). */
59456
+ var PACKAGE_STILL_BOUND_MS = 6e3;
59457
+ /** One live-source attempt never takes longer than this (a sleeping camera). */
59458
+ var PACKAGE_STILL_ATTEMPT_TIMEOUT_MS = 3e3;
59459
+ /** Pause between two live attempts. */
59460
+ var PACKAGE_STILL_RETRY_PAUSE_MS = 750;
59461
+ var PACKAGE_STILL_LIVE_ATTEMPTS = 3;
59462
+ var realPause = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
59248
59463
  async function jpegOf(reply) {
59249
59464
  if (reply.tier === "ram-fullframe") return "preview-only";
59250
59465
  if (reply.jpegBytes !== void 0 && reply.jpegBytes.byteLength > 0) return reply.jpegBytes;
59251
59466
  if (reply.bytes !== void 0 && reply.bytes.length === reply.width * reply.height * 3) return encodeRgbCropToJpeg(reply.bytes, reply.width, reply.height);
59252
59467
  return "empty-frame";
59253
59468
  }
59469
+ /** One live read, cut off after `limitMs` so a hung camera cannot hold the delivery. */
59470
+ async function readLive(source, limitMs) {
59471
+ let timer;
59472
+ const timeout = new Promise((resolve) => {
59473
+ timer = setTimeout(() => resolve(null), limitMs);
59474
+ });
59475
+ try {
59476
+ return await Promise.race([source(), timeout]);
59477
+ } finally {
59478
+ if (timer !== void 0) clearTimeout(timer);
59479
+ }
59480
+ }
59481
+ /** Retry the live source under {@link PACKAGE_STILL_BOUND_MS} until a frame lands (D60). */
59482
+ async function liveStill(input, source) {
59483
+ const now = input.now ?? Date.now;
59484
+ const pause = input.pause ?? realPause;
59485
+ const deadline = now() + PACKAGE_STILL_BOUND_MS;
59486
+ let reason = "live-unavailable";
59487
+ let attempts = 0;
59488
+ while (attempts < PACKAGE_STILL_LIVE_ATTEMPTS) {
59489
+ const remaining = deadline - now();
59490
+ if (remaining <= 0) return {
59491
+ jpeg: null,
59492
+ reason: "bound-exhausted",
59493
+ attempts
59494
+ };
59495
+ attempts += 1;
59496
+ try {
59497
+ const jpeg = await readLive(source, Math.min(PACKAGE_STILL_ATTEMPT_TIMEOUT_MS, remaining));
59498
+ if (jpeg !== null && jpeg.byteLength > 0) return {
59499
+ jpeg,
59500
+ reason,
59501
+ attempts
59502
+ };
59503
+ reason = jpeg === null ? "live-unavailable" : "empty-frame";
59504
+ } catch {
59505
+ reason = "live-unavailable";
59506
+ }
59507
+ if (attempts < PACKAGE_STILL_LIVE_ATTEMPTS) await pause(PACKAGE_STILL_RETRY_PAUSE_MS);
59508
+ }
59509
+ return {
59510
+ jpeg: null,
59511
+ reason,
59512
+ attempts
59513
+ };
59514
+ }
59254
59515
  /**
59255
59516
  * The entry carrying its still's `keyFrameMediaId`, or the entry unchanged when
59256
59517
  * it already had one or none could be stored (said, with the reason).
59518
+ *
59519
+ * Ladder: the native handle while its lease can still be alive, then a frame
59520
+ * that exists now (retried under a bound). Every landed still is logged next to
59521
+ * every miss (D400).
59257
59522
  */
59258
59523
  async function withParcelStill(input) {
59259
59524
  const { entry, logger } = input;
59260
59525
  if (entry.keyFrameMediaId !== void 0) return entry;
59261
- const miss = (reason, detail) => {
59526
+ const tags = { deviceId: entry.deviceId };
59527
+ const miss = (reason, extra = {}) => {
59262
59528
  logger.warn("package still NOT stored — the delivery ships without a picture of the parcel", {
59263
- tags: { deviceId: entry.deviceId },
59529
+ tags,
59264
59530
  meta: {
59265
59531
  entryId: entry.id,
59266
59532
  reason,
59267
- ...detail !== void 0 ? { error: detail } : {}
59533
+ ...extra
59268
59534
  }
59269
59535
  });
59270
59536
  return entry;
59271
59537
  };
59272
- if (input.handle === null) return miss("no-frame-handle");
59273
59538
  if (input.writer === null) return miss("no-media-store");
59539
+ const now = input.now ?? Date.now;
59540
+ let jpeg = null;
59541
+ let source = "native";
59542
+ let stamp = input.timestamp;
59543
+ let nativeMiss = "no-frame-handle";
59544
+ let liveReason = null;
59545
+ let attempts = 0;
59274
59546
  try {
59275
- const reply = await input.query({
59276
- handle: input.handle,
59277
- bbox: {
59278
- x: 0,
59279
- y: 0,
59280
- w: entry.frameWidth,
59281
- h: entry.frameHeight
59282
- },
59283
- acceptJpegBytes: true,
59284
- encodeJpeg: true,
59285
- pin: nodePin(input.handle.nodeId)
59547
+ if (input.handle !== null) {
59548
+ const reply = await input.query({
59549
+ handle: input.handle,
59550
+ bbox: {
59551
+ x: 0,
59552
+ y: 0,
59553
+ w: entry.frameWidth,
59554
+ h: entry.frameHeight
59555
+ },
59556
+ acceptJpegBytes: true,
59557
+ encodeJpeg: true,
59558
+ pin: nodePin(input.handle.nodeId)
59559
+ });
59560
+ if (reply === null) nativeMiss = "native-miss";
59561
+ else {
59562
+ const out = await jpegOf(reply);
59563
+ if (typeof out === "string") nativeMiss = out;
59564
+ else jpeg = out;
59565
+ }
59566
+ }
59567
+ if (jpeg === null && input.live !== null) {
59568
+ const live = await liveStill(input, input.live);
59569
+ attempts = live.attempts;
59570
+ if (live.jpeg !== null) {
59571
+ jpeg = live.jpeg;
59572
+ source = "live";
59573
+ stamp = now();
59574
+ } else liveReason = live.reason;
59575
+ }
59576
+ if (jpeg === null) return miss(liveReason ?? nativeMiss, {
59577
+ ...input.handle !== null ? { nativeMiss } : {},
59578
+ ...liveReason !== null ? { liveAttempts: attempts } : {}
59286
59579
  });
59287
- if (reply === null) return miss("native-miss");
59288
- const jpeg = await jpegOf(reply);
59289
- if (typeof jpeg === "string") return miss(jpeg);
59290
59580
  const keyFrameMediaId = await input.writer.putReplacing({
59291
59581
  deviceId: entry.deviceId,
59292
59582
  ownerKind: "track",
59293
59583
  ownerId: entry.id,
59294
59584
  kind: "keyFrame",
59295
- timestamp: input.timestamp,
59585
+ timestamp: stamp,
59296
59586
  data: Buffer.from(jpeg),
59297
59587
  subjectBox: {
59298
59588
  x: entry.bbox.x,
@@ -59303,12 +59593,20 @@ async function withParcelStill(input) {
59303
59593
  frameHeight: entry.frameHeight
59304
59594
  }
59305
59595
  });
59596
+ logger.info("package still stored", {
59597
+ tags,
59598
+ meta: {
59599
+ entryId: entry.id,
59600
+ mediaId: keyFrameMediaId,
59601
+ source
59602
+ }
59603
+ });
59306
59604
  return {
59307
59605
  ...entry,
59308
59606
  keyFrameMediaId
59309
59607
  };
59310
59608
  } catch (err) {
59311
- return miss("write-failed", errMsg(err));
59609
+ return miss("write-failed", { error: errMsg(err) });
59312
59610
  }
59313
59611
  }
59314
59612
  /**
@@ -70967,6 +71265,7 @@ Object.freeze({
70967
71265
  "addon-pages-source": ["listPages"],
70968
71266
  "addon-routes": ["getRoutes"],
70969
71267
  "addon-widgets-source": ["listWidgets"],
71268
+ "board-key-source": ["listSources"],
70970
71269
  "broker": ["list", "listProviders"],
70971
71270
  "calendar-source": ["listCalendars", "listEvents"],
70972
71271
  "custom-model-registry": ["listModels"],
@@ -72495,7 +72794,7 @@ function buildGlobalSettingsSchema(cap) {
72495
72794
  type: "slider",
72496
72795
  key: "packageDropActivityWindowSec",
72497
72796
  label: "Deliverer window",
72498
- description: "A delivery only counts if a person or vehicle was in the configured package drop-off zone within this many seconds before the package appeared — and a pick-up only with somebody in that zone when it vanished. Motion elsewhere on the camera does not count. 0 disables the requirement.",
72797
+ description: "A delivery only counts if a person or vehicle was in the configured package drop-off zone within this many seconds before the package appeared — and a pick-up only with somebody in that zone when it vanished. Person-sized motion beside the drop-off zone also counts when nobody was tracked. Motion elsewhere on the camera does not count. 0 disables the requirement.",
72499
72798
  min: 0,
72500
72799
  max: 1800,
72501
72800
  step: 30,
@@ -87015,6 +87314,13 @@ var NC_STILL_WAIT_MAX_AGE_MS = 3e4;
87015
87314
  function canStillGainMedia(entry) {
87016
87315
  return entry.recordKind === "object-event";
87017
87316
  }
87317
+ /** The variables that carry a finished cycle's run summary. */
87318
+ var CYCLE_SUMMARY_VARS = [
87319
+ "duration",
87320
+ "energy",
87321
+ "afterDuration",
87322
+ "usedEnergy"
87323
+ ];
87018
87324
  var NcDispatcher = class {
87019
87325
  deps;
87020
87326
  targetCache = null;
@@ -87918,6 +88224,7 @@ var NcDispatcher = class {
87918
88224
  }
87919
88225
  /** Rules already warned about a deprecated variable in this process — once each. */
87920
88226
  deprecatedVarWarned = /* @__PURE__ */ new Set();
88227
+ cycleSummaryWarned = /* @__PURE__ */ new Set();
87921
88228
  /**
87922
88229
  * A rule template written by an older client may still say `{{camera}}`. It
87923
88230
  * renders (the alias), and the rule is named once so the operator can edit it.
@@ -87937,6 +88244,27 @@ var NcDispatcher = class {
87937
88244
  });
87938
88245
  }
87939
88246
  /**
88247
+ * A FINISHED-cycle row whose own template places none of the four cycle
88248
+ * variables delivers no run summary (D391: accepted, produced less). Said
88249
+ * once per rule; the operator's text is never touched.
88250
+ */
88251
+ warnCycleSummaryDropped(entry) {
88252
+ const deviceId = entry.payload.subject.applianceCycle?.deviceId;
88253
+ const template = entry.payload.template;
88254
+ if (deviceId === void 0 || template === void 0) return;
88255
+ if (this.cycleSummaryWarned.has(entry.ruleId)) return;
88256
+ const used = new Set([...templatePlaceholders(template.title ?? ""), ...templatePlaceholders(template.body ?? "")]);
88257
+ if (CYCLE_SUMMARY_VARS.some((name) => used.has(name))) return;
88258
+ this.cycleSummaryWarned.add(entry.ruleId);
88259
+ this.deps.logger.warn("appliance cycle finished but the rule template places no run summary — the message carries no duration or energy", {
88260
+ tags: {
88261
+ deviceId,
88262
+ ruleId: entry.ruleId
88263
+ },
88264
+ meta: { placeholders: [...CYCLE_SUMMARY_VARS] }
88265
+ });
88266
+ }
88267
+ /**
87940
88268
  * The facts of a finished appliance cycle; unknown on every other row and on
87941
88269
  * any failure (a part that cannot be read is omitted, never a blocked send).
87942
88270
  */
@@ -87981,6 +88309,7 @@ var NcDispatcher = class {
87981
88309
  const cycleFacts = await this.applianceCycleFacts(entry);
87982
88310
  const vars = buildTemplateVars(this.texts, entry, deviceName, zoneLabels, void 0, cycleFacts);
87983
88311
  this.warnDeprecatedVars(entry);
88312
+ this.warnCycleSummaryDropped(entry);
87984
88313
  const systemCount = systemEvent?.textCount !== void 0 ? { count: systemEvent.textCount } : {};
87985
88314
  const title = renderRowTitle(this.texts, entry, vars);
87986
88315
  const authoredBody = entry.payload.template?.body;
@@ -101963,7 +102292,10 @@ function buildProvider(host) {
101963
102292
  catalog: [...NC_CONDITION_CATALOG],
101964
102293
  taxonomy: NC_TAXONOMY
101965
102294
  }),
101966
- getTemplateCatalog: async () => ({ vars: servedTemplateVars() }),
102295
+ getTemplateCatalog: async () => ({
102296
+ vars: servedTemplateVars(),
102297
+ defaults: servedTemplateDefaults(host.texts)
102298
+ }),
101967
102299
  previewTemplate: async (input) => previewTemplate(host.texts, input),
101968
102300
  getHistory: async ({ filter }) => {
101969
102301
  const entries = await host.outbox.queryHistory({
@@ -124900,6 +125232,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
124900
125232
  this.packageDropDetector?.forgetDevice(data.deviceId);
124901
125233
  this.packageScene?.forget(data.deviceId);
124902
125234
  this.frameState.lastNonPackageActivityAt.delete(data.deviceId);
125235
+ this.frameState.lastPackageZoneMotionAt.delete(data.deviceId);
124903
125236
  this.frameState.packageCollectors.forgetDevice(data.deviceId);
124904
125237
  this.frameState.packageOversizeLogAt.delete(data.deviceId);
124905
125238
  this.frameState.packageLookFrames.delete(data.deviceId);
@@ -124924,6 +125257,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
124924
125257
  this.packageDropDetector?.forgetDevice(deviceId);
124925
125258
  this.packageScene?.forget(deviceId);
124926
125259
  this.frameState.lastNonPackageActivityAt.delete(deviceId);
125260
+ this.frameState.lastPackageZoneMotionAt.delete(deviceId);
124927
125261
  this.frameState.packageCollectors.forgetDevice(deviceId);
124928
125262
  this.frameState.packageOversizeLogAt.delete(deviceId);
124929
125263
  this.frameState.packageLookFrames.delete(deviceId);
@@ -127496,6 +127830,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
127496
127830
  detected,
127497
127831
  atMs: timestamp
127498
127832
  });
127833
+ if (detected) await this.stampPackageZoneMotion(deviceId, payload, timestamp);
127499
127834
  if (detected) this.eventStore?.noteMotionSample(deviceId, payload.regionCount, timestamp);
127500
127835
  await this.motionEpisodes?.observe(deviceId, "analyzer", detected, timestamp, {
127501
127836
  regionCount: payload.regionCount,
@@ -127514,6 +127849,28 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
127514
127849
  });
127515
127850
  }
127516
127851
  /**
127852
+ * Stamp analyzer motion that reached a package drop-off zone (D1003): the
127853
+ * courier who never became an L1 track still backs the OPEN of a candidate.
127854
+ * Onboard motion carries no regions or dimensions and never stamps.
127855
+ */
127856
+ async stampPackageZoneMotion(deviceId, payload, timestamp) {
127857
+ const proxy = await this.ensureProxy(deviceId);
127858
+ const packageZoneIds = collectPackageZoneIds(proxy?.state.zoneRules.value?.package ?? []);
127859
+ if (packageZoneIds.size === 0) return;
127860
+ const zoneRect = packageZoneCropRect({
127861
+ zones: proxy?.state.zones.value?.zones ?? [],
127862
+ packageZoneIds,
127863
+ frameWidth: payload.frameWidth,
127864
+ frameHeight: payload.frameHeight
127865
+ });
127866
+ if (delivererMotionNearPackageZone({
127867
+ regions: payload.regions,
127868
+ frameWidth: payload.frameWidth,
127869
+ frameHeight: payload.frameHeight,
127870
+ zoneRect
127871
+ })) this.frameState.lastPackageZoneMotionAt.set(deviceId, timestamp);
127872
+ }
127873
+ /**
127517
127874
  * Persist firmware-driven (onboard / device-activity) motion events into
127518
127875
  * the SAME episode tracker as {@link handleMotionAnalysis}, keyed per
127519
127876
  * `(deviceId, source)` so the two paths can never share — or fight over —
@@ -127846,6 +128203,10 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
127846
128203
  encodeJpeg: request.encodeJpeg
127847
128204
  }, request.pin);
127848
128205
  }
128206
+ zoneMotionStamp(deviceId) {
128207
+ const at = this.frameState.lastPackageZoneMotionAt.get(deviceId);
128208
+ return at === void 0 ? {} : { lastDelivererMotionAt: at };
128209
+ }
127849
128210
  deliverPackageSceneSightings(delivery) {
127850
128211
  const settings = this.packageDropSettingsFromCache(delivery.deviceId);
127851
128212
  const lastActivityAt = this.frameState.lastNonPackageActivityAt.get(delivery.deviceId);
@@ -127859,6 +128220,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
127859
128220
  minDwellMs: settings.packageDropDwellSec * 1e3,
127860
128221
  activityWindowMs: settings.packageDropActivityWindowSec * 1e3,
127861
128222
  ...lastActivityAt !== void 0 ? { lastActivityAt } : {},
128223
+ ...this.zoneMotionStamp(delivery.deviceId),
127862
128224
  looked: false
127863
128225
  });
127864
128226
  this.bridgePackageStillness({
@@ -128044,6 +128406,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
128044
128406
  minDwellMs: input.settings.packageDropDwellSec * 1e3,
128045
128407
  activityWindowMs: input.settings.packageDropActivityWindowSec * 1e3,
128046
128408
  ...lastActivityAt !== void 0 ? { lastActivityAt } : {},
128409
+ ...this.zoneMotionStamp(input.deviceId),
128047
128410
  ...lookEvidence
128048
128411
  });
128049
128412
  this.bridgePackageStillness({
@@ -128149,11 +128512,15 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
128149
128512
  const lookFrame = this.frameState.packageLookFrames.get(input.deviceId);
128150
128513
  promoteWithStill({
128151
128514
  entry,
128152
- handle: lookFrame !== void 0 && input.timestamp - lookFrame.at <= PACKAGE_LOOK_FRAME_MAX_AGE_MS ? lookFrame.handle : null,
128515
+ handle: lookFrame !== void 0 && input.timestamp - lookFrame.at <= PACKAGE_NATIVE_HANDLE_MAX_AGE_MS ? lookFrame.handle : null,
128153
128516
  timestamp: lookFrame?.at ?? input.timestamp,
128154
128517
  query: (request) => this.queryPackageSceneCrop(request),
128155
128518
  writer: this.mediaStore,
128156
128519
  logger: this.ctx.logger,
128520
+ live: async () => {
128521
+ const snap = await this.ctx.api.snapshot.getSnapshot.query({ deviceId: input.deviceId });
128522
+ return snap === null ? null : Uint8Array.from(Buffer.from(snap.base64, "base64"));
128523
+ },
128157
128524
  detector: this.packageDropDetector
128158
128525
  }).catch((err) => {
128159
128526
  this.ctx.logger.warn("package promotion failed", {
@@ -128235,6 +128602,15 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
128235
128602
  });
128236
128603
  }).catch(() => void 0);
128237
128604
  }
128605
+ for (const c of outcome.continued) this.ctx.logger.info("package candidate continued by a sub-floor box", {
128606
+ tags,
128607
+ meta: {
128608
+ entryId: c.id,
128609
+ hits: c.hits,
128610
+ score: c.score,
128611
+ via: input.via
128612
+ }
128613
+ });
128238
128614
  for (const u of outcome.earlyEvidenceUnbacked) this.ctx.logger.info("early pick-up evidence complete — nobody around, left to the TTL", {
128239
128615
  tags,
128240
128616
  meta: {
@@ -128262,6 +128638,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
128262
128638
  observedDwellMs,
128263
128639
  requiredDwellMs,
128264
128640
  activityBackedAtOpen: ex.activityBackedAtOpen,
128641
+ lastZoneMotionAt: this.frameState.lastPackageZoneMotionAt.get(input.deviceId) ?? null,
128265
128642
  reasons
128266
128643
  }
128267
128644
  });