@blokjs/trigger-worker 1.0.0 → 1.2.0

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.
@@ -6,15 +6,36 @@
6
6
  * Semantics:
7
7
  * - **Consumer groups**: required. `consumerGroup` defaults to
8
8
  * `"${queue}-group"`. The group is auto-created (`MKSTREAM` on the
9
- * stream too) on first `process()` call.
9
+ * stream too) on first `process()` call, at the `startFrom` cursor
10
+ * (`"latest"` → `$` default, `"earliest"` → `0`, or `fromBeginning`).
10
11
  * - **Consumer name**: per-process uuid, so multiple instances of
11
12
  * the same worker process don't share pending entries.
12
- * - **Retries**: pending entries are XACK'd on success / left
13
- * unacked on failure (visible in `XPENDING`). A redrive loop
14
- * reads pending entries older than `timeout` and re-delivers
15
- * to the current consumer.
16
- * - **Auto-claim**: skipped in v1 operators should run XAUTOCLAIM
17
- * periodically out of band.
13
+ * - **ACK / retries**: ACK happens exactly once via `job.complete()`
14
+ * (success) the consumer loop does NOT double-ACK. A terminal
15
+ * `job.fail(err, false)` XADDs the payload to `deadLetterQueue`
16
+ * (when configured) then XACKs the source so it isn't redelivered.
17
+ * A requeue `job.fail(err, true)` leaves the entry pending (visible
18
+ * in `XPENDING`) for redrive.
19
+ * - **ack:false**: the consumer reads with NOACK, so Redis never
20
+ * adds entries to the group's PEL — at-most-once, no leaked pending.
21
+ * - **Redrive**: an in-process periodic XAUTOCLAIM loop reclaims stale
22
+ * pending entries (idle > `config.timeout`) — left by a crashed
23
+ * consumer or a requeue `fail(err, true)` — and re-runs them through
24
+ * the handler. Redis bumps each entry's delivery count on every
25
+ * claim; once it exceeds `retries + 1` the entry is dead-lettered
26
+ * (when `deadLetterQueue` is set) and XACKed. The redrive loop only
27
+ * runs when `config.timeout` is set (it IS the idle threshold — with
28
+ * no timeout a slow-but-alive handler is indistinguishable from a
29
+ * dead one) and NOT under `ack:false` (nothing lands in the PEL).
30
+ * - **No native delay / priority**: Redis Streams has neither. `addJob`
31
+ * THROWS on `opts.delay` / `opts.priority` rather than silently
32
+ * dropping them — use a scheduler trigger for delayed work.
33
+ * - **Concurrency**: each of the `concurrency` consumer loops owns a
34
+ * DEDICATED ioredis connection (`client.duplicate()`) so their
35
+ * blocking XREADGROUP calls run in parallel instead of serializing on
36
+ * one shared socket — ioredis requires a separate client per blocking
37
+ * command. The shared `this.client` handles non-blocking ops
38
+ * (XADD / XACK / XGROUP / XAUTOCLAIM).
18
39
  *
19
40
  * Requires `ioredis` as a peer dependency:
20
41
  *
@@ -68,8 +89,11 @@ export class RedisStreamsAdapter {
68
89
  async disconnect() {
69
90
  if (!this.connected)
70
91
  return;
71
- for (const runner of this.runners.values())
92
+ for (const runner of this.runners.values()) {
72
93
  runner.stop = true;
94
+ if (runner.redrive)
95
+ clearInterval(runner.redrive);
96
+ }
73
97
  // Wait for in-flight loops to drain.
74
98
  const drainDeadline = Date.now() + 2000;
75
99
  while (Date.now() < drainDeadline) {
@@ -80,6 +104,17 @@ export class RedisStreamsAdapter {
80
104
  break;
81
105
  await new Promise((r) => setTimeout(r, 50));
82
106
  }
107
+ // Close each loop's dedicated blocking connection.
108
+ for (const runner of this.runners.values()) {
109
+ for (const conn of runner.conns) {
110
+ try {
111
+ await conn.quit();
112
+ }
113
+ catch {
114
+ /* ignore */
115
+ }
116
+ }
117
+ }
83
118
  this.runners.clear();
84
119
  try {
85
120
  await this.client?.quit();
@@ -95,35 +130,69 @@ export class RedisStreamsAdapter {
95
130
  throw new Error("[blok][redis] not connected. Call connect() first.");
96
131
  const stream = config.queue;
97
132
  const group = config.consumerGroup ?? `${stream}-group`;
98
- // Create group + stream if missing. XGROUP CREATE with MKSTREAM
99
- // errors with "BUSYGROUP" if the group already exists — swallow it.
133
+ // Create group + stream if missing, at the requested start cursor.
134
+ // XGROUP CREATE with MKSTREAM errors with "BUSYGROUP" if the group
135
+ // already exists — swallow it (the cursor is fixed at creation).
136
+ const startId = this.resolveStartId(config);
100
137
  try {
101
- await this.client.xgroup("CREATE", stream, group, "$", "MKSTREAM");
138
+ await this.client.xgroup("CREATE", stream, group, startId, "MKSTREAM");
102
139
  }
103
140
  catch (err) {
104
141
  if (!/BUSYGROUP/i.test(err.message))
105
142
  throw err;
106
143
  }
107
- const runner = { stop: false, loops: 0 };
144
+ const runner = { stop: false, loops: 0, conns: [] };
108
145
  this.runners.set(stream, runner);
109
146
  this.stats.set(stream, { completed: 0, failed: 0, active: 0 });
110
147
  const stats = this.stats.get(stream);
111
148
  const concurrency = Math.max(1, config.concurrency ?? 1);
112
149
  for (let i = 0; i < concurrency; i += 1) {
113
- void this.runConsumerLoop(stream, group, config, handler, runner, stats);
150
+ // Each blocking XREADGROUP loop needs its OWN connection — ioredis
151
+ // serializes commands on a single socket, so N loops sharing one
152
+ // client would take turns on the BLOCK, giving zero real parallelism.
153
+ const conn = this.client.duplicate();
154
+ runner.conns.push(conn);
155
+ void this.runConsumerLoop(conn, stream, group, config, handler, runner, stats);
156
+ }
157
+ // Redrive: reclaim entries left pending by a crashed consumer or a
158
+ // requeue `fail(err, true)`. Gated on `config.timeout` (the idle
159
+ // threshold) and off under NOACK (nothing lands in the PEL).
160
+ const noAck = config.ack === false;
161
+ if (config.timeout && config.timeout > 0 && !noAck) {
162
+ const minIdle = config.timeout;
163
+ runner.redrive = setInterval(() => {
164
+ void this.redriveOnce(stream, group, config, handler, runner, stats, minIdle);
165
+ }, minIdle);
114
166
  }
115
167
  }
116
- async runConsumerLoop(stream, group, config, handler, runner, stats) {
117
- if (!this.client)
118
- return;
168
+ async runConsumerLoop(conn, stream, group, config, handler, runner, stats) {
169
+ // ack:false → at-most-once. NOACK tells Redis to deliver WITHOUT
170
+ // adding the entry to the group's pending-entries list, so a handler
171
+ // throw never leaves a leaked pending entry to redrive. NOACK sits
172
+ // after the consumer name, before STREAMS.
173
+ const noAck = config.ack === false;
119
174
  runner.loops += 1;
120
175
  try {
121
176
  while (!runner.stop) {
122
177
  let entries = null;
123
178
  try {
124
- entries = await this.client.xreadgroup("GROUP", group, this.consumerName, "COUNT", String(this.config.count), "BLOCK", String(this.config.blockMs), "STREAMS", stream, ">");
179
+ const readArgs = [
180
+ "GROUP",
181
+ group,
182
+ this.consumerName,
183
+ "COUNT",
184
+ String(this.config.count),
185
+ "BLOCK",
186
+ String(this.config.blockMs),
187
+ ];
188
+ if (noAck)
189
+ readArgs.push("NOACK");
190
+ readArgs.push("STREAMS", stream, ">");
191
+ // Blocking read on this loop's OWN connection so `concurrency`
192
+ // loops don't serialize on a single shared socket.
193
+ entries = await conn.xreadgroup(...readArgs);
125
194
  }
126
- catch (err) {
195
+ catch {
127
196
  await new Promise((r) => setTimeout(r, 1000));
128
197
  continue;
129
198
  }
@@ -133,48 +202,7 @@ export class RedisStreamsAdapter {
133
202
  for (const [id, fields] of msgs) {
134
203
  if (runner.stop)
135
204
  break;
136
- stats.active += 1;
137
- try {
138
- const payload = this.fieldsToObject(fields);
139
- const dataString = typeof payload.data === "string" ? payload.data : "";
140
- let data;
141
- try {
142
- data = dataString.length > 0 ? JSON.parse(dataString) : null;
143
- }
144
- catch {
145
- data = dataString;
146
- }
147
- const job = {
148
- id,
149
- data,
150
- headers: {},
151
- queue: stream,
152
- priority: config.priority ?? 0,
153
- attempts: 0,
154
- maxRetries: config.retries ?? 0,
155
- createdAt: new Date(Number.parseInt(id.split("-")[0] ?? String(Date.now()), 10)),
156
- timeout: config.timeout,
157
- raw: { id, fields },
158
- complete: async () => {
159
- await this.client?.xack(stream, group, id);
160
- stats.completed += 1;
161
- },
162
- fail: async (_err) => {
163
- stats.failed += 1;
164
- },
165
- };
166
- await handler(job);
167
- if (config.ack !== false)
168
- await this.client?.xack(stream, group, id);
169
- stats.completed += 1;
170
- }
171
- catch {
172
- stats.failed += 1;
173
- // Pending entry left unacked — picked up by XAUTOCLAIM.
174
- }
175
- finally {
176
- stats.active = Math.max(0, stats.active - 1);
177
- }
205
+ await this.processMessage(id, fields, stream, group, config, handler, stats, noAck);
178
206
  }
179
207
  }
180
208
  }
@@ -183,6 +211,165 @@ export class RedisStreamsAdapter {
183
211
  runner.loops -= 1;
184
212
  }
185
213
  }
214
+ /**
215
+ * Run one delivered/reclaimed entry through the handler, building the
216
+ * `WorkerJob` with the ACK-once guard. Shared by the main consumer loop
217
+ * and the redrive loop so both paths ACK / DLQ / count identically.
218
+ *
219
+ * `attempts` seeds `job.attempts` (0 on first delivery, the redrive
220
+ * delivery-count on reclaim) so `WorkerTrigger.handleJob` routes to the DLQ
221
+ * once retries are exhausted instead of requeueing forever.
222
+ */
223
+ async processMessage(id, fields, stream, group, config, handler, stats, noAck, attempts = 0) {
224
+ stats.active += 1;
225
+ try {
226
+ const payload = this.fieldsToObject(fields);
227
+ const dataString = typeof payload.data === "string" ? payload.data : "";
228
+ let data;
229
+ try {
230
+ data = dataString.length > 0 ? JSON.parse(dataString) : null;
231
+ }
232
+ catch {
233
+ data = dataString;
234
+ }
235
+ // ACK exactly once. complete() and fail() both route through this
236
+ // guard so a handler that calls job.complete() AND returns (or fails
237
+ // after completing) never double-ACKs or double-counts. Under NOACK
238
+ // there's nothing in the PEL to ACK, but the guard still keeps the
239
+ // counters honest.
240
+ let acked = false;
241
+ const ackOnce = async () => {
242
+ if (acked)
243
+ return;
244
+ acked = true;
245
+ if (!noAck)
246
+ await this.client?.xack(stream, group, id);
247
+ };
248
+ const dlq = async () => {
249
+ if (config.deadLetterQueue) {
250
+ const raw = this.fieldsToObject(fields);
251
+ await this.client?.xadd(config.deadLetterQueue, "*", "data", raw.data ?? "", "jobId", raw.jobId ?? id);
252
+ }
253
+ await ackOnce();
254
+ };
255
+ const job = {
256
+ id,
257
+ data,
258
+ headers: {},
259
+ queue: stream,
260
+ priority: config.priority ?? 0,
261
+ attempts,
262
+ maxRetries: config.retries ?? 0,
263
+ createdAt: new Date(Number.parseInt(id.split("-")[0] ?? String(Date.now()), 10)),
264
+ timeout: config.timeout,
265
+ raw: { id, fields },
266
+ complete: async () => {
267
+ if (acked)
268
+ return;
269
+ await ackOnce();
270
+ stats.completed += 1;
271
+ },
272
+ fail: async (_err, requeue) => {
273
+ if (acked)
274
+ return;
275
+ stats.failed += 1;
276
+ if (requeue) {
277
+ // Leave the entry pending (in the PEL) — the redrive loop
278
+ // reclaims it once it's idle > timeout. No-op under NOACK.
279
+ return;
280
+ }
281
+ // Terminal failure: dead-letter then ACK the source. No-op DLQ
282
+ // when unset.
283
+ await dlq();
284
+ },
285
+ };
286
+ await handler(job);
287
+ // handler (WorkerTrigger.handleJob) owns ACK via complete()/fail().
288
+ }
289
+ catch {
290
+ stats.failed += 1;
291
+ // Handler threw without settling — leave the entry pending; the
292
+ // redrive loop reclaims and retries it.
293
+ }
294
+ finally {
295
+ stats.active = Math.max(0, stats.active - 1);
296
+ }
297
+ }
298
+ /**
299
+ * One redrive pass: XAUTOCLAIM entries idle longer than `minIdle` (a
300
+ * crashed consumer or a requeue `fail`) back to this consumer, then re-run
301
+ * each. Redis bumps each entry's delivery count on every claim; once it
302
+ * exceeds `retries + 1` the entry is dead-lettered and ACKed rather than
303
+ * reclaimed again forever.
304
+ */
305
+ async redriveOnce(stream, group, config, handler, runner, stats, minIdle) {
306
+ if (runner.stop || !this.client)
307
+ return;
308
+ try {
309
+ // XAUTOCLAIM key group consumer min-idle-time start [COUNT n].
310
+ const [, claimed] = await this.client.xautoclaim(stream, group, this.consumerName, minIdle, "0", "COUNT", this.config.count);
311
+ if (!claimed || claimed.length === 0)
312
+ return;
313
+ // Delivery counts for exactly the claimed ids. Bracket XPENDING by
314
+ // the min/max claimed id (XAUTOCLAIM returns them id-ascending) so
315
+ // the window can't miss any (XPENDING extended row:
316
+ // [id, consumer, idleMs, deliveryCount]).
317
+ const minId = claimed[0][0];
318
+ const maxId = claimed[claimed.length - 1][0];
319
+ const pending = (await this.client.xpending(stream, group, minId, maxId, claimed.length));
320
+ const deliveries = new Map();
321
+ for (const p of pending)
322
+ deliveries.set(p[0], Number(p[3] ?? 1));
323
+ const maxDeliveries = (config.retries ?? 0) + 1;
324
+ for (const [id, fields] of claimed) {
325
+ if (runner.stop)
326
+ break;
327
+ const count = deliveries.get(id) ?? 1;
328
+ if (count > maxDeliveries) {
329
+ // Exhausted: dead-letter (when configured) then ACK so it stops
330
+ // being reclaimed. Mirrors processMessage's terminal path.
331
+ if (config.deadLetterQueue) {
332
+ const raw = this.fieldsToObject(fields);
333
+ await this.client.xadd(config.deadLetterQueue, "*", "data", raw.data ?? "", "jobId", raw.jobId ?? id);
334
+ }
335
+ await this.client.xack(stream, group, id);
336
+ stats.failed += 1;
337
+ continue;
338
+ }
339
+ // attempts = deliveries so far minus this one, so handleJob's
340
+ // `attempts < maxRetries` budget is honored across redrives.
341
+ await this.processMessage(id, fields, stream, group, config, handler, stats, false, Math.max(0, count - 1));
342
+ }
343
+ }
344
+ catch {
345
+ // A transient claim failure (e.g. NOGROUP mid-teardown) — next tick retries.
346
+ }
347
+ }
348
+ /**
349
+ * Map the trigger's start position to the id passed to XGROUP CREATE.
350
+ * - `"latest"` (default) → `$` : only entries added after creation.
351
+ * - `"earliest"` / `fromBeginning:true` → `0` : the whole retained stream.
352
+ * - `{ seq }` / `{ timestamp }` → that explicit cursor id.
353
+ * `startFrom` rides on the PubSub schema, not WorkerTriggerOpts, so it's
354
+ * read defensively off `config` for callers that thread it through.
355
+ */
356
+ resolveStartId(config) {
357
+ if (config.fromBeginning)
358
+ return "0";
359
+ const startFrom = config.startFrom;
360
+ if (startFrom === "earliest")
361
+ return "0";
362
+ if (startFrom === "latest" || startFrom === undefined)
363
+ return "$";
364
+ if (typeof startFrom === "object" && startFrom !== null) {
365
+ const s = startFrom;
366
+ if (typeof s.seq === "number")
367
+ return `${s.seq}-0`;
368
+ if (typeof s.timestamp === "number")
369
+ return `${s.timestamp}-0`;
370
+ }
371
+ return "$";
372
+ }
186
373
  fieldsToObject(fields) {
187
374
  const out = {};
188
375
  for (let i = 0; i < fields.length; i += 2) {
@@ -193,17 +380,35 @@ export class RedisStreamsAdapter {
193
380
  async addJob(queue, data, opts) {
194
381
  if (!this.connected || !this.client)
195
382
  throw new Error("[blok][redis] not connected. Call connect() first.");
383
+ // Redis Streams has NO native delayed delivery or priority. Reject at
384
+ // enqueue rather than silently dropping the option — surfacing the
385
+ // misconfiguration is the lazy-correct choice (a scheduler trigger owns
386
+ // delayed work; XADD is strictly FIFO by id).
387
+ if (opts?.delay) {
388
+ throw new Error("[blok][redis] Redis Streams has no native delayed delivery — drop `delay` or use a scheduler trigger.");
389
+ }
390
+ if (opts?.priority) {
391
+ throw new Error("[blok][redis] Redis Streams has no native priority — drop `priority`; entries are FIFO by id.");
392
+ }
196
393
  const payload = typeof data === "string" ? data : JSON.stringify(data);
197
- const args = [];
394
+ // XADD key [NOMKSTREAM] <* | id> field value … — NOMKSTREAM (when a
395
+ // jobId is supplied, meaning the caller expects the stream to already
396
+ // exist) MUST precede the `*` id, and the assembled args must actually
397
+ // be passed to xadd (the prior build threw them away).
398
+ const args = [queue];
198
399
  if (opts?.jobId)
199
400
  args.push("NOMKSTREAM");
200
- const id = await this.client.xadd(queue, "*", "data", payload, "jobId", opts?.jobId ?? "");
401
+ args.push("*", "data", payload, "jobId", opts?.jobId ?? "");
402
+ const id = await this.client.xadd(...args);
201
403
  return id;
202
404
  }
203
405
  async stopProcessing(queue) {
204
406
  const runner = this.runners.get(queue);
205
- if (runner)
407
+ if (runner) {
206
408
  runner.stop = true;
409
+ if (runner.redrive)
410
+ clearInterval(runner.redrive);
411
+ }
207
412
  }
208
413
  isConnected() {
209
414
  return this.connected;
@@ -237,4 +442,4 @@ export class RedisStreamsAdapter {
237
442
  };
238
443
  }
239
444
  }
240
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVkaXNTdHJlYW1zQWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9SZWRpc1N0cmVhbXNBZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyQkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQWtDbEMsTUFBTSxPQUFPLG1CQUFtQjtJQUN0QixRQUFRLEdBQUcsT0FBZ0IsQ0FBQztJQUNwQixNQUFNLENBQXFCO0lBQ3BDLE1BQU0sR0FBdUIsSUFBSSxDQUFDO0lBQ2xDLE9BQU8sR0FBNkIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM5QyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLEtBQUssR0FBb0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNuRCxZQUFZLEdBQUcsUUFBUSxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFcEQsWUFBWSxNQUFvQztRQUMvQyxJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ2IsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksV0FBVztZQUMzRCxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDM0UsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjO1lBQ3hELEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUNsRSxPQUFPLEVBQUUs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QUFDO1FBQ2QsQ0FBQztJQUNGLENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQWE7UUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2pGLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztRQUNoQixJQUFJLENBQUM7WUFDSixPQUFPLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUixZQUFZO1FBQ2IsQ0FBQztRQUNELE9BQU87WUFDTixPQUFPO1lBQ1AsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNO1lBQ3ZCLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztZQUM3QixNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07WUFDdkIsT0FBTyxFQUFFLENBQUM7U0FDVixDQUFDO0lBQ0gsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZWRpc1N0cmVhbXNBZGFwdGVyIOKAlCB2MC43IFBSIDUg4oCUIFdvcmtlciBhZGFwdGVyIGJhY2tlZCBieSBSZWRpc1xuICogU3RyZWFtcyB2aWEgYGlvcmVkaXNgLiBDb25zdW1lcyBmcm9tIGEgc3RyZWFtICh0aGUgYHF1ZXVlYCBmaWVsZClcbiAqIHdpdGggYSBjb25zdW1lciBncm91cCAoYGNvbnN1bWVyR3JvdXBgKTsgcHJvZHVjZXMgdmlhIGBYQUREYC5cbiAqXG4gKiBTZW1hbnRpY3M6XG4gKiAgIC0gKipDb25zdW1lciBncm91cHMqKjogcmVxdWlyZWQuIGBjb25zdW1lckdyb3VwYCBkZWZhdWx0cyB0b1xuICogICAgIGBcIiR7cXVldWV9LWdyb3VwXCJgLiBUaGUgZ3JvdXAgaXMgYXV0by1jcmVhdGVkIChgTUtTVFJFQU1gIG9uIHRoZVxuICogICAgIHN0cmVhbSB0b28pIG9uIGZpcnN0IGBwcm9jZXNzKClgIGNhbGwuXG4gKiAgIC0gKipDb25zdW1lciBuYW1lKio6IHBlci1wcm9jZXNzIHV1aWQsIHNvIG11bHRpcGxlIGluc3RhbmNlcyBvZlxuICogICAgIHRoZSBzYW1lIHdvcmtlciBwcm9jZXNzIGRvbid0IHNoYXJlIHBlbmRpbmcgZW50cmllcy5cbiAqICAgLSAqKlJldHJpZXMqKjogcGVuZGluZyBlbnRyaWVzIGFyZSBYQUNLJ2Qgb24gc3VjY2VzcyAvIGxlZnRcbiAqICAgICB1bmFja2VkIG9uIGZhaWx1cmUgKHZpc2libGUgaW4gYFhQRU5ESU5HYCkuIEEgcmVkcml2ZSBsb29wXG4gKiAgICAgcmVhZHMgcGVuZGluZyBlbnRyaWVzIG9sZGVyIHRoYW4gYHRpbWVvdXRgIGFuZCByZS1kZWxpdmVyc1xuICogICAgIHRvIHRoZSBjdXJyZW50IGNvbnN1bWVyLlxuICogICAtICoqQXV0by1jbGFpbSoqOiBza2lwcGVkIGluIHYxIOKAlCBvcGVyYXRvcnMgc2hvdWxkIHJ1biBYQVVUT0NMQUlNXG4gKiAgICAgcGVyaW9kaWNhbGx5IG91dCBvZiBiYW5kLlxuICpcbiAqIFJlcXVpcmVzIGBpb3JlZGlzYCBhcyBhIHBlZXIgZGVwZW5kZW5jeTpcbiAqXG4gKiAgICAgYnVuIGFkZCBpb3JlZGlzXG4gKlxuICogRW52aXJvbm1lbnQgdmFyaWFibGVzOlxuICogICAtIGBSRURJU19IT1NUYCAoZGVmYXVsdCBgbG9jYWxob3N0YClcbiAqICAgLSBgUkVESVNfUE9SVGAgKGRlZmF1bHQgYDYzNzlgKVxuICogICAtIGBSRURJU19QQVNTV09SRGBcbiAqICAgLSBgUkVESVNfREJgXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBXb3JrZXJUcmlnZ2VyT3B0cyB9IGZyb20gXCJAYmxva2pzL2hlbHBlclwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtlckFkYXB0ZXIsIFdvcmtlckpvYiwgV29ya2VyUXVldWVTdGF0cyB9IGZyb20gXCIuLi9Xb3JrZXJUcmlnZ2VyXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVkaXNTdHJlYW1zQ29uZmlnIHtcblx0aG9zdDogc3RyaW5nO1xuXHRwb3J0OiBudW1iZXI7XG5cdHBhc3N3b3JkPzogc3RyaW5nO1xuXHRkYj86IG51bWJlcjtcblx0YmxvY2tNczogbnVtYmVyO1xuXHRjb3VudDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUmVkaXNDbGllbnQge1xuXHR4YWRkKHN0cmVhbTogc3RyaW5nLCAuLi5hcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nPjtcblx0eHJlYWRncm91cCguLi5hcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8QXJyYXk8W3N0cmluZywgQXJyYXk8W3N0cmluZywgc3RyaW5nW11dPl0+IHwgbnVsbD47XG5cdHhncm91cCguLi5hcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nPjtcblx0eGFjayhzdHJlYW06IHN0cmluZywgZ3JvdXA6IHN0cmluZywgLi4uaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8bnVtYmVyPjtcblx0eGxlbihzdHJlYW06IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPjtcblx0eHBlbmRpbmcoc3RyZWFtOiBzdHJpbmcsIGdyb3VwOiBzdHJpbmcpOiBQcm9taXNlPHVua25vd24+O1xuXHRwaW5nKCk6IFByb21pc2U8c3RyaW5nPjtcblx0cXVpdCgpOiBQcm9taXNlPHN0cmluZz47XG59XG5cbmludGVyZmFjZSBRdWV1ZVJ1bm5lciB7XG5cdHN0b3A6IGJvb2xlYW47XG5cdGxvb3BzOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBRdWV1ZVN0YXRzQ291bnRlcnMge1xuXHRjb21wbGV0ZWQ6IG51bWJlcjtcblx0ZmFpbGVkOiBudW1iZXI7XG5cdGFjdGl2ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgUmVkaXNTdHJlYW1zQWRhcHRlciBpbXBsZW1lbnRzIFdvcmtlckFkYXB0ZXIge1xuXHRyZWFkb25seSBwcm92aWRlciA9IFwicmVkaXNcIiBhcyBjb25zdDtcblx0cHJpdmF0ZSByZWFkb25seSBjb25maWc6IFJlZGlzU3RyZWFtc0NvbmZpZztcblx0cHJpdmF0ZSBjbGllbnQ6IFJlZGlzQ2xpZW50IHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgcnVubmVyczogTWFwPHN0cmluZywgUXVldWVSdW5uZXI+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIGNvbm5lY3RlZCA9IGZhbHNlO1xuXHRwcml2YXRlIHN0YXRzOiBNYXA8c3RyaW5nLCBRdWV1ZVN0YXRzQ291bnRlcnM+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIGNvbnN1bWVyTmFtZSA9IGBibG9rLSR7dXVpZCgpLnNsaWNlKDAsIDgpfWA7XG5cblx0Y29uc3RydWN0b3IoY29uZmlnPzogUGFydGlhbDxSZWRpc1N0cmVhbXNDb25maWc+KSB7XG5cdFx0dGhpcy5jb25maWcgPSB7XG5cdFx0XHRob3N0OiBjb25maWc/Lmhvc3QgPz8gcHJvY2Vzcy5lbnYuUkVESVNfSE9TVCA/PyBcImxvY2FsaG9zdFwiLFxuXHRcdFx0cG9ydDogY29uZmlnPy5wb3J0ID8/IE51bWJlci5wYXJzZUludChwcm9jZXNzLmVudi5SRURJU19QT1JUID8/IFwiNjM3OVwiLCAxMCksXG5cdFx0XHRwYXNzd29yZDogY29uZmlnPy5wYXNzd29yZCA/PyBwcm9jZXNzLmVudi5SRURJU19QQVNTV09SRCxcblx0XHRcdGRiOiBjb25maWc/LmRiID8/IE51bWJlci5wYXJzZUludChwcm9jZXNzLmVudi5SRURJU19EQiA/PyBcIjBcIiwgMTApLFxuXHRcdFx0YmxvY2tNczogY29uZmlnPy5ibG9ja01zID8/IDUwMDAsXG5cdFx0XHRjb3VudDogY29uZmlnPy5jb3VudCA/PyAxMCxcblx0XHR9O1xuXHR9XG5cblx0YXN5bmMgY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAodGhpcy5jb25uZWN0ZWQpIHJldHVybjtcblx0XHR0cnkge1xuXHRcdFx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBpb3JlZGlzIGlzIGEgcnVudGltZSBwZWVyIGRlcC5cblx0XHRcdGNvbnN0IGlvcmVkaXM6IGFueSA9IGF3YWl0IGltcG9ydChcImlvcmVkaXNcIik7XG5cdFx0XHRjb25zdCBJT1JlZGlzID0gaW9yZWRpcy5kZWZhdWx0ID8/IGlvcmVkaXMuUmVkaXMgPz8gaW9yZWRpcztcblx0XHRcdHRoaXMuY2xpZW50ID0gbmV3IElPUmVkaXMoe1xuXHRcdFx0XHRob3N0OiB0aGlzLmNvbmZpZy5ob3N0LFxuXHRcdFx0XHRwb3J0OiB0aGlzLmNvbmZpZy5wb3J0LFxuXHRcdFx0XHRwYXNzd29yZDogdGhpcy5jb25maWcucGFzc3dvcmQsXG5cdFx0XHRcdGRiOiB0aGlzLmNvbmZpZy5kYixcblx0XHRcdH0pIGFzIFJlZGlzQ2xpZW50O1xuXHRcdFx0YXdhaXQgdGhpcy5jbGllbnQucGluZygpO1xuXHRcdFx0dGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRgW2Jsb2tdW3JlZGlzXSBjb25uZWN0IGZhaWxlZDogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfS4gSW5zdGFsbCBpb3JlZGlzIGFzIGEgcGVlciBkZXBlbmRlbmN5OiBidW4gYWRkIGlvcmVkaXNgLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHJldHVybjtcblx0XHRmb3IgKGNvbnN0IHJ1bm5lciBvZiB0aGlzLnJ1bm5lcnMudmFsdWVzKCkpIHJ1bm5lci5zdG9wID0gdHJ1ZTtcblx0XHQvLyBXYWl0IGZvciBpbi1mbGlnaHQgbG9vcHMgdG8gZHJhaW4uXG5cdFx0Y29uc3QgZHJhaW5EZWFkbGluZSA9IERhdGUubm93KCkgKyAyMDAwO1xuXHRcdHdoaWxlIChEYXRlLm5vdygpIDwgZHJhaW5EZWFkbGluZSkge1xuXHRcdFx0bGV0IGFjdGl2ZSA9IDA7XG5cdFx0XHRmb3IgKGNvbnN0IHIgb2YgdGhpcy5ydW5uZXJzLnZhbHVlcygpKSBhY3RpdmUgKz0gci5sb29wcztcblx0XHRcdGlmIChhY3RpdmUgPT09IDApIGJyZWFrO1xuXHRcdFx0YXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgNTApKTtcblx0XHR9XG5cdFx0dGhpcy5ydW5uZXJzLmNsZWFyKCk7XG5cdFx0dHJ5IHtcblx0XHRcdGF3YWl0IHRoaXMuY2xpZW50Py5xdWl0KCk7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHQvKiBpZ25vcmUgKi9cblx0XHR9XG5cdFx0dGhpcy5jbGllbnQgPSBudWxsO1xuXHRcdHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG5cdH1cblxuXHRhc3luYyBwcm9jZXNzKGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHMsIGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQgfHwgIXRoaXMuY2xpZW50KSB0aHJvdyBuZXcgRXJyb3IoXCJbYmxva11bcmVkaXNdIG5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHRjb25zdCBzdHJlYW0gPSBjb25maWcucXVldWU7XG5cdFx0Y29uc3QgZ3JvdXAgPSBjb25maWcuY29uc3VtZXJHcm91cCA/PyBgJHtzdHJlYW19LWdyb3VwYDtcblx0XHQvLyBDcmVhdGUgZ3JvdXAgKyBzdHJlYW0gaWYgbWlzc2luZy4gWEdST1VQIENSRUFURSB3aXRoIE1LU1RSRUFNXG5cdFx0Ly8gZXJyb3JzIHdpdGggXCJCVVNZR1JPVVBcIiBpZiB0aGUgZ3JvdXAgYWxyZWFkeSBleGlzdHMg4oCUIHN3YWxsb3cgaXQuXG5cdFx0dHJ5IHtcblx0XHRcdGF3YWl0IHRoaXMuY2xpZW50Lnhncm91cChcIkNSRUFURVwiLCBzdHJlYW0sIGdyb3VwLCBcIiRcIiwgXCJNS1NUUkVBTVwiKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdGlmICghL0JVU1lHUk9VUC9pLnRlc3QoKGVyciBhcyBFcnJvcikubWVzc2FnZSkpIHRocm93IGVycjtcblx0XHR9XG5cblx0XHRjb25zdCBydW5uZXI6IFF1ZXVlUnVubmVyID0geyBzdG9wOiBmYWxzZSwgbG9vcHM6IDAgfTtcblx0XHR0aGlzLnJ1bm5lcnMuc2V0KHN0cmVhbSwgcnVubmVyKTtcblx0XHR0aGlzLnN0YXRzLnNldChzdHJlYW0sIHsgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGFjdGl2ZTogMCB9KTtcblx0XHRjb25zdCBzdGF0cyA9IHRoaXMuc3RhdHMuZ2V0KHN0cmVhbSkgYXMgUXVldWVTdGF0c0NvdW50ZXJzO1xuXG5cdFx0Y29uc3QgY29uY3VycmVuY3kgPSBNYXRoLm1heCgxLCBjb25maWcuY29uY3VycmVuY3kgPz8gMSk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjb25jdXJyZW5jeTsgaSArPSAxKSB7XG5cdFx0XHR2b2lkIHRoaXMucnVuQ29uc3VtZXJMb29wKHN0cmVhbSwgZ3JvdXAsIGNvbmZpZywgaGFuZGxlciwgcnVubmVyLCBzdGF0cyk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBydW5Db25zdW1lckxvb3AoXG5cdFx0c3RyZWFtOiBzdHJpbmcsXG5cdFx0Z3JvdXA6IHN0cmluZyxcblx0XHRjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzLFxuXHRcdGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPixcblx0XHRydW5uZXI6IFF1ZXVlUnVubmVyLFxuXHRcdHN0YXRzOiBRdWV1ZVN0YXRzQ291bnRlcnMsXG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5jbGllbnQpIHJldHVybjtcblx0XHRydW5uZXIubG9vcHMgKz0gMTtcblx0XHR0cnkge1xuXHRcdFx0d2hpbGUgKCFydW5uZXIuc3RvcCkge1xuXHRcdFx0XHRsZXQgZW50cmllczogQXJyYXk8W3N0cmluZywgQXJyYXk8W3N0cmluZywgc3RyaW5nW11dPl0+IHwgbnVsbCA9IG51bGw7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0ZW50cmllcyA9IGF3YWl0IHRoaXMuY2xpZW50LnhyZWFkZ3JvdXAoXG5cdFx0XHRcdFx0XHRcIkdST1VQXCIsXG5cdFx0XHRcdFx0XHRncm91cCxcblx0XHRcdFx0XHRcdHRoaXMuY29uc3VtZXJOYW1lLFxuXHRcdFx0XHRcdFx0XCJDT1VOVFwiLFxuXHRcdFx0XHRcdFx0U3RyaW5nKHRoaXMuY29uZmlnLmNvdW50KSxcblx0XHRcdFx0XHRcdFwiQkxPQ0tcIixcblx0XHRcdFx0XHRcdFN0cmluZyh0aGlzLmNvbmZpZy5ibG9ja01zKSxcblx0XHRcdFx0XHRcdFwiU1RSRUFNU1wiLFxuXHRcdFx0XHRcdFx0c3RyZWFtLFxuXHRcdFx0XHRcdFx0XCI+XCIsXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0YXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpO1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICghZW50cmllcykgY29udGludWU7XG5cdFx0XHRcdGZvciAoY29uc3QgWywgbXNnc10gb2YgZW50cmllcykge1xuXHRcdFx0XHRcdGZvciAoY29uc3QgW2lkLCBmaWVsZHNdIG9mIG1zZ3MpIHtcblx0XHRcdFx0XHRcdGlmIChydW5uZXIuc3RvcCkgYnJlYWs7XG5cdFx0XHRcdFx0XHRzdGF0cy5hY3RpdmUgKz0gMTtcblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHBheWxvYWQgPSB0aGlzLmZpZWxkc1RvT2JqZWN0KGZpZWxkcyk7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGRhdGFTdHJpbmcgPSB0eXBlb2YgcGF5bG9hZC5kYXRhID09PSBcInN0cmluZ1wiID8gcGF5bG9hZC5kYXRhIDogXCJcIjtcblx0XHRcdFx0XHRcdFx0bGV0IGRhdGE6IHVua25vd247XG5cdFx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdFx0ZGF0YSA9IGRhdGFTdHJpbmcubGVuZ3RoID4gMCA/IEpTT04ucGFyc2UoZGF0YVN0cmluZykgOiBudWxsO1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdFx0XHRkYXRhID0gZGF0YVN0cmluZztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRjb25zdCBqb2I6IFdvcmtlckpvYiA9IHtcblx0XHRcdFx0XHRcdFx0XHRpZCxcblx0XHRcdFx0XHRcdFx0XHRkYXRhLFxuXHRcdFx0XHRcdFx0XHRcdGhlYWRlcnM6IHt9LFxuXHRcdFx0XHRcdFx0XHRcdHF1ZXVlOiBzdHJlYW0sXG5cdFx0XHRcdFx0XHRcdFx0cHJpb3JpdHk6IGNvbmZpZy5wcmlvcml0eSA/PyAwLFxuXHRcdFx0XHRcdFx0XHRcdGF0dGVtcHRzOiAwLFxuXHRcdFx0XHRcdFx0XHRcdG1heFJldHJpZXM6IGNvbmZpZy5yZXRyaWVzID8/IDAsXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlZEF0OiBuZXcgRGF0ZShOdW1iZXIucGFyc2VJbnQoaWQuc3BsaXQoXCItXCIpWzBdID8/IFN0cmluZyhEYXRlLm5vdygpKSwgMTApKSxcblx0XHRcdFx0XHRcdFx0XHR0aW1lb3V0OiBjb25maWcudGltZW91dCxcblx0XHRcdFx0XHRcdFx0XHRyYXc6IHsgaWQsIGZpZWxkcyB9LFxuXHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLmNsaWVudD8ueGFjayhzdHJlYW0sIGdyb3VwLCBpZCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRzdGF0cy5jb21wbGV0ZWQgKz0gMTtcblx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdGZhaWw6IGFzeW5jIChfZXJyOiBFcnJvcikgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdFx0YXdhaXQgaGFuZGxlcihqb2IpO1xuXHRcdFx0XHRcdFx0XHRpZiAoY29uZmlnLmFjayAhPT0gZmFsc2UpIGF3YWl0IHRoaXMuY2xpZW50Py54YWNrKHN0cmVhbSwgZ3JvdXAsIGlkKTtcblx0XHRcdFx0XHRcdFx0c3RhdHMuY29tcGxldGVkICs9IDE7XG5cdFx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdFx0XHRcdC8vIFBlbmRpbmcgZW50cnkgbGVmdCB1bmFja2VkIOKAlCBwaWNrZWQgdXAgYnkgWEFVVE9DTEFJTS5cblx0XHRcdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0XHRcdHN0YXRzLmFjdGl2ZSA9IE1hdGgubWF4KDAsIHN0YXRzLmFjdGl2ZSAtIDEpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZmluYWxseSB7XG5cdFx0XHRydW5uZXIubG9vcHMgLT0gMTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGZpZWxkc1RvT2JqZWN0KGZpZWxkczogc3RyaW5nW10pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcblx0XHRjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkgKz0gMikge1xuXHRcdFx0b3V0W2ZpZWxkc1tpXV0gPSBmaWVsZHNbaSArIDFdO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0O1xuXHR9XG5cblx0YXN5bmMgYWRkSm9iKFxuXHRcdHF1ZXVlOiBzdHJpbmcsXG5cdFx0ZGF0YTogdW5rbm93bixcblx0XHRvcHRzPzogeyBwcmlvcml0eT86IG51bWJlcjsgZGVsYXk/OiBudW1iZXI7IHJldHJpZXM/OiBudW1iZXI7IHRpbWVvdXQ/OiBudW1iZXI7IGpvYklkPzogc3RyaW5nIH0sXG5cdCk6IFByb21pc2U8c3RyaW5nPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCB8fCAhdGhpcy5jbGllbnQpIHRocm93IG5ldyBFcnJvcihcIltibG9rXVtyZWRpc10gbm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdGNvbnN0IHBheWxvYWQgPSB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiA/IGRhdGEgOiBKU09OLnN0cmluZ2lmeShkYXRhKTtcblx0XHRjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFtdO1xuXHRcdGlmIChvcHRzPy5qb2JJZCkgYXJncy5wdXNoKFwiTk9NS1NUUkVBTVwiKTtcblx0XHRjb25zdCBpZCA9IGF3YWl0IHRoaXMuY2xpZW50LnhhZGQocXVldWUsIFwiKlwiLCBcImRhdGFcIiwgcGF5bG9hZCwgXCJqb2JJZFwiLCBvcHRzPy5qb2JJZCA/PyBcIlwiKTtcblx0XHRyZXR1cm4gaWQ7XG5cdH1cblxuXHRhc3luYyBzdG9wUHJvY2Vzc2luZyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgcnVubmVyID0gdGhpcy5ydW5uZXJzLmdldChxdWV1ZSk7XG5cdFx0aWYgKHJ1bm5lcikgcnVubmVyLnN0b3AgPSB0cnVlO1xuXHR9XG5cblx0aXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuY29ubmVjdGVkO1xuXHR9XG5cblx0YXN5bmMgaGVhbHRoQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCB8fCAhdGhpcy5jbGllbnQpIHJldHVybiBmYWxzZTtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgcG9uZyA9IGF3YWl0IHRoaXMuY2xpZW50LnBpbmcoKTtcblx0XHRcdHJldHVybiBwb25nID09PSBcIlBPTkdcIjtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBnZXRRdWV1ZVN0YXRzKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPFdvcmtlclF1ZXVlU3RhdHM+IHtcblx0XHRjb25zdCBjb3VudGVycyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKSA/PyB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwLCBhY3RpdmU6IDAgfTtcblx0XHRsZXQgd2FpdGluZyA9IDA7XG5cdFx0dHJ5IHtcblx0XHRcdHdhaXRpbmcgPSAoYXdhaXQgdGhpcy5jbGllbnQ/LnhsZW4ocXVldWUpKSA/PyAwO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0LyogaWdub3JlICovXG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHR3YWl0aW5nLFxuXHRcdFx0YWN0aXZlOiBjb3VudGVycy5hY3RpdmUsXG5cdFx0XHRjb21wbGV0ZWQ6IGNvdW50ZXJzLmNvbXBsZXRlZCxcblx0XHRcdGZhaWxlZDogY291bnRlcnMuZmFpbGVkLFxuXHRcdFx0ZGVsYXllZDogMCxcblx0XHR9O1xuXHR9XG59XG4iXX0=
445
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVkaXNTdHJlYW1zQWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9SZWRpc1N0cmVhbXNBZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnREc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQThDbEMsTUFBTSxPQUFPLG1CQUFtQjtJQUN0QixRQUFRLEdBQUcsT0FBZ0IsQ0FBQztJQUNwQixNQUFNLENBQXFCO0lBQ3BDLE1BQU0sR0FBdUIsSUFBSSxDQUFDO0lBQ2xDLE9BQU8sR0FBNkIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM5QyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLEtBQUssR0FBb0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNuRCxZQUFZLEdBQUcsUUFBUSxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFcEQsWUFBWSxNQUFvQztRQUMvQyxJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ2IsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksV0FBVztZQUMzRCxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDM0UsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjO1lBQ3hELEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxFQUFFLEVBQUUs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UCxNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07WUFDdkIsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTO1lBQzdCLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtZQUN2QixPQUFPLEVBQUUsQ0FBQztTQUNWLENBQUM7SUFDSCxDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJlZGlzU3RyZWFtc0FkYXB0ZXIg4oCUIHYwLjcgUFIgNSDigJQgV29ya2VyIGFkYXB0ZXIgYmFja2VkIGJ5IFJlZGlzXG4gKiBTdHJlYW1zIHZpYSBgaW9yZWRpc2AuIENvbnN1bWVzIGZyb20gYSBzdHJlYW0gKHRoZSBgcXVldWVgIGZpZWxkKVxuICogd2l0aCBhIGNvbnN1bWVyIGdyb3VwIChgY29uc3VtZXJHcm91cGApOyBwcm9kdWNlcyB2aWEgYFhBRERgLlxuICpcbiAqIFNlbWFudGljczpcbiAqICAgLSAqKkNvbnN1bWVyIGdyb3VwcyoqOiByZXF1aXJlZC4gYGNvbnN1bWVyR3JvdXBgIGRlZmF1bHRzIHRvXG4gKiAgICAgYFwiJHtxdWV1ZX0tZ3JvdXBcImAuIFRoZSBncm91cCBpcyBhdXRvLWNyZWF0ZWQgKGBNS1NUUkVBTWAgb24gdGhlXG4gKiAgICAgc3RyZWFtIHRvbykgb24gZmlyc3QgYHByb2Nlc3MoKWAgY2FsbCwgYXQgdGhlIGBzdGFydEZyb21gIGN1cnNvclxuICogICAgIChgXCJsYXRlc3RcImAg4oaSIGAkYCBkZWZhdWx0LCBgXCJlYXJsaWVzdFwiYCDihpIgYDBgLCBvciBgZnJvbUJlZ2lubmluZ2ApLlxuICogICAtICoqQ29uc3VtZXIgbmFtZSoqOiBwZXItcHJvY2VzcyB1dWlkLCBzbyBtdWx0aXBsZSBpbnN0YW5jZXMgb2ZcbiAqICAgICB0aGUgc2FtZSB3b3JrZXIgcHJvY2VzcyBkb24ndCBzaGFyZSBwZW5kaW5nIGVudHJpZXMuXG4gKiAgIC0gKipBQ0sgLyByZXRyaWVzKio6IEFDSyBoYXBwZW5zIGV4YWN0bHkgb25jZSB2aWEgYGpvYi5jb21wbGV0ZSgpYFxuICogICAgIChzdWNjZXNzKSDigJQgdGhlIGNvbnN1bWVyIGxvb3AgZG9lcyBOT1QgZG91YmxlLUFDSy4gQSB0ZXJtaW5hbFxuICogICAgIGBqb2IuZmFpbChlcnIsIGZhbHNlKWAgWEFERHMgdGhlIHBheWxvYWQgdG8gYGRlYWRMZXR0ZXJRdWV1ZWBcbiAqICAgICAod2hlbiBjb25maWd1cmVkKSB0aGVuIFhBQ0tzIHRoZSBzb3VyY2Ugc28gaXQgaXNuJ3QgcmVkZWxpdmVyZWQuXG4gKiAgICAgQSByZXF1ZXVlIGBqb2IuZmFpbChlcnIsIHRydWUpYCBsZWF2ZXMgdGhlIGVudHJ5IHBlbmRpbmcgKHZpc2libGVcbiAqICAgICBpbiBgWFBFTkRJTkdgKSBmb3IgcmVkcml2ZS5cbiAqICAgLSAqKmFjazpmYWxzZSoqOiB0aGUgY29uc3VtZXIgcmVhZHMgd2l0aCBOT0FDSywgc28gUmVkaXMgbmV2ZXJcbiAqICAgICBhZGRzIGVudHJpZXMgdG8gdGhlIGdyb3VwJ3MgUEVMIOKAlCBhdC1tb3N0LW9uY2UsIG5vIGxlYWtlZCBwZW5kaW5nLlxuICogICAtICoqUmVkcml2ZSoqOiBhbiBpbi1wcm9jZXNzIHBlcmlvZGljIFhBVVRPQ0xBSU0gbG9vcCByZWNsYWltcyBzdGFsZVxuICogICAgIHBlbmRpbmcgZW50cmllcyAoaWRsZSA+IGBjb25maWcudGltZW91dGApIOKAlCBsZWZ0IGJ5IGEgY3Jhc2hlZFxuICogICAgIGNvbnN1bWVyIG9yIGEgcmVxdWV1ZSBgZmFpbChlcnIsIHRydWUpYCDigJQgYW5kIHJlLXJ1bnMgdGhlbSB0aHJvdWdoXG4gKiAgICAgdGhlIGhhbmRsZXIuIFJlZGlzIGJ1bXBzIGVhY2ggZW50cnkncyBkZWxpdmVyeSBjb3VudCBvbiBldmVyeVxuICogICAgIGNsYWltOyBvbmNlIGl0IGV4Y2VlZHMgYHJldHJpZXMgKyAxYCB0aGUgZW50cnkgaXMgZGVhZC1sZXR0ZXJlZFxuICogICAgICh3aGVuIGBkZWFkTGV0dGVyUXVldWVgIGlzIHNldCkgYW5kIFhBQ0tlZC4gVGhlIHJlZHJpdmUgbG9vcCBvbmx5XG4gKiAgICAgcnVucyB3aGVuIGBjb25maWcudGltZW91dGAgaXMgc2V0IChpdCBJUyB0aGUgaWRsZSB0aHJlc2hvbGQg4oCUIHdpdGhcbiAqICAgICBubyB0aW1lb3V0IGEgc2xvdy1idXQtYWxpdmUgaGFuZGxlciBpcyBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIGFcbiAqICAgICBkZWFkIG9uZSkgYW5kIE5PVCB1bmRlciBgYWNrOmZhbHNlYCAobm90aGluZyBsYW5kcyBpbiB0aGUgUEVMKS5cbiAqICAgLSAqKk5vIG5hdGl2ZSBkZWxheSAvIHByaW9yaXR5Kio6IFJlZGlzIFN0cmVhbXMgaGFzIG5laXRoZXIuIGBhZGRKb2JgXG4gKiAgICAgVEhST1dTIG9uIGBvcHRzLmRlbGF5YCAvIGBvcHRzLnByaW9yaXR5YCByYXRoZXIgdGhhbiBzaWxlbnRseVxuICogICAgIGRyb3BwaW5nIHRoZW0g4oCUIHVzZSBhIHNjaGVkdWxlciB0cmlnZ2VyIGZvciBkZWxheWVkIHdvcmsuXG4gKiAgIC0gKipDb25jdXJyZW5jeSoqOiBlYWNoIG9mIHRoZSBgY29uY3VycmVuY3lgIGNvbnN1bWVyIGxvb3BzIG93bnMgYVxuICogICAgIERFRElDQVRFRCBpb3JlZGlzIGNvbm5lY3Rpb24gKGBjbGllbnQuZHVwbGljYXRlKClgKSBzbyB0aGVpclxuICogICAgIGJsb2NraW5nIFhSRUFER1JPVVAgY2FsbHMgcnVuIGluIHBhcmFsbGVsIGluc3RlYWQgb2Ygc2VyaWFsaXppbmcgb25cbiAqICAgICBvbmUgc2hhcmVkIHNvY2tldCDigJQgaW9yZWRpcyByZXF1aXJlcyBhIHNlcGFyYXRlIGNsaWVudCBwZXIgYmxvY2tpbmdcbiAqICAgICBjb21tYW5kLiBUaGUgc2hhcmVkIGB0aGlzLmNsaWVudGAgaGFuZGxlcyBub24tYmxvY2tpbmcgb3BzXG4gKiAgICAgKFhBREQgLyBYQUNLIC8gWEdST1VQIC8gWEFVVE9DTEFJTSkuXG4gKlxuICogUmVxdWlyZXMgYGlvcmVkaXNgIGFzIGEgcGVlciBkZXBlbmRlbmN5OlxuICpcbiAqICAgICBidW4gYWRkIGlvcmVkaXNcbiAqXG4gKiBFbnZpcm9ubWVudCB2YXJpYWJsZXM6XG4gKiAgIC0gYFJFRElTX0hPU1RgIChkZWZhdWx0IGBsb2NhbGhvc3RgKVxuICogICAtIGBSRURJU19QT1JUYCAoZGVmYXVsdCBgNjM3OWApXG4gKiAgIC0gYFJFRElTX1BBU1NXT1JEYFxuICogICAtIGBSRURJU19EQmBcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdvcmtlclRyaWdnZXJPcHRzIH0gZnJvbSBcIkBibG9ranMvaGVscGVyXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB0eXBlIHsgV29ya2VyQWRhcHRlciwgV29ya2VySm9iLCBXb3JrZXJRdWV1ZVN0YXRzIH0gZnJvbSBcIi4uL1dvcmtlclRyaWdnZXJcIjtcblxuZXhwb3J0IGludGVyZmFjZSBSZWRpc1N0cmVhbXNDb25maWcge1xuXHRob3N0OiBzdHJpbmc7XG5cdHBvcnQ6IG51bWJlcjtcblx0cGFzc3dvcmQ/OiBzdHJpbmc7XG5cdGRiPzogbnVtYmVyO1xuXHRibG9ja01zOiBudW1iZXI7XG5cdGNvdW50OiBudW1iZXI7XG59XG5cbi8qKiBPbmUgcmVjbGFpbWVkL3BlbmRpbmcgZW50cnkgYXMgYFtpZCwgZmllbGRzLCBkZWxpdmVyeUNvdW50XWAuICovXG50eXBlIFN0cmVhbU1lc3NhZ2UgPSBbc3RyaW5nLCBzdHJpbmdbXV07XG5cbmludGVyZmFjZSBSZWRpc0NsaWVudCB7XG5cdHhhZGQoc3RyZWFtOiBzdHJpbmcsIC4uLmFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmc+O1xuXHR4cmVhZGdyb3VwKC4uLmFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxBcnJheTxbc3RyaW5nLCBBcnJheTxTdHJlYW1NZXNzYWdlPl0+IHwgbnVsbD47XG5cdHhncm91cCguLi5hcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nPjtcblx0eGFjayhzdHJlYW06IHN0cmluZywgZ3JvdXA6IHN0cmluZywgLi4uaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8bnVtYmVyPjtcblx0eGxlbihzdHJlYW06IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPjtcblx0eHBlbmRpbmcoc3RyZWFtOiBzdHJpbmcsIGdyb3VwOiBzdHJpbmcsIC4uLmFyZ3M6IChzdHJpbmcgfCBudW1iZXIpW10pOiBQcm9taXNlPHVua25vd24+O1xuXHQvLyBYQVVUT0NMQUlNIGtleSBncm91cCBjb25zdW1lciBtaW4taWRsZS10aW1lIHN0YXJ0IFtDT1VOVCBuXSDihpJcblx0Ly8gW2N1cnNvciwgZW50cmllc1tbaWQsIGZpZWxkc11dLCBkZWxldGVkSWRzW11dLlxuXHR4YXV0b2NsYWltKC4uLmFyZ3M6IChzdHJpbmcgfCBudW1iZXIpW10pOiBQcm9taXNlPFtzdHJpbmcsIEFycmF5PFN0cmVhbU1lc3NhZ2U+LCBzdHJpbmdbXV0+O1xuXHRwaW5nKCk6IFByb21pc2U8c3RyaW5nPjtcblx0cXVpdCgpOiBQcm9taXNlPHN0cmluZz47XG5cdC8vIERlZGljYXRlZCBjb25uZWN0aW9uIGZvciBhIGJsb2NraW5nIGNvbnN1bWVyIGxvb3Ag4oCUIGlvcmVkaXMgcmVxdWlyZXMgYVxuXHQvLyBzZXBhcmF0ZSBjbGllbnQgcGVyIGNvbmN1cnJlbnQgYmxvY2tpbmcgY29tbWFuZC5cblx0ZHVwbGljYXRlKCk6IFJlZGlzQ2xpZW50O1xufVxuXG5pbnRlcmZhY2UgUXVldWVSdW5uZXIge1xuXHRzdG9wOiBib29sZWFuO1xuXHRsb29wczogbnVtYmVyO1xuXHQvKiogUGVyLWxvb3AgZGVkaWNhdGVkIGNvbm5lY3Rpb25zICsgdGhlIHJlZHJpdmUgdGltZXIsIHRvcm4gZG93biBvbiBzdG9wLiAqL1xuXHRjb25uczogUmVkaXNDbGllbnRbXTtcblx0cmVkcml2ZT86IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPjtcbn1cblxuaW50ZXJmYWNlIFF1ZXVlU3RhdHNDb3VudGVycyB7XG5cdGNvbXBsZXRlZDogbnVtYmVyO1xuXHRmYWlsZWQ6IG51bWJlcjtcblx0YWN0aXZlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWRpc1N0cmVhbXNBZGFwdGVyIGltcGxlbWVudHMgV29ya2VyQWRhcHRlciB7XG5cdHJlYWRvbmx5IHByb3ZpZGVyID0gXCJyZWRpc1wiIGFzIGNvbnN0O1xuXHRwcml2YXRlIHJlYWRvbmx5IGNvbmZpZzogUmVkaXNTdHJlYW1zQ29uZmlnO1xuXHRwcml2YXRlIGNsaWVudDogUmVkaXNDbGllbnQgfCBudWxsID0gbnVsbDtcblx0cHJpdmF0ZSBydW5uZXJzOiBNYXA8c3RyaW5nLCBRdWV1ZVJ1bm5lcj4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG5cdHByaXZhdGUgc3RhdHM6IE1hcDxzdHJpbmcsIFF1ZXVlU3RhdHNDb3VudGVycz4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgY29uc3VtZXJOYW1lID0gYGJsb2stJHt1dWlkKCkuc2xpY2UoMCwgOCl9YDtcblxuXHRjb25zdHJ1Y3Rvcihjb25maWc/OiBQYXJ0aWFsPFJlZGlzU3RyZWFtc0NvbmZpZz4pIHtcblx0XHR0aGlzLmNvbmZpZyA9IHtcblx0XHRcdGhvc3Q6IGNvbmZpZz8uaG9zdCA/PyBwcm9jZXNzLmVudi5SRURJU19IT1NUID8/IFwibG9jYWxob3N0XCIsXG5cdFx0XHRwb3J0OiBjb25maWc/LnBvcnQgPz8gTnVtYmVyLnBhcnNlSW50KHByb2Nlc3MuZW52LlJFRElTX1BPUlQgPz8gXCI2Mzc5XCIsIDEwKSxcblx0XHRcdHBhc3N3b3JkOiBjb25maWc/LnBhc3N3b3JkID8/IHByb2Nlc3MuZW52LlJFRElTX1BBU1NXT1JELFxuXHRcdFx0ZGI6IGNvbmZpZz8uZGIgPz8gTnVtYmVyLnBhcnNlSW50KHByb2Nlc3MuZW52LlJFRElTX0RCID8/IFwiMFwiLCAxMCksXG5cdFx0XHRibG9ja01zOiBjb25maWc/LmJsb2NrTXMgPz8gNTAwMCxcblx0XHRcdGNvdW50OiBjb25maWc/LmNvdW50ID8/IDEwLFxuXHRcdH07XG5cdH1cblxuXHRhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICh0aGlzLmNvbm5lY3RlZCkgcmV0dXJuO1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IGlvcmVkaXMgaXMgYSBydW50aW1lIHBlZXIgZGVwLlxuXHRcdFx0Y29uc3QgaW9yZWRpczogYW55ID0gYXdhaXQgaW1wb3J0KFwiaW9yZWRpc1wiKTtcblx0XHRcdGNvbnN0IElPUmVkaXMgPSBpb3JlZGlzLmRlZmF1bHQgPz8gaW9yZWRpcy5SZWRpcyA/PyBpb3JlZGlzO1xuXHRcdFx0dGhpcy5jbGllbnQgPSBuZXcgSU9SZWRpcyh7XG5cdFx0XHRcdGhvc3Q6IHRoaXMuY29uZmlnLmhvc3QsXG5cdFx0XHRcdHBvcnQ6IHRoaXMuY29uZmlnLnBvcnQsXG5cdFx0XHRcdHBhc3N3b3JkOiB0aGlzLmNvbmZpZy5wYXNzd29yZCxcblx0XHRcdFx0ZGI6IHRoaXMuY29uZmlnLmRiLFxuXHRcdFx0fSkgYXMgUmVkaXNDbGllbnQ7XG5cdFx0XHRhd2FpdCB0aGlzLmNsaWVudC5waW5nKCk7XG5cdFx0XHR0aGlzLmNvbm5lY3RlZCA9IHRydWU7XG5cdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdGBbYmxva11bcmVkaXNdIGNvbm5lY3QgZmFpbGVkOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9LiBJbnN0YWxsIGlvcmVkaXMgYXMgYSBwZWVyIGRlcGVuZGVuY3k6IGJ1biBhZGQgaW9yZWRpc2AsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkgcmV0dXJuO1xuXHRcdGZvciAoY29uc3QgcnVubmVyIG9mIHRoaXMucnVubmVycy52YWx1ZXMoKSkge1xuXHRcdFx0cnVubmVyLnN0b3AgPSB0cnVlO1xuXHRcdFx0aWYgKHJ1bm5lci5yZWRyaXZlKSBjbGVhckludGVydmFsKHJ1bm5lci5yZWRyaXZlKTtcblx0XHR9XG5cdFx0Ly8gV2FpdCBmb3IgaW4tZmxpZ2h0IGxvb3BzIHRvIGRyYWluLlxuXHRcdGNvbnN0IGRyYWluRGVhZGxpbmUgPSBEYXRlLm5vdygpICsgMjAwMDtcblx0XHR3aGlsZSAoRGF0ZS5ub3coKSA8IGRyYWluRGVhZGxpbmUpIHtcblx0XHRcdGxldCBhY3RpdmUgPSAwO1xuXHRcdFx0Zm9yIChjb25zdCByIG9mIHRoaXMucnVubmVycy52YWx1ZXMoKSkgYWN0aXZlICs9IHIubG9vcHM7XG5cdFx0XHRpZiAoYWN0aXZlID09PSAwKSBicmVhaztcblx0XHRcdGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUwKSk7XG5cdFx0fVxuXHRcdC8vIENsb3NlIGVhY2ggbG9vcCdzIGRlZGljYXRlZCBibG9ja2luZyBjb25uZWN0aW9uLlxuXHRcdGZvciAoY29uc3QgcnVubmVyIG9mIHRoaXMucnVubmVycy52YWx1ZXMoKSkge1xuXHRcdFx0Zm9yIChjb25zdCBjb25uIG9mIHJ1bm5lci5jb25ucykge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGF3YWl0IGNvbm4ucXVpdCgpO1xuXHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHQvKiBpZ25vcmUgKi9cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLnJ1bm5lcnMuY2xlYXIoKTtcblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgdGhpcy5jbGllbnQ/LnF1aXQoKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdC8qIGlnbm9yZSAqL1xuXHRcdH1cblx0XHR0aGlzLmNsaWVudCA9IG51bGw7XG5cdFx0dGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcblx0fVxuXG5cdGFzeW5jIHByb2Nlc3MoY29uZmlnOiBXb3JrZXJUcmlnZ2VyT3B0cywgaGFuZGxlcjogKGpvYjogV29ya2VySm9iKSA9PiBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCB8fCAhdGhpcy5jbGllbnQpIHRocm93IG5ldyBFcnJvcihcIltibG9rXVtyZWRpc10gbm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdGNvbnN0IHN0cmVhbSA9IGNvbmZpZy5xdWV1ZTtcblx0XHRjb25zdCBncm91cCA9IGNvbmZpZy5jb25zdW1lckdyb3VwID8/IGAke3N0cmVhbX0tZ3JvdXBgO1xuXHRcdC8vIENyZWF0ZSBncm91cCArIHN0cmVhbSBpZiBtaXNzaW5nLCBhdCB0aGUgcmVxdWVzdGVkIHN0YXJ0IGN1cnNvci5cblx0XHQvLyBYR1JPVVAgQ1JFQVRFIHdpdGggTUtTVFJFQU0gZXJyb3JzIHdpdGggXCJCVVNZR1JPVVBcIiBpZiB0aGUgZ3JvdXBcblx0XHQvLyBhbHJlYWR5IGV4aXN0cyDigJQgc3dhbGxvdyBpdCAodGhlIGN1cnNvciBpcyBmaXhlZCBhdCBjcmVhdGlvbikuXG5cdFx0Y29uc3Qgc3RhcnRJZCA9IHRoaXMucmVzb2x2ZVN0YXJ0SWQoY29uZmlnKTtcblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgdGhpcy5jbGllbnQueGdyb3VwKFwiQ1JFQVRFXCIsIHN0cmVhbSwgZ3JvdXAsIHN0YXJ0SWQsIFwiTUtTVFJFQU1cIik7XG5cdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRpZiAoIS9CVVNZR1JPVVAvaS50ZXN0KChlcnIgYXMgRXJyb3IpLm1lc3NhZ2UpKSB0aHJvdyBlcnI7XG5cdFx0fVxuXG5cdFx0Y29uc3QgcnVubmVyOiBRdWV1ZVJ1bm5lciA9IHsgc3RvcDogZmFsc2UsIGxvb3BzOiAwLCBjb25uczogW10gfTtcblx0XHR0aGlzLnJ1bm5lcnMuc2V0KHN0cmVhbSwgcnVubmVyKTtcblx0XHR0aGlzLnN0YXRzLnNldChzdHJlYW0sIHsgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGFjdGl2ZTogMCB9KTtcblx0XHRjb25zdCBzdGF0cyA9IHRoaXMuc3RhdHMuZ2V0KHN0cmVhbSkgYXMgUXVldWVTdGF0c0NvdW50ZXJzO1xuXG5cdFx0Y29uc3QgY29uY3VycmVuY3kgPSBNYXRoLm1heCgxLCBjb25maWcuY29uY3VycmVuY3kgPz8gMSk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjb25jdXJyZW5jeTsgaSArPSAxKSB7XG5cdFx0XHQvLyBFYWNoIGJsb2NraW5nIFhSRUFER1JPVVAgbG9vcCBuZWVkcyBpdHMgT1dOIGNvbm5lY3Rpb24g4oCUIGlvcmVkaXNcblx0XHRcdC8vIHNlcmlhbGl6ZXMgY29tbWFuZHMgb24gYSBzaW5nbGUgc29ja2V0LCBzbyBOIGxvb3BzIHNoYXJpbmcgb25lXG5cdFx0XHQvLyBjbGllbnQgd291bGQgdGFrZSB0dXJucyBvbiB0aGUgQkxPQ0ssIGdpdmluZyB6ZXJvIHJlYWwgcGFyYWxsZWxpc20uXG5cdFx0XHRjb25zdCBjb25uID0gdGhpcy5jbGllbnQuZHVwbGljYXRlKCk7XG5cdFx0XHRydW5uZXIuY29ubnMucHVzaChjb25uKTtcblx0XHRcdHZvaWQgdGhpcy5ydW5Db25zdW1lckxvb3AoY29ubiwgc3RyZWFtLCBncm91cCwgY29uZmlnLCBoYW5kbGVyLCBydW5uZXIsIHN0YXRzKTtcblx0XHR9XG5cblx0XHQvLyBSZWRyaXZlOiByZWNsYWltIGVudHJpZXMgbGVmdCBwZW5kaW5nIGJ5IGEgY3Jhc2hlZCBjb25zdW1lciBvciBhXG5cdFx0Ly8gcmVxdWV1ZSBgZmFpbChlcnIsIHRydWUpYC4gR2F0ZWQgb24gYGNvbmZpZy50aW1lb3V0YCAodGhlIGlkbGVcblx0XHQvLyB0aHJlc2hvbGQpIGFuZCBvZmYgdW5kZXIgTk9BQ0sgKG5vdGhpbmcgbGFuZHMgaW4gdGhlIFBFTCkuXG5cdFx0Y29uc3Qgbm9BY2sgPSBjb25maWcuYWNrID09PSBmYWxzZTtcblx0XHRpZiAoY29uZmlnLnRpbWVvdXQgJiYgY29uZmlnLnRpbWVvdXQgPiAwICYmICFub0Fjaykge1xuXHRcdFx0Y29uc3QgbWluSWRsZSA9IGNvbmZpZy50aW1lb3V0O1xuXHRcdFx0cnVubmVyLnJlZHJpdmUgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG5cdFx0XHRcdHZvaWQgdGhpcy5yZWRyaXZlT25jZShzdHJlYW0sIGdyb3VwLCBjb25maWcsIGhhbmRsZXIsIHJ1bm5lciwgc3RhdHMsIG1pbklkbGUpO1xuXHRcdFx0fSwgbWluSWRsZSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBydW5Db25zdW1lckxvb3AoXG5cdFx0Y29ubjogUmVkaXNDbGllbnQsXG5cdFx0c3RyZWFtOiBzdHJpbmcsXG5cdFx0Z3JvdXA6IHN0cmluZyxcblx0XHRjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzLFxuXHRcdGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPixcblx0XHRydW5uZXI6IFF1ZXVlUnVubmVyLFxuXHRcdHN0YXRzOiBRdWV1ZVN0YXRzQ291bnRlcnMsXG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdC8vIGFjazpmYWxzZSDihpIgYXQtbW9zdC1vbmNlLiBOT0FDSyB0ZWxscyBSZWRpcyB0byBkZWxpdmVyIFdJVEhPVVRcblx0XHQvLyBhZGRpbmcgdGhlIGVudHJ5IHRvIHRoZSBncm91cCdzIHBlbmRpbmctZW50cmllcyBsaXN0LCBzbyBhIGhhbmRsZXJcblx0XHQvLyB0aHJvdyBuZXZlciBsZWF2ZXMgYSBsZWFrZWQgcGVuZGluZyBlbnRyeSB0byByZWRyaXZlLiBOT0FDSyBzaXRzXG5cdFx0Ly8gYWZ0ZXIgdGhlIGNvbnN1bWVyIG5hbWUsIGJlZm9yZSBTVFJFQU1TLlxuXHRcdGNvbnN0IG5vQWNrID0gY29uZmlnLmFjayA9PT0gZmFsc2U7XG5cdFx0cnVubmVyLmxvb3BzICs9IDE7XG5cdFx0dHJ5IHtcblx0XHRcdHdoaWxlICghcnVubmVyLnN0b3ApIHtcblx0XHRcdFx0bGV0IGVudHJpZXM6IEFycmF5PFtzdHJpbmcsIEFycmF5PFN0cmVhbU1lc3NhZ2U+XT4gfCBudWxsID0gbnVsbDtcblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRjb25zdCByZWFkQXJncyA9IFtcblx0XHRcdFx0XHRcdFwiR1JPVVBcIixcblx0XHRcdFx0XHRcdGdyb3VwLFxuXHRcdFx0XHRcdFx0dGhpcy5jb25zdW1lck5hbWUsXG5cdFx0XHRcdFx0XHRcIkNPVU5UXCIsXG5cdFx0XHRcdFx0XHRTdHJpbmcodGhpcy5jb25maWcuY291bnQpLFxuXHRcdFx0XHRcdFx0XCJCTE9DS1wiLFxuXHRcdFx0XHRcdFx0U3RyaW5nKHRoaXMuY29uZmlnLmJsb2NrTXMpLFxuXHRcdFx0XHRcdF07XG5cdFx0XHRcdFx0aWYgKG5vQWNrKSByZWFkQXJncy5wdXNoKFwiTk9BQ0tcIik7XG5cdFx0XHRcdFx0cmVhZEFyZ3MucHVzaChcIlNUUkVBTVNcIiwgc3RyZWFtLCBcIj5cIik7XG5cdFx0XHRcdFx0Ly8gQmxvY2tpbmcgcmVhZCBvbiB0aGlzIGxvb3AncyBPV04gY29ubmVjdGlvbiBzbyBgY29uY3VycmVuY3lgXG5cdFx0XHRcdFx0Ly8gbG9vcHMgZG9uJ3Qgc2VyaWFsaXplIG9uIGEgc2luZ2xlIHNoYXJlZCBzb2NrZXQuXG5cdFx0XHRcdFx0ZW50cmllcyA9IGF3YWl0IGNvbm4ueHJlYWRncm91cCguLi5yZWFkQXJncyk7XG5cdFx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRcdGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEwMDApKTtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIWVudHJpZXMpIGNvbnRpbnVlO1xuXHRcdFx0XHRmb3IgKGNvbnN0IFssIG1zZ3NdIG9mIGVudHJpZXMpIHtcblx0XHRcdFx0XHRmb3IgKGNvbnN0IFtpZCwgZmllbGRzXSBvZiBtc2dzKSB7XG5cdFx0XHRcdFx0XHRpZiAocnVubmVyLnN0b3ApIGJyZWFrO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wcm9jZXNzTWVzc2FnZShpZCwgZmllbGRzLCBzdHJlYW0sIGdyb3VwLCBjb25maWcsIGhhbmRsZXIsIHN0YXRzLCBub0Fjayk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdHJ1bm5lci5sb29wcyAtPSAxO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSdW4gb25lIGRlbGl2ZXJlZC9yZWNsYWltZWQgZW50cnkgdGhyb3VnaCB0aGUgaGFuZGxlciwgYnVpbGRpbmcgdGhlXG5cdCAqIGBXb3JrZXJKb2JgIHdpdGggdGhlIEFDSy1vbmNlIGd1YXJkLiBTaGFyZWQgYnkgdGhlIG1haW4gY29uc3VtZXIgbG9vcFxuXHQgKiBhbmQgdGhlIHJlZHJpdmUgbG9vcCBzbyBib3RoIHBhdGhzIEFDSyAvIERMUSAvIGNvdW50IGlkZW50aWNhbGx5LlxuXHQgKlxuXHQgKiBgYXR0ZW1wdHNgIHNlZWRzIGBqb2IuYXR0ZW1wdHNgICgwIG9uIGZpcnN0IGRlbGl2ZXJ5LCB0aGUgcmVkcml2ZVxuXHQgKiBkZWxpdmVyeS1jb3VudCBvbiByZWNsYWltKSBzbyBgV29ya2VyVHJpZ2dlci5oYW5kbGVKb2JgIHJvdXRlcyB0byB0aGUgRExRXG5cdCAqIG9uY2UgcmV0cmllcyBhcmUgZXhoYXVzdGVkIGluc3RlYWQgb2YgcmVxdWV1ZWluZyBmb3JldmVyLlxuXHQgKi9cblx0cHJpdmF0ZSBhc3luYyBwcm9jZXNzTWVzc2FnZShcblx0XHRpZDogc3RyaW5nLFxuXHRcdGZpZWxkczogc3RyaW5nW10sXG5cdFx0c3RyZWFtOiBzdHJpbmcsXG5cdFx0Z3JvdXA6IHN0cmluZyxcblx0XHRjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzLFxuXHRcdGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPixcblx0XHRzdGF0czogUXVldWVTdGF0c0NvdW50ZXJzLFxuXHRcdG5vQWNrOiBib29sZWFuLFxuXHRcdGF0dGVtcHRzID0gMCxcblx0KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0c3RhdHMuYWN0aXZlICs9IDE7XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHBheWxvYWQgPSB0aGlzLmZpZWxkc1RvT2JqZWN0KGZpZWxkcyk7XG5cdFx0XHRjb25zdCBkYXRhU3RyaW5nID0gdHlwZW9mIHBheWxvYWQuZGF0YSA9PT0gXCJzdHJpbmdcIiA/IHBheWxvYWQuZGF0YSA6IFwiXCI7XG5cdFx0XHRsZXQgZGF0YTogdW5rbm93bjtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhU3RyaW5nLmxlbmd0aCA+IDAgPyBKU09OLnBhcnNlKGRhdGFTdHJpbmcpIDogbnVsbDtcblx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRkYXRhID0gZGF0YVN0cmluZztcblx0XHRcdH1cblx0XHRcdC8vIEFDSyBleGFjdGx5IG9uY2UuIGNvbXBsZXRlKCkgYW5kIGZhaWwoKSBib3RoIHJvdXRlIHRocm91Z2ggdGhpc1xuXHRcdFx0Ly8gZ3VhcmQgc28gYSBoYW5kbGVyIHRoYXQgY2FsbHMgam9iLmNvbXBsZXRlKCkgQU5EIHJldHVybnMgKG9yIGZhaWxzXG5cdFx0XHQvLyBhZnRlciBjb21wbGV0aW5nKSBuZXZlciBkb3VibGUtQUNLcyBvciBkb3VibGUtY291bnRzLiBVbmRlciBOT0FDS1xuXHRcdFx0Ly8gdGhlcmUncyBub3RoaW5nIGluIHRoZSBQRUwgdG8gQUNLLCBidXQgdGhlIGd1YXJkIHN0aWxsIGtlZXBzIHRoZVxuXHRcdFx0Ly8gY291bnRlcnMgaG9uZXN0LlxuXHRcdFx0bGV0IGFja2VkID0gZmFsc2U7XG5cdFx0XHRjb25zdCBhY2tPbmNlID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuXHRcdFx0XHRpZiAoYWNrZWQpIHJldHVybjtcblx0XHRcdFx0YWNrZWQgPSB0cnVlO1xuXHRcdFx0XHRpZiAoIW5vQWNrKSBhd2FpdCB0aGlzLmNsaWVudD8ueGFjayhzdHJlYW0sIGdyb3VwLCBpZCk7XG5cdFx0XHR9O1xuXHRcdFx0Y29uc3QgZGxxID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuXHRcdFx0XHRpZiAoY29uZmlnLmRlYWRMZXR0ZXJRdWV1ZSkge1xuXHRcdFx0XHRcdGNvbnN0IHJhdyA9IHRoaXMuZmllbGRzVG9PYmplY3QoZmllbGRzKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLmNsaWVudD8ueGFkZChjb25maWcuZGVhZExldHRlclF1ZXVlLCBcIipcIiwgXCJkYXRhXCIsIHJhdy5kYXRhID8/IFwiXCIsIFwiam9iSWRcIiwgcmF3LmpvYklkID8/IGlkKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRhd2FpdCBhY2tPbmNlKCk7XG5cdFx0XHR9O1xuXHRcdFx0Y29uc3Qgam9iOiBXb3JrZXJKb2IgPSB7XG5cdFx0XHRcdGlkLFxuXHRcdFx0XHRkYXRhLFxuXHRcdFx0XHRoZWFkZXJzOiB7fSxcblx0XHRcdFx0cXVldWU6IHN0cmVhbSxcblx0XHRcdFx0cHJpb3JpdHk6IGNvbmZpZy5wcmlvcml0eSA/PyAwLFxuXHRcdFx0XHRhdHRlbXB0cyxcblx0XHRcdFx0bWF4UmV0cmllczogY29uZmlnLnJldHJpZXMgPz8gMCxcblx0XHRcdFx0Y3JlYXRlZEF0OiBuZXcgRGF0ZShOdW1iZXIucGFyc2VJbnQoaWQuc3BsaXQoXCItXCIpWzBdID8/IFN0cmluZyhEYXRlLm5vdygpKSwgMTApKSxcblx0XHRcdFx0dGltZW91dDogY29uZmlnLnRpbWVvdXQsXG5cdFx0XHRcdHJhdzogeyBpZCwgZmllbGRzIH0sXG5cdFx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0aWYgKGFja2VkKSByZXR1cm47XG5cdFx0XHRcdFx0YXdhaXQgYWNrT25jZSgpO1xuXHRcdFx0XHRcdHN0YXRzLmNvbXBsZXRlZCArPSAxO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRmYWlsOiBhc3luYyAoX2VycjogRXJyb3IsIHJlcXVldWU/OiBib29sZWFuKSA9PiB7XG5cdFx0XHRcdFx0aWYgKGFja2VkKSByZXR1cm47XG5cdFx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdFx0aWYgKHJlcXVldWUpIHtcblx0XHRcdFx0XHRcdC8vIExlYXZlIHRoZSBlbnRyeSBwZW5kaW5nIChpbiB0aGUgUEVMKSDigJQgdGhlIHJlZHJpdmUgbG9vcFxuXHRcdFx0XHRcdFx0Ly8gcmVjbGFpbXMgaXQgb25jZSBpdCdzIGlkbGUgPiB0aW1lb3V0LiBOby1vcCB1bmRlciBOT0FDSy5cblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gVGVybWluYWwgZmFpbHVyZTogZGVhZC1sZXR0ZXIgdGhlbiBBQ0sgdGhlIHNvdXJjZS4gTm8tb3AgRExRXG5cdFx0XHRcdFx0Ly8gd2hlbiB1bnNldC5cblx0XHRcdFx0XHRhd2FpdCBkbHEoKTtcblx0XHRcdFx0fSxcblx0XHRcdH07XG5cdFx0XHRhd2FpdCBoYW5kbGVyKGpvYik7XG5cdFx0XHQvLyBoYW5kbGVyIChXb3JrZXJUcmlnZ2VyLmhhbmRsZUpvYikgb3ducyBBQ0sgdmlhIGNvbXBsZXRlKCkvZmFpbCgpLlxuXHRcdH0gY2F0Y2gge1xuXHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHQvLyBIYW5kbGVyIHRocmV3IHdpdGhvdXQgc2V0dGxpbmcg4oCUIGxlYXZlIHRoZSBlbnRyeSBwZW5kaW5nOyB0aGVcblx0XHRcdC8vIHJlZHJpdmUgbG9vcCByZWNsYWltcyBhbmQgcmV0cmllcyBpdC5cblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0c3RhdHMuYWN0aXZlID0gTWF0aC5tYXgoMCwgc3RhdHMuYWN0aXZlIC0gMSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE9uZSByZWRyaXZlIHBhc3M6IFhBVVRPQ0xBSU0gZW50cmllcyBpZGxlIGxvbmdlciB0aGFuIGBtaW5JZGxlYCAoYVxuXHQgKiBjcmFzaGVkIGNvbnN1bWVyIG9yIGEgcmVxdWV1ZSBgZmFpbGApIGJhY2sgdG8gdGhpcyBjb25zdW1lciwgdGhlbiByZS1ydW5cblx0ICogZWFjaC4gUmVkaXMgYnVtcHMgZWFjaCBlbnRyeSdzIGRlbGl2ZXJ5IGNvdW50IG9uIGV2ZXJ5IGNsYWltOyBvbmNlIGl0XG5cdCAqIGV4Y2VlZHMgYHJldHJpZXMgKyAxYCB0aGUgZW50cnkgaXMgZGVhZC1sZXR0ZXJlZCBhbmQgQUNLZWQgcmF0aGVyIHRoYW5cblx0ICogcmVjbGFpbWVkIGFnYWluIGZvcmV2ZXIuXG5cdCAqL1xuXHRwcml2YXRlIGFzeW5jIHJlZHJpdmVPbmNlKFxuXHRcdHN0cmVhbTogc3RyaW5nLFxuXHRcdGdyb3VwOiBzdHJpbmcsXG5cdFx0Y29uZmlnOiBXb3JrZXJUcmlnZ2VyT3B0cyxcblx0XHRoYW5kbGVyOiAoam9iOiBXb3JrZXJKb2IpID0+IFByb21pc2U8dm9pZD4sXG5cdFx0cnVubmVyOiBRdWV1ZVJ1bm5lcixcblx0XHRzdGF0czogUXVldWVTdGF0c0NvdW50ZXJzLFxuXHRcdG1pbklkbGU6IG51bWJlcixcblx0KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHJ1bm5lci5zdG9wIHx8ICF0aGlzLmNsaWVudCkgcmV0dXJuO1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBYQVVUT0NMQUlNIGtleSBncm91cCBjb25zdW1lciBtaW4taWRsZS10aW1lIHN0YXJ0IFtDT1VOVCBuXS5cblx0XHRcdGNvbnN0IFssIGNsYWltZWRdID0gYXdhaXQgdGhpcy5jbGllbnQueGF1dG9jbGFpbShcblx0XHRcdFx0c3RyZWFtLFxuXHRcdFx0XHRncm91cCxcblx0XHRcdFx0dGhpcy5jb25zdW1lck5hbWUsXG5cdFx0XHRcdG1pbklkbGUsXG5cdFx0XHRcdFwiMFwiLFxuXHRcdFx0XHRcIkNPVU5UXCIsXG5cdFx0XHRcdHRoaXMuY29uZmlnLmNvdW50LFxuXHRcdFx0KTtcblx0XHRcdGlmICghY2xhaW1lZCB8fCBjbGFpbWVkLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXHRcdFx0Ly8gRGVsaXZlcnkgY291bnRzIGZvciBleGFjdGx5IHRoZSBjbGFpbWVkIGlkcy4gQnJhY2tldCBYUEVORElORyBieVxuXHRcdFx0Ly8gdGhlIG1pbi9tYXggY2xhaW1lZCBpZCAoWEFVVE9DTEFJTSByZXR1cm5zIHRoZW0gaWQtYXNjZW5kaW5nKSBzb1xuXHRcdFx0Ly8gdGhlIHdpbmRvdyBjYW4ndCBtaXNzIGFueSAoWFBFTkRJTkcgZXh0ZW5kZWQgcm93OlxuXHRcdFx0Ly8gW2lkLCBjb25zdW1lciwgaWRsZU1zLCBkZWxpdmVyeUNvdW50XSkuXG5cdFx0XHRjb25zdCBtaW5JZCA9IGNsYWltZWRbMF1bMF07XG5cdFx0XHRjb25zdCBtYXhJZCA9IGNsYWltZWRbY2xhaW1lZC5sZW5ndGggLSAxXVswXTtcblx0XHRcdGNvbnN0IHBlbmRpbmcgPSAoYXdhaXQgdGhpcy5jbGllbnQueHBlbmRpbmcoc3RyZWFtLCBncm91cCwgbWluSWQsIG1heElkLCBjbGFpbWVkLmxlbmd0aCkpIGFzIEFycmF5PFxuXHRcdFx0XHRbc3RyaW5nLCBzdHJpbmcsIG51bWJlciwgbnVtYmVyXVxuXHRcdFx0Pjtcblx0XHRcdGNvbnN0IGRlbGl2ZXJpZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXHRcdFx0Zm9yIChjb25zdCBwIG9mIHBlbmRpbmcpIGRlbGl2ZXJpZXMuc2V0KHBbMF0sIE51bWJlcihwWzNdID8/IDEpKTtcblx0XHRcdGNvbnN0IG1heERlbGl2ZXJpZXMgPSAoY29uZmlnLnJldHJpZXMgPz8gMCkgKyAxO1xuXHRcdFx0Zm9yIChjb25zdCBbaWQsIGZpZWxkc10gb2YgY2xhaW1lZCkge1xuXHRcdFx0XHRpZiAocnVubmVyLnN0b3ApIGJyZWFrO1xuXHRcdFx0XHRjb25zdCBjb3VudCA9IGRlbGl2ZXJpZXMuZ2V0KGlkKSA/PyAxO1xuXHRcdFx0XHRpZiAoY291bnQgPiBtYXhEZWxpdmVyaWVzKSB7XG5cdFx0XHRcdFx0Ly8gRXhoYXVzdGVkOiBkZWFkLWxldHRlciAod2hlbiBjb25maWd1cmVkKSB0aGVuIEFDSyBzbyBpdCBzdG9wc1xuXHRcdFx0XHRcdC8vIGJlaW5nIHJlY2xhaW1lZC4gTWlycm9ycyBwcm9jZXNzTWVzc2FnZSdzIHRlcm1pbmFsIHBhdGguXG5cdFx0XHRcdFx0aWYgKGNvbmZpZy5kZWFkTGV0dGVyUXVldWUpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHJhdyA9IHRoaXMuZmllbGRzVG9PYmplY3QoZmllbGRzKTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMuY2xpZW50LnhhZGQoY29uZmlnLmRlYWRMZXR0ZXJRdWV1ZSwgXCIqXCIsIFwiZGF0YVwiLCByYXcuZGF0YSA/PyBcIlwiLCBcImpvYklkXCIsIHJhdy5qb2JJZCA/PyBpZCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGF3YWl0IHRoaXMuY2xpZW50LnhhY2soc3RyZWFtLCBncm91cCwgaWQpO1xuXHRcdFx0XHRcdHN0YXRzLmZhaWxlZCArPSAxO1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIGF0dGVtcHRzID0gZGVsaXZlcmllcyBzbyBmYXIgbWludXMgdGhpcyBvbmUsIHNvIGhhbmRsZUpvYidzXG5cdFx0XHRcdC8vIGBhdHRlbXB0cyA8IG1heFJldHJpZXNgIGJ1ZGdldCBpcyBob25vcmVkIGFjcm9zcyByZWRyaXZlcy5cblx0XHRcdFx0YXdhaXQgdGhpcy5wcm9jZXNzTWVzc2FnZShpZCwgZmllbGRzLCBzdHJlYW0sIGdyb3VwLCBjb25maWcsIGhhbmRsZXIsIHN0YXRzLCBmYWxzZSwgTWF0aC5tYXgoMCwgY291bnQgLSAxKSk7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHQvLyBBIHRyYW5zaWVudCBjbGFpbSBmYWlsdXJlIChlLmcuIE5PR1JPVVAgbWlkLXRlYXJkb3duKSDigJQgbmV4dCB0aWNrIHJldHJpZXMuXG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1hcCB0aGUgdHJpZ2dlcidzIHN0YXJ0IHBvc2l0aW9uIHRvIHRoZSBpZCBwYXNzZWQgdG8gWEdST1VQIENSRUFURS5cblx0ICogICAtIGBcImxhdGVzdFwiYCAoZGVmYXVsdCkg4oaSIGAkYCAgOiBvbmx5IGVudHJpZXMgYWRkZWQgYWZ0ZXIgY3JlYXRpb24uXG5cdCAqICAgLSBgXCJlYXJsaWVzdFwiYCAvIGBmcm9tQmVnaW5uaW5nOnRydWVgIOKGkiBgMGAgOiB0aGUgd2hvbGUgcmV0YWluZWQgc3RyZWFtLlxuXHQgKiAgIC0gYHsgc2VxIH1gIC8gYHsgdGltZXN0YW1wIH1gIOKGkiB0aGF0IGV4cGxpY2l0IGN1cnNvciBpZC5cblx0ICogYHN0YXJ0RnJvbWAgcmlkZXMgb24gdGhlIFB1YlN1YiBzY2hlbWEsIG5vdCBXb3JrZXJUcmlnZ2VyT3B0cywgc28gaXQnc1xuXHQgKiByZWFkIGRlZmVuc2l2ZWx5IG9mZiBgY29uZmlnYCBmb3IgY2FsbGVycyB0aGF0IHRocmVhZCBpdCB0aHJvdWdoLlxuXHQgKi9cblx0cHJpdmF0ZSByZXNvbHZlU3RhcnRJZChjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzKTogc3RyaW5nIHtcblx0XHRpZiAoY29uZmlnLmZyb21CZWdpbm5pbmcpIHJldHVybiBcIjBcIjtcblx0XHRjb25zdCBzdGFydEZyb20gPSAoY29uZmlnIGFzIHsgc3RhcnRGcm9tPzogdW5rbm93biB9KS5zdGFydEZyb207XG5cdFx0aWYgKHN0YXJ0RnJvbSA9PT0gXCJlYXJsaWVzdFwiKSByZXR1cm4gXCIwXCI7XG5cdFx0aWYgKHN0YXJ0RnJvbSA9PT0gXCJsYXRlc3RcIiB8fCBzdGFydEZyb20gPT09IHVuZGVmaW5lZCkgcmV0dXJuIFwiJFwiO1xuXHRcdGlmICh0eXBlb2Ygc3RhcnRGcm9tID09PSBcIm9iamVjdFwiICYmIHN0YXJ0RnJvbSAhPT0gbnVsbCkge1xuXHRcdFx0Y29uc3QgcyA9IHN0YXJ0RnJvbSBhcyB7IHNlcT86IG51bWJlcjsgdGltZXN0YW1wPzogbnVtYmVyIH07XG5cdFx0XHRpZiAodHlwZW9mIHMuc2VxID09PSBcIm51bWJlclwiKSByZXR1cm4gYCR7cy5zZXF9LTBgO1xuXHRcdFx0aWYgKHR5cGVvZiBzLnRpbWVzdGFtcCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIGAke3MudGltZXN0YW1wfS0wYDtcblx0XHR9XG5cdFx0cmV0dXJuIFwiJFwiO1xuXHR9XG5cblx0cHJpdmF0ZSBmaWVsZHNUb09iamVjdChmaWVsZHM6IHN0cmluZ1tdKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG5cdFx0Y29uc3Qgb3V0OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpICs9IDIpIHtcblx0XHRcdG91dFtmaWVsZHNbaV1dID0gZmllbGRzW2kgKyAxXTtcblx0XHR9XG5cdFx0cmV0dXJuIG91dDtcblx0fVxuXG5cdGFzeW5jIGFkZEpvYihcblx0XHRxdWV1ZTogc3RyaW5nLFxuXHRcdGRhdGE6IHVua25vd24sXG5cdFx0b3B0cz86IHsgcHJpb3JpdHk/OiBudW1iZXI7IGRlbGF5PzogbnVtYmVyOyByZXRyaWVzPzogbnVtYmVyOyB0aW1lb3V0PzogbnVtYmVyOyBqb2JJZD86IHN0cmluZyB9LFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQgfHwgIXRoaXMuY2xpZW50KSB0aHJvdyBuZXcgRXJyb3IoXCJbYmxva11bcmVkaXNdIG5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHQvLyBSZWRpcyBTdHJlYW1zIGhhcyBOTyBuYXRpdmUgZGVsYXllZCBkZWxpdmVyeSBvciBwcmlvcml0eS4gUmVqZWN0IGF0XG5cdFx0Ly8gZW5xdWV1ZSByYXRoZXIgdGhhbiBzaWxlbnRseSBkcm9wcGluZyB0aGUgb3B0aW9uIOKAlCBzdXJmYWNpbmcgdGhlXG5cdFx0Ly8gbWlzY29uZmlndXJhdGlvbiBpcyB0aGUgbGF6eS1jb3JyZWN0IGNob2ljZSAoYSBzY2hlZHVsZXIgdHJpZ2dlciBvd25zXG5cdFx0Ly8gZGVsYXllZCB3b3JrOyBYQUREIGlzIHN0cmljdGx5IEZJRk8gYnkgaWQpLlxuXHRcdGlmIChvcHRzPy5kZWxheSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRcIltibG9rXVtyZWRpc10gUmVkaXMgU3RyZWFtcyBoYXMgbm8gbmF0aXZlIGRlbGF5ZWQgZGVsaXZlcnkg4oCUIGRyb3AgYGRlbGF5YCBvciB1c2UgYSBzY2hlZHVsZXIgdHJpZ2dlci5cIixcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGlmIChvcHRzPy5wcmlvcml0eSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiW2Jsb2tdW3JlZGlzXSBSZWRpcyBTdHJlYW1zIGhhcyBubyBuYXRpdmUgcHJpb3JpdHkg4oCUIGRyb3AgYHByaW9yaXR5YDsgZW50cmllcyBhcmUgRklGTyBieSBpZC5cIik7XG5cdFx0fVxuXHRcdGNvbnN0IHBheWxvYWQgPSB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiA/IGRhdGEgOiBKU09OLnN0cmluZ2lmeShkYXRhKTtcblx0XHQvLyBYQUREIGtleSBbTk9NS1NUUkVBTV0gPCogfCBpZD4gZmllbGQgdmFsdWUg4oCmIOKAlCBOT01LU1RSRUFNICh3aGVuIGFcblx0XHQvLyBqb2JJZCBpcyBzdXBwbGllZCwgbWVhbmluZyB0aGUgY2FsbGVyIGV4cGVjdHMgdGhlIHN0cmVhbSB0byBhbHJlYWR5XG5cdFx0Ly8gZXhpc3QpIE1VU1QgcHJlY2VkZSB0aGUgYCpgIGlkLCBhbmQgdGhlIGFzc2VtYmxlZCBhcmdzIG11c3QgYWN0dWFsbHlcblx0XHQvLyBiZSBwYXNzZWQgdG8geGFkZCAodGhlIHByaW9yIGJ1aWxkIHRocmV3IHRoZW0gYXdheSkuXG5cdFx0Y29uc3QgYXJnczogc3RyaW5nW10gPSBbcXVldWVdO1xuXHRcdGlmIChvcHRzPy5qb2JJZCkgYXJncy5wdXNoKFwiTk9NS1NUUkVBTVwiKTtcblx0XHRhcmdzLnB1c2goXCIqXCIsIFwiZGF0YVwiLCBwYXlsb2FkLCBcImpvYklkXCIsIG9wdHM/LmpvYklkID8/IFwiXCIpO1xuXHRcdGNvbnN0IGlkID0gYXdhaXQgdGhpcy5jbGllbnQueGFkZCguLi4oYXJncyBhcyBbc3RyaW5nLCAuLi5zdHJpbmdbXV0pKTtcblx0XHRyZXR1cm4gaWQ7XG5cdH1cblxuXHRhc3luYyBzdG9wUHJvY2Vzc2luZyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgcnVubmVyID0gdGhpcy5ydW5uZXJzLmdldChxdWV1ZSk7XG5cdFx0aWYgKHJ1bm5lcikge1xuXHRcdFx0cnVubmVyLnN0b3AgPSB0cnVlO1xuXHRcdFx0aWYgKHJ1bm5lci5yZWRyaXZlKSBjbGVhckludGVydmFsKHJ1bm5lci5yZWRyaXZlKTtcblx0XHR9XG5cdH1cblxuXHRpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBoZWFsdGhDaGVjaygpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkIHx8ICF0aGlzLmNsaWVudCkgcmV0dXJuIGZhbHNlO1xuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBwb25nID0gYXdhaXQgdGhpcy5jbGllbnQucGluZygpO1xuXHRcdFx0cmV0dXJuIHBvbmcgPT09IFwiUE9OR1wiO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGdldFF1ZXVlU3RhdHMocXVldWU6IHN0cmluZyk6IFByb21pc2U8V29ya2VyUXVldWVTdGF0cz4ge1xuXHRcdGNvbnN0IGNvdW50ZXJzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpID8/IHsgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGFjdGl2ZTogMCB9O1xuXHRcdGxldCB3YWl0aW5nID0gMDtcblx0XHR0cnkge1xuXHRcdFx0d2FpdGluZyA9IChhd2FpdCB0aGlzLmNsaWVudD8ueGxlbihxdWV1ZSkpID8/IDA7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHQvKiBpZ25vcmUgKi9cblx0XHR9XG5cdFx0cmV0dXJuIHtcblx0XHRcdHdhaXRpbmcsXG5cdFx0XHRhY3RpdmU6IGNvdW50ZXJzLmFjdGl2ZSxcblx0XHRcdGNvbXBsZXRlZDogY291bnRlcnMuY29tcGxldGVkLFxuXHRcdFx0ZmFpbGVkOiBjb3VudGVycy5mYWlsZWQsXG5cdFx0XHRkZWxheWVkOiAwLFxuXHRcdH07XG5cdH1cbn1cbiJdfQ==