1 | ;
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | var __importStar = (this && this.__importStar) || function (mod) {
|
6 | if (mod && mod.__esModule) return mod;
|
7 | var result = {};
|
8 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
9 | result["default"] = mod;
|
10 | return result;
|
11 | };
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | const lodash_1 = require("lodash");
|
14 | const read_file_relative_1 = require("read-file-relative");
|
15 | const promisify_event_1 = __importDefault(require("promisify-event"));
|
16 | const mustache_1 = __importDefault(require("mustache"));
|
17 | const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
|
18 | const debug_log_1 = __importDefault(require("./debug-log"));
|
19 | const formattable_adapter_1 = __importDefault(require("../errors/test-run/formattable-adapter"));
|
20 | const error_list_1 = __importDefault(require("../errors/error-list"));
|
21 | const test_run_1 = require("../errors/test-run/");
|
22 | const phase_1 = __importDefault(require("./phase"));
|
23 | const client_messages_1 = __importDefault(require("./client-messages"));
|
24 | const type_1 = __importDefault(require("./commands/type"));
|
25 | const delay_1 = __importDefault(require("../utils/delay"));
|
26 | const marker_symbol_1 = __importDefault(require("./marker-symbol"));
|
27 | const test_run_tracker_1 = __importDefault(require("../api/test-run-tracker"));
|
28 | const phase_2 = __importDefault(require("../role/phase"));
|
29 | const plugin_host_1 = __importDefault(require("../reporter/plugin-host"));
|
30 | const browser_console_messages_1 = __importDefault(require("./browser-console-messages"));
|
31 | const unstable_network_mode_1 = require("../browser/connection/unstable-network-mode");
|
32 | const warning_log_1 = __importDefault(require("../notifications/warning-log"));
|
33 | const warning_message_1 = __importDefault(require("../notifications/warning-message"));
|
34 | const testcafe_hammerhead_1 = require("testcafe-hammerhead");
|
35 | const actions_1 = require("./commands/actions");
|
36 | const INJECTABLES = __importStar(require("../assets/injectables"));
|
37 | const utils_1 = require("../custom-client-scripts/utils");
|
38 | const get_url_1 = __importDefault(require("../custom-client-scripts/get-url"));
|
39 | const string_1 = require("../utils/string");
|
40 | const utils_2 = require("./commands/utils");
|
41 | const types_1 = require("../errors/types");
|
42 | const lazyRequire = require('import-lazy')(require);
|
43 | const SessionController = lazyRequire('./session-controller');
|
44 | const ClientFunctionBuilder = lazyRequire('../client-functions/client-function-builder');
|
45 | const BrowserManipulationQueue = lazyRequire('./browser-manipulation-queue');
|
46 | const TestRunBookmark = lazyRequire('./bookmark');
|
47 | const AssertionExecutor = lazyRequire('../assertions/executor');
|
48 | const actionCommands = lazyRequire('./commands/actions');
|
49 | const browserManipulationCommands = lazyRequire('./commands/browser-manipulation');
|
50 | const serviceCommands = lazyRequire('./commands/service');
|
51 | const { executeJsExpression, executeAsyncJsExpression } = lazyRequire('./execute-js-expression');
|
52 | const TEST_RUN_TEMPLATE = read_file_relative_1.readSync('../client/test-run/index.js.mustache');
|
53 | const IFRAME_TEST_RUN_TEMPLATE = read_file_relative_1.readSync('../client/test-run/iframe.js.mustache');
|
54 | const TEST_DONE_CONFIRMATION_RESPONSE = 'test-done-confirmation';
|
55 | const MAX_RESPONSE_DELAY = 3000;
|
56 | const CHILD_WINDOW_READY_TIMEOUT = 30 * 1000;
|
57 | const ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT = 'all-driver-tasks-added-to-queue';
|
58 | class TestRun extends async_event_emitter_1.default {
|
59 | constructor(test, browserConnection, screenshotCapturer, globalWarningLog, opts) {
|
60 | super();
|
61 | this[marker_symbol_1.default] = true;
|
62 | this.warningLog = new warning_log_1.default(globalWarningLog);
|
63 | this.opts = opts;
|
64 | this.test = test;
|
65 | this.browserConnection = browserConnection;
|
66 | this.phase = phase_1.default.initial;
|
67 | this.driverTaskQueue = [];
|
68 | this.testDoneCommandQueued = false;
|
69 | this.activeDialogHandler = null;
|
70 | this.activeIframeSelector = null;
|
71 | this.speed = this.opts.speed;
|
72 | this.pageLoadTimeout = this.opts.pageLoadTimeout;
|
73 | this.disablePageReloads = test.disablePageReloads || opts.disablePageReloads && test.disablePageReloads !==
|
74 | false;
|
75 | this.disablePageCaching = test.disablePageCaching || opts.disablePageCaching;
|
76 | this.allowMultipleWindows = opts.allowMultipleWindows;
|
77 | this.session = SessionController.getSession(this);
|
78 | this.consoleMessages = new browser_console_messages_1.default();
|
79 | this.pendingRequest = null;
|
80 | this.pendingPageError = null;
|
81 | this.controller = null;
|
82 | this.ctx = Object.create(null);
|
83 | this.fixtureCtx = null;
|
84 | this.currentRoleId = null;
|
85 | this.usedRoleStates = Object.create(null);
|
86 | this.errs = [];
|
87 | this.lastDriverStatusId = null;
|
88 | this.lastDriverStatusResponse = null;
|
89 | this.fileDownloadingHandled = false;
|
90 | this.resolveWaitForFileDownloadingPromise = null;
|
91 | this.addingDriverTasksCount = 0;
|
92 | this.debugging = this.opts.debugMode;
|
93 | this.debugOnFail = this.opts.debugOnFail;
|
94 | this.disableDebugBreakpoints = false;
|
95 | this.debugReporterPluginHost = new plugin_host_1.default({ noColors: false });
|
96 | this.browserManipulationQueue = new BrowserManipulationQueue(browserConnection, screenshotCapturer, this.warningLog);
|
97 | this.debugLog = new debug_log_1.default(this.browserConnection.userAgent);
|
98 | this.quarantine = null;
|
99 | this.debugLogger = this.opts.debugLogger;
|
100 | this._addInjectables();
|
101 | this._initRequestHooks();
|
102 | }
|
103 | _addClientScriptContentWarningsIfNecessary() {
|
104 | const { empty, duplicatedContent } = utils_1.findProblematicScripts(this.test.clientScripts);
|
105 | if (empty.length)
|
106 | this.warningLog.addWarning(warning_message_1.default.clientScriptsWithEmptyContent);
|
107 | if (duplicatedContent.length) {
|
108 | const suffix = string_1.getPluralSuffix(duplicatedContent);
|
109 | const duplicatedContentClientScriptsStr = string_1.getConcatenatedValuesString(duplicatedContent, ',\n ');
|
110 | this.warningLog.addWarning(warning_message_1.default.clientScriptsWithDuplicatedContent, suffix, duplicatedContentClientScriptsStr);
|
111 | }
|
112 | }
|
113 | _addInjectables() {
|
114 | this._addClientScriptContentWarningsIfNecessary();
|
115 | this.injectable.scripts.push(...INJECTABLES.SCRIPTS);
|
116 | this.injectable.userScripts.push(...this.test.clientScripts.map(script => {
|
117 | return {
|
118 | url: get_url_1.default(script),
|
119 | page: script.page
|
120 | };
|
121 | }));
|
122 | this.injectable.styles.push(INJECTABLES.TESTCAFE_UI_STYLES);
|
123 | }
|
124 | get id() {
|
125 | return this.session.id;
|
126 | }
|
127 | get injectable() {
|
128 | return this.session.injectable;
|
129 | }
|
130 | addQuarantineInfo(quarantine) {
|
131 | this.quarantine = quarantine;
|
132 | }
|
133 | addRequestHook(hook) {
|
134 | if (this.requestHooks.indexOf(hook) !== -1)
|
135 | return;
|
136 | this.requestHooks.push(hook);
|
137 | this._initRequestHook(hook);
|
138 | }
|
139 | removeRequestHook(hook) {
|
140 | if (this.requestHooks.indexOf(hook) === -1)
|
141 | return;
|
142 | lodash_1.pull(this.requestHooks, hook);
|
143 | this._disposeRequestHook(hook);
|
144 | }
|
145 | _initRequestHook(hook) {
|
146 | hook.warningLog = this.warningLog;
|
147 | hook._instantiateRequestFilterRules();
|
148 | hook._instantiatedRequestFilterRules.forEach(rule => {
|
149 | this.session.addRequestEventListeners(rule, {
|
150 | onRequest: hook.onRequest.bind(hook),
|
151 | onConfigureResponse: hook._onConfigureResponse.bind(hook),
|
152 | onResponse: hook.onResponse.bind(hook)
|
153 | }, err => this._onRequestHookMethodError(err, hook));
|
154 | });
|
155 | }
|
156 | _onRequestHookMethodError(event, hook) {
|
157 | let err = event.error;
|
158 | const isRequestHookNotImplementedMethodError = err instanceof test_run_1.RequestHookNotImplementedMethodError;
|
159 | if (!isRequestHookNotImplementedMethodError) {
|
160 | const hookClassName = hook.constructor.name;
|
161 | err = new test_run_1.RequestHookUnhandledError(err, hookClassName, event.methodName);
|
162 | }
|
163 | this.addError(err);
|
164 | }
|
165 | _disposeRequestHook(hook) {
|
166 | hook.warningLog = null;
|
167 | hook._instantiatedRequestFilterRules.forEach(rule => {
|
168 | this.session.removeRequestEventListeners(rule);
|
169 | });
|
170 | }
|
171 | _initRequestHooks() {
|
172 | this.requestHooks = Array.from(this.test.requestHooks);
|
173 | this.requestHooks.forEach(hook => this._initRequestHook(hook));
|
174 | }
|
175 | // Hammerhead payload
|
176 | _getPayloadScript() {
|
177 | this.fileDownloadingHandled = false;
|
178 | this.resolveWaitForFileDownloadingPromise = null;
|
179 | return mustache_1.default.render(TEST_RUN_TEMPLATE, {
|
180 | testRunId: JSON.stringify(this.session.id),
|
181 | browserId: JSON.stringify(this.browserConnection.id),
|
182 | browserHeartbeatRelativeUrl: JSON.stringify(this.browserConnection.heartbeatRelativeUrl),
|
183 | browserStatusRelativeUrl: JSON.stringify(this.browserConnection.statusRelativeUrl),
|
184 | browserStatusDoneRelativeUrl: JSON.stringify(this.browserConnection.statusDoneRelativeUrl),
|
185 | browserActiveWindowIdUrl: JSON.stringify(this.browserConnection.activeWindowIdUrl),
|
186 | userAgent: JSON.stringify(this.browserConnection.userAgent),
|
187 | testName: JSON.stringify(this.test.name),
|
188 | fixtureName: JSON.stringify(this.test.fixture.name),
|
189 | selectorTimeout: this.opts.selectorTimeout,
|
190 | pageLoadTimeout: this.pageLoadTimeout,
|
191 | childWindowReadyTimeout: CHILD_WINDOW_READY_TIMEOUT,
|
192 | skipJsErrors: this.opts.skipJsErrors,
|
193 | retryTestPages: this.opts.retryTestPages,
|
194 | speed: this.speed,
|
195 | dialogHandler: JSON.stringify(this.activeDialogHandler)
|
196 | });
|
197 | }
|
198 | _getIframePayloadScript() {
|
199 | return mustache_1.default.render(IFRAME_TEST_RUN_TEMPLATE, {
|
200 | testRunId: JSON.stringify(this.session.id),
|
201 | selectorTimeout: this.opts.selectorTimeout,
|
202 | pageLoadTimeout: this.pageLoadTimeout,
|
203 | retryTestPages: !!this.opts.retryTestPages,
|
204 | speed: this.speed,
|
205 | dialogHandler: JSON.stringify(this.activeDialogHandler)
|
206 | });
|
207 | }
|
208 | // Hammerhead handlers
|
209 | getAuthCredentials() {
|
210 | return this.test.authCredentials;
|
211 | }
|
212 | handleFileDownload() {
|
213 | if (this.resolveWaitForFileDownloadingPromise) {
|
214 | this.resolveWaitForFileDownloadingPromise(true);
|
215 | this.resolveWaitForFileDownloadingPromise = null;
|
216 | }
|
217 | else
|
218 | this.fileDownloadingHandled = true;
|
219 | }
|
220 | handlePageError(ctx, err) {
|
221 | if (ctx.req.headers[unstable_network_mode_1.UNSTABLE_NETWORK_MODE_HEADER]) {
|
222 | ctx.closeWithError(500, err.toString());
|
223 | return;
|
224 | }
|
225 | this.pendingPageError = new test_run_1.PageLoadError(err, ctx.reqOpts.url);
|
226 | ctx.redirect(ctx.toProxyUrl(testcafe_hammerhead_1.SPECIAL_ERROR_PAGE));
|
227 | }
|
228 | // Test function execution
|
229 | async _executeTestFn(phase, fn) {
|
230 | this.phase = phase;
|
231 | try {
|
232 | await fn(this);
|
233 | }
|
234 | catch (err) {
|
235 | let screenshotPath = null;
|
236 | const { screenshots } = this.opts;
|
237 | if (screenshots && screenshots.takeOnFails)
|
238 | screenshotPath = await this.executeCommand(new browserManipulationCommands.TakeScreenshotOnFailCommand());
|
239 | this.addError(err, screenshotPath);
|
240 | return false;
|
241 | }
|
242 | return !this._addPendingPageErrorIfAny();
|
243 | }
|
244 | async _runBeforeHook() {
|
245 | if (this.test.beforeFn)
|
246 | return await this._executeTestFn(phase_1.default.inTestBeforeHook, this.test.beforeFn);
|
247 | if (this.test.fixture.beforeEachFn)
|
248 | return await this._executeTestFn(phase_1.default.inFixtureBeforeEachHook, this.test.fixture.beforeEachFn);
|
249 | return true;
|
250 | }
|
251 | async _runAfterHook() {
|
252 | if (this.test.afterFn)
|
253 | return await this._executeTestFn(phase_1.default.inTestAfterHook, this.test.afterFn);
|
254 | if (this.test.fixture.afterEachFn)
|
255 | return await this._executeTestFn(phase_1.default.inFixtureAfterEachHook, this.test.fixture.afterEachFn);
|
256 | return true;
|
257 | }
|
258 | async start() {
|
259 | test_run_tracker_1.default.activeTestRuns[this.session.id] = this;
|
260 | await this.emit('start');
|
261 | const onDisconnected = err => this._disconnect(err);
|
262 | this.browserConnection.once('disconnected', onDisconnected);
|
263 | await this.once('connected');
|
264 | await this.emit('ready');
|
265 | if (await this._runBeforeHook()) {
|
266 | await this._executeTestFn(phase_1.default.inTest, this.test.fn);
|
267 | await this._runAfterHook();
|
268 | }
|
269 | if (this.disconnected)
|
270 | return;
|
271 | this.browserConnection.removeListener('disconnected', onDisconnected);
|
272 | if (this.errs.length && this.debugOnFail)
|
273 | await this._enqueueSetBreakpointCommand(null, this.debugReporterPluginHost.formatError(this.errs[0]));
|
274 | await this.emit('before-done');
|
275 | await this.executeCommand(new serviceCommands.TestDoneCommand());
|
276 | this._addPendingPageErrorIfAny();
|
277 | this.session.clearRequestEventListeners();
|
278 | this.normalizeRequestHookErrors();
|
279 | delete test_run_tracker_1.default.activeTestRuns[this.session.id];
|
280 | await this.emit('done');
|
281 | }
|
282 | // Errors
|
283 | _addPendingPageErrorIfAny() {
|
284 | if (this.pendingPageError) {
|
285 | this.addError(this.pendingPageError);
|
286 | this.pendingPageError = null;
|
287 | return true;
|
288 | }
|
289 | return false;
|
290 | }
|
291 | _createErrorAdapter(err, screenshotPath) {
|
292 | return new formattable_adapter_1.default(err, {
|
293 | userAgent: this.browserConnection.userAgent,
|
294 | screenshotPath: screenshotPath || '',
|
295 | testRunPhase: this.phase
|
296 | });
|
297 | }
|
298 | addError(err, screenshotPath) {
|
299 | const errList = err instanceof error_list_1.default ? err.items : [err];
|
300 | errList.forEach(item => {
|
301 | const adapter = this._createErrorAdapter(item, screenshotPath);
|
302 | this.errs.push(adapter);
|
303 | });
|
304 | }
|
305 | normalizeRequestHookErrors() {
|
306 | const requestHookErrors = lodash_1.remove(this.errs, e => e.code === types_1.TEST_RUN_ERRORS.requestHookNotImplementedError ||
|
307 | e.code === types_1.TEST_RUN_ERRORS.requestHookUnhandledError);
|
308 | if (!requestHookErrors.length)
|
309 | return;
|
310 | const uniqRequestHookErrors = lodash_1.chain(requestHookErrors)
|
311 | .uniqBy(e => e.hookClassName + e.methodName)
|
312 | .sortBy(['hookClassName', 'methodName'])
|
313 | .value();
|
314 | this.errs = this.errs.concat(uniqRequestHookErrors);
|
315 | }
|
316 | // Task queue
|
317 | _enqueueCommand(command, callsite) {
|
318 | if (this.pendingRequest)
|
319 | this._resolvePendingRequest(command);
|
320 | return new Promise(async (resolve, reject) => {
|
321 | this.addingDriverTasksCount--;
|
322 | this.driverTaskQueue.push({ command, resolve, reject, callsite });
|
323 | if (!this.addingDriverTasksCount)
|
324 | await this.emit(ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT, this.driverTaskQueue.length);
|
325 | });
|
326 | }
|
327 | get driverTaskQueueLength() {
|
328 | return this.addingDriverTasksCount ? promisify_event_1.default(this, ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT) : Promise.resolve(this.driverTaskQueue.length);
|
329 | }
|
330 | async _enqueueBrowserConsoleMessagesCommand(command, callsite) {
|
331 | await this._enqueueCommand(command, callsite);
|
332 | const consoleMessageCopy = this.consoleMessages.getCopy();
|
333 | return consoleMessageCopy[this.browserConnection.activeWindowId];
|
334 | }
|
335 | async _enqueueSetBreakpointCommand(callsite, error) {
|
336 | if (this.browserConnection.isHeadlessBrowser()) {
|
337 | this.warningLog.addWarning(warning_message_1.default.debugInHeadlessError);
|
338 | return;
|
339 | }
|
340 | if (this.debugLogger)
|
341 | this.debugLogger.showBreakpoint(this.session.id, this.browserConnection.userAgent, callsite, error);
|
342 | this.debugging = await this.executeCommand(new serviceCommands.SetBreakpointCommand(!!error), callsite);
|
343 | }
|
344 | _removeAllNonServiceTasks() {
|
345 | this.driverTaskQueue = this.driverTaskQueue.filter(driverTask => utils_2.isServiceCommand(driverTask.command));
|
346 | this.browserManipulationQueue.removeAllNonServiceManipulations();
|
347 | }
|
348 | // Current driver task
|
349 | get currentDriverTask() {
|
350 | return this.driverTaskQueue[0];
|
351 | }
|
352 | _resolveCurrentDriverTask(result) {
|
353 | this.currentDriverTask.resolve(result);
|
354 | this.driverTaskQueue.shift();
|
355 | if (this.testDoneCommandQueued)
|
356 | this._removeAllNonServiceTasks();
|
357 | }
|
358 | _rejectCurrentDriverTask(err) {
|
359 | err.callsite = err.callsite || this.currentDriverTask.callsite;
|
360 | this.currentDriverTask.reject(err);
|
361 | this._removeAllNonServiceTasks();
|
362 | }
|
363 | // Pending request
|
364 | _clearPendingRequest() {
|
365 | if (this.pendingRequest) {
|
366 | clearTimeout(this.pendingRequest.responseTimeout);
|
367 | this.pendingRequest = null;
|
368 | }
|
369 | }
|
370 | _resolvePendingRequest(command) {
|
371 | this.lastDriverStatusResponse = command;
|
372 | this.pendingRequest.resolve(command);
|
373 | this._clearPendingRequest();
|
374 | }
|
375 | // Handle driver request
|
376 | _fulfillCurrentDriverTask(driverStatus) {
|
377 | if (!this.currentDriverTask)
|
378 | return;
|
379 | if (driverStatus.executionError)
|
380 | this._rejectCurrentDriverTask(driverStatus.executionError);
|
381 | else
|
382 | this._resolveCurrentDriverTask(driverStatus.result);
|
383 | }
|
384 | _handlePageErrorStatus(pageError) {
|
385 | if (this.currentDriverTask && utils_2.isCommandRejectableByPageError(this.currentDriverTask.command)) {
|
386 | this._rejectCurrentDriverTask(pageError);
|
387 | this.pendingPageError = null;
|
388 | return true;
|
389 | }
|
390 | this.pendingPageError = this.pendingPageError || pageError;
|
391 | return false;
|
392 | }
|
393 | _handleDriverRequest(driverStatus) {
|
394 | const isTestDone = this.currentDriverTask && this.currentDriverTask.command.type ===
|
395 | type_1.default.testDone;
|
396 | const pageError = this.pendingPageError || driverStatus.pageError;
|
397 | const currentTaskRejectedByError = pageError && this._handlePageErrorStatus(pageError);
|
398 | if (this.disconnected)
|
399 | return new Promise((_, reject) => reject());
|
400 | this.consoleMessages.concat(driverStatus.consoleMessages);
|
401 | if (!currentTaskRejectedByError && driverStatus.isCommandResult) {
|
402 | if (isTestDone) {
|
403 | this._resolveCurrentDriverTask();
|
404 | return TEST_DONE_CONFIRMATION_RESPONSE;
|
405 | }
|
406 | this._fulfillCurrentDriverTask(driverStatus);
|
407 | if (driverStatus.isPendingWindowSwitching)
|
408 | return null;
|
409 | }
|
410 | return this._getCurrentDriverTaskCommand();
|
411 | }
|
412 | _getCurrentDriverTaskCommand() {
|
413 | if (!this.currentDriverTask)
|
414 | return null;
|
415 | const command = this.currentDriverTask.command;
|
416 | if (command.type === type_1.default.navigateTo && command.stateSnapshot)
|
417 | this.session.useStateSnapshot(JSON.parse(command.stateSnapshot));
|
418 | return command;
|
419 | }
|
420 | // Execute command
|
421 | _executeJsExpression(command) {
|
422 | const resultVariableName = command.resultVariableName;
|
423 | let expression = command.expression;
|
424 | if (resultVariableName)
|
425 | expression = `${resultVariableName} = ${expression}, ${resultVariableName}`;
|
426 | return executeJsExpression(expression, this, { skipVisibilityCheck: false });
|
427 | }
|
428 | async _executeAssertion(command, callsite) {
|
429 | const assertionTimeout = command.options.timeout ===
|
430 | void 0 ? this.opts.assertionTimeout : command.options.timeout;
|
431 | const executor = new AssertionExecutor(command, assertionTimeout, callsite);
|
432 | executor.once('start-assertion-retries', timeout => this.executeCommand(new serviceCommands.ShowAssertionRetriesStatusCommand(timeout)));
|
433 | executor.once('end-assertion-retries', success => this.executeCommand(new serviceCommands.HideAssertionRetriesStatusCommand(success)));
|
434 | const executeFn = this.decoratePreventEmitActionEvents(() => executor.run(), { prevent: true });
|
435 | return await executeFn();
|
436 | }
|
437 | _adjustConfigurationWithCommand(command) {
|
438 | if (command.type === type_1.default.testDone) {
|
439 | this.testDoneCommandQueued = true;
|
440 | if (this.debugLogger)
|
441 | this.debugLogger.hideBreakpoint(this.session.id);
|
442 | }
|
443 | else if (command.type === type_1.default.setNativeDialogHandler)
|
444 | this.activeDialogHandler = command.dialogHandler;
|
445 | else if (command.type === type_1.default.switchToIframe)
|
446 | this.activeIframeSelector = command.selector;
|
447 | else if (command.type === type_1.default.switchToMainWindow)
|
448 | this.activeIframeSelector = null;
|
449 | else if (command.type === type_1.default.setTestSpeed)
|
450 | this.speed = command.speed;
|
451 | else if (command.type === type_1.default.setPageLoadTimeout)
|
452 | this.pageLoadTimeout = command.duration;
|
453 | else if (command.type === type_1.default.debug)
|
454 | this.debugging = true;
|
455 | }
|
456 | async _adjustScreenshotCommand(command) {
|
457 | const browserId = this.browserConnection.id;
|
458 | const { hasChromelessScreenshots } = await this.browserConnection.provider.hasCustomActionForBrowser(browserId);
|
459 | if (!hasChromelessScreenshots)
|
460 | command.generateScreenshotMark();
|
461 | }
|
462 | async _setBreakpointIfNecessary(command, callsite) {
|
463 | if (!this.disableDebugBreakpoints && this.debugging && utils_2.canSetDebuggerBreakpointBeforeCommand(command))
|
464 | await this._enqueueSetBreakpointCommand(callsite);
|
465 | }
|
466 | async executeAction(actionName, command, callsite) {
|
467 | let error = null;
|
468 | let result = null;
|
469 | await this.emitActionStart(actionName, command);
|
470 | try {
|
471 | result = await this.executeCommand(command, callsite);
|
472 | }
|
473 | catch (err) {
|
474 | error = err;
|
475 | }
|
476 | await this.emitActionDone(actionName, command, error);
|
477 | if (error)
|
478 | throw error;
|
479 | return result;
|
480 | }
|
481 | async executeCommand(command, callsite) {
|
482 | this.debugLog.command(command);
|
483 | if (this.pendingPageError && utils_2.isCommandRejectableByPageError(command))
|
484 | return this._rejectCommandWithPageError(callsite);
|
485 | if (utils_2.isExecutableOnClientCommand(command))
|
486 | this.addingDriverTasksCount++;
|
487 | this._adjustConfigurationWithCommand(command);
|
488 | await this._setBreakpointIfNecessary(command, callsite);
|
489 | if (utils_2.isScreenshotCommand(command)) {
|
490 | if (this.opts.disableScreenshots) {
|
491 | this.warningLog.addWarning(warning_message_1.default.screenshotsDisabled);
|
492 | return null;
|
493 | }
|
494 | await this._adjustScreenshotCommand(command);
|
495 | }
|
496 | if (utils_2.isBrowserManipulationCommand(command)) {
|
497 | this.browserManipulationQueue.push(command);
|
498 | if (utils_2.isResizeWindowCommand(command) && this.opts.videoPath)
|
499 | this.warningLog.addWarning(warning_message_1.default.videoBrowserResizing, this.test.name);
|
500 | }
|
501 | if (command.type === type_1.default.wait)
|
502 | return delay_1.default(command.timeout);
|
503 | if (command.type === type_1.default.setPageLoadTimeout)
|
504 | return null;
|
505 | if (command.type === type_1.default.debug)
|
506 | return await this._enqueueSetBreakpointCommand(callsite);
|
507 | if (command.type === type_1.default.useRole) {
|
508 | let fn = () => this._useRole(command.role, callsite);
|
509 | fn = this.decoratePreventEmitActionEvents(fn, { prevent: true });
|
510 | fn = this.decorateDisableDebugBreakpoints(fn, { disable: true });
|
511 | return await fn();
|
512 | }
|
513 | if (command.type === type_1.default.assertion)
|
514 | return this._executeAssertion(command, callsite);
|
515 | if (command.type === type_1.default.executeExpression)
|
516 | return await this._executeJsExpression(command, callsite);
|
517 | if (command.type === type_1.default.executeAsyncExpression)
|
518 | return await executeAsyncJsExpression(command.expression, this, callsite);
|
519 | if (command.type === type_1.default.getBrowserConsoleMessages)
|
520 | return await this._enqueueBrowserConsoleMessagesCommand(command, callsite);
|
521 | return this._enqueueCommand(command, callsite);
|
522 | }
|
523 | _rejectCommandWithPageError(callsite) {
|
524 | const err = this.pendingPageError;
|
525 | err.callsite = callsite;
|
526 | this.pendingPageError = null;
|
527 | return Promise.reject(err);
|
528 | }
|
529 | _decorateWithFlag(fn, flagName, value) {
|
530 | return async () => {
|
531 | this[flagName] = value;
|
532 | try {
|
533 | return await fn();
|
534 | }
|
535 | catch (err) {
|
536 | throw err;
|
537 | }
|
538 | finally {
|
539 | this[flagName] = !value;
|
540 | }
|
541 | };
|
542 | }
|
543 | decoratePreventEmitActionEvents(fn, { prevent }) {
|
544 | return this._decorateWithFlag(fn, 'preventEmitActionEvents', prevent);
|
545 | }
|
546 | decorateDisableDebugBreakpoints(fn, { disable }) {
|
547 | return this._decorateWithFlag(fn, 'disableDebugBreakpoints', disable);
|
548 | }
|
549 | // Role management
|
550 | async getStateSnapshot() {
|
551 | const state = this.session.getStateSnapshot();
|
552 | state.storages = await this.executeCommand(new serviceCommands.BackupStoragesCommand());
|
553 | return state;
|
554 | }
|
555 | async switchToCleanRun(url) {
|
556 | this.ctx = Object.create(null);
|
557 | this.fixtureCtx = Object.create(null);
|
558 | this.consoleMessages = new browser_console_messages_1.default();
|
559 | this.session.useStateSnapshot(testcafe_hammerhead_1.StateSnapshot.empty());
|
560 | if (this.speed !== this.opts.speed) {
|
561 | const setSpeedCommand = new actionCommands.SetTestSpeedCommand({ speed: this.opts.speed });
|
562 | await this.executeCommand(setSpeedCommand);
|
563 | }
|
564 | if (this.pageLoadTimeout !== this.opts.pageLoadTimeout) {
|
565 | const setPageLoadTimeoutCommand = new actionCommands.SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout });
|
566 | await this.executeCommand(setPageLoadTimeoutCommand);
|
567 | }
|
568 | await this.navigateToUrl(url, true);
|
569 | if (this.activeDialogHandler) {
|
570 | const removeDialogHandlerCommand = new actionCommands.SetNativeDialogHandlerCommand({ dialogHandler: { fn: null } });
|
571 | await this.executeCommand(removeDialogHandlerCommand);
|
572 | }
|
573 | }
|
574 | async navigateToUrl(url, forceReload, stateSnapshot) {
|
575 | const navigateCommand = new actions_1.NavigateToCommand({ url, forceReload, stateSnapshot });
|
576 | await this.executeCommand(navigateCommand);
|
577 | }
|
578 | async _getStateSnapshotFromRole(role) {
|
579 | const prevPhase = this.phase;
|
580 | this.phase = phase_1.default.inRoleInitializer;
|
581 | if (role.phase === phase_2.default.uninitialized)
|
582 | await role.initialize(this);
|
583 | else if (role.phase === phase_2.default.pendingInitialization)
|
584 | await promisify_event_1.default(role, 'initialized');
|
585 | if (role.initErr)
|
586 | throw role.initErr;
|
587 | this.phase = prevPhase;
|
588 | return role.stateSnapshot;
|
589 | }
|
590 | async _useRole(role, callsite) {
|
591 | if (this.phase === phase_1.default.inRoleInitializer)
|
592 | throw new test_run_1.RoleSwitchInRoleInitializerError(callsite);
|
593 | const bookmark = new TestRunBookmark(this, role);
|
594 | await bookmark.init();
|
595 | if (this.currentRoleId)
|
596 | this.usedRoleStates[this.currentRoleId] = await this.getStateSnapshot();
|
597 | const stateSnapshot = this.usedRoleStates[role.id] || await this._getStateSnapshotFromRole(role);
|
598 | this.session.useStateSnapshot(stateSnapshot);
|
599 | this.currentRoleId = role.id;
|
600 | await bookmark.restore(callsite, stateSnapshot);
|
601 | }
|
602 | // Get current URL
|
603 | async getCurrentUrl() {
|
604 | const builder = new ClientFunctionBuilder(() => {
|
605 | /* eslint-disable no-undef */
|
606 | return window.location.href;
|
607 | /* eslint-enable no-undef */
|
608 | }, { boundTestRun: this });
|
609 | const getLocation = builder.getFunction();
|
610 | return await getLocation();
|
611 | }
|
612 | _disconnect(err) {
|
613 | this.disconnected = true;
|
614 | if (this.currentDriverTask)
|
615 | this._rejectCurrentDriverTask(err);
|
616 | this.emit('disconnected', err);
|
617 | delete test_run_tracker_1.default.activeTestRuns[this.session.id];
|
618 | }
|
619 | async emitActionStart(apiActionName, command) {
|
620 | if (!this.preventEmitActionEvents)
|
621 | await this.emit('action-start', { command, apiActionName });
|
622 | }
|
623 | async emitActionDone(apiActionName, command, errors) {
|
624 | if (!this.preventEmitActionEvents)
|
625 | await this.emit('action-done', { command, apiActionName, errors });
|
626 | }
|
627 | }
|
628 | exports.default = TestRun;
|
629 | // Service message handlers
|
630 | const ServiceMessages = TestRun.prototype;
|
631 | // NOTE: this function is time-critical and must return ASAP to avoid client disconnection
|
632 | ServiceMessages[client_messages_1.default.ready] = function (msg) {
|
633 | this.debugLog.driverMessage(msg);
|
634 | this.emit('connected');
|
635 | this._clearPendingRequest();
|
636 | // NOTE: the driver sends the status for the second time if it didn't get a response at the
|
637 | // first try. This is possible when the page was unloaded after the driver sent the status.
|
638 | if (msg.status.id === this.lastDriverStatusId)
|
639 | return this.lastDriverStatusResponse;
|
640 | this.lastDriverStatusId = msg.status.id;
|
641 | this.lastDriverStatusResponse = this._handleDriverRequest(msg.status);
|
642 | if (this.lastDriverStatusResponse || msg.status.isPendingWindowSwitching)
|
643 | return this.lastDriverStatusResponse;
|
644 | // NOTE: we send an empty response after the MAX_RESPONSE_DELAY timeout is exceeded to keep connection
|
645 | // with the client and prevent the response timeout exception on the client side
|
646 | const responseTimeout = setTimeout(() => this._resolvePendingRequest(null), MAX_RESPONSE_DELAY);
|
647 | return new Promise((resolve, reject) => {
|
648 | this.pendingRequest = { resolve, reject, responseTimeout };
|
649 | });
|
650 | };
|
651 | ServiceMessages[client_messages_1.default.readyForBrowserManipulation] = async function (msg) {
|
652 | this.debugLog.driverMessage(msg);
|
653 | let result = null;
|
654 | let error = null;
|
655 | try {
|
656 | result = await this.browserManipulationQueue.executePendingManipulation(msg);
|
657 | }
|
658 | catch (err) {
|
659 | error = err;
|
660 | }
|
661 | return { result, error };
|
662 | };
|
663 | ServiceMessages[client_messages_1.default.waitForFileDownload] = function (msg) {
|
664 | this.debugLog.driverMessage(msg);
|
665 | return new Promise(resolve => {
|
666 | if (this.fileDownloadingHandled) {
|
667 | this.fileDownloadingHandled = false;
|
668 | resolve(true);
|
669 | }
|
670 | else
|
671 | this.resolveWaitForFileDownloadingPromise = resolve;
|
672 | });
|
673 | };
|
674 | module.exports = exports.default;
|
675 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC1ydW4vaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsbUNBQTZDO0FBQzdDLDJEQUFzRDtBQUN0RCxzRUFBNkM7QUFDN0Msd0RBQWdDO0FBQ2hDLHVGQUE2RDtBQUM3RCw0REFBMEM7QUFDMUMsaUdBQW9GO0FBQ3BGLHNFQUFxRDtBQUNyRCxrREFLNkI7QUFDN0Isb0RBQTRCO0FBQzVCLHdFQUFnRDtBQUNoRCwyREFBMkM7QUFDM0MsMkRBQW1DO0FBQ25DLG9FQUE0QztBQUM1QywrRUFBcUQ7QUFDckQsMERBQXVDO0FBQ3ZDLDBFQUF5RDtBQUN6RCwwRkFBZ0U7QUFDaEUsdUZBQTJGO0FBQzNGLCtFQUFzRDtBQUN0RCx1RkFBK0Q7QUFDL0QsNkRBQXdFO0FBQ3hFLGdEQUF1RDtBQUN2RCxtRUFBcUQ7QUFDckQsMERBQXdFO0FBQ3hFLCtFQUF3RTtBQUN4RSw0Q0FBK0U7QUFFL0UsNENBUTBCO0FBRTFCLDJDQUFrRDtBQUVsRCxNQUFNLFdBQVcsR0FBbUIsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BFLE1BQU0saUJBQWlCLEdBQWEsV0FBVyxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFDeEUsTUFBTSxxQkFBcUIsR0FBUyxXQUFXLENBQUMsNkNBQTZDLENBQUMsQ0FBQztBQUMvRixNQUFNLHdCQUF3QixHQUFNLFdBQVcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0FBQ2hGLE1BQU0sZUFBZSxHQUFlLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM5RCxNQUFNLGlCQUFpQixHQUFhLFdBQVcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQzFFLE1BQU0sY0FBYyxHQUFnQixXQUFXLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQUN0RSxNQUFNLDJCQUEyQixHQUFHLFdBQVcsQ0FBQyxpQ0FBaUMsQ0FB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QUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDN0IsQ0FBQyxDQUFDO0FBRUYsZUFBZSxDQUFDLHlCQUFlLENBQUMsbUJBQW1CLENBQUMsR0FBRyxVQUFVLEdBQUc7SUFDaEUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFakMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUN6QixJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUM3QixJQUFJLENBQUMsc0JBQXNCLEdBQUcsS0FBSyxDQUFDO1lBQ3BDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNqQjs7WUFFRyxJQUFJLENBQUMsb0NBQW9DLEdBQUcsT0FBTyxDQUFDO0lBQzVELENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcHVsbCwgcmVtb3ZlLCBjaGFpbiB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyByZWFkU3luYyBhcyByZWFkIH0gZnJvbSAncmVhZC1maWxlLXJlbGF0aXZlJztcbmltcG9ydCBwcm9taXNpZnlFdmVudCBmcm9tICdwcm9taXNpZnktZXZlbnQnO1xuaW1wb3J0IE11c3RhY2hlIGZyb20gJ211c3RhY2hlJztcbmltcG9ydCBBc3luY0V2ZW50RW1pdHRlciBmcm9tICcuLi91dGlscy9hc3luYy1ldmVudC1lbWl0dGVyJztcbmltcG9ydCBUZXN0UnVuRGVidWdMb2cgZnJvbSAnLi9kZWJ1Zy1sb2cnO1xuaW1wb3J0IFRlc3RSdW5FcnJvckZvcm1hdHRhYmxlQWRhcHRlciBmcm9tICcuLi9lcnJvcnMvdGVzdC1ydW4vZm9ybWF0dGFibGUtYWRhcHRlcic7XG5pbXBvcnQgVGVzdENhZmVFcnJvckxpc3QgZnJvbSAnLi4vZXJyb3JzL2Vycm9yLWxpc3QnO1xuaW1wb3J0IHtcbiAgICBSZXF1ZXN0SG9va1VuaGFuZGxlZEVycm9yLFxuICAgIFBhZ2VMb2FkRXJyb3IsXG4gICAgUmVxdWVzdEhvb2tOb3RJbXBsZW1lbnRlZE1ldGhvZEVycm9yLFxuICAgIFJvbGVTd2l0Y2hJblJvbGVJbml0aWFsaXplckVycm9yXG59IGZyb20gJy4uL2Vycm9ycy90ZXN0LXJ1bi8nO1xuaW1wb3J0IFBIQVNFIGZyb20gJy4vcGhhc2UnO1xuaW1wb3J0IENMSUVOVF9NRVNTQUdFUyBmcm9tICcuL2NsaWVudC1tZXNzYWdlcyc7XG5pbXBvcnQgQ09NTUFORF9UWVBFIGZyb20gJy4vY29tbWFuZHMvdHlwZSc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi4vdXRpbHMvZGVsYXknO1xuaW1wb3J0IHRlc3RSdW5NYXJrZXIgZnJvbSAnLi9tYXJrZXItc3ltYm9sJztcbmltcG9ydCB0ZXN0UnVuVHJhY2tlciBmcm9tICcuLi9hcGkvdGVzdC1ydW4tdHJhY2tlcic7XG5pbXBvcnQgUk9MRV9QSEFTRSBmcm9tICcuLi9yb2xlL3BoYXNlJztcbmltcG9ydCBSZXBvcnRlclBsdWdpbkhvc3QgZnJvbSAnLi4vcmVwb3J0ZXIvcGx1Z2luLWhvc3QnO1xuaW1wb3J0IEJyb3dzZXJDb25zb2xlTWVzc2FnZXMgZnJvbSAnLi9icm93c2VyLWNvbnNvbGUtbWVzc2FnZXMnO1xuaW1wb3J0IHsgVU5TVEFCTEVfTkVUV09SS19NT0RFX0hFQURFUiB9IGZyb20gJy4uL2Jyb3dzZXIvY29ubmVjdGlvbi91bnN0YWJsZS1uZXR3b3JrLW1vZGUnO1xuaW1wb3J0IFdhcm5pbmdMb2cgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLWxvZyc7XG5pbXBvcnQgV0FSTklOR19NRVNTQUdFIGZyb20gJy4uL25vdGlmaWNhdGlvbnMvd2FybmluZy1tZXNzYWdlJztcbmltcG9ydCB7IFN0YXRlU25hcHNob3QsIFNQRUNJQUxfRVJST1JfUEFHRSB9IGZyb20gJ3Rlc3RjYWZlLWhhbW1lcmhlYWQnO1xuaW1wb3J0IHsgTmF2aWdhdGVUb0NvbW1hbmQgfSBmcm9tICcuL2NvbW1hbmRzL2FjdGlvbnMnO1xuaW1wb3J0ICogYXMgSU5KRUNUQUJMRVMgZnJvbSAnLi4vYXNzZXRzL2luamVjdGFibGVzJztcbmltcG9ydCB7IGZpbmRQcm9ibGVtYXRpY1NjcmlwdHMgfSBmcm9tICcuLi9jdXN0b20tY2xpZW50LXNjcmlwdHMvdXRpbHMnO1xuaW1wb3J0IGdldEN1c3RvbUNsaWVudFNjcmlwdFVybCBmcm9tICcuLi9jdXN0b20tY2xpZW50LXNjcmlwdHMvZ2V0LXVybCc7XG5pbXBvcnQgeyBnZXRQbHVyYWxTdWZmaXgsIGdldENvbmNhdGVuYXRlZFZhbHVlc1N0cmluZyB9IGZyb20gJy4uL3V0aWxzL3N0cmluZyc7XG5cbmltcG9ydCB7XG4gICAgaXNDb21tYW5kUmVqZWN0YWJsZUJ5UGFnZUVycm9yLFxuICAgIGlzQnJvd3Nlck1hbmlwdWxhdGlvbkNvbW1hbmQsXG4gICAgaXNTY3JlZW5zaG90Q29tbWFuZCxcbiAgICBpc1NlcnZpY2VDb21tYW5kLFxuICAgIGNhblNldERlYnVnZ2VyQnJlYWtwb2ludEJlZm9yZUNvbW1hbmQsXG4gICAgaXNFeGVjdXRhYmxlT25DbGllbnRDb21tYW5kLFxuICAgIGlzUmVzaXplV2luZG93Q29tbWFuZFxufSBmcm9tICcuL2NvbW1hbmRzL3V0aWxzJztcblxuaW1wb3J0IHsgVEVTVF9SVU5fRVJST1JTIH0gZnJvbSAnLi4vZXJyb3JzL3R5cGVzJztcblxuY29uc3QgbGF6eVJlcXVpcmUgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnaW1wb3J0LWxhenknKShyZXF1aXJlKTtcbmNvbnN0IFNlc3Npb25Db250cm9sbGVyICAgICAgICAgICA9IGxhenlSZXF1aXJlKCcuL3Nlc3Npb24tY29udHJvbGxlcicpO1xuY29uc3QgQ2xpZW50RnVuY3Rpb25CdWlsZGVyICAgICAgID0gbGF6eVJlcXVpcmUoJy4uL2NsaWVudC1mdW5jdGlvbnMvY2xpZW50LWZ1bmN0aW9uLWJ1aWxkZXInKTtcbmNvbnN0IEJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZSAgICA9IGxhenlSZXF1aXJlKCcuL2Jyb3dzZXItbWFuaXB1bGF0aW9uLXF1ZXVlJyk7XG5jb25zdCBUZXN0UnVuQm9va21hcmsgICAgICAgICAgICAgPSBsYXp5UmVxdWlyZSgnLi9ib29rbWFyaycpO1xuY29uc3QgQXNzZXJ0aW9uRXhlY3V0b3IgICAgICAgICAgID0gbGF6eVJlcXVpcmUoJy4uL2Fzc2VydGlvbnMvZXhlY3V0b3InKTtcbmNvbnN0IGFjdGlvbkNvbW1hbmRzICAgICAgICAgICAgICA9IGxhenlSZXF1aXJlKCcuL2NvbW1hbmRzL2FjdGlvbnMnKTtcbmNvbnN0IGJyb3dzZXJNYW5pcHVsYXRpb25Db21tYW5kcyA9IGxhenlSZXF1aXJlKCcuL2NvbW1hbmRzL2Jyb3dzZXItbWFuaXB1bGF0aW9uJyk7XG5jb25zdCBzZXJ2aWNlQ29tbWFuZHMgICAgICAgICAgICAgPSBsYXp5UmVxdWlyZSgnLi9jb21tYW5kcy9zZXJ2aWNlJyk7XG5cbmNvbnN0IHsgZXhlY3V0ZUpzRXhwcmVzc2lvbiwgZXhlY3V0ZUFzeW5jSnNFeHByZXNzaW9uIH0gPSBsYXp5UmVxdWlyZSgnLi9leGVjdXRlLWpzLWV4cHJlc3Npb24nKTtcblxuY29uc3QgVEVTVF9SVU5fVEVNUExBVEUgICAgICAgICAgICAgICA9IHJlYWQoJy4uL2NsaWVudC90ZXN0LXJ1bi9pbmRleC5qcy5tdXN0YWNoZScpO1xuY29uc3QgSUZSQU1FX1RFU1RfUlVOX1RFTVBMQVRFICAgICAgICA9IHJlYWQoJy4uL2NsaWVudC90ZXN0LXJ1bi9pZnJhbWUuanMubXVzdGFjaGUnKTtcbmNvbnN0IFRFU1RfRE9ORV9DT05GSVJNQVRJT05fUkVTUE9OU0UgPSAndGVzdC1kb25lLWNvbmZpcm1hdGlvbic7XG5jb25zdCBNQVhfUkVTUE9OU0VfREVMQVkgICAgICAgICAgICAgID0gMzAwMDtcbmNvbnN0IENISUxEX1dJTkRPV19SRUFEWV9USU1FT1VUICAgICAgPSAzMCAqIDEwMDA7XG5cbmNvbnN0IEFMTF9EUklWRVJfVEFTS1NfQURERURfVE9fUVVFVUVfRVZFTlQgPSAnYWxsLWRyaXZlci10YXNrcy1hZGRlZC10by1xdWV1ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RSdW4gZXh0ZW5kcyBBc3luY0V2ZW50RW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IgKHRlc3QsIGJyb3dzZXJDb25uZWN0aW9uLCBzY3JlZW5zaG90Q2FwdHVyZXIsIGdsb2JhbFdhcm5pbmdMb2csIG9wdHMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW3Rlc3RSdW5NYXJrZXJdID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLndhcm5pbmdMb2cgPSBuZXcgV2FybmluZ0xvZyhnbG9iYWxXYXJuaW5nTG9nKTtcblxuICAgICAgICB0aGlzLm9wdHMgICAgICAgICAgICAgID0gb3B0cztcbiAgICAgICAgdGhpcy50ZXN0ICAgICAgICAgICAgICA9IHRlc3Q7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb24gPSBicm93c2VyQ29ubmVjdGlvbjtcblxuICAgICAgICB0aGlzLnBoYXNlID0gUEhBU0UuaW5pdGlhbDtcblxuICAgICAgICB0aGlzLmRyaXZlclRhc2tRdWV1ZSAgICAgICA9IFtdO1xuICAgICAgICB0aGlzLnRlc3REb25lQ29tbWFuZFF1ZXVlZCA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuYWN0aXZlRGlhbG9nSGFuZGxlciAgPSBudWxsO1xuICAgICAgICB0aGlzLmFjdGl2ZUlmcmFtZVNlbGVjdG9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5zcGVlZCAgICAgICAgICAgICAgICA9IHRoaXMub3B0cy5zcGVlZDtcbiAgICAgICAgdGhpcy5wYWdlTG9hZFRpbWVvdXQgICAgICA9IHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQ7XG5cbiAgICAgICAgdGhpcy5kaXNhYmxlUGFnZVJlbG9hZHMgICA9IHRlc3QuZGlzYWJsZVBhZ2VSZWxvYWRzIHx8IG9wdHMuZGlzYWJsZVBhZ2VSZWxvYWRzICYmIHRlc3QuZGlzYWJsZVBhZ2VSZWxvYWRzICE9PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2U7XG4gICAgICAgIHRoaXMuZGlzYWJsZVBhZ2VDYWNoaW5nICAgPSB0ZXN0LmRpc2FibGVQYWdlQ2FjaGluZyB8fCBvcHRzLmRpc2FibGVQYWdlQ2FjaGluZztcbiAgICAgICAgdGhpcy5hbGxvd011bHRpcGxlV2luZG93cyA9IG9wdHMuYWxsb3dNdWx0aXBsZVdpbmRvd3M7XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uID0gU2Vzc2lvbkNvbnRyb2xsZXIuZ2V0U2Vzc2lvbih0aGlzKTtcblxuICAgICAgICB0aGlzLmNvbnNvbGVNZXNzYWdlcyA9IG5ldyBCcm93c2VyQ29uc29sZU1lc3NhZ2VzKCk7XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdCAgID0gbnVsbDtcbiAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gbnVsbDtcblxuICAgICAgICB0aGlzLmNvbnRyb2xsZXIgPSBudWxsO1xuICAgICAgICB0aGlzLmN0eCAgICAgICAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLmZpeHR1cmVDdHggPSBudWxsO1xuXG4gICAgICAgIHRoaXMuY3VycmVudFJvbGVJZCAgPSBudWxsO1xuICAgICAgICB0aGlzLnVzZWRSb2xlU3RhdGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgICAgICB0aGlzLmVycnMgPSBbXTtcblxuICAgICAgICB0aGlzLmxhc3REcml2ZXJTdGF0dXNJZCAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMubGFzdERyaXZlclN0YXR1c1Jlc3BvbnNlID0gbnVsbDtcblxuICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgICAgICAgICAgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50ID0gMDtcblxuICAgICAgICB0aGlzLmRlYnVnZ2luZyAgICAgICAgICAgICAgID0gdGhpcy5vcHRzLmRlYnVnTW9kZTtcbiAgICAgICAgdGhpcy5kZWJ1Z09uRmFpbCAgICAgICAgICAgICA9IHRoaXMub3B0cy5kZWJ1Z09uRmFpbDtcbiAgICAgICAgdGhpcy5kaXNhYmxlRGVidWdCcmVha3BvaW50cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRlYnVnUmVwb3J0ZXJQbHVnaW5Ib3N0ID0gbmV3IFJlcG9ydGVyUGx1Z2luSG9zdCh7IG5vQ29sb3JzOiBmYWxzZSB9KTtcblxuICAgICAgICB0aGlzLmJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZSA9IG5ldyBCcm93c2VyTWFuaXB1bGF0aW9uUXVldWUoYnJvd3NlckNvbm5lY3Rpb24sIHNjcmVlbnNob3RDYXB0dXJlciwgdGhpcy53YXJuaW5nTG9nKTtcblxuICAgICAgICB0aGlzLmRlYnVnTG9nID0gbmV3IFRlc3RSdW5EZWJ1Z0xvZyh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnVzZXJBZ2VudCk7XG5cbiAgICAgICAgdGhpcy5xdWFyYW50aW5lICA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlciA9IHRoaXMub3B0cy5kZWJ1Z0xvZ2dlcjtcblxuICAgICAgICB0aGlzLl9hZGRJbmplY3RhYmxlcygpO1xuICAgICAgICB0aGlzLl9pbml0UmVxdWVzdEhvb2tzKCk7XG4gICAgfVxuXG4gICAgX2FkZENsaWVudFNjcmlwdENvbnRlbnRXYXJuaW5nc0lmTmVjZXNzYXJ5ICgpIHtcbiAgICAgICAgY29uc3QgeyBlbXB0eSwgZHVwbGljYXRlZENvbnRlbnQgfSA9IGZpbmRQcm9ibGVtYXRpY1NjcmlwdHModGhpcy50ZXN0LmNsaWVudFNjcmlwdHMpO1xuXG4gICAgICAgIGlmIChlbXB0eS5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyhXQVJOSU5HX01FU1NBR0UuY2xpZW50U2NyaXB0c1dpdGhFbXB0eUNvbnRlbnQpO1xuXG4gICAgICAgIGlmIChkdXBsaWNhdGVkQ29udGVudC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHN1ZmZpeCAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGdldFBsdXJhbFN1ZmZpeChkdXBsaWNhdGVkQ29udGVudCk7XG4gICAgICAgICAgICBjb25zdCBkdXBsaWNhdGVkQ29udGVudENsaWVudFNjcmlwdHNTdHIgPSBnZXRDb25jYXRlbmF0ZWRWYWx1ZXNTdHJpbmcoZHVwbGljYXRlZENvbnRlbnQsICcsXFxuICcpO1xuXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyhXQVJOSU5HX01FU1NBR0UuY2xpZW50U2NyaXB0c1dpdGhEdXBsaWNhdGVkQ29udGVudCwgc3VmZml4LCBkdXBsaWNhdGVkQ29udGVudENsaWVudFNjcmlwdHNTdHIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FkZEluamVjdGFibGVzICgpIHtcbiAgICAgICAgdGhpcy5fYWRkQ2xpZW50U2NyaXB0Q29udGVudFdhcm5pbmdzSWZOZWNlc3NhcnkoKTtcbiAgICAgICAgdGhpcy5pbmplY3RhYmxlLnNjcmlwdHMucHVzaCguLi5JTkpFQ1RBQkxFUy5TQ1JJUFRTKTtcbiAgICAgICAgdGhpcy5pbmplY3RhYmxlLnVzZXJTY3JpcHRzLnB1c2goLi4udGhpcy50ZXN0LmNsaWVudFNjcmlwdHMubWFwKHNjcmlwdCA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHVybDogIGdldEN1c3RvbUNsaWVudFNjcmlwdFVybChzY3JpcHQpLFxuICAgICAgICAgICAgICAgIHBhZ2U6IHNjcmlwdC5wYWdlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuaW5qZWN0YWJsZS5zdHlsZXMucHVzaChJTkpFQ1RBQkxFUy5URVNUQ0FGRV9VSV9TVFlMRVMpO1xuICAgIH1cblxuICAgIGdldCBpZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlc3Npb24uaWQ7XG4gICAgfVxuXG4gICAgZ2V0IGluamVjdGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXNzaW9uLmluamVjdGFibGU7XG4gICAgfVxuXG4gICAgYWRkUXVhcmFudGluZUluZm8gKHF1YXJhbnRpbmUpIHtcbiAgICAgICAgdGhpcy5xdWFyYW50aW5lID0gcXVhcmFudGluZTtcbiAgICB9XG5cbiAgICBhZGRSZXF1ZXN0SG9vayAoaG9vaykge1xuICAgICAgICBpZiAodGhpcy5yZXF1ZXN0SG9va3MuaW5kZXhPZihob29rKSAhPT0gLTEpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5yZXF1ZXN0SG9va3MucHVzaChob29rKTtcbiAgICAgICAgdGhpcy5faW5pdFJlcXVlc3RIb29rKGhvb2spO1xuICAgIH1cblxuICAgIHJlbW92ZVJlcXVlc3RIb29rIChob29rKSB7XG4gICAgICAgIGlmICh0aGlzLnJlcXVlc3RIb29rcy5pbmRleE9mKGhvb2spID09PSAtMSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBwdWxsKHRoaXMucmVxdWVzdEhvb2tzLCBob29rKTtcbiAgICAgICAgdGhpcy5fZGlzcG9zZVJlcXVlc3RIb29rKGhvb2spO1xuICAgIH1cblxuICAgIF9pbml0UmVxdWVzdEhvb2sgKGhvb2spIHtcbiAgICAgICAgaG9vay53YXJuaW5nTG9nID0gdGhpcy53YXJuaW5nTG9nO1xuXG4gICAgICAgIGhvb2suX2luc3RhbnRpYXRlUmVxdWVzdEZpbHRlclJ1bGVzKCk7XG4gICAgICAgIGhvb2suX2luc3RhbnRpYXRlZFJlcXVlc3RGaWx0ZXJSdWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmFkZFJlcXVlc3RFdmVudExpc3RlbmVycyhydWxlLCB7XG4gICAgICAgICAgICAgICAgb25SZXF1ZXN0OiAgICAgICAgICAgaG9vay5vblJlcXVlc3QuYmluZChob29rKSxcbiAgICAgICAgICAgICAgICBvbkNvbmZpZ3VyZVJlc3BvbnNlOiBob29rLl9vbkNvbmZpZ3VyZVJlc3BvbnNlLmJpbmQoaG9vayksXG4gICAgICAgICAgICAgICAgb25SZXNwb25zZTogICAgICAgICAgaG9vay5vblJlc3BvbnNlLmJpbmQoaG9vaylcbiAgICAgICAgICAgIH0sIGVyciA9PiB0aGlzLl9vblJlcXVlc3RIb29rTWV0aG9kRXJyb3IoZXJyLCBob29rKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9vblJlcXVlc3RIb29rTWV0aG9kRXJyb3IgKGV2ZW50LCBob29rKSB7XG4gICAgICAgIGxldCBlcnIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gZXZlbnQuZXJyb3I7XG4gICAgICAgIGNvbnN0IGlzUmVxdWVzdEhvb2tOb3RJbXBsZW1lbnRlZE1ldGhvZEVycm9yID0gZXJyIGluc3RhbmNlb2YgUmVxdWVzdEhvb2tOb3RJbXBsZW1lbnRlZE1ldGhvZEVycm9yO1xuXG4gICAgICAgIGlmICghaXNSZXF1ZXN0SG9va05vdEltcGxlbWVudGVkTWV0aG9kRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IGhvb2tDbGFzc05hbWUgPSBob29rLmNvbnN0cnVjdG9yLm5hbWU7XG5cbiAgICAgICAgICAgIGVyciA9IG5ldyBSZXF1ZXN0SG9va1VuaGFuZGxlZEVycm9yKGVyciwgaG9va0NsYXNzTmFtZSwgZXZlbnQubWV0aG9kTmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFkZEVycm9yKGVycik7XG4gICAgfVxuXG4gICAgX2Rpc3Bvc2VSZXF1ZXN0SG9vayAoaG9vaykge1xuICAgICAgICBob29rLndhcm5pbmdMb2cgPSBudWxsO1xuXG4gICAgICAgIGhvb2suX2luc3RhbnRpYXRlZFJlcXVlc3RGaWx0ZXJSdWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnJlbW92ZVJlcXVlc3RFdmVudExpc3RlbmVycyhydWxlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2luaXRSZXF1ZXN0SG9va3MgKCkge1xuICAgICAgICB0aGlzLnJlcXVlc3RIb29rcyA9IEFycmF5LmZyb20odGhpcy50ZXN0LnJlcXVlc3RIb29rcyk7XG5cbiAgICAgICAgdGhpcy5yZXF1ZXN0SG9va3MuZm9yRWFjaChob29rID0+IHRoaXMuX2luaXRSZXF1ZXN0SG9vayhob29rKSk7XG4gICAgfVxuXG4gICAgLy8gSGFtbWVyaGVhZCBwYXlsb2FkXG4gICAgX2dldFBheWxvYWRTY3JpcHQgKCkge1xuICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgICAgICAgICAgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSA9IG51bGw7XG5cbiAgICAgICAgcmV0dXJuIE11c3RhY2hlLnJlbmRlcihURVNUX1JVTl9URU1QTEFURSwge1xuICAgICAgICAgICAgdGVzdFJ1bklkOiAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5zZXNzaW9uLmlkKSxcbiAgICAgICAgICAgIGJyb3dzZXJJZDogICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uaWQpLFxuICAgICAgICAgICAgYnJvd3NlckhlYXJ0YmVhdFJlbGF0aXZlVXJsOiAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi5oZWFydGJlYXRSZWxhdGl2ZVVybCksXG4gICAgICAgICAgICBicm93c2VyU3RhdHVzUmVsYXRpdmVVcmw6ICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnN0YXR1c1JlbGF0aXZlVXJsKSxcbiAgICAgICAgICAgIGJyb3dzZXJTdGF0dXNEb25lUmVsYXRpdmVVcmw6IEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uc3RhdHVzRG9uZVJlbGF0aXZlVXJsKSxcbiAgICAgICAgICAgIGJyb3dzZXJBY3RpdmVXaW5kb3dJZFVybDogICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uYWN0aXZlV2luZG93SWRVcmwpLFxuICAgICAgICAgICAgdXNlckFnZW50OiAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi51c2VyQWdlbnQpLFxuICAgICAgICAgICAgdGVzdE5hbWU6ICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy50ZXN0Lm5hbWUpLFxuICAgICAgICAgICAgZml4dHVyZU5hbWU6ICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy50ZXN0LmZpeHR1cmUubmFtZSksXG4gICAgICAgICAgICBzZWxlY3RvclRpbWVvdXQ6ICAgICAgICAgICAgICB0aGlzLm9wdHMuc2VsZWN0b3JUaW1lb3V0LFxuICAgICAgICAgICAgcGFnZUxvYWRUaW1lb3V0OiAgICAgICAgICAgICAgdGhpcy5wYWdlTG9hZFRpbWVvdXQsXG4gICAgICAgICAgICBjaGlsZFdpbmRvd1JlYWR5VGltZW91dDogICAgICBDSElMRF9XSU5ET1dfUkVBRFlfVElNRU9VVCxcbiAgICAgICAgICAgIHNraXBKc0Vycm9yczogICAgICAgICAgICAgICAgIHRoaXMub3B0cy5za2lwSnNFcnJvcnMsXG4gICAgICAgICAgICByZXRyeVRlc3RQYWdlczogICAgICAgICAgICAgICB0aGlzLm9wdHMucmV0cnlUZXN0UGFnZXMsXG4gICAgICAgICAgICBzcGVlZDogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNwZWVkLFxuICAgICAgICAgICAgZGlhbG9nSGFuZGxlcjogICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5hY3RpdmVEaWFsb2dIYW5kbGVyKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfZ2V0SWZyYW1lUGF5bG9hZFNjcmlwdCAoKSB7XG4gICAgICAgIHJldHVybiBNdXN0YWNoZS5yZW5kZXIoSUZSQU1FX1RFU1RfUlVOX1RFTVBMQVRFLCB7XG4gICAgICAgICAgICB0ZXN0UnVuSWQ6ICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuc2Vzc2lvbi5pZCksXG4gICAgICAgICAgICBzZWxlY3RvclRpbWVvdXQ6IHRoaXMub3B0cy5zZWxlY3RvclRpbWVvdXQsXG4gICAgICAgICAgICBwYWdlTG9hZFRpbWVvdXQ6IHRoaXMucGFnZUxvYWRUaW1lb3V0LFxuICAgICAgICAgICAgcmV0cnlUZXN0UGFnZXM6ICAhIXRoaXMub3B0cy5yZXRyeVRlc3RQYWdlcyxcbiAgICAgICAgICAgIHNwZWVkOiAgICAgICAgICAgdGhpcy5zcGVlZCxcbiAgICAgICAgICAgIGRpYWxvZ0hhbmRsZXI6ICAgSlNPTi5zdHJpbmdpZnkodGhpcy5hY3RpdmVEaWFsb2dIYW5kbGVyKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBIYW1tZXJoZWFkIGhhbmRsZXJzXG4gICAgZ2V0QXV0aENyZWRlbnRpYWxzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdC5hdXRoQ3JlZGVudGlhbHM7XG4gICAgfVxuXG4gICAgaGFuZGxlRmlsZURvd25sb2FkICgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlKSB7XG4gICAgICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSh0cnVlKTtcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGhhbmRsZVBhZ2VFcnJvciAoY3R4LCBlcnIpIHtcbiAgICAgICAgaWYgKGN0eC5yZXEuaGVhZGVyc1tVTlNUQUJMRV9ORVRXT1JLX01PREVfSEVBREVSXSkge1xuICAgICAgICAgICAgY3R4LmNsb3NlV2l0aEVycm9yKDUwMCwgZXJyLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gbmV3IFBhZ2VMb2FkRXJyb3IoZXJyLCBjdHgucmVxT3B0cy51cmwpO1xuXG4gICAgICAgIGN0eC5yZWRpcmVjdChjdHgudG9Qcm94eVVybChTUEVDSUFMX0VSUk9SX1BBR0UpKTtcbiAgICB9XG5cbiAgICAvLyBUZXN0IGZ1bmN0aW9uIGV4ZWN1dGlvblxuICAgIGFzeW5jIF9leGVjdXRlVGVzdEZuIChwaGFzZSwgZm4pIHtcbiAgICAgICAgdGhpcy5waGFzZSA9IHBoYXNlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBmbih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBsZXQgc2NyZWVuc2hvdFBhdGggPSBudWxsO1xuXG4gICAgICAgICAgICBjb25zdCB7IHNjcmVlbnNob3RzIH0gPSB0aGlzLm9wdHM7XG5cbiAgICAgICAgICAgIGlmIChzY3JlZW5zaG90cyAmJiBzY3JlZW5zaG90cy50YWtlT25GYWlscylcbiAgICAgICAgICAgICAgICBzY3JlZW5zaG90UGF0aCA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQobmV3IGJyb3dzZXJNYW5pcHVsYXRpb25Db21tYW5kcy5UYWtlU2NyZWVuc2hvdE9uRmFpbENvbW1hbmQoKSk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkRXJyb3IoZXJyLCBzY3JlZW5zaG90UGF0aCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gIXRoaXMuX2FkZFBlbmRpbmdQYWdlRXJyb3JJZkFueSgpO1xuICAgIH1cblxuICAgIGFzeW5jIF9ydW5CZWZvcmVIb29rICgpIHtcbiAgICAgICAgaWYgKHRoaXMudGVzdC5iZWZvcmVGbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9leGVjdXRlVGVzdEZuKFBIQVNFLmluVGVzdEJlZm9yZUhvb2ssIHRoaXMudGVzdC5iZWZvcmVGbik7XG5cbiAgICAgICAgaWYgKHRoaXMudGVzdC5maXh0dXJlLmJlZm9yZUVhY2hGbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9leGVjdXRlVGVzdEZuKFBIQVNFLmluRml4dHVyZUJlZm9yZUVhY2hIb29rLCB0aGlzLnRlc3QuZml4dHVyZS5iZWZvcmVFYWNoRm4pO1xuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGFzeW5jIF9ydW5BZnRlckhvb2sgKCkge1xuICAgICAgICBpZiAodGhpcy50ZXN0LmFmdGVyRm4pXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZXhlY3V0ZVRlc3RGbihQSEFTRS5pblRlc3RBZnRlckhvb2ssIHRoaXMudGVzdC5hZnRlckZuKTtcblxuICAgICAgICBpZiAodGhpcy50ZXN0LmZpeHR1cmUuYWZ0ZXJFYWNoRm4pXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZXhlY3V0ZVRlc3RGbihQSEFTRS5pbkZpeHR1cmVBZnRlckVhY2hIb29rLCB0aGlzLnRlc3QuZml4dHVyZS5hZnRlckVhY2hGbik7XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgYXN5bmMgc3RhcnQgKCkge1xuICAgICAgICB0ZXN0UnVuVHJhY2tlci5hY3RpdmVUZXN0UnVuc1t0aGlzLnNlc3Npb24uaWRdID0gdGhpcztcblxuICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3N0YXJ0Jyk7XG5cbiAgICAgICAgY29uc3Qgb25EaXNjb25uZWN0ZWQgPSBlcnIgPT4gdGhpcy5fZGlzY29ubmVjdChlcnIpO1xuXG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb24ub25jZSgnZGlzY29ubmVjdGVkJywgb25EaXNjb25uZWN0ZWQpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMub25jZSgnY29ubmVjdGVkJyk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdyZWFkeScpO1xuXG4gICAgICAgIGlmIChhd2FpdCB0aGlzLl9ydW5CZWZvcmVIb29rKCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2V4ZWN1dGVUZXN0Rm4oUEhBU0UuaW5UZXN0LCB0aGlzLnRlc3QuZm4pO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fcnVuQWZ0ZXJIb29rKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kaXNjb25uZWN0ZWQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbi5yZW1vdmVMaXN0ZW5lcignZGlzY29ubmVjdGVkJywgb25EaXNjb25uZWN0ZWQpO1xuXG4gICAgICAgIGlmICh0aGlzLmVycnMubGVuZ3RoICYmIHRoaXMuZGVidWdPbkZhaWwpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9lbnF1ZXVlU2V0QnJlYWtwb2ludENvbW1hbmQobnVsbCwgdGhpcy5kZWJ1Z1JlcG9ydGVyUGx1Z2luSG9zdC5mb3JtYXRFcnJvcih0aGlzLmVycnNbMF0pKTtcblxuICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ2JlZm9yZS1kb25lJyk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChuZXcgc2VydmljZUNvbW1hbmRzLlRlc3REb25lQ29tbWFuZCgpKTtcblxuICAgICAgICB0aGlzLl9hZGRQZW5kaW5nUGFnZUVycm9ySWZBbnkoKTtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmNsZWFyUmVxdWVzdEV2ZW50TGlzdGVuZXJzKCk7XG4gICAgICAgIHRoaXMubm9ybWFsaXplUmVxdWVzdEhvb2tFcnJvcnMoKTtcblxuICAgICAgICBkZWxldGUgdGVzdFJ1blRyYWNrZXIuYWN0aXZlVGVzdFJ1bnNbdGhpcy5zZXNzaW9uLmlkXTtcblxuICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ2RvbmUnKTtcbiAgICB9XG5cbiAgICAvLyBFcnJvcnNcbiAgICBfYWRkUGVuZGluZ1BhZ2VFcnJvcklmQW55ICgpIHtcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ1BhZ2VFcnJvcikge1xuICAgICAgICAgICAgdGhpcy5hZGRFcnJvcih0aGlzLnBlbmRpbmdQYWdlRXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIF9jcmVhdGVFcnJvckFkYXB0ZXIgKGVyciwgc2NyZWVuc2hvdFBhdGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXN0UnVuRXJyb3JGb3JtYXR0YWJsZUFkYXB0ZXIoZXJyLCB7XG4gICAgICAgICAgICB1c2VyQWdlbnQ6ICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbi51c2VyQWdlbnQsXG4gICAgICAgICAgICBzY3JlZW5zaG90UGF0aDogc2NyZWVuc2hvdFBhdGggfHwgJycsXG4gICAgICAgICAgICB0ZXN0UnVuUGhhc2U6ICAgdGhpcy5waGFzZVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRFcnJvciAoZXJyLCBzY3JlZW5zaG90UGF0aCkge1xuICAgICAgICBjb25zdCBlcnJMaXN0ID0gZXJyIGluc3RhbmNlb2YgVGVzdENhZmVFcnJvckxpc3QgPyBlcnIuaXRlbXMgOiBbZXJyXTtcblxuICAgICAgICBlcnJMaXN0LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5fY3JlYXRlRXJyb3JBZGFwdGVyKGl0ZW0sIHNjcmVlbnNob3RQYXRoKTtcblxuICAgICAgICAgICAgdGhpcy5lcnJzLnB1c2goYWRhcHRlcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5vcm1hbGl6ZVJlcXVlc3RIb29rRXJyb3JzICgpIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdEhvb2tFcnJvcnMgPSByZW1vdmUodGhpcy5lcnJzLCBlID0+XG4gICAgICAgICAgICBlLmNvZGUgPT09IFRFU1RfUlVOX0VSUk9SUy5yZXF1ZXN0SG9va05vdEltcGxlbWVudGVkRXJyb3IgfHxcbiAgICAgICAgICAgIGUuY29kZSA9PT0gVEVTVF9SVU5fRVJST1JTLnJlcXVlc3RIb29rVW5oYW5kbGVkRXJyb3IpO1xuXG4gICAgICAgIGlmICghcmVxdWVzdEhvb2tFcnJvcnMubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHVuaXFSZXF1ZXN0SG9va0Vycm9ycyA9IGNoYWluKHJlcXVlc3RIb29rRXJyb3JzKVxuICAgICAgICAgICAgLnVuaXFCeShlID0+IGUuaG9va0NsYXNzTmFtZSArIGUubWV0aG9kTmFtZSlcbiAgICAgICAgICAgIC5zb3J0QnkoWydob29rQ2xhc3NOYW1lJywgJ21ldGhvZE5hbWUnXSlcbiAgICAgICAgICAgIC52YWx1ZSgpO1xuXG4gICAgICAgIHRoaXMuZXJycyA9IHRoaXMuZXJycy5jb25jYXQodW5pcVJlcXVlc3RIb29rRXJyb3JzKTtcbiAgICB9XG5cbiAgICAvLyBUYXNrIHF1ZXVlXG4gICAgX2VucXVldWVDb21tYW5kIChjb21tYW5kLCBjYWxsc2l0ZSkge1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nUmVxdWVzdClcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVQZW5kaW5nUmVxdWVzdChjb21tYW5kKTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50LS07XG4gICAgICAgICAgICB0aGlzLmRyaXZlclRhc2tRdWV1ZS5wdXNoKHsgY29tbWFuZCwgcmVzb2x2ZSwgcmVqZWN0LCBjYWxsc2l0ZSB9KTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmFkZGluZ0RyaXZlclRhc2tzQ291bnQpXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KEFMTF9EUklWRVJfVEFTS1NfQURERURfVE9fUVVFVUVfRVZFTlQsIHRoaXMuZHJpdmVyVGFza1F1ZXVlLmxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldCBkcml2ZXJUYXNrUXVldWVMZW5ndGggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50ID8gcHJvbWlzaWZ5RXZlbnQodGhpcywgQUxMX0RSSVZFUl9UQVNLU19BRERFRF9UT19RVUVVRV9FVkVOVCkgOiBQcm9taXNlLnJlc29sdmUodGhpcy5kcml2ZXJUYXNrUXVldWUubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBhc3luYyBfZW5xdWV1ZUJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kIChjb21tYW5kLCBjYWxsc2l0ZSkge1xuICAgICAgICBhd2FpdCB0aGlzLl9lbnF1ZXVlQ29tbWFuZChjb21tYW5kLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgY29uc3QgY29uc29sZU1lc3NhZ2VDb3B5ID0gdGhpcy5jb25zb2xlTWVzc2FnZXMuZ2V0Q29weSgpO1xuXG4gICAgICAgIHJldHVybiBjb25zb2xlTWVzc2FnZUNvcHlbdGhpcy5icm93c2VyQ29ubmVjdGlvbi5hY3RpdmVXaW5kb3dJZF07XG4gICAgfVxuXG4gICAgYXN5bmMgX2VucXVldWVTZXRCcmVha3BvaW50Q29tbWFuZCAoY2FsbHNpdGUsIGVycm9yKSB7XG4gICAgICAgIGlmICh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmlzSGVhZGxlc3NCcm93c2VyKCkpIHtcbiAgICAgICAgICAgIHRoaXMud2FybmluZ0xvZy5hZGRXYXJuaW5nKFdBUk5JTkdfTUVTU0FHRS5kZWJ1Z0luSGVhZGxlc3NFcnJvcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kZWJ1Z0xvZ2dlcilcbiAgICAgICAgICAgIHRoaXMuZGVidWdMb2dnZXIuc2hvd0JyZWFrcG9pbnQodGhpcy5zZXNzaW9uLmlkLCB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnVzZXJBZ2VudCwgY2FsbHNpdGUsIGVycm9yKTtcblxuICAgICAgICB0aGlzLmRlYnVnZ2luZyA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQobmV3IHNlcnZpY2VDb21tYW5kcy5TZXRCcmVha3BvaW50Q29tbWFuZCghIWVycm9yKSwgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIF9yZW1vdmVBbGxOb25TZXJ2aWNlVGFza3MgKCkge1xuICAgICAgICB0aGlzLmRyaXZlclRhc2tRdWV1ZSA9IHRoaXMuZHJpdmVyVGFza1F1ZXVlLmZpbHRlcihkcml2ZXJUYXNrID0+IGlzU2VydmljZUNvbW1hbmQoZHJpdmVyVGFzay5jb21tYW5kKSk7XG5cbiAgICAgICAgdGhpcy5icm93c2VyTWFuaXB1bGF0aW9uUXVldWUucmVtb3ZlQWxsTm9uU2VydmljZU1hbmlwdWxhdGlvbnMoKTtcbiAgICB9XG5cbiAgICAvLyBDdXJyZW50IGRyaXZlciB0YXNrXG4gICAgZ2V0IGN1cnJlbnREcml2ZXJUYXNrICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZHJpdmVyVGFza1F1ZXVlWzBdO1xuICAgIH1cblxuICAgIF9yZXNvbHZlQ3VycmVudERyaXZlclRhc2sgKHJlc3VsdCkge1xuICAgICAgICB0aGlzLmN1cnJlbnREcml2ZXJUYXNrLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgdGhpcy5kcml2ZXJUYXNrUXVldWUuc2hpZnQoKTtcblxuICAgICAgICBpZiAodGhpcy50ZXN0RG9uZUNvbW1hbmRRdWV1ZWQpXG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVBbGxOb25TZXJ2aWNlVGFza3MoKTtcbiAgICB9XG5cbiAgICBfcmVqZWN0Q3VycmVudERyaXZlclRhc2sgKGVycikge1xuICAgICAgICBlcnIuY2FsbHNpdGUgPSBlcnIuY2FsbHNpdGUgfHwgdGhpcy5jdXJyZW50RHJpdmVyVGFzay5jYWxsc2l0ZTtcblxuICAgICAgICB0aGlzLmN1cnJlbnREcml2ZXJUYXNrLnJlamVjdChlcnIpO1xuICAgICAgICB0aGlzLl9yZW1vdmVBbGxOb25TZXJ2aWNlVGFza3MoKTtcbiAgICB9XG5cbiAgICAvLyBQZW5kaW5nIHJlcXVlc3RcbiAgICBfY2xlYXJQZW5kaW5nUmVxdWVzdCAoKSB7XG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdSZXF1ZXN0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZW5kaW5nUmVxdWVzdC5yZXNwb25zZVRpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcmVzb2x2ZVBlbmRpbmdSZXF1ZXN0IChjb21tYW5kKSB7XG4gICAgICAgIHRoaXMubGFzdERyaXZlclN0YXR1c1Jlc3BvbnNlID0gY29tbWFuZDtcbiAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdC5yZXNvbHZlKGNvbW1hbmQpO1xuICAgICAgICB0aGlzLl9jbGVhclBlbmRpbmdSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGRyaXZlciByZXF1ZXN0XG4gICAgX2Z1bGZpbGxDdXJyZW50RHJpdmVyVGFzayAoZHJpdmVyU3RhdHVzKSB7XG4gICAgICAgIGlmICghdGhpcy5jdXJyZW50RHJpdmVyVGFzaylcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBpZiAoZHJpdmVyU3RhdHVzLmV4ZWN1dGlvbkVycm9yKVxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0Q3VycmVudERyaXZlclRhc2soZHJpdmVyU3RhdHVzLmV4ZWN1dGlvbkVycm9yKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZUN1cnJlbnREcml2ZXJUYXNrKGRyaXZlclN0YXR1cy5yZXN1bHQpO1xuICAgIH1cblxuICAgIF9oYW5kbGVQYWdlRXJyb3JTdGF0dXMgKHBhZ2VFcnJvcikge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50RHJpdmVyVGFzayAmJiBpc0NvbW1hbmRSZWplY3RhYmxlQnlQYWdlRXJyb3IodGhpcy5jdXJyZW50RHJpdmVyVGFzay5jb21tYW5kKSkge1xuICAgICAgICAgICAgdGhpcy5fcmVqZWN0Q3VycmVudERyaXZlclRhc2socGFnZUVycm9yKTtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1BhZ2VFcnJvciA9IG51bGw7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gdGhpcy5wZW5kaW5nUGFnZUVycm9yIHx8IHBhZ2VFcnJvcjtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgX2hhbmRsZURyaXZlclJlcXVlc3QgKGRyaXZlclN0YXR1cykge1xuICAgICAgICBjb25zdCBpc1Rlc3REb25lICAgICAgICAgICAgICAgICA9IHRoaXMuY3VycmVudERyaXZlclRhc2sgJiYgdGhpcy5jdXJyZW50RHJpdmVyVGFzay5jb21tYW5kLnR5cGUgPT09XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NTUFORF9UWVBFLnRlc3REb25lO1xuICAgICAgICBjb25zdCBwYWdlRXJyb3IgICAgICAgICAgICAgICAgICA9IHRoaXMucGVuZGluZ1BhZ2VFcnJvciB8fCBkcml2ZXJTdGF0dXMucGFnZUVycm9yO1xuICAgICAgICBjb25zdCBjdXJyZW50VGFza1JlamVjdGVkQnlFcnJvciA9IHBhZ2VFcnJvciAmJiB0aGlzLl9oYW5kbGVQYWdlRXJyb3JTdGF0dXMocGFnZUVycm9yKTtcblxuICAgICAgICBpZiAodGhpcy5kaXNjb25uZWN0ZWQpXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKF8sIHJlamVjdCkgPT4gcmVqZWN0KCkpO1xuXG4gICAgICAgIHRoaXMuY29uc29sZU1lc3NhZ2VzLmNvbmNhdChkcml2ZXJTdGF0dXMuY29uc29sZU1lc3NhZ2VzKTtcblxuICAgICAgICBpZiAoIWN1cnJlbnRUYXNrUmVqZWN0ZWRCeUVycm9yICYmIGRyaXZlclN0YXR1cy5pc0NvbW1hbmRSZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChpc1Rlc3REb25lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZUN1cnJlbnREcml2ZXJUYXNrKCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gVEVTVF9ET05FX0NPTkZJUk1BVElPTl9SRVNQT05TRTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fZnVsZmlsbEN1cnJlbnREcml2ZXJUYXNrKGRyaXZlclN0YXR1cyk7XG5cbiAgICAgICAgICAgIGlmIChkcml2ZXJTdGF0dXMuaXNQZW5kaW5nV2luZG93U3dpdGNoaW5nKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEN1cnJlbnREcml2ZXJUYXNrQ29tbWFuZCgpO1xuICAgIH1cblxuICAgIF9nZXRDdXJyZW50RHJpdmVyVGFza0NvbW1hbmQgKCkge1xuICAgICAgICBpZiAoIXRoaXMuY3VycmVudERyaXZlclRhc2spXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCBjb21tYW5kID0gdGhpcy5jdXJyZW50RHJpdmVyVGFzay5jb21tYW5kO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5uYXZpZ2F0ZVRvICYmIGNvbW1hbmQuc3RhdGVTbmFwc2hvdClcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi51c2VTdGF0ZVNuYXBzaG90KEpTT04ucGFyc2UoY29tbWFuZC5zdGF0ZVNuYXBzaG90KSk7XG5cbiAgICAgICAgcmV0dXJuIGNvbW1hbmQ7XG4gICAgfVxuXG4gICAgLy8gRXhlY3V0ZSBjb21tYW5kXG4gICAgX2V4ZWN1dGVKc0V4cHJlc3Npb24gKGNvbW1hbmQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0VmFyaWFibGVOYW1lID0gY29tbWFuZC5yZXN1bHRWYXJpYWJsZU5hbWU7XG4gICAgICAgIGxldCBleHByZXNzaW9uICAgICAgICAgICA9IGNvbW1hbmQuZXhwcmVzc2lvbjtcblxuICAgICAgICBpZiAocmVzdWx0VmFyaWFibGVOYW1lKVxuICAgICAgICAgICAgZXhwcmVzc2lvbiA9IGAke3Jlc3VsdFZhcmlhYmxlTmFtZX0gPSAke2V4cHJlc3Npb259LCAke3Jlc3VsdFZhcmlhYmxlTmFtZX1gO1xuXG4gICAgICAgIHJldHVybiBleGVjdXRlSnNFeHByZXNzaW9uKGV4cHJlc3Npb24sIHRoaXMsIHsgc2tpcFZpc2liaWxpdHlDaGVjazogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2V4ZWN1dGVBc3NlcnRpb24gKGNvbW1hbmQsIGNhbGxzaXRlKSB7XG4gICAgICAgIGNvbnN0IGFzc2VydGlvblRpbWVvdXQgPSBjb21tYW5kLm9wdGlvbnMudGltZW91dCA9PT1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgMCA/IHRoaXMub3B0cy5hc3NlcnRpb25UaW1lb3V0IDogY29tbWFuZC5vcHRpb25zLnRpbWVvdXQ7XG4gICAgICAgIGNvbnN0IGV4ZWN1dG9yICAgICAgICAgPSBuZXcgQXNzZXJ0aW9uRXhlY3V0b3IoY29tbWFuZCwgYXNzZXJ0aW9uVGltZW91dCwgY2FsbHNpdGUpO1xuXG4gICAgICAgIGV4ZWN1dG9yLm9uY2UoJ3N0YXJ0LWFzc2VydGlvbi1yZXRyaWVzJywgdGltZW91dCA9PiB0aGlzLmV4ZWN1dGVDb21tYW5kKG5ldyBzZXJ2aWNlQ29tbWFuZHMuU2hvd0Fzc2VydGlvblJldHJpZXNTdGF0dXNDb21tYW5kKHRpbWVvdXQpKSk7XG4gICAgICAgIGV4ZWN1dG9yLm9uY2UoJ2VuZC1hc3NlcnRpb24tcmV0cmllcycsIHN1Y2Nlc3MgPT4gdGhpcy5leGVjdXRlQ29tbWFuZChuZXcgc2VydmljZUNvbW1hbmRzLkhpZGVBc3NlcnRpb25SZXRyaWVzU3RhdHVzQ29tbWFuZChzdWNjZXNzKSkpO1xuXG4gICAgICAgIGNvbnN0IGV4ZWN1dGVGbiA9IHRoaXMuZGVjb3JhdGVQcmV2ZW50RW1pdEFjdGlvbkV2ZW50cygoKSA9PiBleGVjdXRvci5ydW4oKSwgeyBwcmV2ZW50OiB0cnVlIH0pO1xuXG4gICAgICAgIHJldHVybiBhd2FpdCBleGVjdXRlRm4oKTtcbiAgICB9XG5cbiAgICBfYWRqdXN0Q29uZmlndXJhdGlvbldpdGhDb21tYW5kIChjb21tYW5kKSB7XG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS50ZXN0RG9uZSkge1xuICAgICAgICAgICAgdGhpcy50ZXN0RG9uZUNvbW1hbmRRdWV1ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVidWdMb2dnZXIpXG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlci5oaWRlQnJlYWtwb2ludCh0aGlzLnNlc3Npb24uaWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuc2V0TmF0aXZlRGlhbG9nSGFuZGxlcilcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlRGlhbG9nSGFuZGxlciA9IGNvbW1hbmQuZGlhbG9nSGFuZGxlcjtcblxuICAgICAgICBlbHNlIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5zd2l0Y2hUb0lmcmFtZSlcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlSWZyYW1lU2VsZWN0b3IgPSBjb21tYW5kLnNlbGVjdG9yO1xuXG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnN3aXRjaFRvTWFpbldpbmRvdylcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlSWZyYW1lU2VsZWN0b3IgPSBudWxsO1xuXG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnNldFRlc3RTcGVlZClcbiAgICAgICAgICAgIHRoaXMuc3BlZWQgPSBjb21tYW5kLnNwZWVkO1xuXG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnNldFBhZ2VMb2FkVGltZW91dClcbiAgICAgICAgICAgIHRoaXMucGFnZUxvYWRUaW1lb3V0ID0gY29tbWFuZC5kdXJhdGlvbjtcblxuICAgICAgICBlbHNlIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5kZWJ1ZylcbiAgICAgICAgICAgIHRoaXMuZGVidWdnaW5nID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBhc3luYyBfYWRqdXN0U2NyZWVuc2hvdENvbW1hbmQgKGNvbW1hbmQpIHtcbiAgICAgICAgY29uc3QgYnJvd3NlcklkICAgICAgICAgICAgICAgICAgICA9IHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uaWQ7XG4gICAgICAgIGNvbnN0IHsgaGFzQ2hyb21lbGVzc1NjcmVlbnNob3RzIH0gPSBhd2FpdCB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnByb3ZpZGVyLmhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIoYnJvd3NlcklkKTtcblxuICAgICAgICBpZiAoIWhhc0Nocm9tZWxlc3NTY3JlZW5zaG90cylcbiAgICAgICAgICAgIGNvbW1hbmQuZ2VuZXJhdGVTY3JlZW5zaG90TWFyaygpO1xuICAgIH1cblxuICAgIGFzeW5jIF9zZXRCcmVha3BvaW50SWZOZWNlc3NhcnkgKGNvbW1hbmQsIGNhbGxzaXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5kaXNhYmxlRGVidWdCcmVha3BvaW50cyAmJiB0aGlzLmRlYnVnZ2luZyAmJiBjYW5TZXREZWJ1Z2dlckJyZWFrcG9pbnRCZWZvcmVDb21tYW5kKGNvbW1hbmQpKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5fZW5xdWV1ZVNldEJyZWFrcG9pbnRDb21tYW5kKGNhbGxzaXRlKTtcbiAgICB9XG5cbiAgICBhc3luYyBleGVjdXRlQWN0aW9uIChhY3Rpb25OYW1lLCBjb21tYW5kLCBjYWxsc2l0ZSkge1xuICAgICAgICBsZXQgZXJyb3IgID0gbnVsbDtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG51bGw7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0QWN0aW9uU3RhcnQoYWN0aW9uTmFtZSwgY29tbWFuZCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0QWN0aW9uRG9uZShhY3Rpb25OYW1lLCBjb21tYW5kLCBlcnJvcik7XG5cbiAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBhc3luYyBleGVjdXRlQ29tbWFuZCAoY29tbWFuZCwgY2FsbHNpdGUpIHtcbiAgICAgICAgdGhpcy5kZWJ1Z0xvZy5jb21tYW5kKGNvbW1hbmQpO1xuXG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdQYWdlRXJyb3IgJiYgaXNDb21tYW5kUmVqZWN0YWJsZUJ5UGFnZUVycm9yKGNvbW1hbmQpKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdENvbW1hbmRXaXRoUGFnZUVycm9yKGNhbGxzaXRlKTtcblxuICAgICAgICBpZiAoaXNFeGVjdXRhYmxlT25DbGllbnRDb21tYW5kKGNvbW1hbmQpKVxuICAgICAgICAgICAgdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50Kys7XG5cbiAgICAgICAgdGhpcy5fYWRqdXN0Q29uZmlndXJhdGlvbldpdGhDb21tYW5kKGNvbW1hbmQpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX3NldEJyZWFrcG9pbnRJZk5lY2Vzc2FyeShjb21tYW5kLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgaWYgKGlzU2NyZWVuc2hvdENvbW1hbmQoY29tbWFuZCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuZGlzYWJsZVNjcmVlbnNob3RzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53YXJuaW5nTG9nLmFkZFdhcm5pbmcoV0FSTklOR19NRVNTQUdFLnNjcmVlbnNob3RzRGlzYWJsZWQpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2FkanVzdFNjcmVlbnNob3RDb21tYW5kKGNvbW1hbmQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQnJvd3Nlck1hbmlwdWxhdGlvbkNvbW1hbmQoY29tbWFuZCkpIHtcbiAgICAgICAgICAgIHRoaXMuYnJvd3Nlck1hbmlwdWxhdGlvblF1ZXVlLnB1c2goY29tbWFuZCk7XG5cbiAgICAgICAgICAgIGlmIChpc1Jlc2l6ZVdpbmRvd0NvbW1hbmQoY29tbWFuZCkgJiYgdGhpcy5vcHRzLnZpZGVvUGF0aClcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyhXQVJOSU5HX01FU1NBR0UudmlkZW9Ccm93c2VyUmVzaXppbmcsIHRoaXMudGVzdC5uYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS53YWl0KVxuICAgICAgICAgICAgcmV0dXJuIGRlbGF5KGNvbW1hbmQudGltZW91dCk7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnNldFBhZ2VMb2FkVGltZW91dClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5kZWJ1ZylcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9lbnF1ZXVlU2V0QnJlYWtwb2ludENvbW1hbmQoY2FsbHNpdGUpO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS51c2VSb2xlKSB7XG4gICAgICAgICAgICBsZXQgZm4gPSAoKSA9PiB0aGlzLl91c2VSb2xlKGNvbW1hbmQucm9sZSwgY2FsbHNpdGUpO1xuXG4gICAgICAgICAgICBmbiA9IHRoaXMuZGVjb3JhdGVQcmV2ZW50RW1pdEFjdGlvbkV2ZW50cyhmbiwgeyBwcmV2ZW50OiB0cnVlIH0pO1xuICAgICAgICAgICAgZm4gPSB0aGlzLmRlY29yYXRlRGlzYWJsZURlYnVnQnJlYWtwb2ludHMoZm4sIHsgZGlzYWJsZTogdHJ1ZSB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuYXNzZXJ0aW9uKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4ZWN1dGVBc3NlcnRpb24oY29tbWFuZCwgY2FsbHNpdGUpO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5leGVjdXRlRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9leGVjdXRlSnNFeHByZXNzaW9uKGNvbW1hbmQsIGNhbGxzaXRlKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuZXhlY3V0ZUFzeW5jRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBleGVjdXRlQXN5bmNKc0V4cHJlc3Npb24oY29tbWFuZC5leHByZXNzaW9uLCB0aGlzLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLmdldEJyb3dzZXJDb25zb2xlTWVzc2FnZXMpXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZW5xdWV1ZUJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIF9yZWplY3RDb21tYW5kV2l0aFBhZ2VFcnJvciAoY2FsbHNpdGUpIHtcbiAgICAgICAgY29uc3QgZXJyID0gdGhpcy5wZW5kaW5nUGFnZUVycm9yO1xuXG4gICAgICAgIGVyci5jYWxsc2l0ZSAgICAgICAgICA9IGNhbGxzaXRlO1xuICAgICAgICB0aGlzLnBlbmRpbmdQYWdlRXJyb3IgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuICAgIH1cblxuICAgIF9kZWNvcmF0ZVdpdGhGbGFnIChmbiwgZmxhZ05hbWUsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzW2ZsYWdOYW1lXSA9IHZhbHVlO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBmbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXNbZmxhZ05hbWVdID0gIXZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGRlY29yYXRlUHJldmVudEVtaXRBY3Rpb25FdmVudHMgKGZuLCB7IHByZXZlbnQgfSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb3JhdGVXaXRoRmxhZyhmbiwgJ3ByZXZlbnRFbWl0QWN0aW9uRXZlbnRzJywgcHJldmVudCk7XG4gICAgfVxuXG4gICAgZGVjb3JhdGVEaXNhYmxlRGVidWdCcmVha3BvaW50cyAoZm4sIHsgZGlzYWJsZSB9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNvcmF0ZVdpdGhGbGFnKGZuLCAnZGlzYWJsZURlYnVnQnJlYWtwb2ludHMnLCBkaXNhYmxlKTtcbiAgICB9XG5cbiAgICAvLyBSb2xlIG1hbmFnZW1lbnRcbiAgICBhc3luYyBnZXRTdGF0ZVNuYXBzaG90ICgpIHtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLnNlc3Npb24uZ2V0U3RhdGVTbmFwc2hvdCgpO1xuXG4gICAgICAgIHN0YXRlLnN0b3JhZ2VzID0gYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChuZXcgc2VydmljZUNvbW1hbmRzLkJhY2t1cFN0b3JhZ2VzQ29tbWFuZCgpKTtcblxuICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfVxuXG4gICAgYXN5bmMgc3dpdGNoVG9DbGVhblJ1biAodXJsKSB7XG4gICAgICAgIHRoaXMuY3R4ICAgICAgICAgICAgID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5maXh0dXJlQ3R4ICAgICAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLmNvbnNvbGVNZXNzYWdlcyA9IG5ldyBCcm93c2VyQ29uc29sZU1lc3NhZ2VzKCk7XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uLnVzZVN0YXRlU25hcHNob3QoU3RhdGVTbmFwc2hvdC5lbXB0eSgpKTtcblxuICAgICAgICBpZiAodGhpcy5zcGVlZCAhPT0gdGhpcy5vcHRzLnNwZWVkKSB7XG4gICAgICAgICAgICBjb25zdCBzZXRTcGVlZENvbW1hbmQgPSBuZXcgYWN0aW9uQ29tbWFuZHMuU2V0VGVzdFNwZWVkQ29tbWFuZCh7IHNwZWVkOiB0aGlzLm9wdHMuc3BlZWQgfSk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQoc2V0U3BlZWRDb21tYW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnBhZ2VMb2FkVGltZW91dCAhPT0gdGhpcy5vcHRzLnBhZ2VMb2FkVGltZW91dCkge1xuICAgICAgICAgICAgY29uc3Qgc2V0UGFnZUxvYWRUaW1lb3V0Q29tbWFuZCA9IG5ldyBhY3Rpb25Db21tYW5kcy5TZXRQYWdlTG9hZFRpbWVvdXRDb21tYW5kKHsgZHVyYXRpb246IHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQgfSk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQoc2V0UGFnZUxvYWRUaW1lb3V0Q29tbWFuZCk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLm5hdmlnYXRlVG9VcmwodXJsLCB0cnVlKTtcblxuICAgICAgICBpZiAodGhpcy5hY3RpdmVEaWFsb2dIYW5kbGVyKSB7XG4gICAgICAgICAgICBjb25zdCByZW1vdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCA9IG5ldyBhY3Rpb25Db21tYW5kcy5TZXROYXRpdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCh7IGRpYWxvZ0hhbmRsZXI6IHsgZm46IG51bGwgfSB9KTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChyZW1vdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBuYXZpZ2F0ZVRvVXJsICh1cmwsIGZvcmNlUmVsb2FkLCBzdGF0ZVNuYXBzaG90KSB7XG4gICAgICAgIGNvbnN0IG5hdmlnYXRlQ29tbWFuZCA9IG5ldyBOYXZpZ2F0ZVRvQ29tbWFuZCh7IHVybCwgZm9yY2VSZWxvYWQsIHN0YXRlU25hcHNob3QgfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChuYXZpZ2F0ZUNvbW1hbmQpO1xuICAgIH1cblxuICAgIGFzeW5jIF9nZXRTdGF0ZVNuYXBzaG90RnJvbVJvbGUgKHJvbGUpIHtcbiAgICAgICAgY29uc3QgcHJldlBoYXNlID0gdGhpcy5waGFzZTtcblxuICAgICAgICB0aGlzLnBoYXNlID0gUEhBU0UuaW5Sb2xlSW5pdGlhbGl6ZXI7XG5cbiAgICAgICAgaWYgKHJvbGUucGhhc2UgPT09IFJPTEVfUEhBU0UudW5pbml0aWFsaXplZClcbiAgICAgICAgICAgIGF3YWl0IHJvbGUuaW5pdGlhbGl6ZSh0aGlzKTtcblxuICAgICAgICBlbHNlIGlmIChyb2xlLnBoYXNlID09PSBST0xFX1BIQVNFLnBlbmRpbmdJbml0aWFsaXphdGlvbilcbiAgICAgICAgICAgIGF3YWl0IHByb21pc2lmeUV2ZW50KHJvbGUsICdpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIGlmIChyb2xlLmluaXRFcnIpXG4gICAgICAgICAgICB0aHJvdyByb2xlLmluaXRFcnI7XG5cbiAgICAgICAgdGhpcy5waGFzZSA9IHByZXZQaGFzZTtcblxuICAgICAgICByZXR1cm4gcm9sZS5zdGF0ZVNuYXBzaG90O1xuICAgIH1cblxuICAgIGFzeW5jIF91c2VSb2xlIChyb2xlLCBjYWxsc2l0ZSkge1xuICAgICAgICBpZiAodGhpcy5waGFzZSA9PT0gUEhBU0UuaW5Sb2xlSW5pdGlhbGl6ZXIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUm9sZVN3aXRjaEluUm9sZUluaXRpYWxpemVyRXJyb3IoY2FsbHNpdGUpO1xuXG4gICAgICAgIGNvbnN0IGJvb2ttYXJrID0gbmV3IFRlc3RSdW5Cb29rbWFyayh0aGlzLCByb2xlKTtcblxuICAgICAgICBhd2FpdCBib29rbWFyay5pbml0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFJvbGVJZClcbiAgICAgICAgICAgIHRoaXMudXNlZFJvbGVTdGF0ZXNbdGhpcy5jdXJyZW50Um9sZUlkXSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGVTbmFwc2hvdCgpO1xuXG4gICAgICAgIGNvbnN0IHN0YXRlU25hcHNob3QgPSB0aGlzLnVzZWRSb2xlU3RhdGVzW3JvbGUuaWRdIHx8IGF3YWl0IHRoaXMuX2dldFN0YXRlU25hcHNob3RGcm9tUm9sZShyb2xlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24udXNlU3RhdGVTbmFwc2hvdChzdGF0ZVNuYXBzaG90KTtcblxuICAgICAgICB0aGlzLmN1cnJlbnRSb2xlSWQgPSByb2xlLmlkO1xuXG4gICAgICAgIGF3YWl0IGJvb2ttYXJrLnJlc3RvcmUoY2FsbHNpdGUsIHN0YXRlU25hcHNob3QpO1xuICAgIH1cblxuICAgIC8vIEdldCBjdXJyZW50IFVSTFxuICAgIGFzeW5jIGdldEN1cnJlbnRVcmwgKCkge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gbmV3IENsaWVudEZ1bmN0aW9uQnVpbGRlcigoKSA9PiB7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICB9LCB7IGJvdW5kVGVzdFJ1bjogdGhpcyB9KTtcblxuICAgICAgICBjb25zdCBnZXRMb2NhdGlvbiA9IGJ1aWxkZXIuZ2V0RnVuY3Rpb24oKTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgZ2V0TG9jYXRpb24oKTtcbiAgICB9XG5cbiAgICBfZGlzY29ubmVjdCAoZXJyKSB7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcblxuICAgICAgICBpZiAodGhpcy5jdXJyZW50RHJpdmVyVGFzaylcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdEN1cnJlbnREcml2ZXJUYXNrKGVycik7XG5cbiAgICAgICAgdGhpcy5lbWl0KCdkaXNjb25uZWN0ZWQnLCBlcnIpO1xuXG4gICAgICAgIGRlbGV0ZSB0ZXN0UnVuVHJhY2tlci5hY3RpdmVUZXN0UnVuc1t0aGlzLnNlc3Npb24uaWRdO1xuICAgIH1cblxuICAgIGFzeW5jIGVtaXRBY3Rpb25TdGFydCAoYXBpQWN0aW9uTmFtZSwgY29tbWFuZCkge1xuICAgICAgICBpZiAoIXRoaXMucHJldmVudEVtaXRBY3Rpb25FdmVudHMpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ2FjdGlvbi1zdGFydCcsIHsgY29tbWFuZCwgYXBpQWN0aW9uTmFtZSB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBlbWl0QWN0aW9uRG9uZSAoYXBpQWN0aW9uTmFtZSwgY29tbWFuZCwgZXJyb3JzKSB7XG4gICAgICAgIGlmICghdGhpcy5wcmV2ZW50RW1pdEFjdGlvbkV2ZW50cylcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgnYWN0aW9uLWRvbmUnLCB7IGNvbW1hbmQsIGFwaUFjdGlvbk5hbWUsIGVycm9ycyB9KTtcbiAgICB9XG59XG5cbi8vIFNlcnZpY2UgbWVzc2FnZSBoYW5kbGVyc1xuY29uc3QgU2VydmljZU1lc3NhZ2VzID0gVGVzdFJ1bi5wcm90b3R5cGU7XG5cbi8vIE5PVEU6IHRoaXMgZnVuY3Rpb24gaXMgdGltZS1jcml0aWNhbCBhbmQgbXVzdCByZXR1cm4gQVNBUCB0byBhdm9pZCBjbGllbnQgZGlzY29ubmVjdGlvblxuU2VydmljZU1lc3NhZ2VzW0NMSUVOVF9NRVNTQUdFUy5yZWFkeV0gPSBmdW5jdGlvbiAobXNnKSB7XG4gICAgdGhpcy5kZWJ1Z0xvZy5kcml2ZXJNZXNzYWdlKG1zZyk7XG5cbiAgICB0aGlzLmVtaXQoJ2Nvbm5lY3RlZCcpO1xuXG4gICAgdGhpcy5fY2xlYXJQZW5kaW5nUmVxdWVzdCgpO1xuXG4gICAgLy8gTk9URTogdGhlIGRyaXZlciBzZW5kcyB0aGUgc3RhdHVzIGZvciB0aGUgc2Vjb25kIHRpbWUgaWYgaXQgZGlkbid0IGdldCBhIHJlc3BvbnNlIGF0IHRoZVxuICAgIC8vIGZpcnN0IHRyeS4gVGhpcyBpcyBwb3NzaWJsZSB3aGVuIHRoZSBwYWdlIHdhcyB1bmxvYWRlZCBhZnRlciB0aGUgZHJpdmVyIHNlbnQgdGhlIHN0YXR1cy5cbiAgICBpZiAobXNnLnN0YXR1cy5pZCA9PT0gdGhpcy5sYXN0RHJpdmVyU3RhdHVzSWQpXG4gICAgICAgIHJldHVybiB0aGlzLmxhc3REcml2ZXJTdGF0dXNSZXNwb25zZTtcblxuICAgIHRoaXMubGFzdERyaXZlclN0YXR1c0lkICAgICAgID0gbXNnLnN0YXR1cy5pZDtcbiAgICB0aGlzLmxhc3REcml2ZXJTdGF0dXNSZXNwb25zZSA9IHRoaXMuX2hhbmRsZURyaXZlclJlcXVlc3QobXNnLnN0YXR1cyk7XG5cbiAgICBpZiAodGhpcy5sYXN0RHJpdmVyU3RhdHVzUmVzcG9uc2UgfHwgbXNnLnN0YXR1cy5pc1BlbmRpbmdXaW5kb3dTd2l0Y2hpbmcpXG4gICAgICAgIHJldHVybiB0aGlzLmxhc3REcml2ZXJTdGF0dXNSZXNwb25zZTtcblxuICAgIC8vIE5PVEU6IHdlIHNlbmQgYW4gZW1wdHkgcmVzcG9uc2UgYWZ0ZXIgdGhlIE1BWF9SRVNQT05TRV9ERUxBWSB0aW1lb3V0IGlzIGV4Y2VlZGVkIHRvIGtlZXAgY29ubmVjdGlvblxuICAgIC8vIHdpdGggdGhlIGNsaWVudCBhbmQgcHJldmVudCB0aGUgcmVzcG9uc2UgdGltZW91dCBleGNlcHRpb24gb24gdGhlIGNsaWVudCBzaWRlXG4gICAgY29uc3QgcmVzcG9uc2VUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLl9yZXNvbHZlUGVuZGluZ1JlcXVlc3QobnVsbCksIE1BWF9SRVNQT05TRV9ERUxBWSk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLnBlbmRpbmdSZXF1ZXN0ID0geyByZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlVGltZW91dCB9O1xuICAgIH0pO1xufTtcblxuU2VydmljZU1lc3NhZ2VzW0NMSUVOVF9NRVNTQUdFUy5yZWFkeUZvckJyb3dzZXJNYW5pcHVsYXRpb25dID0gYXN5bmMgZnVuY3Rpb24gKG1zZykge1xuICAgIHRoaXMuZGVidWdMb2cuZHJpdmVyTWVzc2FnZShtc2cpO1xuXG4gICAgbGV0IHJlc3VsdCA9IG51bGw7XG4gICAgbGV0IGVycm9yICA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgICByZXN1bHQgPSBhd2FpdCB0aGlzLmJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZS5leGVjdXRlUGVuZGluZ01hbmlwdWxhdGlvbihtc2cpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGVycm9yID0gZXJyO1xuICAgIH1cblxuICAgIHJldHVybiB7IHJlc3VsdCwgZXJyb3IgfTtcbn07XG5cblNlcnZpY2VNZXNzYWdlc1tDTElFTlRfTUVTU0FHRVMud2FpdEZvckZpbGVEb3dubG9hZF0gPSBmdW5jdGlvbiAobXNnKSB7XG4gICAgdGhpcy5kZWJ1Z0xvZy5kcml2ZXJNZXNzYWdlKG1zZyk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsZURvd25sb2FkaW5nSGFuZGxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG59O1xuIl19 |
\ | No newline at end of file |