ontotext-reusable-ui-components
Version:
Unified reusable UI components designed for the Ontotext ecosystem.
191 lines • 30.7 kB
JavaScript
import { ApplicationRef, Component, ComponentFactoryResolver, EventEmitter, Injector, Input, Output, Renderer2, ViewChild, ViewContainerRef } from '@angular/core';
import { OntoSearchFacetComponent } from '../onto-search-facet.component';
import { FormControl, FormGroup } from '@angular/forms';
import moment from 'moment';
import { DateRange } from '@angular/material/datepicker';
import { DomPortalOutlet, TemplatePortal } from '@angular/cdk/portal';
const DATE_PATTERNS = {
YEAR: 'YYYY',
MONTH: 'MMMM YYYY',
DAY: 'MMMM D, YYYY'
};
export class DateRangeFacetComponent extends OntoSearchFacetComponent {
constructor(renderer, _viewContainerRef, componentFactoryResolver, applicationRef, injector) {
super();
this.renderer = renderer;
this._viewContainerRef = _viewContainerRef;
this.componentFactoryResolver = componentFactoryResolver;
this.applicationRef = applicationRef;
this.injector = injector;
this.onSelectionChange = new EventEmitter();
this.dateRangeGroup = new FormGroup({
start: new FormControl(),
end: new FormControl()
});
this.daysMap = new Map();
this.monthsMap = new Map();
this.yearsMap = new Map();
this.buttonUnsubscribeFns = [];
}
ngOnChanges(changes) {
super.ngOnChanges(changes);
this.mapFacetDates(this.data.facetGroupData);
this.datePickerPlaceholder = this.data.placeholder;
this.setSelectedRange(this.data.selectedRange);
}
ngOnDestroy() {
super.ngOnDestroy();
this.unsubscribeBtnListeners();
}
calendarOpened() {
// Add to event loop queue to execute after angular has finished working on the dom
setTimeout(() => {
this.unsubscribeBtnListeners();
const buttons = this.getCalendarPanelButtons();
this.subscribeToBtnListeners(buttons);
this.updateDayStyles();
});
}
calendarClosed() {
this.unsubscribeBtnListeners();
if (this.dateRangeGroup.get('end').value && this.dateRangeGroup.get('start').value) {
this.data.selectedRange = this.getSearchDateFacetRange();
this.onSelectionChange.emit(this.data.selectedRange);
}
}
inputChange(picker) {
if (!picker.opened) {
this.calendarClosed();
}
}
mapFacetDates(facetGroupData) {
for (const facet of facetGroupData) {
const monthDate = moment(facet.facetData).startOf('month').toISOString();
const yearDate = moment(facet.facetData).startOf('year').toISOString();
this.daysMap.set(moment(facet.facetData).toISOString(), +facet.count);
const existingMonth = this.monthsMap.get(monthDate) || 0;
this.monthsMap.set(monthDate, existingMonth + +facet.count);
const existingYear = this.yearsMap.get(yearDate) || 0;
this.yearsMap.set(yearDate, existingYear + +facet.count);
}
}
updateDayStyles() {
if (document.querySelector('mat-month-view')) {
this.addTooltipsToCalendarCells('mat-month-view', this.daysMap, DATE_PATTERNS.DAY);
}
else if (document.querySelector('mat-multi-year-view')) {
this.addTooltipsToCalendarCells('mat-multi-year-view', this.yearsMap, DATE_PATTERNS.YEAR);
}
else if (document.querySelector('mat-year-view')) {
this.addTooltipsToCalendarCells('mat-year-view', this.monthsMap, DATE_PATTERNS.MONTH);
}
}
addTooltipsToCalendarCells(view, datesMap, dateFormat) {
const calendarCells = this.getCalendarCellsForView(view);
calendarCells.forEach((calendarCell) => {
datesMap.forEach((count, dateString) => {
const calendarCellDateString = moment(calendarCell.getAttribute('aria-label'), dateFormat);
if (calendarCellDateString.isSame(dateString)) {
this.createTooltipForCalendarCell(calendarCell, count);
}
});
});
}
/**
* Creates a portal outlet from the calendar cell div and attaches the tooltip template from view
* Applies "onto-date-range-facet-tooltip" class to calendar cell child div
*
* @param calendarCell - calendar cell to which the span is appended
* @param toolTipContext - context for the tooltip template
*/
createTooltipForCalendarCell(calendarCell, toolTipContext) {
const calendarCellContent = this.getCalendarCellContent(calendarCell);
const tooltipElements = this.getCalendarCellTooltipElements(calendarCell);
if (tooltipElements.length === 0) {
const template = new TemplatePortal(this.toolTipTemplate, this._viewContainerRef);
template.context = { $implicit: toolTipContext };
const outlet = new DomPortalOutlet(calendarCellContent, this.componentFactoryResolver, this.applicationRef, this.injector);
outlet.attachTemplatePortal(template);
calendarCellContent.classList.add('onto-date-range-facet-tooltip');
}
}
getCalendarPanelButtons() {
return document.querySelectorAll('mat-calendar .mat-calendar-body-cell, mat-calendar button, mat-calendar .mat-icon-button');
}
setSelectedRange(selectedRange) {
let momentDateRange;
if (selectedRange) {
momentDateRange = new DateRange(moment(selectedRange.selected.start), moment(selectedRange.selected.end));
}
else {
momentDateRange = new DateRange(null, null);
}
this.dateRangeGroup.setValue(momentDateRange);
this.dateRangeGroup.updateValueAndValidity();
this.data.selectedRange = selectedRange ? this.getSearchDateFacetRange() : null;
}
getSearchDateFacetRange() {
const start = this.dateRangeGroup.get('start').value;
const end = this.dateRangeGroup.get('end').value;
return {
name: this.facetGroupName,
selected: {
start: start.toDate(),
end: end.toDate()
},
count: this.getCountForRange(start, end)
};
}
getCountForRange(start, end) {
const dayKeys = [...this.daysMap.keys()];
return dayKeys.filter((day) => start.isSameOrBefore(day) && end.isSameOrAfter(day))
.map((key) => this.daysMap.get(key))
.reduce((accumulator, count) => accumulator + count, 0);
}
subscribeToBtnListeners(buttons) {
const unsubscribeFns = [];
buttons.forEach((btn) => {
const unsubscribe = this.renderer.listen(btn, 'click', () => {
this.calendarOpened();
});
unsubscribeFns.push(unsubscribe);
});
this.buttonUnsubscribeFns = [...unsubscribeFns];
}
unsubscribeBtnListeners() {
this.buttonUnsubscribeFns.forEach((unsubscribeFn) => {
unsubscribeFn();
});
this.buttonUnsubscribeFns = [];
}
getCalendarCellsForView(view) {
const elements = document.querySelectorAll('.onto-date-range-picker ' + view);
return elements.length > 0 ? elements[0].querySelectorAll('.mat-calendar-body-cell') : [];
}
getCalendarCellContent(calendarCell) {
return calendarCell.querySelectorAll('div')[0];
}
getCalendarCellTooltipElements(calendarCell) {
return calendarCell.querySelectorAll('span.onto-date-range-facet-tooltiptext');
}
}
DateRangeFacetComponent.decorators = [
{ type: Component, args: [{
selector: 'onto-daterange-facet',
template: "<div class=\"onto-date-range-facet\" appCypressData=\"onto-date-range-facet\">\n <div appCypressData=\"onto-date-range-facet-title\">\n <ng-container *ngTemplateOutlet=\"facetTitleTemplate\">\n </ng-container>\n </div>\n <div class=\"onto-date-range-facet-picker\" appCypressData=\"onto-date-range-facet-picker\">\n <mat-form-field>\n <mat-label>{{datePickerPlaceholder}}</mat-label>\n <mat-date-range-input [rangePicker]=\"picker\" [formGroup]=\"dateRangeGroup\">\n <input matInput matStartDate formControlName=\"start\" (dateChange)=\"inputChange(picker)\">\n <input matInput matEndDate formControlName=\"end\" (dateChange)=\"inputChange(picker)\">\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"\n appCypressData=\"onto-date-range-picker-toggle\"></mat-datepicker-toggle>\n <mat-date-range-picker panelClass=\"onto-date-range-picker\" #picker\n (closed)=\"calendarClosed()\"\n (opened)=\"calendarOpened()\"\n appCypressData=\"onto-date-range-picker\"></mat-date-range-picker>\n </mat-form-field>\n <ng-container *ngTemplateOutlet=\"facetTemplate; context: {$implicit: data.selectedRange}\">\n </ng-container>\n </div>\n</div>\n\n<ng-template #toolTipTemplate let-count>\n <span class=\"onto-date-range-facet-tooltiptext\">{{count}}</span>\n</ng-template>\n",
styles: ["::ng-deep .onto-date-range-facet-tooltip:not(.mat-calendar-body-selected):not(.mat-calendar-body-today){background-color:#f0f8ff;border-color:rgba(0,0,0,.38);border-style:dashed}::ng-deep .onto-date-range-facet-tooltip .onto-date-range-facet-tooltiptext{background-color:#000;border-radius:6px;bottom:120%;color:#fff;padding:8px;position:absolute;text-align:center;visibility:hidden;z-index:1}::ng-deep .onto-date-range-facet-tooltip:hover:after{border:8px solid transparent;border-top-color:#000;content:\"\";left:50%;margin-left:-8px;position:absolute;top:-25%}::ng-deep .onto-date-range-facet-tooltip:hover .onto-date-range-facet-tooltiptext{visibility:visible}"]
},] }
];
DateRangeFacetComponent.ctorParameters = () => [
{ type: Renderer2 },
{ type: ViewContainerRef },
{ type: ComponentFactoryResolver },
{ type: ApplicationRef },
{ type: Injector }
];
DateRangeFacetComponent.propDecorators = {
toolTipTemplate: [{ type: ViewChild, args: ['toolTipTemplate',] }],
data: [{ type: Input }],
onSelectionChange: [{ type: Output }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS1mYWNldC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiL29wdC9qZW5raW5zX2pvYnMvd29ya3NwYWNlL3JldXNhYmxlLXVpLWNvbXBvbmVudHMtcmVsZWFzZS9wcm9qZWN0cy9vbnRvLXNlYXJjaC9zcmMvIiwic291cmNlcyI6WyJsaWIvb250by1zZWFyY2gtZmFjZXQvZGF0ZS1yYW5nZS1mYWNldC9kYXRlLXJhbmdlLWZhY2V0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsY0FBYyxFQUNkLFNBQVMsRUFDVCx3QkFBd0IsRUFDeEIsWUFBWSxFQUNaLFFBQVEsRUFDUixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFHVCxTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2pCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3hFLE9BQU8sRUFBQyxXQUFXLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEQsT0FBTyxNQUFnQixNQUFNLFFBQVEsQ0FBQztBQUN0QyxPQUFPLEVBQUMsU0FBUyxFQUFxQixNQUFNLDhCQUE4QixDQUFDO0FBRzNFLE9BQU8sRUFBQyxlQUFlLEVBQUUsY0FBYyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFFcEUsTUFBTSxhQUFhLEdBQUc7SUFDcEIsSUFBSSxFQUFFLE1BQU07SUFDWixLQUFLLEVBQUUsV0FBVztJQUNsQixHQUFHLEVBQUUsY0FBYztDQUNwQixDQUFDO0FBT0YsTUFBTSxPQUFPLHVCQUF3QixTQUFRLHdCQUF3QjtJQW9CbkUsWUFBb0IsUUFBbUIsRUFDbkIsaUJBQW1DLEVBQ25DLHdCQUFrRCxFQUNsRCxjQUE4QixFQUM5QixRQUFrQjtRQUNwQyxLQUFLLEVBQUUsQ0FBQztRQUxVLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNu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QUMsSUFBWTtRQUMxQyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDOUUsT0FBTyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLHlCQUF5QixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM1RixDQUFDO0lBRU8sc0JBQXNCLENBQUMsWUFBWTtRQUN6QyxPQUFPLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRU8sOEJBQThCLENBQUMsWUFBWTtRQUNqRCxPQUFPLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0lBQ2pGLENBQUM7OztZQS9MRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLHNCQUFzQjtnQkFDaEMscThDQUFnRDs7YUFFakQ7OztZQXpCQyxTQUFTO1lBSVQsZ0JBQWdCO1lBVmhCLHdCQUF3QjtZQUZ4QixjQUFjO1lBSWQsUUFBUTs7OzhCQStCUCxTQUFTLFNBQUMsaUJBQWlCO21CQUMzQixLQUFLO2dDQUVMLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBcHBsaWNhdGlvblJlZixcbiAgQ29tcG9uZW50LFxuICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtPbnRvU2VhcmNoRmFjZXRDb21wb25lbnR9IGZyb20gJy4uL29udG8tc2VhcmNoLWZhY2V0LmNvbXBvbmVudCc7XG5pbXBvcnQge0Zvcm1Db250cm9sLCBGb3JtR3JvdXB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7U2VhcmNoRGF0ZUZhY2V0R3JvdXBNb2RlbH0gZnJvbSAnLi9tb2RlbHMvc2VhcmNoLWRhdGUtZmFjZXQtZ3JvdXAtbW9kZWwnO1xuaW1wb3J0IG1vbWVudCwge01vbWVudH0gZnJvbSAnbW9tZW50JztcbmltcG9ydCB7RGF0ZVJhbmdlLCBNYXREYXRlUmFuZ2VQaWNrZXJ9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RhdGVwaWNrZXInO1xuaW1wb3J0IHtTZWFyY2hEYXRlRmFjZXRNb2RlbH0gZnJvbSAnLi9tb2RlbHMvc2VhcmNoLWRhdGUtZmFjZXQtbW9kZWwnO1xuaW1wb3J0IHtTZWFyY2hEYXRlRmFjZXRSYW5nZX0gZnJvbSAnLi9tb2RlbHMvc2VhcmNoLWRhdGUtZmFjZXQtcmFuZ2UnO1xuaW1wb3J0IHtEb21Qb3J0YWxPdXRsZXQsIFRlbXBsYXRlUG9ydGFsfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcblxuY29uc3QgREFURV9QQVRURVJOUyA9IHtcbiAgWUVBUjogJ1lZWVknLFxuICBNT05USDogJ01NTU0gWVlZWScsXG4gIERBWTogJ01NTU0gRCwgWVlZWSdcbn07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ29udG8tZGF0ZXJhbmdlLWZhY2V0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2RhdGUtcmFuZ2UtZmFjZXQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9kYXRlLXJhbmdlLWZhY2V0LmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRGF0ZVJhbmdlRmFjZXRDb21wb25lbnQgZXh0ZW5kcyBPbnRvU2VhcmNoRmFjZXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBAVmlld0NoaWxkKCd0b29sVGlwVGVtcGxhdGUnKSB0b29sVGlwVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBkYXRhOiBTZWFyY2hEYXRlRmFjZXRHcm91cE1vZGVsO1xuICBAT3V0cHV0KClcbiAgcHVibGljIG9uU2VsZWN0aW9uQ2hhbmdlOiBFdmVudEVtaXR0ZXI8U2VhcmNoRGF0ZUZhY2V0UmFuZ2U+ID0gbmV3IEV2ZW50RW1pdHRlcjxTZWFyY2hEYXRlRmFjZXRSYW5nZT4oKTtcblxuICBkYXRlUmFuZ2VHcm91cDogRm9ybUdyb3VwID0gbmV3IEZvcm1Hcm91cCh7XG4gICAgc3RhcnQ6IG5ldyBGb3JtQ29udHJvbCgpLFxuICAgIGVuZDogbmV3IEZvcm1Db250cm9sKClcbiAgfSk7XG5cbiAgZGF0ZVBpY2tlclBsYWNlaG9sZGVyOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBkYXlzTWFwOiBNYXA8c3RyaW5nLCBudW1iZXI+ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSBtb250aHNNYXA6IE1hcDxzdHJpbmcsIG51bWJlcj4gPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBwcml2YXRlIHllYXJzTWFwOiBNYXA8c3RyaW5nLCBudW1iZXI+ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICBwcml2YXRlIGJ1dHRvblVuc3Vic2NyaWJlRm5zOiAoKCkgPT4gdm9pZClbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBhcHBsaWNhdGlvblJlZjogQXBwbGljYXRpb25SZWYsXG4gICAgICAgICAgICAgIHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBzdXBlci5uZ09uQ2hhbmdlcyhjaGFuZ2VzKTtcbiAgICB0aGlzLm1hcEZhY2V0RGF0ZXModGhpcy5kYXRhLmZhY2V0R3JvdXBEYXRhKTtcblxuICAgIHRoaXMuZGF0ZVBpY2tlclBsYWNlaG9sZGVyID0gdGhpcy5kYXRhLnBsYWNlaG9sZGVyO1xuICAgIHRoaXMuc2V0U2VsZWN0ZWRSYW5nZSh0aGlzLmRhdGEuc2VsZWN0ZWRSYW5nZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICAgIHRoaXMudW5zdWJzY3JpYmVCdG5MaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIGNhbGVuZGFyT3BlbmVkKCk6IHZvaWQge1xuICAgIC8vIEFkZCB0byBldmVudCBsb29wIHF1ZXVlIHRvIGV4ZWN1dGUgYWZ0ZXIgYW5ndWxhciBoYXMgZmluaXNoZWQgd29ya2luZyBvbiB0aGUgZG9tXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnVuc3Vic2NyaWJlQnRuTGlzdGVuZXJzKCk7XG4gICAgICBjb25zdCBidXR0b25zID0gdGhpcy5nZXRDYWxlbmRhclBhbmVsQnV0dG9ucygpO1xuICAgICAgdGhpcy5zdWJzY3JpYmVUb0J0bkxpc3RlbmVycyhidXR0b25zKTtcbiAgICAgIHRoaXMudXBkYXRlRGF5U3R5bGVzKCk7XG4gICAgfSk7XG4gIH1cblxuICBjYWxlbmRhckNsb3NlZCgpOiB2b2lkIHtcbiAgICB0aGlzLnVuc3Vic2NyaWJlQnRuTGlzdGVuZXJzKCk7XG4gICAgaWYgKHRoaXMuZGF0ZVJhbmdlR3JvdXAuZ2V0KCdlbmQnKS52YWx1ZSAmJiB0aGlzLmRhdGVSYW5nZUdyb3VwLmdldCgnc3RhcnQnKS52YWx1ZSkge1xuICAgICAgdGhpcy5kYXRhLnNlbGVjdGVkUmFuZ2UgPSB0aGlzLmdldFNlYXJjaERhdGVGYWNldFJhbmdlKCk7XG4gICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlLmVtaXQodGhpcy5kYXRhLnNlbGVjdGVkUmFuZ2UpO1xuICAgIH1cbiAgfVxuXG4gIGlucHV0Q2hhbmdlKHBpY2tlcjogTWF0RGF0ZVJhbmdlUGlja2VyPE1vbWVudD4pOiB2b2lkIHtcbiAgICBpZiAoIXBpY2tlci5vcGVuZWQpIHtcbiAgICAgIHRoaXMuY2FsZW5kYXJDbG9zZWQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1hcEZhY2V0RGF0ZXMoZmFjZXRHcm91cERhdGE6IFNlYXJjaERhdGVGYWNldE1vZGVsW10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGZhY2V0IG9mIGZhY2V0R3JvdXBEYXRhKSB7XG4gICAgICBjb25zdCBtb250aERhdGUgPSBtb21lbnQoZmFjZXQuZmFjZXREYXRhKS5zdGFydE9mKCdtb250aCcpLnRvSVNPU3RyaW5nKCk7XG4gICAgICBjb25zdCB5ZWFyRGF0ZSA9IG1vbWVudChmYWNldC5mYWNldERhdGEpLnN0YXJ0T2YoJ3llYXInKS50b0lTT1N0cmluZygpO1xuICAgICAgdGhpcy5kYXlzTWFwLnNldChtb21lbnQoZmFjZXQuZmFjZXREYXRhKS50b0lTT1N0cmluZygpLCArZmFjZXQuY291bnQpO1xuICAgICAgY29uc3QgZXhpc3RpbmdNb250aCA9IHRoaXMubW9udGhzTWFwLmdldChtb250aERhdGUpIHx8IDA7XG4gICAgICB0aGlzLm1vbnRoc01hcC5zZXQobW9udGhEYXRlLCBleGlzdGluZ01vbnRoICsgK2ZhY2V0LmNvdW50KTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nWWVhciA9IHRoaXMueWVhcnNNYXAuZ2V0KHllYXJEYXRlKSB8fCAwO1xuICAgICAgdGhpcy55ZWFyc01hcC5zZXQoeWVhckRhdGUsIGV4aXN0aW5nWWVhciArICtmYWNldC5jb3VudCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVEYXlTdHlsZXMoKTogdm9pZCB7XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21hdC1tb250aC12aWV3JykpIHtcbiAgICAgIHRoaXMuYWRkVG9vbHRpcHNUb0NhbGVuZGFyQ2VsbHMoJ21hdC1tb250aC12aWV3JywgdGhpcy5kYXlzTWFwLCBEQVRFX1BBVFRFUk5TLkRBWSk7XG4gICAgfSBlbHNlIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtYXQtbXVsdGkteWVhci12aWV3JykpIHtcbiAgICAgIHRoaXMuYWRkVG9vbHRpcHNUb0NhbGVuZGFyQ2VsbHMoJ21hdC1tdWx0aS15ZWFyLXZpZXcnLCB0aGlzLnllYXJzTWFwLCBEQVRFX1BBVFRFUk5TLllFQVIpO1xuICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbWF0LXllYXItdmlldycpKSB7XG4gICAgICB0aGlzLmFkZFRvb2x0aXBzVG9DYWxlbmRhckNlbGxzKCdtYXQteWVhci12aWV3JywgdGhpcy5tb250aHNNYXAsIERBVEVfUEFUVEVSTlMuTU9OVEgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWRkVG9vbHRpcHNUb0NhbGVuZGFyQ2VsbHModmlldzogc3RyaW5nLCBkYXRlc01hcDogTWFwPHN0cmluZywgbnVtYmVyPiwgZGF0ZUZvcm1hdDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY2FsZW5kYXJDZWxscyA9IHRoaXMuZ2V0Q2FsZW5kYXJDZWxsc0ZvclZpZXcodmlldyk7XG4gICAgY2FsZW5kYXJDZWxscy5mb3JFYWNoKChjYWxlbmRhckNlbGwpID0+IHtcbiAgICAgIGRhdGVzTWFwLmZvckVhY2goKGNvdW50LCBkYXRlU3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGVuZGFyQ2VsbERhdGVTdHJpbmcgPSBtb21lbnQoY2FsZW5kYXJDZWxsLmdldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcpLCBkYXRlRm9ybWF0KTtcbiAgICAgICAgaWYgKGNhbGVuZGFyQ2VsbERhdGVTdHJpbmcuaXNTYW1lKGRhdGVTdHJpbmcpKSB7XG4gICAgICAgICAgdGhpcy5jcmVhdGVUb29sdGlwRm9yQ2FsZW5kYXJDZWxsKGNhbGVuZGFyQ2VsbCwgY291bnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgcG9ydGFsIG91dGxldCBmcm9tIHRoZSBjYWxlbmRhciBjZWxsIGRpdiBhbmQgYXR0YWNoZXMgdGhlIHRvb2x0aXAgdGVtcGxhdGUgZnJvbSB2aWV3XG4gICAqIEFwcGxpZXMgXCJvbnRvLWRhdGUtcmFuZ2UtZmFjZXQtdG9vbHRpcFwiIGNsYXNzIHRvIGNhbGVuZGFyIGNlbGwgY2hpbGQgZGl2XG4gICAqXG4gICAqIEBwYXJhbSBjYWxlbmRhckNlbGwgLSBjYWxlbmRhciBjZWxsIHRvIHdoaWNoIHRoZSBzcGFuIGlzIGFwcGVuZGVkXG4gICAqIEBwYXJhbSB0b29sVGlwQ29udGV4dCAtIGNvbnRleHQgZm9yIHRoZSB0b29sdGlwIHRlbXBsYXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVRvb2x0aXBGb3JDYWxlbmRhckNlbGwoY2FsZW5kYXJDZWxsLCB0b29sVGlwQ29udGV4dDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgY2FsZW5kYXJDZWxsQ29udGVudCA9IHRoaXMuZ2V0Q2FsZW5kYXJDZWxsQ29udGVudChjYWxlbmRhckNlbGwpO1xuICAgIGNvbnN0IHRvb2x0aXBFbGVtZW50cyA9IHRoaXMuZ2V0Q2FsZW5kYXJDZWxsVG9vbHRpcEVsZW1lbnRzKGNhbGVuZGFyQ2VsbCk7XG4gICAgaWYgKHRvb2x0aXBFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gbmV3IFRlbXBsYXRlUG9ydGFsKHRoaXMudG9vbFRpcFRlbXBsYXRlLCB0aGlzLl92aWV3Q29udGFpbmVyUmVmKTtcbiAgICAgIHRlbXBsYXRlLmNvbnRleHQgPSB7JGltcGxpY2l0OiB0b29sVGlwQ29udGV4dH07XG5cbiAgICAgIGNvbnN0IG91dGxldCA9IG5ldyBEb21Qb3J0YWxPdXRsZXQoY2FsZW5kYXJDZWxsQ29udGVudCwgdGhpcy5jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIHRoaXMuYXBwbGljYXRpb25SZWYsIHRoaXMuaW5qZWN0b3IpO1xuICAgICAgb3V0bGV0LmF0dGFjaFRlbXBsYXRlUG9ydGFsKHRlbXBsYXRlKTtcbiAgICAgIGNhbGVuZGFyQ2VsbENvbnRlbnQuY2xhc3NMaXN0LmFkZCgnb250by1kYXRlLXJhbmdlLWZhY2V0LXRvb2x0aXAnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldENhbGVuZGFyUGFuZWxCdXR0b25zKCk6IGFueSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ21hdC1jYWxlbmRhciAubWF0LWNhbGVuZGFyLWJvZHktY2VsbCwgbWF0LWNhbGVuZGFyIGJ1dHRvbiwgbWF0LWNhbGVuZGFyIC5tYXQtaWNvbi1idXR0b24nKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U2VsZWN0ZWRSYW5nZShzZWxlY3RlZFJhbmdlOiBTZWFyY2hEYXRlRmFjZXRSYW5nZSk6IHZvaWQge1xuICAgIGxldCBtb21lbnREYXRlUmFuZ2U7XG4gICAgaWYgKHNlbGVjdGVkUmFuZ2UpIHtcbiAgICAgIG1vbWVudERhdGVSYW5nZSA9IG5ldyBEYXRlUmFuZ2U8TW9tZW50Pihtb21lbnQoc2VsZWN0ZWRSYW5nZS5zZWxlY3RlZC5zdGFydCksIG1vbWVudChzZWxlY3RlZFJhbmdlLnNlbGVjdGVkLmVuZCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb21lbnREYXRlUmFuZ2UgPSBuZXcgRGF0ZVJhbmdlKG51bGwsIG51bGwpO1xuICAgIH1cblxuICAgIHRoaXMuZGF0ZVJhbmdlR3JvdXAuc2V0VmFsdWUobW9tZW50RGF0ZVJhbmdlKTtcbiAgICB0aGlzLmRhdGVSYW5nZUdyb3VwLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICB0aGlzLmRhdGEuc2VsZWN0ZWRSYW5nZSA9IHNlbGVjdGVkUmFuZ2UgPyB0aGlzLmdldFNlYXJjaERhdGVGYWNldFJhbmdlKCkgOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTZWFyY2hEYXRlRmFjZXRSYW5nZSgpOiBTZWFyY2hEYXRlRmFjZXRSYW5nZSB7XG4gICAgY29uc3Qgc3RhcnQ6IE1vbWVudCA9IHRoaXMuZGF0ZVJhbmdlR3JvdXAuZ2V0KCdzdGFydCcpLnZhbHVlO1xuICAgIGNvbnN0IGVuZDogTW9tZW50ID0gdGhpcy5kYXRlUmFuZ2VHcm91cC5nZXQoJ2VuZCcpLnZhbHVlO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHRoaXMuZmFjZXRHcm91cE5hbWUsXG4gICAgICBzZWxlY3RlZDoge1xuICAgICAgICBzdGFydDogc3RhcnQudG9EYXRlKCksXG4gICAgICAgIGVuZDogZW5kLnRvRGF0ZSgpXG4gICAgICB9IGFzIERhdGVSYW5nZTxEYXRlPixcbiAgICAgIGNvdW50OiB0aGlzLmdldENvdW50Rm9yUmFuZ2Uoc3RhcnQsIGVuZClcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb3VudEZvclJhbmdlKHN0YXJ0OiBNb21lbnQsIGVuZDogTW9tZW50KTogbnVtYmVyIHtcbiAgICBjb25zdCBkYXlLZXlzID0gWy4uLnRoaXMuZGF5c01hcC5rZXlzKCldO1xuICAgIHJldHVybiBkYXlLZXlzLmZpbHRlcigoZGF5KSA9PiBzdGFydC5pc1NhbWVPckJlZm9yZShkYXkpICYmIGVuZC5pc1NhbWVPckFmdGVyKGRheSkpXG4gICAgICAgIC5tYXAoKGtleSkgPT4gdGhpcy5kYXlzTWFwLmdldChrZXkpKVxuICAgICAgICAucmVkdWNlKChhY2N1bXVsYXRvciwgY291bnQpID0+IGFjY3VtdWxhdG9yICsgY291bnQsIDApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb0J0bkxpc3RlbmVycyhidXR0b25zOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCB1bnN1YnNjcmliZUZucyA9IFtdO1xuICAgIGJ1dHRvbnMuZm9yRWFjaCgoYnRuKSA9PiB7XG4gICAgICBjb25zdCB1bnN1YnNjcmliZSA9IHRoaXMucmVuZGVyZXIubGlzdGVuKGJ0biwgJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICB0aGlzLmNhbGVuZGFyT3BlbmVkKCk7XG4gICAgICB9KTtcbiAgICAgIHVuc3Vic2NyaWJlRm5zLnB1c2godW5zdWJzY3JpYmUpO1xuICAgIH0pO1xuICAgIHRoaXMuYnV0dG9uVW5zdWJzY3JpYmVGbnMgPSBbLi4udW5zdWJzY3JpYmVGbnNdO1xuICB9XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZUJ0bkxpc3RlbmVycygpOiB2b2lkIHtcbiAgICB0aGlzLmJ1dHRvblVuc3Vic2NyaWJlRm5zLmZvckVhY2goKHVuc3Vic2NyaWJlRm4pID0+IHtcbiAgICAgIHVuc3Vic2NyaWJlRm4oKTtcbiAgICB9KTtcbiAgICB0aGlzLmJ1dHRvblVuc3Vic2NyaWJlRm5zID0gW107XG4gIH1cblxuICBwcml2YXRlIGdldENhbGVuZGFyQ2VsbHNGb3JWaWV3KHZpZXc6IHN0cmluZyk6IGFueSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcub250by1kYXRlLXJhbmdlLXBpY2tlciAnICsgdmlldyk7XG4gICAgcmV0dXJuIGVsZW1lbnRzLmxlbmd0aCA+IDAgPyBlbGVtZW50c1swXS5xdWVyeVNlbGVjdG9yQWxsKCcubWF0LWNhbGVuZGFyLWJvZHktY2VsbCcpIDogW107XG4gIH1cblxuICBwcml2YXRlIGdldENhbGVuZGFyQ2VsbENvbnRlbnQoY2FsZW5kYXJDZWxsKTogSFRNTERpdkVsZW1lbnQge1xuICAgIHJldHVybiBjYWxlbmRhckNlbGwucXVlcnlTZWxlY3RvckFsbCgnZGl2JylbMF07XG4gIH1cblxuICBwcml2YXRlIGdldENhbGVuZGFyQ2VsbFRvb2x0aXBFbGVtZW50cyhjYWxlbmRhckNlbGwpOiBIVE1MRGl2RWxlbWVudFtdIHtcbiAgICByZXR1cm4gY2FsZW5kYXJDZWxsLnF1ZXJ5U2VsZWN0b3JBbGwoJ3NwYW4ub250by1kYXRlLXJhbmdlLWZhY2V0LXRvb2x0aXB0ZXh0Jyk7XG4gIH1cbn1cbiJdfQ==