UNPKG

@paddls/ngx-easy-table

Version:
210 lines 25 kB
import { Directive, EventEmitter, Input, Output } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "./pagination.service"; /** * This directive is what powers all pagination controls components, including the default one. * It exposes an API which is hooked up to the PaginationService to keep the PaginatePipe in sync * with the pagination controls. */ export class PaginationControlsDirective { constructor(service, changeDetectorRef) { this.service = service; this.changeDetectorRef = changeDetectorRef; this.maxSize = 7; this.pageChange = new EventEmitter(); this.pageBoundsCorrection = new EventEmitter(); this.pages = []; this.changeSub = this.service.change .subscribe(id => { if (this.id === id) { this.updatePageLinks(); this.changeDetectorRef.markForCheck(); this.changeDetectorRef.detectChanges(); } }); } ngOnInit() { if (this.id === undefined) { this.id = this.service.defaultId(); } this.updatePageLinks(); } ngOnChanges() { this.updatePageLinks(); } ngOnDestroy() { this.changeSub.unsubscribe(); } /** * Go to the previous page */ previous() { this.checkValidId(); this.setCurrent(this.getCurrent() - 1); } /** * Go to the next page */ next() { this.checkValidId(); this.setCurrent(this.getCurrent() + 1); } /** * Returns true if current page is first page */ isFirstPage() { return this.getCurrent() === 1; } /** * Returns true if current page is last page */ isLastPage() { return this.getLastPage() === this.getCurrent(); } /** * Set the current page number. */ setCurrent(page) { this.pageChange.emit(page); } /** * Get the current page number. */ getCurrent() { return this.service.getCurrentPage(this.id); } /** * Returns the last page number */ getLastPage() { let inst = this.service.getInstance(this.id); const totalItems = inst.totalItems ?? 0; if (totalItems < 1) { // when there are 0 or fewer (an error case) items, there are no "pages" as such, // but it makes sense to consider a single, empty page as the last page. return 1; } return Math.ceil(totalItems / inst.itemsPerPage); } getTotalItems() { return this.service.getInstance(this.id).totalItems ?? 0; } checkValidId() { if (this.service.getInstance(this.id).id == null) { console.warn(`PaginationControlsDirective: the specified id "${this.id}" does not match any registered PaginationInstance`); } } /** * Updates the page links and checks that the current page is valid. Should run whenever the * PaginationService.change stream emits a value matching the current ID, or when any of the * input values changes. */ updatePageLinks() { let inst = this.service.getInstance(this.id); const correctedCurrentPage = this.outOfBoundCorrection(inst); if (correctedCurrentPage !== inst.currentPage) { setTimeout(() => { this.pageBoundsCorrection.emit(correctedCurrentPage); this.pages = this.createPageArray(inst.currentPage, inst.itemsPerPage, (inst.totalItems ?? 0), this.maxSize); }); } else { this.pages = this.createPageArray(inst.currentPage, inst.itemsPerPage, (inst.totalItems ?? 0), this.maxSize); } } /** * Checks that the instance.currentPage property is within bounds for the current page range. * If not, return a correct value for currentPage, or the current value if OK. */ outOfBoundCorrection(instance) { const totalPages = Math.ceil((instance.totalItems ?? 0) / instance.itemsPerPage); if (totalPages < instance.currentPage && 0 < totalPages) { return totalPages; } else if (instance.currentPage < 1) { return 1; } return instance.currentPage; } /** * Returns an array of Page objects to use in the pagination controls. */ createPageArray(currentPage, itemsPerPage, totalItems, paginationRange) { // paginationRange could be a string if passed from attribute, so cast to number. paginationRange = +paginationRange; let pages = []; // Return 1 as default page number // Make sense to show 1 instead of empty when there are no items const totalPages = Math.max(Math.ceil(totalItems / itemsPerPage), 1); const halfWay = Math.ceil(paginationRange / 2); const isStart = currentPage <= halfWay; const isEnd = totalPages - halfWay < currentPage; const isMiddle = !isStart && !isEnd; let ellipsesNeeded = paginationRange < totalPages; let i = 1; while (i <= totalPages && i <= paginationRange) { let label; let pageNumber = this.calculatePageNumber(i, currentPage, paginationRange, totalPages); let openingEllipsesNeeded = (i === 2 && (isMiddle || isEnd)); let closingEllipsesNeeded = (i === paginationRange - 1 && (isMiddle || isStart)); if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) { label = '...'; } else { label = pageNumber; } // @ts-ignore don't know why it considers the object as never :shrug: pages.push({ label: label, value: pageNumber }); i++; } return pages; } /** * Given the position in the sequence of pagination links [i], * figure out what page number corresponds to that position. */ calculatePageNumber(i, currentPage, paginationRange, totalPages) { let halfWay = Math.ceil(paginationRange / 2); if (i === paginationRange) { return totalPages; } else if (i === 1) { return i; } else if (paginationRange < totalPages) { if (totalPages - halfWay < currentPage) { return totalPages - paginationRange + i; } else if (halfWay < currentPage) { return currentPage - halfWay + i; } else { return i; } } else { return i; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationControlsDirective, deps: [{ token: i1.PaginationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: PaginationControlsDirective, selector: "pagination-template,[pagination-template]", inputs: { id: "id", maxSize: "maxSize" }, outputs: { pageChange: "pageChange", pageBoundsCorrection: "pageBoundsCorrection" }, exportAs: ["paginationApi"], usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationControlsDirective, decorators: [{ type: Directive, args: [{ selector: 'pagination-template,[pagination-template]', exportAs: 'paginationApi' }] }], ctorParameters: function () { return [{ type: i1.PaginationService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { id: [{ type: Input }], maxSize: [{ type: Input }], pageChange: [{ type: Output }], pageBoundsCorrection: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdGlvbi1jb250cm9scy5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWFzeS10YWJsZS9zcmMvbGliL2ZlYXR1cmVzL3BhZ2luYXRpb24vcGFnaW5hdGlvbi1jb250cm9scy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7OztBQVd4Rjs7OztHQUlHO0FBS0gsTUFBTSxPQUFPLDJCQUEyQjtJQVNwQyxZQUFvQixPQUEwQixFQUMxQixpQkFBb0M7UUFEcEMsWUFBTyxHQUFQLE9BQU8sQ0FBbUI7UUFDMUIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQVIvQyxZQUFPLEdBQVcsQ0FBQyxDQUFDO1FBQ25CLGVBQVUsR0FBeUIsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUM5RCx5QkFBb0IsR0FBeUIsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUNsRixVQUFLLEdBQVcsRUFBRSxDQUFDO1FBTWYsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU07YUFDL0IsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ1osSUFBSSxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDaEIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUMxQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssU0FBUyxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFD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QUFHLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxLQUFLLGVBQWUsRUFBRTtZQUN2QixPQUFPLFVBQVUsQ0FBQztTQUNyQjthQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNoQixPQUFPLENBQUMsQ0FBQztTQUNaO2FBQU0sSUFBSSxlQUFlLEdBQUcsVUFBVSxFQUFFO1lBQ3JDLElBQUksVUFBVSxHQUFHLE9BQU8sR0FBRyxXQUFXLEVBQUU7Z0JBQ3BDLE9BQU8sVUFBVSxHQUFHLGVBQWUsR0FBRyxDQUFDLENBQUM7YUFDM0M7aUJBQU0sSUFBSSxPQUFPLEdBQUcsV0FBVyxFQUFFO2dCQUM5QixPQUFPLFdBQVcsR0FBRyxPQUFPLEdBQUcsQ0FBQyxDQUFDO2FBQ3BDO2lCQUFNO2dCQUNILE9BQU8sQ0FBQyxDQUFDO2FBQ1o7U0FDSjthQUFNO1lBQ0gsT0FBTyxDQUFDLENBQUM7U0FDWjtJQUNMLENBQUM7OEdBdk1RLDJCQUEyQjtrR0FBM0IsMkJBQTJCOzsyRkFBM0IsMkJBQTJCO2tCQUp2QyxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSwyQ0FBMkM7b0JBQ3JELFFBQVEsRUFBRSxlQUFlO2lCQUM1Qjt3SUFFWSxFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNJLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csb0JBQW9CO3NCQUE3QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3RvclJlZiwgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1BhZ2luYXRpb25TZXJ2aWNlfSBmcm9tICcuL3BhZ2luYXRpb24uc2VydmljZSc7XG5pbXBvcnQge1BhZ2luYXRpb25JbnN0YW5jZUludGVyZmFjZX0gZnJvbSAnLi9pbnRlcmZhY2VzL3BhZ2luYXRpb24taW5zdGFuY2UuaW50ZXJmYWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBQYWdlIHtcbiAgICBsYWJlbDogc3RyaW5nO1xuICAgIHZhbHVlOiBhbnk7XG59XG5cbi8qKlxuICogVGhpcyBkaXJlY3RpdmUgaXMgd2hhdCBwb3dlcnMgYWxsIHBhZ2luYXRpb24gY29udHJvbHMgY29tcG9uZW50cywgaW5jbHVkaW5nIHRoZSBkZWZhdWx0IG9uZS5cbiAqIEl0IGV4cG9zZXMgYW4gQVBJIHdoaWNoIGlzIGhvb2tlZCB1cCB0byB0aGUgUGFnaW5hdGlvblNlcnZpY2UgdG8ga2VlcCB0aGUgUGFnaW5hdGVQaXBlIGluIHN5bmNcbiAqIHdpdGggdGhlIHBhZ2luYXRpb24gY29udHJvbHMuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAncGFnaW5hdGlvbi10ZW1wbGF0ZSxbcGFnaW5hdGlvbi10ZW1wbGF0ZV0nLFxuICAgIGV4cG9ydEFzOiAncGFnaW5hdGlvbkFwaSdcbn0pXG5leHBvcnQgY2xhc3MgUGFnaW5hdGlvbkNvbnRyb2xzRGlyZWN0aXZlIHtcbiAgICBASW5wdXQoKSBpZDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIG1heFNpemU6IG51bWJlciA9IDc7XG4gICAgQE91dHB1dCgpIHBhZ2VDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gICAgQE91dHB1dCgpIHBhZ2VCb3VuZHNDb3JyZWN0aW9uOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICAgIHBhZ2VzOiBQYWdlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2hhbmdlU3ViOiBTdWJzY3JpcHRpb247XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNlcnZpY2U6IFBhZ2luYXRpb25TZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlU3ViID0gdGhpcy5zZXJ2aWNlLmNoYW5nZVxuICAgICAgICAgICAgLnN1YnNjcmliZShpZCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaWQgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUGFnZUxpbmtzKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICBpZiAodGhpcy5pZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmlkID0gdGhpcy5zZXJ2aWNlLmRlZmF1bHRJZCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlUGFnZUxpbmtzKCk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlUGFnZUxpbmtzKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gdG8gdGhlIHByZXZpb3VzIHBhZ2VcbiAgICAgKi9cbiAgICBwcmV2aW91cygpIHtcbiAgICAgICAgdGhpcy5jaGVja1ZhbGlkSWQoKTtcbiAgICAgICAgdGhpcy5zZXRDdXJyZW50KHRoaXMuZ2V0Q3VycmVudCgpIC0gMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gdG8gdGhlIG5leHQgcGFnZVxuICAgICAqL1xuICAgIG5leHQoKSB7XG4gICAgICAgIHRoaXMuY2hlY2tWYWxpZElkKCk7XG4gICAgICAgIHRoaXMuc2V0Q3VycmVudCh0aGlzLmdldEN1cnJlbnQoKSArIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiBjdXJyZW50IHBhZ2UgaXMgZmlyc3QgcGFnZVxuICAgICAqL1xuICAgIGlzRmlyc3RQYWdlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50KCkgPT09IDE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIGN1cnJlbnQgcGFnZSBpcyBsYXN0IHBhZ2VcbiAgICAgKi9cbiAgICBpc0xhc3RQYWdlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRMYXN0UGFnZSgpID09PSB0aGlzLmdldEN1cnJlbnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGN1cnJlbnQgcGFnZSBudW1iZXIuXG4gICAgICovXG4gICAgc2V0Q3VycmVudChwYWdlOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5wYWdlQ2hhbmdlLmVtaXQocGFnZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHBhZ2UgbnVtYmVyLlxuICAgICAqL1xuICAgIGdldEN1cnJlbnQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VydmljZS5nZXRDdXJyZW50UGFnZSh0aGlzLmlkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IHBhZ2UgbnVtYmVyXG4gICAgICovXG4gICAgZ2V0TGFzdFBhZ2UoKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGluc3QgPSB0aGlzLnNlcnZpY2UuZ2V0SW5zdGFuY2UodGhpcy5pZCk7XG4gICAgICAgIGNvbnN0IHRvdGFsSXRlbXMgPSBpbnN0LnRvdGFsSXRlbXMgPz8gMDtcbiAgICAgICAgaWYgKHRvdGFsSXRlbXMgPCAxKSB7XG4gICAgICAgICAgICAvLyB3aGVuIHRoZXJlIGFyZSAwIG9yIGZld2VyIChhbiBlcnJvciBjYXNlKSBpdGVtcywgdGhlcmUgYXJlIG5vIFwicGFnZXNcIiBhcyBzdWNoLFxuICAgICAgICAgICAgLy8gYnV0IGl0IG1ha2VzIHNlbnNlIHRvIGNvbnNpZGVyIGEgc2luZ2xlLCBlbXB0eSBwYWdlIGFzIHRoZSBsYXN0IHBhZ2UuXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTWF0aC5jZWlsKHRvdGFsSXRlbXMgLyBpbnN0Lml0ZW1zUGVyUGFnZSk7XG4gICAgfVxuXG4gICAgZ2V0VG90YWxJdGVtcygpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXJ2aWNlLmdldEluc3RhbmNlKHRoaXMuaWQpLnRvdGFsSXRlbXMgPz8gMDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrVmFsaWRJZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2VydmljZS5nZXRJbnN0YW5jZSh0aGlzLmlkKS5pZCA9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFBhZ2luYXRpb25Db250cm9sc0RpcmVjdGl2ZTogdGhlIHNwZWNpZmllZCBpZCBcIiR7dGhpcy5pZH1cIiBkb2VzIG5vdCBtYXRjaCBhbnkgcmVnaXN0ZXJlZCBQYWdpbmF0aW9uSW5zdGFuY2VgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIHBhZ2UgbGlua3MgYW5kIGNoZWNrcyB0aGF0IHRoZSBjdXJyZW50IHBhZ2UgaXMgdmFsaWQuIFNob3VsZCBydW4gd2hlbmV2ZXIgdGhlXG4gICAgICogUGFnaW5hdGlvblNlcnZpY2UuY2hhbmdlIHN0cmVhbSBlbWl0cyBhIHZhbHVlIG1hdGNoaW5nIHRoZSBjdXJyZW50IElELCBvciB3aGVuIGFueSBvZiB0aGVcbiAgICAgKiBpbnB1dCB2YWx1ZXMgY2hhbmdlcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZVBhZ2VMaW5rcygpIHtcbiAgICAgICAgbGV0IGluc3QgPSB0aGlzLnNlcnZpY2UuZ2V0SW5zdGFuY2UodGhpcy5pZCk7XG4gICAgICAgIGNvbnN0IGNvcnJlY3RlZEN1cnJlbnRQYWdlID0gdGhpcy5vdXRPZkJvdW5kQ29ycmVjdGlvbihpbnN0KTtcblxuICAgICAgICBpZiAoY29ycmVjdGVkQ3VycmVudFBhZ2UgIT09IGluc3QuY3VycmVudFBhZ2UpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucGFnZUJvdW5kc0NvcnJlY3Rpb24uZW1pdChjb3JyZWN0ZWRDdXJyZW50UGFnZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5wYWdlcyA9IHRoaXMuY3JlYXRlUGFnZUFycmF5KGluc3QuY3VycmVudFBhZ2UsIGluc3QuaXRlbXNQZXJQYWdlLCAoaW5zdC50b3RhbEl0ZW1zID8/IDApLCB0aGlzLm1heFNpemUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnBhZ2VzID0gdGhpcy5jcmVhdGVQYWdlQXJyYXkoaW5zdC5jdXJyZW50UGFnZSwgaW5zdC5pdGVtc1BlclBhZ2UsIChpbnN0LnRvdGFsSXRlbXMgPz8gMCksIHRoaXMubWF4U2l6ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgdGhhdCB0aGUgaW5zdGFuY2UuY3VycmVudFBhZ2UgcHJvcGVydHkgaXMgd2l0aGluIGJvdW5kcyBmb3IgdGhlIGN1cnJlbnQgcGFnZSByYW5nZS5cbiAgICAgKiBJZiBub3QsIHJldHVybiBhIGNvcnJlY3QgdmFsdWUgZm9yIGN1cnJlbnRQYWdlLCBvciB0aGUgY3VycmVudCB2YWx1ZSBpZiBPSy5cbiAgICAgKi9cbiAgICBwcml2YXRlIG91dE9mQm91bmRDb3JyZWN0aW9uKGluc3RhbmNlOiBQYWdpbmF0aW9uSW5zdGFuY2VJbnRlcmZhY2UpOiBudW1iZXIge1xuICAgICAgICBjb25zdCB0b3RhbFBhZ2VzID0gTWF0aC5jZWlsKChpbnN0YW5jZS50b3RhbEl0ZW1zID8/IDApIC8gaW5zdGFuY2UuaXRlbXNQZXJQYWdlKTtcbiAgICAgICAgaWYgKHRvdGFsUGFnZXMgPCBpbnN0YW5jZS5jdXJyZW50UGFnZSAmJiAwIDwgdG90YWxQYWdlcykge1xuICAgICAgICAgICAgcmV0dXJuIHRvdGFsUGFnZXM7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UuY3VycmVudFBhZ2UgPCAxKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbnN0YW5jZS5jdXJyZW50UGFnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIFBhZ2Ugb2JqZWN0cyB0byB1c2UgaW4gdGhlIHBhZ2luYXRpb24gY29udHJvbHMuXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVQYWdlQXJyYXkoY3VycmVudFBhZ2U6IG51bWJlciwgaXRlbXNQZXJQYWdlOiBudW1iZXIsIHRvdGFsSXRlbXM6IG51bWJlciwgcGFnaW5hdGlvblJhbmdlOiBudW1iZXIpOiBQYWdlW10ge1xuICAgICAgICAvLyBwYWdpbmF0aW9uUmFuZ2UgY291bGQgYmUgYSBzdHJpbmcgaWYgcGFzc2VkIGZyb20gYXR0cmlidXRlLCBzbyBjYXN0IHRvIG51bWJlci5cbiAgICAgICAgcGFnaW5hdGlvblJhbmdlID0gK3BhZ2luYXRpb25SYW5nZTtcbiAgICAgICAgbGV0IHBhZ2VzID0gW107XG5cbiAgICAgICAgLy8gUmV0dXJuIDEgYXMgZGVmYXVsdCBwYWdlIG51bWJlclxuICAgICAgICAvLyBNYWtlIHNlbnNlIHRvIHNob3cgMSBpbnN0ZWFkIG9mIGVtcHR5IHdoZW4gdGhlcmUgYXJlIG5vIGl0ZW1zXG4gICAgICAgIGNvbnN0IHRvdGFsUGFnZXMgPSBNYXRoLm1heChNYXRoLmNlaWwodG90YWxJdGVtcyAvIGl0ZW1zUGVyUGFnZSksIDEpO1xuICAgICAgICBjb25zdCBoYWxmV2F5ID0gTWF0aC5jZWlsKHBhZ2luYXRpb25SYW5nZSAvIDIpO1xuXG4gICAgICAgIGNvbnN0IGlzU3RhcnQgPSBjdXJyZW50UGFnZSA8PSBoYWxmV2F5O1xuICAgICAgICBjb25zdCBpc0VuZCA9IHRvdGFsUGFnZXMgLSBoYWxmV2F5IDwgY3VycmVudFBhZ2U7XG4gICAgICAgIGNvbnN0IGlzTWlkZGxlID0gIWlzU3RhcnQgJiYgIWlzRW5kO1xuXG4gICAgICAgIGxldCBlbGxpcHNlc05lZWRlZCA9IHBhZ2luYXRpb25SYW5nZSA8IHRvdGFsUGFnZXM7XG4gICAgICAgIGxldCBpID0gMTtcblxuICAgICAgICB3aGlsZSAoaSA8PSB0b3RhbFBhZ2VzICYmIGkgPD0gcGFnaW5hdGlvblJhbmdlKSB7XG4gICAgICAgICAgICBsZXQgbGFiZWw7XG4gICAgICAgICAgICBsZXQgcGFnZU51bWJlciA9IHRoaXMuY2FsY3VsYXRlUGFnZU51bWJlcihpLCBjdXJyZW50UGFnZSwgcGFnaW5hdGlvblJhbmdlLCB0b3RhbFBhZ2VzKTtcbiAgICAgICAgICAgIGxldCBvcGVuaW5nRWxsaXBzZXNOZWVkZWQgPSAoaSA9PT0gMiAmJiAoaXNNaWRkbGUgfHwgaXNFbmQpKTtcbiAgICAgICAgICAgIGxldCBjbG9zaW5nRWxsaXBzZXNOZWVkZWQgPSAoaSA9PT0gcGFnaW5hdGlvblJhbmdlIC0gMSAmJiAoaXNNaWRkbGUgfHwgaXNTdGFydCkpO1xuICAgICAgICAgICAgaWYgKGVsbGlwc2VzTmVlZGVkICYmIChvcGVuaW5nRWxsaXBzZXNOZWVkZWQgfHwgY2xvc2luZ0VsbGlwc2VzTmVlZGVkKSkge1xuICAgICAgICAgICAgICAgIGxhYmVsID0gJy4uLic7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxhYmVsID0gcGFnZU51bWJlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUgZG9uJ3Qga25vdyB3aHkgaXQgY29uc2lkZXJzIHRoZSBvYmplY3QgYXMgbmV2ZXIgOnNocnVnOlxuICAgICAgICAgICAgcGFnZXMucHVzaCh7XG4gICAgICAgICAgICAgIGxhYmVsOiBsYWJlbCxcbiAgICAgICAgICAgICAgdmFsdWU6IHBhZ2VOdW1iZXJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaSArKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFnZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gdGhlIHBvc2l0aW9uIGluIHRoZSBzZXF1ZW5jZSBvZiBwYWdpbmF0aW9uIGxpbmtzIFtpXSxcbiAgICAgKiBmaWd1cmUgb3V0IHdoYXQgcGFnZSBudW1iZXIgY29ycmVzcG9uZHMgdG8gdGhhdCBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIGNhbGN1bGF0ZVBhZ2VOdW1iZXIoaTogbnVtYmVyLCBjdXJyZW50UGFnZTogbnVtYmVyLCBwYWdpbmF0aW9uUmFuZ2U6IG51bWJlciwgdG90YWxQYWdlczogbnVtYmVyKSB7XG4gICAgICAgIGxldCBoYWxmV2F5ID0gTWF0aC5jZWlsKHBhZ2luYXRpb25SYW5nZSAvIDIpO1xuICAgICAgICBpZiAoaSA9PT0gcGFnaW5hdGlvblJhbmdlKSB7XG4gICAgICAgICAgICByZXR1cm4gdG90YWxQYWdlcztcbiAgICAgICAgfSBlbHNlIGlmIChpID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfSBlbHNlIGlmIChwYWdpbmF0aW9uUmFuZ2UgPCB0b3RhbFBhZ2VzKSB7XG4gICAgICAgICAgICBpZiAodG90YWxQYWdlcyAtIGhhbGZXYXkgPCBjdXJyZW50UGFnZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0b3RhbFBhZ2VzIC0gcGFnaW5hdGlvblJhbmdlICsgaTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFsZldheSA8IGN1cnJlbnRQYWdlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRQYWdlIC0gaGFsZldheSArIGk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=