UNPKG

ngx-masonry-gallery

Version:
246 lines 33 kB
import { Component, EventEmitter, Input, Output, Renderer2, ChangeDetectionStrategy, } from "@angular/core"; import * as imagesLoaded from "imagesloaded"; import * as Masonry from "masonry-layout"; import { utilities } from "./utilities"; import * as i0 from "@angular/core"; export class MasonryGalleryComponent { constructor(renderer) { this.renderer = renderer; this.images = []; this.width = 330; this.gutter = 5; this.verticalGutter = 5; this.imageClasses = []; this.clickImage = new EventEmitter(); this.removeComplete = new EventEmitter(); this.layoutComplete = new EventEmitter(); this.galleryGuid = utilities.newGuid(); this.mansonryItemSelectorClass = `grid-item-${this.galleryGuid}`; this.activeImages = []; this.viewReady = false; } ngOnChanges(changes) { if (changes.images && changes.images.currentValue) { if (!this.viewReady) { // process images once we can this.changesToProcess = changes; } else { this.processImages(changes); } } } ngOnDestroy() { this.msnry?.destroy?.(); } handleClick(image) { this.clickImage.next(image); } ngAfterViewInit() { this.viewReady = true; this.initMasonry(); // process images now if (this.changesToProcess) { this.processImages(this.changesToProcess); this.changesToProcess = undefined; } } addImages(images) { if (images && images.length > 0) { this.addImagesToGallery(images); } } removeImages(images) { if (images && images.length > 0) { images.forEach((image) => { this.removeImageFromGallery(image); }); } } processImages(changes) { const imagesToProcess = this.getAddedAndRemovesImages(changes); // add images to mansonry layout this.addImages(imagesToProcess.addedImages); // removes images from layout this.removeImages(imagesToProcess.removedImages); } getAddedAndRemovesImages(changes) { let addedImages = []; const removedImages = []; const newImagesValue = changes.images .currentValue; const oldImagesValue = changes.images .previousValue; if (!oldImagesValue) { // all images are new ones addedImages = changes.images.currentValue; } else { // process added images newImagesValue.forEach((newImage) => { const existingImage = oldImagesValue.find((m) => m.imageUrl.toLowerCase() === newImage.imageUrl.toLowerCase()); if (existingImage) { // image was in previous value && is in new, do nothing } else { // image is new addedImages.push(newImage); } }); // process removed images oldImagesValue.forEach((oldImage) => { const existingImage = newImagesValue.find((m) => m.imageUrl.toLowerCase() === oldImage.imageUrl.toLowerCase()); if (existingImage) { // image was in previous value && is in new, do nothing } else { // image is removed removedImages.push(oldImage); } }); } return { addedImages: addedImages, removedImages: removedImages, }; } initMasonry() { const grid = document.getElementById(this.galleryGuid); if (!grid) { console.warn(`Invalid grid element with id '${this.galleryGuid}'`); return; } // remove all existing data from grid grid.innerHTML = ""; const msnry = new Masonry(grid, { // options... itemSelector: "." + this.mansonryItemSelectorClass, columnWidth: this.width, gutter: this.gutter, }); const that = this; msnry.on?.("layoutComplete", (items) => { that.layoutComplete.next(items); }); msnry.on?.("removeComplete", (items) => { that.removeComplete.next(items); }); this.grid = grid; this.msnry = msnry; } removeImageFromGallery(image) { // get image guid const imageIdResult = this.activeImages.find((m) => m.image.imageUrl.toLowerCase() === image.imageUrl.toLowerCase()); if (!imageIdResult) { // image was not found, this is probably an error console.warn(`Image with url '${image.imageUrl}' was not found. If you are adding images, make sure to 'replace' the images array with a new one so that detection change can be executed instead of just adding an image to array (which doesn't fire change detection on array property)`); return; } // find image based on its id const imageElem = document.getElementById(imageIdResult.id); if (!imageElem) { // image was not found in DOM console.warn(`Image with id '{${imageIdResult.id}}' was not found in DOM. Have you manipulated the DOM in some way?`); return; } // remove image from gallery this.msnry?.remove?.([imageElem]); // refresh layout this.msnry?.layout?.(); // remove image from array for (let i = 0; i < this.activeImages.length; i++) { const idWithImage = this.activeImages[i]; if (idWithImage.image.imageUrl.toLowerCase() === imageIdResult.image.imageUrl.toLowerCase()) { this.activeImages.splice(i, 1); } } } addImagesToGallery(images) { if (!this.grid) { throw Error("Grid element is not yet ready, are you trying to add image too soon?"); } const imagesWrapper = this.renderer.createElement("span"); images.forEach((image) => { // generate unique image id const imageId = this.getImageId(); // create element const imageElem = this.renderer.createElement("img"); imageElem.setAttribute("id", imageId); imageElem.setAttribute("alt", image.alt ? image.alt : "no description"); imageElem.setAttribute("src", image.imageUrl); // note - images are hidden by default and should be shown only after they are loaded imageElem.setAttribute("style", `display: block; width: ${this.width}px; margin-bottom: ${this.verticalGutter}px`); imageElem.className = this.getImageClass(); imageElem.addEventListener("click", () => { this.handleClick(image); }); // store guid with this image this.activeImages.push({ id: imageId, image: image, }); // add to dom and mansory & refresh layout this.renderer.appendChild(imagesWrapper, imageElem); }); // add html to dom this.renderer.appendChild(this.grid, imagesWrapper); // add images once they are loaded const imgLoad = imagesLoaded(imagesWrapper); imgLoad.on("progress", (instance, image) => { if (image && image.isLoaded && this.msnry && this.msnry.appended && this.msnry.reloadItems) { // this.renderer.appendChild(this.grid, image.img); // unhide image // this.renderer.setStyle(image.img, "display", "block"); // remove image from gallery this.msnry?.addItems?.([image.img]); // refresh layout this.msnry?.layout?.(); } }); } getImageClass() { let className = this.mansonryItemSelectorClass; if (this.imageClasses && this.imageClasses.length > 0) { const customClass = this.imageClasses.join(" "); className += " " + customClass; } return className; } getImageId() { return this.galleryGuid + "_" + utilities.newGuid(); } } /** @nocollapse */ MasonryGalleryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MasonryGalleryComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ MasonryGalleryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.0", type: MasonryGalleryComponent, selector: "ngx-masonry-gallery", inputs: { images: "images", width: "width", gutter: "gutter", verticalGutter: "verticalGutter", imageClasses: "imageClasses" }, outputs: { clickImage: "clickImage", removeComplete: "removeComplete", layoutComplete: "layoutComplete" }, usesOnChanges: true, ngImport: i0, template: '<div [id]="galleryGuid"></div>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MasonryGalleryComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: "ngx-masonry-gallery", template: '<div [id]="galleryGuid"></div>', }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { images: [{ type: Input }], width: [{ type: Input }], gutter: [{ type: Input }], verticalGutter: [{ type: Input }], imageClasses: [{ type: Input }], clickImage: [{ type: Output }], removeComplete: [{ type: Output }], layoutComplete: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzb25yeS1nYWxsZXJ5LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvbWFzb25yeS1nYWxsZXJ5LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFFVCx1QkFBdUIsR0FDeEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxLQUFLLFlBQVksTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxLQUFLLE9BQU8sTUFBTSxnQkFBZ0IsQ0FBQztBQUcxQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDOztBQU94QyxNQUFNLE9BQU8sdUJBQXVCO0lBdUJsQyxZQUFvQixRQUFtQjtRQUFuQixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBcEI5QixXQUFNLEdBQTJCLEVBQUUsQ0FBQztRQUNwQyxVQUFLLEdBQVcsR0FBRyxDQUFDO1FBQ3BCLFdBQU0sR0FBVyxDQUFDLENBQUM7UUFDbkIsbUJBQWMsR0FBVyxDQUFDLENBQUM7UUFDM0IsaUJBQVksR0FBYSxFQUFFLENBQUM7UUFFM0IsZUFBVSxHQUFHLElBQUksWUFBWSxFQUF3QixDQUFDO1FBQ3RELG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVMsQ0FBQztRQUMzQyxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUFTLENBQUM7UUFFckMsZ0JBQVcsR0FBVyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFekMsOEJBQXlCLEdBQUcsYUFBYSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDNUQsaUJBQVksR0FBa0IsRUFBRSxDQUFDO1FBSzFDLGNBQVMsR0FBWSxLQUFLLENBQUM7SUFFTyxDQUFDO0lBRTNDLFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxZ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R0FBRyxDQUFDLENBQUMsQ0FBQztnQkFFcEMsaUJBQWlCO2dCQUNqQixJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUM7YUFDeEI7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxhQUFhO1FBQ25CLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQztRQUUvQyxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3JELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWhELFNBQVMsSUFBSSxHQUFHLEdBQUcsV0FBVyxDQUFDO1NBQ2hDO1FBRUQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVPLFVBQVU7UUFDaEIsT0FBTyxJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsR0FBRyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDdEQsQ0FBQzs7dUlBN1JVLHVCQUF1QjsySEFBdkIsdUJBQXVCLDJUQUZ4QixnQ0FBZ0M7MkZBRS9CLHVCQUF1QjtrQkFMbkMsU0FBUzttQkFBQztvQkFDVCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsUUFBUSxFQUFFLHFCQUFxQjtvQkFDL0IsUUFBUSxFQUFFLGdDQUFnQztpQkFDM0M7Z0dBSVUsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUVJLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIENvbXBvbmVudCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uRGVzdHJveSxcclxuICBPdXRwdXQsXHJcbiAgUmVuZGVyZXIyLFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXHJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0ICogYXMgaW1hZ2VzTG9hZGVkIGZyb20gXCJpbWFnZXNsb2FkZWRcIjtcclxuaW1wb3J0ICogYXMgTWFzb25yeSBmcm9tIFwibWFzb25yeS1sYXlvdXRcIjtcclxuXHJcbmltcG9ydCB7IElNYXNvbnJ5R2FsbGVyeUltYWdlIH0gZnJvbSBcIi4vbWFzb25yeS1nYWxsZXJ5LW1vZGVsc1wiO1xyXG5pbXBvcnQgeyB1dGlsaXRpZXMgfSBmcm9tIFwiLi91dGlsaXRpZXNcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIHNlbGVjdG9yOiBcIm5neC1tYXNvbnJ5LWdhbGxlcnlcIixcclxuICB0ZW1wbGF0ZTogJzxkaXYgW2lkXT1cImdhbGxlcnlHdWlkXCI+PC9kaXY+JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIE1hc29ucnlHYWxsZXJ5Q29tcG9uZW50XHJcbiAgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlc1xyXG57XHJcbiAgQElucHV0KCkgaW1hZ2VzOiBJTWFzb25yeUdhbGxlcnlJbWFnZVtdID0gW107XHJcbiAgQElucHV0KCkgd2lkdGg6IG51bWJlciA9IDMzMDtcclxuICBASW5wdXQoKSBndXR0ZXI6IG51bWJlciA9IDU7XHJcbiAgQElucHV0KCkgdmVydGljYWxHdXR0ZXI6IG51bWJlciA9IDU7XHJcbiAgQElucHV0KCkgaW1hZ2VDbGFzc2VzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICBAT3V0cHV0KCkgY2xpY2tJbWFnZSA9IG5ldyBFdmVudEVtaXR0ZXI8SU1hc29ucnlHYWxsZXJ5SW1hZ2U+KCk7XHJcbiAgQE91dHB1dCgpIHJlbW92ZUNvbXBsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnlbXT4oKTtcclxuICBAT3V0cHV0KCkgbGF5b3V0Q29tcGxldGUgPSBuZXcgRXZlbnRFbWl0dGVyPGFueVtdPigpO1xyXG5cclxuICBwdWJsaWMgcmVhZG9ubHkgZ2FsbGVyeUd1aWQ6IHN0cmluZyA9IHV0aWxpdGllcy5uZXdHdWlkKCk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgbWFuc29ucnlJdGVtU2VsZWN0b3JDbGFzcyA9IGBncmlkLWl0ZW0tJHt0aGlzLmdhbGxlcnlHdWlkfWA7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBhY3RpdmVJbWFnZXM6IEFjdGl2ZUltYWdlW10gPSBbXTtcclxuXHJcbiAgcHJpdmF0ZSBtc25yeT86IE1hc29ucnk7XHJcbiAgcHJpdmF0ZSBncmlkPzogSFRNTEVsZW1lbnQgfCBudWxsO1xyXG4gIHByaXZhdGUgY2hhbmdlc1RvUHJvY2Vzcz86IFNpbXBsZUNoYW5nZXM7XHJcbiAgcHJpdmF0ZSB2aWV3UmVhZHk6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyKSB7fVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICBpZiAoY2hhbmdlcy5pbWFnZXMgJiYgY2hhbmdlcy5pbWFnZXMuY3VycmVudFZhbHVlKSB7XHJcbiAgICAgIGlmICghdGhpcy52aWV3UmVhZHkpIHtcclxuICAgICAgICAvLyBwcm9jZXNzIGltYWdlcyBvbmNlIHdlIGNhblxyXG4gICAgICAgIHRoaXMuY2hhbmdlc1RvUHJvY2VzcyA9IGNoYW5nZXM7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5wcm9jZXNzSW1hZ2VzKGNoYW5nZXMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMubXNucnk/LmRlc3Ryb3k/LigpO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlQ2xpY2soaW1hZ2U6IElNYXNvbnJ5R2FsbGVyeUltYWdlKTogdm9pZCB7XHJcbiAgICB0aGlzLmNsaWNrSW1hZ2UubmV4dChpbWFnZSk7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLnZpZXdSZWFkeSA9IHRydWU7XHJcbiAgICB0aGlzLmluaXRNYXNvbnJ5KCk7XHJcblxyXG4gICAgLy8gcHJvY2VzcyBpbWFnZXMgbm93XHJcbiAgICBpZiAodGhpcy5jaGFuZ2VzVG9Qcm9jZXNzKSB7XHJcbiAgICAgIHRoaXMucHJvY2Vzc0ltYWdlcyh0aGlzLmNoYW5nZXNUb1Byb2Nlc3MpO1xyXG4gICAgICB0aGlzLmNoYW5nZXNUb1Byb2Nlc3MgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhZGRJbWFnZXMoaW1hZ2VzOiBJTWFzb25yeUdhbGxlcnlJbWFnZVtdKTogdm9pZCB7XHJcbiAgICBpZiAoaW1hZ2VzICYmIGltYWdlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMuYWRkSW1hZ2VzVG9HYWxsZXJ5KGltYWdlcyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZW1vdmVJbWFnZXMoaW1hZ2VzOiBJTWFzb25yeUdhbGxlcnlJbWFnZVtdKTogdm9pZCB7XHJcbiAgICBpZiAoaW1hZ2VzICYmIGltYWdlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGltYWdlcy5mb3JFYWNoKChpbWFnZSkgPT4ge1xyXG4gICAgICAgIHRoaXMucmVtb3ZlSW1hZ2VGcm9tR2FsbGVyeShpbWFnZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwcm9jZXNzSW1hZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgIGNvbnN0IGltYWdlc1RvUHJvY2VzcyA9IHRoaXMuZ2V0QWRkZWRBbmRSZW1vdmVzSW1hZ2VzKGNoYW5nZXMpO1xyXG5cclxuICAgIC8vIGFkZCBpbWFnZXMgdG8gbWFuc29ucnkgbGF5b3V0XHJcbiAgICB0aGlzLmFkZEltYWdlcyhpbWFnZXNUb1Byb2Nlc3MuYWRkZWRJbWFnZXMpO1xyXG5cclxuICAgIC8vIHJlbW92ZXMgaW1hZ2VzIGZyb20gbGF5b3V0XHJcbiAgICB0aGlzLnJlbW92ZUltYWdlcyhpbWFnZXNUb1Byb2Nlc3MucmVtb3ZlZEltYWdlcyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldEFkZGVkQW5kUmVtb3Zlc0ltYWdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKToge1xyXG4gICAgYWRkZWRJbWFnZXM6IElNYXNvbnJ5R2FsbGVyeUltYWdlW107XHJcbiAgICByZW1vdmVkSW1hZ2VzOiBJTWFzb25yeUdhbGxlcnlJbWFnZVtdO1xyXG4gIH0ge1xyXG4gICAgbGV0IGFkZGVkSW1hZ2VzOiBJTWFzb25yeUdhbGxlcnlJbWFnZVtdID0gW107XHJcbiAgICBjb25zdCByZW1vdmVkSW1hZ2VzOiBJTWFzb25yeUdhbGxlcnlJbWFnZVtdID0gW107XHJcblxyXG4gICAgY29uc3QgbmV3SW1hZ2VzVmFsdWUgPSBjaGFuZ2VzLmltYWdlc1xyXG4gICAgICAuY3VycmVudFZhbHVlIGFzIElNYXNvbnJ5R2FsbGVyeUltYWdlW107XHJcbiAgICBjb25zdCBvbGRJbWFnZXNWYWx1ZSA9IGNoYW5nZXMuaW1hZ2VzXHJcbiAgICAgIC5wcmV2aW91c1ZhbHVlIGFzIElNYXNvbnJ5R2FsbGVyeUltYWdlW107XHJcblxyXG4gICAgaWYgKCFvbGRJbWFnZXNWYWx1ZSkge1xyXG4gICAgICAvLyBhbGwgaW1hZ2VzIGFyZSBuZXcgb25lc1xyXG4gICAgICBhZGRlZEltYWdlcyA9IGNoYW5nZXMuaW1hZ2VzLmN1cnJlbnRWYWx1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIHByb2Nlc3MgYWRkZWQgaW1hZ2VzXHJcbiAgICAgIG5ld0ltYWdlc1ZhbHVlLmZvckVhY2goKG5ld0ltYWdlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmdJbWFnZSA9IG9sZEltYWdlc1ZhbHVlLmZpbmQoXHJcbiAgICAgICAgICAobSkgPT4gbS5pbWFnZVVybC50b0xvd2VyQ2FzZSgpID09PSBuZXdJbWFnZS5pbWFnZVVybC50b0xvd2VyQ2FzZSgpXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgaWYgKGV4aXN0aW5nSW1hZ2UpIHtcclxuICAgICAgICAgIC8vIGltYWdlIHdhcyBpbiBwcmV2aW91cyB2YWx1ZSAmJiBpcyBpbiBuZXcsIGRvIG5vdGhpbmdcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gaW1hZ2UgaXMgbmV3XHJcbiAgICAgICAgICBhZGRlZEltYWdlcy5wdXNoKG5ld0ltYWdlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gcHJvY2VzcyByZW1vdmVkIGltYWdlc1xyXG4gICAgICBvbGRJbWFnZXNWYWx1ZS5mb3JFYWNoKChvbGRJbWFnZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGV4aXN0aW5nSW1hZ2UgPSBuZXdJbWFnZXNWYWx1ZS5maW5kKFxyXG4gICAgICAgICAgKG0pID0+IG0uaW1hZ2VVcmwudG9Mb3dlckNhc2UoKSA9PT0gb2xkSW1hZ2UuaW1hZ2VVcmwudG9Mb3dlckNhc2UoKVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGlmIChleGlzdGluZ0ltYWdlKSB7XHJcbiAgICAgICAgICAvLyBpbWFnZSB3YXMgaW4gcHJldmlvdXMgdmFsdWUgJiYgaXMgaW4gbmV3LCBkbyBub3RoaW5nXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIGltYWdlIGlzIHJlbW92ZWRcclxuICAgICAgICAgIHJlbW92ZWRJbWFnZXMucHVzaChvbGRJbWFnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBhZGRlZEltYWdlczogYWRkZWRJbWFnZXMsXHJcbiAgICAgIHJlbW92ZWRJbWFnZXM6IHJlbW92ZWRJbWFnZXMsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0TWFzb25yeSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGdyaWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmdhbGxlcnlHdWlkKTtcclxuXHJcbiAgICBpZiAoIWdyaWQpIHtcclxuICAgICAgY29uc29sZS53YXJuKGBJbnZhbGlkIGdyaWQgZWxlbWVudCB3aXRoIGlkICcke3RoaXMuZ2FsbGVyeUd1aWR9J2ApO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmVtb3ZlIGFsbCBleGlzdGluZyBkYXRhIGZyb20gZ3JpZFxyXG4gICAgZ3JpZC5pbm5lckhUTUwgPSBcIlwiO1xyXG5cclxuICAgIGNvbnN0IG1zbnJ5ID0gbmV3IE1hc29ucnkoZ3JpZCwge1xyXG4gICAgICAvLyBvcHRpb25zLi4uXHJcbiAgICAgIGl0ZW1TZWxlY3RvcjogXCIuXCIgKyB0aGlzLm1hbnNvbnJ5SXRlbVNlbGVjdG9yQ2xhc3MsXHJcbiAgICAgIGNvbHVtbldpZHRoOiB0aGlzLndpZHRoLFxyXG4gICAgICBndXR0ZXI6IHRoaXMuZ3V0dGVyLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XHJcblxyXG4gICAgbXNucnkub24/LihcImxheW91dENvbXBsZXRlXCIsIChpdGVtczogYW55KSA9PiB7XHJcbiAgICAgIHRoYXQubGF5b3V0Q29tcGxldGUubmV4dChpdGVtcyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBtc25yeS5vbj8uKFwicmVtb3ZlQ29tcGxldGVcIiwgKGl0ZW1zOiBhbnkpID0+IHtcclxuICAgICAgdGhhdC5yZW1vdmVDb21wbGV0ZS5uZXh0KGl0ZW1zKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZ3JpZCA9IGdyaWQ7XHJcbiAgICB0aGlzLm1zbnJ5ID0gbXNucnk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlbW92ZUltYWdlRnJvbUdhbGxlcnkoaW1hZ2U6IElNYXNvbnJ5R2FsbGVyeUltYWdlKTogdm9pZCB7XHJcbiAgICAvLyBnZXQgaW1hZ2UgZ3VpZFxyXG4gICAgY29uc3QgaW1hZ2VJZFJlc3VsdCA9IHRoaXMuYWN0aXZlSW1hZ2VzLmZpbmQoXHJcbiAgICAgIChtKSA9PiBtLmltYWdlLmltYWdlVXJsLnRvTG93ZXJDYXNlKCkgPT09IGltYWdlLmltYWdlVXJsLnRvTG93ZXJDYXNlKClcclxuICAgICk7XHJcblxyXG4gICAgaWYgKCFpbWFnZUlkUmVzdWx0KSB7XHJcbiAgICAgIC8vIGltYWdlIHdhcyBub3QgZm91bmQsIHRoaXMgaXMgcHJvYmFibHkgYW4gZXJyb3JcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgIGBJbWFnZSB3aXRoIHVybCAnJHtpbWFnZS5pbWFnZVVybH0nIHdhcyBub3QgZm91bmQuIElmIHlvdSBhcmUgYWRkaW5nIGltYWdlcywgbWFrZSBzdXJlIHRvICdyZXBsYWNlJyB0aGUgaW1hZ2VzIGFycmF5IHdpdGggYSBuZXcgb25lXHJcbiAgICAgICAgICAgICAgICBzbyB0aGF0IGRldGVjdGlvbiBjaGFuZ2UgY2FuIGJlIGV4ZWN1dGVkIGluc3RlYWQgb2YganVzdCBhZGRpbmcgYW4gaW1hZ2UgdG8gYXJyYXlcclxuICAgICAgICAgICAgICAgICh3aGljaCBkb2Vzbid0IGZpcmUgY2hhbmdlIGRldGVjdGlvbiBvbiBhcnJheSBwcm9wZXJ0eSlgXHJcbiAgICAgICk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBmaW5kIGltYWdlIGJhc2VkIG9uIGl0cyBpZFxyXG4gICAgY29uc3QgaW1hZ2VFbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaW1hZ2VJZFJlc3VsdC5pZCk7XHJcblxyXG4gICAgaWYgKCFpbWFnZUVsZW0pIHtcclxuICAgICAgLy8gaW1hZ2Ugd2FzIG5vdCBmb3VuZCBpbiBET01cclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgIGBJbWFnZSB3aXRoIGlkICd7JHtpbWFnZUlkUmVzdWx0LmlkfX0nIHdhcyBub3QgZm91bmQgaW4gRE9NLiBIYXZlIHlvdSBtYW5pcHVsYXRlZCB0aGUgRE9NIGluIHNvbWUgd2F5P2BcclxuICAgICAgKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJlbW92ZSBpbWFnZSBmcm9tIGdhbGxlcnlcclxuICAgIHRoaXMubXNucnk/LnJlbW92ZT8uKFtpbWFnZUVsZW1dKTtcclxuXHJcbiAgICAvLyByZWZyZXNoIGxheW91dFxyXG4gICAgdGhpcy5tc25yeT8ubGF5b3V0Py4oKTtcclxuXHJcbiAgICAvLyByZW1vdmUgaW1hZ2UgZnJvbSBhcnJheVxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmFjdGl2ZUltYWdlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBpZFdpdGhJbWFnZSA9IHRoaXMuYWN0aXZlSW1hZ2VzW2ldO1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgaWRXaXRoSW1hZ2UuaW1hZ2UuaW1hZ2VVcmwudG9Mb3dlckNhc2UoKSA9PT1cclxuICAgICAgICBpbWFnZUlkUmVzdWx0LmltYWdlLmltYWdlVXJsLnRvTG93ZXJDYXNlKClcclxuICAgICAgKSB7XHJcbiAgICAgICAgdGhpcy5hY3RpdmVJbWFnZXMuc3BsaWNlKGksIDEpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFkZEltYWdlc1RvR2FsbGVyeShpbWFnZXM6IElNYXNvbnJ5R2FsbGVyeUltYWdlW10pOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5ncmlkKSB7XHJcbiAgICAgIHRocm93IEVycm9yKFxyXG4gICAgICAgIFwiR3JpZCBlbGVtZW50IGlzIG5vdCB5ZXQgcmVhZHksIGFyZSB5b3UgdHJ5aW5nIHRvIGFkZCBpbWFnZSB0b28gc29vbj9cIlxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGltYWdlc1dyYXBwZXIgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xyXG5cclxuICAgIGltYWdlcy5mb3JFYWNoKChpbWFnZSkgPT4ge1xyXG4gICAgICAvLyBnZW5lcmF0ZSB1bmlxdWUgaW1hZ2UgaWRcclxuICAgICAgY29uc3QgaW1hZ2VJZCA9IHRoaXMuZ2V0SW1hZ2VJZCgpO1xyXG5cclxuICAgICAgLy8gY3JlYXRlIGVsZW1lbnRcclxuICAgICAgY29uc3QgaW1hZ2VFbGVtID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KFwiaW1nXCIpO1xyXG4gICAgICBpbWFnZUVsZW0uc2V0QXR0cmlidXRlKFwiaWRcIiwgaW1hZ2VJZCk7XHJcbiAgICAgIGltYWdlRWxlbS5zZXRBdHRyaWJ1dGUoXCJhbHRcIiwgaW1hZ2UuYWx0ID8gaW1hZ2UuYWx0IDogXCJubyBkZXNjcmlwdGlvblwiKTtcclxuICAgICAgaW1hZ2VFbGVtLnNldEF0dHJpYnV0ZShcInNyY1wiLCBpbWFnZS5pbWFnZVVybCk7XHJcbiAgICAgIC8vIG5vdGUgLSBpbWFnZXMgYXJlIGhpZGRlbiBieSBkZWZhdWx0IGFuZCBzaG91bGQgYmUgc2hvd24gb25seSBhZnRlciB0aGV5IGFyZSBsb2FkZWRcclxuICAgICAgaW1hZ2VFbGVtLnNldEF0dHJpYnV0ZShcclxuICAgICAgICBcInN0eWxlXCIsXHJcbiAgICAgICAgYGRpc3BsYXk6IGJsb2NrOyB3aWR0aDogJHt0aGlzLndpZHRofXB4OyBtYXJnaW4tYm90dG9tOiAke3RoaXMudmVydGljYWxHdXR0ZXJ9cHhgXHJcbiAgICAgICk7XHJcbiAgICAgIGltYWdlRWxlbS5jbGFzc05hbWUgPSB0aGlzLmdldEltYWdlQ2xhc3MoKTtcclxuICAgICAgaW1hZ2VFbGVtLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5oYW5kbGVDbGljayhpbWFnZSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gc3RvcmUgZ3VpZCB3aXRoIHRoaXMgaW1hZ2VcclxuICAgICAgdGhpcy5hY3RpdmVJbWFnZXMucHVzaCh7XHJcbiAgICAgICAgaWQ6IGltYWdlSWQsXHJcbiAgICAgICAgaW1hZ2U6IGltYWdlLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIGFkZCB0byBkb20gYW5kIG1hbnNvcnkgJiByZWZyZXNoIGxheW91dFxyXG4gICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKGltYWdlc1dyYXBwZXIsIGltYWdlRWxlbSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBhZGQgaHRtbCB0byBkb21cclxuICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5ncmlkLCBpbWFnZXNXcmFwcGVyKTtcclxuXHJcbiAgICAvLyBhZGQgaW1hZ2VzIG9uY2UgdGhleSBhcmUgbG9hZGVkXHJcbiAgICBjb25zdCBpbWdMb2FkID0gaW1hZ2VzTG9hZGVkKGltYWdlc1dyYXBwZXIpO1xyXG4gICAgaW1nTG9hZC5vbihcInByb2dyZXNzXCIsIChpbnN0YW5jZSwgaW1hZ2UpID0+IHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIGltYWdlICYmXHJcbiAgICAgICAgaW1hZ2UuaXNMb2FkZWQgJiZcclxuICAgICAgICB0aGlzLm1zbnJ5ICYmXHJcbiAgICAgICAgdGhpcy5tc25yeS5hcHBlbmRlZCAmJlxyXG4gICAgICAgIHRoaXMubXNucnkucmVsb2FkSXRlbXNcclxuICAgICAgKSB7XHJcbiAgICAgICAgLy8gdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmdyaWQsIGltYWdlLmltZyk7XHJcbiAgICAgICAgLy8gdW5oaWRlIGltYWdlXHJcbiAgICAgICAgLy8gdGhpcy5yZW5kZXJlci5zZXRTdHlsZShpbWFnZS5pbWcsIFwiZGlzcGxheVwiLCBcImJsb2NrXCIpO1xyXG5cclxuICAgICAgICAvLyByZW1vdmUgaW1hZ2UgZnJvbSBnYWxsZXJ5XHJcbiAgICAgICAgdGhpcy5tc25yeT8uYWRkSXRlbXM/LihbaW1hZ2UuaW1nXSk7XHJcblxyXG4gICAgICAgIC8vIHJlZnJlc2ggbGF5b3V0XHJcbiAgICAgICAgdGhpcy5tc25yeT8ubGF5b3V0Py4oKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldEltYWdlQ2xhc3MoKTogc3RyaW5nIHtcclxuICAgIGxldCBjbGFzc05hbWUgPSB0aGlzLm1hbnNvbnJ5SXRlbVNlbGVjdG9yQ2xhc3M7XHJcblxyXG4gICAgaWYgKHRoaXMuaW1hZ2VDbGFzc2VzICYmIHRoaXMuaW1hZ2VDbGFzc2VzLmxlbmd0aCA+IDApIHtcclxuICAgICAgY29uc3QgY3VzdG9tQ2xhc3MgPSB0aGlzLmltYWdlQ2xhc3Nlcy5qb2luKFwiIFwiKTtcclxuXHJcbiAgICAgIGNsYXNzTmFtZSArPSBcIiBcIiArIGN1c3RvbUNsYXNzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjbGFzc05hbWU7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldEltYWdlSWQoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmdhbGxlcnlHdWlkICsgXCJfXCIgKyB1dGlsaXRpZXMubmV3R3VpZCgpO1xyXG4gIH1cclxufVxyXG5cclxuaW50ZXJmYWNlIEFjdGl2ZUltYWdlIHtcclxuICBpZDogc3RyaW5nO1xyXG4gIGltYWdlOiBJTWFzb25yeUdhbGxlcnlJbWFnZTtcclxufVxyXG4iXX0=