angular-material-datatransfer-lib
Version:
A HTML5 datatransfer UI for handling upload and download of multiple simultaneous files.
673 lines • 57.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/facades/datatransfer.facade.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { ConfigService } from '../services/config.service';
import { TransferStatus } from '../enums/transfer-status.enum';
import { TransferType } from '../enums/transfer-type.enum';
import { BrowseDialogComponent } from '../components/browse-dialog.component';
import { EditDialogComponent } from '../components/edit-dialog.component';
import { CustomEventType, CustomEventTypeExtensions } from '../enums/custom-event-type.enum';
export class DatatransferFacade {
/**
* @param {?} logger
* @param {?} zone
* @param {?} store
* @param {?} dateUtil
* @param {?} paginationService
* @param {?} exportService
* @param {?} uploader
* @param {?} downloader
* @param {?} dialog
*/
constructor(logger, zone, store, dateUtil, paginationService, exportService, uploader, downloader, dialog) {
this.logger = logger;
this.zone = zone;
this.store = store;
this.dateUtil = dateUtil;
this.paginationService = paginationService;
this.exportService = exportService;
this.uploader = uploader;
this.downloader = downloader;
this.dialog = dialog;
// Interval in milliseconds to calculate progress:
this.progressInterval = 200;
// Interval in milliseconds to calculate bitrate:
this.bitrateInterval = 1000;
this.uploadProgress = this.store.uploadProgress;
this.downloadProgress = this.store.downloadProgress;
this.init(this.uploader, this.uploadProgress);
this.init(this.downloader, this.downloadProgress);
}
/**
* @private
* @param {?} datatransfer
* @param {?} progressContainer
* @return {?}
*/
init(datatransfer, progressContainer) {
datatransfer.on('itemAdded', (/**
* @param {?} item
* @return {?}
*/
function (item) {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.zone.run((/**
* @return {?}
*/
() => {
that.addItem(item);
}));
}).bind(this));
datatransfer.on('zoneUpdated', (/**
* @param {?} item
* @param {?} status
* @param {?=} message
* @return {?}
*/
function (item, status, message) {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.zone.run((/**
* @return {?}
*/
() => {
// console.log(that.uploader.isWorking());
}));
}).bind(this));
datatransfer.on('itemStatusChanged', (/**
* @param {?} item
* @param {?} status
* @param {?=} message
* @return {?}
*/
function (item, status, message) {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.zone.run((/**
* @return {?}
*/
() => {
that.changeItemStatus(item, status, message);
}));
}).bind(this));
datatransfer.on('itemProgressUpdated', (/**
* @param {?} item
* @param {?} progress
* @return {?}
*/
function (item, progress) {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.zone.run((/**
* @return {?}
*/
() => {
that.updateItemProgress(item, progress);
}));
}).bind(this));
datatransfer.on('overallProgressUpdated', (/**
* @param {?} transferType
* @param {?} progress
* @return {?}
*/
function (transferType, progress) {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.zone.run((/**
* @return {?}
*/
() => {
that.updateOverallProgress(progressContainer, transferType, progress);
}));
}).bind(this));
datatransfer.on('overallSizeUpdated', (/**
* @param {?} size
* @return {?}
*/
function (size) {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.zone.run((/**
* @return {?}
*/
() => {
that.updateOverallSize(progressContainer, size);
}));
}).bind(this));
}
/**
* @param {?} element
* @param {?=} isDirectory
* @return {?}
*/
assignUploadBrowse(element, isDirectory = false) {
this.uploader.assignBrowse(element, isDirectory);
}
/**
* @param {?} element
* @return {?}
*/
assignUploadDrop(element) {
this.uploader.assignDrop(element);
}
/**
* @return {?}
*/
openBrowseDialog() {
/** @type {?} */
const dialogRef = this.dialog.open(BrowseDialogComponent, {
data: {
datatransferFacade: this
}
});
}
/**
* @param {?} item
* @return {?}
*/
openEditPathDialog(item) {
/** @type {?} */
const dialogRef = this.dialog.open(EditDialogComponent, {
data: {
datatransferFacade: this,
mode: 'edit-path',
item
}
});
}
/**
* @param {?} item
* @return {?}
*/
openEditFilenameDialog(item) {
/** @type {?} */
const dialogRef = this.dialog.open(EditDialogComponent, {
data: {
datatransferFacade: this,
mode: 'edit-filename',
item
}
});
}
/**
* @param {?} checked
* @return {?}
*/
toggleVisible(checked) {
this.paginationService.paginatedItems.forEach((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
(item, index) => {
item.isSelected = checked;
}));
}
/**
* @return {?}
*/
startAll() {
this.store.getItems().forEach((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
(item, index) => {
/** @type {?} */
const that = (/** @type {?} */ (this));
if (item.transferType === TransferType.Upload && item.status === TransferStatus.Ready) {
that.changeItemStatus(item, TransferStatus.Queued);
}
}));
this.uploader.startAll();
}
/**
* @return {?}
*/
pauseAll() {
this.store.getItems().forEach((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
(item, index) => {
item.preprocessContainer.pause(true);
}));
this.uploader.pauseAll();
this.downloader.pauseAll();
}
/**
* @return {?}
*/
removeAll() {
this.store.getItems().forEach((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
(item, index) => {
item.preprocessContainer.cancel(true);
}));
this.uploader.removeAll();
this.downloader.removeAll();
this.store.clear();
this.uploadProgress.reset(0);
this.paginationService.update(0);
document.dispatchEvent(new CustomEvent(CustomEventTypeExtensions.toString(CustomEventType.ITEMS_CLEARED)));
}
/**
* @return {?}
*/
retryAll() {
this.store.getByStatus(TransferStatus.Failed).forEach((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
(item, index) => {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.retryItem(item);
}));
}
/**
* @return {?}
*/
removeSelected() {
/** @type {?} */
const temp = this.store.getSelected().slice();
temp.forEach((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
(item, index) => {
/** @type {?} */
const that = (/** @type {?} */ (this));
that.removeItem(item);
}));
}
/**
* @param {?} item
* @return {?}
*/
addItem(item) {
if (!!item) {
this.store.addItem(item);
this.paginationService.update(this.store.count);
document.dispatchEvent(new CustomEvent(CustomEventTypeExtensions.toString(CustomEventType.ITEM_ADDED), { detail: item }));
}
}
/**
* @param {?} item
* @return {?}
*/
removeItem(item) {
if (!!item) {
item.preprocessContainer.cancel(true);
switch (item.transferType) {
case TransferType.Upload:
this.uploader.removeItem(item);
break;
case TransferType.Download:
this.downloader.removeItem(item);
break;
default:
break;
}
this.store.removeById(item.id);
this.paginationService.update(this.store.count);
document.dispatchEvent(new CustomEvent(CustomEventTypeExtensions.toString(CustomEventType.ITEM_REMOVED), { detail: item }));
}
}
/**
* @param {?} item
* @return {?}
*/
retryItem(item) {
if (!!item) {
item.preprocessContainer.cancel(true);
switch (item.transferType) {
case TransferType.Upload:
this.uploader.retryItem(item);
break;
case TransferType.Download:
this.downloader.retryItem(item);
break;
default:
break;
}
}
}
/**
* @param {?} item
* @param {?} status
* @param {?=} message
* @return {?}
*/
changeItemStatus(item, status, message) {
if (!!item && !!status) {
if (item.status !== status) {
this.paginationService.setPageByItemId(item.id);
item.status = status;
if (!!message) {
item.message = message;
}
this.store.updateFailedCount();
if (status === TransferStatus.Finished) {
document.dispatchEvent(new CustomEvent(CustomEventTypeExtensions.toString(CustomEventType.ITEM_COMPLETED), { detail: item }));
}
}
}
}
/**
* @param {?} item
* @param {?} progress
* @return {?}
*/
updateItemProgress(item, progress) {
if (!!item) {
/** @type {?} */
const now = this.dateUtil.now();
/** @type {?} */
const loaded = item.progressContainer.total * progress;
item.progressContainer.updateBitrate(now, loaded, this.bitrateInterval);
item.progressContainer.updateProgress(now, loaded, this.progressInterval);
}
}
/**
* @param {?} progressContainer
* @param {?} transferType
* @param {?} progress
* @return {?}
*/
updateOverallProgress(progressContainer, transferType, progress) {
/** @type {?} */
const now = this.dateUtil.now();
/** @type {?} */
const loaded = progressContainer.total * progress;
// this.logger.log('total: ' + progressContainer.total + ' progress: ' + progress + ' loaded: ' + loaded);
progressContainer.updateBitrate(now, loaded, this.bitrateInterval);
progressContainer.updateProgress(now, loaded, this.progressInterval);
if (progressContainer.total > 0 && loaded >= progressContainer.total) {
switch (transferType) {
case TransferType.Upload:
document.dispatchEvent(new CustomEvent(CustomEventTypeExtensions.toString(CustomEventType.UPLOAD_COMPLETED)));
break;
case TransferType.Download:
document.dispatchEvent(new CustomEvent(CustomEventTypeExtensions.toString(CustomEventType.DOWNLOAD_COMPLETED)));
break;
default:
break;
}
}
}
/**
* @param {?} progressContainer
* @param {?} size
* @return {?}
*/
updateOverallSize(progressContainer, size) {
progressContainer.reset(size);
}
/**
* @param {?} filename
* @param {?} url
* @param {?} sizeInBytes
* @return {?}
*/
download(filename, url, sizeInBytes) {
this.downloader.download(filename, url, sizeInBytes);
}
/**
* @param {?} exportType
* @return {?}
*/
export(exportType) {
this.exportService.export(exportType);
}
/**
* @param {?} status
* @return {?}
*/
getStatusClass(status) {
switch (status) {
case TransferStatus.Ready:
return 'add_circle_outline';
case TransferStatus.Uploading:
return 'arrow_upward';
case TransferStatus.Downloading:
return 'arrow_downward';
case TransferStatus.Failed:
return 'error_outline';
case TransferStatus.Queued:
case TransferStatus.Preprocessing:
return 'schedule';
case TransferStatus.Finished:
return 'done_all';
default:
return '';
}
}
/**
* @return {?}
*/
showStartButton() {
return this.store.count > 0 && !this.uploader.isWorking() && !this.downloader.isWorking();
}
/**
* @return {?}
*/
showPauseButton() {
return this.uploader.isWorking();
}
/**
* @return {?}
*/
showRemoveButton() {
return this.store.count > 0;
}
/**
* @return {?}
*/
showRetryButton() {
return this.store.failedCount > 0 && !this.uploader.isWorking() && !this.downloader.isWorking();
}
/**
* @param {?} item
* @return {?}
*/
showRetryButtonByItem(item) {
return item.status === TransferStatus.Failed;
}
/**
* @return {?}
*/
showExportButton() {
return this.store.count > 0;
}
/**
* @return {?}
*/
showPreprocessingCheckbox() {
return this.store.count > 0 && ConfigService.settings.core.preprocessHashEnabled;
}
/**
* @return {?}
*/
showPreprocessingTooltip() {
return this.showPreprocessingCheckbox() && !!ConfigService.settings.core.preprocessHashTooltipContent;
}
/**
* @param {?} item
* @return {?}
*/
showSpinner(item) {
return item.preprocessContainer.percent > 0 && item.status === TransferStatus.Preprocessing;
}
/**
* @param {?} item
* @return {?}
*/
showProgressbar(item) {
return item.progressContainer.percent > 0 &&
(item.status === TransferStatus.Uploading || item.status === TransferStatus.Downloading);
}
/**
* @param {?} items
* @param {?} index
* @return {?}
*/
showPath(items, index) {
if (index > 0 && items.length > index) {
/** @type {?} */
const currentPath = items[index].path;
// don't show if previous path is same as current
return items[index - 1].path !== currentPath;
}
return true;
}
/**
* @param {?} item
* @return {?}
*/
showEditDialog(item) {
/** @type {?} */
let result = false;
if (item) {
switch (item.transferType) {
case TransferType.Upload:
if (item.status === TransferStatus.Ready) {
result = true;
}
break;
default:
break;
}
}
return result;
}
/**
* @param {?} item
* @param {?} oldPath
* @param {?} newPath
* @return {?}
*/
editPath(item, oldPath, newPath) {
switch (item.transferType) {
case TransferType.Upload:
// replace all \ with /
/** @type {?} */
let cleanedPath = newPath.replace(/\\/g, '/');
// replace repeated / with one
cleanedPath = cleanedPath.replace(/\/+/g, '/');
if (cleanedPath.startsWith('/')) {
cleanedPath = cleanedPath.slice(1);
}
if (cleanedPath && !cleanedPath.endsWith('/')) {
cleanedPath += '/';
}
this.uploader.editPath(oldPath, cleanedPath);
break;
default:
break;
}
}
/**
* @param {?} item
* @param {?} name
* @return {?}
*/
editFilename(item, name) {
switch (item.transferType) {
case TransferType.Upload:
this.uploader.editFilename(item, name);
break;
default:
break;
}
}
/**
* @param {?} item
* @return {?}
*/
parseMessage(item) {
if (ConfigService.settings.core.parseMessageCallback instanceof Function) {
return ConfigService.settings.core.parseMessageCallback(item.message);
}
else {
return undefined;
}
}
}
if (false) {
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.uploadProgress;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.downloadProgress;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.progressInterval;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.bitrateInterval;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.logger;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.zone;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.store;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.dateUtil;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.paginationService;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.exportService;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.uploader;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.downloader;
/**
* @type {?}
* @private
*/
DatatransferFacade.prototype.dialog;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXRyYW5zZmVyLmZhY2FkZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FuZ3VsYXItbWF0ZXJpYWwtZGF0YXRyYW5zZmVyLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9mYWNhZGVzL2RhdGF0cmFuc2Zlci5mYWNhZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFHQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFVM0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZUFBZSxFQUFFLHlCQUF5QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0YsTUFBTSxPQUFPLGtCQUFrQjs7Ozs7Ozs7Ozs7O0lBVTNCLFlBQW9CLE1BQXFCLEVBQVUsSUFBWSxFQUFVLEtBQXdCLEVBQzdFLFFBQWtCLEVBQVUsaUJBQW9DLEVBQVUsYUFBNEIsRUFDdEcsUUFBbUIsRUFBVSxVQUF1QixFQUFVLE1BQWlCO1FBRi9FLFdBQU0sR0FBTixNQUFNLENBQWU7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFRO1FBQVUsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFDN0UsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUFVLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFBVSxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUN0RyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQVUsZUFBVSxHQUFWLFVBQVUsQ0FBYTtRQUFVLFdBQU0sR0FBTixNQUFNLENBQVc7O1FBTjNGLHFCQUFnQixHQUFHLEdBQUcsQ0FBQzs7UUFFdkIsb0JBQWUsR0FBRyxJQUFJLENBQUM7UUFLM0IsSUFBSSxDQUFD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b0I7Ozs7O0lBQUUsbUNBQWdDOzs7OztJQUNyRixzQ0FBMEI7Ozs7O0lBQUUsK0NBQTRDOzs7OztJQUFFLDJDQUFvQzs7Ozs7SUFDOUcsc0NBQTJCOzs7OztJQUFFLHdDQUErQjs7Ozs7SUFBRSxvQ0FBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwnO1xyXG5pbXBvcnQgeyBJUHJvZ3Jlc3NDb250YWluZXIgfSBmcm9tICcuLi9tb2RlbHMvcHJvZ3Jlc3MtY29udGFpbmVyLm1vZGVsJztcclxuaW1wb3J0IHsgQ29uZmlnU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2NvbmZpZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTG9nZ2VyU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2xvZ2dlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRGF0YXRyYW5zZmVyU3RvcmUgfSBmcm9tICcuLi9zdG9yZXMvZGF0YXRyYW5zZmVyLnN0b3JlJztcclxuaW1wb3J0IHsgRGF0ZVV0aWwgfSBmcm9tICcuLi91dGlscy9kYXRlLnV0aWwnO1xyXG5pbXBvcnQgeyBQYWdpbmF0aW9uU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3BhZ2luYXRpb24uc2VydmljZSc7XHJcbmltcG9ydCB7IEV4cG9ydFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9leHBvcnQuc2VydmljZSc7XHJcbmltcG9ydCB7IElVcGxvYWRlciB9IGZyb20gJy4uL2lvL3VwbG9hZGVycy9iYXNlLnVwbG9hZGVyJztcclxuaW1wb3J0IHsgSURvd25sb2FkZXIgfSBmcm9tICcuLi9pby9kb3dubG9hZGVycy9iYXNlLmRvd25sb2FkZXInO1xyXG5pbXBvcnQgeyBJRGF0YXRyYW5zZmVyIH0gZnJvbSAnLi4vaW8vZGF0YXRyYW5zZmVyLmlvJztcclxuaW1wb3J0IHsgSURhdGF0cmFuc2Zlckl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvZGF0YXRyYW5zZmVyLWl0ZW0ubW9kZWwnO1xyXG5pbXBvcnQgeyBUcmFuc2ZlclN0YXR1cyB9IGZyb20gJy4uL2VudW1zL3RyYW5zZmVyLXN0YXR1cy5lbnVtJztcclxuaW1wb3J0IHsgVHJhbnNmZXJUeXBlIH0gZnJvbSAnLi4vZW51bXMvdHJhbnNmZXItdHlwZS5lbnVtJztcclxuaW1wb3J0IHsgQnJvd3NlRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9icm93c2UtZGlhbG9nLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEVkaXREaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL2VkaXQtZGlhbG9nLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEN1c3RvbUV2ZW50VHlwZSwgQ3VzdG9tRXZlbnRUeXBlRXh0ZW5zaW9ucyB9IGZyb20gJy4uL2VudW1zL2N1c3RvbS1ldmVudC10eXBlLmVudW0nO1xyXG5cclxuZXhwb3J0IGNsYXNzIERhdGF0cmFuc2ZlckZhY2FkZSB7XHJcblxyXG4gICAgcHJpdmF0ZSB1cGxvYWRQcm9ncmVzczogSVByb2dyZXNzQ29udGFpbmVyO1xyXG4gICAgcHJpdmF0ZSBkb3dubG9hZFByb2dyZXNzOiBJUHJvZ3Jlc3NDb250YWluZXI7XHJcblxyXG4gICAgLy8gSW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIHRvIGNhbGN1bGF0ZSBwcm9ncmVzczpcclxuICAgIHByaXZhdGUgcHJvZ3Jlc3NJbnRlcnZhbCA9IDIwMDtcclxuICAgIC8vIEludGVydmFsIGluIG1pbGxpc2Vjb25kcyB0byBjYWxjdWxhdGUgYml0cmF0ZTpcclxuICAgIHByaXZhdGUgYml0cmF0ZUludGVydmFsID0gMTAwMDtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGxvZ2dlcjogTG9nZ2VyU2VydmljZSwgcHJpdmF0ZSB6b25lOiBOZ1pvbmUsIHByaXZhdGUgc3RvcmU6IERhdGF0cmFuc2ZlclN0b3JlLFxyXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkYXRlVXRpbDogRGF0ZVV0aWwsIHByaXZhdGUgcGFnaW5hdGlvblNlcnZpY2U6IFBhZ2luYXRpb25TZXJ2aWNlLCBwcml2YXRlIGV4cG9ydFNlcnZpY2U6IEV4cG9ydFNlcnZpY2UsXHJcbiAgICAgICAgICAgICAgICBwcml2YXRlIHVwbG9hZGVyOiBJVXBsb2FkZXIsIHByaXZhdGUgZG93bmxvYWRlcjogSURvd25sb2FkZXIsIHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2cpIHtcclxuICAgICAgICB0aGlzLnVwbG9hZFByb2dyZXNzID0gdGhpcy5zdG9yZS51cGxvYWRQcm9ncmVzcztcclxuICAgICAgICB0aGlzLmRvd25sb2FkUHJvZ3Jlc3MgPSB0aGlzLnN0b3JlLmRvd25sb2FkUHJvZ3Jlc3M7XHJcbiAgICAgICAgdGhpcy5pbml0KHRoaXMudXBsb2FkZXIsIHRoaXMudXBsb2FkUHJvZ3Jlc3MpO1xyXG4gICAgICAgIHRoaXMuaW5pdCh0aGlzLmRvd25sb2FkZXIsIHRoaXMuZG93bmxvYWRQcm9ncmVzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBpbml0KGRhdGF0cmFuc2ZlcjogSURhdGF0cmFuc2ZlciwgcHJvZ3Jlc3NDb250YWluZXI6IElQcm9ncmVzc0NvbnRhaW5lcik6IHZvaWQge1xyXG4gICAgICAgIGRhdGF0cmFuc2Zlci5vbignaXRlbUFkZGVkJywgZnVuY3Rpb24oaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0pIHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgRGF0YXRyYW5zZmVyRmFjYWRlO1xyXG4gICAgICAgICAgICB0aGF0LnpvbmUucnVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoYXQuYWRkSXRlbShpdGVtKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBkYXRhdHJhbnNmZXIub24oJ3pvbmVVcGRhdGVkJywgZnVuY3Rpb24oaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0sIHN0YXR1czogVHJhbnNmZXJTdGF0dXMsIG1lc3NhZ2U/OiBzdHJpbmcpIHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgRGF0YXRyYW5zZmVyRmFjYWRlO1xyXG4gICAgICAgICAgICB0aGF0LnpvbmUucnVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHRoYXQudXBsb2FkZXIuaXNXb3JraW5nKCkpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIGRhdGF0cmFuc2Zlci5vbignaXRlbVN0YXR1c0NoYW5nZWQnLCBmdW5jdGlvbihpdGVtOiBJRGF0YXRyYW5zZmVySXRlbSwgc3RhdHVzOiBUcmFuc2ZlclN0YXR1cywgbWVzc2FnZT86IHN0cmluZykge1xyXG4gICAgICAgICAgICBjb25zdCB0aGF0ID0gdGhpcyBhcyBEYXRhdHJhbnNmZXJGYWNhZGU7XHJcbiAgICAgICAgICAgIHRoYXQuem9uZS5ydW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhhdC5jaGFuZ2VJdGVtU3RhdHVzKGl0ZW0sIHN0YXR1cywgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgZGF0YXRyYW5zZmVyLm9uKCdpdGVtUHJvZ3Jlc3NVcGRhdGVkJywgZnVuY3Rpb24oaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0sIHByb2dyZXNzOiBudW1iZXIpIHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgRGF0YXRyYW5zZmVyRmFjYWRlO1xyXG4gICAgICAgICAgICB0aGF0LnpvbmUucnVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoYXQudXBkYXRlSXRlbVByb2dyZXNzKGl0ZW0sIHByb2dyZXNzKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBkYXRhdHJhbnNmZXIub24oJ292ZXJhbGxQcm9ncmVzc1VwZGF0ZWQnLCBmdW5jdGlvbih0cmFuc2ZlclR5cGU6IFRyYW5zZmVyVHlwZSwgcHJvZ3Jlc3M6IG51bWJlcikge1xyXG4gICAgICAgICAgICBjb25zdCB0aGF0ID0gdGhpcyBhcyBEYXRhdHJhbnNmZXJGYWNhZGU7XHJcbiAgICAgICAgICAgIHRoYXQuem9uZS5ydW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhhdC51cGRhdGVPdmVyYWxsUHJvZ3Jlc3MocHJvZ3Jlc3NDb250YWluZXIsIHRyYW5zZmVyVHlwZSwgcHJvZ3Jlc3MpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIGRhdGF0cmFuc2Zlci5vbignb3ZlcmFsbFNpemVVcGRhdGVkJywgZnVuY3Rpb24oc2l6ZTogbnVtYmVyKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzIGFzIERhdGF0cmFuc2ZlckZhY2FkZTtcclxuICAgICAgICAgICAgdGhhdC56b25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGF0LnVwZGF0ZU92ZXJhbGxTaXplKHByb2dyZXNzQ29udGFpbmVyLCBzaXplKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXNzaWduVXBsb2FkQnJvd3NlKGVsZW1lbnQsIGlzRGlyZWN0b3J5ID0gZmFsc2UpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnVwbG9hZGVyLmFzc2lnbkJyb3dzZShlbGVtZW50LCBpc0RpcmVjdG9yeSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzc2lnblVwbG9hZERyb3AoZWxlbWVudCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudXBsb2FkZXIuYXNzaWduRHJvcChlbGVtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb3BlbkJyb3dzZURpYWxvZygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEJyb3dzZURpYWxvZ0NvbXBvbmVudCwge1xyXG4gICAgICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICAgICAgICBkYXRhdHJhbnNmZXJGYWNhZGU6IHRoaXNcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvcGVuRWRpdFBhdGhEaWFsb2coaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0pOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEVkaXREaWFsb2dDb21wb25lbnQsIHtcclxuICAgICAgICAgICAgZGF0YToge1xyXG4gICAgICAgICAgICAgICAgZGF0YXRyYW5zZmVyRmFjYWRlOiB0aGlzLFxyXG4gICAgICAgICAgICAgICAgbW9kZTogJ2VkaXQtcGF0aCcsXHJcbiAgICAgICAgICAgICAgICBpdGVtXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb3BlbkVkaXRGaWxlbmFtZURpYWxvZyhpdGVtOiBJRGF0YXRyYW5zZmVySXRlbSk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oRWRpdERpYWxvZ0NvbXBvbmVudCwge1xyXG4gICAgICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICAgICAgICBkYXRhdHJhbnNmZXJGYWNhZGU6IHRoaXMsXHJcbiAgICAgICAgICAgICAgICBtb2RlOiAnZWRpdC1maWxlbmFtZScsXHJcbiAgICAgICAgICAgICAgICBpdGVtXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdG9nZ2xlVmlzaWJsZShjaGVja2VkOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5wYWdpbmF0aW9uU2VydmljZS5wYWdpbmF0ZWRJdGVtcy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBpdGVtLmlzU2VsZWN0ZWQgPSBjaGVja2VkO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdGFydEFsbCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnN0b3JlLmdldEl0ZW1zKCkuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgRGF0YXRyYW5zZmVyRmFjYWRlO1xyXG4gICAgICAgICAgICBpZiAoaXRlbS50cmFuc2ZlclR5cGUgPT09IFRyYW5zZmVyVHlwZS5VcGxvYWQgJiYgaXRlbS5zdGF0dXMgPT09IFRyYW5zZmVyU3RhdHVzLlJlYWR5KSB7XHJcbiAgICAgICAgICAgICAgICB0aGF0LmNoYW5nZUl0ZW1TdGF0dXMoaXRlbSwgVHJhbnNmZXJTdGF0dXMuUXVldWVkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMudXBsb2FkZXIuc3RhcnRBbGwoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcGF1c2VBbGwoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5zdG9yZS5nZXRJdGVtcygpLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIGl0ZW0ucHJlcHJvY2Vzc0NvbnRhaW5lci5wYXVzZSh0cnVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLnVwbG9hZGVyLnBhdXNlQWxsKCk7XHJcbiAgICAgICAgdGhpcy5kb3dubG9hZGVyLnBhdXNlQWxsKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZUFsbCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnN0b3JlLmdldEl0ZW1zKCkuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgaXRlbS5wcmVwcm9jZXNzQ29udGFpbmVyLmNhbmNlbCh0cnVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLnVwbG9hZGVyLnJlbW92ZUFsbCgpO1xyXG4gICAgICAgIHRoaXMuZG93bmxvYWRlci5yZW1vdmVBbGwoKTtcclxuICAgICAgICB0aGlzLnN0b3JlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy51cGxvYWRQcm9ncmVzcy5yZXNldCgwKTtcclxuICAgICAgICB0aGlzLnBhZ2luYXRpb25TZXJ2aWNlLnVwZGF0ZSgwKTtcclxuICAgICAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChDdXN0b21FdmVudFR5cGVFeHRlbnNpb25zLnRvU3RyaW5nKEN1c3RvbUV2ZW50VHlwZS5JVEVNU19DTEVBUkVEKSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZXRyeUFsbCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnN0b3JlLmdldEJ5U3RhdHVzKFRyYW5zZmVyU3RhdHVzLkZhaWxlZCkuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgRGF0YXRyYW5zZmVyRmFjYWRlO1xyXG4gICAgICAgICAgICB0aGF0LnJldHJ5SXRlbShpdGVtKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcmVtb3ZlU2VsZWN0ZWQoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgdGVtcCA9IHRoaXMuc3RvcmUuZ2V0U2VsZWN0ZWQoKS5zbGljZSgpO1xyXG4gICAgICAgIHRlbXAuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgRGF0YXRyYW5zZmVyRmFjYWRlO1xyXG4gICAgICAgICAgICB0aGF0LnJlbW92ZUl0ZW0oaXRlbSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFkZEl0ZW0oaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0pOiB2b2lkIHtcclxuICAgICAgICBpZiAoISFpdGVtKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RvcmUuYWRkSXRlbShpdGVtKTtcclxuICAgICAgICAgICAgdGhpcy5wYWdpbmF0aW9uU2VydmljZS51cGRhdGUodGhpcy5zdG9yZS5jb3VudCk7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KEN1c3RvbUV2ZW50VHlwZUV4dGVuc2lvbnMudG9TdHJpbmcoQ3VzdG9tRXZlbnRUeXBlLklURU1fQURERUQpLCB7IGRldGFpbDogaXRlbSB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZW1vdmVJdGVtKGl0ZW06IElEYXRhdHJhbnNmZXJJdGVtKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCEhaXRlbSkge1xyXG4gICAgICAgICAgICBpdGVtLnByZXByb2Nlc3NDb250YWluZXIuY2FuY2VsKHRydWUpO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGl0ZW0udHJhbnNmZXJUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRyYW5zZmVyVHlwZS5VcGxvYWQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlci5yZW1vdmVJdGVtKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUcmFuc2ZlclR5cGUuRG93bmxvYWQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb3dubG9hZGVyLnJlbW92ZUl0ZW0oaXRlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc3RvcmUucmVtb3ZlQnlJZChpdGVtLmlkKTtcclxuICAgICAgICAgICAgdGhpcy5wYWdpbmF0aW9uU2VydmljZS51cGRhdGUodGhpcy5zdG9yZS5jb3VudCk7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQoXHJcbiAgICAgICAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoQ3VzdG9tRXZlbnRUeXBlRXh0ZW5zaW9ucy50b1N0cmluZyhDdXN0b21FdmVudFR5cGUuSVRFTV9SRU1PVkVEKSwgeyBkZXRhaWw6IGl0ZW0gfSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcmV0cnlJdGVtKGl0ZW06IElEYXRhdHJhbnNmZXJJdGVtKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCEhaXRlbSkge1xyXG4gICAgICAgICAgICBpdGVtLnByZXByb2Nlc3NDb250YWluZXIuY2FuY2VsKHRydWUpO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGl0ZW0udHJhbnNmZXJUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRyYW5zZmVyVHlwZS5VcGxvYWQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlci5yZXRyeUl0ZW0oaXRlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRyYW5zZmVyVHlwZS5Eb3dubG9hZDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRvd25sb2FkZXIucmV0cnlJdGVtKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY2hhbmdlSXRlbVN0YXR1cyhpdGVtOiBJRGF0YXRyYW5zZmVySXRlbSwgc3RhdHVzOiBUcmFuc2ZlclN0YXR1cywgbWVzc2FnZT86IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGlmICghIWl0ZW0gJiYgISFzdGF0dXMpIHtcclxuICAgICAgICAgICAgaWYgKGl0ZW0uc3RhdHVzICE9PSBzdGF0dXMpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGFnaW5hdGlvblNlcnZpY2Uuc2V0UGFnZUJ5SXRlbUlkKGl0ZW0uaWQpO1xyXG4gICAgICAgICAgICAgICAgaXRlbS5zdGF0dXMgPSBzdGF0dXM7XHJcbiAgICAgICAgICAgICAgICBpZiAoISFtZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5tZXNzYWdlID0gbWVzc2FnZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuc3RvcmUudXBkYXRlRmFpbGVkQ291bnQoKTtcclxuICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09IFRyYW5zZmVyU3RhdHVzLkZpbmlzaGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KEN1c3RvbUV2ZW50VHlwZUV4dGVuc2lvbnMudG9TdHJpbmcoQ3VzdG9tRXZlbnRUeXBlLklURU1fQ09NUExFVEVEKSwgeyBkZXRhaWw6IGl0ZW0gfSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVJdGVtUHJvZ3Jlc3MoaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0sIHByb2dyZXNzOiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBpZiAoISFpdGVtKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5vdzogbnVtYmVyID0gdGhpcy5kYXRlVXRpbC5ub3coKTtcclxuICAgICAgICAgICAgY29uc3QgbG9hZGVkOiBudW1iZXIgPSBpdGVtLnByb2dyZXNzQ29udGFpbmVyLnRvdGFsICogcHJvZ3Jlc3M7XHJcbiAgICAgICAgICAgIGl0ZW0ucHJvZ3Jlc3NDb250YWluZXIudXBkYXRlQml0cmF0ZShub3csIGxvYWRlZCwgdGhpcy5iaXRyYXRlSW50ZXJ2YWwpO1xyXG4gICAgICAgICAgICBpdGVtLnByb2dyZXNzQ29udGFpbmVyLnVwZGF0ZVByb2dyZXNzKG5vdywgbG9hZGVkLCB0aGlzLnByb2dyZXNzSW50ZXJ2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdXBkYXRlT3ZlcmFsbFByb2dyZXNzKHByb2dyZXNzQ29udGFpbmVyOiBJUHJvZ3Jlc3NDb250YWluZXIsIHRyYW5zZmVyVHlwZTogVHJhbnNmZXJUeXBlLCBwcm9ncmVzczogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgbm93OiBudW1iZXIgPSB0aGlzLmRhdGVVdGlsLm5vdygpO1xyXG4gICAgICAgIGNvbnN0IGxvYWRlZDogbnVtYmVyID0gcHJvZ3Jlc3NDb250YWluZXIudG90YWwgKiBwcm9ncmVzcztcclxuICAgICAgICAvLyB0aGlzLmxvZ2dlci5sb2coJ3RvdGFsOiAnICsgcHJvZ3Jlc3NDb250YWluZXIudG90YWwgKyAnIHByb2dyZXNzOiAnICsgcHJvZ3Jlc3MgKyAnIGxvYWRlZDogJyArIGxvYWRlZCk7XHJcbiAgICAgICAgcHJvZ3Jlc3NDb250YWluZXIudXBkYXRlQml0cmF0ZShub3csIGxvYWRlZCwgdGhpcy5iaXRyYXRlSW50ZXJ2YWwpO1xyXG4gICAgICAgIHByb2dyZXNzQ29udGFpbmVyLnVwZGF0ZVByb2dyZXNzKG5vdywgbG9hZGVkLCB0aGlzLnByb2dyZXNzSW50ZXJ2YWwpO1xyXG4gICAgICAgIGlmIChwcm9ncmVzc0NvbnRhaW5lci50b3RhbCA+IDAgJiYgbG9hZGVkID49IHByb2dyZXNzQ29udGFpbmVyLnRvdGFsKSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAodHJhbnNmZXJUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRyYW5zZmVyVHlwZS5VcGxvYWQ6XHJcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoQ3VzdG9tRXZlbnRUeXBlRXh0ZW5zaW9ucy50b1N0cmluZyhDdXN0b21FdmVudFR5cGUuVVBMT0