UNPKG

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