@pipeline-builder/pipeline-data 4.3.11 → 4.3.12

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.
@@ -22,10 +22,42 @@
22
22
  * Matched by image digest when the version has one (a team running its parent's
23
23
  * plugin, or another org's install, pins the same digest), else by name +
24
24
  * version within the owner org and its teams.
25
+ *
26
+ * A MANAGED TOOLCHAIN half (the system org's `pipeline-bootstrap` / `cdk-synth`,
27
+ * docs/plans/bootstrap-image-versioning.md §4/§5) is referenced whenever its
28
+ * RELEASE is: a pipeline deploying or declaring EITHER half of the same version
29
+ * references both. A pipeline that only runs the release's build image (the
30
+ * manifest's non-step `build-image` row) still holds its synth half, and the
31
+ * reverse — the release is one unit, created, deleted and purged together.
25
32
  */
33
+ import { BUILD_IMAGE_STEP_KEY, isManagedToolchainPlugin, isSystemOrgId, MANAGED_TOOLCHAIN_PLUGINS, SYSTEM_ORG_ID, } from '@pipeline-builder/api-core';
26
34
  import { sql } from 'drizzle-orm';
27
35
  import { executeRows } from '../database/pg-result.js';
28
36
  import { withTenantTx } from '../database/tenancy.js';
37
+ /** The managed toolchain names as an SQL list (constants, never input). */
38
+ const MANAGED_NAMES_SQL = sql.raw(MANAGED_TOOLCHAIN_PLUGINS.map((n) => `'${n}'`).join(', '));
39
+ const SYSTEM_ORG_ID_LOWER = SYSTEM_ORG_ID.toLowerCase();
40
+ /**
41
+ * "This row is a release half whose RELEASE some pipeline references": a
42
+ * system-org managed row, and a manifest / resolution / open deployed exposure
43
+ * naming either half at its version. Managed names are reserved to the system
44
+ * org, so a publisher-less row with one IS that release's.
45
+ */
46
+ function managedReleaseReferenced(cols) {
47
+ // COALESCE: a caller passing NULL columns (the listing image GC) must read
48
+ // FALSE here, never NULL — `NOT NULL` would silently keep every image.
49
+ return sql `COALESCE(lower(${cols.orgId}) = ${SYSTEM_ORG_ID_LOWER} AND ${cols.name} IN (${MANAGED_NAMES_SQL}) AND (
50
+ EXISTS (SELECT 1 FROM pipeline_step_manifests m WHERE m.plugin_name IN (${MANAGED_NAMES_SQL}) AND m.plugin_version = ${cols.version}
51
+ AND m.plugin_publisher IS NULL)
52
+ OR EXISTS (SELECT 1 FROM pipeline_plugin_resolution r JOIN pipelines lp ON lp.id::text = r.pipeline_id AND lp.deleted_at IS NULL
53
+ WHERE r.plugin_name IN (${MANAGED_NAMES_SQL}) AND r.resolved_version = ${cols.version} AND r.plugin_publisher IS NULL)
54
+ OR EXISTS (SELECT 1 FROM plugin_vuln_exposure e WHERE e.plugin_name IN (${MANAGED_NAMES_SQL}) AND e.plugin_version = ${cols.version}
55
+ AND e.plugin_publisher IS NULL AND e.source = 'deployed' AND e.fixed_at IS NULL)), false)`;
56
+ }
57
+ /** Whether `target` is a managed toolchain half (matched release-wide, see the module doc). */
58
+ function isManagedReleaseTarget(target) {
59
+ return isManagedToolchainPlugin(target.pluginName) && !target.publisher && isSystemOrgId(target.ownerOrgId ?? '');
60
+ }
29
61
  /**
30
62
  * The SQL predicate "some pipeline references this row's image / version", over
31
63
  * a `plugins`-shaped row's columns — the purge guard's form of
@@ -33,6 +65,7 @@ import { withTenantTx } from '../database/tenancy.js';
33
65
  */
34
66
  export function versionReferencedPredicate(cols) {
35
67
  return sql `(
68
+ ${managedReleaseReferenced(cols)} OR
36
69
  (${cols.digest} IS NOT NULL AND (
37
70
  EXISTS (SELECT 1 FROM pipeline_step_manifests m WHERE m.image_digest = ${cols.digest})
38
71
  OR EXISTS (SELECT 1 FROM pipeline_plugin_resolution r JOIN pipelines p ON p.id::text = r.pipeline_id AND p.deleted_at IS NULL
@@ -52,9 +85,14 @@ export function versionReferencedPredicate(cols) {
52
85
  * names other orgs' pipelines; callers show the OWNER only counts and its own
53
86
  * org's pipelines, and notify each referencing org about its own.
54
87
  */
55
- export async function findVersionReferences(target) {
88
+ export async function findVersionReferences(target, run = withTenantTx) {
56
89
  const digest = target.imageDigest ?? null;
57
90
  const owner = target.ownerOrgId?.toLowerCase() ?? null;
91
+ const managed = isManagedReleaseTarget(target);
92
+ // A managed half: either half of the release, at its version (module doc).
93
+ const release = (alias, versionCol) => (managed
94
+ ? sql ` OR (${sql.raw(`${alias}.plugin_name`)} IN (${MANAGED_NAMES_SQL}) AND ${sql.raw(`${alias}.${versionCol}`)} = ${target.pluginVersion} AND ${sql.raw(`${alias}.plugin_publisher`)} IS NULL)`
95
+ : sql ``);
58
96
  const declaredMatch = digest
59
97
  ? sql `r.resolved_digest = ${digest}`
60
98
  : sql `r.plugin_name = ${target.pluginName} AND r.resolved_version = ${target.pluginVersion}
@@ -67,7 +105,7 @@ export async function findVersionReferences(target) {
67
105
  ? sql `e.image_digest = ${digest}`
68
106
  : sql `e.plugin_name = ${target.pluginName} AND e.plugin_version = ${target.pluginVersion}
69
107
  AND ${target.publisher ? sql `e.plugin_publisher = ${target.publisher}` : sql `e.plugin_publisher IS NULL AND lower(e.org_id) = ${owner}`}`;
70
- const rows = await withTenantTx((tx) => executeRows(tx, sql `
108
+ const rows = await run((tx) => executeRows(tx, sql `
71
109
  SELECT x.pipeline_id, x.org_id, x.source, p.pipeline_name, (p.id IS NULL OR p.deleted_at IS NOT NULL) AS deleted,
72
110
  array_agg(DISTINCT x.step) FILTER (WHERE x.step IS NOT NULL) AS steps
73
111
  FROM (
@@ -75,13 +113,14 @@ export async function findVersionReferences(target) {
75
113
  CASE WHEN r.stage_name = 'synth' AND r.step_name = 'synth' THEN 'synth' ELSE r.stage_name || '/' || r.step_name END AS step
76
114
  FROM pipeline_plugin_resolution r
77
115
  JOIN pipelines lp ON lp.id::text = r.pipeline_id AND lp.deleted_at IS NULL
78
- WHERE ${declaredMatch}
116
+ WHERE (${declaredMatch}${release('r', 'resolved_version')})
79
117
  UNION ALL
80
- SELECT m.pipeline_id::text, m.org_id, 'deployed', m.stage_name || '/' || m.action_name
81
- FROM pipeline_step_manifests m WHERE ${deployedMatch}
118
+ SELECT m.pipeline_id::text, m.org_id, 'deployed',
119
+ CASE WHEN m.step_key = ${BUILD_IMAGE_STEP_KEY} THEN ${BUILD_IMAGE_STEP_KEY} ELSE m.stage_name || '/' || m.action_name END
120
+ FROM pipeline_step_manifests m WHERE (${deployedMatch}${release('m', 'plugin_version')})
82
121
  UNION ALL
83
122
  SELECT e.pipeline_id, e.org_id, 'exposure', NULL
84
- FROM plugin_vuln_exposure e WHERE ${exposureMatch} AND e.source = 'deployed' AND e.fixed_at IS NULL
123
+ FROM plugin_vuln_exposure e WHERE (${exposureMatch}${release('e', 'plugin_version')}) AND e.source = 'deployed' AND e.fixed_at IS NULL
85
124
  ) x
86
125
  LEFT JOIN pipelines p ON p.id::text = x.pipeline_id
87
126
  GROUP BY x.pipeline_id, x.org_id, x.source, p.pipeline_name, p.id, p.deleted_at
@@ -132,4 +171,4 @@ export async function orgImageDigestsInUse(orgId) {
132
171
  `));
133
172
  return rows.map((r) => r.d);
134
173
  }
135
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi1yZWZlcmVuY2VzLmpzIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3ZlcnNpb24tcmVmZXJlbmNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBRUgsT0FBTyxFQUFFLEdBQUcsRUFBWSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBd0J0RDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUFDLElBQTBEO0lBQ25HLE9BQU8sR0FBRyxDQUFBO09BQ0wsSUFBSSxDQUFDLE1BQU07K0VBQzZELElBQUksQ0FBQyxNQUFNOzs4Q0FFNUMsSUFBSSxDQUFDLE1BQU07K0VBQ3NCLElBQUksQ0FBQyxNQUFNO1VBQ2hGLElBQUksQ0FBQyxNQUFNOzhFQUN5RCxJQUFJLENBQUMsSUFBSSwyQkFBMkIsSUFBSSxDQUFDLE9BQU87NkVBQ2pELElBQUksQ0FBQyxLQUFLOzswQ0FFN0MsSUFBSSxDQUFDLElBQUksNkJBQTZCLElBQUksQ0FBQyxPQUFPO21EQUN6QyxJQUFJLENBQUMsS0FBSyxxQ0FBcUMsSUFBSSxDQUFDLEtBQUs7SUFDeEcsQ0FBQztBQUNMLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUscUJBQXFCLENBQUMsTUFBOEI7SUFDeEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUM7SUFDMUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsSUFBSSxJQUFJLENBQUM7SUFDdkQsTUFBTSxhQUFhLEdBQUcsTUFBTTtRQUMxQixDQUFDLENBQUMsR0FBRyxDQUFBLHVCQUF1QixNQUFNLEVBQUU7UUFD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QyxDQUFDLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUNELE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FBQyxLQUFhO0lBQ3RELE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNoQyxNQUFNLElBQUksR0FBRyxNQUFNLFlBQVksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsV0FBVyxDQUFnQixFQUFFLEVBQUUsR0FBRyxDQUFBOztvRUFFUixHQUFHOzsyRUFFSSxHQUFHLDhCQUE4QixHQUFHOzsrSEFFZ0IsR0FBRzswSEFDUixHQUFHOzt3SEFFTCxHQUFHOztHQUV4SCxDQUFDLENBQUMsQ0FBQztJQUNKLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBXaGljaCBwaXBlbGluZXMgc3RpbGwgUkVGRVJFTkNFIGEgcGx1Z2luIHZlcnNpb24gb3IgaW1hZ2Ug4oCUIHRoZSBvbmUgcnVsZSBldmVyeVxuICogcmVtb3ZhbCBwYXRoIGFza3MgYmVmb3JlIGl0IGRlbGV0ZXMgYW55dGhpbmc6IGFuIG9yZyBwbHVnaW4gZGVsZXRlIChmb3JjZWQgb3JcbiAqIG5vdCksIGEgYnVsayBkZWxldGUsIGEgdG9tYnN0b25lIHB1cmdlIChtYW51YWwgb3IgdGhlIHJldGVudGlvbiBzd2VlcCksIHRoZVxuICogaW1hZ2UgcmVnaXN0cnkncyBhZ2UgR0MsIHRoZSBsaXN0aW5nIGltYWdlIEdDLlxuICpcbiAqIFRIRSBSVUxFOiBhIHZlcnNpb24gKG9yIGl0cyBpbWFnZSkgdGhhdCBhbnkgcGlwZWxpbmUgcmVmZXJlbmNlcyBjYW5ub3QgYmVcbiAqIGRlbGV0ZWQgdW50aWwgbm8gcGlwZWxpbmUgZG9lcyDigJQgd2hhdGV2ZXIgaXRzIHZ1bG5lcmFiaWxpdHkgc3RhdGUuIEFcbiAqIHZ1bG5lcmFibGUgaW1hZ2UgaXMgdGhlIFdPUlNUIHRoaW5nIHRvIGRlbGV0ZSBvdXQgZnJvbSB1bmRlciBhIHBpcGVsaW5lOiB0aGVcbiAqIG5leHQgcnVuIGZhaWxzIHRvIHB1bGwsIGFuZCB0aGUgb3duZXJzIGxlYXJuIGFib3V0IHRoZSBDVkUgZnJvbSBhbiBvdXRhZ2UuXG4gKiBWdWxuZXJhYmlsaXR5IGNvbnNlcXVlbmNlcyBhcmUgZ3JhZGVkIHdhcm5pbmdzIGFuZCBub3RpZmljYXRpb25zLCBuZXZlciByZW1vdmFsLlxuICpcbiAqIEEgcmVmZXJlbmNlIGlzIGFueSBvZjpcbiAqICAtIGBkZWNsYXJlZGAg4oCUIGEgTElWRSBwaXBlbGluZSdzIGNvbmZpZyByZXNvbHZlcyB0byBpdCAoYHBpcGVsaW5lX3BsdWdpbl9yZXNvbHV0aW9uYCk7XG4gKiAgLSBgZGVwbG95ZWRgIOKAlCBhIHBpcGVsaW5lJ3MgbGFzdCBkZXBsb3kgcmVjb3JkZWQgaXQgKGBwaXBlbGluZV9zdGVwX21hbmlmZXN0c2ApLFxuICogICAgSU5DTFVESU5HIGEgc29mdC1kZWxldGVkIHBpcGVsaW5lOiBpdHMgQ29kZVBpcGVsaW5lIHN0aWxsIHJ1bnMgdGhlIGltYWdlO1xuICogIC0gYGV4cG9zdXJlYCDigJQgYW4gb3BlbiBERVBMT1lFRCBleHBvc3VyZSBzdGlsbCBuYW1lcyBpdCAodGhlIHNhbWUgXCJzdGlsbCBydW5zXG4gKiAgICBpdFwiIGZhY3QsIGtlcHQgd2hlbiBhIG1hbmlmZXN0IGlzIGdvbmUpLlxuICpcbiAqIE1hdGNoZWQgYnkgaW1hZ2UgZGlnZXN0IHdoZW4gdGhlIHZlcnNpb24gaGFzIG9uZSAoYSB0ZWFtIHJ1bm5pbmcgaXRzIHBhcmVudCdzXG4gKiBwbHVnaW4sIG9yIGFub3RoZXIgb3JnJ3MgaW5zdGFsbCwgcGlucyB0aGUgc2FtZSBkaWdlc3QpLCBlbHNlIGJ5IG5hbWUgK1xuICogdmVyc2lvbiB3aXRoaW4gdGhlIG93bmVyIG9yZyBhbmQgaXRzIHRlYW1zLlxuICovXG5cbmltcG9ydCB7IHNxbCwgdHlwZSBTUUwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBleGVjdXRlUm93cyB9IGZyb20gJy4uL2RhdGFiYXNlL3BnLXJlc3VsdC5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHggfSBmcm9tICcuLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuLyoqIEEgdmVyc2lvbiAvIGltYWdlIHdob3NlIHJlZmVyZW5jZXMgYXJlIHdhbnRlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmVyc2lvblJlZmVyZW5jZVRhcmdldCB7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nO1xuICBpbWFnZURpZ2VzdD86IHN0cmluZyB8IG51bGw7XG4gIC8qKiBUaGUgb3duaW5nIG9yZyBvZiBhbiBvcmcgcGx1Z2luIChpdHMgdGVhbXMgY291bnQgdG9vKTsgb21pdHRlZCBmb3IgYSBsaXN0aW5nIHZlcnNpb24uICovXG4gIG93bmVyT3JnSWQ/OiBzdHJpbmcgfCBudWxsO1xuICAvKiogVGhlIGxpc3RpbmcncyBwdWJsaXNoZXIgaGFuZGxlIChhIGxpc3RpbmcgdmVyc2lvbik7IG51bGwvb21pdHRlZCBmb3IgYW4gb3JnIHBsdWdpbi4gKi9cbiAgcHVibGlzaGVyPzogc3RyaW5nIHwgbnVsbDtcbn1cblxuLyoqIE9uZSBwaXBlbGluZSByZWZlcmVuY2luZyBhIHZlcnNpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIFZlcnNpb25SZWZlcmVuY2Uge1xuICBwaXBlbGluZUlkOiBzdHJpbmc7XG4gIHBpcGVsaW5lTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgb3JnSWQ6IHN0cmluZztcbiAgc291cmNlOiAnZGVjbGFyZWQnIHwgJ2RlcGxveWVkJyB8ICdleHBvc3VyZSc7XG4gIC8qKiBUaGUgcGlwZWxpbmUgaXMgc29mdC1kZWxldGVkIChzdGlsbCBkZXBsb3llZDogaXRzIG1hbmlmZXN0IG9yIGV4cG9zdXJlIHJlbWFpbnMpLiAqL1xuICBwaXBlbGluZURlbGV0ZWQ6IGJvb2xlYW47XG4gIHN0ZXBzOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBUaGUgU1FMIHByZWRpY2F0ZSBcInNvbWUgcGlwZWxpbmUgcmVmZXJlbmNlcyB0aGlzIHJvdydzIGltYWdlIC8gdmVyc2lvblwiLCBvdmVyXG4gKiBhIGBwbHVnaW5zYC1zaGFwZWQgcm93J3MgY29sdW1ucyDigJQgdGhlIHB1cmdlIGd1YXJkJ3MgZm9ybSBvZlxuICoge0BsaW5rIGZpbmRWZXJzaW9uUmVmZXJlbmNlc30gKHNhbWUgdGhyZWUgc291cmNlcywgc2FtZSBtYXRjaGluZykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJzaW9uUmVmZXJlbmNlZFByZWRpY2F0ZShjb2xzOiB7IGRpZ2VzdDogU1FMOyBuYW1lOiBTUUw7IHZlcnNpb246IFNRTDsgb3JnSWQ6IFNRTCB9KTogU1FMIHtcbiAgcmV0dXJuIHNxbGAoXG4gICAgKCR7Y29scy5kaWdlc3R9IElTIE5PVCBOVUxMIEFORCAoXG4gICAgICBFWElTVFMgKFNFTEVDVCAxIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbSBXSEVSRSBtLmltYWdlX2RpZ2VzdCA9ICR7Y29scy5kaWdlc3R9KVxuICAgICAgT1IgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIHBpcGVsaW5lX3BsdWdpbl9yZXNvbHV0aW9uIHIgSk9JTiBwaXBlbGluZXMgcCBPTiBwLmlkOjp0ZXh0ID0gci5waXBlbGluZV9pZCBBTkQgcC5kZWxldGVkX2F0IElTIE5VTExcbiAgICAgICAgICAgICAgICAgIFdIRVJFIHIucmVzb2x2ZWRfZGlnZXN0ID0gJHtjb2xzLmRpZ2VzdH0pXG4gICAgICBPUiBFWElTVFMgKFNFTEVDVCAxIEZST00gcGx1Z2luX3Z1bG5fZXhwb3N1cmUgZSBXSEVSRSBlLmltYWdlX2RpZ2VzdCA9ICR7Y29scy5kaWdlc3R9IEFORCBlLnNvdXJjZSA9ICdkZXBsb3llZCcgQU5EIGUuZml4ZWRfYXQgSVMgTlVMTCkpKVxuICAgIE9SICgke2NvbHMuZGlnZXN0fSBJUyBOVUxMIEFORCAoXG4gICAgICBFWElTVFMgKFNFTEVDVCAxIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbSBXSEVSRSBtLnBsdWdpbl9uYW1lID0gJHtjb2xzLm5hbWV9IEFORCBtLnBsdWdpbl92ZXJzaW9uID0gJHtjb2xzLnZlcnNpb259XG4gICAgICAgICAgICAgICAgQU5EIG0ucGx1Z2luX3B1Ymxpc2hlciBJUyBOVUxMIEFORCBsb3dlcihtLm9yZ19pZCkgPSBsb3dlcigke2NvbHMub3JnSWR9KSlcbiAgICAgIE9SIEVYSVNUUyAoU0VMRUNUIDEgRlJPTSBwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbiByIEpPSU4gcGlwZWxpbmVzIHAgT04gcC5pZDo6dGV4dCA9IHIucGlwZWxpbmVfaWQgQU5EIHAuZGVsZXRlZF9hdCBJUyBOVUxMXG4gICAgICAgICAgICAgICAgICBXSEVSRSByLnBsdWdpbl9uYW1lID0gJHtjb2xzLm5hbWV9IEFORCByLnJlc29sdmVkX3ZlcnNpb24gPSAke2NvbHMudmVyc2lvbn0gQU5EIHIucGx1Z2luX3B1Ymxpc2hlciBJUyBOVUxMXG4gICAgICAgICAgICAgICAgICAgIEFORCAobG93ZXIoci5vcmdfaWQpID0gbG93ZXIoJHtjb2xzLm9yZ0lkfSkgT1IgbG93ZXIoci5yb290X29yZ19pZCkgPSBsb3dlcigke2NvbHMub3JnSWR9KSkpKSlcbiAgKWA7XG59XG5cbi8qKlxuICogRXZlcnkgcGlwZWxpbmUgcmVmZXJlbmNpbmcgYHRhcmdldGAgKHNlZSB0aGUgbW9kdWxlIGRvYyksIGFjcm9zcyBvcmdzIOKAlCBzbyBpdFxuICogbXVzdCBydW4gd2l0aCBhIHNjb3BlIHRoYXQgY2FuIHJlYWQgZXZlcnkgb3JnJ3Mgcm93cyAoZWxldmF0ZWQpLiBUaGUgcmVzdWx0XG4gKiBuYW1lcyBvdGhlciBvcmdzJyBwaXBlbGluZXM7IGNhbGxlcnMgc2hvdyB0aGUgT1dORVIgb25seSBjb3VudHMgYW5kIGl0cyBvd25cbiAqIG9yZydzIHBpcGVsaW5lcywgYW5kIG5vdGlmeSBlYWNoIHJlZmVyZW5jaW5nIG9yZyBhYm91dCBpdHMgb3duLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluZFZlcnNpb25SZWZlcmVuY2VzKHRhcmdldDogVmVyc2lvblJlZmVyZW5jZVRhcmdldCk6IFByb21pc2U8VmVyc2lvblJlZmVyZW5jZVtdPiB7XG4gIGNvbnN0IGRpZ2VzdCA9IHRhcmdldC5pbWFnZURpZ2VzdCA/PyBudWxsO1xuICBjb25zdCBvd25lciA9IHRhcmdldC5vd25lck9yZ0lkPy50b0xvd2VyQ2FzZSgpID8/IG51bGw7XG4gIGNvbnN0IGRlY2xhcmVkTWF0Y2ggPSBkaWdlc3RcbiAgICA/IHNxbGByLnJlc29sdmVkX2RpZ2VzdCA9ICR7ZGlnZXN0fWBcbiAgICA6IHNxbGByLnBsdWdpbl9uYW1lID0gJHt0YXJnZXQucGx1Z2luTmFtZX0gQU5EIHIucmVzb2x2ZWRfdmVyc2lvbiA9ICR7dGFyZ2V0LnBsdWdpblZlcnNpb259XG4gICAgICAgICAgQU5EICR7dGFyZ2V0LnB1Ymxpc2hlciA/IHNxbGByLnBsdWdpbl9wdWJsaXNoZXIgPSAke3RhcmdldC5wdWJsaXNoZXJ9YCA6IHNxbGByLnBsdWdpbl9wdWJsaXNoZXIgSVMgTlVMTCBBTkQgKGxvd2VyKHIub3JnX2lkKSA9ICR7b3duZXJ9IE9SIGxvd2VyKHIucm9vdF9vcmdfaWQpID0gJHtvd25lcn0pYH1gO1xuICBjb25zdCBkZXBsb3llZE1hdGNoID0gZGlnZXN0XG4gICAgPyBzcWxgbS5pbWFnZV9kaWdlc3QgPSAke2RpZ2VzdH1gXG4gICAgOiBzcWxgbS5wbHVnaW5fbmFtZSA9ICR7dGFyZ2V0LnBsdWdpbk5hbWV9IEFORCBtLnBsdWdpbl92ZXJzaW9uID0gJHt0YXJnZXQucGx1Z2luVmVyc2lvbn1cbiAgICAgICAgICBBTkQgJHt0YXJnZXQucHVibGlzaGVyID8gc3FsYG0ucGx1Z2luX3B1Ymxpc2hlciA9ICR7dGFyZ2V0LnB1Ymxpc2hlcn1gIDogc3FsYG0ucGx1Z2luX3B1Ymxpc2hlciBJUyBOVUxMIEFORCBsb3dlcihtLm9yZ19pZCkgPSAke293bmVyfWB9YDtcbiAgY29uc3QgZXhwb3N1cmVNYXRjaCA9IGRpZ2VzdFxuICAgID8gc3FsYGUuaW1hZ2VfZGlnZXN0ID0gJHtkaWdlc3R9YFxuICAgIDogc3FsYGUucGx1Z2luX25hbWUgPSAke3RhcmdldC5wbHVnaW5OYW1lfSBBTkQgZS5wbHVnaW5fdmVyc2lvbiA9ICR7dGFyZ2V0LnBsdWdpblZlcnNpb259XG4gICAgICAgICAgQU5EICR7dGFyZ2V0LnB1Ymxpc2hlciA/IHNxbGBlLnBsdWdpbl9wdWJsaXNoZXIgPSAke3RhcmdldC5wdWJsaXNoZXJ9YCA6IHNxbGBlLnBsdWdpbl9wdWJsaXNoZXIgSVMgTlVMTCBBTkQgbG93ZXIoZS5vcmdfaWQpID0gJHtvd25lcn1gfWA7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiBleGVjdXRlUm93czx7IHBpcGVsaW5lX2lkOiBzdHJpbmc7IG9yZ19pZDogc3RyaW5nOyBzb3VyY2U6IFZlcnNpb25SZWZlcmVuY2VbJ3NvdXJjZSddOyBwaXBlbGluZV9uYW1lOiBzdHJpbmcgfCBudWxsOyBkZWxldGVkOiBib29sZWFuOyBzdGVwczogc3RyaW5nW10gfCBudWxsIH0+KHR4LCBzcWxgXG4gICAgU0VMRUNUIHgucGlwZWxpbmVfaWQsIHgub3JnX2lkLCB4LnNvdXJjZSwgcC5waXBlbGluZV9uYW1lLCAocC5pZCBJUyBOVUxMIE9SIHAuZGVsZXRlZF9hdCBJUyBOT1QgTlVMTCkgQVMgZGVsZXRlZCxcbiAgICAgICAgICAgYXJyYXlfYWdnKERJU1RJTkNUIHguc3RlcCkgRklMVEVSIChXSEVSRSB4LnN0ZXAgSVMgTk9UIE5VTEwpIEFTIHN0ZXBzXG4gICAgICBGUk9NIChcbiAgICAgICAgU0VMRUNUIHIucGlwZWxpbmVfaWQsIHIub3JnX2lkLCAnZGVjbGFyZWQnIEFTIHNvdXJjZSxcbiAgICAgICAgICAgICAgIENBU0UgV0hFTiByLnN0YWdlX25hbWUgPSAnc3ludGgnIEFORCByLnN0ZXBfbmFtZSA9ICdzeW50aCcgVEhFTiAnc3ludGgnIEVMU0Ugci5zdGFnZV9uYW1lIHx8ICcvJyB8fCByLnN0ZXBfbmFtZSBFTkQgQVMgc3RlcFxuICAgICAgICAgIEZST00gcGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb24gclxuICAgICAgICAgIEpPSU4gcGlwZWxpbmVzIGxwIE9OIGxwLmlkOjp0ZXh0ID0gci5waXBlbGluZV9pZCBBTkQgbHAuZGVsZXRlZF9hdCBJUyBOVUxMXG4gICAgICAgICBXSEVSRSAke2RlY2xhcmVkTWF0Y2h9XG4gICAgICAgIFVOSU9OIEFMTFxuICAgICAgICBTRUxFQ1QgbS5waXBlbGluZV9pZDo6dGV4dCwgbS5vcmdfaWQsICdkZXBsb3llZCcsIG0uc3RhZ2VfbmFtZSB8fCAnLycgfHwgbS5hY3Rpb25fbmFtZVxuICAgICAgICAgIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbSBXSEVSRSAke2RlcGxveWVkTWF0Y2h9XG4gICAgICAgIFVOSU9OIEFMTFxuICAgICAgICBTRUxFQ1QgZS5waXBlbGluZV9pZCwgZS5vcmdfaWQsICdleHBvc3VyZScsIE5VTExcbiAgICAgICAgICBGUk9NIHBsdWdpbl92dWxuX2V4cG9zdXJlIGUgV0hFUkUgJHtleHBvc3VyZU1hdGNofSBBTkQgZS5zb3VyY2UgPSAnZGVwbG95ZWQnIEFORCBlLmZpeGVkX2F0IElTIE5VTExcbiAgICAgICkgeFxuICAgICAgTEVGVCBKT0lOIHBpcGVsaW5lcyBwIE9OIHAuaWQ6OnRleHQgPSB4LnBpcGVsaW5lX2lkXG4gICAgIEdST1VQIEJZIHgucGlwZWxpbmVfaWQsIHgub3JnX2lkLCB4LnNvdXJjZSwgcC5waXBlbGluZV9uYW1lLCBwLmlkLCBwLmRlbGV0ZWRfYXRcbiAgICAgT1JERVIgQlkgeC5vcmdfaWQsIHgucGlwZWxpbmVfaWQsIHguc291cmNlXG4gIGApKTtcbiAgcmV0dXJuIHJvd3MubWFwKChyKSA9PiAoe1xuICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVfaWQsXG4gICAgcGlwZWxpbmVOYW1lOiByLnBpcGVsaW5lX25hbWUgPz8gbnVsbCxcbiAgICBvcmdJZDogci5vcmdfaWQsXG4gICAgc291cmNlOiByLnNvdXJjZSxcbiAgICBwaXBlbGluZURlbGV0ZWQ6IHIuZGVsZXRlZCA9PT0gdHJ1ZSxcbiAgICBzdGVwczogci5zdGVwcyA/PyBbXSxcbiAgfSkpO1xufVxuXG4vKiogRGlzdGluY3QgcGlwZWxpbmVzIGFtb25nIGByZWZzYCAoYSBwaXBlbGluZSBib3RoIGRlY2xhcmVkIGFuZCBkZXBsb3llZCBjb3VudHMgb25jZSkuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzdGluY3RQaXBlbGluZXMocmVmczogcmVhZG9ubHkgVmVyc2lvblJlZmVyZW5jZVtdKTogQXJyYXk8eyBwaXBlbGluZUlkOiBzdHJpbmc7IHBpcGVsaW5lTmFtZTogc3RyaW5nIHwgbnVsbDsgb3JnSWQ6IHN0cmluZzsgc291cmNlczogc3RyaW5nW107IHBpcGVsaW5lRGVsZXRlZDogYm9vbGVhbjsgc3RlcHM6IHN0cmluZ1tdIH0+IHtcbiAgY29uc3QgYnlJZCA9IG5ldyBNYXA8c3RyaW5nLCB7IHBpcGVsaW5lSWQ6IHN0cmluZzsgcGlwZWxpbmVOYW1lOiBzdHJpbmcgfCBudWxsOyBvcmdJZDogc3RyaW5nOyBzb3VyY2VzOiBzdHJpbmdbXTsgcGlwZWxpbmVEZWxldGVkOiBib29sZWFuOyBzdGVwczogc3RyaW5nW10gfT4oKTtcbiAgZm9yIChjb25zdCByIG9mIHJlZnMpIHtcbiAgICBjb25zdCBlID0gYnlJZC5nZXQoci5waXBlbGluZUlkKSA/PyB7IHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCwgcGlwZWxpbmVOYW1lOiByLnBpcGVsaW5lTmFtZSwgb3JnSWQ6IHIub3JnSWQsIHNvdXJjZXM6IFtdLCBwaXBlbGluZURlbGV0ZWQ6IHIucGlwZWxpbmVEZWxldGVkLCBzdGVwczogW10gfTtcbiAgICBpZiAoIWUuc291cmNlcy5pbmNsdWRlcyhyLnNvdXJjZSkpIGUuc291cmNlcy5wdXNoKHIuc291cmNlKTtcbiAgICBlLnN0ZXBzID0gWy4uLm5ldyBTZXQoWy4uLmUuc3RlcHMsIC4uLnIuc3RlcHNdKV07XG4gICAgYnlJZC5zZXQoci5waXBlbGluZUlkLCBlKTtcbiAgfVxuICByZXR1cm4gWy4uLmJ5SWQudmFsdWVzKCldO1xufVxuXG4vKipcbiAqIFRoZSBpbWFnZSBkaWdlc3RzIGFuIG9yZydzIG5hbWVzcGFjZSBzdGlsbCBuZWVkczogZXZlcnkgYHBsdWdpbnNgIHJvdydzXG4gKiBkaWdlc3QgKGFjdGl2ZSwgaW5hY3RpdmUgb3Igc29mdC1kZWxldGVkIOKAlCBhIHRvbWJzdG9uZSBpcyByZXN0b3JhYmxlIHVudGlsXG4gKiBwdXJnZWQsIGFuZCB0aGUgcHVyZ2UgaXRzZWxmIGlzIGd1YXJkZWQpIHBsdXMgZXZlcnkgZGlnZXN0IGEgcGlwZWxpbmUgb2YgdGhlXG4gKiBvcmcgb3IgaXRzIHRlYW1zIGRlY2xhcmVzLCBydW5zIG9yIGhhcyBhbiBvcGVuIGRlcGxveWVkIGV4cG9zdXJlIG9uLiBXaGF0IHRoZVxuICogaW1hZ2UgcmVnaXN0cnkncyBhZ2UgR0MgY29uc3VsdHMgYmVmb3JlIGRlbGV0aW5nIGFueXRoaW5nIGluIGBvcmctPGlkPi8qYC5cbiAqIEVsZXZhdGVkIHJlYWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcmdJbWFnZURpZ2VzdHNJblVzZShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICBjb25zdCBvcmcgPSBvcmdJZC50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gZXhlY3V0ZVJvd3M8eyBkOiBzdHJpbmcgfT4odHgsIHNxbGBcbiAgICBTRUxFQ1QgRElTVElOQ1QgZCBGUk9NIChcbiAgICAgIFNFTEVDVCBpbWFnZV9kaWdlc3QgQVMgZCBGUk9NIHBsdWdpbnMgV0hFUkUgbG93ZXIob3JnX2lkKSA9ICR7b3JnfSBBTkQgaW1hZ2VfZGlnZXN0IElTIE5PVCBOVUxMXG4gICAgICBVTklPTiBTRUxFQ1Qgci5yZXNvbHZlZF9kaWdlc3QgRlJPTSBwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbiByXG4gICAgICAgICAgICAgIFdIRVJFIHIucmVzb2x2ZWRfZGlnZXN0IElTIE5PVCBOVUxMIEFORCAobG93ZXIoci5vcmdfaWQpID0gJHtvcmd9IE9SIGxvd2VyKHIucm9vdF9vcmdfaWQpID0gJHtvcmd9KVxuICAgICAgVU5JT04gU0VMRUNUIG0uaW1hZ2VfZGlnZXN0IEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbVxuICAgICAgICAgICAgICBXSEVSRSBtLmltYWdlX2RpZ2VzdCBJUyBOT1QgTlVMTCBBTkQgbS5pbWFnZV9kaWdlc3QgSU4gKFNFTEVDVCBpbWFnZV9kaWdlc3QgRlJPTSBwbHVnaW5zIFdIRVJFIGxvd2VyKG9yZ19pZCkgPSAke29yZ30gQU5EIGltYWdlX2RpZ2VzdCBJUyBOT1QgTlVMTClcbiAgICAgIFVOSU9OIFNFTEVDVCBtLmltYWdlX2RpZ2VzdCBGUk9NIHBpcGVsaW5lX3N0ZXBfbWFuaWZlc3RzIG0gV0hFUkUgbS5pbWFnZV9kaWdlc3QgSVMgTk9UIE5VTEwgQU5EIGxvd2VyKG0ub3JnX2lkKSA9ICR7b3JnfVxuICAgICAgVU5JT04gU0VMRUNUIGUuaW1hZ2VfZGlnZXN0IEZST00gcGx1Z2luX3Z1bG5fZXhwb3N1cmUgZVxuICAgICAgICAgICAgICBXSEVSRSBlLmltYWdlX2RpZ2VzdCBJUyBOT1QgTlVMTCBBTkQgZS5zb3VyY2UgPSAnZGVwbG95ZWQnIEFORCBlLmZpeGVkX2F0IElTIE5VTEwgQU5EIGxvd2VyKGUub3JnX2lkKSA9ICR7b3JnfVxuICAgICkgeCBXSEVSRSBkIElTIE5PVCBOVUxMXG4gIGApKTtcbiAgcmV0dXJuIHJvd3MubWFwKChyKSA9PiByLmQpO1xufVxuIl19
174
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi1yZWZlcmVuY2VzLmpzIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3ZlcnNpb24tcmVmZXJlbmNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCRztBQUVILE9BQU8sRUFDTCxvQkFBb0IsRUFBRSx3QkFBd0IsRUFBRSxhQUFhLEVBQUUseUJBQXlCLEVBQUUsYUFBYSxHQUN4RyxNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFBRSxHQUFHLEVBQVksTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV0RCwyRUFBMkU7QUFDM0UsTUFBTSxpQkFBaUIsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQzdGLE1BQU0sbUJBQW1CLEdBQUcsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBRXhEOzs7OztHQUtHO0FBQ0gsU0FBUyx3QkFBd0IsQ0FBQyxJQUE2QztJQUM3RSwyRUFBMkU7SUFDM0UsdUVBQXVFO0lBQ3ZFLE9BQU8sR0FBRyxDQUFBLGtCQUFrQixJQUFJLENBQUMsS0FBSyxPQUFPLG1CQUFtQixRQUFRLElBQUksQ0FBQyxJQUFJLFFBQVEsaUJBQWlCO2dGQUM1QixpQkFBaUIsNEJBQTRCLElBQUksQ0FBQyxPQUFPOzs7NENBRzdGLGlCQUFpQiw4QkFBOEIsSUFBSSxDQUFDLE9BQU87Z0ZBQ3ZCLGlCQUFpQiw0QkFBNEIsSUFBSSxDQUFDLE9BQU87NEdBQzdCLENBQUM7QUFDN0csQ0FBQztBQWFELCtG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QyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogV2hpY2ggcGlwZWxpbmVzIHN0aWxsIFJFRkVSRU5DRSBhIHBsdWdpbiB2ZXJzaW9uIG9yIGltYWdlIOKAlCB0aGUgb25lIHJ1bGUgZXZlcnlcbiAqIHJlbW92YWwgcGF0aCBhc2tzIGJlZm9yZSBpdCBkZWxldGVzIGFueXRoaW5nOiBhbiBvcmcgcGx1Z2luIGRlbGV0ZSAoZm9yY2VkIG9yXG4gKiBub3QpLCBhIGJ1bGsgZGVsZXRlLCBhIHRvbWJzdG9uZSBwdXJnZSAobWFudWFsIG9yIHRoZSByZXRlbnRpb24gc3dlZXApLCB0aGVcbiAqIGltYWdlIHJlZ2lzdHJ5J3MgYWdlIEdDLCB0aGUgbGlzdGluZyBpbWFnZSBHQy5cbiAqXG4gKiBUSEUgUlVMRTogYSB2ZXJzaW9uIChvciBpdHMgaW1hZ2UpIHRoYXQgYW55IHBpcGVsaW5lIHJlZmVyZW5jZXMgY2Fubm90IGJlXG4gKiBkZWxldGVkIHVudGlsIG5vIHBpcGVsaW5lIGRvZXMg4oCUIHdoYXRldmVyIGl0cyB2dWxuZXJhYmlsaXR5IHN0YXRlLiBBXG4gKiB2dWxuZXJhYmxlIGltYWdlIGlzIHRoZSBXT1JTVCB0aGluZyB0byBkZWxldGUgb3V0IGZyb20gdW5kZXIgYSBwaXBlbGluZTogdGhlXG4gKiBuZXh0IHJ1biBmYWlscyB0byBwdWxsLCBhbmQgdGhlIG93bmVycyBsZWFybiBhYm91dCB0aGUgQ1ZFIGZyb20gYW4gb3V0YWdlLlxuICogVnVsbmVyYWJpbGl0eSBjb25zZXF1ZW5jZXMgYXJlIGdyYWRlZCB3YXJuaW5ncyBhbmQgbm90aWZpY2F0aW9ucywgbmV2ZXIgcmVtb3ZhbC5cbiAqXG4gKiBBIHJlZmVyZW5jZSBpcyBhbnkgb2Y6XG4gKiAgLSBgZGVjbGFyZWRgIOKAlCBhIExJVkUgcGlwZWxpbmUncyBjb25maWcgcmVzb2x2ZXMgdG8gaXQgKGBwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbmApO1xuICogIC0gYGRlcGxveWVkYCDigJQgYSBwaXBlbGluZSdzIGxhc3QgZGVwbG95IHJlY29yZGVkIGl0IChgcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHNgKSxcbiAqICAgIElOQ0xVRElORyBhIHNvZnQtZGVsZXRlZCBwaXBlbGluZTogaXRzIENvZGVQaXBlbGluZSBzdGlsbCBydW5zIHRoZSBpbWFnZTtcbiAqICAtIGBleHBvc3VyZWAg4oCUIGFuIG9wZW4gREVQTE9ZRUQgZXhwb3N1cmUgc3RpbGwgbmFtZXMgaXQgKHRoZSBzYW1lIFwic3RpbGwgcnVuc1xuICogICAgaXRcIiBmYWN0LCBrZXB0IHdoZW4gYSBtYW5pZmVzdCBpcyBnb25lKS5cbiAqXG4gKiBNYXRjaGVkIGJ5IGltYWdlIGRpZ2VzdCB3aGVuIHRoZSB2ZXJzaW9uIGhhcyBvbmUgKGEgdGVhbSBydW5uaW5nIGl0cyBwYXJlbnQnc1xuICogcGx1Z2luLCBvciBhbm90aGVyIG9yZydzIGluc3RhbGwsIHBpbnMgdGhlIHNhbWUgZGlnZXN0KSwgZWxzZSBieSBuYW1lICtcbiAqIHZlcnNpb24gd2l0aGluIHRoZSBvd25lciBvcmcgYW5kIGl0cyB0ZWFtcy5cbiAqXG4gKiBBIE1BTkFHRUQgVE9PTENIQUlOIGhhbGYgKHRoZSBzeXN0ZW0gb3JnJ3MgYHBpcGVsaW5lLWJvb3RzdHJhcGAgLyBgY2RrLXN5bnRoYCxcbiAqIGRvY3MvcGxhbnMvYm9vdHN0cmFwLWltYWdlLXZlcnNpb25pbmcubWQgwqc0L8KnNSkgaXMgcmVmZXJlbmNlZCB3aGVuZXZlciBpdHNcbiAqIFJFTEVBU0UgaXM6IGEgcGlwZWxpbmUgZGVwbG95aW5nIG9yIGRlY2xhcmluZyBFSVRIRVIgaGFsZiBvZiB0aGUgc2FtZSB2ZXJzaW9uXG4gKiByZWZlcmVuY2VzIGJvdGguIEEgcGlwZWxpbmUgdGhhdCBvbmx5IHJ1bnMgdGhlIHJlbGVhc2UncyBidWlsZCBpbWFnZSAodGhlXG4gKiBtYW5pZmVzdCdzIG5vbi1zdGVwIGBidWlsZC1pbWFnZWAgcm93KSBzdGlsbCBob2xkcyBpdHMgc3ludGggaGFsZiwgYW5kIHRoZVxuICogcmV2ZXJzZSDigJQgdGhlIHJlbGVhc2UgaXMgb25lIHVuaXQsIGNyZWF0ZWQsIGRlbGV0ZWQgYW5kIHB1cmdlZCB0b2dldGhlci5cbiAqL1xuXG5pbXBvcnQge1xuICBCVUlMRF9JTUFHRV9TVEVQX0tFWSwgaXNNYW5hZ2VkVG9vbGNoYWluUGx1Z2luLCBpc1N5c3RlbU9yZ0lkLCBNQU5BR0VEX1RPT0xDSEFJTl9QTFVHSU5TLCBTWVNURU1fT1JHX0lELFxufSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBzcWwsIHR5cGUgU1FMIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZXhlY3V0ZVJvd3MgfSBmcm9tICcuLi9kYXRhYmFzZS9wZy1yZXN1bHQuanMnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4IH0gZnJvbSAnLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5cbi8qKiBUaGUgbWFuYWdlZCB0b29sY2hhaW4gbmFtZXMgYXMgYW4gU1FMIGxpc3QgKGNvbnN0YW50cywgbmV2ZXIgaW5wdXQpLiAqL1xuY29uc3QgTUFOQUdFRF9OQU1FU19TUUwgPSBzcWwucmF3KE1BTkFHRURfVE9PTENIQUlOX1BMVUdJTlMubWFwKChuKSA9PiBgJyR7bn0nYCkuam9pbignLCAnKSk7XG5jb25zdCBTWVNURU1fT1JHX0lEX0xPV0VSID0gU1lTVEVNX09SR19JRC50b0xvd2VyQ2FzZSgpO1xuXG4vKipcbiAqIFwiVGhpcyByb3cgaXMgYSByZWxlYXNlIGhhbGYgd2hvc2UgUkVMRUFTRSBzb21lIHBpcGVsaW5lIHJlZmVyZW5jZXNcIjogYVxuICogc3lzdGVtLW9yZyBtYW5hZ2VkIHJvdywgYW5kIGEgbWFuaWZlc3QgLyByZXNvbHV0aW9uIC8gb3BlbiBkZXBsb3llZCBleHBvc3VyZVxuICogbmFtaW5nIGVpdGhlciBoYWxmIGF0IGl0cyB2ZXJzaW9uLiBNYW5hZ2VkIG5hbWVzIGFyZSByZXNlcnZlZCB0byB0aGUgc3lzdGVtXG4gKiBvcmcsIHNvIGEgcHVibGlzaGVyLWxlc3Mgcm93IHdpdGggb25lIElTIHRoYXQgcmVsZWFzZSdzLlxuICovXG5mdW5jdGlvbiBtYW5hZ2VkUmVsZWFzZVJlZmVyZW5jZWQoY29sczogeyBuYW1lOiBTUUw7IHZlcnNpb246IFNRTDsgb3JnSWQ6IFNRTCB9KTogU1FMIHtcbiAgLy8gQ09BTEVTQ0U6IGEgY2FsbGVyIHBhc3NpbmcgTlVMTCBjb2x1bW5zICh0aGUgbGlzdGluZyBpbWFnZSBHQykgbXVzdCByZWFkXG4gIC8vIEZBTFNFIGhlcmUsIG5ldmVyIE5VTEwg4oCUIGBOT1QgTlVMTGAgd291bGQgc2lsZW50bHkga2VlcCBldmVyeSBpbWFnZS5cbiAgcmV0dXJuIHNxbGBDT0FMRVNDRShsb3dlcigke2NvbHMub3JnSWR9KSA9ICR7U1lTVEVNX09SR19JRF9MT1dFUn0gQU5EICR7Y29scy5uYW1lfSBJTiAoJHtNQU5BR0VEX05BTUVTX1NRTH0pIEFORCAoXG4gICAgICBFWElTVFMgKFNFTEVDVCAxIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbSBXSEVSRSBtLnBsdWdpbl9uYW1lIElOICgke01BTkFHRURfTkFNRVNfU1FMfSkgQU5EIG0ucGx1Z2luX3ZlcnNpb24gPSAke2NvbHMudmVyc2lvbn1cbiAgICAgICAgICAgICAgICBBTkQgbS5wbHVnaW5fcHVibGlzaGVyIElTIE5VTEwpXG4gICAgICBPUiBFWElTVFMgKFNFTEVDVCAxIEZST00gcGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb24gciBKT0lOIHBpcGVsaW5lcyBscCBPTiBscC5pZDo6dGV4dCA9IHIucGlwZWxpbmVfaWQgQU5EIGxwLmRlbGV0ZWRfYXQgSVMgTlVMTFxuICAgICAgICAgICAgICAgICAgV0hFUkUgci5wbHVnaW5fbmFtZSBJTiAoJHtNQU5BR0VEX05BTUVTX1NRTH0pIEFORCByLnJlc29sdmVkX3ZlcnNpb24gPSAke2NvbHMudmVyc2lvbn0gQU5EIHIucGx1Z2luX3B1Ymxpc2hlciBJUyBOVUxMKVxuICAgICAgT1IgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIHBsdWdpbl92dWxuX2V4cG9zdXJlIGUgV0hFUkUgZS5wbHVnaW5fbmFtZSBJTiAoJHtNQU5BR0VEX05BTUVTX1NRTH0pIEFORCBlLnBsdWdpbl92ZXJzaW9uID0gJHtjb2xzLnZlcnNpb259XG4gICAgICAgICAgICAgICAgICBBTkQgZS5wbHVnaW5fcHVibGlzaGVyIElTIE5VTEwgQU5EIGUuc291cmNlID0gJ2RlcGxveWVkJyBBTkQgZS5maXhlZF9hdCBJUyBOVUxMKSksIGZhbHNlKWA7XG59XG5cbi8qKiBBIHZlcnNpb24gLyBpbWFnZSB3aG9zZSByZWZlcmVuY2VzIGFyZSB3YW50ZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIFZlcnNpb25SZWZlcmVuY2VUYXJnZXQge1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZztcbiAgaW1hZ2VEaWdlc3Q/OiBzdHJpbmcgfCBudWxsO1xuICAvKiogVGhlIG93bmluZyBvcmcgb2YgYW4gb3JnIHBsdWdpbiAoaXRzIHRlYW1zIGNvdW50IHRvbyk7IG9taXR0ZWQgZm9yIGEgbGlzdGluZyB2ZXJzaW9uLiAqL1xuICBvd25lck9yZ0lkPzogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIFRoZSBsaXN0aW5nJ3MgcHVibGlzaGVyIGhhbmRsZSAoYSBsaXN0aW5nIHZlcnNpb24pOyBudWxsL29taXR0ZWQgZm9yIGFuIG9yZyBwbHVnaW4uICovXG4gIHB1Ymxpc2hlcj86IHN0cmluZyB8IG51bGw7XG59XG5cbi8qKiBXaGV0aGVyIGB0YXJnZXRgIGlzIGEgbWFuYWdlZCB0b29sY2hhaW4gaGFsZiAobWF0Y2hlZCByZWxlYXNlLXdpZGUsIHNlZSB0aGUgbW9kdWxlIGRvYykuICovXG5mdW5jdGlvbiBpc01hbmFnZWRSZWxlYXNlVGFyZ2V0KHRhcmdldDogVmVyc2lvblJlZmVyZW5jZVRhcmdldCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNNYW5hZ2VkVG9vbGNoYWluUGx1Z2luKHRhcmdldC5wbHVnaW5OYW1lKSAmJiAhdGFyZ2V0LnB1Ymxpc2hlciAmJiBpc1N5c3RlbU9yZ0lkKHRhcmdldC5vd25lck9yZ0lkID8/ICcnKTtcbn1cblxuLyoqIE9uZSBwaXBlbGluZSByZWZlcmVuY2luZyBhIHZlcnNpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIFZlcnNpb25SZWZlcmVuY2Uge1xuICBwaXBlbGluZUlkOiBzdHJpbmc7XG4gIHBpcGVsaW5lTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgb3JnSWQ6IHN0cmluZztcbiAgc291cmNlOiAnZGVjbGFyZWQnIHwgJ2RlcGxveWVkJyB8ICdleHBvc3VyZSc7XG4gIC8qKiBUaGUgcGlwZWxpbmUgaXMgc29mdC1kZWxldGVkIChzdGlsbCBkZXBsb3llZDogaXRzIG1hbmlmZXN0IG9yIGV4cG9zdXJlIHJlbWFpbnMpLiAqL1xuICBwaXBlbGluZURlbGV0ZWQ6IGJvb2xlYW47XG4gIHN0ZXBzOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBUaGUgU1FMIHByZWRpY2F0ZSBcInNvbWUgcGlwZWxpbmUgcmVmZXJlbmNlcyB0aGlzIHJvdydzIGltYWdlIC8gdmVyc2lvblwiLCBvdmVyXG4gKiBhIGBwbHVnaW5zYC1zaGFwZWQgcm93J3MgY29sdW1ucyDigJQgdGhlIHB1cmdlIGd1YXJkJ3MgZm9ybSBvZlxuICoge0BsaW5rIGZpbmRWZXJzaW9uUmVmZXJlbmNlc30gKHNhbWUgdGhyZWUgc291cmNlcywgc2FtZSBtYXRjaGluZykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJzaW9uUmVmZXJlbmNlZFByZWRpY2F0ZShjb2xzOiB7IGRpZ2VzdDogU1FMOyBuYW1lOiBTUUw7IHZlcnNpb246IFNRTDsgb3JnSWQ6IFNRTCB9KTogU1FMIHtcbiAgcmV0dXJuIHNxbGAoXG4gICAgJHttYW5hZ2VkUmVsZWFzZVJlZmVyZW5jZWQoY29scyl9IE9SXG4gICAgKCR7Y29scy5kaWdlc3R9IElTIE5PVCBOVUxMIEFORCAoXG4gICAgICBFWElTVFMgKFNFTEVDVCAxIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbSBXSEVSRSBtLmltYWdlX2RpZ2VzdCA9ICR7Y29scy5kaWdlc3R9KVxuICAgICAgT1IgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIHBpcGVsaW5lX3BsdWdpbl9yZXNvbHV0aW9uIHIgSk9JTiBwaXBlbGluZXMgcCBPTiBwLmlkOjp0ZXh0ID0gci5waXBlbGluZV9pZCBBTkQgcC5kZWxldGVkX2F0IElTIE5VTExcbiAgICAgICAgICAgICAgICAgIFdIRVJFIHIucmVzb2x2ZWRfZGlnZXN0ID0gJHtjb2xzLmRpZ2VzdH0pXG4gICAgICBPUiBFWElTVFMgKFNFTEVDVCAxIEZST00gcGx1Z2luX3Z1bG5fZXhwb3N1cmUgZSBXSEVSRSBlLmltYWdlX2RpZ2VzdCA9ICR7Y29scy5kaWdlc3R9IEFORCBlLnNvdXJjZSA9ICdkZXBsb3llZCcgQU5EIGUuZml4ZWRfYXQgSVMgTlVMTCkpKVxuICAgIE9SICgke2NvbHMuZGlnZXN0fSBJUyBOVUxMIEFORCAoXG4gICAgICBFWElTVFMgKFNFTEVDVCAxIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbSBXSEVSRSBtLnBsdWdpbl9uYW1lID0gJHtjb2xzLm5hbWV9IEFORCBtLnBsdWdpbl92ZXJzaW9uID0gJHtjb2xzLnZlcnNpb259XG4gICAgICAgICAgICAgICAgQU5EIG0ucGx1Z2luX3B1Ymxpc2hlciBJUyBOVUxMIEFORCBsb3dlcihtLm9yZ19pZCkgPSBsb3dlcigke2NvbHMub3JnSWR9KSlcbiAgICAgIE9SIEVYSVNUUyAoU0VMRUNUIDEgRlJPTSBwaXBlbGluZV9wbHVnaW5fcmVzb2x1dGlvbiByIEpPSU4gcGlwZWxpbmVzIHAgT04gcC5pZDo6dGV4dCA9IHIucGlwZWxpbmVfaWQgQU5EIHAuZGVsZXRlZF9hdCBJUyBOVUxMXG4gICAgICAgICAgICAgICAgICBXSEVSRSByLnBsdWdpbl9uYW1lID0gJHtjb2xzLm5hbWV9IEFORCByLnJlc29sdmVkX3ZlcnNpb24gPSAke2NvbHMudmVyc2lvbn0gQU5EIHIucGx1Z2luX3B1Ymxpc2hlciBJUyBOVUxMXG4gICAgICAgICAgICAgICAgICAgIEFORCAobG93ZXIoci5vcmdfaWQpID0gbG93ZXIoJHtjb2xzLm9yZ0lkfSkgT1IgbG93ZXIoci5yb290X29yZ19pZCkgPSBsb3dlcigke2NvbHMub3JnSWR9KSkpKSlcbiAgKWA7XG59XG5cbi8qKlxuICogRXZlcnkgcGlwZWxpbmUgcmVmZXJlbmNpbmcgYHRhcmdldGAgKHNlZSB0aGUgbW9kdWxlIGRvYyksIGFjcm9zcyBvcmdzIOKAlCBzbyBpdFxuICogbXVzdCBydW4gd2l0aCBhIHNjb3BlIHRoYXQgY2FuIHJlYWQgZXZlcnkgb3JnJ3Mgcm93cyAoZWxldmF0ZWQpLiBUaGUgcmVzdWx0XG4gKiBuYW1lcyBvdGhlciBvcmdzJyBwaXBlbGluZXM7IGNhbGxlcnMgc2hvdyB0aGUgT1dORVIgb25seSBjb3VudHMgYW5kIGl0cyBvd25cbiAqIG9yZydzIHBpcGVsaW5lcywgYW5kIG5vdGlmeSBlYWNoIHJlZmVyZW5jaW5nIG9yZyBhYm91dCBpdHMgb3duLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluZFZlcnNpb25SZWZlcmVuY2VzKFxuICB0YXJnZXQ6IFZlcnNpb25SZWZlcmVuY2VUYXJnZXQsXG4gIHJ1bjogPFQ+KGZuOiAodHg6IFBhcmFtZXRlcnM8UGFyYW1ldGVyczx0eXBlb2Ygd2l0aFRlbmFudFR4PlswXT5bMF0pID0+IFByb21pc2U8VD4pID0+IFByb21pc2U8VD4gPSB3aXRoVGVuYW50VHgsXG4pOiBQcm9taXNlPFZlcnNpb25SZWZlcmVuY2VbXT4ge1xuICBjb25zdCBkaWdlc3QgPSB0YXJnZXQuaW1hZ2VEaWdlc3QgPz8gbnVsbDtcbiAgY29uc3Qgb3duZXIgPSB0YXJnZXQub3duZXJPcmdJZD8udG9Mb3dlckNhc2UoKSA/PyBudWxsO1xuICBjb25zdCBtYW5hZ2VkID0gaXNNYW5hZ2VkUmVsZWFzZVRhcmdldCh0YXJnZXQpO1xuICAvLyBBIG1hbmFnZWQgaGFsZjogZWl0aGVyIGhhbGYgb2YgdGhlIHJlbGVhc2UsIGF0IGl0cyB2ZXJzaW9uIChtb2R1bGUgZG9jKS5cbiAgY29uc3QgcmVsZWFzZSA9IChhbGlhczogJ3InIHwgJ20nIHwgJ2UnLCB2ZXJzaW9uQ29sOiBzdHJpbmcpID0+IChtYW5hZ2VkXG4gICAgPyBzcWxgIE9SICgke3NxbC5yYXcoYCR7YWxpYXN9LnBsdWdpbl9uYW1lYCl9IElOICgke01BTkFHRURfTkFNRVNfU1FMfSkgQU5EICR7c3FsLnJhdyhgJHthbGlhc30uJHt2ZXJzaW9uQ29sfWApfSA9ICR7dGFyZ2V0LnBsdWdpblZlcnNpb259IEFORCAke3NxbC5yYXcoYCR7YWxpYXN9LnBsdWdpbl9wdWJsaXNoZXJgKX0gSVMgTlVMTClgXG4gICAgOiBzcWxgYCk7XG4gIGNvbnN0IGRlY2xhcmVkTWF0Y2ggPSBkaWdlc3RcbiAgICA/IHNxbGByLnJlc29sdmVkX2RpZ2VzdCA9ICR7ZGlnZXN0fWBcbiAgICA6IHNxbGByLnBsdWdpbl9uYW1lID0gJHt0YXJnZXQucGx1Z2luTmFtZX0gQU5EIHIucmVzb2x2ZWRfdmVyc2lvbiA9ICR7dGFyZ2V0LnBsdWdpblZlcnNpb259XG4gICAgICAgICAgQU5EICR7dGFyZ2V0LnB1Ymxpc2hlciA/IHNxbGByLnBsdWdpbl9wdWJsaXNoZXIgPSAke3RhcmdldC5wdWJsaXNoZXJ9YCA6IHNxbGByLnBsdWdpbl9wdWJsaXNoZXIgSVMgTlVMTCBBTkQgKGxvd2VyKHIub3JnX2lkKSA9ICR7b3duZXJ9IE9SIGxvd2VyKHIucm9vdF9vcmdfaWQpID0gJHtvd25lcn0pYH1gO1xuICBjb25zdCBkZXBsb3llZE1hdGNoID0gZGlnZXN0XG4gICAgPyBzcWxgbS5pbWFnZV9kaWdlc3QgPSAke2RpZ2VzdH1gXG4gICAgOiBzcWxgbS5wbHVnaW5fbmFtZSA9ICR7dGFyZ2V0LnBsdWdpbk5hbWV9IEFORCBtLnBsdWdpbl92ZXJzaW9uID0gJHt0YXJnZXQucGx1Z2luVmVyc2lvbn1cbiAgICAgICAgICBBTkQgJHt0YXJnZXQucHVibGlzaGVyID8gc3FsYG0ucGx1Z2luX3B1Ymxpc2hlciA9ICR7dGFyZ2V0LnB1Ymxpc2hlcn1gIDogc3FsYG0ucGx1Z2luX3B1Ymxpc2hlciBJUyBOVUxMIEFORCBsb3dlcihtLm9yZ19pZCkgPSAke293bmVyfWB9YDtcbiAgY29uc3QgZXhwb3N1cmVNYXRjaCA9IGRpZ2VzdFxuICAgID8gc3FsYGUuaW1hZ2VfZGlnZXN0ID0gJHtkaWdlc3R9YFxuICAgIDogc3FsYGUucGx1Z2luX25hbWUgPSAke3RhcmdldC5wbHVnaW5OYW1lfSBBTkQgZS5wbHVnaW5fdmVyc2lvbiA9ICR7dGFyZ2V0LnBsdWdpblZlcnNpb259XG4gICAgICAgICAgQU5EICR7dGFyZ2V0LnB1Ymxpc2hlciA/IHNxbGBlLnBsdWdpbl9wdWJsaXNoZXIgPSAke3RhcmdldC5wdWJsaXNoZXJ9YCA6IHNxbGBlLnBsdWdpbl9wdWJsaXNoZXIgSVMgTlVMTCBBTkQgbG93ZXIoZS5vcmdfaWQpID0gJHtvd25lcn1gfWA7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCBydW4oKHR4KSA9PiBleGVjdXRlUm93czx7IHBpcGVsaW5lX2lkOiBzdHJpbmc7IG9yZ19pZDogc3RyaW5nOyBzb3VyY2U6IFZlcnNpb25SZWZlcmVuY2VbJ3NvdXJjZSddOyBwaXBlbGluZV9uYW1lOiBzdHJpbmcgfCBudWxsOyBkZWxldGVkOiBib29sZWFuOyBzdGVwczogc3RyaW5nW10gfCBudWxsIH0+KHR4LCBzcWxgXG4gICAgU0VMRUNUIHgucGlwZWxpbmVfaWQsIHgub3JnX2lkLCB4LnNvdXJjZSwgcC5waXBlbGluZV9uYW1lLCAocC5pZCBJUyBOVUxMIE9SIHAuZGVsZXRlZF9hdCBJUyBOT1QgTlVMTCkgQVMgZGVsZXRlZCxcbiAgICAgICAgICAgYXJyYXlfYWdnKERJU1RJTkNUIHguc3RlcCkgRklMVEVSIChXSEVSRSB4LnN0ZXAgSVMgTk9UIE5VTEwpIEFTIHN0ZXBzXG4gICAgICBGUk9NIChcbiAgICAgICAgU0VMRUNUIHIucGlwZWxpbmVfaWQsIHIub3JnX2lkLCAnZGVjbGFyZWQnIEFTIHNvdXJjZSxcbiAgICAgICAgICAgICAgIENBU0UgV0hFTiByLnN0YWdlX25hbWUgPSAnc3ludGgnIEFORCByLnN0ZXBfbmFtZSA9ICdzeW50aCcgVEhFTiAnc3ludGgnIEVMU0Ugci5zdGFnZV9uYW1lIHx8ICcvJyB8fCByLnN0ZXBfbmFtZSBFTkQgQVMgc3RlcFxuICAgICAgICAgIEZST00gcGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb24gclxuICAgICAgICAgIEpPSU4gcGlwZWxpbmVzIGxwIE9OIGxwLmlkOjp0ZXh0ID0gci5waXBlbGluZV9pZCBBTkQgbHAuZGVsZXRlZF9hdCBJUyBOVUxMXG4gICAgICAgICBXSEVSRSAoJHtkZWNsYXJlZE1hdGNofSR7cmVsZWFzZSgncicsICdyZXNvbHZlZF92ZXJzaW9uJyl9KVxuICAgICAgICBVTklPTiBBTExcbiAgICAgICAgU0VMRUNUIG0ucGlwZWxpbmVfaWQ6OnRleHQsIG0ub3JnX2lkLCAnZGVwbG95ZWQnLFxuICAgICAgICAgICAgICAgQ0FTRSBXSEVOIG0uc3RlcF9rZXkgPSAke0JVSUxEX0lNQUdFX1NURVBfS0VZfSBUSEVOICR7QlVJTERfSU1BR0VfU1RFUF9LRVl9IEVMU0UgbS5zdGFnZV9uYW1lIHx8ICcvJyB8fCBtLmFjdGlvbl9uYW1lIEVORFxuICAgICAgICAgIEZST00gcGlwZWxpbmVfc3RlcF9tYW5pZmVzdHMgbSBXSEVSRSAoJHtkZXBsb3llZE1hdGNofSR7cmVsZWFzZSgnbScsICdwbHVnaW5fdmVyc2lvbicpfSlcbiAgICAgICAgVU5JT04gQUxMXG4gICAgICAgIFNFTEVDVCBlLnBpcGVsaW5lX2lkLCBlLm9yZ19pZCwgJ2V4cG9zdXJlJywgTlVMTFxuICAgICAgICAgIEZST00gcGx1Z2luX3Z1bG5fZXhwb3N1cmUgZSBXSEVSRSAoJHtleHBvc3VyZU1hdGNofSR7cmVsZWFzZSgnZScsICdwbHVnaW5fdmVyc2lvbicpfSkgQU5EIGUuc291cmNlID0gJ2RlcGxveWVkJyBBTkQgZS5maXhlZF9hdCBJUyBOVUxMXG4gICAgICApIHhcbiAgICAgIExFRlQgSk9JTiBwaXBlbGluZXMgcCBPTiBwLmlkOjp0ZXh0ID0geC5waXBlbGluZV9pZFxuICAgICBHUk9VUCBCWSB4LnBpcGVsaW5lX2lkLCB4Lm9yZ19pZCwgeC5zb3VyY2UsIHAucGlwZWxpbmVfbmFtZSwgcC5pZCwgcC5kZWxldGVkX2F0XG4gICAgIE9SREVSIEJZIHgub3JnX2lkLCB4LnBpcGVsaW5lX2lkLCB4LnNvdXJjZVxuICBgKSk7XG4gIHJldHVybiByb3dzLm1hcCgocikgPT4gKHtcbiAgICBwaXBlbGluZUlkOiByLnBpcGVsaW5lX2lkLFxuICAgIHBpcGVsaW5lTmFtZTogci5waXBlbGluZV9uYW1lID8/IG51bGwsXG4gICAgb3JnSWQ6IHIub3JnX2lkLFxuICAgIHNvdXJjZTogci5zb3VyY2UsXG4gICAgcGlwZWxpbmVEZWxldGVkOiByLmRlbGV0ZWQgPT09IHRydWUsXG4gICAgc3RlcHM6IHIuc3RlcHMgPz8gW10sXG4gIH0pKTtcbn1cblxuLyoqIERpc3RpbmN0IHBpcGVsaW5lcyBhbW9uZyBgcmVmc2AgKGEgcGlwZWxpbmUgYm90aCBkZWNsYXJlZCBhbmQgZGVwbG95ZWQgY291bnRzIG9uY2UpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc3RpbmN0UGlwZWxpbmVzKHJlZnM6IHJlYWRvbmx5IFZlcnNpb25SZWZlcmVuY2VbXSk6IEFycmF5PHsgcGlwZWxpbmVJZDogc3RyaW5nOyBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7IG9yZ0lkOiBzdHJpbmc7IHNvdXJjZXM6IHN0cmluZ1tdOyBwaXBlbGluZURlbGV0ZWQ6IGJvb2xlYW47IHN0ZXBzOiBzdHJpbmdbXSB9PiB7XG4gIGNvbnN0IGJ5SWQgPSBuZXcgTWFwPHN0cmluZywgeyBwaXBlbGluZUlkOiBzdHJpbmc7IHBpcGVsaW5lTmFtZTogc3RyaW5nIHwgbnVsbDsgb3JnSWQ6IHN0cmluZzsgc291cmNlczogc3RyaW5nW107IHBpcGVsaW5lRGVsZXRlZDogYm9vbGVhbjsgc3RlcHM6IHN0cmluZ1tdIH0+KCk7XG4gIGZvciAoY29uc3QgciBvZiByZWZzKSB7XG4gICAgY29uc3QgZSA9IGJ5SWQuZ2V0KHIucGlwZWxpbmVJZCkgPz8geyBwaXBlbGluZUlkOiByLnBpcGVsaW5lSWQsIHBpcGVsaW5lTmFtZTogci5waXBlbGluZU5hbWUsIG9yZ0lkOiByLm9yZ0lkLCBzb3VyY2VzOiBbXSwgcGlwZWxpbmVEZWxldGVkOiByLnBpcGVsaW5lRGVsZXRlZCwgc3RlcHM6IFtdIH07XG4gICAgaWYgKCFlLnNvdXJjZXMuaW5jbHVkZXMoci5zb3VyY2UpKSBlLnNvdXJjZXMucHVzaChyLnNvdXJjZSk7XG4gICAgZS5zdGVwcyA9IFsuLi5uZXcgU2V0KFsuLi5lLnN0ZXBzLCAuLi5yLnN0ZXBzXSldO1xuICAgIGJ5SWQuc2V0KHIucGlwZWxpbmVJZCwgZSk7XG4gIH1cbiAgcmV0dXJuIFsuLi5ieUlkLnZhbHVlcygpXTtcbn1cblxuLyoqXG4gKiBUaGUgaW1hZ2UgZGlnZXN0cyBhbiBvcmcncyBuYW1lc3BhY2Ugc3RpbGwgbmVlZHM6IGV2ZXJ5IGBwbHVnaW5zYCByb3cnc1xuICogZGlnZXN0IChhY3RpdmUsIGluYWN0aXZlIG9yIHNvZnQtZGVsZXRlZCDigJQgYSB0b21ic3RvbmUgaXMgcmVzdG9yYWJsZSB1bnRpbFxuICogcHVyZ2VkLCBhbmQgdGhlIHB1cmdlIGl0c2VsZiBpcyBndWFyZGVkKSBwbHVzIGV2ZXJ5IGRpZ2VzdCBhIHBpcGVsaW5lIG9mIHRoZVxuICogb3JnIG9yIGl0cyB0ZWFtcyBkZWNsYXJlcywgcnVucyBvciBoYXMgYW4gb3BlbiBkZXBsb3llZCBleHBvc3VyZSBvbi4gV2hhdCB0aGVcbiAqIGltYWdlIHJlZ2lzdHJ5J3MgYWdlIEdDIGNvbnN1bHRzIGJlZm9yZSBkZWxldGluZyBhbnl0aGluZyBpbiBgb3JnLTxpZD4vKmAuXG4gKiBFbGV2YXRlZCByZWFkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb3JnSW1hZ2VEaWdlc3RzSW5Vc2Uob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgY29uc3Qgb3JnID0gb3JnSWQudG9Mb3dlckNhc2UoKTtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IGV4ZWN1dGVSb3dzPHsgZDogc3RyaW5nIH0+KHR4LCBzcWxgXG4gICAgU0VMRUNUIERJU1RJTkNUIGQgRlJPTSAoXG4gICAgICBTRUxFQ1QgaW1hZ2VfZGlnZXN0IEFTIGQgRlJPTSBwbHVnaW5zIFdIRVJFIGxvd2VyKG9yZ19pZCkgPSAke29yZ30gQU5EIGltYWdlX2RpZ2VzdCBJUyBOT1QgTlVMTFxuICAgICAgVU5JT04gU0VMRUNUIHIucmVzb2x2ZWRfZGlnZXN0IEZST00gcGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb24gclxuICAgICAgICAgICAgICBXSEVSRSByLnJlc29sdmVkX2RpZ2VzdCBJUyBOT1QgTlVMTCBBTkQgKGxvd2VyKHIub3JnX2lkKSA9ICR7b3JnfSBPUiBsb3dlcihyLnJvb3Rfb3JnX2lkKSA9ICR7b3JnfSlcbiAgICAgIFVOSU9OIFNFTEVDVCBtLmltYWdlX2RpZ2VzdCBGUk9NIHBpcGVsaW5lX3N0ZXBfbWFuaWZlc3RzIG1cbiAgICAgICAgICAgICAgV0hFUkUgbS5pbWFnZV9kaWdlc3QgSVMgTk9UIE5VTEwgQU5EIG0uaW1hZ2VfZGlnZXN0IElOIChTRUxFQ1QgaW1hZ2VfZGlnZXN0IEZST00gcGx1Z2lucyBXSEVSRSBsb3dlcihvcmdfaWQpID0gJHtvcmd9IEFORCBpbWFnZV9kaWdlc3QgSVMgTk9UIE5VTEwpXG4gICAgICBVTklPTiBTRUxFQ1QgbS5pbWFnZV9kaWdlc3QgRlJPTSBwaXBlbGluZV9zdGVwX21hbmlmZXN0cyBtIFdIRVJFIG0uaW1hZ2VfZGlnZXN0IElTIE5PVCBOVUxMIEFORCBsb3dlcihtLm9yZ19pZCkgPSAke29yZ31cbiAgICAgIFVOSU9OIFNFTEVDVCBlLmltYWdlX2RpZ2VzdCBGUk9NIHBsdWdpbl92dWxuX2V4cG9zdXJlIGVcbiAgICAgICAgICAgICAgV0hFUkUgZS5pbWFnZV9kaWdlc3QgSVMgTk9UIE5VTEwgQU5EIGUuc291cmNlID0gJ2RlcGxveWVkJyBBTkQgZS5maXhlZF9hdCBJUyBOVUxMIEFORCBsb3dlcihlLm9yZ19pZCkgPSAke29yZ31cbiAgICApIHggV0hFUkUgZCBJUyBOT1QgTlVMTFxuICBgKSk7XG4gIHJldHVybiByb3dzLm1hcCgocikgPT4gci5kKTtcbn1cbiJdfQ==