@pipeline-builder/pipeline-data 3.4.112 → 3.4.114

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.
@@ -19,6 +19,13 @@ export function drizzleRows(rows) {
19
19
  export function drizzleCount(rows) {
20
20
  return rows;
21
21
  }
22
+ /**
23
+ * Retention before a soft-deleted row becomes purge-eligible, shared across
24
+ * every CrudService entity (unified `SOFT_DELETE_RETENTION_DAYS`, default 30d).
25
+ * Stamped into `purge_after` at delete time; the per-service purge sweep hard-
26
+ * deletes tombstones once it has passed. `0` disables purge-deadline stamping.
27
+ */
28
+ const SOFT_DELETE_RETENTION_MS = Math.max(0, Number.parseInt(process.env.SOFT_DELETE_RETENTION_DAYS ?? '30', 10) || 0) * 24 * 60 * 60 * 1000;
22
29
  export class CrudService {
23
30
  /**
24
31
  * Typed column view of {@link schema}. `PgTable` exposes no static columns, so
@@ -88,6 +95,28 @@ export class CrudService {
88
95
  async onAfterUpdate(_id, _entity, _userId) { }
89
96
  /** Called after an entity is soft-deleted */
90
97
  async onAfterDelete(_id, _entity, _userId) { }
98
+ /** Called after a soft-deleted entity is restored (undo the delete). Override
99
+ * for entities whose restore has side-effects (e.g. re-notify). Best-effort. */
100
+ async onAfterRestore(_id, _entity, _userId) { }
101
+ /** Called (best-effort) with the ids about to be hard-purged, BEFORE the
102
+ * delete, so a subclass can tear down dependents that lack ON DELETE CASCADE.
103
+ * Throwing aborts that batch's purge (rows stay tombstoned, retried next tick). */
104
+ async onBeforePurge(_ids) { }
105
+ /** Called after rows are hard-purged, for external side-effects (e.g. plugin
106
+ * image GC). Best-effort: errors are logged, never block the sweep. */
107
+ async onAfterPurge(_ids) { }
108
+ /** Retention before a soft-deleted row becomes purge-eligible. Defaults to the
109
+ * shared `SOFT_DELETE_RETENTION_DAYS`; override per entity for a bespoke window. */
110
+ get softDeleteRetentionMs() {
111
+ return SOFT_DELETE_RETENTION_MS;
112
+ }
113
+ /** The `purge_after` value to stamp on a soft-delete: `now + retention`, or the
114
+ * spread-friendly empty object when the entity has no `purge_after` column. */
115
+ purgeAfterStamp(now) {
116
+ if (!this.cols.purgeAfter || this.softDeleteRetentionMs <= 0)
117
+ return {};
118
+ return { purgeAfter: new Date(now.getTime() + this.softDeleteRetentionMs) };
119
+ }
91
120
  /**
92
121
  * Org → team hierarchy: when a read is widened to a parent org (`parentOrgId`
93
122
  * set), the parent's rows are outside the caller's RLS scope, so the read must
@@ -324,6 +353,14 @@ export class CrudService {
324
353
  target: this.conflictTarget,
325
354
  set: {
326
355
  ...safeData,
356
+ // RESURRECT on re-create: `delete` soft-deletes (isActive=false + deletedAt/
357
+ // deletedBy set), but the unique constraint keeps the tombstoned row, so a
358
+ // re-create with the same conflict key lands here. Without resetting these,
359
+ // the row's body updates but it stays soft-deleted and never reappears
360
+ // (reads default to isActive=true). Matches the pipeline/plugin overrides.
361
+ isActive: true,
362
+ deletedAt: null,
363
+ deletedBy: null,
327
364
  updatedAt: new Date(),
328
365
  updatedBy: userId || 'system',
329
366
  },
@@ -374,14 +411,17 @@ export class CrudService {
374
411
  */
375
412
  async delete(id, orgId, userId) {
376
413
  const conditions = this.writeConditions(id, orgId);
414
+ const now = new Date();
377
415
  const [deleted] = await withTenantTx(async (tx) => tx
378
416
  .update(this.schema)
379
417
  .set({
380
418
  isActive: false,
381
- updatedAt: new Date(),
419
+ updatedAt: now,
382
420
  updatedBy: userId || 'system',
383
- deletedAt: new Date(),
421
+ deletedAt: now,
384
422
  deletedBy: userId || 'system',
423
+ // Stamp the purge deadline so the retention sweep can hard-delete later.
424
+ ...this.purgeAfterStamp(now),
385
425
  })
386
426
  .where(and(...conditions))
387
427
  .returning().then(r => drizzleRows(r)));
@@ -509,6 +549,13 @@ export class CrudService {
509
549
  }
510
550
  set[key] = sql `excluded.${sql.identifier(name)}`;
511
551
  }
552
+ // RESURRECT on bulk re-create (matches the single-row create): reset the
553
+ // soft-delete columns explicitly rather than rely on `excluded.*` + column
554
+ // defaults, so a re-created same-key row is always reactivated, not left
555
+ // tombstoned. All CrudService entities carry these (delete() sets all three).
556
+ set.isActive = true;
557
+ set.deletedAt = null;
558
+ set.deletedBy = null;
512
559
  return set;
513
560
  }
514
561
  async bulkCreate(items, userId) {
@@ -577,11 +624,148 @@ export class CrudService {
577
624
  updatedBy: user,
578
625
  deletedAt: now,
579
626
  deletedBy: user,
627
+ // Stamp the purge deadline so the retention sweep can hard-delete later.
628
+ ...this.purgeAfterStamp(now),
580
629
  })
581
630
  .where(and(...conditions))
582
631
  .returning().then(r => drizzleRows(r)));
583
632
  await Promise.all(deleted.map(entity => this.onAfterDelete(entity.id, entity, userId).catch(err => this._logger.warn('Lifecycle hook failed', { error: String(err) }))));
584
633
  return deleted;
585
634
  }
635
+ /**
636
+ * Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/
637
+ * `deletedBy`/`purgeAfter` so it reappears in normal reads.
638
+ *
639
+ * Matches ONLY a genuine tombstone — `isActive = false` AND `deletedAt IS NOT
640
+ * NULL` — so a merely *deactivated* row (isActive=false, no deletedAt) is never
641
+ * silently "restored". Pinned to the caller's own org (orgId-less sysadmin
642
+ * context spans orgs, matching delete/update). Returns null when there is no
643
+ * such tombstone (already active, purged, or unknown) so the route can 404.
644
+ * A unique-key collision (a live row already holds the key) surfaces as the
645
+ * driver's unique-violation for the route to map to 409 — in practice the
646
+ * tombstone IS the key holder, so this is defensive.
647
+ */
648
+ async restore(id, orgId, userId) {
649
+ if (!this.cols.deletedAt)
650
+ return null; // entity has no soft-delete lifecycle
651
+ const conditions = [
652
+ this.exactIdCondition(id),
653
+ eq(this.cols.isActive, false),
654
+ sql `${this.cols.deletedAt} IS NOT NULL`,
655
+ ];
656
+ if (orgId)
657
+ conditions.push(eq(this.getOrgColumn(), orgId));
658
+ const [restored] = await withTenantTx(async (tx) => tx
659
+ .update(this.schema)
660
+ .set({
661
+ isActive: true,
662
+ updatedAt: new Date(),
663
+ updatedBy: userId || 'system',
664
+ deletedAt: null,
665
+ deletedBy: null,
666
+ ...(this.cols.purgeAfter ? { purgeAfter: null } : {}),
667
+ })
668
+ .where(and(...conditions))
669
+ .returning().then(r => drizzleRows(r)));
670
+ if (restored) {
671
+ try {
672
+ await this.onAfterRestore(id, restored, userId);
673
+ }
674
+ catch (err) {
675
+ this._logger.warn('Lifecycle hook failed', { error: String(err) });
676
+ }
677
+ }
678
+ return restored || null;
679
+ }
680
+ /**
681
+ * Read a soft-deleted entity by id (the inverse of the default `isActive=true`
682
+ * reads) — used by restore routes to load the tombstone for access-control
683
+ * gating before restoring. Returns null unless the row exists AND is a genuine
684
+ * tombstone (`isActive=false` + `deletedAt IS NOT NULL`).
685
+ */
686
+ async findDeletedById(id, orgId, parentOrgId) {
687
+ if (!this.cols.deletedAt)
688
+ return null;
689
+ const conditions = [
690
+ this.exactIdCondition(id),
691
+ eq(this.cols.isActive, false),
692
+ sql `${this.cols.deletedAt} IS NOT NULL`,
693
+ ];
694
+ if (orgId)
695
+ conditions.push(eq(this.getOrgColumn(), orgId));
696
+ const results = await this.runRead(parentOrgId, () => withTenantTx(async (tx) => tx
697
+ .select()
698
+ .from(this.schema)
699
+ .where(and(...conditions))
700
+ .limit(1).then(r => drizzleRows(r))));
701
+ return results[0] || null;
702
+ }
703
+ /**
704
+ * List an org's soft-deleted tombstones (`isActive=false` + `deletedAt IS NOT
705
+ * NULL`), most-recently-deleted first — powers the "recently deleted" restore
706
+ * UI. Returns `[]` for entities without a soft-delete lifecycle. `limit` is
707
+ * clamped to [1, 200] to keep the response bounded (the retention sweep hard-
708
+ * deletes old tombstones anyway, so this is a short, self-limiting list).
709
+ */
710
+ async findDeleted(orgId, opts = {}, parentOrgId) {
711
+ if (!this.cols.deletedAt)
712
+ return [];
713
+ const limit = Math.min(Math.max(1, opts.limit ?? 50), 200);
714
+ const offset = Math.max(0, opts.offset ?? 0);
715
+ const conditions = [
716
+ eq(this.cols.isActive, false),
717
+ sql `${this.cols.deletedAt} IS NOT NULL`,
718
+ ];
719
+ if (orgId)
720
+ conditions.push(eq(this.getOrgColumn(), orgId));
721
+ return this.runRead(parentOrgId, () => withTenantTx(async (tx) => tx
722
+ .select()
723
+ .from(this.schema)
724
+ .where(and(...conditions))
725
+ .orderBy(desc(this.cols.deletedAt))
726
+ .limit(limit)
727
+ .offset(offset)
728
+ .then(r => drizzleRows(r))));
729
+ }
730
+ /**
731
+ * Hard-delete a batch of tombstones whose purge deadline has passed
732
+ * (`deletedAt IS NOT NULL AND purge_after < now`). Batched (`limit`) so a
733
+ * sweep tick stays bounded; the per-service sweep loops until a tick returns
734
+ * `< limit`. Runs across ALL orgs, so callers MUST invoke it from a system
735
+ * (no-tenant) context. `onBeforePurge` tears down dependents lacking ON DELETE
736
+ * CASCADE (inside the tx); `onAfterPurge` handles external side-effects.
737
+ * Returns the number of rows purged. No-op (0) for entities without the columns.
738
+ */
739
+ async purgeExpired(now, limit = 500) {
740
+ if (!this.cols.deletedAt || !this.cols.purgeAfter)
741
+ return 0;
742
+ const purgedIds = await withTenantTx(async (tx) => {
743
+ const doomed = await tx
744
+ // `as any`: cols.id is the base `AnyColumn`, which drizzle's typed
745
+ // select-field map doesn't accept directly (same friction the `.set()`
746
+ // casts elsewhere in this file work around). Result is re-typed below.
747
+ .select({ id: this.cols.id })
748
+ .from(this.schema)
749
+ .where(and(sql `${this.cols.deletedAt} IS NOT NULL`, sql `${this.cols.purgeAfter} < ${now}`))
750
+ .limit(limit)
751
+ .then(r => r.map(d => String(d.id)));
752
+ if (doomed.length === 0)
753
+ return [];
754
+ // Dependent teardown must happen inside the same tx so a FK-blocking child
755
+ // can't strand the parent. A throw here aborts this batch (retried next tick).
756
+ await this.onBeforePurge(doomed);
757
+ await tx.delete(this.schema).where(inArray(this.cols.id, doomed));
758
+ return doomed;
759
+ });
760
+ if (purgedIds.length > 0) {
761
+ try {
762
+ await this.onAfterPurge(purgedIds);
763
+ }
764
+ catch (err) {
765
+ this._logger.warn('Lifecycle hook failed', { error: String(err) });
766
+ }
767
+ }
768
+ return purgedIds.length;
769
+ }
586
770
  }
587
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J1ZC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9jcnVkLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBR3JGLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU5RixtRkFBbUY7QUFDbkYsTUFBTSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBSSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDakYsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUUxRTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUksSUFBYTtJQUMxQyxPQUFPLElBQVcsQ0FBQztBQUNyQixDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBYTtJQUN4QyxPQUFPLElBQTJCLENBQUM7QUFDckMsQ0FBQztBQTJGRCxNQUFNLE9BQWdCLFdBQVc7SUFTL0I7Ozs7OztPQU1HO0lBQ0gsSUFBWSxJQUFJO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBZ0MsQ0FBQztJQUMvQyxDQUFDO0lBeUJnQixPQUFPLEdBQUcsWUFBWSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBRXhEO1FBQ0Usd0VBQXdFO1FBQ3hFLHlFQUF5RTtRQUN6RSxzRUFBc0U7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RSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDdEUsQ0FBQztRQUVGLE1BQU0sT0FBTyxHQUFHLE1BQU0sWUFBWSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUU7YUFDaEQsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7YUFDbkIsR0FBRyxDQUFDO1lBQ0gsUUFBUSxFQUFFLEtBQUs7WUFDZixTQUFTLEVBQUUsR0FBRztZQUNkLFNBQVMsRUFBRSxJQUFJO1lBQ2YsU0FBUyxFQUFFLEdBQUc7WUFDZCxTQUFTLEVBQUUsSUFBSTtTQUNULENBQUM7YUFDUixLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUM7YUFDekIsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVuRCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUNuQixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUN4RCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUNuRSxDQUNGLENBQ0YsQ0FBQztRQUVGLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBOb3RGb3VuZEVycm9yLCBjcmVhdGVMb2dnZXIgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBTUUwsIGVxLCBhbmQsIGFzYywgZGVzYywgc3FsLCBpbkFycmF5LCBnZXRUYWJsZUNvbHVtbnMgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5pbXBvcnQgdHlwZSB7IFBnVGFibGUgfSBmcm9tICdkcml6emxlLW9ybS9wZy1jb3JlJztcbmltcG9ydCB7IHdpdGhUZW5hbnRUeCwgcnVuV2l0aFRlbmFudENvbnRleHQsIGdldFRlbmFudENvbnRleHQgfSBmcm9tICcuLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuLyoqIFBhZ2luYXRpb24gZGVmYXVsdHMg4oCUIHJlYWQgZnJvbSBlbnYgdG8gbWF0Y2ggQ29yZUNvbnN0YW50cyBpbiBwaXBlbGluZS1jb3JlLiAqL1xuY29uc3QgREVGQVVMVF9QQUdFX0xJTUlUID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuREVGQVVMVF9QQUdFX0xJTUlUIHx8ICcxMDAnLCAxMCk7XG5jb25zdCBNQVhfUEFHRV9MSU1JVCA9IHBhcnNlSW50KHByb2Nlc3MuZW52Lk1BWF9QQUdFX0xJTUlUIHx8ICcxMDAwJywgMTApO1xuXG4vKipcbiAqIENhc3QgRHJpenpsZSBxdWVyeSByZXN1bHRzIHRvIGEgdHlwZWQgYXJyYXkuXG4gKiBEcml6emxlJ3MgZ2VuZXJpYyByZXR1cm4gdHlwZSAoYFBnU2VsZWN0QmFzZTwuLi4+YCkgZG9lc24ndCBuYXJyb3cgdG8gb3VyXG4gKiBlbnRpdHkgZ2VuZXJpY3MsIHNvIGFuIGV4cGxpY2l0IGNhc3QgaXMgbmVlZGVkLiBDZW50cmFsaXNlZCBoZXJlIHNvIGV2ZXJ5XG4gKiBjYWxsLXNpdGUgc3RheXMgb25lLWxpbmVyIGNsZWFuIGFuZCB0aGUgY2FzdCBpcyBkb2N1bWVudGVkIGluIG9uZSBwbGFjZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXp6bGVSb3dzPFQ+KHJvd3M6IHVua25vd24pOiBUW10ge1xuICByZXR1cm4gcm93cyBhcyBUW107XG59XG5cbi8qKiBDYXN0IGEgRHJpenpsZSBhZ2dyZWdhdGUgcmVzdWx0IHRvIGV4dHJhY3QgYFt7IGNvdW50OiBudW1iZXIgfV1gLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXp6bGVDb3VudChyb3dzOiB1bmtub3duKTogW3sgY291bnQ6IG51bWJlciB9XSB7XG4gIHJldHVybiByb3dzIGFzIFt7IGNvdW50OiBudW1iZXIgfV07XG59XG5cbi8qKlxuICogQmFzZSBpbnRlcmZhY2UgZm9yIGVudGl0aWVzIHdpdGggY29tbW9uIGZpZWxkc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VFbnRpdHkge1xuICBpZDogc3RyaW5nO1xuICBvcmdJZDogc3RyaW5nO1xuICBpc0RlZmF1bHQ6IGJvb2xlYW47XG4gIGNyZWF0ZWRBdDogRGF0ZTtcbiAgdXBkYXRlZEF0OiBEYXRlO1xuICBjcmVhdGVkQnk6IHN0cmluZztcbiAgdXBkYXRlZEJ5OiBzdHJpbmc7XG4gIFtrZXk6IHN0cmluZ106IHVua25vd247XG59XG5cbi8qKlxuICogUGFnaW5hdGlvbiBhbmQgc29ydGluZyBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVlcnlPcHRpb25zIHtcbiAgbGltaXQ/OiBudW1iZXI7XG4gIG9mZnNldD86IG51bWJlcjtcbiAgc29ydEJ5Pzogc3RyaW5nO1xuICBzb3J0T3JkZXI/OiAnYXNjJyB8ICdkZXNjJztcbiAgLyoqIFdoZW4gdHJ1ZSwgcnVucyBhIHNlcGFyYXRlIENPVU5UKCopIHF1ZXJ5IHRvIGluY2x1ZGUgZXhhY3QgdG90YWwuIERlZmF1bHQ6IGZhbHNlLiAqL1xuICBpbmNsdWRlVG90YWw/OiBib29sZWFuO1xuICAvKiogQ3Vyc29yLWJhc2VkIHBhZ2luYXRpb246IGZldGNoIHJvd3MgYWZ0ZXIgdGhpcyBjdXJzb3IgdmFsdWUgKHVzZXMgc29ydEJ5IGNvbHVtbikuICovXG4gIGN1cnNvcj86IHN0cmluZztcbiAgLyoqIFNwYXJzZSBmaWVsZHNldDogY29sdW1uIG5hbWVzIHRvIHNlbGVjdC4gUmV0dXJucyBhbGwgY29sdW1ucyB3aGVuIG9taXR0ZWQuICovXG4gIGZpZWxkcz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFBhZ2luYXRlZCByZXN1bHQgd2l0aCBtZXRhZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2luYXRlZFJlc3VsdDxUPiB7XG4gIGRhdGE6IFRbXTtcbiAgLyoqIFRvdGFsIGNvdW50IG9mIG1hdGNoaW5nIGVudGl0aWVzLiBPbmx5IHByZXNlbnQgd2hlbiBpbmNsdWRlVG90YWwgaXMgdHJ1ZS4gKi9cbiAgdG90YWw/OiBudW1iZXI7XG4gIGxpbWl0OiBudW1iZXI7XG4gIG9mZnNldDogbnVtYmVyO1xuICBoYXNNb3JlOiBib29sZWFuO1xuICAvKiogQ3Vyc29yIHBvaW50aW5nIHRvIHRoZSBsYXN0IGl0ZW0sIGZvciBjdXJzb3ItYmFzZWQgcGFnaW5hdGlvbi4gKi9cbiAgbmV4dEN1cnNvcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBYnN0cmFjdCBDUlVEIHNlcnZpY2Ugd2l0aCBtdWx0aS10ZW5hbnQgYWNjZXNzIGNvbnRyb2wgYW5kIHBhZ2luYXRpb24uXG4gKlxuICogU3ViY2xhc3NlcyBiaW5kIHRvIGEgc3BlY2lmaWMgRHJpenpsZSB0YWJsZSBieSBpbXBsZW1lbnRpbmcgYHNjaGVtYWAsXG4gKiBgYnVpbGRDb25kaXRpb25zYCwgYGdldFNvcnRDb2x1bW5gLCBhbmQgdGhlIG9yZy9wcm9qZWN0LWNvbHVtbiBhY2Nlc3NvcnMuXG4gKlxuICogQHR5cGVQYXJhbSBURW50aXR5IC0gRW50aXR5IHR5cGUgZXh0ZW5kaW5nIEJhc2VFbnRpdHlcbiAqIEB0eXBlUGFyYW0gVEZpbHRlciAtIEZpbHRlciB0eXBlIGZvciBxdWVyeSBwYXJhbWV0ZXJzXG4gKiBAdHlwZVBhcmFtIFRJbnNlcnQgLSBJbnNlcnQgRFRPIHR5cGVcbiAqIEB0eXBlUGFyYW0gVFVwZGF0ZSAtIFVwZGF0ZSBEVE8gdHlwZVxuICpcbiAqICoqQSBub3RlIG9uIHRoZSB0eXBlIGNhc3RzLioqIERyaXp6bGUncyByb3cgdHlwZXMgYXJlIGluZmVycmVkIGZyb21cbiAqIGBwZ1RhYmxlKC4uLilgIGFuZCBkb24ndCBnZW5lcmljYWxseSBuYXJyb3cgdGhyb3VnaCB0aGUgYWJzdHJhY3QgYHNjaGVtYWBcbiAqIGdldHRlciwgc28gdGhlIGJhc2UgY2xhc3MgY2FzdHMgcXVlcnkgcmVzdWx0cyB0byBgVEVudGl0eWAgYW5kIGJhY2suIFRoZVxuICogY2FzdCBpcyAqbm90KiBhIHJ1bnRpbWUgc2FmZXR5IGd1YXJhbnRlZSDigJQgaXQgcmVsaWVzIG9uIGVhY2ggc3ViY2xhc3NcbiAqIHBhc3NpbmcgdGhlIG1hdGNoaW5nIGVudGl0eSB0eXBlLiBPcmctc2NvcGluZyBpcyBlbmZvcmNlZCBieSBldmVyeVxuICogc3ViY2xhc3MncyBgYnVpbGRDb25kaXRpb25zYCBpbmplY3RpbmcgYFdIRVJFIG9yZ19pZCA9ICQxYDsgdGhpcyBjbGFzc1xuICogZG9lcyBub3QgYWRkIHRoYXQgZmlsdGVyIGl0c2VsZi5cbiAqXG4gKiAqKkVycm9yIHBvbGljeS4qKiBFcnJvcnMgcHJvcGFnYXRlIHVwIHRvIHRoZSByb3V0ZS1sZXZlbCBoYW5kbGVyXG4gKiAoYHdpdGhSb3V0ZWApOyBubyBjYXRjaC1hbmQtc3dhbGxvdyBoZXJlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjbGFzcyBQaXBlbGluZVNlcnZpY2UgZXh0ZW5kcyBDcnVkU2VydmljZTxQaXBlbGluZSwgUGlwZWxpbmVGaWx0ZXIsIFBpcGVsaW5lSW5zZXJ0LCBQaXBlbGluZVVwZGF0ZT4ge1xuICogICBwcm90ZWN0ZWQgZ2V0IHNjaGVtYSgpIHsgcmV0dXJuIHNjaGVtYS5waXBlbGluZTsgfVxuICogICBwcm90ZWN0ZWQgYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQpIHsgcmV0dXJuIGJ1aWxkUGlwZWxpbmVDb25kaXRpb25zKGZpbHRlciwgb3JnSWQpOyB9XG4gKiAgIHByb3RlY3RlZCBnZXRTb3J0Q29sdW1uKHNvcnRCeSkgeyByZXR1cm4gc29ydENvbHVtbk1hcFtzb3J0QnldID8/IG51bGw7IH1cbiAqICAgcHJvdGVjdGVkIGdldFByb2plY3RDb2x1bW4oKSB7IHJldHVybiBzY2hlbWEucGlwZWxpbmUucHJvamVjdDsgfVxuICogICBwcm90ZWN0ZWQgZ2V0T3JnQ29sdW1uKCkgeyByZXR1cm4gc2NoZW1hLnBpcGVsaW5lLm9yZ0lkOyB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuLyoqIFN0cnVjdHVyYWwgdmlldyBvZiB0aGUgc3ViY2xhc3MgdGFibGUncyBjb2x1bW5zIHRoZSBiYXNlIGNsYXNzIHRvdWNoZXNcbiAqICBkaXJlY3RseS4gYGlkYC9gaXNBY3RpdmVgL2Bpc0RlZmF1bHRgIGFyZSBhbHdheXMgcHJlc2VudCBvbiBhIENSVUQgZW50aXR5O1xuICogIGBhY2Nlc3NNb2RpZmllcmAgb25seSBvbiBwdWJsaWMtdmlzaWJpbGl0eSBlbnRpdGllczsgdGhlIGluZGV4IHNpZ25hdHVyZVxuICogIGNvdmVycyBkeW5hbWljIChzcGFyc2UtZmllbGRzZXQpIGNvbHVtbiBhY2Nlc3MuICovXG5pbnRlcmZhY2UgQ3J1ZENvbHVtbnMge1xuICBpZDogQW55Q29sdW1uO1xuICBpc0FjdGl2ZTogQW55Q29sdW1uO1xuICBpc0RlZmF1bHQ6IEFueUNvbHVtbjtcbiAgYWNjZXNzTW9kaWZpZXI/OiBBbnlDb2x1bW47XG4gIFtrZXk6IHN0cmluZ106IEFueUNvbHVtbiB8IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENydWRTZXJ2aWNlPFxuICBURW50aXR5IGV4dGVuZHMgQmFzZUVudGl0eSxcbiAgVEZpbHRlcixcbiAgVEluc2VydCxcbiAgVFVwZGF0ZSxcbj4ge1xuICAvKiogRHJpenpsZSBzY2hlbWEgdGFibGUgZm9yIHRoaXMgZW50aXR5ICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXQgc2NoZW1hKCk6IFBnVGFibGU7XG5cbiAgLyoqXG4gICAqIFR5cGVkIGNvbHVtbiB2aWV3IG9mIHtAbGluayBzY2hlbWF9LiBgUGdUYWJsZWAgZXhwb3NlcyBubyBzdGF0aWMgY29sdW1ucywgc29cbiAgICogdGhlIGJhc2UgY2xhc3MgcHJldmlvdXNseSByZWFjaGVkIGZvciBgKHRoaXMuc2NoZW1hIGFzIGFueSkuaWRgIGV0Yy4gYXQgZWFjaFxuICAgKiB1c2U7IGNlbnRyYWxpemUgdGhhdCBzaW5nbGUgdW5hdm9pZGFibGUgY2FzdCBoZXJlIHNvIGNhbGxlcnMgZ2V0IHN0cnVjdHVyZWQsXG4gICAqIHR5cGVkIGFjY2VzcyBpbnN0ZWFkLiBgYWNjZXNzTW9kaWZpZXJgIGlzIG9wdGlvbmFsIChub3QgZXZlcnkgZW50aXR5IGhhcyBpdClcbiAgICogYW5kIHRoZSBpbmRleCBzaWduYXR1cmUgY292ZXJzIGR5bmFtaWMgc3BhcnNlLWZpZWxkc2V0IGNvbHVtbiBsb29rdXAuXG4gICAqL1xuICBwcml2YXRlIGdldCBjb2xzKCk6IENydWRDb2x1bW5zIHtcbiAgICByZXR1cm4gdGhpcy5zY2hlbWEgYXMgdW5rbm93biBhcyBDcnVkQ29sdW1ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBTUUwgY29uZGl0aW9ucyBmb3IgZmlsdGVyaW5nIGVudGl0aWVzLlxuICAgKiBgcGFyZW50T3JnSWRgIChvcmcg4oaSIHRlYW0gaGllcmFyY2h5KSBpcyBvcHRpb25hbCBhbmQgb25seSBob25vcmVkIGJ5XG4gICAqIHNlcnZpY2VzIHRoYXQgb3B0IGludG8gcGFyZW50LWluaGVyaXRlZCB2aXNpYmlsaXR5IChlLmcuIHBsdWdpbnMpLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdO1xuXG4gIC8qKiBHZXQgdGhlIHNjaGVtYSBjb2x1bW4gZm9yIHNvcnRpbmcgYnkgZmllbGQgbmFtZSAqL1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0U29ydENvbHVtbihzb3J0Qnk6IHN0cmluZyk6IEFueUNvbHVtbiB8IG51bGw7XG5cbiAgLyoqIEdldCB0aGUgcHJvamVjdCBjb2x1bW4gZm9yIHNldERlZmF1bHQgc2NvcGluZyAobnVsbCBpZiBlbnRpdHkgaGFzIG5vIHByb2plY3Qgc2NvcGUpICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRQcm9qZWN0Q29sdW1uKCk6IEFueUNvbHVtbiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdGVuYW50IG9yZy1pZCBjb2x1bW4uIFVzZWQgYm90aCB0byBzY29wZSBgc2V0RGVmYXVsdGAgYW5kIHRvIHBpblxuICAgKiBldmVyeSB3cml0ZSAodXBkYXRlL2RlbGV0ZS9idWxrRGVsZXRlKSB0byB0aGUgY2FsbGVyJ3Mgb3duIG9yZyDigJQgc28gaXQgTVVTVFxuICAgKiBiZSB0aGUgdGVuYW50IGBvcmdJZGAgY29sdW1uLCBub3QgYSBkaXNwbGF5L25hbWUgY29sdW1uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldE9yZ0NvbHVtbigpOiBBbnlDb2x1bW47XG5cbiAgLyoqIEdldCB0aGUgdW5pcXVlIGNvbnN0cmFpbnQgY29sdW1ucyBmb3Igb25Db25mbGljdERvVXBkYXRlICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXQgY29uZmxpY3RUYXJnZXQoKTogQW55Q29sdW1uW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdjcnVkLXNlcnZpY2UnKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBGYWlsIGZhc3QgaWYgYSBzdWJjbGFzcyBkb2Vzbid0IGV4cG9zZSBhIHRlbmFudCBvcmcgY29sdW1uLiBUaGUgd3JpdGVcbiAgICAvLyBwYXRocyAod3JpdGVDb25kaXRpb25zIC8gYnVsa0RlbGV0ZSkgcGluIG11dGF0aW9ucyB0byB0aGUgY2FsbGVyJ3Mgb3duXG4gICAgLy8gb3JnIHRocm91Z2ggaXQ7IGEgbWlzc2luZyBjb2x1bW4gd291bGQgc2lsZW50bHkgZHJvcCB0aGF0IGd1YXJkIOKAlCBhXG4gICAgLy8gY3Jvc3MtdGVuYW50IGZhaWwtb3BlbiDigJQgc28gYXNzZXJ0IGl0cyBwcmVzZW5jZSB1cCBmcm9udC5cbiAgICBpZiAodGhpcy5nZXRPcmdDb2x1bW4oKSA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogZ2V0T3JnQ29sdW1uKCkgbXVzdCByZXR1cm4gdGhlIHRlbmFudCBvcmcgY29sdW1uYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEJ1aWxkIGNvbmRpdGlvbnMgZm9yIGEgc2luZ2xlIGVudGl0eSBieSBJRC5cbiAgICogIGBwYXJlbnRPcmdJZGAgd2lkZW5zIHZpc2liaWxpdHkgdG8gYSBwYXJlbnQgb3JnJ3MgcHVibGljIHJvd3MgKG9yZyDihpIgdGVhbVxuICAgKiAgaGllcmFyY2h5KSDigJQgc2FtZSBvcHQtaW4gc2VtYW50aWNzIGFzIGBmaW5kYC9gZmluZFBhZ2luYXRlZGAuIE9taXR0ZWQgYnkgdGhlXG4gICAqICB3cml0ZSBwYXRoIChgd3JpdGVDb25kaXRpb25zYCksIHdoaWNoIG11c3Qgc3RheSBvd24tb3JnIHNjb3BlZC4gKi9cbiAgcHJpdmF0ZSBpZENvbmRpdGlvbnMoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogU1FMW10ge1xuICAgIHJldHVybiB0aGlzLmJ1aWxkQ29uZGl0aW9ucyh7IGlkIH0gYXMgdW5rbm93biBhcyBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmRpdGlvbnMgZm9yIGEgTVVUQVRJT04gKHVwZGF0ZS9kZWxldGUpIG9mIGEgc2luZ2xlIGVudGl0eS5cbiAgICpcbiAgICogYGlkQ29uZGl0aW9uc2AgcmV1c2VzIHRoZSBSRUFEIGFjY2Vzcy1jb250cm9sIGNsYXVzZSwgd2hpY2ggYWxzbyBtYXRjaGVzXG4gICAqIHN5c3RlbS1vcmcgLyBvdGhlci1vcmcgUFVCTElDIHJlY29yZHMg4oCUIHNvIHdpdGhvdXQgYW4gZXh0cmEgb3duZXJzaGlwIHBpbiBhbnlcbiAgICogdGVuYW50IGNvdWxkIHVwZGF0ZSBvciBzb2Z0LWRlbGV0ZSBhbm90aGVyIG9yZydzIChvciB0aGUgc3lzdGVtIG9yZydzKSBwdWJsaWNcbiAgICogcmVjb3Jkcy4gQU5EIGEgc3RyaWN0IGBvcmdJZCA9PT0gY2FsbGVyYCBwcmVkaWNhdGU6IHRoZSByZWFkIGNsYXVzZSdzXG4gICAqIHB1YmxpYy1PUiBicmFuY2ggcmVxdWlyZXMgYG9yZ19pZCA9ICdzeXN0ZW0nYCwgd2hpY2ggdGhlbiBjYW4ndCBiZSBzYXRpc2ZpZWQsXG4gICAqIGxlYXZpbmcgb25seSBvd24tb3JnIHJvd3MuIG9yZ0lkLWxlc3MgKHN5c2FkbWluKSBjb250ZXh0IGtlZXBzIGZ1bGwgYWNjZXNzLlxuICAgKi9cbiAgcHJpdmF0ZSB3cml0ZUNvbmRpdGlvbnMoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuaWRDb25kaXRpb25zKGlkLCBvcmdJZCk7XG4gICAgLy8gUGluIHRoZSBtdXRhdGlvbiB0byB0aGUgY2FsbGVyJ3Mgb3duIG9yZyB2aWEgdGhlIHRlbmFudCBjb2x1bW5cbiAgICAvLyAoZ2V0T3JnQ29sdW1uLCBhc3NlcnRlZCBub24tbnVsbCBpbiB0aGUgY29uc3RydWN0b3IpIOKAlCBjb25zaXN0ZW50IHdpdGhcbiAgICAvLyBzZXREZWZhdWx0IGFuZCB3aXRob3V0IHRoZSBvbGQgc2lsZW50IGZhaWwtb3BlbiB3aGVuIHRoZSBwcm9wZXJ0eSB3YXMgYWJzZW50LlxuICAgIGlmIChvcmdJZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKSk7XG4gICAgLy8gRm9yY2UgRVhBQ1QgaWQgZXF1YWxpdHkgb24gdGhlIG11dGF0aW9uIHBhdGguIGBpZENvbmRpdGlvbnNgIHJldXNlcyB0aGVcbiAgICAvLyBsaXN0LWZpbHRlciBjbGF1c2UsIHdob3NlIGBidWlsZElkRmlsdGVyYCBQUkVGSVgtbWF0Y2hlcyAoYGlkOjp0ZXh0IExJS0VcbiAgICAvLyAndmFsJSdgKSBhbnkgbm9uLWZ1bGwtVVVJRCB2YWx1ZSDigJQgc28gYSBwYXJ0aWFsIGlkIChgREVMRVRFIC94L2FiYCkgd291bGRcbiAgICAvLyBzb2Z0LWRlbGV0ZS9tdXRhdGUgRVZFUlkgb3duLW9yZyByb3cgd2hvc2UgaWQgc3RhcnRzIHdpdGggYGFiYCBhbmQgcmVwb3J0XG4gICAgLy8gdG91Y2hpbmcgb25lLiBBTkRpbmcgYW4gZXhhY3QgYGlkID0gdmFsYCBjb2xsYXBzZXMgdGhlIHByZWZpeCBjbGF1c2UgdG8gYXRcbiAgICAvLyBtb3N0IHRoZSBzaW5nbGUgZXhhY3Qgcm93OyBhIG1hbGZvcm1lZC9wYXJ0aWFsIGlkIHRoZW4gbWF0Y2hlcyBub3RoaW5nXG4gICAgLy8gKOKGkiA0MDQgdmlhIHRoZSBjYWxsZXJzJyBgaWYgKCFkZWxldGVkKWAgZ3VhcmQpIGluc3RlYWQgb2YgbWFzcy1tdXRhdGluZy5cbiAgICBjb25kaXRpb25zLnB1c2godGhpcy5leGFjdElkQ29uZGl0aW9uKGlkKSk7XG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cblxuICAvKiogRXhhY3QgaWQgZXF1YWxpdHksIGxvd2VyLWNhc2VkIHRvIG1hdGNoIGBidWlsZElkRmlsdGVyYCdzIGZ1bGwtVVVJRCBicmFuY2guXG4gICAqICBgc2NoZW1hYCBpcyB0eXBlZCBgUGdUYWJsZWAgKG5vIHN0YXRpYyBgLmlkYCksIHNvIGNhc3Qg4oCUIHNhbWUgcGF0dGVybiB0aGVcbiAgICogIHNvcnQvZGVmYXVsdCBoZWxwZXJzIHVzZSBmb3IgY29sdW1uIGFjY2Vzcy4gKi9cbiAgcHJpdmF0ZSBleGFjdElkQ29uZGl0aW9uKGlkOiBzdHJpbmcpOiBTUUwge1xuICAgIHJldHVybiBlcSh0aGlzLmNvbHMuaWQsIFN0cmluZyhpZCkudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICAvLyBMaWZlY3ljbGUgaG9va3Mg4oCUIG92ZXJyaWRlIGluIHN1YmNsYXNzZXMgdG8gcmVhY3QgdG8gbXV0YXRpb25zXG4gIC8vIFRoZXNlIGFyZSBmaXJlLWFuZC1mb3JnZXQ6IGVycm9ycyBhcmUgbG9nZ2VkIGJ1dCBuZXZlciBibG9jayB0aGUgY2FsbGVyLlxuXG4gIC8qKiBDYWxsZWQgYWZ0ZXIgYSBuZXcgZW50aXR5IGlzIGNyZWF0ZWQgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJDcmVhdGUoX2VudGl0eTogVEVudGl0eSwgX3VzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBDYWxsZWQgYWZ0ZXIgYW4gZW50aXR5IGlzIHVwZGF0ZWQgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJVcGRhdGUoX2lkOiBzdHJpbmcsIF9lbnRpdHk6IFRFbnRpdHksIF91c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogQ2FsbGVkIGFmdGVyIGFuIGVudGl0eSBpcyBzb2Z0LWRlbGV0ZWQgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJEZWxldGUoX2lkOiBzdHJpbmcsIF9lbnRpdHk6IFRFbnRpdHksIF91c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKipcbiAgICogT3JnIOKGkiB0ZWFtIGhpZXJhcmNoeTogd2hlbiBhIHJlYWQgaXMgd2lkZW5lZCB0byBhIHBhcmVudCBvcmcgKGBwYXJlbnRPcmdJZGBcbiAgICogc2V0KSwgdGhlIHBhcmVudCdzIHJvd3MgYXJlIG91dHNpZGUgdGhlIGNhbGxlcidzIFJMUyBzY29wZSwgc28gdGhlIHJlYWQgbXVzdFxuICAgKiBydW4gdW5kZXIgc3lzYWRtaW4gY29udGV4dCDigJQgdGhlIGFjY2Vzcy1jb250cm9sIFdIRVJFIGNsYXVzZSAob3duICsgcGFyZW50ICtcbiAgICogc3lzdGVtIHB1YmxpYywgYnVpbHQgc2VydmVyLXNpZGUgZnJvbSBhIHRydXN0ZWQgSldUIGNsYWltKSBpcyB0aGVuIHRoZVxuICAgKiBhdXRob3JpdGF0aXZlIHRlbmFuY3kgZ2F0ZS4gV2l0aG91dCBgcGFyZW50T3JnSWRgIGl0IHN0YXlzIFJMUy1zY29wZWQuXG4gICAqXG4gICAqIElOVkFSSUFOVCAod2h5IHRoZSBzeXNhZG1pbiBieXBhc3MgaXMgc2FmZSk6IHRoZSBXSEVSRSBjbGF1c2UgaXMgYWx3YXlzXG4gICAqIHNlcnZlci1idWlsdCBieSBgYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKWAgZnJvbSB2YWx1ZXNcbiAgICogZGVyaXZlZCBmcm9tIHRoZSB2YWxpZGF0ZWQgSldUIChgb3JnSWRgID0gYWN0aXZlIG9yZywgYHBhcmVudE9yZ0lkYCA9IHRoZVxuICAgKiBhY3RpdmUgb3JnJ3MgcGFyZW50KS4gTm9uZSBvZiB0aGVtIGlzIGEgcmF3IHVzZXItc3VwcGxpZWQgcHJlZGljYXRlLCBzbyB0aGVcbiAgICogYnlwYXNzIG9ubHkgZXZlciB3aWRlbnMgdGhlIHJlYWQgdG8gdGhlIGNhbGxlcidzIG93biBzdWJ0cmVlICsgc3lzdGVtIHB1YmxpY1xuICAgKiByb3dzIOKAlCBpdCBjYW4gTk9UIGJlIHN0ZWVyZWQgYXQgYW4gYXJiaXRyYXJ5IG9yZy4gTk9URTogdGhpcyBkb2VzIHJlbW92ZSB0aGVcbiAgICogUkxTIGJhY2tzdG9wIGZvciB0aGUgd2lkZW5lZCByZWFkOyBhIHNpbmdsZS1HVUMgYGFwcC5vcmdfaWRgIGNhbid0IGV4cHJlc3NcbiAgICogdGhlIFwib3duIE9SIHBhcmVudCBPUiBzeXN0ZW1cIiBzZXQgdGhlIHBvbGljeSB3b3VsZCBuZWVkLCBzbyByZXBsYWNpbmcgdGhlXG4gICAqIGJ5cGFzcyB3b3VsZCByZXF1aXJlIGEgdGVuYW5jeS1sYXllciBjaGFuZ2UgKGUuZy4gYSBtdWx0aS1vcmcgUkxTIHBvbGljeSkuXG4gICAqIERlZmVycmVkIGRlbGliZXJhdGVseSDigJQgZG8gbm90IHN3YXAgdGhpcyBmb3IgYSBibGFua2V0IGJ5cGFzcyB3aXRob3V0XG4gICAqIHJlLWNoZWNraW5nIHRoZSBXSEVSRSBpcyBzdGlsbCBmdWxseSBzZXJ2ZXItYnVpbHQuXG4gICAqL1xuICBwcml2YXRlIHJ1blJlYWQ8VD4ocGFyZW50T3JnSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCwgZm46ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICByZXR1cm4gcGFyZW50T3JnSWQgPyBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCBmbikgOiBmbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgZW50aXRpZXMgbWF0Y2hpbmcgZmlsdGVyIGNyaXRlcmlhXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKi9cbiAgYXN5bmMgZmluZChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKTtcblxuICAgIHJldHVybiB0aGlzLnJ1blJlYWQocGFyZW50T3JnSWQsICgpID0+IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAuc2VsZWN0KClcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgZW50aXRpZXMgd2l0aCBwYWdpbmF0aW9uIGFuZCBzb3J0aW5nXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFBhZ2luYXRpb24gYW5kIHNvcnRpbmcgb3B0aW9uc1xuICAgKi9cbiAgYXN5bmMgZmluZFBhZ2luYXRlZChcbiAgICBmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sXG4gICAgb3JnSWQ/OiBzdHJpbmcsXG4gICAgb3B0aW9uczogUXVlcnlPcHRpb25zID0ge30sXG4gICAgcGFyZW50T3JnSWQ/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UGFnaW5hdGVkUmVzdWx0PFRFbnRpdHk+PiB7XG4gICAgY29uc3QgeyBsaW1pdDogcmF3TGltaXQgPSBERUZBVUxUX1BBR0VfTElNSVQsIG9mZnNldCA9IDAsIHNvcnRCeSwgc29ydE9yZGVyID0gJ2FzYycsIGluY2x1ZGVUb3RhbCA9IGZhbHNlLCBjdXJzb3IsIGZpZWxkcyB9ID0gb3B0aW9ucztcbiAgICBjb25zdCBsaW1pdCA9IE1hdGgubWluKE1hdGgubWF4KDEsIHJhd0xpbWl0KSwgTUFYX1BBR0VfTElNSVQpO1xuXG4gICAgLy8gQ3Vyc29yIGFuZCBvZmZzZXQgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSDigJQgY3Vyc29yIHRha2VzIHByZWNlZGVuY2VcbiAgICBjb25zdCB1c2VDdXJzb3IgPSAhIShjdXJzb3IgJiYgc29ydEJ5KTtcblxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG5cbiAgICAvLyBDdXJzb3ItYmFzZWQgcGFnaW5hdGlvbjogYWRkIFdIRVJFIGNsYXVzZSBmb3Iga2V5c2V0IHBhZ2luYXRpb25cbiAgICBpZiAodXNlQ3Vyc29yKSB7XG4gICAgICBjb25zdCBzb3J0Q29sdW1uID0gdGhpcy5nZXRTb3J0Q29sdW1uKHNvcnRCeSk7XG4gICAgICBpZiAoc29ydENvbHVtbikge1xuICAgICAgICBjb25zdCBvcCA9IHNvcnRPcmRlciA9PT0gJ2Rlc2MnXG4gICAgICAgICAgPyBzcWxgJHtzb3J0Q29sdW1ufSA8ICR7Y3Vyc29yfWBcbiAgICAgICAgICA6IHNxbGAke3NvcnRDb2x1bW59ID4gJHtjdXJzb3J9YDtcbiAgICAgICAgY29uZGl0aW9ucy5wdXNoKG9wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBXcmFwIHRoZSB3aG9sZSBwYWdpbmF0ZWQgcmVhZCAoU0VMRUNUICsgb3B0aW9uYWwgQ09VTlQpIGluIG9uZVxuICAgIC8vIHRlbmFudCB0eC4gQm90aCBxdWVyaWVzIGFyZSB2aXNpYmlsaXR5LXNjb3BlZCBieSB0aGUgc2FtZSBSTFMgcG9saWN5LFxuICAgIC8vIGFuZCBwaW5uaW5nIHRoZW0gdG8gYSBzaW5nbGUgdHgga2VlcHMgdGhlIGBhcHAub3JnX2lkYCBHVUMgc3RhYmxlXG4gICAgLy8gYmV0d2VlbiB0aGVtLiBXaGVuIHdpZGVuaW5nIHRvIGEgcGFyZW50IG9yZywgdGhlIHdob2xlIHJlYWQgcnVucyB1bmRlclxuICAgIC8vIHN5c2FkbWluIGNvbnRleHQgKHNlZSBydW5SZWFkKSBzbyB0aGUgYWNjZXNzLWNvbnRyb2wgV0hFUkUgaXMgdGhlIGdhdGUuXG4gICAgcmV0dXJuIHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgLy8gQnVpbGQgU0VMRUNUIOKAlCBzcGFyc2UgZmllbGRzZXQgd2hlbiBmaWVsZHMgYXJlIHNwZWNpZmllZC4gVGhlIHNvcnRCeVxuICAgICAgLy8gY29sdW1uIE1VU1QgYmUgcGFydCBvZiB0aGUgcHJvamVjdGlvbiB3aGVuZXZlciBzb3J0aW5nIGlzIGFjdGl2ZTogdGhlXG4gICAgICAvLyBuZXh0IGN1cnNvciBpcyBkZXJpdmVkIGZyb20gYGxhc3RJdGVtW3NvcnRCeV1gIGJlbG93LCBzbyBhIGZpZWxkcyBzZXRcbiAgICAgIC8vIHRoYXQgb21pdHMgc29ydEJ5IHdvdWxkIGxlYXZlIHRoZSBjdXJzb3IgdW5kZWZpbmVkIGFuZCBzdGFsbCB0aGUgY2xpZW50XG4gICAgICAvLyBvbiBwYWdlIDEuIGJ1aWxkRmllbGRTZWxlY3QgYWx3YXlzIGFkZHMgaXQgYmFjayAobGlrZSBgaWRgKS5cbiAgICAgIGNvbnN0IHNlbGVjdFNwZWMgPSBmaWVsZHMgPyB0aGlzLmJ1aWxkRmllbGRTZWxlY3QoZmllbGRzLCBzb3J0QnkpIDogdW5kZWZpbmVkO1xuICAgICAgbGV0IHF1ZXJ5ID0gc2VsZWN0U3BlY1xuICAgICAgICA/IHR4LnNlbGVjdChzZWxlY3RTcGVjIGFzIGFueSkuZnJvbSh0aGlzLnNjaGVtYSkud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgICA6IHR4LnNlbGVjdCgpLmZyb20odGhpcy5zY2hlbWEpLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSk7XG5cbiAgICAgIGlmIChzb3J0QnkpIHtcbiAgICAgICAgY29uc3Qgc29ydENvbHVtbiA9IHRoaXMuZ2V0U29ydENvbHVtbihzb3J0QnkpO1xuICAgICAgICBpZiAoc29ydENvbHVtbikge1xuICAgICAgICAgIHF1ZXJ5ID0gcXVlcnkub3JkZXJCeShzb3J0T3JkZXIgPT09ICdkZXNjJyA/IGRlc2Moc29ydENvbHVtbikgOiBhc2Moc29ydENvbHVtbikpIGFzIGFueTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBGZXRjaCBsaW1pdCsxIHRvIGRldGVjdCBoYXNNb3JlIHdpdGhvdXQgQ09VTlQoKilcbiAgICAgIGNvbnN0IGVmZmVjdGl2ZU9mZnNldCA9IHVzZUN1cnNvciA/IDAgOiBvZmZzZXQ7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgcXVlcnlcbiAgICAgICAgLmxpbWl0KGxpbWl0ICsgMSlcbiAgICAgICAgLm9mZnNldChlZmZlY3RpdmVPZmZzZXQpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSk7XG5cbiAgICAgIGNvbnN0IGhhc01vcmUgPSByb3dzLmxlbmd0aCA+IGxpbWl0O1xuICAgICAgY29uc3QgZGF0YSA9IGhhc01vcmUgPyByb3dzLnNsaWNlKDAsIGxpbWl0KSA6IHJvd3M7XG5cbiAgICAgIGNvbnN0IHJlc3VsdDogUGFnaW5hdGVkUmVzdWx0PFRFbnRpdHk+ID0geyBkYXRhLCBsaW1pdCwgb2Zmc2V0OiBlZmZlY3RpdmVPZmZzZXQsIGhhc01vcmUgfTtcblxuICAgICAgLy8gUHJvdmlkZSBuZXh0IGN1cnNvciBmcm9tIGxhc3QgaXRlbSdzIHNvcnQgY29sdW1uIHZhbHVlXG4gICAgICBpZiAoZGF0YS5sZW5ndGggPiAwICYmIHNvcnRCeSkge1xuICAgICAgICBjb25zdCBsYXN0SXRlbSA9IGRhdGFbZGF0YS5sZW5ndGggLSAxXSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgY29uc3QgY3Vyc29yVmFsdWUgPSBsYXN0SXRlbVtzb3J0QnldO1xuICAgICAgICBpZiAoY3Vyc29yVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlc3VsdC5uZXh0Q3Vyc29yID0gY3Vyc29yVmFsdWUgaW5zdGFuY2VvZiBEYXRlID8gY3Vyc29yVmFsdWUudG9JU09TdHJpbmcoKSA6IFN0cmluZyhjdXJzb3JWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT25seSBydW4gdGhlIENPVU5UKCopIHF1ZXJ5IHdoZW4gdGhlIGNhbGxlciBleHBsaWNpdGx5IG5lZWRzIHRoZSB0b3RhbC5cbiAgICAgIC8vIE11c3QgaW5jbHVkZSBwYXJlbnRPcmdJZCBzbyBgdG90YWxgIG1hdGNoZXMgdGhlIHdpZGVuZWQgZGF0YSBzZXQuXG4gICAgICBpZiAoaW5jbHVkZVRvdGFsKSB7XG4gICAgICAgIGNvbnN0IGJhc2VDb25kaXRpb25zID0gdGhpcy5idWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICAgICAgICBjb25zdCBbY291bnRSZXN1bHRdID0gYXdhaXQgdHhcbiAgICAgICAgICAuc2VsZWN0KHsgY291bnQ6IHNxbDxudW1iZXI+YGNvdW50KCopOjppbnRgIH0pXG4gICAgICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAgICAgLndoZXJlKGFuZCguLi5iYXNlQ29uZGl0aW9ucykpLnRoZW4ociA9PiBkcml6emxlQ291bnQocikpO1xuICAgICAgICByZXN1bHQudG90YWwgPSBjb3VudFJlc3VsdD8uY291bnQgfHwgMDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb2x1bW4gc2VsZWN0aW9uIG1hcCBmb3Igc3BhcnNlIGZpZWxkc2V0cy5cbiAgICogRmFsbHMgYmFjayB0byBmdWxsIHNlbGVjdCBpZiBubyBtYXRjaGluZyBjb2x1bW5zIGZvdW5kLlxuICAgKlxuICAgKiBgc29ydEJ5YCAod2hlbiBzZXQpIGlzIGFsd2F5cyBmb2xkZWQgaW50byB0aGUgcHJvamVjdGlvbiBldmVuIGlmIHRoZSBjYWxsZXInc1xuICAgKiBgZmllbGRzYCBvbWl0cyBpdCDigJQgY3Vyc29yIHBhZ2luYXRpb24gcmVhZHMgdGhlIG5leHQgY3Vyc29yIGZyb20gdGhlIHNvcnRcbiAgICogY29sdW1uJ3MgdmFsdWUgb24gdGhlIGxhc3Qgcm93LCBzbyBkcm9wcGluZyBpdCBmcm9tIHRoZSBTRUxFQ1Qgd291bGQgeWllbGQgYW5cbiAgICogdW5kZWZpbmVkIGN1cnNvciBhbmQgc3RhbGwgcGFnaW5nLiBJbmNsdWRlZCB0aGUgc2FtZSB3YXkgYGlkYCBhbHdheXMgaXMuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkRmllbGRTZWxlY3QoZmllbGRzOiBzdHJpbmdbXSwgc29ydEJ5Pzogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQge1xuICAgIGlmIChmaWVsZHMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY29sdW1uczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICAvLyBBbHdheXMgaW5jbHVkZSBpZCBmb3IgZW50aXR5IGlkZW50aXR5XG4gICAgY29sdW1ucy5pZCA9IHRoaXMuY29scy5pZDtcblxuICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB7XG4gICAgICBpZiAoZmllbGQgPT09ICdpZCcpIGNvbnRpbnVlOyAvLyBBbHJlYWR5IGluY2x1ZGVkXG4gICAgICBjb25zdCBjb2wgPSB0aGlzLmNvbHNbZmllbGRdO1xuICAgICAgaWYgKGNvbCkgY29sdW1uc1tmaWVsZF0gPSBjb2w7XG4gICAgfVxuXG4gICAgLy8gR3VhcmFudGVlIHRoZSBzb3J0IGNvbHVtbiBpcyBzZWxlY3RhYmxlIHNvIHRoZSBuZXh0IGN1cnNvciBjYW4gYmUgcmVhZFxuICAgIC8vIGZyb20gdGhlIGxhc3Qgcm93IChzZWUgZmluZFBhZ2luYXRlZCkuIE5vLW9wIGlmIGFscmVhZHkgYWRkZWQgb3IgdW5rbm93bi5cbiAgICBpZiAoc29ydEJ5ICYmIHNvcnRCeSAhPT0gJ2lkJyAmJiAhKHNvcnRCeSBpbiBjb2x1bW5zKSkge1xuICAgICAgY29uc3Qgc29ydENvbCA9IHRoaXMuY29sc1tzb3J0QnldO1xuICAgICAgaWYgKHNvcnRDb2wpIGNvbHVtbnNbc29ydEJ5XSA9IHNvcnRDb2w7XG4gICAgfVxuXG4gICAgLy8gQXQgbWluaW11bSB3ZSdsbCBoYXZlIHsgaWQgfSwgd2hpY2ggaXMgdmFsaWRcbiAgICByZXR1cm4gY29sdW1ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3VudCBlbnRpdGllcyBtYXRjaGluZyBmaWx0ZXIgY3JpdGVyaWFcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcGFyYW0gb3JnSWQgLSBVc2VyJ3Mgb3JnYW5pemF0aW9uIElEIChvcHRpb25hbCDigJQgb21pdCBmb3IgYW5vbnltb3VzL3N5c3RlbS1wdWJsaWMtb25seSBhY2Nlc3MpXG4gICAqIEBwYXJhbSBwYXJlbnRPcmdJZCAtIE9yZyDihpIgdGVhbSBoaWVyYXJjaHk6IHdpZGVuIHRoZSBjb3VudCB0byB0aGUgcGFyZW50IG9yZydzXG4gICAqICAgcHVibGljIHJvd3MuIE1VU1QgbWlycm9yIGBmaW5kYC9gZmluZFBhZ2luYXRlZGAncyB3aWRlbmluZyAoc2FtZVxuICAgKiAgIGBidWlsZENvbmRpdGlvbnNgIGFyZ3MgKyBzeXNhZG1pbi1zY29wZWQgcmVhZCB2aWEgYHJ1blJlYWRgKSBzbyBhIHBhZ2VkXG4gICAqICAgbGlzdCdzIGB0b3RhbGAgbWF0Y2hlcyB0aGUgcm93cyBhIHdpZGVuZWQgYGZpbmQoKWAgcmV0dXJucyDigJQgb3RoZXJ3aXNlIHRoZVxuICAgKiAgIGNvdW50IG9taXRzIHRoZSBwYXJlbnQncyByb3dzIGFuZCByZXBvcnRzIGEgbmFycm93ZXIgdG90YWwgdGhhbiB0aGUgZGF0YSBzZXQuXG4gICAqL1xuICBhc3luYyBjb3VudChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKTtcblxuICAgIGNvbnN0IFtyZXN1bHRdID0gYXdhaXQgdGhpcy5ydW5SZWFkKHBhcmVudE9yZ0lkLCAoKSA9PiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCh7IGNvdW50OiBzcWw8bnVtYmVyPmBjb3VudCgqKTo6aW50YCB9KVxuICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKS50aGVuKHIgPT4gZHJpenpsZUNvdW50KHIpKSkpO1xuXG4gICAgcmV0dXJuIHJlc3VsdD8uY291bnQgfHwgMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGEgc2luZ2xlIGVudGl0eSBieSBJRFxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBFbnRpdHkgSURcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKiBAcGFyYW0gcGFyZW50T3JnSWQgLSBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB3aWRlbiB2aXNpYmlsaXR5IHRvIHRoZSBwYXJlbnRcbiAgICogICBvcmcncyBwdWJsaWMgcm93cyAoc28gYSB0ZWFtIGNhbiBmZXRjaCBhIHBhcmVudCdzIHB1YmxpYyBlbnRpdHkgYnkgaWQpLlxuICAgKiAgIFNhbWUgb3B0LWluICsgc3lzYWRtaW4tc2NvcGVkIHJlYWQgYXMgYGZpbmRgL2BmaW5kUGFnaW5hdGVkYDsgdGhlXG4gICAqICAgYWNjZXNzLWNvbnRyb2wgV0hFUkUgY2xhdXNlIGlzIHRoZSBhdXRob3JpdGF0aXZlIHRlbmFuY3kgZ2F0ZS5cbiAgICovXG4gIGFzeW5jIGZpbmRCeUlkKGlkOiBzdHJpbmcsIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy5pZENvbmRpdGlvbnMoaWQsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG4gICAgLy8gRXhhY3QgaWQg4oCUIGBmaW5kQnlJZGAgbWVhbnMgVEhFIHJvdyB3aXRoIHRoaXMgaWQsIG5vdCBhIHByZWZpeCBtYXRjaC4gVGhlXG4gICAgLy8gc2hhcmVkIGBidWlsZElkRmlsdGVyYCBwcmVmaXgtbWF0Y2hlcyBub24tZnVsbC1VVUlEIHZhbHVlcyAoYSBsaXN0LXNlYXJjaFxuICAgIC8vIGZlYXR1cmUpLCB3aGljaCBoZXJlIHdvdWxkIHJldHVybiBhbiBhcmJpdHJhcnkgZmlyc3QgcHJlZml4IGhpdCBmb3IgYVxuICAgIC8vIHBhcnRpYWwgaWQ7IHBpbiBpdCB0byBleGFjdCBzbyBhIG1hbGZvcm1lZCBpZCByZXR1cm5zIG51bGwuXG4gICAgY29uZGl0aW9ucy5wdXNoKHRoaXMuZXhhY3RJZENvbmRpdGlvbihpZCkpO1xuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5zZWxlY3QoKVxuICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLmxpbWl0KDEpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpKTtcblxuICAgIHJldHVybiByZXN1bHRzWzBdIHx8IG51bGw7XG4gIH1cblxuICAvLyBNdXRhdGlvbiBvcGVyYXRpb25zXG5cbiAgLyoqXG4gICAqIERlZmVuc2UtaW4tZGVwdGggdGVuYW50IHN0YW1wLiBSTFMgaXMgaW4gb3duZXItYnlwYXNzIG1vZGUsIHNvIHRoZSBhcHAgbGF5ZXJcbiAgICogaXMgdGhlIG9ubHkgdGVuYW50IGdhdGUgb24gd3JpdGVzLiBBIE5PTi1zeXNhZG1pbiBjYWxsZXIgbWF5IG9ubHkgd3JpdGUgaW50b1xuICAgKiBpdHMgT1dOIG9yZywgc28gcGluIHRoZSByb3cgdG8gdGhlIHRydXN0ZWQgdGVuYW50LWNvbnRleHQgb3JnLlxuICAgKlxuICAgKiBUaGUgc3RhbXAgZmlyZXMgd2hlbmV2ZXIgdGhlIHBheWxvYWQncyBgb3JnSWRgIGRpZmZlcnMgZnJvbSB0aGUgY29udGV4dCBvcmcg4oCUXG4gICAqIHdoaWNoIGNvdmVycyBCT1RIIGEgZm9yZ2VkL21pc21hdGNoZWQgYGRhdGEub3JnSWRgIEFORCBhbiBBQlNFTlQgb25lLiBUaGVcbiAgICogYWJzZW50IGNhc2UgaXMgdGhlIGltcG9ydGFudCB0ZW5hbnQtYm91bmRhcnkgZml4OiB0aGUgYG9yZ19pZGAgY29sdW1uIERFRkFVTFRzXG4gICAqIHRvIGBTWVNURU1fT1JHX0lEYCAoc2NoZW1hL3BpcGVsaW5lLnRzLCBzY2hlbWEvcGx1Z2luLnRzKSwgc28gYW4gaW5zZXJ0IHRoYXRcbiAgICogb21pdHMgYG9yZ0lkYCB3b3VsZCBvdGhlcndpc2UgbGFuZCB0aGUgdGVuYW50J3Mgcm93IGluIHRoZSBwdWJsaWMgc3lzdGVtXG4gICAqIGNhdGFsb2cg4oCUIGEgY3Jvc3MtdGVuYW50IGZhaWwtb3Blbi4gQWx3YXlzIGluamVjdGluZyBgY3R4Lm9yZ0lkYCBjbG9zZXMgaXQuXG4gICAqXG4gICAqIFN5c2FkbWluIChhbmQgb3V0LW9mLWNvbnRleHQgd29ya2VyL3N5c3RlbSBwYXRocywgd2hlcmUgYGdldFRlbmFudENvbnRleHQoKWBcbiAgICogaXMgdW5kZWZpbmVkKSBrZWVwIHRoZSBzdXBwbGllZCBvcmcsIG1hdGNoaW5nIHRoZSBSTFMgcG9saWN5XG4gICAqIGBjdXJyZW50X2lzX3N5c2FkbWluKCkgT1Igb3JnX2lkID0gY3VycmVudF9vcmdfaWQoKWAuXG4gICAqL1xuICBwcm90ZWN0ZWQgZW5mb3JjZU9yZ0lkKGRhdGE6IFRJbnNlcnQpOiBUSW5zZXJ0IHtcbiAgICBjb25zdCBjdHggPSBnZXRUZW5hbnRDb250ZXh0KCk7XG4gICAgY29uc3QgZCA9IGRhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgaWYgKGN0eCAmJiAhY3R4LmlzU3VwZXJBZG1pbiAmJiBjdHgub3JnSWQgJiYgZC5vcmdJZCAhPT0gY3R4Lm9yZ0lkKSB7XG4gICAgICAvLyBEaXN0aW5ndWlzaCB0aGUgdHdvIGNhc2VzIHRoYXQgcmVhY2ggaGVyZSBzbyB0aGUgbG9nIHN0YXlzIHVzZWZ1bCBhbmRcbiAgICAgIC8vIHF1aWV0OiBhIFBSRVNFTlQtYnV0LW1pc21hdGNoZWQgYG9yZ0lkYCBpcyBhbiBhY3R1YWwgb3ZlcnJpZGUgYXR0ZW1wdFxuICAgICAgLy8gKHdhcm4pLCB3aGlsZSBhbiBBQlNFTlQgYG9yZ0lkYCBpcyB0aGUgY29tbW9uIG5vcm1hbC13cml0ZSBwYXRoIHRoYXQganVzdFxuICAgICAgLy8gbmVlZHMgdGhlIGRlZmF1bHQgc3RhbXAgKGRlYnVnKSDigJQgbG9nZ2luZyB0aGF0IGF0IHdhcm4gZmxvb2RzIHRoZSBsb2cgb25cbiAgICAgIC8vIGV2ZXJ5IHdyaXRlIHRoYXQgb21pdHMgb3JnSWQuXG4gICAgICBjb25zdCBtZXRhID0geyBzdXBwbGllZDogJ29yZ0lkJyBpbiBkID8gZC5vcmdJZCA6IHVuZGVmaW5lZCwgZW5mb3JjZWQ6IGN0eC5vcmdJZCB9O1xuICAgICAgaWYgKCdvcmdJZCcgaW4gZCkge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignQ3J1ZFNlcnZpY2U6IG92ZXJyaWRpbmcgbWlzbWF0Y2hlZCBvcmcgb24gd3JpdGUnLCBtZXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnQ3J1ZFNlcnZpY2U6IHN0YW1waW5nIHRlbmFudC1jb250ZXh0IG9yZyBvbiB3cml0ZScsIG1ldGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgLi4uZCwgb3JnSWQ6IGN0eC5vcmdJZCB9IGFzIFRJbnNlcnQ7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBlbnRpdHlcbiAgICovXG4gIGFzeW5jIGNyZWF0ZShkYXRhOiBUSW5zZXJ0LCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VEVudGl0eT4ge1xuICAgIGNvbnN0IHNhZmVEYXRhID0gdGhpcy5lbmZvcmNlT3JnSWQoZGF0YSk7XG4gICAgY29uc3QgW2NyZWF0ZWRdID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5pbnNlcnQodGhpcy5zY2hlbWEpXG4gICAgICAudmFsdWVzKHtcbiAgICAgICAgLi4uc2FmZURhdGEsXG4gICAgICAgIGNyZWF0ZWRCeTogdXNlcklkIHx8ICdzeXN0ZW0nLFxuICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgIH0gYXMgYW55KVxuICAgICAgLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogdGhpcy5jb25mbGljdFRhcmdldCBhcyBhbnksXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIC4uLnNhZmVEYXRhLFxuICAgICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICB9KVxuICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpO1xuXG4gICAgLy8gQXdhaXRlZCBpbnRlbnRpb25hbGx5OiBjYWNoZSBpbnZhbGlkYXRpb24gaGFwcGVucyBpbiB0aGUgaG9vaywgYW5kIGFcbiAgICAvLyBmaXJlLWFuZC1mb3JnZXQgcGF0dGVybiBsZXRzIGEgc3Vic2VxdWVudCByZWFkIGluc2lkZSB0aGUgc2FtZSByZXF1ZXN0XG4gICAgLy8gcmV0dXJuIHRoZSBzdGFsZSBwcmUtd3JpdGUgZW50cnkuIFRoZSBob29rIGlzIGV4cGVjdGVkIHRvIGJlIGZhc3RcbiAgICAvLyAoc2luZ2xlIFJlZGlzIG9wKTsgc2xvdyBob29rcyBzaG91bGQgcnVuIHRoZWlyIG93biBiYWNrZ3JvdW5kIHdvcmsuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMub25BZnRlckNyZWF0ZShjcmVhdGVkLCB1c2VySWQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhbiBleGlzdGluZyBlbnRpdHlcbiAgICovXG4gIGFzeW5jIHVwZGF0ZShcbiAgICBpZDogc3RyaW5nLFxuICAgIGRhdGE6IFBhcnRpYWw8VFVwZGF0ZT4sXG4gICAgb3JnSWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxURW50aXR5IHwgbnVsbD4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLndyaXRlQ29uZGl0aW9ucyhpZCwgb3JnSWQpO1xuXG4gICAgLy8gU2NydWIgYSBjYWxsZXItc3VwcGxpZWQgYG9yZ0lkYCBpbiB0aGUgdXBkYXRlIHBheWxvYWQgKGFzIGNyZWF0ZSBkb2VzKTogdGhlXG4gICAgLy8gV0hFUkUgb25seSBwaW5zIHdoaWNoIHJvd3MgeW91IGNhbiBUQVJHRVQsIG5vdCB3aGF0IHlvdSBjYW4gc2V0IOKAlCB3aXRob3V0IHRoaXNcbiAgICAvLyBhIHRlbmFudCBjb3VsZCByZS1ob21lIGEgcm93IGl0IG93bnMgaW50byBhbm90aGVyIG9yZyB2aWEgYGRhdGEub3JnSWRgLlxuICAgIGNvbnN0IHNhZmVEYXRhID0gdGhpcy5lbmZvcmNlT3JnSWQoZGF0YSBhcyB1bmtub3duIGFzIFRJbnNlcnQpIGFzIHVua25vd24gYXMgUGFydGlhbDxUVXBkYXRlPjtcblxuICAgIGNvbnN0IFt1cGRhdGVkXSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAudXBkYXRlKHRoaXMuc2NoZW1hKVxuICAgICAgLnNldCh7XG4gICAgICAgIC4uLnNhZmVEYXRhLFxuICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIHVwZGF0ZWRCeTogdXNlcklkIHx8ICdzeXN0ZW0nLFxuICAgICAgfSBhcyBhbnkpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpO1xuXG4gICAgaWYgKHVwZGF0ZWQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMub25BZnRlclVwZGF0ZShpZCwgdXBkYXRlZCwgdXNlcklkKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignTGlmZWN5Y2xlIGhvb2sgZmFpbGVkJywgeyBlcnJvcjogU3RyaW5nKGVycikgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVwZGF0ZWQgfHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYW4gZW50aXR5IChzb2Z0IGRlbGV0ZSBieSBzZXR0aW5nIGlzQWN0aXZlID0gZmFsc2UpXG4gICAqL1xuICBhc3luYyBkZWxldGUoaWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZywgdXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPFRFbnRpdHkgfCBudWxsPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMud3JpdGVDb25kaXRpb25zKGlkLCBvcmdJZCk7XG5cbiAgICBjb25zdCBbZGVsZXRlZF0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgIC5zZXQoe1xuICAgICAgICBpc0FjdGl2ZTogZmFsc2UsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICAgIGRlbGV0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgZGVsZXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICB9IGFzIGFueSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICBpZiAoZGVsZXRlZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5vbkFmdGVyRGVsZXRlKGlkLCBkZWxldGVkLCB1c2VySWQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdMaWZlY3ljbGUgaG9vayBmYWlsZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGVsZXRlZCB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCBhbiBlbnRpdHkgYXMgdGhlIGRlZmF1bHQgZm9yIGEgcHJvamVjdC9vcmdhbml6YXRpb24gc2NvcGUuXG4gICAqIE1hcmtzIGFsbCBvdGhlciBlbnRpdGllcyBhcyBub24tZGVmYXVsdCwgdGhlbiBzZXRzIHRoZSBzcGVjaWZpZWQgZW50aXR5LlxuICAgKiBVc2VzIGEgdHJhbnNhY3Rpb24gdG8gZW5zdXJlIGF0b21pY2l0eS5cbiAgICovXG4gIGFzeW5jIHNldERlZmF1bHQoXG4gICAgcHJvamVjdDogc3RyaW5nLFxuICAgIG9yZzogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8VEVudGl0eT4ge1xuICAgIC8vIEEgbm9uLXN5c2FkbWluIG1heSBvbmx5IGZsaXAgZGVmYXVsdHMgd2l0aGluIGl0cyBPV04gb3JnIOKAlCBwaW4gdGhlIHNjb3BlIHRvXG4gICAgLy8gdGhlIHRydXN0ZWQgdGVuYW50IGNvbnRleHQgc28gYSBmb3J3YXJkZWQgYG9yZ2AgYXJnIGNhbid0IHRvdWNoIGFub3RoZXJcbiAgICAvLyB0ZW5hbnQncyBkZWZhdWx0cyAoUkxTIGlzIGluIG93bmVyLWJ5cGFzcyBtb2RlOyB0aGlzIGlzIHRoZSBnYXRlKS5cbiAgICBjb25zdCBjdHggPSBnZXRUZW5hbnRDb250ZXh0KCk7XG4gICAgaWYgKGN0eCAmJiAhY3R4LmlzU3VwZXJBZG1pbiAmJiBjdHgub3JnSWQpIG9yZyA9IGN0eC5vcmdJZDtcbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgY29uc3Qgb3JnQ29sdW1uID0gdGhpcy5nZXRPcmdDb2x1bW4oKTtcbiAgICAgIGNvbnN0IHByb2plY3RDb2x1bW4gPSB0aGlzLmdldFByb2plY3RDb2x1bW4oKTtcblxuICAgICAgLy8gQnVpbGQgc2NvcGluZyBjb25kaXRpb25zIGZvciBjbGVhcmluZyBkZWZhdWx0c1xuICAgICAgY29uc3Qgc2NvcGVDb25kaXRpb25zID0gW1xuICAgICAgICBlcShvcmdDb2x1bW4sIG9yZyksXG4gICAgICAgIGVxKHRoaXMuY29scy5pc0RlZmF1bHQsIHRydWUpLFxuICAgICAgXTtcbiAgICAgIGlmIChwcm9qZWN0Q29sdW1uKSB7XG4gICAgICAgIHNjb3BlQ29uZGl0aW9ucy5wdXNoKGVxKHByb2plY3RDb2x1bW4sIHByb2plY3QpKTtcbiAgICAgIH1cblxuICAgICAgLy8gTG9jayBleGlzdGluZyBkZWZhdWx0cyB3aXRoIEZPUiBVUERBVEUgdG8gcHJldmVudCBjb25jdXJyZW50IHNldERlZmF1bHQgcmFjZXNcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1QgaWQgRlJPTSAke3RoaXMuc2NoZW1hfVxuICAgICAgICAgICAgV0hFUkUgJHtvcmdDb2x1bW59ID0gJHtvcmd9XG4gICAgICAgICAgICAgIEFORCAke3RoaXMuY29scy5pc0RlZmF1bHR9ID0gdHJ1ZVxuICAgICAgICAgICAgJHtwcm9qZWN0Q29sdW1uID8gc3FsYEFORCAke3Byb2plY3RDb2x1bW59ID0gJHtwcm9qZWN0fWAgOiBzcWxgYH1cbiAgICAgICAgICAgIEZPUiBVUERBVEVgLFxuICAgICAgKTtcblxuICAgICAgLy8gTWFyayBhbGwgZW50aXRpZXMgaW4gc2NvcGUgYXMgbm9uLWRlZmF1bHRcbiAgICAgIGF3YWl0IHR4XG4gICAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAgIC5zZXQoe1xuICAgICAgICAgIGlzRGVmYXVsdDogZmFsc2UsXG4gICAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICAgIHVwZGF0ZWRCeTogdXNlcklkIHx8ICdzeXN0ZW0nLFxuICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgLndoZXJlKGFuZCguLi5zY29wZUNvbmRpdGlvbnMpKTtcblxuICAgICAgLy8gU2V0IHRoZSBzcGVjaWZpZWQgZW50aXR5IGFzIGRlZmF1bHQuIEd1YXJkIGFnYWluc3QgcHJvbW90aW5nIGFcbiAgICAgIC8vIHNvZnQtZGVsZXRlZCByb3cgKGlzQWN0aXZlID0gdHJ1ZSkg4oCUIGEgZGVsZXRlZCBlbnRpdHkgbXVzdCBuZXZlciBiZWNvbWVcbiAgICAgIC8vIHRoZSBhY3RpdmUgZGVmYXVsdCDigJQgYW5kIHBpbiB0aGUgaWQgd2l0aCB0aGUgc2FtZSBsb3dlcmNhc2VkXG4gICAgICAvLyBleGFjdElkQ29uZGl0aW9uIHRoZSBtdXRhdGlvbiBwYXRocyB1c2UgKHRoZSByYXcgYGVxKGNvbHMuaWQsIGlkKWAgaGVyZVxuICAgICAgLy8gc2tpcHBlZCB0aGUgbG93ZXItY2FzaW5nIHRoYXQgYGJ1aWxkSWRGaWx0ZXJgL2B3cml0ZUNvbmRpdGlvbnNgIGFwcGx5LFxuICAgICAgLy8gc28gYSBtaXhlZC1jYXNlIGlkIGNvdWxkIG1pc3MgaXRzIHJvdykuIEEgbm9uLW1hdGNoIOKGkiBOb3RGb3VuZEVycm9yIGJlbG93LlxuICAgICAgY29uc3QgW3VwZGF0ZWRdID0gYXdhaXQgdHhcbiAgICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgICAgLnNldCh7XG4gICAgICAgICAgaXNEZWZhdWx0OiB0cnVlLFxuICAgICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgIC53aGVyZShcbiAgICAgICAgICBhbmQoXG4gICAgICAgICAgICB0aGlzLmV4YWN0SWRDb25kaXRpb24oaWQpLFxuICAgICAgICAgICAgZXEob3JnQ29sdW1uLCBvcmcpLFxuICAgICAgICAgICAgZXEodGhpcy5jb2xzLmlzQWN0aXZlLCB0cnVlKSxcbiAgICAgICAgICApLFxuICAgICAgICApXG4gICAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpO1xuXG4gICAgICBpZiAoIXVwZGF0ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoYEVudGl0eSB3aXRoIGlkICR7aWR9IG5vdCBmb3VuZGApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdXBkYXRlZDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgbXVsdGlwbGUgZW50aXRpZXMgbWF0Y2hpbmcgZmlsdGVyXG4gICAqL1xuICBhc3luYyB1cGRhdGVNYW55KFxuICAgIGZpbHRlcjogUGFydGlhbDxURmlsdGVyPixcbiAgICBkYXRhOiBQYXJ0aWFsPFRVcGRhdGU+LFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQpO1xuICAgIC8vIE93bi1vcmcgd3JpdGUtcGluOiBidWlsZENvbmRpdGlvbnMgYWxzbyBtYXRjaGVzIHN5c3RlbS9vdGhlci1vcmcgUFVCTElDXG4gICAgLy8gcm93cywgc28gd2l0aG91dCB0aGUgc3RyaWN0IG9yZ0lkIHBpbiBhIGZpbHRlci1iYXNlZCB1cGRhdGUgY291bGQgbXV0YXRlXG4gICAgLy8gc2hhcmVkIChvciBhbm90aGVyIHRlbmFudCdzIHB1YmxpYykgcmVjb3Jkcy4gTWlycm9yIHVwZGF0ZS9kZWxldGUvXG4gICAgLy8gYnVsa0RlbGV0ZS4gKFNlZSB3cml0ZUNvbmRpdGlvbnMuKSBBbiBvcmdJZC1sZXNzIChzeXNhZG1pbikgY29udGV4dCBrZWVwc1xuICAgIC8vIGZ1bGwgYWNjZXNzLlxuICAgIGlmIChvcmdJZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKSk7XG5cbiAgICAvLyBTY3J1YiBhIGNhbGxlci1zdXBwbGllZCBvcmdJZCAoc2VlIHVwZGF0ZSgpKSBzbyBhIGZpbHRlci1iYXNlZCB1cGRhdGUgY2FuJ3RcbiAgICAvLyByZS1ob21lIHJvd3MgaW50byBhbm90aGVyIHRlbmFudC5cbiAgICBjb25zdCBzYWZlRGF0YSA9IHRoaXMuZW5mb3JjZU9yZ0lkKGRhdGEgYXMgdW5rbm93biBhcyBUSW5zZXJ0KSBhcyB1bmtub3duIGFzIFBhcnRpYWw8VFVwZGF0ZT47XG5cbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHtcbiAgICAgICAgLi4uc2FmZURhdGEsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICB9IGFzIGFueSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIG11bHRpcGxlIGVudGl0aWVzIGluIGEgc2luZ2xlIGJhdGNoIGluc2VydC5cbiAgICogVXNlcyB1cHNlcnQgKG9uQ29uZmxpY3REb1VwZGF0ZSkg4oCUIGFsbCByb3dzIGFyZSBpbnNlcnRlZCBpbiBvbmUgcXVlcnkgcGVyIGNodW5rLlxuICAgKiBDaHVua3Mgb2YgMTAwIHRvIHN0YXkgd2l0aGluIFBvc3RncmVTUUwgcGFyYW1ldGVyIGxpbWl0cy5cbiAgICovXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgYG9uQ29uZmxpY3REb1VwZGF0ZWAgU0VUIGZvciBhIGJ1bGsgdXBzZXJ0LiBVbmxpa2UgYSBzaW5nbGUtcm93XG4gICAqIGNyZWF0ZSAod2hpY2ggY2FuIHNwcmVhZCB0aGUgb25lIHJvdydzIGRhdGEpLCBhIGJhdGNoZWQgaW5zZXJ0IGhhcyBtYW55IHJvd3MsXG4gICAqIHNvIGVhY2ggdXBkYXRhYmxlIGNvbHVtbiBpcyB3cml0dGVuIGZyb20gYGV4Y2x1ZGVkLipgICh0aGUgd291bGQtYmUtaW5zZXJ0ZWRcbiAgICogdmFsdWUpIOKAlCBvdGhlcndpc2UgYW4gZXhpc3Rpbmcgcm93J3MgZmllbGRzIGFyZSBzaWxlbnRseSBkaXNjYXJkZWQgYW5kIG9ubHlcbiAgICogdGltZXN0YW1wcyBidW1wLiBTa2lwcyBpZGVudGl0eS9pbW11dGFibGUgKGBpZGAsIGBjcmVhdGVkQXRgLCBgY3JlYXRlZEJ5YClcbiAgICogYW5kIHRoZSBjb25mbGljdC10YXJnZXQgY29sdW1uczsgYHVwZGF0ZWRBdGAvYHVwZGF0ZWRCeWAgZ2V0IHRoZSBmcmVzaCB2YWx1ZXMuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQnVsa1Vwc2VydFNldChub3c6IERhdGUsIHVzZXI6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCBjb25mbGljdE5hbWVzID0gbmV3IFNldCh0aGlzLmNvbmZsaWN0VGFyZ2V0Lm1hcCgoYykgPT4gKGMgYXMgdW5rbm93biBhcyB7IG5hbWU6IHN0cmluZyB9KS5uYW1lKSk7XG4gICAgY29uc3Qgc2V0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgY29sXSBvZiBPYmplY3QuZW50cmllcyhnZXRUYWJsZUNvbHVtbnModGhpcy5zY2hlbWEpKSkge1xuICAgICAgY29uc3QgbmFtZSA9IChjb2wgYXMgdW5rbm93biBhcyB7IG5hbWU6IHN0cmluZyB9KS5uYW1lO1xuICAgICAgaWYgKGtleSA9PT0gJ2lkJyB8fCBrZXkgPT09ICdjcmVhdGVkQXQnIHx8IGtleSA9PT0gJ2NyZWF0ZWRCeScgfHwgY29uZmxpY3ROYW1lcy5oYXMobmFtZSkpIGNvbnRpbnVlO1xuICAgICAgaWYgKGtleSA9PT0gJ3VwZGF0ZWRBdCcpIHsgc2V0W2tleV0gPSBub3c7IGNvbnRpbnVlOyB9XG4gICAgICBpZiAoa2V5ID09PSAndXBkYXRlZEJ5JykgeyBzZXRba2V5XSA9IHVzZXI7IGNvbnRpbnVlOyB9XG4gICAgICBzZXRba2V5XSA9IHNxbGBleGNsdWRlZC4ke3NxbC5pZGVudGlmaWVyKG5hbWUpfWA7XG4gICAgfVxuICAgIHJldHVybiBzZXQ7XG4gIH1cblxuICBhc3luYyBidWxrQ3JlYXRlKGl0ZW1zOiBUSW5zZXJ0W10sIHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5W10+IHtcbiAgICBpZiAoaXRlbXMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBDSFVOS19TSVpFID0gMTAwO1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgdXNlciA9IHVzZXJJZCB8fCAnc3lzdGVtJztcbiAgICBjb25zdCBjb25mbGljdFNldCA9IHRoaXMuYnVpbGRCdWxrVXBzZXJ0U2V0KG5vdywgdXNlcik7XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgY29uc3QgYWxsQ3JlYXRlZDogVEVudGl0eVtdID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpICs9IENIVU5LX1NJWkUpIHtcbiAgICAgICAgY29uc3QgY2h1bmsgPSBpdGVtcy5zbGljZShpLCBpICsgQ0hVTktfU0laRSk7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IGNodW5rLm1hcChkYXRhID0+ICh7XG4gICAgICAgICAgLi4udGhpcy5lbmZvcmNlT3JnSWQoZGF0YSksXG4gICAgICAgICAgY3JlYXRlZEJ5OiB1c2VyLFxuICAgICAgICAgIHVwZGF0ZWRCeTogdXNlcixcbiAgICAgICAgfSBhcyBhbnkpKTtcblxuICAgICAgICBjb25zdCBjcmVhdGVkID0gYXdhaXQgdHhcbiAgICAgICAgICAuaW5zZXJ0KHRoaXMuc2NoZW1hKVxuICAgICAgICAgIC52YWx1ZXModmFsdWVzKVxuICAgICAgICAgIC5vbkNvbmZsaWN0RG9VcGRhdGUoe1xuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmNvbmZsaWN0VGFyZ2V0IGFzIGFueSxcbiAgICAgICAgICAgIHNldDogY29uZmxpY3RTZXQgYXMgYW55LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSk7XG5cbiAgICAgICAgYWxsQ3JlYXRlZC5wdXNoKC4uLmNyZWF0ZWQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYWxsQ3JlYXRlZDtcbiAgICB9KTtcblxuICAgIC8vIFJ1biBob29rcyBpbiBwYXJhbGxlbCBidXQgYXdhaXQgYWxsIGJlZm9yZSByZXR1cm5pbmcgc28gYSBzdWJzZXF1ZW50XG4gICAgLy8gcmVhZCBpbiB0aGUgc2FtZSByZXF1ZXN0IHNlZXMgYSBjb2hlcmVudCBwb3N0LXdyaXRlIHZpZXcuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICByZXN1bHRzLm1hcChlbnRpdHkgPT5cbiAgICAgICAgdGhpcy5vbkFmdGVyQ3JlYXRlKGVudGl0eSwgdXNlcklkKS5jYXRjaChlcnIgPT5cbiAgICAgICAgICB0aGlzLl9sb2dnZXIud2FybignTGlmZWN5Y2xlIGhvb2sgZmFpbGVkJywgeyBlcnJvcjogU3RyaW5nKGVycikgfSksXG4gICAgICAgICksXG4gICAgICApLFxuICAgICk7XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBTb2Z0LWRlbGV0ZSBtdWx0aXBsZSBlbnRpdGllcyBieSBJRHMgaW4gYSBzaW5nbGUgYmF0Y2ggb3BlcmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgYnVsa0RlbGV0ZShcbiAgICBpZHM6IHN0cmluZ1tdLFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICAgLyoqIFdoZW4gdHJ1ZSwgb25seSBQUklWQVRFIHJlY29yZHMgYXJlIGRlbGV0ZWQg4oCUIG1pcnJvcnMgdGhlIHNpbmdsZS1kZWxldGVcbiAgICAgKiAgYHJlcXVpcmVQdWJsaWNBY2Nlc3NgIGdhdGUgc28gYSBub24tc3lzYWRtaW4gY2FuJ3QgYnVsay1kZWxldGUgcHVibGljXG4gICAgICogIChzaGFyZWQvc3lzYWRtaW4tbWFuYWdlZCkgcmVjb3Jkcy4gTm8tb3AgZm9yIGVudGl0aWVzIHdpdGhvdXQgYW5cbiAgICAgKiAgYGFjY2Vzc01vZGlmaWVyYCBjb2x1bW4uIENhbGxlcnMgcGFzcyBgIWlzU3lzdGVtQWRtaW4ocmVxKWAuICovXG4gICAgcmVzdHJpY3RUb1ByaXZhdGUgPSBmYWxzZSxcbiAgKTogUHJvbWlzZTxURW50aXR5W10+IHtcbiAgICBpZiAoaWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB1c2VyID0gdXNlcklkIHx8ICdzeXN0ZW0nO1xuICAgIC8vIE93bmVyLXNjb3BlIHRoZSBidWxrIHNvZnQtZGVsZXRlOiBidWlsZENvbmRpdGlvbnMgYWxzbyBtYXRjaGVzIHN5c3RlbS9vdGhlclxuICAgIC8vIC1vcmcgUFVCTElDIHJvd3MsIHNvIHdpdGhvdXQgdGhlIHN0cmljdCBvcmdJZCBwaW4gYSB0ZW5hbnQgY291bGQgZGVsZXRlXG4gICAgLy8gc2hhcmVkIHJlY29yZHMgYnkgaWQuIChTZWUgd3JpdGVDb25kaXRpb25zLilcbiAgICBjb25zdCBhY2Nlc3NDb2wgPSB0aGlzLmNvbHMuYWNjZXNzTW9kaWZpZXI7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IFtcbiAgICAgIGluQXJyYXkodGhpcy5jb2xzLmlkLCBpZHMpLFxuICAgICAgLi4udGhpcy5idWlsZENvbmRpdGlvbnMoe30gYXMgUGFydGlhbDxURmlsdGVyPiwgb3JnSWQpLFxuICAgICAgLy8gVGVuYW50IGNvbHVtbiAoZ2V0T3JnQ29sdW1uLCBhc3NlcnRlZCBub24tbnVsbCkg4oCUIGNvbnNpc3RlbnQgd2l0aFxuICAgICAgLy8gd3JpdGVDb25kaXRpb25zOyBubyBzaWxlbnQgZmFpbC1vcGVuIHdoZW4gdGhlIHByb3BlcnR5IGlzIGFic2VudC5cbiAgICAgIC4uLihvcmdJZCA/IFtlcSh0aGlzLmdldE9yZ0NvbHVtbigpLCBvcmdJZCldIDogW10pLFxuICAgICAgLi4uKHJlc3RyaWN0VG9Qcml2YXRlICYmIGFjY2Vzc0NvbCA/IFtlcShhY2Nlc3NDb2wsICdwcml2YXRlJyldIDogW10pLFxuICAgIF07XG5cbiAgICBjb25zdCBkZWxldGVkID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHtcbiAgICAgICAgaXNBY3RpdmU6IGZhbHNlLFxuICAgICAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VyLFxuICAgICAgICBkZWxldGVkQXQ6IG5vdyxcbiAgICAgICAgZGVsZXRlZEJ5OiB1c2VyLFxuICAgICAgfSBhcyBhbnkpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBkZWxldGVkLm1hcChlbnRpdHkgPT5cbiAgICAgICAgdGhpcy5vbkFmdGVyRGVsZXRlKGVudGl0eS5pZCwgZW50aXR5LCB1c2VySWQpLmNhdGNoKGVyciA9PlxuICAgICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdMaWZlY3ljbGUgaG9vayBmYWlsZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgKTtcblxuICAgIHJldHVybiBkZWxldGVkO1xuICB9XG59XG4iXX0=
771
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J1ZC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9jcnVkLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBR3JGLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU5RixtRkFBbUY7QUFDbkYsTUFBTSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBSSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDakYsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUUxRTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUksSUFBYTtJQUMxQyxPQUFPLElBQVcsQ0FBQztBQUNyQixDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBYTtJQUN4QyxPQUFPLElBQTJCLENBQUM7QUFDckMsQ0FBQztBQStGRDs7Ozs7R0FLRztBQUNILE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixJQUFJLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVB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Q0FBQyxFQUFFLENBQUUsQ0FBNEIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVuRSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFBRSxPQUFPLEVBQUUsQ0FBQztZQUVuQywyRUFBMkU7WUFDM0UsK0VBQStFO1lBQy9FLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUVqQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNsRSxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDckUsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDMUIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IE5vdEZvdW5kRXJyb3IsIGNyZWF0ZUxvZ2dlciB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IFNRTCwgZXEsIGFuZCwgYXNjLCBkZXNjLCBzcWwsIGluQXJyYXksIGdldFRhYmxlQ29sdW1ucyB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB0eXBlIHsgQW55Q29sdW1uIH0gZnJvbSAnZHJpenpsZS1vcm0vY29sdW1uJztcbmltcG9ydCB0eXBlIHsgUGdUYWJsZSB9IGZyb20gJ2RyaXp6bGUtb3JtL3BnLWNvcmUnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4LCBydW5XaXRoVGVuYW50Q29udGV4dCwgZ2V0VGVuYW50Q29udGV4dCB9IGZyb20gJy4uL2RhdGFiYXNlL3RlbmFuY3kuanMnO1xuXG4vKiogUGFnaW5hdGlvbiBkZWZhdWx0cyDigJQgcmVhZCBmcm9tIGVudiB0byBtYXRjaCBDb3JlQ29uc3RhbnRzIGluIHBpcGVsaW5lLWNvcmUuICovXG5jb25zdCBERUZBVUxUX1BBR0VfTElNSVQgPSBwYXJzZUludChwcm9jZXNzLmVudi5ERUZBVUxUX1BBR0VfTElNSVQgfHwgJzEwMCcsIDEwKTtcbmNvbnN0IE1BWF9QQUdFX0xJTUlUID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuTUFYX1BBR0VfTElNSVQgfHwgJzEwMDAnLCAxMCk7XG5cbi8qKlxuICogQ2FzdCBEcml6emxlIHF1ZXJ5IHJlc3VsdHMgdG8gYSB0eXBlZCBhcnJheS5cbiAqIERyaXp6bGUncyBnZW5lcmljIHJldHVybiB0eXBlIChgUGdTZWxlY3RCYXNlPC4uLj5gKSBkb2Vzbid0IG5hcnJvdyB0byBvdXJcbiAqIGVudGl0eSBnZW5lcmljcywgc28gYW4gZXhwbGljaXQgY2FzdCBpcyBuZWVkZWQuIENlbnRyYWxpc2VkIGhlcmUgc28gZXZlcnlcbiAqIGNhbGwtc2l0ZSBzdGF5cyBvbmUtbGluZXIgY2xlYW4gYW5kIHRoZSBjYXN0IGlzIGRvY3VtZW50ZWQgaW4gb25lIHBsYWNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZHJpenpsZVJvd3M8VD4ocm93czogdW5rbm93bik6IFRbXSB7XG4gIHJldHVybiByb3dzIGFzIFRbXTtcbn1cblxuLyoqIENhc3QgYSBEcml6emxlIGFnZ3JlZ2F0ZSByZXN1bHQgdG8gZXh0cmFjdCBgW3sgY291bnQ6IG51bWJlciB9XWAuICovXG5leHBvcnQgZnVuY3Rpb24gZHJpenpsZUNvdW50KHJvd3M6IHVua25vd24pOiBbeyBjb3VudDogbnVtYmVyIH1dIHtcbiAgcmV0dXJuIHJvd3MgYXMgW3sgY291bnQ6IG51bWJlciB9XTtcbn1cblxuLyoqXG4gKiBCYXNlIGludGVyZmFjZSBmb3IgZW50aXRpZXMgd2l0aCBjb21tb24gZmllbGRzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUVudGl0eSB7XG4gIGlkOiBzdHJpbmc7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIGlzRGVmYXVsdDogYm9vbGVhbjtcbiAgY3JlYXRlZEF0OiBEYXRlO1xuICB1cGRhdGVkQXQ6IERhdGU7XG4gIGNyZWF0ZWRCeTogc3RyaW5nO1xuICB1cGRhdGVkQnk6IHN0cmluZztcbiAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBQYWdpbmF0aW9uIGFuZCBzb3J0aW5nIG9wdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdWVyeU9wdGlvbnMge1xuICBsaW1pdD86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xuICBzb3J0Qnk/OiBzdHJpbmc7XG4gIHNvcnRPcmRlcj86ICdhc2MnIHwgJ2Rlc2MnO1xuICAvKiogV2hlbiB0cnVlLCBydW5zIGEgc2VwYXJhdGUgQ09VTlQoKikgcXVlcnkgdG8gaW5jbHVkZSBleGFjdCB0b3RhbC4gRGVmYXVsdDogZmFsc2UuICovXG4gIGluY2x1ZGVUb3RhbD86IGJvb2xlYW47XG4gIC8qKiBDdXJzb3ItYmFzZWQgcGFnaW5hdGlvbjogZmV0Y2ggcm93cyBhZnRlciB0aGlzIGN1cnNvciB2YWx1ZSAodXNlcyBzb3J0QnkgY29sdW1uKS4gKi9cbiAgY3Vyc29yPzogc3RyaW5nO1xuICAvKiogU3BhcnNlIGZpZWxkc2V0OiBjb2x1bW4gbmFtZXMgdG8gc2VsZWN0LiBSZXR1cm5zIGFsbCBjb2x1bW5zIHdoZW4gb21pdHRlZC4gKi9cbiAgZmllbGRzPzogc3RyaW5nW107XG59XG5cbi8qKlxuICogUGFnaW5hdGVkIHJlc3VsdCB3aXRoIG1ldGFkYXRhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFnaW5hdGVkUmVzdWx0PFQ+IHtcbiAgZGF0YTogVFtdO1xuICAvKiogVG90YWwgY291bnQgb2YgbWF0Y2hpbmcgZW50aXRpZXMuIE9ubHkgcHJlc2VudCB3aGVuIGluY2x1ZGVUb3RhbCBpcyB0cnVlLiAqL1xuICB0b3RhbD86IG51bWJlcjtcbiAgbGltaXQ6IG51bWJlcjtcbiAgb2Zmc2V0OiBudW1iZXI7XG4gIGhhc01vcmU6IGJvb2xlYW47XG4gIC8qKiBDdXJzb3IgcG9pbnRpbmcgdG8gdGhlIGxhc3QgaXRlbSwgZm9yIGN1cnNvci1iYXNlZCBwYWdpbmF0aW9uLiAqL1xuICBuZXh0Q3Vyc29yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFic3RyYWN0IENSVUQgc2VydmljZSB3aXRoIG11bHRpLXRlbmFudCBhY2Nlc3MgY29udHJvbCBhbmQgcGFnaW5hdGlvbi5cbiAqXG4gKiBTdWJjbGFzc2VzIGJpbmQgdG8gYSBzcGVjaWZpYyBEcml6emxlIHRhYmxlIGJ5IGltcGxlbWVudGluZyBgc2NoZW1hYCxcbiAqIGBidWlsZENvbmRpdGlvbnNgLCBgZ2V0U29ydENvbHVtbmAsIGFuZCB0aGUgb3JnL3Byb2plY3QtY29sdW1uIGFjY2Vzc29ycy5cbiAqXG4gKiBAdHlwZVBhcmFtIFRFbnRpdHkgLSBFbnRpdHkgdHlwZSBleHRlbmRpbmcgQmFzZUVudGl0eVxuICogQHR5cGVQYXJhbSBURmlsdGVyIC0gRmlsdGVyIHR5cGUgZm9yIHF1ZXJ5IHBhcmFtZXRlcnNcbiAqIEB0eXBlUGFyYW0gVEluc2VydCAtIEluc2VydCBEVE8gdHlwZVxuICogQHR5cGVQYXJhbSBUVXBkYXRlIC0gVXBkYXRlIERUTyB0eXBlXG4gKlxuICogKipBIG5vdGUgb24gdGhlIHR5cGUgY2FzdHMuKiogRHJpenpsZSdzIHJvdyB0eXBlcyBhcmUgaW5mZXJyZWQgZnJvbVxuICogYHBnVGFibGUoLi4uKWAgYW5kIGRvbid0IGdlbmVyaWNhbGx5IG5hcnJvdyB0aHJvdWdoIHRoZSBhYnN0cmFjdCBgc2NoZW1hYFxuICogZ2V0dGVyLCBzbyB0aGUgYmFzZSBjbGFzcyBjYXN0cyBxdWVyeSByZXN1bHRzIHRvIGBURW50aXR5YCBhbmQgYmFjay4gVGhlXG4gKiBjYXN0IGlzICpub3QqIGEgcnVudGltZSBzYWZldHkgZ3VhcmFudGVlIOKAlCBpdCByZWxpZXMgb24gZWFjaCBzdWJjbGFzc1xuICogcGFzc2luZyB0aGUgbWF0Y2hpbmcgZW50aXR5IHR5cGUuIE9yZy1zY29waW5nIGlzIGVuZm9yY2VkIGJ5IGV2ZXJ5XG4gKiBzdWJjbGFzcydzIGBidWlsZENvbmRpdGlvbnNgIGluamVjdGluZyBgV0hFUkUgb3JnX2lkID0gJDFgOyB0aGlzIGNsYXNzXG4gKiBkb2VzIG5vdCBhZGQgdGhhdCBmaWx0ZXIgaXRzZWxmLlxuICpcbiAqICoqRXJyb3IgcG9saWN5LioqIEVycm9ycyBwcm9wYWdhdGUgdXAgdG8gdGhlIHJvdXRlLWxldmVsIGhhbmRsZXJcbiAqIChgd2l0aFJvdXRlYCk7IG5vIGNhdGNoLWFuZC1zd2FsbG93IGhlcmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsYXNzIFBpcGVsaW5lU2VydmljZSBleHRlbmRzIENydWRTZXJ2aWNlPFBpcGVsaW5lLCBQaXBlbGluZUZpbHRlciwgUGlwZWxpbmVJbnNlcnQsIFBpcGVsaW5lVXBkYXRlPiB7XG4gKiAgIHByb3RlY3RlZCBnZXQgc2NoZW1hKCkgeyByZXR1cm4gc2NoZW1hLnBpcGVsaW5lOyB9XG4gKiAgIHByb3RlY3RlZCBidWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCkgeyByZXR1cm4gYnVpbGRQaXBlbGluZUNvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCk7IH1cbiAqICAgcHJvdGVjdGVkIGdldFNvcnRDb2x1bW4oc29ydEJ5KSB7IHJldHVybiBzb3J0Q29sdW1uTWFwW3NvcnRCeV0gPz8gbnVsbDsgfVxuICogICBwcm90ZWN0ZWQgZ2V0UHJvamVjdENvbHVtbigpIHsgcmV0dXJuIHNjaGVtYS5waXBlbGluZS5wcm9qZWN0OyB9XG4gKiAgIHByb3RlY3RlZCBnZXRPcmdDb2x1bW4oKSB7IHJldHVybiBzY2hlbWEucGlwZWxpbmUub3JnSWQ7IH1cbiAqIH1cbiAqIGBgYFxuICovXG4vKiogU3RydWN0dXJhbCB2aWV3IG9mIHRoZSBzdWJjbGFzcyB0YWJsZSdzIGNvbHVtbnMgdGhlIGJhc2UgY2xhc3MgdG91Y2hlc1xuICogIGRpcmVjdGx5LiBgaWRgL2Bpc0FjdGl2ZWAvYGlzRGVmYXVsdGAgYXJlIGFsd2F5cyBwcmVzZW50IG9uIGEgQ1JVRCBlbnRpdHk7XG4gKiAgYGFjY2Vzc01vZGlmaWVyYCBvbmx5IG9uIHB1YmxpYy12aXNpYmlsaXR5IGVudGl0aWVzOyB0aGUgaW5kZXggc2lnbmF0dXJlXG4gKiAgY292ZXJzIGR5bmFtaWMgKHNwYXJzZS1maWVsZHNldCkgY29sdW1uIGFjY2Vzcy4gKi9cbmludGVyZmFjZSBDcnVkQ29sdW1ucyB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIGlzQWN0aXZlOiBBbnlDb2x1bW47XG4gIGlzRGVmYXVsdDogQW55Q29sdW1uO1xuICBhY2Nlc3NNb2RpZmllcj86IEFueUNvbHVtbjtcbiAgLy8gU29mdC1kZWxldGUgbGlmZWN5Y2xlIGNvbHVtbnMgKHByZXNlbnQgb24gdG9tYnN0b25lLWJlYXJpbmcgZW50aXRpZXMgb25seTtcbiAgLy8gYHJlc3RvcmVgL2BwdXJnZUV4cGlyZWRgIGFyZSBuby1vcHMgd2hlbiBhYnNlbnQpLlxuICBkZWxldGVkQXQ/OiBBbnlDb2x1bW47XG4gIHB1cmdlQWZ0ZXI/OiBBbnlDb2x1bW47XG4gIFtrZXk6IHN0cmluZ106IEFueUNvbHVtbiB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXRlbnRpb24gYmVmb3JlIGEgc29mdC1kZWxldGVkIHJvdyBiZWNvbWVzIHB1cmdlLWVsaWdpYmxlLCBzaGFyZWQgYWNyb3NzXG4gKiBldmVyeSBDcnVkU2VydmljZSBlbnRpdHkgKHVuaWZpZWQgYFNPRlRfREVMRVRFX1JFVEVOVElPTl9EQVlTYCwgZGVmYXVsdCAzMGQpLlxuICogU3RhbXBlZCBpbnRvIGBwdXJnZV9hZnRlcmAgYXQgZGVsZXRlIHRpbWU7IHRoZSBwZXItc2VydmljZSBwdXJnZSBzd2VlcCBoYXJkLVxuICogZGVsZXRlcyB0b21ic3RvbmVzIG9uY2UgaXQgaGFzIHBhc3NlZC4gYDBgIGRpc2FibGVzIHB1cmdlLWRlYWRsaW5lIHN0YW1waW5nLlxuICovXG5jb25zdCBTT0ZUX0RFTEVURV9SRVRFTlRJT05fTVMgPSBNYXRoLm1heCgwLCBOdW1iZXIucGFyc2VJbnQocHJvY2Vzcy5lbnYuU09GVF9ERUxFVEVfUkVURU5USU9OX0RBWVMgPz8gJzMwJywgMTApIHx8IDApICogMjQgKiA2MCAqIDYwICogMTAwMDtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENydWRTZXJ2aWNlPFxuICBURW50aXR5IGV4dGVuZHMgQmFzZUVudGl0eSxcbiAgVEZpbHRlcixcbiAgVEluc2VydCxcbiAgVFVwZGF0ZSxcbj4ge1xuICAvKiogRHJpenpsZSBzY2hlbWEgdGFibGUgZm9yIHRoaXMgZW50aXR5ICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXQgc2NoZW1hKCk6IFBnVGFibGU7XG5cbiAgLyoqXG4gICAqIFR5cGVkIGNvbHVtbiB2aWV3IG9mIHtAbGluayBzY2hlbWF9LiBgUGdUYWJsZWAgZXhwb3NlcyBubyBzdGF0aWMgY29sdW1ucywgc29cbiAgICogdGhlIGJhc2UgY2xhc3MgcHJldmlvdXNseSByZWFjaGVkIGZvciBgKHRoaXMuc2NoZW1hIGFzIGFueSkuaWRgIGV0Yy4gYXQgZWFjaFxuICAgKiB1c2U7IGNlbnRyYWxpemUgdGhhdCBzaW5nbGUgdW5hdm9pZGFibGUgY2FzdCBoZXJlIHNvIGNhbGxlcnMgZ2V0IHN0cnVjdHVyZWQsXG4gICAqIHR5cGVkIGFjY2VzcyBpbnN0ZWFkLiBgYWNjZXNzTW9kaWZpZXJgIGlzIG9wdGlvbmFsIChub3QgZXZlcnkgZW50aXR5IGhhcyBpdClcbiAgICogYW5kIHRoZSBpbmRleCBzaWduYXR1cmUgY292ZXJzIGR5bmFtaWMgc3BhcnNlLWZpZWxkc2V0IGNvbHVtbiBsb29rdXAuXG4gICAqL1xuICBwcml2YXRlIGdldCBjb2xzKCk6IENydWRDb2x1bW5zIHtcbiAgICByZXR1cm4gdGhpcy5zY2hlbWEgYXMgdW5rbm93biBhcyBDcnVkQ29sdW1ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBTUUwgY29uZGl0aW9ucyBmb3IgZmlsdGVyaW5nIGVudGl0aWVzLlxuICAgKiBgcGFyZW50T3JnSWRgIChvcmcg4oaSIHRlYW0gaGllcmFyY2h5KSBpcyBvcHRpb25hbCBhbmQgb25seSBob25vcmVkIGJ5XG4gICAqIHNlcnZpY2VzIHRoYXQgb3B0IGludG8gcGFyZW50LWluaGVyaXRlZCB2aXNpYmlsaXR5IChlLmcuIHBsdWdpbnMpLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdO1xuXG4gIC8qKiBHZXQgdGhlIHNjaGVtYSBjb2x1bW4gZm9yIHNvcnRpbmcgYnkgZmllbGQgbmFtZSAqL1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0U29ydENvbHVtbihzb3J0Qnk6IHN0cmluZyk6IEFueUNvbHVtbiB8IG51bGw7XG5cbiAgLyoqIEdldCB0aGUgcHJvamVjdCBjb2x1bW4gZm9yIHNldERlZmF1bHQgc2NvcGluZyAobnVsbCBpZiBlbnRpdHkgaGFzIG5vIHByb2plY3Qgc2NvcGUpICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRQcm9qZWN0Q29sdW1uKCk6IEFueUNvbHVtbiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdGVuYW50IG9yZy1pZCBjb2x1bW4uIFVzZWQgYm90aCB0byBzY29wZSBgc2V0RGVmYXVsdGAgYW5kIHRvIHBpblxuICAgKiBldmVyeSB3cml0ZSAodXBkYXRlL2RlbGV0ZS9idWxrRGVsZXRlKSB0byB0aGUgY2FsbGVyJ3Mgb3duIG9yZyDigJQgc28gaXQgTVVTVFxuICAgKiBiZSB0aGUgdGVuYW50IGBvcmdJZGAgY29sdW1uLCBub3QgYSBkaXNwbGF5L25hbWUgY29sdW1uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldE9yZ0NvbHVtbigpOiBBbnlDb2x1bW47XG5cbiAgLyoqIEdldCB0aGUgdW5pcXVlIGNvbnN0cmFpbnQgY29sdW1ucyBmb3Igb25Db25mbGljdERvVXBkYXRlICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXQgY29uZmxpY3RUYXJnZXQoKTogQW55Q29sdW1uW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdjcnVkLXNlcnZpY2UnKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBGYWlsIGZhc3QgaWYgYSBzdWJjbGFzcyBkb2Vzbid0IGV4cG9zZSBhIHRlbmFudCBvcmcgY29sdW1uLiBUaGUgd3JpdGVcbiAgICAvLyBwYXRocyAod3JpdGVDb25kaXRpb25zIC8gYnVsa0RlbGV0ZSkgcGluIG11dGF0aW9ucyB0byB0aGUgY2FsbGVyJ3Mgb3duXG4gICAgLy8gb3JnIHRocm91Z2ggaXQ7IGEgbWlzc2luZyBjb2x1bW4gd291bGQgc2lsZW50bHkgZHJvcCB0aGF0IGd1YXJkIOKAlCBhXG4gICAgLy8gY3Jvc3MtdGVuYW50IGZhaWwtb3BlbiDigJQgc28gYXNzZXJ0IGl0cyBwcmVzZW5jZSB1cCBmcm9udC5cbiAgICBpZiAodGhpcy5nZXRPcmdDb2x1bW4oKSA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogZ2V0T3JnQ29sdW1uKCkgbXVzdCByZXR1cm4gdGhlIHRlbmFudCBvcmcgY29sdW1uYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEJ1aWxkIGNvbmRpdGlvbnMgZm9yIGEgc2luZ2xlIGVudGl0eSBieSBJRC5cbiAgICogIGBwYXJlbnRPcmdJZGAgd2lkZW5zIHZpc2liaWxpdHkgdG8gYSBwYXJlbnQgb3JnJ3MgcHVibGljIHJvd3MgKG9yZyDihpIgdGVhbVxuICAgKiAgaGllcmFyY2h5KSDigJQgc2FtZSBvcHQtaW4gc2VtYW50aWNzIGFzIGBmaW5kYC9gZmluZFBhZ2luYXRlZGAuIE9taXR0ZWQgYnkgdGhlXG4gICAqICB3cml0ZSBwYXRoIChgd3JpdGVDb25kaXRpb25zYCksIHdoaWNoIG11c3Qgc3RheSBvd24tb3JnIHNjb3BlZC4gKi9cbiAgcHJpdmF0ZSBpZENvbmRpdGlvbnMoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogU1FMW10ge1xuICAgIHJldHVybiB0aGlzLmJ1aWxkQ29uZGl0aW9ucyh7IGlkIH0gYXMgdW5rbm93biBhcyBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmRpdGlvbnMgZm9yIGEgTVVUQVRJT04gKHVwZGF0ZS9kZWxldGUpIG9mIGEgc2luZ2xlIGVudGl0eS5cbiAgICpcbiAgICogYGlkQ29uZGl0aW9uc2AgcmV1c2VzIHRoZSBSRUFEIGFjY2Vzcy1jb250cm9sIGNsYXVzZSwgd2hpY2ggYWxzbyBtYXRjaGVzXG4gICAqIHN5c3RlbS1vcmcgLyBvdGhlci1vcmcgUFVCTElDIHJlY29yZHMg4oCUIHNvIHdpdGhvdXQgYW4gZXh0cmEgb3duZXJzaGlwIHBpbiBhbnlcbiAgICogdGVuYW50IGNvdWxkIHVwZGF0ZSBvciBzb2Z0LWRlbGV0ZSBhbm90aGVyIG9yZydzIChvciB0aGUgc3lzdGVtIG9yZydzKSBwdWJsaWNcbiAgICogcmVjb3Jkcy4gQU5EIGEgc3RyaWN0IGBvcmdJZCA9PT0gY2FsbGVyYCBwcmVkaWNhdGU6IHRoZSByZWFkIGNsYXVzZSdzXG4gICAqIHB1YmxpYy1PUiBicmFuY2ggcmVxdWlyZXMgYG9yZ19pZCA9ICdzeXN0ZW0nYCwgd2hpY2ggdGhlbiBjYW4ndCBiZSBzYXRpc2ZpZWQsXG4gICAqIGxlYXZpbmcgb25seSBvd24tb3JnIHJvd3MuIG9yZ0lkLWxlc3MgKHN5c2FkbWluKSBjb250ZXh0IGtlZXBzIGZ1bGwgYWNjZXNzLlxuICAgKi9cbiAgcHJpdmF0ZSB3cml0ZUNvbmRpdGlvbnMoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuaWRDb25kaXRpb25zKGlkLCBvcmdJZCk7XG4gICAgLy8gUGluIHRoZSBtdXRhdGlvbiB0byB0aGUgY2FsbGVyJ3Mgb3duIG9yZyB2aWEgdGhlIHRlbmFudCBjb2x1bW5cbiAgICAvLyAoZ2V0T3JnQ29sdW1uLCBhc3NlcnRlZCBub24tbnVsbCBpbiB0aGUgY29uc3RydWN0b3IpIOKAlCBjb25zaXN0ZW50IHdpdGhcbiAgICAvLyBzZXREZWZhdWx0IGFuZCB3aXRob3V0IHRoZSBvbGQgc2lsZW50IGZhaWwtb3BlbiB3aGVuIHRoZSBwcm9wZXJ0eSB3YXMgYWJzZW50LlxuICAgIGlmIChvcmdJZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKSk7XG4gICAgLy8gRm9yY2UgRVhBQ1QgaWQgZXF1YWxpdHkgb24gdGhlIG11dGF0aW9uIHBhdGguIGBpZENvbmRpdGlvbnNgIHJldXNlcyB0aGVcbiAgICAvLyBsaXN0LWZpbHRlciBjbGF1c2UsIHdob3NlIGBidWlsZElkRmlsdGVyYCBQUkVGSVgtbWF0Y2hlcyAoYGlkOjp0ZXh0IExJS0VcbiAgICAvLyAndmFsJSdgKSBhbnkgbm9uLWZ1bGwtVVVJRCB2YWx1ZSDigJQgc28gYSBwYXJ0aWFsIGlkIChgREVMRVRFIC94L2FiYCkgd291bGRcbiAgICAvLyBzb2Z0LWRlbGV0ZS9tdXRhdGUgRVZFUlkgb3duLW9yZyByb3cgd2hvc2UgaWQgc3RhcnRzIHdpdGggYGFiYCBhbmQgcmVwb3J0XG4gICAgLy8gdG91Y2hpbmcgb25lLiBBTkRpbmcgYW4gZXhhY3QgYGlkID0gdmFsYCBjb2xsYXBzZXMgdGhlIHByZWZpeCBjbGF1c2UgdG8gYXRcbiAgICAvLyBtb3N0IHRoZSBzaW5nbGUgZXhhY3Qgcm93OyBhIG1hbGZvcm1lZC9wYXJ0aWFsIGlkIHRoZW4gbWF0Y2hlcyBub3RoaW5nXG4gICAgLy8gKOKGkiA0MDQgdmlhIHRoZSBjYWxsZXJzJyBgaWYgKCFkZWxldGVkKWAgZ3VhcmQpIGluc3RlYWQgb2YgbWFzcy1tdXRhdGluZy5cbiAgICBjb25kaXRpb25zLnB1c2godGhpcy5leGFjdElkQ29uZGl0aW9uKGlkKSk7XG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cblxuICAvKiogRXhhY3QgaWQgZXF1YWxpdHksIGxvd2VyLWNhc2VkIHRvIG1hdGNoIGBidWlsZElkRmlsdGVyYCdzIGZ1bGwtVVVJRCBicmFuY2guXG4gICAqICBgc2NoZW1hYCBpcyB0eXBlZCBgUGdUYWJsZWAgKG5vIHN0YXRpYyBgLmlkYCksIHNvIGNhc3Qg4oCUIHNhbWUgcGF0dGVybiB0aGVcbiAgICogIHNvcnQvZGVmYXVsdCBoZWxwZXJzIHVzZSBmb3IgY29sdW1uIGFjY2Vzcy4gKi9cbiAgcHJpdmF0ZSBleGFjdElkQ29uZGl0aW9uKGlkOiBzdHJpbmcpOiBTUUwge1xuICAgIHJldHVybiBlcSh0aGlzLmNvbHMuaWQsIFN0cmluZyhpZCkudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICAvLyBMaWZlY3ljbGUgaG9va3Mg4oCUIG92ZXJyaWRlIGluIHN1YmNsYXNzZXMgdG8gcmVhY3QgdG8gbXV0YXRpb25zXG4gIC8vIFRoZXNlIGFyZSBmaXJlLWFuZC1mb3JnZXQ6IGVycm9ycyBhcmUgbG9nZ2VkIGJ1dCBuZXZlciBibG9jayB0aGUgY2FsbGVyLlxuXG4gIC8qKiBDYWxsZWQgYWZ0ZXIgYSBuZXcgZW50aXR5IGlzIGNyZWF0ZWQgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJDcmVhdGUoX2VudGl0eTogVEVudGl0eSwgX3VzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBDYWxsZWQgYWZ0ZXIgYW4gZW50aXR5IGlzIHVwZGF0ZWQgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJVcGRhdGUoX2lkOiBzdHJpbmcsIF9lbnRpdHk6IFRFbnRpdHksIF91c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogQ2FsbGVkIGFmdGVyIGFuIGVudGl0eSBpcyBzb2Z0LWRlbGV0ZWQgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQWZ0ZXJEZWxldGUoX2lkOiBzdHJpbmcsIF9lbnRpdHk6IFRFbnRpdHksIF91c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogQ2FsbGVkIGFmdGVyIGEgc29mdC1kZWxldGVkIGVudGl0eSBpcyByZXN0b3JlZCAodW5kbyB0aGUgZGVsZXRlKS4gT3ZlcnJpZGVcbiAgICogIGZvciBlbnRpdGllcyB3aG9zZSByZXN0b3JlIGhhcyBzaWRlLWVmZmVjdHMgKGUuZy4gcmUtbm90aWZ5KS4gQmVzdC1lZmZvcnQuICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkFmdGVyUmVzdG9yZShfaWQ6IHN0cmluZywgX2VudGl0eTogVEVudGl0eSwgX3VzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBDYWxsZWQgKGJlc3QtZWZmb3J0KSB3aXRoIHRoZSBpZHMgYWJvdXQgdG8gYmUgaGFyZC1wdXJnZWQsIEJFRk9SRSB0aGVcbiAgICogIGRlbGV0ZSwgc28gYSBzdWJjbGFzcyBjYW4gdGVhciBkb3duIGRlcGVuZGVudHMgdGhhdCBsYWNrIE9OIERFTEVURSBDQVNDQURFLlxuICAgKiAgVGhyb3dpbmcgYWJvcnRzIHRoYXQgYmF0Y2gncyBwdXJnZSAocm93cyBzdGF5IHRvbWJzdG9uZWQsIHJldHJpZWQgbmV4dCB0aWNrKS4gKi9cbiAgcHJvdGVjdGVkIGFzeW5jIG9uQmVmb3JlUHVyZ2UoX2lkczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIENhbGxlZCBhZnRlciByb3dzIGFyZSBoYXJkLXB1cmdlZCwgZm9yIGV4dGVybmFsIHNpZGUtZWZmZWN0cyAoZS5nLiBwbHVnaW5cbiAgICogIGltYWdlIEdDKS4gQmVzdC1lZmZvcnQ6IGVycm9ycyBhcmUgbG9nZ2VkLCBuZXZlciBibG9jayB0aGUgc3dlZXAuICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkFmdGVyUHVyZ2UoX2lkczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgLyoqIFJldGVudGlvbiBiZWZvcmUgYSBzb2Z0LWRlbGV0ZWQgcm93IGJlY29tZXMgcHVyZ2UtZWxpZ2libGUuIERlZmF1bHRzIHRvIHRoZVxuICAgKiAgc2hhcmVkIGBTT0ZUX0RFTEVURV9SRVRFTlRJT05fREFZU2A7IG92ZXJyaWRlIHBlciBlbnRpdHkgZm9yIGEgYmVzcG9rZSB3aW5kb3cuICovXG4gIHByb3RlY3RlZCBnZXQgc29mdERlbGV0ZVJldGVudGlvbk1zKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIFNPRlRfREVMRVRFX1JFVEVOVElPTl9NUztcbiAgfVxuXG4gIC8qKiBUaGUgYHB1cmdlX2FmdGVyYCB2YWx1ZSB0byBzdGFtcCBvbiBhIHNvZnQtZGVsZXRlOiBgbm93ICsgcmV0ZW50aW9uYCwgb3IgdGhlXG4gICAqICBzcHJlYWQtZnJpZW5kbHkgZW1wdHkgb2JqZWN0IHdoZW4gdGhlIGVudGl0eSBoYXMgbm8gYHB1cmdlX2FmdGVyYCBjb2x1bW4uICovXG4gIHByaXZhdGUgcHVyZ2VBZnRlclN0YW1wKG5vdzogRGF0ZSk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBpZiAoIXRoaXMuY29scy5wdXJnZUFmdGVyIHx8IHRoaXMuc29mdERlbGV0ZVJldGVudGlvbk1zIDw9IDApIHJldHVybiB7fTtcbiAgICByZXR1cm4geyBwdXJnZUFmdGVyOiBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgdGhpcy5zb2Z0RGVsZXRlUmV0ZW50aW9uTXMpIH07XG4gIH1cblxuICAvKipcbiAgICogT3JnIOKGkiB0ZWFtIGhpZXJhcmNoeTogd2hlbiBhIHJlYWQgaXMgd2lkZW5lZCB0byBhIHBhcmVudCBvcmcgKGBwYXJlbnRPcmdJZGBcbiAgICogc2V0KSwgdGhlIHBhcmVudCdzIHJvd3MgYXJlIG91dHNpZGUgdGhlIGNhbGxlcidzIFJMUyBzY29wZSwgc28gdGhlIHJlYWQgbXVzdFxuICAgKiBydW4gdW5kZXIgc3lzYWRtaW4gY29udGV4dCDigJQgdGhlIGFjY2Vzcy1jb250cm9sIFdIRVJFIGNsYXVzZSAob3duICsgcGFyZW50ICtcbiAgICogc3lzdGVtIHB1YmxpYywgYnVpbHQgc2VydmVyLXNpZGUgZnJvbSBhIHRydXN0ZWQgSldUIGNsYWltKSBpcyB0aGVuIHRoZVxuICAgKiBhdXRob3JpdGF0aXZlIHRlbmFuY3kgZ2F0ZS4gV2l0aG91dCBgcGFyZW50T3JnSWRgIGl0IHN0YXlzIFJMUy1zY29wZWQuXG4gICAqXG4gICAqIElOVkFSSUFOVCAod2h5IHRoZSBzeXNhZG1pbiBieXBhc3MgaXMgc2FmZSk6IHRoZSBXSEVSRSBjbGF1c2UgaXMgYWx3YXlzXG4gICAqIHNlcnZlci1idWlsdCBieSBgYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKWAgZnJvbSB2YWx1ZXNcbiAgICogZGVyaXZlZCBmcm9tIHRoZSB2YWxpZGF0ZWQgSldUIChgb3JnSWRgID0gYWN0aXZlIG9yZywgYHBhcmVudE9yZ0lkYCA9IHRoZVxuICAgKiBhY3RpdmUgb3JnJ3MgcGFyZW50KS4gTm9uZSBvZiB0aGVtIGlzIGEgcmF3IHVzZXItc3VwcGxpZWQgcHJlZGljYXRlLCBzbyB0aGVcbiAgICogYnlwYXNzIG9ubHkgZXZlciB3aWRlbnMgdGhlIHJlYWQgdG8gdGhlIGNhbGxlcidzIG93biBzdWJ0cmVlICsgc3lzdGVtIHB1YmxpY1xuICAgKiByb3dzIOKAlCBpdCBjYW4gTk9UIGJlIHN0ZWVyZWQgYXQgYW4gYXJiaXRyYXJ5IG9yZy4gTk9URTogdGhpcyBkb2VzIHJlbW92ZSB0aGVcbiAgICogUkxTIGJhY2tzdG9wIGZvciB0aGUgd2lkZW5lZCByZWFkOyBhIHNpbmdsZS1HVUMgYGFwcC5vcmdfaWRgIGNhbid0IGV4cHJlc3NcbiAgICogdGhlIFwib3duIE9SIHBhcmVudCBPUiBzeXN0ZW1cIiBzZXQgdGhlIHBvbGljeSB3b3VsZCBuZWVkLCBzbyByZXBsYWNpbmcgdGhlXG4gICAqIGJ5cGFzcyB3b3VsZCByZXF1aXJlIGEgdGVuYW5jeS1sYXllciBjaGFuZ2UgKGUuZy4gYSBtdWx0aS1vcmcgUkxTIHBvbGljeSkuXG4gICAqIERlZmVycmVkIGRlbGliZXJhdGVseSDigJQgZG8gbm90IHN3YXAgdGhpcyBmb3IgYSBibGFua2V0IGJ5cGFzcyB3aXRob3V0XG4gICAqIHJlLWNoZWNraW5nIHRoZSBXSEVSRSBpcyBzdGlsbCBmdWxseSBzZXJ2ZXItYnVpbHQuXG4gICAqL1xuICBwcml2YXRlIHJ1blJlYWQ8VD4ocGFyZW50T3JnSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCwgZm46ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICByZXR1cm4gcGFyZW50T3JnSWQgPyBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCBmbikgOiBmbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgZW50aXRpZXMgbWF0Y2hpbmcgZmlsdGVyIGNyaXRlcmlhXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKi9cbiAgYXN5bmMgZmluZChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKTtcblxuICAgIHJldHVybiB0aGlzLnJ1blJlYWQocGFyZW50T3JnSWQsICgpID0+IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAuc2VsZWN0KClcbiAgICAgIC5mcm9tKHRoaXMuc2NoZW1hKVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgZW50aXRpZXMgd2l0aCBwYWdpbmF0aW9uIGFuZCBzb3J0aW5nXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFBhZ2luYXRpb24gYW5kIHNvcnRpbmcgb3B0aW9uc1xuICAgKi9cbiAgYXN5bmMgZmluZFBhZ2luYXRlZChcbiAgICBmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sXG4gICAgb3JnSWQ/OiBzdHJpbmcsXG4gICAgb3B0aW9uczogUXVlcnlPcHRpb25zID0ge30sXG4gICAgcGFyZW50T3JnSWQ/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UGFnaW5hdGVkUmVzdWx0PFRFbnRpdHk+PiB7XG4gICAgY29uc3QgeyBsaW1pdDogcmF3TGltaXQgPSBERUZBVUxUX1BBR0VfTElNSVQsIG9mZnNldCA9IDAsIHNvcnRCeSwgc29ydE9yZGVyID0gJ2FzYycsIGluY2x1ZGVUb3RhbCA9IGZhbHNlLCBjdXJzb3IsIGZpZWxkcyB9ID0gb3B0aW9ucztcbiAgICBjb25zdCBsaW1pdCA9IE1hdGgubWluKE1hdGgubWF4KDEsIHJhd0xpbWl0KSwgTUFYX1BBR0VfTElNSVQpO1xuXG4gICAgLy8gQ3Vyc29yIGFuZCBvZmZzZXQgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSDigJQgY3Vyc29yIHRha2VzIHByZWNlZGVuY2VcbiAgICBjb25zdCB1c2VDdXJzb3IgPSAhIShjdXJzb3IgJiYgc29ydEJ5KTtcblxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmJ1aWxkQ29uZGl0aW9ucyhmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG5cbiAgICAvLyBDdXJzb3ItYmFzZWQgcGFnaW5hdGlvbjogYWRkIFdIRVJFIGNsYXVzZSBmb3Iga2V5c2V0IHBhZ2luYXRpb25cbiAgICBpZiAodXNlQ3Vyc29yKSB7XG4gICAgICBjb25zdCBzb3J0Q29sdW1uID0gdGhpcy5nZXRTb3J0Q29sdW1uKHNvcnRCeSk7XG4gICAgICBpZiAoc29ydENvbHVtbikge1xuICAgICAgICBjb25zdCBvcCA9IHNvcnRPcmRlciA9PT0gJ2Rlc2MnXG4gICAgICAgICAgPyBzcWxgJHtzb3J0Q29sdW1ufSA8ICR7Y3Vyc29yfWBcbiAgICAgICAgICA6IHNxbGAke3NvcnRDb2x1bW59ID4gJHtjdXJzb3J9YDtcbiAgICAgICAgY29uZGl0aW9ucy5wdXNoKG9wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBXcmFwIHRoZSB3aG9sZSBwYWdpbmF0ZWQgcmVhZCAoU0VMRUNUICsgb3B0aW9uYWwgQ09VTlQpIGluIG9uZVxuICAgIC8vIHRlbmFudCB0eC4gQm90aCBxdWVyaWVzIGFyZSB2aXNpYmlsaXR5LXNjb3BlZCBieSB0aGUgc2FtZSBSTFMgcG9saWN5LFxuICAgIC8vIGFuZCBwaW5uaW5nIHRoZW0gdG8gYSBzaW5nbGUgdHgga2VlcHMgdGhlIGBhcHAub3JnX2lkYCBHVUMgc3RhYmxlXG4gICAgLy8gYmV0d2VlbiB0aGVtLiBXaGVuIHdpZGVuaW5nIHRvIGEgcGFyZW50IG9yZywgdGhlIHdob2xlIHJlYWQgcnVucyB1bmRlclxuICAgIC8vIHN5c2FkbWluIGNvbnRleHQgKHNlZSBydW5SZWFkKSBzbyB0aGUgYWNjZXNzLWNvbnRyb2wgV0hFUkUgaXMgdGhlIGdhdGUuXG4gICAgcmV0dXJuIHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgLy8gQnVpbGQgU0VMRUNUIOKAlCBzcGFyc2UgZmllbGRzZXQgd2hlbiBmaWVsZHMgYXJlIHNwZWNpZmllZC4gVGhlIHNvcnRCeVxuICAgICAgLy8gY29sdW1uIE1VU1QgYmUgcGFydCBvZiB0aGUgcHJvamVjdGlvbiB3aGVuZXZlciBzb3J0aW5nIGlzIGFjdGl2ZTogdGhlXG4gICAgICAvLyBuZXh0IGN1cnNvciBpcyBkZXJpdmVkIGZyb20gYGxhc3RJdGVtW3NvcnRCeV1gIGJlbG93LCBzbyBhIGZpZWxkcyBzZXRcbiAgICAgIC8vIHRoYXQgb21pdHMgc29ydEJ5IHdvdWxkIGxlYXZlIHRoZSBjdXJzb3IgdW5kZWZpbmVkIGFuZCBzdGFsbCB0aGUgY2xpZW50XG4gICAgICAvLyBvbiBwYWdlIDEuIGJ1aWxkRmllbGRTZWxlY3QgYWx3YXlzIGFkZHMgaXQgYmFjayAobGlrZSBgaWRgKS5cbiAgICAgIGNvbnN0IHNlbGVjdFNwZWMgPSBmaWVsZHMgPyB0aGlzLmJ1aWxkRmllbGRTZWxlY3QoZmllbGRzLCBzb3J0QnkpIDogdW5kZWZpbmVkO1xuICAgICAgbGV0IHF1ZXJ5ID0gc2VsZWN0U3BlY1xuICAgICAgICA/IHR4LnNlbGVjdChzZWxlY3RTcGVjIGFzIGFueSkuZnJvbSh0aGlzLnNjaGVtYSkud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgICA6IHR4LnNlbGVjdCgpLmZyb20odGhpcy5zY2hlbWEpLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSk7XG5cbiAgICAgIGlmIChzb3J0QnkpIHtcbiAgICAgICAgY29uc3Qgc29ydENvbHVtbiA9IHRoaXMuZ2V0U29ydENvbHVtbihzb3J0QnkpO1xuICAgICAgICBpZiAoc29ydENvbHVtbikge1xuICAgICAgICAgIHF1ZXJ5ID0gcXVlcnkub3JkZXJCeShzb3J0T3JkZXIgPT09ICdkZXNjJyA/IGRlc2Moc29ydENvbHVtbikgOiBhc2Moc29ydENvbHVtbikpIGFzIGFueTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBGZXRjaCBsaW1pdCsxIHRvIGRldGVjdCBoYXNNb3JlIHdpdGhvdXQgQ09VTlQoKilcbiAgICAgIGNvbnN0IGVmZmVjdGl2ZU9mZnNldCA9IHVzZUN1cnNvciA/IDAgOiBvZmZzZXQ7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgcXVlcnlcbiAgICAgICAgLmxpbWl0KGxpbWl0ICsgMSlcbiAgICAgICAgLm9mZnNldChlZmZlY3RpdmVPZmZzZXQpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSk7XG5cbiAgICAgIGNvbnN0IGhhc01vcmUgPSByb3dzLmxlbmd0aCA+IGxpbWl0O1xuICAgICAgY29uc3QgZGF0YSA9IGhhc01vcmUgPyByb3dzLnNsaWNlKDAsIGxpbWl0KSA6IHJvd3M7XG5cbiAgICAgIGNvbnN0IHJlc3VsdDogUGFnaW5hdGVkUmVzdWx0PFRFbnRpdHk+ID0geyBkYXRhLCBsaW1pdCwgb2Zmc2V0OiBlZmZlY3RpdmVPZmZzZXQsIGhhc01vcmUgfTtcblxuICAgICAgLy8gUHJvdmlkZSBuZXh0IGN1cnNvciBmcm9tIGxhc3QgaXRlbSdzIHNvcnQgY29sdW1uIHZhbHVlXG4gICAgICBpZiAoZGF0YS5sZW5ndGggPiAwICYmIHNvcnRCeSkge1xuICAgICAgICBjb25zdCBsYXN0SXRlbSA9IGRhdGFbZGF0YS5sZW5ndGggLSAxXSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgY29uc3QgY3Vyc29yVmFsdWUgPSBsYXN0SXRlbVtzb3J0QnldO1xuICAgICAgICBpZiAoY3Vyc29yVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlc3VsdC5uZXh0Q3Vyc29yID0gY3Vyc29yVmFsdWUgaW5zdGFuY2VvZiBEYXRlID8gY3Vyc29yVmFsdWUudG9JU09TdHJpbmcoKSA6IFN0cmluZyhjdXJzb3JWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT25seSBydW4gdGhlIENPVU5UKCopIHF1ZXJ5IHdoZW4gdGhlIGNhbGxlciBleHBsaWNpdGx5IG5lZWRzIHRoZSB0b3RhbC5cbiAgICAgIC8vIE11c3QgaW5jbHVkZSBwYXJlbnRPcmdJZCBzbyBgdG90YWxgIG1hdGNoZXMgdGhlIHdpZGVuZWQgZGF0YSBzZXQuXG4gICAgICBpZiAoaW5jbHVkZVRvdGFsKSB7XG4gICAgICAgIGNvbnN0IGJhc2VDb25kaXRpb25zID0gdGhpcy5idWlsZENvbmRpdGlvbnMoZmlsdGVyLCBvcmdJZCwgcGFyZW50T3JnSWQpO1xuICAgICAgICBjb25zdCBbY291bnRSZXN1bHRdID0gYXdhaXQgdHhcbiAgICAgICAgICAuc2VsZWN0KHsgY291bnQ6IHNxbDxudW1iZXI+YGNvdW50KCopOjppbnRgIH0pXG4gICAgICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAgICAgLndoZXJlKGFuZCguLi5iYXNlQ29uZGl0aW9ucykpLnRoZW4ociA9PiBkcml6emxlQ291bnQocikpO1xuICAgICAgICByZXN1bHQudG90YWwgPSBjb3VudFJlc3VsdD8uY291bnQgfHwgMDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb2x1bW4gc2VsZWN0aW9uIG1hcCBmb3Igc3BhcnNlIGZpZWxkc2V0cy5cbiAgICogRmFsbHMgYmFjayB0byBmdWxsIHNlbGVjdCBpZiBubyBtYXRjaGluZyBjb2x1bW5zIGZvdW5kLlxuICAgKlxuICAgKiBgc29ydEJ5YCAod2hlbiBzZXQpIGlzIGFsd2F5cyBmb2xkZWQgaW50byB0aGUgcHJvamVjdGlvbiBldmVuIGlmIHRoZSBjYWxsZXInc1xuICAgKiBgZmllbGRzYCBvbWl0cyBpdCDigJQgY3Vyc29yIHBhZ2luYXRpb24gcmVhZHMgdGhlIG5leHQgY3Vyc29yIGZyb20gdGhlIHNvcnRcbiAgICogY29sdW1uJ3MgdmFsdWUgb24gdGhlIGxhc3Qgcm93LCBzbyBkcm9wcGluZyBpdCBmcm9tIHRoZSBTRUxFQ1Qgd291bGQgeWllbGQgYW5cbiAgICogdW5kZWZpbmVkIGN1cnNvciBhbmQgc3RhbGwgcGFnaW5nLiBJbmNsdWRlZCB0aGUgc2FtZSB3YXkgYGlkYCBhbHdheXMgaXMuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkRmllbGRTZWxlY3QoZmllbGRzOiBzdHJpbmdbXSwgc29ydEJ5Pzogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQge1xuICAgIGlmIChmaWVsZHMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY29sdW1uczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICAvLyBBbHdheXMgaW5jbHVkZSBpZCBmb3IgZW50aXR5IGlkZW50aXR5XG4gICAgY29sdW1ucy5pZCA9IHRoaXMuY29scy5pZDtcblxuICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB7XG4gICAgICBpZiAoZmllbGQgPT09ICdpZCcpIGNvbnRpbnVlOyAvLyBBbHJlYWR5IGluY2x1ZGVkXG4gICAgICBjb25zdCBjb2wgPSB0aGlzLmNvbHNbZmllbGRdO1xuICAgICAgaWYgKGNvbCkgY29sdW1uc1tmaWVsZF0gPSBjb2w7XG4gICAgfVxuXG4gICAgLy8gR3VhcmFudGVlIHRoZSBzb3J0IGNvbHVtbiBpcyBzZWxlY3RhYmxlIHNvIHRoZSBuZXh0IGN1cnNvciBjYW4gYmUgcmVhZFxuICAgIC8vIGZyb20gdGhlIGxhc3Qgcm93IChzZWUgZmluZFBhZ2luYXRlZCkuIE5vLW9wIGlmIGFscmVhZHkgYWRkZWQgb3IgdW5rbm93bi5cbiAgICBpZiAoc29ydEJ5ICYmIHNvcnRCeSAhPT0gJ2lkJyAmJiAhKHNvcnRCeSBpbiBjb2x1bW5zKSkge1xuICAgICAgY29uc3Qgc29ydENvbCA9IHRoaXMuY29sc1tzb3J0QnldO1xuICAgICAgaWYgKHNvcnRDb2wpIGNvbHVtbnNbc29ydEJ5XSA9IHNvcnRDb2w7XG4gICAgfVxuXG4gICAgLy8gQXQgbWluaW11bSB3ZSdsbCBoYXZlIHsgaWQgfSwgd2hpY2ggaXMgdmFsaWRcbiAgICByZXR1cm4gY29sdW1ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3VudCBlbnRpdGllcyBtYXRjaGluZyBmaWx0ZXIgY3JpdGVyaWFcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcGFyYW0gb3JnSWQgLSBVc2VyJ3Mgb3JnYW5pemF0aW9uIElEIChvcHRpb25hbCDigJQgb21pdCBmb3IgYW5vbnltb3VzL3N5c3RlbS1wdWJsaWMtb25seSBhY2Nlc3MpXG4gICAqIEBwYXJhbSBwYXJlbnRPcmdJZCAtIE9yZyDihpIgdGVhbSBoaWVyYXJjaHk6IHdpZGVuIHRoZSBjb3VudCB0byB0aGUgcGFyZW50IG9yZydzXG4gICAqICAgcHVibGljIHJvd3MuIE1VU1QgbWlycm9yIGBmaW5kYC9gZmluZFBhZ2luYXRlZGAncyB3aWRlbmluZyAoc2FtZVxuICAgKiAgIGBidWlsZENvbmRpdGlvbnNgIGFyZ3MgKyBzeXNhZG1pbi1zY29wZWQgcmVhZCB2aWEgYHJ1blJlYWRgKSBzbyBhIHBhZ2VkXG4gICAqICAgbGlzdCdzIGB0b3RhbGAgbWF0Y2hlcyB0aGUgcm93cyBhIHdpZGVuZWQgYGZpbmQoKWAgcmV0dXJucyDigJQgb3RoZXJ3aXNlIHRoZVxuICAgKiAgIGNvdW50IG9taXRzIHRoZSBwYXJlbnQncyByb3dzIGFuZCByZXBvcnRzIGEgbmFycm93ZXIgdG90YWwgdGhhbiB0aGUgZGF0YSBzZXQuXG4gICAqL1xuICBhc3luYyBjb3VudChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKTtcblxuICAgIGNvbnN0IFtyZXN1bHRdID0gYXdhaXQgdGhpcy5ydW5SZWFkKHBhcmVudE9yZ0lkLCAoKSA9PiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCh7IGNvdW50OiBzcWw8bnVtYmVyPmBjb3VudCgqKTo6aW50YCB9KVxuICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKS50aGVuKHIgPT4gZHJpenpsZUNvdW50KHIpKSkpO1xuXG4gICAgcmV0dXJuIHJlc3VsdD8uY291bnQgfHwgMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGEgc2luZ2xlIGVudGl0eSBieSBJRFxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBFbnRpdHkgSURcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIG9taXQgZm9yIGFub255bW91cy9zeXN0ZW0tcHVibGljLW9ubHkgYWNjZXNzKVxuICAgKiBAcGFyYW0gcGFyZW50T3JnSWQgLSBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB3aWRlbiB2aXNpYmlsaXR5IHRvIHRoZSBwYXJlbnRcbiAgICogICBvcmcncyBwdWJsaWMgcm93cyAoc28gYSB0ZWFtIGNhbiBmZXRjaCBhIHBhcmVudCdzIHB1YmxpYyBlbnRpdHkgYnkgaWQpLlxuICAgKiAgIFNhbWUgb3B0LWluICsgc3lzYWRtaW4tc2NvcGVkIHJlYWQgYXMgYGZpbmRgL2BmaW5kUGFnaW5hdGVkYDsgdGhlXG4gICAqICAgYWNjZXNzLWNvbnRyb2wgV0hFUkUgY2xhdXNlIGlzIHRoZSBhdXRob3JpdGF0aXZlIHRlbmFuY3kgZ2F0ZS5cbiAgICovXG4gIGFzeW5jIGZpbmRCeUlkKGlkOiBzdHJpbmcsIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy5pZENvbmRpdGlvbnMoaWQsIG9yZ0lkLCBwYXJlbnRPcmdJZCk7XG4gICAgLy8gRXhhY3QgaWQg4oCUIGBmaW5kQnlJZGAgbWVhbnMgVEhFIHJvdyB3aXRoIHRoaXMgaWQsIG5vdCBhIHByZWZpeCBtYXRjaC4gVGhlXG4gICAgLy8gc2hhcmVkIGBidWlsZElkRmlsdGVyYCBwcmVmaXgtbWF0Y2hlcyBub24tZnVsbC1VVUlEIHZhbHVlcyAoYSBsaXN0LXNlYXJjaFxuICAgIC8vIGZlYXR1cmUpLCB3aGljaCBoZXJlIHdvdWxkIHJldHVybiBhbiBhcmJpdHJhcnkgZmlyc3QgcHJlZml4IGhpdCBmb3IgYVxuICAgIC8vIHBhcnRpYWwgaWQ7IHBpbiBpdCB0byBleGFjdCBzbyBhIG1hbGZvcm1lZCBpZCByZXR1cm5zIG51bGwuXG4gICAgY29uZGl0aW9ucy5wdXNoKHRoaXMuZXhhY3RJZENvbmRpdGlvbihpZCkpO1xuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5zZWxlY3QoKVxuICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLmxpbWl0KDEpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpKTtcblxuICAgIHJldHVybiByZXN1bHRzWzBdIHx8IG51bGw7XG4gIH1cblxuICAvLyBNdXRhdGlvbiBvcGVyYXRpb25zXG5cbiAgLyoqXG4gICAqIERlZmVuc2UtaW4tZGVwdGggdGVuYW50IHN0YW1wLiBSTFMgaXMgaW4gb3duZXItYnlwYXNzIG1vZGUsIHNvIHRoZSBhcHAgbGF5ZXJcbiAgICogaXMgdGhlIG9ubHkgdGVuYW50IGdhdGUgb24gd3JpdGVzLiBBIE5PTi1zeXNhZG1pbiBjYWxsZXIgbWF5IG9ubHkgd3JpdGUgaW50b1xuICAgKiBpdHMgT1dOIG9yZywgc28gcGluIHRoZSByb3cgdG8gdGhlIHRydXN0ZWQgdGVuYW50LWNvbnRleHQgb3JnLlxuICAgKlxuICAgKiBUaGUgc3RhbXAgZmlyZXMgd2hlbmV2ZXIgdGhlIHBheWxvYWQncyBgb3JnSWRgIGRpZmZlcnMgZnJvbSB0aGUgY29udGV4dCBvcmcg4oCUXG4gICAqIHdoaWNoIGNvdmVycyBCT1RIIGEgZm9yZ2VkL21pc21hdGNoZWQgYGRhdGEub3JnSWRgIEFORCBhbiBBQlNFTlQgb25lLiBUaGVcbiAgICogYWJzZW50IGNhc2UgaXMgdGhlIGltcG9ydGFudCB0ZW5hbnQtYm91bmRhcnkgZml4OiB0aGUgYG9yZ19pZGAgY29sdW1uIERFRkFVTFRzXG4gICAqIHRvIGBTWVNURU1fT1JHX0lEYCAoc2NoZW1hL3BpcGVsaW5lLnRzLCBzY2hlbWEvcGx1Z2luLnRzKSwgc28gYW4gaW5zZXJ0IHRoYXRcbiAgICogb21pdHMgYG9yZ0lkYCB3b3VsZCBvdGhlcndpc2UgbGFuZCB0aGUgdGVuYW50J3Mgcm93IGluIHRoZSBwdWJsaWMgc3lzdGVtXG4gICAqIGNhdGFsb2cg4oCUIGEgY3Jvc3MtdGVuYW50IGZhaWwtb3Blbi4gQWx3YXlzIGluamVjdGluZyBgY3R4Lm9yZ0lkYCBjbG9zZXMgaXQuXG4gICAqXG4gICAqIFN5c2FkbWluIChhbmQgb3V0LW9mLWNvbnRleHQgd29ya2VyL3N5c3RlbSBwYXRocywgd2hlcmUgYGdldFRlbmFudENvbnRleHQoKWBcbiAgICogaXMgdW5kZWZpbmVkKSBrZWVwIHRoZSBzdXBwbGllZCBvcmcsIG1hdGNoaW5nIHRoZSBSTFMgcG9saWN5XG4gICAqIGBjdXJyZW50X2lzX3N5c2FkbWluKCkgT1Igb3JnX2lkID0gY3VycmVudF9vcmdfaWQoKWAuXG4gICAqL1xuICBwcm90ZWN0ZWQgZW5mb3JjZU9yZ0lkKGRhdGE6IFRJbnNlcnQpOiBUSW5zZXJ0IHtcbiAgICBjb25zdCBjdHggPSBnZXRUZW5hbnRDb250ZXh0KCk7XG4gICAgY29uc3QgZCA9IGRhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgaWYgKGN0eCAmJiAhY3R4LmlzU3VwZXJBZG1pbiAmJiBjdHgub3JnSWQgJiYgZC5vcmdJZCAhPT0gY3R4Lm9yZ0lkKSB7XG4gICAgICAvLyBEaXN0aW5ndWlzaCB0aGUgdHdvIGNhc2VzIHRoYXQgcmVhY2ggaGVyZSBzbyB0aGUgbG9nIHN0YXlzIHVzZWZ1bCBhbmRcbiAgICAgIC8vIHF1aWV0OiBhIFBSRVNFTlQtYnV0LW1pc21hdGNoZWQgYG9yZ0lkYCBpcyBhbiBhY3R1YWwgb3ZlcnJpZGUgYXR0ZW1wdFxuICAgICAgLy8gKHdhcm4pLCB3aGlsZSBhbiBBQlNFTlQgYG9yZ0lkYCBpcyB0aGUgY29tbW9uIG5vcm1hbC13cml0ZSBwYXRoIHRoYXQganVzdFxuICAgICAgLy8gbmVlZHMgdGhlIGRlZmF1bHQgc3RhbXAgKGRlYnVnKSDigJQgbG9nZ2luZyB0aGF0IGF0IHdhcm4gZmxvb2RzIHRoZSBsb2cgb25cbiAgICAgIC8vIGV2ZXJ5IHdyaXRlIHRoYXQgb21pdHMgb3JnSWQuXG4gICAgICBjb25zdCBtZXRhID0geyBzdXBwbGllZDogJ29yZ0lkJyBpbiBkID8gZC5vcmdJZCA6IHVuZGVmaW5lZCwgZW5mb3JjZWQ6IGN0eC5vcmdJZCB9O1xuICAgICAgaWYgKCdvcmdJZCcgaW4gZCkge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignQ3J1ZFNlcnZpY2U6IG92ZXJyaWRpbmcgbWlzbWF0Y2hlZCBvcmcgb24gd3JpdGUnLCBtZXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnQ3J1ZFNlcnZpY2U6IHN0YW1waW5nIHRlbmFudC1jb250ZXh0IG9yZyBvbiB3cml0ZScsIG1ldGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgLi4uZCwgb3JnSWQ6IGN0eC5vcmdJZCB9IGFzIFRJbnNlcnQ7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBlbnRpdHlcbiAgICovXG4gIGFzeW5jIGNyZWF0ZShkYXRhOiBUSW5zZXJ0LCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VEVudGl0eT4ge1xuICAgIGNvbnN0IHNhZmVEYXRhID0gdGhpcy5lbmZvcmNlT3JnSWQoZGF0YSk7XG4gICAgY29uc3QgW2NyZWF0ZWRdID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5pbnNlcnQodGhpcy5zY2hlbWEpXG4gICAgICAudmFsdWVzKHtcbiAgICAgICAgLi4uc2FmZURhdGEsXG4gICAgICAgIGNyZWF0ZWRCeTogdXNlcklkIHx8ICdzeXN0ZW0nLFxuICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgIH0gYXMgYW55KVxuICAgICAgLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogdGhpcy5jb25mbGljdFRhcmdldCBhcyBhbnksXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIC4uLnNhZmVEYXRhLFxuICAgICAgICAgIC8vIFJFU1VSUkVDVCBvbiByZS1jcmVhdGU6IGBkZWxldGVgIHNvZnQtZGVsZXRlcyAoaXNBY3RpdmU9ZmFsc2UgKyBkZWxldGVkQXQvXG4gICAgICAgICAgLy8gZGVsZXRlZEJ5IHNldCksIGJ1dCB0aGUgdW5pcXVlIGNvbnN0cmFpbnQga2VlcHMgdGhlIHRvbWJzdG9uZWQgcm93LCBzbyBhXG4gICAgICAgICAgLy8gcmUtY3JlYXRlIHdpdGggdGhlIHNhbWUgY29uZmxpY3Qga2V5IGxhbmRzIGhlcmUuIFdpdGhvdXQgcmVzZXR0aW5nIHRoZXNlLFxuICAgICAgICAgIC8vIHRoZSByb3cncyBib2R5IHVwZGF0ZXMgYnV0IGl0IHN0YXlzIHNvZnQtZGVsZXRlZCBhbmQgbmV2ZXIgcmVhcHBlYXJzXG4gICAgICAgICAgLy8gKHJlYWRzIGRlZmF1bHQgdG8gaXNBY3RpdmU9dHJ1ZSkuIE1hdGNoZXMgdGhlIHBpcGVsaW5lL3BsdWdpbiBvdmVycmlkZXMuXG4gICAgICAgICAgaXNBY3RpdmU6IHRydWUsXG4gICAgICAgICAgZGVsZXRlZEF0OiBudWxsLFxuICAgICAgICAgIGRlbGV0ZWRCeTogbnVsbCxcbiAgICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgfSlcbiAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKTtcblxuICAgIC8vIEF3YWl0ZWQgaW50ZW50aW9uYWxseTogY2FjaGUgaW52YWxpZGF0aW9uIGhhcHBlbnMgaW4gdGhlIGhvb2ssIGFuZCBhXG4gICAgLy8gZmlyZS1hbmQtZm9yZ2V0IHBhdHRlcm4gbGV0cyBhIHN1YnNlcXVlbnQgcmVhZCBpbnNpZGUgdGhlIHNhbWUgcmVxdWVzdFxuICAgIC8vIHJldHVybiB0aGUgc3RhbGUgcHJlLXdyaXRlIGVudHJ5LiBUaGUgaG9vayBpcyBleHBlY3RlZCB0byBiZSBmYXN0XG4gICAgLy8gKHNpbmdsZSBSZWRpcyBvcCk7IHNsb3cgaG9va3Mgc2hvdWxkIHJ1biB0aGVpciBvd24gYmFja2dyb3VuZCB3b3JrLlxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLm9uQWZ0ZXJDcmVhdGUoY3JlYXRlZCwgdXNlcklkKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdMaWZlY3ljbGUgaG9vayBmYWlsZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYW4gZXhpc3RpbmcgZW50aXR5XG4gICAqL1xuICBhc3luYyB1cGRhdGUoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBkYXRhOiBQYXJ0aWFsPFRVcGRhdGU+LFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8VEVudGl0eSB8IG51bGw+IHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy53cml0ZUNvbmRpdGlvbnMoaWQsIG9yZ0lkKTtcblxuICAgIC8vIFNjcnViIGEgY2FsbGVyLXN1cHBsaWVkIGBvcmdJZGAgaW4gdGhlIHVwZGF0ZSBwYXlsb2FkIChhcyBjcmVhdGUgZG9lcyk6IHRoZVxuICAgIC8vIFdIRVJFIG9ubHkgcGlucyB3aGljaCByb3dzIHlvdSBjYW4gVEFSR0VULCBub3Qgd2hhdCB5b3UgY2FuIHNldCDigJQgd2l0aG91dCB0aGlzXG4gICAgLy8gYSB0ZW5hbnQgY291bGQgcmUtaG9tZSBhIHJvdyBpdCBvd25zIGludG8gYW5vdGhlciBvcmcgdmlhIGBkYXRhLm9yZ0lkYC5cbiAgICBjb25zdCBzYWZlRGF0YSA9IHRoaXMuZW5mb3JjZU9yZ0lkKGRhdGEgYXMgdW5rbm93biBhcyBUSW5zZXJ0KSBhcyB1bmtub3duIGFzIFBhcnRpYWw8VFVwZGF0ZT47XG5cbiAgICBjb25zdCBbdXBkYXRlZF0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgIC5zZXQoe1xuICAgICAgICAuLi5zYWZlRGF0YSxcbiAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgIH0gYXMgYW55KVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKTtcblxuICAgIGlmICh1cGRhdGVkKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLm9uQWZ0ZXJVcGRhdGUoaWQsIHVwZGF0ZWQsIHVzZXJJZCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1cGRhdGVkIHx8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGFuIGVudGl0eSAoc29mdCBkZWxldGUgYnkgc2V0dGluZyBpc0FjdGl2ZSA9IGZhbHNlKVxuICAgKi9cbiAgYXN5bmMgZGVsZXRlKGlkOiBzdHJpbmcsIG9yZ0lkOiBzdHJpbmcsIHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5IHwgbnVsbD4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLndyaXRlQ29uZGl0aW9ucyhpZCwgb3JnSWQpO1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cbiAgICBjb25zdCBbZGVsZXRlZF0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgIC5zZXQoe1xuICAgICAgICBpc0FjdGl2ZTogZmFsc2UsXG4gICAgICAgIHVwZGF0ZWRBdDogbm93LFxuICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgICAgZGVsZXRlZEF0OiBub3csXG4gICAgICAgIGRlbGV0ZWRCeTogdXNlcklkIHx8ICdzeXN0ZW0nLFxuICAgICAgICAvLyBTdGFtcCB0aGUgcHVyZ2UgZGVhZGxpbmUgc28gdGhlIHJldGVudGlvbiBzd2VlcCBjYW4gaGFyZC1kZWxldGUgbGF0ZXIuXG4gICAgICAgIC4uLnRoaXMucHVyZ2VBZnRlclN0YW1wKG5vdyksXG4gICAgICB9IGFzIGFueSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG5cbiAgICBpZiAoZGVsZXRlZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5vbkFmdGVyRGVsZXRlKGlkLCBkZWxldGVkLCB1c2VySWQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdMaWZlY3ljbGUgaG9vayBmYWlsZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGVsZXRlZCB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCBhbiBlbnRpdHkgYXMgdGhlIGRlZmF1bHQgZm9yIGEgcHJvamVjdC9vcmdhbml6YXRpb24gc2NvcGUuXG4gICAqIE1hcmtzIGFsbCBvdGhlciBlbnRpdGllcyBhcyBub24tZGVmYXVsdCwgdGhlbiBzZXRzIHRoZSBzcGVjaWZpZWQgZW50aXR5LlxuICAgKiBVc2VzIGEgdHJhbnNhY3Rpb24gdG8gZW5zdXJlIGF0b21pY2l0eS5cbiAgICovXG4gIGFzeW5jIHNldERlZmF1bHQoXG4gICAgcHJvamVjdDogc3RyaW5nLFxuICAgIG9yZzogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8VEVudGl0eT4ge1xuICAgIC8vIEEgbm9uLXN5c2FkbWluIG1heSBvbmx5IGZsaXAgZGVmYXVsdHMgd2l0aGluIGl0cyBPV04gb3JnIOKAlCBwaW4gdGhlIHNjb3BlIHRvXG4gICAgLy8gdGhlIHRydXN0ZWQgdGVuYW50IGNvbnRleHQgc28gYSBmb3J3YXJkZWQgYG9yZ2AgYXJnIGNhbid0IHRvdWNoIGFub3RoZXJcbiAgICAvLyB0ZW5hbnQncyBkZWZhdWx0cyAoUkxTIGlzIGluIG93bmVyLWJ5cGFzcyBtb2RlOyB0aGlzIGlzIHRoZSBnYXRlKS5cbiAgICBjb25zdCBjdHggPSBnZXRUZW5hbnRDb250ZXh0KCk7XG4gICAgaWYgKGN0eCAmJiAhY3R4LmlzU3VwZXJBZG1pbiAmJiBjdHgub3JnSWQpIG9yZyA9IGN0eC5vcmdJZDtcbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgY29uc3Qgb3JnQ29sdW1uID0gdGhpcy5nZXRPcmdDb2x1bW4oKTtcbiAgICAgIGNvbnN0IHByb2plY3RDb2x1bW4gPSB0aGlzLmdldFByb2plY3RDb2x1bW4oKTtcblxuICAgICAgLy8gQnVpbGQgc2NvcGluZyBjb25kaXRpb25zIGZvciBjbGVhcmluZyBkZWZhdWx0c1xuICAgICAgY29uc3Qgc2NvcGVDb25kaXRpb25zID0gW1xuICAgICAgICBlcShvcmdDb2x1bW4sIG9yZyksXG4gICAgICAgIGVxKHRoaXMuY29scy5pc0RlZmF1bHQsIHRydWUpLFxuICAgICAgXTtcbiAgICAgIGlmIChwcm9qZWN0Q29sdW1uKSB7XG4gICAgICAgIHNjb3BlQ29uZGl0aW9ucy5wdXNoKGVxKHByb2plY3RDb2x1bW4sIHByb2plY3QpKTtcbiAgICAgIH1cblxuICAgICAgLy8gTG9jayBleGlzdGluZyBkZWZhdWx0cyB3aXRoIEZPUiBVUERBVEUgdG8gcHJldmVudCBjb25jdXJyZW50IHNldERlZmF1bHQgcmFjZXNcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1QgaWQgRlJPTSAke3RoaXMuc2NoZW1hfVxuICAgICAgICAgICAgV0hFUkUgJHtvcmdDb2x1bW59ID0gJHtvcmd9XG4gICAgICAgICAgICAgIEFORCAke3RoaXMuY29scy5pc0RlZmF1bHR9ID0gdHJ1ZVxuICAgICAgICAgICAgJHtwcm9qZWN0Q29sdW1uID8gc3FsYEFORCAke3Byb2plY3RDb2x1bW59ID0gJHtwcm9qZWN0fWAgOiBzcWxgYH1cbiAgICAgICAgICAgIEZPUiBVUERBVEVgLFxuICAgICAgKTtcblxuICAgICAgLy8gTWFyayBhbGwgZW50aXRpZXMgaW4gc2NvcGUgYXMgbm9uLWRlZmF1bHRcbiAgICAgIGF3YWl0IHR4XG4gICAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAgIC5zZXQoe1xuICAgICAgICAgIGlzRGVmYXVsdDogZmFsc2UsXG4gICAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICAgIHVwZGF0ZWRCeTogdXNlcklkIHx8ICdzeXN0ZW0nLFxuICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgLndoZXJlKGFuZCguLi5zY29wZUNvbmRpdGlvbnMpKTtcblxuICAgICAgLy8gU2V0IHRoZSBzcGVjaWZpZWQgZW50aXR5IGFzIGRlZmF1bHQuIEd1YXJkIGFnYWluc3QgcHJvbW90aW5nIGFcbiAgICAgIC8vIHNvZnQtZGVsZXRlZCByb3cgKGlzQWN0aXZlID0gdHJ1ZSkg4oCUIGEgZGVsZXRlZCBlbnRpdHkgbXVzdCBuZXZlciBiZWNvbWVcbiAgICAgIC8vIHRoZSBhY3RpdmUgZGVmYXVsdCDigJQgYW5kIHBpbiB0aGUgaWQgd2l0aCB0aGUgc2FtZSBsb3dlcmNhc2VkXG4gICAgICAvLyBleGFjdElkQ29uZGl0aW9uIHRoZSBtdXRhdGlvbiBwYXRocyB1c2UgKHRoZSByYXcgYGVxKGNvbHMuaWQsIGlkKWAgaGVyZVxuICAgICAgLy8gc2tpcHBlZCB0aGUgbG93ZXItY2FzaW5nIHRoYXQgYGJ1aWxkSWRGaWx0ZXJgL2B3cml0ZUNvbmRpdGlvbnNgIGFwcGx5LFxuICAgICAgLy8gc28gYSBtaXhlZC1jYXNlIGlkIGNvdWxkIG1pc3MgaXRzIHJvdykuIEEgbm9uLW1hdGNoIOKGkiBOb3RGb3VuZEVycm9yIGJlbG93LlxuICAgICAgY29uc3QgW3VwZGF0ZWRdID0gYXdhaXQgdHhcbiAgICAgICAgLnVwZGF0ZSh0aGlzLnNjaGVtYSlcbiAgICAgICAgLnNldCh7XG4gICAgICAgICAgaXNEZWZhdWx0OiB0cnVlLFxuICAgICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICB1cGRhdGVkQnk6IHVzZXJJZCB8fCAnc3lzdGVtJyxcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgIC53aGVyZShcbiAgICAgICAgICBhbmQoXG4gICAgICAgICAgICB0aGlzLmV4YWN0SWRDb25kaXRpb24oaWQpLFxuICAgICAgICAgICAgZXEob3JnQ29sdW1uLCBvcmcpLFxuICAgICAgICAgICAgZXEodGhpcy5jb2xzLmlzQWN0aXZlLCB0cnVlKSxcbiAgICAgICAgICApLFxuICAgICAgICApXG4gICAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpO1xuXG4gICAgICBpZiAoIXVwZGF0ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoYEVudGl0eSB3aXRoIGlkICR7aWR9IG5vdCBmb3VuZGApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdXBkYXRlZDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgbXVsdGlwbGUgZW50aXRpZXMgbWF0Y2hpbmcgZmlsdGVyXG4gICAqL1xuICBhc3luYyB1cGRhdGVNYW55KFxuICAgIGZpbHRlcjogUGFydGlhbDxURmlsdGVyPixcbiAgICBkYXRhOiBQYXJ0aWFsPFRVcGRhdGU+LFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMuYnVpbGRDb25kaXRpb25zKGZpbHRlciwgb3JnSWQpO1xuICAgIC8vIE93bi1vcmcgd3JpdGUtcGluOiBidWlsZENvbmRpdGlvbnMgYWxzbyBtYXRjaGVzIHN5c3RlbS9vdGhlci1vcmcgUFVCTElDXG4gICAgLy8gcm93cywgc28gd2l0aG91dCB0aGUgc3RyaWN0IG9yZ0lkIHBpbiBhIGZpbHRlci1iYXNlZCB1cGRhdGUgY291bGQgbXV0YXRlXG4gICAgLy8gc2hhcmVkIChvciBhbm90aGVyIHRlbmFudCdzIHB1YmxpYykgcmVjb3Jkcy4gTWlycm9yIHVwZGF0ZS9kZWxldGUvXG4gICAgLy8gYnVsa0RlbGV0ZS4gKFNlZSB3cml0ZUNvbmRpdGlvbnMuKSBBbiBvcmdJZC1sZXNzIChzeXNhZG1pbikgY29udGV4dCBrZWVwc1xuICAgIC8vIGZ1bGwgYWNjZXNzLlxuICAgIGlmIChvcmdJZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKSk7XG5cbiAgICAvLyBTY3J1YiBhIGNhbGxlci1zdXBwbGllZCBvcmdJZCAoc2VlIHVwZGF0ZSgpKSBzbyBhIGZpbHRlci1iYXNlZCB1cGRhdGUgY2FuJ3RcbiAgICAvLyByZS1ob21lIHJvd3MgaW50byBhbm90aGVyIHRlbmFudC5cbiAgICBjb25zdCBzYWZlRGF0YSA9IHRoaXMuZW5mb3JjZU9yZ0lkKGRhdGEgYXMgdW5rbm93biBhcyBUSW5zZXJ0KSBhcyB1bmtub3duIGFzIFBhcnRpYWw8VFVwZGF0ZT47XG5cbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHtcbiAgICAgICAgLi4uc2FmZURhdGEsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICB9IGFzIGFueSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAucmV0dXJuaW5nKCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRFbnRpdHk+KHIpKSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIG11bHRpcGxlIGVudGl0aWVzIGluIGEgc2luZ2xlIGJhdGNoIGluc2VydC5cbiAgICogVXNlcyB1cHNlcnQgKG9uQ29uZmxpY3REb1VwZGF0ZSkg4oCUIGFsbCByb3dzIGFyZSBpbnNlcnRlZCBpbiBvbmUgcXVlcnkgcGVyIGNodW5rLlxuICAgKiBDaHVua3Mgb2YgMTAwIHRvIHN0YXkgd2l0aGluIFBvc3RncmVTUUwgcGFyYW1ldGVyIGxpbWl0cy5cbiAgICovXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgYG9uQ29uZmxpY3REb1VwZGF0ZWAgU0VUIGZvciBhIGJ1bGsgdXBzZXJ0LiBVbmxpa2UgYSBzaW5nbGUtcm93XG4gICAqIGNyZWF0ZSAod2hpY2ggY2FuIHNwcmVhZCB0aGUgb25lIHJvdydzIGRhdGEpLCBhIGJhdGNoZWQgaW5zZXJ0IGhhcyBtYW55IHJvd3MsXG4gICAqIHNvIGVhY2ggdXBkYXRhYmxlIGNvbHVtbiBpcyB3cml0dGVuIGZyb20gYGV4Y2x1ZGVkLipgICh0aGUgd291bGQtYmUtaW5zZXJ0ZWRcbiAgICogdmFsdWUpIOKAlCBvdGhlcndpc2UgYW4gZXhpc3Rpbmcgcm93J3MgZmllbGRzIGFyZSBzaWxlbnRseSBkaXNjYXJkZWQgYW5kIG9ubHlcbiAgICogdGltZXN0YW1wcyBidW1wLiBTa2lwcyBpZGVudGl0eS9pbW11dGFibGUgKGBpZGAsIGBjcmVhdGVkQXRgLCBgY3JlYXRlZEJ5YClcbiAgICogYW5kIHRoZSBjb25mbGljdC10YXJnZXQgY29sdW1uczsgYHVwZGF0ZWRBdGAvYHVwZGF0ZWRCeWAgZ2V0IHRoZSBmcmVzaCB2YWx1ZXMuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQnVsa1Vwc2VydFNldChub3c6IERhdGUsIHVzZXI6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCBjb25mbGljdE5hbWVzID0gbmV3IFNldCh0aGlzLmNvbmZsaWN0VGFyZ2V0Lm1hcCgoYykgPT4gKGMgYXMgdW5rbm93biBhcyB7IG5hbWU6IHN0cmluZyB9KS5uYW1lKSk7XG4gICAgY29uc3Qgc2V0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgY29sXSBvZiBPYmplY3QuZW50cmllcyhnZXRUYWJsZUNvbHVtbnModGhpcy5zY2hlbWEpKSkge1xuICAgICAgY29uc3QgbmFtZSA9IChjb2wgYXMgdW5rbm93biBhcyB7IG5hbWU6IHN0cmluZyB9KS5uYW1lO1xuICAgICAgaWYgKGtleSA9PT0gJ2lkJyB8fCBrZXkgPT09ICdjcmVhdGVkQXQnIHx8IGtleSA9PT0gJ2NyZWF0ZWRCeScgfHwgY29uZmxpY3ROYW1lcy5oYXMobmFtZSkpIGNvbnRpbnVlO1xuICAgICAgaWYgKGtleSA9PT0gJ3VwZGF0ZWRBdCcpIHsgc2V0W2tleV0gPSBub3c7IGNvbnRpbnVlOyB9XG4gICAgICBpZiAoa2V5ID09PSAndXBkYXRlZEJ5JykgeyBzZXRba2V5XSA9IHVzZXI7IGNvbnRpbnVlOyB9XG4gICAgICBzZXRba2V5XSA9IHNxbGBleGNsdWRlZC4ke3NxbC5pZGVudGlmaWVyKG5hbWUpfWA7XG4gICAgfVxuICAgIC8vIFJFU1VSUkVDVCBvbiBidWxrIHJlLWNyZWF0ZSAobWF0Y2hlcyB0aGUgc2luZ2xlLXJvdyBjcmVhdGUpOiByZXNldCB0aGVcbiAgICAvLyBzb2Z0LWRlbGV0ZSBjb2x1bW5zIGV4cGxpY2l0bHkgcmF0aGVyIHRoYW4gcmVseSBvbiBgZXhjbHVkZWQuKmAgKyBjb2x1bW5cbiAgICAvLyBkZWZhdWx0cywgc28gYSByZS1jcmVhdGVkIHNhbWUta2V5IHJvdyBpcyBhbHdheXMgcmVhY3RpdmF0ZWQsIG5vdCBsZWZ0XG4gICAgLy8gdG9tYnN0b25lZC4gQWxsIENydWRTZXJ2aWNlIGVudGl0aWVzIGNhcnJ5IHRoZXNlIChkZWxldGUoKSBzZXRzIGFsbCB0aHJlZSkuXG4gICAgc2V0LmlzQWN0aXZlID0gdHJ1ZTtcbiAgICBzZXQuZGVsZXRlZEF0ID0gbnVsbDtcbiAgICBzZXQuZGVsZXRlZEJ5ID0gbnVsbDtcbiAgICByZXR1cm4gc2V0O1xuICB9XG5cbiAgYXN5bmMgYnVsa0NyZWF0ZShpdGVtczogVEluc2VydFtdLCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gICAgY29uc3QgQ0hVTktfU0laRSA9IDEwMDtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IHVzZXIgPSB1c2VySWQgfHwgJ3N5c3RlbSc7XG4gICAgY29uc3QgY29uZmxpY3RTZXQgPSB0aGlzLmJ1aWxkQnVsa1Vwc2VydFNldChub3csIHVzZXIpO1xuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAgIGNvbnN0IGFsbENyZWF0ZWQ6IFRFbnRpdHlbXSA9IFtdO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSArPSBDSFVOS19TSVpFKSB7XG4gICAgICAgIGNvbnN0IGNodW5rID0gaXRlbXMuc2xpY2UoaSwgaSArIENIVU5LX1NJWkUpO1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSBjaHVuay5tYXAoZGF0YSA9PiAoe1xuICAgICAgICAgIC4uLnRoaXMuZW5mb3JjZU9yZ0lkKGRhdGEpLFxuICAgICAgICAgIGNyZWF0ZWRCeTogdXNlcixcbiAgICAgICAgICB1cGRhdGVkQnk6IHVzZXIsXG4gICAgICAgIH0gYXMgYW55KSk7XG5cbiAgICAgICAgY29uc3QgY3JlYXRlZCA9IGF3YWl0IHR4XG4gICAgICAgICAgLmluc2VydCh0aGlzLnNjaGVtYSlcbiAgICAgICAgICAudmFsdWVzKHZhbHVlcylcbiAgICAgICAgICAub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgICAgIHRhcmdldDogdGhpcy5jb25mbGljdFRhcmdldCBhcyBhbnksXG4gICAgICAgICAgICBzZXQ6IGNvbmZsaWN0U2V0IGFzIGFueSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpO1xuXG4gICAgICAgIGFsbENyZWF0ZWQucHVzaCguLi5jcmVhdGVkKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGFsbENyZWF0ZWQ7XG4gICAgfSk7XG5cbiAgICAvLyBSdW4gaG9va3MgaW4gcGFyYWxsZWwgYnV0IGF3YWl0IGFsbCBiZWZvcmUgcmV0dXJuaW5nIHNvIGEgc3Vic2VxdWVudFxuICAgIC8vIHJlYWQgaW4gdGhlIHNhbWUgcmVxdWVzdCBzZWVzIGEgY29oZXJlbnQgcG9zdC13cml0ZSB2aWV3LlxuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgcmVzdWx0cy5tYXAoZW50aXR5ID0+XG4gICAgICAgIHRoaXMub25BZnRlckNyZWF0ZShlbnRpdHksIHVzZXJJZCkuY2F0Y2goZXJyID0+XG4gICAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICAvKipcbiAgICogU29mdC1kZWxldGUgbXVsdGlwbGUgZW50aXRpZXMgYnkgSURzIGluIGEgc2luZ2xlIGJhdGNoIG9wZXJhdGlvbi5cbiAgICovXG4gIGFzeW5jIGJ1bGtEZWxldGUoXG4gICAgaWRzOiBzdHJpbmdbXSxcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIHVzZXJJZDogc3RyaW5nLFxuICAgIC8qKiBXaGVuIHRydWUsIG9ubHkgUFJJVkFURSByZWNvcmRzIGFyZSBkZWxldGVkIOKAlCBtaXJyb3JzIHRoZSBzaW5nbGUtZGVsZXRlXG4gICAgICogIGByZXF1aXJlUHVibGljQWNjZXNzYCBnYXRlIHNvIGEgbm9uLXN5c2FkbWluIGNhbid0IGJ1bGstZGVsZXRlIHB1YmxpY1xuICAgICAqICAoc2hhcmVkL3N5c2FkbWluLW1hbmFnZWQpIHJlY29yZHMuIE5vLW9wIGZvciBlbnRpdGllcyB3aXRob3V0IGFuXG4gICAgICogIGBhY2Nlc3NNb2RpZmllcmAgY29sdW1uLiBDYWxsZXJzIHBhc3MgYCFpc1N5c3RlbUFkbWluKHJlcSlgLiAqL1xuICAgIHJlc3RyaWN0VG9Qcml2YXRlID0gZmFsc2UsXG4gICk6IFByb21pc2U8VEVudGl0eVtdPiB7XG4gICAgaWYgKGlkcy5sZW5ndGggPT09IDApIHJldHVybiBbXTtcblxuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgdXNlciA9IHVzZXJJZCB8fCAnc3lzdGVtJztcbiAgICAvLyBPd25lci1zY29wZSB0aGUgYnVsayBzb2Z0LWRlbGV0ZTogYnVpbGRDb25kaXRpb25zIGFsc28gbWF0Y2hlcyBzeXN0ZW0vb3RoZXJcbiAgICAvLyAtb3JnIFBVQkxJQyByb3dzLCBzbyB3aXRob3V0IHRoZSBzdHJpY3Qgb3JnSWQgcGluIGEgdGVuYW50IGNvdWxkIGRlbGV0ZVxuICAgIC8vIHNoYXJlZCByZWNvcmRzIGJ5IGlkLiAoU2VlIHdyaXRlQ29uZGl0aW9ucy4pXG4gICAgY29uc3QgYWNjZXNzQ29sID0gdGhpcy5jb2xzLmFjY2Vzc01vZGlmaWVyO1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSBbXG4gICAgICBpbkFycmF5KHRoaXMuY29scy5pZCwgaWRzKSxcbiAgICAgIC4uLnRoaXMuYnVpbGRDb25kaXRpb25zKHt9IGFzIFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkKSxcbiAgICAgIC8vIFRlbmFudCBjb2x1bW4gKGdldE9yZ0NvbHVtbiwgYXNzZXJ0ZWQgbm9uLW51bGwpIOKAlCBjb25zaXN0ZW50IHdpdGhcbiAgICAgIC8vIHdyaXRlQ29uZGl0aW9uczsgbm8gc2lsZW50IGZhaWwtb3BlbiB3aGVuIHRoZSBwcm9wZXJ0eSBpcyBhYnNlbnQuXG4gICAgICAuLi4ob3JnSWQgPyBbZXEodGhpcy5nZXRPcmdDb2x1bW4oKSwgb3JnSWQpXSA6IFtdKSxcbiAgICAgIC4uLihyZXN0cmljdFRvUHJpdmF0ZSAmJiBhY2Nlc3NDb2wgPyBbZXEoYWNjZXNzQ29sLCAncHJpdmF0ZScpXSA6IFtdKSxcbiAgICBdO1xuXG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHR4XG4gICAgICAudXBkYXRlKHRoaXMuc2NoZW1hKVxuICAgICAgLnNldCh7XG4gICAgICAgIGlzQWN0aXZlOiBmYWxzZSxcbiAgICAgICAgdXBkYXRlZEF0OiBub3csXG4gICAgICAgIHVwZGF0ZWRCeTogdXNlcixcbiAgICAgICAgZGVsZXRlZEF0OiBub3csXG4gICAgICAgIGRlbGV0ZWRCeTogdXNlcixcbiAgICAgICAgLy8gU3RhbXAgdGhlIHB1cmdlIGRlYWRsaW5lIHNvIHRoZSByZXRlbnRpb24gc3dlZXAgY2FuIGhhcmQtZGVsZXRlIGxhdGVyLlxuICAgICAgICAuLi50aGlzLnB1cmdlQWZ0ZXJTdGFtcChub3cpLFxuICAgICAgfSBhcyBhbnkpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLnJldHVybmluZygpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBkZWxldGVkLm1hcChlbnRpdHkgPT5cbiAgICAgICAgdGhpcy5vbkFmdGVyRGVsZXRlKGVudGl0eS5pZCwgZW50aXR5LCB1c2VySWQpLmNhdGNoKGVyciA9PlxuICAgICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKCdMaWZlY3ljbGUgaG9vayBmYWlsZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgKTtcblxuICAgIHJldHVybiBkZWxldGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc3RvcmUgYSBzb2Z0LWRlbGV0ZWQgKHRvbWJzdG9uZWQpIGVudGl0eTogY2xlYXIgYGlzQWN0aXZlYC9gZGVsZXRlZEF0YC9cbiAgICogYGRlbGV0ZWRCeWAvYHB1cmdlQWZ0ZXJgIHNvIGl0IHJlYXBwZWFycyBpbiBub3JtYWwgcmVhZHMuXG4gICAqXG4gICAqIE1hdGNoZXMgT05MWSBhIGdlbnVpbmUgdG9tYnN0b25lIOKAlCBgaXNBY3RpdmUgPSBmYWxzZWAgQU5EIGBkZWxldGVkQXQgSVMgTk9UXG4gICAqIE5VTExgIOKAlCBzbyBhIG1lcmVseSAqZGVhY3RpdmF0ZWQqIHJvdyAoaXNBY3RpdmU9ZmFsc2UsIG5vIGRlbGV0ZWRBdCkgaXMgbmV2ZXJcbiAgICogc2lsZW50bHkgXCJyZXN0b3JlZFwiLiBQaW5uZWQgdG8gdGhlIGNhbGxlcidzIG93biBvcmcgKG9yZ0lkLWxlc3Mgc3lzYWRtaW5cbiAgICogY29udGV4dCBzcGFucyBvcmdzLCBtYXRjaGluZyBkZWxldGUvdXBkYXRlKS4gUmV0dXJucyBudWxsIHdoZW4gdGhlcmUgaXMgbm9cbiAgICogc3VjaCB0b21ic3RvbmUgKGFscmVhZHkgYWN0aXZlLCBwdXJnZWQsIG9yIHVua25vd24pIHNvIHRoZSByb3V0ZSBjYW4gNDA0LlxuICAgKiBBIHVuaXF1ZS1rZXkgY29sbGlzaW9uIChhIGxpdmUgcm93IGFscmVhZHkgaG9sZHMgdGhlIGtleSkgc3VyZmFjZXMgYXMgdGhlXG4gICAqIGRyaXZlcidzIHVuaXF1ZS12aW9sYXRpb24gZm9yIHRoZSByb3V0ZSB0byBtYXAgdG8gNDA5IOKAlCBpbiBwcmFjdGljZSB0aGVcbiAgICogdG9tYnN0b25lIElTIHRoZSBrZXkgaG9sZGVyLCBzbyB0aGlzIGlzIGRlZmVuc2l2ZS5cbiAgICovXG4gIGFzeW5jIHJlc3RvcmUoaWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZywgdXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPFRFbnRpdHkgfCBudWxsPiB7XG4gICAgaWYgKCF0aGlzLmNvbHMuZGVsZXRlZEF0KSByZXR1cm4gbnVsbDsgLy8gZW50aXR5IGhhcyBubyBzb2Z0LWRlbGV0ZSBsaWZlY3ljbGVcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtcbiAgICAgIHRoaXMuZXhhY3RJZENvbmRpdGlvbihpZCksXG4gICAgICBlcSh0aGlzLmNvbHMuaXNBY3RpdmUsIGZhbHNlKSxcbiAgICAgIHNxbGAke3RoaXMuY29scy5kZWxldGVkQXR9IElTIE5PVCBOVUxMYCxcbiAgICBdO1xuICAgIGlmIChvcmdJZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKSk7XG5cbiAgICBjb25zdCBbcmVzdG9yZWRdID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC51cGRhdGUodGhpcy5zY2hlbWEpXG4gICAgICAuc2V0KHtcbiAgICAgICAgaXNBY3RpdmU6IHRydWUsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgdXBkYXRlZEJ5OiB1c2VySWQgfHwgJ3N5c3RlbScsXG4gICAgICAgIGRlbGV0ZWRBdDogbnVsbCxcbiAgICAgICAgZGVsZXRlZEJ5OiBudWxsLFxuICAgICAgICAuLi4odGhpcy5jb2xzLnB1cmdlQWZ0ZXIgPyB7IHB1cmdlQWZ0ZXI6IG51bGwgfSA6IHt9KSxcbiAgICAgIH0gYXMgYW55KVxuICAgICAgLndoZXJlKGFuZCguLi5jb25kaXRpb25zKSlcbiAgICAgIC5yZXR1cm5pbmcoKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VEVudGl0eT4ocikpKTtcblxuICAgIGlmIChyZXN0b3JlZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5vbkFmdGVyUmVzdG9yZShpZCwgcmVzdG9yZWQsIHVzZXJJZCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN0b3JlZCB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgYSBzb2Z0LWRlbGV0ZWQgZW50aXR5IGJ5IGlkICh0aGUgaW52ZXJzZSBvZiB0aGUgZGVmYXVsdCBgaXNBY3RpdmU9dHJ1ZWBcbiAgICogcmVhZHMpIOKAlCB1c2VkIGJ5IHJlc3RvcmUgcm91dGVzIHRvIGxvYWQgdGhlIHRvbWJzdG9uZSBmb3IgYWNjZXNzLWNvbnRyb2xcbiAgICogZ2F0aW5nIGJlZm9yZSByZXN0b3JpbmcuIFJldHVybnMgbnVsbCB1bmxlc3MgdGhlIHJvdyBleGlzdHMgQU5EIGlzIGEgZ2VudWluZVxuICAgKiB0b21ic3RvbmUgKGBpc0FjdGl2ZT1mYWxzZWAgKyBgZGVsZXRlZEF0IElTIE5PVCBOVUxMYCkuXG4gICAqL1xuICBhc3luYyBmaW5kRGVsZXRlZEJ5SWQoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxURW50aXR5IHwgbnVsbD4ge1xuICAgIGlmICghdGhpcy5jb2xzLmRlbGV0ZWRBdCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXG4gICAgICB0aGlzLmV4YWN0SWRDb25kaXRpb24oaWQpLFxuICAgICAgZXEodGhpcy5jb2xzLmlzQWN0aXZlLCBmYWxzZSksXG4gICAgICBzcWxgJHt0aGlzLmNvbHMuZGVsZXRlZEF0fSBJUyBOT1QgTlVMTGAsXG4gICAgXTtcbiAgICBpZiAob3JnSWQpIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLmdldE9yZ0NvbHVtbigpLCBvcmdJZCkpO1xuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMucnVuUmVhZChwYXJlbnRPcmdJZCwgKCkgPT4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4gdHhcbiAgICAgIC5zZWxlY3QoKVxuICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAud2hlcmUoYW5kKC4uLmNvbmRpdGlvbnMpKVxuICAgICAgLmxpbWl0KDEpLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpKTtcblxuICAgIHJldHVybiByZXN1bHRzWzBdIHx8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBhbiBvcmcncyBzb2Z0LWRlbGV0ZWQgdG9tYnN0b25lcyAoYGlzQWN0aXZlPWZhbHNlYCArIGBkZWxldGVkQXQgSVMgTk9UXG4gICAqIE5VTExgKSwgbW9zdC1yZWNlbnRseS1kZWxldGVkIGZpcnN0IOKAlCBwb3dlcnMgdGhlIFwicmVjZW50bHkgZGVsZXRlZFwiIHJlc3RvcmVcbiAgICogVUkuIFJldHVybnMgYFtdYCBmb3IgZW50aXRpZXMgd2l0aG91dCBhIHNvZnQtZGVsZXRlIGxpZmVjeWNsZS4gYGxpbWl0YCBpc1xuICAgKiBjbGFtcGVkIHRvIFsxLCAyMDBdIHRvIGtlZXAgdGhlIHJlc3BvbnNlIGJvdW5kZWQgKHRoZSByZXRlbnRpb24gc3dlZXAgaGFyZC1cbiAgICogZGVsZXRlcyBvbGQgdG9tYnN0b25lcyBhbnl3YXksIHNvIHRoaXMgaXMgYSBzaG9ydCwgc2VsZi1saW1pdGluZyBsaXN0KS5cbiAgICovXG4gIGFzeW5jIGZpbmREZWxldGVkKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgb3B0czogeyBsaW1pdD86IG51bWJlcjsgb2Zmc2V0PzogbnVtYmVyIH0gPSB7fSxcbiAgICBwYXJlbnRPcmdJZD86IHN0cmluZyxcbiAgKTogUHJvbWlzZTxURW50aXR5W10+IHtcbiAgICBpZiAoIXRoaXMuY29scy5kZWxldGVkQXQpIHJldHVybiBbXTtcbiAgICBjb25zdCBsaW1pdCA9IE1hdGgubWluKE1hdGgubWF4KDEsIG9wdHMubGltaXQgPz8gNTApLCAyMDApO1xuICAgIGNvbnN0IG9mZnNldCA9IE1hdGgubWF4KDAsIG9wdHMub2Zmc2V0ID8/IDApO1xuXG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXG4gICAgICBlcSh0aGlzLmNvbHMuaXNBY3RpdmUsIGZhbHNlKSxcbiAgICAgIHNxbGAke3RoaXMuY29scy5kZWxldGVkQXR9IElTIE5PVCBOVUxMYCxcbiAgICBdO1xuICAgIGlmIChvcmdJZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuZ2V0T3JnQ29sdW1uKCksIG9yZ0lkKSk7XG5cbiAgICByZXR1cm4gdGhpcy5ydW5SZWFkKHBhcmVudE9yZ0lkLCAoKSA9PiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB0eFxuICAgICAgLnNlbGVjdCgpXG4gICAgICAuZnJvbSh0aGlzLnNjaGVtYSlcbiAgICAgIC53aGVyZShhbmQoLi4uY29uZGl0aW9ucykpXG4gICAgICAub3JkZXJCeShkZXNjKHRoaXMuY29scy5kZWxldGVkQXQhKSlcbiAgICAgIC5saW1pdChsaW1pdClcbiAgICAgIC5vZmZzZXQob2Zmc2V0KVxuICAgICAgLnRoZW4ociA9PiBkcml6emxlUm93czxURW50aXR5PihyKSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYXJkLWRlbGV0ZSBhIGJhdGNoIG9mIHRvbWJzdG9uZXMgd2hvc2UgcHVyZ2UgZGVhZGxpbmUgaGFzIHBhc3NlZFxuICAgKiAoYGRlbGV0ZWRBdCBJUyBOT1QgTlVMTCBBTkQgcHVyZ2VfYWZ0ZXIgPCBub3dgKS4gQmF0Y2hlZCAoYGxpbWl0YCkgc28gYVxuICAgKiBzd2VlcCB0aWNrIHN0YXlzIGJvdW5kZWQ7IHRoZSBwZXItc2VydmljZSBzd2VlcCBsb29wcyB1bnRpbCBhIHRpY2sgcmV0dXJuc1xuICAgKiBgPCBsaW1pdGAuIFJ1bnMgYWNyb3NzIEFMTCBvcmdzLCBzbyBjYWxsZXJzIE1VU1QgaW52b2tlIGl0IGZyb20gYSBzeXN0ZW1cbiAgICogKG5vLXRlbmFudCkgY29udGV4dC4gYG9uQmVmb3JlUHVyZ2VgIHRlYXJzIGRvd24gZGVwZW5kZW50cyBsYWNraW5nIE9OIERFTEVURVxuICAgKiBDQVNDQURFIChpbnNpZGUgdGhlIHR4KTsgYG9uQWZ0ZXJQdXJnZWAgaGFuZGxlcyBleHRlcm5hbCBzaWRlLWVmZmVjdHMuXG4gICAqIFJldHVybnMgdGhlIG51bWJlciBvZiByb3dzIHB1cmdlZC4gTm8tb3AgKDApIGZvciBlbnRpdGllcyB3aXRob3V0IHRoZSBjb2x1bW5zLlxuICAgKi9cbiAgYXN5bmMgcHVyZ2VFeHBpcmVkKG5vdzogRGF0ZSwgbGltaXQgPSA1MDApOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGlmICghdGhpcy5jb2xzLmRlbGV0ZWRBdCB8fCAhdGhpcy5jb2xzLnB1cmdlQWZ0ZXIpIHJldHVybiAwO1xuXG4gICAgY29uc3QgcHVyZ2VkSWRzID0gYXdhaXQgd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgY29uc3QgZG9vbWVkID0gYXdhaXQgdHhcbiAgICAgICAgLy8gYGFzIGFueWA6IGNvbHMuaWQgaXMgdGhlIGJhc2UgYEFueUNvbHVtbmAsIHdoaWNoIGRyaXp6bGUncyB0eXBlZFxuICAgICAgICAvLyBzZWxlY3QtZmllbGQgbWFwIGRvZXNuJ3QgYWNjZXB0IGRpcmVjdGx5IChzYW1lIGZyaWN0aW9uIHRoZSBgLnNldCgpYFxuICAgICAgICAvLyBjYXN0cyBlbHNld2hlcmUgaW4gdGhpcyBmaWxlIHdvcmsgYXJvdW5kKS4gUmVzdWx0IGlzIHJlLXR5cGVkIGJlbG93LlxuICAgICAgICAuc2VsZWN0KHsgaWQ6IHRoaXMuY29scy5pZCBhcyBhbnkgfSlcbiAgICAgICAgLmZyb20odGhpcy5zY2hlbWEpXG4gICAgICAgIC53aGVyZShhbmQoc3FsYCR7dGhpcy5jb2xzLmRlbGV0ZWRBdH0gSVMgTk9UIE5VTExgLCBzcWxgJHt0aGlzLmNvbHMucHVyZ2VBZnRlcn0gPCAke25vd31gKSlcbiAgICAgICAgLmxpbWl0KGxpbWl0KVxuICAgICAgICAudGhlbihyID0+IChyIGFzIEFycmF5PHsgaWQ6IHVua25vd24gfT4pLm1hcChkID0+IFN0cmluZyhkLmlkKSkpO1xuXG4gICAgICBpZiAoZG9vbWVkLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gICAgICAvLyBEZXBlbmRlbnQgdGVhcmRvd24gbXVzdCBoYXBwZW4gaW5zaWRlIHRoZSBzYW1lIHR4IHNvIGEgRkstYmxvY2tpbmcgY2hpbGRcbiAgICAgIC8vIGNhbid0IHN0cmFuZCB0aGUgcGFyZW50LiBBIHRocm93IGhlcmUgYWJvcnRzIHRoaXMgYmF0Y2ggKHJldHJpZWQgbmV4dCB0aWNrKS5cbiAgICAgIGF3YWl0IHRoaXMub25CZWZvcmVQdXJnZShkb29tZWQpO1xuXG4gICAgICBhd2FpdCB0eC5kZWxldGUodGhpcy5zY2hlbWEpLndoZXJlKGluQXJyYXkodGhpcy5jb2xzLmlkLCBkb29tZWQpKTtcbiAgICAgIHJldHVybiBkb29tZWQ7XG4gICAgfSk7XG5cbiAgICBpZiAocHVyZ2VkSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMub25BZnRlclB1cmdlKHB1cmdlZElkcyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ0xpZmVjeWNsZSBob29rIGZhaWxlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwdXJnZWRJZHMubGVuZ3RoO1xuICB9XG59XG4iXX0=