@hxui/angular
Version:
* * *
414 lines • 33.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
import { Component, ElementRef, Renderer2, Input, Output, EventEmitter, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { PaginationConfig } from './pagination.config';
/** @type {?} */
export const PAGER_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PagerComponent),
multi: true
};
/** @type {?} */
const PAGER_TEMPLATE = `
<ul class="hx-flex hx-flex-justify-between">
<li [class.is-disabled]="noPrevious()" [class.is-previous]="align" class="{{ pageBtnClass }}">
<a href (click)="selectPage(page - 1, $event)">{{getText('previous')}}</a>
</li>
<li [class.is-disabled]="noNext()" [class.is-next]="align" class="{{ pageBtnClass }}">
<a href (click)="selectPage(page + 1, $event)">{{getText('next')}}</a>
</li>
</ul>
`;
export class PagerComponent {
/**
* @param {?} renderer
* @param {?} elementRef
* @param {?} paginationConfig
*/
constructor(renderer, elementRef, paginationConfig) {
/**
* fired when total pages count changes, $event:number equals to total pages count
*/
this.numPages = new EventEmitter();
/**
* fired when page was changed, $event:{page, itemsPerPage} equals to object with current page index and number of items per page
*/
this.pageChanged = new EventEmitter();
this.onChange = Function.prototype;
this.onTouched = Function.prototype;
this.inited = false;
this._page = 1;
this.renderer = renderer;
this.elementRef = elementRef;
if (!this.config) {
this.configureOptions(Object.assign({}, paginationConfig.main, paginationConfig.pager));
}
}
/**
* maximum number of items per page. If value less than 1 will display all items on one page
* @return {?}
*/
get itemsPerPage() {
return this._itemsPerPage;
}
/**
* @param {?} v
* @return {?}
*/
set itemsPerPage(v) {
this._itemsPerPage = v;
this.totalPages = this.calculateTotalPages();
}
/**
* total number of items in all pages
* @return {?}
*/
get totalItems() {
return this._totalItems;
}
/**
* @param {?} v
* @return {?}
*/
set totalItems(v) {
this._totalItems = v;
this.totalPages = this.calculateTotalPages();
}
/**
* @return {?}
*/
get totalPages() {
return this._totalPages;
}
/**
* @param {?} v
* @return {?}
*/
set totalPages(v) {
this._totalPages = v;
this.numPages.emit(v);
if (this.inited) {
this.selectPage(this.page);
}
}
/**
* @param {?} value
* @return {?}
*/
set page(value) {
/** @type {?} */
const _previous = this._page;
this._page = (value > this.totalPages) ? this.totalPages : (value || 1);
if (_previous === this._page || typeof _previous === 'undefined') {
return;
}
this.pageChanged.emit({
page: this._page,
itemsPerPage: this.itemsPerPage
});
}
/**
* @return {?}
*/
get page() {
return this._page;
}
/**
* @param {?} config
* @return {?}
*/
configureOptions(config) {
this.config = Object.assign({}, config);
}
/**
* @return {?}
*/
ngOnInit() {
this.classMap = this.elementRef.nativeElement.getAttribute('class') || '';
// watch for maxSize
this.maxSize = typeof this.maxSize !== 'undefined'
? this.maxSize
: this.config.maxSize;
this.rotate = typeof this.rotate !== 'undefined'
? this.rotate
: this.config.rotate;
this.boundaryLinks = typeof this.boundaryLinks !== 'undefined'
? this.boundaryLinks
: this.config.boundaryLinks;
this.directionLinks = typeof this.directionLinks !== 'undefined'
? this.directionLinks
: this.config.directionLinks;
this.pageBtnClass = typeof this.pageBtnClass !== 'undefined'
? this.pageBtnClass
: this.config.pageBtnClass;
// base class
this.itemsPerPage = typeof this.itemsPerPage !== 'undefined'
? this.itemsPerPage
: this.config.itemsPerPage;
this.totalPages = this.calculateTotalPages();
// this class
this.pages = this.getPages(this.page, this.totalPages);
this.inited = true;
}
/**
* @param {?} value
* @return {?}
*/
writeValue(value) {
this.page = value;
this.pages = this.getPages(this.page, this.totalPages);
}
/**
* @param {?} key
* @return {?}
*/
getText(key) {
return ((/** @type {?} */ (this)))[key + 'Text'] || this.config[key + 'Text'];
}
/**
* @return {?}
*/
noPrevious() {
return this.page === 1;
}
/**
* @return {?}
*/
noNext() {
return this.page === this.totalPages;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* @param {?} page
* @param {?=} event
* @return {?}
*/
selectPage(page, event) {
if (event) {
event.preventDefault();
}
if (!this.disabled) {
if (event && event.target) {
/** @type {?} */
const target = event.target;
target.blur();
}
this.writeValue(page);
this.onChange(this.page);
}
}
// Create page object used in template
/**
* @param {?} num
* @param {?} text
* @param {?} active
* @return {?}
*/
makePage(num, text, active) {
return { text, number: num, active };
}
/**
* @param {?} currentPage
* @param {?} totalPages
* @return {?}
*/
getPages(currentPage, totalPages) {
/** @type {?} */
const pages = [];
// Default page limits
/** @type {?} */
let startPage = 1;
/** @type {?} */
let endPage = totalPages;
/** @type {?} */
const isMaxSized = typeof this.maxSize !== 'undefined' && this.maxSize < totalPages;
// recompute if maxSize
if (isMaxSized) {
if (this.rotate) {
// Current page is displayed in the middle of the visible ones
startPage = Math.max(currentPage - Math.floor(this.maxSize / 2), 1);
endPage = startPage + this.maxSize - 1;
// Adjust if limit is exceeded
if (endPage > totalPages) {
endPage = totalPages;
startPage = endPage - this.maxSize + 1;
}
}
else {
// Visible pages are paginated with maxSize
startPage = ((Math.ceil(currentPage / this.maxSize) - 1) * this.maxSize) + 1;
// Adjust last page if limit is exceeded
endPage = Math.min(startPage + this.maxSize - 1, totalPages);
}
}
// Add page number links
for (let num = startPage; num <= endPage; num++) {
/** @type {?} */
const page = this.makePage(num, num.toString(), num === currentPage);
pages.push(page);
}
// Add links to move between page sets
if (isMaxSized && !this.rotate) {
if (startPage > 1) {
/** @type {?} */
const previousPageSet = this.makePage(startPage - 1, '...', false);
pages.unshift(previousPageSet);
}
if (endPage < totalPages) {
/** @type {?} */
const nextPageSet = this.makePage(endPage + 1, '...', false);
pages.push(nextPageSet);
}
}
return pages;
}
// base class
/**
* @return {?}
*/
calculateTotalPages() {
/** @type {?} */
const totalPages = this.itemsPerPage < 1
? 1
: Math.ceil(this.totalItems / this.itemsPerPage);
return Math.max(totalPages || 0, 1);
}
}
PagerComponent.decorators = [
{ type: Component, args: [{
selector: 'hx-pager',
template: PAGER_TEMPLATE,
providers: [PAGER_CONTROL_VALUE_ACCESSOR]
},] },
];
/** @nocollapse */
PagerComponent.ctorParameters = () => [
{ type: Renderer2 },
{ type: ElementRef },
{ type: PaginationConfig }
];
PagerComponent.propDecorators = {
align: [{ type: Input }],
maxSize: [{ type: Input }],
boundaryLinks: [{ type: Input }],
directionLinks: [{ type: Input }],
firstText: [{ type: Input }],
previousText: [{ type: Input }],
nextText: [{ type: Input }],
lastText: [{ type: Input }],
rotate: [{ type: Input }],
pageBtnClass: [{ type: Input }],
disabled: [{ type: Input }],
numPages: [{ type: Output }],
pageChanged: [{ type: Output }],
itemsPerPage: [{ type: Input }],
totalItems: [{ type: Input }]
};
if (false) {
/** @type {?} */
PagerComponent.prototype.config;
/**
* if `true` aligns each link to the sides of pager
* @type {?}
*/
PagerComponent.prototype.align;
/**
* limit number for page links in pager
* @type {?}
*/
PagerComponent.prototype.maxSize;
/**
* if false first and last buttons will be hidden
* @type {?}
*/
PagerComponent.prototype.boundaryLinks;
/**
* if false previous and next buttons will be hidden
* @type {?}
*/
PagerComponent.prototype.directionLinks;
/**
* first button text
* @type {?}
*/
PagerComponent.prototype.firstText;
/**
* previous button text
* @type {?}
*/
PagerComponent.prototype.previousText;
/**
* next button text
* @type {?}
*/
PagerComponent.prototype.nextText;
/**
* last button text
* @type {?}
*/
PagerComponent.prototype.lastText;
/**
* if true current page will in the middle of pages list
* @type {?}
*/
PagerComponent.prototype.rotate;
/**
* add class to <li>
* @type {?}
*/
PagerComponent.prototype.pageBtnClass;
/**
* if true pagination component will be disabled
* @type {?}
*/
PagerComponent.prototype.disabled;
/**
* fired when total pages count changes, $event:number equals to total pages count
* @type {?}
*/
PagerComponent.prototype.numPages;
/**
* fired when page was changed, $event:{page, itemsPerPage} equals to object with current page index and number of items per page
* @type {?}
*/
PagerComponent.prototype.pageChanged;
/** @type {?} */
PagerComponent.prototype.onChange;
/** @type {?} */
PagerComponent.prototype.onTouched;
/** @type {?} */
PagerComponent.prototype.renderer;
/** @type {?} */
PagerComponent.prototype.elementRef;
/** @type {?} */
PagerComponent.prototype.classMap;
/** @type {?} */
PagerComponent.prototype.pages;
/** @type {?} */
PagerComponent.prototype._itemsPerPage;
/** @type {?} */
PagerComponent.prototype._totalItems;
/** @type {?} */
PagerComponent.prototype._totalPages;
/** @type {?} */
PagerComponent.prototype.inited;
/** @type {?} */
PagerComponent.prototype._page;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGh4dWkvYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9wYWdpbmF0aW9uL3BhZ2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQVUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsSCxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBRXZELE1BQU0sT0FBTyw0QkFBNEIsR0FBUTtJQUMvQyxPQUFPLEVBQUUsaUJBQWlCO0lBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsY0FBYyxDQUFDO0lBQzdDLEtBQUssRUFBRSxJQUFJO0NBQ1o7O01BRUssY0FBYyxHQUFHOzs7Ozs7Ozs7Q0FTdEI7QUFPRCxNQUFNLE9BQU8sY0FBYzs7Ozs7O0lBb0d6QixZQUFtQixRQUFtQixFQUFFLFVBQXNCLEVBQUUsZ0JBQWtDOzs7O1FBdkVqRixhQUFRLEdBQXlCLElBQUksWUFBWSxFQUFVLENBQUM7Ozs7UUFFNUQsZ0JBQVcsR0FBbUMsSUFBSSxZQUFZLEVBQW9CLENBQUM7UUFzRDdGLGFBQVEsR0FBUSxRQUFRLENBQUMsU0FBUyxDQUFDO1FBQ25DLGNBQVMsR0FBUSxRQUFRLENBQUMsU0FBUyxDQUFDO1FBV2pDLFdBQU0sR0FBRyxLQUFLLENBQUM7UUFDZixVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBR2xCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxn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QUFLO3dCQUdMLEtBQUs7MkJBRUwsS0FBSzt1QkFFTCxLQUFLO3VCQUVMLEtBQUs7cUJBRUwsS0FBSzsyQkFHTCxLQUFLO3VCQUdMLEtBQUs7dUJBR0wsTUFBTTswQkFFTixNQUFNOzJCQUdOLEtBQUs7eUJBV0wsS0FBSzs7OztJQTVDTixnQ0FBbUI7Ozs7O0lBRW5CLCtCQUErQjs7Ozs7SUFFL0IsaUNBQWdDOzs7OztJQUVoQyx1Q0FBdUM7Ozs7O0lBRXZDLHdDQUF3Qzs7Ozs7SUFHeEMsbUNBQWtDOzs7OztJQUVsQyxzQ0FBcUM7Ozs7O0lBRXJDLGtDQUFpQzs7Ozs7SUFFakMsa0NBQWlDOzs7OztJQUVqQyxnQ0FBZ0M7Ozs7O0lBR2hDLHNDQUFxQzs7Ozs7SUFHckMsa0NBQWtDOzs7OztJQUdsQyxrQ0FBNkU7Ozs7O0lBRTdFLHFDQUFvRzs7SUFzRHBHLGtDQUEwQzs7SUFDMUMsbUNBQTJDOztJQUUzQyxrQ0FBMkI7O0lBQzNCLG9DQUE4Qjs7SUFFOUIsa0NBQXdCOztJQUN4QiwrQkFBb0I7O0lBRXBCLHVDQUFnQzs7SUFDaEMscUNBQThCOztJQUM5QixxQ0FBOEI7O0lBQzlCLGdDQUF5Qjs7SUFDekIsK0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBPbkluaXQsIFJlbmRlcmVyMiwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBmb3J3YXJkUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgUGFnZUNoYW5nZWRFdmVudCB9IGZyb20gJy4vcGFnaW5hdGlvbi5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBQYWdpbmF0aW9uQ29uZmlnIH0gZnJvbSAnLi9wYWdpbmF0aW9uLmNvbmZpZyc7XHJcblxyXG5leHBvcnQgY29uc3QgUEFHRVJfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUjogYW55ID0ge1xyXG4gIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFBhZ2VyQ29tcG9uZW50KSxcclxuICBtdWx0aTogdHJ1ZVxyXG59O1xyXG5cclxuY29uc3QgUEFHRVJfVEVNUExBVEUgPSBgXHJcbiAgICA8dWwgY2xhc3M9XCJoeC1mbGV4IGh4LWZsZXgtanVzdGlmeS1iZXR3ZWVuXCI+XHJcbiAgICAgIDxsaSBbY2xhc3MuaXMtZGlzYWJsZWRdPVwibm9QcmV2aW91cygpXCIgW2NsYXNzLmlzLXByZXZpb3VzXT1cImFsaWduXCIgY2xhc3M9XCJ7eyBwYWdlQnRuQ2xhc3MgfX1cIj5cclxuICAgICAgICA8YSBocmVmIChjbGljayk9XCJzZWxlY3RQYWdlKHBhZ2UgLSAxLCAkZXZlbnQpXCI+e3tnZXRUZXh0KCdwcmV2aW91cycpfX08L2E+XHJcbiAgICAgIDwvbGk+XHJcbiAgICAgIDxsaSBbY2xhc3MuaXMtZGlzYWJsZWRdPVwibm9OZXh0KClcIiBbY2xhc3MuaXMtbmV4dF09XCJhbGlnblwiIGNsYXNzPVwie3sgcGFnZUJ0bkNsYXNzIH19XCI+XHJcbiAgICAgICAgPGEgaHJlZiAoY2xpY2spPVwic2VsZWN0UGFnZShwYWdlICsgMSwgJGV2ZW50KVwiPnt7Z2V0VGV4dCgnbmV4dCcpfX08L2E+XHJcbiAgICAgIDwvbGk+XHJcbiAgPC91bD5cclxuYDtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnaHgtcGFnZXInLFxyXG4gIHRlbXBsYXRlOiBQQUdFUl9URU1QTEFURSxcclxuICBwcm92aWRlcnM6IFtQQUdFUl9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgUGFnZXJDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0IHtcclxuICBwdWJsaWMgY29uZmlnOiBhbnk7XHJcbiAgLyoqIGlmIGB0cnVlYCBhbGlnbnMgZWFjaCBsaW5rIHRvIHRoZSBzaWRlcyBvZiBwYWdlciAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBhbGlnbjogYm9vbGVhbjtcclxuICAvKiogbGltaXQgbnVtYmVyIGZvciBwYWdlIGxpbmtzIGluIHBhZ2VyICovXHJcbiAgQElucHV0KCkgcHVibGljIG1heFNpemU6IG51bWJlcjtcclxuICAvKiogaWYgZmFsc2UgZmlyc3QgYW5kIGxhc3QgYnV0dG9ucyB3aWxsIGJlIGhpZGRlbiAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBib3VuZGFyeUxpbmtzOiBib29sZWFuO1xyXG4gIC8qKiBpZiBmYWxzZSBwcmV2aW91cyBhbmQgbmV4dCBidXR0b25zIHdpbGwgYmUgaGlkZGVuICovXHJcbiAgQElucHV0KCkgcHVibGljIGRpcmVjdGlvbkxpbmtzOiBib29sZWFuO1xyXG4gIC8vIGxhYmVsc1xyXG4gIC8qKiBmaXJzdCBidXR0b24gdGV4dCAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBmaXJzdFRleHQ6IHN0cmluZztcclxuICAvKiogcHJldmlvdXMgYnV0dG9uIHRleHQgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgcHJldmlvdXNUZXh0OiBzdHJpbmc7XHJcbiAgLyoqIG5leHQgYnV0dG9uIHRleHQgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgbmV4dFRleHQ6IHN0cmluZztcclxuICAvKiogbGFzdCBidXR0b24gdGV4dCAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBsYXN0VGV4dDogc3RyaW5nO1xyXG4gIC8qKiBpZiB0cnVlIGN1cnJlbnQgcGFnZSB3aWxsIGluIHRoZSBtaWRkbGUgb2YgcGFnZXMgbGlzdCAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyByb3RhdGU6IGJvb2xlYW47XHJcbiAgLy8gY3NzXHJcbiAgLyoqIGFkZCBjbGFzcyB0byA8bGk+ICovXHJcbiAgQElucHV0KCkgcHVibGljIHBhZ2VCdG5DbGFzczogc3RyaW5nO1xyXG5cclxuICAvKiogaWYgdHJ1ZSBwYWdpbmF0aW9uIGNvbXBvbmVudCB3aWxsIGJlIGRpc2FibGVkICovXHJcbiAgQElucHV0KCkgcHVibGljIGRpc2FibGVkOiBib29sZWFuO1xyXG5cclxuICAvKiogZmlyZWQgd2hlbiB0b3RhbCBwYWdlcyBjb3VudCBjaGFuZ2VzLCAkZXZlbnQ6bnVtYmVyIGVxdWFscyB0byB0b3RhbCBwYWdlcyBjb3VudCAqL1xyXG4gIEBPdXRwdXQoKSBwdWJsaWMgbnVtUGFnZXM6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcbiAgLyoqIGZpcmVkIHdoZW4gcGFnZSB3YXMgY2hhbmdlZCwgJGV2ZW50OntwYWdlLCBpdGVtc1BlclBhZ2V9IGVxdWFscyB0byBvYmplY3Qgd2l0aCBjdXJyZW50IHBhZ2UgaW5kZXggYW5kIG51bWJlciBvZiBpdGVtcyBwZXIgcGFnZSAqL1xyXG4gIEBPdXRwdXQoKSBwdWJsaWMgcGFnZUNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxQYWdlQ2hhbmdlZEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8UGFnZUNoYW5nZWRFdmVudD4oKTtcclxuXHJcbiAgLyoqIG1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHBlciBwYWdlLiBJZiB2YWx1ZSBsZXNzIHRoYW4gMSB3aWxsIGRpc3BsYXkgYWxsIGl0ZW1zIG9uIG9uZSBwYWdlICovXHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZ2V0IGl0ZW1zUGVyUGFnZSgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2l0ZW1zUGVyUGFnZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXQgaXRlbXNQZXJQYWdlKHY6IG51bWJlcikge1xyXG4gICAgdGhpcy5faXRlbXNQZXJQYWdlID0gdjtcclxuICAgIHRoaXMudG90YWxQYWdlcyA9IHRoaXMuY2FsY3VsYXRlVG90YWxQYWdlcygpO1xyXG4gIH1cclxuXHJcbiAgLyoqIHRvdGFsIG51bWJlciBvZiBpdGVtcyBpbiBhbGwgcGFnZXMgKi9cclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBnZXQgdG90YWxJdGVtcygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX3RvdGFsSXRlbXM7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0IHRvdGFsSXRlbXModjogbnVtYmVyKSB7XHJcbiAgICB0aGlzLl90b3RhbEl0ZW1zID0gdjtcclxuICAgIHRoaXMudG90YWxQYWdlcyA9IHRoaXMuY2FsY3VsYXRlVG90YWxQYWdlcygpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCB0b3RhbFBhZ2VzKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5fdG90YWxQYWdlcztcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXQgdG90YWxQYWdlcyh2OiBudW1iZXIpIHtcclxuICAgIHRoaXMuX3RvdGFsUGFnZXMgPSB2O1xyXG4gICAgdGhpcy5udW1QYWdlcy5lbWl0KHYpO1xyXG4gICAgaWYgKHRoaXMuaW5pdGVkKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0UGFnZSh0aGlzLnBhZ2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldCBwYWdlKHZhbHVlOiBudW1iZXIpIHtcclxuICAgIGNvbnN0IF9wcmV2aW91cyA9IHRoaXMuX3BhZ2U7XHJcbiAgICB0aGlzLl9wYWdlID0gKHZhbHVlID4gdGhpcy50b3RhbFBhZ2VzKSA/IHRoaXMudG90YWxQYWdlcyA6ICh2YWx1ZSB8fCAxKTtcclxuXHJcbiAgICBpZiAoX3ByZXZpb3VzID09PSB0aGlzLl9wYWdlIHx8IHR5cGVvZiBfcHJldmlvdXMgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBhZ2VDaGFuZ2VkLmVtaXQoe1xyXG4gICAgICBwYWdlOiB0aGlzLl9wYWdlLFxyXG4gICAgICBpdGVtc1BlclBhZ2U6IHRoaXMuaXRlbXNQZXJQYWdlXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXQgcGFnZSgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX3BhZ2U7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25DaGFuZ2U6IGFueSA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcclxuICBwdWJsaWMgb25Ub3VjaGVkOiBhbnkgPSBGdW5jdGlvbi5wcm90b3R5cGU7XHJcblxyXG4gIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIyO1xyXG4gIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmO1xyXG5cclxuICBwdWJsaWMgY2xhc3NNYXA6IHN0cmluZztcclxuICBwdWJsaWMgcGFnZXM6IGFueVtdO1xyXG5cclxuICBwcm90ZWN0ZWQgX2l0ZW1zUGVyUGFnZTogbnVtYmVyO1xyXG4gIHByb3RlY3RlZCBfdG90YWxJdGVtczogbnVtYmVyO1xyXG4gIHByb3RlY3RlZCBfdG90YWxQYWdlczogbnVtYmVyO1xyXG4gIHByb3RlY3RlZCBpbml0ZWQgPSBmYWxzZTtcclxuICBwcm90ZWN0ZWQgX3BhZ2UgPSAxO1xyXG5cclxuICBwdWJsaWMgY29uc3RydWN0b3IocmVuZGVyZXI6IFJlbmRlcmVyMiwgZWxlbWVudFJlZjogRWxlbWVudFJlZiwgcGFnaW5hdGlvbkNvbmZpZzogUGFnaW5hdGlvbkNvbmZpZykge1xyXG4gICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xyXG4gICAgdGhpcy5lbGVtZW50UmVmID0gZWxlbWVudFJlZjtcclxuICAgIGlmICghdGhpcy5jb25maWcpIHtcclxuICAgICAgdGhpcy5jb25maWd1cmVPcHRpb25zKE9iamVjdC5hc3NpZ24oe30sIHBhZ2luYXRpb25Db25maWcubWFpbiwgcGFnaW5hdGlvbkNvbmZpZy5wYWdlcikpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGNvbmZpZ3VyZU9wdGlvbnMoY29uZmlnOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuY29uZmlnID0gT2JqZWN0LmFzc2lnbih7fSwgY29uZmlnKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2xhc3NNYXAgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykgfHwgJyc7XHJcbiAgICAvLyB3YXRjaCBmb3IgbWF4U2l6ZVxyXG4gICAgdGhpcy5tYXhTaXplID0gdHlwZW9mIHRoaXMubWF4U2l6ZSAhPT0gJ3VuZGVmaW5lZCdcclxuICAgICAgPyB0aGlzLm1heFNpemVcclxuICAgICAgOiB0aGlzLmNvbmZpZy5tYXhTaXplO1xyXG4gICAgdGhpcy5yb3RhdGUgPSB0eXBlb2YgdGhpcy5yb3RhdGUgIT09ICd1bmRlZmluZWQnXHJcbiAgICAgID8gdGhpcy5yb3RhdGVcclxuICAgICAgOiB0aGlzLmNvbmZpZy5yb3RhdGU7XHJcbiAgICB0aGlzLmJvdW5kYXJ5TGlua3MgPSB0eXBlb2YgdGhpcy5ib3VuZGFyeUxpbmtzICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICA/IHRoaXMuYm91bmRhcnlMaW5rc1xyXG4gICAgICA6IHRoaXMuY29uZmlnLmJvdW5kYXJ5TGlua3M7XHJcbiAgICB0aGlzLmRpcmVjdGlvbkxpbmtzID0gdHlwZW9mIHRoaXMuZGlyZWN0aW9uTGlua3MgIT09ICd1bmRlZmluZWQnXHJcbiAgICAgID8gdGhpcy5kaXJlY3Rpb25MaW5rc1xyXG4gICAgICA6IHRoaXMuY29uZmlnLmRpcmVjdGlvbkxpbmtzO1xyXG4gICAgdGhpcy5wYWdlQnRuQ2xhc3MgPSB0eXBlb2YgdGhpcy5wYWdlQnRuQ2xhc3MgIT09ICd1bmRlZmluZWQnXHJcbiAgICAgID8gdGhpcy5wYWdlQnRuQ2xhc3NcclxuICAgICAgOiB0aGlzLmNvbmZpZy5wYWdlQnRuQ2xhc3M7XHJcblxyXG4gICAgLy8gYmFzZSBjbGFzc1xyXG4gICAgdGhpcy5pdGVtc1BlclBhZ2UgPSB0eXBlb2YgdGhpcy5pdGVtc1BlclBhZ2UgIT09ICd1bmRlZmluZWQnXHJcbiAgICAgID8gdGhpcy5pdGVtc1BlclBhZ2VcclxuICAgICAgOiB0aGlzLmNvbmZpZy5pdGVtc1BlclBhZ2U7XHJcbiAgICB0aGlzLnRvdGFsUGFnZXMgPSB0aGlzLmNhbGN1bGF0ZVRvdGFsUGFnZXMoKTtcclxuICAgIC8vIHRoaXMgY2xhc3NcclxuICAgIHRoaXMucGFnZXMgPSB0aGlzLmdldFBhZ2VzKHRoaXMucGFnZSwgdGhpcy50b3RhbFBhZ2VzKTtcclxuICAgIHRoaXMuaW5pdGVkID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIHRoaXMucGFnZSA9IHZhbHVlO1xyXG4gICAgdGhpcy5wYWdlcyA9IHRoaXMuZ2V0UGFnZXModGhpcy5wYWdlLCB0aGlzLnRvdGFsUGFnZXMpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldFRleHQoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuICh0aGlzIGFzIGFueSlba2V5ICsgJ1RleHQnXSB8fCB0aGlzLmNvbmZpZ1trZXkgKyAnVGV4dCddO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5vUHJldmlvdXMoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5wYWdlID09PSAxO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5vTmV4dCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnBhZ2UgPT09IHRoaXMudG90YWxQYWdlcztcclxuICB9XHJcblxyXG4gIHB1YmxpYyByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoXzogYW55KSA9PiB7fSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB7fSk6IHZvaWQge1xyXG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZWxlY3RQYWdlKHBhZ2U6IG51bWJlciwgZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XHJcbiAgICAgIGlmIChldmVudCAmJiBldmVudC50YXJnZXQpIHtcclxuICAgICAgICBjb25zdCB0YXJnZXQ6IGFueSA9IGV2ZW50LnRhcmdldDtcclxuICAgICAgICB0YXJnZXQuYmx1cigpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMud3JpdGVWYWx1ZShwYWdlKTtcclxuICAgICAgdGhpcy5vbkNoYW5nZSh0aGlzLnBhZ2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gQ3JlYXRlIHBhZ2Ugb2JqZWN0IHVzZWQgaW4gdGVtcGxhdGVcclxuICBwcm90ZWN0ZWQgbWFrZVBhZ2UobnVtOiBudW1iZXIsIHRleHQ6IHN0cmluZywgYWN0aXZlOiBib29sZWFuKToge251bWJlcjogbnVtYmVyLCB0ZXh0OiBzdHJpbmcsIGFjdGl2ZTogYm9vbGVhbn0ge1xyXG4gICAgcmV0dXJuIHt0ZXh0LCBudW1iZXI6IG51bSwgYWN0aXZlfTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBnZXRQYWdlcyhjdXJyZW50UGFnZTogbnVtYmVyLCB0b3RhbFBhZ2VzOiBudW1iZXIpOiBhbnlbXSB7XHJcbiAgICBjb25zdCBwYWdlczogYW55W10gPSBbXTtcclxuXHJcbiAgICAvLyBEZWZhdWx0IHBhZ2UgbGltaXRzXHJcbiAgICBsZXQgc3RhcnRQYWdlID0gMTtcclxuICAgIGxldCBlbmRQYWdlID0gdG90YWxQYWdlcztcclxuICAgIGNvbnN0IGlzTWF4U2l6ZWQgPSB0eXBlb2YgdGhpcy5tYXhTaXplICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLm1heFNpemUgPCB0b3RhbFBhZ2VzO1xyXG5cclxuICAgIC8vIHJlY29tcHV0ZSBpZiBtYXhTaXplXHJcbiAgICBpZiAoaXNNYXhTaXplZCkge1xyXG4gICAgICBpZiAodGhpcy5yb3RhdGUpIHtcclxuICAgICAgICAvLyBDdXJyZW50IHBhZ2UgaXMgZGlzcGxheWVkIGluIHRoZSBtaWRkbGUgb2YgdGhlIHZpc2libGUgb25lc1xyXG4gICAgICAgIHN0YXJ0UGFnZSA9IE1hdGgubWF4KGN1cnJlbnRQYWdlIC0gTWF0aC5mbG9vcih0aGlzLm1heFNpemUgLyAyKSwgMSk7XHJcbiAgICAgICAgZW5kUGFnZSA9IHN0YXJ0UGFnZSArIHRoaXMubWF4U2l6ZSAtIDE7XHJcblxyXG4gICAgICAgIC8vIEFkanVzdCBpZiBsaW1pdCBpcyBleGNlZWRlZFxyXG4gICAgICAgIGlmIChlbmRQYWdlID4gdG90YWxQYWdlcykge1xyXG4gICAgICAgICAgZW5kUGFnZSA9IHRvdGFsUGFnZXM7XHJcbiAgICAgICAgICBzdGFydFBhZ2UgPSBlbmRQYWdlIC0gdGhpcy5tYXhTaXplICsgMTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gVmlzaWJsZSBwYWdlcyBhcmUgcGFnaW5hdGVkIHdpdGggbWF4U2l6ZVxyXG4gICAgICAgIHN0YXJ0UGFnZSA9ICgoTWF0aC5jZWlsKGN1cnJlbnRQYWdlIC8gdGhpcy5tYXhTaXplKSAtIDEpICogdGhpcy5tYXhTaXplKSArIDE7XHJcblxyXG4gICAgICAgIC8vIEFkanVzdCBsYXN0IHBhZ2UgaWYgbGltaXQgaXMgZXhjZWVkZWRcclxuICAgICAgICBlbmRQYWdlID0gTWF0aC5taW4oc3RhcnRQYWdlICsgdGhpcy5tYXhTaXplIC0gMSwgdG90YWxQYWdlcyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBBZGQgcGFnZSBudW1iZXIgbGlua3NcclxuICAgIGZvciAobGV0IG51bSA9IHN0YXJ0UGFnZTsgbnVtIDw9IGVuZFBhZ2U7IG51bSsrKSB7XHJcbiAgICAgIGNvbnN0IHBhZ2UgPSB0aGlzLm1ha2VQYWdlKG51bSwgbnVtLnRvU3RyaW5nKCksIG51bSA9PT0gY3VycmVudFBhZ2UpO1xyXG4gICAgICBwYWdlcy5wdXNoKHBhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEFkZCBsaW5rcyB0byBtb3ZlIGJldHdlZW4gcGFnZSBzZXRzXHJcbiAgICBpZiAoaXNNYXhTaXplZCAmJiAhdGhpcy5yb3RhdGUpIHtcclxuICAgICAgaWYgKHN0YXJ0UGFnZSA+IDEpIHtcclxuICAgICAgICBjb25zdCBwcmV2aW91c1BhZ2VTZXQgPSB0aGlzLm1ha2VQYWdlKHN0YXJ0UGFnZSAtIDEsICcuLi4nLCBmYWxzZSk7XHJcbiAgICAgICAgcGFnZXMudW5zaGlmdChwcmV2aW91c1BhZ2VTZXQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoZW5kUGFnZSA8IHRvdGFsUGFnZXMpIHtcclxuICAgICAgICBjb25zdCBuZXh0UGFnZVNldCA9IHRoaXMubWFrZVBhZ2UoZW5kUGFnZSArIDEsICcuLi4nLCBmYWxzZSk7XHJcbiAgICAgICAgcGFnZXMucHVzaChuZXh0UGFnZVNldCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcGFnZXM7XHJcbiAgfVxyXG5cclxuICAvLyBiYXNlIGNsYXNzXHJcbiAgcHJvdGVjdGVkIGNhbGN1bGF0ZVRvdGFsUGFnZXMoKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IHRvdGFsUGFnZXMgPSB0aGlzLml0ZW1zUGVyUGFnZSA8IDFcclxuICAgICAgPyAxXHJcbiAgICAgIDogTWF0aC5jZWlsKHRoaXMudG90YWxJdGVtcyAvIHRoaXMuaXRlbXNQZXJQYWdlKTtcclxuICAgIHJldHVybiBNYXRoLm1heCh0b3RhbFBhZ2VzIHx8IDAsIDEpO1xyXG4gIH1cclxufVxyXG4iXX0=