velocious 1.0.376 → 1.0.378
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/README.md +13 -1
- package/build/src/background-jobs/main.d.ts +76 -3
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +263 -44
- package/build/src/background-jobs/store.d.ts +9 -0
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +28 -1
- package/build/src/configuration-types.d.ts +39 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +18 -1
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +10 -2
- package/build/src/database/table-data/table-column.d.ts.map +1 -1
- package/build/src/database/table-data/table-column.js +5 -1
- package/package.json +1 -1
|
@@ -4,6 +4,20 @@ import JsonSocket from "./json-socket.js";
|
|
|
4
4
|
import BackgroundJobsScheduler from "./scheduler.js";
|
|
5
5
|
import BackgroundJobsStore from "./store.js";
|
|
6
6
|
import Logger from "../logger.js";
|
|
7
|
+
/**
|
|
8
|
+
* Channel used by `background-jobs-main` to coordinate dispatch wake-ups
|
|
9
|
+
* across processes via Beacon. Workers do NOT subscribe to this channel
|
|
10
|
+
* — they already receive job-handoff messages on their JsonSocket to
|
|
11
|
+
* main; this channel exists so cross-process enqueues (or future
|
|
12
|
+
* multi-main deployments) can poke an idle main to drain.
|
|
13
|
+
*/
|
|
14
|
+
const DISPATCH_CHANNEL = "velocious-background-jobs-dispatch";
|
|
15
|
+
/**
|
|
16
|
+
* `setTimeout` is implemented with 32-bit signed delays on Node; passing
|
|
17
|
+
* anything larger silently clamps to 1ms and fires immediately. Cap the
|
|
18
|
+
* scheduled-job timer here and re-arm when it expires.
|
|
19
|
+
*/
|
|
20
|
+
const MAX_TIMER_MS = 2_147_483_647; // ~24.8 days
|
|
7
21
|
export default class BackgroundJobsMain {
|
|
8
22
|
/**
|
|
9
23
|
* @param {object} args - Options.
|
|
@@ -16,6 +30,8 @@ export default class BackgroundJobsMain {
|
|
|
16
30
|
const config = configuration.getBackgroundJobsConfig();
|
|
17
31
|
this.host = host || config.host;
|
|
18
32
|
this.port = typeof port === "number" ? port : config.port;
|
|
33
|
+
this.dispatchStrategy = config.dispatchStrategy;
|
|
34
|
+
this.pollIntervalMs = config.pollIntervalMs;
|
|
19
35
|
this.store = new BackgroundJobsStore({ configuration, databaseIdentifier: config.databaseIdentifier });
|
|
20
36
|
this.logger = new Logger(this);
|
|
21
37
|
/** @type {Set<JsonSocket>} */
|
|
@@ -25,17 +41,30 @@ export default class BackgroundJobsMain {
|
|
|
25
41
|
/** @type {net.Server | undefined} */
|
|
26
42
|
this.server = undefined;
|
|
27
43
|
/** @type {NodeJS.Timeout | undefined} */
|
|
28
|
-
this.
|
|
44
|
+
this._pollTimer = undefined;
|
|
45
|
+
/** @type {NodeJS.Timeout | undefined} */
|
|
46
|
+
this._scheduledTimer = undefined;
|
|
47
|
+
/** @type {NodeJS.Timeout | undefined} */
|
|
48
|
+
this._errorRetryTimer = undefined;
|
|
29
49
|
/** @type {NodeJS.Timeout | undefined} */
|
|
30
50
|
this._orphanTimer = undefined;
|
|
31
51
|
/** @type {BackgroundJobsScheduler | undefined} */
|
|
32
52
|
this.scheduler = undefined;
|
|
33
|
-
this.
|
|
53
|
+
this._draining = false;
|
|
54
|
+
this._redrainQueued = false;
|
|
55
|
+
this._stopped = false;
|
|
56
|
+
/** @type {(() => void) | undefined} */
|
|
57
|
+
this._unsubscribeBeacon = undefined;
|
|
58
|
+
/** @type {((...args: any[]) => void) | undefined} */
|
|
59
|
+
this._beaconConnectHandler = undefined;
|
|
60
|
+
/** @type {import("../beacon/client.js").default | import("../beacon/in-process-client.js").default | undefined} */
|
|
61
|
+
this._beaconClient = undefined;
|
|
34
62
|
}
|
|
35
63
|
/**
|
|
36
64
|
* @returns {Promise<void>} - Resolves when listening.
|
|
37
65
|
*/
|
|
38
66
|
async start() {
|
|
67
|
+
this._stopped = false;
|
|
39
68
|
this.configuration.setCurrent();
|
|
40
69
|
await this.configuration.initialize({ type: "background-jobs-main" });
|
|
41
70
|
await this.configuration.connectBeacon({ peerType: "background-jobs-main" });
|
|
@@ -51,9 +80,7 @@ export default class BackgroundJobsMain {
|
|
|
51
80
|
if (address && typeof address === "object") {
|
|
52
81
|
this.port = address.port;
|
|
53
82
|
}
|
|
54
|
-
this.
|
|
55
|
-
void this._dispatch();
|
|
56
|
-
}, 1000);
|
|
83
|
+
this._setupDispatchTriggers();
|
|
57
84
|
this._orphanTimer = setInterval(() => {
|
|
58
85
|
void this._sweepOrphans();
|
|
59
86
|
}, 60000);
|
|
@@ -65,10 +92,17 @@ export default class BackgroundJobsMain {
|
|
|
65
92
|
args,
|
|
66
93
|
options
|
|
67
94
|
});
|
|
68
|
-
|
|
95
|
+
this._notifyEnqueued();
|
|
96
|
+
await this._drain();
|
|
69
97
|
}
|
|
70
98
|
});
|
|
71
99
|
await this.scheduler.start();
|
|
100
|
+
// Startup catch-up: drain anything that was waiting before this
|
|
101
|
+
// process came up. In beacon mode this is also the safety net for
|
|
102
|
+
// races between attaching the connect listener and the initial
|
|
103
|
+
// connect firing (the listener could miss the very first connect,
|
|
104
|
+
// but this drain covers it).
|
|
105
|
+
await this._drain();
|
|
72
106
|
}
|
|
73
107
|
catch (error) {
|
|
74
108
|
await this.stop();
|
|
@@ -79,13 +113,31 @@ export default class BackgroundJobsMain {
|
|
|
79
113
|
* @returns {Promise<void>} - Resolves when closed.
|
|
80
114
|
*/
|
|
81
115
|
async stop() {
|
|
116
|
+
this._stopped = true;
|
|
82
117
|
for (const worker of this.workers) {
|
|
83
118
|
worker.close();
|
|
84
119
|
}
|
|
85
|
-
if (this.
|
|
86
|
-
clearInterval(this.
|
|
120
|
+
if (this._pollTimer)
|
|
121
|
+
clearInterval(this._pollTimer);
|
|
122
|
+
if (this._scheduledTimer)
|
|
123
|
+
clearTimeout(this._scheduledTimer);
|
|
124
|
+
if (this._errorRetryTimer)
|
|
125
|
+
clearTimeout(this._errorRetryTimer);
|
|
87
126
|
if (this._orphanTimer)
|
|
88
127
|
clearInterval(this._orphanTimer);
|
|
128
|
+
this._pollTimer = undefined;
|
|
129
|
+
this._scheduledTimer = undefined;
|
|
130
|
+
this._errorRetryTimer = undefined;
|
|
131
|
+
this._orphanTimer = undefined;
|
|
132
|
+
if (this._unsubscribeBeacon) {
|
|
133
|
+
this._unsubscribeBeacon();
|
|
134
|
+
this._unsubscribeBeacon = undefined;
|
|
135
|
+
}
|
|
136
|
+
if (this._beaconClient && this._beaconConnectHandler) {
|
|
137
|
+
this._beaconClient.off("connect", this._beaconConnectHandler);
|
|
138
|
+
}
|
|
139
|
+
this._beaconConnectHandler = undefined;
|
|
140
|
+
this._beaconClient = undefined;
|
|
89
141
|
this.scheduler?.stop();
|
|
90
142
|
await this.configuration.disconnectBeacon();
|
|
91
143
|
if (!this.server)
|
|
@@ -99,6 +151,65 @@ export default class BackgroundJobsMain {
|
|
|
99
151
|
getPort() {
|
|
100
152
|
return this.port;
|
|
101
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Wires up the dispatch-triggering signal sources for the configured
|
|
156
|
+
* strategy. In `"beacon"` mode (default) this means subscribing to the
|
|
157
|
+
* `velocious-background-jobs-dispatch` channel for cross-process
|
|
158
|
+
* wake-ups, listening for Beacon (re)connects to catch up on missed
|
|
159
|
+
* work, and relying on direct in-process calls from `_handleEnqueue`,
|
|
160
|
+
* `_handleJobComplete`/`Failed`, worker hello/ready, and the
|
|
161
|
+
* scheduled-job `setTimeout`. In `"polling"` mode we restore the
|
|
162
|
+
* legacy fixed-interval poll for users who want the previous behavior.
|
|
163
|
+
* @returns {void}
|
|
164
|
+
*/
|
|
165
|
+
_setupDispatchTriggers() {
|
|
166
|
+
if (this.dispatchStrategy === "polling") {
|
|
167
|
+
this._pollTimer = setInterval(() => {
|
|
168
|
+
void this._drain();
|
|
169
|
+
}, this.pollIntervalMs);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const beaconClient = this.configuration.getBeaconClient();
|
|
173
|
+
if (!beaconClient)
|
|
174
|
+
return;
|
|
175
|
+
this._beaconClient = beaconClient;
|
|
176
|
+
this._unsubscribeBeacon = beaconClient.onBroadcast((message) => {
|
|
177
|
+
if (message?.channel !== DISPATCH_CHANNEL)
|
|
178
|
+
return;
|
|
179
|
+
void this._drain();
|
|
180
|
+
});
|
|
181
|
+
// Drain on every (re)connect to catch up on jobs enqueued while the
|
|
182
|
+
// bus was unreachable. The DB is the durable log; Beacon is just the
|
|
183
|
+
// wake-up signal.
|
|
184
|
+
this._beaconConnectHandler = () => {
|
|
185
|
+
void this._drain();
|
|
186
|
+
};
|
|
187
|
+
beaconClient.on("connect", this._beaconConnectHandler);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Publishes a dispatch wake-up on the Beacon channel. No-op in polling
|
|
191
|
+
* mode or when Beacon is not connected; in those cases the direct
|
|
192
|
+
* in-process `_drain()` call in the enqueue/handle paths is sufficient
|
|
193
|
+
* (there are no other processes to notify).
|
|
194
|
+
* @returns {void}
|
|
195
|
+
*/
|
|
196
|
+
_notifyEnqueued() {
|
|
197
|
+
if (this.dispatchStrategy === "polling")
|
|
198
|
+
return;
|
|
199
|
+
const beaconClient = this.configuration.getBeaconClient();
|
|
200
|
+
if (!beaconClient || !beaconClient.isConnected())
|
|
201
|
+
return;
|
|
202
|
+
try {
|
|
203
|
+
beaconClient.publish({
|
|
204
|
+
channel: DISPATCH_CHANNEL,
|
|
205
|
+
broadcastParams: {},
|
|
206
|
+
body: { action: "wake" }
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
this.logger.warn(() => ["Failed to publish background jobs wake broadcast:", error]);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
102
213
|
/**
|
|
103
214
|
* @param {import("net").Socket} socket - Socket.
|
|
104
215
|
* @returns {void}
|
|
@@ -126,7 +237,7 @@ export default class BackgroundJobsMain {
|
|
|
126
237
|
jsonSocket.workerId = message.workerId;
|
|
127
238
|
this.workers.add(jsonSocket);
|
|
128
239
|
this.readyWorkers.add(jsonSocket);
|
|
129
|
-
this.
|
|
240
|
+
void this._drain();
|
|
130
241
|
}
|
|
131
242
|
return;
|
|
132
243
|
}
|
|
@@ -136,7 +247,7 @@ export default class BackgroundJobsMain {
|
|
|
136
247
|
}
|
|
137
248
|
if (role === "worker" && message?.type === "ready") {
|
|
138
249
|
this.readyWorkers.add(jsonSocket);
|
|
139
|
-
this.
|
|
250
|
+
void this._drain();
|
|
140
251
|
return;
|
|
141
252
|
}
|
|
142
253
|
if (role === "worker" && message?.type === "draining") {
|
|
@@ -169,7 +280,8 @@ export default class BackgroundJobsMain {
|
|
|
169
280
|
options: message.options || {}
|
|
170
281
|
});
|
|
171
282
|
jsonSocket.send({ type: "enqueued", jobId });
|
|
172
|
-
|
|
283
|
+
this._notifyEnqueued();
|
|
284
|
+
await this._drain();
|
|
173
285
|
}
|
|
174
286
|
catch (error) {
|
|
175
287
|
this.logger.error(() => ["Failed to enqueue background job:", error]);
|
|
@@ -211,60 +323,167 @@ export default class BackgroundJobsMain {
|
|
|
211
323
|
handedOffAtMs: message.handedOffAtMs
|
|
212
324
|
});
|
|
213
325
|
jsonSocket.send({ type: "job-updated", jobId: message.jobId });
|
|
214
|
-
|
|
326
|
+
// A failed job may have been re-queued (with backoff) for retry —
|
|
327
|
+
// poke the dispatcher so the retry timer is armed.
|
|
328
|
+
this._notifyEnqueued();
|
|
329
|
+
await this._drain();
|
|
215
330
|
}
|
|
216
331
|
catch (error) {
|
|
217
332
|
this.logger.error(() => ["Failed to update job failure:", error]);
|
|
218
333
|
jsonSocket.send({ type: "job-update-error", jobId: message.jobId, error: "Failed to update job" });
|
|
219
334
|
}
|
|
220
335
|
}
|
|
221
|
-
|
|
222
|
-
|
|
336
|
+
/**
|
|
337
|
+
* Drains all dispatchable jobs to ready workers, then arms the
|
|
338
|
+
* scheduled-job timer for the next future `scheduled_at_ms`. Coalesces
|
|
339
|
+
* concurrent triggers: a wake-up that lands while a drain is in
|
|
340
|
+
* flight just sets a re-drain flag and lets the in-flight drain
|
|
341
|
+
* re-loop after it finishes, so no signal is dropped but no two
|
|
342
|
+
* drains run in parallel.
|
|
343
|
+
*
|
|
344
|
+
* Resilience: in beacon mode this is the sole wake-up path for
|
|
345
|
+
* already-queued work, so a transient DB error during the drain (e.g.
|
|
346
|
+
* `nextAvailableJob()` rejecting) must not strand the queue until the
|
|
347
|
+
* next external signal. On any error we log it and arm a one-shot
|
|
348
|
+
* retry via `_scheduleErrorRetry` using `pollIntervalMs` as the
|
|
349
|
+
* cadence; on success the retry timer is cleared. Polling-mode runs
|
|
350
|
+
* `_drain` from its own interval, so the retry timer is a no-op there.
|
|
351
|
+
* @returns {Promise<void>}
|
|
352
|
+
*/
|
|
353
|
+
async _drain() {
|
|
354
|
+
if (this._stopped)
|
|
223
355
|
return;
|
|
224
|
-
if (this.
|
|
356
|
+
if (this._draining) {
|
|
357
|
+
this._redrainQueued = true;
|
|
225
358
|
return;
|
|
226
|
-
|
|
359
|
+
}
|
|
360
|
+
this._draining = true;
|
|
361
|
+
let errored = false;
|
|
227
362
|
try {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (!job)
|
|
231
|
-
return;
|
|
232
|
-
const [worker] = this.readyWorkers;
|
|
233
|
-
if (!worker)
|
|
234
|
-
return;
|
|
235
|
-
this.readyWorkers.delete(worker);
|
|
236
|
-
const handedOffAtMs = await this.store.markHandedOff({ jobId: job.id, workerId: worker.workerId });
|
|
363
|
+
do {
|
|
364
|
+
this._redrainQueued = false;
|
|
237
365
|
try {
|
|
238
|
-
|
|
239
|
-
type: "job",
|
|
240
|
-
payload: {
|
|
241
|
-
id: job.id,
|
|
242
|
-
jobName: job.jobName,
|
|
243
|
-
args: job.args,
|
|
244
|
-
workerId: worker.workerId,
|
|
245
|
-
handedOffAtMs,
|
|
246
|
-
options: {
|
|
247
|
-
forked: job.forked
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
});
|
|
366
|
+
await this._drainOnce();
|
|
251
367
|
}
|
|
252
368
|
catch (error) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
369
|
+
errored = true;
|
|
370
|
+
this.logger.error(() => ["Background jobs drain failed:", error]);
|
|
371
|
+
break;
|
|
256
372
|
}
|
|
257
|
-
}
|
|
373
|
+
} while (this._redrainQueued && !this._stopped);
|
|
258
374
|
}
|
|
259
375
|
finally {
|
|
260
|
-
this.
|
|
376
|
+
this._draining = false;
|
|
261
377
|
}
|
|
378
|
+
if (this._stopped)
|
|
379
|
+
return;
|
|
380
|
+
if (errored) {
|
|
381
|
+
this._scheduleErrorRetry();
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
await this._armScheduledTimer();
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
this.logger.error(() => ["Background jobs scheduled-timer arming failed:", error]);
|
|
389
|
+
this._scheduleErrorRetry();
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
if (this._errorRetryTimer) {
|
|
393
|
+
clearTimeout(this._errorRetryTimer);
|
|
394
|
+
this._errorRetryTimer = undefined;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Arms a one-shot `setTimeout` to retry `_drain` after a transient
|
|
399
|
+
* failure. Idempotent — repeated calls while a retry is already
|
|
400
|
+
* pending are no-ops. Polling mode already retries via its own
|
|
401
|
+
* interval, so this is a no-op in that mode.
|
|
402
|
+
* @returns {void}
|
|
403
|
+
*/
|
|
404
|
+
_scheduleErrorRetry() {
|
|
405
|
+
if (this._stopped)
|
|
406
|
+
return;
|
|
407
|
+
if (this._errorRetryTimer)
|
|
408
|
+
return;
|
|
409
|
+
if (this.dispatchStrategy === "polling")
|
|
410
|
+
return;
|
|
411
|
+
this._errorRetryTimer = setTimeout(() => {
|
|
412
|
+
this._errorRetryTimer = undefined;
|
|
413
|
+
void this._drain();
|
|
414
|
+
}, this.pollIntervalMs);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Inner drain loop: pulls eligible queued jobs and hands them off to
|
|
418
|
+
* ready workers until one of them runs out.
|
|
419
|
+
* @returns {Promise<void>}
|
|
420
|
+
*/
|
|
421
|
+
async _drainOnce() {
|
|
422
|
+
while (this.readyWorkers.size > 0 && !this._stopped) {
|
|
423
|
+
const job = await this.store.nextAvailableJob();
|
|
424
|
+
if (!job)
|
|
425
|
+
return;
|
|
426
|
+
const [worker] = this.readyWorkers;
|
|
427
|
+
if (!worker)
|
|
428
|
+
return;
|
|
429
|
+
this.readyWorkers.delete(worker);
|
|
430
|
+
const handedOffAtMs = await this.store.markHandedOff({ jobId: job.id, workerId: worker.workerId });
|
|
431
|
+
try {
|
|
432
|
+
worker.send({
|
|
433
|
+
type: "job",
|
|
434
|
+
payload: {
|
|
435
|
+
id: job.id,
|
|
436
|
+
jobName: job.jobName,
|
|
437
|
+
args: job.args,
|
|
438
|
+
workerId: worker.workerId,
|
|
439
|
+
handedOffAtMs,
|
|
440
|
+
options: {
|
|
441
|
+
forked: job.forked
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
this.logger.warn(() => ["Failed to send job to worker, re-queueing:", error]);
|
|
448
|
+
await this.store.markReturnedToQueue({ jobId: job.id });
|
|
449
|
+
this.readyWorkers.add(worker);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Arms a single `setTimeout` for the soonest future-scheduled job's
|
|
455
|
+
* `scheduled_at_ms`. Replaces the second responsibility of the legacy
|
|
456
|
+
* 1-second poll (becoming-eligible scheduled jobs). The timer is
|
|
457
|
+
* idempotently re-armed at the end of every drain.
|
|
458
|
+
* @returns {Promise<void>}
|
|
459
|
+
*/
|
|
460
|
+
async _armScheduledTimer() {
|
|
461
|
+
if (this._scheduledTimer) {
|
|
462
|
+
clearTimeout(this._scheduledTimer);
|
|
463
|
+
this._scheduledTimer = undefined;
|
|
464
|
+
}
|
|
465
|
+
if (this._stopped)
|
|
466
|
+
return;
|
|
467
|
+
if (this.dispatchStrategy === "polling")
|
|
468
|
+
return;
|
|
469
|
+
const next = await this.store.nextScheduledJob();
|
|
470
|
+
if (!next || typeof next.scheduledAtMs !== "number")
|
|
471
|
+
return;
|
|
472
|
+
const delay = Math.max(0, Math.min(next.scheduledAtMs - Date.now(), MAX_TIMER_MS));
|
|
473
|
+
this._scheduledTimer = setTimeout(() => {
|
|
474
|
+
this._scheduledTimer = undefined;
|
|
475
|
+
void this._drain();
|
|
476
|
+
}, delay);
|
|
262
477
|
}
|
|
263
478
|
async _sweepOrphans() {
|
|
264
479
|
try {
|
|
265
480
|
const count = await this.store.markOrphanedJobs();
|
|
266
481
|
if (count > 0) {
|
|
267
482
|
this.logger.warn(() => ["Marked orphaned background jobs", count]);
|
|
483
|
+
// Reclaimed orphans become `queued` again — wake the dispatcher
|
|
484
|
+
// so they aren't stranded until the next external signal.
|
|
485
|
+
this._notifyEnqueued();
|
|
486
|
+
await this._drain();
|
|
268
487
|
}
|
|
269
488
|
}
|
|
270
489
|
catch (error) {
|
|
@@ -272,4 +491,4 @@ export default class BackgroundJobsMain {
|
|
|
272
491
|
}
|
|
273
492
|
}
|
|
274
493
|
}
|
|
275
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZ3JvdW5kLWpvYnMvbWFpbi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFBO0FBQ3JCLE9BQU8sVUFBVSxNQUFNLGtCQUFrQixDQUFBO0FBQ3pDLE9BQU8sdUJBQXVCLE1BQU0sZ0JBQWdCLENBQUE7QUFDcEQsT0FBTyxtQkFBbUIsTUFBTSxZQUFZLENBQUE7QUFDNUMsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBRWpDLE1BQU0sQ0FBQyxPQUFPLE9BQU8sa0JBQWtCO0lBQ3JDOzs7OztPQUtHO0lBQ0gsWUFBWSxFQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFDO1FBQ3JDLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyx1QkFBdUIsRUFBRSxDQUFBO1FBQ3RELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUE7UUFDL0IsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQTtRQUN6RCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksbUJBQW1CLENBQUMsRUFBQyxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxDQUFDLGtCQUFrQixFQUFDLENBQUMsQ0FBQTtRQUNwRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlCLDhCQUE4QjtRQUM5QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7UUFDeEIsOEJBQThCO1FBQzlCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FB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QUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUE7Z0JBQy9CLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUE7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYTtRQUNqQixJQUFJLENBQUM7WUFDSCxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtZQUVqRCxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDZCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLGlDQUFpQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUE7WUFDcEUsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQywrQkFBK0IsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQ25FLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IG5ldCBmcm9tIFwibmV0XCJcbmltcG9ydCBKc29uU29ja2V0IGZyb20gXCIuL2pzb24tc29ja2V0LmpzXCJcbmltcG9ydCBCYWNrZ3JvdW5kSm9ic1NjaGVkdWxlciBmcm9tIFwiLi9zY2hlZHVsZXIuanNcIlxuaW1wb3J0IEJhY2tncm91bmRKb2JzU3RvcmUgZnJvbSBcIi4vc3RvcmUuanNcIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi4vbG9nZ2VyLmpzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmFja2dyb3VuZEpvYnNNYWluIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5ob3N0XSAtIEhvc3RuYW1lLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MucG9ydF0gLSBQb3J0LlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGhvc3QsIHBvcnR9KSB7XG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIGNvbnN0IGNvbmZpZyA9IGNvbmZpZ3VyYXRpb24uZ2V0QmFja2dyb3VuZEpvYnNDb25maWcoKVxuICAgIHRoaXMuaG9zdCA9IGhvc3QgfHwgY29uZmlnLmhvc3RcbiAgICB0aGlzLnBvcnQgPSB0eXBlb2YgcG9ydCA9PT0gXCJudW1iZXJcIiA/IHBvcnQgOiBjb25maWcucG9ydFxuICAgIHRoaXMuc3RvcmUgPSBuZXcgQmFja2dyb3VuZEpvYnNTdG9yZSh7Y29uZmlndXJhdGlvbiwgZGF0YWJhc2VJZGVudGlmaWVyOiBjb25maWcuZGF0YWJhc2VJZGVudGlmaWVyfSlcbiAgICB0aGlzLmxvZ2dlciA9IG5ldyBMb2dnZXIodGhpcylcbiAgICAvKiogQHR5cGUge1NldDxKc29uU29ja2V0Pn0gKi9cbiAgICB0aGlzLndvcmtlcnMgPSBuZXcgU2V0KClcbiAgICAvKiogQHR5cGUge1NldDxKc29uU29ja2V0Pn0gKi9cbiAgICB0aGlzLnJlYWR5V29ya2VycyA9IG5ldyBTZXQoKVxuICAgIC8qKiBAdHlwZSB7bmV0LlNlcnZlciB8IHVuZGVmaW5lZH0gKi9cbiAgICB0aGlzLnNlcnZlciA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7Tm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5fZGlzcGF0Y2hUaW1lciA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7Tm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5fb3JwaGFuVGltZXIgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge0JhY2tncm91bmRKb2JzU2NoZWR1bGVyIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuc2NoZWR1bGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fZGlzcGF0Y2hpbmcgPSBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gbGlzdGVuaW5nLlxuICAgKi9cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgdGhpcy5jb25maWd1cmF0aW9uLnNldEN1cnJlbnQoKVxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5pbml0aWFsaXplKHt0eXBlOiBcImJhY2tncm91bmQtam9icy1tYWluXCJ9KVxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5jb25uZWN0QmVhY29uKHtwZWVyVHlwZTogXCJiYWNrZ3JvdW5kLWpvYnMtbWFpblwifSlcbiAgICBhd2FpdCB0aGlzLnN0b3JlLmVuc3VyZVJlYWR5KClcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXQuY3JlYXRlU2VydmVyKChzb2NrZXQpID0+IHRoaXMuX2hhbmRsZUNvbm5lY3Rpb24oc29ja2V0KSlcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlclxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgc2VydmVyLm9uY2UoXCJlcnJvclwiLCByZWplY3QpXG4gICAgICAgIHNlcnZlci5saXN0ZW4odGhpcy5wb3J0LCB0aGlzLmhvc3QsICgpID0+IHJlc29sdmUodW5kZWZpbmVkKSlcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpXG4gICAgICBpZiAoYWRkcmVzcyAmJiB0eXBlb2YgYWRkcmVzcyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aGlzLnBvcnQgPSBhZGRyZXNzLnBvcnRcbiAgICAgIH1cblxuICAgICAgdGhpcy5fZGlzcGF0Y2hUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgdm9pZCB0aGlzLl9kaXNwYXRjaCgpXG4gICAgICB9LCAxMDAwKVxuXG4gICAgICB0aGlzLl9vcnBoYW5UaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgdm9pZCB0aGlzLl9zd2VlcE9ycGhhbnMoKVxuICAgICAgfSwgNjAwMDApXG5cbiAgICAgIHRoaXMuc2NoZWR1bGVyID0gbmV3IEJhY2tncm91bmRKb2JzU2NoZWR1bGVyKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICBlbnF1ZXVlSm9iOiBhc3luYyAoe2FyZ3MsIGpvYkNsYXNzLCBvcHRpb25zfSkgPT4ge1xuICAgICAgICAgIGF3YWl0IHRoaXMuc3RvcmUuZW5xdWV1ZSh7XG4gICAgICAgICAgICBqb2JOYW1lOiBqb2JDbGFzcy5qb2JOYW1lKCksXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICAgIH0pXG4gICAgICAgICAgYXdhaXQgdGhpcy5fZGlzcGF0Y2goKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgYXdhaXQgdGhpcy5zY2hlZHVsZXIuc3RhcnQoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3AoKVxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjbG9zZWQuXG4gICAqL1xuICBhc3luYyBzdG9wKCkge1xuICAgIGZvciAoY29uc3Qgd29ya2VyIG9mIHRoaXMud29ya2Vycykge1xuICAgICAgd29ya2VyLmNsb3NlKClcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZGlzcGF0Y2hUaW1lcikgY2xlYXJJbnRlcnZhbCh0aGlzLl9kaXNwYXRjaFRpbWVyKVxuICAgIGlmICh0aGlzLl9vcnBoYW5UaW1lcikgY2xlYXJJbnRlcnZhbCh0aGlzLl9vcnBoYW5UaW1lcilcbiAgICB0aGlzLnNjaGVkdWxlcj8uc3RvcCgpXG5cbiAgICBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZGlzY29ubmVjdEJlYWNvbigpXG5cbiAgICBpZiAoIXRoaXMuc2VydmVyKSByZXR1cm5cblxuICAgIGNvbnN0IHtzZXJ2ZXJ9ID0gdGhpc1xuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXJ2ZXIuY2xvc2UoKCkgPT4gcmVzb2x2ZSh1bmRlZmluZWQpKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIEJvdW5kIHBvcnQuXG4gICAqL1xuICBnZXRQb3J0KCkge1xuICAgIHJldHVybiB0aGlzLnBvcnRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIm5ldFwiKS5Tb2NrZXR9IHNvY2tldCAtIFNvY2tldC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBfaGFuZGxlQ29ubmVjdGlvbihzb2NrZXQpIHtcbiAgICBjb25zdCBqc29uU29ja2V0ID0gbmV3IEpzb25Tb2NrZXQoc29ja2V0KVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iU29ja2V0Um9sZSB8IG51bGx9ICovXG4gICAgbGV0IHJvbGUgPSBudWxsXG5cbiAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgaWYgKHJvbGUgPT09IFwid29ya2VyXCIpIHtcbiAgICAgICAgdGhpcy53b3JrZXJzLmRlbGV0ZShqc29uU29ja2V0KVxuICAgICAgICB0aGlzLnJlYWR5V29ya2Vycy5kZWxldGUoanNvblNvY2tldClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBqc29uU29ja2V0Lm9uKFwiY2xvc2VcIiwgY2xlYW51cClcbiAgICBqc29uU29ja2V0Lm9uKFwiZXJyb3JcIiwgKGVycm9yKSA9PiB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtcIkJhY2tncm91bmQgam9icyBjb25uZWN0aW9uIGVycm9yOlwiLCBlcnJvcl0pXG4gICAgICBjbGVhbnVwKClcbiAgICB9KVxuXG4gICAgLyoqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iU29ja2V0TWVzc2FnZX0gbWVzc2FnZSAtIFNvY2tldCBtZXNzYWdlLiAqL1xuICAgIGpzb25Tb2NrZXQub24oXCJtZXNzYWdlXCIsIChtZXNzYWdlKSA9PiB7XG4gICAgICBpZiAoIXJvbGUgJiYgbWVzc2FnZT8udHlwZSA9PT0gXCJoZWxsb1wiKSB7XG4gICAgICAgIHJvbGUgPSBtZXNzYWdlLnJvbGVcblxuICAgICAgICBpZiAocm9sZSA9PT0gXCJ3b3JrZXJcIikge1xuICAgICAgICAgIGpzb25Tb2NrZXQud29ya2VySWQgPSBtZXNzYWdlLndvcmtlcklkXG4gICAgICAgICAgdGhpcy53b3JrZXJzLmFkZChqc29uU29ja2V0KVxuICAgICAgICAgIHRoaXMucmVhZHlXb3JrZXJzLmFkZChqc29uU29ja2V0KVxuICAgICAgICAgIHRoaXMuX2Rpc3BhdGNoKClcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAocm9sZSA9PT0gXCJjbGllbnRcIiAmJiBtZXNzYWdlPy50eXBlID09PSBcImVucXVldWVcIikge1xuICAgICAgICB0aGlzLl9oYW5kbGVFbnF1ZXVlKHtqc29uU29ja2V0LCBtZXNzYWdlfSlcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmIChyb2xlID09PSBcIndvcmtlclwiICYmIG1lc3NhZ2U/LnR5cGUgPT09IFwicmVhZHlcIikge1xuICAgICAgICB0aGlzLnJlYWR5V29ya2Vycy5hZGQoanNvblNvY2tldClcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKHJvbGUgPT09IFwid29ya2VyXCIgJiYgbWVzc2FnZT8udHlwZSA9PT0gXCJkcmFpbmluZ1wiKSB7XG4gICAgICAgIC8vIFRoZSB3b3JrZXIgaXMgc2h1dHRpbmcgZG93biBncmFjZWZ1bGx5LiBTdG9wIGRpc3BhdGNoaW5nIG5ldyBqb2JzXG4gICAgICAgIC8vIHRvIGl0IGJ1dCBrZWVwIHRoZSBjb25uZWN0aW9uIGluIGB3b3JrZXJzYCBzbyBhbnkgaW4tZmxpZ2h0IGpvYlxuICAgICAgICAvLyBpdCdzIHN0aWxsIGRyYWluaW5nIGNhbiByZXBvcnQgaXRzIHJlc3VsdC5cbiAgICAgICAgdGhpcy5yZWFkeVdvcmtlcnMuZGVsZXRlKGpzb25Tb2NrZXQpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAoKHJvbGUgPT09IFwid29ya2VyXCIgfHwgcm9sZSA9PT0gXCJyZXBvcnRlclwiKSAmJiBtZXNzYWdlPy50eXBlID09PSBcImpvYi1jb21wbGV0ZVwiKSB7XG4gICAgICAgIHRoaXMuX2hhbmRsZUpvYkNvbXBsZXRlKHtqc29uU29ja2V0LCBtZXNzYWdlfSlcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmICgocm9sZSA9PT0gXCJ3b3JrZXJcIiB8fCByb2xlID09PSBcInJlcG9ydGVyXCIpICYmIG1lc3NhZ2U/LnR5cGUgPT09IFwiam9iLWZhaWxlZFwiKSB7XG4gICAgICAgIHRoaXMuX2hhbmRsZUpvYkZhaWxlZCh7anNvblNvY2tldCwgbWVzc2FnZX0pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7SnNvblNvY2tldH0gYXJncy5qc29uU29ja2V0IC0gSlNPTiBzb2NrZXQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iRW5xdWV1ZU1lc3NhZ2V9IGFyZ3MubWVzc2FnZSAtIE1lc3NhZ2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gaGFuZGxlZC5cbiAgICovXG4gIGFzeW5jIF9oYW5kbGVFbnF1ZXVlKHtqc29uU29ja2V0LCBtZXNzYWdlfSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBqb2JJZCA9IGF3YWl0IHRoaXMuc3RvcmUuZW5xdWV1ZSh7XG4gICAgICAgIGpvYk5hbWU6IG1lc3NhZ2Uuam9iTmFtZSxcbiAgICAgICAgYXJnczogbWVzc2FnZS5hcmdzIHx8IFtdLFxuICAgICAgICBvcHRpb25zOiBtZXNzYWdlLm9wdGlvbnMgfHwge31cbiAgICAgIH0pXG5cbiAgICAgIGpzb25Tb2NrZXQuc2VuZCh7dHlwZTogXCJlbnF1ZXVlZFwiLCBqb2JJZH0pXG4gICAgICBhd2FpdCB0aGlzLl9kaXNwYXRjaCgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCgpID0+IFtcIkZhaWxlZCB0byBlbnF1ZXVlIGJhY2tncm91bmQgam9iOlwiLCBlcnJvcl0pXG4gICAgICBqc29uU29ja2V0LnNlbmQoe3R5cGU6IFwiZW5xdWV1ZS1lcnJvclwiLCBlcnJvcjogXCJGYWlsZWQgdG8gZW5xdWV1ZSBqb2JcIn0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtKc29uU29ja2V0fSBhcmdzLmpzb25Tb2NrZXQgLSBKU09OIHNvY2tldC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJhY2tncm91bmRKb2JDb21wbGV0ZU1lc3NhZ2V9IGFyZ3MubWVzc2FnZSAtIE1lc3NhZ2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gaGFuZGxlZC5cbiAgICovXG4gIGFzeW5jIF9oYW5kbGVKb2JDb21wbGV0ZSh7anNvblNvY2tldCwgbWVzc2FnZX0pIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zdG9yZS5tYXJrQ29tcGxldGVkKHtcbiAgICAgICAgam9iSWQ6IG1lc3NhZ2Uuam9iSWQsXG4gICAgICAgIHdvcmtlcklkOiBtZXNzYWdlLndvcmtlcklkLFxuICAgICAgICBoYW5kZWRPZmZBdE1zOiBtZXNzYWdlLmhhbmRlZE9mZkF0TXNcbiAgICAgIH0pXG4gICAgICBqc29uU29ja2V0LnNlbmQoe3R5cGU6IFwiam9iLXVwZGF0ZWRcIiwgam9iSWQ6IG1lc3NhZ2Uuam9iSWR9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcigoKSA9PiBbXCJGYWlsZWQgdG8gdXBkYXRlIGpvYiBjb21wbGV0aW9uOlwiLCBlcnJvcl0pXG4gICAgICBqc29uU29ja2V0LnNlbmQoe3R5cGU6IFwiam9iLXVwZGF0ZS1lcnJvclwiLCBqb2JJZDogbWVzc2FnZS5qb2JJZCwgZXJyb3I6IFwiRmFpbGVkIHRvIHVwZGF0ZSBqb2JcIn0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtKc29uU29ja2V0fSBhcmdzLmpzb25Tb2NrZXQgLSBKU09OIHNvY2tldC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJhY2tncm91bmRKb2JGYWlsZWRNZXNzYWdlfSBhcmdzLm1lc3NhZ2UgLSBNZXNzYWdlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyBfaGFuZGxlSm9iRmFpbGVkKHtqc29uU29ja2V0LCBtZXNzYWdlfSkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3JlLm1hcmtGYWlsZWQoe1xuICAgICAgICBqb2JJZDogbWVzc2FnZS5qb2JJZCxcbiAgICAgICAgZXJyb3I6IG1lc3NhZ2UuZXJyb3IsXG4gICAgICAgIHdvcmtlcklkOiBtZXNzYWdlLndvcmtlcklkLFxuICAgICAgICBoYW5kZWRPZmZBdE1zOiBtZXNzYWdlLmhhbmRlZE9mZkF0TXNcbiAgICAgIH0pXG4gICAgICBqc29uU29ja2V0LnNlbmQoe3R5cGU6IFwiam9iLXVwZGF0ZWRcIiwgam9iSWQ6IG1lc3NhZ2Uuam9iSWR9KVxuICAgICAgYXdhaXQgdGhpcy5fZGlzcGF0Y2goKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcigoKSA9PiBbXCJGYWlsZWQgdG8gdXBkYXRlIGpvYiBmYWlsdXJlOlwiLCBlcnJvcl0pXG4gICAgICBqc29uU29ja2V0LnNlbmQoe3R5cGU6IFwiam9iLXVwZGF0ZS1lcnJvclwiLCBqb2JJZDogbWVzc2FnZS5qb2JJZCwgZXJyb3I6IFwiRmFpbGVkIHRvIHVwZGF0ZSBqb2JcIn0pXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgX2Rpc3BhdGNoKCkge1xuICAgIGlmICh0aGlzLl9kaXNwYXRjaGluZykgcmV0dXJuXG4gICAgaWYgKHRoaXMucmVhZHlXb3JrZXJzLnNpemUgPT09IDApIHJldHVyblxuXG4gICAgdGhpcy5fZGlzcGF0Y2hpbmcgPSB0cnVlXG5cbiAgICB0cnkge1xuICAgICAgd2hpbGUgKHRoaXMucmVhZHlXb3JrZXJzLnNpemUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGpvYiA9IGF3YWl0IHRoaXMuc3RvcmUubmV4dEF2YWlsYWJsZUpvYigpXG4gICAgICAgIGlmICgham9iKSByZXR1cm5cblxuICAgICAgICBjb25zdCBbd29ya2VyXSA9IHRoaXMucmVhZHlXb3JrZXJzXG4gICAgICAgIGlmICghd29ya2VyKSByZXR1cm5cblxuICAgICAgICB0aGlzLnJlYWR5V29ya2Vycy5kZWxldGUod29ya2VyKVxuXG4gICAgICAgIGNvbnN0IGhhbmRlZE9mZkF0TXMgPSBhd2FpdCB0aGlzLnN0b3JlLm1hcmtIYW5kZWRPZmYoe2pvYklkOiBqb2IuaWQsIHdvcmtlcklkOiB3b3JrZXIud29ya2VySWR9KVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgd29ya2VyLnNlbmQoe1xuICAgICAgICAgICAgdHlwZTogXCJqb2JcIixcbiAgICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgICAgaWQ6IGpvYi5pZCxcbiAgICAgICAgICAgICAgam9iTmFtZTogam9iLmpvYk5hbWUsXG4gICAgICAgICAgICAgIGFyZ3M6IGpvYi5hcmdzLFxuICAgICAgICAgICAgICB3b3JrZXJJZDogd29ya2VyLndvcmtlcklkLFxuICAgICAgICAgICAgICBoYW5kZWRPZmZBdE1zLFxuICAgICAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgZm9ya2VkOiBqb2IuZm9ya2VkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oKCkgPT4gW1wiRmFpbGVkIHRvIHNlbmQgam9iIHRvIHdvcmtlciwgcmUtcXVldWVpbmc6XCIsIGVycm9yXSlcbiAgICAgICAgICBhd2FpdCB0aGlzLnN0b3JlLm1hcmtSZXR1cm5lZFRvUXVldWUoe2pvYklkOiBqb2IuaWR9KVxuICAgICAgICAgIHRoaXMucmVhZHlXb3JrZXJzLmFkZCh3b3JrZXIpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5fZGlzcGF0Y2hpbmcgPSBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9zd2VlcE9ycGhhbnMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvdW50ID0gYXdhaXQgdGhpcy5zdG9yZS5tYXJrT3JwaGFuZWRKb2JzKClcblxuICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtcIk1hcmtlZCBvcnBoYW5lZCBiYWNrZ3JvdW5kIGpvYnNcIiwgY291bnRdKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcigoKSA9PiBbXCJGYWlsZWQgdG8gbWFyayBvcnBoYW5lZCBqb2JzOlwiLCBlcnJvcl0pXG4gICAgfVxuICB9XG59XG4iXX0=
|
|
494
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZ3JvdW5kLWpvYnMvbWFpbi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFBO0FBQ3JCLE9BQU8sVUFBVSxNQUFNLGtCQUFrQixDQUFBO0FBQ3pDLE9BQU8sdUJBQXVCLE1BQU0sZ0JBQWdCLENBQUE7QUFDcEQsT0FBTyxtQkFBbUIsTUFBTSxZQUFZLENBQUE7QUFDNUMsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBRWpDOzs7Ozs7R0FNRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsb0NBQW9DLENBQUE7QUFFN0Q7Ozs7R0FJRztBQUNILE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQSxDQUFDLGFBQWE7QUFFaEQsTUFBTSxDQUFDLE9BQU8sT0FBTyxrQkFBa0I7SUFDckM7Ozs7O09BS0c7SUFDSCxZQUFZLEVBQUMsYUFBYSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUM7UUFDckMsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFDbEMsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLHVCQUF1QixFQUFFLENBQUE7UUFDdEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQTtRQUMvQixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFBO1FBQ3pELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUE7UUFDL0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFBO1FBQzNDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxtQkFBbUIsQ0FBQyxFQUFDLGFBQWEsRUFBRSxrQkFBa0IsRUFBRSxNQUFN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QUFJLENBQUMsZUFBZSxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDckMsSUFBSSxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUE7WUFDaEMsS0FBSyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUE7UUFDcEIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQ1gsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhO1FBQ2pCLElBQUksQ0FBQztZQUNILE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO1lBRWpELElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNkLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQTtnQkFDbEUsZ0VBQWdFO2dCQUNoRSwwREFBMEQ7Z0JBQzFELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQTtnQkFDdEIsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUE7WUFDckIsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQywrQkFBK0IsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQ25FLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IG5ldCBmcm9tIFwibmV0XCJcbmltcG9ydCBKc29uU29ja2V0IGZyb20gXCIuL2pzb24tc29ja2V0LmpzXCJcbmltcG9ydCBCYWNrZ3JvdW5kSm9ic1NjaGVkdWxlciBmcm9tIFwiLi9zY2hlZHVsZXIuanNcIlxuaW1wb3J0IEJhY2tncm91bmRKb2JzU3RvcmUgZnJvbSBcIi4vc3RvcmUuanNcIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi4vbG9nZ2VyLmpzXCJcblxuLyoqXG4gKiBDaGFubmVsIHVzZWQgYnkgYGJhY2tncm91bmQtam9icy1tYWluYCB0byBjb29yZGluYXRlIGRpc3BhdGNoIHdha2UtdXBzXG4gKiBhY3Jvc3MgcHJvY2Vzc2VzIHZpYSBCZWFjb24uIFdvcmtlcnMgZG8gTk9UIHN1YnNjcmliZSB0byB0aGlzIGNoYW5uZWxcbiAqIOKAlCB0aGV5IGFscmVhZHkgcmVjZWl2ZSBqb2ItaGFuZG9mZiBtZXNzYWdlcyBvbiB0aGVpciBKc29uU29ja2V0IHRvXG4gKiBtYWluOyB0aGlzIGNoYW5uZWwgZXhpc3RzIHNvIGNyb3NzLXByb2Nlc3MgZW5xdWV1ZXMgKG9yIGZ1dHVyZVxuICogbXVsdGktbWFpbiBkZXBsb3ltZW50cykgY2FuIHBva2UgYW4gaWRsZSBtYWluIHRvIGRyYWluLlxuICovXG5jb25zdCBESVNQQVRDSF9DSEFOTkVMID0gXCJ2ZWxvY2lvdXMtYmFja2dyb3VuZC1qb2JzLWRpc3BhdGNoXCJcblxuLyoqXG4gKiBgc2V0VGltZW91dGAgaXMgaW1wbGVtZW50ZWQgd2l0aCAzMi1iaXQgc2lnbmVkIGRlbGF5cyBvbiBOb2RlOyBwYXNzaW5nXG4gKiBhbnl0aGluZyBsYXJnZXIgc2lsZW50bHkgY2xhbXBzIHRvIDFtcyBhbmQgZmlyZXMgaW1tZWRpYXRlbHkuIENhcCB0aGVcbiAqIHNjaGVkdWxlZC1qb2IgdGltZXIgaGVyZSBhbmQgcmUtYXJtIHdoZW4gaXQgZXhwaXJlcy5cbiAqL1xuY29uc3QgTUFYX1RJTUVSX01TID0gMl8xNDdfNDgzXzY0NyAvLyB+MjQuOCBkYXlzXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhY2tncm91bmRKb2JzTWFpbiB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuaG9zdF0gLSBIb3N0bmFtZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFthcmdzLnBvcnRdIC0gUG9ydC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBob3N0LCBwb3J0fSkge1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb25cbiAgICBjb25zdCBjb25maWcgPSBjb25maWd1cmF0aW9uLmdldEJhY2tncm91bmRKb2JzQ29uZmlnKClcbiAgICB0aGlzLmhvc3QgPSBob3N0IHx8IGNvbmZpZy5ob3N0XG4gICAgdGhpcy5wb3J0ID0gdHlwZW9mIHBvcnQgPT09IFwibnVtYmVyXCIgPyBwb3J0IDogY29uZmlnLnBvcnRcbiAgICB0aGlzLmRpc3BhdGNoU3RyYXRlZ3kgPSBjb25maWcuZGlzcGF0Y2hTdHJhdGVneVxuICAgIHRoaXMucG9sbEludGVydmFsTXMgPSBjb25maWcucG9sbEludGVydmFsTXNcbiAgICB0aGlzLnN0b3JlID0gbmV3IEJhY2tncm91bmRKb2JzU3RvcmUoe2NvbmZpZ3VyYXRpb24sIGRhdGFiYXNlSWRlbnRpZmllcjogY29uZmlnLmRhdGFiYXNlSWRlbnRpZmllcn0pXG4gICAgdGhpcy5sb2dnZXIgPSBuZXcgTG9nZ2VyKHRoaXMpXG4gICAgLyoqIEB0eXBlIHtTZXQ8SnNvblNvY2tldD59ICovXG4gICAgdGhpcy53b3JrZXJzID0gbmV3IFNldCgpXG4gICAgLyoqIEB0eXBlIHtTZXQ8SnNvblNvY2tldD59ICovXG4gICAgdGhpcy5yZWFkeVdvcmtlcnMgPSBuZXcgU2V0KClcbiAgICAvKiogQHR5cGUge25ldC5TZXJ2ZXIgfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5zZXJ2ZXIgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge05vZGVKUy5UaW1lb3V0IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX3BvbGxUaW1lciA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7Tm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5fc2NoZWR1bGVkVGltZXIgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge05vZGVKUy5UaW1lb3V0IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX2Vycm9yUmV0cnlUaW1lciA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7Tm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5fb3JwaGFuVGltZXIgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge0JhY2tncm91bmRKb2JzU2NoZWR1bGVyIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuc2NoZWR1bGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fZHJhaW5pbmcgPSBmYWxzZVxuICAgIHRoaXMuX3JlZHJhaW5RdWV1ZWQgPSBmYWxzZVxuICAgIHRoaXMuX3N0b3BwZWQgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7KCgpID0+IHZvaWQpIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX3Vuc3Vic2NyaWJlQmVhY29uID0gdW5kZWZpbmVkXG4gICAgLyoqIEB0eXBlIHsoKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkKSB8IHVuZGVmaW5lZH0gKi9cbiAgICB0aGlzLl9iZWFjb25Db25uZWN0SGFuZGxlciA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vYmVhY29uL2NsaWVudC5qc1wiKS5kZWZhdWx0IHwgaW1wb3J0KFwiLi4vYmVhY29uL2luLXByb2Nlc3MtY2xpZW50LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5fYmVhY29uQ2xpZW50ID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBsaXN0ZW5pbmcuXG4gICAqL1xuICBhc3luYyBzdGFydCgpIHtcbiAgICB0aGlzLl9zdG9wcGVkID0gZmFsc2VcbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0Q3VycmVudCgpXG4gICAgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmluaXRpYWxpemUoe3R5cGU6IFwiYmFja2dyb3VuZC1qb2JzLW1haW5cIn0pXG4gICAgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmNvbm5lY3RCZWFjb24oe3BlZXJUeXBlOiBcImJhY2tncm91bmQtam9icy1tYWluXCJ9KVxuICAgIGF3YWl0IHRoaXMuc3RvcmUuZW5zdXJlUmVhZHkoKVxuICAgIGNvbnN0IHNlcnZlciA9IG5ldC5jcmVhdGVTZXJ2ZXIoKHNvY2tldCkgPT4gdGhpcy5faGFuZGxlQ29ubmVjdGlvbihzb2NrZXQpKVxuICAgIHRoaXMuc2VydmVyID0gc2VydmVyXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBzZXJ2ZXIub25jZShcImVycm9yXCIsIHJlamVjdClcbiAgICAgICAgc2VydmVyLmxpc3Rlbih0aGlzLnBvcnQsIHRoaXMuaG9zdCwgKCkgPT4gcmVzb2x2ZSh1bmRlZmluZWQpKVxuICAgICAgfSlcblxuICAgICAgY29uc3QgYWRkcmVzcyA9IHNlcnZlci5hZGRyZXNzKClcbiAgICAgIGlmIChhZGRyZXNzICYmIHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHRoaXMucG9ydCA9IGFkZHJlc3MucG9ydFxuICAgICAgfVxuXG4gICAgICB0aGlzLl9zZXR1cERpc3BhdGNoVHJpZ2dlcnMoKVxuXG4gICAgICB0aGlzLl9vcnBoYW5UaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgdm9pZCB0aGlzLl9zd2VlcE9ycGhhbnMoKVxuICAgICAgfSwgNjAwMDApXG5cbiAgICAgIHRoaXMuc2NoZWR1bGVyID0gbmV3IEJhY2tncm91bmRKb2JzU2NoZWR1bGVyKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICBlbnF1ZXVlSm9iOiBhc3luYyAoe2FyZ3MsIGpvYkNsYXNzLCBvcHRpb25zfSkgPT4ge1xuICAgICAgICAgIGF3YWl0IHRoaXMuc3RvcmUuZW5xdWV1ZSh7XG4gICAgICAgICAgICBqb2JOYW1lOiBqb2JDbGFzcy5qb2JOYW1lKCksXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICAgIH0pXG4gICAgICAgICAgdGhpcy5fbm90aWZ5RW5xdWV1ZWQoKVxuICAgICAgICAgIGF3YWl0IHRoaXMuX2RyYWluKClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIGF3YWl0IHRoaXMuc2NoZWR1bGVyLnN0YXJ0KClcblxuICAgICAgLy8gU3RhcnR1cCBjYXRjaC11cDogZHJhaW4gYW55dGhpbmcgdGhhdCB3YXMgd2FpdGluZyBiZWZvcmUgdGhpc1xuICAgICAgLy8gcHJvY2VzcyBjYW1lIHVwLiBJbiBiZWFjb24gbW9kZSB0aGlzIGlzIGFsc28gdGhlIHNhZmV0eSBuZXQgZm9yXG4gICAgICAvLyByYWNlcyBiZXR3ZWVuIGF0dGFjaGluZyB0aGUgY29ubmVjdCBsaXN0ZW5lciBhbmQgdGhlIGluaXRpYWxcbiAgICAgIC8vIGNvbm5lY3QgZmlyaW5nICh0aGUgbGlzdGVuZXIgY291bGQgbWlzcyB0aGUgdmVyeSBmaXJzdCBjb25uZWN0LFxuICAgICAgLy8gYnV0IHRoaXMgZHJhaW4gY292ZXJzIGl0KS5cbiAgICAgIGF3YWl0IHRoaXMuX2RyYWluKClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5zdG9wKClcbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY2xvc2VkLlxuICAgKi9cbiAgYXN5bmMgc3RvcCgpIHtcbiAgICB0aGlzLl9zdG9wcGVkID0gdHJ1ZVxuXG4gICAgZm9yIChjb25zdCB3b3JrZXIgb2YgdGhpcy53b3JrZXJzKSB7XG4gICAgICB3b3JrZXIuY2xvc2UoKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9wb2xsVGltZXIpIGNsZWFySW50ZXJ2YWwodGhpcy5fcG9sbFRpbWVyKVxuICAgIGlmICh0aGlzLl9zY2hlZHVsZWRUaW1lcikgY2xlYXJUaW1lb3V0KHRoaXMuX3NjaGVkdWxlZFRpbWVyKVxuICAgIGlmICh0aGlzLl9lcnJvclJldHJ5VGltZXIpIGNsZWFyVGltZW91dCh0aGlzLl9lcnJvclJldHJ5VGltZXIpXG4gICAgaWYgKHRoaXMuX29ycGhhblRpbWVyKSBjbGVhckludGVydmFsKHRoaXMuX29ycGhhblRpbWVyKVxuICAgIHRoaXMuX3BvbGxUaW1lciA9IHVuZGVmaW5lZFxuICAgIHRoaXMuX3NjaGVkdWxlZFRpbWVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fZXJyb3JSZXRyeVRpbWVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fb3JwaGFuVGltZXIgPSB1bmRlZmluZWRcblxuICAgIGlmICh0aGlzLl91bnN1YnNjcmliZUJlYWNvbikge1xuICAgICAgdGhpcy5fdW5zdWJzY3JpYmVCZWFjb24oKVxuICAgICAgdGhpcy5fdW5zdWJzY3JpYmVCZWFjb24gPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fYmVhY29uQ2xpZW50ICYmIHRoaXMuX2JlYWNvbkNvbm5lY3RIYW5kbGVyKSB7XG4gICAgICB0aGlzLl9iZWFjb25DbGllbnQub2ZmKFwiY29ubmVjdFwiLCB0aGlzLl9iZWFjb25Db25uZWN0SGFuZGxlcilcbiAgICB9XG4gICAgdGhpcy5fYmVhY29uQ29ubmVjdEhhbmRsZXIgPSB1bmRlZmluZWRcbiAgICB0aGlzLl9iZWFjb25DbGllbnQgPSB1bmRlZmluZWRcblxuICAgIHRoaXMuc2NoZWR1bGVyPy5zdG9wKClcblxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5kaXNjb25uZWN0QmVhY29uKClcblxuICAgIGlmICghdGhpcy5zZXJ2ZXIpIHJldHVyblxuXG4gICAgY29uc3Qge3NlcnZlcn0gPSB0aGlzXG4gICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNlcnZlci5jbG9zZSgoKSA9PiByZXNvbHZlKHVuZGVmaW5lZCkpKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gQm91bmQgcG9ydC5cbiAgICovXG4gIGdldFBvcnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucG9ydFxuICB9XG5cbiAgLyoqXG4gICAqIFdpcmVzIHVwIHRoZSBkaXNwYXRjaC10cmlnZ2VyaW5nIHNpZ25hbCBzb3VyY2VzIGZvciB0aGUgY29uZmlndXJlZFxuICAgKiBzdHJhdGVneS4gSW4gYFwiYmVhY29uXCJgIG1vZGUgKGRlZmF1bHQpIHRoaXMgbWVhbnMgc3Vic2NyaWJpbmcgdG8gdGhlXG4gICAqIGB2ZWxvY2lvdXMtYmFja2dyb3VuZC1qb2JzLWRpc3BhdGNoYCBjaGFubmVsIGZvciBjcm9zcy1wcm9jZXNzXG4gICAqIHdha2UtdXBzLCBsaXN0ZW5pbmcgZm9yIEJlYWNvbiAocmUpY29ubmVjdHMgdG8gY2F0Y2ggdXAgb24gbWlzc2VkXG4gICAqIHdvcmssIGFuZCByZWx5aW5nIG9uIGRpcmVjdCBpbi1wcm9jZXNzIGNhbGxzIGZyb20gYF9oYW5kbGVFbnF1ZXVlYCxcbiAgICogYF9oYW5kbGVKb2JDb21wbGV0ZWAvYEZhaWxlZGAsIHdvcmtlciBoZWxsby9yZWFkeSwgYW5kIHRoZVxuICAgKiBzY2hlZHVsZWQtam9iIGBzZXRUaW1lb3V0YC4gSW4gYFwicG9sbGluZ1wiYCBtb2RlIHdlIHJlc3RvcmUgdGhlXG4gICAqIGxlZ2FjeSBmaXhlZC1pbnRlcnZhbCBwb2xsIGZvciB1c2VycyB3aG8gd2FudCB0aGUgcHJldmlvdXMgYmVoYXZpb3IuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgX3NldHVwRGlzcGF0Y2hUcmlnZ2VycygpIHtcbiAgICBpZiAodGhpcy5kaXNwYXRjaFN0cmF0ZWd5ID09PSBcInBvbGxpbmdcIikge1xuICAgICAgdGhpcy5fcG9sbFRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICB2b2lkIHRoaXMuX2RyYWluKClcbiAgICAgIH0sIHRoaXMucG9sbEludGVydmFsTXMpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBiZWFjb25DbGllbnQgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0QmVhY29uQ2xpZW50KClcbiAgICBpZiAoIWJlYWNvbkNsaWVudCkgcmV0dXJuXG5cbiAgICB0aGlzLl9iZWFjb25DbGllbnQgPSBiZWFjb25DbGllbnRcblxuICAgIHRoaXMuX3Vuc3Vic2NyaWJlQmVhY29uID0gYmVhY29uQ2xpZW50Lm9uQnJvYWRjYXN0KChtZXNzYWdlKSA9PiB7XG4gICAgICBpZiAobWVzc2FnZT8uY2hhbm5lbCAhPT0gRElTUEFUQ0hfQ0hBTk5FTCkgcmV0dXJuXG4gICAgICB2b2lkIHRoaXMuX2RyYWluKClcbiAgICB9KVxuXG4gICAgLy8gRHJhaW4gb24gZXZlcnkgKHJlKWNvbm5lY3QgdG8gY2F0Y2ggdXAgb24gam9icyBlbnF1ZXVlZCB3aGlsZSB0aGVcbiAgICAvLyBidXMgd2FzIHVucmVhY2hhYmxlLiBUaGUgREIgaXMgdGhlIGR1cmFibGUgbG9nOyBCZWFjb24gaXMganVzdCB0aGVcbiAgICAvLyB3YWtlLXVwIHNpZ25hbC5cbiAgICB0aGlzLl9iZWFjb25Db25uZWN0SGFuZGxlciA9ICgpID0+IHtcbiAgICAgIHZvaWQgdGhpcy5fZHJhaW4oKVxuICAgIH1cbiAgICBiZWFjb25DbGllbnQub24oXCJjb25uZWN0XCIsIHRoaXMuX2JlYWNvbkNvbm5lY3RIYW5kbGVyKVxuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2hlcyBhIGRpc3BhdGNoIHdha2UtdXAgb24gdGhlIEJlYWNvbiBjaGFubmVsLiBOby1vcCBpbiBwb2xsaW5nXG4gICAqIG1vZGUgb3Igd2hlbiBCZWFjb24gaXMgbm90IGNvbm5lY3RlZDsgaW4gdGhvc2UgY2FzZXMgdGhlIGRpcmVjdFxuICAgKiBpbi1wcm9jZXNzIGBfZHJhaW4oKWAgY2FsbCBpbiB0aGUgZW5xdWV1ZS9oYW5kbGUgcGF0aHMgaXMgc3VmZmljaWVudFxuICAgKiAodGhlcmUgYXJlIG5vIG90aGVyIHByb2Nlc3NlcyB0byBub3RpZnkpLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIF9ub3RpZnlFbnF1ZXVlZCgpIHtcbiAgICBpZiAodGhpcy5kaXNwYXRjaFN0cmF0ZWd5ID09PSBcInBvbGxpbmdcIikgcmV0dXJuXG5cbiAgICBjb25zdCBiZWFjb25DbGllbnQgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0QmVhY29uQ2xpZW50KClcbiAgICBpZiAoIWJlYWNvbkNsaWVudCB8fCAhYmVhY29uQ2xpZW50LmlzQ29ubmVjdGVkKCkpIHJldHVyblxuXG4gICAgdHJ5IHtcbiAgICAgIGJlYWNvbkNsaWVudC5wdWJsaXNoKHtcbiAgICAgICAgY2hhbm5lbDogRElTUEFUQ0hfQ0hBTk5FTCxcbiAgICAgICAgYnJvYWRjYXN0UGFyYW1zOiB7fSxcbiAgICAgICAgYm9keToge2FjdGlvbjogXCJ3YWtlXCJ9XG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtcIkZhaWxlZCB0byBwdWJsaXNoIGJhY2tncm91bmQgam9icyB3YWtlIGJyb2FkY2FzdDpcIiwgZXJyb3JdKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIm5ldFwiKS5Tb2NrZXR9IHNvY2tldCAtIFNvY2tldC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBfaGFuZGxlQ29ubmVjdGlvbihzb2NrZXQpIHtcbiAgICBjb25zdCBqc29uU29ja2V0ID0gbmV3IEpzb25Tb2NrZXQoc29ja2V0KVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iU29ja2V0Um9sZSB8IG51bGx9ICovXG4gICAgbGV0IHJvbGUgPSBudWxsXG5cbiAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgaWYgKHJvbGUgPT09IFwid29ya2VyXCIpIHtcbiAgICAgICAgdGhpcy53b3JrZXJzLmRlbGV0ZShqc29uU29ja2V0KVxuICAgICAgICB0aGlzLnJlYWR5V29ya2Vycy5kZWxldGUoanNvblNvY2tldClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBqc29uU29ja2V0Lm9uKFwiY2xvc2VcIiwgY2xlYW51cClcbiAgICBqc29uU29ja2V0Lm9uKFwiZXJyb3JcIiwgKGVycm9yKSA9PiB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtcIkJhY2tncm91bmQgam9icyBjb25uZWN0aW9uIGVycm9yOlwiLCBlcnJvcl0pXG4gICAgICBjbGVhbnVwKClcbiAgICB9KVxuXG4gICAgLyoqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iU29ja2V0TWVzc2FnZX0gbWVzc2FnZSAtIFNvY2tldCBtZXNzYWdlLiAqL1xuICAgIGpzb25Tb2NrZXQub24oXCJtZXNzYWdlXCIsIChtZXNzYWdlKSA9PiB7XG4gICAgICBpZiAoIXJvbGUgJiYgbWVzc2FnZT8udHlwZSA9PT0gXCJoZWxsb1wiKSB7XG4gICAgICAgIHJvbGUgPSBtZXNzYWdlLnJvbGVcblxuICAgICAgICBpZiAocm9sZSA9PT0gXCJ3b3JrZXJcIikge1xuICAgICAgICAgIGpzb25Tb2NrZXQud29ya2VySWQgPSBtZXNzYWdlLndvcmtlcklkXG4gICAgICAgICAgdGhpcy53b3JrZXJzLmFkZChqc29uU29ja2V0KVxuICAgICAgICAgIHRoaXMucmVhZHlXb3JrZXJzLmFkZChqc29uU29ja2V0KVxuICAgICAgICAgIHZvaWQgdGhpcy5fZHJhaW4oKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmIChyb2xlID09PSBcImNsaWVudFwiICYmIG1lc3NhZ2U/LnR5cGUgPT09IFwiZW5xdWV1ZVwiKSB7XG4gICAgICAgIHRoaXMuX2hhbmRsZUVucXVldWUoe2pzb25Tb2NrZXQsIG1lc3NhZ2V9KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKHJvbGUgPT09IFwid29ya2VyXCIgJiYgbWVzc2FnZT8udHlwZSA9PT0gXCJyZWFkeVwiKSB7XG4gICAgICAgIHRoaXMucmVhZHlXb3JrZXJzLmFkZChqc29uU29ja2V0KVxuICAgICAgICB2b2lkIHRoaXMuX2RyYWluKClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmIChyb2xlID09PSBcIndvcmtlclwiICYmIG1lc3NhZ2U/LnR5cGUgPT09IFwiZHJhaW5pbmdcIikge1xuICAgICAgICAvLyBUaGUgd29ya2VyIGlzIHNodXR0aW5nIGRvd24gZ3JhY2VmdWxseS4gU3RvcCBkaXNwYXRjaGluZyBuZXcgam9ic1xuICAgICAgICAvLyB0byBpdCBidXQga2VlcCB0aGUgY29ubmVjdGlvbiBpbiBgd29ya2Vyc2Agc28gYW55IGluLWZsaWdodCBqb2JcbiAgICAgICAgLy8gaXQncyBzdGlsbCBkcmFpbmluZyBjYW4gcmVwb3J0IGl0cyByZXN1bHQuXG4gICAgICAgIHRoaXMucmVhZHlXb3JrZXJzLmRlbGV0ZShqc29uU29ja2V0KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKChyb2xlID09PSBcIndvcmtlclwiIHx8IHJvbGUgPT09IFwicmVwb3J0ZXJcIikgJiYgbWVzc2FnZT8udHlwZSA9PT0gXCJqb2ItY29tcGxldGVcIikge1xuICAgICAgICB0aGlzLl9oYW5kbGVKb2JDb21wbGV0ZSh7anNvblNvY2tldCwgbWVzc2FnZX0pXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAoKHJvbGUgPT09IFwid29ya2VyXCIgfHwgcm9sZSA9PT0gXCJyZXBvcnRlclwiKSAmJiBtZXNzYWdlPy50eXBlID09PSBcImpvYi1mYWlsZWRcIikge1xuICAgICAgICB0aGlzLl9oYW5kbGVKb2JGYWlsZWQoe2pzb25Tb2NrZXQsIG1lc3NhZ2V9KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICAgKiBAcGFyYW0ge0pzb25Tb2NrZXR9IGFyZ3MuanNvblNvY2tldCAtIEpTT04gc29ja2V0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmFja2dyb3VuZEpvYkVucXVldWVNZXNzYWdlfSBhcmdzLm1lc3NhZ2UgLSBNZXNzYWdlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyBfaGFuZGxlRW5xdWV1ZSh7anNvblNvY2tldCwgbWVzc2FnZX0pIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgam9iSWQgPSBhd2FpdCB0aGlzLnN0b3JlLmVucXVldWUoe1xuICAgICAgICBqb2JOYW1lOiBtZXNzYWdlLmpvYk5hbWUsXG4gICAgICAgIGFyZ3M6IG1lc3NhZ2UuYXJncyB8fCBbXSxcbiAgICAgICAgb3B0aW9uczogbWVzc2FnZS5vcHRpb25zIHx8IHt9XG4gICAgICB9KVxuXG4gICAgICBqc29uU29ja2V0LnNlbmQoe3R5cGU6IFwiZW5xdWV1ZWRcIiwgam9iSWR9KVxuICAgICAgdGhpcy5fbm90aWZ5RW5xdWV1ZWQoKVxuICAgICAgYXdhaXQgdGhpcy5fZHJhaW4oKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcigoKSA9PiBbXCJGYWlsZWQgdG8gZW5xdWV1ZSBiYWNrZ3JvdW5kIGpvYjpcIiwgZXJyb3JdKVxuICAgICAganNvblNvY2tldC5zZW5kKHt0eXBlOiBcImVucXVldWUtZXJyb3JcIiwgZXJyb3I6IFwiRmFpbGVkIHRvIGVucXVldWUgam9iXCJ9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7SnNvblNvY2tldH0gYXJncy5qc29uU29ja2V0IC0gSlNPTiBzb2NrZXQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iQ29tcGxldGVNZXNzYWdlfSBhcmdzLm1lc3NhZ2UgLSBNZXNzYWdlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyBfaGFuZGxlSm9iQ29tcGxldGUoe2pzb25Tb2NrZXQsIG1lc3NhZ2V9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc3RvcmUubWFya0NvbXBsZXRlZCh7XG4gICAgICAgIGpvYklkOiBtZXNzYWdlLmpvYklkLFxuICAgICAgICB3b3JrZXJJZDogbWVzc2FnZS53b3JrZXJJZCxcbiAgICAgICAgaGFuZGVkT2ZmQXRNczogbWVzc2FnZS5oYW5kZWRPZmZBdE1zXG4gICAgICB9KVxuICAgICAganNvblNvY2tldC5zZW5kKHt0eXBlOiBcImpvYi11cGRhdGVkXCIsIGpvYklkOiBtZXNzYWdlLmpvYklkfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoKCkgPT4gW1wiRmFpbGVkIHRvIHVwZGF0ZSBqb2IgY29tcGxldGlvbjpcIiwgZXJyb3JdKVxuICAgICAganNvblNvY2tldC5zZW5kKHt0eXBlOiBcImpvYi11cGRhdGUtZXJyb3JcIiwgam9iSWQ6IG1lc3NhZ2Uuam9iSWQsIGVycm9yOiBcIkZhaWxlZCB0byB1cGRhdGUgam9iXCJ9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7SnNvblNvY2tldH0gYXJncy5qc29uU29ja2V0IC0gSlNPTiBzb2NrZXQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iRmFpbGVkTWVzc2FnZX0gYXJncy5tZXNzYWdlIC0gTWVzc2FnZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBoYW5kbGVkLlxuICAgKi9cbiAgYXN5bmMgX2hhbmRsZUpvYkZhaWxlZCh7anNvblNvY2tldCwgbWVzc2FnZX0pIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zdG9yZS5tYXJrRmFpbGVkKHtcbiAgICAgICAgam9iSWQ6IG1lc3NhZ2Uuam9iSWQsXG4gICAgICAgIGVycm9yOiBtZXNzYWdlLmVycm9yLFxuICAgICAgICB3b3JrZXJJZDogbWVzc2FnZS53b3JrZXJJZCxcbiAgICAgICAgaGFuZGVkT2ZmQXRNczogbWVzc2FnZS5oYW5kZWRPZmZBdE1zXG4gICAgICB9KVxuICAgICAganNvblNvY2tldC5zZW5kKHt0eXBlOiBcImpvYi11cGRhdGVkXCIsIGpvYklkOiBtZXNzYWdlLmpvYklkfSlcbiAgICAgIC8vIEEgZmFpbGVkIGpvYiBtYXkgaGF2ZSBiZWVuIHJlLXF1ZXVlZCAod2l0aCBiYWNrb2ZmKSBmb3IgcmV0cnkg4oCUXG4gICAgICAvLyBwb2tlIHRoZSBkaXNwYXRjaGVyIHNvIHRoZSByZXRyeSB0aW1lciBpcyBhcm1lZC5cbiAgICAgIHRoaXMuX25vdGlmeUVucXVldWVkKClcbiAgICAgIGF3YWl0IHRoaXMuX2RyYWluKClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoKCkgPT4gW1wiRmFpbGVkIHRvIHVwZGF0ZSBqb2IgZmFpbHVyZTpcIiwgZXJyb3JdKVxuICAgICAganNvblNvY2tldC5zZW5kKHt0eXBlOiBcImpvYi11cGRhdGUtZXJyb3JcIiwgam9iSWQ6IG1lc3NhZ2Uuam9iSWQsIGVycm9yOiBcIkZhaWxlZCB0byB1cGRhdGUgam9iXCJ9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEcmFpbnMgYWxsIGRpc3BhdGNoYWJsZSBqb2JzIHRvIHJlYWR5IHdvcmtlcnMsIHRoZW4gYXJtcyB0aGVcbiAgICogc2NoZWR1bGVkLWpvYiB0aW1lciBmb3IgdGhlIG5leHQgZnV0dXJlIGBzY2hlZHVsZWRfYXRfbXNgLiBDb2FsZXNjZXNcbiAgICogY29uY3VycmVudCB0cmlnZ2VyczogYSB3YWtlLXVwIHRoYXQgbGFuZHMgd2hpbGUgYSBkcmFpbiBpcyBpblxuICAgKiBmbGlnaHQganVzdCBzZXRzIGEgcmUtZHJhaW4gZmxhZyBhbmQgbGV0cyB0aGUgaW4tZmxpZ2h0IGRyYWluXG4gICAqIHJlLWxvb3AgYWZ0ZXIgaXQgZmluaXNoZXMsIHNvIG5vIHNpZ25hbCBpcyBkcm9wcGVkIGJ1dCBubyB0d29cbiAgICogZHJhaW5zIHJ1biBpbiBwYXJhbGxlbC5cbiAgICpcbiAgICogUmVzaWxpZW5jZTogaW4gYmVhY29uIG1vZGUgdGhpcyBpcyB0aGUgc29sZSB3YWtlLXVwIHBhdGggZm9yXG4gICAqIGFscmVhZHktcXVldWVkIHdvcmssIHNvIGEgdHJhbnNpZW50IERCIGVycm9yIGR1cmluZyB0aGUgZHJhaW4gKGUuZy5cbiAgICogYG5leHRBdmFpbGFibGVKb2IoKWAgcmVqZWN0aW5nKSBtdXN0IG5vdCBzdHJhbmQgdGhlIHF1ZXVlIHVudGlsIHRoZVxuICAgKiBuZXh0IGV4dGVybmFsIHNpZ25hbC4gT24gYW55IGVycm9yIHdlIGxvZyBpdCBhbmQgYXJtIGEgb25lLXNob3RcbiAgICogcmV0cnkgdmlhIGBfc2NoZWR1bGVFcnJvclJldHJ5YCB1c2luZyBgcG9sbEludGVydmFsTXNgIGFzIHRoZVxuICAgKiBjYWRlbmNlOyBvbiBzdWNjZXNzIHRoZSByZXRyeSB0aW1lciBpcyBjbGVhcmVkLiBQb2xsaW5nLW1vZGUgcnVuc1xuICAgKiBgX2RyYWluYCBmcm9tIGl0cyBvd24gaW50ZXJ2YWwsIHNvIHRoZSByZXRyeSB0aW1lciBpcyBhIG5vLW9wIHRoZXJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIF9kcmFpbigpIHtcbiAgICBpZiAodGhpcy5fc3RvcHBlZCkgcmV0dXJuXG5cbiAgICBpZiAodGhpcy5fZHJhaW5pbmcpIHtcbiAgICAgIHRoaXMuX3JlZHJhaW5RdWV1ZWQgPSB0cnVlXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9kcmFpbmluZyA9IHRydWVcbiAgICBsZXQgZXJyb3JlZCA9IGZhbHNlXG5cbiAgICB0cnkge1xuICAgICAgZG8ge1xuICAgICAgICB0aGlzLl9yZWRyYWluUXVldWVkID0gZmFsc2VcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLl9kcmFpbk9uY2UoKVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGVycm9yZWQgPSB0cnVlXG4gICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoKCkgPT4gW1wiQmFja2dyb3VuZCBqb2JzIGRyYWluIGZhaWxlZDpcIiwgZXJyb3JdKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKHRoaXMuX3JlZHJhaW5RdWV1ZWQgJiYgIXRoaXMuX3N0b3BwZWQpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX2RyYWluaW5nID0gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc3RvcHBlZCkgcmV0dXJuXG5cbiAgICBpZiAoZXJyb3JlZCkge1xuICAgICAgdGhpcy5fc2NoZWR1bGVFcnJvclJldHJ5KClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9hcm1TY2hlZHVsZWRUaW1lcigpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCgpID0+IFtcIkJhY2tncm91bmQgam9icyBzY2hlZHVsZWQtdGltZXIgYXJtaW5nIGZhaWxlZDpcIiwgZXJyb3JdKVxuICAgICAgdGhpcy5fc2NoZWR1bGVFcnJvclJldHJ5KClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLl9lcnJvclJldHJ5VGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9lcnJvclJldHJ5VGltZXIpXG4gICAgICB0aGlzLl9lcnJvclJldHJ5VGltZXIgPSB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQXJtcyBhIG9uZS1zaG90IGBzZXRUaW1lb3V0YCB0byByZXRyeSBgX2RyYWluYCBhZnRlciBhIHRyYW5zaWVudFxuICAgKiBmYWlsdXJlLiBJZGVtcG90ZW50IOKAlCByZXBlYXRlZCBjYWxscyB3aGlsZSBhIHJldHJ5IGlzIGFscmVhZHlcbiAgICogcGVuZGluZyBhcmUgbm8tb3BzLiBQb2xsaW5nIG1vZGUgYWxyZWFkeSByZXRyaWVzIHZpYSBpdHMgb3duXG4gICAqIGludGVydmFsLCBzbyB0aGlzIGlzIGEgbm8tb3AgaW4gdGhhdCBtb2RlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIF9zY2hlZHVsZUVycm9yUmV0cnkoKSB7XG4gICAgaWYgKHRoaXMuX3N0b3BwZWQpIHJldHVyblxuICAgIGlmICh0aGlzLl9lcnJvclJldHJ5VGltZXIpIHJldHVyblxuICAgIGlmICh0aGlzLmRpc3BhdGNoU3RyYXRlZ3kgPT09IFwicG9sbGluZ1wiKSByZXR1cm5cblxuICAgIHRoaXMuX2Vycm9yUmV0cnlUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5fZXJyb3JSZXRyeVRpbWVyID0gdW5kZWZpbmVkXG4gICAgICB2b2lkIHRoaXMuX2RyYWluKClcbiAgICB9LCB0aGlzLnBvbGxJbnRlcnZhbE1zKVxuICB9XG5cbiAgLyoqXG4gICAqIElubmVyIGRyYWluIGxvb3A6IHB1bGxzIGVsaWdpYmxlIHF1ZXVlZCBqb2JzIGFuZCBoYW5kcyB0aGVtIG9mZiB0b1xuICAgKiByZWFkeSB3b3JrZXJzIHVudGlsIG9uZSBvZiB0aGVtIHJ1bnMgb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIF9kcmFpbk9uY2UoKSB7XG4gICAgd2hpbGUgKHRoaXMucmVhZHlXb3JrZXJzLnNpemUgPiAwICYmICF0aGlzLl9zdG9wcGVkKSB7XG4gICAgICBjb25zdCBqb2IgPSBhd2FpdCB0aGlzLnN0b3JlLm5leHRBdmFpbGFibGVKb2IoKVxuICAgICAgaWYgKCFqb2IpIHJldHVyblxuXG4gICAgICBjb25zdCBbd29ya2VyXSA9IHRoaXMucmVhZHlXb3JrZXJzXG4gICAgICBpZiAoIXdvcmtlcikgcmV0dXJuXG5cbiAgICAgIHRoaXMucmVhZHlXb3JrZXJzLmRlbGV0ZSh3b3JrZXIpXG5cbiAgICAgIGNvbnN0IGhhbmRlZE9mZkF0TXMgPSBhd2FpdCB0aGlzLnN0b3JlLm1hcmtIYW5kZWRPZmYoe2pvYklkOiBqb2IuaWQsIHdvcmtlcklkOiB3b3JrZXIud29ya2VySWR9KVxuXG4gICAgICB0cnkge1xuICAgICAgICB3b3JrZXIuc2VuZCh7XG4gICAgICAgICAgdHlwZTogXCJqb2JcIixcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogam9iLmlkLFxuICAgICAgICAgICAgam9iTmFtZTogam9iLmpvYk5hbWUsXG4gICAgICAgICAgICBhcmdzOiBqb2IuYXJncyxcbiAgICAgICAgICAgIHdvcmtlcklkOiB3b3JrZXIud29ya2VySWQsXG4gICAgICAgICAgICBoYW5kZWRPZmZBdE1zLFxuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICBmb3JrZWQ6IGpvYi5mb3JrZWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtcIkZhaWxlZCB0byBzZW5kIGpvYiB0byB3b3JrZXIsIHJlLXF1ZXVlaW5nOlwiLCBlcnJvcl0pXG4gICAgICAgIGF3YWl0IHRoaXMuc3RvcmUubWFya1JldHVybmVkVG9RdWV1ZSh7am9iSWQ6IGpvYi5pZH0pXG4gICAgICAgIHRoaXMucmVhZHlXb3JrZXJzLmFkZCh3b3JrZXIpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFybXMgYSBzaW5nbGUgYHNldFRpbWVvdXRgIGZvciB0aGUgc29vbmVzdCBmdXR1cmUtc2NoZWR1bGVkIGpvYidzXG4gICAqIGBzY2hlZHVsZWRfYXRfbXNgLiBSZXBsYWNlcyB0aGUgc2Vjb25kIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBsZWdhY3lcbiAgICogMS1zZWNvbmQgcG9sbCAoYmVjb21pbmctZWxpZ2libGUgc2NoZWR1bGVkIGpvYnMpLiBUaGUgdGltZXIgaXNcbiAgICogaWRlbXBvdGVudGx5IHJlLWFybWVkIGF0IHRoZSBlbmQgb2YgZXZlcnkgZHJhaW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgX2FybVNjaGVkdWxlZFRpbWVyKCkge1xuICAgIGlmICh0aGlzLl9zY2hlZHVsZWRUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3NjaGVkdWxlZFRpbWVyKVxuICAgICAgdGhpcy5fc2NoZWR1bGVkVGltZXIgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc3RvcHBlZCkgcmV0dXJuXG4gICAgaWYgKHRoaXMuZGlzcGF0Y2hTdHJhdGVneSA9PT0gXCJwb2xsaW5nXCIpIHJldHVyblxuXG4gICAgY29uc3QgbmV4dCA9IGF3YWl0IHRoaXMuc3RvcmUubmV4dFNjaGVkdWxlZEpvYigpXG4gICAgaWYgKCFuZXh0IHx8IHR5cGVvZiBuZXh0LnNjaGVkdWxlZEF0TXMgIT09IFwibnVtYmVyXCIpIHJldHVyblxuXG4gICAgY29uc3QgZGVsYXkgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihuZXh0LnNjaGVkdWxlZEF0TXMgLSBEYXRlLm5vdygpLCBNQVhfVElNRVJfTVMpKVxuXG4gICAgdGhpcy5fc2NoZWR1bGVkVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuX3NjaGVkdWxlZFRpbWVyID0gdW5kZWZpbmVkXG4gICAgICB2b2lkIHRoaXMuX2RyYWluKClcbiAgICB9LCBkZWxheSlcbiAgfVxuXG4gIGFzeW5jIF9zd2VlcE9ycGhhbnMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvdW50ID0gYXdhaXQgdGhpcy5zdG9yZS5tYXJrT3JwaGFuZWRKb2JzKClcblxuICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtcIk1hcmtlZCBvcnBoYW5lZCBiYWNrZ3JvdW5kIGpvYnNcIiwgY291bnRdKVxuICAgICAgICAvLyBSZWNsYWltZWQgb3JwaGFucyBiZWNvbWUgYHF1ZXVlZGAgYWdhaW4g4oCUIHdha2UgdGhlIGRpc3BhdGNoZXJcbiAgICAgICAgLy8gc28gdGhleSBhcmVuJ3Qgc3RyYW5kZWQgdW50aWwgdGhlIG5leHQgZXh0ZXJuYWwgc2lnbmFsLlxuICAgICAgICB0aGlzLl9ub3RpZnlFbnF1ZXVlZCgpXG4gICAgICAgIGF3YWl0IHRoaXMuX2RyYWluKClcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoKCkgPT4gW1wiRmFpbGVkIHRvIG1hcmsgb3JwaGFuZWQgam9iczpcIiwgZXJyb3JdKVxuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -36,6 +36,15 @@ export default class BackgroundJobsStore {
|
|
|
36
36
|
* @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Next job.
|
|
37
37
|
*/
|
|
38
38
|
nextAvailableJob(): Promise<import("./types.js").BackgroundJobRow | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Returns the soonest future-scheduled queued job (one whose
|
|
41
|
+
* `scheduled_at_ms` is in the future), or null when there are no
|
|
42
|
+
* future-scheduled jobs. Used by the event-driven dispatcher to arm a
|
|
43
|
+
* `setTimeout` for the exact moment the next scheduled job becomes
|
|
44
|
+
* eligible, replacing the legacy 1-second polling loop.
|
|
45
|
+
* @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Soonest future-scheduled job, or null.
|
|
46
|
+
*/
|
|
47
|
+
nextScheduledJob(): Promise<import("./types.js").BackgroundJobRow | null>;
|
|
39
48
|
/**
|
|
40
49
|
* @param {string} jobId - Job id.
|
|
41
50
|
* @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Job row.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/store.js"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/store.js"],"names":[],"mappings":"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"}
|