1 | /**
|
2 | * @license
|
3 | * Copyright Google Inc. All Rights Reserved.
|
4 | *
|
5 | * Use of this source code is governed by an MIT-style license that can be
|
6 | * found in the LICENSE file at https://angular.io/license
|
7 | */
|
8 | (function (factory) {
|
9 | if (typeof module === "object" && typeof module.exports === "object") {
|
10 | var v = factory(require, exports);
|
11 | if (v !== undefined) module.exports = v;
|
12 | }
|
13 | else if (typeof define === "function" && define.amd) {
|
14 | define("@angular/compiler-cli/src/perform_watch", ["require", "exports", "chokidar", "path", "typescript", "@angular/compiler-cli/src/perform_compile", "@angular/compiler-cli/src/transformers/api", "@angular/compiler-cli/src/transformers/entry_points", "@angular/compiler-cli/src/transformers/util"], factory);
|
15 | }
|
16 | })(function (require, exports) {
|
17 | ;
|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
19 | var chokidar = require("chokidar");
|
20 | var path = require("path");
|
21 | var ts = require("typescript");
|
22 | var perform_compile_1 = require("@angular/compiler-cli/src/perform_compile");
|
23 | var api = require("@angular/compiler-cli/src/transformers/api");
|
24 | var entry_points_1 = require("@angular/compiler-cli/src/transformers/entry_points");
|
25 | var util_1 = require("@angular/compiler-cli/src/transformers/util");
|
26 | function totalCompilationTimeDiagnostic(timeInMillis) {
|
27 | var duration;
|
28 | if (timeInMillis > 1000) {
|
29 | duration = (timeInMillis / 1000).toPrecision(2) + "s";
|
30 | }
|
31 | else {
|
32 | duration = timeInMillis + "ms";
|
33 | }
|
34 | return {
|
35 | category: ts.DiagnosticCategory.Message,
|
36 | messageText: "Total time: " + duration,
|
37 | code: api.DEFAULT_ERROR_CODE,
|
38 | source: api.SOURCE,
|
39 | };
|
40 | }
|
41 | var FileChangeEvent;
|
42 | (function (FileChangeEvent) {
|
43 | FileChangeEvent[FileChangeEvent["Change"] = 0] = "Change";
|
44 | FileChangeEvent[FileChangeEvent["CreateDelete"] = 1] = "CreateDelete";
|
45 | FileChangeEvent[FileChangeEvent["CreateDeleteDir"] = 2] = "CreateDeleteDir";
|
46 | })(FileChangeEvent = exports.FileChangeEvent || (exports.FileChangeEvent = {}));
|
47 | function createPerformWatchHost(configFileName, reportDiagnostics, existingOptions, createEmitCallback) {
|
48 | return {
|
49 | reportDiagnostics: reportDiagnostics,
|
50 | createCompilerHost: function (options) { return entry_points_1.createCompilerHost({ options: options }); },
|
51 | readConfiguration: function () { return perform_compile_1.readConfiguration(configFileName, existingOptions); },
|
52 | createEmitCallback: function (options) { return createEmitCallback ? createEmitCallback(options) : undefined; },
|
53 | onFileChange: function (options, listener, ready) {
|
54 | if (!options.basePath) {
|
55 | reportDiagnostics([{
|
56 | category: ts.DiagnosticCategory.Error,
|
57 | messageText: 'Invalid configuration option. baseDir not specified',
|
58 | source: api.SOURCE,
|
59 | code: api.DEFAULT_ERROR_CODE
|
60 | }]);
|
61 | return { close: function () { } };
|
62 | }
|
63 | var watcher = chokidar.watch(options.basePath, {
|
64 | // ignore .dotfiles, .js and .map files.
|
65 | // can't ignore other files as we e.g. want to recompile if an `.html` file changes as well.
|
66 | ignored: /((^[\/\\])\..)|(\.js$)|(\.map$)|(\.metadata\.json|node_modules)/,
|
67 | ignoreInitial: true,
|
68 | persistent: true,
|
69 | });
|
70 | watcher.on('all', function (event, path) {
|
71 | switch (event) {
|
72 | case 'change':
|
73 | listener(FileChangeEvent.Change, path);
|
74 | break;
|
75 | case 'unlink':
|
76 | case 'add':
|
77 | listener(FileChangeEvent.CreateDelete, path);
|
78 | break;
|
79 | case 'unlinkDir':
|
80 | case 'addDir':
|
81 | listener(FileChangeEvent.CreateDeleteDir, path);
|
82 | break;
|
83 | }
|
84 | });
|
85 | watcher.on('ready', ready);
|
86 | return { close: function () { return watcher.close(); }, ready: ready };
|
87 | },
|
88 | setTimeout: (ts.sys.clearTimeout && ts.sys.setTimeout) || setTimeout,
|
89 | clearTimeout: (ts.sys.setTimeout && ts.sys.clearTimeout) || clearTimeout,
|
90 | };
|
91 | }
|
92 | exports.createPerformWatchHost = createPerformWatchHost;
|
93 | /**
|
94 | * The logic in this function is adapted from `tsc.ts` from TypeScript.
|
95 | */
|
96 | function performWatchCompilation(host) {
|
97 | var cachedProgram; // Program cached from last compilation
|
98 | var cachedCompilerHost; // CompilerHost cached from last compilation
|
99 | var cachedOptions; // CompilerOptions cached from last compilation
|
100 | var timerHandleForRecompilation; // Handle for 0.25s wait timer to trigger recompilation
|
101 | var ignoreFilesForWatch = new Set();
|
102 | var fileCache = new Map();
|
103 | var firstCompileResult = doCompilation();
|
104 | // Watch basePath, ignoring .dotfiles
|
105 | var resolveReadyPromise;
|
106 | var readyPromise = new Promise(function (resolve) { return resolveReadyPromise = resolve; });
|
107 | // Note: ! is ok as options are filled after the first compilation
|
108 | // Note: ! is ok as resolvedReadyPromise is filled by the previous call
|
109 | var fileWatcher = host.onFileChange(cachedOptions.options, watchedFileChanged, resolveReadyPromise);
|
110 | return { close: close, ready: function (cb) { return readyPromise.then(cb); }, firstCompileResult: firstCompileResult };
|
111 | function cacheEntry(fileName) {
|
112 | fileName = path.normalize(fileName);
|
113 | var entry = fileCache.get(fileName);
|
114 | if (!entry) {
|
115 | entry = {};
|
116 | fileCache.set(fileName, entry);
|
117 | }
|
118 | return entry;
|
119 | }
|
120 | function close() {
|
121 | fileWatcher.close();
|
122 | if (timerHandleForRecompilation) {
|
123 | host.clearTimeout(timerHandleForRecompilation.timerHandle);
|
124 | timerHandleForRecompilation = undefined;
|
125 | }
|
126 | }
|
127 | // Invoked to perform initial compilation or re-compilation in watch mode
|
128 | function doCompilation(modifiedResourceFiles) {
|
129 | if (!cachedOptions) {
|
130 | cachedOptions = host.readConfiguration();
|
131 | }
|
132 | if (cachedOptions.errors && cachedOptions.errors.length) {
|
133 | host.reportDiagnostics(cachedOptions.errors);
|
134 | return cachedOptions.errors;
|
135 | }
|
136 | var startTime = Date.now();
|
137 | if (!cachedCompilerHost) {
|
138 | cachedCompilerHost = host.createCompilerHost(cachedOptions.options);
|
139 | var originalWriteFileCallback_1 = cachedCompilerHost.writeFile;
|
140 | cachedCompilerHost.writeFile = function (fileName, data, writeByteOrderMark, onError, sourceFiles) {
|
141 | if (sourceFiles === void 0) { sourceFiles = []; }
|
142 | ignoreFilesForWatch.add(path.normalize(fileName));
|
143 | return originalWriteFileCallback_1(fileName, data, writeByteOrderMark, onError, sourceFiles);
|
144 | };
|
145 | var originalFileExists_1 = cachedCompilerHost.fileExists;
|
146 | cachedCompilerHost.fileExists = function (fileName) {
|
147 | var ce = cacheEntry(fileName);
|
148 | if (ce.exists == null) {
|
149 | ce.exists = originalFileExists_1.call(this, fileName);
|
150 | }
|
151 | return ce.exists;
|
152 | };
|
153 | var originalGetSourceFile_1 = cachedCompilerHost.getSourceFile;
|
154 | cachedCompilerHost.getSourceFile = function (fileName, languageVersion) {
|
155 | var ce = cacheEntry(fileName);
|
156 | if (!ce.sf) {
|
157 | ce.sf = originalGetSourceFile_1.call(this, fileName, languageVersion);
|
158 | }
|
159 | return ce.sf;
|
160 | };
|
161 | var originalReadFile_1 = cachedCompilerHost.readFile;
|
162 | cachedCompilerHost.readFile = function (fileName) {
|
163 | var ce = cacheEntry(fileName);
|
164 | if (ce.content == null) {
|
165 | ce.content = originalReadFile_1.call(this, fileName);
|
166 | }
|
167 | return ce.content;
|
168 | };
|
169 | // Provide access to the file paths that triggered this rebuild
|
170 | cachedCompilerHost.getModifiedResourceFiles =
|
171 | modifiedResourceFiles !== undefined ? function () { return modifiedResourceFiles; } : undefined;
|
172 | }
|
173 | ignoreFilesForWatch.clear();
|
174 | var oldProgram = cachedProgram;
|
175 | // We clear out the `cachedProgram` here as a
|
176 | // program can only be used as `oldProgram` 1x
|
177 | cachedProgram = undefined;
|
178 | var compileResult = perform_compile_1.performCompilation({
|
179 | rootNames: cachedOptions.rootNames,
|
180 | options: cachedOptions.options,
|
181 | host: cachedCompilerHost,
|
182 | oldProgram: oldProgram,
|
183 | emitCallback: host.createEmitCallback(cachedOptions.options)
|
184 | });
|
185 | if (compileResult.diagnostics.length) {
|
186 | host.reportDiagnostics(compileResult.diagnostics);
|
187 | }
|
188 | var endTime = Date.now();
|
189 | if (cachedOptions.options.diagnostics) {
|
190 | var totalTime = (endTime - startTime) / 1000;
|
191 | host.reportDiagnostics([totalCompilationTimeDiagnostic(endTime - startTime)]);
|
192 | }
|
193 | var exitCode = perform_compile_1.exitCodeFromResult(compileResult.diagnostics);
|
194 | if (exitCode == 0) {
|
195 | cachedProgram = compileResult.program;
|
196 | host.reportDiagnostics([util_1.createMessageDiagnostic('Compilation complete. Watching for file changes.')]);
|
197 | }
|
198 | else {
|
199 | host.reportDiagnostics([util_1.createMessageDiagnostic('Compilation failed. Watching for file changes.')]);
|
200 | }
|
201 | return compileResult.diagnostics;
|
202 | }
|
203 | function resetOptions() {
|
204 | cachedProgram = undefined;
|
205 | cachedCompilerHost = undefined;
|
206 | cachedOptions = undefined;
|
207 | }
|
208 | function watchedFileChanged(event, fileName) {
|
209 | if (cachedOptions && event === FileChangeEvent.Change &&
|
210 | // TODO(chuckj): validate that this is sufficient to skip files that were written.
|
211 | // This assumes that the file path we write is the same file path we will receive in the
|
212 | // change notification.
|
213 | path.normalize(fileName) === path.normalize(cachedOptions.project)) {
|
214 | // If the configuration file changes, forget everything and start the recompilation timer
|
215 | resetOptions();
|
216 | }
|
217 | else if (event === FileChangeEvent.CreateDelete || event === FileChangeEvent.CreateDeleteDir) {
|
218 | // If a file was added or removed, reread the configuration
|
219 | // to determine the new list of root files.
|
220 | cachedOptions = undefined;
|
221 | }
|
222 | if (event === FileChangeEvent.CreateDeleteDir) {
|
223 | fileCache.clear();
|
224 | }
|
225 | else {
|
226 | fileCache.delete(path.normalize(fileName));
|
227 | }
|
228 | if (!ignoreFilesForWatch.has(path.normalize(fileName))) {
|
229 | // Ignore the file if the file is one that was written by the compiler.
|
230 | startTimerForRecompilation(fileName);
|
231 | }
|
232 | }
|
233 | // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch
|
234 | // operations (such as saving all modified files in an editor) a chance to complete before we kick
|
235 | // off a new compilation.
|
236 | function startTimerForRecompilation(changedPath) {
|
237 | if (timerHandleForRecompilation) {
|
238 | host.clearTimeout(timerHandleForRecompilation.timerHandle);
|
239 | }
|
240 | else {
|
241 | timerHandleForRecompilation = {
|
242 | modifiedResourceFiles: new Set(),
|
243 | timerHandle: undefined
|
244 | };
|
245 | }
|
246 | timerHandleForRecompilation.timerHandle = host.setTimeout(recompile, 250);
|
247 | timerHandleForRecompilation.modifiedResourceFiles.add(changedPath);
|
248 | }
|
249 | function recompile() {
|
250 | host.reportDiagnostics([util_1.createMessageDiagnostic('File change detected. Starting incremental compilation.')]);
|
251 | doCompilation(timerHandleForRecompilation.modifiedResourceFiles);
|
252 | timerHandleForRecompilation = undefined;
|
253 | }
|
254 | }
|
255 | exports.performWatchCompilation = performWatchCompilation;
|
256 | });
|
257 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVyZm9ybV93YXRjaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyLWNsaS9zcmMvcGVyZm9ybV93YXRjaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7OztJQUVILG1DQUFxQztJQUNyQywyQkFBNkI7SUFDN0IsK0JBQWlDO0lBRWpDLDZFQUF3SjtJQUN4SixnRUFBMEM7SUFDMUMsb0ZBQStEO0lBQy9ELG9FQUE0RDtJQUU1RCxTQUFTLDhCQUE4QixDQUFDLFlBQW9CO1FBQzFELElBQUksUUFBZ0IsQ0FBQztRQUNyQixJQUFJLFlBQVksR0FBRyxJQUFJLEVBQUU7WUFDdkIsUUFBUSxHQUFNLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBRyxDQUFDO1NBQ3ZEO2FBQU07WUFDTCxRQUFRLEdBQU0sWUFBWSxPQUFJLENBQUM7U0FDaEM7UUFDRCxPQUFPO1lBQ0wsUUFBUSxFQUFFLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPO1lBQ3ZDLFdBQVcsRUFBRSxpQkFBZSxRQUFVO1lBQ3RDLElBQUksRUFBRSxHQUFHLENBQUMsa0JBQWtCO1lBQzVCLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTTtTQUNuQixDQUFDO0lBQ0osQ0FBQztJQUVELElBQVksZUFJWDtJQUpELFdBQVksZUFBZTtRQUN6Qix5REFBTSxDQUFBO1FBQ04scUVBQVksQ0FBQTtRQUNaLDJFQUFlLENBQUE7SUFDakIsQ0FBQyxFQUpXLGVBQWUsR0FBZix1QkFBZSxLQUFmLHVCQUFlLFFBSTFCO0lBY0QsU0FBZ0Isc0JBQXNCLENBQ2xDLGNBQXNCLEVBQUUsaUJBQXFELEVBQzdFLGVBQW9DLEVBQUUsa0JBQ2tDO1FBQzFFLE9BQU87WUFDTCxpQkFBaUIsRUFBRSxpQkFBaUI7WUFDcEMsa0JBQWtCLEVBQUUsVUFBQSxPQUFPLElBQUks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QUFDLDJCQUEyQixDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLDJCQUEyQixHQUFHO29CQUM1QixxQkFBcUIsRUFBRSxJQUFJLEdBQUcsRUFBVTtvQkFDeEMsV0FBVyxFQUFFLFNBQVM7aUJBQ3ZCLENBQUM7YUFDSDtZQUNELDJCQUEyQixDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMxRSwyQkFBMkIsQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUVELFNBQVMsU0FBUztZQUNoQixJQUFJLENBQUMsaUJBQWlCLENBQ2xCLENBQUMsOEJBQXVCLENBQUMseURBQXlELENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUYsYUFBYSxDQUFDLDJCQUE2QixDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDbkUsMkJBQTJCLEdBQUcsU0FBUyxDQUFDO1FBQzFDLENBQUM7SUFDSCxDQUFDO0lBbkxELDBEQW1MQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIHRzIGZyb20gJ3R5cGVzY3JpcHQnO1xuXG5pbXBvcnQge0RpYWdub3N0aWNzLCBQYXJzZWRDb25maWd1cmF0aW9uLCBQZXJmb3JtQ29tcGlsYXRpb25SZXN1bHQsIGV4aXRDb2RlRnJvbVJlc3VsdCwgcGVyZm9ybUNvbXBpbGF0aW9uLCByZWFkQ29uZmlndXJhdGlvbn0gZnJvbSAnLi9wZXJmb3JtX2NvbXBpbGUnO1xuaW1wb3J0ICogYXMgYXBpIGZyb20gJy4vdHJhbnNmb3JtZXJzL2FwaSc7XG5pbXBvcnQge2NyZWF0ZUNvbXBpbGVySG9zdH0gZnJvbSAnLi90cmFuc2Zvcm1lcnMvZW50cnlfcG9pbnRzJztcbmltcG9ydCB7Y3JlYXRlTWVzc2FnZURpYWdub3N0aWN9IGZyb20gJy4vdHJhbnNmb3JtZXJzL3V0aWwnO1xuXG5mdW5jdGlvbiB0b3RhbENvbXBpbGF0aW9uVGltZURpYWdub3N0aWModGltZUluTWlsbGlzOiBudW1iZXIpOiBhcGkuRGlhZ25vc3RpYyB7XG4gIGxldCBkdXJhdGlvbjogc3RyaW5nO1xuICBpZiAodGltZUluTWlsbGlzID4gMTAwMCkge1xuICAgIGR1cmF0aW9uID0gYCR7KHRpbWVJbk1pbGxpcyAvIDEwMDApLnRvUHJlY2lzaW9uKDIpfXNgO1xuICB9IGVsc2Uge1xuICAgIGR1cmF0aW9uID0gYCR7dGltZUluTWlsbGlzfW1zYDtcbiAgfVxuICByZXR1cm4ge1xuICAgIGNhdGVnb3J5OiB0cy5EaWFnbm9zdGljQ2F0ZWdvcnkuTWVzc2FnZSxcbiAgICBtZXNzYWdlVGV4dDogYFRvdGFsIHRpbWU6ICR7ZHVyYXRpb259YCxcbiAgICBjb2RlOiBhcGkuREVGQVVMVF9FUlJPUl9DT0RFLFxuICAgIHNvdXJjZTogYXBpLlNPVVJDRSxcbiAgfTtcbn1cblxuZXhwb3J0IGVudW0gRmlsZUNoYW5nZUV2ZW50IHtcbiAgQ2hhbmdlLFxuICBDcmVhdGVEZWxldGUsXG4gIENyZWF0ZURlbGV0ZURpcixcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZXJmb3JtV2F0Y2hIb3N0IHtcbiAgcmVwb3J0RGlhZ25vc3RpY3MoZGlhZ25vc3RpY3M6IERpYWdub3N0aWNzKTogdm9pZDtcbiAgcmVhZENvbmZpZ3VyYXRpb24oKTogUGFyc2VkQ29uZmlndXJhdGlvbjtcbiAgY3JlYXRlQ29tcGlsZXJIb3N0KG9wdGlvbnM6IGFwaS5Db21waWxlck9wdGlvbnMpOiBhcGkuQ29tcGlsZXJIb3N0O1xuICBjcmVhdGVFbWl0Q2FsbGJhY2sob3B0aW9uczogYXBpLkNvbXBpbGVyT3B0aW9ucyk6IGFwaS5Uc0VtaXRDYWxsYmFja3x1bmRlZmluZWQ7XG4gIG9uRmlsZUNoYW5nZShcbiAgICAgIG9wdGlvbnM6IGFwaS5Db21waWxlck9wdGlvbnMsIGxpc3RlbmVyOiAoZXZlbnQ6IEZpbGVDaGFuZ2VFdmVudCwgZmlsZU5hbWU6IHN0cmluZykgPT4gdm9pZCxcbiAgICAgIHJlYWR5OiAoKSA9PiB2b2lkKToge2Nsb3NlOiAoKSA9PiB2b2lkfTtcbiAgc2V0VGltZW91dChjYWxsYmFjazogKCkgPT4gdm9pZCwgbXM6IG51bWJlcik6IGFueTtcbiAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZDogYW55KTogdm9pZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBlcmZvcm1XYXRjaEhvc3QoXG4gICAgY29uZmlnRmlsZU5hbWU6IHN0cmluZywgcmVwb3J0RGlhZ25vc3RpY3M6IChkaWFnbm9zdGljczogRGlhZ25vc3RpY3MpID0+IHZvaWQsXG4gICAgZXhpc3RpbmdPcHRpb25zPzogdHMuQ29tcGlsZXJPcHRpb25zLCBjcmVhdGVFbWl0Q2FsbGJhY2s/OiAob3B0aW9uczogYXBpLkNvbXBpbGVyT3B0aW9ucykgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcGkuVHNFbWl0Q2FsbGJhY2sgfCB1bmRlZmluZWQpOiBQZXJmb3JtV2F0Y2hIb3N0IHtcbiAgcmV0dXJuIHtcbiAgICByZXBvcnREaWFnbm9zdGljczogcmVwb3J0RGlhZ25vc3RpY3MsXG4gICAgY3JlYXRlQ29tcGlsZXJIb3N0OiBvcHRpb25zID0+IGNyZWF0ZUNvbXBpbGVySG9zdCh7b3B0aW9uc30pLFxuICAgIHJlYWRDb25maWd1cmF0aW9uOiAoKSA9PiByZWFkQ29uZmlndXJhdGlvbihjb25maWdGaWxlTmFtZSwgZXhpc3RpbmdPcHRpb25zKSxcbiAgICBjcmVhdGVFbWl0Q2FsbGJhY2s6IG9wdGlvbnMgPT4gY3JlYXRlRW1pdENhbGxiYWNrID8gY3JlYXRlRW1pdENhbGxiYWNrKG9wdGlvbnMpIDogdW5kZWZpbmVkLFxuICAgIG9uRmlsZUNoYW5nZTogKG9wdGlvbnMsIGxpc3RlbmVyLCByZWFkeTogKCkgPT4gdm9pZCkgPT4ge1xuICAgICAgaWYgKCFvcHRpb25zLmJhc2VQYXRoKSB7XG4gICAgICAgIHJlcG9ydERpYWdub3N0aWNzKFt7XG4gICAgICAgICAgY2F0ZWdvcnk6IHRzLkRpYWdub3N0aWNDYXRlZ29yeS5FcnJvcixcbiAgICAgICAgICBtZXNzYWdlVGV4dDogJ0ludmFsaWQgY29uZmlndXJhdGlvbiBvcHRpb24uIGJhc2VEaXIgbm90IHNwZWNpZmllZCcsXG4gICAgICAgICAgc291cmNlOiBhcGkuU09VUkNFLFxuICAgICAgICAgIGNvZGU6IGFwaS5ERUZBVUxUX0VSUk9SX0NPREVcbiAgICAgICAgfV0pO1xuICAgICAgICByZXR1cm4ge2Nsb3NlOiAoKSA9PiB7fX07XG4gICAgICB9XG4gICAgICBjb25zdCB3YXRjaGVyID0gY2hva2lkYXIud2F0Y2gob3B0aW9ucy5iYXNlUGF0aCwge1xuICAgICAgICAvLyBpZ25vcmUgLmRvdGZpbGVzLCAuanMgYW5kIC5tYXAgZmlsZXMuXG4gICAgICAgIC8vIGNhbid0IGlnbm9yZSBvdGhlciBmaWxlcyBhcyB3ZSBlLmcuIHdhbnQgdG8gcmVjb21waWxlIGlmIGFuIGAuaHRtbGAgZmlsZSBjaGFuZ2VzIGFzIHdlbGwuXG4gICAgICAgIGlnbm9yZWQ6IC8oKF5bXFwvXFxcXF0pXFwuLil8KFxcLmpzJCl8KFxcLm1hcCQpfChcXC5tZXRhZGF0YVxcLmpzb258bm9kZV9tb2R1bGVzKS8sXG4gICAgICAgIGlnbm9yZUluaXRpYWw6IHRydWUsXG4gICAgICAgIHBlcnNpc3RlbnQ6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHdhdGNoZXIub24oJ2FsbCcsIChldmVudDogc3RyaW5nLCBwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgc3dpdGNoIChldmVudCkge1xuICAgICAgICAgIGNhc2UgJ2NoYW5nZSc6XG4gICAgICAgICAgICBsaXN0ZW5lcihGaWxlQ2hhbmdlRXZlbnQuQ2hhbmdlLCBwYXRoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3VubGluayc6XG4gICAgICAgICAgY2FzZSAnYWRkJzpcbiAgICAgICAgICAgIGxpc3RlbmVyKEZpbGVDaGFuZ2VFdmVudC5DcmVhdGVEZWxldGUsIHBhdGgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndW5saW5rRGlyJzpcbiAgICAgICAgICBjYXNlICdhZGREaXInOlxuICAgICAgICAgICAgbGlzdGVuZXIoRmlsZUNoYW5nZUV2ZW50LkNyZWF0ZURlbGV0ZURpciwgcGF0aCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB3YXRjaGVyLm9uKCdyZWFkeScsIHJlYWR5KTtcbiAgICAgIHJldHVybiB7Y2xvc2U6ICgpID0+IHdhdGNoZXIuY2xvc2UoKSwgcmVhZHl9O1xuICAgIH0sXG4gICAgc2V0VGltZW91dDogKHRzLnN5cy5jbGVhclRpbWVvdXQgJiYgdHMuc3lzLnNldFRpbWVvdXQpIHx8IHNldFRpbWVvdXQsXG4gICAgY2xlYXJUaW1lb3V0OiAodHMuc3lzLnNldFRpbWVvdXQgJiYgdHMuc3lzLmNsZWFyVGltZW91dCkgfHwgY2xlYXJUaW1lb3V0LFxuICB9O1xufVxuXG5pbnRlcmZhY2UgQ2FjaGVFbnRyeSB7XG4gIGV4aXN0cz86IGJvb2xlYW47XG4gIHNmPzogdHMuU291cmNlRmlsZTtcbiAgY29udGVudD86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFF1ZXVlZENvbXBpbGF0aW9uSW5mbyB7XG4gIHRpbWVySGFuZGxlOiBhbnk7XG4gIG1vZGlmaWVkUmVzb3VyY2VGaWxlczogU2V0PHN0cmluZz47XG59XG5cbi8qKlxuICogVGhlIGxvZ2ljIGluIHRoaXMgZnVuY3Rpb24gaXMgYWRhcHRlZCBmcm9tIGB0c2MudHNgIGZyb20gVHlwZVNjcmlwdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBlcmZvcm1XYXRjaENvbXBpbGF0aW9uKGhvc3Q6IFBlcmZvcm1XYXRjaEhvc3QpOlxuICAgIHtjbG9zZTogKCkgPT4gdm9pZCwgcmVhZHk6IChjYjogKCkgPT4gdm9pZCkgPT4gdm9pZCwgZmlyc3RDb21waWxlUmVzdWx0OiBEaWFnbm9zdGljc30ge1xuICBsZXQgY2FjaGVkUHJvZ3JhbTogYXBpLlByb2dyYW18dW5kZWZpbmVkOyAgICAgICAgICAgIC8vIFByb2dyYW0gY2FjaGVkIGZyb20gbGFzdCBjb21waWxhdGlvblxuICBsZXQgY2FjaGVkQ29tcGlsZXJIb3N0OiBhcGkuQ29tcGlsZXJIb3N0fHVuZGVmaW5lZDsgIC8vIENvbXBpbGVySG9zdCBjYWNoZWQgZnJvbSBsYXN0IGNvbXBpbGF0aW9uXG4gIGxldCBjYWNoZWRPcHRpb25zOiBQYXJzZWRDb25maWd1cmF0aW9ufHVuZGVmaW5lZDsgIC8vIENvbXBpbGVyT3B0aW9ucyBjYWNoZWQgZnJvbSBsYXN0IGNvbXBpbGF0aW9uXG4gIGxldCB0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb246IFF1ZXVlZENvbXBpbGF0aW9uSW5mb3xcbiAgICAgIHVuZGVmaW5lZDsgIC8vIEhhbmRsZSBmb3IgMC4yNXMgd2FpdCB0aW1lciB0byB0cmlnZ2VyIHJlY29tcGlsYXRpb25cblxuICBjb25zdCBpZ25vcmVGaWxlc0ZvcldhdGNoID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IGZpbGVDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBDYWNoZUVudHJ5PigpO1xuXG4gIGNvbnN0IGZpcnN0Q29tcGlsZVJlc3VsdCA9IGRvQ29tcGlsYXRpb24oKTtcblxuICAvLyBXYXRjaCBiYXNlUGF0aCwgaWdub3JpbmcgLmRvdGZpbGVzXG4gIGxldCByZXNvbHZlUmVhZHlQcm9taXNlOiAoKSA9PiB2b2lkO1xuICBjb25zdCByZWFkeVByb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHJlc29sdmVSZWFkeVByb21pc2UgPSByZXNvbHZlKTtcbiAgLy8gTm90ZTogISBpcyBvayBhcyBvcHRpb25zIGFyZSBmaWxsZWQgYWZ0ZXIgdGhlIGZpcnN0IGNvbXBpbGF0aW9uXG4gIC8vIE5vdGU6ICEgaXMgb2sgYXMgcmVzb2x2ZWRSZWFkeVByb21pc2UgaXMgZmlsbGVkIGJ5IHRoZSBwcmV2aW91cyBjYWxsXG4gIGNvbnN0IGZpbGVXYXRjaGVyID1cbiAgICAgIGhvc3Qub25GaWxlQ2hhbmdlKGNhY2hlZE9wdGlvbnMgIS5vcHRpb25zLCB3YXRjaGVkRmlsZUNoYW5nZWQsIHJlc29sdmVSZWFkeVByb21pc2UgISk7XG5cbiAgcmV0dXJuIHtjbG9zZSwgcmVhZHk6IGNiID0+IHJlYWR5UHJvbWlzZS50aGVuKGNiKSwgZmlyc3RDb21waWxlUmVzdWx0fTtcblxuICBmdW5jdGlvbiBjYWNoZUVudHJ5KGZpbGVOYW1lOiBzdHJpbmcpOiBDYWNoZUVudHJ5IHtcbiAgICBmaWxlTmFtZSA9IHBhdGgubm9ybWFsaXplKGZpbGVOYW1lKTtcbiAgICBsZXQgZW50cnkgPSBmaWxlQ2FjaGUuZ2V0KGZpbGVOYW1lKTtcbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICBlbnRyeSA9IHt9O1xuICAgICAgZmlsZUNhY2hlLnNldChmaWxlTmFtZSwgZW50cnkpO1xuICAgIH1cbiAgICByZXR1cm4gZW50cnk7XG4gIH1cblxuICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICBmaWxlV2F0Y2hlci5jbG9zZSgpO1xuICAgIGlmICh0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24pIHtcbiAgICAgIGhvc3QuY2xlYXJUaW1lb3V0KHRpbWVySGFuZGxlRm9yUmVjb21waWxhdGlvbi50aW1lckhhbmRsZSk7XG4gICAgICB0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLy8gSW52b2tlZCB0byBwZXJmb3JtIGluaXRpYWwgY29tcGlsYXRpb24gb3IgcmUtY29tcGlsYXRpb24gaW4gd2F0Y2ggbW9kZVxuICBmdW5jdGlvbiBkb0NvbXBpbGF0aW9uKG1vZGlmaWVkUmVzb3VyY2VGaWxlcz86IFNldDxzdHJpbmc+KTogRGlhZ25vc3RpY3Mge1xuICAgIGlmICghY2FjaGVkT3B0aW9ucykge1xuICAgICAgY2FjaGVkT3B0aW9ucyA9IGhvc3QucmVhZENvbmZpZ3VyYXRpb24oKTtcbiAgICB9XG4gICAgaWYgKGNhY2hlZE9wdGlvbnMuZXJyb3JzICYmIGNhY2hlZE9wdGlvbnMuZXJyb3JzLmxlbmd0aCkge1xuICAgICAgaG9zdC5yZXBvcnREaWFnbm9zdGljcyhjYWNoZWRPcHRpb25zLmVycm9ycyk7XG4gICAgICByZXR1cm4gY2FjaGVkT3B0aW9ucy5lcnJvcnM7XG4gICAgfVxuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgaWYgKCFjYWNoZWRDb21waWxlckhvc3QpIHtcbiAgICAgIGNhY2hlZENvbXBpbGVySG9zdCA9IGhvc3QuY3JlYXRlQ29tcGlsZXJIb3N0KGNhY2hlZE9wdGlvbnMub3B0aW9ucyk7XG4gICAgICBjb25zdCBvcmlnaW5hbFdyaXRlRmlsZUNhbGxiYWNrID0gY2FjaGVkQ29tcGlsZXJIb3N0LndyaXRlRmlsZTtcbiAgICAgIGNhY2hlZENvbXBpbGVySG9zdC53cml0ZUZpbGUgPSBmdW5jdGlvbihcbiAgICAgICAgICBmaWxlTmFtZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIHdyaXRlQnl0ZU9yZGVyTWFyazogYm9vbGVhbixcbiAgICAgICAgICBvbkVycm9yPzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCwgc291cmNlRmlsZXM6IFJlYWRvbmx5QXJyYXk8dHMuU291cmNlRmlsZT4gPSBbXSkge1xuICAgICAgICBpZ25vcmVGaWxlc0ZvcldhdGNoLmFkZChwYXRoLm5vcm1hbGl6ZShmaWxlTmFtZSkpO1xuICAgICAgICByZXR1cm4gb3JpZ2luYWxXcml0ZUZpbGVDYWxsYmFjayhmaWxlTmFtZSwgZGF0YSwgd3JpdGVCeXRlT3JkZXJNYXJrLCBvbkVycm9yLCBzb3VyY2VGaWxlcyk7XG4gICAgICB9O1xuICAgICAgY29uc3Qgb3JpZ2luYWxGaWxlRXhpc3RzID0gY2FjaGVkQ29tcGlsZXJIb3N0LmZpbGVFeGlzdHM7XG4gICAgICBjYWNoZWRDb21waWxlckhvc3QuZmlsZUV4aXN0cyA9IGZ1bmN0aW9uKGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgY2UgPSBjYWNoZUVudHJ5KGZpbGVOYW1lKTtcbiAgICAgICAgaWYgKGNlLmV4aXN0cyA9PSBudWxsKSB7XG4gICAgICAgICAgY2UuZXhpc3RzID0gb3JpZ2luYWxGaWxlRXhpc3RzLmNhbGwodGhpcywgZmlsZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjZS5leGlzdHMgITtcbiAgICAgIH07XG4gICAgICBjb25zdCBvcmlnaW5hbEdldFNvdXJjZUZpbGUgPSBjYWNoZWRDb21waWxlckhvc3QuZ2V0U291cmNlRmlsZTtcbiAgICAgIGNhY2hlZENvbXBpbGVySG9zdC5nZXRTb3VyY2VGaWxlID0gZnVuY3Rpb24oXG4gICAgICAgICAgZmlsZU5hbWU6IHN0cmluZywgbGFuZ3VhZ2VWZXJzaW9uOiB0cy5TY3JpcHRUYXJnZXQpIHtcbiAgICAgICAgY29uc3QgY2UgPSBjYWNoZUVudHJ5KGZpbGVOYW1lKTtcbiAgICAgICAgaWYgKCFjZS5zZikge1xuICAgICAgICAgIGNlLnNmID0gb3JpZ2luYWxHZXRTb3VyY2VGaWxlLmNhbGwodGhpcywgZmlsZU5hbWUsIGxhbmd1YWdlVmVyc2lvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNlLnNmICE7XG4gICAgICB9O1xuICAgICAgY29uc3Qgb3JpZ2luYWxSZWFkRmlsZSA9IGNhY2hlZENvbXBpbGVySG9zdC5yZWFkRmlsZTtcbiAgICAgIGNhY2hlZENvbXBpbGVySG9zdC5yZWFkRmlsZSA9IGZ1bmN0aW9uKGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgY2UgPSBjYWNoZUVudHJ5KGZpbGVOYW1lKTtcbiAgICAgICAgaWYgKGNlLmNvbnRlbnQgPT0gbnVsbCkge1xuICAgICAgICAgIGNlLmNvbnRlbnQgPSBvcmlnaW5hbFJlYWRGaWxlLmNhbGwodGhpcywgZmlsZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjZS5jb250ZW50ICE7XG4gICAgICB9O1xuICAgICAgLy8gUHJvdmlkZSBhY2Nlc3MgdG8gdGhlIGZpbGUgcGF0aHMgdGhhdCB0cmlnZ2VyZWQgdGhpcyByZWJ1aWxkXG4gICAgICBjYWNoZWRDb21waWxlckhvc3QuZ2V0TW9kaWZpZWRSZXNvdXJjZUZpbGVzID1cbiAgICAgICAgICBtb2RpZmllZFJlc291cmNlRmlsZXMgIT09IHVuZGVmaW5lZCA/ICgpID0+IG1vZGlmaWVkUmVzb3VyY2VGaWxlcyA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaWdub3JlRmlsZXNGb3JXYXRjaC5jbGVhcigpO1xuICAgIGNvbnN0IG9sZFByb2dyYW0gPSBjYWNoZWRQcm9ncmFtO1xuICAgIC8vIFdlIGNsZWFyIG91dCB0aGUgYGNhY2hlZFByb2dyYW1gIGhlcmUgYXMgYVxuICAgIC8vIHByb2dyYW0gY2FuIG9ubHkgYmUgdXNlZCBhcyBgb2xkUHJvZ3JhbWAgMXhcbiAgICBjYWNoZWRQcm9ncmFtID0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGNvbXBpbGVSZXN1bHQgPSBwZXJmb3JtQ29tcGlsYXRpb24oe1xuICAgICAgcm9vdE5hbWVzOiBjYWNoZWRPcHRpb25zLnJvb3ROYW1lcyxcbiAgICAgIG9wdGlvbnM6IGNhY2hlZE9wdGlvbnMub3B0aW9ucyxcbiAgICAgIGhvc3Q6IGNhY2hlZENvbXBpbGVySG9zdCxcbiAgICAgIG9sZFByb2dyYW06IG9sZFByb2dyYW0sXG4gICAgICBlbWl0Q2FsbGJhY2s6IGhvc3QuY3JlYXRlRW1pdENhbGxiYWNrKGNhY2hlZE9wdGlvbnMub3B0aW9ucylcbiAgICB9KTtcblxuICAgIGlmIChjb21waWxlUmVzdWx0LmRpYWdub3N0aWNzLmxlbmd0aCkge1xuICAgICAgaG9zdC5yZXBvcnREaWFnbm9zdGljcyhjb21waWxlUmVzdWx0LmRpYWdub3N0aWNzKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBpZiAoY2FjaGVkT3B0aW9ucy5vcHRpb25zLmRpYWdub3N0aWNzKSB7XG4gICAgICBjb25zdCB0b3RhbFRpbWUgPSAoZW5kVGltZSAtIHN0YXJ0VGltZSkgLyAxMDAwO1xuICAgICAgaG9zdC5yZXBvcnREaWFnbm9zdGljcyhbdG90YWxDb21waWxhdGlvblRpbWVEaWFnbm9zdGljKGVuZFRpbWUgLSBzdGFydFRpbWUpXSk7XG4gICAgfVxuICAgIGNvbnN0IGV4aXRDb2RlID0gZXhpdENvZGVGcm9tUmVzdWx0KGNvbXBpbGVSZXN1bHQuZGlhZ25vc3RpY3MpO1xuICAgIGlmIChleGl0Q29kZSA9PSAwKSB7XG4gICAgICBjYWNoZWRQcm9ncmFtID0gY29tcGlsZVJlc3VsdC5wcm9ncmFtO1xuICAgICAgaG9zdC5yZXBvcnREaWFnbm9zdGljcyhcbiAgICAgICAgICBbY3JlYXRlTWVzc2FnZURpYWdub3N0aWMoJ0NvbXBpbGF0aW9uIGNvbXBsZXRlLiBXYXRjaGluZyBmb3IgZmlsZSBjaGFuZ2VzLicpXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhvc3QucmVwb3J0RGlhZ25vc3RpY3MoXG4gICAgICAgICAgW2NyZWF0ZU1lc3NhZ2VEaWFnbm9zdGljKCdDb21waWxhdGlvbiBmYWlsZWQuIFdhdGNoaW5nIGZvciBmaWxlIGNoYW5nZXMuJyldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tcGlsZVJlc3VsdC5kaWFnbm9zdGljcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0T3B0aW9ucygpIHtcbiAgICBjYWNoZWRQcm9ncmFtID0gdW5kZWZpbmVkO1xuICAgIGNhY2hlZENvbXBpbGVySG9zdCA9IHVuZGVmaW5lZDtcbiAgICBjYWNoZWRPcHRpb25zID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZnVuY3Rpb24gd2F0Y2hlZEZpbGVDaGFuZ2VkKGV2ZW50OiBGaWxlQ2hhbmdlRXZlbnQsIGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAoY2FjaGVkT3B0aW9ucyAmJiBldmVudCA9PT0gRmlsZUNoYW5nZUV2ZW50LkNoYW5nZSAmJlxuICAgICAgICAvLyBUT0RPKGNodWNraik6IHZhbGlkYXRlIHRoYXQgdGhpcyBpcyBzdWZmaWNpZW50IHRvIHNraXAgZmlsZXMgdGhhdCB3ZXJlIHdyaXR0ZW4uXG4gICAgICAgIC8vIFRoaXMgYXNzdW1lcyB0aGF0IHRoZSBmaWxlIHBhdGggd2Ugd3JpdGUgaXMgdGhlIHNhbWUgZmlsZSBwYXRoIHdlIHdpbGwgcmVjZWl2ZSBpbiB0aGVcbiAgICAgICAgLy8gY2hhbmdlIG5vdGlmaWNhdGlvbi5cbiAgICAgICAgcGF0aC5ub3JtYWxpemUoZmlsZU5hbWUpID09PSBwYXRoLm5vcm1hbGl6ZShjYWNoZWRPcHRpb25zLnByb2plY3QpKSB7XG4gICAgICAvLyBJZiB0aGUgY29uZmlndXJhdGlvbiBmaWxlIGNoYW5nZXMsIGZvcmdldCBldmVyeXRoaW5nIGFuZCBzdGFydCB0aGUgcmVjb21waWxhdGlvbiB0aW1lclxuICAgICAgcmVzZXRPcHRpb25zKCk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXZlbnQgPT09IEZpbGVDaGFuZ2VFdmVudC5DcmVhdGVEZWxldGUgfHwgZXZlbnQgPT09IEZpbGVDaGFuZ2VFdmVudC5DcmVhdGVEZWxldGVEaXIpIHtcbiAgICAgIC8vIElmIGEgZmlsZSB3YXMgYWRkZWQgb3IgcmVtb3ZlZCwgcmVyZWFkIHRoZSBjb25maWd1cmF0aW9uXG4gICAgICAvLyB0byBkZXRlcm1pbmUgdGhlIG5ldyBsaXN0IG9mIHJvb3QgZmlsZXMuXG4gICAgICBjYWNoZWRPcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChldmVudCA9PT0gRmlsZUNoYW5nZUV2ZW50LkNyZWF0ZURlbGV0ZURpcikge1xuICAgICAgZmlsZUNhY2hlLmNsZWFyKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZpbGVDYWNoZS5kZWxldGUocGF0aC5ub3JtYWxpemUoZmlsZU5hbWUpKTtcbiAgICB9XG5cbiAgICBpZiAoIWlnbm9yZUZpbGVzRm9yV2F0Y2guaGFzKHBhdGgubm9ybWFsaXplKGZpbGVOYW1lKSkpIHtcbiAgICAgIC8vIElnbm9yZSB0aGUgZmlsZSBpZiB0aGUgZmlsZSBpcyBvbmUgdGhhdCB3YXMgd3JpdHRlbiBieSB0aGUgY29tcGlsZXIuXG4gICAgICBzdGFydFRpbWVyRm9yUmVjb21waWxhdGlvbihmaWxlTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gVXBvbiBkZXRlY3RpbmcgYSBmaWxlIGNoYW5nZSwgd2FpdCBmb3IgMjUwbXMgYW5kIHRoZW4gcGVyZm9ybSBhIHJlY29tcGlsYXRpb24uIFRoaXMgZ2l2ZXMgYmF0Y2hcbiAgLy8gb3BlcmF0aW9ucyAoc3VjaCBhcyBzYXZpbmcgYWxsIG1vZGlmaWVkIGZpbGVzIGluIGFuIGVkaXRvcikgYSBjaGFuY2UgdG8gY29tcGxldGUgYmVmb3JlIHdlIGtpY2tcbiAgLy8gb2ZmIGEgbmV3IGNvbXBpbGF0aW9uLlxuICBmdW5jdGlvbiBzdGFydFRpbWVyRm9yUmVjb21waWxhdGlvbihjaGFuZ2VkUGF0aDogc3RyaW5nKSB7XG4gICAgaWYgKHRpbWVySGFuZGxlRm9yUmVjb21waWxhdGlvbikge1xuICAgICAgaG9zdC5jbGVhclRpbWVvdXQodGltZXJIYW5kbGVGb3JSZWNvbXBpbGF0aW9uLnRpbWVySGFuZGxlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGltZXJIYW5kbGVGb3JSZWNvbXBpbGF0aW9uID0ge1xuICAgICAgICBtb2RpZmllZFJlc291cmNlRmlsZXM6IG5ldyBTZXQ8c3RyaW5nPigpLFxuICAgICAgICB0aW1lckhhbmRsZTogdW5kZWZpbmVkXG4gICAgICB9O1xuICAgIH1cbiAgICB0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24udGltZXJIYW5kbGUgPSBob3N0LnNldFRpbWVvdXQocmVjb21waWxlLCAyNTApO1xuICAgIHRpbWVySGFuZGxlRm9yUmVjb21waWxhdGlvbi5tb2RpZmllZFJlc291cmNlRmlsZXMuYWRkKGNoYW5nZWRQYXRoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29tcGlsZSgpIHtcbiAgICBob3N0LnJlcG9ydERpYWdub3N0aWNzKFxuICAgICAgICBbY3JlYXRlTWVzc2FnZURpYWdub3N0aWMoJ0ZpbGUgY2hhbmdlIGRldGVjdGVkLiBTdGFydGluZyBpbmNyZW1lbnRhbCBjb21waWxhdGlvbi4nKV0pO1xuICAgIGRvQ29tcGlsYXRpb24odGltZXJIYW5kbGVGb3JSZWNvbXBpbGF0aW9uICEubW9kaWZpZWRSZXNvdXJjZUZpbGVzKTtcbiAgICB0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24gPSB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ== |
\ | No newline at end of file |