1 | (function (factory) {
|
2 | if (typeof module === "object" && typeof module.exports === "object") {
|
3 | var v = factory(require, exports);
|
4 | if (v !== undefined) module.exports = v;
|
5 | }
|
6 | else if (typeof define === "function" && define.amd) {
|
7 | define("@angular/compiler-cli/ngcc/src/entry_point_finder/directory_walker_entry_point_finder", ["require", "exports", "tslib", "@angular/compiler-cli/ngcc/src/packages/entry_point", "@angular/compiler-cli/ngcc/src/writing/new_entry_point_file_writer", "@angular/compiler-cli/ngcc/src/entry_point_finder/utils"], factory);
|
8 | }
|
9 | })(function (require, exports) {
|
10 | ;
|
11 | Object.defineProperty(exports, "__esModule", { value: true });
|
12 | var tslib_1 = require("tslib");
|
13 | var entry_point_1 = require("@angular/compiler-cli/ngcc/src/packages/entry_point");
|
14 | var new_entry_point_file_writer_1 = require("@angular/compiler-cli/ngcc/src/writing/new_entry_point_file_writer");
|
15 | var utils_1 = require("@angular/compiler-cli/ngcc/src/entry_point_finder/utils");
|
16 | /**
|
17 | * An EntryPointFinder that searches for all entry-points that can be found given a `basePath` and
|
18 | * `pathMappings`.
|
19 | */
|
20 | var DirectoryWalkerEntryPointFinder = /** @class */ (function () {
|
21 | function DirectoryWalkerEntryPointFinder(fs, config, logger, resolver, entryPointManifest, sourceDirectory, pathMappings) {
|
22 | this.fs = fs;
|
23 | this.config = config;
|
24 | this.logger = logger;
|
25 | this.resolver = resolver;
|
26 | this.entryPointManifest = entryPointManifest;
|
27 | this.sourceDirectory = sourceDirectory;
|
28 | this.pathMappings = pathMappings;
|
29 | this.basePaths = utils_1.getBasePaths(this.logger, this.sourceDirectory, this.pathMappings);
|
30 | }
|
31 | /**
|
32 | * Search the `sourceDirectory`, and sub-directories, using `pathMappings` as necessary, to find
|
33 | * all package entry-points.
|
34 | */
|
35 | DirectoryWalkerEntryPointFinder.prototype.findEntryPoints = function () {
|
36 | var e_1, _a;
|
37 | var unsortedEntryPoints = [];
|
38 | try {
|
39 | for (var _b = tslib_1.__values(this.basePaths), _c = _b.next(); !_c.done; _c = _b.next()) {
|
40 | var basePath = _c.value;
|
41 | var entryPoints = this.entryPointManifest.readEntryPointsUsingManifest(basePath) ||
|
42 | this.walkBasePathForPackages(basePath);
|
43 | unsortedEntryPoints.push.apply(unsortedEntryPoints, tslib_1.__spread(entryPoints));
|
44 | }
|
45 | }
|
46 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
47 | finally {
|
48 | try {
|
49 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
50 | }
|
51 | finally { if (e_1) throw e_1.error; }
|
52 | }
|
53 | return this.resolver.sortEntryPointsByDependency(unsortedEntryPoints);
|
54 | };
|
55 | /**
|
56 | * Search the `basePath` for possible Angular packages and entry-points.
|
57 | *
|
58 | * @param basePath The path at which to start the search
|
59 | * @returns an array of `EntryPoint`s that were found within `basePath`.
|
60 | */
|
61 | DirectoryWalkerEntryPointFinder.prototype.walkBasePathForPackages = function (basePath) {
|
62 | var _this = this;
|
63 | this.logger.debug("No manifest found for " + basePath + " so walking the directories for entry-points.");
|
64 | var entryPoints = utils_1.trackDuration(function () { return _this.walkDirectoryForPackages(basePath); }, function (duration) { return _this.logger.debug("Walking " + basePath + " for entry-points took " + duration + "s."); });
|
65 | this.entryPointManifest.writeEntryPointManifest(basePath, entryPoints);
|
66 | return entryPoints;
|
67 | };
|
68 | /**
|
69 | * Look for Angular packages that need to be compiled, starting at the source directory.
|
70 | * The function will recurse into directories that start with `@...`, e.g. `@angular/...`.
|
71 | *
|
72 | * @param sourceDirectory An absolute path to the root directory where searching begins.
|
73 | * @returns an array of `EntryPoint`s that were found within `sourceDirectory`.
|
74 | */
|
75 | DirectoryWalkerEntryPointFinder.prototype.walkDirectoryForPackages = function (sourceDirectory) {
|
76 | var e_2, _a;
|
77 | // Try to get a primary entry point from this directory
|
78 | var primaryEntryPoint = entry_point_1.getEntryPointInfo(this.fs, this.config, this.logger, sourceDirectory, sourceDirectory);
|
79 | // If there is an entry-point but it is not compatible with ngcc (it has a bad package.json or
|
80 | // invalid typings) then exit. It is unlikely that such an entry point has a dependency on an
|
81 | // Angular library.
|
82 | if (primaryEntryPoint === entry_point_1.INCOMPATIBLE_ENTRY_POINT) {
|
83 | return [];
|
84 | }
|
85 | var entryPoints = [];
|
86 | if (primaryEntryPoint !== entry_point_1.NO_ENTRY_POINT) {
|
87 | entryPoints.push(primaryEntryPoint);
|
88 | this.collectSecondaryEntryPoints(entryPoints, sourceDirectory, sourceDirectory, this.fs.readdir(sourceDirectory));
|
89 | // Also check for any nested node_modules in this package but only if at least one of the
|
90 | // entry-points was compiled by Angular.
|
91 | if (entryPoints.some(function (e) { return e.compiledByAngular; })) {
|
92 | var nestedNodeModulesPath = this.fs.join(sourceDirectory, 'node_modules');
|
93 | if (this.fs.exists(nestedNodeModulesPath)) {
|
94 | entryPoints.push.apply(entryPoints, tslib_1.__spread(this.walkDirectoryForPackages(nestedNodeModulesPath)));
|
95 | }
|
96 | }
|
97 | return entryPoints;
|
98 | }
|
99 | try {
|
100 | // The `sourceDirectory` was not a package (i.e. there was no package.json)
|
101 | // So search its sub-directories for Angular packages and entry-points
|
102 | for (var _b = tslib_1.__values(this.fs.readdir(sourceDirectory)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
103 | var path = _c.value;
|
104 | if (isIgnorablePath(path)) {
|
105 | // Ignore hidden files, node_modules and ngcc directory
|
106 | continue;
|
107 | }
|
108 | var absolutePath = this.fs.resolve(sourceDirectory, path);
|
109 | var stat = this.fs.lstat(absolutePath);
|
110 | if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
111 | // Ignore symbolic links and non-directories
|
112 | continue;
|
113 | }
|
114 | entryPoints.push.apply(entryPoints, tslib_1.__spread(this.walkDirectoryForPackages(this.fs.join(sourceDirectory, path))));
|
115 | }
|
116 | }
|
117 | catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
118 | finally {
|
119 | try {
|
120 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
121 | }
|
122 | finally { if (e_2) throw e_2.error; }
|
123 | }
|
124 | return entryPoints;
|
125 | };
|
126 | /**
|
127 | * Search the `directory` looking for any secondary entry-points for a package, adding any that
|
128 | * are found to the `entryPoints` array.
|
129 | *
|
130 | * @param entryPoints An array where we will add any entry-points found in this directory
|
131 | * @param packagePath The absolute path to the package that may contain entry-points
|
132 | * @param directory The current directory being searched
|
133 | * @param paths The paths contained in the current `directory`.
|
134 | */
|
135 | DirectoryWalkerEntryPointFinder.prototype.collectSecondaryEntryPoints = function (entryPoints, packagePath, directory, paths) {
|
136 | var e_3, _a;
|
137 | var _this = this;
|
138 | var _loop_1 = function (path) {
|
139 | if (isIgnorablePath(path)) {
|
140 | return "continue";
|
141 | }
|
142 | var absolutePath = this_1.fs.resolve(directory, path);
|
143 | var stat = this_1.fs.lstat(absolutePath);
|
144 | if (stat.isSymbolicLink()) {
|
145 | return "continue";
|
146 | }
|
147 | var isDirectory = stat.isDirectory();
|
148 | if (!path.endsWith('.js') && !isDirectory) {
|
149 | return "continue";
|
150 | }
|
151 | // If the path is a JS file then strip its extension and see if we can match an
|
152 | // entry-point.
|
153 | var possibleEntryPointPath = isDirectory ? absolutePath : stripJsExtension(absolutePath);
|
154 | var isEntryPoint = false;
|
155 | var subEntryPoint = entry_point_1.getEntryPointInfo(this_1.fs, this_1.config, this_1.logger, packagePath, possibleEntryPointPath);
|
156 | if (subEntryPoint !== entry_point_1.NO_ENTRY_POINT && subEntryPoint !== entry_point_1.INCOMPATIBLE_ENTRY_POINT) {
|
157 | entryPoints.push(subEntryPoint);
|
158 | isEntryPoint = true;
|
159 | }
|
160 | if (!isDirectory) {
|
161 | return "continue";
|
162 | }
|
163 | // This directory may contain entry-points of its own.
|
164 | var childPaths = this_1.fs.readdir(absolutePath);
|
165 | if (!isEntryPoint &&
|
166 | childPaths.some(function (childPath) { return childPath.endsWith('.js') &&
|
167 | _this.fs.stat(_this.fs.resolve(absolutePath, childPath)).isFile(); })) {
|
168 | return "continue";
|
169 | }
|
170 | this_1.collectSecondaryEntryPoints(entryPoints, packagePath, absolutePath, childPaths);
|
171 | };
|
172 | var this_1 = this;
|
173 | try {
|
174 | for (var paths_1 = tslib_1.__values(paths), paths_1_1 = paths_1.next(); !paths_1_1.done; paths_1_1 = paths_1.next()) {
|
175 | var path = paths_1_1.value;
|
176 | _loop_1(path);
|
177 | }
|
178 | }
|
179 | catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
180 | finally {
|
181 | try {
|
182 | if (paths_1_1 && !paths_1_1.done && (_a = paths_1.return)) _a.call(paths_1);
|
183 | }
|
184 | finally { if (e_3) throw e_3.error; }
|
185 | }
|
186 | };
|
187 | return DirectoryWalkerEntryPointFinder;
|
188 | }());
|
189 | exports.DirectoryWalkerEntryPointFinder = DirectoryWalkerEntryPointFinder;
|
190 | function stripJsExtension(filePath) {
|
191 | return filePath.replace(/\.js$/, '');
|
192 | }
|
193 | function isIgnorablePath(path) {
|
194 | return path.startsWith('.') || path === 'node_modules' || path === new_entry_point_file_writer_1.NGCC_DIRECTORY;
|
195 | }
|
196 | });
|
197 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0b3J5X3dhbGtlcl9lbnRyeV9wb2ludF9maW5kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci1jbGkvbmdjYy9zcmMvZW50cnlfcG9pbnRfZmluZGVyL2RpcmVjdG9yeV93YWxrZXJfZW50cnlfcG9pbnRfZmluZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztJQVdBLG1GQUFnSDtJQUdoSCxrSEFBc0U7SUFHdEUsaUZBQW9EO0lBRXBEOzs7T0FHRztJQUNIO1FBRUUseUNBQ1ksRUFBYyxFQUFVLE1BQXlCLEVBQVUsTUFBYyxFQUN6RSxRQUE0QixFQUFVLGtCQUFzQyxFQUM1RSxlQUErQixFQUFVLFlBQW9DO1lBRjdFLE9BQUUsR0FBRixFQUFFLENBQVk7WUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFtQjtZQUFVLFdBQU0sR0FBTixNQUFNLENBQVE7WUFDekUsYUFBUSxHQUFSLFFBQVEsQ0FBb0I7WUFBVSx1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1lBQzVFLG9CQUFlLEdBQWYsZUFBZSxDQUFnQjtZQUFVLGlCQUFZLEdBQVosWUFBWSxDQUF3QjtZQUpqRixjQUFTLEdBQUcsb0JBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBSUssQ0FBQztRQUM3Rjs7O1dBR0c7UUFDSCx5REFBZSxHQUFmOztZQUNFLElBQU0sbUJBQW1CLEdBQWlCLEVBQUUsQ0FBQzs7Z0JBQzdDLEtBQXVCLElBQUEsS0FBQSxpQkFBQSxJQUFJLENBQUMsU0FBUyxDQUFBLGdCQUFBLDRCQUFFO29CQUFsQyxJQUFNLFFBQVEsV0FBQTtvQkFDakIsSUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLDRCQUE0QixDQUFDLFFBQVEsQ0FBQzt3QkFDOUUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUMzQyxtQkFBbUIsQ0FBQyxJQUFJLE9BQXhCLG1CQUFtQixtQkFBUyxXQUFXLEdBQUU7aUJBQzFDOzs7Ozs7Ozs7WUFDRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsMkJBQTJCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBRUQ7Ozs7O1dBS0c7UUFDSCxpRUFBdUIsR0FBdkIsVUFBd0IsUUFBd0I7WUFBaEQsaUJBUUM7WUFQQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDYiwyQkFBeUIsUUFBUSxrREFBK0MsQ0FBQyxDQUFDO1lBQ3RGLElBQU0sV0FBVyxHQUFpQixxQkFBYSxDQUMzQyxjQUFNLE9BQUEsS0FBSSxDQUFDLHdCQUF3QixDQUFDLFFBQVEsQ0FBQyxFQUF2QyxDQUF1QyxFQUM3QyxVQUFBLFFBQVEsSUFBSSxPQUFBLEtBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQVcsUUFBUSwrQkFBMEIsUUFBUSxPQUFJLENBQUMsRUFBNUUsQ0FBNEUsQ0FBQyxDQUFDO1lBQzlGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDdkUsT0FBTyxXQUFXLENBQUM7UUFDckIsQ0FBQztRQUVEOzs7Ozs7V0FNRztRQUNILGtFQUF3QixHQUF4QixVQUF5QixlQUErQjs7WUFDdEQsdURBQXVEO1lBQ3ZELElBQU0saUJBQWlCLEdBQ25CLCtCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLGVBQWUsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUUzRiw4RkFBOEY7WUFDOUYsNkZBQTZGO1lBQzdGLG1CQUFtQjtZQUNuQixJQUFJLGlCQUFpQixLQUFLLHNDQUF3QixFQUFFO2dCQUNsRCxPQUFPLEVBQUUsQ0FBQzthQUNYO1lBRUQsSUFBTSxXQUFXLEdBQWlCLEVBQUUsQ0FBQztZQUNyQyxJQUFJLGlCQUFpQixLQUFLLDRCQUFjLEVBQUU7Z0JBQ3hDLFdBQVcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLDJCQUEyQixDQUM1QixXQUFXLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO2dCQUVyRix5RkFBeUY7Z0JBQ3pGLHdDQUF3QztnQkFDeEMsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxDQUFDLGlCQUFpQixFQUFuQixDQUFtQixDQUFDLEVBQUU7b0JBQzlDLElBQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLGNBQWMsQ0FBQyxDQUFDO29CQUM1RSxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEVBQUU7d0JBQ3pDLFdBQVcsQ0FBQyxJQUFJLE9BQWhCLFdBQVcsbUJBQVMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLHFCQUFxQixDQUFDLEdBQUU7cUJBQzNFO2lCQUNGO2dCQUVELE9BQU8sV0FBVyxDQUFDO2FBQ3BCOztnQkFFRCwyRUFBMkU7Z0JBQzNFLHNFQUFzRTtnQkFDdEUsS0FBbUIsSUFBQSxLQUFBLGlCQUFBLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFBLGdCQUFBLDRCQUFFO29CQUFoRCxJQUFNLElBQUksV0FBQTtvQkFDYixJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRTt3QkFDekIsdURBQXVEO3dCQUN2RCxTQUFTO3FCQUNWO29CQUVELElBQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDNUQsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3pDLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFO3dCQUNoRCw0Q0FBNEM7d0JBQzVDLFNBQVM7cUJBQ1Y7b0JBRUQsV0FBVyxDQUFDLElBQUksT0FBaEIsV0FBVyxtQkFBUyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUU7aUJBQ3pGOzs7Ozs7Ozs7WUFFRCxPQUFPLFdBQVcsQ0FBQztRQUNyQixDQUFDO1FBRUQ7Ozs7Ozs7O1dBUUc7UUFDSyxxRUFBMkIsR0FBbkMsVUFDSSxXQUF5QixFQUFFLFdBQTJCLEVBQUUsU0FBeUIsRUFDakYsS0FBb0I7O1lBRnhCLGlCQWtEQztvQ0EvQ1ksSUFBSTtnQkFDYixJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRTs7aUJBRzFCO2dCQUVELElBQU0sWUFBWSxHQUFHLE9BQUssRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3RELElBQU0sSUFBSSxHQUFHLE9BQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDekMsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUU7O2lCQUcxQjtnQkFFRCxJQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFOztpQkFHMUM7Z0JBRUQsK0VBQStFO2dCQUMvRSxlQUFlO2dCQUNmLElBQU0sc0JBQXNCLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUMzRixJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7Z0JBQ3pCLElBQU0sYUFBYSxHQUNmLCtCQUFpQixDQUFDLE9BQUssRUFBRSxFQUFFLE9BQUssTUFBTSxFQUFFLE9BQUssTUFBTSxFQUFFLFdBQVcsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO2dCQUM5RixJQUFJLGFBQWEsS0FBSyw0QkFBYyxJQUFJLGFBQWEsS0FBSyxzQ0FBd0IsRUFBRTtvQkFDbEYsV0FBVyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztvQkFDaEMsWUFBWSxHQUFHLElBQUksQ0FBQztpQkFDckI7Z0JBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRTs7aUJBR2pCO2dCQUVELHNEQUFzRDtnQkFDdEQsSUFBTSxVQUFVLEdBQUcsT0FBSyxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLENBQUMsWUFBWTtvQkFDYixVQUFVLENBQUMsSUFBSSxDQUNYLFVBQUEsU0FBUyxJQUFJLE9BQUEsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7d0JBQ2xDLEtBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUR0RCxDQUNzRCxDQUFDLEVBQUU7O2lCQUk3RTtnQkFDRCxPQUFLLDJCQUEyQixDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDOzs7O2dCQTdDdkYsS0FBbUIsSUFBQSxVQUFBLGlCQUFBLEtBQUssQ0FBQSw0QkFBQTtvQkFBbkIsSUFBTSxJQUFJLGtCQUFBOzRCQUFKLElBQUk7aUJBOENkOzs7Ozs7Ozs7UUFDSCxDQUFDO1FBQ0gsc0NBQUM7SUFBRCxDQUFDLEFBMUpELElBMEpDO0lBMUpZLDBFQUErQjtJQTRKNUMsU0FBUyxnQkFBZ0IsQ0FBbUIsUUFBVztRQUNyRCxPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBTSxDQUFDO0lBQzVDLENBQUM7SUFFRCxTQUFTLGVBQWUsQ0FBQyxJQUFpQjtRQUN4QyxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxLQUFLLGNBQWMsSUFBSSxJQUFJLEtBQUssNENBQWMsQ0FBQztJQUNwRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHtBYnNvbHV0ZUZzUGF0aCwgRmlsZVN5c3RlbSwgUGF0aFNlZ21lbnR9IGZyb20gJy4uLy4uLy4uL3NyYy9uZ3RzYy9maWxlX3N5c3RlbSc7XG5pbXBvcnQge0RlcGVuZGVuY3lSZXNvbHZlciwgU29ydGVkRW50cnlQb2ludHNJbmZvfSBmcm9tICcuLi9kZXBlbmRlbmNpZXMvZGVwZW5kZW5jeV9yZXNvbHZlcic7XG5pbXBvcnQge0xvZ2dlcn0gZnJvbSAnLi4vbG9nZ2luZy9sb2dnZXInO1xuaW1wb3J0IHtOZ2NjQ29uZmlndXJhdGlvbn0gZnJvbSAnLi4vcGFja2FnZXMvY29uZmlndXJhdGlvbic7XG5pbXBvcnQge0VudHJ5UG9pbnQsIGdldEVudHJ5UG9pbnRJbmZvLCBJTkNPTVBBVElCTEVfRU5UUllfUE9JTlQsIE5PX0VOVFJZX1BPSU5UfSBmcm9tICcuLi9wYWNrYWdlcy9lbnRyeV9wb2ludCc7XG5pbXBvcnQge0VudHJ5UG9pbnRNYW5pZmVzdH0gZnJvbSAnLi4vcGFja2FnZXMvZW50cnlfcG9pbnRfbWFuaWZlc3QnO1xuaW1wb3J0IHtQYXRoTWFwcGluZ3N9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7TkdDQ19ESVJFQ1RPUll9IGZyb20gJy4uL3dyaXRpbmcvbmV3X2VudHJ5X3BvaW50X2ZpbGVfd3JpdGVyJztcblxuaW1wb3J0IHtFbnRyeVBvaW50RmluZGVyfSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQge2dldEJhc2VQYXRocywgdHJhY2tEdXJhdGlvbn0gZnJvbSAnLi91dGlscyc7XG5cbi8qKlxuICogQW4gRW50cnlQb2ludEZpbmRlciB0aGF0IHNlYXJjaGVzIGZvciBhbGwgZW50cnktcG9pbnRzIHRoYXQgY2FuIGJlIGZvdW5kIGdpdmVuIGEgYGJhc2VQYXRoYCBhbmRcbiAqIGBwYXRoTWFwcGluZ3NgLlxuICovXG5leHBvcnQgY2xhc3MgRGlyZWN0b3J5V2Fsa2VyRW50cnlQb2ludEZpbmRlciBpbXBsZW1lbnRzIEVudHJ5UG9pbnRGaW5kZXIge1xuICBwcml2YXRlIGJhc2VQYXRocyA9IGdldEJhc2VQYXRocyh0aGlzLmxvZ2dlciwgdGhpcy5zb3VyY2VEaXJlY3RvcnksIHRoaXMucGF0aE1hcHBpbmdzKTtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIGZzOiBGaWxlU3lzdGVtLCBwcml2YXRlIGNvbmZpZzogTmdjY0NvbmZpZ3VyYXRpb24sIHByaXZhdGUgbG9nZ2VyOiBMb2dnZXIsXG4gICAgICBwcml2YXRlIHJlc29sdmVyOiBEZXBlbmRlbmN5UmVzb2x2ZXIsIHByaXZhdGUgZW50cnlQb2ludE1hbmlmZXN0OiBFbnRyeVBvaW50TWFuaWZlc3QsXG4gICAgICBwcml2YXRlIHNvdXJjZURpcmVjdG9yeTogQWJzb2x1dGVGc1BhdGgsIHByaXZhdGUgcGF0aE1hcHBpbmdzOiBQYXRoTWFwcGluZ3N8dW5kZWZpbmVkKSB7fVxuICAvKipcbiAgICogU2VhcmNoIHRoZSBgc291cmNlRGlyZWN0b3J5YCwgYW5kIHN1Yi1kaXJlY3RvcmllcywgdXNpbmcgYHBhdGhNYXBwaW5nc2AgYXMgbmVjZXNzYXJ5LCB0byBmaW5kXG4gICAqIGFsbCBwYWNrYWdlIGVudHJ5LXBvaW50cy5cbiAgICovXG4gIGZpbmRFbnRyeVBvaW50cygpOiBTb3J0ZWRFbnRyeVBvaW50c0luZm8ge1xuICAgIGNvbnN0IHVuc29ydGVkRW50cnlQb2ludHM6IEVudHJ5UG9pbnRbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgYmFzZVBhdGggb2YgdGhpcy5iYXNlUGF0aHMpIHtcbiAgICAgIGNvbnN0IGVudHJ5UG9pbnRzID0gdGhpcy5lbnRyeVBvaW50TWFuaWZlc3QucmVhZEVudHJ5UG9pbnRzVXNpbmdNYW5pZmVzdChiYXNlUGF0aCkgfHxcbiAgICAgICAgICB0aGlzLndhbGtCYXNlUGF0aEZvclBhY2thZ2VzKGJhc2VQYXRoKTtcbiAgICAgIHVuc29ydGVkRW50cnlQb2ludHMucHVzaCguLi5lbnRyeVBvaW50cyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlc29sdmVyLnNvcnRFbnRyeVBvaW50c0J5RGVwZW5kZW5jeSh1bnNvcnRlZEVudHJ5UG9pbnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWFyY2ggdGhlIGBiYXNlUGF0aGAgZm9yIHBvc3NpYmxlIEFuZ3VsYXIgcGFja2FnZXMgYW5kIGVudHJ5LXBvaW50cy5cbiAgICpcbiAgICogQHBhcmFtIGJhc2VQYXRoIFRoZSBwYXRoIGF0IHdoaWNoIHRvIHN0YXJ0IHRoZSBzZWFyY2hcbiAgICogQHJldHVybnMgYW4gYXJyYXkgb2YgYEVudHJ5UG9pbnRgcyB0aGF0IHdlcmUgZm91bmQgd2l0aGluIGBiYXNlUGF0aGAuXG4gICAqL1xuICB3YWxrQmFzZVBhdGhGb3JQYWNrYWdlcyhiYXNlUGF0aDogQWJzb2x1dGVGc1BhdGgpOiBFbnRyeVBvaW50W10ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTm8gbWFuaWZlc3QgZm91bmQgZm9yICR7YmFzZVBhdGh9IHNvIHdhbGtpbmcgdGhlIGRpcmVjdG9yaWVzIGZvciBlbnRyeS1wb2ludHMuYCk7XG4gICAgY29uc3QgZW50cnlQb2ludHM6IEVudHJ5UG9pbnRbXSA9IHRyYWNrRHVyYXRpb24oXG4gICAgICAgICgpID0+IHRoaXMud2Fsa0RpcmVjdG9yeUZvclBhY2thZ2VzKGJhc2VQYXRoKSxcbiAgICAgICAgZHVyYXRpb24gPT4gdGhpcy5sb2dnZXIuZGVidWcoYFdhbGtpbmcgJHtiYXNlUGF0aH0gZm9yIGVudHJ5LXBvaW50cyB0b29rICR7ZHVyYXRpb259cy5gKSk7XG4gICAgdGhpcy5lbnRyeVBvaW50TWFuaWZlc3Qud3JpdGVFbnRyeVBvaW50TWFuaWZlc3QoYmFzZVBhdGgsIGVudHJ5UG9pbnRzKTtcbiAgICByZXR1cm4gZW50cnlQb2ludHM7XG4gIH1cblxuICAvKipcbiAgICogTG9vayBmb3IgQW5ndWxhciBwYWNrYWdlcyB0aGF0IG5lZWQgdG8gYmUgY29tcGlsZWQsIHN0YXJ0aW5nIGF0IHRoZSBzb3VyY2UgZGlyZWN0b3J5LlxuICAgKiBUaGUgZnVuY3Rpb24gd2lsbCByZWN1cnNlIGludG8gZGlyZWN0b3JpZXMgdGhhdCBzdGFydCB3aXRoIGBALi4uYCwgZS5nLiBgQGFuZ3VsYXIvLi4uYC5cbiAgICpcbiAgICogQHBhcmFtIHNvdXJjZURpcmVjdG9yeSBBbiBhYnNvbHV0ZSBwYXRoIHRvIHRoZSByb290IGRpcmVjdG9yeSB3aGVyZSBzZWFyY2hpbmcgYmVnaW5zLlxuICAgKiBAcmV0dXJucyBhbiBhcnJheSBvZiBgRW50cnlQb2ludGBzIHRoYXQgd2VyZSBmb3VuZCB3aXRoaW4gYHNvdXJjZURpcmVjdG9yeWAuXG4gICAqL1xuICB3YWxrRGlyZWN0b3J5Rm9yUGFja2FnZXMoc291cmNlRGlyZWN0b3J5OiBBYnNvbHV0ZUZzUGF0aCk6IEVudHJ5UG9pbnRbXSB7XG4gICAgLy8gVHJ5IHRvIGdldCBhIHByaW1hcnkgZW50cnkgcG9pbnQgZnJvbSB0aGlzIGRpcmVjdG9yeVxuICAgIGNvbnN0IHByaW1hcnlFbnRyeVBvaW50ID1cbiAgICAgICAgZ2V0RW50cnlQb2ludEluZm8odGhpcy5mcywgdGhpcy5jb25maWcsIHRoaXMubG9nZ2VyLCBzb3VyY2VEaXJlY3RvcnksIHNvdXJjZURpcmVjdG9yeSk7XG5cbiAgICAvLyBJZiB0aGVyZSBpcyBhbiBlbnRyeS1wb2ludCBidXQgaXQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBuZ2NjIChpdCBoYXMgYSBiYWQgcGFja2FnZS5qc29uIG9yXG4gICAgLy8gaW52YWxpZCB0eXBpbmdzKSB0aGVuIGV4aXQuIEl0IGlzIHVubGlrZWx5IHRoYXQgc3VjaCBhbiBlbnRyeSBwb2ludCBoYXMgYSBkZXBlbmRlbmN5IG9uIGFuXG4gICAgLy8gQW5ndWxhciBsaWJyYXJ5LlxuICAgIGlmIChwcmltYXJ5RW50cnlQb2ludCA9PT0gSU5DT01QQVRJQkxFX0VOVFJZX1BPSU5UKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgZW50cnlQb2ludHM6IEVudHJ5UG9pbnRbXSA9IFtdO1xuICAgIGlmIChwcmltYXJ5RW50cnlQb2ludCAhPT0gTk9fRU5UUllfUE9JTlQpIHtcbiAgICAgIGVudHJ5UG9pbnRzLnB1c2gocHJpbWFyeUVudHJ5UG9pbnQpO1xuICAgICAgdGhpcy5jb2xsZWN0U2Vjb25kYXJ5RW50cnlQb2ludHMoXG4gICAgICAgICAgZW50cnlQb2ludHMsIHNvdXJjZURpcmVjdG9yeSwgc291cmNlRGlyZWN0b3J5LCB0aGlzLmZzLnJlYWRkaXIoc291cmNlRGlyZWN0b3J5KSk7XG5cbiAgICAgIC8vIEFsc28gY2hlY2sgZm9yIGFueSBuZXN0ZWQgbm9kZV9tb2R1bGVzIGluIHRoaXMgcGFja2FnZSBidXQgb25seSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlXG4gICAgICAvLyBlbnRyeS1wb2ludHMgd2FzIGNvbXBpbGVkIGJ5IEFuZ3VsYXIuXG4gICAgICBpZiAoZW50cnlQb2ludHMuc29tZShlID0+IGUuY29tcGlsZWRCeUFuZ3VsYXIpKSB7XG4gICAgICAgIGNvbnN0IG5lc3RlZE5vZGVNb2R1bGVzUGF0aCA9IHRoaXMuZnMuam9pbihzb3VyY2VEaXJlY3RvcnksICdub2RlX21vZHVsZXMnKTtcbiAgICAgICAgaWYgKHRoaXMuZnMuZXhpc3RzKG5lc3RlZE5vZGVNb2R1bGVzUGF0aCkpIHtcbiAgICAgICAgICBlbnRyeVBvaW50cy5wdXNoKC4uLnRoaXMud2Fsa0RpcmVjdG9yeUZvclBhY2thZ2VzKG5lc3RlZE5vZGVNb2R1bGVzUGF0aCkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlbnRyeVBvaW50cztcbiAgICB9XG5cbiAgICAvLyBUaGUgYHNvdXJjZURpcmVjdG9yeWAgd2FzIG5vdCBhIHBhY2thZ2UgKGkuZS4gdGhlcmUgd2FzIG5vIHBhY2thZ2UuanNvbilcbiAgICAvLyBTbyBzZWFyY2ggaXRzIHN1Yi1kaXJlY3RvcmllcyBmb3IgQW5ndWxhciBwYWNrYWdlcyBhbmQgZW50cnktcG9pbnRzXG4gICAgZm9yIChjb25zdCBwYXRoIG9mIHRoaXMuZnMucmVhZGRpcihzb3VyY2VEaXJlY3RvcnkpKSB7XG4gICAgICBpZiAoaXNJZ25vcmFibGVQYXRoKHBhdGgpKSB7XG4gICAgICAgIC8vIElnbm9yZSBoaWRkZW4gZmlsZXMsIG5vZGVfbW9kdWxlcyBhbmQgbmdjYyBkaXJlY3RvcnlcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHRoaXMuZnMucmVzb2x2ZShzb3VyY2VEaXJlY3RvcnksIHBhdGgpO1xuICAgICAgY29uc3Qgc3RhdCA9IHRoaXMuZnMubHN0YXQoYWJzb2x1dGVQYXRoKTtcbiAgICAgIGlmIChzdGF0LmlzU3ltYm9saWNMaW5rKCkgfHwgIXN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAvLyBJZ25vcmUgc3ltYm9saWMgbGlua3MgYW5kIG5vbi1kaXJlY3Rvcmllc1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgZW50cnlQb2ludHMucHVzaCguLi50aGlzLndhbGtEaXJlY3RvcnlGb3JQYWNrYWdlcyh0aGlzLmZzLmpvaW4oc291cmNlRGlyZWN0b3J5LCBwYXRoKSkpO1xuICAgIH1cblxuICAgIHJldHVybiBlbnRyeVBvaW50cztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWFyY2ggdGhlIGBkaXJlY3RvcnlgIGxvb2tpbmcgZm9yIGFueSBzZWNvbmRhcnkgZW50cnktcG9pbnRzIGZvciBhIHBhY2thZ2UsIGFkZGluZyBhbnkgdGhhdFxuICAgKiBhcmUgZm91bmQgdG8gdGhlIGBlbnRyeVBvaW50c2AgYXJyYXkuXG4gICAqXG4gICAqIEBwYXJhbSBlbnRyeVBvaW50cyBBbiBhcnJheSB3aGVyZSB3ZSB3aWxsIGFkZCBhbnkgZW50cnktcG9pbnRzIGZvdW5kIGluIHRoaXMgZGlyZWN0b3J5XG4gICAqIEBwYXJhbSBwYWNrYWdlUGF0aCBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgcGFja2FnZSB0aGF0IG1heSBjb250YWluIGVudHJ5LXBvaW50c1xuICAgKiBAcGFyYW0gZGlyZWN0b3J5IFRoZSBjdXJyZW50IGRpcmVjdG9yeSBiZWluZyBzZWFyY2hlZFxuICAgKiBAcGFyYW0gcGF0aHMgVGhlIHBhdGhzIGNvbnRhaW5lZCBpbiB0aGUgY3VycmVudCBgZGlyZWN0b3J5YC5cbiAgICovXG4gIHByaXZhdGUgY29sbGVjdFNlY29uZGFyeUVudHJ5UG9pbnRzKFxuICAgICAgZW50cnlQb2ludHM6IEVudHJ5UG9pbnRbXSwgcGFja2FnZVBhdGg6IEFic29sdXRlRnNQYXRoLCBkaXJlY3Rvcnk6IEFic29sdXRlRnNQYXRoLFxuICAgICAgcGF0aHM6IFBhdGhTZWdtZW50W10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAgIGlmIChpc0lnbm9yYWJsZVBhdGgocGF0aCkpIHtcbiAgICAgICAgLy8gSWdub3JlIGhpZGRlbiBmaWxlcywgbm9kZV9tb2R1bGVzIGFuZCBuZ2NjIGRpcmVjdG9yeVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYWJzb2x1dGVQYXRoID0gdGhpcy5mcy5yZXNvbHZlKGRpcmVjdG9yeSwgcGF0aCk7XG4gICAgICBjb25zdCBzdGF0ID0gdGhpcy5mcy5sc3RhdChhYnNvbHV0ZVBhdGgpO1xuICAgICAgaWYgKHN0YXQuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgICAvLyBJZ25vcmUgc3ltYm9saWMgbGlua3NcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlzRGlyZWN0b3J5ID0gc3RhdC5pc0RpcmVjdG9yeSgpO1xuICAgICAgaWYgKCFwYXRoLmVuZHNXaXRoKCcuanMnKSAmJiAhaXNEaXJlY3RvcnkpIHtcbiAgICAgICAgLy8gSWdub3JlIGZpbGVzIHRoYXQgZG8gbm90IGVuZCBpbiBgLmpzYFxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIHBhdGggaXMgYSBKUyBmaWxlIHRoZW4gc3RyaXAgaXRzIGV4dGVuc2lvbiBhbmQgc2VlIGlmIHdlIGNhbiBtYXRjaCBhblxuICAgICAgLy8gZW50cnktcG9pbnQuXG4gICAgICBjb25zdCBwb3NzaWJsZUVudHJ5UG9pbnRQYXRoID0gaXNEaXJlY3RvcnkgPyBhYnNvbHV0ZVBhdGggOiBzdHJpcEpzRXh0ZW5zaW9uKGFic29sdXRlUGF0aCk7XG4gICAgICBsZXQgaXNFbnRyeVBvaW50ID0gZmFsc2U7XG4gICAgICBjb25zdCBzdWJFbnRyeVBvaW50ID1cbiAgICAgICAgICBnZXRFbnRyeVBvaW50SW5mbyh0aGlzLmZzLCB0aGlzLmNvbmZpZywgdGhpcy5sb2dnZXIsIHBhY2thZ2VQYXRoLCBwb3NzaWJsZUVudHJ5UG9pbnRQYXRoKTtcbiAgICAgIGlmIChzdWJFbnRyeVBvaW50ICE9PSBOT19FTlRSWV9QT0lOVCAmJiBzdWJFbnRyeVBvaW50ICE9PSBJTkNPTVBBVElCTEVfRU5UUllfUE9JTlQpIHtcbiAgICAgICAgZW50cnlQb2ludHMucHVzaChzdWJFbnRyeVBvaW50KTtcbiAgICAgICAgaXNFbnRyeVBvaW50ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc0RpcmVjdG9yeSkge1xuICAgICAgICAvLyBUaGlzIHBhdGggaXMgbm90IGEgZGlyZWN0b3J5IHNvIHdlIGFyZSBkb25lLlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gVGhpcyBkaXJlY3RvcnkgbWF5IGNvbnRhaW4gZW50cnktcG9pbnRzIG9mIGl0cyBvd24uXG4gICAgICBjb25zdCBjaGlsZFBhdGhzID0gdGhpcy5mcy5yZWFkZGlyKGFic29sdXRlUGF0aCk7XG4gICAgICBpZiAoIWlzRW50cnlQb2ludCAmJlxuICAgICAgICAgIGNoaWxkUGF0aHMuc29tZShcbiAgICAgICAgICAgICAgY2hpbGRQYXRoID0+IGNoaWxkUGF0aC5lbmRzV2l0aCgnLmpzJykgJiZcbiAgICAgICAgICAgICAgICAgIHRoaXMuZnMuc3RhdCh0aGlzLmZzLnJlc29sdmUoYWJzb2x1dGVQYXRoLCBjaGlsZFBhdGgpKS5pc0ZpbGUoKSkpIHtcbiAgICAgICAgLy8gV2UgZG8gbm90IGNvbnNpZGVyIG5vbi1lbnRyeS1wb2ludCBkaXJlY3RvcmllcyB0aGF0IGNvbnRhaW4gSlMgZmlsZXMgYXMgdGhleSBhcmUgdmVyeVxuICAgICAgICAvLyB1bmxpa2VseSB0byBiZSBjb250YWluZXJzIGZvciBzdWItZW50cnktcG9pbnRzLlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY29sbGVjdFNlY29uZGFyeUVudHJ5UG9pbnRzKGVudHJ5UG9pbnRzLCBwYWNrYWdlUGF0aCwgYWJzb2x1dGVQYXRoLCBjaGlsZFBhdGhzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc3RyaXBKc0V4dGVuc2lvbjxUIGV4dGVuZHMgc3RyaW5nPihmaWxlUGF0aDogVCk6IFQge1xuICByZXR1cm4gZmlsZVBhdGgucmVwbGFjZSgvXFwuanMkLywgJycpIGFzIFQ7XG59XG5cbmZ1bmN0aW9uIGlzSWdub3JhYmxlUGF0aChwYXRoOiBQYXRoU2VnbWVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcGF0aC5zdGFydHNXaXRoKCcuJykgfHwgcGF0aCA9PT0gJ25vZGVfbW9kdWxlcycgfHwgcGF0aCA9PT0gTkdDQ19ESVJFQ1RPUlk7XG59XG4iXX0= |
\ | No newline at end of file |