@pipeline-builder/api-server 4.1.4 → 4.1.5
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 +1 -1
- package/lib/api/app-factory.d.ts +8 -1
- package/lib/api/app-factory.js +68 -59
- package/lib/api/idempotency-middleware.js +14 -1
- package/lib/api/index.d.ts +0 -1
- package/lib/api/index.js +1 -2
- package/lib/api/metrics.d.ts +9 -0
- package/lib/api/metrics.js +23 -1
- package/lib/api/middleware-factory.js +2 -2
- package/lib/api/quota-helpers.d.ts +2 -4
- package/lib/api/quota-helpers.js +3 -3
- package/lib/api/rate-limit-by-org.js +10 -5
- package/lib/api/request-types.d.ts +1 -1
- package/lib/api/request-types.js +7 -2
- package/lib/api/server.js +19 -2
- package/lib/http/index.d.ts +0 -1
- package/lib/http/index.js +1 -2
- package/lib/http/sse-connection-manager.d.ts +59 -29
- package/lib/http/sse-connection-manager.js +89 -42
- package/lib/http/sse-relay.d.ts +16 -5
- package/lib/http/sse-relay.js +28 -16
- package/lib/http/sse-ticket-channel.d.ts +4 -2
- package/lib/http/sse-ticket-channel.js +13 -10
- package/package.json +5 -6
- package/lib/api/middleware.d.ts +0 -1
- package/lib/api/middleware.js +0 -8
- package/lib/http/sse-ticket-store.d.ts +0 -75
- package/lib/http/sse-ticket-store.js +0 -160
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// Copyright 2026 Pipeline Builder Contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { randomBytes } from 'node:crypto';
|
|
4
|
-
import { createLogger, SSE_TICKET_TTL_MS, writeSseHeaders } from '@pipeline-builder/api-core';
|
|
4
|
+
import { createLogger, createMemorySseTicketStore, SSE_TICKET_TTL_MS, writeSseHeaders } from '@pipeline-builder/api-core';
|
|
5
5
|
import { CoreConstants } from '@pipeline-builder/pipeline-core';
|
|
6
6
|
import { v7 as uuid } from 'uuid';
|
|
7
|
-
import { createMemoryTicketStore } from './sse-ticket-store.js';
|
|
8
7
|
import { incCounter, setGauge } from '../api/metrics.js';
|
|
9
8
|
const logger = createLogger('sse-manager');
|
|
10
9
|
/**
|
|
@@ -40,10 +39,10 @@ export class SSEManager {
|
|
|
40
39
|
* map mirrors `clients[].orgId` counts at all times. Orgs reach zero are
|
|
41
40
|
* deleted to keep the map bounded. */
|
|
42
41
|
orgClientCounts = new Map();
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
/** Injected ticket + stream-ownership backend, or the lazily built in-memory default. */
|
|
43
|
+
ticketStoreInstance;
|
|
44
|
+
/** True when this manager built its ticket store (so shutdown stops it). */
|
|
45
|
+
ownsTicketStore = false;
|
|
47
46
|
maxClientsPerRequest;
|
|
48
47
|
maxTotalClients;
|
|
49
48
|
maxClientsPerOrg;
|
|
@@ -55,6 +54,9 @@ export class SSEManager {
|
|
|
55
54
|
cleanupInterval = null;
|
|
56
55
|
/** Cross-pod fan-out bus (undefined ⇒ local-only delivery). */
|
|
57
56
|
relay;
|
|
57
|
+
relayFactory;
|
|
58
|
+
/** Whether `ctx.log` frames are streamed (see {@link SSEManagerOptions.logStream}). */
|
|
59
|
+
logStreamEnabled;
|
|
58
60
|
/** This manager instance's id — tags relayed frames so we ignore our own echo. */
|
|
59
61
|
nodeId = randomBytes(8).toString('hex');
|
|
60
62
|
constructor(options = {}) {
|
|
@@ -65,7 +67,8 @@ export class SSEManager {
|
|
|
65
67
|
this.maxTicketsPerOrg = options.maxTicketsPerOrg ?? parseInt(process.env.SSE_MAX_TICKETS_PER_ORG || '10', 10);
|
|
66
68
|
this.ticketTtlMs = options.ticketTtlMs ?? SSE_TICKET_TTL_MS;
|
|
67
69
|
this.streamOwnerTtlMs = options.streamOwnerTtlMs ?? parseInt(process.env.SSE_STREAM_OWNER_TTL_MS || '3600000', 10); // 1 hour
|
|
68
|
-
this.
|
|
70
|
+
this.ticketStoreInstance = options.ticketStore;
|
|
71
|
+
this.logStreamEnabled = options.logStream ?? false;
|
|
69
72
|
this.clientTimeoutMs = options.clientTimeoutMs ?? parseInt(process.env.SSE_CLIENT_TIMEOUT_MS || '1800000', 10); // 30 minutes
|
|
70
73
|
const cleanupIntervalMs = options.cleanupIntervalMs ?? parseInt(process.env.SSE_CLEANUP_INTERVAL_MS || '300000', 10); // 5 minutes
|
|
71
74
|
this.startCleanupInterval(cleanupIntervalMs);
|
|
@@ -73,8 +76,37 @@ export class SSEManager {
|
|
|
73
76
|
// any other pod are re-emitted to THIS pod's local clients. Frames we
|
|
74
77
|
// published ourselves are ignored (origin === nodeId) — we already wrote them
|
|
75
78
|
// locally. Fail-safe: no relay ⇒ local-only delivery (single-replica default).
|
|
76
|
-
this.
|
|
77
|
-
|
|
79
|
+
this.relayFactory = options.relayFactory;
|
|
80
|
+
if (options.relay)
|
|
81
|
+
this.attachRelay(options.relay);
|
|
82
|
+
}
|
|
83
|
+
attachRelay(relay) {
|
|
84
|
+
this.relay = relay;
|
|
85
|
+
relay.subscribe((msg) => this.onRelayMessage(msg));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Turn on cross-pod delivery using the configured `relayFactory`. Idempotent;
|
|
89
|
+
* a no-op when a relay is already wired or no factory was given, and when the
|
|
90
|
+
* factory returns null (Redis not configured → local-only delivery).
|
|
91
|
+
*/
|
|
92
|
+
enableRelay() {
|
|
93
|
+
if (this.relay || !this.relayFactory)
|
|
94
|
+
return;
|
|
95
|
+
const relay = this.relayFactory();
|
|
96
|
+
if (relay)
|
|
97
|
+
this.attachRelay(relay);
|
|
98
|
+
}
|
|
99
|
+
/** The ticket store, building the in-memory default on first use. */
|
|
100
|
+
get ticketStore() {
|
|
101
|
+
if (!this.ticketStoreInstance) {
|
|
102
|
+
this.ticketStoreInstance = createMemorySseTicketStore({
|
|
103
|
+
ttlMs: this.ticketTtlMs,
|
|
104
|
+
maxTotal: this.maxTotalTickets,
|
|
105
|
+
maxPerOrg: this.maxTicketsPerOrg,
|
|
106
|
+
});
|
|
107
|
+
this.ownsTicketStore = true;
|
|
108
|
+
}
|
|
109
|
+
return this.ticketStoreInstance;
|
|
78
110
|
}
|
|
79
111
|
/**
|
|
80
112
|
* Handle a frame received from another pod via the relay. We already delivered
|
|
@@ -145,7 +177,7 @@ export class SSEManager {
|
|
|
145
177
|
* @param orgId - The owning org (normalized internally via normalizeOrgId).
|
|
146
178
|
*/
|
|
147
179
|
async bindStreamOwner(requestId, orgId) {
|
|
148
|
-
await this.ticketStore.
|
|
180
|
+
await this.ticketStore.bindOwner(SSEManager.normalizeRequestId(requestId), SSEManager.normalizeOrgId(orgId), this.streamOwnerTtlMs);
|
|
149
181
|
}
|
|
150
182
|
/**
|
|
151
183
|
* Mint a short-lived, single-use SSE ticket bound to `orgId` AND a specific
|
|
@@ -162,8 +194,8 @@ export class SSEManager {
|
|
|
162
194
|
* wiring not yet present), minting falls back to binding the ticket to the
|
|
163
195
|
* caller's own org, preserving current behavior.
|
|
164
196
|
*
|
|
165
|
-
* Bounded by
|
|
166
|
-
*
|
|
197
|
+
* Bounded by the ticket store's live-ticket caps (total and per org). An
|
|
198
|
+
* ownership lookup the store can't answer is refused as `capacity`.
|
|
167
199
|
*
|
|
168
200
|
* @param orgId - Owning org (normalized internally via normalizeOrgId).
|
|
169
201
|
* @param requestId - The build-log stream subject this ticket authorizes.
|
|
@@ -178,27 +210,29 @@ export class SSEManager {
|
|
|
178
210
|
// false-`forbidden` the real owner (mirrors requestId normalization).
|
|
179
211
|
const normalized = SSEManager.normalizeRequestId(requestId);
|
|
180
212
|
const normalizedOrg = SSEManager.normalizeOrgId(orgId);
|
|
181
|
-
|
|
213
|
+
let owner;
|
|
214
|
+
try {
|
|
215
|
+
owner = await this.ticketStore.getOwner(normalized);
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
// Can't tell who owns the subject — refuse rather than mint unchecked.
|
|
219
|
+
logger.warn('SSE ticket refused: stream ownership lookup failed', { error: err instanceof Error ? err.message : String(err) });
|
|
220
|
+
incCounter('sse_ticket_rejected_total', { reason: 'capacity' });
|
|
221
|
+
return { ok: false, reason: 'capacity' };
|
|
222
|
+
}
|
|
182
223
|
if (owner && owner !== normalizedOrg) {
|
|
183
224
|
logger.warn(`SSE ticket refused: org ${normalizedOrg} does not own stream subject`);
|
|
184
225
|
incCounter('sse_ticket_rejected_total', { reason: 'forbidden' });
|
|
185
226
|
return { ok: false, reason: 'forbidden' };
|
|
186
227
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
logger.warn(`SSE ticket
|
|
191
|
-
incCounter('sse_ticket_rejected_total', { reason
|
|
192
|
-
return { ok: false, reason
|
|
228
|
+
const issued = await this.ticketStore.issue(normalizedOrg, normalized);
|
|
229
|
+
if (!issued.ok) {
|
|
230
|
+
const reason = issued.reason === 'org' ? 'org-limit' : 'capacity';
|
|
231
|
+
logger.warn(`SSE ticket refused (${reason}) for ${normalizedOrg}`);
|
|
232
|
+
incCounter('sse_ticket_rejected_total', { reason });
|
|
233
|
+
return { ok: false, reason };
|
|
193
234
|
}
|
|
194
|
-
|
|
195
|
-
logger.warn(`Per-org SSE ticket cap reached for ${normalizedOrg} (max: ${this.maxTicketsPerOrg})`);
|
|
196
|
-
incCounter('sse_ticket_rejected_total', { reason: 'org-limit' });
|
|
197
|
-
return { ok: false, reason: 'org-limit' };
|
|
198
|
-
}
|
|
199
|
-
const ticket = randomBytes(24).toString('base64url');
|
|
200
|
-
await this.ticketStore.put(ticket, { orgId: normalizedOrg, requestId: normalized }, this.ticketTtlMs);
|
|
201
|
-
return { ok: true, ticket };
|
|
235
|
+
return { ok: true, ticket: issued.ticket };
|
|
202
236
|
}
|
|
203
237
|
/**
|
|
204
238
|
* Validate and CONSUME a ticket for a specific stream subject. Single-use:
|
|
@@ -223,8 +257,9 @@ export class SSEManager {
|
|
|
223
257
|
if (!ticket)
|
|
224
258
|
return null;
|
|
225
259
|
// Subject binding — reject a ticket presented for a subject it was not
|
|
226
|
-
// minted for
|
|
227
|
-
|
|
260
|
+
// minted for (including an unbound, org-channel ticket). Both sides are
|
|
261
|
+
// normalized so dashed/undashed forms match.
|
|
262
|
+
if (ticket.subject !== SSEManager.normalizeRequestId(requestId))
|
|
228
263
|
return null;
|
|
229
264
|
return { orgId: ticket.orgId };
|
|
230
265
|
}
|
|
@@ -235,9 +270,12 @@ export class SSEManager {
|
|
|
235
270
|
* @param res - Express Response object
|
|
236
271
|
* @param orgId - Authenticated org id (optional). When set, enforces the
|
|
237
272
|
* per-org cap and the counter is decremented on disconnect/cleanup.
|
|
273
|
+
* @param maxClientsForSubject - Per-subject cap override (default
|
|
274
|
+
* `maxClientsPerRequest`). An org-keyed channel's subject IS the org, so it
|
|
275
|
+
* must not inherit the small per-build-request cap — see {@link addOrgClient}.
|
|
238
276
|
* @returns true if client was added, false if rejected (limit reached)
|
|
239
277
|
*/
|
|
240
|
-
addClient(requestId, res, orgId) {
|
|
278
|
+
addClient(requestId, res, orgId, maxClientsForSubject = this.maxClientsPerRequest) {
|
|
241
279
|
// Normalize the map key: the subject id is allowed in two forms (dashed
|
|
242
280
|
// api-server uuid vs undashed nginx $request_id), and a producer/consumer that
|
|
243
281
|
// render it differently would otherwise key different Map entries — the client
|
|
@@ -246,8 +284,8 @@ export class SSEManager {
|
|
|
246
284
|
requestId = SSEManager.normalizeRequestId(requestId);
|
|
247
285
|
const existing = this.clients.get(requestId) || [];
|
|
248
286
|
// Check client limit
|
|
249
|
-
if (existing.length >=
|
|
250
|
-
logger.warn(`Client limit reached for request ${requestId} (max: ${
|
|
287
|
+
if (existing.length >= maxClientsForSubject) {
|
|
288
|
+
logger.warn(`Client limit reached for request ${requestId} (max: ${maxClientsForSubject})`);
|
|
251
289
|
incCounter('sse_connection_rejected_total', { reason: 'request-limit' });
|
|
252
290
|
return false;
|
|
253
291
|
}
|
|
@@ -308,6 +346,14 @@ export class SSEManager {
|
|
|
308
346
|
logger.debug(`Client ${clientId} connected for request ${requestId} (total: ${existing.length})`);
|
|
309
347
|
return true;
|
|
310
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Attach a client to an ORG-keyed stream (the org is the subject). Counts
|
|
351
|
+
* against the per-org cap, and the org — not the per-request cap — bounds how
|
|
352
|
+
* many streams share the subject.
|
|
353
|
+
*/
|
|
354
|
+
addOrgClient(orgId, res) {
|
|
355
|
+
return this.addClient(orgId, res, orgId, this.maxClientsPerOrg);
|
|
356
|
+
}
|
|
311
357
|
/** Drop one from the per-org counter. Idempotent: a counter at 0 stays at 0
|
|
312
358
|
* and the org key is removed from the map. */
|
|
313
359
|
decrementOrgCount(orgId) {
|
|
@@ -457,13 +503,17 @@ export class SSEManager {
|
|
|
457
503
|
*/
|
|
458
504
|
closeRequest(requestId, finalMessage) {
|
|
459
505
|
requestId = SSEManager.normalizeRequestId(requestId);
|
|
460
|
-
|
|
461
|
-
if (!clients)
|
|
506
|
+
if (!this.clients.has(requestId))
|
|
462
507
|
return;
|
|
508
|
+
// LOCAL only: this closes this pod's clients, so the final frame is for them
|
|
509
|
+
// (relaying it would push a COMPLETED to other pods' still-open streams).
|
|
463
510
|
if (finalMessage) {
|
|
464
|
-
this.
|
|
511
|
+
this.sendLocal(requestId, { ts: new Date().toISOString(), type: 'COMPLETED', message: finalMessage });
|
|
465
512
|
}
|
|
466
|
-
|
|
513
|
+
// Read the entry AFTER the final write: sendLocal removes (and un-counts)
|
|
514
|
+
// clients that were already gone, so iterating an earlier snapshot would
|
|
515
|
+
// decrement their org count a second time.
|
|
516
|
+
for (const client of this.clients.get(requestId) ?? []) {
|
|
467
517
|
clearTimeout(client.timeout);
|
|
468
518
|
this.decrementOrgCount(client.orgId);
|
|
469
519
|
try {
|
|
@@ -610,11 +660,6 @@ export class SSEManager {
|
|
|
610
660
|
cleanup() {
|
|
611
661
|
const now = Date.now();
|
|
612
662
|
let cleaned = 0;
|
|
613
|
-
// Sweep expired tickets/owners so an in-memory store stays bounded even when
|
|
614
|
-
// tickets are minted but never consumed (client closed the tab before
|
|
615
|
-
// connecting). Consume-time still re-checks expiry, so this is memory
|
|
616
|
-
// hygiene only; the Redis store relies on native key TTL (sweep is a no-op).
|
|
617
|
-
void this.ticketStore.sweep?.();
|
|
618
663
|
for (const [requestId, clients] of this.clients.entries()) {
|
|
619
664
|
const stale = [];
|
|
620
665
|
const active = [];
|
|
@@ -666,7 +711,9 @@ export class SSEManager {
|
|
|
666
711
|
}
|
|
667
712
|
// Tear down the relay's Redis connections (best-effort; never throws).
|
|
668
713
|
void this.relay?.close().catch(() => { });
|
|
714
|
+
if (this.ownsTicketStore)
|
|
715
|
+
this.ticketStoreInstance?.stop();
|
|
669
716
|
logger.info('SSE Manager shut down');
|
|
670
717
|
}
|
|
671
718
|
}
|
|
672
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhFLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBRSx1QkFBdUIsRUFBNkIsTUFBTSx1QkFBdUIsQ0FBQztBQUMzRixPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQWlHM0M7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLHFFQUFxRSxDQUFDO0FBZ0J2Rzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQUNiLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztJQUNqRDs7MkNBRXVDO0lBQy9CLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUNwRDs7aUZBRTZFO0lBQzVELFdBQVcsQ0FBdUI7SUFDbEMsb0JBQW9CLENBQVM7SUFDN0IsZUFBZSxDQUFTO0lBQ3hCLGdCQUFnQixDQUFTO0lBQ3pCLGVBQWUsQ0FBUztJQUN4QixnQkFBZ0IsQ0FBUztJQUN6QixXQUFXLENBQVM7SUFDcEIsZ0JBQWdCLENBQVM7SUFDekIsZUFBZSxDQUFTO0lBQ2pDLGVBQWUsR0FBMEIsSUFBSSxD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QUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNqRCxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCx1RUFBdUU7UUFDdkUsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBeUIsQ0FBQyxDQUFDLENBQUM7UUFFaEUsTUFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgU1NFX1RJQ0tFVF9UVExfTVMsIHdyaXRlU3NlSGVhZGVycyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IENvcmVDb25zdGFudHMgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1jb3JlJztcbmltcG9ydCB0eXBlIHsgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IHY3IGFzIHV1aWQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB0eXBlIHsgU1NFUmVsYXksIFNTRVJlbGF5TWVzc2FnZSB9IGZyb20gJy4vc3NlLXJlbGF5LmpzJztcbmltcG9ydCB7IGNyZWF0ZU1lbW9yeVRpY2tldFN0b3JlLCB0eXBlIFNTRVN0cmVhbVRpY2tldFN0b3JlIH0gZnJvbSAnLi9zc2UtdGlja2V0LXN0b3JlLmpzJztcbmltcG9ydCB7IGluY0NvdW50ZXIsIHNldEdhdWdlIH0gZnJvbSAnLi4vYXBpL21ldHJpY3MuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS1tYW5hZ2VyJyk7XG5cbi8qKlxuICogRXZlbnQgdHlwZXMgZm9yIFNTRSBsb2dnaW5nXG4gKi9cbmV4cG9ydCB0eXBlIFNTRUV2ZW50VHlwZSA9ICdJTkZPJyB8ICdXQVJOJyB8ICdFUlJPUicgfCAnQ09NUExFVEVEJyB8ICdST0xMQkFDSycgfCAnTUVTU0FHRSc7XG5cbi8qKlxuICogU1NFIHBheWxvYWQgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFUGF5bG9hZCB7XG4gIHRzOiBzdHJpbmc7XG4gIHR5cGU6IFNTRUV2ZW50VHlwZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkYXRhPzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBTU0UgY2xpZW50IHdpdGggY29ubmVjdGlvbiB0cmFja2luZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRUNsaWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIHJlczogUmVzcG9uc2U7XG4gIGNvbm5lY3RlZEF0OiBudW1iZXI7XG4gIHRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMgKHdyaXRlIHJldHVybmVkIGZhbHNlKS4gKi9cbiAgYmFja3ByZXNzdXJlQ291bnQ6IG51bWJlcjtcbiAgLyoqIE93bmluZyBvcmcgaWQg4oCUIHBvcHVsYXRlZCB3aGVuIHRoZSByZXF1ZXN0IHdhcyBhdXRoZW50aWNhdGVkLiBVc2VkIHRvXG4gICAqICBkZWNyZW1lbnQgdGhlIHBlci1vcmcgY291bnRlciBvbiBkaXNjb25uZWN0IC8gY2xlYW51cC4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU1NFIE1hbmFnZXIgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlck9wdGlvbnMge1xuICAvKiogTWF4aW11bSBjbGllbnRzIGFsbG93ZWQgcGVyIHJlcXVlc3QgSUQgKGRlZmF1bHQ6IDEwKSAqL1xuICBtYXhDbGllbnRzUGVyUmVxdWVzdD86IG51bWJlcjtcbiAgLyoqIENsaWVudCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMzAgbWludXRlcykgKi9cbiAgY2xpZW50VGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogSW50ZXJ2YWwgZm9yIGNsZWFudXAgY2hlY2tzIGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogNSBtaW51dGVzKSAqL1xuICBjbGVhbnVwSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEhhcmQgY2FwIG9uIHRvdGFsIG9wZW4gY29ubmVjdGlvbnMgcGVyIHByb2Nlc3MuIERlZmF1bHRzIHRvIDEwMDAgZnJvbVxuICAgKiBgU1NFX01BWF9UT1RBTF9DTElFTlRTYC4gTmV3IGNvbm5lY3Rpb25zIGJleW9uZCB0aGlzIGFyZSByZWplY3RlZCBhdFxuICAgKiBgYWRkQ2xpZW50KClgLiBUdW5lIHVwIGlmIHlvdXIgc2VydmljZSBzZXJ2ZXMgPiAxMDAwIGNvbmN1cnJlbnQgU1NFXG4gICAqIGRhc2hib2FyZHMsIGJ1dCBiZSBhd2FyZSBOb2RlLmpzIGZkIGxpbWl0cyBkb21pbmF0ZSBhYm92ZSB+NTAwMC5cbiAgICovXG4gIG1heFRvdGFsQ2xpZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2VpbGluZyBvbiBjb25jdXJyZW50IFNTRSBzdHJlYW1zLiBEZWZhdWx0cyB0byA1MCBmcm9tXG4gICAqIGBTU0VfTUFYX0NMSUVOVFNfUEVSX09SR2AuIFByb3RlY3RzIGFnYWluc3Qgb25lIG5vaXN5IG9yZyBjb25zdW1pbmcgdGhlXG4gICAqIHByb2Nlc3Mtd2lkZSBidWRnZXQg4oCUIHdpdGhvdXQgaXQsIGFuIGF1dGhlbnRpY2F0ZWQgdXNlciBjYW4gZmFuIG91dFxuICAgKiB0aG91c2FuZHMgb2Ygc3RyZWFtcyAob25lIHBlciBkYXNoYm9hcmQgLyBsb2cgc3RyZWFtKSBhbmQgc3RhcnZlIG90aGVyXG4gICAqIG9yZ3Mgb2YgY29ubmVjdGlvbiBzbG90cy4gVGhlIGNhcCBpcyBlbmZvcmNlZCBvbmx5IG9uIGBhZGRDbGllbnRgIGNhbGxzXG4gICAqIHRoYXQgY2FycnkgYW4gYG9yZ0lkYDsgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91cyBTU0UgdHJhZmZpYyBza2lwcyBpdC5cbiAgICovXG4gIG1heENsaWVudHNQZXJPcmc/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIYXJkIGNhcCBvbiB0b3RhbCBsaXZlICh1bmNvbnN1bWVkLCB1bmV4cGlyZWQpIFNTRSB0aWNrZXRzIGFjcm9zcyB0aGVcbiAgICogcHJvY2Vzcy4gRGVmYXVsdHMgdG8gMTAwMCBmcm9tIGBTU0VfTUFYX1RPVEFMX1RJQ0tFVFNgLiBCb3VuZHMgbWVtb3J5XG4gICAqIHVuZGVyIGFidXNlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH1gXG4gICAqIG9uY2UgcmVhY2hlZC5cbiAgICovXG4gIG1heFRvdGFsVGlja2V0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2FwIG9uIGxpdmUgU1NFIHRpY2tldHMuIERlZmF1bHRzIHRvIDEwIGZyb21cbiAgICogYFNTRV9NQVhfVElDS0VUU19QRVJfT1JHYC4gUHJldmVudHMgYSBzaW5nbGUgdGVuYW50IGZyb20gc2F0dXJhdGluZyB0aGVcbiAgICogdGlja2V0IHRhYmxlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnb3JnLWxpbWl0JyB9YFxuICAgKiBvbmNlIHJlYWNoZWQuXG4gICAqL1xuICBtYXhUaWNrZXRzUGVyT3JnPzogbnVtYmVyO1xuICAvKiogVGlja2V0IFRUTCBpbiBtcyAoZGVmYXVsdDogYFNTRV9USUNLRVRfVFRMX01TYCBmcm9tIGFwaS1jb3JlKS4gKi9cbiAgdGlja2V0VHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQuIERlZmF1bHRzIHRvIGFuIGluLW1lbW9yeSBzdG9yZSAoY29ycmVjdFxuICAgKiBzaW5nbGUtcmVwbGljYSBvbmx5KS4gSW5qZWN0IGBjcmVhdGVFbnZSZWRpc1RpY2tldFN0b3JlKClgIChvciBhIGJlc3Bva2VcbiAgICogYFNTRVN0cmVhbVRpY2tldFN0b3JlYCkgc28gdGlja2V0IG1pbnQvcmVkZWVtIEFORCBzdHJlYW0gb3duZXJzaGlwIHdvcmsgYWNyb3NzXG4gICAqIGhvcml6b250YWxseS1zY2FsZWQgcG9kcyBhbmQg4oCUIGNyaXRpY2FsbHkg4oCUIHNvIHRoZSBwbGF0Zm9ybSBzdHJlYW0gcHJvZHVjZXJcbiAgICogKGEgZGlmZmVyZW50IHNlcnZpY2UpIGNhbiBiaW5kIG93bmVyc2hpcCB0aGF0IHRoaXMgc2VydmljZSByZWFkcy5cbiAgICovXG4gIHRpY2tldFN0b3JlPzogU1NFU3RyZWFtVGlja2V0U3RvcmU7XG4gIC8qKlxuICAgKiBUVEwgZm9yIGEgc3RyZWFtLW93bmVyc2hpcCBiaW5kaW5nIChkZWZhdWx0OiBgU1NFX1NUUkVBTV9PV05FUl9UVExfTVNgIGVudiBvclxuICAgKiAxaCkuIExvbmcgZW5vdWdoIHRvIG91dGxpdmUgYSBidWlsZDsgdGhlIHByb2R1Y2VyIHJlLWJpbmRzIGFzIG5lZWRlZC5cbiAgICovXG4gIHN0cmVhbU93bmVyVHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDcm9zcy1wb2QgZmFuLW91dCBidXMgZm9yIGBzZW5kKClgL2Bicm9hZGNhc3QoKWAuIE9wdGlvbmFsIOKAlCB3aGVuIG9taXR0ZWQsXG4gICAqIGRlbGl2ZXJ5IGlzIExPQ0FMLU9OTFkgKGNvcnJlY3Qgc2luZ2xlLXJlcGxpY2E7IHRvZGF5J3MgYmVoYXZpb3IpLiBJbmplY3RcbiAgICogYGNyZWF0ZUVudlJlZGlzU1NFUmVsYXkoKWAgc28gYSBmcmFtZSBwcm9kdWNlZCBvbiBvbmUgcG9kIHJlYWNoZXMgYW5cbiAgICogRXZlbnRTb3VyY2UgYXR0YWNoZWQgb24gYSBESUZGRVJFTlQgcG9kLiBEZWdyYWRlcyB0byBsb2NhbC1vbmx5IGF1dG9tYXRpY2FsbHlcbiAgICogd2hlbiBSZWRpcyBpcyB1bnNldCAodGhlIGZhY3RvcnkgcmV0dXJucyBudWxsKSBvciBkdXJpbmcgYSBSZWRpcyBvdXRhZ2UuXG4gICAqL1xuICByZWxheT86IFNTRVJlbGF5O1xufVxuXG4vKipcbiAqIEEgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IGlkOiBlaXRoZXIgYSBkYXNoZWQgVVVJRCAoYXBpLXNlcnZlcidzIGB1dWlkKClgKVxuICogb3IgbmdpbngncyBgJHJlcXVlc3RfaWRgIOKAlCAxNiByYW5kb20gYnl0ZXMgcmVuZGVyZWQgYXMgMzIgaGV4IGNoYXJzIHdpdGggTk9cbiAqIGRhc2hlcy4gQWNjZXB0IGJvdGggYnkgbWFraW5nIHRoZSBncm91cCBzZXBhcmF0b3JzIG9wdGlvbmFsOyBzdGlsbCBzdHJpY3RseVxuICogMzIgaGV4IGNoYXJzIHNvIGl0IGNhbid0IGNhcnJ5IGFuIGluamVjdGlvbiAvIHBhdGgtdHJhdmVyc2FsIHBheWxvYWQgaW50byB0aGVcbiAqIFNTRSBzdWJqZWN0LiBTaGFyZWQgYnkgdGhlIHRpY2tldC1taW50IHJvdXRlIGFuZCB0aGUgc3RyZWFtIG1pZGRsZXdhcmUgc29cbiAqIGJvdGggdmFsaWRhdGUgdGhlIHN1YmplY3QgaWRlbnRpY2FsbHkuXG4gKi9cbmV4cG9ydCBjb25zdCBTU0VfUkVRVUVTVF9JRF9SRSA9IC9eWzAtOWEtZl17OH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezEyfSQvaTtcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgU1NFTWFuYWdlci5jcmVhdGVUaWNrZXR9LiAqL1xuZXhwb3J0IHR5cGUgQ3JlYXRlVGlja2V0UmVzdWx0ID1cbiAgfCB7IG9rOiB0cnVlOyB0aWNrZXQ6IHN0cmluZyB9XG4gIHwgeyBvazogZmFsc2U7IHJlYXNvbjogJ29yZy1saW1pdCcgfCAnY2FwYWNpdHknIHwgJ2ZvcmJpZGRlbicgfTtcblxuLyoqXG4gKiBTU0UgTWFuYWdlciBzdGF0aXN0aWNzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlclN0YXRzIHtcbiAgdG90YWxSZXF1ZXN0czogbnVtYmVyO1xuICB0b3RhbENsaWVudHM6IG51bWJlcjtcbiAgb2xkZXN0Q29ubmVjdGlvbk1zOiBudW1iZXIgfCBudWxsO1xufVxuXG4vKipcbiAqIFNTRSBoZWxwZXIgY2xhc3Mgd2l0aCBtZW1vcnkgbGVhayBwcm90ZWN0aW9uXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIENsaWVudCBsaW1pdHMgcGVyIHJlcXVlc3QgSURcbiAqIC0gQXV0b21hdGljIHRpbWVvdXQgZm9yIGlkbGUgY29ubmVjdGlvbnNcbiAqIC0gUGVyaW9kaWMgY2xlYW51cCBvZiBzdGFsZSBjb25uZWN0aW9uc1xuICogLSBDb25uZWN0aW9uIHN0YXRpc3RpY3NcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc3NlTWFuYWdlciA9IG5ldyBTU0VNYW5hZ2VyKHsgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IDUgfSk7XG4gKiBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuICpcbiAqIC8vIFNlbmQgZXZlbnRzXG4gKiBzc2VNYW5hZ2VyLnNlbmQoJ3JlcXVlc3QtMTIzJywgJ0lORk8nLCAnUHJvY2Vzc2luZy4uLicpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTU0VNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBjbGllbnRzID0gbmV3IE1hcDxzdHJpbmcsIFNTRUNsaWVudFtdPigpO1xuICAvKiogUGVyLW9yZyBvcGVuLWNsaWVudCBjb3VudGVycy4gRGVjcmVtZW50ZWQgb24gcmVtb3ZlQ2xpZW50L2NsZWFudXAgc28gdGhlXG4gICAqICBtYXAgbWlycm9ycyBgY2xpZW50c1tdLm9yZ0lkYCBjb3VudHMgYXQgYWxsIHRpbWVzLiBPcmdzIHJlYWNoIHplcm8gYXJlXG4gICAqICBkZWxldGVkIHRvIGtlZXAgdGhlIG1hcCBib3VuZGVkLiAqL1xuICBwcml2YXRlIG9yZ0NsaWVudENvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQgKGluLW1lbW9yeSBkZWZhdWx0OyBSZWRpcyBmb3IgbXVsdGktcG9kKS5cbiAgICogIEJvdW5kZWQgYnkgYG1heFRvdGFsVGlja2V0c2AgLyBgbWF4VGlja2V0c1Blck9yZ2AsIGVuZm9yY2VkIGluIGNyZWF0ZVRpY2tldDtcbiAgICogIGV4cGlyeSBpcyB2YWxpZGF0ZWQgYXQgY29uc3VtZSB0aW1lIGFuZCBzd2VwdCBvbiB0aGUgY2xlYW51cCBpbnRlcnZhbC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0aWNrZXRTdG9yZTogU1NFU3RyZWFtVGlja2V0U3RvcmU7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbENsaWVudHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VG90YWxUaWNrZXRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VGlja2V0c1Blck9yZzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHRpY2tldFR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyZWFtT3duZXJUdGxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRpbWVvdXRNczogbnVtYmVyO1xuICBwcml2YXRlIGNsZWFudXBJbnRlcnZhbDogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgLyoqIENyb3NzLXBvZCBmYW4tb3V0IGJ1cyAodW5kZWZpbmVkIOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5KS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZWxheT86IFNTRVJlbGF5O1xuICAvKiogVGhpcyBtYW5hZ2VyIGluc3RhbmNlJ3MgaWQg4oCUIHRhZ3MgcmVsYXllZCBmcmFtZXMgc28gd2UgaWdub3JlIG91ciBvd24gZWNoby4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBub2RlSWQgPSByYW5kb21CeXRlcyg4KS50b1N0cmluZygnaGV4Jyk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU1NFTWFuYWdlck9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QgPSBvcHRpb25zLm1heENsaWVudHNQZXJSZXF1ZXN0ID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfQ0xJRU5UU19QRVJfUkVRVUVTVCB8fCAnMTAnLCAxMCk7XG4gICAgdGhpcy5tYXhUb3RhbENsaWVudHMgPSBvcHRpb25zLm1heFRvdGFsQ2xpZW50cyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX1RPVEFMX0NMSUVOVFMgfHwgJzEwMDAnLCAxMCk7XG4gICAgdGhpcy5tYXhDbGllbnRzUGVyT3JnID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyT3JnID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfQ0xJRU5UU19QRVJfT1JHIHx8ICc1MCcsIDEwKTtcbiAgICB0aGlzLm1heFRvdGFsVGlja2V0cyA9IG9wdGlvbnMubWF4VG90YWxUaWNrZXRzID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfVE9UQUxfVElDS0VUUyB8fCAnMTAwMCcsIDEwKTtcbiAgICB0aGlzLm1heFRpY2tldHNQZXJPcmcgPSBvcHRpb25zLm1heFRpY2tldHNQZXJPcmcgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX01BWF9USUNLRVRTX1BFUl9PUkcgfHwgJzEwJywgMTApO1xuICAgIHRoaXMudGlja2V0VHRsTXMgPSBvcHRpb25zLnRpY2tldFR0bE1zID8/IFNTRV9USUNLRVRfVFRMX01TO1xuICAgIHRoaXMuc3RyZWFtT3duZXJUdGxNcyA9IG9wdGlvbnMuc3RyZWFtT3duZXJUdGxNcyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfU1RSRUFNX09XTkVSX1RUTF9NUyB8fCAnMzYwMDAwMCcsIDEwKTsgLy8gMSBob3VyXG4gICAgdGhpcy50aWNrZXRTdG9yZSA9IG9wdGlvbnMudGlja2V0U3RvcmUgPz8gY3JlYXRlTWVtb3J5VGlja2V0U3RvcmUoKTtcbiAgICB0aGlzLmNsaWVudFRpbWVvdXRNcyA9IG9wdGlvbnMuY2xpZW50VGltZW91dE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTElFTlRfVElNRU9VVF9NUyB8fCAnMTgwMDAwMCcsIDEwKTsgLy8gMzAgbWludXRlc1xuXG4gICAgY29uc3QgY2xlYW51cEludGVydmFsTXMgPSBvcHRpb25zLmNsZWFudXBJbnRlcnZhbE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTEVBTlVQX0lOVEVSVkFMX01TIHx8ICczMDAwMDAnLCAxMCk7IC8vIDUgbWludXRlc1xuICAgIHRoaXMuc3RhcnRDbGVhbnVwSW50ZXJ2YWwoY2xlYW51cEludGVydmFsTXMpO1xuXG4gICAgLy8gV2lyZSB0aGUgY3Jvc3MtcG9kIHJlbGF5OiBzdWJzY3JpYmUgb25jZSBvbiBzdGFydHVwIHNvIGZyYW1lcyBQVUJMSVNIRUQgYnlcbiAgICAvLyBhbnkgb3RoZXIgcG9kIGFyZSByZS1lbWl0dGVkIHRvIFRISVMgcG9kJ3MgbG9jYWwgY2xpZW50cy4gRnJhbWVzIHdlXG4gICAgLy8gcHVibGlzaGVkIG91cnNlbHZlcyBhcmUgaWdub3JlZCAob3JpZ2luID09PSBub2RlSWQpIOKAlCB3ZSBhbHJlYWR5IHdyb3RlIHRoZW1cbiAgICAvLyBsb2NhbGx5LiBGYWlsLXNhZmU6IG5vIHJlbGF5IOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5IChzaW5nbGUtcmVwbGljYSBkZWZhdWx0KS5cbiAgICB0aGlzLnJlbGF5ID0gb3B0aW9ucy5yZWxheTtcbiAgICB0aGlzLnJlbGF5Py5zdWJzY3JpYmUoKG1zZykgPT4gdGhpcy5vblJlbGF5TWVzc2FnZShtc2cpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgYSBmcmFtZSByZWNlaXZlZCBmcm9tIGFub3RoZXIgcG9kIHZpYSB0aGUgcmVsYXkuIFdlIGFscmVhZHkgZGVsaXZlcmVkXG4gICAqIG91ciBPV04gZnJhbWVzIHRvIGxvY2FsIGNsaWVudHMgYmVmb3JlIHB1Ymxpc2hpbmcsIHNvIGlnbm9yZSBvdXIgZWNoby4gQVxuICAgKiBgc2VuZGAgcmUtZW1pdHMgdG8gdGhlIHN1YmplY3QncyBsb2NhbCBjbGllbnRzOyBhIGBicm9hZGNhc3RgIHRvIGFsbCBvZiB0aGVtLlxuICAgKiBQdXJlbHkgbG9jYWwg4oCUIG5ldmVyIHJlLXB1Ymxpc2hlcywgc28gdGhlcmUgaXMgbm8gZmFuLW91dCBsb29wLlxuICAgKi9cbiAgcHJpdmF0ZSBvblJlbGF5TWVzc2FnZShtc2c6IFNTRVJlbGF5TWVzc2FnZSk6IHZvaWQge1xuICAgIGlmICghbXNnIHx8IG1zZy5vcmlnaW4gPT09IHRoaXMubm9kZUlkKSByZXR1cm47XG4gICAgaWYgKG1zZy5raW5kID09PSAnYnJvYWRjYXN0Jykge1xuICAgICAgdGhpcy5icm9hZGNhc3RMb2NhbChtc2cucGF5bG9hZCk7XG4gICAgfSBlbHNlIGlmIChtc2cucmVxdWVzdElkKSB7XG4gICAgICB0aGlzLnNlbmRMb2NhbChtc2cucmVxdWVzdElkLCBtc2cucGF5bG9hZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFRvdGFsIG9wZW4gY29ubmVjdGlvbnMgYWNyb3NzIGFsbCByZXF1ZXN0cy4gKi9cbiAgcHJpdmF0ZSB0b3RhbENsaWVudHMoKTogbnVtYmVyIHtcbiAgICBsZXQgbiA9IDA7XG4gICAgZm9yIChjb25zdCBjbGllbnRzIG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkgbiArPSBjbGllbnRzLmxlbmd0aDtcbiAgICByZXR1cm4gbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIHRoZSBjdXJyZW50IGxpdmUtY29ubmVjdGlvbiBjb3VudCBhcyBhIGdhdWdlIHNvIG9uLWNhbGwgY2FuIHNlZSBTU0VcbiAgICogc2F0dXJhdGlvbiAoYXBwcm9hY2ggdG8gdGhlIHBlci1wcm9jZXNzIGNhcCkgb24gYSBkYXNoYm9hcmQg4oCUIHByZXZpb3VzbHlcbiAgICogdGhlc2UgbnVtYmVycyBsaXZlZCBvbmx5IGluIGBnZXRTdGF0cygpYC9sb2dzLiBDYWxsZWQgYWZ0ZXIgZXZlcnkgYWRkL3JlbW92ZS9cbiAgICogY2xvc2UvY2xlYW51cC4gQ2hlYXAgKE8oUikpOyBtZXRyaWMgaGVscGVycyBuZXZlciB0aHJvdy5cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlQWN0aXZlR2F1Z2UoKTogdm9pZCB7XG4gICAgc2V0R2F1Z2UoJ3NzZV9hY3RpdmVfY29ubmVjdGlvbnMnLCB7fSwgdGhpcy50b3RhbENsaWVudHMoKSk7XG4gIH1cblxuICAvKiogQ3VycmVudCBvcGVuLXN0cmVhbSBjb3VudCBmb3IgYW4gb3JnICgwIGlmIHVuc2VlbikuICovXG4gIGdldE9yZ0NsaWVudENvdW50KG9yZ0lkOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gIH1cblxuICAvKipcbiAgICogQ2Fub25pY2FsIGZvcm0gb2YgYSByZXF1ZXN0SWQgZm9yIGVxdWFsaXR5IGNoZWNrczogZGFzaGVzIHN0cmlwcGVkIGFuZFxuICAgKiBsb3dlcmNhc2VkLCBzbyB0aGUgZGFzaGVkIChhcGktc2VydmVyIGB1dWlkKClgKSBhbmQgdW5kYXNoZWQgKG5naW54XG4gICAqIGAkcmVxdWVzdF9pZGApIHJlbmRlcmluZ3Mgb2YgdGhlIHNhbWUgaWQgY29tcGFyZSBlcXVhbC4gQ2FsbGVycyBhcmVcbiAgICogZXhwZWN0ZWQgdG8gaGF2ZSBhbHJlYWR5IGZvcm1hdC12YWxpZGF0ZWQgYWdhaW5zdCB7QGxpbmsgU1NFX1JFUVVFU1RfSURfUkV9LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVxdWVzdElkLnJlcGxhY2UoLy0vZywgJycpLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2Fub25pY2FsIGZvcm0gb2YgYW4gb3JnSWQgZm9yIG93bmVyc2hpcCBlcXVhbGl0eSBjaGVja3M6IHRyaW1tZWQgYW5kXG4gICAqIGxvd2VyY2FzZWQuIFRoZSBzdHJlYW0gUFJPRFVDRVIgKGJpbmRTdHJlYW1Pd25lcikgYW5kIHRoZSB0aWNrZXQtbWludGluZ1xuICAgKiBDT05TVU1FUiAoY3JlYXRlVGlja2V0KSBydW4gaW4gZGlmZmVyZW50IHNlcnZpY2VzLCBzbyBhIGNhc2luZyAvIHdoaXRlc3BhY2VcbiAgICogZHJpZnQgYmV0d2VlbiBob3cgZWFjaCByZW5kZXJzIHRoZSBzYW1lIG9yZyB3b3VsZCBvdGhlcndpc2UgbWFrZSB0aGUgb3duZXJcbiAgICogY29tcGFyaXNvbiBpbiB7QGxpbmsgY3JlYXRlVGlja2V0fSBmYWxzZS1gZm9yYmlkZGVuYCB0aGUgcmVhbCBvd25lci5cbiAgICogTm9ybWFsaXppbmcgYm90aCBzaWRlcyDigJQgbWlycm9yaW5nIHtAbGluayBub3JtYWxpemVSZXF1ZXN0SWR9IOKAlCBjbG9zZXMgdGhhdC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIG5vcm1hbGl6ZU9yZ0lkKG9yZ0lkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBvcmdJZC50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgdGhlIG9yZyB0aGF0IE9XTlMgYSBzdHJlYW0gc3ViamVjdC4gVGhlIHN0cmVhbSBQUk9EVUNFUiBjYWxscyB0aGlzXG4gICAqIHdoZW4gaXQgY3JlYXRlcyBhIGJ1aWxkLWxvZyBzdHJlYW0gc28gdGhhdCB0aWNrZXQgbWludGluZyBjYW4gYXNzZXJ0IHRoZVxuICAgKiBjYWxsZXIncyBvcmcgb3ducyB0aGUgc3ViamVjdCAoc2VlIHtAbGluayBjcmVhdGVUaWNrZXR9KS4gQmFja2VkIGJ5IHRoZVxuICAgKiBpbmplY3RlZCB0aWNrZXQgc3RvcmUsIHNvIHdoZW4gYSBSZWRpcyBzdG9yZSBpcyB3aXJlZCB0aGUgcGxhdGZvcm0gcHJvZHVjZXJcbiAgICogKGEgZGlmZmVyZW50IHNlcnZpY2Ugc2hhcmluZyB0aGUgc2FtZSBSZWRpcykgY2FuIGJpbmQgb3duZXJzaGlwIHRoYXQgdGhpc1xuICAgKiBzZXJ2aWNlIHJlYWRzIOKAlCBjbG9zaW5nIHRoZSBjcm9zcy10ZW5hbnQgYXR0YWNoIGdhcCB3aGVyZSBhbnkgb3JnIGNvdWxkIG1pbnRcbiAgICogYSB0aWNrZXQgZm9yIGEgZ3Vlc3NlZCByZXF1ZXN0SWQuXG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBUaGUgc3RyZWFtIHN1YmplY3QgKGZvcm1hdC12YWxpZGF0ZWQgYnkgdGhlIGNhbGxlcikuXG4gICAqIEBwYXJhbSBvcmdJZCAtIFRoZSBvd25pbmcgb3JnIChub3JtYWxpemVkIGludGVybmFsbHkgdmlhIG5vcm1hbGl6ZU9yZ0lkKS5cbiAgICovXG4gIGFzeW5jIGJpbmRTdHJlYW1Pd25lcihyZXF1ZXN0SWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMudGlja2V0U3RvcmUuYmluZFN0cmVhbU93bmVyKFxuICAgICAgU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSxcbiAgICAgIFNTRU1hbmFnZXIubm9ybWFsaXplT3JnSWQob3JnSWQpLFxuICAgICAgdGhpcy5zdHJlYW1Pd25lclR0bE1zLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogTWludCBhIHNob3J0LWxpdmVkLCBzaW5nbGUtdXNlIFNTRSB0aWNrZXQgYm91bmQgdG8gYG9yZ0lkYCBBTkQgYSBzcGVjaWZpY1xuICAgKiBzdHJlYW0gc3ViamVjdCAoYHJlcXVlc3RJZGApLiBDbGllbnRzIFBPU1QgdG8gb2J0YWluIG9uZSAoSldULWF1dGhlbnRpY2F0ZWQpXG4gICAqIGZvciB0aGUgZXhhY3Qgc3RyZWFtIHRoZXkgaW50ZW5kIHRvIG9wZW4sIHRoZW4gb3BlbiB0aGUgRXZlbnRTb3VyY2Ugd2l0aFxuICAgKiBgP3RpY2tldD08dD5gIHNvIHRoZSBKV1QgbmV2ZXIgbGFuZHMgaW4gYSBxdWVyeSBzdHJpbmcgLyBhY2Nlc3MgbG9nLiBUaGVcbiAgICogdGlja2V0IGNhbiB0aGVuIG9ubHkgYmUgY29uc3VtZWQgdG8gb3BlbiB0aGF0IG9uZSBzdWJqZWN0J3Mgc3RyZWFtIOKAlCBzZWVcbiAgICoge0BsaW5rIGNvbnN1bWVUaWNrZXR9IOKAlCB3aGljaCBpcyB3aGF0IGVuZm9yY2VzIHBlci1zdWJqZWN0IGF1dGhvcml6YXRpb24uXG4gICAqXG4gICAqIE9SRy1PV05FUlNISVA6IGlmIGEgc3RyZWFtIG93bmVyIGhhcyBiZWVuIGJvdW5kIGZvciB0aGlzIHN1YmplY3QgKHZpYVxuICAgKiB7QGxpbmsgYmluZFN0cmVhbU93bmVyfSkgYW5kIGl0IGlzIGEgRElGRkVSRU5UIG9yZywgbWludGluZyBpcyByZWZ1c2VkXG4gICAqIChgcmVhc29uOiAnZm9yYmlkZGVuJ2ApIOKAlCBhbiBvcmcgY2Fubm90IG1pbnQgYSB0aWNrZXQgZm9yIGFub3RoZXIgb3JnJ3NcbiAgICogc3RyZWFtIGV2ZW4gaWYgaXQgZ3Vlc3NlcyB0aGUgcmVxdWVzdElkLiBXaGVuIG5vIG93bmVyIGlzIGJvdW5kIChwcm9kdWNlclxuICAgKiB3aXJpbmcgbm90IHlldCBwcmVzZW50KSwgbWludGluZyBmYWxscyBiYWNrIHRvIGJpbmRpbmcgdGhlIHRpY2tldCB0byB0aGVcbiAgICogY2FsbGVyJ3Mgb3duIG9yZywgcHJlc2VydmluZyBjdXJyZW50IGJlaGF2aW9yLlxuICAgKlxuICAgKiBCb3VuZGVkIGJ5IGBtYXhUb3RhbFRpY2tldHNgIChwcm9jZXNzLXdpZGUpIGFuZCBgbWF4VGlja2V0c1Blck9yZ2BcbiAgICogKHBlci10ZW5hbnQpLiBNaXJyb3JzIHRoZSBtZXNzYWdlLXNlcnZpY2Ugbm90aWZpY2F0aW9ucyB0aWNrZXQgc3RvcmUuXG4gICAqXG4gICAqIEBwYXJhbSBvcmdJZCAtIE93bmluZyBvcmcgKG5vcm1hbGl6ZWQgaW50ZXJuYWxseSB2aWEgbm9ybWFsaXplT3JnSWQpLlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVGhlIGJ1aWxkLWxvZyBzdHJlYW0gc3ViamVjdCB0aGlzIHRpY2tldCBhdXRob3JpemVzLlxuICAgKiAgIFRoZSBjYWxsZXIgbXVzdCBoYXZlIGZvcm1hdC12YWxpZGF0ZWQgaXQgKHNlZSB7QGxpbmsgU1NFX1JFUVVFU1RfSURfUkV9KS5cbiAgICogQHJldHVybnMgYHsgb2s6IHRydWUsIHRpY2tldCB9YCBvbiBzdWNjZXNzLCBvciBgeyBvazogZmFsc2UsIHJlYXNvbiB9YFxuICAgKiAgIHdoZXJlIHJlYXNvbiBpcyBgJ29yZy1saW1pdCdgLCBgJ2NhcGFjaXR5J2AsIG9yIGAnZm9yYmlkZGVuJ2AuXG4gICAqL1xuICBhc3luYyBjcmVhdGVUaWNrZXQob3JnSWQ6IHN0cmluZywgcmVxdWVzdElkOiBzdHJpbmcpOiBQcm9taXNlPENyZWF0ZVRpY2tldFJlc3VsdD4ge1xuICAgIC8vIE93bmVyc2hpcCBnYXRlIGZpcnN0IOKAlCBhIGNyb3NzLXRlbmFudCBtaW50IGF0dGVtcHQgc2hvdWxkIG5ldmVyIGV2ZW5cbiAgICAvLyBjb25zdW1lIGNhcCBidWRnZXQuIE9ubHkgZW5mb3JjZWQgd2hlbiBhbiBvd25lciBpcyBhY3R1YWxseSBib3VuZC4gQm90aFxuICAgIC8vIHNpZGVzIGFyZSBvcmctbm9ybWFsaXplZCBzbyBhIHByb2R1Y2VyL2NvbnN1bWVyIGNhc2luZyBkcmlmdCBjYW4ndFxuICAgIC8vIGZhbHNlLWBmb3JiaWRkZW5gIHRoZSByZWFsIG93bmVyIChtaXJyb3JzIHJlcXVlc3RJZCBub3JtYWxpemF0aW9uKS5cbiAgICBjb25zdCBub3JtYWxpemVkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTtcbiAgICBjb25zdCBub3JtYWxpemVkT3JnID0gU1NFTWFuYWdlci5ub3JtYWxpemVPcmdJZChvcmdJZCk7XG4gICAgY29uc3Qgb3duZXIgPSBhd2FpdCB0aGlzLnRpY2tldFN0b3JlLmdldFN0cmVhbU93bmVyKG5vcm1hbGl6ZWQpO1xuICAgIGlmIChvd25lciAmJiBvd25lciAhPT0gbm9ybWFsaXplZE9yZykge1xuICAgICAgbG9nZ2VyLndhcm4oYFNTRSB0aWNrZXQgcmVmdXNlZDogb3JnICR7bm9ybWFsaXplZE9yZ30gZG9lcyBub3Qgb3duIHN0cmVhbSBzdWJqZWN0YCk7XG4gICAgICBpbmNDb3VudGVyKCdzc2VfdGlja2V0X3JlamVjdGVkX3RvdGFsJywgeyByZWFzb246ICdmb3JiaWRkZW4nIH0pO1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCByZWFzb246ICdmb3JiaWRkZW4nIH07XG4gICAgfVxuXG4gICAgLy8gVG90YWwgY2FwIG5leHQg4oCUIHByb3RlY3RzIHByb2Nlc3MgbWVtb3J5IGV2ZW4gd2hlbiBhIHNpbmdsZSBvcmcgaXNcbiAgICAvLyB0aGUgb2ZmZW5kZXIuIFRoZW4gdGhlIHBlci1vcmcgY2FwIGZvciBmYWlyLXNoYXJlLlxuICAgIGlmICgoYXdhaXQgdGhpcy50aWNrZXRTdG9yZS50b3RhbCgpKSA+PSB0aGlzLm1heFRvdGFsVGlja2V0cykge1xuICAgICAgbG9nZ2VyLndhcm4oYFNTRSB0aWNrZXQgY2FwIHJlYWNoZWQgKG1heDogJHt0aGlzLm1heFRvdGFsVGlja2V0c30pOyByZWplY3RpbmcgdGlja2V0IHJlcXVlc3RgKTtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV90aWNrZXRfcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ2NhcGFjaXR5JyB9KTtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH07XG4gICAgfVxuICAgIGlmICgoYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5jb3VudEZvck9yZyhub3JtYWxpemVkT3JnKSkgPj0gdGhpcy5tYXhUaWNrZXRzUGVyT3JnKSB7XG4gICAgICBsb2dnZXIud2FybihgUGVyLW9yZyBTU0UgdGlja2V0IGNhcCByZWFjaGVkIGZvciAke25vcm1hbGl6ZWRPcmd9IChtYXg6ICR7dGhpcy5tYXhUaWNrZXRzUGVyT3JnfSlgKTtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV90aWNrZXRfcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ29yZy1saW1pdCcgfSk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ29yZy1saW1pdCcgfTtcbiAgICB9XG5cbiAgICBjb25zdCB0aWNrZXQgPSByYW5kb21CeXRlcygyNCkudG9TdHJpbmcoJ2Jhc2U2NHVybCcpO1xuICAgIGF3YWl0IHRoaXMudGlja2V0U3RvcmUucHV0KHRpY2tldCwgeyBvcmdJZDogbm9ybWFsaXplZE9yZywgcmVxdWVzdElkOiBub3JtYWxpemVkIH0sIHRoaXMudGlja2V0VHRsTXMpO1xuICAgIHJldHVybiB7IG9rOiB0cnVlLCB0aWNrZXQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbmQgQ09OU1VNRSBhIHRpY2tldCBmb3IgYSBzcGVjaWZpYyBzdHJlYW0gc3ViamVjdC4gU2luZ2xlLXVzZTpcbiAgICogdGhlIHRpY2tldCBpcyBkZWxldGVkIHdoZXRoZXIgb3Igbm90IGl0IHR1cm5zIG91dCB0byBiZSB2YWxpZCwgc28gYSByZXBsYXlcbiAgICogb2YgdGhlIHNhbWUgdmFsdWUgYWx3YXlzIGZhaWxzLiBSZXR1cm5zIHRoZSBib3VuZCBvcmcgb24gc3VjY2Vzcywgb3IgbnVsbFxuICAgKiB3aGVuIHRoZSB0aWNrZXQgaXMgdW5rbm93biAvIGFscmVhZHktdXNlZCAvIGV4cGlyZWQgLyBPUiB3YXMgbWludGVkIGZvciBhXG4gICAqIERJRkZFUkVOVCBgcmVxdWVzdElkYCB0aGFuIHRoZSBvbmUgYmVpbmcgb3BlbmVkLlxuICAgKlxuICAgKiBUaGUgc3ViamVjdCBjaGVjayBpcyB0aGUgYXV0aG9yaXphdGlvbiBmaXg6IHdpdGhvdXQgaXQsIGEgdGlja2V0IG1pbnRlZCBmb3JcbiAgICogb25lIHN0cmVhbSBjb3VsZCBiZSBwcmVzZW50ZWQgdG8gb3BlbiBBTlkgc3RyZWFtIHRoZSBob2xkZXIncyBvcmcgY291bGRcbiAgICogbmFtZSwgbGV0dGluZyBhbiBhdXRoZW50aWNhdGVkIG9yZyBhdHRhY2ggdG8gYW5vdGhlciBvcmcncyBsb2cgc3RyZWFtIGJ5XG4gICAqIGd1ZXNzaW5nIGl0cyByZXF1ZXN0SWQuIFRoZSBnZW5lcmljIDQwMSB0aGUgY2FsbGVyIHJldHVybnMgZG9lcyBub3RcbiAgICogZGlzdGluZ3Vpc2ggXCJ1bmtub3duIHRpY2tldFwiIGZyb20gXCJ3cm9uZyBzdWJqZWN0XCIsIHNvIGl0IGxlYWtzIG5vdGhpbmdcbiAgICogYWJvdXQgd2hpY2ggcmVxdWVzdElkcyBleGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHRpY2tldElkIC0gVGhlIG9wYXF1ZSB0aWNrZXQgdmFsdWUgZnJvbSBgP3RpY2tldD1gLlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVGhlIHN0cmVhbSBzdWJqZWN0IGZyb20gdGhlIFVSTCBwYXRoIChgOnJlcXVlc3RJZGApLFxuICAgKiAgIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyLlxuICAgKi9cbiAgYXN5bmMgY29uc3VtZVRpY2tldCh0aWNrZXRJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8eyBvcmdJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgY29uc3QgdGlja2V0ID0gYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5jb25zdW1lKHRpY2tldElkKTsgLy8gc2luZ2xlLXVzZVxuICAgIGlmICghdGlja2V0KSByZXR1cm4gbnVsbDtcbiAgICAvLyBTdWJqZWN0IGJpbmRpbmcg4oCUIHJlamVjdCBhIHRpY2tldCBwcmVzZW50ZWQgZm9yIGEgc3ViamVjdCBpdCB3YXMgbm90XG4gICAgLy8gbWludGVkIGZvci4gQm90aCBzaWRlcyBhcmUgbm9ybWFsaXplZCBzbyBkYXNoZWQvdW5kYXNoZWQgZm9ybXMgbWF0Y2guXG4gICAgaWYgKHRpY2tldC5yZXF1ZXN0SWQgIT09IFNTRU1hbmFnZXIubm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZCkpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7IG9yZ0lkOiB0aWNrZXQub3JnSWQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgY2xpZW50IHRvIHRoZSBTU0UgbWFuYWdlclxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVW5pcXVlIHJlcXVlc3QgSURcbiAgICogQHBhcmFtIHJlcyAtIEV4cHJlc3MgUmVzcG9uc2Ugb2JqZWN0XG4gICAqIEBwYXJhbSBvcmdJZCAtIEF1dGhlbnRpY2F0ZWQgb3JnIGlkIChvcHRpb25hbCkuIFdoZW4gc2V0LCBlbmZvcmNlcyB0aGVcbiAgICogICBwZXItb3JnIGNhcCBhbmQgdGhlIGNvdW50ZXIgaXMgZGVjcmVtZW50ZWQgb24gZGlzY29ubmVjdC9jbGVhbnVwLlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIGNsaWVudCB3YXMgYWRkZWQsIGZhbHNlIGlmIHJlamVjdGVkIChsaW1pdCByZWFjaGVkKVxuICAgKi9cbiAgYWRkQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCByZXM6IFJlc3BvbnNlLCBvcmdJZD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIC8vIE5vcm1hbGl6ZSB0aGUgbWFwIGtleTogdGhlIHN1YmplY3QgaWQgaXMgYWxsb3dlZCBpbiB0d28gZm9ybXMgKGRhc2hlZFxuICAgIC8vIGFwaS1zZXJ2ZXIgdXVpZCB2cyB1bmRhc2hlZCBuZ2lueCAkcmVxdWVzdF9pZCksIGFuZCBhIHByb2R1Y2VyL2NvbnN1bWVyIHRoYXRcbiAgICAvLyByZW5kZXIgaXQgZGlmZmVyZW50bHkgd291bGQgb3RoZXJ3aXNlIGtleSBkaWZmZXJlbnQgTWFwIGVudHJpZXMg4oCUIHRoZSBjbGllbnRcbiAgICAvLyByZWdpc3RlcnMgdW5kZXIgb25lIGFuZCBldmVyeSBzZW5kKCkvcmVsYXkgd3JpdGVzIHRvIGFub3RoZXIsIGRyb3BwaW5nIGFsbFxuICAgIC8vIGZyYW1lcy4gTm9ybWFsaXppbmcgaGVyZSAoYW5kIGluIHNlbmQvc2VuZExvY2FsL2Nsb3NlUmVxdWVzdC9ldGMuKSB1bmlmaWVzIHRoZW0uXG4gICAgcmVxdWVzdElkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKSB8fCBbXTtcblxuICAgIC8vIENoZWNrIGNsaWVudCBsaW1pdFxuICAgIGlmIChleGlzdGluZy5sZW5ndGggPj0gdGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdCkge1xuICAgICAgbG9nZ2VyLndhcm4oYENsaWVudCBsaW1pdCByZWFjaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1BlclJlcXVlc3R9KWApO1xuICAgICAgaW5jQ291bnRlcignc3NlX2Nvbm5lY3Rpb25fcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ3JlcXVlc3QtbGltaXQnIH0pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFByb2Nlc3Mtd2lkZSBjYXA6IHByb3RlY3RzIGZkIHRhYmxlICsgbWVtb3J5IGZyb20gcnVuYXdheSBkYXNoYm9hcmRzLlxuICAgIGlmICh0aGlzLnRvdGFsQ2xpZW50cygpID49IHRoaXMubWF4VG90YWxDbGllbnRzKSB7XG4gICAgICBsb2dnZXIud2FybihgVG90YWwgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCAobWF4OiAke3RoaXMubWF4VG90YWxDbGllbnRzfSk7IHJlamVjdGluZyBuZXcgY29ubmVjdGlvbmApO1xuICAgICAgaW5jQ291bnRlcignc3NlX2Nvbm5lY3Rpb25fcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ3RvdGFsLWNhcCcgfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUGVyLW9yZyBjYXA6IHByZXZlbnRzIG9uZSBub2lzeSBvcmcgZnJvbSBtb25vcG9saXppbmcgcHJvY2Vzcy13aWRlXG4gICAgLy8gc2xvdHMuIEVuZm9yY2VkIG9ubHkgd2hlbiBvcmdJZCBpcyBrbm93biDigJQgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91c1xuICAgIC8vIHN0cmVhbXMgdGhhdCBuZXZlciBpZGVudGlmeSB3aXRoIGFuIG9yZ0lkIHN0YXkgc3ViamVjdCB0byB0aGUgZ2xvYmFsXG4gICAgLy8gY2VpbGluZ3MgYWJvdmUuIFJlc2VydmUgYXRvbWljYWxseSBiZWZvcmUgaW5zZXJ0IHNvIHR3byBjb25jdXJyZW50XG4gICAgLy8gcmVxdWVzdHMgYXQgdGhlIGxpbWl0IGNhbid0IGJvdGggc3VjY2VlZC5cbiAgICBpZiAob3JnSWQpIHtcbiAgICAgIGNvbnN0IG9yZ0N1cnJlbnQgPSB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gICAgICBpZiAob3JnQ3VycmVudCA+PSB0aGlzLm1heENsaWVudHNQZXJPcmcpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJPcmd9KTsgcmVqZWN0aW5nIG5ldyBjb25uZWN0aW9uYCk7XG4gICAgICAgIGluY0NvdW50ZXIoJ3NzZV9jb25uZWN0aW9uX3JlamVjdGVkX3RvdGFsJywgeyByZWFzb246ICdvcmctY2FwJyB9KTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhpcy5vcmdDbGllbnRDb3VudHMuc2V0KG9yZ0lkLCBvcmdDdXJyZW50ICsgMSk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHRpbWVvdXQgZm9yIHRoaXMgY2xpZW50XG4gICAgY29uc3QgY2xpZW50SWQgPSB1dWlkKCk7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgbG9nZ2VyLmRlYnVnKGBDbGllbnQgJHtjbGllbnRJZH0gdGltZWQgb3V0IGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfWApO1xuICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnRJZCk7XG4gICAgICB0cnkge1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdSZXNwb25zZSBhbHJlYWR5IGNsb3NlZCBvbiB0aW1lb3V0JywgeyByZXF1ZXN0SWQsIGNsaWVudElkLCBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH0sIHRoaXMuY2xpZW50VGltZW91dE1zKTtcblxuICAgIGNvbnN0IGNsaWVudDogU1NFQ2xpZW50ID0ge1xuICAgICAgaWQ6IGNsaWVudElkLFxuICAgICAgcmVzLFxuICAgICAgY29ubmVjdGVkQXQ6IERhdGUubm93KCksXG4gICAgICB0aW1lb3V0LFxuICAgICAgYmFja3ByZXNzdXJlQ291bnQ6IDAsXG4gICAgICBvcmdJZCxcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIGRpc2Nvbm5lY3Rpb25cbiAgICByZXMub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnRJZCk7XG4gICAgfSk7XG5cbiAgICByZXMub24oJ2Vycm9yJywgKGVycikgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKGBTU0UgY2xpZW50IGVycm9yIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfTpgLCBlcnIpO1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnRJZCk7XG4gICAgfSk7XG5cbiAgICBleGlzdGluZy5wdXNoKGNsaWVudCk7XG4gICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIGV4aXN0aW5nKTtcbiAgICBpbmNDb3VudGVyKCdzc2VfY29ubmVjdGlvbnNfdG90YWwnLCB7fSk7XG4gICAgdGhpcy51cGRhdGVBY3RpdmVHYXVnZSgpO1xuXG4gICAgbG9nZ2VyLmRlYnVnKGBDbGllbnQgJHtjbGllbnRJZH0gY29ubmVjdGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAodG90YWw6ICR7ZXhpc3RpbmcubGVuZ3RofSlgKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBEcm9wIG9uZSBmcm9tIHRoZSBwZXItb3JnIGNvdW50ZXIuIElkZW1wb3RlbnQ6IGEgY291bnRlciBhdCAwIHN0YXlzIGF0IDBcbiAgICogIGFuZCB0aGUgb3JnIGtleSBpcyByZW1vdmVkIGZyb20gdGhlIG1hcC4gKi9cbiAgcHJpdmF0ZSBkZWNyZW1lbnRPcmdDb3VudChvcmdJZD86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghb3JnSWQpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwO1xuICAgIGlmIChjdXJyZW50IDw9IDEpIHRoaXMub3JnQ2xpZW50Q291bnRzLmRlbGV0ZShvcmdJZCk7XG4gICAgZWxzZSB0aGlzLm9yZ0NsaWVudENvdW50cy5zZXQob3JnSWQsIGN1cnJlbnQgLSAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgY2xpZW50IGZyb20gdGhlIG1hbmFnZXJcbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCBjbGllbnRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKTtcbiAgICBpZiAoIWNsaWVudHMpIHJldHVybjtcblxuICAgIGNvbnN0IHJlbWFpbmluZyA9IGNsaWVudHMuZmlsdGVyKGMgPT4ge1xuICAgICAgaWYgKGMuaWQgPT09IGNsaWVudElkKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjLnRpbWVvdXQpO1xuICAgICAgICAvLyBNaXJyb3IgdGhlIHBlci1vcmcgY291bnRlciDigJQgbXVzdCBkZWNyZW1lbnQgaGVyZSwgbm90IGp1c3QgaW4gdGhlXG4gICAgICAgIC8vIGV4cGxpY2l0IGNsb3NlIHBhdGhzLCBzaW5jZSAnY2xvc2UnLydlcnJvcicgZXZlbnQgaGFuZGxlcnMgYXJlIHRoZVxuICAgICAgICAvLyBwcmltYXJ5IGRpc2Nvbm5lY3Qgc2lnbmFsIGluIHByYWN0aWNlLlxuICAgICAgICB0aGlzLmRlY3JlbWVudE9yZ0NvdW50KGMub3JnSWQpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIGlmIChyZW1haW5pbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICBsb2dnZXIuZGVidWcoYEFsbCBjbGllbnRzIGRpc2Nvbm5lY3RlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIHJlbWFpbmluZyk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gYWxsIFNTRSBjbGllbnRzIGZvciBhIHJlcXVlc3RJZFxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gUmVxdWVzdCBJRFxuICAgKiBAcGFyYW0gdHlwZSAtIEV2ZW50IHR5cGVcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBNZXNzYWdlIHN0cmluZ1xuICAgKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YVxuICAgKiBAcmV0dXJucyBOdW1iZXIgb2YgY2xpZW50cyB0aGUgbWVzc2FnZSB3YXMgc2VudCB0b1xuICAgKi9cbiAgc2VuZChyZXF1ZXN0SWQ6IHN0cmluZywgdHlwZTogU1NFRXZlbnRUeXBlLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogbnVtYmVyIHtcbiAgICByZXF1ZXN0SWQgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpOyAvLyB1bmlmeSBwcm9kdWNlci9jb25zdW1lciBrZXkgZm9ybXNcbiAgICBjb25zdCBwYXlsb2FkOiBTU0VQYXlsb2FkID0ge1xuICAgICAgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHR5cGUsXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGF0YSxcbiAgICB9O1xuXG4gICAgLy8gRGVsaXZlciB0byBMT0NBTCBjbGllbnRzIGZpcnN0LCB0aGVuIHJlbGF5IHRoZSBTQU1FIHBheWxvYWQgdG8gb3RoZXIgcG9kc1xuICAgIC8vIHNvIGFuIEV2ZW50U291cmNlIGF0dGFjaGVkIG9uIGEgZGlmZmVyZW50IHJlcGxpY2EgYWxzbyByZWNlaXZlcyBpdC4gVGhlXG4gICAgLy8gcmVsYXkgaXMgZmlyZS1hbmQtZm9yZ2V0IGFuZCBmYWlsLXNhZmU6IG5vIHJlbGF5IC8gUmVkaXMgZG93biDih5IgbG9jYWwtb25seS5cbiAgICBjb25zdCBzZW50Q291bnQgPSB0aGlzLnNlbmRMb2NhbChyZXF1ZXN0SWQsIHBheWxvYWQpO1xuICAgIHRoaXMucHVibGlzaFJlbGF5KHsgb3JpZ2luOiB0aGlzLm5vZGVJZCwga2luZDogJ3NlbmQnLCByZXF1ZXN0SWQsIHBheWxvYWQgfSk7XG4gICAgcmV0dXJuIHNlbnRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZSBhIHByZS1idWlsdCBwYXlsb2FkIHRvIHRoaXMgcG9kJ3MgTE9DQUwgY2xpZW50cyBmb3IgYHJlcXVlc3RJZGAuIFNoYXJlZFxuICAgKiBieSB7QGxpbmsgc2VuZH0gKGxvY2FsIGhhbGYpIGFuZCB0aGUgcmVsYXkgcmUtZW1pdCBwYXRoICh7QGxpbmsgb25SZWxheU1lc3NhZ2V9KSxcbiAgICogc28gYSByZWxheWVkIGZyYW1lIHJldXNlcyB0aGUgcHJvZHVjZXIncyBvcmlnaW5hbCBgdHNgIHJhdGhlciB0aGFuIGEgbmV3IG9uZS5cbiAgICogTmV2ZXIgcmVsYXlzIOKAlCBjYWxsZXJzIGRlY2lkZSB3aGV0aGVyIHRvIHB1Ymxpc2guXG4gICAqL1xuICBwcml2YXRlIHNlbmRMb2NhbChyZXF1ZXN0SWQ6IHN0cmluZywgcGF5bG9hZDogU1NFUGF5bG9hZCk6IG51bWJlciB7XG4gICAgcmVxdWVzdElkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTsgLy8gaWRlbXBvdGVudDsgY292ZXJzIHRoZSByZWxheSByZS1lbWl0IHBhdGhcbiAgICBjb25zdCBjbGllbnRzID0gWy4uLih0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgfHwgW10pXTtcbiAgICBsZXQgc2VudENvdW50ID0gMDtcbiAgICBjb25zdCBzZXJpYWxpemVkID0gYGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkocGF5bG9hZCl9XFxuXFxuYDtcblxuICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIEJhY2twcmVzc3VyZTogc2tpcCBjbGllbnRzIHdob3NlIHdyaXRlIGJ1ZmZlciBpcyBmdWxsXG4gICAgICAgIGlmIChjbGllbnQucmVzLndyaXRhYmxlRW5kZWQpIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FuV3JpdGUgPSBjbGllbnQucmVzLndyaXRlKHNlcmlhbGl6ZWQpO1xuICAgICAgICBpZiAoIWNhbldyaXRlKSB7XG4gICAgICAgICAgY2xpZW50LmJhY2twcmVzc3VyZUNvdW50Kys7XG4gICAgICAgICAgLy8gRGlzY29ubmVjdCBjbGllbnRzIHRoYXQgY29uc2lzdGVudGx5IGNhbid0IGtlZXAgdXAgKDEwIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMpXG4gICAgICAgICAgaWYgKGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCA+PSBDb3JlQ29uc3RhbnRzLlNTRV9CQUNLUFJFU1NVUkVfVEhSRVNIT0xEKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybihgRGlzY29ubmVjdGluZyBzbG93IGNsaWVudCAke2NsaWVudC5pZH0gZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9ICgke2NsaWVudC5iYWNrcHJlc3N1cmVDb3VudH0gYmFja3ByZXNzdXJlIGV2ZW50cylgKTtcbiAgICAgICAgICAgIGluY0NvdW50ZXIoJ3NzZV9iYWNrcHJlc3N1cmVfZGlzY29ubmVjdHNfdG90YWwnLCB7fSk7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICAgICAgICB0cnkgeyBjbGllbnQucmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCA9IDA7IC8vIFJlc2V0IG9uIHN1Y2Nlc3NmdWwgd3JpdGVcbiAgICAgICAgfVxuICAgICAgICBzZW50Q291bnQrKztcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHNlbmQgdG8gY2xpZW50ICR7Y2xpZW50LmlkfTpgLCBlcnJvcik7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VudENvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEJyb2FkY2FzdCBhIG1lc3NhZ2UgdG8gYWxsIGNvbm5lY3RlZCBjbGllbnRzIGFjcm9zcyBhbGwgcmVxdWVzdHNcbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBFdmVudCB0eXBlXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gTWVzc2FnZSBzdHJpbmdcbiAgICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBhZGRpdGlvbmFsIGRhdGFcbiAgICogQHJldHVybnMgVG90YWwgbnVtYmVyIG9mIGNsaWVudHMgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgdG9cbiAgICovXG4gIGJyb2FkY2FzdCh0eXBlOiBTU0VFdmVudFR5cGUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IHVua25vd24pOiBudW1iZXIge1xuICAgIGNvbnN0IHBheWxvYWQ6IFNTRVBheWxvYWQgPSB7XG4gICAgICB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgdHlwZSxcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBkYXRhLFxuICAgIH07XG4gICAgLy8gRGVsaXZlciB0byBsb2NhbCBjbGllbnRzLCB0aGVuIHJlbGF5IGEgc2luZ2xlIGJyb2FkY2FzdCBmcmFtZSBzbyBFVkVSWSBwb2RcbiAgICAvLyByZS1lbWl0cyB0byBBTEwgb2YgaXRzIG93biBjbGllbnRzIOKAlCBhIHBlci1yZXF1ZXN0SWQgcmVsYXkgd291bGQgbWlzc1xuICAgIC8vIHN1YmplY3RzIHRoYXQgb25seSBleGlzdCBvbiBvdGhlciByZXBsaWNhcy5cbiAgICBjb25zdCB0b3RhbFNlbnQgPSB0aGlzLmJyb2FkY2FzdExvY2FsKHBheWxvYWQpO1xuICAgIHRoaXMucHVibGlzaFJlbGF5KHsgb3JpZ2luOiB0aGlzLm5vZGVJZCwga2luZDogJ2Jyb2FkY2FzdCcsIHBheWxvYWQgfSk7XG4gICAgcmV0dXJuIHRvdGFsU2VudDtcbiAgfVxuXG4gIC8qKiBXcml0ZSBhIHByZS1idWlsdCBwYXlsb2FkIHRvIGFsbCBMT0NBTCBjbGllbnRzIGFjcm9zcyBldmVyeSByZXF1ZXN0LiAqL1xuICBwcml2YXRlIGJyb2FkY2FzdExvY2FsKHBheWxvYWQ6IFNTRVBheWxvYWQpOiBudW1iZXIge1xuICAgIGxldCB0b3RhbFNlbnQgPSAwO1xuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdG90YWxTZW50ICs9IHRoaXMuc2VuZExvY2FsKHJlcXVlc3RJZCwgcGF5bG9hZCk7XG4gICAgfVxuICAgIHJldHVybiB0b3RhbFNlbnQ7XG4gIH1cblxuICAvKiogRmlyZS1hbmQtZm9yZ2V0IHJlbGF5IHB1Ymxpc2guIE5vLW9wIChsb2NhbC1vbmx5KSB3aGVuIG5vIHJlbGF5IGlzIHdpcmVkLiAqL1xuICBwcml2YXRlIHB1Ymxpc2hSZWxheShtc2c6IFNTRVJlbGF5TWVzc2FnZSk6IHZvaWQge1xuICAgIHRoaXMucmVsYXk/LnB1Ymxpc2gobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhbGwgY2xpZW50cyBmb3IgYSBzcGVjaWZpYyByZXF1ZXN0XG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBSZXF1ZXN0IElEIHRvIGNsb3NlXG4gICAqIEBwYXJhbSBmaW5hbE1lc3NhZ2UgLSBPcHRpb25hbCBmaW5hbCBtZXNzYWdlIHRvIHNlbmQgYmVmb3JlIGNsb3NpbmdcbiAgICovXG4gIGNsb3NlUmVxdWVzdChyZXF1ZXN0SWQ6IHN0cmluZywgZmluYWxNZXNzYWdlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgcmVxdWVzdElkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTtcbiAgICBjb25zdCBjbGllbnRzID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpO1xuICAgIGlmICghY2xpZW50cykgcmV0dXJuO1xuXG4gICAgaWYgKGZpbmFsTWVzc2FnZSkge1xuICAgICAgdGhpcy5zZW5kKHJlcXVlc3RJZCwgJ0NPTVBMRVRFRCcsIGZpbmFsTWVzc2FnZSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgY2xlYXJUaW1lb3V0KGNsaWVudC50aW1lb3V0KTtcbiAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoY2xpZW50Lm9yZ0lkKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNsaWVudC5yZXMuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdSZXNwb25zZSBhbHJlYWR5IGNsb3NlZCBvbiByZXF1ZXN0IGNsb3NlJywgeyByZXF1ZXN0SWQsIGNsaWVudElkOiBjbGllbnQuaWQsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jbGllbnRzLmRlbGV0ZShyZXF1ZXN0SWQpO1xuICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgICBsb2dnZXIuZGVidWcoYENsb3NlZCBhbGwgY2xpZW50cyBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc3RhdGlzdGljcyBhYm91dCBjdXJyZW50IGNvbm5lY3Rpb25zXG4gICAqL1xuICBnZXRTdGF0cygpOiBTU0VNYW5hZ2VyU3RhdHMge1xuICAgIGxldCB0b3RhbENsaWVudHMgPSAwO1xuICAgIGxldCBvbGRlc3RDb25uZWN0aW9uOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gICAgZm9yIChjb25zdCBjbGllbnRzIG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkge1xuICAgICAgdG90YWxDbGllbnRzICs9IGNsaWVudHMubGVuZ3RoO1xuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgICBjb25zdCBhZ2UgPSBub3cgLSBjbGllbnQuY29ubmVjdGVkQXQ7XG4gICAgICAgIGlmIChvbGRlc3RDb25uZWN0aW9uID09PSBudWxsIHx8IGFnZSA+IG9sZGVzdENvbm5lY3Rpb24pIHtcbiAgICAgICAgICBvbGRlc3RDb25uZWN0aW9uID0gYWdlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsUmVxdWVzdHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgdG90YWxDbGllbnRzLFxuICAgICAgb2xkZXN0Q29ubmVjdGlvbk1zOiBvbGRlc3RDb25uZWN0aW9uLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSByZXF1ZXN0IGhhcyBhbnkgY29ubmVjdGVkIGNsaWVudHNcbiAgICovXG4gIGhhc0NsaWVudHMocmVxdWVzdElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBjbGllbnRzID0gdGhpcy5jbGllbnRzLmdldChTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpKTtcbiAgICByZXR1cm4gY2xpZW50cyAhPT0gdW5kZWZpbmVkICYmIGNsaWVudHMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG51bWJlciBvZiBjbGllbnRzIGZvciBhIHNwZWNpZmljIHJlcXVlc3RcbiAgICovXG4gIGdldENsaWVudENvdW50KHJlcXVlc3RJZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpKT8ubGVuZ3RoID8/IDA7XG4gIH1cblxuICAvKipcbiAgICogTWlkZGxld2FyZSB0byBpbml0aWFsaXplIGEgdGlja2V0LWF1dGhlbnRpY2F0ZWQgU1NFIGNvbm5lY3Rpb24uXG4gICAqXG4gICAqIFRoZSBzdHJlYW0gaXMgTk9UIG9wZW4gdG8gdGhlIHdvcmxkOiB0aGUgY2FsbGVyIG11c3QgZmlyc3QgZXhjaGFuZ2UgaXRzXG4gICAqIEpXVCBmb3IgYSBzaG9ydC1saXZlZCBzaW5nbGUtdXNlIHRpY2tldCAoc2VlIHtAbGluayBjcmVhdGVUaWNrZXR9LCB3aXJlZCB0b1xuICAgKiBgUE9TVCAvbG9ncy90aWNrZXRgKSBhbmQgcGFzcyBpdCBhcyBgP3RpY2tldD08dD5gLiBUaGUgbWlkZGxld2FyZSB2YWxpZGF0ZXNcbiAgICogKyBjb25zdW1lcyB0aGUgdGlja2V0LCBiaW5kcyB0aGUgY29ubmVjdGlvbiB0byB0aGUgdGlja2V0J3Mgb3JnLCBhbmRcbiAgICogZW5mb3JjZXMgdGhlIHBlci1vcmcgY29ubmVjdGlvbiBjYXAuIEEgbWlzc2luZyAvIGludmFsaWQgLyBleHBpcmVkIC9cbiAgICogYWxyZWFkeS11c2VkIHRpY2tldCBpcyByZWplY3RlZCB3aXRoIDQwMSBiZWZvcmUgYW55IFNTRSBoZWFkZXJzIGZsdXNoLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG4gICAqIGBgYFxuICAgKi9cbiAgbWlkZGxld2FyZSgpIHtcbiAgICByZXR1cm4gYXN5bmMgKHJlcTogeyBwYXJhbXM6IHsgcmVxdWVzdElkOiBzdHJpbmcgfTsgcXVlcnk/OiB7IHRpY2tldD86IHVua25vd24gfSB9LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBjb25zdCB7IHJlcXVlc3RJZCB9ID0gcmVxLnBhcmFtcztcblxuICAgICAgaWYgKCFTU0VfUkVRVUVTVF9JRF9SRS50ZXN0KHJlcXVlc3RJZCkpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDApLmVuZCgnSW52YWxpZCByZXF1ZXN0SWQgZm9ybWF0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gVGlja2V0IGF1dGgg4oCUIHJlcXVpcmVkLiBSZXNvbHZlIGA/dGlja2V0PTx0PmAsIHRoZW4gdmFsaWRhdGUgKyBjb25zdW1lXG4gICAgICAvLyBpdCAoc2luZ2xlLXVzZSkgRk9SIFRISVMgU1VCSkVDVC4gQW4gYW5vbnltb3VzLCBtYWxmb3JtZWQsIHVua25vd24sXG4gICAgICAvLyBleHBpcmVkLCBhbHJlYWR5LWNvbnN1bWVkLCBvciB3cm9uZy1zdWJqZWN0IHRpY2tldCBpcyBhIDQwMS4gVGhlIG9yZyBpc1xuICAgICAgLy8gdGFrZW4gZnJvbSB0aGUgdGlja2V0LCBzbyB0aGUgc3RyZWFtIGlzIGFsd2F5cyBib3VuZCB0byBhIHZlcmlmaWVkXG4gICAgICAvLyB0ZW5hbnQgQU5EIHRvIHRoZSBleGFjdCBzdWJqZWN0IHRoZSB0aWNrZXQgd2FzIG1pbnRlZCBmb3IgKG5vIGFub255bW91c1xuICAgICAgLy8gc3RyZWFtcywgbm8gY3Jvc3Mtc3ViamVjdCBhdHRhY2gpLlxuICAgICAgY29uc3QgdGlja2V0SWQgPSByZXEucXVlcnk/LnRpY2tldDtcbiAgICAgIGlmICh0eXBlb2YgdGlja2V0SWQgIT09ICdzdHJpbmcnIHx8IHRpY2tldElkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMSkuZW5kKCdNaXNzaW5nIHRpY2tldCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBjb25zdW1lZCA9IGF3YWl0IHRoaXMuY29uc3VtZVRpY2tldCh0aWNrZXRJZCwgcmVxdWVzdElkKTtcbiAgICAgIGlmICghY29uc3VtZWQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDEpLmVuZCgnSW52YWxpZCBvciBleHBpcmVkIHRpY2tldCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBvcmdJZCA9IGNvbnN1bWVkLm9yZ0lkO1xuXG4gICAgICAvLyBQcmUtZmxpZ2h0IHBlci1yZXF1ZXN0IGNhcCBzbyB3ZSBjYW4gcmV0dXJuIDQyOSBiZWZvcmUgZmx1c2hpbmdcbiAgICAgIC8vIFNTRSBoZWFkZXJzIChhZnRlciBoZWFkZXJzIGFyZSBmbHVzaGVkIHRoZSBjbGllbnQgY2FuJ3QgcmVhZCBhIDQyOSkuXG4gICAgICAvL1xuICAgICAgLy8gTk9STUFMSVpFIGZpcnN0OiBgYWRkQ2xpZW50YCBrZXlzIHRoZSBtYXAgb24gdGhlIG5vcm1hbGl6ZWQgZm9ybVxuICAgICAgLy8gKGRhc2hlcyBzdHJpcHBlZCksIHNvIHJlYWRpbmcgdGhlIHJhdyBgcmVxdWVzdElkYCBoZXJlIGFsd2F5cyBmb3VuZCAwXG4gICAgICAvLyBmb3IgYSBjbGllbnQgdXNpbmcgdGhlIGRhc2hlZCBmb3JtLiBUaGUgY2FwIHdhcyB0aGVuIG9ubHkgY2F1Z2h0IGluc2lkZVxuICAgICAgLy8gYGFkZENsaWVudGAg4oCUIEFGVEVSIGBmbHVzaEhlYWRlcnMoKWAg4oCUIHdoaWNoIGlzIGV4YWN0bHkgdGhlIGNhc2UgdGhpc1xuICAgICAgLy8gcHJlLWZsaWdodCBleGlzdHMgdG8gYXZvaWQ6IHRoZSBjbGllbnQgZ290IGEgc2lsZW50bHktY2xvc2VkIHN0cmVhbVxuICAgICAgLy8gaW5zdGVhZCBvZiBhIDQyOS5cbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5jbGllbnRzLmdldChTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpKSB8fCBbXTtcbiAgICAgIGlmIChleGlzdGluZy5sZW5ndGggPj0gdGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdCkge1xuICAgICAgICBsb2dnZXIud2FybihgQ2xpZW50IGxpbWl0IHJlYWNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdH0pYCk7XG4gICAgICAgIHJlcy5zdGF0dXMoNDI5KS5lbmQoJ1RvbyBtYW55IGNvbm5lY3Rpb25zIGZvciB0aGlzIHJlcXVlc3QnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTYW1lIGZvciB0aGUgcGVyLW9yZyBjYXAg4oCUIGJldHRlciB0byBzZW5kIDQyOSB0aGFuIG9wZW4gdGhlIHN0cmVhbSBhbmRcbiAgICAgIC8vIGltbWVkaWF0ZWx5IGNsb3NlIGl0LiBUaGUgdGlja2V0IGd1YXJhbnRlZXMgYSB2ZXJpZmllZCBvcmcgaWQsIHNvIHRoZVxuICAgICAgLy8gcGVyLW9yZyBjZWlsaW5nIGlzIGFsd2F5cyBlbmZvcmNlZCBmb3IgdGhlIC9sb2dzIHN0cmVhbS5cbiAgICAgIGlmICgodGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwKSA+PSB0aGlzLm1heENsaWVudHNQZXJPcmcpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJPcmd9KWApO1xuICAgICAgICByZXMuc3RhdHVzKDQyOSkuZW5kKCdUb28gbWFueSBTU0UgY29ubmVjdGlvbnMgZm9yIHRoaXMgb3JnYW5pemF0aW9uJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgd3JpdGVTc2VIZWFkZXJzKHJlcyk7XG4gICAgICByZXMuZmx1c2hIZWFkZXJzKCk7XG5cbiAgICAgIC8vIEhlYWRlcnMgYXJlIGZsdXNoZWQg4oCUIHdlIGNhbiBubyBsb25nZXIgc2VuZCBhIDQyOS4gYWRkQ2xpZW50IHJlLWNoZWNrc1xuICAgICAgLy8gdGhlIGNhcHMgKGluY2x1ZGluZyB0aGUgcHJvY2Vzcy13aWRlIHRvdGFsLWNsaWVudHMgY2FwLCB3aGljaCB0aGVcbiAgICAgIC8vIHByZS1mbGlnaHQgYWJvdmUgZG9lcyBub3QpIGFuZCBjYW4gc3RpbGwgcmVqZWN0IG9uIGEgcmFjZTogYSBjb25jdXJyZW50XG4gICAgICAvLyBjb25uZWN0aW9uIG1heSBoYXZlIGZpbGxlZCBhIGNhcCBiZXR3ZWVuIHRoZSBwcmUtZmxpZ2h0IGNoZWNrIGFuZCBoZXJlLlxuICAgICAgLy8gT24gcmVqZWN0aW9uLCBjbG9zZSB0aGUgbm93LWRhbmdsaW5nIHJlc3BvbnNlIGluc3RlYWQgb2YgbGVhdmluZyBhblxuICAgICAgLy8gb3BlbiBzb2NrZXQgd2l0aCBubyBjbGllbnQgcmVjb3JkICh3aGljaCB3b3VsZCBsZWFrIGFuIGZkICsgbmV2ZXIgZW1pdFxuICAgICAgLy8gc3RyZWFtIGRhdGEpLlxuICAgICAgY29uc3QgYWRkZWQgPSB0aGlzLmFkZENsaWVudChyZXF1ZXN0SWQsIHJlcywgb3JnSWQpO1xuICAgICAgaWYgKCFhZGRlZCkge1xuICAgICAgICBsb2dnZXIud2FybihgU1NFIGFkZENsaWVudCByZWplY3RlZCBhZnRlciBoZWFkZXJzIGZsdXNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9OyBjbG9zaW5nIGRhbmdsaW5nIHJlc3BvbnNlYCk7XG4gICAgICAgIHRyeSB7IHJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHBlcmlvZGljIGNsZWFudXAgb2Ygc3RhbGUgY29ubmVjdGlvbnNcbiAgICovXG4gIHByaXZhdGUgc3RhcnRDbGVhbnVwSW50ZXJ2YWwoaW50ZXJ2YWxNczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICB9LCBpbnRlcnZhbE1zKTtcblxuICAgIC8vIERvbid0IHByZXZlbnQgcHJvY2VzcyBleGl0XG4gICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwudW5yZWYoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBzdGFsZSBjb25uZWN0aW9ucyB1c2luZyBzaW5nbGUtcGFzcyBwYXJ0aXRpb24uXG4gICAqIE8oUiDDlyBDKSBpbnN0ZWFkIG9mIE8oUiDDlyBDwrIpLCBhbmQgYXZvaWRzIG11dGF0aW9uLWR1cmluZy1pdGVyYXRpb24uXG4gICAqL1xuICBwcml2YXRlIGNsZWFudXAoKTogdm9pZCB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgY2xlYW5lZCA9IDA7XG5cbiAgICAvLyBTd2VlcCBleHBpcmVkIHRpY2tldHMvb3duZXJzIHNvIGFuIGluLW1lbW9yeSBzdG9yZSBzdGF5cyBib3VuZGVkIGV2ZW4gd2hlblxuICAgIC8vIHRpY2tldHMgYXJlIG1pbnRlZCBidXQgbmV2ZXIgY29uc3VtZWQgKGNsaWVudCBjbG9zZWQgdGhlIHRhYiBiZWZvcmVcbiAgICAvLyBjb25uZWN0aW5nKS4gQ29uc3VtZS10aW1lIHN0aWxsIHJlLWNoZWNrcyBleHBpcnksIHNvIHRoaXMgaXMgbWVtb3J5XG4gICAgLy8gaHlnaWVuZSBvbmx5OyB0aGUgUmVkaXMgc3RvcmUgcmVsaWVzIG9uIG5hdGl2ZSBrZXkgVFRMIChzd2VlcCBpcyBhIG5vLW9wKS5cbiAgICB2b2lkIHRoaXMudGlja2V0U3RvcmUuc3dlZXA/LigpO1xuXG4gICAgZm9yIChjb25zdCBbcmVxdWVzdElkLCBjbGllbnRzXSBvZiB0aGlzLmNsaWVudHMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCBzdGFsZTogU1NFQ2xpZW50W10gPSBbXTtcbiAgICAgIGNvbnN0IGFjdGl2ZTogU1NFQ2xpZW50W10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgICAvLyBUaW1lLWJhc2VkIGV2aWN0aW9uIE9SIGEgc29ja2V0IHRoYXQgc2lsZW50bHkgY2xvc2VkIChubyAnY2xvc2UnXG4gICAgICAgIC8vIGV2ZW50KSDigJQgTm9kZSBzb21ldGltZXMgZHJvcHMgc29ja2V0cyB3aXRob3V0IGZpcmluZyB0aGUgZXZlbnQsXG4gICAgICAgIC8vIHNvIHdlIGV4cGxpY2l0bHkgY2hlY2sgd3JpdGFibGVFbmRlZC9kZXN0cm95ZWQgaGVyZS5cbiAgICAgICAgY29uc3QgYWdlU3RhbGUgPSBub3cgLSBjbGllbnQuY29ubmVjdGVkQXQgPiB0aGlzLmNsaWVudFRpbWVvdXRNcztcbiAgICAgICAgY29uc3Qgc29ja2V0RGVhZCA9IGNsaWVudC5yZXMud3JpdGFibGVFbmRlZCB8fCAoY2xpZW50LnJlcyBhcyB7IGRlc3Ryb3llZD86IGJvb2xlYW4gfSkuZGVzdHJveWVkID09PSB0cnVlO1xuICAgICAgICBpZiAoYWdlU3RhbGUgfHwgc29ja2V0RGVhZCkge1xuICAgICAgICAgIHN0YWxlLnB1c2goY2xpZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY3RpdmUucHVzaChjbGllbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIHN0YWxlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjbGllbnQudGltZW91dCk7XG4gICAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoY2xpZW50Lm9yZ0lkKTtcbiAgICAgICAgdHJ5IHsgY2xpZW50LnJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgICAgY2xlYW5lZCsrO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aXZlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YWxlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIGFjdGl2ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNsZWFuZWQgPiAwKSB7XG4gICAgICBpbmNDb3VudGVyKCdzc2Vfc3RhbGVfY2xlYW5lZF90b3RhbCcsIHt9LCBjbGVhbmVkKTtcbiAgICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgICAgIGxvZ2dlci5pbmZvKGBDbGVhbmVkIHVwICR7Y2xlYW5lZH0gc3RhbGUgU1NFIGNvbm5lY3Rpb25zYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNodXRkb3duIHRoZSBTU0UgbWFuYWdlciBhbmQgY2xvc2UgYWxsIGNvbm5lY3Rpb25zXG4gICAqL1xuICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jbGVhbnVwSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdGhpcy5jbG9zZVJlcXVlc3QocmVxdWVzdElkLCAnU2VydmVyIHNodXR0aW5nIGRvd24nKTtcbiAgICB9XG5cbiAgICAvLyBUZWFyIGRvd24gdGhlIHJlbGF5J3MgUmVkaXMgY29ubmVjdGlvbnMgKGJlc3QtZWZmb3J0OyBuZXZlciB0aHJvd3MpLlxuICAgIHZvaWQgdGhpcy5yZWxheT8uY2xvc2UoKS5jYXRjaCgoKSA9PiB7IC8qIGFscmVhZHkgY2xvc2luZyAqLyB9KTtcblxuICAgIGxvZ2dlci5pbmZvKCdTU0UgTWFuYWdlciBzaHV0IGRvd24nKTtcbiAgfVxufVxuIl19
|
|
719
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsMEJBQTBCLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUF1QixNQUFNLDRCQUE0QixDQUFDO0FBQy9JLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVoRSxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVsQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQTBHM0M7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLHFFQUFxRSxDQUFDO0FBZ0J2Rzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQUNiLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztJQUNqRDs7MkNBRXVDO0lBQy9CLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUNwRCx5RkFBeUY7SUFDakYsbUJBQW1CLENBQWtCO0lBQzdDLDRFQUE0RTtJQUNwRSxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBQ2Ysb0JBQW9CLENBQVM7SUFDN0IsZUFBZSxDQUFTO0lBQ3hCLGdCQUFnQixDQUFTO0lBQ3pCLGVBQWUsQ0FBUztJQUN4QixnQkFBZ0IsQ0FBUztJQUN6QixXQUFXLENBQVM7SUFDcEIsZ0JBQWdCLENBQVM7SUFDekIsZUFBZSxDQUFTO0lBQ2pDLGVBQWUsR0FBMEIsSUFBSSxDQUFDO0lBQ3RELCtEQUErRDtJQUN2RCxLQUFLLENBQVk7SUFDUixZQUFZLENBQXlCO0lBQ3RELHVGQUF1RjtJQUM5RSxnQkFBZ0IsQ0FBVTtJQUNuQyxrRkFBa0Y7SUFDakUsTUFBTSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFekQsWUFBWSxPQUFPLEdBQXNCLEVBQUU7UUFDekMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsSUFBSSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDMUgsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM1RyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM5RyxJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxlQUFlLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLElBQUksTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVHLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLElBQUksSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzlHLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSxpQkFBaUIsQ0FBQztRQUM1RCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVM7UUFDN0gsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFDL0MsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDO1FBQ25ELElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsSUFBSSxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhO1FBRTdILE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVk7UUFDbEksSUFBSSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFN0MsNkVBQTZFO1FBQzdFLHNFQUFzRTtRQUN0RSw4RUFBOEU7UUFDOUUsK0VBQStFO1FBQy9FLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztRQUN6QyxJQUFJLE9BQU8sQ0FBQyxLQUFLO1lBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVPLFdBQVcsQ0FBQyxLQUFlO1FBQ2pDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWTtZQUFFLE9BQU87UUFDN0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xDLElBQUksS0FBSztZQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELHFFQUFxRTtJQUNyRSxJQUFZLFdBQVc7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxtQkFBbUIsR0FBRywwQkFBMEIsQ0FBQztnQkFDcEQsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUN2QixRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWU7Z0JBQzlCLFNBQVMsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO2FBQ2pDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1FBQzlCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxjQUFjLENBQUMsR0FBb0I7UUFDekMsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUMvQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbkMsQ0FBQzthQUFNLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0MsQ0FBQztJQUNILENBQUM7SUFFRCxrREFBa0Q7SUFDMUMsWUFBWTtRQUNsQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDVixLQUFLLE1BQU0sT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO1lBQUUsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDakUsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxpQkFBaUI7UUFDdkIsUUFBUSxDQUFDLHdCQUF3QixFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsMERBQTBEO0lBQzFELGlCQUFpQixDQUFDLEtBQWE7UUFDN0IsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQWlCO1FBQ2pELE9BQU8sU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQWE7UUFDekMsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FBQyxTQUFpQixFQUFFLEtBQWE7UUFDcEQsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FDOUIsVUFBVSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUN4QyxVQUFVLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxFQUNoQyxJQUFJLENBQUMsZ0JBQWdCLENBQ3RCLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BdUJHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFhLEVBQUUsU0FBaUI7UUFDakQsdUVBQXVFO1FBQ3ZFLDBFQUEwRTtRQUMxRSxxRUFBcUU7UUFDckUsc0VBQXNFO1FBQ3RFLE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM1RCxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZELElBQUksS0FBb0IsQ0FBQztRQUN6QixJQUFJLENBQUM7WUFDSCxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLHVFQUF1RTtZQUN2RSxNQUFNLENBQUMsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDL0gsVUFBVSxDQUFDLDJCQUEyQixFQUFFLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDaEUsT0FBTyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLEtBQUssSUFBSSxLQUFLLEtBQUssYUFBYSxFQUFFLENBQUM7WUFDckMsTUFBTSxDQUFDLElBQUksQ0FBQywyQkFBMkIsYUFBYSw4QkFBOEIsQ0FBQyxDQUFDO1lBQ3BGLFVBQVUsQ0FBQywyQkFBMkIsRUFBRSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQ2pFLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUM1QyxDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNmLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztZQUNsRSxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixNQUFNLFNBQVMsYUFBYSxFQUFFLENBQUMsQ0FBQztZQUNuRSxVQUFVLENBQUMsMkJBQTJCLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3BELE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQy9CLENBQUM7UUFDRCxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FpQkc7SUFDSCxLQUFLLENBQUMsYUFBYSxDQUFDLFFBQWdCLEVBQUUsU0FBaUI7UUFDckQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLGFBQWE7UUFDdEUsSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPLElBQUksQ0FBQztRQUN6Qix1RUFBdUU7UUFDdkUsd0VBQXdFO1FBQ3hFLDZDQUE2QztRQUM3QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssVUFBVSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzdFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILFNBQVMsQ0FBQyxTQUFpQixFQUFFLEdBQWEsRUFBRSxLQUFjLEVBQUUsb0JBQW9CLEdBQVcsSUFBSSxDQUFDLG9CQUFvQjtRQUNsSCx3RUFBd0U7UUFDeEUsK0VBQStFO1FBQy9FLCtFQUErRTtRQUMvRSw2RUFBNkU7UUFDN0UsbUZBQW1GO1FBQ25GLFNBQVMsR0FBRyxVQUFVLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRW5ELHFCQUFxQjtRQUNyQixJQUFJLFFBQVEsQ0FBQyxNQUFNLElBQUksb0JBQW9CLEVBQUUsQ0FBQztZQUM1QyxNQUFNLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxTQUFTLFVBQVUsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO1lBQzVGLFVBQVUsQ0FBQywrQkFBK0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDO1lBQ3pFLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUVELHdFQUF3RTtRQUN4RSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDaEQsTUFBTSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsSUFBSSxDQUFDLGVBQWUsNkJBQTZCLENBQUMsQ0FBQztZQUNyRyxVQUFVLENBQUMsK0JBQStCLEVBQUUsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUNyRSxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxxRUFBcUU7UUFDckUsMEVBQTBFO1FBQzFFLHVFQUF1RTtRQUN2RSxxRUFBcUU7UUFDckUsNENBQTRDO1FBQzVDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEQsSUFBSSxVQUFVLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0NBQXNDLEtBQUssVUFBVSxJQUFJLENBQUMsZ0JBQWdCLDZCQUE2QixDQUFDLENBQUM7Z0JBQ3JILFVBQVUsQ0FBQywrQkFBK0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7WUFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFFRCxpQ0FBaUM7UUFDakMsTUFBTSxRQUFRLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDeEIsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsUUFBUSwwQkFBMEIsU0FBUyxFQUFFLENBQUMsQ0FBQztZQUN0RSxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUM7Z0JBQ0gsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1osQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdkksQ0FBQztRQUNILENBQUMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFekIsTUFBTSxNQUFNLEdBQWM7WUFDeEIsRUFBRSxFQUFFLFFBQVE7WUFDWixHQUFHO1lBQ0gsV0FBVyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDdkIsT0FBTztZQUNQLGlCQUFpQixFQUFFLENBQUM7WUFDcEIsS0FBSztTQUNOLENBQUM7UUFFRix1QkFBdUI7UUFDdkIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO1lBQ25CLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztRQUVILEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDdEIsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsU0FBUyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdEMsVUFBVSxDQUFDLHVCQUF1QixFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRXpCLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxRQUFRLDBCQUEwQixTQUFTLFlBQVksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDbEcsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFlBQVksQ0FBQyxLQUFhLEVBQUUsR0FBYTtRQUN2QyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVEO21EQUMrQztJQUN2QyxpQkFBaUIsQ0FBQyxLQUFjO1FBQ3RDLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUNuQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckQsSUFBSSxPQUFPLElBQUksQ0FBQztZQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDOztZQUNoRCxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRDs7T0FFRztJQUNLLFlBQVksQ0FBQyxTQUFpQixFQUFFLFFBQWdCO1FBQ3RELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUVyQixNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ25DLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDdEIsWUFBWSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDeEIsb0VBQW9FO2dCQUNwRSxxRUFBcUU7Z0JBQ3JFLHlDQUF5QztnQkFDekMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDaEMsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMvQixNQUFNLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFDRCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxJQUFJLENBQUMsU0FBaUIsRUFBRSxJQUFrQixFQUFFLE9BQWUsRUFBRSxJQUFjO1FBQ3pFLFNBQVMsR0FBRyxVQUFVLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxvQ0FBb0M7UUFDMUYsTUFBTSxPQUFPLEdBQWU7WUFDMUIsRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO1lBQzVCLElBQUk7WUFDSixPQUFPO1lBQ1AsSUFBSTtTQUNMLENBQUM7UUFFRiw0RUFBNEU7UUFDNUUsMEVBQTBFO1FBQzFFLDhFQUE4RTtRQUM5RSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM3RSxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxTQUFTLENBQUMsU0FBaUIsRUFBRSxPQUFtQjtRQUN0RCxTQUFTLEdBQUcsVUFBVSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsNENBQTRDO1FBQ2xHLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekQsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLE1BQU0sVUFBVSxHQUFHLFNBQVMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBRTFELEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDO2dCQUNILHdEQUF3RDtnQkFDeEQsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO29CQUM3QixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3hDLFNBQVM7Z0JBQ1gsQ0FBQztnQkFDRCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDOUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUNkLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO29CQUMzQiwwRkFBMEY7b0JBQzFGLElBQUksTUFBTSxDQUFDLGlCQUFpQixJQUFJLGFBQWEsQ0FBQywwQkFBMEIsRUFBRSxDQUFDO3dCQUN6RSxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixNQUFNLENBQUMsRUFBRSxnQkFBZ0IsU0FBUyxLQUFLLE1BQU0sQ0FBQyxpQkFBaUIsdUJBQXVCLENBQUMsQ0FBQzt3QkFDakksVUFBVSxDQUFDLG9DQUFvQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO3dCQUNyRCxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQ3hDLElBQUksQ0FBQzs0QkFBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUFDLENBQUM7d0JBQUMsTUFBTSxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQzt3QkFDeEQsU0FBUztvQkFDWCxDQUFDO2dCQUNILENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDLENBQUMsNEJBQTRCO2dCQUM1RCxDQUFDO2dCQUNELFNBQVMsRUFBRSxDQUFDO1lBQ2QsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUM5RCxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDMUMsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILFNBQVMsQ0FBQyxJQUFrQixFQUFFLE9BQWUsRUFBRSxJQUFjO1FBQzNELE1BQU0sT0FBTyxHQUFlO1lBQzFCLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUM1QixJQUFJO1lBQ0osT0FBTztZQUNQLElBQUk7U0FDTCxDQUFDO1FBQ0YsNkVBQTZFO1FBQzdFLHdFQUF3RTtRQUN4RSw4Q0FBOEM7UUFDOUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZFLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCwyRUFBMkU7SUFDbkUsY0FBYyxDQUFDLE9BQW1CO1FBQ3hDLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNsQixLQUFLLE1BQU0sU0FBUyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNqRCxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxnRkFBZ0Y7SUFDeEUsWUFBWSxDQUFDLEdBQW9CO1FBQ3ZDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFlBQVksQ0FBQyxTQUFpQixFQUFFLFlBQXFCO1FBQ25ELFNBQVMsR0FBRyxVQUFVLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQztZQUFFLE9BQU87UUFFekMsNkVBQTZFO1FBQzdFLDBFQUEwRTtRQUMxRSxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUN4RyxDQUFDO1FBRUQsMEVBQTBFO1FBQzFFLHlFQUF5RTtRQUN6RSwyQ0FBMkM7UUFDM0MsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUN2RCxZQUFZLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDO2dCQUNILE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDbkIsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQywwQ0FBMEMsRUFBRSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4SixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNOLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztRQUNyQixJQUFJLGdCQUFnQixHQUFrQixJQUFJLENBQUM7UUFDM0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRXZCLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1lBQzVDLFlBQVksSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQy9CLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO2dCQUNyQyxJQUFJLGdCQUFnQixLQUFLLElBQUksSUFBSSxHQUFHLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQztvQkFDeEQsZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO2dCQUN6QixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPO1lBQ0wsYUFBYSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSTtZQUNoQyxZQUFZO1lBQ1osa0JBQWtCLEVBQUUsZ0JBQWdCO1NBQ3JDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVLENBQUMsU0FBaUI7UUFDMUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDM0UsT0FBTyxPQUFPLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRDs7T0FFRztJQUNILGNBQWMsQ0FBQyxTQUFpQjtRQUM5QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUM7SUFDakYsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0gsVUFBVTtRQUNSLE9BQU8sS0FBSyxFQUFFLEdBQW9FLEVBQUUsR0FBYSxFQUFFLEVBQUU7WUFDbkcsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFFakMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUN2QyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO2dCQUNoRCxPQUFPO1lBQ1QsQ0FBQztZQUVELHlFQUF5RTtZQUN6RSxzRUFBc0U7WUFDdEUsMEVBQTBFO1lBQzFFLHFFQUFxRTtZQUNyRSwwRUFBMEU7WUFDMUUscUNBQXFDO1lBQ3JDLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDO1lBQ25DLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQzFELEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ3RDLE9BQU87WUFDVCxDQUFDO1lBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUMsQ0FBQztnQkFDakQsT0FBTztZQUNULENBQUM7WUFDRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBRTdCLGtFQUFrRTtZQUNsRSx1RUFBdUU7WUFDdkUsRUFBRTtZQUNGLG1FQUFtRTtZQUNuRSx3RUFBd0U7WUFDeEUsMEVBQTBFO1lBQzFFLHdFQUF3RTtZQUN4RSxzRUFBc0U7WUFDdEUsb0JBQW9CO1lBQ3BCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsRixJQUFJLFFBQVEsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7Z0JBQ2pELE1BQU0sQ0FBQyxJQUFJLENBQUMsb0NBQW9DLFNBQVMsVUFBVSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO2dCQUNqRyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO2dCQUM3RCxPQUFPO1lBQ1QsQ0FBQztZQUVELHlFQUF5RTtZQUN6RSx3RUFBd0U7WUFDeEUsMkRBQTJEO1lBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztnQkFDcEUsTUFBTSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsS0FBSyxVQUFVLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7Z0JBQzNGLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7Z0JBQ3RFLE9BQU87WUFDVCxDQUFDO1lBRUQsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUVuQix5RUFBeUU7WUFDekUsb0VBQW9FO1lBQ3BFLDBFQUEwRTtZQUMxRSwwRUFBMEU7WUFDMUUsc0VBQXNFO1lBQ3RFLHlFQUF5RTtZQUN6RSxnQkFBZ0I7WUFDaEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxNQUFNLENBQUMsSUFBSSxDQUFDLDREQUE0RCxTQUFTLDZCQUE2QixDQUFDLENBQUM7Z0JBQ2hILElBQUksQ0FBQztvQkFBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQUMsQ0FBQztnQkFBQyxNQUFNLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ25ELENBQUM7UUFDSCxDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyxvQkFBb0IsQ0FBQyxVQUFrQjtRQUM3QyxJQUFJLENBQUMsZUFBZSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7WUFDdEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUVmLDZCQUE2QjtRQUM3QixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRDs7O09BR0c7SUFDSyxPQUFPO1FBQ2IsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztRQUVoQixLQUFLLE1BQU0sQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQzFELE1BQU0sS0FBSyxHQUFnQixFQUFFLENBQUM7WUFDOUIsTUFBTSxNQUFNLEdBQWdCLEVBQUUsQ0FBQztZQUUvQixLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUM3QixtRUFBbUU7Z0JBQ25FLGtFQUFrRTtnQkFDbEUsdURBQXVEO2dCQUN2RCxNQUFNLFFBQVEsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUNqRSxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsSUFBSyxNQUFNLENBQUMsR0FBK0IsQ0FBQyxTQUFTLEtBQUssSUFBSSxDQUFDO2dCQUMxRyxJQUFJLFFBQVEsSUFBSSxVQUFVLEVBQUUsQ0FBQztvQkFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDckIsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3RCLENBQUM7WUFDSCxDQUFDO1lBRUQsS0FBSyxNQUFNLE1BQU0sSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDM0IsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDckMsSUFBSSxDQUFDO29CQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQUMsQ0FBQztnQkFBQyxNQUFNLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO2dCQUN4RCxPQUFPLEVBQUUsQ0FBQztZQUNaLENBQUM7WUFFRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2pDLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdEMsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNoQixVQUFVLENBQUMseUJBQXlCLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ25ELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxPQUFPLHdCQUF3QixDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN6QixhQUFhLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1FBQzlCLENBQUM7UUFFRCxLQUFLLE1BQU0sU0FBUyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNqRCxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCx1RUFBdUU7UUFDdkUsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBeUIsQ0FBQyxDQUFDLENBQUM7UUFDaEUsSUFBSSxJQUFJLENBQUMsZUFBZTtZQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUUzRCxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDdkMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBjcmVhdGVNZW1vcnlTc2VUaWNrZXRTdG9yZSwgU1NFX1RJQ0tFVF9UVExfTVMsIHdyaXRlU3NlSGVhZGVycywgdHlwZSBTc2VUaWNrZXRTdG9yZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IENvcmVDb25zdGFudHMgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1jb3JlJztcbmltcG9ydCB0eXBlIHsgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IHY3IGFzIHV1aWQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB0eXBlIHsgU1NFUmVsYXksIFNTRVJlbGF5TWVzc2FnZSB9IGZyb20gJy4vc3NlLXJlbGF5LmpzJztcbmltcG9ydCB7IGluY0NvdW50ZXIsIHNldEdhdWdlIH0gZnJvbSAnLi4vYXBpL21ldHJpY3MuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS1tYW5hZ2VyJyk7XG5cbi8qKlxuICogRXZlbnQgdHlwZXMgZm9yIFNTRSBsb2dnaW5nXG4gKi9cbmV4cG9ydCB0eXBlIFNTRUV2ZW50VHlwZSA9ICdJTkZPJyB8ICdXQVJOJyB8ICdFUlJPUicgfCAnQ09NUExFVEVEJyB8ICdST0xMQkFDSycgfCAnTUVTU0FHRSc7XG5cbi8qKlxuICogU1NFIHBheWxvYWQgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFUGF5bG9hZCB7XG4gIHRzOiBzdHJpbmc7XG4gIHR5cGU6IFNTRUV2ZW50VHlwZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkYXRhPzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBTU0UgY2xpZW50IHdpdGggY29ubmVjdGlvbiB0cmFja2luZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRUNsaWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIHJlczogUmVzcG9uc2U7XG4gIGNvbm5lY3RlZEF0OiBudW1iZXI7XG4gIHRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMgKHdyaXRlIHJldHVybmVkIGZhbHNlKS4gKi9cbiAgYmFja3ByZXNzdXJlQ291bnQ6IG51bWJlcjtcbiAgLyoqIE93bmluZyBvcmcgaWQg4oCUIHBvcHVsYXRlZCB3aGVuIHRoZSByZXF1ZXN0IHdhcyBhdXRoZW50aWNhdGVkLiBVc2VkIHRvXG4gICAqICBkZWNyZW1lbnQgdGhlIHBlci1vcmcgY291bnRlciBvbiBkaXNjb25uZWN0IC8gY2xlYW51cC4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU1NFIE1hbmFnZXIgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlck9wdGlvbnMge1xuICAvKiogTWF4aW11bSBjbGllbnRzIGFsbG93ZWQgcGVyIHJlcXVlc3QgSUQgKGRlZmF1bHQ6IDEwKSAqL1xuICBtYXhDbGllbnRzUGVyUmVxdWVzdD86IG51bWJlcjtcbiAgLyoqIENsaWVudCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMzAgbWludXRlcykgKi9cbiAgY2xpZW50VGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogSW50ZXJ2YWwgZm9yIGNsZWFudXAgY2hlY2tzIGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogNSBtaW51dGVzKSAqL1xuICBjbGVhbnVwSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEhhcmQgY2FwIG9uIHRvdGFsIG9wZW4gY29ubmVjdGlvbnMgcGVyIHByb2Nlc3MuIERlZmF1bHRzIHRvIDEwMDAgZnJvbVxuICAgKiBgU1NFX01BWF9UT1RBTF9DTElFTlRTYC4gTmV3IGNvbm5lY3Rpb25zIGJleW9uZCB0aGlzIGFyZSByZWplY3RlZCBhdFxuICAgKiBgYWRkQ2xpZW50KClgLiBUdW5lIHVwIGlmIHlvdXIgc2VydmljZSBzZXJ2ZXMgPiAxMDAwIGNvbmN1cnJlbnQgU1NFXG4gICAqIGRhc2hib2FyZHMsIGJ1dCBiZSBhd2FyZSBOb2RlLmpzIGZkIGxpbWl0cyBkb21pbmF0ZSBhYm92ZSB+NTAwMC5cbiAgICovXG4gIG1heFRvdGFsQ2xpZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2VpbGluZyBvbiBjb25jdXJyZW50IFNTRSBzdHJlYW1zLiBEZWZhdWx0cyB0byA1MCBmcm9tXG4gICAqIGBTU0VfTUFYX0NMSUVOVFNfUEVSX09SR2AuIFByb3RlY3RzIGFnYWluc3Qgb25lIG5vaXN5IG9yZyBjb25zdW1pbmcgdGhlXG4gICAqIHByb2Nlc3Mtd2lkZSBidWRnZXQg4oCUIHdpdGhvdXQgaXQsIGFuIGF1dGhlbnRpY2F0ZWQgdXNlciBjYW4gZmFuIG91dFxuICAgKiB0aG91c2FuZHMgb2Ygc3RyZWFtcyAob25lIHBlciBkYXNoYm9hcmQgLyBsb2cgc3RyZWFtKSBhbmQgc3RhcnZlIG90aGVyXG4gICAqIG9yZ3Mgb2YgY29ubmVjdGlvbiBzbG90cy4gVGhlIGNhcCBpcyBlbmZvcmNlZCBvbmx5IG9uIGBhZGRDbGllbnRgIGNhbGxzXG4gICAqIHRoYXQgY2FycnkgYW4gYG9yZ0lkYDsgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91cyBTU0UgdHJhZmZpYyBza2lwcyBpdC5cbiAgICovXG4gIG1heENsaWVudHNQZXJPcmc/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDYXAgb24gbGl2ZSBsb2ctc3RyZWFtIHRpY2tldHMgYWNyb3NzIHRoZSBwcm9jZXNzLCBmb3IgdGhlIERFRkFVTFRcbiAgICogaW4tbWVtb3J5IHRpY2tldCBzdG9yZS4gRGVmYXVsdHMgdG8gMTAwMCBmcm9tIGBTU0VfTUFYX1RPVEFMX1RJQ0tFVFNgLlxuICAgKiBJZ25vcmVkIHdoZW4gYHRpY2tldFN0b3JlYCBpcyBpbmplY3RlZCAodGhlIHN0b3JlIGNhcnJpZXMgaXRzIG93biBjYXBzKS5cbiAgICovXG4gIG1heFRvdGFsVGlja2V0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2FwIG9uIGxpdmUgbG9nLXN0cmVhbSB0aWNrZXRzLCBmb3IgdGhlIERFRkFVTFQgaW4tbWVtb3J5IHRpY2tldFxuICAgKiBzdG9yZS4gRGVmYXVsdHMgdG8gMTAgZnJvbSBgU1NFX01BWF9USUNLRVRTX1BFUl9PUkdgLiBJZ25vcmVkIHdoZW5cbiAgICogYHRpY2tldFN0b3JlYCBpcyBpbmplY3RlZC5cbiAgICovXG4gIG1heFRpY2tldHNQZXJPcmc/OiBudW1iZXI7XG4gIC8qKiBUaWNrZXQgVFRMIGluIG1zIGZvciB0aGUgZGVmYXVsdCBzdG9yZSAoZGVmYXVsdDogYFNTRV9USUNLRVRfVFRMX01TYCBmcm9tIGFwaS1jb3JlKS4gKi9cbiAgdGlja2V0VHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQgZm9yIHRoZSBzdWJqZWN0LWJvdW5kIGxvZyBzdHJlYW0uIERlZmF1bHRzXG4gICAqIHRvIGFuIGluLW1lbW9yeSBzdG9yZSAoc2luZ2xlIHJlcGxpY2Egb25seSksIGJ1aWx0IG9uIGZpcnN0IHVzZS4gSW5qZWN0IGFuXG4gICAqIGFwaS1jb3JlIGBjcmVhdGVFbnZTc2VUaWNrZXRTdG9yZSguLi4pYCBzbyBtaW50L3JlZGVlbSBhbmQgc3RyZWFtIG93bmVyc2hpcFxuICAgKiB3b3JrIGFjcm9zcyBwb2RzLlxuICAgKi9cbiAgdGlja2V0U3RvcmU/OiBTc2VUaWNrZXRTdG9yZTtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBzZXJ2aWNlIHN0cmVhbXMgcGVyLXJlcXVlc3QgbG9ncyAoYGN0eC5sb2dgIGZyYW1lcyBrZXllZCBieVxuICAgKiByZXF1ZXN0SWQsIHRoZSBgL2xvZ3NgIGNoYW5uZWwpLiBEZWZhdWx0IGZhbHNlOiBgY3R4LmxvZ2AgdGhlbiBvbmx5IHdyaXRlc1xuICAgKiB0byB0aGUgbG9nZ2VyLCBzbyBhIHNlcnZpY2UgdGhhdCBuZXZlciBzZXJ2ZXMgYSBsb2cgc3RyZWFtIGRvZXNuJ3QgcHVzaFxuICAgKiBldmVyeSBsb2cgbGluZSB0aHJvdWdoIFNTRSAoYW5kIG92ZXIgUmVkaXMpLlxuICAgKi9cbiAgbG9nU3RyZWFtPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRUTCBmb3IgYSBzdHJlYW0tb3duZXJzaGlwIGJpbmRpbmcgKGRlZmF1bHQ6IGBTU0VfU1RSRUFNX09XTkVSX1RUTF9NU2AgZW52IG9yXG4gICAqIDFoKS4gTG9uZyBlbm91Z2ggdG8gb3V0bGl2ZSBhIGJ1aWxkOyB0aGUgcHJvZHVjZXIgcmUtYmluZHMgYXMgbmVlZGVkLlxuICAgKi9cbiAgc3RyZWFtT3duZXJUdGxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIENyb3NzLXBvZCBmYW4tb3V0IGJ1cyBmb3IgYHNlbmQoKWAvYGJyb2FkY2FzdCgpYCwgd2lyZWQgYXQgY29uc3RydWN0aW9uLlxuICAgKiBXaGVuIG9taXR0ZWQgKGFuZCBubyBgcmVsYXlGYWN0b3J5YCBpcyBlbmFibGVkKSBkZWxpdmVyeSBpcyBMT0NBTC1PTkxZLlxuICAgKiBEZWdyYWRlcyB0byBsb2NhbC1vbmx5IGR1cmluZyBhIFJlZGlzIG91dGFnZS5cbiAgICovXG4gIHJlbGF5PzogU1NFUmVsYXk7XG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHJlbGF5IG9uIGRlbWFuZCDigJQgc2VlIHtAbGluayBTU0VNYW5hZ2VyLmVuYWJsZVJlbGF5fS4gTGV0cyBhXG4gICAqIHNlcnZpY2Ugb3BlbiBhIHJlbGF5IGNvbm5lY3Rpb24gb25seSB3aGVuIGl0IGFjdHVhbGx5IGhhcyBhIHN0cmVhbWluZ1xuICAgKiBjaGFubmVsICh0aGUgbG9nIHN0cmVhbSwgb3IgYW4gb3JnLWtleWVkIGNoYW5uZWwpLiBSZXR1cm5pbmcgbnVsbCAoUmVkaXNcbiAgICogbm90IGNvbmZpZ3VyZWQpIGtlZXBzIGxvY2FsLW9ubHkgZGVsaXZlcnkuXG4gICAqL1xuICByZWxheUZhY3Rvcnk/OiAoKSA9PiBTU0VSZWxheSB8IG51bGw7XG59XG5cbi8qKlxuICogQSBidWlsZC1sb2cgc3RyZWFtIHN1YmplY3QgaWQ6IGVpdGhlciBhIGRhc2hlZCBVVUlEIChhcGktc2VydmVyJ3MgYHV1aWQoKWApXG4gKiBvciBuZ2lueCdzIGAkcmVxdWVzdF9pZGAg4oCUIDE2IHJhbmRvbSBieXRlcyByZW5kZXJlZCBhcyAzMiBoZXggY2hhcnMgd2l0aCBOT1xuICogZGFzaGVzLiBBY2NlcHQgYm90aCBieSBtYWtpbmcgdGhlIGdyb3VwIHNlcGFyYXRvcnMgb3B0aW9uYWw7IHN0aWxsIHN0cmljdGx5XG4gKiAzMiBoZXggY2hhcnMgc28gaXQgY2FuJ3QgY2FycnkgYW4gaW5qZWN0aW9uIC8gcGF0aC10cmF2ZXJzYWwgcGF5bG9hZCBpbnRvIHRoZVxuICogU1NFIHN1YmplY3QuIFNoYXJlZCBieSB0aGUgdGlja2V0LW1pbnQgcm91dGUgYW5kIHRoZSBzdHJlYW0gbWlkZGxld2FyZSBzb1xuICogYm90aCB2YWxpZGF0ZSB0aGUgc3ViamVjdCBpZGVudGljYWxseS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNTRV9SRVFVRVNUX0lEX1JFID0gL15bMC05YS1mXXs4fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17MTJ9JC9pO1xuXG4vKiogUmVzdWx0IG9mIHtAbGluayBTU0VNYW5hZ2VyLmNyZWF0ZVRpY2tldH0uICovXG5leHBvcnQgdHlwZSBDcmVhdGVUaWNrZXRSZXN1bHQgPVxuICB8IHsgb2s6IHRydWU7IHRpY2tldDogc3RyaW5nIH1cbiAgfCB7IG9rOiBmYWxzZTsgcmVhc29uOiAnb3JnLWxpbWl0JyB8ICdjYXBhY2l0eScgfCAnZm9yYmlkZGVuJyB9O1xuXG4vKipcbiAqIFNTRSBNYW5hZ2VyIHN0YXRpc3RpY3NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTU0VNYW5hZ2VyU3RhdHMge1xuICB0b3RhbFJlcXVlc3RzOiBudW1iZXI7XG4gIHRvdGFsQ2xpZW50czogbnVtYmVyO1xuICBvbGRlc3RDb25uZWN0aW9uTXM6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKlxuICogU1NFIGhlbHBlciBjbGFzcyB3aXRoIG1lbW9yeSBsZWFrIHByb3RlY3Rpb25cbiAqXG4gKiBGZWF0dXJlczpcbiAqIC0gQ2xpZW50IGxpbWl0cyBwZXIgcmVxdWVzdCBJRFxuICogLSBBdXRvbWF0aWMgdGltZW91dCBmb3IgaWRsZSBjb25uZWN0aW9uc1xuICogLSBQZXJpb2RpYyBjbGVhbnVwIG9mIHN0YWxlIGNvbm5lY3Rpb25zXG4gKiAtIENvbm5lY3Rpb24gc3RhdGlzdGljc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBzc2VNYW5hZ2VyID0gbmV3IFNTRU1hbmFnZXIoeyBtYXhDbGllbnRzUGVyUmVxdWVzdDogNSB9KTtcbiAqIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG4gKlxuICogLy8gU2VuZCBldmVudHNcbiAqIHNzZU1hbmFnZXIuc2VuZCgncmVxdWVzdC0xMjMnLCAnSU5GTycsICdQcm9jZXNzaW5nLi4uJyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFNTRU1hbmFnZXIge1xuICBwcml2YXRlIGNsaWVudHMgPSBuZXcgTWFwPHN0cmluZywgU1NFQ2xpZW50W10+KCk7XG4gIC8qKiBQZXItb3JnIG9wZW4tY2xpZW50IGNvdW50ZXJzLiBEZWNyZW1lbnRlZCBvbiByZW1vdmVDbGllbnQvY2xlYW51cCBzbyB0aGVcbiAgICogIG1hcCBtaXJyb3JzIGBjbGllbnRzW10ub3JnSWRgIGNvdW50cyBhdCBhbGwgdGltZXMuIE9yZ3MgcmVhY2ggemVybyBhcmVcbiAgICogIGRlbGV0ZWQgdG8ga2VlcCB0aGUgbWFwIGJvdW5kZWQuICovXG4gIHByaXZhdGUgb3JnQ2xpZW50Q291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIEluamVjdGVkIHRpY2tldCArIHN0cmVhbS1vd25lcnNoaXAgYmFja2VuZCwgb3IgdGhlIGxhemlseSBidWlsdCBpbi1tZW1vcnkgZGVmYXVsdC4gKi9cbiAgcHJpdmF0ZSB0aWNrZXRTdG9yZUluc3RhbmNlPzogU3NlVGlja2V0U3RvcmU7XG4gIC8qKiBUcnVlIHdoZW4gdGhpcyBtYW5hZ2VyIGJ1aWx0IGl0cyB0aWNrZXQgc3RvcmUgKHNvIHNodXRkb3duIHN0b3BzIGl0KS4gKi9cbiAgcHJpdmF0ZSBvd25zVGlja2V0U3RvcmUgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyUmVxdWVzdDogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heFRvdGFsQ2xpZW50czogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heENsaWVudHNQZXJPcmc6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbFRpY2tldHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUaWNrZXRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGlja2V0VHRsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBzdHJlYW1Pd25lclR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50VGltZW91dE1zOiBudW1iZXI7XG4gIHByaXZhdGUgY2xlYW51cEludGVydmFsOiBOb2RlSlMuVGltZW91dCB8IG51bGwgPSBudWxsO1xuICAvKiogQ3Jvc3MtcG9kIGZhbi1vdXQgYnVzICh1bmRlZmluZWQg4oeSIGxvY2FsLW9ubHkgZGVsaXZlcnkpLiAqL1xuICBwcml2YXRlIHJlbGF5PzogU1NFUmVsYXk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVsYXlGYWN0b3J5PzogKCkgPT4gU1NFUmVsYXkgfCBudWxsO1xuICAvKiogV2hldGhlciBgY3R4LmxvZ2AgZnJhbWVzIGFyZSBzdHJlYW1lZCAoc2VlIHtAbGluayBTU0VNYW5hZ2VyT3B0aW9ucy5sb2dTdHJlYW19KS4gKi9cbiAgcmVhZG9ubHkgbG9nU3RyZWFtRW5hYmxlZDogYm9vbGVhbjtcbiAgLyoqIFRoaXMgbWFuYWdlciBpbnN0YW5jZSdzIGlkIOKAlCB0YWdzIHJlbGF5ZWQgZnJhbWVzIHNvIHdlIGlnbm9yZSBvdXIgb3duIGVjaG8uICovXG4gIHByaXZhdGUgcmVhZG9ubHkgbm9kZUlkID0gcmFuZG9tQnl0ZXMoOCkudG9TdHJpbmcoJ2hleCcpO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNTRU1hbmFnZXJPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0ID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyUmVxdWVzdCA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX0NMSUVOVFNfUEVSX1JFUVVFU1QgfHwgJzEwJywgMTApO1xuICAgIHRoaXMubWF4VG90YWxDbGllbnRzID0gb3B0aW9ucy5tYXhUb3RhbENsaWVudHMgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX01BWF9UT1RBTF9DTElFTlRTIHx8ICcxMDAwJywgMTApO1xuICAgIHRoaXMubWF4Q2xpZW50c1Blck9yZyA9IG9wdGlvbnMubWF4Q2xpZW50c1Blck9yZyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX0NMSUVOVFNfUEVSX09SRyB8fCAnNTAnLCAxMCk7XG4gICAgdGhpcy5tYXhUb3RhbFRpY2tldHMgPSBvcHRpb25zLm1heFRvdGFsVGlja2V0cyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX1RPVEFMX1RJQ0tFVFMgfHwgJzEwMDAnLCAxMCk7XG4gICAgdGhpcy5tYXhUaWNrZXRzUGVyT3JnID0gb3B0aW9ucy5tYXhUaWNrZXRzUGVyT3JnID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfVElDS0VUU19QRVJfT1JHIHx8ICcxMCcsIDEwKTtcbiAgICB0aGlzLnRpY2tldFR0bE1zID0gb3B0aW9ucy50aWNrZXRUdGxNcyA/PyBTU0VfVElDS0VUX1RUTF9NUztcbiAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMgPSBvcHRpb25zLnN0cmVhbU93bmVyVHRsTXMgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX1NUUkVBTV9PV05FUl9UVExfTVMgfHwgJzM2MDAwMDAnLCAxMCk7IC8vIDEgaG91clxuICAgIHRoaXMudGlja2V0U3RvcmVJbnN0YW5jZSA9IG9wdGlvbnMudGlja2V0U3RvcmU7XG4gICAgdGhpcy5sb2dTdHJlYW1FbmFibGVkID0gb3B0aW9ucy5sb2dTdHJlYW0gPz8gZmFsc2U7XG4gICAgdGhpcy5jbGllbnRUaW1lb3V0TXMgPSBvcHRpb25zLmNsaWVudFRpbWVvdXRNcyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfQ0xJRU5UX1RJTUVPVVRfTVMgfHwgJzE4MDAwMDAnLCAxMCk7IC8vIDMwIG1pbnV0ZXNcblxuICAgIGNvbnN0IGNsZWFudXBJbnRlcnZhbE1zID0gb3B0aW9ucy5jbGVhbnVwSW50ZXJ2YWxNcyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfQ0xFQU5VUF9JTlRFUlZBTF9NUyB8fCAnMzAwMDAwJywgMTApOyAvLyA1IG1pbnV0ZXNcbiAgICB0aGlzLnN0YXJ0Q2xlYW51cEludGVydmFsKGNsZWFudXBJbnRlcnZhbE1zKTtcblxuICAgIC8vIFdpcmUgdGhlIGNyb3NzLXBvZCByZWxheTogc3Vic2NyaWJlIG9uY2Ugb24gc3RhcnR1cCBzbyBmcmFtZXMgUFVCTElTSEVEIGJ5XG4gICAgLy8gYW55IG90aGVyIHBvZCBhcmUgcmUtZW1pdHRlZCB0byBUSElTIHBvZCdzIGxvY2FsIGNsaWVudHMuIEZyYW1lcyB3ZVxuICAgIC8vIHB1Ymxpc2hlZCBvdXJzZWx2ZXMgYXJlIGlnbm9yZWQgKG9yaWdpbiA9PT0gbm9kZUlkKSDigJQgd2UgYWxyZWFkeSB3cm90ZSB0aGVtXG4gICAgLy8gbG9jYWxseS4gRmFpbC1zYWZlOiBubyByZWxheSDih5IgbG9jYWwtb25seSBkZWxpdmVyeSAoc2luZ2xlLXJlcGxpY2EgZGVmYXVsdCkuXG4gICAgdGhpcy5yZWxheUZhY3RvcnkgPSBvcHRpb25zLnJlbGF5RmFjdG9yeTtcbiAgICBpZiAob3B0aW9ucy5yZWxheSkgdGhpcy5hdHRhY2hSZWxheShvcHRpb25zLnJlbGF5KTtcbiAgfVxuXG4gIHByaXZhdGUgYXR0YWNoUmVsYXkocmVsYXk6IFNTRVJlbGF5KTogdm9pZCB7XG4gICAgdGhpcy5yZWxheSA9IHJlbGF5O1xuICAgIHJlbGF5LnN1YnNjcmliZSgobXNnKSA9PiB0aGlzLm9uUmVsYXlNZXNzYWdlKG1zZykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFR1cm4gb24gY3Jvc3MtcG9kIGRlbGl2ZXJ5IHVzaW5nIHRoZSBjb25maWd1cmVkIGByZWxheUZhY3RvcnlgLiBJZGVtcG90ZW50O1xuICAgKiBhIG5vLW9wIHdoZW4gYSByZWxheSBpcyBhbHJlYWR5IHdpcmVkIG9yIG5vIGZhY3Rvcnkgd2FzIGdpdmVuLCBhbmQgd2hlbiB0aGVcbiAgICogZmFjdG9yeSByZXR1cm5zIG51bGwgKFJlZGlzIG5vdCBjb25maWd1cmVkIOKGkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5KS5cbiAgICovXG4gIGVuYWJsZVJlbGF5KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJlbGF5IHx8ICF0aGlzLnJlbGF5RmFjdG9yeSkgcmV0dXJuO1xuICAgIGNvbnN0IHJlbGF5ID0gdGhpcy5yZWxheUZhY3RvcnkoKTtcbiAgICBpZiAocmVsYXkpIHRoaXMuYXR0YWNoUmVsYXkocmVsYXkpO1xuICB9XG5cbiAgLyoqIFRoZSB0aWNrZXQgc3RvcmUsIGJ1aWxkaW5nIHRoZSBpbi1tZW1vcnkgZGVmYXVsdCBvbiBmaXJzdCB1c2UuICovXG4gIHByaXZhdGUgZ2V0IHRpY2tldFN0b3JlKCk6IFNzZVRpY2tldFN0b3JlIHtcbiAgICBpZiAoIXRoaXMudGlja2V0U3RvcmVJbnN0YW5jZSkge1xuICAgICAgdGhpcy50aWNrZXRTdG9yZUluc3RhbmNlID0gY3JlYXRlTWVtb3J5U3NlVGlja2V0U3RvcmUoe1xuICAgICAgICB0dGxNczogdGhpcy50aWNrZXRUdGxNcyxcbiAgICAgICAgbWF4VG90YWw6IHRoaXMubWF4VG90YWxUaWNrZXRzLFxuICAgICAgICBtYXhQZXJPcmc6IHRoaXMubWF4VGlja2V0c1Blck9yZyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vd25zVGlja2V0U3RvcmUgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50aWNrZXRTdG9yZUluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBhIGZyYW1lIHJlY2VpdmVkIGZyb20gYW5vdGhlciBwb2QgdmlhIHRoZSByZWxheS4gV2UgYWxyZWFkeSBkZWxpdmVyZWRcbiAgICogb3VyIE9XTiBmcmFtZXMgdG8gbG9jYWwgY2xpZW50cyBiZWZvcmUgcHVibGlzaGluZywgc28gaWdub3JlIG91ciBlY2hvLiBBXG4gICAqIGBzZW5kYCByZS1lbWl0cyB0byB0aGUgc3ViamVjdCdzIGxvY2FsIGNsaWVudHM7IGEgYGJyb2FkY2FzdGAgdG8gYWxsIG9mIHRoZW0uXG4gICAqIFB1cmVseSBsb2NhbCDigJQgbmV2ZXIgcmUtcHVibGlzaGVzLCBzbyB0aGVyZSBpcyBubyBmYW4tb3V0IGxvb3AuXG4gICAqL1xuICBwcml2YXRlIG9uUmVsYXlNZXNzYWdlKG1zZzogU1NFUmVsYXlNZXNzYWdlKTogdm9pZCB7XG4gICAgaWYgKCFtc2cgfHwgbXNnLm9yaWdpbiA9PT0gdGhpcy5ub2RlSWQpIHJldHVybjtcbiAgICBpZiAobXNnLmtpbmQgPT09ICdicm9hZGNhc3QnKSB7XG4gICAgICB0aGlzLmJyb2FkY2FzdExvY2FsKG1zZy5wYXlsb2FkKTtcbiAgICB9IGVsc2UgaWYgKG1zZy5yZXF1ZXN0SWQpIHtcbiAgICAgIHRoaXMuc2VuZExvY2FsKG1zZy5yZXF1ZXN0SWQsIG1zZy5wYXlsb2FkKTtcbiAgICB9XG4gIH1cblxuICAvKiogVG90YWwgb3BlbiBjb25uZWN0aW9ucyBhY3Jvc3MgYWxsIHJlcXVlc3RzLiAqL1xuICBwcml2YXRlIHRvdGFsQ2xpZW50cygpOiBudW1iZXIge1xuICAgIGxldCBuID0gMDtcbiAgICBmb3IgKGNvbnN0IGNsaWVudHMgb2YgdGhpcy5jbGllbnRzLnZhbHVlcygpKSBuICs9IGNsaWVudHMubGVuZ3RoO1xuICAgIHJldHVybiBuO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdGhlIGN1cnJlbnQgbGl2ZS1jb25uZWN0aW9uIGNvdW50IGFzIGEgZ2F1Z2Ugc28gb24tY2FsbCBjYW4gc2VlIFNTRVxuICAgKiBzYXR1cmF0aW9uIChhcHByb2FjaCB0byB0aGUgcGVyLXByb2Nlc3MgY2FwKSBvbiBhIGRhc2hib2FyZCDigJQgcHJldmlvdXNseVxuICAgKiB0aGVzZSBudW1iZXJzIGxpdmVkIG9ubHkgaW4gYGdldFN0YXRzKClgL2xvZ3MuIENhbGxlZCBhZnRlciBldmVyeSBhZGQvcmVtb3ZlL1xuICAgKiBjbG9zZS9jbGVhbnVwLiBDaGVhcCAoTyhSKSk7IG1ldHJpYyBoZWxwZXJzIG5ldmVyIHRocm93LlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVBY3RpdmVHYXVnZSgpOiB2b2lkIHtcbiAgICBzZXRHYXVnZSgnc3NlX2FjdGl2ZV9jb25uZWN0aW9ucycsIHt9LCB0aGlzLnRvdGFsQ2xpZW50cygpKTtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IG9wZW4tc3RyZWFtIGNvdW50IGZvciBhbiBvcmcgKDAgaWYgdW5zZWVuKS4gKi9cbiAgZ2V0T3JnQ2xpZW50Q291bnQob3JnSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhIHJlcXVlc3RJZCBmb3IgZXF1YWxpdHkgY2hlY2tzOiBkYXNoZXMgc3RyaXBwZWQgYW5kXG4gICAqIGxvd2VyY2FzZWQsIHNvIHRoZSBkYXNoZWQgKGFwaS1zZXJ2ZXIgYHV1aWQoKWApIGFuZCB1bmRhc2hlZCAobmdpbnhcbiAgICogYCRyZXF1ZXN0X2lkYCkgcmVuZGVyaW5ncyBvZiB0aGUgc2FtZSBpZCBjb21wYXJlIGVxdWFsLiBDYWxsZXJzIGFyZVxuICAgKiBleHBlY3RlZCB0byBoYXZlIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBhZ2FpbnN0IHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0uXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXF1ZXN0SWQucmVwbGFjZSgvLS9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhbiBvcmdJZCBmb3Igb3duZXJzaGlwIGVxdWFsaXR5IGNoZWNrczogdHJpbW1lZCBhbmRcbiAgICogbG93ZXJjYXNlZC4gVGhlIHN0cmVhbSBQUk9EVUNFUiAoYmluZFN0cmVhbU93bmVyKSBhbmQgdGhlIHRpY2tldC1taW50aW5nXG4gICAqIENPTlNVTUVSIChjcmVhdGVUaWNrZXQpIHJ1biBpbiBkaWZmZXJlbnQgc2VydmljZXMsIHNvIGEgY2FzaW5nIC8gd2hpdGVzcGFjZVxuICAgKiBkcmlmdCBiZXR3ZWVuIGhvdyBlYWNoIHJlbmRlcnMgdGhlIHNhbWUgb3JnIHdvdWxkIG90aGVyd2lzZSBtYWtlIHRoZSBvd25lclxuICAgKiBjb21wYXJpc29uIGluIHtAbGluayBjcmVhdGVUaWNrZXR9IGZhbHNlLWBmb3JiaWRkZW5gIHRoZSByZWFsIG93bmVyLlxuICAgKiBOb3JtYWxpemluZyBib3RoIHNpZGVzIOKAlCBtaXJyb3Jpbmcge0BsaW5rIG5vcm1hbGl6ZVJlcXVlc3RJZH0g4oCUIGNsb3NlcyB0aGF0LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbm9ybWFsaXplT3JnSWQob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG9yZ0lkLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCB0aGUgb3JnIHRoYXQgT1dOUyBhIHN0cmVhbSBzdWJqZWN0LiBUaGUgc3RyZWFtIFBST0RVQ0VSIGNhbGxzIHRoaXNcbiAgICogd2hlbiBpdCBjcmVhdGVzIGEgYnVpbGQtbG9nIHN0cmVhbSBzbyB0aGF0IHRpY2tldCBtaW50aW5nIGNhbiBhc3NlcnQgdGhlXG4gICAqIGNhbGxlcidzIG9yZyBvd25zIHRoZSBzdWJqZWN0IChzZWUge0BsaW5rIGNyZWF0ZVRpY2tldH0pLiBCYWNrZWQgYnkgdGhlXG4gICAqIGluamVjdGVkIHRpY2tldCBzdG9yZSwgc28gd2hlbiBhIFJlZGlzIHN0b3JlIGlzIHdpcmVkIHRoZSBwbGF0Zm9ybSBwcm9kdWNlclxuICAgKiAoYSBkaWZmZXJlbnQgc2VydmljZSBzaGFyaW5nIHRoZSBzYW1lIFJlZGlzKSBjYW4gYmluZCBvd25lcnNoaXAgdGhhdCB0aGlzXG4gICAqIHNlcnZpY2UgcmVhZHMg4oCUIGNsb3NpbmcgdGhlIGNyb3NzLXRlbmFudCBhdHRhY2ggZ2FwIHdoZXJlIGFueSBvcmcgY291bGQgbWludFxuICAgKiBhIHRpY2tldCBmb3IgYSBndWVzc2VkIHJlcXVlc3RJZC5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBzdHJlYW0gc3ViamVjdCAoZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyKS5cbiAgICogQHBhcmFtIG9yZ0lkIC0gVGhlIG93bmluZyBvcmcgKG5vcm1hbGl6ZWQgaW50ZXJuYWxseSB2aWEgbm9ybWFsaXplT3JnSWQpLlxuICAgKi9cbiAgYXN5bmMgYmluZFN0cmVhbU93bmVyKHJlcXVlc3RJZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5iaW5kT3duZXIoXG4gICAgICBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpLFxuICAgICAgU1NFTWFuYWdlci5ub3JtYWxpemVPcmdJZChvcmdJZCksXG4gICAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaW50IGEgc2hvcnQtbGl2ZWQsIHNpbmdsZS11c2UgU1NFIHRpY2tldCBib3VuZCB0byBgb3JnSWRgIEFORCBhIHNwZWNpZmljXG4gICAqIHN0cmVhbSBzdWJqZWN0IChgcmVxdWVzdElkYCkuIENsaWVudHMgUE9TVCB0byBvYnRhaW4gb25lIChKV1QtYXV0aGVudGljYXRlZClcbiAgICogZm9yIHRoZSBleGFjdCBzdHJlYW0gdGhleSBpbnRlbmQgdG8gb3BlbiwgdGhlbiBvcGVuIHRoZSBFdmVudFNvdXJjZSB3aXRoXG4gICAqIGA/dGlja2V0PTx0PmAgc28gdGhlIEpXVCBuZXZlciBsYW5kcyBpbiBhIHF1ZXJ5IHN0cmluZyAvIGFjY2VzcyBsb2cuIFRoZVxuICAgKiB0aWNrZXQgY2FuIHRoZW4gb25seSBiZSBjb25zdW1lZCB0byBvcGVuIHRoYXQgb25lIHN1YmplY3QncyBzdHJlYW0g4oCUIHNlZVxuICAgKiB7QGxpbmsgY29uc3VtZVRpY2tldH0g4oCUIHdoaWNoIGlzIHdoYXQgZW5mb3JjZXMgcGVyLXN1YmplY3QgYXV0aG9yaXphdGlvbi5cbiAgICpcbiAgICogT1JHLU9XTkVSU0hJUDogaWYgYSBzdHJlYW0gb3duZXIgaGFzIGJlZW4gYm91bmQgZm9yIHRoaXMgc3ViamVjdCAodmlhXG4gICAqIHtAbGluayBiaW5kU3RyZWFtT3duZXJ9KSBhbmQgaXQgaXMgYSBESUZGRVJFTlQgb3JnLCBtaW50aW5nIGlzIHJlZnVzZWRcbiAgICogKGByZWFzb246ICdmb3JiaWRkZW4nYCkg4oCUIGFuIG9yZyBjYW5ub3QgbWludCBhIHRpY2tldCBmb3IgYW5vdGhlciBvcmcnc1xuICAgKiBzdHJlYW0gZXZlbiBpZiBpdCBndWVzc2VzIHRoZSByZXF1ZXN0SWQuIFdoZW4gbm8gb3duZXIgaXMgYm91bmQgKHByb2R1Y2VyXG4gICAqIHdpcmluZyBub3QgeWV0IHByZXNlbnQpLCBtaW50aW5nIGZhbGxzIGJhY2sgdG8gYmluZGluZyB0aGUgdGlja2V0IHRvIHRoZVxuICAgKiBjYWxsZXIncyBvd24gb3JnLCBwcmVzZXJ2aW5nIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAqXG4gICAqIEJvdW5kZWQgYnkgdGhlIHRpY2tldCBzdG9yZSdzIGxpdmUtdGlja2V0IGNhcHMgKHRvdGFsIGFuZCBwZXIgb3JnKS4gQW5cbiAgICogb3duZXJzaGlwIGxvb2t1cCB0aGUgc3RvcmUgY2FuJ3QgYW5zd2VyIGlzIHJlZnVzZWQgYXMgYGNhcGFjaXR5YC5cbiAgICpcbiAgICogQHBhcmFtIG9yZ0lkIC0gT3duaW5nIG9yZyAobm9ybWFsaXplZCBpbnRlcm5hbGx5IHZpYSBub3JtYWxpemVPcmdJZCkuXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBUaGUgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IHRoaXMgdGlja2V0IGF1dGhvcml6ZXMuXG4gICAqICAgVGhlIGNhbGxlciBtdXN0IGhhdmUgZm9ybWF0LXZhbGlkYXRlZCBpdCAoc2VlIHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0pLlxuICAgKiBAcmV0dXJucyBgeyBvazogdHJ1ZSwgdGlja2V0IH1gIG9uIHN1Y2Nlc3MsIG9yIGB7IG9rOiBmYWxzZSwgcmVhc29uIH1gXG4gICAqICAgd2hlcmUgcmVhc29uIGlzIGAnb3JnLWxpbWl0J2AsIGAnY2FwYWNpdHknYCwgb3IgYCdmb3JiaWRkZW4nYC5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZVRpY2tldChvcmdJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8Q3JlYXRlVGlja2V0UmVzdWx0PiB7XG4gICAgLy8gT3duZXJzaGlwIGdhdGUgZmlyc3Qg4oCUIGEgY3Jvc3MtdGVuYW50IG1pbnQgYXR0ZW1wdCBzaG91bGQgbmV2ZXIgZXZlblxuICAgIC8vIGNvbnN1bWUgY2FwIGJ1ZGdldC4gT25seSBlbmZvcmNlZCB3aGVuIGFuIG93bmVyIGlzIGFjdHVhbGx5IGJvdW5kLiBCb3RoXG4gICAgLy8gc2lkZXMgYXJlIG9yZy1ub3JtYWxpemVkIHNvIGEgcHJvZHVjZXIvY29uc3VtZXIgY2FzaW5nIGRyaWZ0IGNhbid0XG4gICAgLy8gZmFsc2UtYGZvcmJpZGRlbmAgdGhlIHJlYWwgb3duZXIgKG1pcnJvcnMgcmVxdWVzdElkIG5vcm1hbGl6YXRpb24pLlxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRPcmcgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZU9yZ0lkKG9yZ0lkKTtcbiAgICBsZXQgb3duZXI6IHN0cmluZyB8IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIG93bmVyID0gYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5nZXRPd25lcihub3JtYWxpemVkKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIC8vIENhbid0IHRlbGwgd2hvIG93bnMgdGhlIHN1YmplY3Qg4oCUIHJlZnVzZSByYXRoZXIgdGhhbiBtaW50IHVuY2hlY2tlZC5cbiAgICAgIGxvZ2dlci53YXJuKCdTU0UgdGlja2V0IHJlZnVzZWQ6IHN0cmVhbSBvd25lcnNoaXAgbG9va3VwIGZhaWxlZCcsIHsgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV90aWNrZXRfcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ2NhcGFjaXR5JyB9KTtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH07XG4gICAgfVxuICAgIGlmIChvd25lciAmJiBvd25lciAhPT0gbm9ybWFsaXplZE9yZykge1xuICAgICAgbG9nZ2VyLndhcm4oYFNTRSB0aWNrZXQgcmVmdXNlZDogb3JnICR7bm9ybWFsaXplZE9yZ30gZG9lcyBub3Qgb3duIHN0cmVhbSBzdWJqZWN0YCk7XG4gICAgICBpbmNDb3VudGVyKCdzc2VfdGlja2V0X3JlamVjdGVkX3RvdGFsJywgeyByZWFzb246ICdmb3JiaWRkZW4nIH0pO1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCByZWFzb246ICdmb3JiaWRkZW4nIH07XG4gICAgfVxuXG4gICAgY29uc3QgaXNzdWVkID0gYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5pc3N1ZShub3JtYWxpemVkT3JnLCBub3JtYWxpemVkKTtcbiAgICBpZiAoIWlzc3VlZC5vaykge1xuICAgICAgY29uc3QgcmVhc29uID0gaXNzdWVkLnJlYXNvbiA9PT0gJ29yZycgPyAnb3JnLWxpbWl0JyA6ICdjYXBhY2l0eSc7XG4gICAgICBsb2dnZXIud2FybihgU1NFIHRpY2tldCByZWZ1c2VkICgke3JlYXNvbn0pIGZvciAke25vcm1hbGl6ZWRPcmd9YCk7XG4gICAgICBpbmNDb3VudGVyKCdzc2VfdGlja2V0X3JlamVjdGVkX3RvdGFsJywgeyByZWFzb24gfSk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbiB9O1xuICAgIH1cbiAgICByZXR1cm4geyBvazogdHJ1ZSwgdGlja2V0OiBpc3N1ZWQudGlja2V0IH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYW5kIENPTlNVTUUgYSB0aWNrZXQgZm9yIGEgc3BlY2lmaWMgc3RyZWFtIHN1YmplY3QuIFNpbmdsZS11c2U6XG4gICAqIHRoZSB0aWNrZXQgaXMgZGVsZXRlZCB3aGV0aGVyIG9yIG5vdCBpdCB0dXJucyBvdXQgdG8gYmUgdmFsaWQsIHNvIGEgcmVwbGF5XG4gICAqIG9mIHRoZSBzYW1lIHZhbHVlIGFsd2F5cyBmYWlscy4gUmV0dXJucyB0aGUgYm91bmQgb3JnIG9uIHN1Y2Nlc3MsIG9yIG51bGxcbiAgICogd2hlbiB0aGUgdGlja2V0IGlzIHVua25vd24gLyBhbHJlYWR5LXVzZWQgLyBleHBpcmVkIC8gT1Igd2FzIG1pbnRlZCBmb3IgYVxuICAgKiBESUZGRVJFTlQgYHJlcXVlc3RJZGAgdGhhbiB0aGUgb25lIGJlaW5nIG9wZW5lZC5cbiAgICpcbiAgICogVGhlIHN1YmplY3QgY2hlY2sgaXMgdGhlIGF1dGhvcml6YXRpb24gZml4OiB3aXRob3V0IGl0LCBhIHRpY2tldCBtaW50ZWQgZm9yXG4gICAqIG9uZSBzdHJlYW0gY291bGQgYmUgcHJlc2VudGVkIHRvIG9wZW4gQU5ZIHN0cmVhbSB0aGUgaG9sZGVyJ3Mgb3JnIGNvdWxkXG4gICAqIG5hbWUsIGxldHRpbmcgYW4gYXV0aGVudGljYXRlZCBvcmcgYXR0YWNoIHRvIGFub3RoZXIgb3JnJ3MgbG9nIHN0cmVhbSBieVxuICAgKiBndWVzc2luZyBpdHMgcmVxdWVzdElkLiBUaGUgZ2VuZXJpYyA0MDEgdGhlIGNhbGxlciByZXR1cm5zIGRvZXMgbm90XG4gICAqIGRpc3Rpbmd1aXNoIFwidW5rbm93biB0aWNrZXRcIiBmcm9tIFwid3Jvbmcgc3ViamVjdFwiLCBzbyBpdCBsZWFrcyBub3RoaW5nXG4gICAqIGFib3V0IHdoaWNoIHJlcXVlc3RJZHMgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB0aWNrZXRJZCAtIFRoZSBvcGFxdWUgdGlja2V0IHZhbHVlIGZyb20gYD90aWNrZXQ9YC5cbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBzdHJlYW0gc3ViamVjdCBmcm9tIHRoZSBVUkwgcGF0aCAoYDpyZXF1ZXN0SWRgKSxcbiAgICogICBhbHJlYWR5IGZvcm1hdC12YWxpZGF0ZWQgYnkgdGhlIGNhbGxlci5cbiAgICovXG4gIGFzeW5jIGNvbnN1bWVUaWNrZXQodGlja2V0SWQ6IHN0cmluZywgcmVxdWVzdElkOiBzdHJpbmcpOiBQcm9taXNlPHsgb3JnSWQ6IHN0cmluZyB9IHwgbnVsbD4ge1xuICAgIGNvbnN0IHRpY2tldCA9IGF3YWl0IHRoaXMudGlja2V0U3RvcmUuY29uc3VtZSh0aWNrZXRJZCk7IC8vIHNpbmdsZS11c2VcbiAgICBpZiAoIXRpY2tldCkgcmV0dXJuIG51bGw7XG4gICAgLy8gU3ViamVjdCBiaW5kaW5nIOKAlCByZWplY3QgYSB0aWNrZXQgcHJlc2VudGVkIGZvciBhIHN1YmplY3QgaXQgd2FzIG5vdFxuICAgIC8vIG1pbnRlZCBmb3IgKGluY2x1ZGluZyBhbiB1bmJvdW5kLCBvcmctY2hhbm5lbCB0aWNrZXQpLiBCb3RoIHNpZGVzIGFyZVxuICAgIC8vIG5vcm1hbGl6ZWQgc28gZGFzaGVkL3VuZGFzaGVkIGZvcm1zIG1hdGNoLlxuICAgIGlmICh0aWNrZXQuc3ViamVjdCAhPT0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHsgb3JnSWQ6IHRpY2tldC5vcmdJZCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjbGllbnQgdG8gdGhlIFNTRSBtYW5hZ2VyXG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBVbmlxdWUgcmVxdWVzdCBJRFxuICAgKiBAcGFyYW0gcmVzIC0gRXhwcmVzcyBSZXNwb25zZSBvYmplY3RcbiAgICogQHBhcmFtIG9yZ0lkIC0gQXV0aGVudGljYXRlZCBvcmcgaWQgKG9wdGlvbmFsKS4gV2hlbiBzZXQsIGVuZm9yY2VzIHRoZVxuICAgKiAgIHBlci1vcmcgY2FwIGFuZCB0aGUgY291bnRlciBpcyBkZWNyZW1lbnRlZCBvbiBkaXNjb25uZWN0L2NsZWFudXAuXG4gICAqIEBwYXJhbSBtYXhDbGllbnRzRm9yU3ViamVjdCAtIFBlci1zdWJqZWN0IGNhcCBvdmVycmlkZSAoZGVmYXVsdFxuICAgKiAgIGBtYXhDbGllbnRzUGVyUmVxdWVzdGApLiBBbiBvcmcta2V5ZWQgY2hhbm5lbCdzIHN1YmplY3QgSVMgdGhlIG9yZywgc28gaXRcbiAgICogICBtdXN0IG5vdCBpbmhlcml0IHRoZSBzbWFsbCBwZXItYnVpbGQtcmVxdWVzdCBjYXAg4oCUIHNlZSB7QGxpbmsgYWRkT3JnQ2xpZW50fS5cbiAgICogQHJldHVybnMgdHJ1ZSBpZiBjbGllbnQgd2FzIGFkZGVkLCBmYWxzZSBpZiByZWplY3RlZCAobGltaXQgcmVhY2hlZClcbiAgICovXG4gIGFkZENsaWVudChyZXF1ZXN0SWQ6IHN0cmluZywgcmVzOiBSZXNwb25zZSwgb3JnSWQ/OiBzdHJpbmcsIG1heENsaWVudHNGb3JTdWJqZWN0OiBudW1iZXIgPSB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0KTogYm9vbGVhbiB7XG4gICAgLy8gTm9ybWFsaXplIHRoZSBtYXAga2V5OiB0aGUgc3ViamVjdCBpZCBpcyBhbGxvd2VkIGluIHR3byBmb3JtcyAoZGFzaGVkXG4gICAgLy8gYXBpLXNlcnZlciB1dWlkIHZzIHVuZGFzaGVkIG5naW54ICRyZXF1ZXN0X2lkKSwgYW5kIGEgcHJvZHVjZXIvY29uc3VtZXIgdGhhdFxuICAgIC8vIHJlbmRlciBpdCBkaWZmZXJlbnRseSB3b3VsZCBvdGhlcndpc2Uga2V5IGRpZmZlcmVudCBNYXAgZW50cmllcyDigJQgdGhlIGNsaWVudFxuICAgIC8vIHJlZ2lzdGVycyB1bmRlciBvbmUgYW5kIGV2ZXJ5IHNlbmQoKS9yZWxheSB3cml0ZXMgdG8gYW5vdGhlciwgZHJvcHBpbmcgYWxsXG4gICAgLy8gZnJhbWVzLiBOb3JtYWxpemluZyBoZXJlIChhbmQgaW4gc2VuZC9zZW5kTG9jYWwvY2xvc2VSZXF1ZXN0L2V0Yy4pIHVuaWZpZXMgdGhlbS5cbiAgICByZXF1ZXN0SWQgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpIHx8IFtdO1xuXG4gICAgLy8gQ2hlY2sgY2xpZW50IGxpbWl0XG4gICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA+PSBtYXhDbGllbnRzRm9yU3ViamVjdCkge1xuICAgICAgbG9nZ2VyLndhcm4oYENsaWVudCBsaW1pdCByZWFjaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAobWF4OiAke21heENsaWVudHNGb3JTdWJqZWN0fSlgKTtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV9jb25uZWN0aW9uX3JlamVjdGVkX3RvdGFsJywgeyByZWFzb246ICdyZXF1ZXN0LWxpbWl0JyB9KTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzLXdpZGUgY2FwOiBwcm90ZWN0cyBmZCB0YWJsZSArIG1lbW9yeSBmcm9tIHJ1bmF3YXkgZGFzaGJvYXJkcy5cbiAgICBpZiAodGhpcy50b3RhbENsaWVudHMoKSA+PSB0aGlzLm1heFRvdGFsQ2xpZW50cykge1xuICAgICAgbG9nZ2VyLndhcm4oYFRvdGFsIFNTRSBjbGllbnQgY2FwIHJlYWNoZWQgKG1heDogJHt0aGlzLm1heFRvdGFsQ2xpZW50c30pOyByZWplY3RpbmcgbmV3IGNvbm5lY3Rpb25gKTtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV9jb25uZWN0aW9uX3JlamVjdGVkX3RvdGFsJywgeyByZWFzb246ICd0b3RhbC1jYXAnIH0pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFBlci1vcmcgY2FwOiBwcmV2ZW50cyBvbmUgbm9pc3kgb3JnIGZyb20gbW9ub3BvbGl6aW5nIHByb2Nlc3Mtd2lkZVxuICAgIC8vIHNsb3RzLiBFbmZvcmNlZCBvbmx5IHdoZW4gb3JnSWQgaXMga25vd24g4oCUIHNlcnZpY2UtaW50ZXJuYWwgLyBhbm9ueW1vdXNcbiAgICAvLyBzdHJlYW1zIHRoYXQgbmV2ZXIgaWRlbnRpZnkgd2l0aCBhbiBvcmdJZCBzdGF5IHN1YmplY3QgdG8gdGhlIGdsb2JhbFxuICAgIC8vIGNlaWxpbmdzIGFib3ZlLiBSZXNlcnZlIGF0b21pY2FsbHkgYmVmb3JlIGluc2VydCBzbyB0d28gY29uY3VycmVudFxuICAgIC8vIHJlcXVlc3RzIGF0IHRoZSBsaW1pdCBjYW4ndCBib3RoIHN1Y2NlZWQuXG4gICAgaWYgKG9yZ0lkKSB7XG4gICAgICBjb25zdCBvcmdDdXJyZW50ID0gdGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwO1xuICAgICAgaWYgKG9yZ0N1cnJlbnQgPj0gdGhpcy5tYXhDbGllbnRzUGVyT3JnKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBQZXItb3JnIFNTRSBjbGllbnQgY2FwIHJlYWNoZWQgZm9yICR7b3JnSWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyT3JnfSk7IHJlamVjdGluZyBuZXcgY29ubmVjdGlvbmApO1xuICAgICAgICBpbmNDb3VudGVyKCdzc2VfY29ubmVjdGlvbl9yZWplY3RlZF90b3RhbCcsIHsgcmVhc29uOiAnb3JnLWNhcCcgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMub3JnQ2xpZW50Q291bnRzLnNldChvcmdJZCwgb3JnQ3VycmVudCArIDEpO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSB0aW1lb3V0IGZvciB0aGlzIGNsaWVudFxuICAgIGNvbnN0IGNsaWVudElkID0gdXVpZCgpO1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ2xpZW50ICR7Y2xpZW50SWR9IHRpbWVkIG91dCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUmVzcG9uc2UgYWxyZWFkeSBjbG9zZWQgb24gdGltZW91dCcsIHsgcmVxdWVzdElkLCBjbGllbnRJZCwgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLmNsaWVudFRpbWVvdXRNcyk7XG5cbiAgICBjb25zdCBjbGllbnQ6IFNTRUNsaWVudCA9IHtcbiAgICAgIGlkOiBjbGllbnRJZCxcbiAgICAgIHJlcyxcbiAgICAgIGNvbm5lY3RlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgdGltZW91dCxcbiAgICAgIGJhY2twcmVzc3VyZUNvdW50OiAwLFxuICAgICAgb3JnSWQsXG4gICAgfTtcblxuICAgIC8vIEhhbmRsZSBkaXNjb25uZWN0aW9uXG4gICAgcmVzLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgcmVzLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci5lcnJvcihgU1NFIGNsaWVudCBlcnJvciBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH06YCwgZXJyKTtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgZXhpc3RpbmcucHVzaChjbGllbnQpO1xuICAgIHRoaXMuY2xpZW50cy5zZXQocmVxdWVzdElkLCBleGlzdGluZyk7XG4gICAgaW5jQ291bnRlcignc3NlX2Nvbm5lY3Rpb25zX3RvdGFsJywge30pO1xuICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcblxuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xpZW50ICR7Y2xpZW50SWR9IGNvbm5lY3RlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKHRvdGFsOiAke2V4aXN0aW5nLmxlbmd0aH0pYCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoIGEgY2xpZW50IHRvIGFuIE9SRy1rZXllZCBzdHJlYW0gKHRoZSBvcmcgaXMgdGhlIHN1YmplY3QpLiBDb3VudHNcbiAgICogYWdhaW5zdCB0aGUgcGVyLW9yZyBjYXAsIGFuZCB0aGUgb3JnIOKAlCBub3QgdGhlIHBlci1yZXF1ZXN0IGNhcCDigJQgYm91bmRzIGhvd1xuICAgKiBtYW55IHN0cmVhbXMgc2hhcmUgdGhlIHN1YmplY3QuXG4gICAqL1xuICBhZGRPcmdDbGllbnQob3JnSWQ6IHN0cmluZywgcmVzOiBSZXNwb25zZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFkZENsaWVudChvcmdJZCwgcmVzLCBvcmdJZCwgdGhpcy5tYXhDbGllbnRzUGVyT3JnKTtcbiAgfVxuXG4gIC8qKiBEcm9wIG9uZSBmcm9tIHRoZSBwZXItb3JnIGNvdW50ZXIuIElkZW1wb3RlbnQ6IGEgY291bnRlciBhdCAwIHN0YXlzIGF0IDBcbiAgICogIGFuZCB0aGUgb3JnIGtleSBpcyByZW1vdmVkIGZyb20gdGhlIG1hcC4gKi9cbiAgcHJpdmF0ZSBkZWNyZW1lbnRPcmdDb3VudChvcmdJZD86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghb3JnSWQpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwO1xuICAgIGlmIChjdXJyZW50IDw9IDEpIHRoaXMub3JnQ2xpZW50Q291bnRzLmRlbGV0ZShvcmdJZCk7XG4gICAgZWxzZSB0aGlzLm9yZ0NsaWVudENvdW50cy5zZXQob3JnSWQsIGN1cnJlbnQgLSAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgY2xpZW50IGZyb20gdGhlIG1hbmFnZXJcbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCBjbGllbnRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKTtcbiAgICBpZiAoIWNsaWVudHMpIHJldHVybjtcblxuICAgIGNvbnN0IHJlbWFpbmluZyA9IGNsaWVudHMuZmlsdGVyKGMgPT4ge1xuICAgICAgaWYgKGMuaWQgPT09IGNsaWVudElkKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjLnRpbWVvdXQpO1xuICAgICAgICAvLyBNaXJyb3IgdGhlIHBlci1vcmcgY291bnRlciDigJQgbXVzdCBkZWNyZW1lbnQgaGVyZSwgbm90IGp1c3QgaW4gdGhlXG4gICAgICAgIC8vIGV4cGxpY2l0IGNsb3NlIHBhdGhzLCBzaW5jZSAnY2xvc2UnLydlcnJvcicgZXZlbnQgaGFuZGxlcnMgYXJlIHRoZVxuICAgICAgICAvLyBwcmltYXJ5IGRpc2Nvbm5lY3Qgc2lnbmFsIGluIHByYWN0aWNlLlxuICAgICAgICB0aGlzLmRlY3JlbWVudE9yZ0NvdW50KGMub3JnSWQpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIGlmIChyZW1haW5pbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICBsb2dnZXIuZGVidWcoYEFsbCBjbGllbnRzIGRpc2Nvbm5lY3RlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIHJlbWFpbmluZyk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gYWxsIFNTRSBjbGllbnRzIGZvciBhIHJlcXVlc3RJZFxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gUmVxdWVzdCBJRFxuICAgKiBAcGFyYW0gdHlwZSAtIEV2ZW50IHR5cGVcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBNZXNzYWdlIHN0cmluZ1xuICAgKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YVxuICAgKiBAcmV0dXJucyBOdW1iZXIgb2YgY2xpZW50cyB0aGUgbWVzc2FnZSB3YXMgc2VudCB0b1xuICAgKi9cbiAgc2VuZChyZXF1ZXN0SWQ6IHN0cmluZywgdHlwZTogU1NFRXZlbnRUeXBlLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogbnVtYmVyIHtcbiAgICByZXF1ZXN0SWQgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpOyAvLyB1bmlmeSBwcm9kdWNlci9jb25zdW1lciBrZXkgZm9ybXNcbiAgICBjb25zdCBwYXlsb2FkOiBTU0VQYXlsb2FkID0ge1xuICAgICAgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHR5cGUsXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGF0YSxcbiAgICB9O1xuXG4gICAgLy8gRGVsaXZlciB0byBMT0NBTCBjbGllbnRzIGZpcnN0LCB0aGVuIHJlbGF5IHRoZSBTQU1FIHBheWxvYWQgdG8gb3RoZXIgcG9kc1xuICAgIC8vIHNvIGFuIEV2ZW50U291cmNlIGF0dGFjaGVkIG9uIGEgZGlmZmVyZW50IHJlcGxpY2EgYWxzbyByZWNlaXZlcyBpdC4gVGhlXG4gICAgLy8gcmVsYXkgaXMgZmlyZS1hbmQtZm9yZ2V0IGFuZCBmYWlsLXNhZmU6IG5vIHJlbGF5IC8gUmVkaXMgZG93biDih5IgbG9jYWwtb25seS5cbiAgICBjb25zdCBzZW50Q291bnQgPSB0aGlzLnNlbmRMb2NhbChyZXF1ZXN0SWQsIHBheWxvYWQpO1xuICAgIHRoaXMucHVibGlzaFJlbGF5KHsgb3JpZ2luOiB0aGlzLm5vZGVJZCwga2luZDogJ3NlbmQnLCByZXF1ZXN0SWQsIHBheWxvYWQgfSk7XG4gICAgcmV0dXJuIHNlbnRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZSBhIHByZS1idWlsdCBwYXlsb2FkIHRvIHRoaXMgcG9kJ3MgTE9DQUwgY2xpZW50cyBmb3IgYHJlcXVlc3RJZGAuIFNoYXJlZFxuICAgKiBieSB7QGxpbmsgc2VuZH0gKGxvY2FsIGhhbGYpIGFuZCB0aGUgcmVsYXkgcmUtZW1pdCBwYXRoICh7QGxpbmsgb25SZWxheU1lc3NhZ2V9KSxcbiAgICogc28gYSByZWxheWVkIGZyYW1lIHJldXNlcyB0aGUgcHJvZHVjZXIncyBvcmlnaW5hbCBgdHNgIHJhdGhlciB0aGFuIGEgbmV3IG9uZS5cbiAgICogTmV2ZXIgcmVsYXlzIOKAlCBjYWxsZXJzIGRlY2lkZSB3aGV0aGVyIHRvIHB1Ymxpc2guXG4gICAqL1xuICBwcml2YXRlIHNlbmRMb2NhbChyZXF1ZXN0SWQ6IHN0cmluZywgcGF5bG9hZDogU1NFUGF5bG9hZCk6IG51bWJlciB7XG4gICAgcmVxdWVzdElkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTsgLy8gaWRlbXBvdGVudDsgY292ZXJzIHRoZSByZWxheSByZS1lbWl0IHBhdGhcbiAgICBjb25zdCBjbGllbnRzID0gWy4uLih0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgfHwgW10pXTtcbiAgICBsZXQgc2VudENvdW50ID0gMDtcbiAgICBjb25zdCBzZXJpYWxpemVkID0gYGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkocGF5bG9hZCl9XFxuXFxuYDtcblxuICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIEJhY2twcmVzc3VyZTogc2tpcCBjbGllbnRzIHdob3NlIHdyaXRlIGJ1ZmZlciBpcyBmdWxsXG4gICAgICAgIGlmIChjbGllbnQucmVzLndyaXRhYmxlRW5kZWQpIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FuV3JpdGUgPSBjbGllbnQucmVzLndyaXRlKHNlcmlhbGl6ZWQpO1xuICAgICAgICBpZiAoIWNhbldyaXRlKSB7XG4gICAgICAgICAgY2xpZW50LmJhY2twcmVzc3VyZUNvdW50Kys7XG4gICAgICAgICAgLy8gRGlzY29ubmVjdCBjbGllbnRzIHRoYXQgY29uc2lzdGVudGx5IGNhbid0IGtlZXAgdXAgKDEwIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMpXG4gICAgICAgICAgaWYgKGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCA+PSBDb3JlQ29uc3RhbnRzLlNTRV9CQUNLUFJFU1NVUkVfVEhSRVNIT0xEKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybihgRGlzY29ubmVjdGluZyBzbG93IGNsaWVudCAke2NsaWVudC5pZH0gZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9ICgke2NsaWVudC5iYWNrcHJlc3N1cmVDb3VudH0gYmFja3ByZXNzdXJlIGV2ZW50cylgKTtcbiAgICAgICAgICAgIGluY0NvdW50ZXIoJ3NzZV9iYWNrcHJlc3N1cmVfZGlzY29ubmVjdHNfdG90YWwnLCB7fSk7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICAgICAgICB0cnkgeyBjbGllbnQucmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCA9IDA7IC8vIFJlc2V0IG9uIHN1Y2Nlc3NmdWwgd3JpdGVcbiAgICAgICAgfVxuICAgICAgICBzZW50Q291bnQrKztcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHNlbmQgdG8gY2xpZW50ICR7Y2xpZW50LmlkfTpgLCBlcnJvcik7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VudENvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEJyb2FkY2FzdCBhIG1lc3NhZ2UgdG8gYWxsIGNvbm5lY3RlZCBjbGllbnRzIGFjcm9zcyBhbGwgcmVxdWVzdHNcbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBFdmVudCB0eXBlXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gTWVzc2FnZSBzdHJpbmdcbiAgICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBhZGRpdGlvbmFsIGRhdGFcbiAgICogQHJldHVybnMgVG90YWwgbnVtYmVyIG9mIGNsaWVudHMgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgdG9cbiAgICovXG4gIGJyb2FkY2FzdCh0eXBlOiBTU0VFdmVudFR5cGUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IHVua25vd24pOiBudW1iZXIge1xuICAgIGNvbnN0IHBheWxvYWQ6IFNTRVBheWxvYWQgPSB7XG4gICAgICB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgdHlwZSxcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBkYXRhLFxuICAgIH07XG4gICAgLy8gRGVsaXZlciB0byBsb2NhbCBjbGllbnRzLCB0aGVuIHJlbGF5IGEgc2luZ2xlIGJyb2FkY2FzdCBmcmFtZSBzbyBFVkVSWSBwb2RcbiAgICAvLyByZS1lbWl0cyB0byBBTEwgb2YgaXRzIG93biBjbGllbnRzIOKAlCBhIHBlci1yZXF1ZXN0SWQgcmVsYXkgd291bGQgbWlzc1xuICAgIC8vIHN1YmplY3RzIHRoYXQgb25seSBleGlzdCBvbiBvdGhlciByZXBsaWNhcy5cbiAgICBjb25zdCB0b3RhbFNlbnQgPSB0aGlzLmJyb2FkY2FzdExvY2FsKHBheWxvYWQpO1xuICAgIHRoaXMucHVibGlzaFJlbGF5KHsgb3JpZ2luOiB0aGlzLm5vZGVJZCwga2luZDogJ2Jyb2FkY2FzdCcsIHBheWxvYWQgfSk7XG4gICAgcmV0dXJuIHRvdGFsU2VudDtcbiAgfVxuXG4gIC8qKiBXcml0ZSBhIHByZS1idWlsdCBwYXlsb2FkIHRvIGFsbCBMT0NBTCBjbGllbnRzIGFjcm9zcyBldmVyeSByZXF1ZXN0LiAqL1xuICBwcml2YXRlIGJyb2FkY2FzdExvY2FsKHBheWxvYWQ6IFNTRVBheWxvYWQpOiBudW1iZXIge1xuICAgIGxldCB0b3RhbFNlbnQgPSAwO1xuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdG90YWxTZW50ICs9IHRoaXMuc2VuZExvY2FsKHJlcXVlc3RJZCwgcGF5bG9hZCk7XG4gICAgfVxuICAgIHJldHVybiB0b3RhbFNlbnQ7XG4gIH1cblxuICAvKiogRmlyZS1hbmQtZm9yZ2V0IHJlbGF5IHB1Ymxpc2guIE5vLW9wIChsb2NhbC1vbmx5KSB3aGVuIG5vIHJlbGF5IGlzIHdpcmVkLiAqL1xuICBwcml2YXRlIHB1Ymxpc2hSZWxheShtc2c6IFNTRVJlbGF5TWVzc2FnZSk6IHZvaWQge1xuICAgIHRoaXMucmVsYXk/LnB1Ymxpc2gobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhbGwgY2xpZW50cyBmb3IgYSBzcGVjaWZpYyByZXF1ZXN0XG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBSZXF1ZXN0IElEIHRvIGNsb3NlXG4gICAqIEBwYXJhbSBmaW5hbE1lc3NhZ2UgLSBPcHRpb25hbCBmaW5hbCBtZXNzYWdlIHRvIHNlbmQgYmVmb3JlIGNsb3NpbmdcbiAgICovXG4gIGNsb3NlUmVxdWVzdChyZXF1ZXN0SWQ6IHN0cmluZywgZmluYWxNZXNzYWdlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgcmVxdWVzdElkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTtcbiAgICBpZiAoIXRoaXMuY2xpZW50cy5oYXMocmVxdWVzdElkKSkgcmV0dXJuO1xuXG4gICAgLy8gTE9DQUwgb25seTogdGhpcyBjbG9zZXMgdGhpcyBwb2QncyBjbGllbnRzLCBzbyB0aGUgZmluYWwgZnJhbWUgaXMgZm9yIHRoZW1cbiAgICAvLyAocmVsYXlpbmcgaXQgd291bGQgcHVzaCBhIENPTVBMRVRFRCB0byBvdGhlciBwb2RzJyBzdGlsbC1vcGVuIHN0cmVhbXMpLlxuICAgIGlmIChmaW5hbE1lc3NhZ2UpIHtcbiAgICAgIHRoaXMuc2VuZExvY2FsKHJlcXVlc3RJZCwgeyB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCB0eXBlOiAnQ09NUExFVEVEJywgbWVzc2FnZTogZmluYWxNZXNzYWdlIH0pO1xuICAgIH1cblxuICAgIC8vIFJlYWQgdGhlIGVudHJ5IEFGVEVSIHRoZSBmaW5hbCB3cml0ZTogc2VuZExvY2FsIHJlbW92ZXMgKGFuZCB1bi1jb3VudHMpXG4gICAgLy8gY2xpZW50cyB0aGF0IHdlcmUgYWxyZWFkeSBnb25lLCBzbyBpdGVyYXRpbmcgYW4gZWFybGllciBzbmFwc2hvdCB3b3VsZFxuICAgIC8vIGRlY3JlbWVudCB0aGVpciBvcmcgY291bnQgYSBzZWNvbmQgdGltZS5cbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgPz8gW10pIHtcbiAgICAgIGNsZWFyVGltZW91dChjbGllbnQudGltZW91dCk7XG4gICAgICB0aGlzLmRlY3JlbWVudE9yZ0NvdW50KGNsaWVudC5vcmdJZCk7XG4gICAgICB0cnkge1xuICAgICAgICBjbGllbnQucmVzLmVuZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUmVzcG9uc2UgYWxyZWFkeSBjbG9zZWQgb24gcmVxdWVzdCBjbG9zZScsIHsgcmVxdWVzdElkLCBjbGllbnRJZDogY2xpZW50LmlkLCBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICB0aGlzLnVwZGF0ZUFjdGl2ZUdhdWdlKCk7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbG9zZWQgYWxsIGNsaWVudHMgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHN0YXRpc3RpY3MgYWJvdXQgY3VycmVudCBjb25uZWN0aW9uc1xuICAgKi9cbiAgZ2V0U3RhdHMoKTogU1NFTWFuYWdlclN0YXRzIHtcbiAgICBsZXQgdG90YWxDbGllbnRzID0gMDtcbiAgICBsZXQgb2xkZXN0Q29ubmVjdGlvbjogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgY2xpZW50cyBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIHtcbiAgICAgIHRvdGFsQ2xpZW50cyArPSBjbGllbnRzLmxlbmd0aDtcbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgICAgY29uc3QgYWdlID0gbm93IC0gY2xpZW50LmNvbm5lY3RlZEF0O1xuICAgICAgICBpZiAob2xkZXN0Q29ubmVjdGlvbiA9PT0gbnVsbCB8fCBhZ2UgPiBvbGRlc3RDb25uZWN0aW9uKSB7XG4gICAgICAgICAgb2xkZXN0Q29ubmVjdGlvbiA9IGFnZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0b3RhbFJlcXVlc3RzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgIHRvdGFsQ2xpZW50cyxcbiAgICAgIG9sZGVzdENvbm5lY3Rpb25Nczogb2xkZXN0Q29ubmVjdGlvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgcmVxdWVzdCBoYXMgYW55IGNvbm5lY3RlZCBjbGllbnRzXG4gICAqL1xuICBoYXNDbGllbnRzKHJlcXVlc3RJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQoU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSk7XG4gICAgcmV0dXJuIGNsaWVudHMgIT09IHVuZGVmaW5lZCAmJiBjbGllbnRzLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgY2xpZW50cyBmb3IgYSBzcGVjaWZpYyByZXF1ZXN0XG4gICAqL1xuICBnZXRDbGllbnRDb3VudChyZXF1ZXN0SWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50cy5nZXQoU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSk/Lmxlbmd0aCA/PyAwO1xuICB9XG5cbiAgLyoqXG4gICAqIE1pZGRsZXdhcmUgdG8gaW5pdGlhbGl6ZSBhIHRpY2tldC1hdXRoZW50aWNhdGVkIFNTRSBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBUaGUgc3RyZWFtIGlzIE5PVCBvcGVuIHRvIHRoZSB3b3JsZDogdGhlIGNhbGxlciBtdXN0IGZpcnN0IGV4Y2hhbmdlIGl0c1xuICAgKiBKV1QgZm9yIGEgc2hvcnQtbGl2ZWQgc2luZ2xlLXVzZSB0aWNrZXQgKHNlZSB7QGxpbmsgY3JlYXRlVGlja2V0fSwgd2lyZWQgdG9cbiAgICogYFBPU1QgL2xvZ3MvdGlja2V0YCkgYW5kIHBhc3MgaXQgYXMgYD90aWNrZXQ9PHQ+YC4gVGhlIG1pZGRsZXdhcmUgdmFsaWRhdGVzXG4gICAqICsgY29uc3VtZXMgdGhlIHRpY2tldCwgYmluZHMgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHRpY2tldCdzIG9yZywgYW5kXG4gICAqIGVuZm9yY2VzIHRoZSBwZXItb3JnIGNvbm5lY3Rpb24gY2FwLiBBIG1pc3NpbmcgLyBpbnZhbGlkIC8gZXhwaXJlZCAvXG4gICAqIGFscmVhZHktdXNlZCB0aWNrZXQgaXMgcmVqZWN0ZWQgd2l0aCA0MDEgYmVmb3JlIGFueSBTU0UgaGVhZGVycyBmbHVzaC5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuICAgKiBgYGBcbiAgICovXG4gIG1pZGRsZXdhcmUoKSB7XG4gICAgcmV0dXJuIGFzeW5jIChyZXE6IHsgcGFyYW1zOiB7IHJlcXVlc3RJZDogc3RyaW5nIH07IHF1ZXJ5PzogeyB0aWNrZXQ/OiB1bmtub3duIH0gfSwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgY29uc3QgeyByZXF1ZXN0SWQgfSA9IHJlcS5wYXJhbXM7XG5cbiAgICAgIGlmICghU1NFX1JFUVVFU1RfSURfUkUudGVzdChyZXF1ZXN0SWQpKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAwKS5lbmQoJ0ludmFsaWQgcmVxdWVzdElkIGZvcm1hdCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFRpY2tldCBhdXRoIOKAlCByZXF1aXJlZC4gUmVzb2x2ZSBgP3RpY2tldD08dD5gLCB0aGVuIHZhbGlkYXRlICsgY29uc3VtZVxuICAgICAgLy8gaXQgKHNpbmdsZS11c2UpIEZPUiBUSElTIFNVQkpFQ1QuIEFuIGFub255bW91cywgbWFsZm9ybWVkLCB1bmtub3duLFxuICAgICAgLy8gZXhwaXJlZCwgYWxyZWFkeS1jb25zdW1lZCwgb3Igd3Jvbmctc3ViamVjdCB0aWNrZXQgaXMgYSA0MDEuIFRoZSBvcmcgaXNcbiAgICAgIC8vIHRha2VuIGZyb20gdGhlIHRpY2tldCwgc28gdGhlIHN0cmVhbSBpcyBhbHdheXMgYm91bmQgdG8gYSB2ZXJpZmllZFxuICAgICAgLy8gdGVuYW50IEFORCB0byB0aGUgZXhhY3Qgc3ViamVjdCB0aGUgdGlja2V0IHdhcyBtaW50ZWQgZm9yIChubyBhbm9ueW1vdXNcbiAgICAgIC8vIHN0cmVhbXMsIG5vIGNyb3NzLXN1YmplY3QgYXR0YWNoKS5cbiAgICAgIGNvbnN0IHRpY2tldElkID0gcmVxLnF1ZXJ5Py50aWNrZXQ7XG4gICAgICBpZiAodHlwZW9mIHRpY2tldElkICE9PSAnc3RyaW5nJyB8fCB0aWNrZXRJZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDEpLmVuZCgnTWlzc2luZyB0aWNrZXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgY29uc3VtZWQgPSBhd2FpdCB0aGlzLmNvbnN1bWVUaWNrZXQodGlja2V0SWQsIHJlcXVlc3RJZCk7XG4gICAgICBpZiAoIWNvbnN1bWVkKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAxKS5lbmQoJ0ludmFsaWQgb3IgZXhwaXJlZCB0aWNrZXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3JnSWQgPSBjb25zdW1lZC5vcmdJZDtcblxuICAgICAgLy8gUHJlLWZsaWdodCBwZXItcmVxdWVzdCBjYXAgc28gd2UgY2FuIHJldHVybiA0MjkgYmVmb3JlIGZsdXNoaW5nXG4gICAgICAvLyBTU0UgaGVhZGVycyAoYWZ0ZXIgaGVhZGVycyBhcmUgZmx1c2hlZCB0aGUgY2xpZW50IGNhbid0IHJlYWQgYSA0MjkpLlxuICAgICAgLy9cbiAgICAgIC8vIE5PUk1BTElaRSBmaXJzdDogYGFkZENsaWVudGAga2V5cyB0aGUgbWFwIG9uIHRoZSBub3JtYWxpemVkIGZvcm1cbiAgICAgIC8vIChkYXNoZXMgc3RyaXBwZWQpLCBzbyByZWFkaW5nIHRoZSByYXcgYHJlcXVlc3RJZGAgaGVyZSBhbHdheXMgZm91bmQgMFxuICAgICAgLy8gZm9yIGEgY2xpZW50IHVzaW5nIHRoZSBkYXNoZWQgZm9ybS4gVGhlIGNhcCB3YXMgdGhlbiBvbmx5IGNhdWdodCBpbnNpZGVcbiAgICAgIC8vIGBhZGRDbGllbnRgIOKAlCBBRlRFUiBgZmx1c2hIZWFkZXJzKClgIOKAlCB3aGljaCBpcyBleGFjdGx5IHRoZSBjYXNlIHRoaXNcbiAgICAgIC8vIHByZS1mbGlnaHQgZXhpc3RzIHRvIGF2b2lkOiB0aGUgY2xpZW50IGdvdCBhIHNpbGVudGx5LWNsb3NlZCBzdHJlYW1cbiAgICAgIC8vIGluc3RlYWQgb2YgYSA0MjkuXG4gICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuY2xpZW50cy5nZXQoU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSkgfHwgW107XG4gICAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID49IHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYENsaWVudCBsaW1pdCByZWFjaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1BlclJlcXVlc3R9KWApO1xuICAgICAgICByZXMuc3RhdHVzKDQyOSkuZW5kKCdUb28gbWFueSBjb25uZWN0aW9ucyBmb3IgdGhpcyByZXF1ZXN0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU2FtZSBmb3IgdGhlIHBlci1vcmcgY2FwIOKAlCBiZXR0ZXIgdG8gc2VuZCA0MjkgdGhhbiBvcGVuIHRoZSBzdHJlYW0gYW5kXG4gICAgICAvLyBpbW1lZGlhdGVseSBjbG9zZSBpdC4gVGhlIHRpY2tldCBndWFyYW50ZWVzIGEgdmVyaWZpZWQgb3JnIGlkLCBzbyB0aGVcbiAgICAgIC8vIHBlci1vcmcgY2VpbGluZyBpcyBhbHdheXMgZW5mb3JjZWQgZm9yIHRoZSAvbG9ncyBzdHJlYW0uXG4gICAgICBpZiAoKHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMCkgPj0gdGhpcy5tYXhDbGllbnRzUGVyT3JnKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBQZXItb3JnIFNTRSBjbGllbnQgY2FwIHJlYWNoZWQgZm9yICR7b3JnSWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyT3JnfSlgKTtcbiAgICAgICAgcmVzLnN0YXR1cyg0MjkpLmVuZCgnVG9vIG1hbnkgU1NFIGNvbm5lY3Rpb25zIGZvciB0aGlzIG9yZ2FuaXphdGlvbicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHdyaXRlU3NlSGVhZGVycyhyZXMpO1xuICAgICAgcmVzLmZsdXNoSGVhZGVycygpO1xuXG4gICAgICAvLyBIZWFkZXJzIGFyZSBmbHVzaGVkIOKAlCB3ZSBjYW4gbm8gbG9uZ2VyIHNlbmQgYSA0MjkuIGFkZENsaWVudCByZS1jaGVja3NcbiAgICAgIC8vIHRoZSBjYXBzIChpbmNsdWRpbmcgdGhlIHByb2Nlc3Mtd2lkZSB0b3RhbC1jbGllbnRzIGNhcCwgd2hpY2ggdGhlXG4gICAgICAvLyBwcmUtZmxpZ2h0IGFib3ZlIGRvZXMgbm90KSBhbmQgY2FuIHN0aWxsIHJlamVjdCBvbiBhIHJhY2U6IGEgY29uY3VycmVudFxuICAgICAgLy8gY29ubmVjdGlvbiBtYXkgaGF2ZSBmaWxsZWQgYSBjYXAgYmV0d2VlbiB0aGUgcHJlLWZsaWdodCBjaGVjayBhbmQgaGVyZS5cbiAgICAgIC8vIE9uIHJlamVjdGlvbiwgY2xvc2UgdGhlIG5vdy1kYW5nbGluZyByZXNwb25zZSBpbnN0ZWFkIG9mIGxlYXZpbmcgYW5cbiAgICAgIC8vIG9wZW4gc29ja2V0IHdpdGggbm8gY2xpZW50IHJlY29yZCAod2hpY2ggd291bGQgbGVhayBhbiBmZCArIG5ldmVyIGVtaXRcbiAgICAgIC8vIHN0cmVhbSBkYXRhKS5cbiAgICAgIGNvbnN0IGFkZGVkID0gdGhpcy5hZGRDbGllbnQocmVxdWVzdElkLCByZXMsIG9yZ0lkKTtcbiAgICAgIGlmICghYWRkZWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFNTRSBhZGRDbGllbnQgcmVqZWN0ZWQgYWZ0ZXIgaGVhZGVycyBmbHVzaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfTsgY2xvc2luZyBkYW5nbGluZyByZXNwb25zZWApO1xuICAgICAgICB0cnkgeyByZXMuZW5kKCk7IH0gY2F0Y2ggeyAvKiBhbHJlYWR5IGNsb3NlZCAqLyB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBwZXJpb2RpYyBjbGVhbnVwIG9mIHN0YWxlIGNvbm5lY3Rpb25zXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0Q2xlYW51cEludGVydmFsKGludGVydmFsTXM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuY2xlYW51cEludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgfSwgaW50ZXJ2YWxNcyk7XG5cbiAgICAvLyBEb24ndCBwcmV2ZW50IHByb2Nlc3MgZXhpdFxuICAgIHRoaXMuY2xlYW51cEludGVydmFsLnVucmVmKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW4gdXAgc3RhbGUgY29ubmVjdGlvbnMgdXNpbmcgc2luZ2xlLXBhc3MgcGFydGl0aW9uLlxuICAgKiBPKFIgw5cgQykgaW5zdGVhZCBvZiBPKFIgw5cgQ8KyKSwgYW5kIGF2b2lkcyBtdXRhdGlvbi1kdXJpbmctaXRlcmF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBjbGVhbnVwKCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgbGV0IGNsZWFuZWQgPSAwO1xuXG4gICAgZm9yIChjb25zdCBbcmVxdWVzdElkLCBjbGllbnRzXSBvZiB0aGlzLmNsaWVudHMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCBzdGFsZTogU1NFQ2xpZW50W10gPSBbXTtcbiAgICAgIGNvbnN0IGFjdGl2ZTogU1NFQ2xpZW50W10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgICAvLyBUaW1lLWJhc2VkIGV2aWN0aW9uIE9SIGEgc29ja2V0IHRoYXQgc2lsZW50bHkgY2xvc2VkIChubyAnY2xvc2UnXG4gICAgICAgIC8vIGV2ZW50KSDigJQgTm9kZSBzb21ldGltZXMgZHJvcHMgc29ja2V0cyB3aXRob3V0IGZpcmluZyB0aGUgZXZlbnQsXG4gICAgICAgIC8vIHNvIHdlIGV4cGxpY2l0bHkgY2hlY2sgd3JpdGFibGVFbmRlZC9kZXN0cm95ZWQgaGVyZS5cbiAgICAgICAgY29uc3QgYWdlU3RhbGUgPSBub3cgLSBjbGllbnQuY29ubmVjdGVkQXQgPiB0aGlzLmNsaWVudFRpbWVvdXRNcztcbiAgICAgICAgY29uc3Qgc29ja2V0RGVhZCA9IGNsaWVudC5yZXMud3JpdGFibGVFbmRlZCB8fCAoY2xpZW50LnJlcyBhcyB7IGRlc3Ryb3llZD86IGJvb2xlYW4gfSkuZGVzdHJveWVkID09PSB0cnVlO1xuICAgICAgICBpZiAoYWdlU3RhbGUgfHwgc29ja2V0RGVhZCkge1xuICAgICAgICAgIHN0YWxlLnB1c2goY2xpZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY3RpdmUucHVzaChjbGllbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIHN0YWxlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjbGllbnQudGltZW91dCk7XG4gICAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoY2xpZW50Lm9yZ0lkKTtcbiAgICAgICAgdHJ5IHsgY2xpZW50LnJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgICAgY2xlYW5lZCsrO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aXZlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YWxlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIGFjdGl2ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNsZWFuZWQgPiAwKSB7XG4gICAgICBpbmNDb3VudGVyKCdzc2Vfc3RhbGVfY2xlYW5lZF90b3RhbCcsIHt9LCBjbGVhbmVkKTtcbiAgICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgICAgIGxvZ2dlci5pbmZvKGBDbGVhbmVkIHVwICR7Y2xlYW5lZH0gc3RhbGUgU1NFIGNvbm5lY3Rpb25zYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNodXRkb3duIHRoZSBTU0UgbWFuYWdlciBhbmQgY2xvc2UgYWxsIGNvbm5lY3Rpb25zXG4gICAqL1xuICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jbGVhbnVwSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdGhpcy5jbG9zZVJlcXVlc3QocmVxdWVzdElkLCAnU2VydmVyIHNodXR0aW5nIGRvd24nKTtcbiAgICB9XG5cbiAgICAvLyBUZWFyIGRvd24gdGhlIHJlbGF5J3MgUmVkaXMgY29ubmVjdGlvbnMgKGJlc3QtZWZmb3J0OyBuZXZlciB0aHJvd3MpLlxuICAgIHZvaWQgdGhpcy5yZWxheT8uY2xvc2UoKS5jYXRjaCgoKSA9PiB7IC8qIGFscmVhZHkgY2xvc2luZyAqLyB9KTtcbiAgICBpZiAodGhpcy5vd25zVGlja2V0U3RvcmUpIHRoaXMudGlja2V0U3RvcmVJbnN0YW5jZT8uc3RvcCgpO1xuXG4gICAgbG9nZ2VyLmluZm8oJ1NTRSBNYW5hZ2VyIHNodXQgZG93bicpO1xuICB9XG59XG4iXX0=
|
package/lib/http/sse-relay.d.ts
CHANGED
|
@@ -45,19 +45,30 @@ export interface RedisPubSubClient {
|
|
|
45
45
|
publish(channel: string, message: string): Promise<number>;
|
|
46
46
|
subscribe(...channels: string[]): Promise<unknown>;
|
|
47
47
|
on(event: 'message', cb: (channel: string, message: string) => void): void;
|
|
48
|
+
on(event: 'error', cb: (err: unknown) => void): void;
|
|
48
49
|
duplicate(): RedisPubSubClient;
|
|
49
50
|
quit(): Promise<unknown>;
|
|
50
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* The relay channel for one service. Every replica of a service shares it, and
|
|
54
|
+
* no other service does: an SSE subject (an org id, a build requestId) only has
|
|
55
|
+
* meaning inside the service whose clients subscribed to it, so a shared channel
|
|
56
|
+
* made every service's pods parse — and re-emit to same-named subjects — every
|
|
57
|
+
* other service's frames. `requestId` rides in the message body rather than the
|
|
58
|
+
* channel name so each pod SUBSCRIBES exactly once on startup — no per-subject
|
|
59
|
+
* subscribe/unsubscribe churn as clients come and go.
|
|
60
|
+
*/
|
|
61
|
+
export declare function sseRelayChannel(serviceName: string): string;
|
|
51
62
|
/**
|
|
52
63
|
* Redis-backed relay. Uses the given client for PUBLISH and a `duplicate()` for
|
|
53
64
|
* SUBSCRIBE (ioredis forbids mixing subscribe with normal commands on one
|
|
54
65
|
* connection). Publish is fire-and-forget with a swallowed rejection; a subscribe
|
|
55
66
|
* handler that throws is isolated so one bad frame can't kill the subscriber.
|
|
56
67
|
*/
|
|
57
|
-
export declare function createRedisSSERelay(publisher: RedisPubSubClient): SSERelay;
|
|
68
|
+
export declare function createRedisSSERelay(publisher: RedisPubSubClient, channel: string): SSERelay;
|
|
58
69
|
/**
|
|
59
|
-
* Build a Redis-backed SSE relay from the shared env Redis
|
|
60
|
-
*
|
|
61
|
-
*
|
|
70
|
+
* Build a Redis-backed SSE relay from the shared env Redis, on this service's
|
|
71
|
+
* own channel (`SERVICE_NAME`). Returns null when Redis isn't configured so the
|
|
72
|
+
* caller keeps local-only delivery.
|
|
62
73
|
*/
|
|
63
|
-
export declare function createEnvRedisSSERelay(): SSERelay | null;
|
|
74
|
+
export declare function createEnvRedisSSERelay(serviceName?: string): SSERelay | null;
|