com.phloxui
Version:
PhloxUI Ng2+ Framework
684 lines (683 loc) • 50.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { EventEmitter } from '@angular/core';
import { LoaderStatus } from './LoaderStatus';
import { DefaultLoadTask } from './DefaultLoadTask';
import { EventUtils } from '../share/utils/EventUtils';
import { TASK_START_EVENT, TASK_COMPLETE_EVENT, TASK_RESOLVE_EVENT, TASK_REJECT_EVENT, PAUSE_EVENT, RESUME_EVENT, STOP_EVENT } from '../share/CustomEventType';
var LoadProcess = /** @class */ (function () {
function LoadProcess(name, continueOnReject) {
this.name = name;
this.status = LoaderStatus.STOPPED;
this.tasks = [];
this.successResult = {};
this.rejectResult = {};
this.disabled = false;
this.isFirstStarted = false;
this.percent = 0;
this.currentTask = null;
this.taskStartEvent = new EventEmitter();
this.taskCompleteEvent = new EventEmitter();
this.taskResolveEvent = new EventEmitter();
this.taskRejectEvent = new EventEmitter();
this.pauseEvent = new EventEmitter();
this.resumeEvent = new EventEmitter();
this.startEvent = new EventEmitter();
this.stopEvent = new EventEmitter();
if (continueOnReject === null || typeof continueOnReject !== 'boolean') {
this.continueOnReject = true;
}
else {
this.continueOnReject = continueOnReject;
}
}
/**
* @param {?} taskCount
* @return {?}
*/
LoadProcess.prototype.updatePercent = /**
* @param {?} taskCount
* @return {?}
*/
function (taskCount) {
var /** @type {?} */ allTask = (this.tasks.length > 0) ? this.tasks.length : 0;
var /** @type {?} */ perTask = 0;
if (allTask > 0) {
perTask = 100 / allTask;
}
var /** @type {?} */ totalPercent = taskCount * perTask;
if (taskCount === allTask) {
totalPercent = 100;
}
this.percent = totalPercent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getResultObject = /**
* @return {?}
*/
function () {
var /** @type {?} */ result = {
success: this.successResult,
error: this.rejectResult
};
return result;
};
/**
* @param {?} type
* @param {?} name
* @param {?} success
* @param {?} error
* @return {?}
*/
LoadProcess.prototype.getCustomEventObject = /**
* @param {?} type
* @param {?} name
* @param {?} success
* @param {?} error
* @return {?}
*/
function (type, name, success, error) {
var /** @type {?} */ successCount = Object.keys(this.successResult).length;
var /** @type {?} */ errorCount = Object.keys(this.rejectResult).length;
var /** @type {?} */ wrapData = {
name: name,
success: success,
error: error,
percent: this.percent,
totalCount: this.tasks.length,
processed: successCount + errorCount,
successCount: successCount,
errorCount: errorCount
};
var /** @type {?} */ ev = EventUtils.newCustomEvent(type, null, wrapData, null);
return ev;
};
/**
* @param {?} index
* @return {?}
*/
LoadProcess.prototype.wrapPromise = /**
* @param {?} index
* @return {?}
*/
function (index) {
var _this = this;
if (index <= -1 || index >= this.tasks.length) {
return Promise.resolve();
}
if (this.isStopped()) {
var /** @type {?} */ result = {
loadStatus: LoaderStatus.STOPPED,
index: index
};
return Promise.reject(result);
}
if (index >= this.tasks.length) {
return Promise.resolve(null);
}
if (this.isPaused()) {
return this.delayPromise(Promise.resolve(), 500).then(function (result) {
return _this.wrapPromise(index);
});
}
var /** @type {?} */ currentResult = this.getResultObject();
this.currentTask = this.tasks[index];
var /** @type {?} */ taskName = this.currentTask.getName();
var /** @type {?} */ compEv = this.getCustomEventObject(TASK_START_EVENT, taskName, null, null);
this.taskStartEvent.emit(compEv);
var /** @type {?} */ exeProm = null;
try {
exeProm = this.tasks[index].execute(currentResult);
}
catch (/** @type {?} */ e) {
exeProm = Promise.reject(e);
}
return exeProm.then(function (result) {
_this.successResult[taskName] = result;
// update percent
// update percent
_this.updatePercent(index + 1);
// emit complete event
var /** @type {?} */ ev = _this.getCustomEventObject(TASK_RESOLVE_EVENT, taskName, result, null);
_this.taskResolveEvent.emit(ev);
var /** @type {?} */ compEv = _this.getCustomEventObject(TASK_COMPLETE_EVENT, taskName, result, null);
_this.taskCompleteEvent.emit(compEv);
_this.currentTask = null;
return _this.wrapPromise(++index);
}, function (rejResult) {
if (rejResult !== null && rejResult !== 'undefined') {
if (rejResult.loadStatus !== LoaderStatus.STOPPED) {
// this is real reject result
var /** @type {?} */ taskName_1 = _this.tasks[index].getName();
_this.rejectResult[taskName_1] = rejResult;
// continue to next promise
if (_this.continueOnReject) {
_this.updatePercent(index + 1);
// emit complated event
var /** @type {?} */ ev = _this.getCustomEventObject(TASK_REJECT_EVENT, taskName_1, null, rejResult);
_this.taskRejectEvent.emit(ev);
var /** @type {?} */ compEv_1 = _this.getCustomEventObject(TASK_COMPLETE_EVENT, taskName_1, null, rejResult);
_this.taskCompleteEvent.emit(compEv_1);
_this.currentTask = null;
return _this.wrapPromise(++index);
}
}
}
// that mean not continue to next promise
if (rejResult.loadStatus !== LoaderStatus.STOPPED) {
_this.updatePercent(index + 1);
var /** @type {?} */ ev = _this.getCustomEventObject(TASK_REJECT_EVENT, taskName, null, rejResult);
_this.taskRejectEvent.emit(ev);
var /** @type {?} */ compEv_2 = _this.getCustomEventObject(TASK_COMPLETE_EVENT, taskName, null, rejResult);
_this.taskCompleteEvent.emit(compEv_2);
_this.currentTask = null;
}
return Promise.reject(rejResult);
});
};
/**
* @param {?} prom
* @param {?} delayMS
* @return {?}
*/
LoadProcess.prototype.delayPromise = /**
* @param {?} prom
* @param {?} delayMS
* @return {?}
*/
function (prom, delayMS) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, delayMS);
}).then(function () {
return prom;
});
};
/**
* @param {?} name
* @param {?} taskFunc
* @return {?}
*/
LoadProcess.prototype.add = /**
* @param {?} name
* @param {?} taskFunc
* @return {?}
*/
function (name, taskFunc) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
this.tasks.push(new DefaultLoadTask(name, taskFunc));
return this;
};
/**
* @param {?} task
* @return {?}
*/
LoadProcess.prototype.addTask = /**
* @param {?} task
* @return {?}
*/
function (task) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
if (task !== null && task !== undefined) {
this.tasks.push(task);
}
return this;
};
/**
* @param {?} task
* @return {?}
*/
LoadProcess.prototype.removeTask = /**
* @param {?} task
* @return {?}
*/
function (task) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
var /** @type {?} */ index = this.tasks.indexOf(task);
return this.remove(index);
};
/**
* @param {?} index
* @return {?}
*/
LoadProcess.prototype.remove = /**
* @param {?} index
* @return {?}
*/
function (index) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
if (index < this.tasks.length) {
this.tasks.splice(index, 1);
}
return this;
};
/**
* @param {?} disabled
* @return {?}
*/
LoadProcess.prototype.setDisabled = /**
* @param {?} disabled
* @return {?}
*/
function (disabled) {
this.disabled = disabled;
};
/**
* @return {?}
*/
LoadProcess.prototype.isDisabled = /**
* @return {?}
*/
function () {
return this.disabled;
};
/**
* @return {?}
*/
LoadProcess.prototype.start = /**
* @return {?}
*/
function () {
var _this = this;
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
if (this.isStopped()) {
this.status = LoaderStatus.RUNNING;
this.isFirstStarted = true;
}
// promise start
return new Promise(function (resolve, reject) {
_this.wrapPromise(0).then(function (result) {
var /** @type {?} */ resolveResult = _this.getResultObject();
resolve(resolveResult);
}, function (rejectResult) {
var /** @type {?} */ resolveResult = _this.getResultObject();
if (rejectResult !== null && rejectResult !== undefined && rejectResult.loadStatus === LoaderStatus.STOPPED) {
// break for STOP status
resolve(resolveResult);
}
else {
if (_this.continueOnReject) {
// resolve whatever rejected
resolve(resolveResult);
}
else {
// reject if any of reject was found
reject(resolveResult);
}
}
});
});
};
/**
* @return {?}
*/
LoadProcess.prototype.pause = /**
* @return {?}
*/
function () {
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isRunning()) {
this.status = LoaderStatus.PAUSED;
}
var /** @type {?} */ ev = this.getCustomEventObject(PAUSE_EVENT, null, null, null);
this.pauseEvent.emit(ev);
};
/**
* @return {?}
*/
LoadProcess.prototype.resume = /**
* @return {?}
*/
function () {
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isPaused()) {
this.status = LoaderStatus.RUNNING;
}
var /** @type {?} */ taskName = null;
if (this.currentTask !== null) {
taskName = this.currentTask.getName();
}
var /** @type {?} */ ev = this.getCustomEventObject(RESUME_EVENT, taskName, null, null);
this.resumeEvent.emit(ev);
};
/**
* @return {?}
*/
LoadProcess.prototype.stop = /**
* @return {?}
*/
function () {
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isRunning() || this.isPaused()) {
this.status = LoaderStatus.STOPPED;
}
var /** @type {?} */ taskName = null;
if (this.currentTask !== null) {
taskName = this.currentTask.getName();
}
var /** @type {?} */ ev = this.getCustomEventObject(STOP_EVENT, taskName, null, null);
this.stopEvent.emit(ev);
};
/**
* @return {?}
*/
LoadProcess.prototype.getState = /**
* @return {?}
*/
function () {
return this.status;
};
/**
* @return {?}
*/
LoadProcess.prototype.isRunning = /**
* @return {?}
*/
function () {
return this.status === LoaderStatus.RUNNING;
};
/**
* @return {?}
*/
LoadProcess.prototype.isPaused = /**
* @return {?}
*/
function () {
return this.status === LoaderStatus.PAUSED;
};
/**
* @return {?}
*/
LoadProcess.prototype.isStopped = /**
* @return {?}
*/
function () {
return this.status === LoaderStatus.STOPPED;
};
/**
* @return {?}
*/
LoadProcess.prototype.getContinueOnReject = /**
* @return {?}
*/
function () {
return this.continueOnReject;
};
/**
* @param {?} continueOnReject
* @return {?}
*/
LoadProcess.prototype.setContinueOnReject = /**
* @param {?} continueOnReject
* @return {?}
*/
function (continueOnReject) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
this.continueOnReject = continueOnReject;
};
/**
* @return {?}
*/
LoadProcess.prototype.getPercent = /**
* @return {?}
*/
function () {
return this.percent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getTaskCount = /**
* @return {?}
*/
function () {
return this.tasks.length;
};
/**
* @return {?}
*/
LoadProcess.prototype.getName = /**
* @return {?}
*/
function () {
return this.name;
};
/**
* @param {?} name
* @return {?}
*/
LoadProcess.prototype.setName = /**
* @param {?} name
* @return {?}
*/
function (name) {
this.name = name;
};
/**
* @return {?}
*/
LoadProcess.prototype.getTaskStartEvent = /**
* @return {?}
*/
function () {
return this.taskStartEvent;
};
/**
* @param {?} taskStartEvent
* @return {?}
*/
LoadProcess.prototype.setTaskStartEvent = /**
* @param {?} taskStartEvent
* @return {?}
*/
function (taskStartEvent) {
this.taskStartEvent = taskStartEvent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getTaskCompleteEvent = /**
* @return {?}
*/
function () {
return this.taskCompleteEvent;
};
/**
* @param {?} taskCompleteEvent
* @return {?}
*/
LoadProcess.prototype.setTaskCompleteEvent = /**
* @param {?} taskCompleteEvent
* @return {?}
*/
function (taskCompleteEvent) {
this.taskCompleteEvent = taskCompleteEvent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getTaskResolveEvent = /**
* @return {?}
*/
function () {
return this.taskResolveEvent;
};
/**
* @param {?} taskResolveEvent
* @return {?}
*/
LoadProcess.prototype.setTaskResolveEvent = /**
* @param {?} taskResolveEvent
* @return {?}
*/
function (taskResolveEvent) {
this.taskResolveEvent = taskResolveEvent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getTaskRejectEvent = /**
* @return {?}
*/
function () {
return this.taskRejectEvent;
};
/**
* @param {?} taskRejectEvent
* @return {?}
*/
LoadProcess.prototype.setTaskRejectEvent = /**
* @param {?} taskRejectEvent
* @return {?}
*/
function (taskRejectEvent) {
this.taskRejectEvent = taskRejectEvent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getPauseEvent = /**
* @return {?}
*/
function () {
return this.pauseEvent;
};
/**
* @param {?} pauseEvent
* @return {?}
*/
LoadProcess.prototype.setPauseEvent = /**
* @param {?} pauseEvent
* @return {?}
*/
function (pauseEvent) {
this.pauseEvent = pauseEvent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getResumeEvent = /**
* @return {?}
*/
function () {
return this.resumeEvent;
};
/**
* @param {?} resumeEvent
* @return {?}
*/
LoadProcess.prototype.setResumeEvent = /**
* @param {?} resumeEvent
* @return {?}
*/
function (resumeEvent) {
this.resumeEvent = resumeEvent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getStartEvent = /**
* @return {?}
*/
function () {
return this.startEvent;
};
/**
* @param {?} startEvent
* @return {?}
*/
LoadProcess.prototype.setStartEvent = /**
* @param {?} startEvent
* @return {?}
*/
function (startEvent) {
this.startEvent = startEvent;
};
/**
* @return {?}
*/
LoadProcess.prototype.getStopEvent = /**
* @return {?}
*/
function () {
return this.stopEvent;
};
/**
* @param {?} stopEvent
* @return {?}
*/
LoadProcess.prototype.setStopEvent = /**
* @param {?} stopEvent
* @return {?}
*/
function (stopEvent) {
this.stopEvent = stopEvent;
};
return LoadProcess;
}());
export { LoadProcess };
function LoadProcess_tsickle_Closure_declarations() {
/** @type {?} */
LoadProcess.prototype.tasks;
/** @type {?} */
LoadProcess.prototype.disabled;
/** @type {?} */
LoadProcess.prototype.status;
/** @type {?} */
LoadProcess.prototype.successResult;
/** @type {?} */
LoadProcess.prototype.rejectResult;
/** @type {?} */
LoadProcess.prototype.continueOnReject;
/** @type {?} */
LoadProcess.prototype.isFirstStarted;
/** @type {?} */
LoadProcess.prototype.percent;
/** @type {?} */
LoadProcess.prototype.name;
/** @type {?} */
LoadProcess.prototype.currentTask;
/** @type {?} */
LoadProcess.prototype.taskStartEvent;
/** @type {?} */
LoadProcess.prototype.taskCompleteEvent;
/** @type {?} */
LoadProcess.prototype.taskResolveEvent;
/** @type {?} */
LoadProcess.prototype.taskRejectEvent;
/** @type {?} */
LoadProcess.prototype.pauseEvent;
/** @type {?} */
LoadProcess.prototype.resumeEvent;
/** @type {?} */
LoadProcess.prototype.startEvent;
/** @type {?} */
LoadProcess.prototype.stopEvent;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9hZFByb2Nlc3MuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9jb20ucGhsb3h1aS8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnQvTG9hZFByb2Nlc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkQsT0FBTyxFQUNMLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUNwSCxNQUFNLDBCQUEwQixDQUFDO0FBRWxDLElBQUE7SUFxQkUscUJBQVksSUFBWSxFQUFFLGdCQUEwQjtRQUNsRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUM7UUFDbkMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7UUFDNUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFFeEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzVDLElBQUks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LEdBQUcsVUFBVSxDQUFDOzs7OztJQUd4QixvQ0FBYzs7OztRQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQzs7Ozs7O0lBR25CLG9DQUFjOzs7O2NBQUMsV0FBOEI7UUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7Ozs7O0lBRzFCLG1DQUFhOzs7O1FBQ2xCLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDOzs7Ozs7SUFHbEIsbUNBQWE7Ozs7Y0FBQyxVQUE2QjtRQUNoRCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQzs7Ozs7SUFHeEIsa0NBQVk7Ozs7UUFDakIsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7Ozs7OztJQUdqQixrQ0FBWTs7OztjQUFDLFNBQTRCO1FBQzlDLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDOztzQkFsYy9CO0lBb2NDLENBQUE7QUExYkQsdUJBMGJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJTG9hZGVyIH0gZnJvbSAnLi9JTG9hZGVyJztcbmltcG9ydCB7IElMb2FkVGFzayB9IGZyb20gJy4vSUxvYWRUYXNrJztcbmltcG9ydCB7IExvYWRlclN0YXR1cyB9IGZyb20gJy4vTG9hZGVyU3RhdHVzJztcbmltcG9ydCB7IERlZmF1bHRMb2FkVGFzayB9IGZyb20gJy4vRGVmYXVsdExvYWRUYXNrJztcbmltcG9ydCB7IEV2ZW50VXRpbHMgfSBmcm9tICcuLi9zaGFyZS91dGlscy9FdmVudFV0aWxzJztcbmltcG9ydCB7XG4gIFRBU0tfU1RBUlRfRVZFTlQsIFRBU0tfQ09NUExFVEVfRVZFTlQsIFRBU0tfUkVTT0xWRV9FVkVOVCwgVEFTS19SRUpFQ1RfRVZFTlQsIFBBVVNFX0VWRU5ULCBSRVNVTUVfRVZFTlQsIFNUT1BfRVZFTlRcbn0gZnJvbSAnLi4vc2hhcmUvQ3VzdG9tRXZlbnRUeXBlJztcblxuZXhwb3J0IGNsYXNzIExvYWRQcm9jZXNzIGltcGxlbWVudHMgSUxvYWRlciB7XG5cbiAgcHJpdmF0ZSB0YXNrczogSUxvYWRUYXNrW107XG4gIHByaXZhdGUgZGlzYWJsZWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgc3RhdHVzOiBMb2FkZXJTdGF0dXM7XG4gIHByaXZhdGUgc3VjY2Vzc1Jlc3VsdDogYW55O1xuICBwcml2YXRlIHJlamVjdFJlc3VsdDogYW55O1xuICBwcml2YXRlIGNvbnRpbnVlT25SZWplY3Q6IGJvb2xlYW47XG4gIHByaXZhdGUgaXNGaXJzdFN0YXJ0ZWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgcGVyY2VudDogbnVtYmVyO1xuICBwcml2YXRlIG5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSBjdXJyZW50VGFzazogSUxvYWRUYXNrO1xuICBwcml2YXRlIHRhc2tTdGFydEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgcHJpdmF0ZSB0YXNrQ29tcGxldGVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgdGFza1Jlc29sdmVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgdGFza1JlamVjdEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgcHJpdmF0ZSBwYXVzZUV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgcHJpdmF0ZSByZXN1bWVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgc3RhcnRFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgc3RvcEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcblxuICBjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcsIGNvbnRpbnVlT25SZWplY3Q/OiBib29sZWFuKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLnN0YXR1cyA9IExvYWRlclN0YXR1cy5TVE9QUEVEO1xuICAgIHRoaXMudGFza3MgPSBbXTtcbiAgICB0aGlzLnN1Y2Nlc3NSZXN1bHQgPSB7fTtcbiAgICB0aGlzLnJlamVjdFJlc3VsdCA9IHt9O1xuICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICB0aGlzLmlzRmlyc3RTdGFydGVkID0gZmFsc2U7XG4gICAgdGhpcy5wZXJjZW50ID0gMDtcbiAgICB0aGlzLmN1cnJlbnRUYXNrID0gbnVsbDtcblxuICAgIHRoaXMudGFza1N0YXJ0RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy50YXNrQ29tcGxldGVFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICB0aGlzLnRhc2tSZXNvbHZlRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy50YXNrUmVqZWN0RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5wYXVzZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMucmVzdW1lRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5zdGFydEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuc3RvcEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgaWYgKGNvbnRpbnVlT25SZWplY3QgPT09IG51bGwgfHwgdHlwZW9mIGNvbnRpbnVlT25SZWplY3QgIT09ICdib29sZWFuJykge1xuICAgICAgdGhpcy5jb250aW51ZU9uUmVqZWN0ID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb250aW51ZU9uUmVqZWN0ID0gY29udGludWVPblJlamVjdDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBlcmNlbnQodGFza0NvdW50OiBudW1iZXIpOiB2b2lkIHtcbiAgICBsZXQgYWxsVGFzayA9ICh0aGlzLnRhc2tzLmxlbmd0aCA+IDApID8gdGhpcy50YXNrcy5sZW5ndGggOiAwO1xuICAgIGxldCBwZXJUYXNrID0gMDtcbiAgICBpZiAoYWxsVGFzayA+IDApIHtcbiAgICAgIHBlclRhc2sgPSAxMDAgLyBhbGxUYXNrO1xuICAgIH1cbiAgICBsZXQgdG90YWxQZXJjZW50ID0gdGFza0NvdW50ICogcGVyVGFzaztcblxuICAgIGlmICh0YXNrQ291bnQgPT09IGFsbFRhc2spIHtcbiAgICAgIHRvdGFsUGVyY2VudCA9IDEwMDtcbiAgICB9XG5cbiAgICB0aGlzLnBlcmNlbnQgPSB0b3RhbFBlcmNlbnQ7XG4gIH1cblxuICBwcml2YXRlIGdldFJlc3VsdE9iamVjdCgpOiBhbnkge1xuICAgIGxldCByZXN1bHQ6IGFueSA9IHtcbiAgICAgIHN1Y2Nlc3M6IHRoaXMuc3VjY2Vzc1Jlc3VsdCxcbiAgICAgIGVycm9yOiB0aGlzLnJlamVjdFJlc3VsdFxuICAgIH07XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDdXN0b21FdmVudE9iamVjdCh0eXBlOiBhbnksIG5hbWU6IGFueSwgc3VjY2VzczogYW55LCBlcnJvcjogYW55KTogYW55IHtcbiAgICBsZXQgc3VjY2Vzc0NvdW50ID0gT2JqZWN0LmtleXModGhpcy5zdWNjZXNzUmVzdWx0KS5sZW5ndGg7XG4gICAgbGV0IGVycm9yQ291bnQgPSBPYmplY3Qua2V5cyh0aGlzLnJlamVjdFJlc3VsdCkubGVuZ3RoO1xuXG4gICAgbGV0IHdyYXBEYXRhID0ge1xuICAgICAgbmFtZTogbmFtZSxcbiAgICAgIHN1Y2Nlc3M6IHN1Y2Nlc3MsXG4gICAgICBlcnJvcjogZXJyb3IsXG4gICAgICBwZXJjZW50OiB0aGlzLnBlcmNlbnQsXG4gICAgICB0b3RhbENvdW50OiB0aGlzLnRhc2tzLmxlbmd0aCxcbiAgICAgIHByb2Nlc3NlZDogc3VjY2Vzc0NvdW50ICsgZXJyb3JDb3VudCxcbiAgICAgIHN1Y2Nlc3NDb3VudDogc3VjY2Vzc0NvdW50LFxuICAgICAgZXJyb3JDb3VudDogZXJyb3JDb3VudFxuICAgIH07XG4gICAgbGV0IGV2ID0gRXZlbnRVdGlscy5uZXdDdXN0b21FdmVudCh0eXBlLCBudWxsLCB3cmFwRGF0YSwgbnVsbCk7XG5cbiAgICByZXR1cm4gZXY7XG4gIH1cblxuICBwcml2YXRlIHdyYXBQcm9taXNlKGluZGV4OiBudW1iZXIpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmIChpbmRleCA8PSAtMSB8fCBpbmRleCA+PSB0aGlzLnRhc2tzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzU3RvcHBlZCgpKSB7XG4gICAgICBsZXQgcmVzdWx0ID0ge1xuICAgICAgICBsb2FkU3RhdHVzOiBMb2FkZXJTdGF0dXMuU1RPUFBFRCxcbiAgICAgICAgaW5kZXg6IGluZGV4XG4gICAgICB9O1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlc3VsdCk7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID49IHRoaXMudGFza3MubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzUGF1c2VkKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlbGF5UHJvbWlzZShQcm9taXNlLnJlc29sdmUoKSwgNTAwKS50aGVuKChyZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwUHJvbWlzZShpbmRleCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBsZXQgY3VycmVudFJlc3VsdCA9IHRoaXMuZ2V0UmVzdWx0T2JqZWN0KCk7XG5cbiAgICB0aGlzLmN1cnJlbnRUYXNrID0gdGhpcy50YXNrc1tpbmRleF07XG4gICAgbGV0IHRhc2tOYW1lID0gdGhpcy5jdXJyZW50VGFzay5nZXROYW1lKCk7XG4gICAgbGV0IGNvbXBFdiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoVEFTS19TVEFSVF9FVkVOVCwgdGFza05hbWUsIG51bGwsIG51bGwpO1xuICAgIHRoaXMudGFza1N0YXJ0RXZlbnQuZW1pdChjb21wRXYpO1xuXG4gICAgbGV0IGV4ZVByb206IFByb21pc2U8YW55PiA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgZXhlUHJvbSA9IHRoaXMudGFza3NbaW5kZXhdLmV4ZWN1dGUoY3VycmVudFJlc3VsdCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXhlUHJvbSA9IFByb21pc2UucmVqZWN0KGUpO1xuICAgIH1cblxuICAgIHJldHVybiBleGVQcm9tLnRoZW4oKHJlc3VsdDogYW55KSA9PiB7XG4gICAgICB0aGlzLnN1Y2Nlc3NSZXN1bHRbdGFza05hbWVdID0gcmVzdWx0O1xuXG4gICAgICAvLyB1cGRhdGUgcGVyY2VudFxuICAgICAgdGhpcy51cGRhdGVQZXJjZW50KGluZGV4ICsgMSk7XG5cbiAgICAgIC8vIGVtaXQgY29tcGxldGUgZXZlbnRcbiAgICAgIGxldCBldiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoVEFTS19SRVNPTFZFX0VWRU5ULCB0YXNrTmFtZSwgcmVzdWx0LCBudWxsKTtcbiAgICAgIHRoaXMudGFza1Jlc29sdmVFdmVudC5lbWl0KGV2KTtcbiAgICAgIGxldCBjb21wRXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfQ09NUExFVEVfRVZFTlQsIHRhc2tOYW1lLCByZXN1bHQsIG51bGwpO1xuICAgICAgdGhpcy50YXNrQ29tcGxldGVFdmVudC5lbWl0KGNvbXBFdik7XG5cbiAgICAgIHRoaXMuY3VycmVudFRhc2sgPSBudWxsO1xuXG4gICAgICByZXR1cm4gdGhpcy53cmFwUHJvbWlzZSgrK2luZGV4KTtcbiAgICB9LCAocmVqUmVzdWx0OiBhbnkpID0+IHtcbiAgICAgIGlmIChyZWpSZXN1bHQgIT09IG51bGwgJiYgcmVqUmVzdWx0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAocmVqUmVzdWx0LmxvYWRTdGF0dXMgIT09IExvYWRlclN0YXR1cy5TVE9QUEVEKSB7XG4gICAgICAgICAgLy8gdGhpcyBpcyByZWFsIHJlamVjdCByZXN1bHRcbiAgICAgICAgICBsZXQgdGFza05hbWUgPSB0aGlzLnRhc2tzW2luZGV4XS5nZXROYW1lKCk7XG4gICAgICAgICAgdGhpcy5yZWplY3RSZXN1bHRbdGFza05hbWVdID0gcmVqUmVzdWx0O1xuXG4gICAgICAgICAgLy8gY29udGludWUgdG8gbmV4dCBwcm9taXNlXG4gICAgICAgICAgaWYgKHRoaXMuY29udGludWVPblJlamVjdCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVQZXJjZW50KGluZGV4ICsgMSk7XG5cbiAgICAgICAgICAgIC8vIGVtaXQgY29tcGxhdGVkIGV2ZW50XG4gICAgICAgICAgICBsZXQgZXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfUkVKRUNUX0VWRU5ULCB0YXNrTmFtZSwgbnVsbCwgcmVqUmVzdWx0KTtcbiAgICAgICAgICAgIHRoaXMudGFza1JlamVjdEV2ZW50LmVtaXQoZXYpO1xuICAgICAgICAgICAgbGV0IGNvbXBFdiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoVEFTS19DT01QTEVURV9FVkVOVCwgdGFza05hbWUsIG51bGwsIHJlalJlc3VsdCk7XG4gICAgICAgICAgICB0aGlzLnRhc2tDb21wbGV0ZUV2ZW50LmVtaXQoY29tcEV2KTtcblxuICAgICAgICAgICAgdGhpcy5jdXJyZW50VGFzayA9IG51bGw7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLndyYXBQcm9taXNlKCsraW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB0aGF0IG1lYW4gbm90IGNvbnRpbnVlIHRvIG5leHQgcHJvbWlzZVxuICAgICAgaWYgKHJlalJlc3VsdC5sb2FkU3RhdHVzICE9PSBMb2FkZXJTdGF0dXMuU1RPUFBFRCkge1xuICAgICAgICB0aGlzLnVwZGF0ZVBlcmNlbnQoaW5kZXggKyAxKTtcblxuICAgICAgICBsZXQgZXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfUkVKRUNUX0VWRU5ULCB0YXNrTmFtZSwgbnVsbCwgcmVqUmVzdWx0KTtcbiAgICAgICAgdGhpcy50YXNrUmVqZWN0RXZlbnQuZW1pdChldik7XG4gICAgICAgIGxldCBjb21wRXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfQ09NUExFVEVfRVZFTlQsIHRhc2tOYW1lLCBudWxsLCByZWpSZXN1bHQpO1xuICAgICAgICB0aGlzLnRhc2tDb21wbGV0ZUV2ZW50LmVtaXQoY29tcEV2KTtcblxuICAgICAgICB0aGlzLmN1cnJlbnRUYXNrID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlalJlc3VsdCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRlbGF5UHJvbWlzZShwcm9tOiBQcm9taXNlPGFueT4sIGRlbGF5TVM6IG51bWJlcik6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9LCBkZWxheU1TKTtcbiAgICB9KS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiBwcm9tO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFkZChuYW1lOiBzdHJpbmcsIHRhc2tGdW5jOiBGdW5jdGlvbik6IExvYWRQcm9jZXNzIHtcbiAgICBpZiAodGhpcy5pc0ZpcnN0U3RhcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm9jZXNzIHdhcyBzdGFydGVkIG9yIGhhcyBiZWVuIHByb2Nlc3MnKTtcbiAgICB9XG5cbiAgICB0aGlzLnRhc2tzLnB1c2gobmV3IERlZmF1bHRMb2FkVGFzayhuYW1lLCB0YXNrRnVuYykpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgYWRkVGFzayh0YXNrOiBJTG9hZFRhc2spOiBMb2FkUHJvY2VzcyB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKHRhc2sgIT09IG51bGwgJiYgdGFzayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnRhc2tzLnB1c2godGFzayk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlVGFzayh0YXNrOiBJTG9hZFRhc2spOiBMb2FkUHJvY2VzcyB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgbGV0IGluZGV4ID0gdGhpcy50YXNrcy5pbmRleE9mKHRhc2spO1xuICAgIHJldHVybiB0aGlzLnJlbW92ZShpbmRleCk7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlKGluZGV4OiBudW1iZXIpOiBMb2FkUHJvY2VzcyB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4IDwgdGhpcy50YXNrcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMudGFza3Muc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGlmIGlzRGlzYWJsZSBhbGwgYWN0aW9uXG4gIHB1YmxpYyBzZXREaXNhYmxlZChkaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBkaXNhYmxlZDtcbiAgfVxuXG4gIHB1YmxpYyBpc0Rpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRpc2FibGVkO1xuICB9XG5cbiAgcHVibGljIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyBpcyBkaXNhYmxlZCcpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRmlyc3RTdGFydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2Nlc3Mgd2FzIHN0YXJ0ZWQgb3IgaGFzIGJlZW4gcHJvY2VzcycpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzU3RvcHBlZCgpKSB7XG4gICAgICB0aGlzLnN0YXR1cyA9IExvYWRlclN0YXR1cy5SVU5OSU5HO1xuXG4gICAgICB0aGlzLmlzRmlyc3RTdGFydGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBwcm9taXNlIHN0YXJ0XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMud3JhcFByb21pc2UoMCkudGhlbigocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVSZXN1bHQ6IGFueSA9IHRoaXMuZ2V0UmVzdWx0T2JqZWN0KCk7XG5cbiAgICAgICAgcmVzb2x2ZShyZXNvbHZlUmVzdWx0KTtcbiAgICAgIH0sIChyZWplY3RSZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgICBsZXQgcmVzb2x2ZVJlc3VsdDogYW55ID0gdGhpcy5nZXRSZXN1bHRPYmplY3QoKTtcblxuICAgICAgICBpZiAocmVqZWN0UmVzdWx0ICE9PSBudWxsICYmIHJlamVjdFJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIHJlamVjdFJlc3VsdC5sb2FkU3RhdHVzID09PSBMb2FkZXJTdGF0dXMuU1RPUFBFRCkge1xuICAgICAgICAgIC8vIGJyZWFrIGZvciBTVE9QIHN0YXR1c1xuICAgICAgICAgIHJlc29sdmUocmVzb2x2ZVJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMuY29udGludWVPblJlamVjdCkge1xuICAgICAgICAgICAgLy8gcmVzb2x2ZSB3aGF0ZXZlciByZWplY3RlZFxuICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlUmVzdWx0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcmVqZWN0IGlmIGFueSBvZiByZWplY3Qgd2FzIGZvdW5kXG4gICAgICAgICAgICByZWplY3QocmVzb2x2ZVJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBwYXVzZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm9jZXNzIGlzIGRpc2FibGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNSdW5uaW5nKCkpIHtcbiAgICAgIHRoaXMuc3RhdHVzID0gTG9hZGVyU3RhdHVzLlBBVVNFRDtcbiAgICB9XG5cbiAgICBsZXQgZXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFBBVVNFX0VWRU5ULCBudWxsLCBudWxsLCBudWxsKTtcbiAgICB0aGlzLnBhdXNlRXZlbnQuZW1pdChldik7XG4gIH1cblxuICBwdWJsaWMgcmVzdW1lKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2Nlc3MgaXMgZGlzYWJsZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc1BhdXNlZCgpKSB7XG4gICAgICB0aGlzLnN0YXR1cyA9IExvYWRlclN0YXR1cy5SVU5OSU5HO1xuICAgIH1cblxuICAgIGxldCB0YXNrTmFtZSA9IG51bGw7XG4gICAgaWYgKHRoaXMuY3VycmVudFRhc2sgIT09IG51bGwpIHtcbiAgICAgIHRhc2tOYW1lID0gdGhpcy5jdXJyZW50VGFzay5nZXROYW1lKCk7XG4gICAgfVxuXG4gICAgbGV0IGV2ID0gdGhpcy5nZXRDdXN0b21FdmVudE9iamVjdChSRVNVTUVfRVZFTlQsIHRhc2tOYW1lLCBudWxsLCBudWxsKTtcbiAgICB0aGlzLnJlc3VtZUV2ZW50LmVtaXQoZXYpO1xuICB9XG5cbiAgcHVibGljIHN0b3AoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyBpcyBkaXNhYmxlZCcpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzUnVubmluZygpIHx8IHRoaXMuaXNQYXVzZWQoKSkge1xuICAgICAgdGhpcy5zdGF0dXMgPSBMb2FkZXJTdGF0dXMuU1RPUFBFRDtcbiAgICB9XG5cbiAgICBsZXQgdGFza05hbWUgPSBudWxsO1xuICAgIGlmICh0aGlzLmN1cnJlbnRUYXNrICE9PSBudWxsKSB7XG4gICAgICB0YXNrTmFtZSA9IHRoaXMuY3VycmVudFRhc2suZ2V0TmFtZSgpO1xuICAgIH1cblxuICAgIGxldCBldiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoU1RPUF9FVkVOVCwgdGFza05hbWUsIG51bGwsIG51bGwpO1xuICAgIHRoaXMuc3RvcEV2ZW50LmVtaXQoZXYpO1xuICB9XG5cbiAgcHVibGljIGdldFN0YXRlKCk6IExvYWRlclN0YXR1cyB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzO1xuICB9XG5cbiAgcHVibGljIGlzUnVubmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXMgPT09IExvYWRlclN0YXR1cy5SVU5OSU5HO1xuICB9XG5cbiAgcHVibGljIGlzUGF1c2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gTG9hZGVyU3RhdHVzLlBBVVNFRDtcbiAgfVxuXG4gIHB1YmxpYyBpc1N0b3BwZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzID09PSBMb2FkZXJTdGF0dXMuU1RPUFBFRDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDb250aW51ZU9uUmVqZWN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbnRpbnVlT25SZWplY3Q7XG4gIH1cblxuICBwdWJsaWMgc2V0Q29udGludWVPblJlamVjdChjb250aW51ZU9uUmVqZWN0OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250aW51ZU9uUmVqZWN0ID0gY29udGludWVPblJlamVjdDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRQZXJjZW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGVyY2VudDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUYXNrQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50YXNrcy5sZW5ndGg7XG4gIH1cblxuICBwdWJsaWMgZ2V0TmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cblxuICBwdWJsaWMgc2V0TmFtZShuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICB9XG5cbiAgcHVibGljIGdldFRhc2tTdGFydEV2ZW50KCk6IEV2ZW50RW1pdHRlcjxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy50YXNrU3RhcnRFdmVudDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRUYXNrU3RhcnRFdmVudCh0YXNrU3RhcnRFdmVudDogRXZlbnRFbWl0dGVyPGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLnRhc2tTdGFydEV2ZW50ID0gdGFza1N0YXJ0RXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0VGFza0NvbXBsZXRlRXZlbnQoKTogRXZlbnRFbWl0dGVyPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnRhc2tDb21wbGV0ZUV2ZW50O1xuICB9XG5cbiAgcHVibGljIHNldFRhc2tDb21wbGV0ZUV2ZW50KHRhc2tDb21wbGV0ZUV2ZW50OiBFdmVudEVtaXR0ZXI8YW55Pik6IHZvaWQge1xuICAgIHRoaXMudGFza0NvbXBsZXRlRXZlbnQgPSB0YXNrQ29tcGxldGVFdmVudDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUYXNrUmVzb2x2ZUV2ZW50KCk6IEV2ZW50RW1pdHRlcjxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy50YXNrUmVzb2x2ZUV2ZW50O1xuICB9XG5cbiAgcHVibGljIHNldFRhc2tSZXNvbHZlRXZlbnQodGFza1Jlc29sdmVFdmVudDogRXZlbnRFbWl0dGVyPGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLnRhc2tSZXNvbHZlRXZlbnQgPSB0YXNrUmVzb2x2ZUV2ZW50O1xuICB9XG5cbiAgcHVibGljIGdldFRhc2tSZWplY3RFdmVudCgpOiBFdmVudEVtaXR0ZXI8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMudGFza1JlamVjdEV2ZW50O1xuICB9XG5cbiAgcHVibGljIHNldFRhc2tSZWplY3RFdmVudCh0YXNrUmVqZWN0RXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy50YXNrUmVqZWN0RXZlbnQgPSB0YXNrUmVqZWN0RXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGF1c2VFdmVudCgpOiBFdmVudEVtaXR0ZXI8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMucGF1c2VFdmVudDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRQYXVzZUV2ZW50KHBhdXNlRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+KTogdm9pZCB7XG4