1 | import { join, normalize, relative, strings, JsonParseMode, parseJson, basename, dirname as dirname$1, tags, resolve } from '@angular-devkit/core';
|
2 | import { __values, __spread, __makeTemplateObject, __assign, __extends } from 'tslib';
|
3 | import { SyntaxKind, forEachChild, isClassDeclaration, createSourceFile, ScriptTarget } from 'typescript';
|
4 | import { SchematicsException } from '@angular-devkit/schematics';
|
5 | import { dirname, join as join$1, normalize as normalize$1, parse } from 'path';
|
6 | import { isString, cloneDeep } from 'lodash';
|
7 | import { isString as isString$1, assertObject, isNil, isNotNil, assertArray, isArray, isPlainObject } from '@ibm-wch-sdk/utils';
|
8 | export { wchGetDeliveryUrlFromApiURL } from '@ibm-wch-sdk/utils';
|
9 | import { ok } from 'assert';
|
10 | import { validate } from 'email-validator';
|
11 | import { isWebUri, isUri } from 'valid-url';
|
12 | import { ajax } from 'rxjs/ajax';
|
13 | import { map, catchError, mergeMap, mapTo, pluck, switchMap, switchMapTo, first, filter, takeUntil, tap } from 'rxjs/operators';
|
14 | import { Observable, of, bindNodeCallback, throwError, defer, fromEvent } from 'rxjs';
|
15 | import { readFile } from 'fs';
|
16 | import { exec } from 'child_process';
|
17 | import { RSA_PKCS1_PADDING } from 'constants';
|
18 | import { privateDecrypt } from 'crypto';
|
19 | import { homedir, platform } from 'os';
|
20 | import { env } from 'process';
|
21 | import 'sshpk';
|
22 | import { satisfies, coerce } from 'semver';
|
23 | import { KEY_BASICAUTH_LOGIN_PASSWORD, KEY_BASICAUTH_LOGIN_USERNAME, REL_PATH_BASICAUTH_LOGIN, REL_PATH_CURRENT_USER } from '@ibm-wch-sdk/api';
|
24 | import { VError } from 'verror';
|
25 | import { get } from 'request';
|
26 | import { Writable } from 'stream';
|
27 | import { Parse } from 'unzip';
|
28 | import { load } from 'cheerio';
|
29 |
|
30 | /**
|
31 | * @fileoverview added by tsickle
|
32 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
33 | */
|
34 | /**
|
35 | * Find the module referred by a set of options passed to the schematics.
|
36 | * @param {?} host
|
37 | * @param {?} options
|
38 | * @return {?}
|
39 | */
|
40 | function findModuleFromOptions(host, options) {
|
41 | if (options.hasOwnProperty('skipImport') && options.skipImport) {
|
42 | return undefined;
|
43 | }
|
44 | if (!options.module) {
|
45 | /** @type {?} */
|
46 | var pathToCheck = (options.path || '')
|
47 | + (options.flat ? '' : '/' + strings.dasherize(options.name));
|
48 | return normalize(findModule(host, pathToCheck));
|
49 | }
|
50 | else {
|
51 | /** @type {?} */
|
52 | var modulePath = normalize('/' + (options.path) + '/' + options.module);
|
53 | /** @type {?} */
|
54 | var moduleBaseName = normalize(modulePath).split('/').pop();
|
55 | if (host.exists(modulePath)) {
|
56 | return normalize(modulePath);
|
57 | }
|
58 | else if (host.exists(modulePath + '.ts')) {
|
59 | return normalize(modulePath + '.ts');
|
60 | }
|
61 | else if (host.exists(modulePath + '.module.ts')) {
|
62 | return normalize(modulePath + '.module.ts');
|
63 | }
|
64 | else if (host.exists(modulePath + '/' + moduleBaseName + '.module.ts')) {
|
65 | return normalize(modulePath + '/' + moduleBaseName + '.module.ts');
|
66 | }
|
67 | else {
|
68 | throw new Error('Specified module does not exist');
|
69 | }
|
70 | }
|
71 | }
|
72 | /**
|
73 | * Function to find the "closest" module to a generated file's path.
|
74 | * @param {?} host
|
75 | * @param {?} generateDir
|
76 | * @return {?}
|
77 | */
|
78 | function findModule(host, generateDir) {
|
79 | /** @type {?} */
|
80 | var dir = host.getDir('/' + generateDir);
|
81 | /** @type {?} */
|
82 | var moduleRe = /\.module\.ts$/;
|
83 | /** @type {?} */
|
84 | var routingModuleRe = /-routing\.module\.ts/;
|
85 | while (dir) {
|
86 | /** @type {?} */
|
87 | var matches = dir.subfiles.filter(function (p) { return moduleRe.test(p) && !routingModuleRe.test(p); });
|
88 | if (matches.length == 1) {
|
89 | return join(dir.path, matches[0]);
|
90 | }
|
91 | else if (matches.length > 1) {
|
92 | throw new Error('More than one module matches. Use skip-import option to skip importing '
|
93 | + 'the component into the closest module.');
|
94 | }
|
95 | dir = dir.parent;
|
96 | }
|
97 | throw new Error('Could not find an NgModule. Use the skip-import '
|
98 | + 'option to skip importing in NgModule.');
|
99 | }
|
100 | /**
|
101 | * Build a relative path from one file path to another file path.
|
102 | * @param {?} from
|
103 | * @param {?} to
|
104 | * @return {?}
|
105 | */
|
106 | function buildRelativePath(from, to) {
|
107 | from = normalize(from);
|
108 | to = normalize(to);
|
109 | /** @type {?} */
|
110 | var fromParts = from.split('/');
|
111 | /** @type {?} */
|
112 | var toParts = to.split('/');
|
113 | // Remove file names (preserving destination)
|
114 | fromParts.pop();
|
115 | /** @type {?} */
|
116 | var toFileName = toParts.pop();
|
117 | /** @type {?} */
|
118 | var relativePath = relative(normalize(fromParts.join('/')), normalize(toParts.join('/')));
|
119 | /** @type {?} */
|
120 | var pathPrefix = '';
|
121 | // Set the path prefix for same dir or child dir, parent dir starts with `..`
|
122 | if (!relativePath) {
|
123 | pathPrefix = '.';
|
124 | }
|
125 | else if (!relativePath.startsWith('.')) {
|
126 | pathPrefix = "./";
|
127 | }
|
128 | if (pathPrefix && !pathPrefix.endsWith('/')) {
|
129 | pathPrefix += '/';
|
130 | }
|
131 | return pathPrefix + (relativePath ? relativePath + '/' : '') + toFileName;
|
132 | }
|
133 |
|
134 | /**
|
135 | * @fileoverview added by tsickle
|
136 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
137 | */
|
138 | /**
|
139 | * An operation that does nothing.
|
140 | */
|
141 | var /**
|
142 | * An operation that does nothing.
|
143 | */
|
144 | NoopChange = /** @class */ (function () {
|
145 | function NoopChange() {
|
146 | this.description = 'No operation.';
|
147 | this.order = Infinity;
|
148 | this.path = null;
|
149 | }
|
150 | /**
|
151 | * @return {?}
|
152 | */
|
153 | NoopChange.prototype.apply = /**
|
154 | * @return {?}
|
155 | */
|
156 | function () { return Promise.resolve(); };
|
157 | return NoopChange;
|
158 | }());
|
159 | /**
|
160 | * Will add text to the source code.
|
161 | */
|
162 | var /**
|
163 | * Will add text to the source code.
|
164 | */
|
165 | InsertChange = /** @class */ (function () {
|
166 | function InsertChange(path, pos, toAdd) {
|
167 | this.path = path;
|
168 | this.pos = pos;
|
169 | this.toAdd = toAdd;
|
170 | if (pos < 0) {
|
171 | throw new Error('Negative positions are invalid');
|
172 | }
|
173 | this.description = "Inserted " + toAdd + " into position " + pos + " of " + path;
|
174 | this.order = pos;
|
175 | }
|
176 | /**
|
177 | * This method does not insert spaces if there is none in the original string.
|
178 | */
|
179 | /**
|
180 | * This method does not insert spaces if there is none in the original string.
|
181 | * @param {?} host
|
182 | * @return {?}
|
183 | */
|
184 | InsertChange.prototype.apply = /**
|
185 | * This method does not insert spaces if there is none in the original string.
|
186 | * @param {?} host
|
187 | * @return {?}
|
188 | */
|
189 | function (host) {
|
190 | var _this = this;
|
191 | return host.read(this.path).then(function (content) {
|
192 | /** @type {?} */
|
193 | var prefix = content.substring(0, _this.pos);
|
194 | /** @type {?} */
|
195 | var suffix = content.substring(_this.pos);
|
196 | return host.write(_this.path, "" + prefix + _this.toAdd + suffix);
|
197 | });
|
198 | };
|
199 | return InsertChange;
|
200 | }());
|
201 | /**
|
202 | * Will remove text from the source code.
|
203 | */
|
204 | var /**
|
205 | * Will remove text from the source code.
|
206 | */
|
207 | RemoveChange = /** @class */ (function () {
|
208 | function RemoveChange(path, pos, toRemove) {
|
209 | this.path = path;
|
210 | this.pos = pos;
|
211 | this.toRemove = toRemove;
|
212 | if (pos < 0) {
|
213 | throw new Error('Negative positions are invalid');
|
214 | }
|
215 | this.description = "Removed " + toRemove + " into position " + pos + " of " + path;
|
216 | this.order = pos;
|
217 | }
|
218 | /**
|
219 | * @param {?} host
|
220 | * @return {?}
|
221 | */
|
222 | RemoveChange.prototype.apply = /**
|
223 | * @param {?} host
|
224 | * @return {?}
|
225 | */
|
226 | function (host) {
|
227 | var _this = this;
|
228 | return host.read(this.path).then(function (content) {
|
229 | /** @type {?} */
|
230 | var prefix = content.substring(0, _this.pos);
|
231 | /** @type {?} */
|
232 | var suffix = content.substring(_this.pos + _this.toRemove.length);
|
233 | // TODO: throw error if toRemove doesn't match removed string.
|
234 | return host.write(_this.path, "" + prefix + suffix);
|
235 | });
|
236 | };
|
237 | return RemoveChange;
|
238 | }());
|
239 | /**
|
240 | * Will replace text from the source code.
|
241 | */
|
242 | var /**
|
243 | * Will replace text from the source code.
|
244 | */
|
245 | ReplaceChange = /** @class */ (function () {
|
246 | function ReplaceChange(path, pos, oldText, newText) {
|
247 | this.path = path;
|
248 | this.pos = pos;
|
249 | this.oldText = oldText;
|
250 | this.newText = newText;
|
251 | if (pos < 0) {
|
252 | throw new Error('Negative positions are invalid');
|
253 | }
|
254 | this.description = "Replaced " + oldText + " into position " + pos + " of " + path + " with " + newText;
|
255 | this.order = pos;
|
256 | }
|
257 | /**
|
258 | * @param {?} host
|
259 | * @return {?}
|
260 | */
|
261 | ReplaceChange.prototype.apply = /**
|
262 | * @param {?} host
|
263 | * @return {?}
|
264 | */
|
265 | function (host) {
|
266 | var _this = this;
|
267 | return host.read(this.path).then(function (content) {
|
268 | /** @type {?} */
|
269 | var prefix = content.substring(0, _this.pos);
|
270 | /** @type {?} */
|
271 | var suffix = content.substring(_this.pos + _this.oldText.length);
|
272 | /** @type {?} */
|
273 | var text = content.substring(_this.pos, _this.pos + _this.oldText.length);
|
274 | if (text !== _this.oldText) {
|
275 | return Promise.reject(new Error("Invalid replace: \"" + text + "\" != \"" + _this.oldText + "\"."));
|
276 | }
|
277 | // TODO: throw error if oldText doesn't match removed string.
|
278 | return host.write(_this.path, "" + prefix + _this.newText + suffix);
|
279 | });
|
280 | };
|
281 | return ReplaceChange;
|
282 | }());
|
283 |
|
284 | /**
|
285 | * @fileoverview added by tsickle
|
286 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
287 | */
|
288 | /**
|
289 | * Add Import `import { symbolName } from fileName` if the import doesn't exit
|
290 | * already. Assumes fileToEdit can be resolved and accessed.
|
291 | * @param {?} source
|
292 | * @param {?} fileToEdit (file we want to add import to)
|
293 | * @param {?} symbolName (item to import)
|
294 | * @param {?} fileName (path to the file)
|
295 | * @param {?=} isDefault (if true, import follows style for importing default exports)
|
296 | * @return {?} Change
|
297 | */
|
298 | function insertImport(source, fileToEdit, symbolName, fileName, isDefault) {
|
299 | if (isDefault === void 0) { isDefault = false; }
|
300 | /** @type {?} */
|
301 | var rootNode = source;
|
302 | /** @type {?} */
|
303 | var allImports = findNodes(rootNode, SyntaxKind.ImportDeclaration);
|
304 | /** @type {?} */
|
305 | var relevantImports = allImports.filter(function (node) {
|
306 | /** @type {?} */
|
307 | var importFiles = node
|
308 | .getChildren()
|
309 | .filter(function (child) { return child.kind === SyntaxKind.StringLiteral; })
|
310 | .map(function (n) { return (/** @type {?} */ (n)).text; });
|
311 | return importFiles.filter(function (file) { return file === fileName; }).length === 1;
|
312 | });
|
313 | if (relevantImports.length > 0) {
|
314 | /** @type {?} */
|
315 | var importsAsterisk_1 = false;
|
316 | /** @type {?} */
|
317 | var imports_1 = [];
|
318 | relevantImports.forEach(function (n) {
|
319 | Array.prototype.push.apply(imports_1, findNodes(n, SyntaxKind.Identifier));
|
320 | if (findNodes(n, SyntaxKind.AsteriskToken).length > 0) {
|
321 | importsAsterisk_1 = true;
|
322 | }
|
323 | });
|
324 | // if imports * from fileName, don't add symbolName
|
325 | if (importsAsterisk_1) {
|
326 | return new NoopChange();
|
327 | }
|
328 | /** @type {?} */
|
329 | var importTextNodes = imports_1.filter(function (n) { return (/** @type {?} */ (n)).text === symbolName; });
|
330 | // insert import if it's not there
|
331 | if (importTextNodes.length === 0) {
|
332 | /** @type {?} */
|
333 | var fallbackPos_1 = findNodes(relevantImports[0], SyntaxKind.CloseBraceToken)[0].getStart() ||
|
334 | findNodes(relevantImports[0], SyntaxKind.FromKeyword)[0].getStart();
|
335 | return insertAfterLastOccurrence(imports_1, ", " + symbolName, fileToEdit, fallbackPos_1);
|
336 | }
|
337 | return new NoopChange();
|
338 | }
|
339 | /** @type {?} */
|
340 | var useStrict = findNodes(rootNode, SyntaxKind.StringLiteral).filter(function (n) { return n.text === 'use strict'; });
|
341 | /** @type {?} */
|
342 | var fallbackPos = 0;
|
343 | if (useStrict.length > 0) {
|
344 | fallbackPos = useStrict[0].end;
|
345 | }
|
346 | /** @type {?} */
|
347 | var open = isDefault ? '' : '{ ';
|
348 | /** @type {?} */
|
349 | var close = isDefault ? '' : ' }';
|
350 | /** @type {?} */
|
351 | var insertAtBeginning = allImports.length === 0 && useStrict.length === 0;
|
352 | /** @type {?} */
|
353 | var separator = insertAtBeginning ? '' : ';\n';
|
354 | /** @type {?} */
|
355 | var toInsert = separator + "import " + open + symbolName + close +
|
356 | (" from '" + fileName + "'" + (insertAtBeginning ? ';\n' : ''));
|
357 | return insertAfterLastOccurrence(allImports, toInsert, fileToEdit, fallbackPos, SyntaxKind.StringLiteral);
|
358 | }
|
359 | /**
|
360 | * Find all nodes from the AST in the subtree of node of SyntaxKind kind.
|
361 | * @param {?} node
|
362 | * @param {?} kind
|
363 | * @param {?=} max The maximum number of items to return.
|
364 | * @return {?} all nodes of kind, or [] if none is found
|
365 | */
|
366 | function findNodes(node, kind, max) {
|
367 | if (max === void 0) { max = Infinity; }
|
368 | var e_1, _a;
|
369 | if (!node || max == 0) {
|
370 | return [];
|
371 | }
|
372 | /** @type {?} */
|
373 | var arr = [];
|
374 | if (node.kind === kind) {
|
375 | arr.push(node);
|
376 | max--;
|
377 | }
|
378 | if (max > 0) {
|
379 | try {
|
380 | for (var _b = __values(node.getChildren()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
381 | var child = _c.value;
|
382 | findNodes(child, kind, max).forEach(function (node) {
|
383 | if (max > 0) {
|
384 | arr.push(node);
|
385 | }
|
386 | max--;
|
387 | });
|
388 | if (max <= 0) {
|
389 | break;
|
390 | }
|
391 | }
|
392 | }
|
393 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
394 | finally {
|
395 | try {
|
396 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
397 | }
|
398 | finally { if (e_1) throw e_1.error; }
|
399 | }
|
400 | }
|
401 | return arr;
|
402 | }
|
403 | /**
|
404 | * Get all the nodes from a source.
|
405 | * @param {?} sourceFile The source file object.
|
406 | * @return {?} An observable of all the nodes in the source.
|
407 | */
|
408 | function getSourceNodes(sourceFile) {
|
409 | /** @type {?} */
|
410 | var nodes = [sourceFile];
|
411 | /** @type {?} */
|
412 | var result = [];
|
413 | while (nodes.length > 0) {
|
414 | /** @type {?} */
|
415 | var node = nodes.shift();
|
416 | if (node) {
|
417 | result.push(node);
|
418 | if (node.getChildCount(sourceFile) >= 0) {
|
419 | nodes.unshift.apply(nodes, __spread(node.getChildren()));
|
420 | }
|
421 | }
|
422 | }
|
423 | return result;
|
424 | }
|
425 | /**
|
426 | * @param {?} node
|
427 | * @param {?} kind
|
428 | * @param {?} text
|
429 | * @return {?}
|
430 | */
|
431 | function findNode(node, kind, text) {
|
432 | if (node.kind === kind && node.getText() === text) {
|
433 | // throw new Error(node.getText());
|
434 | return node;
|
435 | }
|
436 | /** @type {?} */
|
437 | var foundNode = null;
|
438 | forEachChild(node, function (childNode) {
|
439 | foundNode = foundNode || findNode(childNode, kind, text);
|
440 | });
|
441 | return foundNode;
|
442 | }
|
443 | /**
|
444 | * Helper for sorting nodes.
|
445 | * @param {?} first
|
446 | * @param {?} second
|
447 | * @return {?} function to sort nodes in increasing order of position in sourceFile
|
448 | */
|
449 | function nodesByPosition(first$$1, second) {
|
450 | return first$$1.getStart() - second.getStart();
|
451 | }
|
452 | /**
|
453 | * Insert `toInsert` after the last occurence of `ts.SyntaxKind[nodes[i].kind]`
|
454 | * or after the last of occurence of `syntaxKind` if the last occurence is a sub child
|
455 | * of ts.SyntaxKind[nodes[i].kind] and save the changes in file.
|
456 | *
|
457 | * \@throw Error if toInsert is first occurence but fall back is not set
|
458 | * @param {?} nodes insert after the last occurence of nodes
|
459 | * @param {?} toInsert string to insert
|
460 | * @param {?} file file to insert changes into
|
461 | * @param {?} fallbackPos position to insert if toInsert happens to be the first occurence
|
462 | * @param {?=} syntaxKind the ts.SyntaxKind of the subchildren to insert after
|
463 | * @return {?} Change instance
|
464 | */
|
465 | function insertAfterLastOccurrence(nodes, toInsert, file, fallbackPos, syntaxKind) {
|
466 | /** @type {?} */
|
467 | var lastItem = __spread(nodes).sort(nodesByPosition).pop();
|
468 | if (!lastItem) {
|
469 | throw new Error();
|
470 | }
|
471 | if (syntaxKind) {
|
472 | lastItem = findNodes(lastItem, syntaxKind)
|
473 | .sort(nodesByPosition)
|
474 | .pop();
|
475 | }
|
476 | if (!lastItem && fallbackPos == undefined) {
|
477 | throw new Error("tried to insert " + toInsert + " as first occurence with no fallback position");
|
478 | }
|
479 | /** @type {?} */
|
480 | var lastItemPosition = lastItem ? lastItem.getEnd() : fallbackPos;
|
481 | return new InsertChange(file, lastItemPosition, toInsert);
|
482 | }
|
483 | /**
|
484 | * @param {?} _source
|
485 | * @param {?} node
|
486 | * @return {?}
|
487 | */
|
488 | function getContentOfKeyLiteral(_source, node) {
|
489 | if (node.kind == SyntaxKind.Identifier) {
|
490 | return (/** @type {?} */ (node)).text;
|
491 | }
|
492 | else if (node.kind == SyntaxKind.StringLiteral) {
|
493 | return (/** @type {?} */ (node)).text;
|
494 | }
|
495 | else {
|
496 | return null;
|
497 | }
|
498 | }
|
499 | /**
|
500 | * @param {?} node
|
501 | * @param {?} _sourceFile
|
502 | * @return {?}
|
503 | */
|
504 | function _angularImportsFromNode(node, _sourceFile) {
|
505 | var _a;
|
506 | /** @type {?} */
|
507 | var ms = node.moduleSpecifier;
|
508 | /** @type {?} */
|
509 | var modulePath;
|
510 | switch (ms.kind) {
|
511 | case SyntaxKind.StringLiteral:
|
512 | modulePath = (/** @type {?} */ (ms)).text;
|
513 | break;
|
514 | default:
|
515 | return {};
|
516 | }
|
517 | if (!modulePath.startsWith('@angular/')) {
|
518 | return {};
|
519 | }
|
520 | if (node.importClause) {
|
521 | if (node.importClause.name) {
|
522 | // This is of the form `import Name from 'path'`. Ignore.
|
523 | return {};
|
524 | }
|
525 | else if (node.importClause.namedBindings) {
|
526 | /** @type {?} */
|
527 | var nb = node.importClause.namedBindings;
|
528 | if (nb.kind == SyntaxKind.NamespaceImport) {
|
529 | // This is of the form `import * as name from 'path'`. Return `name.`.
|
530 | return _a = {},
|
531 | _a[(/** @type {?} */ (nb)).name.text + '.'] = modulePath,
|
532 | _a;
|
533 | }
|
534 | else {
|
535 | /** @type {?} */
|
536 | var namedImports = /** @type {?} */ (nb);
|
537 | return namedImports.elements
|
538 | .map(function (is) {
|
539 | return is.propertyName ? is.propertyName.text : is.name.text;
|
540 | })
|
541 | .reduce(function (acc, curr) {
|
542 | acc[curr] = modulePath;
|
543 | return acc;
|
544 | }, {});
|
545 | }
|
546 | }
|
547 | return {};
|
548 | }
|
549 | else {
|
550 | // This is of the form `import 'path';`. Nothing to do.
|
551 | return {};
|
552 | }
|
553 | }
|
554 | /**
|
555 | * @param {?} source
|
556 | * @param {?} identifier
|
557 | * @param {?} module
|
558 | * @return {?}
|
559 | */
|
560 | function getDecoratorMetadata(source, identifier, module) {
|
561 | /** @type {?} */
|
562 | var angularImports = findNodes(source, SyntaxKind.ImportDeclaration)
|
563 | .map(function (node) { return _angularImportsFromNode(node, source); })
|
564 | .reduce(function (acc, current) {
|
565 | var e_2, _a;
|
566 | try {
|
567 | for (var _b = __values(Object.keys(current)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
568 | var key = _c.value;
|
569 | acc[key] = current[key];
|
570 | }
|
571 | }
|
572 | catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
573 | finally {
|
574 | try {
|
575 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
576 | }
|
577 | finally { if (e_2) throw e_2.error; }
|
578 | }
|
579 | return acc;
|
580 | }, {});
|
581 | return getSourceNodes(source)
|
582 | .filter(function (node) {
|
583 | return (node.kind == SyntaxKind.Decorator &&
|
584 | (/** @type {?} */ (node)).expression.kind == SyntaxKind.CallExpression);
|
585 | })
|
586 | .map(function (node) { return ((/** @type {?} */ (node)).expression); })
|
587 | .filter(function (expr) {
|
588 | if (expr.expression.kind == SyntaxKind.Identifier) {
|
589 | /** @type {?} */
|
590 | var id = /** @type {?} */ (expr.expression);
|
591 | return (id.getFullText(source) == identifier &&
|
592 | angularImports[id.getFullText(source)] === module);
|
593 | }
|
594 | else if (expr.expression.kind == SyntaxKind.PropertyAccessExpression) {
|
595 | /** @type {?} */
|
596 | var paExpr = /** @type {?} */ (expr.expression);
|
597 | // If the left expression is not an identifier, just give up at that point.
|
598 | if (paExpr.expression.kind !== SyntaxKind.Identifier) {
|
599 | return false;
|
600 | }
|
601 | /** @type {?} */
|
602 | var id = paExpr.name.text;
|
603 | /** @type {?} */
|
604 | var moduleId = (/** @type {?} */ (paExpr.expression)).getText(source);
|
605 | return id === identifier && angularImports[moduleId + '.'] === module;
|
606 | }
|
607 | return false;
|
608 | })
|
609 | .filter(function (expr) {
|
610 | return expr.arguments[0] &&
|
611 | expr.arguments[0].kind == SyntaxKind.ObjectLiteralExpression;
|
612 | })
|
613 | .map(function (expr) { return (expr.arguments[0]); });
|
614 | }
|
615 | /**
|
616 | * @param {?} node
|
617 | * @return {?}
|
618 | */
|
619 | function findClassDeclarationParent(node) {
|
620 | if (isClassDeclaration(node)) {
|
621 | return node;
|
622 | }
|
623 | return node.parent && findClassDeclarationParent(node.parent);
|
624 | }
|
625 | /**
|
626 | * Given a source file with \@NgModule class(es), find the name of the first \@NgModule class.
|
627 | *
|
628 | * @param {?} source source file containing one or more \@NgModule
|
629 | * @return {?} the name of the first \@NgModule, or `undefined` if none is found
|
630 | */
|
631 | function getFirstNgModuleName(source) {
|
632 | /** @type {?} */
|
633 | var ngModulesMetadata = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
634 | if (ngModulesMetadata.length === 0) {
|
635 | return undefined;
|
636 | }
|
637 | /** @type {?} */
|
638 | var moduleClass = findClassDeclarationParent(ngModulesMetadata[0]);
|
639 | if (!moduleClass || !moduleClass.name) {
|
640 | return undefined;
|
641 | }
|
642 | // Get the class name of the module ClassDeclaration.
|
643 | return moduleClass.name.text;
|
644 | }
|
645 | /**
|
646 | * @param {?} source
|
647 | * @param {?} ngModulePath
|
648 | * @param {?} metadataField
|
649 | * @param {?} symbolName
|
650 | * @param {?=} importPath
|
651 | * @return {?}
|
652 | */
|
653 | function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbolName, importPath) {
|
654 | if (importPath === void 0) { importPath = null; }
|
655 | /** @type {?} */
|
656 | var nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
657 | /** @type {?} */
|
658 | var node = nodes[0]; // tslint:disable-line:no-any
|
659 | // Find the decorator declaration.
|
660 | if (!node) {
|
661 | return [];
|
662 | }
|
663 | /** @type {?} */
|
664 | var matchingProperties = (/** @type {?} */ (node)).properties
|
665 | .filter(function (prop) { return prop.kind == SyntaxKind.PropertyAssignment; })
|
666 | // Filter out every fields that's not "metadataField". Also handles string literals
|
667 | // (but not expressions).
|
668 | .filter(function (prop) {
|
669 | /** @type {?} */
|
670 | var name = prop.name;
|
671 | switch (name.kind) {
|
672 | case SyntaxKind.Identifier:
|
673 | return (/** @type {?} */ (name)).getText(source) == metadataField;
|
674 | case SyntaxKind.StringLiteral:
|
675 | return (/** @type {?} */ (name)).text == metadataField;
|
676 | }
|
677 | return false;
|
678 | });
|
679 | // Get the last node of the array literal.
|
680 | if (!matchingProperties) {
|
681 | return [];
|
682 | }
|
683 | if (matchingProperties.length == 0) {
|
684 | /** @type {?} */
|
685 | var expr = /** @type {?} */ (node);
|
686 | /** @type {?} */
|
687 | var position_1 = void 0;
|
688 | /** @type {?} */
|
689 | var toInsert_1 = void 0;
|
690 | if (expr.properties.length == 0) {
|
691 | position_1 = expr.getEnd() - 1;
|
692 | toInsert_1 = " " + metadataField + ": [" + symbolName + "]\n";
|
693 | }
|
694 | else {
|
695 | node = expr.properties[expr.properties.length - 1];
|
696 | position_1 = node.getEnd();
|
697 | /** @type {?} */
|
698 | var text = node.getFullText(source);
|
699 | /** @type {?} */
|
700 | var matches = text.match(/^\r?\n\s*/);
|
701 | if (matches.length > 0) {
|
702 | toInsert_1 = "," + matches[0] + metadataField + ": [" + symbolName + "]";
|
703 | }
|
704 | else {
|
705 | toInsert_1 = ", " + metadataField + ": [" + symbolName + "]";
|
706 | }
|
707 | }
|
708 | if (importPath !== null) {
|
709 | return [
|
710 | new InsertChange(ngModulePath, position_1, toInsert_1),
|
711 | insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath)
|
712 | ];
|
713 | }
|
714 | else {
|
715 | return [new InsertChange(ngModulePath, position_1, toInsert_1)];
|
716 | }
|
717 | }
|
718 | /** @type {?} */
|
719 | var assignment = /** @type {?} */ (matchingProperties[0]);
|
720 | // If it's not an array, nothing we can do really.
|
721 | if (assignment.initializer.kind !== SyntaxKind.ArrayLiteralExpression) {
|
722 | return [];
|
723 | }
|
724 | /** @type {?} */
|
725 | var arrLiteral = /** @type {?} */ (assignment.initializer);
|
726 | if (arrLiteral.elements.length == 0) {
|
727 | // Forward the property.
|
728 | node = arrLiteral;
|
729 | }
|
730 | else {
|
731 | node = arrLiteral.elements;
|
732 | }
|
733 | if (!node) {
|
734 | console.log('No app module found. Please add your new class to your component.');
|
735 | return [];
|
736 | }
|
737 | if (Array.isArray(node)) {
|
738 | /** @type {?} */
|
739 | var nodeArray = /** @type {?} */ ((/** @type {?} */ (node)));
|
740 | /** @type {?} */
|
741 | var symbolsArray = nodeArray.map(function (node) { return node.getText(); });
|
742 | if (symbolsArray.indexOf(symbolName) >= 0) {
|
743 | return [];
|
744 | }
|
745 | node = node[node.length - 1];
|
746 | }
|
747 | /** @type {?} */
|
748 | var toInsert;
|
749 | /** @type {?} */
|
750 | var position = node.getEnd();
|
751 | if (node.kind == SyntaxKind.ObjectLiteralExpression) {
|
752 | /** @type {?} */
|
753 | var expr = /** @type {?} */ (node);
|
754 | if (expr.properties.length == 0) {
|
755 | position = expr.getEnd() - 1;
|
756 | toInsert = " " + metadataField + ": [" + symbolName + "]\n";
|
757 | }
|
758 | else {
|
759 | node = expr.properties[expr.properties.length - 1];
|
760 | position = node.getEnd();
|
761 | /** @type {?} */
|
762 | var text = node.getFullText(source);
|
763 | if (text.match('^\r?\r?\n')) {
|
764 | toInsert = "," + text.match(/^\r?\n\s+/)[0] + metadataField + ": [" + symbolName + "]";
|
765 | }
|
766 | else {
|
767 | toInsert = ", " + metadataField + ": [" + symbolName + "]";
|
768 | }
|
769 | }
|
770 | }
|
771 | else if (node.kind == SyntaxKind.ArrayLiteralExpression) {
|
772 | // We found the field but it's empty. Insert it just before the `]`.
|
773 | position--;
|
774 | toInsert = "" + symbolName;
|
775 | }
|
776 | else {
|
777 | /** @type {?} */
|
778 | var text = node.getFullText(source);
|
779 | if (text.match(/^\r?\n/)) {
|
780 | toInsert = "," + text.match(/^\r?\n(\r?)\s+/)[0] + symbolName;
|
781 | }
|
782 | else {
|
783 | toInsert = ", " + symbolName;
|
784 | }
|
785 | }
|
786 | if (importPath !== null) {
|
787 | return [
|
788 | new InsertChange(ngModulePath, position, toInsert),
|
789 | insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath)
|
790 | ];
|
791 | }
|
792 | return [new InsertChange(ngModulePath, position, toInsert)];
|
793 | }
|
794 | /**
|
795 | * Custom function to insert a declaration (component, pipe, directive)
|
796 | * into NgModule declarations. It also imports the component.
|
797 | * @param {?} source
|
798 | * @param {?} modulePath
|
799 | * @param {?} classifiedName
|
800 | * @param {?} importPath
|
801 | * @return {?}
|
802 | */
|
803 | function addDeclarationToModule(source, modulePath, classifiedName, importPath) {
|
804 | return addSymbolToNgModuleMetadata(source, modulePath, 'declarations', classifiedName, importPath);
|
805 | }
|
806 | /**
|
807 | * Custom function to insert an NgModule into NgModule imports. It also imports the module.
|
808 | * @param {?} source
|
809 | * @param {?} modulePath
|
810 | * @param {?} classifiedName
|
811 | * @param {?} importPath
|
812 | * @return {?}
|
813 | */
|
814 | function addImportToModule(source, modulePath, classifiedName, importPath) {
|
815 | return addSymbolToNgModuleMetadata(source, modulePath, 'imports', classifiedName, importPath);
|
816 | }
|
817 | /**
|
818 | * Custom function to insert a provider into NgModule. It also imports it.
|
819 | * @param {?} source
|
820 | * @param {?} modulePath
|
821 | * @param {?} classifiedName
|
822 | * @param {?} importPath
|
823 | * @return {?}
|
824 | */
|
825 | function addProviderToModule(source, modulePath, classifiedName, importPath) {
|
826 | return addSymbolToNgModuleMetadata(source, modulePath, 'providers', classifiedName, importPath);
|
827 | }
|
828 | /**
|
829 | * Custom function to insert an export into NgModule. It also imports it.
|
830 | * @param {?} source
|
831 | * @param {?} modulePath
|
832 | * @param {?} classifiedName
|
833 | * @param {?} importPath
|
834 | * @return {?}
|
835 | */
|
836 | function addExportToModule(source, modulePath, classifiedName, importPath) {
|
837 | return addSymbolToNgModuleMetadata(source, modulePath, 'exports', classifiedName, importPath);
|
838 | }
|
839 | /**
|
840 | * Custom function to insert an export into NgModule. It also imports it.
|
841 | * @param {?} source
|
842 | * @param {?} modulePath
|
843 | * @param {?} classifiedName
|
844 | * @param {?} importPath
|
845 | * @return {?}
|
846 | */
|
847 | function addBootstrapToModule(source, modulePath, classifiedName, importPath) {
|
848 | return addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath);
|
849 | }
|
850 | /**
|
851 | * Custom function to insert an entryComponent into NgModule. It also imports it.
|
852 | * @param {?} source
|
853 | * @param {?} modulePath
|
854 | * @param {?} classifiedName
|
855 | * @param {?} importPath
|
856 | * @return {?}
|
857 | */
|
858 | function addEntryComponentToModule(source, modulePath, classifiedName, importPath) {
|
859 | return addSymbolToNgModuleMetadata(source, modulePath, 'entryComponents', classifiedName, importPath);
|
860 | }
|
861 | /**
|
862 | * Determine if an import already exists.
|
863 | * @param {?} source
|
864 | * @param {?} classifiedName
|
865 | * @param {?} importPath
|
866 | * @return {?}
|
867 | */
|
868 | function isImported(source, classifiedName, importPath) {
|
869 | /** @type {?} */
|
870 | var allNodes = getSourceNodes(source);
|
871 | /** @type {?} */
|
872 | var matchingNodes = allNodes
|
873 | .filter(function (node) { return node.kind === SyntaxKind.ImportDeclaration; })
|
874 | .filter(function (imp) {
|
875 | return imp.moduleSpecifier.kind === SyntaxKind.StringLiteral;
|
876 | })
|
877 | .filter(function (imp) {
|
878 | return (/** @type {?} */ (imp.moduleSpecifier)).text === importPath;
|
879 | })
|
880 | .filter(function (imp) {
|
881 | if (!imp.importClause) {
|
882 | return false;
|
883 | }
|
884 | /** @type {?} */
|
885 | var nodes = findNodes(imp.importClause, SyntaxKind.ImportSpecifier).filter(function (n) { return n.getText() === classifiedName; });
|
886 | return nodes.length > 0;
|
887 | });
|
888 | return matchingNodes.length > 0;
|
889 | }
|
890 |
|
891 | /**
|
892 | * @fileoverview added by tsickle
|
893 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
894 | */
|
895 | /**
|
896 | * @param {?} host
|
897 | * @return {?}
|
898 | */
|
899 | function getWorkspacePath(host) {
|
900 | /** @type {?} */
|
901 | var possibleFiles = ['/angular.json', '/.angular.json'];
|
902 | /** @type {?} */
|
903 | var path = possibleFiles.filter(function (path) { return host.exists(path); })[0];
|
904 | return path;
|
905 | }
|
906 | /**
|
907 | * @param {?} host
|
908 | * @return {?}
|
909 | */
|
910 | function getWorkspace(host) {
|
911 | /** @type {?} */
|
912 | var path = getWorkspacePath(host);
|
913 | /** @type {?} */
|
914 | var configBuffer = host.read(path);
|
915 | if (configBuffer === null) {
|
916 | throw new SchematicsException("Could not find (" + path + ")");
|
917 | }
|
918 | /** @type {?} */
|
919 | var content = configBuffer.toString();
|
920 | return /** @type {?} */ ((parseJson(content, JsonParseMode.Loose)));
|
921 | }
|
922 | /**
|
923 | * @param {?} workspace
|
924 | * @param {?} name
|
925 | * @param {?} project
|
926 | * @return {?}
|
927 | */
|
928 | function addProjectToWorkspace(workspace, name, project) {
|
929 | return function (host, context) {
|
930 | if (workspace.projects[name]) {
|
931 | throw new Error("Project '" + name + "' already exists in workspace.");
|
932 | }
|
933 | // Add project to workspace.
|
934 | workspace.projects[name] = project;
|
935 | if (!workspace.defaultProject && Object.keys(workspace.projects).length === 1) {
|
936 | // Make the new project the default one.
|
937 | workspace.defaultProject = name;
|
938 | }
|
939 | host.overwrite(getWorkspacePath(host), JSON.stringify(workspace, null, 2));
|
940 | };
|
941 | }
|
942 | /** @type {?} */
|
943 | var configPath = '/.angular-cli.json';
|
944 | /**
|
945 | * @param {?} host
|
946 | * @return {?}
|
947 | */
|
948 | function getConfig(host) {
|
949 | /** @type {?} */
|
950 | var configBuffer = host.read(configPath);
|
951 | if (configBuffer === null) {
|
952 | throw new SchematicsException('Could not find .angular-cli.json');
|
953 | }
|
954 | /** @type {?} */
|
955 | var config = /** @type {?} */ ((parseJson(configBuffer.toString(), JsonParseMode.Loose)));
|
956 | return config;
|
957 | }
|
958 | /**
|
959 | * @param {?} config
|
960 | * @param {?} appIndexOrName
|
961 | * @return {?}
|
962 | */
|
963 | function getAppFromConfig(config, appIndexOrName) {
|
964 | if (!config.apps) {
|
965 | return null;
|
966 | }
|
967 | if (parseInt(appIndexOrName) >= 0) {
|
968 | return config.apps[parseInt(appIndexOrName)];
|
969 | }
|
970 | return config.apps.filter(function (app) { return app.name === appIndexOrName; })[0];
|
971 | }
|
972 |
|
973 | /**
|
974 | * @fileoverview added by tsickle
|
975 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
976 | */
|
977 | /**
|
978 | * @param {?} host
|
979 | * @param {?} mainPath
|
980 | * @return {?}
|
981 | */
|
982 | function findBootstrapModuleCall(host, mainPath) {
|
983 | var e_1, _a;
|
984 | /** @type {?} */
|
985 | var mainBuffer = host.read(mainPath);
|
986 | if (!mainBuffer) {
|
987 | throw new SchematicsException("Main file (" + mainPath + ") not found");
|
988 | }
|
989 | /** @type {?} */
|
990 | var mainText = mainBuffer.toString('utf-8');
|
991 | /** @type {?} */
|
992 | var source = createSourceFile(mainPath, mainText, ScriptTarget.Latest, true);
|
993 | /** @type {?} */
|
994 | var allNodes = getSourceNodes(source);
|
995 | /** @type {?} */
|
996 | var bootstrapCall = null;
|
997 | try {
|
998 | for (var allNodes_1 = __values(allNodes), allNodes_1_1 = allNodes_1.next(); !allNodes_1_1.done; allNodes_1_1 = allNodes_1.next()) {
|
999 | var node = allNodes_1_1.value;
|
1000 | /** @type {?} */
|
1001 | var bootstrapCallNode = null;
|
1002 | bootstrapCallNode = findNode(node, SyntaxKind.Identifier, 'bootstrapModule');
|
1003 | // Walk up the parent until CallExpression is found.
|
1004 | while (bootstrapCallNode && bootstrapCallNode.parent
|
1005 | && bootstrapCallNode.parent.kind !== SyntaxKind.CallExpression) {
|
1006 | bootstrapCallNode = bootstrapCallNode.parent;
|
1007 | }
|
1008 | if (bootstrapCallNode !== null &&
|
1009 | bootstrapCallNode.parent !== undefined &&
|
1010 | bootstrapCallNode.parent.kind === SyntaxKind.CallExpression) {
|
1011 | bootstrapCall = /** @type {?} */ (bootstrapCallNode.parent);
|
1012 | break;
|
1013 | }
|
1014 | }
|
1015 | }
|
1016 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
1017 | finally {
|
1018 | try {
|
1019 | if (allNodes_1_1 && !allNodes_1_1.done && (_a = allNodes_1.return)) _a.call(allNodes_1);
|
1020 | }
|
1021 | finally { if (e_1) throw e_1.error; }
|
1022 | }
|
1023 | return bootstrapCall;
|
1024 | }
|
1025 | /**
|
1026 | * @param {?} host
|
1027 | * @param {?} mainPath
|
1028 | * @return {?}
|
1029 | */
|
1030 | function findBootstrapModulePath(host, mainPath) {
|
1031 | /** @type {?} */
|
1032 | var bootstrapCall = findBootstrapModuleCall(host, mainPath);
|
1033 | if (!bootstrapCall) {
|
1034 | throw new SchematicsException('Bootstrap call not found');
|
1035 | }
|
1036 | /** @type {?} */
|
1037 | var bootstrapModule = bootstrapCall.arguments[0];
|
1038 | /** @type {?} */
|
1039 | var mainBuffer = host.read(mainPath);
|
1040 | if (!mainBuffer) {
|
1041 | throw new SchematicsException("Client app main file (" + mainPath + ") not found");
|
1042 | }
|
1043 | /** @type {?} */
|
1044 | var mainText = mainBuffer.toString('utf-8');
|
1045 | /** @type {?} */
|
1046 | var source = createSourceFile(mainPath, mainText, ScriptTarget.Latest, true);
|
1047 | /** @type {?} */
|
1048 | var allNodes = getSourceNodes(source);
|
1049 | /** @type {?} */
|
1050 | var bootstrapModuleRelativePath = allNodes
|
1051 | .filter(function (node) { return node.kind === SyntaxKind.ImportDeclaration; })
|
1052 | .filter(function (imp) {
|
1053 | return findNode(imp, SyntaxKind.Identifier, bootstrapModule.getText());
|
1054 | })
|
1055 | .map(function (imp) {
|
1056 | /** @type {?} */
|
1057 | var modulePathStringLiteral = /** @type {?} */ (imp.moduleSpecifier);
|
1058 | return modulePathStringLiteral.text;
|
1059 | })[0];
|
1060 | return bootstrapModuleRelativePath;
|
1061 | }
|
1062 | /**
|
1063 | * @param {?} host
|
1064 | * @param {?} mainPath
|
1065 | * @return {?}
|
1066 | */
|
1067 | function getAppModulePath(host, mainPath) {
|
1068 | /** @type {?} */
|
1069 | var moduleRelativePath = findBootstrapModulePath(host, mainPath);
|
1070 | /** @type {?} */
|
1071 | var mainDir = dirname(mainPath);
|
1072 | /** @type {?} */
|
1073 | var modulePath = normalize("/" + mainDir + "/" + moduleRelativePath + ".ts");
|
1074 | return modulePath;
|
1075 | }
|
1076 |
|
1077 | /**
|
1078 | * @fileoverview added by tsickle
|
1079 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1080 | */
|
1081 | /**
|
1082 | * @param {?} path
|
1083 | * @param {?} name
|
1084 | * @return {?}
|
1085 | */
|
1086 | function parseName(path, name) {
|
1087 | /** @type {?} */
|
1088 | var nameWithoutPath = basename(/** @type {?} */ (name));
|
1089 | /** @type {?} */
|
1090 | var namePath = dirname$1(/** @type {?} */ ((path + '/' + name)));
|
1091 | return {
|
1092 | name: nameWithoutPath,
|
1093 | path: normalize('/' + namePath),
|
1094 | };
|
1095 | }
|
1096 |
|
1097 | /**
|
1098 | * @fileoverview added by tsickle
|
1099 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1100 | */
|
1101 | /**
|
1102 | * @param {?} name
|
1103 | * @return {?}
|
1104 | */
|
1105 | function validateName(name) {
|
1106 | if (name && /^\d/.test(name)) {
|
1107 | throw new SchematicsException(tags.oneLine(templateObject_1 || (templateObject_1 = __makeTemplateObject(["name (", ")\n can not start with a digit."], ["name (", ")\n can not start with a digit."])), name));
|
1108 | }
|
1109 | }
|
1110 | /** @type {?} */
|
1111 | var htmlSelectorRe = /^[a-zA-Z][.0-9a-zA-Z]*(:?-[a-zA-Z][.0-9a-zA-Z]*)*$/;
|
1112 | /**
|
1113 | * @param {?} selector
|
1114 | * @return {?}
|
1115 | */
|
1116 | function validateHtmlSelector(selector) {
|
1117 | if (selector && !htmlSelectorRe.test(selector)) {
|
1118 | throw new SchematicsException(tags.oneLine(templateObject_2 || (templateObject_2 = __makeTemplateObject(["Selector (", ")\n is invalid."], ["Selector (", ")\n is invalid."])), selector));
|
1119 | }
|
1120 | }
|
1121 | /**
|
1122 | * @param {?} projectName
|
1123 | * @return {?}
|
1124 | */
|
1125 | function validateProjectName(projectName) {
|
1126 | /** @type {?} */
|
1127 | var errorIndex = getRegExpFailPosition(projectName);
|
1128 | /** @type {?} */
|
1129 | var unsupportedProjectNames = ['test', 'ember', 'ember-cli', 'vendor', 'app'];
|
1130 | /** @type {?} */
|
1131 | var packageNameRegex = /^(?:@[a-zA-Z0-9_-]+\/)?[a-zA-Z0-9_-]+$/;
|
1132 | if (errorIndex !== null) {
|
1133 | /** @type {?} */
|
1134 | var firstMessage = tags.oneLine(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n Project name \"", "\" is not valid. New project names must\n start with a letter, and must contain only alphanumeric characters or dashes.\n When adding a dash the segment after the dash must also start with a letter.\n "], ["\n Project name \"", "\" is not valid. New project names must\n start with a letter, and must contain only alphanumeric characters or dashes.\n When adding a dash the segment after the dash must also start with a letter.\n "])), projectName);
|
1135 | /** @type {?} */
|
1136 | var msg = tags.stripIndent(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n ", "\n ", "\n ", "\n "], ["\n ", "\n ", "\n ", "\n "])), firstMessage, projectName, Array(errorIndex + 1).join(' ') + '^');
|
1137 | throw new SchematicsException(msg);
|
1138 | }
|
1139 | else if (unsupportedProjectNames.indexOf(projectName) !== -1) {
|
1140 | throw new SchematicsException("Project name " + JSON.stringify(projectName) + " is not a supported name.");
|
1141 | }
|
1142 | else if (!packageNameRegex.test(projectName)) {
|
1143 | throw new SchematicsException("Project name " + JSON.stringify(projectName) + " is invalid.");
|
1144 | }
|
1145 | }
|
1146 | /**
|
1147 | * @param {?} str
|
1148 | * @return {?}
|
1149 | */
|
1150 | function getRegExpFailPosition(str) {
|
1151 | /** @type {?} */
|
1152 | var isScope = /^@.*\/.*/.test(str);
|
1153 | if (isScope) {
|
1154 | // Remove starting @
|
1155 | str = str.replace(/^@/, '');
|
1156 | // Change / to - for validation
|
1157 | str = str.replace(/\//g, '-');
|
1158 | }
|
1159 | /** @type {?} */
|
1160 | var parts = str.indexOf('-') >= 0 ? str.split('-') : [str];
|
1161 | /** @type {?} */
|
1162 | var matched = [];
|
1163 | /** @type {?} */
|
1164 | var projectNameRegexp = /^[a-zA-Z][.0-9a-zA-Z]*(-[.0-9a-zA-Z]*)*$/;
|
1165 | parts.forEach(function (part) {
|
1166 | if (part.match(projectNameRegexp)) {
|
1167 | matched.push(part);
|
1168 | }
|
1169 | });
|
1170 | /** @type {?} */
|
1171 | var compare = matched.join('-');
|
1172 | return (str !== compare) ? compare.length : null;
|
1173 | }
|
1174 | var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
|
1175 |
|
1176 | /**
|
1177 | * @fileoverview added by tsickle
|
1178 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1179 | */
|
1180 |
|
1181 | /**
|
1182 | * @fileoverview added by tsickle
|
1183 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1184 | */
|
1185 | /**
|
1186 | * @param {?} aUrl
|
1187 | * @return {?}
|
1188 | */
|
1189 | function _ensureTrailingSlash(aUrl) {
|
1190 | return aUrl.endsWith('/') ? aUrl : aUrl + '/';
|
1191 | }
|
1192 | /**
|
1193 | * @param {?} aUrl
|
1194 | * @return {?}
|
1195 | */
|
1196 | function _hasTrailingSlash(aUrl) {
|
1197 | return !!(aUrl && isString(aUrl) && aUrl.endsWith('/'));
|
1198 | }
|
1199 |
|
1200 | /**
|
1201 | * @fileoverview added by tsickle
|
1202 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1203 | */
|
1204 | /**
|
1205 | * @param {?} aValue
|
1206 | * @param {?=} aName
|
1207 | * @return {?}
|
1208 | */
|
1209 | function assertNotNull(aValue, aName) {
|
1210 | ok(aValue != null, aName
|
1211 | ? "Value [" + aName + "] must not be null or undefined."
|
1212 | : 'Value must not be null or undefined.');
|
1213 | }
|
1214 | /**
|
1215 | * @param {?} aValue
|
1216 | * @param {?} aParameterName
|
1217 | * @return {?}
|
1218 | */
|
1219 | function assertParameter(aValue, aParameterName) {
|
1220 | ok(!!aValue, "Please specify the '--" + aParameterName + "' parameter.");
|
1221 | }
|
1222 | /**
|
1223 | * @param {?} aValue
|
1224 | * @return {?}
|
1225 | */
|
1226 | function isValidUrl(aValue) {
|
1227 | return isString$1(aValue) && !!isWebUri(aValue);
|
1228 | }
|
1229 | /**
|
1230 | * @param {?} aValue
|
1231 | * @param {?=} aName
|
1232 | * @return {?}
|
1233 | */
|
1234 | function assertIsUrl(aValue, aName) {
|
1235 | ok(isValidUrl(aValue), aName
|
1236 | ? "Value [" + aName + "] must be a valid URL."
|
1237 | : 'Value must be a valid URL.');
|
1238 | return aValue;
|
1239 | }
|
1240 | /**
|
1241 | * @param {?} aValue
|
1242 | * @return {?}
|
1243 | */
|
1244 | function isValidEmail(aValue) {
|
1245 | return isString$1(aValue) && !!validate(aValue);
|
1246 | }
|
1247 | /**
|
1248 | * @param {?} aValue
|
1249 | * @return {?}
|
1250 | */
|
1251 | function isValidUserName(aValue) {
|
1252 | return isString$1(aValue) && (!!validate(aValue) || aValue === 'apikey');
|
1253 | }
|
1254 | /**
|
1255 | * @param {?} aValue
|
1256 | * @param {?=} aName
|
1257 | * @return {?}
|
1258 | */
|
1259 | function assertIsEmail(aValue, aName) {
|
1260 | ok(isValidEmail(aValue), aName
|
1261 | ? "Value [" + aName + "] must be a valid e-mail address."
|
1262 | : 'Value must be a valid e-mail address.');
|
1263 | return aValue;
|
1264 | }
|
1265 | /**
|
1266 | * @param {?} aValue
|
1267 | * @param {?=} aName
|
1268 | * @return {?}
|
1269 | */
|
1270 | function assertIsValidUserName(aValue, aName) {
|
1271 | ok(isValidUserName(aValue), aName
|
1272 | ? "Value [" + aName + "] must be a valid e-mail address or the term 'apikey'."
|
1273 | : "Value must be a valid e-mail address or the term 'apikey'.");
|
1274 | return aValue;
|
1275 | }
|
1276 | /**
|
1277 | * @param {?} aValue
|
1278 | * @return {?}
|
1279 | */
|
1280 | function assertHasTrailingSlash(aValue) {
|
1281 | ok(isValidUrl(aValue) && _hasTrailingSlash(aValue), 'URL [${aValue}] must end with a slash.');
|
1282 | return aValue;
|
1283 | }
|
1284 |
|
1285 | /**
|
1286 | * @fileoverview added by tsickle
|
1287 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1288 | */
|
1289 | /* Copyright IBM Corp. 2018 */
|
1290 | /** @type {?} */
|
1291 | var HEX_REGEXP_STRING = '[0-9a-fA-F]';
|
1292 | /** @type {?} */
|
1293 | var UUID_V4_REGEXP_STRING = HEX_REGEXP_STRING + "{8}-" + HEX_REGEXP_STRING + "{4}-4" + HEX_REGEXP_STRING + "{3}-[89abAB]" + HEX_REGEXP_STRING + "{3}-" + HEX_REGEXP_STRING + "{12}";
|
1294 | /** @type {?} */
|
1295 | var TENANT_BASED_URL = "^(?:\\/api)?\\/(" + UUID_V4_REGEXP_STRING + ")(?:\\/)?(?:.*)$";
|
1296 | /** @type {?} */
|
1297 | var TENANT_BASED_URL_REGEXP = new RegExp(TENANT_BASED_URL);
|
1298 |
|
1299 | /**
|
1300 | * @fileoverview added by tsickle
|
1301 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1302 | */
|
1303 | /** @type {?} */
|
1304 | var createXHR = function () {
|
1305 | /** @type {?} */
|
1306 | var XMLHttpRequest = require('xhr2');
|
1307 | return new XMLHttpRequest();
|
1308 | };
|
1309 | /** @type {?} */
|
1310 | var ajaxRequest = function (req) {
|
1311 | return ajax(__assign({}, req, { responseType: 'text', createXHR: createXHR })).pipe(map(function (resp) { return (resp.response); }));
|
1312 | };
|
1313 | /**
|
1314 | * @param {?} aUri
|
1315 | * @return {?}
|
1316 | */
|
1317 | function rxGet(aUri) {
|
1318 | // setup the request
|
1319 | return ajaxRequest({
|
1320 | url: aUri
|
1321 | });
|
1322 | }
|
1323 | /**
|
1324 | * @param {?} aUri
|
1325 | * @return {?}
|
1326 | */
|
1327 | function rxGetJson(aUri) {
|
1328 | return rxGet(aUri).pipe(map(function (data) { return JSON.parse(data); }));
|
1329 | }
|
1330 | /**
|
1331 | * @param {?} aUri
|
1332 | * @param {?} aData
|
1333 | * @return {?}
|
1334 | */
|
1335 | function rxFormPost(aUri, aData) {
|
1336 | // setup the request
|
1337 | return ajaxRequest({
|
1338 | method: 'POST',
|
1339 | url: aUri,
|
1340 | body: aData
|
1341 | });
|
1342 | }
|
1343 |
|
1344 | /**
|
1345 | * @fileoverview added by tsickle
|
1346 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1347 | */
|
1348 | /**
|
1349 | * @param {?} aPath
|
1350 | * @return {?}
|
1351 | */
|
1352 | function rxReadFile(aPath) {
|
1353 | return Observable.create(function (observer) {
|
1354 | readFile(aPath, 'utf-8', function (err, data) {
|
1355 | if (err) {
|
1356 | observer.error(err);
|
1357 | }
|
1358 | else {
|
1359 | observer.next(data);
|
1360 | observer.complete();
|
1361 | }
|
1362 | });
|
1363 | });
|
1364 | }
|
1365 |
|
1366 | /**
|
1367 | * @fileoverview added by tsickle
|
1368 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1369 | */
|
1370 | /**
|
1371 | * @param {?=} aCred
|
1372 | * @return {?}
|
1373 | */
|
1374 | function _isValidCredential(aCred) {
|
1375 | return !!(aCred &&
|
1376 | isValidUserName(aCred.username) &&
|
1377 | isString(aCred.password));
|
1378 | }
|
1379 | /**
|
1380 | * @return {?}
|
1381 | */
|
1382 | function _emptyCredentials() {
|
1383 | return {
|
1384 | username: '',
|
1385 | password: ''
|
1386 | };
|
1387 | }
|
1388 | /**
|
1389 | * @return {?}
|
1390 | */
|
1391 | function _getCredentialsFromEnvironment() {
|
1392 | /** @type {?} */
|
1393 | var username = env['ibm_wch_sdk_cli_username'] || '';
|
1394 | /** @type {?} */
|
1395 | var password = env['ibm_wch_sdk_cli_password'] || '';
|
1396 | // construct
|
1397 | return { username: username, password: password };
|
1398 | }
|
1399 | /**
|
1400 | * Merge different credentials layers
|
1401 | *
|
1402 | * @param {?} aBase base layer
|
1403 | * @param {?=} aOverride override layer
|
1404 | *
|
1405 | * @return {?} the merged credentials
|
1406 | */
|
1407 | function _mergeCredentials(aBase, aOverride) {
|
1408 | // target
|
1409 | if (!aOverride) {
|
1410 | return aBase;
|
1411 | }
|
1412 | /** @type {?} */
|
1413 | var cred = cloneDeep(aBase);
|
1414 | // override
|
1415 | if (!!aOverride.username) {
|
1416 | cred.username = aOverride.username;
|
1417 | }
|
1418 | if (!!aOverride.password) {
|
1419 | cred.password = aOverride.password;
|
1420 | }
|
1421 | // ok
|
1422 | return cred;
|
1423 | }
|
1424 | /** @type {?} */
|
1425 | var PADDING_MODE = RSA_PKCS1_PADDING;
|
1426 | /**
|
1427 | * @return {?}
|
1428 | */
|
1429 | function _loadPrivateKey() {
|
1430 | /** @type {?} */
|
1431 | var name = join$1(homedir(), '.ssh', 'id_rsa');
|
1432 | return rxReadFile(name).pipe(map(function (key) { return ({ key: key, padding: PADDING_MODE }); }));
|
1433 | }
|
1434 | /** @type {?} */
|
1435 | var ENCRYPTED_ENCODING = 'base64';
|
1436 | /** @type {?} */
|
1437 | var DECTYPTED_ENCODING = 'utf8';
|
1438 | /**
|
1439 | * @param {?} aHash
|
1440 | * @param {?} aKey
|
1441 | * @return {?}
|
1442 | */
|
1443 | function _decryptPassword(aHash, aKey) {
|
1444 | return privateDecrypt(aKey, Buffer.from(aHash, ENCRYPTED_ENCODING)).toString(DECTYPTED_ENCODING);
|
1445 | }
|
1446 | /**
|
1447 | * @param {?} aApiBase
|
1448 | * @return {?}
|
1449 | */
|
1450 | function _loadCredentials(aApiBase) {
|
1451 | // validate the URL
|
1452 | assertHasTrailingSlash(aApiBase);
|
1453 | /** @type {?} */
|
1454 | var filename = join$1(homedir(), '.ibm-wch-sdk-cli', '.credentials');
|
1455 | /** @type {?} */
|
1456 | var key = _loadPrivateKey();
|
1457 | // load the file
|
1458 | return rxReadFile(filename).pipe(map(function (data) { return JSON.parse(data); }), map(function (data) { return data[aApiBase]; }), mergeMap(function (cred) {
|
1459 | return key.pipe(map(function (k) { return _decryptPassword(cred.password, k); }), map(function (p) {
|
1460 | cred.password = p;
|
1461 | return cred;
|
1462 | }));
|
1463 | }), catchError(function () { return of(_emptyCredentials()); }));
|
1464 | }
|
1465 | /**
|
1466 | * @param {?} aApiUrl
|
1467 | * @return {?}
|
1468 | */
|
1469 | function _getWindowsCredentials(aApiUrl) {
|
1470 | // validate the URL
|
1471 | assertHasTrailingSlash(aApiUrl);
|
1472 | /** @type {?} */
|
1473 | var path = normalize$1(join$1(__dirname, '..', '..', '..', 'assets', 'credman', process.arch, 'WchCredMan.exe'));
|
1474 | /** @type {?} */
|
1475 | var cmd = "\"" + path + "\" \"" + aApiUrl + "\"";
|
1476 | // construct the observable
|
1477 | return Observable.create(function (observer) {
|
1478 | // execute the command
|
1479 | exec(cmd, {
|
1480 | encoding: 'utf8'
|
1481 | }, function (error, stdout, stderr) {
|
1482 | if (error) {
|
1483 | observer.error(error);
|
1484 | }
|
1485 | else {
|
1486 | try {
|
1487 | // parse
|
1488 | observer.next(JSON.parse(stdout));
|
1489 | observer.complete();
|
1490 | }
|
1491 | catch (e) {
|
1492 | observer.error(e);
|
1493 | }
|
1494 | }
|
1495 | });
|
1496 | });
|
1497 | }
|
1498 | /**
|
1499 | * @param {?} aApiUrl
|
1500 | * @return {?}
|
1501 | */
|
1502 | function _getStoredCredentials(aApiUrl) {
|
1503 | /** @type {?} */
|
1504 | var key = _ensureTrailingSlash(aApiUrl);
|
1505 | // normalize the URL
|
1506 | if (platform() === 'win32') {
|
1507 | // load the credentials module
|
1508 | return _getWindowsCredentials(key).pipe(mergeMap(function (cred) {
|
1509 | return _isValidCredential(cred) ? of(cred) : _loadCredentials(key);
|
1510 | }), catchError(function () { return _loadCredentials(key); }));
|
1511 | }
|
1512 | // linux like fallback
|
1513 | return _loadCredentials(key);
|
1514 | }
|
1515 | /**
|
1516 | * @param {?} aApiUrl
|
1517 | * @return {?}
|
1518 | */
|
1519 | function wchToolsGetCredentials(aApiUrl) {
|
1520 | // return
|
1521 | return _getStoredCredentials(aApiUrl).pipe(map(function (cred) { return _mergeCredentials(_getCredentialsFromEnvironment(), cred); }), catchError(function (err) { return of(_getCredentialsFromEnvironment()); }));
|
1522 | }
|
1523 |
|
1524 | /**
|
1525 | * @fileoverview added by tsickle
|
1526 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1527 | */
|
1528 | /** @enum {number} */
|
1529 | var DEP_TYPE = {
|
1530 | PEER: 0,
|
1531 | RUNTIME: 1,
|
1532 | DEVELOPMENT: 2,
|
1533 | };
|
1534 | DEP_TYPE[DEP_TYPE.PEER] = 'PEER';
|
1535 | DEP_TYPE[DEP_TYPE.RUNTIME] = 'RUNTIME';
|
1536 | DEP_TYPE[DEP_TYPE.DEVELOPMENT] = 'DEVELOPMENT';
|
1537 | /**
|
1538 | * @param {?=} aType
|
1539 | * @return {?}
|
1540 | */
|
1541 | function getFolderForType(aType) {
|
1542 | return aType === DEP_TYPE.PEER
|
1543 | ? 'peerDependencies'
|
1544 | : aType === DEP_TYPE.DEVELOPMENT
|
1545 | ? 'devDependencies'
|
1546 | : 'dependencies';
|
1547 | }
|
1548 | /**
|
1549 | * Updates the package JSON to use at least the given version
|
1550 | *
|
1551 | * @param {?} aName name
|
1552 | * @param {?} aMinVersion min version
|
1553 | * @param {?} aPkg package
|
1554 | * @param {?=} aType
|
1555 | * @return {?}
|
1556 | */
|
1557 | function updateMinVersion(aName, aMinVersion, aPkg, aType) {
|
1558 | /** @type {?} */
|
1559 | var folder = getFolderForType(aType);
|
1560 | /** @type {?} */
|
1561 | var deps = /** @type {?} */ (assertObject(folder, aPkg));
|
1562 | /** @type {?} */
|
1563 | var oldDep = deps[aName];
|
1564 | if (isNil(oldDep) || !satisfies(aMinVersion, oldDep)) {
|
1565 | // just update
|
1566 | deps[aName] = "^" + aMinVersion;
|
1567 | }
|
1568 | // ok
|
1569 | return aPkg;
|
1570 | }
|
1571 | /** @type {?} */
|
1572 | var rxReadFile$1 = bindNodeCallback(readFile);
|
1573 | /**
|
1574 | * @param {?} aDir
|
1575 | * @return {?}
|
1576 | */
|
1577 | function findPackageJson(aDir) {
|
1578 | // read
|
1579 | return rxReadFile$1(join$1(aDir, 'package.json'), 'utf-8').pipe(map(function (data) { return JSON.parse(data); }), catchError(function (err) { return findPackageJson(parse(aDir).dir); }));
|
1580 | }
|
1581 |
|
1582 | /**
|
1583 | * @fileoverview added by tsickle
|
1584 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1585 | */
|
1586 |
|
1587 | /**
|
1588 | * @fileoverview added by tsickle
|
1589 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1590 | */
|
1591 | /**
|
1592 | * @param {?} aPassword
|
1593 | * @return {?}
|
1594 | */
|
1595 | function _isValidPassword(aPassword) {
|
1596 | return aPassword && aPassword.length > 0;
|
1597 | }
|
1598 | /**
|
1599 | * @param {?} aApiUrl
|
1600 | * @param {?} aError
|
1601 | * @return {?}
|
1602 | */
|
1603 | function _throwInvalidUrl(aApiUrl, aError) {
|
1604 | return throwError(new VError(aError, 'The API URL [%s] is not a valid WCH API URL.', aApiUrl));
|
1605 | }
|
1606 | /**
|
1607 | * @param {?} aApiUrl
|
1608 | * @return {?}
|
1609 | */
|
1610 | function _getCurrentUser(aApiUrl) {
|
1611 | /** @type {?} */
|
1612 | var currentUserUrl = "" + aApiUrl + REL_PATH_CURRENT_USER;
|
1613 | return rxGetJson(currentUserUrl).pipe(catchError(function (error) { return _throwInvalidUrl(aApiUrl, error); }));
|
1614 | }
|
1615 | /**
|
1616 | * @param {?} aApiUrl
|
1617 | * @return {?}
|
1618 | */
|
1619 | function _throwInvalidCredentials(aApiUrl) {
|
1620 | return throwError(new VError('Unable to access credentials for the API URL [%s]. Please follow the directions on https://www.npmjs.com/package/ibm-wch-sdk-cli#credential-management to register credentials.', aApiUrl));
|
1621 | }
|
1622 | /**
|
1623 | * @param {?} aApiUrl
|
1624 | * @param {?} aCredentials
|
1625 | * @return {?}
|
1626 | */
|
1627 | function validateCredentials(aApiUrl, aCredentials) {
|
1628 | var _a;
|
1629 | // check the credentials object
|
1630 | if (!aCredentials ||
|
1631 | !isValidUserName(aCredentials.username) ||
|
1632 | !_isValidPassword(aCredentials.password)) {
|
1633 | return _throwInvalidCredentials(aApiUrl);
|
1634 | }
|
1635 | /** @type {?} */
|
1636 | var loginUrl = "" + aApiUrl + REL_PATH_BASICAUTH_LOGIN;
|
1637 | /** @type {?} */
|
1638 | var body = (_a = {},
|
1639 | _a[KEY_BASICAUTH_LOGIN_USERNAME] = aCredentials.username,
|
1640 | _a[KEY_BASICAUTH_LOGIN_PASSWORD] = aCredentials.password,
|
1641 | _a);
|
1642 | // execute
|
1643 | return rxFormPost(loginUrl, body).pipe(map(function (data) { return JSON.parse(data); }), catchError(function (error) {
|
1644 | return throwError(new VError(error, 'Unable to login to [%s] with user [%s]. Please check your registered password.', loginUrl, aCredentials.username));
|
1645 | }), mapTo(aApiUrl));
|
1646 | }
|
1647 | /**
|
1648 | * @param {?} aFeed
|
1649 | * @return {?}
|
1650 | */
|
1651 | function _validateUser(aFeed) {
|
1652 | // test the feed result
|
1653 | if (!aFeed || !aFeed.externalId) {
|
1654 | return throwError(new VError('Invalid currentuser response'));
|
1655 | }
|
1656 | return of(aFeed);
|
1657 | }
|
1658 | /**
|
1659 | * Tests if the API URL is valid and if we have sufficient credentials to access the API
|
1660 | *
|
1661 | * @param {?} aUrl the API URL
|
1662 | * @param {?} bValidateWithCredentials
|
1663 | * @return {?} the url
|
1664 | */
|
1665 | function validateApiUrl(aUrl, bValidateWithCredentials) {
|
1666 | // check if the URL is valud
|
1667 | if (!isUri(aUrl)) {
|
1668 | return throwError(new VError('Please enter a valid API URL. Copy this URL from the "Hub Information" section of your WCH tenant.'));
|
1669 | }
|
1670 | /** @type {?} */
|
1671 | var normUrl = _ensureTrailingSlash(aUrl);
|
1672 | if (bValidateWithCredentials) {
|
1673 | /** @type {?} */
|
1674 | var onCredentials = wchToolsGetCredentials(normUrl).pipe(catchError(function (error) { return _throwInvalidCredentials(normUrl); }));
|
1675 | /** @type {?} */
|
1676 | var onValidUrl = _getCurrentUser(normUrl).pipe(switchMap(_validateUser), switchMapTo(onCredentials), switchMap(function (cred) { return validateCredentials(normUrl, cred); }));
|
1677 | // ok
|
1678 | return onValidUrl;
|
1679 | }
|
1680 | else {
|
1681 | /** @type {?} */
|
1682 | var onValidUrl = _getCurrentUser(normUrl).pipe(switchMap(_validateUser), mapTo(normUrl));
|
1683 | // ok
|
1684 | return onValidUrl;
|
1685 | }
|
1686 | }
|
1687 | /** @type {?} */
|
1688 | var PACKAGE_JSON = /** @type {?} */ ('/package.json');
|
1689 | /** @type {?} */
|
1690 | var FALLBACK = /** @type {?} */ ('/data');
|
1691 | /** @type {?} */
|
1692 | var OPTIONS = /** @type {?} */ ('.wchtoolsoptions.json');
|
1693 | /** @type {?} */
|
1694 | var SDK_IMPORT = '@ibm-wch-sdk/ng';
|
1695 | /** @type {?} */
|
1696 | var CLI_IMPORT = '@ibm-wch-sdk/cli';
|
1697 | /** @type {?} */
|
1698 | var WCHTOOLS_DEPENDENCIES = 'wchtools-dependencies';
|
1699 | /**
|
1700 | * @return {?}
|
1701 | */
|
1702 | function _findBuildVersion() {
|
1703 | // find the package
|
1704 | return findPackageJson(__dirname).pipe(pluck('version'));
|
1705 | }
|
1706 | /**
|
1707 | * Decode the version from the dependency
|
1708 | *
|
1709 | * @param {?} aVersion the version
|
1710 | *
|
1711 | * @return {?} observable of the version
|
1712 | */
|
1713 | function _fromDependency(aVersion) {
|
1714 | /** @type {?} */
|
1715 | var parsed = coerce(aVersion);
|
1716 | return !!parsed ? of(parsed.version) : _findBuildVersion();
|
1717 | }
|
1718 | /**
|
1719 | * @param {?} host
|
1720 | * @return {?}
|
1721 | */
|
1722 | function findSdkVersion(host) {
|
1723 | /** @type {?} */
|
1724 | var buf = host.read(PACKAGE_JSON);
|
1725 | if (isNil(buf)) {
|
1726 | return _findBuildVersion();
|
1727 | }
|
1728 | /** @type {?} */
|
1729 | var pkg = JSON.parse(buf.toString());
|
1730 | /** @type {?} */
|
1731 | var deps = pkg.dependencies || {};
|
1732 | /** @type {?} */
|
1733 | var devDeps = pkg.devDependencies || {};
|
1734 | /** @type {?} */
|
1735 | var fromPkg = deps[SDK_IMPORT] || devDeps[CLI_IMPORT];
|
1736 | return isNotNil(fromPkg) ? _fromDependency(fromPkg) : _findBuildVersion();
|
1737 | }
|
1738 | /**
|
1739 | * @param {?} host
|
1740 | * @return {?}
|
1741 | */
|
1742 | function findDataDir(host) {
|
1743 | /** @type {?} */
|
1744 | var buf = host.read(PACKAGE_JSON);
|
1745 | if (isNil(buf)) {
|
1746 | return FALLBACK;
|
1747 | }
|
1748 | /** @type {?} */
|
1749 | var pkg = JSON.parse(buf.toString());
|
1750 | /** @type {?} */
|
1751 | var cfg = pkg.config || {};
|
1752 | /** @type {?} */
|
1753 | var data = cfg.data || FALLBACK;
|
1754 | return resolve(/** @type {?} */ ('/'), data);
|
1755 | }
|
1756 | /**
|
1757 | * @param {?} host
|
1758 | * @return {?}
|
1759 | */
|
1760 | function findWchToolsOptions(host) {
|
1761 | return resolve(findDataDir(host), OPTIONS);
|
1762 | }
|
1763 | /**
|
1764 | * @param {?} aDeps
|
1765 | * @param {?} aPkg
|
1766 | * @return {?}
|
1767 | */
|
1768 | function addToWchToolsDependencies(aDeps, aPkg) {
|
1769 | /** @type {?} */
|
1770 | var deps = assertArray(WCHTOOLS_DEPENDENCIES, aPkg);
|
1771 | // filter
|
1772 | deps.push.apply(deps, __spread(aDeps.filter(function (dep) { return deps.indexOf(dep) < 0; })));
|
1773 | }
|
1774 |
|
1775 | /**
|
1776 | * @fileoverview added by tsickle
|
1777 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1778 | */
|
1779 | /** @type {?} */
|
1780 | var _keys = Object.keys;
|
1781 | /** @type {?} */
|
1782 | var KEY_WEIGHTS = {
|
1783 | name: 1,
|
1784 | description: 2,
|
1785 | id: 3,
|
1786 | classification: 4
|
1787 | };
|
1788 | /**
|
1789 | * @param {?} aLeft
|
1790 | * @param {?} aRight
|
1791 | * @return {?}
|
1792 | */
|
1793 | function _compareNumber(aLeft, aRight) {
|
1794 | return aLeft < aRight ? -1 : aLeft > aRight ? +1 : 0;
|
1795 | }
|
1796 | /**
|
1797 | * @param {?} aName
|
1798 | * @return {?}
|
1799 | */
|
1800 | function _getKey(aName) {
|
1801 | return KEY_WEIGHTS[aName] || Number.MAX_SAFE_INTEGER;
|
1802 | }
|
1803 | /**
|
1804 | * @param {?} aLeft
|
1805 | * @param {?} aRight
|
1806 | * @return {?}
|
1807 | */
|
1808 | function _compareName(aLeft, aRight) {
|
1809 | /** @type {?} */
|
1810 | var c = _compareNumber(_getKey(aLeft), _getKey(aRight));
|
1811 | if (c === 0) {
|
1812 | c = aLeft.localeCompare(aRight);
|
1813 | }
|
1814 | // ok
|
1815 | return c;
|
1816 | }
|
1817 | /**
|
1818 | * @param {?} aData
|
1819 | * @return {?}
|
1820 | */
|
1821 | function _canonicalize(aData) {
|
1822 | // handle
|
1823 | if (isArray(aData)) {
|
1824 | /** @type {?} */
|
1825 | var copy_1 = [];
|
1826 | aData.forEach(function (v) { return copy_1.push(_canonicalize(v)); });
|
1827 | return copy_1;
|
1828 | }
|
1829 | if (isPlainObject(aData)) {
|
1830 | /** @type {?} */
|
1831 | var copy_2 = {};
|
1832 | _keys(aData)
|
1833 | .sort(_compareName)
|
1834 | .forEach(function (k) { return (copy_2[k] = _canonicalize(aData[k])); });
|
1835 | return copy_2;
|
1836 | }
|
1837 | // nothing to do
|
1838 | return aData;
|
1839 | }
|
1840 | /**
|
1841 | * @param {?} aData
|
1842 | * @return {?}
|
1843 | */
|
1844 | function serializeJson(aData) {
|
1845 | return aData ? JSON.stringify(aData, undefined, 2) : undefined;
|
1846 | }
|
1847 | /**
|
1848 | * @param {?} aName
|
1849 | * @param {?} aGenerator
|
1850 | * @param {?} aObj
|
1851 | * @return {?}
|
1852 | */
|
1853 | function updateField(aName, aGenerator, aObj) {
|
1854 | /** @type {?} */
|
1855 | var oldValue = aObj[aName];
|
1856 | if (isNil(oldValue)) {
|
1857 | // update with the generated value
|
1858 | aObj[aName] = aGenerator();
|
1859 | }
|
1860 | return aObj;
|
1861 | }
|
1862 |
|
1863 | /**
|
1864 | * @fileoverview added by tsickle
|
1865 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1866 | */
|
1867 | /**
|
1868 | * @param {?=} aSource
|
1869 | * @return {?}
|
1870 | */
|
1871 | function serializeLines(aSource) {
|
1872 | return aSource ? aSource.join('\n') : undefined;
|
1873 | }
|
1874 | /**
|
1875 | * @param {?=} aSource
|
1876 | * @return {?}
|
1877 | */
|
1878 | function parseLines(aSource) {
|
1879 | return aSource ? aSource.split('\n') : [];
|
1880 | }
|
1881 | /**
|
1882 | * @param {?} aSource
|
1883 | * @param {?} aInsert
|
1884 | * @return {?}
|
1885 | */
|
1886 | function insertLines(aSource, aInsert) {
|
1887 | if (aSource) {
|
1888 | /** @type {?} */
|
1889 | var existing_1 = new Set(aSource);
|
1890 | return __spread(aSource, aInsert.filter(function (line) { return !existing_1.has(line); }));
|
1891 | }
|
1892 | else {
|
1893 | // just insert into the empty file
|
1894 | return __spread(aInsert);
|
1895 | }
|
1896 | }
|
1897 |
|
1898 | /**
|
1899 | * @fileoverview added by tsickle
|
1900 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1901 | */
|
1902 | /**
|
1903 | * Reads a text file from the tree and then transforms it using the given function. If the result
|
1904 | * is null or undefined, the file will be deleted, else replaced or created.
|
1905 | *
|
1906 | * @param {?} aName name of the file
|
1907 | * @param {?} aOp the operator
|
1908 | * @param {?} aTree the tree to work in
|
1909 | * @return {?}
|
1910 | */
|
1911 | function rxTransformTextFile(aName, aOp, aTree) {
|
1912 | /** @type {?} */
|
1913 | var buffer = aTree.read(aName);
|
1914 | /** @type {?} */
|
1915 | var value = isNotNil(buffer) ? buffer.toString() : null;
|
1916 | /** @type {?} */
|
1917 | var op = /** @type {?} */ (aOp);
|
1918 | // replace
|
1919 | return op(value, aName).pipe(first(), map(function (result) {
|
1920 | return isNotNil(result)
|
1921 | ? isNotNil(buffer)
|
1922 | ? aTree.overwrite(aName, result)
|
1923 | : aTree.create(aName, result)
|
1924 | : isNotNil(buffer)
|
1925 | ? aTree.delete(aName)
|
1926 | : undefined;
|
1927 | }), mapTo(aName));
|
1928 | }
|
1929 | /**
|
1930 | * Reads a JSON file from the tree and then transforms it using the given function. If the result
|
1931 | * is null or undefined, the file will be deleted, else replaced or created.
|
1932 | *
|
1933 | * @param {?} aName name of the file
|
1934 | * @param {?} aOp the operator
|
1935 | * @param {?} aTree the tree to work in
|
1936 | * @return {?}
|
1937 | */
|
1938 | function rxTransformJsonFile(aName, aOp, aTree) {
|
1939 | /** @type {?} */
|
1940 | var op = /** @type {?} */ (aOp);
|
1941 | // dispatch
|
1942 | return rxTransformTextFile(aName, function (textContent, path) {
|
1943 | return op(textContent ? JSON.parse(textContent) : undefined, path).pipe(map(_canonicalize), map(serializeJson));
|
1944 | }, aTree);
|
1945 | }
|
1946 | /**
|
1947 | * Reads a line based file from the tree and then transforms it using the given function. If the result
|
1948 | * is null or undefined, the file will be deleted, else replaced or created.
|
1949 | *
|
1950 | * @param {?} aName name of the file
|
1951 | * @param {?} aOp the operator
|
1952 | * @param {?} aTree the tree to work in
|
1953 | * @return {?}
|
1954 | */
|
1955 | function rxTransformLinesFile(aName, aOp, aTree) {
|
1956 | /** @type {?} */
|
1957 | var op = /** @type {?} */ (aOp);
|
1958 | // dispatch
|
1959 | return rxTransformTextFile(aName, function (textContent, path) {
|
1960 | return op(textContent ? parseLines(textContent) : undefined, path).pipe(map(serializeLines));
|
1961 | }, aTree);
|
1962 | }
|
1963 |
|
1964 | /**
|
1965 | * @fileoverview added by tsickle
|
1966 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
1967 | */
|
1968 | /**
|
1969 | * @param {?} aName
|
1970 | * @param {?} aCount
|
1971 | * @return {?}
|
1972 | */
|
1973 | function _skipPrefix(aName, aCount) {
|
1974 | /** @type {?} */
|
1975 | var idx = 0;
|
1976 | for (var i = 0; i < aCount; ++i) {
|
1977 | /** @type {?} */
|
1978 | var nextIdx = aName.indexOf('/', idx);
|
1979 | if (nextIdx >= idx) {
|
1980 | idx = nextIdx + 1;
|
1981 | }
|
1982 | else {
|
1983 | return null;
|
1984 | }
|
1985 | }
|
1986 | // split
|
1987 | return aName.substring(idx);
|
1988 | }
|
1989 | var StreamOnBuffer = /** @class */ (function (_super) {
|
1990 | __extends(StreamOnBuffer, _super);
|
1991 | function StreamOnBuffer() {
|
1992 | var _this = _super !== null && _super.apply(this, arguments) || this;
|
1993 | _this.buffers = [];
|
1994 | return _this;
|
1995 | }
|
1996 | /**
|
1997 | * @param {?} chunk
|
1998 | * @param {?} encoding
|
1999 | * @param {?} callback
|
2000 | * @return {?}
|
2001 | */
|
2002 | StreamOnBuffer.prototype._write = /**
|
2003 | * @param {?} chunk
|
2004 | * @param {?} encoding
|
2005 | * @param {?} callback
|
2006 | * @return {?}
|
2007 | */
|
2008 | function (chunk, encoding, callback) {
|
2009 | this.buffers.push(chunk);
|
2010 | callback();
|
2011 | };
|
2012 | /**
|
2013 | * @param {?} callback
|
2014 | * @return {?}
|
2015 | */
|
2016 | StreamOnBuffer.prototype._final = /**
|
2017 | * @param {?} callback
|
2018 | * @return {?}
|
2019 | */
|
2020 | function (callback) {
|
2021 | callback();
|
2022 | this.emit('close');
|
2023 | };
|
2024 | return StreamOnBuffer;
|
2025 | }(Writable));
|
2026 | /**
|
2027 | * @param {?} aTree
|
2028 | * @param {?} aEntry
|
2029 | * @param {?} aDstDir
|
2030 | * @param {?} aSkip
|
2031 | * @return {?}
|
2032 | */
|
2033 | function _rxExtractEntry(aTree, aEntry, aDstDir, aSkip) {
|
2034 | /** @type {?} */
|
2035 | var path = _skipPrefix(aEntry.path, aSkip);
|
2036 | if (!path) {
|
2037 | // nothing
|
2038 | return of('').pipe(tap(function () { return aEntry.autodrain(); }), filter(function () { return false; }));
|
2039 | }
|
2040 | /** @type {?} */
|
2041 | var fileName = normalize$1(join$1(aDstDir, path));
|
2042 | // handle directories
|
2043 | if (aEntry.type === 'Directory') {
|
2044 | // create the directory
|
2045 | return of('').pipe(tap(function () { return aEntry.autodrain(); }), filter(function () { return false; }));
|
2046 | }
|
2047 | else {
|
2048 | /** @type {?} */
|
2049 | var stream_1 = aEntry.pipe(new StreamOnBuffer());
|
2050 | // attach
|
2051 | return fromEvent(stream_1, 'close').pipe(
|
2052 | // just take one
|
2053 | first(),
|
2054 | // copy into the tree
|
2055 | map(function () { return aTree.create(fileName, Buffer.concat(stream_1.buffers)); }),
|
2056 | // map to the target name
|
2057 | mapTo(fileName));
|
2058 | }
|
2059 | }
|
2060 | /**
|
2061 | * @param {?} aTree
|
2062 | * @param {?} aSrcUrl
|
2063 | * @param {?} aDstDir
|
2064 | * @param {?=} aSkip
|
2065 | * @return {?}
|
2066 | */
|
2067 | function rxUnzipFromUrl(aTree, aSrcUrl, aDstDir, aSkip) {
|
2068 | if (aSkip === void 0) { aSkip = 0; }
|
2069 | // defer
|
2070 | return defer(function () {
|
2071 | /** @type {?} */
|
2072 | var stream = get(aSrcUrl).pipe(Parse());
|
2073 | /** @type {?} */
|
2074 | var onEntry = fromEvent(stream, 'entry');
|
2075 | /** @type {?} */
|
2076 | var onClose = fromEvent(stream, 'close');
|
2077 | // return the full stream
|
2078 | return onEntry.pipe(takeUntil(onClose), mergeMap(function (entry) { return _rxExtractEntry(aTree, entry, aDstDir, aSkip); }));
|
2079 | });
|
2080 | }
|
2081 |
|
2082 | /**
|
2083 | * @fileoverview added by tsickle
|
2084 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2085 | */
|
2086 | /**
|
2087 | * @param {?=} aString
|
2088 | * @return {?}
|
2089 | */
|
2090 | function _parseHtml(aString) {
|
2091 | return of(load(isNotNil(aString) ? /** @type {?} */ ((aString)) : ''));
|
2092 | }
|
2093 | /**
|
2094 | * @param {?} aHtml
|
2095 | * @return {?}
|
2096 | */
|
2097 | function _serializeHtml(aHtml) {
|
2098 | return of(/** @type {?} */ ((aHtml)).html());
|
2099 | }
|
2100 | /**
|
2101 | * Reads an HMTL from the tree and then transforms it using the given function. If the result
|
2102 | * is null or undefined, the file will be deleted, else replaced or created.
|
2103 | *
|
2104 | * @param {?} aName name of the file
|
2105 | * @param {?} aOp the operator
|
2106 | * @param {?} aTree the tree to work in
|
2107 | * @return {?}
|
2108 | */
|
2109 | function rxTransformHtmlFile(aName, aOp, aTree) {
|
2110 | /** @type {?} */
|
2111 | var op = /** @type {?} */ (aOp);
|
2112 | // dispatch
|
2113 | return rxTransformTextFile(aName, function (textContent, path) {
|
2114 | return _parseHtml(textContent).pipe(switchMap(function (html) { return op(html, path); }), switchMap(_serializeHtml));
|
2115 | }, aTree);
|
2116 | }
|
2117 |
|
2118 | /**
|
2119 | * @fileoverview added by tsickle
|
2120 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2121 | */
|
2122 |
|
2123 | /**
|
2124 | * @fileoverview added by tsickle
|
2125 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2126 | */
|
2127 | /**
|
2128 | * @param {?} host
|
2129 | * @param {?} path
|
2130 | * @return {?}
|
2131 | */
|
2132 | function getSourceFile(host, path) {
|
2133 | /** @type {?} */
|
2134 | var buffer = host.read(path);
|
2135 | if (!buffer) {
|
2136 | throw new SchematicsException("Could not find " + path + ".");
|
2137 | }
|
2138 | /** @type {?} */
|
2139 | var content = buffer.toString();
|
2140 | /** @type {?} */
|
2141 | var source = createSourceFile(path, content, ScriptTarget.Latest, true);
|
2142 | return source;
|
2143 | }
|
2144 |
|
2145 | /**
|
2146 | * @fileoverview added by tsickle
|
2147 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2148 | */
|
2149 | /**
|
2150 | * @param {?} aChanges
|
2151 | * @param {?} aRecorder
|
2152 | * @return {?}
|
2153 | */
|
2154 | function insertChanges(aChanges, aRecorder) {
|
2155 | aChanges.forEach(function (change) {
|
2156 | // delete
|
2157 | if (change instanceof InsertChange) {
|
2158 | aRecorder.insertLeft(change.pos, change.toAdd);
|
2159 | }
|
2160 | else if (change instanceof RemoveChange) ;
|
2161 | else if (change instanceof ReplaceChange) {
|
2162 | /** @type {?} */
|
2163 | var anyChange = /** @type {?} */ (change);
|
2164 | aRecorder.remove(anyChange.pos, anyChange.oldText.length);
|
2165 | aRecorder.insertLeft(anyChange.pos, anyChange.newText);
|
2166 | }
|
2167 | });
|
2168 | }
|
2169 | /**
|
2170 | * @param {?} aFile
|
2171 | * @param {?} aOp
|
2172 | * @param {?} aHost
|
2173 | * @return {?}
|
2174 | */
|
2175 | function changeSourceFile(aFile, aOp, aHost) {
|
2176 | // make sure at least an empty file exists
|
2177 | if (!aHost.exists(aFile)) {
|
2178 | aHost.create(aFile, '');
|
2179 | }
|
2180 | /** @type {?} */
|
2181 | var recorder = aHost.beginUpdate(aFile);
|
2182 | insertChanges(aOp(aFile, getSourceFile(aHost, aFile)), recorder);
|
2183 | aHost.commitUpdate(recorder);
|
2184 | }
|
2185 | /**
|
2186 | * Changes the identified module by adding a couple of imports
|
2187 | *
|
2188 | * @param {?} aFile the filename
|
2189 | * @param {?} aModules the modules to be added
|
2190 | * @param {?} aHost the tree
|
2191 | * @return {?}
|
2192 | */
|
2193 | function addImportsToModule(aFile, aModules, aHost) {
|
2194 | // iterate
|
2195 | Object.keys(aModules).forEach(function (name) {
|
2196 | return changeSourceFile(aFile, function (file, content) { return addImportToModule(content, file, name, aModules[name]); }, aHost);
|
2197 | });
|
2198 | }
|
2199 |
|
2200 | /**
|
2201 | * @fileoverview added by tsickle
|
2202 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2203 | */
|
2204 | /**
|
2205 | * @param {?} aType
|
2206 | * @return {?}
|
2207 | */
|
2208 | function byType(aType) {
|
2209 | return function (node) { return node && node.kind === aType; };
|
2210 | }
|
2211 | /**
|
2212 | * @param {?} aText
|
2213 | * @return {?}
|
2214 | */
|
2215 | function byText(aText) {
|
2216 | return function (node) { return node && node.getText() === aText; };
|
2217 | }
|
2218 | /**
|
2219 | * @param {?} aText
|
2220 | * @return {?}
|
2221 | */
|
2222 | function byName(aText) {
|
2223 | return function (node) { return !!(node && node.name && node.name.getText() === aText); };
|
2224 | }
|
2225 | /**
|
2226 | * @param {?} aType
|
2227 | * @param {?} aName
|
2228 | * @return {?}
|
2229 | */
|
2230 | function byTypeAndName(aType, aName) {
|
2231 | return function (node) { return node && node.kind === aType && node.getText() === aName; };
|
2232 | }
|
2233 | /**
|
2234 | * @param {?} aName
|
2235 | * @return {?}
|
2236 | */
|
2237 | function byIdentifier(aName) {
|
2238 | return byTypeAndName(SyntaxKind.Identifier, aName);
|
2239 | }
|
2240 |
|
2241 | /**
|
2242 | * @fileoverview added by tsickle
|
2243 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2244 | */
|
2245 |
|
2246 | /**
|
2247 | * @fileoverview added by tsickle
|
2248 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2249 | */
|
2250 |
|
2251 | /**
|
2252 | * @fileoverview added by tsickle
|
2253 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2254 | */
|
2255 |
|
2256 | /**
|
2257 | * @fileoverview added by tsickle
|
2258 | * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
2259 | */
|
2260 |
|
2261 | export { findModuleFromOptions, findModule, buildRelativePath, insertImport, findNodes, getSourceNodes, findNode, insertAfterLastOccurrence, getContentOfKeyLiteral, getDecoratorMetadata, getFirstNgModuleName, addSymbolToNgModuleMetadata, addDeclarationToModule, addImportToModule, addProviderToModule, addExportToModule, addBootstrapToModule, addEntryComponentToModule, isImported, getWorkspacePath, getWorkspace, addProjectToWorkspace, getConfig, getAppFromConfig, configPath, findBootstrapModuleCall, findBootstrapModulePath, getAppModulePath, parseName, validateName, validateHtmlSelector, validateProjectName, htmlSelectorRe, NoopChange, InsertChange, RemoveChange, ReplaceChange, assertNotNull, assertParameter, isValidUrl, assertIsUrl, isValidEmail, isValidUserName, assertIsEmail, assertIsValidUserName, assertHasTrailingSlash, TENANT_BASED_URL_REGEXP, _ensureTrailingSlash as ensureTrailingSlash, _hasTrailingSlash as hasTrailingSlash, rxGet, rxGetJson, rxFormPost, wchToolsGetCredentials, validateCredentials, validateApiUrl, findSdkVersion, findDataDir, findWchToolsOptions, addToWchToolsDependencies, WCHTOOLS_DEPENDENCIES, rxReadFile, rxTransformTextFile, rxTransformJsonFile, rxTransformLinesFile, serializeJson, updateField, _canonicalize as canonicalizeJSON, rxUnzipFromUrl, rxTransformHtmlFile, getSourceFile, insertChanges, changeSourceFile, addImportsToModule, byType, byText, byName, byTypeAndName, byIdentifier, serializeLines, parseLines, insertLines, getFolderForType, updateMinVersion, findPackageJson, DEP_TYPE };
|
2262 |
|
2263 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWJtLXdjaC1zZGstc2NoZW1hdGljcy11dGlscy5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS9maW5kLW1vZHVsZS50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS9jaGFuZ2UudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3V0aWxpdHkvYXN0LXV0aWxzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy91dGlsaXR5L2NvbmZpZy50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS9uZy1hc3QtdXRpbHMudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3V0aWxpdHkvcGFyc2UtbmFtZS50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS92YWxpZGF0aW9uLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvdXJsLnV0aWxzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvYXNzZXJ0LnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvdGVuYW50LnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvcngucmVxdWVzdC50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvd2NoL3J4LmZpbGUudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3djaC93Y2h0b29scy50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvcGFja2FnZS9wYWNrYWdlLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvd2NoLnV0aWxzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvanNvbi50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdGV4dC9saW5lcy50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvd2NoL3J4LnRyZWUudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3djaC9yeC56aXAudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3djaC9yeC5odG1sLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy90eXBlc2NyaXB0L3NvdXJjZS50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdHlwZXNjcmlwdC9jaGFuZ2VzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy90eXBlc2NyaXB0L2ZpbmRlcnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgUGF0aCwgam9pbiwgbm9ybWFsaXplLCByZWxhdGl2ZSwgc3RyaW5ncyB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IERpckVudHJ5LCBUcmVlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L3NjaGVtYXRpY3MnO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9kdWxlT3B0aW9ucyB7XG4gIG1vZHVsZT86IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBmbGF0PzogYm9vbGVhbjtcbiAgcGF0aD86IHN0cmluZztcbiAgc2tpcEltcG9ydD86IGJvb2xlYW47XG59XG5cblxuLyoqXG4gKiBGaW5kIHRoZSBtb2R1bGUgcmVmZXJyZWQgYnkgYSBzZXQgb2Ygb3B0aW9ucyBwYXNzZWQgdG8gdGhlIHNjaGVtYXRpY3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTW9kdWxlRnJvbU9wdGlvbnMoaG9zdDogVHJlZSwgb3B0aW9uczogTW9kdWxlT3B0aW9ucyk6IFBhdGggfCB1bmRlZmluZWQge1xuICBpZiAob3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnc2tpcEltcG9ydCcpICYmIG9wdGlvbnMuc2tpcEltcG9ydCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoIW9wdGlvbnMubW9kdWxlKSB7XG4gICAgY29uc3QgcGF0aFRvQ2hlY2sgPSAob3B0aW9ucy5wYXRoIHx8ICcnKVxuICAgICAgICAgICAgICAgICAgICAgICsgKG9wdGlvbnMuZmxhdCA/ICcnIDogJy8nICsgc3RyaW5ncy5kYXNoZXJpemUob3B0aW9ucy5uYW1lKSk7XG5cbiAgICByZXR1cm4gbm9ybWFsaXplKGZpbmRNb2R1bGUoaG9zdCwgcGF0aFRvQ2hlY2spKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBtb2R1bGVQYXRoID0gbm9ybWFsaXplKFxuICAgICAgJy8nICsgKG9wdGlvbnMucGF0aCkgKyAnLycgKyBvcHRpb25zLm1vZHVsZSk7XG4gICAgY29uc3QgbW9kdWxlQmFzZU5hbWUgPSBub3JtYWxpemUobW9kdWxlUGF0aCkuc3BsaXQoJy8nKS5wb3AoKTtcblxuICAgIGlmIChob3N0LmV4aXN0cyhtb2R1bGVQYXRoKSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZShtb2R1bGVQYXRoKTtcbiAgICB9IGVsc2UgaWYgKGhvc3QuZXhpc3RzKG1vZHVsZVBhdGggKyAnLnRzJykpIHtcbiAgICAgIHJldHVybiBub3JtYWxpemUobW9kdWxlUGF0aCArICcudHMnKTtcbiAgICB9IGVsc2UgaWYgKGhvc3QuZXhpc3RzKG1vZHVsZVBhdGggKyAnLm1vZHVsZS50cycpKSB7XG4gICAgICByZXR1cm4gbm9ybWFsaXplKG1vZHVsZVBhdGggKyAnLm1vZHVsZS50cycpO1xuICAgIH0gZWxzZSBpZiAoaG9zdC5leGlzdHMobW9kdWxlUGF0aCArICcvJyArIG1vZHVsZUJhc2VOYW1lICsgJy5tb2R1bGUudHMnKSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZShtb2R1bGVQYXRoICsgJy8nICsgbW9kdWxlQmFzZU5hbWUgKyAnLm1vZHVsZS50cycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NwZWNpZmllZCBtb2R1bGUgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBGdW5jdGlvbiB0byBmaW5kIHRoZSBcImNsb3Nlc3RcIiBtb2R1bGUgdG8gYSBnZW5lcmF0ZWQgZmlsZSdzIHBhdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTW9kdWxlKGhvc3Q6IFRyZWUsIGdlbmVyYXRlRGlyOiBzdHJpbmcpOiBQYXRoIHtcbiAgbGV0IGRpcjogRGlyRW50cnkgfCBudWxsID0gaG9zdC5nZXREaXIoJy8nICsgZ2VuZXJhdGVEaXIpO1xuXG4gIGNvbnN0IG1vZHVsZVJlID0gL1xcLm1vZHVsZVxcLnRzJC87XG4gIGNvbnN0IHJvdXRpbmdNb2R1bGVSZSA9IC8tcm91dGluZ1xcLm1vZHVsZVxcLnRzLztcblxuICB3aGlsZSAoZGlyKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IGRpci5zdWJmaWxlcy5maWx0ZXIocCA9PiBtb2R1bGVSZS50ZXN0KHApICYmICFyb3V0aW5nTW9kdWxlUmUudGVzdChwKSk7XG5cbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggPT0gMSkge1xuICAgICAgcmV0dXJuIGpvaW4oZGlyLnBhdGgsIG1hdGNoZXNbMF0pO1xuICAgIH0gZWxzZSBpZiAobWF0Y2hlcy5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vcmUgdGhhbiBvbmUgbW9kdWxlIG1hdGNoZXMuIFVzZSBza2lwLWltcG9ydCBvcHRpb24gdG8gc2tpcCBpbXBvcnRpbmcgJ1xuICAgICAgICArICd0aGUgY29tcG9uZW50IGludG8gdGhlIGNsb3Nlc3QgbW9kdWxlLicpO1xuICAgIH1cblxuICAgIGRpciA9IGRpci5wYXJlbnQ7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIGFuIE5nTW9kdWxlLiBVc2UgdGhlIHNraXAtaW1wb3J0ICdcbiAgICArICdvcHRpb24gdG8gc2tpcCBpbXBvcnRpbmcgaW4gTmdNb2R1bGUuJyk7XG59XG5cbi8qKlxuICogQnVpbGQgYSByZWxhdGl2ZSBwYXRoIGZyb20gb25lIGZpbGUgcGF0aCB0byBhbm90aGVyIGZpbGUgcGF0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUmVsYXRpdmVQYXRoKGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IHN0cmluZyB7XG4gIGZyb20gPSBub3JtYWxpemUoZnJvbSk7XG4gIHRvID0gbm9ybWFsaXplKHRvKTtcblxuICAvLyBDb252ZXJ0IHRvIGFycmF5cy5cbiAgY29uc3QgZnJvbVBhcnRzID0gZnJvbS5zcGxpdCgnLycpO1xuICBjb25zdCB0b1BhcnRzID0gdG8uc3BsaXQoJy8nKTtcblxuICAvLyBSZW1vdmUgZmlsZSBuYW1lcyAocHJlc2VydmluZyBkZXN0aW5hdGlvbilcbiAgZnJvbVBhcnRzLnBvcCgpO1xuICBjb25zdCB0b0ZpbGVOYW1lID0gdG9QYXJ0cy5wb3AoKTtcblxuICBjb25zdCByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZShub3JtYWxpemUoZnJvbVBhcnRzLmpvaW4oJy8nKSksIG5vcm1hbGl6ZSh0b1BhcnRzLmpvaW4oJy8nKSkpO1xuICBsZXQgcGF0aFByZWZpeCA9ICcnO1xuXG4gIC8vIFNldCB0aGUgcGF0aCBwcmVmaXggZm9yIHNhbWUgZGlyIG9yIGNoaWxkIGRpciwgcGFyZW50IGRpciBzdGFydHMgd2l0aCBgLi5gXG4gIGlmICghcmVsYXRpdmVQYXRoKSB7XG4gICAgcGF0aFByZWZpeCA9ICcuJztcbiAgfSBlbHNlIGlmICghcmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgIHBhdGhQcmVmaXggPSBgLi9gO1xuICB9XG4gIGlmIChwYXRoUHJlZml4ICYmICFwYXRoUHJlZml4LmVuZHNXaXRoKCcvJykpIHtcbiAgICBwYXRoUHJlZml4ICs9ICcvJztcbiAgfVxuXG4gIHJldHVybiBwYXRoUHJlZml4ICsgKHJlbGF0aXZlUGF0aCA/IHJlbGF0aXZlUGF0aCArICcvJyA6ICcnKSArIHRvRmlsZU5hbWU7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhvc3Qge1xuICB3cml0ZShwYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIHJlYWQocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+O1xufVxuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbmdlIHtcbiAgYXBwbHkoaG9zdDogSG9zdCk6IFByb21pc2U8dm9pZD47XG5cbiAgLy8gVGhlIGZpbGUgdGhpcyBjaGFuZ2Ugc2hvdWxkIGJlIGFwcGxpZWQgdG8uIFNvbWUgY2hhbmdlcyBtaWdodCBub3QgYXBwbHkgdG9cbiAgLy8gYSBmaWxlIChtYXliZSB0aGUgY29uZmlnKS5cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nIHwgbnVsbDtcblxuICAvLyBUaGUgb3JkZXIgdGhpcyBjaGFuZ2Ugc2hvdWxkIGJlIGFwcGxpZWQuIE5vcm1hbGx5IHRoZSBwb3NpdGlvbiBpbnNpZGUgdGhlIGZpbGUuXG4gIC8vIENoYW5nZXMgYXJlIGFwcGxpZWQgZnJvbSB0aGUgYm90dG9tIG9mIGEgZmlsZSB0byB0aGUgdG9wLlxuICByZWFkb25seSBvcmRlcjogbnVtYmVyO1xuXG4gIC8vIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGlzIGNoYW5nZS4gVGhpcyB3aWxsIGJlIG91dHB1dHRlZCBpbiBhIGRyeSBvciB2ZXJib3NlIHJ1bi5cbiAgcmVhZG9ubHkgZGVzY3JpcHRpb246IHN0cmluZztcbn1cblxuXG4vKipcbiAqIEFuIG9wZXJhdGlvbiB0aGF0IGRvZXMgbm90aGluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vb3BDaGFuZ2UgaW1wbGVtZW50cyBDaGFuZ2Uge1xuICBkZXNjcmlwdGlvbiA9ICdObyBvcGVyYXRpb24uJztcbiAgb3JkZXIgPSBJbmZpbml0eTtcbiAgcGF0aCA9IG51bGw7XG4gIGFwcGx5KCkgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7IH1cbn1cblxuXG4vKipcbiAqIFdpbGwgYWRkIHRleHQgdG8gdGhlIHNvdXJjZSBjb2RlLlxuICovXG5leHBvcnQgY2xhc3MgSW5zZXJ0Q2hhbmdlIGltcGxlbWVudHMgQ2hhbmdlIHtcblxuICBvcmRlcjogbnVtYmVyO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcsIHB1YmxpYyBwb3M6IG51bWJlciwgcHVibGljIHRvQWRkOiBzdHJpbmcpIHtcbiAgICBpZiAocG9zIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOZWdhdGl2ZSBwb3NpdGlvbnMgYXJlIGludmFsaWQnKTtcbiAgICB9XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGBJbnNlcnRlZCAke3RvQWRkfSBpbnRvIHBvc2l0aW9uICR7cG9zfSBvZiAke3BhdGh9YDtcbiAgICB0aGlzLm9yZGVyID0gcG9zO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IGluc2VydCBzcGFjZXMgaWYgdGhlcmUgaXMgbm9uZSBpbiB0aGUgb3JpZ2luYWwgc3RyaW5nLlxuICAgKi9cbiAgYXBwbHkoaG9zdDogSG9zdCkge1xuICAgIHJldHVybiBob3N0LnJlYWQodGhpcy5wYXRoKS50aGVuKGNvbnRlbnQgPT4ge1xuICAgICAgY29uc3QgcHJlZml4ID0gY29udGVudC5zdWJzdHJpbmcoMCwgdGhpcy5wb3MpO1xuICAgICAgY29uc3Qgc3VmZml4ID0gY29udGVudC5zdWJzdHJpbmcodGhpcy5wb3MpO1xuXG4gICAgICByZXR1cm4gaG9zdC53cml0ZSh0aGlzLnBhdGgsIGAke3ByZWZpeH0ke3RoaXMudG9BZGR9JHtzdWZmaXh9YCk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaWxsIHJlbW92ZSB0ZXh0IGZyb20gdGhlIHNvdXJjZSBjb2RlLlxuICovXG5leHBvcnQgY2xhc3MgUmVtb3ZlQ2hhbmdlIGltcGxlbWVudHMgQ2hhbmdlIHtcblxuICBvcmRlcjogbnVtYmVyO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcsIHByaXZhdGUgcG9zOiBudW1iZXIsIHByaXZhdGUgdG9SZW1vdmU6IHN0cmluZykge1xuICAgIGlmIChwb3MgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05lZ2F0aXZlIHBvc2l0aW9ucyBhcmUgaW52YWxpZCcpO1xuICAgIH1cbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gYFJlbW92ZWQgJHt0b1JlbW92ZX0gaW50byBwb3NpdGlvbiAke3Bvc30gb2YgJHtwYXRofWA7XG4gICAgdGhpcy5vcmRlciA9IHBvcztcbiAgfVxuXG4gIGFwcGx5KGhvc3Q6IEhvc3QpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gaG9zdC5yZWFkKHRoaXMucGF0aCkudGhlbihjb250ZW50ID0+IHtcbiAgICAgIGNvbnN0IHByZWZpeCA9IGNvbnRlbnQuc3Vic3RyaW5nKDAsIHRoaXMucG9zKTtcbiAgICAgIGNvbnN0IHN1ZmZpeCA9IGNvbnRlbnQuc3Vic3RyaW5nKHRoaXMucG9zICsgdGhpcy50b1JlbW92ZS5sZW5ndGgpO1xuXG4gICAgICAvLyBUT0RPOiB0aHJvdyBlcnJvciBpZiB0b1JlbW92ZSBkb2Vzbid0IG1hdGNoIHJlbW92ZWQgc3RyaW5nLlxuICAgICAgcmV0dXJuIGhvc3Qud3JpdGUodGhpcy5wYXRoLCBgJHtwcmVmaXh9JHtzdWZmaXh9YCk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaWxsIHJlcGxhY2UgdGV4dCBmcm9tIHRoZSBzb3VyY2UgY29kZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFJlcGxhY2VDaGFuZ2UgaW1wbGVtZW50cyBDaGFuZ2Uge1xuICBvcmRlcjogbnVtYmVyO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcsIHByaXZhdGUgcG9zOiBudW1iZXIsIHByaXZhdGUgb2xkVGV4dDogc3RyaW5nLFxuICAgICAgICAgICAgICBwcml2YXRlIG5ld1RleHQ6IHN0cmluZykge1xuICAgIGlmIChwb3MgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05lZ2F0aXZlIHBvc2l0aW9ucyBhcmUgaW52YWxpZCcpO1xuICAgIH1cbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gYFJlcGxhY2VkICR7b2xkVGV4dH0gaW50byBwb3NpdGlvbiAke3Bvc30gb2YgJHtwYXRofSB3aXRoICR7bmV3VGV4dH1gO1xuICAgIHRoaXMub3JkZXIgPSBwb3M7XG4gIH1cblxuICBhcHBseShob3N0OiBIb3N0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGhvc3QucmVhZCh0aGlzLnBhdGgpLnRoZW4oY29udGVudCA9PiB7XG4gICAgICBjb25zdCBwcmVmaXggPSBjb250ZW50LnN1YnN0cmluZygwLCB0aGlzLnBvcyk7XG4gICAgICBjb25zdCBzdWZmaXggPSBjb250ZW50LnN1YnN0cmluZyh0aGlzLnBvcyArIHRoaXMub2xkVGV4dC5sZW5ndGgpO1xuICAgICAgY29uc3QgdGV4dCA9IGNvbnRlbnQuc3Vic3RyaW5nKHRoaXMucG9zLCB0aGlzLnBvcyArIHRoaXMub2xkVGV4dC5sZW5ndGgpO1xuXG4gICAgICBpZiAodGV4dCAhPT0gdGhpcy5vbGRUZXh0KSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYEludmFsaWQgcmVwbGFjZTogXCIke3RleHR9XCIgIT0gXCIke3RoaXMub2xkVGV4dH1cIi5gKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFRPRE86IHRocm93IGVycm9yIGlmIG9sZFRleHQgZG9lc24ndCBtYXRjaCByZW1vdmVkIHN0cmluZy5cbiAgICAgIHJldHVybiBob3N0LndyaXRlKHRoaXMucGF0aCwgYCR7cHJlZml4fSR7dGhpcy5uZXdUZXh0fSR7c3VmZml4fWApO1xuICAgIH0pO1xuICB9XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQgKiBhcyB0cyBmcm9tICd0eXBlc2NyaXB0JztcbmltcG9ydCB7IENoYW5nZSwgSW5zZXJ0Q2hhbmdlLCBOb29wQ2hhbmdlIH0gZnJvbSAnLi9jaGFuZ2UnO1xuXG4vKipcbiAqIEFkZCBJbXBvcnQgYGltcG9ydCB7IHN5bWJvbE5hbWUgfSBmcm9tIGZpbGVOYW1lYCBpZiB0aGUgaW1wb3J0IGRvZXNuJ3QgZXhpdFxuICogYWxyZWFkeS4gQXNzdW1lcyBmaWxlVG9FZGl0IGNhbiBiZSByZXNvbHZlZCBhbmQgYWNjZXNzZWQuXG4gKiBAcGFyYW0gZmlsZVRvRWRpdCAoZmlsZSB3ZSB3YW50IHRvIGFkZCBpbXBvcnQgdG8pXG4gKiBAcGFyYW0gc3ltYm9sTmFtZSAoaXRlbSB0byBpbXBvcnQpXG4gKiBAcGFyYW0gZmlsZU5hbWUgKHBhdGggdG8gdGhlIGZpbGUpXG4gKiBAcGFyYW0gaXNEZWZhdWx0IChpZiB0cnVlLCBpbXBvcnQgZm9sbG93cyBzdHlsZSBmb3IgaW1wb3J0aW5nIGRlZmF1bHQgZXhwb3J0cylcbiAqIEByZXR1cm4gQ2hhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRJbXBvcnQoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZSxcbiAgZmlsZVRvRWRpdDogc3RyaW5nLFxuICBzeW1ib2xOYW1lOiBzdHJpbmcsXG4gIGZpbGVOYW1lOiBzdHJpbmcsXG4gIGlzRGVmYXVsdCA9IGZhbHNlXG4pOiBDaGFuZ2Uge1xuICBjb25zdCByb290Tm9kZSA9IHNvdXJjZTtcbiAgY29uc3QgYWxsSW1wb3J0cyA9IGZpbmROb2Rlcyhyb290Tm9kZSwgdHMuU3ludGF4S2luZC5JbXBvcnREZWNsYXJhdGlvbik7XG5cbiAgLy8gZ2V0IG5vZGVzIHRoYXQgbWFwIHRvIGltcG9ydCBzdGF0ZW1lbnRzIGZyb20gdGhlIGZpbGUgZmlsZU5hbWVcbiAgY29uc3QgcmVsZXZhbnRJbXBvcnRzID0gYWxsSW1wb3J0cy5maWx0ZXIobm9kZSA9PiB7XG4gICAgLy8gU3RyaW5nTGl0ZXJhbCBvZiB0aGUgSW1wb3J0RGVjbGFyYXRpb24gaXMgdGhlIGltcG9ydCBmaWxlIChmaWxlTmFtZSBpbiB0aGlzIGNhc2UpLlxuICAgIGNvbnN0IGltcG9ydEZpbGVzID0gbm9kZVxuICAgICAgLmdldENoaWxkcmVuKClcbiAgICAgIC5maWx0ZXIoY2hpbGQgPT4gY2hpbGQua2luZCA9PT0gdHMuU3ludGF4S2luZC5TdHJpbmdMaXRlcmFsKVxuICAgICAgLm1hcChuID0+IChuIGFzIHRzLlN0cmluZ0xpdGVyYWwpLnRleHQpO1xuXG4gICAgcmV0dXJuIGltcG9ydEZpbGVzLmZpbHRlcihmaWxlID0+IGZpbGUgPT09IGZpbGVOYW1lKS5sZW5ndGggPT09IDE7XG4gIH0pO1xuXG4gIGlmIChyZWxldmFudEltcG9ydHMubGVuZ3RoID4gMCkge1xuICAgIGxldCBpbXBvcnRzQXN0ZXJpc2sgPSBmYWxzZTtcbiAgICAvLyBpbXBvcnRzIGZyb20gaW1wb3J0IGZpbGVcbiAgICBjb25zdCBpbXBvcnRzOiB0cy5Ob2RlW10gPSBbXTtcbiAgICByZWxldmFudEltcG9ydHMuZm9yRWFjaChuID0+IHtcbiAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KFxuICAgICAgICBpbXBvcnRzLFxuICAgICAgICBmaW5kTm9kZXMobiwgdHMuU3ludGF4S2luZC5JZGVudGlmaWVyKVxuICAgICAgKTtcbiAgICAgIGlmIChmaW5kTm9kZXMobiwgdHMuU3ludGF4S2luZC5Bc3Rlcmlza1Rva2VuKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGltcG9ydHNBc3RlcmlzayA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBpZiBpbXBvcnRzICogZnJvbSBmaWxlTmFtZSwgZG9uJ3QgYWRkIHN5bWJvbE5hbWVcbiAgICBpZiAoaW1wb3J0c0FzdGVyaXNrKSB7XG4gICAgICByZXR1cm4gbmV3IE5vb3BDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbXBvcnRUZXh0Tm9kZXMgPSBpbXBvcnRzLmZpbHRlcihcbiAgICAgIG4gPT4gKG4gYXMgdHMuSWRlbnRpZmllcikudGV4dCA9PT0gc3ltYm9sTmFtZVxuICAgICk7XG5cbiAgICAvLyBpbnNlcnQgaW1wb3J0IGlmIGl0J3Mgbm90IHRoZXJlXG4gICAgaWYgKGltcG9ydFRleHROb2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnN0IGZhbGxiYWNrUG9zID1cbiAgICAgICAgZmluZE5vZGVzKFxuICAgICAgICAgIHJlbGV2YW50SW1wb3J0c1swXSxcbiAgICAgICAgICB0cy5TeW50YXhLaW5kLkNsb3NlQnJhY2VUb2tlblxuICAgICAgICApWzBdLmdldFN0YXJ0KCkgfHxcbiAgICAgICAgZmluZE5vZGVzKHJlbGV2YW50SW1wb3J0c1swXSwgdHMuU3ludGF4S2luZC5Gcm9tS2V5d29yZClbMF0uZ2V0U3RhcnQoKTtcblxuICAgICAgcmV0dXJuIGluc2VydEFmdGVyTGFzdE9jY3VycmVuY2UoXG4gICAgICAgIGltcG9ydHMsXG4gICAgICAgIGAsICR7c3ltYm9sTmFtZX1gLFxuICAgICAgICBmaWxlVG9FZGl0LFxuICAgICAgICBmYWxsYmFja1Bvc1xuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE5vb3BDaGFuZ2UoKTtcbiAgfVxuXG4gIC8vIG5vIHN1Y2ggaW1wb3J0IGRlY2xhcmF0aW9uIGV4aXN0c1xuICBjb25zdCB1c2VTdHJpY3QgPSBmaW5kTm9kZXMocm9vdE5vZGUsIHRzLlN5bnRheEtpbmQuU3RyaW5nTGl0ZXJhbCkuZmlsdGVyKFxuICAgIChuOiB0cy5TdHJpbmdMaXRlcmFsKSA9PiBuLnRleHQgPT09ICd1c2Ugc3RyaWN0J1xuICApO1xuICBsZXQgZmFsbGJhY2tQb3MgPSAwO1xuICBpZiAodXNlU3RyaWN0Lmxlbmd0aCA+IDApIHtcbiAgICBmYWxsYmFja1BvcyA9IHVzZVN0cmljdFswXS5lbmQ7XG4gIH1cbiAgY29uc3Qgb3BlbiA9IGlzRGVmYXVsdCA/ICcnIDogJ3sgJztcbiAgY29uc3QgY2xvc2UgPSBpc0RlZmF1bHQgPyAnJyA6ICcgfSc7XG4gIC8vIGlmIHRoZXJlIGFyZSBubyBpbXBvcnRzIG9yICd1c2Ugc3RyaWN0JyBzdGF0ZW1lbnQsIGluc2VydCBpbXBvcnQgYXQgYmVnaW5uaW5nIG9mIGZpbGVcbiAgY29uc3QgaW5zZXJ0QXRCZWdpbm5pbmcgPSBhbGxJbXBvcnRzLmxlbmd0aCA9PT0gMCAmJiB1c2VTdHJpY3QubGVuZ3RoID09PSAwO1xuICBjb25zdCBzZXBhcmF0b3IgPSBpbnNlcnRBdEJlZ2lubmluZyA/ICcnIDogJztcXG4nO1xuICBjb25zdCB0b0luc2VydCA9XG4gICAgYCR7c2VwYXJhdG9yfWltcG9ydCAke29wZW59JHtzeW1ib2xOYW1lfSR7Y2xvc2V9YCArXG4gICAgYCBmcm9tICcke2ZpbGVOYW1lfScke2luc2VydEF0QmVnaW5uaW5nID8gJztcXG4nIDogJyd9YDtcblxuICByZXR1cm4gaW5zZXJ0QWZ0ZXJMYXN0T2NjdXJyZW5jZShcbiAgICBhbGxJbXBvcnRzLFxuICAgIHRvSW5zZXJ0LFxuICAgIGZpbGVUb0VkaXQsXG4gICAgZmFsbGJhY2tQb3MsXG4gICAgdHMuU3ludGF4S2luZC5TdHJpbmdMaXRlcmFsXG4gICk7XG59XG5cbi8qKlxuICogRmluZCBhbGwgbm9kZXMgZnJvbSB0aGUgQVNUIGluIHRoZSBzdWJ0cmVlIG9mIG5vZGUgb2YgU3ludGF4S2luZCBraW5kLlxuICogQHBhcmFtIG5vZGVcbiAqIEBwYXJhbSBraW5kXG4gKiBAcGFyYW0gbWF4IFRoZSBtYXhpbXVtIG51bWJlciBvZiBpdGVtcyB0byByZXR1cm4uXG4gKiBAcmV0dXJuIGFsbCBub2RlcyBvZiBraW5kLCBvciBbXSBpZiBub25lIGlzIGZvdW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTm9kZXMoXG4gIG5vZGU6IHRzLk5vZGUsXG4gIGtpbmQ6IHRzLlN5bnRheEtpbmQsXG4gIG1heCA9IEluZmluaXR5XG4pOiB0cy5Ob2RlW10ge1xuICBpZiAoIW5vZGUgfHwgbWF4ID09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBhcnI6IHRzLk5vZGVbXSA9IFtdO1xuICBpZiAobm9kZS5raW5kID09PSBraW5kKSB7XG4gICAgYXJyLnB1c2gobm9kZSk7XG4gICAgbWF4LS07XG4gIH1cbiAgaWYgKG1heCA+IDApIHtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuZ2V0Q2hpbGRyZW4oKSkge1xuICAgICAgZmluZE5vZGVzKGNoaWxkLCBraW5kLCBtYXgpLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgIGlmIChtYXggPiAwKSB7XG4gICAgICAgICAgYXJyLnB1c2gobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgbWF4LS07XG4gICAgICB9KTtcblxuICAgICAgaWYgKG1heCA8PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhcnI7XG59XG5cbi8qKlxuICogR2V0IGFsbCB0aGUgbm9kZXMgZnJvbSBhIHNvdXJjZS5cbiAqIEBwYXJhbSBzb3VyY2VGaWxlIFRoZSBzb3VyY2UgZmlsZSBvYmplY3QuXG4gKiBAcmV0dXJucyBBbiBvYnNlcnZhYmxlIG9mIGFsbCB0aGUgbm9kZXMgaW4gdGhlIHNvdXJjZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNvdXJjZU5vZGVzKHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUpOiB0cy5Ob2RlW10ge1xuICBjb25zdCBub2RlczogdHMuTm9kZVtdID0gW3NvdXJjZUZpbGVdO1xuICBjb25zdCByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAobm9kZXMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IG5vZGUgPSBub2Rlcy5zaGlmdCgpO1xuXG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHJlc3VsdC5wdXNoKG5vZGUpO1xuICAgICAgaWYgKG5vZGUuZ2V0Q2hpbGRDb3VudChzb3VyY2VGaWxlKSA+PSAwKSB7XG4gICAgICAgIG5vZGVzLnVuc2hpZnQoLi4ubm9kZS5nZXRDaGlsZHJlbigpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZE5vZGUoXG4gIG5vZGU6IHRzLk5vZGUsXG4gIGtpbmQ6IHRzLlN5bnRheEtpbmQsXG4gIHRleHQ6IHN0cmluZ1xuKTogdHMuTm9kZSB8IG51bGwge1xuICBpZiAobm9kZS5raW5kID09PSBraW5kICYmIG5vZGUuZ2V0VGV4dCgpID09PSB0ZXh0KSB7XG4gICAgLy8gdGhyb3cgbmV3IEVycm9yKG5vZGUuZ2V0VGV4dCgpKTtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIGxldCBmb3VuZE5vZGU6IHRzLk5vZGUgfCBudWxsID0gbnVsbDtcbiAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIGNoaWxkTm9kZSA9PiB7XG4gICAgZm91bmROb2RlID0gZm91bmROb2RlIHx8IGZpbmROb2RlKGNoaWxkTm9kZSwga2luZCwgdGV4dCk7XG4gIH0pO1xuXG4gIHJldHVybiBmb3VuZE5vZGU7XG59XG5cbi8qKlxuICogSGVscGVyIGZvciBzb3J0aW5nIG5vZGVzLlxuICogQHJldHVybiBmdW5jdGlvbiB0byBzb3J0IG5vZGVzIGluIGluY3JlYXNpbmcgb3JkZXIgb2YgcG9zaXRpb24gaW4gc291cmNlRmlsZVxuICovXG5mdW5jdGlvbiBub2Rlc0J5UG9zaXRpb24oZmlyc3Q6IHRzLk5vZGUsIHNlY29uZDogdHMuTm9kZSk6IG51bWJlciB7XG4gIHJldHVybiBmaXJzdC5nZXRTdGFydCgpIC0gc2Vjb25kLmdldFN0YXJ0KCk7XG59XG5cbi8qKlxuICogSW5zZXJ0IGB0b0luc2VydGAgYWZ0ZXIgdGhlIGxhc3Qgb2NjdXJlbmNlIG9mIGB0cy5TeW50YXhLaW5kW25vZGVzW2ldLmtpbmRdYFxuICogb3IgYWZ0ZXIgdGhlIGxhc3Qgb2Ygb2NjdXJlbmNlIG9mIGBzeW50YXhLaW5kYCBpZiB0aGUgbGFzdCBvY2N1cmVuY2UgaXMgYSBzdWIgY2hpbGRcbiAqIG9mIHRzLlN5bnRheEtpbmRbbm9kZXNbaV0ua2luZF0gYW5kIHNhdmUgdGhlIGNoYW5nZXMgaW4gZmlsZS5cbiAqXG4gKiBAcGFyYW0gbm9kZXMgaW5zZXJ0IGFmdGVyIHRoZSBsYXN0IG9jY3VyZW5jZSBvZiBub2Rlc1xuICogQHBhcmFtIHRvSW5zZXJ0IHN0cmluZyB0byBpbnNlcnRcbiAqIEBwYXJhbSBmaWxlIGZpbGUgdG8gaW5zZXJ0IGNoYW5nZXMgaW50b1xuICogQHBhcmFtIGZhbGxiYWNrUG9zIHBvc2l0aW9uIHRvIGluc2VydCBpZiB0b0luc2VydCBoYXBwZW5zIHRvIGJlIHRoZSBmaXJzdCBvY2N1cmVuY2VcbiAqIEBwYXJhbSBzeW50YXhLaW5kIHRoZSB0cy5TeW50YXhLaW5kIG9mIHRoZSBzdWJjaGlsZHJlbiB0byBpbnNlcnQgYWZ0ZXJcbiAqIEByZXR1cm4gQ2hhbmdlIGluc3RhbmNlXG4gKiBAdGhyb3cgRXJyb3IgaWYgdG9JbnNlcnQgaXMgZmlyc3Qgb2NjdXJlbmNlIGJ1dCBmYWxsIGJhY2sgaXMgbm90IHNldFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zZXJ0QWZ0ZXJMYXN0T2NjdXJyZW5jZShcbiAgbm9kZXM6IHRzLk5vZGVbXSxcbiAgdG9JbnNlcnQ6IHN0cmluZyxcbiAgZmlsZTogc3RyaW5nLFxuICBmYWxsYmFja1BvczogbnVtYmVyLFxuICBzeW50YXhLaW5kPzogdHMuU3ludGF4S2luZFxuKTogQ2hhbmdlIHtcbiAgLy8gc29ydCgpIGhhcyBhIHNpZGUgZWZmZWN0LCBzbyBtYWtlIGEgY29weSBzbyB0aGF0IHdlIHdvbid0IG92ZXJ3cml0ZSB0aGUgcGFyZW50J3Mgb2JqZWN0LlxuICBsZXQgbGFzdEl0ZW0gPSBbLi4ubm9kZXNdLnNvcnQobm9kZXNCeVBvc2l0aW9uKS5wb3AoKTtcbiAgaWYgKCFsYXN0SXRlbSkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xuICB9XG4gIGlmIChzeW50YXhLaW5kKSB7XG4gICAgbGFzdEl0ZW0gPSBmaW5kTm9kZXMobGFzdEl0ZW0sIHN5bnRheEtpbmQpXG4gICAgICAuc29ydChub2Rlc0J5UG9zaXRpb24pXG4gICAgICAucG9wKCk7XG4gIH1cbiAgaWYgKCFsYXN0SXRlbSAmJiBmYWxsYmFja1BvcyA9PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgdHJpZWQgdG8gaW5zZXJ0ICR7dG9JbnNlcnR9IGFzIGZpcnN0IG9jY3VyZW5jZSB3aXRoIG5vIGZhbGxiYWNrIHBvc2l0aW9uYFxuICAgICk7XG4gIH1cbiAgY29uc3QgbGFzdEl0ZW1Qb3NpdGlvbjogbnVtYmVyID0gbGFzdEl0ZW0gPyBsYXN0SXRlbS5nZXRFbmQoKSA6IGZhbGxiYWNrUG9zO1xuXG4gIHJldHVybiBuZXcgSW5zZXJ0Q2hhbmdlKGZpbGUsIGxhc3RJdGVtUG9zaXRpb24sIHRvSW5zZXJ0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbnRlbnRPZktleUxpdGVyYWwoXG4gIF9zb3VyY2U6IHRzLlNvdXJjZUZpbGUsXG4gIG5vZGU6IHRzLk5vZGVcbik6IHN0cmluZyB8IG51bGwge1xuICBpZiAobm9kZS5raW5kID09IHRzLlN5bnRheEtpbmQuSWRlbnRpZmllcikge1xuICAgIHJldHVybiAobm9kZSBhcyB0cy5JZGVudGlmaWVyKS50ZXh0O1xuICB9IGVsc2UgaWYgKG5vZGUua2luZCA9PSB0cy5TeW50YXhLaW5kLlN0cmluZ0xpdGVyYWwpIHtcbiAgICByZXR1cm4gKG5vZGUgYXMgdHMuU3RyaW5nTGl0ZXJhbCkudGV4dDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBfYW5ndWxhckltcG9ydHNGcm9tTm9kZShcbiAgbm9kZTogdHMuSW1wb3J0RGVjbGFyYXRpb24sXG4gIF9zb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlXG4pOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gIGNvbnN0IG1zID0gbm9kZS5tb2R1bGVTcGVjaWZpZXI7XG4gIGxldCBtb2R1bGVQYXRoOiBzdHJpbmc7XG4gIHN3aXRjaCAobXMua2luZCkge1xuICAgIGNhc2UgdHMuU3ludGF4S2luZC5TdHJpbmdMaXRlcmFsOlxuICAgICAgbW9kdWxlUGF0aCA9IChtcyBhcyB0cy5TdHJpbmdMaXRlcmFsKS50ZXh0O1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGlmICghbW9kdWxlUGF0aC5zdGFydHNXaXRoKCdAYW5ndWxhci8nKSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGlmIChub2RlLmltcG9ydENsYXVzZSkge1xuICAgIGlmIChub2RlLmltcG9ydENsYXVzZS5uYW1lKSB7XG4gICAgICAvLyBUaGlzIGlzIG9mIHRoZSBmb3JtIGBpbXBvcnQgTmFtZSBmcm9tICdwYXRoJ2AuIElnbm9yZS5cbiAgICAgIHJldHVybiB7fTtcbiAgICB9IGVsc2UgaWYgKG5vZGUuaW1wb3J0Q2xhdXNlLm5hbWVkQmluZGluZ3MpIHtcbiAgICAgIGNvbnN0IG5iID0gbm9kZS5pbXBvcnRDbGF1c2UubmFtZWRCaW5kaW5ncztcbiAgICAgIGlmIChuYi5raW5kID09IHRzLlN5bnRheEtpbmQuTmFtZXNwYWNlSW1wb3J0KSB7XG4gICAgICAgIC8vIFRoaXMgaXMgb2YgdGhlIGZvcm0gYGltcG9ydCAqIGFzIG5hbWUgZnJvbSAncGF0aCdgLiBSZXR1cm4gYG5hbWUuYC5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBbKG5iIGFzIHRzLk5hbWVzcGFjZUltcG9ydCkubmFtZS50ZXh0ICsgJy4nXTogbW9kdWxlUGF0aFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyBpcyBvZiB0aGUgZm9ybSBgaW1wb3J0IHthLGIsY30gZnJvbSAncGF0aCdgXG4gICAgICAgIGNvbnN0IG5hbWVkSW1wb3J0cyA9IG5iIGFzIHRzLk5hbWVkSW1wb3J0cztcblxuICAgICAgICByZXR1cm4gbmFtZWRJbXBvcnRzLmVsZW1lbnRzXG4gICAgICAgICAgLm1hcChcbiAgICAgICAgICAgIChpczogdHMuSW1wb3J0U3BlY2lmaWVyKSA9PlxuICAgICAgICAgICAgICBpcy5wcm9wZXJ0eU5hbWUgPyBpcy5wcm9wZXJ0eU5hbWUudGV4dCA6IGlzLm5hbWUudGV4dFxuICAgICAgICAgIClcbiAgICAgICAgICAucmVkdWNlKChhY2M6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9LCBjdXJyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGFjY1tjdXJyXSA9IG1vZHVsZVBhdGg7XG5cbiAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgfSwge30pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7fTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGlzIGlzIG9mIHRoZSBmb3JtIGBpbXBvcnQgJ3BhdGgnO2AuIE5vdGhpbmcgdG8gZG8uXG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWNvcmF0b3JNZXRhZGF0YShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBpZGVudGlmaWVyOiBzdHJpbmcsXG4gIG1vZHVsZTogc3RyaW5nXG4pOiB0cy5Ob2RlW10ge1xuICBjb25zdCBhbmd1bGFySW1wb3J0czogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0gPSBmaW5kTm9kZXMoXG4gICAgc291cmNlLFxuICAgIHRzLlN5bnRheEtpbmQuSW1wb3J0RGVjbGFyYXRpb25cbiAgKVxuICAgIC5tYXAoKG5vZGU6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiBfYW5ndWxhckltcG9ydHNGcm9tTm9kZShub2RlLCBzb3VyY2UpKVxuICAgIC5yZWR1Y2UoXG4gICAgICAoXG4gICAgICAgIGFjYzogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICAgICAgIGN1cnJlbnQ6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9XG4gICAgICApID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoY3VycmVudCkpIHtcbiAgICAgICAgICBhY2Nba2V5XSA9IGN1cnJlbnRba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuXG4gIHJldHVybiBnZXRTb3VyY2VOb2Rlcyhzb3VyY2UpXG4gICAgLmZpbHRlcihub2RlID0+IHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIG5vZGUua2luZCA9PSB0cy5TeW50YXhLaW5kLkRlY29yYXRvciAmJlxuICAgICAgICAobm9kZSBhcyB0cy5EZWNvcmF0b3IpLmV4cHJlc3Npb24ua2luZCA9PSB0cy5TeW50YXhLaW5kLkNhbGxFeHByZXNzaW9uXG4gICAgICApO1xuICAgIH0pXG4gICAgLm1hcChub2RlID0+IChub2RlIGFzIHRzLkRlY29yYXRvcikuZXhwcmVzc2lvbiBhcyB0cy5DYWxsRXhwcmVzc2lvbilcbiAgICAuZmlsdGVyKGV4cHIgPT4ge1xuICAgICAgaWYgKGV4cHIuZXhwcmVzc2lvbi5raW5kID09IHRzLlN5bnRheEtpbmQuSWRlbnRpZmllcikge1xuICAgICAgICBjb25zdCBpZCA9IGV4cHIuZXhwcmVzc2lvbiBhcyB0cy5JZGVudGlmaWVyO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgaWQuZ2V0RnVsbFRleHQoc291cmNlKSA9PSBpZGVudGlmaWVyICYmXG4gICAgICAgICAgYW5ndWxhckltcG9ydHNbaWQuZ2V0RnVsbFRleHQoc291cmNlKV0gPT09IG1vZHVsZVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXhwci5leHByZXNzaW9uLmtpbmQgPT0gdHMuU3ludGF4S2luZC5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb25cbiAgICAgICkge1xuICAgICAgICAvLyBUaGlzIGNvdmVycyBmb28uTmdNb2R1bGUgd2hlbiBpbXBvcnRpbmcgKiBhcyBmb28uXG4gICAgICAgIGNvbnN0IHBhRXhwciA9IGV4cHIuZXhwcmVzc2lvbiBhcyB0cy5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb247XG4gICAgICAgIC8vIElmIHRoZSBsZWZ0IGV4cHJlc3Npb24gaXMgbm90IGFuIGlkZW50aWZpZXIsIGp1c3QgZ2l2ZSB1cCBhdCB0aGF0IHBvaW50LlxuICAgICAgICBpZiAocGFFeHByLmV4cHJlc3Npb24ua2luZCAhPT0gdHMuU3ludGF4S2luZC5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaWQgPSBwYUV4cHIubmFtZS50ZXh0O1xuICAgICAgICBjb25zdCBtb2R1bGVJZCA9IChwYUV4cHIuZXhwcmVzc2lvbiBhcyB0cy5JZGVudGlmaWVyKS5nZXRUZXh0KHNvdXJjZSk7XG5cbiAgICAgICAgcmV0dXJuIGlkID09PSBpZGVudGlmaWVyICYmIGFuZ3VsYXJJbXBvcnRzW21vZHVsZUlkICsgJy4nXSA9PT0gbW9kdWxlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSlcbiAgICAuZmlsdGVyKFxuICAgICAgZXhwciA9PlxuICAgICAgICBleHByLmFyZ3VtZW50c1swXSAmJlxuICAgICAgICBleHByLmFyZ3VtZW50c1swXS5raW5kID09IHRzLlN5bnRheEtpbmQuT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb25cbiAgICApXG4gICAgLm1hcChleHByID0+IGV4cHIuYXJndW1lbnRzWzBdIGFzIHRzLk9iamVjdExpdGVyYWxFeHByZXNzaW9uKTtcbn1cblxuZnVuY3Rpb24gZmluZENsYXNzRGVjbGFyYXRpb25QYXJlbnQoXG4gIG5vZGU6IHRzLk5vZGVcbik6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB1bmRlZmluZWQge1xuICBpZiAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICByZXR1cm4gbm9kZS5wYXJlbnQgJiYgZmluZENsYXNzRGVjbGFyYXRpb25QYXJlbnQobm9kZS5wYXJlbnQpO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgc291cmNlIGZpbGUgd2l0aCBATmdNb2R1bGUgY2xhc3MoZXMpLCBmaW5kIHRoZSBuYW1lIG9mIHRoZSBmaXJzdCBATmdNb2R1bGUgY2xhc3MuXG4gKlxuICogQHBhcmFtIHNvdXJjZSBzb3VyY2UgZmlsZSBjb250YWluaW5nIG9uZSBvciBtb3JlIEBOZ01vZHVsZVxuICogQHJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGZpcnN0IEBOZ01vZHVsZSwgb3IgYHVuZGVmaW5lZGAgaWYgbm9uZSBpcyBmb3VuZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmlyc3ROZ01vZHVsZU5hbWUoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZVxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgLy8gRmlyc3QsIGZpbmQgdGhlIEBOZ01vZHVsZSBkZWNvcmF0b3JzLlxuICBjb25zdCBuZ01vZHVsZXNNZXRhZGF0YSA9IGdldERlY29yYXRvck1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICAnTmdNb2R1bGUnLFxuICAgICdAYW5ndWxhci9jb3JlJ1xuICApO1xuICBpZiAobmdNb2R1bGVzTWV0YWRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIFRoZW4gd2FsayBwYXJlbnQgcG9pbnRlcnMgdXAgdGhlIEFTVCwgbG9va2luZyBmb3IgdGhlIENsYXNzRGVjbGFyYXRpb24gcGFyZW50IG9mIHRoZSBOZ01vZHVsZVxuICAvLyBtZXRhZGF0YS5cbiAgY29uc3QgbW9kdWxlQ2xhc3MgPSBmaW5kQ2xhc3NEZWNsYXJhdGlvblBhcmVudChuZ01vZHVsZXNNZXRhZGF0YVswXSk7XG4gIGlmICghbW9kdWxlQ2xhc3MgfHwgIW1vZHVsZUNsYXNzLm5hbWUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBtb2R1bGUgQ2xhc3NEZWNsYXJhdGlvbi5cbiAgcmV0dXJuIG1vZHVsZUNsYXNzLm5hbWUudGV4dDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFN5bWJvbFRvTmdNb2R1bGVNZXRhZGF0YShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBuZ01vZHVsZVBhdGg6IHN0cmluZyxcbiAgbWV0YWRhdGFGaWVsZDogc3RyaW5nLFxuICBzeW1ib2xOYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZyB8IG51bGwgPSBudWxsXG4pOiBDaGFuZ2VbXSB7XG4gIGNvbnN0IG5vZGVzID0gZ2V0RGVjb3JhdG9yTWV0YWRhdGEoc291cmNlLCAnTmdNb2R1bGUnLCAnQGFuZ3VsYXIvY29yZScpO1xuICBsZXQgbm9kZTogYW55ID0gbm9kZXNbMF07IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYW55XG5cbiAgLy8gRmluZCB0aGUgZGVjb3JhdG9yIGRlY2xhcmF0aW9uLlxuICBpZiAoIW5vZGUpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBHZXQgYWxsIHRoZSBjaGlsZHJlbiBwcm9wZXJ0eSBhc3NpZ25tZW50IG9mIG9iamVjdCBsaXRlcmFscy5cbiAgY29uc3QgbWF0Y2hpbmdQcm9wZXJ0aWVzOiB0cy5PYmplY3RMaXRlcmFsRWxlbWVudFtdID0gKG5vZGUgYXMgdHMuT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb24pLnByb3BlcnRpZXNcbiAgICAuZmlsdGVyKHByb3AgPT4gcHJvcC5raW5kID09IHRzLlN5bnRheEtpbmQuUHJvcGVydHlBc3NpZ25tZW50KVxuICAgIC8vIEZpbHRlciBvdXQgZXZlcnkgZmllbGRzIHRoYXQncyBub3QgXCJtZXRhZGF0YUZpZWxkXCIuIEFsc28gaGFuZGxlcyBzdHJpbmcgbGl0ZXJhbHNcbiAgICAvLyAoYnV0IG5vdCBleHByZXNzaW9ucykuXG4gICAgLmZpbHRlcigocHJvcDogdHMuUHJvcGVydHlBc3NpZ25tZW50KSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gcHJvcC5uYW1lO1xuICAgICAgc3dpdGNoIChuYW1lLmtpbmQpIHtcbiAgICAgICAgY2FzZSB0cy5TeW50YXhLaW5kLklkZW50aWZpZXI6XG4gICAgICAgICAgcmV0dXJuIChuYW1lIGFzIHRzLklkZW50aWZpZXIpLmdldFRleHQoc291cmNlKSA9PSBtZXRhZGF0YUZpZWxkO1xuICAgICAgICBjYXNlIHRzLlN5bnRheEtpbmQuU3RyaW5nTGl0ZXJhbDpcbiAgICAgICAgICByZXR1cm4gKG5hbWUgYXMgdHMuU3RyaW5nTGl0ZXJhbCkudGV4dCA9PSBtZXRhZGF0YUZpZWxkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSk7XG5cbiAgLy8gR2V0IHRoZSBsYXN0IG5vZGUgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gIGlmICghbWF0Y2hpbmdQcm9wZXJ0aWVzKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmIChtYXRjaGluZ1Byb3BlcnRpZXMubGVuZ3RoID09IDApIHtcbiAgICAvLyBXZSBoYXZlbid0IGZvdW5kIHRoZSBmaWVsZCBpbiB0aGUgbWV0YWRhdGEgZGVjbGFyYXRpb24uIEluc2VydCBhIG5ldyBmaWVsZC5cbiAgICBjb25zdCBleHByID0gbm9kZSBhcyB0cy5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbjtcbiAgICBsZXQgcG9zaXRpb246IG51bWJlcjtcbiAgICBsZXQgdG9JbnNlcnQ6IHN0cmluZztcbiAgICBpZiAoZXhwci5wcm9wZXJ0aWVzLmxlbmd0aCA9PSAwKSB7XG4gICAgICBwb3NpdGlvbiA9IGV4cHIuZ2V0RW5kKCkgLSAxO1xuICAgICAgdG9JbnNlcnQgPSBgICAke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1cXG5gO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlID0gZXhwci5wcm9wZXJ0aWVzW2V4cHIucHJvcGVydGllcy5sZW5ndGggLSAxXTtcbiAgICAgIHBvc2l0aW9uID0gbm9kZS5nZXRFbmQoKTtcbiAgICAgIC8vIEdldCB0aGUgaW5kZW50YXRpb24gb2YgdGhlIGxhc3QgZWxlbWVudCwgaWYgYW55LlxuICAgICAgY29uc3QgdGV4dCA9IG5vZGUuZ2V0RnVsbFRleHQoc291cmNlKTtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSB0ZXh0Lm1hdGNoKC9eXFxyP1xcblxccyovKTtcbiAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdG9JbnNlcnQgPSBgLCR7bWF0Y2hlc1swXX0ke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9JbnNlcnQgPSBgLCAke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1gO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaW1wb3J0UGF0aCAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgbmV3IEluc2VydENoYW5nZShuZ01vZHVsZVBhdGgsIHBvc2l0aW9uLCB0b0luc2VydCksXG4gICAgICAgIGluc2VydEltcG9ydChcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgbmdNb2R1bGVQYXRoLFxuICAgICAgICAgIHN5bWJvbE5hbWUucmVwbGFjZSgvXFwuLiokLywgJycpLFxuICAgICAgICAgIGltcG9ydFBhdGhcbiAgICAgICAgKVxuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFtuZXcgSW5zZXJ0Q2hhbmdlKG5nTW9kdWxlUGF0aCwgcG9zaXRpb24sIHRvSW5zZXJ0KV07XG4gICAgfVxuICB9XG4gIGNvbnN0IGFzc2lnbm1lbnQgPSBtYXRjaGluZ1Byb3BlcnRpZXNbMF0gYXMgdHMuUHJvcGVydHlBc3NpZ25tZW50O1xuXG4gIC8vIElmIGl0J3Mgbm90IGFuIGFycmF5LCBub3RoaW5nIHdlIGNhbiBkbyByZWFsbHkuXG4gIGlmIChhc3NpZ25tZW50LmluaXRpYWxpemVyLmtpbmQgIT09IHRzLlN5bnRheEtpbmQuQXJyYXlMaXRlcmFsRXhwcmVzc2lvbikge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IGFyckxpdGVyYWwgPSBhc3NpZ25tZW50LmluaXRpYWxpemVyIGFzIHRzLkFycmF5TGl0ZXJhbEV4cHJlc3Npb247XG4gIGlmIChhcnJMaXRlcmFsLmVsZW1lbnRzLmxlbmd0aCA9PSAwKSB7XG4gICAgLy8gRm9yd2FyZCB0aGUgcHJvcGVydHkuXG4gICAgbm9kZSA9IGFyckxpdGVyYWw7XG4gIH0gZWxzZSB7XG4gICAgbm9kZSA9IGFyckxpdGVyYWwuZWxlbWVudHM7XG4gIH1cblxuICBpZiAoIW5vZGUpIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgICdObyBhcHAgbW9kdWxlIGZvdW5kLiBQbGVhc2UgYWRkIHlvdXIgbmV3IGNsYXNzIHRvIHlvdXIgY29tcG9uZW50LidcbiAgICApO1xuXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkobm9kZSkpIHtcbiAgICBjb25zdCBub2RlQXJyYXkgPSAobm9kZSBhcyB7fSkgYXMgQXJyYXk8dHMuTm9kZT47XG4gICAgY29uc3Qgc3ltYm9sc0FycmF5ID0gbm9kZUFycmF5Lm1hcChub2RlID0+IG5vZGUuZ2V0VGV4dCgpKTtcbiAgICBpZiAoc3ltYm9sc0FycmF5LmluZGV4T2Yoc3ltYm9sTmFtZSkgPj0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIG5vZGUgPSBub2RlW25vZGUubGVuZ3RoIC0gMV07XG4gIH1cblxuICBsZXQgdG9JbnNlcnQ6IHN0cmluZztcbiAgbGV0IHBvc2l0aW9uID0gbm9kZS5nZXRFbmQoKTtcbiAgaWYgKG5vZGUua2luZCA9PSB0cy5TeW50YXhLaW5kLk9iamVjdExpdGVyYWxFeHByZXNzaW9uKSB7XG4gICAgLy8gV2UgaGF2ZW4ndCBmb3VuZCB0aGUgZmllbGQgaW4gdGhlIG1ldGFkYXRhIGRlY2xhcmF0aW9uLiBJbnNlcnQgYSBuZXdcbiAgICAvLyBmaWVsZC5cbiAgICBjb25zdCBleHByID0gbm9kZSBhcyB0cy5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbjtcbiAgICBpZiAoZXhwci5wcm9wZXJ0aWVzLmxlbmd0aCA9PSAwKSB7XG4gICAgICBwb3NpdGlvbiA9IGV4cHIuZ2V0RW5kKCkgLSAxO1xuICAgICAgdG9JbnNlcnQgPSBgICAke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1cXG5gO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlID0gZXhwci5wcm9wZXJ0aWVzW2V4cHIucHJvcGVydGllcy5sZW5ndGggLSAxXTtcbiAgICAgIHBvc2l0aW9uID0gbm9kZS5nZXRFbmQoKTtcbiAgICAgIC8vIEdldCB0aGUgaW5kZW50YXRpb24gb2YgdGhlIGxhc3QgZWxlbWVudCwgaWYgYW55LlxuICAgICAgY29uc3QgdGV4dCA9IG5vZGUuZ2V0RnVsbFRleHQoc291cmNlKTtcbiAgICAgIGlmICh0ZXh0Lm1hdGNoKCdeXFxyP1xccj9cXG4nKSkge1xuICAgICAgICB0b0luc2VydCA9IGAsJHtcbiAgICAgICAgICB0ZXh0Lm1hdGNoKC9eXFxyP1xcblxccysvKVswXVxuICAgICAgICB9JHttZXRhZGF0YUZpZWxkfTogWyR7c3ltYm9sTmFtZX1dYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvSW5zZXJ0ID0gYCwgJHttZXRhZGF0YUZpZWxkfTogWyR7c3ltYm9sTmFtZX1dYDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAobm9kZS5raW5kID09IHRzLlN5bnRheEtpbmQuQXJyYXlMaXRlcmFsRXhwcmVzc2lvbikge1xuICAgIC8vIFdlIGZvdW5kIHRoZSBmaWVsZCBidXQgaXQncyBlbXB0eS4gSW5zZXJ0IGl0IGp1c3QgYmVmb3JlIHRoZSBgXWAuXG4gICAgcG9zaXRpb24tLTtcbiAgICB0b0luc2VydCA9IGAke3N5bWJvbE5hbWV9YDtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIGluZGVudGF0aW9uIG9mIHRoZSBsYXN0IGVsZW1lbnQsIGlmIGFueS5cbiAgICBjb25zdCB0ZXh0ID0gbm9kZS5nZXRGdWxsVGV4dChzb3VyY2UpO1xuICAgIGlmICh0ZXh0Lm1hdGNoKC9eXFxyP1xcbi8pKSB7XG4gICAgICB0b0luc2VydCA9IGAsJHt0ZXh0Lm1hdGNoKC9eXFxyP1xcbihcXHI/KVxccysvKVswXX0ke3N5bWJvbE5hbWV9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgdG9JbnNlcnQgPSBgLCAke3N5bWJvbE5hbWV9YDtcbiAgICB9XG4gIH1cbiAgaWYgKGltcG9ydFBhdGggIT09IG51bGwpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IEluc2VydENoYW5nZShuZ01vZHVsZVBhdGgsIHBvc2l0aW9uLCB0b0luc2VydCksXG4gICAgICBpbnNlcnRJbXBvcnQoXG4gICAgICAgIHNvdXJjZSxcbiAgICAgICAgbmdNb2R1bGVQYXRoLFxuICAgICAgICBzeW1ib2xOYW1lLnJlcGxhY2UoL1xcLi4qJC8sICcnKSxcbiAgICAgICAgaW1wb3J0UGF0aFxuICAgICAgKVxuICAgIF07XG4gIH1cblxuICByZXR1cm4gW25ldyBJbnNlcnRDaGFuZ2UobmdNb2R1bGVQYXRoLCBwb3NpdGlvbiwgdG9JbnNlcnQpXTtcbn1cblxuLyoqXG4gKiBDdXN0b20gZnVuY3Rpb24gdG8gaW5zZXJ0IGEgZGVjbGFyYXRpb24gKGNvbXBvbmVudCwgcGlwZSwgZGlyZWN0aXZlKVxuICogaW50byBOZ01vZHVsZSBkZWNsYXJhdGlvbnMuIEl0IGFsc28gaW1wb3J0cyB0aGUgY29tcG9uZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRGVjbGFyYXRpb25Ub01vZHVsZShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBtb2R1bGVQYXRoOiBzdHJpbmcsXG4gIGNsYXNzaWZpZWROYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZ1xuKTogQ2hhbmdlW10ge1xuICByZXR1cm4gYWRkU3ltYm9sVG9OZ01vZHVsZU1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICBtb2R1bGVQYXRoLFxuICAgICdkZWNsYXJhdGlvbnMnLFxuICAgIGNsYXNzaWZpZWROYW1lLFxuICAgIGltcG9ydFBhdGhcbiAgKTtcbn1cblxuLyoqXG4gKiBDdXN0b20gZnVuY3Rpb24gdG8gaW5zZXJ0IGFuIE5nTW9kdWxlIGludG8gTmdNb2R1bGUgaW1wb3J0cy4gSXQgYWxzbyBpbXBvcnRzIHRoZSBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRJbXBvcnRUb01vZHVsZShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBtb2R1bGVQYXRoOiBzdHJpbmcsXG4gIGNsYXNzaWZpZWROYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZ1xuKTogQ2hhbmdlW10ge1xuICByZXR1cm4gYWRkU3ltYm9sVG9OZ01vZHVsZU1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICBtb2R1bGVQYXRoLFxuICAgICdpbXBvcnRzJyxcbiAgICBjbGFzc2lmaWVkTmFtZSxcbiAgICBpbXBvcnRQYXRoXG4gICk7XG59XG5cbi8qKlxuICogQ3VzdG9tIGZ1bmN0aW9uIHRvIGluc2VydCBhIHByb3ZpZGVyIGludG8gTmdNb2R1bGUuIEl0IGFsc28gaW1wb3J0cyBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFByb3ZpZGVyVG9Nb2R1bGUoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZSxcbiAgbW9kdWxlUGF0aDogc3RyaW5nLFxuICBjbGFzc2lmaWVkTmFtZTogc3RyaW5nLFxuICBpbXBvcnRQYXRoOiBzdHJpbmdcbik6IENoYW5nZVtdIHtcbiAgcmV0dXJuIGFkZFN5bWJvbFRvTmdNb2R1bGVNZXRhZGF0YShcbiAgICBzb3VyY2UsXG4gICAgbW9kdWxlUGF0aCxcbiAgICAncHJvdmlkZXJzJyxcbiAgICBjbGFzc2lmaWVkTmFtZSxcbiAgICBpbXBvcnRQYXRoXG4gICk7XG59XG5cbi8qKlxuICogQ3VzdG9tIGZ1bmN0aW9uIHRvIGluc2VydCBhbiBleHBvcnQgaW50byBOZ01vZHVsZS4gSXQgYWxzbyBpbXBvcnRzIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRXhwb3J0VG9Nb2R1bGUoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZSxcbiAgbW9kdWxlUGF0aDogc3RyaW5nLFxuICBjbGFzc2lmaWVkTmFtZTogc3RyaW5nLFxuICBpbXBvcnRQYXRoOiBzdHJpbmdcbik6IENoYW5nZVtdIHtcbiAgcmV0dXJuIGFkZFN5bWJvbFRvTmdNb2R1bGVNZXRhZGF0YShcbiAgICBzb3VyY2UsXG4gICAgbW9kdWxlUGF0aCxcbiAgICAnZXhwb3J0cycsXG4gICAgY2xhc3NpZmllZE5hbWUsXG4gICAgaW1wb3J0UGF0aFxuICApO1xufVxuXG4vKipcbiAqIEN1c3RvbSBmdW5jdGlvbiB0byBpbnNlcnQgYW4gZXhwb3J0IGludG8gTmdNb2R1bGUuIEl0IGFsc28gaW1wb3J0cyBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZEJvb3RzdHJhcFRvTW9kdWxlKFxuICBzb3VyY2U6IHRzLlNvdXJjZUZpbGUsXG4gIG1vZHVsZVBhdGg6IHN0cmluZyxcbiAgY2xhc3NpZmllZE5hbWU6IHN0cmluZyxcbiAgaW1wb3J0UGF0aDogc3RyaW5nXG4pOiBDaGFuZ2VbXSB7XG4gIHJldHVybiBhZGRTeW1ib2xUb05nTW9kdWxlTWV0YWRhdGEoXG4gICAgc291cmNlLFxuICAgIG1vZHVsZVBhdGgsXG4gICAgJ2Jvb3RzdHJhcCcsXG4gICAgY2xhc3NpZmllZE5hbWUsXG4gICAgaW1wb3J0UGF0aFxuICApO1xufVxuXG4vKipcbiAqIEN1c3RvbSBmdW5jdGlvbiB0byBpbnNlcnQgYW4gZW50cnlDb21wb25lbnQgaW50byBOZ01vZHVsZS4gSXQgYWxzbyBpbXBvcnRzIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRW50cnlDb21wb25lbnRUb01vZHVsZShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBtb2R1bGVQYXRoOiBzdHJpbmcsXG4gIGNsYXNzaWZpZWROYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZ1xuKTogQ2hhbmdlW10ge1xuICByZXR1cm4gYWRkU3ltYm9sVG9OZ01vZHVsZU1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICBtb2R1bGVQYXRoLFxuICAgICdlbnRyeUNvbXBvbmVudHMnLFxuICAgIGNsYXNzaWZpZWROYW1lLFxuICAgIGltcG9ydFBhdGhcbiAgKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYW4gaW1wb3J0IGFscmVhZHkgZXhpc3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNJbXBvcnRlZChcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBjbGFzc2lmaWVkTmFtZTogc3RyaW5nLFxuICBpbXBvcnRQYXRoOiBzdHJpbmdcbik6IGJvb2xlYW4ge1xuICBjb25zdCBhbGxOb2RlcyA9IGdldFNvdXJjZU5vZGVzKHNvdXJjZSk7XG4gIGNvbnN0IG1hdGNoaW5nTm9kZXMgPSBhbGxOb2Rlc1xuICAgIC5maWx0ZXIobm9kZSA9PiBub2RlLmtpbmQgPT09IHRzLlN5bnRheEtpbmQuSW1wb3J0RGVjbGFyYXRpb24pXG4gICAgLmZpbHRlcihcbiAgICAgIChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PlxuICAgICAgICBpbXAubW9kdWxlU3BlY2lmaWVyLmtpbmQgPT09IHRzLlN5bnRheEtpbmQuU3RyaW5nTGl0ZXJhbFxuICAgIClcbiAgICAuZmlsdGVyKChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiB7XG4gICAgICByZXR1cm4gKDx0cy5TdHJpbmdMaXRlcmFsPmltcC5tb2R1bGVTcGVjaWZpZXIpLnRleHQgPT09IGltcG9ydFBhdGg7XG4gICAgfSlcbiAgICAuZmlsdGVyKChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBpZiAoIWltcC5pbXBvcnRDbGF1c2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3Qgbm9kZXMgPSBmaW5kTm9kZXMoXG4gICAgICAgIGltcC5pbXBvcnRDbGF1c2UsXG4gICAgICAgIHRzLlN5bnRheEtpbmQuSW1wb3J0U3BlY2lmaWVyXG4gICAgICApLmZpbHRlcihuID0+IG4uZ2V0VGV4dCgpID09PSBjbGFzc2lmaWVkTmFtZSk7XG5cbiAgICAgIHJldHVybiBub2Rlcy5sZW5ndGggPiAwO1xuICAgIH0pO1xuXG4gIHJldHVybiBtYXRjaGluZ05vZGVzLmxlbmd0aCA+IDA7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQgeyBKc29uUGFyc2VNb2RlLCBleHBlcmltZW50YWwsIHBhcnNlSnNvbiB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IFJ1bGUsIFNjaGVtYXRpY0NvbnRleHQsIFNjaGVtYXRpY3NFeGNlcHRpb24sIFRyZWUgfSBmcm9tICdAYW5ndWxhci1kZXZraXQvc2NoZW1hdGljcyc7XG5cblxuLy8gVGhlIGludGVyZmFjZXMgYmVsb3cgYXJlIGdlbmVyYXRlZCBmcm9tIHRoZSBBbmd1bGFyIENMSSBjb25maWd1cmF0aW9uIHNjaGVtYVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci1jbGkvYmxvYi9tYXN0ZXIvcGFja2FnZXMvQGFuZ3VsYXIvY2xpL2xpYi9jb25maWcvc2NoZW1hLmpzb25cbmV4cG9ydCBpbnRlcmZhY2UgQXBwQ29uZmlnIHtcbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIGFwcC5cbiAgICovXG4gIG5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBEaXJlY3Rvcnkgd2hlcmUgYXBwIGZpbGVzIGFyZSBwbGFjZWQuXG4gICAqL1xuICBhcHBSb290Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoZSBhcHAuXG4gICAqL1xuICByb290Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIG91dHB1dCBkaXJlY3RvcnkgZm9yIGJ1aWxkIHJlc3VsdHMuXG4gICAqL1xuICBvdXREaXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBMaXN0IG9mIGFwcGxpY2F0aW9uIGFzc2V0cy5cbiAgICovXG4gIGFzc2V0cz86IChzdHJpbmcgfCB7XG4gICAgICAvKipcbiAgICAgICAqIFRoZSBwYXR0ZXJuIHRvIG1hdGNoLlxuICAgICAgICovXG4gICAgICBnbG9iPzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgZGlyIHRvIHNlYXJjaCB3aXRoaW4uXG4gICAgICAgKi9cbiAgICAgIGlucHV0Pzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgb3V0cHV0IHBhdGggKHJlbGF0aXZlIHRvIHRoZSBvdXREaXIpLlxuICAgICAgICovXG4gICAgICBvdXRwdXQ/OiBzdHJpbmc7XG4gIH0pW107XG4gIC8qKlxuICAgKiBVUkwgd2hlcmUgZmlsZXMgd2lsbCBiZSBkZXBsb3llZC5cbiAgICovXG4gIGRlcGxveVVybD86IHN0cmluZztcbiAgLyoqXG4gICAqIEJhc2UgdXJsIGZvciB0aGUgYXBwbGljYXRpb24gYmVpbmcgYnVpbHQuXG4gICAqL1xuICBiYXNlSHJlZj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBydW50aW1lIHBsYXRmb3JtIG9mIHRoZSBhcHAuXG4gICAqL1xuICBwbGF0Zm9ybT86ICgnYnJvd3NlcicgfCAnc2VydmVyJyk7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgc3RhcnQgSFRNTCBmaWxlLlxuICAgKi9cbiAgaW5kZXg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgbWFpbiBlbnRyeS1wb2ludCBmaWxlLlxuICAgKi9cbiAgbWFpbj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBwb2x5ZmlsbHMgZmlsZS5cbiAgICovXG4gIHBvbHlmaWxscz86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSB0ZXN0IGVudHJ5LXBvaW50IGZpbGUuXG4gICAqL1xuICB0ZXN0Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIFR5cGVTY3JpcHQgY29uZmlndXJhdGlvbiBmaWxlLlxuICAgKi9cbiAgdHNjb25maWc/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgVHlwZVNjcmlwdCBjb25maWd1cmF0aW9uIGZpbGUgZm9yIHVuaXQgdGVzdHMuXG4gICAqL1xuICB0ZXN0VHNjb25maWc/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgcHJlZml4IHRvIGFwcGx5IHRvIGdlbmVyYXRlZCBzZWxlY3RvcnMuXG4gICAqL1xuICBwcmVmaXg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFeHBlcmltZW50YWwgc3VwcG9ydCBmb3IgYSBzZXJ2aWNlIHdvcmtlciBmcm9tIEBhbmd1bGFyL3NlcnZpY2Utd29ya2VyLlxuICAgKi9cbiAgc2VydmljZVdvcmtlcj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBHbG9iYWwgc3R5bGVzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBidWlsZC5cbiAgICovXG4gIHN0eWxlcz86IChzdHJpbmcgfCB7XG4gICAgICBpbnB1dD86IHN0cmluZztcbiAgICAgIFtuYW1lOiBzdHJpbmddOiBhbnk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYW55XG4gIH0pW107XG4gIC8qKlxuICAgKiBPcHRpb25zIHRvIHBhc3MgdG8gc3R5bGUgcHJlcHJvY2Vzc29yc1xuICAgKi9cbiAgc3R5bGVQcmVwcm9jZXNzb3JPcHRpb25zPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBQYXRocyB0byBpbmNsdWRlLiBQYXRocyB3aWxsIGJlIHJlc29sdmVkIHRvIHByb2plY3Qgcm9vdC5cbiAgICAgICAqL1xuICAgICAgaW5jbHVkZVBhdGhzPzogc3RyaW5nW107XG4gIH07XG4gIC8qKlxuICAgKiBHbG9iYWwgc2NyaXB0cyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gICAqL1xuICBzY3JpcHRzPzogKHN0cmluZyB8IHtcbiAgICAgIGlucHV0OiBzdHJpbmc7XG4gICAgICBbbmFtZTogc3RyaW5nXTogYW55OyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWFueVxuICB9KVtdO1xuICAvKipcbiAgICogU291cmNlIGZpbGUgZm9yIGVudmlyb25tZW50IGNvbmZpZy5cbiAgICovXG4gIGVudmlyb25tZW50U291cmNlPzogc3RyaW5nO1xuICAvKipcbiAgICogTmFtZSBhbmQgY29ycmVzcG9uZGluZyBmaWxlIGZvciBlbnZpcm9ubWVudCBjb25maWcuXG4gICAqL1xuICBlbnZpcm9ubWVudHM/OiB7XG4gICAgICBbbmFtZTogc3RyaW5nXTogYW55OyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWFueVxuICB9O1xuICBhcHBTaGVsbD86IHtcbiAgICBhcHA6IHN0cmluZztcbiAgICByb3V0ZTogc3RyaW5nO1xuICB9O1xuICBidWRnZXRzPzoge1xuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGJ1ZGdldFxuICAgICAqL1xuICAgIHR5cGU/OiAoJ2J1bmRsZScgfCAnaW5pdGlhbCcgfCAnYWxsU2NyaXB0JyB8ICdhbGwnIHwgJ2FueVNjcmlwdCcgfCAnYW55Jyk7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJ1bmRsZVxuICAgICAqL1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2VsaW5lIHNpemUgZm9yIGNvbXBhcmlzb24uXG4gICAgICovXG4gICAgYmFzZWxpbmU/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdGhyZXNob2xkIGZvciB3YXJuaW5nIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtYXhpbXVtV2FybmluZz86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB0aHJlc2hvbGQgZm9yIGVycm9yIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtYXhpbXVtRXJyb3I/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdGhyZXNob2xkIGZvciB3YXJuaW5nIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtaW5pbXVtV2FybmluZz86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB0aHJlc2hvbGQgZm9yIGVycm9yIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtaW5pbXVtRXJyb3I/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIHRocmVzaG9sZCBmb3Igd2FybmluZyByZWxhdGl2ZSB0byB0aGUgYmFzZWxpbmUgKG1pbiAmIG1heCkuXG4gICAgICovXG4gICAgd2FybmluZz86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgdGhyZXNob2xkIGZvciBlcnJvciByZWxhdGl2ZSB0byB0aGUgYmFzZWxpbmUgKG1pbiAmIG1heCkuXG4gICAgICovXG4gICAgZXJyb3I/OiBzdHJpbmc7XG4gIH1bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDbGlDb25maWcge1xuICAkc2NoZW1hPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGdsb2JhbCBjb25maWd1cmF0aW9uIG9mIHRoZSBwcm9qZWN0LlxuICAgKi9cbiAgcHJvamVjdD86IHtcbiAgICAgIC8qKlxuICAgICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2plY3QuXG4gICAgICAgKi9cbiAgICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgICAvKipcbiAgICAgICAqIFdoZXRoZXIgb3Igbm90IHRoaXMgcHJvamVjdCB3YXMgZWplY3RlZC5cbiAgICAgICAqL1xuICAgICAgZWplY3RlZD86IGJvb2xlYW47XG4gIH07XG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIG9mIHRoZSBkaWZmZXJlbnQgYXBwbGljYXRpb25zIGluIHRoaXMgcHJvamVjdC5cbiAgICovXG4gIGFwcHM/OiBBcHBDb25maWdbXTtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIGVuZC10by1lbmQgdGVzdHMuXG4gICAqL1xuICBlMmU/OiB7XG4gICAgICBwcm90cmFjdG9yPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFBhdGggdG8gdGhlIGNvbmZpZyBmaWxlLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGNvbmZpZz86IHN0cmluZztcbiAgICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIHRvIGJlIHBhc3NlZCB0byBUU0xpbnQuXG4gICAqL1xuICBsaW50Pzoge1xuICAgICAgLyoqXG4gICAgICAgKiBGaWxlIGdsb2IocykgdG8gbGludC5cbiAgICAgICAqL1xuICAgICAgZmlsZXM/OiAoc3RyaW5nIHwgc3RyaW5nW10pO1xuICAgICAgLyoqXG4gICAgICAgKiBMb2NhdGlvbiBvZiB0aGUgdHNjb25maWcuanNvbiBwcm9qZWN0IGZpbGUuXG4gICAgICAgKiBXaWxsIGFsc28gdXNlIGFzIGZpbGVzIHRvIGxpbnQgaWYgJ2ZpbGVzJyBwcm9wZXJ0eSBub3QgcHJlc2VudC5cbiAgICAgICAqL1xuICAgICAgcHJvamVjdDogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBMb2NhdGlvbiBvZiB0aGUgdHNsaW50Lmpzb24gY29uZmlndXJhdGlvbi5cbiAgICAgICAqL1xuICAgICAgdHNsaW50Q29uZmlnPzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBGaWxlIGdsb2IocykgdG8gaWdub3JlLlxuICAgICAgICovXG4gICAgICBleGNsdWRlPzogKHN0cmluZyB8IHN0cmluZ1tdKTtcbiAgfVtdO1xuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBmb3IgdW5pdCB0ZXN0cy5cbiAgICovXG4gIHRlc3Q/OiB7XG4gICAgICBrYXJtYT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBQYXRoIHRvIHRoZSBrYXJtYSBjb25maWcgZmlsZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb25maWc/OiBzdHJpbmc7XG4gICAgICB9O1xuICAgICAgY29kZUNvdmVyYWdlPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEdsb2JzIHRvIGV4Y2x1ZGUgZnJvbSBjb2RlIGNvdmVyYWdlLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGV4Y2x1ZGU/OiBzdHJpbmdbXTtcbiAgICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBkZWZhdWx0IHZhbHVlcyBmb3IgZ2VuZXJhdGluZy5cbiAgICovXG4gIGRlZmF1bHRzPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgZmlsZSBleHRlbnNpb24gdG8gYmUgdXNlZCBmb3Igc3R5bGUgZmlsZXMuXG4gICAgICAgKi9cbiAgICAgIHN0eWxlRXh0Pzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBIb3cgb2Z0ZW4gdG8gY2hlY2sgZm9yIGZpbGUgdXBkYXRlcy5cbiAgICAgICAqL1xuICAgICAgcG9sbD86IG51bWJlcjtcbiAgICAgIC8qKlxuICAgICAgICogVXNlIGxpbnQgdG8gZml4IGZpbGVzIGFmdGVyIGdlbmVyYXRpb25cbiAgICAgICAqL1xuICAgICAgbGludEZpeD86IGJvb2xlYW47XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBjbGFzcy5cbiAgICAgICAqL1xuICAgICAgY2xhc3M/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBjb21wb25lbnQuXG4gICAgICAgKi9cbiAgICAgIGNvbXBvbmVudD86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGEgZGlyIGlzIGNyZWF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZmxhdD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBTcGVjaWZpZXMgaWYgdGhlIHN0eWxlIHdpbGwgYmUgaW4gdGhlIHRzIGZpbGUuXG4gICAgICAgICAgICovXG4gICAgICAgICAgaW5saW5lU3R5bGU/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNwZWNpZmllcyBpZiB0aGUgdGVtcGxhdGUgd2lsbCBiZSBpbiB0aGUgdHMgZmlsZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBpbmxpbmVUZW1wbGF0ZT86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIHRoZSB2aWV3IGVuY2Fwc3VsYXRpb24gc3RyYXRlZ3kuXG4gICAgICAgICAgICovXG4gICAgICAgICAgdmlld0VuY2Fwc3VsYXRpb24/OiAoJ0VtdWxhdGVkJyB8ICdOYXRpdmUnIHwgJ05vbmUnKTtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBTcGVjaWZpZXMgdGhlIGNoYW5nZSBkZXRlY3Rpb24gc3RyYXRlZ3kuXG4gICAgICAgICAgICovXG4gICAgICAgICAgY2hhbmdlRGV0ZWN0aW9uPzogKCdEZWZhdWx0JyB8ICdPblB1c2gnKTtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBkaXJlY3RpdmUuXG4gICAgICAgKi9cbiAgICAgIGRpcmVjdGl2ZT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGEgZGlyIGlzIGNyZWF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZmxhdD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBndWFyZC5cbiAgICAgICAqL1xuICAgICAgZ3VhcmQ/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRmxhZyB0byBpbmRpY2F0ZSBpZiBhIGRpciBpcyBjcmVhdGVkLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGZsYXQ/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNwZWNpZmllcyBpZiBhIHNwZWMgZmlsZSBpcyBnZW5lcmF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgc3BlYz86IGJvb2xlYW47XG4gICAgICB9O1xuICAgICAgLyoqXG4gICAgICAgKiBPcHRpb25zIGZvciBnZW5lcmF0aW5nIGFuIGludGVyZmFjZS5cbiAgICAgICAqL1xuICAgICAgaW50ZXJmYWNlPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFByZWZpeCB0byBhcHBseSB0byBpbnRlcmZhY2UgbmFtZXMuIChpLmUuIEkpXG4gICAgICAgICAgICovXG4gICAgICAgICAgcHJlZml4Pzogc3RyaW5nO1xuICAgICAgfTtcbiAgICAgIC8qKlxuICAgICAgICogT3B0aW9ucyBmb3IgZ2VuZXJhdGluZyBhIG1vZHVsZS5cbiAgICAgICAqL1xuICAgICAgbW9kdWxlPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEZsYWcgdG8gaW5kaWNhdGUgaWYgYSBkaXIgaXMgY3JlYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBmbGF0PzogYm9vbGVhbjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBTcGVjaWZpZXMgaWYgYSBzcGVjIGZpbGUgaXMgZ2VuZXJhdGVkLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHNwZWM/OiBib29sZWFuO1xuICAgICAgfTtcbiAgICAgIC8qKlxuICAgICAgICogT3B0aW9ucyBmb3IgZ2VuZXJhdGluZyBhIHBpcGUuXG4gICAgICAgKi9cbiAgICAgIHBpcGU/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRmxhZyB0byBpbmRpY2F0ZSBpZiBhIGRpciBpcyBjcmVhdGVkLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGZsYXQ/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNwZWNpZmllcyBpZiBhIHNwZWMgZmlsZSBpcyBnZW5lcmF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgc3BlYz86IGJvb2xlYW47XG4gICAgICB9O1xuICAgICAgLyoqXG4gICAgICAgKiBPcHRpb25zIGZvciBnZW5lcmF0aW5nIGEgc2VydmljZS5cbiAgICAgICAqL1xuICAgICAgc2VydmljZT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGEgZGlyIGlzIGNyZWF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZmxhdD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgdG8gYmUgcGFzc2VkIHRvIHRoZSBidWlsZCBjb21tYW5kLlxuICAgICAgICovXG4gICAgICBidWlsZD86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBPdXRwdXQgc291cmNlbWFwcy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzb3VyY2VtYXBzPzogYm9vbGVhbjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBCYXNlIHVybCBmb3IgdGhlIGFwcGxpY2F0aW9uIGJlaW5nIGJ1aWx0LlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGJhc2VIcmVmPzogc3RyaW5nO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFRoZSBzc2wga2V5IHVzZWQgYnkgdGhlIHNlcnZlci5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBwcm9ncmVzcz86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRW5hYmxlIGFuZCBkZWZpbmUgdGhlIGZpbGUgd2F0Y2hpbmcgcG9sbCB0aW1lIHBlcmlvZCAobWlsbGlzZWNvbmRzKS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBwb2xsPzogbnVtYmVyO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIERlbGV0ZSBvdXRwdXQgcGF0aCBiZWZvcmUgYnVpbGQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZGVsZXRlT3V0cHV0UGF0aD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRG8gbm90IHVzZSB0aGUgcmVhbCBwYXRoIHdoZW4gcmVzb2x2aW5nIG1vZHVsZXMuXG4gICAgICAgICAgICovXG4gICAgICAgICAgcHJlc2VydmVTeW1saW5rcz86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU2hvdyBjaXJjdWxhciBkZXBlbmRlbmN5IHdhcm5pbmdzIG9uIGJ1aWxkcy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzaG93Q2lyY3VsYXJEZXBlbmRlbmNpZXM/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFVzZSBhIHNlcGFyYXRlIGJ1bmRsZSBjb250YWluaW5nIGNvZGUgdXNlZCBhY3Jvc3MgbXVsdGlwbGUgYnVuZGxlcy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb21tb25DaHVuaz86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogVXNlIGZpbGUgbmFtZSBmb3IgbGF6eSBsb2FkZWQgY2h1bmtzLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIG5hbWVkQ2h1bmtzPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgdG8gYmUgcGFzc2VkIHRvIHRoZSBzZXJ2ZSBjb21tYW5kLlxuICAgICAgICovXG4gICAgICBzZXJ2ZT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgcG9ydCB0aGUgYXBwbGljYXRpb24gd2lsbCBiZSBzZXJ2ZWQgb24uXG4gICAgICAgICAgICovXG4gICAgICAgICAgcG9ydD86IG51bWJlcjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgaG9zdCB0aGUgYXBwbGljYXRpb24gd2lsbCBiZSBzZXJ2ZWQgb24uXG4gICAgICAgICAgICovXG4gICAgICAgICAgaG9zdD86IHN0cmluZztcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBFbmFibGVzIHNzbCBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHNzbD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogVGhlIHNzbCBrZXkgdXNlZCBieSB0aGUgc2VydmVyLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHNzbEtleT86IHN0cmluZztcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgc3NsIGNlcnRpZmljYXRlIHVzZWQgYnkgdGhlIHNlcnZlci5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzc2xDZXJ0Pzogc3RyaW5nO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFByb3h5IGNvbmZpZ3VyYXRpb24gZmlsZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBwcm94eUNvbmZpZz86IHN0cmluZztcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgYWJvdXQgc2NoZW1hdGljcy5cbiAgICAgICAqL1xuICAgICAgc2NoZW1hdGljcz86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgc2NoZW1hdGljcyBjb2xsZWN0aW9uIHRvIHVzZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb2xsZWN0aW9uPzogc3RyaW5nO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFRoZSBuZXcgYXBwIHNjaGVtYXRpYy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBuZXdBcHA/OiBzdHJpbmc7XG4gICAgICB9O1xuICB9O1xuICAvKipcbiAgICogU3BlY2lmeSB3aGljaCBwYWNrYWdlIG1hbmFnZXIgdG9vbCB0byB1c2UuXG4gICAqL1xuICBwYWNrYWdlTWFuYWdlcj86ICgnbnBtJyB8ICdjbnBtJyB8ICd5YXJuJyB8ICdkZWZhdWx0Jyk7XG4gIC8qKlxuICAgKiBBbGxvdyBwZW9wbGUgdG8gZGlzYWJsZSBjb25zb2xlIHdhcm5pbmdzLlxuICAgKi9cbiAgd2FybmluZ3M/OiB7XG4gICAgICAvKipcbiAgICAgICAqIFNob3cgYSB3YXJuaW5nIHdoZW4gdGhlIHVzZXIgZW5hYmxlZCB0aGUgLS1obXIgb3B0aW9uLlxuICAgICAgICovXG4gICAgICBobXJXYXJuaW5nPzogYm9vbGVhbjtcbiAgICAgIC8qKlxuICAgICAgICogU2hvdyBhIHdhcm5pbmcgd2hlbiB0aGUgbm9kZSB2ZXJzaW9uIGlzIGluY29tcGF0aWJsZS5cbiAgICAgICAqL1xuICAgICAgbm9kZURlcHJlY2F0aW9uPzogYm9vbGVhbjtcbiAgICAgIC8qKlxuICAgICAgICogU2hvdyBhIHdhcm5pbmcgd2hlbiB0aGUgdXNlciBpbnN0YWxsZWQgYW5ndWxhci1jbGkuXG4gICAgICAgKi9cbiAgICAgIHBhY2thZ2VEZXByZWNhdGlvbj86IGJvb2xlYW47XG4gICAgICAvKipcbiAgICAgICAqIFNob3cgYSB3YXJuaW5nIHdoZW4gdGhlIGdsb2JhbCB2ZXJzaW9uIGlzIG5ld2VyIHRoYW4gdGhlIGxvY2FsIG9uZS5cbiAgICAgICAqL1xuICAgICAgdmVyc2lvbk1pc21hdGNoPzogYm9vbGVhbjtcbiAgICAgIC8qKlxuICAgICAgICogU2hvdyBhIHdhcm5pbmcgd2hlbiB0aGUgVHlwZVNjcmlwdCB2ZXJzaW9uIGlzIGluY29tcGF0aWJsZVxuICAgICAgICovXG4gICAgICB0eXBlc2NyaXB0TWlzbWF0Y2g/OiBib29sZWFuO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VTY2hlbWEgPSBleHBlcmltZW50YWwud29ya3NwYWNlLldvcmtzcGFjZVNjaGVtYTtcbmV4cG9ydCB0eXBlIFdvcmtzcGFjZVByb2plY3QgPSBleHBlcmltZW50YWwud29ya3NwYWNlLldvcmtzcGFjZVByb2plY3Q7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtzcGFjZVBhdGgoaG9zdDogVHJlZSk6IHN0cmluZyB7XG4gIGNvbnN0IHBvc3NpYmxlRmlsZXMgPSBbICcvYW5ndWxhci5qc29uJywgJy8uYW5ndWxhci5qc29uJyBdO1xuICBjb25zdCBwYXRoID0gcG9zc2libGVGaWxlcy5maWx0ZXIocGF0aCA9PiBob3N0LmV4aXN0cyhwYXRoKSlbMF07XG5cbiAgcmV0dXJuIHBhdGg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3Jrc3BhY2UoaG9zdDogVHJlZSk6IFdvcmtzcGFjZVNjaGVtYSB7XG4gIGNvbnN0IHBhdGggPSBnZXRXb3Jrc3BhY2VQYXRoKGhvc3QpO1xuICBjb25zdCBjb25maWdCdWZmZXIgPSBob3N0LnJlYWQocGF0aCk7XG4gIGlmIChjb25maWdCdWZmZXIgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgU2NoZW1hdGljc0V4Y2VwdGlvbihgQ291bGQgbm90IGZpbmQgKCR7cGF0aH0pYCk7XG4gIH1cbiAgY29uc3QgY29udGVudCA9IGNvbmZpZ0J1ZmZlci50b1N0cmluZygpO1xuXG4gIHJldHVybiBwYXJzZUpzb24oY29udGVudCwgSnNvblBhcnNlTW9kZS5Mb29zZSkgYXMge30gYXMgV29ya3NwYWNlU2NoZW1hO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkUHJvamVjdFRvV29ya3NwYWNlKFxuICB3b3Jrc3BhY2U6IFdvcmtzcGFjZVNjaGVtYSxcbiAgbmFtZTogc3RyaW5nLFxuICBwcm9qZWN0OiBXb3Jrc3BhY2VQcm9qZWN0LFxuKTogUnVsZSB7XG4gIHJldHVybiAoaG9zdDogVHJlZSwgY29udGV4dDogU2NoZW1hdGljQ29udGV4dCkgPT4ge1xuXG4gICAgaWYgKHdvcmtzcGFjZS5wcm9qZWN0c1tuYW1lXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm9qZWN0ICcke25hbWV9JyBhbHJlYWR5IGV4aXN0cyBpbiB3b3Jrc3BhY2UuYCk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHByb2plY3QgdG8gd29ya3NwYWNlLlxuICAgIHdvcmtzcGFjZS5wcm9qZWN0c1tuYW1lXSA9IHByb2plY3Q7XG5cbiAgICBpZiAoIXdvcmtzcGFjZS5kZWZhdWx0UHJvamVjdCAmJiBPYmplY3Qua2V5cyh3b3Jrc3BhY2UucHJvamVjdHMpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgLy8gTWFrZSB0aGUgbmV3IHByb2plY3QgdGhlIGRlZmF1bHQgb25lLlxuICAgICAgd29ya3NwYWNlLmRlZmF1bHRQcm9qZWN0ID0gbmFtZTtcbiAgICB9XG5cbiAgICBob3N0Lm92ZXJ3cml0ZShnZXRXb3Jrc3BhY2VQYXRoKGhvc3QpLCBKU09OLnN0cmluZ2lmeSh3b3Jrc3BhY2UsIG51bGwsIDIpKTtcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbmZpZ1BhdGggPSAnLy5hbmd1bGFyLWNsaS5qc29uJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbmZpZyhob3N0OiBUcmVlKTogQ2xpQ29uZmlnIHtcbiAgY29uc3QgY29uZmlnQnVmZmVyID0gaG9zdC5yZWFkKGNvbmZpZ1BhdGgpO1xuICBpZiAoY29uZmlnQnVmZmVyID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oJ0NvdWxkIG5vdCBmaW5kIC5hbmd1bGFyLWNsaS5qc29uJyk7XG4gIH1cblxuICBjb25zdCBjb25maWcgPSBwYXJzZUpzb24oY29uZmlnQnVmZmVyLnRvU3RyaW5nKCksIEpzb25QYXJzZU1vZGUuTG9vc2UpIGFzIHt9IGFzIENsaUNvbmZpZztcblxuICByZXR1cm4gY29uZmlnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXBwRnJvbUNvbmZpZyhjb25maWc6IENsaUNvbmZpZywgYXBwSW5kZXhPck5hbWU6IHN0cmluZyk6IEFwcENvbmZpZyB8IG51bGwge1xuICBpZiAoIWNvbmZpZy5hcHBzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAocGFyc2VJbnQoYXBwSW5kZXhPck5hbWUpID49IDApIHtcbiAgICByZXR1cm4gY29uZmlnLmFwcHNbcGFyc2VJbnQoYXBwSW5kZXhPck5hbWUpXTtcbiAgfVxuXG4gIHJldHVybiBjb25maWcuYXBwcy5maWx0ZXIoKGFwcCkgPT4gYXBwLm5hbWUgPT09IGFwcEluZGV4T3JOYW1lKVswXTtcbn1cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IFNjaGVtYXRpY3NFeGNlcHRpb24sIFRyZWUgfSBmcm9tICdAYW5ndWxhci1kZXZraXQvc2NoZW1hdGljcyc7XG5pbXBvcnQgeyBkaXJuYW1lIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyB0cyBmcm9tICd0eXBlc2NyaXB0JztcbmltcG9ydCB7IGZpbmROb2RlLCBnZXRTb3VyY2VOb2RlcyB9IGZyb20gJy4uL3V0aWxpdHkvYXN0LXV0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRCb290c3RyYXBNb2R1bGVDYWxsKGhvc3Q6IFRyZWUsIG1haW5QYXRoOiBzdHJpbmcpOiB0cy5DYWxsRXhwcmVzc2lvbiB8IG51bGwge1xuICBjb25zdCBtYWluQnVmZmVyID0gaG9zdC5yZWFkKG1haW5QYXRoKTtcbiAgaWYgKCFtYWluQnVmZmVyKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oYE1haW4gZmlsZSAoJHttYWluUGF0aH0pIG5vdCBmb3VuZGApO1xuICB9XG4gIGNvbnN0IG1haW5UZXh0ID0gbWFpbkJ1ZmZlci50b1N0cmluZygndXRmLTgnKTtcbiAgY29uc3Qgc291cmNlID0gdHMuY3JlYXRlU291cmNlRmlsZShtYWluUGF0aCwgbWFpblRleHQsIHRzLlNjcmlwdFRhcmdldC5MYXRlc3QsIHRydWUpO1xuXG4gIGNvbnN0IGFsbE5vZGVzID0gZ2V0U291cmNlTm9kZXMoc291cmNlKTtcblxuICBsZXQgYm9vdHN0cmFwQ2FsbDogdHMuQ2FsbEV4cHJlc3Npb24gfCBudWxsID0gbnVsbDtcblxuICBmb3IgKGNvbnN0IG5vZGUgb2YgYWxsTm9kZXMpIHtcblxuICAgIGxldCBib290c3RyYXBDYWxsTm9kZTogdHMuTm9kZSB8IG51bGwgPSBudWxsO1xuICAgIGJvb3RzdHJhcENhbGxOb2RlID0gZmluZE5vZGUobm9kZSwgdHMuU3ludGF4S2luZC5JZGVudGlmaWVyLCAnYm9vdHN0cmFwTW9kdWxlJyk7XG5cbiAgICAvLyBXYWxrIHVwIHRoZSBwYXJlbnQgdW50aWwgQ2FsbEV4cHJlc3Npb24gaXMgZm91bmQuXG4gICAgd2hpbGUgKGJvb3RzdHJhcENhbGxOb2RlICYmIGJvb3RzdHJhcENhbGxOb2RlLnBhcmVudFxuICAgICAgJiYgYm9vdHN0cmFwQ2FsbE5vZGUucGFyZW50LmtpbmQgIT09IHRzLlN5bnRheEtpbmQuQ2FsbEV4cHJlc3Npb24pIHtcblxuICAgICAgYm9vdHN0cmFwQ2FsbE5vZGUgPSBib290c3RyYXBDYWxsTm9kZS5wYXJlbnQ7XG4gICAgfVxuXG4gICAgaWYgKGJvb3RzdHJhcENhbGxOb2RlICE9PSBudWxsICYmXG4gICAgICBib290c3RyYXBDYWxsTm9kZS5wYXJlbnQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgYm9vdHN0cmFwQ2FsbE5vZGUucGFyZW50LmtpbmQgPT09IHRzLlN5bnRheEtpbmQuQ2FsbEV4cHJlc3Npb24pIHtcbiAgICAgIGJvb3RzdHJhcENhbGwgPSBib290c3RyYXBDYWxsTm9kZS5wYXJlbnQgYXMgdHMuQ2FsbEV4cHJlc3Npb247XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYm9vdHN0cmFwQ2FsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRCb290c3RyYXBNb2R1bGVQYXRoKGhvc3Q6IFRyZWUsIG1haW5QYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBib290c3RyYXBDYWxsID0gZmluZEJvb3RzdHJhcE1vZHVsZUNhbGwoaG9zdCwgbWFpblBhdGgpO1xuICBpZiAoIWJvb3RzdHJhcENhbGwpIHtcbiAgICB0aHJvdyBuZXcgU2NoZW1hdGljc0V4Y2VwdGlvbignQm9vdHN0cmFwIGNhbGwgbm90IGZvdW5kJyk7XG4gIH1cblxuICBjb25zdCBib290c3RyYXBNb2R1bGUgPSBib290c3RyYXBDYWxsLmFyZ3VtZW50c1swXTtcblxuICBjb25zdCBtYWluQnVmZmVyID0gaG9zdC5yZWFkKG1haW5QYXRoKTtcbiAgaWYgKCFtYWluQnVmZmVyKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oYENsaWVudCBhcHAgbWFpbiBmaWxlICgke21haW5QYXRofSkgbm90IGZvdW5kYCk7XG4gIH1cbiAgY29uc3QgbWFpblRleHQgPSBtYWluQnVmZmVyLnRvU3RyaW5nKCd1dGYtOCcpO1xuICBjb25zdCBzb3VyY2UgPSB0cy5jcmVhdGVTb3VyY2VGaWxlKG1haW5QYXRoLCBtYWluVGV4dCwgdHMuU2NyaXB0VGFyZ2V0LkxhdGVzdCwgdHJ1ZSk7XG4gIGNvbnN0IGFsbE5vZGVzID0gZ2V0U291cmNlTm9kZXMoc291cmNlKTtcbiAgY29uc3QgYm9vdHN0cmFwTW9kdWxlUmVsYXRpdmVQYXRoID0gYWxsTm9kZXNcbiAgICAuZmlsdGVyKG5vZGUgPT4gbm9kZS5raW5kID09PSB0cy5TeW50YXhLaW5kLkltcG9ydERlY2xhcmF0aW9uKVxuICAgIC5maWx0ZXIoaW1wID0+IHtcbiAgICAgIHJldHVybiBmaW5kTm9kZShpbXAsIHRzLlN5bnRheEtpbmQuSWRlbnRpZmllciwgYm9vdHN0cmFwTW9kdWxlLmdldFRleHQoKSk7XG4gICAgfSlcbiAgICAubWFwKChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBtb2R1bGVQYXRoU3RyaW5nTGl0ZXJhbCA9IDx0cy5TdHJpbmdMaXRlcmFsPiBpbXAubW9kdWxlU3BlY2lmaWVyO1xuXG4gICAgICByZXR1cm4gbW9kdWxlUGF0aFN0cmluZ0xpdGVyYWwudGV4dDtcbiAgICB9KVswXTtcblxuICByZXR1cm4gYm9vdHN0cmFwTW9kdWxlUmVsYXRpdmVQYXRoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXBwTW9kdWxlUGF0aChob3N0OiBUcmVlLCBtYWluUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbW9kdWxlUmVsYXRpdmVQYXRoID0gZmluZEJvb3RzdHJhcE1vZHVsZVBhdGgoaG9zdCwgbWFpblBhdGgpO1xuICBjb25zdCBtYWluRGlyID0gZGlybmFtZShtYWluUGF0aCk7XG4gIGNvbnN0IG1vZHVsZVBhdGggPSBub3JtYWxpemUoYC8ke21haW5EaXJ9LyR7bW9kdWxlUmVsYXRpdmVQYXRofS50c2ApO1xuXG4gIHJldHVybiBtb2R1bGVQYXRoO1xufVxuIiwiXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG4vLyBpbXBvcnQgeyByZWxhdGl2ZSwgUGF0aCB9IGZyb20gXCIuLi8uLi8uLi9hbmd1bGFyX2RldmtpdC9jb3JlL3NyYy92aXJ0dWFsLWZzXCI7XG5pbXBvcnQgeyBQYXRoLCBiYXNlbmFtZSwgZGlybmFtZSwgbm9ybWFsaXplIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2NvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIExvY2F0aW9uIHtcbiAgbmFtZTogc3RyaW5nO1xuICBwYXRoOiBQYXRoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VOYW1lKHBhdGg6IHN0cmluZywgbmFtZTogc3RyaW5nKTogTG9jYXRpb24ge1xuICBjb25zdCBuYW1lV2l0aG91dFBhdGggPSBiYXNlbmFtZShuYW1lIGFzIFBhdGgpO1xuICBjb25zdCBuYW1lUGF0aCA9IGRpcm5hbWUoKHBhdGggKyAnLycgKyBuYW1lKSBhcyBQYXRoKTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6IG5hbWVXaXRob3V0UGF0aCxcbiAgICBwYXRoOiBub3JtYWxpemUoJy8nICsgbmFtZVBhdGgpLFxuICB9O1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgdGFncyB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IFNjaGVtYXRpY3NFeGNlcHRpb24gfSBmcm9tICdAYW5ndWxhci1kZXZraXQvc2NoZW1hdGljcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZU5hbWUobmFtZTogc3RyaW5nKTogdm9pZCB7XG4gIGlmIChuYW1lICYmIC9eXFxkLy50ZXN0KG5hbWUpKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24odGFncy5vbmVMaW5lYG5hbWUgKCR7bmFtZX0pXG4gICAgICAgIGNhbiBub3Qgc3RhcnQgd2l0aCBhIGRpZ2l0LmApO1xuICB9XG59XG5cbi8vIE11c3Qgc3RhcnQgd2l0aCBhIGxldHRlciwgYW5kIG11c3QgY29udGFpbiBvbmx5IGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIG9yIGRhc2hlcy5cbi8vIFdoZW4gYWRkaW5nIGEgZGFzaCB0aGUgc2VnbWVudCBhZnRlciB0aGUgZGFzaCBtdXN0IGFsc28gc3RhcnQgd2l0aCBhIGxldHRlci5cbmV4cG9ydCBjb25zdCBodG1sU2VsZWN0b3JSZSA9IC9eW2EtekEtWl1bLjAtOWEtekEtWl0qKDo/LVthLXpBLVpdWy4wLTlhLXpBLVpdKikqJC87XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUh0bWxTZWxlY3RvcihzZWxlY3Rvcjogc3RyaW5nKTogdm9pZCB7XG4gIGlmIChzZWxlY3RvciAmJiAhaHRtbFNlbGVjdG9yUmUudGVzdChzZWxlY3RvcikpIHtcbiAgICB0aHJvdyBuZXcgU2NoZW1hdGljc0V4Y2VwdGlvbih0YWdzLm9uZUxpbmVgU2VsZWN0b3IgKCR7c2VsZWN0b3J9KVxuICAgICAgICBpcyBpbnZhbGlkLmApO1xuICB9XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUHJvamVjdE5hbWUocHJvamVjdE5hbWU6IHN0cmluZykge1xuICBjb25zdCBlcnJvckluZGV4ID0gZ2V0UmVnRXhwRmFpbFBvc2l0aW9uKHByb2plY3ROYW1lKTtcbiAgY29uc3QgdW5zdXBwb3J0ZWRQcm9qZWN0TmFtZXMgPSBbJ3Rlc3QnLCAnZW1iZXInLCAnZW1iZXItY2xpJywgJ3ZlbmRvcicsICdhcHAnXTtcbiAgY29uc3QgcGFja2FnZU5hbWVSZWdleCA9IC9eKD86QFthLXpBLVowLTlfLV0rXFwvKT9bYS16QS1aMC05Xy1dKyQvO1xuICBpZiAoZXJyb3JJbmRleCAhPT0gbnVsbCkge1xuICAgIGNvbnN0IGZpcnN0TWVzc2FnZSA9IHRhZ3Mub25lTGluZWBcbiAgICBQcm9qZWN0IG5hbWUgXCIke3Byb2plY3ROYW1lfVwiIGlzIG5vdCB2YWxpZC4gTmV3IHByb2plY3QgbmFtZXMgbXVzdFxuICAgIHN0YXJ0IHdpdGggYSBsZXR0ZXIsIGFuZCBtdXN0IGNvbnRhaW4gb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBvciBkYXNoZXMuXG4gICAgV2hlbiBhZGRpbmcgYSBkYXNoIHRoZSBzZWdtZW50IGFmdGVyIHRoZSBkYXNoIG11c3QgYWxzbyBzdGFydCB3aXRoIGEgbGV0dGVyLlxuICAgIGA7XG4gICAgY29uc3QgbXNnID0gdGFncy5zdHJpcEluZGVudGBcbiAgICAke2ZpcnN0TWVzc2FnZX1cbiAgICAke3Byb2plY3ROYW1lfVxuICAgICR7QXJyYXkoZXJyb3JJbmRleCArIDEpLmpvaW4oJyAnKSArICdeJ31cbiAgICBgO1xuICAgIHRocm93IG5ldyBTY2hlbWF0aWNzRXhjZXB0aW9uKG1zZyk7XG4gIH0gZWxzZSBpZiAodW5zdXBwb3J0ZWRQcm9qZWN0TmFtZXMuaW5kZXhPZihwcm9qZWN0TmFtZSkgIT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oXG4gICAgICBgUHJvamVjdCBuYW1lICR7SlNPTi5zdHJpbmdpZnkocHJvamVjdE5hbWUpfSBpcyBub3QgYSBzdXBwb3J0ZWQgbmFtZS5gKTtcbiAgfSBlbHNlIGlmICghcGFja2FnZU5hbWVSZWdleC50ZXN0KHByb2plY3ROYW1lKSkge1xuICAgIHRocm93IG5ldyBTY2hlbWF0aWNzRXhjZXB0aW9uKGBQcm9qZWN0IG5hbWUgJHtKU09OLnN0cmluZ2lmeShwcm9qZWN0TmFtZSl9IGlzIGludmFsaWQuYCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0UmVnRXhwRmFpbFBvc2l0aW9uKHN0cjogc3RyaW5nKTogbnVtYmVyIHwgbnVsbCB7XG4gIGNvbnN0IGlzU2NvcGUgPSAvXkAuKlxcLy4qLy50ZXN0KHN0cik7XG4gIGlmIChpc1Njb3BlKSB7XG4gICAgLy8gUmVtb3ZlIHN0YXJ0aW5nIEBcbiAgICBzdHIgPSBzdHIucmVwbGFjZSgvXkAvLCAnJyk7XG4gICAgLy8gQ2hhbmdlIC8gdG8gLSBmb3IgdmFsaWRhdGlvblxuICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXC8vZywgJy0nKTtcbiAgfVxuXG4gIGNvbnN0IHBhcnRzID0gc3RyLmluZGV4T2YoJy0nKSA+PSAwID8gc3RyLnNwbGl0KCctJykgOiBbc3RyXTtcbiAgY29uc3QgbWF0Y2hlZDogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdCBwcm9qZWN0TmFtZVJlZ2V4cCA9IC9eW2EtekEtWl1bLjAtOWEtekEtWl0qKC1bLjAtOWEtekEtWl0qKSokLztcblxuICBwYXJ0cy5mb3JFYWNoKHBhcnQgPT4ge1xuICAgIGlmIChwYXJ0Lm1hdGNoKHByb2plY3ROYW1lUmVnZXhwKSkge1xuICAgICAgbWF0Y2hlZC5wdXNoKHBhcnQpO1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgY29tcGFyZSA9IG1hdGNoZWQuam9pbignLScpO1xuXG4gIHJldHVybiAoc3RyICE9PSBjb21wYXJlKSA/IGNvbXBhcmUubGVuZ3RoIDogbnVsbDtcbn1cbiIsIi8qIENvcHlyaWdodCBJQk0gQ29ycC4gMjAxNyAqL1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tICdsb2Rhc2gnO1xuXG4vKlxuICogTWFrZXMgc3VyZSBvdXIgcGF0aCBlbmRzIHdpdGggYSBwcm9wZXIgdHJhaWxpbmcgc2xhc2hcbiAqL1xuZnVuY3Rpb24gX2Vuc3VyZVRyYWlsaW5nU2xhc2goYVVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGFVcmwuZW5kc1dpdGgoJy8nKSA/IGFVcmwgOiBhVXJsICsgJy8nO1xufVxuXG5mdW5jdGlvbiBfaGFzVHJhaWxpbmdTbGFzaChhVXJsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuICEhKGFVcmwgJiYgaXNTdHJpbmcoYVVybCkgJiYgYVVybC5lbmRzV2l0aCgnLycpKTtcbn1cblxuZXhwb3J0IHtcbiAgX2Vuc3VyZVRyYWlsaW5nU2xhc2ggYXMgZW5zdXJlVHJhaWxpbmdTbGFzaCxcbiAgX2hhc1RyYWlsaW5nU2xhc2ggYXMgaGFzVHJhaWxpbmdTbGFzaFxufTtcbiIsImltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcbmltcG9ydCAqIGFzIEFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgdmFsaWRhdGUgYXMgdmFsaWRhdGVFbWFpbCB9IGZyb20gJ2VtYWlsLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBpc1dlYlVyaSB9IGZyb20gJ3ZhbGlkLXVybCc7XG5cbmltcG9ydCB7IGhhc1RyYWlsaW5nU2xhc2ggfSBmcm9tICcuL3VybC51dGlscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnROb3ROdWxsKGFWYWx1ZTogYW55LCBhTmFtZT86IHN0cmluZykge1xuICBBc3NlcnQub2soXG4gICAgYVZhbHVlICE9IG51bGwsXG4gICAgYU5hbWVcbiAgICAgID8gYFZhbHVlIFske2FOYW1lfV0gbXVzdCBub3QgYmUgbnVsbCBvciB1bmRlZmluZWQuYFxuICAgICAgOiAnVmFsdWUgbXVzdCBub3QgYmUgbnVsbCBvciB1bmRlZmluZWQuJ1xuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UGFyYW1ldGVyKGFWYWx1ZTogYW55LCBhUGFyYW1ldGVyTmFtZTogc3RyaW5nKSB7XG4gIEFzc2VydC5vayghIWFWYWx1ZSwgYFBsZWFzZSBzcGVjaWZ5IHRoZSAnLS0ke2FQYXJhbWV0ZXJOYW1lfScgcGFyYW1ldGVyLmApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFVybChhVmFsdWU6IGFueSk6IGFWYWx1ZSBpcyBzdHJpbmcge1xuICByZXR1cm4gaXNTdHJpbmcoYVZhbHVlKSAmJiAhIWlzV2ViVXJpKGFWYWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRJc1VybChhVmFsdWU6IGFueSwgYU5hbWU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBBc3NlcnQub2soXG4gICAgaXNWYWxpZFVybChhVmFsdWUpLFxuICAgIGFOYW1lXG4gICAgICA/IGBWYWx1ZSBbJHthTmFtZX1dIG11c3QgYmUgYSB2YWxpZCBVUkwuYFxuICAgICAgOiAnVmFsdWUgbXVzdCBiZSBhIHZhbGlkIFVSTC4nXG4gICk7XG4gIHJldHVybiBhVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkRW1haWwoYVZhbHVlOiBhbnkpOiBhVmFsdWUgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIGlzU3RyaW5nKGFWYWx1ZSkgJiYgISF2YWxpZGF0ZUVtYWlsKGFWYWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkVXNlck5hbWUoYVZhbHVlOiBhbnkpOiBhVmFsdWUgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIGlzU3RyaW5nKGFWYWx1ZSkgJiYgKCEhdmFsaWRhdGVFbWFpbChhVmFsdWUpIHx8IGFWYWx1ZSA9PT0gJ2FwaWtleScpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0SXNFbWFpbChhVmFsdWU6IGFueSwgYU5hbWU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBBc3NlcnQub2soXG4gICAgaXNWYWxpZEVtYWlsKGFWYWx1ZSksXG4gICAgYU5hbWVcbiAgICAgID8gYFZhbHVlIFske2FOYW1lfV0gbXVzdCBiZSBhIHZhbGlkIGUtbWFpbCBhZGRyZXNzLmBcbiAgICAgIDogJ1ZhbHVlIG11c3QgYmUgYSB2YWxpZCBlLW1haWwgYWRkcmVzcy4nXG4gICk7XG4gIHJldHVybiBhVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRJc1ZhbGlkVXNlck5hbWUoYVZhbHVlOiBhbnksIGFOYW1lPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgQXNzZXJ0Lm9rKFxuICAgIGlzVmFsaWRVc2VyTmFtZShhVmFsdWUpLFxuICAgIGFOYW1lXG4gICAgICA/IGBWYWx1ZSBbJHthTmFtZX1dIG11c3QgYmUgYSB2YWxpZCBlLW1haWwgYWRkcmVzcyBvciB0aGUgdGVybSAnYXBpa2V5Jy5gXG4gICAgICA6IFwiVmFsdWUgbXVzdCBiZSBhIHZhbGlkIGUtbWFpbCBhZGRyZXNzIG9yIHRoZSB0ZXJtICdhcGlrZXknLlwiXG4gICk7XG4gIHJldHVybiBhVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRIYXNUcmFpbGluZ1NsYXNoKGFWYWx1ZTogYW55KTogc3RyaW5nIHtcbiAgQXNzZXJ0Lm9rKFxuICAgIGlzVmFsaWRVcmwoYVZhbHVlKSAmJiBoYXNUcmFpbGluZ1NsYXNoKGFWYWx1ZSksXG4gICAgJ1VSTCBbJHthVmFsdWV9XSBtdXN0IGVuZCB3aXRoIGEgc2xhc2guJ1xuICApO1xuICByZXR1cm4gYVZhbHVlO1xufVxuIiwiLyogQ29weXJpZ2h0IElCTSBDb3JwLiAyMDE4ICovXG5cbi8vIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBkZXRlY3QgdXVpZC52NCBzdHJpbmdzXG5jb25zdCBIRVhfUkVHRVhQX1NUUklORyA9ICdbMC05YS1mQS1GXSc7XG5jb25zdCBIT1NUX1JFR0VYUF9TVFJJTkcgPSAnW15cXFxcLlxcXFw6XSc7XG5jb25zdCBVVUlEX1Y0X1JFR0VYUF9TVFJJTkcgPVxuICAgIGAke0hFWF9SRUdFWFBfU1RSSU5HfXs4fS0ke0hFWF9SRUdFWFBfU1RSSU5HfXs0fS00JHtIRVhfUkVHRVhQX1NUUklOR317M30tWzg5YWJBQl0ke0hFWF9SRUdFWFBfU1RSSU5HfXszfS0ke0hFWF9SRUdFWFBfU1RSSU5HfXsxMn1gO1xuY29uc3QgVEVOQU5UX0JBU0VEX1VSTCA9IGBeKD86XFxcXC9hcGkpP1xcXFwvKCR7VVVJRF9WNF9SRUdFWFBfU1RSSU5HfSkoPzpcXFxcLyk/KD86LiopJGA7XG5leHBvcnQgY29uc3QgVEVOQU5UX0JBU0VEX1VSTF9SRUdFWFAgPSBuZXcgUmVnRXhwKFRFTkFOVF9CQVNFRF9VUkwpO1xuIiwiLyogQ29weXJpZ2h0IElCTSBDb3JwLiAyMDE3ICovXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBkZWZlciwgZnJvbSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgYWpheCwgQWpheFJlcXVlc3QgfSBmcm9tICdyeGpzL2FqYXgnO1xuaW1wb3J0IHsgcGx1Y2ssIG1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCBjcmVhdGVYSFIgPSAoKSA9PiB7XG4gIGNvbnN0IFhNTEh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgneGhyMicpO1xuICByZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG59O1xuXG5jb25zdCBhamF4UmVxdWVzdCA9IChyZXE6IEFqYXhSZXF1ZXN0KSA9PlxuICBhamF4KHsgLi4ucmVxLCByZXNwb25zZVR5cGU6ICd0ZXh0JywgY3JlYXRlWEhSIH0pLnBpcGUoXG4gICAgbWFwKHJlc3AgPT4gcmVzcC5yZXNwb25zZSBhcyBzdHJpbmcpXG4gICk7XG5cbmV4cG9ydCBmdW5jdGlvbiByeEdldChhVXJpOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBzZXR1cCB0aGUgcmVxdWVzdFxuICByZXR1cm4gYWpheFJlcXVlc3Qoe1xuICAgIHVybDogYVVyaVxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ4R2V0SnNvbihhVXJpOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICByZXR1cm4gcnhHZXQoYVVyaSkucGlwZShtYXAoZGF0YSA9PiBKU09OLnBhcnNlKGRhdGEpKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByeEZvcm1Qb3N0KGFVcmk6IHN0cmluZywgYURhdGE6IGFueSk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIHNldHVwIHRoZSByZXF1ZXN0XG4gIHJldHVybiBhamF4UmVxdWVzdCh7XG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgdXJsOiBhVXJpLFxuICAgIGJvZHk6IGFEYXRhXG4gIH0pO1xufVxuIiwiaW1wb3J0IHsgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHJlYWRGaWxlIH0gZnJvbSAnZnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gcnhSZWFkRmlsZShhUGF0aDogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgcmV0dXJuIE9ic2VydmFibGUuY3JlYXRlKChvYnNlcnZlcjogT2JzZXJ2ZXI8c3RyaW5nPikgPT4ge1xuICAgIHJlYWRGaWxlKGFQYXRoLCAndXRmLTgnLCAoZXJyLCBkYXRhKSA9PiB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYnNlcnZlci5uZXh0KGRhdGEpO1xuICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cbiIsImltcG9ydCB7IGV4ZWMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IFJTQV9QS0NTMV9QQURESU5HIH0gZnJvbSAnY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIHByaXZhdGVEZWNyeXB0LFxuICBwdWJsaWNFbmNyeXB0LFxuICBSc2FQcml2YXRlS2V5LFxuICBSc2FQdWJsaWNLZXlcbn0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IGNsb25lRGVlcCwgaXNTdHJpbmcgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgaG9tZWRpciwgcGxhdGZvcm0gfSBmcm9tICdvcyc7XG5pbXBvcnQgeyBqb2luLCBub3JtYWxpemUgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGVudiB9IGZyb20gJ3Byb2Nlc3MnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIG1lcmdlTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgcGFyc2VLZXkgfSBmcm9tICdzc2hwayc7XG5cbmltcG9ydCB7IGFzc2VydEhhc1RyYWlsaW5nU2xhc2gsIGlzVmFsaWRVc2VyTmFtZSB9IGZyb20gJy4vYXNzZXJ0JztcbmltcG9ydCB7IHJ4UmVhZEZpbGUgfSBmcm9tICcuL3J4LmZpbGUnO1xuaW1wb3J0IHsgZW5zdXJlVHJhaWxpbmdTbGFzaCB9IGZyb20gJy4vdXJsLnV0aWxzJztcblxuZXhwb3J0IHsgd2NoR2V0RGVsaXZlcnlVcmxGcm9tQXBpVVJMIH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBDcmVkZW50aWFscyB7XG4gIHVzZXJuYW1lOiBzdHJpbmc7XG4gIHBhc3N3b3JkOiBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIF9pc1ZhbGlkQ3JlZGVudGlhbChhQ3JlZD86IENyZWRlbnRpYWxzKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIShcbiAgICBhQ3JlZCAmJlxuICAgIGlzVmFsaWRVc2VyTmFtZShhQ3JlZC51c2VybmFtZSkgJiZcbiAgICBpc1N0cmluZyhhQ3JlZC5wYXNzd29yZClcbiAgKTtcbn1cblxuZnVuY3Rpb24gX2VtcHR5Q3JlZGVudGlhbHMoKTogQ3JlZGVudGlhbHMge1xuICByZXR1cm4ge1xuICAgIHVzZXJuYW1lOiAnJyxcbiAgICBwYXNzd29yZDogJydcbiAgfTtcbn1cblxuZnVuY3Rpb24gX2NyZWF0ZUNyZWRlbnRpYWxzKGFVc2VyTmFtZTogc3RyaW5nLCBhUGFzc3dvcmQ6IHN0cmluZyk6IENyZWRlbnRpYWxzIHtcbiAgcmV0dXJuIHtcbiAgICB1c2VybmFtZTogYVVzZXJOYW1lLFxuICAgIHBhc3N3b3JkOiBhUGFzc3dvcmRcbiAgfTtcbn1cblxuZnVuY3Rpb24gX2dldENyZWRlbnRpYWxzRnJvbUVudmlyb25tZW50KCk6IENyZWRlbnRpYWxzIHtcbiAgLy8gYWNjZXNzIHRoZSBjcmVkZW50aWFscyBmcm9tIHRoZSBlbnZpcm9ubWVudFxuICBjb25zdCB1c2VybmFtZSA9IGVudlsnaWJtX3djaF9zZGtfY2xpX3VzZXJuYW1lJ10gfHwgJyc7XG4gIGNvbnN0IHBhc3N3b3JkID0gZW52WydpYm1fd2NoX3Nka19jbGlfcGFzc3dvcmQnXSB8fCAnJztcbiAgLy8gY29uc3RydWN0XG4gIHJldHVybiB7IHVzZXJuYW1lLCBwYXNzd29yZCB9O1xufVxuXG4vKipcbiAqIE1lcmdlIGRpZmZlcmVudCBjcmVkZW50aWFscyBsYXllcnNcbiAqXG4gKiBAcGFyYW0gYUJhc2UgICAgICAgICBiYXNlIGxheWVyXG4gKiBAcGFyYW0gYU92ZXJyaWRlICAgICBvdmVycmlkZSBsYXllclxuICpcbiAqIEByZXR1cm4gdGhlIG1lcmdlZCBjcmVkZW50aWFsc1xuICovXG5mdW5jdGlvbiBfbWVyZ2VDcmVkZW50aWFscyhcbiAgYUJhc2U6IENyZWRlbnRpYWxzLFxuICBhT3ZlcnJpZGU/OiBDcmVkZW50aWFsc1xuKTogQ3JlZGVudGlhbHMge1xuICAvLyB0YXJnZXRcbiAgaWYgKCFhT3ZlcnJpZGUpIHtcbiAgICByZXR1cm4gYUJhc2U7XG4gIH1cbiAgLy8gY2xvbmVcbiAgY29uc3QgY3JlZCA9IGNsb25lRGVlcChhQmFzZSk7XG4gIC8vIG92ZXJyaWRlXG4gIGlmICghIWFPdmVycmlkZS51c2VybmFtZSkge1xuICAgIGNyZWQudXNlcm5hbWUgPSBhT3ZlcnJpZGUudXNlcm5hbWU7XG4gIH1cbiAgaWYgKCEhYU92ZXJyaWRlLnBhc3N3b3JkKSB7XG4gICAgY3JlZC5wYXNzd29yZCA9IGFPdmVycmlkZS5wYXNzd29yZDtcbiAgfVxuICAvLyBva1xuICByZXR1cm4gY3JlZDtcbn1cblxuY29uc3QgUEFERElOR19NT0RFID0gUlNBX1BLQ1MxX1BBRERJTkc7XG5cbmZ1bmN0aW9uIF9sb2FkUHJpdmF0ZUtleSgpOiBPYnNlcnZhYmxlPFJzYVByaXZhdGVLZXk+IHtcbiAgLy8gZmlsZW5hbWVcbiAgY29uc3QgbmFtZSA9IGpvaW4oaG9tZWRpcigpLCAnLnNzaCcsICdpZF9yc2EnKTtcbiAgcmV0dXJuIHJ4UmVhZEZpbGUobmFtZSkucGlwZShtYXAoa2V5ID0+ICh7IGtleSwgcGFkZGluZzogUEFERElOR19NT0RFIH0pKSk7XG59XG5cbmZ1bmN0aW9uIF9sb2FkUHVibGljS2V5KCk6IE9ic2VydmFibGU8UnNhUHVibGljS2V5PiB7XG4gIC8vIGZpbGVuYW1lXG4gIGNvbnN0IG5hbWUgPSBqb2luKGhvbWVkaXIoKSwgJy5zc2gnLCAnaWRfcnNhLnB1YicpO1xuICByZXR1cm4gcnhSZWFkRmlsZShuYW1lKS5waXBlKFxuICAgIG1hcChrZXkgPT4gcGFyc2VLZXkoa2V5LCAnYXV0bycpLnRvU3RyaW5nKCdwa2NzMScpKSxcbiAgICBtYXAoa2V5ID0+ICh7IGtleSwgcGFkZGluZzogUEFERElOR19NT0RFIH0pKVxuICApO1xufVxuXG5jb25zdCBFTkNSWVBURURfRU5DT0RJTkcgPSAnYmFzZTY0JztcbmNvbnN0IERFQ1RZUFRFRF9FTkNPRElORyA9ICd1dGY4JztcblxuZnVuY3Rpb24gX2VuY3J5cHRQYXNzd29yZChhUGFzc3dvcmQ6IHN0cmluZywgYUtleTogUnNhUHVibGljS2V5KTogc3RyaW5nIHtcbiAgLy8gZW5jcnlwdFxuICByZXR1cm4gcHVibGljRW5jcnlwdChcbiAgICBhS2V5LFxuICAgIEJ1ZmZlci5mcm9tKGFQYXNzd29yZCwgREVDVFlQVEVEX0VOQ09ESU5HKVxuICApLnRvU3RyaW5nKEVOQ1JZUFRFRF9FTkNPRElORyk7XG59XG5cbmZ1bmN0aW9uIF9kZWNyeXB0UGFzc3dvcmQoYUhhc2g6IHN0cmluZywgYUtleTogUnNhUHJpdmF0ZUtleSk6IHN0cmluZyB7XG4gIHJldHVybiBwcml2YXRlRGVjcnlwdChhS2V5LCBCdWZmZXIuZnJvbShhSGFzaCwgRU5DUllQVEVEX0VOQ09ESU5HKSkudG9TdHJpbmcoXG4gICAgREVDVFlQVEVEX0VOQ09ESU5HXG4gICk7XG59XG5cbmZ1bmN0aW9uIF9sb2FkQ3JlZGVudGlhbHMoYUFwaUJhc2U6IHN0cmluZyk6IE9ic2VydmFibGU8Q3JlZGVudGlhbHM+IHtcbiAgLy8gdmFsaWRhdGUgdGhlIFVSTFxuICBhc3NlcnRIYXNUcmFpbGluZ1NsYXNoKGFBcGlCYXNlKTtcbiAgLy8gY3JlZGVudGlhbCBmaWxlIG5hbWVcbiAgY29uc3QgZmlsZW5hbWUgPSBqb2luKGhvbWVkaXIoKSwgJy5pYm0td2NoLXNkay1jbGknLCAnLmNyZWRlbnRpYWxzJyk7XG4gIC8vIHJlYWQgdGhlIGNyZWRlbnRpYWxcbiAgY29uc3Qga2V5ID0gX2xvYWRQcml2YXRlS2V5KCk7XG4gIC8vIGxvYWQgdGhlIGZpbGVcbiAgcmV0dXJuIHJ4UmVhZEZpbGUoZmlsZW5hbWUpLnBpcGUoXG4gICAgbWFwKGRhdGEgPT4gSlNPTi5wYXJzZShkYXRhKSksXG4gICAgbWFwKGRhdGEgPT4gZGF0YVthQXBpQmFzZV0pLFxuICAgIG1lcmdlTWFwKGNyZWQgPT5cbiAgICAgIGtleS5waXBlKFxuICAgICAgICBtYXAoayA9PiBfZGVjcnlwdFBhc3N3b3JkKGNyZWQucGFzc3dvcmQsIGspKSxcbiAgICAgICAgbWFwKHAgPT4ge1xuICAgICAgICAgIGNyZWQucGFzc3dvcmQgPSBwO1xuICAgICAgICAgIHJldHVybiBjcmVkO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICksXG4gICAgY2F0Y2hFcnJvcigoKSA9PiBvZihfZW1wdHlDcmVkZW50aWFscygpKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gX2dldFdpbmRvd3NDcmVkZW50aWFscyhhQXBpVXJsOiBzdHJpbmcpOiBPYnNlcnZhYmxlPENyZWRlbnRpYWxzPiB7XG4gIC8vIHZhbGlkYXRlIHRoZSBVUkxcbiAgYXNzZXJ0SGFzVHJhaWxpbmdTbGFzaChhQXBpVXJsKTtcbiAgLy8gdGhlIGV4ZWN1dGFibGVcbiAgY29uc3QgcGF0aCA9IG5vcm1hbGl6ZShcbiAgICBqb2luKFxuICAgICAgX19kaXJuYW1lLFxuICAgICAgJy4uJyxcbiAgICAgICcuLicsXG4gICAgICAnLi4nLFxuICAgICAgJ2Fzc2V0cycsXG4gICAgICAnY3JlZG1hbicsXG4gICAgICBwcm9jZXNzLmFyY2gsXG4gICAgICAnV2NoQ3JlZE1hbi5leGUnXG4gICAgKVxuICApO1xuICAvLyBleGVjdXRlXG4gIGNvbnN0IGNtZCA9IGBcXFwiJHtwYXRofVxcXCIgXFxcIiR7YUFwaVVybH1cXFwiYDtcbiAgLy8gY29uc3RydWN0IHRoZSBvYnNlcnZhYmxlXG4gIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZSgob2JzZXJ2ZXI6IE9ic2VydmVyPENyZWRlbnRpYWxzPikgPT4ge1xuICAgIC8vIGV4ZWN1dGUgdGhlIGNvbW1hbmRcbiAgICBleGVjKFxuICAgICAgY21kLFxuICAgICAge1xuICAgICAgICBlbmNvZGluZzogJ3V0ZjgnXG4gICAgICB9LFxuICAgICAgKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIHBhcnNlXG4gICAgICAgICAgICBvYnNlcnZlci5uZXh0KEpTT04ucGFyc2Uoc3Rkb3V0KSk7XG4gICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBfZ2V0U3RvcmVkQ3JlZGVudGlhbHMoYUFwaVVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxDcmVkZW50aWFscz4ge1xuICAvLyB0aGUga2V5XG4gIGNvbnN0IGtleSA9IGVuc3VyZVRyYWlsaW5nU2xhc2goYUFwaVVybCk7XG4gIC8vIG5vcm1hbGl6ZSB0aGUgVVJMXG4gIGlmIChwbGF0Zm9ybSgpID09PSAnd2luMzInKSB7XG4gICAgLy8gbG9hZCB0aGUgY3JlZGVudGlhbHMgbW9kdWxlXG4gICAgcmV0dXJuIF9nZXRXaW5kb3dzQ3JlZGVudGlhbHMoa2V5KS5waXBlKFxuICAgICAgbWVyZ2VNYXAoXG4gICAgICAgIChjcmVkOiBDcmVkZW50aWFscykgPT5cbiAgICAgICAgICBfaXNWYWxpZENyZWRlbnRpYWwoY3JlZCkgPyBvZihjcmVkKSA6IF9sb2FkQ3JlZGVudGlhbHMoa2V5KVxuICAgICAgKSxcbiAgICAgIGNhdGNoRXJyb3IoKCkgPT4gX2xvYWRDcmVkZW50aWFscyhrZXkpKVxuICAgICk7XG4gIH1cbiAgLy8gbGludXggbGlrZSBmYWxsYmFja1xuICByZXR1cm4gX2xvYWRDcmVkZW50aWFscyhrZXkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2NoVG9vbHNHZXRDcmVkZW50aWFscyhcbiAgYUFwaVVybDogc3RyaW5nXG4pOiBPYnNlcnZhYmxlPENyZWRlbnRpYWxzPiB7XG4gIC8vIHJldHVyblxuICByZXR1cm4gX2dldFN0b3JlZENyZWRlbnRpYWxzKGFBcGlVcmwpLnBpcGUoXG4gICAgbWFwKGNyZWQgPT4gX21lcmdlQ3JlZGVudGlhbHMoX2dldENyZWRlbnRpYWxzRnJvbUVudmlyb25tZW50KCksIGNyZWQpKSxcbiAgICBjYXRjaEVycm9yKGVyciA9PiBvZihfZ2V0Q3JlZGVudGlhbHNGcm9tRW52aXJvbm1lbnQoKSkpXG4gICk7XG59XG4iLCJpbXBvcnQgeyBhc3NlcnRPYmplY3QsIGlzTmlsIH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcbmltcG9ydCB7IHJlYWRGaWxlIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiwgcGFyc2UgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGJpbmROb2RlQ2FsbGJhY2ssIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IHNhdGlzZmllcyB9IGZyb20gJ3NlbXZlcic7XG5cbmV4cG9ydCBlbnVtIERFUF9UWVBFIHtcbiAgUEVFUixcbiAgUlVOVElNRSxcbiAgREVWRUxPUE1FTlRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlckZvclR5cGUoYVR5cGU/OiBERVBfVFlQRSk6IHN0cmluZyB7XG4gIHJldHVybiBhVHlwZSA9PT0gREVQX1RZUEUuUEVFUlxuICAgID8gJ3BlZXJEZXBlbmRlbmNpZXMnXG4gICAgOiBhVHlwZSA9PT0gREVQX1RZUEUuREVWRUxPUE1FTlRcbiAgICAgID8gJ2RldkRlcGVuZGVuY2llcydcbiAgICAgIDogJ2RlcGVuZGVuY2llcyc7XG59XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgcGFja2FnZSBKU09OIHRvIHVzZSBhdCBsZWFzdCB0aGUgZ2l2ZW4gdmVyc2lvblxuICpcbiAqIEBwYXJhbSBhTmFtZSAgICAgbmFtZVxuICogQHBhcmFtIGFNaW5WZXJzaW9uICAgbWluIHZlcnNpb25cbiAqIEBwYXJhbSBhUGtnICBwYWNrYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVNaW5WZXJzaW9uKFxuICBhTmFtZTogc3RyaW5nLFxuICBhTWluVmVyc2lvbjogc3RyaW5nLFxuICBhUGtnOiBhbnksXG4gIGFUeXBlPzogREVQX1RZUEVcbik6IGFueSB7XG4gIC8vIGNoZWNrIGlmIHdlIGhhdmUgYSB2ZXJzaW9uIGlkZW50aWZpZXJcbiAgY29uc3QgZm9sZGVyID0gZ2V0Rm9sZGVyRm9yVHlwZShhVHlwZSk7XG4gIC8vIGFjY2Vzc1xuICBjb25zdCBkZXBzID0gYXNzZXJ0T2JqZWN0KGZvbGRlciwgYVBrZykgYXMgYW55O1xuICBjb25zdCBvbGREZXAgPSBkZXBzW2FOYW1lXTtcbiAgaWYgKGlzTmlsKG9sZERlcCkgfHwgIXNhdGlzZmllcyhhTWluVmVyc2lvbiwgb2xkRGVwKSkge1xuICAgIC8vIGp1c3QgdXBkYXRlXG4gICAgZGVwc1thTmFtZV0gPSBgXiR7YU1pblZlcnNpb259YDtcbiAgfVxuICAvLyBva1xuICByZXR1cm4gYVBrZztcbn1cblxuY29uc3QgcnhSZWFkRmlsZSA9IGJpbmROb2RlQ2FsbGJhY2s8c3RyaW5nLCBzdHJpbmcsIHN0cmluZz4ocmVhZEZpbGUpO1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZFBhY2thZ2VKc29uKGFEaXI6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gIC8vIHJlYWRcbiAgcmV0dXJuIHJ4UmVhZEZpbGUoam9pbihhRGlyLCAncGFja2FnZS5qc29uJyksICd1dGYtOCcpLnBpcGUoXG4gICAgbWFwKGRhdGEgPT4gSlNPTi5wYXJzZShkYXRhKSksXG4gICAgY2F0Y2hFcnJvcihlcnIgPT4gZmluZFBhY2thZ2VKc29uKHBhcnNlKGFEaXIpLmRpcikpXG4gICk7XG59XG4iLCJpbXBvcnQgeyBQYXRoLCByZXNvbHZlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2NvcmUnO1xuaW1wb3J0IHsgVHJlZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzJztcbmltcG9ydCB7IGNvZXJjZSB9IGZyb20gJ3NlbXZlcic7XG5pbXBvcnQge1xuICBLRVlfQkFTSUNBVVRIX0xPR0lOX1BBU1NXT1JELFxuICBLRVlfQkFTSUNBVVRIX0xPR0lOX1VTRVJOQU1FLFxuICBSRUxfUEFUSF9CQVNJQ0FVVEhfTE9HSU4sXG4gIFJFTF9QQVRIX0NVUlJFTlRfVVNFUlxufSBmcm9tICdAaWJtLXdjaC1zZGsvYXBpJztcbmltcG9ydCB7IGlzTmlsLCBpc05vdE5pbCwgYXNzZXJ0QXJyYXkgfSBmcm9tICdAaWJtLXdjaC1zZGsvdXRpbHMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGNhdGNoRXJyb3IsXG4gIG1hcCxcbiAgbWFwVG8sXG4gIHBsdWNrLFxuICBzd2l0Y2hNYXAsXG4gIHN3aXRjaE1hcFRvXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IGlzVXJpIH0gZnJvbSAndmFsaWQtdXJsJztcbmltcG9ydCB7IFZFcnJvciB9IGZyb20gJ3ZlcnJvcic7XG5cbmltcG9ydCB7IGZpbmRQYWNrYWdlSnNvbiB9IGZyb20gJy4vLi4vcGFja2FnZSc7XG5pbXBvcnQgeyBpc1ZhbGlkVXNlck5hbWUgfSBmcm9tICcuL2Fzc2VydCc7XG5pbXBvcnQgeyByeEZvcm1Qb3N0LCByeEdldEpzb24gfSBmcm9tICcuL3J4LnJlcXVlc3QnO1xuaW1wb3J0IHsgZW5zdXJlVHJhaWxpbmdTbGFzaCB9IGZyb20gJy4vdXJsLnV0aWxzJztcbmltcG9ydCB7IENyZWRlbnRpYWxzLCB3Y2hUb29sc0dldENyZWRlbnRpYWxzIH0gZnJvbSAnLi93Y2h0b29scyc7XG5cbmZ1bmN0aW9uIF9pc0FwaUtleShhTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBhTmFtZSA9PT0gJ2FwaWtleSc7XG59XG5cbmZ1bmN0aW9uIF9pc1ZhbGlkUGFzc3dvcmQoYVBhc3N3b3JkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGFQYXNzd29yZCAmJiBhUGFzc3dvcmQubGVuZ3RoID4gMDtcbn1cblxuZnVuY3Rpb24gX3Rocm93SW52YWxpZFVybChhQXBpVXJsOiBzdHJpbmcsIGFFcnJvcjogRXJyb3IpOiBPYnNlcnZhYmxlPG5ldmVyPiB7XG4gIHJldHVybiB0aHJvd0Vycm9yKFxuICAgIG5ldyBWRXJyb3IoYUVycm9yLCAnVGhlIEFQSSBVUkwgWyVzXSBpcyBub3QgYSB2YWxpZCBXQ0ggQVBJIFVSTC4nLCBhQXBpVXJsKVxuICApO1xufVxuXG5mdW5jdGlvbiBfZ2V0Q3VycmVudFVzZXIoYUFwaVVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgLy8gdGhlIFVSTFxuICBjb25zdCBjdXJyZW50VXNlclVybCA9IGAke2FBcGlVcmx9JHtSRUxfUEFUSF9DVVJSRU5UX1VTRVJ9YDtcbiAgcmV0dXJuIHJ4R2V0SnNvbihjdXJyZW50VXNlclVybCkucGlwZShcbiAgICBjYXRjaEVycm9yKGVycm9yID0+IF90aHJvd0ludmFsaWRVcmwoYUFwaVVybCwgZXJyb3IpKVxuICApO1xufVxuXG5mdW5jdGlvbiBfdGhyb3dJbnZhbGlkQ3JlZGVudGlhbHMoYUFwaVVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxuZXZlcj4ge1xuICByZXR1cm4gdGhyb3dFcnJvcihcbiAgICBuZXcgVkVycm9yKFxuICAgICAgJ1VuYWJsZSB0byBhY2Nlc3MgY3JlZGVudGlhbHMgZm9yIHRoZSBBUEkgVVJMIFslc10uIFBsZWFzZSBmb2xsb3cgdGhlIGRpcmVjdGlvbnMgb24gaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvaWJtLXdjaC1zZGstY2xpI2NyZWRlbnRpYWwtbWFuYWdlbWVudCB0byByZWdpc3RlciBjcmVkZW50aWFscy4nLFxuICAgICAgYUFwaVVybFxuICAgIClcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ3JlZGVudGlhbHMoXG4gIGFBcGlVcmw6IHN0cmluZyxcbiAgYUNyZWRlbnRpYWxzOiBDcmVkZW50aWFsc1xuKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgLy8gY2hlY2sgdGhlIGNyZWRlbnRpYWxzIG9iamVjdFxuICBpZiAoXG4gICAgIWFDcmVkZW50aWFscyB8fFxuICAgICFpc1ZhbGlkVXNlck5hbWUoYUNyZWRlbnRpYWxzLnVzZXJuYW1lKSB8fFxuICAgICFfaXNWYWxpZFBhc3N3b3JkKGFDcmVkZW50aWFscy5wYXNzd29yZClcbiAgKSB7XG4gICAgcmV0dXJuIF90aHJvd0ludmFsaWRDcmVkZW50aWFscyhhQXBpVXJsKTtcbiAgfVxuICAvLyB0ZXN0IGlmIHdlIGNhbiBsb2dpblxuICBjb25zdCBsb2dpblVybCA9IGAke2FBcGlVcmx9JHtSRUxfUEFUSF9CQVNJQ0FVVEhfTE9HSU59YDtcbiAgY29uc3QgYm9keSA9IHtcbiAgICBbS0VZX0JBU0lDQVVUSF9MT0dJTl9VU0VSTkFNRV06IGFDcmVkZW50aWFscy51c2VybmFtZSxcbiAgICBbS0VZX0JBU0lDQVVUSF9MT0dJTl9QQVNTV09SRF06IGFDcmVkZW50aWFscy5wYXNzd29yZFxuICB9O1xuICAvLyBleGVjdXRlXG4gIHJldHVybiByeEZvcm1Qb3N0KGxvZ2luVXJsLCBib2R5KS5waXBlKFxuICAgIG1hcChkYXRhID0+IEpTT04ucGFyc2UoZGF0YSkpLFxuICAgIGNhdGNoRXJyb3IoZXJyb3IgPT5cbiAgICAgIHRocm93RXJyb3IoXG4gICAgICAgIG5ldyBWRXJyb3IoXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgJ1VuYWJsZSB0byBsb2dpbiB0byBbJXNdIHdpdGggdXNlciBbJXNdLiBQbGVhc2UgY2hlY2sgeW91ciByZWdpc3RlcmVkIHBhc3N3b3JkLicsXG4gICAgICAgICAgbG9naW5VcmwsXG4gICAgICAgICAgYUNyZWRlbnRpYWxzLnVzZXJuYW1lXG4gICAgICAgIClcbiAgICAgIClcbiAgICApLFxuICAgIG1hcFRvKGFBcGlVcmwpXG4gICk7XG59XG5cbmZ1bmN0aW9uIF92YWxpZGF0ZVVzZXIoYUZlZWQ6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG4gIC8vIHRlc3QgdGhlIGZlZWQgcmVzdWx0XG4gIGlmICghYUZlZWQgfHwgIWFGZWVkLmV4dGVybmFsSWQpIHtcbiAgICByZXR1cm4gdGhyb3dFcnJvcihuZXcgVkVycm9yKCdJbnZhbGlkIGN1cnJlbnR1c2VyIHJlc3BvbnNlJykpO1xuICB9XG4gIHJldHVybiBvZihhRmVlZCk7XG59XG5cbi8qKlxuICogVGVzdHMgaWYgIHRoZSBBUEkgVVJMIGlzIHZhbGlkIGFuZCBpZiB3ZSBoYXZlIHN1ZmZpY2llbnQgY3JlZGVudGlhbHMgdG8gYWNjZXNzIHRoZSBBUElcbiAqXG4gKiBAcGFyYW0gYVVybCAgdGhlIEFQSSBVUkxcbiAqIEByZXR1cm4gdGhlIHVybFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVBcGlVcmwoXG4gIGFVcmw6IHN0cmluZyxcbiAgYlZhbGlkYXRlV2l0aENyZWRlbnRpYWxzOiBib29sZWFuXG4pOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBjaGVjayBpZiB0aGUgVVJMIGlzIHZhbHVkXG4gIGlmICghaXNVcmkoYVVybCkpIHtcbiAgICByZXR1cm4gdGhyb3dFcnJvcihcbiAgICAgIG5ldyBWRXJyb3IoXG4gICAgICAgICdQbGVhc2UgZW50ZXIgYSB2YWxpZCBBUEkgVVJMLiBDb3B5IHRoaXMgVVJMIGZyb20gdGhlIFwiSHViIEluZm9ybWF0aW9uXCIgc2VjdGlvbiBvZiB5b3VyIFdDSCB0ZW5hbnQuJ1xuICAgICAgKVxuICAgICk7XG4gIH1cbiAgLy8gY2hlY2sgaWYgdGhlIFVSTCBpcyB2YWxpZFxuICBjb25zdCBub3JtVXJsID0gZW5zdXJlVHJhaWxpbmdTbGFzaChhVXJsKTtcblxuICBpZiAoYlZhbGlkYXRlV2l0aENyZWRlbnRpYWxzKSB7XG4gICAgLy8gbG9hZCB0aGUgY3JlZGVudGlhbHNcbiAgICBjb25zdCBvbkNyZWRlbnRpYWxzID0gd2NoVG9vbHNHZXRDcmVkZW50aWFscyhub3JtVXJsKS5waXBlKFxuICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiBfdGhyb3dJbnZhbGlkQ3JlZGVudGlhbHMobm9ybVVybCkpXG4gICAgKTtcblxuICAgIC8vIGNoZWNrIGlmIHRoZSBVUkwgZXhpc3RzXG4gICAgY29uc3Qgb25WYWxpZFVybDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gX2dldEN1cnJlbnRVc2VyKG5vcm1VcmwpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoX3ZhbGlkYXRlVXNlciksXG4gICAgICBzd2l0Y2hNYXBUbyhvbkNyZWRlbnRpYWxzKSxcbiAgICAgIHN3aXRjaE1hcChjcmVkID0+IHZhbGlkYXRlQ3JlZGVudGlhbHMobm9ybVVybCwgY3JlZCkpXG4gICAgKTtcbiAgICAvLyBva1xuICAgIHJldHVybiBvblZhbGlkVXJsO1xuICB9IGVsc2Uge1xuICAgIC8vIGNoZWNrIGlmIHRoZSBVUkwgZXhpc3RzXG4gICAgY29uc3Qgb25WYWxpZFVybDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gX2dldEN1cnJlbnRVc2VyKG5vcm1VcmwpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoX3ZhbGlkYXRlVXNlciksXG4gICAgICBtYXBUbyhub3JtVXJsKVxuICAgICk7XG4gICAgLy8gb2tcbiAgICByZXR1cm4gb25WYWxpZFVybDtcbiAgfVxufVxuXG5jb25zdCBQQUNLQUdFX0pTT04gPSAnL3BhY2thZ2UuanNvbicgYXMgUGF0aDtcbmNvbnN0IEZBTExCQUNLID0gJy9kYXRhJyBhcyBQYXRoO1xuXG5jb25zdCBPUFRJT05TID0gJy53Y2h0b29sc29wdGlvbnMuanNvbicgYXMgUGF0aDtcblxuY29uc3QgU0RLX0lNUE9SVCA9ICdAaWJtLXdjaC1zZGsvbmcnO1xuY29uc3QgQ0xJX0lNUE9SVCA9ICdAaWJtLXdjaC1zZGsvY2xpJztcblxuZXhwb3J0IGNvbnN0IFdDSFRPT0xTX0RFUEVOREVOQ0lFUyA9ICd3Y2h0b29scy1kZXBlbmRlbmNpZXMnO1xuXG5mdW5jdGlvbiBfZmluZEJ1aWxkVmVyc2lvbigpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBmaW5kIHRoZSBwYWNrYWdlXG4gIHJldHVybiBmaW5kUGFja2FnZUpzb24oX19kaXJuYW1lKS5waXBlKHBsdWNrPGFueSwgc3RyaW5nPigndmVyc2lvbicpKTtcbn1cblxuLyoqXG4gKiBEZWNvZGUgdGhlIHZlcnNpb24gZnJvbSB0aGUgZGVwZW5kZW5jeVxuICpcbiAqIEBwYXJhbSBhVmVyc2lvbiAgdGhlIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIG9ic2VydmFibGUgb2YgdGhlIHZlcnNpb25cbiAqL1xuZnVuY3Rpb24gX2Zyb21EZXBlbmRlbmN5KGFWZXJzaW9uOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICBjb25zdCBwYXJzZWQgPSBjb2VyY2UoYVZlcnNpb24pO1xuICByZXR1cm4gISFwYXJzZWQgPyBvZihwYXJzZWQudmVyc2lvbikgOiBfZmluZEJ1aWxkVmVyc2lvbigpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZFNka1ZlcnNpb24oaG9zdDogVHJlZSk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIHRyeSB0byBsb2NhdGUgdGhlIHBhY2thZ2UganNvblxuICBjb25zdCBidWYgPSBob3N0LnJlYWQoUEFDS0FHRV9KU09OKTtcbiAgaWYgKGlzTmlsKGJ1ZikpIHtcbiAgICByZXR1cm4gX2ZpbmRCdWlsZFZlcnNpb24oKTtcbiAgfVxuICAvLyBzb3VyY2UgcGFja2FnZVxuICBjb25zdCBwa2cgPSBKU09OLnBhcnNlKGJ1Zi50b1N0cmluZygpKTtcbiAgLy8gY2hlY2sgaWYgd2UgaGF2ZSBpbXBvcnRzXG4gIGNvbnN0IGRlcHMgPSBwa2cuZGVwZW5kZW5jaWVzIHx8IHt9O1xuICBjb25zdCBkZXZEZXBzID0gcGtnLmRldkRlcGVuZGVuY2llcyB8fCB7fTtcblxuICBjb25zdCBmcm9tUGtnID0gZGVwc1tTREtfSU1QT1JUXSB8fCBkZXZEZXBzW0NMSV9JTVBPUlRdO1xuXG4gIHJldHVybiBpc05vdE5pbChmcm9tUGtnKSA/IF9mcm9tRGVwZW5kZW5jeShmcm9tUGtnKSA6IF9maW5kQnVpbGRWZXJzaW9uKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kRGF0YURpcihob3N0OiBUcmVlKTogUGF0aCB7XG4gIGNvbnN0IGJ1ZiA9IGhvc3QucmVhZChQQUNLQUdFX0pTT04pO1xuICBpZiAoaXNOaWwoYnVmKSkge1xuICAgIHJldHVybiBGQUxMQkFDSztcbiAgfVxuXG4gIGNvbnN0IHBrZyA9IEpTT04ucGFyc2UoYnVmLnRvU3RyaW5nKCkpO1xuICBjb25zdCBjZmcgPSBwa2cuY29uZmlnIHx8IHt9O1xuXG4gIGNvbnN0IGRhdGEgPSBjZmcuZGF0YSB8fCBGQUxMQkFDSztcblxuICByZXR1cm4gcmVzb2x2ZSgnLycgYXMgUGF0aCwgZGF0YSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kV2NoVG9vbHNPcHRpb25zKGhvc3Q6IFRyZWUpOiBQYXRoIHtcbiAgcmV0dXJuIHJlc29sdmUoZmluZERhdGFEaXIoaG9zdCksIE9QVElPTlMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkVG9XY2hUb29sc0RlcGVuZGVuY2llcyhhRGVwczogc3RyaW5nW10sIGFQa2c6IGFueSkge1xuICAvLyBhZGQgdGhlIGtleVxuICBjb25zdCBkZXBzID0gYXNzZXJ0QXJyYXk8c3RyaW5nPihXQ0hUT09MU19ERVBFTkRFTkNJRVMsIGFQa2cpO1xuICAvLyBmaWx0ZXJcbiAgZGVwcy5wdXNoKC4uLmFEZXBzLmZpbHRlcihkZXAgPT4gZGVwcy5pbmRleE9mKGRlcCkgPCAwKSk7XG59XG4iLCJpbXBvcnQgeyBHZW5lcmF0b3IsIGlzQXJyYXksIGlzTmlsLCBpc1BsYWluT2JqZWN0IH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcblxuY29uc3QgX2tleXMgPSBPYmplY3Qua2V5cztcblxuY29uc3QgS0VZX1dFSUdIVFM6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB7XG4gIG5hbWU6IDEsXG4gIGRlc2NyaXB0aW9uOiAyLFxuICBpZDogMyxcbiAgY2xhc3NpZmljYXRpb246IDRcbn07XG5cbmZ1bmN0aW9uIF9jb21wYXJlTnVtYmVyKGFMZWZ0OiBudW1iZXIsIGFSaWdodDogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIGFMZWZ0IDwgYVJpZ2h0ID8gLTEgOiBhTGVmdCA+IGFSaWdodCA/ICsxIDogMDtcbn1cblxuZnVuY3Rpb24gX2dldEtleShhTmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIEtFWV9XRUlHSFRTW2FOYW1lXSB8fCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbn1cblxuZnVuY3Rpb24gX2NvbXBhcmVOYW1lKGFMZWZ0OiBzdHJpbmcsIGFSaWdodDogc3RyaW5nKTogbnVtYmVyIHtcbiAgLy8gZmlyc3QgYnkga2V5XG4gIGxldCBjID0gX2NvbXBhcmVOdW1iZXIoX2dldEtleShhTGVmdCksIF9nZXRLZXkoYVJpZ2h0KSk7XG4gIGlmIChjID09PSAwKSB7XG4gICAgYyA9IGFMZWZ0LmxvY2FsZUNvbXBhcmUoYVJpZ2h0KTtcbiAgfVxuICAvLyBva1xuICByZXR1cm4gYztcbn1cblxuZnVuY3Rpb24gX2Nhbm9uaWNhbGl6ZShhRGF0YTogYW55KTogYW55IHtcbiAgLy8gaGFuZGxlXG4gIGlmIChpc0FycmF5KGFEYXRhKSkge1xuICAgIGNvbnN0IGNvcHk6IGFueVtdID0gW107XG4gICAgYURhdGEuZm9yRWFjaCh2ID0+IGNvcHkucHVzaChfY2Fub25pY2FsaXplKHYpKSk7XG4gICAgcmV0dXJuIGNvcHk7XG4gIH1cbiAgaWYgKGlzUGxhaW5PYmplY3QoYURhdGEpKSB7XG4gICAgLy8gc29ydCB0aGUga2V5c1xuICAgIGNvbnN0IGNvcHk6IGFueSA9IHt9O1xuICAgIF9rZXlzKGFEYXRhKVxuICAgICAgLnNvcnQoX2NvbXBhcmVOYW1lKVxuICAgICAgLmZvckVhY2goayA9PiAoY29weVtrXSA9IF9jYW5vbmljYWxpemUoYURhdGFba10pKSk7XG4gICAgcmV0dXJuIGNvcHk7XG4gIH1cbiAgLy8gbm90aGluZyB0byBkb1xuICByZXR1cm4gYURhdGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVKc29uKGFEYXRhOiBhbnkpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gYURhdGEgPyBKU09OLnN0cmluZ2lmeShhRGF0YSwgdW5kZWZpbmVkLCAyKSA6IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUZpZWxkKFxuICBhTmFtZTogc3RyaW5nLFxuICBhR2VuZXJhdG9yOiBHZW5lcmF0b3I8c3RyaW5nPixcbiAgYU9iajogYW55XG4pOiBhbnkge1xuICBjb25zdCBvbGRWYWx1ZSA9IGFPYmpbYU5hbWVdO1xuICBpZiAoaXNOaWwob2xkVmFsdWUpKSB7XG4gICAgLy8gdXBkYXRlIHdpdGggdGhlIGdlbmVyYXRlZCB2YWx1ZVxuICAgIGFPYmpbYU5hbWVdID0gYUdlbmVyYXRvcigpO1xuICB9XG4gIHJldHVybiBhT2JqO1xufVxuXG5leHBvcnQgeyBfY2Fub25pY2FsaXplIGFzIGNhbm9uaWNhbGl6ZUpTT04gfTtcbiIsImV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVMaW5lcyhhU291cmNlPzogc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gYVNvdXJjZSA/IGFTb3VyY2Uuam9pbignXFxuJykgOiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxpbmVzKGFTb3VyY2U/OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBhU291cmNlID8gYVNvdXJjZS5zcGxpdCgnXFxuJykgOiBbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydExpbmVzKFxuICBhU291cmNlOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCxcbiAgYUluc2VydDogc3RyaW5nW11cbik6IHN0cmluZ1tdIHtcbiAgaWYgKGFTb3VyY2UpIHtcbiAgICAvLyBidWlsZCB0aGUgc2V0XG4gICAgY29uc3QgZXhpc3RpbmcgPSBuZXcgU2V0PHN0cmluZz4oYVNvdXJjZSk7XG5cbiAgICByZXR1cm4gWy4uLmFTb3VyY2UsIC4uLmFJbnNlcnQuZmlsdGVyKGxpbmUgPT4gIWV4aXN0aW5nLmhhcyhsaW5lKSldO1xuICB9IGVsc2Uge1xuICAgIC8vIGp1c3QgaW5zZXJ0IGludG8gdGhlIGVtcHR5IGZpbGVcbiAgICByZXR1cm4gWy4uLmFJbnNlcnRdO1xuICB9XG59XG4iLCJpbXBvcnQgeyBUcmVlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L3NjaGVtYXRpY3MnO1xuaW1wb3J0IHsgaXNOb3ROaWwgfSBmcm9tICdAaWJtLXdjaC1zZGsvdXRpbHMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgVW5hcnlGdW5jdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlyc3QsIG1hcCwgbWFwVG8gfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGNhbm9uaWNhbGl6ZUpTT04sIHNlcmlhbGl6ZUpzb24gfSBmcm9tICcuL2pzb24nO1xuaW1wb3J0IHsgcGFyc2VMaW5lcywgc2VyaWFsaXplTGluZXMgfSBmcm9tICcuLy4uL3RleHQvbGluZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybVdpdGhQYXRoPFQ+IHtcbiAgKGFTb3VyY2U6IFQgfCB1bmRlZmluZWQsIGFQYXRoOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybVdpdGhvdXRQYXRoPFQ+IHtcbiAgKGFTb3VyY2U6IFQgfCB1bmRlZmluZWQpOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xufVxuXG5leHBvcnQgdHlwZSBUcmFuc2Zvcm1DYWxsYmFjazxUPiA9XG4gIHwgVHJhbnNmb3JtV2l0aFBhdGg8VD5cbiAgfCBUcmFuc2Zvcm1XaXRob3V0UGF0aDxUPjtcblxuLyoqXG4gKiBSZWFkcyBhIHRleHQgZmlsZSBmcm9tIHRoZSB0cmVlIGFuZCB0aGVuIHRyYW5zZm9ybXMgaXQgdXNpbmcgdGhlIGdpdmVuIGZ1bmN0aW9uLiBJZiB0aGUgcmVzdWx0XG4gKiBpcyBudWxsIG9yIHVuZGVmaW5lZCwgdGhlIGZpbGUgd2lsbCBiZSBkZWxldGVkLCBlbHNlIHJlcGxhY2VkIG9yIGNyZWF0ZWQuXG4gKlxuICogQHBhcmFtIGFOYW1lICAgbmFtZSBvZiB0aGUgZmlsZVxuICogQHBhcmFtIGFPcCAgICAgdGhlIG9wZXJhdG9yXG4gKiBAcGFyYW0gYVRyZWUgICB0aGUgdHJlZSB0byB3b3JrIGluXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByeFRyYW5zZm9ybVRleHRGaWxlKFxuICBhTmFtZTogc3RyaW5nLFxuICBhT3A6IFRyYW5zZm9ybUNhbGxiYWNrPHN0cmluZz4sXG4gIGFUcmVlOiBUcmVlXG4pOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBsb2FkIHRoZSBmaWxlIGlmIGl0IGV4aXN0c1xuICBjb25zdCBidWZmZXIgPSBhVHJlZS5yZWFkKGFOYW1lKTtcbiAgY29uc3QgdmFsdWUgPSBpc05vdE5pbChidWZmZXIpID8gYnVmZmVyLnRvU3RyaW5nKCkgOiBudWxsO1xuICBjb25zdCBvcDogVHJhbnNmb3JtV2l0aFBhdGg8c3RyaW5nPiA9IGFPcCBhcyBhbnk7XG4gIC8vIHJlcGxhY2VcbiAgcmV0dXJuIG9wKHZhbHVlLCBhTmFtZSkucGlwZShcbiAgICBmaXJzdCgpLFxuICAgIG1hcChcbiAgICAgIHJlc3VsdCA9PlxuICAgICAgICBpc05vdE5pbChyZXN1bHQpXG4gICAgICAgICAgPyBpc05vdE5pbChidWZmZXIpXG4gICAgICAgICAgICA/IGFUcmVlLm92ZXJ3cml0ZShhTmFtZSwgcmVzdWx0KVxuICAgICAgICAgICAgOiBhVHJlZS5jcmVhdGUoYU5hbWUsIHJlc3VsdClcbiAgICAgICAgICA6IGlzTm90TmlsKGJ1ZmZlcilcbiAgICAgICAgICAgID8gYVRyZWUuZGVsZXRlKGFOYW1lKVxuICAgICAgICAgICAgOiB1bmRlZmluZWRcbiAgICApLFxuICAgIG1hcFRvKGFOYW1lKVxuICApO1xufVxuXG4vKipcbiAqIFJlYWRzIGEgSlNPTiBmaWxlIGZyb20gdGhlIHRyZWUgYW5kIHRoZW4gdHJhbnNmb3JtcyBpdCB1c2luZyB0aGUgZ2l2ZW4gZnVuY3Rpb24uIElmIHRoZSByZXN1bHRcbiAqIGlzIG51bGwgb3IgdW5kZWZpbmVkLCB0aGUgZmlsZSB3aWxsIGJlIGRlbGV0ZWQsIGVsc2UgcmVwbGFjZWQgb3IgY3JlYXRlZC5cbiAqXG4gKiBAcGFyYW0gYU5hbWUgICBuYW1lIG9mIHRoZSBmaWxlXG4gKiBAcGFyYW0gYU9wICAgICB0aGUgb3BlcmF0b3JcbiAqIEBwYXJhbSBhVHJlZSAgIHRoZSB0cmVlIHRvIHdvcmsgaW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ4VHJhbnNmb3JtSnNvbkZpbGUoXG4gIGFOYW1lOiBzdHJpbmcsXG4gIGFPcDogVHJhbnNmb3JtQ2FsbGJhY2s8YW55PixcbiAgYVRyZWU6IFRyZWVcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIGNhc3RcbiAgY29uc3Qgb3A6IFRyYW5zZm9ybVdpdGhQYXRoPGFueT4gPSBhT3AgYXMgYW55O1xuICAvLyBkaXNwYXRjaFxuICByZXR1cm4gcnhUcmFuc2Zvcm1UZXh0RmlsZShcbiAgICBhTmFtZSxcbiAgICAodGV4dENvbnRlbnQsIHBhdGgpID0+XG4gICAgICBvcCh0ZXh0Q29udGVudCA/IEpTT04ucGFyc2UodGV4dENvbnRlbnQpIDogdW5kZWZpbmVkLCBwYXRoKS5waXBlKFxuICAgICAgICBtYXAoY2Fub25pY2FsaXplSlNPTiksXG4gICAgICAgIG1hcChzZXJpYWxpemVKc29uKVxuICAgICAgKSxcbiAgICBhVHJlZVxuICApO1xufVxuXG4vKipcbiAqIFJlYWRzIGEgbGluZSBiYXNlZCBmaWxlIGZyb20gdGhlIHRyZWUgYW5kIHRoZW4gdHJhbnNmb3JtcyBpdCB1c2luZyB0aGUgZ2l2ZW4gZnVuY3Rpb24uIElmIHRoZSByZXN1bHRcbiAqIGlzIG51bGwgb3IgdW5kZWZpbmVkLCB0aGUgZmlsZSB3aWxsIGJlIGRlbGV0ZWQsIGVsc2UgcmVwbGFjZWQgb3IgY3JlYXRlZC5cbiAqXG4gKiBAcGFyYW0gYU5hbWUgICBuYW1lIG9mIHRoZSBmaWxlXG4gKiBAcGFyYW0gYU9wICAgICB0aGUgb3BlcmF0b3JcbiAqIEBwYXJhbSBhVHJlZSAgIHRoZSB0cmVlIHRvIHdvcmsgaW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ4VHJhbnNmb3JtTGluZXNGaWxlKFxuICBhTmFtZTogc3RyaW5nLFxuICBhT3A6IFRyYW5zZm9ybUNhbGxiYWNrPHN0cmluZ1tdPixcbiAgYVRyZWU6IFRyZWVcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIGNhc3RcbiAgY29uc3Qgb3A6IFRyYW5zZm9ybVdpdGhQYXRoPHN0cmluZ1tdPiA9IGFPcCBhcyBhbnk7XG4gIC8vIGRpc3BhdGNoXG4gIHJldHVybiByeFRyYW5zZm9ybVRleHRGaWxlKFxuICAgIGFOYW1lLFxuICAgICh0ZXh0Q29udGVudCwgcGF0aCkgPT5cbiAgICAgIG9wKHRleHRDb250ZW50ID8gcGFyc2VMaW5lcyh0ZXh0Q29udGVudCkgOiB1bmRlZmluZWQsIHBhdGgpLnBpcGUoXG4gICAgICAgIG1hcChzZXJpYWxpemVMaW5lcylcbiAgICAgICksXG4gICAgYVRyZWVcbiAgKTtcbn1cbiIsIi8qIENvcHlyaWdodCBJQk0gQ29ycC4gMjAxOCAqL1xuaW1wb3J0IHsgVHJlZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzJztcbmltcG9ydCB7IGpvaW4sIG5vcm1hbGl6ZSB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgZ2V0IH0gZnJvbSAncmVxdWVzdCc7XG5pbXBvcnQgeyBkZWZlciwgZnJvbUV2ZW50LCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmaXJzdCxcbiAgbWFwLFxuICBtYXBUbyxcbiAgbWVyZ2VNYXAsXG4gIHRha2VVbnRpbCxcbiAgdGFwXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFdyaXRhYmxlIH0gZnJvbSAnc3RyZWFtJztcbmltcG9ydCB7IEVudHJ5LCBQYXJzZSB9IGZyb20gJ3VuemlwJztcblxuZnVuY3Rpb24gX3NraXBQcmVmaXgoYU5hbWU6IHN0cmluZywgYUNvdW50OiBudW1iZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgLy8gY3VycmVudCBuYW1lXG4gIGxldCBpZHggPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFDb3VudDsgKytpKSB7XG4gICAgLy8gZmluZCB0aGUgbmV4dCBzZXBhcmF0b3JcbiAgICBjb25zdCBuZXh0SWR4ID0gYU5hbWUuaW5kZXhPZignLycsIGlkeCk7XG4gICAgaWYgKG5leHRJZHggPj0gaWR4KSB7XG4gICAgICBpZHggPSBuZXh0SWR4ICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIC8vIHNwbGl0XG4gIHJldHVybiBhTmFtZS5zdWJzdHJpbmcoaWR4KTtcbn1cblxuY2xhc3MgU3RyZWFtT25CdWZmZXIgZXh0ZW5kcyBXcml0YWJsZSB7XG4gIGJ1ZmZlcnM6IEJ1ZmZlcltdID0gW107XG5cbiAgX3dyaXRlKGNodW5rOiBhbnksIGVuY29kaW5nOiBzdHJpbmcsIGNhbGxiYWNrOiAoZXJyPzogRXJyb3IpID0+IHZvaWQpIHtcbiAgICB0aGlzLmJ1ZmZlcnMucHVzaChjaHVuayk7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIF9maW5hbChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgICBjYWxsYmFjaygpO1xuICAgIHRoaXMuZW1pdCgnY2xvc2UnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfcnhFeHRyYWN0RW50cnkoXG4gIGFUcmVlOiBUcmVlLFxuICBhRW50cnk6IEVudHJ5LFxuICBhRHN0RGlyOiBzdHJpbmcsXG4gIGFTa2lwOiBudW1iZXJcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIHNraXAgdGhlIHByZWZpeFxuICBjb25zdCBwYXRoID0gX3NraXBQcmVmaXgoYUVudHJ5LnBhdGgsIGFTa2lwKTtcbiAgaWYgKCFwYXRoKSB7XG4gICAgLy8gbm90aGluZ1xuICAgIHJldHVybiBvZignJykucGlwZShcbiAgICAgIHRhcCgoKSA9PiBhRW50cnkuYXV0b2RyYWluKCkpLFxuICAgICAgZmlsdGVyKCgpID0+IGZhbHNlKVxuICAgICk7XG4gIH1cbiAgLy8gY3JlYXRlIGZpbGVuYW1lXG4gIGNvbnN0IGZpbGVOYW1lID0gbm9ybWFsaXplKGpvaW4oYURzdERpciwgcGF0aCkpO1xuICAvLyBoYW5kbGUgZGlyZWN0b3JpZXNcbiAgaWYgKGFFbnRyeS50eXBlID09PSAnRGlyZWN0b3J5Jykge1xuICAgIC8vIGNyZWF0ZSB0aGUgZGlyZWN0b3J5XG4gICAgcmV0dXJuIG9mKCcnKS5waXBlKFxuICAgICAgdGFwKCgpID0+IGFFbnRyeS5hdXRvZHJhaW4oKSksXG4gICAgICBmaWx0ZXIoKCkgPT4gZmFsc2UpXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBjb25zdHJ1Y3QgdGhlIHN0cmVhbVxuICAgIGNvbnN0IHN0cmVhbSA9IGFFbnRyeS5waXBlKG5ldyBTdHJlYW1PbkJ1ZmZlcigpKTtcbiAgICAvLyBhdHRhY2hcbiAgICByZXR1cm4gZnJvbUV2ZW50KHN0cmVhbSwgJ2Nsb3NlJykucGlwZShcbiAgICAgIC8vIGp1c3QgdGFrZSBvbmVcbiAgICAgIGZpcnN0KCksXG4gICAgICAvLyBjb3B5IGludG8gdGhlIHRyZWVcbiAgICAgIG1hcCgoKSA9PiBhVHJlZS5jcmVhdGUoZmlsZU5hbWUsIEJ1ZmZlci5jb25jYXQoc3RyZWFtLmJ1ZmZlcnMpKSksXG4gICAgICAvLyBtYXAgdG8gdGhlIHRhcmdldCBuYW1lXG4gICAgICBtYXBUbyhmaWxlTmFtZSlcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByeFVuemlwRnJvbVVybChcbiAgYVRyZWU6IFRyZWUsXG4gIGFTcmNVcmw6IHN0cmluZyxcbiAgYURzdERpcjogc3RyaW5nLFxuICBhU2tpcDogbnVtYmVyID0gMFxuKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgLy8gZGVmZXJcbiAgcmV0dXJuIGRlZmVyKCgpID0+IHtcbiAgICAvLyBjb25zdHJ1Y3QgdGhlIHN0cmVhbVxuICAgIGNvbnN0IHN0cmVhbSA9IGdldChhU3JjVXJsKS5waXBlKFBhcnNlKCkpO1xuICAgIC8vIGhhbmRsZVxuICAgIGNvbnN0IG9uRW50cnkgPSBmcm9tRXZlbnQ8RW50cnk+KHN0cmVhbSwgJ2VudHJ5Jyk7XG4gICAgY29uc3Qgb25DbG9zZSA9IGZyb21FdmVudChzdHJlYW0sICdjbG9zZScpO1xuICAgIC8vIHJldHVybiB0aGUgZnVsbCBzdHJlYW1cbiAgICByZXR1cm4gb25FbnRyeS5waXBlKFxuICAgICAgdGFrZVVudGlsKG9uQ2xvc2UpLFxuICAgICAgbWVyZ2VNYXAoZW50cnkgPT4gX3J4RXh0cmFjdEVudHJ5KGFUcmVlLCBlbnRyeSwgYURzdERpciwgYVNraXApKVxuICAgICk7XG4gIH0pO1xufVxuIiwiaW1wb3J0IHsgVHJlZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzL3NyYy90cmVlL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBpc05vdE5pbCB9IGZyb20gJ0BpYm0td2NoLXNkay91dGlscyc7XG5pbXBvcnQgeyBsb2FkIH0gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyByeFRyYW5zZm9ybVRleHRGaWxlLCBUcmFuc2Zvcm1DYWxsYmFjaywgVHJhbnNmb3JtV2l0aFBhdGggfSBmcm9tICcuL3J4LnRyZWUnO1xuXG5mdW5jdGlvbiBfcGFyc2VIdG1sKGFTdHJpbmc/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPENoZWVyaW9TdGF0aWM+IHtcbiAgcmV0dXJuIG9mKGxvYWQoaXNOb3ROaWwoYVN0cmluZykgPyBhU3RyaW5nISA6ICcnKSk7XG59XG5cbmZ1bmN0aW9uIF9zZXJpYWxpemVIdG1sKGFIdG1sOiBDaGVlcmlvU3RhdGljKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG9mKGFIdG1sIS5odG1sKCkpO1xufVxuXG4vKipcbiAqIFJlYWRzIGFuIEhNVEwgZnJvbSB0aGUgdHJlZSBhbmQgdGhlbiB0cmFuc2Zvcm1zIGl0IHVzaW5nIHRoZSBnaXZlbiBmdW5jdGlvbi4gSWYgdGhlIHJlc3VsdFxuICogaXMgbnVsbCBvciB1bmRlZmluZWQsIHRoZSBmaWxlIHdpbGwgYmUgZGVsZXRlZCwgZWxzZSByZXBsYWNlZCBvciBjcmVhdGVkLlxuICpcbiAqIEBwYXJhbSBhTmFtZSAgIG5hbWUgb2YgdGhlIGZpbGVcbiAqIEBwYXJhbSBhT3AgICAgIHRoZSBvcGVyYXRvclxuICogQHBhcmFtIGFUcmVlICAgdGhlIHRyZWUgdG8gd29yayBpblxuICovXG5leHBvcnQgZnVuY3Rpb24gcnhUcmFuc2Zvcm1IdG1sRmlsZShcbiAgYU5hbWU6IHN0cmluZyxcbiAgYU9wOiBUcmFuc2Zvcm1DYWxsYmFjazxDaGVlcmlvU3RhdGljPixcbiAgYVRyZWU6IFRyZWVcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIGNhc3RcbiAgY29uc3Qgb3A6IFRyYW5zZm9ybVdpdGhQYXRoPENoZWVyaW9TdGF0aWM+ID0gYU9wIGFzIGFueTtcbiAgLy8gZGlzcGF0Y2hcbiAgcmV0dXJuIHJ4VHJhbnNmb3JtVGV4dEZpbGUoXG4gICAgYU5hbWUsXG4gICAgKHRleHRDb250ZW50LCBwYXRoKSA9PlxuICAgICAgX3BhcnNlSHRtbCh0ZXh0Q29udGVudCkucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKGh0bWwgPT4gb3AoaHRtbCwgcGF0aCkpLFxuICAgICAgICBzd2l0Y2hNYXAoX3NlcmlhbGl6ZUh0bWwpXG4gICAgICApLFxuICAgIGFUcmVlXG4gICk7XG59XG4iLCJpbXBvcnQgeyBTY2hlbWF0aWNzRXhjZXB0aW9uLCBUcmVlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L3NjaGVtYXRpY3MnO1xuaW1wb3J0IHsgY3JlYXRlU291cmNlRmlsZSwgU2NyaXB0VGFyZ2V0LCBTb3VyY2VGaWxlIH0gZnJvbSAndHlwZXNjcmlwdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTb3VyY2VGaWxlKGhvc3Q6IFRyZWUsIHBhdGg6IHN0cmluZyk6IFNvdXJjZUZpbGUge1xuICBjb25zdCBidWZmZXIgPSBob3N0LnJlYWQocGF0aCk7XG4gIGlmICghYnVmZmVyKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oYENvdWxkIG5vdCBmaW5kICR7cGF0aH0uYCk7XG4gIH1cbiAgY29uc3QgY29udGVudCA9IGJ1ZmZlci50b1N0cmluZygpO1xuICBjb25zdCBzb3VyY2UgPSBjcmVhdGVTb3VyY2VGaWxlKHBhdGgsIGNvbnRlbnQsIFNjcmlwdFRhcmdldC5MYXRlc3QsIHRydWUpO1xuXG4gIHJldHVybiBzb3VyY2U7XG59XG4iLCJpbXBvcnQgeyBUcmVlLCBVcGRhdGVSZWNvcmRlciB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzJztcbmltcG9ydCB7IFNvdXJjZUZpbGUgfSBmcm9tICd0eXBlc2NyaXB0JztcblxuaW1wb3J0IHtcbiAgYWRkSW1wb3J0VG9Nb2R1bGUsXG4gIENoYW5nZSxcbiAgSW5zZXJ0Q2hhbmdlLFxuICBSZW1vdmVDaGFuZ2UsXG4gIFJlcGxhY2VDaGFuZ2Vcbn0gZnJvbSAnLi8uLi91dGlsaXR5JztcbmltcG9ydCB7IGdldFNvdXJjZUZpbGUgfSBmcm9tICcuL3NvdXJjZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRDaGFuZ2VzKGFDaGFuZ2VzOiBDaGFuZ2VbXSwgYVJlY29yZGVyOiBVcGRhdGVSZWNvcmRlcikge1xuICBhQ2hhbmdlcy5mb3JFYWNoKChjaGFuZ2U6IENoYW5nZSkgPT4ge1xuICAgIC8vIGRlbGV0ZVxuICAgIGlmIChjaGFuZ2UgaW5zdGFuY2VvZiBJbnNlcnRDaGFuZ2UpIHtcbiAgICAgIGFSZWNvcmRlci5pbnNlcnRMZWZ0KGNoYW5nZS5wb3MsIGNoYW5nZS50b0FkZCk7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UgaW5zdGFuY2VvZiBSZW1vdmVDaGFuZ2UpIHtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZSBpbnN0YW5jZW9mIFJlcGxhY2VDaGFuZ2UpIHtcbiAgICAgIC8vIHJlbW92ZSBvbGQgY2h1bmtcbiAgICAgIGNvbnN0IGFueUNoYW5nZSA9IGNoYW5nZSBhcyBhbnk7XG4gICAgICBhUmVjb3JkZXIucmVtb3ZlKGFueUNoYW5nZS5wb3MsIGFueUNoYW5nZS5vbGRUZXh0Lmxlbmd0aCk7XG4gICAgICBhUmVjb3JkZXIuaW5zZXJ0TGVmdChhbnlDaGFuZ2UucG9zLCBhbnlDaGFuZ2UubmV3VGV4dCk7XG4gICAgfVxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoYW5nZVNvdXJjZUZpbGUoXG4gIGFGaWxlOiBzdHJpbmcsXG4gIGFPcDogKGFGaWxlOiBzdHJpbmcsIGFDb250ZW50OiBTb3VyY2VGaWxlKSA9PiBDaGFuZ2VbXSxcbiAgYUhvc3Q6IFRyZWVcbikge1xuICAvLyBtYWtlIHN1cmUgYXQgbGVhc3QgYW4gZW1wdHkgZmlsZSBleGlzdHNcbiAgaWYgKCFhSG9zdC5leGlzdHMoYUZpbGUpKSB7XG4gICAgYUhvc3QuY3JlYXRlKGFGaWxlLCAnJyk7XG4gIH1cblxuICAvLyB1cGRhdGVcbiAgY29uc3QgcmVjb3JkZXIgPSBhSG9zdC5iZWdpblVwZGF0ZShhRmlsZSk7XG4gIGluc2VydENoYW5nZXMoYU9wKGFGaWxlLCBnZXRTb3VyY2VGaWxlKGFIb3N0LCBhRmlsZSkpLCByZWNvcmRlcik7XG5cbiAgYUhvc3QuY29tbWl0VXBkYXRlKHJlY29yZGVyKTtcbn1cblxuLyoqXG4gKiBDaGFuZ2VzIHRoZSBpZGVudGlmaWVkIG1vZHVsZSBieSBhZGRpbmcgYSBjb3VwbGUgb2YgaW1wb3J0c1xuICpcbiAqIEBwYXJhbSBhRmlsZSB0aGUgZmlsZW5hbWVcbiAqIEBwYXJhbSBhTW9kdWxlcyB0aGUgbW9kdWxlcyB0byBiZSBhZGRlZFxuICogQHBhcmFtIGFIb3N0IHRoZSB0cmVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRJbXBvcnRzVG9Nb2R1bGUoXG4gIGFGaWxlOiBzdHJpbmcsXG4gIGFNb2R1bGVzOiB7IFtpZGVudGlmaWVyOiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgYUhvc3Q6IFRyZWVcbikge1xuICAvLyBpdGVyYXRlXG4gIE9iamVjdC5rZXlzKGFNb2R1bGVzKS5mb3JFYWNoKG5hbWUgPT5cbiAgICBjaGFuZ2VTb3VyY2VGaWxlKFxuICAgICAgYUZpbGUsXG4gICAgICAoZmlsZSwgY29udGVudCkgPT4gYWRkSW1wb3J0VG9Nb2R1bGUoY29udGVudCwgZmlsZSwgbmFtZSwgYU1vZHVsZXNbbmFtZV0pLFxuICAgICAgYUhvc3RcbiAgICApXG4gICk7XG59XG4iLCJpbXBvcnQgeyBQcmVkaWNhdGUgfSBmcm9tICdAaWJtLXdjaC1zZGsvdXRpbHMnO1xuaW1wb3J0IHsgTmFtZWREZWNsYXJhdGlvbiwgTm9kZSwgU3ludGF4S2luZCB9IGZyb20gJ3R5cGVzY3JpcHQnO1xuXG5leHBvcnQgZnVuY3Rpb24gYnlUeXBlKGFUeXBlOiBTeW50YXhLaW5kKTogUHJlZGljYXRlPE5vZGU+IHtcbiAgcmV0dXJuIG5vZGUgPT4gbm9kZSAmJiBub2RlLmtpbmQgPT09IGFUeXBlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnlUZXh0KGFUZXh0OiBzdHJpbmcpOiBQcmVkaWNhdGU8Tm9kZT4ge1xuICByZXR1cm4gbm9kZSA9PiBub2RlICYmIG5vZGUuZ2V0VGV4dCgpID09PSBhVGV4dDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ5TmFtZShhVGV4dDogc3RyaW5nKTogUHJlZGljYXRlPE5hbWVkRGVjbGFyYXRpb24+IHtcbiAgcmV0dXJuIG5vZGUgPT4gISEobm9kZSAmJiBub2RlLm5hbWUgJiYgbm9kZS5uYW1lLmdldFRleHQoKSA9PT0gYVRleHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnlUeXBlQW5kTmFtZShcbiAgYVR5cGU6IFN5bnRheEtpbmQsXG4gIGFOYW1lOiBzdHJpbmdcbik6IFByZWRpY2F0ZTxOb2RlPiB7XG4gIHJldHVybiBub2RlID0+IG5vZGUgJiYgbm9kZS5raW5kID09PSBhVHlwZSAmJiBub2RlLmdldFRleHQoKSA9PT0gYU5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBieUlkZW50aWZpZXIoYU5hbWU6IHN0cmluZyk6IFByZWRpY2F0ZTxOb2RlPiB7XG4gIHJldHVybiBieVR5cGVBbmROYW1lKFN5bnRheEtpbmQuSWRlbnRpZmllciwgYU5hbWUpO1xufVxuIl0sIm5hbWVzIjpbInRzLlN5bnRheEtpbmQiLCJ0c2xpYl8xLl9fdmFsdWVzIiwidHMuZm9yRWFjaENoaWxkIiwiZmlyc3QiLCJ0c2xpYl8xLl9fc3ByZWFkIiwidHMuaXNDbGFzc0RlY2xhcmF0aW9uIiwidHMuY3JlYXRlU291cmNlRmlsZSIsInRzLlNjcmlwdFRhcmdldCIsImRpcm5hbWUiLCJBc3NlcnQub2siLCJpc1N0cmluZyIsInZhbGlkYXRlRW1haWwiLCJoYXNUcmFpbGluZ1NsYXNoIiwiam9pbiIsIm5vcm1hbGl6ZSIsImVuc3VyZVRyYWlsaW5nU2xhc2giLCJyeFJlYWRGaWxlIiwiY2Fub25pY2FsaXplSlNPTiIsInRzbGliXzEuX19leHRlbmRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPQTs7Ozs7O0FBZ0JBLCtCQUFzQyxJQUFVLEVBQUUsT0FBc0I7SUFDdEUsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUU7UUFDOUQsT0FBTyxTQUFT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 |
\ | No newline at end of file |