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 |