@pipeline-builder/pipeline-data 4.1.15 → 4.1.17

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.
Files changed (60) hide show
  1. package/lib/api/access-control-builder.d.ts +18 -1
  2. package/lib/api/access-control-builder.js +19 -6
  3. package/lib/api/crud-service.d.ts +94 -36
  4. package/lib/api/crud-service.js +188 -166
  5. package/lib/api/plugin-resolution.d.ts +253 -0
  6. package/lib/api/plugin-resolution.js +649 -0
  7. package/lib/api/public-directory.d.ts +281 -0
  8. package/lib/api/public-directory.js +457 -0
  9. package/lib/api/query-builders.d.ts +13 -0
  10. package/lib/api/query-builders.js +74 -9
  11. package/lib/api/reporting/caches.js +4 -4
  12. package/lib/api/reporting/dora-scoring.d.ts +3 -3
  13. package/lib/api/reporting/dora-scoring.js +4 -4
  14. package/lib/api/reporting/dora.d.ts +6 -6
  15. package/lib/api/reporting/dora.js +97 -73
  16. package/lib/api/reporting/plugin-runtime.d.ts +25 -0
  17. package/lib/api/reporting/plugin-runtime.js +106 -0
  18. package/lib/api/reporting/query-scope.d.ts +8 -2
  19. package/lib/api/reporting/query-scope.js +16 -7
  20. package/lib/api/reporting/retention.d.ts +4 -10
  21. package/lib/api/reporting/retention.js +8 -11
  22. package/lib/api/reporting/sql-helpers.d.ts +4 -7
  23. package/lib/api/reporting/sql-helpers.js +8 -9
  24. package/lib/api/reporting/types.d.ts +55 -17
  25. package/lib/api/reporting/types.js +1 -1
  26. package/lib/api/reporting-service.d.ts +35 -26
  27. package/lib/api/reporting-service.js +245 -161
  28. package/lib/api/semver-range.d.ts +73 -0
  29. package/lib/api/semver-range.js +227 -0
  30. package/lib/api/soft-delete-sweep.js +8 -20
  31. package/lib/core/query-filters.d.ts +18 -3
  32. package/lib/core/query-filters.js +1 -1
  33. package/lib/database/drizzle-schema.d.ts +7790 -2461
  34. package/lib/database/drizzle-schema.js +29 -1
  35. package/lib/database/index.d.ts +4 -2
  36. package/lib/database/index.js +5 -3
  37. package/lib/database/pg-result.d.ts +19 -0
  38. package/lib/database/pg-result.js +32 -0
  39. package/lib/database/postgres-connection.js +14 -24
  40. package/lib/database/public-reader.d.ts +14 -0
  41. package/lib/database/public-reader.js +68 -0
  42. package/lib/database/retry-strategy.d.ts +3 -5
  43. package/lib/database/retry-strategy.js +4 -6
  44. package/lib/database/schema/compliance.d.ts +16 -34
  45. package/lib/database/schema/compliance.js +4 -4
  46. package/lib/database/schema/dashboard.js +4 -2
  47. package/lib/database/schema/ecosystem.d.ts +6586 -0
  48. package/lib/database/schema/ecosystem.js +709 -0
  49. package/lib/database/schema/message.d.ts +6 -12
  50. package/lib/database/schema/message.js +3 -1
  51. package/lib/database/schema/pipeline.d.ts +79 -5
  52. package/lib/database/schema/pipeline.js +46 -25
  53. package/lib/database/schema/plugin.d.ts +587 -3
  54. package/lib/database/schema/plugin.js +86 -14
  55. package/lib/database/tenancy.d.ts +6 -7
  56. package/lib/database/tenancy.js +13 -14
  57. package/lib/index.d.ts +7 -4
  58. package/lib/index.js +7 -4
  59. package/lib/testing/exports.json +146 -0
  60. package/package.json +44 -7
@@ -1,7 +1,7 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { ConflictError, NotFoundError, createLogger, DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT } from '@pipeline-builder/api-core';
4
- import { SQL, eq, and, or, asc, desc, sql, inArray, getTableColumns } from 'drizzle-orm';
3
+ import { ConflictError, NotFoundError, createLogger, DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT, SYSTEM_ACTOR_ID, envInt } from '@pipeline-builder/api-core';
4
+ import { SQL, eq, and, or, asc, desc, sql, inArray, isNull, getTableColumns } from 'drizzle-orm';
5
5
  import { withTenantTx, runWithTenantContext, getTenantContext } from '../database/tenancy.js';
6
6
  /**
7
7
  * Cast Drizzle query results to a typed array.
@@ -92,7 +92,7 @@ function keysetAfter(sortColumn, idColumn, sortOrder, sortText, id) {
92
92
  * Stamped into `purge_after` at delete time; the per-service purge sweep hard-
93
93
  * deletes tombstones once it has passed. `0` disables purge-deadline stamping.
94
94
  */
95
- const SOFT_DELETE_RETENTION_MS = Math.max(0, Number.parseInt(process.env.SOFT_DELETE_RETENTION_DAYS ?? '30', 10) || 0) * 24 * 60 * 60 * 1000;
95
+ const SOFT_DELETE_RETENTION_MS = envInt('SOFT_DELETE_RETENTION_DAYS', 30, { min: 0 }) * 24 * 60 * 60 * 1000;
96
96
  /** The shared soft-delete retention window in ms (`SOFT_DELETE_RETENTION_DAYS`,
97
97
  * default 30d; 0 disables purge-deadline stamping). Exposed so non-CrudService
98
98
  * soft-delete paths (e.g. platform's hand-rolled dashboard/alert services)
@@ -100,13 +100,45 @@ const SOFT_DELETE_RETENTION_MS = Math.max(0, Number.parseInt(process.env.SOFT_DE
100
100
  export function softDeleteRetentionMs() {
101
101
  return SOFT_DELETE_RETENTION_MS;
102
102
  }
103
+ /**
104
+ * Abstract CRUD service with multi-tenant access control and pagination.
105
+ *
106
+ * Subclasses bind to a specific Drizzle table by implementing `schema`,
107
+ * `buildConditions`, `getSortColumn`, and the org/project-column accessors.
108
+ *
109
+ * @typeParam TEntity - Entity type extending BaseEntity
110
+ * @typeParam TFilter - Filter type for query parameters
111
+ * @typeParam TInsert - Insert DTO type
112
+ * @typeParam TUpdate - Update DTO type
113
+ *
114
+ * **A note on the type casts.** Drizzle's row types are inferred from
115
+ * `pgTable(...)` and don't generically narrow through the abstract `schema`
116
+ * getter, so the base class casts query results to `TEntity` and back. The
117
+ * cast is *not* a runtime safety guarantee — it relies on each subclass
118
+ * passing the matching entity type. Org-scoping is enforced by every
119
+ * subclass's `buildConditions` injecting `WHERE org_id = $1`; this class
120
+ * does not add that filter itself.
121
+ *
122
+ * **Error policy.** Errors propagate up to the route-level handler
123
+ * (`withRoute`); no catch-and-swallow here.
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * class PipelineService extends CrudService<Pipeline, PipelineFilter, PipelineInsert, PipelineUpdate> {
128
+ * protected get schema() { return schema.pipeline; }
129
+ * protected buildConditions(filter, orgId) { return buildPipelineConditions(filter, orgId); }
130
+ * protected getSortColumn(sortBy) { return Object.hasOwn(sortColumnMap, sortBy) ? sortColumnMap[sortBy] : null; }
131
+ * protected getProjectColumn() { return schema.pipeline.project; }
132
+ * protected getOrgColumn() { return schema.pipeline.orgId; }
133
+ * }
134
+ * ```
135
+ */
103
136
  export class CrudService {
104
137
  /**
105
138
  * Typed column view of {@link schema}. `PgTable` exposes no static columns, so
106
- * the base class previously reached for `(this.schema as any).id` etc. at each
107
- * use; centralize that single unavoidable cast here so callers get structured,
108
- * typed access instead. `visibility` is optional (not every entity has it)
109
- * and the index signature covers dynamic sparse-fieldset column lookup.
139
+ * this is the single unavoidable cast for column access. `visibility` is
140
+ * optional (not every entity has it) and the index signature covers dynamic
141
+ * sparse-fieldset column lookup.
110
142
  */
111
143
  get cols() {
112
144
  return this.schema;
@@ -126,7 +158,22 @@ export class CrudService {
126
158
  * hierarchy) — same opt-in semantics as `find`/`findPaginated`. Omitted by the
127
159
  * write path (`writeConditions`), which must stay own-org scoped. */
128
160
  idConditions(id, orgId, parentOrgId) {
129
- return this.buildConditions({ id }, orgId, parentOrgId);
161
+ return [
162
+ ...this.buildConditions({ id }, orgId, parentOrgId),
163
+ ...this.notTombstoned(),
164
+ ];
165
+ }
166
+ /**
167
+ * Excludes soft-deleted tombstones on entities with a `deletedAt` column. The
168
+ * by-id filter deliberately skips the `isActive` default (a deactivated row is
169
+ * still readable by id), so without this a tombstone would be readable and —
170
+ * through `update` — half-revivable (`isActive` flipped back while
171
+ * `deletedAt`/`purgeAfter` stay set, so the sweep later purges a row the UI
172
+ * shows as live). Tombstones are reached only via the dedicated
173
+ * restore/purge/findDeleted paths.
174
+ */
175
+ notTombstoned() {
176
+ return this.cols.deletedAt ? [isNull(this.cols.deletedAt)] : [];
130
177
  }
131
178
  /**
132
179
  * Conditions for a MUTATION (update/delete) of a single entity.
@@ -142,7 +189,7 @@ export class CrudService {
142
189
  const conditions = this.idConditions(id, orgId);
143
190
  // Pin the mutation to the caller's own org via the tenant column
144
191
  // (getOrgColumn, asserted non-null in the constructor) — consistent with
145
- // setDefault and without the old silent fail-open when the property was absent.
192
+ // setDefault, and never silently fail-open when the property is absent.
146
193
  if (orgId)
147
194
  conditions.push(eq(this.getOrgColumn(), orgId));
148
195
  // Force EXACT id equality on the mutation path. `idConditions` reuses the
@@ -161,6 +208,65 @@ export class CrudService {
161
208
  exactIdCondition(id) {
162
209
  return eq(this.cols.id, String(id).toLowerCase());
163
210
  }
211
+ /** The actor stamped on a write: the caller, or the system actor for background work. */
212
+ actor(userId) {
213
+ return userId || SYSTEM_ACTOR_ID;
214
+ }
215
+ /**
216
+ * The one cast point for `.set()` / `.values()` / `.select()` shapes. The base class writes
217
+ * the shared columns (`updatedBy`, `deletedAt`, …) through the abstract
218
+ * `PgTable`, whose insert/update types can't prove those columns exist.
219
+ */
220
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
221
+ row(values) {
222
+ return values;
223
+ }
224
+ /** Run a lifecycle hook best-effort: a failure is logged, never thrown. */
225
+ async runHook(hook) {
226
+ try {
227
+ await hook();
228
+ }
229
+ catch (err) {
230
+ this._logger.warn('Lifecycle hook failed', { error: String(err) });
231
+ }
232
+ }
233
+ /** The columns a soft-delete stamps, including the purge deadline. */
234
+ tombstoneSet(now, userId) {
235
+ const user = this.actor(userId);
236
+ return {
237
+ isActive: false,
238
+ updatedAt: now,
239
+ updatedBy: user,
240
+ deletedAt: now,
241
+ deletedBy: user,
242
+ // Stamp the purge deadline so the retention sweep can hard-delete later.
243
+ ...this.purgeAfterStamp(now),
244
+ };
245
+ }
246
+ /**
247
+ * Hard-delete up to `limit` rows matching `conditions` in one transaction:
248
+ * dependents are torn down first by `onBeforePurge` in the SAME tx (a
249
+ * FK-blocking child can't strand the parent; a throw aborts the batch), then
250
+ * `onAfterPurge` handles external side-effects best-effort. Returns the ids.
251
+ */
252
+ async purgeWhere(conditions, limit) {
253
+ const purgedIds = await withTenantTx(async (tx) => {
254
+ const doomed = await tx
255
+ .select(this.row({ id: this.cols.id }))
256
+ .from(this.schema)
257
+ .where(and(...conditions))
258
+ .limit(limit)
259
+ .then(r => r.map(d => String(d.id)));
260
+ if (doomed.length === 0)
261
+ return [];
262
+ await this.onBeforePurge(doomed, tx);
263
+ await tx.delete(this.schema).where(inArray(this.cols.id, doomed));
264
+ return doomed;
265
+ });
266
+ if (purgedIds.length > 0)
267
+ await this.runHook(() => this.onAfterPurge(purgedIds));
268
+ return purgedIds;
269
+ }
164
270
  // Lifecycle hooks — override in subclasses to react to mutations
165
271
  // These are fire-and-forget: errors are logged but never block the caller.
166
272
  /** Called after a new entity is created */
@@ -231,17 +337,30 @@ export class CrudService {
231
337
  .from(this.schema)
232
338
  .where(and(...conditions)).then(r => drizzleRows(r))));
233
339
  }
340
+ /**
341
+ * ORDER BY for {@link findFirst}, so "take one" is deterministic rather than
342
+ * whatever row the planner meets first: the default row, then the newest,
343
+ * then id as the final tiebreak. Services override it to rank by their own
344
+ * notion of "best match" (plugins: own org first, then semver).
345
+ */
346
+ findFirstOrderBy(_filter, _orgId, _parentOrgId) {
347
+ const { isDefault, createdAt, id } = this.cols;
348
+ return [desc(isDefault), ...(createdAt ? [desc(createdAt)] : []), asc(id)];
349
+ }
234
350
  /**
235
351
  * Find the FIRST entity matching `filter` — a bounded (`LIMIT 1`) variant of
236
352
  * `find` for the "match by filter, take one" read paths (e.g. `GET /find`), so
237
- * they don't `SELECT` every matching org row just to return `[0]`.
353
+ * they don't `SELECT` every matching org row just to return `[0]`. Ranked by
354
+ * {@link findFirstOrderBy}.
238
355
  */
239
356
  async findFirst(filter, orgId, parentOrgId) {
240
357
  const conditions = this.buildConditions(filter, orgId, parentOrgId);
358
+ const orderBy = this.findFirstOrderBy(filter, orgId, parentOrgId);
241
359
  const results = await this.runRead(parentOrgId, () => withTenantTx(async (tx) => tx
242
360
  .select()
243
361
  .from(this.schema)
244
362
  .where(and(...conditions))
363
+ .orderBy(...orderBy)
245
364
  .limit(1).then(r => drizzleRows(r))));
246
365
  return results[0] || null;
247
366
  }
@@ -258,8 +377,8 @@ export class CrudService {
258
377
  // Total, deterministic order: (sort column, id). `id` is unique, so rows that
259
378
  // share a sort value have a stable relative order and a keyset cursor can
260
379
  // never skip or repeat them. An absent or UNKNOWN `sortBy` orders by `id`
261
- // alone — an unknown sort used to add no WHERE and no ORDER BY while still
262
- // emitting a cursor, so a cursor client looped on page 1 forever.
380
+ // alone — an unknown sort that added no WHERE and no ORDER BY while still
381
+ // emitting a cursor would loop a cursor client on page 1 forever.
263
382
  const idColumn = this.cols.id;
264
383
  const sortColumn = (sortBy ? this.getSortColumn(sortBy) : null) ?? idColumn;
265
384
  const direction = sortOrder === 'desc' ? desc : asc;
@@ -393,9 +512,8 @@ export class CrudService {
393
512
  }
394
513
  // Mutation operations
395
514
  /**
396
- * Defense-in-depth tenant stamp. RLS is in owner-bypass mode, so the app layer
397
- * is the only tenant gate on writes. A NON-sysadmin caller may only write into
398
- * its OWN org, so pin the row to the trusted tenant-context org.
515
+ * Defense-in-depth tenant stamp alongside RLS: a NON-sysadmin caller may only
516
+ * write into its OWN org, so pin the row to the trusted tenant-context org.
399
517
  *
400
518
  * The stamp fires whenever the payload's `orgId` differs from the context org —
401
519
  * which covers BOTH a forged/mismatched `data.orgId` AND an ABSENT one. The
@@ -408,10 +526,9 @@ export class CrudService {
408
526
  * is undefined) keep the supplied org, matching the RLS policy
409
527
  * `current_is_sysadmin() OR org_id = current_org_id()`.
410
528
  */
411
- // Generic over the payload shape so BOTH the create (`TInsert`) and update
412
- // (`Partial<TUpdate>`) call sites use it without the `as unknown as TInsert`
413
- // round-trip they previously needed — the org-stamp logic is identical for
414
- // either shape (it only touches the `orgId` key).
529
+ // Generic over the payload shape so both the create (`TInsert`) and update
530
+ // (`Partial<TUpdate>`) call sites use it — the org-stamp logic only touches
531
+ // the `orgId` key.
415
532
  enforceOrgId(data, isCreate = false) {
416
533
  const ctx = getTenantContext();
417
534
  const d = data;
@@ -451,11 +568,11 @@ export class CrudService {
451
568
  // step-up. On any conflict nothing is written and the caller gets a 409.
452
569
  const [created] = await withTenantTx(async (tx) => tx
453
570
  .insert(this.schema)
454
- .values({
571
+ .values(this.row({
455
572
  ...safeData,
456
- createdBy: userId || 'system',
457
- updatedBy: userId || 'system',
458
- })
573
+ createdBy: this.actor(userId),
574
+ updatedBy: this.actor(userId),
575
+ }))
459
576
  .onConflictDoNothing({ target: this.conflictTarget })
460
577
  .returning().then(r => drizzleRows(r)));
461
578
  if (!created) {
@@ -465,12 +582,7 @@ export class CrudService {
465
582
  // fire-and-forget pattern lets a subsequent read inside the same request
466
583
  // return the stale pre-write entry. The hook is expected to be fast
467
584
  // (single Redis op); slow hooks should run their own background work.
468
- try {
469
- await this.onAfterCreate(created, userId);
470
- }
471
- catch (err) {
472
- this._logger.warn('Lifecycle hook failed', { error: String(err) });
473
- }
585
+ await this.runHook(() => this.onAfterCreate(created, userId));
474
586
  return created;
475
587
  }
476
588
  /**
@@ -484,20 +596,15 @@ export class CrudService {
484
596
  const safeData = this.enforceOrgId(data);
485
597
  const [updated] = await withTenantTx(async (tx) => tx
486
598
  .update(this.schema)
487
- .set({
599
+ .set(this.row({
488
600
  ...safeData,
489
601
  updatedAt: new Date(),
490
- updatedBy: userId || 'system',
491
- })
602
+ updatedBy: this.actor(userId),
603
+ }))
492
604
  .where(and(...conditions))
493
605
  .returning().then(r => drizzleRows(r)));
494
606
  if (updated) {
495
- try {
496
- await this.onAfterUpdate(id, updated, userId);
497
- }
498
- catch (err) {
499
- this._logger.warn('Lifecycle hook failed', { error: String(err) });
500
- }
607
+ await this.runHook(() => this.onAfterUpdate(id, updated, userId));
501
608
  }
502
609
  return updated || null;
503
610
  }
@@ -509,24 +616,11 @@ export class CrudService {
509
616
  const now = new Date();
510
617
  const [deleted] = await withTenantTx(async (tx) => tx
511
618
  .update(this.schema)
512
- .set({
513
- isActive: false,
514
- updatedAt: now,
515
- updatedBy: userId || 'system',
516
- deletedAt: now,
517
- deletedBy: userId || 'system',
518
- // Stamp the purge deadline so the retention sweep can hard-delete later.
519
- ...this.purgeAfterStamp(now),
520
- })
619
+ .set(this.row(this.tombstoneSet(now, userId)))
521
620
  .where(and(...conditions))
522
621
  .returning().then(r => drizzleRows(r)));
523
622
  if (deleted) {
524
- try {
525
- await this.onAfterDelete(id, deleted, userId);
526
- }
527
- catch (err) {
528
- this._logger.warn('Lifecycle hook failed', { error: String(err) });
529
- }
623
+ await this.runHook(() => this.onAfterDelete(id, deleted, userId));
530
624
  }
531
625
  return deleted || null;
532
626
  }
@@ -538,7 +632,7 @@ export class CrudService {
538
632
  async setDefault(project, org, id, userId) {
539
633
  // A non-sysadmin may only flip defaults within its OWN org — pin the scope to
540
634
  // the trusted tenant context so a forwarded `org` arg can't touch another
541
- // tenant's defaults (RLS is in owner-bypass mode; this is the gate).
635
+ // tenant's defaults (app-layer pin, in addition to RLS).
542
636
  const ctx = getTenantContext();
543
637
  if (ctx && !ctx.isSuperAdmin && ctx.orgId)
544
638
  org = ctx.orgId;
@@ -562,11 +656,11 @@ export class CrudService {
562
656
  // Mark all entities in scope as non-default
563
657
  await tx
564
658
  .update(this.schema)
565
- .set({
659
+ .set(this.row({
566
660
  isDefault: false,
567
661
  updatedAt: new Date(),
568
- updatedBy: userId || 'system',
569
- })
662
+ updatedBy: this.actor(userId),
663
+ }))
570
664
  .where(and(...scopeConditions));
571
665
  // Set the specified entity as default. Guard against promoting a
572
666
  // soft-deleted row (isActive = true) — a deleted entity must never become
@@ -576,11 +670,11 @@ export class CrudService {
576
670
  // so a mixed-case id could miss its row). A non-match → NotFoundError below.
577
671
  const [updated] = await tx
578
672
  .update(this.schema)
579
- .set({
673
+ .set(this.row({
580
674
  isDefault: true,
581
675
  updatedAt: new Date(),
582
- updatedBy: userId || 'system',
583
- })
676
+ updatedBy: this.actor(userId),
677
+ }))
584
678
  .where(and(this.exactIdCondition(id), eq(orgColumn, org), eq(this.cols.isActive, true)))
585
679
  .returning().then(r => drizzleRows(r));
586
680
  if (!updated) {
@@ -606,11 +700,11 @@ export class CrudService {
606
700
  const safeData = this.enforceOrgId(data);
607
701
  return withTenantTx(async (tx) => tx
608
702
  .update(this.schema)
609
- .set({
703
+ .set(this.row({
610
704
  ...safeData,
611
705
  updatedAt: new Date(),
612
- updatedBy: userId || 'system',
613
- })
706
+ updatedBy: this.actor(userId),
707
+ }))
614
708
  .where(and(...conditions))
615
709
  .returning().then(r => drizzleRows(r)));
616
710
  }
@@ -644,15 +738,8 @@ export class CrudService {
644
738
  async bulkDelete(ids, orgId, userId,
645
739
  /**
646
740
  * The caller's authority on the three-rung `visibility` ladder. Omit (or
647
- * pass `isSystemAdmin: true`) for an unrestricted delete.
648
- *
649
- * This used to be a `restrictToPrivate` boolean that narrowed to
650
- * `visibility = 'private'`. That encoded the OLD two-state model: since
651
- * `resolveVisibility` defaults pipelines and plugins to `org`, and
652
- * single-row delete allows an `org` row with plain `:write`, bulk delete
653
- * 403'd the normal case — an org admin could delete a pipeline one at a
654
- * time but not in bulk. The rungs enforced here mirror
655
- * `requireVisibilityWriteAccess` exactly:
741
+ * pass `isSystemAdmin: true`) for an unrestricted delete. The rungs mirror
742
+ * `requireVisibilityWriteAccess` exactly, so bulk and single-row delete agree:
656
743
  * - `private` → author only (`createdBy === userId`)
657
744
  * - `org` → any member of the org (plain `:write`)
658
745
  * - `public` → requires the entity's publish permission
@@ -661,7 +748,6 @@ export class CrudService {
661
748
  if (ids.length === 0)
662
749
  return [];
663
750
  const now = new Date();
664
- const user = userId || 'system';
665
751
  // Owner-scope the bulk soft-delete: buildConditions also matches system/other
666
752
  // -org PUBLIC rows, so without the strict orgId pin a tenant could delete
667
753
  // shared records by id. (See writeConditions.)
@@ -674,36 +760,17 @@ export class CrudService {
674
760
  // writeConditions; no silent fail-open when the property is absent.
675
761
  ...(orgId ? [eq(this.getOrgColumn(), orgId)] : []),
676
762
  ...this.visibilityDeleteConditions(access, userId, accessCol, createdByCol),
763
+ // Re-deleting a tombstone would re-stamp its purge deadline.
764
+ ...this.notTombstoned(),
677
765
  ];
678
766
  const deleted = await withTenantTx(async (tx) => tx
679
767
  .update(this.schema)
680
- .set({
681
- isActive: false,
682
- updatedAt: now,
683
- updatedBy: user,
684
- deletedAt: now,
685
- deletedBy: user,
686
- // Stamp the purge deadline so the retention sweep can hard-delete later.
687
- ...this.purgeAfterStamp(now),
688
- })
768
+ .set(this.row(this.tombstoneSet(now, userId)))
689
769
  .where(and(...conditions))
690
770
  .returning().then(r => drizzleRows(r)));
691
- await Promise.all(deleted.map(entity => this.onAfterDelete(entity.id, entity, userId).catch(err => this._logger.warn('Lifecycle hook failed', { error: String(err) }))));
771
+ await Promise.all(deleted.map(entity => this.runHook(() => this.onAfterDelete(entity.id, entity, userId))));
692
772
  return deleted;
693
773
  }
694
- /**
695
- * Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/
696
- * `deletedBy`/`purgeAfter` so it reappears in normal reads.
697
- *
698
- * Matches ONLY a genuine tombstone — `isActive = false` AND `deletedAt IS NOT
699
- * NULL` — so a merely *deactivated* row (isActive=false, no deletedAt) is never
700
- * silently "restored". Pinned to the caller's own org (orgId-less sysadmin
701
- * context spans orgs, matching delete/update). Returns null when there is no
702
- * such tombstone (already active, purged, or unknown) so the route can 404.
703
- * A unique-key collision (a live row already holds the key) surfaces as the
704
- * driver's unique-violation for the route to map to 409 — in practice the
705
- * tombstone IS the key holder, so this is defensive.
706
- */
707
774
  /** Conditions matching a GENUINE tombstone (`isActive=false` AND `deletedAt IS
708
775
  * NOT NULL`), optionally pinned to `id` and/or `orgId`. Single source of truth
709
776
  * for restore/findDeletedById/findDeleted so the "what is a tombstone" rule
@@ -723,12 +790,9 @@ export class CrudService {
723
790
  /**
724
791
  * The `private` rung, for TOMBSTONE reads and restore.
725
792
  *
726
- * Deleting a row does not declassify it. These conditions carried only
727
- * `isActive=false + deletedAt IS NOT NULL + org_id = O`, so the "recently
728
- * deleted" list handed every member of an org the tombstones of everyone
729
- * else's PRIVATE pipelines, plugins and templates — rows the very same member
730
- * could not read one second before they were deleted. `restore` shared the
731
- * clause, so they could also bring one back.
793
+ * Deleting a row does not declassify it: without this, the "recently
794
+ * deleted" list (and restore) would expose other members' PRIVATE rows that
795
+ * the same viewer could not read before they were deleted.
732
796
  *
733
797
  * Mirrors the live read ladder (`visibility <> 'private' OR created_by = V`)
734
798
  * rather than the delete ladder: this gates who may SEE a tombstone, and a
@@ -754,29 +818,37 @@ export class CrudService {
754
818
  rungs.push(eq(createdByCol, viewer));
755
819
  return [or(...rungs)];
756
820
  }
821
+ /**
822
+ * Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/
823
+ * `deletedBy`/`purgeAfter` so it reappears in normal reads.
824
+ *
825
+ * Matches ONLY a genuine tombstone — `isActive = false` AND `deletedAt IS NOT
826
+ * NULL` — so a merely *deactivated* row (isActive=false, no deletedAt) is never
827
+ * silently "restored". Pinned to the caller's own org (orgId-less sysadmin
828
+ * context spans orgs, matching delete/update). Returns null when there is no
829
+ * such tombstone (already active, purged, or unknown) so the route can 404.
830
+ * A unique-key collision (a live row already holds the key) surfaces as the
831
+ * driver's unique-violation for the route to map to 409 — in practice the
832
+ * tombstone IS the key holder, so this is defensive.
833
+ */
757
834
  async restore(id, orgId, userId) {
758
835
  if (!this.cols.deletedAt)
759
836
  return null; // entity has no soft-delete lifecycle
760
837
  const conditions = this.tombstoneConditions(orgId, id);
761
838
  const [restored] = await withTenantTx(async (tx) => tx
762
839
  .update(this.schema)
763
- .set({
840
+ .set(this.row({
764
841
  isActive: true,
765
842
  updatedAt: new Date(),
766
- updatedBy: userId || 'system',
843
+ updatedBy: this.actor(userId),
767
844
  deletedAt: null,
768
845
  deletedBy: null,
769
846
  ...(this.cols.purgeAfter ? { purgeAfter: null } : {}),
770
- })
847
+ }))
771
848
  .where(and(...conditions))
772
849
  .returning().then(r => drizzleRows(r)));
773
850
  if (restored) {
774
- try {
775
- await this.onAfterRestore(id, restored, userId);
776
- }
777
- catch (err) {
778
- this._logger.warn('Lifecycle hook failed', { error: String(err) });
779
- }
851
+ await this.runHook(() => this.onAfterRestore(id, restored, userId));
780
852
  }
781
853
  return restored || null;
782
854
  }
@@ -832,33 +904,8 @@ export class CrudService {
832
904
  async purgeExpired(now, limit = 500) {
833
905
  if (!this.cols.deletedAt || !this.cols.purgeAfter)
834
906
  return 0;
835
- const purgedIds = await withTenantTx(async (tx) => {
836
- const doomed = await tx
837
- // `as any`: cols.id is the base `AnyColumn`, which drizzle's typed
838
- // select-field map doesn't accept directly (same friction the `.set()`
839
- // casts elsewhere in this file work around). Result is re-typed below.
840
- .select({ id: this.cols.id })
841
- .from(this.schema)
842
- .where(and(sql `${this.cols.deletedAt} IS NOT NULL`, sql `${this.cols.purgeAfter} < ${now}`))
843
- .limit(limit)
844
- .then(r => r.map(d => String(d.id)));
845
- if (doomed.length === 0)
846
- return [];
847
- // Dependent teardown must happen inside the same tx so a FK-blocking child
848
- // can't strand the parent. A throw here aborts this batch (retried next tick).
849
- await this.onBeforePurge(doomed, tx);
850
- await tx.delete(this.schema).where(inArray(this.cols.id, doomed));
851
- return doomed;
852
- });
853
- if (purgedIds.length > 0) {
854
- try {
855
- await this.onAfterPurge(purgedIds);
856
- }
857
- catch (err) {
858
- this._logger.warn('Lifecycle hook failed', { error: String(err) });
859
- }
860
- }
861
- return purgedIds.length;
907
+ const purged = await this.purgeWhere([sql `${this.cols.deletedAt} IS NOT NULL`, sql `${this.cols.purgeAfter} < ${now}`], limit);
908
+ return purged.length;
862
909
  }
863
910
  /**
864
911
  * On-demand hard-delete of a SINGLE tombstone by id — the manual counterpart
@@ -876,33 +923,8 @@ export class CrudService {
876
923
  async purgeById(id, orgId) {
877
924
  if (!this.cols.deletedAt)
878
925
  return null;
879
- const conditions = this.tombstoneConditions(orgId, id);
880
- const purgedId = await withTenantTx(async (tx) => {
881
- const [doomed] = await tx
882
- // `as any`: cols.id is the base `AnyColumn`, which drizzle's typed
883
- // select-field map doesn't accept directly (same friction elsewhere).
884
- .select({ id: this.cols.id })
885
- .from(this.schema)
886
- .where(and(...conditions))
887
- .limit(1)
888
- .then(r => r.map(d => String(d.id)));
889
- if (!doomed)
890
- return null;
891
- // Dependent teardown in the same tx (FK-blocking children can't strand
892
- // the parent) — identical to the sweep's per-batch path.
893
- await this.onBeforePurge([doomed], tx);
894
- await tx.delete(this.schema).where(inArray(this.cols.id, [doomed]));
895
- return doomed;
896
- });
897
- if (purgedId) {
898
- try {
899
- await this.onAfterPurge([purgedId]);
900
- }
901
- catch (err) {
902
- this._logger.warn('Lifecycle hook failed', { error: String(err) });
903
- }
904
- }
905
- return purgedId;
926
+ const [purgedId] = await this.purgeWhere(this.tombstoneConditions(orgId, id), 1);
927
+ return purgedId ?? null;
906
928
  }
907
929
  }
908
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J1ZC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9jcnVkLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDNUgsT0FBTyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBR3pGLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUc5Rjs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUksSUFBYTtJQUMxQyxPQUFPLElBQVcsQ0FBQztBQUNyQixDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBYTtJQUN4QyxPQUFPLElBQTJCLENBQUM7QUFDckMsQ0FBQztBQXlHRCxxRkFBcUY7QUFDckYsTUFBTSxlQUFlLEdBQUcsaUJBQWlCLENBQUM7QUFFMUM7Ozs7O0dBS0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxRQUF1QixFQUFFLEVBQVU7SUFDdkQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDbkYsQ0FBQztBQUVELCtFQUErRTtBQUMvRSxTQUFTLFlBQVksQ0FBQyxNQUFjO0lBQ2xDLElBQUksQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFZLElBQUksQ0FBQyxLQUFLLENBQUMs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QUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNyRSxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBDb25mbGljdEVycm9yLCBOb3RGb3VuZEVycm9yLCBjcmVhdGVMb2dnZXIsIERFRkFVTFRfUEFHRV9MSU1JVCwgTUFYX1BBR0VfTElNSVQgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBTUUwsIGVxLCBhbmQsIG9yLCBhc2MsIGRlc2MsIHNxbCwgaW5BcnJheSwgZ2V0VGFibGVDb2x1bW5zIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHR5cGUgeyBBbnlDb2x1bW4gfSBmcm9tICdkcml6emxlLW9ybS9jb2x1bW4nO1xuaW1wb3J0IHR5cGUgeyBQZ1RhYmxlIH0gZnJvbSAnZHJpenpsZS1vcm0vcGctY29yZSc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHgsIHJ1bldpdGhUZW5hbnRDb250ZXh0LCBnZXRUZW5hbnRDb250ZXh0IH0gZnJvbSAnLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5cblxuLyoqXG4gKiBDYXN0IERyaXp6bGUgcXVlcnkgcmVzdWx0cyB0byBhIHR5cGVkIGFycmF5LlxuICogRHJpenpsZSdzIGdlbmVyaWMgcmV0dXJuIHR5cGUgKGBQZ1NlbGVjdEJhc2U8Li4uPmApIGRvZXNuJ3QgbmFycm93IHRvIG91clxuICogZW50aXR5IGdlbmVyaWNzLCBzbyBhbiBleHBsaWNpdCBjYXN0IGlzIG5lZWRlZC4gQ2VudHJhbGlzZWQgaGVyZSBzbyBldmVyeVxuICogY2FsbC1zaXRlIHN0YXlzIG9uZS1saW5lciBjbGVhbiBhbmQgdGhlIGNhc3QgaXMgZG9jdW1lbnRlZCBpbiBvbmUgcGxhY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkcml6emxlUm93czxUPihyb3dzOiB1bmtub3duKTogVFtdIHtcbiAgcmV0dXJuIHJvd3MgYXMgVFtdO1xufVxuXG4vKiogQ2FzdCBhIERyaXp6bGUgYWdncmVnYXRlIHJlc3VsdCB0byBleHRyYWN0IGBbeyBjb3VudDogbnVtYmVyIH1dYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkcml6emxlQ291bnQocm93czogdW5rbm93bik6IFt7IGNvdW50OiBudW1iZXIgfV0ge1xuICByZXR1cm4gcm93cyBhcyBbeyBjb3VudDogbnVtYmVyIH1dO1xufVxuXG4vKiogVGhlIERyaXp6bGUgdHJhbnNhY3Rpb24gb2JqZWN0IGhhbmRlZCB0byBgd2l0aFRlbmFudFR4YCBjYWxsYmFja3MuIFBhc3NlZCB0b1xuICogIGBvbkJlZm9yZVB1cmdlYCBzbyBhIHN1YmNsYXNzJ3MgZGVwZW5kZW50IHRlYXJkb3duIHJ1bnMgaW4gdGhlIFNBTUUgcHVyZ2VcbiAqICB0cmFuc2FjdGlvbiAoYXRvbWljIHdpdGggdGhlIHBhcmVudCBERUxFVEUpLCBub3QgYSBmcmVzaCBjb25uZWN0aW9uLiAqL1xuZXhwb3J0IHR5cGUgQ3J1ZFR4ID0gUGFyYW1ldGVyczxQYXJhbWV0ZXJzPHR5cGVvZiB3aXRoVGVuYW50VHg+WzBdPlswXTtcblxuLyoqXG4gKiBCYXNlIGludGVyZmFjZSBmb3IgZW50aXRpZXMgd2l0aCBjb21tb24gZmllbGRzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUVudGl0eSB7XG4gIGlkOiBzdHJpbmc7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIGlzRGVmYXVsdDogYm9vbGVhbjtcbiAgY3JlYXRlZEF0OiBEYXRlO1xuICB1cGRhdGVkQXQ6IERhdGU7XG4gIGNyZWF0ZWRCeTogc3RyaW5nO1xuICB1cGRhdGVkQnk6IHN0cmluZztcbiAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBQYWdpbmF0aW9uIGFuZCBzb3J0aW5nIG9wdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdWVyeU9wdGlvbnMge1xuICBsaW1pdD86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xuICBzb3J0Qnk/OiBzdHJpbmc7XG4gIHNvcnRPcmRlcj86ICdhc2MnIHwgJ2Rlc2MnO1xuICAvKiogV2hlbiB0cnVlLCBydW5zIGEgc2VwYXJhdGUgQ09VTlQoKikgcXVlcnkgdG8gaW5jbHVkZSBleGFjdCB0b3RhbC4gRGVmYXVsdDogZmFsc2UuICovXG4gIGluY2x1ZGVUb3RhbD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBLZXlzZXQgcGFnaW5hdGlvbjogdGhlIG9wYXF1ZSBgbmV4dEN1cnNvcmAgb2YgdGhlIHByZXZpb3VzIHBhZ2UuIENvbnRpbnVlc1xuICAgKiBzdHJpY3RseSBhZnRlciB0aGF0IHJvdyBpbiAoc29ydEJ5LCBpZCkgb3JkZXI7IHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgb2Zmc2V0YC5cbiAgICovXG4gIGN1cnNvcj86IHN0cmluZztcbiAgLyoqIFNwYXJzZSBmaWVsZHNldDogY29sdW1uIG5hbWVzIHRvIHNlbGVjdC4gUmV0dXJucyBhbGwgY29sdW1ucyB3aGVuIG9taXR0ZWQuICovXG4gIGZpZWxkcz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFBhZ2luYXRlZCByZXN1bHQgd2l0aCBtZXRhZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2luYXRlZFJlc3VsdDxUPiB7XG4gIGRhdGE6IFRbXTtcbiAgLyoqIFRvdGFsIGNvdW50IG9mIG1hdGNoaW5nIGVudGl0aWVzLiBPbmx5IHByZXNlbnQgd2hlbiBpbmNsdWRlVG90YWwgaXMgdHJ1ZS4gKi9cbiAgdG90YWw/OiBudW1iZXI7XG4gIGxpbWl0OiBudW1iZXI7XG4gIG9mZnNldDogbnVtYmVyO1xuICBoYXNNb3JlOiBib29sZWFuO1xuICAvKiogT3BhcXVlIGN1cnNvciBmb3IgdGhlIG5leHQgcGFnZS4gUHJlc2VudCBvbmx5IHdoZW4gYGhhc01vcmVgLiAqL1xuICBuZXh0Q3Vyc29yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFic3RyYWN0IENSVUQgc2VydmljZSB3aXRoIG11bHRpLXRlbmFudCBhY2Nlc3MgY29udHJvbCBhbmQgcGFnaW5hdGlvbi5cbiAqXG4gKiBTdWJjbGFzc2VzIGJpbmQgdG8gYSBzcGVjaWZpYyBEcml6emxlIHRhYmxlIGJ5IGltcGxlbWVudGluZyBgc2NoZW1hYCxcbiAqIGBidWlsZENvbmRpdGlvbnNgLCBgZ2V0U29ydENvbHVtbmAsIGFuZCB0aGUgb3JnL3Byb2plY3QtY29sdW1uIGFjY2Vzc29ycy5cbiAqXG4gKiBAdHlwZVBhcmFtIFRFbnRpdHkgLSBFbnRpdHkgdHlwZSBleHRlbmRpbmcgQmFzZUVudGl0eVxuICogQHR5cGVQYXJhbSBURmlsdGVyIC0gRmlsdGVyIHR5cGUgZm9yIHF1ZXJ5IHBhcmFtZXRlcnNcbiAqIEB0eXBlUGFyYW0gVEluc2VydCAtIEluc2VydCBEVE8gdHlwZVxuICogQHR5cGVQYXJhbSBUVXBkYXRlIC0gVXBkYXRlIERUTyB0eXBlXG4gKlxuICogKipBIG5vdGUgb24gdGhlIHR5cGUgY2FzdHMuKiogRHJpenpsZSdzIHJvdyB0eXBlcyBhcmUgaW5mZXJyZWQgZnJvbVxuICogYHBnVGFibGUoLi4uKWAgYW5kIGRvbid0IGdlbmVyaWNhbGx5IG5hcnJvdyB0aHJvdWdoIHRoZSBhYnN0cmFjdCBgc2NoZW1hYFxuICogZ2V0dGVyLCBzbyB0aGUgYmFzZSBjbGFzcyBjYXN0cyBxdWVyeSByZXN1bHRzIHRvIGBURW50aXR5YCBhbmQgYmFjay4gVGhlXG4gKiBjYXN0IGlzICpub3QqIGEgcnVudGltZSBzYWZldHkgZ3VhcmFudGVlIOKAlCBpdCByZWxpZXMgb24gZWFjaCBzdWJjbGFzc1xuICogcGFzc2luZyB0aGUgbWF0Y2hpbmcgZW50aXR5IHR5cGUuIE9yZy1zY29waW5nIGlzIGVuZm9yY2VkIGJ5IGV2ZXJ5XG4gKiBzdWJjbGFzcydzIGBidWlsZENvbmRpdGlvbnNgIGluamVjdGluZyBgV0hFUkUgb3JnX2lkID0gJDFgOyB0aGlzIGNsYXNzXG4gKiBkb2VzIG5vdCBhZGQgdGhhdCBmaWx0ZXIgaXRzZWxmLlxuICpcbiAqICoqRXJyb3IgcG9saWN5LioqIEVycm9ycyBwcm9wYWdhdGUgdXAgdG8gdGhlIHJvdXRlLWxldmVsIGhhbmRsZXJcbiAqIChgd2l0aFJvdXRlYCk7IG5vIGNhdGNoLWFuZC1zd2FsbG93IGhlcmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsYXNzIFBpcGVsaW5lU2VydmljZSBleHRlbmRzIENydWRTZXJ2aWNlPFBpcGVsaW5lLCBQaXBlbGluZUZpbHRlciwgUGlwZWxpbmVJbnNlcnQsIFBpcGVsaW5lVXBkYXRlPiB7XG4gKiAgIHByb3RlY3RlZCBnZXQgc2NoZW1hKCkgeyByZXR1cm4gc2NoZW1hLnBpcGVsaW5lOyB9XG4gKiAgIHByb3RlY3RlZCBidWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCkgeyByZXR1cm4gYnVpbGRQaXBlbGluZUNvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCk7IH1cbiAqICAgcHJvdGVjdGVkIGdldFNvcnRDb2x1bW4oc29ydEJ5KSB7IHJldHVybiBzb3J0Q29sdW1uTWFwW3NvcnRCeV0gPz8gbnVsbDsgfVxuICogICBwcm90ZWN0ZWQgZ2V0UHJvamVjdENvbHVtbigpIHsgcmV0dXJuIHNjaGVtYS5waXBlbGluZS5wcm9qZWN0OyB9XG4gKiAgIHByb3RlY3RlZCBnZXRPcmdDb2x1bW4oKSB7IHJldHVybiBzY2hlbWEucGlwZWxpbmUub3JnSWQ7IH1cbiAqIH1cbiAqIGBgYFxuICovXG4vKiogU3RydWN0dXJhbCB2aWV3IG9mIHRoZSBzdWJjbGFzcyB0YWJsZSdzIGNvbHVtbnMgdGhlIGJhc2UgY2xhc3MgdG91Y2hlc1xuICogIGRpcmVjdGx5LiBgaWRgL2Bpc0FjdGl2ZWAvYGlzRGVmYXVsdGAgYXJlIGFsd2F5cyBwcmVzZW50IG9uIGEgQ1JVRCBlbnRpdHk7XG4gKiAgYHZpc2liaWxpdHlgIG9ubHkgb24gdmlzaWJpbGl0eS1iZWFyaW5nIGVudGl0aWVzOyB0aGUgaW5kZXggc2lnbmF0dXJlXG4gKiAgY292ZXJzIGR5bmFtaWMgKHNwYXJzZS1maWVsZHNldCkgY29sdW1uIGFjY2Vzcy4gKi9cbmludGVyZmFjZSBDcnVkQ29sdW1ucyB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIGlzQWN0aXZlOiBBbnlDb2x1bW47XG4gIGlzRGVmYXVsdDogQW55Q29sdW1uO1xuICB2aXNpYmlsaXR5PzogQW55Q29sdW1uO1xuICAvKiogQXV0aG9yIGNvbHVtbiDigJQgdGhlIGBwcml2YXRlYCBydW5nIG9mIHRoZSB2aXNpYmlsaXR5IGxhZGRlciBpcyBhdXRob3Itb25seS4gKi9cbiAgY3JlYXRlZEJ5PzogQW55Q29sdW1uO1xuICAvLyBTb2Z0LWRlbGV0ZSBsaWZlY3ljbGUgY29sdW1ucyAocHJlc2VudCBvbiB0b21ic3RvbmUtYmVhcmluZyBlbnRpdGllcyBvbmx5O1xuICAvLyBgcmVzdG9yZWAvYHB1cmdlRXhwaXJlZGAgYXJlIG5vLW9wcyB3aGVuIGFic2VudCkuXG4gIGRlbGV0ZWRBdD86IEFueUNvbHVtbjtcbiAgcHVyZ2VBZnRlcj86IEFueUNvbHVtbjtcbiAgW2tleTogc3RyaW5nXTogQW55Q29sdW1uIHwgdW5kZWZpbmVkO1xufVxuXG4vKiogUHJvamVjdGlvbiBhbGlhcyBjYXJyeWluZyB0aGUgc29ydCBjb2x1bW4ncyBleGFjdCBEQiB0ZXh0IGZvciB0aGUgbmV4dCBjdXJzb3IuICovXG5jb25zdCBDVVJTT1JfU09SVF9LRVkgPSAnX19jdXJzb3JTb3J0S2V5JztcblxuLyoqXG4gKiBPcGFxdWUga2V5c2V0IGN1cnNvcjogdGhlIGxhc3Qgcm93J3Mgc29ydCB2YWx1ZSBhcyBQb3N0Z3JlcyBURVhUIChmdWxsXG4gKiBwcmVjaXNpb24g4oCUIGEgSlMgYERhdGVgIHdvdWxkIHRydW5jYXRlIGB0aW1lc3RhbXB0emAgbWljcm9zZWNvbmRzIHRvIG1zLCBzb1xuICogYGNyZWF0ZWRfYXQgPiAnPG1zPidgIHJlLXJldHVybnMgb3Igc2tpcHMgcm93cyBpbiB0aGUgc2FtZSBtaWxsaXNlY29uZCkgcGx1c1xuICogaXRzIGBpZGAgYXMgdGhlIHRpZS1icmVha2VyLlxuICovXG5mdW5jdGlvbiBlbmNvZGVDdXJzb3Ioc29ydFRleHQ6IHN0cmluZyB8IG51bGwsIGlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoW3NvcnRUZXh0LCBpZF0pLCAndXRmOCcpLnRvU3RyaW5nKCdiYXNlNjR1cmwnKTtcbn1cblxuLyoqIERlY29kZSBhIGN1cnNvciBwcm9kdWNlZCBieSB7QGxpbmsgZW5jb2RlQ3Vyc29yfTsgYG51bGxgIHdoZW4gbWFsZm9ybWVkLiAqL1xuZnVuY3Rpb24gZGVjb2RlQ3Vyc29yKGN1cnNvcjogc3RyaW5nKTogeyBzb3J0VGV4dDogc3RyaW5nIHwgbnVsbDsgaWQ6IHN0cmluZyB9IHwgbnVsbCB7XG4gIHRyeSB7XG4gICAgY29uc3QgcGFyc2VkOiB1bmtub3duID0gSlNPTi5wYXJzZShCdWZmZXIuZnJvbShjdXJzb3IsICdiYXNlNjR1cmwnKS50b1N0cmluZygndXRmOCcpKTtcbiAgICBpZiAoXG4gICAgICBBcnJheS5pc0FycmF5KHBhcnNlZCkgJiYgcGFyc2VkLmxlbmd0aCA9PT0gMlxuICAgICAgJiYgKHBhcnNlZFswXSA9PT0gbnVsbCB8fCB0eXBlb2YgcGFyc2VkWzBdID09PSAnc3RyaW5nJylcbiAgICAgICYmIHR5cGVvZiBwYXJzZWRbMV0gPT09ICdzdHJpbmcnICYmIHBhcnNlZFsxXS5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICByZXR1cm4geyBzb3J0VGV4dDogcGFyc2VkWzBdLCBpZDogcGFyc2VkWzFdIH07XG4gICAgfVxuICB9IGNhdGNoIHtcbiAgICAvLyBmYWxsIHRocm91Z2hcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3QgVVVJRF9URVhUID0gL15bMC05YS1mXXs4fS1bMC05YS1mXXs0fS1bMC05YS1mXXs0fS1bMC05YS1mXXs0fS1bMC05YS1mXXsxMn0kL2k7XG4vKiogUG9zdGdyZXMgYHRpbWVzdGFtcFt0el06OnRleHRgIC8gYGRhdGU6OnRleHRgIChhbHNvIGFjY2VwdHMgSVNPLTg2MDEpLiAqL1xuY29uc3QgVElNRVNUQU1QX1RFWFQgPSAvXlxcZHs0fS1cXGR7Mn0tXFxkezJ9KD86WyBUXVxcZHsyfTpcXGR7Mn0oPzo6XFxkezJ9KD86XFwuXFxkezEsNn0pPyk/KD86WnxbKy1dXFxkezJ9KD86Oj9cXGR7Mn0pPyk/KT8kLztcbmNvbnN0IE5VTUVSSUNfVEVYVCA9IC9eLT9cXGQrKD86XFwuXFxkKyk/KD86W2VFXVstK10/XFxkKyk/JC87XG5cbi8qKlxuICogV2hldGhlciBgdGV4dGAgY2FuIGJlIGNhc3QgdG8gYGNvbHVtbmAncyB0eXBlLiBBIGRlY29kZWQgY3Vyc29yIGlzIHN0aWxsXG4gKiBjbGllbnQgaW5wdXQ6IGEgdmFsdWUgUG9zdGdyZXMgY2FuJ3QgY2FzdCAoYSBub24tVVVJRCBpZCwgYSBnYXJiYWdlXG4gKiB0aW1lc3RhbXApIGZhaWxzIHRoZSB3aG9sZSBxdWVyeSB3aXRoIGEgNTAwLiBDb2x1bW4gdHlwZXMgdGhpcyBkb2Vzbid0IGtub3dcbiAqICh0ZXh0LCB2YXJjaGFyLCDigKYpIGFjY2VwdCBhbnkgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBpc0Nhc3RhYmxlVG8oY29sdW1uOiBBbnlDb2x1bW4sIHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCB7IGNvbHVtblR5cGUsIGRhdGFUeXBlIH0gPSBjb2x1bW47XG4gIGNvbnN0IGVudW1WYWx1ZXMgPSAoY29sdW1uIGFzIHsgZW51bVZhbHVlcz86IHJlYWRvbmx5IHN0cmluZ1tdIH0pLmVudW1WYWx1ZXM7XG4gIGlmIChjb2x1bW5UeXBlID09PSAnUGdVVUlEJykgcmV0dXJuIFVVSURfVEVYVC50ZXN0KHRleHQpO1xuICBpZiAoKGNvbHVtblR5cGUgPT09ICdQZ0VudW1Db2x1bW4nIHx8IGNvbHVtblR5cGUgPT09ICdQZ0VudW1PYmplY3RDb2x1bW4nKSAmJiBlbnVtVmFsdWVzPy5sZW5ndGgpIHJldHVybiBlbnVtVmFsdWVzLmluY2x1ZGVzKHRleHQpO1xuICBpZiAoZGF0YVR5cGUgPT09ICdkYXRlJyB8fCBjb2x1bW5UeXBlID09PSAnUGdUaW1lc3RhbXBTdHJpbmcnIHx8IGNvbHVtblR5cGUgPT09ICdQZ0RhdGVTdHJpbmcnKSByZXR1cm4gVElNRVNUQU1QX1RFWFQudGVzdCh0ZXh0KTtcbiAgaWYgKGRhdGFUeXBlID09PSAnYm9vbGVhbicpIHJldHVybiB0ZXh0ID09PSAndHJ1ZScgfHwgdGV4dCA9PT0gJ2ZhbHNlJztcbiAgaWYgKGRhdGFUeXBlID09PSAnbnVtYmVyJyB8fCBkYXRhVHlwZSA9PT0gJ2JpZ2ludCcpIHJldHVybiBOVU1FUklDX1RFWFQudGVzdCh0ZXh0KTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogS2V5c2V0IHByZWRpY2F0ZSBcInN0cmljdGx5IGFmdGVyIChzb3J0VGV4dCwgaWQpXCIgZm9yIGBPUkRFUiBCWSBzb3J0IDxkaXI+LCBpZCA8ZGlyPmBcbiAqIHVuZGVyIFBvc3RncmVzJyBkZWZhdWx0IG51bGwgcGxhY2VtZW50IChBU0Mg4oaSIE5VTExTIExBU1QsIERFU0Mg4oaSIE5VTExTIEZJUlNUKS5cbiAqIFRoZSB0ZXh0IHZhbHVlIGlzIGJvdW5kIGFzIGEgcGFyYW1ldGVyIGNvbXBhcmVkIGFnYWluc3QgdGhlIGNvbHVtbiwgc28gUG9zdGdyZXNcbiAqIGNhc3RzIGl0IGJhY2sgdG8gdGhlIGNvbHVtbidzIHR5cGUgYXQgZnVsbCBwcmVjaXNpb24uXG4gKi9cbmZ1bmN0aW9uIGtleXNldEFmdGVyKFxuICBzb3J0Q29sdW1uOiBBbnlDb2x1bW4sXG4gIGlkQ29sdW1uOiBBbnlDb2x1bW4sXG4gIHNvcnRPcmRlcjogJ2FzYycgfCAnZGVzYycsXG4gIHNvcnRUZXh0OiBzdHJpbmcgfCBudWxsLFxuICBpZDogc3RyaW5nLFxuKTogU1FMIHtcbiAgaWYgKHNvcnRDb2x1bW4gPT09IGlkQ29sdW1uKSB7XG4gICAgcmV0dXJuIHNvcnRPcmRlciA9PT0gJ2Rlc2MnID8gc3FsYCR7aWRDb2x1bW59IDwgJHtpZH1gIDogc3FsYCR7aWRDb2x1bW59ID4gJHtpZH1gO1xuICB9XG4gIGlmIChzb3J0T3JkZXIgPT09ICdhc2MnKSB7XG4gICAgcmV0dXJuIHNvcnRUZXh0ID09PSBudWxsXG4gICAgICA/IHNxbGAoJHtzb3J0Q29sdW1ufSBJUyBOVUxMIEFORCAke2lkQ29sdW1ufSA+ICR7aWR9KWBcbiAgICAgIDogc3FsYCgke3NvcnRDb2x1bW59ID4gJHtzb3J0VGV4dH0gT1IgKCR7c29ydENvbHVtbn0gPSAke3NvcnRUZXh0fSBBTkQgJHtpZENvbHVtbn0gPiAke2lkfSkgT1IgJHtzb3J0Q29sdW1ufSBJUyBOVUxMKWA7XG4gIH1cbiAgcmV0dXJuIHNvcnRUZXh0ID09PSBudWxsXG4gICAgPyBzcWxgKCR7c29ydENvbHVtbn0gSVMgTk9UIE5VTEwgT1IgKCR7c29ydENvbHVtbn0gSVMgTlVMTCBBTkQgJHtpZENvbHVtbn0gPCAke2lkfSkpYFxuICAgIDogc3FsYCgke3NvcnRDb2x1bW59IDwgJHtzb3J0VGV4dH0gT1IgKCR7c29ydENvbHVtbn0gPSAke3NvcnRUZXh0fSBBTkQgJHtpZENvbHVtbn0gPCAke2lkfSkpYDtcbn1cblxuLyoqXG4gKiBSZXRlbnRpb24gYmVmb3JlIGEgc29mdC1kZWxldGVkIHJvdyBiZWNvbWVzIHB1cmdlLWVsaWdpYmxlLCBzaGFyZWQgYWNyb3NzXG4gKiBldmVyeSBDcnVkU2VydmljZSBlbnRpdHkgKHVuaWZpZWQgYFNPRlRfREVMRVRFX1JFVEVOVElPTl9EQVlTYCwgZGVmYXVsdCAzMGQpLlxuICogU3RhbXBlZCBpbnRvIGBwdXJnZV9hZnRlcmAgYXQgZGVsZXRlIHRpbWU7IHRoZSBwZXItc2VydmljZSBwdXJnZSBzd2VlcCBoYXJkLVxuICogZGVsZXRlcyB0b21ic3RvbmVzIG9uY2UgaXQgaGFzIHBhc3NlZC4gYDBgIGRpc2FibGVzIHB1cmdlLWRlYWRsaW5lIHN0YW1waW5nLlxuICovXG5jb25zdCBTT0ZUX0RFTEVURV9SRVRFTlRJT05fTVMgPSBNYXRoLm1heCgwLCBOdW1iZXIucGFyc2VJbnQocHJvY2Vzcy5lbnYuU09GVF9ERUxFVEVfUkVURU5USU9OX0RBWVMgPz8gJzMwJywgMTApIHx8IDApICogMjQgKiA2MCAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBzaGFyZWQgc29mdC1kZWxldGUgcmV0ZW50aW9uIHdpbmRvdyBpbiBtcyAoYFNPRlRfREVMRVRFX1JFVEVOVElPTl9EQVlTYCxcbiAqICBkZWZhdWx0IDMwZDsgMCBkaXNhYmxlcyBwdXJnZS1kZWFkbGluZSBzdGFtcGluZykuIEV4cG9zZWQgc28gbm9uLUNydWRTZXJ2aWNlXG4gKiAgc29mdC1kZWxldGUgcGF0aHMgKGUuZy4gcGxhdGZvcm0ncyBoYW5kLXJvbGxlZCBkYXNoYm9hcmQvYWxlcnQgc2VydmljZXMpXG4gKiAgc3RhbXAgYHB1cmdlX2FmdGVyYCB3aXRoIHRoZSBTQU1FIHdpbmRvdyB0aGUgQ3J1ZFNlcnZpY2UgZW50aXRpZXMgdXNlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvZnREZWxldGVSZXRlbnRpb25NcygpOiBudW1iZXIge1xuICByZXR1cm4gU09GVF9ERUxFVEVfUkVURU5USU9OX01TO1xufVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ3J1ZFNlcnZpY2U8XG4gIFRFbnRpdHkgZXh0ZW5kcyBCYXNlRW50aXR5LFxuICBURmlsdGVyLFxuICBUSW5zZXJ0LFxuICBUVXBkYXRlLFxuPiB7XG4gIC8qKiBEcml6emxlIHNjaGVtYSB0YWJsZSBmb3IgdGhpcyBlbnRpdHkgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldCBzY2hlbWEoKTogUGdUYWJsZTtcblxuICAvKipcbiAgICogVHlwZWQgY29sdW1uIHZpZXcgb2Yge0BsaW5rIHNjaGVtYX0uIGBQZ1RhYmxlYCBleHBvc2VzIG5vIHN0YXRpYyBjb2x1bW5zLCBzb1xuICAgKiB0aGUgYmFzZSBjbGFzcyBwcmV2aW91c2x5IHJlYWNoZWQgZm9yIGAodGhpcy5zY2hlbWEgYXMgYW55KS5pZGAgZXRjLiBhdCBlYWNoXG4gICAqIHVzZTsgY2VudHJhbGl6ZSB0aGF0IHNpbmdsZSB1bmF2b2lkYWJsZSBjYXN0IGhlcmUgc28gY2FsbGVycyBnZXQgc3RydWN0dXJlZCxcbiAgICogdHlwZWQgYWNjZXNzIGluc3RlYWQuIGB2aXNpYmlsaXR5YCBpcyBvcHRpb25hbCAobm90IGV2ZXJ5IGVudGl0eSBoYXMgaXQpXG4gICAqIGFuZCB0aGUgaW5kZXggc2lnbmF0dXJlIGNvdmVycyBkeW5hbWljIHNwYXJzZS1maWVsZHNldCBjb2x1bW4gbG9va3VwLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgY29scygpOiBDcnVkQ29sdW1ucyB7XG4gICAgcmV0dXJuIHRoaXMuc2NoZW1hIGFzIHVua25vd24gYXMgQ3J1ZENvbHVtbnM7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgU1FMIGNvbmRpdGlvbnMgZm9yIGZpbHRlcmluZyBlbnRpdGllcy5cbiAgICogYHBhcmVudE9yZ0lkYCAob3JnIOKGkiB0ZWFtIGhpZXJhcmNoeSkgaXMgb3B0aW9uYWwgYW5kIG9ubHkgaG9ub3JlZCBieVxuICAgKiBzZXJ2aWNlcyB0aGF0IG9wdCBpbnRvIHBhcmVudC1pbmhlcml0ZWQgdmlzaWJpbGl0eSAoZS5nLiBwbHVnaW5zKS5cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBidWlsZENvbmRpdGlvbnMoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXTtcblxuICAvKiogR2V0IHRoZSBzY2hlbWEgY29sdW1uIGZvciBzb3J0aW5nIGJ5IGZpZWxkIG5hbWUgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldFNvcnRDb2x1bW4oc29ydEJ5OiBzdHJpbmcpOiBBbnlDb2x1bW4gfCBudWxsO1xuXG4gIC8qKiBHZXQgdGhlIHByb2plY3QgY29sdW1uIGZvciBzZXREZWZhdWx0IHNjb3BpbmcgKG51bGwgaWYgZW50aXR5IGhhcyBubyBwcm9qZWN0IHNjb3BlKSAqL1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0UHJvamVjdENvbHVtbigpOiBBbnlDb2x1bW4gfCBudWxsO1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHRlbmFudCBvcmctaWQgY29sdW1uLiBVc2VkIGJvdGggdG8gc2NvcGUgYHNldERlZmF1bHRgIGFuZCB0byBwaW5cbiAgICogZXZlcnkgd3JpdGUgKHVwZGF0ZS9kZWxldGUvYnVsa0RlbGV0ZSkgdG8gdGhlIGNhbGxlcidzIG93biBvcmcg4oCUIHNvIGl0IE1VU1RcbiAgICogYmUgdGhlIHRlbmFudCBgb3JnSWRgIGNvbHVtbiwgbm90IGEgZGlzcGxheS9uYW1lIGNvbHVtbi5cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRPcmdDb2x1bW4oKTogQW55Q29sdW1uO1xuXG4gIC8qKiBUaGUgdW5pcXVlLWNvbnN0cmFpbnQgY29sdW1ucyBhIGNyZWF0ZSBtdXN0IG5vdCBjb25mbGljdCBvbiAoc2VlIHtAbGluayBjcmVhdGV9KS4gKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldCBjb25mbGljdFRhcmdldCgpOiBBbnlDb2x1bW5bXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9sb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2NydWQtc2VydmljZScpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIEZhaWwgZmFzdCBpZiBhIHN1YmNsYXNzIGRvZXNuJ3QgZXhwb3NlIGEgdGVuYW50IG9yZyBjb2x1bW4uIFRoZSB3cml0ZVxuICAgIC8vIHBhdGhzICh3cml0ZUNvbmRpdGlvbnMgLyBidWxrRGVsZXRlKSBwaW4gbXV0YXRpb25zIHRvIHRoZSBjYWxsZXIncyBvd25cbiAgICAvLyBvcmcgdGhyb3VnaCBpdDsgYSBtaXNzaW5nIGNvbHVtbiB3b3VsZCBzaWxlbnRseSBkcm9wIHRoYXQgZ3VhcmQg4oCUIGFcbiAgICAvLyBjcm9zcy10ZW5hbnQgZmFpbC1vcGVuIOKAlCBzbyBhc3NlcnQgaXRzIHByZXNlbmNlIHVwIGZyb250LlxuICAgIGlmICh0aGlzLmdldE9yZ0NvbHVtbigpID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9OiBnZXRPcmdDb2x1bW4oKSBtdXN0IHJldHVybiB0aGUgdGVuYW50IG9yZyBjb2x1bW5gKTtcbiAgICB9XG4gIH1cblxuICAvKiogQnVpbGQgY29uZGl0aW9ucyBmb3IgYSBzaW5nbGUgZW50aXR5IGJ5IElELlxuICAgKiAgYHBhcmVudE9yZ0lkYCB3aWRlbnMgdmlzaWJpbGl0eSB0byBhIHBhcmVudCBvcmcncyBwdWJsaWMgcm93cyAob3JnIOKGkiB0ZWFtXG4gICAqICBoaWVyYXJjaHkpIOKAlCBzYW1lIG9wdC1pbiBzZW1hbnRpY3MgYXMgYGZpbmRgL2BmaW5kUGFnaW5hdGVkYC4gT21pdHRlZCBieSB0aGVcbiAgICogIHdyaXRlIHBhdGggKGB3cml0ZUNvbmRpdGlvbnNgKSwgd2hpY2ggbXVzdCBzdGF5IG93bi1vcmcgc2NvcGVkLiAqL1xuICBwcml2YXRlIGlkQ29uZGl0aW9ucyhpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGRDb25kaXRpb25zKHsgaWQgfSBhcyB1bmtub3duIGFzIFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG4gIH1cblxuICAvKipcbiAgICogQ29uZGl0aW9ucyBmb3IgYSBNVVRBVElPTiAodXBkYXRlL2RlbGV0ZSkgb2YgYSBzaW5nbGUgZW50aXR5LlxuICAgKlxuICAgKiBgaWRDb25kaXRpb25zYCByZXVzZXMgdGhlIFJFQUQgYWNjZXNzLWNvbnRyb2wgY2xhdXNlLCB3aGljaCBhbHNvIG1hdGNoZXNcbiAgICogc3lzdGVtLW9yZyAvIG90aGVyLW9yZyBQVUJMSUMgcmVjb3JkcyDigJQgc28gd2l0aG91dCBhbiBleHRyYSBvd25lcnNoaXAgcGluIGFueVxuICAgKiB0ZW5hbnQgY291bGQgdXBkYXRlIG9yIHNvZnQtZGVsZXRlIGFub3RoZXIgb3JnJ3MgKG9yIHRoZSBzeXN0ZW0gb3JnJ3MpIHB1YmxpY1xuICAgKiByZWNvcmRzLiBBTkQgYSBzdHJpY3QgYG9yZ0lkID09PSBjYWxsZXJgIHByZWRpY2F0ZTogdGhlIHJlYWQgY2xhdXNlJ3NcbiAgICogcHVibGljLU9SIGJyYW5jaCByZXF1aXJlcyBgb3JnX2lkID0gJ3N5c3RlbSdgLCB3aGljaCB0aGVuIGNhbid0IGJlIHNhdGlzZmllZCxcbiAgICogbGVhdmluZyBvbmx5IG93bi1vcmcgcm93cy4gb3JnSWQtbGVzcyAoc3lzYWRtaW4pIGNvbnRleHQga2VlcHMgZnVsbCBhY2Nlc3MuXG4gICAqL1xuICBwcml2YXRlIHdyaXRlQ29uZGl0aW9ucyhpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy5pZENvbmRpdGlvbnMoaWQsIG9yZ0lkKTtcbiAgICAvLyBQaW4gdGhlIG11dGF0aW9uIHRvIHRoZSBjYWxsZXIncyBvd24gb3JnIHZpYSB0aGUgdGVuYW50IGNvbHVtblxuICAgIC8vIChnZXRPcmdDb2x1bW4sIGFzc2VydGVkIG5vbi1udWxsIGluIHRoZSBjb25zdHJ1Y3Rvcikg4oCUIGNvbnNpc3RlbnQgd2l0aFxuICAgIC8vIHNldERlZmF1bHQgYW5kIHdpdGhvdXQgdGhlIG9sZCBzaWxlbnQgZmFpbC1vcGVuIHdoZW4gdGhlIHByb3BlcnR5IHdhcyBhYnNlbnQuXG4gICAgaWYgKG9yZ0lkKSBjb25kaXRpb25zLnB1c2goZXEodGhpcy5nZXRPcmdDb2x1bW4oKSwgb3JnSWQpKTtcbiAgICAvLyBGb3JjZSBFWEFDVCBpZCBlcXVhbGl0eSBvbiB0aGUgbXV0YXRpb24gcGF0aC4gYGlkQ29uZGl0aW9uc2AgcmV1c2VzIHRoZVxuICAgIC8vIGxpc3QtZmlsdGVyIGNsYXVzZSwgd2hvc2UgYGJ1aWxkSWRGaWx0ZXJgIFBSRUZJWC1tYXRjaGVzIChgaWQ6OnRleHQgTElLRVxuICAgIC8vICd2YWwlJ2ApIGFueSBub24tZnVsbC1VVUlEIHZhbHVlIOKAlCBzbyBhIHBhcnRpYWwgaWQgKGBERUxFVEUgL3gvYWJgKSB3b3VsZFxuICAgIC8vIHNvZnQtZGVsZXRlL211dGF0ZSBFVkVSWSBvd24tb3JnIHJvdyB3aG9zZSBpZCBzdGFydHMgd2l0aCBgYWJgIGFuZCByZXBvcnRcbiAgICAvLyB0b3VjaGluZyBvbmUuIEFORGluZyBhbiBleGFjdCBgaWQgPSB2YWxgIGNvbGxhcHNlcyB0aGUgcHJlZml4IGNsYXVzZSB0byBhdFxuICAgIC8vIG1vc3QgdGhlIHNpbmdsZSBleGFjdCByb3c7IGEgbWFsZm9ybWVkL3BhcnRpYWwgaWQgdGhlbiBtYXRjaGVzIG5vdGhpbmdcbiAgICAvLyAo4oaSIDQwNCB2aWEgdGhlIGNhbGxlcnMnIGBpZiAoIWRlbGV0ZWQpYCBndWFyZCkgaW5zdGVhZCBvZiBtYXNzLW11dGF0aW5nLlxuICAgIGNvbmRpdGlvbnMucHVzaCh0aGlzLmV4YWN0SWRDb25kaXRpb24oaWQpKTtcbiAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgfVxuXG4gIC8qKiBFeGFjdCBpZCBlcXVhbGl0eSwgbG93ZXItY2FzZWQgdG8gbWF0Y2ggYGJ1aWxkSWRGaWx0ZXJgJ3MgZnVsbC1VVUlEIGJyYW5jaC5cbiAgICogIGBzY2hlbWFgIGlzIHR5cGVkIGBQZ1RhYmxlYCAobm8gc3RhdGljIGAuaWRgKSwgc28gY2FzdCDigJQgc2FtZSBwYXR0ZXJuIHRoZVxuICAgKiAgc29ydC9kZWZhdWx0IGhlbHBlcnMgdXNlIGZvciBjb2x1bW4gYWNjZXNzLiAqL1xuICBwcml2YXRlIGV4YWN0SWRDb25kaXRpb24oaWQ6IHN0cmluZyk6IFNRTCB7XG4gICAgcmV0dXJuIGVxKHRoaXMuY29scy5pZCwgU3RyaW5nKGlkKS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxuXG4gIC8vIExpZmVjeWNsZSBob29rcyDigJQgb3ZlcnJpZGUgaW4gc3ViY2xhc3NlcyB0byByZWFjdCB0byBtdXRhdGlvbnNcbiAgLy8gVGhlc2UgYXJlIGZpcmUtYW5kLWZvcmdldDogZXJyb3JzIGFyZSBsb2dnZWQgYnV0IG5ldmVyIGJsb2NrIHRoZSBjYWxsZXIuXG5cbiAgLyoqIENhbGxlZCBhZnRlciBhIG5ldyBlbnRpdHkgaXMgY3JlYXRlZCAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgb25BZnRlckNyZWF0ZShfZW50aXR5OiBURW50aXR5LCBfdXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIENhbGxlZCBhZnRlciBhbiBlbnRpdHkgaXMgdXBkYXRlZCAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgb25BZnRlclVwZGF0ZShfaWQ6IHN0cmluZywgX2VudGl0eTogVEVudGl0eSwgX3VzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBDYWxsZWQgYWZ0ZXIgYW4gZW50aXR5IGlzIHNvZnQtZGVsZXRlZCAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgb25BZnRlckRlbGV0ZShfaWQ6IHN0cmluZywgX2VudGl0eTogVEVudGl0eSwgX3VzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBDYWxsZWQgYWZ0ZXIgYSBzb2Z0LWRlbGV0ZWQgZW50aXR5IGlzIHJlc3RvcmVkICh1bmRvIHRoZSBkZWxldGUpLiBPdmVycmlkZVxuICAgKiAgZm9yIGVudGl0aWVzIHdob3NlIHJlc3RvcmUgaGFzIHNpZGUtZWZmZWN0cyAoZS5nLiByZS1ub3RpZnkpLiBCZXN0LWVmZm9ydC4gKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJSZXN0b3JlKF9pZDogc3RyaW5nLCBfZW50aXR5OiBURW50aXR5LCBfdXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIENhbGxlZCB3aXRoIHRoZSBpZHMgYWJvdXQgdG8gYmUgaGFyZC1wdXJnZWQsIEJFRk9SRSB0aGUgZGVsZXRlLCBpbnNpZGUgdGhlXG4gICAqICBwdXJnZSB0cmFuc2FjdGlvbiAoYHR4YCkg4oCUIGEgc3ViY2xhc3MgdGVhcmluZyBkb3duIGRlcGVuZGVudHMgdGhhdCBsYWNrIE9OXG4gICAqICBERUxFVEUgQ0FTQ0FERSBNVVNUIHVzZSBgdHhgIHNvIHRoZSB0ZWFyZG93biBpcyBhdG9taWMgd2l0aCB0aGUgcGFyZW50XG4gICAqICBERUxFVEUgKGFuZCBjYW4ndCBzZWxmLWRlYWRsb2NrIGFnYWluc3QgaXRzIHJvdyBsb2NrcykuIFRocm93aW5nIGFib3J0cyB0aGF0XG4gICAqICBiYXRjaCdzIHB1cmdlIChyb3dzIHN0YXkgdG9tYnN0b25lZCwgcmV0cmllZCBuZXh0IHRpY2spLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgb25CZWZvcmVQdXJnZShfaWRzOiBzdHJpbmdbXSwgX3R4OiBDcnVkVHgpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIENhbGxlZCBhZnRlciByb3dzIGFyZSBoYXJkLXB1cmdlZCwgZm9yIGV4dGVybmFsIHNpZGUtZWZmZWN0cyAoZS5nLiBwbHVnaW5cbiAgICogIGltYWdlIEdDKS4gQmVzdC1lZmZvcnQ6IGVycm9ycyBhcmUgbG9nZ2VkLCBuZXZlciBibG9jayB0aGUgc3dlZXAuICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkFmdGVyUHVyZ2UoX2lkczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIFJldGVudGlvbiBiZWZvcmUgYSBzb2Z0LWRlbGV0ZWQgcm93IGJlY29tZXMgcHVyZ2UtZWxpZ2libGUuIERlZmF1bHRzIHRvIHRoZVxuICAgKiAgc2hhcmVkIGBTT0ZUX0RFTEVURV9SRVRFTlRJT05fREFZU2A7IG92ZXJyaWRlIHBlciBlbnRpdHkgZm9yIGEgYmVzcG9rZSB3aW5kb3cuICovXG4gIHByb3RlY3RlZCBnZXQgc29mdERlbGV0ZVJldGVudGlvbk1zKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIFNPRlRfREVMRVRFX1JFVEVOVElPTl9NUztcbiAgfVxuXG4gIC8qKiBUaGUgYHB1cmdlX2FmdGVyYCB2YWx1ZSB0byBzdGFtcCBvbiBhIHNvZnQtZGVsZXRlOiBgbm93ICsgcmV0ZW50aW9uYCwgb3IgdGhlXG4gICAqICBzcHJlYWQtZnJpZW5kbHkgZW1wdHkgb2JqZWN0IHdoZW4gdGhlIGVudGl0eSBoYXMgbm8gYHB1cmdlX2FmdGVyYCBjb2x1bW4uXG4gICAqICBgcHJvdGVjdGVkYCBzbyBzdWJjbGFzc2VzIHdpdGggaGFuZC1yb2xsZWQgc29mdC1kZWxldGUgcGF0aHMgKGUuZy5cbiAgICogIG1lc3NhZ2Utc2VydmljZSdzIHRocmVhZCBjYXNjYWRlIC8gc3lzYWRtaW4gbW9kZXJhdGlvbikgc3RhbXAgaXQgdG9vIOKAlCBhblxuICAgKiAgdW4tc3RhbXBlZCB0b21ic3RvbmUgaGFzIE5VTEwgYHB1cmdlX2FmdGVyYCBhbmQgaXMgbmV2ZXIgaGFyZC1wdXJnZWQuICovXG4gIHByb3RlY3RlZCBwdXJnZUFmdGVyU3RhbXAobm93OiBEYXRlKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIGlmICghdGhpcy5jb2xzLnB1cmdlQWZ0ZXIgfHwgdGhpcy5zb2Z0RGVsZXRlUmV0ZW50aW9uTXMgPD0gMCkgcmV0dXJuIHt9O1xuICAgIHJldHVybiB7IHB1cmdlQWZ0ZXI6IG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLnNvZnREZWxldGVSZXRlbnRpb25NcykgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB3aGVuIGEgcmVhZCBpcyB3aWRlbmVkIHRvIGEgcGFyZW50IG9yZyAoYHBhcmVudE9yZ0lkYFxuICAgKiBzZXQpLCB0aGUgcGFyZW50J3Mgcm93cyBhcmUgb3V0c2lkZSB0aGUgY2FsbGVyJ3MgUkxTIHNjb3BlLCBzbyB0aGUgcmVhZCBtdXN0XG4gICAqIHJ1biB1bmRlciBzeXNhZG1pbiBjb250ZXh0IOKAlCB0aGUgYWNjZXNzLWNvbnRyb2wgV0hFUkUgY2xhdXNlIChvd24gKyBwYXJlbnQgK1xuICAgKiBzeXN0ZW0gcHVibGljLCBidWlsdCBzZXJ2ZXItc2lkZSBmcm9tIGEgdHJ1c3RlZCBKV1QgY2xhaW0pIGlzIHRoZW4gdGhlXG4gICAqIGF1dGhvcml0YXRpdmUgdGVuYW5jeSBnYXRlLiBXaXRob3V0IGBwYXJlbnRPcmdJZGAgaXQgc3RheXMgUkxTLXNjb3BlZC5cbiAgICpcbiAgICogSU5WQVJJQU5UICh3aHkgdGhlIHN5c2FkbWluIGJ5cGFzcyBpcyBzYWZlKTogdGhlIFdIRVJFIGNsYXVzZSBpcyBhbHdheXNcbiAgICogc2VydmVyLWJ1aWx0IGJ5IGBidWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCwgcGFyZW50T3JnSWQpYCBmcm9tIHZhbHVlc1xuICAgKiBkZXJpdmVkIGZyb20gdGhlIHZhbGlkYXRlZCBKV1QgKGBvcmdJZGAgPSBhY3RpdmUgb3JnLCBgcGFyZW50T3JnSWRgID0gdGhlXG4gICAqIGFjdGl2ZSBvcmcncyBwYXJlbnQpLiBOb25lIG9mIHRoZW0gaXMgYSByYXcgdXNlci1zdXBwbGllZCBwcmVkaWNhdGUsIHNvIHRoZVxuICAgKiBieXBhc3Mgb25seSBldmVyIHdpZGVucyB0aGUgcmVhZCB0byB0aGUgY2FsbGVyJ3Mgb3duIHN1YnRyZWUgKyBzeXN0ZW0gcHVibGljXG4gICAqIHJvd3Mg4oCUIGl0IGNhbiBOT1QgYmUgc3RlZXJlZCBhdCBhbiBhcmJpdHJhcnkgb3JnLiBOT1RFOiB0aGlzIGRvZXMgcmVtb3ZlIHRoZVxuICAgKiBSTFMgYmFja3N0b3AgZm9yIHRoZSB3aWRlbmVkIHJlYWQ7IGEgc2luZ2xlLUdVQyBgYXBwLm9yZ19pZGAgY2FuJ3QgZXhwcmVzc1xuICAgKiB0aGUgXCJvd24gT1IgcGFyZW50IE9SIHN5c3RlbVwiIHNldCB0aGUgcG9saWN5IHdvdWxkIG5lZWQsIHNvIHJlcGxhY2luZyB0aGVcbiAgICogYnlwYXNzIHdvdWxkIHJlcXVpcmUgYSB0ZW5hbmN5LWxheWVyIGNoYW5nZSAoZS5nLiBhIG11bHRpLW9yZyBSTFMgcG9saWN5KS5cbiAgICogRGVmZXJyZWQgZGVsaWJlcmF0ZWx5IOKAlCBkbyBub3Qgc3dhcCB0aGlzIGZvciBhIGJsYW5rZXQgYnlwYXNzIHdpdGhvdXRcbiAgICogcmUtY2hlY2tpbmcgdGhlIFdIRVJFIGlzIHN0aWxsIGZ1bGx5IHNlcnZlci1idWlsdC5cbiAgICovXG4gIHByaXZhdGUgcnVuUmVhZDxUPihwYXJlbnRPcmdJZDogc3RyaW5nIHwgdW5kZWZpbmVkLCBmbjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgIHJldHVybiBwYXJlbnRPcmdJZCA/IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIGZuKSA6IGZuKCk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBlbnRpdGllcyBtYXRjaGluZyBmaWx0ZXIgY3JpdGVyaWFcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcGFyYW0gb3JnSWQgLSBVc2VyJ3Mgb3JnYW5pemF0aW9uIElEIChvcHRpb25hbCDigJQgb21pdCBmb3IgYW5vbnltb3VzL3N5c3RlbS1wdWJsaWMtb25seSBhY2Nlc3MpXG4gICAqL1xuICBhc3luYyBmaW5kKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPiwgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5W10+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy5idWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuXG4gICAgcmV0dXJuIHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5zZWxlY3QoKVxuICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKSk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCB0aGUgRklSU1QgZW50aXR5IG1hdGNoaW5nIGBmaWx0ZXJgIOKAlCBhIGJvdW5kZWQgKGBMSU1JVCAxYCkgdmFyaWFudCBvZlxuICAgKiBgZmluZGAgZm9yIHRoZSBcIm1hdGNoIGJ5IGZpbHRlciwgdGFrZSBvbmVcIiByZWFkIHBhdGhzIChlLmcuIGBHRVQgL2ZpbmRgKSwgc29cbiAgICogdGhleSBkb24ndCBgU0VMRUNUYCBldmVyeSBtYXRjaGluZyBvcmcgcm93IGp1c3QgdG8gcmV0dXJuIGBbMF1gLlxuICAgKi9cbiAgYXN5bmMgZmluZEZpcnN0KGZpbHRlcjogUGFydGlhbDxURmlsdGVyPiwgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5IHwgbnVsbD4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5ydW5SZWFkKHBhcmVudE9yZ0lkLCAoKSA9PiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCgpXG4gICAgICAuZnJvbSh0aGlzLnNjaGVtYSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAubGltaXQoMSkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSkpO1xuXG4gICAgcmV0dXJuIHJlc3VsdHNbMF0gfHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGVudGl0aWVzIHdpdGggcGFnaW5hdGlvbiBhbmQgc29ydGluZ1xuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsIOKAlCBvbWl0IGZvciBhbm9ueW1vdXMvc3lzdGVtLXB1YmxpYy1vbmx5IGFjY2VzcylcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBQYWdpbmF0aW9uIGFuZCBzb3J0aW5nIG9wdGlvbnNcbiAgICovXG4gIGFzeW5jIGZpbmRQYWdpbmF0ZWQoXG4gICAgZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LFxuICAgIG9yZ0lkPzogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHBhcmVudE9yZ0lkPzogc3RyaW5nLFxuICApOiBQcm9taXNlPFBhZ2luYXRlZFJlc3VsdDxURW50aXR5Pj4ge1xuICAgIGNvbnN0IHsgbGltaXQ6IHJhd0xpbWl0ID0gREVGQVVMVF9QQUdFX0xJTUlULCBvZmZzZXQgPSAwLCBzb3J0QnksIHNvcnRPcmRlciA9ICdhc2MnLCBpbmNsdWRlVG90YWwgPSBmYWxzZSwgY3Vyc29yLCBmaWVsZHMgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgbGltaXQgPSBNYXRoLm1pbihNYXRoLm1heCgxLCByYXdMaW1pdCksIE1BWF9QQUdFX0xJTUlUKTtcblxuICAgIC8vIFRvdGFsLCBkZXRlcm1pbmlzdGljIG9yZGVyOiAoc29ydCBjb2x1bW4sIGlkKS4gYGlkYCBpcyB1bmlxdWUsIHNvIHJvd3MgdGhhdFxuICAgIC8vIHNoYXJlIGEgc29ydCB2YWx1ZSBoYXZlIGEgc3RhYmxlIHJlbGF0aXZlIG9yZGVyIGFuZCBhIGtleXNldCBjdXJzb3IgY2FuXG4gICAgLy8gbmV2ZXIgc2tpcCBvciByZXBlYXQgdGhlbS4gQW4gYWJzZW50IG9yIFVOS05PV04gYHNvcnRCeWAgb3JkZXJzIGJ5IGBpZGBcbiAgICAvLyBhbG9uZSDigJQgYW4gdW5rbm93biBzb3J0IHVzZWQgdG8gYWRkIG5vIFdIRVJFIGFuZCBubyBPUkRFUiBCWSB3aGlsZSBzdGlsbFxuICAgIC8vIGVtaXR0aW5nIGEgY3Vyc29yLCBzbyBhIGN1cnNvciBjbGllbnQgbG9vcGVkIG9uIHBhZ2UgMSBmb3JldmVyLlxuICAgIGNvbnN0IGlkQ29sdW1uID0gdGhpcy5jb2xzLmlkO1xuICAgIGNvbnN0IHNvcnRDb2x1bW4gPSAoc29ydEJ5ID8gdGhpcy5nZXRTb3J0Q29sdW1uKHNvcnRCeSkgOiBudWxsKSA/PyBpZENvbHVtbjtcbiAgICBjb25zdCBkaXJlY3Rpb24gPSBzb3J0T3JkZXIgPT09ICdkZXNjJyA/IGRlc2MgOiBhc2M7XG4gICAgY29uc3Qgb3JkZXJCeSA9IHNvcnRDb2x1bW4gPT09IGlkQ29sdW1uID8gW2RpcmVjdGlvbihpZENvbHVtbildIDogW2RpcmVjdGlvbihzb3J0Q29sdW1uKSwgZGlyZWN0aW9uKGlkQ29sdW1uKV07XG5cbiAgICAvLyBDdXJzb3IgYW5kIG9mZnNldCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIOKAlCBhIHZhbGlkIGN1cnNvciB0YWtlcyBwcmVjZWRlbmNlLlxuICAgIC8vIEEgbWFsZm9ybWVkL3RhbXBlcmVkIGN1cnNvciDigJQgaW5jbHVkaW5nIHdlbGwtZm9ybWVkIEpTT04gd2hvc2UgdmFsdWVzXG4gICAgLy8gY2FuJ3QgYmUgY2FzdCB0byB0aGUgaWQgLyBzb3J0IGNvbHVtbiB0eXBlcyDigJQgaXMgaWdub3JlZCAocmVhZHMgZnJvbSB0aGVcbiAgICAvLyBzdGFydCkgaW5zdGVhZCBvZiByZWFjaGluZyBQb3N0Z3JlcyBhbmQgZmFpbGluZyB0aGUgcXVlcnkuXG4gICAgY29uc3QgcmF3Q3Vyc29yID0gY3Vyc29yID8gZGVjb2RlQ3Vyc29yKGN1cnNvcikgOiBudWxsO1xuICAgIGNvbnN0IGRlY29kZWRDdXJzb3IgPSByYXdDdXJzb3JcbiAgICAgICYmIGlzQ2FzdGFibGVUbyhpZENvbHVtbiwgcmF3Q3Vyc29yLmlkKVxuICAgICAgLy8gKGFuIGlkLW9ubHkgb3JkZXIgbmV2ZXIgYmluZHMgdGhlIHNvcnQgdmFsdWUg4oCUIHNlZSBrZXlzZXRBZnRlcilcbiAgICAgICYmIChzb3J0Q29sdW1uID09PSBpZENvbHVtbiB8fCByYXdDdXJzb3Iuc29ydFRleHQgPT09IG51bGwgfHwgaXNDYXN0YWJsZVRvKHNvcnRDb2x1bW4sIHJhd0N1cnNvci5zb3J0VGV4dCkpXG4gICAgICA/IHJhd0N1cnNvclxuICAgICAgOiBudWxsO1xuICAgIGlmIChjdXJzb3IgJiYgIWRlY29kZWRDdXJzb3IpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdJZ25vcmluZyBtYWxmb3JtZWQgcGFnaW5hdGlvbiBjdXJzb3InLCB7IGVudGl0eTogdGhpcy5jb25zdHJ1Y3Rvci5uYW1lIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG4gICAgaWYgKGRlY29kZWRDdXJzb3IpIHtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChrZXlzZXRBZnRlcihzb3J0Q29sdW1uLCBpZENvbHVtbiwgc29ydE9yZGVyLCBkZWNvZGVkQ3Vyc29yLnNvcnRUZXh0LCBkZWNvZGVkQ3Vyc29yLmlkKSk7XG4gICAgfVxuXG4gICAgLy8gV3JhcCB0aGUgd2hvbGUgcGFnaW5hdGVkIHJlYWQgKFNFTEVDVCArIG9wdGlvbmFsIENPVU5UKSBpbiBvbmVcbiAgICAvLyB0ZW5hbnQgdHguIEJvdGggcXVlcmllcyBhcmUgdmlzaWJpbGl0eS1zY29wZWQgYnkgdGhlIHNhbWUgUkxTIHBvbGljeSxcbiAgICAvLyBhbmQgcGlubmluZyB0aGVtIHRvIGEgc2luZ2xlIHR4IGtlZXBzIHRoZSBgYXBwLm9yZ19pZGAgR1VDIHN0YWJsZVxuICAgIC8vIGJldHdlZW4gdGhlbS4gV2hlbiB3aWRlbmluZyB0byBhIHBhcmVudCBvcmcsIHRoZSB3aG9sZSByZWFkIHJ1bnMgdW5kZXJcbiAgICAvLyBzeXNhZG1pbiBjb250ZXh0IChzZWUgcnVuUmVhZCkgc28gdGhlIGFjY2Vzcy1jb250cm9sIFdIRVJFIGlzIHRoZSBnYXRlLlxuICAgIHJldHVybiB0aGlzLnJ1blJlYWQocGFyZW50T3JnSWQsICgpID0+IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAgIC8vIFByb2plY3Rpb246IHRoZSBzcGFyc2UgZmllbGRzZXQgKGFsd2F5cyBpbmNsdWRlcyBgaWRgKSBvciBldmVyeSBjb2x1bW4sXG4gICAgICAvLyBwbHVzIHRoZSBzb3J0IGNvbHVtbidzIGV4YWN0IHRleHQgZm9yIHRoZSBuZXh0IGN1cnNvci5cbiAgICAgIGNvbnN0IGJhc2VTZWxlY3QgPSAoZmllbGRzID8gdGhpcy5idWlsZEZpZWxkU2VsZWN0KGZpZWxkcykgOiB1bmRlZmluZWQpID8/IGdldFRhYmxlQ29sdW1ucyh0aGlzLnNjaGVtYSk7XG4gICAgICBjb25zdCBzZWxlY3RTcGVjID0geyAuLi5iYXNlU2VsZWN0LCBbQ1VSU09SX1NPUlRfS0VZXTogc3FsPHN0cmluZyB8IG51bGw+YCR7c29ydENvbHVtbn06OnRleHRgIH07XG5cbiAgICAgIC8vIEZldGNoIGxpbWl0KzEgdG8gZGV0ZWN0IGhhc01vcmUgd2l0aG91dCBDT1VOVCgqKVxuICAgICAgY29uc3QgZWZmZWN0aXZlT2Zmc2V0ID0gZGVjb2RlZEN1cnNvciA/IDAgOiBvZmZzZXQ7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdHguc2VsZWN0KHNlbGVjdFNwZWMgYXMgYW55KS5mcm9tKHRoaXMuc2NoZW1hKS53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAgIC5vcmRlckJ5KC4uLm9yZGVyQnkpXG4gICAgICAgIC5saW1pdChsaW1pdCArIDEpXG4gICAgICAgIC5vZmZzZXQoZWZmZWN0aXZlT2Zmc2V0KS50aGVuKHIgPT4gZHJpenpsZVJvd3M8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHIpKTtcblxuICAgICAgY29uc3QgaGFzTW9yZSA9IHJvd3MubGVuZ3RoID4gbGltaXQ7XG4gICAgICBjb25zdCBwYWdlID0gaGFzTW9yZSA/IHJvd3Muc2xpY2UoMCwgbGltaXQpIDogcm93cztcbiAgICAgIGNvbnN0IGRhdGEgPSBwYWdlLm1hcCgocm93KSA9PiB7XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IHsgLi4ucm93IH07XG4gICAgICAgIGRlbGV0ZSBlbnRpdHlbQ1VSU09SX1NPUlRfS0VZXTtcbiAgICAgICAgcmV0dXJuIGVudGl0eSBhcyBURW50aXR5O1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdDogUGFnaW5hdGVkUmVzdWx0PFRFbnRpdHk+ID0geyBkYXRhLCBsaW1pdCwgb2Zmc2V0OiBlZmZlY3RpdmVPZmZzZXQsIGhhc01vcmUgfTtcblxuICAgICAgaWYgKGhhc01vcmUpIHtcbiAgICAgICAgY29uc3QgbGFzdCA9IHBhZ2VbcGFnZS5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3Qgc29ydFRleHQgPSBsYXN0W0NVUlNPUl9TT1JUX0tFWV07XG4gICAgICAgIHJlc3VsdC5uZXh0Q3Vyc29yID0gZW5jb2RlQ3Vyc29yKHNvcnRUZXh0ID09IG51bGwgPyBudWxsIDogU3RyaW5nKHNvcnRUZXh0KSwgU3RyaW5nKGxhc3QuaWQpKTtcbiAgICAgIH1cblxuICAgICAgLy8gT25seSBydW4gdGhlIENPVU5UKCopIHF1ZXJ5IHdoZW4gdGhlIGNhbGxlciBleHBsaWNpdGx5IG5lZWRzIHRoZSB0b3RhbC5cbiAgICAgIC8vIE11c3QgaW5jbHVkZSBwYXJlbnRPcmdJZCBzbyBgdG90YWxgIG1hdGNoZXMgdGhlIHdpZGVuZWQgZGF0YSBzZXQuXG4gICAgICBpZiAoaW5jbHVkZVRvdGFsKSB7XG4gICAgICAgIGNvbnN0IGJhc2VDb25kaXRpb25zID0gdGhpcy5idWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICAgICAgICBjb25zdCBbY291bnRSZXN1bHRdID0gYXdhaXQgdHhcbiAgICAgICAgICAuc2VsZWN0KHsgY291bnQ6IHNxbDxudW1iZXI+YGNvdW50KCopOjppbnRgIH0pXG4gICAgICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAgICAgLndoZXJlKGFuZCguLi5iYXNlQ29uZGl0aW9ucykpLnRoZW4ociA9PiBkcml6emxlQ291bnQocikpO1xuICAgICAgICByZXN1bHQudG90YWwgPSBjb3VudFJlc3VsdD8uY291bnQgfHwgMDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb2x1bW4gc2VsZWN0aW9uIG1hcCBmb3Igc3BhcnNlIGZpZWxkc2V0cy5cbiAgICogRmFsbHMgYmFjayB0byBmdWxsIHNlbGVjdCBpZiBubyBmaWVsZHMgYXJlIHJlcXVlc3RlZC5cbiAgICpcbiAgICogYGlkYCBpcyBhbHdheXMgaW5jbHVkZWQg4oCUIGl0IGlzIHRoZSBlbnRpdHkgaWRlbnRpdHkgQU5EIHRoZSBrZXlzZXQgY3Vyc29yJ3NcbiAgICogdGllLWJyZWFrZXIuIFRoZSBzb3J0IHZhbHVlIGZvciB0aGUgY3Vyc29yIGlzIHByb2plY3RlZCBzZXBhcmF0ZWx5IChhcyB0ZXh0KVxuICAgKiBieSBgZmluZFBhZ2luYXRlZGAsIHNvIHRoZSBmaWVsZHNldCBuZWVkIG5vdCBjYXJyeSB0aGUgc29ydCBjb2x1bW4uXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkRmllbGRTZWxlY3QoZmllbGRzOiBzdHJpbmdbXSk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoZmllbGRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgLy8gQWx3YXlzIGluY2x1ZGUgaWQgZm9yIGVudGl0eSBpZGVudGl0eVxuICAgIGNvbHVtbnMuaWQgPSB0aGlzLmNvbHMuaWQ7XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgaWYgKGZpZWxkID09PSAnaWQnKSBjb250aW51ZTsgLy8gQWxyZWFkeSBpbmNsdWRlZFxuICAgICAgY29uc3QgY29sID0gdGhpcy5jb2xzW2ZpZWxkXTtcbiAgICAgIGlmIChjb2wpIGNvbHVtbnNbZmllbGRdID0gY29sO1xuICAgIH1cblxuICAgIC8vIEF0IG1pbmltdW0gd2UnbGwgaGF2ZSB7IGlkIH0sIHdoaWNoIGlzIHZhbGlkXG4gICAgcmV0dXJuIGNvbHVtbnM7XG4gIH1cblxuICAvKipcbiAgICogQ291bnQgZW50aXRpZXMgbWF0Y2hpbmcgZmlsdGVyIGNyaXRlcmlhXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKiBAcGFyYW0gcGFyZW50T3JnSWQgLSBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB3aWRlbiB0aGUgY291bnQgdG8gdGhlIHBhcmVudCBvcmcnc1xuICAgKiAgIHB1YmxpYyByb3dzLiBNVVNUIG1pcnJvciBgZmluZGAvYGZpbmRQYWdpbmF0ZWRgJ3Mgd2lkZW5pbmcgKHNhbWVcbiAgICogICBgYnVpbGRDb25kaXRpb25zYCBhcmdzICsgc3lzYWRtaW4tc2NvcGVkIHJlYWQgdmlhIGBydW5SZWFkYCkgc28gYSBwYWdlZFxuICAgKiAgIGxpc3QncyBgdG90YWxgIG1hdGNoZXMgdGhlIHJvd3MgYSB3aWRlbmVkIGBmaW5kKClgIHJldHVybnMg4oCUIG90aGVyd2lzZSB0aGVcbiAgICogICBjb3VudCBvbWl0cyB0aGUgcGFyZW50J3Mgcm93cyBhbmQgcmVwb3J0cyBhIG5hcnJvd2VyIHRvdGFsIHRoYW4gdGhlIGRhdGEgc2V0LlxuICAgKi9cbiAgYXN5bmMgY291bnQoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG5cbiAgICBjb25zdCBbcmVzdWx0XSA9IGF3YWl0IHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5zZWxlY3QoeyBjb3VudDogc3FsPG51bWJlcj5gY291bnQoKik6OmludGAgfSlcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSkudGhlbihyID0+IGRyaXp6bGVDb3VudChyKSkpKTtcblxuICAgIHJldHVybiByZXN1bHQ/LmNvdW50IHx8IDA7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhIHNpbmdsZSBlbnRpdHkgYnkgSURcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gRW50aXR5IElEXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsIOKAlCBvbWl0IGZvciBhbm9ueW1vdXMvc3lzdGVtLXB1YmxpYy1vbmx5IGFjY2VzcylcbiAgICogQHBhcmFtIHBhcmVudE9yZ0lkIC0gT3JnIOKGkiB0ZWFtIGhpZXJhcmNoeTogd2lkZW4gdmlzaWJpbGl0eSB0byB0aGUgcGFyZW50XG4gICAqICAgb3JnJ3MgcHVibGljIHJvd3MgKHNvIGEgdGVhbSBjYW4gZmV0Y2ggYSBwYXJlbnQncyBwdWJsaWMgZW50aXR5IGJ5IGlkKS5cbiAgICogICBTYW1lIG9wdC1pbiArIHN5c2FkbWluLXNjb3BlZCByZWFkIGFzIGBmaW5kYC9gZmluZFBhZ2luYXRlZGA7IHRoZVxuICAgKiAgIGFjY2Vzcy1jb250cm9sIFdIRVJFIGNsYXVzZSBpcyB0aGUgYXV0aG9yaXRhdGl2ZSB0ZW5hbmN5IGdhdGUuXG4gICAqL1xuICBhc3luYyBmaW5kQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFRFbnRpdHkgfCBudWxsPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuaWRDb25kaXRpb25zKGlkLCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICAgIC8vIEV4YWN0IGlkIOKAlCBgZmluZEJ5SWRgIG1lYW5zIFRIRSByb3cgd2l0aCB0aGlzIGlkLCBub3QgYSBwcmVmaXggbWF0Y2guIFRoZVxuICAgIC8vIHNoYXJlZCBgYnVpbGRJZEZpbHRlcmAgcHJlZml4LW1hdGNoZXMgbm9uLWZ1bGwtVVVJRCB2YWx1ZXMgKGEgbGlzdC1zZWFyY2hcbiAgICAvLyBmZWF0dXJlKSwgd2hpY2ggaGVyZSB3b3VsZCByZXR1cm4gYW4gYXJiaXRyYXJ5IGZpcnN0IHByZWZpeCBoaXQgZm9yIGFcbiAgICAvLyBwYXJ0aWFsIGlkOyBwaW4gaXQgdG8gZXhhY3Qgc28gYSBtYWxmb3JtZWQgaWQgcmV0dXJucyBudWxsLlxuICAgIGNvbmRpdGlvbnMucHVzaCh0aGlzLmV4YWN0SWRDb25kaXRpb24oaWQpKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLnJ1blJlYWQocGFyZW50T3JnSWQsICgpID0+IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAuc2VsZWN0KClcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5saW1pdCgxKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKSk7XG5cbiAgICByZXR1cm4gcmVzdWx0c1swXSB8fCBudWxsO1xuICB9XG5cbiAgLy8gTXV0YXRpb24gb3BlcmF0aW9uc1xuXG4gIC8qKlxuICAgKiBEZWZlbnNlLWluLWRlcHRoIHRlbmFudCBzdGFtcC4gUkxTIGlzIGluIG93bmVyLWJ5cGFzcyBtb2RlLCBzbyB0aGUgYXBwIGxheWVyXG4gICAqIGlzIHRoZSBvbmx5IHRlbmFudCBnYXRlIG9uIHdyaXRlcy4gQSBOT04tc3lzYWRtaW4gY2FsbGVyIG1heSBvbmx5IHdyaXRlIGludG9cbiAgICogaXRzIE9XTiBvcmcsIHNvIHBpbiB0aGUgcm93IHRvIHRoZSB0cnVzdGVkIHRlbmFudC1jb250ZXh0IG9yZy5cbiAgICpcbiAgICogVGhlIHN0YW1wIGZpcmVzIHdoZW5ldmVyIHRoZSBwYXlsb2FkJ3MgYG9yZ0lkYCBkaWZmZXJzIGZyb20gdGhlIGNvbnRleHQgb3JnIOKAlFxuICAgKiB3aGljaCBjb3ZlcnMgQk9USCBhIGZvcmdlZC9taXNtYXRjaGVkIGBkYXRhLm9yZ0lkYCBBTkQgYW4gQUJTRU5UIG9uZS4gVGhlXG4gICAqIGFic2VudCBjYXNlIGlzIHRoZSBpbXBvcnRhbnQgdGVuYW50LWJvdW5kYXJ5IGZpeDogdGhlIGBvcmdfaWRgIGNvbHVtbiBERUZBVUxUc1xuICAgKiB0byBgU1lTVEVNX09SR19JRGAgKHNjaGVtYS9waXBlbGluZS50cywgc2NoZW1hL3BsdWdpbi50cyksIHNvIGFuIGluc2VydCB0aGF0XG4gICAqIG9taXRzIGBvcmdJZGAgd291bGQgb3RoZXJ3aXNlIGxhbmQgdGhlIHRlbmFudCdzIHJvdyBpbiB0aGUgcHVibGljIHN5c3RlbVxuICAgKiBjYXRhbG9nIOKAlCBhIGNyb3NzLXRlbmFudCBmYWlsLW9wZW4uIEFsd2F5cyBpbmplY3RpbmcgYGN0eC5vcmdJZGAgY2xvc2VzIGl0LlxuICAgKlxuICAgKiBTeXNhZG1pbiAoYW5kIG91dC1vZi1jb250ZXh0IHdvcmtlci9zeXN0ZW0gcGF0aHMsIHdoZXJlIGBnZXRUZW5hbnRDb250ZXh0KClgXG4gICAqIGlzIHVuZGVmaW5lZCkga2VlcCB0aGUgc3VwcGxpZWQgb3JnLCBtYXRjaGluZyB0aGUgUkxTIHBvbGljeVxuICAgKiBgY3VycmVudF9pc19zeXNhZG1pbigpIE9SIG9yZ19pZCA9IGN1cnJlbnRfb3JnX2lkKClgLlxuICAgKi9cbiAgLy8gR2VuZXJpYyBvdmVyIHRoZSBwYXlsb2FkIHNoYXBlIHNvIEJPVEggdGhlIGNyZWF0ZSAoYFRJbnNlcnRgKSBhbmQgdXBkYXRlXG4gIC8vIChgUGFydGlhbDxUVXBkYXRlPmApIGNhbGwgc2l0ZXMgdXNlIGl0IHdpdGhvdXQgdGhlIGBhcyB1bmtub3duIGFzIFRJbnNlcnRgXG4gIC8vIHJvdW5kLXRyaXAgdGhleSBwcmV2aW91c2x5IG5lZWRlZCDigJQgdGhlIG9yZy1zdGFtcCBsb2dpYyBpcyBpZGVudGljYWwgZm9yXG4gIC8vIGVpdGhlciBzaGFwZSAoaXQgb25seSB0b3VjaGVzIHRoZSBgb3JnSWRgIGtleSkuXG4gIHByb3RlY3RlZCBlbmZvcmNlT3JnSWQ8VD4oZGF0YTogVCwgaXNDcmVhdGUgPSBmYWxzZSk6IFQge1xuICAgIGNvbnN0IGN0eCA9IGdldFRlbmFudENvbnRleHQoKTtcbiAgICBjb25zdCBkID0gZGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAvLyBSZWZ1c2UgYSBjb250ZXh0LWxlc3MsIG9yZ0lkLWxlc3MgSU5TRVJUIG9uIGFuIG9yZy1zY29wZWQgZW50aXR5OiB0aGUgYG9yZ0lkYFxuICAgIC8vIGNvbHVtbiBkZWZhdWx0cyB0byBTWVNURU1fT1JHX0lELCBzbyBzdWNoIGEgcm93IHdvdWxkIHNpbGVudGx5IGxhbmQgaW4gdGhlXG4gICAgLy8gcHVibGljIGNyb3NzLW9yZyBjYXRhbG9nLiBBIGJhY2tncm91bmQgam9iIHRoYXQgZm9yZ290IGBydW5XaXRoVGVuYW50Q29udGV4dGBcbiAgICAvLyAoYW5kIGRpZG4ndCBwYXNzIGFuIGV4cGxpY2l0IG9yZ0lkKSBtdXN0IGZhaWwgbG91ZGx5LCBub3QgbGVhayBpbnRvIGBzeXN0ZW1gLlxuICAgIC8vIChTeXNhZG1pbi9zZWVkIHdyaXRlcyBjYXJyeSBhIGNvbnRleHQgb3IgYW4gZXhwbGljaXQgb3JnSWQsIHNvIHRoZXkgcGFzcy4pXG4gICAgaWYgKGlzQ3JlYXRlICYmICFjdHggJiYgZC5vcmdJZCA9PSBudWxsICYmIHRoaXMuY29scy5vcmdJZCAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfS5jcmVhdGUgcmVxdWlyZXMgYW4gb3JnSWQgKG5vIHRlbmFudCBjb250ZXh0IGFuZCBub25lIHN1cHBsaWVkKSDigJQgcmVmdXNpbmcgdG8gZGVmYXVsdCB0byB0aGUgc3lzdGVtIG9yZ2ApO1xuICAgIH1cbiAgICBpZiAoY3R4ICYmICFjdHguaXNTdXBlckFkbWluICYmIGN0eC5vcmdJZCAmJiBkLm9yZ0lkICE9PSBjdHgub3JnSWQpIHtcbiAgICAgIC8vIERpc3Rpbmd1aXNoIHRoZSB0d28gY2FzZXMgdGhhdCByZWFjaCBoZXJlIHNvIHRoZSBsb2cgc3RheXMgdXNlZnVsIGFuZFxuICAgICAgLy8gcXVpZXQ6IGEgUFJFU0VOVC1idXQtbWlzbWF0Y2hlZCBgb3JnSWRgIGlzIGFuIGFjdHVhbCBvdmVycmlkZSBhdHRlbXB0XG4gICAgICAvLyAod2FybiksIHdoaWxlIGFuIEFCU0VOVCBgb3JnSWRgIGlzIHRoZSBjb21tb24gbm9ybWFsLXdyaXRlIHBhdGggdGhhdCBqdXN0XG4gICAgICAvLyBuZWVkcyB0aGUgZGVmYXVsdCBzdGFtcCAoZGVidWcpIOKAlCBsb2dnaW5nIHRoYXQgYXQgd2FybiBmbG9vZHMgdGhlIGxvZyBvblxuICAgICAgLy8gZXZlcnkgd3JpdGUgdGhhdCBvbWl0cyBvcmdJZC5cbiAgICAgIGNvbnN0IG1ldGEgPSB7IHN1cHBsaWVkOiAnb3JnSWQnIGluIGQgPyBkLm9yZ0lkIDogdW5kZWZpbmVkLCBlbmZvcmNlZDogY3R4Lm9yZ0lkIH07XG4gICAgICBpZiAoJ29yZ0lkJyBpbiBkKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdDcnVkU2VydmljZTogb3ZlcnJpZGluZyBtaXNtYXRjaGVkIG9yZyBvbiB3cml0ZScsIG1ldGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKCdDcnVkU2VydmljZTogc3RhbXBpbmcgdGVuYW50LWNvbnRleHQgb3JnIG9uIHdyaXRlJywgbWV0YSk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyAuLi5kLCBvcmdJZDogY3R4Lm9yZ0lkIH0gYXMgVDtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGVudGl0eVxuICAgKi9cbiAgYXN5bmMgY3JlYXRlKGRhdGE6IFRJbnNlcnQsIHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5PiB7XG4gICAgY29uc3Qgc2FmZURhdGEgPSB0aGlzLmVuZm9yY2VPcmdJZChkYXRhLCAvKiBpc0NyZWF0ZSAqLyB0cnVlKTtcbiAgICAvLyBDcmVhdGUgbmV2ZXIgb3ZlcndyaXRlcy4gVGhlIGNvbmZsaWN0IGtleSBjYW4gbWF0Y2ggYSBMSVZFIHJvdyAoYW5vdGhlclxuICAgIC8vIGF1dGhvcidzLCBvciBvbmUgdGhlIGNhbGxlciBjb3VsZG4ndCBlZGl0IHRocm91Z2ggdXBkYXRlKSBvciBhIHNvZnQtZGVsZXRlZFxuICAgIC8vIFRPTUJTVE9ORTsgcmVwbGFjaW5nIGVpdGhlciB3b3VsZCBieXBhc3MgdXBkYXRlJ3MgYWNjZXNzIGNoZWNrcyBvciByZXN0b3JlJ3NcbiAgICAvLyBzdGVwLXVwLiBPbiBhbnkgY29uZmxpY3Qgbm90aGluZyBpcyB3cml0dGVuIGFuZCB0aGUgY2FsbGVyIGdldHMgYSA0MDkuXG4gICAgY29uc3QgW2NyZWF0ZWRdID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5pbnNlcnQodGhpcy5zY2hlbWEpXG4gICAgICAudmFsdWVzKHtcbiAgICAgICAgLi4uc2FmZURhdGEsXG4gICAgICAgIGNyZWF0ZWRCeTogdXNlcklkIHx8ICdzeXN0ZW0nLFxuICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgIH0gYXMgYW55KVxuICAgICAgLm9uQ29uZmxpY3REb05vdGhpbmcoeyB0YXJnZXQ6IHRoaXMuY29uZmxpY3RUYXJnZXQgYXMgYW55IH0pXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICBpZiAoIWNyZWF0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBDb25mbGljdEVycm9yKCdBIHJlY29yZCB3aXRoIHRoZSBzYW1lIGlkZW50aXR5IGFscmVhZHkgZXhpc3RzLiBJZiBpdCB3YXMgZGVsZXRlZCwgcmVzdG9yZSBpdCBpbnN0ZWFkLicpO1xuICAgIH1cblxuICAgIC8vIEF3YWl0ZWQgaW50ZW50aW9uYWxseTogY2FjaGUgaW52YWxpZGF0aW9uIGhhcHBlbnMgaW4gdGhlIGhvb2ssIGFuZCBhXG4gICAgLy8gZmlyZS1hbmQtZm9yZ2V0IHBhdHRlcm4gbGV0cyBhIHN1YnNlcXVlbnQgcmVhZCBpbnNpZGUgdGhlIHNhbWUgcmVxdWVzdFxuICAgIC8vIHJldHVybiB0aGUgc3RhbGUgcHJlLXdyaXRlIGVudHJ5LiBUaGUgaG9vayBpcyBleHBlY3RlZCB0byBiZSBmYXN0XG4gICAgLy8gKHNpbmdsZSBSZWRpcyBvcCk7IHNsb3cgaG9va3Mgc2hvdWxkIHJ1biB0aGVpciBvd24gYmFja2dyb3VuZCB3b3JrLlxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLm9uQWZ0ZXJDcmVhdGUoY3JlYXRlZCwgdXNlcklkKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdMaWZlY3ljbGUgaG9vayBmYWlsZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYW4gZXhpc3RpbmcgZW50aXR5XG4gICAqL1xuICBhc3luYyB1cGRhdGUoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBkYXRhOiBQYXJ0aWFsPFRVcGRhdGU+LFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy53cml0ZUNvbmRpdGlvbnMoaWQsIG9yZ0lkKTtcblxuICAgIC8vIFNjcnViIGEgY2FsbGVyLXN1cHBsaWVkIGBvcmdJZGAgaW4gdGhlIHVwZGF0ZSBwYXlsb2FkIChhcyBjcmVhdGUgZG9lcyk6IHRoZVxuICAgIC8vIFdIRVJFIG9ubHkgcGlucyB3aGljaCByb3dzIHlvdSBjYW4gVEFSR0VULCBub3Qgd2hhdCB5b3UgY2FuIHNldCDigJQgd2l0aG91dCB0aGlzXG4gICAgLy8gYSB0ZW5hbnQgY291bGQgcmUtaG9tZSBhIHJvdyBpdCBvd25zIGludG8gYW5vdGhlciBvcmcgdmlhIGBkYXRhLm9yZ0lkYC5cbiAgICBjb25zdCBzYWZlRGF0YSA9IHRoaXMuZW5mb3JjZU9yZ0lkKGRhdGEpO1xuXG4gICAgY29uc3QgW3VwZGF0ZWRdID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHtcbiAgICAgICAgLi4uc2FmZURhdGEsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICB9IGFzIGFueSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICBpZiAodXBkYXRlZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5vbkFmdGVyVXBkYXRlKGlkLCB1cGRhdGVkLCB1c2VySWQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdMaWZlY3ljbGUgaG9vayBmYWlsZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdXBkYXRlZCB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhbiBlbnRpdHkgKHNvZnQgZGVsZXRlIGJ5IHNldHRpbmcgaXNBY3RpdmUgPSBmYWxzZSlcbiAgICovXG4gIGFzeW5jIGRlbGV0ZShpZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy53cml0ZUNvbmRpdGlvbnMoaWQsIG9yZ0lkKTtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gICAgY29uc3QgW2RlbGV0ZWRdID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHtcbiAgICAgICAgaXNBY3RpdmU6IGZhbHNlLFxuICAgICAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICAgIGRlbGV0ZWRBdDogbm93LFxuICAgICAgICBkZWxldGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgICAgLy8gU3RhbXAgdGhlIHB1cmdlIGRlYWRsaW5lIHNvIHRoZSByZXRlbnRpb24gc3dlZXAgY2FuIGhhcmQtZGVsZXRlIGxhdGVyLlxuICAgICAgICAuLi50aGlzLnB1cmdlQWZ0ZXJTdGFtcChub3cpLFxuICAgICAgfSBhcyBhbnkpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpO1xuXG4gICAgaWYgKGRlbGV0ZWQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMub25BZnRlckRlbGV0ZShpZCwgZGVsZXRlZCwgdXNlcklkKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignTGlmZWN5Y2xlIGhvb2sgZmFpbGVkJywgeyBlcnJvcjogU3RyaW5nKGVycikgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlbGV0ZWQgfHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYW4gZW50aXR5IGFzIHRoZSBkZWZhdWx0IGZvciBhIHByb2plY3Qvb3JnYW5pemF0aW9uIHNjb3BlLlxuICAgKiBNYXJrcyBhbGwgb3RoZXIgZW50aXRpZXMgYXMgbm9uLWRlZmF1bHQsIHRoZW4gc2V0cyB0aGUgc3BlY2lmaWVkIGVudGl0eS5cbiAgICogVXNlcyBhIHRyYW5zYWN0aW9uIHRvIGVuc3VyZSBhdG9taWNpdHkuXG4gICAqL1xuICBhc3luYyBzZXREZWZhdWx0KFxuICAgIHByb2plY3Q6IHN0cmluZyxcbiAgICBvcmc6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nLFxuICAgIHVzZXJJZDogc3RyaW5nLFxuICApOiBQcm9taXNlPFRFbnRpdHk+IHtcbiAgICAvLyBBIG5vbi1zeXNhZG1pbiBtYXkgb25seSBmbGlwIGRlZmF1bHRzIHdpdGhpbiBpdHMgT1dOIG9yZyDigJQgcGluIHRoZSBzY29wZSB0b1xuICAgIC8vIHRoZSB0cnVzdGVkIHRlbmFudCBjb250ZXh0IHNvIGEgZm9yd2FyZGVkIGBvcmdgIGFyZyBjYW4ndCB0b3VjaCBhbm90aGVyXG4gICAgLy8gdGVuYW50J3MgZGVmYXVsdHMgKFJMUyBpcyBpbiBvd25lci1ieXBhc3MgbW9kZTsgdGhpcyBpcyB0aGUgZ2F0ZSkuXG4gICAgY29uc3QgY3R4ID0gZ2V0VGVuYW50Q29udGV4dCgpO1xuICAgIGlmIChjdHggJiYgIWN0eC5pc1N1cGVyQWRtaW4gJiYgY3R4Lm9yZ0lkKSBvcmcgPSBjdHgub3JnSWQ7XG4gICAgcmV0dXJuIHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAgIGNvbnN0IG9yZ0NvbHVtbiA9IHRoaXMuZ2V0T3JnQ29sdW1uKCk7XG4gICAgICBjb25zdCBwcm9qZWN0Q29sdW1uID0gdGhpcy5nZXRQcm9qZWN0Q29sdW1uKCk7XG5cbiAgICAgIC8vIEJ1aWxkIHNjb3BpbmcgY29uZGl0aW9ucyBmb3IgY2xlYXJpbmcgZGVmYXVsdHNcbiAgICAgIGNvbnN0IHNjb3BlQ29uZGl0aW9ucyA9IFtcbiAgICAgICAgZXEob3JnQ29sdW1uLCBvcmcpLFxuICAgICAgICBlcSh0aGlzLmNvbHMuaXNEZWZhdWx0LCB0cnVlKSxcbiAgICAgIF07XG4gICAgICBpZiAocHJvamVjdENvbHVtbikge1xuICAgICAgICBzY29wZUNvbmRpdGlvbnMucHVzaChlcShwcm9qZWN0Q29sdW1uLCBwcm9qZWN0KSk7XG4gICAgICB9XG5cbiAgICAgIC8vIExvY2sgZXhpc3RpbmcgZGVmYXVsdHMgd2l0aCBGT1IgVVBEQVRFIHRvIHByZXZlbnQgY29uY3VycmVudCBzZXREZWZhdWx0IHJhY2VzXG4gICAgICBhd2FpdCB0eC5leGVjdXRlKFxuICAgICAgICBzcWxgU0VMRUNUIGlkIEZST00gJHt0aGlzLnNjaGVtYX1cbiAgICAgICAgICAgIFdIRVJFICR7b3JnQ29sdW1ufSA9ICR7b3JnfVxuICAgICAgICAgICAgICBBTkQgJHt0aGlzLmNvbHMuaXNEZWZhdWx0fSA9IHRydWVcbiAgICAgICAgICAgICR7cHJvamVjdENvbHVtbiA/IHNxbGBBTkQgJHtwcm9qZWN0Q29sdW1ufSA9ICR7cHJvamVjdH1gIDogc3FsYGB9XG4gICAgICAgICAgICBGT1IgVVBEQVRFYCxcbiAgICAgICk7XG5cbiAgICAgIC8vIE1hcmsgYWxsIGVudGl0aWVzIGluIHNjb3BlIGFzIG5vbi1kZWZhdWx0XG4gICAgICBhd2FpdCB0eFxuICAgICAgICAudXBkYXRlKHRoaXMuc2NoZW1hKVxuICAgICAgICAuc2V0KHtcbiAgICAgICAgICBpc0RlZmF1bHQ6IGZhbHNlLFxuICAgICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgIC53aGVyZShhbmQoLi4uc2NvcGVDb25kaXRpb25zKSk7XG5cbiAgICAgIC8vIFNldCB0aGUgc3BlY2lmaWVkIGVudGl0eSBhcyBkZWZhdWx0LiBHdWFyZCBhZ2FpbnN0IHByb21vdGluZyBhXG4gICAgICAvLyBzb2Z0LWRlbGV0ZWQgcm93IChpc0FjdGl2ZSA9IHRydWUpIOKAlCBhIGRlbGV0ZWQgZW50aXR5IG11c3QgbmV2ZXIgYmVjb21lXG4gICAgICAvLyB0aGUgYWN0aXZlIGRlZmF1bHQg4oCUIGFuZCBwaW4gdGhlIGlkIHdpdGggdGhlIHNhbWUgbG93ZXJjYXNlZFxuICAgICAgLy8gZXhhY3RJZENvbmRpdGlvbiB0aGUgbXV0YXRpb24gcGF0aHMgdXNlICh0aGUgcmF3IGBlcShjb2xzLmlkLCBpZClgIGhlcmVcbiAgICAgIC8vIHNraXBwZWQgdGhlIGxvd2VyLWNhc2luZyB0aGF0IGBidWlsZElkRmlsdGVyYC9gd3JpdGVDb25kaXRpb25zYCBhcHBseSxcbiAgICAgIC8vIHNvIGEgbWl4ZWQtY2FzZSBpZCBjb3VsZCBtaXNzIGl0cyByb3cpLiBBIG5vbi1tYXRjaCDihpIgTm90Rm91bmRFcnJvciBiZWxvdy5cbiAgICAgIGNvbnN0IFt1cGRhdGVkXSA9IGF3YWl0IHR4XG4gICAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAgIC5zZXQoe1xuICAgICAgICAgIGlzRGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgICAud2hlcmUoXG4gICAgICAgICAgYW5kKFxuICAgICAgICAgICAgdGhpcy5leGFjdElkQ29uZGl0aW9uKGlkKSxcbiAgICAgICAgICAgIGVxKG9yZ0NvbHVtbiwgb3JnKSxcbiAgICAgICAgICAgIGVxKHRoaXMuY29scy5pc0FjdGl2ZSwgdHJ1ZSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKVxuICAgICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKTtcblxuICAgICAgaWYgKCF1cGRhdGVkKSB7XG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEVycm9yKGBFbnRpdHkgd2l0aCBpZCAke2lkfSBub3QgZm91bmRgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVwZGF0ZWQ7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIG11bHRpcGxlIGVudGl0aWVzIG1hdGNoaW5nIGZpbHRlclxuICAgKi9cbiAgYXN5bmMgdXBkYXRlTWFueShcbiAgICBmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sXG4gICAgZGF0YTogUGFydGlhbDxUVXBkYXRlPixcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIHVzZXJJZDogc3RyaW5nLFxuICApOiBQcm9taXNlPFRFbnRpdHlbXT4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkKTtcbiAgICAvLyBPd24tb3JnIHdyaXRlLXBpbjogYnVpbGRDb25kaXRpb25zIGFsc28gbWF0Y2hlcyBzeXN0ZW0vb3RoZXItb3JnIFBVQkxJQ1xuICAgIC8vIHJvd3MsIHNvIHdpdGhvdXQgdGhlIHN0cmljdCBvcmdJZCBwaW4gYSBmaWx0ZXItYmFzZWQgdXBkYXRlIGNvdWxkIG11dGF0ZVxuICAgIC8vIHNoYXJlZCAob3IgYW5vdGhlciB0ZW5hbnQncyBwdWJsaWMpIHJlY29yZHMuIE1pcnJvciB1cGRhdGUvZGVsZXRlL1xuICAgIC8vIGJ1bGtEZWxldGUuIChTZWUgd3JpdGVDb25kaXRpb25zLikgQW4gb3JnSWQtbGVzcyAoc3lzYWRtaW4pIGNvbnRleHQga2VlcHNcbiAgICAvLyBmdWxsIGFjY2Vzcy5cbiAgICBpZiAob3JnSWQpIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLmdldE9yZ0NvbHVtbigpLCBvcmdJZCkpO1xuXG4gICAgLy8gU2NydWIgYSBjYWxsZXItc3VwcGxpZWQgb3JnSWQgKHNlZSB1cGRhdGUoKSkgc28gYSBmaWx0ZXItYmFzZWQgdXBkYXRlIGNhbid0XG4gICAgLy8gcmUtaG9tZSByb3dzIGludG8gYW5vdGhlciB0ZW5hbnQuXG4gICAgY29uc3Qgc2FmZURhdGEgPSB0aGlzLmVuZm9yY2VPcmdJZChkYXRhKTtcblxuICAgIHJldHVybiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgIC5zZXQoe1xuICAgICAgICAuLi5zYWZlRGF0YSxcbiAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgIH0gYXMgYW55KVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFRoZSBgdmlzaWJpbGl0eWAgcHJlZGljYXRlIGZvciBhIGJ1bGsgc29mdC1kZWxldGUsIG1pcnJvcmluZ1xuICAgKiBgcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2Vzc2AgcnVuZyBmb3IgcnVuZyBzbyBidWxrIGFuZCBzaW5nbGUtcm93IGRlbGV0ZVxuICAgKiBjYW4gbmV2ZXIgZGlzYWdyZWUgYWJvdXQgd2hhdCBhIGNhbGxlciBtYXkgcmVtb3ZlLlxuICAgKlxuICAgKiBSZXR1cm5zIG5vIGNvbmRpdGlvbiBhdCBhbGwgZm9yIGEgc3lzdGVtIGFkbWluLCBvciBmb3IgYW4gZW50aXR5IHdpdGggbm9cbiAgICogYHZpc2liaWxpdHlgIGNvbHVtbiAobm90aGluZyB0byBnYXRlIG9uKS5cbiAgICovXG4gIHByaXZhdGUgdmlzaWJpbGl0eURlbGV0ZUNvbmRpdGlvbnMoXG4gICAgYWNjZXNzOiB7IGlzU3lzdGVtQWRtaW46IGJvb2xlYW47IGNhblB1Ymxpc2g6IGJvb2xlYW4gfSB8IHVuZGVmaW5lZCxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgICBhY2Nlc3NDb2w/OiBBbnlDb2x1bW4sXG4gICAgY3JlYXRlZEJ5Q29sPzogQW55Q29sdW1uLFxuICApOiBTUUxbXSB7XG4gICAgaWYgKCFhY2Nlc3NDb2wpIHJldHVybiBbXTtcbiAgICBpZiAoIWFjY2VzcyB8fCBhY2Nlc3MuaXNTeXN0ZW1BZG1pbikgcmV0dXJuIFtdO1xuXG4gICAgY29uc3QgcnVuZ3M6IFNRTFtdID0gW2VxKGFjY2Vzc0NvbCwgJ29yZycpXTtcbiAgICAvLyBgcHJpdmF0ZWAgaXMgYXV0aG9yLW9ubHkuIFdpdGggbm8gYXV0aG9yIGNvbHVtbiBvciBubyBjYWxsZXIgaWRlbnRpdHkgd2VcbiAgICAvLyBjYW5ub3QgcHJvdmUgYXV0aG9yc2hpcCwgc28gdGhlIHJ1bmcgaXMgc2ltcGx5IG5vdCBvZmZlcmVkIChmYWlsIGNsb3NlZClcbiAgICAvLyByYXRoZXIgdGhhbiBtYXRjaGluZyBldmVyeSBwcml2YXRlIHJvdy5cbiAgICBpZiAoY3JlYXRlZEJ5Q29sICYmIHVzZXJJZCkge1xuICAgICAgcnVuZ3MucHVzaChhbmQoZXEoYWNjZXNzQ29sLCAncHJpdmF0ZScpLCBlcShjcmVhdGVkQnlDb2wsIHVzZXJJZCkpIGFzIFNRTCk7XG4gICAgfVxuICAgIGlmIChhY2Nlc3MuY2FuUHVibGlzaCkgcnVuZ3MucHVzaChlcShhY2Nlc3NDb2wsICdwdWJsaWMnKSk7XG5cbiAgICByZXR1cm4gW29yKC4uLnJ1bmdzKSBhcyBTUUxdO1xuICB9XG5cbiAgLyoqXG4gICAqIFNvZnQtZGVsZXRlIG11bHRpcGxlIGVudGl0aWVzIGJ5IElEcyBpbiBhIHNpbmdsZSBiYXRjaCBvcGVyYXRpb24uXG4gICAqL1xuICBhc3luYyBidWxrRGVsZXRlKFxuICAgIGlkczogc3RyaW5nW10sXG4gICAgb3JnSWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgICAvKipcbiAgICAgKiBUaGUgY2FsbGVyJ3MgYXV0aG9yaXR5IG9uIHRoZSB0aHJlZS1ydW5nIGB2aXNpYmlsaXR5YCBsYWRkZXIuIE9taXQgKG9yXG4gICAgICogcGFzcyBgaXNTeXN0ZW1BZG1pbjogdHJ1ZWApIGZvciBhbiB1bnJlc3RyaWN0ZWQgZGVsZXRlLlxuICAgICAqXG4gICAgICogVGhpcyB1c2VkIHRvIGJlIGEgYHJlc3RyaWN0VG9Qcml2YXRlYCBib29sZWFuIHRoYXQgbmFycm93ZWQgdG9cbiAgICAgKiBgdmlzaWJpbGl0eSA9ICdwcml2YXRlJ2AuIFRoYXQgZW5jb2RlZCB0aGUgT0xEIHR3by1zdGF0ZSBtb2RlbDogc2luY2VcbiAgICAgKiBgcmVzb2x2ZVZpc2liaWxpdHlgIGRlZmF1bHRzIHBpcGVsaW5lcyBhbmQgcGx1Z2lucyB0byBgb3JnYCwgYW5kXG4gICAgICogc2luZ2xlLXJvdyBkZWxldGUgYWxsb3dzIGFuIGBvcmdgIHJvdyB3aXRoIHBsYWluIGA6d3JpdGVgLCBidWxrIGRlbGV0ZVxuICAgICAqIDQwMydkIHRoZSBub3JtYWwgY2FzZSDigJQgYW4gb3JnIGFkbWluIGNvdWxkIGRlbGV0ZSBhIHBpcGVsaW5lIG9uZSBhdCBhXG4gICAgICogdGltZSBidXQgbm90IGluIGJ1bGsuIFRoZSBydW5ncyBlbmZvcmNlZCBoZXJlIG1pcnJvclxuICAgICAqIGByZXF1aXJlVmlzaWJpbGl0eVdyaXRlQWNjZXNzYCBleGFjdGx5OlxuICAgICAqICAgLSBgcHJpdmF0ZWAg4oaSIGF1dGhvciBvbmx5IChgY3JlYXRlZEJ5ID09PSB1c2VySWRgKVxuICAgICAqICAgLSBgb3JnYCAgICAg4oaSIGFueSBtZW1iZXIgb2YgdGhlIG9yZyAocGxhaW4gYDp3cml0ZWApXG4gICAgICogICAtIGBwdWJsaWNgICDihpIgcmVxdWlyZXMgdGhlIGVudGl0eSdzIHB1Ymxpc2ggcGVybWlzc2lvblxuICAgICAqL1xuICAgIGFjY2Vzcz86IHsgaXNTeXN0ZW1BZG1pbjogYm9vbGVhbjsgY2FuUHVibGlzaDogYm9vbGVhbiB9LFxuICApOiBQcm9taXNlPFRFbnRpdHlbXT4ge1xuICAgIGlmIChpZHMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IHVzZXIgPSB1c2VySWQgfHwgJ3N5c3RlbSc7XG4gICAgLy8gT3duZXItc2NvcGUgdGhlIGJ1bGsgc29mdC1kZWxldGU6IGJ1aWxkQ29uZGl0aW9ucyBhbHNvIG1hdGNoZXMgc3lzdGVtL290aGVyXG4gICAgLy8gLW9yZyBQVUJMSUMgcm93cywgc28gd2l0aG91dCB0aGUgc3RyaWN0IG9yZ0lkIHBpbiBhIHRlbmFudCBjb3VsZCBkZWxldGVcbiAgICAvLyBzaGFyZWQgcmVjb3JkcyBieSBpZC4gKFNlZSB3cml0ZUNvbmRpdGlvbnMuKVxuICAgIGNvbnN0IGFjY2Vzc0NvbCA9IHRoaXMuY29scy52aXNpYmlsaXR5O1xuICAgIGNvbnN0IGNyZWF0ZWRCeUNvbCA9IHRoaXMuY29scy5jcmVhdGVkQnk7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IFtcbiAgICAgIGluQXJyYXkodGhpcy5jb2xzLmlkLCBpZHMpLFxuICAgICAgLi4udGhpcy5idWlsZENvbmRpdGlvbnMoe30gYXMgUGFydGlhbDxURmlsdGVyPiwgb3JnSWQpLFxuICAgICAgLy8gVGVuYW50IGNvbHVtbiAoZ2V0T3JnQ29sdW1uLCBhc3NlcnRlZCBub24tbnVsbCkg4oCUIGNvbnNpc3RlbnQgd2l0aFxuICAgICAgLy8gd3JpdGVDb25kaXRpb25zOyBubyBzaWxlbnQgZmFpbC1vcGVuIHdoZW4gdGhlIHByb3BlcnR5IGlzIGFic2VudC5cbiAgICAgIC4uLihvcmdJZCA/IFtlcSh0aGlzLmdldE9yZ0NvbHVtbigpLCBvcmdJZCldIDogW10pLFxuICAgICAgLi4udGhpcy52aXNpYmlsaXR5RGVsZXRlQ29uZGl0aW9ucyhhY2Nlc3MsIHVzZXJJZCwgYWNjZXNzQ29sLCBjcmVhdGVkQnlDb2wpLFxuICAgIF07XG5cbiAgICBjb25zdCBkZWxldGVkID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHtcbiAgICAgICAgaXNBY3RpdmU6IGZhbHNlLFxuICAgICAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VyLFxuICAgICAgICBkZWxldGVkQXQ6IG5vdyxcbiAgICAgICAgZGVsZXRlZEJ5OiB1c2VyLFxuICAgICAgICAvLyBTdGFtcCB0aGUgcHVyZ2UgZGVhZGxpbmUgc28gdGhlIHJldGVudGlvbiBzd2VlcCBjYW4gaGFyZC1kZWxldGUgbGF0ZXIuXG4gICAgICAgIC4uLnRoaXMucHVyZ2VBZnRlclN0YW1wKG5vdyksXG4gICAgICB9IGFzIGFueSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGRlbGV0ZWQubWFwKGVudGl0eSA9PlxuICAgICAgICB0aGlzLm9uQWZ0ZXJEZWxldGUoZW50aXR5LmlkLCBlbnRpdHksIHVzZXJJZCkuY2F0Y2goZXJyID0+XG4gICAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgcmV0dXJuIGRlbGV0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmVzdG9yZSBhIHNvZnQtZGVsZXRlZCAodG9tYnN0b25lZCkgZW50aXR5OiBjbGVhciBgaXNBY3RpdmVgL2BkZWxldGVkQXRgL1xuICAgKiBgZGVsZXRlZEJ5YC9gcHVyZ2VBZnRlcmAgc28gaXQgcmVhcHBlYXJzIGluIG5vcm1hbCByZWFkcy5cbiAgICpcbiAgICogTWF0Y2hlcyBPTkxZIGEgZ2VudWluZSB0b21ic3RvbmUg4oCUIGBpc0FjdGl2ZSA9IGZhbHNlYCBBTkQgYGRlbGV0ZWRBdCBJUyBOT1RcbiAgICogTlVMTGAg4oCUIHNvIGEgbWVyZWx5ICpkZWFjdGl2YXRlZCogcm93IChpc0FjdGl2ZT1mYWxzZSwgbm8gZGVsZXRlZEF0KSBpcyBuZXZlclxuICAgKiBzaWxlbnRseSBcInJlc3RvcmVkXCIuIFBpbm5lZCB0byB0aGUgY2FsbGVyJ3Mgb3duIG9yZyAob3JnSWQtbGVzcyBzeXNhZG1pblxuICAgKiBjb250ZXh0IHNwYW5zIG9yZ3MsIG1hdGNoaW5nIGRlbGV0ZS91cGRhdGUpLiBSZXR1cm5zIG51bGwgd2hlbiB0aGVyZSBpcyBub1xuICAgKiBzdWNoIHRvbWJzdG9uZSAoYWxyZWFkeSBhY3RpdmUsIHB1cmdlZCwgb3IgdW5rbm93bikgc28gdGhlIHJvdXRlIGNhbiA0MDQuXG4gICAqIEEgdW5pcXVlLWtleSBjb2xsaXNpb24gKGEgbGl2ZSByb3cgYWxyZWFkeSBob2xkcyB0aGUga2V5KSBzdXJmYWNlcyBhcyB0aGVcbiAgICogZHJpdmVyJ3MgdW5pcXVlLXZpb2xhdGlvbiBmb3IgdGhlIHJvdXRlIHRvIG1hcCB0byA0MDkg4oCUIGluIHByYWN0aWNlIHRoZVxuICAgKiB0b21ic3RvbmUgSVMgdGhlIGtleSBob2xkZXIsIHNvIHRoaXMgaXMgZGVmZW5zaXZlLlxuICAgKi9cbiAgLyoqIENvbmRpdGlvbnMgbWF0Y2hpbmcgYSBHRU5VSU5FIHRvbWJzdG9uZSAoYGlzQWN0aXZlPWZhbHNlYCBBTkQgYGRlbGV0ZWRBdCBJU1xuICAgKiAgTk9UIE5VTExgKSwgb3B0aW9uYWxseSBwaW5uZWQgdG8gYGlkYCBhbmQvb3IgYG9yZ0lkYC4gU2luZ2xlIHNvdXJjZSBvZiB0cnV0aFxuICAgKiAgZm9yIHJlc3RvcmUvZmluZERlbGV0ZWRCeUlkL2ZpbmREZWxldGVkIHNvIHRoZSBcIndoYXQgaXMgYSB0b21ic3RvbmVcIiBydWxlXG4gICAqICBsaXZlcyBpbiBvbmUgcGxhY2UuICovXG4gIHByaXZhdGUgdG9tYnN0b25lQ29uZGl0aW9ucyhvcmdJZD86IHN0cmluZywgaWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXG4gICAgICBlcSh0aGlzLmNvbHMuaXNBY3RpdmUsIGZhbHNlKSxcbiAgICAgIHNxbGAke3RoaXMuY29scy5kZWxldGVkQXR9IElTIE5PVCBOVUxMYCxcbiAgICAgIC4uLnRoaXMudG9tYnN0b25lVmlzaWJpbGl0eUNvbmRpdGlvbnMoKSxcbiAgICBdO1xuICAgIGlmIChpZCAhPT0gdW5kZWZpbmVkKSBjb25kaXRpb25zLnVuc2hpZnQodGhpcy5leGFjdElkQ29uZGl0aW9uKGlkKSk7XG4gICAgaWYgKG9yZ0lkKSBjb25kaXRpb25zLnB1c2goZXEodGhpcy5nZXRPcmdDb2x1bW4oKSwgb3JnSWQpKTtcbiAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYHByaXZhdGVgIHJ1bmcsIGZvciBUT01CU1RPTkUgcmVhZHMgYW5kIHJlc3RvcmUuXG4gICAqXG4gICAqIERlbGV0aW5nIGEgcm93IGRvZXMgbm90IGRlY2xhc3NpZnkgaXQuIFRoZXNlIGNvbmRpdGlvbnMgY2FycmllZCBvbmx5XG4gICAqIGBpc0FjdGl2ZT1mYWxzZSArIGRlbGV0ZWRBdCBJUyBOT1QgTlVMTCArIG9yZ19pZCA9IE9gLCBzbyB0aGUgXCJyZWNlbnRseVxuICAgKiBkZWxldGVkXCIgbGlzdCBoYW5kZWQgZXZlcnkgbWVtYmVyIG9mIGFuIG9yZyB0aGUgdG9tYnN0b25lcyBvZiBldmVyeW9uZVxuICAgKiBlbHNlJ3MgUFJJVkFURSBwaXBlbGluZXMsIHBsdWdpbnMgYW5kIHRlbXBsYXRlcyDigJQgcm93cyB0aGUgdmVyeSBzYW1lIG1lbWJlclxuICAgKiBjb3VsZCBub3QgcmVhZCBvbmUgc2Vjb25kIGJlZm9yZSB0aGV5IHdlcmUgZGVsZXRlZC4gYHJlc3RvcmVgIHNoYXJlZCB0aGVcbiAgICogY2xhdXNlLCBzbyB0aGV5IGNvdWxkIGFsc28gYnJpbmcgb25lIGJhY2suXG4gICAqXG4gICAqIE1pcnJvcnMgdGhlIGxpdmUgcmVhZCBsYWRkZXIgKGB2aXNpYmlsaXR5IDw+ICdwcml2YXRlJyBPUiBjcmVhdGVkX2J5ID0gVmApXG4gICAqIHJhdGhlciB0aGFuIHRoZSBkZWxldGUgbGFkZGVyOiB0aGlzIGdhdGVzIHdobyBtYXkgU0VFIGEgdG9tYnN0b25lLCBhbmQgYVxuICAgKiB0b21ic3RvbmUgc2hvdWxkIGJlIHZpc2libGUgdG8gZXhhY3RseSB3aG9ldmVyIGNvdWxkIHNlZSB0aGUgcm93LiBBXG4gICAqIHN1cGVyLWFkbWluIGFkbWluaXN0ZXJzIHRoZSB3aG9sZSBjYXRhbG9nLCBzbyB0aGUgcnVuZyBsaWZ0cyBmb3IgdGhlbS5cbiAgICpcbiAgICogRmFpbHMgQ0xPU0VEOiB3aXRoIG5vIGF1dGhvciBjb2x1bW4gb3Igbm8gdmlld2VyIChiYWNrZ3JvdW5kIGpvYnMsIHRoZVxuICAgKiByZXRlbnRpb24gc3dlZXApIHRoZSBwcml2YXRlIHJ1bmcgaXMgbm90IG9mZmVyZWQgYXQgYWxsIHJhdGhlciB0aGFuXG4gICAqIG1hdGNoaW5nIGV2ZXJ5IHByaXZhdGUgcm93LiBgcHVyZ2VFeHBpcmVkYCBkZWxpYmVyYXRlbHkgZG9lcyBub3QgdXNlIHRoaXMg4oCUXG4gICAqIGl0IHJ1bnMgb3JnLXdpZGUgdW5kZXIgYSBzeXNhZG1pbiBzY29wZSBhbmQgbXVzdCByZWFjaCBldmVyeSB0b21ic3RvbmUuXG4gICAqL1xuICBwcml2YXRlIHRvbWJzdG9uZVZpc2liaWxpdHlDb25kaXRpb25zKCk6IFNRTFtdIHtcbiAgICBjb25zdCBhY2Nlc3NDb2wgPSB0aGlzLmNvbHMudmlzaWJpbGl0eTtcbiAgICBpZiAoIWFjY2Vzc0NvbCkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IGN0eCA9IGdldFRlbmFudENvbnRleHQoKTtcbiAgICBpZiAoY3R4Py5pc1N1cGVyQWRtaW4pIHJldHVybiBbXTtcblxuICAgIGNvbnN0IGNyZWF0ZWRCeUNvbCA9IHRoaXMuY29scy5jcmVhdGVkQnk7XG4gICAgY29uc3Qgdmlld2VyID0gY3R4Py51c2VySWQ7XG4gICAgY29uc3QgcnVuZ3M6IFNRTFtdID0gW3NxbGAke2FjY2Vzc0NvbH0gPD4gJ3ByaXZhdGUnYF07XG4gICAgaWYgKGNyZWF0ZWRCeUNvbCAmJiB2aWV3ZXIpIHJ1bmdzLnB1c2goZXEoY3JlYXRlZEJ5Q29sLCB2aWV3ZXIpKTtcbiAgICByZXR1cm4gW29yKC4uLnJ1bmdzKSBhcyBTUUxdO1xuICB9XG5cbiAgYXN5bmMgcmVzdG9yZShpZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBpZiAoIXRoaXMuY29scy5kZWxldGVkQXQpIHJldHVybiBudWxsOyAvLyBlbnRpdHkgaGFzIG5vIHNvZnQtZGVsZXRlIGxpZmVjeWNsZVxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLnRvbWJzdG9uZUNvbmRpdGlvbnMob3JnSWQsIGlkKTtcblxuICAgIGNvbnN0IFtyZXN0b3JlZF0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgIC5zZXQoe1xuICAgICAgICBpc0FjdGl2ZTogdHJ1ZSxcbiAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgICAgZGVsZXRlZEF0OiBudWxsLFxuICAgICAgICBkZWxldGVkQnk6IG51bGwsXG4gICAgICAgIC4uLih0aGlzLmNvbHMucHVyZ2VBZnRlciA/IHsgcHVyZ2VBZnRlcjogbnVsbCB9IDoge30pLFxuICAgICAgfSBhcyBhbnkpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpO1xuXG4gICAgaWYgKHJlc3RvcmVkKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLm9uQWZ0ZXJSZXN0b3JlKGlkLCByZXN0b3JlZCwgdXNlcklkKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignTGlmZWN5Y2xlIGhvb2sgZmFpbGVkJywgeyBlcnJvcjogU3RyaW5nKGVycikgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3RvcmVkIHx8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBhIHNvZnQtZGVsZXRlZCBlbnRpdHkgYnkgaWQgKHRoZSBpbnZlcnNlIG9mIHRoZSBkZWZhdWx0IGBpc0FjdGl2ZT10cnVlYFxuICAgKiByZWFkcykg4oCUIHVzZWQgYnkgcmVzdG9yZSByb3V0ZXMgdG8gbG9hZCB0aGUgdG9tYnN0b25lIGZvciBhY2Nlc3MtY29udHJvbFxuICAgKiBnYXRpbmcgYmVmb3JlIHJlc3RvcmluZy4gUmV0dXJucyBudWxsIHVubGVzcyB0aGUgcm93IGV4aXN0cyBBTkQgaXMgYSBnZW51aW5lXG4gICAqIHRvbWJzdG9uZSAoYGlzQWN0aXZlPWZhbHNlYCArIGBkZWxldGVkQXQgSVMgTk9UIE5VTExgKS5cbiAgICovXG4gIGFzeW5jIGZpbmREZWxldGVkQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBpZiAoIXRoaXMuY29scy5kZWxldGVkQXQpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLnRvbWJzdG9uZUNvbmRpdGlvbnMob3JnSWQsIGlkKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCgpXG4gICAgICAuZnJvbSh0aGlzLnNjaGVtYSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAubGltaXQoMSkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICByZXR1cm4gcmVzdWx0c1swXSB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3QgYW4gb3JnJ3Mgc29mdC1kZWxldGVkIHRvbWJzdG9uZXMgKGBpc0FjdGl2ZT1mYWxzZWAgKyBgZGVsZXRlZEF0IElTIE5PVFxuICAgKiBOVUxMYCksIG1vc3QtcmVjZW50bHktZGVsZXRlZCBmaXJzdCDigJQgcG93ZXJzIHRoZSBcInJlY2VudGx5IGRlbGV0ZWRcIiByZXN0b3JlXG4gICAqIFVJLiBSZXR1cm5zIGBbXWAgZm9yIGVudGl0aWVzIHdpdGhvdXQgYSBzb2Z0LWRlbGV0ZSBsaWZlY3ljbGUuIGBsaW1pdGAgaXNcbiAgICogY2xhbXBlZCB0byBbMSwgMjAwXSB0byBrZWVwIHRoZSByZXNwb25zZSBib3VuZGVkICh0aGUgcmV0ZW50aW9uIHN3ZWVwIGhhcmQtXG4gICAqIGRlbGV0ZXMgb2xkIHRvbWJzdG9uZXMgYW55d2F5LCBzbyB0aGlzIGlzIGEgc2hvcnQsIHNlbGYtbGltaXRpbmcgbGlzdCkuXG4gICAqL1xuICBhc3luYyBmaW5kRGVsZXRlZChcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIG9wdHM6IHsgbGltaXQ/OiBudW1iZXI7IG9mZnNldD86IG51bWJlciB9ID0ge30sXG4gICk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgaWYgKCF0aGlzLmNvbHMuZGVsZXRlZEF0KSByZXR1cm4gW107XG4gICAgY29uc3QgbGltaXQgPSBNYXRoLm1pbihNYXRoLm1heCgxLCBvcHRzLmxpbWl0ID8/IDUwKSwgMjAwKTtcbiAgICBjb25zdCBvZmZzZXQgPSBNYXRoLm1heCgwLCBvcHRzLm9mZnNldCA/PyAwKTtcblxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLnRvbWJzdG9uZUNvbmRpdGlvbnMob3JnSWQpO1xuXG4gICAgcmV0dXJuIHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAuc2VsZWN0KClcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5vcmRlckJ5KGRlc2ModGhpcy5jb2xzLmRlbGV0ZWRBdCEpKVxuICAgICAgLmxpbWl0KGxpbWl0KVxuICAgICAgLm9mZnNldChvZmZzZXQpXG4gICAgICAudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG4gIH1cblxuICAvKipcbiAgICogSGFyZC1kZWxldGUgYSBiYXRjaCBvZiB0b21ic3RvbmVzIHdob3NlIHB1cmdlIGRlYWRsaW5lIGhhcyBwYXNzZWRcbiAgICogKGBkZWxldGVkQXQgSVMgTk9UIE5VTEwgQU5EIHB1cmdlX2FmdGVyIDwgbm93YCkuIEJhdGNoZWQgKGBsaW1pdGApIHNvIGFcbiAgICogc3dlZXAgdGljayBzdGF5cyBib3VuZGVkOyB0aGUgcGVyLXNlcnZpY2Ugc3dlZXAgbG9vcHMgdW50aWwgYSB0aWNrIHJldHVybnNcbiAgICogYDwgbGltaXRgLiBSdW5zIGFjcm9zcyBBTEwgb3Jncywgc28gY2FsbGVycyBNVVNUIGludm9rZSBpdCBmcm9tIGEgc3lzYWRtaW5cbiAgICogc2NvcGUgKGBydW5Tb2Z0RGVsZXRlUHVyZ2VgIGVzdGFibGlzaGVzIG9uZSkuIGBvbkJlZm9yZVB1cmdlKGlkcywgdHgpYCB0ZWFyc1xuICAgKiBkb3duIGRlcGVuZGVudHMgbGFja2luZyBPTiBERUxFVEUgQ0FTQ0FERSBpbnNpZGUgdGhlIHNhbWUgdHg7IGBvbkFmdGVyUHVyZ2VgXG4gICAqIGhhbmRsZXMgZXh0ZXJuYWwgc2lkZS1lZmZlY3RzLlxuICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygcm93cyBwdXJnZWQuIE5vLW9wICgwKSBmb3IgZW50aXRpZXMgd2l0aG91dCB0aGUgY29sdW1ucy5cbiAgICovXG4gIGFzeW5jIHB1cmdlRXhwaXJlZChub3c6IERhdGUsIGxpbWl0ID0gNTAwKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAoIXRoaXMuY29scy5kZWxldGVkQXQgfHwgIXRoaXMuY29scy5wdXJnZUFmdGVyKSByZXR1cm4gMDtcblxuICAgIGNvbnN0IHB1cmdlZElkcyA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAgIGNvbnN0IGRvb21lZCA9IGF3YWl0IHR4XG4gICAgICAgIC8vIGBhcyBhbnlgOiBjb2xzLmlkIGlzIHRoZSBiYXNlIGBBbnlDb2x1bW5gLCB3aGljaCBkcml6emxlJ3MgdHlwZWRcbiAgICAgICAgLy8gc2VsZWN0LWZpZWxkIG1hcCBkb2Vzbid0IGFjY2VwdCBkaXJlY3RseSAoc2FtZSBmcmljdGlvbiB0aGUgYC5zZXQoKWBcbiAgICAgICAgLy8gY2FzdHMgZWxzZXdoZXJlIGluIHRoaXMgZmlsZSB3b3JrIGFyb3VuZCkuIFJlc3VsdCBpcyByZS10eXBlZCBiZWxvdy5cbiAgICAgICAgLnNlbGVjdCh7IGlkOiB0aGlzLmNvbHMuaWQgYXMgYW55IH0pXG4gICAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgICAud2hlcmUoYW5kKHNxbGAke3RoaXMuY29scy5kZWxldGVkQXR9IElTIE5PVCBOVUxMYCwgc3FsYCR7dGhpcy5jb2xzLnB1cmdlQWZ0ZXJ9IDwgJHtub3d9YCkpXG4gICAgICAgIC5saW1pdChsaW1pdClcbiAgICAgICAgLnRoZW4ociA9PiAociBhcyBBcnJheTx7IGlkOiB1bmtub3duIH0+KS5tYXAoZCA9PiBTdHJpbmcoZC5pZCkpKTtcblxuICAgICAgaWYgKGRvb21lZC5sZW5ndGggPT09IDApIHJldHVybiBbXTtcblxuICAgICAgLy8gRGVwZW5kZW50IHRlYXJkb3duIG11c3QgaGFwcGVuIGluc2lkZSB0aGUgc2FtZSB0eCBzbyBhIEZLLWJsb2NraW5nIGNoaWxkXG4gICAgICAvLyBjYW4ndCBzdHJhbmQgdGhlIHBhcmVudC4gQSB0aHJvdyBoZXJlIGFib3J0cyB0aGlzIGJhdGNoIChyZXRyaWVkIG5leHQgdGljaykuXG4gICAgICBhd2FpdCB0aGlzLm9uQmVmb3JlUHVyZ2UoZG9vbWVkLCB0eCk7XG5cbiAgICAgIGF3YWl0IHR4LmRlbGV0ZSh0aGlzLnNjaGVtYSkud2hlcmUoaW5BcnJheSh0aGlzLmNvbHMuaWQsIGRvb21lZCkpO1xuICAgICAgcmV0dXJuIGRvb21lZDtcbiAgICB9KTtcblxuICAgIGlmIChwdXJnZWRJZHMubGVuZ3RoID4gMCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5vbkFmdGVyUHVyZ2UocHVyZ2VkSWRzKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignTGlmZWN5Y2xlIGhvb2sgZmFpbGVkJywgeyBlcnJvcjogU3RyaW5nKGVycikgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHB1cmdlZElkcy5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogT24tZGVtYW5kIGhhcmQtZGVsZXRlIG9mIGEgU0lOR0xFIHRvbWJzdG9uZSBieSBpZCDigJQgdGhlIG1hbnVhbCBjb3VudGVycGFydFxuICAgKiB0byB0aGUgcmV0ZW50aW9uIHN3ZWVwJ3MgYHB1cmdlRXhwaXJlZGAuIFBlcm1hbmVudGx5IHJlbW92ZXMgdGhlIHJvdyBPTkxZXG4gICAqIHdoZW4gaXQgaXMgYSBnZW51aW5lIHRvbWJzdG9uZSAoYGlzQWN0aXZlPWZhbHNlYCArIGBkZWxldGVkQXQgSVMgTk9UIE5VTExgKSxcbiAgICogb3B0aW9uYWxseSBwaW5uZWQgdG8gYG9yZ0lkYCAoYW4gb3JnSWQtbGVzcyBzeXNhZG1pbiBjb250ZXh0IHNwYW5zIG9yZ3MsXG4gICAqIG1hdGNoaW5nIHJlc3RvcmUvZGVsZXRlKS4gUnVucyB0aGUgc2FtZSBgb25CZWZvcmVQdXJnZWAgZGVwZW5kZW50IHRlYXJkb3duXG4gICAqIGluc2lkZSB0aGUgdHggYW5kIHRoZSBzYW1lIGBvbkFmdGVyUHVyZ2VgIHNpZGUtZWZmZWN0cyBhcyB0aGUgc3dlZXAuXG4gICAqXG4gICAqIElnbm9yZXMgYHB1cmdlQWZ0ZXJgOiBhIG1hbnVhbCBwdXJnZSBmaW5hbGl6ZXMgYW4gYWxyZWFkeS1zb2Z0LWRlbGV0ZWQgaXRlbVxuICAgKiBpbW1lZGlhdGVseSByYXRoZXIgdGhhbiB3YWl0aW5nIGZvciB0aGUgcmV0ZW50aW9uIGRlYWRsaW5lLiBSZXR1cm5zIHRoZVxuICAgKiBwdXJnZWQgaWQsIG9yIG51bGwgd2hlbiB0aGVyZSBpcyBubyBzdWNoIHRvbWJzdG9uZSAoYWxyZWFkeSBhY3RpdmUsIHB1cmdlZCxcbiAgICogb3V0IG9mIHNjb3BlLCBvciB1bmtub3duKSBzbyB0aGUgcm91dGUgY2FuIDQwNC5cbiAgICovXG4gIGFzeW5jIHB1cmdlQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGlmICghdGhpcy5jb2xzLmRlbGV0ZWRBdCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMudG9tYnN0b25lQ29uZGl0aW9ucyhvcmdJZCwgaWQpO1xuXG4gICAgY29uc3QgcHVyZ2VkSWQgPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgICBjb25zdCBbZG9vbWVkXSA9IGF3YWl0IHR4XG4gICAgICAgIC8vIGBhcyBhbnlgOiBjb2xzLmlkIGlzIHRoZSBiYXNlIGBBbnlDb2x1bW5gLCB3aGljaCBkcml6emxlJ3MgdHlwZWRcbiAgICAgICAgLy8gc2VsZWN0LWZpZWxkIG1hcCBkb2Vzbid0IGFjY2VwdCBkaXJlY3RseSAoc2FtZSBmcmljdGlvbiBlbHNld2hlcmUpLlxuICAgICAgICAuc2VsZWN0KHsgaWQ6IHRoaXMuY29scy5pZCBhcyBhbnkgfSlcbiAgICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAgIC5saW1pdCgxKVxuICAgICAgICAudGhlbihyID0+IChyIGFzIEFycmF5PHsgaWQ6IHVua25vd24gfT4pLm1hcChkID0+IFN0cmluZyhkLmlkKSkpO1xuXG4gICAgICBpZiAoIWRvb21lZCkgcmV0dXJuIG51bGw7XG5cbiAgICAgIC8vIERlcGVuZGVudCB0ZWFyZG93biBpbiB0aGUgc2FtZSB0eCAoRkstYmxvY2tpbmcgY2hpbGRyZW4gY2FuJ3Qgc3RyYW5kXG4gICAgICAvLyB0aGUgcGFyZW50KSDigJQgaWRlbnRpY2FsIHRvIHRoZSBzd2VlcCdzIHBlci1iYXRjaCBwYXRoLlxuICAgICAgYXdhaXQgdGhpcy5vbkJlZm9yZVB1cmdlKFtkb29tZWRdLCB0eCk7XG4gICAgICBhd2FpdCB0eC5kZWxldGUodGhpcy5zY2hlbWEpLndoZXJlKGluQXJyYXkodGhpcy5jb2xzLmlkLCBbZG9vbWVkXSkpO1xuICAgICAgcmV0dXJuIGRvb21lZDtcbiAgICB9KTtcblxuICAgIGlmIChwdXJnZWRJZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5vbkFmdGVyUHVyZ2UoW3B1cmdlZElkXSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwdXJnZWRJZDtcbiAgfVxufVxuIl19
930
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J1ZC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9jcnVkLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNySixPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBR2pHLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUc5Rjs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUksSUFBYTtJQUMxQyxPQUFPLElBQVcsQ0FBQztBQUNyQixDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBYTtJQUN4QyxPQUFPLElBQTJCLENBQUM7QUFDckMsQ0FBQztBQXdFRCxxRkFBcUY7QUFDckYsTUFBTSxlQUFlLEdBQUcsaUJBQWlCLENBQUM7QUFFMUM7Ozs7O0dBS0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxRQUF1QixFQUFFLEVBQVU7SUFDdkQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDbkYsQ0FBQztBQUVELCtFQUErRTtBQUMvRSxTQUFTLFlBQVksQ0FBQyxNQUFjO0lBQ2xDLElBQUksQ0FBQztRQUNILE1BQU0s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QztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IENvbmZsaWN0RXJyb3IsIE5vdEZvdW5kRXJyb3IsIGNyZWF0ZUxvZ2dlciwgREVGQVVMVF9QQUdFX0xJTUlULCBNQVhfUEFHRV9MSU1JVCwgU1lTVEVNX0FDVE9SX0lELCBlbnZJbnQgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBTUUwsIGVxLCBhbmQsIG9yLCBhc2MsIGRlc2MsIHNxbCwgaW5BcnJheSwgaXNOdWxsLCBnZXRUYWJsZUNvbHVtbnMgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5pbXBvcnQgdHlwZSB7IFBnVGFibGUgfSBmcm9tICdkcml6emxlLW9ybS9wZy1jb3JlJztcbmltcG9ydCB7IHdpdGhUZW5hbnRUeCwgcnVuV2l0aFRlbmFudENvbnRleHQsIGdldFRlbmFudENvbnRleHQgfSBmcm9tICcuLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuXG4vKipcbiAqIENhc3QgRHJpenpsZSBxdWVyeSByZXN1bHRzIHRvIGEgdHlwZWQgYXJyYXkuXG4gKiBEcml6emxlJ3MgZ2VuZXJpYyByZXR1cm4gdHlwZSAoYFBnU2VsZWN0QmFzZTwuLi4+YCkgZG9lc24ndCBuYXJyb3cgdG8gb3VyXG4gKiBlbnRpdHkgZ2VuZXJpY3MsIHNvIGFuIGV4cGxpY2l0IGNhc3QgaXMgbmVlZGVkLiBDZW50cmFsaXNlZCBoZXJlIHNvIGV2ZXJ5XG4gKiBjYWxsLXNpdGUgc3RheXMgb25lLWxpbmVyIGNsZWFuIGFuZCB0aGUgY2FzdCBpcyBkb2N1bWVudGVkIGluIG9uZSBwbGFjZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXp6bGVSb3dzPFQ+KHJvd3M6IHVua25vd24pOiBUW10ge1xuICByZXR1cm4gcm93cyBhcyBUW107XG59XG5cbi8qKiBDYXN0IGEgRHJpenpsZSBhZ2dyZWdhdGUgcmVzdWx0IHRvIGV4dHJhY3QgYFt7IGNvdW50OiBudW1iZXIgfV1gLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXp6bGVDb3VudChyb3dzOiB1bmtub3duKTogW3sgY291bnQ6IG51bWJlciB9XSB7XG4gIHJldHVybiByb3dzIGFzIFt7IGNvdW50OiBudW1iZXIgfV07XG59XG5cbi8qKiBUaGUgRHJpenpsZSB0cmFuc2FjdGlvbiBvYmplY3QgaGFuZGVkIHRvIGB3aXRoVGVuYW50VHhgIGNhbGxiYWNrcy4gUGFzc2VkIHRvXG4gKiAgYG9uQmVmb3JlUHVyZ2VgIHNvIGEgc3ViY2xhc3MncyBkZXBlbmRlbnQgdGVhcmRvd24gcnVucyBpbiB0aGUgU0FNRSBwdXJnZVxuICogIHRyYW5zYWN0aW9uIChhdG9taWMgd2l0aCB0aGUgcGFyZW50IERFTEVURSksIG5vdCBhIGZyZXNoIGNvbm5lY3Rpb24uICovXG5leHBvcnQgdHlwZSBDcnVkVHggPSBQYXJhbWV0ZXJzPFBhcmFtZXRlcnM8dHlwZW9mIHdpdGhUZW5hbnRUeD5bMF0+WzBdO1xuXG4vKipcbiAqIEJhc2UgaW50ZXJmYWNlIGZvciBlbnRpdGllcyB3aXRoIGNvbW1vbiBmaWVsZHNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCYXNlRW50aXR5IHtcbiAgaWQ6IHN0cmluZztcbiAgb3JnSWQ6IHN0cmluZztcbiAgaXNEZWZhdWx0OiBib29sZWFuO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIHVwZGF0ZWRBdDogRGF0ZTtcbiAgY3JlYXRlZEJ5OiBzdHJpbmc7XG4gIHVwZGF0ZWRCeTogc3RyaW5nO1xuICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xufVxuXG4vKipcbiAqIFBhZ2luYXRpb24gYW5kIHNvcnRpbmcgb3B0aW9uc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1ZXJ5T3B0aW9ucyB7XG4gIGxpbWl0PzogbnVtYmVyO1xuICBvZmZzZXQ/OiBudW1iZXI7XG4gIHNvcnRCeT86IHN0cmluZztcbiAgc29ydE9yZGVyPzogJ2FzYycgfCAnZGVzYyc7XG4gIC8qKiBXaGVuIHRydWUsIHJ1bnMgYSBzZXBhcmF0ZSBDT1VOVCgqKSBxdWVyeSB0byBpbmNsdWRlIGV4YWN0IHRvdGFsLiBEZWZhdWx0OiBmYWxzZS4gKi9cbiAgaW5jbHVkZVRvdGFsPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEtleXNldCBwYWdpbmF0aW9uOiB0aGUgb3BhcXVlIGBuZXh0Q3Vyc29yYCBvZiB0aGUgcHJldmlvdXMgcGFnZS4gQ29udGludWVzXG4gICAqIHN0cmljdGx5IGFmdGVyIHRoYXQgcm93IGluIChzb3J0QnksIGlkKSBvcmRlcjsgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGBvZmZzZXRgLlxuICAgKi9cbiAgY3Vyc29yPzogc3RyaW5nO1xuICAvKiogU3BhcnNlIGZpZWxkc2V0OiBjb2x1bW4gbmFtZXMgdG8gc2VsZWN0LiBSZXR1cm5zIGFsbCBjb2x1bW5zIHdoZW4gb21pdHRlZC4gKi9cbiAgZmllbGRzPzogc3RyaW5nW107XG59XG5cbi8qKlxuICogUGFnaW5hdGVkIHJlc3VsdCB3aXRoIG1ldGFkYXRhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFnaW5hdGVkUmVzdWx0PFQ+IHtcbiAgZGF0YTogVFtdO1xuICAvKiogVG90YWwgY291bnQgb2YgbWF0Y2hpbmcgZW50aXRpZXMuIE9ubHkgcHJlc2VudCB3aGVuIGluY2x1ZGVUb3RhbCBpcyB0cnVlLiAqL1xuICB0b3RhbD86IG51bWJlcjtcbiAgbGltaXQ6IG51bWJlcjtcbiAgb2Zmc2V0OiBudW1iZXI7XG4gIGhhc01vcmU6IGJvb2xlYW47XG4gIC8qKiBPcGFxdWUgY3Vyc29yIGZvciB0aGUgbmV4dCBwYWdlLiBQcmVzZW50IG9ubHkgd2hlbiBgaGFzTW9yZWAuICovXG4gIG5leHRDdXJzb3I/OiBzdHJpbmc7XG59XG5cbi8qKiBTdHJ1Y3R1cmFsIHZpZXcgb2YgdGhlIHN1YmNsYXNzIHRhYmxlJ3MgY29sdW1ucyB0aGUgYmFzZSBjbGFzcyB0b3VjaGVzXG4gKiAgZGlyZWN0bHkuIGBpZGAvYGlzQWN0aXZlYC9gaXNEZWZhdWx0YCBhcmUgYWx3YXlzIHByZXNlbnQgb24gYSBDUlVEIGVudGl0eTtcbiAqICBgdmlzaWJpbGl0eWAgb25seSBvbiB2aXNpYmlsaXR5LWJlYXJpbmcgZW50aXRpZXM7IHRoZSBpbmRleCBzaWduYXR1cmVcbiAqICBjb3ZlcnMgZHluYW1pYyAoc3BhcnNlLWZpZWxkc2V0KSBjb2x1bW4gYWNjZXNzLiAqL1xuaW50ZXJmYWNlIENydWRDb2x1bW5zIHtcbiAgaWQ6IEFueUNvbHVtbjtcbiAgaXNBY3RpdmU6IEFueUNvbHVtbjtcbiAgaXNEZWZhdWx0OiBBbnlDb2x1bW47XG4gIHZpc2liaWxpdHk/OiBBbnlDb2x1bW47XG4gIC8qKiBBdXRob3IgY29sdW1uIOKAlCB0aGUgYHByaXZhdGVgIHJ1bmcgb2YgdGhlIHZpc2liaWxpdHkgbGFkZGVyIGlzIGF1dGhvci1vbmx5LiAqL1xuICBjcmVhdGVkQnk/OiBBbnlDb2x1bW47XG4gIC8vIFNvZnQtZGVsZXRlIGxpZmVjeWNsZSBjb2x1bW5zIChwcmVzZW50IG9uIHRvbWJzdG9uZS1iZWFyaW5nIGVudGl0aWVzIG9ubHk7XG4gIC8vIGByZXN0b3JlYC9gcHVyZ2VFeHBpcmVkYCBhcmUgbm8tb3BzIHdoZW4gYWJzZW50KS5cbiAgZGVsZXRlZEF0PzogQW55Q29sdW1uO1xuICBwdXJnZUFmdGVyPzogQW55Q29sdW1uO1xuICBba2V5OiBzdHJpbmddOiBBbnlDb2x1bW4gfCB1bmRlZmluZWQ7XG59XG5cbi8qKiBQcm9qZWN0aW9uIGFsaWFzIGNhcnJ5aW5nIHRoZSBzb3J0IGNvbHVtbidzIGV4YWN0IERCIHRleHQgZm9yIHRoZSBuZXh0IGN1cnNvci4gKi9cbmNvbnN0IENVUlNPUl9TT1JUX0tFWSA9ICdfX2N1cnNvclNvcnRLZXknO1xuXG4vKipcbiAqIE9wYXF1ZSBrZXlzZXQgY3Vyc29yOiB0aGUgbGFzdCByb3cncyBzb3J0IHZhbHVlIGFzIFBvc3RncmVzIFRFWFQgKGZ1bGxcbiAqIHByZWNpc2lvbiDigJQgYSBKUyBgRGF0ZWAgd291bGQgdHJ1bmNhdGUgYHRpbWVzdGFtcHR6YCBtaWNyb3NlY29uZHMgdG8gbXMsIHNvXG4gKiBgY3JlYXRlZF9hdCA+ICc8bXM+J2AgcmUtcmV0dXJucyBvciBza2lwcyByb3dzIGluIHRoZSBzYW1lIG1pbGxpc2Vjb25kKSBwbHVzXG4gKiBpdHMgYGlkYCBhcyB0aGUgdGllLWJyZWFrZXIuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZUN1cnNvcihzb3J0VGV4dDogc3RyaW5nIHwgbnVsbCwgaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShbc29ydFRleHQsIGlkXSksICd1dGY4JykudG9TdHJpbmcoJ2Jhc2U2NHVybCcpO1xufVxuXG4vKiogRGVjb2RlIGEgY3Vyc29yIHByb2R1Y2VkIGJ5IHtAbGluayBlbmNvZGVDdXJzb3J9OyBgbnVsbGAgd2hlbiBtYWxmb3JtZWQuICovXG5mdW5jdGlvbiBkZWNvZGVDdXJzb3IoY3Vyc29yOiBzdHJpbmcpOiB7IHNvcnRUZXh0OiBzdHJpbmcgfCBudWxsOyBpZDogc3RyaW5nIH0gfCBudWxsIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWQ6IHVua25vd24gPSBKU09OLnBhcnNlKEJ1ZmZlci5mcm9tKGN1cnNvciwgJ2Jhc2U2NHVybCcpLnRvU3RyaW5nKCd1dGY4JykpO1xuICAgIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkocGFyc2VkKSAmJiBwYXJzZWQubGVuZ3RoID09PSAyXG4gICAgICAmJiAocGFyc2VkWzBdID09PSBudWxsIHx8IHR5cGVvZiBwYXJzZWRbMF0gPT09ICdzdHJpbmcnKVxuICAgICAgJiYgdHlwZW9mIHBhcnNlZFsxXSA9PT0gJ3N0cmluZycgJiYgcGFyc2VkWzFdLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIHJldHVybiB7IHNvcnRUZXh0OiBwYXJzZWRbMF0sIGlkOiBwYXJzZWRbMV0gfTtcbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIC8vIGZhbGwgdGhyb3VnaFxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBVVUlEX1RFWFQgPSAvXlswLTlhLWZdezh9LVswLTlhLWZdezR9LVswLTlhLWZdezR9LVswLTlhLWZdezR9LVswLTlhLWZdezEyfSQvaTtcbi8qKiBQb3N0Z3JlcyBgdGltZXN0YW1wW3R6XTo6dGV4dGAgLyBgZGF0ZTo6dGV4dGAgKGFsc28gYWNjZXB0cyBJU08tODYwMSkuICovXG5jb25zdCBUSU1FU1RBTVBfVEVYVCA9IC9eXFxkezR9LVxcZHsyfS1cXGR7Mn0oPzpbIFRdXFxkezJ9OlxcZHsyfSg/OjpcXGR7Mn0oPzpcXC5cXGR7MSw2fSk/KT8oPzpafFsrLV1cXGR7Mn0oPzo6P1xcZHsyfSk/KT8pPyQvO1xuY29uc3QgTlVNRVJJQ19URVhUID0gL14tP1xcZCsoPzpcXC5cXGQrKT8oPzpbZUVdWy0rXT9cXGQrKT8kLztcblxuLyoqXG4gKiBXaGV0aGVyIGB0ZXh0YCBjYW4gYmUgY2FzdCB0byBgY29sdW1uYCdzIHR5cGUuIEEgZGVjb2RlZCBjdXJzb3IgaXMgc3RpbGxcbiAqIGNsaWVudCBpbnB1dDogYSB2YWx1ZSBQb3N0Z3JlcyBjYW4ndCBjYXN0IChhIG5vbi1VVUlEIGlkLCBhIGdhcmJhZ2VcbiAqIHRpbWVzdGFtcCkgZmFpbHMgdGhlIHdob2xlIHF1ZXJ5IHdpdGggYSA1MDAuIENvbHVtbiB0eXBlcyB0aGlzIGRvZXNuJ3Qga25vd1xuICogKHRleHQsIHZhcmNoYXIsIOKApikgYWNjZXB0IGFueSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGlzQ2FzdGFibGVUbyhjb2x1bW46IEFueUNvbHVtbiwgdGV4dDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgY29sdW1uVHlwZSwgZGF0YVR5cGUgfSA9IGNvbHVtbjtcbiAgY29uc3QgZW51bVZhbHVlcyA9IChjb2x1bW4gYXMgeyBlbnVtVmFsdWVzPzogcmVhZG9ubHkgc3RyaW5nW10gfSkuZW51bVZhbHVlcztcbiAgaWYgKGNvbHVtblR5cGUgPT09ICdQZ1VVSUQnKSByZXR1cm4gVVVJRF9URVhULnRlc3QodGV4dCk7XG4gIGlmICgoY29sdW1uVHlwZSA9PT0gJ1BnRW51bUNvbHVtbicgfHwgY29sdW1uVHlwZSA9PT0gJ1BnRW51bU9iamVjdENvbHVtbicpICYmIGVudW1WYWx1ZXM/Lmxlbmd0aCkgcmV0dXJuIGVudW1WYWx1ZXMuaW5jbHVkZXModGV4dCk7XG4gIGlmIChkYXRhVHlwZSA9PT0gJ2RhdGUnIHx8IGNvbHVtblR5cGUgPT09ICdQZ1RpbWVzdGFtcFN0cmluZycgfHwgY29sdW1uVHlwZSA9PT0gJ1BnRGF0ZVN0cmluZycpIHJldHVybiBUSU1FU1RBTVBfVEVYVC50ZXN0KHRleHQpO1xuICBpZiAoZGF0YVR5cGUgPT09ICdib29sZWFuJykgcmV0dXJuIHRleHQgPT09ICd0cnVlJyB8fCB0ZXh0ID09PSAnZmFsc2UnO1xuICBpZiAoZGF0YVR5cGUgPT09ICdudW1iZXInIHx8IGRhdGFUeXBlID09PSAnYmlnaW50JykgcmV0dXJuIE5VTUVSSUNfVEVYVC50ZXN0KHRleHQpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBLZXlzZXQgcHJlZGljYXRlIFwic3RyaWN0bHkgYWZ0ZXIgKHNvcnRUZXh0LCBpZClcIiBmb3IgYE9SREVSIEJZIHNvcnQgPGRpcj4sIGlkIDxkaXI+YFxuICogdW5kZXIgUG9zdGdyZXMnIGRlZmF1bHQgbnVsbCBwbGFjZW1lbnQgKEFTQyDihpIgTlVMTFMgTEFTVCwgREVTQyDihpIgTlVMTFMgRklSU1QpLlxuICogVGhlIHRleHQgdmFsdWUgaXMgYm91bmQgYXMgYSBwYXJhbWV0ZXIgY29tcGFyZWQgYWdhaW5zdCB0aGUgY29sdW1uLCBzbyBQb3N0Z3Jlc1xuICogY2FzdHMgaXQgYmFjayB0byB0aGUgY29sdW1uJ3MgdHlwZSBhdCBmdWxsIHByZWNpc2lvbi5cbiAqL1xuZnVuY3Rpb24ga2V5c2V0QWZ0ZXIoXG4gIHNvcnRDb2x1bW46IEFueUNvbHVtbixcbiAgaWRDb2x1bW46IEFueUNvbHVtbixcbiAgc29ydE9yZGVyOiAnYXNjJyB8ICdkZXNjJyxcbiAgc29ydFRleHQ6IHN0cmluZyB8IG51bGwsXG4gIGlkOiBzdHJpbmcsXG4pOiBTUUwge1xuICBpZiAoc29ydENvbHVtbiA9PT0gaWRDb2x1bW4pIHtcbiAgICByZXR1cm4gc29ydE9yZGVyID09PSAnZGVzYycgPyBzcWxgJHtpZENvbHVtbn0gPCAke2lkfWAgOiBzcWxgJHtpZENvbHVtbn0gPiAke2lkfWA7XG4gIH1cbiAgaWYgKHNvcnRPcmRlciA9PT0gJ2FzYycpIHtcbiAgICByZXR1cm4gc29ydFRleHQgPT09IG51bGxcbiAgICAgID8gc3FsYCgke3NvcnRDb2x1bW59IElTIE5VTEwgQU5EICR7aWRDb2x1bW59ID4gJHtpZH0pYFxuICAgICAgOiBzcWxgKCR7c29ydENvbHVtbn0gPiAke3NvcnRUZXh0fSBPUiAoJHtzb3J0Q29sdW1ufSA9ICR7c29ydFRleHR9IEFORCAke2lkQ29sdW1ufSA+ICR7aWR9KSBPUiAke3NvcnRDb2x1bW59IElTIE5VTEwpYDtcbiAgfVxuICByZXR1cm4gc29ydFRleHQgPT09IG51bGxcbiAgICA/IHNxbGAoJHtzb3J0Q29sdW1ufSBJUyBOT1QgTlVMTCBPUiAoJHtzb3J0Q29sdW1ufSBJUyBOVUxMIEFORCAke2lkQ29sdW1ufSA8ICR7aWR9KSlgXG4gICAgOiBzcWxgKCR7c29ydENvbHVtbn0gPCAke3NvcnRUZXh0fSBPUiAoJHtzb3J0Q29sdW1ufSA9ICR7c29ydFRleHR9IEFORCAke2lkQ29sdW1ufSA8ICR7aWR9KSlgO1xufVxuXG4vKipcbiAqIFJldGVudGlvbiBiZWZvcmUgYSBzb2Z0LWRlbGV0ZWQgcm93IGJlY29tZXMgcHVyZ2UtZWxpZ2libGUsIHNoYXJlZCBhY3Jvc3NcbiAqIGV2ZXJ5IENydWRTZXJ2aWNlIGVudGl0eSAodW5pZmllZCBgU09GVF9ERUxFVEVfUkVURU5USU9OX0RBWVNgLCBkZWZhdWx0IDMwZCkuXG4gKiBTdGFtcGVkIGludG8gYHB1cmdlX2FmdGVyYCBhdCBkZWxldGUgdGltZTsgdGhlIHBlci1zZXJ2aWNlIHB1cmdlIHN3ZWVwIGhhcmQtXG4gKiBkZWxldGVzIHRvbWJzdG9uZXMgb25jZSBpdCBoYXMgcGFzc2VkLiBgMGAgZGlzYWJsZXMgcHVyZ2UtZGVhZGxpbmUgc3RhbXBpbmcuXG4gKi9cbmNvbnN0IFNPRlRfREVMRVRFX1JFVEVOVElPTl9NUyA9IGVudkludCgnU09GVF9ERUxFVEVfUkVURU5USU9OX0RBWVMnLCAzMCwgeyBtaW46IDAgfSkgKiAyNCAqIDYwICogNjAgKiAxMDAwO1xuXG4vKiogVGhlIHNoYXJlZCBzb2Z0LWRlbGV0ZSByZXRlbnRpb24gd2luZG93IGluIG1zIChgU09GVF9ERUxFVEVfUkVURU5USU9OX0RBWVNgLFxuICogIGRlZmF1bHQgMzBkOyAwIGRpc2FibGVzIHB1cmdlLWRlYWRsaW5lIHN0YW1waW5nKS4gRXhwb3NlZCBzbyBub24tQ3J1ZFNlcnZpY2VcbiAqICBzb2Z0LWRlbGV0ZSBwYXRocyAoZS5nLiBwbGF0Zm9ybSdzIGhhbmQtcm9sbGVkIGRhc2hib2FyZC9hbGVydCBzZXJ2aWNlcylcbiAqICBzdGFtcCBgcHVyZ2VfYWZ0ZXJgIHdpdGggdGhlIFNBTUUgd2luZG93IHRoZSBDcnVkU2VydmljZSBlbnRpdGllcyB1c2UuICovXG5leHBvcnQgZnVuY3Rpb24gc29mdERlbGV0ZVJldGVudGlvbk1zKCk6IG51bWJlciB7XG4gIHJldHVybiBTT0ZUX0RFTEVURV9SRVRFTlRJT05fTVM7XG59XG5cbi8qKlxuICogQWJzdHJhY3QgQ1JVRCBzZXJ2aWNlIHdpdGggbXVsdGktdGVuYW50IGFjY2VzcyBjb250cm9sIGFuZCBwYWdpbmF0aW9uLlxuICpcbiAqIFN1YmNsYXNzZXMgYmluZCB0byBhIHNwZWNpZmljIERyaXp6bGUgdGFibGUgYnkgaW1wbGVtZW50aW5nIGBzY2hlbWFgLFxuICogYGJ1aWxkQ29uZGl0aW9uc2AsIGBnZXRTb3J0Q29sdW1uYCwgYW5kIHRoZSBvcmcvcHJvamVjdC1jb2x1bW4gYWNjZXNzb3JzLlxuICpcbiAqIEB0eXBlUGFyYW0gVEVudGl0eSAtIEVudGl0eSB0eXBlIGV4dGVuZGluZyBCYXNlRW50aXR5XG4gKiBAdHlwZVBhcmFtIFRGaWx0ZXIgLSBGaWx0ZXIgdHlwZSBmb3IgcXVlcnkgcGFyYW1ldGVyc1xuICogQHR5cGVQYXJhbSBUSW5zZXJ0IC0gSW5zZXJ0IERUTyB0eXBlXG4gKiBAdHlwZVBhcmFtIFRVcGRhdGUgLSBVcGRhdGUgRFRPIHR5cGVcbiAqXG4gKiAqKkEgbm90ZSBvbiB0aGUgdHlwZSBjYXN0cy4qKiBEcml6emxlJ3Mgcm93IHR5cGVzIGFyZSBpbmZlcnJlZCBmcm9tXG4gKiBgcGdUYWJsZSguLi4pYCBhbmQgZG9uJ3QgZ2VuZXJpY2FsbHkgbmFycm93IHRocm91Z2ggdGhlIGFic3RyYWN0IGBzY2hlbWFgXG4gKiBnZXR0ZXIsIHNvIHRoZSBiYXNlIGNsYXNzIGNhc3RzIHF1ZXJ5IHJlc3VsdHMgdG8gYFRFbnRpdHlgIGFuZCBiYWNrLiBUaGVcbiAqIGNhc3QgaXMgKm5vdCogYSBydW50aW1lIHNhZmV0eSBndWFyYW50ZWUg4oCUIGl0IHJlbGllcyBvbiBlYWNoIHN1YmNsYXNzXG4gKiBwYXNzaW5nIHRoZSBtYXRjaGluZyBlbnRpdHkgdHlwZS4gT3JnLXNjb3BpbmcgaXMgZW5mb3JjZWQgYnkgZXZlcnlcbiAqIHN1YmNsYXNzJ3MgYGJ1aWxkQ29uZGl0aW9uc2AgaW5qZWN0aW5nIGBXSEVSRSBvcmdfaWQgPSAkMWA7IHRoaXMgY2xhc3NcbiAqIGRvZXMgbm90IGFkZCB0aGF0IGZpbHRlciBpdHNlbGYuXG4gKlxuICogKipFcnJvciBwb2xpY3kuKiogRXJyb3JzIHByb3BhZ2F0ZSB1cCB0byB0aGUgcm91dGUtbGV2ZWwgaGFuZGxlclxuICogKGB3aXRoUm91dGVgKTsgbm8gY2F0Y2gtYW5kLXN3YWxsb3cgaGVyZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY2xhc3MgUGlwZWxpbmVTZXJ2aWNlIGV4dGVuZHMgQ3J1ZFNlcnZpY2U8UGlwZWxpbmUsIFBpcGVsaW5lRmlsdGVyLCBQaXBlbGluZUluc2VydCwgUGlwZWxpbmVVcGRhdGU+IHtcbiAqICAgcHJvdGVjdGVkIGdldCBzY2hlbWEoKSB7IHJldHVybiBzY2hlbWEucGlwZWxpbmU7IH1cbiAqICAgcHJvdGVjdGVkIGJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkKSB7IHJldHVybiBidWlsZFBpcGVsaW5lQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkKTsgfVxuICogICBwcm90ZWN0ZWQgZ2V0U29ydENvbHVtbihzb3J0QnkpIHsgcmV0dXJuIE9iamVjdC5oYXNPd24oc29ydENvbHVtbk1hcCwgc29ydEJ5KSA/IHNvcnRDb2x1bW5NYXBbc29ydEJ5XSA6IG51bGw7IH1cbiAqICAgcHJvdGVjdGVkIGdldFByb2plY3RDb2x1bW4oKSB7IHJldHVybiBzY2hlbWEucGlwZWxpbmUucHJvamVjdDsgfVxuICogICBwcm90ZWN0ZWQgZ2V0T3JnQ29sdW1uKCkgeyByZXR1cm4gc2NoZW1hLnBpcGVsaW5lLm9yZ0lkOyB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENydWRTZXJ2aWNlPFxuICBURW50aXR5IGV4dGVuZHMgQmFzZUVudGl0eSxcbiAgVEZpbHRlcixcbiAgVEluc2VydCxcbiAgVFVwZGF0ZSxcbj4ge1xuICAvKiogRHJpenpsZSBzY2hlbWEgdGFibGUgZm9yIHRoaXMgZW50aXR5ICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXQgc2NoZW1hKCk6IFBnVGFibGU7XG5cbiAgLyoqXG4gICAqIFR5cGVkIGNvbHVtbiB2aWV3IG9mIHtAbGluayBzY2hlbWF9LiBgUGdUYWJsZWAgZXhwb3NlcyBubyBzdGF0aWMgY29sdW1ucywgc29cbiAgICogdGhpcyBpcyB0aGUgc2luZ2xlIHVuYXZvaWRhYmxlIGNhc3QgZm9yIGNvbHVtbiBhY2Nlc3MuIGB2aXNpYmlsaXR5YCBpc1xuICAgKiBvcHRpb25hbCAobm90IGV2ZXJ5IGVudGl0eSBoYXMgaXQpIGFuZCB0aGUgaW5kZXggc2lnbmF0dXJlIGNvdmVycyBkeW5hbWljXG4gICAqIHNwYXJzZS1maWVsZHNldCBjb2x1bW4gbG9va3VwLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgY29scygpOiBDcnVkQ29sdW1ucyB7XG4gICAgcmV0dXJuIHRoaXMuc2NoZW1hIGFzIHVua25vd24gYXMgQ3J1ZENvbHVtbnM7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgU1FMIGNvbmRpdGlvbnMgZm9yIGZpbHRlcmluZyBlbnRpdGllcy5cbiAgICogYHBhcmVudE9yZ0lkYCAob3JnIOKGkiB0ZWFtIGhpZXJhcmNoeSkgaXMgb3B0aW9uYWwgYW5kIG9ubHkgaG9ub3JlZCBieVxuICAgKiBzZXJ2aWNlcyB0aGF0IG9wdCBpbnRvIHBhcmVudC1pbmhlcml0ZWQgdmlzaWJpbGl0eSAoZS5nLiBwbHVnaW5zKS5cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBidWlsZENvbmRpdGlvbnMoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXTtcblxuICAvKiogR2V0IHRoZSBzY2hlbWEgY29sdW1uIGZvciBzb3J0aW5nIGJ5IGZpZWxkIG5hbWUgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldFNvcnRDb2x1bW4oc29ydEJ5OiBzdHJpbmcpOiBBbnlDb2x1bW4gfCBudWxsO1xuXG4gIC8qKiBHZXQgdGhlIHByb2plY3QgY29sdW1uIGZvciBzZXREZWZhdWx0IHNjb3BpbmcgKG51bGwgaWYgZW50aXR5IGhhcyBubyBwcm9qZWN0IHNjb3BlKSAqL1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0UHJvamVjdENvbHVtbigpOiBBbnlDb2x1bW4gfCBudWxsO1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHRlbmFudCBvcmctaWQgY29sdW1uLiBVc2VkIGJvdGggdG8gc2NvcGUgYHNldERlZmF1bHRgIGFuZCB0byBwaW5cbiAgICogZXZlcnkgd3JpdGUgKHVwZGF0ZS9kZWxldGUvYnVsa0RlbGV0ZSkgdG8gdGhlIGNhbGxlcidzIG93biBvcmcg4oCUIHNvIGl0IE1VU1RcbiAgICogYmUgdGhlIHRlbmFudCBgb3JnSWRgIGNvbHVtbiwgbm90IGEgZGlzcGxheS9uYW1lIGNvbHVtbi5cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRPcmdDb2x1bW4oKTogQW55Q29sdW1uO1xuXG4gIC8qKiBUaGUgdW5pcXVlLWNvbnN0cmFpbnQgY29sdW1ucyBhIGNyZWF0ZSBtdXN0IG5vdCBjb25mbGljdCBvbiAoc2VlIHtAbGluayBjcmVhdGV9KS4gKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldCBjb25mbGljdFRhcmdldCgpOiBBbnlDb2x1bW5bXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9sb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2NydWQtc2VydmljZScpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIEZhaWwgZmFzdCBpZiBhIHN1YmNsYXNzIGRvZXNuJ3QgZXhwb3NlIGEgdGVuYW50IG9yZyBjb2x1bW4uIFRoZSB3cml0ZVxuICAgIC8vIHBhdGhzICh3cml0ZUNvbmRpdGlvbnMgLyBidWxrRGVsZXRlKSBwaW4gbXV0YXRpb25zIHRvIHRoZSBjYWxsZXIncyBvd25cbiAgICAvLyBvcmcgdGhyb3VnaCBpdDsgYSBtaXNzaW5nIGNvbHVtbiB3b3VsZCBzaWxlbnRseSBkcm9wIHRoYXQgZ3VhcmQg4oCUIGFcbiAgICAvLyBjcm9zcy10ZW5hbnQgZmFpbC1vcGVuIOKAlCBzbyBhc3NlcnQgaXRzIHByZXNlbmNlIHVwIGZyb250LlxuICAgIGlmICh0aGlzLmdldE9yZ0NvbHVtbigpID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9OiBnZXRPcmdDb2x1bW4oKSBtdXN0IHJldHVybiB0aGUgdGVuYW50IG9yZyBjb2x1bW5gKTtcbiAgICB9XG4gIH1cblxuICAvKiogQnVpbGQgY29uZGl0aW9ucyBmb3IgYSBzaW5nbGUgZW50aXR5IGJ5IElELlxuICAgKiAgYHBhcmVudE9yZ0lkYCB3aWRlbnMgdmlzaWJpbGl0eSB0byBhIHBhcmVudCBvcmcncyBwdWJsaWMgcm93cyAob3JnIOKGkiB0ZWFtXG4gICAqICBoaWVyYXJjaHkpIOKAlCBzYW1lIG9wdC1pbiBzZW1hbnRpY3MgYXMgYGZpbmRgL2BmaW5kUGFnaW5hdGVkYC4gT21pdHRlZCBieSB0aGVcbiAgICogIHdyaXRlIHBhdGggKGB3cml0ZUNvbmRpdGlvbnNgKSwgd2hpY2ggbXVzdCBzdGF5IG93bi1vcmcgc2NvcGVkLiAqL1xuICBwcml2YXRlIGlkQ29uZGl0aW9ucyhpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLnRoaXMuYnVpbGRDb25kaXRpb25zKHsgaWQgfSBhcyB1bmtub3duIGFzIFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkLCBwYXJlbnRPcmdJZCksXG4gICAgICAuLi50aGlzLm5vdFRvbWJzdG9uZWQoKSxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4Y2x1ZGVzIHNvZnQtZGVsZXRlZCB0b21ic3RvbmVzIG9uIGVudGl0aWVzIHdpdGggYSBgZGVsZXRlZEF0YCBjb2x1bW4uIFRoZVxuICAgKiBieS1pZCBmaWx0ZXIgZGVsaWJlcmF0ZWx5IHNraXBzIHRoZSBgaXNBY3RpdmVgIGRlZmF1bHQgKGEgZGVhY3RpdmF0ZWQgcm93IGlzXG4gICAqIHN0aWxsIHJlYWRhYmxlIGJ5IGlkKSwgc28gd2l0aG91dCB0aGlzIGEgdG9tYnN0b25lIHdvdWxkIGJlIHJlYWRhYmxlIGFuZCDigJRcbiAgICogdGhyb3VnaCBgdXBkYXRlYCDigJQgaGFsZi1yZXZpdmFibGUgKGBpc0FjdGl2ZWAgZmxpcHBlZCBiYWNrIHdoaWxlXG4gICAqIGBkZWxldGVkQXRgL2BwdXJnZUFmdGVyYCBzdGF5IHNldCwgc28gdGhlIHN3ZWVwIGxhdGVyIHB1cmdlcyBhIHJvdyB0aGUgVUlcbiAgICogc2hvd3MgYXMgbGl2ZSkuIFRvbWJzdG9uZXMgYXJlIHJlYWNoZWQgb25seSB2aWEgdGhlIGRlZGljYXRlZFxuICAgKiByZXN0b3JlL3B1cmdlL2ZpbmREZWxldGVkIHBhdGhzLlxuICAgKi9cbiAgcHJpdmF0ZSBub3RUb21ic3RvbmVkKCk6IFNRTFtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2xzLmRlbGV0ZWRBdCA/IFtpc051bGwodGhpcy5jb2xzLmRlbGV0ZWRBdCldIDogW107XG4gIH1cblxuICAvKipcbiAgICogQ29uZGl0aW9ucyBmb3IgYSBNVVRBVElPTiAodXBkYXRlL2RlbGV0ZSkgb2YgYSBzaW5nbGUgZW50aXR5LlxuICAgKlxuICAgKiBgaWRDb25kaXRpb25zYCByZXVzZXMgdGhlIFJFQUQgYWNjZXNzLWNvbnRyb2wgY2xhdXNlLCB3aGljaCBhbHNvIG1hdGNoZXNcbiAgICogc3lzdGVtLW9yZyAvIG90aGVyLW9yZyBQVUJMSUMgcmVjb3JkcyDigJQgc28gd2l0aG91dCBhbiBleHRyYSBvd25lcnNoaXAgcGluIGFueVxuICAgKiB0ZW5hbnQgY291bGQgdXBkYXRlIG9yIHNvZnQtZGVsZXRlIGFub3RoZXIgb3JnJ3MgKG9yIHRoZSBzeXN0ZW0gb3JnJ3MpIHB1YmxpY1xuICAgKiByZWNvcmRzLiBBTkQgYSBzdHJpY3QgYG9yZ0lkID09PSBjYWxsZXJgIHByZWRpY2F0ZTogdGhlIHJlYWQgY2xhdXNlJ3NcbiAgICogcHVibGljLU9SIGJyYW5jaCByZXF1aXJlcyBgb3JnX2lkID0gJ3N5c3RlbSdgLCB3aGljaCB0aGVuIGNhbid0IGJlIHNhdGlzZmllZCxcbiAgICogbGVhdmluZyBvbmx5IG93bi1vcmcgcm93cy4gb3JnSWQtbGVzcyAoc3lzYWRtaW4pIGNvbnRleHQga2VlcHMgZnVsbCBhY2Nlc3MuXG4gICAqL1xuICBwcml2YXRlIHdyaXRlQ29uZGl0aW9ucyhpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy5pZENvbmRpdGlvbnMoaWQsIG9yZ0lkKTtcbiAgICAvLyBQaW4gdGhlIG11dGF0aW9uIHRvIHRoZSBjYWxsZXIncyBvd24gb3JnIHZpYSB0aGUgdGVuYW50IGNvbHVtblxuICAgIC8vIChnZXRPcmdDb2x1bW4sIGFzc2VydGVkIG5vbi1udWxsIGluIHRoZSBjb25zdHJ1Y3Rvcikg4oCUIGNvbnNpc3RlbnQgd2l0aFxuICAgIC8vIHNldERlZmF1bHQsIGFuZCBuZXZlciBzaWxlbnRseSBmYWlsLW9wZW4gd2hlbiB0aGUgcHJvcGVydHkgaXMgYWJzZW50LlxuICAgIGlmIChvcmdJZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKSk7XG4gICAgLy8gRm9yY2UgRVhBQ1QgaWQgZXF1YWxpdHkgb24gdGhlIG11dGF0aW9uIHBhdGguIGBpZENvbmRpdGlvbnNgIHJldXNlcyB0aGVcbiAgICAvLyBsaXN0LWZpbHRlciBjbGF1c2UsIHdob3NlIGBidWlsZElkRmlsdGVyYCBQUkVGSVgtbWF0Y2hlcyAoYGlkOjp0ZXh0IExJS0VcbiAgICAvLyAndmFsJSdgKSBhbnkgbm9uLWZ1bGwtVVVJRCB2YWx1ZSDigJQgc28gYSBwYXJ0aWFsIGlkIChgREVMRVRFIC94L2FiYCkgd291bGRcbiAgICAvLyBzb2Z0LWRlbGV0ZS9tdXRhdGUgRVZFUlkgb3duLW9yZyByb3cgd2hvc2UgaWQgc3RhcnRzIHdpdGggYGFiYCBhbmQgcmVwb3J0XG4gICAgLy8gdG91Y2hpbmcgb25lLiBBTkRpbmcgYW4gZXhhY3QgYGlkID0gdmFsYCBjb2xsYXBzZXMgdGhlIHByZWZpeCBjbGF1c2UgdG8gYXRcbiAgICAvLyBtb3N0IHRoZSBzaW5nbGUgZXhhY3Qgcm93OyBhIG1hbGZvcm1lZC9wYXJ0aWFsIGlkIHRoZW4gbWF0Y2hlcyBub3RoaW5nXG4gICAgLy8gKOKGkiA0MDQgdmlhIHRoZSBjYWxsZXJzJyBgaWYgKCFkZWxldGVkKWAgZ3VhcmQpIGluc3RlYWQgb2YgbWFzcy1tdXRhdGluZy5cbiAgICBjb25kaXRpb25zLnB1c2godGhpcy5leGFjdElkQ29uZGl0aW9uKGlkKSk7XG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cblxuICAvKiogRXhhY3QgaWQgZXF1YWxpdHksIGxvd2VyLWNhc2VkIHRvIG1hdGNoIGBidWlsZElkRmlsdGVyYCdzIGZ1bGwtVVVJRCBicmFuY2guXG4gICAqICBgc2NoZW1hYCBpcyB0eXBlZCBgUGdUYWJsZWAgKG5vIHN0YXRpYyBgLmlkYCksIHNvIGNhc3Qg4oCUIHNhbWUgcGF0dGVybiB0aGVcbiAgICogIHNvcnQvZGVmYXVsdCBoZWxwZXJzIHVzZSBmb3IgY29sdW1uIGFjY2Vzcy4gKi9cbiAgcHJpdmF0ZSBleGFjdElkQ29uZGl0aW9uKGlkOiBzdHJpbmcpOiBTUUwge1xuICAgIHJldHVybiBlcSh0aGlzLmNvbHMuaWQsIFN0cmluZyhpZCkudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICAvKiogVGhlIGFjdG9yIHN0YW1wZWQgb24gYSB3cml0ZTogdGhlIGNhbGxlciwgb3IgdGhlIHN5c3RlbSBhY3RvciBmb3IgYmFja2dyb3VuZCB3b3JrLiAqL1xuICBwcml2YXRlIGFjdG9yKHVzZXJJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdXNlcklkIHx8IFNZU1RFTV9BQ1RPUl9JRDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgb25lIGNhc3QgcG9pbnQgZm9yIGAuc2V0KClgIC8gYC52YWx1ZXMoKWAgLyBgLnNlbGVjdCgpYCBzaGFwZXMuIFRoZSBiYXNlIGNsYXNzIHdyaXRlc1xuICAgKiB0aGUgc2hhcmVkIGNvbHVtbnMgKGB1cGRhdGVkQnlgLCBgZGVsZXRlZEF0YCwg4oCmKSB0aHJvdWdoIHRoZSBhYnN0cmFjdFxuICAgKiBgUGdUYWJsZWAsIHdob3NlIGluc2VydC91cGRhdGUgdHlwZXMgY2FuJ3QgcHJvdmUgdGhvc2UgY29sdW1ucyBleGlzdC5cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIHByaXZhdGUgcm93KHZhbHVlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBhbnkge1xuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cblxuICAvKiogUnVuIGEgbGlmZWN5Y2xlIGhvb2sgYmVzdC1lZmZvcnQ6IGEgZmFpbHVyZSBpcyBsb2dnZWQsIG5ldmVyIHRocm93bi4gKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5Ib29rKGhvb2s6ICgpID0+IFByb21pc2U8dm9pZD4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgaG9vaygpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBUaGUgY29sdW1ucyBhIHNvZnQtZGVsZXRlIHN0YW1wcywgaW5jbHVkaW5nIHRoZSBwdXJnZSBkZWFkbGluZS4gKi9cbiAgcHJpdmF0ZSB0b21ic3RvbmVTZXQobm93OiBEYXRlLCB1c2VySWQ6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCB1c2VyID0gdGhpcy5hY3Rvcih1c2VySWQpO1xuICAgIHJldHVybiB7XG4gICAgICBpc0FjdGl2ZTogZmFsc2UsXG4gICAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgICAgIHVwZGF0ZWRCeTogdXNlcixcbiAgICAgIGRlbGV0ZWRBdDogbm93LFxuICAgICAgZGVsZXRlZEJ5OiB1c2VyLFxuICAgICAgLy8gU3RhbXAgdGhlIHB1cmdlIGRlYWRsaW5lIHNvIHRoZSByZXRlbnRpb24gc3dlZXAgY2FuIGhhcmQtZGVsZXRlIGxhdGVyLlxuICAgICAgLi4udGhpcy5wdXJnZUFmdGVyU3RhbXAobm93KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEhhcmQtZGVsZXRlIHVwIHRvIGBsaW1pdGAgcm93cyBtYXRjaGluZyBgY29uZGl0aW9uc2AgaW4gb25lIHRyYW5zYWN0aW9uOlxuICAgKiBkZXBlbmRlbnRzIGFyZSB0b3JuIGRvd24gZmlyc3QgYnkgYG9uQmVmb3JlUHVyZ2VgIGluIHRoZSBTQU1FIHR4IChhXG4gICAqIEZLLWJsb2NraW5nIGNoaWxkIGNhbid0IHN0cmFuZCB0aGUgcGFyZW50OyBhIHRocm93IGFib3J0cyB0aGUgYmF0Y2gpLCB0aGVuXG4gICAqIGBvbkFmdGVyUHVyZ2VgIGhhbmRsZXMgZXh0ZXJuYWwgc2lkZS1lZmZlY3RzIGJlc3QtZWZmb3J0LiBSZXR1cm5zIHRoZSBpZHMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHB1cmdlV2hlcmUoY29uZGl0aW9uczogU1FMW10sIGxpbWl0OiBudW1iZXIpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgcHVyZ2VkSWRzID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgY29uc3QgZG9vbWVkID0gYXdhaXQgdHhcbiAgICAgICAgLnNlbGVjdCh0aGlzLnJvdyh7IGlkOiB0aGlzLmNvbHMuaWQgfSkpXG4gICAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgICAubGltaXQobGltaXQpXG4gICAgICAgIC50aGVuKHIgPT4gKHIgYXMgQXJyYXk8eyBpZDogdW5rbm93biB9PikubWFwKGQgPT4gU3RyaW5nKGQuaWQpKSk7XG5cbiAgICAgIGlmIChkb29tZWQubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gICAgICBhd2FpdCB0aGlzLm9uQmVmb3JlUHVyZ2UoZG9vbWVkLCB0eCk7XG4gICAgICBhd2FpdCB0eC5kZWxldGUodGhpcy5zY2hlbWEpLndoZXJlKGluQXJyYXkodGhpcy5jb2xzLmlkLCBkb29tZWQpKTtcbiAgICAgIHJldHVybiBkb29tZWQ7XG4gICAgfSk7XG5cbiAgICBpZiAocHVyZ2VkSWRzLmxlbmd0aCA+IDApIGF3YWl0IHRoaXMucnVuSG9vaygoKSA9PiB0aGlzLm9uQWZ0ZXJQdXJnZShwdXJnZWRJZHMpKTtcbiAgICByZXR1cm4gcHVyZ2VkSWRzO1xuICB9XG5cbiAgLy8gTGlmZWN5Y2xlIGhvb2tzIOKAlCBvdmVycmlkZSBpbiBzdWJjbGFzc2VzIHRvIHJlYWN0IHRvIG11dGF0aW9uc1xuICAvLyBUaGVzZSBhcmUgZmlyZS1hbmQtZm9yZ2V0OiBlcnJvcnMgYXJlIGxvZ2dlZCBidXQgbmV2ZXIgYmxvY2sgdGhlIGNhbGxlci5cblxuICAvKiogQ2FsbGVkIGFmdGVyIGEgbmV3IGVudGl0eSBpcyBjcmVhdGVkICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkFmdGVyQ3JlYXRlKF9lbnRpdHk6IFRFbnRpdHksIF91c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogQ2FsbGVkIGFmdGVyIGFuIGVudGl0eSBpcyB1cGRhdGVkICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkFmdGVyVXBkYXRlKF9pZDogc3RyaW5nLCBfZW50aXR5OiBURW50aXR5LCBfdXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIENhbGxlZCBhZnRlciBhbiBlbnRpdHkgaXMgc29mdC1kZWxldGVkICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkFmdGVyRGVsZXRlKF9pZDogc3RyaW5nLCBfZW50aXR5OiBURW50aXR5LCBfdXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIENhbGxlZCBhZnRlciBhIHNvZnQtZGVsZXRlZCBlbnRpdHkgaXMgcmVzdG9yZWQgKHVuZG8gdGhlIGRlbGV0ZSkuIE92ZXJyaWRlXG4gICAqICBmb3IgZW50aXRpZXMgd2hvc2UgcmVzdG9yZSBoYXMgc2lkZS1lZmZlY3RzIChlLmcuIHJlLW5vdGlmeSkuIEJlc3QtZWZmb3J0LiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgb25BZnRlclJlc3RvcmUoX2lkOiBzdHJpbmcsIF9lbnRpdHk6IFRFbnRpdHksIF91c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogQ2FsbGVkIHdpdGggdGhlIGlkcyBhYm91dCB0byBiZSBoYXJkLXB1cmdlZCwgQkVGT1JFIHRoZSBkZWxldGUsIGluc2lkZSB0aGVcbiAgICogIHB1cmdlIHRyYW5zYWN0aW9uIChgdHhgKSDigJQgYSBzdWJjbGFzcyB0ZWFyaW5nIGRvd24gZGVwZW5kZW50cyB0aGF0IGxhY2sgT05cbiAgICogIERFTEVURSBDQVNDQURFIE1VU1QgdXNlIGB0eGAgc28gdGhlIHRlYXJkb3duIGlzIGF0b21pYyB3aXRoIHRoZSBwYXJlbnRcbiAgICogIERFTEVURSAoYW5kIGNhbid0IHNlbGYtZGVhZGxvY2sgYWdhaW5zdCBpdHMgcm93IGxvY2tzKS4gVGhyb3dpbmcgYWJvcnRzIHRoYXRcbiAgICogIGJhdGNoJ3MgcHVyZ2UgKHJvd3Mgc3RheSB0b21ic3RvbmVkLCByZXRyaWVkIG5leHQgdGljaykuICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkJlZm9yZVB1cmdlKF9pZHM6IHN0cmluZ1tdLCBfdHg6IENydWRUeCk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogQ2FsbGVkIGFmdGVyIHJvd3MgYXJlIGhhcmQtcHVyZ2VkLCBmb3IgZXh0ZXJuYWwgc2lkZS1lZmZlY3RzIChlLmcuIHBsdWdpblxuICAgKiAgaW1hZ2UgR0MpLiBCZXN0LWVmZm9ydDogZXJyb3JzIGFyZSBsb2dnZWQsIG5ldmVyIGJsb2NrIHRoZSBzd2VlcC4gKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJQdXJnZShfaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogUmV0ZW50aW9uIGJlZm9yZSBhIHNvZnQtZGVsZXRlZCByb3cgYmVjb21lcyBwdXJnZS1lbGlnaWJsZS4gRGVmYXVsdHMgdG8gdGhlXG4gICAqICBzaGFyZWQgYFNPRlRfREVMRVRFX1JFVEVOVElPTl9EQVlTYDsgb3ZlcnJpZGUgcGVyIGVudGl0eSBmb3IgYSBiZXNwb2tlIHdpbmRvdy4gKi9cbiAgcHJvdGVjdGVkIGdldCBzb2Z0RGVsZXRlUmV0ZW50aW9uTXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gU09GVF9ERUxFVEVfUkVURU5USU9OX01TO1xuICB9XG5cbiAgLyoqIFRoZSBgcHVyZ2VfYWZ0ZXJgIHZhbHVlIHRvIHN0YW1wIG9uIGEgc29mdC1kZWxldGU6IGBub3cgKyByZXRlbnRpb25gLCBvciB0aGVcbiAgICogIHNwcmVhZC1mcmllbmRseSBlbXB0eSBvYmplY3Qgd2hlbiB0aGUgZW50aXR5IGhhcyBubyBgcHVyZ2VfYWZ0ZXJgIGNvbHVtbi5cbiAgICogIGBwcm90ZWN0ZWRgIHNvIHN1YmNsYXNzZXMgd2l0aCBoYW5kLXJvbGxlZCBzb2Z0LWRlbGV0ZSBwYXRocyAoZS5nLlxuICAgKiAgbWVzc2FnZS1zZXJ2aWNlJ3MgdGhyZWFkIGNhc2NhZGUgLyBzeXNhZG1pbiBtb2RlcmF0aW9uKSBzdGFtcCBpdCB0b28g4oCUIGFuXG4gICAqICB1bi1zdGFtcGVkIHRvbWJzdG9uZSBoYXMgTlVMTCBgcHVyZ2VfYWZ0ZXJgIGFuZCBpcyBuZXZlciBoYXJkLXB1cmdlZC4gKi9cbiAgcHJvdGVjdGVkIHB1cmdlQWZ0ZXJTdGFtcChub3c6IERhdGUpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgaWYgKCF0aGlzLmNvbHMucHVyZ2VBZnRlciB8fCB0aGlzLnNvZnREZWxldGVSZXRlbnRpb25NcyA8PSAwKSByZXR1cm4ge307XG4gICAgcmV0dXJuIHsgcHVyZ2VBZnRlcjogbmV3IERhdGUobm93LmdldFRpbWUoKSArIHRoaXMuc29mdERlbGV0ZVJldGVudGlvbk1zKSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIE9yZyDihpIgdGVhbSBoaWVyYXJjaHk6IHdoZW4gYSByZWFkIGlzIHdpZGVuZWQgdG8gYSBwYXJlbnQgb3JnIChgcGFyZW50T3JnSWRgXG4gICAqIHNldCksIHRoZSBwYXJlbnQncyByb3dzIGFyZSBvdXRzaWRlIHRoZSBjYWxsZXIncyBSTFMgc2NvcGUsIHNvIHRoZSByZWFkIG11c3RcbiAgICogcnVuIHVuZGVyIHN5c2FkbWluIGNvbnRleHQg4oCUIHRoZSBhY2Nlc3MtY29udHJvbCBXSEVSRSBjbGF1c2UgKG93biArIHBhcmVudCArXG4gICAqIHN5c3RlbSBwdWJsaWMsIGJ1aWx0IHNlcnZlci1zaWRlIGZyb20gYSB0cnVzdGVkIEpXVCBjbGFpbSkgaXMgdGhlbiB0aGVcbiAgICogYXV0aG9yaXRhdGl2ZSB0ZW5hbmN5IGdhdGUuIFdpdGhvdXQgYHBhcmVudE9yZ0lkYCBpdCBzdGF5cyBSTFMtc2NvcGVkLlxuICAgKlxuICAgKiBJTlZBUklBTlQgKHdoeSB0aGUgc3lzYWRtaW4gYnlwYXNzIGlzIHNhZmUpOiB0aGUgV0hFUkUgY2xhdXNlIGlzIGFsd2F5c1xuICAgKiBzZXJ2ZXItYnVpbHQgYnkgYGJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZClgIGZyb20gdmFsdWVzXG4gICAqIGRlcml2ZWQgZnJvbSB0aGUgdmFsaWRhdGVkIEpXVCAoYG9yZ0lkYCA9IGFjdGl2ZSBvcmcsIGBwYXJlbnRPcmdJZGAgPSB0aGVcbiAgICogYWN0aXZlIG9yZydzIHBhcmVudCkuIE5vbmUgb2YgdGhlbSBpcyBhIHJhdyB1c2VyLXN1cHBsaWVkIHByZWRpY2F0ZSwgc28gdGhlXG4gICAqIGJ5cGFzcyBvbmx5IGV2ZXIgd2lkZW5zIHRoZSByZWFkIHRvIHRoZSBjYWxsZXIncyBvd24gc3VidHJlZSArIHN5c3RlbSBwdWJsaWNcbiAgICogcm93cyDigJQgaXQgY2FuIE5PVCBiZSBzdGVlcmVkIGF0IGFuIGFyYml0cmFyeSBvcmcuIE5PVEU6IHRoaXMgZG9lcyByZW1vdmUgdGhlXG4gICAqIFJMUyBiYWNrc3RvcCBmb3IgdGhlIHdpZGVuZWQgcmVhZDsgYSBzaW5nbGUtR1VDIGBhcHAub3JnX2lkYCBjYW4ndCBleHByZXNzXG4gICAqIHRoZSBcIm93biBPUiBwYXJlbnQgT1Igc3lzdGVtXCIgc2V0IHRoZSBwb2xpY3kgd291bGQgbmVlZCwgc28gcmVwbGFjaW5nIHRoZVxuICAgKiBieXBhc3Mgd291bGQgcmVxdWlyZSBhIHRlbmFuY3ktbGF5ZXIgY2hhbmdlIChlLmcuIGEgbXVsdGktb3JnIFJMUyBwb2xpY3kpLlxuICAgKiBEZWZlcnJlZCBkZWxpYmVyYXRlbHkg4oCUIGRvIG5vdCBzd2FwIHRoaXMgZm9yIGEgYmxhbmtldCBieXBhc3Mgd2l0aG91dFxuICAgKiByZS1jaGVja2luZyB0aGUgV0hFUkUgaXMgc3RpbGwgZnVsbHkgc2VydmVyLWJ1aWx0LlxuICAgKi9cbiAgcHJpdmF0ZSBydW5SZWFkPFQ+KHBhcmVudE9yZ0lkOiBzdHJpbmcgfCB1bmRlZmluZWQsIGZuOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgcmV0dXJuIHBhcmVudE9yZ0lkID8gcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgZm4pIDogZm4oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGVudGl0aWVzIG1hdGNoaW5nIGZpbHRlciBjcml0ZXJpYVxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsIOKAlCBvbWl0IGZvciBhbm9ueW1vdXMvc3lzdGVtLXB1YmxpYy1vbmx5IGFjY2VzcylcbiAgICovXG4gIGFzeW5jIGZpbmQoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFRFbnRpdHlbXT4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG5cbiAgICByZXR1cm4gdGhpcy5ydW5SZWFkKHBhcmVudE9yZ0lkLCAoKSA9PiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCgpXG4gICAgICAuZnJvbSh0aGlzLnNjaGVtYSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPUkRFUiBCWSBmb3Ige0BsaW5rIGZpbmRGaXJzdH0sIHNvIFwidGFrZSBvbmVcIiBpcyBkZXRlcm1pbmlzdGljIHJhdGhlciB0aGFuXG4gICAqIHdoYXRldmVyIHJvdyB0aGUgcGxhbm5lciBtZWV0cyBmaXJzdDogdGhlIGRlZmF1bHQgcm93LCB0aGVuIHRoZSBuZXdlc3QsXG4gICAqIHRoZW4gaWQgYXMgdGhlIGZpbmFsIHRpZWJyZWFrLiBTZXJ2aWNlcyBvdmVycmlkZSBpdCB0byByYW5rIGJ5IHRoZWlyIG93blxuICAgKiBub3Rpb24gb2YgXCJiZXN0IG1hdGNoXCIgKHBsdWdpbnM6IG93biBvcmcgZmlyc3QsIHRoZW4gc2VtdmVyKS5cbiAgICovXG4gIHByb3RlY3RlZCBmaW5kRmlyc3RPcmRlckJ5KF9maWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIF9vcmdJZD86IHN0cmluZywgX3BhcmVudE9yZ0lkPzogc3RyaW5nKTogU1FMW10ge1xuICAgIGNvbnN0IHsgaXNEZWZhdWx0LCBjcmVhdGVkQXQsIGlkIH0gPSB0aGlzLmNvbHM7XG4gICAgcmV0dXJuIFtkZXNjKGlzRGVmYXVsdCksIC4uLihjcmVhdGVkQXQgPyBbZGVzYyhjcmVhdGVkQXQpXSA6IFtdKSwgYXNjKGlkKV07XG4gIH1cblxuICAvKipcbiAgICogRmluZCB0aGUgRklSU1QgZW50aXR5IG1hdGNoaW5nIGBmaWx0ZXJgIOKAlCBhIGJvdW5kZWQgKGBMSU1JVCAxYCkgdmFyaWFudCBvZlxuICAgKiBgZmluZGAgZm9yIHRoZSBcIm1hdGNoIGJ5IGZpbHRlciwgdGFrZSBvbmVcIiByZWFkIHBhdGhzIChlLmcuIGBHRVQgL2ZpbmRgKSwgc29cbiAgICogdGhleSBkb24ndCBgU0VMRUNUYCBldmVyeSBtYXRjaGluZyBvcmcgcm93IGp1c3QgdG8gcmV0dXJuIGBbMF1gLiBSYW5rZWQgYnlcbiAgICoge0BsaW5rIGZpbmRGaXJzdE9yZGVyQnl9LlxuICAgKi9cbiAgYXN5bmMgZmluZEZpcnN0KGZpbHRlcjogUGFydGlhbDxURmlsdGVyPiwgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5IHwgbnVsbD4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG4gICAgY29uc3Qgb3JkZXJCeSA9IHRoaXMuZmluZEZpcnN0T3JkZXJCeShmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5ydW5SZWFkKHBhcmVudE9yZ0lkLCAoKSA9PiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCgpXG4gICAgICAuZnJvbSh0aGlzLnNjaGVtYSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAub3JkZXJCeSguLi5vcmRlckJ5KVxuICAgICAgLmxpbWl0KDEpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpKTtcblxuICAgIHJldHVybiByZXN1bHRzWzBdIHx8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBlbnRpdGllcyB3aXRoIHBhZ2luYXRpb24gYW5kIHNvcnRpbmdcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcGFyYW0gb3JnSWQgLSBVc2VyJ3Mgb3JnYW5pemF0aW9uIElEIChvcHRpb25hbCDigJQgb21pdCBmb3IgYW5vbnltb3VzL3N5c3RlbS1wdWJsaWMtb25seSBhY2Nlc3MpXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gUGFnaW5hdGlvbiBhbmQgc29ydGluZyBvcHRpb25zXG4gICAqL1xuICBhc3luYyBmaW5kUGFnaW5hdGVkKFxuICAgIGZpbHRlcjogUGFydGlhbDxURmlsdGVyPixcbiAgICBvcmdJZD86IHN0cmluZyxcbiAgICBvcHRpb25zOiBRdWVyeU9wdGlvbnMgPSB7fSxcbiAgICBwYXJlbnRPcmdJZD86IHN0cmluZyxcbiAgKTogUHJvbWlzZTxQYWdpbmF0ZWRSZXN1bHQ8VEVudGl0eT4+IHtcbiAgICBjb25zdCB7IGxpbWl0OiByYXdMaW1pdCA9IERFRkFVTFRfUEFHRV9MSU1JVCwgb2Zmc2V0ID0gMCwgc29ydEJ5LCBzb3J0T3JkZXIgPSAnYXNjJywgaW5jbHVkZVRvdGFsID0gZmFsc2UsIGN1cnNvciwgZmllbGRzIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGxpbWl0ID0gTWF0aC5taW4oTWF0aC5tYXgoMSwgcmF3TGltaXQpLCBNQVhfUEFHRV9MSU1JVCk7XG5cbiAgICAvLyBUb3RhbCwgZGV0ZXJtaW5pc3RpYyBvcmRlcjogKHNvcnQgY29sdW1uLCBpZCkuIGBpZGAgaXMgdW5pcXVlLCBzbyByb3dzIHRoYXRcbiAgICAvLyBzaGFyZSBhIHNvcnQgdmFsdWUgaGF2ZSBhIHN0YWJsZSByZWxhdGl2ZSBvcmRlciBhbmQgYSBrZXlzZXQgY3Vyc29yIGNhblxuICAgIC8vIG5ldmVyIHNraXAgb3IgcmVwZWF0IHRoZW0uIEFuIGFic2VudCBvciBVTktOT1dOIGBzb3J0QnlgIG9yZGVycyBieSBgaWRgXG4gICAgLy8gYWxvbmUg4oCUIGFuIHVua25vd24gc29ydCB0aGF0IGFkZGVkIG5vIFdIRVJFIGFuZCBubyBPUkRFUiBCWSB3aGlsZSBzdGlsbFxuICAgIC8vIGVtaXR0aW5nIGEgY3Vyc29yIHdvdWxkIGxvb3AgYSBjdXJzb3IgY2xpZW50IG9uIHBhZ2UgMSBmb3JldmVyLlxuICAgIGNvbnN0IGlkQ29sdW1uID0gdGhpcy5jb2xzLmlkO1xuICAgIGNvbnN0IHNvcnRDb2x1bW4gPSAoc29ydEJ5ID8gdGhpcy5nZXRTb3J0Q29sdW1uKHNvcnRCeSkgOiBudWxsKSA/PyBpZENvbHVtbjtcbiAgICBjb25zdCBkaXJlY3Rpb24gPSBzb3J0T3JkZXIgPT09ICdkZXNjJyA/IGRlc2MgOiBhc2M7XG4gICAgY29uc3Qgb3JkZXJCeSA9IHNvcnRDb2x1bW4gPT09IGlkQ29sdW1uID8gW2RpcmVjdGlvbihpZENvbHVtbildIDogW2RpcmVjdGlvbihzb3J0Q29sdW1uKSwgZGlyZWN0aW9uKGlkQ29sdW1uKV07XG5cbiAgICAvLyBDdXJzb3IgYW5kIG9mZnNldCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIOKAlCBhIHZhbGlkIGN1cnNvciB0YWtlcyBwcmVjZWRlbmNlLlxuICAgIC8vIEEgbWFsZm9ybWVkL3RhbXBlcmVkIGN1cnNvciDigJQgaW5jbHVkaW5nIHdlbGwtZm9ybWVkIEpTT04gd2hvc2UgdmFsdWVzXG4gICAgLy8gY2FuJ3QgYmUgY2FzdCB0byB0aGUgaWQgLyBzb3J0IGNvbHVtbiB0eXBlcyDigJQgaXMgaWdub3JlZCAocmVhZHMgZnJvbSB0aGVcbiAgICAvLyBzdGFydCkgaW5zdGVhZCBvZiByZWFjaGluZyBQb3N0Z3JlcyBhbmQgZmFpbGluZyB0aGUgcXVlcnkuXG4gICAgY29uc3QgcmF3Q3Vyc29yID0gY3Vyc29yID8gZGVjb2RlQ3Vyc29yKGN1cnNvcikgOiBudWxsO1xuICAgIGNvbnN0IGRlY29kZWRDdXJzb3IgPSByYXdDdXJzb3JcbiAgICAgICYmIGlzQ2FzdGFibGVUbyhpZENvbHVtbiwgcmF3Q3Vyc29yLmlkKVxuICAgICAgLy8gKGFuIGlkLW9ubHkgb3JkZXIgbmV2ZXIgYmluZHMgdGhlIHNvcnQgdmFsdWUg4oCUIHNlZSBrZXlzZXRBZnRlcilcbiAgICAgICYmIChzb3J0Q29sdW1uID09PSBpZENvbHVtbiB8fCByYXdDdXJzb3Iuc29ydFRleHQgPT09IG51bGwgfHwgaXNDYXN0YWJsZVRvKHNvcnRDb2x1bW4sIHJhd0N1cnNvci5zb3J0VGV4dCkpXG4gICAgICA/IHJhd0N1cnNvclxuICAgICAgOiBudWxsO1xuICAgIGlmIChjdXJzb3IgJiYgIWRlY29kZWRDdXJzb3IpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdJZ25vcmluZyBtYWxmb3JtZWQgcGFnaW5hdGlvbiBjdXJzb3InLCB7IGVudGl0eTogdGhpcy5jb25zdHJ1Y3Rvci5uYW1lIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG4gICAgaWYgKGRlY29kZWRDdXJzb3IpIHtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChrZXlzZXRBZnRlcihzb3J0Q29sdW1uLCBpZENvbHVtbiwgc29ydE9yZGVyLCBkZWNvZGVkQ3Vyc29yLnNvcnRUZXh0LCBkZWNvZGVkQ3Vyc29yLmlkKSk7XG4gICAgfVxuXG4gICAgLy8gV3JhcCB0aGUgd2hvbGUgcGFnaW5hdGVkIHJlYWQgKFNFTEVDVCArIG9wdGlvbmFsIENPVU5UKSBpbiBvbmVcbiAgICAvLyB0ZW5hbnQgdHguIEJvdGggcXVlcmllcyBhcmUgdmlzaWJpbGl0eS1zY29wZWQgYnkgdGhlIHNhbWUgUkxTIHBvbGljeSxcbiAgICAvLyBhbmQgcGlubmluZyB0aGVtIHRvIGEgc2luZ2xlIHR4IGtlZXBzIHRoZSBgYXBwLm9yZ19pZGAgR1VDIHN0YWJsZVxuICAgIC8vIGJldHdlZW4gdGhlbS4gV2hlbiB3aWRlbmluZyB0byBhIHBhcmVudCBvcmcsIHRoZSB3aG9sZSByZWFkIHJ1bnMgdW5kZXJcbiAgICAvLyBzeXNhZG1pbiBjb250ZXh0IChzZWUgcnVuUmVhZCkgc28gdGhlIGFjY2Vzcy1jb250cm9sIFdIRVJFIGlzIHRoZSBnYXRlLlxuICAgIHJldHVybiB0aGlzLnJ1blJlYWQocGFyZW50T3JnSWQsICgpID0+IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAgIC8vIFByb2plY3Rpb246IHRoZSBzcGFyc2UgZmllbGRzZXQgKGFsd2F5cyBpbmNsdWRlcyBgaWRgKSBvciBldmVyeSBjb2x1bW4sXG4gICAgICAvLyBwbHVzIHRoZSBzb3J0IGNvbHVtbidzIGV4YWN0IHRleHQgZm9yIHRoZSBuZXh0IGN1cnNvci5cbiAgICAgIGNvbnN0IGJhc2VTZWxlY3QgPSAoZmllbGRzID8gdGhpcy5idWlsZEZpZWxkU2VsZWN0KGZpZWxkcykgOiB1bmRlZmluZWQpID8/IGdldFRhYmxlQ29sdW1ucyh0aGlzLnNjaGVtYSk7XG4gICAgICBjb25zdCBzZWxlY3RTcGVjID0geyAuLi5iYXNlU2VsZWN0LCBbQ1VSU09SX1NPUlRfS0VZXTogc3FsPHN0cmluZyB8IG51bGw+YCR7c29ydENvbHVtbn06OnRleHRgIH07XG5cbiAgICAgIC8vIEZldGNoIGxpbWl0KzEgdG8gZGV0ZWN0IGhhc01vcmUgd2l0aG91dCBDT1VOVCgqKVxuICAgICAgY29uc3QgZWZmZWN0aXZlT2Zmc2V0ID0gZGVjb2RlZEN1cnNvciA/IDAgOiBvZmZzZXQ7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdHguc2VsZWN0KHNlbGVjdFNwZWMgYXMgYW55KS5mcm9tKHRoaXMuc2NoZW1hKS53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAgIC5vcmRlckJ5KC4uLm9yZGVyQnkpXG4gICAgICAgIC5saW1pdChsaW1pdCArIDEpXG4gICAgICAgIC5vZmZzZXQoZWZmZWN0aXZlT2Zmc2V0KS50aGVuKHIgPT4gZHJpenpsZVJvd3M8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHIpKTtcblxuICAgICAgY29uc3QgaGFzTW9yZSA9IHJvd3MubGVuZ3RoID4gbGltaXQ7XG4gICAgICBjb25zdCBwYWdlID0gaGFzTW9yZSA/IHJvd3Muc2xpY2UoMCwgbGltaXQpIDogcm93cztcbiAgICAgIGNvbnN0IGRhdGEgPSBwYWdlLm1hcCgocm93KSA9PiB7XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IHsgLi4ucm93IH07XG4gICAgICAgIGRlbGV0ZSBlbnRpdHlbQ1VSU09SX1NPUlRfS0VZXTtcbiAgICAgICAgcmV0dXJuIGVudGl0eSBhcyBURW50aXR5O1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdDogUGFnaW5hdGVkUmVzdWx0PFRFbnRpdHk+ID0geyBkYXRhLCBsaW1pdCwgb2Zmc2V0OiBlZmZlY3RpdmVPZmZzZXQsIGhhc01vcmUgfTtcblxuICAgICAgaWYgKGhhc01vcmUpIHtcbiAgICAgICAgY29uc3QgbGFzdCA9IHBhZ2VbcGFnZS5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3Qgc29ydFRleHQgPSBsYXN0W0NVUlNPUl9TT1JUX0tFWV07XG4gICAgICAgIHJlc3VsdC5uZXh0Q3Vyc29yID0gZW5jb2RlQ3Vyc29yKHNvcnRUZXh0ID09IG51bGwgPyBudWxsIDogU3RyaW5nKHNvcnRUZXh0KSwgU3RyaW5nKGxhc3QuaWQpKTtcbiAgICAgIH1cblxuICAgICAgLy8gT25seSBydW4gdGhlIENPVU5UKCopIHF1ZXJ5IHdoZW4gdGhlIGNhbGxlciBleHBsaWNpdGx5IG5lZWRzIHRoZSB0b3RhbC5cbiAgICAgIC8vIE11c3QgaW5jbHVkZSBwYXJlbnRPcmdJZCBzbyBgdG90YWxgIG1hdGNoZXMgdGhlIHdpZGVuZWQgZGF0YSBzZXQuXG4gICAgICBpZiAoaW5jbHVkZVRvdGFsKSB7XG4gICAgICAgIGNvbnN0IGJhc2VDb25kaXRpb25zID0gdGhpcy5idWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICAgICAgICBjb25zdCBbY291bnRSZXN1bHRdID0gYXdhaXQgdHhcbiAgICAgICAgICAuc2VsZWN0KHsgY291bnQ6IHNxbDxudW1iZXI+YGNvdW50KCopOjppbnRgIH0pXG4gICAgICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAgICAgLndoZXJlKGFuZCguLi5iYXNlQ29uZGl0aW9ucykpLnRoZW4ociA9PiBkcml6emxlQ291bnQocikpO1xuICAgICAgICByZXN1bHQudG90YWwgPSBjb3VudFJlc3VsdD8uY291bnQgfHwgMDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb2x1bW4gc2VsZWN0aW9uIG1hcCBmb3Igc3BhcnNlIGZpZWxkc2V0cy5cbiAgICogRmFsbHMgYmFjayB0byBmdWxsIHNlbGVjdCBpZiBubyBmaWVsZHMgYXJlIHJlcXVlc3RlZC5cbiAgICpcbiAgICogYGlkYCBpcyBhbHdheXMgaW5jbHVkZWQg4oCUIGl0IGlzIHRoZSBlbnRpdHkgaWRlbnRpdHkgQU5EIHRoZSBrZXlzZXQgY3Vyc29yJ3NcbiAgICogdGllLWJyZWFrZXIuIFRoZSBzb3J0IHZhbHVlIGZvciB0aGUgY3Vyc29yIGlzIHByb2plY3RlZCBzZXBhcmF0ZWx5IChhcyB0ZXh0KVxuICAgKiBieSBgZmluZFBhZ2luYXRlZGAsIHNvIHRoZSBmaWVsZHNldCBuZWVkIG5vdCBjYXJyeSB0aGUgc29ydCBjb2x1bW4uXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkRmllbGRTZWxlY3QoZmllbGRzOiBzdHJpbmdbXSk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoZmllbGRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgLy8gQWx3YXlzIGluY2x1ZGUgaWQgZm9yIGVudGl0eSBpZGVudGl0eVxuICAgIGNvbHVtbnMuaWQgPSB0aGlzLmNvbHMuaWQ7XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgaWYgKGZpZWxkID09PSAnaWQnKSBjb250aW51ZTsgLy8gQWxyZWFkeSBpbmNsdWRlZFxuICAgICAgY29uc3QgY29sID0gdGhpcy5jb2xzW2ZpZWxkXTtcbiAgICAgIGlmIChjb2wpIGNvbHVtbnNbZmllbGRdID0gY29sO1xuICAgIH1cblxuICAgIC8vIEF0IG1pbmltdW0gd2UnbGwgaGF2ZSB7IGlkIH0sIHdoaWNoIGlzIHZhbGlkXG4gICAgcmV0dXJuIGNvbHVtbnM7XG4gIH1cblxuICAvKipcbiAgICogQ291bnQgZW50aXRpZXMgbWF0Y2hpbmcgZmlsdGVyIGNyaXRlcmlhXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKiBAcGFyYW0gcGFyZW50T3JnSWQgLSBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB3aWRlbiB0aGUgY291bnQgdG8gdGhlIHBhcmVudCBvcmcnc1xuICAgKiAgIHB1YmxpYyByb3dzLiBNVVNUIG1pcnJvciBgZmluZGAvYGZpbmRQYWdpbmF0ZWRgJ3Mgd2lkZW5pbmcgKHNhbWVcbiAgICogICBgYnVpbGRDb25kaXRpb25zYCBhcmdzICsgc3lzYWRtaW4tc2NvcGVkIHJlYWQgdmlhIGBydW5SZWFkYCkgc28gYSBwYWdlZFxuICAgKiAgIGxpc3QncyBgdG90YWxgIG1hdGNoZXMgdGhlIHJvd3MgYSB3aWRlbmVkIGBmaW5kKClgIHJldHVybnMg4oCUIG90aGVyd2lzZSB0aGVcbiAgICogICBjb3VudCBvbWl0cyB0aGUgcGFyZW50J3Mgcm93cyBhbmQgcmVwb3J0cyBhIG5hcnJvd2VyIHRvdGFsIHRoYW4gdGhlIGRhdGEgc2V0LlxuICAgKi9cbiAgYXN5bmMgY291bnQoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG5cbiAgICBjb25zdCBbcmVzdWx0XSA9IGF3YWl0IHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5zZWxlY3QoeyBjb3VudDogc3FsPG51bWJlcj5gY291bnQoKik6OmludGAgfSlcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSkudGhlbihyID0+IGRyaXp6bGVDb3VudChyKSkpKTtcblxuICAgIHJldHVybiByZXN1bHQ/LmNvdW50IHx8IDA7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhIHNpbmdsZSBlbnRpdHkgYnkgSURcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gRW50aXR5IElEXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsIOKAlCBvbWl0IGZvciBhbm9ueW1vdXMvc3lzdGVtLXB1YmxpYy1vbmx5IGFjY2VzcylcbiAgICogQHBhcmFtIHBhcmVudE9yZ0lkIC0gT3JnIOKGkiB0ZWFtIGhpZXJhcmNoeTogd2lkZW4gdmlzaWJpbGl0eSB0byB0aGUgcGFyZW50XG4gICAqICAgb3JnJ3MgcHVibGljIHJvd3MgKHNvIGEgdGVhbSBjYW4gZmV0Y2ggYSBwYXJlbnQncyBwdWJsaWMgZW50aXR5IGJ5IGlkKS5cbiAgICogICBTYW1lIG9wdC1pbiArIHN5c2FkbWluLXNjb3BlZCByZWFkIGFzIGBmaW5kYC9gZmluZFBhZ2luYXRlZGA7IHRoZVxuICAgKiAgIGFjY2Vzcy1jb250cm9sIFdIRVJFIGNsYXVzZSBpcyB0aGUgYXV0aG9yaXRhdGl2ZSB0ZW5hbmN5IGdhdGUuXG4gICAqL1xuICBhc3luYyBmaW5kQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFRFbnRpdHkgfCBudWxsPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuaWRDb25kaXRpb25zKGlkLCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICAgIC8vIEV4YWN0IGlkIOKAlCBgZmluZEJ5SWRgIG1lYW5zIFRIRSByb3cgd2l0aCB0aGlzIGlkLCBub3QgYSBwcmVmaXggbWF0Y2guIFRoZVxuICAgIC8vIHNoYXJlZCBgYnVpbGRJZEZpbHRlcmAgcHJlZml4LW1hdGNoZXMgbm9uLWZ1bGwtVVVJRCB2YWx1ZXMgKGEgbGlzdC1zZWFyY2hcbiAgICAvLyBmZWF0dXJlKSwgd2hpY2ggaGVyZSB3b3VsZCByZXR1cm4gYW4gYXJiaXRyYXJ5IGZpcnN0IHByZWZpeCBoaXQgZm9yIGFcbiAgICAvLyBwYXJ0aWFsIGlkOyBwaW4gaXQgdG8gZXhhY3Qgc28gYSBtYWxmb3JtZWQgaWQgcmV0dXJucyBudWxsLlxuICAgIGNvbmRpdGlvbnMucHVzaCh0aGlzLmV4YWN0SWRDb25kaXRpb24oaWQpKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLnJ1blJlYWQocGFyZW50T3JnSWQsICgpID0+IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAuc2VsZWN0KClcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5saW1pdCgxKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKSk7XG5cbiAgICByZXR1cm4gcmVzdWx0c1swXSB8fCBudWxsO1xuICB9XG5cbiAgLy8gTXV0YXRpb24gb3BlcmF0aW9uc1xuXG4gIC8qKlxuICAgKiBEZWZlbnNlLWluLWRlcHRoIHRlbmFudCBzdGFtcCBhbG9uZ3NpZGUgUkxTOiBhIE5PTi1zeXNhZG1pbiBjYWxsZXIgbWF5IG9ubHlcbiAgICogd3JpdGUgaW50byBpdHMgT1dOIG9yZywgc28gcGluIHRoZSByb3cgdG8gdGhlIHRydXN0ZWQgdGVuYW50LWNvbnRleHQgb3JnLlxuICAgKlxuICAgKiBUaGUgc3RhbXAgZmlyZXMgd2hlbmV2ZXIgdGhlIHBheWxvYWQncyBgb3JnSWRgIGRpZmZlcnMgZnJvbSB0aGUgY29udGV4dCBvcmcg4oCUXG4gICAqIHdoaWNoIGNvdmVycyBCT1RIIGEgZm9yZ2VkL21pc21hdGNoZWQgYGRhdGEub3JnSWRgIEFORCBhbiBBQlNFTlQgb25lLiBUaGVcbiAgICogYWJzZW50IGNhc2UgaXMgdGhlIGltcG9ydGFudCB0ZW5hbnQtYm91bmRhcnkgZml4OiB0aGUgYG9yZ19pZGAgY29sdW1uIERFRkFVTFRzXG4gICAqIHRvIGBTWVNURU1fT1JHX0lEYCAoc2NoZW1hL3BpcGVsaW5lLnRzLCBzY2hlbWEvcGx1Z2luLnRzKSwgc28gYW4gaW5zZXJ0IHRoYXRcbiAgICogb21pdHMgYG9yZ0lkYCB3b3VsZCBvdGhlcndpc2UgbGFuZCB0aGUgdGVuYW50J3Mgcm93IGluIHRoZSBwdWJsaWMgc3lzdGVtXG4gICAqIGNhdGFsb2cg4oCUIGEgY3Jvc3MtdGVuYW50IGZhaWwtb3Blbi4gQWx3YXlzIGluamVjdGluZyBgY3R4Lm9yZ0lkYCBjbG9zZXMgaXQuXG4gICAqXG4gICAqIFN5c2FkbWluIChhbmQgb3V0LW9mLWNvbnRleHQgd29ya2VyL3N5c3RlbSBwYXRocywgd2hlcmUgYGdldFRlbmFudENvbnRleHQoKWBcbiAgICogaXMgdW5kZWZpbmVkKSBrZWVwIHRoZSBzdXBwbGllZCBvcmcsIG1hdGNoaW5nIHRoZSBSTFMgcG9saWN5XG4gICAqIGBjdXJyZW50X2lzX3N5c2FkbWluKCkgT1Igb3JnX2lkID0gY3VycmVudF9vcmdfaWQoKWAuXG4gICAqL1xuICAvLyBHZW5lcmljIG92ZXIgdGhlIHBheWxvYWQgc2hhcGUgc28gYm90aCB0aGUgY3JlYXRlIChgVEluc2VydGApIGFuZCB1cGRhdGVcbiAgLy8gKGBQYXJ0aWFsPFRVcGRhdGU+YCkgY2FsbCBzaXRlcyB1c2UgaXQg4oCUIHRoZSBvcmctc3RhbXAgbG9naWMgb25seSB0b3VjaGVzXG4gIC8vIHRoZSBgb3JnSWRgIGtleS5cbiAgcHJvdGVjdGVkIGVuZm9yY2VPcmdJZDxUPihkYXRhOiBULCBpc0NyZWF0ZSA9IGZhbHNlKTogVCB7XG4gICAgY29uc3QgY3R4ID0gZ2V0VGVuYW50Q29udGV4dCgpO1xuICAgIGNvbnN0IGQgPSBkYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIC8vIFJlZnVzZSBhIGNvbnRleHQtbGVzcywgb3JnSWQtbGVzcyBJTlNFUlQgb24gYW4gb3JnLXNjb3BlZCBlbnRpdHk6IHRoZSBgb3JnSWRgXG4gICAgLy8gY29sdW1uIGRlZmF1bHRzIHRvIFNZU1RFTV9PUkdfSUQsIHNvIHN1Y2ggYSByb3cgd291bGQgc2lsZW50bHkgbGFuZCBpbiB0aGVcbiAgICAvLyBwdWJsaWMgY3Jvc3Mtb3JnIGNhdGFsb2cuIEEgYmFja2dyb3VuZCBqb2IgdGhhdCBmb3Jnb3QgYHJ1bldpdGhUZW5hbnRDb250ZXh0YFxuICAgIC8vIChhbmQgZGlkbid0IHBhc3MgYW4gZXhwbGljaXQgb3JnSWQpIG11c3QgZmFpbCBsb3VkbHksIG5vdCBsZWFrIGludG8gYHN5c3RlbWAuXG4gICAgLy8gKFN5c2FkbWluL3NlZWQgd3JpdGVzIGNhcnJ5IGEgY29udGV4dCBvciBhbiBleHBsaWNpdCBvcmdJZCwgc28gdGhleSBwYXNzLilcbiAgICBpZiAoaXNDcmVhdGUgJiYgIWN0eCAmJiBkLm9yZ0lkID09IG51bGwgJiYgdGhpcy5jb2xzLm9yZ0lkICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9LmNyZWF0ZSByZXF1aXJlcyBhbiBvcmdJZCAobm8gdGVuYW50IGNvbnRleHQgYW5kIG5vbmUgc3VwcGxpZWQpIOKAlCByZWZ1c2luZyB0byBkZWZhdWx0IHRvIHRoZSBzeXN0ZW0gb3JnYCk7XG4gICAgfVxuICAgIGlmIChjdHggJiYgIWN0eC5pc1N1cGVyQWRtaW4gJiYgY3R4Lm9yZ0lkICYmIGQub3JnSWQgIT09IGN0eC5vcmdJZCkge1xuICAgICAgLy8gRGlzdGluZ3Vpc2ggdGhlIHR3byBjYXNlcyB0aGF0IHJlYWNoIGhlcmUgc28gdGhlIGxvZyBzdGF5cyB1c2VmdWwgYW5kXG4gICAgICAvLyBxdWlldDogYSBQUkVTRU5ULWJ1dC1taXNtYXRjaGVkIGBvcmdJZGAgaXMgYW4gYWN0dWFsIG92ZXJyaWRlIGF0dGVtcHRcbiAgICAgIC8vICh3YXJuKSwgd2hpbGUgYW4gQUJTRU5UIGBvcmdJZGAgaXMgdGhlIGNvbW1vbiBub3JtYWwtd3JpdGUgcGF0aCB0aGF0IGp1c3RcbiAgICAgIC8vIG5lZWRzIHRoZSBkZWZhdWx0IHN0YW1wIChkZWJ1Zykg4oCUIGxvZ2dpbmcgdGhhdCBhdCB3YXJuIGZsb29kcyB0aGUgbG9nIG9uXG4gICAgICAvLyBldmVyeSB3cml0ZSB0aGF0IG9taXRzIG9yZ0lkLlxuICAgICAgY29uc3QgbWV0YSA9IHsgc3VwcGxpZWQ6ICdvcmdJZCcgaW4gZCA/IGQub3JnSWQgOiB1bmRlZmluZWQsIGVuZm9yY2VkOiBjdHgub3JnSWQgfTtcbiAgICAgIGlmICgnb3JnSWQnIGluIGQpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0NydWRTZXJ2aWNlOiBvdmVycmlkaW5nIG1pc21hdGNoZWQgb3JnIG9uIHdyaXRlJywgbWV0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ0NydWRTZXJ2aWNlOiBzdGFtcGluZyB0ZW5hbnQtY29udGV4dCBvcmcgb24gd3JpdGUnLCBtZXRhKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IC4uLmQsIG9yZ0lkOiBjdHgub3JnSWQgfSBhcyBUO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgZW50aXR5XG4gICAqL1xuICBhc3luYyBjcmVhdGUoZGF0YTogVEluc2VydCwgdXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPFRFbnRpdHk+IHtcbiAgICBjb25zdCBzYWZlRGF0YSA9IHRoaXMuZW5mb3JjZU9yZ0lkKGRhdGEsIC8qIGlzQ3JlYXRlICovIHRydWUpO1xuICAgIC8vIENyZWF0ZSBuZXZlciBvdmVyd3JpdGVzLiBUaGUgY29uZmxpY3Qga2V5IGNhbiBtYXRjaCBhIExJVkUgcm93IChhbm90aGVyXG4gICAgLy8gYXV0aG9yJ3MsIG9yIG9uZSB0aGUgY2FsbGVyIGNvdWxkbid0IGVkaXQgdGhyb3VnaCB1cGRhdGUpIG9yIGEgc29mdC1kZWxldGVkXG4gICAgLy8gVE9NQlNUT05FOyByZXBsYWNpbmcgZWl0aGVyIHdvdWxkIGJ5cGFzcyB1cGRhdGUncyBhY2Nlc3MgY2hlY2tzIG9yIHJlc3RvcmUnc1xuICAgIC8vIHN0ZXAtdXAuIE9uIGFueSBjb25mbGljdCBub3RoaW5nIGlzIHdyaXR0ZW4gYW5kIHRoZSBjYWxsZXIgZ2V0cyBhIDQwOS5cbiAgICBjb25zdCBbY3JlYXRlZF0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLmluc2VydCh0aGlzLnNjaGVtYSlcbiAgICAgIC52YWx1ZXModGhpcy5yb3coe1xuICAgICAgICAuLi5zYWZlRGF0YSxcbiAgICAgICAgY3JlYXRlZEJ5OiB0aGlzLmFjdG9yKHVzZXJJZCksXG4gICAgICAgIHVwZGF0ZWRCeTogdGhpcy5hY3Rvcih1c2VySWQpLFxuICAgICAgfSkpXG4gICAgICAub25Db25mbGljdERvTm90aGluZyh7IHRhcmdldDogdGhpcy5jb25mbGljdFRhcmdldCBhcyBhbnkgfSlcbiAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKTtcblxuICAgIGlmICghY3JlYXRlZCkge1xuICAgICAgdGhyb3cgbmV3IENvbmZsaWN0RXJyb3IoJ0EgcmVjb3JkIHdpdGggdGhlIHNhbWUgaWRlbnRpdHkgYWxyZWFkeSBleGlzdHMuIElmIGl0IHdhcyBkZWxldGVkLCByZXN0b3JlIGl0IGluc3RlYWQuJyk7XG4gICAgfVxuXG4gICAgLy8gQXdhaXRlZCBpbnRlbnRpb25hbGx5OiBjYWNoZSBpbnZhbGlkYXRpb24gaGFwcGVucyBpbiB0aGUgaG9vaywgYW5kIGFcbiAgICAvLyBmaXJlLWFuZC1mb3JnZXQgcGF0dGVybiBsZXRzIGEgc3Vic2VxdWVudCByZWFkIGluc2lkZSB0aGUgc2FtZSByZXF1ZXN0XG4gICAgLy8gcmV0dXJuIHRoZSBzdGFsZSBwcmUtd3JpdGUgZW50cnkuIFRoZSBob29rIGlzIGV4cGVjdGVkIHRvIGJlIGZhc3RcbiAgICAvLyAoc2luZ2xlIFJlZGlzIG9wKTsgc2xvdyBob29rcyBzaG91bGQgcnVuIHRoZWlyIG93biBiYWNrZ3JvdW5kIHdvcmsuXG4gICAgYXdhaXQgdGhpcy5ydW5Ib29rKCgpID0+IHRoaXMub25BZnRlckNyZWF0ZShjcmVhdGVkLCB1c2VySWQpKTtcblxuICAgIHJldHVybiBjcmVhdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhbiBleGlzdGluZyBlbnRpdHlcbiAgICovXG4gIGFzeW5jIHVwZGF0ZShcbiAgICBpZDogc3RyaW5nLFxuICAgIGRhdGE6IFBhcnRpYWw8VFVwZGF0ZT4sXG4gICAgb3JnSWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxURW50aXR5IHwgbnVsbD4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLndyaXRlQ29uZGl0aW9ucyhpZCwgb3JnSWQpO1xuXG4gICAgLy8gU2NydWIgYSBjYWxsZXItc3VwcGxpZWQgYG9yZ0lkYCBpbiB0aGUgdXBkYXRlIHBheWxvYWQgKGFzIGNyZWF0ZSBkb2VzKTogdGhlXG4gICAgLy8gV0hFUkUgb25seSBwaW5zIHdoaWNoIHJvd3MgeW91IGNhbiBUQVJHRVQsIG5vdCB3aGF0IHlvdSBjYW4gc2V0IOKAlCB3aXRob3V0IHRoaXNcbiAgICAvLyBhIHRlbmFudCBjb3VsZCByZS1ob21lIGEgcm93IGl0IG93bnMgaW50byBhbm90aGVyIG9yZyB2aWEgYGRhdGEub3JnSWRgLlxuICAgIGNvbnN0IHNhZmVEYXRhID0gdGhpcy5lbmZvcmNlT3JnSWQoZGF0YSk7XG5cbiAgICBjb25zdCBbdXBkYXRlZF0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgIC5zZXQodGhpcy5yb3coe1xuICAgICAgICAuLi5zYWZlRGF0YSxcbiAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICB1cGRhdGVkQnk6IHRoaXMuYWN0b3IodXNlcklkKSxcbiAgICAgIH0pKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKTtcblxuICAgIGlmICh1cGRhdGVkKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bkhvb2soKCkgPT4gdGhpcy5vbkFmdGVyVXBkYXRlKGlkLCB1cGRhdGVkLCB1c2VySWQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXBkYXRlZCB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhbiBlbnRpdHkgKHNvZnQgZGVsZXRlIGJ5IHNldHRpbmcgaXNBY3RpdmUgPSBmYWxzZSlcbiAgICovXG4gIGFzeW5jIGRlbGV0ZShpZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy53cml0ZUNvbmRpdGlvbnMoaWQsIG9yZ0lkKTtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gICAgY29uc3QgW2RlbGV0ZWRdID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHRoaXMucm93KHRoaXMudG9tYnN0b25lU2V0KG5vdywgdXNlcklkKSkpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpO1xuXG4gICAgaWYgKGRlbGV0ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuSG9vaygoKSA9PiB0aGlzLm9uQWZ0ZXJEZWxldGUoaWQsIGRlbGV0ZWQsIHVzZXJJZCkpO1xuICAgIH1cblxuICAgIHJldHVybiBkZWxldGVkIHx8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGFuIGVudGl0eSBhcyB0aGUgZGVmYXVsdCBmb3IgYSBwcm9qZWN0L29yZ2FuaXphdGlvbiBzY29wZS5cbiAgICogTWFya3MgYWxsIG90aGVyIGVudGl0aWVzIGFzIG5vbi1kZWZhdWx0LCB0aGVuIHNldHMgdGhlIHNwZWNpZmllZCBlbnRpdHkuXG4gICAqIFVzZXMgYSB0cmFuc2FjdGlvbiB0byBlbnN1cmUgYXRvbWljaXR5LlxuICAgKi9cbiAgYXN5bmMgc2V0RGVmYXVsdChcbiAgICBwcm9qZWN0OiBzdHJpbmcsXG4gICAgb3JnOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxURW50aXR5PiB7XG4gICAgLy8gQSBub24tc3lzYWRtaW4gbWF5IG9ubHkgZmxpcCBkZWZhdWx0cyB3aXRoaW4gaXRzIE9XTiBvcmcg4oCUIHBpbiB0aGUgc2NvcGUgdG9cbiAgICAvLyB0aGUgdHJ1c3RlZCB0ZW5hbnQgY29udGV4dCBzbyBhIGZvcndhcmRlZCBgb3JnYCBhcmcgY2FuJ3QgdG91Y2ggYW5vdGhlclxuICAgIC8vIHRlbmFudCdzIGRlZmF1bHRzIChhcHAtbGF5ZXIgcGluLCBpbiBhZGRpdGlvbiB0byBSTFMpLlxuICAgIGNvbnN0IGN0eCA9IGdldFRlbmFudENvbnRleHQoKTtcbiAgICBpZiAoY3R4ICYmICFjdHguaXNTdXBlckFkbWluICYmIGN0eC5vcmdJZCkgb3JnID0gY3R4Lm9yZ0lkO1xuICAgIHJldHVybiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgICBjb25zdCBvcmdDb2x1bW4gPSB0aGlzLmdldE9yZ0NvbHVtbigpO1xuICAgICAgY29uc3QgcHJvamVjdENvbHVtbiA9IHRoaXMuZ2V0UHJvamVjdENvbHVtbigpO1xuXG4gICAgICAvLyBCdWlsZCBzY29waW5nIGNvbmRpdGlvbnMgZm9yIGNsZWFyaW5nIGRlZmF1bHRzXG4gICAgICBjb25zdCBzY29wZUNvbmRpdGlvbnMgPSBbXG4gICAgICAgIGVxKG9yZ0NvbHVtbiwgb3JnKSxcbiAgICAgICAgZXEodGhpcy5jb2xzLmlzRGVmYXVsdCwgdHJ1ZSksXG4gICAgICBdO1xuICAgICAgaWYgKHByb2plY3RDb2x1bW4pIHtcbiAgICAgICAgc2NvcGVDb25kaXRpb25zLnB1c2goZXEocHJvamVjdENvbHVtbiwgcHJvamVjdCkpO1xuICAgICAgfVxuXG4gICAgICAvLyBMb2NrIGV4aXN0aW5nIGRlZmF1bHRzIHdpdGggRk9SIFVQREFURSB0byBwcmV2ZW50IGNvbmN1cnJlbnQgc2V0RGVmYXVsdCByYWNlc1xuICAgICAgYXdhaXQgdHguZXhlY3V0ZShcbiAgICAgICAgc3FsYFNFTEVDVCBpZCBGUk9NICR7dGhpcy5zY2hlbWF9XG4gICAgICAgICAgICBXSEVSRSAke29yZ0NvbHVtbn0gPSAke29yZ31cbiAgICAgICAgICAgICAgQU5EICR7dGhpcy5jb2xzLmlzRGVmYXVsdH0gPSB0cnVlXG4gICAgICAgICAgICAke3Byb2plY3RDb2x1bW4gPyBzcWxgQU5EICR7cHJvamVjdENvbHVtbn0gPSAke3Byb2plY3R9YCA6IHNxbGBgfVxuICAgICAgICAgICAgRk9SIFVQREFURWAsXG4gICAgICApO1xuXG4gICAgICAvLyBNYXJrIGFsbCBlbnRpdGllcyBpbiBzY29wZSBhcyBub24tZGVmYXVsdFxuICAgICAgYXdhaXQgdHhcbiAgICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgICAgLnNldCh0aGlzLnJvdyh7XG4gICAgICAgICAgaXNEZWZhdWx0OiBmYWxzZSxcbiAgICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgICAgdXBkYXRlZEJ5OiB0aGlzLmFjdG9yKHVzZXJJZCksXG4gICAgICAgIH0pKVxuICAgICAgICAud2hlcmUoYW5kKC4uLnNjb3BlQ29uZGl0aW9ucykpO1xuXG4gICAgICAvLyBTZXQgdGhlIHNwZWNpZmllZCBlbnRpdHkgYXMgZGVmYXVsdC4gR3VhcmQgYWdhaW5zdCBwcm9tb3RpbmcgYVxuICAgICAgLy8gc29mdC1kZWxldGVkIHJvdyAoaXNBY3RpdmUgPSB0cnVlKSDigJQgYSBkZWxldGVkIGVudGl0eSBtdXN0IG5ldmVyIGJlY29tZVxuICAgICAgLy8gdGhlIGFjdGl2ZSBkZWZhdWx0IOKAlCBhbmQgcGluIHRoZSBpZCB3aXRoIHRoZSBzYW1lIGxvd2VyY2FzZWRcbiAgICAgIC8vIGV4YWN0SWRDb25kaXRpb24gdGhlIG11dGF0aW9uIHBhdGhzIHVzZSAodGhlIHJhdyBgZXEoY29scy5pZCwgaWQpYCBoZXJlXG4gICAgICAvLyBza2lwcGVkIHRoZSBsb3dlci1jYXNpbmcgdGhhdCBgYnVpbGRJZEZpbHRlcmAvYHdyaXRlQ29uZGl0aW9uc2AgYXBwbHksXG4gICAgICAvLyBzbyBhIG1peGVkLWNhc2UgaWQgY291bGQgbWlzcyBpdHMgcm93KS4gQSBub24tbWF0Y2gg4oaSIE5vdEZvdW5kRXJyb3IgYmVsb3cuXG4gICAgICBjb25zdCBbdXBkYXRlZF0gPSBhd2FpdCB0eFxuICAgICAgICAudXBkYXRlKHRoaXMuc2NoZW1hKVxuICAgICAgICAuc2V0KHRoaXMucm93KHtcbiAgICAgICAgICBpc0RlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICAgIHVwZGF0ZWRCeTogdGhpcy5hY3Rvcih1c2VySWQpLFxuICAgICAgICB9KSlcbiAgICAgICAgLndoZXJlKFxuICAgICAgICAgIGFuZChcbiAgICAgICAgICAgIHRoaXMuZXhhY3RJZENvbmRpdGlvbihpZCksXG4gICAgICAgICAgICBlcShvcmdDb2x1bW4sIG9yZyksXG4gICAgICAgICAgICBlcSh0aGlzLmNvbHMuaXNBY3RpdmUsIHRydWUpLFxuICAgICAgICAgICksXG4gICAgICAgIClcbiAgICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSk7XG5cbiAgICAgIGlmICghdXBkYXRlZCkge1xuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihgRW50aXR5IHdpdGggaWQgJHtpZH0gbm90IGZvdW5kYCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1cGRhdGVkO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBtdWx0aXBsZSBlbnRpdGllcyBtYXRjaGluZyBmaWx0ZXJcbiAgICovXG4gIGFzeW5jIHVwZGF0ZU1hbnkoXG4gICAgZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LFxuICAgIGRhdGE6IFBhcnRpYWw8VFVwZGF0ZT4sXG4gICAgb3JnSWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxURW50aXR5W10+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy5idWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCk7XG4gICAgLy8gT3duLW9yZyB3cml0ZS1waW46IGJ1aWxkQ29uZGl0aW9ucyBhbHNvIG1hdGNoZXMgc3lzdGVtL290aGVyLW9yZyBQVUJMSUNcbiAgICAvLyByb3dzLCBzbyB3aXRob3V0IHRoZSBzdHJpY3Qgb3JnSWQgcGluIGEgZmlsdGVyLWJhc2VkIHVwZGF0ZSBjb3VsZCBtdXRhdGVcbiAgICAvLyBzaGFyZWQgKG9yIGFub3RoZXIgdGVuYW50J3MgcHVibGljKSByZWNvcmRzLiBNaXJyb3IgdXBkYXRlL2RlbGV0ZS9cbiAgICAvLyBidWxrRGVsZXRlLiAoU2VlIHdyaXRlQ29uZGl0aW9ucy4pIEFuIG9yZ0lkLWxlc3MgKHN5c2FkbWluKSBjb250ZXh0IGtlZXBzXG4gICAgLy8gZnVsbCBhY2Nlc3MuXG4gICAgaWYgKG9yZ0lkKSBjb25kaXRpb25zLnB1c2goZXEodGhpcy5nZXRPcmdDb2x1bW4oKSwgb3JnSWQpKTtcblxuICAgIC8vIFNjcnViIGEgY2FsbGVyLXN1cHBsaWVkIG9yZ0lkIChzZWUgdXBkYXRlKCkpIHNvIGEgZmlsdGVyLWJhc2VkIHVwZGF0ZSBjYW4ndFxuICAgIC8vIHJlLWhvbWUgcm93cyBpbnRvIGFub3RoZXIgdGVuYW50LlxuICAgIGNvbnN0IHNhZmVEYXRhID0gdGhpcy5lbmZvcmNlT3JnSWQoZGF0YSk7XG5cbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHRoaXMucm93KHtcbiAgICAgICAgLi4uc2FmZURhdGEsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgdXBkYXRlZEJ5OiB0aGlzLmFjdG9yKHVzZXJJZCksXG4gICAgICB9KSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBUaGUgYHZpc2liaWxpdHlgIHByZWRpY2F0ZSBmb3IgYSBidWxrIHNvZnQtZGVsZXRlLCBtaXJyb3JpbmdcbiAgICogYHJlcXVpcmVWaXNpYmlsaXR5V3JpdGVBY2Nlc3NgIHJ1bmcgZm9yIHJ1bmcgc28gYnVsayBhbmQgc2luZ2xlLXJvdyBkZWxldGVcbiAgICogY2FuIG5ldmVyIGRpc2FncmVlIGFib3V0IHdoYXQgYSBjYWxsZXIgbWF5IHJlbW92ZS5cbiAgICpcbiAgICogUmV0dXJucyBubyBjb25kaXRpb24gYXQgYWxsIGZvciBhIHN5c3RlbSBhZG1pbiwgb3IgZm9yIGFuIGVudGl0eSB3aXRoIG5vXG4gICAqIGB2aXNpYmlsaXR5YCBjb2x1bW4gKG5vdGhpbmcgdG8gZ2F0ZSBvbikuXG4gICAqL1xuICBwcml2YXRlIHZpc2liaWxpdHlEZWxldGVDb25kaXRpb25zKFxuICAgIGFjY2VzczogeyBpc1N5c3RlbUFkbWluOiBib29sZWFuOyBjYW5QdWJsaXNoOiBib29sZWFuIH0gfCB1bmRlZmluZWQsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICAgYWNjZXNzQ29sPzogQW55Q29sdW1uLFxuICAgIGNyZWF0ZWRCeUNvbD86IEFueUNvbHVtbixcbiAgKTogU1FMW10ge1xuICAgIGlmICghYWNjZXNzQ29sKSByZXR1cm4gW107XG4gICAgaWYgKCFhY2Nlc3MgfHwgYWNjZXNzLmlzU3lzdGVtQWRtaW4pIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHJ1bmdzOiBTUUxbXSA9IFtlcShhY2Nlc3NDb2wsICdvcmcnKV07XG4gICAgLy8gYHByaXZhdGVgIGlzIGF1dGhvci1vbmx5LiBXaXRoIG5vIGF1dGhvciBjb2x1bW4gb3Igbm8gY2FsbGVyIGlkZW50aXR5IHdlXG4gICAgLy8gY2Fubm90IHByb3ZlIGF1dGhvcnNoaXAsIHNvIHRoZSBydW5nIGlzIHNpbXBseSBub3Qgb2ZmZXJlZCAoZmFpbCBjbG9zZWQpXG4gICAgLy8gcmF0aGVyIHRoYW4gbWF0Y2hpbmcgZXZlcnkgcHJpdmF0ZSByb3cuXG4gICAgaWYgKGNyZWF0ZWRCeUNvbCAmJiB1c2VySWQpIHtcbiAgICAgIHJ1bmdzLnB1c2goYW5kKGVxKGFjY2Vzc0NvbCwgJ3ByaXZhdGUnKSwgZXEoY3JlYXRlZEJ5Q29sLCB1c2VySWQpKSBhcyBTUUwpO1xuICAgIH1cbiAgICBpZiAoYWNjZXNzLmNhblB1Ymxpc2gpIHJ1bmdzLnB1c2goZXEoYWNjZXNzQ29sLCAncHVibGljJykpO1xuXG4gICAgcmV0dXJuIFtvciguLi5ydW5ncykgYXMgU1FMXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTb2Z0LWRlbGV0ZSBtdWx0aXBsZSBlbnRpdGllcyBieSBJRHMgaW4gYSBzaW5nbGUgYmF0Y2ggb3BlcmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgYnVsa0RlbGV0ZShcbiAgICBpZHM6IHN0cmluZ1tdLFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICAgLyoqXG4gICAgICogVGhlIGNhbGxlcidzIGF1dGhvcml0eSBvbiB0aGUgdGhyZWUtcnVuZyBgdmlzaWJpbGl0eWAgbGFkZGVyLiBPbWl0IChvclxuICAgICAqIHBhc3MgYGlzU3lzdGVtQWRtaW46IHRydWVgKSBmb3IgYW4gdW5yZXN0cmljdGVkIGRlbGV0ZS4gVGhlIHJ1bmdzIG1pcnJvclxuICAgICAqIGByZXF1aXJlVmlzaWJpbGl0eVdyaXRlQWNjZXNzYCBleGFjdGx5LCBzbyBidWxrIGFuZCBzaW5nbGUtcm93IGRlbGV0ZSBhZ3JlZTpcbiAgICAgKiAgIC0gYHByaXZhdGVgIOKGkiBhdXRob3Igb25seSAoYGNyZWF0ZWRCeSA9PT0gdXNlcklkYClcbiAgICAgKiAgIC0gYG9yZ2AgICAgIOKGkiBhbnkgbWVtYmVyIG9mIHRoZSBvcmcgKHBsYWluIGA6d3JpdGVgKVxuICAgICAqICAgLSBgcHVibGljYCAg4oaSIHJlcXVpcmVzIHRoZSBlbnRpdHkncyBwdWJsaXNoIHBlcm1pc3Npb25cbiAgICAgKi9cbiAgICBhY2Nlc3M/OiB7IGlzU3lzdGVtQWRtaW46IGJvb2xlYW47IGNhblB1Ymxpc2g6IGJvb2xlYW4gfSxcbiAgKTogUHJvbWlzZTxURW50aXR5W10+IHtcbiAgICBpZiAoaWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICAvLyBPd25lci1zY29wZSB0aGUgYnVsayBzb2Z0LWRlbGV0ZTogYnVpbGRDb25kaXRpb25zIGFsc28gbWF0Y2hlcyBzeXN0ZW0vb3RoZXJcbiAgICAvLyAtb3JnIFBVQkxJQyByb3dzLCBzbyB3aXRob3V0IHRoZSBzdHJpY3Qgb3JnSWQgcGluIGEgdGVuYW50IGNvdWxkIGRlbGV0ZVxuICAgIC8vIHNoYXJlZCByZWNvcmRzIGJ5IGlkLiAoU2VlIHdyaXRlQ29uZGl0aW9ucy4pXG4gICAgY29uc3QgYWNjZXNzQ29sID0gdGhpcy5jb2xzLnZpc2liaWxpdHk7XG4gICAgY29uc3QgY3JlYXRlZEJ5Q29sID0gdGhpcy5jb2xzLmNyZWF0ZWRCeTtcbiAgICBjb25zdCBjb25kaXRpb25zID0gW1xuICAgICAgaW5BcnJheSh0aGlzLmNvbHMuaWQsIGlkcyksXG4gICAgICAuLi50aGlzLmJ1aWxkQ29uZGl0aW9ucyh7fSBhcyBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZCksXG4gICAgICAvLyBUZW5hbnQgY29sdW1uIChnZXRPcmdDb2x1bW4sIGFzc2VydGVkIG5vbi1udWxsKSDigJQgY29uc2lzdGVudCB3aXRoXG4gICAgICAvLyB3cml0ZUNvbmRpdGlvbnM7IG5vIHNpbGVudCBmYWlsLW9wZW4gd2hlbiB0aGUgcHJvcGVydHkgaXMgYWJzZW50LlxuICAgICAgLi4uKG9yZ0lkID8gW2VxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKV0gOiBbXSksXG4gICAgICAuLi50aGlzLnZpc2liaWxpdHlEZWxldGVDb25kaXRpb25zKGFjY2VzcywgdXNlcklkLCBhY2Nlc3NDb2wsIGNyZWF0ZWRCeUNvbCksXG4gICAgICAvLyBSZS1kZWxldGluZyBhIHRvbWJzdG9uZSB3b3VsZCByZS1zdGFtcCBpdHMgcHVyZ2UgZGVhZGxpbmUuXG4gICAgICAuLi50aGlzLm5vdFRvbWJzdG9uZWQoKSxcbiAgICBdO1xuXG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAudXBkYXRlKHRoaXMuc2NoZW1hKVxuICAgICAgLnNldCh0aGlzLnJvdyh0aGlzLnRvbWJzdG9uZVNldChub3csIHVzZXJJZCkpKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKTtcblxuICAgIGF3YWl0IFByb21pc2UuYWxsKGRlbGV0ZWQubWFwKGVudGl0eSA9PiB0aGlzLnJ1bkhvb2soKCkgPT4gdGhpcy5vbkFmdGVyRGVsZXRlKGVudGl0eS5pZCwgZW50aXR5LCB1c2VySWQpKSkpO1xuXG4gICAgcmV0dXJuIGRlbGV0ZWQ7XG4gIH1cblxuICAvKiogQ29uZGl0aW9ucyBtYXRjaGluZyBhIEdFTlVJTkUgdG9tYnN0b25lIChgaXNBY3RpdmU9ZmFsc2VgIEFORCBgZGVsZXRlZEF0IElTXG4gICAqICBOT1QgTlVMTGApLCBvcHRpb25hbGx5IHBpbm5lZCB0byBgaWRgIGFuZC9vciBgb3JnSWRgLiBTaW5nbGUgc291cmNlIG9mIHRydXRoXG4gICAqICBmb3IgcmVzdG9yZS9maW5kRGVsZXRlZEJ5SWQvZmluZERlbGV0ZWQgc28gdGhlIFwid2hhdCBpcyBhIHRvbWJzdG9uZVwiIHJ1bGVcbiAgICogIGxpdmVzIGluIG9uZSBwbGFjZS4gKi9cbiAgcHJpdmF0ZSB0b21ic3RvbmVDb25kaXRpb25zKG9yZ0lkPzogc3RyaW5nLCBpZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtcbiAgICAgIGVxKHRoaXMuY29scy5pc0FjdGl2ZSwgZmFsc2UpLFxuICAgICAgc3FsYCR7dGhpcy5jb2xzLmRlbGV0ZWRBdH0gSVMgTk9UIE5VTExgLFxuICAgICAgLi4udGhpcy50b21ic3RvbmVWaXNpYmlsaXR5Q29uZGl0aW9ucygpLFxuICAgIF07XG4gICAgaWYgKGlkICE9PSB1bmRlZmluZWQpIGNvbmRpdGlvbnMudW5zaGlmdCh0aGlzLmV4YWN0SWRDb25kaXRpb24oaWQpKTtcbiAgICBpZiAob3JnSWQpIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLmdldE9yZ0NvbHVtbigpLCBvcmdJZCkpO1xuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBgcHJpdmF0ZWAgcnVuZywgZm9yIFRPTUJTVE9ORSByZWFkcyBhbmQgcmVzdG9yZS5cbiAgICpcbiAgICogRGVsZXRpbmcgYSByb3cgZG9lcyBub3QgZGVjbGFzc2lmeSBpdDogd2l0aG91dCB0aGlzLCB0aGUgXCJyZWNlbnRseVxuICAgKiBkZWxldGVkXCIgbGlzdCAoYW5kIHJlc3RvcmUpIHdvdWxkIGV4cG9zZSBvdGhlciBtZW1iZXJzJyBQUklWQVRFIHJvd3MgdGhhdFxuICAgKiB0aGUgc2FtZSB2aWV3ZXIgY291bGQgbm90IHJlYWQgYmVmb3JlIHRoZXkgd2VyZSBkZWxldGVkLlxuICAgKlxuICAgKiBNaXJyb3JzIHRoZSBsaXZlIHJlYWQgbGFkZGVyIChgdmlzaWJpbGl0eSA8PiAncHJpdmF0ZScgT1IgY3JlYXRlZF9ieSA9IFZgKVxuICAgKiByYXRoZXIgdGhhbiB0aGUgZGVsZXRlIGxhZGRlcjogdGhpcyBnYXRlcyB3aG8gbWF5IFNFRSBhIHRvbWJzdG9uZSwgYW5kIGFcbiAgICogdG9tYnN0b25lIHNob3VsZCBiZSB2aXNpYmxlIHRvIGV4YWN0bHkgd2hvZXZlciBjb3VsZCBzZWUgdGhlIHJvdy4gQVxuICAgKiBzdXBlci1hZG1pbiBhZG1pbmlzdGVycyB0aGUgd2hvbGUgY2F0YWxvZywgc28gdGhlIHJ1bmcgbGlmdHMgZm9yIHRoZW0uXG4gICAqXG4gICAqIEZhaWxzIENMT1NFRDogd2l0aCBubyBhdXRob3IgY29sdW1uIG9yIG5vIHZpZXdlciAoYmFja2dyb3VuZCBqb2JzLCB0aGVcbiAgICogcmV0ZW50aW9uIHN3ZWVwKSB0aGUgcHJpdmF0ZSBydW5nIGlzIG5vdCBvZmZlcmVkIGF0IGFsbCByYXRoZXIgdGhhblxuICAgKiBtYXRjaGluZyBldmVyeSBwcml2YXRlIHJvdy4gYHB1cmdlRXhwaXJlZGAgZGVsaWJlcmF0ZWx5IGRvZXMgbm90IHVzZSB0aGlzIOKAlFxuICAgKiBpdCBydW5zIG9yZy13aWRlIHVuZGVyIGEgc3lzYWRtaW4gc2NvcGUgYW5kIG11c3QgcmVhY2ggZXZlcnkgdG9tYnN0b25lLlxuICAgKi9cbiAgcHJpdmF0ZSB0b21ic3RvbmVWaXNpYmlsaXR5Q29uZGl0aW9ucygpOiBTUUxbXSB7XG4gICAgY29uc3QgYWNjZXNzQ29sID0gdGhpcy5jb2xzLnZpc2liaWxpdHk7XG4gICAgaWYgKCFhY2Nlc3NDb2wpIHJldHVybiBbXTtcbiAgICBjb25zdCBjdHggPSBnZXRUZW5hbnRDb250ZXh0KCk7XG4gICAgaWYgKGN0eD8uaXNTdXBlckFkbWluKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBjcmVhdGVkQnlDb2wgPSB0aGlzLmNvbHMuY3JlYXRlZEJ5O1xuICAgIGNvbnN0IHZpZXdlciA9IGN0eD8udXNlcklkO1xuICAgIGNvbnN0IHJ1bmdzOiBTUUxbXSA9IFtzcWxgJHthY2Nlc3NDb2x9IDw+ICdwcml2YXRlJ2BdO1xuICAgIGlmIChjcmVhdGVkQnlDb2wgJiYgdmlld2VyKSBydW5ncy5wdXNoKGVxKGNyZWF0ZWRCeUNvbCwgdmlld2VyKSk7XG4gICAgcmV0dXJuIFtvciguLi5ydW5ncykgYXMgU1FMXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXN0b3JlIGEgc29mdC1kZWxldGVkICh0b21ic3RvbmVkKSBlbnRpdHk6IGNsZWFyIGBpc0FjdGl2ZWAvYGRlbGV0ZWRBdGAvXG4gICAqIGBkZWxldGVkQnlgL2BwdXJnZUFmdGVyYCBzbyBpdCByZWFwcGVhcnMgaW4gbm9ybWFsIHJlYWRzLlxuICAgKlxuICAgKiBNYXRjaGVzIE9OTFkgYSBnZW51aW5lIHRvbWJzdG9uZSDigJQgYGlzQWN0aXZlID0gZmFsc2VgIEFORCBgZGVsZXRlZEF0IElTIE5PVFxuICAgKiBOVUxMYCDigJQgc28gYSBtZXJlbHkgKmRlYWN0aXZhdGVkKiByb3cgKGlzQWN0aXZlPWZhbHNlLCBubyBkZWxldGVkQXQpIGlzIG5ldmVyXG4gICAqIHNpbGVudGx5IFwicmVzdG9yZWRcIi4gUGlubmVkIHRvIHRoZSBjYWxsZXIncyBvd24gb3JnIChvcmdJZC1sZXNzIHN5c2FkbWluXG4gICAqIGNvbnRleHQgc3BhbnMgb3JncywgbWF0Y2hpbmcgZGVsZXRlL3VwZGF0ZSkuIFJldHVybnMgbnVsbCB3aGVuIHRoZXJlIGlzIG5vXG4gICAqIHN1Y2ggdG9tYnN0b25lIChhbHJlYWR5IGFjdGl2ZSwgcHVyZ2VkLCBvciB1bmtub3duKSBzbyB0aGUgcm91dGUgY2FuIDQwNC5cbiAgICogQSB1bmlxdWUta2V5IGNvbGxpc2lvbiAoYSBsaXZlIHJvdyBhbHJlYWR5IGhvbGRzIHRoZSBrZXkpIHN1cmZhY2VzIGFzIHRoZVxuICAgKiBkcml2ZXIncyB1bmlxdWUtdmlvbGF0aW9uIGZvciB0aGUgcm91dGUgdG8gbWFwIHRvIDQwOSDigJQgaW4gcHJhY3RpY2UgdGhlXG4gICAqIHRvbWJzdG9uZSBJUyB0aGUga2V5IGhvbGRlciwgc28gdGhpcyBpcyBkZWZlbnNpdmUuXG4gICAqL1xuICBhc3luYyByZXN0b3JlKGlkOiBzdHJpbmcsIG9yZ0lkOiBzdHJpbmcsIHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5IHwgbnVsbD4ge1xuICAgIGlmICghdGhpcy5jb2xzLmRlbGV0ZWRBdCkgcmV0dXJuIG51bGw7IC8vIGVudGl0eSBoYXMgbm8gc29mdC1kZWxldGUgbGlmZWN5Y2xlXG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMudG9tYnN0b25lQ29uZGl0aW9ucyhvcmdJZCwgaWQpO1xuXG4gICAgY29uc3QgW3Jlc3RvcmVkXSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAudXBkYXRlKHRoaXMuc2NoZW1hKVxuICAgICAgLnNldCh0aGlzLnJvdyh7XG4gICAgICAgIGlzQWN0aXZlOiB0cnVlLFxuICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIHVwZGF0ZWRCeTogdGhpcy5hY3Rvcih1c2VySWQpLFxuICAgICAgICBkZWxldGVkQXQ6IG51bGwsXG4gICAgICAgIGRlbGV0ZWRCeTogbnVsbCxcbiAgICAgICAgLi4uKHRoaXMuY29scy5wdXJnZUFmdGVyID8geyBwdXJnZUFmdGVyOiBudWxsIH0gOiB7fSksXG4gICAgICB9KSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICBpZiAocmVzdG9yZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuSG9vaygoKSA9PiB0aGlzLm9uQWZ0ZXJSZXN0b3JlKGlkLCByZXN0b3JlZCwgdXNlcklkKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3RvcmVkIHx8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBhIHNvZnQtZGVsZXRlZCBlbnRpdHkgYnkgaWQgKHRoZSBpbnZlcnNlIG9mIHRoZSBkZWZhdWx0IGBpc0FjdGl2ZT10cnVlYFxuICAgKiByZWFkcykg4oCUIHVzZWQgYnkgcmVzdG9yZSByb3V0ZXMgdG8gbG9hZCB0aGUgdG9tYnN0b25lIGZvciBhY2Nlc3MtY29udHJvbFxuICAgKiBnYXRpbmcgYmVmb3JlIHJlc3RvcmluZy4gUmV0dXJucyBudWxsIHVubGVzcyB0aGUgcm93IGV4aXN0cyBBTkQgaXMgYSBnZW51aW5lXG4gICAqIHRvbWJzdG9uZSAoYGlzQWN0aXZlPWZhbHNlYCArIGBkZWxldGVkQXQgSVMgTk9UIE5VTExgKS5cbiAgICovXG4gIGFzeW5jIGZpbmREZWxldGVkQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBpZiAoIXRoaXMuY29scy5kZWxldGVkQXQpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLnRvbWJzdG9uZUNvbmRpdGlvbnMob3JnSWQsIGlkKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCgpXG4gICAgICAuZnJvbSh0aGlzLnNjaGVtYSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAubGltaXQoMSkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICByZXR1cm4gcmVzdWx0c1swXSB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3QgYW4gb3JnJ3Mgc29mdC1kZWxldGVkIHRvbWJzdG9uZXMgKGBpc0FjdGl2ZT1mYWxzZWAgKyBgZGVsZXRlZEF0IElTIE5PVFxuICAgKiBOVUxMYCksIG1vc3QtcmVjZW50bHktZGVsZXRlZCBmaXJzdCDigJQgcG93ZXJzIHRoZSBcInJlY2VudGx5IGRlbGV0ZWRcIiByZXN0b3JlXG4gICAqIFVJLiBSZXR1cm5zIGBbXWAgZm9yIGVudGl0aWVzIHdpdGhvdXQgYSBzb2Z0LWRlbGV0ZSBsaWZlY3ljbGUuIGBsaW1pdGAgaXNcbiAgICogY2xhbXBlZCB0byBbMSwgMjAwXSB0byBrZWVwIHRoZSByZXNwb25zZSBib3VuZGVkICh0aGUgcmV0ZW50aW9uIHN3ZWVwIGhhcmQtXG4gICAqIGRlbGV0ZXMgb2xkIHRvbWJzdG9uZXMgYW55d2F5LCBzbyB0aGlzIGlzIGEgc2hvcnQsIHNlbGYtbGltaXRpbmcgbGlzdCkuXG4gICAqL1xuICBhc3luYyBmaW5kRGVsZXRlZChcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIG9wdHM6IHsgbGltaXQ/OiBudW1iZXI7IG9mZnNldD86IG51bWJlciB9ID0ge30sXG4gICk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgaWYgKCF0aGlzLmNvbHMuZGVsZXRlZEF0KSByZXR1cm4gW107XG4gICAgY29uc3QgbGltaXQgPSBNYXRoLm1pbihNYXRoLm1heCgxLCBvcHRzLmxpbWl0ID8/IDUwKSwgMjAwKTtcbiAgICBjb25zdCBvZmZzZXQgPSBNYXRoLm1heCgwLCBvcHRzLm9mZnNldCA/PyAwKTtcblxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLnRvbWJzdG9uZUNvbmRpdGlvbnMob3JnSWQpO1xuXG4gICAgcmV0dXJuIHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAuc2VsZWN0KClcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5vcmRlckJ5KGRlc2ModGhpcy5jb2xzLmRlbGV0ZWRBdCEpKVxuICAgICAgLmxpbWl0KGxpbWl0KVxuICAgICAgLm9mZnNldChvZmZzZXQpXG4gICAgICAudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG4gIH1cblxuICAvKipcbiAgICogSGFyZC1kZWxldGUgYSBiYXRjaCBvZiB0b21ic3RvbmVzIHdob3NlIHB1cmdlIGRlYWRsaW5lIGhhcyBwYXNzZWRcbiAgICogKGBkZWxldGVkQXQgSVMgTk9UIE5VTEwgQU5EIHB1cmdlX2FmdGVyIDwgbm93YCkuIEJhdGNoZWQgKGBsaW1pdGApIHNvIGFcbiAgICogc3dlZXAgdGljayBzdGF5cyBib3VuZGVkOyB0aGUgcGVyLXNlcnZpY2Ugc3dlZXAgbG9vcHMgdW50aWwgYSB0aWNrIHJldHVybnNcbiAgICogYDwgbGltaXRgLiBSdW5zIGFjcm9zcyBBTEwgb3Jncywgc28gY2FsbGVycyBNVVNUIGludm9rZSBpdCBmcm9tIGEgc3lzYWRtaW5cbiAgICogc2NvcGUgKGBydW5Tb2Z0RGVsZXRlUHVyZ2VgIGVzdGFibGlzaGVzIG9uZSkuIGBvbkJlZm9yZVB1cmdlKGlkcywgdHgpYCB0ZWFyc1xuICAgKiBkb3duIGRlcGVuZGVudHMgbGFja2luZyBPTiBERUxFVEUgQ0FTQ0FERSBpbnNpZGUgdGhlIHNhbWUgdHg7IGBvbkFmdGVyUHVyZ2VgXG4gICAqIGhhbmRsZXMgZXh0ZXJuYWwgc2lkZS1lZmZlY3RzLlxuICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygcm93cyBwdXJnZWQuIE5vLW9wICgwKSBmb3IgZW50aXRpZXMgd2l0aG91dCB0aGUgY29sdW1ucy5cbiAgICovXG4gIGFzeW5jIHB1cmdlRXhwaXJlZChub3c6IERhdGUsIGxpbWl0ID0gNTAwKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAoIXRoaXMuY29scy5kZWxldGVkQXQgfHwgIXRoaXMuY29scy5wdXJnZUFmdGVyKSByZXR1cm4gMDtcbiAgICBjb25zdCBwdXJnZWQgPSBhd2FpdCB0aGlzLnB1cmdlV2hlcmUoW3NxbGAke3RoaXMuY29scy5kZWxldGVkQXR9IElTIE5PVCBOVUxMYCwgc3FsYCR7dGhpcy5jb2xzLnB1cmdlQWZ0ZXJ9IDwgJHtub3d9YF0sIGxpbWl0KTtcbiAgICByZXR1cm4gcHVyZ2VkLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbi1kZW1hbmQgaGFyZC1kZWxldGUgb2YgYSBTSU5HTEUgdG9tYnN0b25lIGJ5IGlkIOKAlCB0aGUgbWFudWFsIGNvdW50ZXJwYXJ0XG4gICAqIHRvIHRoZSByZXRlbnRpb24gc3dlZXAncyBgcHVyZ2VFeHBpcmVkYC4gUGVybWFuZW50bHkgcmVtb3ZlcyB0aGUgcm93IE9OTFlcbiAgICogd2hlbiBpdCBpcyBhIGdlbnVpbmUgdG9tYnN0b25lIChgaXNBY3RpdmU9ZmFsc2VgICsgYGRlbGV0ZWRBdCBJUyBOT1QgTlVMTGApLFxuICAgKiBvcHRpb25hbGx5IHBpbm5lZCB0byBgb3JnSWRgIChhbiBvcmdJZC1sZXNzIHN5c2FkbWluIGNvbnRleHQgc3BhbnMgb3JncyxcbiAgICogbWF0Y2hpbmcgcmVzdG9yZS9kZWxldGUpLiBSdW5zIHRoZSBzYW1lIGBvbkJlZm9yZVB1cmdlYCBkZXBlbmRlbnQgdGVhcmRvd25cbiAgICogaW5zaWRlIHRoZSB0eCBhbmQgdGhlIHNhbWUgYG9uQWZ0ZXJQdXJnZWAgc2lkZS1lZmZlY3RzIGFzIHRoZSBzd2VlcC5cbiAgICpcbiAgICogSWdub3JlcyBgcHVyZ2VBZnRlcmA6IGEgbWFudWFsIHB1cmdlIGZpbmFsaXplcyBhbiBhbHJlYWR5LXNvZnQtZGVsZXRlZCBpdGVtXG4gICAqIGltbWVkaWF0ZWx5IHJhdGhlciB0aGFuIHdhaXRpbmcgZm9yIHRoZSByZXRlbnRpb24gZGVhZGxpbmUuIFJldHVybnMgdGhlXG4gICAqIHB1cmdlZCBpZCwgb3IgbnVsbCB3aGVuIHRoZXJlIGlzIG5vIHN1Y2ggdG9tYnN0b25lIChhbHJlYWR5IGFjdGl2ZSwgcHVyZ2VkLFxuICAgKiBvdXQgb2Ygc2NvcGUsIG9yIHVua25vd24pIHNvIHRoZSByb3V0ZSBjYW4gNDA0LlxuICAgKi9cbiAgYXN5bmMgcHVyZ2VCeUlkKGlkOiBzdHJpbmcsIG9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgaWYgKCF0aGlzLmNvbHMuZGVsZXRlZEF0KSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBbcHVyZ2VkSWRdID0gYXdhaXQgdGhpcy5wdXJnZVdoZXJlKHRoaXMudG9tYnN0b25lQ29uZGl0aW9ucyhvcmdJZCwgaWQpLCAxKTtcbiAgICByZXR1cm4gcHVyZ2VkSWQgPz8gbnVsbDtcbiAgfVxufVxuIl19