@camstack/addon-smtp-nodemailer 1.2.22 → 1.2.23

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.
@@ -7587,7 +7587,7 @@ var RecordingBandSchema = object({
7587
7587
  postBufferSec: number().min(0).optional()
7588
7588
  });
7589
7589
  ({
7590
- preBufferSec: 10,
7590
+ preBufferSec: 15,
7591
7591
  postBufferSec: 30
7592
7592
  }).postBufferSec * 1e3;
7593
7593
  /**
@@ -13526,128 +13526,103 @@ var COCO_TO_MACRO = {
13526
13526
  var AUDIO_MACRO_LABELS = [
13527
13527
  {
13528
13528
  id: "speech",
13529
- name: "Speech",
13530
- icon: "🗣️"
13529
+ name: "Speech"
13531
13530
  },
13532
13531
  {
13533
13532
  id: "scream",
13534
- name: "Scream / Shout",
13535
- icon: "😱"
13533
+ name: "Scream / Shout"
13536
13534
  },
13537
13535
  {
13538
13536
  id: "crying",
13539
- name: "Crying / Baby",
13540
- icon: "😢"
13537
+ name: "Crying / Baby"
13541
13538
  },
13542
13539
  {
13543
13540
  id: "laughter",
13544
- name: "Laughter",
13545
- icon: "😂"
13541
+ name: "Laughter"
13546
13542
  },
13547
13543
  {
13548
13544
  id: "music",
13549
- name: "Music",
13550
- icon: "🎵"
13545
+ name: "Music"
13551
13546
  },
13552
13547
  {
13553
13548
  id: "dog",
13554
- name: "Dog",
13555
- icon: "🐕"
13549
+ name: "Dog"
13556
13550
  },
13557
13551
  {
13558
13552
  id: "cat",
13559
- name: "Cat",
13560
- icon: "🐈"
13553
+ name: "Cat"
13561
13554
  },
13562
13555
  {
13563
13556
  id: "bird",
13564
- name: "Bird",
13565
- icon: "🐦"
13557
+ name: "Bird"
13566
13558
  },
13567
13559
  {
13568
13560
  id: "animal",
13569
- name: "Animal (other)",
13570
- icon: "🐾"
13561
+ name: "Animal (other)"
13571
13562
  },
13572
13563
  {
13573
13564
  id: "alarm",
13574
- name: "Alarm / Siren",
13575
- icon: "🚨"
13565
+ name: "Alarm / Siren"
13576
13566
  },
13577
13567
  {
13578
13568
  id: "doorbell",
13579
- name: "Doorbell / Knock",
13580
- icon: "🔔"
13569
+ name: "Doorbell / Knock"
13581
13570
  },
13582
13571
  {
13583
13572
  id: "glass_breaking",
13584
- name: "Glass Breaking",
13585
- icon: "💥"
13573
+ name: "Glass Breaking"
13586
13574
  },
13587
13575
  {
13588
13576
  id: "gunshot",
13589
- name: "Gunshot / Explosion",
13590
- icon: "💣"
13577
+ name: "Gunshot / Explosion"
13591
13578
  },
13592
13579
  {
13593
13580
  id: "vehicle",
13594
- name: "Vehicle",
13595
- icon: "🚗"
13581
+ name: "Vehicle"
13596
13582
  },
13597
13583
  {
13598
13584
  id: "siren",
13599
- name: "Emergency Siren",
13600
- icon: "🚑"
13585
+ name: "Emergency Siren"
13601
13586
  },
13602
13587
  {
13603
13588
  id: "fire",
13604
- name: "Fire / Smoke",
13605
- icon: "🔥"
13589
+ name: "Fire / Smoke"
13606
13590
  },
13607
13591
  {
13608
13592
  id: "water",
13609
- name: "Water",
13610
- icon: "💧"
13593
+ name: "Water"
13611
13594
  },
13612
13595
  {
13613
13596
  id: "wind",
13614
- name: "Wind / Weather",
13615
- icon: "🌬️"
13597
+ name: "Wind / Weather"
13616
13598
  },
13617
13599
  {
13618
13600
  id: "door",
13619
- name: "Door",
13620
- icon: "🚪"
13601
+ name: "Door"
13621
13602
  },
13622
13603
  {
13623
13604
  id: "footsteps",
13624
- name: "Footsteps",
13625
- icon: "👣"
13605
+ name: "Footsteps"
13626
13606
  },
13627
13607
  {
13628
13608
  id: "crowd",
13629
- name: "Crowd / Chatter",
13630
- icon: "👥"
13609
+ name: "Crowd / Chatter"
13631
13610
  },
13632
13611
  {
13633
13612
  id: "telephone",
13634
- name: "Telephone",
13635
- icon: "📞"
13613
+ name: "Telephone"
13636
13614
  },
13637
13615
  {
13638
13616
  id: "engine",
13639
- name: "Engine / Motor",
13640
- icon: "⚙️"
13617
+ name: "Engine / Motor"
13641
13618
  },
13642
13619
  {
13643
13620
  id: "tools",
13644
- name: "Tools / Construction",
13645
- icon: "🔨"
13621
+ name: "Tools / Construction"
13646
13622
  },
13647
13623
  {
13648
13624
  id: "silence",
13649
- name: "Silence",
13650
- icon: "🤫"
13625
+ name: "Silence"
13651
13626
  }
13652
13627
  ];
13653
13628
  var YAMNET_TO_MACRO = {
@@ -16111,7 +16086,7 @@ var TrackEnvelopeSchema = object({
16111
16086
  * `snapshots[]` references — megabytes across a page of tracks. `slim`
16112
16087
  * keeps every scalar the list surfaces actually render (ids, class(es),
16113
16088
  * label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
16114
- * zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
16089
+ * zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
16115
16090
  * `snapshots` as EMPTY arrays — detail views re-fetch the full row via
16116
16091
  * `getTrack`. Mirrors the event-store `projection` convention
16117
16092
  * (`getObjectEvents` et al.).
@@ -16406,6 +16381,35 @@ var TrackSchema = object({
16406
16381
  */
16407
16382
  hasFace: boolean().optional(),
16408
16383
  /**
16384
+ * This track has a face row IN THE GALLERY: a crop **and** an embedding — a
16385
+ * face an operator could ASSIGN to an identity.
16386
+ *
16387
+ * The STRICT twin of {@link hasFace}, and the pair only earns its keep
16388
+ * because the two disagree. `hasFace` is stamped at the TOP of the face
16389
+ * branch, before every gate, and means no more than "a face detector produced
16390
+ * a face detail". This one is stamped at the single moment the gallery row
16391
+ * LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
16392
+ * past the embedding-magnitude verdict, the `minFacePx` detection gate, the
16393
+ * candidate gate, the imageless-track drop (no crop was ever captured) and
16394
+ * the crop-store drop. Everything between the detector and that insert can
16395
+ * legitimately refuse the face, so a flag written any earlier promises the
16396
+ * operator something to assign and delivers nothing.
16397
+ *
16398
+ * **Independent of recognition.** A face collected but never auto-matched is
16399
+ * still assignable — it is in fact the face an operator most wants to reach —
16400
+ * so this is NOT gated on `recognizedIdentityId`. Recognition lands in
16401
+ * `subLabel`; this says only that the raw material exists.
16402
+ *
16403
+ * **Set once, never cleared.** A track that produced a gallery row produced
16404
+ * one; deleting the row later is the gallery's business, not this flag's.
16405
+ *
16406
+ * **Absent ≠ false**, the same rule as {@link hasFace}: every row written
16407
+ * before the column omits it, and so does every server that predates the
16408
+ * field. A consumer must test `=== true` and render nothing otherwise —
16409
+ * never infer "no assignable face".
16410
+ */
16411
+ hasEmbeddedFace: boolean().optional(),
16412
+ /**
16409
16413
  * This subject CONTAINS a folded rider — a person the rider-pairing step
16410
16414
  * ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
16411
16415
  * so the passage is tracked once and as a VEHICLE.
@@ -17755,6 +17759,32 @@ var DetailResultSchema = object({
17755
17759
  /** FRAME-space bbox (already mapped back from crop space). */
17756
17760
  bbox: NativeCropBboxSchema.optional(),
17757
17761
  embedding: string().optional(),
17762
+ /**
17763
+ * L2 magnitude of the RAW pre-normalization embedding. Additive and optional
17764
+ * so an older runner that does not send it degrades to "unmeasurable", which
17765
+ * the consuming gate treats as accept — never as reject.
17766
+ */
17767
+ embeddingMagnitude: number().optional(),
17768
+ /**
17769
+ * Model that produced `embedding` — the SAME contract `labelModelId` has for
17770
+ * `label`, and for the same reason: the producing node is the only side that
17771
+ * knows which model actually ran, and re-deriving it downstream is exactly
17772
+ * the inference this model exists to forbid.
17773
+ *
17774
+ * Additive and optional, so a runner that predates it degrades to
17775
+ * "unmeasurable" rather than to a wrong answer — the consumer falls back to
17776
+ * its previous assumption instead of refusing.
17777
+ *
17778
+ * Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
17779
+ * to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
17780
+ * with nothing on the wire it took the id from the GALLERY, so the gate
17781
+ * compared the gallery against itself and could never fire. That turned the
17782
+ * one guard protecting the face feature space into a tautology, and it is
17783
+ * why swapping `face-embedding`'s model would NOT have stranded the enrolled
17784
+ * gallery as the catalog comment predicts — it would have scored the new
17785
+ * model's vectors against the old model's samples in one cosine space.
17786
+ */
17787
+ embeddingModelId: string().optional(),
17758
17788
  label: string().optional(),
17759
17789
  /**
17760
17790
  * The tier `label` occupies, copied VERBATIM from the producing step's
@@ -19178,6 +19208,7 @@ DeviceType.Camera, method(object({
19178
19208
  isBattery: boolean(),
19179
19209
  reason: _enum([
19180
19210
  "disabled",
19211
+ "offline",
19181
19212
  "sleeping",
19182
19213
  "unreachable",
19183
19214
  "waking"
@@ -19223,9 +19254,17 @@ targets: array(object({
19223
19254
  sleeping: boolean(),
19224
19255
  /** Current device state rendered over the cached frame. State images
19225
19256
  * remain authoritative even when their photographic background is
19226
- * old; null means the link must carry a current camera frame. */
19257
+ * old; null means the link must carry a current camera frame.
19258
+ *
19259
+ * **This is the ONLY source a surface may derive an inactive tile
19260
+ * from.** A client that reads a device's `online`/`disabled` flags and
19261
+ * draws its own verdict will disagree with the pixels it is painting
19262
+ * — the frame comes from here, and so must the sentence over it
19263
+ * (D190). Pair with `ageMs` for the age of the photograph behind the
19264
+ * state. */
19227
19265
  stateReason: _enum([
19228
19266
  "disabled",
19267
+ "offline",
19229
19268
  "sleeping",
19230
19269
  "unreachable",
19231
19270
  "waking"
@@ -33411,7 +33450,6 @@ var NC_AUDIO_DEFAULTS = {
33411
33450
  hitPercent: 60,
33412
33451
  samplingSeconds: 10
33413
33452
  };
33414
- new Map(AUDIO_MACRO_LABELS.flatMap((macro) => macro.icon === void 0 ? [] : [[macro.id, macro.icon]]));
33415
33453
  new Set(["devices", "classes"]);
33416
33454
  NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
33417
33455
  /**
@@ -33645,6 +33683,39 @@ TimelapseRuleInputSchema.extend({
33645
33683
  createdAt: number(),
33646
33684
  updatedAt: number()
33647
33685
  });
33686
+ Object.freeze(Object.fromEntries([{
33687
+ stepId: "face-embedding",
33688
+ label: "Face recognition model",
33689
+ defaultModelId: "arcface-r100",
33690
+ indexName: "the enrolled face gallery",
33691
+ options: [
33692
+ {
33693
+ id: "arcface-r100",
33694
+ label: "ArcFace (ResNet34)"
33695
+ },
33696
+ {
33697
+ id: "auraface-r100",
33698
+ label: "AuraFace R100"
33699
+ },
33700
+ {
33701
+ id: "inception-resnet-v1",
33702
+ label: "Inception ResNet V1"
33703
+ }
33704
+ ]
33705
+ }, {
33706
+ stepId: "clip-embedding",
33707
+ label: "Semantic search model",
33708
+ defaultModelId: "mobileclip-s1",
33709
+ indexName: "the object semantic-search index",
33710
+ options: [{
33711
+ id: "mobileclip-s1",
33712
+ label: "MobileCLIP S1"
33713
+ }, {
33714
+ id: "mobileclip-s2",
33715
+ label: "MobileCLIP S2"
33716
+ }]
33717
+ }].map((s) => [s.stepId, s.defaultModelId])));
33718
+ string().min(1);
33648
33719
  object({
33649
33720
  /**
33650
33721
  * Fraction of the box's own size added on EACH side before cutting.
@@ -33665,10 +33736,21 @@ object({
33665
33736
  */
33666
33737
  square: boolean()
33667
33738
  });
33668
- ({
33739
+ /**
33740
+ * The convention in force when nobody has configured one — byte-for-byte the
33741
+ * behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
33742
+ */
33743
+ var DEFAULT_DETAIL_CROP_CONVENTION = {
33669
33744
  paddingRatio: .15,
33670
33745
  square: false
33671
- }).paddingRatio;
33746
+ };
33747
+ Object.freeze({
33748
+ x: 0,
33749
+ y: 0,
33750
+ w: 1,
33751
+ h: 1
33752
+ });
33753
+ DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
33672
33754
  /**
33673
33755
  * WHICH delivered frames the decode worker retains a native copy of.
33674
33756
  *
@@ -7585,7 +7585,7 @@ var RecordingBandSchema = object({
7585
7585
  postBufferSec: number().min(0).optional()
7586
7586
  });
7587
7587
  ({
7588
- preBufferSec: 10,
7588
+ preBufferSec: 15,
7589
7589
  postBufferSec: 30
7590
7590
  }).postBufferSec * 1e3;
7591
7591
  /**
@@ -13524,128 +13524,103 @@ var COCO_TO_MACRO = {
13524
13524
  var AUDIO_MACRO_LABELS = [
13525
13525
  {
13526
13526
  id: "speech",
13527
- name: "Speech",
13528
- icon: "🗣️"
13527
+ name: "Speech"
13529
13528
  },
13530
13529
  {
13531
13530
  id: "scream",
13532
- name: "Scream / Shout",
13533
- icon: "😱"
13531
+ name: "Scream / Shout"
13534
13532
  },
13535
13533
  {
13536
13534
  id: "crying",
13537
- name: "Crying / Baby",
13538
- icon: "😢"
13535
+ name: "Crying / Baby"
13539
13536
  },
13540
13537
  {
13541
13538
  id: "laughter",
13542
- name: "Laughter",
13543
- icon: "😂"
13539
+ name: "Laughter"
13544
13540
  },
13545
13541
  {
13546
13542
  id: "music",
13547
- name: "Music",
13548
- icon: "🎵"
13543
+ name: "Music"
13549
13544
  },
13550
13545
  {
13551
13546
  id: "dog",
13552
- name: "Dog",
13553
- icon: "🐕"
13547
+ name: "Dog"
13554
13548
  },
13555
13549
  {
13556
13550
  id: "cat",
13557
- name: "Cat",
13558
- icon: "🐈"
13551
+ name: "Cat"
13559
13552
  },
13560
13553
  {
13561
13554
  id: "bird",
13562
- name: "Bird",
13563
- icon: "🐦"
13555
+ name: "Bird"
13564
13556
  },
13565
13557
  {
13566
13558
  id: "animal",
13567
- name: "Animal (other)",
13568
- icon: "🐾"
13559
+ name: "Animal (other)"
13569
13560
  },
13570
13561
  {
13571
13562
  id: "alarm",
13572
- name: "Alarm / Siren",
13573
- icon: "🚨"
13563
+ name: "Alarm / Siren"
13574
13564
  },
13575
13565
  {
13576
13566
  id: "doorbell",
13577
- name: "Doorbell / Knock",
13578
- icon: "🔔"
13567
+ name: "Doorbell / Knock"
13579
13568
  },
13580
13569
  {
13581
13570
  id: "glass_breaking",
13582
- name: "Glass Breaking",
13583
- icon: "💥"
13571
+ name: "Glass Breaking"
13584
13572
  },
13585
13573
  {
13586
13574
  id: "gunshot",
13587
- name: "Gunshot / Explosion",
13588
- icon: "💣"
13575
+ name: "Gunshot / Explosion"
13589
13576
  },
13590
13577
  {
13591
13578
  id: "vehicle",
13592
- name: "Vehicle",
13593
- icon: "🚗"
13579
+ name: "Vehicle"
13594
13580
  },
13595
13581
  {
13596
13582
  id: "siren",
13597
- name: "Emergency Siren",
13598
- icon: "🚑"
13583
+ name: "Emergency Siren"
13599
13584
  },
13600
13585
  {
13601
13586
  id: "fire",
13602
- name: "Fire / Smoke",
13603
- icon: "🔥"
13587
+ name: "Fire / Smoke"
13604
13588
  },
13605
13589
  {
13606
13590
  id: "water",
13607
- name: "Water",
13608
- icon: "💧"
13591
+ name: "Water"
13609
13592
  },
13610
13593
  {
13611
13594
  id: "wind",
13612
- name: "Wind / Weather",
13613
- icon: "🌬️"
13595
+ name: "Wind / Weather"
13614
13596
  },
13615
13597
  {
13616
13598
  id: "door",
13617
- name: "Door",
13618
- icon: "🚪"
13599
+ name: "Door"
13619
13600
  },
13620
13601
  {
13621
13602
  id: "footsteps",
13622
- name: "Footsteps",
13623
- icon: "👣"
13603
+ name: "Footsteps"
13624
13604
  },
13625
13605
  {
13626
13606
  id: "crowd",
13627
- name: "Crowd / Chatter",
13628
- icon: "👥"
13607
+ name: "Crowd / Chatter"
13629
13608
  },
13630
13609
  {
13631
13610
  id: "telephone",
13632
- name: "Telephone",
13633
- icon: "📞"
13611
+ name: "Telephone"
13634
13612
  },
13635
13613
  {
13636
13614
  id: "engine",
13637
- name: "Engine / Motor",
13638
- icon: "⚙️"
13615
+ name: "Engine / Motor"
13639
13616
  },
13640
13617
  {
13641
13618
  id: "tools",
13642
- name: "Tools / Construction",
13643
- icon: "🔨"
13619
+ name: "Tools / Construction"
13644
13620
  },
13645
13621
  {
13646
13622
  id: "silence",
13647
- name: "Silence",
13648
- icon: "🤫"
13623
+ name: "Silence"
13649
13624
  }
13650
13625
  ];
13651
13626
  var YAMNET_TO_MACRO = {
@@ -16109,7 +16084,7 @@ var TrackEnvelopeSchema = object({
16109
16084
  * `snapshots[]` references — megabytes across a page of tracks. `slim`
16110
16085
  * keeps every scalar the list surfaces actually render (ids, class(es),
16111
16086
  * label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
16112
- * zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
16087
+ * zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
16113
16088
  * `snapshots` as EMPTY arrays — detail views re-fetch the full row via
16114
16089
  * `getTrack`. Mirrors the event-store `projection` convention
16115
16090
  * (`getObjectEvents` et al.).
@@ -16404,6 +16379,35 @@ var TrackSchema = object({
16404
16379
  */
16405
16380
  hasFace: boolean().optional(),
16406
16381
  /**
16382
+ * This track has a face row IN THE GALLERY: a crop **and** an embedding — a
16383
+ * face an operator could ASSIGN to an identity.
16384
+ *
16385
+ * The STRICT twin of {@link hasFace}, and the pair only earns its keep
16386
+ * because the two disagree. `hasFace` is stamped at the TOP of the face
16387
+ * branch, before every gate, and means no more than "a face detector produced
16388
+ * a face detail". This one is stamped at the single moment the gallery row
16389
+ * LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
16390
+ * past the embedding-magnitude verdict, the `minFacePx` detection gate, the
16391
+ * candidate gate, the imageless-track drop (no crop was ever captured) and
16392
+ * the crop-store drop. Everything between the detector and that insert can
16393
+ * legitimately refuse the face, so a flag written any earlier promises the
16394
+ * operator something to assign and delivers nothing.
16395
+ *
16396
+ * **Independent of recognition.** A face collected but never auto-matched is
16397
+ * still assignable — it is in fact the face an operator most wants to reach —
16398
+ * so this is NOT gated on `recognizedIdentityId`. Recognition lands in
16399
+ * `subLabel`; this says only that the raw material exists.
16400
+ *
16401
+ * **Set once, never cleared.** A track that produced a gallery row produced
16402
+ * one; deleting the row later is the gallery's business, not this flag's.
16403
+ *
16404
+ * **Absent ≠ false**, the same rule as {@link hasFace}: every row written
16405
+ * before the column omits it, and so does every server that predates the
16406
+ * field. A consumer must test `=== true` and render nothing otherwise —
16407
+ * never infer "no assignable face".
16408
+ */
16409
+ hasEmbeddedFace: boolean().optional(),
16410
+ /**
16407
16411
  * This subject CONTAINS a folded rider — a person the rider-pairing step
16408
16412
  * ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
16409
16413
  * so the passage is tracked once and as a VEHICLE.
@@ -17753,6 +17757,32 @@ var DetailResultSchema = object({
17753
17757
  /** FRAME-space bbox (already mapped back from crop space). */
17754
17758
  bbox: NativeCropBboxSchema.optional(),
17755
17759
  embedding: string().optional(),
17760
+ /**
17761
+ * L2 magnitude of the RAW pre-normalization embedding. Additive and optional
17762
+ * so an older runner that does not send it degrades to "unmeasurable", which
17763
+ * the consuming gate treats as accept — never as reject.
17764
+ */
17765
+ embeddingMagnitude: number().optional(),
17766
+ /**
17767
+ * Model that produced `embedding` — the SAME contract `labelModelId` has for
17768
+ * `label`, and for the same reason: the producing node is the only side that
17769
+ * knows which model actually ran, and re-deriving it downstream is exactly
17770
+ * the inference this model exists to forbid.
17771
+ *
17772
+ * Additive and optional, so a runner that predates it degrades to
17773
+ * "unmeasurable" rather than to a wrong answer — the consumer falls back to
17774
+ * its previous assumption instead of refusing.
17775
+ *
17776
+ * Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
17777
+ * to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
17778
+ * with nothing on the wire it took the id from the GALLERY, so the gate
17779
+ * compared the gallery against itself and could never fire. That turned the
17780
+ * one guard protecting the face feature space into a tautology, and it is
17781
+ * why swapping `face-embedding`'s model would NOT have stranded the enrolled
17782
+ * gallery as the catalog comment predicts — it would have scored the new
17783
+ * model's vectors against the old model's samples in one cosine space.
17784
+ */
17785
+ embeddingModelId: string().optional(),
17756
17786
  label: string().optional(),
17757
17787
  /**
17758
17788
  * The tier `label` occupies, copied VERBATIM from the producing step's
@@ -19176,6 +19206,7 @@ DeviceType.Camera, method(object({
19176
19206
  isBattery: boolean(),
19177
19207
  reason: _enum([
19178
19208
  "disabled",
19209
+ "offline",
19179
19210
  "sleeping",
19180
19211
  "unreachable",
19181
19212
  "waking"
@@ -19221,9 +19252,17 @@ targets: array(object({
19221
19252
  sleeping: boolean(),
19222
19253
  /** Current device state rendered over the cached frame. State images
19223
19254
  * remain authoritative even when their photographic background is
19224
- * old; null means the link must carry a current camera frame. */
19255
+ * old; null means the link must carry a current camera frame.
19256
+ *
19257
+ * **This is the ONLY source a surface may derive an inactive tile
19258
+ * from.** A client that reads a device's `online`/`disabled` flags and
19259
+ * draws its own verdict will disagree with the pixels it is painting
19260
+ * — the frame comes from here, and so must the sentence over it
19261
+ * (D190). Pair with `ageMs` for the age of the photograph behind the
19262
+ * state. */
19225
19263
  stateReason: _enum([
19226
19264
  "disabled",
19265
+ "offline",
19227
19266
  "sleeping",
19228
19267
  "unreachable",
19229
19268
  "waking"
@@ -33409,7 +33448,6 @@ var NC_AUDIO_DEFAULTS = {
33409
33448
  hitPercent: 60,
33410
33449
  samplingSeconds: 10
33411
33450
  };
33412
- new Map(AUDIO_MACRO_LABELS.flatMap((macro) => macro.icon === void 0 ? [] : [[macro.id, macro.icon]]));
33413
33451
  new Set(["devices", "classes"]);
33414
33452
  NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
33415
33453
  /**
@@ -33643,6 +33681,39 @@ TimelapseRuleInputSchema.extend({
33643
33681
  createdAt: number(),
33644
33682
  updatedAt: number()
33645
33683
  });
33684
+ Object.freeze(Object.fromEntries([{
33685
+ stepId: "face-embedding",
33686
+ label: "Face recognition model",
33687
+ defaultModelId: "arcface-r100",
33688
+ indexName: "the enrolled face gallery",
33689
+ options: [
33690
+ {
33691
+ id: "arcface-r100",
33692
+ label: "ArcFace (ResNet34)"
33693
+ },
33694
+ {
33695
+ id: "auraface-r100",
33696
+ label: "AuraFace R100"
33697
+ },
33698
+ {
33699
+ id: "inception-resnet-v1",
33700
+ label: "Inception ResNet V1"
33701
+ }
33702
+ ]
33703
+ }, {
33704
+ stepId: "clip-embedding",
33705
+ label: "Semantic search model",
33706
+ defaultModelId: "mobileclip-s1",
33707
+ indexName: "the object semantic-search index",
33708
+ options: [{
33709
+ id: "mobileclip-s1",
33710
+ label: "MobileCLIP S1"
33711
+ }, {
33712
+ id: "mobileclip-s2",
33713
+ label: "MobileCLIP S2"
33714
+ }]
33715
+ }].map((s) => [s.stepId, s.defaultModelId])));
33716
+ string().min(1);
33646
33717
  object({
33647
33718
  /**
33648
33719
  * Fraction of the box's own size added on EACH side before cutting.
@@ -33663,10 +33734,21 @@ object({
33663
33734
  */
33664
33735
  square: boolean()
33665
33736
  });
33666
- ({
33737
+ /**
33738
+ * The convention in force when nobody has configured one — byte-for-byte the
33739
+ * behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
33740
+ */
33741
+ var DEFAULT_DETAIL_CROP_CONVENTION = {
33667
33742
  paddingRatio: .15,
33668
33743
  square: false
33669
- }).paddingRatio;
33744
+ };
33745
+ Object.freeze({
33746
+ x: 0,
33747
+ y: 0,
33748
+ w: 1,
33749
+ h: 1
33750
+ });
33751
+ DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
33670
33752
  /**
33671
33753
  * WHICH delivered frames the decode worker retains a native copy of.
33672
33754
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-smtp-nodemailer",
3
- "version": "1.2.22",
3
+ "version": "1.2.23",
4
4
  "description": "SMTP email provider addon for CamStack — wraps `nodemailer` and registers a `smtp-provider` cap collection entry. Used by magic-link login + notifier addons.",
5
5
  "keywords": [
6
6
  "camstack",