@progress/telerik-angular-native-report-viewer
Version:
Progress® Telerik® Native Report Viewer for Angular
259 lines (251 loc) • 35.8 kB
JavaScript
import { Component, Input, ViewChild } from '@angular/core';
import { DatePickerComponent } from '@progress/kendo-angular-dateinputs';
import { debounceTime } from 'rxjs';
import * as i0 from "@angular/core";
import * as i1 from "../reporting-angular-viewer.service";
import * as i2 from "@angular/common";
import * as i3 from "@progress/kendo-angular-dropdowns";
import * as i4 from "@progress/kendo-angular-inputs";
import * as i5 from "@progress/kendo-angular-buttons";
import * as i6 from "@progress/kendo-angular-dateinputs";
const SystemBooleanType = 'System.Boolean';
const SystemDateTimeType = 'System.DateTime';
export class ParametersSectionComponent {
static isInvalidInput(parameter) {
if (parameter.allowNull) {
return false;
}
if (parameter.multivalue) {
return parameter.value == null || parameter.value.length === 0;
}
return parameter.value == null;
}
constructor(service, cdr) {
this.service = service;
this.cdr = cdr;
this.loading = true;
this.parameter = {
name: '',
type: '',
text: '',
multivalue: false,
allowNull: false,
allowBlank: false,
isVisible: false,
autoRefresh: false,
hasChildParameters: false,
childParameters: [],
availableValues: [],
value: '',
id: '',
label: ''
};
this.datepickerValue = new Date();
this.isInvalidInput = ParametersSectionComponent.isInvalidInput;
}
ngAfterViewInit() {
this.datePicker?.valueChange.asObservable().pipe(debounceTime(this.parameter.autoRefresh ? 2000 : 0)).subscribe(value => {
this.onValueChange(this.parameter, adjustTimezone(value));
});
const reportDateParam = this.service.parameters.find(p => p.type === SystemDateTimeType && p.id === this.parameter.id);
this.datepickerValue = new Date(reportDateParam?.value);
}
onClearSelectionClick(param) {
param.value = '';
}
onSelectAllClick(parameter) {
parameter.value = parameter.availableValues.map((val) => val.value);
this.service.options.reportSource.parameters = JSON.parse(JSON.stringify(this.service.options.reportSource.parameters));
this.service.options.reportSource.parameters[parameter.id] = parameter.value;
if (!parameter.autoRefresh || !this.service.controller.autoRunEnabled)
return;
this.service.applyParameter(parameter.id, parameter.value);
}
onValueChange(parameter, value) {
//TODO: should be removed once the common viewer accepts lower case true/false values
if (parameter.type === SystemBooleanType) {
value = value.target.checked ? 'True' : 'False';
}
parameter.value = value;
this.service.options.reportSource.parameters = JSON.parse(JSON.stringify(this.service.options.reportSource.parameters));
// Can't check for all falsy values because 0 is falsy, won't work with integer parameters
if (value === undefined || value === null || value.length === 0) {
parameter.value = value = null;
if (!parameter.allowNull)
return;
}
if (parameter.childParameters?.length > 0) {
parameter.childParameters.forEach((param) => {
delete this.service.options.reportSource.parameters[param.toString()];
});
this.service.options.reportSource.parameters[parameter.id] = parameter.value;
if (!parameter.autoRefresh || !this.service.controller.autoRunEnabled)
return;
this.service.controller.setParameters(this.service.options.reportSource.parameters);
this.service.controller.refreshReport(true, '');
}
else {
this.service.options.reportSource.parameters[parameter.id] = value;
if (!parameter.autoRefresh || !this.service.controller.autoRunEnabled)
return;
this.service.applyParameter(parameter.id, value);
this.cdr.detectChanges();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ParametersSectionComponent, deps: [{ token: i1.ReportingAngularViewerService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ParametersSectionComponent, selector: "parameters-section", inputs: { loading: "loading", parameter: "parameter" }, viewQueries: [{ propertyName: "datePicker", first: true, predicate: DatePickerComponent, descendants: true }], ngImport: i0, template: `
<div *ngIf="parameter.isVisible" class="k-card trv-parameter-container">
<div class="k-card-header trv-parameter-header">
<div class="k-card-title trv-parameter-title" [title]="parameter.text">{{parameter.text}}</div>
</div>
<div class="k-card-body trv-parameter-value">
<div *ngIf="isInvalidInput(parameter)" class="k-notification k-notification-error trv-parameter-error">
<div class="k-notification-wrap">
<span class="k-icon k-i-warning"></span>
<span class="k-notification-content trv-parameter-error-message">{{' ' + service.options.messages.ReportViewer_InvalidParameter}}</span>
</div>
</div>
<div class="trv-parameter-editor-available-values">
<kendo-multiselect
*ngIf="parameter.multivalue && parameter.availableValues"
[data]="parameter.availableValues"
[valuePrimitive]="true"
textField="name"
valueField="value"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
[kendoDropDownFilter]="{caseSensitive: false, operator: 'contains'}"
>
</kendo-multiselect>
<kendo-combobox
*ngIf="!parameter.multivalue && parameter.availableValues"
[data]="parameter.availableValues"
[valuePrimitive]="true"
textField="name"
valueField="value"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
>
</kendo-combobox>
<div *ngIf="parameter.availableValues" class="k-actions k-actions-end trv-parameter-actions">
<button kendoButton *ngIf="parameter.multivalue" fillMode="outline" class="trv-select-all" (click)="onSelectAllClick(parameter)">Select all</button>
</div>
<kendo-datepicker *ngIf="parameter.type === 'System.DateTime' && !parameter.availableValues"
[value]="datepickerValue"
[disabled]="loading"
>
</kendo-datepicker>
<kendo-numerictextbox *ngIf="(parameter.type === 'System.Int64' || parameter.type ==='System.Double') && !parameter.availableValues"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
>
</kendo-numerictextbox>
<kendo-textbox *ngIf="parameter.type === 'System.String' && !parameter.availableValues"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
>
</kendo-textbox>
<input *ngIf="parameter.type === 'System.Boolean' && !parameter.availableValues"
type="checkbox"
kendoCheckBox
[id]="parameter.id"
[checked]="(parameter.value && parameter.value !== 'False') || parameter.value === 'True'"
(change)="onValueChange(parameter, $event)"
[disabled]="loading"
/>
</div>
</div>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.FilterDirective, selector: "[kendoDropDownFilter]", inputs: ["data", "kendoDropDownFilter", "filterable"] }, { kind: "component", type: i4.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "component", type: i3.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "title", "subtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i3.MultiSelectComponent, selector: "kendo-multiselect", inputs: ["showStickyHeader", "focusableId", "autoClose", "loading", "data", "value", "valueField", "textField", "tabindex", "tabIndex", "size", "rounded", "fillMode", "placeholder", "adaptiveMode", "title", "subtitle", "disabled", "itemDisabled", "checkboxes", "readonly", "filterable", "virtual", "popupSettings", "listHeight", "valuePrimitive", "clearButton", "tagMapper", "allowCustom", "valueNormalizer", "inputAttributes"], outputs: ["filterChange", "valueChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "removeTag"], exportAs: ["kendoMultiSelect"] }, { kind: "component", type: i5.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: i6.DatePickerComponent, selector: "kendo-datepicker", inputs: ["focusableId", "cellTemplate", "clearButton", "inputAttributes", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "headerTemplate", "footerTemplate", "footer", "navigationItemTemplate", "weekDaysFormat", "showOtherMonthDays", "activeView", "bottomView", "topView", "calendarType", "animateCalendarNavigation", "disabled", "readonly", "readOnlyInput", "popupSettings", "navigation", "min", "max", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "autoFill", "focusedDate", "value", "format", "twoDigitYearMax", "formatPlaceholder", "placeholder", "tabindex", "tabIndex", "disabledDates", "title", "subtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "component", type: i4.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i4.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ParametersSectionComponent, decorators: [{
type: Component,
args: [{
selector: 'parameters-section',
template: `
<div *ngIf="parameter.isVisible" class="k-card trv-parameter-container">
<div class="k-card-header trv-parameter-header">
<div class="k-card-title trv-parameter-title" [title]="parameter.text">{{parameter.text}}</div>
</div>
<div class="k-card-body trv-parameter-value">
<div *ngIf="isInvalidInput(parameter)" class="k-notification k-notification-error trv-parameter-error">
<div class="k-notification-wrap">
<span class="k-icon k-i-warning"></span>
<span class="k-notification-content trv-parameter-error-message">{{' ' + service.options.messages.ReportViewer_InvalidParameter}}</span>
</div>
</div>
<div class="trv-parameter-editor-available-values">
<kendo-multiselect
*ngIf="parameter.multivalue && parameter.availableValues"
[data]="parameter.availableValues"
[valuePrimitive]="true"
textField="name"
valueField="value"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
[kendoDropDownFilter]="{caseSensitive: false, operator: 'contains'}"
>
</kendo-multiselect>
<kendo-combobox
*ngIf="!parameter.multivalue && parameter.availableValues"
[data]="parameter.availableValues"
[valuePrimitive]="true"
textField="name"
valueField="value"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
>
</kendo-combobox>
<div *ngIf="parameter.availableValues" class="k-actions k-actions-end trv-parameter-actions">
<button kendoButton *ngIf="parameter.multivalue" fillMode="outline" class="trv-select-all" (click)="onSelectAllClick(parameter)">Select all</button>
</div>
<kendo-datepicker *ngIf="parameter.type === 'System.DateTime' && !parameter.availableValues"
[value]="datepickerValue"
[disabled]="loading"
>
</kendo-datepicker>
<kendo-numerictextbox *ngIf="(parameter.type === 'System.Int64' || parameter.type ==='System.Double') && !parameter.availableValues"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
>
</kendo-numerictextbox>
<kendo-textbox *ngIf="parameter.type === 'System.String' && !parameter.availableValues"
[value]="parameter.value"
(valueChange)="onValueChange(parameter, $event)"
[disabled]="loading"
>
</kendo-textbox>
<input *ngIf="parameter.type === 'System.Boolean' && !parameter.availableValues"
type="checkbox"
kendoCheckBox
[id]="parameter.id"
[checked]="(parameter.value && parameter.value !== 'False') || parameter.value === 'True'"
(change)="onValueChange(parameter, $event)"
[disabled]="loading"
/>
</div>
</div>
</div>
`
}]
}], ctorParameters: function () { return [{ type: i1.ReportingAngularViewerService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { datePicker: [{
type: ViewChild,
args: [DatePickerComponent]
}], loading: [{
type: Input
}], parameter: [{
type: Input
}] } });
// TODO: This method is taken from HTML viewer
export function adjustTimezone(date) {
let result = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
return result;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVycy1zZWN0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcGFyYW1ldGVycy9wYXJhbWV0ZXJzLXNlY3Rpb24uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBRTlGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7O0FBR3BDLE1BQU0saUJBQWlCLEdBQUcsZ0JBQWdCLENBQUM7QUFDM0MsTUFBTSxrQkFBa0IsR0FBRyxpQkFBaUIsQ0FBQztBQTZFN0MsTUFBTSxPQUFPLDBCQUEwQjtJQXdCNUIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxTQUF3QjtRQUNqRCxJQUFJLFNBQVMsQ0FBQyxTQUFTLEVBQUU7WUFDckIsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFFRCxJQUFJLFNBQVMsQ0FBQyxVQUFVLEVBQUU7WUFDdEIsT0FBTyxTQUFTLENBQUMsS0FBSyxJQUFJLElBQUksSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7U0FDbEU7UUFFRCxPQUFPLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDO0lBQ25DLENBQUM7SUFFRCxZQUEwQixPQUFzQyxFQUFXLEdBQXNCO1FBQXZFLFlBQU8sR0FBUCxPQUFPLENBQStCO1FBQVcsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFqQ2pGLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFDZixjQUFTLEdBQWtCO1lBQ3ZDLElBQUksRUFBRSxFQUFFO1lBQ1IsSUFBSSxFQUFFLEVBQUU7WUFDUixJQUFJLEVBQUUsRUFBRTtZQUNSLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLFNBQVMsRUFBRSxL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c0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBJbnB1dCwgVmlld0NoaWxkLCBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwb3J0aW5nQW5ndWxhclZpZXdlclNlcnZpY2UgfSBmcm9tICcuLi9yZXBvcnRpbmctYW5ndWxhci12aWV3ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlUGlja2VyQ29tcG9uZW50IH0gZnJvbSAnQHByb2dyZXNzL2tlbmRvLWFuZ3VsYXItZGF0ZWlucHV0cyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFBhcmFtZXRlckluZm8sIFBhcmFtZXRlclZhbHVlIH0gZnJvbSAnQHByb2dyZXNzL3RlbGVyaWstY29tbW9uLXJlcG9ydC12aWV3ZXInO1xuXG5jb25zdCBTeXN0ZW1Cb29sZWFuVHlwZSA9ICdTeXN0ZW0uQm9vbGVhbic7XG5jb25zdCBTeXN0ZW1EYXRlVGltZVR5cGUgPSAnU3lzdGVtLkRhdGVUaW1lJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdwYXJhbWV0ZXJzLXNlY3Rpb24nLFxuICAgIHRlbXBsYXRlOiBgXG4gICAgICAgIDxkaXYgKm5nSWY9XCJwYXJhbWV0ZXIuaXNWaXNpYmxlXCIgY2xhc3M9XCJrLWNhcmQgdHJ2LXBhcmFtZXRlci1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJrLWNhcmQtaGVhZGVyIHRydi1wYXJhbWV0ZXItaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImstY2FyZC10aXRsZSB0cnYtcGFyYW1ldGVyLXRpdGxlXCIgW3RpdGxlXT1cInBhcmFtZXRlci50ZXh0XCI+e3twYXJhbWV0ZXIudGV4dH19PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJrLWNhcmQtYm9keSB0cnYtcGFyYW1ldGVyLXZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzSW52YWxpZElucHV0KHBhcmFtZXRlcilcIiBjbGFzcz1cImstbm90aWZpY2F0aW9uIGstbm90aWZpY2F0aW9uLWVycm9yIHRydi1wYXJhbWV0ZXItZXJyb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImstbm90aWZpY2F0aW9uLXdyYXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiay1pY29uIGstaS13YXJuaW5nXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJrLW5vdGlmaWNhdGlvbi1jb250ZW50IHRydi1wYXJhbWV0ZXItZXJyb3ItbWVzc2FnZVwiPnt7JyAnICsgc2VydmljZS5vcHRpb25zLm1lc3NhZ2VzLlJlcG9ydFZpZXdlcl9JbnZhbGlkUGFyYW1ldGVyfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0cnYtcGFyYW1ldGVyLWVkaXRvci1hdmFpbGFibGUtdmFsdWVzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxrZW5kby1tdWx0aXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJwYXJhbWV0ZXIubXVsdGl2YWx1ZSAmJiBwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhXT1cInBhcmFtZXRlci5hdmFpbGFibGVWYWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlUHJpbWl0aXZlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEZpZWxkPVwibmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUZpZWxkPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInBhcmFtZXRlci52YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwib25WYWx1ZUNoYW5nZShwYXJhbWV0ZXIsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2tlbmRvRHJvcERvd25GaWx0ZXJdPVwie2Nhc2VTZW5zaXRpdmU6IGZhbHNlLCBvcGVyYXRvcjogJ2NvbnRhaW5zJ31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8L2tlbmRvLW11bHRpc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8a2VuZG8tY29tYm9ib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXBhcmFtZXRlci5tdWx0aXZhbHVlICYmIHBhcmFtZXRlci5hdmFpbGFibGVWYWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGFdPVwicGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVQcmltaXRpdmVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0RmllbGQ9XCJuYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlRmllbGQ9XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGFyYW1ldGVyLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvblZhbHVlQ2hhbmdlKHBhcmFtZXRlciwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwva2VuZG8tY29tYm9ib3g+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCIgY2xhc3M9XCJrLWFjdGlvbnMgay1hY3Rpb25zLWVuZCB0cnYtcGFyYW1ldGVyLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24ga2VuZG9CdXR0b24gKm5nSWY9XCJwYXJhbWV0ZXIubXVsdGl2YWx1ZVwiIGZpbGxNb2RlPVwib3V0bGluZVwiIGNsYXNzPVwidHJ2LXNlbGVjdC1hbGxcIiAoY2xpY2spPVwib25TZWxlY3RBbGxDbGljayhwYXJhbWV0ZXIpXCI+U2VsZWN0IGFsbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8a2VuZG8tZGF0ZXBpY2tlciAqbmdJZj1cInBhcmFtZXRlci50eXBlID09PSAnU3lzdGVtLkRhdGVUaW1lJyAmJiAhcGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiZGF0ZXBpY2tlclZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9rZW5kby1kYXRlcGlja2VyPlxuXG4gICAgICAgICAgICAgICAgICAgIDxrZW5kby1udW1lcmljdGV4dGJveCAqbmdJZj1cIihwYXJhbWV0ZXIudHlwZSA9PT0gJ1N5c3RlbS5JbnQ2NCcgfHwgcGFyYW1ldGVyLnR5cGUgPT09J1N5c3RlbS5Eb3VibGUnKSAmJiAhcGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGFyYW1ldGVyLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvblZhbHVlQ2hhbmdlKHBhcmFtZXRlciwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwva2VuZG8tbnVtZXJpY3RleHRib3g+XG5cbiAgICAgICAgICAgICAgICAgICAgPGtlbmRvLXRleHRib3ggKm5nSWY9XCJwYXJhbWV0ZXIudHlwZSA9PT0gJ1N5c3RlbS5TdHJpbmcnICYmICFwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJwYXJhbWV0ZXIudmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uVmFsdWVDaGFuZ2UocGFyYW1ldGVyLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9rZW5kby10ZXh0Ym94PlxuXG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInBhcmFtZXRlci50eXBlID09PSAnU3lzdGVtLkJvb2xlYW4nICYmICFwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBrZW5kb0NoZWNrQm94XG4gICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwicGFyYW1ldGVyLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cIihwYXJhbWV0ZXIudmFsdWUgJiYgcGFyYW1ldGVyLnZhbHVlICE9PSAnRmFsc2UnKSB8fCBwYXJhbWV0ZXIudmFsdWUgPT09ICdUcnVlJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uVmFsdWVDaGFuZ2UocGFyYW1ldGVyLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgYFxufSlcbmV4cG9ydCBjbGFzcyBQYXJhbWV0ZXJzU2VjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICAgIEBWaWV3Q2hpbGQoRGF0ZVBpY2tlckNvbXBvbmVudCkgcHVibGljIGRhdGVQaWNrZXI6IERhdGVQaWNrZXJDb21wb25lbnQ7XG5cbiAgICBASW5wdXQoKSBwdWJsaWMgbG9hZGluZyA9IHRydWU7XG4gICAgQElucHV0KCkgcHVibGljIHBhcmFtZXRlcjogUGFyYW1ldGVySW5mbyA9IHtcbiAgICAgICAgbmFtZTogJycsXG4gICAgICAgIHR5cGU6ICcnLFxuICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgbXVsdGl2YWx1ZTogZmFsc2UsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsIFxuICAgICAgICBhbGxvd0JsYW5rOiBmYWxzZSxcbiAgICAgICAgaXNWaXNpYmxlOiBmYWxzZSwgXG4gICAgICAgIGF1dG9SZWZyZXNoOiBmYWxzZSxcbiAgICAgICAgaGFzQ2hpbGRQYXJhbWV0ZXJzOiBmYWxzZSxcbiAgICAgICAgY2hpbGRQYXJhbWV0ZXJzOiBbXSxcbiAgICAgICAgYXZhaWxhYmxlVmFsdWVzOiBbXSxcbiAgICAgICAgdmFsdWU6ICcnLFxuICAgICAgICBpZDogJycsXG4gICAgICAgIGxhYmVsOiAnJ1xuICAgIH07XG5cbiAgICBwdWJsaWMgZGF0ZXBpY2tlclZhbHVlOiBEYXRlID0gbmV3IERhdGUoKTtcbiAgICBpc0ludmFsaWRJbnB1dCA9IFBhcmFtZXRlcnNTZWN0aW9uQ29tcG9uZW50LmlzSW52YWxpZElucHV0XG5cbiAgICBwdWJsaWMgc3RhdGljIGlzSW52YWxpZElucHV0KHBhcmFtZXRlcjogUGFyYW1ldGVySW5mbyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAocGFyYW1ldGVyLmFsbG93TnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcmFtZXRlci5tdWx0aXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyYW1ldGVyLnZhbHVlID09IG51bGwgfHwgcGFyYW1ldGVyLnZhbHVlLmxlbmd0aCA9PT0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXJhbWV0ZXIudmFsdWUgPT0gbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHVibGljIHNlcnZpY2U6IFJlcG9ydGluZ0FuZ3VsYXJWaWV3ZXJTZXJ2aWNlLCAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kYXRlUGlja2VyPy52YWx1ZUNoYW5nZS5hc09ic2VydmFibGUoKS5waXBlKGRlYm91bmNlVGltZSh0aGlzLnBhcmFtZXRlci5hdXRvUmVmcmVzaCA/IDIwMDAgOiAwKSkuc3Vic2NyaWJlKHZhbHVlID0+IHtcbiAgICAgICAgICAgIHRoaXMub25WYWx1ZUNoYW5nZSh0aGlzLnBhcmFtZXRlciwgYWRqdXN0VGltZXpvbmUodmFsdWUpKTtcbiAgICAgICAgfSk7XG4gICAgICAgICAgICBcbiAgICAgICAgY29uc3QgcmVwb3J0RGF0ZVBhcmFtOiBQYXJhbWV0ZXJJbmZvID0gPFBhcmFtZXRlckluZm8+dGhpcy5zZXJ2aWNlLnBhcmFtZXRlcnMuZmluZChwID0+IHAudHlwZSA9PT0gU3lzdGVtRGF0ZVRpbWVUeXBlICYmIHAuaWQgPT09IHRoaXMucGFyYW1ldGVyLmlkKTtcbiAgICAgICAgdGhpcy5kYXRlcGlja2VyVmFsdWUgPSBuZXcgRGF0ZSg8c3RyaW5nPnJlcG9ydERhdGVQYXJhbT8udmFsdWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNsZWFyU2VsZWN0aW9uQ2xpY2socGFyYW06IFBhcmFtZXRlckluZm8pOiB2b2lkIHtcbiAgICAgICAgcGFyYW0udmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZWxlY3RBbGxDbGljayhwYXJhbWV0ZXI6IFBhcmFtZXRlckluZm8pOiB2b2lkIHtcbiAgICAgICAgcGFyYW1ldGVyLnZhbHVlID0gcGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlcy5tYXAoKHZhbDogUGFyYW1ldGVyVmFsdWUpID0+IHZhbC52YWx1ZSk7XG5cbiAgICAgICAgdGhpcy5zZXJ2aWNlLm9wdGlvbnMucmVwb3J0U291cmNlLnBhcmFtZXRlcnMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuc2VydmljZS5vcHRpb25zLnJlcG9ydFNvdXJjZS5wYXJhbWV0ZXJzKSk7XG4gICAgICAgIHRoaXMuc2VydmljZS5vcHRpb25zLnJlcG9ydFNvdXJjZS5wYXJhbWV0ZXJzW3BhcmFtZXRlci5pZF0gPSBwYXJhbWV0ZXIudmFsdWU7XG5cbiAgICAgICAgaWYgKCFwYXJhbWV0ZXIuYXV0b1JlZnJlc2ggfHwgIXRoaXMuc2VydmljZS5jb250cm9sbGVyLmF1dG9SdW5FbmFibGVkKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5zZXJ2aWNlLmFwcGx5UGFyYW1ldGVyKHBhcmFtZXRlci5pZCwgcGFyYW1ldGVyLnZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25WYWx1ZUNoYW5nZShwYXJhbWV0ZXI6IFBhcmFtZXRlckluZm8sIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgLy9UT0RPOiBzaG91bGQgYmUgcmVtb3ZlZCBvbmNlIHRoZSBjb21tb24gdmlld2VyIGFjY2VwdHMgbG93ZXIgY2FzZSB0cnVlL2ZhbHNlIHZhbHVlc1xuICAgICAgICBpZiAocGFyYW1ldGVyLnR5cGUgPT09IFN5c3RlbUJvb2xlYW5UeXBlKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRhcmdldC5jaGVja2VkID8gJ1RydWUnIDogJ0ZhbHNlJztcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtZXRlci52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVycyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5zZXJ2aWNlLm9wdGlvbnMucmVwb3J0U291cmNlLnBhcmFtZXRlcnMpKTtcblxuICAgICAgICAvLyBDYW4ndCBjaGVjayBmb3IgYWxsIGZhbHN5IHZhbHVlcyBiZWNhdXNlIDAgaXMgZmFsc3ksIHdvbid0IHdvcmsgd2l0aCBpbnRlZ2VyIHBhcmFtZXRlcnNcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUubGVuZ3RoID09PSAwKXtcbiAgICAgICAgICAgIHBhcmFtZXRlci52YWx1ZSA9IHZhbHVlID0gbnVsbDtcblxuICAgICAgICAgICAgaWYoIXBhcmFtZXRlci5hbGxvd051bGwpIHJldHVybjtcbiAgICAgICAgfSBcblxuICAgICAgICBpZiAocGFyYW1ldGVyLmNoaWxkUGFyYW1ldGVycz8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgcGFyYW1ldGVyLmNoaWxkUGFyYW1ldGVycy5mb3JFYWNoKChwYXJhbTogUGFyYW1ldGVySW5mbykgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVyc1twYXJhbS50b1N0cmluZygpXTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVyc1twYXJhbWV0ZXIuaWRdID0gcGFyYW1ldGVyLnZhbHVlO1xuXG4gICAgICAgICAgICBpZiAoIXBhcmFtZXRlci5hdXRvUmVmcmVzaCB8fCAhdGhpcy5zZXJ2aWNlLmNvbnRyb2xsZXIuYXV0b1J1bkVuYWJsZWQpIHJldHVybjtcblxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmNvbnRyb2xsZXIuc2V0UGFyYW1ldGVycyh0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVycyk7XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UuY29udHJvbGxlci5yZWZyZXNoUmVwb3J0KHRydWUsICcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5vcHRpb25zLnJlcG9ydFNvdXJjZS5wYXJhbWV0ZXJzW3BhcmFtZXRlci5pZF0gPSB2YWx1ZTtcblxuICAgICAgICAgICAgaWYgKCFwYXJhbWV0ZXIuYXV0b1JlZnJlc2ggfHwgIXRoaXMuc2VydmljZS5jb250cm9sbGVyLmF1dG9SdW5FbmFibGVkKSByZXR1cm47XG5cbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5hcHBseVBhcmFtZXRlcihwYXJhbWV0ZXIuaWQsIHZhbHVlKTtcblxuICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vLyBUT0RPOiBUaGlzIG1ldGhvZCBpcyB0YWtlbiBmcm9tIEhUTUwgdmlld2VyXG5leHBvcnQgZnVuY3Rpb24gYWRqdXN0VGltZXpvbmUoZGF0ZTogRGF0ZSkge1xuICAgIGxldCByZXN1bHQgPSBuZXcgRGF0ZShcbiAgICAgICAgRGF0ZS5VVEMoXG4gICAgICAgICAgICBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgICAgICBkYXRlLmdldE1vbnRoKCksXG4gICAgICAgICAgICBkYXRlLmdldERhdGUoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0TWludXRlcygpLFxuICAgICAgICAgICAgZGF0ZS5nZXRTZWNvbmRzKCksXG4gICAgICAgICAgICBkYXRlLmdldE1pbGxpc2Vjb25kcygpXG4gICAgICAgIClcbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG4iXX0=