@pipeline-builder/pipeline-data 4.1.14 → 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.
Files changed (60) hide show
  1. package/lib/api/access-control-builder.d.ts +18 -1
  2. package/lib/api/access-control-builder.js +19 -6
  3. package/lib/api/crud-service.d.ts +94 -36
  4. package/lib/api/crud-service.js +188 -166
  5. package/lib/api/plugin-resolution.d.ts +253 -0
  6. package/lib/api/plugin-resolution.js +649 -0
  7. package/lib/api/public-directory.d.ts +281 -0
  8. package/lib/api/public-directory.js +457 -0
  9. package/lib/api/query-builders.d.ts +13 -0
  10. package/lib/api/query-builders.js +74 -9
  11. package/lib/api/reporting/caches.js +4 -4
  12. package/lib/api/reporting/dora-scoring.d.ts +3 -3
  13. package/lib/api/reporting/dora-scoring.js +4 -4
  14. package/lib/api/reporting/dora.d.ts +6 -6
  15. package/lib/api/reporting/dora.js +97 -73
  16. package/lib/api/reporting/plugin-runtime.d.ts +25 -0
  17. package/lib/api/reporting/plugin-runtime.js +106 -0
  18. package/lib/api/reporting/query-scope.d.ts +8 -2
  19. package/lib/api/reporting/query-scope.js +16 -7
  20. package/lib/api/reporting/retention.d.ts +4 -10
  21. package/lib/api/reporting/retention.js +8 -11
  22. package/lib/api/reporting/sql-helpers.d.ts +4 -7
  23. package/lib/api/reporting/sql-helpers.js +8 -9
  24. package/lib/api/reporting/types.d.ts +55 -17
  25. package/lib/api/reporting/types.js +1 -1
  26. package/lib/api/reporting-service.d.ts +35 -26
  27. package/lib/api/reporting-service.js +245 -161
  28. package/lib/api/semver-range.d.ts +73 -0
  29. package/lib/api/semver-range.js +227 -0
  30. package/lib/api/soft-delete-sweep.js +8 -20
  31. package/lib/core/query-filters.d.ts +18 -3
  32. package/lib/core/query-filters.js +1 -1
  33. package/lib/database/drizzle-schema.d.ts +7790 -2461
  34. package/lib/database/drizzle-schema.js +29 -1
  35. package/lib/database/index.d.ts +4 -2
  36. package/lib/database/index.js +5 -3
  37. package/lib/database/pg-result.d.ts +19 -0
  38. package/lib/database/pg-result.js +32 -0
  39. package/lib/database/postgres-connection.js +14 -24
  40. package/lib/database/public-reader.d.ts +14 -0
  41. package/lib/database/public-reader.js +68 -0
  42. package/lib/database/retry-strategy.d.ts +3 -5
  43. package/lib/database/retry-strategy.js +4 -6
  44. package/lib/database/schema/compliance.d.ts +16 -34
  45. package/lib/database/schema/compliance.js +4 -4
  46. package/lib/database/schema/dashboard.js +4 -2
  47. package/lib/database/schema/ecosystem.d.ts +6586 -0
  48. package/lib/database/schema/ecosystem.js +709 -0
  49. package/lib/database/schema/message.d.ts +6 -12
  50. package/lib/database/schema/message.js +3 -1
  51. package/lib/database/schema/pipeline.d.ts +79 -5
  52. package/lib/database/schema/pipeline.js +46 -25
  53. package/lib/database/schema/plugin.d.ts +587 -3
  54. package/lib/database/schema/plugin.js +86 -14
  55. package/lib/database/tenancy.d.ts +6 -7
  56. package/lib/database/tenancy.js +13 -14
  57. package/lib/index.d.ts +7 -4
  58. package/lib/index.js +7 -4
  59. package/lib/testing/exports.json +146 -0
  60. 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLXJlc29sdXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3BsdWdpbi1yZXNvbHV0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUVILE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUvQyxPQUFPLEVBQ0wsYUFBYSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsb0JBQW9CLEdBQ25GLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixlQUFlLEVBQ2YsTUFBTSxHQWFQLE1BQU0sK0JBQStCLENBQUM7QUFnQnZDLDJFQUEyRTtBQUMzRSxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBZ0MsTUFBTSxDQUFDLE1BQU0sQ0FBb0I7SUFDdEcsWUFBWSxFQUFFLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQztJQUN0QyxvQkFBb0IsRUFBRSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUM7SUFDakQsbUJBQW1CLEVBQUUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDO0lBQzdDLGVBQWUsRUFBRSxVQUFVO0lBQzNCLGdCQUFnQixFQUFFLFVBQVU7SUFDNUIsZUFBZSxFQUFFLEVBQUU7Q0FDcEIsQ0FBQyxDQUFDO0FBRUgscURBQXFEO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQztBQUV4QyxNQUFNLFdBQVcsR0FBK0IsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBRTlFLE1BQU0sU0FBUyxHQUFHLENBQUMsS0FBOEIsRUFBbUIsRUFBRSxDQUNwRSxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUV2RCxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQW9CLEVBQVUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFFaEYsU0FBUyxjQUFjLENBQUMsSUFBa0M7SUFDeEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQTZCLENBQUM7SUFDbEQsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJO1FBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDeEYsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZGLENBQUM7QUFFRCxvRUFBb0U7QUFDcEUsTUFBTSxVQUFVLFFBQVEsQ0FBQyxHQUFvRDtJQUMzRSxNQUFNLENBQUMsR0FBRywwQkFBMEIsQ0FBQztJQUNyQyxPQUFPO1FBQ0wsWUFBWSxFQUFFLFNBQVMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUM7UUFDNUQsb0JBQW9CLEVBQUUsU0FBUyxDQUFDLEdBQUcsRUFBRSxvQkFBb0IsSUFBSSxDQUFDLENBQUMsb0JBQW9CLENBQUM7UUFDcEYsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLEdBQUcsRUFBRSxtQkFBbUIsSUFBSSxDQUFDLENBQUMsbUJBQW1CLENBQUM7UUFDakYsZUFBZSxFQUFFLEdBQUcsRUFBRSxlQUFlLElBQUksQ0FBQyxDQUFDLGVBQWU7UUFDMUQsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxnQkFBZ0I7UUFDN0QsZUFBZSxFQUFFLGNBQWMsQ0FBQyxHQUFHLEVBQUUsZUFBZSxJQUFJLENBQUMsQ0FBQyxlQUFlLENBQUM7S0FDM0UsQ0FBQztBQUNKLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsd0JBQXdCLENBQUMsSUFBdUIsRUFBRSxJQUF1QjtJQUN2RixNQUFNLFNBQVMsR0FBRyxDQUFDLENBQWtCLEVBQUUsQ0FBa0IsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hHLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBa0IsRUFBRSxDQUFrQixFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEYsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQzFHLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ2hELE9BQU87UUFDTCxZQUFZLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUM3RCxvQkFBb0IsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztRQUNqRixtQkFBbUIsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUNsRixlQUFlLEVBQUUsYUFBYTtRQUM5QixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssVUFBVSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVTtRQUN4SCxlQUFlLEVBQUUsY0FBYyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0tBQ3BGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FDeEMsSUFBc0UsRUFDdEUsS0FBYSxFQUNiLFNBQWtCO0lBRWxCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDO0lBQ3hELElBQUksQ0FBQyxTQUFTLElBQUksU0FBUyxLQUFLLEtBQUs7UUFBRSxPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1RCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQztJQUN2RSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDcEUsQ0FBQztBQUVELE1BQU0sU0FBUyxHQUFHLDRCQUE0QixDQUFDO0FBQy9DLE1BQU0sT0FBTyxHQUFHLHdCQUF3QixDQUFDO0FBRXpDLFNBQVMsUUFBUSxDQUFDLENBQVUsRUFBRSxLQUFhO0lBQ3pDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUFFLE9BQU8sR0FBRyxLQUFLLDRCQUE0QixDQUFDO0lBQ25FLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUUsZUFBc0MsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRixJQUFJLEdBQUcsQ0FBQyxNQUFNO1FBQUUsT0FBTyxHQUFHLEtBQUssdUJBQXVCLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDbkYsT0FBTyxTQUFTLENBQUMsQ0FBb0IsQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQXVCLEVBQUUsS0FBYztJQUN2RSxJQUFJLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sd0JBQXdCLENBQUM7SUFDakcsTUFBTSxDQUFDLEdBQUcsS0FBZ0MsQ0FBQztJQUMzQyxNQUFNLElBQUksR0FBc0IsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO0lBQzVDLEtBQUssTUFBTSxLQUFLLElBQUksQ0FBQyxjQUFjLEVBQUUsc0JBQXNCLEVBQUUscUJBQXFCLENBQVUsRUFBRSxDQUFDO1FBQzdGLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLFNBQVM7WUFBRSxTQUFTO1FBQ3JDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDNUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBQ0QsSUFBSSxDQUFDLENBQUMsZUFBZSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxlQUFrQyxDQUFDO1lBQUUsT0FBTyxpREFBaUQsQ0FBQztRQUMxSCxJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQyxlQUFrQyxDQUFDO0lBQzlELENBQUM7SUFDRCxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsS0FBSyxVQUFVLElBQUksQ0FBQyxDQUFDLGdCQUFnQixLQUFLLFVBQVU7WUFBRSxPQUFPLCtDQUErQyxDQUFDO1FBQ25JLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsZ0JBQWdCLENBQUM7SUFDN0MsQ0FBQztJQUNELElBQUksQ0FBQyxDQUFDLGVBQWUsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNwQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO1lBQUUsT0FBTyxrQ0FBa0MsQ0FBQztRQUNqRixJQUFJLENBQUMsQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLG9CQUFvQjtZQUFFLE9BQU8sV0FBVyxvQkFBb0IsbUJBQW1CLENBQUM7UUFDL0csTUFBTSxJQUFJLEdBQXdCLEVBQUUsQ0FBQztRQUNyQyxLQUFLLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNwQyxNQUFNLEdBQUcsR0FBRyxPQUFPLEdBQUcsS0FBSyxRQUFRO2dCQUNqQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pILENBQUMsQ0FBQyxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRyxHQUF5QixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUcsR0FBeUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3ZJLElBQUksQ0FBQyxHQUFHLElBQUksT0FBTyxHQUFHLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxPQUFPLEdBQUcsQ0FBQyxJQUFJLEtBQUssUUFBUTttQkFDeEUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQy9ELE9BQU8sd0VBQXdFLENBQUM7WUFDbEYsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUEwQkQsa0ZBQWtGO0FBQ2xGLE1BQU0sVUFBVSxZQUFZLENBQzFCLE1BQXlCLEVBQ3pCLFNBQTZELEVBQzdELE9BQThDO0lBRTlDLE1BQU0sR0FBRyxHQUFHLEdBQUcsU0FBUyxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbEQsSUFBSSxTQUFTLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUssV0FBVyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUssYUFBYSxFQUFFLENBQUM7UUFDOUYsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEdBQUcsR0FBRyxPQUFPLE9BQU8sQ0FBQyxLQUFLLEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFdBQVcsMEJBQTBCLEVBQUUsQ0FBQztJQUNoSixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDcEcsT0FBTyxFQUFFLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxPQUFPLEVBQUUsNENBQTRDLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDcEcsQ0FBQztJQUNELElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNsRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsbURBQW1ELFNBQVMsQ0FBQyxJQUFJLGFBQWEsR0FBRyxJQUFJLEVBQUUsQ0FBQztJQUM1SCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsa0RBQWtEO0FBQ2xELE1BQU0sVUFBVSxZQUFZLENBQUMsS0FBbUI7SUFDOUMsT0FBTyxLQUFLLENBQUMsTUFBTSxLQUFLLFdBQVc7UUFDakMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUU7UUFDN0UsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLDBCQUEwQixFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDekYsQ0FBQztBQUVELGdGQUFnRjtBQUNoRixhQUFhO0FBQ2IsZ0ZBQWdGO0FBRWhGLHdEQUF3RDtBQUN4RCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBbUU7SUFDdkcsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFDO0lBQ3RCLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUM7SUFDMUIsS0FBSyxFQUFFLEVBQUU7Q0FDVixDQUFDO0FBRUYsTUFBTSxVQUFVLEdBQUcsK0VBQStFLENBQUM7QUFFbkcsK0ZBQStGO0FBQy9GLFNBQVMsbUJBQW1CLENBQUMsR0FBVyxFQUFFLE9BQWU7SUFDdkQsTUFBTSxNQUFNLEdBQUcscUJBQXFCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9DLElBQUksTUFBTTtRQUFFLE9BQU8sYUFBYSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFFLENBQUMsSUFBSSxDQUFDLElBQUksYUFBYSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEcsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0MsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFFLENBQUM7UUFBRSxPQUFPLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFFLENBQUMsQ0FBQztJQUN2RyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUN2QixNQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxDQUFDO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDckIsTUFBTSxDQUFDLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFFLENBQUMsQ0FBQztRQUN4QyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNwQixLQUFLLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekIsS0FBSyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pCLEtBQUssR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN2QixLQUFLLEdBQUcsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdkIsU0FBUyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEtBQWEsRUFBRSxPQUFlO0lBQ2hFLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDeEMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxLQUFLLEVBQUUsSUFBSSxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hJLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQWE7SUFDaEQsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzdCLElBQUksT0FBTyxLQUFLLEVBQUU7UUFBRSxPQUFPLDZCQUE2QixDQUFDO0lBQ3pELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxHQUFHO1FBQUUsT0FBTyxrREFBa0QsQ0FBQztJQUNwRixLQUFLLE1BQU0sR0FBRyxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQzNELElBQUksR0FBRyxLQUFLLEdBQUc7WUFBRSxTQUFTO1FBQzFCLElBQUksR0FBRyxLQUFLLEVBQUU7WUFBRSxPQUFPLGtEQUFrRCxDQUFDO1FBQzFFLE1BQU0sTUFBTSxHQUFHLHFCQUFxQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFFLENBQUM7Z0JBQUUsT0FBTyxJQUFJLEdBQUcsK0JBQStCLENBQUM7WUFDeEcsU0FBUztRQUNYLENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUksZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBRSxDQUFDO1lBQUUsU0FBUztRQUN6RixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxJQUFJLEdBQUcsS0FBSyxTQUFTO1lBQUUsT0FBTyxJQUFJLEdBQUcsbUVBQW1FLENBQUM7SUFDM0csQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELCtGQUErRjtBQUMvRixNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLFVBQXdCLEVBQ3hCLE9BQWU7SUFFZixNQUFNLElBQUksR0FBcUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDM0YsT0FBTyxVQUFVO1NBQ2QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLFdBQVcsSUFBSSxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQ3ZGLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ3pELENBQUM7QUFFRCxnRUFBZ0U7QUFDaEUsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxVQUF1SCxFQUN2SCxPQUFlLEVBQ2YsTUFBa0Q7SUFFbEQsTUFBTSxVQUFVLEdBQUcseUJBQXlCLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3JFLElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDdkMsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDL0ksQ0FBQztBQWFELE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBUyxFQUFXLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV4Rjs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLFFBQStCO0lBQ2xFLE1BQU0sTUFBTSxHQUFHLFFBQVE7U0FDcEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNqRCxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0MsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNyQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDcEMsQ0FBQztBQUVELDhGQUE4RjtBQUM5RixNQUFNLFVBQVUsYUFBYSxDQUMzQixPQUErRCxFQUMvRCxPQUFlLEVBQ2YsUUFBK0I7SUFFL0IsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztJQUNuQyxRQUFRLE9BQU8sQ0FBQyxhQUFxQyxFQUFFLENBQUM7UUFDdEQsS0FBSyxRQUFRO1lBQ1gsT0FBTyxPQUFPLEtBQUssSUFBSSxDQUFDO1FBQzFCLEtBQUssT0FBTztZQUNWLE9BQU8sSUFBSSxLQUFLLElBQUksSUFBSSxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLEtBQUssT0FBTztZQUNWLE9BQU8sSUFBSSxLQUFLLElBQUksSUFBSSxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUNyQyxJQUFJLElBQUksS0FBSyxJQUFJO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQy9CLElBQUksYUFBYSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBQ25ELHVEQUF1RDtZQUN2RCxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDM0gsQ0FBQztRQUNEO1lBQ0UsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztBQUNILENBQUM7QUFFRCxvRkFBb0Y7QUFDcEYsTUFBTSxVQUFVLFVBQVUsQ0FBQyxJQUFpQixFQUFFLE9BQWUsRUFBRSxRQUErQjtJQUM1RixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssVUFBVTtRQUFFLE9BQU8sYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3BGLE1BQU0sS0FBSyxHQUFHLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzdDLE9BQU8sS0FBSyxLQUFLLElBQUksSUFBSSxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDaEUsQ0FBQztBQWFEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBaUMsS0FBNEI7SUFDL0YsTUFBTSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDO0lBQ3JFLE1BQU0sS0FBSyxHQUFHLFNBQVMsS0FBSyxTQUFTLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBRTlGLElBQUksS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ25CLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLENBQUM7WUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsT0FBTyxFQUFFLEdBQUcsR0FBRyw2QkFBNkIsS0FBSyxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQ3JJLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2YsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1AsSUFBSSxFQUFFLG9CQUFvQjtvQkFDMUIsTUFBTSxFQUFFLFFBQVE7b0JBQ2hCLE9BQU8sRUFBRSxHQUFHLEdBQUcsSUFBSSxLQUFLLGFBQWEsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsZ0NBQWdDO29CQUM1RyxPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFO2lCQUM1QjthQUNGLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzlFLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQLElBQUksRUFBRSxzQkFBc0I7b0JBQzVCLE1BQU0sRUFBRSx5QkFBeUI7b0JBQ2pDLE9BQU8sRUFBRSxHQUFHLEdBQUcsSUFBSSxLQUFLLDZCQUE2QixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsU0FBUyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsK0JBQStCO29CQUNqSixPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUU7aUJBQ2xIO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFDRCxNQUFNLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELElBQUksUUFBUSxDQUFDLE1BQU07WUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGVBQWUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDL0UsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDdEYsNkVBQTZFO0lBQzdFLHlFQUF5RTtJQUN6RSxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRO1dBQzlDLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDO1lBQzdFLENBQUMsQ0FBQyxTQUFTLEtBQUssU0FBUyxJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztXQUNsRSxDQUFDLFNBQVMsS0FBSyxTQUFTLElBQUksb0JBQW9CLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztXQUN2RSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsT0FBTyxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUM7SUFDcEQsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ3ZHLDBFQUEwRTtJQUMxRSxrQ0FBa0M7SUFDbEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3BELElBQUksSUFBSTtRQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUUsRUFBRSxDQUFDO0lBRXZFLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN4QixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFFLENBQUM7UUFDeEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxlQUFlLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNuRyxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxTQUFTLEtBQUssU0FBUztXQUNsRCxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLElBQUksb0JBQW9CLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDckYsT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUCxJQUFJLEVBQUUsc0JBQXNCO2dCQUM1QixNQUFNLEVBQUUseUJBQXlCO2dCQUNqQyxPQUFPLEVBQUUsaUJBQWlCLEdBQUcsYUFBYSxTQUFTLDRCQUE0QixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsU0FBUyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsK0JBQStCO2dCQUMzSyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRTthQUM3RztTQUNGLENBQUM7SUFDSixDQUFDO0lBQ0QsT0FBTztRQUNMLE9BQU8sRUFBRTtZQUNQLElBQUksRUFBRSxXQUFXO1lBQ2pCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsT0FBTyxFQUFFLDRCQUE0QixHQUFHLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxZQUFZLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUc7U0FDdkY7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELGtFQUFrRTtBQUNsRSxTQUFTLE9BQU8sQ0FBQyxRQUEyQjtJQUMxQyxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQWdCLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLGFBQWEsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3JILENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxHQUFXLEVBQUUsT0FBZSxFQUFFLFFBQTZGO0lBQ2xKLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRixPQUFPO1FBQ0wsSUFBSSxFQUFFLDBCQUEwQjtRQUNoQyxNQUFNLEVBQUUsVUFBVTtRQUNsQixPQUFPLEVBQUUsR0FBRyxHQUFHLElBQUksT0FBTyx1REFBdUQsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRztjQUM5SSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLGFBQWEsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDMUQsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtLQUMvRyxDQUFDO0FBQ0osQ0FBQztBQWFELGdFQUFnRTtBQUNoRSxNQUFNLFVBQVUsV0FBVyxDQUFDLEtBQXNCO0lBQ2hELE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDdEMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUM1QyxPQUFPLElBQUksSUFBSSxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwRCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUM1QixTQUFvQyxFQUNwQyxPQUEyQyxFQUMzQyxRQUFrQyxFQUNsQyxNQUF5QixFQUN6QixLQUFzQjtJQUV0QixNQUFNLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN0RSxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQzFGLElBQUksTUFBTSxFQUFFLE1BQU0sS0FBSyxRQUFRO1FBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDaEcsSUFBSSxPQUFPLEVBQUUsTUFBTSxLQUFLLFFBQVE7UUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNqRyxNQUFNLEdBQUcsR0FBRyxHQUFHLFNBQVMsQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2xELElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyx5QkFBeUIsRUFBRSxDQUFDO1FBQ25ELElBQUksTUFBTSxDQUFDLGdCQUFnQixLQUFLLFVBQVU7WUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxDQUFDO1FBQ3hFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLHNCQUFzQjtnQkFDNUIsTUFBTSxFQUFFLG1CQUFtQjtnQkFDM0IsT0FBTyxFQUFFLG1FQUFtRSxHQUFHLFNBQVM7YUFDekYsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBQ0QsSUFBSSxNQUFNLEVBQUUsTUFBTSxLQUFLLGtCQUFrQixFQUFFLENBQUM7UUFDMUMsT0FBTyxFQUFFLElBQUksRUFBRSxzQkFBc0IsRUFBRSxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixHQUFHLDJCQUEyQixFQUFFLENBQUM7SUFDakksQ0FBQztJQUNELElBQUksTUFBTSxFQUFFLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNoQyxPQUFPLEVBQUUsSUFBSSxFQUFFLHNCQUFzQixFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixHQUFHLGNBQWMsRUFBRSxDQUFDO0lBQzFHLENBQUM7SUFDRCxPQUFPLEVBQUUsSUFBSSxFQUFFLHNCQUFzQixFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLEdBQUcsR0FBRyx5Q0FBeUMsRUFBRSxDQUFDO0FBQzdILENBQUM7QUFxQkQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsRUFBVTtJQUM3QyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDZCxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO0lBQzNCLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7SUFDL0IsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDO0lBQ3RDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUM7SUFDaEMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQztJQUMvQixNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUM7SUFDdEMsT0FBTztRQUNMLGlCQUFpQixFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFpQixDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUk7UUFDeEgsZUFBZSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2pHLGFBQWEsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxFQUFFLENBQ3hDLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFxQixDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUk7UUFDMUgsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQUcsRUFBRSxFQUFFLEVBQUU7WUFDbEMsSUFBSSxNQUFNLENBQUMsR0FBRyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUM7Z0JBQUUsT0FBTyxFQUFFLENBQUM7WUFDckQsSUFBSSxNQUFNLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7Z0JBQUUsT0FBTyxFQUFFLENBQUM7WUFDekQsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQ2xDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLGNBQWMsQ0FBQyxDQUFDLEVBQzVDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFDbEQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUN6RCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDNUcscUJBQXFCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDN0ksZUFBZSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUks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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=