@pipeline-builder/pipeline-data 4.1.15 → 4.1.16
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.
- package/lib/api/access-control-builder.d.ts +18 -1
- package/lib/api/access-control-builder.js +19 -6
- package/lib/api/crud-service.d.ts +94 -36
- package/lib/api/crud-service.js +188 -166
- package/lib/api/plugin-resolution.d.ts +253 -0
- package/lib/api/plugin-resolution.js +649 -0
- package/lib/api/public-directory.d.ts +281 -0
- package/lib/api/public-directory.js +457 -0
- package/lib/api/query-builders.d.ts +13 -0
- package/lib/api/query-builders.js +74 -9
- package/lib/api/reporting/caches.js +4 -4
- package/lib/api/reporting/dora-scoring.d.ts +3 -3
- package/lib/api/reporting/dora-scoring.js +4 -4
- package/lib/api/reporting/dora.d.ts +6 -6
- package/lib/api/reporting/dora.js +97 -73
- package/lib/api/reporting/plugin-runtime.d.ts +25 -0
- package/lib/api/reporting/plugin-runtime.js +106 -0
- package/lib/api/reporting/query-scope.d.ts +8 -2
- package/lib/api/reporting/query-scope.js +16 -7
- package/lib/api/reporting/retention.d.ts +4 -10
- package/lib/api/reporting/retention.js +8 -11
- package/lib/api/reporting/sql-helpers.d.ts +4 -7
- package/lib/api/reporting/sql-helpers.js +8 -9
- package/lib/api/reporting/types.d.ts +55 -17
- package/lib/api/reporting/types.js +1 -1
- package/lib/api/reporting-service.d.ts +35 -26
- package/lib/api/reporting-service.js +245 -161
- package/lib/api/semver-range.d.ts +73 -0
- package/lib/api/semver-range.js +227 -0
- package/lib/api/soft-delete-sweep.js +8 -20
- package/lib/core/query-filters.d.ts +18 -3
- package/lib/core/query-filters.js +1 -1
- package/lib/database/drizzle-schema.d.ts +7790 -2461
- package/lib/database/drizzle-schema.js +29 -1
- package/lib/database/index.d.ts +4 -2
- package/lib/database/index.js +5 -3
- package/lib/database/pg-result.d.ts +19 -0
- package/lib/database/pg-result.js +32 -0
- package/lib/database/postgres-connection.js +14 -24
- package/lib/database/public-reader.d.ts +14 -0
- package/lib/database/public-reader.js +68 -0
- package/lib/database/retry-strategy.d.ts +3 -5
- package/lib/database/retry-strategy.js +4 -6
- package/lib/database/schema/compliance.d.ts +16 -34
- package/lib/database/schema/compliance.js +4 -4
- package/lib/database/schema/dashboard.js +4 -2
- package/lib/database/schema/ecosystem.d.ts +6586 -0
- package/lib/database/schema/ecosystem.js +709 -0
- package/lib/database/schema/message.d.ts +6 -12
- package/lib/database/schema/message.js +3 -1
- package/lib/database/schema/pipeline.d.ts +79 -5
- package/lib/database/schema/pipeline.js +46 -25
- package/lib/database/schema/plugin.d.ts +587 -3
- package/lib/database/schema/plugin.js +86 -14
- package/lib/database/tenancy.d.ts +6 -7
- package/lib/database/tenancy.js +13 -14
- package/lib/index.d.ts +7 -4
- package/lib/index.js +7 -4
- package/lib/testing/exports.json +146 -0
- package/package.json +44 -7
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Resolving a plugin reference to an ecosystem LISTING version through the
|
|
5
|
+
* org's install (docs/plugin-installing.md).
|
|
6
|
+
*
|
|
7
|
+
* One implementation shared by every place that answers "which listed version
|
|
8
|
+
* does this org's reference run?": the plugin service's `/plugins/lookup` (what
|
|
9
|
+
* synth pins), the pipeline service's contract check at pipeline create, the AI
|
|
10
|
+
* generator's plugin list and the placeholder guard. The decisions are PURE
|
|
11
|
+
* functions over loaded rows; the rows come through a {@link ListingDataSource}
|
|
12
|
+
* so each service can load them its own way ({@link drizzleListingSource} is the
|
|
13
|
+
* plain drizzle one).
|
|
14
|
+
*
|
|
15
|
+
* The model:
|
|
16
|
+
* - An org resolves a listing only through an INSTALL: an explicit
|
|
17
|
+
* `plugin_installs` row (its own, or — for a team — its root org's), or
|
|
18
|
+
* for the Official publisher the IMPLICIT install every org has unless its
|
|
19
|
+
* consumption policy says `officialInstalls: explicit`. An explicit
|
|
20
|
+
* install overrides the implicit one.
|
|
21
|
+
* - The org's CONSUMPTION POLICY is applied at every resolution: allowed
|
|
22
|
+
* tiers, blocked listings, advisory blocking; secrets are withheld from tiers
|
|
23
|
+
* the policy doesn't trust with them. A team's policy is merged with its root
|
|
24
|
+
* org's and can only be stricter.
|
|
25
|
+
* - Version choice: the install's range (pinned / `~` / `^` / non-breaking
|
|
26
|
+
* latest; implicit = the lowest live major), narrowed by the reference's own
|
|
27
|
+
* version spec. Yanked versions never resolve for a listing; a paused
|
|
28
|
+
* version is skipped unless the install already resolved to it or the
|
|
29
|
+
* reference pins it exactly; advisory-blocked versions are skipped.
|
|
30
|
+
*/
|
|
31
|
+
import { and, eq, inArray } from 'drizzle-orm';
|
|
32
|
+
import { compareSemver, isVersionRange, parseSemver, parseVersionSpec, satisfiesVersionSpec, } from './semver-range.js';
|
|
33
|
+
import { OFFICIAL_PUBLISHER_HANDLE, PUBLISHER_TIERS, schema, } from '../database/drizzle-schema.js';
|
|
34
|
+
/** The defaults (and the column defaults of `plugin_install_policies`). */
|
|
35
|
+
export const DEFAULT_CONSUMPTION_POLICY = Object.freeze({
|
|
36
|
+
allowedTiers: ['official', 'verified'],
|
|
37
|
+
requireApprovalTiers: ['community', 'unverified'],
|
|
38
|
+
secretsAllowedTiers: ['official', 'verified'],
|
|
39
|
+
blockOnAdvisory: 'critical',
|
|
40
|
+
officialInstalls: 'implicit',
|
|
41
|
+
blockedListings: [],
|
|
42
|
+
});
|
|
43
|
+
/** At most this many blocked listings per policy. */
|
|
44
|
+
export const MAX_BLOCKED_LISTINGS = 500;
|
|
45
|
+
const BLOCK_ORDER = ['never', 'critical', 'high'];
|
|
46
|
+
const sortTiers = (tiers) => PUBLISHER_TIERS.filter((t) => new Set(tiers).has(t));
|
|
47
|
+
const listingKey = (r) => `${r.publisher}/${r.name}`;
|
|
48
|
+
function uniqueListings(refs) {
|
|
49
|
+
const seen = new Map();
|
|
50
|
+
for (const r of refs)
|
|
51
|
+
seen.set(listingKey(r), { publisher: r.publisher, name: r.name });
|
|
52
|
+
return [...seen.values()].sort((a, b) => listingKey(a).localeCompare(listingKey(b)));
|
|
53
|
+
}
|
|
54
|
+
/** A stored policy row (or none) as a {@link ConsumptionPolicy}. */
|
|
55
|
+
export function policyOf(row) {
|
|
56
|
+
const d = DEFAULT_CONSUMPTION_POLICY;
|
|
57
|
+
return {
|
|
58
|
+
allowedTiers: sortTiers(row?.allowedTiers ?? d.allowedTiers),
|
|
59
|
+
requireApprovalTiers: sortTiers(row?.requireApprovalTiers ?? d.requireApprovalTiers),
|
|
60
|
+
secretsAllowedTiers: sortTiers(row?.secretsAllowedTiers ?? d.secretsAllowedTiers),
|
|
61
|
+
blockOnAdvisory: row?.blockOnAdvisory ?? d.blockOnAdvisory,
|
|
62
|
+
officialInstalls: row?.officialInstalls ?? d.officialInstalls,
|
|
63
|
+
blockedListings: uniqueListings(row?.blockedListings ?? d.blockedListings),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A team's policy under its root org's: each field takes the STRICTER of
|
|
68
|
+
* the two, so a team can narrow what its root allows but never widen it.
|
|
69
|
+
*/
|
|
70
|
+
export function mergeConsumptionPolicies(root, team) {
|
|
71
|
+
const intersect = (a, b) => sortTiers(a.filter((t) => b.includes(t)));
|
|
72
|
+
const union = (a, b) => sortTiers([...a, ...b]);
|
|
73
|
+
const stricterBlock = BLOCK_ORDER.indexOf(root.blockOnAdvisory) >= BLOCK_ORDER.indexOf(team.blockOnAdvisory)
|
|
74
|
+
? root.blockOnAdvisory : team.blockOnAdvisory;
|
|
75
|
+
return {
|
|
76
|
+
allowedTiers: intersect(root.allowedTiers, team.allowedTiers),
|
|
77
|
+
requireApprovalTiers: union(root.requireApprovalTiers, team.requireApprovalTiers),
|
|
78
|
+
secretsAllowedTiers: intersect(root.secretsAllowedTiers, team.secretsAllowedTiers),
|
|
79
|
+
blockOnAdvisory: stricterBlock,
|
|
80
|
+
officialInstalls: root.officialInstalls === 'explicit' || team.officialInstalls === 'explicit' ? 'explicit' : 'implicit',
|
|
81
|
+
blockedListings: uniqueListings([...root.blockedListings, ...team.blockedListings]),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The policy an org's resolution runs under. A root org: its own row (or the
|
|
86
|
+
* defaults). A team (`rootOrgId` set): its root's policy, merged with the
|
|
87
|
+
* team's own row when it has one.
|
|
88
|
+
*/
|
|
89
|
+
export function effectiveConsumptionPolicy(rows, orgId, rootOrgId) {
|
|
90
|
+
const own = rows.find((r) => r.orgId === orgId) ?? null;
|
|
91
|
+
if (!rootOrgId || rootOrgId === orgId)
|
|
92
|
+
return policyOf(own);
|
|
93
|
+
const root = policyOf(rows.find((r) => r.orgId === rootOrgId) ?? null);
|
|
94
|
+
return own ? mergeConsumptionPolicies(root, policyOf(own)) : root;
|
|
95
|
+
}
|
|
96
|
+
const HANDLE_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
97
|
+
const NAME_RE = /^[a-z0-9][a-z0-9._-]*$/;
|
|
98
|
+
function tierList(v, field) {
|
|
99
|
+
if (!Array.isArray(v))
|
|
100
|
+
return `${field} must be an array of tiers`;
|
|
101
|
+
const bad = v.filter((t) => !PUBLISHER_TIERS.includes(t));
|
|
102
|
+
if (bad.length)
|
|
103
|
+
return `${field} has unknown tiers: ${bad.map(String).join(', ')}`;
|
|
104
|
+
return sortTiers(v);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Validate a (partial) policy update over `base`. Returns the full new policy,
|
|
108
|
+
* or an error message. `blockedListings` entries are `{ publisher, name }` or
|
|
109
|
+
* `"publisher/name"`.
|
|
110
|
+
*/
|
|
111
|
+
export function applyPolicyUpdate(base, input) {
|
|
112
|
+
if (!input || typeof input !== 'object' || Array.isArray(input))
|
|
113
|
+
return 'body must be an object';
|
|
114
|
+
const b = input;
|
|
115
|
+
const next = { ...base };
|
|
116
|
+
for (const field of ['allowedTiers', 'requireApprovalTiers', 'secretsAllowedTiers']) {
|
|
117
|
+
if (b[field] === undefined)
|
|
118
|
+
continue;
|
|
119
|
+
const tiers = tierList(b[field], field);
|
|
120
|
+
if (typeof tiers === 'string')
|
|
121
|
+
return tiers;
|
|
122
|
+
next[field] = tiers;
|
|
123
|
+
}
|
|
124
|
+
if (b.blockOnAdvisory !== undefined) {
|
|
125
|
+
if (!BLOCK_ORDER.includes(b.blockOnAdvisory))
|
|
126
|
+
return 'blockOnAdvisory must be critical, high or never';
|
|
127
|
+
next.blockOnAdvisory = b.blockOnAdvisory;
|
|
128
|
+
}
|
|
129
|
+
if (b.officialInstalls !== undefined) {
|
|
130
|
+
if (b.officialInstalls !== 'implicit' && b.officialInstalls !== 'explicit')
|
|
131
|
+
return 'officialInstalls must be implicit or explicit';
|
|
132
|
+
next.officialInstalls = b.officialInstalls;
|
|
133
|
+
}
|
|
134
|
+
if (b.blockedListings !== undefined) {
|
|
135
|
+
if (!Array.isArray(b.blockedListings))
|
|
136
|
+
return 'blockedListings must be an array';
|
|
137
|
+
if (b.blockedListings.length > MAX_BLOCKED_LISTINGS)
|
|
138
|
+
return `at most ${MAX_BLOCKED_LISTINGS} blocked listings`;
|
|
139
|
+
const refs = [];
|
|
140
|
+
for (const raw of b.blockedListings) {
|
|
141
|
+
const ref = typeof raw === 'string'
|
|
142
|
+
? (() => { const [publisher, name, extra] = raw.split('/'); return extra === undefined ? { publisher, name } : null; })()
|
|
143
|
+
: raw && typeof raw === 'object' ? { publisher: raw.publisher, name: raw.name } : null;
|
|
144
|
+
if (!ref || typeof ref.publisher !== 'string' || typeof ref.name !== 'string'
|
|
145
|
+
|| !HANDLE_RE.test(ref.publisher) || !NAME_RE.test(ref.name)) {
|
|
146
|
+
return 'each blocked listing must be { publisher, name } (or "publisher/name")';
|
|
147
|
+
}
|
|
148
|
+
refs.push({ publisher: ref.publisher, name: ref.name });
|
|
149
|
+
}
|
|
150
|
+
next.blockedListings = uniqueListings(refs);
|
|
151
|
+
}
|
|
152
|
+
return next;
|
|
153
|
+
}
|
|
154
|
+
/** Whether `policy` (or the listing's own state) refuses the listing outright. */
|
|
155
|
+
export function listingBlock(policy, publisher, listing) {
|
|
156
|
+
const ref = `${publisher.handle}/${listing.name}`;
|
|
157
|
+
if (publisher.suspendedAt || listing.state === 'suspended' || listing.state === 'transferred') {
|
|
158
|
+
return { reason: 'suspended', message: `${ref} is ${listing.state === 'transferred' ? 'transferred' : 'suspended'} and no longer resolves.` };
|
|
159
|
+
}
|
|
160
|
+
if (policy.blockedListings.some((b) => b.publisher === publisher.handle && b.name === listing.name)) {
|
|
161
|
+
return { reason: 'blocked_listing', message: `Your organization's plugin policy blocks ${ref}.` };
|
|
162
|
+
}
|
|
163
|
+
if (!policy.allowedTiers.includes(publisher.tier)) {
|
|
164
|
+
return { reason: 'tier', message: `Your organization's plugin policy doesn't allow ${publisher.tier} plugins (${ref}).` };
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
/** The refusal a {@link ListingBlock} becomes. */
|
|
169
|
+
export function blockRefusal(block) {
|
|
170
|
+
return block.reason === 'suspended'
|
|
171
|
+
? { code: 'PLUGIN_UNAVAILABLE', reason: 'suspended', message: block.message }
|
|
172
|
+
: { code: 'PLUGIN_BLOCKED_BY_POLICY', reason: block.reason, message: block.message };
|
|
173
|
+
}
|
|
174
|
+
// -----------------------------------------------------------------------------
|
|
175
|
+
// Advisories
|
|
176
|
+
// -----------------------------------------------------------------------------
|
|
177
|
+
/** Severities each `blockOnAdvisory` setting blocks. */
|
|
178
|
+
export const ADVISORY_BLOCK_SEVERITIES = {
|
|
179
|
+
critical: ['critical'],
|
|
180
|
+
high: ['critical', 'high'],
|
|
181
|
+
never: [],
|
|
182
|
+
};
|
|
183
|
+
const COMPARATOR = /^(>=|<=|>|<|=)?\s*v?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)$/;
|
|
184
|
+
/** One comparator set (`>=1.0.0 <1.2.3`, `^1.2`, `1.x`, `1.0.0 - 1.2.0`) against `version`. */
|
|
185
|
+
function comparatorSetCovers(set, version) {
|
|
186
|
+
const hyphen = /^(\S+)\s+-\s+(\S+)$/.exec(set);
|
|
187
|
+
if (hyphen)
|
|
188
|
+
return compareSemver(version, hyphen[1]) >= 0 && compareSemver(version, hyphen[2]) <= 0;
|
|
189
|
+
const parts = set.split(/\s+/).filter(Boolean);
|
|
190
|
+
if (parts.length === 1 && parseVersionSpec(parts[0]))
|
|
191
|
+
return satisfiesVersionSpec(version, parts[0]);
|
|
192
|
+
return parts.every((p) => {
|
|
193
|
+
const m = COMPARATOR.exec(p);
|
|
194
|
+
if (!m)
|
|
195
|
+
return false;
|
|
196
|
+
const c = compareSemver(version, m[2]);
|
|
197
|
+
switch (m[1] ?? '=') {
|
|
198
|
+
case '>=': return c >= 0;
|
|
199
|
+
case '<=': return c <= 0;
|
|
200
|
+
case '>': return c > 0;
|
|
201
|
+
case '<': return c < 0;
|
|
202
|
+
default: return c === 0;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Whether an advisory's `affectedRange` covers `version`: `||`-separated
|
|
208
|
+
* comparator sets, each either the lookup spec forms (`^`, `~`, partial,
|
|
209
|
+
* exact) or space-separated comparators (`>=1.0.0 <1.2.3`) or a hyphen range.
|
|
210
|
+
* `*` covers everything; an unparseable range covers nothing.
|
|
211
|
+
*/
|
|
212
|
+
export function advisoryRangeCovers(range, version) {
|
|
213
|
+
if (!parseSemver(version))
|
|
214
|
+
return false;
|
|
215
|
+
return range.split('||').map((s) => s.trim()).some((set) => set === '*' || (set !== '' && comparatorSetCovers(set, version)));
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Why `range` isn't a usable advisory range (the forms {@link advisoryRangeCovers}
|
|
219
|
+
* understands), or null when it is. An advisory whose range parses as nothing
|
|
220
|
+
* would silently cover nothing, so drafts are refused instead.
|
|
221
|
+
*/
|
|
222
|
+
export function advisoryRangeProblem(range) {
|
|
223
|
+
const trimmed = range.trim();
|
|
224
|
+
if (trimmed === '')
|
|
225
|
+
return 'the affected range is empty';
|
|
226
|
+
if (trimmed.length > 255)
|
|
227
|
+
return 'the affected range is longer than 255 characters';
|
|
228
|
+
for (const set of trimmed.split('||').map((x) => x.trim())) {
|
|
229
|
+
if (set === '*')
|
|
230
|
+
continue;
|
|
231
|
+
if (set === '')
|
|
232
|
+
return 'the affected range has an empty "||" alternative';
|
|
233
|
+
const hyphen = /^(\S+)\s+-\s+(\S+)$/.exec(set);
|
|
234
|
+
if (hyphen) {
|
|
235
|
+
if (!parseSemver(hyphen[1]) || !parseSemver(hyphen[2]))
|
|
236
|
+
return `"${set}" is not a valid hyphen range`;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const parts = set.split(/\s+/).filter(Boolean);
|
|
240
|
+
if (parts.length === 1 && parts[0] !== 'latest' && parseVersionSpec(parts[0]))
|
|
241
|
+
continue;
|
|
242
|
+
const bad = parts.find((x) => !COMPARATOR.test(x));
|
|
243
|
+
if (bad !== undefined)
|
|
244
|
+
return `"${bad}" is not a version, a ^/~ range or a comparator (>=, <=, >, <, =)`;
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
/** The PUBLISHED advisories whose range covers `version` (any severity), most severe first. */
|
|
249
|
+
export function advisoriesCovering(advisories, version) {
|
|
250
|
+
const rank = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
251
|
+
return advisories
|
|
252
|
+
.filter((a) => a.state === 'published' && advisoryRangeCovers(a.affectedRange, version))
|
|
253
|
+
.sort((a, b) => rank[a.severity] - rank[b.severity]);
|
|
254
|
+
}
|
|
255
|
+
/** The PUBLISHED advisories the policy blocks `version` for. */
|
|
256
|
+
export function blockingAdvisories(advisories, version, policy) {
|
|
257
|
+
const severities = ADVISORY_BLOCK_SEVERITIES[policy.blockOnAdvisory];
|
|
258
|
+
if (severities.length === 0)
|
|
259
|
+
return [];
|
|
260
|
+
return advisories.filter((a) => a.state === 'published' && severities.includes(a.severity) && advisoryRangeCovers(a.affectedRange, version));
|
|
261
|
+
}
|
|
262
|
+
const isStable = (v) => (parseSemver(v)?.prerelease.length ?? 1) === 0;
|
|
263
|
+
/**
|
|
264
|
+
* The implicit Official install's range: every version of the LOWEST live
|
|
265
|
+
* major (`<major>.x`) — patch and minor versions flow, a new major never does
|
|
266
|
+
* (the org moves to it with an explicit install). Null when nothing is live.
|
|
267
|
+
*/
|
|
268
|
+
export function implicitInstallRange(versions) {
|
|
269
|
+
const majors = versions
|
|
270
|
+
.filter((v) => !v.yankedAt && isStable(v.version))
|
|
271
|
+
.map((v) => parseSemver(v.version).major);
|
|
272
|
+
if (majors.length === 0)
|
|
273
|
+
return null;
|
|
274
|
+
return `${Math.min(...majors)}.x`;
|
|
275
|
+
}
|
|
276
|
+
/** Whether an install's version policy admits `version` (the baseline is `pinnedVersion`). */
|
|
277
|
+
export function installAdmits(install, version, versions) {
|
|
278
|
+
const base = install.pinnedVersion;
|
|
279
|
+
switch (install.versionPolicy) {
|
|
280
|
+
case 'pinned':
|
|
281
|
+
return version === base;
|
|
282
|
+
case 'patch':
|
|
283
|
+
return base !== null && satisfiesVersionSpec(version, `~${base}`);
|
|
284
|
+
case 'minor':
|
|
285
|
+
return base !== null && satisfiesVersionSpec(version, `^${base}`);
|
|
286
|
+
case 'latest': {
|
|
287
|
+
if (!isStable(version))
|
|
288
|
+
return false;
|
|
289
|
+
if (base === null)
|
|
290
|
+
return true;
|
|
291
|
+
if (compareSemver(version, base) < 0)
|
|
292
|
+
return false;
|
|
293
|
+
// Never cross a version the publisher marked breaking.
|
|
294
|
+
return !versions.some((v) => v.breaking && compareSemver(v.version, base) > 0 && compareSemver(v.version, version) <= 0);
|
|
295
|
+
}
|
|
296
|
+
default:
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/** Whether `mode` admits `version` (the implicit range for an implicit install). */
|
|
301
|
+
export function modeAdmits(mode, version, versions) {
|
|
302
|
+
if (mode.kind === 'explicit')
|
|
303
|
+
return installAdmits(mode.install, version, versions);
|
|
304
|
+
const range = implicitInstallRange(versions);
|
|
305
|
+
return range !== null && satisfiesVersionSpec(version, range);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Pick the listed version a reference resolves to (see the module doc), or
|
|
309
|
+
* the refusal that explains why none can.
|
|
310
|
+
*/
|
|
311
|
+
export function selectListingVersion(input) {
|
|
312
|
+
const { ref, versions, mode, requested, advisories, policy } = input;
|
|
313
|
+
const exact = requested !== undefined && !isVersionRange(requested) ? requested.trim() : null;
|
|
314
|
+
if (exact !== null) {
|
|
315
|
+
const v = versions.find((x) => x.version === exact);
|
|
316
|
+
if (!v)
|
|
317
|
+
return { refusal: { code: 'NOT_FOUND', reason: 'version_not_found', message: `${ref} has no published version ${exact}.` } };
|
|
318
|
+
if (v.yankedAt) {
|
|
319
|
+
return {
|
|
320
|
+
refusal: {
|
|
321
|
+
code: 'PLUGIN_UNAVAILABLE',
|
|
322
|
+
reason: 'yanked',
|
|
323
|
+
message: `${ref}@${exact} is yanked${v.yankReason ? `: ${v.yankReason}` : ''}. Move to a supported version.`,
|
|
324
|
+
details: { version: exact },
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
if (mode.kind === 'explicit' && !installAdmits(mode.install, exact, versions)) {
|
|
329
|
+
return {
|
|
330
|
+
refusal: {
|
|
331
|
+
code: 'PLUGIN_NOT_INSTALLED',
|
|
332
|
+
reason: 'version_outside_install',
|
|
333
|
+
message: `${ref}@${exact} is outside your install (${mode.install.versionPolicy} from ${mode.install.pinnedVersion}). Upgrade the install first.`,
|
|
334
|
+
details: { version: exact, versionPolicy: mode.install.versionPolicy, pinnedVersion: mode.install.pinnedVersion },
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const blocking = blockingAdvisories(advisories, exact, policy);
|
|
339
|
+
if (blocking.length)
|
|
340
|
+
return { refusal: advisoryRefusal(ref, exact, blocking) };
|
|
341
|
+
return { version: v };
|
|
342
|
+
}
|
|
343
|
+
const resolvedBefore = mode.kind === 'explicit' ? mode.install.resolvedVersion : null;
|
|
344
|
+
// The range the INSTALL allows. For the implicit install an explicit spec on
|
|
345
|
+
// the reference replaces the implicit range (it is a deliberate choice).
|
|
346
|
+
const admitted = versions.filter((v) => !v.yankedAt
|
|
347
|
+
&& (mode.kind === 'explicit' ? installAdmits(mode.install, v.version, versions)
|
|
348
|
+
: requested !== undefined || modeAdmits(mode, v.version, versions))
|
|
349
|
+
&& (requested === undefined || satisfiesVersionSpec(v.version, requested))
|
|
350
|
+
&& (!v.pausedAt || v.version === resolvedBefore));
|
|
351
|
+
const allowed = admitted.filter((v) => blockingAdvisories(advisories, v.version, policy).length === 0);
|
|
352
|
+
// Ranges only admit prereleases they name (npm semantics), so the highest
|
|
353
|
+
// admitted version is the answer.
|
|
354
|
+
const best = highest(allowed.map((v) => v.version));
|
|
355
|
+
if (best)
|
|
356
|
+
return { version: allowed.find((v) => v.version === best) };
|
|
357
|
+
if (admitted.length > 0) {
|
|
358
|
+
const newest = highest(admitted.map((v) => v.version));
|
|
359
|
+
return { refusal: advisoryRefusal(ref, newest, blockingAdvisories(advisories, newest, policy)) };
|
|
360
|
+
}
|
|
361
|
+
if (mode.kind === 'explicit' && requested !== undefined
|
|
362
|
+
&& versions.some((v) => !v.yankedAt && satisfiesVersionSpec(v.version, requested))) {
|
|
363
|
+
return {
|
|
364
|
+
refusal: {
|
|
365
|
+
code: 'PLUGIN_NOT_INSTALLED',
|
|
366
|
+
reason: 'version_outside_install',
|
|
367
|
+
message: `No version of ${ref} matching ${requested} is inside your install (${mode.install.versionPolicy} from ${mode.install.pinnedVersion}). Upgrade the install first.`,
|
|
368
|
+
details: { requested, versionPolicy: mode.install.versionPolicy, pinnedVersion: mode.install.pinnedVersion },
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
refusal: {
|
|
374
|
+
code: 'NOT_FOUND',
|
|
375
|
+
reason: 'no_matching_version',
|
|
376
|
+
message: `No resolvable version of ${ref}${requested ? ` matches ${requested}` : ''}.`,
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
/** The highest of `versions` by semver (prereleases included). */
|
|
381
|
+
function highest(versions) {
|
|
382
|
+
return versions.reduce((best, v) => (best === null || compareSemver(v, best) > 0 ? v : best), null);
|
|
383
|
+
}
|
|
384
|
+
function advisoryRefusal(ref, version, blocking) {
|
|
385
|
+
const fixed = blocking.map((a) => a.fixedVersion).filter((v) => !!v);
|
|
386
|
+
return {
|
|
387
|
+
code: 'PLUGIN_BLOCKED_BY_POLICY',
|
|
388
|
+
reason: 'advisory',
|
|
389
|
+
message: `${ref}@${version} is blocked by your organization's advisory policy: ${blocking.map((a) => `${a.severity} — ${a.summary}`).join('; ')}.`
|
|
390
|
+
+ (fixed.length ? ` Fixed in ${fixed.join(', ')}.` : ''),
|
|
391
|
+
details: { version, advisories: blocking.map((a) => a.id), ...(fixed.length ? { fixedVersions: fixed } : {}) },
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
/** The org ids whose installs and policies apply, own first. */
|
|
395
|
+
export function scopeOrgIds(scope) {
|
|
396
|
+
const own = scope.orgId.toLowerCase();
|
|
397
|
+
const root = scope.rootOrgId?.toLowerCase();
|
|
398
|
+
return root && root !== own ? [own, root] : [own];
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* How the org reaches `listing` — or the refusal. An ACTIVE own-org row wins,
|
|
402
|
+
* then the root org's (a team inherits it); failing both, the implicit
|
|
403
|
+
* Official install (unless the policy is `explicit`); otherwise the org's own
|
|
404
|
+
* pending / denied row explains the refusal.
|
|
405
|
+
*/
|
|
406
|
+
export function installModeFor(publisher, listing, installs, policy, scope) {
|
|
407
|
+
const [own, root] = scopeOrgIds(scope);
|
|
408
|
+
const forListing = installs.filter((i) => i.listingId === listing.id);
|
|
409
|
+
const ownRow = forListing.find((i) => i.orgId.toLowerCase() === own);
|
|
410
|
+
const rootRow = root ? forListing.find((i) => i.orgId.toLowerCase() === root) : undefined;
|
|
411
|
+
if (ownRow?.status === 'active')
|
|
412
|
+
return { kind: 'explicit', install: ownRow, inherited: false };
|
|
413
|
+
if (rootRow?.status === 'active')
|
|
414
|
+
return { kind: 'explicit', install: rootRow, inherited: true };
|
|
415
|
+
const ref = `${publisher.handle}/${listing.name}`;
|
|
416
|
+
if (publisher.handle === OFFICIAL_PUBLISHER_HANDLE) {
|
|
417
|
+
if (policy.officialInstalls === 'implicit')
|
|
418
|
+
return { kind: 'implicit' };
|
|
419
|
+
if (!ownRow) {
|
|
420
|
+
return {
|
|
421
|
+
code: 'PLUGIN_NOT_INSTALLED',
|
|
422
|
+
reason: 'official_explicit',
|
|
423
|
+
message: `Your organization installs Official plugins explicitly; install ${ref} first.`,
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (ownRow?.status === 'pending_approval') {
|
|
428
|
+
return { code: 'PLUGIN_NOT_INSTALLED', reason: 'pending_approval', message: `The install of ${ref} is waiting for approval.` };
|
|
429
|
+
}
|
|
430
|
+
if (ownRow?.status === 'denied') {
|
|
431
|
+
return { code: 'PLUGIN_NOT_INSTALLED', reason: 'denied', message: `The install of ${ref} was denied.` };
|
|
432
|
+
}
|
|
433
|
+
return { code: 'PLUGIN_NOT_INSTALLED', reason: 'not_installed', message: `${ref} is not installed in your organization.` };
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* A {@link ListingDataSource} over a drizzle transaction. The caller owns the
|
|
437
|
+
* transaction's scope: it must be able to read the ecosystem tables (app-role
|
|
438
|
+
* RLS) and the install rows of the org AND its root org (a team's reads of its
|
|
439
|
+
* root's rows need an elevated scope, like parent-org plugin reads).
|
|
440
|
+
*/
|
|
441
|
+
export function drizzleListingSource(tx) {
|
|
442
|
+
const db = tx;
|
|
443
|
+
const P = schema.publisher;
|
|
444
|
+
const L = schema.pluginListing;
|
|
445
|
+
const V = schema.pluginListingVersion;
|
|
446
|
+
const A = schema.pluginAdvisory;
|
|
447
|
+
const I = schema.pluginInstall;
|
|
448
|
+
const IP = schema.pluginInstallPolicy;
|
|
449
|
+
return {
|
|
450
|
+
publisherByHandle: async (handle) => (await db.select().from(P).where(eq(P.handle, handle)))[0] ?? null,
|
|
451
|
+
publishersByIds: async (ids) => (ids.length ? db.select().from(P).where(inArray(P.id, ids)) : []),
|
|
452
|
+
listingByName: async (publisherId, name) => (await db.select().from(L).where(and(eq(L.publisherId, publisherId), eq(L.name, name))))[0] ?? null,
|
|
453
|
+
liveListings: async (filter = {}) => {
|
|
454
|
+
if (filter.ids && filter.ids.length === 0)
|
|
455
|
+
return [];
|
|
456
|
+
if (filter.names && filter.names.length === 0)
|
|
457
|
+
return [];
|
|
458
|
+
return db.select().from(L).where(and(inArray(L.state, ['listed', 'unmaintained']), ...(filter.ids ? [inArray(L.id, filter.ids)] : []), ...(filter.names ? [inArray(L.name, filter.names)] : [])));
|
|
459
|
+
},
|
|
460
|
+
versionsForListings: async (ids) => (ids.length ? db.select().from(V).where(inArray(V.listingId, ids)) : []),
|
|
461
|
+
advisoriesForListings: async (ids) => (ids.length ? db.select().from(A).where(and(inArray(A.listingId, ids), eq(A.state, 'published'))) : []),
|
|
462
|
+
installsForOrgs: async (orgIds) => (orgIds.length ? db.select().from(I).where(inArray(I.orgId, orgIds)) : []),
|
|
463
|
+
policiesForOrgs: async (orgIds) => (orgIds.length ? db.select().from(IP).where(inArray(IP.orgId, orgIds)) : []),
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Resolve `ref` to a listed version for `scope`, or refuse. Null when the
|
|
468
|
+
* listing doesn't exist at all (an unqualified reference then simply has no
|
|
469
|
+
* Official fallback).
|
|
470
|
+
*/
|
|
471
|
+
export async function resolveListingReference(source, ref, scope) {
|
|
472
|
+
const handle = ref.publisher ?? OFFICIAL_PUBLISHER_HANDLE;
|
|
473
|
+
const publisher = await source.publisherByHandle(handle);
|
|
474
|
+
if (!publisher)
|
|
475
|
+
return null;
|
|
476
|
+
const listing = await source.listingByName(publisher.id, ref.name);
|
|
477
|
+
if (!listing)
|
|
478
|
+
return null;
|
|
479
|
+
const orgIds = scopeOrgIds(scope);
|
|
480
|
+
const [policies, installs] = await Promise.all([source.policiesForOrgs(orgIds), source.installsForOrgs(orgIds)]);
|
|
481
|
+
const policy = effectiveConsumptionPolicy(policies, orgIds[0], orgIds[1]);
|
|
482
|
+
const block = listingBlock(policy, publisher, listing);
|
|
483
|
+
if (block)
|
|
484
|
+
return { ok: false, refusal: blockRefusal(block), publisher, listing };
|
|
485
|
+
const mode = installModeFor(publisher, listing, installs, policy, scope);
|
|
486
|
+
if ('code' in mode)
|
|
487
|
+
return { ok: false, refusal: mode, publisher, listing };
|
|
488
|
+
const [versions, advisories] = await Promise.all([
|
|
489
|
+
source.versionsForListings([listing.id]),
|
|
490
|
+
source.advisoriesForListings([listing.id]),
|
|
491
|
+
]);
|
|
492
|
+
const ref_ = `${publisher.handle}/${listing.name}`;
|
|
493
|
+
const choice = selectListingVersion({ ref: ref_, versions, mode, requested: ref.version, advisories, policy });
|
|
494
|
+
if ('refusal' in choice)
|
|
495
|
+
return { ok: false, refusal: choice.refusal, publisher, listing };
|
|
496
|
+
const version = choice.version;
|
|
497
|
+
const { warnings, secretsWithheld } = listedVersionWarnings({ publisher, listing, version, advisories, policy });
|
|
498
|
+
return { ok: true, publisher, listing, version, mode, policy, secretsWithheld, warnings };
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* The non-fatal notes a resolved listed version carries (lookup answers,
|
|
502
|
+
* synth prints them, the installs view shows them): an unmaintained listing, a
|
|
503
|
+
* deprecated version, a PUBLISHED advisory covering the version that the org's
|
|
504
|
+
* `blockOnAdvisory` doesn't block (a blocking one refuses resolution instead),
|
|
505
|
+
* and withheld secrets.
|
|
506
|
+
*/
|
|
507
|
+
export function listedVersionWarnings(input) {
|
|
508
|
+
const { publisher, listing, version, advisories, policy } = input;
|
|
509
|
+
const ref = `${publisher.handle}/${listing.name}`;
|
|
510
|
+
const declaresSecrets = (version.specSnapshot?.secrets ?? []).length > 0;
|
|
511
|
+
const secretsWithheld = declaresSecrets && !policy.secretsAllowedTiers.includes(publisher.tier);
|
|
512
|
+
const warnings = [];
|
|
513
|
+
if (listing.state === 'unmaintained') {
|
|
514
|
+
warnings.push({ code: 'LISTING_UNMAINTAINED', message: `${ref} is unmaintained: it receives no updates. Plan a replacement.` });
|
|
515
|
+
}
|
|
516
|
+
if (version.deprecatedAt) {
|
|
517
|
+
warnings.push({ code: 'PLUGIN_DEPRECATED', message: `${ref}@${version.version} is deprecated${version.deprecationMessage ? `: ${version.deprecationMessage}` : ''}.` });
|
|
518
|
+
}
|
|
519
|
+
for (const a of advisoriesCovering(advisories, version.version)) {
|
|
520
|
+
warnings.push({
|
|
521
|
+
code: 'PLUGIN_ADVISORY',
|
|
522
|
+
message: `${ref}@${version.version} is affected by a ${a.severity} security advisory: ${a.summary}`
|
|
523
|
+
+ `${a.fixedVersion ? ` Fixed in ${a.fixedVersion}.` : ''}`,
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
if (secretsWithheld) {
|
|
527
|
+
warnings.push({ code: 'PLUGIN_SECRETS_WITHHELD', message: `${ref} is a ${publisher.tier} plugin; your organization's policy gives it no secrets, so its declared secrets are not injected.` });
|
|
528
|
+
}
|
|
529
|
+
return { warnings, secretsWithheld };
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* The plugin record a resolved listing version runs as — the shape synth and
|
|
533
|
+
* the contract check read (a `plugins` row's run fields), built from the
|
|
534
|
+
* version's frozen spec snapshot. `id` is the LISTING VERSION's id (the step
|
|
535
|
+
* manifest resolves it back), `imageRepository` its `public/*` copy.
|
|
536
|
+
*/
|
|
537
|
+
export function listedPluginRecord(res) {
|
|
538
|
+
const { publisher, listing, version, mode } = res;
|
|
539
|
+
const s = (version.specSnapshot ?? {});
|
|
540
|
+
const arr = (v) => (Array.isArray(v) ? v : []);
|
|
541
|
+
const obj = (v) => (v && typeof v === 'object' && !Array.isArray(v) ? v : {});
|
|
542
|
+
return {
|
|
543
|
+
id: version.id,
|
|
544
|
+
source: 'listing',
|
|
545
|
+
publisher: publisher.handle,
|
|
546
|
+
publisherTier: publisher.tier,
|
|
547
|
+
listingId: listing.id,
|
|
548
|
+
install: mode.kind,
|
|
549
|
+
name: listing.name,
|
|
550
|
+
version: version.version,
|
|
551
|
+
imageRepository: version.imageRepository,
|
|
552
|
+
imageDigest: version.imageDigest,
|
|
553
|
+
buildType: typeof s.buildType === 'string' ? s.buildType : (version.imageDigest ? 'build_image' : 'metadata_only'),
|
|
554
|
+
pluginType: s.pluginType ?? 'CodeBuildStep',
|
|
555
|
+
computeType: s.computeType ?? 'SMALL',
|
|
556
|
+
description: s.description ?? listing.description ?? null,
|
|
557
|
+
summary: s.summary ?? listing.summary ?? null,
|
|
558
|
+
displayName: s.displayName ?? null,
|
|
559
|
+
keywords: arr(s.keywords),
|
|
560
|
+
category: s.category ?? listing.category,
|
|
561
|
+
metadata: obj(s.metadata),
|
|
562
|
+
env: obj(s.env),
|
|
563
|
+
buildArgs: {},
|
|
564
|
+
installCommands: arr(s.installCommands),
|
|
565
|
+
commands: arr(s.commands),
|
|
566
|
+
timeout: s.timeout ?? null,
|
|
567
|
+
failureBehavior: s.failureBehavior ?? 'fail',
|
|
568
|
+
primaryOutputDirectory: s.primaryOutputDirectory ?? null,
|
|
569
|
+
secrets: res.secretsWithheld ? [] : arr(s.secrets),
|
|
570
|
+
requiredMetadata: arr(s.requiredMetadata),
|
|
571
|
+
requiredVars: arr(s.requiredVars),
|
|
572
|
+
metadataTypes: obj(s.metadataTypes),
|
|
573
|
+
varsTypes: obj(s.varsTypes),
|
|
574
|
+
networkEgress: arr(s.networkEgress),
|
|
575
|
+
runAsRoot: s.runAsRoot ?? null,
|
|
576
|
+
license: s.license ?? listing.license ?? null,
|
|
577
|
+
homepageUrl: s.homepageUrl ?? listing.homepageUrl ?? null,
|
|
578
|
+
sourceUrl: s.sourceUrl ?? listing.sourceUrl ?? null,
|
|
579
|
+
documentationUrl: s.documentationUrl ?? null,
|
|
580
|
+
icon: s.icon ?? listing.icon ?? null,
|
|
581
|
+
changelog: version.changelog,
|
|
582
|
+
breaking: version.breaking,
|
|
583
|
+
vulnCritical: version.vulnCritical,
|
|
584
|
+
vulnHigh: version.vulnHigh,
|
|
585
|
+
scannedAt: version.scannedAt,
|
|
586
|
+
lifecycle: version.deprecatedAt ? 'deprecated' : 'production',
|
|
587
|
+
deprecatedAt: version.deprecatedAt,
|
|
588
|
+
deprecationMessage: version.deprecationMessage,
|
|
589
|
+
yankedAt: null,
|
|
590
|
+
yankReason: null,
|
|
591
|
+
visibility: 'public',
|
|
592
|
+
isDefault: true,
|
|
593
|
+
isActive: true,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
/** Load the org's policy and install rows. */
|
|
597
|
+
export async function loadOrgInstallContext(source, scope) {
|
|
598
|
+
const orgIds = scopeOrgIds(scope);
|
|
599
|
+
const [policies, installs] = await Promise.all([source.policiesForOrgs(orgIds), source.installsForOrgs(orgIds)]);
|
|
600
|
+
return { policy: effectiveConsumptionPolicy(policies, orgIds[0], orgIds[1]), installs, scope };
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* The org's standing on every live listing (or only `filter`'s). Used by the
|
|
604
|
+
* in-app catalog; {@link resolvableListings} narrows it to what resolves.
|
|
605
|
+
*/
|
|
606
|
+
export async function orgListingStates(source, scope, filter = {}, ctx) {
|
|
607
|
+
const context = ctx ?? await loadOrgInstallContext(source, scope);
|
|
608
|
+
const live = await source.liveListings(filter);
|
|
609
|
+
if (live.length === 0)
|
|
610
|
+
return [];
|
|
611
|
+
const ids = live.map((l) => l.id);
|
|
612
|
+
const [pubs, versions, advisories] = await Promise.all([
|
|
613
|
+
source.publishersByIds([...new Set(live.map((l) => l.publisherId))]),
|
|
614
|
+
source.versionsForListings(ids),
|
|
615
|
+
source.advisoriesForListings(ids),
|
|
616
|
+
]);
|
|
617
|
+
const byPublisher = new Map(pubs.map((p) => [p.id, p]));
|
|
618
|
+
const own = scopeOrgIds(scope)[0];
|
|
619
|
+
const out = [];
|
|
620
|
+
for (const listing of live) {
|
|
621
|
+
const publisher = byPublisher.get(listing.publisherId);
|
|
622
|
+
if (!publisher)
|
|
623
|
+
continue;
|
|
624
|
+
const vs = versions.filter((v) => v.listingId === listing.id);
|
|
625
|
+
const block = listingBlock(context.policy, publisher, listing);
|
|
626
|
+
const mode = installModeFor(publisher, listing, context.installs, context.policy, scope);
|
|
627
|
+
const listingAdvisories = advisories.filter((a) => a.listingId === listing.id);
|
|
628
|
+
let resolved = null;
|
|
629
|
+
let refusal = null;
|
|
630
|
+
if (!block && !('code' in mode)) {
|
|
631
|
+
const choice = selectListingVersion({
|
|
632
|
+
ref: `${publisher.handle}/${listing.name}`, versions: vs, mode, advisories: listingAdvisories, policy: context.policy,
|
|
633
|
+
});
|
|
634
|
+
if ('version' in choice)
|
|
635
|
+
resolved = choice.version;
|
|
636
|
+
else
|
|
637
|
+
refusal = choice.refusal;
|
|
638
|
+
}
|
|
639
|
+
const ownInstall = context.installs.find((i) => i.listingId === listing.id && i.orgId.toLowerCase() === own) ?? null;
|
|
640
|
+
out.push({ publisher, listing, versions: vs, mode, block, resolved, refusal, advisories: listingAdvisories, ownInstall, policy: context.policy });
|
|
641
|
+
}
|
|
642
|
+
return out;
|
|
643
|
+
}
|
|
644
|
+
/** The listings an org's references resolve to now (installed or implicit, not blocked). */
|
|
645
|
+
export async function resolvableListings(source, scope, filter = {}) {
|
|
646
|
+
return (await orgListingStates(source, scope, filter))
|
|
647
|
+
.filter((s) => s.resolved !== null);
|
|
648
|
+
}
|
|
649
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLXJlc29sdXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3BsdWdpbi1yZXNvbHV0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUVILE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUvQyxPQUFPLEVBQ0wsYUFBYSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsb0JBQW9CLEdBQ25GLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixlQUFlLEVBQ2YsTUFBTSxHQWFQLE1BQU0sK0JBQStCLENBQUM7QUFnQnZDLDJFQUEyRTtBQUMzRSxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBZ0MsTUFBTSxDQUFDLE1BQU0sQ0FBb0I7SUFDdEcsWUFBWSxFQUFFLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQztJQUN0QyxvQkFBb0IsRUFBRSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUM7SUFDakQsbUJBQW1CLEVBQUUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDO0lBQzdDLGVBQWUsRUFBRSxVQUFVO0lBQzNCLGdCQUFnQixFQUFFLFVBQVU7SUFDNUIsZUFBZSxFQUFFLEVBQUU7Q0FDcEIsQ0FBQyxDQUFDO0FBRUgscURBQXFEO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQztBQUV4QyxNQUFNLFdBQVcsR0FBK0IsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBRTlFLE1BQU0sU0FBUyxHQUFHLENBQUMsS0FBOEIsRUFBbUIsRUFBRSxDQUNwRSxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJ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LGNBQWMsQ0FBQyxDQUFDLEVBQzVDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFDbEQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUN6RCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDNUcscUJBQXFCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDN0ksZUFBZSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUks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T0FBTyxDQUFDLE1BQU0sZ0JBQWdCLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztTQUNuRCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQTZELEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxDQUFDO0FBQ25HLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBSZXNvbHZpbmcgYSBwbHVnaW4gcmVmZXJlbmNlIHRvIGFuIGVjb3N5c3RlbSBMSVNUSU5HIHZlcnNpb24gdGhyb3VnaCB0aGVcbiAqIG9yZydzIGluc3RhbGwgKGRvY3MvcGx1Z2luLWluc3RhbGxpbmcubWQpLlxuICpcbiAqIE9uZSBpbXBsZW1lbnRhdGlvbiBzaGFyZWQgYnkgZXZlcnkgcGxhY2UgdGhhdCBhbnN3ZXJzIFwid2hpY2ggbGlzdGVkIHZlcnNpb25cbiAqIGRvZXMgdGhpcyBvcmcncyByZWZlcmVuY2UgcnVuP1wiOiB0aGUgcGx1Z2luIHNlcnZpY2UncyBgL3BsdWdpbnMvbG9va3VwYCAod2hhdFxuICogc3ludGggcGlucyksIHRoZSBwaXBlbGluZSBzZXJ2aWNlJ3MgY29udHJhY3QgY2hlY2sgYXQgcGlwZWxpbmUgY3JlYXRlLCB0aGUgQUlcbiAqIGdlbmVyYXRvcidzIHBsdWdpbiBsaXN0IGFuZCB0aGUgcGxhY2Vob2xkZXIgZ3VhcmQuIFRoZSBkZWNpc2lvbnMgYXJlIFBVUkVcbiAqIGZ1bmN0aW9ucyBvdmVyIGxvYWRlZCByb3dzOyB0aGUgcm93cyBjb21lIHRocm91Z2ggYSB7QGxpbmsgTGlzdGluZ0RhdGFTb3VyY2V9XG4gKiBzbyBlYWNoIHNlcnZpY2UgY2FuIGxvYWQgdGhlbSBpdHMgb3duIHdheSAoe0BsaW5rIGRyaXp6bGVMaXN0aW5nU291cmNlfSBpcyB0aGVcbiAqIHBsYWluIGRyaXp6bGUgb25lKS5cbiAqXG4gKiBUaGUgbW9kZWw6XG4gKiAgLSBBbiBvcmcgcmVzb2x2ZXMgYSBsaXN0aW5nIG9ubHkgdGhyb3VnaCBhbiBJTlNUQUxMOiBhbiBleHBsaWNpdFxuICogICAgYHBsdWdpbl9pbnN0YWxsc2Agcm93IChpdHMgb3duLCBvciDigJQgZm9yIGEgdGVhbSDigJQgaXRzIHJvb3Qgb3JnJ3MpLCBvclxuICogICAgZm9yIHRoZSBPZmZpY2lhbCBwdWJsaXNoZXIgdGhlIElNUExJQ0lUIGluc3RhbGwgZXZlcnkgb3JnIGhhcyB1bmxlc3MgaXRzXG4gKiAgICBjb25zdW1wdGlvbiBwb2xpY3kgc2F5cyBgb2ZmaWNpYWxJbnN0YWxsczogZXhwbGljaXRgLiBBbiBleHBsaWNpdFxuICogICAgaW5zdGFsbCBvdmVycmlkZXMgdGhlIGltcGxpY2l0IG9uZS5cbiAqICAtIFRoZSBvcmcncyBDT05TVU1QVElPTiBQT0xJQ1kgaXMgYXBwbGllZCBhdCBldmVyeSByZXNvbHV0aW9uOiBhbGxvd2VkXG4gKiAgICB0aWVycywgYmxvY2tlZCBsaXN0aW5ncywgYWR2aXNvcnkgYmxvY2tpbmc7IHNlY3JldHMgYXJlIHdpdGhoZWxkIGZyb20gdGllcnNcbiAqICAgIHRoZSBwb2xpY3kgZG9lc24ndCB0cnVzdCB3aXRoIHRoZW0uIEEgdGVhbSdzIHBvbGljeSBpcyBtZXJnZWQgd2l0aCBpdHMgcm9vdFxuICogICAgb3JnJ3MgYW5kIGNhbiBvbmx5IGJlIHN0cmljdGVyLlxuICogIC0gVmVyc2lvbiBjaG9pY2U6IHRoZSBpbnN0YWxsJ3MgcmFuZ2UgKHBpbm5lZCAvIGB+YCAvIGBeYCAvIG5vbi1icmVha2luZ1xuICogICAgbGF0ZXN0OyBpbXBsaWNpdCA9IHRoZSBsb3dlc3QgbGl2ZSBtYWpvciksIG5hcnJvd2VkIGJ5IHRoZSByZWZlcmVuY2UncyBvd25cbiAqICAgIHZlcnNpb24gc3BlYy4gWWFua2VkIHZlcnNpb25zIG5ldmVyIHJlc29sdmUgZm9yIGEgbGlzdGluZzsgYSBwYXVzZWRcbiAqICAgIHZlcnNpb24gaXMgc2tpcHBlZCB1bmxlc3MgdGhlIGluc3RhbGwgYWxyZWFkeSByZXNvbHZlZCB0byBpdCBvciB0aGVcbiAqICAgIHJlZmVyZW5jZSBwaW5zIGl0IGV4YWN0bHk7IGFkdmlzb3J5LWJsb2NrZWQgdmVyc2lvbnMgYXJlIHNraXBwZWQuXG4gKi9cblxuaW1wb3J0IHsgYW5kLCBlcSwgaW5BcnJheSB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB0eXBlIHsgQ3J1ZFR4IH0gZnJvbSAnLi9jcnVkLXNlcnZpY2UuanMnO1xuaW1wb3J0IHtcbiAgY29tcGFyZVNlbXZlciwgaXNWZXJzaW9uUmFuZ2UsIHBhcnNlU2VtdmVyLCBwYXJzZVZlcnNpb25TcGVjLCBzYXRpc2ZpZXNWZXJzaW9uU3BlYyxcbn0gZnJvbSAnLi9zZW12ZXItcmFuZ2UuanMnO1xuaW1wb3J0IHtcbiAgT0ZGSUNJQUxfUFVCTElTSEVSX0hBTkRMRSxcbiAgUFVCTElTSEVSX1RJRVJTLFxuICBzY2hlbWEsXG4gIHR5cGUgQWR2aXNvcnlTZXZlcml0eSxcbiAgdHlwZSBCbG9ja2VkTGlzdGluZ1JlZixcbiAgdHlwZSBCbG9ja09uQWR2aXNvcnksXG4gIHR5cGUgSW5zdGFsbFZlcnNpb25Qb2xpY3ksXG4gIHR5cGUgT2ZmaWNpYWxJbnN0YWxscyxcbiAgdHlwZSBQbHVnaW5BZHZpc29yeSxcbiAgdHlwZSBQbHVnaW5JbnN0YWxsLFxuICB0eXBlIFBsdWdpbkluc3RhbGxQb2xpY3ksXG4gIHR5cGUgUGx1Z2luTGlzdGluZyxcbiAgdHlwZSBQbHVnaW5MaXN0aW5nVmVyc2lvbixcbiAgdHlwZSBQdWJsaXNoZXIsXG4gIHR5cGUgUHVibGlzaGVyVGllcixcbn0gZnJvbSAnLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEuanMnO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQ29uc3VtcHRpb24gcG9saWN5XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogQW4gb3JnJ3MgY29uc3VtcHRpb24gcG9saWN5LCBhcyB0aGUgcmVzb2x2ZXIgYXBwbGllcyBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29uc3VtcHRpb25Qb2xpY3kge1xuICBhbGxvd2VkVGllcnM6IFB1Ymxpc2hlclRpZXJbXTtcbiAgcmVxdWlyZUFwcHJvdmFsVGllcnM6IFB1Ymxpc2hlclRpZXJbXTtcbiAgc2VjcmV0c0FsbG93ZWRUaWVyczogUHVibGlzaGVyVGllcltdO1xuICBibG9ja09uQWR2aXNvcnk6IEJsb2NrT25BZHZpc29yeTtcbiAgb2ZmaWNpYWxJbnN0YWxsczogT2ZmaWNpYWxJbnN0YWxscztcbiAgYmxvY2tlZExpc3RpbmdzOiBCbG9ja2VkTGlzdGluZ1JlZltdO1xufVxuXG4vKiogVGhlIGRlZmF1bHRzIChhbmQgdGhlIGNvbHVtbiBkZWZhdWx0cyBvZiBgcGx1Z2luX2luc3RhbGxfcG9saWNpZXNgKS4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0NPTlNVTVBUSU9OX1BPTElDWTogUmVhZG9ubHk8Q29uc3VtcHRpb25Qb2xpY3k+ID0gT2JqZWN0LmZyZWV6ZTxDb25zdW1wdGlvblBvbGljeT4oe1xuICBhbGxvd2VkVGllcnM6IFsnb2ZmaWNpYWwnLCAndmVyaWZpZWQnXSxcbiAgcmVxdWlyZUFwcHJvdmFsVGllcnM6IFsnY29tbXVuaXR5JywgJ3VudmVyaWZpZWQnXSxcbiAgc2VjcmV0c0FsbG93ZWRUaWVyczogWydvZmZpY2lhbCcsICd2ZXJpZmllZCddLFxuICBibG9ja09uQWR2aXNvcnk6ICdjcml0aWNhbCcsXG4gIG9mZmljaWFsSW5zdGFsbHM6ICdpbXBsaWNpdCcsXG4gIGJsb2NrZWRMaXN0aW5nczogW10sXG59KTtcblxuLyoqIEF0IG1vc3QgdGhpcyBtYW55IGJsb2NrZWQgbGlzdGluZ3MgcGVyIHBvbGljeS4gKi9cbmV4cG9ydCBjb25zdCBNQVhfQkxPQ0tFRF9MSVNUSU5HUyA9IDUwMDtcblxuY29uc3QgQkxPQ0tfT1JERVI6IHJlYWRvbmx5IEJsb2NrT25BZHZpc29yeVtdID0gWyduZXZlcicsICdjcml0aWNhbCcsICdoaWdoJ107XG5cbmNvbnN0IHNvcnRUaWVycyA9ICh0aWVyczogSXRlcmFibGU8UHVibGlzaGVyVGllcj4pOiBQdWJsaXNoZXJUaWVyW10gPT5cbiAgUFVCTElTSEVSX1RJRVJTLmZpbHRlcigodCkgPT4gbmV3IFNldCh0aWVycykuaGFzKHQpKTtcblxuY29uc3QgbGlzdGluZ0tleSA9IChyOiBCbG9ja2VkTGlzdGluZ1JlZik6IHN0cmluZyA9PiBgJHtyLnB1Ymxpc2hlcn0vJHtyLm5hbWV9YDtcblxuZnVuY3Rpb24gdW5pcXVlTGlzdGluZ3MocmVmczogcmVhZG9ubHkgQmxvY2tlZExpc3RpbmdSZWZbXSk6IEJsb2NrZWRMaXN0aW5nUmVmW10ge1xuICBjb25zdCBzZWVuID0gbmV3IE1hcDxzdHJpbmcsIEJsb2NrZWRMaXN0aW5nUmVmPigpO1xuICBmb3IgKGNvbnN0IHIgb2YgcmVmcykgc2Vlbi5zZXQobGlzdGluZ0tleShyKSwgeyBwdWJsaXNoZXI6IHIucHVibGlzaGVyLCBuYW1lOiByLm5hbWUgfSk7XG4gIHJldHVybiBbLi4uc2Vlbi52YWx1ZXMoKV0uc29ydCgoYSwgYikgPT4gbGlzdGluZ0tleShhKS5sb2NhbGVDb21wYXJlKGxpc3RpbmdLZXkoYikpKTtcbn1cblxuLyoqIEEgc3RvcmVkIHBvbGljeSByb3cgKG9yIG5vbmUpIGFzIGEge0BsaW5rIENvbnN1bXB0aW9uUG9saWN5fS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2xpY3lPZihyb3c6IFBhcnRpYWw8UGx1Z2luSW5zdGFsbFBvbGljeT4gfCBudWxsIHwgdW5kZWZpbmVkKTogQ29uc3VtcHRpb25Qb2xpY3kge1xuICBjb25zdCBkID0gREVGQVVMVF9DT05TVU1QVElPTl9QT0xJQ1k7XG4gIHJldHVybiB7XG4gICAgYWxsb3dlZFRpZXJzOiBzb3J0VGllcnMocm93Py5hbGxvd2VkVGllcnMgPz8gZC5hbGxvd2VkVGllcnMpLFxuICAgIHJlcXVpcmVBcHByb3ZhbFRpZXJzOiBzb3J0VGllcnMocm93Py5yZXF1aXJlQXBwcm92YWxUaWVycyA/PyBkLnJlcXVpcmVBcHByb3ZhbFRpZXJzKSxcbiAgICBzZWNyZXRzQWxsb3dlZFRpZXJzOiBzb3J0VGllcnMocm93Py5zZWNyZXRzQWxsb3dlZFRpZXJzID8/IGQuc2VjcmV0c0FsbG93ZWRUaWVycyksXG4gICAgYmxvY2tPbkFkdmlzb3J5OiByb3c/LmJsb2NrT25BZHZpc29yeSA/PyBkLmJsb2NrT25BZHZpc29yeSxcbiAgICBvZmZpY2lhbEluc3RhbGxzOiByb3c/Lm9mZmljaWFsSW5zdGFsbHMgPz8gZC5vZmZpY2lhbEluc3RhbGxzLFxuICAgIGJsb2NrZWRMaXN0aW5nczogdW5pcXVlTGlzdGluZ3Mocm93Py5ibG9ja2VkTGlzdGluZ3MgPz8gZC5ibG9ja2VkTGlzdGluZ3MpLFxuICB9O1xufVxuXG4vKipcbiAqIEEgdGVhbSdzIHBvbGljeSB1bmRlciBpdHMgcm9vdCBvcmcnczogZWFjaCBmaWVsZCB0YWtlcyB0aGUgU1RSSUNURVIgb2ZcbiAqIHRoZSB0d28sIHNvIGEgdGVhbSBjYW4gbmFycm93IHdoYXQgaXRzIHJvb3QgYWxsb3dzIGJ1dCBuZXZlciB3aWRlbiBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlQ29uc3VtcHRpb25Qb2xpY2llcyhyb290OiBDb25zdW1wdGlvblBvbGljeSwgdGVhbTogQ29uc3VtcHRpb25Qb2xpY3kpOiBDb25zdW1wdGlvblBvbGljeSB7XG4gIGNvbnN0IGludGVyc2VjdCA9IChhOiBQdWJsaXNoZXJUaWVyW10sIGI6IFB1Ymxpc2hlclRpZXJbXSkgPT4gc29ydFRpZXJzKGEuZmlsdGVyKCh0KSA9PiBiLmluY2x1ZGVzKHQpKSk7XG4gIGNvbnN0IHVuaW9uID0gKGE6IFB1Ymxpc2hlclRpZXJbXSwgYjogUHVibGlzaGVyVGllcltdKSA9PiBzb3J0VGllcnMoWy4uLmEsIC4uLmJdKTtcbiAgY29uc3Qgc3RyaWN0ZXJCbG9jayA9IEJMT0NLX09SREVSLmluZGV4T2Yocm9vdC5ibG9ja09uQWR2aXNvcnkpID49IEJMT0NLX09SREVSLmluZGV4T2YodGVhbS5ibG9ja09uQWR2aXNvcnkpXG4gICAgPyByb290LmJsb2NrT25BZHZpc29yeSA6IHRlYW0uYmxvY2tPbkFkdmlzb3J5O1xuICByZXR1cm4ge1xuICAgIGFsbG93ZWRUaWVyczogaW50ZXJzZWN0KHJvb3QuYWxsb3dlZFRpZXJzLCB0ZWFtLmFsbG93ZWRUaWVycyksXG4gICAgcmVxdWlyZUFwcHJvdmFsVGllcnM6IHVuaW9uKHJvb3QucmVxdWlyZUFwcHJvdmFsVGllcnMsIHRlYW0ucmVxdWlyZUFwcHJvdmFsVGllcnMpLFxuICAgIHNlY3JldHNBbGxvd2VkVGllcnM6IGludGVyc2VjdChyb290LnNlY3JldHNBbGxvd2VkVGllcnMsIHRlYW0uc2VjcmV0c0FsbG93ZWRUaWVycyksXG4gICAgYmxvY2tPbkFkdmlzb3J5OiBzdHJpY3RlckJsb2NrLFxuICAgIG9mZmljaWFsSW5zdGFsbHM6IHJvb3Qub2ZmaWNpYWxJbnN0YWxscyA9PT0gJ2V4cGxpY2l0JyB8fCB0ZWFtLm9mZmljaWFsSW5zdGFsbHMgPT09ICdleHBsaWNpdCcgPyAnZXhwbGljaXQnIDogJ2ltcGxpY2l0JyxcbiAgICBibG9ja2VkTGlzdGluZ3M6IHVuaXF1ZUxpc3RpbmdzKFsuLi5yb290LmJsb2NrZWRMaXN0aW5ncywgLi4udGVhbS5ibG9ja2VkTGlzdGluZ3NdKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgcG9saWN5IGFuIG9yZydzIHJlc29sdXRpb24gcnVucyB1bmRlci4gQSByb290IG9yZzogaXRzIG93biByb3cgKG9yIHRoZVxuICogZGVmYXVsdHMpLiBBIHRlYW0gKGByb290T3JnSWRgIHNldCk6IGl0cyByb290J3MgcG9saWN5LCBtZXJnZWQgd2l0aCB0aGVcbiAqIHRlYW0ncyBvd24gcm93IHdoZW4gaXQgaGFzIG9uZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVmZmVjdGl2ZUNvbnN1bXB0aW9uUG9saWN5KFxuICByb3dzOiBSZWFkb25seUFycmF5PFBhcnRpYWw8UGx1Z2luSW5zdGFsbFBvbGljeT4gJiB7IG9yZ0lkPzogc3RyaW5nIH0+LFxuICBvcmdJZDogc3RyaW5nLFxuICByb290T3JnSWQ/OiBzdHJpbmcsXG4pOiBDb25zdW1wdGlvblBvbGljeSB7XG4gIGNvbnN0IG93biA9IHJvd3MuZmluZCgocikgPT4gci5vcmdJZCA9PT0gb3JnSWQpID8/IG51bGw7XG4gIGlmICghcm9vdE9yZ0lkIHx8IHJvb3RPcmdJZCA9PT0gb3JnSWQpIHJldHVybiBwb2xpY3lPZihvd24pO1xuICBjb25zdCByb290ID0gcG9saWN5T2Yocm93cy5maW5kKChyKSA9PiByLm9yZ0lkID09PSByb290T3JnSWQpID8/IG51bGwpO1xuICByZXR1cm4gb3duID8gbWVyZ2VDb25zdW1wdGlvblBvbGljaWVzKHJvb3QsIHBvbGljeU9mKG93bikpIDogcm9vdDtcbn1cblxuY29uc3QgSEFORExFX1JFID0gL15bYS16MC05XSsoPzotW2EtejAtOV0rKSokLztcbmNvbnN0IE5BTUVfUkUgPSAvXlthLXowLTldW2EtejAtOS5fLV0qJC87XG5cbmZ1bmN0aW9uIHRpZXJMaXN0KHY6IHVua25vd24sIGZpZWxkOiBzdHJpbmcpOiBQdWJsaXNoZXJUaWVyW10gfCBzdHJpbmcge1xuICBpZiAoIUFycmF5LmlzQXJyYXkodikpIHJldHVybiBgJHtmaWVsZH0gbXVzdCBiZSBhbiBhcnJheSBvZiB0aWVyc2A7XG4gIGNvbnN0IGJhZCA9IHYuZmlsdGVyKCh0KSA9PiAhKFBVQkxJU0hFUl9USUVSUyBhcyByZWFkb25seSB1bmtub3duW10pLmluY2x1ZGVzKHQpKTtcbiAgaWYgKGJhZC5sZW5ndGgpIHJldHVybiBgJHtmaWVsZH0gaGFzIHVua25vd24gdGllcnM6ICR7YmFkLm1hcChTdHJpbmcpLmpvaW4oJywgJyl9YDtcbiAgcmV0dXJuIHNvcnRUaWVycyh2IGFzIFB1Ymxpc2hlclRpZXJbXSk7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgYSAocGFydGlhbCkgcG9saWN5IHVwZGF0ZSBvdmVyIGBiYXNlYC4gUmV0dXJucyB0aGUgZnVsbCBuZXcgcG9saWN5LFxuICogb3IgYW4gZXJyb3IgbWVzc2FnZS4gYGJsb2NrZWRMaXN0aW5nc2AgZW50cmllcyBhcmUgYHsgcHVibGlzaGVyLCBuYW1lIH1gIG9yXG4gKiBgXCJwdWJsaXNoZXIvbmFtZVwiYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UG9saWN5VXBkYXRlKGJhc2U6IENvbnN1bXB0aW9uUG9saWN5LCBpbnB1dDogdW5rbm93bik6IENvbnN1bXB0aW9uUG9saWN5IHwgc3RyaW5nIHtcbiAgaWYgKCFpbnB1dCB8fCB0eXBlb2YgaW5wdXQgIT09ICdvYmplY3QnIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpKSByZXR1cm4gJ2JvZHkgbXVzdCBiZSBhbiBvYmplY3QnO1xuICBjb25zdCBiID0gaW5wdXQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNvbnN0IG5leHQ6IENvbnN1bXB0aW9uUG9saWN5ID0geyAuLi5iYXNlIH07XG4gIGZvciAoY29uc3QgZmllbGQgb2YgWydhbGxvd2VkVGllcnMnLCAncmVxdWlyZUFwcHJvdmFsVGllcnMnLCAnc2VjcmV0c0FsbG93ZWRUaWVycyddIGFzIGNvbnN0KSB7XG4gICAgaWYgKGJbZmllbGRdID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHRpZXJzID0gdGllckxpc3QoYltmaWVsZF0sIGZpZWxkKTtcbiAgICBpZiAodHlwZW9mIHRpZXJzID09PSAnc3RyaW5nJykgcmV0dXJuIHRpZXJzO1xuICAgIG5leHRbZmllbGRdID0gdGllcnM7XG4gIH1cbiAgaWYgKGIuYmxvY2tPbkFkdmlzb3J5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoIUJMT0NLX09SREVSLmluY2x1ZGVzKGIuYmxvY2tPbkFkdmlzb3J5IGFzIEJsb2NrT25BZHZpc29yeSkpIHJldHVybiAnYmxvY2tPbkFkdmlzb3J5IG11c3QgYmUgY3JpdGljYWwsIGhpZ2ggb3IgbmV2ZXInO1xuICAgIG5leHQuYmxvY2tPbkFkdmlzb3J5ID0gYi5ibG9ja09uQWR2aXNvcnkgYXMgQmxvY2tPbkFkdmlzb3J5O1xuICB9XG4gIGlmIChiLm9mZmljaWFsSW5zdGFsbHMgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChiLm9mZmljaWFsSW5zdGFsbHMgIT09ICdpbXBsaWNpdCcgJiYgYi5vZmZpY2lhbEluc3RhbGxzICE9PSAnZXhwbGljaXQnKSByZXR1cm4gJ29mZmljaWFsSW5zdGFsbHMgbXVzdCBiZSBpbXBsaWNpdCBvciBleHBsaWNpdCc7XG4gICAgbmV4dC5vZmZpY2lhbEluc3RhbGxzID0gYi5vZmZpY2lhbEluc3RhbGxzO1xuICB9XG4gIGlmIChiLmJsb2NrZWRMaXN0aW5ncyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGIuYmxvY2tlZExpc3RpbmdzKSkgcmV0dXJuICdibG9ja2VkTGlzdGluZ3MgbXVzdCBiZSBhbiBhcnJheSc7XG4gICAgaWYgKGIuYmxvY2tlZExpc3RpbmdzLmxlbmd0aCA+IE1BWF9CTE9DS0VEX0xJU1RJTkdTKSByZXR1cm4gYGF0IG1vc3QgJHtNQVhfQkxPQ0tFRF9MSVNUSU5HU30gYmxvY2tlZCBsaXN0aW5nc2A7XG4gICAgY29uc3QgcmVmczogQmxvY2tlZExpc3RpbmdSZWZbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcmF3IG9mIGIuYmxvY2tlZExpc3RpbmdzKSB7XG4gICAgICBjb25zdCByZWYgPSB0eXBlb2YgcmF3ID09PSAnc3RyaW5nJ1xuICAgICAgICA/ICgoKSA9PiB7IGNvbnN0IFtwdWJsaXNoZXIsIG5hbWUsIGV4dHJhXSA9IHJhdy5zcGxpdCgnLycpOyByZXR1cm4gZXh0cmEgPT09IHVuZGVmaW5lZCA/IHsgcHVibGlzaGVyLCBuYW1lIH0gOiBudWxsOyB9KSgpXG4gICAgICAgIDogcmF3ICYmIHR5cGVvZiByYXcgPT09ICdvYmplY3QnID8geyBwdWJsaXNoZXI6IChyYXcgYXMgQmxvY2tlZExpc3RpbmdSZWYpLnB1Ymxpc2hlciwgbmFtZTogKHJhdyBhcyBCbG9ja2VkTGlzdGluZ1JlZikubmFtZSB9IDogbnVsbDtcbiAgICAgIGlmICghcmVmIHx8IHR5cGVvZiByZWYucHVibGlzaGVyICE9PSAnc3RyaW5nJyB8fCB0eXBlb2YgcmVmLm5hbWUgIT09ICdzdHJpbmcnXG4gICAgICAgIHx8ICFIQU5ETEVfUkUudGVzdChyZWYucHVibGlzaGVyKSB8fCAhTkFNRV9SRS50ZXN0KHJlZi5uYW1lKSkge1xuICAgICAgICByZXR1cm4gJ2VhY2ggYmxvY2tlZCBsaXN0aW5nIG11c3QgYmUgeyBwdWJsaXNoZXIsIG5hbWUgfSAob3IgXCJwdWJsaXNoZXIvbmFtZVwiKSc7XG4gICAgICB9XG4gICAgICByZWZzLnB1c2goeyBwdWJsaXNoZXI6IHJlZi5wdWJsaXNoZXIsIG5hbWU6IHJlZi5uYW1lIH0pO1xuICAgIH1cbiAgICBuZXh0LmJsb2NrZWRMaXN0aW5ncyA9IHVuaXF1ZUxpc3RpbmdzKHJlZnMpO1xuICB9XG4gIHJldHVybiBuZXh0O1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmVmdXNhbHMgYW5kIHdhcm5pbmdzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogV2h5IGEgcmVmZXJlbmNlIGNhbid0IHJlc29sdmU7IGBjb2RlYCBpcyBhbiBhcGktY29yZSBgRXJyb3JDb2RlYCBuYW1lLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHV0aW9uUmVmdXNhbCB7XG4gIGNvZGU6ICdOT1RfRk9VTkQnIHwgJ1BMVUdJTl9OT1RfSU5TVEFMTEVEJyB8ICdQTFVHSU5fQkxPQ0tFRF9CWV9QT0xJQ1knIHwgJ1BMVUdJTl9VTkFWQUlMQUJMRSc7XG4gIHJlYXNvbjogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGRldGFpbHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuLyoqIEEgbm9uLWZhdGFsIG5vdGUgYSByZXNvbHV0aW9uIGNhcnJpZXMgKHN5bnRoIHByaW50cyBpdCkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdXRpb25XYXJuaW5nIHtcbiAgY29kZTogJ1BMVUdJTl9BRFZJU09SWScgfCAnUExVR0lOX0RFUFJFQ0FURUQnIHwgJ1BMVUdJTl9TRUNSRVRTX1dJVEhIRUxEJyB8ICdMSVNUSU5HX1VOTUFJTlRBSU5FRCc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbn1cblxuLyoqIFdoeSB0aGUgb3JnJ3MgcG9saWN5IChvciB0aGUgbGlzdGluZydzIHN0YXRlKSBrZWVwcyBhIGxpc3Rpbmcgb3V0LCBvciBudWxsLiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaXN0aW5nQmxvY2sge1xuICByZWFzb246ICd0aWVyJyB8ICdibG9ja2VkX2xpc3RpbmcnIHwgJ3N1c3BlbmRlZCc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbn1cblxuLyoqIFdoZXRoZXIgYHBvbGljeWAgKG9yIHRoZSBsaXN0aW5nJ3Mgb3duIHN0YXRlKSByZWZ1c2VzIHRoZSBsaXN0aW5nIG91dHJpZ2h0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RpbmdCbG9jayhcbiAgcG9saWN5OiBDb25zdW1wdGlvblBvbGljeSxcbiAgcHVibGlzaGVyOiBQaWNrPFB1Ymxpc2hlciwgJ2hhbmRsZScgfCAndGllcicgfCAnc3VzcGVuZGVkQXQnPixcbiAgbGlzdGluZzogUGljazxQbHVnaW5MaXN0aW5nLCAnbmFtZScgfCAnc3RhdGUnPixcbik6IExpc3RpbmdCbG9jayB8IG51bGwge1xuICBjb25zdCByZWYgPSBgJHtwdWJsaXNoZXIuaGFuZGxlfS8ke2xpc3RpbmcubmFtZX1gO1xuICBpZiAocHVibGlzaGVyLnN1c3BlbmRlZEF0IHx8IGxpc3Rpbmcuc3RhdGUgPT09ICdzdXNwZW5kZWQnIHx8IGxpc3Rpbmcuc3RhdGUgPT09ICd0cmFuc2ZlcnJlZCcpIHtcbiAgICByZXR1cm4geyByZWFzb246ICdzdXNwZW5kZWQnLCBtZXNzYWdlOiBgJHtyZWZ9IGlzICR7bGlzdGluZy5zdGF0ZSA9PT0gJ3RyYW5zZmVycmVkJyA/ICd0cmFuc2ZlcnJlZCcgOiAnc3VzcGVuZGVkJ30gYW5kIG5vIGxvbmdlciByZXNvbHZlcy5gIH07XG4gIH1cbiAgaWYgKHBvbGljeS5ibG9ja2VkTGlzdGluZ3Muc29tZSgoYikgPT4gYi5wdWJsaXNoZXIgPT09IHB1Ymxpc2hlci5oYW5kbGUgJiYgYi5uYW1lID09PSBsaXN0aW5nLm5hbWUpKSB7XG4gICAgcmV0dXJuIHsgcmVhc29uOiAnYmxvY2tlZF9saXN0aW5nJywgbWVzc2FnZTogYFlvdXIgb3JnYW5pemF0aW9uJ3MgcGx1Z2luIHBvbGljeSBibG9ja3MgJHtyZWZ9LmAgfTtcbiAgfVxuICBpZiAoIXBvbGljeS5hbGxvd2VkVGllcnMuaW5jbHVkZXMocHVibGlzaGVyLnRpZXIpKSB7XG4gICAgcmV0dXJuIHsgcmVhc29uOiAndGllcicsIG1lc3NhZ2U6IGBZb3VyIG9yZ2FuaXphdGlvbidzIHBsdWdpbiBwb2xpY3kgZG9lc24ndCBhbGxvdyAke3B1Ymxpc2hlci50aWVyfSBwbHVnaW5zICgke3JlZn0pLmAgfTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqIFRoZSByZWZ1c2FsIGEge0BsaW5rIExpc3RpbmdCbG9ja30gYmVjb21lcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBibG9ja1JlZnVzYWwoYmxvY2s6IExpc3RpbmdCbG9jayk6IFJlc29sdXRpb25SZWZ1c2FsIHtcbiAgcmV0dXJuIGJsb2NrLnJlYXNvbiA9PT0gJ3N1c3BlbmRlZCdcbiAgICA/IHsgY29kZTogJ1BMVUdJTl9VTkFWQUlMQUJMRScsIHJlYXNvbjogJ3N1c3BlbmRlZCcsIG1lc3NhZ2U6IGJsb2NrLm1lc3NhZ2UgfVxuICAgIDogeyBjb2RlOiAnUExVR0lOX0JMT0NLRURfQllfUE9MSUNZJywgcmVhc29uOiBibG9jay5yZWFzb24sIG1lc3NhZ2U6IGJsb2NrLm1lc3NhZ2UgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEFkdmlzb3JpZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBTZXZlcml0aWVzIGVhY2ggYGJsb2NrT25BZHZpc29yeWAgc2V0dGluZyBibG9ja3MuICovXG5leHBvcnQgY29uc3QgQURWSVNPUllfQkxPQ0tfU0VWRVJJVElFUzogUmVhZG9ubHk8UmVjb3JkPEJsb2NrT25BZHZpc29yeSwgcmVhZG9ubHkgQWR2aXNvcnlTZXZlcml0eVtdPj4gPSB7XG4gIGNyaXRpY2FsOiBbJ2NyaXRpY2FsJ10sXG4gIGhpZ2g6IFsnY3JpdGljYWwnLCAnaGlnaCddLFxuICBuZXZlcjogW10sXG59O1xuXG5jb25zdCBDT01QQVJBVE9SID0gL14oPj18PD18Pnw8fD0pP1xccyp2PyhcXGQrXFwuXFxkK1xcLlxcZCsoPzotWzAtOUEtWmEtei4tXSspPyg/OlxcK1swLTlBLVphLXouLV0rKT8pJC87XG5cbi8qKiBPbmUgY29tcGFyYXRvciBzZXQgKGA+PTEuMC4wIDwxLjIuM2AsIGBeMS4yYCwgYDEueGAsIGAxLjAuMCAtIDEuMi4wYCkgYWdhaW5zdCBgdmVyc2lvbmAuICovXG5mdW5jdGlvbiBjb21wYXJhdG9yU2V0Q292ZXJzKHNldDogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgaHlwaGVuID0gL14oXFxTKylcXHMrLVxccysoXFxTKykkLy5leGVjKHNldCk7XG4gIGlmIChoeXBoZW4pIHJldHVybiBjb21wYXJlU2VtdmVyKHZlcnNpb24sIGh5cGhlblsxXSEpID49IDAgJiYgY29tcGFyZVNlbXZlcih2ZXJzaW9uLCBoeXBoZW5bMl0hKSA8PSAwO1xuICBjb25zdCBwYXJ0cyA9IHNldC5zcGxpdCgvXFxzKy8pLmZpbHRlcihCb29sZWFuKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMSAmJiBwYXJzZVZlcnNpb25TcGVjKHBhcnRzWzBdISkpIHJldHVybiBzYXRpc2ZpZXNWZXJzaW9uU3BlYyh2ZXJzaW9uLCBwYXJ0c1swXSEpO1xuICByZXR1cm4gcGFydHMuZXZlcnkoKHApID0+IHtcbiAgICBjb25zdCBtID0gQ09NUEFSQVRPUi5leGVjKHApO1xuICAgIGlmICghbSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGMgPSBjb21wYXJlU2VtdmVyKHZlcnNpb24sIG1bMl0hKTtcbiAgICBzd2l0Y2ggKG1bMV0gPz8gJz0nKSB7XG4gICAgICBjYXNlICc+PSc6IHJldHVybiBjID49IDA7XG4gICAgICBjYXNlICc8PSc6IHJldHVybiBjIDw9IDA7XG4gICAgICBjYXNlICc+JzogcmV0dXJuIGMgPiAwO1xuICAgICAgY2FzZSAnPCc6IHJldHVybiBjIDwgMDtcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBjID09PSAwO1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogV2hldGhlciBhbiBhZHZpc29yeSdzIGBhZmZlY3RlZFJhbmdlYCBjb3ZlcnMgYHZlcnNpb25gOiBgfHxgLXNlcGFyYXRlZFxuICogY29tcGFyYXRvciBzZXRzLCBlYWNoIGVpdGhlciB0aGUgbG9va3VwIHNwZWMgZm9ybXMgKGBeYCwgYH5gLCBwYXJ0aWFsLFxuICogZXhhY3QpIG9yIHNwYWNlLXNlcGFyYXRlZCBjb21wYXJhdG9ycyAoYD49MS4wLjAgPDEuMi4zYCkgb3IgYSBoeXBoZW4gcmFuZ2UuXG4gKiBgKmAgY292ZXJzIGV2ZXJ5dGhpbmc7IGFuIHVucGFyc2VhYmxlIHJhbmdlIGNvdmVycyBub3RoaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWR2aXNvcnlSYW5nZUNvdmVycyhyYW5nZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFwYXJzZVNlbXZlcih2ZXJzaW9uKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gcmFuZ2Uuc3BsaXQoJ3x8JykubWFwKChzKSA9PiBzLnRyaW0oKSkuc29tZSgoc2V0KSA9PiBzZXQgPT09ICcqJyB8fCAoc2V0ICE9PSAnJyAmJiBjb21wYXJhdG9yU2V0Q292ZXJzKHNldCwgdmVyc2lvbikpKTtcbn1cblxuLyoqXG4gKiBXaHkgYHJhbmdlYCBpc24ndCBhIHVzYWJsZSBhZHZpc29yeSByYW5nZSAodGhlIGZvcm1zIHtAbGluayBhZHZpc29yeVJhbmdlQ292ZXJzfVxuICogdW5kZXJzdGFuZHMpLCBvciBudWxsIHdoZW4gaXQgaXMuIEFuIGFkdmlzb3J5IHdob3NlIHJhbmdlIHBhcnNlcyBhcyBub3RoaW5nXG4gKiB3b3VsZCBzaWxlbnRseSBjb3ZlciBub3RoaW5nLCBzbyBkcmFmdHMgYXJlIHJlZnVzZWQgaW5zdGVhZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkdmlzb3J5UmFuZ2VQcm9ibGVtKHJhbmdlOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgdHJpbW1lZCA9IHJhbmdlLnRyaW0oKTtcbiAgaWYgKHRyaW1tZWQgPT09ICcnKSByZXR1cm4gJ3RoZSBhZmZlY3RlZCByYW5nZSBpcyBlbXB0eSc7XG4gIGlmICh0cmltbWVkLmxlbmd0aCA+IDI1NSkgcmV0dXJuICd0aGUgYWZmZWN0ZWQgcmFuZ2UgaXMgbG9uZ2VyIHRoYW4gMjU1IGNoYXJhY3RlcnMnO1xuICBmb3IgKGNvbnN0IHNldCBvZiB0cmltbWVkLnNwbGl0KCd8fCcpLm1hcCgoeCkgPT4geC50cmltKCkpKSB7XG4gICAgaWYgKHNldCA9PT0gJyonKSBjb250aW51ZTtcbiAgICBpZiAoc2V0ID09PSAnJykgcmV0dXJuICd0aGUgYWZmZWN0ZWQgcmFuZ2UgaGFzIGFuIGVtcHR5IFwifHxcIiBhbHRlcm5hdGl2ZSc7XG4gICAgY29uc3QgaHlwaGVuID0gL14oXFxTKylcXHMrLVxccysoXFxTKykkLy5leGVjKHNldCk7XG4gICAgaWYgKGh5cGhlbikge1xuICAgICAgaWYgKCFwYXJzZVNlbXZlcihoeXBoZW5bMV0hKSB8fCAhcGFyc2VTZW12ZXIoaHlwaGVuWzJdISkpIHJldHVybiBgXCIke3NldH1cIiBpcyBub3QgYSB2YWxpZCBoeXBoZW4gcmFuZ2VgO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRzID0gc2V0LnNwbGl0KC9cXHMrLykuZmlsdGVyKEJvb2xlYW4pO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDEgJiYgcGFydHNbMF0gIT09ICdsYXRlc3QnICYmIHBhcnNlVmVyc2lvblNwZWMocGFydHNbMF0hKSkgY29udGludWU7XG4gICAgY29uc3QgYmFkID0gcGFydHMuZmluZCgoeCkgPT4gIUNPTVBBUkFUT1IudGVzdCh4KSk7XG4gICAgaWYgKGJhZCAhPT0gdW5kZWZpbmVkKSByZXR1cm4gYFwiJHtiYWR9XCIgaXMgbm90IGEgdmVyc2lvbiwgYSBeL34gcmFuZ2Ugb3IgYSBjb21wYXJhdG9yICg+PSwgPD0sID4sIDwsID0pYDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqIFRoZSBQVUJMSVNIRUQgYWR2aXNvcmllcyB3aG9zZSByYW5nZSBjb3ZlcnMgYHZlcnNpb25gIChhbnkgc2V2ZXJpdHkpLCBtb3N0IHNldmVyZSBmaXJzdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZHZpc29yaWVzQ292ZXJpbmc8QSBleHRlbmRzIFBpY2s8UGx1Z2luQWR2aXNvcnksICdzZXZlcml0eScgfCAnc3RhdGUnIHwgJ2FmZmVjdGVkUmFuZ2UnPj4oXG4gIGFkdmlzb3JpZXM6IHJlYWRvbmx5IEFbXSxcbiAgdmVyc2lvbjogc3RyaW5nLFxuKTogQVtdIHtcbiAgY29uc3QgcmFuazogUmVjb3JkPEFkdmlzb3J5U2V2ZXJpdHksIG51bWJlcj4gPSB7IGNyaXRpY2FsOiAwLCBoaWdoOiAxLCBtZWRpdW06IDIsIGxvdzogMyB9O1xuICByZXR1cm4gYWR2aXNvcmllc1xuICAgIC5maWx0ZXIoKGEpID0+IGEuc3RhdGUgPT09ICdwdWJsaXNoZWQnICYmIGFkdmlzb3J5UmFuZ2VDb3ZlcnMoYS5hZmZlY3RlZFJhbmdlLCB2ZXJzaW9uKSlcbiAgICAuc29ydCgoYSwgYikgPT4gcmFua1thLnNldmVyaXR5XSAtIHJhbmtbYi5zZXZlcml0eV0pO1xufVxuXG4vKiogVGhlIFBVQkxJU0hFRCBhZHZpc29yaWVzIHRoZSBwb2xpY3kgYmxvY2tzIGB2ZXJzaW9uYCBmb3IuICovXG5leHBvcnQgZnVuY3Rpb24gYmxvY2tpbmdBZHZpc29yaWVzKFxuICBhZHZpc29yaWVzOiByZWFkb25seSBQaWNrPFBsdWdpbkFkdmlzb3J5LCAnaWQnIHwgJ3NldmVyaXR5JyB8ICdzdGF0ZScgfCAnYWZmZWN0ZWRSYW5nZScgfCAnZml4ZWRWZXJzaW9uJyB8ICdzdW1tYXJ5Jz5bXSxcbiAgdmVyc2lvbjogc3RyaW5nLFxuICBwb2xpY3k6IFBpY2s8Q29uc3VtcHRpb25Qb2xpY3ksICdibG9ja09uQWR2aXNvcnknPixcbik6IEFycmF5PFBpY2s8UGx1Z2luQWR2aXNvcnksICdpZCcgfCAnc2V2ZXJpdHknIHwgJ3N0YXRlJyB8ICdhZmZlY3RlZFJhbmdlJyB8ICdmaXhlZFZlcnNpb24nIHwgJ3N1bW1hcnknPj4ge1xuICBjb25zdCBzZXZlcml0aWVzID0gQURWSVNPUllfQkxPQ0tfU0VWRVJJVElFU1twb2xpY3kuYmxvY2tPbkFkdmlzb3J5XTtcbiAgaWYgKHNldmVyaXRpZXMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gIHJldHVybiBhZHZpc29yaWVzLmZpbHRlcigoYSkgPT4gYS5zdGF0ZSA9PT0gJ3B1Ymxpc2hlZCcgJiYgc2V2ZXJpdGllcy5pbmNsdWRlcyhhLnNldmVyaXR5KSAmJiBhZHZpc29yeVJhbmdlQ292ZXJzKGEuYWZmZWN0ZWRSYW5nZSwgdmVyc2lvbikpO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gSW5zdGFsbHMgYW5kIHZlcnNpb24gY2hvaWNlXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogSG93IHRoZSBvcmcgcmVhY2hlcyBhIGxpc3Rpbmc6IGFuIGV4cGxpY2l0IGluc3RhbGwgcm93LCBvciB0aGUgaW1wbGljaXQgT2ZmaWNpYWwgb25lLiAqL1xuZXhwb3J0IHR5cGUgSW5zdGFsbE1vZGUgPVxuICB8IHsga2luZDogJ2V4cGxpY2l0JzsgaW5zdGFsbDogUGx1Z2luSW5zdGFsbDsgaW5oZXJpdGVkOiBib29sZWFuIH1cbiAgfCB7IGtpbmQ6ICdpbXBsaWNpdCcgfTtcblxudHlwZSBWZXJzaW9uUm93ID0gUGljazxQbHVnaW5MaXN0aW5nVmVyc2lvbiwgJ3ZlcnNpb24nIHwgJ3lhbmtlZEF0JyB8ICdwYXVzZWRBdCcgfCAnYnJlYWtpbmcnPjtcblxuY29uc3QgaXNTdGFibGUgPSAodjogc3RyaW5nKTogYm9vbGVhbiA9PiAocGFyc2VTZW12ZXIodik/LnByZXJlbGVhc2UubGVuZ3RoID8/IDEpID09PSAwO1xuXG4vKipcbiAqIFRoZSBpbXBsaWNpdCBPZmZpY2lhbCBpbnN0YWxsJ3MgcmFuZ2U6IGV2ZXJ5IHZlcnNpb24gb2YgdGhlIExPV0VTVCBsaXZlXG4gKiBtYWpvciAoYDxtYWpvcj4ueGApIOKAlCBwYXRjaCBhbmQgbWlub3IgdmVyc2lvbnMgZmxvdywgYSBuZXcgbWFqb3IgbmV2ZXIgZG9lc1xuICogKHRoZSBvcmcgbW92ZXMgdG8gaXQgd2l0aCBhbiBleHBsaWNpdCBpbnN0YWxsKS4gTnVsbCB3aGVuIG5vdGhpbmcgaXMgbGl2ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGltcGxpY2l0SW5zdGFsbFJhbmdlKHZlcnNpb25zOiByZWFkb25seSBWZXJzaW9uUm93W10pOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgbWFqb3JzID0gdmVyc2lvbnNcbiAgICAuZmlsdGVyKCh2KSA9PiAhdi55YW5rZWRBdCAmJiBpc1N0YWJsZSh2LnZlcnNpb24pKVxuICAgIC5tYXAoKHYpID0+IHBhcnNlU2VtdmVyKHYudmVyc2lvbikhLm1ham9yKTtcbiAgaWYgKG1ham9ycy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICByZXR1cm4gYCR7TWF0aC5taW4oLi4ubWFqb3JzKX0ueGA7XG59XG5cbi8qKiBXaGV0aGVyIGFuIGluc3RhbGwncyB2ZXJzaW9uIHBvbGljeSBhZG1pdHMgYHZlcnNpb25gICh0aGUgYmFzZWxpbmUgaXMgYHBpbm5lZFZlcnNpb25gKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YWxsQWRtaXRzKFxuICBpbnN0YWxsOiBQaWNrPFBsdWdpbkluc3RhbGwsICd2ZXJzaW9uUG9saWN5JyB8ICdwaW5uZWRWZXJzaW9uJz4sXG4gIHZlcnNpb246IHN0cmluZyxcbiAgdmVyc2lvbnM6IHJlYWRvbmx5IFZlcnNpb25Sb3dbXSxcbik6IGJvb2xlYW4ge1xuICBjb25zdCBiYXNlID0gaW5zdGFsbC5waW5uZWRWZXJzaW9uO1xuICBzd2l0Y2ggKGluc3RhbGwudmVyc2lvblBvbGljeSBhcyBJbnN0YWxsVmVyc2lvblBvbGljeSkge1xuICAgIGNhc2UgJ3Bpbm5lZCc6XG4gICAgICByZXR1cm4gdmVyc2lvbiA9PT0gYmFzZTtcbiAgICBjYXNlICdwYXRjaCc6XG4gICAgICByZXR1cm4gYmFzZSAhPT0gbnVsbCAmJiBzYXRpc2ZpZXNWZXJzaW9uU3BlYyh2ZXJzaW9uLCBgfiR7YmFzZX1gKTtcbiAgICBjYXNlICdtaW5vcic6XG4gICAgICByZXR1cm4gYmFzZSAhPT0gbnVsbCAmJiBzYXRpc2ZpZXNWZXJzaW9uU3BlYyh2ZXJzaW9uLCBgXiR7YmFzZX1gKTtcbiAgICBjYXNlICdsYXRlc3QnOiB7XG4gICAgICBpZiAoIWlzU3RhYmxlKHZlcnNpb24pKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoYmFzZSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAoY29tcGFyZVNlbXZlcih2ZXJzaW9uLCBiYXNlKSA8IDApIHJldHVybiBmYWxzZTtcbiAgICAgIC8vIE5ldmVyIGNyb3NzIGEgdmVyc2lvbiB0aGUgcHVibGlzaGVyIG1hcmtlZCBicmVha2luZy5cbiAgICAgIHJldHVybiAhdmVyc2lvbnMuc29tZSgodikgPT4gdi5icmVha2luZyAmJiBjb21wYXJlU2VtdmVyKHYudmVyc2lvbiwgYmFzZSkgPiAwICYmIGNvbXBhcmVTZW12ZXIodi52ZXJzaW9uLCB2ZXJzaW9uKSA8PSAwKTtcbiAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKiogV2hldGhlciBgbW9kZWAgYWRtaXRzIGB2ZXJzaW9uYCAodGhlIGltcGxpY2l0IHJhbmdlIGZvciBhbiBpbXBsaWNpdCBpbnN0YWxsKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlQWRtaXRzKG1vZGU6IEluc3RhbGxNb2RlLCB2ZXJzaW9uOiBzdHJpbmcsIHZlcnNpb25zOiByZWFkb25seSBWZXJzaW9uUm93W10pOiBib29sZWFuIHtcbiAgaWYgKG1vZGUua2luZCA9PT0gJ2V4cGxpY2l0JykgcmV0dXJuIGluc3RhbGxBZG1pdHMobW9kZS5pbnN0YWxsLCB2ZXJzaW9uLCB2ZXJzaW9ucyk7XG4gIGNvbnN0IHJhbmdlID0gaW1wbGljaXRJbnN0YWxsUmFuZ2UodmVyc2lvbnMpO1xuICByZXR1cm4gcmFuZ2UgIT09IG51bGwgJiYgc2F0aXNmaWVzVmVyc2lvblNwZWModmVyc2lvbiwgcmFuZ2UpO1xufVxuXG4vKiogSW5wdXQgdG8ge0BsaW5rIHNlbGVjdExpc3RpbmdWZXJzaW9ufS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmVyc2lvbkNob2ljZUlucHV0PFYgZXh0ZW5kcyBQbHVnaW5MaXN0aW5nVmVyc2lvbiA9IFBsdWdpbkxpc3RpbmdWZXJzaW9uPiB7XG4gIHJlZjogc3RyaW5nO1xuICB2ZXJzaW9uczogcmVhZG9ubHkgVltdO1xuICBtb2RlOiBJbnN0YWxsTW9kZTtcbiAgLyoqIFRoZSByZWZlcmVuY2UncyBvd24gdmVyc2lvbiBzcGVjIChgZmlsdGVyLnZlcnNpb25gKS4gKi9cbiAgcmVxdWVzdGVkPzogc3RyaW5nO1xuICBhZHZpc29yaWVzOiByZWFkb25seSBQbHVnaW5BZHZpc29yeVtdO1xuICBwb2xpY3k6IENvbnN1bXB0aW9uUG9saWN5O1xufVxuXG4vKipcbiAqIFBpY2sgdGhlIGxpc3RlZCB2ZXJzaW9uIGEgcmVmZXJlbmNlIHJlc29sdmVzIHRvIChzZWUgdGhlIG1vZHVsZSBkb2MpLCBvclxuICogdGhlIHJlZnVzYWwgdGhhdCBleHBsYWlucyB3aHkgbm9uZSBjYW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3RMaXN0aW5nVmVyc2lvbjxWIGV4dGVuZHMgUGx1Z2luTGlzdGluZ1ZlcnNpb24+KGlucHV0OiBWZXJzaW9uQ2hvaWNlSW5wdXQ8Vj4pOiB7IHZlcnNpb246IFYgfSB8IHsgcmVmdXNhbDogUmVzb2x1dGlvblJlZnVzYWwgfSB7XG4gIGNvbnN0IHsgcmVmLCB2ZXJzaW9ucywgbW9kZSwgcmVxdWVzdGVkLCBhZHZpc29yaWVzLCBwb2xpY3kgfSA9IGlucHV0O1xuICBjb25zdCBleGFjdCA9IHJlcXVlc3RlZCAhPT0gdW5kZWZpbmVkICYmICFpc1ZlcnNpb25SYW5nZShyZXF1ZXN0ZWQpID8gcmVxdWVzdGVkLnRyaW0oKSA6IG51bGw7XG5cbiAgaWYgKGV4YWN0ICE9PSBudWxsKSB7XG4gICAgY29uc3QgdiA9IHZlcnNpb25zLmZpbmQoKHgpID0+IHgudmVyc2lvbiA9PT0gZXhhY3QpO1xuICAgIGlmICghdikgcmV0dXJuIHsgcmVmdXNhbDogeyBjb2RlOiAnTk9UX0ZPVU5EJywgcmVhc29uOiAndmVyc2lvbl9ub3RfZm91bmQnLCBtZXNzYWdlOiBgJHtyZWZ9IGhhcyBubyBwdWJsaXNoZWQgdmVyc2lvbiAke2V4YWN0fS5gIH0gfTtcbiAgICBpZiAodi55YW5rZWRBdCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVmdXNhbDoge1xuICAgICAgICAgIGNvZGU6ICdQTFVHSU5fVU5BVkFJTEFCTEUnLFxuICAgICAgICAgIHJlYXNvbjogJ3lhbmtlZCcsXG4gICAgICAgICAgbWVzc2FnZTogYCR7cmVmfUAke2V4YWN0fSBpcyB5YW5rZWQke3YueWFua1JlYXNvbiA/IGA6ICR7di55YW5rUmVhc29ufWAgOiAnJ30uIE1vdmUgdG8gYSBzdXBwb3J0ZWQgdmVyc2lvbi5gLFxuICAgICAgICAgIGRldGFpbHM6IHsgdmVyc2lvbjogZXhhY3QgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChtb2RlLmtpbmQgPT09ICdleHBsaWNpdCcgJiYgIWluc3RhbGxBZG1pdHMobW9kZS5pbnN0YWxsLCBleGFjdCwgdmVyc2lvbnMpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZWZ1c2FsOiB7XG4gICAgICAgICAgY29kZTogJ1BMVUdJTl9OT1RfSU5TVEFMTEVEJyxcbiAgICAgICAgICByZWFzb246ICd2ZXJzaW9uX291dHNpZGVfaW5zdGFsbCcsXG4gICAgICAgICAgbWVzc2FnZTogYCR7cmVmfUAke2V4YWN0fSBpcyBvdXRzaWRlIHlvdXIgaW5zdGFsbCAoJHttb2RlLmluc3RhbGwudmVyc2lvblBvbGljeX0gZnJvbSAke21vZGUuaW5zdGFsbC5waW5uZWRWZXJzaW9ufSkuIFVwZ3JhZGUgdGhlIGluc3RhbGwgZmlyc3QuYCxcbiAgICAgICAgICBkZXRhaWxzOiB7IHZlcnNpb246IGV4YWN0LCB2ZXJzaW9uUG9saWN5OiBtb2RlLmluc3RhbGwudmVyc2lvblBvbGljeSwgcGlubmVkVmVyc2lvbjogbW9kZS5pbnN0YWxsLnBpbm5lZFZlcnNpb24gfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IGJsb2NraW5nID0gYmxvY2tpbmdBZHZpc29yaWVzKGFkdmlzb3JpZXMsIGV4YWN0LCBwb2xpY3kpO1xuICAgIGlmIChibG9ja2luZy5sZW5ndGgpIHJldHVybiB7IHJlZnVzYWw6IGFkdmlzb3J5UmVmdXNhbChyZWYsIGV4YWN0LCBibG9ja2luZykgfTtcbiAgICByZXR1cm4geyB2ZXJzaW9uOiB2IH07XG4gIH1cblxuICBjb25zdCByZXNvbHZlZEJlZm9yZSA9IG1vZGUua2luZCA9PT0gJ2V4cGxpY2l0JyA/IG1vZGUuaW5zdGFsbC5yZXNvbHZlZFZlcnNpb24gOiBudWxsO1xuICAvLyBUaGUgcmFuZ2UgdGhlIElOU1RBTEwgYWxsb3dzLiBGb3IgdGhlIGltcGxpY2l0IGluc3RhbGwgYW4gZXhwbGljaXQgc3BlYyBvblxuICAvLyB0aGUgcmVmZXJlbmNlIHJlcGxhY2VzIHRoZSBpbXBsaWNpdCByYW5nZSAoaXQgaXMgYSBkZWxpYmVyYXRlIGNob2ljZSkuXG4gIGNvbnN0IGFkbWl0dGVkID0gdmVyc2lvbnMuZmlsdGVyKCh2KSA9PiAhdi55YW5rZWRBdFxuICAgICYmIChtb2RlLmtpbmQgPT09ICdleHBsaWNpdCcgPyBpbnN0YWxsQWRtaXRzKG1vZGUuaW5zdGFsbCwgdi52ZXJzaW9uLCB2ZXJzaW9ucylcbiAgICAgIDogcmVxdWVzdGVkICE9PSB1bmRlZmluZWQgfHwgbW9kZUFkbWl0cyhtb2RlLCB2LnZlcnNpb24sIHZlcnNpb25zKSlcbiAgICAmJiAocmVxdWVzdGVkID09PSB1bmRlZmluZWQgfHwgc2F0aXNmaWVzVmVyc2lvblNwZWModi52ZXJzaW9uLCByZXF1ZXN0ZWQpKVxuICAgICYmICghdi5wYXVzZWRBdCB8fCB2LnZlcnNpb24gPT09IHJlc29sdmVkQmVmb3JlKSk7XG4gIGNvbnN0IGFsbG93ZWQgPSBhZG1pdHRlZC5maWx0ZXIoKHYpID0+IGJsb2NraW5nQWR2aXNvcmllcyhhZHZpc29yaWVzLCB2LnZlcnNpb24sIHBvbGljeSkubGVuZ3RoID09PSAwKTtcbiAgLy8gUmFuZ2VzIG9ubHkgYWRtaXQgcHJlcmVsZWFzZXMgdGhleSBuYW1lIChucG0gc2VtYW50aWNzKSwgc28gdGhlIGhpZ2hlc3RcbiAgLy8gYWRtaXR0ZWQgdmVyc2lvbiBpcyB0aGUgYW5zd2VyLlxuICBjb25zdCBiZXN0ID0gaGlnaGVzdChhbGxvd2VkLm1hcCgodikgPT4gdi52ZXJzaW9uKSk7XG4gIGlmIChiZXN0KSByZXR1cm4geyB2ZXJzaW9uOiBhbGxvd2VkLmZpbmQoKHYpID0+IHYudmVyc2lvbiA9PT0gYmVzdCkhIH07XG5cbiAgaWYgKGFkbWl0dGVkLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBuZXdlc3QgPSBoaWdoZXN0KGFkbWl0dGVkLm1hcCgodikgPT4gdi52ZXJzaW9uKSkhO1xuICAgIHJldHVybiB7IHJlZnVzYWw6IGFkdmlzb3J5UmVmdXNhbChyZWYsIG5ld2VzdCwgYmxvY2tpbmdBZHZpc29yaWVzKGFkdmlzb3JpZXMsIG5ld2VzdCwgcG9saWN5KSkgfTtcbiAgfVxuICBpZiAobW9kZS5raW5kID09PSAnZXhwbGljaXQnICYmIHJlcXVlc3RlZCAhPT0gdW5kZWZpbmVkXG4gICAgJiYgdmVyc2lvbnMuc29tZSgodikgPT4gIXYueWFua2VkQXQgJiYgc2F0aXNmaWVzVmVyc2lvblNwZWModi52ZXJzaW9uLCByZXF1ZXN0ZWQpKSkge1xuICAgIHJldHVybiB7XG4gICAgICByZWZ1c2FsOiB7XG4gICAgICAgIGNvZGU6ICdQTFVHSU5fTk9UX0lOU1RBTExFRCcsXG4gICAgICAgIHJlYXNvbjogJ3ZlcnNpb25fb3V0c2lkZV9pbnN0YWxsJyxcbiAgICAgICAgbWVzc2FnZTogYE5vIHZlcnNpb24gb2YgJHtyZWZ9IG1hdGNoaW5nICR7cmVxdWVzdGVkfSBpcyBpbnNpZGUgeW91ciBpbnN0YWxsICgke21vZGUuaW5zdGFsbC52ZXJzaW9uUG9saWN5fSBmcm9tICR7bW9kZS5pbnN0YWxsLnBpbm5lZFZlcnNpb259KS4gVXBncmFkZSB0aGUgaW5zdGFsbCBmaXJzdC5gLFxuICAgICAgICBkZXRhaWxzOiB7IHJlcXVlc3RlZCwgdmVyc2lvblBvbGljeTogbW9kZS5pbnN0YWxsLnZlcnNpb25Qb2xpY3ksIHBpbm5lZFZlcnNpb246IG1vZGUuaW5zdGFsbC5waW5uZWRWZXJzaW9uIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICByZWZ1c2FsOiB7XG4gICAgICBjb2RlOiAnTk9UX0ZPVU5EJyxcbiAgICAgIHJlYXNvbjogJ25vX21hdGNoaW5nX3ZlcnNpb24nLFxuICAgICAgbWVzc2FnZTogYE5vIHJlc29sdmFibGUgdmVyc2lvbiBvZiAke3JlZn0ke3JlcXVlc3RlZCA/IGAgbWF0Y2hlcyAke3JlcXVlc3RlZH1gIDogJyd9LmAsXG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIFRoZSBoaWdoZXN0IG9mIGB2ZXJzaW9uc2AgYnkgc2VtdmVyIChwcmVyZWxlYXNlcyBpbmNsdWRlZCkuICovXG5mdW5jdGlvbiBoaWdoZXN0KHZlcnNpb25zOiByZWFkb25seSBzdHJpbmdbXSk6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gdmVyc2lvbnMucmVkdWNlPHN0cmluZyB8IG51bGw+KChiZXN0LCB2KSA9PiAoYmVzdCA9PT0gbnVsbCB8fCBjb21wYXJlU2VtdmVyKHYsIGJlc3QpID4gMCA/IHYgOiBiZXN0KSwgbnVsbCk7XG59XG5cbmZ1bmN0aW9uIGFkdmlzb3J5UmVmdXNhbChyZWY6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBibG9ja2luZzogUmVhZG9ubHlBcnJheTxQaWNrPFBsdWdpbkFkdmlzb3J5LCAnaWQnIHwgJ3NldmVyaXR5JyB8ICdmaXhlZFZlcnNpb24nIHwgJ3N1bW1hcnknPj4pOiBSZXNvbHV0aW9uUmVmdXNhbCB7XG4gIGNvbnN0IGZpeGVkID0gYmxvY2tpbmcubWFwKChhKSA9PiBhLmZpeGVkVmVyc2lvbikuZmlsdGVyKCh2KTogdiBpcyBzdHJpbmcgPT4gISF2KTtcbiAgcmV0dXJuIHtcbiAgICBjb2RlOiAnUExVR0lOX0JMT0NLRURfQllfUE9MSUNZJyxcbiAgICByZWFzb246ICdhZHZpc29yeScsXG4gICAgbWVzc2FnZTogYCR7cmVmfUAke3ZlcnNpb259IGlzIGJsb2NrZWQgYnkgeW91ciBvcmdhbml6YXRpb24ncyBhZHZpc29yeSBwb2xpY3k6ICR7YmxvY2tpbmcubWFwKChhKSA9PiBgJHthLnNldmVyaXR5fSDigJQgJHthLnN1bW1hcnl9YCkuam9pbignOyAnKX0uYFxuICAgICAgKyAoZml4ZWQubGVuZ3RoID8gYCBGaXhlZCBpbiAke2ZpeGVkLmpvaW4oJywgJyl9LmAgOiAnJyksXG4gICAgZGV0YWlsczogeyB2ZXJzaW9uLCBhZHZpc29yaWVzOiBibG9ja2luZy5tYXAoKGEpID0+IGEuaWQpLCAuLi4oZml4ZWQubGVuZ3RoID8geyBmaXhlZFZlcnNpb25zOiBmaXhlZCB9IDoge30pIH0sXG4gIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUaGUgb3JnJ3MgaW5zdGFsbCBzdGF0ZSBmb3Igb25lIGxpc3Rpbmdcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBUaGUgb3JnIChhbmQsIGZvciBhIHRlYW0sIGl0cyByb290IG9yZykgYSByZXNvbHV0aW9uIHJ1bnMgZm9yLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHV0aW9uU2NvcGUge1xuICBvcmdJZDogc3RyaW5nO1xuICAvKiogVGhlIHJvb3Qgb3JnIHdoZW4gdGhlIGNhbGxlciBpcyBhIHRlYW0uICovXG4gIHJvb3RPcmdJZD86IHN0cmluZztcbn1cblxuLyoqIFRoZSBvcmcgaWRzIHdob3NlIGluc3RhbGxzIGFuZCBwb2xpY2llcyBhcHBseSwgb3duIGZpcnN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjb3BlT3JnSWRzKHNjb3BlOiBSZXNvbHV0aW9uU2NvcGUpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG93biA9IHNjb3BlLm9yZ0lkLnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IHJvb3QgPSBzY29wZS5yb290T3JnSWQ/LnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiByb290ICYmIHJvb3QgIT09IG93biA/IFtvd24sIHJvb3RdIDogW293bl07XG59XG5cbi8qKlxuICogSG93IHRoZSBvcmcgcmVhY2hlcyBgbGlzdGluZ2Ag4oCUIG9yIHRoZSByZWZ1c2FsLiBBbiBBQ1RJVkUgb3duLW9yZyByb3cgd2lucyxcbiAqIHRoZW4gdGhlIHJvb3Qgb3JnJ3MgKGEgdGVhbSBpbmhlcml0cyBpdCk7IGZhaWxpbmcgYm90aCwgdGhlIGltcGxpY2l0XG4gKiBPZmZpY2lhbCBpbnN0YWxsICh1bmxlc3MgdGhlIHBvbGljeSBpcyBgZXhwbGljaXRgKTsgb3RoZXJ3aXNlIHRoZSBvcmcncyBvd25cbiAqIHBlbmRpbmcgLyBkZW5pZWQgcm93IGV4cGxhaW5zIHRoZSByZWZ1c2FsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zdGFsbE1vZGVGb3IoXG4gIHB1Ymxpc2hlcjogUGljazxQdWJsaXNoZXIsICdoYW5kbGUnPixcbiAgbGlzdGluZzogUGljazxQbHVnaW5MaXN0aW5nLCAnaWQnIHwgJ25hbWUnPixcbiAgaW5zdGFsbHM6IHJlYWRvbmx5IFBsdWdpbkluc3RhbGxbXSxcbiAgcG9saWN5OiBDb25zdW1wdGlvblBvbGljeSxcbiAgc2NvcGU6IFJlc29sdXRpb25TY29wZSxcbik6IEluc3RhbGxNb2RlIHwgUmVzb2x1dGlvblJlZnVzYWwge1xuICBjb25zdCBbb3duLCByb290XSA9IHNjb3BlT3JnSWRzKHNjb3BlKTtcbiAgY29uc3QgZm9yTGlzdGluZyA9IGluc3RhbGxzLmZpbHRlcigoaSkgPT4gaS5saXN0aW5nSWQgPT09IGxpc3RpbmcuaWQpO1xuICBjb25zdCBvd25Sb3cgPSBmb3JMaXN0aW5nLmZpbmQoKGkpID0+IGkub3JnSWQudG9Mb3dlckNhc2UoKSA9PT0gb3duKTtcbiAgY29uc3Qgcm9vdFJvdyA9IHJvb3QgPyBmb3JMaXN0aW5nLmZpbmQoKGkpID0+IGkub3JnSWQudG9Mb3dlckNhc2UoKSA9PT0gcm9vdCkgOiB1bmRlZmluZWQ7XG4gIGlmIChvd25Sb3c/LnN0YXR1cyA9PT0gJ2FjdGl2ZScpIHJldHVybiB7IGtpbmQ6ICdleHBsaWNpdCcsIGluc3RhbGw6IG93blJvdywgaW5oZXJpdGVkOiBmYWxzZSB9O1xuICBpZiAocm9vdFJvdz8uc3RhdHVzID09PSAnYWN0aXZlJykgcmV0dXJuIHsga2luZDogJ2V4cGxpY2l0JywgaW5zdGFsbDogcm9vdFJvdywgaW5oZXJpdGVkOiB0cnVlIH07XG4gIGNvbnN0IHJlZiA9IGAke3B1Ymxpc2hlci5oYW5kbGV9LyR7bGlzdGluZy5uYW1lfWA7XG4gIGlmIChwdWJsaXNoZXIuaGFuZGxlID09PSBPRkZJQ0lBTF9QVUJMSVNIRVJfSEFORExFKSB7XG4gICAgaWYgKHBvbGljeS5vZmZpY2lhbEluc3RhbGxzID09PSAnaW1wbGljaXQnKSByZXR1cm4geyBraW5kOiAnaW1wbGljaXQnIH07XG4gICAgaWYgKCFvd25Sb3cpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvZGU6ICdQTFVHSU5fTk9UX0lOU1RBTExFRCcsXG4gICAgICAgIHJlYXNvbjogJ29mZmljaWFsX2V4cGxpY2l0JyxcbiAgICAgICAgbWVzc2FnZTogYFlvdXIgb3JnYW5pemF0aW9uIGluc3RhbGxzIE9mZmljaWFsIHBsdWdpbnMgZXhwbGljaXRseTsgaW5zdGFsbCAke3JlZn0gZmlyc3QuYCxcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIGlmIChvd25Sb3c/LnN0YXR1cyA9PT0gJ3BlbmRpbmdfYXBwcm92YWwnKSB7XG4gICAgcmV0dXJuIHsgY29kZTogJ1BMVUdJTl9OT1RfSU5TVEFMTEVEJywgcmVhc29uOiAncGVuZGluZ19hcHByb3ZhbCcsIG1lc3NhZ2U6IGBUaGUgaW5zdGFsbCBvZiAke3JlZn0gaXMgd2FpdGluZyBmb3IgYXBwcm92YWwuYCB9O1xuICB9XG4gIGlmIChvd25Sb3c/LnN0YXR1cyA9PT0gJ2RlbmllZCcpIHtcbiAgICByZXR1cm4geyBjb2RlOiAnUExVR0lOX05PVF9JTlNUQUxMRUQnLCByZWFzb246ICdkZW5pZWQnLCBtZXNzYWdlOiBgVGhlIGluc3RhbGwgb2YgJHtyZWZ9IHdhcyBkZW5pZWQuYCB9O1xuICB9XG4gIHJldHVybiB7IGNvZGU6ICdQTFVHSU5fTk9UX0lOU1RBTExFRCcsIHJlYXNvbjogJ25vdF9pbnN0YWxsZWQnLCBtZXNzYWdlOiBgJHtyZWZ9IGlzIG5vdCBpbnN0YWxsZWQgaW4geW91ciBvcmdhbml6YXRpb24uYCB9O1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRGF0YSBzb3VyY2Vcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBUaGUgcm93cyB0aGUgcmVzb2x2ZXIgcmVhZHMuIEltcGxlbWVudGF0aW9ucyBtdXN0IHJ1biB3aXRoIGEgc2NvcGUgdGhhdCBjYW5cbiAqICByZWFkIHRoZSBlY29zeXN0ZW0gdGFibGVzIGFuZCB0aGUgb3JnJ3MgKGFuZCByb290IG9yZydzKSBpbnN0YWxsIHJvd3MuICovXG5leHBvcnQgaW50ZXJmYWNlIExpc3RpbmdEYXRhU291cmNlIHtcbiAgcHVibGlzaGVyQnlIYW5kbGUoaGFuZGxlOiBzdHJpbmcpOiBQcm9taXNlPFB1Ymxpc2hlciB8IG51bGw+O1xuICBwdWJsaXNoZXJzQnlJZHMoaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8UHVibGlzaGVyW10+O1xuICBsaXN0aW5nQnlOYW1lKHB1Ymxpc2hlcklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8UGx1Z2luTGlzdGluZyB8IG51bGw+O1xuICAvKiogTGlzdGVkIC8gdW5tYWludGFpbmVkIGxpc3RpbmdzIChvcHRpb25hbGx5IG9ubHkgdGhlc2UgaWRzIG9yIG5hbWVzKS4gKi9cbiAgbGl2ZUxpc3RpbmdzKGZpbHRlcj86IHsgaWRzPzogc3RyaW5nW107IG5hbWVzPzogc3RyaW5nW10gfSk6IFByb21pc2U8UGx1Z2luTGlzdGluZ1tdPjtcbiAgdmVyc2lvbnNGb3JMaXN0aW5ncyhsaXN0aW5nSWRzOiBzdHJpbmdbXSk6IFByb21pc2U8UGx1Z2luTGlzdGluZ1ZlcnNpb25bXT47XG4gIC8qKiBQVUJMSVNIRUQgYWR2aXNvcmllcy4gKi9cbiAgYWR2aXNvcmllc0Zvckxpc3RpbmdzKGxpc3RpbmdJZHM6IHN0cmluZ1tdKTogUHJvbWlzZTxQbHVnaW5BZHZpc29yeVtdPjtcbiAgaW5zdGFsbHNGb3JPcmdzKG9yZ0lkczogc3RyaW5nW10pOiBQcm9taXNlPFBsdWdpbkluc3RhbGxbXT47XG4gIHBvbGljaWVzRm9yT3JncyhvcmdJZHM6IHN0cmluZ1tdKTogUHJvbWlzZTxQbHVnaW5JbnN0YWxsUG9saWN5W10+O1xufVxuXG4vKipcbiAqIEEge0BsaW5rIExpc3RpbmdEYXRhU291cmNlfSBvdmVyIGEgZHJpenpsZSB0cmFuc2FjdGlvbi4gVGhlIGNhbGxlciBvd25zIHRoZVxuICogdHJhbnNhY3Rpb24ncyBzY29wZTogaXQgbXVzdCBiZSBhYmxlIHRvIHJlYWQgdGhlIGVjb3N5c3RlbSB0YWJsZXMgKGFwcC1yb2xlXG4gKiBSTFMpIGFuZCB0aGUgaW5zdGFsbCByb3dzIG9mIHRoZSBvcmcgQU5EIGl0cyByb290IG9yZyAoYSB0ZWFtJ3MgcmVhZHMgb2YgaXRzXG4gKiByb290J3Mgcm93cyBuZWVkIGFuIGVsZXZhdGVkIHNjb3BlLCBsaWtlIHBhcmVudC1vcmcgcGx1Z2luIHJlYWRzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXp6bGVMaXN0aW5nU291cmNlKHR4OiBDcnVkVHgpOiBMaXN0aW5nRGF0YVNvdXJjZSB7XG4gIGNvbnN0IGRiID0gdHg7XG4gIGNvbnN0IFAgPSBzY2hlbWEucHVibGlzaGVyO1xuICBjb25zdCBMID0gc2NoZW1hLnBsdWdpbkxpc3Rpbmc7XG4gIGNvbnN0IFYgPSBzY2hlbWEucGx1Z2luTGlzdGluZ1ZlcnNpb247XG4gIGNvbnN0IEEgPSBzY2hlbWEucGx1Z2luQWR2aXNvcnk7XG4gIGNvbnN0IEkgPSBzY2hlbWEucGx1Z2luSW5zdGFsbDtcbiAgY29uc3QgSVAgPSBzY2hlbWEucGx1Z2luSW5zdGFsbFBvbGljeTtcbiAgcmV0dXJuIHtcbiAgICBwdWJsaXNoZXJCeUhhbmRsZTogYXN5bmMgKGhhbmRsZSkgPT4gKChhd2FpdCBkYi5zZWxlY3QoKS5mcm9tKFApLndoZXJlKGVxKFAuaGFuZGxlLCBoYW5kbGUpKSkgYXMgUHVibGlzaGVyW10pWzBdID8/IG51bGwsXG4gICAgcHVibGlzaGVyc0J5SWRzOiBhc3luYyAoaWRzKSA9PiAoaWRzLmxlbmd0aCA/IGRiLnNlbGVjdCgpLmZyb20oUCkud2hlcmUoaW5BcnJheShQLmlkLCBpZHMpKSA6IFtdKSxcbiAgICBsaXN0aW5nQnlOYW1lOiBhc3luYyAocHVibGlzaGVySWQsIG5hbWUpID0+XG4gICAgICAoKGF3YWl0IGRiLnNlbGVjdCgpLmZyb20oTCkud2hlcmUoYW5kKGVxKEwucHVibGlzaGVySWQsIHB1Ymxpc2hlcklkKSwgZXEoTC5uYW1lLCBuYW1lKSkpKSBhcyBQbHVnaW5MaXN0aW5nW10pWzBdID8/IG51bGwsXG4gICAgbGl2ZUxpc3RpbmdzOiBhc3luYyAoZmlsdGVyID0ge30pID0+IHtcbiAgICAgIGlmIChmaWx0ZXIuaWRzICYmIGZpbHRlci5pZHMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gICAgICBpZiAoZmlsdGVyLm5hbWVzICYmIGZpbHRlci5uYW1lcy5sZW5ndGggPT09IDApIHJldHVybiBbXTtcbiAgICAgIHJldHVybiBkYi5zZWxlY3QoKS5mcm9tKEwpLndoZXJlKGFuZChcbiAgICAgICAgaW5BcnJheShMLnN0YXRlLCBbJ2xpc3RlZCcsICd1bm1haW50YWluZWQnXSksXG4gICAgICAgIC4uLihmaWx0ZXIuaWRzID8gW2luQXJyYXkoTC5pZCwgZmlsdGVyLmlkcyldIDogW10pLFxuICAgICAgICAuLi4oZmlsdGVyLm5hbWVzID8gW2luQXJyYXkoTC5uYW1lLCBmaWx0ZXIubmFtZXMpXSA6IFtdKSxcbiAgICAgICkpO1xuICAgIH0sXG4gICAgdmVyc2lvbnNGb3JMaXN0aW5nczogYXN5bmMgKGlkcykgPT4gKGlkcy5sZW5ndGggPyBkYi5zZWxlY3QoKS5mcm9tKFYpLndoZXJlKGluQXJyYXkoVi5saXN0aW5nSWQsIGlkcykpIDogW10pLFxuICAgIGFkdmlzb3JpZXNGb3JMaXN0aW5nczogYXN5bmMgKGlkcykgPT4gKGlkcy5sZW5ndGggPyBkYi5zZWxlY3QoKS5mcm9tKEEpLndoZXJlKGFuZChpbkFycmF5KEEubGlzdGluZ0lkLCBpZHMpLCBlcShBLnN0YXRlLCAncHVibGlzaGVkJykpKSA6IFtdKSxcbiAgICBpbnN0YWxsc0Zvck9yZ3M6IGFzeW5jIChvcmdJZHMpID0+IChvcmdJZHMubGVuZ3RoID8gZGIuc2VsZWN0KCkuZnJvbShJKS53aGVyZShpbkFycmF5KEkub3JnSWQsIG9yZ0lkcykpIDogW10pLFxuICAgIHBvbGljaWVzRm9yT3JnczogYXN5bmMgKG9yZ0lkcykgPT4gKG9yZ0lkcy5sZW5ndGggPyBkYi5zZWxlY3QoKS5mcm9tKElQKS53aGVyZShpbkFycmF5KElQLm9yZ0lkLCBvcmdJZHMpKSA6IFtdKSxcbiAgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlc29sdXRpb25cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBBIHBsdWdpbiByZWZlcmVuY2UgYXMgdGhlIHJlc29sdmVyIHJlYWRzIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaXN0aW5nUmVmZXJlbmNlIHtcbiAgLyoqIFB1Ymxpc2hlciBoYW5kbGU7IGFic2VudCA9IHRoZSBPZmZpY2lhbCBsaXN0aW5nICh0aGUgdW5xdWFsaWZpZWQgZmFsbGJhY2spLiAqL1xuICBwdWJsaXNoZXI/OiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgLyoqIFRoZSByZWZlcmVuY2UncyBgZmlsdGVyLnZlcnNpb25gLiAqL1xuICB2ZXJzaW9uPzogc3RyaW5nO1xufVxuXG4vKiogQSByZWZlcmVuY2UgdGhhdCByZXNvbHZlZCB0byBhIGxpc3RlZCB2ZXJzaW9uLiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaXN0aW5nUmVzb2x2ZWQge1xuICBvazogdHJ1ZTtcbiAgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG4gIGxpc3Rpbmc6IFBsdWdpbkxpc3Rpbmc7XG4gIHZlcnNpb246IFBsdWdpbkxpc3RpbmdWZXJzaW9uO1xuICBtb2RlOiBJbnN0YWxsTW9kZTtcbiAgcG9saWN5OiBDb25zdW1wdGlvblBvbGljeTtcbiAgLyoqIFRoZSBzcGVjIGRlY2xhcmVzIHNlY3JldHMgdGhlIHBvbGljeSB3aXRoaG9sZHMgZnJvbSB0aGlzIHRpZXIuICovXG4gIHNlY3JldHNXaXRoaGVsZDogYm9vbGVhbjtcbiAgd2FybmluZ3M6IFJlc29sdXRpb25XYXJuaW5nW107XG59XG5cbi8qKiBBIHJlZmVyZW5jZSB0aGF0IG5hbWVkIGEgbGlzdGluZyBidXQgY2FuJ3QgcmVzb2x2ZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdGluZ1JlZnVzZWQge1xuICBvazogZmFsc2U7XG4gIHJlZnVzYWw6IFJlc29sdXRpb25SZWZ1c2FsO1xuICBwdWJsaXNoZXI/OiBQdWJsaXNoZXI7XG4gIGxpc3Rpbmc/OiBQbHVnaW5MaXN0aW5nO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYHJlZmAgdG8gYSBsaXN0ZWQgdmVyc2lvbiBmb3IgYHNjb3BlYCwgb3IgcmVmdXNlLiBOdWxsIHdoZW4gdGhlXG4gKiBsaXN0aW5nIGRvZXNuJ3QgZXhpc3QgYXQgYWxsIChhbiB1bnF1YWxpZmllZCByZWZlcmVuY2UgdGhlbiBzaW1wbHkgaGFzIG5vXG4gKiBPZmZpY2lhbCBmYWxsYmFjaykuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlTGlzdGluZ1JlZmVyZW5jZShcbiAgc291cmNlOiBMaXN0aW5nRGF0YVNvdXJjZSxcbiAgcmVmOiBMaXN0aW5nUmVmZXJlbmNlLFxuICBzY29wZTogUmVzb2x1dGlvblNjb3BlLFxuKTogUHJvbWlzZTxMaXN0aW5nUmVzb2x2ZWQgfCBMaXN0aW5nUmVmdXNlZCB8IG51bGw+IHtcbiAgY29uc3QgaGFuZGxlID0gcmVmLnB1Ymxpc2hlciA/PyBPRkZJQ0lBTF9QVUJMSVNIRVJfSEFORExFO1xuICBjb25zdCBwdWJsaXNoZXIgPSBhd2FpdCBzb3VyY2UucHVibGlzaGVyQnlIYW5kbGUoaGFuZGxlKTtcbiAgaWYgKCFwdWJsaXNoZXIpIHJldHVybiBudWxsO1xuICBjb25zdCBsaXN0aW5nID0gYXdhaXQgc291cmNlLmxpc3RpbmdCeU5hbWUocHVibGlzaGVyLmlkLCByZWYubmFtZSk7XG4gIGlmICghbGlzdGluZykgcmV0dXJuIG51bGw7XG5cbiAgY29uc3Qgb3JnSWRzID0gc2NvcGVPcmdJZHMoc2NvcGUpO1xuICBjb25zdCBbcG9saWNpZXMsIGluc3RhbGxzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtzb3VyY2UucG9saWNpZXNGb3JPcmdzKG9yZ0lkcyksIHNvdXJjZS5pbnN0YWxsc0Zvck9yZ3Mob3JnSWRzKV0pO1xuICBjb25zdCBwb2xpY3kgPSBlZmZlY3RpdmVDb25zdW1wdGlvblBvbGljeShwb2xpY2llcywgb3JnSWRzWzBdISwgb3JnSWRzWzFdKTtcbiAgY29uc3QgYmxvY2sgPSBsaXN0aW5nQmxvY2socG9saWN5LCBwdWJsaXNoZXIsIGxpc3RpbmcpO1xuICBpZiAoYmxvY2spIHJldHVybiB7IG9rOiBmYWxzZSwgcmVmdXNhbDogYmxvY2tSZWZ1c2FsKGJsb2NrKSwgcHVibGlzaGVyLCBsaXN0aW5nIH07XG5cbiAgY29uc3QgbW9kZSA9IGluc3RhbGxNb2RlRm9yKHB1Ymxpc2hlciwgbGlzdGluZywgaW5zdGFsbHMsIHBvbGljeSwgc2NvcGUpO1xuICBpZiAoJ2NvZGUnIGluIG1vZGUpIHJldHVybiB7IG9rOiBmYWxzZSwgcmVmdXNhbDogbW9kZSwgcHVibGlzaGVyLCBsaXN0aW5nIH07XG5cbiAgY29uc3QgW3ZlcnNpb25zLCBhZHZpc29yaWVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICBzb3VyY2UudmVyc2lvbnNGb3JMaXN0aW5ncyhbbGlzdGluZy5pZF0pLFxuICAgIHNvdXJjZS5hZHZpc29yaWVzRm9yTGlzdGluZ3MoW2xpc3RpbmcuaWRdKSxcbiAgXSk7XG4gIGNvbnN0IHJlZl8gPSBgJHtwdWJsaXNoZXIuaGFuZGxlfS8ke2xpc3RpbmcubmFtZX1gO1xuICBjb25zdCBjaG9pY2UgPSBzZWxlY3RMaXN0aW5nVmVyc2lvbih7IHJlZjogcmVmXywgdmVyc2lvbnMsIG1vZGUsIHJlcXVlc3RlZDogcmVmLnZlcnNpb24sIGFkdmlzb3JpZXMsIHBvbGljeSB9KTtcbiAgaWYgKCdyZWZ1c2FsJyBpbiBjaG9pY2UpIHJldHVybiB7IG9rOiBmYWxzZSwgcmVmdXNhbDogY2hvaWNlLnJlZnVzYWwsIHB1Ymxpc2hlciwgbGlzdGluZyB9O1xuXG4gIGNvbnN0IHZlcnNpb24gPSBjaG9pY2UudmVyc2lvbjtcbiAgY29uc3QgeyB3YXJuaW5ncywgc2VjcmV0c1dpdGhoZWxkIH0gPSBsaXN0ZWRWZXJzaW9uV2FybmluZ3MoeyBwdWJsaXNoZXIsIGxpc3RpbmcsIHZlcnNpb24sIGFkdmlzb3JpZXMsIHBvbGljeSB9KTtcbiAgcmV0dXJuIHsgb2s6IHRydWUsIHB1Ymxpc2hlciwgbGlzdGluZywgdmVyc2lvbiwgbW9kZSwgcG9saWN5LCBzZWNyZXRzV2l0aGhlbGQsIHdhcm5pbmdzIH07XG59XG5cbi8qKlxuICogVGhlIG5vbi1mYXRhbCBub3RlcyBhIHJlc29sdmVkIGxpc3RlZCB2ZXJzaW9uIGNhcnJpZXMgKGxvb2t1cCBhbnN3ZXJzLFxuICogc3ludGggcHJpbnRzIHRoZW0sIHRoZSBpbnN0YWxscyB2aWV3IHNob3dzIHRoZW0pOiBhbiB1bm1haW50YWluZWQgbGlzdGluZywgYVxuICogZGVwcmVjYXRlZCB2ZXJzaW9uLCBhIFBVQkxJU0hFRCBhZHZpc29yeSBjb3ZlcmluZyB0aGUgdmVyc2lvbiB0aGF0IHRoZSBvcmcnc1xuICogYGJsb2NrT25BZHZpc29yeWAgZG9lc24ndCBibG9jayAoYSBibG9ja2luZyBvbmUgcmVmdXNlcyByZXNvbHV0aW9uIGluc3RlYWQpLFxuICogYW5kIHdpdGhoZWxkIHNlY3JldHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZWRWZXJzaW9uV2FybmluZ3MoaW5wdXQ6IHtcbiAgcHVibGlzaGVyOiBQaWNrPFB1Ymxpc2hlciwgJ2hhbmRsZScgfCAndGllcic+O1xuICBsaXN0aW5nOiBQaWNrPFBsdWdpbkxpc3RpbmcsICduYW1lJyB8ICdzdGF0ZSc+O1xuICB2ZXJzaW9uOiBQaWNrPFBsdWdpbkxpc3RpbmdWZXJzaW9uLCAndmVyc2lvbicgfCAnZGVwcmVjYXRlZEF0JyB8ICdkZXByZWNhdGlvbk1lc3NhZ2UnIHwgJ3NwZWNTbmFwc2hvdCc+O1xuICBhZHZpc29yaWVzOiByZWFkb25seSBQaWNrPFBsdWdpbkFkdmlzb3J5LCAnc2V2ZXJpdHknIHwgJ3N0YXRlJyB8ICdhZmZlY3RlZFJhbmdlJyB8ICdmaXhlZFZlcnNpb24nIHwgJ3N1bW1hcnknPltdO1xuICBwb2xpY3k6IFBpY2s8Q29uc3VtcHRpb25Qb2xpY3ksICdzZWNyZXRzQWxsb3dlZFRpZXJzJz47XG59KTogeyB3YXJuaW5nczogUmVzb2x1dGlvbldhcm5pbmdbXTsgc2VjcmV0c1dpdGhoZWxkOiBib29sZWFuIH0ge1xuICBjb25zdCB7IHB1Ymxpc2hlciwgbGlzdGluZywgdmVyc2lvbiwgYWR2aXNvcmllcywgcG9saWN5IH0gPSBpbnB1dDtcbiAgY29uc3QgcmVmID0gYCR7cHVibGlzaGVyLmhhbmRsZX0vJHtsaXN0aW5nLm5hbWV9YDtcbiAgY29uc3QgZGVjbGFyZXNTZWNyZXRzID0gKHZlcnNpb24uc3BlY1NuYXBzaG90Py5zZWNyZXRzID8/IFtdKS5sZW5ndGggPiAwO1xuICBjb25zdCBzZWNyZXRzV2l0aGhlbGQgPSBkZWNsYXJlc1NlY3JldHMgJiYgIXBvbGljeS5zZWNyZXRzQWxsb3dlZFRpZXJzLmluY2x1ZGVzKHB1Ymxpc2hlci50aWVyKTtcbiAgY29uc3Qgd2FybmluZ3M6IFJlc29sdXRpb25XYXJuaW5nW10gPSBbXTtcbiAgaWYgKGxpc3Rpbmcuc3RhdGUgPT09ICd1bm1haW50YWluZWQnKSB7XG4gICAgd2FybmluZ3MucHVzaCh7IGNvZGU6ICdMSVNUSU5HX1VOTUFJTlRBSU5FRCcsIG1lc3NhZ2U6IGAke3JlZn0gaXMgdW5tYWludGFpbmVkOiBpdCByZWNlaXZlcyBubyB1cGRhdGVzLiBQbGFuIGEgcmVwbGFjZW1lbnQuYCB9KTtcbiAgfVxuICBpZiAodmVyc2lvbi5kZXByZWNhdGVkQXQpIHtcbiAgICB3YXJuaW5ncy5wdXNoKHsgY29kZTogJ1BMVUdJTl9ERVBSRUNBVEVEJywgbWVzc2FnZTogYCR7cmVmfUAke3ZlcnNpb24udmVyc2lvbn0gaXMgZGVwcmVjYXRlZCR7dmVyc2lvbi5kZXByZWNhdGlvbk1lc3NhZ2UgPyBgOiAke3ZlcnNpb24uZGVwcmVjYXRpb25NZXNzYWdlfWAgOiAnJ30uYCB9KTtcbiAgfVxuICBmb3IgKGNvbnN0IGEgb2YgYWR2aXNvcmllc0NvdmVyaW5nKGFkdmlzb3JpZXMsIHZlcnNpb24udmVyc2lvbikpIHtcbiAgICB3YXJuaW5ncy5wdXNoKHtcbiAgICAgIGNvZGU6ICdQTFVHSU5fQURWSVNPUlknLFxuICAgICAgbWVzc2FnZTogYCR7cmVmfUAke3ZlcnNpb24udmVyc2lvbn0gaXMgYWZmZWN0ZWQgYnkgYSAke2Euc2V2ZXJpdHl9IHNlY3VyaXR5IGFkdmlzb3J5OiAke2Euc3VtbWFyeX1gXG4gICAgICAgICsgYCR7YS5maXhlZFZlcnNpb24gPyBgIEZpeGVkIGluICR7YS5maXhlZFZlcnNpb259LmAgOiAnJ31gLFxuICAgIH0pO1xuICB9XG4gIGlmIChzZWNyZXRzV2l0aGhlbGQpIHtcbiAgICB3YXJuaW5ncy5wdXNoKHsgY29kZTogJ1BMVUdJTl9TRUNSRVRTX1dJVEhIRUxEJywgbWVzc2FnZTogYCR7cmVmfSBpcyBhICR7cHVibGlzaGVyLnRpZXJ9IHBsdWdpbjsgeW91ciBvcmdhbml6YXRpb24ncyBwb2xpY3kgZ2l2ZXMgaXQgbm8gc2VjcmV0cywgc28gaXRzIGRlY2xhcmVkIHNlY3JldHMgYXJlIG5vdCBpbmplY3RlZC5gIH0pO1xuICB9XG4gIHJldHVybiB7IHdhcm5pbmdzLCBzZWNyZXRzV2l0aGhlbGQgfTtcbn1cblxuLyoqXG4gKiBUaGUgcGx1Z2luIHJlY29yZCBhIHJlc29sdmVkIGxpc3RpbmcgdmVyc2lvbiBydW5zIGFzIOKAlCB0aGUgc2hhcGUgc3ludGggYW5kXG4gKiB0aGUgY29udHJhY3QgY2hlY2sgcmVhZCAoYSBgcGx1Z2luc2Agcm93J3MgcnVuIGZpZWxkcyksIGJ1aWx0IGZyb20gdGhlXG4gKiB2ZXJzaW9uJ3MgZnJvemVuIHNwZWMgc25hcHNob3QuIGBpZGAgaXMgdGhlIExJU1RJTkcgVkVSU0lPTidzIGlkICh0aGUgc3RlcFxuICogbWFuaWZlc3QgcmVzb2x2ZXMgaXQgYmFjayksIGBpbWFnZVJlcG9zaXRvcnlgIGl0cyBgcHVibGljLypgIGNvcHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZWRQbHVnaW5SZWNvcmQocmVzOiBMaXN0aW5nUmVzb2x2ZWQpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGNvbnN0IHsgcHVibGlzaGVyLCBsaXN0aW5nLCB2ZXJzaW9uLCBtb2RlIH0gPSByZXM7XG4gIGNvbnN0IHMgPSAodmVyc2lvbi5zcGVjU25hcHNob3QgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb25zdCBhcnIgPSA8VD4odjogdW5rbm93bik6IFRbXSA9PiAoQXJyYXkuaXNBcnJheSh2KSA/IHYgYXMgVFtdIDogW10pO1xuICBjb25zdCBvYmogPSAodjogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+ICh2ICYmIHR5cGVvZiB2ID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheSh2KSA/IHYgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gOiB7fSk7XG4gIHJldHVybiB7XG4gICAgaWQ6IHZlcnNpb24uaWQsXG4gICAgc291cmNlOiAnbGlzdGluZycsXG4gICAgcHVibGlzaGVyOiBwdWJsaXNoZXIuaGFuZGxlLFxuICAgIHB1Ymxpc2hlclRpZXI6IHB1Ymxpc2hlci50aWVyLFxuICAgIGxpc3RpbmdJZDogbGlzdGluZy5pZCxcbiAgICBpbnN0YWxsOiBtb2RlLmtpbmQsXG4gICAgbmFtZTogbGlzdGluZy5uYW1lLFxuICAgIHZlcnNpb246IHZlcnNpb24udmVyc2lvbixcbiAgICBpbWFnZVJlcG9zaXRvcnk6IHZlcnNpb24uaW1hZ2VSZXBvc2l0b3J5LFxuICAgIGltYWdlRGlnZXN0OiB2ZXJzaW9uLmltYWdlRGlnZXN0LFxuICAgIGJ1aWxkVHlwZTogdHlwZW9mIHMuYnVpbGRUeXBlID09PSAnc3RyaW5nJyA/IHMuYnVpbGRUeXBlIDogKHZlcnNpb24uaW1hZ2VEaWdlc3QgPyAnYnVpbGRfaW1hZ2UnIDogJ21ldGFkYXRhX29ubHknKSxcbiAgICBwbHVnaW5UeXBlOiBzLnBsdWdpblR5cGUgPz8gJ0NvZGVCdWlsZFN0ZXAnLFxuICAgIGNvbXB1dGVUeXBlOiBzLmNvbXB1dGVUeXBlID8/ICdTTUFMTCcsXG4gICAgZGVzY3JpcHRpb246IHMuZGVzY3JpcHRpb24gPz8gbGlzdGluZy5kZXNjcmlwdGlvbiA/PyBudWxsLFxuICAgIHN1bW1hcnk6IHMuc3VtbWFyeSA/PyBsaXN0aW5nLnN1bW1hcnkgPz8gbnVsbCxcbiAgICBkaXNwbGF5TmFtZTogcy5kaXNwbGF5TmFtZSA/PyBudWxsLFxuICAgIGtleXdvcmRzOiBhcnI8c3RyaW5nPihzLmtleXdvcmRzKSxcbiAgICBjYXRlZ29yeTogcy5jYXRlZ29yeSA/PyBsaXN0aW5nLmNhdGVnb3J5LFxuICAgIG1ldGFkYXRhOiBvYmoocy5tZXRhZGF0YSksXG4gICAgZW52OiBvYmoocy5lbnYpLFxuICAgIGJ1aWxkQXJnczoge30sXG4gICAgaW5zdGFsbENvbW1hbmRzOiBhcnI8c3RyaW5nPihzLmluc3RhbGxDb21tYW5kcyksXG4gICAgY29tbWFuZHM6IGFycjxzdHJpbmc+KHMuY29tbWFuZHMpLFxuICAgIHRpbWVvdXQ6IHMudGltZW91dCA/PyBudWxsLFxuICAgIGZhaWx1cmVCZWhhdmlvcjogcy5mYWlsdXJlQmVoYXZpb3IgPz8gJ2ZhaWwnLFxuICAgIHByaW1hcnlPdXRwdXREaXJlY3Rvcnk6IHMucHJpbWFyeU91dHB1dERpcmVjdG9yeSA/PyBudWxsLFxuICAgIHNlY3JldHM6IHJlcy5zZWNyZXRzV2l0aGhlbGQgPyBbXSA6IGFycihzLnNlY3JldHMpLFxuICAgIHJlcXVpcmVkTWV0YWRhdGE6IGFycjxzdHJpbmc+KHMucmVxdWlyZWRNZXRhZGF0YSksXG4gICAgcmVxdWlyZWRWYXJzOiBhcnI8c3RyaW5nPihzLnJlcXVpcmVkVmFycyksXG4gICAgbWV0YWRhdGFUeXBlczogb2JqKHMubWV0YWRhdGFUeXBlcyksXG4gICAgdmFyc1R5cGVzOiBvYmoocy52YXJzVHlwZXMpLFxuICAgIG5ldHdvcmtFZ3Jlc3M6IGFycjxzdHJpbmc+KHMubmV0d29ya0VncmVzcyksXG4gICAgcnVuQXNSb290OiBzLnJ1bkFzUm9vdCA/PyBudWxsLFxuICAgIGxpY2Vuc2U6IHMubGljZW5zZSA/PyBsaXN0aW5nLmxpY2Vuc2UgPz8gbnVsbCxcbiAgICBob21lcGFnZVVybDogcy5ob21lcGFnZVVybCA/PyBsaXN0aW5nLmhvbWVwYWdlVXJsID8/IG51bGwsXG4gICAgc291cmNlVXJsOiBzLnNvdXJjZVVybCA/PyBsaXN0aW5nLnNvdXJjZVVybCA/PyBudWxsLFxuICAgIGRvY3VtZW50YXRpb25Vcmw6IHMuZG9jdW1lbnRhdGlvblVybCA/PyBudWxsLFxuICAgIGljb246IHMuaWNvbiA/PyBsaXN0aW5nLmljb24gPz8gbnVsbCxcbiAgICBjaGFuZ2Vsb2c6IHZlcnNpb24uY2hhbmdlbG9nLFxuICAgIGJyZWFraW5nOiB2ZXJzaW9uLmJyZWFraW5nLFxuICAgIHZ1bG5Dcml0aWNhbDogdmVyc2lvbi52dWxuQ3JpdGljYWwsXG4gICAgdnVsbkhpZ2g6IHZlcnNpb24udnVsbkhpZ2gsXG4gICAgc2Nhbm5lZEF0OiB2ZXJzaW9uLnNjYW5uZWRBdCxcbiAgICBsaWZlY3ljbGU6IHZlcnNpb24uZGVwcmVjYXRlZEF0ID8gJ2RlcHJlY2F0ZWQnIDogJ3Byb2R1Y3Rpb24nLFxuICAgIGRlcHJlY2F0ZWRBdDogdmVyc2lvbi5kZXByZWNhdGVkQXQsXG4gICAgZGVwcmVjYXRpb25NZXNzYWdlOiB2ZXJzaW9uLmRlcHJlY2F0aW9uTWVzc2FnZSxcbiAgICB5YW5rZWRBdDogbnVsbCxcbiAgICB5YW5rUmVhc29uOiBudWxsLFxuICAgIHZpc2liaWxpdHk6ICdwdWJsaWMnLFxuICAgIGlzRGVmYXVsdDogdHJ1ZSxcbiAgICBpc0FjdGl2ZTogdHJ1ZSxcbiAgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEV2ZXJ5dGhpbmcgYW4gb3JnIGNhbiByZXNvbHZlIChjYXRhbG9nLCBBSSBzZWxlY3Rpb24sIHBsYWNlaG9sZGVyIGd1YXJkKVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqIE9uZSBsaXN0aW5nIHdpdGggdGhlIG9yZydzIHN0YW5kaW5nIG9uIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcmdMaXN0aW5nU3RhdGUge1xuICBwdWJsaXNoZXI6IFB1Ymxpc2hlcjtcbiAgbGlzdGluZzogUGx1Z2luTGlzdGluZztcbiAgdmVyc2lvbnM6IFBsdWdpbkxpc3RpbmdWZXJzaW9uW107XG4gIC8qKiBIb3cgdGhlIG9yZyByZWFjaGVzIGl0LCBvciB3aHkgaXQgY2FuJ3QgKG5vdCBpbnN0YWxsZWQsIHBlbmRpbmcsIOKApikuICovXG4gIG1vZGU6IEluc3RhbGxNb2RlIHwgUmVzb2x1dGlvblJlZnVzYWw7XG4gIC8qKiBBIHBvbGljeSAvIHN0YXRlIGJsb2NrICh0aWVyLCBibG9ja2VkIGxpc3RpbmcsIHN1c3BlbmRlZCksIG9yIG51bGwuICovXG4gIGJsb2NrOiBMaXN0aW5nQmxvY2sgfCBudWxsO1xuICAvKiogV2hhdCBhbiBVTlZFUlNJT05FRCByZWZlcmVuY2UgcmVzb2x2ZXMgdG8gcmlnaHQgbm93LCBvciBudWxsLiAqL1xuICByZXNvbHZlZDogUGx1Z2luTGlzdGluZ1ZlcnNpb24gfCBudWxsO1xuICAvKiogV2h5IG5vdGhpbmcgcmVzb2x2ZXMsIHdoZW4gdGhlIG9yZyBkb2VzIHJlYWNoIHRoZSBsaXN0aW5nIChlLmcuIGFuIGFkdmlzb3J5IGJsb2NrKS4gKi9cbiAgcmVmdXNhbDogUmVzb2x1dGlvblJlZnVzYWwgfCBudWxsO1xuICAvKiogVGhlIGxpc3RpbmcncyBQVUJMSVNIRUQgYWR2aXNvcmllcy4gKi9cbiAgYWR2aXNvcmllczogUGx1Z2luQWR2aXNvcnlbXTtcbiAgLyoqIFRoZSBvcmcncyBvd24gaW5zdGFsbCByb3cgZm9yIGl0IChleHBsaWNpdCwgcG9zc2libHkgcGVuZGluZy9kZW5pZWQpLiAqL1xuICBvd25JbnN0YWxsOiBQbHVnaW5JbnN0YWxsIHwgbnVsbDtcbiAgLyoqIFRoZSBvcmcncyBlZmZlY3RpdmUgY29uc3VtcHRpb24gcG9saWN5ICh0aGUgc2FtZSBmb3IgZXZlcnkgbGlzdGluZykuICovXG4gIHBvbGljeTogQ29uc3VtcHRpb25Qb2xpY3k7XG59XG5cbi8qKiBUaGUgb3JnJ3MgcG9saWN5ICsgaW5zdGFsbCByb3dzIChvd24gYW5kIHJvb3QpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcmdJbnN0YWxsQ29udGV4dCB7XG4gIHBvbGljeTogQ29uc3VtcHRpb25Qb2xpY3k7XG4gIGluc3RhbGxzOiBQbHVnaW5JbnN0YWxsW107XG4gIHNjb3BlOiBSZXNvbHV0aW9uU2NvcGU7XG59XG5cbi8qKiBMb2FkIHRoZSBvcmcncyBwb2xpY3kgYW5kIGluc3RhbGwgcm93cy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkT3JnSW5zdGFsbENvbnRleHQoc291cmNlOiBMaXN0aW5nRGF0YVNvdXJjZSwgc2NvcGU6IFJlc29sdXRpb25TY29wZSk6IFByb21pc2U8T3JnSW5zdGFsbENvbnRleHQ+IHtcbiAgY29uc3Qgb3JnSWRzID0gc2NvcGVPcmdJZHMoc2NvcGUpO1xuICBjb25zdCBbcG9saWNpZXMsIGluc3RhbGxzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtzb3VyY2UucG9saWNpZXNGb3JPcmdzKG9yZ0lkcyksIHNvdXJjZS5pbnN0YWxsc0Zvck9yZ3Mob3JnSWRzKV0pO1xuICByZXR1cm4geyBwb2xpY3k6IGVmZmVjdGl2ZUNvbnN1bXB0aW9uUG9saWN5KHBvbGljaWVzLCBvcmdJZHNbMF0hLCBvcmdJZHNbMV0pLCBpbnN0YWxscywgc2NvcGUgfTtcbn1cblxuLyoqXG4gKiBUaGUgb3JnJ3Mgc3RhbmRpbmcgb24gZXZlcnkgbGl2ZSBsaXN0aW5nIChvciBvbmx5IGBmaWx0ZXJgJ3MpLiBVc2VkIGJ5IHRoZVxuICogaW4tYXBwIGNhdGFsb2c7IHtAbGluayByZXNvbHZhYmxlTGlzdGluZ3N9IG5hcnJvd3MgaXQgdG8gd2hhdCByZXNvbHZlcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9yZ0xpc3RpbmdTdGF0ZXMoXG4gIHNvdXJjZTogTGlzdGluZ0RhdGFTb3VyY2UsXG4gIHNjb3BlOiBSZXNvbHV0aW9uU2NvcGUsXG4gIGZpbHRlcjogeyBpZHM/OiBzdHJpbmdbXTsgbmFtZXM/OiBzdHJpbmdbXSB9ID0ge30sXG4gIGN0eD86IE9yZ0luc3RhbGxDb250ZXh0LFxuKTogUHJvbWlzZTxPcmdMaXN0aW5nU3RhdGVbXT4ge1xuICBjb25zdCBjb250ZXh0ID0gY3R4ID8/IGF3YWl0IGxvYWRPcmdJbnN0YWxsQ29udGV4dChzb3VyY2UsIHNjb3BlKTtcbiAgY29uc3QgbGl2ZSA9IGF3YWl0IHNvdXJjZS5saXZlTGlzdGluZ3MoZmlsdGVyKTtcbiAgaWYgKGxpdmUubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gIGNvbnN0IGlkcyA9IGxpdmUubWFwKChsKSA9PiBsLmlkKTtcbiAgY29uc3QgW3B1YnMsIHZlcnNpb25zLCBhZHZpc29yaWVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICBzb3VyY2UucHVibGlzaGVyc0J5SWRzKFsuLi5uZXcgU2V0KGxpdmUubWFwKChsKSA9PiBsLnB1Ymxpc2hlcklkKSldKSxcbiAgICBzb3VyY2UudmVyc2lvbnNGb3JMaXN0aW5ncyhpZHMpLFxuICAgIHNvdXJjZS5hZHZpc29yaWVzRm9yTGlzdGluZ3MoaWRzKSxcbiAgXSk7XG4gIGNvbnN0IGJ5UHVibGlzaGVyID0gbmV3IE1hcChwdWJzLm1hcCgocCkgPT4gW3AuaWQsIHBdKSk7XG4gIGNvbnN0IG93biA9IHNjb3BlT3JnSWRzKHNjb3BlKVswXSE7XG4gIGNvbnN0IG91dDogT3JnTGlzdGluZ1N0YXRlW10gPSBbXTtcbiAgZm9yIChjb25zdCBsaXN0aW5nIG9mIGxpdmUpIHtcbiAgICBjb25zdCBwdWJsaXNoZXIgPSBieVB1Ymxpc2hlci5nZXQobGlzdGluZy5wdWJsaXNoZXJJZCk7XG4gICAgaWYgKCFwdWJsaXNoZXIpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHZzID0gdmVyc2lvbnMuZmlsdGVyKCh2KSA9PiB2Lmxpc3RpbmdJZCA9PT0gbGlzdGluZy5pZCk7XG4gICAgY29uc3QgYmxvY2sgPSBsaXN0aW5nQmxvY2soY29udGV4dC5wb2xpY3ksIHB1Ymxpc2hlciwgbGlzdGluZyk7XG4gICAgY29uc3QgbW9kZSA9IGluc3RhbGxNb2RlRm9yKHB1Ymxpc2hlciwgbGlzdGluZywgY29udGV4dC5pbnN0YWxscywgY29udGV4dC5wb2xpY3ksIHNjb3BlKTtcbiAgICBjb25zdCBsaXN0aW5nQWR2aXNvcmllcyA9IGFkdmlzb3JpZXMuZmlsdGVyKChhKSA9PiBhLmxpc3RpbmdJZCA9PT0gbGlzdGluZy5pZCk7XG4gICAgbGV0IHJlc29sdmVkOiBQbHVnaW5MaXN0aW5nVmVyc2lvbiB8IG51bGwgPSBudWxsO1xuICAgIGxldCByZWZ1c2FsOiBSZXNvbHV0aW9uUmVmdXNhbCB8IG51bGwgPSBudWxsO1xuICAgIGlmICghYmxvY2sgJiYgISgnY29kZScgaW4gbW9kZSkpIHtcbiAgICAgIGNvbnN0IGNob2ljZSA9IHNlbGVjdExpc3RpbmdWZXJzaW9uKHtcbiAgICAgICAgcmVmOiBgJHtwdWJsaXNoZXIuaGFuZGxlfS8ke2xpc3RpbmcubmFtZX1gLCB2ZXJzaW9uczogdnMsIG1vZGUsIGFkdmlzb3JpZXM6IGxpc3RpbmdBZHZpc29yaWVzLCBwb2xpY3k6IGNvbnRleHQucG9saWN5LFxuICAgICAgfSk7XG4gICAgICBpZiAoJ3ZlcnNpb24nIGluIGNob2ljZSkgcmVzb2x2ZWQgPSBjaG9pY2UudmVyc2lvbjtcbiAgICAgIGVsc2UgcmVmdXNhbCA9IGNob2ljZS5yZWZ1c2FsO1xuICAgIH1cbiAgICBjb25zdCBvd25JbnN0YWxsID0gY29udGV4dC5pbnN0YWxscy5maW5kKChpKSA9PiBpLmxpc3RpbmdJZCA9PT0gbGlzdGluZy5pZCAmJiBpLm9yZ0lkLnRvTG93ZXJDYXNlKCkgPT09IG93bikgPz8gbnVsbDtcbiAgICBvdXQucHVzaCh7IHB1Ymxpc2hlciwgbGlzdGluZywgdmVyc2lvbnM6IHZzLCBtb2RlLCBibG9jaywgcmVzb2x2ZWQsIHJlZnVzYWwsIGFkdmlzb3JpZXM6IGxpc3RpbmdBZHZpc29yaWVzLCBvd25JbnN0YWxsLCBwb2xpY3k6IGNvbnRleHQucG9saWN5IH0pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBUaGUgbGlzdGluZ3MgYW4gb3JnJ3MgcmVmZXJlbmNlcyByZXNvbHZlIHRvIG5vdyAoaW5zdGFsbGVkIG9yIGltcGxpY2l0LCBub3QgYmxvY2tlZCkuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2YWJsZUxpc3RpbmdzKFxuICBzb3VyY2U6IExpc3RpbmdEYXRhU291cmNlLFxuICBzY29wZTogUmVzb2x1dGlvblNjb3BlLFxuICBmaWx0ZXI6IHsgbmFtZXM/OiBzdHJpbmdbXSB9ID0ge30sXG4pOiBQcm9taXNlPEFycmF5PE9yZ0xpc3RpbmdTdGF0ZSAmIHsgcmVzb2x2ZWQ6IFBsdWdpbkxpc3RpbmdWZXJzaW9uIH0+PiB7XG4gIHJldHVybiAoYXdhaXQgb3JnTGlzdGluZ1N0YXRlcyhzb3VyY2UsIHNjb3BlLCBmaWx0ZXIpKVxuICAgIC5maWx0ZXIoKHMpOiBzIGlzIE9yZ0xpc3RpbmdTdGF0ZSAmIHsgcmVzb2x2ZWQ6IFBsdWdpbkxpc3RpbmdWZXJzaW9uIH0gPT4gcy5yZXNvbHZlZCAhPT0gbnVsbCk7XG59XG4iXX0=
|