@pipeline-builder/api-server 4.1.22 → 4.1.23

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.
@@ -1,9 +1,10 @@
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, createMemorySseTicketStore, envSseTicketCaps, SSE_TICKET_TTL_MS, writeSseHeaders, errorMessage, envInt } from '@pipeline-builder/api-core';
4
+ import { createLogger, writeSseHeaders, errorMessage, envInt } from '@pipeline-builder/api-core';
5
5
  import { CoreConstants } from '@pipeline-builder/pipeline-core';
6
6
  import { v7 as uuid } from 'uuid';
7
+ import { normalizeRequestId, SseTicketBroker } from './sse-ticket-broker.js';
7
8
  import { incCounter, setGauge } from '../api/metrics.js';
8
9
  const logger = createLogger('sse-manager');
9
10
  /**
@@ -39,17 +40,11 @@ export class SSEManager {
39
40
  * map mirrors `clients[].orgId` counts at all times. Orgs reach zero are
40
41
  * deleted to keep the map bounded. */
41
42
  orgClientCounts = new Map();
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;
43
+ /** Ticket minting / redemption + stream ownership (see ./sse-ticket-broker.ts). */
44
+ tickets;
46
45
  maxClientsPerRequest;
47
46
  maxTotalClients;
48
47
  maxClientsPerOrg;
49
- maxTotalTickets;
50
- maxTicketsPerOrg;
51
- ticketTtlMs;
52
- streamOwnerTtlMs;
53
48
  clientTimeoutMs;
54
49
  cleanupInterval = null;
55
50
  /** Cross-pod fan-out bus (undefined ⇒ local-only delivery). */
@@ -63,12 +58,13 @@ export class SSEManager {
63
58
  this.maxClientsPerRequest = options.maxClientsPerRequest ?? envInt('SSE_MAX_CLIENTS_PER_REQUEST', 10, { min: 1 });
64
59
  this.maxTotalClients = options.maxTotalClients ?? envInt('SSE_MAX_TOTAL_CLIENTS', 1000, { min: 1 });
65
60
  this.maxClientsPerOrg = options.maxClientsPerOrg ?? envInt('SSE_MAX_CLIENTS_PER_ORG', 50, { min: 1 });
66
- const ticketCaps = envSseTicketCaps();
67
- this.maxTotalTickets = options.maxTotalTickets ?? ticketCaps.maxTotal;
68
- this.maxTicketsPerOrg = options.maxTicketsPerOrg ?? ticketCaps.maxPerOrg;
69
- this.ticketTtlMs = options.ticketTtlMs ?? SSE_TICKET_TTL_MS;
70
- this.streamOwnerTtlMs = options.streamOwnerTtlMs ?? 3_600_000; // 1 hour
71
- this.ticketStoreInstance = options.ticketStore;
61
+ this.tickets = new SseTicketBroker({
62
+ store: options.ticketStore,
63
+ maxTotal: options.maxTotalTickets,
64
+ maxPerOrg: options.maxTicketsPerOrg,
65
+ ttlMs: options.ticketTtlMs,
66
+ ownerTtlMs: options.streamOwnerTtlMs,
67
+ });
72
68
  this.logStreamEnabled = options.logStream ?? false;
73
69
  this.clientTimeoutMs = options.clientTimeoutMs ?? envInt('SSE_CLIENT_TIMEOUT_MS', 1_800_000, { min: 1 }); // 30 minutes
74
70
  const cleanupIntervalMs = options.cleanupIntervalMs ?? envInt('SSE_CLEANUP_INTERVAL_MS', 300_000, { min: 1 }); // 5 minutes
@@ -97,18 +93,6 @@ export class SSEManager {
97
93
  if (relay)
98
94
  this.attachRelay(relay);
99
95
  }
100
- /** The ticket store, building the in-memory default on first use. */
101
- get ticketStore() {
102
- if (!this.ticketStoreInstance) {
103
- this.ticketStoreInstance = createMemorySseTicketStore({
104
- ttlMs: this.ticketTtlMs,
105
- maxTotal: this.maxTotalTickets,
106
- maxPerOrg: this.maxTicketsPerOrg,
107
- });
108
- this.ownsTicketStore = true;
109
- }
110
- return this.ticketStoreInstance;
111
- }
112
96
  /**
113
97
  * Handle a frame received from another pod via the relay. We already delivered
114
98
  * our OWN frames to local clients before publishing, so ignore our echo. A
@@ -146,123 +130,27 @@ export class SSEManager {
146
130
  return this.orgClientCounts.get(orgId) ?? 0;
147
131
  }
148
132
  /**
149
- * Canonical form of a requestId for equality checks: dashes stripped and
150
- * lowercased, so the dashed (api-server `uuid()`) and undashed (nginx
151
- * `$request_id`) renderings of the same id compare equal. Callers are
152
- * expected to have already format-validated against {@link SSE_REQUEST_ID_RE}.
153
- */
154
- static normalizeRequestId(requestId) {
155
- return requestId.replace(/-/g, '').toLowerCase();
156
- }
157
- /**
158
- * Canonical form of an orgId for ownership equality checks: trimmed and
159
- * lowercased. The stream PRODUCER (bindStreamOwner) and the ticket-minting
160
- * CONSUMER (createTicket) run in different services, so a casing / whitespace
161
- * drift between how each renders the same org would otherwise make the owner
162
- * comparison in {@link createTicket} false-`forbidden` the real owner.
163
- * Normalizing both sides — mirroring {@link normalizeRequestId} — closes that.
164
- */
165
- static normalizeOrgId(orgId) {
166
- return orgId.trim().toLowerCase();
167
- }
168
- /**
169
- * Record the org that OWNS a stream subject. The stream PRODUCER calls this
170
- * when it creates a build-log stream so that ticket minting can assert the
171
- * caller's org owns the subject (see {@link createTicket}). Backed by the
172
- * injected ticket store, so when a Redis store is wired the platform producer
173
- * (a different service sharing the same Redis) can bind ownership that this
174
- * service reads — closing the cross-tenant attach gap where any org could mint
175
- * a ticket for a guessed requestId.
176
- *
177
- * @param requestId - The stream subject (format-validated by the caller).
178
- * @param orgId - The owning org (normalized internally via normalizeOrgId).
133
+ * Record the org that OWNS a stream subject, so ticket minting can refuse a
134
+ * cross-tenant mint. Delegates to the ticket broker.
179
135
  */
180
136
  async bindStreamOwner(requestId, orgId) {
181
- await this.ticketStore.bindOwner(SSEManager.normalizeRequestId(requestId), SSEManager.normalizeOrgId(orgId), this.streamOwnerTtlMs);
137
+ await this.tickets.bindStreamOwner(requestId, orgId);
182
138
  }
183
139
  /**
184
- * Mint a short-lived, single-use SSE ticket bound to `orgId` AND a specific
185
- * stream subject (`requestId`). Clients POST to obtain one (JWT-authenticated)
186
- * for the exact stream they intend to open, then open the EventSource with
187
- * `?ticket=<t>` so the JWT never lands in a query string / access log. The
188
- * ticket can then only be consumed to open that one subject's stream — see
189
- * {@link consumeTicket} — which is what enforces per-subject authorization.
190
- *
191
- * ORG-OWNERSHIP: if a stream owner has been bound for this subject (via
192
- * {@link bindStreamOwner}) and it is a DIFFERENT org, minting is refused
193
- * (`reason: 'forbidden'`) — an org cannot mint a ticket for another org's
194
- * stream even if it guesses the requestId. When no owner is bound (producer
195
- * wiring not yet present), minting falls back to binding the ticket to the
196
- * caller's own org, preserving current behavior.
197
- *
198
- * Bounded by the ticket store's live-ticket caps (total and per org). An
199
- * ownership lookup the store can't answer is refused as `capacity`.
200
- *
201
- * @param orgId - Owning org (normalized internally via normalizeOrgId).
202
- * @param requestId - The build-log stream subject this ticket authorizes.
203
- * The caller must have format-validated it (see {@link SSE_REQUEST_ID_RE}).
204
- * @returns `{ ok: true, ticket }` on success, or `{ ok: false, reason }`
205
- * where reason is `'org-limit'`, `'capacity'`, or `'forbidden'`.
140
+ * Mint a short-lived, single-use ticket bound to `orgId` AND this stream
141
+ * subject — how a browser opens an EventSource without putting its JWT in a
142
+ * query string. Delegates to the ticket broker, which owns the ownership and
143
+ * cap rules.
206
144
  */
207
145
  async createTicket(orgId, requestId) {
208
- // Ownership gate first — a cross-tenant mint attempt should never even
209
- // consume cap budget. Only enforced when an owner is actually bound. Both
210
- // sides are org-normalized so a producer/consumer casing drift can't
211
- // false-`forbidden` the real owner (mirrors requestId normalization).
212
- const normalized = SSEManager.normalizeRequestId(requestId);
213
- const normalizedOrg = SSEManager.normalizeOrgId(orgId);
214
- let owner;
215
- try {
216
- owner = await this.ticketStore.getOwner(normalized);
217
- }
218
- catch (err) {
219
- // Can't tell who owns the subject — refuse rather than mint unchecked.
220
- logger.warn('SSE ticket refused: stream ownership lookup failed', { error: errorMessage(err) });
221
- incCounter('sse_ticket_rejected_total', { reason: 'capacity' });
222
- return { ok: false, reason: 'capacity' };
223
- }
224
- if (owner && owner !== normalizedOrg) {
225
- logger.warn(`SSE ticket refused: org ${normalizedOrg} does not own stream subject`);
226
- incCounter('sse_ticket_rejected_total', { reason: 'forbidden' });
227
- return { ok: false, reason: 'forbidden' };
228
- }
229
- const issued = await this.ticketStore.issue(normalizedOrg, normalized);
230
- if (!issued.ok) {
231
- const reason = issued.reason === 'org' ? 'org-limit' : 'capacity';
232
- logger.warn(`SSE ticket refused (${reason}) for ${normalizedOrg}`);
233
- incCounter('sse_ticket_rejected_total', { reason });
234
- return { ok: false, reason };
235
- }
236
- return { ok: true, ticket: issued.ticket };
146
+ return this.tickets.createTicket(orgId, requestId);
237
147
  }
238
148
  /**
239
- * Validate and CONSUME a ticket for a specific stream subject. Single-use:
240
- * the ticket is deleted whether or not it turns out to be valid, so a replay
241
- * of the same value always fails. Returns the bound org on success, or null
242
- * when the ticket is unknown / already-used / expired / OR was minted for a
243
- * DIFFERENT `requestId` than the one being opened.
244
- *
245
- * The subject check is the authorization fix: without it, a ticket minted for
246
- * one stream could be presented to open ANY stream the holder's org could
247
- * name, letting an authenticated org attach to another org's log stream by
248
- * guessing its requestId. The generic 401 the caller returns does not
249
- * distinguish "unknown ticket" from "wrong subject", so it leaks nothing
250
- * about which requestIds exist.
251
- *
252
- * @param ticketId - The opaque ticket value from `?ticket=`.
253
- * @param requestId - The stream subject from the URL path (`:requestId`),
254
- * already format-validated by the caller.
149
+ * Validate and CONSUME a ticket for a specific stream subject (single-use,
150
+ * subject-bound). Delegates to the ticket broker.
255
151
  */
256
152
  async consumeTicket(ticketId, requestId) {
257
- const ticket = await this.ticketStore.consume(ticketId); // single-use
258
- if (!ticket)
259
- return null;
260
- // Subject binding — reject a ticket presented for a subject it was not
261
- // minted for (including an unbound, org-channel ticket). Both sides are
262
- // normalized so dashed/undashed forms match.
263
- if (ticket.subject !== SSEManager.normalizeRequestId(requestId))
264
- return null;
265
- return { orgId: ticket.orgId };
153
+ return this.tickets.consumeTicket(ticketId, requestId);
266
154
  }
267
155
  /**
268
156
  * Adds a client to the SSE manager
@@ -282,7 +170,7 @@ export class SSEManager {
282
170
  // render it differently would otherwise key different Map entries — the client
283
171
  // registers under one and every send()/relay writes to another, dropping all
284
172
  // frames. Normalizing here (and in send/sendLocal/closeRequest/etc.) unifies them.
285
- requestId = SSEManager.normalizeRequestId(requestId);
173
+ requestId = normalizeRequestId(requestId);
286
174
  const existing = this.clients.get(requestId) || [];
287
175
  // Check client limit
288
176
  if (existing.length >= maxClientsForSubject) {
@@ -403,7 +291,7 @@ export class SSEManager {
403
291
  * @returns Number of clients the message was sent to
404
292
  */
405
293
  send(requestId, type, message, data) {
406
- requestId = SSEManager.normalizeRequestId(requestId); // unify producer/consumer key forms
294
+ requestId = normalizeRequestId(requestId); // unify producer/consumer key forms
407
295
  const payload = {
408
296
  ts: new Date().toISOString(),
409
297
  type,
@@ -424,7 +312,7 @@ export class SSEManager {
424
312
  * Never relays — callers decide whether to publish.
425
313
  */
426
314
  sendLocal(requestId, payload) {
427
- requestId = SSEManager.normalizeRequestId(requestId); // idempotent; covers the relay re-emit path
315
+ requestId = normalizeRequestId(requestId); // idempotent; covers the relay re-emit path
428
316
  const clients = [...(this.clients.get(requestId) || [])];
429
317
  let sentCount = 0;
430
318
  const serialized = `data: ${JSON.stringify(payload)}\n\n`;
@@ -503,7 +391,7 @@ export class SSEManager {
503
391
  * @param finalMessage - Optional final message to send before closing
504
392
  */
505
393
  closeRequest(requestId, finalMessage) {
506
- requestId = SSEManager.normalizeRequestId(requestId);
394
+ requestId = normalizeRequestId(requestId);
507
395
  if (!this.clients.has(requestId))
508
396
  return;
509
397
  // LOCAL only: this closes this pod's clients, so the final frame is for them
@@ -554,14 +442,14 @@ export class SSEManager {
554
442
  * Check if a request has any connected clients
555
443
  */
556
444
  hasClients(requestId) {
557
- const clients = this.clients.get(SSEManager.normalizeRequestId(requestId));
445
+ const clients = this.clients.get(normalizeRequestId(requestId));
558
446
  return clients !== undefined && clients.length > 0;
559
447
  }
560
448
  /**
561
449
  * Get the number of clients for a specific request
562
450
  */
563
451
  getClientCount(requestId) {
564
- return this.clients.get(SSEManager.normalizeRequestId(requestId))?.length ?? 0;
452
+ return this.clients.get(normalizeRequestId(requestId))?.length ?? 0;
565
453
  }
566
454
  /**
567
455
  * Middleware to initialize a ticket-authenticated SSE connection.
@@ -611,7 +499,7 @@ export class SSEManager {
611
499
  // `addClient` — AFTER `flushHeaders()` — which is exactly the case this
612
500
  // pre-flight exists to avoid: the client got a silently-closed stream
613
501
  // instead of a 429.
614
- const existing = this.clients.get(SSEManager.normalizeRequestId(requestId)) || [];
502
+ const existing = this.clients.get(normalizeRequestId(requestId)) || [];
615
503
  if (existing.length >= this.maxClientsPerRequest) {
616
504
  logger.warn(`Client limit reached for request ${requestId} (max: ${this.maxClientsPerRequest})`);
617
505
  res.status(429).end('Too many connections for this request');
@@ -712,9 +600,8 @@ export class SSEManager {
712
600
  }
713
601
  // Tear down the relay's Redis connections (best-effort; never throws).
714
602
  void this.relay?.close().catch(() => { });
715
- if (this.ownsTicketStore)
716
- this.ticketStoreInstance?.stop();
603
+ this.tickets.shutdown();
717
604
  logger.info('SSE Manager shut down');
718
605
  }
719
606
  }
720
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsMEJBQTBCLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUF1QixZQUFZLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkwsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhFLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBMEczQzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcscUVBQXFFLENBQUM7QUFnQnZHOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBQ2IsT0FBTyxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO0lBQ2pEOzsyQ0FFdUM7SUFDL0IsZUFBZSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQ3BELHlGQUF5RjtJQUNqRixtQkFBbUIsQ0FBa0I7SUFDN0MsNEVBQTRFO0lBQ3BFLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDZixvQkFBb0IsQ0FBUztJQUM3QixlQUFlLENBQVM7SUFDeEIsZ0JBQWdCLENBQVM7SUFDekIsZUFBZSxDQUFTO0lBQ3hCLGdCQUFnQixDQUFTO0lBQ3pCLFdBQVcsQ0FBUztJQUNwQixnQkFBZ0IsQ0FBUztJ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ZUFBZTtZQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUUzRCxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDdkMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBjcmVhdGVNZW1vcnlTc2VUaWNrZXRTdG9yZSwgZW52U3NlVGlja2V0Q2FwcywgU1NFX1RJQ0tFVF9UVExfTVMsIHdyaXRlU3NlSGVhZGVycywgdHlwZSBTc2VUaWNrZXRTdG9yZSwgZXJyb3JNZXNzYWdlLCBlbnZJbnQgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBDb3JlQ29uc3RhbnRzIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtY29yZSc7XG5pbXBvcnQgdHlwZSB7IFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyB2NyBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgdHlwZSB7IFNTRVJlbGF5LCBTU0VSZWxheU1lc3NhZ2UgfSBmcm9tICcuL3NzZS1yZWxheS5qcyc7XG5pbXBvcnQgeyBpbmNDb3VudGVyLCBzZXRHYXVnZSB9IGZyb20gJy4uL2FwaS9tZXRyaWNzLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdzc2UtbWFuYWdlcicpO1xuXG4vKipcbiAqIEV2ZW50IHR5cGVzIGZvciBTU0UgbG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBTU0VFdmVudFR5cGUgPSAnSU5GTycgfCAnV0FSTicgfCAnRVJST1InIHwgJ0NPTVBMRVRFRCcgfCAnUk9MTEJBQ0snIHwgJ01FU1NBR0UnO1xuXG4vKipcbiAqIFNTRSBwYXlsb2FkIHN0cnVjdHVyZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRVBheWxvYWQge1xuICB0czogc3RyaW5nO1xuICB0eXBlOiBTU0VFdmVudFR5cGU7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgZGF0YT86IHVua25vd247XG59XG5cbi8qKlxuICogU1NFIGNsaWVudCB3aXRoIGNvbm5lY3Rpb24gdHJhY2tpbmdcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTU0VDbGllbnQge1xuICBpZDogc3RyaW5nO1xuICByZXM6IFJlc3BvbnNlO1xuICBjb25uZWN0ZWRBdDogbnVtYmVyO1xuICB0aW1lb3V0OiBOb2RlSlMuVGltZW91dDtcbiAgLyoqIE51bWJlciBvZiBjb25zZWN1dGl2ZSBiYWNrcHJlc3N1cmUgZXZlbnRzICh3cml0ZSByZXR1cm5lZCBmYWxzZSkuICovXG4gIGJhY2twcmVzc3VyZUNvdW50OiBudW1iZXI7XG4gIC8qKiBPd25pbmcgb3JnIGlkIOKAlCBwb3B1bGF0ZWQgd2hlbiB0aGUgcmVxdWVzdCB3YXMgYXV0aGVudGljYXRlZC4gVXNlZCB0b1xuICAgKiAgZGVjcmVtZW50IHRoZSBwZXItb3JnIGNvdW50ZXIgb24gZGlzY29ubmVjdCAvIGNsZWFudXAuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFNTRSBNYW5hZ2VyIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRU1hbmFnZXJPcHRpb25zIHtcbiAgLyoqIE1heGltdW0gY2xpZW50cyBhbGxvd2VkIHBlciByZXF1ZXN0IElEIChkZWZhdWx0OiAxMCkgKi9cbiAgbWF4Q2xpZW50c1BlclJlcXVlc3Q/OiBudW1iZXI7XG4gIC8qKiBDbGllbnQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDMwIG1pbnV0ZXMpICovXG4gIGNsaWVudFRpbWVvdXRNcz86IG51bWJlcjtcbiAgLyoqIEludGVydmFsIGZvciBjbGVhbnVwIGNoZWNrcyBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDUgbWludXRlcykgKi9cbiAgY2xlYW51cEludGVydmFsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIYXJkIGNhcCBvbiB0b3RhbCBvcGVuIGNvbm5lY3Rpb25zIHBlciBwcm9jZXNzLiBEZWZhdWx0cyB0byAxMDAwIGZyb21cbiAgICogYFNTRV9NQVhfVE9UQUxfQ0xJRU5UU2AuIE5ldyBjb25uZWN0aW9ucyBiZXlvbmQgdGhpcyBhcmUgcmVqZWN0ZWQgYXRcbiAgICogYGFkZENsaWVudCgpYC4gVHVuZSB1cCBpZiB5b3VyIHNlcnZpY2Ugc2VydmVzID4gMTAwMCBjb25jdXJyZW50IFNTRVxuICAgKiBkYXNoYm9hcmRzLCBidXQgYmUgYXdhcmUgTm9kZS5qcyBmZCBsaW1pdHMgZG9taW5hdGUgYWJvdmUgfjUwMDAuXG4gICAqL1xuICBtYXhUb3RhbENsaWVudHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQZXItb3JnIGNlaWxpbmcgb24gY29uY3VycmVudCBTU0Ugc3RyZWFtcy4gRGVmYXVsdHMgdG8gNTAgZnJvbVxuICAgKiBgU1NFX01BWF9DTElFTlRTX1BFUl9PUkdgLiBQcm90ZWN0cyBhZ2FpbnN0IG9uZSBub2lzeSBvcmcgY29uc3VtaW5nIHRoZVxuICAgKiBwcm9jZXNzLXdpZGUgYnVkZ2V0IOKAlCB3aXRob3V0IGl0LCBhbiBhdXRoZW50aWNhdGVkIHVzZXIgY2FuIGZhbiBvdXRcbiAgICogdGhvdXNhbmRzIG9mIHN0cmVhbXMgKG9uZSBwZXIgZGFzaGJvYXJkIC8gbG9nIHN0cmVhbSkgYW5kIHN0YXJ2ZSBvdGhlclxuICAgKiBvcmdzIG9mIGNvbm5lY3Rpb24gc2xvdHMuIFRoZSBjYXAgaXMgZW5mb3JjZWQgb25seSBvbiBgYWRkQ2xpZW50YCBjYWxsc1xuICAgKiB0aGF0IGNhcnJ5IGFuIGBvcmdJZGA7IHNlcnZpY2UtaW50ZXJuYWwgLyBhbm9ueW1vdXMgU1NFIHRyYWZmaWMgc2tpcHMgaXQuXG4gICAqL1xuICBtYXhDbGllbnRzUGVyT3JnPzogbnVtYmVyO1xuICAvKipcbiAgICogQ2FwIG9uIGxpdmUgbG9nLXN0cmVhbSB0aWNrZXRzIGFjcm9zcyB0aGUgcHJvY2VzcywgZm9yIHRoZSBERUZBVUxUXG4gICAqIGluLW1lbW9yeSB0aWNrZXQgc3RvcmUuIERlZmF1bHRzIHRvIDEwMDAgZnJvbSBgU1NFX01BWF9UT1RBTF9USUNLRVRTYC5cbiAgICogSWdub3JlZCB3aGVuIGB0aWNrZXRTdG9yZWAgaXMgaW5qZWN0ZWQgKHRoZSBzdG9yZSBjYXJyaWVzIGl0cyBvd24gY2FwcykuXG4gICAqL1xuICBtYXhUb3RhbFRpY2tldHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQZXItb3JnIGNhcCBvbiBsaXZlIGxvZy1zdHJlYW0gdGlja2V0cywgZm9yIHRoZSBERUZBVUxUIGluLW1lbW9yeSB0aWNrZXRcbiAgICogc3RvcmUuIERlZmF1bHRzIHRvIDEwIGZyb20gYFNTRV9NQVhfVElDS0VUU19QRVJfT1JHYC4gSWdub3JlZCB3aGVuXG4gICAqIGB0aWNrZXRTdG9yZWAgaXMgaW5qZWN0ZWQuXG4gICAqL1xuICBtYXhUaWNrZXRzUGVyT3JnPzogbnVtYmVyO1xuICAvKiogVGlja2V0IFRUTCBpbiBtcyBmb3IgdGhlIGRlZmF1bHQgc3RvcmUgKGRlZmF1bHQ6IGBTU0VfVElDS0VUX1RUTF9NU2AgZnJvbSBhcGktY29yZSkuICovXG4gIHRpY2tldFR0bE1zPzogbnVtYmVyO1xuICAvKipcbiAgICogVGlja2V0ICsgc3RyZWFtLW93bmVyc2hpcCBiYWNrZW5kIGZvciB0aGUgc3ViamVjdC1ib3VuZCBsb2cgc3RyZWFtLiBEZWZhdWx0c1xuICAgKiB0byBhbiBpbi1tZW1vcnkgc3RvcmUgKHNpbmdsZSByZXBsaWNhIG9ubHkpLCBidWlsdCBvbiBmaXJzdCB1c2UuIEluamVjdCBhblxuICAgKiBhcGktY29yZSBgY3JlYXRlRW52U3NlVGlja2V0U3RvcmUoLi4uKWAgc28gbWludC9yZWRlZW0gYW5kIHN0cmVhbSBvd25lcnNoaXBcbiAgICogd29yayBhY3Jvc3MgcG9kcy5cbiAgICovXG4gIHRpY2tldFN0b3JlPzogU3NlVGlja2V0U3RvcmU7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgc2VydmljZSBzdHJlYW1zIHBlci1yZXF1ZXN0IGxvZ3MgKGBjdHgubG9nYCBmcmFtZXMga2V5ZWQgYnlcbiAgICogcmVxdWVzdElkLCB0aGUgYC9sb2dzYCBjaGFubmVsKS4gRGVmYXVsdCBmYWxzZTogYGN0eC5sb2dgIHRoZW4gb25seSB3cml0ZXNcbiAgICogdG8gdGhlIGxvZ2dlciwgc28gYSBzZXJ2aWNlIHRoYXQgbmV2ZXIgc2VydmVzIGEgbG9nIHN0cmVhbSBkb2Vzbid0IHB1c2hcbiAgICogZXZlcnkgbG9nIGxpbmUgdGhyb3VnaCBTU0UgKGFuZCBvdmVyIFJlZGlzKS5cbiAgICovXG4gIGxvZ1N0cmVhbT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBUVEwgZm9yIGEgc3RyZWFtLW93bmVyc2hpcCBiaW5kaW5nIChkZWZhdWx0OiBgU1NFX1NUUkVBTV9PV05FUl9UVExfTVNgIGVudiBvclxuICAgKiAxaCkuIExvbmcgZW5vdWdoIHRvIG91dGxpdmUgYSBidWlsZDsgdGhlIHByb2R1Y2VyIHJlLWJpbmRzIGFzIG5lZWRlZC5cbiAgICovXG4gIHN0cmVhbU93bmVyVHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDcm9zcy1wb2QgZmFuLW91dCBidXMgZm9yIGBzZW5kKClgL2Bicm9hZGNhc3QoKWAsIHdpcmVkIGF0IGNvbnN0cnVjdGlvbi5cbiAgICogV2hlbiBvbWl0dGVkIChhbmQgbm8gYHJlbGF5RmFjdG9yeWAgaXMgZW5hYmxlZCkgZGVsaXZlcnkgaXMgTE9DQUwtT05MWS5cbiAgICogRGVncmFkZXMgdG8gbG9jYWwtb25seSBkdXJpbmcgYSBSZWRpcyBvdXRhZ2UuXG4gICAqL1xuICByZWxheT86IFNTRVJlbGF5O1xuICAvKipcbiAgICogQnVpbGRzIHRoZSByZWxheSBvbiBkZW1hbmQg4oCUIHNlZSB7QGxpbmsgU1NFTWFuYWdlci5lbmFibGVSZWxheX0uIExldHMgYVxuICAgKiBzZXJ2aWNlIG9wZW4gYSByZWxheSBjb25uZWN0aW9uIG9ubHkgd2hlbiBpdCBhY3R1YWxseSBoYXMgYSBzdHJlYW1pbmdcbiAgICogY2hhbm5lbCAodGhlIGxvZyBzdHJlYW0sIG9yIGFuIG9yZy1rZXllZCBjaGFubmVsKS4gUmV0dXJuaW5nIG51bGwgKFJlZGlzXG4gICAqIG5vdCBjb25maWd1cmVkKSBrZWVwcyBsb2NhbC1vbmx5IGRlbGl2ZXJ5LlxuICAgKi9cbiAgcmVsYXlGYWN0b3J5PzogKCkgPT4gU1NFUmVsYXkgfCBudWxsO1xufVxuXG4vKipcbiAqIEEgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IGlkOiBlaXRoZXIgYSBkYXNoZWQgVVVJRCAoYXBpLXNlcnZlcidzIGB1dWlkKClgKVxuICogb3IgbmdpbngncyBgJHJlcXVlc3RfaWRgIOKAlCAxNiByYW5kb20gYnl0ZXMgcmVuZGVyZWQgYXMgMzIgaGV4IGNoYXJzIHdpdGggTk9cbiAqIGRhc2hlcy4gQWNjZXB0IGJvdGggYnkgbWFraW5nIHRoZSBncm91cCBzZXBhcmF0b3JzIG9wdGlvbmFsOyBzdGlsbCBzdHJpY3RseVxuICogMzIgaGV4IGNoYXJzIHNvIGl0IGNhbid0IGNhcnJ5IGFuIGluamVjdGlvbiAvIHBhdGgtdHJhdmVyc2FsIHBheWxvYWQgaW50byB0aGVcbiAqIFNTRSBzdWJqZWN0LiBTaGFyZWQgYnkgdGhlIHRpY2tldC1taW50IHJvdXRlIGFuZCB0aGUgc3RyZWFtIG1pZGRsZXdhcmUgc29cbiAqIGJvdGggdmFsaWRhdGUgdGhlIHN1YmplY3QgaWRlbnRpY2FsbHkuXG4gKi9cbmV4cG9ydCBjb25zdCBTU0VfUkVRVUVTVF9JRF9SRSA9IC9eWzAtOWEtZl17OH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezEyfSQvaTtcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgU1NFTWFuYWdlci5jcmVhdGVUaWNrZXR9LiAqL1xuZXhwb3J0IHR5cGUgQ3JlYXRlVGlja2V0UmVzdWx0ID1cbiAgfCB7IG9rOiB0cnVlOyB0aWNrZXQ6IHN0cmluZyB9XG4gIHwgeyBvazogZmFsc2U7IHJlYXNvbjogJ29yZy1saW1pdCcgfCAnY2FwYWNpdHknIHwgJ2ZvcmJpZGRlbicgfTtcblxuLyoqXG4gKiBTU0UgTWFuYWdlciBzdGF0aXN0aWNzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlclN0YXRzIHtcbiAgdG90YWxSZXF1ZXN0czogbnVtYmVyO1xuICB0b3RhbENsaWVudHM6IG51bWJlcjtcbiAgb2xkZXN0Q29ubmVjdGlvbk1zOiBudW1iZXIgfCBudWxsO1xufVxuXG4vKipcbiAqIFNTRSBoZWxwZXIgY2xhc3Mgd2l0aCBtZW1vcnkgbGVhayBwcm90ZWN0aW9uXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIENsaWVudCBsaW1pdHMgcGVyIHJlcXVlc3QgSURcbiAqIC0gQXV0b21hdGljIHRpbWVvdXQgZm9yIGlkbGUgY29ubmVjdGlvbnNcbiAqIC0gUGVyaW9kaWMgY2xlYW51cCBvZiBzdGFsZSBjb25uZWN0aW9uc1xuICogLSBDb25uZWN0aW9uIHN0YXRpc3RpY3NcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc3NlTWFuYWdlciA9IG5ldyBTU0VNYW5hZ2VyKHsgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IDUgfSk7XG4gKiBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuICpcbiAqIC8vIFNlbmQgZXZlbnRzXG4gKiBzc2VNYW5hZ2VyLnNlbmQoJ3JlcXVlc3QtMTIzJywgJ0lORk8nLCAnUHJvY2Vzc2luZy4uLicpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTU0VNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBjbGllbnRzID0gbmV3IE1hcDxzdHJpbmcsIFNTRUNsaWVudFtdPigpO1xuICAvKiogUGVyLW9yZyBvcGVuLWNsaWVudCBjb3VudGVycy4gRGVjcmVtZW50ZWQgb24gcmVtb3ZlQ2xpZW50L2NsZWFudXAgc28gdGhlXG4gICAqICBtYXAgbWlycm9ycyBgY2xpZW50c1tdLm9yZ0lkYCBjb3VudHMgYXQgYWxsIHRpbWVzLiBPcmdzIHJlYWNoIHplcm8gYXJlXG4gICAqICBkZWxldGVkIHRvIGtlZXAgdGhlIG1hcCBib3VuZGVkLiAqL1xuICBwcml2YXRlIG9yZ0NsaWVudENvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiBJbmplY3RlZCB0aWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQsIG9yIHRoZSBsYXppbHkgYnVpbHQgaW4tbWVtb3J5IGRlZmF1bHQuICovXG4gIHByaXZhdGUgdGlja2V0U3RvcmVJbnN0YW5jZT86IFNzZVRpY2tldFN0b3JlO1xuICAvKiogVHJ1ZSB3aGVuIHRoaXMgbWFuYWdlciBidWlsdCBpdHMgdGlja2V0IHN0b3JlIChzbyBzaHV0ZG93biBzdG9wcyBpdCkuICovXG4gIHByaXZhdGUgb3duc1RpY2tldFN0b3JlID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbENsaWVudHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VG90YWxUaWNrZXRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VGlja2V0c1Blck9yZzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHRpY2tldFR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyZWFtT3duZXJUdGxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRpbWVvdXRNczogbnVtYmVyO1xuICBwcml2YXRlIGNsZWFudXBJbnRlcnZhbDogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgLyoqIENyb3NzLXBvZCBmYW4tb3V0IGJ1cyAodW5kZWZpbmVkIOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5KS4gKi9cbiAgcHJpdmF0ZSByZWxheT86IFNTRVJlbGF5O1xuICBwcml2YXRlIHJlYWRvbmx5IHJlbGF5RmFjdG9yeT86ICgpID0+IFNTRVJlbGF5IHwgbnVsbDtcbiAgLyoqIFdoZXRoZXIgYGN0eC5sb2dgIGZyYW1lcyBhcmUgc3RyZWFtZWQgKHNlZSB7QGxpbmsgU1NFTWFuYWdlck9wdGlvbnMubG9nU3RyZWFtfSkuICovXG4gIHJlYWRvbmx5IGxvZ1N0cmVhbUVuYWJsZWQ6IGJvb2xlYW47XG4gIC8qKiBUaGlzIG1hbmFnZXIgaW5zdGFuY2UncyBpZCDigJQgdGFncyByZWxheWVkIGZyYW1lcyBzbyB3ZSBpZ25vcmUgb3VyIG93biBlY2hvLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IG5vZGVJZCA9IHJhbmRvbUJ5dGVzKDgpLnRvU3RyaW5nKCdoZXgnKTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBTU0VNYW5hZ2VyT3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdCA9IG9wdGlvbnMubWF4Q2xpZW50c1BlclJlcXVlc3QgPz8gZW52SW50KCdTU0VfTUFYX0NMSUVOVFNfUEVSX1JFUVVFU1QnLCAxMCwgeyBtaW46IDEgfSk7XG4gICAgdGhpcy5tYXhUb3RhbENsaWVudHMgPSBvcHRpb25zLm1heFRvdGFsQ2xpZW50cyA/PyBlbnZJbnQoJ1NTRV9NQVhfVE9UQUxfQ0xJRU5UUycsIDEwMDAsIHsgbWluOiAxIH0pO1xuICAgIHRoaXMubWF4Q2xpZW50c1Blck9yZyA9IG9wdGlvbnMubWF4Q2xpZW50c1Blck9yZyA/PyBlbnZJbnQoJ1NTRV9NQVhfQ0xJRU5UU19QRVJfT1JHJywgNTAsIHsgbWluOiAxIH0pO1xuICAgIGNvbnN0IHRpY2tldENhcHMgPSBlbnZTc2VUaWNrZXRDYXBzKCk7XG4gICAgdGhpcy5tYXhUb3RhbFRpY2tldHMgPSBvcHRpb25zLm1heFRvdGFsVGlja2V0cyA/PyB0aWNrZXRDYXBzLm1heFRvdGFsO1xuICAgIHRoaXMubWF4VGlja2V0c1Blck9yZyA9IG9wdGlvbnMubWF4VGlja2V0c1Blck9yZyA/PyB0aWNrZXRDYXBzLm1heFBlck9yZztcbiAgICB0aGlzLnRpY2tldFR0bE1zID0gb3B0aW9ucy50aWNrZXRUdGxNcyA/PyBTU0VfVElDS0VUX1RUTF9NUztcbiAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMgPSBvcHRpb25zLnN0cmVhbU93bmVyVHRsTXMgPz8gM182MDBfMDAwOyAvLyAxIGhvdXJcbiAgICB0aGlzLnRpY2tldFN0b3JlSW5zdGFuY2UgPSBvcHRpb25zLnRpY2tldFN0b3JlO1xuICAgIHRoaXMubG9nU3RyZWFtRW5hYmxlZCA9IG9wdGlvbnMubG9nU3RyZWFtID8/IGZhbHNlO1xuICAgIHRoaXMuY2xpZW50VGltZW91dE1zID0gb3B0aW9ucy5jbGllbnRUaW1lb3V0TXMgPz8gZW52SW50KCdTU0VfQ0xJRU5UX1RJTUVPVVRfTVMnLCAxXzgwMF8wMDAsIHsgbWluOiAxIH0pOyAvLyAzMCBtaW51dGVzXG5cbiAgICBjb25zdCBjbGVhbnVwSW50ZXJ2YWxNcyA9IG9wdGlvbnMuY2xlYW51cEludGVydmFsTXMgPz8gZW52SW50KCdTU0VfQ0xFQU5VUF9JTlRFUlZBTF9NUycsIDMwMF8wMDAsIHsgbWluOiAxIH0pOyAvLyA1IG1pbnV0ZXNcbiAgICB0aGlzLnN0YXJ0Q2xlYW51cEludGVydmFsKGNsZWFudXBJbnRlcnZhbE1zKTtcblxuICAgIC8vIFdpcmUgdGhlIGNyb3NzLXBvZCByZWxheTogc3Vic2NyaWJlIG9uY2Ugb24gc3RhcnR1cCBzbyBmcmFtZXMgUFVCTElTSEVEIGJ5XG4gICAgLy8gYW55IG90aGVyIHBvZCBhcmUgcmUtZW1pdHRlZCB0byBUSElTIHBvZCdzIGxvY2FsIGNsaWVudHMuIEZyYW1lcyB3ZVxuICAgIC8vIHB1Ymxpc2hlZCBvdXJzZWx2ZXMgYXJlIGlnbm9yZWQgKG9yaWdpbiA9PT0gbm9kZUlkKSDigJQgd2UgYWxyZWFkeSB3cm90ZSB0aGVtXG4gICAgLy8gbG9jYWxseS4gRmFpbC1zYWZlOiBubyByZWxheSDih5IgbG9jYWwtb25seSBkZWxpdmVyeSAoc2luZ2xlLXJlcGxpY2EgZGVmYXVsdCkuXG4gICAgdGhpcy5yZWxheUZhY3RvcnkgPSBvcHRpb25zLnJlbGF5RmFjdG9yeTtcbiAgICBpZiAob3B0aW9ucy5yZWxheSkgdGhpcy5hdHRhY2hSZWxheShvcHRpb25zLnJlbGF5KTtcbiAgfVxuXG4gIHByaXZhdGUgYXR0YWNoUmVsYXkocmVsYXk6IFNTRVJlbGF5KTogdm9pZCB7XG4gICAgdGhpcy5yZWxheSA9IHJlbGF5O1xuICAgIHJlbGF5LnN1YnNjcmliZSgobXNnKSA9PiB0aGlzLm9uUmVsYXlNZXNzYWdlKG1zZykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFR1cm4gb24gY3Jvc3MtcG9kIGRlbGl2ZXJ5IHVzaW5nIHRoZSBjb25maWd1cmVkIGByZWxheUZhY3RvcnlgLiBJZGVtcG90ZW50O1xuICAgKiBhIG5vLW9wIHdoZW4gYSByZWxheSBpcyBhbHJlYWR5IHdpcmVkIG9yIG5vIGZhY3Rvcnkgd2FzIGdpdmVuLCBhbmQgd2hlbiB0aGVcbiAgICogZmFjdG9yeSByZXR1cm5zIG51bGwgKFJlZGlzIG5vdCBjb25maWd1cmVkIOKGkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5KS5cbiAgICovXG4gIGVuYWJsZVJlbGF5KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJlbGF5IHx8ICF0aGlzLnJlbGF5RmFjdG9yeSkgcmV0dXJuO1xuICAgIGNvbnN0IHJlbGF5ID0gdGhpcy5yZWxheUZhY3RvcnkoKTtcbiAgICBpZiAocmVsYXkpIHRoaXMuYXR0YWNoUmVsYXkocmVsYXkpO1xuICB9XG5cbiAgLyoqIFRoZSB0aWNrZXQgc3RvcmUsIGJ1aWxkaW5nIHRoZSBpbi1tZW1vcnkgZGVmYXVsdCBvbiBmaXJzdCB1c2UuICovXG4gIHByaXZhdGUgZ2V0IHRpY2tldFN0b3JlKCk6IFNzZVRpY2tldFN0b3JlIHtcbiAgICBpZiAoIXRoaXMudGlja2V0U3RvcmVJbnN0YW5jZSkge1xuICAgICAgdGhpcy50aWNrZXRTdG9yZUluc3RhbmNlID0gY3JlYXRlTWVtb3J5U3NlVGlja2V0U3RvcmUoe1xuICAgICAgICB0dGxNczogdGhpcy50aWNrZXRUdGxNcyxcbiAgICAgICAgbWF4VG90YWw6IHRoaXMubWF4VG90YWxUaWNrZXRzLFxuICAgICAgICBtYXhQZXJPcmc6IHRoaXMubWF4VGlja2V0c1Blck9yZyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vd25zVGlja2V0U3RvcmUgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50aWNrZXRTdG9yZUluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBhIGZyYW1lIHJlY2VpdmVkIGZyb20gYW5vdGhlciBwb2QgdmlhIHRoZSByZWxheS4gV2UgYWxyZWFkeSBkZWxpdmVyZWRcbiAgICogb3VyIE9XTiBmcmFtZXMgdG8gbG9jYWwgY2xpZW50cyBiZWZvcmUgcHVibGlzaGluZywgc28gaWdub3JlIG91ciBlY2hvLiBBXG4gICAqIGBzZW5kYCByZS1lbWl0cyB0byB0aGUgc3ViamVjdCdzIGxvY2FsIGNsaWVudHM7IGEgYGJyb2FkY2FzdGAgdG8gYWxsIG9mIHRoZW0uXG4gICAqIFB1cmVseSBsb2NhbCDigJQgbmV2ZXIgcmUtcHVibGlzaGVzLCBzbyB0aGVyZSBpcyBubyBmYW4tb3V0IGxvb3AuXG4gICAqL1xuICBwcml2YXRlIG9uUmVsYXlNZXNzYWdlKG1zZzogU1NFUmVsYXlNZXNzYWdlKTogdm9pZCB7XG4gICAgaWYgKCFtc2cgfHwgbXNnLm9yaWdpbiA9PT0gdGhpcy5ub2RlSWQpIHJldHVybjtcbiAgICBpZiAobXNnLmtpbmQgPT09ICdicm9hZGNhc3QnKSB7XG4gICAgICB0aGlzLmJyb2FkY2FzdExvY2FsKG1zZy5wYXlsb2FkKTtcbiAgICB9IGVsc2UgaWYgKG1zZy5yZXF1ZXN0SWQpIHtcbiAgICAgIHRoaXMuc2VuZExvY2FsKG1zZy5yZXF1ZXN0SWQsIG1zZy5wYXlsb2FkKTtcbiAgICB9XG4gIH1cblxuICAvKiogVG90YWwgb3BlbiBjb25uZWN0aW9ucyBhY3Jvc3MgYWxsIHJlcXVlc3RzLiAqL1xuICBwcml2YXRlIHRvdGFsQ2xpZW50cygpOiBudW1iZXIge1xuICAgIGxldCBuID0gMDtcbiAgICBmb3IgKGNvbnN0IGNsaWVudHMgb2YgdGhpcy5jbGllbnRzLnZhbHVlcygpKSBuICs9IGNsaWVudHMubGVuZ3RoO1xuICAgIHJldHVybiBuO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdGhlIGN1cnJlbnQgbGl2ZS1jb25uZWN0aW9uIGNvdW50IGFzIGEgZ2F1Z2Ugc28gb24tY2FsbCBjYW4gc2VlIFNTRVxuICAgKiBzYXR1cmF0aW9uIChhcHByb2FjaCB0byB0aGUgcGVyLXByb2Nlc3MgY2FwKSBvbiBhIGRhc2hib2FyZCwgbm90IG9ubHkgaW5cbiAgICogYGdldFN0YXRzKClgL2xvZ3MuIENhbGxlZCBhZnRlciBldmVyeSBhZGQvcmVtb3ZlL1xuICAgKiBjbG9zZS9jbGVhbnVwLiBDaGVhcCAoTyhSKSk7IG1ldHJpYyBoZWxwZXJzIG5ldmVyIHRocm93LlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVBY3RpdmVHYXVnZSgpOiB2b2lkIHtcbiAgICBzZXRHYXVnZSgnc3NlX2FjdGl2ZV9jb25uZWN0aW9ucycsIHt9LCB0aGlzLnRvdGFsQ2xpZW50cygpKTtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IG9wZW4tc3RyZWFtIGNvdW50IGZvciBhbiBvcmcgKDAgaWYgdW5zZWVuKS4gKi9cbiAgZ2V0T3JnQ2xpZW50Q291bnQob3JnSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhIHJlcXVlc3RJZCBmb3IgZXF1YWxpdHkgY2hlY2tzOiBkYXNoZXMgc3RyaXBwZWQgYW5kXG4gICAqIGxvd2VyY2FzZWQsIHNvIHRoZSBkYXNoZWQgKGFwaS1zZXJ2ZXIgYHV1aWQoKWApIGFuZCB1bmRhc2hlZCAobmdpbnhcbiAgICogYCRyZXF1ZXN0X2lkYCkgcmVuZGVyaW5ncyBvZiB0aGUgc2FtZSBpZCBjb21wYXJlIGVxdWFsLiBDYWxsZXJzIGFyZVxuICAgKiBleHBlY3RlZCB0byBoYXZlIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBhZ2FpbnN0IHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0uXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXF1ZXN0SWQucmVwbGFjZSgvLS9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhbiBvcmdJZCBmb3Igb3duZXJzaGlwIGVxdWFsaXR5IGNoZWNrczogdHJpbW1lZCBhbmRcbiAgICogbG93ZXJjYXNlZC4gVGhlIHN0cmVhbSBQUk9EVUNFUiAoYmluZFN0cmVhbU93bmVyKSBhbmQgdGhlIHRpY2tldC1taW50aW5nXG4gICAqIENPTlNVTUVSIChjcmVhdGVUaWNrZXQpIHJ1biBpbiBkaWZmZXJlbnQgc2VydmljZXMsIHNvIGEgY2FzaW5nIC8gd2hpdGVzcGFjZVxuICAgKiBkcmlmdCBiZXR3ZWVuIGhvdyBlYWNoIHJlbmRlcnMgdGhlIHNhbWUgb3JnIHdvdWxkIG90aGVyd2lzZSBtYWtlIHRoZSBvd25lclxuICAgKiBjb21wYXJpc29uIGluIHtAbGluayBjcmVhdGVUaWNrZXR9IGZhbHNlLWBmb3JiaWRkZW5gIHRoZSByZWFsIG93bmVyLlxuICAgKiBOb3JtYWxpemluZyBib3RoIHNpZGVzIOKAlCBtaXJyb3Jpbmcge0BsaW5rIG5vcm1hbGl6ZVJlcXVlc3RJZH0g4oCUIGNsb3NlcyB0aGF0LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbm9ybWFsaXplT3JnSWQob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG9yZ0lkLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCB0aGUgb3JnIHRoYXQgT1dOUyBhIHN0cmVhbSBzdWJqZWN0LiBUaGUgc3RyZWFtIFBST0RVQ0VSIGNhbGxzIHRoaXNcbiAgICogd2hlbiBpdCBjcmVhdGVzIGEgYnVpbGQtbG9nIHN0cmVhbSBzbyB0aGF0IHRpY2tldCBtaW50aW5nIGNhbiBhc3NlcnQgdGhlXG4gICAqIGNhbGxlcidzIG9yZyBvd25zIHRoZSBzdWJqZWN0IChzZWUge0BsaW5rIGNyZWF0ZVRpY2tldH0pLiBCYWNrZWQgYnkgdGhlXG4gICAqIGluamVjdGVkIHRpY2tldCBzdG9yZSwgc28gd2hlbiBhIFJlZGlzIHN0b3JlIGlzIHdpcmVkIHRoZSBwbGF0Zm9ybSBwcm9kdWNlclxuICAgKiAoYSBkaWZmZXJlbnQgc2VydmljZSBzaGFyaW5nIHRoZSBzYW1lIFJlZGlzKSBjYW4gYmluZCBvd25lcnNoaXAgdGhhdCB0aGlzXG4gICAqIHNlcnZpY2UgcmVhZHMg4oCUIGNsb3NpbmcgdGhlIGNyb3NzLXRlbmFudCBhdHRhY2ggZ2FwIHdoZXJlIGFueSBvcmcgY291bGQgbWludFxuICAgKiBhIHRpY2tldCBmb3IgYSBndWVzc2VkIHJlcXVlc3RJZC5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBzdHJlYW0gc3ViamVjdCAoZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyKS5cbiAgICogQHBhcmFtIG9yZ0lkIC0gVGhlIG93bmluZyBvcmcgKG5vcm1hbGl6ZWQgaW50ZXJuYWxseSB2aWEgbm9ybWFsaXplT3JnSWQpLlxuICAgKi9cbiAgYXN5bmMgYmluZFN0cmVhbU93bmVyKHJlcXVlc3RJZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5iaW5kT3duZXIoXG4gICAgICBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpLFxuICAgICAgU1NFTWFuYWdlci5ub3JtYWxpemVPcmdJZChvcmdJZCksXG4gICAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaW50IGEgc2hvcnQtbGl2ZWQsIHNpbmdsZS11c2UgU1NFIHRpY2tldCBib3VuZCB0byBgb3JnSWRgIEFORCBhIHNwZWNpZmljXG4gICAqIHN0cmVhbSBzdWJqZWN0IChgcmVxdWVzdElkYCkuIENsaWVudHMgUE9TVCB0byBvYnRhaW4gb25lIChKV1QtYXV0aGVudGljYXRlZClcbiAgICogZm9yIHRoZSBleGFjdCBzdHJlYW0gdGhleSBpbnRlbmQgdG8gb3BlbiwgdGhlbiBvcGVuIHRoZSBFdmVudFNvdXJjZSB3aXRoXG4gICAqIGA/dGlja2V0PTx0PmAgc28gdGhlIEpXVCBuZXZlciBsYW5kcyBpbiBhIHF1ZXJ5IHN0cmluZyAvIGFjY2VzcyBsb2cuIFRoZVxuICAgKiB0aWNrZXQgY2FuIHRoZW4gb25seSBiZSBjb25zdW1lZCB0byBvcGVuIHRoYXQgb25lIHN1YmplY3QncyBzdHJlYW0g4oCUIHNlZVxuICAgKiB7QGxpbmsgY29uc3VtZVRpY2tldH0g4oCUIHdoaWNoIGlzIHdoYXQgZW5mb3JjZXMgcGVyLXN1YmplY3QgYXV0aG9yaXphdGlvbi5cbiAgICpcbiAgICogT1JHLU9XTkVSU0hJUDogaWYgYSBzdHJlYW0gb3duZXIgaGFzIGJlZW4gYm91bmQgZm9yIHRoaXMgc3ViamVjdCAodmlhXG4gICAqIHtAbGluayBiaW5kU3RyZWFtT3duZXJ9KSBhbmQgaXQgaXMgYSBESUZGRVJFTlQgb3JnLCBtaW50aW5nIGlzIHJlZnVzZWRcbiAgICogKGByZWFzb246ICdmb3JiaWRkZW4nYCkg4oCUIGFuIG9yZyBjYW5ub3QgbWludCBhIHRpY2tldCBmb3IgYW5vdGhlciBvcmcnc1xuICAgKiBzdHJlYW0gZXZlbiBpZiBpdCBndWVzc2VzIHRoZSByZXF1ZXN0SWQuIFdoZW4gbm8gb3duZXIgaXMgYm91bmQgKHByb2R1Y2VyXG4gICAqIHdpcmluZyBub3QgeWV0IHByZXNlbnQpLCBtaW50aW5nIGZhbGxzIGJhY2sgdG8gYmluZGluZyB0aGUgdGlja2V0IHRvIHRoZVxuICAgKiBjYWxsZXIncyBvd24gb3JnLCBwcmVzZXJ2aW5nIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAqXG4gICAqIEJvdW5kZWQgYnkgdGhlIHRpY2tldCBzdG9yZSdzIGxpdmUtdGlja2V0IGNhcHMgKHRvdGFsIGFuZCBwZXIgb3JnKS4gQW5cbiAgICogb3duZXJzaGlwIGxvb2t1cCB0aGUgc3RvcmUgY2FuJ3QgYW5zd2VyIGlzIHJlZnVzZWQgYXMgYGNhcGFjaXR5YC5cbiAgICpcbiAgICogQHBhcmFtIG9yZ0lkIC0gT3duaW5nIG9yZyAobm9ybWFsaXplZCBpbnRlcm5hbGx5IHZpYSBub3JtYWxpemVPcmdJZCkuXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBUaGUgYnVpbGQtbG9nIHN0cmVhbSBzdWJqZWN0IHRoaXMgdGlja2V0IGF1dGhvcml6ZXMuXG4gICAqICAgVGhlIGNhbGxlciBtdXN0IGhhdmUgZm9ybWF0LXZhbGlkYXRlZCBpdCAoc2VlIHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0pLlxuICAgKiBAcmV0dXJucyBgeyBvazogdHJ1ZSwgdGlja2V0IH1gIG9uIHN1Y2Nlc3MsIG9yIGB7IG9rOiBmYWxzZSwgcmVhc29uIH1gXG4gICAqICAgd2hlcmUgcmVhc29uIGlzIGAnb3JnLWxpbWl0J2AsIGAnY2FwYWNpdHknYCwgb3IgYCdmb3JiaWRkZW4nYC5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZVRpY2tldChvcmdJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8Q3JlYXRlVGlja2V0UmVzdWx0PiB7XG4gICAgLy8gT3duZXJzaGlwIGdhdGUgZmlyc3Qg4oCUIGEgY3Jvc3MtdGVuYW50IG1pbnQgYXR0ZW1wdCBzaG91bGQgbmV2ZXIgZXZlblxuICAgIC8vIGNvbnN1bWUgY2FwIGJ1ZGdldC4gT25seSBlbmZvcmNlZCB3aGVuIGFuIG93bmVyIGlzIGFjdHVhbGx5IGJvdW5kLiBCb3RoXG4gICAgLy8gc2lkZXMgYXJlIG9yZy1ub3JtYWxpemVkIHNvIGEgcHJvZHVjZXIvY29uc3VtZXIgY2FzaW5nIGRyaWZ0IGNhbid0XG4gICAgLy8gZmFsc2UtYGZvcmJpZGRlbmAgdGhlIHJlYWwgb3duZXIgKG1pcnJvcnMgcmVxdWVzdElkIG5vcm1hbGl6YXRpb24pLlxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRPcmcgPSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZU9yZ0lkKG9yZ0lkKTtcbiAgICBsZXQgb3duZXI6IHN0cmluZyB8IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIG93bmVyID0gYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5nZXRPd25lcihub3JtYWxpemVkKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIC8vIENhbid0IHRlbGwgd2hvIG93bnMgdGhlIHN1YmplY3Qg4oCUIHJlZnVzZSByYXRoZXIgdGhhbiBtaW50IHVuY2hlY2tlZC5cbiAgICAgIGxvZ2dlci53YXJuKCdTU0UgdGlja2V0IHJlZnVzZWQ6IHN0cmVhbSBvd25lcnNoaXAgbG9va3VwIGZhaWxlZCcsIHsgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgaW5jQ291bnRlcignc3NlX3RpY2tldF9yZWplY3RlZF90b3RhbCcsIHsgcmVhc29uOiAnY2FwYWNpdHknIH0pO1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCByZWFzb246ICdjYXBhY2l0eScgfTtcbiAgICB9XG4gICAgaWYgKG93bmVyICYmIG93bmVyICE9PSBub3JtYWxpemVkT3JnKSB7XG4gICAgICBsb2dnZXIud2FybihgU1NFIHRpY2tldCByZWZ1c2VkOiBvcmcgJHtub3JtYWxpemVkT3JnfSBkb2VzIG5vdCBvd24gc3RyZWFtIHN1YmplY3RgKTtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV90aWNrZXRfcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ2ZvcmJpZGRlbicgfSk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ2ZvcmJpZGRlbicgfTtcbiAgICB9XG5cbiAgICBjb25zdCBpc3N1ZWQgPSBhd2FpdCB0aGlzLnRpY2tldFN0b3JlLmlzc3VlKG5vcm1hbGl6ZWRPcmcsIG5vcm1hbGl6ZWQpO1xuICAgIGlmICghaXNzdWVkLm9rKSB7XG4gICAgICBjb25zdCByZWFzb24gPSBpc3N1ZWQucmVhc29uID09PSAnb3JnJyA/ICdvcmctbGltaXQnIDogJ2NhcGFjaXR5JztcbiAgICAgIGxvZ2dlci53YXJuKGBTU0UgdGlja2V0IHJlZnVzZWQgKCR7cmVhc29ufSkgZm9yICR7bm9ybWFsaXplZE9yZ31gKTtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV90aWNrZXRfcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbiB9KTtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uIH07XG4gICAgfVxuICAgIHJldHVybiB7IG9rOiB0cnVlLCB0aWNrZXQ6IGlzc3VlZC50aWNrZXQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbmQgQ09OU1VNRSBhIHRpY2tldCBmb3IgYSBzcGVjaWZpYyBzdHJlYW0gc3ViamVjdC4gU2luZ2xlLXVzZTpcbiAgICogdGhlIHRpY2tldCBpcyBkZWxldGVkIHdoZXRoZXIgb3Igbm90IGl0IHR1cm5zIG91dCB0byBiZSB2YWxpZCwgc28gYSByZXBsYXlcbiAgICogb2YgdGhlIHNhbWUgdmFsdWUgYWx3YXlzIGZhaWxzLiBSZXR1cm5zIHRoZSBib3VuZCBvcmcgb24gc3VjY2Vzcywgb3IgbnVsbFxuICAgKiB3aGVuIHRoZSB0aWNrZXQgaXMgdW5rbm93biAvIGFscmVhZHktdXNlZCAvIGV4cGlyZWQgLyBPUiB3YXMgbWludGVkIGZvciBhXG4gICAqIERJRkZFUkVOVCBgcmVxdWVzdElkYCB0aGFuIHRoZSBvbmUgYmVpbmcgb3BlbmVkLlxuICAgKlxuICAgKiBUaGUgc3ViamVjdCBjaGVjayBpcyB0aGUgYXV0aG9yaXphdGlvbiBmaXg6IHdpdGhvdXQgaXQsIGEgdGlja2V0IG1pbnRlZCBmb3JcbiAgICogb25lIHN0cmVhbSBjb3VsZCBiZSBwcmVzZW50ZWQgdG8gb3BlbiBBTlkgc3RyZWFtIHRoZSBob2xkZXIncyBvcmcgY291bGRcbiAgICogbmFtZSwgbGV0dGluZyBhbiBhdXRoZW50aWNhdGVkIG9yZyBhdHRhY2ggdG8gYW5vdGhlciBvcmcncyBsb2cgc3RyZWFtIGJ5XG4gICAqIGd1ZXNzaW5nIGl0cyByZXF1ZXN0SWQuIFRoZSBnZW5lcmljIDQwMSB0aGUgY2FsbGVyIHJldHVybnMgZG9lcyBub3RcbiAgICogZGlzdGluZ3Vpc2ggXCJ1bmtub3duIHRpY2tldFwiIGZyb20gXCJ3cm9uZyBzdWJqZWN0XCIsIHNvIGl0IGxlYWtzIG5vdGhpbmdcbiAgICogYWJvdXQgd2hpY2ggcmVxdWVzdElkcyBleGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHRpY2tldElkIC0gVGhlIG9wYXF1ZSB0aWNrZXQgdmFsdWUgZnJvbSBgP3RpY2tldD1gLlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVGhlIHN0cmVhbSBzdWJqZWN0IGZyb20gdGhlIFVSTCBwYXRoIChgOnJlcXVlc3RJZGApLFxuICAgKiAgIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBieSB0aGUgY2FsbGVyLlxuICAgKi9cbiAgYXN5bmMgY29uc3VtZVRpY2tldCh0aWNrZXRJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IFByb21pc2U8eyBvcmdJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgY29uc3QgdGlja2V0ID0gYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5jb25zdW1lKHRpY2tldElkKTsgLy8gc2luZ2xlLXVzZVxuICAgIGlmICghdGlja2V0KSByZXR1cm4gbnVsbDtcbiAgICAvLyBTdWJqZWN0IGJpbmRpbmcg4oCUIHJlamVjdCBhIHRpY2tldCBwcmVzZW50ZWQgZm9yIGEgc3ViamVjdCBpdCB3YXMgbm90XG4gICAgLy8gbWludGVkIGZvciAoaW5jbHVkaW5nIGFuIHVuYm91bmQsIG9yZy1jaGFubmVsIHRpY2tldCkuIEJvdGggc2lkZXMgYXJlXG4gICAgLy8gbm9ybWFsaXplZCBzbyBkYXNoZWQvdW5kYXNoZWQgZm9ybXMgbWF0Y2guXG4gICAgaWYgKHRpY2tldC5zdWJqZWN0ICE9PSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4geyBvcmdJZDogdGlja2V0Lm9yZ0lkIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIGNsaWVudCB0byB0aGUgU1NFIG1hbmFnZXJcbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFVuaXF1ZSByZXF1ZXN0IElEXG4gICAqIEBwYXJhbSByZXMgLSBFeHByZXNzIFJlc3BvbnNlIG9iamVjdFxuICAgKiBAcGFyYW0gb3JnSWQgLSBBdXRoZW50aWNhdGVkIG9yZyBpZCAob3B0aW9uYWwpLiBXaGVuIHNldCwgZW5mb3JjZXMgdGhlXG4gICAqICAgcGVyLW9yZyBjYXAgYW5kIHRoZSBjb3VudGVyIGlzIGRlY3JlbWVudGVkIG9uIGRpc2Nvbm5lY3QvY2xlYW51cC5cbiAgICogQHBhcmFtIG1heENsaWVudHNGb3JTdWJqZWN0IC0gUGVyLXN1YmplY3QgY2FwIG92ZXJyaWRlIChkZWZhdWx0XG4gICAqICAgYG1heENsaWVudHNQZXJSZXF1ZXN0YCkuIEFuIG9yZy1rZXllZCBjaGFubmVsJ3Mgc3ViamVjdCBJUyB0aGUgb3JnLCBzbyBpdFxuICAgKiAgIG11c3Qgbm90IGluaGVyaXQgdGhlIHNtYWxsIHBlci1idWlsZC1yZXF1ZXN0IGNhcCDigJQgc2VlIHtAbGluayBhZGRPcmdDbGllbnR9LlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIGNsaWVudCB3YXMgYWRkZWQsIGZhbHNlIGlmIHJlamVjdGVkIChsaW1pdCByZWFjaGVkKVxuICAgKi9cbiAgYWRkQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCByZXM6IFJlc3BvbnNlLCBvcmdJZD86IHN0cmluZywgbWF4Q2xpZW50c0ZvclN1YmplY3Q6IG51bWJlciA9IHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QpOiBib29sZWFuIHtcbiAgICAvLyBOb3JtYWxpemUgdGhlIG1hcCBrZXk6IHRoZSBzdWJqZWN0IGlkIGlzIGFsbG93ZWQgaW4gdHdvIGZvcm1zIChkYXNoZWRcbiAgICAvLyBhcGktc2VydmVyIHV1aWQgdnMgdW5kYXNoZWQgbmdpbnggJHJlcXVlc3RfaWQpLCBhbmQgYSBwcm9kdWNlci9jb25zdW1lciB0aGF0XG4gICAgLy8gcmVuZGVyIGl0IGRpZmZlcmVudGx5IHdvdWxkIG90aGVyd2lzZSBrZXkgZGlmZmVyZW50IE1hcCBlbnRyaWVzIOKAlCB0aGUgY2xpZW50XG4gICAgLy8gcmVnaXN0ZXJzIHVuZGVyIG9uZSBhbmQgZXZlcnkgc2VuZCgpL3JlbGF5IHdyaXRlcyB0byBhbm90aGVyLCBkcm9wcGluZyBhbGxcbiAgICAvLyBmcmFtZXMuIE5vcm1hbGl6aW5nIGhlcmUgKGFuZCBpbiBzZW5kL3NlbmRMb2NhbC9jbG9zZVJlcXVlc3QvZXRjLikgdW5pZmllcyB0aGVtLlxuICAgIHJlcXVlc3RJZCA9IFNTRU1hbmFnZXIubm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZCk7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgfHwgW107XG5cbiAgICAvLyBDaGVjayBjbGllbnQgbGltaXRcbiAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID49IG1heENsaWVudHNGb3JTdWJqZWN0KSB7XG4gICAgICBsb2dnZXIud2FybihgQ2xpZW50IGxpbWl0IHJlYWNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9IChtYXg6ICR7bWF4Q2xpZW50c0ZvclN1YmplY3R9KWApO1xuICAgICAgaW5jQ291bnRlcignc3NlX2Nvbm5lY3Rpb25fcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ3JlcXVlc3QtbGltaXQnIH0pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFByb2Nlc3Mtd2lkZSBjYXA6IHByb3RlY3RzIGZkIHRhYmxlICsgbWVtb3J5IGZyb20gcnVuYXdheSBkYXNoYm9hcmRzLlxuICAgIGlmICh0aGlzLnRvdGFsQ2xpZW50cygpID49IHRoaXMubWF4VG90YWxDbGllbnRzKSB7XG4gICAgICBsb2dnZXIud2FybihgVG90YWwgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCAobWF4OiAke3RoaXMubWF4VG90YWxDbGllbnRzfSk7IHJlamVjdGluZyBuZXcgY29ubmVjdGlvbmApO1xuICAgICAgaW5jQ291bnRlcignc3NlX2Nvbm5lY3Rpb25fcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ3RvdGFsLWNhcCcgfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUGVyLW9yZyBjYXA6IHByZXZlbnRzIG9uZSBub2lzeSBvcmcgZnJvbSBtb25vcG9saXppbmcgcHJvY2Vzcy13aWRlXG4gICAgLy8gc2xvdHMuIEVuZm9yY2VkIG9ubHkgd2hlbiBvcmdJZCBpcyBrbm93biDigJQgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91c1xuICAgIC8vIHN0cmVhbXMgdGhhdCBuZXZlciBpZGVudGlmeSB3aXRoIGFuIG9yZ0lkIHN0YXkgc3ViamVjdCB0byB0aGUgZ2xvYmFsXG4gICAgLy8gY2VpbGluZ3MgYWJvdmUuIFJlc2VydmUgYXRvbWljYWxseSBiZWZvcmUgaW5zZXJ0IHNvIHR3byBjb25jdXJyZW50XG4gICAgLy8gcmVxdWVzdHMgYXQgdGhlIGxpbWl0IGNhbid0IGJvdGggc3VjY2VlZC5cbiAgICBpZiAob3JnSWQpIHtcbiAgICAgIGNvbnN0IG9yZ0N1cnJlbnQgPSB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gICAgICBpZiAob3JnQ3VycmVudCA+PSB0aGlzLm1heENsaWVudHNQZXJPcmcpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJPcmd9KTsgcmVqZWN0aW5nIG5ldyBjb25uZWN0aW9uYCk7XG4gICAgICAgIGluY0NvdW50ZXIoJ3NzZV9jb25uZWN0aW9uX3JlamVjdGVkX3RvdGFsJywgeyByZWFzb246ICdvcmctY2FwJyB9KTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhpcy5vcmdDbGllbnRDb3VudHMuc2V0KG9yZ0lkLCBvcmdDdXJyZW50ICsgMSk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHRpbWVvdXQgZm9yIHRoaXMgY2xpZW50XG4gICAgY29uc3QgY2xpZW50SWQgPSB1dWlkKCk7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgbG9nZ2VyLmRlYnVnKGBDbGllbnQgJHtjbGllbnRJZH0gdGltZWQgb3V0IGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfWApO1xuICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnRJZCk7XG4gICAgICB0cnkge1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdSZXNwb25zZSBhbHJlYWR5IGNsb3NlZCBvbiB0aW1lb3V0JywgeyByZXF1ZXN0SWQsIGNsaWVudElkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5jbGllbnRUaW1lb3V0TXMpO1xuXG4gICAgY29uc3QgY2xpZW50OiBTU0VDbGllbnQgPSB7XG4gICAgICBpZDogY2xpZW50SWQsXG4gICAgICByZXMsXG4gICAgICBjb25uZWN0ZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgIHRpbWVvdXQsXG4gICAgICBiYWNrcHJlc3N1cmVDb3VudDogMCxcbiAgICAgIG9yZ0lkLFxuICAgIH07XG5cbiAgICAvLyBIYW5kbGUgZGlzY29ubmVjdGlvblxuICAgIHJlcy5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudElkKTtcbiAgICB9KTtcblxuICAgIHJlcy5vbignZXJyb3InLCAoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFNTRSBjbGllbnQgZXJyb3IgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9OmAsIGVycik7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudElkKTtcbiAgICB9KTtcblxuICAgIGV4aXN0aW5nLnB1c2goY2xpZW50KTtcbiAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgZXhpc3RpbmcpO1xuICAgIGluY0NvdW50ZXIoJ3NzZV9jb25uZWN0aW9uc190b3RhbCcsIHt9KTtcbiAgICB0aGlzLnVwZGF0ZUFjdGl2ZUdhdWdlKCk7XG5cbiAgICBsb2dnZXIuZGVidWcoYENsaWVudCAke2NsaWVudElkfSBjb25uZWN0ZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9ICh0b3RhbDogJHtleGlzdGluZy5sZW5ndGh9KWApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaCBhIGNsaWVudCB0byBhbiBPUkcta2V5ZWQgc3RyZWFtICh0aGUgb3JnIGlzIHRoZSBzdWJqZWN0KS4gQ291bnRzXG4gICAqIGFnYWluc3QgdGhlIHBlci1vcmcgY2FwLCBhbmQgdGhlIG9yZyDigJQgbm90IHRoZSBwZXItcmVxdWVzdCBjYXAg4oCUIGJvdW5kcyBob3dcbiAgICogbWFueSBzdHJlYW1zIHNoYXJlIHRoZSBzdWJqZWN0LlxuICAgKi9cbiAgYWRkT3JnQ2xpZW50KG9yZ0lkOiBzdHJpbmcsIHJlczogUmVzcG9uc2UpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5hZGRDbGllbnQob3JnSWQsIHJlcywgb3JnSWQsIHRoaXMubWF4Q2xpZW50c1Blck9yZyk7XG4gIH1cblxuICAvKiogRHJvcCBvbmUgZnJvbSB0aGUgcGVyLW9yZyBjb3VudGVyLiBJZGVtcG90ZW50OiBhIGNvdW50ZXIgYXQgMCBzdGF5cyBhdCAwXG4gICAqICBhbmQgdGhlIG9yZyBrZXkgaXMgcmVtb3ZlZCBmcm9tIHRoZSBtYXAuICovXG4gIHByaXZhdGUgZGVjcmVtZW50T3JnQ291bnQob3JnSWQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIW9yZ0lkKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgICBpZiAoY3VycmVudCA8PSAxKSB0aGlzLm9yZ0NsaWVudENvdW50cy5kZWxldGUob3JnSWQpO1xuICAgIGVsc2UgdGhpcy5vcmdDbGllbnRDb3VudHMuc2V0KG9yZ0lkLCBjdXJyZW50IC0gMSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGNsaWVudCBmcm9tIHRoZSBtYW5hZ2VyXG4gICAqL1xuICBwcml2YXRlIHJlbW92ZUNsaWVudChyZXF1ZXN0SWQ6IHN0cmluZywgY2xpZW50SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCk7XG4gICAgaWYgKCFjbGllbnRzKSByZXR1cm47XG5cbiAgICBjb25zdCByZW1haW5pbmcgPSBjbGllbnRzLmZpbHRlcihjID0+IHtcbiAgICAgIGlmIChjLmlkID09PSBjbGllbnRJZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQoYy50aW1lb3V0KTtcbiAgICAgICAgLy8gTWlycm9yIHRoZSBwZXItb3JnIGNvdW50ZXIg4oCUIG11c3QgZGVjcmVtZW50IGhlcmUsIG5vdCBqdXN0IGluIHRoZVxuICAgICAgICAvLyBleHBsaWNpdCBjbG9zZSBwYXRocywgc2luY2UgJ2Nsb3NlJy8nZXJyb3InIGV2ZW50IGhhbmRsZXJzIGFyZSB0aGVcbiAgICAgICAgLy8gcHJpbWFyeSBkaXNjb25uZWN0IHNpZ25hbCBpbiBwcmFjdGljZS5cbiAgICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjLm9yZ0lkKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG5cbiAgICBpZiAocmVtYWluaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbGllbnRzLmRlbGV0ZShyZXF1ZXN0SWQpO1xuICAgICAgbG9nZ2VyLmRlYnVnKGBBbGwgY2xpZW50cyBkaXNjb25uZWN0ZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2xpZW50cy5zZXQocmVxdWVzdElkLCByZW1haW5pbmcpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUFjdGl2ZUdhdWdlKCk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZHMgYSBtZXNzYWdlIHRvIGFsbCBTU0UgY2xpZW50cyBmb3IgYSByZXF1ZXN0SWRcbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFJlcXVlc3QgSURcbiAgICogQHBhcmFtIHR5cGUgLSBFdmVudCB0eXBlXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gTWVzc2FnZSBzdHJpbmdcbiAgICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBhZGRpdGlvbmFsIGRhdGFcbiAgICogQHJldHVybnMgTnVtYmVyIG9mIGNsaWVudHMgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgdG9cbiAgICovXG4gIHNlbmQocmVxdWVzdElkOiBzdHJpbmcsIHR5cGU6IFNTRUV2ZW50VHlwZSwgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bik6IG51bWJlciB7XG4gICAgcmVxdWVzdElkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTsgLy8gdW5pZnkgcHJvZHVjZXIvY29uc3VtZXIga2V5IGZvcm1zXG4gICAgY29uc3QgcGF5bG9hZDogU1NFUGF5bG9hZCA9IHtcbiAgICAgIHRzOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB0eXBlLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIGRhdGEsXG4gICAgfTtcblxuICAgIC8vIERlbGl2ZXIgdG8gTE9DQUwgY2xpZW50cyBmaXJzdCwgdGhlbiByZWxheSB0aGUgU0FNRSBwYXlsb2FkIHRvIG90aGVyIHBvZHNcbiAgICAvLyBzbyBhbiBFdmVudFNvdXJjZSBhdHRhY2hlZCBvbiBhIGRpZmZlcmVudCByZXBsaWNhIGFsc28gcmVjZWl2ZXMgaXQuIFRoZVxuICAgIC8vIHJlbGF5IGlzIGZpcmUtYW5kLWZvcmdldCBhbmQgZmFpbC1zYWZlOiBubyByZWxheSAvIFJlZGlzIGRvd24g4oeSIGxvY2FsLW9ubHkuXG4gICAgY29uc3Qgc2VudENvdW50ID0gdGhpcy5zZW5kTG9jYWwocmVxdWVzdElkLCBwYXlsb2FkKTtcbiAgICB0aGlzLnB1Ymxpc2hSZWxheSh7IG9yaWdpbjogdGhpcy5ub2RlSWQsIGtpbmQ6ICdzZW5kJywgcmVxdWVzdElkLCBwYXlsb2FkIH0pO1xuICAgIHJldHVybiBzZW50Q291bnQ7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgYSBwcmUtYnVpbHQgcGF5bG9hZCB0byB0aGlzIHBvZCdzIExPQ0FMIGNsaWVudHMgZm9yIGByZXF1ZXN0SWRgLiBTaGFyZWRcbiAgICogYnkge0BsaW5rIHNlbmR9IChsb2NhbCBoYWxmKSBhbmQgdGhlIHJlbGF5IHJlLWVtaXQgcGF0aCAoe0BsaW5rIG9uUmVsYXlNZXNzYWdlfSksXG4gICAqIHNvIGEgcmVsYXllZCBmcmFtZSByZXVzZXMgdGhlIHByb2R1Y2VyJ3Mgb3JpZ2luYWwgYHRzYCByYXRoZXIgdGhhbiBhIG5ldyBvbmUuXG4gICAqIE5ldmVyIHJlbGF5cyDigJQgY2FsbGVycyBkZWNpZGUgd2hldGhlciB0byBwdWJsaXNoLlxuICAgKi9cbiAgcHJpdmF0ZSBzZW5kTG9jYWwocmVxdWVzdElkOiBzdHJpbmcsIHBheWxvYWQ6IFNTRVBheWxvYWQpOiBudW1iZXIge1xuICAgIHJlcXVlc3RJZCA9IFNTRU1hbmFnZXIubm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZCk7IC8vIGlkZW1wb3RlbnQ7IGNvdmVycyB0aGUgcmVsYXkgcmUtZW1pdCBwYXRoXG4gICAgY29uc3QgY2xpZW50cyA9IFsuLi4odGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpIHx8IFtdKV07XG4gICAgbGV0IHNlbnRDb3VudCA9IDA7XG4gICAgY29uc3Qgc2VyaWFsaXplZCA9IGBkYXRhOiAke0pTT04uc3RyaW5naWZ5KHBheWxvYWQpfVxcblxcbmA7XG5cbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBCYWNrcHJlc3N1cmU6IHNraXAgY2xpZW50cyB3aG9zZSB3cml0ZSBidWZmZXIgaXMgZnVsbFxuICAgICAgICBpZiAoY2xpZW50LnJlcy53cml0YWJsZUVuZGVkKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnQuaWQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNhbldyaXRlID0gY2xpZW50LnJlcy53cml0ZShzZXJpYWxpemVkKTtcbiAgICAgICAgaWYgKCFjYW5Xcml0ZSkge1xuICAgICAgICAgIGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCsrO1xuICAgICAgICAgIC8vIERpc2Nvbm5lY3QgY2xpZW50cyB0aGF0IGNvbnNpc3RlbnRseSBjYW4ndCBrZWVwIHVwICgxMCBjb25zZWN1dGl2ZSBiYWNrcHJlc3N1cmUgZXZlbnRzKVxuICAgICAgICAgIGlmIChjbGllbnQuYmFja3ByZXNzdXJlQ291bnQgPj0gQ29yZUNvbnN0YW50cy5TU0VfQkFDS1BSRVNTVVJFX1RIUkVTSE9MRCkge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oYERpc2Nvbm5lY3Rpbmcgc2xvdyBjbGllbnQgJHtjbGllbnQuaWR9IGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAoJHtjbGllbnQuYmFja3ByZXNzdXJlQ291bnR9IGJhY2twcmVzc3VyZSBldmVudHMpYCk7XG4gICAgICAgICAgICBpbmNDb3VudGVyKCdzc2VfYmFja3ByZXNzdXJlX2Rpc2Nvbm5lY3RzX3RvdGFsJywge30pO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnQuaWQpO1xuICAgICAgICAgICAgdHJ5IHsgY2xpZW50LnJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbGllbnQuYmFja3ByZXNzdXJlQ291bnQgPSAwOyAvLyBSZXNldCBvbiBzdWNjZXNzZnVsIHdyaXRlXG4gICAgICAgIH1cbiAgICAgICAgc2VudENvdW50Kys7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBzZW5kIHRvIGNsaWVudCAke2NsaWVudC5pZH06YCwgZXJyb3IpO1xuICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbnRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCcm9hZGNhc3QgYSBtZXNzYWdlIHRvIGFsbCBjb25uZWN0ZWQgY2xpZW50cyBhY3Jvc3MgYWxsIHJlcXVlc3RzXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gRXZlbnQgdHlwZVxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIE1lc3NhZ2Ugc3RyaW5nXG4gICAqIEBwYXJhbSBkYXRhIC0gT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhXG4gICAqIEByZXR1cm5zIFRvdGFsIG51bWJlciBvZiBjbGllbnRzIHRoZSBtZXNzYWdlIHdhcyBzZW50IHRvXG4gICAqL1xuICBicm9hZGNhc3QodHlwZTogU1NFRXZlbnRUeXBlLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogbnVtYmVyIHtcbiAgICBjb25zdCBwYXlsb2FkOiBTU0VQYXlsb2FkID0ge1xuICAgICAgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHR5cGUsXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGF0YSxcbiAgICB9O1xuICAgIC8vIERlbGl2ZXIgdG8gbG9jYWwgY2xpZW50cywgdGhlbiByZWxheSBhIHNpbmdsZSBicm9hZGNhc3QgZnJhbWUgc28gRVZFUlkgcG9kXG4gICAgLy8gcmUtZW1pdHMgdG8gQUxMIG9mIGl0cyBvd24gY2xpZW50cyDigJQgYSBwZXItcmVxdWVzdElkIHJlbGF5IHdvdWxkIG1pc3NcbiAgICAvLyBzdWJqZWN0cyB0aGF0IG9ubHkgZXhpc3Qgb24gb3RoZXIgcmVwbGljYXMuXG4gICAgY29uc3QgdG90YWxTZW50ID0gdGhpcy5icm9hZGNhc3RMb2NhbChwYXlsb2FkKTtcbiAgICB0aGlzLnB1Ymxpc2hSZWxheSh7IG9yaWdpbjogdGhpcy5ub2RlSWQsIGtpbmQ6ICdicm9hZGNhc3QnLCBwYXlsb2FkIH0pO1xuICAgIHJldHVybiB0b3RhbFNlbnQ7XG4gIH1cblxuICAvKiogV3JpdGUgYSBwcmUtYnVpbHQgcGF5bG9hZCB0byBhbGwgTE9DQUwgY2xpZW50cyBhY3Jvc3MgZXZlcnkgcmVxdWVzdC4gKi9cbiAgcHJpdmF0ZSBicm9hZGNhc3RMb2NhbChwYXlsb2FkOiBTU0VQYXlsb2FkKTogbnVtYmVyIHtcbiAgICBsZXQgdG90YWxTZW50ID0gMDtcbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RJZCBvZiBbLi4udGhpcy5jbGllbnRzLmtleXMoKV0pIHtcbiAgICAgIHRvdGFsU2VudCArPSB0aGlzLnNlbmRMb2NhbChyZXF1ZXN0SWQsIHBheWxvYWQpO1xuICAgIH1cbiAgICByZXR1cm4gdG90YWxTZW50O1xuICB9XG5cbiAgLyoqIEZpcmUtYW5kLWZvcmdldCByZWxheSBwdWJsaXNoLiBOby1vcCAobG9jYWwtb25seSkgd2hlbiBubyByZWxheSBpcyB3aXJlZC4gKi9cbiAgcHJpdmF0ZSBwdWJsaXNoUmVsYXkobXNnOiBTU0VSZWxheU1lc3NhZ2UpOiB2b2lkIHtcbiAgICB0aGlzLnJlbGF5Py5wdWJsaXNoKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgYWxsIGNsaWVudHMgZm9yIGEgc3BlY2lmaWMgcmVxdWVzdFxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gUmVxdWVzdCBJRCB0byBjbG9zZVxuICAgKiBAcGFyYW0gZmluYWxNZXNzYWdlIC0gT3B0aW9uYWwgZmluYWwgbWVzc2FnZSB0byBzZW5kIGJlZm9yZSBjbG9zaW5nXG4gICAqL1xuICBjbG9zZVJlcXVlc3QocmVxdWVzdElkOiBzdHJpbmcsIGZpbmFsTWVzc2FnZT86IHN0cmluZyk6IHZvaWQge1xuICAgIHJlcXVlc3RJZCA9IFNTRU1hbmFnZXIubm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZCk7XG4gICAgaWYgKCF0aGlzLmNsaWVudHMuaGFzKHJlcXVlc3RJZCkpIHJldHVybjtcblxuICAgIC8vIExPQ0FMIG9ubHk6IHRoaXMgY2xvc2VzIHRoaXMgcG9kJ3MgY2xpZW50cywgc28gdGhlIGZpbmFsIGZyYW1lIGlzIGZvciB0aGVtXG4gICAgLy8gKHJlbGF5aW5nIGl0IHdvdWxkIHB1c2ggYSBDT01QTEVURUQgdG8gb3RoZXIgcG9kcycgc3RpbGwtb3BlbiBzdHJlYW1zKS5cbiAgICBpZiAoZmluYWxNZXNzYWdlKSB7XG4gICAgICB0aGlzLnNlbmRMb2NhbChyZXF1ZXN0SWQsIHsgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwgdHlwZTogJ0NPTVBMRVRFRCcsIG1lc3NhZ2U6IGZpbmFsTWVzc2FnZSB9KTtcbiAgICB9XG5cbiAgICAvLyBSZWFkIHRoZSBlbnRyeSBBRlRFUiB0aGUgZmluYWwgd3JpdGU6IHNlbmRMb2NhbCByZW1vdmVzIChhbmQgdW4tY291bnRzKVxuICAgIC8vIGNsaWVudHMgdGhhdCB3ZXJlIGFscmVhZHkgZ29uZSwgc28gaXRlcmF0aW5nIGFuIGVhcmxpZXIgc25hcHNob3Qgd291bGRcbiAgICAvLyBkZWNyZW1lbnQgdGhlaXIgb3JnIGNvdW50IGEgc2Vjb25kIHRpbWUuXG4gICAgZm9yIChjb25zdCBjbGllbnQgb2YgdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpID8/IFtdKSB7XG4gICAgICBjbGVhclRpbWVvdXQoY2xpZW50LnRpbWVvdXQpO1xuICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjbGllbnQub3JnSWQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2xpZW50LnJlcy5lbmQoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1Jlc3BvbnNlIGFscmVhZHkgY2xvc2VkIG9uIHJlcXVlc3QgY2xvc2UnLCB7IHJlcXVlc3RJZCwgY2xpZW50SWQ6IGNsaWVudC5pZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICB0aGlzLnVwZGF0ZUFjdGl2ZUdhdWdlKCk7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbG9zZWQgYWxsIGNsaWVudHMgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHN0YXRpc3RpY3MgYWJvdXQgY3VycmVudCBjb25uZWN0aW9uc1xuICAgKi9cbiAgZ2V0U3RhdHMoKTogU1NFTWFuYWdlclN0YXRzIHtcbiAgICBsZXQgdG90YWxDbGllbnRzID0gMDtcbiAgICBsZXQgb2xkZXN0Q29ubmVjdGlvbjogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgY2xpZW50cyBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIHtcbiAgICAgIHRvdGFsQ2xpZW50cyArPSBjbGllbnRzLmxlbmd0aDtcbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgICAgY29uc3QgYWdlID0gbm93IC0gY2xpZW50LmNvbm5lY3RlZEF0O1xuICAgICAgICBpZiAob2xkZXN0Q29ubmVjdGlvbiA9PT0gbnVsbCB8fCBhZ2UgPiBvbGRlc3RDb25uZWN0aW9uKSB7XG4gICAgICAgICAgb2xkZXN0Q29ubmVjdGlvbiA9IGFnZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0b3RhbFJlcXVlc3RzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgIHRvdGFsQ2xpZW50cyxcbiAgICAgIG9sZGVzdENvbm5lY3Rpb25Nczogb2xkZXN0Q29ubmVjdGlvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgcmVxdWVzdCBoYXMgYW55IGNvbm5lY3RlZCBjbGllbnRzXG4gICAqL1xuICBoYXNDbGllbnRzKHJlcXVlc3RJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQoU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSk7XG4gICAgcmV0dXJuIGNsaWVudHMgIT09IHVuZGVmaW5lZCAmJiBjbGllbnRzLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgY2xpZW50cyBmb3IgYSBzcGVjaWZpYyByZXF1ZXN0XG4gICAqL1xuICBnZXRDbGllbnRDb3VudChyZXF1ZXN0SWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50cy5nZXQoU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSk/Lmxlbmd0aCA/PyAwO1xuICB9XG5cbiAgLyoqXG4gICAqIE1pZGRsZXdhcmUgdG8gaW5pdGlhbGl6ZSBhIHRpY2tldC1hdXRoZW50aWNhdGVkIFNTRSBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBUaGUgc3RyZWFtIGlzIE5PVCBvcGVuIHRvIHRoZSB3b3JsZDogdGhlIGNhbGxlciBtdXN0IGZpcnN0IGV4Y2hhbmdlIGl0c1xuICAgKiBKV1QgZm9yIGEgc2hvcnQtbGl2ZWQgc2luZ2xlLXVzZSB0aWNrZXQgKHNlZSB7QGxpbmsgY3JlYXRlVGlja2V0fSwgd2lyZWQgdG9cbiAgICogYFBPU1QgL2xvZ3MvdGlja2V0YCkgYW5kIHBhc3MgaXQgYXMgYD90aWNrZXQ9PHQ+YC4gVGhlIG1pZGRsZXdhcmUgdmFsaWRhdGVzXG4gICAqICsgY29uc3VtZXMgdGhlIHRpY2tldCwgYmluZHMgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHRpY2tldCdzIG9yZywgYW5kXG4gICAqIGVuZm9yY2VzIHRoZSBwZXItb3JnIGNvbm5lY3Rpb24gY2FwLiBBIG1pc3NpbmcgLyBpbnZhbGlkIC8gZXhwaXJlZCAvXG4gICAqIGFscmVhZHktdXNlZCB0aWNrZXQgaXMgcmVqZWN0ZWQgd2l0aCA0MDEgYmVmb3JlIGFueSBTU0UgaGVhZGVycyBmbHVzaC5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuICAgKiBgYGBcbiAgICovXG4gIG1pZGRsZXdhcmUoKSB7XG4gICAgcmV0dXJuIGFzeW5jIChyZXE6IHsgcGFyYW1zOiB7IHJlcXVlc3RJZDogc3RyaW5nIH07IHF1ZXJ5PzogeyB0aWNrZXQ/OiB1bmtub3duIH0gfSwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgY29uc3QgeyByZXF1ZXN0SWQgfSA9IHJlcS5wYXJhbXM7XG5cbiAgICAgIGlmICghU1NFX1JFUVVFU1RfSURfUkUudGVzdChyZXF1ZXN0SWQpKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAwKS5lbmQoJ0ludmFsaWQgcmVxdWVzdElkIGZvcm1hdCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFRpY2tldCBhdXRoIOKAlCByZXF1aXJlZC4gUmVzb2x2ZSBgP3RpY2tldD08dD5gLCB0aGVuIHZhbGlkYXRlICsgY29uc3VtZVxuICAgICAgLy8gaXQgKHNpbmdsZS11c2UpIEZPUiBUSElTIFNVQkpFQ1QuIEFuIGFub255bW91cywgbWFsZm9ybWVkLCB1bmtub3duLFxuICAgICAgLy8gZXhwaXJlZCwgYWxyZWFkeS1jb25zdW1lZCwgb3Igd3Jvbmctc3ViamVjdCB0aWNrZXQgaXMgYSA0MDEuIFRoZSBvcmcgaXNcbiAgICAgIC8vIHRha2VuIGZyb20gdGhlIHRpY2tldCwgc28gdGhlIHN0cmVhbSBpcyBhbHdheXMgYm91bmQgdG8gYSB2ZXJpZmllZFxuICAgICAgLy8gdGVuYW50IEFORCB0byB0aGUgZXhhY3Qgc3ViamVjdCB0aGUgdGlja2V0IHdhcyBtaW50ZWQgZm9yIChubyBhbm9ueW1vdXNcbiAgICAgIC8vIHN0cmVhbXMsIG5vIGNyb3NzLXN1YmplY3QgYXR0YWNoKS5cbiAgICAgIGNvbnN0IHRpY2tldElkID0gcmVxLnF1ZXJ5Py50aWNrZXQ7XG4gICAgICBpZiAodHlwZW9mIHRpY2tldElkICE9PSAnc3RyaW5nJyB8fCB0aWNrZXRJZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDEpLmVuZCgnTWlzc2luZyB0aWNrZXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgY29uc3VtZWQgPSBhd2FpdCB0aGlzLmNvbnN1bWVUaWNrZXQodGlja2V0SWQsIHJlcXVlc3RJZCk7XG4gICAgICBpZiAoIWNvbnN1bWVkKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAxKS5lbmQoJ0ludmFsaWQgb3IgZXhwaXJlZCB0aWNrZXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3JnSWQgPSBjb25zdW1lZC5vcmdJZDtcblxuICAgICAgLy8gUHJlLWZsaWdodCBwZXItcmVxdWVzdCBjYXAgc28gd2UgY2FuIHJldHVybiA0MjkgYmVmb3JlIGZsdXNoaW5nXG4gICAgICAvLyBTU0UgaGVhZGVycyAoYWZ0ZXIgaGVhZGVycyBhcmUgZmx1c2hlZCB0aGUgY2xpZW50IGNhbid0IHJlYWQgYSA0MjkpLlxuICAgICAgLy9cbiAgICAgIC8vIE5PUk1BTElaRSBmaXJzdDogYGFkZENsaWVudGAga2V5cyB0aGUgbWFwIG9uIHRoZSBub3JtYWxpemVkIGZvcm1cbiAgICAgIC8vIChkYXNoZXMgc3RyaXBwZWQpLCBzbyByZWFkaW5nIHRoZSByYXcgYHJlcXVlc3RJZGAgaGVyZSBhbHdheXMgZm91bmQgMFxuICAgICAgLy8gZm9yIGEgY2xpZW50IHVzaW5nIHRoZSBkYXNoZWQgZm9ybS4gVGhlIGNhcCB3YXMgdGhlbiBvbmx5IGNhdWdodCBpbnNpZGVcbiAgICAgIC8vIGBhZGRDbGllbnRgIOKAlCBBRlRFUiBgZmx1c2hIZWFkZXJzKClgIOKAlCB3aGljaCBpcyBleGFjdGx5IHRoZSBjYXNlIHRoaXNcbiAgICAgIC8vIHByZS1mbGlnaHQgZXhpc3RzIHRvIGF2b2lkOiB0aGUgY2xpZW50IGdvdCBhIHNpbGVudGx5LWNsb3NlZCBzdHJlYW1cbiAgICAgIC8vIGluc3RlYWQgb2YgYSA0MjkuXG4gICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuY2xpZW50cy5nZXQoU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSkgfHwgW107XG4gICAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID49IHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYENsaWVudCBsaW1pdCByZWFjaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1BlclJlcXVlc3R9KWApO1xuICAgICAgICByZXMuc3RhdHVzKDQyOSkuZW5kKCdUb28gbWFueSBjb25uZWN0aW9ucyBmb3IgdGhpcyByZXF1ZXN0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU2FtZSBmb3IgdGhlIHBlci1vcmcgY2FwIOKAlCBiZXR0ZXIgdG8gc2VuZCA0MjkgdGhhbiBvcGVuIHRoZSBzdHJlYW0gYW5kXG4gICAgICAvLyBpbW1lZGlhdGVseSBjbG9zZSBpdC4gVGhlIHRpY2tldCBndWFyYW50ZWVzIGEgdmVyaWZpZWQgb3JnIGlkLCBzbyB0aGVcbiAgICAgIC8vIHBlci1vcmcgY2VpbGluZyBpcyBhbHdheXMgZW5mb3JjZWQgZm9yIHRoZSAvbG9ncyBzdHJlYW0uXG4gICAgICBpZiAoKHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMCkgPj0gdGhpcy5tYXhDbGllbnRzUGVyT3JnKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBQZXItb3JnIFNTRSBjbGllbnQgY2FwIHJlYWNoZWQgZm9yICR7b3JnSWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyT3JnfSlgKTtcbiAgICAgICAgcmVzLnN0YXR1cyg0MjkpLmVuZCgnVG9vIG1hbnkgU1NFIGNvbm5lY3Rpb25zIGZvciB0aGlzIG9yZ2FuaXphdGlvbicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHdyaXRlU3NlSGVhZGVycyhyZXMpO1xuICAgICAgcmVzLmZsdXNoSGVhZGVycygpO1xuXG4gICAgICAvLyBIZWFkZXJzIGFyZSBmbHVzaGVkIOKAlCB3ZSBjYW4gbm8gbG9uZ2VyIHNlbmQgYSA0MjkuIGFkZENsaWVudCByZS1jaGVja3NcbiAgICAgIC8vIHRoZSBjYXBzIChpbmNsdWRpbmcgdGhlIHByb2Nlc3Mtd2lkZSB0b3RhbC1jbGllbnRzIGNhcCwgd2hpY2ggdGhlXG4gICAgICAvLyBwcmUtZmxpZ2h0IGFib3ZlIGRvZXMgbm90KSBhbmQgY2FuIHN0aWxsIHJlamVjdCBvbiBhIHJhY2U6IGEgY29uY3VycmVudFxuICAgICAgLy8gY29ubmVjdGlvbiBtYXkgaGF2ZSBmaWxsZWQgYSBjYXAgYmV0d2VlbiB0aGUgcHJlLWZsaWdodCBjaGVjayBhbmQgaGVyZS5cbiAgICAgIC8vIE9uIHJlamVjdGlvbiwgY2xvc2UgdGhlIG5vdy1kYW5nbGluZyByZXNwb25zZSBpbnN0ZWFkIG9mIGxlYXZpbmcgYW5cbiAgICAgIC8vIG9wZW4gc29ja2V0IHdpdGggbm8gY2xpZW50IHJlY29yZCAod2hpY2ggd291bGQgbGVhayBhbiBmZCArIG5ldmVyIGVtaXRcbiAgICAgIC8vIHN0cmVhbSBkYXRhKS5cbiAgICAgIGNvbnN0IGFkZGVkID0gdGhpcy5hZGRDbGllbnQocmVxdWVzdElkLCByZXMsIG9yZ0lkKTtcbiAgICAgIGlmICghYWRkZWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFNTRSBhZGRDbGllbnQgcmVqZWN0ZWQgYWZ0ZXIgaGVhZGVycyBmbHVzaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfTsgY2xvc2luZyBkYW5nbGluZyByZXNwb25zZWApO1xuICAgICAgICB0cnkgeyByZXMuZW5kKCk7IH0gY2F0Y2ggeyAvKiBhbHJlYWR5IGNsb3NlZCAqLyB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBwZXJpb2RpYyBjbGVhbnVwIG9mIHN0YWxlIGNvbm5lY3Rpb25zXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0Q2xlYW51cEludGVydmFsKGludGVydmFsTXM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuY2xlYW51cEludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgfSwgaW50ZXJ2YWxNcyk7XG5cbiAgICAvLyBEb24ndCBwcmV2ZW50IHByb2Nlc3MgZXhpdFxuICAgIHRoaXMuY2xlYW51cEludGVydmFsLnVucmVmKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW4gdXAgc3RhbGUgY29ubmVjdGlvbnMgdXNpbmcgc2luZ2xlLXBhc3MgcGFydGl0aW9uLlxuICAgKiBPKFIgw5cgQykgaW5zdGVhZCBvZiBPKFIgw5cgQ8KyKSwgYW5kIGF2b2lkcyBtdXRhdGlvbi1kdXJpbmctaXRlcmF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBjbGVhbnVwKCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgbGV0IGNsZWFuZWQgPSAwO1xuXG4gICAgZm9yIChjb25zdCBbcmVxdWVzdElkLCBjbGllbnRzXSBvZiB0aGlzLmNsaWVudHMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCBzdGFsZTogU1NFQ2xpZW50W10gPSBbXTtcbiAgICAgIGNvbnN0IGFjdGl2ZTogU1NFQ2xpZW50W10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgICAvLyBUaW1lLWJhc2VkIGV2aWN0aW9uIE9SIGEgc29ja2V0IHRoYXQgc2lsZW50bHkgY2xvc2VkIChubyAnY2xvc2UnXG4gICAgICAgIC8vIGV2ZW50KSDigJQgTm9kZSBzb21ldGltZXMgZHJvcHMgc29ja2V0cyB3aXRob3V0IGZpcmluZyB0aGUgZXZlbnQsXG4gICAgICAgIC8vIHNvIHdlIGV4cGxpY2l0bHkgY2hlY2sgd3JpdGFibGVFbmRlZC9kZXN0cm95ZWQgaGVyZS5cbiAgICAgICAgY29uc3QgYWdlU3RhbGUgPSBub3cgLSBjbGllbnQuY29ubmVjdGVkQXQgPiB0aGlzLmNsaWVudFRpbWVvdXRNcztcbiAgICAgICAgY29uc3Qgc29ja2V0RGVhZCA9IGNsaWVudC5yZXMud3JpdGFibGVFbmRlZCB8fCAoY2xpZW50LnJlcyBhcyB7IGRlc3Ryb3llZD86IGJvb2xlYW4gfSkuZGVzdHJveWVkID09PSB0cnVlO1xuICAgICAgICBpZiAoYWdlU3RhbGUgfHwgc29ja2V0RGVhZCkge1xuICAgICAgICAgIHN0YWxlLnB1c2goY2xpZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY3RpdmUucHVzaChjbGllbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIHN0YWxlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjbGllbnQudGltZW91dCk7XG4gICAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoY2xpZW50Lm9yZ0lkKTtcbiAgICAgICAgdHJ5IHsgY2xpZW50LnJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgICAgY2xlYW5lZCsrO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aXZlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YWxlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIGFjdGl2ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNsZWFuZWQgPiAwKSB7XG4gICAgICBpbmNDb3VudGVyKCdzc2Vfc3RhbGVfY2xlYW5lZF90b3RhbCcsIHt9LCBjbGVhbmVkKTtcbiAgICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgICAgIGxvZ2dlci5pbmZvKGBDbGVhbmVkIHVwICR7Y2xlYW5lZH0gc3RhbGUgU1NFIGNvbm5lY3Rpb25zYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNodXRkb3duIHRoZSBTU0UgbWFuYWdlciBhbmQgY2xvc2UgYWxsIGNvbm5lY3Rpb25zXG4gICAqL1xuICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jbGVhbnVwSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdGhpcy5jbG9zZVJlcXVlc3QocmVxdWVzdElkLCAnU2VydmVyIHNodXR0aW5nIGRvd24nKTtcbiAgICB9XG5cbiAgICAvLyBUZWFyIGRvd24gdGhlIHJlbGF5J3MgUmVkaXMgY29ubmVjdGlvbnMgKGJlc3QtZWZmb3J0OyBuZXZlciB0aHJvd3MpLlxuICAgIHZvaWQgdGhpcy5yZWxheT8uY2xvc2UoKS5jYXRjaCgoKSA9PiB7IC8qIGFscmVhZHkgY2xvc2luZyAqLyB9KTtcbiAgICBpZiAodGhpcy5vd25zVGlja2V0U3RvcmUpIHRoaXMudGlja2V0U3RvcmVJbnN0YW5jZT8uc3RvcCgpO1xuXG4gICAgbG9nZ2VyLmluZm8oJ1NTRSBNYW5hZ2VyIHNodXQgZG93bicpO1xuICB9XG59XG4iXX0=
607
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUF1QixZQUFZLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdEgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhFLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxlQUFlLEVBQTJCLE1BQU0sd0JBQXdCLENBQUM7QUFDdEcsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUV6RCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7QUEwRzNDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxxRUFBcUUsQ0FBQztBQWF2Rzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQUNiLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztJQUNqRDs7MkNBRXVDO0lBQy9CLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUNwRCxtRkFBbUY7SUFDbEUsT0FBTyxDQUFrQjtJQUN6QixvQkFBb0IsQ0FBUztJQUM3QixlQUFlLENBQVM7SUFDeEIsZ0JBQWdCLENBQVM7SUFDekIsZUFBZSxDQUFTO0lBQ2pDLGVBQWUsR0FBMEIsSUFBSSxDQUFDO0lBQ3RELCtEQUErRDtJQUN2RCxLQUFLLENBQVk7SUFDUixZQUFZLENBQXlCO0lB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QUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1FBQzlCLENBQUM7UUFFRCxLQUFLLE1BQU0sU0FBUyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNqRCxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCx1RUFBdUU7UUFDdkUsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBeUIsQ0FBQyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUV4QixNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDdkMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCB3cml0ZVNzZUhlYWRlcnMsIHR5cGUgU3NlVGlja2V0U3RvcmUsIGVycm9yTWVzc2FnZSwgZW52SW50IH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29yZUNvbnN0YW50cyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHR5cGUgeyBTU0VSZWxheSwgU1NFUmVsYXlNZXNzYWdlIH0gZnJvbSAnLi9zc2UtcmVsYXkuanMnO1xuaW1wb3J0IHsgbm9ybWFsaXplUmVxdWVzdElkLCBTc2VUaWNrZXRCcm9rZXIsIHR5cGUgQ3JlYXRlVGlja2V0UmVzdWx0IH0gZnJvbSAnLi9zc2UtdGlja2V0LWJyb2tlci5qcyc7XG5pbXBvcnQgeyBpbmNDb3VudGVyLCBzZXRHYXVnZSB9IGZyb20gJy4uL2FwaS9tZXRyaWNzLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdzc2UtbWFuYWdlcicpO1xuXG4vKipcbiAqIEV2ZW50IHR5cGVzIGZvciBTU0UgbG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBTU0VFdmVudFR5cGUgPSAnSU5GTycgfCAnV0FSTicgfCAnRVJST1InIHwgJ0NPTVBMRVRFRCcgfCAnUk9MTEJBQ0snIHwgJ01FU1NBR0UnO1xuXG4vKipcbiAqIFNTRSBwYXlsb2FkIHN0cnVjdHVyZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRVBheWxvYWQge1xuICB0czogc3RyaW5nO1xuICB0eXBlOiBTU0VFdmVudFR5cGU7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgZGF0YT86IHVua25vd247XG59XG5cbi8qKlxuICogU1NFIGNsaWVudCB3aXRoIGNvbm5lY3Rpb24gdHJhY2tpbmdcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTU0VDbGllbnQge1xuICBpZDogc3RyaW5nO1xuICByZXM6IFJlc3BvbnNlO1xuICBjb25uZWN0ZWRBdDogbnVtYmVyO1xuICB0aW1lb3V0OiBOb2RlSlMuVGltZW91dDtcbiAgLyoqIE51bWJlciBvZiBjb25zZWN1dGl2ZSBiYWNrcHJlc3N1cmUgZXZlbnRzICh3cml0ZSByZXR1cm5lZCBmYWxzZSkuICovXG4gIGJhY2twcmVzc3VyZUNvdW50OiBudW1iZXI7XG4gIC8qKiBPd25pbmcgb3JnIGlkIOKAlCBwb3B1bGF0ZWQgd2hlbiB0aGUgcmVxdWVzdCB3YXMgYXV0aGVudGljYXRlZC4gVXNlZCB0b1xuICAgKiAgZGVjcmVtZW50IHRoZSBwZXItb3JnIGNvdW50ZXIgb24gZGlzY29ubmVjdCAvIGNsZWFudXAuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFNTRSBNYW5hZ2VyIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRU1hbmFnZXJPcHRpb25zIHtcbiAgLyoqIE1heGltdW0gY2xpZW50cyBhbGxvd2VkIHBlciByZXF1ZXN0IElEIChkZWZhdWx0OiAxMCkgKi9cbiAgbWF4Q2xpZW50c1BlclJlcXVlc3Q/OiBudW1iZXI7XG4gIC8qKiBDbGllbnQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDMwIG1pbnV0ZXMpICovXG4gIGNsaWVudFRpbWVvdXRNcz86IG51bWJlcjtcbiAgLyoqIEludGVydmFsIGZvciBjbGVhbnVwIGNoZWNrcyBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDUgbWludXRlcykgKi9cbiAgY2xlYW51cEludGVydmFsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIYXJkIGNhcCBvbiB0b3RhbCBvcGVuIGNvbm5lY3Rpb25zIHBlciBwcm9jZXNzLiBEZWZhdWx0cyB0byAxMDAwIGZyb21cbiAgICogYFNTRV9NQVhfVE9UQUxfQ0xJRU5UU2AuIE5ldyBjb25uZWN0aW9ucyBiZXlvbmQgdGhpcyBhcmUgcmVqZWN0ZWQgYXRcbiAgICogYGFkZENsaWVudCgpYC4gVHVuZSB1cCBpZiB5b3VyIHNlcnZpY2Ugc2VydmVzID4gMTAwMCBjb25jdXJyZW50IFNTRVxuICAgKiBkYXNoYm9hcmRzLCBidXQgYmUgYXdhcmUgTm9kZS5qcyBmZCBsaW1pdHMgZG9taW5hdGUgYWJvdmUgfjUwMDAuXG4gICAqL1xuICBtYXhUb3RhbENsaWVudHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQZXItb3JnIGNlaWxpbmcgb24gY29uY3VycmVudCBTU0Ugc3RyZWFtcy4gRGVmYXVsdHMgdG8gNTAgZnJvbVxuICAgKiBgU1NFX01BWF9DTElFTlRTX1BFUl9PUkdgLiBQcm90ZWN0cyBhZ2FpbnN0IG9uZSBub2lzeSBvcmcgY29uc3VtaW5nIHRoZVxuICAgKiBwcm9jZXNzLXdpZGUgYnVkZ2V0IOKAlCB3aXRob3V0IGl0LCBhbiBhdXRoZW50aWNhdGVkIHVzZXIgY2FuIGZhbiBvdXRcbiAgICogdGhvdXNhbmRzIG9mIHN0cmVhbXMgKG9uZSBwZXIgZGFzaGJvYXJkIC8gbG9nIHN0cmVhbSkgYW5kIHN0YXJ2ZSBvdGhlclxuICAgKiBvcmdzIG9mIGNvbm5lY3Rpb24gc2xvdHMuIFRoZSBjYXAgaXMgZW5mb3JjZWQgb25seSBvbiBgYWRkQ2xpZW50YCBjYWxsc1xuICAgKiB0aGF0IGNhcnJ5IGFuIGBvcmdJZGA7IHNlcnZpY2UtaW50ZXJuYWwgLyBhbm9ueW1vdXMgU1NFIHRyYWZmaWMgc2tpcHMgaXQuXG4gICAqL1xuICBtYXhDbGllbnRzUGVyT3JnPzogbnVtYmVyO1xuICAvKipcbiAgICogQ2FwIG9uIGxpdmUgbG9nLXN0cmVhbSB0aWNrZXRzIGFjcm9zcyB0aGUgcHJvY2VzcywgZm9yIHRoZSBERUZBVUxUXG4gICAqIGluLW1lbW9yeSB0aWNrZXQgc3RvcmUuIERlZmF1bHRzIHRvIDEwMDAgZnJvbSBgU1NFX01BWF9UT1RBTF9USUNLRVRTYC5cbiAgICogSWdub3JlZCB3aGVuIGB0aWNrZXRTdG9yZWAgaXMgaW5qZWN0ZWQgKHRoZSBzdG9yZSBjYXJyaWVzIGl0cyBvd24gY2FwcykuXG4gICAqL1xuICBtYXhUb3RhbFRpY2tldHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQZXItb3JnIGNhcCBvbiBsaXZlIGxvZy1zdHJlYW0gdGlja2V0cywgZm9yIHRoZSBERUZBVUxUIGluLW1lbW9yeSB0aWNrZXRcbiAgICogc3RvcmUuIERlZmF1bHRzIHRvIDEwIGZyb20gYFNTRV9NQVhfVElDS0VUU19QRVJfT1JHYC4gSWdub3JlZCB3aGVuXG4gICAqIGB0aWNrZXRTdG9yZWAgaXMgaW5qZWN0ZWQuXG4gICAqL1xuICBtYXhUaWNrZXRzUGVyT3JnPzogbnVtYmVyO1xuICAvKiogVGlja2V0IFRUTCBpbiBtcyBmb3IgdGhlIGRlZmF1bHQgc3RvcmUgKGRlZmF1bHQ6IGBTU0VfVElDS0VUX1RUTF9NU2AgZnJvbSBhcGktY29yZSkuICovXG4gIHRpY2tldFR0bE1zPzogbnVtYmVyO1xuICAvKipcbiAgICogVGlja2V0ICsgc3RyZWFtLW93bmVyc2hpcCBiYWNrZW5kIGZvciB0aGUgc3ViamVjdC1ib3VuZCBsb2cgc3RyZWFtLiBEZWZhdWx0c1xuICAgKiB0byBhbiBpbi1tZW1vcnkgc3RvcmUgKHNpbmdsZSByZXBsaWNhIG9ubHkpLCBidWlsdCBvbiBmaXJzdCB1c2UuIEluamVjdCBhblxuICAgKiBhcGktY29yZSBgY3JlYXRlRW52U3NlVGlja2V0U3RvcmUoLi4uKWAgc28gbWludC9yZWRlZW0gYW5kIHN0cmVhbSBvd25lcnNoaXBcbiAgICogd29yayBhY3Jvc3MgcG9kcy5cbiAgICovXG4gIHRpY2tldFN0b3JlPzogU3NlVGlja2V0U3RvcmU7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgc2VydmljZSBzdHJlYW1zIHBlci1yZXF1ZXN0IGxvZ3MgKGBjdHgubG9nYCBmcmFtZXMga2V5ZWQgYnlcbiAgICogcmVxdWVzdElkLCB0aGUgYC9sb2dzYCBjaGFubmVsKS4gRGVmYXVsdCBmYWxzZTogYGN0eC5sb2dgIHRoZW4gb25seSB3cml0ZXNcbiAgICogdG8gdGhlIGxvZ2dlciwgc28gYSBzZXJ2aWNlIHRoYXQgbmV2ZXIgc2VydmVzIGEgbG9nIHN0cmVhbSBkb2Vzbid0IHB1c2hcbiAgICogZXZlcnkgbG9nIGxpbmUgdGhyb3VnaCBTU0UgKGFuZCBvdmVyIFJlZGlzKS5cbiAgICovXG4gIGxvZ1N0cmVhbT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBUVEwgZm9yIGEgc3RyZWFtLW93bmVyc2hpcCBiaW5kaW5nIChkZWZhdWx0IDFoKS4gTG9uZyBlbm91Z2ggdG8gb3V0bGl2ZSBhXG4gICAqIGJ1aWxkOyB0aGUgcHJvZHVjZXIgcmUtYmluZHMgYXMgbmVlZGVkLlxuICAgKi9cbiAgc3RyZWFtT3duZXJUdGxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIENyb3NzLXBvZCBmYW4tb3V0IGJ1cyBmb3IgYHNlbmQoKWAvYGJyb2FkY2FzdCgpYCwgd2lyZWQgYXQgY29uc3RydWN0aW9uLlxuICAgKiBXaGVuIG9taXR0ZWQgKGFuZCBubyBgcmVsYXlGYWN0b3J5YCBpcyBlbmFibGVkKSBkZWxpdmVyeSBpcyBMT0NBTC1PTkxZLlxuICAgKiBEZWdyYWRlcyB0byBsb2NhbC1vbmx5IGR1cmluZyBhIFJlZGlzIG91dGFnZS5cbiAgICovXG4gIHJlbGF5PzogU1NFUmVsYXk7XG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHJlbGF5IG9uIGRlbWFuZCDigJQgc2VlIHtAbGluayBTU0VNYW5hZ2VyLmVuYWJsZVJlbGF5fS4gTGV0cyBhXG4gICAqIHNlcnZpY2Ugb3BlbiBhIHJlbGF5IGNvbm5lY3Rpb24gb25seSB3aGVuIGl0IGFjdHVhbGx5IGhhcyBhIHN0cmVhbWluZ1xuICAgKiBjaGFubmVsICh0aGUgbG9nIHN0cmVhbSwgb3IgYW4gb3JnLWtleWVkIGNoYW5uZWwpLiBSZXR1cm5pbmcgbnVsbCAoUmVkaXNcbiAgICogbm90IGNvbmZpZ3VyZWQpIGtlZXBzIGxvY2FsLW9ubHkgZGVsaXZlcnkuXG4gICAqL1xuICByZWxheUZhY3Rvcnk/OiAoKSA9PiBTU0VSZWxheSB8IG51bGw7XG59XG5cbi8qKlxuICogQSBidWlsZC1sb2cgc3RyZWFtIHN1YmplY3QgaWQ6IGVpdGhlciBhIGRhc2hlZCBVVUlEIChhcGktc2VydmVyJ3MgYHV1aWQoKWApXG4gKiBvciBuZ2lueCdzIGAkcmVxdWVzdF9pZGAg4oCUIDE2IHJhbmRvbSBieXRlcyByZW5kZXJlZCBhcyAzMiBoZXggY2hhcnMgd2l0aCBOT1xuICogZGFzaGVzLiBBY2NlcHQgYm90aCBieSBtYWtpbmcgdGhlIGdyb3VwIHNlcGFyYXRvcnMgb3B0aW9uYWw7IHN0aWxsIHN0cmljdGx5XG4gKiAzMiBoZXggY2hhcnMgc28gaXQgY2FuJ3QgY2FycnkgYW4gaW5qZWN0aW9uIC8gcGF0aC10cmF2ZXJzYWwgcGF5bG9hZCBpbnRvIHRoZVxuICogU1NFIHN1YmplY3QuIFNoYXJlZCBieSB0aGUgdGlja2V0LW1pbnQgcm91dGUgYW5kIHRoZSBzdHJlYW0gbWlkZGxld2FyZSBzb1xuICogYm90aCB2YWxpZGF0ZSB0aGUgc3ViamVjdCBpZGVudGljYWxseS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNTRV9SRVFVRVNUX0lEX1JFID0gL15bMC05YS1mXXs4fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17MTJ9JC9pO1xuXG5leHBvcnQgdHlwZSB7IENyZWF0ZVRpY2tldFJlc3VsdCB9O1xuXG4vKipcbiAqIFNTRSBNYW5hZ2VyIHN0YXRpc3RpY3NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTU0VNYW5hZ2VyU3RhdHMge1xuICB0b3RhbFJlcXVlc3RzOiBudW1iZXI7XG4gIHRvdGFsQ2xpZW50czogbnVtYmVyO1xuICBvbGRlc3RDb25uZWN0aW9uTXM6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKlxuICogU1NFIGhlbHBlciBjbGFzcyB3aXRoIG1lbW9yeSBsZWFrIHByb3RlY3Rpb25cbiAqXG4gKiBGZWF0dXJlczpcbiAqIC0gQ2xpZW50IGxpbWl0cyBwZXIgcmVxdWVzdCBJRFxuICogLSBBdXRvbWF0aWMgdGltZW91dCBmb3IgaWRsZSBjb25uZWN0aW9uc1xuICogLSBQZXJpb2RpYyBjbGVhbnVwIG9mIHN0YWxlIGNvbm5lY3Rpb25zXG4gKiAtIENvbm5lY3Rpb24gc3RhdGlzdGljc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBzc2VNYW5hZ2VyID0gbmV3IFNTRU1hbmFnZXIoeyBtYXhDbGllbnRzUGVyUmVxdWVzdDogNSB9KTtcbiAqIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG4gKlxuICogLy8gU2VuZCBldmVudHNcbiAqIHNzZU1hbmFnZXIuc2VuZCgncmVxdWVzdC0xMjMnLCAnSU5GTycsICdQcm9jZXNzaW5nLi4uJyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFNTRU1hbmFnZXIge1xuICBwcml2YXRlIGNsaWVudHMgPSBuZXcgTWFwPHN0cmluZywgU1NFQ2xpZW50W10+KCk7XG4gIC8qKiBQZXItb3JnIG9wZW4tY2xpZW50IGNvdW50ZXJzLiBEZWNyZW1lbnRlZCBvbiByZW1vdmVDbGllbnQvY2xlYW51cCBzbyB0aGVcbiAgICogIG1hcCBtaXJyb3JzIGBjbGllbnRzW10ub3JnSWRgIGNvdW50cyBhdCBhbGwgdGltZXMuIE9yZ3MgcmVhY2ggemVybyBhcmVcbiAgICogIGRlbGV0ZWQgdG8ga2VlcCB0aGUgbWFwIGJvdW5kZWQuICovXG4gIHByaXZhdGUgb3JnQ2xpZW50Q291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIFRpY2tldCBtaW50aW5nIC8gcmVkZW1wdGlvbiArIHN0cmVhbSBvd25lcnNoaXAgKHNlZSAuL3NzZS10aWNrZXQtYnJva2VyLnRzKS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0aWNrZXRzOiBTc2VUaWNrZXRCcm9rZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbENsaWVudHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50VGltZW91dE1zOiBudW1iZXI7XG4gIHByaXZhdGUgY2xlYW51cEludGVydmFsOiBOb2RlSlMuVGltZW91dCB8IG51bGwgPSBudWxsO1xuICAvKiogQ3Jvc3MtcG9kIGZhbi1vdXQgYnVzICh1bmRlZmluZWQg4oeSIGxvY2FsLW9ubHkgZGVsaXZlcnkpLiAqL1xuICBwcml2YXRlIHJlbGF5PzogU1NFUmVsYXk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVsYXlGYWN0b3J5PzogKCkgPT4gU1NFUmVsYXkgfCBudWxsO1xuICAvKiogV2hldGhlciBgY3R4LmxvZ2AgZnJhbWVzIGFyZSBzdHJlYW1lZCAoc2VlIHtAbGluayBTU0VNYW5hZ2VyT3B0aW9ucy5sb2dTdHJlYW19KS4gKi9cbiAgcmVhZG9ubHkgbG9nU3RyZWFtRW5hYmxlZDogYm9vbGVhbjtcbiAgLyoqIFRoaXMgbWFuYWdlciBpbnN0YW5jZSdzIGlkIOKAlCB0YWdzIHJlbGF5ZWQgZnJhbWVzIHNvIHdlIGlnbm9yZSBvdXIgb3duIGVjaG8uICovXG4gIHByaXZhdGUgcmVhZG9ubHkgbm9kZUlkID0gcmFuZG9tQnl0ZXMoOCkudG9TdHJpbmcoJ2hleCcpO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNTRU1hbmFnZXJPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0ID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyUmVxdWVzdCA/PyBlbnZJbnQoJ1NTRV9NQVhfQ0xJRU5UU19QRVJfUkVRVUVTVCcsIDEwLCB7IG1pbjogMSB9KTtcbiAgICB0aGlzLm1heFRvdGFsQ2xpZW50cyA9IG9wdGlvbnMubWF4VG90YWxDbGllbnRzID8/IGVudkludCgnU1NFX01BWF9UT1RBTF9DTElFTlRTJywgMTAwMCwgeyBtaW46IDEgfSk7XG4gICAgdGhpcy5tYXhDbGllbnRzUGVyT3JnID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyT3JnID8/IGVudkludCgnU1NFX01BWF9DTElFTlRTX1BFUl9PUkcnLCA1MCwgeyBtaW46IDEgfSk7XG4gICAgdGhpcy50aWNrZXRzID0gbmV3IFNzZVRpY2tldEJyb2tlcih7XG4gICAgICBzdG9yZTogb3B0aW9ucy50aWNrZXRTdG9yZSxcbiAgICAgIG1heFRvdGFsOiBvcHRpb25zLm1heFRvdGFsVGlja2V0cyxcbiAgICAgIG1heFBlck9yZzogb3B0aW9ucy5tYXhUaWNrZXRzUGVyT3JnLFxuICAgICAgdHRsTXM6IG9wdGlvbnMudGlja2V0VHRsTXMsXG4gICAgICBvd25lclR0bE1zOiBvcHRpb25zLnN0cmVhbU93bmVyVHRsTXMsXG4gICAgfSk7XG4gICAgdGhpcy5sb2dTdHJlYW1FbmFibGVkID0gb3B0aW9ucy5sb2dTdHJlYW0gPz8gZmFsc2U7XG4gICAgdGhpcy5jbGllbnRUaW1lb3V0TXMgPSBvcHRpb25zLmNsaWVudFRpbWVvdXRNcyA/PyBlbnZJbnQoJ1NTRV9DTElFTlRfVElNRU9VVF9NUycsIDFfODAwXzAwMCwgeyBtaW46IDEgfSk7IC8vIDMwIG1pbnV0ZXNcblxuICAgIGNvbnN0IGNsZWFudXBJbnRlcnZhbE1zID0gb3B0aW9ucy5jbGVhbnVwSW50ZXJ2YWxNcyA/PyBlbnZJbnQoJ1NTRV9DTEVBTlVQX0lOVEVSVkFMX01TJywgMzAwXzAwMCwgeyBtaW46IDEgfSk7IC8vIDUgbWludXRlc1xuICAgIHRoaXMuc3RhcnRDbGVhbnVwSW50ZXJ2YWwoY2xlYW51cEludGVydmFsTXMpO1xuXG4gICAgLy8gV2lyZSB0aGUgY3Jvc3MtcG9kIHJlbGF5OiBzdWJzY3JpYmUgb25jZSBvbiBzdGFydHVwIHNvIGZyYW1lcyBQVUJMSVNIRUQgYnlcbiAgICAvLyBhbnkgb3RoZXIgcG9kIGFyZSByZS1lbWl0dGVkIHRvIFRISVMgcG9kJ3MgbG9jYWwgY2xpZW50cy4gRnJhbWVzIHdlXG4gICAgLy8gcHVibGlzaGVkIG91cnNlbHZlcyBhcmUgaWdub3JlZCAob3JpZ2luID09PSBub2RlSWQpIOKAlCB3ZSBhbHJlYWR5IHdyb3RlIHRoZW1cbiAgICAvLyBsb2NhbGx5LiBGYWlsLXNhZmU6IG5vIHJlbGF5IOKHkiBsb2NhbC1vbmx5IGRlbGl2ZXJ5IChzaW5nbGUtcmVwbGljYSBkZWZhdWx0KS5cbiAgICB0aGlzLnJlbGF5RmFjdG9yeSA9IG9wdGlvbnMucmVsYXlGYWN0b3J5O1xuICAgIGlmIChvcHRpb25zLnJlbGF5KSB0aGlzLmF0dGFjaFJlbGF5KG9wdGlvbnMucmVsYXkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhdHRhY2hSZWxheShyZWxheTogU1NFUmVsYXkpOiB2b2lkIHtcbiAgICB0aGlzLnJlbGF5ID0gcmVsYXk7XG4gICAgcmVsYXkuc3Vic2NyaWJlKChtc2cpID0+IHRoaXMub25SZWxheU1lc3NhZ2UobXNnKSk7XG4gIH1cblxuICAvKipcbiAgICogVHVybiBvbiBjcm9zcy1wb2QgZGVsaXZlcnkgdXNpbmcgdGhlIGNvbmZpZ3VyZWQgYHJlbGF5RmFjdG9yeWAuIElkZW1wb3RlbnQ7XG4gICAqIGEgbm8tb3Agd2hlbiBhIHJlbGF5IGlzIGFscmVhZHkgd2lyZWQgb3Igbm8gZmFjdG9yeSB3YXMgZ2l2ZW4sIGFuZCB3aGVuIHRoZVxuICAgKiBmYWN0b3J5IHJldHVybnMgbnVsbCAoUmVkaXMgbm90IGNvbmZpZ3VyZWQg4oaSIGxvY2FsLW9ubHkgZGVsaXZlcnkpLlxuICAgKi9cbiAgZW5hYmxlUmVsYXkoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVsYXkgfHwgIXRoaXMucmVsYXlGYWN0b3J5KSByZXR1cm47XG4gICAgY29uc3QgcmVsYXkgPSB0aGlzLnJlbGF5RmFjdG9yeSgpO1xuICAgIGlmIChyZWxheSkgdGhpcy5hdHRhY2hSZWxheShyZWxheSk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGEgZnJhbWUgcmVjZWl2ZWQgZnJvbSBhbm90aGVyIHBvZCB2aWEgdGhlIHJlbGF5LiBXZSBhbHJlYWR5IGRlbGl2ZXJlZFxuICAgKiBvdXIgT1dOIGZyYW1lcyB0byBsb2NhbCBjbGllbnRzIGJlZm9yZSBwdWJsaXNoaW5nLCBzbyBpZ25vcmUgb3VyIGVjaG8uIEFcbiAgICogYHNlbmRgIHJlLWVtaXRzIHRvIHRoZSBzdWJqZWN0J3MgbG9jYWwgY2xpZW50czsgYSBgYnJvYWRjYXN0YCB0byBhbGwgb2YgdGhlbS5cbiAgICogUHVyZWx5IGxvY2FsIOKAlCBuZXZlciByZS1wdWJsaXNoZXMsIHNvIHRoZXJlIGlzIG5vIGZhbi1vdXQgbG9vcC5cbiAgICovXG4gIHByaXZhdGUgb25SZWxheU1lc3NhZ2UobXNnOiBTU0VSZWxheU1lc3NhZ2UpOiB2b2lkIHtcbiAgICBpZiAoIW1zZyB8fCBtc2cub3JpZ2luID09PSB0aGlzLm5vZGVJZCkgcmV0dXJuO1xuICAgIGlmIChtc2cua2luZCA9PT0gJ2Jyb2FkY2FzdCcpIHtcbiAgICAgIHRoaXMuYnJvYWRjYXN0TG9jYWwobXNnLnBheWxvYWQpO1xuICAgIH0gZWxzZSBpZiAobXNnLnJlcXVlc3RJZCkge1xuICAgICAgdGhpcy5zZW5kTG9jYWwobXNnLnJlcXVlc3RJZCwgbXNnLnBheWxvYWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBUb3RhbCBvcGVuIGNvbm5lY3Rpb25zIGFjcm9zcyBhbGwgcmVxdWVzdHMuICovXG4gIHByaXZhdGUgdG90YWxDbGllbnRzKCk6IG51bWJlciB7XG4gICAgbGV0IG4gPSAwO1xuICAgIGZvciAoY29uc3QgY2xpZW50cyBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIG4gKz0gY2xpZW50cy5sZW5ndGg7XG4gICAgcmV0dXJuIG47XG4gIH1cblxuICAvKipcbiAgICogUHVibGlzaCB0aGUgY3VycmVudCBsaXZlLWNvbm5lY3Rpb24gY291bnQgYXMgYSBnYXVnZSBzbyBvbi1jYWxsIGNhbiBzZWUgU1NFXG4gICAqIHNhdHVyYXRpb24gKGFwcHJvYWNoIHRvIHRoZSBwZXItcHJvY2VzcyBjYXApIG9uIGEgZGFzaGJvYXJkLCBub3Qgb25seSBpblxuICAgKiBgZ2V0U3RhdHMoKWAvbG9ncy4gQ2FsbGVkIGFmdGVyIGV2ZXJ5IGFkZC9yZW1vdmUvXG4gICAqIGNsb3NlL2NsZWFudXAuIENoZWFwIChPKFIpKTsgbWV0cmljIGhlbHBlcnMgbmV2ZXIgdGhyb3cuXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUFjdGl2ZUdhdWdlKCk6IHZvaWQge1xuICAgIHNldEdhdWdlKCdzc2VfYWN0aXZlX2Nvbm5lY3Rpb25zJywge30sIHRoaXMudG90YWxDbGllbnRzKCkpO1xuICB9XG5cbiAgLyoqIEN1cnJlbnQgb3Blbi1zdHJlYW0gY291bnQgZm9yIGFuIG9yZyAoMCBpZiB1bnNlZW4pLiAqL1xuICBnZXRPcmdDbGllbnRDb3VudChvcmdJZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCB0aGUgb3JnIHRoYXQgT1dOUyBhIHN0cmVhbSBzdWJqZWN0LCBzbyB0aWNrZXQgbWludGluZyBjYW4gcmVmdXNlIGFcbiAgICogY3Jvc3MtdGVuYW50IG1pbnQuIERlbGVnYXRlcyB0byB0aGUgdGlja2V0IGJyb2tlci5cbiAgICovXG4gIGFzeW5jIGJpbmRTdHJlYW1Pd25lcihyZXF1ZXN0SWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMudGlja2V0cy5iaW5kU3RyZWFtT3duZXIocmVxdWVzdElkLCBvcmdJZCk7XG4gIH1cblxuICAvKipcbiAgICogTWludCBhIHNob3J0LWxpdmVkLCBzaW5nbGUtdXNlIHRpY2tldCBib3VuZCB0byBgb3JnSWRgIEFORCB0aGlzIHN0cmVhbVxuICAgKiBzdWJqZWN0IOKAlCBob3cgYSBicm93c2VyIG9wZW5zIGFuIEV2ZW50U291cmNlIHdpdGhvdXQgcHV0dGluZyBpdHMgSldUIGluIGFcbiAgICogcXVlcnkgc3RyaW5nLiBEZWxlZ2F0ZXMgdG8gdGhlIHRpY2tldCBicm9rZXIsIHdoaWNoIG93bnMgdGhlIG93bmVyc2hpcCBhbmRcbiAgICogY2FwIHJ1bGVzLlxuICAgKi9cbiAgYXN5bmMgY3JlYXRlVGlja2V0KG9yZ0lkOiBzdHJpbmcsIHJlcXVlc3RJZDogc3RyaW5nKTogUHJvbWlzZTxDcmVhdGVUaWNrZXRSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy50aWNrZXRzLmNyZWF0ZVRpY2tldChvcmdJZCwgcmVxdWVzdElkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbmQgQ09OU1VNRSBhIHRpY2tldCBmb3IgYSBzcGVjaWZpYyBzdHJlYW0gc3ViamVjdCAoc2luZ2xlLXVzZSxcbiAgICogc3ViamVjdC1ib3VuZCkuIERlbGVnYXRlcyB0byB0aGUgdGlja2V0IGJyb2tlci5cbiAgICovXG4gIGFzeW5jIGNvbnN1bWVUaWNrZXQodGlja2V0SWQ6IHN0cmluZywgcmVxdWVzdElkOiBzdHJpbmcpOiBQcm9taXNlPHsgb3JnSWQ6IHN0cmluZyB9IHwgbnVsbD4ge1xuICAgIHJldHVybiB0aGlzLnRpY2tldHMuY29uc3VtZVRpY2tldCh0aWNrZXRJZCwgcmVxdWVzdElkKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjbGllbnQgdG8gdGhlIFNTRSBtYW5hZ2VyXG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBVbmlxdWUgcmVxdWVzdCBJRFxuICAgKiBAcGFyYW0gcmVzIC0gRXhwcmVzcyBSZXNwb25zZSBvYmplY3RcbiAgICogQHBhcmFtIG9yZ0lkIC0gQXV0aGVudGljYXRlZCBvcmcgaWQgKG9wdGlvbmFsKS4gV2hlbiBzZXQsIGVuZm9yY2VzIHRoZVxuICAgKiAgIHBlci1vcmcgY2FwIGFuZCB0aGUgY291bnRlciBpcyBkZWNyZW1lbnRlZCBvbiBkaXNjb25uZWN0L2NsZWFudXAuXG4gICAqIEBwYXJhbSBtYXhDbGllbnRzRm9yU3ViamVjdCAtIFBlci1zdWJqZWN0IGNhcCBvdmVycmlkZSAoZGVmYXVsdFxuICAgKiAgIGBtYXhDbGllbnRzUGVyUmVxdWVzdGApLiBBbiBvcmcta2V5ZWQgY2hhbm5lbCdzIHN1YmplY3QgSVMgdGhlIG9yZywgc28gaXRcbiAgICogICBtdXN0IG5vdCBpbmhlcml0IHRoZSBzbWFsbCBwZXItYnVpbGQtcmVxdWVzdCBjYXAg4oCUIHNlZSB7QGxpbmsgYWRkT3JnQ2xpZW50fS5cbiAgICogQHJldHVybnMgdHJ1ZSBpZiBjbGllbnQgd2FzIGFkZGVkLCBmYWxzZSBpZiByZWplY3RlZCAobGltaXQgcmVhY2hlZClcbiAgICovXG4gIGFkZENsaWVudChyZXF1ZXN0SWQ6IHN0cmluZywgcmVzOiBSZXNwb25zZSwgb3JnSWQ/OiBzdHJpbmcsIG1heENsaWVudHNGb3JTdWJqZWN0OiBudW1iZXIgPSB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0KTogYm9vbGVhbiB7XG4gICAgLy8gTm9ybWFsaXplIHRoZSBtYXAga2V5OiB0aGUgc3ViamVjdCBpZCBpcyBhbGxvd2VkIGluIHR3byBmb3JtcyAoZGFzaGVkXG4gICAgLy8gYXBpLXNlcnZlciB1dWlkIHZzIHVuZGFzaGVkIG5naW54ICRyZXF1ZXN0X2lkKSwgYW5kIGEgcHJvZHVjZXIvY29uc3VtZXIgdGhhdFxuICAgIC8vIHJlbmRlciBpdCBkaWZmZXJlbnRseSB3b3VsZCBvdGhlcndpc2Uga2V5IGRpZmZlcmVudCBNYXAgZW50cmllcyDigJQgdGhlIGNsaWVudFxuICAgIC8vIHJlZ2lzdGVycyB1bmRlciBvbmUgYW5kIGV2ZXJ5IHNlbmQoKS9yZWxheSB3cml0ZXMgdG8gYW5vdGhlciwgZHJvcHBpbmcgYWxsXG4gICAgLy8gZnJhbWVzLiBOb3JtYWxpemluZyBoZXJlIChhbmQgaW4gc2VuZC9zZW5kTG9jYWwvY2xvc2VSZXF1ZXN0L2V0Yy4pIHVuaWZpZXMgdGhlbS5cbiAgICByZXF1ZXN0SWQgPSBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKSB8fCBbXTtcblxuICAgIC8vIENoZWNrIGNsaWVudCBsaW1pdFxuICAgIGlmIChleGlzdGluZy5sZW5ndGggPj0gbWF4Q2xpZW50c0ZvclN1YmplY3QpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBDbGllbnQgbGltaXQgcmVhY2hlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKG1heDogJHttYXhDbGllbnRzRm9yU3ViamVjdH0pYCk7XG4gICAgICBpbmNDb3VudGVyKCdzc2VfY29ubmVjdGlvbl9yZWplY3RlZF90b3RhbCcsIHsgcmVhc29uOiAncmVxdWVzdC1saW1pdCcgfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUHJvY2Vzcy13aWRlIGNhcDogcHJvdGVjdHMgZmQgdGFibGUgKyBtZW1vcnkgZnJvbSBydW5hd2F5IGRhc2hib2FyZHMuXG4gICAgaWYgKHRoaXMudG90YWxDbGllbnRzKCkgPj0gdGhpcy5tYXhUb3RhbENsaWVudHMpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBUb3RhbCBTU0UgY2xpZW50IGNhcCByZWFjaGVkIChtYXg6ICR7dGhpcy5tYXhUb3RhbENsaWVudHN9KTsgcmVqZWN0aW5nIG5ldyBjb25uZWN0aW9uYCk7XG4gICAgICBpbmNDb3VudGVyKCdzc2VfY29ubmVjdGlvbl9yZWplY3RlZF90b3RhbCcsIHsgcmVhc29uOiAndG90YWwtY2FwJyB9KTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBQZXItb3JnIGNhcDogcHJldmVudHMgb25lIG5vaXN5IG9yZyBmcm9tIG1vbm9wb2xpemluZyBwcm9jZXNzLXdpZGVcbiAgICAvLyBzbG90cy4gRW5mb3JjZWQgb25seSB3aGVuIG9yZ0lkIGlzIGtub3duIOKAlCBzZXJ2aWNlLWludGVybmFsIC8gYW5vbnltb3VzXG4gICAgLy8gc3RyZWFtcyB0aGF0IG5ldmVyIGlkZW50aWZ5IHdpdGggYW4gb3JnSWQgc3RheSBzdWJqZWN0IHRvIHRoZSBnbG9iYWxcbiAgICAvLyBjZWlsaW5ncyBhYm92ZS4gUmVzZXJ2ZSBhdG9taWNhbGx5IGJlZm9yZSBpbnNlcnQgc28gdHdvIGNvbmN1cnJlbnRcbiAgICAvLyByZXF1ZXN0cyBhdCB0aGUgbGltaXQgY2FuJ3QgYm90aCBzdWNjZWVkLlxuICAgIGlmIChvcmdJZCkge1xuICAgICAgY29uc3Qgb3JnQ3VycmVudCA9IHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgICAgIGlmIChvcmdDdXJyZW50ID49IHRoaXMubWF4Q2xpZW50c1Blck9yZykge1xuICAgICAgICBsb2dnZXIud2FybihgUGVyLW9yZyBTU0UgY2xpZW50IGNhcCByZWFjaGVkIGZvciAke29yZ0lkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1Blck9yZ30pOyByZWplY3RpbmcgbmV3IGNvbm5lY3Rpb25gKTtcbiAgICAgICAgaW5jQ291bnRlcignc3NlX2Nvbm5lY3Rpb25fcmVqZWN0ZWRfdG90YWwnLCB7IHJlYXNvbjogJ29yZy1jYXAnIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLm9yZ0NsaWVudENvdW50cy5zZXQob3JnSWQsIG9yZ0N1cnJlbnQgKyAxKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgdGltZW91dCBmb3IgdGhpcyBjbGllbnRcbiAgICBjb25zdCBjbGllbnRJZCA9IHV1aWQoKTtcbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBsb2dnZXIuZGVidWcoYENsaWVudCAke2NsaWVudElkfSB0aW1lZCBvdXQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudElkKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcy5lbmQoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1Jlc3BvbnNlIGFscmVhZHkgY2xvc2VkIG9uIHRpbWVvdXQnLCB7IHJlcXVlc3RJZCwgY2xpZW50SWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLmNsaWVudFRpbWVvdXRNcyk7XG5cbiAgICBjb25zdCBjbGllbnQ6IFNTRUNsaWVudCA9IHtcbiAgICAgIGlkOiBjbGllbnRJZCxcbiAgICAgIHJlcyxcbiAgICAgIGNvbm5lY3RlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgdGltZW91dCxcbiAgICAgIGJhY2twcmVzc3VyZUNvdW50OiAwLFxuICAgICAgb3JnSWQsXG4gICAgfTtcblxuICAgIC8vIEhhbmRsZSBkaXNjb25uZWN0aW9uXG4gICAgcmVzLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgcmVzLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci5lcnJvcihgU1NFIGNsaWVudCBlcnJvciBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH06YCwgZXJyKTtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50SWQpO1xuICAgIH0pO1xuXG4gICAgZXhpc3RpbmcucHVzaChjbGllbnQpO1xuICAgIHRoaXMuY2xpZW50cy5zZXQocmVxdWVzdElkLCBleGlzdGluZyk7XG4gICAgaW5jQ291bnRlcignc3NlX2Nvbm5lY3Rpb25zX3RvdGFsJywge30pO1xuICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcblxuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xpZW50ICR7Y2xpZW50SWR9IGNvbm5lY3RlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKHRvdGFsOiAke2V4aXN0aW5nLmxlbmd0aH0pYCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoIGEgY2xpZW50IHRvIGFuIE9SRy1rZXllZCBzdHJlYW0gKHRoZSBvcmcgaXMgdGhlIHN1YmplY3QpLiBDb3VudHNcbiAgICogYWdhaW5zdCB0aGUgcGVyLW9yZyBjYXAsIGFuZCB0aGUgb3JnIOKAlCBub3QgdGhlIHBlci1yZXF1ZXN0IGNhcCDigJQgYm91bmRzIGhvd1xuICAgKiBtYW55IHN0cmVhbXMgc2hhcmUgdGhlIHN1YmplY3QuXG4gICAqL1xuICBhZGRPcmdDbGllbnQob3JnSWQ6IHN0cmluZywgcmVzOiBSZXNwb25zZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFkZENsaWVudChvcmdJZCwgcmVzLCBvcmdJZCwgdGhpcy5tYXhDbGllbnRzUGVyT3JnKTtcbiAgfVxuXG4gIC8qKiBEcm9wIG9uZSBmcm9tIHRoZSBwZXItb3JnIGNvdW50ZXIuIElkZW1wb3RlbnQ6IGEgY291bnRlciBhdCAwIHN0YXlzIGF0IDBcbiAgICogIGFuZCB0aGUgb3JnIGtleSBpcyByZW1vdmVkIGZyb20gdGhlIG1hcC4gKi9cbiAgcHJpdmF0ZSBkZWNyZW1lbnRPcmdDb3VudChvcmdJZD86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghb3JnSWQpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwO1xuICAgIGlmIChjdXJyZW50IDw9IDEpIHRoaXMub3JnQ2xpZW50Q291bnRzLmRlbGV0ZShvcmdJZCk7XG4gICAgZWxzZSB0aGlzLm9yZ0NsaWVudENvdW50cy5zZXQob3JnSWQsIGN1cnJlbnQgLSAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgY2xpZW50IGZyb20gdGhlIG1hbmFnZXJcbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCBjbGllbnRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKTtcbiAgICBpZiAoIWNsaWVudHMpIHJldHVybjtcblxuICAgIGNvbnN0IHJlbWFpbmluZyA9IGNsaWVudHMuZmlsdGVyKGMgPT4ge1xuICAgICAgaWYgKGMuaWQgPT09IGNsaWVudElkKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjLnRpbWVvdXQpO1xuICAgICAgICAvLyBNaXJyb3IgdGhlIHBlci1vcmcgY291bnRlciDigJQgbXVzdCBkZWNyZW1lbnQgaGVyZSwgbm90IGp1c3QgaW4gdGhlXG4gICAgICAgIC8vIGV4cGxpY2l0IGNsb3NlIHBhdGhzLCBzaW5jZSAnY2xvc2UnLydlcnJvcicgZXZlbnQgaGFuZGxlcnMgYXJlIHRoZVxuICAgICAgICAvLyBwcmltYXJ5IGRpc2Nvbm5lY3Qgc2lnbmFsIGluIHByYWN0aWNlLlxuICAgICAgICB0aGlzLmRlY3JlbWVudE9yZ0NvdW50KGMub3JnSWQpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIGlmIChyZW1haW5pbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICBsb2dnZXIuZGVidWcoYEFsbCBjbGllbnRzIGRpc2Nvbm5lY3RlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIHJlbWFpbmluZyk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gYWxsIFNTRSBjbGllbnRzIGZvciBhIHJlcXVlc3RJZFxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gUmVxdWVzdCBJRFxuICAgKiBAcGFyYW0gdHlwZSAtIEV2ZW50IHR5cGVcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBNZXNzYWdlIHN0cmluZ1xuICAgKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YVxuICAgKiBAcmV0dXJucyBOdW1iZXIgb2YgY2xpZW50cyB0aGUgbWVzc2FnZSB3YXMgc2VudCB0b1xuICAgKi9cbiAgc2VuZChyZXF1ZXN0SWQ6IHN0cmluZywgdHlwZTogU1NFRXZlbnRUeXBlLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogbnVtYmVyIHtcbiAgICByZXF1ZXN0SWQgPSBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTsgLy8gdW5pZnkgcHJvZHVjZXIvY29uc3VtZXIga2V5IGZvcm1zXG4gICAgY29uc3QgcGF5bG9hZDogU1NFUGF5bG9hZCA9IHtcbiAgICAgIHRzOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB0eXBlLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIGRhdGEsXG4gICAgfTtcblxuICAgIC8vIERlbGl2ZXIgdG8gTE9DQUwgY2xpZW50cyBmaXJzdCwgdGhlbiByZWxheSB0aGUgU0FNRSBwYXlsb2FkIHRvIG90aGVyIHBvZHNcbiAgICAvLyBzbyBhbiBFdmVudFNvdXJjZSBhdHRhY2hlZCBvbiBhIGRpZmZlcmVudCByZXBsaWNhIGFsc28gcmVjZWl2ZXMgaXQuIFRoZVxuICAgIC8vIHJlbGF5IGlzIGZpcmUtYW5kLWZvcmdldCBhbmQgZmFpbC1zYWZlOiBubyByZWxheSAvIFJlZGlzIGRvd24g4oeSIGxvY2FsLW9ubHkuXG4gICAgY29uc3Qgc2VudENvdW50ID0gdGhpcy5zZW5kTG9jYWwocmVxdWVzdElkLCBwYXlsb2FkKTtcbiAgICB0aGlzLnB1Ymxpc2hSZWxheSh7IG9yaWdpbjogdGhpcy5ub2RlSWQsIGtpbmQ6ICdzZW5kJywgcmVxdWVzdElkLCBwYXlsb2FkIH0pO1xuICAgIHJldHVybiBzZW50Q291bnQ7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgYSBwcmUtYnVpbHQgcGF5bG9hZCB0byB0aGlzIHBvZCdzIExPQ0FMIGNsaWVudHMgZm9yIGByZXF1ZXN0SWRgLiBTaGFyZWRcbiAgICogYnkge0BsaW5rIHNlbmR9IChsb2NhbCBoYWxmKSBhbmQgdGhlIHJlbGF5IHJlLWVtaXQgcGF0aCAoe0BsaW5rIG9uUmVsYXlNZXNzYWdlfSksXG4gICAqIHNvIGEgcmVsYXllZCBmcmFtZSByZXVzZXMgdGhlIHByb2R1Y2VyJ3Mgb3JpZ2luYWwgYHRzYCByYXRoZXIgdGhhbiBhIG5ldyBvbmUuXG4gICAqIE5ldmVyIHJlbGF5cyDigJQgY2FsbGVycyBkZWNpZGUgd2hldGhlciB0byBwdWJsaXNoLlxuICAgKi9cbiAgcHJpdmF0ZSBzZW5kTG9jYWwocmVxdWVzdElkOiBzdHJpbmcsIHBheWxvYWQ6IFNTRVBheWxvYWQpOiBudW1iZXIge1xuICAgIHJlcXVlc3RJZCA9IG5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpOyAvLyBpZGVtcG90ZW50OyBjb3ZlcnMgdGhlIHJlbGF5IHJlLWVtaXQgcGF0aFxuICAgIGNvbnN0IGNsaWVudHMgPSBbLi4uKHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKSB8fCBbXSldO1xuICAgIGxldCBzZW50Q291bnQgPSAwO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBgZGF0YTogJHtKU09OLnN0cmluZ2lmeShwYXlsb2FkKX1cXG5cXG5gO1xuXG4gICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQmFja3ByZXNzdXJlOiBza2lwIGNsaWVudHMgd2hvc2Ugd3JpdGUgYnVmZmVyIGlzIGZ1bGxcbiAgICAgICAgaWYgKGNsaWVudC5yZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYW5Xcml0ZSA9IGNsaWVudC5yZXMud3JpdGUoc2VyaWFsaXplZCk7XG4gICAgICAgIGlmICghY2FuV3JpdGUpIHtcbiAgICAgICAgICBjbGllbnQuYmFja3ByZXNzdXJlQ291bnQrKztcbiAgICAgICAgICAvLyBEaXNjb25uZWN0IGNsaWVudHMgdGhhdCBjb25zaXN0ZW50bHkgY2FuJ3Qga2VlcCB1cCAoMTAgY29uc2VjdXRpdmUgYmFja3ByZXNzdXJlIGV2ZW50cylcbiAgICAgICAgICBpZiAoY2xpZW50LmJhY2twcmVzc3VyZUNvdW50ID49IENvcmVDb25zdGFudHMuU1NFX0JBQ0tQUkVTU1VSRV9USFJFU0hPTEQpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKGBEaXNjb25uZWN0aW5nIHNsb3cgY2xpZW50ICR7Y2xpZW50LmlkfSBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKCR7Y2xpZW50LmJhY2twcmVzc3VyZUNvdW50fSBiYWNrcHJlc3N1cmUgZXZlbnRzKWApO1xuICAgICAgICAgICAgaW5jQ291bnRlcignc3NlX2JhY2twcmVzc3VyZV9kaXNjb25uZWN0c190b3RhbCcsIHt9KTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgICAgICAgIHRyeSB7IGNsaWVudC5yZXMuZW5kKCk7IH0gY2F0Y2ggeyAvKiBhbHJlYWR5IGNsb3NlZCAqLyB9XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2xpZW50LmJhY2twcmVzc3VyZUNvdW50ID0gMDsgLy8gUmVzZXQgb24gc3VjY2Vzc2Z1bCB3cml0ZVxuICAgICAgICB9XG4gICAgICAgIHNlbnRDb3VudCsrO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc2VuZCB0byBjbGllbnQgJHtjbGllbnQuaWR9OmAsIGVycm9yKTtcbiAgICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnQuaWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzZW50Q291bnQ7XG4gIH1cblxuICAvKipcbiAgICogQnJvYWRjYXN0IGEgbWVzc2FnZSB0byBhbGwgY29ubmVjdGVkIGNsaWVudHMgYWNyb3NzIGFsbCByZXF1ZXN0c1xuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIEV2ZW50IHR5cGVcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBNZXNzYWdlIHN0cmluZ1xuICAgKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YVxuICAgKiBAcmV0dXJucyBUb3RhbCBudW1iZXIgb2YgY2xpZW50cyB0aGUgbWVzc2FnZSB3YXMgc2VudCB0b1xuICAgKi9cbiAgYnJvYWRjYXN0KHR5cGU6IFNTRUV2ZW50VHlwZSwgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bik6IG51bWJlciB7XG4gICAgY29uc3QgcGF5bG9hZDogU1NFUGF5bG9hZCA9IHtcbiAgICAgIHRzOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB0eXBlLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIGRhdGEsXG4gICAgfTtcbiAgICAvLyBEZWxpdmVyIHRvIGxvY2FsIGNsaWVudHMsIHRoZW4gcmVsYXkgYSBzaW5nbGUgYnJvYWRjYXN0IGZyYW1lIHNvIEVWRVJZIHBvZFxuICAgIC8vIHJlLWVtaXRzIHRvIEFMTCBvZiBpdHMgb3duIGNsaWVudHMg4oCUIGEgcGVyLXJlcXVlc3RJZCByZWxheSB3b3VsZCBtaXNzXG4gICAgLy8gc3ViamVjdHMgdGhhdCBvbmx5IGV4aXN0IG9uIG90aGVyIHJlcGxpY2FzLlxuICAgIGNvbnN0IHRvdGFsU2VudCA9IHRoaXMuYnJvYWRjYXN0TG9jYWwocGF5bG9hZCk7XG4gICAgdGhpcy5wdWJsaXNoUmVsYXkoeyBvcmlnaW46IHRoaXMubm9kZUlkLCBraW5kOiAnYnJvYWRjYXN0JywgcGF5bG9hZCB9KTtcbiAgICByZXR1cm4gdG90YWxTZW50O1xuICB9XG5cbiAgLyoqIFdyaXRlIGEgcHJlLWJ1aWx0IHBheWxvYWQgdG8gYWxsIExPQ0FMIGNsaWVudHMgYWNyb3NzIGV2ZXJ5IHJlcXVlc3QuICovXG4gIHByaXZhdGUgYnJvYWRjYXN0TG9jYWwocGF5bG9hZDogU1NFUGF5bG9hZCk6IG51bWJlciB7XG4gICAgbGV0IHRvdGFsU2VudCA9IDA7XG4gICAgZm9yIChjb25zdCByZXF1ZXN0SWQgb2YgWy4uLnRoaXMuY2xpZW50cy5rZXlzKCldKSB7XG4gICAgICB0b3RhbFNlbnQgKz0gdGhpcy5zZW5kTG9jYWwocmVxdWVzdElkLCBwYXlsb2FkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRvdGFsU2VudDtcbiAgfVxuXG4gIC8qKiBGaXJlLWFuZC1mb3JnZXQgcmVsYXkgcHVibGlzaC4gTm8tb3AgKGxvY2FsLW9ubHkpIHdoZW4gbm8gcmVsYXkgaXMgd2lyZWQuICovXG4gIHByaXZhdGUgcHVibGlzaFJlbGF5KG1zZzogU1NFUmVsYXlNZXNzYWdlKTogdm9pZCB7XG4gICAgdGhpcy5yZWxheT8ucHVibGlzaChtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIGFsbCBjbGllbnRzIGZvciBhIHNwZWNpZmljIHJlcXVlc3RcbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFJlcXVlc3QgSUQgdG8gY2xvc2VcbiAgICogQHBhcmFtIGZpbmFsTWVzc2FnZSAtIE9wdGlvbmFsIGZpbmFsIG1lc3NhZ2UgdG8gc2VuZCBiZWZvcmUgY2xvc2luZ1xuICAgKi9cbiAgY2xvc2VSZXF1ZXN0KHJlcXVlc3RJZDogc3RyaW5nLCBmaW5hbE1lc3NhZ2U/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICByZXF1ZXN0SWQgPSBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTtcbiAgICBpZiAoIXRoaXMuY2xpZW50cy5oYXMocmVxdWVzdElkKSkgcmV0dXJuO1xuXG4gICAgLy8gTE9DQUwgb25seTogdGhpcyBjbG9zZXMgdGhpcyBwb2QncyBjbGllbnRzLCBzbyB0aGUgZmluYWwgZnJhbWUgaXMgZm9yIHRoZW1cbiAgICAvLyAocmVsYXlpbmcgaXQgd291bGQgcHVzaCBhIENPTVBMRVRFRCB0byBvdGhlciBwb2RzJyBzdGlsbC1vcGVuIHN0cmVhbXMpLlxuICAgIGlmIChmaW5hbE1lc3NhZ2UpIHtcbiAgICAgIHRoaXMuc2VuZExvY2FsKHJlcXVlc3RJZCwgeyB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCB0eXBlOiAnQ09NUExFVEVEJywgbWVzc2FnZTogZmluYWxNZXNzYWdlIH0pO1xuICAgIH1cblxuICAgIC8vIFJlYWQgdGhlIGVudHJ5IEFGVEVSIHRoZSBmaW5hbCB3cml0ZTogc2VuZExvY2FsIHJlbW92ZXMgKGFuZCB1bi1jb3VudHMpXG4gICAgLy8gY2xpZW50cyB0aGF0IHdlcmUgYWxyZWFkeSBnb25lLCBzbyBpdGVyYXRpbmcgYW4gZWFybGllciBzbmFwc2hvdCB3b3VsZFxuICAgIC8vIGRlY3JlbWVudCB0aGVpciBvcmcgY291bnQgYSBzZWNvbmQgdGltZS5cbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgPz8gW10pIHtcbiAgICAgIGNsZWFyVGltZW91dChjbGllbnQudGltZW91dCk7XG4gICAgICB0aGlzLmRlY3JlbWVudE9yZ0NvdW50KGNsaWVudC5vcmdJZCk7XG4gICAgICB0cnkge1xuICAgICAgICBjbGllbnQucmVzLmVuZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUmVzcG9uc2UgYWxyZWFkeSBjbG9zZWQgb24gcmVxdWVzdCBjbG9zZScsIHsgcmVxdWVzdElkLCBjbGllbnRJZDogY2xpZW50LmlkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jbGllbnRzLmRlbGV0ZShyZXF1ZXN0SWQpO1xuICAgIHRoaXMudXBkYXRlQWN0aXZlR2F1Z2UoKTtcbiAgICBsb2dnZXIuZGVidWcoYENsb3NlZCBhbGwgY2xpZW50cyBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc3RhdGlzdGljcyBhYm91dCBjdXJyZW50IGNvbm5lY3Rpb25zXG4gICAqL1xuICBnZXRTdGF0cygpOiBTU0VNYW5hZ2VyU3RhdHMge1xuICAgIGxldCB0b3RhbENsaWVudHMgPSAwO1xuICAgIGxldCBvbGRlc3RDb25uZWN0aW9uOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gICAgZm9yIChjb25zdCBjbGllbnRzIG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkge1xuICAgICAgdG90YWxDbGllbnRzICs9IGNsaWVudHMubGVuZ3RoO1xuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgICBjb25zdCBhZ2UgPSBub3cgLSBjbGllbnQuY29ubmVjdGVkQXQ7XG4gICAgICAgIGlmIChvbGRlc3RDb25uZWN0aW9uID09PSBudWxsIHx8IGFnZSA+IG9sZGVzdENvbm5lY3Rpb24pIHtcbiAgICAgICAgICBvbGRlc3RDb25uZWN0aW9uID0gYWdlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsUmVxdWVzdHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgdG90YWxDbGllbnRzLFxuICAgICAgb2xkZXN0Q29ubmVjdGlvbk1zOiBvbGRlc3RDb25uZWN0aW9uLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSByZXF1ZXN0IGhhcyBhbnkgY29ubmVjdGVkIGNsaWVudHNcbiAgICovXG4gIGhhc0NsaWVudHMocmVxdWVzdElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBjbGllbnRzID0gdGhpcy5jbGllbnRzLmdldChub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSk7XG4gICAgcmV0dXJuIGNsaWVudHMgIT09IHVuZGVmaW5lZCAmJiBjbGllbnRzLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgY2xpZW50cyBmb3IgYSBzcGVjaWZpYyByZXF1ZXN0XG4gICAqL1xuICBnZXRDbGllbnRDb3VudChyZXF1ZXN0SWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50cy5nZXQobm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZCkpPy5sZW5ndGggPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaWRkbGV3YXJlIHRvIGluaXRpYWxpemUgYSB0aWNrZXQtYXV0aGVudGljYXRlZCBTU0UgY29ubmVjdGlvbi5cbiAgICpcbiAgICogVGhlIHN0cmVhbSBpcyBOT1Qgb3BlbiB0byB0aGUgd29ybGQ6IHRoZSBjYWxsZXIgbXVzdCBmaXJzdCBleGNoYW5nZSBpdHNcbiAgICogSldUIGZvciBhIHNob3J0LWxpdmVkIHNpbmdsZS11c2UgdGlja2V0IChzZWUge0BsaW5rIGNyZWF0ZVRpY2tldH0sIHdpcmVkIHRvXG4gICAqIGBQT1NUIC9sb2dzL3RpY2tldGApIGFuZCBwYXNzIGl0IGFzIGA/dGlja2V0PTx0PmAuIFRoZSBtaWRkbGV3YXJlIHZhbGlkYXRlc1xuICAgKiArIGNvbnN1bWVzIHRoZSB0aWNrZXQsIGJpbmRzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSB0aWNrZXQncyBvcmcsIGFuZFxuICAgKiBlbmZvcmNlcyB0aGUgcGVyLW9yZyBjb25uZWN0aW9uIGNhcC4gQSBtaXNzaW5nIC8gaW52YWxpZCAvIGV4cGlyZWQgL1xuICAgKiBhbHJlYWR5LXVzZWQgdGlja2V0IGlzIHJlamVjdGVkIHdpdGggNDAxIGJlZm9yZSBhbnkgU1NFIGhlYWRlcnMgZmx1c2guXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogYXBwLmdldCgnL2xvZ3MvOnJlcXVlc3RJZCcsIHNzZU1hbmFnZXIubWlkZGxld2FyZSgpKTtcbiAgICogYGBgXG4gICAqL1xuICBtaWRkbGV3YXJlKCkge1xuICAgIHJldHVybiBhc3luYyAocmVxOiB7IHBhcmFtczogeyByZXF1ZXN0SWQ6IHN0cmluZyB9OyBxdWVyeT86IHsgdGlja2V0PzogdW5rbm93biB9IH0sIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgIGNvbnN0IHsgcmVxdWVzdElkIH0gPSByZXEucGFyYW1zO1xuXG4gICAgICBpZiAoIVNTRV9SRVFVRVNUX0lEX1JFLnRlc3QocmVxdWVzdElkKSkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMCkuZW5kKCdJbnZhbGlkIHJlcXVlc3RJZCBmb3JtYXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUaWNrZXQgYXV0aCDigJQgcmVxdWlyZWQuIFJlc29sdmUgYD90aWNrZXQ9PHQ+YCwgdGhlbiB2YWxpZGF0ZSArIGNvbnN1bWVcbiAgICAgIC8vIGl0IChzaW5nbGUtdXNlKSBGT1IgVEhJUyBTVUJKRUNULiBBbiBhbm9ueW1vdXMsIG1hbGZvcm1lZCwgdW5rbm93bixcbiAgICAgIC8vIGV4cGlyZWQsIGFscmVhZHktY29uc3VtZWQsIG9yIHdyb25nLXN1YmplY3QgdGlja2V0IGlzIGEgNDAxLiBUaGUgb3JnIGlzXG4gICAgICAvLyB0YWtlbiBmcm9tIHRoZSB0aWNrZXQsIHNvIHRoZSBzdHJlYW0gaXMgYWx3YXlzIGJvdW5kIHRvIGEgdmVyaWZpZWRcbiAgICAgIC8vIHRlbmFudCBBTkQgdG8gdGhlIGV4YWN0IHN1YmplY3QgdGhlIHRpY2tldCB3YXMgbWludGVkIGZvciAobm8gYW5vbnltb3VzXG4gICAgICAvLyBzdHJlYW1zLCBubyBjcm9zcy1zdWJqZWN0IGF0dGFjaCkuXG4gICAgICBjb25zdCB0aWNrZXRJZCA9IHJlcS5xdWVyeT8udGlja2V0O1xuICAgICAgaWYgKHR5cGVvZiB0aWNrZXRJZCAhPT0gJ3N0cmluZycgfHwgdGlja2V0SWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAxKS5lbmQoJ01pc3NpbmcgdGlja2V0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbnN1bWVkID0gYXdhaXQgdGhpcy5jb25zdW1lVGlja2V0KHRpY2tldElkLCByZXF1ZXN0SWQpO1xuICAgICAgaWYgKCFjb25zdW1lZCkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMSkuZW5kKCdJbnZhbGlkIG9yIGV4cGlyZWQgdGlja2V0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG9yZ0lkID0gY29uc3VtZWQub3JnSWQ7XG5cbiAgICAgIC8vIFByZS1mbGlnaHQgcGVyLXJlcXVlc3QgY2FwIHNvIHdlIGNhbiByZXR1cm4gNDI5IGJlZm9yZSBmbHVzaGluZ1xuICAgICAgLy8gU1NFIGhlYWRlcnMgKGFmdGVyIGhlYWRlcnMgYXJlIGZsdXNoZWQgdGhlIGNsaWVudCBjYW4ndCByZWFkIGEgNDI5KS5cbiAgICAgIC8vXG4gICAgICAvLyBOT1JNQUxJWkUgZmlyc3Q6IGBhZGRDbGllbnRgIGtleXMgdGhlIG1hcCBvbiB0aGUgbm9ybWFsaXplZCBmb3JtXG4gICAgICAvLyAoZGFzaGVzIHN0cmlwcGVkKSwgc28gcmVhZGluZyB0aGUgcmF3IGByZXF1ZXN0SWRgIGhlcmUgYWx3YXlzIGZvdW5kIDBcbiAgICAgIC8vIGZvciBhIGNsaWVudCB1c2luZyB0aGUgZGFzaGVkIGZvcm0uIFRoZSBjYXAgd2FzIHRoZW4gb25seSBjYXVnaHQgaW5zaWRlXG4gICAgICAvLyBgYWRkQ2xpZW50YCDigJQgQUZURVIgYGZsdXNoSGVhZGVycygpYCDigJQgd2hpY2ggaXMgZXhhY3RseSB0aGUgY2FzZSB0aGlzXG4gICAgICAvLyBwcmUtZmxpZ2h0IGV4aXN0cyB0byBhdm9pZDogdGhlIGNsaWVudCBnb3QgYSBzaWxlbnRseS1jbG9zZWQgc3RyZWFtXG4gICAgICAvLyBpbnN0ZWFkIG9mIGEgNDI5LlxuICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmNsaWVudHMuZ2V0KG5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpKSB8fCBbXTtcbiAgICAgIGlmIChleGlzdGluZy5sZW5ndGggPj0gdGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdCkge1xuICAgICAgICBsb2dnZXIud2FybihgQ2xpZW50IGxpbWl0IHJlYWNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdH0pYCk7XG4gICAgICAgIHJlcy5zdGF0dXMoNDI5KS5lbmQoJ1RvbyBtYW55IGNvbm5lY3Rpb25zIGZvciB0aGlzIHJlcXVlc3QnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTYW1lIGZvciB0aGUgcGVyLW9yZyBjYXAg4oCUIGJldHRlciB0byBzZW5kIDQyOSB0aGFuIG9wZW4gdGhlIHN0cmVhbSBhbmRcbiAgICAgIC8vIGltbWVkaWF0ZWx5IGNsb3NlIGl0LiBUaGUgdGlja2V0IGd1YXJhbnRlZXMgYSB2ZXJpZmllZCBvcmcgaWQsIHNvIHRoZVxuICAgICAgLy8gcGVyLW9yZyBjZWlsaW5nIGlzIGFsd2F5cyBlbmZvcmNlZCBmb3IgdGhlIC9sb2dzIHN0cmVhbS5cbiAgICAgIGlmICgodGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwKSA+PSB0aGlzLm1heENsaWVudHNQZXJPcmcpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJPcmd9KWApO1xuICAgICAgICByZXMuc3RhdHVzKDQyOSkuZW5kKCdUb28gbWFueSBTU0UgY29ubmVjdGlvbnMgZm9yIHRoaXMgb3JnYW5pemF0aW9uJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgd3JpdGVTc2VIZWFkZXJzKHJlcyk7XG4gICAgICByZXMuZmx1c2hIZWFkZXJzKCk7XG5cbiAgICAgIC8vIEhlYWRlcnMgYXJlIGZsdXNoZWQg4oCUIHdlIGNhbiBubyBsb25nZXIgc2VuZCBhIDQyOS4gYWRkQ2xpZW50IHJlLWNoZWNrc1xuICAgICAgLy8gdGhlIGNhcHMgKGluY2x1ZGluZyB0aGUgcHJvY2Vzcy13aWRlIHRvdGFsLWNsaWVudHMgY2FwLCB3aGljaCB0aGVcbiAgICAgIC8vIHByZS1mbGlnaHQgYWJvdmUgZG9lcyBub3QpIGFuZCBjYW4gc3RpbGwgcmVqZWN0IG9uIGEgcmFjZTogYSBjb25jdXJyZW50XG4gICAgICAvLyBjb25uZWN0aW9uIG1heSBoYXZlIGZpbGxlZCBhIGNhcCBiZXR3ZWVuIHRoZSBwcmUtZmxpZ2h0IGNoZWNrIGFuZCBoZXJlLlxuICAgICAgLy8gT24gcmVqZWN0aW9uLCBjbG9zZSB0aGUgbm93LWRhbmdsaW5nIHJlc3BvbnNlIGluc3RlYWQgb2YgbGVhdmluZyBhblxuICAgICAgLy8gb3BlbiBzb2NrZXQgd2l0aCBubyBjbGllbnQgcmVjb3JkICh3aGljaCB3b3VsZCBsZWFrIGFuIGZkICsgbmV2ZXIgZW1pdFxuICAgICAgLy8gc3RyZWFtIGRhdGEpLlxuICAgICAgY29uc3QgYWRkZWQgPSB0aGlzLmFkZENsaWVudChyZXF1ZXN0SWQsIHJlcywgb3JnSWQpO1xuICAgICAgaWYgKCFhZGRlZCkge1xuICAgICAgICBsb2dnZXIud2FybihgU1NFIGFkZENsaWVudCByZWplY3RlZCBhZnRlciBoZWFkZXJzIGZsdXNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9OyBjbG9zaW5nIGRhbmdsaW5nIHJlc3BvbnNlYCk7XG4gICAgICAgIHRyeSB7IHJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHBlcmlvZGljIGNsZWFudXAgb2Ygc3RhbGUgY29ubmVjdGlvbnNcbiAgICovXG4gIHByaXZhdGUgc3RhcnRDbGVhbnVwSW50ZXJ2YWwoaW50ZXJ2YWxNczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICB9LCBpbnRlcnZhbE1zKTtcblxuICAgIC8vIERvbid0IHByZXZlbnQgcHJvY2VzcyBleGl0XG4gICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwudW5yZWYoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBzdGFsZSBjb25uZWN0aW9ucyB1c2luZyBzaW5nbGUtcGFzcyBwYXJ0aXRpb24uXG4gICAqIE8oUiDDlyBDKSBpbnN0ZWFkIG9mIE8oUiDDlyBDwrIpLCBhbmQgYXZvaWRzIG11dGF0aW9uLWR1cmluZy1pdGVyYXRpb24uXG4gICAqL1xuICBwcml2YXRlIGNsZWFudXAoKTogdm9pZCB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgY2xlYW5lZCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IFtyZXF1ZXN0SWQsIGNsaWVudHNdIG9mIHRoaXMuY2xpZW50cy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHN0YWxlOiBTU0VDbGllbnRbXSA9IFtdO1xuICAgICAgY29uc3QgYWN0aXZlOiBTU0VDbGllbnRbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICAgIC8vIFRpbWUtYmFzZWQgZXZpY3Rpb24gT1IgYSBzb2NrZXQgdGhhdCBzaWxlbnRseSBjbG9zZWQgKG5vICdjbG9zZSdcbiAgICAgICAgLy8gZXZlbnQpIOKAlCBOb2RlIHNvbWV0aW1lcyBkcm9wcyBzb2NrZXRzIHdpdGhvdXQgZmlyaW5nIHRoZSBldmVudCxcbiAgICAgICAgLy8gc28gd2UgZXhwbGljaXRseSBjaGVjayB3cml0YWJsZUVuZGVkL2Rlc3Ryb3llZCBoZXJlLlxuICAgICAgICBjb25zdCBhZ2VTdGFsZSA9IG5vdyAtIGNsaWVudC5jb25uZWN0ZWRBdCA+IHRoaXMuY2xpZW50VGltZW91dE1zO1xuICAgICAgICBjb25zdCBzb2NrZXREZWFkID0gY2xpZW50LnJlcy53cml0YWJsZUVuZGVkIHx8IChjbGllbnQucmVzIGFzIHsgZGVzdHJveWVkPzogYm9vbGVhbiB9KS5kZXN0cm95ZWQgPT09IHRydWU7XG4gICAgICAgIGlmIChhZ2VTdGFsZSB8fCBzb2NrZXREZWFkKSB7XG4gICAgICAgICAgc3RhbGUucHVzaChjbGllbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFjdGl2ZS5wdXNoKGNsaWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2Ygc3RhbGUpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGNsaWVudC50aW1lb3V0KTtcbiAgICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjbGllbnQub3JnSWQpO1xuICAgICAgICB0cnkgeyBjbGllbnQucmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgICBjbGVhbmVkKys7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3RpdmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhbGUubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgYWN0aXZlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2xlYW5lZCA+IDApIHtcbiAgICAgIGluY0NvdW50ZXIoJ3NzZV9zdGFsZV9jbGVhbmVkX3RvdGFsJywge30sIGNsZWFuZWQpO1xuICAgICAgdGhpcy51cGRhdGVBY3RpdmVHYXVnZSgpO1xuICAgICAgbG9nZ2VyLmluZm8oYENsZWFuZWQgdXAgJHtjbGVhbmVkfSBzdGFsZSBTU0UgY29ubmVjdGlvbnNgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2h1dGRvd24gdGhlIFNTRSBtYW5hZ2VyIGFuZCBjbG9zZSBhbGwgY29ubmVjdGlvbnNcbiAgICovXG4gIHNodXRkb3duKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNsZWFudXBJbnRlcnZhbCkge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmNsZWFudXBJbnRlcnZhbCk7XG4gICAgICB0aGlzLmNsZWFudXBJbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0SWQgb2YgWy4uLnRoaXMuY2xpZW50cy5rZXlzKCldKSB7XG4gICAgICB0aGlzLmNsb3NlUmVxdWVzdChyZXF1ZXN0SWQsICdTZXJ2ZXIgc2h1dHRpbmcgZG93bicpO1xuICAgIH1cblxuICAgIC8vIFRlYXIgZG93biB0aGUgcmVsYXkncyBSZWRpcyBjb25uZWN0aW9ucyAoYmVzdC1lZmZvcnQ7IG5ldmVyIHRocm93cykuXG4gICAgdm9pZCB0aGlzLnJlbGF5Py5jbG9zZSgpLmNhdGNoKCgpID0+IHsgLyogYWxyZWFkeSBjbG9zaW5nICovIH0pO1xuICAgIHRoaXMudGlja2V0cy5zaHV0ZG93bigpO1xuXG4gICAgbG9nZ2VyLmluZm8oJ1NTRSBNYW5hZ2VyIHNodXQgZG93bicpO1xuICB9XG59XG4iXX0=