@camstack/addon-provider-reolink 1.2.44 → 1.2.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +167 -59
- package/dist/addon.mjs +167 -59
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -7605,7 +7605,7 @@ var RecordingBandSchema = object({
|
|
|
7605
7605
|
postBufferSec: number().min(0).optional()
|
|
7606
7606
|
});
|
|
7607
7607
|
({
|
|
7608
|
-
preBufferSec:
|
|
7608
|
+
preBufferSec: 15,
|
|
7609
7609
|
postBufferSec: 30
|
|
7610
7610
|
}).postBufferSec * 1e3;
|
|
7611
7611
|
/**
|
|
@@ -13995,128 +13995,103 @@ var COCO_TO_MACRO = {
|
|
|
13995
13995
|
var AUDIO_MACRO_LABELS = [
|
|
13996
13996
|
{
|
|
13997
13997
|
id: "speech",
|
|
13998
|
-
name: "Speech"
|
|
13999
|
-
icon: "🗣️"
|
|
13998
|
+
name: "Speech"
|
|
14000
13999
|
},
|
|
14001
14000
|
{
|
|
14002
14001
|
id: "scream",
|
|
14003
|
-
name: "Scream / Shout"
|
|
14004
|
-
icon: "😱"
|
|
14002
|
+
name: "Scream / Shout"
|
|
14005
14003
|
},
|
|
14006
14004
|
{
|
|
14007
14005
|
id: "crying",
|
|
14008
|
-
name: "Crying / Baby"
|
|
14009
|
-
icon: "😢"
|
|
14006
|
+
name: "Crying / Baby"
|
|
14010
14007
|
},
|
|
14011
14008
|
{
|
|
14012
14009
|
id: "laughter",
|
|
14013
|
-
name: "Laughter"
|
|
14014
|
-
icon: "😂"
|
|
14010
|
+
name: "Laughter"
|
|
14015
14011
|
},
|
|
14016
14012
|
{
|
|
14017
14013
|
id: "music",
|
|
14018
|
-
name: "Music"
|
|
14019
|
-
icon: "🎵"
|
|
14014
|
+
name: "Music"
|
|
14020
14015
|
},
|
|
14021
14016
|
{
|
|
14022
14017
|
id: "dog",
|
|
14023
|
-
name: "Dog"
|
|
14024
|
-
icon: "🐕"
|
|
14018
|
+
name: "Dog"
|
|
14025
14019
|
},
|
|
14026
14020
|
{
|
|
14027
14021
|
id: "cat",
|
|
14028
|
-
name: "Cat"
|
|
14029
|
-
icon: "🐈"
|
|
14022
|
+
name: "Cat"
|
|
14030
14023
|
},
|
|
14031
14024
|
{
|
|
14032
14025
|
id: "bird",
|
|
14033
|
-
name: "Bird"
|
|
14034
|
-
icon: "🐦"
|
|
14026
|
+
name: "Bird"
|
|
14035
14027
|
},
|
|
14036
14028
|
{
|
|
14037
14029
|
id: "animal",
|
|
14038
|
-
name: "Animal (other)"
|
|
14039
|
-
icon: "🐾"
|
|
14030
|
+
name: "Animal (other)"
|
|
14040
14031
|
},
|
|
14041
14032
|
{
|
|
14042
14033
|
id: "alarm",
|
|
14043
|
-
name: "Alarm / Siren"
|
|
14044
|
-
icon: "🚨"
|
|
14034
|
+
name: "Alarm / Siren"
|
|
14045
14035
|
},
|
|
14046
14036
|
{
|
|
14047
14037
|
id: "doorbell",
|
|
14048
|
-
name: "Doorbell / Knock"
|
|
14049
|
-
icon: "🔔"
|
|
14038
|
+
name: "Doorbell / Knock"
|
|
14050
14039
|
},
|
|
14051
14040
|
{
|
|
14052
14041
|
id: "glass_breaking",
|
|
14053
|
-
name: "Glass Breaking"
|
|
14054
|
-
icon: "💥"
|
|
14042
|
+
name: "Glass Breaking"
|
|
14055
14043
|
},
|
|
14056
14044
|
{
|
|
14057
14045
|
id: "gunshot",
|
|
14058
|
-
name: "Gunshot / Explosion"
|
|
14059
|
-
icon: "💣"
|
|
14046
|
+
name: "Gunshot / Explosion"
|
|
14060
14047
|
},
|
|
14061
14048
|
{
|
|
14062
14049
|
id: "vehicle",
|
|
14063
|
-
name: "Vehicle"
|
|
14064
|
-
icon: "🚗"
|
|
14050
|
+
name: "Vehicle"
|
|
14065
14051
|
},
|
|
14066
14052
|
{
|
|
14067
14053
|
id: "siren",
|
|
14068
|
-
name: "Emergency Siren"
|
|
14069
|
-
icon: "🚑"
|
|
14054
|
+
name: "Emergency Siren"
|
|
14070
14055
|
},
|
|
14071
14056
|
{
|
|
14072
14057
|
id: "fire",
|
|
14073
|
-
name: "Fire / Smoke"
|
|
14074
|
-
icon: "🔥"
|
|
14058
|
+
name: "Fire / Smoke"
|
|
14075
14059
|
},
|
|
14076
14060
|
{
|
|
14077
14061
|
id: "water",
|
|
14078
|
-
name: "Water"
|
|
14079
|
-
icon: "💧"
|
|
14062
|
+
name: "Water"
|
|
14080
14063
|
},
|
|
14081
14064
|
{
|
|
14082
14065
|
id: "wind",
|
|
14083
|
-
name: "Wind / Weather"
|
|
14084
|
-
icon: "🌬️"
|
|
14066
|
+
name: "Wind / Weather"
|
|
14085
14067
|
},
|
|
14086
14068
|
{
|
|
14087
14069
|
id: "door",
|
|
14088
|
-
name: "Door"
|
|
14089
|
-
icon: "🚪"
|
|
14070
|
+
name: "Door"
|
|
14090
14071
|
},
|
|
14091
14072
|
{
|
|
14092
14073
|
id: "footsteps",
|
|
14093
|
-
name: "Footsteps"
|
|
14094
|
-
icon: "👣"
|
|
14074
|
+
name: "Footsteps"
|
|
14095
14075
|
},
|
|
14096
14076
|
{
|
|
14097
14077
|
id: "crowd",
|
|
14098
|
-
name: "Crowd / Chatter"
|
|
14099
|
-
icon: "👥"
|
|
14078
|
+
name: "Crowd / Chatter"
|
|
14100
14079
|
},
|
|
14101
14080
|
{
|
|
14102
14081
|
id: "telephone",
|
|
14103
|
-
name: "Telephone"
|
|
14104
|
-
icon: "📞"
|
|
14082
|
+
name: "Telephone"
|
|
14105
14083
|
},
|
|
14106
14084
|
{
|
|
14107
14085
|
id: "engine",
|
|
14108
|
-
name: "Engine / Motor"
|
|
14109
|
-
icon: "⚙️"
|
|
14086
|
+
name: "Engine / Motor"
|
|
14110
14087
|
},
|
|
14111
14088
|
{
|
|
14112
14089
|
id: "tools",
|
|
14113
|
-
name: "Tools / Construction"
|
|
14114
|
-
icon: "🔨"
|
|
14090
|
+
name: "Tools / Construction"
|
|
14115
14091
|
},
|
|
14116
14092
|
{
|
|
14117
14093
|
id: "silence",
|
|
14118
|
-
name: "Silence"
|
|
14119
|
-
icon: "🤫"
|
|
14094
|
+
name: "Silence"
|
|
14120
14095
|
}
|
|
14121
14096
|
];
|
|
14122
14097
|
var YAMNET_TO_MACRO = {
|
|
@@ -16618,7 +16593,7 @@ var TrackEnvelopeSchema = object({
|
|
|
16618
16593
|
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16619
16594
|
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16620
16595
|
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16621
|
-
* zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
|
|
16596
|
+
* zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
|
|
16622
16597
|
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16623
16598
|
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16624
16599
|
* (`getObjectEvents` et al.).
|
|
@@ -16913,6 +16888,35 @@ var TrackSchema = object({
|
|
|
16913
16888
|
*/
|
|
16914
16889
|
hasFace: boolean().optional(),
|
|
16915
16890
|
/**
|
|
16891
|
+
* This track has a face row IN THE GALLERY: a crop **and** an embedding — a
|
|
16892
|
+
* face an operator could ASSIGN to an identity.
|
|
16893
|
+
*
|
|
16894
|
+
* The STRICT twin of {@link hasFace}, and the pair only earns its keep
|
|
16895
|
+
* because the two disagree. `hasFace` is stamped at the TOP of the face
|
|
16896
|
+
* branch, before every gate, and means no more than "a face detector produced
|
|
16897
|
+
* a face detail". This one is stamped at the single moment the gallery row
|
|
16898
|
+
* LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
|
|
16899
|
+
* past the embedding-magnitude verdict, the `minFacePx` detection gate, the
|
|
16900
|
+
* candidate gate, the imageless-track drop (no crop was ever captured) and
|
|
16901
|
+
* the crop-store drop. Everything between the detector and that insert can
|
|
16902
|
+
* legitimately refuse the face, so a flag written any earlier promises the
|
|
16903
|
+
* operator something to assign and delivers nothing.
|
|
16904
|
+
*
|
|
16905
|
+
* **Independent of recognition.** A face collected but never auto-matched is
|
|
16906
|
+
* still assignable — it is in fact the face an operator most wants to reach —
|
|
16907
|
+
* so this is NOT gated on `recognizedIdentityId`. Recognition lands in
|
|
16908
|
+
* `subLabel`; this says only that the raw material exists.
|
|
16909
|
+
*
|
|
16910
|
+
* **Set once, never cleared.** A track that produced a gallery row produced
|
|
16911
|
+
* one; deleting the row later is the gallery's business, not this flag's.
|
|
16912
|
+
*
|
|
16913
|
+
* **Absent ≠ false**, the same rule as {@link hasFace}: every row written
|
|
16914
|
+
* before the column omits it, and so does every server that predates the
|
|
16915
|
+
* field. A consumer must test `=== true` and render nothing otherwise —
|
|
16916
|
+
* never infer "no assignable face".
|
|
16917
|
+
*/
|
|
16918
|
+
hasEmbeddedFace: boolean().optional(),
|
|
16919
|
+
/**
|
|
16916
16920
|
* This subject CONTAINS a folded rider — a person the rider-pairing step
|
|
16917
16921
|
* ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
|
|
16918
16922
|
* so the passage is tracked once and as a VEHICLE.
|
|
@@ -18302,6 +18306,32 @@ var DetailResultSchema = object({
|
|
|
18302
18306
|
/** FRAME-space bbox (already mapped back from crop space). */
|
|
18303
18307
|
bbox: NativeCropBboxSchema.optional(),
|
|
18304
18308
|
embedding: string().optional(),
|
|
18309
|
+
/**
|
|
18310
|
+
* L2 magnitude of the RAW pre-normalization embedding. Additive and optional
|
|
18311
|
+
* so an older runner that does not send it degrades to "unmeasurable", which
|
|
18312
|
+
* the consuming gate treats as accept — never as reject.
|
|
18313
|
+
*/
|
|
18314
|
+
embeddingMagnitude: number().optional(),
|
|
18315
|
+
/**
|
|
18316
|
+
* Model that produced `embedding` — the SAME contract `labelModelId` has for
|
|
18317
|
+
* `label`, and for the same reason: the producing node is the only side that
|
|
18318
|
+
* knows which model actually ran, and re-deriving it downstream is exactly
|
|
18319
|
+
* the inference this model exists to forbid.
|
|
18320
|
+
*
|
|
18321
|
+
* Additive and optional, so a runner that predates it degrades to
|
|
18322
|
+
* "unmeasurable" rather than to a wrong answer — the consumer falls back to
|
|
18323
|
+
* its previous assumption instead of refusing.
|
|
18324
|
+
*
|
|
18325
|
+
* Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
|
|
18326
|
+
* to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
|
|
18327
|
+
* with nothing on the wire it took the id from the GALLERY, so the gate
|
|
18328
|
+
* compared the gallery against itself and could never fire. That turned the
|
|
18329
|
+
* one guard protecting the face feature space into a tautology, and it is
|
|
18330
|
+
* why swapping `face-embedding`'s model would NOT have stranded the enrolled
|
|
18331
|
+
* gallery as the catalog comment predicts — it would have scored the new
|
|
18332
|
+
* model's vectors against the old model's samples in one cosine space.
|
|
18333
|
+
*/
|
|
18334
|
+
embeddingModelId: string().optional(),
|
|
18305
18335
|
label: string().optional(),
|
|
18306
18336
|
/**
|
|
18307
18337
|
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
@@ -19766,6 +19796,7 @@ var snapshotCapability = {
|
|
|
19766
19796
|
isBattery: boolean(),
|
|
19767
19797
|
reason: _enum([
|
|
19768
19798
|
"disabled",
|
|
19799
|
+
"offline",
|
|
19769
19800
|
"sleeping",
|
|
19770
19801
|
"unreachable",
|
|
19771
19802
|
"waking"
|
|
@@ -19855,9 +19886,17 @@ targets: array(object({
|
|
|
19855
19886
|
sleeping: boolean(),
|
|
19856
19887
|
/** Current device state rendered over the cached frame. State images
|
|
19857
19888
|
* remain authoritative even when their photographic background is
|
|
19858
|
-
* old; null means the link must carry a current camera frame.
|
|
19889
|
+
* old; null means the link must carry a current camera frame.
|
|
19890
|
+
*
|
|
19891
|
+
* **This is the ONLY source a surface may derive an inactive tile
|
|
19892
|
+
* from.** A client that reads a device's `online`/`disabled` flags and
|
|
19893
|
+
* draws its own verdict will disagree with the pixels it is painting
|
|
19894
|
+
* — the frame comes from here, and so must the sentence over it
|
|
19895
|
+
* (D190). Pair with `ageMs` for the age of the photograph behind the
|
|
19896
|
+
* state. */
|
|
19859
19897
|
stateReason: _enum([
|
|
19860
19898
|
"disabled",
|
|
19899
|
+
"offline",
|
|
19861
19900
|
"sleeping",
|
|
19862
19901
|
"unreachable",
|
|
19863
19902
|
"waking"
|
|
@@ -26669,9 +26708,21 @@ var RecordingLocationUsageSchema = object({
|
|
|
26669
26708
|
* previously rendered as two identical "disks" with a nonsensical used
|
|
26670
26709
|
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
26671
26710
|
locationIds: array(string()).optional(),
|
|
26672
|
-
/**
|
|
26711
|
+
/**
|
|
26712
|
+
* Filesystem root of the physical volume this row accounts — the only
|
|
26713
|
+
* operator-legible identity when a location has no `displayName` yet, and
|
|
26714
|
+
* what a "which disk is full" alert has to name. OPTIONAL for the same
|
|
26715
|
+
* train-skew reason as `oldestMs`: a recorder that predates the field omits
|
|
26716
|
+
* it, and this schema must keep validating that older provider's payload.
|
|
26717
|
+
*/
|
|
26718
|
+
root: string().optional(),
|
|
26719
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). This is
|
|
26720
|
+
* the footage's SHARE of the volume, not how full the volume is — the disk
|
|
26721
|
+
* also holds everything that is not recordings. Volume fill is
|
|
26722
|
+
* `(totalBytes - availableBytes) / totalBytes`. */
|
|
26673
26723
|
usedBytes: number(),
|
|
26674
|
-
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26724
|
+
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26725
|
+
* (remote/unstattable — the recorder logs the statfs failure with the root). */
|
|
26675
26726
|
availableBytes: number().nullable(),
|
|
26676
26727
|
/** Total bytes of the location's volume; null when unknown. */
|
|
26677
26728
|
totalBytes: number().nullable()
|
|
@@ -26683,7 +26734,15 @@ var RecordingStorageUsageSchema = object({
|
|
|
26683
26734
|
nodeId: string(),
|
|
26684
26735
|
totalUsedBytes: number(),
|
|
26685
26736
|
devices: array(RecordingDeviceUsageSchema),
|
|
26686
|
-
|
|
26737
|
+
/**
|
|
26738
|
+
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
26739
|
+
* of the payload without it: the hub serves this method through a BAKED
|
|
26740
|
+
* router, so a hub whose framework train predates a change to this array
|
|
26741
|
+
* strips it out of an answer a newer recorder happily produced. A UI that
|
|
26742
|
+
* dereferences it unconditionally crashes the whole Storage page over a
|
|
26743
|
+
* missing disk bar.
|
|
26744
|
+
*/
|
|
26745
|
+
locations: array(RecordingLocationUsageSchema).optional()
|
|
26687
26746
|
});
|
|
26688
26747
|
/**
|
|
26689
26748
|
* The OPERATOR-ARMED half of multi-location recordings (D116).
|
|
@@ -37746,8 +37805,13 @@ Object.freeze({
|
|
|
37746
37805
|
"network-access": "ingress",
|
|
37747
37806
|
"smtp-provider": "email"
|
|
37748
37807
|
});
|
|
37749
|
-
|
|
37808
|
+
/** Schema defaults — an untouched sub-field must author exactly these. */
|
|
37809
|
+
var NC_AUDIO_DEFAULTS = {
|
|
37810
|
+
hitPercent: 60,
|
|
37811
|
+
samplingSeconds: 10
|
|
37812
|
+
};
|
|
37750
37813
|
new Set(["devices", "classes"]);
|
|
37814
|
+
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
37751
37815
|
/**
|
|
37752
37816
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
37753
37817
|
*
|
|
@@ -37979,6 +38043,39 @@ TimelapseRuleInputSchema.extend({
|
|
|
37979
38043
|
createdAt: number(),
|
|
37980
38044
|
updatedAt: number()
|
|
37981
38045
|
});
|
|
38046
|
+
Object.freeze(Object.fromEntries([{
|
|
38047
|
+
stepId: "face-embedding",
|
|
38048
|
+
label: "Face recognition model",
|
|
38049
|
+
defaultModelId: "arcface-r100",
|
|
38050
|
+
indexName: "the enrolled face gallery",
|
|
38051
|
+
options: [
|
|
38052
|
+
{
|
|
38053
|
+
id: "arcface-r100",
|
|
38054
|
+
label: "ArcFace (ResNet34)"
|
|
38055
|
+
},
|
|
38056
|
+
{
|
|
38057
|
+
id: "auraface-r100",
|
|
38058
|
+
label: "AuraFace R100"
|
|
38059
|
+
},
|
|
38060
|
+
{
|
|
38061
|
+
id: "inception-resnet-v1",
|
|
38062
|
+
label: "Inception ResNet V1"
|
|
38063
|
+
}
|
|
38064
|
+
]
|
|
38065
|
+
}, {
|
|
38066
|
+
stepId: "clip-embedding",
|
|
38067
|
+
label: "Semantic search model",
|
|
38068
|
+
defaultModelId: "mobileclip-s1",
|
|
38069
|
+
indexName: "the object semantic-search index",
|
|
38070
|
+
options: [{
|
|
38071
|
+
id: "mobileclip-s1",
|
|
38072
|
+
label: "MobileCLIP S1"
|
|
38073
|
+
}, {
|
|
38074
|
+
id: "mobileclip-s2",
|
|
38075
|
+
label: "MobileCLIP S2"
|
|
38076
|
+
}]
|
|
38077
|
+
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
38078
|
+
string().min(1);
|
|
37982
38079
|
object({
|
|
37983
38080
|
/**
|
|
37984
38081
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -37999,10 +38096,21 @@ object({
|
|
|
37999
38096
|
*/
|
|
38000
38097
|
square: boolean()
|
|
38001
38098
|
});
|
|
38002
|
-
|
|
38099
|
+
/**
|
|
38100
|
+
* The convention in force when nobody has configured one — byte-for-byte the
|
|
38101
|
+
* behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
|
|
38102
|
+
*/
|
|
38103
|
+
var DEFAULT_DETAIL_CROP_CONVENTION = {
|
|
38003
38104
|
paddingRatio: .15,
|
|
38004
38105
|
square: false
|
|
38005
|
-
}
|
|
38106
|
+
};
|
|
38107
|
+
Object.freeze({
|
|
38108
|
+
x: 0,
|
|
38109
|
+
y: 0,
|
|
38110
|
+
w: 1,
|
|
38111
|
+
h: 1
|
|
38112
|
+
});
|
|
38113
|
+
DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
|
|
38006
38114
|
/**
|
|
38007
38115
|
* WHICH delivered frames the decode worker retains a native copy of.
|
|
38008
38116
|
*
|
package/dist/addon.mjs
CHANGED
|
@@ -7600,7 +7600,7 @@ var RecordingBandSchema = object({
|
|
|
7600
7600
|
postBufferSec: number().min(0).optional()
|
|
7601
7601
|
});
|
|
7602
7602
|
({
|
|
7603
|
-
preBufferSec:
|
|
7603
|
+
preBufferSec: 15,
|
|
7604
7604
|
postBufferSec: 30
|
|
7605
7605
|
}).postBufferSec * 1e3;
|
|
7606
7606
|
/**
|
|
@@ -13990,128 +13990,103 @@ var COCO_TO_MACRO = {
|
|
|
13990
13990
|
var AUDIO_MACRO_LABELS = [
|
|
13991
13991
|
{
|
|
13992
13992
|
id: "speech",
|
|
13993
|
-
name: "Speech"
|
|
13994
|
-
icon: "🗣️"
|
|
13993
|
+
name: "Speech"
|
|
13995
13994
|
},
|
|
13996
13995
|
{
|
|
13997
13996
|
id: "scream",
|
|
13998
|
-
name: "Scream / Shout"
|
|
13999
|
-
icon: "😱"
|
|
13997
|
+
name: "Scream / Shout"
|
|
14000
13998
|
},
|
|
14001
13999
|
{
|
|
14002
14000
|
id: "crying",
|
|
14003
|
-
name: "Crying / Baby"
|
|
14004
|
-
icon: "😢"
|
|
14001
|
+
name: "Crying / Baby"
|
|
14005
14002
|
},
|
|
14006
14003
|
{
|
|
14007
14004
|
id: "laughter",
|
|
14008
|
-
name: "Laughter"
|
|
14009
|
-
icon: "😂"
|
|
14005
|
+
name: "Laughter"
|
|
14010
14006
|
},
|
|
14011
14007
|
{
|
|
14012
14008
|
id: "music",
|
|
14013
|
-
name: "Music"
|
|
14014
|
-
icon: "🎵"
|
|
14009
|
+
name: "Music"
|
|
14015
14010
|
},
|
|
14016
14011
|
{
|
|
14017
14012
|
id: "dog",
|
|
14018
|
-
name: "Dog"
|
|
14019
|
-
icon: "🐕"
|
|
14013
|
+
name: "Dog"
|
|
14020
14014
|
},
|
|
14021
14015
|
{
|
|
14022
14016
|
id: "cat",
|
|
14023
|
-
name: "Cat"
|
|
14024
|
-
icon: "🐈"
|
|
14017
|
+
name: "Cat"
|
|
14025
14018
|
},
|
|
14026
14019
|
{
|
|
14027
14020
|
id: "bird",
|
|
14028
|
-
name: "Bird"
|
|
14029
|
-
icon: "🐦"
|
|
14021
|
+
name: "Bird"
|
|
14030
14022
|
},
|
|
14031
14023
|
{
|
|
14032
14024
|
id: "animal",
|
|
14033
|
-
name: "Animal (other)"
|
|
14034
|
-
icon: "🐾"
|
|
14025
|
+
name: "Animal (other)"
|
|
14035
14026
|
},
|
|
14036
14027
|
{
|
|
14037
14028
|
id: "alarm",
|
|
14038
|
-
name: "Alarm / Siren"
|
|
14039
|
-
icon: "🚨"
|
|
14029
|
+
name: "Alarm / Siren"
|
|
14040
14030
|
},
|
|
14041
14031
|
{
|
|
14042
14032
|
id: "doorbell",
|
|
14043
|
-
name: "Doorbell / Knock"
|
|
14044
|
-
icon: "🔔"
|
|
14033
|
+
name: "Doorbell / Knock"
|
|
14045
14034
|
},
|
|
14046
14035
|
{
|
|
14047
14036
|
id: "glass_breaking",
|
|
14048
|
-
name: "Glass Breaking"
|
|
14049
|
-
icon: "💥"
|
|
14037
|
+
name: "Glass Breaking"
|
|
14050
14038
|
},
|
|
14051
14039
|
{
|
|
14052
14040
|
id: "gunshot",
|
|
14053
|
-
name: "Gunshot / Explosion"
|
|
14054
|
-
icon: "💣"
|
|
14041
|
+
name: "Gunshot / Explosion"
|
|
14055
14042
|
},
|
|
14056
14043
|
{
|
|
14057
14044
|
id: "vehicle",
|
|
14058
|
-
name: "Vehicle"
|
|
14059
|
-
icon: "🚗"
|
|
14045
|
+
name: "Vehicle"
|
|
14060
14046
|
},
|
|
14061
14047
|
{
|
|
14062
14048
|
id: "siren",
|
|
14063
|
-
name: "Emergency Siren"
|
|
14064
|
-
icon: "🚑"
|
|
14049
|
+
name: "Emergency Siren"
|
|
14065
14050
|
},
|
|
14066
14051
|
{
|
|
14067
14052
|
id: "fire",
|
|
14068
|
-
name: "Fire / Smoke"
|
|
14069
|
-
icon: "🔥"
|
|
14053
|
+
name: "Fire / Smoke"
|
|
14070
14054
|
},
|
|
14071
14055
|
{
|
|
14072
14056
|
id: "water",
|
|
14073
|
-
name: "Water"
|
|
14074
|
-
icon: "💧"
|
|
14057
|
+
name: "Water"
|
|
14075
14058
|
},
|
|
14076
14059
|
{
|
|
14077
14060
|
id: "wind",
|
|
14078
|
-
name: "Wind / Weather"
|
|
14079
|
-
icon: "🌬️"
|
|
14061
|
+
name: "Wind / Weather"
|
|
14080
14062
|
},
|
|
14081
14063
|
{
|
|
14082
14064
|
id: "door",
|
|
14083
|
-
name: "Door"
|
|
14084
|
-
icon: "🚪"
|
|
14065
|
+
name: "Door"
|
|
14085
14066
|
},
|
|
14086
14067
|
{
|
|
14087
14068
|
id: "footsteps",
|
|
14088
|
-
name: "Footsteps"
|
|
14089
|
-
icon: "👣"
|
|
14069
|
+
name: "Footsteps"
|
|
14090
14070
|
},
|
|
14091
14071
|
{
|
|
14092
14072
|
id: "crowd",
|
|
14093
|
-
name: "Crowd / Chatter"
|
|
14094
|
-
icon: "👥"
|
|
14073
|
+
name: "Crowd / Chatter"
|
|
14095
14074
|
},
|
|
14096
14075
|
{
|
|
14097
14076
|
id: "telephone",
|
|
14098
|
-
name: "Telephone"
|
|
14099
|
-
icon: "📞"
|
|
14077
|
+
name: "Telephone"
|
|
14100
14078
|
},
|
|
14101
14079
|
{
|
|
14102
14080
|
id: "engine",
|
|
14103
|
-
name: "Engine / Motor"
|
|
14104
|
-
icon: "⚙️"
|
|
14081
|
+
name: "Engine / Motor"
|
|
14105
14082
|
},
|
|
14106
14083
|
{
|
|
14107
14084
|
id: "tools",
|
|
14108
|
-
name: "Tools / Construction"
|
|
14109
|
-
icon: "🔨"
|
|
14085
|
+
name: "Tools / Construction"
|
|
14110
14086
|
},
|
|
14111
14087
|
{
|
|
14112
14088
|
id: "silence",
|
|
14113
|
-
name: "Silence"
|
|
14114
|
-
icon: "🤫"
|
|
14089
|
+
name: "Silence"
|
|
14115
14090
|
}
|
|
14116
14091
|
];
|
|
14117
14092
|
var YAMNET_TO_MACRO = {
|
|
@@ -16613,7 +16588,7 @@ var TrackEnvelopeSchema = object({
|
|
|
16613
16588
|
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16614
16589
|
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16615
16590
|
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16616
|
-
* zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
|
|
16591
|
+
* zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
|
|
16617
16592
|
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16618
16593
|
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16619
16594
|
* (`getObjectEvents` et al.).
|
|
@@ -16908,6 +16883,35 @@ var TrackSchema = object({
|
|
|
16908
16883
|
*/
|
|
16909
16884
|
hasFace: boolean().optional(),
|
|
16910
16885
|
/**
|
|
16886
|
+
* This track has a face row IN THE GALLERY: a crop **and** an embedding — a
|
|
16887
|
+
* face an operator could ASSIGN to an identity.
|
|
16888
|
+
*
|
|
16889
|
+
* The STRICT twin of {@link hasFace}, and the pair only earns its keep
|
|
16890
|
+
* because the two disagree. `hasFace` is stamped at the TOP of the face
|
|
16891
|
+
* branch, before every gate, and means no more than "a face detector produced
|
|
16892
|
+
* a face detail". This one is stamped at the single moment the gallery row
|
|
16893
|
+
* LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
|
|
16894
|
+
* past the embedding-magnitude verdict, the `minFacePx` detection gate, the
|
|
16895
|
+
* candidate gate, the imageless-track drop (no crop was ever captured) and
|
|
16896
|
+
* the crop-store drop. Everything between the detector and that insert can
|
|
16897
|
+
* legitimately refuse the face, so a flag written any earlier promises the
|
|
16898
|
+
* operator something to assign and delivers nothing.
|
|
16899
|
+
*
|
|
16900
|
+
* **Independent of recognition.** A face collected but never auto-matched is
|
|
16901
|
+
* still assignable — it is in fact the face an operator most wants to reach —
|
|
16902
|
+
* so this is NOT gated on `recognizedIdentityId`. Recognition lands in
|
|
16903
|
+
* `subLabel`; this says only that the raw material exists.
|
|
16904
|
+
*
|
|
16905
|
+
* **Set once, never cleared.** A track that produced a gallery row produced
|
|
16906
|
+
* one; deleting the row later is the gallery's business, not this flag's.
|
|
16907
|
+
*
|
|
16908
|
+
* **Absent ≠ false**, the same rule as {@link hasFace}: every row written
|
|
16909
|
+
* before the column omits it, and so does every server that predates the
|
|
16910
|
+
* field. A consumer must test `=== true` and render nothing otherwise —
|
|
16911
|
+
* never infer "no assignable face".
|
|
16912
|
+
*/
|
|
16913
|
+
hasEmbeddedFace: boolean().optional(),
|
|
16914
|
+
/**
|
|
16911
16915
|
* This subject CONTAINS a folded rider — a person the rider-pairing step
|
|
16912
16916
|
* ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
|
|
16913
16917
|
* so the passage is tracked once and as a VEHICLE.
|
|
@@ -18297,6 +18301,32 @@ var DetailResultSchema = object({
|
|
|
18297
18301
|
/** FRAME-space bbox (already mapped back from crop space). */
|
|
18298
18302
|
bbox: NativeCropBboxSchema.optional(),
|
|
18299
18303
|
embedding: string().optional(),
|
|
18304
|
+
/**
|
|
18305
|
+
* L2 magnitude of the RAW pre-normalization embedding. Additive and optional
|
|
18306
|
+
* so an older runner that does not send it degrades to "unmeasurable", which
|
|
18307
|
+
* the consuming gate treats as accept — never as reject.
|
|
18308
|
+
*/
|
|
18309
|
+
embeddingMagnitude: number().optional(),
|
|
18310
|
+
/**
|
|
18311
|
+
* Model that produced `embedding` — the SAME contract `labelModelId` has for
|
|
18312
|
+
* `label`, and for the same reason: the producing node is the only side that
|
|
18313
|
+
* knows which model actually ran, and re-deriving it downstream is exactly
|
|
18314
|
+
* the inference this model exists to forbid.
|
|
18315
|
+
*
|
|
18316
|
+
* Additive and optional, so a runner that predates it degrades to
|
|
18317
|
+
* "unmeasurable" rather than to a wrong answer — the consumer falls back to
|
|
18318
|
+
* its previous assumption instead of refusing.
|
|
18319
|
+
*
|
|
18320
|
+
* Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
|
|
18321
|
+
* to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
|
|
18322
|
+
* with nothing on the wire it took the id from the GALLERY, so the gate
|
|
18323
|
+
* compared the gallery against itself and could never fire. That turned the
|
|
18324
|
+
* one guard protecting the face feature space into a tautology, and it is
|
|
18325
|
+
* why swapping `face-embedding`'s model would NOT have stranded the enrolled
|
|
18326
|
+
* gallery as the catalog comment predicts — it would have scored the new
|
|
18327
|
+
* model's vectors against the old model's samples in one cosine space.
|
|
18328
|
+
*/
|
|
18329
|
+
embeddingModelId: string().optional(),
|
|
18300
18330
|
label: string().optional(),
|
|
18301
18331
|
/**
|
|
18302
18332
|
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
@@ -19761,6 +19791,7 @@ var snapshotCapability = {
|
|
|
19761
19791
|
isBattery: boolean(),
|
|
19762
19792
|
reason: _enum([
|
|
19763
19793
|
"disabled",
|
|
19794
|
+
"offline",
|
|
19764
19795
|
"sleeping",
|
|
19765
19796
|
"unreachable",
|
|
19766
19797
|
"waking"
|
|
@@ -19850,9 +19881,17 @@ targets: array(object({
|
|
|
19850
19881
|
sleeping: boolean(),
|
|
19851
19882
|
/** Current device state rendered over the cached frame. State images
|
|
19852
19883
|
* remain authoritative even when their photographic background is
|
|
19853
|
-
* old; null means the link must carry a current camera frame.
|
|
19884
|
+
* old; null means the link must carry a current camera frame.
|
|
19885
|
+
*
|
|
19886
|
+
* **This is the ONLY source a surface may derive an inactive tile
|
|
19887
|
+
* from.** A client that reads a device's `online`/`disabled` flags and
|
|
19888
|
+
* draws its own verdict will disagree with the pixels it is painting
|
|
19889
|
+
* — the frame comes from here, and so must the sentence over it
|
|
19890
|
+
* (D190). Pair with `ageMs` for the age of the photograph behind the
|
|
19891
|
+
* state. */
|
|
19854
19892
|
stateReason: _enum([
|
|
19855
19893
|
"disabled",
|
|
19894
|
+
"offline",
|
|
19856
19895
|
"sleeping",
|
|
19857
19896
|
"unreachable",
|
|
19858
19897
|
"waking"
|
|
@@ -26664,9 +26703,21 @@ var RecordingLocationUsageSchema = object({
|
|
|
26664
26703
|
* previously rendered as two identical "disks" with a nonsensical used
|
|
26665
26704
|
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
26666
26705
|
locationIds: array(string()).optional(),
|
|
26667
|
-
/**
|
|
26706
|
+
/**
|
|
26707
|
+
* Filesystem root of the physical volume this row accounts — the only
|
|
26708
|
+
* operator-legible identity when a location has no `displayName` yet, and
|
|
26709
|
+
* what a "which disk is full" alert has to name. OPTIONAL for the same
|
|
26710
|
+
* train-skew reason as `oldestMs`: a recorder that predates the field omits
|
|
26711
|
+
* it, and this schema must keep validating that older provider's payload.
|
|
26712
|
+
*/
|
|
26713
|
+
root: string().optional(),
|
|
26714
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). This is
|
|
26715
|
+
* the footage's SHARE of the volume, not how full the volume is — the disk
|
|
26716
|
+
* also holds everything that is not recordings. Volume fill is
|
|
26717
|
+
* `(totalBytes - availableBytes) / totalBytes`. */
|
|
26668
26718
|
usedBytes: number(),
|
|
26669
|
-
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26719
|
+
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26720
|
+
* (remote/unstattable — the recorder logs the statfs failure with the root). */
|
|
26670
26721
|
availableBytes: number().nullable(),
|
|
26671
26722
|
/** Total bytes of the location's volume; null when unknown. */
|
|
26672
26723
|
totalBytes: number().nullable()
|
|
@@ -26678,7 +26729,15 @@ var RecordingStorageUsageSchema = object({
|
|
|
26678
26729
|
nodeId: string(),
|
|
26679
26730
|
totalUsedBytes: number(),
|
|
26680
26731
|
devices: array(RecordingDeviceUsageSchema),
|
|
26681
|
-
|
|
26732
|
+
/**
|
|
26733
|
+
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
26734
|
+
* of the payload without it: the hub serves this method through a BAKED
|
|
26735
|
+
* router, so a hub whose framework train predates a change to this array
|
|
26736
|
+
* strips it out of an answer a newer recorder happily produced. A UI that
|
|
26737
|
+
* dereferences it unconditionally crashes the whole Storage page over a
|
|
26738
|
+
* missing disk bar.
|
|
26739
|
+
*/
|
|
26740
|
+
locations: array(RecordingLocationUsageSchema).optional()
|
|
26682
26741
|
});
|
|
26683
26742
|
/**
|
|
26684
26743
|
* The OPERATOR-ARMED half of multi-location recordings (D116).
|
|
@@ -37741,8 +37800,13 @@ Object.freeze({
|
|
|
37741
37800
|
"network-access": "ingress",
|
|
37742
37801
|
"smtp-provider": "email"
|
|
37743
37802
|
});
|
|
37744
|
-
|
|
37803
|
+
/** Schema defaults — an untouched sub-field must author exactly these. */
|
|
37804
|
+
var NC_AUDIO_DEFAULTS = {
|
|
37805
|
+
hitPercent: 60,
|
|
37806
|
+
samplingSeconds: 10
|
|
37807
|
+
};
|
|
37745
37808
|
new Set(["devices", "classes"]);
|
|
37809
|
+
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
37746
37810
|
/**
|
|
37747
37811
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
37748
37812
|
*
|
|
@@ -37974,6 +38038,39 @@ TimelapseRuleInputSchema.extend({
|
|
|
37974
38038
|
createdAt: number(),
|
|
37975
38039
|
updatedAt: number()
|
|
37976
38040
|
});
|
|
38041
|
+
Object.freeze(Object.fromEntries([{
|
|
38042
|
+
stepId: "face-embedding",
|
|
38043
|
+
label: "Face recognition model",
|
|
38044
|
+
defaultModelId: "arcface-r100",
|
|
38045
|
+
indexName: "the enrolled face gallery",
|
|
38046
|
+
options: [
|
|
38047
|
+
{
|
|
38048
|
+
id: "arcface-r100",
|
|
38049
|
+
label: "ArcFace (ResNet34)"
|
|
38050
|
+
},
|
|
38051
|
+
{
|
|
38052
|
+
id: "auraface-r100",
|
|
38053
|
+
label: "AuraFace R100"
|
|
38054
|
+
},
|
|
38055
|
+
{
|
|
38056
|
+
id: "inception-resnet-v1",
|
|
38057
|
+
label: "Inception ResNet V1"
|
|
38058
|
+
}
|
|
38059
|
+
]
|
|
38060
|
+
}, {
|
|
38061
|
+
stepId: "clip-embedding",
|
|
38062
|
+
label: "Semantic search model",
|
|
38063
|
+
defaultModelId: "mobileclip-s1",
|
|
38064
|
+
indexName: "the object semantic-search index",
|
|
38065
|
+
options: [{
|
|
38066
|
+
id: "mobileclip-s1",
|
|
38067
|
+
label: "MobileCLIP S1"
|
|
38068
|
+
}, {
|
|
38069
|
+
id: "mobileclip-s2",
|
|
38070
|
+
label: "MobileCLIP S2"
|
|
38071
|
+
}]
|
|
38072
|
+
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
38073
|
+
string().min(1);
|
|
37977
38074
|
object({
|
|
37978
38075
|
/**
|
|
37979
38076
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -37994,10 +38091,21 @@ object({
|
|
|
37994
38091
|
*/
|
|
37995
38092
|
square: boolean()
|
|
37996
38093
|
});
|
|
37997
|
-
|
|
38094
|
+
/**
|
|
38095
|
+
* The convention in force when nobody has configured one — byte-for-byte the
|
|
38096
|
+
* behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
|
|
38097
|
+
*/
|
|
38098
|
+
var DEFAULT_DETAIL_CROP_CONVENTION = {
|
|
37998
38099
|
paddingRatio: .15,
|
|
37999
38100
|
square: false
|
|
38000
|
-
}
|
|
38101
|
+
};
|
|
38102
|
+
Object.freeze({
|
|
38103
|
+
x: 0,
|
|
38104
|
+
y: 0,
|
|
38105
|
+
w: 1,
|
|
38106
|
+
h: 1
|
|
38107
|
+
});
|
|
38108
|
+
DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
|
|
38001
38109
|
/**
|
|
38002
38110
|
* WHICH delivered frames the decode worker retains a native copy of.
|
|
38003
38111
|
*
|