@acrodata/gui 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ import { AfterViewInit, ChangeDetectorRef } from '@angular/core';
2
+ import { ControlValueAccessor } from '@angular/forms';
3
+ import { MtxSelect } from '@ng-matero/extensions/select';
4
+ import { GuiBasicValue, GuiControl } from '../interface';
5
+ import * as i0 from "@angular/core";
6
+ export declare class GuiCombobox implements ControlValueAccessor, AfterViewInit {
7
+ private cdr;
8
+ mtxSelect: MtxSelect;
9
+ config: Partial<GuiControl>;
10
+ disabled: boolean;
11
+ appendTo: string;
12
+ value: GuiBasicValue;
13
+ private onChange;
14
+ private onTouched;
15
+ constructor(cdr: ChangeDetectorRef);
16
+ ngAfterViewInit(): void;
17
+ writeValue(value: string | number): void;
18
+ registerOnChange(fn: (value: GuiBasicValue) => void): void;
19
+ registerOnTouched(fn: () => void): void;
20
+ setDisabledState(isDisabled: boolean): void;
21
+ onValueChange(): void;
22
+ addTagFn(label: string): {
23
+ label: string;
24
+ value: string;
25
+ };
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<GuiCombobox, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<GuiCombobox, "gui-combobox", never, { "config": { "alias": "config"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "appendTo": { "alias": "appendTo"; "required": false; }; }, {}, never, never, true, never>;
28
+ }
@@ -0,0 +1,41 @@
1
+ .gui-combobox {
2
+ .ng-select {
3
+ padding-left: 0.5rem;
4
+ padding-right: 0.5rem;
5
+ margin-left: -0.5rem;
6
+ margin-right: -0.5rem;
7
+
8
+ &.ng-select-multiple .ng-value {
9
+ flex-direction: row-reverse;
10
+ }
11
+
12
+ .ng-value-icon {
13
+ font-family: math;
14
+ font-size: 10px;
15
+ }
16
+
17
+ .ng-clear-wrapper .ng-clear {
18
+ font-family: math;
19
+ font-size: 12px;
20
+ }
21
+
22
+ .ng-arrow {
23
+ vertical-align: -1px;
24
+ }
25
+ }
26
+
27
+ &.ng-dropdown-panel {
28
+ padding: 0.5rem 0;
29
+
30
+ .ng-dropdown-panel-items {
31
+ .ng-option {
32
+ padding: 0 0.5rem;
33
+ line-height: var(--mat-option-label-text-line-height);
34
+
35
+ .ng-tag-label {
36
+ line-height: 1;
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,82 @@
1
+ import { ChangeDetectionStrategy, Component, forwardRef, Input, ViewChild, ViewEncapsulation, } from '@angular/core';
2
+ import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
3
+ import { MatFormField, MatHint, MatPrefix, MatSuffix } from '@angular/material/form-field';
4
+ import { MtxSelect, MtxSelectOptionTemplate } from '@ng-matero/extensions/select';
5
+ import { GuiFieldLabel } from '../field-label/field-label';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/forms";
8
+ export class GuiCombobox {
9
+ constructor(cdr) {
10
+ this.cdr = cdr;
11
+ this.config = {};
12
+ this.disabled = false;
13
+ this.appendTo = 'body';
14
+ this.value = '';
15
+ this.onChange = () => { };
16
+ this.onTouched = () => { };
17
+ }
18
+ ngAfterViewInit() {
19
+ // Add additional class for ng-select's dropdown panel
20
+ const { ngSelect } = this.mtxSelect;
21
+ ngSelect.classes = (ngSelect.classes || '') + ' gui-combobox';
22
+ }
23
+ writeValue(value) {
24
+ this.value = value;
25
+ this.cdr.markForCheck();
26
+ }
27
+ registerOnChange(fn) {
28
+ this.onChange = fn;
29
+ }
30
+ registerOnTouched(fn) {
31
+ this.onTouched = fn;
32
+ }
33
+ setDisabledState(isDisabled) {
34
+ this.disabled = isDisabled;
35
+ this.cdr.markForCheck();
36
+ }
37
+ onValueChange() {
38
+ this.onChange(this.value);
39
+ }
40
+ addTagFn(label) {
41
+ return { label, value: label };
42
+ }
43
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: GuiCombobox, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
44
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: GuiCombobox, isStandalone: true, selector: "gui-combobox", inputs: { config: "config", disabled: "disabled", appendTo: "appendTo" }, host: { classAttribute: "gui-field gui-combobox" }, providers: [
45
+ {
46
+ provide: NG_VALUE_ACCESSOR,
47
+ useExisting: forwardRef(() => GuiCombobox),
48
+ multi: true,
49
+ },
50
+ ], viewQueries: [{ propertyName: "mtxSelect", first: true, predicate: MtxSelect, descendants: true }], ngImport: i0, template: "<mat-form-field>\n @if (config.prefix) {\n <span matPrefix>{{ config.prefix }}</span>\n }\n <mtx-select\n [(ngModel)]=\"value\"\n [disabled]=\"disabled\"\n [placeholder]=\"config.placeholder || ''\"\n [appendTo]=\"appendTo\"\n [items]=\"config.options || []\"\n bindLabel=\"label\"\n bindValue=\"value\"\n [multiple]=\"config.multiple || false\"\n [addTag]=\"addTagFn\"\n [closeOnSelect]=\"!config.multiple\"\n [deselectOnClick]=\"true\"\n (change)=\"onValueChange()\"\n >\n <ng-template ng-option-tmp let-item=\"item\">\n <div class=\"ng-option-label\" [style.font-family]=\"config.useFont ? item.value : ''\">\n {{ item.label }}\n </div>\n </ng-template>\n </mtx-select>\n @if (config.suffix) {\n <span matSuffix>{{ config.suffix }}</span>\n }\n @if (config.parentType === 'inline') {\n <mat-hint>\n <gui-field-label [config]=\"config\" />\n </mat-hint>\n }\n</mat-form-field>\n", styles: [".gui-combobox .ng-select{padding-left:.5rem;padding-right:.5rem;margin-left:-.5rem;margin-right:-.5rem}.gui-combobox .ng-select.ng-select-multiple .ng-value{flex-direction:row-reverse}.gui-combobox .ng-select .ng-value-icon{font-family:math;font-size:10px}.gui-combobox .ng-select .ng-clear-wrapper .ng-clear{font-family:math;font-size:12px}.gui-combobox .ng-select .ng-arrow{vertical-align:-1px}.gui-combobox.ng-dropdown-panel{padding:.5rem 0}.gui-combobox.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{padding:0 .5rem;line-height:var(--mat-option-label-text-line-height)}.gui-combobox.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label{line-height:1}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: MtxSelect, selector: "mtx-select", inputs: ["addTag", "addTagText", "appearance", "appendTo", "bindLabel", "bindValue", "closeOnSelect", "clearAllText", "clearable", "clearOnBackspace", "compareWith", "dropdownPosition", "groupBy", "groupValue", "bufferAmount", "selectableGroup", "selectableGroupAsModel", "hideSelected", "loading", "loadingText", "labelForId", "markFirst", "maxSelectedItems", "multiple", "notFoundText", "searchable", "readonly", "searchFn", "searchWhileComposing", "selectOnTab", "trackByFn", "inputAttrs", "tabIndex", "openOnEnter", "minTermLength", "editableSearchTerm", "keyDownFn", "virtualScroll", "typeToSearchText", "typeahead", "isOpen", "fixedPlaceholder", "deselectOnClick", "clearSearchOnAdd", "items", "value", "id", "placeholder", "disabled", "required", "errorStateMatcher", "aria-label", "aria-labelledby"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"], exportAs: ["mtxSelect"] }, { kind: "directive", type: MtxSelectOptionTemplate, selector: "[ng-option-tmp]" }, { kind: "component", type: GuiFieldLabel, selector: "gui-field-label", inputs: ["config", "index"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
51
+ }
52
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: GuiCombobox, decorators: [{
53
+ type: Component,
54
+ args: [{ selector: 'gui-combobox', host: {
55
+ class: 'gui-field gui-combobox',
56
+ }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
57
+ {
58
+ provide: NG_VALUE_ACCESSOR,
59
+ useExisting: forwardRef(() => GuiCombobox),
60
+ multi: true,
61
+ },
62
+ ], standalone: true, imports: [
63
+ FormsModule,
64
+ MatFormField,
65
+ MatPrefix,
66
+ MatSuffix,
67
+ MatHint,
68
+ MtxSelect,
69
+ MtxSelectOptionTemplate,
70
+ GuiFieldLabel,
71
+ ], template: "<mat-form-field>\n @if (config.prefix) {\n <span matPrefix>{{ config.prefix }}</span>\n }\n <mtx-select\n [(ngModel)]=\"value\"\n [disabled]=\"disabled\"\n [placeholder]=\"config.placeholder || ''\"\n [appendTo]=\"appendTo\"\n [items]=\"config.options || []\"\n bindLabel=\"label\"\n bindValue=\"value\"\n [multiple]=\"config.multiple || false\"\n [addTag]=\"addTagFn\"\n [closeOnSelect]=\"!config.multiple\"\n [deselectOnClick]=\"true\"\n (change)=\"onValueChange()\"\n >\n <ng-template ng-option-tmp let-item=\"item\">\n <div class=\"ng-option-label\" [style.font-family]=\"config.useFont ? item.value : ''\">\n {{ item.label }}\n </div>\n </ng-template>\n </mtx-select>\n @if (config.suffix) {\n <span matSuffix>{{ config.suffix }}</span>\n }\n @if (config.parentType === 'inline') {\n <mat-hint>\n <gui-field-label [config]=\"config\" />\n </mat-hint>\n }\n</mat-form-field>\n", styles: [".gui-combobox .ng-select{padding-left:.5rem;padding-right:.5rem;margin-left:-.5rem;margin-right:-.5rem}.gui-combobox .ng-select.ng-select-multiple .ng-value{flex-direction:row-reverse}.gui-combobox .ng-select .ng-value-icon{font-family:math;font-size:10px}.gui-combobox .ng-select .ng-clear-wrapper .ng-clear{font-family:math;font-size:12px}.gui-combobox .ng-select .ng-arrow{vertical-align:-1px}.gui-combobox.ng-dropdown-panel{padding:.5rem 0}.gui-combobox.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{padding:0 .5rem;line-height:var(--mat-option-label-text-line-height)}.gui-combobox.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label{line-height:1}\n"] }]
72
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { mtxSelect: [{
73
+ type: ViewChild,
74
+ args: [MtxSelect]
75
+ }], config: [{
76
+ type: Input
77
+ }], disabled: [{
78
+ type: Input
79
+ }], appendTo: [{
80
+ type: Input
81
+ }] } });
82
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tYm9ib3guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9ndWkvY29tYm9ib3gvY29tYm9ib3gudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9ndWkvY29tYm9ib3gvY29tYm9ib3guaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsS0FBSyxFQUNMLFNBQVMsRUFDVCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0YsT0FBTyxFQUFFLFNBQVMsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7O0FBK0IzRCxNQUFNLE9BQU8sV0FBVztJQVl0QixZQUFvQixHQUFzQjtRQUF0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQVRqQyxXQUFNLEdBQXdCLEVBQUUsQ0FBQztRQUNqQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGFBQVEsR0FBRyxNQUFNLENBQUM7UUFFM0IsVUFBSyxHQUFrQixFQUFFLENBQUM7UUFFbEIsYUFBUSxHQUFtQyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFDcEQsY0FBUyxHQUFlLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztJQUVJLENBQUM7SUFFOUMsZUFBZTtRQUNiLHNEQUFzRDtRQUN0RCxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNwQyxRQUFRLENBQUMsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsR0FBRyxlQUFlLENBQUM7SUFDaEUsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFzQjtRQUMvQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxFQUFrQztRQUNqRCxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsaUJBQWlCLENBQUMsRUFBYztRQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQsZ0JBQWdCLENBQUMsVUFBbUI7UUFDbEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7UUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxRQUFRLENBQUMsS0FBYTtRQUNwQixPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUNqQyxDQUFDOzhHQTVDVSxXQUFXO2tHQUFYLFdBQVcseUxBbkJYO1lBQ1Q7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFpQjtnQkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUM7Z0JBQzFDLEtBQUssRUFBRSxJQUFJO2FBQ1o7U0FDRixxRUFjVSxTQUFTLGdEQzdDdEIsdThCQWlDQSxndUJEQ0ksV0FBVywrVkFDWCxZQUFZLDRMQUNaLFNBQVMscUhBQ1QsU0FBUyxxSEFDVCxPQUFPLDhFQUNQLFNBQVMsNitCQUNULHVCQUF1Qiw0REFDdkIsYUFBYTs7MkZBR0osV0FBVztrQkE1QnZCLFNBQVM7K0JBQ0UsY0FBYyxRQUdsQjt3QkFDSixLQUFLLEVBQUUsd0JBQXdCO3FCQUNoQyxpQkFDYyxpQkFBaUIsQ0FBQyxJQUFJLG1CQUNwQix1QkFBdUIsQ0FBQyxNQUFNLGFBQ3BDO3dCQUNUOzRCQUNFLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQzs0QkFDMUMsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0YsY0FDVyxJQUFJLFdBQ1A7d0JBQ1AsV0FBVzt3QkFDWCxZQUFZO3dCQUNaLFNBQVM7d0JBQ1QsU0FBUzt3QkFDVCxPQUFPO3dCQUNQLFNBQVM7d0JBQ1QsdUJBQXVCO3dCQUN2QixhQUFhO3FCQUNkO3NGQUdxQixTQUFTO3NCQUE5QixTQUFTO3VCQUFDLFNBQVM7Z0JBRVgsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBmb3J3YXJkUmVmLFxuICBJbnB1dCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybXNNb2R1bGUsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkLCBNYXRIaW50LCBNYXRQcmVmaXgsIE1hdFN1ZmZpeCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTXR4U2VsZWN0LCBNdHhTZWxlY3RPcHRpb25UZW1wbGF0ZSB9IGZyb20gJ0BuZy1tYXRlcm8vZXh0ZW5zaW9ucy9zZWxlY3QnO1xuaW1wb3J0IHsgR3VpRmllbGRMYWJlbCB9IGZyb20gJy4uL2ZpZWxkLWxhYmVsL2ZpZWxkLWxhYmVsJztcbmltcG9ydCB7IEd1aUJhc2ljVmFsdWUsIEd1aUNvbnRyb2wgfSBmcm9tICcuLi9pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdndWktY29tYm9ib3gnLFxuICB0ZW1wbGF0ZVVybDogJy4vY29tYm9ib3guaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9jb21ib2JveC5zY3NzJyxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnZ3VpLWZpZWxkIGd1aS1jb21ib2JveCcsXG4gIH0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IEd1aUNvbWJvYm94KSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gIF0sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBNYXRGb3JtRmllbGQsXG4gICAgTWF0UHJlZml4LFxuICAgIE1hdFN1ZmZpeCxcbiAgICBNYXRIaW50LFxuICAgIE10eFNlbGVjdCxcbiAgICBNdHhTZWxlY3RPcHRpb25UZW1wbGF0ZSxcbiAgICBHdWlGaWVsZExhYmVsLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBHdWlDb21ib2JveCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBBZnRlclZpZXdJbml0IHtcbiAgQFZpZXdDaGlsZChNdHhTZWxlY3QpIG10eFNlbGVjdCE6IE10eFNlbGVjdDtcblxuICBASW5wdXQoKSBjb25maWc6IFBhcnRpYWw8R3VpQ29udHJvbD4gPSB7fTtcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgYXBwZW5kVG8gPSAnYm9keSc7XG5cbiAgdmFsdWU6IEd1aUJhc2ljVmFsdWUgPSAnJztcblxuICBwcml2YXRlIG9uQ2hhbmdlOiAodmFsdWU6IEd1aUJhc2ljVmFsdWUpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgcHJpdmF0ZSBvblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIC8vIEFkZCBhZGRpdGlvbmFsIGNsYXNzIGZvciBuZy1zZWxlY3QncyBkcm9wZG93biBwYW5lbFxuICAgIGNvbnN0IHsgbmdTZWxlY3QgfSA9IHRoaXMubXR4U2VsZWN0O1xuICAgIG5nU2VsZWN0LmNsYXNzZXMgPSAobmdTZWxlY3QuY2xhc3NlcyB8fCAnJykgKyAnIGd1aS1jb21ib2JveCc7XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IEd1aUJhc2ljVmFsdWUpID0+IHZvaWQpIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCkge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uVmFsdWVDaGFuZ2UoKSB7XG4gICAgdGhpcy5vbkNoYW5nZSh0aGlzLnZhbHVlKTtcbiAgfVxuXG4gIGFkZFRhZ0ZuKGxhYmVsOiBzdHJpbmcpIHtcbiAgICByZXR1cm4geyBsYWJlbCwgdmFsdWU6IGxhYmVsIH07XG4gIH1cbn1cbiIsIjxtYXQtZm9ybS1maWVsZD5cbiAgQGlmIChjb25maWcucHJlZml4KSB7XG4gICAgPHNwYW4gbWF0UHJlZml4Pnt7IGNvbmZpZy5wcmVmaXggfX08L3NwYW4+XG4gIH1cbiAgPG10eC1zZWxlY3RcbiAgICBbKG5nTW9kZWwpXT1cInZhbHVlXCJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgIFtwbGFjZWhvbGRlcl09XCJjb25maWcucGxhY2Vob2xkZXIgfHwgJydcIlxuICAgIFthcHBlbmRUb109XCJhcHBlbmRUb1wiXG4gICAgW2l0ZW1zXT1cImNvbmZpZy5vcHRpb25zIHx8IFtdXCJcbiAgICBiaW5kTGFiZWw9XCJsYWJlbFwiXG4gICAgYmluZFZhbHVlPVwidmFsdWVcIlxuICAgIFttdWx0aXBsZV09XCJjb25maWcubXVsdGlwbGUgfHwgZmFsc2VcIlxuICAgIFthZGRUYWddPVwiYWRkVGFnRm5cIlxuICAgIFtjbG9zZU9uU2VsZWN0XT1cIiFjb25maWcubXVsdGlwbGVcIlxuICAgIFtkZXNlbGVjdE9uQ2xpY2tdPVwidHJ1ZVwiXG4gICAgKGNoYW5nZSk9XCJvblZhbHVlQ2hhbmdlKClcIlxuICA+XG4gICAgPG5nLXRlbXBsYXRlIG5nLW9wdGlvbi10bXAgbGV0LWl0ZW09XCJpdGVtXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibmctb3B0aW9uLWxhYmVsXCIgW3N0eWxlLmZvbnQtZmFtaWx5XT1cImNvbmZpZy51c2VGb250ID8gaXRlbS52YWx1ZSA6ICcnXCI+XG4gICAgICAgIHt7IGl0ZW0ubGFiZWwgfX1cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvbXR4LXNlbGVjdD5cbiAgQGlmIChjb25maWcuc3VmZml4KSB7XG4gICAgPHNwYW4gbWF0U3VmZml4Pnt7IGNvbmZpZy5zdWZmaXggfX08L3NwYW4+XG4gIH1cbiAgQGlmIChjb25maWcucGFyZW50VHlwZSA9PT0gJ2lubGluZScpIHtcbiAgICA8bWF0LWhpbnQ+XG4gICAgICA8Z3VpLWZpZWxkLWxhYmVsIFtjb25maWddPVwiY29uZmlnXCIgLz5cbiAgICA8L21hdC1oaW50PlxuICB9XG48L21hdC1mb3JtLWZpZWxkPlxuIl19