@inspark/inspark-components 14.0.59 → 14.0.60

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.
@@ -1,11 +1,11 @@
1
- import { ChangeDetectorRef, EventEmitter, OnChanges, OnInit } from '@angular/core';
1
+ import { ChangeDetectorRef, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
2
2
  import { ControlValueAccessor } from '@angular/forms';
3
3
  import * as i0 from "@angular/core";
4
4
  declare type IconPos = 'left' | 'right';
5
- interface SelectOption {
5
+ export interface SelectOption {
6
6
  label: string;
7
7
  title?: string;
8
- value: any;
8
+ value: string | number | boolean;
9
9
  icon?: string;
10
10
  readonly?: boolean;
11
11
  }
@@ -21,37 +21,28 @@ export declare class SelectButtonComponent implements ControlValueAccessor, OnIn
21
21
  disabled: boolean;
22
22
  required: boolean;
23
23
  multiple: boolean;
24
- initial?: any[];
24
+ initial?: Array<string | number | boolean>;
25
25
  focus: EventEmitter<any>;
26
26
  blur: EventEmitter<any>;
27
27
  click: EventEmitter<any>;
28
28
  change: EventEmitter<any>;
29
- selected: any[];
30
- value: Object | Object[];
31
- bindingtype: any;
29
+ selected: Array<string | number | boolean>;
30
+ value: string | number | boolean | Array<string | number | boolean> | null;
31
+ private propagateChange;
32
+ private propagateTouched;
32
33
  constructor(cdRef: ChangeDetectorRef);
33
34
  ngOnInit(): void;
34
- ngOnChanges(): void;
35
- clickButton(option: any): boolean;
36
- /**
37
- * Write form value to the DOM element (model => view)
38
- */
35
+ ngOnChanges(changes: SimpleChanges): void;
36
+ clickButton(option: SelectOption): void;
39
37
  writeValue(value: any): void;
40
- /**
41
- * Write form disabled state to the DOM element (model => view)
42
- */
43
- setDisabledState(isDisabled: boolean): void;
44
- /**
45
- * Update form when DOM element value changes (view => model)
46
- */
47
38
  registerOnChange(fn: any): void;
48
- /**
49
- * Update form when DOM element is blurred (view => model)
50
- */
51
39
  registerOnTouched(fn: any): void;
52
- private propagateChange;
40
+ setDisabledState(isDisabled: boolean): void;
53
41
  private onChange;
54
- private onTouched;
42
+ onBlur(): void;
43
+ onFocus(): void;
44
+ private syncSelectedWithOptions;
45
+ trackByValue(index: number, item: SelectOption): string | number | boolean;
55
46
  static ɵfac: i0.ɵɵFactoryDeclaration<SelectButtonComponent, never>;
56
47
  static ɵcmp: i0.ɵɵComponentDeclaration<SelectButtonComponent, "in-select-button", never, { "name": "name"; "testId": "testId"; "label": "label"; "icon": "icon"; "error": "error"; "iconPos": "iconPos"; "options": "options"; "disabled": "disabled"; "required": "required"; "multiple": "multiple"; "initial": "initial"; }, { "focus": "focus"; "blur": "blur"; "click": "click"; "change": "change"; }, never, never, false>;
57
48
  }
@@ -1,4 +1,4 @@
1
- import { ChangeDetectorRef, Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
1
+ import { ChangeDetectorRef, Component, EventEmitter, forwardRef, Input, Output, } from '@angular/core';
2
2
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
3
  import * as i0 from "@angular/core";
4
4
  import * as i1 from "@angular/common";
@@ -14,38 +14,48 @@ export class SelectButtonComponent {
14
14
  this.error = '';
15
15
  this.iconPos = 'left';
16
16
  this.options = [];
17
+ this.disabled = false;
17
18
  this.required = false;
18
19
  this.multiple = false;
19
20
  this.focus = new EventEmitter();
20
21
  this.blur = new EventEmitter();
21
22
  this.click = new EventEmitter();
22
23
  this.change = new EventEmitter();
24
+ // хранит выбранные ЗНАЧЕНИЯ, а не объекты
23
25
  this.selected = [];
24
- this.propagateChange = (_) => {
25
- };
26
+ // то, что отдаем наружу в форму
27
+ this.value = null;
28
+ this.propagateChange = () => { };
29
+ this.propagateTouched = () => { };
26
30
  }
27
- ngOnInit() {
28
- }
29
- ngOnChanges() {
30
- if (this.initial) {
31
- this.selected = this.initial;
31
+ ngOnInit() { }
32
+ ngOnChanges(changes) {
33
+ // применяем initial только когда он реально поменялся
34
+ if (changes['initial'] && this.initial) {
35
+ this.selected = [...this.initial];
36
+ this.value = this.multiple ? [...this.initial] : this.initial[0] ?? null;
37
+ this.cdRef.detectChanges();
32
38
  }
33
- else {
34
- this.selected = [];
39
+ // если меняется список опций, надо попытаться восстановить выделение
40
+ if (changes['options'] && this.options && this.options.length > 0) {
41
+ this.syncSelectedWithOptions();
35
42
  }
36
43
  }
37
44
  clickButton(option) {
38
- if (option.readonly) {
39
- return false;
45
+ if (option.readonly || this.disabled) {
46
+ return;
40
47
  }
48
+ this.click.emit(option);
41
49
  if (this.multiple) {
42
- if (this.selected.indexOf(option.value) !== -1) {
43
- this.selected = this.selected.filter(item => item !== option.value);
50
+ if (this.selected.includes(option.value)) {
51
+ // убираем
52
+ this.selected = this.selected.filter(v => v !== option.value);
44
53
  }
45
54
  else {
46
- this.selected.push(option.value);
55
+ // добавляем
56
+ this.selected = [...this.selected, option.value];
47
57
  }
48
- this.value = this.options.filter(item => this.selected.indexOf(item.value) !== -1).map(val => val.value);
58
+ this.value = [...this.selected];
49
59
  }
50
60
  else {
51
61
  this.selected = [option.value];
@@ -54,46 +64,79 @@ export class SelectButtonComponent {
54
64
  this.cdRef.detectChanges();
55
65
  this.onChange();
56
66
  }
57
- /**
58
- * Write form value to the DOM element (model => view)
59
- */
67
+ // ControlValueAccessor: model -> view
60
68
  writeValue(value) {
61
69
  this.value = value;
62
- if (value !== null && value !== undefined) {
63
- if (Array.isArray(value)) {
64
- this.selected = value.map(val => val);
65
- }
66
- else {
67
- this.selected = [value];
68
- }
70
+ if (value === null || value === undefined) {
71
+ this.selected = [];
69
72
  }
73
+ else if (Array.isArray(value)) {
74
+ // multiple
75
+ this.selected = [...value];
76
+ }
77
+ else {
78
+ // single
79
+ this.selected = [value];
80
+ }
81
+ // когда значение пришло извне, надо убедиться что такие опции есть
82
+ this.syncSelectedWithOptions();
70
83
  this.cdRef.detectChanges();
71
84
  }
72
- /**
73
- * Write form disabled state to the DOM element (model => view)
74
- */
75
- setDisabledState(isDisabled) {
76
- this.disabled = isDisabled;
77
- }
78
- /**
79
- * Update form when DOM element value changes (view => model)
80
- */
85
+ // ControlValueAccessor
81
86
  registerOnChange(fn) {
82
- // Store the provided function as an internal method.
83
87
  this.propagateChange = fn;
84
88
  }
85
- /**
86
- * Update form when DOM element is blurred (view => model)
87
- */
89
+ // ControlValueAccessor
88
90
  registerOnTouched(fn) {
89
- // Store the provided function as an internal method.
90
- this.onTouched = fn;
91
+ this.propagateTouched = fn;
91
92
  }
93
+ // ControlValueAccessor: disabled
94
+ setDisabledState(isDisabled) {
95
+ this.disabled = isDisabled;
96
+ this.cdRef.detectChanges();
97
+ }
98
+ // пробросить наружу
92
99
  onChange() {
93
100
  this.propagateChange(this.value);
94
101
  this.change.emit(this.value);
95
102
  }
96
- onTouched() {
103
+ onBlur() {
104
+ this.propagateTouched();
105
+ this.blur.emit();
106
+ }
107
+ onFocus() {
108
+ this.focus.emit();
109
+ }
110
+ // синхронизируем текущее выбранное со свежими options
111
+ syncSelectedWithOptions() {
112
+ if (!this.options || this.options.length === 0) {
113
+ return;
114
+ }
115
+ if (this.multiple) {
116
+ // оставляем только те выбранные, которые реально есть в новых options
117
+ const optionValues = this.options.map(o => o.value);
118
+ this.selected = this.selected.filter(v => optionValues.includes(v));
119
+ this.value = [...this.selected];
120
+ }
121
+ else {
122
+ if (this.selected.length > 0) {
123
+ const current = this.selected[0];
124
+ const found = this.options.find(o => o.value === current);
125
+ if (!found) {
126
+ // выбранного больше нет в списке
127
+ this.selected = [];
128
+ this.value = null;
129
+ }
130
+ else {
131
+ this.selected = [found.value];
132
+ this.value = found.value;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ // для *ngFor trackBy
138
+ trackByValue(index, item) {
139
+ return item.value;
97
140
  }
98
141
  }
99
142
  SelectButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectButtonComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
@@ -102,8 +145,8 @@ SelectButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
102
145
  provide: NG_VALUE_ACCESSOR,
103
146
  useExisting: forwardRef(() => SelectButtonComponent),
104
147
  multi: true,
105
- }
106
- ], usesOnChanges: true, ngImport: i0, template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{label}}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{error}}</span>\n </span>\n<div class=\"container\">\n <in-button class=\"button-none\"></in-button>\n <in-button (click)=\"clickButton(option)\"\n *ngFor=\"let option of options\"\n [color]=\"selected.indexOf(option.value) === -1 ? 'normal': 'primary' \"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name] = option.label\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ButtonComponent, selector: "in-button", inputs: ["size", "color", "type", "name", "testId", "label", "icon", "className", "notify", "svg", "width", "link", "isLoading", "shadow", "isIconOnly", "linkType", "linkTarget", "pressed", "disabled", "iconPos", "selectedItem", "menuPlacement", "menuItems"], outputs: ["focus", "blur", "click"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
148
+ },
149
+ ], usesOnChanges: true, ngImport: i0, template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{ label }}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{ error }}</span>\n</span>\n\n<div class=\"container\">\n <!-- \u0444\u0438\u043A\u0442\u0438\u0432\u043D\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0430 \u0435\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 -->\n <in-button class=\"button-none\"></in-button>\n\n <in-button\n *ngFor=\"let option of options; trackBy: trackByValue\"\n (click)=\"clickButton(option)\"\n [color]=\"selected.includes(option.value) ? 'primary' : 'normal'\"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name]=\"option.label\"\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ButtonComponent, selector: "in-button", inputs: ["size", "color", "type", "name", "testId", "label", "icon", "className", "notify", "svg", "width", "link", "isLoading", "shadow", "isIconOnly", "linkType", "linkTarget", "pressed", "disabled", "iconPos", "selectedItem", "menuPlacement", "menuItems"], outputs: ["focus", "blur", "click"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
107
150
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectButtonComponent, decorators: [{
108
151
  type: Component,
109
152
  args: [{ selector: 'in-select-button', providers: [
@@ -111,8 +154,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
111
154
  provide: NG_VALUE_ACCESSOR,
112
155
  useExisting: forwardRef(() => SelectButtonComponent),
113
156
  multi: true,
114
- }
115
- ], template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{label}}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{error}}</span>\n </span>\n<div class=\"container\">\n <in-button class=\"button-none\"></in-button>\n <in-button (click)=\"clickButton(option)\"\n *ngFor=\"let option of options\"\n [color]=\"selected.indexOf(option.value) === -1 ? 'normal': 'primary' \"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name] = option.label\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"] }]
157
+ },
158
+ ], template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{ label }}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{ error }}</span>\n</span>\n\n<div class=\"container\">\n <!-- \u0444\u0438\u043A\u0442\u0438\u0432\u043D\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0430 \u0435\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 -->\n <in-button class=\"button-none\"></in-button>\n\n <in-button\n *ngFor=\"let option of options; trackBy: trackByValue\"\n (click)=\"clickButton(option)\"\n [color]=\"selected.includes(option.value) ? 'primary' : 'normal'\"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name]=\"option.label\"\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"] }]
116
159
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { name: [{
117
160
  type: Input
118
161
  }], testId: [{
@@ -144,4 +187,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
144
187
  }], change: [{
145
188
  type: Output
146
189
  }] } });
147
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnNwYXJrLWNvbXBvbmVudHMvc3JjL2NvbXBvbmVudHMvc2VsZWN0LWJ1dHRvbi9zZWxlY3QtYnV0dG9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2luc3BhcmstY29tcG9uZW50cy9zcmMvY29tcG9uZW50cy9zZWxlY3QtYnV0dG9uL3NlbGVjdC1idXR0b24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3ZILE9BQU8sRUFBdUIsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7QUEwQnZFLE1BQU0sT0FBTyxxQkFBcUI7SUF5QmhDLFlBQW9CLEtBQXdCO1FBQXhCLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBdkJuQyxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ1YsV0FBTSxHQUFHLEVBQUUsQ0FBQztRQUNaLFVBQUssR0FBRyxFQUFFLENBQUM7UUFDWCxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ1YsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUNYLFlBQU8sR0FBWSxNQUFNLENBQUM7UUFDMUIsWUFBTyxHQUFtQixFQUFFLENBQUM7UUFFN0IsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBR2hCLFVBQUssR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUM5QyxTQUFJLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDN0MsVUFBSyxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzlDLFdBQU0sR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FB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Qy9CLENBQUM7SUFFTyxTQUFTO0lBQ2pCLENBQUM7O2tIQTFHVSxxQkFBcUI7c0dBQXJCLHFCQUFxQixnVkFSckI7UUFDVDtZQUNFLE9BQU8sRUFBRSxpQkFBaUI7WUFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQztZQUNwRCxLQUFLLEVBQUUsSUFBSTtTQUNaO0tBQ0YsK0NDekJILHd6QkFtQkE7MkZEUWEscUJBQXFCO2tCQVpqQyxTQUFTOytCQUNFLGtCQUFrQixhQUdqQjt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsaUJBQWlCOzRCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxzQkFBc0IsQ0FBQzs0QkFDcEQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7d0dBSVEsSUFBSTtzQkFBWixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFFSSxLQUFLO3NCQUFkLE1BQU07Z0JBQ0csSUFBSTtzQkFBYixNQUFNO2dCQUNHLEtBQUs7c0JBQWQsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgZm9yd2FyZFJlZiwgSW5wdXQsIE9uQ2hhbmdlcywgT25Jbml0LCBPdXRwdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1J9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuXG50eXBlIEljb25Qb3MgPSAnbGVmdCcgfCAncmlnaHQnO1xuXG5pbnRlcmZhY2UgU2VsZWN0T3B0aW9uIHtcbiAgbGFiZWw6IHN0cmluZztcbiAgdGl0bGU/OiBzdHJpbmc7XG4gIHZhbHVlOiBhbnk7XG4gIGljb24/OiBzdHJpbmc7XG4gIHJlYWRvbmx5PzogYm9vbGVhbjtcbn1cblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdpbi1zZWxlY3QtYnV0dG9uJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3NlbGVjdC1idXR0b24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zZWxlY3QtYnV0dG9uLmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gU2VsZWN0QnV0dG9uQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH1cbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgU2VsZWN0QnV0dG9uQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKSBuYW1lID0gJyc7XG4gIEBJbnB1dCgpIHRlc3RJZCA9ICcnO1xuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xuICBASW5wdXQoKSBpY29uID0gJyc7XG4gIEBJbnB1dCgpIGVycm9yID0gJyc7XG4gIEBJbnB1dCgpIGljb25Qb3M6IEljb25Qb3MgPSAnbGVmdCc7XG4gIEBJbnB1dCgpIG9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gW107XG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuO1xuICBASW5wdXQoKSByZXF1aXJlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBtdWx0aXBsZSA9IGZhbHNlO1xuICBASW5wdXQoKSBpbml0aWFsPzogYW55W107XG5cbiAgQE91dHB1dCgpIGZvY3VzOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGJsdXI6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgY2xpY2s6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgY2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBzZWxlY3RlZCA9IFtdO1xuXG4gIHZhbHVlOiBPYmplY3QgfCBPYmplY3RbXTtcblxuICBiaW5kaW5ndHlwZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuXG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIGlmICh0aGlzLmluaXRpYWwpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLmluaXRpYWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSBbXTtcbiAgICB9XG4gIH1cblxuICBjbGlja0J1dHRvbihvcHRpb24pIHtcbiAgICBpZiAob3B0aW9uLnJlYWRvbmx5KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZC5pbmRleE9mKG9wdGlvbi52YWx1ZSkgIT09IC0xKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkLmZpbHRlcihpdGVtID0+IGl0ZW0gIT09IG9wdGlvbi52YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNlbGVjdGVkLnB1c2gob3B0aW9uLnZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm9wdGlvbnMuZmlsdGVyKGl0ZW0gPT4gdGhpcy5zZWxlY3RlZC5pbmRleE9mKGl0ZW0udmFsdWUpICE9PSAtMSkubWFwKHZhbCA9PiB2YWwudmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkID0gW29wdGlvbi52YWx1ZV07XG4gICAgICB0aGlzLnZhbHVlID0gb3B0aW9uLnZhbHVlO1xuICAgIH1cbiAgICB0aGlzLmNkUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICB0aGlzLm9uQ2hhbmdlKCk7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgZm9ybSB2YWx1ZSB0byB0aGUgRE9NIGVsZW1lbnQgKG1vZGVsID0+IHZpZXcpXG4gICAqL1xuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gdmFsdWUubWFwKHZhbCA9PiB2YWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZCA9IFt2YWx1ZV07XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlIGZvcm0gZGlzYWJsZWQgc3RhdGUgdG8gdGhlIERPTSBlbGVtZW50IChtb2RlbCA9PiB2aWV3KVxuICAgKi9cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGZvcm0gd2hlbiBET00gZWxlbWVudCB2YWx1ZSBjaGFuZ2VzICh2aWV3ID0+IG1vZGVsKVxuICAgKi9cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XG4gICAgLy8gU3RvcmUgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uIGFzIGFuIGludGVybmFsIG1ldGhvZC5cbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBmb3JtIHdoZW4gRE9NIGVsZW1lbnQgaXMgYmx1cnJlZCAodmlldyA9PiBtb2RlbClcbiAgICovXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICAvLyBTdG9yZSB0aGUgcHJvdmlkZWQgZnVuY3Rpb24gYXMgYW4gaW50ZXJuYWwgbWV0aG9kLlxuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBwcml2YXRlIHByb3BhZ2F0ZUNoYW5nZSA9IChfOiBhbnkpID0+IHtcbiAgfVxuXG4gIHByaXZhdGUgb25DaGFuZ2UoKSB7XG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UodGhpcy52YWx1ZSk7XG4gICAgdGhpcy5jaGFuZ2UuZW1pdCh0aGlzLnZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgb25Ub3VjaGVkKCkge1xuICB9XG59XG4iLCI8c3BhbiAqbmdJZj1cImxhYmVsXCIgY2xhc3M9XCJjLWxhYmVsX19jb250ZW50XCI+XG4gICAgICAgIHt7bGFiZWx9fVxuICA8c3BhbiAqbmdJZj1cInJlcXVpcmVkXCIgY2xhc3M9XCJjLWxhYmVsX19yZXFcIj4qPC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cImVycm9yXCIgY2xhc3M9XCJjLWxhYmVsX19zdWJfaXMtZXJyb3JcIj57e2Vycm9yfX08L3NwYW4+XG4gICAgPC9zcGFuPlxuPGRpdiBjbGFzcz1cImNvbnRhaW5lclwiPlxuICA8aW4tYnV0dG9uIGNsYXNzPVwiYnV0dG9uLW5vbmVcIj48L2luLWJ1dHRvbj5cbiAgPGluLWJ1dHRvbiAoY2xpY2spPVwiY2xpY2tCdXR0b24ob3B0aW9uKVwiXG4gICAgICAgICAgICAgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBvcHRpb25zXCJcbiAgICAgICAgICAgICBbY29sb3JdPVwic2VsZWN0ZWQuaW5kZXhPZihvcHRpb24udmFsdWUpID09PSAtMSA/ICdub3JtYWwnOiAncHJpbWFyeScgXCJcbiAgICAgICAgICAgICBbaWNvbl09XCJvcHRpb24uaWNvblwiXG4gICAgICAgICAgICAgW2xhYmVsXT1cIm9wdGlvbi5sYWJlbCB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgW3Rlc3RJZF09XCInZmlsdGVyLWJ1dHRvbnMtJyArIG9wdGlvbi52YWx1ZVwiXG4gICAgICAgICAgICAgW3RpdGxlXT1cIm9wdGlvbi50aXRsZSA/IChvcHRpb24udGl0bGUgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgICAgICAgICAgIFtuYW1lXSA9IG9wdGlvbi5sYWJlbFxuICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJvcHRpb24ucmVhZG9ubHkgfHwgZGlzYWJsZWRcIlxuICA+XG4gIDwvaW4tYnV0dG9uPlxuPC9kaXY+XG4iXX0=
190
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnNwYXJrLWNvbXBvbmVudHMvc3JjL2NvbXBvbmVudHMvc2VsZWN0LWJ1dHRvbi9zZWxlY3QtYnV0dG9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2luc3BhcmstY29tcG9uZW50cy9zcmMvY29tcG9uZW50cy9zZWxlY3QtYnV0dG9uL3NlbGVjdC1idXR0b24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBR0wsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBdUIsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7QUF3QnZFLE1BQU0sT0FBTyxxQkFBcUI7SUE2QmhDLFlBQW9CLEtBQXdCO1FBQXhCLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBMUJuQyxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ1YsV0FBTSxHQUFHLEVBQUUsQ0FBQztRQUNaLFVBQUssR0FBRyxFQUFFLENBQUM7UUFDWCxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ1YsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUNYLFlBQU8sR0FBWSxNQUFNLENBQUM7UUFDMUIsWUFBTyxHQUFtQixFQUFFLENBQUM7UUFDN0IsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFHaEIsVUFBSyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDaEMsU0FBSSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDL0IsVUFBSyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDaEMsV0FBTSxH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S0FBSyxFQUFFLElBQUk7U0FDWjtLQUNGLCtDQ2pDSCxpOUJBdUJBOzJGRFlhLHFCQUFxQjtrQkFaakMsU0FBUzsrQkFDRSxrQkFBa0IsYUFHakI7d0JBQ1Q7NEJBQ0UsT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsc0JBQXNCLENBQUM7NEJBQ3BELEtBQUssRUFBRSxJQUFJO3lCQUNaO3FCQUNGO3dHQUtRLElBQUk7c0JBQVosS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUksS0FBSztzQkFBZCxNQUFNO2dCQUNHLElBQUk7c0JBQWIsTUFBTTtnQkFDRyxLQUFLO3NCQUFkLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG50eXBlIEljb25Qb3MgPSAnbGVmdCcgfCAncmlnaHQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdE9wdGlvbiB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHRpdGxlPzogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbjsgLy8g0LLQsNC20L3Qvjog0L/RgNC40LzQuNGC0LjQslxuICBpY29uPzogc3RyaW5nO1xuICByZWFkb25seT86IGJvb2xlYW47XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2luLXNlbGVjdC1idXR0b24nLFxuICB0ZW1wbGF0ZVVybDogJy4vc2VsZWN0LWJ1dHRvbi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NlbGVjdC1idXR0b24uY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBTZWxlY3RCdXR0b25Db21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgU2VsZWN0QnV0dG9uQ29tcG9uZW50XG4gIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKSBuYW1lID0gJyc7XG4gIEBJbnB1dCgpIHRlc3RJZCA9ICcnO1xuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xuICBASW5wdXQoKSBpY29uID0gJyc7XG4gIEBJbnB1dCgpIGVycm9yID0gJyc7XG4gIEBJbnB1dCgpIGljb25Qb3M6IEljb25Qb3MgPSAnbGVmdCc7XG4gIEBJbnB1dCgpIG9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gW107XG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIHJlcXVpcmVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIG11bHRpcGxlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGluaXRpYWw/OiBBcnJheTxzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPjtcblxuICBAT3V0cHV0KCkgZm9jdXMgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIGJsdXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIGNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBjaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAvLyDRhdGA0LDQvdC40YIg0LLRi9Cx0YDQsNC90L3Ri9C1INCX0J3QkNCn0JXQndCY0K8sINCwINC90LUg0L7QsdGK0LXQutGC0YtcbiAgc2VsZWN0ZWQ6IEFycmF5PHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4+ID0gW107XG5cbiAgLy8g0YLQviwg0YfRgtC+INC+0YLQtNCw0LXQvCDQvdCw0YDRg9C20YMg0LIg0YTQvtGA0LzRg1xuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IEFycmF5PHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4+IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBwcm9wYWdhdGVDaGFuZ2U6ICh2YWw6IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBwcml2YXRlIHByb3BhZ2F0ZVRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vINC/0YDQuNC80LXQvdGP0LXQvCBpbml0aWFsINGC0L7Qu9GM0LrQviDQutC+0LPQtNCwINC+0L0g0YDQtdCw0LvRjNC90L4g0L/QvtC80LXQvdGP0LvRgdGPXG4gICAgaWYgKGNoYW5nZXNbJ2luaXRpYWwnXSAmJiB0aGlzLmluaXRpYWwpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSBbLi4udGhpcy5pbml0aWFsXTtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm11bHRpcGxlID8gWy4uLnRoaXMuaW5pdGlhbF0gOiB0aGlzLmluaXRpYWxbMF0gPz8gbnVsbDtcbiAgICAgIHRoaXMuY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIC8vINC10YHQu9C4INC80LXQvdGP0LXRgtGB0Y8g0YHQv9C40YHQvtC6INC+0L/RhtC40LksINC90LDQtNC+INC/0L7Qv9GL0YLQsNGC0YzRgdGPINCy0L7RgdGB0YLQsNC90L7QstC40YLRjCDQstGL0LTQtdC70LXQvdC40LVcbiAgICBpZiAoY2hhbmdlc1snb3B0aW9ucyddICYmIHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zeW5jU2VsZWN0ZWRXaXRoT3B0aW9ucygpO1xuICAgIH1cbiAgfVxuXG4gIGNsaWNrQnV0dG9uKG9wdGlvbjogU2VsZWN0T3B0aW9uKTogdm9pZCB7XG4gICAgaWYgKG9wdGlvbi5yZWFkb25seSB8fCB0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jbGljay5lbWl0KG9wdGlvbik7XG5cbiAgICBpZiAodGhpcy5tdWx0aXBsZSkge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWQuaW5jbHVkZXMob3B0aW9uLnZhbHVlKSkge1xuICAgICAgICAvLyDRg9Cx0LjRgNCw0LXQvFxuICAgICAgICB0aGlzLnNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZC5maWx0ZXIodiA9PiB2ICE9PSBvcHRpb24udmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g0LTQvtCx0LDQstC70Y/QtdC8XG4gICAgICAgIHRoaXMuc2VsZWN0ZWQgPSBbLi4udGhpcy5zZWxlY3RlZCwgb3B0aW9uLnZhbHVlXTtcbiAgICAgIH1cbiAgICAgIHRoaXMudmFsdWUgPSBbLi4udGhpcy5zZWxlY3RlZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSBbb3B0aW9uLnZhbHVlXTtcbiAgICAgIHRoaXMudmFsdWUgPSBvcHRpb24udmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgdGhpcy5vbkNoYW5nZSgpO1xuICB9XG5cbiAgLy8gQ29udHJvbFZhbHVlQWNjZXNzb3I6IG1vZGVsIC0+IHZpZXdcbiAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuXG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSBbXTtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAvLyBtdWx0aXBsZVxuICAgICAgdGhpcy5zZWxlY3RlZCA9IFsuLi52YWx1ZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHNpbmdsZVxuICAgICAgdGhpcy5zZWxlY3RlZCA9IFt2YWx1ZV07XG4gICAgfVxuXG4gICAgLy8g0LrQvtCz0LTQsCDQt9C90LDRh9C10L3QuNC1INC/0YDQuNGI0LvQviDQuNC30LLQvdC1LCDQvdCw0LTQviDRg9Cx0LXQtNC40YLRjNGB0Y8g0YfRgtC+INGC0LDQutC40LUg0L7Qv9GG0LjQuCDQtdGB0YLRjFxuICAgIHRoaXMuc3luY1NlbGVjdGVkV2l0aE9wdGlvbnMoKTtcbiAgICB0aGlzLmNkUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8vIENvbnRyb2xWYWx1ZUFjY2Vzc29yXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMucHJvcGFnYXRlQ2hhbmdlID0gZm47XG4gIH1cblxuICAvLyBDb250cm9sVmFsdWVBY2Nlc3NvclxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5wcm9wYWdhdGVUb3VjaGVkID0gZm47XG4gIH1cblxuICAvLyBDb250cm9sVmFsdWVBY2Nlc3NvcjogZGlzYWJsZWRcbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvLyDQv9GA0L7QsdGA0L7RgdC40YLRjCDQvdCw0YDRg9C20YNcbiAgcHJpdmF0ZSBvbkNoYW5nZSgpOiB2b2lkIHtcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0aGlzLnZhbHVlKTtcbiAgICB0aGlzLmNoYW5nZS5lbWl0KHRoaXMudmFsdWUpO1xuICB9XG5cbiAgb25CbHVyKCk6IHZvaWQge1xuICAgIHRoaXMucHJvcGFnYXRlVG91Y2hlZCgpO1xuICAgIHRoaXMuYmx1ci5lbWl0KCk7XG4gIH1cblxuICBvbkZvY3VzKCk6IHZvaWQge1xuICAgIHRoaXMuZm9jdXMuZW1pdCgpO1xuICB9XG5cbiAgLy8g0YHQuNC90YXRgNC+0L3QuNC30LjRgNGD0LXQvCDRgtC10LrRg9GJ0LXQtSDQstGL0LHRgNCw0L3QvdC+0LUg0YHQviDRgdCy0LXQttC40LzQuCBvcHRpb25zXG4gIHByaXZhdGUgc3luY1NlbGVjdGVkV2l0aE9wdGlvbnMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMgfHwgdGhpcy5vcHRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICAvLyDQvtGB0YLQsNCy0LvRj9C10Lwg0YLQvtC70YzQutC+INGC0LUg0LLRi9Cx0YDQsNC90L3Ri9C1LCDQutC+0YLQvtGA0YvQtSDRgNC10LDQu9GM0L3QviDQtdGB0YLRjCDQsiDQvdC+0LLRi9GFIG9wdGlvbnNcbiAgICAgIGNvbnN0IG9wdGlvblZhbHVlcyA9IHRoaXMub3B0aW9ucy5tYXAobyA9PiBvLnZhbHVlKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkLmZpbHRlcih2ID0+IG9wdGlvblZhbHVlcy5pbmNsdWRlcyh2KSk7XG4gICAgICB0aGlzLnZhbHVlID0gWy4uLnRoaXMuc2VsZWN0ZWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnNlbGVjdGVkWzBdO1xuICAgICAgICBjb25zdCBmb3VuZCA9IHRoaXMub3B0aW9ucy5maW5kKG8gPT4gby52YWx1ZSA9PT0gY3VycmVudCk7XG4gICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICAvLyDQstGL0LHRgNCw0L3QvdC+0LPQviDQsdC+0LvRjNGI0LUg0L3QtdGCINCyINGB0L/QuNGB0LrQtVxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWQgPSBbXTtcbiAgICAgICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkID0gW2ZvdW5kLnZhbHVlXTtcbiAgICAgICAgICB0aGlzLnZhbHVlID0gZm91bmQudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyDQtNC70Y8gKm5nRm9yIHRyYWNrQnlcbiAgdHJhY2tCeVZhbHVlKGluZGV4OiBudW1iZXIsIGl0ZW06IFNlbGVjdE9wdGlvbik6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4ge1xuICAgIHJldHVybiBpdGVtLnZhbHVlO1xuICB9XG59XG4iLCI8c3BhbiAqbmdJZj1cImxhYmVsXCIgY2xhc3M9XCJjLWxhYmVsX19jb250ZW50XCI+XG4gIHt7IGxhYmVsIH19XG4gIDxzcGFuICpuZ0lmPVwicmVxdWlyZWRcIiBjbGFzcz1cImMtbGFiZWxfX3JlcVwiPio8L3NwYW4+XG4gIDxzcGFuICpuZ0lmPVwiZXJyb3JcIiBjbGFzcz1cImMtbGFiZWxfX3N1Yl9pcy1lcnJvclwiPnt7IGVycm9yIH19PC9zcGFuPlxuPC9zcGFuPlxuXG48ZGl2IGNsYXNzPVwiY29udGFpbmVyXCI+XG4gIDwhLS0g0YTQuNC60YLQuNCy0L3QsNGPINC60L3QvtC/0LrQsCDQtdGB0LvQuCDQvdGD0LbQvdCwINGA0LDQt9C80LXRgtC60LAgLS0+XG4gIDxpbi1idXR0b24gY2xhc3M9XCJidXR0b24tbm9uZVwiPjwvaW4tYnV0dG9uPlxuXG4gIDxpbi1idXR0b25cbiAgICAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIG9wdGlvbnM7IHRyYWNrQnk6IHRyYWNrQnlWYWx1ZVwiXG4gICAgKGNsaWNrKT1cImNsaWNrQnV0dG9uKG9wdGlvbilcIlxuICAgIFtjb2xvcl09XCJzZWxlY3RlZC5pbmNsdWRlcyhvcHRpb24udmFsdWUpID8gJ3ByaW1hcnknIDogJ25vcm1hbCdcIlxuICAgIFtpY29uXT1cIm9wdGlvbi5pY29uXCJcbiAgICBbbGFiZWxdPVwib3B0aW9uLmxhYmVsIHwgdHJhbnNsYXRlXCJcbiAgICBbdGVzdElkXT1cIidmaWx0ZXItYnV0dG9ucy0nICsgb3B0aW9uLnZhbHVlXCJcbiAgICBbdGl0bGVdPVwib3B0aW9uLnRpdGxlID8gKG9wdGlvbi50aXRsZSB8IHRyYW5zbGF0ZSkgOiAnJ1wiXG4gICAgW25hbWVdPVwib3B0aW9uLmxhYmVsXCJcbiAgICBbZGlzYWJsZWRdPVwib3B0aW9uLnJlYWRvbmx5IHx8IGRpc2FibGVkXCJcbiAgPlxuICA8L2luLWJ1dHRvbj5cbjwvZGl2PlxuIl19
@@ -2102,38 +2102,49 @@ class SelectButtonComponent {
2102
2102
  this.error = '';
2103
2103
  this.iconPos = 'left';
2104
2104
  this.options = [];
2105
+ this.disabled = false;
2105
2106
  this.required = false;
2106
2107
  this.multiple = false;
2107
2108
  this.focus = new EventEmitter();
2108
2109
  this.blur = new EventEmitter();
2109
2110
  this.click = new EventEmitter();
2110
2111
  this.change = new EventEmitter();
2112
+ // хранит выбранные ЗНАЧЕНИЯ, а не объекты
2111
2113
  this.selected = [];
2112
- this.propagateChange = (_) => {
2113
- };
2114
- }
2115
- ngOnInit() {
2114
+ // то, что отдаем наружу в форму
2115
+ this.value = null;
2116
+ this.propagateChange = () => { };
2117
+ this.propagateTouched = () => { };
2116
2118
  }
2117
- ngOnChanges() {
2118
- if (this.initial) {
2119
- this.selected = this.initial;
2119
+ ngOnInit() { }
2120
+ ngOnChanges(changes) {
2121
+ var _a;
2122
+ // применяем initial только когда он реально поменялся
2123
+ if (changes['initial'] && this.initial) {
2124
+ this.selected = [...this.initial];
2125
+ this.value = this.multiple ? [...this.initial] : (_a = this.initial[0]) !== null && _a !== void 0 ? _a : null;
2126
+ this.cdRef.detectChanges();
2120
2127
  }
2121
- else {
2122
- this.selected = [];
2128
+ // если меняется список опций, надо попытаться восстановить выделение
2129
+ if (changes['options'] && this.options && this.options.length > 0) {
2130
+ this.syncSelectedWithOptions();
2123
2131
  }
2124
2132
  }
2125
2133
  clickButton(option) {
2126
- if (option.readonly) {
2127
- return false;
2134
+ if (option.readonly || this.disabled) {
2135
+ return;
2128
2136
  }
2137
+ this.click.emit(option);
2129
2138
  if (this.multiple) {
2130
- if (this.selected.indexOf(option.value) !== -1) {
2131
- this.selected = this.selected.filter(item => item !== option.value);
2139
+ if (this.selected.includes(option.value)) {
2140
+ // убираем
2141
+ this.selected = this.selected.filter(v => v !== option.value);
2132
2142
  }
2133
2143
  else {
2134
- this.selected.push(option.value);
2144
+ // добавляем
2145
+ this.selected = [...this.selected, option.value];
2135
2146
  }
2136
- this.value = this.options.filter(item => this.selected.indexOf(item.value) !== -1).map(val => val.value);
2147
+ this.value = [...this.selected];
2137
2148
  }
2138
2149
  else {
2139
2150
  this.selected = [option.value];
@@ -2142,46 +2153,79 @@ class SelectButtonComponent {
2142
2153
  this.cdRef.detectChanges();
2143
2154
  this.onChange();
2144
2155
  }
2145
- /**
2146
- * Write form value to the DOM element (model => view)
2147
- */
2156
+ // ControlValueAccessor: model -> view
2148
2157
  writeValue(value) {
2149
2158
  this.value = value;
2150
- if (value !== null && value !== undefined) {
2151
- if (Array.isArray(value)) {
2152
- this.selected = value.map(val => val);
2153
- }
2154
- else {
2155
- this.selected = [value];
2156
- }
2159
+ if (value === null || value === undefined) {
2160
+ this.selected = [];
2157
2161
  }
2162
+ else if (Array.isArray(value)) {
2163
+ // multiple
2164
+ this.selected = [...value];
2165
+ }
2166
+ else {
2167
+ // single
2168
+ this.selected = [value];
2169
+ }
2170
+ // когда значение пришло извне, надо убедиться что такие опции есть
2171
+ this.syncSelectedWithOptions();
2158
2172
  this.cdRef.detectChanges();
2159
2173
  }
2160
- /**
2161
- * Write form disabled state to the DOM element (model => view)
2162
- */
2163
- setDisabledState(isDisabled) {
2164
- this.disabled = isDisabled;
2165
- }
2166
- /**
2167
- * Update form when DOM element value changes (view => model)
2168
- */
2174
+ // ControlValueAccessor
2169
2175
  registerOnChange(fn) {
2170
- // Store the provided function as an internal method.
2171
2176
  this.propagateChange = fn;
2172
2177
  }
2173
- /**
2174
- * Update form when DOM element is blurred (view => model)
2175
- */
2178
+ // ControlValueAccessor
2176
2179
  registerOnTouched(fn) {
2177
- // Store the provided function as an internal method.
2178
- this.onTouched = fn;
2180
+ this.propagateTouched = fn;
2181
+ }
2182
+ // ControlValueAccessor: disabled
2183
+ setDisabledState(isDisabled) {
2184
+ this.disabled = isDisabled;
2185
+ this.cdRef.detectChanges();
2179
2186
  }
2187
+ // пробросить наружу
2180
2188
  onChange() {
2181
2189
  this.propagateChange(this.value);
2182
2190
  this.change.emit(this.value);
2183
2191
  }
2184
- onTouched() {
2192
+ onBlur() {
2193
+ this.propagateTouched();
2194
+ this.blur.emit();
2195
+ }
2196
+ onFocus() {
2197
+ this.focus.emit();
2198
+ }
2199
+ // синхронизируем текущее выбранное со свежими options
2200
+ syncSelectedWithOptions() {
2201
+ if (!this.options || this.options.length === 0) {
2202
+ return;
2203
+ }
2204
+ if (this.multiple) {
2205
+ // оставляем только те выбранные, которые реально есть в новых options
2206
+ const optionValues = this.options.map(o => o.value);
2207
+ this.selected = this.selected.filter(v => optionValues.includes(v));
2208
+ this.value = [...this.selected];
2209
+ }
2210
+ else {
2211
+ if (this.selected.length > 0) {
2212
+ const current = this.selected[0];
2213
+ const found = this.options.find(o => o.value === current);
2214
+ if (!found) {
2215
+ // выбранного больше нет в списке
2216
+ this.selected = [];
2217
+ this.value = null;
2218
+ }
2219
+ else {
2220
+ this.selected = [found.value];
2221
+ this.value = found.value;
2222
+ }
2223
+ }
2224
+ }
2225
+ }
2226
+ // для *ngFor trackBy
2227
+ trackByValue(index, item) {
2228
+ return item.value;
2185
2229
  }
2186
2230
  }
2187
2231
  SelectButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectButtonComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
@@ -2190,8 +2234,8 @@ SelectButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
2190
2234
  provide: NG_VALUE_ACCESSOR,
2191
2235
  useExisting: forwardRef(() => SelectButtonComponent),
2192
2236
  multi: true,
2193
- }
2194
- ], usesOnChanges: true, ngImport: i0, template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{label}}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{error}}</span>\n </span>\n<div class=\"container\">\n <in-button class=\"button-none\"></in-button>\n <in-button (click)=\"clickButton(option)\"\n *ngFor=\"let option of options\"\n [color]=\"selected.indexOf(option.value) === -1 ? 'normal': 'primary' \"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name] = option.label\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "in-button", inputs: ["size", "color", "type", "name", "testId", "label", "icon", "className", "notify", "svg", "width", "link", "isLoading", "shadow", "isIconOnly", "linkType", "linkTarget", "pressed", "disabled", "iconPos", "selectedItem", "menuPlacement", "menuItems"], outputs: ["focus", "blur", "click"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] });
2237
+ },
2238
+ ], usesOnChanges: true, ngImport: i0, template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{ label }}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{ error }}</span>\n</span>\n\n<div class=\"container\">\n <!-- \u0444\u0438\u043A\u0442\u0438\u0432\u043D\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0430 \u0435\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 -->\n <in-button class=\"button-none\"></in-button>\n\n <in-button\n *ngFor=\"let option of options; trackBy: trackByValue\"\n (click)=\"clickButton(option)\"\n [color]=\"selected.includes(option.value) ? 'primary' : 'normal'\"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name]=\"option.label\"\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "in-button", inputs: ["size", "color", "type", "name", "testId", "label", "icon", "className", "notify", "svg", "width", "link", "isLoading", "shadow", "isIconOnly", "linkType", "linkTarget", "pressed", "disabled", "iconPos", "selectedItem", "menuPlacement", "menuItems"], outputs: ["focus", "blur", "click"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] });
2195
2239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectButtonComponent, decorators: [{
2196
2240
  type: Component,
2197
2241
  args: [{ selector: 'in-select-button', providers: [
@@ -2199,8 +2243,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2199
2243
  provide: NG_VALUE_ACCESSOR,
2200
2244
  useExisting: forwardRef(() => SelectButtonComponent),
2201
2245
  multi: true,
2202
- }
2203
- ], template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{label}}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{error}}</span>\n </span>\n<div class=\"container\">\n <in-button class=\"button-none\"></in-button>\n <in-button (click)=\"clickButton(option)\"\n *ngFor=\"let option of options\"\n [color]=\"selected.indexOf(option.value) === -1 ? 'normal': 'primary' \"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name] = option.label\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"] }]
2246
+ },
2247
+ ], template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{ label }}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{ error }}</span>\n</span>\n\n<div class=\"container\">\n <!-- \u0444\u0438\u043A\u0442\u0438\u0432\u043D\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0430 \u0435\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 -->\n <in-button class=\"button-none\"></in-button>\n\n <in-button\n *ngFor=\"let option of options; trackBy: trackByValue\"\n (click)=\"clickButton(option)\"\n [color]=\"selected.includes(option.value) ? 'primary' : 'normal'\"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name]=\"option.label\"\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"] }]
2204
2248
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { name: [{
2205
2249
  type: Input
2206
2250
  }], testId: [{