UNPKG

@bimeister/pupakit.calendar

Version:
76 lines 20.9 kB
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; import { ChangeDetectionStrategy, Component, EventEmitter, Output, ViewChild, ViewEncapsulation, } from '@angular/core'; import { isNil } from '@bimeister/utilities'; import { Subject } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { MONTHS_IN_YEAR } from '../../declarations/constants/months-in-year.const'; import { CalendarTextKey } from '../../declarations/enums/calendar-text-key.enum'; import '../../declarations/enums/month-index.enum'; import '../../declarations/interfaces/calendar-month.interface'; import '../../declarations/interfaces/calendar-translation.interface'; import { CalendarConfigService } from '../../services/calendar-config.service'; import { CalendarTranslationService } from '../../services/calendar-translation.service'; import * as i0 from "@angular/core"; import * as i1 from "../../services/calendar-translation.service"; import * as i2 from "../../services/calendar-config.service"; import * as i3 from "@angular/common"; import * as i4 from "@bimeister/pupakit.kit"; import * as i5 from "@bimeister/pupakit.common"; import * as i6 from "@angular/cdk/scrolling"; import * as i7 from "../calendar-header/calendar-header.component"; import * as i8 from "../calendar-selector-button/calendar-selector-button.component"; import * as i9 from "../../pipes/is-current-calendar-month.pipe"; const DIVIDER_HEIGHT_PX = 12; const YEAR_LABEL_HEIGHT_PX = 16; const YEAR_TABLE_HEIGHT_PX = 188; const ITEM_HEIGHT_PX = DIVIDER_HEIGHT_PX * 2 + YEAR_LABEL_HEIGHT_PX + YEAR_TABLE_HEIGHT_PX; export class CalendarMonthSelectorComponent { constructor(calendarTranslationService, calendarConfigService) { this.calendarTranslationService = calendarTranslationService; this.calendarConfigService = calendarConfigService; this.select = new EventEmitter(); this.virtualScrollViewport$ = new Subject(); this.headerTitle$ = this.calendarTranslationService.translation$.pipe(map((translation) => translation.texts[CalendarTextKey.SelectMonth])); this.itemHeight = ITEM_HEIGHT_PX; this.startYear = this.calendarConfigService.startYear; this.currentYearInScroll$ = this.virtualScrollViewport$.pipe(switchMap((viewport) => viewport.scrolledIndexChange), map((index) => index + this.startYear)); this.yearsIndexes = Array.from({ length: this.calendarConfigService.yearsRange, }); this.monthsIndexes = Array.from({ length: MONTHS_IN_YEAR }); this.monthNameByIndex$ = this.calendarTranslationService.translation$.pipe(map((translation) => translation.months)); } ngAfterViewInit() { this.scrollToCurrentYear(); if (!isNil(this.virtualScrollViewport)) { this.virtualScrollViewport$.next(this.virtualScrollViewport); } } selectMonth(year, month) { this.select.emit({ year, month, }); } scrollToCurrentYear() { if (isNil(this.virtualScrollViewport)) { return; } const currentYearIndex = new Date().getFullYear() - this.startYear; requestAnimationFrame(() => { this.virtualScrollViewport.scrollToIndex(currentYearIndex); }); } } CalendarMonthSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarMonthSelectorComponent, deps: [{ token: i1.CalendarTranslationService }, { token: i2.CalendarConfigService }], target: i0.ɵɵFactoryTarget.Component }); CalendarMonthSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarMonthSelectorComponent, selector: "pupa-calendar-month-selector", outputs: { select: "select" }, viewQueries: [{ propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], ngImport: i0, template: "<pupa-calendar-header>\n <div class=\"header-content\">\n <h4 class=\"header-title\">\n {{ headerTitle$ | async }}\n </h4>\n\n <div class=\"year-label\">{{ currentYearInScroll$ | async }}</div>\n </div>\n</pupa-calendar-header>\n\n<div class=\"scroller-wrapper\">\n <cdk-virtual-scroll-viewport\n *pupaLet=\"monthNameByIndex$ | async as monthNameByIndex\"\n pupaScrollableContent\n class=\"scroller\"\n [itemSize]=\"itemHeight\"\n >\n <div\n class=\"scroller__item\"\n *cdkVirtualFor=\"let _ of yearsIndexes; templateCacheSize: 10; let isLast = last; let yearIndex = index\"\n >\n <div class=\"scroller__divider\"></div>\n\n <div class=\"year-table\">\n <div class=\"year-table__month\" *ngFor=\"let __ of monthsIndexes; let month = index\">\n <pupa-calendar-selector-button\n [isCurrent]=\"{ year: startYear + yearIndex, month } | isCurrentCalendarMonth\"\n (click)=\"selectMonth(startYear + yearIndex, month)\"\n >\n {{ monthNameByIndex[month] }}\n </pupa-calendar-selector-button>\n </div>\n </div>\n\n <ng-container *ngIf=\"!isLast\">\n <div class=\"scroller__divider\"></div>\n <div class=\"year-label\">{{ yearIndex + startYear + 1 }}</div>\n </ng-container>\n </div>\n </cdk-virtual-scroll-viewport>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;width:100%;position:absolute;z-index:2;top:0;left:0;right:0;bottom:0;background-color:rgba(var(--semantic-color_surface-primary),var(--semantic-color-alpha_surface-primary))}.header-content{flex-direction:column;box-sizing:border-box;padding:0 4rem}.header-title{display:flex;align-items:center;margin:0;height:12rem}.scroller-wrapper{width:100%;height:100%;box-sizing:border-box;display:block}.scroller{width:100%;height:100%;display:block;box-sizing:border-box}.scroller__item{padding:0rem 4rem}.scroller__divider{display:block;width:100%;height:3rem}.year-label{font-family:NotoSans,sans-serif;font-weight:400;font-size:11px;line-height:16px}.year-table{display:grid;grid-template-columns:repeat(3,1fr);column-gap:2rem;row-gap:5rem}.year-table__month{width:100%}\n"], 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: "directive", type: i4.ScrollableContentDirective, selector: "[pupaScrollableContent]" }, { kind: "directive", type: i5.LetDirective, selector: "[pupaLet]", inputs: ["pupaLet"] }, { kind: "directive", type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i6.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: i7.CalendarHeaderComponent, selector: "pupa-calendar-header" }, { kind: "component", type: i8.CalendarSelectorButtonComponent, selector: "pupa-calendar-selector-button", inputs: ["isCurrent"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i9.IsCurrentCalendarMonthPipe, name: "isCurrentCalendarMonth" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarMonthSelectorComponent, decorators: [{ type: Component, args: [{ selector: 'pupa-calendar-month-selector', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<pupa-calendar-header>\n <div class=\"header-content\">\n <h4 class=\"header-title\">\n {{ headerTitle$ | async }}\n </h4>\n\n <div class=\"year-label\">{{ currentYearInScroll$ | async }}</div>\n </div>\n</pupa-calendar-header>\n\n<div class=\"scroller-wrapper\">\n <cdk-virtual-scroll-viewport\n *pupaLet=\"monthNameByIndex$ | async as monthNameByIndex\"\n pupaScrollableContent\n class=\"scroller\"\n [itemSize]=\"itemHeight\"\n >\n <div\n class=\"scroller__item\"\n *cdkVirtualFor=\"let _ of yearsIndexes; templateCacheSize: 10; let isLast = last; let yearIndex = index\"\n >\n <div class=\"scroller__divider\"></div>\n\n <div class=\"year-table\">\n <div class=\"year-table__month\" *ngFor=\"let __ of monthsIndexes; let month = index\">\n <pupa-calendar-selector-button\n [isCurrent]=\"{ year: startYear + yearIndex, month } | isCurrentCalendarMonth\"\n (click)=\"selectMonth(startYear + yearIndex, month)\"\n >\n {{ monthNameByIndex[month] }}\n </pupa-calendar-selector-button>\n </div>\n </div>\n\n <ng-container *ngIf=\"!isLast\">\n <div class=\"scroller__divider\"></div>\n <div class=\"year-label\">{{ yearIndex + startYear + 1 }}</div>\n </ng-container>\n </div>\n </cdk-virtual-scroll-viewport>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;width:100%;position:absolute;z-index:2;top:0;left:0;right:0;bottom:0;background-color:rgba(var(--semantic-color_surface-primary),var(--semantic-color-alpha_surface-primary))}.header-content{flex-direction:column;box-sizing:border-box;padding:0 4rem}.header-title{display:flex;align-items:center;margin:0;height:12rem}.scroller-wrapper{width:100%;height:100%;box-sizing:border-box;display:block}.scroller{width:100%;height:100%;display:block;box-sizing:border-box}.scroller__item{padding:0rem 4rem}.scroller__divider{display:block;width:100%;height:3rem}.year-label{font-family:NotoSans,sans-serif;font-weight:400;font-size:11px;line-height:16px}.year-table{display:grid;grid-template-columns:repeat(3,1fr);column-gap:2rem;row-gap:5rem}.year-table__month{width:100%}\n"] }] }], ctorParameters: function () { return [{ type: i1.CalendarTranslationService }, { type: i2.CalendarConfigService }]; }, propDecorators: { select: [{ type: Output }], virtualScrollViewport: [{ type: ViewChild, args: [CdkVirtualScrollViewport] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItbW9udGgtc2VsZWN0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvY2FsZW5kYXItbW9udGgtc2VsZWN0b3IvY2FsZW5kYXItbW9udGgtc2VsZWN0b3IuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvY2FsZW5kYXItbW9udGgtc2VsZWN0b3IvY2FsZW5kYXItbW9udGgtc2VsZWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbEUsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM3QyxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBQ25GLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUNsRixPQUEyQiwyQ0FBMkMsQ0FBQztBQUN2RSxPQUE4Qix3REFBd0QsQ0FBQztBQUN2RixPQUFvQyw4REFBOEQsQ0FBQztBQUNuRyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUMvRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7Ozs7Ozs7Ozs7QUFFekYsTUFBTSxpQkFBaUIsR0FBVyxFQUFFLENBQUM7QUFDckMsTUFBTSxvQkFBb0IsR0FBVyxFQUFFLENBQUM7QUFDeEMs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b3J0IHsgQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3Njcm9sbGluZyc7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc05pbCB9IGZyb20gJ0BiaW1laXN0ZXIvdXRpbGl0aWVzJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgTU9OVEhTX0lOX1lFQVIgfSBmcm9tICcuLi8uLi9kZWNsYXJhdGlvbnMvY29uc3RhbnRzL21vbnRocy1pbi15ZWFyLmNvbnN0JztcbmltcG9ydCB7IENhbGVuZGFyVGV4dEtleSB9IGZyb20gJy4uLy4uL2RlY2xhcmF0aW9ucy9lbnVtcy9jYWxlbmRhci10ZXh0LWtleS5lbnVtJztcbmltcG9ydCB7IE1vbnRoSW5kZXggfSBmcm9tICcuLi8uLi9kZWNsYXJhdGlvbnMvZW51bXMvbW9udGgtaW5kZXguZW51bSc7XG5pbXBvcnQgeyBDYWxlbmRhck1vbnRoIH0gZnJvbSAnLi4vLi4vZGVjbGFyYXRpb25zL2ludGVyZmFjZXMvY2FsZW5kYXItbW9udGguaW50ZXJmYWNlJztcbmltcG9ydCB7IENhbGVuZGFyVHJhbnNsYXRpb24gfSBmcm9tICcuLi8uLi9kZWNsYXJhdGlvbnMvaW50ZXJmYWNlcy9jYWxlbmRhci10cmFuc2xhdGlvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQ2FsZW5kYXJDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY2FsZW5kYXItY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2FsZW5kYXJUcmFuc2xhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jYWxlbmRhci10cmFuc2xhdGlvbi5zZXJ2aWNlJztcblxuY29uc3QgRElWSURFUl9IRUlHSFRfUFg6IG51bWJlciA9IDEyO1xuY29uc3QgWUVBUl9MQUJFTF9IRUlHSFRfUFg6IG51bWJlciA9IDE2O1xuY29uc3QgWUVBUl9UQUJMRV9IRUlHSFRfUFg6IG51bWJlciA9IDE4ODtcblxuY29uc3QgSVRFTV9IRUlHSFRfUFg6IG51bWJlciA9IERJVklERVJfSEVJR0hUX1BYICogMiArIFlFQVJfTEFCRUxfSEVJR0hUX1BYICsgWUVBUl9UQUJMRV9IRUlHSFRfUFg7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3B1cGEtY2FsZW5kYXItbW9udGgtc2VsZWN0b3InLFxuICB0ZW1wbGF0ZVVybDogJy4vY2FsZW5kYXItbW9udGgtc2VsZWN0b3IuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jYWxlbmRhci1tb250aC1zZWxlY3Rvci5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5FbXVsYXRlZCxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIENhbGVuZGFyTW9udGhTZWxlY3RvckNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICBAT3V0cHV0KCkgcHVibGljIHNlbGVjdDogRXZlbnRFbWl0dGVyPENhbGVuZGFyTW9udGg+ID0gbmV3IEV2ZW50RW1pdHRlcjxDYWxlbmRhck1vbnRoPigpO1xuXG4gIEBWaWV3Q2hpbGQoQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KVxuICBwcml2YXRlIHJlYWRvbmx5IHZpcnR1YWxTY3JvbGxWaWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdmlydHVhbFNjcm9sbFZpZXdwb3J0JDogU3ViamVjdDxDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQ+ID0gbmV3IFN1YmplY3Q8Q2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0PigpO1xuXG4gIHB1YmxpYyByZWFkb25seSBoZWFkZXJUaXRsZSQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuY2FsZW5kYXJUcmFuc2xhdGlvblNlcnZpY2UudHJhbnNsYXRpb24kLnBpcGUoXG4gICAgbWFwKCh0cmFuc2xhdGlvbjogQ2FsZW5kYXJUcmFuc2xhdGlvbikgPT4gdHJhbnNsYXRpb24udGV4dHNbQ2FsZW5kYXJUZXh0S2V5LlNlbGVjdE1vbnRoXSlcbiAgKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgaXRlbUhlaWdodDogbnVtYmVyID0gSVRFTV9IRUlHSFRfUFg7XG5cbiAgcHVibGljIHJlYWRvbmx5IHN0YXJ0WWVhcjogbnVtYmVyID0gdGhpcy5jYWxlbmRhckNvbmZpZ1NlcnZpY2Uuc3RhcnRZZWFyO1xuXG4gIHB1YmxpYyByZWFkb25seSBjdXJyZW50WWVhckluU2Nyb2xsJDogT2JzZXJ2YWJsZTxudW1iZXI+ID0gdGhpcy52aXJ0dWFsU2Nyb2xsVmlld3BvcnQkLnBpcGUoXG4gICAgc3dpdGNoTWFwKCh2aWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KSA9PiB2aWV3cG9ydC5zY3JvbGxlZEluZGV4Q2hhbmdlKSxcbiAgICBtYXAoKGluZGV4OiBudW1iZXIpID0+IGluZGV4ICsgdGhpcy5zdGFydFllYXIpXG4gICk7XG5cbiAgcHVibGljIHJlYWRvbmx5IHllYXJzSW5kZXhlczogdW5rbm93bltdID0gQXJyYXkuZnJvbSh7XG4gICAgbGVuZ3RoOiB0aGlzLmNhbGVuZGFyQ29uZmlnU2VydmljZS55ZWFyc1JhbmdlLFxuICB9KTtcbiAgcHVibGljIHJlYWRvbmx5IG1vbnRoc0luZGV4ZXM6IHVua25vd25bXSA9IEFycmF5LmZyb20oeyBsZW5ndGg6IE1PTlRIU19JTl9ZRUFSIH0pO1xuXG4gIHB1YmxpYyByZWFkb25seSBtb250aE5hbWVCeUluZGV4JDogT2JzZXJ2YWJsZTxSZWNvcmQ8TW9udGhJbmRleCwgc3RyaW5nPj4gPVxuICAgIHRoaXMuY2FsZW5kYXJUcmFuc2xhdGlvblNlcnZpY2UudHJhbnNsYXRpb24kLnBpcGUobWFwKCh0cmFuc2xhdGlvbjogQ2FsZW5kYXJUcmFuc2xhdGlvbikgPT4gdHJhbnNsYXRpb24ubW9udGhzKSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjYWxlbmRhclRyYW5zbGF0aW9uU2VydmljZTogQ2FsZW5kYXJUcmFuc2xhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjYWxlbmRhckNvbmZpZ1NlcnZpY2U6IENhbGVuZGFyQ29uZmlnU2VydmljZVxuICApIHt9XG5cbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNjcm9sbFRvQ3VycmVudFllYXIoKTtcblxuICAgIGlmICghaXNOaWwodGhpcy52aXJ0dWFsU2Nyb2xsVmlld3BvcnQpKSB7XG4gICAgICB0aGlzLnZpcnR1YWxTY3JvbGxWaWV3cG9ydCQubmV4dCh0aGlzLnZpcnR1YWxTY3JvbGxWaWV3cG9ydCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNlbGVjdE1vbnRoKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0LmVtaXQoe1xuICAgICAgeWVhcixcbiAgICAgIG1vbnRoLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzY3JvbGxUb0N1cnJlbnRZZWFyKCk6IHZvaWQge1xuICAgIGlmIChpc05pbCh0aGlzLnZpcnR1YWxTY3JvbGxWaWV3cG9ydCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50WWVhckluZGV4OiBudW1iZXIgPSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgLSB0aGlzLnN0YXJ0WWVhcjtcblxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICB0aGlzLnZpcnR1YWxTY3JvbGxWaWV3cG9ydC5zY3JvbGxUb0luZGV4KGN1cnJlbnRZZWFySW5kZXgpO1xuICAgIH0pO1xuICB9XG59XG4iLCI8cHVwYS1jYWxlbmRhci1oZWFkZXI+XG4gIDxkaXYgY2xhc3M9XCJoZWFkZXItY29udGVudFwiPlxuICAgIDxoNCBjbGFzcz1cImhlYWRlci10aXRsZVwiPlxuICAgICAge3sgaGVhZGVyVGl0bGUkIHwgYXN5bmMgfX1cbiAgICA8L2g0PlxuXG4gICAgPGRpdiBjbGFzcz1cInllYXItbGFiZWxcIj57eyBjdXJyZW50WWVhckluU2Nyb2xsJCB8IGFzeW5jIH19PC9kaXY+XG4gIDwvZGl2PlxuPC9wdXBhLWNhbGVuZGFyLWhlYWRlcj5cblxuPGRpdiBjbGFzcz1cInNjcm9sbGVyLXdyYXBwZXJcIj5cbiAgPGNkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydFxuICAgICpwdXBhTGV0PVwibW9udGhOYW1lQnlJbmRleCQgfCBhc3luYyBhcyBtb250aE5hbWVCeUluZGV4XCJcbiAgICBwdXBhU2Nyb2xsYWJsZUNvbnRlbnRcbiAgICBjbGFzcz1cInNjcm9sbGVyXCJcbiAgICBbaXRlbVNpemVdPVwiaXRlbUhlaWdodFwiXG4gID5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cInNjcm9sbGVyX19pdGVtXCJcbiAgICAgICpjZGtWaXJ0dWFsRm9yPVwibGV0IF8gb2YgeWVhcnNJbmRleGVzOyB0ZW1wbGF0ZUNhY2hlU2l6ZTogMTA7IGxldCBpc0xhc3QgPSBsYXN0OyBsZXQgeWVhckluZGV4ID0gaW5kZXhcIlxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJzY3JvbGxlcl9fZGl2aWRlclwiPjwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwieWVhci10YWJsZVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwieWVhci10YWJsZV9fbW9udGhcIiAqbmdGb3I9XCJsZXQgX18gb2YgbW9udGhzSW5kZXhlczsgbGV0IG1vbnRoID0gaW5kZXhcIj5cbiAgICAgICAgICA8cHVwYS1jYWxlbmRhci1zZWxlY3Rvci1idXR0b25cbiAgICAgICAgICAgIFtpc0N1cnJlbnRdPVwieyB5ZWFyOiBzdGFydFllYXIgKyB5ZWFySW5kZXgsIG1vbnRoIH0gfCBpc0N1cnJlbnRDYWxlbmRhck1vbnRoXCJcbiAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RNb250aChzdGFydFllYXIgKyB5ZWFySW5kZXgsIG1vbnRoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgbW9udGhOYW1lQnlJbmRleFttb250aF0gfX1cbiAgICAgICAgICA8L3B1cGEtY2FsZW5kYXItc2VsZWN0b3ItYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzTGFzdFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsZXJfX2RpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInllYXItbGFiZWxcIj57eyB5ZWFySW5kZXggKyBzdGFydFllYXIgKyAxIH19PC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgPC9jZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQ+XG48L2Rpdj5cbiJdfQ==