ais-uploader
Version:
Simple uploader library for Angular 2+
701 lines • 64.5 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, EventEmitter, Inject, Output, PLATFORM_ID, ViewChild, ViewEncapsulation, } from '@angular/core';
import { isPlatformServer } from '@angular/common';
import { DocumentFileType } from './models/uploader-item';
import { AisUploaderService } from './ais-uploader.service';
import { UploaderTypesPipe } from './pipes/uploader-enum.pipe';
var AisUploaderComponent = /** @class */ (function () {
function AisUploaderComponent(platformId, uploderService, uploaderEnum) {
this.uploderService = uploderService;
this.uploaderEnum = uploaderEnum;
this.onChange = new EventEmitter();
this.onProgress = new EventEmitter();
this.onError = new EventEmitter();
this._allowedExtensions = [];
if (isPlatformServer(platformId) || typeof ((/** @type {?} */ (window))).MouseEvent === 'function') {
return;
}
/**
* @param {?} event
* @param {?} params
* @return {?}
*/
function CustomEvent(event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
/** @type {?} */
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
}
CustomEvent.prototype = ((/** @type {?} */ (window))).Event.prototype;
((/** @type {?} */ (window))).CustomEvent = CustomEvent;
}
/**
* @return {?}
*/
AisUploaderComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this._generateAllowedExtensions();
};
/**
* @return {?}
*/
AisUploaderComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
if (this._progressSub$) {
this._progressSub$.unsubscribe();
}
if (this._uploaderSub$) {
this._uploaderSub$.unsubscribe();
}
};
Object.defineProperty(AisUploaderComponent.prototype, "fileName", {
// return file name or arr file names if isMultiple: true
get:
// return file name or arr file names if isMultiple: true
/**
* @return {?}
*/
function () {
if (this.config.isMultiple) {
return this.filesNames;
}
if (!this._file) {
return '';
}
return this._file.name;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AisUploaderComponent.prototype, "filesNames", {
// return arr file names if isMultiple: true
get:
// return arr file names if isMultiple: true
/**
* @return {?}
*/
function () {
if (!this._files || !this._files.length) {
return undefined;
}
return this._files.map(function (file) { return file.name; });
},
enumerable: true,
configurable: true
});
Object.defineProperty(AisUploaderComponent.prototype, "tooltipMessage", {
// return info message
get:
// return info message
/**
* @return {?}
*/
function () {
if (!this.config.supportedFormats.length) {
return "Max. size is " + (this.config.maxSize ? this.config.maxSize : 'unlimited') + " Mb";
}
/** @type {?} */
var formats = this.uploaderEnum.transform(this.config.supportedFormats);
return "Supported formats are " + (formats || 'All formats') + ". Max. size is " + (this.config.maxSize ?
this.config.maxSize : 'unlimited') + " Mb";
},
enumerable: true,
configurable: true
});
// open selction window
// open selction window
/**
* @return {?}
*/
AisUploaderComponent.prototype.select =
// open selction window
/**
* @return {?}
*/
function () {
/** @type {?} */
var event;
if (typeof ((/** @type {?} */ (window))).MouseEvent === 'function') {
event = new MouseEvent('click', {});
}
else {
event = new CustomEvent('click');
}
this.fileSelector.nativeElement.dispatchEvent(event);
};
// remove file from files arr
// remove file from files arr
/**
* @param {?} i
* @return {?}
*/
AisUploaderComponent.prototype.delete =
// remove file from files arr
/**
* @param {?} i
* @return {?}
*/
function (i) {
this._files.splice(i, 1);
};
// remove file or all files
// remove file or all files
/**
* @param {?=} emit
* @return {?}
*/
AisUploaderComponent.prototype.clear =
// remove file or all files
/**
* @param {?=} emit
* @return {?}
*/
function (emit) {
if (emit === void 0) { emit = true; }
this._file = undefined;
this._files = undefined;
this.fileSelector.nativeElement.value = '';
if (emit) {
this.onChange.emit('');
}
};
/**
* @param {?} event
* @return {?}
*/
AisUploaderComponent.prototype.loadFile = /**
* @param {?} event
* @return {?}
*/
function (event) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var e_1, _a, _files, _files_1, _files_1_1, file, isValid, e_1_1, _file, isValid, res, e_2;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!this.config.isMultiple) return [3 /*break*/, 9];
_files = event.target.files;
_b.label = 1;
case 1:
_b.trys.push([1, 6, 7, 8]);
_files_1 = tslib_1.__values(_files), _files_1_1 = _files_1.next();
_b.label = 2;
case 2:
if (!!_files_1_1.done) return [3 /*break*/, 5];
file = _files_1_1.value;
return [4 /*yield*/, this.validate(file)];
case 3:
isValid = _b.sent();
if (!isValid) {
return [2 /*return*/];
}
_b.label = 4;
case 4:
_files_1_1 = _files_1.next();
return [3 /*break*/, 2];
case 5: return [3 /*break*/, 8];
case 6:
e_1_1 = _b.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 8];
case 7:
try {
if (_files_1_1 && !_files_1_1.done && (_a = _files_1.return)) _a.call(_files_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
case 8:
this._files = tslib_1.__spread(_files);
return [3 /*break*/, 11];
case 9:
_file = event.target.files[0];
if (!_file) {
return [2 /*return*/];
}
return [4 /*yield*/, this.validate(_file)];
case 10:
isValid = _b.sent();
if (!isValid) {
return [2 /*return*/];
}
this._file = _file;
_b.label = 11;
case 11:
if (!this.config.isAutoupload) return [3 /*break*/, 16];
_b.label = 12;
case 12:
_b.trys.push([12, 14, , 15]);
return [4 /*yield*/, this.upload()];
case 13:
res = _b.sent();
this.onChange.emit(res);
return [3 /*break*/, 15];
case 14:
e_2 = _b.sent();
this.onError.emit(e_2);
return [3 /*break*/, 15];
case 15: return [2 /*return*/];
case 16:
if (!this.config.isPreviewDisabled) {
this._makePreview();
return [2 /*return*/];
}
this.onChange.emit(this._file.name);
return [2 /*return*/];
}
});
});
};
// upload to server
// upload to server
/**
* @return {?}
*/
AisUploaderComponent.prototype.upload =
// upload to server
/**
* @return {?}
*/
function () {
var _this = this;
if (this._progressSub$) {
this._progressSub$.unsubscribe();
}
this._onLoaderSub();
if (!this.config.isMultiple) {
return new Promise(function (resolve) {
_this._uploaderSub$ = _this.uploderService.upload(_this._file, _this.config).subscribe(function (res) {
_this.onProgress.emit(0);
_this.uploadingProgress = 0;
resolve(res);
}, function (err) {
_this.onError.emit('Uploading error');
_this.preventUploading();
resolve(undefined);
});
});
}
else {
return new Promise(function (resolve) {
_this._uploaderSub$ = _this.uploderService.uploadMultiple(_this._files, _this.config).subscribe(function (res) {
_this.onProgress.emit(0);
_this.uploadingProgress = 0;
resolve(res);
}, function (err) {
_this.onError.emit('Uploading error');
_this.preventUploading();
resolve(undefined);
});
});
}
};
// cancel current uploading
// cancel current uploading
/**
* @return {?}
*/
AisUploaderComponent.prototype.preventUploading =
// cancel current uploading
/**
* @return {?}
*/
function () {
if (!this.uploadingProgress) {
return;
}
if (this._progressSub$) {
this._progressSub$.unsubscribe();
}
if (this._uploaderSub$) {
this._uploaderSub$.unsubscribe();
}
this.onProgress.emit(0);
this.uploadingProgress = 0;
this.clear();
};
/**
* @private
* @param {?} file
* @return {?}
*/
AisUploaderComponent.prototype.validate = /**
* @private
* @param {?} file
* @return {?}
*/
function (file) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var resolution, img, e_3;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!file || !this.config) {
this.throwError('Uploader error');
return [2 /*return*/, false];
}
if (this.config.maxSize &&
file.size / 1024 / 1024 > this.config.maxSize) {
this.throwError("File size should be no more than " + this.config.maxSize + "Mb");
return [2 /*return*/, false];
}
if (this.config.supportedFormats.length && file.type &&
!this.config.supportedFormats.includes(file.type)) {
this.throwError("Unsupported file format");
return [2 /*return*/, false];
}
if (this.config.supportedFormats.length && !file.type &&
!this._validateFormat(file.name)) {
this.throwError("Unsupported file format");
return [2 /*return*/, false];
}
if (!this.config.imageResolution) return [3 /*break*/, 5];
resolution = this.config.imageResolution.split('x');
img = void 0;
if (!resolution || !resolution.length || resolution.length !== 2) {
this.throwError("Unsupported resolution format");
return [2 /*return*/, false];
}
resolution = resolution.map(function (r) { return Math.ceil(Number(r)); }).filter(function (n) { return !!n; });
if (!resolution || !resolution.length || resolution.length !== 2) {
this.throwError("Unsupported resolution format");
return [2 /*return*/, false];
}
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, this._addImageProcess(file)];
case 2:
img = _a.sent();
return [3 /*break*/, 4];
case 3:
e_3 = _a.sent();
console.warn('Resolution property allows only for Images - Error Skipped');
return [2 /*return*/, true];
case 4:
if (img.width !== resolution[0] || img.height !== resolution[1]) {
this.throwError("Unsupported resolution format! Correct resolution is " + this.config.imageResolution);
return [2 /*return*/, false];
}
_a.label = 5;
case 5: return [2 /*return*/, true];
}
});
});
};
/**
* @private
* @param {?} file
* @return {?}
*/
AisUploaderComponent.prototype._addImageProcess = /**
* @private
* @param {?} file
* @return {?}
*/
function (file) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/, new Promise(function (resolve, reject) {
// @ts-ignore
/** @type {?} */
var _URL = window.URL || window.webkitURL;
/** @type {?} */
var img = new Image();
/** @type {?} */
var objectUrl = _URL.createObjectURL(file);
img.onload = function () {
_URL.revokeObjectURL(objectUrl);
return resolve({ height: img.height, width: img.width });
};
img.onerror = reject;
img.src = objectUrl;
})];
});
});
};
/**
* @private
* @return {?}
*/
AisUploaderComponent.prototype._onLoaderSub = /**
* @private
* @return {?}
*/
function () {
var _this = this;
this._progressSub$ = this.uploderService.uploadingProgress
.subscribe(function (progress) {
_this.onProgress.emit(progress);
_this.uploadingProgress = progress;
});
};
/**
* @private
* @return {?}
*/
AisUploaderComponent.prototype._makePreview = /**
* @private
* @return {?}
*/
function () {
var _this = this;
if (!this.config.isMultiple) {
/** @type {?} */
var reader = new FileReader();
reader.onload = function (event) {
_this.onChange.emit(event.target.result);
};
reader.readAsDataURL(this._file);
}
else {
/** @type {?} */
var dataArr_1 = [];
var _loop_1 = function (i) {
/** @type {?} */
var reader = new FileReader();
reader.onload = function (event) {
dataArr_1[i] = (event.target.result);
};
reader.readAsDataURL(this_1._files[i]);
if (i == this_1._files.length - 1) {
this_1.onChange.emit(dataArr_1);
}
};
var this_1 = this;
for (var i = 0; i < this._files.length; i++) {
_loop_1(i);
}
}
};
/**
* @private
* @param {?} name
* @return {?}
*/
AisUploaderComponent.prototype._validateFormat = /**
* @private
* @param {?} name
* @return {?}
*/
function (name) {
if (!this.config.supportedFormats.length) {
return true;
}
/** @type {?} */
var extension = name.split('.').pop().toLowerCase();
return this._allowedExtensions.some(function (s) { return s === extension; });
};
/**
* @private
* @param {?} message
* @return {?}
*/
AisUploaderComponent.prototype.throwError = /**
* @private
* @param {?} message
* @return {?}
*/
function (message) {
this.onError.emit(message);
this.fileSelector.nativeElement.value = '';
};
// tslint:disable-next-line:cyclomatic-complexity
// tslint:disable-next-line:cyclomatic-complexity
/**
* @private
* @return {?}
*/
AisUploaderComponent.prototype._generateAllowedExtensions =
// tslint:disable-next-line:cyclomatic-complexity
/**
* @private
* @return {?}
*/
function () {
var e_4, _a;
if (!this.config || !this.config.supportedFormats) {
return;
}
try {
for (var _b = tslib_1.__values(this.config.supportedFormats), _c = _b.next(); !_c.done; _c = _b.next()) {
var format = _c.value;
switch (format) {
case DocumentFileType.DOC:
this._allowedExtensions.push('doc');
break;
case DocumentFileType.DOCX:
this._allowedExtensions.push('docx');
break;
case DocumentFileType.XLSX:
this._allowedExtensions.push('xlsx');
break;
case DocumentFileType.XLS:
this._allowedExtensions.push('xls');
break;
case DocumentFileType.PDF:
this._allowedExtensions.push('pdf');
break;
case DocumentFileType.TXT:
this._allowedExtensions.push('txt');
break;
case DocumentFileType.PPTX:
this._allowedExtensions.push('pptx');
break;
case DocumentFileType.PPT:
this._allowedExtensions.push('ppt');
break;
case DocumentFileType.AVI:
this._allowedExtensions.push('avi');
break;
case DocumentFileType.FLV:
this._allowedExtensions.push('flv');
break;
case DocumentFileType.MP4:
this._allowedExtensions.push('mp4');
break;
case DocumentFileType.MPEG:
this._allowedExtensions.push('mpeg');
break;
case DocumentFileType.OGG:
this._allowedExtensions.push('ogg');
break;
case DocumentFileType.WEBM:
this._allowedExtensions.push('webm');
break;
case DocumentFileType.JPEG:
this._allowedExtensions.push('jpeg');
break;
case DocumentFileType.JPG:
this._allowedExtensions.push('jpg');
break;
case DocumentFileType.PNG:
this._allowedExtensions.push('png');
break;
case DocumentFileType.TIFF:
this._allowedExtensions.push('tiff');
break;
case DocumentFileType.WBMP:
this._allowedExtensions.push('wbmp');
break;
case DocumentFileType.WEBP:
this._allowedExtensions.push('webp');
break;
case DocumentFileType.SVG:
this._allowedExtensions.push('svg');
break;
case DocumentFileType.GIF:
this._allowedExtensions.push('gif');
break;
case DocumentFileType.CSV:
this._allowedExtensions.push('csv');
break;
case DocumentFileType.MSCSV:
this._allowedExtensions.push('csv');
break;
case DocumentFileType.MOV:
this._allowedExtensions.push('mov');
break;
case DocumentFileType.MP3:
this._allowedExtensions.push('mp3');
break;
case DocumentFileType.WAV:
this._allowedExtensions.push('wav');
break;
case DocumentFileType.XWAV:
this._allowedExtensions.push('wav');
break;
default:
break;
}
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_4) throw e_4.error; }
}
};
AisUploaderComponent.decorators = [
{ type: Component, args: [{
selector: 'ais-uploader',
template: "<input id=\"uploader_lib\" #fileSelector type=\"file\" [accept]=\"config?.supportedFormats | uploaderTypes:true\"\r\n (change)=\"loadFile($event)\">\r\n",
encapsulation: ViewEncapsulation.None,
styles: ["#uploader_lib{display:none}@keyframes blink{0%,100%{box-shadow:0 2px 2px rgba(0,0,0,.24),0 0 2px rgba(0,0,0,.12)}50%{box-shadow:none}}@-webkit-keyframes blink{0%,100%{box-shadow:0 2px 2px rgba(0,0,0,.24),0 0 2px rgba(0,0,0,.12)}50%{box-shadow:0 0 0}}.blink{-webkit-animation:3s linear infinite blink;animation:3s linear infinite blink}"]
}] }
];
/** @nocollapse */
AisUploaderComponent.ctorParameters = function () { return [
{ type: String, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
{ type: AisUploaderService },
{ type: UploaderTypesPipe }
]; };
AisUploaderComponent.propDecorators = {
onChange: [{ type: Output }],
onProgress: [{ type: Output }],
onError: [{ type: Output }],
fileSelector: [{ type: ViewChild, args: ['fileSelector',] }]
};
return AisUploaderComponent;
}());
export { AisUploaderComponent };
if (false) {
/** @type {?} */
AisUploaderComponent.prototype.config;
/** @type {?} */
AisUploaderComponent.prototype.uploadingProgress;
/** @type {?} */
AisUploaderComponent.prototype.onChange;
/** @type {?} */
AisUploaderComponent.prototype.onProgress;
/** @type {?} */
AisUploaderComponent.prototype.onError;
/** @type {?} */
AisUploaderComponent.prototype.fileSelector;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._file;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._files;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._allowedExtensions;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._progressSub$;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._uploaderSub$;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype.uploderService;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype.uploaderEnum;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWlzLXVwbG9hZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2Fpcy11cGxvYWRlci8iLCJzb3VyY2VzIjpbImxpYi9haXMtdXBsb2FkZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUdOLE1BQU0sRUFDTixXQUFXLEVBQ1gsU0FBUyxFQUNULGlCQUFpQixHQUNwQixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUUvRDtJQW9CSSw4QkFDeUIsVUFBa0IsRUFDL0IsY0FBa0MsRUFDbEMsWUFBK0I7UUFEL0IsbUJBQWMsR0FBZCxjQUFjLENBQW9CO1FBQ2xDLGlCQUFZLEdBQVosWUFBWSxDQUFtQjtRQWRqQyxhQUFRLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakQsZUFBVSxHQUF5QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3RELFlBQU8sR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUtyRCx1QkFBa0IsR0FBYSxFQUFFLENBQUM7UUFTdEMsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsSUFBSSxPQUFPLENBQUMsbUJBQUssTUFBTSxFQUFBLENBQUMsQ0FBQyxVQUFVLEtBQUssVUFBVSxFQUFFO1lBQ2hGLE9BQU87U0FDVjs7Ozs7O1FBRUQsU0FBUyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU07WUFDOUIsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFB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QU07NkJBQ04sTUFBTTswQkFDTixNQUFNOytCQUVOLFNBQVMsU0FBQyxjQUFjOztJQTZYN0IsMkJBQUM7Q0FBQSxBQTFZRCxJQTBZQztTQXBZWSxvQkFBb0I7OztJQUM3QixzQ0FBdUI7O0lBQ3ZCLGlEQUEwQjs7SUFDMUIsd0NBQTJEOztJQUMzRCwwQ0FBZ0U7O0lBQ2hFLHVDQUE2RDs7SUFFN0QsNENBQXdDOzs7OztJQUN4QyxxQ0FBb0I7Ozs7O0lBQ3BCLHNDQUF1Qjs7Ozs7SUFDdkIsa0RBQTBDOzs7OztJQUMxQyw2Q0FBb0M7Ozs7O0lBQ3BDLDZDQUFvQzs7Ozs7SUFJaEMsOENBQTBDOzs7OztJQUMxQyw0Q0FBdUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgRXZlbnRFbWl0dGVyLFxyXG4gICAgSW5qZWN0LFxyXG4gICAgT25EZXN0cm95LFxyXG4gICAgT25Jbml0LFxyXG4gICAgT3V0cHV0LFxyXG4gICAgUExBVEZPUk1fSUQsXHJcbiAgICBWaWV3Q2hpbGQsXHJcbiAgICBWaWV3RW5jYXBzdWxhdGlvbixcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVXBsb2FkZXJDb25maWcgfSBmcm9tICcuL21vZGVscy91cGxvYWRlci1jb25maWcnO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgaXNQbGF0Zm9ybVNlcnZlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IERvY3VtZW50RmlsZVR5cGUgfSBmcm9tICcuL21vZGVscy91cGxvYWRlci1pdGVtJztcclxuaW1wb3J0IHsgQWlzVXBsb2FkZXJTZXJ2aWNlIH0gZnJvbSAnLi9haXMtdXBsb2FkZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFVwbG9hZGVyVHlwZXNQaXBlIH0gZnJvbSAnLi9waXBlcy91cGxvYWRlci1lbnVtLnBpcGUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ2Fpcy11cGxvYWRlcicsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vYWlzLXVwbG9hZGVyLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2Fpcy11cGxvYWRlci5jb21wb25lbnQuc2NzcyddLFxyXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcclxufSlcclxuZXhwb3J0IGNsYXNzIEFpc1VwbG9hZGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gICAgY29uZmlnOiBVcGxvYWRlckNvbmZpZztcclxuICAgIHVwbG9hZGluZ1Byb2dyZXNzOiBudW1iZXI7XHJcbiAgICBAT3V0cHV0KCkgb25DaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgQE91dHB1dCgpIG9uUHJvZ3Jlc3M6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgQE91dHB1dCgpIG9uRXJyb3I6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICAgIEBWaWV3Q2hpbGQoJ2ZpbGVTZWxlY3RvcicpIGZpbGVTZWxlY3RvcjtcclxuICAgIHByaXZhdGUgX2ZpbGU6IEZpbGU7XHJcbiAgICBwcml2YXRlIF9maWxlczogRmlsZVtdO1xyXG4gICAgcHJpdmF0ZSBfYWxsb3dlZEV4dGVuc2lvbnM6IHN0cmluZ1tdID0gW107XHJcbiAgICBwcml2YXRlIF9wcm9ncmVzc1N1YiQ6IFN1YnNjcmlwdGlvbjtcclxuICAgIHByaXZhdGUgX3VwbG9hZGVyU3ViJDogU3Vic2NyaXB0aW9uO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHBsYXRmb3JtSWQ6IHN0cmluZyxcclxuICAgICAgICBwcml2YXRlIHVwbG9kZXJTZXJ2aWNlOiBBaXNVcGxvYWRlclNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSB1cGxvYWRlckVudW06IFVwbG9hZGVyVHlwZXNQaXBlLFxyXG4gICAgKSB7XHJcbiAgICAgICAgaWYgKGlzUGxhdGZvcm1TZXJ2ZXIocGxhdGZvcm1JZCkgfHwgdHlwZW9mICg8YW55PndpbmRvdykuTW91c2VFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBDdXN0b21FdmVudChldmVudCwgcGFyYW1zKTogYW55IHtcclxuICAgICAgICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHtidWJibGVzOiBmYWxzZSwgY2FuY2VsYWJsZTogZmFsc2UsIGRldGFpbDogdW5kZWZpbmVkfTtcclxuICAgICAgICAgICAgY29uc3QgZXZ0OiBhbnkgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcclxuICAgICAgICAgICAgZXZ0LmluaXRDdXN0b21FdmVudChldmVudCwgcGFyYW1zLmJ1YmJsZXMsIHBhcmFtcy5jYW5jZWxhYmxlLCBwYXJhbXMuZGV0YWlsKTtcclxuICAgICAgICAgICAgcmV0dXJuIGV2dDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIEN1c3RvbUV2ZW50LnByb3RvdHlwZSA9ICg8YW55PndpbmRvdykuRXZlbnQucHJvdG90eXBlO1xyXG4gICAgICAgICg8YW55PndpbmRvdykuQ3VzdG9tRXZlbnQgPSBDdXN0b21FdmVudDtcclxuICAgIH1cclxuXHJcbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9nZW5lcmF0ZUFsbG93ZWRFeHRlbnNpb25zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3Byb2dyZXNzU3ViJCkge1xyXG4gICAgICAgICAgICB0aGlzLl9wcm9ncmVzc1N1YiQudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuX3VwbG9hZGVyU3ViJCkge1xyXG4gICAgICAgICAgICB0aGlzLl91cGxvYWRlclN1YiQudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmV0dXJuIGZpbGUgbmFtZSBvciBhcnIgZmlsZSBuYW1lcyBpZiBpc011bHRpcGxlOiB0cnVlXHJcbiAgICBnZXQgZmlsZU5hbWUoKTogc3RyaW5nIHwgc3RyaW5nW10ge1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5pc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbGVzTmFtZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5fZmlsZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLl9maWxlLm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmV0dXJuIGFyciBmaWxlIG5hbWVzIGlmIGlzTXVsdGlwbGU6IHRydWVcclxuICAgIGdldCBmaWxlc05hbWVzKCk6IHN0cmluZ1tdIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2ZpbGVzIHx8ICF0aGlzLl9maWxlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbGVzLm1hcChmaWxlID0+IGZpbGUubmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmV0dXJuIGluZm8gbWVzc2FnZVxyXG4gICAgZ2V0IHRvb2x0aXBNZXNzYWdlKCk6IHN0cmluZyB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5zdXBwb3J0ZWRGb3JtYXRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICByZXR1cm4gYE1heC4gc2l6ZSBpcyAke3RoaXMuY29uZmlnLm1heFNpemUgPyB0aGlzLmNvbmZpZy5tYXhTaXplIDogJ3VubGltaXRlZCd9IE1iYDtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZm9ybWF0cyA9IHRoaXMudXBsb2FkZXJFbnVtLnRyYW5zZm9ybSh0aGlzLmNvbmZpZy5zdXBwb3J0ZWRGb3JtYXRzKTtcclxuICAgICAgICByZXR1cm4gYFN1cHBvcnRlZCBmb3JtYXRzIGFyZSAke2Zvcm1hdHMgfHwgJ0FsbCBmb3JtYXRzJ30uIE1heC4gc2l6ZSBpcyAke3RoaXMuY29uZmlnLm1heFNpemUgP1xyXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5tYXhTaXplIDogJ3VubGltaXRlZCd9IE1iYDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBvcGVuIHNlbGN0aW9uIHdpbmRvd1xyXG4gICAgc2VsZWN0KCk6IHZvaWQge1xyXG4gICAgICAgIGxldCBldmVudDogYW55O1xyXG4gICAgICAgIGlmICh0eXBlb2YgKDxhbnk+d2luZG93KS5Nb3VzZUV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgIGV2ZW50ID0gbmV3IE1vdXNlRXZlbnQoJ2NsaWNrJywge30pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCdjbGljaycpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmZpbGVTZWxlY3Rvci5uYXRpdmVFbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJlbW92ZSBmaWxlIGZyb20gZmlsZXMgYXJyXHJcbiAgICBkZWxldGUoaTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZmlsZXMuc3BsaWNlKGksIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJlbW92ZSBmaWxlIG9yIGFsbCBmaWxlc1xyXG4gICAgY2xlYXIoZW1pdDogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9maWxlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMuX2ZpbGVzID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMuZmlsZVNlbGVjdG9yLm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcclxuICAgICAgICBpZiAoZW1pdCkge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlLmVtaXQoJycpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBsb2FkRmlsZShldmVudCk6IFByb21pc2U8YW55PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmlzTXVsdGlwbGUpIHtcclxuICAgICAgICAgICAgY29uc3QgX2ZpbGVzID0gZXZlbnQudGFyZ2V0LmZpbGVzO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgX2ZpbGVzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpc1ZhbGlkID0gYXdhaXQgdGhpcy52YWxpZGF0ZShmaWxlKTtcclxuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9maWxlcyA9IFsuLi5fZmlsZXNdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IF9maWxlID0gZXZlbnQudGFyZ2V0LmZpbGVzWzBdO1xyXG4gICAgICAgICAgICBpZiAoIV9maWxlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgaXNWYWxpZCA9IGF3YWl0IHRoaXMudmFsaWRhdGUoX2ZpbGUpO1xyXG4gICAgICAgICAgIC