@pipeline-builder/pipeline-data 4.1.22 → 4.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,221 +1,36 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { createLogger, errorMessage, scrubAwsIdentifiers, scrubAwsIdentifiersFromString } from '@pipeline-builder/api-core';
4
- import { eq, inArray, sql } from 'drizzle-orm';
3
+ import { createLogger, errorMessage, isoOrNull, scrubAwsIdentifiersFromString } from '@pipeline-builder/api-core';
4
+ import { eq, sql } from 'drizzle-orm';
5
5
  import { drizzleRows } from './crud-service.js';
6
6
  import { schema } from '../database/drizzle-schema.js';
7
7
  import { withTenantTx, runWithTenantContext } from '../database/tenancy.js';
8
8
  // Extracted for size — see ./reporting/. Everything public is re-exported below
9
9
  // so `@pipeline-builder/pipeline-data`'s surface is unchanged by the split.
10
- import { inventoryCache, timeseriesCache } from './reporting/caches.js';
10
+ import { inventoryCache, invalidateOrgReports } from './reporting/caches.js';
11
11
  import { DORA_INCIDENT_WINDOW_HOURS, resolveIncidentWindowHours } from './reporting/dora-scoring.js';
12
12
  import { getDoraMetrics as doraMetrics, getDoraTrend as doraTrend, getBuildHealth as buildHealth, } from './reporting/dora.js';
13
+ // Aliased: the module functions and the delegating methods below share names.
14
+ import { ingestEvents as ingest } from './reporting/ingest.js';
13
15
  import { getPluginRuntime as pluginRuntime, getPluginRuntimeAggregate as pluginRuntimeAggregate, hasVerifiedPluginUse as verifiedPluginUse, } from './reporting/plugin-runtime.js';
14
16
  import { report } from './reporting/query-scope.js';
15
- // Aliased: the module functions and the delegating methods below share names.
16
- import { REPORTING_EVENT_RETENTION_DAYS, REPORTING_DORA_RETENTION_DAYS, resolveEventRetentionDays, resolveDoraRetentionDays, retentionCutoff, } from './reporting/retention.js';
17
+ import { purgeExpiredReportingData as purgeReportingRetention } from './reporting/retention-sweep.js';
18
+ import { REPORTING_EVENT_RETENTION_DAYS, REPORTING_DORA_RETENTION_DAYS } from './reporting/retention.js';
17
19
  import { assertReportInterval, scrubOptional, optionalStartedAtRange, startedAtWindow } from './reporting/sql-helpers.js';
18
20
  const logger = createLogger('reporting-service');
19
- /** An action/build event that can be attributed to a plugin step. */
20
- function isAttributable(e) {
21
- return (e.eventType === 'ACTION' || e.eventType === 'BUILD')
22
- && (e.eventSource === 'codepipeline' || e.eventSource === 'codebuild')
23
- && !!e.stageName && !!e.actionName;
24
- }
25
- function stepKey(pipelineId, stageName, actionName) {
26
- return `${pipelineId}\u0000${stageName}\u0000${actionName}`;
27
- }
28
- /**
29
- * Plugin attribution: the step manifests of every pipeline with an attributable
30
- * event, in ONE read per batch, keyed for an in-memory join. Names are compared
31
- * post-scrub on both sides (the manifest stores them scrubbed the same way).
32
- */
33
- async function loadStepPlugins(tx, attributable) {
34
- const pipelineIds = [...new Set(attributable.map((e) => e.pipelineId))];
35
- if (pipelineIds.length === 0)
36
- return new Map();
37
- const rows = await tx
38
- .select({
39
- pipelineId: schema.pipelineStepManifest.pipelineId,
40
- orgId: schema.pipelineStepManifest.orgId,
41
- stageName: schema.pipelineStepManifest.stageName,
42
- actionName: schema.pipelineStepManifest.actionName,
43
- pluginPublisher: schema.pipelineStepManifest.pluginPublisher,
44
- pluginPublisherId: schema.pipelineStepManifest.pluginPublisherId,
45
- pluginName: schema.pipelineStepManifest.pluginName,
46
- pluginVersion: schema.pipelineStepManifest.pluginVersion,
47
- })
48
- .from(schema.pipelineStepManifest)
49
- .where(inArray(schema.pipelineStepManifest.pipelineId, pipelineIds));
50
- return new Map(rows.map((m) => [stepKey(m.pipelineId, m.stageName, m.actionName), m]));
51
- }
52
- /**
53
- * The persisted row for one ingested event. This is the DURABLE persistence
54
- * boundary: every user/AWS-derived free-form string is scrubbed here, and
55
- * tenancy comes from the pipeline registry, never the caller's claimed org.
56
- */
57
- function toEventRow(event, registry, plugin) {
58
- return {
59
- // registry.pipelineId === event.pipelineId; the registry's is always a row
60
- // that exists (FK) and its orgId is the trusted tenant.
61
- pipelineId: registry.pipelineId,
62
- orgId: registry.orgId,
63
- eventSource: event.eventSource,
64
- eventType: event.eventType,
65
- status: event.status,
66
- // An AWS-ASSIGNED UUID, not free-form text: it can't carry an account id,
67
- // and scrubbing a 12-digit run inside it would corrupt the correlation key.
68
- executionId: event.executionId,
69
- // USER-AUTHORED pipeline-structure names — same untrusted origin as
70
- // errorMessage, so scrubbed (a stage named with an ARN must not persist).
71
- stageName: scrubOptional(event.stageName),
72
- actionName: scrubOptional(event.actionName),
73
- // HARD CONSTRAINT: an AWS account id must NEVER be persisted. Failure detail
74
- // and messages routinely carry ARNs and bare 12-digit account ids.
75
- errorMessage: scrubOptional(event.errorMessage),
76
- startedAt: event.startedAt ? new Date(event.startedAt) : undefined,
77
- completedAt: event.completedAt ? new Date(event.completedAt) : undefined,
78
- durationMs: event.durationMs,
79
- // Deploy attribution — scrubbed like the other free-form strings.
80
- commitSha: scrubOptional(event.commitSha),
81
- commitRef: scrubOptional(event.commitRef),
82
- environment: scrubOptional(event.environment),
83
- // Measured lead time: the oldest unshipped commit's time + the count. An
84
- // SCM-derived instant and a plain integer — nothing to scrub.
85
- commitTimestamp: event.commitTimestamp ? new Date(event.commitTimestamp) : undefined,
86
- commitCount: event.commitCount,
87
- // NULL for non-plugin actions and for pipelines deployed without a manifest.
88
- pluginPublisher: plugin?.pluginPublisher ?? null,
89
- pluginPublisherId: plugin?.pluginPublisherId ?? null,
90
- pluginName: plugin?.pluginName ?? null,
91
- pluginVersion: plugin?.pluginVersion ?? null,
92
- detail: event.detail !== undefined ? scrubAwsIdentifiers(event.detail) : undefined,
93
- };
94
- }
95
- /**
96
- * Fan terminal STAGE outcomes into the route's metric hook (pipeline-data can't
97
- * import api-server's registry) after the insert commits. Driven off the
98
- * INSERTED rows, so a re-delivered event the dedup index swallowed is never
99
- * counted twice. A non-null environment marks a deploy.
100
- */
101
- function emitStageMetrics(rows, onMetric) {
102
- for (const r of rows) {
103
- if (r.eventType !== 'STAGE' || (r.status !== 'SUCCEEDED' && r.status !== 'FAILED') || !r.pipelineId)
104
- continue;
105
- onMetric({
106
- pipelineId: r.pipelineId,
107
- orgId: r.orgId,
108
- stage: r.stageName ?? '',
109
- environment: r.environment ?? null,
110
- result: r.status === 'SUCCEEDED' ? 'succeeded' : 'failed',
111
- });
112
- }
113
- }
114
21
  export class ReportingService {
115
22
  /** Invalidate all cached reports for an org (call after event ingest). */
116
23
  async invalidateOrg(orgId) {
117
- await Promise.all([
118
- inventoryCache.invalidatePattern(`${orgId}:*`),
119
- timeseriesCache.invalidatePattern(`${orgId}:*`),
120
- ]);
24
+ await invalidateOrgReports(orgId);
121
25
  }
122
26
  /**
123
27
  * Resolve incoming events against the pipeline registry, batch-insert the
124
28
  * matched ones, and invalidate reporting caches for affected orgs.
125
- * Events for unregistered pipeline ids are dropped (and logged at WARN
126
- * with sample ids so an operator can see when EventBridge is delivering
127
- * events for pipelines that haven't called POST /pipelines/registry yet).
128
- *
129
- * Returns counts + a sample of unregistered pipeline ids for observability.
29
+ * See ./reporting/ingest.ts — the caller must already hold a sysadmin
30
+ * tenant scope, because a batch spans whatever orgs the registry resolves to.
130
31
  */
131
32
  async ingestEvents(events, onMetric) {
132
- // Multi-org batch insert: the caller resolves to multiple orgs via the
133
- // pipeline-registry lookup below, so the route layer MUST establish a
134
- // `runWithTenantContext({ isSuperAdmin: true }, ...)` scope before calling
135
- // this method. Under FORCE'd RLS, a single tx with `app.org_id = <one
136
- // org>` could only write events for that org; bypass via sysadmin is
137
- // the right gate for this server-internal cross-tenant endpoint. See
138
- // api/reporting/src/routes/event-ingest.ts for the wrapper.
139
- // Caches are invalidated AFTER the tx resolves: doing it inside held the pg
140
- // locks open across unrelated cache round-trips. The TTL is 2-5 min, so a
141
- // fire-and-forget post-commit invalidation is an acceptable trade.
142
- const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, insertedRows } = await withTenantTx(async (tx) => {
143
- // Batch-resolve all unique pipeline ids in one query
144
- const uniqueIds = [...new Set(events.map(e => e.pipelineId))];
145
- const registryRows = await tx
146
- .select({
147
- pipelineId: schema.pipelineRegistry.pipelineId,
148
- orgId: schema.pipelineRegistry.orgId,
149
- })
150
- .from(schema.pipelineRegistry)
151
- .where(inArray(schema.pipelineRegistry.pipelineId, uniqueIds));
152
- const idMap = new Map(registryRows.map(r => [r.pipelineId, r]));
153
- const stepPlugins = await loadStepPlugins(tx, events.filter((e) => isAttributable(e) && idMap.has(e.pipelineId)));
154
- // Build insert batch (skip events whose pipeline isn't registered)
155
- const rows = [];
156
- let skippedLocal = 0;
157
- const unregisteredLocal = [];
158
- for (const event of events) {
159
- const registry = idMap.get(event.pipelineId);
160
- if (!registry) {
161
- skippedLocal++;
162
- unregisteredLocal.push(event.pipelineId);
163
- continue;
164
- }
165
- const stageName = scrubOptional(event.stageName);
166
- const actionName = scrubOptional(event.actionName);
167
- const step = isAttributable(event) && stageName && actionName
168
- ? stepPlugins.get(stepKey(registry.pipelineId, stageName, actionName))
169
- : undefined;
170
- // Same-org guard: a manifest row is only ever written by the org that
171
- // owns the pipeline, but the ingest runs cross-tenant, so don't lean on it.
172
- rows.push(toEventRow(event, registry, step && step.orgId === registry.orgId ? step : undefined));
173
- }
174
- // SQS is at-least-once, so EventBridge can deliver the same state-change
175
- // twice. `onConflictDoNothing` + the partial unique index on
176
- // (pipeline_id, execution_id, event_type, status, stage_name, action_name)
177
- // makes re-delivery idempotent. `returning` gives the REAL inserted set so
178
- // counts, metrics and cache invalidation all ignore duplicates.
179
- const landed = rows.length > 0
180
- ? await tx.insert(schema.pipelineEvent).values(rows)
181
- .onConflictDoNothing()
182
- .returning({
183
- orgId: schema.pipelineEvent.orgId,
184
- pipelineId: schema.pipelineEvent.pipelineId,
185
- eventType: schema.pipelineEvent.eventType,
186
- status: schema.pipelineEvent.status,
187
- stageName: schema.pipelineEvent.stageName,
188
- environment: schema.pipelineEvent.environment,
189
- })
190
- : [];
191
- return {
192
- inserted: landed.length,
193
- skipped: skippedLocal,
194
- unregisteredPipelineIds: unregisteredLocal,
195
- affectedOrgs: [...new Set(landed.map(r => r.orgId))],
196
- insertedRows: landed,
197
- };
198
- });
199
- if (onMetric)
200
- emitStageMetrics(insertedRows, onMetric);
201
- // Surface the silent skip: an unregistered pipeline id usually means the
202
- // pipeline hasn't called POST /pipelines/registry yet (or its
203
- // pb.pipeline-id tag is missing/unreadable by the Lambda). Logging it
204
- // makes a broken join visible instead of looking like "no activity".
205
- if (unregisteredPipelineIds.length > 0) {
206
- logger.warn('Pipeline events skipped: pipeline id not found in registry', {
207
- count: unregisteredPipelineIds.length,
208
- sample: unregisteredPipelineIds.slice(0, 3),
209
- });
210
- }
211
- // Post-commit cache invalidation. Fire-and-forget with logging — TTL is
212
- // short enough that a missed invalidation self-heals.
213
- if (affectedOrgs.length > 0) {
214
- void Promise.all(affectedOrgs.map((org) => this.invalidateOrg(org).catch((err) => {
215
- logger.warn('Reporting cache invalidation failed', { orgId: org, error: errorMessage(err) });
216
- })));
217
- }
218
- return { inserted, skipped, unregisteredPipelineIds, affectedOrgs };
33
+ return ingest(events, onMetric);
219
34
  }
220
35
  // ── Category 1: Pipeline Execution & Performance ──
221
36
  /** Execution count per pipeline with status breakdown. */
@@ -835,150 +650,19 @@ export class ReportingService {
835
650
  return null;
836
651
  return {
837
652
  updatedAt: row.updatedAt.toISOString(),
838
- lastEventAt: row.lastEventAt ? row.lastEventAt.toISOString() : null,
653
+ lastEventAt: isoOrNull(row.lastEventAt),
839
654
  forwarded: row.forwarded ?? null,
840
655
  dropped: row.dropped ?? null,
841
656
  };
842
657
  }
843
658
  /**
844
- * Batched hard-DELETE of one reporting table's rows expired past a `created_at`
845
- * cutoff, scoped to an org and an optional row predicate. Uses a
846
- * `ctid`-in-subquery LIMIT so each statement touches at most `batchSize` rows
847
- * (short lock windows, no long table scan under lock); `RETURNING 1` lets us
848
- * count via `.rows.length` without depending on the driver's `rowCount`. Loops
849
- * until a short batch (drained) or the per-tick cap, then defers the rest.
850
- * MUST run inside a sysadmin tenant scope (see purgeExpiredReportingData) so it
851
- * bypasses RLS and can delete across the org's rows.
852
- */
853
- async #purgeReportingTableBatched(tableSql, predicate, batchSize, maxBatches) {
854
- let total = 0;
855
- for (let i = 0; i < maxBatches; i++) {
856
- const res = await withTenantTx((tx) => tx.execute(sql `
857
- DELETE FROM ${tableSql}
858
- WHERE ctid IN (
859
- SELECT ctid FROM ${tableSql}
860
- WHERE ${predicate}
861
- LIMIT ${batchSize}
862
- )
863
- RETURNING 1
864
- `));
865
- const purged = drizzleRows(res.rows).length;
866
- total += purged;
867
- if (purged < batchSize)
868
- break; // drained
869
- if (i === maxBatches - 1) {
870
- logger.warn('Reporting retention hit per-tick cap; remaining rows deferred', {
871
- purgedThisTick: total,
872
- });
873
- }
874
- }
875
- return total;
876
- }
877
- /**
878
- * Reporting retention sweep. Hard-deletes rows older than their
879
- * retention window, by `created_at`, across every org that has reporting data —
880
- * a **split** policy so high-volume standard events expire faster than the
881
- * low-volume DORA source:
882
- * - `pipeline_events WHERE environment IS NULL` → standard-event window.
883
- * - `pipeline_events WHERE environment IS NOT NULL` (deploy stages),
884
- * `deployment_outcomes`, and `incidents` → DORA-source window.
885
- * Each org's windows come from its `dora_settings` override, else the global
886
- * env defaults (see {@link resolveEventRetentionDays} / {@link resolveDoraRetentionDays}).
887
- * `ingest_health` and `dora_settings` are never purged. One `now` for the whole
888
- * tick (rows crossing the boundary mid-sweep wait for the next). Establishes a
889
- * sysadmin tenant scope so the deletes span all orgs / bypass RLS — this is a
890
- * cross-tenant housekeeping job. Returns (and logs) per-window purge tallies.
659
+ * Reporting retention sweep: hard-deletes rows past their per-org retention
660
+ * window (split standard-event vs DORA-source). Cross-tenant housekeeping —
661
+ * it establishes its own sysadmin scope. See ./reporting/retention-sweep.ts.
891
662
  */
892
663
  async purgeExpiredReportingData(opts = {}) {
893
- const batchSize = Math.max(1, opts.batchSize ?? 1000);
894
- const maxBatches = Math.max(1, opts.maxBatchesPerTable ?? 50);
895
- const now = opts.now ?? new Date();
896
- const resolveRetentionOrgId = opts.resolveRetentionOrgId ?? (async (orgId) => orgId);
897
- const counts = {
898
- orgs: 0, standardEvents: 0, doraEvents: 0, deploymentOutcomes: 0, incidents: 0,
899
- };
900
- return runWithTenantContext({ isSuperAdmin: true }, async () => {
901
- // Enumerate every org with reporting data (union across the three tables).
902
- const orgRows = drizzleRows((await withTenantTx((tx) => tx.execute(sql `
903
- SELECT DISTINCT org_id FROM (
904
- SELECT ${schema.pipelineEvent.orgId} AS org_id FROM ${schema.pipelineEvent}
905
- UNION
906
- SELECT ${schema.deploymentOutcome.orgId} AS org_id FROM ${schema.deploymentOutcome}
907
- UNION
908
- SELECT ${schema.incident.orgId} AS org_id FROM ${schema.incident}
909
- ) AS orgs
910
- `))).rows);
911
- if (orgRows.length === 0)
912
- return counts;
913
- // Per-org retention overrides (a single read; orgs without a row use defaults).
914
- const overrideRows = drizzleRows((await withTenantTx((tx) => tx.execute(sql `
915
- SELECT ${schema.doraSettings.orgId} AS org_id,
916
- ${schema.doraSettings.eventRetentionDays} AS event_retention_days,
917
- ${schema.doraSettings.doraRetentionDays} AS dora_retention_days
918
- FROM ${schema.doraSettings}
919
- `))).rows);
920
- const overrides = new Map(overrideRows.map((r) => [r.org_id, r]));
921
- const eventsTable = sql `${schema.pipelineEvent}`;
922
- const outcomesTable = sql `${schema.deploymentOutcome}`;
923
- const incidentsTable = sql `${schema.incident}`;
924
- for (const { org_id: orgId } of orgRows) {
925
- // Retention follows the account ROOT's entitlement (billing syncs it onto
926
- // the root only). An unresolvable root ⇒ skip this org this tick rather
927
- // than purge a team's rows on the (shorter) env default.
928
- let retentionOrgId;
929
- try {
930
- retentionOrgId = await resolveRetentionOrgId(orgId);
931
- }
932
- catch (err) {
933
- logger.warn('Reporting retention: root resolution threw; skipping org this tick', { orgId, error: errorMessage(err) });
934
- retentionOrgId = null;
935
- }
936
- if (retentionOrgId === null) {
937
- logger.warn('Reporting retention: could not resolve the retention root; org skipped this tick', { orgId });
938
- continue;
939
- }
940
- const ov = overrides.get(retentionOrgId);
941
- const eventDays = resolveEventRetentionDays(ov?.event_retention_days);
942
- const doraDays = resolveDoraRetentionDays(ov?.dora_retention_days);
943
- // `-1` = unlimited: keep forever, skip that window's deletes for
944
- // this org. Standard-event and DORA-source windows are independent; an org
945
- // with both `-1` is fully skipped. Log the skip so it's observable.
946
- const skipEvents = eventDays === -1;
947
- const skipDora = doraDays === -1;
948
- if (skipEvents || skipDora) {
949
- logger.info('Reporting retention sweep skipping unlimited window(s)', {
950
- orgId,
951
- standardEvents: skipEvents ? 'unlimited' : eventDays,
952
- doraSource: skipDora ? 'unlimited' : doraDays,
953
- });
954
- }
955
- if (!skipEvents) {
956
- const eventCutoff = retentionCutoff(now, eventDays);
957
- counts.standardEvents += await this.#purgeReportingTableBatched(eventsTable,
958
- // Spare rows carrying a commit timestamp: they are DORA SOURCE data.
959
- // Lead time joins deploys to the execution's earliest
960
- // `commit_timestamp`, and that enrichment rides the PIPELINE/source
961
- // event (environment IS NULL), never the deploy STAGE row. Purging
962
- // them on this short window while the deploys they explain live on
963
- // the DORA window made lead time read "unknown" for every range
964
- // older than the standard retention — silently, with the deploys
965
- // still counted. They follow the DORA window below instead.
966
- sql `org_id = ${orgId} AND environment IS NULL AND commit_timestamp IS NULL AND created_at < ${eventCutoff}`, batchSize, maxBatches);
967
- }
968
- if (!skipDora) {
969
- const doraCutoff = retentionCutoff(now, doraDays);
970
- counts.doraEvents += await this.#purgeReportingTableBatched(eventsTable, sql `org_id = ${orgId} AND (environment IS NOT NULL OR commit_timestamp IS NOT NULL) AND created_at < ${doraCutoff}`, batchSize, maxBatches);
971
- counts.deploymentOutcomes += await this.#purgeReportingTableBatched(outcomesTable, sql `org_id = ${orgId} AND created_at < ${doraCutoff}`, batchSize, maxBatches);
972
- counts.incidents += await this.#purgeReportingTableBatched(incidentsTable, sql `org_id = ${orgId} AND created_at < ${doraCutoff}`, batchSize, maxBatches);
973
- }
974
- counts.orgs += 1;
975
- }
976
- const purgedAny = counts.standardEvents + counts.doraEvents + counts.deploymentOutcomes + counts.incidents;
977
- if (purgedAny > 0)
978
- logger.info('Reporting retention sweep purged expired rows', { ...counts });
979
- return counts;
980
- });
664
+ return purgeReportingRetention(opts);
981
665
  }
982
666
  }
983
667
  export const reportingService = new ReportingService();
984
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM1SCxPQUFPLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBZSxNQUFNLG1CQUFtQixDQUFDO0FBQzdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUUsZ0ZBQWdGO0FBQ2hGLDRFQUE0RTtBQUM1RSxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JHLE9BQU8sRUFDTCxjQUFjLElBQUksV0FBVyxFQUM3QixZQUFZLElBQUksU0FBUyxFQUN6QixjQUFjLElBQUksV0FBVyxHQUM5QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxnQkFBZ0IsSUFBSSxhQUFhLEVBQ2pDLHlCQUF5QixJQUFJLHNCQUFzQixFQUNuRCxvQkFBb0IsSUFBSSxpQkFBaUIsR0FDMUMsTUFBTSwrQkFBK0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEQsOEVBQThFO0FBQzlFLE9BQU8sRUFDTCw4QkFBOEIsRUFBRSw2QkFBNkIsRUFDN0QseUJBQXlCLEVBQUUsd0JBQXdCLEVBQUUsZUFBZSxH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QU0sZ0JBQWdCLEdBQUcsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBzY3J1YkF3c0lkZW50aWZpZXJzLCBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGVxLCBpbkFycmF5LCBzcWwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBkcml6emxlUm93cywgdHlwZSBDcnVkVHggfSBmcm9tICcuL2NydWQtc2VydmljZS5qcyc7XG5pbXBvcnQgeyBzY2hlbWEgfSBmcm9tICcuLi9kYXRhYmFzZS9kcml6emxlLXNjaGVtYS5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHgsIHJ1bldpdGhUZW5hbnRDb250ZXh0IH0gZnJvbSAnLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5cbi8vIEV4dHJhY3RlZCBmb3Igc2l6ZSDigJQgc2VlIC4vcmVwb3J0aW5nLy4gRXZlcnl0aGluZyBwdWJsaWMgaXMgcmUtZXhwb3J0ZWQgYmVsb3dcbi8vIHNvIGBAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1kYXRhYCdzIHN1cmZhY2UgaXMgdW5jaGFuZ2VkIGJ5IHRoZSBzcGxpdC5cbmltcG9ydCB7IGludmVudG9yeUNhY2hlLCB0aW1lc2VyaWVzQ2FjaGUgfSBmcm9tICcuL3JlcG9ydGluZy9jYWNoZXMuanMnO1xuaW1wb3J0IHsgRE9SQV9JTkNJREVOVF9XSU5ET1dfSE9VUlMsIHJlc29sdmVJbmNpZGVudFdpbmRvd0hvdXJzIH0gZnJvbSAnLi9yZXBvcnRpbmcvZG9yYS1zY29yaW5nLmpzJztcbmltcG9ydCB7XG4gIGdldERvcmFNZXRyaWNzIGFzIGRvcmFNZXRyaWNzLFxuICBnZXREb3JhVHJlbmQgYXMgZG9yYVRyZW5kLFxuICBnZXRCdWlsZEhlYWx0aCBhcyBidWlsZEhlYWx0aCxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvZG9yYS5qcyc7XG5pbXBvcnQge1xuICBnZXRQbHVnaW5SdW50aW1lIGFzIHBsdWdpblJ1bnRpbWUsXG4gIGdldFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUgYXMgcGx1Z2luUnVudGltZUFnZ3JlZ2F0ZSxcbiAgaGFzVmVyaWZpZWRQbHVnaW5Vc2UgYXMgdmVyaWZpZWRQbHVnaW5Vc2UsXG59IGZyb20gJy4vcmVwb3J0aW5nL3BsdWdpbi1ydW50aW1lLmpzJztcbmltcG9ydCB7IHJlcG9ydCB9IGZyb20gJy4vcmVwb3J0aW5nL3F1ZXJ5LXNjb3BlLmpzJztcbi8vIEFsaWFzZWQ6IHRoZSBtb2R1bGUgZnVuY3Rpb25zIGFuZCB0aGUgZGVsZWdhdGluZyBtZXRob2RzIGJlbG93IHNoYXJlIG5hbWVzLlxuaW1wb3J0IHtcbiAgUkVQT1JUSU5HX0VWRU5UX1JFVEVOVElPTl9EQVlTLCBSRVBPUlRJTkdfRE9SQV9SRVRFTlRJT05fREFZUyxcbiAgcmVzb2x2ZUV2ZW50UmV0ZW50aW9uRGF5cywgcmVzb2x2ZURvcmFSZXRlbnRpb25EYXlzLCByZXRlbnRpb25DdXRvZmYsXG59IGZyb20gJy4vcmVwb3J0aW5nL3JldGVudGlvbi5qcyc7XG5pbXBvcnQgeyBhc3NlcnRSZXBvcnRJbnRlcnZhbCwgc2NydWJPcHRpb25hbCwgb3B0aW9uYWxTdGFydGVkQXRSYW5nZSwgc3RhcnRlZEF0V2luZG93IH0gZnJvbSAnLi9yZXBvcnRpbmcvc3FsLWhlbHBlcnMuanMnO1xuaW1wb3J0IHR5cGUge1xuICBFeGVjdXRpb25Db3VudCwgVGltZVNlcmllc0VudHJ5LCBEdXJhdGlvblN0YXRzLCBQaXBlbGluZUV4ZWN1dGlvbiwgU3RhZ2VGYWlsdXJlLCBTdGFnZUJvdHRsZW5lY2ssXG4gIEFjdGlvbkZhaWx1cmUsIEVycm9yRW50cnksIFBsdWdpblN1bW1hcnksIFR5cGVDb21wdXRlRGlzdHJpYnV0aW9uLCBWZXJzaW9uQ291bnQsXG4gIEJ1aWxkVGltZVNlcmllc0VudHJ5LCBCdWlsZER1cmF0aW9uLCBCdWlsZEZhaWx1cmUsXG4gIFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUsIFBsdWdpblJ1bnRpbWVGaWx0ZXIsIFBsdWdpblJ1bnRpbWVTdGF0cyxcbiAgUmVwb3J0aW5nUmV0ZW50aW9uT3B0aW9ucywgUmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzLFxuICBEb3JhT3B0aW9ucywgUmVwb3J0aW5nU2V0dGluZ3MsIFJlcG9ydGluZ1NldHRpbmdzUGF0Y2gsIEluY2lkZW50TGlzdEl0ZW0sIEluY2lkZW50VGVzdFJlc3VsdCxcbiAgRG9yYU1ldHJpY3MsIERvcmFUcmVuZFBvaW50LCBCdWlsZEhlYWx0aCwgSW5jaWRlbnRJbnB1dCxcbiAgSW5nZXN0RXZlbnQsIEluZ2VzdE1ldHJpYywgSW5nZXN0UmVzdWx0LCBJbmdlc3RIZWFsdGhTdGF0dXMsXG59IGZyb20gJy4vcmVwb3J0aW5nL3R5cGVzLmpzJztcblxuLy8gVGhlIHJlcG9ydGluZyB0eXBlcyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBwYWNrYWdlIEFQSS4gRW51bWVyYXRlZCByYXRoZXIgdGhhblxuLy8gYGV4cG9ydCAqYCBiZWNhdXNlIHRoZSByZXBvcnRpbmcgbW9kdWxlcyBhbHNvIGV4cG9ydCBpbnRlcm5hbHMgKG9yZ1Njb3BlLFxuLy8gcnVuUmVwb3J0LCB0aGUgY2FjaGVzLCB0aGUgRE9SQSByb3cgc2hhcGVzKSB0aGF0IG11c3Qgc3RheSBwcml2YXRlLlxuZXhwb3J0IHR5cGUge1xuICBCdWlsZEhlYWx0aCwgQnVpbGRIZWFsdGhTdGFnZSwgRG9yYUVudk1ldHJpY3MsIERvcmFMZXZlbCwgRG9yYU1ldHJpY3MsIERvcmFPcHRpb25zLCBEb3JhVHJlbmRQb2ludCxcbiAgSW5jaWRlbnRJbnB1dCwgSW5jaWRlbnRMaXN0SXRlbSwgUmVwb3J0aW5nU2V0dGluZ3MsIEluY2lkZW50VGVzdFJlc3VsdCxcbiAgSW5nZXN0RXZlbnQsIEluZ2VzdEhlYWx0aFN0YXR1cywgSW5nZXN0TWV0cmljLCBJbmdlc3RSZXN1bHQsXG4gIFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUsIFBsdWdpblJ1bnRpbWVGaWx0ZXIsIFBsdWdpblJ1bnRpbWVTdGF0cyxcbiAgUmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzLCBSZXBvcnRpbmdSZXRlbnRpb25PcHRpb25zLCBSZXBvcnRpbmdSZXRlbnRpb25TZXR0aW5ncyxcbiAgUmVwb3J0aW5nU2V0dGluZ3NQYXRjaCxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvdHlwZXMuanMnO1xuXG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLXNlcnZpY2UnKTtcblxudHlwZSBQaXBlbGluZUV2ZW50SW5zZXJ0ID0gdHlwZW9mIHNjaGVtYS5waXBlbGluZUV2ZW50LiRpbmZlckluc2VydDtcblxuLyoqIFRoZSBwbHVnaW4gYSBwaXBlbGluZSBzdGVwIHJ1bnMsIGZyb20gdGhlIHN0ZXAgbWFuaWZlc3QgaXRzIGxhc3QgZGVwbG95IHJlZ2lzdGVyZWQuICovXG5pbnRlcmZhY2UgU3RlcFBsdWdpbiB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHBsdWdpblB1Ymxpc2hlcjogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luUHVibGlzaGVySWQ6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpbk5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZyB8IG51bGw7XG59XG5cbi8qKiBBbiBhY3Rpb24vYnVpbGQgZXZlbnQgdGhhdCBjYW4gYmUgYXR0cmlidXRlZCB0byBhIHBsdWdpbiBzdGVwLiAqL1xuZnVuY3Rpb24gaXNBdHRyaWJ1dGFibGUoZTogSW5nZXN0RXZlbnQpOiBib29sZWFuIHtcbiAgcmV0dXJuIChlLmV2ZW50VHlwZSA9PT0gJ0FDVElPTicgfHwgZS5ldmVudFR5cGUgPT09ICdCVUlMRCcpXG4gICAgJiYgKGUuZXZlbnRTb3VyY2UgPT09ICdjb2RlcGlwZWxpbmUnIHx8IGUuZXZlbnRTb3VyY2UgPT09ICdjb2RlYnVpbGQnKVxuICAgICYmICEhZS5zdGFnZU5hbWUgJiYgISFlLmFjdGlvbk5hbWU7XG59XG5cbmZ1bmN0aW9uIHN0ZXBLZXkocGlwZWxpbmVJZDogc3RyaW5nLCBzdGFnZU5hbWU6IHN0cmluZywgYWN0aW9uTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke3BpcGVsaW5lSWR9XFx1MDAwMCR7c3RhZ2VOYW1lfVxcdTAwMDAke2FjdGlvbk5hbWV9YDtcbn1cblxuLyoqXG4gKiBQbHVnaW4gYXR0cmlidXRpb246IHRoZSBzdGVwIG1hbmlmZXN0cyBvZiBldmVyeSBwaXBlbGluZSB3aXRoIGFuIGF0dHJpYnV0YWJsZVxuICogZXZlbnQsIGluIE9ORSByZWFkIHBlciBiYXRjaCwga2V5ZWQgZm9yIGFuIGluLW1lbW9yeSBqb2luLiBOYW1lcyBhcmUgY29tcGFyZWRcbiAqIHBvc3Qtc2NydWIgb24gYm90aCBzaWRlcyAodGhlIG1hbmlmZXN0IHN0b3JlcyB0aGVtIHNjcnViYmVkIHRoZSBzYW1lIHdheSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxvYWRTdGVwUGx1Z2lucyh0eDogQ3J1ZFR4LCBhdHRyaWJ1dGFibGU6IEluZ2VzdEV2ZW50W10pOiBQcm9taXNlPE1hcDxzdHJpbmcsIFN0ZXBQbHVnaW4+PiB7XG4gIGNvbnN0IHBpcGVsaW5lSWRzID0gWy4uLm5ldyBTZXQoYXR0cmlidXRhYmxlLm1hcCgoZSkgPT4gZS5waXBlbGluZUlkKSldO1xuICBpZiAocGlwZWxpbmVJZHMubGVuZ3RoID09PSAwKSByZXR1cm4gbmV3IE1hcCgpO1xuICBjb25zdCByb3dzID0gYXdhaXQgdHhcbiAgICAuc2VsZWN0KHtcbiAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5waXBlbGluZUlkLFxuICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5vcmdJZCxcbiAgICAgIHN0YWdlTmFtZTogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnN0YWdlTmFtZSxcbiAgICAgIGFjdGlvbk5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5hY3Rpb25OYW1lLFxuICAgICAgcGx1Z2luUHVibGlzaGVyOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luUHVibGlzaGVyLFxuICAgICAgcGx1Z2luUHVibGlzaGVySWQ6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5QdWJsaXNoZXJJZCxcbiAgICAgIHBsdWdpbk5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5OYW1lLFxuICAgICAgcGx1Z2luVmVyc2lvbjogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblZlcnNpb24sXG4gICAgfSlcbiAgICAuZnJvbShzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QpXG4gICAgLndoZXJlKGluQXJyYXkoc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBpcGVsaW5lSWQsIHBpcGVsaW5lSWRzKSk7XG4gIHJldHVybiBuZXcgTWFwKHJvd3MubWFwKChtKSA9PiBbc3RlcEtleShtLnBpcGVsaW5lSWQsIG0uc3RhZ2VOYW1lLCBtLmFjdGlvbk5hbWUpLCBtXSkpO1xufVxuXG4vKipcbiAqIFRoZSBwZXJzaXN0ZWQgcm93IGZvciBvbmUgaW5nZXN0ZWQgZXZlbnQuIFRoaXMgaXMgdGhlIERVUkFCTEUgcGVyc2lzdGVuY2VcbiAqIGJvdW5kYXJ5OiBldmVyeSB1c2VyL0FXUy1kZXJpdmVkIGZyZWUtZm9ybSBzdHJpbmcgaXMgc2NydWJiZWQgaGVyZSwgYW5kXG4gKiB0ZW5hbmN5IGNvbWVzIGZyb20gdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBuZXZlciB0aGUgY2FsbGVyJ3MgY2xhaW1lZCBvcmcuXG4gKi9cbmZ1bmN0aW9uIHRvRXZlbnRSb3coZXZlbnQ6IEluZ2VzdEV2ZW50LCByZWdpc3RyeTogeyBwaXBlbGluZUlkOiBzdHJpbmc7IG9yZ0lkOiBzdHJpbmcgfSwgcGx1Z2luOiBTdGVwUGx1Z2luIHwgdW5kZWZpbmVkKTogUGlwZWxpbmVFdmVudEluc2VydCB7XG4gIHJldHVybiB7XG4gICAgLy8gcmVnaXN0cnkucGlwZWxpbmVJZCA9PT0gZXZlbnQucGlwZWxpbmVJZDsgdGhlIHJlZ2lzdHJ5J3MgaXMgYWx3YXlzIGEgcm93XG4gICAgLy8gdGhhdCBleGlzdHMgKEZLKSBhbmQgaXRzIG9yZ0lkIGlzIHRoZSB0cnVzdGVkIHRlbmFudC5cbiAgICBwaXBlbGluZUlkOiByZWdpc3RyeS5waXBlbGluZUlkLFxuICAgIG9yZ0lkOiByZWdpc3RyeS5vcmdJZCxcbiAgICBldmVudFNvdXJjZTogZXZlbnQuZXZlbnRTb3VyY2UsXG4gICAgZXZlbnRUeXBlOiBldmVudC5ldmVudFR5cGUsXG4gICAgc3RhdHVzOiBldmVudC5zdGF0dXMsXG4gICAgLy8gQW4gQVdTLUFTU0lHTkVEIFVVSUQsIG5vdCBmcmVlLWZvcm0gdGV4dDogaXQgY2FuJ3QgY2FycnkgYW4gYWNjb3VudCBpZCxcbiAgICAvLyBhbmQgc2NydWJiaW5nIGEgMTItZGlnaXQgcnVuIGluc2lkZSBpdCB3b3VsZCBjb3JydXB0IHRoZSBjb3JyZWxhdGlvbiBrZXkuXG4gICAgZXhlY3V0aW9uSWQ6IGV2ZW50LmV4ZWN1dGlvbklkLFxuICAgIC8vIFVTRVItQVVUSE9SRUQgcGlwZWxpbmUtc3RydWN0dXJlIG5hbWVzIOKAlCBzYW1lIHVudHJ1c3RlZCBvcmlnaW4gYXNcbiAgICAvLyBlcnJvck1lc3NhZ2UsIHNvIHNjcnViYmVkIChhIHN0YWdlIG5hbWVkIHdpdGggYW4gQVJOIG11c3Qgbm90IHBlcnNpc3QpLlxuICAgIHN0YWdlTmFtZTogc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpLFxuICAgIGFjdGlvbk5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSksXG4gICAgLy8gSEFSRCBDT05TVFJBSU5UOiBhbiBBV1MgYWNjb3VudCBpZCBtdXN0IE5FVkVSIGJlIHBlcnNpc3RlZC4gRmFpbHVyZSBkZXRhaWxcbiAgICAvLyBhbmQgbWVzc2FnZXMgcm91dGluZWx5IGNhcnJ5IEFSTnMgYW5kIGJhcmUgMTItZGlnaXQgYWNjb3VudCBpZHMuXG4gICAgZXJyb3JNZXNzYWdlOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVycm9yTWVzc2FnZSksXG4gICAgc3RhcnRlZEF0OiBldmVudC5zdGFydGVkQXQgPyBuZXcgRGF0ZShldmVudC5zdGFydGVkQXQpIDogdW5kZWZpbmVkLFxuICAgIGNvbXBsZXRlZEF0OiBldmVudC5jb21wbGV0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LmNvbXBsZXRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICBkdXJhdGlvbk1zOiBldmVudC5kdXJhdGlvbk1zLFxuICAgIC8vIERlcGxveSBhdHRyaWJ1dGlvbiDigJQgc2NydWJiZWQgbGlrZSB0aGUgb3RoZXIgZnJlZS1mb3JtIHN0cmluZ3MuXG4gICAgY29tbWl0U2hhOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFNoYSksXG4gICAgY29tbWl0UmVmOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFJlZiksXG4gICAgZW52aXJvbm1lbnQ6IHNjcnViT3B0aW9uYWwoZXZlbnQuZW52aXJvbm1lbnQpLFxuICAgIC8vIE1lYXN1cmVkIGxlYWQgdGltZTogdGhlIG9sZGVzdCB1bnNoaXBwZWQgY29tbWl0J3MgdGltZSArIHRoZSBjb3VudC4gQW5cbiAgICAvLyBTQ00tZGVyaXZlZCBpbnN0YW50IGFuZCBhIHBsYWluIGludGVnZXIg4oCUIG5vdGhpbmcgdG8gc2NydWIuXG4gICAgY29tbWl0VGltZXN0YW1wOiBldmVudC5jb21taXRUaW1lc3RhbXAgPyBuZXcgRGF0ZShldmVudC5jb21taXRUaW1lc3RhbXApIDogdW5kZWZpbmVkLFxuICAgIGNvbW1pdENvdW50OiBldmVudC5jb21taXRDb3VudCxcbiAgICAvLyBOVUxMIGZvciBub24tcGx1Z2luIGFjdGlvbnMgYW5kIGZvciBwaXBlbGluZXMgZGVwbG95ZWQgd2l0aG91dCBhIG1hbmlmZXN0LlxuICAgIHBsdWdpblB1Ymxpc2hlcjogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5QdWJsaXNoZXJJZDogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXJJZCA/PyBudWxsLFxuICAgIHBsdWdpbk5hbWU6IHBsdWdpbj8ucGx1Z2luTmFtZSA/PyBudWxsLFxuICAgIHBsdWdpblZlcnNpb246IHBsdWdpbj8ucGx1Z2luVmVyc2lvbiA/PyBudWxsLFxuICAgIGRldGFpbDogZXZlbnQuZGV0YWlsICE9PSB1bmRlZmluZWQgPyBzY3J1YkF3c0lkZW50aWZpZXJzKGV2ZW50LmRldGFpbCkgOiB1bmRlZmluZWQsXG4gIH07XG59XG5cbi8qKlxuICogRmFuIHRlcm1pbmFsIFNUQUdFIG91dGNvbWVzIGludG8gdGhlIHJvdXRlJ3MgbWV0cmljIGhvb2sgKHBpcGVsaW5lLWRhdGEgY2FuJ3RcbiAqIGltcG9ydCBhcGktc2VydmVyJ3MgcmVnaXN0cnkpIGFmdGVyIHRoZSBpbnNlcnQgY29tbWl0cy4gRHJpdmVuIG9mZiB0aGVcbiAqIElOU0VSVEVEIHJvd3MsIHNvIGEgcmUtZGVsaXZlcmVkIGV2ZW50IHRoZSBkZWR1cCBpbmRleCBzd2FsbG93ZWQgaXMgbmV2ZXJcbiAqIGNvdW50ZWQgdHdpY2UuIEEgbm9uLW51bGwgZW52aXJvbm1lbnQgbWFya3MgYSBkZXBsb3kuXG4gKi9cbmZ1bmN0aW9uIGVtaXRTdGFnZU1ldHJpY3MoXG4gIHJvd3M6IFJlYWRvbmx5QXJyYXk8eyBvcmdJZDogc3RyaW5nOyBwaXBlbGluZUlkOiBzdHJpbmcgfCBudWxsOyBldmVudFR5cGU6IHN0cmluZzsgc3RhdHVzOiBzdHJpbmc7IHN0YWdlTmFtZTogc3RyaW5nIHwgbnVsbDsgZW52aXJvbm1lbnQ6IHN0cmluZyB8IG51bGwgfT4sXG4gIG9uTWV0cmljOiAobTogSW5nZXN0TWV0cmljKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIGZvciAoY29uc3QgciBvZiByb3dzKSB7XG4gICAgaWYgKHIuZXZlbnRUeXBlICE9PSAnU1RBR0UnIHx8IChyLnN0YXR1cyAhPT0gJ1NVQ0NFRURFRCcgJiYgci5zdGF0dXMgIT09ICdGQUlMRUQnKSB8fCAhci5waXBlbGluZUlkKSBjb250aW51ZTtcbiAgICBvbk1ldHJpYyh7XG4gICAgICBwaXBlbGluZUlkOiByLnBpcGVsaW5lSWQsXG4gICAgICBvcmdJZDogci5vcmdJZCxcbiAgICAgIHN0YWdlOiByLnN0YWdlTmFtZSA/PyAnJyxcbiAgICAgIGVudmlyb25tZW50OiByLmVudmlyb25tZW50ID8/IG51bGwsXG4gICAgICByZXN1bHQ6IHIuc3RhdHVzID09PSAnU1VDQ0VFREVEJyA/ICdzdWNjZWVkZWQnIDogJ2ZhaWxlZCcsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJlcG9ydGluZ1NlcnZpY2Uge1xuXG4gIC8qKiBJbnZhbGlkYXRlIGFsbCBjYWNoZWQgcmVwb3J0cyBmb3IgYW4gb3JnIChjYWxsIGFmdGVyIGV2ZW50IGluZ2VzdCkuICovXG4gIGFzeW5jIGludmFsaWRhdGVPcmcob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIGludmVudG9yeUNhY2hlLmludmFsaWRhdGVQYXR0ZXJuKGAke29yZ0lkfToqYCksXG4gICAgICB0aW1lc2VyaWVzQ2FjaGUuaW52YWxpZGF0ZVBhdHRlcm4oYCR7b3JnSWR9OipgKSxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIGluY29taW5nIGV2ZW50cyBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgYmF0Y2gtaW5zZXJ0IHRoZVxuICAgKiBtYXRjaGVkIG9uZXMsIGFuZCBpbnZhbGlkYXRlIHJlcG9ydGluZyBjYWNoZXMgZm9yIGFmZmVjdGVkIG9yZ3MuXG4gICAqIEV2ZW50cyBmb3IgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gICAqIHdpdGggc2FtcGxlIGlkcyBzbyBhbiBvcGVyYXRvciBjYW4gc2VlIHdoZW4gRXZlbnRCcmlkZ2UgaXMgZGVsaXZlcmluZ1xuICAgKiBldmVudHMgZm9yIHBpcGVsaW5lcyB0aGF0IGhhdmVuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQpLlxuICAgKlxuICAgKiBSZXR1cm5zIGNvdW50cyArIGEgc2FtcGxlIG9mIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZHMgZm9yIG9ic2VydmFiaWxpdHkuXG4gICAqL1xuICBhc3luYyBpbmdlc3RFdmVudHMoZXZlbnRzOiBJbmdlc3RFdmVudFtdLCBvbk1ldHJpYz86IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQpOiBQcm9taXNlPEluZ2VzdFJlc3VsdD4ge1xuICAgIC8vIE11bHRpLW9yZyBiYXRjaCBpbnNlcnQ6IHRoZSBjYWxsZXIgcmVzb2x2ZXMgdG8gbXVsdGlwbGUgb3JncyB2aWEgdGhlXG4gICAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAgIC8vIGBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCAuLi4pYCBzY29wZSBiZWZvcmUgY2FsbGluZ1xuICAgIC8vIHRoaXMgbWV0aG9kLiBVbmRlciBGT1JDRSdkIFJMUywgYSBzaW5nbGUgdHggd2l0aCBgYXBwLm9yZ19pZCA9IDxvbmVcbiAgICAvLyBvcmc+YCBjb3VsZCBvbmx5IHdyaXRlIGV2ZW50cyBmb3IgdGhhdCBvcmc7IGJ5cGFzcyB2aWEgc3lzYWRtaW4gaXNcbiAgICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgICAvLyBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzIGZvciB0aGUgd3JhcHBlci5cbiAgICAvLyBDYWNoZXMgYXJlIGludmFsaWRhdGVkIEFGVEVSIHRoZSB0eCByZXNvbHZlczogZG9pbmcgaXQgaW5zaWRlIGhlbGQgdGhlIHBnXG4gICAgLy8gbG9ja3Mgb3BlbiBhY3Jvc3MgdW5yZWxhdGVkIGNhY2hlIHJvdW5kLXRyaXBzLiBUaGUgVFRMIGlzIDItNSBtaW4sIHNvIGFcbiAgICAvLyBmaXJlLWFuZC1mb3JnZXQgcG9zdC1jb21taXQgaW52YWxpZGF0aW9uIGlzIGFuIGFjY2VwdGFibGUgdHJhZGUuXG4gICAgY29uc3QgeyBpbnNlcnRlZCwgc2tpcHBlZCwgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMsIGFmZmVjdGVkT3JncywgaW5zZXJ0ZWRSb3dzIH0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgICAgY29uc3QgdW5pcXVlSWRzID0gWy4uLm5ldyBTZXQoZXZlbnRzLm1hcChlID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgICAgIGNvbnN0IHJlZ2lzdHJ5Um93cyA9IGF3YWl0IHR4XG4gICAgICAgIC5zZWxlY3Qoe1xuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5LnBpcGVsaW5lSWQsXG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5Lm9yZ0lkLFxuICAgICAgICB9KVxuICAgICAgICAuZnJvbShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeSlcbiAgICAgICAgLndoZXJlKGluQXJyYXkoc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCwgdW5pcXVlSWRzKSk7XG5cbiAgICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcbiAgICAgIGNvbnN0IHN0ZXBQbHVnaW5zID0gYXdhaXQgbG9hZFN0ZXBQbHVnaW5zKHR4LCBldmVudHMuZmlsdGVyKChlKSA9PiBpc0F0dHJpYnV0YWJsZShlKSAmJiBpZE1hcC5oYXMoZS5waXBlbGluZUlkKSkpO1xuXG4gICAgICAvLyBCdWlsZCBpbnNlcnQgYmF0Y2ggKHNraXAgZXZlbnRzIHdob3NlIHBpcGVsaW5lIGlzbid0IHJlZ2lzdGVyZWQpXG4gICAgICBjb25zdCByb3dzOiBQaXBlbGluZUV2ZW50SW5zZXJ0W10gPSBbXTtcbiAgICAgIGxldCBza2lwcGVkTG9jYWwgPSAwO1xuICAgICAgY29uc3QgdW5yZWdpc3RlcmVkTG9jYWw6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gaWRNYXAuZ2V0KGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgICBpZiAoIXJlZ2lzdHJ5KSB7XG4gICAgICAgICAgc2tpcHBlZExvY2FsKys7XG4gICAgICAgICAgdW5yZWdpc3RlcmVkTG9jYWwucHVzaChldmVudC5waXBlbGluZUlkKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGFnZU5hbWUgPSBzY3J1Yk9wdGlvbmFsKGV2ZW50LnN0YWdlTmFtZSk7XG4gICAgICAgIGNvbnN0IGFjdGlvbk5hbWUgPSBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpO1xuICAgICAgICBjb25zdCBzdGVwID0gaXNBdHRyaWJ1dGFibGUoZXZlbnQpICYmIHN0YWdlTmFtZSAmJiBhY3Rpb25OYW1lXG4gICAgICAgICAgPyBzdGVwUGx1Z2lucy5nZXQoc3RlcEtleShyZWdpc3RyeS5waXBlbGluZUlkLCBzdGFnZU5hbWUsIGFjdGlvbk5hbWUpKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICAvLyBTYW1lLW9yZyBndWFyZDogYSBtYW5pZmVzdCByb3cgaXMgb25seSBldmVyIHdyaXR0ZW4gYnkgdGhlIG9yZyB0aGF0XG4gICAgICAgIC8vIG93bnMgdGhlIHBpcGVsaW5lLCBidXQgdGhlIGluZ2VzdCBydW5zIGNyb3NzLXRlbmFudCwgc28gZG9uJ3QgbGVhbiBvbiBpdC5cbiAgICAgICAgcm93cy5wdXNoKHRvRXZlbnRSb3coZXZlbnQsIHJlZ2lzdHJ5LCBzdGVwICYmIHN0ZXAub3JnSWQgPT09IHJlZ2lzdHJ5Lm9yZ0lkID8gc3RlcCA6IHVuZGVmaW5lZCkpO1xuICAgICAgfVxuXG4gICAgICAvLyBTUVMgaXMgYXQtbGVhc3Qtb25jZSwgc28gRXZlbnRCcmlkZ2UgY2FuIGRlbGl2ZXIgdGhlIHNhbWUgc3RhdGUtY2hhbmdlXG4gICAgICAvLyB0d2ljZS4gYG9uQ29uZmxpY3REb05vdGhpbmdgICsgdGhlIHBhcnRpYWwgdW5pcXVlIGluZGV4IG9uXG4gICAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAgIC8vIG1ha2VzIHJlLWRlbGl2ZXJ5IGlkZW1wb3RlbnQuIGByZXR1cm5pbmdgIGdpdmVzIHRoZSBSRUFMIGluc2VydGVkIHNldCBzb1xuICAgICAgLy8gY291bnRzLCBtZXRyaWNzIGFuZCBjYWNoZSBpbnZhbGlkYXRpb24gYWxsIGlnbm9yZSBkdXBsaWNhdGVzLlxuICAgICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICAgID8gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZUV2ZW50KS52YWx1ZXMocm93cylcbiAgICAgICAgICAub25Db25mbGljdERvTm90aGluZygpXG4gICAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQub3JnSWQsXG4gICAgICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVFdmVudC5waXBlbGluZUlkLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgICBzdGF0dXM6IHNjaGVtYS5waXBlbGluZUV2ZW50LnN0YXR1cyxcbiAgICAgICAgICAgIHN0YWdlTmFtZTogc2NoZW1hLnBpcGVsaW5lRXZlbnQuc3RhZ2VOYW1lLFxuICAgICAgICAgICAgZW52aXJvbm1lbnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmVudmlyb25tZW50LFxuICAgICAgICAgIH0pXG4gICAgICAgIDogW107XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGluc2VydGVkOiBsYW5kZWQubGVuZ3RoLFxuICAgICAgICBza2lwcGVkOiBza2lwcGVkTG9jYWwsXG4gICAgICAgIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzOiB1bnJlZ2lzdGVyZWRMb2NhbCxcbiAgICAgICAgYWZmZWN0ZWRPcmdzOiBbLi4ubmV3IFNldChsYW5kZWQubWFwKHIgPT4gci5vcmdJZCkpXSxcbiAgICAgICAgaW5zZXJ0ZWRSb3dzOiBsYW5kZWQsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgaWYgKG9uTWV0cmljKSBlbWl0U3RhZ2VNZXRyaWNzKGluc2VydGVkUm93cywgb25NZXRyaWMpO1xuXG4gICAgLy8gU3VyZmFjZSB0aGUgc2lsZW50IHNraXA6IGFuIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZCB1c3VhbGx5IG1lYW5zIHRoZVxuICAgIC8vIHBpcGVsaW5lIGhhc24ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCAob3IgaXRzXG4gICAgLy8gcGIucGlwZWxpbmUtaWQgdGFnIGlzIG1pc3NpbmcvdW5yZWFkYWJsZSBieSB0aGUgTGFtYmRhKS4gTG9nZ2luZyBpdFxuICAgIC8vIG1ha2VzIGEgYnJva2VuIGpvaW4gdmlzaWJsZSBpbnN0ZWFkIG9mIGxvb2tpbmcgbGlrZSBcIm5vIGFjdGl2aXR5XCIuXG4gICAgaWYgKHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdQaXBlbGluZSBldmVudHMgc2tpcHBlZDogcGlwZWxpbmUgaWQgbm90IGZvdW5kIGluIHJlZ2lzdHJ5Jywge1xuICAgICAgICBjb3VudDogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoLFxuICAgICAgICBzYW1wbGU6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLnNsaWNlKDAsIDMpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gUG9zdC1jb21taXQgY2FjaGUgaW52YWxpZGF0aW9uLiBGaXJlLWFuZC1mb3JnZXQgd2l0aCBsb2dnaW5nIOKAlCBUVEwgaXNcbiAgICAvLyBzaG9ydCBlbm91Z2ggdGhhdCBhIG1pc3NlZCBpbnZhbGlkYXRpb24gc2VsZi1oZWFscy5cbiAgICBpZiAoYWZmZWN0ZWRPcmdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHZvaWQgUHJvbWlzZS5hbGwoYWZmZWN0ZWRPcmdzLm1hcCgob3JnKSA9PlxuICAgICAgICB0aGlzLmludmFsaWRhdGVPcmcob3JnKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLCBhZmZlY3RlZE9yZ3MgfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAxOiBQaXBlbGluZSBFeGVjdXRpb24gJiBQZXJmb3JtYW5jZSDilIDilIBcblxuXG4gIC8qKiBFeGVjdXRpb24gY291bnQgcGVyIHBpcGVsaW5lIHdpdGggc3RhdHVzIGJyZWFrZG93bi4gKi9cbiAgYXN5bmMgZ2V0RXhlY3V0aW9uQ291bnQob3JnSWQ6IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10sIHJhbmdlPzogeyBmcm9tPzogc3RyaW5nOyB0bz86IHN0cmluZyB9KTogUHJvbWlzZTxFeGVjdXRpb25Db3VudFtdPiB7XG4gICAgLy8gT3B0aW9uYWwgW2Zyb20sdG9dIHdpbmRvdyBvbiB0aGUgZXhlY3V0aW9uJ3Mgc3RhcnRlZF9hdCwgbWlycm9yaW5nIHRoZVxuICAgIC8vIHNpYmxpbmcgdGltZXNlcmllcyByZXBvcnRzIHNvIHRoZSBkYXNoYm9hcmQgZGF0ZS1yYW5nZSBwaWNrZXIgbmFycm93cyB0aGVcbiAgICAvLyBjb3VudCB0b28gKGFuIGVtcHR5IHJhbmdlID0gYWxsLXRpbWUsIHByZXNlcnZpbmcgdGhlIHByaW9yIGJlaGF2aW9yKS4gVGhlXG4gICAgLy8gcmFuZ2UgcmlkZXMgdGhlIEpPSU4gc28gcGlwZWxpbmVzIHdpdGggbm8gaW4td2luZG93IGV2ZW50cyBzdGlsbCBsaXN0XG4gICAgLy8gKExFRlQgc2VtYW50aWNzIHByZXNlcnZlZCB2aWEgdGhlIGlubmVyLWpvaW4gZmlsdGVyIOKAlCBhIHBpcGVsaW5lIHdpdGggemVyb1xuICAgIC8vIG1hdGNoaW5nIGV2ZW50cyBkcm9wcyBmcm9tIHRoZSBjb3VudCwgc2FtZSBhcyBiZWZvcmUgZm9yIGl0cyB3aW5kb3cpLlxuICAgIGNvbnN0IHJhbmdlQ2xhdXNlID0gb3B0aW9uYWxTdGFydGVkQXRSYW5nZShyYW5nZSk7XG4gICAgcmV0dXJuIHJlcG9ydDxFeGVjdXRpb25Db3VudD4oYGV4ZWMtY291bnQ6JHtyYW5nZT8uZnJvbSA/PyAnJ306JHtyYW5nZT8udG8gPz8gJyd9YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5wcm9qZWN0LCBwLm9yZ2FuaXphdGlvbiwgcC5waXBlbGluZV9uYW1lLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIE1JTihlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGZpcnN0X2V4ZWN1dGlvbixcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X2V4ZWN1dGlvblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lfSBwXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZSBPTiBlLnBpcGVsaW5lX2lkID0gcC5pZFxuICAgICAgICAgIEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyAhPSAnU1RBUlRFRCdcbiAgICAgICAgICAke3JhbmdlQ2xhdXNlfVxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBwLmlzX2FjdGl2ZSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgcC5pZFxuICAgICAgICBPUkRFUiBCWSB0b3RhbCBERVNDXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXItcGlwZWxpbmUgZXhlY3V0aW9uIGhpc3Rvcnkg4oCUIERJU1RJTkNUIGV4ZWN1dGlvbnMgZm9yIG9uZSBwaXBlbGluZSxcbiAgICogbmV3ZXN0IGZpcnN0LiBHcm91cHMgYWxsIGV2ZW50cyBieSBgZXhlY3V0aW9uX2lkYCBpbiBhIHNpbmdsZSBzY2FuIGFuZFxuICAgKiByb2xscyBlYWNoIGV4ZWN1dGlvbiB1cCB0byBvbmUgcm93OlxuICAgKiAgIC0gc3RhdHVzOiBkZXJpdmVkIGZyb20gdGhlIFBJUEVMSU5FLXR5cGUgZXZlbnRzLiBGQUlMRUQgd2lucywgdGhlblxuICAgKiAgICAgU1VDQ0VFREVELCB0aGVuIENBTkNFTEVEOyBhbiBleGVjdXRpb24gd2l0aCBubyB0ZXJtaW5hbCBQSVBFTElORSBldmVudFxuICAgKiAgICAgaXMgc3RpbGwgYGluLXByb2dyZXNzYC5cbiAgICogICAtIHN0YXJ0ZWRBdC9lbmRlZEF0L2R1cmF0aW9uTXM6IGZyb20gdGhlIFBJUEVMSU5FIGxpZmVjeWNsZSBldmVudHMuXG4gICAqICAgLSBmYWlsaW5nU3RhZ2UvZmFpbGluZ0FjdGlvbjogdGhlIGZpcnN0IEZBSUxFRCBTVEFHRS9BQ1RJT04gZXZlbnQgKGNoZWFwIOKAlFxuICAgKiAgICAgc2FtZSBzY2FuLCBubyBleHRyYSBxdWVyeSkuXG4gICAqXG4gICAqIE9SRy1TQ09QSU5HOiBpZGVudGljYWwgdG8gdGhlIHNpYmxpbmcgZXhlY3V0aW9uIHJlcG9ydHMg4oCUIGpvaW5zIHRoZSBwaXBlbGluZVxuICAgKiByZWdpc3RyeSB0YWJsZSAoYHBpcGVsaW5lYCkgYW5kIGdhdGVzIG9uIGBwLm9yZ19pZCAke3ByZWR9YCwgd2hlcmUgYHByZWRgIGlzXG4gICAqIHRoZSBzaW5nbGUtb3JnIGA9ICRvcmdgIG9yICh3aXRoIGEgcm9sbHVwKSBhbiBgSU4gKC4uLilgIG92ZXIgdGhlIG9yZ+KGknRlYW1cbiAgICogc3VidHJlZS4gQSBwaXBlbGluZUlkIGJlbG9uZ2luZyB0byBhbm90aGVyIG9yZyB5aWVsZHMgemVybyByb3dzLlxuICAgKi9cbiAgYXN5bmMgbGlzdFBpcGVsaW5lRXhlY3V0aW9ucyhcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIHBpcGVsaW5lSWQ6IHN0cmluZyxcbiAgICBvcmdJZHM/OiBzdHJpbmdbXSxcbiAgICByYW5nZT86IHsgZnJvbT86IHN0cmluZzsgdG8/OiBzdHJpbmcgfSxcbiAgICBsaW1pdDogbnVtYmVyID0gNTAsXG4gICk6IFByb21pc2U8UGlwZWxpbmVFeGVjdXRpb25bXT4ge1xuICAgIGNvbnN0IHJhbmdlQ2xhdXNlID0gb3B0aW9uYWxTdGFydGVkQXRSYW5nZShyYW5nZSk7XG4gICAgcmV0dXJuIHJlcG9ydDxQaXBlbGluZUV4ZWN1dGlvbj4oYHBpcGVsaW5lLWV4ZWN1dGlvbnM6JHtwaXBlbGluZUlkfToke3JhbmdlPy5mcm9tID8/ICcnfToke3JhbmdlPy50byA/PyAnJ306JHtsaW1pdH1gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmV4ZWN1dGlvbl9pZCxcbiAgICAgICAgICBDQVNFXG4gICAgICAgICAgICBXSEVOIGJvb2xfb3IoZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5zdGF0dXMgPSAnRkFJTEVEJykgVEhFTiAnZmFpbGVkJ1xuICAgICAgICAgICAgV0hFTiBib29sX29yKGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpIFRIRU4gJ3N1Y2NlZWRlZCdcbiAgICAgICAgICAgIFdIRU4gYm9vbF9vcihlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpIFRIRU4gJ2NhbmNlbGVkJ1xuICAgICAgICAgICAgRUxTRSAnaW4tcHJvZ3Jlc3MnXG4gICAgICAgICAgRU5EIEFTIHN0YXR1cyxcbiAgICAgICAgICBNSU4oZS5zdGFydGVkX2F0KSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScpOjp0ZXh0IEFTIHN0YXJ0ZWRfYXQsXG4gICAgICAgICAgTUFYKGUuY29tcGxldGVkX2F0KSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScpOjp0ZXh0IEFTIGVuZGVkX2F0LFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScpOjppbnQgQVMgZHVyYXRpb25fbXMsXG4gICAgICAgICAgKEFSUkFZX0FHRyhlLnN0YWdlX25hbWUpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1NUQUdFJyBBTkQgZS5zdGF0dXMgPSAnRkFJTEVEJykpWzFdIEFTIGZhaWxpbmdfc3RhZ2UsXG4gICAgICAgICAgKEFSUkFZX0FHRyhlLmFjdGlvbl9uYW1lKSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdBQ1RJT04nIEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnKSlbMV0gQVMgZmFpbGluZ19hY3Rpb25cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5waXBlbGluZV9pZCA9ICR7cGlwZWxpbmVJZH0gQU5EIGUuZXhlY3V0aW9uX2lkIElTIE5PVCBOVUxMXG4gICAgICAgICAgJHtyYW5nZUNsYXVzZX1cbiAgICAgICAgR1JPVVAgQlkgZS5leGVjdXRpb25faWRcbiAgICAgICAgT1JERVIgQlkgTUFYKGUuY3JlYXRlZF9hdCkgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCk7XG4gIH1cblxuICAvKiogU3VjY2VzcyByYXRlIG92ZXIgdGltZSBmb3IgYW4gb3JnLiAqL1xuICBhc3luYyBnZXRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxUaW1lU2VyaWVzRW50cnlbXT4ge1xuICAgIGFzc2VydFJlcG9ydEludGVydmFsKGludGVydmFsKTtcbiAgICByZXR1cm4gcmVwb3J0PFRpbWVTZXJpZXNFbnRyeT4oYHN1Y2Nlc3MtcmF0ZToke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORSdcbiAgICAgICAgICBBTkQgZS5zdGF0dXMgSU4gKCdTVUNDRUVERUQnLCAnRkFJTEVEJywgJ0NBTkNFTEVEJylcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBBdmVyYWdlIGR1cmF0aW9uIHBlciBwaXBlbGluZS4gKi9cbiAgYXN5bmMgZ2V0QXZlcmFnZUR1cmF0aW9uKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPER1cmF0aW9uU3RhdHNbXT4ge1xuICAgIHJldHVybiByZXBvcnQ8RHVyYXRpb25TdGF0cz4oYGF2Zy1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5wcm9qZWN0LCBwLnBpcGVsaW5lX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1JTihlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1pbl9tcyxcbiAgICAgICAgICBNQVgoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtYXhfbXMsXG4gICAgICAgICAgUEVSQ0VOVElMRV9DT05UKDAuOTUpIFdJVEhJTiBHUk9VUCAoT1JERVIgQlkgZS5kdXJhdGlvbl9tcyk6OmludCBBUyBwOTVfbXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBleGVjdXRpb25zXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwLmlkIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBTdGFnZSBmYWlsdXJlIGhlYXRtYXAg4oCUIHdoaWNoIHN0YWdlcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldFN0YWdlRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8U3RhZ2VGYWlsdXJlW10+IHtcbiAgICByZXR1cm4gcmVwb3J0PFN0YWdlRmFpbHVyZT4oYHN0YWdlLWZhaWx1cmVzOiR7ZnJvbX06JHt0b31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWx1cmVzLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgZmFpbHVyZV9wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ1NUQUdFJyBBTkQgZS5zdGFnZV9uYW1lIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgZS5zdGFnZV9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3RpbmN0IGRlcGxveSBgZW52aXJvbm1lbnRgIHZhbHVlcyBvYnNlcnZlZCBpbiB0aGUgd2luZG93IOKAlCBwb3dlcnMgdGhlXG4gICAqIERPUkEgZW52aXJvbm1lbnQtc2NvcGUgZGF0YWxpc3QuIE9yZy1zY29wZWQgKyByb2xsdXAtYXdhcmUgbGlrZSB0aGUgc2libGluZ1xuICAgKiByZXBvcnRzOyBvbmx5IG5vbi1udWxsIGVudmlyb25tZW50cyAoaS5lLiBkZXBsb3ktYXR0cmlidXRlZCBleGVjdXRpb25zKS5cbiAgICovXG4gIGFzeW5jIGdldFJlcG9ydEVudmlyb25tZW50cyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCByZXBvcnQ8eyBlbnZpcm9ubWVudDogc3RyaW5nIH0+KGByZXBvcnQtZW52czoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUIERJU1RJTkNUIGUuZW52aXJvbm1lbnQgQVMgZW52aXJvbm1lbnRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5lbnZpcm9ubWVudCBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIE9SREVSIEJZIGVudmlyb25tZW50XG4gICAgICBgKTtcbiAgICByZXR1cm4gcm93cy5tYXAoKHJvdykgPT4gcm93LmVudmlyb25tZW50KTtcbiAgfVxuXG4gIC8qKiBTdGFnZSBib3R0bGVuZWNrcyDigJQgc2xvd2VzdCBzdGFnZXMgcGVyIHBpcGVsaW5lLiAqL1xuICBhc3luYyBnZXRTdGFnZUJvdHRsZW5lY2tzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPFN0YWdlQm90dGxlbmVja1tdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxTdGFnZUJvdHRsZW5lY2s+KGBzdGFnZS1ib3R0bGVuZWNrczoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5waXBlbGluZV9uYW1lLCBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgcC5pZCwgZS5zdGFnZV9uYW1lIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBBY3Rpb24gZmFpbHVyZSByYXRlIOKAlCB3aGljaCBwbHVnaW4gc3RlcHMgZmFpbCBtb3N0LiAqL1xuICBhc3luYyBnZXRBY3Rpb25GYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxBY3Rpb25GYWlsdXJlW10+IHtcbiAgICByZXR1cm4gcmVwb3J0PEFjdGlvbkZhaWx1cmU+KGBhY3Rpb24tZmFpbHVyZXM6JHtmcm9tfToke3RvfWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuYWN0aW9uX25hbWUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWx1cmVzLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgZmFpbHVyZV9wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ0FDVElPTicgQU5EIGUuYWN0aW9uX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBlLmFjdGlvbl9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVycm9yIGNhdGVnb3JpemF0aW9uIOKAlCBncm91cCBmYWlsdXJlIG1lc3NhZ2VzLiBFeGVjdXRpb24gcmVwb3J0LCBzb1xuICAgKiByb2xsdXAtYXdhcmUgZXhhY3RseSBsaWtlIHRoZSBzaWJsaW5nIGV4ZWN1dGlvbiByZXBvcnRzOiB3aXRoIGBvcmdJZHNgXG4gICAqICh0aGUgb3Jn4oaSdGVhbSBzdWJ0cmVlKSB0aGUgb3JnIGdhdGUgYmVjb21lcyBhbiBgSU4gKC4uLilgIGFuZCB0aGUgcmVhZCBydW5zXG4gICAqIGZyZXNoIHVuZGVyIHN5c2FkbWluIHZpYSBgcnVuUmVwb3J0YDsgc2luZ2xlLW9yZyByZWFkcyBrZWVwIHRoZSBwZXItb3JnIGNhY2hlLlxuICAgKi9cbiAgYXN5bmMgZ2V0RXJyb3JzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgbGltaXQ6IG51bWJlciA9IDIwLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8RXJyb3JFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxFcnJvckVudHJ5PihgZXJyb3JzOiR7ZnJvbX06JHt0b306JHtsaW1pdH1gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBTVUJTVFJJTkcoZS5lcnJvcl9tZXNzYWdlIEZST00gMSBGT1IgMjAwKSBBUyBlcnJvcl9wYXR0ZXJuLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgb2NjdXJyZW5jZXMsXG4gICAgICAgICAgQ09VTlQoRElTVElOQ1QgZS5waXBlbGluZV9pZCk6OmludCBBUyBhZmZlY3RlZF9waXBlbGluZXMsXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9zZWVuXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuc3RhdHVzID0gJ0ZBSUxFRCcgQU5EIGUuZXJyb3JfbWVzc2FnZSBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIGVycm9yX3BhdHRlcm4gT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGZvdXIgRE9SQSBtZWFzdXJlcyBwbHVzIHRoZWlyIHBlci1lbnZpcm9ubWVudCBicmVha2Rvd24uXG4gICAqIEltcGxlbWVudGF0aW9uIGluIC4vcmVwb3J0aW5nL2RvcmEudHMg4oCUIHNlZSB0aGF0IGZpbGUncyBoZWFkZXIgZm9yIHdoeS5cbiAgICovXG4gIGdldERvcmFNZXRyaWNzKFxuICAgIG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10sIG9wdHM6IERvcmFPcHRpb25zID0ge30sXG4gICk6IFByb21pc2U8RG9yYU1ldHJpY3M+IHtcbiAgICByZXR1cm4gZG9yYU1ldHJpY3Mob3JnSWQsIGZyb20sIHRvLCBvcmdJZHMsIG9wdHMpO1xuICB9XG5cbiAgLyoqIERPUkEgbWVhc3VyZXMgYnVja2V0ZWQgb3ZlciB0aW1lLiAqL1xuICBnZXREb3JhVHJlbmQoXG4gICAgb3JnSWQ6IHN0cmluZywgaW50ZXJ2YWw6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSwgb3B0czogRG9yYU9wdGlvbnMgPSB7fSxcbiAgKTogUHJvbWlzZTxEb3JhVHJlbmRQb2ludFtdPiB7XG4gICAgcmV0dXJuIGRvcmFUcmVuZChvcmdJZCwgaW50ZXJ2YWwsIGZyb20sIHRvLCBvcmdJZHMsIG9wdHMpO1xuICB9XG5cbiAgLyoqIFBlci1waXBlbGluZSBidWlsZCBoZWFsdGggKHN0YWdlIHBhc3MgcmF0ZXMgb3ZlciBhIHdpbmRvdykuICovXG4gIGdldEJ1aWxkSGVhbHRoKFxuICAgIG9yZ0lkOiBzdHJpbmcsIHBpcGVsaW5lSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSxcbiAgKTogUHJvbWlzZTxCdWlsZEhlYWx0aD4ge1xuICAgIHJldHVybiBidWlsZEhlYWx0aChvcmdJZCwgcGlwZWxpbmVJZCwgZnJvbSwgdG8sIG9yZ0lkcyk7XG4gIH1cblxuICBhc3luYyBnZXRQbHVnaW5TdW1tYXJ5KG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFBsdWdpblN1bW1hcnk+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi1zdW1tYXJ5YCwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSk6OmludCBBUyBhY3RpdmUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBOT1QgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSk6OmludCBBUyBpbmFjdGl2ZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi52aXNpYmlsaXR5fSA9ICdwdWJsaWMnKTo6aW50IEFTIHB1YmxpYyxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi52aXNpYmlsaXR5fSA9ICdvcmcnKTo6aW50IEFTIG9yZyxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi52aXNpYmlsaXR5fSA9ICdwcml2YXRlJyk6OmludCBBUyBwcml2YXRlLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUICR7c2NoZW1hLnBsdWdpbi5uYW1lfSk6OmludCBBUyB1bmlxdWVfbmFtZXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfVxuICAgICAgYCkpO1xuICAgICAgcmV0dXJuIChkcml6emxlUm93czxQbHVnaW5TdW1tYXJ5Pihyb3dzLnJvd3MpWzBdIHx8IHsgdG90YWw6IDAsIGFjdGl2ZTogMCwgaW5hY3RpdmU6IDAsIHB1YmxpYzogMCwgb3JnOiAwLCBwcml2YXRlOiAwLCB1bmlxdWVOYW1lczogMCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBUeXBlICYgY29tcHV0ZSBkaXN0cmlidXRpb24uXG4gICAqICBJTlRFTlRJT05BTExZIFNJTkdMRS1PUkcgKG5vIHJvbGx1cCk6IHBsdWdpbiBpbnZlbnRvcnkgaXMgcGVyLW9yZyAoc2VlXG4gICAqICBnZXRQbHVnaW5TdW1tYXJ5KS4gU2luZ2xlIGA9ICRvcmdgIHNjb3BlLiAqL1xuICBhc3luYyBnZXRQbHVnaW5EaXN0cmlidXRpb24ob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VHlwZUNvbXB1dGVEaXN0cmlidXRpb25bXT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLWRpc3RyaWJ1dGlvbmAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9IEFTIHBsdWdpbl90eXBlLFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5jb21wdXRlVHlwZX0gQVMgY29tcHV0ZV90eXBlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgY291bnRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9LCAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9XG4gICAgICAgIE9SREVSIEJZIGNvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbj4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogVmVyc2lvbiBjb3VudHMgcGVyIHBsdWdpbiBuYW1lLlxuICAgKiAgSU5URU5USU9OQUxMWSBTSU5HTEUtT1JHIChubyByb2xsdXApOiBwbHVnaW4gaW52ZW50b3J5IGlzIHBlci1vcmcgKHNlZVxuICAgKiAgZ2V0UGx1Z2luU3VtbWFyeSkuIFNpbmdsZSBgPSAkb3JnYCBzY29wZS4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luVmVyc2lvbnMob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VmVyc2lvbkNvdW50W10+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi12ZXJzaW9uc2AsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLm5hbWV9LFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdmVyc2lvbl9jb3VudCxcbiAgICAgICAgICAtLSBIaWdoZXN0IHZlcnNpb24gYnkgTlVNRVJJQyBzZW12ZXIgY29yZSAobm90IGxleGljYWw6ICcxMC4wLjAnID4gJzkuMC4wJykuXG4gICAgICAgICAgLS0gU3RyaXAgYW55IC1wcmVyZWxlYXNlLytidWlsZCBzdWZmaXggYmVmb3JlIHRoZSBpbnRbXSBjYXN0IHNvIGl0IGNhbid0XG4gICAgICAgICAgLS0gZXJyb3Igb24gdmFsaWQgc2VtdmVyOyBrZWVwIHRoZSBvcmlnaW5hbCBzdHJpbmcgZm9yIGRpc3BsYXkuXG4gICAgICAgICAgLS0gR1VBUkQ6IGEgbm9uLW51bWVyaWMtZG90dGVkIHZlcnNpb24gKCdsYXRlc3QnLCAnJywgJ3YxJykgd291bGQgbWFrZSB0aGVcbiAgICAgICAgICAtLSA6OmludFtdIGNhc3QgdGhyb3cgYW5kIGJsb3cgdXAgdGhlIFdIT0xFIG9yZyBzdW1tYXJ5LiBPbmx5IGNhc3Qgcm93c1xuICAgICAgICAgIC0tIHdob3NlIHN0cmlwcGVkIGNvcmUgbWF0Y2hlcyBhIG51bWVyaWMtZG90dGVkIHNoYXBlOyBzb3J0IGV2ZXJ5dGhpbmdcbiAgICAgICAgICAtLSBlbHNlIHRvIHRoZSBib3R0b20gdmlhIGEgc2VudGluZWwgQVJSQVlbLTFdIHNvIHRoZSByb3cgc3RpbGwgY291bnRzLlxuICAgICAgICAgIChhcnJheV9hZ2coJHtzY2hlbWEucGx1Z2luLnZlcnNpb259XG4gICAgICAgICAgICAgT1JERVIgQlkgQ0FTRVxuICAgICAgICAgICAgICAgV0hFTiByZWdleHBfcmVwbGFjZSgke3NjaGVtYS5wbHVnaW4udmVyc2lvbn0sICdbLStdLiokJywgJycpIH4gJ15bMC05XSsoWy5dWzAtOV0rKSokJ1xuICAgICAgICAgICAgICAgICBUSEVOIHN0cmluZ190b19hcnJheShyZWdleHBfcmVwbGFjZSgke3NjaGVtYS5wbHVnaW4udmVyc2lvbn0sICdbLStdLiokJywgJycpLCAnLicpOjppbnRbXVxuICAgICAgICAgICAgICAgRUxTRSBBUlJBWVstMV1cbiAgICAgICAgICAgICBFTkQgREVTQ1xuICAgICAgICAgICkpWzFdIEFTIGxhdGVzdF92ZXJzaW9uLFxuICAgICAgICAgIGJvb2xfb3IoJHtzY2hlbWEucGx1Z2luLmlzRGVmYXVsdH0pIEFTIGhhc19kZWZhdWx0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGx1Z2lufVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5wbHVnaW4ub3JnSWR9ID0gJHtvcmdJZH0gQU5EICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0gPSB0cnVlXG4gICAgICAgIEdST1VQIEJZICR7c2NoZW1hLnBsdWdpbi5uYW1lfVxuICAgICAgICBPUkRFUiBCWSB2ZXJzaW9uX2NvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxWZXJzaW9uQ291bnQ+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHN1Y2Nlc3MgcmF0ZSBvdmVyIHRpbWUuXG4gICAqXG4gICAqIFNUQVRVUyBDQVNJTkcgTk9URTogVGhpcyBxdWVyeSBmaWx0ZXJzIGJ5IGBldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJ2BcbiAgICogYW5kIHVzZXMgbG93ZXJjYXNlIHN0YXR1cyB2YWx1ZXMgKGAnY29tcGxldGVkJ2AsIGAnZmFpbGVkJ2ApLCB3aGlsZVxuICAgKiBgZ2V0U3VjY2Vzc1JhdGVgICgxLjIpIGZpbHRlcnMgYnkgYGV2ZW50X3R5cGUgPSAnUElQRUxJTkUnYCB3aXRoXG4gICAqIHVwcGVyY2FzZSBBV1Mtc3R5bGUgc3RhdHVzZXMgKGAnU1VDQ0VFREVEJ2AsIGAnRkFJTEVEJ2AsIGAnQ0FOQ0VMRUQnYCkuXG4gICAqIFRoZSBjYXNpbmcgZHJpZnQgaXMgaW50ZW50aW9uYWwgYW5kIHRyYWNrcyB0aGUgcHJvZHVjZXI6XG4gICAqICAgLSBgcGx1Z2luLWJ1aWxkYCBldmVudHMgY29tZSBmcm9tIG91ciBvd24gYnVpbGQgcGlwZWxpbmUgKGxvd2VyY2FzZSlcbiAgICogICAtIGBQSVBFTElORWAgZXZlbnRzIGNvbWUgZnJvbSBBV1MgQ29kZVBpcGVsaW5lICh1cHBlcmNhc2UpXG4gICAqIFRoZSBpbmdlc3QgWm9kIHNjaGVtYSBhdCBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzXG4gICAqIFNIT1VMRCBlbnVtIHRoZXNlIHBlci1ldmVudFNvdXJjZSBzbyB3ZSBjYXRjaCBkcmlmdCBhdCBpbmdlc3QgcmF0aGVyXG4gICAqIHRoYW4gc2lsZW50bHkgcHJvZHVjaW5nIHplcm8gcm93cyBoZXJlLiBTZWUgZmluZGluZ3MgTjcxLlxuICAgKi9cbiAgYXN5bmMgZ2V0QnVpbGRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxCdWlsZFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgYXNzZXJ0UmVwb3J0SW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgIC8vIEJ1aWxkIGFjdGl2aXR5IHJlcG9ydCDigJQgcm9sbHVwLWF3YXJlIGxpa2UgdGhlIGV4ZWN1dGlvbiByZXBvcnRzLiBUaGVzZVxuICAgIC8vIHJvd3MgYXJlIGdhdGVkIG9uIHRoZSBwaXBlbGluZV9ldmVudCBgb3JnX2lkYCBkaXJlY3RseSAobm8gcGlwZWxpbmUgam9pbiksXG4gICAgLy8gc28gYHByZWRgIGFwcGxpZXMgdG8gYGUub3JnX2lkYC5cbiAgICByZXR1cm4gcmVwb3J0PEJ1aWxkVGltZVNlcmllc0VudHJ5PihgYnVpbGQtc3VjY2Vzczoke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2ZhaWxlZCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnY29tcGxldGVkJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnXG4gICAgICAgICAgQU5EIGUuc3RhdHVzIElOICgnY29tcGxldGVkJywgJ2ZhaWxlZCcpXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgcGVyaW9kIE9SREVSIEJZIHBlcmlvZFxuICAgICAgYCk7XG4gIH1cblxuICAvKiogQnVpbGQgZHVyYXRpb24gcGVyIHBsdWdpbi4gQnVpbGQgYWN0aXZpdHkgcmVwb3J0IOKAlCByb2xsdXAtYXdhcmUuICovXG4gIGFzeW5jIGdldEJ1aWxkRHVyYXRpb24ob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8QnVpbGREdXJhdGlvbltdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxCdWlsZER1cmF0aW9uPihgYnVpbGQtZHVyYXRpb246JHtmcm9tfToke3RvfWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZGV0YWlsLT4+J3BsdWdpbk5hbWUnIEFTIHBsdWdpbl9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNQVgoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtYXhfbXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBidWlsZHNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCcgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwbHVnaW5fbmFtZSBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCk7XG4gIH1cblxuICAvKiogQnVpbGQgZmFpbHVyZXMg4oCUIHRvcCBlcnJvciBtZXNzYWdlcy4gQnVpbGQgYWN0aXZpdHkgcmVwb3J0IOKAlCByb2xsdXAtYXdhcmUuICovXG4gIGFzeW5jIGdldEJ1aWxkRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBsaW1pdDogbnVtYmVyID0gMjAsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxCdWlsZEZhaWx1cmVbXT4ge1xuICAgIHJldHVybiByZXBvcnQ8QnVpbGRGYWlsdXJlPihgYnVpbGQtZmFpbHVyZXM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZGV0YWlsLT4+J3BsdWdpbk5hbWUnIEFTIHBsdWdpbl9uYW1lLFxuICAgICAgICAgIGUuZXJyb3JfbWVzc2FnZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIG9jY3VycmVuY2VzLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3Rfc2VlblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgV0hFUkUgZS5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJyBBTkQgZS5zdGF0dXMgPSAnZmFpbGVkJ1xuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIHBsdWdpbl9uYW1lLCBlLmVycm9yX21lc3NhZ2VcbiAgICAgICAgT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCk7XG4gIH1cblxuICAvLyDilIDilIAgUGx1Z2luIHJ1bnRpbWUgdGVsZW1ldHJ5IOKAlCBzZWUgLi9yZXBvcnRpbmcvcGx1Z2luLXJ1bnRpbWUudHMg4pSA4pSAXG5cbiAgLyoqXG4gICAqIFBsdWdpbiBydW50aW1lOiBwZXIgcGx1Z2luIHZlcnNpb24gcnVucywgc3VjY2VzcyByYXRlIGFuZCBwNTAvcDk1XG4gICAqIGR1cmF0aW9uIG92ZXIgYFtmcm9tLCB0b11gLCBmcm9tIHRoZSBtYW5pZmVzdC1hdHRyaWJ1dGVkIEFDVElPTiBldmVudHMuXG4gICAqIFJvbGx1cC1hd2FyZS5cbiAgICovXG4gIGFzeW5jIGdldFBsdWdpblJ1bnRpbWUob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBmaWx0ZXI/OiBQbHVnaW5SdW50aW1lRmlsdGVyLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8UGx1Z2luUnVudGltZVN0YXRzW10+IHtcbiAgICByZXR1cm4gcGx1Z2luUnVudGltZShvcmdJZCwgZnJvbSwgdG8sIGZpbHRlciwgb3JnSWRzKTtcbiAgfVxuXG4gIC8qKiBDcm9zcy1vcmcgMzAtZGF5IHJ1bnRpbWUgYWdncmVnYXRlIGZvciBhIGAocHVibGlzaGVyLCBuYW1lKWAgbGlzdGluZyAocGx1Z2luX3N0YXRzIGlucHV0KS4gU2VydmljZSBjYWxsZXJzIG9ubHkuICovXG4gIGFzeW5jIGdldFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUocHVibGlzaGVyOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8UGx1Z2luUnVudGltZUFnZ3JlZ2F0ZT4ge1xuICAgIHJldHVybiBwbHVnaW5SdW50aW1lQWdncmVnYXRlKHB1Ymxpc2hlciwgbmFtZSk7XG4gIH1cblxuICAvKiogUmV2aWV3IFwidmVyaWZpZWQgdXNlXCI6IGBvcmdJZGAgcmFuIGAocHVibGlzaGVyLCBuYW1lKWAgc3VjY2Vzc2Z1bGx5IHdpdGhpbiA5MCBkYXlzLiBTZXJ2aWNlIGNhbGxlcnMgb25seS4gKi9cbiAgYXN5bmMgaGFzVmVyaWZpZWRQbHVnaW5Vc2Uob3JnSWQ6IHN0cmluZywgcHVibGlzaGVyOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB2ZXJpZmllZFBsdWdpblVzZShvcmdJZCwgcHVibGlzaGVyLCBuYW1lKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAzOiBET1JBIHdyaXRlIHBhdGhzIChwb3N0LWRlcGxveSBvdXRjb21lcyArIGluZ2VzdCBoZWFsdGgpIOKUgOKUgFxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYSBtYW51YWwgcG9zdC1kZXBsb3kgb3V0Y29tZSBtYXJrZXI6IGEgdXNlciBtYXJrcyBhXG4gICAqIGRlcGxveW1lbnQgYGZhaWxlZGAgKGEgcHJvZHVjdGlvbiBpbmNpZGVudCBsaW5rZWQgdG8gdGhlIGRlcGxveSkgb3JcbiAgICogYHJlc3RvcmVkYCAocmVjb3ZlcmVkKS4gSWRlbXBvdGVudCDigJQga2V5ZWQgb24gKGV4ZWN1dGlvbl9pZCwgb3V0Y29tZSkgc28gYVxuICAgKiBkdXBsaWNhdGUgUE9TVCByZWZyZXNoZXMgYGF0YCByYXRoZXIgdGhhbiBkb3VibGUtY291bnRpbmcsIHdoaWxlIGFcbiAgICogZmFpbGVk4oaScmVzdG9yZWQgcGFpciBzdGF5cyB0d28gcm93cy4gRmVlZHMgdGhlIHBvc3QtZGVwbG95IENGUiBjb21wb25lbnQgYW5kXG4gICAqIHRoZSByZWFsIE1UVFIuIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIG9yZyBjb250ZXh0IChSTFMgV0lUSCBDSEVDSykuXG4gICAqL1xuICBhc3luYyByZWNvcmREZXBsb3ltZW50T3V0Y29tZShcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIGV4ZWN1dGlvbklkOiBzdHJpbmcsXG4gICAgaW5wdXQ6IHsgb3V0Y29tZTogJ2ZhaWxlZCcgfCAncmVzdG9yZWQnOyBhdDogc3RyaW5nOyBlbnZpcm9ubWVudD86IHN0cmluZyB9LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmRlcGxveW1lbnRPdXRjb21lKS52YWx1ZXMoe1xuICAgICAgICBleGVjdXRpb25JZCxcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGlucHV0LmVudmlyb25tZW50KSxcbiAgICAgICAgb3V0Y29tZTogaW5wdXQub3V0Y29tZSxcbiAgICAgICAgYXQ6IG5ldyBEYXRlKGlucHV0LmF0KSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogW3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZS5leGVjdXRpb25JZCwgc2NoZW1hLmRlcGxveW1lbnRPdXRjb21lLm91dGNvbWVdLFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICBhdDogbmV3IERhdGUoaW5wdXQuYXQpLFxuICAgICAgICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGlucHV0LmVudmlyb25tZW50KSA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgLy8gT3V0Y29tZSBjaGFuZ2VzIHRoZSBET1JBIGFnZ3JlZ2F0ZSDigJQgZHJvcCB0aGUgb3JnJ3MgY2FjaGVkIHJlcG9ydHMuXG4gICAgYXdhaXQgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZ0lkKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW5nZXN0IGEgcHJvZHVjdGlvbiBpbmNpZGVudCBmcm9tIHRoZSBvcmcncyBpbmNpZGVudCB0b29saW5nXG4gICAqIChQYWdlckR1dHkgLyBEYXRhZG9nIC8gQWxlcnRtYW5hZ2VyIHdlYmhvb2spLiBJZGVtcG90ZW50IOKAlCBrZXllZCBvblxuICAgKiAob3JnX2lkLCBpbmNpZGVudF9pZCkgc28gYSBsYXRlciByZXNvbHZlIHJlLXBvc3QgdXBzZXJ0cyBgcmVzb2x2ZWRfYXRgXG4gICAqIChhbmQgcmVmcmVzaGVzIHRoZSBvdGhlciBtdXRhYmxlIGZpZWxkcykgaW5zdGVhZCBvZiBpbnNlcnRpbmcgYSBkdXBsaWNhdGUuXG4gICAqIERPUkEgY29ycmVsYXRlcyBlYWNoIGluY2lkZW50IHRvIHRoZSBtb3N0IHJlY2VudCBzdWNjZXNzZnVsIGRlcGxveSB0byBpdHNcbiAgICogYGVudmlyb25tZW50YCwgcHJvZHVjaW5nIGFuIGF1dG9tYXRlZCBwb3N0LWRlcGxveSBmYWlsdXJlICsgYSByZWFsIE1UVFIuXG4gICAqIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIG9yZyBjb250ZXh0IChSTFMgV0lUSCBDSEVDSyk7IGZyZWUtZm9ybSBmaWVsZHMgYXJlXG4gICAqIEFXUy1pZCBzY3J1YmJlZCBhdCB0aGlzIHBlcnNpc3RlbmNlIGJvdW5kYXJ5IGxpa2UgdGhlIG90aGVyIGluZ2VzdCBwYXRocy5cbiAgICovXG4gIGFzeW5jIHJlY29yZEluY2lkZW50KG9yZ0lkOiBzdHJpbmcsIGlucHV0OiBJbmNpZGVudElucHV0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW5jaWRlbnRJZCA9IHNjcnViQXdzSWRlbnRpZmllcnNGcm9tU3RyaW5nKGlucHV0LmluY2lkZW50SWQpO1xuICAgIGNvbnN0IGVudmlyb25tZW50ID0gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcoaW5wdXQuZW52aXJvbm1lbnQpO1xuICAgIGNvbnN0IHNldmVyaXR5ID0gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcoaW5wdXQuc2V2ZXJpdHkpO1xuICAgIGNvbnN0IG9wZW5lZEF0ID0gbmV3IERhdGUoaW5wdXQub3BlbmVkQXQpO1xuICAgIGNvbnN0IHJlc29sdmVkQXQgPSBpbnB1dC5yZXNvbHZlZEF0ID8gbmV3IERhdGUoaW5wdXQucmVzb2x2ZWRBdCkgOiBudWxsO1xuICAgIGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbjogZmFsc2UgfSwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4Lmluc2VydChzY2hlbWEuaW5jaWRlbnQpLnZhbHVlcyh7XG4gICAgICAgIGluY2lkZW50SWQsXG4gICAgICAgIG9yZ0lkLFxuICAgICAgICBlbnZpcm9ubWVudCxcbiAgICAgICAgb3BlbmVkQXQsXG4gICAgICAgIHJlc29sdmVkQXQsXG4gICAgICAgIHNldmVyaXR5LFxuICAgICAgfSkub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgdGFyZ2V0OiBbc2NoZW1hLmluY2lkZW50Lm9yZ0lkLCBzY2hlbWEuaW5jaWRlbnQuaW5jaWRlbnRJZF0sXG4gICAgICAgIC8vIEEgcmVkZWxpdmVyZWQgRklSSU5HIHBvc3QgKG5vIHJlc29sdmVkQXQpIG11c3Qgbm90IHdpcGUgYSByZWNvcmRlZFxuICAgICAgICAvLyByZXNvbHZlIOKAlCBzZW5kZXJzIHJlLXBvc3QgZmlyaW5nIGFsZXJ0cyBvbiBldmVyeSByZXBlYXQgaW50ZXJ2YWwsIGFuZFxuICAgICAgICAvLyBkZWxpdmVyeSBvcmRlciBpc24ndCBndWFyYW50ZWVkLiBLZWVwIHRoZSBzdG9yZWQgcmVzb2x2ZSB1bmxlc3MgdGhlXG4gICAgICAgIC8vIHBvc3QgY2FycmllcyBpdHMgb3duLCBvciB0aGUgaW5jaWRlbnQgd2FzIFJFLU9QRU5FRCAoYSBkaWZmZXJlbnRcbiAgICAgICAgLy8gb3BlbmVkQXQgbWVhbnMgYSBuZXcgb2NjdXJyZW5jZSwgd2hvc2UgcmVzb2x2ZSBzdGF0ZSBpcyB0aGUgcG9zdCdzKS5cbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgZW52aXJvbm1lbnQsXG4gICAgICAgICAgb3BlbmVkQXQsXG4gICAgICAgICAgcmVzb2x2ZWRBdDogc3FsYENBU0UgV0hFTiAke3NjaGVtYS5pbmNpZGVudC5vcGVuZWRBdH0gPSBleGNsdWRlZC5vcGVuZWRfYXRcbiAgICAgICAgICAgIFRIRU4gQ09BTEVTQ0UoZXhjbHVkZWQucmVzb2x2ZWRfYXQsICR7c2NoZW1hLmluY2lkZW50LnJlc29sdmVkQXR9KVxuICAgICAgICAgICAgRUxTRSBleGNsdWRlZC5yZXNvbHZlZF9hdCBFTkRgLFxuICAgICAgICAgIHNldmVyaXR5LFxuICAgICAgICB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgLy8gQSBuZXcvdXBkYXRlZCBpbmNpZGVudCBjaGFuZ2VzIHRoZSBET1JBIGFnZ3JlZ2F0ZSDigJQgZHJvcCBjYWNoZWQgcmVwb3J0cy5cbiAgICBhd2FpdCB0aGlzLmludmFsaWRhdGVPcmcob3JnSWQpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIHRoZSBwZXItb3JnIERPUkEgc2V0dGluZ3MuIFJldHVybnMgdGhlIHN0b3JlZFxuICAgKiBgaW5jaWRlbnRXaW5kb3dIb3Vyc2Agb3ZlcnJpZGUgKG9yIGBudWxsYCB3aGVuIHVuc2V0KSBwbHVzIHRoZSBnbG9iYWwgZW52XG4gICAqIGRlZmF1bHQsIHNvIHRoZSBzZXR0aW5ncyBVSSBjYW4gc2hvdyBib3RoLiBSdW5zIHVuZGVyIHRoZSBjYWxsZXIncyB0ZW5hbnRcbiAgICogY29udGV4dCAoUkxTLXNjb3BlZCk7IGEgc2luZ2xlLW9yZyByZWFkLlxuICAgKi9cbiAgYXN5bmMgZ2V0UmVwb3J0aW5nU2V0dGluZ3Mob3JnSWQ6IHN0cmluZywgcmV0ZW50aW9uT3JnSWQ6IHN0cmluZyA9IG9yZ0lkKTogUHJvbWlzZTxSZXBvcnRpbmdTZXR0aW5ncz4ge1xuICAgIGNvbnN0IHJvd3MgPSBkcml6emxlUm93czx7XG4gICAgICBpbmNpZGVudF93aW5kb3dfaG91cnM6IG51bWJlciB8IG51bGw7XG4gICAgICBldmVudF9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICAgIGRvcmFfcmV0ZW50aW9uX2RheXM6IG51bWJlciB8IG51bGw7XG4gICAgfT4oKGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1QgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmluY2lkZW50V2luZG93SG91cnN9IEFTIGluY2lkZW50X3dpbmRvd19ob3VycyxcbiAgICAgICAgICAgICAgICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5ldmVudFJldGVudGlvbkRheXN9IEFTIGV2ZW50X3JldGVudGlvbl9kYXlzLFxuICAgICAgICAgICAgICAgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmRvcmFSZXRlbnRpb25EYXlzfSBBUyBkb3JhX3JldGVudGlvbl9kYXlzXG4gICAgICAgIEZST00gJHtzY2hlbWEuZG9yYVNldHRpbmdzfVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5kb3JhU2V0dGluZ3Mub3JnSWR9ID0gJHtvcmdJZH1cbiAgICAgICAgTElNSVQgMVxuICAgICAgYCkpKS5yb3dzKTtcbiAgICBjb25zdCByb3cgPSByb3dzWzBdO1xuICAgIC8vIFJldGVudGlvbiBpcyBhIGJpbGxpbmcgZW50aXRsZW1lbnQgc3luY2VkIG9udG8gdGhlIGFjY291bnQgUk9PVCBvbmx5OyBhXG4gICAgLy8gdGVhbSByZWFkcyBpdHMgcm9vdCdzIHdpbmRvdyAodGhlIGluY2lkZW50IHdpbmRvdyBzdGF5cyB0aGUgdGVhbSdzIG93bikuXG4gICAgY29uc3QgcmV0ZW50aW9uID0gcmV0ZW50aW9uT3JnSWQgPT09IG9yZ0lkXG4gICAgICA/IHJvd1xuICAgICAgOiBhd2FpdCB0aGlzLiNyZWFkUmV0ZW50aW9uT3ZlcnJpZGUocmV0ZW50aW9uT3JnSWQpO1xuICAgIHJldHVybiB7XG4gICAgICBpbmNpZGVudFdpbmRvd0hvdXJzOiByb3c/LmluY2lkZW50X3dpbmRvd19ob3VycyAhPSBudWxsID8gTnVtYmVyKHJvdy5pbmNpZGVudF93aW5kb3dfaG91cnMpIDogbnVsbCxcbiAgICAgIGRlZmF1bHRXaW5kb3dIb3VyczogRE9SQV9JTkNJREVOVF9XSU5ET1dfSE9VUlMsXG4gICAgICBldmVudFJldGVudGlvbkRheXM6IHJldGVudGlvbj8uZXZlbnRfcmV0ZW50aW9uX2RheXMgIT0gbnVsbCA/IE51bWJlcihyZXRlbnRpb24uZXZlbnRfcmV0ZW50aW9uX2RheXMpIDogbnVsbCxcbiAgICAgIGRvcmFSZXRlbnRpb25EYXlzOiByZXRlbnRpb24/LmRvcmFfcmV0ZW50aW9uX2RheXMgIT0gbnVsbCA/IE51bWJlcihyZXRlbnRpb24uZG9yYV9yZXRlbnRpb25fZGF5cykgOiBudWxsLFxuICAgICAgZGVmYXVsdEV2ZW50UmV0ZW50aW9uRGF5czogUkVQT1JUSU5HX0VWRU5UX1JFVEVOVElPTl9EQVlTLFxuICAgICAgZGVmYXVsdERvcmFSZXRlbnRpb25EYXlzOiBSRVBPUlRJTkdfRE9SQV9SRVRFTlRJT05fREFZUyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBST09UIG9yZydzIHN0b3JlZCByZXRlbnRpb24gb3ZlcnJpZGUuIFRoZSBjYWxsZXIgKGEgdGVhbSkgY2FuJ3Qgc2VlIHRoZVxuICAgKiByb290J3MgYGRvcmFfc2V0dGluZ3NgIHJvdyB1bmRlciBpdHMgb3duIFJMUyBzY29wZSwgc28gdGhpcyBuYXJyb3cgcmVhZCBvZlxuICAgKiB0d28gaW50ZWdlciBjb2x1bW5zIOKAlCBrZXllZCBieSB0aGUgZXhwbGljaXQsIEpXVC1kZXJpdmVkIHJvb3QgaWQg4oCUIHJ1bnMgaW4gYVxuICAgKiBzeXNhZG1pbiBzY29wZS5cbiAgICovXG4gIGFzeW5jICNyZWFkUmV0ZW50aW9uT3ZlcnJpZGUob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8eyBldmVudF9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDsgZG9yYV9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbCB9IHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3Qgcm93cyA9IGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIGFzeW5jICgpID0+IGRyaXp6bGVSb3dzPHtcbiAgICAgIGV2ZW50X3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgZG9yYV9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVCAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZXZlbnRSZXRlbnRpb25EYXlzfSBBUyBldmVudF9yZXRlbnRpb25fZGF5cyxcbiAgICAgICAgICAgICAgICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5kb3JhUmV0ZW50aW9uRGF5c30gQVMgZG9yYV9yZXRlbnRpb25fZGF5c1xuICAgICAgICBGUk9NICR7c2NoZW1hLmRvcmFTZXR0aW5nc31cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEuZG9yYVNldHRpbmdzLm9yZ0lkfSA9ICR7b3JnSWR9XG4gICAgICAgIExJTUlUIDFcbiAgICAgIGApKSkucm93cykpO1xuICAgIHJldHVybiByb3dzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwc2VydCBwZXItb3JnIHJlcG9ydGluZyBzZXR0aW5ncyAoaW5jaWRlbnQgd2luZG93ICtcbiAgICogcmV0ZW50aW9uIG92ZXJyaWRlcyksIGlkZW1wb3RlbnQgb24gYG9yZ19pZGAuIEEgcGFydGlhbCB3cml0ZSDigJQgb25seSB0aGVcbiAgICogZmllbGRzIHByZXNlbnQgaW4gYHBhdGNoYCBhcmUgc2V0IChzbyB1cGRhdGluZyByZXRlbnRpb24gbmV2ZXIgY2xlYXJzIHRoZVxuICAgKiBpbmNpZGVudCB3aW5kb3csIGFuZCB2aWNlLXZlcnNhKS4gU2V0IHNlbGYtc2VydmUgYnkgYW4gb3JnIGFkbWluIHZpYVxuICAgKiBgUFVUIC9hcGkvcmVwb3J0cy9zZXR0aW5ncy9pbmNpZGVudHNgLiBSdW5zIHVuZGVyIHRoZSBjYWxsZXIncyBvcmcgY29udGV4dFxuICAgKiAoUkxTIFdJVEggQ0hFQ0spOyBhIGNoYW5nZWQgdmFsdWUgYWZmZWN0cyBET1JBIGFnZ3JlZ2F0ZXMgc28gdGhlIG9yZydzXG4gICAqIGNhY2hlZCByZXBvcnRzIGFyZSBkcm9wcGVkLlxuICAgKi9cbiAgYXN5bmMgc2V0UmVwb3J0aW5nU2V0dGluZ3Mob3JnSWQ6IHN0cmluZywgcGF0Y2g6IFJlcG9ydGluZ1NldHRpbmdzUGF0Y2gpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzZXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyB1cGRhdGVkQXQ6IG5ldyBEYXRlKCkgfTtcbiAgICBpZiAocGF0Y2guaW5jaWRlbnRXaW5kb3dIb3VycyAhPT0gdW5kZWZpbmVkKSBzZXQuaW5jaWRlbnRXaW5kb3dIb3VycyA9IHBhdGNoLmluY2lkZW50V2luZG93SG91cnM7XG4gICAgaWYgKHBhdGNoLmV2ZW50UmV0ZW50aW9uRGF5cyAhPT0gdW5kZWZpbmVkKSBzZXQuZXZlbnRSZXRlbnRpb25EYXlzID0gcGF0Y2guZXZlbnRSZXRlbnRpb25EYXlzO1xuICAgIGlmIChwYXRjaC5kb3JhUmV0ZW50aW9uRGF5cyAhPT0gdW5kZWZpbmVkKSBzZXQuZG9yYVJldGVudGlvbkRheXMgPSBwYXRjaC5kb3JhUmV0ZW50aW9uRGF5cztcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmRvcmFTZXR0aW5ncykudmFsdWVzKHtcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGluY2lkZW50V2luZG93SG91cnM6IHBhdGNoLmluY2lkZW50V2luZG93SG91cnMsXG4gICAgICAgIGV2ZW50UmV0ZW50aW9uRGF5czogcGF0Y2guZXZlbnRSZXRlbnRpb25EYXlzLFxuICAgICAgICBkb3JhUmV0ZW50aW9uRGF5czogcGF0Y2guZG9yYVJldGVudGlvbkRheXMsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogc2NoZW1hLmRvcmFTZXR0aW5ncy5vcmdJZCxcbiAgICAgICAgc2V0LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZ0lkKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCByZWNlbnQgaW5jaWRlbnRzIGZvciBhbiBvcmcgKG9yZy1hZG1pbiBzdXJmYWNlKSwgbmV3ZXN0IGZpcnN0LFxuICAgKiBwYWdpbmF0ZWQuIEVhY2ggcm93IGNhcnJpZXMgaXRzIHJlc29sdmVkIHN0YXRlIGFuZCBpdHMgZGVwbG95IGNvcnJlbGF0aW9uIOKAlFxuICAgKiB0aGUgbW9zdCByZWNlbnQgU1VDQ0VTU0ZVTCBkZXBsb3kgdG8gdGhlIGluY2lkZW50J3MgYGVudmlyb25tZW50YCB3aG9zZVxuICAgKiBgY29tcGxldGVkX2F0YCBmYWxscyB3aXRoaW4gdGhlIGVmZmVjdGl2ZSBwZXItb3JnIGNvcnJlbGF0aW9uIHdpbmRvdyBiZWZvcmVcbiAgICogYG9wZW5lZF9hdGAgKHRoZSBzYW1lIHJ1bGUgRE9SQSdzIENGUi9NVFRSIGNvcnJlbGF0aW9uIGFwcGxpZXMpLiBTaW5nbGUtb3JnXG4gICAqIChubyByb2xsdXApIOKAlCBhbiBvcmcgYWRtaW4gdmlld3MgdGhlaXIgb3duIG9yZydzIGluY2lkZW50cy4gUkxTLXNjb3BlZCB2aWFcbiAgICogdGhlIGBwLm9yZ19pZGAvYGkub3JnX2lkYCBwcmVkaWNhdGVzICsgdGhlIHRlbmFudCBjb250ZXh0LlxuICAgKi9cbiAgYXN5bmMgbGlzdEluY2lkZW50cyhvcmdJZDogc3RyaW5nLCBvcHRzOiB7IGxpbWl0OiBudW1iZXI7IG9mZnNldDogbnVtYmVyIH0pOiBQcm9taXNlPEluY2lkZW50TGlzdEl0ZW1bXT4ge1xuICAgIGNvbnN0IHsgaW5jaWRlbnRXaW5kb3dIb3VycyB9ID0gYXdhaXQgdGhpcy5nZXRSZXBvcnRpbmdTZXR0aW5ncyhvcmdJZCk7XG4gICAgY29uc3Qgd2luZG93SG91cnMgPSByZXNvbHZlSW5jaWRlbnRXaW5kb3dIb3VycyhpbmNpZGVudFdpbmRvd0hvdXJzKTtcbiAgICBjb25zdCBsaW1pdCA9IE1hdGgubWF4KDEsIE1hdGgubWluKG9wdHMubGltaXQsIDIwMCkpO1xuICAgIGNvbnN0IG9mZnNldCA9IE1hdGgubWF4KDAsIG9wdHMub2Zmc2V0KTtcbiAgICAvLyBUaGUgY29ycmVsYXRpb24gd2luZG93IGlzIGV4cHJlc3NlZCBpbiBTRUNPTkRTIGFzIGEgZG91YmxlLCBub3QgYXNcbiAgICAvLyBgbWFrZV9pbnRlcnZhbChob3VycyA9PiBOOjppbnQpYC4gVGhlIHdpbmRvdyBpcyB2YWxpZGF0ZWQgYXMgYW55IHBvc2l0aXZlXG4gICAgLy8gbnVtYmVyICgwLjVoIGlzIGxlZ2FsKSBhbmQgdGhlIGluLW1lbW9yeSBET1JBIGNvcnJlbGF0aW9uIHVzZXMgaXQgZXhhY3RseTtcbiAgICAvLyB0aGUgaW50IGNhc3QgbWFkZSBQb3N0Z3JlcyByZWplY3QgYSBmcmFjdGlvbmFsIHZhbHVlLCBzbyBhIDAuNWggd2luZG93XG4gICAgLy8gcmV0dXJuZWQgNTAwIGZyb20gdGhpcyBlbmRwb2ludCBhbmQgZnJvbSB0aGUgY29ycmVsYXRpb24gbG9va3VwIGJlbG93LlxuICAgIHJldHVybiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgaS5pbmNpZGVudF9pZCBBUyBcImluY2lkZW50SWRcIixcbiAgICAgICAgICBpLmVudmlyb25tZW50IEFTIGVudmlyb25tZW50LFxuICAgICAgICAgIGkuc2V2ZXJpdHkgQVMgc2V2ZXJpdHksXG4gICAgICAgICAgaS5vcGVuZWRfYXQ6OnRleHQgQVMgXCJvcGVuZWRBdFwiLFxuICAgICAgICAgIGkucmVzb2x2ZWRfYXQ6OnRleHQgQVMgXCJyZXNvbHZlZEF0XCIsXG4gICAgICAgICAgaS5jcmVhdGVkX2F0Ojp0ZXh0IEFTIFwiY3JlYXRlZEF0XCIsXG4gICAgICAgICAgKGkucmVzb2x2ZWRfYXQgSVMgTk9UIE5VTEwpIEFTIHJlc29sdmVkLFxuICAgICAgICAgIGNvcnIuZXhlY3V0aW9uX2lkIEFTIFwiY29ycmVsYXRlZEV4ZWN1dGlvbklkXCIsXG4gICAgICAgICAgY29yci5jb21wbGV0ZWRfYXQ6OnRleHQgQVMgXCJkZXBsb3lDb21wbGV0ZWRBdFwiXG4gICAgICAgIEZST00gJHtzY2hlbWEuaW5jaWRlbnR9IGlcbiAgICAgICAgTEVGVCBKT0lOIExBVEVSQUwgKFxuICAgICAgICAgIFNFTEVDVCBlLmV4ZWN1dGlvbl9pZCwgZS5jb21wbGV0ZWRfYXRcbiAgICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ1NUQUdFJ1xuICAgICAgICAgICAgQU5EIGUuZW52aXJvbm1lbnQgPSBpLmVudmlyb25tZW50IEFORCBlLnN0YXR1cyA9ICdTVUNDRUVERUQnXG4gICAgICAgICAgICBBTkQgZS5jb21wbGV0ZWRfYXQgPD0gaS5vcGVuZWRfYXRcbiAgICAgICAgICAgIEFORCBlLmNvbXBsZXRlZF9hdCA+PSBpLm9wZW5lZF9hdCAtIG1ha2VfaW50ZXJ2YWwoc2VjcyA9PiAke3dpbmRvd0hvdXJzICogMzYwMH06OmRvdWJsZSBwcmVjaXNpb24pXG4gICAgICAgICAgT1JERVIgQlkgZS5jb21wbGV0ZWRfYXQgREVTQ1xuICAgICAgICAgIExJTUlUIDFcbiAgICAgICAgKSBjb3JyIE9OIHRydWVcbiAgICAgICAgV0hFUkUgaS5vcmdfaWQgPSAke29yZ0lkfVxuICAgICAgICBPUkRFUiBCWSBpLm9wZW5lZF9hdCBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9IE9GRlNFVCAke29mZnNldH1cbiAgICAgIGApLnRoZW4oKHIpID0+IGRyaXp6bGVSb3dzPEluY2lkZW50TGlzdEl0ZW0+KHIucm93cykubWFwKChyb3cpID0+ICh7XG4gICAgICAuLi5yb3csXG4gICAgICByZXNvbHZlZDogcm93LnJlc29sdmVkID09PSB0cnVlIHx8IChyb3cucmVzb2x2ZWQgYXMgdW5rbm93bikgPT09ICd0JyxcbiAgICAgIGNvcnJlbGF0ZWRFeGVjdXRpb25JZDogcm93LmNvcnJlbGF0ZWRFeGVjdXRpb25JZCA/PyBudWxsLFxuICAgICAgZGVwbG95Q29tcGxldGVkQXQ6IHJvdy5kZXBsb3lDb21wbGV0ZWRBdCA/PyBudWxsLFxuICAgIH0pKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdpcmluZy10ZXN0IGRyeS1ydW46IHdvdWxkIGEgc3ludGhldGljIGluY2lkZW50IG9wZW5pbmcgTk9XIGZvclxuICAgKiBgZW52aXJvbm1lbnRgIGNvcnJlbGF0ZSB0byBhIHJlY2VudCBzdWNjZXNzZnVsIGRlcGxveSB1bmRlciB0aGUgb3JnJ3NcbiAgICogZWZmZWN0aXZlIHdpbmRvdz8gVGhpcyBpcyBhIE5PTi1wZXJzaXN0aW5nIGNvcnJlbGF0aW9uIGNoZWNrIOKAlCBpdCB2ZXJpZmllc1xuICAgKiB0aGUgYWRtaW4ncyBlbnZpcm9ubWVudCBuYW1pbmcgKyB3aW5kb3cgbGluZSB1cCB3aXRoIHJlYWwgZGVwbG95IGV2ZW50c1xuICAgKiBXSVRIT1VUIHdyaXRpbmcgYW4gaW5jaWRlbnQgKHNvIGEgXCJ0ZXN0XCIgbmV2ZXIgcG9sbHV0ZXMgQ0ZSL01UVFIpLiBSTFMtc2NvcGVkLlxuICAgKi9cbiAgYXN5bmMgdGVzdEluY2lkZW50Q29ycmVsYXRpb24ob3JnSWQ6IHN0cmluZywgZW52aXJvbm1lbnQ6IHN0cmluZyk6IFByb21pc2U8SW5jaWRlbnRUZXN0UmVzdWx0PiB7XG4gICAgY29uc3QgZW52ID0gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcoZW52aXJvbm1lbnQpO1xuICAgIGNvbnN0IG9wZW5lZEF0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgIGNvbnN0IHsgaW5jaWRlbnRXaW5kb3dIb3VycyB9ID0gYXdhaXQgdGhpcy5nZXRSZXBvcnRpbmdTZXR0aW5ncyhvcmdJZCk7XG4gICAgY29uc3Qgd2luZG93SG91cnMgPSByZXNvbHZlSW5jaWRlbnRXaW5kb3dIb3VycyhpbmNpZGVudFdpbmRvd0hvdXJzKTtcbiAgICBjb25zdCByb3dzID0gZHJpenpsZVJvd3M8eyBleGVjdXRpb25faWQ6IHN0cmluZyB8IG51bGw7IGNvbXBsZXRlZF9hdDogc3RyaW5nIHwgbnVsbCB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVCBlLmV4ZWN1dGlvbl9pZCBBUyBleGVjdXRpb25faWQsIGUuY29tcGxldGVkX2F0Ojp0ZXh0IEFTIGNvbXBsZXRlZF9hdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnXG4gICAgICAgICAgQU5EIGUuZW52aXJvbm1lbnQgPSAke2Vudn0gQU5EIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCdcbiAgICAgICAgICBBTkQgZS5jb21wbGV0ZWRfYXQgPD0gJHtvcGVuZWRBdH06OnRpbWVzdGFtcHR6XG4gICAgICAgICAgQU5EIGUuY29tcGxldGVkX2F0ID49ICR7b3BlbmVkQXR9Ojp0aW1lc3RhbXB0eiAtIG1ha2VfaW50ZXJ2YWwoc2VjcyA9PiAke3dpbmRvd0hvdXJzICogMzYwMH06OmRvdWJsZSBwcmVjaXNpb24pXG4gICAgICAgIE9SREVSIEJZIGUuY29tcGxldGVkX2F0IERFU0NcbiAgICAgICAgTElNSVQgMVxuICAgICAgYCkpKS5yb3dzKTtcbiAgICBjb25zdCBoaXQgPSByb3dzWzBdO1xuICAgIHJldHVybiB7XG4gICAgICBlbnZpcm9ubWVudDogZW52LFxuICAgICAgb3BlbmVkQXQsXG4gICAgICB3aW5kb3dIb3VycyxcbiAgICAgIGNvcnJlbGF0ZWQ6IGhpdD8uZXhlY3V0aW9uX2lkICE9IG51bGwsXG4gICAgICBleGVjdXRpb25JZDogaGl0Py5leGVjdXRpb25faWQgPz8gbnVsbCxcbiAgICAgIGRlcGxveUNvbXBsZXRlZEF0OiBoaXQ/LmNvbXBsZXRlZF9hdCA/PyBudWxsLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVXBzZXJ0IHBlci1vcmcgaW5nZXN0aW9uIGhlYWx0aDogdGhlIEFXUyBldmVudHMgTGFtYmRhIHBlcmlvZGljYWxseVxuICAgKiByZXBvcnRzIGZvcndhcmRlZC9kcm9wcGVkIGNvdW50ZXJzICsgdGhlIGxhc3QgZXZlbnQgdGltZXN0YW1wIHNvIHRoZSBSZXBvcnRzXG4gICAqIFVJIGNhbiBzaG93IGZsb3dpbmcgLyBzdGFsZSAvIGRyb3BwaW5nLiBPbmUgcm93IHBlciBvcmcgKHVwc2VydCBvbiBvcmdfaWQpLlxuICAgKi9cbiAgYXN5bmMgcmVjb3JkSW5nZXN0SGVhbHRoKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgaW5wdXQ6IHsgZm9yd2FyZGVkPzogbnVtYmVyOyBkcm9wcGVkPzogbnVtYmVyOyBsYXN0RXZlbnRBdD86IHN0cmluZyB9LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsYXN0RXZlbnRBdCA9IGlucHV0Lmxhc3RFdmVudEF0ID8gbmV3IERhdGUoaW5wdXQubGFzdEV2ZW50QXQpIDogdW5kZWZpbmVkO1xuICAgIGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbjogZmFsc2UgfSwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4Lmluc2VydChzY2hlbWEuaW5nZXN0SGVhbHRoKS52YWx1ZXMoe1xuICAgICAgICBvcmdJZCxcbiAgICAgICAgZm9yd2FyZGVkOiBpbnB1dC5mb3J3YXJkZWQsXG4gICAgICAgIGRyb3BwZWQ6IGlucHV0LmRyb3BwZWQsXG4gICAgICAgIGxhc3RFdmVudEF0LFxuICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICB9KS5vbkNvbmZsaWN0RG9VcGRhdGUoe1xuICAgICAgICB0YXJnZXQ6IHNjaGVtYS5pbmdlc3RIZWFsdGgub3JnSWQsXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIGZvcndhcmRlZDogaW5wdXQuZm9yd2FyZGVkLFxuICAgICAgICAgIGRyb3BwZWQ6IGlucHV0LmRyb3BwZWQsXG4gICAgICAgICAgbGFzdEV2ZW50QXQsXG4gICAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBiYWNrIG9uZSBvcmcncyBpbmdlc3Rpb24gaGVhbHRoIGZvciB0aGUgUmVwb3J0cyBVSSBmcmVzaG5lc3NcbiAgICogaW5kaWNhdG9yLiBSZXR1cm5zIGBudWxsYCB3aGVuIHRoZSBvcmcgaGFzIE5PIHJvdyDigJQgaS5lLiB0aGUgZGVwbG95bWVudCBoYXNcbiAgICogbmV2ZXIgaW5nZXN0ZWQgYW55dGhpbmcg4oCUIHdoaWNoIHRoZSBVSSBtdXN0IHJlbmRlciBhcyBcIm5vIGluZ2VzdCByZXBvcnRlZFxuICAgKiB5ZXRcIiwgbmV2ZXIgYXMgXCJzdGFsZVwiLiBSTFMtc2NvcGVkIHRvIHRoZSBvcmcgbGlrZSBldmVyeSBvdGhlciByZWFkLlxuICAgKi9cbiAgYXN5bmMgZ2V0SW5nZXN0SGVhbHRoKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEluZ2VzdEhlYWx0aFN0YXR1cyB8IG51bGw+IHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgcnVuV2l0aFRlbmFudENvbnRleHQoeyBvcmdJZCwgaXNTdXBlckFkbWluOiBmYWxzZSB9LCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHhcbiAgICAgICAgLnNlbGVjdCgpXG4gICAgICAgIC5mcm9tKHNjaGVtYS5pbmdlc3RIZWFsdGgpXG4gICAgICAgIC53aGVyZShlcShzY2hlbWEuaW5nZXN0SGVhbHRoLm9yZ0lkLCBvcmdJZCkpXG4gICAgICAgIC5saW1pdCgxKSksXG4gICAgKTtcbiAgICBjb25zdCByb3cgPSByb3dzWzBdO1xuICAgIGlmICghcm93KSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4ge1xuICAgICAgdXBkYXRlZEF0OiByb3cudXBkYXRlZEF0LnRvSVNPU3RyaW5nKCksXG4gICAgICBsYXN0RXZlbnRBdDogcm93Lmxhc3RFdmVudEF0ID8gcm93Lmxhc3RFdmVudEF0LnRvSVNPU3RyaW5nKCkgOiBudWxsLFxuICAgICAgZm9yd2FyZGVkOiByb3cuZm9yd2FyZGVkID8/IG51bGwsXG4gICAgICBkcm9wcGVkOiByb3cuZHJvcHBlZCA/PyBudWxsLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQmF0Y2hlZCBoYXJkLURFTEVURSBvZiBvbmUgcmVwb3J0aW5nIHRhYmxlJ3Mgcm93cyBleHBpcmVkIHBhc3QgYSBgY3JlYXRlZF9hdGBcbiAgICogY3V0b2ZmLCBzY29wZWQgdG8gYW4gb3JnIGFuZCBhbiBvcHRpb25hbCByb3cgcHJlZGljYXRlLiBVc2VzIGFcbiAgICogYGN0aWRgLWluLXN1YnF1ZXJ5IExJTUlUIHNvIGVhY2ggc3RhdGVtZW50IHRvdWNoZXMgYXQgbW9zdCBgYmF0Y2hTaXplYCByb3dzXG4gICAqIChzaG9ydCBsb2NrIHdpbmRvd3MsIG5vIGxvbmcgdGFibGUgc2NhbiB1bmRlciBsb2NrKTsgYFJFVFVSTklORyAxYCBsZXRzIHVzXG4gICAqIGNvdW50IHZpYSBgLnJvd3MubGVuZ3RoYCB3aXRob3V0IGRlcGVuZGluZyBvbiB0aGUgZHJpdmVyJ3MgYHJvd0NvdW50YC4gTG9vcHNcbiAgICogdW50aWwgYSBzaG9ydCBiYXRjaCAoZHJhaW5lZCkgb3IgdGhlIHBlci10aWNrIGNhcCwgdGhlbiBkZWZlcnMgdGhlIHJlc3QuXG4gICAqIE1VU1QgcnVuIGluc2lkZSBhIHN5c2FkbWluIHRlbmFudCBzY29wZSAoc2VlIHB1cmdlRXhwaXJlZFJlcG9ydGluZ0RhdGEpIHNvIGl0XG4gICAqIGJ5cGFzc2VzIFJMUyBhbmQgY2FuIGRlbGV0ZSBhY3Jvc3MgdGhlIG9yZydzIHJvd3MuXG4gICAqL1xuICBhc3luYyAjcHVyZ2VSZXBvcnRpbmdUYWJsZUJhdGNoZWQoXG4gICAgdGFibGVTcWw6IFJldHVyblR5cGU8dHlwZW9mIHNxbD4sXG4gICAgcHJlZGljYXRlOiBSZXR1cm5UeXBlPHR5cGVvZiBzcWw+LFxuICAgIGJhdGNoU2l6ZTogbnVtYmVyLFxuICAgIG1heEJhdGNoZXM6IG51bWJlcixcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBsZXQgdG90YWwgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4QmF0Y2hlczsgaSsrKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgREVMRVRFIEZST00gJHt0YWJsZVNxbH1cbiAgICAgICAgV0hFUkUgY3RpZCBJTiAoXG4gICAgICAgICAgU0VMRUNUIGN0aWQgRlJPTSAke3RhYmxlU3FsfVxuICAgICAgICAgIFdIRVJFICR7cHJlZGljYXRlfVxuICAgICAgICAgIExJTUlUICR7YmF0Y2hTaXplfVxuICAgICAgICApXG4gICAgICAgIFJFVFVSTklORyAxXG4gICAgICBgKSk7XG4gICAgICBjb25zdCBwdXJnZWQgPSBkcml6emxlUm93czx1bmtub3duPihyZXMucm93cykubGVuZ3RoO1xuICAgICAgdG90YWwgKz0gcHVyZ2VkO1xuICAgICAgaWYgKHB1cmdlZCA8IGJhdGNoU2l6ZSkgYnJlYWs7IC8vIGRyYWluZWRcbiAgICAgIGlmIChpID09PSBtYXhCYXRjaGVzIC0gMSkge1xuICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbiBoaXQgcGVyLXRpY2sgY2FwOyByZW1haW5pbmcgcm93cyBkZWZlcnJlZCcsIHtcbiAgICAgICAgICBwdXJnZWRUaGlzVGljazogdG90YWwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdG90YWw7XG4gIH1cblxuICAvKipcbiAgICogUmVwb3J0aW5nIHJldGVudGlvbiBzd2VlcC4gSGFyZC1kZWxldGVzIHJvd3Mgb2xkZXIgdGhhbiB0aGVpclxuICAgKiByZXRlbnRpb24gd2luZG93LCBieSBgY3JlYXRlZF9hdGAsIGFjcm9zcyBldmVyeSBvcmcgdGhhdCBoYXMgcmVwb3J0aW5nIGRhdGEg4oCUXG4gICAqIGEgKipzcGxpdCoqIHBvbGljeSBzbyBoaWdoLXZvbHVtZSBzdGFuZGFyZCBldmVudHMgZXhwaXJlIGZhc3RlciB0aGFuIHRoZVxuICAgKiBsb3ctdm9sdW1lIERPUkEgc291cmNlOlxuICAgKiAgLSBgcGlwZWxpbmVfZXZlbnRzIFdIRVJFIGVudmlyb25tZW50IElTIE5VTExgIOKGkiBzdGFuZGFyZC1ldmVudCB3aW5kb3cuXG4gICAqICAtIGBwaXBlbGluZV9ldmVudHMgV0hFUkUgZW52aXJvbm1lbnQgSVMgTk9UIE5VTExgIChkZXBsb3kgc3RhZ2VzKSxcbiAgICogICAgYGRlcGxveW1lbnRfb3V0Y29tZXNgLCBhbmQgYGluY2lkZW50c2Ag4oaSIERPUkEtc291cmNlIHdpbmRvdy5cbiAgICogRWFjaCBvcmcncyB3aW5kb3dzIGNvbWUgZnJvbSBpdHMgYGRvcmFfc2V0dGluZ3NgIG92ZXJyaWRlLCBlbHNlIHRoZSBnbG9iYWxcbiAgICogZW52IGRlZmF1bHRzIChzZWUge0BsaW5rIHJlc29sdmVFdmVudFJldGVudGlvbkRheXN9IC8ge0BsaW5rIHJlc29sdmVEb3JhUmV0ZW50aW9uRGF5c30pLlxuICAgKiBgaW5nZXN0X2hlYWx0aGAgYW5kIGBkb3JhX3NldHRpbmdzYCBhcmUgbmV2ZXIgcHVyZ2VkLiBPbmUgYG5vd2AgZm9yIHRoZSB3aG9sZVxuICAgKiB0aWNrIChyb3dzIGNyb3NzaW5nIHRoZSBib3VuZGFyeSBtaWQtc3dlZXAgd2FpdCBmb3IgdGhlIG5leHQpLiBFc3RhYmxpc2hlcyBhXG4gICAqIHN5c2FkbWluIHRlbmFudCBzY29wZSBzbyB0aGUgZGVsZXRlcyBzcGFuIGFsbCBvcmdzIC8gYnlwYXNzIFJMUyDigJQgdGhpcyBpcyBhXG4gICAqIGNyb3NzLXRlbmFudCBob3VzZWtlZXBpbmcgam9iLiBSZXR1cm5zIChhbmQgbG9ncykgcGVyLXdpbmRvdyBwdXJnZSB0YWxsaWVzLlxuICAgKi9cbiAgYXN5bmMgcHVyZ2VFeHBpcmVkUmVwb3J0aW5nRGF0YShvcHRzOiBSZXBvcnRpbmdSZXRlbnRpb25PcHRpb25zID0ge30pOiBQcm9taXNlPFJlcG9ydGluZ1JldGVudGlvbkNvdW50cz4ge1xuICAgIGNvbnN0IGJhdGNoU2l6ZSA9IE1hdGgubWF4KDEsIG9wdHMuYmF0Y2hTaXplID8/IDEwMDApO1xuICAgIGNvbnN0IG1heEJhdGNoZXMgPSBNYXRoLm1heCgxLCBvcHRzLm1heEJhdGNoZXNQZXJUYWJsZSA/PyA1MCk7XG4gICAgY29uc3Qgbm93ID0gb3B0cy5ub3cgPz8gbmV3IERhdGUoKTtcbiAgICBjb25zdCByZXNvbHZlUmV0ZW50aW9uT3JnSWQgPSBvcHRzLnJlc29sdmVSZXRlbnRpb25PcmdJZCA/PyAoYXN5bmMgKG9yZ0lkOiBzdHJpbmcpID0+IG9yZ0lkKTtcbiAgICBjb25zdCBjb3VudHM6IFJlcG9ydGluZ1JldGVudGlvbkNvdW50cyA9IHtcbiAgICAgIG9yZ3M6IDAsIHN0YW5kYXJkRXZlbnRzOiAwLCBkb3JhRXZlbnRzOiAwLCBkZXBsb3ltZW50T3V0Y29tZXM6IDAsIGluY2lkZW50czogMCxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEVudW1lcmF0ZSBldmVyeSBvcmcgd2l0aCByZXBvcnRpbmcgZGF0YSAodW5pb24gYWNyb3NzIHRoZSB0aHJlZSB0YWJsZXMpLlxuICAgICAgY29uc3Qgb3JnUm93cyA9IGRyaXp6bGVSb3dzPHsgb3JnX2lkOiBzdHJpbmcgfT4oKGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1QgRElTVElOQ1Qgb3JnX2lkIEZST00gKFxuICAgICAgICAgIFNFTEVDVCAke3NjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkfSBBUyBvcmdfaWQgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fVxuICAgICAgICAgIFVOSU9OXG4gICAgICAgICAgU0VMRUNUICR7c2NoZW1hLmRlcGxveW1lbnRPdXRjb21lLm9yZ0lkfSBBUyBvcmdfaWQgRlJPTSAke3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZX1cbiAgICAgICAgICBVTklPTlxuICAgICAgICAgIFNFTEVDVCAke3NjaGVtYS5pbmNpZGVudC5vcmdJZH0gQVMgb3JnX2lkIEZST00gJHtzY2hlbWEuaW5jaWRlbnR9XG4gICAgICAgICkgQVMgb3Jnc1xuICAgICAgYCkpKS5yb3dzKTtcbiAgICAgIGlmIChvcmdSb3dzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGNvdW50cztcblxuICAgICAgLy8gUGVyLW9yZyByZXRlbnRpb24gb3ZlcnJpZGVzIChhIHNpbmdsZSByZWFkOyBvcmdzIHdpdGhvdXQgYSByb3cgdXNlIGRlZmF1bHRzKS5cbiAgICAgIGNvbnN0IG92ZXJyaWRlUm93cyA9IGRyaXp6bGVSb3dzPHtcbiAgICAgICAgb3JnX2lkOiBzdHJpbmc7XG4gICAgICAgIGV2ZW50X3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgICBkb3JhX3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgfT4oKGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1QgJHtzY2hlbWEuZG9yYVNldHRpbmdzLm9yZ0lkfSBBUyBvcmdfaWQsXG4gICAgICAgICAgICAgICAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZXZlbnRSZXRlbnRpb25EYXlzfSBBUyBldmVudF9yZXRlbnRpb25fZGF5cyxcbiAgICAgICAgICAgICAgICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5kb3JhUmV0ZW50aW9uRGF5c30gQVMgZG9yYV9yZXRlbnRpb25fZGF5c1xuICAgICAgICBGUk9NICR7c2NoZW1hLmRvcmFTZXR0aW5nc31cbiAgICAgIGApKSkucm93cyk7XG4gICAgICBjb25zdCBvdmVycmlkZXMgPSBuZXcgTWFwKG92ZXJyaWRlUm93cy5tYXAoKHIpID0+IFtyLm9yZ19pZCwgcl0pKTtcblxuICAgICAgY29uc3QgZXZlbnRzVGFibGUgPSBzcWxgJHtzY2hlbWEucGlwZWxpbmVFdmVudH1gO1xuICAgICAgY29uc3Qgb3V0Y29tZXNUYWJsZSA9IHNxbGAke3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZX1gO1xuICAgICAgY29uc3QgaW5jaWRlbnRzVGFibGUgPSBzcWxgJHtzY2hlbWEuaW5jaWRlbnR9YDtcblxuICAgICAgZm9yIChjb25zdCB7IG9yZ19pZDogb3JnSWQgfSBvZiBvcmdSb3dzKSB7XG4gICAgICAgIC8vIFJldGVudGlvbiBmb2xsb3dzIHRoZSBhY2NvdW50IFJPT1QncyBlbnRpdGxlbWVudCAoYmlsbGluZyBzeW5jcyBpdCBvbnRvXG4gICAgICAgIC8vIHRoZSByb290IG9ubHkpLiBBbiB1bnJlc29sdmFibGUgcm9vdCDih5Igc2tpcCB0aGlzIG9yZyB0aGlzIHRpY2sgcmF0aGVyXG4gICAgICAgIC8vIHRoYW4gcHVyZ2UgYSB0ZWFtJ3Mgcm93cyBvbiB0aGUgKHNob3J0ZXIpIGVudiBkZWZhdWx0LlxuICAgICAgICBsZXQgcmV0ZW50aW9uT3JnSWQ6IHN0cmluZyB8IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0ZW50aW9uT3JnSWQgPSBhd2FpdCByZXNvbHZlUmV0ZW50aW9uT3JnSWQob3JnSWQpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbjogcm9vdCByZXNvbHV0aW9uIHRocmV3OyBza2lwcGluZyBvcmcgdGhpcyB0aWNrJywgeyBvcmdJZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgICAgIHJldGVudGlvbk9yZ0lkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmV0ZW50aW9uT3JnSWQgPT09IG51bGwpIHtcbiAgICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbjogY291bGQgbm90IHJlc29sdmUgdGhlIHJldGVudGlvbiByb290OyBvcmcgc2tpcHBlZCB0aGlzIHRpY2snLCB7IG9yZ0lkIH0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG92ID0gb3ZlcnJpZGVzLmdldChyZXRlbnRpb25PcmdJZCk7XG4gICAgICAgIGNvbnN0IGV2ZW50RGF5cyA9IHJlc29sdmVFdmVudFJldGVudGlvbkRheXMob3Y/LmV2ZW50X3JldGVudGlvbl9kYXlzKTtcbiAgICAgICAgY29uc3QgZG9yYURheXMgPSByZXNvbHZlRG9yYVJldGVudGlvbkRheXMob3Y/LmRvcmFfcmV0ZW50aW9uX2RheXMpO1xuICAgICAgICAvLyBgLTFgID0gdW5saW1pdGVkOiBrZWVwIGZvcmV2ZXIsIHNraXAgdGhhdCB3aW5kb3cncyBkZWxldGVzIGZvclxuICAgICAgICAvLyB0aGlzIG9yZy4gU3RhbmRhcmQtZXZlbnQgYW5kIERPUkEtc291cmNlIHdpbmRvd3MgYXJlIGluZGVwZW5kZW50OyBhbiBvcmdcbiAgICAgICAgLy8gd2l0aCBib3RoIGAtMWAgaXMgZnVsbHkgc2tpcHBlZC4gTG9nIHRoZSBza2lwIHNvIGl0J3Mgb2JzZXJ2YWJsZS5cbiAgICAgICAgY29uc3Qgc2tpcEV2ZW50cyA9IGV2ZW50RGF5cyA9PT0gLTE7XG4gICAgICAgIGNvbnN0IHNraXBEb3JhID0gZG9yYURheXMgPT09IC0xO1xuICAgICAgICBpZiAoc2tpcEV2ZW50cyB8fCBza2lwRG9yYSkge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKCdSZXBvcnRpbmcgcmV0ZW50aW9uIHN3ZWVwIHNraXBwaW5nIHVubGltaXRlZCB3aW5kb3cocyknLCB7XG4gICAgICAgICAgICBvcmdJZCxcbiAgICAgICAgICAgIHN0YW5kYXJkRXZlbnRzOiBza2lwRXZlbnRzID8gJ3VubGltaXRlZCcgOiBldmVudERheXMsXG4gICAgICAgICAgICBkb3JhU291cmNlOiBza2lwRG9yYSA/ICd1bmxpbWl0ZWQnIDogZG9yYURheXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXNraXBFdmVudHMpIHtcbiAgICAgICAgICBjb25zdCBldmVudEN1dG9mZiA9IHJldGVudGlvbkN1dG9mZihub3csIGV2ZW50RGF5cyk7XG4gICAgICAgICAgY291bnRzLnN0YW5kYXJkRXZlbnRzICs9IGF3YWl0IHRoaXMuI3B1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgICAgZXZlbnRzVGFibGUsXG4gICAgICAgICAgICAvLyBTcGFyZSByb3dzIGNhcnJ5aW5nIGEgY29tbWl0IHRpbWVzdGFtcDogdGhleSBhcmUgRE9SQSBTT1VSQ0UgZGF0YS5cbiAgICAgICAgICAgIC8vIExlYWQgdGltZSBqb2lucyBkZXBsb3lzIHRvIHRoZSBleGVjdXRpb24ncyBlYXJsaWVzdFxuICAgICAgICAgICAgLy8gYGNvbW1pdF90aW1lc3RhbXBgLCBhbmQgdGhhdCBlbnJpY2htZW50IHJpZGVzIHRoZSBQSVBFTElORS9zb3VyY2VcbiAgICAgICAgICAgIC8vIGV2ZW50IChlbnZpcm9ubWVudCBJUyBOVUxMKSwgbmV2ZXIgdGhlIGRlcGxveSBTVEFHRSByb3cuIFB1cmdpbmdcbiAgICAgICAgICAgIC8vIHRoZW0gb24gdGhpcyBzaG9ydCB3aW5kb3cgd2hpbGUgdGhlIGRlcGxveXMgdGhleSBleHBsYWluIGxpdmUgb25cbiAgICAgICAgICAgIC8vIHRoZSBET1JBIHdpbmRvdyBtYWRlIGxlYWQgdGltZSByZWFkIFwidW5rbm93blwiIGZvciBldmVyeSByYW5nZVxuICAgICAgICAgICAgLy8gb2xkZXIgdGhhbiB0aGUgc3RhbmRhcmQgcmV0ZW50aW9uIOKAlCBzaWxlbnRseSwgd2l0aCB0aGUgZGVwbG95c1xuICAgICAgICAgICAgLy8gc3RpbGwgY291bnRlZC4gVGhleSBmb2xsb3cgdGhlIERPUkEgd2luZG93IGJlbG93IGluc3RlYWQuXG4gICAgICAgICAgICBzcWxgb3JnX2lkID0gJHtvcmdJZH0gQU5EIGVudmlyb25tZW50IElTIE5VTEwgQU5EIGNvbW1pdF90aW1lc3RhbXAgSVMgTlVMTCBBTkQgY3JlYXRlZF9hdCA8ICR7ZXZlbnRDdXRvZmZ9YCxcbiAgICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFza2lwRG9yYSkge1xuICAgICAgICAgIGNvbnN0IGRvcmFDdXRvZmYgPSByZXRlbnRpb25DdXRvZmYobm93LCBkb3JhRGF5cyk7XG4gICAgICAgICAgY291bnRzLmRvcmFFdmVudHMgKz0gYXdhaXQgdGhpcy4jcHVyZ2VSZXBvcnRpbmdUYWJsZUJhdGNoZWQoXG4gICAgICAgICAgICBldmVudHNUYWJsZSxcbiAgICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgKGVudmlyb25tZW50IElTIE5PVCBOVUxMIE9SIGNvbW1pdF90aW1lc3RhbXAgSVMgTk9UIE5VTEwpIEFORCBjcmVhdGVkX2F0IDwgJHtkb3JhQ3V0b2ZmfWAsXG4gICAgICAgICAgICBiYXRjaFNpemUsIG1heEJhdGNoZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb3VudHMuZGVwbG95bWVudE91dGNvbWVzICs9IGF3YWl0IHRoaXMuI3B1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgICAgb3V0Y29tZXNUYWJsZSxcbiAgICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgY3JlYXRlZF9hdCA8ICR7ZG9yYUN1dG9mZn1gLFxuICAgICAgICAgICAgYmF0Y2hTaXplLCBtYXhCYXRjaGVzLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY291bnRzLmluY2lkZW50cyArPSBhd2FpdCB0aGlzLiNwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgICAgICAgICAgIGluY2lkZW50c1RhYmxlLFxuICAgICAgICAgICAgc3FsYG9yZ19pZCA9ICR7b3JnSWR9IEFORCBjcmVhdGVkX2F0IDwgJHtkb3JhQ3V0b2ZmfWAsXG4gICAgICAgICAgICBiYXRjaFNpemUsIG1heEJhdGNoZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBjb3VudHMub3JncyArPSAxO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwdXJnZWRBbnkgPSBjb3VudHMuc3RhbmRhcmRFdmVudHMgKyBjb3VudHMuZG9yYUV2ZW50cyArIGNvdW50cy5kZXBsb3ltZW50T3V0Y29tZXMgKyBjb3VudHMuaW5jaWRlbnRzO1xuICAgICAgaWYgKHB1cmdlZEFueSA+IDApIGxvZ2dlci5pbmZvKCdSZXBvcnRpbmcgcmV0ZW50aW9uIHN3ZWVwIHB1cmdlZCBleHBpcmVkIHJvd3MnLCB7IC4uLmNvdW50cyB9KTtcbiAgICAgIHJldHVybiBjb3VudHM7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHJlcG9ydGluZ1NlcnZpY2UgPSBuZXcgUmVwb3J0aW5nU2VydmljZSgpO1xuIl19
668
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbEgsT0FBTyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUUsZ0ZBQWdGO0FBQ2hGLDRFQUE0RTtBQUM1RSxPQUFPLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0UsT0FBTyxFQUFFLDBCQUEwQixFQUFFLDBCQUEwQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckcsT0FBTyxFQUNMLGNBQWMsSUFBSSxXQUFXLEVBQzdCLFlBQVksSUFBSSxTQUFTLEVBQ3pCLGNBQWMsSUFBSSxXQUFXLEdBQzlCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsOEVBQThFO0FBQzlFLE9BQU8sRUFBRSxZQUFZLElBQUksTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDL0QsT0FBTyxFQUNMLGdCQUFnQixJQUFJLGFBQWEsRUFDakMseUJBQXlCLElBQUksc0JBQXNCLEVBQ25ELG9CQUFvQixJQUFJLGlCQUFpQixHQUMxQyxNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUseUJBQXlCLElBQUks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ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIsIGVycm9yTWVzc2FnZSwgaXNvT3JOdWxsLCBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGVxLCBzcWwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBkcml6emxlUm93cyB9IGZyb20gJy4vY3J1ZC1zZXJ2aWNlLmpzJztcbmltcG9ydCB7IHNjaGVtYSB9IGZyb20gJy4uL2RhdGFiYXNlL2RyaXp6bGUtc2NoZW1hLmpzJztcbmltcG9ydCB7IHdpdGhUZW5hbnRUeCwgcnVuV2l0aFRlbmFudENvbnRleHQgfSBmcm9tICcuLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuLy8gRXh0cmFjdGVkIGZvciBzaXplIOKAlCBzZWUgLi9yZXBvcnRpbmcvLiBFdmVyeXRoaW5nIHB1YmxpYyBpcyByZS1leHBvcnRlZCBiZWxvd1xuLy8gc28gYEBwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWRhdGFgJ3Mgc3VyZmFjZSBpcyB1bmNoYW5nZWQgYnkgdGhlIHNwbGl0LlxuaW1wb3J0IHsgaW52ZW50b3J5Q2FjaGUsIGludmFsaWRhdGVPcmdSZXBvcnRzIH0gZnJvbSAnLi9yZXBvcnRpbmcvY2FjaGVzLmpzJztcbmltcG9ydCB7IERPUkFfSU5DSURFTlRfV0lORE9XX0hPVVJTLCByZXNvbHZlSW5jaWRlbnRXaW5kb3dIb3VycyB9IGZyb20gJy4vcmVwb3J0aW5nL2RvcmEtc2NvcmluZy5qcyc7XG5pbXBvcnQge1xuICBnZXREb3JhTWV0cmljcyBhcyBkb3JhTWV0cmljcyxcbiAgZ2V0RG9yYVRyZW5kIGFzIGRvcmFUcmVuZCxcbiAgZ2V0QnVpbGRIZWFsdGggYXMgYnVpbGRIZWFsdGgsXG59IGZyb20gJy4vcmVwb3J0aW5nL2RvcmEuanMnO1xuLy8gQWxpYXNlZDogdGhlIG1vZHVsZSBmdW5jdGlvbnMgYW5kIHRoZSBkZWxlZ2F0aW5nIG1ldGhvZHMgYmVsb3cgc2hhcmUgbmFtZXMuXG5pbXBvcnQgeyBpbmdlc3RFdmVudHMgYXMgaW5nZXN0IH0gZnJvbSAnLi9yZXBvcnRpbmcvaW5nZXN0LmpzJztcbmltcG9ydCB7XG4gIGdldFBsdWdpblJ1bnRpbWUgYXMgcGx1Z2luUnVudGltZSxcbiAgZ2V0UGx1Z2luUnVudGltZUFnZ3JlZ2F0ZSBhcyBwbHVnaW5SdW50aW1lQWdncmVnYXRlLFxuICBoYXNWZXJpZmllZFBsdWdpblVzZSBhcyB2ZXJpZmllZFBsdWdpblVzZSxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvcGx1Z2luLXJ1bnRpbWUuanMnO1xuaW1wb3J0IHsgcmVwb3J0IH0gZnJvbSAnLi9yZXBvcnRpbmcvcXVlcnktc2NvcGUuanMnO1xuaW1wb3J0IHsgcHVyZ2VFeHBpcmVkUmVwb3J0aW5nRGF0YSBhcyBwdXJnZVJlcG9ydGluZ1JldGVudGlvbiB9IGZyb20gJy4vcmVwb3J0aW5nL3JldGVudGlvbi1zd2VlcC5qcyc7XG5pbXBvcnQgeyBSRVBPUlRJTkdfRVZFTlRfUkVURU5USU9OX0RBWVMsIFJFUE9SVElOR19ET1JBX1JFVEVOVElPTl9EQVlTIH0gZnJvbSAnLi9yZXBvcnRpbmcvcmV0ZW50aW9uLmpzJztcbmltcG9ydCB7IGFzc2VydFJlcG9ydEludGVydmFsLCBzY3J1Yk9wdGlvbmFsLCBvcHRpb25hbFN0YXJ0ZWRBdFJhbmdlLCBzdGFydGVkQXRXaW5kb3cgfSBmcm9tICcuL3JlcG9ydGluZy9zcWwtaGVscGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEV4ZWN1dGlvbkNvdW50LCBUaW1lU2VyaWVzRW50cnksIER1cmF0aW9uU3RhdHMsIFBpcGVsaW5lRXhlY3V0aW9uLCBTdGFnZUZhaWx1cmUsIFN0YWdlQm90dGxlbmVjayxcbiAgQWN0aW9uRmFpbHVyZSwgRXJyb3JFbnRyeSwgUGx1Z2luU3VtbWFyeSwgVHlwZUNvbXB1dGVEaXN0cmlidXRpb24sIFZlcnNpb25Db3VudCxcbiAgQnVpbGRUaW1lU2VyaWVzRW50cnksIEJ1aWxkRHVyYXRpb24sIEJ1aWxkRmFpbHVyZSxcbiAgUGx1Z2luUnVudGltZUFnZ3JlZ2F0ZSwgUGx1Z2luUnVudGltZUZpbHRlciwgUGx1Z2luUnVudGltZVN0YXRzLFxuICBSZXBvcnRpbmdSZXRlbnRpb25PcHRpb25zLCBSZXBvcnRpbmdSZXRlbnRpb25Db3VudHMsXG4gIERvcmFPcHRpb25zLCBSZXBvcnRpbmdTZXR0aW5ncywgUmVwb3J0aW5nU2V0dGluZ3NQYXRjaCwgSW5jaWRlbnRMaXN0SXRlbSwgSW5jaWRlbnRUZXN0UmVzdWx0LFxuICBEb3JhTWV0cmljcywgRG9yYVRyZW5kUG9pbnQsIEJ1aWxkSGVhbHRoLCBJbmNpZGVudElucHV0LFxuICBJbmdlc3RFdmVudCwgSW5nZXN0TWV0cmljLCBJbmdlc3RSZXN1bHQsIEluZ2VzdEhlYWx0aFN0YXR1cyxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvdHlwZXMuanMnO1xuXG4vLyBUaGUgcmVwb3J0aW5nIHR5cGVzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIHBhY2thZ2UgQVBJLiBFbnVtZXJhdGVkIHJhdGhlciB0aGFuXG4vLyBgZXhwb3J0ICpgIGJlY2F1c2UgdGhlIHJlcG9ydGluZyBtb2R1bGVzIGFsc28gZXhwb3J0IGludGVybmFscyAob3JnU2NvcGUsXG4vLyBydW5SZXBvcnQsIHRoZSBjYWNoZXMsIHRoZSBET1JBIHJvdyBzaGFwZXMpIHRoYXQgbXVzdCBzdGF5IHByaXZhdGUuXG5leHBvcnQgdHlwZSB7XG4gIEJ1aWxkSGVhbHRoLCBCdWlsZEhlYWx0aFN0YWdlLCBEb3JhRW52TWV0cmljcywgRG9yYUxldmVsLCBEb3JhTWV0cmljcywgRG9yYU9wdGlvbnMsIERvcmFUcmVuZFBvaW50LFxuICBJbmNpZGVudElucHV0LCBJbmNpZGVudExpc3RJdGVtLCBSZXBvcnRpbmdTZXR0aW5ncywgSW5jaWRlbnRUZXN0UmVzdWx0LFxuICBJbmdlc3RFdmVudCwgSW5nZXN0SGVhbHRoU3RhdHVzLCBJbmdlc3RNZXRyaWMsIEluZ2VzdFJlc3VsdCxcbiAgUGx1Z2luUnVudGltZUFnZ3JlZ2F0ZSwgUGx1Z2luUnVudGltZUZpbHRlciwgUGx1Z2luUnVudGltZVN0YXRzLFxuICBSZXBvcnRpbmdSZXRlbnRpb25Db3VudHMsIFJlcG9ydGluZ1JldGVudGlvbk9wdGlvbnMsIFJlcG9ydGluZ1JldGVudGlvblNldHRpbmdzLFxuICBSZXBvcnRpbmdTZXR0aW5nc1BhdGNoLFxufSBmcm9tICcuL3JlcG9ydGluZy90eXBlcy5qcyc7XG5cblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZXBvcnRpbmctc2VydmljZScpO1xuXG5leHBvcnQgY2xhc3MgUmVwb3J0aW5nU2VydmljZSB7XG5cbiAgLyoqIEludmFsaWRhdGUgYWxsIGNhY2hlZCByZXBvcnRzIGZvciBhbiBvcmcgKGNhbGwgYWZ0ZXIgZXZlbnQgaW5nZXN0KS4gKi9cbiAgYXN5bmMgaW52YWxpZGF0ZU9yZyhvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgaW52YWxpZGF0ZU9yZ1JlcG9ydHMob3JnSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgaW5jb21pbmcgZXZlbnRzIGFnYWluc3QgdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBiYXRjaC1pbnNlcnQgdGhlXG4gICAqIG1hdGNoZWQgb25lcywgYW5kIGludmFsaWRhdGUgcmVwb3J0aW5nIGNhY2hlcyBmb3IgYWZmZWN0ZWQgb3Jncy5cbiAgICogU2VlIC4vcmVwb3J0aW5nL2luZ2VzdC50cyDigJQgdGhlIGNhbGxlciBtdXN0IGFscmVhZHkgaG9sZCBhIHN5c2FkbWluXG4gICAqIHRlbmFudCBzY29wZSwgYmVjYXVzZSBhIGJhdGNoIHNwYW5zIHdoYXRldmVyIG9yZ3MgdGhlIHJlZ2lzdHJ5IHJlc29sdmVzIHRvLlxuICAgKi9cbiAgYXN5bmMgaW5nZXN0RXZlbnRzKGV2ZW50czogSW5nZXN0RXZlbnRbXSwgb25NZXRyaWM/OiAobTogSW5nZXN0TWV0cmljKSA9PiB2b2lkKTogUHJvbWlzZTxJbmdlc3RSZXN1bHQ+IHtcbiAgICByZXR1cm4gaW5nZXN0KGV2ZW50cywgb25NZXRyaWMpO1xuICB9XG5cbiAgLy8g4pSA4pSAIENhdGVnb3J5IDE6IFBpcGVsaW5lIEV4ZWN1dGlvbiAmIFBlcmZvcm1hbmNlIOKUgOKUgFxuXG5cbiAgLyoqIEV4ZWN1dGlvbiBjb3VudCBwZXIgcGlwZWxpbmUgd2l0aCBzdGF0dXMgYnJlYWtkb3duLiAqL1xuICBhc3luYyBnZXRFeGVjdXRpb25Db3VudChvcmdJZDogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSwgcmFuZ2U/OiB7IGZyb20/OiBzdHJpbmc7IHRvPzogc3RyaW5nIH0pOiBQcm9taXNlPEV4ZWN1dGlvbkNvdW50W10+IHtcbiAgICAvLyBPcHRpb25hbCBbZnJvbSx0b10gd2luZG93IG9uIHRoZSBleGVjdXRpb24ncyBzdGFydGVkX2F0LCBtaXJyb3JpbmcgdGhlXG4gICAgLy8gc2libGluZyB0aW1lc2VyaWVzIHJlcG9ydHMgc28gdGhlIGRhc2hib2FyZCBkYXRlLXJhbmdlIHBpY2tlciBuYXJyb3dzIHRoZVxuICAgIC8vIGNvdW50IHRvbyAoYW4gZW1wdHkgcmFuZ2UgPSBhbGwtdGltZSwgcHJlc2VydmluZyB0aGUgcHJpb3IgYmVoYXZpb3IpLiBUaGVcbiAgICAvLyByYW5nZSByaWRlcyB0aGUgSk9JTiBzbyBwaXBlbGluZXMgd2l0aCBubyBpbi13aW5kb3cgZXZlbnRzIHN0aWxsIGxpc3RcbiAgICAvLyAoTEVGVCBzZW1hbnRpY3MgcHJlc2VydmVkIHZpYSB0aGUgaW5uZXItam9pbiBmaWx0ZXIg4oCUIGEgcGlwZWxpbmUgd2l0aCB6ZXJvXG4gICAgLy8gbWF0Y2hpbmcgZXZlbnRzIGRyb3BzIGZyb20gdGhlIGNvdW50LCBzYW1lIGFzIGJlZm9yZSBmb3IgaXRzIHdpbmRvdykuXG4gICAgY29uc3QgcmFuZ2VDbGF1c2UgPSBvcHRpb25hbFN0YXJ0ZWRBdFJhbmdlKHJhbmdlKTtcbiAgICByZXR1cm4gcmVwb3J0PEV4ZWN1dGlvbkNvdW50PihgZXhlYy1jb3VudDoke3JhbmdlPy5mcm9tID8/ICcnfToke3JhbmdlPy50byA/PyAnJ31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnByb2plY3QsIHAub3JnYW5pemF0aW9uLCBwLnBpcGVsaW5lX25hbWUsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpOjppbnQgQVMgY2FuY2VsZWQsXG4gICAgICAgICAgTUlOKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgZmlyc3RfZXhlY3V0aW9uLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3RfZXhlY3V0aW9uXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmV9IHBcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlIE9OIGUucGlwZWxpbmVfaWQgPSBwLmlkXG4gICAgICAgICAgQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuc3RhdHVzICE9ICdTVEFSVEVEJ1xuICAgICAgICAgICR7cmFuZ2VDbGF1c2V9XG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIHAuaXNfYWN0aXZlID0gdHJ1ZVxuICAgICAgICBHUk9VUCBCWSBwLmlkXG4gICAgICAgIE9SREVSIEJZIHRvdGFsIERFU0NcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlci1waXBlbGluZSBleGVjdXRpb24gaGlzdG9yeSDigJQgRElTVElOQ1QgZXhlY3V0aW9ucyBmb3Igb25lIHBpcGVsaW5lLFxuICAgKiBuZXdlc3QgZmlyc3QuIEdyb3VwcyBhbGwgZXZlbnRzIGJ5IGBleGVjdXRpb25faWRgIGluIGEgc2luZ2xlIHNjYW4gYW5kXG4gICAqIHJvbGxzIGVhY2ggZXhlY3V0aW9uIHVwIHRvIG9uZSByb3c6XG4gICAqICAgLSBzdGF0dXM6IGRlcml2ZWQgZnJvbSB0aGUgUElQRUxJTkUtdHlwZSBldmVudHMuIEZBSUxFRCB3aW5zLCB0aGVuXG4gICAqICAgICBTVUNDRUVERUQsIHRoZW4gQ0FOQ0VMRUQ7IGFuIGV4ZWN1dGlvbiB3aXRoIG5vIHRlcm1pbmFsIFBJUEVMSU5FIGV2ZW50XG4gICAqICAgICBpcyBzdGlsbCBgaW4tcHJvZ3Jlc3NgLlxuICAgKiAgIC0gc3RhcnRlZEF0L2VuZGVkQXQvZHVyYXRpb25NczogZnJvbSB0aGUgUElQRUxJTkUgbGlmZWN5Y2xlIGV2ZW50cy5cbiAgICogICAtIGZhaWxpbmdTdGFnZS9mYWlsaW5nQWN0aW9uOiB0aGUgZmlyc3QgRkFJTEVEIFNUQUdFL0FDVElPTiBldmVudCAoY2hlYXAg4oCUXG4gICAqICAgICBzYW1lIHNjYW4sIG5vIGV4dHJhIHF1ZXJ5KS5cbiAgICpcbiAgICogT1JHLVNDT1BJTkc6IGlkZW50aWNhbCB0byB0aGUgc2libGluZyBleGVjdXRpb24gcmVwb3J0cyDigJQgam9pbnMgdGhlIHBpcGVsaW5lXG4gICAqIHJlZ2lzdHJ5IHRhYmxlIChgcGlwZWxpbmVgKSBhbmQgZ2F0ZXMgb24gYHAub3JnX2lkICR7cHJlZH1gLCB3aGVyZSBgcHJlZGAgaXNcbiAgICogdGhlIHNpbmdsZS1vcmcgYD0gJG9yZ2Agb3IgKHdpdGggYSByb2xsdXApIGFuIGBJTiAoLi4uKWAgb3ZlciB0aGUgb3Jn4oaSdGVhbVxuICAgKiBzdWJ0cmVlLiBBIHBpcGVsaW5lSWQgYmVsb25naW5nIHRvIGFub3RoZXIgb3JnIHlpZWxkcyB6ZXJvIHJvd3MuXG4gICAqL1xuICBhc3luYyBsaXN0UGlwZWxpbmVFeGVjdXRpb25zKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgcGlwZWxpbmVJZDogc3RyaW5nLFxuICAgIG9yZ0lkcz86IHN0cmluZ1tdLFxuICAgIHJhbmdlPzogeyBmcm9tPzogc3RyaW5nOyB0bz86IHN0cmluZyB9LFxuICAgIGxpbWl0OiBudW1iZXIgPSA1MCxcbiAgKTogUHJvbWlzZTxQaXBlbGluZUV4ZWN1dGlvbltdPiB7XG4gICAgY29uc3QgcmFuZ2VDbGF1c2UgPSBvcHRpb25hbFN0YXJ0ZWRBdFJhbmdlKHJhbmdlKTtcbiAgICByZXR1cm4gcmVwb3J0PFBpcGVsaW5lRXhlY3V0aW9uPihgcGlwZWxpbmUtZXhlY3V0aW9uczoke3BpcGVsaW5lSWR9OiR7cmFuZ2U/LmZyb20gPz8gJyd9OiR7cmFuZ2U/LnRvID8/ICcnfToke2xpbWl0fWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZXhlY3V0aW9uX2lkLFxuICAgICAgICAgIENBU0VcbiAgICAgICAgICAgIFdIRU4gYm9vbF9vcihlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnKSBUSEVOICdmYWlsZWQnXG4gICAgICAgICAgICBXSEVOIGJvb2xfb3IoZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJykgVEhFTiAnc3VjY2VlZGVkJ1xuICAgICAgICAgICAgV0hFTiBib29sX29yKGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuc3RhdHVzID0gJ0NBTkNFTEVEJykgVEhFTiAnY2FuY2VsZWQnXG4gICAgICAgICAgICBFTFNFICdpbi1wcm9ncmVzcydcbiAgICAgICAgICBFTkQgQVMgc3RhdHVzLFxuICAgICAgICAgIE1JTihlLnN0YXJ0ZWRfYXQpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyk6OnRleHQgQVMgc3RhcnRlZF9hdCxcbiAgICAgICAgICBNQVgoZS5jb21wbGV0ZWRfYXQpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyk6OnRleHQgQVMgZW5kZWRfYXQsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyk6OmludCBBUyBkdXJhdGlvbl9tcyxcbiAgICAgICAgICAoQVJSQVlfQUdHKGUuc3RhZ2VfbmFtZSkgRklMVEVSIChXSEVSRSBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnKSlbMV0gQVMgZmFpbGluZ19zdGFnZSxcbiAgICAgICAgICAoQVJSQVlfQUdHKGUuYWN0aW9uX25hbWUpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ0FDVElPTicgQU5EIGUuc3RhdHVzID0gJ0ZBSUxFRCcpKVsxXSBBUyBmYWlsaW5nX2FjdGlvblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLnBpcGVsaW5lX2lkID0gJHtwaXBlbGluZUlkfSBBTkQgZS5leGVjdXRpb25faWQgSVMgTk9UIE5VTExcbiAgICAgICAgICAke3JhbmdlQ2xhdXNlfVxuICAgICAgICBHUk9VUCBCWSBlLmV4ZWN1dGlvbl9pZFxuICAgICAgICBPUkRFUiBCWSBNQVgoZS5jcmVhdGVkX2F0KSBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9XG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBTdWNjZXNzIHJhdGUgb3ZlciB0aW1lIGZvciBhbiBvcmcuICovXG4gIGFzeW5jIGdldFN1Y2Nlc3NSYXRlKG9yZ0lkOiBzdHJpbmcsIGludGVydmFsOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgYXNzZXJ0UmVwb3J0SW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgIHJldHVybiByZXBvcnQ8VGltZVNlcmllc0VudHJ5Pihgc3VjY2Vzcy1yYXRlOiR7aW50ZXJ2YWx9OiR7ZnJvbX06JHt0b31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBEQVRFX1RSVU5DKCR7aW50ZXJ2YWx9LCBlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIHBlcmlvZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpOjppbnQgQVMgY2FuY2VsZWQsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgc3VjY2Vzc19wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJ1xuICAgICAgICAgIEFORCBlLnN0YXR1cyBJTiAoJ1NVQ0NFRURFRCcsICdGQUlMRUQnLCAnQ0FOQ0VMRUQnKVxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIHBlcmlvZCBPUkRFUiBCWSBwZXJpb2RcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqIEF2ZXJhZ2UgZHVyYXRpb24gcGVyIHBpcGVsaW5lLiAqL1xuICBhc3luYyBnZXRBdmVyYWdlRHVyYXRpb24ob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8RHVyYXRpb25TdGF0c1tdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxEdXJhdGlvblN0YXRzPihgYXZnLWR1cmF0aW9uOiR7ZnJvbX06JHt0b31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnByb2plY3QsIHAucGlwZWxpbmVfbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUlOKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWluX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tcyxcbiAgICAgICAgICBQRVJDRU5USUxFX0NPTlQoMC45NSkgV0lUSElOIEdST1VQIChPUkRFUiBCWSBlLmR1cmF0aW9uX21zKTo6aW50IEFTIHA5NV9tcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGV4ZWN1dGlvbnNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIHAuaWQgT1JERVIgQlkgYXZnX21zIERFU0NcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqIFN0YWdlIGZhaWx1cmUgaGVhdG1hcCDigJQgd2hpY2ggc3RhZ2VzIGZhaWwgbW9zdC4gKi9cbiAgYXN5bmMgZ2V0U3RhZ2VGYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxTdGFnZUZhaWx1cmVbXT4ge1xuICAgIHJldHVybiByZXBvcnQ8U3RhZ2VGYWlsdXJlPihgc3RhZ2UtZmFpbHVyZXM6JHtmcm9tfToke3RvfWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuc3RhZ2VfbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbHVyZXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBmYWlsdXJlX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLnN0YWdlX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBlLnN0YWdlX25hbWUgT1JERVIgQlkgZmFpbHVyZXMgREVTQ1xuICAgICAgYCk7XG4gIH1cblxuICAvKipcbiAgICogRGlzdGluY3QgZGVwbG95IGBlbnZpcm9ubWVudGAgdmFsdWVzIG9ic2VydmVkIGluIHRoZSB3aW5kb3cg4oCUIHBvd2VycyB0aGVcbiAgICogRE9SQSBlbnZpcm9ubWVudC1zY29wZSBkYXRhbGlzdC4gT3JnLXNjb3BlZCArIHJvbGx1cC1hd2FyZSBsaWtlIHRoZSBzaWJsaW5nXG4gICAqIHJlcG9ydHM7IG9ubHkgbm9uLW51bGwgZW52aXJvbm1lbnRzIChpLmUuIGRlcGxveS1hdHRyaWJ1dGVkIGV4ZWN1dGlvbnMpLlxuICAgKi9cbiAgYXN5bmMgZ2V0UmVwb3J0RW52aXJvbm1lbnRzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3Qgcm93cyA9IGF3YWl0IHJlcG9ydDx7IGVudmlyb25tZW50OiBzdHJpbmcgfT4oYHJlcG9ydC1lbnZzOiR7ZnJvbX06JHt0b31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1QgRElTVElOQ1QgZS5lbnZpcm9ubWVudCBBUyBlbnZpcm9ubWVudFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmVudmlyb25tZW50IElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgT1JERVIgQlkgZW52aXJvbm1lbnRcbiAgICAgIGApO1xuICAgIHJldHVybiByb3dzLm1hcCgocm93KSA9PiByb3cuZW52aXJvbm1lbnQpO1xuICB9XG5cbiAgLyoqIFN0YWdlIGJvdHRsZW5lY2tzIOKAlCBzbG93ZXN0IHN0YWdlcyBwZXIgcGlwZWxpbmUuICovXG4gIGFzeW5jIGdldFN0YWdlQm90dGxlbmVja3Mob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8U3RhZ2VCb3R0bGVuZWNrW10+IHtcbiAgICByZXR1cm4gcmVwb3J0PFN0YWdlQm90dGxlbmVjaz4oYHN0YWdlLWJvdHRsZW5lY2tzOiR7ZnJvbX06JHt0b31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnBpcGVsaW5lX25hbWUsIGUuc3RhZ2VfbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdTVEFHRScgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwLmlkLCBlLnN0YWdlX25hbWUgT1JERVIgQlkgYXZnX21zIERFU0NcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqIEFjdGlvbiBmYWlsdXJlIHJhdGUg4oCUIHdoaWNoIHBsdWdpbiBzdGVwcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldEFjdGlvbkZhaWx1cmVzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPEFjdGlvbkZhaWx1cmVbXT4ge1xuICAgIHJldHVybiByZXBvcnQ8QWN0aW9uRmFpbHVyZT4oYGFjdGlvbi1mYWlsdXJlczoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5hY3Rpb25fbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbHVyZXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBmYWlsdXJlX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnQUNUSU9OJyBBTkQgZS5hY3Rpb25fbmFtZSBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIGUuYWN0aW9uX25hbWUgT1JERVIgQlkgZmFpbHVyZXMgREVTQ1xuICAgICAgYCk7XG4gIH1cblxuICAvKipcbiAgICogRXJyb3IgY2F0ZWdvcml6YXRpb24g4oCUIGdyb3VwIGZhaWx1cmUgbWVzc2FnZXMuIEV4ZWN1dGlvbiByZXBvcnQsIHNvXG4gICAqIHJvbGx1cC1hd2FyZSBleGFjdGx5IGxpa2UgdGhlIHNpYmxpbmcgZXhlY3V0aW9uIHJlcG9ydHM6IHdpdGggYG9yZ0lkc2BcbiAgICogKHRoZSBvcmfihpJ0ZWFtIHN1YnRyZWUpIHRoZSBvcmcgZ2F0ZSBiZWNvbWVzIGFuIGBJTiAoLi4uKWAgYW5kIHRoZSByZWFkIHJ1bnNcbiAgICogZnJlc2ggdW5kZXIgc3lzYWRtaW4gdmlhIGBydW5SZXBvcnRgOyBzaW5nbGUtb3JnIHJlYWRzIGtlZXAgdGhlIHBlci1vcmcgY2FjaGUuXG4gICAqL1xuICBhc3luYyBnZXRFcnJvcnMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBsaW1pdDogbnVtYmVyID0gMjAsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxFcnJvckVudHJ5W10+IHtcbiAgICByZXR1cm4gcmVwb3J0PEVycm9yRW50cnk+KGBlcnJvcnM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIFNVQlNUUklORyhlLmVycm9yX21lc3NhZ2UgRlJPTSAxIEZPUiAyMDApIEFTIGVycm9yX3BhdHRlcm4sXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBvY2N1cnJlbmNlcyxcbiAgICAgICAgICBDT1VOVChESVNUSU5DVCBlLnBpcGVsaW5lX2lkKTo6aW50IEFTIGFmZmVjdGVkX3BpcGVsaW5lcyxcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X3NlZW5cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5zdGF0dXMgPSAnRkFJTEVEJyBBTkQgZS5lcnJvcl9tZXNzYWdlIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgZXJyb3JfcGF0dGVybiBPUkRFUiBCWSBvY2N1cnJlbmNlcyBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9XG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgZm91ciBET1JBIG1lYXN1cmVzIHBsdXMgdGhlaXIgcGVyLWVudmlyb25tZW50IGJyZWFrZG93bi5cbiAgICogSW1wbGVtZW50YXRpb24gaW4gLi9yZXBvcnRpbmcvZG9yYS50cyDigJQgc2VlIHRoYXQgZmlsZSdzIGhlYWRlciBmb3Igd2h5LlxuICAgKi9cbiAgZ2V0RG9yYU1ldHJpY3MoXG4gICAgb3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSwgb3B0czogRG9yYU9wdGlvbnMgPSB7fSxcbiAgKTogUHJvbWlzZTxEb3JhTWV0cmljcz4ge1xuICAgIHJldHVybiBkb3JhTWV0cmljcyhvcmdJZCwgZnJvbSwgdG8sIG9yZ0lkcywgb3B0cyk7XG4gIH1cblxuICAvKiogRE9SQSBtZWFzdXJlcyBidWNrZXRlZCBvdmVyIHRpbWUuICovXG4gIGdldERvcmFUcmVuZChcbiAgICBvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdLCBvcHRzOiBEb3JhT3B0aW9ucyA9IHt9LFxuICApOiBQcm9taXNlPERvcmFUcmVuZFBvaW50W10+IHtcbiAgICByZXR1cm4gZG9yYVRyZW5kKG9yZ0lkLCBpbnRlcnZhbCwgZnJvbSwgdG8sIG9yZ0lkcywgb3B0cyk7XG4gIH1cblxuICAvKiogUGVyLXBpcGVsaW5lIGJ1aWxkIGhlYWx0aCAoc3RhZ2UgcGFzcyByYXRlcyBvdmVyIGEgd2luZG93KS4gKi9cbiAgZ2V0QnVpbGRIZWFsdGgoXG4gICAgb3JnSWQ6IHN0cmluZywgcGlwZWxpbmVJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdLFxuICApOiBQcm9taXNlPEJ1aWxkSGVhbHRoPiB7XG4gICAgcmV0dXJuIGJ1aWxkSGVhbHRoKG9yZ0lkLCBwaXBlbGluZUlkLCBmcm9tLCB0bywgb3JnSWRzKTtcbiAgfVxuXG4gIGFzeW5jIGdldFBsdWdpblN1bW1hcnkob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8UGx1Z2luU3VtbWFyeT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLXN1bW1hcnlgLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9KTo6aW50IEFTIGFjdGl2ZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIE5PVCAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9KTo6aW50IEFTIGluYWN0aXZlLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLnZpc2liaWxpdHl9ID0gJ3B1YmxpYycpOjppbnQgQVMgcHVibGljLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLnZpc2liaWxpdHl9ID0gJ29yZycpOjppbnQgQVMgb3JnLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLnZpc2liaWxpdHl9ID0gJ3ByaXZhdGUnKTo6aW50IEFTIHByaXZhdGUsXG4gICAgICAgICAgQ09VTlQoRElTVElOQ1QgJHtzY2hlbWEucGx1Z2luLm5hbWV9KTo6aW50IEFTIHVuaXF1ZV9uYW1lc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBsdWdpbn1cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEucGx1Z2luLm9yZ0lkfSA9ICR7b3JnSWR9XG4gICAgICBgKSk7XG4gICAgICByZXR1cm4gKGRyaXp6bGVSb3dzPFBsdWdpblN1bW1hcnk+KHJvd3Mucm93cylbMF0gfHwgeyB0b3RhbDogMCwgYWN0aXZlOiAwLCBpbmFjdGl2ZTogMCwgcHVibGljOiAwLCBvcmc6IDAsIHByaXZhdGU6IDAsIHVuaXF1ZU5hbWVzOiAwIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIFR5cGUgJiBjb21wdXRlIGRpc3RyaWJ1dGlvbi5cbiAgICogIElOVEVOVElPTkFMTFkgU0lOR0xFLU9SRyAobm8gcm9sbHVwKTogcGx1Z2luIGludmVudG9yeSBpcyBwZXItb3JnIChzZWVcbiAgICogIGdldFBsdWdpblN1bW1hcnkpLiBTaW5nbGUgYD0gJG9yZ2Agc2NvcGUuICovXG4gIGFzeW5jIGdldFBsdWdpbkRpc3RyaWJ1dGlvbihvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbltdPiB7XG4gICAgcmV0dXJuIGludmVudG9yeUNhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpwbHVnaW4tZGlzdHJpYnV0aW9uYCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICAke3NjaGVtYS5wbHVnaW4ucGx1Z2luVHlwZX0gQVMgcGx1Z2luX3R5cGUsXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLmNvbXB1dGVUeXBlfSBBUyBjb21wdXRlX3R5cGUsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBjb3VudFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBsdWdpbn1cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEucGx1Z2luLm9yZ0lkfSA9ICR7b3JnSWR9IEFORCAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9ID0gdHJ1ZVxuICAgICAgICBHUk9VUCBCWSAke3NjaGVtYS5wbHVnaW4ucGx1Z2luVHlwZX0sICR7c2NoZW1hLnBsdWdpbi5jb21wdXRlVHlwZX1cbiAgICAgICAgT1JERVIgQlkgY291bnQgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFR5cGVDb21wdXRlRGlzdHJpYnV0aW9uPihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBWZXJzaW9uIGNvdW50cyBwZXIgcGx1Z2luIG5hbWUuXG4gICAqICBJTlRFTlRJT05BTExZIFNJTkdMRS1PUkcgKG5vIHJvbGx1cCk6IHBsdWdpbiBpbnZlbnRvcnkgaXMgcGVyLW9yZyAoc2VlXG4gICAqICBnZXRQbHVnaW5TdW1tYXJ5KS4gU2luZ2xlIGA9ICRvcmdgIHNjb3BlLiAqL1xuICBhc3luYyBnZXRQbHVnaW5WZXJzaW9ucyhvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxWZXJzaW9uQ291bnRbXT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLXZlcnNpb25zYCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICAke3NjaGVtYS5wbHVnaW4ubmFtZX0sXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB2ZXJzaW9uX2NvdW50LFxuICAgICAgICAgIC0tIEhpZ2hlc3QgdmVyc2lvbiBieSBOVU1FUklDIHNlbXZlciBjb3JlIChub3QgbGV4aWNhbDogJzEwLjAuMCcgPiAnOS4wLjAnKS5cbiAgICAgICAgICAtLSBTdHJpcCBhbnkgLXByZXJlbGVhc2UvK2J1aWxkIHN1ZmZpeCBiZWZvcmUgdGhlIGludFtdIGNhc3Qgc28gaXQgY2FuJ3RcbiAgICAgICAgICAtLSBlcnJvciBvbiB2YWxpZCBzZW12ZXI7IGtlZXAgdGhlIG9yaWdpbmFsIHN0cmluZyBmb3IgZGlzcGxheS5cbiAgICAgICAgICAtLSBHVUFSRDogYSBub24tbnVtZXJpYy1kb3R0ZWQgdmVyc2lvbiAoJ2xhdGVzdCcsICcnLCAndjEnKSB3b3VsZCBtYWtlIHRoZVxuICAgICAgICAgIC0tIDo6aW50W10gY2FzdCB0aHJvdyBhbmQgYmxvdyB1cCB0aGUgV0hPTEUgb3JnIHN1bW1hcnkuIE9ubHkgY2FzdCByb3dzXG4gICAgICAgICAgLS0gd2hvc2Ugc3RyaXBwZWQgY29yZSBtYXRjaGVzIGEgbnVtZXJpYy1kb3R0ZWQgc2hhcGU7IHNvcnQgZXZlcnl0aGluZ1xuICAgICAgICAgIC0tIGVsc2UgdG8gdGhlIGJvdHRvbSB2aWEgYSBzZW50aW5lbCBBUlJBWVstMV0gc28gdGhlIHJvdyBzdGlsbCBjb3VudHMuXG4gICAgICAgICAgKGFycmF5X2FnZygke3NjaGVtYS5wbHVnaW4udmVyc2lvbn1cbiAgICAgICAgICAgICBPUkRFUiBCWSBDQVNFXG4gICAgICAgICAgICAgICBXSEVOIHJlZ2V4cF9yZXBsYWNlKCR7c2NoZW1hLnBsdWdpbi52ZXJzaW9ufSwgJ1stK10uKiQnLCAnJykgfiAnXlswLTldKyhbLl1bMC05XSspKiQnXG4gICAgICAgICAgICAgICAgIFRIRU4gc3RyaW5nX3RvX2FycmF5KHJlZ2V4cF9yZXBsYWNlKCR7c2NoZW1hLnBsdWdpbi52ZXJzaW9ufSwgJ1stK10uKiQnLCAnJyksICcuJyk6OmludFtdXG4gICAgICAgICAgICAgICBFTFNFIEFSUkFZWy0xXVxuICAgICAgICAgICAgIEVORCBERVNDXG4gICAgICAgICAgKSlbMV0gQVMgbGF0ZXN0X3ZlcnNpb24sXG4gICAgICAgICAgYm9vbF9vcigke3NjaGVtYS5wbHVnaW4uaXNEZWZhdWx0fSkgQVMgaGFzX2RlZmF1bHRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLm5hbWV9XG4gICAgICAgIE9SREVSIEJZIHZlcnNpb25fY291bnQgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFZlcnNpb25Db3VudD4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgc3VjY2VzcyByYXRlIG92ZXIgdGltZS5cbiAgICpcbiAgICogU1RBVFVTIENBU0lORyBOT1RFOiBUaGlzIHF1ZXJ5IGZpbHRlcnMgYnkgYGV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnYFxuICAgKiBhbmQgdXNlcyBsb3dlcmNhc2Ugc3RhdHVzIHZhbHVlcyAoYCdjb21wbGV0ZWQnYCwgYCdmYWlsZWQnYCksIHdoaWxlXG4gICAqIGBnZXRTdWNjZXNzUmF0ZWAgKDEuMikgZmlsdGVycyBieSBgZXZlbnRfdHlwZSA9ICdQSVBFTElORSdgIHdpdGhcbiAgICogdXBwZXJjYXNlIEFXUy1zdHlsZSBzdGF0dXNlcyAoYCdTVUNDRUVERUQnYCwgYCdGQUlMRUQnYCwgYCdDQU5DRUxFRCdgKS5cbiAgICogVGhlIGNhc2luZyBkcmlmdCBpcyBpbnRlbnRpb25hbCBhbmQgdHJhY2tzIHRoZSBwcm9kdWNlcjpcbiAgICogICAtIGBwbHVnaW4tYnVpbGRgIGV2ZW50cyBjb21lIGZyb20gb3VyIG93biBidWlsZCBwaXBlbGluZSAobG93ZXJjYXNlKVxuICAgKiAgIC0gYFBJUEVMSU5FYCBldmVudHMgY29tZSBmcm9tIEFXUyBDb2RlUGlwZWxpbmUgKHVwcGVyY2FzZSlcbiAgICogVGhlIGluZ2VzdCBab2Qgc2NoZW1hIGF0IGFwaS9yZXBvcnRpbmcvc3JjL3JvdXRlcy9ldmVudC1pbmdlc3QudHNcbiAgICogU0hPVUxEIGVudW0gdGhlc2UgcGVyLWV2ZW50U291cmNlIHNvIHdlIGNhdGNoIGRyaWZ0IGF0IGluZ2VzdCByYXRoZXJcbiAgICogdGhhbiBzaWxlbnRseSBwcm9kdWNpbmcgemVybyByb3dzIGhlcmUuIFNlZSBmaW5kaW5ncyBONzEuXG4gICAqL1xuICBhc3luYyBnZXRCdWlsZFN1Y2Nlc3NSYXRlKG9yZ0lkOiBzdHJpbmcsIGludGVydmFsOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPEJ1aWxkVGltZVNlcmllc0VudHJ5W10+IHtcbiAgICBhc3NlcnRSZXBvcnRJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgLy8gQnVpbGQgYWN0aXZpdHkgcmVwb3J0IOKAlCByb2xsdXAtYXdhcmUgbGlrZSB0aGUgZXhlY3V0aW9uIHJlcG9ydHMuIFRoZXNlXG4gICAgLy8gcm93cyBhcmUgZ2F0ZWQgb24gdGhlIHBpcGVsaW5lX2V2ZW50IGBvcmdfaWRgIGRpcmVjdGx5IChubyBwaXBlbGluZSBqb2luKSxcbiAgICAvLyBzbyBgcHJlZGAgYXBwbGllcyB0byBgZS5vcmdfaWRgLlxuICAgIHJldHVybiByZXBvcnQ8QnVpbGRUaW1lU2VyaWVzRW50cnk+KGBidWlsZC1zdWNjZXNzOiR7aW50ZXJ2YWx9OiR7ZnJvbX06JHt0b31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBEQVRFX1RSVU5DKCR7aW50ZXJ2YWx9LCBlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIHBlcmlvZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2NvbXBsZXRlZCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnZmFpbGVkJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgc3VjY2Vzc19wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCdcbiAgICAgICAgICBBTkQgZS5zdGF0dXMgSU4gKCdjb21wbGV0ZWQnLCAnZmFpbGVkJylcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBCdWlsZCBkdXJhdGlvbiBwZXIgcGx1Z2luLiBCdWlsZCBhY3Rpdml0eSByZXBvcnQg4oCUIHJvbGx1cC1hd2FyZS4gKi9cbiAgYXN5bmMgZ2V0QnVpbGREdXJhdGlvbihvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxCdWlsZER1cmF0aW9uW10+IHtcbiAgICByZXR1cm4gcmVwb3J0PEJ1aWxkRHVyYXRpb24+KGBidWlsZC1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5kZXRhaWwtPj4ncGx1Z2luTmFtZScgQVMgcGx1Z2luX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGJ1aWxkc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgV0hFUkUgZS5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIHBsdWdpbl9uYW1lIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBCdWlsZCBmYWlsdXJlcyDigJQgdG9wIGVycm9yIG1lc3NhZ2VzLiBCdWlsZCBhY3Rpdml0eSByZXBvcnQg4oCUIHJvbGx1cC1hd2FyZS4gKi9cbiAgYXN5bmMgZ2V0QnVpbGRGYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIGxpbWl0OiBudW1iZXIgPSAyMCwgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPEJ1aWxkRmFpbHVyZVtdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxCdWlsZEZhaWx1cmU+KGBidWlsZC1mYWlsdXJlczoke2Zyb219OiR7dG99OiR7bGltaXR9YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5kZXRhaWwtPj4ncGx1Z2luTmFtZScgQVMgcGx1Z2luX25hbWUsXG4gICAgICAgICAgZS5lcnJvcl9tZXNzYWdlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgb2NjdXJyZW5jZXMsXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9zZWVuXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnIEFORCBlLnN0YXR1cyA9ICdmYWlsZWQnXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgcGx1Z2luX25hbWUsIGUuZXJyb3JfbWVzc2FnZVxuICAgICAgICBPUkRFUiBCWSBvY2N1cnJlbmNlcyBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9XG4gICAgICBgKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQbHVnaW4gcnVudGltZSB0ZWxlbWV0cnkg4oCUIHNlZSAuL3JlcG9ydGluZy9wbHVnaW4tcnVudGltZS50cyDilIDilIBcblxuICAvKipcbiAgICogUGx1Z2luIHJ1bnRpbWU6IHBlciBwbHVnaW4gdmVyc2lvbiBydW5zLCBzdWNjZXNzIHJhdGUgYW5kIHA1MC9wOTVcbiAgICogZHVyYXRpb24gb3ZlciBgW2Zyb20sIHRvXWAsIGZyb20gdGhlIG1hbmlmZXN0LWF0dHJpYnV0ZWQgQUNUSU9OIGV2ZW50cy5cbiAgICogUm9sbHVwLWF3YXJlLlxuICAgKi9cbiAgYXN5bmMgZ2V0UGx1Z2luUnVudGltZShvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIGZpbHRlcj86IFBsdWdpblJ1bnRpbWVGaWx0ZXIsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxQbHVnaW5SdW50aW1lU3RhdHNbXT4ge1xuICAgIHJldHVybiBwbHVnaW5SdW50aW1lKG9yZ0lkLCBmcm9tLCB0bywgZmlsdGVyLCBvcmdJZHMpO1xuICB9XG5cbiAgLyoqIENyb3NzLW9yZyAzMC1kYXkgcnVudGltZSBhZ2dyZWdhdGUgZm9yIGEgYChwdWJsaXNoZXIsIG5hbWUpYCBsaXN0aW5nIChwbHVnaW5fc3RhdHMgaW5wdXQpLiBTZXJ2aWNlIGNhbGxlcnMgb25seS4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luUnVudGltZUFnZ3JlZ2F0ZShwdWJsaXNoZXI6IHN0cmluZywgbmFtZTogc3RyaW5nKTogUHJvbWlzZTxQbHVnaW5SdW50aW1lQWdncmVnYXRlPiB7XG4gICAgcmV0dXJuIHBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUocHVibGlzaGVyLCBuYW1lKTtcbiAgfVxuXG4gIC8qKiBSZXZpZXcgXCJ2ZXJpZmllZCB1c2VcIjogYG9yZ0lkYCByYW4gYChwdWJsaXNoZXIsIG5hbWUpYCBzdWNjZXNzZnVsbHkgd2l0aGluIDkwIGRheXMuIFNlcnZpY2UgY2FsbGVycyBvbmx5LiAqL1xuICBhc3luYyBoYXNWZXJpZmllZFBsdWdpblVzZShvcmdJZDogc3RyaW5nLCBwdWJsaXNoZXI6IHN0cmluZywgbmFtZTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHZlcmlmaWVkUGx1Z2luVXNlKG9yZ0lkLCBwdWJsaXNoZXIsIG5hbWUpO1xuICB9XG5cbiAgLy8g4pSA4pSAIENhdGVnb3J5IDM6IERPUkEgd3JpdGUgcGF0aHMgKHBvc3QtZGVwbG95IG91dGNvbWVzICsgaW5nZXN0IGhlYWx0aCkg4pSA4pSAXG5cbiAgLyoqXG4gICAqIFJlY29yZCBhIG1hbnVhbCBwb3N0LWRlcGxveSBvdXRjb21lIG1hcmtlcjogYSB1c2VyIG1hcmtzIGFcbiAgICogZGVwbG95bWVudCBgZmFpbGVkYCAoYSBwcm9kdWN0aW9uIGluY2lkZW50IGxpbmtlZCB0byB0aGUgZGVwbG95KSBvclxuICAgKiBgcmVzdG9yZWRgIChyZWNvdmVyZWQpLiBJZGVtcG90ZW50IOKAlCBrZXllZCBvbiAoZXhlY3V0aW9uX2lkLCBvdXRjb21lKSBzbyBhXG4gICAqIGR1cGxpY2F0ZSBQT1NUIHJlZnJlc2hlcyBgYXRgIHJhdGhlciB0aGFuIGRvdWJsZS1jb3VudGluZywgd2hpbGUgYVxuICAgKiBmYWlsZWTihpJyZXN0b3JlZCBwYWlyIHN0YXlzIHR3byByb3dzLiBGZWVkcyB0aGUgcG9zdC1kZXBsb3kgQ0ZSIGNvbXBvbmVudCBhbmRcbiAgICogdGhlIHJlYWwgTVRUUi4gUnVucyB1bmRlciB0aGUgY2FsbGVyJ3Mgb3JnIGNvbnRleHQgKFJMUyBXSVRIIENIRUNLKS5cbiAgICovXG4gIGFzeW5jIHJlY29yZERlcGxveW1lbnRPdXRjb21lKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgZXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICBpbnB1dDogeyBvdXRjb21lOiAnZmFpbGVkJyB8ICdyZXN0b3JlZCc7IGF0OiBzdHJpbmc7IGVudmlyb25tZW50Pzogc3RyaW5nIH0sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbjogZmFsc2UgfSwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4Lmluc2VydChzY2hlbWEuZGVwbG95bWVudE91dGNvbWUpLnZhbHVlcyh7XG4gICAgICAgIGV4ZWN1dGlvbklkLFxuICAgICAgICBvcmdJZCxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHNjcnViT3B0aW9uYWwoaW5wdXQuZW52aXJvbm1lbnQpLFxuICAgICAgICBvdXRjb21lOiBpbnB1dC5vdXRjb21lLFxuICAgICAgICBhdDogbmV3IERhdGUoaW5wdXQuYXQpLFxuICAgICAgfSkub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgdGFyZ2V0OiBbc2NoZW1hLmRlcGxveW1lbnRPdXRjb21lLmV4ZWN1dGlvbklkLCBzY2hlbWEuZGVwbG95bWVudE91dGNvbWUub3V0Y29tZV0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIGF0OiBuZXcgRGF0ZShpbnB1dC5hdCksXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHNjcnViT3B0aW9uYWwoaW5wdXQuZW52aXJvbm1lbnQpID8/IG51bGwsXG4gICAgICAgIH0sXG4gICAgICB9KSksXG4gICAgKTtcbiAgICAvLyBPdXRjb21lIGNoYW5nZXMgdGhlIERPUkEgYWdncmVnYXRlIOKAlCBkcm9wIHRoZSBvcmcncyBjYWNoZWQgcmVwb3J0cy5cbiAgICBhd2FpdCB0aGlzLmludmFsaWRhdGVPcmcob3JnSWQpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmdlc3QgYSBwcm9kdWN0aW9uIGluY2lkZW50IGZyb20gdGhlIG9yZydzIGluY2lkZW50IHRvb2xpbmdcbiAgICogKFBhZ2VyRHV0eSAvIERhdGFkb2cgLyBBbGVydG1hbmFnZXIgd2ViaG9vaykuIElkZW1wb3RlbnQg4oCUIGtleWVkIG9uXG4gICAqIChvcmdfaWQsIGluY2lkZW50X2lkKSBzbyBhIGxhdGVyIHJlc29sdmUgcmUtcG9zdCB1cHNlcnRzIGByZXNvbHZlZF9hdGBcbiAgICogKGFuZCByZWZyZXNoZXMgdGhlIG90aGVyIG11dGFibGUgZmllbGRzKSBpbnN0ZWFkIG9mIGluc2VydGluZyBhIGR1cGxpY2F0ZS5cbiAgICogRE9SQSBjb3JyZWxhdGVzIGVhY2ggaW5jaWRlbnQgdG8gdGhlIG1vc3QgcmVjZW50IHN1Y2Nlc3NmdWwgZGVwbG95IHRvIGl0c1xuICAgKiBgZW52aXJvbm1lbnRgLCBwcm9kdWNpbmcgYW4gYXV0b21hdGVkIHBvc3QtZGVwbG95IGZhaWx1cmUgKyBhIHJlYWwgTVRUUi5cbiAgICogUnVucyB1bmRlciB0aGUgY2FsbGVyJ3Mgb3JnIGNvbnRleHQgKFJMUyBXSVRIIENIRUNLKTsgZnJlZS1mb3JtIGZpZWxkcyBhcmVcbiAgICogQVdTLWlkIHNjcnViYmVkIGF0IHRoaXMgcGVyc2lzdGVuY2UgYm91bmRhcnkgbGlrZSB0aGUgb3RoZXIgaW5nZXN0IHBhdGhzLlxuICAgKi9cbiAgYXN5bmMgcmVjb3JkSW5jaWRlbnQob3JnSWQ6IHN0cmluZywgaW5wdXQ6IEluY2lkZW50SW5wdXQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpbmNpZGVudElkID0gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcoaW5wdXQuaW5jaWRlbnRJZCk7XG4gICAgY29uc3QgZW52aXJvbm1lbnQgPSBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyhpbnB1dC5lbnZpcm9ubWVudCk7XG4gICAgY29uc3Qgc2V2ZXJpdHkgPSBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyhpbnB1dC5zZXZlcml0eSk7XG4gICAgY29uc3Qgb3BlbmVkQXQgPSBuZXcgRGF0ZShpbnB1dC5vcGVuZWRBdCk7XG4gICAgY29uc3QgcmVzb2x2ZWRBdCA9IGlucHV0LnJlc29sdmVkQXQgPyBuZXcgRGF0ZShpbnB1dC5yZXNvbHZlZEF0KSA6IG51bGw7XG4gICAgYXdhaXQgcnVuV2l0aFRlbmFudENvbnRleHQoeyBvcmdJZCwgaXNTdXBlckFkbWluOiBmYWxzZSB9LCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguaW5zZXJ0KHNjaGVtYS5pbmNpZGVudCkudmFsdWVzKHtcbiAgICAgICAgaW5jaWRlbnRJZCxcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGVudmlyb25tZW50LFxuICAgICAgICBvcGVuZWRBdCxcbiAgICAgICAgcmVzb2x2ZWRBdCxcbiAgICAgICAgc2V2ZXJpdHksXG4gICAgICB9KS5vbkNvbmZsaWN0RG9VcGRhdGUoe1xuICAgICAgICB0YXJnZXQ6IFtzY2hlbWEuaW5jaWRlbnQub3JnSWQsIHNjaGVtYS5pbmNpZGVudC5pbmNpZGVudElkXSxcbiAgICAgICAgLy8gQSByZWRlbGl2ZXJlZCBGSVJJTkcgcG9zdCAobm8gcmVzb2x2ZWRBdCkgbXVzdCBub3Qgd2lwZSBhIHJlY29yZGVkXG4gICAgICAgIC8vIHJlc29sdmUg4oCUIHNlbmRlcnMgcmUtcG9zdCBmaXJpbmcgYWxlcnRzIG9uIGV2ZXJ5IHJlcGVhdCBpbnRlcnZhbCwgYW5kXG4gICAgICAgIC8vIGRlbGl2ZXJ5IG9yZGVyIGlzbid0IGd1YXJhbnRlZWQuIEtlZXAgdGhlIHN0b3JlZCByZXNvbHZlIHVubGVzcyB0aGVcbiAgICAgICAgLy8gcG9zdCBjYXJyaWVzIGl0cyBvd24sIG9yIHRoZSBpbmNpZGVudCB3YXMgUkUtT1BFTkVEIChhIGRpZmZlcmVudFxuICAgICAgICAvLyBvcGVuZWRBdCBtZWFucyBhIG5ldyBvY2N1cnJlbmNlLCB3aG9zZSByZXNvbHZlIHN0YXRlIGlzIHRoZSBwb3N0J3MpLlxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICBlbnZpcm9ubWVudCxcbiAgICAgICAgICBvcGVuZWRBdCxcbiAgICAgICAgICByZXNvbHZlZEF0OiBzcWxgQ0FTRSBXSEVOICR7c2NoZW1hLmluY2lkZW50Lm9wZW5lZEF0fSA9IGV4Y2x1ZGVkLm9wZW5lZF9hdFxuICAgICAgICAgICAgVEhFTiBDT0FMRVNDRShleGNsdWRlZC5yZXNvbHZlZF9hdCwgJHtzY2hlbWEuaW5jaWRlbnQucmVzb2x2ZWRBdH0pXG4gICAgICAgICAgICBFTFNFIGV4Y2x1ZGVkLnJlc29sdmVkX2F0IEVORGAsXG4gICAgICAgICAgc2V2ZXJpdHksXG4gICAgICAgIH0sXG4gICAgICB9KSksXG4gICAgKTtcbiAgICAvLyBBIG5ldy91cGRhdGVkIGluY2lkZW50IGNoYW5nZXMgdGhlIERPUkEgYWdncmVnYXRlIOKAlCBkcm9wIGNhY2hlZCByZXBvcnRzLlxuICAgIGF3YWl0IHRoaXMuaW52YWxpZGF0ZU9yZyhvcmdJZCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgdGhlIHBlci1vcmcgRE9SQSBzZXR0aW5ncy4gUmV0dXJucyB0aGUgc3RvcmVkXG4gICAqIGBpbmNpZGVudFdpbmRvd0hvdXJzYCBvdmVycmlkZSAob3IgYG51bGxgIHdoZW4gdW5zZXQpIHBsdXMgdGhlIGdsb2JhbCBlbnZcbiAgICogZGVmYXVsdCwgc28gdGhlIHNldHRpbmdzIFVJIGNhbiBzaG93IGJvdGguIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIHRlbmFudFxuICAgKiBjb250ZXh0IChSTFMtc2NvcGVkKTsgYSBzaW5nbGUtb3JnIHJlYWQuXG4gICAqL1xuICBhc3luYyBnZXRSZXBvcnRpbmdTZXR0aW5ncyhvcmdJZDogc3RyaW5nLCByZXRlbnRpb25PcmdJZDogc3RyaW5nID0gb3JnSWQpOiBQcm9taXNlPFJlcG9ydGluZ1NldHRpbmdzPiB7XG4gICAgY29uc3Qgcm93cyA9IGRyaXp6bGVSb3dzPHtcbiAgICAgIGluY2lkZW50X3dpbmRvd19ob3VyczogbnVtYmVyIHwgbnVsbDtcbiAgICAgIGV2ZW50X3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgZG9yYV9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVCAke3NjaGVtYS5kb3JhU2V0dGluZ3MuaW5jaWRlbnRXaW5kb3dIb3Vyc30gQVMgaW5jaWRlbnRfd2luZG93X2hvdXJzLFxuICAgICAgICAgICAgICAgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmV2ZW50UmV0ZW50aW9uRGF5c30gQVMgZXZlbnRfcmV0ZW50aW9uX2RheXMsXG4gICAgICAgICAgICAgICAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZG9yYVJldGVudGlvbkRheXN9IEFTIGRvcmFfcmV0ZW50aW9uX2RheXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5kb3JhU2V0dGluZ3N9XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5vcmdJZH0gPSAke29yZ0lkfVxuICAgICAgICBMSU1JVCAxXG4gICAgICBgKSkpLnJvd3MpO1xuICAgIGNvbnN0IHJvdyA9IHJvd3NbMF07XG4gICAgLy8gUmV0ZW50aW9uIGlzIGEgYmlsbGluZyBlbnRpdGxlbWVudCBzeW5jZWQgb250byB0aGUgYWNjb3VudCBST09UIG9ubHk7IGFcbiAgICAvLyB0ZWFtIHJlYWRzIGl0cyByb290J3Mgd2luZG93ICh0aGUgaW5jaWRlbnQgd2luZG93IHN0YXlzIHRoZSB0ZWFtJ3Mgb3duKS5cbiAgICBjb25zdCByZXRlbnRpb24gPSByZXRlbnRpb25PcmdJZCA9PT0gb3JnSWRcbiAgICAgID8gcm93XG4gICAgICA6IGF3YWl0IHRoaXMuI3JlYWRSZXRlbnRpb25PdmVycmlkZShyZXRlbnRpb25PcmdJZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluY2lkZW50V2luZG93SG91cnM6IHJvdz8uaW5jaWRlbnRfd2luZG93X2hvdXJzICE9IG51bGwgPyBOdW1iZXIocm93LmluY2lkZW50X3dpbmRvd19ob3VycykgOiBudWxsLFxuICAgICAgZGVmYXVsdFdpbmRvd0hvdXJzOiBET1JBX0lOQ0lERU5UX1dJTkRPV19IT1VSUyxcbiAgICAgIGV2ZW50UmV0ZW50aW9uRGF5czogcmV0ZW50aW9uPy5ldmVudF9yZXRlbnRpb25fZGF5cyAhPSBudWxsID8gTnVtYmVyKHJldGVudGlvbi5ldmVudF9yZXRlbnRpb25fZGF5cykgOiBudWxsLFxuICAgICAgZG9yYVJldGVudGlvbkRheXM6IHJldGVudGlvbj8uZG9yYV9yZXRlbnRpb25fZGF5cyAhPSBudWxsID8gTnVtYmVyKHJldGVudGlvbi5kb3JhX3JldGVudGlvbl9kYXlzKSA6IG51bGwsXG4gICAgICBkZWZhdWx0RXZlbnRSZXRlbnRpb25EYXlzOiBSRVBPUlRJTkdfRVZFTlRfUkVURU5USU9OX0RBWVMsXG4gICAgICBkZWZhdWx0RG9yYVJldGVudGlvbkRheXM6IFJFUE9SVElOR19ET1JBX1JFVEVOVElPTl9EQVlTLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIFJPT1Qgb3JnJ3Mgc3RvcmVkIHJldGVudGlvbiBvdmVycmlkZS4gVGhlIGNhbGxlciAoYSB0ZWFtKSBjYW4ndCBzZWUgdGhlXG4gICAqIHJvb3QncyBgZG9yYV9zZXR0aW5nc2Agcm93IHVuZGVyIGl0cyBvd24gUkxTIHNjb3BlLCBzbyB0aGlzIG5hcnJvdyByZWFkIG9mXG4gICAqIHR3byBpbnRlZ2VyIGNvbHVtbnMg4oCUIGtleWVkIGJ5IHRoZSBleHBsaWNpdCwgSldULWRlcml2ZWQgcm9vdCBpZCDigJQgcnVucyBpbiBhXG4gICAqIHN5c2FkbWluIHNjb3BlLlxuICAgKi9cbiAgYXN5bmMgI3JlYWRSZXRlbnRpb25PdmVycmlkZShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx7IGV2ZW50X3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsOyBkb3JhX3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsIH0gfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgYXN5bmMgKCkgPT4gZHJpenpsZVJvd3M8e1xuICAgICAgZXZlbnRfcmV0ZW50aW9uX2RheXM6IG51bWJlciB8IG51bGw7XG4gICAgICBkb3JhX3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgIH0+KChhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5ldmVudFJldGVudGlvbkRheXN9IEFTIGV2ZW50X3JldGVudGlvbl9kYXlzLFxuICAgICAgICAgICAgICAgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmRvcmFSZXRlbnRpb25EYXlzfSBBUyBkb3JhX3JldGVudGlvbl9kYXlzXG4gICAgICAgIEZST00gJHtzY2hlbWEuZG9yYVNldHRpbmdzfVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5kb3JhU2V0dGluZ3Mub3JnSWR9ID0gJHtvcmdJZH1cbiAgICAgICAgTElNSVQgMVxuICAgICAgYCkpKS5yb3dzKSk7XG4gICAgcmV0dXJuIHJvd3NbMF07XG4gIH1cblxuICAvKipcbiAgICogVXBzZXJ0IHBlci1vcmcgcmVwb3J0aW5nIHNldHRpbmdzIChpbmNpZGVudCB3aW5kb3cgK1xuICAgKiByZXRlbnRpb24gb3ZlcnJpZGVzKSwgaWRlbXBvdGVudCBvbiBgb3JnX2lkYC4gQSBwYXJ0aWFsIHdyaXRlIOKAlCBvbmx5IHRoZVxuICAgKiBmaWVsZHMgcHJlc2VudCBpbiBgcGF0Y2hgIGFyZSBzZXQgKHNvIHVwZGF0aW5nIHJldGVudGlvbiBuZXZlciBjbGVhcnMgdGhlXG4gICAqIGluY2lkZW50IHdpbmRvdywgYW5kIHZpY2UtdmVyc2EpLiBTZXQgc2VsZi1zZXJ2ZSBieSBhbiBvcmcgYWRtaW4gdmlhXG4gICAqIGBQVVQgL2FwaS9yZXBvcnRzL3NldHRpbmdzL2luY2lkZW50c2AuIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIG9yZyBjb250ZXh0XG4gICAqIChSTFMgV0lUSCBDSEVDSyk7IGEgY2hhbmdlZCB2YWx1ZSBhZmZlY3RzIERPUkEgYWdncmVnYXRlcyBzbyB0aGUgb3JnJ3NcbiAgICogY2FjaGVkIHJlcG9ydHMgYXJlIGRyb3BwZWQuXG4gICAqL1xuICBhc3luYyBzZXRSZXBvcnRpbmdTZXR0aW5ncyhvcmdJZDogc3RyaW5nLCBwYXRjaDogUmVwb3J0aW5nU2V0dGluZ3NQYXRjaCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNldDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7IHVwZGF0ZWRBdDogbmV3IERhdGUoKSB9O1xuICAgIGlmIChwYXRjaC5pbmNpZGVudFdpbmRvd0hvdXJzICE9PSB1bmRlZmluZWQpIHNldC5pbmNpZGVudFdpbmRvd0hvdXJzID0gcGF0Y2guaW5jaWRlbnRXaW5kb3dIb3VycztcbiAgICBpZiAocGF0Y2guZXZlbnRSZXRlbnRpb25EYXlzICE9PSB1bmRlZmluZWQpIHNldC5ldmVudFJldGVudGlvbkRheXMgPSBwYXRjaC5ldmVudFJldGVudGlvbkRheXM7XG4gICAgaWYgKHBhdGNoLmRvcmFSZXRlbnRpb25EYXlzICE9PSB1bmRlZmluZWQpIHNldC5kb3JhUmV0ZW50aW9uRGF5cyA9IHBhdGNoLmRvcmFSZXRlbnRpb25EYXlzO1xuICAgIGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbjogZmFsc2UgfSwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4Lmluc2VydChzY2hlbWEuZG9yYVNldHRpbmdzKS52YWx1ZXMoe1xuICAgICAgICBvcmdJZCxcbiAgICAgICAgaW5jaWRlbnRXaW5kb3dIb3VyczogcGF0Y2guaW5jaWRlbnRXaW5kb3dIb3VycyxcbiAgICAgICAgZXZlbnRSZXRlbnRpb25EYXlzOiBwYXRjaC5ldmVudFJldGVudGlvbkRheXMsXG4gICAgICAgIGRvcmFSZXRlbnRpb25EYXlzOiBwYXRjaC5kb3JhUmV0ZW50aW9uRGF5cyxcbiAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgfSkub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgdGFyZ2V0OiBzY2hlbWEuZG9yYVNldHRpbmdzLm9yZ0lkLFxuICAgICAgICBzZXQsXG4gICAgICB9KSksXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLmludmFsaWRhdGVPcmcob3JnSWQpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IHJlY2VudCBpbmNpZGVudHMgZm9yIGFuIG9yZyAob3JnLWFkbWluIHN1cmZhY2UpLCBuZXdlc3QgZmlyc3QsXG4gICAqIHBhZ2luYXRlZC4gRWFjaCByb3cgY2FycmllcyBpdHMgcmVzb2x2ZWQgc3RhdGUgYW5kIGl0cyBkZXBsb3kgY29ycmVsYXRpb24g4oCUXG4gICAqIHRoZSBtb3N0IHJlY2VudCBTVUNDRVNTRlVMIGRlcGxveSB0byB0aGUgaW5jaWRlbnQncyBgZW52aXJvbm1lbnRgIHdob3NlXG4gICAqIGBjb21wbGV0ZWRfYXRgIGZhbGxzIHdpdGhpbiB0aGUgZWZmZWN0aXZlIHBlci1vcmcgY29ycmVsYXRpb24gd2luZG93IGJlZm9yZVxuICAgKiBgb3BlbmVkX2F0YCAodGhlIHNhbWUgcnVsZSBET1JBJ3MgQ0ZSL01UVFIgY29ycmVsYXRpb24gYXBwbGllcykuIFNpbmdsZS1vcmdcbiAgICogKG5vIHJvbGx1cCkg4oCUIGFuIG9yZyBhZG1pbiB2aWV3cyB0aGVpciBvd24gb3JnJ3MgaW5jaWRlbnRzLiBSTFMtc2NvcGVkIHZpYVxuICAgKiB0aGUgYHAub3JnX2lkYC9gaS5vcmdfaWRgIHByZWRpY2F0ZXMgKyB0aGUgdGVuYW50IGNvbnRleHQuXG4gICAqL1xuICBhc3luYyBsaXN0SW5jaWRlbnRzKG9yZ0lkOiBzdHJpbmcsIG9wdHM6IHsgbGltaXQ6IG51bWJlcjsgb2Zmc2V0OiBudW1iZXIgfSk6IFByb21pc2U8SW5jaWRlbnRMaXN0SXRlbVtdPiB7XG4gICAgY29uc3QgeyBpbmNpZGVudFdpbmRvd0hvdXJzIH0gPSBhd2FpdCB0aGlzLmdldFJlcG9ydGluZ1NldHRpbmdzKG9yZ0lkKTtcbiAgICBjb25zdCB3aW5kb3dIb3VycyA9IHJlc29sdmVJbmNpZGVudFdpbmRvd0hvdXJzKGluY2lkZW50V2luZG93SG91cnMpO1xuICAgIGNvbnN0IGxpbWl0ID0gTWF0aC5tYXgoMSwgTWF0aC5taW4ob3B0cy5saW1pdCwgMjAwKSk7XG4gICAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5tYXgoMCwgb3B0cy5vZmZzZXQpO1xuICAgIC8vIFRoZSBjb3JyZWxhdGlvbiB3aW5kb3cgaXMgZXhwcmVzc2VkIGluIFNFQ09ORFMgYXMgYSBkb3VibGUsIG5vdCBhc1xuICAgIC8vIGBtYWtlX2ludGVydmFsKGhvdXJzID0+IE46OmludClgLiBUaGUgd2luZG93IGlzIHZhbGlkYXRlZCBhcyBhbnkgcG9zaXRpdmVcbiAgICAvLyBudW1iZXIgKDAuNWggaXMgbGVnYWwpIGFuZCB0aGUgaW4tbWVtb3J5IERPUkEgY29ycmVsYXRpb24gdXNlcyBpdCBleGFjdGx5O1xuICAgIC8vIHRoZSBpbnQgY2FzdCBtYWRlIFBvc3RncmVzIHJlamVjdCBhIGZyYWN0aW9uYWwgdmFsdWUsIHNvIGEgMC41aCB3aW5kb3dcbiAgICAvLyByZXR1cm5lZCA1MDAgZnJvbSB0aGlzIGVuZHBvaW50IGFuZCBmcm9tIHRoZSBjb3JyZWxhdGlvbiBsb29rdXAgYmVsb3cuXG4gICAgcmV0dXJuIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBpLmluY2lkZW50X2lkIEFTIFwiaW5jaWRlbnRJZFwiLFxuICAgICAgICAgIGkuZW52aXJvbm1lbnQgQVMgZW52aXJvbm1lbnQsXG4gICAgICAgICAgaS5zZXZlcml0eSBBUyBzZXZlcml0eSxcbiAgICAgICAgICBpLm9wZW5lZF9hdDo6dGV4dCBBUyBcIm9wZW5lZEF0XCIsXG4gICAgICAgICAgaS5yZXNvbHZlZF9hdDo6dGV4dCBBUyBcInJlc29sdmVkQXRcIixcbiAgICAgICAgICBpLmNyZWF0ZWRfYXQ6OnRleHQgQVMgXCJjcmVhdGVkQXRcIixcbiAgICAgICAgICAoaS5yZXNvbHZlZF9hdCBJUyBOT1QgTlVMTCkgQVMgcmVzb2x2ZWQsXG4gICAgICAgICAgY29yci5leGVjdXRpb25faWQgQVMgXCJjb3JyZWxhdGVkRXhlY3V0aW9uSWRcIixcbiAgICAgICAgICBjb3JyLmNvbXBsZXRlZF9hdDo6dGV4dCBBUyBcImRlcGxveUNvbXBsZXRlZEF0XCJcbiAgICAgICAgRlJPTSAke3NjaGVtYS5pbmNpZGVudH0gaVxuICAgICAgICBMRUZUIEpPSU4gTEFURVJBTCAoXG4gICAgICAgICAgU0VMRUNUIGUuZXhlY3V0aW9uX2lkLCBlLmNvbXBsZXRlZF9hdFxuICAgICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnXG4gICAgICAgICAgICBBTkQgZS5lbnZpcm9ubWVudCA9IGkuZW52aXJvbm1lbnQgQU5EIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCdcbiAgICAgICAgICAgIEFORCBlLmNvbXBsZXRlZF9hdCA8PSBpLm9wZW5lZF9hdFxuICAgICAgICAgICAgQU5EIGUuY29tcGxldGVkX2F0ID49IGkub3BlbmVkX2F0IC0gbWFrZV9pbnRlcnZhbChzZWNzID0+ICR7d2luZG93SG91cnMgKiAzNjAwfTo6ZG91YmxlIHByZWNpc2lvbilcbiAgICAgICAgICBPUkRFUiBCWSBlLmNvbXBsZXRlZF9hdCBERVNDXG4gICAgICAgICAgTElNSVQgMVxuICAgICAgICApIGNvcnIgT04gdHJ1ZVxuICAgICAgICBXSEVSRSBpLm9yZ19pZCA9ICR7b3JnSWR9XG4gICAgICAgIE9SREVSIEJZIGkub3BlbmVkX2F0IERFU0NcbiAgICAgICAgTElNSVQgJHtsaW1pdH0gT0ZGU0VUICR7b2Zmc2V0fVxuICAgICAgYCkudGhlbigocikgPT4gZHJpenpsZVJvd3M8SW5jaWRlbnRMaXN0SXRlbT4oci5yb3dzKS5tYXAoKHJvdykgPT4gKHtcbiAgICAgIC4uLnJvdyxcbiAgICAgIHJlc29sdmVkOiByb3cucmVzb2x2ZWQgPT09IHRydWUgfHwgKHJvdy5yZXNvbHZlZCBhcyB1bmtub3duKSA9PT0gJ3QnLFxuICAgICAgY29ycmVsYXRlZEV4ZWN1dGlvbklkOiByb3cuY29ycmVsYXRlZEV4ZWN1dGlvbklkID8/IG51bGwsXG4gICAgICBkZXBsb3lDb21wbGV0ZWRBdDogcm93LmRlcGxveUNvbXBsZXRlZEF0ID8/IG51bGwsXG4gICAgfSkpKSk7XG4gIH1cblxuICAvKipcbiAgICogV2lyaW5nLXRlc3QgZHJ5LXJ1bjogd291bGQgYSBzeW50aGV0aWMgaW5jaWRlbnQgb3BlbmluZyBOT1cgZm9yXG4gICAqIGBlbnZpcm9ubWVudGAgY29ycmVsYXRlIHRvIGEgcmVjZW50IHN1Y2Nlc3NmdWwgZGVwbG95IHVuZGVyIHRoZSBvcmcnc1xuICAgKiBlZmZlY3RpdmUgd2luZG93PyBUaGlzIGlzIGEgTk9OLXBlcnNpc3RpbmcgY29ycmVsYXRpb24gY2hlY2sg4oCUIGl0IHZlcmlmaWVzXG4gICAqIHRoZSBhZG1pbidzIGVudmlyb25tZW50IG5hbWluZyArIHdpbmRvdyBsaW5lIHVwIHdpdGggcmVhbCBkZXBsb3kgZXZlbnRzXG4gICAqIFdJVEhPVVQgd3JpdGluZyBhbiBpbmNpZGVudCAoc28gYSBcInRlc3RcIiBuZXZlciBwb2xsdXRlcyBDRlIvTVRUUikuIFJMUy1zY29wZWQuXG4gICAqL1xuICBhc3luYyB0ZXN0SW5jaWRlbnRDb3JyZWxhdGlvbihvcmdJZDogc3RyaW5nLCBlbnZpcm9ubWVudDogc3RyaW5nKTogUHJvbWlzZTxJbmNpZGVudFRlc3RSZXN1bHQ+IHtcbiAgICBjb25zdCBlbnYgPSBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyhlbnZpcm9ubWVudCk7XG4gICAgY29uc3Qgb3BlbmVkQXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgY29uc3QgeyBpbmNpZGVudFdpbmRvd0hvdXJzIH0gPSBhd2FpdCB0aGlzLmdldFJlcG9ydGluZ1NldHRpbmdzKG9yZ0lkKTtcbiAgICBjb25zdCB3aW5kb3dIb3VycyA9IHJlc29sdmVJbmNpZGVudFdpbmRvd0hvdXJzKGluY2lkZW50V2luZG93SG91cnMpO1xuICAgIGNvbnN0IHJvd3MgPSBkcml6emxlUm93czx7IGV4ZWN1dGlvbl9pZDogc3RyaW5nIHwgbnVsbDsgY29tcGxldGVkX2F0OiBzdHJpbmcgfCBudWxsIH0+KChhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUIGUuZXhlY3V0aW9uX2lkIEFTIGV4ZWN1dGlvbl9pZCwgZS5jb21wbGV0ZWRfYXQ6OnRleHQgQVMgY29tcGxldGVkX2F0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdTVEFHRSdcbiAgICAgICAgICBBTkQgZS5lbnZpcm9ubWVudCA9ICR7ZW52fSBBTkQgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJ1xuICAgICAgICAgIEFORCBlLmNvbXBsZXRlZF9hdCA8PSAke29wZW5lZEF0fTo6dGltZXN0YW1wdHpcbiAgICAgICAgICBBTkQgZS5jb21wbGV0ZWRfYXQgPj0gJHtvcGVuZWRBdH06OnRpbWVzdGFtcHR6IC0gbWFrZV9pbnRlcnZhbChzZWNzID0+ICR7d2luZG93SG91cnMgKiAzNjAwfTo6ZG91YmxlIHByZWNpc2lvbilcbiAgICAgICAgT1JERVIgQlkgZS5jb21wbGV0ZWRfYXQgREVTQ1xuICAgICAgICBMSU1JVCAxXG4gICAgICBgKSkpLnJvd3MpO1xuICAgIGNvbnN0IGhpdCA9IHJvd3NbMF07XG4gICAgcmV0dXJuIHtcbiAgICAgIGVudmlyb25tZW50OiBlbnYsXG4gICAgICBvcGVuZWRBdCxcbiAgICAgIHdpbmRvd0hvdXJzLFxuICAgICAgY29ycmVsYXRlZDogaGl0Py5leGVjdXRpb25faWQgIT0gbnVsbCxcbiAgICAgIGV4ZWN1dGlvbklkOiBoaXQ/LmV4ZWN1dGlvbl9pZCA/PyBudWxsLFxuICAgICAgZGVwbG95Q29tcGxldGVkQXQ6IGhpdD8uY29tcGxldGVkX2F0ID8/IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcHNlcnQgcGVyLW9yZyBpbmdlc3Rpb24gaGVhbHRoOiB0aGUgQVdTIGV2ZW50cyBMYW1iZGEgcGVyaW9kaWNhbGx5XG4gICAqIHJlcG9ydHMgZm9yd2FyZGVkL2Ryb3BwZWQgY291bnRlcnMgKyB0aGUgbGFzdCBldmVudCB0aW1lc3RhbXAgc28gdGhlIFJlcG9ydHNcbiAgICogVUkgY2FuIHNob3cgZmxvd2luZyAvIHN0YWxlIC8gZHJvcHBpbmcuIE9uZSByb3cgcGVyIG9yZyAodXBzZXJ0IG9uIG9yZ19pZCkuXG4gICAqL1xuICBhc3luYyByZWNvcmRJbmdlc3RIZWFsdGgoXG4gICAgb3JnSWQ6IHN0cmluZyxcbiAgICBpbnB1dDogeyBmb3J3YXJkZWQ/OiBudW1iZXI7IGRyb3BwZWQ/OiBudW1iZXI7IGxhc3RFdmVudEF0Pzogc3RyaW5nIH0sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGxhc3RFdmVudEF0ID0gaW5wdXQubGFzdEV2ZW50QXQgPyBuZXcgRGF0ZShpbnB1dC5sYXN0RXZlbnRBdCkgOiB1bmRlZmluZWQ7XG4gICAgYXdhaXQgcnVuV2l0aFRlbmFudENvbnRleHQoeyBvcmdJZCwgaXNTdXBlckFkbWluOiBmYWxzZSB9LCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguaW5zZXJ0KHNjaGVtYS5pbmdlc3RIZWFsdGgpLnZhbHVlcyh7XG4gICAgICAgIG9yZ0lkLFxuICAgICAgICBmb3J3YXJkZWQ6IGlucHV0LmZvcndhcmRlZCxcbiAgICAgICAgZHJvcHBlZDogaW5wdXQuZHJvcHBlZCxcbiAgICAgICAgbGFzdEV2ZW50QXQsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogc2NoZW1hLmluZ2VzdEhlYWx0aC5vcmdJZCxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgZm9yd2FyZGVkOiBpbnB1dC5mb3J3YXJkZWQsXG4gICAgICAgICAgZHJvcHBlZDogaW5wdXQuZHJvcHBlZCxcbiAgICAgICAgICBsYXN0RXZlbnRBdCxcbiAgICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIH0sXG4gICAgICB9KSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIGJhY2sgb25lIG9yZydzIGluZ2VzdGlvbiBoZWFsdGggZm9yIHRoZSBSZXBvcnRzIFVJIGZyZXNobmVzc1xuICAgKiBpbmRpY2F0b3IuIFJldHVybnMgYG51bGxgIHdoZW4gdGhlIG9yZyBoYXMgTk8gcm93IOKAlCBpLmUuIHRoZSBkZXBsb3ltZW50IGhhc1xuICAgKiBuZXZlciBpbmdlc3RlZCBhbnl0aGluZyDigJQgd2hpY2ggdGhlIFVJIG11c3QgcmVuZGVyIGFzIFwibm8gaW5nZXN0IHJlcG9ydGVkXG4gICAqIHlldFwiLCBuZXZlciBhcyBcInN0YWxlXCIuIFJMUy1zY29wZWQgdG8gdGhlIG9yZyBsaWtlIGV2ZXJ5IG90aGVyIHJlYWQuXG4gICAqL1xuICBhc3luYyBnZXRJbmdlc3RIZWFsdGgob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8SW5nZXN0SGVhbHRoU3RhdHVzIHwgbnVsbD4ge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eFxuICAgICAgICAuc2VsZWN0KClcbiAgICAgICAgLmZyb20oc2NoZW1hLmluZ2VzdEhlYWx0aClcbiAgICAgICAgLndoZXJlKGVxKHNjaGVtYS5pbmdlc3RIZWFsdGgub3JnSWQsIG9yZ0lkKSlcbiAgICAgICAgLmxpbWl0KDEpKSxcbiAgICApO1xuICAgIGNvbnN0IHJvdyA9IHJvd3NbMF07XG4gICAgaWYgKCFyb3cpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7XG4gICAgICB1cGRhdGVkQXQ6IHJvdy51cGRhdGVkQXQudG9JU09TdHJpbmcoKSxcbiAgICAgIGxhc3RFdmVudEF0OiBpc29Pck51bGwocm93Lmxhc3RFdmVudEF0KSxcbiAgICAgIGZvcndhcmRlZDogcm93LmZvcndhcmRlZCA/PyBudWxsLFxuICAgICAgZHJvcHBlZDogcm93LmRyb3BwZWQgPz8gbnVsbCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcG9ydGluZyByZXRlbnRpb24gc3dlZXA6IGhhcmQtZGVsZXRlcyByb3dzIHBhc3QgdGhlaXIgcGVyLW9yZyByZXRlbnRpb25cbiAgICogd2luZG93IChzcGxpdCBzdGFuZGFyZC1ldmVudCB2cyBET1JBLXNvdXJjZSkuIENyb3NzLXRlbmFudCBob3VzZWtlZXBpbmcg4oCUXG4gICAqIGl0IGVzdGFibGlzaGVzIGl0cyBvd24gc3lzYWRtaW4gc2NvcGUuIFNlZSAuL3JlcG9ydGluZy9yZXRlbnRpb24tc3dlZXAudHMuXG4gICAqL1xuICBhc3luYyBwdXJnZUV4cGlyZWRSZXBvcnRpbmdEYXRhKG9wdHM6IFJlcG9ydGluZ1JldGVudGlvbk9wdGlvbnMgPSB7fSk6IFByb21pc2U8UmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzPiB7XG4gICAgcmV0dXJuIHB1cmdlUmVwb3J0aW5nUmV0ZW50aW9uKG9wdHMpO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCByZXBvcnRpbmdTZXJ2aWNlID0gbmV3IFJlcG9ydGluZ1NlcnZpY2UoKTtcbiJdfQ==