UNPKG

@asadi/angular-date-components

Version:

`Angular Date Components` is a comprehensive angular library of date-related components designed to meet the needs of applications that require localization based on various calendar systems. While the package currently includes two powerful components (S

125 lines 29.8 kB
import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, EventEmitter, inject, Input, Output, Renderer2, ViewChild } from '@angular/core'; import { TableViewControllerDirective } from '../../directives/table-view-controller.directive'; import { ADC_OPTIONS } from '../../injection-token'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; /** * A reusable and customizable table component for displaying date-related data. * The `adc-table` component is designed for use within the Angular Date Components package. * It supports features like row and column labels, custom cell event builders, and date range selection. * * The component allows for displaying a dynamic table with custom rows, columns, and cells. * It supports both left-to-right (`ltr`) and right-to-left (`rtl`) layouts. * * ### Features * - Dynamically updates the table view when cell data changes. * - Supports date filtering and custom event builders for handling cell events. * - Emits an event when a date range is selected. * * @example * ```html * <adc-table * [Rows]="tableRows" * [Columns]="tableColumns" * [Cells]="tableCells" * [Title]="'My Schedule'" * [TitleClass]="'table-title'" * [ShowRowLabels]="true" * [ShowColumnLabels]="false" * [Dir]="'ltr'" * [DateFilter]="customDateFilter" * [EventBuilder]="eventBuilderInstance" * (DateRangeSelect)="onDateRangeSelect($event)"> * </adc-table> * ``` * * @example * ```typescript * // In your component class * tableRows: ADCITableRow[] = [...]; * tableColumns: ADCITableColumn[] = [...]; * tableCells: ADCITableCell[] = [...]; * * onDateRangeSelect(selectedCells: ADCITableCell[]) { * console.log('Selected cells:', selectedCells); * } * ``` */ export class ADCTableComponent { constructor() { this.options = inject(ADC_OPTIONS); this.renderer = inject(Renderer2); /** * An array of rows to display in the table. */ this.tableRows = []; /** * a boolean which determines if row details should be displayed or not */ this.showRow = true; /** * * The title displayed above the table. */ this.title = ''; /** * CSS classes to apply to the title. */ this.titleClassList = ''; this.viewReadyEvent = new EventEmitter(); this.maxHeight = null; } ngOnInit() { this.maxHeight = `${window.innerHeight - 250}px`; } ngAfterViewInit() { if (this.viewCtrl == null) return; if (this.eventBuilder) { if (this.viewCtrl == null) return; this.eventBuilder.init(this.renderer, this.viewCtrl, this.options); } if (this.selectionManager) { this.selectionManager.init(this.viewCtrl); } } onViewReady() { this.viewReadyEvent.emit(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: ADCTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.7", type: ADCTableComponent, isStandalone: true, selector: "adc-table", inputs: { tableRows: ["rows", "tableRows"], showRow: ["showRowDetails", "showRow"], title: "title", titleClassList: ["titleClass", "titleClassList"], eventBuilder: "eventBuilder", selectionManager: "selectionManager" }, outputs: { viewReadyEvent: "viewReady" }, viewQueries: [{ propertyName: "viewCtrl", first: true, predicate: TableViewControllerDirective, descendants: true }], ngImport: i0, template: "\r\n<div [dir]=\"options.direction\">\r\n\r\n <div [classList]=\"titleClassList + ' font-bold text-xl'\" style=\"border-bottom: 1px solid #000; text-align: center;\">\r\n {{title}}\r\n </div>\r\n\r\n <div [style.maxHeight]=\"maxHeight\" style=\"overflow: scroll;min-height: 300px;\">\r\n\r\n <div style=\"flex: 1;display: flex;flex-direction: column;\" class=\"adc-table\" tableViewController (viewReady)=\"onViewReady()\">\r\n\r\n <ng-container *ngFor=\"let row of tableRows; let lastRow = last; let rowIndex = index\">\r\n \r\n <div class=\"row\" style=\"position: relative;flex-shrink: 0;\" [attr.sticky]=\"rowIndex == 0\" \r\n [class.sticky]=\"rowIndex == 0\" [class.vertical-stick]=\"rowIndex == 0\" [attr.row-index]=\"rowIndex\">\r\n \r\n <!-- cells - columns -->\r\n <div style=\"display: flex;flex-direction: row;flex-wrap: nowrap;flex: 1;height: 100%;\" cells>\r\n \r\n <ng-container *ngIf=\"showRow\">\r\n \r\n <div style=\"min-width: 100px;display: flex;flex-direction: column;overflow: hidden;\r\n padding: 6px;\" [style.justifyContent]=\"row.verticalAlign\" [style.alignItems]=\"row.horizontalAlign\"\r\n [classList]=\"row.classList + ' column column-border sticky horizontal-stick'\" detail=\"true\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\">\r\n \r\n <span class=\"label\">{{row.prefix}}</span>\r\n <span class=\"label\">{{row.label}}</span>\r\n <span class=\"label\">{{row.suffix}}</span>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n <ng-container *ngFor=\"let column of row.columns; let lastColumn = last; let columnIndex = index\">\r\n <div style=\"min-width: 50px;display: flex;flex-direction: column;overflow: hidden;\r\n white-space: nowrap;text-overflow: ellipsis;padding: 6px;flex: 1;\" [style.justifyContent]=\"column.verticalAlign\" [attr.selectable]=\"column.selectable\"\r\n [classList]=\"column.classList + ' column'\" [attr.columnValue]=\"column.value\" [style.alignItems]=\"column.horizontalAlign\"\r\n [attr.rowValue]=\"row.value\" [attr.rowIndex]=\"rowIndex\" [attr.columnIndex]=\"columnIndex\"\r\n [ngClass]=\"{'column-border': !lastColumn}\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\" detail=\"false\">\r\n \r\n <span class=\"label\">{{column.prefix}}</span>\r\n <span class=\"label\">{{column.label}}</span>\r\n <span class=\"label\">{{column.suffix}}</span>\r\n \r\n </div>\r\n </ng-container>\r\n \r\n </div>\r\n \r\n <!-- events -->\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 1;pointer-events: none;\" events></div>\r\n\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 3;pointer-events: none;\" tooltip></div>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n </div>\r\n\r\n </div>\r\n\r\n</div>\r\n", styles: ["[dir=rtl] .column-border{border-left:1px solid #000}[dir=ltr] .column-border{border-right:1px solid #000}[dir=ltr] .adc-table{transform-origin:left top}[dir=rtl] .adc-table{transform-origin:right top}.adc-table{transition:transform;transition-duration:.2s;transition-timing-function:ease-out;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smooth:always}.row .column:nth-child(2n):not(.today){background-color:#f0f0f0}.row .column:nth-child(odd):not(.today){background-color:#fff}.sticky{position:sticky!important;z-index:9}[dir=ltr] .sticky.horizontal-stick{left:0}[dir=rtl] .sticky.horizontal-stick{right:0}.sticky.vertical-stick{top:0}.today{background-color:#f7ffac}[selectable=true]:not([invalid]):hover{cursor:pointer;box-shadow:inset 0 1px 3px #00000080}[selectable=true][invalid]:hover{cursor:not-allowed}.unavailable{opacity:.5}.holiday{color:red}[dir=rtl]{text-align:right}[dir=ltr]{text-align:left}.label{white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden}[selectable=true][pointed]:not([invalid]):not([selected]){background-color:#c384ff80!important;opacity:1!important}[selectable=true][selected]:not([invalid]){background-color:#c384ff!important;opacity:1!important}[selectable=true][invalid]{background-color:#aaa!important;opacity:1!important}[dir=rtl] .table-event.event-start-day{border-top-right-radius:15px;border-bottom-right-radius:15px}[dir=ltr] .table-event.event-start-day,[dir=rtl] .table-event.event-end-day{border-top-left-radius:15px;border-bottom-left-radius:15px}[dir=ltr] .table-event.event-end-day{border-top-right-radius:15px;border-bottom-right-radius:15px}.table-event{overflow:hidden;position:absolute;display:flex;justify-content:center;align-items:center;font-weight:400;font-size:clamp(10px,14px,16px);line-height:22px;z-index:9;color:#fff;text-wrap:nowrap;pointer-events:fill}.tooltip{position:absolute;background-color:#000c;color:#fff;padding:5px 10px;border-radius:4px;pointer-events:none;white-space:nowrap;z-index:1000;overflow:hidden;max-width:350px;white-space:break-word;text-wrap:wrap;word-break:break-all}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: TableViewControllerDirective, selector: "[tableViewController]", outputs: ["viewReady"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: ADCTableComponent, decorators: [{ type: Component, args: [{ selector: 'adc-table', standalone: true, imports: [ CommonModule, TableViewControllerDirective, ], changeDetection: ChangeDetectionStrategy.OnPush, template: "\r\n<div [dir]=\"options.direction\">\r\n\r\n <div [classList]=\"titleClassList + ' font-bold text-xl'\" style=\"border-bottom: 1px solid #000; text-align: center;\">\r\n {{title}}\r\n </div>\r\n\r\n <div [style.maxHeight]=\"maxHeight\" style=\"overflow: scroll;min-height: 300px;\">\r\n\r\n <div style=\"flex: 1;display: flex;flex-direction: column;\" class=\"adc-table\" tableViewController (viewReady)=\"onViewReady()\">\r\n\r\n <ng-container *ngFor=\"let row of tableRows; let lastRow = last; let rowIndex = index\">\r\n \r\n <div class=\"row\" style=\"position: relative;flex-shrink: 0;\" [attr.sticky]=\"rowIndex == 0\" \r\n [class.sticky]=\"rowIndex == 0\" [class.vertical-stick]=\"rowIndex == 0\" [attr.row-index]=\"rowIndex\">\r\n \r\n <!-- cells - columns -->\r\n <div style=\"display: flex;flex-direction: row;flex-wrap: nowrap;flex: 1;height: 100%;\" cells>\r\n \r\n <ng-container *ngIf=\"showRow\">\r\n \r\n <div style=\"min-width: 100px;display: flex;flex-direction: column;overflow: hidden;\r\n padding: 6px;\" [style.justifyContent]=\"row.verticalAlign\" [style.alignItems]=\"row.horizontalAlign\"\r\n [classList]=\"row.classList + ' column column-border sticky horizontal-stick'\" detail=\"true\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\">\r\n \r\n <span class=\"label\">{{row.prefix}}</span>\r\n <span class=\"label\">{{row.label}}</span>\r\n <span class=\"label\">{{row.suffix}}</span>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n <ng-container *ngFor=\"let column of row.columns; let lastColumn = last; let columnIndex = index\">\r\n <div style=\"min-width: 50px;display: flex;flex-direction: column;overflow: hidden;\r\n white-space: nowrap;text-overflow: ellipsis;padding: 6px;flex: 1;\" [style.justifyContent]=\"column.verticalAlign\" [attr.selectable]=\"column.selectable\"\r\n [classList]=\"column.classList + ' column'\" [attr.columnValue]=\"column.value\" [style.alignItems]=\"column.horizontalAlign\"\r\n [attr.rowValue]=\"row.value\" [attr.rowIndex]=\"rowIndex\" [attr.columnIndex]=\"columnIndex\"\r\n [ngClass]=\"{'column-border': !lastColumn}\" [style.borderBottom]=\"lastRow ? 'none' : '1px solid #000'\" detail=\"false\">\r\n \r\n <span class=\"label\">{{column.prefix}}</span>\r\n <span class=\"label\">{{column.label}}</span>\r\n <span class=\"label\">{{column.suffix}}</span>\r\n \r\n </div>\r\n </ng-container>\r\n \r\n </div>\r\n \r\n <!-- events -->\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 1;pointer-events: none;\" events></div>\r\n\r\n <div style=\"position: absolute;height: 100%;width: 100%;left: 0;top: 0;z-index: 3;pointer-events: none;\" tooltip></div>\r\n \r\n </div>\r\n \r\n </ng-container>\r\n \r\n </div>\r\n\r\n </div>\r\n\r\n</div>\r\n", styles: ["[dir=rtl] .column-border{border-left:1px solid #000}[dir=ltr] .column-border{border-right:1px solid #000}[dir=ltr] .adc-table{transform-origin:left top}[dir=rtl] .adc-table{transform-origin:right top}.adc-table{transition:transform;transition-duration:.2s;transition-timing-function:ease-out;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smooth:always}.row .column:nth-child(2n):not(.today){background-color:#f0f0f0}.row .column:nth-child(odd):not(.today){background-color:#fff}.sticky{position:sticky!important;z-index:9}[dir=ltr] .sticky.horizontal-stick{left:0}[dir=rtl] .sticky.horizontal-stick{right:0}.sticky.vertical-stick{top:0}.today{background-color:#f7ffac}[selectable=true]:not([invalid]):hover{cursor:pointer;box-shadow:inset 0 1px 3px #00000080}[selectable=true][invalid]:hover{cursor:not-allowed}.unavailable{opacity:.5}.holiday{color:red}[dir=rtl]{text-align:right}[dir=ltr]{text-align:left}.label{white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden}[selectable=true][pointed]:not([invalid]):not([selected]){background-color:#c384ff80!important;opacity:1!important}[selectable=true][selected]:not([invalid]){background-color:#c384ff!important;opacity:1!important}[selectable=true][invalid]{background-color:#aaa!important;opacity:1!important}[dir=rtl] .table-event.event-start-day{border-top-right-radius:15px;border-bottom-right-radius:15px}[dir=ltr] .table-event.event-start-day,[dir=rtl] .table-event.event-end-day{border-top-left-radius:15px;border-bottom-left-radius:15px}[dir=ltr] .table-event.event-end-day{border-top-right-radius:15px;border-bottom-right-radius:15px}.table-event{overflow:hidden;position:absolute;display:flex;justify-content:center;align-items:center;font-weight:400;font-size:clamp(10px,14px,16px);line-height:22px;z-index:9;color:#fff;text-wrap:nowrap;pointer-events:fill}.tooltip{position:absolute;background-color:#000c;color:#fff;padding:5px 10px;border-radius:4px;pointer-events:none;white-space:nowrap;z-index:1000;overflow:hidden;max-width:350px;white-space:break-word;text-wrap:wrap;word-break:break-all}\n"] }] }], propDecorators: { tableRows: [{ type: Input, args: ['rows'] }], showRow: [{ type: Input, args: ['showRowDetails'] }], title: [{ type: Input, args: ['title'] }], titleClassList: [{ type: Input, args: ['titleClass'] }], eventBuilder: [{ type: Input, args: ["eventBuilder"] }], selectionManager: [{ type: Input, args: ['selectionManager'] }], viewCtrl: [{ type: ViewChild, args: [TableViewControllerDirective] }], viewReadyEvent: [{ type: Output, args: ['viewReady'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRjLXRhYmxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FzYWRpL2FuZ3VsYXItZGF0ZS1jb21wb25lbnRzL2NvcmUvc3JjL2NvbXBvbmVudHMvYWRjLXRhYmxlL2FkYy10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hc2FkaS9hbmd1bGFyLWRhdGUtY29tcG9uZW50cy9jb3JlL3NyYy9jb21wb25lbnRzL2FkYy10YWJsZS9hZGMtdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXJKLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBSXBEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlDRztBQVlILE1BQU0sT0FBTyxpQkFBaUI7SUFYOUI7UUFhVyxZQUFPLEdBQUcsTUFBTSxDQUFjLFdBQVcsQ0FBQyxDQUFDO1FBQzNDLGFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFcEM7O1NBRUM7UUFFSCxjQUFTLEdBQW1CLEVBQUUsQ0FBQztRQUU3Qjs7U0FFQztRQUVILFlBQU8sR0FBWSxJQUFJLENBQUM7UUFFdEI7OztTQUdDO1FBRUgsVUFBSyxHQUFXLEVBQUUsQ0FBQztRQUVqQjs7U0FFQztRQUVILG1CQUFjLEdBQVcsRUFBRSxDQUFDO1FBWTVCLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUUxQyxjQUFTLEdBQWtCLElBQUksQ0FBQztLQThCakM7SUE1QkMsUUFBUTtRQUVOLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxNQUFNLENBQUMsV0FBVyxHQUFHLEdBQUcsSUFBSSxDQUFDO0lBQ25ELENBQUM7SUFHRCxlQUFlO1FBRWIsSUFBRyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUk7WUFBRSxPQUFPO1FBRWpDLElBQUcsSUFBSSxDQUFDLFlBQVksRUFDcEI7WUFDRSxJQUFHLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSTtnQkFBRSxPQUFPO1lBRWpDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDcEU7UUFFRCxJQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFDeEI7WUFDRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUMzQztJQUNILENBQUM7SUFFRCxXQUFXO1FBRVQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM3QixDQUFDOzhHQXRFVSxpQkFBaUI7a0dBQWpCLGlCQUFpQixxWEFvQ2pCLDRCQUE0QixnRENqR3pDLDBnSEErREEsbW5FRFRJLFlBQVksOFZBQ1osNEJBQTRCOzsyRkFNbkIsaUJBQWlCO2tCQVg3QixTQUFTOytCQUNFLFdBQVcsY0FDVCxJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWiw0QkFBNEI7cUJBQzdCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzhCQVcvQyxTQUFTO3NCQURSLEtBQUs7dUJBQUMsTUFBTTtnQkFPYixPQUFPO3NCQUROLEtBQUs7dUJBQUMsZ0JBQWdCO2dCQVF2QixLQUFLO3NCQURKLEtBQUs7dUJBQUMsT0FBTztnQkFPZCxjQUFjO3NCQURiLEtBQUs7dUJBQUMsWUFBWTtnQkFJbkIsWUFBWTtzQkFEWCxLQUFLO3VCQUFDLGNBQWM7Z0JBSXJCLGdCQUFnQjtzQkFEZixLQUFLO3VCQUFDLGtCQUFrQjtnQkFJakIsUUFBUTtzQkFEZixTQUFTO3VCQUFDLDRCQUE0QjtnQkFJdkMsY0FBYztzQkFEYixNQUFNO3VCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIGluamVjdCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBSZW5kZXJlcjIsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBBRENJVGFibGVSb3csIEFEQ0lPcHRpb25zIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgVGFibGVWaWV3Q29udHJvbGxlckRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvdGFibGUtdmlldy1jb250cm9sbGVyLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEFEQ19PUFRJT05TIH0gZnJvbSAnLi4vLi4vaW5qZWN0aW9uLXRva2VuJztcclxuaW1wb3J0IHsgVGFibGVTZWxlY3Rpb24gfSBmcm9tICcuLi8uLi90YWJsZS1zZWxlY3Rpb24nO1xyXG5pbXBvcnQgeyBGbGF0RXZlbnRCdWlsZGVyIH0gZnJvbSAnLi4vLi4vZmxhdC1ldmVudC1idWlsZGVyJztcclxuXHJcbi8qKlxyXG4gKiBBIHJldXNhYmxlIGFuZCBjdXN0b21pemFibGUgdGFibGUgY29tcG9uZW50IGZvciBkaXNwbGF5aW5nIGRhdGUtcmVsYXRlZCBkYXRhLlxyXG4gKiBUaGUgYGFkYy10YWJsZWAgY29tcG9uZW50IGlzIGRlc2lnbmVkIGZvciB1c2Ugd2l0aGluIHRoZSBBbmd1bGFyIERhdGUgQ29tcG9uZW50cyBwYWNrYWdlLlxyXG4gKiBJdCBzdXBwb3J0cyBmZWF0dXJlcyBsaWtlIHJvdyBhbmQgY29sdW1uIGxhYmVscywgY3VzdG9tIGNlbGwgZXZlbnQgYnVpbGRlcnMsIGFuZCBkYXRlIHJhbmdlIHNlbGVjdGlvbi5cclxuICpcclxuICogVGhlIGNvbXBvbmVudCBhbGxvd3MgZm9yIGRpc3BsYXlpbmcgYSBkeW5hbWljIHRhYmxlIHdpdGggY3VzdG9tIHJvd3MsIGNvbHVtbnMsIGFuZCBjZWxscy5cclxuICogSXQgc3VwcG9ydHMgYm90aCBsZWZ0LXRvLXJpZ2h0IChgbHRyYCkgYW5kIHJpZ2h0LXRvLWxlZnQgKGBydGxgKSBsYXlvdXRzLlxyXG4gKiBcclxuICogIyMjIEZlYXR1cmVzXHJcbiAqIC0gRHluYW1pY2FsbHkgdXBkYXRlcyB0aGUgdGFibGUgdmlldyB3aGVuIGNlbGwgZGF0YSBjaGFuZ2VzLlxyXG4gKiAtIFN1cHBvcnRzIGRhdGUgZmlsdGVyaW5nIGFuZCBjdXN0b20gZXZlbnQgYnVpbGRlcnMgZm9yIGhhbmRsaW5nIGNlbGwgZXZlbnRzLlxyXG4gKiAtIEVtaXRzIGFuIGV2ZW50IHdoZW4gYSBkYXRlIHJhbmdlIGlzIHNlbGVjdGVkLlxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGBodG1sXHJcbiAqIDxhZGMtdGFibGVcclxuICogICBbUm93c109XCJ0YWJsZVJvd3NcIlxyXG4gKiAgIFtDb2x1bW5zXT1cInRhYmxlQ29sdW1uc1wiXHJcbiAqICAgW0NlbGxzXT1cInRhYmxlQ2VsbHNcIlxyXG4gKiAgIFtUaXRsZV09XCInTXkgU2NoZWR1bGUnXCJcclxuICogICBbVGl0bGVDbGFzc109XCIndGFibGUtdGl0bGUnXCJcclxuICogICBbU2hvd1Jvd0xhYmVsc109XCJ0cnVlXCJcclxuICogICBbU2hvd0NvbHVtbkxhYmVsc109XCJmYWxzZVwiXHJcbiAqICAgW0Rpcl09XCInbHRyJ1wiXHJcbiAqICAgW0RhdGVGaWx0ZXJdPVwiY3VzdG9tRGF0ZUZpbHRlclwiXHJcbiAqICAgW0V2ZW50QnVpbGRlcl09XCJldmVudEJ1aWxkZXJJbnN0YW5jZVwiXHJcbiAqICAgKERhdGVSYW5nZVNlbGVjdCk9XCJvbkRhdGVSYW5nZVNlbGVjdCgkZXZlbnQpXCI+XHJcbiAqIDwvYWRjLXRhYmxlPlxyXG4gKiBgYGBcclxuICogXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYHR5cGVzY3JpcHRcclxuICogLy8gSW4geW91ciBjb21wb25lbnQgY2xhc3NcclxuICogdGFibGVSb3dzOiBBRENJVGFibGVSb3dbXSA9IFsuLi5dO1xyXG4gKiB0YWJsZUNvbHVtbnM6IEFEQ0lUYWJsZUNvbHVtbltdID0gWy4uLl07XHJcbiAqIHRhYmxlQ2VsbHM6IEFEQ0lUYWJsZUNlbGxbXSA9IFsuLi5dO1xyXG4gKiBcclxuICogb25EYXRlUmFuZ2VTZWxlY3Qoc2VsZWN0ZWRDZWxsczogQURDSVRhYmxlQ2VsbFtdKSB7XHJcbiAqICAgY29uc29sZS5sb2coJ1NlbGVjdGVkIGNlbGxzOicsIHNlbGVjdGVkQ2VsbHMpO1xyXG4gKiB9XHJcbiAqIGBgYFxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdhZGMtdGFibGUnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgQ29tbW9uTW9kdWxlLFxyXG4gICAgVGFibGVWaWV3Q29udHJvbGxlckRpcmVjdGl2ZSxcclxuICBdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9hZGMtdGFibGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2FkYy10YWJsZS5jb21wb25lbnQuY3NzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcclxufSlcclxuZXhwb3J0IGNsYXNzIEFEQ1RhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25Jbml0e1xyXG5cclxuICByZWFkb25seSBvcHRpb25zID0gaW5qZWN0PEFEQ0lPcHRpb25zPihBRENfT1BUSU9OUyk7XHJcbiAgcmVhZG9ubHkgcmVuZGVyZXIgPSBpbmplY3QoUmVuZGVyZXIyKTtcclxuXHJcbiAgICAvKipcclxuICAgKiBBbiBhcnJheSBvZiByb3dzIHRvIGRpc3BsYXkgaW4gdGhlIHRhYmxlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgncm93cycpXHJcbiAgdGFibGVSb3dzOiBBRENJVGFibGVSb3dbXSA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAqIGEgYm9vbGVhbiB3aGljaCBkZXRlcm1pbmVzIGlmIHJvdyBkZXRhaWxzIHNob3VsZCBiZSBkaXNwbGF5ZWQgb3Igbm90XHJcbiAgICovXHJcbiAgQElucHV0KCdzaG93Um93RGV0YWlscycpXHJcbiAgc2hvd1JvdzogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBcclxuICAgKiBUaGUgdGl0bGUgZGlzcGxheWVkIGFib3ZlIHRoZSB0YWJsZS5cclxuICAgKi9cclxuICBASW5wdXQoJ3RpdGxlJylcclxuICB0aXRsZTogc3RyaW5nID0gJyc7XHJcblxyXG4gICAgLyoqXHJcbiAgICogQ1NTIGNsYXNzZXMgdG8gYXBwbHkgdG8gdGhlIHRpdGxlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgndGl0bGVDbGFzcycpXHJcbiAgdGl0bGVDbGFzc0xpc3Q6IHN0cmluZyA9ICcnO1xyXG5cclxuICBASW5wdXQoXCJldmVudEJ1aWxkZXJcIilcclxuICBldmVudEJ1aWxkZXIhOiBGbGF0RXZlbnRCdWlsZGVyO1xyXG5cclxuICBASW5wdXQoJ3NlbGVjdGlvbk1hbmFnZXInKVxyXG4gIHNlbGVjdGlvbk1hbmFnZXIhOiBUYWJsZVNlbGVjdGlvbjtcclxuXHJcbiAgQFZpZXdDaGlsZChUYWJsZVZpZXdDb250cm9sbGVyRGlyZWN0aXZlKVxyXG4gIHByaXZhdGUgdmlld0N0cmwhOiBUYWJsZVZpZXdDb250cm9sbGVyRGlyZWN0aXZlO1xyXG5cclxuICBAT3V0cHV0KCd2aWV3UmVhZHknKVxyXG4gIHZpZXdSZWFkeUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICBtYXhIZWlnaHQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIFxyXG4gIHtcclxuICAgIHRoaXMubWF4SGVpZ2h0ID0gYCR7d2luZG93LmlubmVySGVpZ2h0IC0gMjUwfXB4YDtcclxuICB9XHJcblxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCBcclxuICB7XHJcbiAgICBpZih0aGlzLnZpZXdDdHJsID09IG51bGwpIHJldHVybjtcclxuXHJcbiAgICBpZih0aGlzLmV2ZW50QnVpbGRlcilcclxuICAgIHtcclxuICAgICAgaWYodGhpcy52aWV3Q3RybCA9PSBudWxsKSByZXR1cm47XHJcbiAgICAgIFxyXG4gICAgICB0aGlzLmV2ZW50QnVpbGRlci5pbml0KHRoaXMucmVuZGVyZXIsIHRoaXMudmlld0N0cmwsIHRoaXMub3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYodGhpcy5zZWxlY3Rpb25NYW5hZ2VyKVxyXG4gICAge1xyXG4gICAgICB0aGlzLnNlbGVjdGlvbk1hbmFnZXIuaW5pdCh0aGlzLnZpZXdDdHJsKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uVmlld1JlYWR5KCk6IHZvaWRcclxuICB7XHJcbiAgICB0aGlzLnZpZXdSZWFkeUV2ZW50LmVtaXQoKTtcclxuICB9XHJcblxyXG59XHJcbiIsIlxyXG48ZGl2IFtkaXJdPVwib3B0aW9ucy5kaXJlY3Rpb25cIj5cclxuXHJcbiAgICA8ZGl2IFtjbGFzc0xpc3RdPVwidGl0bGVDbGFzc0xpc3QgKyAnIGZvbnQtYm9sZCB0ZXh0LXhsJ1wiIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICMwMDA7IHRleHQtYWxpZ246IGNlbnRlcjtcIj5cclxuICAgICAgICB7e3RpdGxlfX1cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgW3N0eWxlLm1heEhlaWdodF09XCJtYXhIZWlnaHRcIiBzdHlsZT1cIm92ZXJmbG93OiBzY3JvbGw7bWluLWhlaWdodDogMzAwcHg7XCI+XHJcblxyXG4gICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OiAxO2Rpc3BsYXk6IGZsZXg7ZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcIiBjbGFzcz1cImFkYy10YWJsZVwiIHRhYmxlVmlld0NvbnRyb2xsZXIgKHZpZXdSZWFkeSk9XCJvblZpZXdSZWFkeSgpXCI+XHJcblxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByb3cgb2YgdGFibGVSb3dzOyBsZXQgbGFzdFJvdyA9IGxhc3Q7IGxldCByb3dJbmRleCA9IGluZGV4XCI+XHJcbiAgICBcclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiBzdHlsZT1cInBvc2l0aW9uOiByZWxhdGl2ZTtmbGV4LXNocmluazogMDtcIiBbYXR0ci5zdGlja3ldPVwicm93SW5kZXggPT0gMFwiIFxyXG4gICAgICAgICAgICAgICAgW2NsYXNzLnN0aWNreV09XCJyb3dJbmRleCA9PSAwXCIgW2NsYXNzLnZlcnRpY2FsLXN0aWNrXT1cInJvd0luZGV4ID09IDBcIiBbYXR0ci5yb3ctaW5kZXhdPVwicm93SW5kZXhcIj5cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gY2VsbHMgLSBjb2x1bW5zIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4O2ZsZXgtZGlyZWN0aW9uOiByb3c7ZmxleC13cmFwOiBub3dyYXA7ZmxleDogMTtoZWlnaHQ6IDEwMCU7XCIgY2VsbHM+XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3dSb3dcIj5cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cIm1pbi13aWR0aDogMTAwcHg7ZGlzcGxheTogZmxleDtmbGV4LWRpcmVjdGlvbjogY29sdW1uO292ZXJmbG93OiBoaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogNnB4O1wiIFtzdHlsZS5qdXN0aWZ5Q29udGVudF09XCJyb3cudmVydGljYWxBbGlnblwiIFtzdHlsZS5hbGlnbkl0ZW1zXT1cInJvdy5ob3Jpem9udGFsQWxpZ25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc0xpc3RdPVwicm93LmNsYXNzTGlzdCArICcgY29sdW1uIGNvbHVtbi1ib3JkZXIgc3RpY2t5IGhvcml6b250YWwtc3RpY2snXCIgZGV0YWlsPVwidHJ1ZVwiIFtzdHlsZS5ib3JkZXJCb3R0b21dPVwibGFzdFJvdyA/ICdub25lJyA6ICcxcHggc29saWQgIzAwMCdcIj5cclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+e3tyb3cucHJlZml4fX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPnt7cm93LmxhYmVsfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPnt7cm93LnN1ZmZpeH19PC9zcGFuPlxyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiByb3cuY29sdW1uczsgbGV0IGxhc3RDb2x1bW4gPSBsYXN0OyBsZXQgY29sdW1uSW5kZXggPSBpbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cIm1pbi13aWR0aDogNTBweDtkaXNwbGF5OiBmbGV4O2ZsZXgtZGlyZWN0aW9uOiBjb2x1bW47b3ZlcmZsb3c6IGhpZGRlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7dGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7cGFkZGluZzogNnB4O2ZsZXg6IDE7XCIgW3N0eWxlLmp1c3RpZnlDb250ZW50XT1cImNvbHVtbi52ZXJ0aWNhbEFsaWduXCIgW2F0dHIuc2VsZWN0YWJsZV09XCJjb2x1bW4uc2VsZWN0YWJsZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NMaXN0XT1cImNvbHVtbi5jbGFzc0xpc3QgKyAnIGNvbHVtbidcIiBbYXR0ci5jb2x1bW5WYWx1ZV09XCJjb2x1bW4udmFsdWVcIiBbc3R5bGUuYWxpZ25JdGVtc109XCJjb2x1bW4uaG9yaXpvbnRhbEFsaWduXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLnJvd1ZhbHVlXT1cInJvdy52YWx1ZVwiIFthdHRyLnJvd0luZGV4XT1cInJvd0luZGV4XCIgW2F0dHIuY29sdW1uSW5kZXhdPVwiY29sdW1uSW5kZXhcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydjb2x1bW4tYm9yZGVyJzogIWxhc3RDb2x1bW59XCIgW3N0eWxlLmJvcmRlckJvdHRvbV09XCJsYXN0Um93ID8gJ25vbmUnIDogJzFweCBzb2xpZCAjMDAwJ1wiIGRldGFpbD1cImZhbHNlXCI+XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPnt7Y29sdW1uLnByZWZpeH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj57e2NvbHVtbi5sYWJlbH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj57e2NvbHVtbi5zdWZmaXh9fTwvc3Bhbj5cclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBldmVudHMgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTtoZWlnaHQ6IDEwMCU7d2lkdGg6IDEwMCU7bGVmdDogMDt0b3A6IDA7ei1pbmRleDogMTtwb2ludGVyLWV2ZW50czogbm9uZTtcIiBldmVudHM+PC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7aGVpZ2h0OiAxMDAlO3dpZHRoOiAxMDAlO2xlZnQ6IDA7dG9wOiAwO3otaW5kZXg6IDM7cG9pbnRlci1ldmVudHM6IG5vbmU7XCIgdG9vbHRpcD48L2Rpdj5cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICBcclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICBcclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICA8L2Rpdj5cclxuXHJcbjwvZGl2PlxyXG4iXX0=