@camstack/addon-provider-reolink 1.2.131 → 1.2.133
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 +91 -40
- package/dist/addon.mjs +91 -40
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -20082,13 +20082,26 @@ var TrackAudioLabelSchema = object({
|
|
|
20082
20082
|
* - `audio` — an audio event on the camera itself that was anomalous for
|
|
20083
20083
|
* THAT camera, loud, and heard while nothing visual was happening (D62).
|
|
20084
20084
|
*
|
|
20085
|
+
* - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
|
|
20086
|
+
* that frame's pixel space. A real root detector and a SPATIAL one: its
|
|
20087
|
+
* boxes are the same kind of fact `pipeline`'s are, produced by a different
|
|
20088
|
+
* detector.
|
|
20089
|
+
*
|
|
20090
|
+
* `onboard` was missing here while `DetectionSourceSchema` already had it, so
|
|
20091
|
+
* a persisted onboard track failed `safeParse` on read and came back with NO
|
|
20092
|
+
* source at all — which `isSpatialTrack` then admitted by accident, through the
|
|
20093
|
+
* `undefined` arm rather than by anybody's decision, and which `excludeSources`
|
|
20094
|
+
* could not name.
|
|
20095
|
+
*
|
|
20085
20096
|
* The spatial subsystems (tracker association, occupancy count, re-id /
|
|
20086
20097
|
* embedding, resurrection) MUST skip every synthetic source. Test for that
|
|
20087
|
-
* with `isSpatialTrack`, which allow-lists
|
|
20088
|
-
* check silently readmits every source added after it was
|
|
20098
|
+
* with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
|
|
20099
|
+
* `!== 'sensor'` check silently readmits every source added after it was
|
|
20100
|
+
* written.
|
|
20089
20101
|
*/
|
|
20090
20102
|
var TrackSourceSchema = _enum([
|
|
20091
20103
|
"pipeline",
|
|
20104
|
+
"onboard",
|
|
20092
20105
|
"sensor",
|
|
20093
20106
|
"audio"
|
|
20094
20107
|
]);
|
|
@@ -20676,6 +20689,7 @@ var MediaFileKindEnum = _enum([
|
|
|
20676
20689
|
"keyFrame",
|
|
20677
20690
|
"keyFrameSmall",
|
|
20678
20691
|
"thumbnailSmall",
|
|
20692
|
+
"confirmationCrop",
|
|
20679
20693
|
"sceneFrame"
|
|
20680
20694
|
]);
|
|
20681
20695
|
/**
|
|
@@ -22170,13 +22184,39 @@ var MotionSourceEnum = _enum([
|
|
|
22170
22184
|
*/
|
|
22171
22185
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
22172
22186
|
/**
|
|
22173
|
-
* Which root
|
|
22174
|
-
*
|
|
22175
|
-
*
|
|
22176
|
-
*
|
|
22177
|
-
*
|
|
22187
|
+
* Which root detector a camera runs — EXACTLY ONE.
|
|
22188
|
+
*
|
|
22189
|
+
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
22190
|
+
* with (`DetectionSource`) rather than a second spelling of the same two
|
|
22191
|
+
* ideas: the value an operator picks here is the value that comes back on the
|
|
22192
|
+
* track, the overlay and the debug row.
|
|
22193
|
+
*
|
|
22194
|
+
* ## Why one, and why it is still an array
|
|
22195
|
+
*
|
|
22196
|
+
* Two roots on one camera is a capability nobody asked for and the operator has
|
|
22197
|
+
* since ruled out. It was never free: both planes feed the SAME per-device
|
|
22198
|
+
* stationary registry, both can promote the same parked object, and the two
|
|
22199
|
+
* detectors disagree about the same box by construction — which is the
|
|
22200
|
+
* disagreement D505 had to arbitrate. Removing the case removes the arbitration.
|
|
22201
|
+
*
|
|
22202
|
+
* The ARRAY shape survives because the stored settings and the attach payload
|
|
22203
|
+
* already speak it on every camera of every fleet, and a cap input that
|
|
22204
|
+
* suddenly refuses a stored value makes the camera un-attachable — a fail-closed
|
|
22205
|
+
* in the one direction that costs an operator their cameras. So the wire stays
|
|
22206
|
+
* tolerant and the TYPE is exact: a longer list is truncated to its first
|
|
22207
|
+
* element rather than refused, and `max(1)` is what every consumer can then
|
|
22208
|
+
* rely on.
|
|
22209
|
+
*
|
|
22210
|
+
* AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
|
|
22211
|
+
* a camera an operator left with no root detector — and `planDetectionSources`
|
|
22212
|
+
* has always said so: inventing a root for them is how a default acts without
|
|
22213
|
+
* anybody choosing it. Tightening this to `length(1)` broke that, and the
|
|
22214
|
+
* suite caught it.
|
|
22215
|
+
*
|
|
22216
|
+
* Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
|
|
22217
|
+
* `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
|
|
22178
22218
|
*/
|
|
22179
|
-
var DetectionSourcesSchema = array(DetectionSourceSchema);
|
|
22219
|
+
var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
|
|
22180
22220
|
/**
|
|
22181
22221
|
* Input shape for `pipeline-runner.reportMotion` cap method. Exported
|
|
22182
22222
|
* so cap-side consumers (the orchestrator forward, the runner addon's
|
|
@@ -145521,6 +145561,29 @@ function buildOsdSection(snapshot, values, opts) {
|
|
|
145521
145561
|
};
|
|
145522
145562
|
}
|
|
145523
145563
|
//#endregion
|
|
145564
|
+
//#region src/snapshot-wake-gate.ts
|
|
145565
|
+
/**
|
|
145566
|
+
* Decide whether a snapshot read may reach the camera's socket.
|
|
145567
|
+
*
|
|
145568
|
+
* Pure, and deliberately total: three inputs, no clock, no cooldown, no
|
|
145569
|
+
* fallible read (D49 — a gate that can be talked out of its answer by a
|
|
145570
|
+
* stale timestamp is not a gate).
|
|
145571
|
+
*/
|
|
145572
|
+
function decideSnapshotCameraAccess(input) {
|
|
145573
|
+
if (!input.isBattery || !input.sleeping) return {
|
|
145574
|
+
kind: "proceed",
|
|
145575
|
+
stampCooldown: false
|
|
145576
|
+
};
|
|
145577
|
+
if (!input.force) return {
|
|
145578
|
+
kind: "refuse",
|
|
145579
|
+
reason: "sleeping"
|
|
145580
|
+
};
|
|
145581
|
+
return {
|
|
145582
|
+
kind: "proceed",
|
|
145583
|
+
stampCooldown: true
|
|
145584
|
+
};
|
|
145585
|
+
}
|
|
145586
|
+
//#endregion
|
|
145524
145587
|
//#region src/raw-state.ts
|
|
145525
145588
|
/**
|
|
145526
145589
|
* Source tag for every raw-state blob this provider emits.
|
|
@@ -150315,9 +150378,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
150315
150378
|
}
|
|
150316
150379
|
registerNativeCapabilities() {
|
|
150317
150380
|
this.ctx.registerNativeCap(snapshotCapability, {
|
|
150318
|
-
getSnapshot: async ({ deviceId }) => {
|
|
150381
|
+
getSnapshot: async ({ deviceId, force }) => {
|
|
150319
150382
|
if (deviceId !== this.id) throw new Error(`ReolinkCamera: deviceId mismatch, expected ${this.id}, got ${deviceId}`);
|
|
150320
|
-
return this.fetchSnapshotWithSingleFlight();
|
|
150383
|
+
return this.fetchSnapshotWithSingleFlight(force === true);
|
|
150321
150384
|
},
|
|
150322
150385
|
invalidateCache: async () => {}
|
|
150323
150386
|
});
|
|
@@ -150760,33 +150823,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
150760
150823
|
status: this.state.battery
|
|
150761
150824
|
}));
|
|
150762
150825
|
}
|
|
150763
|
-
/**
|
|
150764
|
-
* Gate for a PROACTIVE camera read, checked BEFORE `ensureApi()`.
|
|
150765
|
-
*
|
|
150766
|
-
* The login itself is the wake. On a sleeping UDP/battery camera the
|
|
150767
|
-
* lib's discovery + handshake nudges the firmware awake (same reason
|
|
150768
|
-
* `refreshParentSettingsSnapshot` refuses to call `ensureApi` while
|
|
150769
|
-
* asleep), so gating only the explicit `wakeUp()` call is useless —
|
|
150770
|
-
* by the time we reach it the camera is already up. Production logs
|
|
150771
|
-
* showed exactly that: a background read produced a full
|
|
150772
|
-
* `Connecting to Reolink` → BCUDP discovery → `battery sleep state
|
|
150773
|
-
* committed` (awake) → whole refresh cascade, on a camera that had
|
|
150774
|
-
* been asleep for six minutes.
|
|
150775
|
-
*
|
|
150776
|
-
* Returns `false` when the caller must serve cache / bail out without
|
|
150777
|
-
* touching the socket. Stamps the cooldown when it does let a wake
|
|
150778
|
-
* through, so "at most one proactive wake per
|
|
150779
|
-
* `PROACTIVE_WAKE_COOLDOWN_MS`" holds across ALL proactive callers
|
|
150780
|
-
* rather than per-caller.
|
|
150781
|
-
*
|
|
150782
|
-
* Demand-driven paths never call this — see `canProactivelyWake`.
|
|
150783
|
-
*/
|
|
150784
|
-
allowProactiveCameraAccess(reason) {
|
|
150785
|
-
if (!this.isBattery || !this.sleeping) return true;
|
|
150786
|
-
if (!this.canProactivelyWake(reason)) return false;
|
|
150787
|
-
this.markWakeIssued();
|
|
150788
|
-
return true;
|
|
150789
|
-
}
|
|
150790
150826
|
updateBatteryCache(info) {
|
|
150791
150827
|
const mapped = this.mapBatteryInfo(info);
|
|
150792
150828
|
const now = Date.now();
|
|
@@ -151066,12 +151102,27 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
151066
151102
|
}
|
|
151067
151103
|
await this.refreshCameraEmailConfig().catch(() => {});
|
|
151068
151104
|
}
|
|
151069
|
-
|
|
151105
|
+
/**
|
|
151106
|
+
* @param force - the caller's `snapshot.getSnapshot({ force })`. THE gate:
|
|
151107
|
+
* without it a sleeping battery camera is never touched, whatever the
|
|
151108
|
+
* cache holds. See `snapshot-wake-gate.ts` for why the flag — and not a
|
|
151109
|
+
* cooldown — is what decides.
|
|
151110
|
+
*/
|
|
151111
|
+
async fetchSnapshotWithSingleFlight(force) {
|
|
151070
151112
|
if (this.snapshotInFlight) return this.snapshotInFlight;
|
|
151071
|
-
|
|
151072
|
-
|
|
151113
|
+
const access = decideSnapshotCameraAccess({
|
|
151114
|
+
isBattery: this.isBattery,
|
|
151115
|
+
sleeping: this.sleeping,
|
|
151116
|
+
force
|
|
151117
|
+
});
|
|
151118
|
+
if (access.kind === "refuse") {
|
|
151119
|
+
this.ctx.logger.info("snapshot: refused — battery cam asleep and no operator force", {
|
|
151120
|
+
tags: { deviceId: this.id },
|
|
151121
|
+
meta: { reason: access.reason }
|
|
151122
|
+
});
|
|
151073
151123
|
return null;
|
|
151074
151124
|
}
|
|
151125
|
+
if (access.stampCooldown) this.markWakeIssued();
|
|
151075
151126
|
const promise = (async () => {
|
|
151076
151127
|
let api;
|
|
151077
151128
|
try {
|
package/dist/addon.mjs
CHANGED
|
@@ -20077,13 +20077,26 @@ var TrackAudioLabelSchema = object({
|
|
|
20077
20077
|
* - `audio` — an audio event on the camera itself that was anomalous for
|
|
20078
20078
|
* THAT camera, loud, and heard while nothing visual was happening (D62).
|
|
20079
20079
|
*
|
|
20080
|
+
* - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
|
|
20081
|
+
* that frame's pixel space. A real root detector and a SPATIAL one: its
|
|
20082
|
+
* boxes are the same kind of fact `pipeline`'s are, produced by a different
|
|
20083
|
+
* detector.
|
|
20084
|
+
*
|
|
20085
|
+
* `onboard` was missing here while `DetectionSourceSchema` already had it, so
|
|
20086
|
+
* a persisted onboard track failed `safeParse` on read and came back with NO
|
|
20087
|
+
* source at all — which `isSpatialTrack` then admitted by accident, through the
|
|
20088
|
+
* `undefined` arm rather than by anybody's decision, and which `excludeSources`
|
|
20089
|
+
* could not name.
|
|
20090
|
+
*
|
|
20080
20091
|
* The spatial subsystems (tracker association, occupancy count, re-id /
|
|
20081
20092
|
* embedding, resurrection) MUST skip every synthetic source. Test for that
|
|
20082
|
-
* with `isSpatialTrack`, which allow-lists
|
|
20083
|
-
* check silently readmits every source added after it was
|
|
20093
|
+
* with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
|
|
20094
|
+
* `!== 'sensor'` check silently readmits every source added after it was
|
|
20095
|
+
* written.
|
|
20084
20096
|
*/
|
|
20085
20097
|
var TrackSourceSchema = _enum([
|
|
20086
20098
|
"pipeline",
|
|
20099
|
+
"onboard",
|
|
20087
20100
|
"sensor",
|
|
20088
20101
|
"audio"
|
|
20089
20102
|
]);
|
|
@@ -20671,6 +20684,7 @@ var MediaFileKindEnum = _enum([
|
|
|
20671
20684
|
"keyFrame",
|
|
20672
20685
|
"keyFrameSmall",
|
|
20673
20686
|
"thumbnailSmall",
|
|
20687
|
+
"confirmationCrop",
|
|
20674
20688
|
"sceneFrame"
|
|
20675
20689
|
]);
|
|
20676
20690
|
/**
|
|
@@ -22165,13 +22179,39 @@ var MotionSourceEnum = _enum([
|
|
|
22165
22179
|
*/
|
|
22166
22180
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
22167
22181
|
/**
|
|
22168
|
-
* Which root
|
|
22169
|
-
*
|
|
22170
|
-
*
|
|
22171
|
-
*
|
|
22172
|
-
*
|
|
22182
|
+
* Which root detector a camera runs — EXACTLY ONE.
|
|
22183
|
+
*
|
|
22184
|
+
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
22185
|
+
* with (`DetectionSource`) rather than a second spelling of the same two
|
|
22186
|
+
* ideas: the value an operator picks here is the value that comes back on the
|
|
22187
|
+
* track, the overlay and the debug row.
|
|
22188
|
+
*
|
|
22189
|
+
* ## Why one, and why it is still an array
|
|
22190
|
+
*
|
|
22191
|
+
* Two roots on one camera is a capability nobody asked for and the operator has
|
|
22192
|
+
* since ruled out. It was never free: both planes feed the SAME per-device
|
|
22193
|
+
* stationary registry, both can promote the same parked object, and the two
|
|
22194
|
+
* detectors disagree about the same box by construction — which is the
|
|
22195
|
+
* disagreement D505 had to arbitrate. Removing the case removes the arbitration.
|
|
22196
|
+
*
|
|
22197
|
+
* The ARRAY shape survives because the stored settings and the attach payload
|
|
22198
|
+
* already speak it on every camera of every fleet, and a cap input that
|
|
22199
|
+
* suddenly refuses a stored value makes the camera un-attachable — a fail-closed
|
|
22200
|
+
* in the one direction that costs an operator their cameras. So the wire stays
|
|
22201
|
+
* tolerant and the TYPE is exact: a longer list is truncated to its first
|
|
22202
|
+
* element rather than refused, and `max(1)` is what every consumer can then
|
|
22203
|
+
* rely on.
|
|
22204
|
+
*
|
|
22205
|
+
* AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
|
|
22206
|
+
* a camera an operator left with no root detector — and `planDetectionSources`
|
|
22207
|
+
* has always said so: inventing a root for them is how a default acts without
|
|
22208
|
+
* anybody choosing it. Tightening this to `length(1)` broke that, and the
|
|
22209
|
+
* suite caught it.
|
|
22210
|
+
*
|
|
22211
|
+
* Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
|
|
22212
|
+
* `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
|
|
22173
22213
|
*/
|
|
22174
|
-
var DetectionSourcesSchema = array(DetectionSourceSchema);
|
|
22214
|
+
var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
|
|
22175
22215
|
/**
|
|
22176
22216
|
* Input shape for `pipeline-runner.reportMotion` cap method. Exported
|
|
22177
22217
|
* so cap-side consumers (the orchestrator forward, the runner addon's
|
|
@@ -145516,6 +145556,29 @@ function buildOsdSection(snapshot, values, opts) {
|
|
|
145516
145556
|
};
|
|
145517
145557
|
}
|
|
145518
145558
|
//#endregion
|
|
145559
|
+
//#region src/snapshot-wake-gate.ts
|
|
145560
|
+
/**
|
|
145561
|
+
* Decide whether a snapshot read may reach the camera's socket.
|
|
145562
|
+
*
|
|
145563
|
+
* Pure, and deliberately total: three inputs, no clock, no cooldown, no
|
|
145564
|
+
* fallible read (D49 — a gate that can be talked out of its answer by a
|
|
145565
|
+
* stale timestamp is not a gate).
|
|
145566
|
+
*/
|
|
145567
|
+
function decideSnapshotCameraAccess(input) {
|
|
145568
|
+
if (!input.isBattery || !input.sleeping) return {
|
|
145569
|
+
kind: "proceed",
|
|
145570
|
+
stampCooldown: false
|
|
145571
|
+
};
|
|
145572
|
+
if (!input.force) return {
|
|
145573
|
+
kind: "refuse",
|
|
145574
|
+
reason: "sleeping"
|
|
145575
|
+
};
|
|
145576
|
+
return {
|
|
145577
|
+
kind: "proceed",
|
|
145578
|
+
stampCooldown: true
|
|
145579
|
+
};
|
|
145580
|
+
}
|
|
145581
|
+
//#endregion
|
|
145519
145582
|
//#region src/raw-state.ts
|
|
145520
145583
|
/**
|
|
145521
145584
|
* Source tag for every raw-state blob this provider emits.
|
|
@@ -150310,9 +150373,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
150310
150373
|
}
|
|
150311
150374
|
registerNativeCapabilities() {
|
|
150312
150375
|
this.ctx.registerNativeCap(snapshotCapability, {
|
|
150313
|
-
getSnapshot: async ({ deviceId }) => {
|
|
150376
|
+
getSnapshot: async ({ deviceId, force }) => {
|
|
150314
150377
|
if (deviceId !== this.id) throw new Error(`ReolinkCamera: deviceId mismatch, expected ${this.id}, got ${deviceId}`);
|
|
150315
|
-
return this.fetchSnapshotWithSingleFlight();
|
|
150378
|
+
return this.fetchSnapshotWithSingleFlight(force === true);
|
|
150316
150379
|
},
|
|
150317
150380
|
invalidateCache: async () => {}
|
|
150318
150381
|
});
|
|
@@ -150755,33 +150818,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
150755
150818
|
status: this.state.battery
|
|
150756
150819
|
}));
|
|
150757
150820
|
}
|
|
150758
|
-
/**
|
|
150759
|
-
* Gate for a PROACTIVE camera read, checked BEFORE `ensureApi()`.
|
|
150760
|
-
*
|
|
150761
|
-
* The login itself is the wake. On a sleeping UDP/battery camera the
|
|
150762
|
-
* lib's discovery + handshake nudges the firmware awake (same reason
|
|
150763
|
-
* `refreshParentSettingsSnapshot` refuses to call `ensureApi` while
|
|
150764
|
-
* asleep), so gating only the explicit `wakeUp()` call is useless —
|
|
150765
|
-
* by the time we reach it the camera is already up. Production logs
|
|
150766
|
-
* showed exactly that: a background read produced a full
|
|
150767
|
-
* `Connecting to Reolink` → BCUDP discovery → `battery sleep state
|
|
150768
|
-
* committed` (awake) → whole refresh cascade, on a camera that had
|
|
150769
|
-
* been asleep for six minutes.
|
|
150770
|
-
*
|
|
150771
|
-
* Returns `false` when the caller must serve cache / bail out without
|
|
150772
|
-
* touching the socket. Stamps the cooldown when it does let a wake
|
|
150773
|
-
* through, so "at most one proactive wake per
|
|
150774
|
-
* `PROACTIVE_WAKE_COOLDOWN_MS`" holds across ALL proactive callers
|
|
150775
|
-
* rather than per-caller.
|
|
150776
|
-
*
|
|
150777
|
-
* Demand-driven paths never call this — see `canProactivelyWake`.
|
|
150778
|
-
*/
|
|
150779
|
-
allowProactiveCameraAccess(reason) {
|
|
150780
|
-
if (!this.isBattery || !this.sleeping) return true;
|
|
150781
|
-
if (!this.canProactivelyWake(reason)) return false;
|
|
150782
|
-
this.markWakeIssued();
|
|
150783
|
-
return true;
|
|
150784
|
-
}
|
|
150785
150821
|
updateBatteryCache(info) {
|
|
150786
150822
|
const mapped = this.mapBatteryInfo(info);
|
|
150787
150823
|
const now = Date.now();
|
|
@@ -151061,12 +151097,27 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
151061
151097
|
}
|
|
151062
151098
|
await this.refreshCameraEmailConfig().catch(() => {});
|
|
151063
151099
|
}
|
|
151064
|
-
|
|
151100
|
+
/**
|
|
151101
|
+
* @param force - the caller's `snapshot.getSnapshot({ force })`. THE gate:
|
|
151102
|
+
* without it a sleeping battery camera is never touched, whatever the
|
|
151103
|
+
* cache holds. See `snapshot-wake-gate.ts` for why the flag — and not a
|
|
151104
|
+
* cooldown — is what decides.
|
|
151105
|
+
*/
|
|
151106
|
+
async fetchSnapshotWithSingleFlight(force) {
|
|
151065
151107
|
if (this.snapshotInFlight) return this.snapshotInFlight;
|
|
151066
|
-
|
|
151067
|
-
|
|
151108
|
+
const access = decideSnapshotCameraAccess({
|
|
151109
|
+
isBattery: this.isBattery,
|
|
151110
|
+
sleeping: this.sleeping,
|
|
151111
|
+
force
|
|
151112
|
+
});
|
|
151113
|
+
if (access.kind === "refuse") {
|
|
151114
|
+
this.ctx.logger.info("snapshot: refused — battery cam asleep and no operator force", {
|
|
151115
|
+
tags: { deviceId: this.id },
|
|
151116
|
+
meta: { reason: access.reason }
|
|
151117
|
+
});
|
|
151068
151118
|
return null;
|
|
151069
151119
|
}
|
|
151120
|
+
if (access.stampCooldown) this.markWakeIssued();
|
|
151070
151121
|
const promise = (async () => {
|
|
151071
151122
|
let api;
|
|
151072
151123
|
try {
|