@tangential/input-widgets
Version:
Input Widgets with persistable, dynamic configuration.
250 lines (248 loc) • 24.6 kB
JavaScript
import { ChangeDetectorRef, Component, EventEmitter, forwardRef, HostBinding, Input, Output, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Hacks } from '@tangential/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/material/form-field";
import * as i4 from "@angular/material/input";
import * as i5 from "./number-slider-widget.component";
/**
* Provider Expression that allows this widget to register as a ControlValueAccessor.
* This allows it to support [(ngModel)].
* @docs-private
*/
export const TANJ_NUMBER_SLIDER_WIDGET_CONFIG_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumberSliderWidgetConfigureComponent),
multi: true
};
export class NumberSliderWidgetConfigureChange {
constructor(source, value) {
this.source = source;
this.value = value;
}
}
export class NumberSliderWidgetConfigureComponent {
constructor(changeDetectorRef) {
this.changeDetectorRef = changeDetectorRef;
this.flex = '';
this.flexLayout = 'column';
this.flexLayoutAlign = 'start';
this.value = 0;
this.valueChange = new EventEmitter(false);
this.labelPosition = 'below';
this.disabled = false;
/**
* Configuration Fields
*/
this.label = '';
this.defaultValue = 0;
this.max = 10;
this.min = 0;
this.step = 1;
this.decimalPlaces = 0;
this.labelChange = new EventEmitter(false);
this.defaultValueChange = new EventEmitter(false);
this.maxChange = new EventEmitter(false);
this.minChange = new EventEmitter(false);
this.stepChange = new EventEmitter(false);
this.decimalPlacesChange = new EventEmitter(false);
this.change = new EventEmitter(false);
/**
* Called when the spinner is blurred. Needed to properly implement ControlValueAccessor.
* @docs-private
*/
this.onTouched = () => { };
this.controlValueAccessorChangeFn = (value) => { };
}
ngOnInit() {
Hacks.materialDesignPlaceholderText(this.changeDetectorRef);
}
ngOnChanges(changes) {
}
emitChangeEvent(value, label) {
this.controlValueAccessorChangeFn(this.value);
this.change.emit(new NumberSliderWidgetConfigureChange(this, this.value));
if (value) {
this.valueChange.emit(this.value);
this.defaultValueChange.emit(this.defaultValue);
}
if (label) {
this.labelChange.emit(this.label);
}
}
/**
* Boilerplate / required for Angular
*
*/
writeValue(value) {
this.value = value;
}
registerOnChange(fn) {
this.controlValueAccessorChangeFn = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* Sets the input's disabled state. Implemented as a part of ControlValueAccessor.
* @param isDisabled Whether the input should be disabled.
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
}
NumberSliderWidgetConfigureComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: NumberSliderWidgetConfigureComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
NumberSliderWidgetConfigureComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: NumberSliderWidgetConfigureComponent, selector: "tanj-number-slider-configure", inputs: { value: "value", labelPosition: "labelPosition", disabled: "disabled", label: "label", defaultValue: "defaultValue", max: "max", min: "min", step: "step", decimalPlaces: "decimalPlaces" }, outputs: { valueChange: "valueChange", labelChange: "labelChange", defaultValueChange: "defaultValueChange", maxChange: "maxChange", minChange: "minChange", stepChange: "stepChange", decimalPlacesChange: "decimalPlacesChange", change: "change" }, host: { properties: { "attr.flex": "this.flex", "attr.layout": "this.flexLayout", "attr.layout-align": "this.flexLayoutAlign" } }, providers: [TANJ_NUMBER_SLIDER_WIDGET_CONFIG_CONTROL_VALUE_ACCESSOR], usesOnChanges: true, ngImport: i0, template: `<!-- -->
<div class="tanj-input-template tanj-mode-configure" flex layout="column" layout-align="start">
<mat-form-field dividerColor="accent">
<input matInput class="tanj-input" type="text" maxlength="50" placeholder="Enter a label for this input"
(change)="labelChange.emit(label)"
[(ngModel)]="label"/>
</mat-form-field>
<ng-container *ngIf="label">
<tanj-number-slider-widget [(value)]="defaultValue"
(valueChange)="value = defaultValue; emitChangeEvent(true, false)"
[defaultValue]="defaultValue"
[max]="max"
[min]="min"
[step]="step"
[decimalPlaces]="decimalPlaces"
label="Default Value"></tanj-number-slider-widget>
<mat-form-field dividerColor="accent">
<input matInput
class="tanj-input"
type="number"
placeholder="Min"
(change)="minChange.emit(min)"
[(ngModel)]="min"/>
</mat-form-field>
<mat-form-field dividerColor="accent">
<input matInput
class="tanj-input"
type="number"
placeholder="Max"
(change)="maxChange.emit(max)"
[(ngModel)]="max"/>
</mat-form-field>
<mat-form-field dividerColor="accent">
<input matInput
class="tanj-input"
type="number"
placeholder="Step"
(change)="stepChange.emit(step)"
[(ngModel)]="step"/>
</mat-form-field>
<mat-form-field dividerColor="accent">
<input matInput class="tanj-input"
type="number"
placeholder="Decimal Places"
(change)="decimalPlacesChange.emit(decimalPlaces)"
[(ngModel)]="decimalPlaces"/>
</mat-form-field>
</ng-container>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.NumberSliderWidgetComponent, selector: "tanj-number-slider-widget", inputs: ["value", "labelPosition", "disabled", "hideLabel", "onlyLabel", "label", "defaultValue", "max", "min", "step", "decimalPlaces", "tickInterval", "vertical"], outputs: ["valueChange", "change"] }], encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: NumberSliderWidgetConfigureComponent, decorators: [{
type: Component,
args: [{
selector: 'tanj-number-slider-configure',
template: `<!-- -->
<div class="tanj-input-template tanj-mode-configure" flex layout="column" layout-align="start">
<mat-form-field dividerColor="accent">
<input matInput class="tanj-input" type="text" maxlength="50" placeholder="Enter a label for this input"
(change)="labelChange.emit(label)"
[(ngModel)]="label"/>
</mat-form-field>
<ng-container *ngIf="label">
<tanj-number-slider-widget [(value)]="defaultValue"
(valueChange)="value = defaultValue; emitChangeEvent(true, false)"
[defaultValue]="defaultValue"
[max]="max"
[min]="min"
[step]="step"
[decimalPlaces]="decimalPlaces"
label="Default Value"></tanj-number-slider-widget>
<mat-form-field dividerColor="accent">
<input matInput
class="tanj-input"
type="number"
placeholder="Min"
(change)="minChange.emit(min)"
[(ngModel)]="min"/>
</mat-form-field>
<mat-form-field dividerColor="accent">
<input matInput
class="tanj-input"
type="number"
placeholder="Max"
(change)="maxChange.emit(max)"
[(ngModel)]="max"/>
</mat-form-field>
<mat-form-field dividerColor="accent">
<input matInput
class="tanj-input"
type="number"
placeholder="Step"
(change)="stepChange.emit(step)"
[(ngModel)]="step"/>
</mat-form-field>
<mat-form-field dividerColor="accent">
<input matInput class="tanj-input"
type="number"
placeholder="Decimal Places"
(change)="decimalPlacesChange.emit(decimalPlaces)"
[(ngModel)]="decimalPlaces"/>
</mat-form-field>
</ng-container>
</div>
`,
providers: [TANJ_NUMBER_SLIDER_WIDGET_CONFIG_CONTROL_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { flex: [{
type: HostBinding,
args: ['attr.flex']
}], flexLayout: [{
type: HostBinding,
args: ['attr.layout']
}], flexLayoutAlign: [{
type: HostBinding,
args: ['attr.layout-align']
}], value: [{
type: Input
}], valueChange: [{
type: Output
}], labelPosition: [{
type: Input
}], disabled: [{
type: Input
}], label: [{
type: Input
}], defaultValue: [{
type: Input
}], max: [{
type: Input
}], min: [{
type: Input
}], step: [{
type: Input
}], decimalPlaces: [{
type: Input
}], labelChange: [{
type: Output
}], defaultValueChange: [{
type: Output
}], maxChange: [{
type: Output
}], minChange: [{
type: Output
}], stepChange: [{
type: Output
}], decimalPlacesChange: [{
type: Output
}], change: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVtYmVyLXNsaWRlci13aWRnZXQtY29uZmlndXJlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdlbnRpYWwvaW5wdXQtd2lkZ2V0cy9zcmMvbGliL251bWJlci1zbGlkZXItd2lkZ2V0L251bWJlci1zbGlkZXItd2lkZ2V0LWNvbmZpZ3VyZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsS0FBSyxFQUdMLE1BQU0sRUFFTixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxFQUVMLGlCQUFpQixFQUNsQixNQUFNLGdCQUFnQixDQUFBO0FBQ3ZCLE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTs7Ozs7OztBQUd0Qzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sdURBQXVELEdBQVE7SUFDMUUsT0FBTyxFQUFNLGlCQUFpQjtJQUM5QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLG9DQUFvQyxDQUFDO0lBQ25FLEtBQUssRUFBUSxJQUFJO0NBQ2xCLENBQUM7QUFFRixNQUFNLE9BQU8saUNBQWlDO0lBQzVDLFlBQW1CLE1BQTRDLEVBQVMsS0FBYTtRQUFsRSxXQUFNLEdBQU4sTUFBTSxDQUFzQztRQUFTLFVBQUssR0FBTCxLQUFLLENBQVE7SUFDckYsQ0FBQztDQUNGO0FBMkRELE1BQU0sT0FBTyxvQ0FBb0M7SUF1Qy9DLFlBQW9CLGlCQUFvQztRQUFwQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBcEM5QixTQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ1IsZUFBVSxHQUFHLFFBQVEsQ0FBQztRQUNoQixvQkFBZSxHQUFHLE9BQU8sQ0FBQztRQUVuRCxVQUFLLEdBQVcsQ0FBQyxDQUFBO1FBQ2hCLGdCQUFXLEdBQXlCLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRTVELGtCQUFhLEdBQWlDLE9BQU8sQ0FBQTtRQUNyRCxhQUFRLEdBQVksS0FBSyxDQUFBO1FBRWxDOztXQUVHO1FBQ00sVUFBSyxHQUFXLEVBQUUsQ0FBQTtRQUNsQixpQkFBWSxHQUFXLENBQUMsQ0FBQTtRQUN4QixRQUFHLEdBQVcsRUFBRSxDQUFBO1FBQ2hCLFFBQUcsR0FBVyxDQUFDLENBQUE7UUFDZixTQUFJLEdBQVcsQ0FBQyxDQUFBO1FBQ2hCLGtCQUFhLEdBQVcsQ0FBQyxDQUFBO1FBRXhCLGdCQUFXLEdBQXlCLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQzNELHVCQUFrQixHQUF5QixJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNsRSxjQUFTLEdBQXlCLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3pELGNBQVMsR0FBeUIsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDekQsZUFBVSxHQUF5QixJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUMxRCx3QkFBbUIsR0FBeUIsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFbkUsV0FBTSxHQUFzQixJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUU3RDs7O1dBR0c7UUFDSCxjQUFTLEdBQWMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLGlDQUE0QixHQUF5QixDQUFDLEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRzVFLENBQUM7SUFFRCxRQUFRO1FBQ04sS0FBSyxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO0lBQzdELENBQUM7SUFFRCxXQUFXLENBQUMsT0FBcUQ7SUFDakUsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFjLEVBQUUsS0FBYztRQUM1QyxJQUFJLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUNBQWlDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQ3pFLElBQUksS0FBSyxFQUFFO1lBQ1QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFBO1NBQ2hEO1FBQ0QsSUFBSSxLQUFLLEVBQUU7WUFDVCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7U0FDbEM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksVUFBVSxDQUFDLEtBQWE7UUFDN0IsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUE7SUFDcEIsQ0FBQztJQUVNLGdCQUFnQixDQUFDLEVBQU87UUFDN0IsSUFBSSxDQUFDLDRCQUE0QixHQUFHLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRU0saUJBQWlCLENBQUMsRUFBTztRQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZ0JBQWdCLENBQUMsVUFBbUI7UUFDbEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7SUFDN0IsQ0FBQzs7a0lBbkZVLG9DQUFvQztzSEFBcEMsb0NBQW9DLHVuQkFIaEMsQ0FBQyx1REFBdUQsQ0FBQywrQ0FuRHpEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztrQkFrREM7NEZBSUwsb0NBQW9DO2tCQXhEaEQsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQU8sOEJBQThCO29CQUM3QyxRQUFRLEVBQU87Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O2tCQWtEQztvQkFDaEIsU0FBUyxFQUFNLENBQUMsdURBQXVELENBQUM7b0JBQ3hFLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO2lCQUN0Qzt3R0FJMkIsSUFBSTtzQkFBN0IsV0FBVzt1QkFBQyxXQUFXO2dCQUNJLFVBQVU7c0JBQXJDLFdBQVc7dUJBQUMsYUFBYTtnQkFDUSxlQUFlO3NCQUFoRCxXQUFXO3VCQUFDLG1CQUFtQjtnQkFFdkIsS0FBSztzQkFBYixLQUFLO2dCQUNJLFdBQVc7c0JBQXBCLE1BQU07Z0JBRUUsYUFBYTtzQkFBckIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUtHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxHQUFHO3NCQUFYLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csU0FBUztzQkFBbEIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUVHLE1BQU07c0JBQWYsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2UsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQge1xuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgTkdfVkFMVUVfQUNDRVNTT1Jcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnXG5pbXBvcnQge0hhY2tzfSBmcm9tICdAdGFuZ2VudGlhbC9jb3JlJ1xuXG5cbi8qKlxuICogUHJvdmlkZXIgRXhwcmVzc2lvbiB0aGF0IGFsbG93cyB0aGlzIHdpZGdldCB0byByZWdpc3RlciBhcyBhIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICogVGhpcyBhbGxvd3MgaXQgdG8gc3VwcG9ydCBbKG5nTW9kZWwpXS5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IFRBTkpfTlVNQkVSX1NMSURFUl9XSURHRVRfQ09ORklHX0NPTlRST0xfVkFMVUVfQUNDRVNTT1I6IGFueSA9IHtcbiAgcHJvdmlkZTogICAgIE5HX1ZBTFVFX0FDQ0VTU09SLFxuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOdW1iZXJTbGlkZXJXaWRnZXRDb25maWd1cmVDb21wb25lbnQpLFxuICBtdWx0aTogICAgICAgdHJ1ZVxufTtcblxuZXhwb3J0IGNsYXNzIE51bWJlclNsaWRlcldpZGdldENvbmZpZ3VyZUNoYW5nZSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzb3VyY2U6IE51bWJlclNsaWRlcldpZGdldENvbmZpZ3VyZUNvbXBvbmVudCwgcHVibGljIHZhbHVlOiBudW1iZXIpIHtcbiAgfVxufVxuXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogICAgICAndGFuai1udW1iZXItc2xpZGVyLWNvbmZpZ3VyZScsXG4gIHRlbXBsYXRlOiAgICAgIGA8IS0tIC0tPlxuICA8ZGl2IGNsYXNzPVwidGFuai1pbnB1dC10ZW1wbGF0ZSB0YW5qLW1vZGUtY29uZmlndXJlXCIgZmxleCBsYXlvdXQ9XCJjb2x1bW5cIiBsYXlvdXQtYWxpZ249XCJzdGFydFwiPlxuICAgIDxtYXQtZm9ybS1maWVsZCBkaXZpZGVyQ29sb3I9XCJhY2NlbnRcIj5cbiAgICAgIDxpbnB1dCBtYXRJbnB1dCBjbGFzcz1cInRhbmotaW5wdXRcIiB0eXBlPVwidGV4dFwiIG1heGxlbmd0aD1cIjUwXCIgcGxhY2Vob2xkZXI9XCJFbnRlciBhIGxhYmVsIGZvciB0aGlzIGlucHV0XCJcbiAgICAgICAgICAgICAoY2hhbmdlKT1cImxhYmVsQ2hhbmdlLmVtaXQobGFiZWwpXCJcbiAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImxhYmVsXCIvPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxhYmVsXCI+XG4gICAgICA8dGFuai1udW1iZXItc2xpZGVyLXdpZGdldCBbKHZhbHVlKV09XCJkZWZhdWx0VmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwidmFsdWUgPSBkZWZhdWx0VmFsdWU7IGVtaXRDaGFuZ2VFdmVudCh0cnVlLCBmYWxzZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGVmYXVsdFZhbHVlXT1cImRlZmF1bHRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhdPVwibWF4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJtaW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RlcF09XCJzdGVwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RlY2ltYWxQbGFjZXNdPVwiZGVjaW1hbFBsYWNlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPVwiRGVmYXVsdCBWYWx1ZVwiPjwvdGFuai1udW1iZXItc2xpZGVyLXdpZGdldD5cbiAgICAgIDxtYXQtZm9ybS1maWVsZCBkaXZpZGVyQ29sb3I9XCJhY2NlbnRcIj5cbiAgICAgICAgPGlucHV0IG1hdElucHV0XG4gICAgICAgICAgICAgICBjbGFzcz1cInRhbmotaW5wdXRcIlxuICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIk1pblwiXG4gICAgICAgICAgICAgICAoY2hhbmdlKT1cIm1pbkNoYW5nZS5lbWl0KG1pbilcIlxuICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJtaW5cIi8+XG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgPG1hdC1mb3JtLWZpZWxkIGRpdmlkZXJDb2xvcj1cImFjY2VudFwiPlxuICAgICAgICA8aW5wdXQgbWF0SW5wdXRcbiAgICAgICAgICAgICAgIGNsYXNzPVwidGFuai1pbnB1dFwiXG4gICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiTWF4XCJcbiAgICAgICAgICAgICAgIChjaGFuZ2UpPVwibWF4Q2hhbmdlLmVtaXQobWF4KVwiXG4gICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm1heFwiLz5cbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICA8bWF0LWZvcm0tZmllbGQgZGl2aWRlckNvbG9yPVwiYWNjZW50XCI+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgY2xhc3M9XCJ0YW5qLWlucHV0XCJcbiAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTdGVwXCJcbiAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic3RlcENoYW5nZS5lbWl0KHN0ZXApXCJcbiAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic3RlcFwiLz5cbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICA8bWF0LWZvcm0tZmllbGQgZGl2aWRlckNvbG9yPVwiYWNjZW50XCI+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBjbGFzcz1cInRhbmotaW5wdXRcIlxuICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkRlY2ltYWwgUGxhY2VzXCJcbiAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiZGVjaW1hbFBsYWNlc0NoYW5nZS5lbWl0KGRlY2ltYWxQbGFjZXMpXCJcbiAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZGVjaW1hbFBsYWNlc1wiLz5cbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgPC9kaXY+XG4gICAgICAgICAgICAgICAgIGAsXG4gIHByb3ZpZGVyczogICAgIFtUQU5KX05VTUJFUl9TTElERVJfV0lER0VUX0NPTkZJR19DT05UUk9MX1ZBTFVFX0FDQ0VTU09SXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBOdW1iZXJTbGlkZXJXaWRnZXRDb25maWd1cmVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuXG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmZsZXgnKSBmbGV4ID0gJyc7XG4gIEBIb3N0QmluZGluZygnYXR0ci5sYXlvdXQnKSBmbGV4TGF5b3V0ID0gJ2NvbHVtbic7XG4gIEBIb3N0QmluZGluZygnYXR0ci5sYXlvdXQtYWxpZ24nKSBmbGV4TGF5b3V0QWxpZ24gPSAnc3RhcnQnO1xuXG4gIEBJbnB1dCgpIHZhbHVlOiBudW1iZXIgPSAwXG4gIEBPdXRwdXQoKSB2YWx1ZUNoYW5nZTogRXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyKGZhbHNlKVxuXG4gIEBJbnB1dCgpIGxhYmVsUG9zaXRpb246ICdiZWZvcmUnIHwgJ2FmdGVyJyB8ICdiZWxvdycgPSAnYmVsb3cnXG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2VcblxuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBGaWVsZHNcbiAgICovXG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSAnJ1xuICBASW5wdXQoKSBkZWZhdWx0VmFsdWU6IG51bWJlciA9IDBcbiAgQElucHV0KCkgbWF4OiBudW1iZXIgPSAxMFxuICBASW5wdXQoKSBtaW46IG51bWJlciA9IDBcbiAgQElucHV0KCkgc3RlcDogbnVtYmVyID0gMVxuICBASW5wdXQoKSBkZWNpbWFsUGxhY2VzOiBudW1iZXIgPSAwXG5cbiAgQE91dHB1dCgpIGxhYmVsQ2hhbmdlOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpXG4gIEBPdXRwdXQoKSBkZWZhdWx0VmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSlcbiAgQE91dHB1dCgpIG1heENoYW5nZTogRXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyKGZhbHNlKVxuICBAT3V0cHV0KCkgbWluQ2hhbmdlOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpXG4gIEBPdXRwdXQoKSBzdGVwQ2hhbmdlOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpXG4gIEBPdXRwdXQoKSBkZWNpbWFsUGxhY2VzQ2hhbmdlOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpXG5cbiAgQE91dHB1dCgpIGNoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKGZhbHNlKVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgc3Bpbm5lciBpcyBibHVycmVkLiBOZWVkZWQgdG8gcHJvcGVybHkgaW1wbGVtZW50IENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICAgKiBAZG9jcy1wcml2YXRlXG4gICAqL1xuICBvblRvdWNoZWQ6ICgpID0+IGFueSA9ICgpID0+IHsgfTtcbiAgcHJpdmF0ZSBjb250cm9sVmFsdWVBY2Nlc3NvckNoYW5nZUZuOiAodmFsdWU6IGFueSkgPT4gdm9pZCA9ICh2YWx1ZSkgPT4geyB9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBIYWNrcy5tYXRlcmlhbERlc2lnblBsYWNlaG9sZGVyVGV4dCh0aGlzLmNoYW5nZURldGVjdG9yUmVmKVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogeyBjb25maWc6IFNpbXBsZUNoYW5nZSwgaXZhbDogU2ltcGxlQ2hhbmdlIH0pIHtcbiAgfVxuXG4gIGVtaXRDaGFuZ2VFdmVudCh2YWx1ZTogYm9vbGVhbiwgbGFiZWw6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmNvbnRyb2xWYWx1ZUFjY2Vzc29yQ2hhbmdlRm4odGhpcy52YWx1ZSk7XG4gICAgdGhpcy5jaGFuZ2UuZW1pdChuZXcgTnVtYmVyU2xpZGVyV2lkZ2V0Q29uZmlndXJlQ2hhbmdlKHRoaXMsIHRoaXMudmFsdWUpKVxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHRoaXMudmFsdWUpO1xuICAgICAgdGhpcy5kZWZhdWx0VmFsdWVDaGFuZ2UuZW1pdCh0aGlzLmRlZmF1bHRWYWx1ZSlcbiAgICB9XG4gICAgaWYgKGxhYmVsKSB7XG4gICAgICB0aGlzLmxhYmVsQ2hhbmdlLmVtaXQodGhpcy5sYWJlbClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQm9pbGVycGxhdGUgLyByZXF1aXJlZCBmb3IgQW5ndWxhclxuICAgKlxuICAgKi9cbiAgcHVibGljIHdyaXRlVmFsdWUodmFsdWU6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZVxuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbFZhbHVlQWNjZXNzb3JDaGFuZ2VGbiA9IGZuO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGlucHV0J3MgZGlzYWJsZWQgc3RhdGUuIEltcGxlbWVudGVkIGFzIGEgcGFydCBvZiBDb250cm9sVmFsdWVBY2Nlc3Nvci5cbiAgICogQHBhcmFtIGlzRGlzYWJsZWQgV2hldGhlciB0aGUgaW5wdXQgc2hvdWxkIGJlIGRpc2FibGVkLlxuICAgKi9cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gIH1cbn1cbiJdfQ==