UNPKG

sp-attachment-library

Version:

This is library is used ro do attachments realted actions on a list item in Sharepoint Angular SPA Addins.

657 lines 54.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, Input } from '@angular/core'; import { SpAttachmentLibraryService } from './sp-attachment-library.service'; import { fileToBlob } from '../shared/file-util'; import * as fa from '@fortawesome/free-solid-svg-icons'; import Swal from 'sweetalert2'; var SpAttachmentLibraryComponent = /** @class */ (function () { function SpAttachmentLibraryComponent(spAttachmentLibraryService) { this.spAttachmentLibraryService = spAttachmentLibraryService; this.attachments = []; this.unUpLoadedItems = 0; this.fa = fa; this.deleteSwalOptions = { title: 'Do you really want to delete this attachment?', type: 'warning', confirmButtonText: 'Yes, delete it!', cancelButtonText: 'No, keep it', showCancelButton: 'true', customClass: { confirmButton: 'btn btn-success', cancelButton: 'btn btn-danger ml-sm-2' } }; this.deleteAllSwalOptions = { title: 'Do you really want to delete all selected attachments?', message: 'All selected attachments added to this list item will be deleted.', type: 'warning', confirmButtonText: 'Yes, delete it!', cancelButtonText: 'No, keep it', showCancelButton: 'true', customClass: { confirmButton: 'btn btn-danger', cancelButton: 'btn btn-success ml-sm-2' } }; } Object.defineProperty(SpAttachmentLibraryComponent.prototype, "listName", { set: /** * @param {?} listName * @return {?} */ function (listName) { this._listName = listName; }, enumerable: true, configurable: true }); Object.defineProperty(SpAttachmentLibraryComponent.prototype, "itemId", { set: /** * @param {?} itemId * @return {?} */ function (itemId) { this._itemId = itemId; }, enumerable: true, configurable: true }); /** * @return {?} */ SpAttachmentLibraryComponent.prototype.ngOnInit = /** * @return {?} */ function () { if (this._listName && this._itemId) { this.loadExistingFiles(); } }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.loadExistingFiles = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var unuploaded = this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return !x.isSelected && x.serverRelativeUrl === null; })); this.spAttachmentLibraryService.getAttachmentsById(this._listName, this._itemId).then((/** * @param {?} data * @return {?} */ function (data) { var _a; _this.attachments = []; data.result.forEach((/** * @param {?} element * @return {?} */ function (element) { _this.attachments.push({ fileName: element.FileName, content: null, extension: element.FileName.substring(element.FileName.lastIndexOf('.') + 1), serverRelativeUrl: element.ServerRelativeUrl, isUploaded: false, isContentChanged: false, isLoading: false, isSelected: false, }); })); (_a = _this.attachments).push.apply(_a, tslib_1.__spread(unuploaded)); })); }; /** * @param {?} event * @return {?} */ SpAttachmentLibraryComponent.prototype.onAttachmentAdded = /** * @param {?} event * @return {?} */ function (event) { var _this = this; var e_1, _a; var _loop_1 = function (file) { if (this_1.attachments.findIndex((/** * @param {?} x * @return {?} */ function (x) { return x.fileName === file.name; })) < 0) { this_1.getBase64(file) .then((/** * @param {?} response * @return {?} */ function (response) { _this.attachments.push({ fileName: (/** @type {?} */ (file.name)), content: (/** @type {?} */ (response)), extension: file.name.substring(file.name.lastIndexOf('.') + 1), serverRelativeUrl: null, isUploaded: false, isContentChanged: false, isLoading: false, isSelected: false, }); })); } else { this_1.promptReplace(file); } }; var this_1 = this; try { for (var _b = tslib_1.__values(event.target.files), _c = _b.next(); !_c.done; _c = _b.next()) { var file = _c.value; _loop_1(file); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } }; /** * @param {?} file * @return {?} */ SpAttachmentLibraryComponent.prototype.promptReplace = /** * @param {?} file * @return {?} */ function (file) { var _this = this; /** @type {?} */ var replaceContentSwal = Swal.mixin({ customClass: { confirmButton: 'btn btn-success', cancelButton: 'btn btn-danger ml-sm-2' }, buttonsStyling: false, }); replaceContentSwal.fire({ title: 'File already exists. Do you want to replace it?', text: 'The file content will be replaced', type: 'warning', showCancelButton: true, confirmButtonText: 'Yes, replace it!', cancelButtonText: 'No, keep it' }).then((/** * @param {?} result * @return {?} */ function (result) { if (result.value) { _this.getBase64(file) .then((/** * @param {?} response * @return {?} */ function (response) { /** @type {?} */ var exitingFileIndex = _this.attachments.findIndex((/** * @param {?} x * @return {?} */ function (x) { return x.fileName === file.name; })); /** @type {?} */ var existingItem = _this.attachments.find((/** * @param {?} x * @return {?} */ function (x) { return x.fileName === file.name; })); existingItem.content = (/** @type {?} */ (response)); existingItem.extension = file.name.substring(file.name.lastIndexOf('.') + 1); existingItem.isContentChanged = true; existingItem.isUploaded = false; _this.attachments.splice(exitingFileIndex, 1, existingItem); })); } else if (result.dismiss === Swal.DismissReason.cancel) { Swal.fire('Cancelled'); } })); }; /** * @param {?} event * @return {?} */ SpAttachmentLibraryComponent.prototype.resetFiles = /** * @param {?} event * @return {?} */ function (event) { event.target.value = null; }; /** * @param {?} file * @return {?} */ SpAttachmentLibraryComponent.prototype.removeAttachment = /** * @param {?} file * @return {?} */ function (file) { var _this = this; file.isLoading = true; if (!file.serverRelativeUrl) { /** @type {?} */ var index = this.attachments.findIndex((/** * @param {?} x * @return {?} */ function (x) { return x.fileName === file.fileName; })); file.isLoading = false; this.attachments.splice(index, 1); } else { file.isLoading = true; this.spAttachmentLibraryService.deleteAttachment(this._listName, this._itemId, file.fileName).then((/** * @param {?} data * @return {?} */ function (data) { /** @type {?} */ var index = _this.attachments.findIndex((/** * @param {?} x * @return {?} */ function (x) { return x.fileName === file.fileName; })); file.isLoading = false; _this.attachments.splice(index, 1); })).catch((/** * @param {?} error * @return {?} */ function (error) { console.log(error); })); } }; /** * @param {?} file * @return {?} */ SpAttachmentLibraryComponent.prototype.uploadAttachment = /** * @param {?} file * @return {?} */ function (file) { var _this = this; file.isLoading = true; this._selectedUploadAttachment = { content: fileToBlob(file), name: file.fileName }; this.spAttachmentLibraryService.addAttachment(this._listName, this._itemId, this._selectedUploadAttachment).then((/** * @param {?} data * @return {?} */ function (data) { file.isLoading = false; /** @type {?} */ var fileIndex = _this.attachments.findIndex((/** * @param {?} x * @return {?} */ function (x) { return x.fileName === file.fileName; })); _this.attachments[fileIndex].serverRelativeUrl = data.result.data.ServerRelativeUrl; _this.attachments[fileIndex].isContentChanged = false; })).catch((/** * @param {?} error * @return {?} */ function (error) { console.log(error); })); }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.hasNewUnUploadedAndSelcted = /** * @return {?} */ function () { return this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return x.serverRelativeUrl === null && x.isSelected; })).length > 0; }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.getUnUploadedCount = /** * @return {?} */ function () { return this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return x.serverRelativeUrl === null && x.isSelected; })).length; }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.hasSelected = /** * @return {?} */ function () { return this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return x.isSelected; })).length > 0; }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.allSelected = /** * @return {?} */ function () { return this.attachments.every((/** * @param {?} x * @return {?} */ function (x) { return x.isSelected; })); }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.getSelectedCount = /** * @return {?} */ function () { return this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return x.isSelected; })).length; }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.markOrUnMarkAll = /** * @return {?} */ function () { this.attachments.forEach((/** * @param {?} e * @return {?} */ function (e) { e.isSelected = e.isSelected ? false : true; })); }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.uploadNewAttachments = /** * @return {?} */ function () { var _this = this; var e_2, _a; /** @type {?} */ var newAttachments = Array(); /** @type {?} */ var newlyAddedAttachments = this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return x.serverRelativeUrl === null && x.isSelected; })); newlyAddedAttachments.forEach((/** * @param {?} x * @return {?} */ function (x) { x.isLoading = true; })); /** @type {?} */ var promises = []; try { for (var newlyAddedAttachments_1 = tslib_1.__values(newlyAddedAttachments), newlyAddedAttachments_1_1 = newlyAddedAttachments_1.next(); !newlyAddedAttachments_1_1.done; newlyAddedAttachments_1_1 = newlyAddedAttachments_1.next()) { var attachment = newlyAddedAttachments_1_1.value; promises.push(fileToBlob(attachment)); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (newlyAddedAttachments_1_1 && !newlyAddedAttachments_1_1.done && (_a = newlyAddedAttachments_1.return)) _a.call(newlyAddedAttachments_1); } finally { if (e_2) throw e_2.error; } } Promise.all(promises).then((/** * @param {?} attachmentBlobs * @return {?} */ function (attachmentBlobs) { attachmentBlobs.forEach((/** * @param {?} blob * @param {?} index * @return {?} */ function (blob, index) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, newAttachments.push({ name: (newlyAddedAttachments[index].fileName), content: blob })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })); _this.spAttachmentLibraryService.addAttachments(_this._listName, _this._itemId, newAttachments).then((/** * @param {?} data * @return {?} */ function (data) { _this.loadExistingFiles(); })).catch((/** * @param {?} error * @return {?} */ function (error) { console.log(error); })); })).catch((/** * @param {?} error * @return {?} */ function (error) { console.log(error); })); }; /** * @param {?} file * @return {?} */ SpAttachmentLibraryComponent.prototype.replaceAttachment = /** * @param {?} file * @return {?} */ function (file) { var _this = this; file.isLoading = true; this.spAttachmentLibraryService.deleteAttachment(this._listName, this._itemId, file.fileName).then((/** * @param {?} data * @return {?} */ function (data) { file.isLoading = false; _this.uploadAttachment(file); })).catch((/** * @param {?} error * @return {?} */ function (error) { console.log(error); })); }; /** * @return {?} */ SpAttachmentLibraryComponent.prototype.deleteSelected = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var selectedLocalAttachments = this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return x.isSelected && x.serverRelativeUrl === null; })); this.attachments.forEach((/** * @param {?} e * @return {?} */ function (e) { e.isLoading = e.isSelected ? true : false; })); selectedLocalAttachments.forEach((/** * @param {?} e * @return {?} */ function (e) { /** @type {?} */ var index = _this.attachments.findIndex((/** * @param {?} a * @return {?} */ function (a) { return a.fileName === e.fileName; })); _this.attachments.splice(index, 1); })); /** @type {?} */ var serverFiles = this.attachments.filter((/** * @param {?} x * @return {?} */ function (x) { return x.serverRelativeUrl !== null && x.isSelected; })); this.attachments.forEach((/** * @param {?} e * @return {?} */ function (e) { e.isLoading = e.isSelected ? true : false; })); /** @type {?} */ var fileNames = serverFiles.map((/** * @param {?} x * @return {?} */ function (x) { return x.fileName; })); this.spAttachmentLibraryService.deleteAttachments(this._listName, this._itemId, fileNames).then((/** * @param {?} data * @return {?} */ function (data) { _this.loadExistingFiles(); })).catch((/** * @param {?} error * @return {?} */ function (error) { console.log(error); })); }; /** * @param {?} file * @return {?} */ SpAttachmentLibraryComponent.prototype.getBase64 = /** * @param {?} file * @return {?} */ function (file) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ function (resolve, reject) { /** @type {?} */ var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (/** * @return {?} */ function () { return resolve(reader.result); }); reader.onerror = (/** * @param {?} error * @return {?} */ function (error) { return reject(error); }); })); }; SpAttachmentLibraryComponent.decorators = [ { type: Component, args: [{ selector: 'sp-attachment', template: "<div class=\"container\">\r\n <h4>Attachments</h4>\r\n <div class=\"row\">\r\n <div class=\"col-md-12\">\r\n <div class=\"form-group\">\r\n <label class=\"control-label\">Attachments</label>\r\n <input type=\"file\" multiple size=\"50\" class=\"custom-file-input\" id=\"customFile\" name=\"filename\"\r\n base-sixty-four-input (click)=\"resetFiles($event)\" (input)=\"onAttachmentAdded($event)\">\r\n <label class=\"custom-file-label\" for=\"customFile\">choose your attachments</label>\r\n <ul class=\"list-group\">\r\n <li class=\"list-group-item\">\r\n <div class=\"row\">\r\n <div class=\"col-md-8 pull-left\">Files</div>\r\n <div class=\"col-md-4 pull-right\">Actions</div>\r\n </div>\r\n </li>\r\n </ul>\r\n <ul class=\"list-group\" *ngFor=\"let attachment of attachments\">\r\n <li *ngIf=\"!attachment.isLoading\" class=\"list-group-item\">\r\n <div class=\"row\">\r\n <div class=\"col-md-8 pull-left\">\r\n <div class=\"form-check\">\r\n <input type=\"checkbox\" [(ngModel)]=\"attachment.isSelected\" class=\"form-check-input\" id=\"{{ attachment.fileName }}\">\r\n </div>\r\n <a class=\"ml-sm-3\" href=\"{{ attachment.serverRelativeUrl }}\" target=\"_blank\">\r\n {{attachment.fileName}}\r\n </a>\r\n </div>\r\n <div class=\"col-md-4 pull-right\">\r\n <button class=\"btn btn-danger btn-xs\" [swal]=\"deleteSwalOptions\"\r\n (confirm)=\"removeAttachment(attachment)\">\r\n <fa-icon [icon]=\"fa.faTrash\"></fa-icon>\r\n </button>\r\n <button *ngIf=\"!attachment.serverRelativeUrl\" class=\"btn btn-primary btn-xs ml-sm-2\"\r\n (click)=\"uploadAttachment(attachment)\">\r\n <fa-icon [icon]=\"fa.faUpload\"></fa-icon>\r\n </button>\r\n <button *ngIf=\"attachment.isContentChanged\" class=\"btn btn-primary btn-xs ml-sm-2\"\r\n (click)=\"replaceAttachment(attachment)\">\r\n <fa-icon [icon]=\"fa.faEdit\"></fa-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n <li *ngIf=\"attachment.isLoading\" class=\"list-group-item animated-background\">\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-md-12\" *ngIf=\"attachments.length > 0\">\r\n <button type=\"button\" class=\"btn btn-info btn-sm ml-sm-2\"\r\n (click)=\"markOrUnMarkAll()\">\r\n {{ allSelected() ? 'Unmark All' : 'Mark All'}}\r\n </button>\r\n <button *ngIf=\"hasNewUnUploadedAndSelcted()\" type=\"button\" class=\"btn btn-success btn-sm ml-sm-2\"\r\n (click)=\"uploadNewAttachments()\">\r\n Upload Selected({{ getUnUploadedCount() }})\r\n </button>\r\n <button *ngIf=\"hasSelected()\" type=\"button\" class=\"btn btn-danger btn-sm ml-sm-2\" [swal]=\"deleteAllSwalOptions\"\r\n (confirm)=\"deleteSelected()\">Delete Selected({{ getSelectedCount() }})\r\n </button>\r\n </div>\r\n </div>\r\n</div>", styles: [".btn-group-xs>.btn,.btn-xs{padding:.25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}.loader-container{margin:0 auto;width:400px;max-width:90%;display:flex;flex-direction:column;justify-content:center;align-items:center}@-webkit-keyframes placeholder{0%{background-position:-600px 0}100%{background-position:600px 0}}@keyframes placeholder{0%{background-position:-600px 0}100%{background-position:600px 0}}.animated-background{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:placeholder;animation-name:placeholder;-webkit-animation-timing-function:linear;animation-timing-function:linear;background:#eee;background:linear-gradient(to right,#eee 8%,#ddd 18%,#eee 33%);background-size:1200px 100px;min-height:30px;width:100%;margin:5px 0;border-radius:3px}"] }] } ]; /** @nocollapse */ SpAttachmentLibraryComponent.ctorParameters = function () { return [ { type: SpAttachmentLibraryService } ]; }; SpAttachmentLibraryComponent.propDecorators = { listName: [{ type: Input }], itemId: [{ type: Input }] }; return SpAttachmentLibraryComponent; }()); export { SpAttachmentLibraryComponent }; if (false) { /** * @type {?} * @private */ SpAttachmentLibraryComponent.prototype._listName; /** * @type {?} * @private */ SpAttachmentLibraryComponent.prototype._itemId; /** * @type {?} * @private */ SpAttachmentLibraryComponent.prototype._selectedUploadAttachment; /** @type {?} */ SpAttachmentLibraryComponent.prototype.attachments; /** @type {?} */ SpAttachmentLibraryComponent.prototype.unUpLoadedItems; /** @type {?} */ SpAttachmentLibraryComponent.prototype.fa; /** @type {?} */ SpAttachmentLibraryComponent.prototype.deleteSwalOptions; /** @type {?} */ SpAttachmentLibraryComponent.prototype.deleteAllSwalOptions; /** * @type {?} * @private */ SpAttachmentLibraryComponent.prototype.spAttachmentLibraryService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3AtYXR0YWNobWVudC1saWJyYXJ5LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3NwLWF0dGFjaG1lbnQtbGlicmFyeS8iLCJzb3VyY2VzIjpbImxpYi9zcC1hdHRhY2htZW50LWxpYnJhcnkuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBSWpELE9BQU8sS0FBSyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDeEQsT0FBTyxJQUFJLE1BQU0sYUFBYSxDQUFDO0FBRS9CO0lBb0RJLHNDQUFvQiwwQkFBc0Q7UUFBdEQsK0JBQTBCLEdBQTFCLDBCQUEwQixDQUE0QjtRQXhDMUUsZ0JBQVcsR0FBaUIsRUFBRSxDQUFDO1FBQy9CLG9CQUFlLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLE9BQUUsR0FBRyxFQUFFLENBQUM7UUFFUixzQkFBaUIsR0FBRztZQUNoQixLQUFLLEVBQUUsK0NBQStDO1lBQ3RELElBQUksRUFBRSxTQUFTO1lBQ2YsaUJBQWlCLEVBQUUsaUJBQWlCO1lBQ3BDLGdCQUFnQixFQUFFLGFBQWE7WUFDL0IsZ0JBQWdCLEVBQUUsTUFBTTtZQUN4QixXQUFXLEVBQUU7Z0JBQ1QsYUFBYSxFQUFFLGlCQUFpQjtnQkFDaEMsWUFBWSxFQUFFLHdCQUF3QjthQUN6QztTQUNKLENBQUM7UUFFRix5QkFBb0IsR0FBRztZQUNuQixLQUFLLEVBQUUsd0RBQXdEO1lBQy9ELE9BQU8sRUFBRSxtRUFBbUU7WUFDNUUsSUFBSSxFQUFFLFNBQVM7WUFDZixpQkFBaUIsRUFBRSxpQkFBaUI7WUFDcEMsZ0JBQWdCLEVBQUUsYUFBYTtZQUMvQixnQkFBZ0IsRUFBRSxNQUFNO1lBQ3hCLFdB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b0JBQ1AsUUFBUSxFQUFFLGVBQWU7b0JBQ3pCLCs2SEFBcUQ7O2lCQUV4RDs7OztnQkFiUSwwQkFBMEI7OzsyQkFrRDlCLEtBQUs7eUJBS0wsS0FBSzs7SUFxT1YsbUNBQUM7Q0FBQSxBQW5SRCxJQW1SQztTQTlRWSw0QkFBNEI7Ozs7OztJQUVyQyxpREFBMEI7Ozs7O0lBQzFCLCtDQUF3Qjs7Ozs7SUFFeEIsaUVBQXNEOztJQUV0RCxtREFBK0I7O0lBQy9CLHVEQUFvQjs7SUFDcEIsMENBQVE7O0lBRVIseURBVUU7O0lBRUYsNERBV0U7Ozs7O0lBYVUsa0VBQThEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFNwQXR0YWNobWVudExpYnJhcnlTZXJ2aWNlIH0gZnJvbSAnLi9zcC1hdHRhY2htZW50LWxpYnJhcnkuc2VydmljZSc7XHJcbmltcG9ydCB7IEF0dGFjaG1lbnQgfSBmcm9tICcuLi9tb2RlbHMvYXR0YWNobWVudCc7XHJcbmltcG9ydCB7IGZpbGVUb0Jsb2IgfSBmcm9tICcuLi9zaGFyZWQvZmlsZS11dGlsJztcclxuXHJcbi8vIFRoaXJkIFBhcnR5XHJcbmltcG9ydCB7IEF0dGFjaG1lbnRGaWxlSW5mbywgRmllbGQgfSBmcm9tICdAcG5wL3NwJztcclxuaW1wb3J0ICogYXMgZmEgZnJvbSAnQGZvcnRhd2Vzb21lL2ZyZWUtc29saWQtc3ZnLWljb25zJztcclxuaW1wb3J0IFN3YWwgZnJvbSAnc3dlZXRhbGVydDInO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NwLWF0dGFjaG1lbnQnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL3NwLWF0dGFjaG1lbnQtbGlicmFyeS5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9zcC1hdHRhY2htZW50LWxpYnJhcnkuY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgU3BBdHRhY2htZW50TGlicmFyeUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gICAgcHJpdmF0ZSBfbGlzdE5hbWU6IHN0cmluZztcclxuICAgIHByaXZhdGUgX2l0ZW1JZDogbnVtYmVyO1xyXG5cclxuICAgIHByaXZhdGUgX3NlbGVjdGVkVXBsb2FkQXR0YWNobWVudDogQXR0YWNobWVudEZpbGVJbmZvO1xyXG5cclxuICAgIGF0dGFjaG1lbnRzOiBBdHRhY2htZW50W10gPSBbXTtcclxuICAgIHVuVXBMb2FkZWRJdGVtcyA9IDA7XHJcbiAgICBmYSA9IGZhO1xyXG5cclxuICAgIGRlbGV0ZVN3YWxPcHRpb25zID0ge1xyXG4gICAgICAgIHRpdGxlOiAnRG8geW91IHJlYWxseSB3YW50IHRvIGRlbGV0ZSB0aGlzIGF0dGFjaG1lbnQ/JyxcclxuICAgICAgICB0eXBlOiAnd2FybmluZycsXHJcbiAgICAgICAgY29uZmlybUJ1dHRvblRleHQ6ICdZZXMsIGRlbGV0ZSBpdCEnLFxyXG4gICAgICAgIGNhbmNlbEJ1dHRvblRleHQ6ICdObywga2VlcCBpdCcsXHJcbiAgICAgICAgc2hvd0NhbmNlbEJ1dHRvbjogJ3RydWUnLFxyXG4gICAgICAgIGN1c3RvbUNsYXNzOiB7XHJcbiAgICAgICAgICAgIGNvbmZpcm1CdXR0b246ICdidG4gYnRuLXN1Y2Nlc3MnLFxyXG4gICAgICAgICAgICBjYW5jZWxCdXR0b246ICdidG4gYnRuLWRhbmdlciBtbC1zbS0yJ1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgZGVsZXRlQWxsU3dhbE9wdGlvbnMgPSB7XHJcbiAgICAgICAgdGl0bGU6ICdEbyB5b3UgcmVhbGx5IHdhbnQgdG8gZGVsZXRlIGFsbCBzZWxlY3RlZCBhdHRhY2htZW50cz8nLFxyXG4gICAgICAgIG1lc3NhZ2U6ICdBbGwgc2VsZWN0ZWQgYXR0YWNobWVudHMgYWRkZWQgdG8gdGhpcyBsaXN0IGl0ZW0gd2lsbCBiZSBkZWxldGVkLicsXHJcbiAgICAgICAgdHlwZTogJ3dhcm5pbmcnLFxyXG4gICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiAnWWVzLCBkZWxldGUgaXQhJyxcclxuICAgICAgICBjYW5jZWxCdXR0b25UZXh0OiAnTm8sIGtlZXAgaXQnLFxyXG4gICAgICAgIHNob3dDYW5jZWxCdXR0b246ICd0cnVlJyxcclxuICAgICAgICBjdXN0b21DbGFzczoge1xyXG4gICAgICAgICAgICBjb25maXJtQnV0dG9uOiAnYnRuIGJ0bi1kYW5nZXInLFxyXG4gICAgICAgICAgICBjYW5jZWxCdXR0b246ICdidG4gYnRuLXN1Y2Nlc3MgbWwtc20tMidcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2V0IGxpc3ROYW1lKGxpc3ROYW1lOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9saXN0TmFtZSA9IGxpc3ROYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2V0IGl0ZW1JZChpdGVtSWQ6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuX2l0ZW1JZCA9IGl0ZW1JZDtcclxuICAgIH1cclxuXHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzcEF0dGFjaG1lbnRMaWJyYXJ5U2VydmljZTogU3BBdHRhY2htZW50TGlicmFyeVNlcnZpY2UpIHsgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9saXN0TmFtZSAmJiB0aGlzLl9pdGVtSWQpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2FkRXhpc3RpbmdGaWxlcygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBsb2FkRXhpc3RpbmdGaWxlcygpIHtcclxuICAgICAgICBjb25zdCB1bnVwbG9hZGVkID0gdGhpcy5hdHRhY2htZW50cy5maWx0ZXIoeCA9PiAheC5pc1NlbGVjdGVkICYmIHguc2VydmVyUmVsYXRpdmVVcmwgPT09IG51bGwpO1xyXG4gICAgICAgIHRoaXMuc3BBdHRhY2htZW50TGlicmFyeVNlcnZpY2UuZ2V0QXR0YWNobWVudHNCeUlkKHRoaXMuX2xpc3ROYW1lLCB0aGlzLl9pdGVtSWQpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50cyA9IFtdO1xyXG4gICAgICAgICAgICBkYXRhLnJlc3VsdC5mb3JFYWNoKGVsZW1lbnQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50cy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZTogZWxlbWVudC5GaWxlTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbjogZWxlbWVudC5GaWxlTmFtZS5zdWJzdHJpbmcoZWxlbWVudC5GaWxlTmFtZS5sYXN0SW5kZXhPZignLicpICsgMSksXHJcbiAgICAgICAgICAgICAgICAgICAgc2VydmVyUmVsYXRpdmVVcmw6IGVsZW1lbnQuU2VydmVyUmVsYXRpdmVVcmwsXHJcbiAgICAgICAgICAgICAgICAgICAgaXNVcGxvYWRlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgaXNDb250ZW50Q2hhbmdlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICBpc1NlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50cy5wdXNoKC4uLnVudXBsb2FkZWQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQXR0YWNobWVudEFkZGVkKGV2ZW50OiBhbnkpIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZXZlbnQudGFyZ2V0LmZpbGVzKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmF0dGFjaG1lbnRzLmZpbmRJbmRleCh4ID0+IHguZmlsZU5hbWUgPT09IGZpbGUubmFtZSkgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdldEJhc2U2NChmaWxlKVxyXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmF0dGFjaG1lbnRzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWU6IGZpbGUubmFtZSBhcyBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiByZXNwb25zZSBhcyBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb246IGZpbGUubmFtZS5zdWJzdHJpbmcoZmlsZS5uYW1lLmxhc3RJbmRleE9mKCcuJykgKyAxKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlclJlbGF0aXZlVXJsOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNVcGxvYWRlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0NvbnRlbnRDaGFuZ2VkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1NlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnByb21wdFJlcGxhY2UoZmlsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJvbXB0UmVwbGFjZShmaWxlOiBhbnkpIHtcclxuICAgICAgICBjb25zdCByZXBsYWNlQ29udGVudFN3YWwgPSBTd2FsLm1peGluKHtcclxuICAgICAgICAgICAgY3VzdG9tQ2xhc3M6IHtcclxuICAgICAgICAgICAgICAgIGNvbmZpcm1CdXR0b246ICdidG4gYnRuLXN1Y2Nlc3MnLFxyXG4gICAgICAgICAgICAgICAgY2FuY2VsQnV0dG9uOiAnYnRuIGJ0bi1kYW5nZXIgbWwtc20tMidcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgYnV0dG9uc1N0eWxpbmc6IGZhbHNlLFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXBsYWNlQ29udGVudFN3YWwuZmlyZSh7XHJcbiAgICAgICAgICAgIHRpdGxlOiAnRmlsZSBhbHJlYWR5IGV4aXN0cy4gRG8geW91IHdhbnQgdG8gcmVwbGFjZSBpdD8nLFxyXG4gICAgICAgICAgICB0ZXh0OiAnVGhlIGZpbGUgY29udGVudCB3aWxsIGJlIHJlcGxhY2VkJyxcclxuICAgICAgICAgICAgdHlwZTogJ3dhcm5pbmcnLFxyXG4gICAgICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxyXG4gICAgICAgICAgICBjb25maXJtQnV0dG9uVGV4dDogJ1llcywgcmVwbGFjZSBpdCEnLFxyXG4gICAgICAgICAgICBjYW5jZWxCdXR0b25UZXh0OiAnTm8sIGtlZXAgaXQnXHJcbiAgICAgICAgfSkudGhlbigocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQudmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0QmFzZTY0KGZpbGUpXHJcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXRpbmdGaWxlSW5kZXggPSB0aGlzLmF0dGFjaG1lbnRzLmZpbmRJbmRleCh4ID0+IHguZmlsZU5hbWUgPT09IGZpbGUubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSXRlbSA9IHRoaXMuYXR0YWNobWVudHMuZmluZCh4ID0+IHguZmlsZU5hbWUgPT09IGZpbGUubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nSXRlbS5jb250ZW50ID0gcmVzcG9uc2UgYXMgc3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0l0ZW0uZXh0ZW5zaW9uID0gZmlsZS5uYW1lLnN1YnN0cmluZyhmaWxlLm5hbWUubGFzdEluZGV4T2YoJy4nKSArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0l0ZW0uaXNDb250ZW50Q2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nSXRlbS5pc1VwbG9hZGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXR0YWNobWVudHMuc3BsaWNlKGV4aXRpbmdGaWxlSW5kZXgsIDEsIGV4aXN0aW5nSXRlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmRpc21pc3MgPT09IFN3YWwuRGlzbWlzc1JlYXNvbi5jYW5jZWwpIHtcclxuICAgICAgICAgICAgICAgIFN3YWwuZmlyZShcclxuICAgICAgICAgICAgICAgICAgICAnQ2FuY2VsbGVkJyxcclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJlc2V0RmlsZXMoZXZlbnQ6IGFueSkge1xyXG4gICAgICAgIGV2ZW50LnRhcmdldC52YWx1ZSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlQXR0YWNobWVudChmaWxlOiBBdHRhY2htZW50KSB7XHJcbiAgICAgICAgZmlsZS5pc0xvYWRpbmcgPSB0cnVlO1xyXG4gICAgICAgIGlmICghZmlsZS5zZXJ2ZXJSZWxhdGl2ZVVybCkge1xyXG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuYXR0YWNobWVudHMuZmluZEluZGV4KHggPT4geC5maWxlTmFtZSA9PT0gZmlsZS5maWxlTmFtZSk7XHJcbiAgICAgICAgICAgIGZpbGUuaXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuYXR0YWNobWVudHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBmaWxlLmlzTG9hZGluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuc3BBdHRhY2htZW50TGlicmFyeVNlcnZpY2UuZGVsZXRlQXR0YWNobWVudCh0aGlzLl9saXN0TmFtZSwgdGhpcy5faXRlbUlkLCBmaWxlLmZpbGVOYW1lKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuYXR0YWNobWVudHMuZmluZEluZGV4KHggPT4geC5maWxlTmFtZSA9PT0gZmlsZS5maWxlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICBmaWxlLmlzTG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50cy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHVwbG9hZEF0dGFjaG1lbnQoZmlsZTogQXR0YWNobWVudCkge1xyXG4gICAgICAgIGZpbGUuaXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9zZWxlY3RlZFVwbG9hZEF0dGFjaG1lbnQgPSB7XHJcbiAgICAgICAgICAgIGNvbnRlbnQgOiBmaWxlVG9CbG9iKGZpbGUpLFxyXG4gICAgICAgICAgICBuYW1lOiBmaWxlLmZpbGVOYW1lXHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnNwQXR0YWNobWVudExpYnJhcnlTZXJ2aWNlLmFkZEF0dGFjaG1lbnQodGhpcy5fbGlzdE5hbWUsIHRoaXMuX2l0ZW1JZCwgdGhpcy5fc2VsZWN0ZWRVcGxvYWRBdHRhY2htZW50KS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGZpbGUuaXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbGVJbmRleCA9IHRoaXMuYXR0YWNobWVudHMuZmluZEluZGV4KHggPT4geC5maWxlTmFtZSA9PT0gZmlsZS5maWxlTmFtZSk7XHJcbiAgICAgICAgICAgIHRoaXMuYXR0YWNobWVudHNbZmlsZUluZGV4XS5zZXJ2ZXJSZWxhdGl2ZVVybCA9IGRhdGEucmVzdWx0LmRhdGEuU2VydmVyUmVsYXRpdmVVcmw7XHJcbiAgICAgICAgICAgIHRoaXMuYXR0YWNobWVudHNbZmlsZUluZGV4XS5pc0NvbnRlbnRDaGFuZ2VkID0gZmFsc2U7XHJcbiAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBoYXNOZXdVblVwbG9hZGVkQW5kU2VsY3RlZCgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5hdHRhY2htZW50cy5maWx0ZXIoeCA9PiB4LnNlcnZlclJlbGF0aXZlVXJsID09PSBudWxsICYmIHguaXNTZWxlY3RlZCkubGVuZ3RoID4gMDtcclxuICAgIH1cclxuXHJcbiAgICBnZXRVblVwbG9hZG