UNPKG

stimulsoft-viewer-angular

Version:

The Viewer component is designed to view reports and dashboards in the web browser.

291 lines (279 loc) 32.3 kB
import { Component, Input } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "../services/model.service"; import * as i2 from "../services/helper.service"; import * as i3 from "@angular/common"; import * as i4 from "../controls/button.component"; import * as i5 from "../controls/text-box.componet"; import * as i6 from "../controls/drop-down-list.component"; import * as i7 from "../controls/date-picker-day-button.component"; export class DatePickerMenuComponent { constructor(model, helper) { this.model = model; this.helper = helper; this.keyTo = false; this.closeOnAction = true; this.monthesForDatePickerItems = []; this.cols = [0, 1, 2, 3, 4, 5, 6]; this.rows = [0, 1, 2, 3, 4, 5]; this.model.months.forEach((m, i) => this.monthesForDatePickerItems.push({ name: 'Month' + i, caption: this.model.loc('Month' + m), key: i })); const firstLetters = {}; this.model.dayOfWeek.forEach((d) => { const dayName = this.model.loc('Day' + d); firstLetters[dayName.toString().substring(0, 1).toUpperCase()] = true; }); this.countLetters = Object.keys(firstLetters).length < 5 ? 2 : 1; } ngOnInit() { } getButtonSelected(col, row) { const firstDay = this.getFirstDay(); const curDay = row * 7 + col; const day = curDay - firstDay + 1; return day === this.key.day; } getButtonCaption(col, row) { const firstDay = this.getFirstDay(); const daysInMonth = this.helper.getCountDaysOfMonth(this.key.year, this.key.month - 1); const curDay = row * 7 + col; const day = curDay - firstDay + 1; if (curDay >= firstDay && day <= daysInMonth) { return day.toString(); } return ''; } getTime() { return this.helper.formatDate(this.helper.getDate(this.key), 'H:mm:ss'); } getFirstDay() { let firstDay = new Date(this.key.year, this.key.month - 1, 1).getDay(); if (firstDay === 0) { firstDay = 7; } if (this.model.options.appearance.datePickerFirstDayOfWeek !== 'Sunday') { firstDay--; } return firstDay; } get showTime() { return this.menu?.params?.dateTimeType !== 'Date'; } get key() { return this.keyTo ? this.menu.params.keyTo : this.menu.params.key; } yearAction(input) { try { this.key.year = parseInt(input.value, 10); } catch { } } timeAction(input) { const time = this.helper.stringToTime(input.value); this.key.seconds = time.seconds; this.key.minutes = time.minutes; this.key.hours = time.hours; } getShortDayName(index) { const dayName = this.model.loc('Day' + this.model.dayOfWeek[index]); if (dayName) { return dayName.toString().substring(0, this.countLetters <= dayName.length ? this.countLetters : 1).toUpperCase(); } return ''; } getShortDayColor(index) { if (index === (this.model.options.appearance.datePickerFirstDayOfWeek === 'Sunday' ? 6 : 5)) { return '#0000ff'; } if (index === (this.model.options.appearance.datePickerFirstDayOfWeek === 'Sunday' ? 0 : 6)) { return '#ff0000'; } return ''; } prevMonthButtonAction() { let month = this.key.month; let year = this.key.year; month--; if (month === 0) { month = 12; year--; } const countDaysInMonth = this.helper.getCountDaysOfMonth(year, month - 1); if (countDaysInMonth < this.key.day) { this.key.day = countDaysInMonth; } this.key.month = month; this.key.year = year; } nextMonthButtonAction() { let month = this.key.month; let year = this.key.year; month++; if (month === 13) { month = 1; year++; } const countDaysInMonth = this.helper.getCountDaysOfMonth(year, month - 1); if (countDaysInMonth < this.key.day) { this.key.day = countDaysInMonth; } this.key.month = month; this.key.year = year; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatePickerMenuComponent, deps: [{ token: i1.ModelService }, { token: i2.HelperService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DatePickerMenuComponent, selector: "sti-date-picker-menu", inputs: { menu: "menu", keyTo: "keyTo", closeOnAction: "closeOnAction" }, ngImport: i0, template: ` <table class="stiJsViewerClearAllStyles" cellpadding="0" cellspacing="0"> <tbody> <tr class="stiJsViewerClearAllStyles"> <td class="stiJsViewerClearAllStyles"> <sti-button [imageName]="'Arrows.BigArrowLeft.png'" [margin]="'1px 2px 0 1px'" (action)="prevMonthButtonAction()"> </sti-button> </td> <td class="stiJsViewerClearAllStyles"> <sti-drop-down-list [width]="model.options.isTouchDevice ? 79 : 81" [readOnly]="true" [margin]="'1px 2px 0 0'" [items]="monthesForDatePickerItems" [key]="key.month - 1" (action)="key.month = $event.key + 1"> </sti-drop-down-list> </td> <td class="stiJsViewerClearAllStyles"> <sti-text-box [width]="40" [margin]="'1px 2px 0 0'" [value]="key.year" (onchange)="yearAction($event)"> </sti-text-box> </td> <td class="stiJsViewerClearAllStyles"> <sti-button [imageName]="'Arrows.BigArrowRight.png'" [margin]="'1px 1px 0 0'" (action)="nextMonthButtonAction()"> </sti-button> </td> </tr> </tbody> </table> <div class="stiJsViewerDatePickerSeparator" [style.margin]="'2px 0px'"></div> <table class="stiJsViewerClearAllStyles" cellpadding="0" cellspacing="0"> <tbody> <tr class="stiJsViewerClearAllStyles"> <td *ngFor="let item of model.dayOfWeek; let i = index" class="stiJsViewerDatePickerDayOfWeekCell" [style.fontSize]="countLetters == 2 ? '11px' : ''" [style.color]="getShortDayColor(i)"> {{getShortDayName(i)}} </td> </tr> <tr *ngFor="let row of rows" class="stiJsViewerClearAllStyles"> <td *ngFor="let col of cols" class="stiJsViewerClearAllStyles"> <sti-date-picker-day-button [col]="col" [row]="row" [date]="key" [selected]="getButtonSelected(col, row)" [caption]="getButtonCaption(col, row)" [enabled]="getButtonCaption(col, row) != ''"> [closeOnAction]="closeOnAction" </sti-date-picker-day-button> </td> </tr> </tbody> </table> <div *ngIf="showTime" class="stiJsViewerDatePickerSeparator" [style.margin]="'2px 0px'"></div> <table *ngIf="showTime" class="stiJsViewerClearAllStyles" cellpadding="0" cellspacing="0" [style.width]="'100%'"> <tbody> <tr class="stiJsViewerClearAllStyles"> <td class="stiJsViewerClearAllStyles" [style.padding]="'0 4px 0 4px'" [style.whiteSpace]="'nowrap'"> {{this.model.loc('Time') + ':'}} </td> <td class="stiJsViewerClearAllStyles" [style.textAlign]="'right'"> <sti-text-box [width]="90" [margin]="'1px 2px 2px 2px'" [value]="getTime()" (action)="timeAction($event)"> </sti-text-box> </td> </tr> </tbody> </table> `, isInline: true, dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.ButtonComponent, selector: "sti-button", inputs: ["caption", "caption2", "captionAlign", "captionPadding", "captionPaddingLeft", "captionWhiteSpace", "captionOverflow", "captionTextOverflow", "captionWidth", "captionMaxWidth", "captionLineHeight", "imageName", "arrow", "arrowMarginTop", "margin", "height", "selected", "minWidth", "innerTableWidth", "menuItems", "actionName", "tooltip", "imageCellTextAlign", "imageCellWidth", "imageCellPadding", "imageSizesWidth", "imageSizesHeight", "imageMargin", "width", "display", "closeButton", "resourceButton", "styleColors", "boxSizing", "navagationPanelTooltip", "cursor", "fontSize", "helpLink", "borderColor", "styleName", "enabled"], outputs: ["action", "closeButtonAction"] }, { kind: "component", type: i5.TextBoxComponent, selector: "sti-text-box", inputs: ["width", "actionLostFocus", "tooltip", "enabled", "value", "margin", "focusOnCreate", "maxLength", "color", "type", "padding", "border", "variable", "textAlign", "autocomplete", "readOnly"], outputs: ["action", "onchange", "onblur"] }, { kind: "component", type: i6.DropDownListComponent, selector: "sti-drop-down-list", inputs: ["toolTip", "showImage", "width", "margin", "items", "styleDisplay", "verticalAlign", "readOnly", "enabled", "key"], outputs: ["action"] }, { kind: "component", type: i7.DatePickerDayButtonComponent, selector: "sti-date-picker-day-button", inputs: ["col", "row", "caption", "enabled", "selected", "date", "closeOnAction"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatePickerMenuComponent, decorators: [{ type: Component, args: [{ selector: 'sti-date-picker-menu', template: ` <table class="stiJsViewerClearAllStyles" cellpadding="0" cellspacing="0"> <tbody> <tr class="stiJsViewerClearAllStyles"> <td class="stiJsViewerClearAllStyles"> <sti-button [imageName]="'Arrows.BigArrowLeft.png'" [margin]="'1px 2px 0 1px'" (action)="prevMonthButtonAction()"> </sti-button> </td> <td class="stiJsViewerClearAllStyles"> <sti-drop-down-list [width]="model.options.isTouchDevice ? 79 : 81" [readOnly]="true" [margin]="'1px 2px 0 0'" [items]="monthesForDatePickerItems" [key]="key.month - 1" (action)="key.month = $event.key + 1"> </sti-drop-down-list> </td> <td class="stiJsViewerClearAllStyles"> <sti-text-box [width]="40" [margin]="'1px 2px 0 0'" [value]="key.year" (onchange)="yearAction($event)"> </sti-text-box> </td> <td class="stiJsViewerClearAllStyles"> <sti-button [imageName]="'Arrows.BigArrowRight.png'" [margin]="'1px 1px 0 0'" (action)="nextMonthButtonAction()"> </sti-button> </td> </tr> </tbody> </table> <div class="stiJsViewerDatePickerSeparator" [style.margin]="'2px 0px'"></div> <table class="stiJsViewerClearAllStyles" cellpadding="0" cellspacing="0"> <tbody> <tr class="stiJsViewerClearAllStyles"> <td *ngFor="let item of model.dayOfWeek; let i = index" class="stiJsViewerDatePickerDayOfWeekCell" [style.fontSize]="countLetters == 2 ? '11px' : ''" [style.color]="getShortDayColor(i)"> {{getShortDayName(i)}} </td> </tr> <tr *ngFor="let row of rows" class="stiJsViewerClearAllStyles"> <td *ngFor="let col of cols" class="stiJsViewerClearAllStyles"> <sti-date-picker-day-button [col]="col" [row]="row" [date]="key" [selected]="getButtonSelected(col, row)" [caption]="getButtonCaption(col, row)" [enabled]="getButtonCaption(col, row) != ''"> [closeOnAction]="closeOnAction" </sti-date-picker-day-button> </td> </tr> </tbody> </table> <div *ngIf="showTime" class="stiJsViewerDatePickerSeparator" [style.margin]="'2px 0px'"></div> <table *ngIf="showTime" class="stiJsViewerClearAllStyles" cellpadding="0" cellspacing="0" [style.width]="'100%'"> <tbody> <tr class="stiJsViewerClearAllStyles"> <td class="stiJsViewerClearAllStyles" [style.padding]="'0 4px 0 4px'" [style.whiteSpace]="'nowrap'"> {{this.model.loc('Time') + ':'}} </td> <td class="stiJsViewerClearAllStyles" [style.textAlign]="'right'"> <sti-text-box [width]="90" [margin]="'1px 2px 2px 2px'" [value]="getTime()" (action)="timeAction($event)"> </sti-text-box> </td> </tr> </tbody> </table> ` }] }], ctorParameters: () => [{ type: i1.ModelService }, { type: i2.HelperService }], propDecorators: { menu: [{ type: Input }], keyTo: [{ type: Input }], closeOnAction: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXItbWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdGltdWxzb2Z0LXZpZXdlci1hbmd1bGFyL3NyYy9saWIvbWVudS9kYXRlLXBpY2tlci1tZW51LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7O0FBd0Z6RCxNQUFNLE9BQU8sdUJBQXVCO0lBV2xDLFlBQW1CLEtBQW1CLEVBQVMsTUFBcUI7UUFBakQsVUFBSyxHQUFMLEtBQUssQ0FBYztRQUFTLFdBQU0sR0FBTixNQUFNLENBQWU7UUFSM0QsVUFBSyxHQUFHLEtBQUssQ0FBQztRQUNkLGtCQUFhLEdBQUcsSUFBSSxDQUFDO1FBRXZCLDhCQUF5QixHQUFXLEVBQUUsQ0FBQztRQUV2QyxTQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QixTQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRy9CLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxHQUFHLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFOUksTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFD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LEdBQUcsQ0FBQyxLQUFLLENBQUM7UUFDM0IsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDekIsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLEtBQUssS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUNqQixLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ1YsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDO1FBQ0QsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDMUUsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLGdCQUFnQixDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ3ZCLENBQUM7K0dBaklVLHVCQUF1QjttR0FBdkIsdUJBQXVCLHNJQWhGeEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkVUOzs0RkFHVSx1QkFBdUI7a0JBbEZuQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxzQkFBc0I7b0JBQ2hDLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2RVQ7aUJBQ0Y7NkdBSVUsSUFBSTtzQkFBWixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE1vZGVsU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBNZW51IH0gZnJvbSAnLi9tZW51LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBIZWxwZXJTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvaGVscGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJdGVtLCBEYXRlVGltZU9iamVjdCB9IGZyb20gJy4uL3NlcnZpY2VzL29iamVjdHMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdzdGktZGF0ZS1waWNrZXItbWVudScsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgICAgICA8dGFibGUgY2xhc3M9XCJzdGlKc1ZpZXdlckNsZWFyQWxsU3R5bGVzXCIgY2VsbHBhZGRpbmc9XCIwXCIgY2VsbHNwYWNpbmc9XCIwXCI+XHJcbiAgICAgICAgICA8dGJvZHk+XHJcbiAgICAgICAgICAgIDx0ciBjbGFzcz1cInN0aUpzVmlld2VyQ2xlYXJBbGxTdHlsZXNcIj5cclxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJzdGlKc1ZpZXdlckNsZWFyQWxsU3R5bGVzXCI+XHJcbiAgICAgICAgICAgICAgICA8c3RpLWJ1dHRvbiBbaW1hZ2VOYW1lXT1cIidBcnJvd3MuQmlnQXJyb3dMZWZ0LnBuZydcIiBbbWFyZ2luXT1cIicxcHggMnB4IDAgMXB4J1wiIChhY3Rpb24pPVwicHJldk1vbnRoQnV0dG9uQWN0aW9uKClcIj5cclxuICAgICAgICAgICAgICAgIDwvc3RpLWJ1dHRvbj5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG5cclxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJzdGlKc1ZpZXdlckNsZWFyQWxsU3R5bGVzXCI+XHJcbiAgICAgICAgICAgICAgICA8c3RpLWRyb3AtZG93bi1saXN0XHJcbiAgICAgICAgICAgICAgICAgIFt3aWR0aF09XCJtb2RlbC5vcHRpb25zLmlzVG91Y2hEZXZpY2UgPyA3OSA6IDgxXCJcclxuICAgICAgICAgICAgICAgICAgW3JlYWRPbmx5XT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICBbbWFyZ2luXT1cIicxcHggMnB4IDAgMCdcIlxyXG4gICAgICAgICAgICAgICAgICBbaXRlbXNdPVwibW9udGhlc0ZvckRhdGVQaWNrZXJJdGVtc1wiXHJcbiAgICAgICAgICAgICAgICAgIFtrZXldPVwia2V5Lm1vbnRoIC0gMVwiXHJcbiAgICAgICAgICAgICAgICAgIChhY3Rpb24pPVwia2V5Lm1vbnRoID0gJGV2ZW50LmtleSArIDFcIj5cclxuICAgICAgICAgICAgICAgIDwvc3RpLWRyb3AtZG93bi1saXN0PlxyXG4gICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInN0aUpzVmlld2VyQ2xlYXJBbGxTdHlsZXNcIj5cclxuICAgICAgICAgICAgICAgIDxzdGktdGV4dC1ib3ggW3dpZHRoXT1cIjQwXCIgW21hcmdpbl09XCInMXB4IDJweCAwIDAnXCIgW3ZhbHVlXT1cImtleS55ZWFyXCIgKG9uY2hhbmdlKT1cInllYXJBY3Rpb24oJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICAgICAgPC9zdGktdGV4dC1ib3g+XHJcbiAgICAgICAgICAgICAgPC90ZD5cclxuXHJcbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwic3RpSnNWaWV3ZXJDbGVhckFsbFN0eWxlc1wiPlxyXG4gICAgICAgICAgICAgICAgPHN0aS1idXR0b24gW2ltYWdlTmFtZV09XCInQXJyb3dzLkJpZ0Fycm93UmlnaHQucG5nJ1wiIFttYXJnaW5dPVwiJzFweCAxcHggMCAwJ1wiIChhY3Rpb24pPVwibmV4dE1vbnRoQnV0dG9uQWN0aW9uKClcIj5cclxuICAgICAgICAgICAgICAgIDwvc3RpLWJ1dHRvbj5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPC90Ym9keT5cclxuICAgICAgICA8L3RhYmxlPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzdGlKc1ZpZXdlckRhdGVQaWNrZXJTZXBhcmF0b3JcIiBbc3R5bGUubWFyZ2luXT1cIicycHggMHB4J1wiPjwvZGl2PlxyXG5cclxuICAgICAgICA8dGFibGUgY2xhc3M9XCJzdGlKc1ZpZXdlckNsZWFyQWxsU3R5bGVzXCIgY2VsbHBhZGRpbmc9XCIwXCIgY2VsbHNwYWNpbmc9XCIwXCI+XHJcbiAgICAgICAgICA8dGJvZHk+XHJcbiAgICAgICAgICAgIDx0ciBjbGFzcz1cInN0aUpzVmlld2VyQ2xlYXJBbGxTdHlsZXNcIj5cclxuICAgICAgICAgICAgICA8dGQgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbW9kZWwuZGF5T2ZXZWVrOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJzdGlKc1ZpZXdlckRhdGVQaWNrZXJEYXlPZldlZWtDZWxsXCJcclxuICAgICAgICAgICAgICAgICAgW3N0eWxlLmZvbnRTaXplXT1cImNvdW50TGV0dGVycyA9PSAyID8gJzExcHgnIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwiZ2V0U2hvcnREYXlDb2xvcihpKVwiPlxyXG4gICAgICAgICAgICAgICAgICB7e2dldFNob3J0RGF5TmFtZShpKX19XHJcbiAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2Ygcm93c1wiIGNsYXNzPVwic3RpSnNWaWV3ZXJDbGVhckFsbFN0eWxlc1wiPlxyXG4gICAgICAgICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sc1wiIGNsYXNzPVwic3RpSnNWaWV3ZXJDbGVhckFsbFN0eWxlc1wiPlxyXG4gICAgICAgICAgICAgICAgICA8c3RpLWRhdGUtcGlja2VyLWRheS1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgIFtjb2xdPVwiY29sXCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtyb3ddPVwicm93XCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtkYXRlXT1cImtleVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICBbc2VsZWN0ZWRdPVwiZ2V0QnV0dG9uU2VsZWN0ZWQoY29sLCByb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtjYXB0aW9uXT1cImdldEJ1dHRvbkNhcHRpb24oY29sLCByb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtlbmFibGVkXT1cImdldEJ1dHRvbkNhcHRpb24oY29sLCByb3cpICE9ICcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICBbY2xvc2VPbkFjdGlvbl09XCJjbG9zZU9uQWN0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgPC9zdGktZGF0ZS1waWNrZXItZGF5LWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgIDwvdGFibGU+XHJcblxyXG4gICAgICAgIDxkaXYgKm5nSWY9XCJzaG93VGltZVwiIGNsYXNzPVwic3RpSnNWaWV3ZXJEYXRlUGlja2VyU2VwYXJhdG9yXCIgW3N0eWxlLm1hcmdpbl09XCInMnB4IDBweCdcIj48L2Rpdj5cclxuICAgICAgICA8dGFibGUgKm5nSWY9XCJzaG93VGltZVwiIGNsYXNzPVwic3RpSnNWaWV3ZXJDbGVhckFsbFN0eWxlc1wiIGNlbGxwYWRkaW5nPVwiMFwiIGNlbGxzcGFjaW5nPVwiMFwiIFtzdHlsZS53aWR0aF09XCInMTAwJSdcIj5cclxuICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgPHRyIGNsYXNzPVwic3RpSnNWaWV3ZXJDbGVhckFsbFN0eWxlc1wiPlxyXG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInN0aUpzVmlld2VyQ2xlYXJBbGxTdHlsZXNcIiBbc3R5bGUucGFkZGluZ109XCInMCA0cHggMCA0cHgnXCIgW3N0eWxlLndoaXRlU3BhY2VdPVwiJ25vd3JhcCdcIj5cclxuICAgICAgICAgICAgICAgIHt7dGhpcy5tb2RlbC5sb2MoJ1RpbWUnKSArICc6J319XHJcbiAgICAgICAgICAgICAgPC90ZD5cclxuXHJcbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwic3RpSnNWaWV3ZXJDbGVhckFsbFN0eWxlc1wiIFtzdHlsZS50ZXh0QWxpZ25dPVwiJ3JpZ2h0J1wiPlxyXG4gICAgICAgICAgICAgICAgPHN0aS10ZXh0LWJveCBbd2lkdGhdPVwiOTBcIlxyXG4gICAgICAgICAgICAgICAgICAgIFttYXJnaW5dPVwiJzFweCAycHggMnB4IDJweCdcIlxyXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRUaW1lKClcIlxyXG4gICAgICAgICAgICAgICAgICAgIChhY3Rpb24pPVwidGltZUFjdGlvbigkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgICAgICA8L3N0aS10ZXh0LWJveD5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPC90Ym9keT5cclxuICAgICAgICA8L3RhYmxlPlxyXG4gIGBcclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBEYXRlUGlja2VyTWVudUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBJbnB1dCgpIG1lbnU6IE1lbnU7XHJcbiAgQElucHV0KCkga2V5VG8gPSBmYWxzZTtcclxuICBASW5wdXQoKSBjbG9zZU9uQWN0aW9uID0gdHJ1ZTtcclxuXHJcbiAgcHVibGljIG1vbnRoZXNGb3JEYXRlUGlja2VySXRlbXM6IEl0ZW1bXSA9IFtdO1xyXG4gIHB1YmxpYyBjb3VudExldHRlcnM6IG51bWJlcjtcclxuICBwdWJsaWMgY29scyA9IFswLCAxLCAyLCAzLCA0LCA1LCA2XTtcclxuICBwdWJsaWMgcm93cyA9IFswLCAxLCAyLCAzLCA0LCA1XTtcclxuXHJcbiAgY29uc3RydWN0b3IocHVibGljIG1vZGVsOiBNb2RlbFNlcnZpY2UsIHB1YmxpYyBoZWxwZXI6IEhlbHBlclNlcnZpY2UpIHtcclxuICAgIHRoaXMubW9kZWwubW9udGhzLmZvckVhY2goKG0sIGkpID0+IHRoaXMubW9udGhlc0ZvckRhdGVQaWNrZXJJdGVtcy5wdXNoKHsgbmFtZTogJ01vbnRoJyArIGksIGNhcHRpb246IHRoaXMubW9kZWwubG9jKCdNb250aCcgKyBtKSwga2V5OiBpIH0pKTtcclxuXHJcbiAgICBjb25zdCBmaXJzdExldHRlcnMgPSB7fTtcclxuICAgIHRoaXMubW9kZWwuZGF5T2ZXZWVrLmZvckVhY2goKGQpID0+IHtcclxuICAgICAgY29uc3QgZGF5TmFtZSA9IHRoaXMubW9kZWwubG9jKCdEYXknICsgZCk7XHJcbiAgICAgIGZpcnN0TGV0dGVyc1tkYXlOYW1lLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDAsIDEpLnRvVXBwZXJDYXNlKCldID0gdHJ1ZTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5jb3VudExldHRlcnMgPSBPYmplY3Qua2V5cyhmaXJzdExldHRlcnMpLmxlbmd0aCA8IDUgPyAyIDogMTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkgeyB9XHJcblxyXG4gIGdldEJ1dHRvblNlbGVjdGVkKGNvbDogbnVtYmVyLCByb3c6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgZmlyc3REYXkgPSB0aGlzLmdldEZpcnN0RGF5KCk7XHJcbiAgICBjb25zdCBjdXJEYXkgPSByb3cgKiA3ICsgY29sO1xyXG4gICAgY29uc3QgZGF5ID0gY3VyRGF5IC0gZmlyc3REYXkgKyAxO1xyXG5cclxuICAgIHJldHVybiBkYXkgPT09IHRoaXMua2V5LmRheTtcclxuICB9XHJcblxyXG4gIGdldEJ1dHRvbkNhcHRpb24oY29sOiBudW1iZXIsIHJvdzogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGZpcnN0RGF5ID0gdGhpcy5nZXRGaXJzdERheSgpO1xyXG4gICAgY29uc3QgZGF5c0luTW9udGggPSB0aGlzLmhlbHBlci5nZXRDb3VudERheXNPZk1vbnRoKHRoaXMua2V5LnllYXIsIHRoaXMua2V5Lm1vbnRoIC0gMSk7XHJcbiAgICBjb25zdCBjdXJEYXkgPSByb3cgKiA3ICsgY29sO1xyXG4gICAgY29uc3QgZGF5ID0gY3VyRGF5IC0gZmlyc3REYXkgKyAxO1xyXG4gICAgaWYgKGN1ckRheSA+PSBmaXJzdERheSAmJiBkYXkgPD0gZGF5c0luTW9udGgpIHtcclxuICAgICAgcmV0dXJuIGRheS50b1N0cmluZygpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuICcnO1xyXG4gIH1cclxuXHJcblxyXG4gIGdldFRpbWUoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmhlbHBlci5mb3JtYXREYXRlKHRoaXMuaGVscGVyLmdldERhdGUodGhpcy5rZXkpLCAnSDptbTpzcycpO1xyXG4gIH1cclxuXHJcbiAgZ2V0Rmlyc3REYXkoKTogbnVtYmVyIHtcclxuICAgIGxldCBmaXJzdERheSA9IG5ldyBEYXRlKHRoaXMua2V5LnllYXIsIHRoaXMua2V5Lm1vbnRoIC0gMSwgMSkuZ2V0RGF5KCk7XHJcbiAgICBpZiAoZmlyc3REYXkgPT09IDApIHtcclxuICAgICAgZmlyc3REYXkgPSA3O1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMubW9kZWwub3B0aW9ucy5hcHBlYXJhbmNlLmRhdGVQaWNrZXJGaXJzdERheU9mV2VlayAhPT0gJ1N1bmRheScpIHtcclxuICAgICAgZmlyc3REYXktLTtcclxuICAgIH1cclxuICAgIHJldHVybiBmaXJzdERheTtcclxuICB9XHJcblxyXG4gIGdldCBzaG93VGltZSgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLm1lbnU/LnBhcmFtcz8uZGF0ZVRpbWVUeXBlICE9PSAnRGF0ZSc7XHJcbiAgfVxyXG5cclxuICBnZXQga2V5KCk6IERhdGVUaW1lT2JqZWN0IHtcclxuICAgIHJldHVybiB0aGlzLmtleVRvID8gdGhpcy5tZW51LnBhcmFtcy5rZXlUbyA6IHRoaXMubWVudS5wYXJhbXMua2V5O1xyXG4gIH1cclxuXHJcbiAgeWVhckFjdGlvbihpbnB1dDogYW55KSB7XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLmtleS55ZWFyID0gcGFyc2VJbnQoaW5wdXQudmFsdWUsIDEwKTtcclxuICAgIH0gY2F0Y2ggeyB9XHJcbiAgfVxyXG5cclxuICB0aW1lQWN0aW9uKGlucHV0OiBhbnkpIHtcclxuICAgIGNvbnN0IHRpbWUgPSB0aGlzLmhlbHBlci5zdHJpbmdUb1RpbWUoaW5wdXQudmFsdWUpO1xyXG4gICAgdGhpcy5rZXkuc2Vjb25kcyA9IHRpbWUuc2Vjb25kcztcclxuICAgIHRoaXMua2V5Lm1pbnV0ZXMgPSB0aW1lLm1pbnV0ZXM7XHJcbiAgICB0aGlzLmtleS5ob3VycyA9IHRpbWUuaG91cnM7XHJcbiAgfVxyXG5cclxuICBnZXRTaG9ydERheU5hbWUoaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICBjb25zdCBkYXlOYW1lID0gdGhpcy5tb2RlbC5sb2MoJ0RheScgKyB0aGlzLm1vZGVsLmRheU9mV2Vla1tpbmRleF0pO1xyXG4gICAgaWYgKGRheU5hbWUpIHtcclxuICAgICAgcmV0dXJuIGRheU5hbWUudG9TdHJpbmcoKS5zdWJzdHJpbmcoMCwgdGhpcy5jb3VudExldHRlcnMgPD0gZGF5TmFtZS5sZW5ndGggPyB0aGlzLmNvdW50TGV0dGVycyA6IDEpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG5cclxuICBnZXRTaG9ydERheUNvbG9yKGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKGluZGV4ID09PSAodGhpcy5tb2RlbC5vcHRpb25zLmFwcGVhcmFuY2UuZGF0ZVBpY2tlckZpcnN0RGF5T2ZXZWVrID09PSAnU3VuZGF5JyA/IDYgOiA1KSkge1xyXG4gICAgICByZXR1cm4gJyMwMDAwZmYnO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpbmRleCA9PT0gKHRoaXMubW9kZWwub3B0aW9ucy5hcHBlYXJhbmNlLmRhdGVQaWNrZXJGaXJzdERheU9mV2VlayA9PT0gJ1N1bmRheScgPyAwIDogNikpIHtcclxuICAgICAgcmV0dXJuICcjZmYwMDAwJztcclxuICAgIH1cclxuICAgIHJldHVybiAnJztcclxuICB9XHJcblxyXG4gIHByZXZNb250aEJ1dHRvbkFjdGlvbigpIHtcclxuICAgIGxldCBtb250aCA9IHRoaXMua2V5Lm1vbnRoO1xyXG4gICAgbGV0IHllYXIgPSB0aGlzLmtleS55ZWFyO1xyXG4gICAgbW9udGgtLTtcclxuICAgIGlmIChtb250aCA9PT0gMCkge1xyXG4gICAgICBtb250aCA9IDEyO1xyXG4gICAgICB5ZWFyLS07XHJcbiAgICB9XHJcbiAgICBjb25zdCBjb3VudERheXNJbk1vbnRoID0gdGhpcy5oZWxwZXIuZ2V0Q291bnREYXlzT2ZNb250aCh5ZWFyLCBtb250aCAtIDEpO1xyXG4gICAgaWYgKGNvdW50RGF5c0luTW9udGggPCB0aGlzLmtleS5kYXkpIHtcclxuICAgICAgdGhpcy5rZXkuZGF5ID0gY291bnREYXlzSW5Nb250aDtcclxuICAgIH1cclxuICAgIHRoaXMua2V5Lm1vbnRoID0gbW9udGg7XHJcbiAgICB0aGlzLmtleS55ZWFyID0geWVhcjtcclxuICB9XHJcblxyXG4gIG5leHRNb250aEJ1dHRvbkFjdGlvbigpIHtcclxuICAgIGxldCBtb250aCA9IHRoaXMua2V5Lm1vbnRoO1xyXG4gICAgbGV0IHllYXIgPSB0aGlzLmtleS55ZWFyO1xyXG4gICAgbW9udGgrKztcclxuICAgIGlmIChtb250aCA9PT0gMTMpIHtcclxuICAgICAgbW9udGggPSAxO1xyXG4gICAgICB5ZWFyKys7XHJcbiAgICB9XHJcbiAgICBjb25zdCBjb3VudERheXNJbk1vbnRoID0gdGhpcy5oZWxwZXIuZ2V0Q291bnREYXlzT2ZNb250aCh5ZWFyLCBtb250aCAtIDEpO1xyXG4gICAgaWYgKGNvdW50RGF5c0luTW9udGggPCB0aGlzLmtleS5kYXkpIHtcclxuICAgICAgdGhpcy5rZXkuZGF5ID0gY291bnREYXlzSW5Nb250aDtcclxuICAgIH1cclxuICAgIHRoaXMua2V5Lm1vbnRoID0gbW9udGg7XHJcbiAgICB0aGlzLmtleS55ZWFyID0geWVhcjtcclxuICB9XHJcblxyXG5cclxufVxyXG4iXX0=