@pipeline-builder/pipeline-data 4.3.3 → 4.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/lib/api/crud-service.d.ts +7 -0
  2. package/lib/api/crud-service.js +14 -3
  3. package/lib/api/pipeline-step-resolution.d.ts +111 -0
  4. package/lib/api/pipeline-step-resolution.js +163 -0
  5. package/lib/api/plugin-consumption-policy.d.ts +8 -2
  6. package/lib/api/plugin-consumption-policy.js +20 -3
  7. package/lib/api/plugin-resolution.d.ts +26 -9
  8. package/lib/api/plugin-resolution.js +51 -33
  9. package/lib/api/reporting/analytics-queries.d.ts +6 -4
  10. package/lib/api/reporting/analytics-queries.js +11 -11
  11. package/lib/api/reporting/deploy-rollup.d.ts +2 -0
  12. package/lib/api/reporting/deploy-rollup.js +5 -1
  13. package/lib/api/reporting/failure-classifier.d.ts +2 -6
  14. package/lib/api/reporting/failure-classifier.js +22 -1
  15. package/lib/api/reporting/ingest.js +73 -16
  16. package/lib/api/reporting/plugin-exposure.d.ts +261 -15
  17. package/lib/api/reporting/plugin-exposure.js +423 -38
  18. package/lib/api/reporting/stakeholder/compose.d.ts +1 -1
  19. package/lib/api/reporting/stakeholder/compose.js +30 -1
  20. package/lib/api/reporting/stakeholder/store.d.ts +16 -2
  21. package/lib/api/reporting/stakeholder/store.js +17 -6
  22. package/lib/api/reporting/types.d.ts +80 -1
  23. package/lib/api/reporting/types.js +1 -1
  24. package/lib/api/reporting-service.d.ts +11 -4
  25. package/lib/api/reporting-service.js +106 -43
  26. package/lib/api/soft-delete-sweep.d.ts +8 -18
  27. package/lib/api/soft-delete-sweep.js +35 -5
  28. package/lib/api/version-references.d.ts +80 -0
  29. package/lib/api/version-references.js +135 -0
  30. package/lib/core/query-filters.d.ts +3 -3
  31. package/lib/core/query-filters.js +1 -1
  32. package/lib/database/drizzle-schema.d.ts +1238 -143
  33. package/lib/database/drizzle-schema.js +6 -3
  34. package/lib/database/index.d.ts +1 -1
  35. package/lib/database/index.js +2 -2
  36. package/lib/database/schema/ecosystem.d.ts +53 -0
  37. package/lib/database/schema/ecosystem.js +14 -3
  38. package/lib/database/schema/pipeline.d.ts +38 -0
  39. package/lib/database/schema/pipeline.js +20 -2
  40. package/lib/database/schema/plugin.d.ts +265 -0
  41. package/lib/database/schema/plugin.js +34 -3
  42. package/lib/database/schema/reporting-analytics.d.ts +786 -4
  43. package/lib/database/schema/reporting-analytics.js +111 -5
  44. package/lib/index.d.ts +5 -3
  45. package/lib/index.js +5 -3
  46. package/lib/testing/exports.json +24 -0
  47. package/package.json +4 -3
@@ -21,9 +21,20 @@
21
21
  * re-synthed since a publish — which is most of the time, and exactly the gap a
22
22
  * vulnerability report is for. Conflating them would let a report say "fixed"
23
23
  * about a pipeline still running the old image.
24
+ *
25
+ * WHO WRITES WHAT:
26
+ * - the pipeline service, on a pipeline write: `replacePipelineResolution` +
27
+ * `reconcilePipelineExposures(source 'declared')`;
28
+ * - the pipeline service, on a deploy registration carrying a step manifest:
29
+ * `reconcilePipelineExposures(source 'deployed')`;
30
+ * - the plugin service, when a version becomes the latest (an org plugin's new
31
+ * default; a listing's publish, yank or unyank): `refreshLatestForPlugin`;
32
+ * - the nightly rescan, per rescanned version: `syncVersionExposures`, which
33
+ * fans the version's findings out to every pipeline declaring or running it
34
+ * (or closes them when the version came back clean).
24
35
  */
25
36
  import { randomUUID } from 'node:crypto';
26
- import { createLogger, errorMessage } from '@pipeline-builder/api-core';
37
+ import { asScanFlag, createLogger, errorMessage, scanFindingKey } from '@pipeline-builder/api-core';
27
38
  import { and, eq, inArray, isNull, lte, sql } from 'drizzle-orm';
28
39
  import { schema } from '../../database/drizzle-schema.js';
29
40
  import { withTenantTx } from '../../database/tenancy.js';
@@ -75,9 +86,12 @@ export async function replacePipelineResolution(pipelineId, steps) {
75
86
  pluginName: s.pluginName,
76
87
  declaredVersion: s.declaredVersion ?? null,
77
88
  resolvedVersion: s.resolvedVersion ?? null,
89
+ resolvedPluginId: s.resolvedPluginId ?? null,
90
+ resolvedDigest: s.resolvedDigest ?? null,
78
91
  latestVersion: s.latestVersion ?? null,
79
92
  versionGap: versionGap(s.resolvedVersion, s.latestVersion),
80
93
  withinPolicy: s.withinPolicy ?? true,
94
+ rootOrgId: s.rootOrgId ?? null,
81
95
  computedAt: new Date(),
82
96
  }));
83
97
  return withTenantTx(async (tx) => {
@@ -98,8 +112,13 @@ export async function replacePipelineResolution(pipelineId, steps) {
98
112
  * the instance that declares the plugin, and re-resolving each of those pipelines
99
113
  * from scratch would make publishing cost O(pipelines) work — so only the two
100
114
  * columns a publish can change are touched.
115
+ *
116
+ * `owner` says whose plugin it is: a listing (`publisher` handle — every org's
117
+ * pipelines that declare it, so the caller must be elevated), or an org's own
118
+ * plugin (`orgId` — that org's pipelines only: an org plugin's name is unique
119
+ * only within its org, so another org's same-named plugin is a different one).
101
120
  */
102
- export async function refreshLatestForPlugin(pluginName, pluginPublisher, latestVersion) {
121
+ export async function refreshLatestForPlugin(pluginName, owner, latestVersion) {
103
122
  const rows = await withTenantTx((tx) => tx.update(schema.pipelinePluginResolution)
104
123
  .set({
105
124
  latestVersion,
@@ -118,19 +137,72 @@ export async function refreshLatestForPlugin(pluginName, pluginPublisher, latest
118
137
  ELSE 'none' END`,
119
138
  computedAt: new Date(),
120
139
  })
121
- .where(and(eq(schema.pipelinePluginResolution.pluginName, pluginName), pluginPublisher === null
122
- ? isNull(schema.pipelinePluginResolution.pluginPublisher)
123
- : eq(schema.pipelinePluginResolution.pluginPublisher, pluginPublisher),
140
+ .where(and(eq(schema.pipelinePluginResolution.pluginName, pluginName), ...('publisher' in owner
141
+ ? [eq(schema.pipelinePluginResolution.pluginPublisher, owner.publisher)]
142
+ : [isNull(schema.pipelinePluginResolution.pluginPublisher), eq(schema.pipelinePluginResolution.orgId, owner.orgId)]),
124
143
  // Only rows whose resolved version parses as semver; anything else has no
125
144
  // gap to compute and the CASE would throw on the cast.
126
145
  sql `${schema.pipelinePluginResolution.resolvedVersion} ~ '^[0-9]+\\.[0-9]+\\.[0-9]+'`))
127
146
  .returning({ pipelineId: schema.pipelinePluginResolution.pipelineId }));
128
147
  return rows.length;
129
148
  }
149
+ /**
150
+ * Whether an exposure row is LIVE: not fixed, not dismissed as a false positive,
151
+ * and not under an acceptance that is still in force.
152
+ *
153
+ * The ONE predicate every reader uses (the report section, needs-attention, the
154
+ * org's open list). Two readers that disagree about what "exposed" means produce
155
+ * a report whose vulnerability panel and needs-attention list contradict each
156
+ * other — which is how this predicate came to exist. An acceptance LAPSES at its
157
+ * deadline and the row is live again; one with no deadline (which
158
+ * `triageExposure` refuses to write) is treated as in force, as every reader
159
+ * already did.
160
+ *
161
+ * `alias` is the table name or alias the caller's query uses.
162
+ */
163
+ export function liveExposurePredicate(now, alias = 'plugin_vuln_exposure') {
164
+ const col = (c) => sql.raw(`${alias}.${c}`);
165
+ return sql `(${col('fixed_at')} IS NULL
166
+ AND (${col('triage_state')} = 'open'
167
+ OR (${col('triage_state')} = 'accepted'
168
+ AND ${col('accepted_until')} IS NOT NULL AND ${col('accepted_until')} <= ${now})))`;
169
+ }
170
+ const keysOf = (findings) => [...new Set(findings.map(scanFindingKey))].sort();
171
+ /** At most this many findings are stored on an exposure row. */
172
+ const EXPOSURE_TOP_FINDINGS = 10;
173
+ /**
174
+ * The exposure a version's scan state amounts to, or null when it has none.
175
+ *
176
+ * Reads the rescan's `scan_summary` (fixable Critical AND High, whether or not the
177
+ * gate tripped) and falls back to `scan_flag` for a version flagged before any
178
+ * summary was written. A summary whose digest is not the step's is IGNORED: a
179
+ * version rebuilt on a patched base is a different artifact, and its findings say
180
+ * nothing about the image the pipeline runs. Only FIXABLE findings count — an
181
+ * exposure is something a rebuild or an upgrade can clear.
182
+ */
183
+ export function exposureFromScan(state) {
184
+ const summary = state.scanSummary && typeof state.scanSummary === 'object' && !Array.isArray(state.scanSummary)
185
+ ? state.scanSummary
186
+ : null;
187
+ const summaryDigest = typeof summary?.imageDigest === 'string' ? summary.imageDigest : null;
188
+ if (summary && typeof summary.criticalFixable === 'number' && typeof summary.highFixable === 'number'
189
+ && (summaryDigest === null || !state.imageDigest || summaryDigest === state.imageDigest)) {
190
+ if (summary.criticalFixable <= 0 && summary.highFixable <= 0)
191
+ return null;
192
+ const all = (Array.isArray(summary.findings) ? summary.findings : [])
193
+ .filter((f) => f && typeof f.id === 'string');
194
+ const findings = all.filter((f) => Array.isArray(f.fixedIn) && f.fixedIn.length > 0);
195
+ return { criticalCount: summary.criticalFixable, highCount: summary.highFixable, topFindings: findings.slice(0, EXPOSURE_TOP_FINDINGS), findingKeys: keysOf(all) };
196
+ }
197
+ const flag = state.scanFlaggedAt ? asScanFlag(state.scanFlag) : null;
198
+ if (!flag || (flag.gated <= 0 && flag.high <= 0))
199
+ return null;
200
+ return { criticalCount: flag.gated, highCount: flag.high, topFindings: flag.findings.slice(0, EXPOSURE_TOP_FINDINGS), findingKeys: keysOf(flag.findings) };
201
+ }
130
202
  /**
131
203
  * Open or refresh exposures.
132
204
  *
133
- * Upserts on (pipeline, plugin, version, source) so a nightly rescan REFRESHES the
205
+ * Upserts on (pipeline, plugin, version, digest, source) so a nightly rescan REFRESHES the
134
206
  * counts rather than opening a new row every night — otherwise the report would
135
207
  * show one exposure per night of the same problem, which reads as an escalating
136
208
  * situation when nothing changed.
@@ -155,6 +227,7 @@ export async function upsertExposures(inputs, now = new Date()) {
155
227
  criticalCount: e.criticalCount,
156
228
  highCount: e.highCount,
157
229
  topFindings: e.topFindings ?? [],
230
+ findingKeys: e.findingKeys ?? [],
158
231
  flaggedAt: now,
159
232
  updatedAt: now,
160
233
  }));
@@ -165,13 +238,14 @@ export async function upsertExposures(inputs, now = new Date()) {
165
238
  schema.pluginVulnExposure.pipelineId,
166
239
  schema.pluginVulnExposure.pluginName,
167
240
  schema.pluginVulnExposure.pluginVersion,
241
+ schema.pluginVulnExposure.imageDigest,
168
242
  schema.pluginVulnExposure.source,
169
243
  ],
170
244
  set: {
171
245
  criticalCount: sql `excluded.critical_count`,
172
246
  highCount: sql `excluded.high_count`,
173
247
  topFindings: sql `excluded.top_findings`,
174
- imageDigest: sql `COALESCE(excluded.image_digest, ${schema.pluginVulnExposure.imageDigest})`,
248
+ findingKeys: sql `excluded.finding_keys`,
175
249
  // Still exposed, so the fix marker is cleared: a row that was closed by a
176
250
  // deploy and is flagged again is a regression, and leaving `fixed_at` set
177
251
  // would hide it.
@@ -179,12 +253,26 @@ export async function upsertExposures(inputs, now = new Date()) {
179
253
  // An acceptance past its deadline stops being an acceptance. That is the
180
254
  // entire point of time-boxing it, and it is enforced HERE rather than at
181
255
  // read time so the stored state is the truth.
256
+ // An acceptance covers the findings it was made over, never ones found
257
+ // since: a refresh carrying a finding key the acceptance did not freeze
258
+ // reopens the row, so the decision is made again about what is there now.
182
259
  triageState: sql `CASE
183
260
  WHEN ${schema.pluginVulnExposure.triageState} = 'accepted'
184
261
  AND ${schema.pluginVulnExposure.acceptedUntil} IS NOT NULL
185
262
  AND ${schema.pluginVulnExposure.acceptedUntil} <= ${now}
186
263
  THEN 'open'
264
+ WHEN ${schema.pluginVulnExposure.triageState} = 'accepted'
265
+ AND NOT (excluded.finding_keys <@ ${schema.pluginVulnExposure.acceptedFindingKeys})
266
+ THEN 'open'
187
267
  WHEN ${schema.pluginVulnExposure.triageState} = 'fixed' THEN 'open'
268
+ -- A REMOVED step / pipeline back on the same version: its acceptance
269
+ -- returns if still in force and it covers what the version carries now.
270
+ WHEN ${schema.pluginVulnExposure.triageState} = 'removed'
271
+ AND ${schema.pluginVulnExposure.acceptedUntil} IS NOT NULL
272
+ AND ${schema.pluginVulnExposure.acceptedUntil} > ${now}
273
+ AND excluded.finding_keys <@ ${schema.pluginVulnExposure.acceptedFindingKeys}
274
+ THEN 'accepted'
275
+ WHEN ${schema.pluginVulnExposure.triageState} = 'removed' THEN 'open'
188
276
  ELSE ${schema.pluginVulnExposure.triageState} END`,
189
277
  updatedAt: now,
190
278
  },
@@ -197,32 +285,200 @@ export async function upsertExposures(inputs, now = new Date()) {
197
285
  return 0;
198
286
  }
199
287
  }
288
+ const liveKey = (v) => `${v.pluginName}@${v.pluginVersion}@${v.imageDigest ?? ''}`;
200
289
  /**
201
- * Close the exposures a pipeline has moved off.
290
+ * Close the exposures of one SOURCE a pipeline has moved off — `fixed` when the
291
+ * pipeline still uses the plugin at another version, `removed` when no live step
292
+ * uses the plugin at all (the triage fields stay, so a re-added step gets an
293
+ * unexpired acceptance back — see {@link upsertExposures}).
202
294
  *
203
- * Called when a deploy records a new step manifest: anything flagged for that
204
- * pipeline whose version is NOT in the set it now runs is fixed. Closing by
295
+ * Called when a deploy records a new step manifest (`deployed`) or a pipeline
296
+ * write re-resolves its config (`declared`): anything open for that pipeline and
297
+ * source whose (version, digest) is NOT in `liveVersions` is fixed. Closing by
205
298
  * absence rather than waiting for a rescan to notice is what makes "we fixed it"
206
299
  * show up in the report on the next deploy instead of the next night.
300
+ *
301
+ * Per source, because the two sides move independently: a config updated to the
302
+ * fixed version closes the DECLARED exposure while the old image keeps running,
303
+ * and its DEPLOYED exposure must stay open until the deploy lands.
207
304
  */
208
- export async function closeFixedExposures(pipelineId, liveVersions, now = new Date()) {
209
- const live = new Set(liveVersions.map((v) => `${v.pluginName}@${v.pluginVersion}`));
305
+ export async function closeFixedExposures(pipelineId, source, liveVersions, now = new Date(), opts = {}) {
306
+ const live = new Set(liveVersions.map(liveKey));
307
+ const livePlugins = new Set([...liveVersions, ...(opts.livePlugins ?? [])].map((v) => (typeof v === 'string' ? v : v.pluginName)));
210
308
  const open = await withTenantTx((tx) => tx.select({
211
309
  id: schema.pluginVulnExposure.id,
212
310
  pluginName: schema.pluginVulnExposure.pluginName,
213
311
  pluginVersion: schema.pluginVulnExposure.pluginVersion,
312
+ imageDigest: schema.pluginVulnExposure.imageDigest,
214
313
  }).from(schema.pluginVulnExposure)
215
- .where(and(eq(schema.pluginVulnExposure.pipelineId, pipelineId), isNull(schema.pluginVulnExposure.fixedAt))));
216
- const stale = open
217
- .filter((r) => !live.has(`${r.pluginName}@${r.pluginVersion}`))
218
- .map((r) => r.id);
219
- if (stale.length === 0)
314
+ .where(and(eq(schema.pluginVulnExposure.pipelineId, pipelineId), eq(schema.pluginVulnExposure.source, source), isNull(schema.pluginVulnExposure.fixedAt))));
315
+ const staleRows = open.filter((r) => !live.has(liveKey(r)));
316
+ if (staleRows.length === 0)
220
317
  return 0;
221
- const closed = await withTenantTx((tx) => tx.update(schema.pluginVulnExposure)
222
- .set({ fixedAt: now, triageState: 'fixed', updatedAt: now })
223
- .where(inArray(schema.pluginVulnExposure.id, stale))
318
+ const fixed = staleRows.filter((r) => livePlugins.has(r.pluginName)).map((r) => r.id);
319
+ const removed = staleRows.filter((r) => !livePlugins.has(r.pluginName)).map((r) => r.id);
320
+ let closed = 0;
321
+ for (const [ids, state] of [[fixed, 'fixed'], [removed, 'removed']]) {
322
+ if (ids.length === 0)
323
+ continue;
324
+ const rows = await withTenantTx((tx) => tx.update(schema.pluginVulnExposure)
325
+ .set({ fixedAt: now, triageState: state, updatedAt: now })
326
+ .where(inArray(schema.pluginVulnExposure.id, [...ids]))
327
+ .returning({ id: schema.pluginVulnExposure.id }));
328
+ closed += rows.length;
329
+ }
330
+ return closed;
331
+ }
332
+ /**
333
+ * Close every open exposure of a pipeline (or of one source) as `removed` — the
334
+ * pipeline was deleted, or deregistered (its deploy is gone). The triage fields
335
+ * stay: a restore re-records the pipeline's resolution, and
336
+ * {@link upsertExposures} reopens the rows (restoring an acceptance still in
337
+ * force). Returns the rows closed.
338
+ */
339
+ export async function closePipelineExposures(pipelineId, state, opts = {}, now = new Date()) {
340
+ const rows = await withTenantTx((tx) => tx.update(schema.pluginVulnExposure)
341
+ .set({ fixedAt: now, triageState: state, updatedAt: now })
342
+ .where(and(eq(schema.pluginVulnExposure.pipelineId, pipelineId), isNull(schema.pluginVulnExposure.fixedAt), ...(opts.source ? [eq(schema.pluginVulnExposure.source, opts.source)] : [])))
224
343
  .returning({ id: schema.pluginVulnExposure.id }));
225
- return closed.length;
344
+ return rows.length;
345
+ }
346
+ /**
347
+ * Bring one pipeline's exposures of one source in line with the steps it now
348
+ * declares (`declared`) or runs (`deployed`): open / refresh a row for every step
349
+ * whose version has open fixable findings, close the rest by absence.
350
+ *
351
+ * Never throws — exposure tracking is reporting, and a pipeline write or a deploy
352
+ * registration must not fail because the report table could not be written.
353
+ */
354
+ export async function reconcilePipelineExposures(input, now = new Date()) {
355
+ const exposed = [];
356
+ const seen = new Set();
357
+ for (const step of input.steps) {
358
+ const counts = exposureFromScan({ ...step.scan, imageDigest: step.imageDigest ?? step.scan.imageDigest ?? null });
359
+ if (!counts)
360
+ continue;
361
+ const key = liveKey({ pluginName: step.pluginName, pluginVersion: step.pluginVersion, imageDigest: step.imageDigest });
362
+ if (seen.has(key))
363
+ continue; // two steps on one version are one exposure
364
+ seen.add(key);
365
+ exposed.push({
366
+ orgId: input.orgId,
367
+ pipelineId: input.pipelineId,
368
+ pluginPublisher: step.pluginPublisher ?? null,
369
+ pluginName: step.pluginName,
370
+ pluginVersion: step.pluginVersion,
371
+ imageDigest: step.imageDigest ?? null,
372
+ source: input.source,
373
+ ...counts,
374
+ topFindings: counts.topFindings,
375
+ });
376
+ }
377
+ try {
378
+ const opened = await upsertExposures(exposed, now);
379
+ // Every plugin a step still uses (clean versions too): a row for one of
380
+ // them closes `fixed`; a row for a plugin no step uses any more, `removed`.
381
+ const closed = await closeFixedExposures(input.pipelineId, input.source, exposed, now, { livePlugins: input.steps.map((s) => s.pluginName) });
382
+ return { opened, closed };
383
+ }
384
+ catch (err) {
385
+ logger.warn('Pipeline exposure reconcile failed', { pipelineId: input.pipelineId, source: input.source, error: errorMessage(err) });
386
+ return { opened: 0, closed: 0 };
387
+ }
388
+ }
389
+ /**
390
+ * Every LIVE pipeline declaring (`pipeline_plugin_resolution`) or running
391
+ * (`pipeline_step_manifests`) a plugin version, one entry per (pipeline, source)
392
+ * with the steps on it. A soft-deleted pipeline is NOT affected: counting it
393
+ * would put a pipeline nobody can open into a notice or a report. Reads under
394
+ * the CALLER's tenant scope: an org-scoped caller sees its own pipelines, the
395
+ * rescan (elevated) sees every org's.
396
+ */
397
+ export async function pipelinesOnVersion(ref) {
398
+ const publisherSql = (col) => (ref.pluginPublisher === undefined
399
+ ? sql ``
400
+ : ref.pluginPublisher === null ? sql ` AND ${sql.raw(col)} IS NULL` : sql ` AND ${sql.raw(col)} = ${ref.pluginPublisher}`);
401
+ const digestSql = (col) => (ref.imageDigest ? sql ` AND ${sql.raw(col)} = ${ref.imageDigest}` : sql ``);
402
+ const orgSql = (col) => (ref.orgIds ? sql ` AND ${sql.raw(col)} = ANY(${[...ref.orgIds]})` : sql ``);
403
+ if (ref.orgIds && ref.orgIds.length === 0)
404
+ return [];
405
+ const result = await withTenantTx((tx) => tx.execute(sql `
406
+ SELECT x.org_id, x.pipeline_id, x.source, MIN(x.plugin_publisher) AS plugin_publisher, MIN(x.image_digest) AS image_digest,
407
+ p.pipeline_name, array_agg(DISTINCT x.step ORDER BY x.step) AS steps
408
+ FROM (
409
+ SELECT m.org_id, m.pipeline_id::text AS pipeline_id, 'deployed' AS source, m.plugin_publisher, m.image_digest,
410
+ m.stage_name || '/' || m.action_name AS step
411
+ FROM pipeline_step_manifests m
412
+ WHERE m.plugin_name = ${ref.pluginName} AND m.plugin_version = ${ref.pluginVersion}
413
+ ${publisherSql('m.plugin_publisher')}${digestSql('m.image_digest')}${orgSql('m.org_id')}
414
+ UNION ALL
415
+ SELECT r.org_id, r.pipeline_id, 'declared' AS source, r.plugin_publisher, r.resolved_digest AS image_digest,
416
+ CASE WHEN r.stage_name = 'synth' AND r.step_name = 'synth' THEN 'synth' ELSE r.stage_name || '/' || r.step_name END AS step
417
+ FROM pipeline_plugin_resolution r
418
+ WHERE r.plugin_name = ${ref.pluginName} AND r.resolved_version = ${ref.pluginVersion}
419
+ ${publisherSql('r.plugin_publisher')}${digestSql('r.resolved_digest')}${orgSql('r.org_id')}
420
+ ) x
421
+ JOIN pipelines p ON p.id::text = x.pipeline_id AND p.deleted_at IS NULL
422
+ GROUP BY x.org_id, x.pipeline_id, x.source, p.pipeline_name
423
+ ORDER BY x.pipeline_id, x.source
424
+ `));
425
+ const rows = Array.isArray(result) ? result : (result?.rows ?? []);
426
+ return rows.map((r) => ({
427
+ orgId: String(r.org_id),
428
+ pipelineId: String(r.pipeline_id),
429
+ pipelineName: r.pipeline_name ?? null,
430
+ source: r.source,
431
+ pluginPublisher: r.plugin_publisher ?? null,
432
+ imageDigest: r.image_digest ?? null,
433
+ steps: Array.isArray(r.steps) ? r.steps : [],
434
+ }));
435
+ }
436
+ /**
437
+ * The rescan's entry point: one rescanned version's findings, fanned out to every
438
+ * pipeline that declares or runs it.
439
+ *
440
+ * A version with open fixable findings opens / refreshes one exposure per
441
+ * (pipeline, source); a version that came back CLEAN closes every open exposure
442
+ * on it (`fixed`), so a rebuild-in-place or an advisory withdrawn upstream shows
443
+ * as fixed on the next night rather than lingering until each pipeline redeploys.
444
+ *
445
+ * Must run with a scope that can read and write every org's rows (the rescan's
446
+ * elevated context). Never throws.
447
+ */
448
+ export async function syncVersionExposures(ref, scan, now = new Date()) {
449
+ try {
450
+ const counts = exposureFromScan({ ...scan, imageDigest: ref.imageDigest ?? scan.imageDigest ?? null });
451
+ if (!counts)
452
+ return { opened: 0, closed: await closeVersionExposures(ref, now) };
453
+ const pipelines = await pipelinesOnVersion(ref);
454
+ const opened = await upsertExposures(pipelines.map((p) => ({
455
+ orgId: p.orgId,
456
+ pipelineId: p.pipelineId,
457
+ pluginPublisher: p.pluginPublisher,
458
+ pluginName: ref.pluginName,
459
+ pluginVersion: ref.pluginVersion,
460
+ imageDigest: ref.imageDigest ?? p.imageDigest,
461
+ source: p.source,
462
+ criticalCount: counts.criticalCount,
463
+ highCount: counts.highCount,
464
+ topFindings: counts.topFindings,
465
+ findingKeys: counts.findingKeys,
466
+ })), now);
467
+ return { opened, closed: 0 };
468
+ }
469
+ catch (err) {
470
+ logger.warn('Version exposure sync failed', { plugin: ref.pluginName, version: ref.pluginVersion, error: errorMessage(err) });
471
+ return { opened: 0, closed: 0 };
472
+ }
473
+ }
474
+ /** Close every open exposure on a version (optionally one image of it). */
475
+ export async function closeVersionExposures(ref, now = new Date()) {
476
+ const E = schema.pluginVulnExposure;
477
+ const rows = await withTenantTx((tx) => tx.update(E)
478
+ .set({ fixedAt: now, triageState: 'fixed', updatedAt: now })
479
+ .where(and(eq(E.pluginName, ref.pluginName), eq(E.pluginVersion, ref.pluginVersion), isNull(E.fixedAt), ...(ref.imageDigest ? [eq(E.imageDigest, ref.imageDigest)] : []), ...(ref.pluginPublisher === undefined ? [] : [ref.pluginPublisher === null ? isNull(E.pluginPublisher) : eq(E.pluginPublisher, ref.pluginPublisher)]), ...(ref.orgIds ? [inArray(E.orgId, [...ref.orgIds])] : [])))
480
+ .returning({ id: E.id }));
481
+ return rows.length;
226
482
  }
227
483
  /**
228
484
  * The org's live exposures, for the report section.
@@ -246,11 +502,7 @@ export async function openExposures(orgId) {
246
502
  acceptedUntil: schema.pluginVulnExposure.acceptedUntil,
247
503
  flaggedAt: schema.pluginVulnExposure.flaggedAt,
248
504
  }).from(schema.pluginVulnExposure)
249
- .where(and(eq(schema.pluginVulnExposure.orgId, orgId), isNull(schema.pluginVulnExposure.fixedAt),
250
- // An acceptance that has run out is not an acceptance.
251
- sql `(${schema.pluginVulnExposure.triageState} <> 'accepted'
252
- OR ${schema.pluginVulnExposure.acceptedUntil} IS NULL
253
- OR ${schema.pluginVulnExposure.acceptedUntil} <= ${now})`))
505
+ .where(and(eq(schema.pluginVulnExposure.orgId, orgId), liveExposurePredicate(now)))
254
506
  .orderBy(sql `${schema.pluginVulnExposure.criticalCount} DESC, ${schema.pluginVulnExposure.highCount} DESC`));
255
507
  return rows.map((r) => ({
256
508
  pipelineId: r.pipelineId,
@@ -261,35 +513,168 @@ export async function openExposures(orgId) {
261
513
  criticalCount: r.criticalCount,
262
514
  highCount: r.highCount,
263
515
  topFindings: r.topFindings ?? [],
264
- // An expired acceptance reads as open, which is what it is.
265
- triageState: r.triageState === 'accepted' && r.acceptedUntil ? 'open' : r.triageState,
516
+ // Only acceptances NOT in force pass the live predicate, so an `accepted`
517
+ // row here is an expired one, and reads as what it is: open.
518
+ triageState: r.triageState === 'accepted' ? 'open' : r.triageState,
266
519
  flaggedAt: r.flaggedAt,
267
520
  }));
268
521
  }
522
+ const E = () => schema.pluginVulnExposure;
523
+ function toPipelineExposure(r, now) {
524
+ const until = r.acceptedUntil ?? null;
525
+ const active = r.triageState === 'accepted' && r.fixedAt == null && until !== null && until.getTime() > now.getTime();
526
+ return {
527
+ id: r.id,
528
+ orgId: r.orgId,
529
+ pipelineId: r.pipelineId,
530
+ pluginPublisher: r.pluginPublisher ?? null,
531
+ pluginName: r.pluginName,
532
+ pluginVersion: r.pluginVersion,
533
+ imageDigest: r.imageDigest ?? null,
534
+ source: r.source,
535
+ criticalCount: r.criticalCount,
536
+ highCount: r.highCount,
537
+ topFindings: r.topFindings ?? [],
538
+ findingKeys: r.findingKeys ?? [],
539
+ triageState: r.triageState === 'accepted' && !active && r.fixedAt == null ? 'open' : r.triageState,
540
+ acceptanceActive: active,
541
+ acceptedUntil: until,
542
+ acceptedFindingKeys: r.acceptedFindingKeys ?? [],
543
+ acceptedKev: r.acceptedKev === true,
544
+ triageReason: r.triageReason ?? null,
545
+ triagedBy: r.triagedBy ?? null,
546
+ triagedAt: r.triagedAt ?? null,
547
+ flaggedAt: r.flaggedAt,
548
+ fixedAt: r.fixedAt ?? null,
549
+ };
550
+ }
551
+ /**
552
+ * One pipeline's exposures: the unfixed ones (open, accepted, false positive),
553
+ * plus the fixed ones when asked — most severe first. Reads under the CALLER's
554
+ * scope, narrowed to `orgId`.
555
+ */
556
+ export async function pipelineExposures(orgId, pipelineId, opts = {}) {
557
+ const now = opts.now ?? new Date();
558
+ const rows = await withTenantTx((tx) => tx.select().from(E())
559
+ .where(and(eq(E().orgId, orgId), eq(E().pipelineId, pipelineId), ...(opts.includeFixed ? [] : [isNull(E().fixedAt)])))
560
+ .orderBy(sql `${E().criticalCount} DESC, ${E().highCount} DESC, ${E().pluginName}`));
561
+ return rows.map((r) => toPipelineExposure(r, now));
562
+ }
563
+ /** One exposure row of `orgId`, or null. */
564
+ export async function exposureById(orgId, id, now = new Date()) {
565
+ const rows = await withTenantTx((tx) => tx.select().from(E()).where(and(eq(E().id, id), eq(E().orgId, orgId))));
566
+ const row = rows[0];
567
+ return row ? toPipelineExposure(row, now) : null;
568
+ }
269
569
  /**
270
- * Record a triage decision.
570
+ * Record a triage decision on one exposure — and on its SIBLINGS: the same
571
+ * pipeline's other open row for the same version and image (the declared and
572
+ * the deployed side). A risk decision is about what the pipeline runs, and
573
+ * leaving one side open would have the report and the lookup disagree.
271
574
  *
272
575
  * `accepted` REQUIRES a deadline and a reason. A permanent, unexplained mute is
273
576
  * how a finding stops being anybody's problem, and there is no good reason to
274
577
  * support it — the caller gets an error rather than a silently unbounded
275
- * acceptance.
578
+ * acceptance. The accepted finding keys are FROZEN at the decision: an
579
+ * acceptance covers what was there when it was made, never a finding since.
580
+ *
581
+ * Returns the updated rows (empty when `id` is not `orgId`'s unfixed exposure).
276
582
  */
277
583
  export async function triageExposure(orgId, id, decision) {
278
584
  if (decision.state === 'accepted' && (!decision.acceptedUntil || !decision.reason?.trim())) {
279
585
  throw new Error('Accepting a vulnerability exposure needs a reason and an expiry date');
280
586
  }
281
- const rows = await withTenantTx((tx) => tx.update(schema.pluginVulnExposure)
587
+ const now = new Date();
588
+ const target = await exposureById(orgId, id, now);
589
+ if (!target || target.fixedAt)
590
+ return [];
591
+ const rows = await withTenantTx((tx) => tx.update(E())
282
592
  .set({
283
593
  triageState: decision.state,
284
594
  acceptedUntil: decision.state === 'accepted' ? (decision.acceptedUntil ?? null) : null,
285
- triageReason: decision.reason ?? null,
595
+ acceptedFindingKeys: decision.state === 'accepted' ? sql `${E().findingKeys}` : [],
596
+ acceptedKev: decision.state === 'accepted' && decision.kev === true,
597
+ triageReason: decision.reason?.trim() || null,
286
598
  triagedBy: decision.actor,
287
- triagedAt: new Date(),
288
- updatedAt: new Date(),
599
+ triagedAt: now,
600
+ updatedAt: now,
289
601
  })
290
- .where(and(eq(schema.pluginVulnExposure.id, id), eq(schema.pluginVulnExposure.orgId, orgId)))
291
- .returning({ id: schema.pluginVulnExposure.id }));
292
- return rows.length > 0;
602
+ .where(and(eq(E().orgId, orgId), eq(E().pipelineId, target.pipelineId), eq(E().pluginName, target.pluginName), eq(E().pluginVersion, target.pluginVersion), target.imageDigest === null ? isNull(E().imageDigest) : eq(E().imageDigest, target.imageDigest), isNull(E().fixedAt)))
603
+ .returning());
604
+ return rows.map((r) => toPipelineExposure(r, now));
605
+ }
606
+ /** `name@version@digest` — the key {@link activeAcceptances} answers under. */
607
+ export const acceptanceKey = (pluginName, pluginVersion, imageDigest) => `${pluginName}@${pluginVersion}@${imageDigest ?? ''}`;
608
+ /**
609
+ * The acceptances IN FORCE for one pipeline (`accepted`, unfixed, deadline in the
610
+ * future), merged per version and image: the union of the finding keys the rows
611
+ * froze, KEV only when every merged row accepted it. Reads under the caller's
612
+ * scope narrowed to `orgId`; a failed read is "no acceptance" — the stricter answer.
613
+ */
614
+ export async function activeAcceptances(orgId, pipelineId, now = new Date()) {
615
+ const out = { byKey: new Map(), versionsByPlugin: new Map() };
616
+ try {
617
+ const rows = await withTenantTx((tx) => tx.select({
618
+ id: E().id,
619
+ pluginName: E().pluginName,
620
+ pluginVersion: E().pluginVersion,
621
+ imageDigest: E().imageDigest,
622
+ acceptedUntil: E().acceptedUntil,
623
+ acceptedFindingKeys: E().acceptedFindingKeys,
624
+ acceptedKev: E().acceptedKev,
625
+ }).from(E())
626
+ .where(and(eq(E().orgId, orgId), eq(E().pipelineId, pipelineId), eq(E().triageState, 'accepted'), isNull(E().fixedAt), sql `${E().acceptedUntil} > ${now}`)));
627
+ for (const r of rows) {
628
+ const key = acceptanceKey(r.pluginName, r.pluginVersion, r.imageDigest);
629
+ const prev = out.byKey.get(key);
630
+ out.byKey.set(key, prev
631
+ ? {
632
+ findingKeys: [...new Set([...prev.findingKeys, ...(r.acceptedFindingKeys ?? [])])],
633
+ kev: prev.kev && r.acceptedKev,
634
+ acceptedUntil: prev.acceptedUntil && new Date(prev.acceptedUntil) < r.acceptedUntil ? prev.acceptedUntil : r.acceptedUntil,
635
+ exposureIds: [...prev.exposureIds, r.id],
636
+ }
637
+ : { findingKeys: r.acceptedFindingKeys ?? [], kev: r.acceptedKev, acceptedUntil: r.acceptedUntil, exposureIds: [r.id] });
638
+ const versions = out.versionsByPlugin.get(r.pluginName) ?? new Set();
639
+ versions.add(r.pluginVersion);
640
+ out.versionsByPlugin.set(r.pluginName, versions);
641
+ }
642
+ }
643
+ catch (err) {
644
+ logger.warn('Pipeline acceptances unreadable; treating as none', { pipelineId, error: errorMessage(err) });
645
+ }
646
+ return out;
647
+ }
648
+ /**
649
+ * Reopen every acceptance whose deadline has passed, and return them so the
650
+ * pipeline owners can be told (N33). Readers already treat such a row as open;
651
+ * writing it makes the stored state the truth and gives the notice exactly one
652
+ * moment to fire. Must run with a scope that can write every org's rows (the
653
+ * nightly rescan's elevated context). Never throws.
654
+ */
655
+ export async function reopenLapsedAcceptances(now = new Date()) {
656
+ try {
657
+ const rows = await withTenantTx((tx) => tx.update(E())
658
+ .set({ triageState: 'open', updatedAt: now })
659
+ .where(and(eq(E().triageState, 'accepted'), isNull(E().fixedAt), lte(E().acceptedUntil, now)))
660
+ .returning({
661
+ id: E().id,
662
+ orgId: E().orgId,
663
+ pipelineId: E().pipelineId,
664
+ pluginPublisher: E().pluginPublisher,
665
+ pluginName: E().pluginName,
666
+ pluginVersion: E().pluginVersion,
667
+ imageDigest: E().imageDigest,
668
+ triagedBy: E().triagedBy,
669
+ triageReason: E().triageReason,
670
+ acceptedUntil: E().acceptedUntil,
671
+ }));
672
+ return rows;
673
+ }
674
+ catch (err) {
675
+ logger.warn('Lapsed acceptances not reopened', { error: errorMessage(err) });
676
+ return [];
677
+ }
293
678
  }
294
679
  /**
295
680
  * Exposures whose acceptance has lapsed, for the org's security notifications.
@@ -309,4 +694,4 @@ export async function lapsedAcceptances(orgId, now = new Date()) {
309
694
  .where(and(eq(schema.pluginVulnExposure.orgId, orgId), eq(schema.pluginVulnExposure.triageState, 'accepted'), isNull(schema.pluginVulnExposure.fixedAt), lte(schema.pluginVulnExposure.acceptedUntil, now))));
310
695
  return rows;
311
696
  }
312
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWV4cG9zdXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvcGx1Z2luLWV4cG9zdXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDakUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRTFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV6RCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQW1CL0MsMERBQTBEO0FBQzFELFNBQVMsTUFBTSxDQUFDLENBQTRCO0lBQzFDLE1BQU0sQ0FBQyxHQUFHLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDakQsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQy9ELENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUFDLFFBQW1DLEVBQUUsTUFBaUM7SUFDL0YsTUFBTSxDQUFDLEdBQUcsTUFBTSxD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Q0FDbEQsQ0FBQyxDQUFDLENBQUM7SUFDTixPQUFPLElBQThILENBQUM7QUFDeEksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIFdoYXQgcGx1Z2luIHZlcnNpb25zIGFuIG9yZydzIHBpcGVsaW5lcyBhcmUgYWN0dWFsbHkgb24sIGFuZCB3aGljaCBvZiB0aG9zZSBhcmVcbiAqIGtub3duLXZ1bG5lcmFibGUuXG4gKlxuICogVHdvIHRhYmxlcywgd3JpdHRlbiBoZXJlLCByZWFkIGJ5IHRoZSBvdXRkYXRlZC1wbHVnaW4gYW5kIHZ1bG5lcmFiaWxpdHkgcmVwb3J0XG4gKiBzZWN0aW9uczpcbiAqXG4gKiAgLSBgcGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb25gIOKAlCB0aGUgREVDTEFSRUQgc2lkZS4gUmVjb21wdXRlZCBvbiBwaXBlbGluZVxuICogICAgd3JpdGUgYW5kIG9uIHBsdWdpbiBwdWJsaXNoLCBiZWNhdXNlIHRoZSBhbHRlcm5hdGl2ZSBpcyByZXNvbHZpbmcgZXZlcnkgc3RlcFxuICogICAgb2YgZXZlcnkgcGlwZWxpbmUgYWdhaW5zdCB0aGUgY2F0YWxvZyBvbiBldmVyeSByZWFkLCBhbmQgdGhhdCBpcyBub3QgYSBxdWVyeVxuICogICAgYW55b25lIGNhbiBhZmZvcmQgdG8gcHV0IGluIGEgcmVwb3J0LlxuICogIC0gYHBsdWdpbl92dWxuX2V4cG9zdXJlYCDigJQgdGhlIFZVTE5FUkFCTEUgc2lkZSwgcGVyIFBJUEVMSU5FLiBBIHZlcnNpb24tbGV2ZWxcbiAqICAgIHRhYmxlIHdvdWxkIGZvcmNlIGV2ZXJ5IHJlYWRlciB0byByZS1kZXJpdmUgXCJ3aGljaCBvZiBvdXIgcGlwZWxpbmVzIGlzXG4gKiAgICBleHBvc2VkXCIsIHdoaWNoIGlzIHRoZSBvbmx5IGZvcm0gb2YgdGhlIHF1ZXN0aW9uIGFueWJvZHkgYXNrcy5cbiAqXG4gKiBERUNMQVJFRCBJUyBOT1QgREVQTE9ZRUQsIGFuZCB0aGUgcmVwb3J0IHNheXMgd2hpY2ggaXQgaXMgc2hvd2luZy4gQSBwaXBlbGluZSdzXG4gKiBjb25maWcgZGVjbGFyZXMgYF4yLjAuMGA7IHdoYXQgcmFuIGF0IGl0cyBsYXN0IGRlcGxveSBpcyB3aGF0ZXZlciB0aGUgc3RlcFxuICogbWFuaWZlc3QgcmVjb3JkZWQsIHBpbm5lZCB0byBhIGRpZ2VzdC4gVGhvc2UgZGlzYWdyZWUgd2hlbmV2ZXIgYSBwaXBlbGluZSBoYXMgbm90XG4gKiByZS1zeW50aGVkIHNpbmNlIGEgcHVibGlzaCDigJQgd2hpY2ggaXMgbW9zdCBvZiB0aGUgdGltZSwgYW5kIGV4YWN0bHkgdGhlIGdhcCBhXG4gKiB2dWxuZXJhYmlsaXR5IHJlcG9ydCBpcyBmb3IuIENvbmZsYXRpbmcgdGhlbSB3b3VsZCBsZXQgYSByZXBvcnQgc2F5IFwiZml4ZWRcIlxuICogYWJvdXQgYSBwaXBlbGluZSBzdGlsbCBydW5uaW5nIHRoZSBvbGQgaW1hZ2UuXG4gKi9cblxuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgYW5kLCBlcSwgaW5BcnJheSwgaXNOdWxsLCBsdGUsIHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IHNjaGVtYSB9IGZyb20gJy4uLy4uL2RhdGFiYXNlL2RyaXp6bGUtc2NoZW1hLmpzJztcbmltcG9ydCB0eXBlIHsgRXhwb3N1cmVTb3VyY2UgfSBmcm9tICcuLi8uLi9kYXRhYmFzZS9zY2hlbWEvcmVwb3J0aW5nLWFuYWx5dGljcy5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHggfSBmcm9tICcuLi8uLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdwbHVnaW4tZXhwb3N1cmUnKTtcblxuLyoqIEhvdyBmYXIgYmVoaW5kIGEgcmVzb2x2ZWQgdmVyc2lvbiBpcyBmcm9tIHRoZSBuZXdlc3Qgb25lIGF2YWlsYWJsZS4gKi9cbmV4cG9ydCB0eXBlIFZlcnNpb25HYXAgPSAnbWFqb3InIHwgJ21pbm9yJyB8ICdwYXRjaCcgfCAnbm9uZSc7XG5cbi8qKiBPbmUgcmVzb2x2ZWQgc3RlcCwgYXMgdGhlIHdyaXRlciB0YWtlcyBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRTdGVwIHtcbiAgb3JnSWQ6IHN0cmluZztcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBzdGFnZU5hbWU6IHN0cmluZztcbiAgc3RlcE5hbWU6IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyPzogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBkZWNsYXJlZFZlcnNpb24/OiBzdHJpbmcgfCBudWxsO1xuICByZXNvbHZlZFZlcnNpb24/OiBzdHJpbmcgfCBudWxsO1xuICBsYXRlc3RWZXJzaW9uPzogc3RyaW5nIHwgbnVsbDtcbiAgd2l0aGluUG9saWN5PzogYm9vbGVhbjtcbn1cblxuLyoqIGAxLjIuM2Ag4oaSIGBbMSwgMiwgM11gOyBhbnl0aGluZyB1bnBhcnNlYWJsZSDihpIgbnVsbC4gKi9cbmZ1bmN0aW9uIHNlbXZlcih2OiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVsbCB7XG4gIGNvbnN0IG0gPSAvXnY/KFxcZCspXFwuKFxcZCspXFwuKFxcZCspLy5leGVjKHYgPz8gJycpO1xuICByZXR1cm4gbSA/IFtOdW1iZXIobVsxXSksIE51bWJlcihtWzJdKSwgTnVtYmVyKG1bM10pXSA6IG51bGw7XG59XG5cbi8qKlxuICogSG93IGZhciBgcmVzb2x2ZWRgIGlzIGJlaGluZCBgbGF0ZXN0YC5cbiAqXG4gKiBgbnVsbGAgd2hlbiBlaXRoZXIgc2lkZSBpcyB1bnBhcnNlYWJsZSwgTk9UIGAnbm9uZSdgLiBcIldlIGNvdWxkIG5vdCB0ZWxsXCIgYW5kXG4gKiBcIml0IGlzIHVwIHRvIGRhdGVcIiBhcmUgb3Bwb3NpdGUgYW5zd2VycywgYW5kIHJlcG9ydGluZyB0aGUgc2Vjb25kIGZvciB0aGUgZmlyc3RcbiAqIGlzIGhvdyBhIHBpcGVsaW5lIG9uIGFuIGFuY2llbnQgcHJlLXJlbGVhc2UgdmVyc2lvbiBnZXRzIGEgY2xlYW4gYmlsbCBvZiBoZWFsdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJzaW9uR2FwKHJlc29sdmVkOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkLCBsYXRlc3Q6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQpOiBWZXJzaW9uR2FwIHwgbnVsbCB7XG4gIGNvbnN0IGEgPSBzZW12ZXIocmVzb2x2ZWQpO1xuICBjb25zdCBiID0gc2VtdmVyKGxhdGVzdCk7XG4gIGlmICghYSB8fCAhYikgcmV0dXJuIG51bGw7XG4gIGlmIChiWzBdID4gYVswXSkgcmV0dXJuICdtYWpvcic7XG4gIGlmIChiWzBdIDwgYVswXSkgcmV0dXJuICdub25lJzsgLy8gcmVzb2x2ZWQgaXMgYWhlYWQgb2YgXCJsYXRlc3RcIiDigJQgbm90IGJlaGluZFxuICBpZiAoYlsxXSA+IGFbMV0pIHJldHVybiAnbWlub3InO1xuICBpZiAoYlsxXSA8IGFbMV0pIHJldHVybiAnbm9uZSc7XG4gIGlmIChiWzJdID4gYVsyXSkgcmV0dXJuICdwYXRjaCc7XG4gIHJldHVybiAnbm9uZSc7XG59XG5cbi8qKlxuICogUmVwbGFjZSBhIHBpcGVsaW5lJ3MgcmVzb2x1dGlvbiByb3dzLlxuICpcbiAqIERFTEVURS10aGVuLUlOU0VSVCBmb3IgdGhlIHBpcGVsaW5lLCBpbiBvbmUgdHJhbnNhY3Rpb24sIGJlY2F1c2UgYSBzdGVwIGNhbiBiZVxuICogUkVNT1ZFRCBmcm9tIGEgY29uZmlnOiBhbiB1cHNlcnQtb25seSB3cml0ZXIgd291bGQgbGVhdmUgdGhlIGRlbGV0ZWQgc3RlcCdzIHJvd1xuICogYmVoaW5kIGZvcmV2ZXIsIGFuZCB0aGUgb3V0ZGF0ZWQtcGx1Z2luIHNlY3Rpb24gd291bGQga2VlcCByZXBvcnRpbmcgYSBzdGVwIHRoZVxuICogcGlwZWxpbmUgbm8gbG9uZ2VyIGhhcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGxhY2VQaXBlbGluZVJlc29sdXRpb24oXG4gIHBpcGVsaW5lSWQ6IHN0cmluZyxcbiAgc3RlcHM6IHJlYWRvbmx5IFJlc29sdmVkU3RlcFtdLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3QgdmFsdWVzID0gc3RlcHMubWFwKChzKSA9PiAoe1xuICAgIG9yZ0lkOiBzLm9yZ0lkLFxuICAgIHBpcGVsaW5lSWQ6IHMucGlwZWxpbmVJZCxcbiAgICBzdGFnZU5hbWU6IHMuc3RhZ2VOYW1lLFxuICAgIHN0ZXBOYW1lOiBzLnN0ZXBOYW1lLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogcy5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBzLnBsdWdpbk5hbWUsXG4gICAgZGVjbGFyZWRWZXJzaW9uOiBzLmRlY2xhcmVkVmVyc2lvbiA/PyBudWxsLFxuICAgIHJlc29sdmVkVmVyc2lvbjogcy5yZXNvbHZlZFZlcnNpb24gPz8gbnVsbCxcbiAgICBsYXRlc3RWZXJzaW9uOiBzLmxhdGVzdFZlcnNpb24gPz8gbnVsbCxcbiAgICB2ZXJzaW9uR2FwOiB2ZXJzaW9uR2FwKHMucmVzb2x2ZWRWZXJzaW9uLCBzLmxhdGVzdFZlcnNpb24pLFxuICAgIHdpdGhpblBvbGljeTogcy53aXRoaW5Qb2xpY3kgPz8gdHJ1ZSxcbiAgICBjb21wdXRlZEF0OiBuZXcgRGF0ZSgpLFxuICB9KSk7XG5cbiAgcmV0dXJuIHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICBhd2FpdCB0eC5kZWxldGUoc2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbilcbiAgICAgIC53aGVyZShlcShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnBpcGVsaW5lSWQsIHBpcGVsaW5lSWQpKTtcbiAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG4gICAgY29uc3QgbGFuZGVkID0gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24pLnZhbHVlcyh2YWx1ZXMpXG4gICAgICAucmV0dXJuaW5nKHsgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5waXBlbGluZUlkIH0pO1xuICAgIHJldHVybiAobGFuZGVkIGFzIHVua25vd25bXSkubGVuZ3RoO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZWZyZXNoIHRoZSBgbGF0ZXN0YC9nYXAgY29sdW1ucyBmb3Igb25lIHBsdWdpbiBhY3Jvc3MgZXZlcnkgcGlwZWxpbmUgdGhhdCB1c2VzXG4gKiBpdCwgd2l0aG91dCByZS1yZXNvbHZpbmcgYW55dGhpbmcgZWxzZS5cbiAqXG4gKiBDYWxsZWQgb24gcHVibGlzaC4gQSBwdWJsaXNoIGNoYW5nZXMgd2hhdCBcImxhdGVzdFwiIG1lYW5zIGZvciBldmVyeSBwaXBlbGluZSBpblxuICogdGhlIGluc3RhbmNlIHRoYXQgZGVjbGFyZXMgdGhlIHBsdWdpbiwgYW5kIHJlLXJlc29sdmluZyBlYWNoIG9mIHRob3NlIHBpcGVsaW5lc1xuICogZnJvbSBzY3JhdGNoIHdvdWxkIG1ha2UgcHVibGlzaGluZyBjb3N0IE8ocGlwZWxpbmVzKSB3b3JrIOKAlCBzbyBvbmx5IHRoZSB0d29cbiAqIGNvbHVtbnMgYSBwdWJsaXNoIGNhbiBjaGFuZ2UgYXJlIHRvdWNoZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWZyZXNoTGF0ZXN0Rm9yUGx1Z2luKFxuICBwbHVnaW5OYW1lOiBzdHJpbmcsXG4gIHBsdWdpblB1Ymxpc2hlcjogc3RyaW5nIHwgbnVsbCxcbiAgbGF0ZXN0VmVyc2lvbjogc3RyaW5nLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LnVwZGF0ZShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uKVxuICAgIC5zZXQoe1xuICAgICAgbGF0ZXN0VmVyc2lvbixcbiAgICAgIC8vIFJlY29tcHV0ZWQgaW4gU1FMIGZyb20gdGhlIHJvdydzIG93biByZXNvbHZlZCB2ZXJzaW9uLCBzbyBvbmUgc3RhdGVtZW50XG4gICAgICAvLyBjb3ZlcnMgZXZlcnkgcGlwZWxpbmUgcmF0aGVyIHRoYW4gYSByb3VuZCB0cmlwIGVhY2guXG4gICAgICAvLyBgOjp0ZXh0YCBvbiBldmVyeSBiaW5kIG9mIHRoZSB2ZXJzaW9uOiBQb3N0Z3JlcyBvdGhlcndpc2UgZGVkdWNlc1xuICAgICAgLy8gaW5jb25zaXN0ZW50IHR5cGVzIGZvciB0aGUgc2FtZSBwYXJhbWV0ZXIgKHZhcmNoYXIgZm9yIHRoZSBhc3NpZ25tZW50LFxuICAgICAgLy8gdGV4dCBmb3IgYHNwbGl0X3BhcnRgKSBhbmQgcmVmdXNlcyB0byBwbGFuIHRoZSBzdGF0ZW1lbnQuXG4gICAgICB2ZXJzaW9uR2FwOiBzcWxgQ0FTRVxuICAgICAgICBXSEVOICR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259IElTIE5VTEwgVEhFTiBOVUxMXG4gICAgICAgIFdIRU4gc3BsaXRfcGFydCgke2xhdGVzdFZlcnNpb259Ojp0ZXh0LCAnLicsIDEpOjppbnQgPiBzcGxpdF9wYXJ0KCR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259LCAnLicsIDEpOjppbnQgVEhFTiAnbWFqb3InXG4gICAgICAgIFdIRU4gc3BsaXRfcGFydCgke2xhdGVzdFZlcnNpb259Ojp0ZXh0LCAnLicsIDEpOjppbnQgPCBzcGxpdF9wYXJ0KCR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259LCAnLicsIDEpOjppbnQgVEhFTiAnbm9uZSdcbiAgICAgICAgV0hFTiBzcGxpdF9wYXJ0KCR7bGF0ZXN0VmVyc2lvbn06OnRleHQsICcuJywgMik6OmludCA+IHNwbGl0X3BhcnQoJHtzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnJlc29sdmVkVmVyc2lvbn0sICcuJywgMik6OmludCBUSEVOICdtaW5vcidcbiAgICAgICAgV0hFTiBzcGxpdF9wYXJ0KCR7bGF0ZXN0VmVyc2lvbn06OnRleHQsICcuJywgMik6OmludCA8IHNwbGl0X3BhcnQoJHtzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnJlc29sdmVkVmVyc2lvbn0sICcuJywgMik6OmludCBUSEVOICdub25lJ1xuICAgICAgICBXSEVOIHNwbGl0X3BhcnQoJHtsYXRlc3RWZXJzaW9ufTo6dGV4dCwgJy4nLCAzKTo6aW50ID4gc3BsaXRfcGFydCgke3NjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucmVzb2x2ZWRWZXJzaW9ufSwgJy4nLCAzKTo6aW50IFRIRU4gJ3BhdGNoJ1xuICAgICAgICBFTFNFICdub25lJyBFTkRgLFxuICAgICAgY29tcHV0ZWRBdDogbmV3IERhdGUoKSxcbiAgICB9KVxuICAgIC53aGVyZShhbmQoXG4gICAgICBlcShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnBsdWdpbk5hbWUsIHBsdWdpbk5hbWUpLFxuICAgICAgcGx1Z2luUHVibGlzaGVyID09PSBudWxsXG4gICAgICAgID8gaXNOdWxsKHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucGx1Z2luUHVibGlzaGVyKVxuICAgICAgICA6IGVxKHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucGx1Z2luUHVibGlzaGVyLCBwbHVnaW5QdWJsaXNoZXIpLFxuICAgICAgLy8gT25seSByb3dzIHdob3NlIHJlc29sdmVkIHZlcnNpb24gcGFyc2VzIGFzIHNlbXZlcjsgYW55dGhpbmcgZWxzZSBoYXMgbm9cbiAgICAgIC8vIGdhcCB0byBjb21wdXRlIGFuZCB0aGUgQ0FTRSB3b3VsZCB0aHJvdyBvbiB0aGUgY2FzdC5cbiAgICAgIHNxbGAke3NjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucmVzb2x2ZWRWZXJzaW9ufSB+ICdeWzAtOV0rXFxcXC5bMC05XStcXFxcLlswLTldKydgLFxuICAgICkpXG4gICAgLnJldHVybmluZyh7IHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucGlwZWxpbmVJZCB9KSk7XG4gIHJldHVybiAocm93cyBhcyB1bmtub3duW10pLmxlbmd0aDtcbn1cblxuLyoqIE9uZSBmbGFnZ2VkIHZlcnNpb24sIGFzIHRoZSByZXNjYW4gcmVwb3J0cyBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3N1cmVJbnB1dCB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHBpcGVsaW5lSWQ6IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyPzogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBwbHVnaW5WZXJzaW9uOiBzdHJpbmc7XG4gIGltYWdlRGlnZXN0Pzogc3RyaW5nIHwgbnVsbDtcbiAgc291cmNlOiBFeHBvc3VyZVNvdXJjZTtcbiAgY3JpdGljYWxDb3VudDogbnVtYmVyO1xuICBoaWdoQ291bnQ6IG51bWJlcjtcbiAgdG9wRmluZGluZ3M/OiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG59XG5cbi8qKlxuICogT3BlbiBvciByZWZyZXNoIGV4cG9zdXJlcy5cbiAqXG4gKiBVcHNlcnRzIG9uIChwaXBlbGluZSwgcGx1Z2luLCB2ZXJzaW9uLCBzb3VyY2UpIHNvIGEgbmlnaHRseSByZXNjYW4gUkVGUkVTSEVTIHRoZVxuICogY291bnRzIHJhdGhlciB0aGFuIG9wZW5pbmcgYSBuZXcgcm93IGV2ZXJ5IG5pZ2h0IOKAlCBvdGhlcndpc2UgdGhlIHJlcG9ydCB3b3VsZFxuICogc2hvdyBvbmUgZXhwb3N1cmUgcGVyIG5pZ2h0IG9mIHRoZSBzYW1lIHByb2JsZW0sIHdoaWNoIHJlYWRzIGFzIGFuIGVzY2FsYXRpbmdcbiAqIHNpdHVhdGlvbiB3aGVuIG5vdGhpbmcgY2hhbmdlZC5cbiAqXG4gKiBBIHJlZnJlc2ggZGVsaWJlcmF0ZWx5IGRvZXMgTk9UIHJlc2V0IGB0cmlhZ2Vfc3RhdGVgOiBhbiBvcmcgdGhhdCBhY2NlcHRlZCBhXG4gKiBmaW5kaW5nIHdpdGggYSByZWFzb24gYW5kIGEgZGVhZGxpbmUgaGFzIG1hZGUgYSBkZWNpc2lvbiwgYW5kIHJlLXJhaXNpbmcgaXQgZXZlcnlcbiAqIG5pZ2h0IGlzIGhvdyBhIHRlYW0gbGVhcm5zIHRvIGlnbm9yZSB0aGUgcmVwb3J0LiBJdCBET0VTIGNsZWFyIGEgc3RhbGVcbiAqIGFjY2VwdGFuY2UsIGJlY2F1c2UgdGhhdCBpcyB3aGF0IHRoZSBkZWFkbGluZSB3YXMgZm9yLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdXBzZXJ0RXhwb3N1cmVzKGlucHV0czogcmVhZG9ubHkgRXhwb3N1cmVJbnB1dFtdLCBub3cgPSBuZXcgRGF0ZSgpKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDApIHJldHVybiAwO1xuICBjb25zdCB2YWx1ZXMgPSBpbnB1dHMubWFwKChlKSA9PiAoe1xuICAgIGlkOiByYW5kb21VVUlEKCksXG4gICAgb3JnSWQ6IGUub3JnSWQsXG4gICAgcGlwZWxpbmVJZDogZS5waXBlbGluZUlkLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogZS5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBlLnBsdWdpbk5hbWUsXG4gICAgcGx1Z2luVmVyc2lvbjogZS5wbHVnaW5WZXJzaW9uLFxuICAgIGltYWdlRGlnZXN0OiBlLmltYWdlRGlnZXN0ID8/IG51bGwsXG4gICAgc291cmNlOiBlLnNvdXJjZSxcbiAgICBjcml0aWNhbENvdW50OiBlLmNyaXRpY2FsQ291bnQsXG4gICAgaGlnaENvdW50OiBlLmhpZ2hDb3VudCxcbiAgICB0b3BGaW5kaW5nczogZS50b3BGaW5kaW5ncyA/PyBbXSxcbiAgICBmbGFnZ2VkQXQ6IG5vdyxcbiAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgfSkpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgbGFuZGVkID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguaW5zZXJ0KHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUpLnZhbHVlcyh2YWx1ZXMpXG4gICAgICAub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgdGFyZ2V0OiBbXG4gICAgICAgICAgc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5waXBlbGluZUlkLFxuICAgICAgICAgIHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luTmFtZSxcbiAgICAgICAgICBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpblZlcnNpb24sXG4gICAgICAgICAgc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5zb3VyY2UsXG4gICAgICAgIF0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIGNyaXRpY2FsQ291bnQ6IHNxbGBleGNsdWRlZC5jcml0aWNhbF9jb3VudGAsXG4gICAgICAgICAgaGlnaENvdW50OiBzcWxgZXhjbHVkZWQuaGlnaF9jb3VudGAsXG4gICAgICAgICAgdG9wRmluZGluZ3M6IHNxbGBleGNsdWRlZC50b3BfZmluZGluZ3NgLFxuICAgICAgICAgIGltYWdlRGlnZXN0OiBzcWxgQ09BTEVTQ0UoZXhjbHVkZWQuaW1hZ2VfZGlnZXN0LCAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaW1hZ2VEaWdlc3R9KWAsXG4gICAgICAgICAgLy8gU3RpbGwgZXhwb3NlZCwgc28gdGhlIGZpeCBtYXJrZXIgaXMgY2xlYXJlZDogYSByb3cgdGhhdCB3YXMgY2xvc2VkIGJ5IGFcbiAgICAgICAgICAvLyBkZXBsb3kgYW5kIGlzIGZsYWdnZWQgYWdhaW4gaXMgYSByZWdyZXNzaW9uLCBhbmQgbGVhdmluZyBgZml4ZWRfYXRgIHNldFxuICAgICAgICAgIC8vIHdvdWxkIGhpZGUgaXQuXG4gICAgICAgICAgZml4ZWRBdDogbnVsbCxcbiAgICAgICAgICAvLyBBbiBhY2NlcHRhbmNlIHBhc3QgaXRzIGRlYWRsaW5lIHN0b3BzIGJlaW5nIGFuIGFjY2VwdGFuY2UuIFRoYXQgaXMgdGhlXG4gICAgICAgICAgLy8gZW50aXJlIHBvaW50IG9mIHRpbWUtYm94aW5nIGl0LCBhbmQgaXQgaXMgZW5mb3JjZWQgSEVSRSByYXRoZXIgdGhhbiBhdFxuICAgICAgICAgIC8vIHJlYWQgdGltZSBzbyB0aGUgc3RvcmVkIHN0YXRlIGlzIHRoZSB0cnV0aC5cbiAgICAgICAgICB0cmlhZ2VTdGF0ZTogc3FsYENBU0VcbiAgICAgICAgICAgIFdIRU4gJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnRyaWFnZVN0YXRlfSA9ICdhY2NlcHRlZCdcbiAgICAgICAgICAgICBBTkQgJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmFjY2VwdGVkVW50aWx9IElTIE5PVCBOVUxMXG4gICAgICAgICAgICAgQU5EICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZFVudGlsfSA8PSAke25vd31cbiAgICAgICAgICAgIFRIRU4gJ29wZW4nXG4gICAgICAgICAgICBXSEVOICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gPSAnZml4ZWQnIFRIRU4gJ29wZW4nXG4gICAgICAgICAgICBFTFNFICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gRU5EYCxcbiAgICAgICAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgICAucmV0dXJuaW5nKHsgaWQ6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaWQgfSkpO1xuICAgIHJldHVybiAobGFuZGVkIGFzIHVua25vd25bXSkubGVuZ3RoO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignUGx1Z2luIGV4cG9zdXJlIHVwc2VydCBmYWlsZWQnLCB7IGNvdW50OiB2YWx1ZXMubGVuZ3RoLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuLyoqXG4gKiBDbG9zZSB0aGUgZXhwb3N1cmVzIGEgcGlwZWxpbmUgaGFzIG1vdmVkIG9mZi5cbiAqXG4gKiBDYWxsZWQgd2hlbiBhIGRlcGxveSByZWNvcmRzIGEgbmV3IHN0ZXAgbWFuaWZlc3Q6IGFueXRoaW5nIGZsYWdnZWQgZm9yIHRoYXRcbiAqIHBpcGVsaW5lIHdob3NlIHZlcnNpb24gaXMgTk9UIGluIHRoZSBzZXQgaXQgbm93IHJ1bnMgaXMgZml4ZWQuIENsb3NpbmcgYnlcbiAqIGFic2VuY2UgcmF0aGVyIHRoYW4gd2FpdGluZyBmb3IgYSByZXNjYW4gdG8gbm90aWNlIGlzIHdoYXQgbWFrZXMgXCJ3ZSBmaXhlZCBpdFwiXG4gKiBzaG93IHVwIGluIHRoZSByZXBvcnQgb24gdGhlIG5leHQgZGVwbG95IGluc3RlYWQgb2YgdGhlIG5leHQgbmlnaHQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZUZpeGVkRXhwb3N1cmVzKFxuICBwaXBlbGluZUlkOiBzdHJpbmcsXG4gIGxpdmVWZXJzaW9uczogUmVhZG9ubHlBcnJheTx7IHBsdWdpbk5hbWU6IHN0cmluZzsgcGx1Z2luVmVyc2lvbjogc3RyaW5nIH0+LFxuICBub3cgPSBuZXcgRGF0ZSgpLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3QgbGl2ZSA9IG5ldyBTZXQobGl2ZVZlcnNpb25zLm1hcCgodikgPT4gYCR7di5wbHVnaW5OYW1lfUAke3YucGx1Z2luVmVyc2lvbn1gKSk7XG4gIGNvbnN0IG9wZW4gPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3Qoe1xuICAgIGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLFxuICAgIHBsdWdpbk5hbWU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luTmFtZSxcbiAgICBwbHVnaW5WZXJzaW9uOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpblZlcnNpb24sXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5waXBlbGluZUlkLCBwaXBlbGluZUlkKSxcbiAgICAgIGlzTnVsbChzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmZpeGVkQXQpLFxuICAgICkpKTtcbiAgY29uc3Qgc3RhbGUgPSAob3BlbiBhcyBBcnJheTx7IGlkOiBzdHJpbmc7IHBsdWdpbk5hbWU6IHN0cmluZzsgcGx1Z2luVmVyc2lvbjogc3RyaW5nIH0+KVxuICAgIC5maWx0ZXIoKHIpID0+ICFsaXZlLmhhcyhgJHtyLnBsdWdpbk5hbWV9QCR7ci5wbHVnaW5WZXJzaW9ufWApKVxuICAgIC5tYXAoKHIpID0+IHIuaWQpO1xuICBpZiAoc3RhbGUubGVuZ3RoID09PSAwKSByZXR1cm4gMDtcblxuICBjb25zdCBjbG9zZWQgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC51cGRhdGUoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAuc2V0KHsgZml4ZWRBdDogbm93LCB0cmlhZ2VTdGF0ZTogJ2ZpeGVkJywgdXBkYXRlZEF0OiBub3cgfSlcbiAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLCBzdGFsZSkpXG4gICAgLnJldHVybmluZyh7IGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkIH0pKTtcbiAgcmV0dXJuIChjbG9zZWQgYXMgdW5rbm93bltdKS5sZW5ndGg7XG59XG5cbi8qKlxuICogVGhlIG9yZydzIGxpdmUgZXhwb3N1cmVzLCBmb3IgdGhlIHJlcG9ydCBzZWN0aW9uLlxuICpcbiAqIGBhY2NlcHRlZGAgcm93cyB3aG9zZSBkZWFkbGluZSBoYXMgcGFzc2VkIGNvbWUgYmFjayBhcyBPUEVOIGV2ZW4gaWYgbm8gcmVzY2FuXG4gKiBoYXMgcmVmcmVzaGVkIHRoZW0geWV0OiBhIHJlYWQgbXVzdCBub3QgcHJlc2VudCBhbiBleHBpcmVkIGFjY2VwdGFuY2UgYXMgYVxuICogY3VycmVudCBvbmUsIGFuZCB0aGUgcmVwb3J0IGlzIHJlYWQgZmFyIG1vcmUgb2Z0ZW4gdGhhbiB0aGUgcmVzY2FuIHJ1bnMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuRXhwb3N1cmVzKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEFycmF5PHtcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyOiBzdHJpbmcgfCBudWxsO1xuICBzb3VyY2U6IEV4cG9zdXJlU291cmNlO1xuICBjcml0aWNhbENvdW50OiBudW1iZXI7XG4gIGhpZ2hDb3VudDogbnVtYmVyO1xuICB0b3BGaW5kaW5nczogQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICB0cmlhZ2VTdGF0ZTogc3RyaW5nO1xuICBmbGFnZ2VkQXQ6IERhdGU7XG59Pj4ge1xuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguc2VsZWN0KHtcbiAgICBwaXBlbGluZUlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBpcGVsaW5lSWQsXG4gICAgcGx1Z2luTmFtZTogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5wbHVnaW5OYW1lLFxuICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luVmVyc2lvbixcbiAgICBwbHVnaW5QdWJsaXNoZXI6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luUHVibGlzaGVyLFxuICAgIHNvdXJjZTogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5zb3VyY2UsXG4gICAgY3JpdGljYWxDb3VudDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5jcml0aWNhbENvdW50LFxuICAgIGhpZ2hDb3VudDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5oaWdoQ291bnQsXG4gICAgdG9wRmluZGluZ3M6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudG9wRmluZGluZ3MsXG4gICAgdHJpYWdlU3RhdGU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudHJpYWdlU3RhdGUsXG4gICAgYWNjZXB0ZWRVbnRpbDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZFVudGlsLFxuICAgIGZsYWdnZWRBdDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5mbGFnZ2VkQXQsXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5vcmdJZCwgb3JnSWQpLFxuICAgICAgaXNOdWxsKHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuZml4ZWRBdCksXG4gICAgICAvLyBBbiBhY2NlcHRhbmNlIHRoYXQgaGFzIHJ1biBvdXQgaXMgbm90IGFuIGFjY2VwdGFuY2UuXG4gICAgICBzcWxgKCR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gPD4gJ2FjY2VwdGVkJ1xuICAgICAgICAgICBPUiAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuYWNjZXB0ZWRVbnRpbH0gSVMgTlVMTFxuICAgICAgICAgICBPUiAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuYWNjZXB0ZWRVbnRpbH0gPD0gJHtub3d9KWAsXG4gICAgKSlcbiAgICAub3JkZXJCeShzcWxgJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmNyaXRpY2FsQ291bnR9IERFU0MsICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5oaWdoQ291bnR9IERFU0NgKSk7XG5cbiAgcmV0dXJuIChyb3dzIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PikubWFwKChyKSA9PiAoe1xuICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCBhcyBzdHJpbmcsXG4gICAgcGx1Z2luTmFtZTogci5wbHVnaW5OYW1lIGFzIHN0cmluZyxcbiAgICBwbHVnaW5WZXJzaW9uOiByLnBsdWdpblZlcnNpb24gYXMgc3RyaW5nLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogKHIucGx1Z2luUHVibGlzaGVyIGFzIHN0cmluZyB8IG51bGwpID8/IG51bGwsXG4gICAgc291cmNlOiByLnNvdXJjZSBhcyBFeHBvc3VyZVNvdXJjZSxcbiAgICBjcml0aWNhbENvdW50OiByLmNyaXRpY2FsQ291bnQgYXMgbnVtYmVyLFxuICAgIGhpZ2hDb3VudDogci5oaWdoQ291bnQgYXMgbnVtYmVyLFxuICAgIHRvcEZpbmRpbmdzOiAoci50b3BGaW5kaW5ncyBhcyBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pID8/IFtdLFxuICAgIC8vIEFuIGV4cGlyZWQgYWNjZXB0YW5jZSByZWFkcyBhcyBvcGVuLCB3aGljaCBpcyB3aGF0IGl0IGlzLlxuICAgIHRyaWFnZVN0YXRlOiByLnRyaWFnZVN0YXRlID09PSAnYWNjZXB0ZWQnICYmIHIuYWNjZXB0ZWRVbnRpbCA/ICdvcGVuJyA6IChyLnRyaWFnZVN0YXRlIGFzIHN0cmluZyksXG4gICAgZmxhZ2dlZEF0OiByLmZsYWdnZWRBdCBhcyBEYXRlLFxuICB9KSk7XG59XG5cbi8qKlxuICogUmVjb3JkIGEgdHJpYWdlIGRlY2lzaW9uLlxuICpcbiAqIGBhY2NlcHRlZGAgUkVRVUlSRVMgYSBkZWFkbGluZSBhbmQgYSByZWFzb24uIEEgcGVybWFuZW50LCB1bmV4cGxhaW5lZCBtdXRlIGlzXG4gKiBob3cgYSBmaW5kaW5nIHN0b3BzIGJlaW5nIGFueWJvZHkncyBwcm9ibGVtLCBhbmQgdGhlcmUgaXMgbm8gZ29vZCByZWFzb24gdG9cbiAqIHN1cHBvcnQgaXQg4oCUIHRoZSBjYWxsZXIgZ2V0cyBhbiBlcnJvciByYXRoZXIgdGhhbiBhIHNpbGVudGx5IHVuYm91bmRlZFxuICogYWNjZXB0YW5jZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRyaWFnZUV4cG9zdXJlKFxuICBvcmdJZDogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBkZWNpc2lvbjogeyBzdGF0ZTogJ29wZW4nIHwgJ2FjY2VwdGVkJyB8ICdmYWxzZV9wb3NpdGl2ZSc7IHJlYXNvbj86IHN0cmluZzsgYWNjZXB0ZWRVbnRpbD86IERhdGU7IGFjdG9yOiBzdHJpbmcgfSxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBpZiAoZGVjaXNpb24uc3RhdGUgPT09ICdhY2NlcHRlZCcgJiYgKCFkZWNpc2lvbi5hY2NlcHRlZFVudGlsIHx8ICFkZWNpc2lvbi5yZWFzb24/LnRyaW0oKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjY2VwdGluZyBhIHZ1bG5lcmFiaWxpdHkgZXhwb3N1cmUgbmVlZHMgYSByZWFzb24gYW5kIGFuIGV4cGlyeSBkYXRlJyk7XG4gIH1cbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LnVwZGF0ZShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlKVxuICAgIC5zZXQoe1xuICAgICAgdHJpYWdlU3RhdGU6IGRlY2lzaW9uLnN0YXRlLFxuICAgICAgYWNjZXB0ZWRVbnRpbDogZGVjaXNpb24uc3RhdGUgPT09ICdhY2NlcHRlZCcgPyAoZGVjaXNpb24uYWNjZXB0ZWRVbnRpbCA/PyBudWxsKSA6IG51bGwsXG4gICAgICB0cmlhZ2VSZWFzb246IGRlY2lzaW9uLnJlYXNvbiA/PyBudWxsLFxuICAgICAgdHJpYWdlZEJ5OiBkZWNpc2lvbi5hY3RvcixcbiAgICAgIHRyaWFnZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICB9KVxuICAgIC53aGVyZShhbmQoXG4gICAgICBlcShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLCBpZCksXG4gICAgICBlcShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLm9yZ0lkLCBvcmdJZCksXG4gICAgKSlcbiAgICAucmV0dXJuaW5nKHsgaWQ6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaWQgfSkpO1xuICByZXR1cm4gKHJvd3MgYXMgdW5rbm93bltdKS5sZW5ndGggPiAwO1xufVxuXG4vKipcbiAqIEV4cG9zdXJlcyB3aG9zZSBhY2NlcHRhbmNlIGhhcyBsYXBzZWQsIGZvciB0aGUgb3JnJ3Mgc2VjdXJpdHkgbm90aWZpY2F0aW9ucy5cbiAqXG4gKiBTdXJmYWNlZCByYXRoZXIgdGhhbiBzaWxlbnRseSByZW9wZW5lZDogc29tZWJvZHkgZGVjaWRlZCB0byBhY2NlcHQgdGhpcyB1bnRpbCBhXG4gKiBkYXRlLCB0aGF0IGRhdGUgaGFzIHBhc3NlZCwgYW5kIHRoZSBwZXJzb24gd2hvIGRlY2lkZWQgaXMgdGhlIG9uZSB3aG8gc2hvdWxkXG4gKiBoZWFyIGFib3V0IGl0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGFwc2VkQWNjZXB0YW5jZXMob3JnSWQ6IHN0cmluZywgbm93ID0gbmV3IERhdGUoKSk6IFByb21pc2U8QXJyYXk8e1xuICBpZDogc3RyaW5nO1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZztcbiAgdHJpYWdlZEJ5OiBzdHJpbmcgfCBudWxsO1xuICBhY2NlcHRlZFVudGlsOiBEYXRlIHwgbnVsbDtcbn0+PiB7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3Qoe1xuICAgIGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLFxuICAgIHBsdWdpbk5hbWU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luTmFtZSxcbiAgICBwbHVnaW5WZXJzaW9uOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpblZlcnNpb24sXG4gICAgdHJpYWdlZEJ5OiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnRyaWFnZWRCeSxcbiAgICBhY2NlcHRlZFVudGlsOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmFjY2VwdGVkVW50aWwsXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5vcmdJZCwgb3JnSWQpLFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZSwgJ2FjY2VwdGVkJyksXG4gICAgICBpc051bGwoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5maXhlZEF0KSxcbiAgICAgIGx0ZShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmFjY2VwdGVkVW50aWwsIG5vdyksXG4gICAgKSkpO1xuICByZXR1cm4gcm93cyBhcyBBcnJheTx7IGlkOiBzdHJpbmc7IHBsdWdpbk5hbWU6IHN0cmluZzsgcGx1Z2luVmVyc2lvbjogc3RyaW5nOyB0cmlhZ2VkQnk6IHN0cmluZyB8IG51bGw7IGFjY2VwdGVkVW50aWw6IERhdGUgfCBudWxsIH0+O1xufVxuIl19
697
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWV4cG9zdXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvcGx1Z2luLWV4cG9zdXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUErQyxNQUFNLDRCQUE0QixDQUFDO0FBQ2pKLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBWSxNQUFNLGFBQWEsQ0FBQztBQUMzRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBeUIvQywwREFBMEQ7QUFDMUQsU0FBUyxNQUFNLENBQUMsQ0FBNEI7SUFDMUMsTUFBTSxDQUFDLEdBQUcsd0JBQXdCLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNqRCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDL0QsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsUUFBbUMsRUFBRSxN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QUMsRUFDckQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsRUFDekMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsR0FBRyxDQUFDLENBQ2xELENBQUMsQ0FBQyxDQUFDO0lBQ04sT0FBTyxJQUE4SCxDQUFDO0FBQ3hJLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBXaGF0IHBsdWdpbiB2ZXJzaW9ucyBhbiBvcmcncyBwaXBlbGluZXMgYXJlIGFjdHVhbGx5IG9uLCBhbmQgd2hpY2ggb2YgdGhvc2UgYXJlXG4gKiBrbm93bi12dWxuZXJhYmxlLlxuICpcbiAqIFR3byB0YWJsZXMsIHdyaXR0ZW4gaGVyZSwgcmVhZCBieSB0aGUgb3V0ZGF0ZWQtcGx1Z2luIGFuZCB2dWxuZXJhYmlsaXR5IHJlcG9ydFxuICogc2VjdGlvbnM6XG4gKlxuICogIC0gYHBpcGVsaW5lX3BsdWdpbl9yZXNvbHV0aW9uYCDigJQgdGhlIERFQ0xBUkVEIHNpZGUuIFJlY29tcHV0ZWQgb24gcGlwZWxpbmVcbiAqICAgIHdyaXRlIGFuZCBvbiBwbHVnaW4gcHVibGlzaCwgYmVjYXVzZSB0aGUgYWx0ZXJuYXRpdmUgaXMgcmVzb2x2aW5nIGV2ZXJ5IHN0ZXBcbiAqICAgIG9mIGV2ZXJ5IHBpcGVsaW5lIGFnYWluc3QgdGhlIGNhdGFsb2cgb24gZXZlcnkgcmVhZCwgYW5kIHRoYXQgaXMgbm90IGEgcXVlcnlcbiAqICAgIGFueW9uZSBjYW4gYWZmb3JkIHRvIHB1dCBpbiBhIHJlcG9ydC5cbiAqICAtIGBwbHVnaW5fdnVsbl9leHBvc3VyZWAg4oCUIHRoZSBWVUxORVJBQkxFIHNpZGUsIHBlciBQSVBFTElORS4gQSB2ZXJzaW9uLWxldmVsXG4gKiAgICB0YWJsZSB3b3VsZCBmb3JjZSBldmVyeSByZWFkZXIgdG8gcmUtZGVyaXZlIFwid2hpY2ggb2Ygb3VyIHBpcGVsaW5lcyBpc1xuICogICAgZXhwb3NlZFwiLCB3aGljaCBpcyB0aGUgb25seSBmb3JtIG9mIHRoZSBxdWVzdGlvbiBhbnlib2R5IGFza3MuXG4gKlxuICogREVDTEFSRUQgSVMgTk9UIERFUExPWUVELCBhbmQgdGhlIHJlcG9ydCBzYXlzIHdoaWNoIGl0IGlzIHNob3dpbmcuIEEgcGlwZWxpbmUnc1xuICogY29uZmlnIGRlY2xhcmVzIGBeMi4wLjBgOyB3aGF0IHJhbiBhdCBpdHMgbGFzdCBkZXBsb3kgaXMgd2hhdGV2ZXIgdGhlIHN0ZXBcbiAqIG1hbmlmZXN0IHJlY29yZGVkLCBwaW5uZWQgdG8gYSBkaWdlc3QuIFRob3NlIGRpc2FncmVlIHdoZW5ldmVyIGEgcGlwZWxpbmUgaGFzIG5vdFxuICogcmUtc3ludGhlZCBzaW5jZSBhIHB1Ymxpc2gg4oCUIHdoaWNoIGlzIG1vc3Qgb2YgdGhlIHRpbWUsIGFuZCBleGFjdGx5IHRoZSBnYXAgYVxuICogdnVsbmVyYWJpbGl0eSByZXBvcnQgaXMgZm9yLiBDb25mbGF0aW5nIHRoZW0gd291bGQgbGV0IGEgcmVwb3J0IHNheSBcImZpeGVkXCJcbiAqIGFib3V0IGEgcGlwZWxpbmUgc3RpbGwgcnVubmluZyB0aGUgb2xkIGltYWdlLlxuICpcbiAqIFdITyBXUklURVMgV0hBVDpcbiAqICAtIHRoZSBwaXBlbGluZSBzZXJ2aWNlLCBvbiBhIHBpcGVsaW5lIHdyaXRlOiBgcmVwbGFjZVBpcGVsaW5lUmVzb2x1dGlvbmAgK1xuICogICAgYHJlY29uY2lsZVBpcGVsaW5lRXhwb3N1cmVzKHNvdXJjZSAnZGVjbGFyZWQnKWA7XG4gKiAgLSB0aGUgcGlwZWxpbmUgc2VydmljZSwgb24gYSBkZXBsb3kgcmVnaXN0cmF0aW9uIGNhcnJ5aW5nIGEgc3RlcCBtYW5pZmVzdDpcbiAqICAgIGByZWNvbmNpbGVQaXBlbGluZUV4cG9zdXJlcyhzb3VyY2UgJ2RlcGxveWVkJylgO1xuICogIC0gdGhlIHBsdWdpbiBzZXJ2aWNlLCB3aGVuIGEgdmVyc2lvbiBiZWNvbWVzIHRoZSBsYXRlc3QgKGFuIG9yZyBwbHVnaW4ncyBuZXdcbiAqICAgIGRlZmF1bHQ7IGEgbGlzdGluZydzIHB1Ymxpc2gsIHlhbmsgb3IgdW55YW5rKTogYHJlZnJlc2hMYXRlc3RGb3JQbHVnaW5gO1xuICogIC0gdGhlIG5pZ2h0bHkgcmVzY2FuLCBwZXIgcmVzY2FubmVkIHZlcnNpb246IGBzeW5jVmVyc2lvbkV4cG9zdXJlc2AsIHdoaWNoXG4gKiAgICBmYW5zIHRoZSB2ZXJzaW9uJ3MgZmluZGluZ3Mgb3V0IHRvIGV2ZXJ5IHBpcGVsaW5lIGRlY2xhcmluZyBvciBydW5uaW5nIGl0XG4gKiAgICAob3IgY2xvc2VzIHRoZW0gd2hlbiB0aGUgdmVyc2lvbiBjYW1lIGJhY2sgY2xlYW4pLlxuICovXG5cbmltcG9ydCB7IHJhbmRvbVVVSUQgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBhc1NjYW5GbGFnLCBjcmVhdGVMb2dnZXIsIGVycm9yTWVzc2FnZSwgc2NhbkZpbmRpbmdLZXksIHR5cGUgUGx1Z2luU2NhbkZpbmRpbmcsIHR5cGUgVnVsbkFjY2VwdGFuY2UgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBhbmQsIGVxLCBpbkFycmF5LCBpc051bGwsIGx0ZSwgc3FsLCB0eXBlIFNRTCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IHNjaGVtYSB9IGZyb20gJy4uLy4uL2RhdGFiYXNlL2RyaXp6bGUtc2NoZW1hLmpzJztcbmltcG9ydCB0eXBlIHsgRXhwb3N1cmVTb3VyY2UgfSBmcm9tICcuLi8uLi9kYXRhYmFzZS9zY2hlbWEvcmVwb3J0aW5nLWFuYWx5dGljcy5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHggfSBmcm9tICcuLi8uLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdwbHVnaW4tZXhwb3N1cmUnKTtcblxuLyoqIEhvdyBmYXIgYmVoaW5kIGEgcmVzb2x2ZWQgdmVyc2lvbiBpcyBmcm9tIHRoZSBuZXdlc3Qgb25lIGF2YWlsYWJsZS4gKi9cbmV4cG9ydCB0eXBlIFZlcnNpb25HYXAgPSAnbWFqb3InIHwgJ21pbm9yJyB8ICdwYXRjaCcgfCAnbm9uZSc7XG5cbi8qKiBPbmUgcmVzb2x2ZWQgc3RlcCwgYXMgdGhlIHdyaXRlciB0YWtlcyBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRTdGVwIHtcbiAgb3JnSWQ6IHN0cmluZztcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBzdGFnZU5hbWU6IHN0cmluZztcbiAgc3RlcE5hbWU6IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyPzogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBkZWNsYXJlZFZlcnNpb24/OiBzdHJpbmcgfCBudWxsO1xuICByZXNvbHZlZFZlcnNpb24/OiBzdHJpbmcgfCBudWxsO1xuICAvKiogVGhlIHJlc29sdmVkIHJlY29yZDogYSBgcGx1Z2luc2Agcm93IGlkIG9yIGEgbGlzdGluZyB2ZXJzaW9uIGlkLiAqL1xuICByZXNvbHZlZFBsdWdpbklkPzogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIFRoZSBpbWFnZSBkaWdlc3QgdGhlIHJlc29sdmVkIHZlcnNpb24gaXMgcGlubmVkIHRvIChudWxsID0gaW1hZ2UtbGVzcykuICovXG4gIHJlc29sdmVkRGlnZXN0Pzogc3RyaW5nIHwgbnVsbDtcbiAgbGF0ZXN0VmVyc2lvbj86IHN0cmluZyB8IG51bGw7XG4gIHdpdGhpblBvbGljeT86IGJvb2xlYW47XG4gIC8qKiBUaGUgcm9vdCBvcmcgb2YgYSB0ZWFtJ3MgcGlwZWxpbmUgKHNlZSB0aGUgY29sdW1uKS4gKi9cbiAgcm9vdE9yZ0lkPzogc3RyaW5nIHwgbnVsbDtcbn1cblxuLyoqIGAxLjIuM2Ag4oaSIGBbMSwgMiwgM11gOyBhbnl0aGluZyB1bnBhcnNlYWJsZSDihpIgbnVsbC4gKi9cbmZ1bmN0aW9uIHNlbXZlcih2OiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVsbCB7XG4gIGNvbnN0IG0gPSAvXnY/KFxcZCspXFwuKFxcZCspXFwuKFxcZCspLy5leGVjKHYgPz8gJycpO1xuICByZXR1cm4gbSA/IFtOdW1iZXIobVsxXSksIE51bWJlcihtWzJdKSwgTnVtYmVyKG1bM10pXSA6IG51bGw7XG59XG5cbi8qKlxuICogSG93IGZhciBgcmVzb2x2ZWRgIGlzIGJlaGluZCBgbGF0ZXN0YC5cbiAqXG4gKiBgbnVsbGAgd2hlbiBlaXRoZXIgc2lkZSBpcyB1bnBhcnNlYWJsZSwgTk9UIGAnbm9uZSdgLiBcIldlIGNvdWxkIG5vdCB0ZWxsXCIgYW5kXG4gKiBcIml0IGlzIHVwIHRvIGRhdGVcIiBhcmUgb3Bwb3NpdGUgYW5zd2VycywgYW5kIHJlcG9ydGluZyB0aGUgc2Vjb25kIGZvciB0aGUgZmlyc3RcbiAqIGlzIGhvdyBhIHBpcGVsaW5lIG9uIGFuIGFuY2llbnQgcHJlLXJlbGVhc2UgdmVyc2lvbiBnZXRzIGEgY2xlYW4gYmlsbCBvZiBoZWFsdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJzaW9uR2FwKHJlc29sdmVkOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkLCBsYXRlc3Q6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQpOiBWZXJzaW9uR2FwIHwgbnVsbCB7XG4gIGNvbnN0IGEgPSBzZW12ZXIocmVzb2x2ZWQpO1xuICBjb25zdCBiID0gc2VtdmVyKGxhdGVzdCk7XG4gIGlmICghYSB8fCAhYikgcmV0dXJuIG51bGw7XG4gIGlmIChiWzBdID4gYVswXSkgcmV0dXJuICdtYWpvcic7XG4gIGlmIChiWzBdIDwgYVswXSkgcmV0dXJuICdub25lJzsgLy8gcmVzb2x2ZWQgaXMgYWhlYWQgb2YgXCJsYXRlc3RcIiDigJQgbm90IGJlaGluZFxuICBpZiAoYlsxXSA+IGFbMV0pIHJldHVybiAnbWlub3InO1xuICBpZiAoYlsxXSA8IGFbMV0pIHJldHVybiAnbm9uZSc7XG4gIGlmIChiWzJdID4gYVsyXSkgcmV0dXJuICdwYXRjaCc7XG4gIHJldHVybiAnbm9uZSc7XG59XG5cbi8qKlxuICogUmVwbGFjZSBhIHBpcGVsaW5lJ3MgcmVzb2x1dGlvbiByb3dzLlxuICpcbiAqIERFTEVURS10aGVuLUlOU0VSVCBmb3IgdGhlIHBpcGVsaW5lLCBpbiBvbmUgdHJhbnNhY3Rpb24sIGJlY2F1c2UgYSBzdGVwIGNhbiBiZVxuICogUkVNT1ZFRCBmcm9tIGEgY29uZmlnOiBhbiB1cHNlcnQtb25seSB3cml0ZXIgd291bGQgbGVhdmUgdGhlIGRlbGV0ZWQgc3RlcCdzIHJvd1xuICogYmVoaW5kIGZvcmV2ZXIsIGFuZCB0aGUgb3V0ZGF0ZWQtcGx1Z2luIHNlY3Rpb24gd291bGQga2VlcCByZXBvcnRpbmcgYSBzdGVwIHRoZVxuICogcGlwZWxpbmUgbm8gbG9uZ2VyIGhhcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGxhY2VQaXBlbGluZVJlc29sdXRpb24oXG4gIHBpcGVsaW5lSWQ6IHN0cmluZyxcbiAgc3RlcHM6IHJlYWRvbmx5IFJlc29sdmVkU3RlcFtdLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3QgdmFsdWVzID0gc3RlcHMubWFwKChzKSA9PiAoe1xuICAgIG9yZ0lkOiBzLm9yZ0lkLFxuICAgIHBpcGVsaW5lSWQ6IHMucGlwZWxpbmVJZCxcbiAgICBzdGFnZU5hbWU6IHMuc3RhZ2VOYW1lLFxuICAgIHN0ZXBOYW1lOiBzLnN0ZXBOYW1lLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogcy5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBzLnBsdWdpbk5hbWUsXG4gICAgZGVjbGFyZWRWZXJzaW9uOiBzLmRlY2xhcmVkVmVyc2lvbiA/PyBudWxsLFxuICAgIHJlc29sdmVkVmVyc2lvbjogcy5yZXNvbHZlZFZlcnNpb24gPz8gbnVsbCxcbiAgICByZXNvbHZlZFBsdWdpbklkOiBzLnJlc29sdmVkUGx1Z2luSWQgPz8gbnVsbCxcbiAgICByZXNvbHZlZERpZ2VzdDogcy5yZXNvbHZlZERpZ2VzdCA/PyBudWxsLFxuICAgIGxhdGVzdFZlcnNpb246IHMubGF0ZXN0VmVyc2lvbiA/PyBudWxsLFxuICAgIHZlcnNpb25HYXA6IHZlcnNpb25HYXAocy5yZXNvbHZlZFZlcnNpb24sIHMubGF0ZXN0VmVyc2lvbiksXG4gICAgd2l0aGluUG9saWN5OiBzLndpdGhpblBvbGljeSA/PyB0cnVlLFxuICAgIHJvb3RPcmdJZDogcy5yb290T3JnSWQgPz8gbnVsbCxcbiAgICBjb21wdXRlZEF0OiBuZXcgRGF0ZSgpLFxuICB9KSk7XG5cbiAgcmV0dXJuIHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICBhd2FpdCB0eC5kZWxldGUoc2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbilcbiAgICAgIC53aGVyZShlcShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnBpcGVsaW5lSWQsIHBpcGVsaW5lSWQpKTtcbiAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG4gICAgY29uc3QgbGFuZGVkID0gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24pLnZhbHVlcyh2YWx1ZXMpXG4gICAgICAucmV0dXJuaW5nKHsgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5waXBlbGluZUlkIH0pO1xuICAgIHJldHVybiAobGFuZGVkIGFzIHVua25vd25bXSkubGVuZ3RoO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZWZyZXNoIHRoZSBgbGF0ZXN0YC9nYXAgY29sdW1ucyBmb3Igb25lIHBsdWdpbiBhY3Jvc3MgZXZlcnkgcGlwZWxpbmUgdGhhdCB1c2VzXG4gKiBpdCwgd2l0aG91dCByZS1yZXNvbHZpbmcgYW55dGhpbmcgZWxzZS5cbiAqXG4gKiBDYWxsZWQgb24gcHVibGlzaC4gQSBwdWJsaXNoIGNoYW5nZXMgd2hhdCBcImxhdGVzdFwiIG1lYW5zIGZvciBldmVyeSBwaXBlbGluZSBpblxuICogdGhlIGluc3RhbmNlIHRoYXQgZGVjbGFyZXMgdGhlIHBsdWdpbiwgYW5kIHJlLXJlc29sdmluZyBlYWNoIG9mIHRob3NlIHBpcGVsaW5lc1xuICogZnJvbSBzY3JhdGNoIHdvdWxkIG1ha2UgcHVibGlzaGluZyBjb3N0IE8ocGlwZWxpbmVzKSB3b3JrIOKAlCBzbyBvbmx5IHRoZSB0d29cbiAqIGNvbHVtbnMgYSBwdWJsaXNoIGNhbiBjaGFuZ2UgYXJlIHRvdWNoZWQuXG4gKlxuICogYG93bmVyYCBzYXlzIHdob3NlIHBsdWdpbiBpdCBpczogYSBsaXN0aW5nIChgcHVibGlzaGVyYCBoYW5kbGUg4oCUIGV2ZXJ5IG9yZydzXG4gKiBwaXBlbGluZXMgdGhhdCBkZWNsYXJlIGl0LCBzbyB0aGUgY2FsbGVyIG11c3QgYmUgZWxldmF0ZWQpLCBvciBhbiBvcmcncyBvd25cbiAqIHBsdWdpbiAoYG9yZ0lkYCDigJQgdGhhdCBvcmcncyBwaXBlbGluZXMgb25seTogYW4gb3JnIHBsdWdpbidzIG5hbWUgaXMgdW5pcXVlXG4gKiBvbmx5IHdpdGhpbiBpdHMgb3JnLCBzbyBhbm90aGVyIG9yZydzIHNhbWUtbmFtZWQgcGx1Z2luIGlzIGEgZGlmZmVyZW50IG9uZSkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWZyZXNoTGF0ZXN0Rm9yUGx1Z2luKFxuICBwbHVnaW5OYW1lOiBzdHJpbmcsXG4gIG93bmVyOiB7IHB1Ymxpc2hlcjogc3RyaW5nIH0gfCB7IG9yZ0lkOiBzdHJpbmcgfSxcbiAgbGF0ZXN0VmVyc2lvbjogc3RyaW5nLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LnVwZGF0ZShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uKVxuICAgIC5zZXQoe1xuICAgICAgbGF0ZXN0VmVyc2lvbixcbiAgICAgIC8vIFJlY29tcHV0ZWQgaW4gU1FMIGZyb20gdGhlIHJvdydzIG93biByZXNvbHZlZCB2ZXJzaW9uLCBzbyBvbmUgc3RhdGVtZW50XG4gICAgICAvLyBjb3ZlcnMgZXZlcnkgcGlwZWxpbmUgcmF0aGVyIHRoYW4gYSByb3VuZCB0cmlwIGVhY2guXG4gICAgICAvLyBgOjp0ZXh0YCBvbiBldmVyeSBiaW5kIG9mIHRoZSB2ZXJzaW9uOiBQb3N0Z3JlcyBvdGhlcndpc2UgZGVkdWNlc1xuICAgICAgLy8gaW5jb25zaXN0ZW50IHR5cGVzIGZvciB0aGUgc2FtZSBwYXJhbWV0ZXIgKHZhcmNoYXIgZm9yIHRoZSBhc3NpZ25tZW50LFxuICAgICAgLy8gdGV4dCBmb3IgYHNwbGl0X3BhcnRgKSBhbmQgcmVmdXNlcyB0byBwbGFuIHRoZSBzdGF0ZW1lbnQuXG4gICAgICB2ZXJzaW9uR2FwOiBzcWxgQ0FTRVxuICAgICAgICBXSEVOICR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259IElTIE5VTEwgVEhFTiBOVUxMXG4gICAgICAgIFdIRU4gc3BsaXRfcGFydCgke2xhdGVzdFZlcnNpb259Ojp0ZXh0LCAnLicsIDEpOjppbnQgPiBzcGxpdF9wYXJ0KCR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259LCAnLicsIDEpOjppbnQgVEhFTiAnbWFqb3InXG4gICAgICAgIFdIRU4gc3BsaXRfcGFydCgke2xhdGVzdFZlcnNpb259Ojp0ZXh0LCAnLicsIDEpOjppbnQgPCBzcGxpdF9wYXJ0KCR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259LCAnLicsIDEpOjppbnQgVEhFTiAnbm9uZSdcbiAgICAgICAgV0hFTiBzcGxpdF9wYXJ0KCR7bGF0ZXN0VmVyc2lvbn06OnRleHQsICcuJywgMik6OmludCA+IHNwbGl0X3BhcnQoJHtzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnJlc29sdmVkVmVyc2lvbn0sICcuJywgMik6OmludCBUSEVOICdtaW5vcidcbiAgICAgICAgV0hFTiBzcGxpdF9wYXJ0KCR7bGF0ZXN0VmVyc2lvbn06OnRleHQsICcuJywgMik6OmludCA8IHNwbGl0X3BhcnQoJHtzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnJlc29sdmVkVmVyc2lvbn0sICcuJywgMik6OmludCBUSEVOICdub25lJ1xuICAgICAgICBXSEVOIHNwbGl0X3BhcnQoJHtsYXRlc3RWZXJzaW9ufTo6dGV4dCwgJy4nLCAzKTo6aW50ID4gc3BsaXRfcGFydCgke3NjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucmVzb2x2ZWRWZXJzaW9ufSwgJy4nLCAzKTo6aW50IFRIRU4gJ3BhdGNoJ1xuICAgICAgICBFTFNFICdub25lJyBFTkRgLFxuICAgICAgY29tcHV0ZWRBdDogbmV3IERhdGUoKSxcbiAgICB9KVxuICAgIC53aGVyZShhbmQoXG4gICAgICBlcShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnBsdWdpbk5hbWUsIHBsdWdpbk5hbWUpLFxuICAgICAgLi4uKCdwdWJsaXNoZXInIGluIG93bmVyXG4gICAgICAgID8gW2VxKHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucGx1Z2luUHVibGlzaGVyLCBvd25lci5wdWJsaXNoZXIpXVxuICAgICAgICA6IFtpc051bGwoc2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5wbHVnaW5QdWJsaXNoZXIpLCBlcShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLm9yZ0lkLCBvd25lci5vcmdJZCldKSxcbiAgICAgIC8vIE9ubHkgcm93cyB3aG9zZSByZXNvbHZlZCB2ZXJzaW9uIHBhcnNlcyBhcyBzZW12ZXI7IGFueXRoaW5nIGVsc2UgaGFzIG5vXG4gICAgICAvLyBnYXAgdG8gY29tcHV0ZSBhbmQgdGhlIENBU0Ugd291bGQgdGhyb3cgb24gdGhlIGNhc3QuXG4gICAgICBzcWxgJHtzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnJlc29sdmVkVmVyc2lvbn0gfiAnXlswLTldK1xcXFwuWzAtOV0rXFxcXC5bMC05XSsnYCxcbiAgICApKVxuICAgIC5yZXR1cm5pbmcoeyBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnBpcGVsaW5lSWQgfSkpO1xuICByZXR1cm4gKHJvd3MgYXMgdW5rbm93bltdKS5sZW5ndGg7XG59XG5cbi8qKiBPbmUgZmxhZ2dlZCB2ZXJzaW9uLCBhcyB0aGUgcmVzY2FuIHJlcG9ydHMgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4cG9zdXJlSW5wdXQge1xuICBvcmdJZDogc3RyaW5nO1xuICBwaXBlbGluZUlkOiBzdHJpbmc7XG4gIHBsdWdpblB1Ymxpc2hlcj86IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nO1xuICBpbWFnZURpZ2VzdD86IHN0cmluZyB8IG51bGw7XG4gIHNvdXJjZTogRXhwb3N1cmVTb3VyY2U7XG4gIGNyaXRpY2FsQ291bnQ6IG51bWJlcjtcbiAgaGlnaENvdW50OiBudW1iZXI7XG4gIHRvcEZpbmRpbmdzPzogQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICAvKiogRXZlcnkgQ3JpdGljYWwvSGlnaCBmaW5kaW5nIGtleSBvZiB0aGUgdmVyc2lvbiAoc2VlIHRoZSBjb2x1bW4pLiAqL1xuICBmaW5kaW5nS2V5cz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYW4gZXhwb3N1cmUgcm93IGlzIExJVkU6IG5vdCBmaXhlZCwgbm90IGRpc21pc3NlZCBhcyBhIGZhbHNlIHBvc2l0aXZlLFxuICogYW5kIG5vdCB1bmRlciBhbiBhY2NlcHRhbmNlIHRoYXQgaXMgc3RpbGwgaW4gZm9yY2UuXG4gKlxuICogVGhlIE9ORSBwcmVkaWNhdGUgZXZlcnkgcmVhZGVyIHVzZXMgKHRoZSByZXBvcnQgc2VjdGlvbiwgbmVlZHMtYXR0ZW50aW9uLCB0aGVcbiAqIG9yZydzIG9wZW4gbGlzdCkuIFR3byByZWFkZXJzIHRoYXQgZGlzYWdyZWUgYWJvdXQgd2hhdCBcImV4cG9zZWRcIiBtZWFucyBwcm9kdWNlXG4gKiBhIHJlcG9ydCB3aG9zZSB2dWxuZXJhYmlsaXR5IHBhbmVsIGFuZCBuZWVkcy1hdHRlbnRpb24gbGlzdCBjb250cmFkaWN0IGVhY2hcbiAqIG90aGVyIOKAlCB3aGljaCBpcyBob3cgdGhpcyBwcmVkaWNhdGUgY2FtZSB0byBleGlzdC4gQW4gYWNjZXB0YW5jZSBMQVBTRVMgYXQgaXRzXG4gKiBkZWFkbGluZSBhbmQgdGhlIHJvdyBpcyBsaXZlIGFnYWluOyBvbmUgd2l0aCBubyBkZWFkbGluZSAod2hpY2hcbiAqIGB0cmlhZ2VFeHBvc3VyZWAgcmVmdXNlcyB0byB3cml0ZSkgaXMgdHJlYXRlZCBhcyBpbiBmb3JjZSwgYXMgZXZlcnkgcmVhZGVyXG4gKiBhbHJlYWR5IGRpZC5cbiAqXG4gKiBgYWxpYXNgIGlzIHRoZSB0YWJsZSBuYW1lIG9yIGFsaWFzIHRoZSBjYWxsZXIncyBxdWVyeSB1c2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGl2ZUV4cG9zdXJlUHJlZGljYXRlKG5vdzogRGF0ZSwgYWxpYXMgPSAncGx1Z2luX3Z1bG5fZXhwb3N1cmUnKTogU1FMIHtcbiAgY29uc3QgY29sID0gKGM6IHN0cmluZykgPT4gc3FsLnJhdyhgJHthbGlhc30uJHtjfWApO1xuICByZXR1cm4gc3FsYCgke2NvbCgnZml4ZWRfYXQnKX0gSVMgTlVMTFxuICAgIEFORCAoJHtjb2woJ3RyaWFnZV9zdGF0ZScpfSA9ICdvcGVuJ1xuICAgICAgICAgT1IgKCR7Y29sKCd0cmlhZ2Vfc3RhdGUnKX0gPSAnYWNjZXB0ZWQnXG4gICAgICAgICAgICAgQU5EICR7Y29sKCdhY2NlcHRlZF91bnRpbCcpfSBJUyBOT1QgTlVMTCBBTkQgJHtjb2woJ2FjY2VwdGVkX3VudGlsJyl9IDw9ICR7bm93fSkpKWA7XG59XG5cbi8qKiBXaGF0IGEgdmVyc2lvbidzIHNjYW4gc3RhdGUgY29udHJpYnV0ZXMgdG8gYW4gZXhwb3N1cmUgKHNlZSB7QGxpbmsgZXhwb3N1cmVGcm9tU2Nhbn0pLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY2FuU3RhdGUge1xuICAvKiogVGhlIGRpZ2VzdCB0aGUgc3RlcCBydW5zLiBBIHNjYW4gc3VtbWFyeSBkZXNjcmliaW5nIGFub3RoZXIgaW1hZ2UgaXMgaWdub3JlZC4gKi9cbiAgaW1hZ2VEaWdlc3Q/OiBzdHJpbmcgfCBudWxsO1xuICBzY2FuU3VtbWFyeT86IHVua25vd247XG4gIHNjYW5GbGFnPzogdW5rbm93bjtcbiAgc2NhbkZsYWdnZWRBdD86IERhdGUgfCBzdHJpbmcgfCBudWxsO1xufVxuXG4vKiogVGhlIGNvdW50cyBhbiBleHBvc3VyZSByb3cgY2Fycmllcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3N1cmVDb3VudHMge1xuICBjcml0aWNhbENvdW50OiBudW1iZXI7XG4gIGhpZ2hDb3VudDogbnVtYmVyO1xuICB0b3BGaW5kaW5nczogUGx1Z2luU2NhbkZpbmRpbmdbXTtcbiAgLyoqIEtleXMgb2YgRVZFUlkgQ3JpdGljYWwvSGlnaCBmaW5kaW5nIGl0ZW1pemVkIChmaXhhYmxlIG9yIG5vdCksIHNvcnRlZC4gKi9cbiAgZmluZGluZ0tleXM6IHN0cmluZ1tdO1xufVxuXG5jb25zdCBrZXlzT2YgPSAoZmluZGluZ3M6IHJlYWRvbmx5IFBsdWdpblNjYW5GaW5kaW5nW10pOiBzdHJpbmdbXSA9PiBbLi4ubmV3IFNldChmaW5kaW5ncy5tYXAoc2NhbkZpbmRpbmdLZXkpKV0uc29ydCgpO1xuXG4vKiogQXQgbW9zdCB0aGlzIG1hbnkgZmluZGluZ3MgYXJlIHN0b3JlZCBvbiBhbiBleHBvc3VyZSByb3cuICovXG5jb25zdCBFWFBPU1VSRV9UT1BfRklORElOR1MgPSAxMDtcblxuLyoqXG4gKiBUaGUgZXhwb3N1cmUgYSB2ZXJzaW9uJ3Mgc2NhbiBzdGF0ZSBhbW91bnRzIHRvLCBvciBudWxsIHdoZW4gaXQgaGFzIG5vbmUuXG4gKlxuICogUmVhZHMgdGhlIHJlc2NhbidzIGBzY2FuX3N1bW1hcnlgIChmaXhhYmxlIENyaXRpY2FsIEFORCBIaWdoLCB3aGV0aGVyIG9yIG5vdCB0aGVcbiAqIGdhdGUgdHJpcHBlZCkgYW5kIGZhbGxzIGJhY2sgdG8gYHNjYW5fZmxhZ2AgZm9yIGEgdmVyc2lvbiBmbGFnZ2VkIGJlZm9yZSBhbnlcbiAqIHN1bW1hcnkgd2FzIHdyaXR0ZW4uIEEgc3VtbWFyeSB3aG9zZSBkaWdlc3QgaXMgbm90IHRoZSBzdGVwJ3MgaXMgSUdOT1JFRDogYVxuICogdmVyc2lvbiByZWJ1aWx0IG9uIGEgcGF0Y2hlZCBiYXNlIGlzIGEgZGlmZmVyZW50IGFydGlmYWN0LCBhbmQgaXRzIGZpbmRpbmdzIHNheVxuICogbm90aGluZyBhYm91dCB0aGUgaW1hZ2UgdGhlIHBpcGVsaW5lIHJ1bnMuIE9ubHkgRklYQUJMRSBmaW5kaW5ncyBjb3VudCDigJQgYW5cbiAqIGV4cG9zdXJlIGlzIHNvbWV0aGluZyBhIHJlYnVpbGQgb3IgYW4gdXBncmFkZSBjYW4gY2xlYXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBvc3VyZUZyb21TY2FuKHN0YXRlOiBTY2FuU3RhdGUpOiBFeHBvc3VyZUNvdW50cyB8IG51bGwge1xuICBjb25zdCBzdW1tYXJ5ID0gc3RhdGUuc2NhblN1bW1hcnkgJiYgdHlwZW9mIHN0YXRlLnNjYW5TdW1tYXJ5ID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShzdGF0ZS5zY2FuU3VtbWFyeSlcbiAgICA/IHN0YXRlLnNjYW5TdW1tYXJ5IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICAgOiBudWxsO1xuICBjb25zdCBzdW1tYXJ5RGlnZXN0ID0gdHlwZW9mIHN1bW1hcnk/LmltYWdlRGlnZXN0ID09PSAnc3RyaW5nJyA/IHN1bW1hcnkuaW1hZ2VEaWdlc3QgOiBudWxsO1xuICBpZiAoc3VtbWFyeSAmJiB0eXBlb2Ygc3VtbWFyeS5jcml0aWNhbEZpeGFibGUgPT09ICdudW1iZXInICYmIHR5cGVvZiBzdW1tYXJ5LmhpZ2hGaXhhYmxlID09PSAnbnVtYmVyJ1xuICAgICYmIChzdW1tYXJ5RGlnZXN0ID09PSBudWxsIHx8ICFzdGF0ZS5pbWFnZURpZ2VzdCB8fCBzdW1tYXJ5RGlnZXN0ID09PSBzdGF0ZS5pbWFnZURpZ2VzdCkpIHtcbiAgICBpZiAoc3VtbWFyeS5jcml0aWNhbEZpeGFibGUgPD0gMCAmJiBzdW1tYXJ5LmhpZ2hGaXhhYmxlIDw9IDApIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGFsbCA9IChBcnJheS5pc0FycmF5KHN1bW1hcnkuZmluZGluZ3MpID8gc3VtbWFyeS5maW5kaW5ncyBhcyBQbHVnaW5TY2FuRmluZGluZ1tdIDogW10pXG4gICAgICAuZmlsdGVyKChmKSA9PiBmICYmIHR5cGVvZiBmLmlkID09PSAnc3RyaW5nJyk7XG4gICAgY29uc3QgZmluZGluZ3MgPSBhbGwuZmlsdGVyKChmKSA9PiBBcnJheS5pc0FycmF5KGYuZml4ZWRJbikgJiYgZi5maXhlZEluLmxlbmd0aCA+IDApO1xuICAgIHJldHVybiB7IGNyaXRpY2FsQ291bnQ6IHN1bW1hcnkuY3JpdGljYWxGaXhhYmxlLCBoaWdoQ291bnQ6IHN1bW1hcnkuaGlnaEZpeGFibGUsIHRvcEZpbmRpbmdzOiBmaW5kaW5ncy5zbGljZSgwLCBFWFBPU1VSRV9UT1BfRklORElOR1MpLCBmaW5kaW5nS2V5czoga2V5c09mKGFsbCkgfTtcbiAgfVxuICBjb25zdCBmbGFnID0gc3RhdGUuc2NhbkZsYWdnZWRBdCA/IGFzU2NhbkZsYWcoc3RhdGUuc2NhbkZsYWcpIDogbnVsbDtcbiAgaWYgKCFmbGFnIHx8IChmbGFnLmdhdGVkIDw9IDAgJiYgZmxhZy5oaWdoIDw9IDApKSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIHsgY3JpdGljYWxDb3VudDogZmxhZy5nYXRlZCwgaGlnaENvdW50OiBmbGFnLmhpZ2gsIHRvcEZpbmRpbmdzOiBmbGFnLmZpbmRpbmdzLnNsaWNlKDAsIEVYUE9TVVJFX1RPUF9GSU5ESU5HUyksIGZpbmRpbmdLZXlzOiBrZXlzT2YoZmxhZy5maW5kaW5ncykgfTtcbn1cblxuLyoqXG4gKiBPcGVuIG9yIHJlZnJlc2ggZXhwb3N1cmVzLlxuICpcbiAqIFVwc2VydHMgb24gKHBpcGVsaW5lLCBwbHVnaW4sIHZlcnNpb24sIGRpZ2VzdCwgc291cmNlKSBzbyBhIG5pZ2h0bHkgcmVzY2FuIFJFRlJFU0hFUyB0aGVcbiAqIGNvdW50cyByYXRoZXIgdGhhbiBvcGVuaW5nIGEgbmV3IHJvdyBldmVyeSBuaWdodCDigJQgb3RoZXJ3aXNlIHRoZSByZXBvcnQgd291bGRcbiAqIHNob3cgb25lIGV4cG9zdXJlIHBlciBuaWdodCBvZiB0aGUgc2FtZSBwcm9ibGVtLCB3aGljaCByZWFkcyBhcyBhbiBlc2NhbGF0aW5nXG4gKiBzaXR1YXRpb24gd2hlbiBub3RoaW5nIGNoYW5nZWQuXG4gKlxuICogQSByZWZyZXNoIGRlbGliZXJhdGVseSBkb2VzIE5PVCByZXNldCBgdHJpYWdlX3N0YXRlYDogYW4gb3JnIHRoYXQgYWNjZXB0ZWQgYVxuICogZmluZGluZyB3aXRoIGEgcmVhc29uIGFuZCBhIGRlYWRsaW5lIGhhcyBtYWRlIGEgZGVjaXNpb24sIGFuZCByZS1yYWlzaW5nIGl0IGV2ZXJ5XG4gKiBuaWdodCBpcyBob3cgYSB0ZWFtIGxlYXJucyB0byBpZ25vcmUgdGhlIHJlcG9ydC4gSXQgRE9FUyBjbGVhciBhIHN0YWxlXG4gKiBhY2NlcHRhbmNlLCBiZWNhdXNlIHRoYXQgaXMgd2hhdCB0aGUgZGVhZGxpbmUgd2FzIGZvci5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwc2VydEV4cG9zdXJlcyhpbnB1dHM6IHJlYWRvbmx5IEV4cG9zdXJlSW5wdXRbXSwgbm93ID0gbmV3IERhdGUoKSk6IFByb21pc2U8bnVtYmVyPiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAwKSByZXR1cm4gMDtcbiAgY29uc3QgdmFsdWVzID0gaW5wdXRzLm1hcCgoZSkgPT4gKHtcbiAgICBpZDogcmFuZG9tVVVJRCgpLFxuICAgIG9yZ0lkOiBlLm9yZ0lkLFxuICAgIHBpcGVsaW5lSWQ6IGUucGlwZWxpbmVJZCxcbiAgICBwbHVnaW5QdWJsaXNoZXI6IGUucGx1Z2luUHVibGlzaGVyID8/IG51bGwsXG4gICAgcGx1Z2luTmFtZTogZS5wbHVnaW5OYW1lLFxuICAgIHBsdWdpblZlcnNpb246IGUucGx1Z2luVmVyc2lvbixcbiAgICBpbWFnZURpZ2VzdDogZS5pbWFnZURpZ2VzdCA/PyBudWxsLFxuICAgIHNvdXJjZTogZS5zb3VyY2UsXG4gICAgY3JpdGljYWxDb3VudDogZS5jcml0aWNhbENvdW50LFxuICAgIGhpZ2hDb3VudDogZS5oaWdoQ291bnQsXG4gICAgdG9wRmluZGluZ3M6IGUudG9wRmluZGluZ3MgPz8gW10sXG4gICAgZmluZGluZ0tleXM6IGUuZmluZGluZ0tleXMgPz8gW10sXG4gICAgZmxhZ2dlZEF0OiBub3csXG4gICAgdXBkYXRlZEF0OiBub3csXG4gIH0pKTtcblxuICB0cnkge1xuICAgIGNvbnN0IGxhbmRlZCA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4Lmluc2VydChzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlKS52YWx1ZXModmFsdWVzKVxuICAgICAgLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogW1xuICAgICAgICAgIHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGlwZWxpbmVJZCxcbiAgICAgICAgICBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpbk5hbWUsXG4gICAgICAgICAgc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5wbHVnaW5WZXJzaW9uLFxuICAgICAgICAgIHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaW1hZ2VEaWdlc3QsXG4gICAgICAgICAgc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5zb3VyY2UsXG4gICAgICAgIF0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIGNyaXRpY2FsQ291bnQ6IHNxbGBleGNsdWRlZC5jcml0aWNhbF9jb3VudGAsXG4gICAgICAgICAgaGlnaENvdW50OiBzcWxgZXhjbHVkZWQuaGlnaF9jb3VudGAsXG4gICAgICAgICAgdG9wRmluZGluZ3M6IHNxbGBleGNsdWRlZC50b3BfZmluZGluZ3NgLFxuICAgICAgICAgIGZpbmRpbmdLZXlzOiBzcWxgZXhjbHVkZWQuZmluZGluZ19rZXlzYCxcbiAgICAgICAgICAvLyBTdGlsbCBleHBvc2VkLCBzbyB0aGUgZml4IG1hcmtlciBpcyBjbGVhcmVkOiBhIHJvdyB0aGF0IHdhcyBjbG9zZWQgYnkgYVxuICAgICAgICAgIC8vIGRlcGxveSBhbmQgaXMgZmxhZ2dlZCBhZ2FpbiBpcyBhIHJlZ3Jlc3Npb24sIGFuZCBsZWF2aW5nIGBmaXhlZF9hdGAgc2V0XG4gICAgICAgICAgLy8gd291bGQgaGlkZSBpdC5cbiAgICAgICAgICBmaXhlZEF0OiBudWxsLFxuICAgICAgICAgIC8vIEFuIGFjY2VwdGFuY2UgcGFzdCBpdHMgZGVhZGxpbmUgc3RvcHMgYmVpbmcgYW4gYWNjZXB0YW5jZS4gVGhhdCBpcyB0aGVcbiAgICAgICAgICAvLyBlbnRpcmUgcG9pbnQgb2YgdGltZS1ib3hpbmcgaXQsIGFuZCBpdCBpcyBlbmZvcmNlZCBIRVJFIHJhdGhlciB0aGFuIGF0XG4gICAgICAgICAgLy8gcmVhZCB0aW1lIHNvIHRoZSBzdG9yZWQgc3RhdGUgaXMgdGhlIHRydXRoLlxuICAgICAgICAgIC8vIEFuIGFjY2VwdGFuY2UgY292ZXJzIHRoZSBmaW5kaW5ncyBpdCB3YXMgbWFkZSBvdmVyLCBuZXZlciBvbmVzIGZvdW5kXG4gICAgICAgICAgLy8gc2luY2U6IGEgcmVmcmVzaCBjYXJyeWluZyBhIGZpbmRpbmcga2V5IHRoZSBhY2NlcHRhbmNlIGRpZCBub3QgZnJlZXplXG4gICAgICAgICAgLy8gcmVvcGVucyB0aGUgcm93LCBzbyB0aGUgZGVjaXNpb24gaXMgbWFkZSBhZ2FpbiBhYm91dCB3aGF0IGlzIHRoZXJlIG5vdy5cbiAgICAgICAgICB0cmlhZ2VTdGF0ZTogc3FsYENBU0VcbiAgICAgICAgICAgIFdIRU4gJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnRyaWFnZVN0YXRlfSA9ICdhY2NlcHRlZCdcbiAgICAgICAgICAgICBBTkQgJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmFjY2VwdGVkVW50aWx9IElTIE5PVCBOVUxMXG4gICAgICAgICAgICAgQU5EICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZFVudGlsfSA8PSAke25vd31cbiAgICAgICAgICAgIFRIRU4gJ29wZW4nXG4gICAgICAgICAgICBXSEVOICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gPSAnYWNjZXB0ZWQnXG4gICAgICAgICAgICAgQU5EIE5PVCAoZXhjbHVkZWQuZmluZGluZ19rZXlzIDxAICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZEZpbmRpbmdLZXlzfSlcbiAgICAgICAgICAgIFRIRU4gJ29wZW4nXG4gICAgICAgICAgICBXSEVOICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gPSAnZml4ZWQnIFRIRU4gJ29wZW4nXG4gICAgICAgICAgICAtLSBBIFJFTU9WRUQgc3RlcCAvIHBpcGVsaW5lIGJhY2sgb24gdGhlIHNhbWUgdmVyc2lvbjogaXRzIGFjY2VwdGFuY2VcbiAgICAgICAgICAgIC0tIHJldHVybnMgaWYgc3RpbGwgaW4gZm9yY2UgYW5kIGl0IGNvdmVycyB3aGF0IHRoZSB2ZXJzaW9uIGNhcnJpZXMgbm93LlxuICAgICAgICAgICAgV0hFTiAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudHJpYWdlU3RhdGV9ID0gJ3JlbW92ZWQnXG4gICAgICAgICAgICAgQU5EICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZFVudGlsfSBJUyBOT1QgTlVMTFxuICAgICAgICAgICAgIEFORCAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuYWNjZXB0ZWRVbnRpbH0gPiAke25vd31cbiAgICAgICAgICAgICBBTkQgZXhjbHVkZWQuZmluZGluZ19rZXlzIDxAICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZEZpbmRpbmdLZXlzfVxuICAgICAgICAgICAgVEhFTiAnYWNjZXB0ZWQnXG4gICAgICAgICAgICBXSEVOICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gPSAncmVtb3ZlZCcgVEhFTiAnb3BlbidcbiAgICAgICAgICAgIEVMU0UgJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnRyaWFnZVN0YXRlfSBFTkRgLFxuICAgICAgICAgIHVwZGF0ZWRBdDogbm93LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC5yZXR1cm5pbmcoeyBpZDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5pZCB9KSk7XG4gICAgcmV0dXJuIChsYW5kZWQgYXMgdW5rbm93bltdKS5sZW5ndGg7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdQbHVnaW4gZXhwb3N1cmUgdXBzZXJ0IGZhaWxlZCcsIHsgY291bnQ6IHZhbHVlcy5sZW5ndGgsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICByZXR1cm4gMDtcbiAgfVxufVxuXG4vKiogT25lIHZlcnNpb24gYSBwaXBlbGluZSBzdGlsbCBkZWNsYXJlcyAvIHJ1bnMgV0lUSCBvcGVuIGZpbmRpbmdzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaXZlVmVyc2lvbiB7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nO1xuICBpbWFnZURpZ2VzdD86IHN0cmluZyB8IG51bGw7XG59XG5cbmNvbnN0IGxpdmVLZXkgPSAodjogTGl2ZVZlcnNpb24pOiBzdHJpbmcgPT4gYCR7di5wbHVnaW5OYW1lfUAke3YucGx1Z2luVmVyc2lvbn1AJHt2LmltYWdlRGlnZXN0ID8/ICcnfWA7XG5cbi8qKlxuICogQ2xvc2UgdGhlIGV4cG9zdXJlcyBvZiBvbmUgU09VUkNFIGEgcGlwZWxpbmUgaGFzIG1vdmVkIG9mZiDigJQgYGZpeGVkYCB3aGVuIHRoZVxuICogcGlwZWxpbmUgc3RpbGwgdXNlcyB0aGUgcGx1Z2luIGF0IGFub3RoZXIgdmVyc2lvbiwgYHJlbW92ZWRgIHdoZW4gbm8gbGl2ZSBzdGVwXG4gKiB1c2VzIHRoZSBwbHVnaW4gYXQgYWxsICh0aGUgdHJpYWdlIGZpZWxkcyBzdGF5LCBzbyBhIHJlLWFkZGVkIHN0ZXAgZ2V0cyBhblxuICogdW5leHBpcmVkIGFjY2VwdGFuY2UgYmFjayDigJQgc2VlIHtAbGluayB1cHNlcnRFeHBvc3VyZXN9KS5cbiAqXG4gKiBDYWxsZWQgd2hlbiBhIGRlcGxveSByZWNvcmRzIGEgbmV3IHN0ZXAgbWFuaWZlc3QgKGBkZXBsb3llZGApIG9yIGEgcGlwZWxpbmVcbiAqIHdyaXRlIHJlLXJlc29sdmVzIGl0cyBjb25maWcgKGBkZWNsYXJlZGApOiBhbnl0aGluZyBvcGVuIGZvciB0aGF0IHBpcGVsaW5lIGFuZFxuICogc291cmNlIHdob3NlICh2ZXJzaW9uLCBkaWdlc3QpIGlzIE5PVCBpbiBgbGl2ZVZlcnNpb25zYCBpcyBmaXhlZC4gQ2xvc2luZyBieVxuICogYWJzZW5jZSByYXRoZXIgdGhhbiB3YWl0aW5nIGZvciBhIHJlc2NhbiB0byBub3RpY2UgaXMgd2hhdCBtYWtlcyBcIndlIGZpeGVkIGl0XCJcbiAqIHNob3cgdXAgaW4gdGhlIHJlcG9ydCBvbiB0aGUgbmV4dCBkZXBsb3kgaW5zdGVhZCBvZiB0aGUgbmV4dCBuaWdodC5cbiAqXG4gKiBQZXIgc291cmNlLCBiZWNhdXNlIHRoZSB0d28gc2lkZXMgbW92ZSBpbmRlcGVuZGVudGx5OiBhIGNvbmZpZyB1cGRhdGVkIHRvIHRoZVxuICogZml4ZWQgdmVyc2lvbiBjbG9zZXMgdGhlIERFQ0xBUkVEIGV4cG9zdXJlIHdoaWxlIHRoZSBvbGQgaW1hZ2Uga2VlcHMgcnVubmluZyxcbiAqIGFuZCBpdHMgREVQTE9ZRUQgZXhwb3N1cmUgbXVzdCBzdGF5IG9wZW4gdW50aWwgdGhlIGRlcGxveSBsYW5kcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsb3NlRml4ZWRFeHBvc3VyZXMoXG4gIHBpcGVsaW5lSWQ6IHN0cmluZyxcbiAgc291cmNlOiBFeHBvc3VyZVNvdXJjZSxcbiAgbGl2ZVZlcnNpb25zOiByZWFkb25seSBMaXZlVmVyc2lvbltdLFxuICBub3cgPSBuZXcgRGF0ZSgpLFxuICBvcHRzOiB7IGxpdmVQbHVnaW5zPzogcmVhZG9ubHkgc3RyaW5nW10gfSA9IHt9LFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3QgbGl2ZSA9IG5ldyBTZXQobGl2ZVZlcnNpb25zLm1hcChsaXZlS2V5KSk7XG4gIGNvbnN0IGxpdmVQbHVnaW5zID0gbmV3IFNldChbLi4ubGl2ZVZlcnNpb25zLCAuLi4ob3B0cy5saXZlUGx1Z2lucyA/PyBbXSldLm1hcCgodikgPT4gKHR5cGVvZiB2ID09PSAnc3RyaW5nJyA/IHYgOiB2LnBsdWdpbk5hbWUpKSk7XG4gIGNvbnN0IG9wZW4gPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3Qoe1xuICAgIGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLFxuICAgIHBsdWdpbk5hbWU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luTmFtZSxcbiAgICBwbHVnaW5WZXJzaW9uOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpblZlcnNpb24sXG4gICAgaW1hZ2VEaWdlc3Q6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaW1hZ2VEaWdlc3QsXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5waXBlbGluZUlkLCBwaXBlbGluZUlkKSxcbiAgICAgIGVxKHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuc291cmNlLCBzb3VyY2UpLFxuICAgICAgaXNOdWxsKHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuZml4ZWRBdCksXG4gICAgKSkpO1xuICBjb25zdCBzdGFsZVJvd3MgPSAob3BlbiBhcyBBcnJheTxMaXZlVmVyc2lvbiAmIHsgaWQ6IHN0cmluZyB9PikuZmlsdGVyKChyKSA9PiAhbGl2ZS5oYXMobGl2ZUtleShyKSkpO1xuICBpZiAoc3RhbGVSb3dzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG4gIGNvbnN0IGZpeGVkID0gc3RhbGVSb3dzLmZpbHRlcigocikgPT4gbGl2ZVBsdWdpbnMuaGFzKHIucGx1Z2luTmFtZSkpLm1hcCgocikgPT4gci5pZCk7XG4gIGNvbnN0IHJlbW92ZWQgPSBzdGFsZVJvd3MuZmlsdGVyKChyKSA9PiAhbGl2ZVBsdWdpbnMuaGFzKHIucGx1Z2luTmFtZSkpLm1hcCgocikgPT4gci5pZCk7XG4gIGxldCBjbG9zZWQgPSAwO1xuICBmb3IgKGNvbnN0IFtpZHMsIHN0YXRlXSBvZiBbW2ZpeGVkLCAnZml4ZWQnXSwgW3JlbW92ZWQsICdyZW1vdmVkJ11dIGFzIGNvbnN0KSB7XG4gICAgaWYgKGlkcy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC51cGRhdGUoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAgIC5zZXQoeyBmaXhlZEF0OiBub3csIHRyaWFnZVN0YXRlOiBzdGF0ZSwgdXBkYXRlZEF0OiBub3cgfSlcbiAgICAgIC53aGVyZShpbkFycmF5KHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaWQsIFsuLi5pZHNdKSlcbiAgICAgIC5yZXR1cm5pbmcoeyBpZDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5pZCB9KSk7XG4gICAgY2xvc2VkICs9IChyb3dzIGFzIHVua25vd25bXSkubGVuZ3RoO1xuICB9XG4gIHJldHVybiBjbG9zZWQ7XG59XG5cbi8qKlxuICogQ2xvc2UgZXZlcnkgb3BlbiBleHBvc3VyZSBvZiBhIHBpcGVsaW5lIChvciBvZiBvbmUgc291cmNlKSBhcyBgcmVtb3ZlZGAg4oCUIHRoZVxuICogcGlwZWxpbmUgd2FzIGRlbGV0ZWQsIG9yIGRlcmVnaXN0ZXJlZCAoaXRzIGRlcGxveSBpcyBnb25lKS4gVGhlIHRyaWFnZSBmaWVsZHNcbiAqIHN0YXk6IGEgcmVzdG9yZSByZS1yZWNvcmRzIHRoZSBwaXBlbGluZSdzIHJlc29sdXRpb24sIGFuZFxuICoge0BsaW5rIHVwc2VydEV4cG9zdXJlc30gcmVvcGVucyB0aGUgcm93cyAocmVzdG9yaW5nIGFuIGFjY2VwdGFuY2Ugc3RpbGwgaW5cbiAqIGZvcmNlKS4gUmV0dXJucyB0aGUgcm93cyBjbG9zZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZVBpcGVsaW5lRXhwb3N1cmVzKFxuICBwaXBlbGluZUlkOiBzdHJpbmcsXG4gIHN0YXRlOiAncmVtb3ZlZCcsXG4gIG9wdHM6IHsgc291cmNlPzogRXhwb3N1cmVTb3VyY2UgfSA9IHt9LFxuICBub3cgPSBuZXcgRGF0ZSgpLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LnVwZGF0ZShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlKVxuICAgIC5zZXQoeyBmaXhlZEF0OiBub3csIHRyaWFnZVN0YXRlOiBzdGF0ZSwgdXBkYXRlZEF0OiBub3cgfSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5waXBlbGluZUlkLCBwaXBlbGluZUlkKSxcbiAgICAgIGlzTnVsbChzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmZpeGVkQXQpLFxuICAgICAgLi4uKG9wdHMuc291cmNlID8gW2VxKHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuc291cmNlLCBvcHRzLnNvdXJjZSldIDogW10pLFxuICAgICkpXG4gICAgLnJldHVybmluZyh7IGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkIH0pKTtcbiAgcmV0dXJuIChyb3dzIGFzIHVua25vd25bXSkubGVuZ3RoO1xufVxuXG4vKiogT25lIHN0ZXAgb2YgYSBwaXBlbGluZSBhcyB7QGxpbmsgcmVjb25jaWxlUGlwZWxpbmVFeHBvc3VyZXN9IHRha2VzIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHBvc3VyZVN0ZXAge1xuICBwbHVnaW5QdWJsaXNoZXI/OiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZztcbiAgaW1hZ2VEaWdlc3Q/OiBzdHJpbmcgfCBudWxsO1xuICAvKiogVGhlIHJlc29sdmVkIHZlcnNpb24ncyBzY2FuIHN0YXRlLCBhcyBzdG9yZWQgb24gaXRzIHJvdy4gKi9cbiAgc2NhbjogU2NhblN0YXRlO1xufVxuXG4vKipcbiAqIEJyaW5nIG9uZSBwaXBlbGluZSdzIGV4cG9zdXJlcyBvZiBvbmUgc291cmNlIGluIGxpbmUgd2l0aCB0aGUgc3RlcHMgaXQgbm93XG4gKiBkZWNsYXJlcyAoYGRlY2xhcmVkYCkgb3IgcnVucyAoYGRlcGxveWVkYCk6IG9wZW4gLyByZWZyZXNoIGEgcm93IGZvciBldmVyeSBzdGVwXG4gKiB3aG9zZSB2ZXJzaW9uIGhhcyBvcGVuIGZpeGFibGUgZmluZGluZ3MsIGNsb3NlIHRoZSByZXN0IGJ5IGFic2VuY2UuXG4gKlxuICogTmV2ZXIgdGhyb3dzIOKAlCBleHBvc3VyZSB0cmFja2luZyBpcyByZXBvcnRpbmcsIGFuZCBhIHBpcGVsaW5lIHdyaXRlIG9yIGEgZGVwbG95XG4gKiByZWdpc3RyYXRpb24gbXVzdCBub3QgZmFpbCBiZWNhdXNlIHRoZSByZXBvcnQgdGFibGUgY291bGQgbm90IGJlIHdyaXR0ZW4uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWNvbmNpbGVQaXBlbGluZUV4cG9zdXJlcyhcbiAgaW5wdXQ6IHsgb3JnSWQ6IHN0cmluZzsgcGlwZWxpbmVJZDogc3RyaW5nOyBzb3VyY2U6IEV4cG9zdXJlU291cmNlOyBzdGVwczogcmVhZG9ubHkgRXhwb3N1cmVTdGVwW10gfSxcbiAgbm93ID0gbmV3IERhdGUoKSxcbik6IFByb21pc2U8eyBvcGVuZWQ6IG51bWJlcjsgY2xvc2VkOiBudW1iZXIgfT4ge1xuICBjb25zdCBleHBvc2VkOiBFeHBvc3VyZUlucHV0W10gPSBbXTtcbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IHN0ZXAgb2YgaW5wdXQuc3RlcHMpIHtcbiAgICBjb25zdCBjb3VudHMgPSBleHBvc3VyZUZyb21TY2FuKHsgLi4uc3RlcC5zY2FuLCBpbWFnZURpZ2VzdDogc3RlcC5pbWFnZURpZ2VzdCA/PyBzdGVwLnNjYW4uaW1hZ2VEaWdlc3QgPz8gbnVsbCB9KTtcbiAgICBpZiAoIWNvdW50cykgY29udGludWU7XG4gICAgY29uc3Qga2V5ID0gbGl2ZUtleSh7IHBsdWdpbk5hbWU6IHN0ZXAucGx1Z2luTmFtZSwgcGx1Z2luVmVyc2lvbjogc3RlcC5wbHVnaW5WZXJzaW9uLCBpbWFnZURpZ2VzdDogc3RlcC5pbWFnZURpZ2VzdCB9KTtcbiAgICBpZiAoc2Vlbi5oYXMoa2V5KSkgY29udGludWU7IC8vIHR3byBzdGVwcyBvbiBvbmUgdmVyc2lvbiBhcmUgb25lIGV4cG9zdXJlXG4gICAgc2Vlbi5hZGQoa2V5KTtcbiAgICBleHBvc2VkLnB1c2goe1xuICAgICAgb3JnSWQ6IGlucHV0Lm9yZ0lkLFxuICAgICAgcGlwZWxpbmVJZDogaW5wdXQucGlwZWxpbmVJZCxcbiAgICAgIHBsdWdpblB1Ymxpc2hlcjogc3RlcC5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICAgIHBsdWdpbk5hbWU6IHN0ZXAucGx1Z2luTmFtZSxcbiAgICAgIHBsdWdpblZlcnNpb246IHN0ZXAucGx1Z2luVmVyc2lvbixcbiAgICAgIGltYWdlRGlnZXN0OiBzdGVwLmltYWdlRGlnZXN0ID8/IG51bGwsXG4gICAgICBzb3VyY2U6IGlucHV0LnNvdXJjZSxcbiAgICAgIC4uLmNvdW50cyxcbiAgICAgIHRvcEZpbmRpbmdzOiBjb3VudHMudG9wRmluZGluZ3MgYXMgdW5rbm93biBhcyBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4gICAgfSk7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCBvcGVuZWQgPSBhd2FpdCB1cHNlcnRFeHBvc3VyZXMoZXhwb3NlZCwgbm93KTtcbiAgICAvLyBFdmVyeSBwbHVnaW4gYSBzdGVwIHN0aWxsIHVzZXMgKGNsZWFuIHZlcnNpb25zIHRvbyk6IGEgcm93IGZvciBvbmUgb2ZcbiAgICAvLyB0aGVtIGNsb3NlcyBgZml4ZWRgOyBhIHJvdyBmb3IgYSBwbHVnaW4gbm8gc3RlcCB1c2VzIGFueSBtb3JlLCBgcmVtb3ZlZGAuXG4gICAgY29uc3QgY2xvc2VkID0gYXdhaXQgY2xvc2VGaXhlZEV4cG9zdXJlcyhpbnB1dC5waXBlbGluZUlkLCBpbnB1dC5zb3VyY2UsIGV4cG9zZWQsIG5vdywgeyBsaXZlUGx1Z2luczogaW5wdXQuc3RlcHMubWFwKChzKSA9PiBzLnBsdWdpbk5hbWUpIH0pO1xuICAgIHJldHVybiB7IG9wZW5lZCwgY2xvc2VkIH07XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdQaXBlbGluZSBleHBvc3VyZSByZWNvbmNpbGUgZmFpbGVkJywgeyBwaXBlbGluZUlkOiBpbnB1dC5waXBlbGluZUlkLCBzb3VyY2U6IGlucHV0LnNvdXJjZSwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIHJldHVybiB7IG9wZW5lZDogMCwgY2xvc2VkOiAwIH07XG4gIH1cbn1cblxuLyoqIEEgcGx1Z2luIHZlcnNpb24gKG9wdGlvbmFsbHkgb25lIGltYWdlIG9mIGl0KSB3aG9zZSBwaXBlbGluZXMgYXJlIHdhbnRlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGx1Z2luVmVyc2lvblJlZiB7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nO1xuICAvKiogTGlzdGluZyBwdWJsaXNoZXIgaGFuZGxlOyBudWxsID0gYW4gb3JnJ3Mgb3duIHBsdWdpbiByb3c7IG9taXR0ZWQgPSBlaXRoZXIuICovXG4gIHBsdWdpblB1Ymxpc2hlcj86IHN0cmluZyB8IG51bGw7XG4gIC8qKiBOYXJyb3cgdG8gcGlwZWxpbmVzIG9uIHRoaXMgaW1hZ2UuIE9taXR0ZWQgPSBhbnkgaW1hZ2Ugb2YgdGhlIHZlcnNpb24uICovXG4gIGltYWdlRGlnZXN0Pzogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIE5hcnJvdyB0byB0aGVzZSBvcmdzLiBPbWl0dGVkID0gZXZlcnkgb3JnIHRoZSBjYWxsZXIncyBzY29wZSBjYW4gcmVhZC4gKi9cbiAgb3JnSWRzPzogcmVhZG9ubHkgc3RyaW5nW107XG59XG5cbi8qKiBBIHBpcGVsaW5lIHRoYXQgZGVjbGFyZXMgb3IgcnVucyBhIGdpdmVuIHBsdWdpbiB2ZXJzaW9uLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQaXBlbGluZU9uVmVyc2lvbiB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHBpcGVsaW5lSWQ6IHN0cmluZztcbiAgcGlwZWxpbmVOYW1lOiBzdHJpbmcgfCBudWxsO1xuICAvKiogYGRlcGxveWVkYCA9IGl0cyBsYXN0IGRlcGxveSdzIHN0ZXAgbWFuaWZlc3Q7IGBkZWNsYXJlZGAgPSBpdHMgY29uZmlnIHJlc29sdmVzIHRvIGl0LiAqL1xuICBzb3VyY2U6IEV4cG9zdXJlU291cmNlO1xuICBwbHVnaW5QdWJsaXNoZXI6IHN0cmluZyB8IG51bGw7XG4gIGltYWdlRGlnZXN0OiBzdHJpbmcgfCBudWxsO1xuICAvKiogVGhlIHN0ZXBzIG9uIGl0OiBgc3ludGhgIG9yIGA8c3RhZ2U+LzxzdGVwPmAgKGRlY2xhcmVkKSAvIGA8c3RhZ2U+LzxhY3Rpb24+YCAoZGVwbG95ZWQpLiAqL1xuICBzdGVwczogc3RyaW5nW107XG59XG5cbi8qKlxuICogRXZlcnkgTElWRSBwaXBlbGluZSBkZWNsYXJpbmcgKGBwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbmApIG9yIHJ1bm5pbmdcbiAqIChgcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHNgKSBhIHBsdWdpbiB2ZXJzaW9uLCBvbmUgZW50cnkgcGVyIChwaXBlbGluZSwgc291cmNlKVxuICogd2l0aCB0aGUgc3RlcHMgb24gaXQuIEEgc29mdC1kZWxldGVkIHBpcGVsaW5lIGlzIE5PVCBhZmZlY3RlZDogY291bnRpbmcgaXRcbiAqIHdvdWxkIHB1dCBhIHBpcGVsaW5lIG5vYm9keSBjYW4gb3BlbiBpbnRvIGEgbm90aWNlIG9yIGEgcmVwb3J0LiBSZWFkcyB1bmRlclxuICogdGhlIENBTExFUidzIHRlbmFudCBzY29wZTogYW4gb3JnLXNjb3BlZCBjYWxsZXIgc2VlcyBpdHMgb3duIHBpcGVsaW5lcywgdGhlXG4gKiByZXNjYW4gKGVsZXZhdGVkKSBzZWVzIGV2ZXJ5IG9yZydzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGlwZWxpbmVzT25WZXJzaW9uKHJlZjogUGx1Z2luVmVyc2lvblJlZik6IFByb21pc2U8UGlwZWxpbmVPblZlcnNpb25bXT4ge1xuICBjb25zdCBwdWJsaXNoZXJTcWwgPSAoY29sOiBzdHJpbmcpID0+IChyZWYucGx1Z2luUHVibGlzaGVyID09PSB1bmRlZmluZWRcbiAgICA/IHNxbGBgXG4gICAgOiByZWYucGx1Z2luUHVibGlzaGVyID09PSBudWxsID8gc3FsYCBBTkQgJHtzcWwucmF3KGNvbCl9IElTIE5VTExgIDogc3FsYCBBTkQgJHtzcWwucmF3KGNvbCl9ID0gJHtyZWYucGx1Z2luUHVibGlzaGVyfWApO1xuICBjb25zdCBkaWdlc3RTcWwgPSAoY29sOiBzdHJpbmcpID0+IChyZWYuaW1hZ2VEaWdlc3QgPyBzcWxgIEFORCAke3NxbC5yYXcoY29sKX0gPSAke3JlZi5pbWFnZURpZ2VzdH1gIDogc3FsYGApO1xuICBjb25zdCBvcmdTcWwgPSAoY29sOiBzdHJpbmcpID0+IChyZWYub3JnSWRzID8gc3FsYCBBTkQgJHtzcWwucmF3KGNvbCl9ID0gQU5ZKCR7Wy4uLnJlZi5vcmdJZHNdfSlgIDogc3FsYGApO1xuICBpZiAocmVmLm9yZ0lkcyAmJiByZWYub3JnSWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICBTRUxFQ1QgeC5vcmdfaWQsIHgucGlwZWxpbmVfaWQsIHguc291cmNlLCBNSU4oeC5wbHVnaW5fcHVibGlzaGVyKSBBUyBwbHVnaW5fcHVibGlzaGVyLCBNSU4oeC5pbWFnZV9kaWdlc3QpIEFTIGltYWdlX2RpZ2VzdCxcbiAgICAgICAgICAgcC5waXBlbGluZV9uYW1lLCBhcnJheV9hZ2coRElTVElOQ1QgeC5zdGVwIE9SREVSIEJZIHguc3RlcCkgQVMgc3RlcHNcbiAgICBGUk9NIChcbiAgICAgIFNFTEVDVCBtLm9yZ19pZCwgbS5waXBlbGluZV9pZDo6dGV4dCBBUyBwaXBlbGluZV9pZCwgJ2RlcGxveWVkJyBBUyBzb3VyY2UsIG0ucGx1Z2luX3B1Ymxpc2hlciwgbS5pbWFnZV9kaWdlc3QsXG4gICAgICAgICAgICAgbS5zdGFnZV9uYW1lIHx8ICcvJyB8fCBtLmFjdGlvbl9uYW1lIEFTIHN0ZXBcbiAgICAgIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbVxuICAgICAgV0hFUkUgbS5wbHVnaW5fbmFtZSA9ICR7cmVmLnBsdWdpbk5hbWV9IEFORCBtLnBsdWdpbl92ZXJzaW9uID0gJHtyZWYucGx1Z2luVmVyc2lvbn1cbiAgICAgICAgJHtwdWJsaXNoZXJTcWwoJ20ucGx1Z2luX3B1Ymxpc2hlcicpfSR7ZGlnZXN0U3FsKCdtLmltYWdlX2RpZ2VzdCcpfSR7b3JnU3FsKCdtLm9yZ19pZCcpfVxuICAgICAgVU5JT04gQUxMXG4gICAgICBTRUxFQ1Qgci5vcmdfaWQsIHIucGlwZWxpbmVfaWQsICdkZWNsYXJlZCcgQVMgc291cmNlLCByLnBsdWdpbl9wdWJsaXNoZXIsIHIucmVzb2x2ZWRfZGlnZXN0IEFTIGltYWdlX2RpZ2VzdCxcbiAgICAgICAgICAgICBDQVNFIFdIRU4gci5zdGFnZV9uYW1lID0gJ3N5bnRoJyBBTkQgci5zdGVwX25hbWUgPSAnc3ludGgnIFRIRU4gJ3N5bnRoJyBFTFNFIHIuc3RhZ2VfbmFtZSB8fCAnLycgfHwgci5zdGVwX25hbWUgRU5EIEFTIHN0ZXBcbiAgICAgIEZST00gcGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb24gclxuICAgICAgV0hFUkUgci5wbHVnaW5fbmFtZSA9ICR7cmVmLnBsdWdpbk5hbWV9IEFORCByLnJlc29sdmVkX3ZlcnNpb24gPSAke3JlZi5wbHVnaW5WZXJzaW9ufVxuICAgICAgICAke3B1Ymxpc2hlclNxbCgnci5wbHVnaW5fcHVibGlzaGVyJyl9JHtkaWdlc3RTcWwoJ3IucmVzb2x2ZWRfZGlnZXN0Jyl9JHtvcmdTcWwoJ3Iub3JnX2lkJyl9XG4gICAgKSB4XG4gICAgSk9JTiBwaXBlbGluZXMgcCBPTiBwLmlkOjp0ZXh0ID0geC5waXBlbGluZV9pZCBBTkQgcC5kZWxldGVkX2F0IElTIE5VTExcbiAgICBHUk9VUCBCWSB4Lm9yZ19pZCwgeC5waXBlbGluZV9pZCwgeC5zb3VyY2UsIHAucGlwZWxpbmVfbmFtZVxuICAgIE9SREVSIEJZIHgucGlwZWxpbmVfaWQsIHguc291cmNlXG4gIGApKTtcbiAgY29uc3Qgcm93cyA9IEFycmF5LmlzQXJyYXkocmVzdWx0KSA/IHJlc3VsdCA6ICgocmVzdWx0IGFzIHsgcm93cz86IHVua25vd25bXSB9KT8ucm93cyA/PyBbXSk7XG4gIHJldHVybiAocm93cyBhcyBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pLm1hcCgocikgPT4gKHtcbiAgICBvcmdJZDogU3RyaW5nKHIub3JnX2lkKSxcbiAgICBwaXBlbGluZUlkOiBTdHJpbmcoci5waXBlbGluZV9pZCksXG4gICAgcGlwZWxpbmVOYW1lOiAoci5waXBlbGluZV9uYW1lIGFzIHN0cmluZyB8IG51bGwpID8/IG51bGwsXG4gICAgc291cmNlOiByLnNvdXJjZSBhcyBFeHBvc3VyZVNvdXJjZSxcbiAgICBwbHVnaW5QdWJsaXNoZXI6IChyLnBsdWdpbl9wdWJsaXNoZXIgYXMgc3RyaW5nIHwgbnVsbCkgPz8gbnVsbCxcbiAgICBpbWFnZURpZ2VzdDogKHIuaW1hZ2VfZGlnZXN0IGFzIHN0cmluZyB8IG51bGwpID8/IG51bGwsXG4gICAgc3RlcHM6IEFycmF5LmlzQXJyYXkoci5zdGVwcykgPyAoci5zdGVwcyBhcyBzdHJpbmdbXSkgOiBbXSxcbiAgfSkpO1xufVxuXG4vKipcbiAqIFRoZSByZXNjYW4ncyBlbnRyeSBwb2ludDogb25lIHJlc2Nhbm5lZCB2ZXJzaW9uJ3MgZmluZGluZ3MsIGZhbm5lZCBvdXQgdG8gZXZlcnlcbiAqIHBpcGVsaW5lIHRoYXQgZGVjbGFyZXMgb3IgcnVucyBpdC5cbiAqXG4gKiBBIHZlcnNpb24gd2l0aCBvcGVuIGZpeGFibGUgZmluZGluZ3Mgb3BlbnMgLyByZWZyZXNoZXMgb25lIGV4cG9zdXJlIHBlclxuICogKHBpcGVsaW5lLCBzb3VyY2UpOyBhIHZlcnNpb24gdGhhdCBjYW1lIGJhY2sgQ0xFQU4gY2xvc2VzIGV2ZXJ5IG9wZW4gZXhwb3N1cmVcbiAqIG9uIGl0IChgZml4ZWRgKSwgc28gYSByZWJ1aWxkLWluLXBsYWNlIG9yIGFuIGFkdmlzb3J5IHdpdGhkcmF3biB1cHN0cmVhbSBzaG93c1xuICogYXMgZml4ZWQgb24gdGhlIG5leHQgbmlnaHQgcmF0aGVyIHRoYW4gbGluZ2VyaW5nIHVudGlsIGVhY2ggcGlwZWxpbmUgcmVkZXBsb3lzLlxuICpcbiAqIE11c3QgcnVuIHdpdGggYSBzY29wZSB0aGF0IGNhbiByZWFkIGFuZCB3cml0ZSBldmVyeSBvcmcncyByb3dzICh0aGUgcmVzY2FuJ3NcbiAqIGVsZXZhdGVkIGNvbnRleHQpLiBOZXZlciB0aHJvd3MuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzeW5jVmVyc2lvbkV4cG9zdXJlcyhcbiAgcmVmOiBQbHVnaW5WZXJzaW9uUmVmLFxuICBzY2FuOiBTY2FuU3RhdGUsXG4gIG5vdyA9IG5ldyBEYXRlKCksXG4pOiBQcm9taXNlPHsgb3BlbmVkOiBudW1iZXI7IGNsb3NlZDogbnVtYmVyIH0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBjb3VudHMgPSBleHBvc3VyZUZyb21TY2FuKHsgLi4uc2NhbiwgaW1hZ2VEaWdlc3Q6IHJlZi5pbWFnZURpZ2VzdCA/PyBzY2FuLmltYWdlRGlnZXN0ID8/IG51bGwgfSk7XG4gICAgaWYgKCFjb3VudHMpIHJldHVybiB7IG9wZW5lZDogMCwgY2xvc2VkOiBhd2FpdCBjbG9zZVZlcnNpb25FeHBvc3VyZXMocmVmLCBub3cpIH07XG4gICAgY29uc3QgcGlwZWxpbmVzID0gYXdhaXQgcGlwZWxpbmVzT25WZXJzaW9uKHJlZik7XG4gICAgY29uc3Qgb3BlbmVkID0gYXdhaXQgdXBzZXJ0RXhwb3N1cmVzKHBpcGVsaW5lcy5tYXAoKHApID0+ICh7XG4gICAgICBvcmdJZDogcC5vcmdJZCxcbiAgICAgIHBpcGVsaW5lSWQ6IHAucGlwZWxpbmVJZCxcbiAgICAgIHBsdWdpblB1Ymxpc2hlcjogcC5wbHVnaW5QdWJsaXNoZXIsXG4gICAgICBwbHVnaW5OYW1lOiByZWYucGx1Z2luTmFtZSxcbiAgICAgIHBsdWdpblZlcnNpb246IHJlZi5wbHVnaW5WZXJzaW9uLFxuICAgICAgaW1hZ2VEaWdlc3Q6IHJlZi5pbWFnZURpZ2VzdCA/PyBwLmltYWdlRGlnZXN0LFxuICAgICAgc291cmNlOiBwLnNvdXJjZSxcbiAgICAgIGNyaXRpY2FsQ291bnQ6IGNvdW50cy5jcml0aWNhbENvdW50LFxuICAgICAgaGlnaENvdW50OiBjb3VudHMuaGlnaENvdW50LFxuICAgICAgdG9wRmluZGluZ3M6IGNvdW50cy50b3BGaW5kaW5ncyBhcyB1bmtub3duIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PixcbiAgICAgIGZpbmRpbmdLZXlzOiBjb3VudHMuZmluZGluZ0tleXMsXG4gICAgfSkpLCBub3cpO1xuICAgIHJldHVybiB7IG9wZW5lZCwgY2xvc2VkOiAwIH07XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdWZXJzaW9uIGV4cG9zdXJlIHN5bmMgZmFpbGVkJywgeyBwbHVnaW46IHJlZi5wbHVnaW5OYW1lLCB2ZXJzaW9uOiByZWYucGx1Z2luVmVyc2lvbiwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIHJldHVybiB7IG9wZW5lZDogMCwgY2xvc2VkOiAwIH07XG4gIH1cbn1cblxuLyoqIENsb3NlIGV2ZXJ5IG9wZW4gZXhwb3N1cmUgb24gYSB2ZXJzaW9uIChvcHRpb25hbGx5IG9uZSBpbWFnZSBvZiBpdCkuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xvc2VWZXJzaW9uRXhwb3N1cmVzKHJlZjogUGx1Z2luVmVyc2lvblJlZiwgbm93ID0gbmV3IERhdGUoKSk6IFByb21pc2U8bnVtYmVyPiB7XG4gIGNvbnN0IEUgPSBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlO1xuICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHgudXBkYXRlKEUpXG4gICAgLnNldCh7IGZpeGVkQXQ6IG5vdywgdHJpYWdlU3RhdGU6ICdmaXhlZCcsIHVwZGF0ZWRBdDogbm93IH0pXG4gICAgLndoZXJlKGFuZChcbiAgICAgIGVxKEUucGx1Z2luTmFtZSwgcmVmLnBsdWdpbk5hbWUpLFxuICAgICAgZXEoRS5wbHVnaW5WZXJzaW9uLCByZWYucGx1Z2luVmVyc2lvbiksXG4gICAgICBpc051bGwoRS5maXhlZEF0KSxcbiAgICAgIC4uLihyZWYuaW1hZ2VEaWdlc3QgPyBbZXEoRS5pbWFnZURpZ2VzdCwgcmVmLmltYWdlRGlnZXN0KV0gOiBbXSksXG4gICAgICAuLi4ocmVmLnBsdWdpblB1Ymxpc2hlciA9PT0gdW5kZWZpbmVkID8gW10gOiBbcmVmLnBsdWdpblB1Ymxpc2hlciA9PT0gbnVsbCA/IGlzTnVsbChFLnBsdWdpblB1Ymxpc2hlcikgOiBlcShFLnBsdWdpblB1Ymxpc2hlciwgcmVmLnBsdWdpblB1Ymxpc2hlcildKSxcbiAgICAgIC4uLihyZWYub3JnSWRzID8gW2luQXJyYXkoRS5vcmdJZCwgWy4uLnJlZi5vcmdJZHNdKV0gOiBbXSksXG4gICAgKSlcbiAgICAucmV0dXJuaW5nKHsgaWQ6IEUuaWQgfSkpO1xuICByZXR1cm4gKHJvd3MgYXMgdW5rbm93bltdKS5sZW5ndGg7XG59XG5cbi8qKlxuICogVGhlIG9yZydzIGxpdmUgZXhwb3N1cmVzLCBmb3IgdGhlIHJlcG9ydCBzZWN0aW9uLlxuICpcbiAqIGBhY2NlcHRlZGAgcm93cyB3aG9zZSBkZWFkbGluZSBoYXMgcGFzc2VkIGNvbWUgYmFjayBhcyBPUEVOIGV2ZW4gaWYgbm8gcmVzY2FuXG4gKiBoYXMgcmVmcmVzaGVkIHRoZW0geWV0OiBhIHJlYWQgbXVzdCBub3QgcHJlc2VudCBhbiBleHBpcmVkIGFjY2VwdGFuY2UgYXMgYVxuICogY3VycmVudCBvbmUsIGFuZCB0aGUgcmVwb3J0IGlzIHJlYWQgZmFyIG1vcmUgb2Z0ZW4gdGhhbiB0aGUgcmVzY2FuIHJ1bnMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuRXhwb3N1cmVzKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEFycmF5PHtcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyOiBzdHJpbmcgfCBudWxsO1xuICBzb3VyY2U6IEV4cG9zdXJlU291cmNlO1xuICBjcml0aWNhbENvdW50OiBudW1iZXI7XG4gIGhpZ2hDb3VudDogbnVtYmVyO1xuICB0b3BGaW5kaW5nczogQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICB0cmlhZ2VTdGF0ZTogc3RyaW5nO1xuICBmbGFnZ2VkQXQ6IERhdGU7XG59Pj4ge1xuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguc2VsZWN0KHtcbiAgICBwaXBlbGluZUlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBpcGVsaW5lSWQsXG4gICAgcGx1Z2luTmFtZTogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5wbHVnaW5OYW1lLFxuICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luVmVyc2lvbixcbiAgICBwbHVnaW5QdWJsaXNoZXI6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luUHVibGlzaGVyLFxuICAgIHNvdXJjZTogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5zb3VyY2UsXG4gICAgY3JpdGljYWxDb3VudDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5jcml0aWNhbENvdW50LFxuICAgIGhpZ2hDb3VudDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5oaWdoQ291bnQsXG4gICAgdG9wRmluZGluZ3M6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudG9wRmluZGluZ3MsXG4gICAgdHJpYWdlU3RhdGU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudHJpYWdlU3RhdGUsXG4gICAgYWNjZXB0ZWRVbnRpbDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZFVudGlsLFxuICAgIGZsYWdnZWRBdDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5mbGFnZ2VkQXQsXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5vcmdJZCwgb3JnSWQpLFxuICAgICAgbGl2ZUV4cG9zdXJlUHJlZGljYXRlKG5vdyksXG4gICAgKSlcbiAgICAub3JkZXJCeShzcWxgJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmNyaXRpY2FsQ291bnR9IERFU0MsICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5oaWdoQ291bnR9IERFU0NgKSk7XG5cbiAgcmV0dXJuIChyb3dzIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PikubWFwKChyKSA9PiAoe1xuICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCBhcyBzdHJpbmcsXG4gICAgcGx1Z2luTmFtZTogci5wbHVnaW5OYW1lIGFzIHN0cmluZyxcbiAgICBwbHVnaW5WZXJzaW9uOiByLnBsdWdpblZlcnNpb24gYXMgc3RyaW5nLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogKHIucGx1Z2luUHVibGlzaGVyIGFzIHN0cmluZyB8IG51bGwpID8/IG51bGwsXG4gICAgc291cmNlOiByLnNvdXJjZSBhcyBFeHBvc3VyZVNvdXJjZSxcbiAgICBjcml0aWNhbENvdW50OiByLmNyaXRpY2FsQ291bnQgYXMgbnVtYmVyLFxuICAgIGhpZ2hDb3VudDogci5oaWdoQ291bnQgYXMgbnVtYmVyLFxuICAgIHRvcEZpbmRpbmdzOiAoci50b3BGaW5kaW5ncyBhcyBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pID8/IFtdLFxuICAgIC8vIE9ubHkgYWNjZXB0YW5jZXMgTk9UIGluIGZvcmNlIHBhc3MgdGhlIGxpdmUgcHJlZGljYXRlLCBzbyBhbiBgYWNjZXB0ZWRgXG4gICAgLy8gcm93IGhlcmUgaXMgYW4gZXhwaXJlZCBvbmUsIGFuZCByZWFkcyBhcyB3aGF0IGl0IGlzOiBvcGVuLlxuICAgIHRyaWFnZVN0YXRlOiByLnRyaWFnZVN0YXRlID09PSAnYWNjZXB0ZWQnID8gJ29wZW4nIDogKHIudHJpYWdlU3RhdGUgYXMgc3RyaW5nKSxcbiAgICBmbGFnZ2VkQXQ6IHIuZmxhZ2dlZEF0IGFzIERhdGUsXG4gIH0pKTtcbn1cblxuLyoqIE9uZSBleHBvc3VyZSByb3cgYXMgdGhlIHBlci1waXBlbGluZSBzZWN1cml0eSB2aWV3cyByZWFkIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBQaXBlbGluZUV4cG9zdXJlIHtcbiAgaWQ6IHN0cmluZztcbiAgb3JnSWQ6IHN0cmluZztcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBwbHVnaW5QdWJsaXNoZXI6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nO1xuICBpbWFnZURpZ2VzdDogc3RyaW5nIHwgbnVsbDtcbiAgc291cmNlOiBFeHBvc3VyZVNvdXJjZTtcbiAgY3JpdGljYWxDb3VudDogbnVtYmVyO1xuICBoaWdoQ291bnQ6IG51bWJlcjtcbiAgdG9wRmluZGluZ3M6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgZmluZGluZ0tleXM6IHN0cmluZ1tdO1xuICAvKiogQXMgc3RvcmVkOyBhbiBgYWNjZXB0ZWRgIHJvdyBwYXN0IGl0cyBkZWFkbGluZSByZWFkcyBgb3BlbmAgKHNlZSB7QGxpbmsgbGl2ZUV4cG9zdXJlUHJlZGljYXRlfSkuICovXG4gIHRyaWFnZVN0YXRlOiBzdHJpbmc7XG4gIC8qKiBBbiBhY2NlcHRhbmNlIHN0aWxsIGluIGZvcmNlIHJpZ2h0IG5vdy4gKi9cbiAgYWNjZXB0YW5jZUFjdGl2ZTogYm9vbGVhbjtcbiAgYWNjZXB0ZWRVbnRpbDogRGF0ZSB8IG51bGw7XG4gIGFjY2VwdGVkRmluZGluZ0tleXM6IHN0cmluZ1tdO1xuICBhY2NlcHRlZEtldjogYm9vbGVhbjtcbiAgdHJpYWdlUmVhc29uOiBzdHJpbmcgfCBudWxsO1xuICB0cmlhZ2VkQnk6IHN0cmluZyB8IG51bGw7XG4gIHRyaWFnZWRBdDogRGF0ZSB8IG51bGw7XG4gIGZsYWdnZWRBdDogRGF0ZTtcbiAgZml4ZWRBdDogRGF0ZSB8IG51bGw7XG59XG5cbmNvbnN0IEUgPSAoKSA9PiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlO1xuXG5mdW5jdGlvbiB0b1BpcGVsaW5lRXhwb3N1cmUocjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIG5vdzogRGF0ZSk6IFBpcGVsaW5lRXhwb3N1cmUge1xuICBjb25zdCB1bnRpbCA9IChyLmFjY2VwdGVkVW50aWwgYXMgRGF0ZSB8IG51bGwpID8/IG51bGw7XG4gIGNvbnN0IGFjdGl2ZSA9IHIudHJpYWdlU3RhdGUgPT09ICdhY2NlcHRlZCcgJiYgci5maXhlZEF0ID09IG51bGwgJiYgdW50aWwgIT09IG51bGwgJiYgdW50aWwuZ2V0VGltZSgpID4gbm93LmdldFRpbWUoKTtcbiAgcmV0dXJuIHtcbiAgICBpZDogci5pZCBhcyBzdHJpbmcsXG4gICAgb3JnSWQ6IHIub3JnSWQgYXMgc3RyaW5nLFxuICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCBhcyBzdHJpbmcsXG4gICAgcGx1Z2luUHVibGlzaGVyOiAoci5wbHVnaW5QdWJsaXNoZXIgYXMgc3RyaW5nIHwgbnVsbCkgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiByLnBsdWdpbk5hbWUgYXMgc3RyaW5nLFxuICAgIHBsdWdpblZlcnNpb246IHIucGx1Z2luVmVyc2lvbiBhcyBzdHJpbmcsXG4gICAgaW1hZ2VEaWdlc3Q6IChyLmltYWdlRGlnZXN0IGFzIHN0cmluZyB8IG51bGwpID8/IG51bGwsXG4gICAgc291cmNlOiByLnNvdXJjZSBhcyBFeHBvc3VyZVNvdXJjZSxcbiAgICBjcml0aWNhbENvdW50OiByLmNyaXRpY2FsQ291bnQgYXMgbnVtYmVyLFxuICAgIGhpZ2hDb3VudDogci5oaWdoQ291bnQgYXMgbnVtYmVyLFxuICAgIHRvcEZpbmRpbmdzOiAoci50b3BGaW5kaW5ncyBhcyBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pID8/IFtdLFxuICAgIGZpbmRpbmdLZXlzOiAoci5maW5kaW5nS2V5cyBhcyBzdHJpbmdbXSkgPz8gW10sXG4gICAgdHJpYWdlU3RhdGU6IHIudHJpYWdlU3RhdGUgPT09ICdhY2NlcHRlZCcgJiYgIWFjdGl2ZSAmJiByLmZpeGVkQXQgPT0gbnVsbCA/ICdvcGVuJyA6IChyLnRyaWFnZVN0YXRlIGFzIHN0cmluZyksXG4gICAgYWNjZXB0YW5jZUFjdGl2ZTogYWN0aXZlLFxuICAgIGFjY2VwdGVkVW50aWw6IHVudGlsLFxuICAgIGFjY2VwdGVkRmluZGluZ0tleXM6IChyLmFjY2VwdGVkRmluZGluZ0tleXMgYXMgc3RyaW5nW10pID8/IFtdLFxuICAgIGFjY2VwdGVkS2V2OiByLmFjY2VwdGVkS2V2ID09PSB0cnVlLFxuICAgIHRyaWFnZVJlYXNvbjogKHIudHJpYWdlUmVhc29uIGFzIHN0cmluZyB8IG51bGwpID8/IG51bGwsXG4gICAgdHJpYWdlZEJ5OiAoci50cmlhZ2VkQnkgYXMgc3RyaW5nIHwgbnVsbCkgPz8gbnVsbCxcbiAgICB0cmlhZ2VkQXQ6IChyLnRyaWFnZWRBdCBhcyBEYXRlIHwgbnVsbCkgPz8gbnVsbCxcbiAgICBmbGFnZ2VkQXQ6IHIuZmxhZ2dlZEF0IGFzIERhdGUsXG4gICAgZml4ZWRBdDogKHIuZml4ZWRBdCBhcyBEYXRlIHwgbnVsbCkgPz8gbnVsbCxcbiAgfTtcbn1cblxuLyoqXG4gKiBPbmUgcGlwZWxpbmUncyBleHBvc3VyZXM6IHRoZSB1bmZpeGVkIG9uZXMgKG9wZW4sIGFjY2VwdGVkLCBmYWxzZSBwb3NpdGl2ZSksXG4gKiBwbHVzIHRoZSBmaXhlZCBvbmVzIHdoZW4gYXNrZWQg4oCUIG1vc3Qgc2V2ZXJlIGZpcnN0LiBSZWFkcyB1bmRlciB0aGUgQ0FMTEVSJ3NcbiAqIHNjb3BlLCBuYXJyb3dlZCB0byBgb3JnSWRgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGlwZWxpbmVFeHBvc3VyZXMoXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHBpcGVsaW5lSWQ6IHN0cmluZyxcbiAgb3B0czogeyBpbmNsdWRlRml4ZWQ/OiBib29sZWFuOyBub3c/OiBEYXRlIH0gPSB7fSxcbik6IFByb21pc2U8UGlwZWxpbmVFeHBvc3VyZVtdPiB7XG4gIGNvbnN0IG5vdyA9IG9wdHMubm93ID8/IG5ldyBEYXRlKCk7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3QoKS5mcm9tKEUoKSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoRSgpLm9yZ0lkLCBvcmdJZCksXG4gICAgICBlcShFKCkucGlwZWxpbmVJZCwgcGlwZWxpbmVJZCksXG4gICAgICAuLi4ob3B0cy5pbmNsdWRlRml4ZWQgPyBbXSA6IFtpc051bGwoRSgpLmZpeGVkQXQpXSksXG4gICAgKSlcbiAgICAub3JkZXJCeShzcWxgJHtFKCkuY3JpdGljYWxDb3VudH0gREVTQywgJHtFKCkuaGlnaENvdW50fSBERVNDLCAke0UoKS5wbHVnaW5OYW1lfWApKTtcbiAgcmV0dXJuIChyb3dzIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PikubWFwKChyKSA9PiB0b1BpcGVsaW5lRXhwb3N1cmUociwgbm93KSk7XG59XG5cbi8qKiBPbmUgZXhwb3N1cmUgcm93IG9mIGBvcmdJZGAsIG9yIG51bGwuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhwb3N1cmVCeUlkKG9yZ0lkOiBzdHJpbmcsIGlkOiBzdHJpbmcsIG5vdyA9IG5ldyBEYXRlKCkpOiBQcm9taXNlPFBpcGVsaW5lRXhwb3N1cmUgfCBudWxsPiB7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3QoKS5mcm9tKEUoKSkud2hlcmUoYW5kKGVxKEUoKS5pZCwgaWQpLCBlcShFKCkub3JnSWQsIG9yZ0lkKSkpKTtcbiAgY29uc3Qgcm93ID0gKHJvd3MgYXMgQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KVswXTtcbiAgcmV0dXJuIHJvdyA/IHRvUGlwZWxpbmVFeHBvc3VyZShyb3csIG5vdykgOiBudWxsO1xufVxuXG4vKiogQSB0cmlhZ2UgZGVjaXNpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIFRyaWFnZURlY2lzaW9uIHtcbiAgc3RhdGU6ICdvcGVuJyB8ICdhY2NlcHRlZCcgfCAnZmFsc2VfcG9zaXRpdmUnO1xuICByZWFzb24/OiBzdHJpbmc7XG4gIGFjY2VwdGVkVW50aWw/OiBEYXRlO1xuICAvKiogQWNjZXB0IEtFVi1saXN0ZWQgZmluZGluZ3MgdG9vLiBOZXZlciBpbXBsaWVkOiBhbiBhY2NlcHRhbmNlIHdpdGhvdXQgaXQgZG9lcyBub3QgY292ZXIgdGhlbS4gKi9cbiAga2V2PzogYm9vbGVhbjtcbiAgYWN0b3I6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZWNvcmQgYSB0cmlhZ2UgZGVjaXNpb24gb24gb25lIGV4cG9zdXJlIOKAlCBhbmQgb24gaXRzIFNJQkxJTkdTOiB0aGUgc2FtZVxuICogcGlwZWxpbmUncyBvdGhlciBvcGVuIHJvdyBmb3IgdGhlIHNhbWUgdmVyc2lvbiBhbmQgaW1hZ2UgKHRoZSBkZWNsYXJlZCBhbmRcbiAqIHRoZSBkZXBsb3llZCBzaWRlKS4gQSByaXNrIGRlY2lzaW9uIGlzIGFib3V0IHdoYXQgdGhlIHBpcGVsaW5lIHJ1bnMsIGFuZFxuICogbGVhdmluZyBvbmUgc2lkZSBvcGVuIHdvdWxkIGhhdmUgdGhlIHJlcG9ydCBhbmQgdGhlIGxvb2t1cCBkaXNhZ3JlZS5cbiAqXG4gKiBgYWNjZXB0ZWRgIFJFUVVJUkVTIGEgZGVhZGxpbmUgYW5kIGEgcmVhc29uLiBBIHBlcm1hbmVudCwgdW5leHBsYWluZWQgbXV0ZSBpc1xuICogaG93IGEgZmluZGluZyBzdG9wcyBiZWluZyBhbnlib2R5J3MgcHJvYmxlbSwgYW5kIHRoZXJlIGlzIG5vIGdvb2QgcmVhc29uIHRvXG4gKiBzdXBwb3J0IGl0IOKAlCB0aGUgY2FsbGVyIGdldHMgYW4gZXJyb3IgcmF0aGVyIHRoYW4gYSBzaWxlbnRseSB1bmJvdW5kZWRcbiAqIGFjY2VwdGFuY2UuIFRoZSBhY2NlcHRlZCBmaW5kaW5nIGtleXMgYXJlIEZST1pFTiBhdCB0aGUgZGVjaXNpb246IGFuXG4gKiBhY2NlcHRhbmNlIGNvdmVycyB3aGF0IHdhcyB0aGVyZSB3aGVuIGl0IHdhcyBtYWRlLCBuZXZlciBhIGZpbmRpbmcgc2luY2UuXG4gKlxuICogUmV0dXJucyB0aGUgdXBkYXRlZCByb3dzIChlbXB0eSB3aGVuIGBpZGAgaXMgbm90IGBvcmdJZGAncyB1bmZpeGVkIGV4cG9zdXJlKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRyaWFnZUV4cG9zdXJlKG9yZ0lkOiBzdHJpbmcsIGlkOiBzdHJpbmcsIGRlY2lzaW9uOiBUcmlhZ2VEZWNpc2lvbik6IFByb21pc2U8UGlwZWxpbmVFeHBvc3VyZVtdPiB7XG4gIGlmIChkZWNpc2lvbi5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJiAoIWRlY2lzaW9uLmFjY2VwdGVkVW50aWwgfHwgIWRlY2lzaW9uLnJlYXNvbj8udHJpbSgpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQWNjZXB0aW5nIGEgdnVsbmVyYWJpbGl0eSBleHBvc3VyZSBuZWVkcyBhIHJlYXNvbiBhbmQgYW4gZXhwaXJ5IGRhdGUnKTtcbiAgfVxuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCB0YXJnZXQgPSBhd2FpdCBleHBvc3VyZUJ5SWQob3JnSWQsIGlkLCBub3cpO1xuICBpZiAoIXRhcmdldCB8fCB0YXJnZXQuZml4ZWRBdCkgcmV0dXJuIFtdO1xuICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHgudXBkYXRlKEUoKSlcbiAgICAuc2V0KHtcbiAgICAgIHRyaWFnZVN0YXRlOiBkZWNpc2lvbi5zdGF0ZSxcbiAgICAgIGFjY2VwdGVkVW50aWw6IGRlY2lzaW9uLnN0YXRlID09PSAnYWNjZXB0ZWQnID8gKGRlY2lzaW9uLmFjY2VwdGVkVW50aWwgPz8gbnVsbCkgOiBudWxsLFxuICAgICAgYWNjZXB0ZWRGaW5kaW5nS2V5czogZGVjaXNpb24uc3RhdGUgPT09ICdhY2NlcHRlZCcgPyBzcWxgJHtFKCkuZmluZGluZ0tleXN9YCA6IFtdLFxuICAgICAgYWNjZXB0ZWRLZXY6IGRlY2lzaW9uLnN0YXRlID09PSAnYWNjZXB0ZWQnICYmIGRlY2lzaW9uLmtldiA9PT0gdHJ1ZSxcbiAgICAgIHRyaWFnZVJlYXNvbjogZGVjaXNpb24ucmVhc29uPy50cmltKCkgfHwgbnVsbCxcbiAgICAgIHRyaWFnZWRCeTogZGVjaXNpb24uYWN0b3IsXG4gICAgICB0cmlhZ2VkQXQ6IG5vdyxcbiAgICAgIHVwZGF0ZWRBdDogbm93LFxuICAgIH0pXG4gICAgLndoZXJlKGFuZChcbiAgICAgIGVxKEUoKS5vcmdJZCwgb3JnSWQpLFxuICAgICAgZXEoRSgpLnBpcGVsaW5lSWQsIHRhcmdldC5waXBlbGluZUlkKSxcbiAgICAgIGVxKEUoKS5wbHVnaW5OYW1lLCB0YXJnZXQucGx1Z2luTmFtZSksXG4gICAgICBlcShFKCkucGx1Z2luVmVyc2lvbiwgdGFyZ2V0LnBsdWdpblZlcnNpb24pLFxuICAgICAgdGFyZ2V0LmltYWdlRGlnZXN0ID09PSBudWxsID8gaXNOdWxsKEUoKS5pbWFnZURpZ2VzdCkgOiBlcShFKCkuaW1hZ2VEaWdlc3QsIHRhcmdldC5pbWFnZURpZ2VzdCksXG4gICAgICBpc051bGwoRSgpLmZpeGVkQXQpLFxuICAgICkpXG4gICAgLnJldHVybmluZygpKTtcbiAgcmV0dXJuIChyb3dzIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PikubWFwKChyKSA9PiB0b1BpcGVsaW5lRXhwb3N1cmUociwgbm93KSk7XG59XG5cbi8qKiBgbmFtZUB2ZXJzaW9uQGRpZ2VzdGAg4oCUIHRoZSBrZXkge0BsaW5rIGFjdGl2ZUFjY2VwdGFuY2VzfSBhbnN3ZXJzIHVuZGVyLiAqL1xuZXhwb3J0IGNvbnN0IGFjY2VwdGFuY2VLZXkgPSAocGx1Z2luTmFtZTogc3RyaW5nLCBwbHVnaW5WZXJzaW9uOiBzdHJpbmcsIGltYWdlRGlnZXN0Pzogc3RyaW5nIHwgbnVsbCk6IHN0cmluZyA9PlxuICBgJHtwbHVnaW5OYW1lfUAke3BsdWdpblZlcnNpb259QCR7aW1hZ2VEaWdlc3QgPz8gJyd9YDtcblxuLyoqIEEgcGlwZWxpbmUncyBhY2NlcHRhbmNlcyBpbiBmb3JjZSwga2V5ZWQgYnkge0BsaW5rIGFjY2VwdGFuY2VLZXl9LCBwbHVzIHRoZSBhY2NlcHRlZCB2ZXJzaW9ucyBwZXIgcGx1Z2luLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQaXBlbGluZUFjY2VwdGFuY2VzIHtcbiAgYnlLZXk6IE1hcDxzdHJpbmcsIFZ1bG5BY2NlcHRhbmNlICYgeyBleHBvc3VyZUlkczogc3RyaW5nW10gfT47XG4gIC8qKiBgcGx1Z2luTmFtZWAg4oaSIHZlcnNpb25zIHdpdGggYW4gYWNjZXB0YW5jZSAodGhlIHJlc29sdmVyJ3MgYGFjY2VwdGVkVmVyc2lvbnNgIGhpbnQpLiAqL1xuICB2ZXJzaW9uc0J5UGx1Z2luOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj47XG59XG5cbi8qKlxuICogVGhlIGFjY2VwdGFuY2VzIElOIEZPUkNFIGZvciBvbmUgcGlwZWxpbmUgKGBhY2NlcHRlZGAsIHVuZml4ZWQsIGRlYWRsaW5lIGluIHRoZVxuICogZnV0dXJlKSwgbWVyZ2VkIHBlciB2ZXJzaW9uIGFuZCBpbWFnZTogdGhlIHVuaW9uIG9mIHRoZSBmaW5kaW5nIGtleXMgdGhlIHJvd3NcbiAqIGZyb3plLCBLRVYgb25seSB3aGVuIGV2ZXJ5IG1lcmdlZCByb3cgYWNjZXB0ZWQgaXQuIFJlYWRzIHVuZGVyIHRoZSBjYWxsZXInc1xuICogc2NvcGUgbmFycm93ZWQgdG8gYG9yZ0lkYDsgYSBmYWlsZWQgcmVhZCBpcyBcIm5vIGFjY2VwdGFuY2VcIiDigJQgdGhlIHN0cmljdGVyIGFuc3dlci5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFjdGl2ZUFjY2VwdGFuY2VzKG9yZ0lkOiBzdHJpbmcsIHBpcGVsaW5lSWQ6IHN0cmluZywgbm93ID0gbmV3IERhdGUoKSk6IFByb21pc2U8UGlwZWxpbmVBY2NlcHRhbmNlcz4ge1xuICBjb25zdCBvdXQ6IFBpcGVsaW5lQWNjZXB0YW5jZXMgPSB7IGJ5S2V5OiBuZXcgTWFwKCksIHZlcnNpb25zQnlQbHVnaW46IG5ldyBNYXAoKSB9O1xuICB0cnkge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3Qoe1xuICAgICAgaWQ6IEUoKS5pZCxcbiAgICAgIHBsdWdpbk5hbWU6IEUoKS5wbHVnaW5OYW1lLFxuICAgICAgcGx1Z2luVmVyc2lvbjogRSgpLnBsdWdpblZlcnNpb24sXG4gICAgICBpbWFnZURpZ2VzdDogRSgpLmltYWdlRGlnZXN0LFxuICAgICAgYWNjZXB0ZWRVbnRpbDogRSgpLmFjY2VwdGVkVW50aWwsXG4gICAgICBhY2NlcHRlZEZpbmRpbmdLZXlzOiBFKCkuYWNjZXB0ZWRGaW5kaW5nS2V5cyxcbiAgICAgIGFjY2VwdGVkS2V2OiBFKCkuYWNjZXB0ZWRLZXYsXG4gICAgfSkuZnJvbShFKCkpXG4gICAgICAud2hlcmUoYW5kKFxuICAgICAgICBlcShFKCkub3JnSWQsIG9yZ0lkKSxcbiAgICAgICAgZXEoRSgpLnBpcGVsaW5lSWQsIHBpcGVsaW5lSWQpLFxuICAgICAgICBlcShFKCkudHJpYWdlU3RhdGUsICdhY2NlcHRlZCcpLFxuICAgICAgICBpc051bGwoRSgpLmZpeGVkQXQpLFxuICAgICAgICBzcWxgJHtFKCkuYWNjZXB0ZWRVbnRpbH0gPiAke25vd31gLFxuICAgICAgKSkpIGFzIEFycmF5PHsgaWQ6IHN0cmluZzsgcGx1Z2luTmFtZTogc3RyaW5nOyBwbHVnaW5WZXJzaW9uOiBzdHJpbmc7IGltYWdlRGlnZXN0OiBzdHJpbmcgfCBudWxsOyBhY2NlcHRlZFVudGlsOiBEYXRlOyBhY2NlcHRlZEZpbmRpbmdLZXlzOiBzdHJpbmdbXTsgYWNjZXB0ZWRLZXY6IGJvb2xlYW4gfT47XG4gICAgZm9yIChjb25zdCByIG9mIHJvd3MpIHtcbiAgICAgIGNvbnN0IGtleSA9IGFjY2VwdGFuY2VLZXkoci5wbHVnaW5OYW1lLCByLnBsdWdpblZlcnNpb24sIHIuaW1hZ2VEaWdlc3QpO1xuICAgICAgY29uc3QgcHJldiA9IG91dC5ieUtleS5nZXQoa2V5KTtcbiAgICAgIG91dC5ieUtleS5zZXQoa2V5LCBwcmV2XG4gICAgICAgID8ge1xuICAgICAgICAgIGZpbmRpbmdLZXlzOiBbLi4ubmV3IFNldChbLi4ucHJldi5maW5kaW5nS2V5cywgLi4uKHIuYWNjZXB0ZWRGaW5kaW5nS2V5cyA/PyBbXSldKV0sXG4gICAgICAgICAga2V2OiBwcmV2LmtldiAmJiByLmFjY2VwdGVkS2V2LFxuICAgICAgICAgIGFjY2VwdGVkVW50aWw6IHByZXYuYWNjZXB0ZWRVbnRpbCAmJiBuZXcgRGF0ZShwcmV2LmFjY2VwdGVkVW50aWwpIDwgci5hY2NlcHRlZFVudGlsID8gcHJldi5hY2NlcHRlZFVudGlsIDogci5hY2NlcHRlZFVudGlsLFxuICAgICAgICAgIGV4cG9zdXJlSWRzOiBbLi4ucHJldi5leHBvc3VyZUlkcywgci5pZF0sXG4gICAgICAgIH1cbiAgICAgICAgOiB7IGZpbmRpbmdLZXlzOiByLmFjY2VwdGVkRmluZGluZ0tleXMgPz8gW10sIGtldjogci5hY2NlcHRlZEtldiwgYWNjZXB0ZWRVbnRpbDogci5hY2NlcHRlZFVudGlsLCBleHBvc3VyZUlkczogW3IuaWRdIH0pO1xuICAgICAgY29uc3QgdmVyc2lvbnMgPSBvdXQudmVyc2lvbnNCeVBsdWdpbi5nZXQoci5wbHVnaW5OYW1lKSA/PyBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIHZlcnNpb25zLmFkZChyLnBsdWdpblZlcnNpb24pO1xuICAgICAgb3V0LnZlcnNpb25zQnlQbHVnaW4uc2V0KHIucGx1Z2luTmFtZSwgdmVyc2lvbnMpO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLndhcm4oJ1BpcGVsaW5lIGFjY2VwdGFuY2VzIHVucmVhZGFibGU7IHRyZWF0aW5nIGFzIG5vbmUnLCB7IHBpcGVsaW5lSWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG4vKiogQW4gYWNjZXB0YW5jZSB0aGF0IGxhcHNlZCwgYXMge0BsaW5rIHJlb3BlbkxhcHNlZEFjY2VwdGFuY2VzfSByZXR1cm5zIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYXBzZWRBY2NlcHRhbmNlIHtcbiAgaWQ6IHN0cmluZztcbiAgb3JnSWQ6IHN0cmluZztcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBwbHVnaW5QdWJsaXNoZXI6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nO1xuICBpbWFnZURpZ2VzdDogc3RyaW5nIHwgbnVsbDtcbiAgdHJpYWdlZEJ5OiBzdHJpbmcgfCBudWxsO1xuICB0cmlhZ2VSZWFzb246IHN0cmluZyB8IG51bGw7XG4gIGFjY2VwdGVkVW50aWw6IERhdGUgfCBudWxsO1xufVxuXG4vKipcbiAqIFJlb3BlbiBldmVyeSBhY2NlcHRhbmNlIHdob3NlIGRlYWRsaW5lIGhhcyBwYXNzZWQsIGFuZCByZXR1cm4gdGhlbSBzbyB0aGVcbiAqIHBpcGVsaW5lIG93bmVycyBjYW4gYmUgdG9sZCAoTjMzKS4gUmVhZGVycyBhbHJlYWR5IHRyZWF0IHN1Y2ggYSByb3cgYXMgb3BlbjtcbiAqIHdyaXRpbmcgaXQgbWFrZXMgdGhlIHN0b3JlZCBzdGF0ZSB0aGUgdHJ1dGggYW5kIGdpdmVzIHRoZSBub3RpY2UgZXhhY3RseSBvbmVcbiAqIG1vbWVudCB0byBmaXJlLiBNdXN0IHJ1biB3aXRoIGEgc2NvcGUgdGhhdCBjYW4gd3JpdGUgZXZlcnkgb3JnJ3Mgcm93cyAodGhlXG4gKiBuaWdodGx5IHJlc2NhbidzIGVsZXZhdGVkIGNvbnRleHQpLiBOZXZlciB0aHJvd3MuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW9wZW5MYXBzZWRBY2NlcHRhbmNlcyhub3cgPSBuZXcgRGF0ZSgpKTogUHJvbWlzZTxMYXBzZWRBY2NlcHRhbmNlW10+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHgudXBkYXRlKEUoKSlcbiAgICAgIC5zZXQoeyB0cmlhZ2VTdGF0ZTogJ29wZW4nLCB1cGRhdGVkQXQ6IG5vdyB9KVxuICAgICAgLndoZXJlKGFuZChcbiAgICAgICAgZXEoRSgpLnRyaWFnZVN0YXRlLCAnYWNjZXB0ZWQnKSxcbiAgICAgICAgaXNOdWxsKEUoKS5maXhlZEF0KSxcbiAgICAgICAgbHRlKEUoKS5hY2NlcHRlZFVudGlsLCBub3cpLFxuICAgICAgKSlcbiAgICAgIC5yZXR1cm5pbmcoe1xuICAgICAgICBpZDogRSgpLmlkLFxuICAgICAgICBvcmdJZDogRSgpLm9yZ0lkLFxuICAgICAgICBwaXBlbGluZUlkOiBFKCkucGlwZWxpbmVJZCxcbiAgICAgICAgcGx1Z2luUHVibGlzaGVyOiBFKCkucGx1Z2luUHVibGlzaGVyLFxuICAgICAgICBwbHVnaW5OYW1lOiBFKCkucGx1Z2luTmFtZSxcbiAgICAgICAgcGx1Z2luVmVyc2lvbjogRSgpLnBsdWdpblZlcnNpb24sXG4gICAgICAgIGltYWdlRGlnZXN0OiBFKCkuaW1hZ2VEaWdlc3QsXG4gICAgICAgIHRyaWFnZWRCeTogRSgpLnRyaWFnZWRCeSxcbiAgICAgICAgdHJpYWdlUmVhc29uOiBFKCkudHJpYWdlUmVhc29uLFxuICAgICAgICBhY2NlcHRlZFVudGlsOiBFKCkuYWNjZXB0ZWRVbnRpbCxcbiAgICAgIH0pKTtcbiAgICByZXR1cm4gcm93cyBhcyBMYXBzZWRBY2NlcHRhbmNlW107XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdMYXBzZWQgYWNjZXB0YW5jZXMgbm90IHJlb3BlbmVkJywgeyBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgcmV0dXJuIFtdO1xuICB9XG59XG5cbi8qKlxuICogRXhwb3N1cmVzIHdob3NlIGFjY2VwdGFuY2UgaGFzIGxhcHNlZCwgZm9yIHRoZSBvcmcncyBzZWN1cml0eSBub3RpZmljYXRpb25zLlxuICpcbiAqIFN1cmZhY2VkIHJhdGhlciB0aGFuIHNpbGVudGx5IHJlb3BlbmVkOiBzb21lYm9keSBkZWNpZGVkIHRvIGFjY2VwdCB0aGlzIHVudGlsIGFcbiAqIGRhdGUsIHRoYXQgZGF0ZSBoYXMgcGFzc2VkLCBhbmQgdGhlIHBlcnNvbiB3aG8gZGVjaWRlZCBpcyB0aGUgb25lIHdobyBzaG91bGRcbiAqIGhlYXIgYWJvdXQgaXQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsYXBzZWRBY2NlcHRhbmNlcyhvcmdJZDogc3RyaW5nLCBub3cgPSBuZXcgRGF0ZSgpKTogUHJvbWlzZTxBcnJheTx7XG4gIGlkOiBzdHJpbmc7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nO1xuICB0cmlhZ2VkQnk6IHN0cmluZyB8IG51bGw7XG4gIGFjY2VwdGVkVW50aWw6IERhdGUgfCBudWxsO1xufT4+IHtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LnNlbGVjdCh7XG4gICAgaWQ6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaWQsXG4gICAgcGx1Z2luTmFtZTogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5wbHVnaW5OYW1lLFxuICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luVmVyc2lvbixcbiAgICB0cmlhZ2VkQnk6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudHJpYWdlZEJ5LFxuICAgIGFjY2VwdGVkVW50aWw6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuYWNjZXB0ZWRVbnRpbCxcbiAgfSkuZnJvbShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlKVxuICAgIC53aGVyZShhbmQoXG4gICAgICBlcShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLm9yZ0lkLCBvcmdJZCksXG4gICAgICBlcShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnRyaWFnZVN0YXRlLCAnYWNjZXB0ZWQnKSxcbiAgICAgIGlzTnVsbChzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmZpeGVkQXQpLFxuICAgICAgbHRlKHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuYWNjZXB0ZWRVbnRpbCwgbm93KSxcbiAgICApKSk7XG4gIHJldHVybiByb3dzIGFzIEFycmF5PHsgaWQ6IHN0cmluZzsgcGx1Z2luTmFtZTogc3RyaW5nOyBwbHVnaW5WZXJzaW9uOiBzdHJpbmc7IHRyaWFnZWRCeTogc3RyaW5nIHwgbnVsbDsgYWNjZXB0ZWRVbnRpbDogRGF0ZSB8IG51bGwgfT47XG59XG4iXX0=