UNPKG

@kushki/ng-suka

Version:

<p align="center"> <h1 align="center">Suka Components Angular</h1> <p align="center"> An Angular implementation of the Suka Design System </p> </p>

589 lines 46.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // tslint:disable: variable-name import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewEncapsulation, HostBinding, } from '@angular/core'; import buildPaginationArray from './pagination-utils'; import { Subject } from 'rxjs'; /** * The default page size if there is no page size and there are no provided page size options. * @type {?} */ var DEFAULT_PAGE_SIZE = 50; /** * Change event object that is emitted when the user selects a * different page size or navigates to another page. */ var /** * Change event object that is emitted when the user selects a * different page size or navigates to another page. */ PageEvent = /** @class */ (function () { function PageEvent() { } return PageEvent; }()); /** * Change event object that is emitted when the user selects a * different page size or navigates to another page. */ export { PageEvent }; if (false) { /** * The current page index. * @type {?} */ PageEvent.prototype.pageIndex; /** * Index of the page that was selected previously. * @type {?} */ PageEvent.prototype.previousPageIndex; /** * The current page size * @type {?} */ PageEvent.prototype.pageSize; /** * The current total number of items being paged * @type {?} */ PageEvent.prototype.length; } /** * Component to provide navigation between paged inforsukaion. Displays the size of the current * page, user-selectable options to change that size, what items are being shown, and * navigational button to go to the previous or next page. */ var Pagination = /** @class */ (function () { function Pagination(_changeDetectorRef) { this._changeDetectorRef = _changeDetectorRef; this.initialized = new Subject(); this.disabled = false; this.baseClass = true; this._pageIndex = 0; this._length = 0; this._pageSizeOptions = []; this._hidePageSize = false; this._showFirstLastButtons = false; /** * Event emitted when the pagination changes the page size or page index. */ this.page = new EventEmitter(); /** * Displayed pages array */ this._pagesArray = []; /** * Calculate the page range */ this.getRangeLabel = (/** * @param {?} page * @param {?} pageSize * @param {?} length * @return {?} */ function (page, pageSize, length) { if (length === 0 || pageSize === 0) { return "0 de " + length; } length = Math.max(length, 0); /** @type {?} */ var startIndex = page * pageSize; // If the start index exceeds the list length, do not try and fix the end index to the end. /** @type {?} */ var endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize; return startIndex + 1 + " \u2013 " + endIndex + " de " + length; }); } Object.defineProperty(Pagination.prototype, "pageIndex", { /** The zero-based page index of the displayed list of items. Defaulted to 0. */ get: /** * The zero-based page index of the displayed list of items. Defaulted to 0. * @return {?} */ function () { return this._pageIndex; }, set: /** * @param {?} value * @return {?} */ function (value) { this._pageIndex = Math.max(coerceNumberProperty(value), 0); this._changeDetectorRef.markForCheck(); }, enumerable: true, configurable: true }); Object.defineProperty(Pagination.prototype, "length", { /** The length of the total number of items that are being paginated. Defaulted to 0. */ get: /** * The length of the total number of items that are being paginated. Defaulted to 0. * @return {?} */ function () { return this._length; }, set: /** * @param {?} value * @return {?} */ function (value) { this._length = coerceNumberProperty(value); this._changeDetectorRef.markForCheck(); this._updateDisplayedPagesArray(); }, enumerable: true, configurable: true }); Object.defineProperty(Pagination.prototype, "pageSize", { /** Number of items to display on a page. By default set to 20. */ get: /** * Number of items to display on a page. By default set to 20. * @return {?} */ function () { return this._pageSize; }, set: /** * @param {?} value * @return {?} */ function (value) { this._pageSize = Math.max(coerceNumberProperty(value), 0); this._updateDisplayedPageSizeOptions(); this._updateDisplayedPagesArray(); }, enumerable: true, configurable: true }); Object.defineProperty(Pagination.prototype, "pageSizeOptions", { /** The set of provided page size options to display to the user. */ get: /** * The set of provided page size options to display to the user. * @return {?} */ function () { return this._pageSizeOptions; }, set: /** * @param {?} value * @return {?} */ function (value) { this._pageSizeOptions = (value || []).map((/** * @param {?} p * @return {?} */ function (p) { return coerceNumberProperty(p); })); this._updateDisplayedPageSizeOptions(); }, enumerable: true, configurable: true }); Object.defineProperty(Pagination.prototype, "hidePageSize", { /** Whether to hide the page size selection UI from the user. */ get: /** * Whether to hide the page size selection UI from the user. * @return {?} */ function () { return this._hidePageSize; }, set: /** * @param {?} value * @return {?} */ function (value) { this._hidePageSize = coerceBooleanProperty(value); }, enumerable: true, configurable: true }); Object.defineProperty(Pagination.prototype, "showFirstLastButtons", { /** Whether to show the first/last buttons UI to the user. */ get: /** * Whether to show the first/last buttons UI to the user. * @return {?} */ function () { return this._showFirstLastButtons; }, set: /** * @param {?} value * @return {?} */ function (value) { this._showFirstLastButtons = coerceBooleanProperty(value); }, enumerable: true, configurable: true }); /** * @return {?} */ Pagination.prototype.ngOnInit = /** * @return {?} */ function () { this._initialized = true; this.initialized.next(true); this._updateDisplayedPageSizeOptions(); }; /** Advances to the next page if it exists. */ /** * Advances to the next page if it exists. * @return {?} */ Pagination.prototype.nextPage = /** * Advances to the next page if it exists. * @return {?} */ function () { if (!this.hasNextPage()) { return; } /** @type {?} */ var previousPageIndex = this.pageIndex; this.pageIndex++; this._updateDisplayedPagesArray(); this._emitPageEvent(previousPageIndex); }; /** Move back to the previous page if it exists. */ /** * Move back to the previous page if it exists. * @return {?} */ Pagination.prototype.previousPage = /** * Move back to the previous page if it exists. * @return {?} */ function () { if (!this.hasPreviousPage()) { return; } /** @type {?} */ var previousPageIndex = this.pageIndex; this.pageIndex--; this._updateDisplayedPagesArray(); this._emitPageEvent(previousPageIndex); }; /** Move to the first page if not already there. */ /** * Move to the first page if not already there. * @return {?} */ Pagination.prototype.firstPage = /** * Move to the first page if not already there. * @return {?} */ function () { // hasPreviousPage being false implies at the start if (!this.hasPreviousPage()) { return; } /** @type {?} */ var previousPageIndex = this.pageIndex; this.pageIndex = 0; this._updateDisplayedPagesArray(); this._emitPageEvent(previousPageIndex); }; /** Move to the last page if not already there. */ /** * Move to the last page if not already there. * @return {?} */ Pagination.prototype.lastPage = /** * Move to the last page if not already there. * @return {?} */ function () { // hasNextPage being false implies at the end if (!this.hasNextPage()) { return; } /** @type {?} */ var previousPageIndex = this.pageIndex; this.pageIndex = this.getNumberOfPages() - 1; this._updateDisplayedPagesArray(); this._emitPageEvent(previousPageIndex); }; /** * @param {?} page * @return {?} */ Pagination.prototype.goToPage = /** * @param {?} page * @return {?} */ function (page) { /** @type {?} */ var previousPageIndex = this.pageIndex; this.pageIndex = page - 1; this._updateDisplayedPagesArray(); this._emitPageEvent(previousPageIndex); }; /** Whether there is a previous page. */ /** * Whether there is a previous page. * @return {?} */ Pagination.prototype.hasPreviousPage = /** * Whether there is a previous page. * @return {?} */ function () { return this.pageIndex >= 1 && this.pageSize !== 0; }; /** Whether there is a next page. */ /** * Whether there is a next page. * @return {?} */ Pagination.prototype.hasNextPage = /** * Whether there is a next page. * @return {?} */ function () { /** @type {?} */ var maxPageIndex = this.getNumberOfPages() - 1; return this.pageIndex < maxPageIndex && this.pageSize !== 0; }; /** Calculate the number of pages */ /** * Calculate the number of pages * @return {?} */ Pagination.prototype.getNumberOfPages = /** * Calculate the number of pages * @return {?} */ function () { if (!this.pageSize) { return 0; } return Math.ceil(this.length / this.pageSize); }; /** * Changes the page size so that the first item displayed on the page will still be * displayed using the new page size. * * For example, if the page size is 10 and on the second page (items indexed 10-19) then * switching so that the page size is 5 will set the third page as the current page so * that the 10th item will still be displayed. */ /** * Changes the page size so that the first item displayed on the page will still be * displayed using the new page size. * * For example, if the page size is 10 and on the second page (items indexed 10-19) then * switching so that the page size is 5 will set the third page as the current page so * that the 10th item will still be displayed. * @param {?} pageSize * @return {?} */ Pagination.prototype._changePageSize = /** * Changes the page size so that the first item displayed on the page will still be * displayed using the new page size. * * For example, if the page size is 10 and on the second page (items indexed 10-19) then * switching so that the page size is 5 will set the third page as the current page so * that the 10th item will still be displayed. * @param {?} pageSize * @return {?} */ function (pageSize) { // Current page needs to be updated to reflect the new page size. Navigate to the page // containing the previous page's first item. /** @type {?} */ var startIndex = this.pageIndex * this.pageSize; /** @type {?} */ var previousPageIndex = this.pageIndex; this.pageIndex = Math.floor(startIndex / pageSize) || 0; this.pageSize = pageSize; this._emitPageEvent(previousPageIndex); }; /** Checks whether the buttons for going forwards should be disabled. */ /** * Checks whether the buttons for going forwards should be disabled. * @return {?} */ Pagination.prototype._nextButtonsDisabled = /** * Checks whether the buttons for going forwards should be disabled. * @return {?} */ function () { return this.disabled || !this.hasNextPage(); }; /** Checks whether the buttons for going backwards should be disabled. */ /** * Checks whether the buttons for going backwards should be disabled. * @return {?} */ Pagination.prototype._previousButtonsDisabled = /** * Checks whether the buttons for going backwards should be disabled. * @return {?} */ function () { return this.disabled || !this.hasPreviousPage(); }; /** * Updates the list of page size options to display to the user. Includes making sure that * the page size is an option and that the list is sorted. */ /** * Updates the list of page size options to display to the user. Includes making sure that * the page size is an option and that the list is sorted. * @private * @return {?} */ Pagination.prototype._updateDisplayedPageSizeOptions = /** * Updates the list of page size options to display to the user. Includes making sure that * the page size is an option and that the list is sorted. * @private * @return {?} */ function () { if (!this._initialized) { return; } // If no page size is provided, use the first page size option or the default page size. if (!this.pageSize) { this._pageSize = this.pageSizeOptions.length !== 0 ? this.pageSizeOptions[0] : DEFAULT_PAGE_SIZE; } this._displayedPageSizeOptions = this.pageSizeOptions.slice(); if (this._displayedPageSizeOptions.indexOf(this.pageSize) === -1) { this._displayedPageSizeOptions.push(this.pageSize); } // Sort the numbers using a number-specific sort function. this._displayedPageSizeOptions.sort((/** * @param {?} a * @param {?} b * @return {?} */ function (a, b) { return a - b; })); this._changeDetectorRef.markForCheck(); }; /** * @private * @return {?} */ Pagination.prototype._updateDisplayedPagesArray = /** * @private * @return {?} */ function () { this._pagesArray = buildPaginationArray(this.getNumberOfPages(), this.pageIndex + 1, 3); }; /** Emits an event notifying that a change of the pagination's properties has been triggered. */ /** * Emits an event notifying that a change of the pagination's properties has been triggered. * @private * @param {?} previousPageIndex * @return {?} */ Pagination.prototype._emitPageEvent = /** * Emits an event notifying that a change of the pagination's properties has been triggered. * @private * @param {?} previousPageIndex * @return {?} */ function (previousPageIndex) { this.page.emit({ previousPageIndex: previousPageIndex, pageIndex: this.pageIndex, pageSize: this.pageSize, length: this.length }); }; Pagination.decorators = [ { type: Component, args: [{ selector: 'suka-pagination', exportAs: 'sukaPagination', template: "\n <div class=\"suka-pagination-outer-container\">\n <div class=\"suka-pagination-container\">\n <div class=\"suka-pagination-results\">\n Mostrando <span class=\"suka-pagination-result\">{{getRangeLabel(pageIndex, pageSize, length)}}</span>\n </div>\n\n <div class=\"suka-pagination-actions\">\n <button\n type=\"button\" class=\"suka-pagination-navigation-first\"\n (click)=\"firstPage()\"\n [disabled]=\"_previousButtonsDisabled()\"\n *ngIf=\"showFirstLastButtons\"\n sukaButton=\"plain\"\n size=\"sm\"\n >\n <suka-icon icon=\"chevrons-left\" class=\"suka-pagination-icon\"></suka-icon>\n </button>\n <button\n type=\"button\" class=\"suka-pagination-navigation-previous\"\n (click)=\"previousPage()\"\n [disabled]=\"_previousButtonsDisabled()\"\n sukaButton=\"plain\"\n size=\"sm\"\n >\n <suka-icon icon=\"chevron-left\" class=\"suka-pagination-icon\"></suka-icon>\n Anterior\n </button>\n <button\n *ngFor=\"let pageNumber of _pagesArray\"\n type=\"button\"\n class=\"suka-pagination-navigation-page\"\n (click)=\"goToPage(pageNumber)\"\n [disabled]=\"pageNumber === '...'\"\n sukaButton=\"plain\"\n size=\"sm\"\n [ngClass]=\"{\n 'suka-pagination-navigation-page--selected': pageNumber === pageIndex + 1\n }\"\n >\n {{pageNumber}}\n </button>\n <button\n type=\"button\"\n class=\"suka-pagination-navigation-next\"\n (click)=\"nextPage()\"\n [disabled]=\"_nextButtonsDisabled()\"\n sukaButton=\"plain\"\n size=\"sm\"\n >\n Siguiente\n <suka-icon icon=\"chevron-right\" class=\"suka-pagination-icon\"></suka-icon>\n </button>\n <button\n type=\"button\" class=\"suka-pagination-navigation-last\"\n (click)=\"lastPage()\"\n [disabled]=\"_nextButtonsDisabled()\"\n *ngIf=\"showFirstLastButtons\"\n sukaButton=\"plain\"\n size=\"sm\"\n >\n <suka-icon icon=\"chevrons-right\" class=\"suka-pagination-icon\"></suka-icon>\n </button>\n </div>\n </div>\n </div>\n\n ", changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }] } ]; /** @nocollapse */ Pagination.ctorParameters = function () { return [ { type: ChangeDetectorRef } ]; }; Pagination.propDecorators = { disabled: [{ type: Input }], baseClass: [{ type: HostBinding, args: ['class.suka-pagination',] }], pageIndex: [{ type: Input }], length: [{ type: Input }], pageSize: [{ type: Input }], pageSizeOptions: [{ type: Input }], hidePageSize: [{ type: Input }], showFirstLastButtons: [{ type: Input }], page: [{ type: Output }] }; return Pagination; }()); export { Pagination }; if (false) { /** * @type {?} * @private */ Pagination.prototype._initialized; /** @type {?} */ Pagination.prototype.initialized; /** @type {?} */ Pagination.prototype.disabled; /** @type {?} */ Pagination.prototype.baseClass; /** * @type {?} * @private */ Pagination.prototype._pageIndex; /** * @type {?} * @private */ Pagination.prototype._length; /** * @type {?} * @private */ Pagination.prototype._pageSize; /** * @type {?} * @private */ Pagination.prototype._pageSizeOptions; /** * @type {?} * @private */ Pagination.prototype._hidePageSize; /** * @type {?} * @private */ Pagination.prototype._showFirstLastButtons; /** * Event emitted when the pagination changes the page size or page index. * @type {?} */ Pagination.prototype.page; /** * Displayed set of page size options. Will be sorted and include current page size. * @type {?} */ Pagination.prototype._displayedPageSizeOptions; /** * Displayed pages array * @type {?} */ Pagination.prototype._pagesArray; /** * Calculate the page range * @type {?} */ Pagination.prototype.getRangeLabel; /** * @type {?} * @private */ Pagination.prototype._changeDetectorRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Aa3VzaGtpL25nLXN1a2EvIiwic291cmNlcyI6WyJsaWIvcGFnaW5hdGlvbi9wYWdpbmF0aW9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3BGLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixpQkFBaUIsRUFDakIsV0FBVyxHQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sb0JBQW9CLE1BQU0sb0JBQW9CLENBQUM7QUFDdEQsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7SUFHckMsaUJBQWlCLEdBQUcsRUFBRTs7Ozs7QUFNNUI7Ozs7O0lBQUE7SUFjQSxDQUFDO0lBQUQsZ0JBQUM7QUFBRCxDQUFDLEFBZEQsSUFjQzs7Ozs7Ozs7Ozs7SUFaQyw4QkFBa0I7Ozs7O0lBS2xCLHNDQUEwQjs7Ozs7SUFHMUIsNkJBQWlCOzs7OztJQUdqQiwyQkFBZTs7Ozs7OztBQVNqQjtJQWtKRSxvQkFBb0Isa0JBQXFDO1FBQXJDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBbUI7UUF0RXpELGdCQUFXLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUVuQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ1ksY0FBUyxHQUFHLElBQUksQ0FBQztRQVUvQyxlQUFVLEdBQUcsQ0FBQyxDQUFDO1FBVWYsWUFBTyxHQUFHLENBQUMsQ0FBQztRQW1CWixxQkFBZ0IsR0FBYSxFQUFFLENBQUM7UUFRaEMsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFTdEIsMEJBQXFCLEdBQUcsS0FBSyxDQUFDOzs7O1FBR25CLFNBQUksR0FBNEIsSUFBSSxZQUFZLEVBQWEsQ0FBQzs7OztRQU1qRixnQkFBVyxHQUFHLEVBQUUsQ0FBQzs7OztRQWlGakIsa0JBQWE7Ozs7OztRQUFHLFVBQUMsSUFBWSxFQUFFLFFBQWdCLEVBQUUsTUFBYztZQUM3RCxJQUFJLE1BQU0sS0FBSyxDQUFDLElBQUksUUFBUSxLQUFLLENBQUMsRUFBRTtnQkFBRSxPQUFPLFVBQVEsTUFBUSxDQUFDO2FBQUU7WUFFaEUsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDOztnQkFFdkIsVUFBVSxHQUFHLElBQUksR0FBRyxRQUFROzs7Z0JBRzVCLFFBQVEsR0FBRyxVQUFVLEdBQUcsTUFBTSxDQUFDLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxVQUFVLEdBQUcsUUFBUTtZQUV2QixPQUFVLFVBQVUsR0FBRyxDQUFDLGdCQUFNLFFBQVEsWUFBTyxNQUFRLENBQUM7UUFDeEQsQ0FBQyxFQUFBO0lBNUY0RCxDQUFDO0lBaEU5RCxzQkFDSSxpQ0FBUztRQUZiLGdGQUFnRjs7Ozs7UUFDaEYsY0FDMEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQzs7Ozs7UUFDbkQsVUFBYyxLQUFhO1lBQ3pCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMzRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDekMsQ0FBQzs7O09BSmtEO0lBU25ELHNCQUNJLDhCQUFNO1FBRlYsd0ZBQXdGOzs7OztRQUN4RixjQUN1QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDOzs7OztRQUM3QyxVQUFXLEtBQWE7WUFDdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdkMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDcEMsQ0FBQzs7O09BTDRDO0lBUzdDLHNCQUNJLGdDQUFRO1FBRlosa0VBQWtFOzs7OztRQUNsRSxjQUN5QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDOzs7OztRQUNqRCxVQUFhLEtBQWE7WUFDeEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQywrQkFBK0IsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ3BDLENBQUM7OztPQUxnRDtJQVNqRCxzQkFDSSx1Q0FBZTtRQUZuQixvRUFBb0U7Ozs7O1FBQ3BFLGNBQ2tDLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQzs7Ozs7UUFDakUsVUFBb0IsS0FBZTtZQUNqQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRzs7OztZQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEVBQXZCLENBQXVCLEVBQUMsQ0FBQztZQUN4RSxJQUFJLENBQUMsK0JBQStCLEVBQUUsQ0FBQztRQUN6QyxDQUFDOzs7T0FKZ0U7SUFRakUsc0JBQ0ksb0NBQVk7UUFGaEIsZ0VBQWdFOzs7OztRQUNoRSxjQUM4QixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDOzs7OztRQUMxRCxVQUFpQixLQUFjO1lBQzdCLElBQUksQ0FBQyxhQUFhLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEQsQ0FBQzs7O09BSHlEO0lBUTFELHNCQUNJLDRDQUFvQjtRQUZ4Qiw2REFBNkQ7Ozs7O1FBQzdELGNBQ3NDLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQzs7Ozs7UUFDMUUsVUFBeUIsS0FBYztZQUNyQyxJQUFJLENBQUMscUJBQXFCLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUQsQ0FBQzs7O09BSHlFOzs7O0lBaUIxRSw2QkFBUTs7O0lBQVI7UUFDRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsK0JBQStCLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRUQsOENBQThDOzs7OztJQUM5Qyw2QkFBUTs7OztJQUFSO1FBQ0UsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUFFLE9BQU87U0FBRTs7WUFFOUIsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVM7UUFDeEMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsbURBQW1EOzs7OztJQUNuRCxpQ0FBWTs7OztJQUFaO1FBQ0UsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRTtZQUFFLE9BQU87U0FBRTs7WUFFbEMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVM7UUFDeEMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsbURBQW1EOzs7OztJQUNuRCw4QkFBUzs7OztJQUFUO1FBQ0UsbURBQW1EO1FBQ25ELElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFBRSxPQUFPO1NBQUU7O1lBRWxDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxTQUFTO1FBQ3hDLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsa0RBQWtEOzs7OztJQUNsRCw2QkFBUTs7OztJQUFSO1FBQ0UsNkNBQTZDO1FBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFBRSxPQUFPO1NBQUU7O1lBRTlCLGlCQUFpQixHQUFHLElBQUksQ0FBQyxTQUFTO1FBQ3hDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN6QyxDQUFDOzs7OztJQUVELDZCQUFROzs7O0lBQVIsVUFBUyxJQUFZOztZQUNiLGlCQUFpQixHQUFHLElBQUksQ0FBQyxTQUFTO1FBRXhDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVELHdDQUF3Qzs7Ozs7SUFDeEMsb0NBQWU7Ozs7SUFBZjtRQUNFLE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELG9DQUFvQzs7Ozs7SUFDcEMsZ0NBQVc7Ozs7SUFBWDs7WUFDUSxZQUFZLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsQ0FBQztRQUNoRCxPQUFPLElBQUksQ0FBQyxTQUFTLEdBQUcsWUFBWSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRCxvQ0FBb0M7Ozs7O0lBQ3BDLHFDQUFnQjs7OztJQUFoQjtRQUNFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2xCLE9BQU8sQ0FBQyxDQUFDO1NBQ1Y7UUFFRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQW1CRDs7Ozs7OztPQU9HOzs7Ozs7Ozs7OztJQUNILG9DQUFlOzs7Ozs7Ozs7O0lBQWYsVUFBZ0IsUUFBZ0I7Ozs7WUFHeEIsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVE7O1lBQzNDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxTQUFTO1FBRXhDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsd0VBQXdFOzs7OztJQUN4RSx5Q0FBb0I7Ozs7SUFBcEI7UUFDRSxPQUFPLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVELHlFQUF5RTs7Ozs7SUFDekUsNkNBQXdCOzs7O0lBQXhCO1FBQ0UsT0FBTyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ2xELENBQUM7SUFFRDs7O09BR0c7Ozs7Ozs7SUFDSyxvREFBK0I7Ozs7OztJQUF2QztRQUNFLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQUUsT0FBTztTQUFFO1FBRW5DLHdGQUF3RjtRQUN4RixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNsQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNsRCxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pCLGlCQUFpQixDQUFDO1NBQ3JCO1FBRUQsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFOUQsSUFBSSxJQUFJLENBQUMseUJBQXlCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUNoRSxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUNwRDtRQUVELDBEQUEwRDtRQUMxRCxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSTs7Ozs7UUFBQyxVQUFDLENBQUMsRUFBRSxDQUFDLElBQUssT0FBQSxDQUFDLEdBQUcsQ0FBQyxFQUFMLENBQUssRUFBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN6QyxDQUFDOzs7OztJQUVPLCtDQUEwQjs7OztJQUFsQztRQUNFLElBQUksQ0FBQyxXQUFXLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUYsQ0FBQztJQUVELGdHQUFnRzs7Ozs7OztJQUN4RixtQ0FBYzs7Ozs7O0lBQXRCLFVBQXVCLGlCQUF5QjtRQUM5QyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNiLGlCQUFpQixtQkFBQTtZQUNqQixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ3ZCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtTQUNwQixDQUFDLENBQUM7SUFDTCxDQUFDOztnQkFuVEYsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxpQkFBaUI7b0JBQzNCLFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFFBQVEsRUFBRSxnOEVBbUVUO29CQUNELGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsSUFBSTtpQkFDdEM7Ozs7Z0JBbEhDLGlCQUFpQjs7OzJCQXVIaEIsS0FBSzs0QkFDTCxXQUFXLFNBQUMsdUJBQXVCOzRCQUduQyxLQUFLO3lCQVVMLEtBQUs7MkJBVUwsS0FBSztrQ0FVTCxLQUFLOytCQVNMLEtBQUs7dUNBU0wsS0FBSzt1QkFRTCxNQUFNOztJQTBLVCxpQkFBQztDQUFBLEFBcFRELElBb1RDO1NBMU9ZLFVBQVU7Ozs7OztJQUNyQixrQ0FBOEI7O0lBQzlCLGlDQUE0Qjs7SUFFNUIsOEJBQTBCOztJQUMxQiwrQkFBdUQ7Ozs7O0lBVXZELGdDQUF1Qjs7Ozs7SUFVdkIsNkJBQW9COzs7OztJQVVwQiwrQkFBMEI7Ozs7O0lBUzFCLHNDQUF3Qzs7Ozs7SUFReEMsbUNBQThCOzs7OztJQVM5QiwyQ0FBc0M7Ozs7O0lBR3RDLDBCQUFpRjs7Ozs7SUFHakYsK0NBQW9DOzs7OztJQUdwQyxpQ0FBaUI7Ozs7O0lBaUZqQixtQ0FhQzs7Ozs7SUE1Rlcsd0NBQTZDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHNsaW50OmRpc2FibGU6IHZhcmlhYmxlLW5hbWVcblxuaW1wb3J0IHsgY29lcmNlTnVtYmVyUHJvcGVydHksIGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBIb3N0QmluZGluZyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgYnVpbGRQYWdpbmF0aW9uQXJyYXkgZnJvbSAnLi9wYWdpbmF0aW9uLXV0aWxzJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuLyoqIFRoZSBkZWZhdWx0IHBhZ2Ugc2l6ZSBpZiB0aGVyZSBpcyBubyBwYWdlIHNpemUgYW5kIHRoZXJlIGFyZSBubyBwcm92aWRlZCBwYWdlIHNpemUgb3B0aW9ucy4gKi9cbmNvbnN0IERFRkFVTFRfUEFHRV9TSVpFID0gNTA7XG5cbi8qKlxuICogQ2hhbmdlIGV2ZW50IG9iamVjdCB0aGF0IGlzIGVtaXR0ZWQgd2hlbiB0aGUgdXNlciBzZWxlY3RzIGFcbiAqIGRpZmZlcmVudCBwYWdlIHNpemUgb3IgbmF2aWdhdGVzIHRvIGFub3RoZXIgcGFnZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFBhZ2VFdmVudCB7XG4gIC8qKiBUaGUgY3VycmVudCBwYWdlIGluZGV4LiAqL1xuICBwYWdlSW5kZXg6IG51bWJlcjtcblxuICAvKipcbiAgICogSW5kZXggb2YgdGhlIHBhZ2UgdGhhdCB3YXMgc2VsZWN0ZWQgcHJldmlvdXNseS5cbiAgICovXG4gIHByZXZpb3VzUGFnZUluZGV4OiBudW1iZXI7XG5cbiAgLyoqIFRoZSBjdXJyZW50IHBhZ2Ugc2l6ZSAqL1xuICBwYWdlU2l6ZTogbnVtYmVyO1xuXG4gIC8qKiBUaGUgY3VycmVudCB0b3RhbCBudW1iZXIgb2YgaXRlbXMgYmVpbmcgcGFnZWQgKi9cbiAgbGVuZ3RoOiBudW1iZXI7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgdG8gcHJvdmlkZSBuYXZpZ2F0aW9uIGJldHdlZW4gcGFnZWQgaW5mb3JzdWthaW9uLiBEaXNwbGF5cyB0aGUgc2l6ZSBvZiB0aGUgY3VycmVudFxuICogcGFnZSwgdXNlci1zZWxlY3RhYmxlIG9wdGlvbnMgdG8gY2hhbmdlIHRoYXQgc2l6ZSwgd2hhdCBpdGVtcyBhcmUgYmVpbmcgc2hvd24sIGFuZFxuICogbmF2aWdhdGlvbmFsIGJ1dHRvbiB0byBnbyB0byB0aGUgcHJldmlvdXMgb3IgbmV4dCBwYWdlLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzdWthLXBhZ2luYXRpb24nLFxuICBleHBvcnRBczogJ3N1a2FQYWdpbmF0aW9uJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwic3VrYS1wYWdpbmF0aW9uLW91dGVyLWNvbnRhaW5lclwiPlxuICAgICAgPGRpdiBjbGFzcz1cInN1a2EtcGFnaW5hdGlvbi1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInN1a2EtcGFnaW5hdGlvbi1yZXN1bHRzXCI+XG4gICAgICAgICAgTW9zdHJhbmRvIDxzcGFuIGNsYXNzPVwic3VrYS1wYWdpbmF0aW9uLXJlc3VsdFwiPnt7Z2V0UmFuZ2VMYWJlbChwYWdlSW5kZXgsIHBhZ2VTaXplLCBsZW5ndGgpfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzdWthLXBhZ2luYXRpb24tYWN0aW9uc1wiPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInN1a2EtcGFnaW5hdGlvbi1uYXZpZ2F0aW9uLWZpcnN0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJmaXJzdFBhZ2UoKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiX3ByZXZpb3VzQnV0dG9uc0Rpc2FibGVkKClcIlxuICAgICAgICAgICAgKm5nSWY9XCJzaG93Rmlyc3RMYXN0QnV0dG9uc1wiXG4gICAgICAgICAgICBzdWthQnV0dG9uPVwicGxhaW5cIlxuICAgICAgICAgICAgc2l6ZT1cInNtXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3VrYS1pY29uIGljb249XCJjaGV2cm9ucy1sZWZ0XCIgY2xhc3M9XCJzdWthLXBhZ2luYXRpb24taWNvblwiPjwvc3VrYS1pY29uPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInN1a2EtcGFnaW5hdGlvbi1uYXZpZ2F0aW9uLXByZXZpb3VzXCJcbiAgICAgICAgICAgIChjbGljayk9XCJwcmV2aW91c1BhZ2UoKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiX3ByZXZpb3VzQnV0dG9uc0Rpc2FibGVkKClcIlxuICAgICAgICAgICAgc3VrYUJ1dHRvbj1cInBsYWluXCJcbiAgICAgICAgICAgIHNpemU9XCJzbVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHN1a2EtaWNvbiBpY29uPVwiY2hldnJvbi1sZWZ0XCIgY2xhc3M9XCJzdWthLXBhZ2luYXRpb24taWNvblwiPjwvc3VrYS1pY29uPlxuICAgICAgICAgICAgQW50ZXJpb3JcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgcGFnZU51bWJlciBvZiBfcGFnZXNBcnJheVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwic3VrYS1wYWdpbmF0aW9uLW5hdmlnYXRpb24tcGFnZVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZ29Ub1BhZ2UocGFnZU51bWJlcilcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cInBhZ2VOdW1iZXIgPT09ICcuLi4nXCJcbiAgICAgICAgICAgIHN1a2FCdXR0b249XCJwbGFpblwiXG4gICAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAnc3VrYS1wYWdpbmF0aW9uLW5hdmlnYXRpb24tcGFnZS0tc2VsZWN0ZWQnOiBwYWdlTnVtYmVyID09PSBwYWdlSW5kZXggKyAxXG4gICAgICAgICAgICB9XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7e3BhZ2VOdW1iZXJ9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJzdWthLXBhZ2luYXRpb24tbmF2aWdhdGlvbi1uZXh0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJuZXh0UGFnZSgpXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJfbmV4dEJ1dHRvbnNEaXNhYmxlZCgpXCJcbiAgICAgICAgICAgIHN1a2FCdXR0b249XCJwbGFpblwiXG4gICAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIFNpZ3VpZW50ZVxuICAgICAgICAgICAgPHN1a2EtaWNvbiBpY29uPVwiY2hldnJvbi1yaWdodFwiIGNsYXNzPVwic3VrYS1wYWdpbmF0aW9uLWljb25cIj48L3N1a2EtaWNvbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzdWthLXBhZ2luYXRpb24tbmF2aWdhdGlvbi1sYXN0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJsYXN0UGFnZSgpXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJfbmV4dEJ1dHRvbnNEaXNhYmxlZCgpXCJcbiAgICAgICAgICAgICpuZ0lmPVwic2hvd0ZpcnN0TGFzdEJ1dHRvbnNcIlxuICAgICAgICAgICAgc3VrYUJ1dHRvbj1cInBsYWluXCJcbiAgICAgICAgICAgIHNpemU9XCJzbVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHN1a2EtaWNvbiBpY29uPVwiY2hldnJvbnMtcmlnaHRcIiBjbGFzcz1cInN1a2EtcGFnaW5hdGlvbi1pY29uXCI+PC9zdWthLWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgYCxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIFBhZ2luYXRpb24gaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIF9pbml0aWFsaXplZDogYm9vbGVhbjtcbiAgaW5pdGlhbGl6ZWQgPSBuZXcgU3ViamVjdCgpO1xuXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIEBIb3N0QmluZGluZygnY2xhc3Muc3VrYS1wYWdpbmF0aW9uJykgYmFzZUNsYXNzID0gdHJ1ZTtcblxuICAvKiogVGhlIHplcm8tYmFzZWQgcGFnZSBpbmRleCBvZiB0aGUgZGlzcGxheWVkIGxpc3Qgb2YgaXRlbXMuIERlZmF1bHRlZCB0byAwLiAqL1xuICBASW5wdXQoKVxuICBnZXQgcGFnZUluZGV4KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9wYWdlSW5kZXg7IH1cbiAgc2V0IHBhZ2VJbmRleCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5fcGFnZUluZGV4ID0gTWF0aC5tYXgoY29lcmNlTnVtYmVyUHJvcGVydHkodmFsdWUpLCAwKTtcbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhZ2VJbmRleCA9IDA7XG5cbiAgLyoqIFRoZSBsZW5ndGggb2YgdGhlIHRvdGFsIG51bWJlciBvZiBpdGVtcyB0aGF0IGFyZSBiZWluZyBwYWdpbmF0ZWQuIERlZmF1bHRlZCB0byAwLiAqL1xuICBASW5wdXQoKVxuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9sZW5ndGg7IH1cbiAgc2V0IGxlbmd0aCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5fbGVuZ3RoID0gY29lcmNlTnVtYmVyUHJvcGVydHkodmFsdWUpO1xuICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgIHRoaXMuX3VwZGF0ZURpc3BsYXllZFBhZ2VzQXJyYXkoKTtcbiAgfVxuICBwcml2YXRlIF9sZW5ndGggPSAwO1xuXG4gIC8qKiBOdW1iZXIgb2YgaXRlbXMgdG8gZGlzcGxheSBvbiBhIHBhZ2UuIEJ5IGRlZmF1bHQgc2V0IHRvIDIwLiAqL1xuICBASW5wdXQoKVxuICBnZXQgcGFnZVNpemUoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3BhZ2VTaXplOyB9XG4gIHNldCBwYWdlU2l6ZSh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5fcGFnZVNpemUgPSBNYXRoLm1heChjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2YWx1ZSksIDApO1xuICAgIHRoaXMuX3VwZGF0ZURpc3BsYXllZFBhZ2VTaXplT3B0aW9ucygpO1xuICAgIHRoaXMuX3VwZGF0ZURpc3BsYXllZFBhZ2VzQXJyYXkoKTtcbiAgfVxuICBwcml2YXRlIF9wYWdlU2l6ZTogbnVtYmVyO1xuXG4gIC8qKiBUaGUgc2V0IG9mIHByb3ZpZGVkIHBhZ2Ugc2l6ZSBvcHRpb25zIHRvIGRpc3BsYXkgdG8gdGhlIHVzZXIuICovXG4gIEBJbnB1dCgpXG4gIGdldCBwYWdlU2l6ZU9wdGlvbnMoKTogbnVtYmVyW10geyByZXR1cm4gdGhpcy5fcGFnZVNpemVPcHRpb25zOyB9XG4gIHNldCBwYWdlU2l6ZU9wdGlvbnModmFsdWU6IG51bWJlcltdKSB7XG4gICAgdGhpcy5fcGFnZVNpemVPcHRpb25zID0gKHZhbHVlIHx8IFtdKS5tYXAocCA9PiBjb2VyY2VOdW1iZXJQcm9wZXJ0eShwKSk7XG4gICAgdGhpcy5fdXBkYXRlRGlzcGxheWVkUGFnZVNpemVPcHRpb25zKCk7XG4gIH1cbiAgcHJpdmF0ZSBfcGFnZVNpemVPcHRpb25zOiBudW1iZXJbXSA9IFtdO1xuXG4gIC8qKiBXaGV0aGVyIHRvIGhpZGUgdGhlIHBhZ2Ugc2l6ZSBzZWxlY3Rpb24gVUkgZnJvbSB0aGUgdXNlci4gKi9cbiAgQElucHV0KClcbiAgZ2V0IGhpZGVQYWdlU2l6ZSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuX2hpZGVQYWdlU2l6ZTsgfVxuICBzZXQgaGlkZVBhZ2VTaXplKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5faGlkZVBhZ2VTaXplID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBwcml2YXRlIF9oaWRlUGFnZVNpemUgPSBmYWxzZTtcblxuXG4gIC8qKiBXaGV0aGVyIHRvIHNob3cgdGhlIGZpcnN0L2xhc3QgYnV0dG9ucyBVSSB0byB0aGUgdXNlci4gKi9cbiAgQElucHV0KClcbiAgZ2V0IHNob3dGaXJzdExhc3RCdXR0b25zKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fc2hvd0ZpcnN0TGFzdEJ1dHRvbnM7IH1cbiAgc2V0IHNob3dGaXJzdExhc3RCdXR0b25zKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fc2hvd0ZpcnN0TGFzdEJ1dHRvbnMgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICB9XG4gIHByaXZhdGUgX3Nob3dGaXJzdExhc3RCdXR0b25zID0gZmFsc2U7XG5cbiAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgcGFnaW5hdGlvbiBjaGFuZ2VzIHRoZSBwYWdlIHNpemUgb3IgcGFnZSBpbmRleC4gKi9cbiAgQE91dHB1dCgpIHJlYWRvbmx5IHBhZ2U6IEV2ZW50RW1pdHRlcjxQYWdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxQYWdlRXZlbnQ+KCk7XG5cbiAgLyoqIERpc3BsYXllZCBzZXQgb2YgcGFnZSBzaXplIG9wdGlvbnMuIFdpbGwgYmUgc29ydGVkIGFuZCBpbmNsdWRlIGN1cnJlbnQgcGFnZSBzaXplLiAqL1xuICBfZGlzcGxheWVkUGFnZVNpemVPcHRpb25zOiBudW1iZXJbXTtcblxuICAvKiogRGlzcGxheWVkIHBhZ2VzIGFycmF5ICovXG4gIF9wYWdlc0FycmF5ID0gW107XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7IH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG4gICAgdGhpcy5pbml0aWFsaXplZC5uZXh0KHRydWUpO1xuICAgIHRoaXMuX3VwZGF0ZURpc3BsYXllZFBhZ2VTaXplT3B0aW9ucygpO1xuICB9XG5cbiAgLyoqIEFkdmFuY2VzIHRvIHRoZSBuZXh0IHBhZ2UgaWYgaXQgZXhpc3RzLiAqL1xuICBuZXh0UGFnZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaGFzTmV4dFBhZ2UoKSkgeyByZXR1cm47IH1cblxuICAgIGNvbnN0IHByZXZpb3VzUGFnZUluZGV4ID0gdGhpcy5wYWdlSW5kZXg7XG4gICAgdGhpcy5wYWdlSW5kZXgrKztcbiAgICB0aGlzLl91cGRhdGVEaXNwbGF5ZWRQYWdlc0FycmF5KCk7XG4gICAgdGhpcy5fZW1pdFBhZ2VFdmVudChwcmV2aW91c1BhZ2VJbmRleCk7XG4gIH1cblxuICAvKiogTW92ZSBiYWNrIHRvIHRoZSBwcmV2aW91cyBwYWdlIGlmIGl0IGV4aXN0cy4gKi9cbiAgcHJldmlvdXNQYWdlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5oYXNQcmV2aW91c1BhZ2UoKSkgeyByZXR1cm47IH1cblxuICAgIGNvbnN0IHByZXZpb3VzUGFnZUluZGV4ID0gdGhpcy5wYWdlSW5kZXg7XG4gICAgdGhpcy5wYWdlSW5kZXgtLTtcbiAgICB0aGlzLl91cGRhdGVEaXNwbGF5ZWRQYWdlc0FycmF5KCk7XG4gICAgdGhpcy5fZW1pdFBhZ2VFdmVudChwcmV2aW91c1BhZ2VJbmRleCk7XG4gIH1cblxuICAvKiogTW92ZSB0byB0aGUgZmlyc3QgcGFnZSBpZiBub3QgYWxyZWFkeSB0aGVyZS4gKi9cbiAgZmlyc3RQYWdlKCk6IHZvaWQge1xuICAgIC8vIGhhc1ByZXZpb3VzUGFnZSBiZWluZyBmYWxzZSBpbXBsaWVzIGF0IHRoZSBzdGFydFxuICAgIGlmICghdGhpcy5oYXNQcmV2aW91c1BhZ2UoKSkgeyByZXR1cm47IH1cblxuICAgIGNvbnN0IHByZXZpb3VzUGFnZUluZGV4ID0gdGhpcy5wYWdlSW5kZXg7XG4gICAgdGhpcy5wYWdlSW5kZXggPSAwO1xuICAgIHRoaXMuX3VwZGF0ZURpc3BsYXllZFBhZ2VzQXJyYXkoKTtcbiAgICB0aGlzLl9lbWl0UGFnZUV2ZW50KHByZXZpb3VzUGFnZUluZGV4KTtcbiAgfVxuXG4gIC8qKiBNb3ZlIHRvIHRoZSBsYXN0IHBhZ2UgaWYgbm90IGFscmVhZHkgdGhlcmUuICovXG4gIGxhc3RQYWdlKCk6IHZvaWQge1xuICAgIC8vIGhhc05leHRQYWdlIGJlaW5nIGZhbHNlIGltcGxpZXMgYXQgdGhlIGVuZFxuICAgIGlmICghdGhpcy5oYXNOZXh0UGFnZSgpKSB7IHJldHVybjsgfVxuXG4gICAgY29uc3QgcHJldmlvdXNQYWdlSW5kZXggPSB0aGlzLnBhZ2VJbmRleDtcbiAgICB0aGlzLnBhZ2VJbmRleCA9IHRoaXMuZ2V0TnVtYmVyT2ZQYWdlcygpIC0gMTtcbiAgICB0aGlzLl91cGRhdGVEaXNwbGF5ZWRQYWdlc0FycmF5KCk7XG4gICAgdGhpcy5fZW1pdFBhZ2VFdmVudChwcmV2aW91c1BhZ2VJbmRleCk7XG4gIH1cblxuICBnb1RvUGFnZShwYWdlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91c1BhZ2VJbmRleCA9IHRoaXMucGFnZUluZGV4O1xuXG4gICAgdGhpcy5wYWdlSW5kZXggPSBwYWdlIC0gMTtcbiAgICB0aGlzLl91cGRhdGVEaXNwbGF5ZWRQYWdlc0FycmF5KCk7XG4gICAgdGhpcy5fZW1pdFBhZ2VFdmVudChwcmV2aW91c1BhZ2VJbmRleCk7XG4gIH1cblxuICAvKiogV2hldGhlciB0aGVyZSBpcyBhIHByZXZpb3VzIHBhZ2UuICovXG4gIGhhc1ByZXZpb3VzUGFnZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5wYWdlSW5kZXggPj0gMSAmJiB0aGlzLnBhZ2VTaXplICE9PSAwO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlcmUgaXMgYSBuZXh0IHBhZ2UuICovXG4gIGhhc05leHRQYWdlKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG1heFBhZ2VJbmRleCA9IHRoaXMuZ2V0TnVtYmVyT2ZQYWdlcygpIC0gMTtcbiAgICByZXR1cm4gdGhpcy5wYWdlSW5kZXggPCBtYXhQYWdlSW5kZXggJiYgdGhpcy5wYWdlU2l6ZSAhPT0gMDtcbiAgfVxuXG4gIC8qKiBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBwYWdlcyAqL1xuICBnZXROdW1iZXJPZlBhZ2VzKCk6IG51bWJlciB7XG4gICAgaWYgKCF0aGlzLnBhZ2VTaXplKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMubGVuZ3RoIC8gdGhpcy5wYWdlU2l6ZSk7XG4gIH1cblxuICAvKiogQ2FsY3VsYXRlIHRoZSBwYWdlIHJhbmdlICovXG4gIGdldFJhbmdlTGFiZWwgPSAocGFnZTogbnVtYmVyLCBwYWdlU2l6ZTogbnVtYmVyLCBsZW5ndGg6IG51bWJlcikgPT4ge1xuICAgIGlmIChsZW5ndGggPT09IDAgfHwgcGFnZVNpemUgPT09IDApIHsgcmV0dXJuIGAwIGRlICR7bGVuZ3RofWA7IH1cblxuICAgIGxlbmd0aCA9IE1hdGgubWF4KGxlbmd0aCwgMCk7XG5cbiAgICBjb25zdCBzdGFydEluZGV4ID0gcGFnZSAqIHBhZ2VTaXplO1xuXG4gICAgLy8gSWYgdGhlIHN0YXJ0IGluZGV4IGV4Y2VlZHMgdGhlIGxpc3QgbGVuZ3RoLCBkbyBub3QgdHJ5IGFuZCBmaXggdGhlIGVuZCBpbmRleCB0byB0aGUgZW5kLlxuICAgIGNvbnN0IGVuZEluZGV4ID0gc3RhcnRJbmRleCA8IGxlbmd0aCA/XG4gICAgICBNYXRoLm1pbihzdGFydEluZGV4ICsgcGFnZVNpemUsIGxlbmd0aCkgOlxuICAgICAgc3RhcnRJbmRleCArIHBhZ2VTaXplO1xuXG4gICAgcmV0dXJuIGAke3N0YXJ0SW5kZXggKyAxfSDigJMgJHtlbmRJbmRleH0gZGUgJHtsZW5ndGh9YDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoYW5nZXMgdGhlIHBhZ2Ugc2l6ZSBzbyB0aGF0IHRoZSBmaXJzdCBpdGVtIGRpc3BsYXllZCBvbiB0aGUgcGFnZSB3aWxsIHN0aWxsIGJlXG4gICAqIGRpc3BsYXllZCB1c2luZyB0aGUgbmV3IHBhZ2Ugc2l6ZS5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIGlmIHRoZSBwYWdlIHNpemUgaXMgMTAgYW5kIG9uIHRoZSBzZWNvbmQgcGFnZSAoaXRlbXMgaW5kZXhlZCAxMC0xOSkgdGhlblxuICAgKiBzd2l0Y2hpbmcgc28gdGhhdCB0aGUgcGFnZSBzaXplIGlzIDUgd2lsbCBzZXQgdGhlIHRoaXJkIHBhZ2UgYXMgdGhlIGN1cnJlbnQgcGFnZSBzb1xuICAgKiB0aGF0IHRoZSAxMHRoIGl0ZW0gd2lsbCBzdGlsbCBiZSBkaXNwbGF5ZWQuXG4gICAqL1xuICBfY2hhbmdlUGFnZVNpemUocGFnZVNpemU6IG51bWJlcikge1xuICAgIC8vIEN1cnJlbnQgcGFnZSBuZWVkcyB0byBiZSB1cGRhdGVkIHRvIHJlZmxlY3QgdGhlIG5ldyBwYWdlIHNpemUuIE5hdmlnYXRlIHRvIHRoZSBwYWdlXG4gICAgLy8gY29udGFpbmluZyB0aGUgcHJldmlvdXMgcGFnZSdzIGZpcnN0IGl0ZW0uXG4gICAgY29uc3Qgc3RhcnRJbmRleCA9IHRoaXMucGFnZUluZGV4ICogdGhpcy5wYWdlU2l6ZTtcbiAgICBjb25zdCBwcmV2aW91c1BhZ2VJbmRleCA9IHRoaXMucGFnZUluZGV4O1xuXG4gICAgdGhpcy5wYWdlSW5kZXggPSBNYXRoLmZsb29yKHN0YXJ0SW5kZXggLyBwYWdlU2l6ZSkgfHwgMDtcbiAgICB0aGlzLnBhZ2VTaXplID0gcGFnZVNpemU7XG4gICAgdGhpcy5fZW1pdFBhZ2VFdmVudChwcmV2aW91c1BhZ2VJbmRleCk7XG4gIH1cblxuICAvKiogQ2hlY2tzIHdoZXRoZXIgdGhlIGJ1dHRvbnMgZm9yIGdvaW5nIGZvcndhcmRzIHNob3VsZCBiZSBkaXNhYmxlZC4gKi9cbiAgX25leHRCdXR0b25zRGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQgfHwgIXRoaXMuaGFzTmV4dFBhZ2UoKTtcbiAgfVxuXG4gIC8qKiBDaGVja3Mgd2hldGhlciB0aGUgYnV0dG9ucyBmb3IgZ29pbmcgYmFja3dhcmRzIHNob3VsZCBiZSBkaXNhYmxlZC4gKi9cbiAgX3ByZXZpb3VzQnV0dG9uc0Rpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmRpc2FibGVkIHx8ICF0aGlzLmhhc1ByZXZpb3VzUGFnZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGxpc3Qgb2YgcGFnZSBzaXplIG9wdGlvbnMgdG8gZGlzcGxheSB0byB0aGUgdXNlci4gSW5jbHVkZXMgbWFraW5nIHN1cmUgdGhhdFxuICAgKiB0aGUgcGFnZSBzaXplIGlzIGFuIG9wdGlvbiBhbmQgdGhhdCB0aGUgbGlzdCBpcyBzb3J0ZWQuXG4gICAqL1xuICBwcml2YXRlIF91cGRhdGVEaXNwbGF5ZWRQYWdlU2l6ZU9wdGlvbnMoKSB7XG4gICAgaWYgKCF0aGlzLl9pbml0aWFsaXplZCkgeyByZXR1cm47IH1cblxuICAgIC8vIElmIG5vIHBhZ2Ugc2l6ZSBpcyBwcm92aWRlZCwgdXNlIHRoZSBmaXJzdCBwYWdlIHNpemUgb3B0aW9uIG9yIHRoZSBkZWZhdWx0IHBhZ2Ugc2l6ZS5cbiAgICBpZiAoIXRoaXMucGFnZVNpemUpIHtcbiAgICAgIHRoaXMuX3BhZ2VTaXplID0gdGhpcy5wYWdlU2l6ZU9wdGlvbnMubGVuZ3RoICE9PSAwID9cbiAgICAgICAgdGhpcy5wYWdlU2l6ZU9wdGlvbnNbMF0gOlxuICAgICAgICBERUZBVUxUX1BBR0VfU0laRTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaXNwbGF5ZWRQYWdlU2l6ZU9wdGlvbnMgPSB0aGlzLnBhZ2VTaXplT3B0aW9ucy5zbGljZSgpO1xuXG4gICAgaWYgKHRoaXMuX2Rpc3BsYXllZFBhZ2VTaXplT3B0aW9ucy5pbmRleE9mKHRoaXMucGFnZVNpemUpID09PSAtMSkge1xuICAgICAgdGhpcy5fZGlzcGxheWVkUGFnZVNpemVPcHRpb25zLnB1c2godGhpcy5wYWdlU2l6ZSk7XG4gICAgfVxuXG4gICAgLy8gU29ydCB0aGUgbnVtYmVycyB1c2luZyBhIG51bWJlci1zcGVjaWZpYyBzb3J0IGZ1bmN0aW9uLlxuICAgIHRoaXMuX2Rpc3BsYXllZFBhZ2VTaXplT3B0aW9ucy5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVEaXNwbGF5ZWRQYWdlc0FycmF5KCkge1xuICAgIHRoaXMuX3BhZ2VzQXJyYXkgPSBidWlsZFBhZ2luYXRpb25BcnJheSh0aGlzLmdldE51bWJlck9mUGFnZXMoKSwgdGhpcy5wYWdlSW5kZXggKyAxLCAzKTtcbiAgfVxuXG4gIC8qKiBFbWl0cyBhbiBldmVudCBub3RpZnlpbmcgdGhhdCBhIGNoYW5nZSBvZiB0aGUgcGFnaW5hdGlvbidzIHByb3BlcnRpZXMgaGFzIGJlZW4gdHJpZ2dlcmVkLiAqL1xuICBwcml2YXRlIF9lbWl0UGFnZUV2ZW50KHByZXZpb3VzUGFnZUluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnBhZ2UuZW1pdCh7XG4gICAgICBwcmV2aW91c1BhZ2VJbmRleCxcbiAgICAgIHBhZ2VJbmRleDogdGhpcy5wYWdlSW5kZXgsXG4gICAgICBwYWdlU2l6ZTogdGhpcy5wYWdlU2l6ZSxcbiAgICAgIGxlbmd0aDogdGhpcy5sZW5ndGhcbiAgICB9KTtcbiAgfVxufVxuIl19