UNPKG

angular-material-datatransfer-lib

Version:

A HTML5 datatransfer UI for handling upload and download of multiple simultaneous files.

398 lines 34.7 kB
/** * @fileoverview added by tsickle * Generated from: lib/io/downloaders/blob.downloader.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { Injectable } from '@angular/core'; import { saveAs } from 'file-saver'; import { BaseDownloader } from './base.downloader'; import { DatatransferItem } from '../../models/datatransfer-item.model'; import { ConfigService } from '../../services/config.service'; import { LoggerService } from '../../services/logger.service'; import { GuidUtil } from '../../utils/guid.util'; import { CryptoService } from '../../services/crypto.service'; import { CommonUtil } from '../../utils/common.util'; import { TransferStatus } from '../../enums/transfer-status.enum'; import { SizeContainer } from '../../models/size-container.model'; import { DecimalByteUnit } from '../../enums/decimal-byte-unit.enum'; import { ProgressContainer } from '../../models/progress-container.model'; import { TransferType } from '../../enums/transfer-type.enum'; var BlobDownloader = /** @class */ (function (_super) { tslib_1.__extends(BlobDownloader, _super); function BlobDownloader(logger, guidUtil, cryptoService, commonUtil) { var _this = _super.call(this, logger, guidUtil, cryptoService) || this; _this.logger = logger; _this.guidUtil = guidUtil; _this.cryptoService = cryptoService; _this.commonUtil = commonUtil; _this.throttleProgressCallbacks = 0.1; _this.files = []; _this.queue = []; _this.downloading = []; return _this; } /** * @return {?} */ BlobDownloader.prototype.startAll = /** * @return {?} */ function () { if (!this.isWorking()) { for (var index = 0; index < ConfigService.settings.core.simultaneousDownloads; index++) { this.downloadNext(); } } }; /** * @return {?} */ BlobDownloader.prototype.pauseAll = /** * @return {?} */ function () { }; /** * @return {?} */ BlobDownloader.prototype.removeAll = /** * @return {?} */ function () { var _this = this; this.files.forEach((/** * @param {?} item * @param {?} index * @return {?} */ function (item, index) { /** @type {?} */ var that = (/** @type {?} */ (_this)); that.abortDownload(item); })); this.files.length = 0; this.queue.length = 0; this.downloading.length = 0; this._isWorking = false; this.updateOverallSize(this.getSize()); this.updateOverallProgress(this.transferType, this.getProgress()); }; /** * @param {?} item * @return {?} */ BlobDownloader.prototype.removeItem = /** * @param {?} item * @return {?} */ function (item) { this.abortDownload(item); this.removeItemFromArray(item, this.files); this.removeItemFromArray(item, this.queue); this.removeItemFromArray(item, this.downloading); this.downloadNext(); }; /** * @private * @param {?} item * @param {?} array * @return {?} */ BlobDownloader.prototype.removeItemFromArray = /** * @private * @param {?} item * @param {?} array * @return {?} */ function (item, array) { for (var i = array.length - 1; i >= 0; i--) { if (array[i] === item) { array.splice(i, 1); break; } } }; /** * @param {?} item * @return {?} */ BlobDownloader.prototype.retryItem = /** * @param {?} item * @return {?} */ function (item) { this.abortDownload(item); this.removeItemFromArray(item, this.queue); this.removeItemFromArray(item, this.downloading); this._isWorking = this.downloading.length > 0; item.externalItem.progress = 0; this.updateItemProgress(item, item.externalItem.progress); this.changeItemStatus(item, TransferStatus.Queued); this.queue.push(item); this.initDownload(item); this.downloadNext(); }; /** * @param {?} filename * @param {?} url * @param {?} sizeInBytes * @return {?} */ BlobDownloader.prototype.download = /** * @param {?} filename * @param {?} url * @param {?} sizeInBytes * @return {?} */ function (filename, url, sizeInBytes) { /** @type {?} */ var newItem = new DatatransferItem({ id: this.generateUniqueIdentifier(), name: filename, sizeContainer: new SizeContainer({ decimalByteUnit: DecimalByteUnit.Byte, decimalByteUnitSize: sizeInBytes }), progressContainer: new ProgressContainer(sizeInBytes), transferType: TransferType.Download, status: TransferStatus.Queued, externalItem: { url: url, progress: 0, size: sizeInBytes, lastProgressCallback: new Date() } }); this.addItem(newItem); this.files.push(newItem); this.queue.push(newItem); this.initDownload(newItem); this.downloadNext(); }; /** * @private * @param {?} item * @return {?} */ BlobDownloader.prototype.initDownload = /** * @private * @param {?} item * @return {?} */ function (item) { /** @type {?} */ var xhr = new XMLHttpRequest(); item.externalItem.xhr = xhr; xhr.open(ConfigService.settings.core.downloadMethod, item.externalItem.url); xhr.timeout = ConfigService.settings.core.downloadXhrTimeout; xhr.withCredentials = ConfigService.settings.core.downloadWithCredentials; // Add data from header options /** @type {?} */ var customHeaders = ConfigService.settings.core.downloadHeaders; if (typeof customHeaders === 'function') { customHeaders = customHeaders(item); } this.commonUtil.each(customHeaders, (/** * @param {?} k * @param {?} v * @return {?} */ function (k, v) { xhr.setRequestHeader(k, v); })); xhr.responseType = 'blob'; xhr.onloadstart = (/** * @param {?} e * @return {?} */ function (e) { /** @type {?} */ var that = (/** @type {?} */ (this)); that.changeItemStatus(item, TransferStatus.Downloading); }).bind(this); xhr.onprogress = (/** * @param {?} e * @return {?} */ function (e) { /** @type {?} */ var that = (/** @type {?} */ (this)); if (new Date().getTime() - item.externalItem.lastProgressCallback.getTime() > that.throttleProgressCallbacks * 1000) { item.externalItem.progress = e.loaded / e.total; that.updateItemProgress(item, item.externalItem.progress); that.updateOverallProgress(that.transferType, that.getProgress()); item.externalItem.lastProgressCallback = new Date(); } }).bind(this); xhr.onloadend = (/** * @param {?} e * @return {?} */ function (e) { /* Value State Description 0 UNSENT Client has been created. open() not called yet. 1 OPENED open() has been called. 2 HEADERS_RECEIVED send() has been called, and headers and status are available. 3 LOADING Downloading; responseText holds partial data. 4 DONE The operation is complete. */ /** @type {?} */ var that = (/** @type {?} */ (this)); if (xhr.readyState === 4) { item.externalItem.progress = 1; that.updateItemProgress(item, item.externalItem.progress); if (xhr.status === 200) { that.changeItemStatus(item, TransferStatus.Finished); saveAs(xhr.response, item.name); } else if (xhr.status !== 0) { // don't change status for aborted items that.changeItemStatus(item, TransferStatus.Failed); } that.removeItemFromArray(item, that.downloading); that.downloadNext(); } }).bind(this); }; /** * @private * @return {?} */ BlobDownloader.prototype.downloadNext = /** * @private * @return {?} */ function () { this.updateOverallSize(this.getSize()); this.updateOverallProgress(this.transferType, this.getProgress()); if (this.downloading.length < ConfigService.settings.core.simultaneousDownloads) { /** @type {?} */ var item = this.queue.shift(); if (!!item && !!item.externalItem && !!item.externalItem.xhr) { this.changeItemStatus(item, TransferStatus.Downloading); this.downloading.push(item); this._isWorking = this.downloading.length > 0; item.externalItem.xhr.send(); } } }; /** * @private * @param {?} item * @return {?} */ BlobDownloader.prototype.abortDownload = /** * @private * @param {?} item * @return {?} */ function (item) { if (!!item && !!item.externalItem && !!item.externalItem.xhr) { item.externalItem.xhr.abort(); item.externalItem.xhr = null; } }; /** * @private * @return {?} */ BlobDownloader.prototype.getSize = /** * @private * @return {?} */ function () { /** @type {?} */ var totalSize = 0; this.files.forEach((/** * @param {?} file * @param {?} index * @return {?} */ function (file, index) { totalSize += file.externalItem.size; })); return totalSize; }; /** * @private * @return {?} */ BlobDownloader.prototype.getProgress = /** * @private * @return {?} */ function () { /** @type {?} */ var totalDone = 0; /** @type {?} */ var totalSize = 0; this.files.forEach((/** * @param {?} file * @param {?} index * @return {?} */ function (file, index) { /** @type {?} */ var currentFileProgress = file.externalItem.progress; if (file.status === TransferStatus.Failed) { currentFileProgress = 1; } totalDone += currentFileProgress * file.externalItem.size; totalSize += file.externalItem.size; })); return totalSize > 0 ? totalDone / totalSize : 0; }; BlobDownloader.decorators = [ { type: Injectable } ]; /** @nocollapse */ BlobDownloader.ctorParameters = function () { return [ { type: LoggerService }, { type: GuidUtil }, { type: CryptoService }, { type: CommonUtil } ]; }; return BlobDownloader; }(BaseDownloader)); export { BlobDownloader }; if (false) { /** * @type {?} * @private */ BlobDownloader.prototype.throttleProgressCallbacks; /** * @type {?} * @private */ BlobDownloader.prototype.files; /** * @type {?} * @private */ BlobDownloader.prototype.queue; /** * @type {?} * @private */ BlobDownloader.prototype.downloading; /** * @type {?} * @protected */ BlobDownloader.prototype.logger; /** * @type {?} * @protected */ BlobDownloader.prototype.guidUtil; /** * @type {?} * @protected */ BlobDownloader.prototype.cryptoService; /** * @type {?} * @private */ BlobDownloader.prototype.commonUtil; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvYi5kb3dubG9hZGVyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1tYXRlcmlhbC1kYXRhdHJhbnNmZXItbGliLyIsInNvdXJjZXMiOlsibGliL2lvL2Rvd25sb2FkZXJzL2Jsb2IuZG93bmxvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBcUIsZ0JBQWdCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUMzRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU5RDtJQUNvQywwQ0FBYztJQU85Qyx3QkFBc0IsTUFBcUIsRUFBWSxRQUFrQixFQUNuRCxhQUE0QixFQUFVLFVBQXNCO1FBRGxGLFlBRUksa0JBQU0sTUFBTSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsU0FD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Q0QsU0FBUyxJQUFJLG1CQUFtQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO1lBQzFELFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztRQUN4QyxDQUFDLEVBQUMsQ0FBQztRQUNILE9BQU8sU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JELENBQUM7O2dCQTVMSixVQUFVOzs7O2dCQVZGLGFBQWE7Z0JBQ2IsUUFBUTtnQkFDUixhQUFhO2dCQUNiLFVBQVU7O0lBb01uQixxQkFBQztDQUFBLEFBN0xELENBQ29DLGNBQWMsR0E0TGpEO1NBNUxZLGNBQWM7Ozs7OztJQUV2QixtREFBd0M7Ozs7O0lBQ3hDLCtCQUF3Qzs7Ozs7SUFDeEMsK0JBQXdDOzs7OztJQUN4QyxxQ0FBOEM7Ozs7O0lBRWxDLGdDQUErQjs7Ozs7SUFBRSxrQ0FBNEI7Ozs7O0lBQzdELHVDQUFzQzs7Ozs7SUFBRSxvQ0FBOEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IHNhdmVBcyB9IGZyb20gJ2ZpbGUtc2F2ZXInO1xyXG5pbXBvcnQgeyBCYXNlRG93bmxvYWRlciB9IGZyb20gJy4vYmFzZS5kb3dubG9hZGVyJztcclxuaW1wb3J0IHsgSURhdGF0cmFuc2Zlckl0ZW0sIERhdGF0cmFuc2Zlckl0ZW0gfSBmcm9tICcuLi8uLi9tb2RlbHMvZGF0YXRyYW5zZmVyLWl0ZW0ubW9kZWwnO1xyXG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2dnZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbG9nZ2VyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBHdWlkVXRpbCB9IGZyb20gJy4uLy4uL3V0aWxzL2d1aWQudXRpbCc7XHJcbmltcG9ydCB7IENyeXB0b1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jcnlwdG8uc2VydmljZSc7XHJcbmltcG9ydCB7IENvbW1vblV0aWwgfSBmcm9tICcuLi8uLi91dGlscy9jb21tb24udXRpbCc7XHJcbmltcG9ydCB7IFRyYW5zZmVyU3RhdHVzIH0gZnJvbSAnLi4vLi4vZW51bXMvdHJhbnNmZXItc3RhdHVzLmVudW0nO1xyXG5pbXBvcnQgeyBTaXplQ29udGFpbmVyIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3NpemUtY29udGFpbmVyLm1vZGVsJztcclxuaW1wb3J0IHsgRGVjaW1hbEJ5dGVVbml0IH0gZnJvbSAnLi4vLi4vZW51bXMvZGVjaW1hbC1ieXRlLXVuaXQuZW51bSc7XHJcbmltcG9ydCB7IFByb2dyZXNzQ29udGFpbmVyIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3Byb2dyZXNzLWNvbnRhaW5lci5tb2RlbCc7XHJcbmltcG9ydCB7IFRyYW5zZmVyVHlwZSB9IGZyb20gJy4uLy4uL2VudW1zL3RyYW5zZmVyLXR5cGUuZW51bSc7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBCbG9iRG93bmxvYWRlciBleHRlbmRzIEJhc2VEb3dubG9hZGVyIHtcclxuXHJcbiAgICBwcml2YXRlIHRocm90dGxlUHJvZ3Jlc3NDYWxsYmFja3MgPSAwLjE7XHJcbiAgICBwcml2YXRlIGZpbGVzOiBJRGF0YXRyYW5zZmVySXRlbVtdID0gW107XHJcbiAgICBwcml2YXRlIHF1ZXVlOiBJRGF0YXRyYW5zZmVySXRlbVtdID0gW107XHJcbiAgICBwcml2YXRlIGRvd25sb2FkaW5nOiBJRGF0YXRyYW5zZmVySXRlbVtdID0gW107XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJvdGVjdGVkIGxvZ2dlcjogTG9nZ2VyU2VydmljZSwgcHJvdGVjdGVkIGd1aWRVdGlsOiBHdWlkVXRpbCxcclxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBjcnlwdG9TZXJ2aWNlOiBDcnlwdG9TZXJ2aWNlLCBwcml2YXRlIGNvbW1vblV0aWw6IENvbW1vblV0aWwpIHtcclxuICAgICAgICBzdXBlcihsb2dnZXIsIGd1aWRVdGlsLCBjcnlwdG9TZXJ2aWNlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhcnRBbGwoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmlzV29ya2luZygpKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuc2ltdWx0YW5lb3VzRG93bmxvYWRzOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRvd25sb2FkTmV4dCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBwYXVzZUFsbCgpOiB2b2lkIHtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZUFsbCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmZpbGVzLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzIGFzIEJsb2JEb3dubG9hZGVyO1xyXG4gICAgICAgICAgICB0aGF0LmFib3J0RG93bmxvYWQoaXRlbSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5maWxlcy5sZW5ndGggPSAwO1xyXG4gICAgICAgIHRoaXMucXVldWUubGVuZ3RoID0gMDtcclxuICAgICAgICB0aGlzLmRvd25sb2FkaW5nLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5faXNXb3JraW5nID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy51cGRhdGVPdmVyYWxsU2l6ZSh0aGlzLmdldFNpemUoKSk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVPdmVyYWxsUHJvZ3Jlc3ModGhpcy50cmFuc2ZlclR5cGUsIHRoaXMuZ2V0UHJvZ3Jlc3MoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZUl0ZW0oaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmFib3J0RG93bmxvYWQoaXRlbSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVJdGVtRnJvbUFycmF5KGl0ZW0sIHRoaXMuZmlsZXMpO1xyXG4gICAgICAgIHRoaXMucmVtb3ZlSXRlbUZyb21BcnJheShpdGVtLCB0aGlzLnF1ZXVlKTtcclxuICAgICAgICB0aGlzLnJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbSwgdGhpcy5kb3dubG9hZGluZyk7XHJcbiAgICAgICAgdGhpcy5kb3dubG9hZE5leHQoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0sIGFycmF5OiBJRGF0YXRyYW5zZmVySXRlbVtdKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IGFycmF5Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgIGlmIChhcnJheVtpXSA9PT0gaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgYXJyYXkuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJldHJ5SXRlbShpdGVtOiBJRGF0YXRyYW5zZmVySXRlbSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuYWJvcnREb3dubG9hZChpdGVtKTtcclxuICAgICAgICB0aGlzLnJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbSwgdGhpcy5xdWV1ZSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVJdGVtRnJvbUFycmF5KGl0ZW0sIHRoaXMuZG93bmxvYWRpbmcpO1xyXG4gICAgICAgIHRoaXMuX2lzV29ya2luZyA9IHRoaXMuZG93bmxvYWRpbmcubGVuZ3RoID4gMDtcclxuICAgICAgICBpdGVtLmV4dGVybmFsSXRlbS5wcm9ncmVzcyA9IDA7XHJcbiAgICAgICAgdGhpcy51cGRhdGVJdGVtUHJvZ3Jlc3MoaXRlbSwgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MpO1xyXG4gICAgICAgIHRoaXMuY2hhbmdlSXRlbVN0YXR1cyhpdGVtLCBUcmFuc2ZlclN0YXR1cy5RdWV1ZWQpO1xyXG4gICAgICAgIHRoaXMucXVldWUucHVzaChpdGVtKTtcclxuICAgICAgICB0aGlzLmluaXREb3dubG9hZChpdGVtKTtcclxuICAgICAgICB0aGlzLmRvd25sb2FkTmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkb3dubG9hZChmaWxlbmFtZTogc3RyaW5nLCB1cmw6IHN0cmluZywgc2l6ZUluQnl0ZXM6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IG5ld0l0ZW0gPSBuZXcgRGF0YXRyYW5zZmVySXRlbSh7XHJcbiAgICAgICAgICAgIGlkOiB0aGlzLmdlbmVyYXRlVW5pcXVlSWRlbnRpZmllcigpLFxyXG4gICAgICAgICAgICBuYW1lOiBmaWxlbmFtZSxcclxuICAgICAgICAgICAgc2l6ZUNvbnRhaW5lcjogbmV3IFNpemVDb250YWluZXIoeyBkZWNpbWFsQnl0ZVVuaXQ6IERlY2ltYWxCeXRlVW5pdC5CeXRlLCBkZWNpbWFsQnl0ZVVuaXRTaXplOiBzaXplSW5CeXRlcyB9KSxcclxuICAgICAgICAgICAgcHJvZ3Jlc3NDb250YWluZXI6IG5ldyBQcm9ncmVzc0NvbnRhaW5lcihzaXplSW5CeXRlcyksXHJcbiAgICAgICAgICAgIHRyYW5zZmVyVHlwZTogVHJhbnNmZXJUeXBlLkRvd25sb2FkLFxyXG4gICAgICAgICAgICBzdGF0dXM6IFRyYW5zZmVyU3RhdHVzLlF1ZXVlZCxcclxuICAgICAgICAgICAgZXh0ZXJuYWxJdGVtOiB7XHJcbiAgICAgICAgICAgICAgICB1cmwsXHJcbiAgICAgICAgICAgICAgICBwcm9ncmVzczogMCxcclxuICAgICAgICAgICAgICAgIHNpemU6IHNpemVJbkJ5dGVzLFxyXG4gICAgICAgICAgICAgICAgbGFzdFByb2dyZXNzQ2FsbGJhY2s6IG5ldyBEYXRlKClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmFkZEl0ZW0obmV3SXRlbSk7XHJcbiAgICAgICAgdGhpcy5maWxlcy5wdXNoKG5ld0l0ZW0pO1xyXG4gICAgICAgIHRoaXMucXVldWUucHVzaChuZXdJdGVtKTtcclxuICAgICAgICB0aGlzLmluaXREb3dubG9hZChuZXdJdGVtKTtcclxuICAgICAgICB0aGlzLmRvd25sb2FkTmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaW5pdERvd25sb2FkKGl0ZW06IElEYXRhdHJhbnNmZXJJdGVtKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ueGhyID0geGhyO1xyXG5cclxuICAgICAgICB4aHIub3BlbihDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuZG93bmxvYWRNZXRob2QsIGl0ZW0uZXh0ZXJuYWxJdGVtLnVybCk7XHJcbiAgICAgICAgeGhyLnRpbWVvdXQgPSBDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuZG93bmxvYWRYaHJUaW1lb3V0O1xyXG4gICAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSBDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuZG93bmxvYWRXaXRoQ3JlZGVudGlhbHM7XHJcblxyXG4gICAgICAgIC8vIEFkZCBkYXRhIGZyb20gaGVhZGVyIG9wdGlvbnNcclxuICAgICAgICBsZXQgY3VzdG9tSGVhZGVycyA9IENvbmZpZ1NlcnZpY2Uuc2V0dGluZ3MuY29yZS5kb3dubG9hZEhlYWRlcnM7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjdXN0b21IZWFkZXJzID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgIGN1c3RvbUhlYWRlcnMgPSBjdXN0b21IZWFkZXJzKGl0ZW0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbW1vblV0aWwuZWFjaChjdXN0b21IZWFkZXJzLCBmdW5jdGlvbihrOiBzdHJpbmcsIHY6IHN0cmluZykge1xyXG4gICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrLCB2KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9ICdibG9iJztcclxuICAgICAgICB4aHIub25sb2Fkc3RhcnQgPSBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzIGFzIEJsb2JEb3dubG9hZGVyO1xyXG4gICAgICAgICAgICB0aGF0LmNoYW5nZUl0ZW1TdGF0dXMoaXRlbSwgVHJhbnNmZXJTdGF0dXMuRG93bmxvYWRpbmcpO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKTtcclxuICAgICAgICB4aHIub25wcm9ncmVzcyA9IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgQmxvYkRvd25sb2FkZXI7XHJcbiAgICAgICAgICAgIGlmIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGl0ZW0uZXh0ZXJuYWxJdGVtLmxhc3RQcm9ncmVzc0NhbGxiYWNrLmdldFRpbWUoKSA+IHRoYXQudGhyb3R0bGVQcm9ncmVzc0NhbGxiYWNrcyAqIDEwMDApIHtcclxuICAgICAgICAgICAgICAgIGl0ZW0uZXh0ZXJuYWxJdGVtLnByb2dyZXNzID0gZS5sb2FkZWQgLyBlLnRvdGFsO1xyXG4gICAgICAgICAgICAgICAgdGhhdC51cGRhdGVJdGVtUHJvZ3Jlc3MoaXRlbSwgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MpO1xyXG4gICAgICAgICAgICAgICAgdGhhdC51cGRhdGVPdmVyYWxsUHJvZ3Jlc3ModGhhdC50cmFuc2ZlclR5cGUsIHRoYXQuZ2V0UHJvZ3Jlc3MoKSk7XHJcbiAgICAgICAgICAgICAgICBpdGVtLmV4dGVybmFsSXRlbS5sYXN0UHJvZ3Jlc3NDYWxsYmFjayA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LmJpbmQodGhpcyk7XHJcbiAgICAgICAgeGhyLm9ubG9hZGVuZCA9IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgVmFsdWVcdFN0YXRlXHREZXNjcmlwdGlvblxyXG4gICAgICAgICAgICAwXHRVTlNFTlRcdENsaWVudCBoYXMgYmVlbiBjcmVhdGVkLiBvcGVuKCkgbm90IGNhbGxlZCB5ZXQuXHJcbiAgICAgICAgICAgIDFcdE9QRU5FRFx0b3BlbigpIGhhcyBiZWVuIGNhbGxlZC5cclxuICAgICAgICAgICAgMlx0SEVBREVSU19SRUNFSVZFRFx0c2VuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIGhlYWRlcnMgYW5kIHN0YXR1cyBhcmUgYXZhaWxhYmxlLlxyXG4gICAgICAgICAgICAzXHRMT0FESU5HXHREb3dubG9hZGluZzsgcmVzcG9uc2VUZXh0IGhvbGRzIHBhcnRpYWwgZGF0YS5cclxuICAgICAgICAgICAgNFx0RE9ORVx0VGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZS5cclxuICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgQmxvYkRvd25sb2FkZXI7XHJcbiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xyXG4gICAgICAgICAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MgPSAxO1xyXG4gICAgICAgICAgICAgICAgdGhhdC51cGRhdGVJdGVtUHJvZ3Jlc3MoaXRlbSwgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQuY2hhbmdlSXRlbVN0YXR1cyhpdGVtLCBUcmFuc2ZlclN0YXR1cy5GaW5pc2hlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2F2ZUFzKHhoci5yZXNwb25zZSwgaXRlbS5uYW1lKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeGhyLnN0YXR1cyAhPT0gMCkgeyAvLyBkb24ndCBjaGFuZ2Ugc3RhdHVzIGZvciBhYm9ydGVkIGl0ZW1zXHJcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5jaGFuZ2VJdGVtU3RhdHVzKGl0ZW0sIFRyYW5zZmVyU3RhdHVzLkZhaWxlZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGF0LnJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbSwgdGhhdC5kb3dubG9hZGluZyk7XHJcbiAgICAgICAgICAgICAgICB0aGF0LmRvd25sb2FkTmV4dCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZG93bmxvYWROZXh0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudXBkYXRlT3ZlcmFsbFNpemUodGhpcy5nZXRTaXplKCkpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlT3ZlcmFsbFByb2dyZXNzKHRoaXMudHJhbnNmZXJUeXBlLCB0aGlzLmdldFByb2dyZXNzKCkpO1xyXG4gICAgICAgIGlmICh0aGlzLmRvd25sb2FkaW5nLmxlbmd0aCA8IENvbmZpZ1NlcnZpY2Uuc2V0dGluZ3MuY29yZS5zaW11bHRhbmVvdXNEb3dubG9hZHMpIHtcclxuICAgICAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMucXVldWUuc2hpZnQoKTtcclxuICAgICAgICAgICAgaWYgKCEhaXRlbSAmJiAhIWl0ZW0uZXh0ZXJuYWxJdGVtICYmICEhaXRlbS5leHRlcm5hbEl0ZW0ueGhyKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZUl0ZW1TdGF0dXMoaXRlbSwgVHJhbnNmZXJTdGF0dXMuRG93bmxvYWRpbmcpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kb3dubG9hZGluZy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faXNXb3JraW5nID0gdGhpcy5kb3dubG9hZGluZy5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ueGhyLnNlbmQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFib3J0RG93bmxvYWQoaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0pOiB2b2lkIHtcclxuICAgICAgICBpZiAoISFpdGVtICYmICEhaXRlbS5leHRlcm5hbEl0ZW0gJiYgISFpdGVtLmV4dGVybmFsSXRlbS54aHIpIHtcclxuICAgICAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ueGhyLmFib3J0KCk7XHJcbiAgICAgICAgICAgIGl0ZW0uZXh0ZXJuYWxJdGVtLnhociA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0U2l6ZSgpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCB0b3RhbFNpemUgPSAwO1xyXG4gICAgICAgIHRoaXMuZmlsZXMuZm9yRWFjaCgoZmlsZSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgdG90YWxTaXplICs9IGZpbGUuZXh0ZXJuYWxJdGVtLnNpemU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRvdGFsU2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFByb2dyZXNzKCk6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IHRvdGFsRG9uZSA9IDA7XHJcbiAgICAgICAgbGV0IHRvdGFsU2l6ZSA9IDA7XHJcbiAgICAgICAgdGhpcy5maWxlcy5mb3JFYWNoKChmaWxlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBsZXQgY3VycmVudEZpbGVQcm9ncmVzcyA9IGZpbGUuZXh0ZXJuYWxJdGVtLnByb2dyZXNzO1xyXG4gICAgICAgICAgICBpZiAoZmlsZS5zdGF0dXMgPT09IFRyYW5zZmVyU3RhdHVzLkZhaWxlZCkge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudEZpbGVQcm9ncmVzcyA9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdG90YWxEb25lICs9IGN1cnJlbnRGaWxlUHJvZ3Jlc3MgKiBmaWxlLmV4dGVybmFsSXRlbS5zaXplO1xyXG4gICAgICAgICAgICB0b3RhbFNpemUgKz0gZmlsZS5leHRlcm5hbEl0ZW0uc2l6ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdG90YWxTaXplID4gMCA/IHRvdGFsRG9uZSAvIHRvdGFsU2l6ZSA6IDA7XHJcbiAgICB9XHJcbn1cclxuIl19