UNPKG

@asoftwareworld/form-builder-pro

Version:

ASW Form Builder Pro helps you with rapid development and designed web forms which includes several controls. The key feature of Form Builder is to make your content attractive and effective. We can customize our control at run time and preview the same b

228 lines 34.2 kB
import { ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, Optional, Output, ViewEncapsulation } from '@angular/core'; import { createMissingDateImplError } from '../datetimepicker-errors'; import { AswCalendarCell } from '../calendar-body/calendar-body'; import { aswDatetimepickerAnimations } from '../datetimepicker-animations'; import { ASW_DATETIME_FORMATS } from '@asoftwareworld/form-builder-pro/common'; import * as i0 from "@angular/core"; import * as i1 from "@asoftwareworld/form-builder-pro/common"; import * as i2 from "../calendar-body/calendar-body"; export const yearsPerPage = 24; export const yearsPerRow = 4; /** * An internal component used to display multiple years in the datetimepicker. * @docs-private */ export class AswMultiYearView { _adapter; _dateFormats; type = 'date'; /** A function used to filter which dates are selectable. */ dateFilter; /** Emits when a new month is selected. */ selectedChange = new EventEmitter(); /** Emits when any date is selected. */ _userSelection = new EventEmitter(); /** Grid of calendar cells representing the years in the range. */ _years; /** The label for this year range (e.g. "2000-2020"). */ _yearLabel; /** The year in this range that today falls on. Null if today is in a different range. */ _todayYear; /** * The year in this range that the selected Date falls on. * Null if the selected Date is in a different range. */ _selectedYear; _calendarState; constructor(_adapter, _dateFormats) { this._adapter = _adapter; this._dateFormats = _dateFormats; if (!this._adapter) { throw createMissingDateImplError('DatetimeAdapter'); } if (!this._dateFormats) { throw createMissingDateImplError('ASW_DATETIME_FORMATS'); } this._activeDate = this._adapter.today(); } /** The date to display in this multi year view */ get activeDate() { return this._activeDate; } set activeDate(value) { const oldActiveDate = this._activeDate; this._activeDate = value || this._adapter.today(); if (oldActiveDate && this._activeDate && !isSameMultiYearView(this._adapter, oldActiveDate, this._activeDate, this.minDate, this.maxDate)) { this._init(); } } _activeDate; /** The currently selected date. */ get selected() { return this._selected; } set selected(value) { this._selected = value; this._selectedYear = this._selected && this._adapter.getYear(this._selected); } _selected; /** The minimum selectable date. */ get minDate() { return this._minDate; } set minDate(value) { this._minDate = this._getValidDateOrNull(this._adapter.deserialize(value)); } _minDate; /** The maximum selectable date. */ get maxDate() { return this._maxDate; } set maxDate(value) { this._maxDate = this._getValidDateOrNull(this._adapter.deserialize(value)); } _maxDate; ngAfterContentInit() { this._init(); } /** Handles when a new year is selected. */ _yearSelected(year) { const month = this._adapter.getMonth(this.activeDate); const normalizedDate = this._adapter.createDatetime(year, month, 1, 0, 0); this.selectedChange.emit(this._adapter.createDatetime(year, month, Math.min(this._adapter.getDate(this.activeDate), this._adapter.getNumDaysInMonth(normalizedDate)), this._adapter.getHour(this.activeDate), this._adapter.getMinute(this.activeDate))); if (this.type === 'year') { this._userSelection.emit(); } } _getActiveCell() { return getActiveOffset(this._adapter, this.activeDate, this.minDate, this.maxDate); } _calendarStateDone() { this._calendarState = ''; } /** Initializes this year view. */ _init() { this._todayYear = this._adapter.getYear(this._adapter.today()); this._yearLabel = this._adapter.getYearName(this.activeDate); const activeYear = this._adapter.getYear(this.activeDate); const minYearOfPage = activeYear - getActiveOffset(this._adapter, this.activeDate, this.minDate, this.maxDate); this._years = []; for (let i = 0, row = []; i < yearsPerPage; i++) { row.push(minYearOfPage + i); if (row.length === yearsPerRow) { this._years.push(row.map((year) => this._createCellForYear(year))); row = []; } } } /** Creates an AswCalendarCell for the given year. */ _createCellForYear(year) { const yearName = this._adapter.getYearName(this._adapter.createDate(year, 0, 1)); return new AswCalendarCell(year, yearName, yearName, this._shouldEnableYear(year)); } /** Whether the given year is enabled. */ _shouldEnableYear(year) { // disable if the year is greater than maxDate lower than minDate if (year === undefined || year === null || (this.maxDate && year > this._adapter.getYear(this.maxDate)) || (this.minDate && year < this._adapter.getYear(this.minDate))) { return false; } // enable if it reaches here and there's no filter defined if (!this.dateFilter) { return true; } const firstOfYear = this._adapter.createDate(year, 0, 1); // If any date in the year is enabled count the year as enabled. for (let date = firstOfYear; this._adapter.getYear(date) === year; date = this._adapter.addCalendarDays(date, 1)) { if (this.dateFilter(date)) { return true; } } return false; } /** * Gets the year in this years range that the given Date falls on. * Returns null if the given Date is not in this range. */ _getYearInCurrentRange(date) { const year = this._adapter.getYear(date); return this._isInRange(year) ? year : null; } /** * Validate if the current year is in the current range * Returns true if is in range else returns false */ _isInRange(year) { return true; } /** * @param obj The object to check. * @returns The given object if it is both a date instance and valid, otherwise null. */ _getValidDateOrNull(obj) { return this._adapter.isDateInstance(obj) && this._adapter.isValid(obj) ? obj : null; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AswMultiYearView, deps: [{ token: i1.DatetimeAdapter, optional: true }, { token: ASW_DATETIME_FORMATS, optional: true }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: AswMultiYearView, selector: "asw-multi-year-view", inputs: { type: "type", dateFilter: "dateFilter", activeDate: "activeDate", selected: "selected", minDate: "minDate", maxDate: "maxDate" }, outputs: { selectedChange: "selectedChange", _userSelection: "_userSelection" }, exportAs: ["aswMultiYearView"], ngImport: i0, template: "<table class=\"asw-calendar-table\" role=\"grid\">\r\n <thead class=\"asw-calendar-table-header\"></thead>\r\n <tbody asw-calendar-body\r\n (@slideCalendar.done)=\"_calendarStateDone()\"\r\n [@slideCalendar]=\"_calendarState\"\r\n [todayValue]=\"_todayYear\"\r\n [rows]=\"_years\"\r\n [numCols]=\"4\"\r\n [activeCell]=\"_getActiveCell()\"\r\n [allowDisabledSelection]=\"true\"\r\n [selectedValue]=\"_selectedYear!\"\r\n (selectedValueChange)=\"_yearSelected($event)\">\r\n </tbody>\r\n</table>\r\n", dependencies: [{ kind: "component", type: i2.AswCalendarBody, selector: "[asw-calendar-body]", inputs: ["label", "rows", "todayValue", "selectedValue", "labelMinRequiredCells", "numCols", "allowDisabledSelection", "activeCell"], outputs: ["selectedValueChange"], exportAs: ["aswCalendarBody"] }], animations: [aswDatetimepickerAnimations.slideCalendar], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AswMultiYearView, decorators: [{ type: Component, args: [{ selector: 'asw-multi-year-view', exportAs: 'aswMultiYearView', animations: [aswDatetimepickerAnimations.slideCalendar], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<table class=\"asw-calendar-table\" role=\"grid\">\r\n <thead class=\"asw-calendar-table-header\"></thead>\r\n <tbody asw-calendar-body\r\n (@slideCalendar.done)=\"_calendarStateDone()\"\r\n [@slideCalendar]=\"_calendarState\"\r\n [todayValue]=\"_todayYear\"\r\n [rows]=\"_years\"\r\n [numCols]=\"4\"\r\n [activeCell]=\"_getActiveCell()\"\r\n [allowDisabledSelection]=\"true\"\r\n [selectedValue]=\"_selectedYear!\"\r\n (selectedValueChange)=\"_yearSelected($event)\">\r\n </tbody>\r\n</table>\r\n" }] }], ctorParameters: () => [{ type: i1.DatetimeAdapter, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ASW_DATETIME_FORMATS] }] }], propDecorators: { type: [{ type: Input }], dateFilter: [{ type: Input }], selectedChange: [{ type: Output }], _userSelection: [{ type: Output }], activeDate: [{ type: Input }], selected: [{ type: Input }], minDate: [{ type: Input }], maxDate: [{ type: Input }] } }); export function isSameMultiYearView(dateAdapter, date1, date2, minDate, maxDate) { const year1 = dateAdapter.getYear(date1); const year2 = dateAdapter.getYear(date2); const startingYear = getStartingYear(dateAdapter, minDate, maxDate); return Math.floor((year1 - startingYear) / yearsPerPage) === Math.floor((year2 - startingYear) / yearsPerPage); } /** * When the multi-year view is first opened, the active year will be in view. * So we compute how many years are between the active year and the *slot* where our * "startingYear" will render when paged into view. */ export function getActiveOffset(dateAdapter, activeDate, minDate, maxDate) { const activeYear = dateAdapter.getYear(activeDate); return euclideanModulo(activeYear - getStartingYear(dateAdapter, minDate, maxDate), yearsPerPage); } /** * We pick a "starting" year such that either the maximum year would be at the end * or the minimum year would be at the beginning of a page. */ function getStartingYear(dateAdapter, minDate, maxDate) { let startingYear = 0; if (maxDate) { const maxYear = dateAdapter.getYear(maxDate); startingYear = maxYear - yearsPerPage + 1; } else if (minDate) { startingYear = dateAdapter.getYear(minDate); } return startingYear; } /** Gets remainder that is non-negative, even if first number is negative */ function euclideanModulo(a, b) { return ((a % b) + b) % b; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGkteWVhci12aWV3LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvZGF0ZXRpbWVwaWNrZXIvbXVsdGkteWVhci12aWV3L211bHRpLXllYXItdmlldy50cyIsIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2RhdGV0aW1lcGlja2VyL211bHRpLXllYXItdmlldy9tdWx0aS15ZWFyLXZpZXcuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW9CLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZKLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRSxPQUFPLEVBQUUsb0JBQW9CLEVBQXVDLE1BQU0seUNBQXlDLENBQUM7Ozs7QUFHcEgsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztBQUUvQixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBRTdCOzs7R0FHRztBQVNILE1BQU0sT0FBTyxnQkFBZ0I7SUE4QkY7SUFDK0I7SUE5QjdDLElBQUksR0FBMEIsTUFBTSxDQUFDO0lBRTlDLDREQUE0RDtJQUNuRCxVQUFVLENBQXdCO0lBRTNDLDBDQUEwQztJQUNoQyxjQUFjLEdBQUcsSUFBSSxZQUFZLEVBQUssQ0FBQztJQUVqRCx1Q0FBdUM7SUFDcEIsY0FBYyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7SUFFN0Qsa0VBQWtFO0lBQ2xFLE1BQU0sQ0FBdUI7SUFFN0Isd0RBQXdEO0lBQ3hELFVBQVUsQ0FBVTtJQUVwQix5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R0FBRyxDQUFDLENBQUM7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5qZWN0LCBJbnB1dCwgT3B0aW9uYWwsIE91dHB1dCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNyZWF0ZU1pc3NpbmdEYXRlSW1wbEVycm9yIH0gZnJvbSAnLi4vZGF0ZXRpbWVwaWNrZXItZXJyb3JzJztcbmltcG9ydCB7IEFzd0NhbGVuZGFyQ2VsbCB9IGZyb20gJy4uL2NhbGVuZGFyLWJvZHkvY2FsZW5kYXItYm9keSc7XG5pbXBvcnQgeyBhc3dEYXRldGltZXBpY2tlckFuaW1hdGlvbnMgfSBmcm9tICcuLi9kYXRldGltZXBpY2tlci1hbmltYXRpb25zJztcbmltcG9ydCB7IEFTV19EQVRFVElNRV9GT1JNQVRTLCBBc3dEYXRldGltZUZvcm1hdHMsIERhdGV0aW1lQWRhcHRlciB9IGZyb20gJ0Bhc29mdHdhcmV3b3JsZC9mb3JtLWJ1aWxkZXItcHJvL2NvbW1vbic7XG5pbXBvcnQgeyBBc3dEYXRldGltZXBpY2tlclR5cGUgfSBmcm9tICcuLi9kYXRldGltZXBpY2tlci10eXBlcyc7XG5cbmV4cG9ydCBjb25zdCB5ZWFyc1BlclBhZ2UgPSAyNDtcblxuZXhwb3J0IGNvbnN0IHllYXJzUGVyUm93ID0gNDtcblxuLyoqXG4gKiBBbiBpbnRlcm5hbCBjb21wb25lbnQgdXNlZCB0byBkaXNwbGF5IG11bHRpcGxlIHllYXJzIGluIHRoZSBkYXRldGltZXBpY2tlci5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhc3ctbXVsdGkteWVhci12aWV3JyxcbiAgICB0ZW1wbGF0ZVVybDogJ211bHRpLXllYXItdmlldy5odG1sJyxcbiAgICBleHBvcnRBczogJ2Fzd011bHRpWWVhclZpZXcnLFxuICAgIGFuaW1hdGlvbnM6IFthc3dEYXRldGltZXBpY2tlckFuaW1hdGlvbnMuc2xpZGVDYWxlbmRhcl0sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBBc3dNdWx0aVllYXJWaWV3PEQ+IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gICAgQElucHV0KCkgdHlwZTogQXN3RGF0ZXRpbWVwaWNrZXJUeXBlID0gJ2RhdGUnO1xuXG4gICAgLyoqIEEgZnVuY3Rpb24gdXNlZCB0byBmaWx0ZXIgd2hpY2ggZGF0ZXMgYXJlIHNlbGVjdGFibGUuICovXG4gICAgQElucHV0KCkgZGF0ZUZpbHRlciE6IChkYXRlOiBEKSA9PiBib29sZWFuO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gYSBuZXcgbW9udGggaXMgc2VsZWN0ZWQuICovXG4gICAgQE91dHB1dCgpIHNlbGVjdGVkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEPigpO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gYW55IGRhdGUgaXMgc2VsZWN0ZWQuICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IF91c2VyU2VsZWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLyoqIEdyaWQgb2YgY2FsZW5kYXIgY2VsbHMgcmVwcmVzZW50aW5nIHRoZSB5ZWFycyBpbiB0aGUgcmFuZ2UuICovXG4gICAgX3llYXJzITogQXN3Q2FsZW5kYXJDZWxsW11bXTtcblxuICAgIC8qKiBUaGUgbGFiZWwgZm9yIHRoaXMgeWVhciByYW5nZSAoZS5nLiBcIjIwMDAtMjAyMFwiKS4gKi9cbiAgICBfeWVhckxhYmVsITogc3RyaW5nO1xuXG4gICAgLyoqIFRoZSB5ZWFyIGluIHRoaXMgcmFuZ2UgdGhhdCB0b2RheSBmYWxscyBvbi4gTnVsbCBpZiB0b2RheSBpcyBpbiBhIGRpZmZlcmVudCByYW5nZS4gKi9cbiAgICBfdG9kYXlZZWFyITogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHllYXIgaW4gdGhpcyByYW5nZSB0aGF0IHRoZSBzZWxlY3RlZCBEYXRlIGZhbGxzIG9uLlxuICAgICAqIE51bGwgaWYgdGhlIHNlbGVjdGVkIERhdGUgaXMgaW4gYSBkaWZmZXJlbnQgcmFuZ2UuXG4gICAgICovXG4gICAgX3NlbGVjdGVkWWVhciE6IG51bWJlciB8IG51bGw7XG5cbiAgICBfY2FsZW5kYXJTdGF0ZSE6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBAT3B0aW9uYWwoKSBwdWJsaWMgX2FkYXB0ZXI6IERhdGV0aW1lQWRhcHRlcjxEPixcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBU1dfREFURVRJTUVfRk9STUFUUykgcHJpdmF0ZSBfZGF0ZUZvcm1hdHM6IEFzd0RhdGV0aW1lRm9ybWF0c1xuICAgICkge1xuICAgICAgICBpZiAoIXRoaXMuX2FkYXB0ZXIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU1pc3NpbmdEYXRlSW1wbEVycm9yKCdEYXRldGltZUFkYXB0ZXInKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5fZGF0ZUZvcm1hdHMpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU1pc3NpbmdEYXRlSW1wbEVycm9yKCdBU1dfREFURVRJTUVfRk9STUFUUycpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fYWN0aXZlRGF0ZSA9IHRoaXMuX2FkYXB0ZXIudG9kYXkoKTtcbiAgICB9XG5cbiAgICAvKiogVGhlIGRhdGUgdG8gZGlzcGxheSBpbiB0aGlzIG11bHRpIHllYXIgdmlldyAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IGFjdGl2ZURhdGUoKTogRCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmVEYXRlO1xuICAgIH1cbiAgICBzZXQgYWN0aXZlRGF0ZSh2YWx1ZTogRCkge1xuICAgICAgICBjb25zdCBvbGRBY3RpdmVEYXRlID0gdGhpcy5fYWN0aXZlRGF0ZTtcbiAgICAgICAgdGhpcy5fYWN0aXZlRGF0ZSA9IHZhbHVlIHx8IHRoaXMuX2FkYXB0ZXIudG9kYXkoKTtcbiAgICAgICAgaWYgKG9sZEFjdGl2ZURhdGUgJiYgdGhpcy5fYWN0aXZlRGF0ZSAmJiAhaXNTYW1lTXVsdGlZZWFyVmlldyh0aGlzLl9hZGFwdGVyLCBvbGRBY3RpdmVEYXRlLCB0aGlzLl9hY3RpdmVEYXRlLCB0aGlzLm1pbkRhdGUsIHRoaXMubWF4RGF0ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuX2luaXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwcml2YXRlIF9hY3RpdmVEYXRlOiBEO1xuXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZGF0ZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBzZWxlY3RlZCgpOiBEIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkO1xuICAgIH1cbiAgICBzZXQgc2VsZWN0ZWQodmFsdWU6IEQpIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWQgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWRZZWFyID0gdGhpcy5fc2VsZWN0ZWQgJiYgdGhpcy5fYWRhcHRlci5nZXRZZWFyKHRoaXMuX3NlbGVjdGVkKTtcbiAgICB9XG4gICAgcHJpdmF0ZSBfc2VsZWN0ZWQhOiBEO1xuXG4gICAgLyoqIFRoZSBtaW5pbXVtIHNlbGVjdGFibGUgZGF0ZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBtaW5EYXRlKCk6IEQgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbkRhdGU7XG4gICAgfVxuICAgIHNldCBtaW5EYXRlKHZhbHVlOiBEIHwgbnVsbCkge1xuICAgICAgICB0aGlzLl9taW5EYXRlID0gdGhpcy5fZ2V0VmFsaWREYXRlT3JOdWxsKHRoaXMuX2FkYXB0ZXIuZGVzZXJpYWxpemUodmFsdWUpKTtcbiAgICB9XG4gICAgcHJpdmF0ZSBfbWluRGF0ZSE6IEQgfCBudWxsO1xuXG4gICAgLyoqIFRoZSBtYXhpbXVtIHNlbGVjdGFibGUgZGF0ZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBtYXhEYXRlKCk6IEQgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heERhdGU7XG4gICAgfVxuICAgIHNldCBtYXhEYXRlKHZhbHVlOiBEIHwgbnVsbCkge1xuICAgICAgICB0aGlzLl9tYXhEYXRlID0gdGhpcy5fZ2V0VmFsaWREYXRlT3JOdWxsKHRoaXMuX2FkYXB0ZXIuZGVzZXJpYWxpemUodmFsdWUpKTtcbiAgICB9XG4gICAgcHJpdmF0ZSBfbWF4RGF0ZSE6IEQgfCBudWxsO1xuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLl9pbml0KCk7XG4gICAgfVxuXG4gICAgLyoqIEhhbmRsZXMgd2hlbiBhIG5ldyB5ZWFyIGlzIHNlbGVjdGVkLiAqL1xuICAgIF95ZWFyU2VsZWN0ZWQoeWVhcjogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IG1vbnRoID0gdGhpcy5fYWRhcHRlci5nZXRNb250aCh0aGlzLmFjdGl2ZURhdGUpO1xuICAgICAgICBjb25zdCBub3JtYWxpemVkRGF0ZSA9IHRoaXMuX2FkYXB0ZXIuY3JlYXRlRGF0ZXRpbWUoeWVhciwgbW9udGgsIDEsIDAsIDApO1xuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDaGFuZ2UuZW1pdChcbiAgICAgICAgICAgIHRoaXMuX2FkYXB0ZXIuY3JlYXRlRGF0ZXRpbWUoeWVhciwgbW9udGgsIE1hdGgubWluKHRoaXMuX2FkYXB0ZXIuZ2V0RGF0ZSh0aGlzLmFjdGl2ZURhdGUpLCB0aGlzLl9hZGFwdGVyLmdldE51bURheXNJbk1vbnRoKG5vcm1hbGl6ZWREYXRlKSksIHRoaXMuX2FkYXB0ZXIuZ2V0SG91cih0aGlzLmFjdGl2ZURhdGUpLCB0aGlzLl9hZGFwdGVyLmdldE1pbnV0ZSh0aGlzLmFjdGl2ZURhdGUpKVxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICd5ZWFyJykge1xuICAgICAgICAgICAgdGhpcy5fdXNlclNlbGVjdGlvbi5lbWl0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfZ2V0QWN0aXZlQ2VsbCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gZ2V0QWN0aXZlT2Zmc2V0KHRoaXMuX2FkYXB0ZXIsIHRoaXMuYWN0aXZlRGF0ZSwgdGhpcy5taW5EYXRlLCB0aGlzLm1heERhdGUpO1xuICAgIH1cblxuICAgIF9jYWxlbmRhclN0YXRlRG9uZSgpIHtcbiAgICAgICAgdGhpcy5fY2FsZW5kYXJTdGF0ZSA9ICcnO1xuICAgIH1cblxuICAgIC8qKiBJbml0aWFsaXplcyB0aGlzIHllYXIgdmlldy4gKi9cbiAgICBwcml2YXRlIF9pbml0KCkge1xuICAgICAgICB0aGlzLl90b2RheVllYXIgPSB0aGlzLl9hZGFwdGVyLmdldFllYXIodGhpcy5fYWRhcHRlci50b2RheSgpKTtcbiAgICAgICAgdGhpcy5feWVhckxhYmVsID0gdGhpcy5fYWRhcHRlci5nZXRZZWFyTmFtZSh0aGlzLmFjdGl2ZURhdGUpO1xuXG4gICAgICAgIGNvbnN0IGFjdGl2ZVllYXIgPSB0aGlzLl9hZGFwdGVyLmdldFllYXIodGhpcy5hY3RpdmVEYXRlKTtcblxuICAgICAgICBjb25zdCBtaW5ZZWFyT2ZQYWdlID0gYWN0aXZlWWVhciAtIGdldEFjdGl2ZU9mZnNldCh0aGlzLl9hZGFwdGVyLCB0aGlzLmFjdGl2ZURhdGUsIHRoaXMubWluRGF0ZSwgdGhpcy5tYXhEYXRlKTtcblxuICAgICAgICB0aGlzLl95ZWFycyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgcm93OiBudW1iZXJbXSA9IFtdOyBpIDwgeWVhcnNQZXJQYWdlOyBpKyspIHtcbiAgICAgICAgICAgIHJvdy5wdXNoKG1pblllYXJPZlBhZ2UgKyBpKTtcbiAgICAgICAgICAgIGlmIChyb3cubGVuZ3RoID09PSB5ZWFyc1BlclJvdykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3llYXJzLnB1c2gocm93Lm1hcCgoeWVhcikgPT4gdGhpcy5fY3JlYXRlQ2VsbEZvclllYXIoeWVhcikpKTtcbiAgICAgICAgICAgICAgICByb3cgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBDcmVhdGVzIGFuIEFzd0NhbGVuZGFyQ2VsbCBmb3IgdGhlIGdpdmVuIHllYXIuICovXG4gICAgcHJpdmF0ZSBfY3JlYXRlQ2VsbEZvclllYXIoeWVhcjogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IHllYXJOYW1lID0gdGhpcy5fYWRhcHRlci5nZXRZZWFyTmFtZSh0aGlzLl9hZGFwdGVyLmNyZWF0ZURhdGUoeWVhciwgMCwgMSkpO1xuICAgICAgICByZXR1cm4gbmV3IEFzd0NhbGVuZGFyQ2VsbCh5ZWFyLCB5ZWFyTmFtZSwgeWVhck5hbWUsIHRoaXMuX3Nob3VsZEVuYWJsZVllYXIoeWVhcikpO1xuICAgIH1cblxuICAgIC8qKiBXaGV0aGVyIHRoZSBnaXZlbiB5ZWFyIGlzIGVuYWJsZWQuICovXG4gICAgcHJpdmF0ZSBfc2hvdWxkRW5hYmxlWWVhcih5ZWFyOiBudW1iZXIpIHtcbiAgICAgICAgLy8gZGlzYWJsZSBpZiB0aGUgeWVhciBpcyBncmVhdGVyIHRoYW4gbWF4RGF0ZSBsb3dlciB0aGFuIG1pbkRhdGVcbiAgICAgICAgaWYgKHllYXIgPT09IHVuZGVmaW5lZCB8fCB5ZWFyID09PSBudWxsIHx8ICh0aGlzLm1heERhdGUgJiYgeWVhciA+IHRoaXMuX2FkYXB0ZXIuZ2V0WWVhcih0aGlzLm1heERhdGUpKSB8fCAodGhpcy5taW5EYXRlICYmIHllYXIgPCB0aGlzLl9hZGFwdGVyLmdldFllYXIodGhpcy5taW5EYXRlKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVuYWJsZSBpZiBpdCByZWFjaGVzIGhlcmUgYW5kIHRoZXJlJ3Mgbm8gZmlsdGVyIGRlZmluZWRcbiAgICAgICAgaWYgKCF0aGlzLmRhdGVGaWx0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RPZlllYXIgPSB0aGlzLl9hZGFwdGVyLmNyZWF0ZURhdGUoeWVhciwgMCwgMSk7XG5cbiAgICAgICAgLy8gSWYgYW55IGRhdGUgaW4gdGhlIHllYXIgaXMgZW5hYmxlZCBjb3VudCB0aGUgeWVhciBhcyBlbmFibGVkLlxuICAgICAgICBmb3IgKGxldCBkYXRlID0gZmlyc3RPZlllYXI7IHRoaXMuX2FkYXB0ZXIuZ2V0WWVhcihkYXRlKSA9PT0geWVhcjsgZGF0ZSA9IHRoaXMuX2FkYXB0ZXIuYWRkQ2FsZW5kYXJEYXlzKGRhdGUsIDEpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kYXRlRmlsdGVyKGRhdGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgeWVhciBpbiB0aGlzIHllYXJzIHJhbmdlIHRoYXQgdGhlIGdpdmVuIERhdGUgZmFsbHMgb24uXG4gICAgICogUmV0dXJucyBudWxsIGlmIHRoZSBnaXZlbiBEYXRlIGlzIG5vdCBpbiB0aGlzIHJhbmdlLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2dldFllYXJJbkN1cnJlbnRSYW5nZShkYXRlOiBEKSB7XG4gICAgICAgIGNvbnN0IHllYXIgPSB0aGlzLl9hZGFwdGVyLmdldFllYXIoZGF0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc0luUmFuZ2UoeWVhcikgPyB5ZWFyIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWYWxpZGF0ZSBpZiB0aGUgY3VycmVudCB5ZWFyIGlzIGluIHRoZSBjdXJyZW50IHJhbmdlXG4gICAgICogUmV0dXJucyB0cnVlIGlmIGlzIGluIHJhbmdlIGVsc2UgcmV0dXJucyBmYWxzZVxuICAgICAqL1xuICAgIHByaXZhdGUgX2lzSW5SYW5nZSh5ZWFyOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIFRoZSBnaXZlbiBvYmplY3QgaWYgaXQgaXMgYm90aCBhIGRhdGUgaW5zdGFuY2UgYW5kIHZhbGlkLCBvdGhlcndpc2UgbnVsbC5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9nZXRWYWxpZERhdGVPck51bGwob2JqOiBhbnkpOiBEIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGFwdGVyLmlzRGF0ZUluc3RhbmNlKG9iaikgJiYgdGhpcy5fYWRhcHRlci5pc1ZhbGlkKG9iaikgPyBvYmogOiBudWxsO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2FtZU11bHRpWWVhclZpZXc8RD4oZGF0ZUFkYXB0ZXI6IERhdGV0aW1lQWRhcHRlcjxEPiwgZGF0ZTE6IEQsIGRhdGUyOiBELCBtaW5EYXRlOiBEIHwgbnVsbCwgbWF4RGF0ZTogRCB8IG51bGwpOiBib29sZWFuIHtcbiAgICBjb25zdCB5ZWFyMSA9IGRhdGVBZGFwdGVyLmdldFllYXIoZGF0ZTEpO1xuICAgIGNvbnN0IHllYXIyID0gZGF0ZUFkYXB0ZXIuZ2V0WWVhcihkYXRlMik7XG4gICAgY29uc3Qgc3RhcnRpbmdZZWFyID0gZ2V0U3RhcnRpbmdZZWFyKGRhdGVBZGFwdGVyLCBtaW5EYXRlLCBtYXhEYXRlKTtcbiAgICByZXR1cm4gTWF0aC5mbG9vcigoeWVhcjEgLSBzdGFydGluZ1llYXIpIC8geWVhcnNQZXJQYWdlKSA9PT0gTWF0aC5mbG9vcigoeWVhcjIgLSBzdGFydGluZ1llYXIpIC8geWVhcnNQZXJQYWdlKTtcbn1cblxuLyoqXG4gKiBXaGVuIHRoZSBtdWx0aS15ZWFyIHZpZXcgaXMgZmlyc3Qgb3BlbmVkLCB0aGUgYWN0aXZlIHllYXIgd2lsbCBiZSBpbiB2aWV3LlxuICogU28gd2UgY29tcHV0ZSBob3cgbWFueSB5ZWFycyBhcmUgYmV0d2VlbiB0aGUgYWN0aXZlIHllYXIgYW5kIHRoZSAqc2xvdCogd2hlcmUgb3VyXG4gKiBcInN0YXJ0aW5nWWVhclwiIHdpbGwgcmVuZGVyIHdoZW4gcGFnZWQgaW50byB2aWV3LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZlT2Zmc2V0PEQ+KGRhdGVBZGFwdGVyOiBEYXRldGltZUFkYXB0ZXI8RD4sIGFjdGl2ZURhdGU6IEQsIG1pbkRhdGU6IEQgfCBudWxsLCBtYXhEYXRlOiBEIHwgbnVsbCk6IG51bWJlciB7XG4gICAgY29uc3QgYWN0aXZlWWVhciA9IGRhdGVBZGFwdGVyLmdldFllYXIoYWN0aXZlRGF0ZSk7XG4gICAgcmV0dXJuIGV1Y2xpZGVhbk1vZHVsbyhhY3RpdmVZZWFyIC0gZ2V0U3RhcnRpbmdZZWFyKGRhdGVBZGFwdGVyLCBtaW5EYXRlLCBtYXhEYXRlKSwgeWVhcnNQZXJQYWdlKTtcbn1cblxuLyoqXG4gKiBXZSBwaWNrIGEgXCJzdGFydGluZ1wiIHllYXIgc3VjaCB0aGF0IGVpdGhlciB0aGUgbWF4aW11bSB5ZWFyIHdvdWxkIGJlIGF0IHRoZSBlbmRcbiAqIG9yIHRoZSBtaW5pbXVtIHllYXIgd291bGQgYmUgYXQgdGhlIGJlZ2lubmluZyBvZiBhIHBhZ2UuXG4gKi9cbmZ1bmN0aW9uIGdldFN0YXJ0aW5nWWVhcjxEPihkYXRlQWRhcHRlcjogRGF0ZXRpbWVBZGFwdGVyPEQ+LCBtaW5EYXRlOiBEIHwgbnVsbCwgbWF4RGF0ZTogRCB8IG51bGwpOiBudW1iZXIge1xuICAgIGxldCBzdGFydGluZ1llYXIgPSAwO1xuICAgIGlmIChtYXhEYXRlKSB7XG4gICAgICAgIGNvbnN0IG1heFllYXIgPSBkYXRlQWRhcHRlci5nZXRZZWFyKG1heERhdGUpO1xuICAgICAgICBzdGFydGluZ1llYXIgPSBtYXhZZWFyIC0geWVhcnNQZXJQYWdlICsgMTtcbiAgICB9IGVsc2UgaWYgKG1pbkRhdGUpIHtcbiAgICAgICAgc3RhcnRpbmdZZWFyID0gZGF0ZUFkYXB0ZXIuZ2V0WWVhcihtaW5EYXRlKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0YXJ0aW5nWWVhcjtcbn1cblxuLyoqIEdldHMgcmVtYWluZGVyIHRoYXQgaXMgbm9uLW5lZ2F0aXZlLCBldmVuIGlmIGZpcnN0IG51bWJlciBpcyBuZWdhdGl2ZSAqL1xuZnVuY3Rpb24gZXVjbGlkZWFuTW9kdWxvKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKChhICUgYikgKyBiKSAlIGI7XG59XG4iLCI8dGFibGUgY2xhc3M9XCJhc3ctY2FsZW5kYXItdGFibGVcIiByb2xlPVwiZ3JpZFwiPlxyXG4gICAgPHRoZWFkIGNsYXNzPVwiYXN3LWNhbGVuZGFyLXRhYmxlLWhlYWRlclwiPjwvdGhlYWQ+XHJcbiAgICA8dGJvZHkgYXN3LWNhbGVuZGFyLWJvZHlcclxuICAgICAgICAoQHNsaWRlQ2FsZW5kYXIuZG9uZSk9XCJfY2FsZW5kYXJTdGF0ZURvbmUoKVwiXHJcbiAgICAgICAgW0BzbGlkZUNhbGVuZGFyXT1cIl9jYWxlbmRhclN0YXRlXCJcclxuICAgICAgICBbdG9kYXlWYWx1ZV09XCJfdG9kYXlZZWFyXCJcclxuICAgICAgICBbcm93c109XCJfeWVhcnNcIlxyXG4gICAgICAgIFtudW1Db2xzXT1cIjRcIlxyXG4gICAgICAgIFthY3RpdmVDZWxsXT1cIl9nZXRBY3RpdmVDZWxsKClcIlxyXG4gICAgICAgIFthbGxvd0Rpc2FibGVkU2VsZWN0aW9uXT1cInRydWVcIlxyXG4gICAgICAgIFtzZWxlY3RlZFZhbHVlXT1cIl9zZWxlY3RlZFllYXIhXCJcclxuICAgICAgICAoc2VsZWN0ZWRWYWx1ZUNoYW5nZSk9XCJfeWVhclNlbGVjdGVkKCRldmVudClcIj5cclxuICAgIDwvdGJvZHk+XHJcbjwvdGFibGU+XHJcbiJdfQ==