@sumaris-net/ngx-components 2.18.0-alpha5 → 2.18.0-alpha7

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.
Files changed (50) hide show
  1. package/esm2022/public_api.mjs +2 -1
  2. package/esm2022/src/app/admin/users/users.mjs +2 -2
  3. package/esm2022/src/app/core/account/account.page.mjs +1 -1
  4. package/esm2022/src/app/core/form/array/form-array.mjs +1 -1
  5. package/esm2022/src/app/core/form/form.class.mjs +7 -14
  6. package/esm2022/src/app/core/form/properties/properties.form.mjs +132 -47
  7. package/esm2022/src/app/core/form/properties/property.validator.mjs +21 -7
  8. package/esm2022/src/app/core/form/properties/testing/properties-form.test.mjs +3 -3
  9. package/esm2022/src/app/core/register/register.form.mjs +1 -1
  10. package/esm2022/src/app/core/services/model/entity.model.mjs +4 -2
  11. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +19 -8
  12. package/esm2022/src/app/core/settings/settings.module.mjs +5 -4
  13. package/esm2022/src/app/core/settings/settings.page.mjs +43 -45
  14. package/esm2022/src/app/core/table/column/nav-actions-column.component.mjs +4 -4
  15. package/esm2022/src/app/core/table/column/row-field.component.mjs +1 -1
  16. package/esm2022/src/app/core/table/testing/table.testing.mjs +1 -1
  17. package/esm2022/src/app/core/table/testing/table2.testing.mjs +1 -1
  18. package/esm2022/src/app/shared/form/field.component.mjs +7 -4
  19. package/esm2022/src/app/shared/functions.mjs +16 -1
  20. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +9 -10
  21. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +1 -1
  22. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +36 -19
  23. package/esm2022/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +1 -1
  24. package/esm2022/src/app/shared/material/chips/material.chips.mjs +3 -3
  25. package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +33 -20
  26. package/esm2022/src/app/shared/named-filter/testing/named-filter-selector.testing.mjs +15 -10
  27. package/esm2022/src/app/shared/pipes/html.pipes.mjs +52 -0
  28. package/esm2022/src/app/shared/pipes/pipes.module.mjs +10 -3
  29. package/esm2022/src/app/social/job/progression/job-progression.list.mjs +8 -9
  30. package/fesm2022/sumaris-net.ngx-components.mjs +638 -436
  31. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  32. package/package.json +1 -1
  33. package/public_api.d.ts +1 -0
  34. package/src/app/core/form/array/form-array.d.ts +1 -1
  35. package/src/app/core/form/form.class.d.ts +2 -5
  36. package/src/app/core/form/properties/properties.form.d.ts +32 -10
  37. package/src/app/core/form/properties/property.validator.d.ts +9 -3
  38. package/src/app/core/services/validator/local-settings.validator.d.ts +6 -2
  39. package/src/app/core/settings/settings.module.d.ts +2 -1
  40. package/src/app/core/settings/settings.page.d.ts +22 -12
  41. package/src/app/shared/form/field.component.d.ts +3 -2
  42. package/src/app/shared/functions.d.ts +2 -0
  43. package/src/app/shared/material/autocomplete/material.autocomplete.config.d.ts +4 -0
  44. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +12 -4
  45. package/src/app/shared/named-filter/named-filter-selector.component.d.ts +9 -6
  46. package/src/app/shared/named-filter/testing/named-filter-selector.testing.d.ts +4 -1
  47. package/src/app/shared/pipes/html.pipes.d.ts +15 -0
  48. package/src/app/shared/pipes/pipes.module.d.ts +5 -4
  49. package/src/assets/i18n/fr.json +3 -2
  50. package/src/assets/manifest.json +1 -1
@@ -1,39 +1,61 @@
1
- import { ChangeDetectionStrategy, Component, Input, Optional } from '@angular/core';
1
+ import { booleanAttribute, ChangeDetectionStrategy, Component, Input, Optional } from '@angular/core';
2
2
  import { EntityUtils } from '../../services/model/entity.model';
3
3
  import { isEmptyArray, isNil } from '../../../shared/functions';
4
4
  import { AppForm } from '../form.class';
5
5
  import { PropertyValidator } from './property.validator';
6
6
  import { FormArrayHelper } from '../array/form-array';
7
+ import { isMobile } from '../../../shared/platforms';
8
+ import { suggestFromArray } from '../../../shared/services';
7
9
  import * as i0 from "@angular/core";
8
10
  import * as i1 from "@angular/forms";
9
11
  import * as i2 from "@angular/material/core";
10
- import * as i3 from "../../services/local-settings.service";
11
- import * as i4 from "./property.validator";
12
- import * as i5 from "@angular/common";
13
- import * as i6 from "@ionic/angular";
14
- import * as i7 from "@ngx-translate/core";
15
- import * as i8 from "@angular/material/form-field";
16
- import * as i9 from "@angular/material/input";
17
- import * as i10 from "@angular/material/icon";
18
- import * as i11 from "@angular/material/button";
19
- import * as i12 from "@angular/material/select";
20
- import * as i13 from "../../../shared/form/field.component";
21
- import * as i14 from "../../../shared/pipes/form.pipes";
12
+ import * as i3 from "./property.validator";
13
+ import * as i4 from "@angular/common";
14
+ import * as i5 from "@ionic/angular";
15
+ import * as i6 from "@ngx-translate/core";
16
+ import * as i7 from "@angular/material/form-field";
17
+ import * as i8 from "@angular/material/input";
18
+ import * as i9 from "@angular/material/icon";
19
+ import * as i10 from "@angular/material/button";
20
+ import * as i11 from "../../../shared/material/autocomplete/material.autocomplete";
21
+ import * as i12 from "../../../shared/form/field.component";
22
+ import * as i13 from "../../../shared/pipes/property.pipes";
23
+ import * as i14 from "../../../shared/pipes/arrays.pipe";
24
+ import * as i15 from "../../../shared/pipes/maps.pipe";
25
+ import * as i16 from "../../../shared/pipes/form.pipes";
26
+ import * as i17 from "../../../shared/pipes/types.pipes";
22
27
  export class AppPropertiesForm extends AppForm {
23
28
  formBuilder;
24
29
  dateAdapter;
25
- settings;
26
30
  cd;
27
31
  validator;
28
32
  formGroupDir;
29
- definitionsMapByKey = {};
30
- definitionsByIndex = {};
31
- helper;
33
+ _definitions;
34
+ _options;
35
+ _definitionsMapByKey = {};
36
+ _definitionsByIndex = {};
37
+ _helper;
38
+ _autocompleteConfig;
32
39
  formArrayName;
33
40
  formArray;
34
41
  options;
35
- definitions;
36
42
  chipColor = 'accent';
43
+ mobile;
44
+ appearance;
45
+ subscriptSizing;
46
+ showHintKey = false;
47
+ showHintKeyPrefix = '';
48
+ showMoreButton = true;
49
+ showMoreButtonTitle = 'SETTINGS.BTN_SHOW_MORE_HELP';
50
+ showAddButton = true;
51
+ set definitions(value) {
52
+ this._definitions = value;
53
+ if (this.loaded)
54
+ this.updateDefinitionsMaps();
55
+ }
56
+ get definitions() {
57
+ return this._definitions;
58
+ }
37
59
  set value(data) {
38
60
  this.setValue(data);
39
61
  }
@@ -46,25 +68,41 @@ export class AppPropertiesForm extends AppForm {
46
68
  get fieldForms() {
47
69
  return this.formArray.controls;
48
70
  }
49
- constructor(injector, formBuilder, dateAdapter, settings, cd, validator, formGroupDir) {
71
+ constructor(injector, formBuilder, dateAdapter, cd, validator, formGroupDir) {
50
72
  super(injector, null);
51
73
  this.formBuilder = formBuilder;
52
74
  this.dateAdapter = dateAdapter;
53
- this.settings = settings;
54
75
  this.cd = cd;
55
76
  this.validator = validator;
56
77
  this.formGroupDir = formGroupDir;
78
+ this.tabindex = 20; // For compatibility - TODO remove later
57
79
  //this.debug = !environment.production;
58
80
  }
59
81
  ngOnInit() {
60
- if (isEmptyArray(this.definitions)) {
82
+ if (this.options?.allowEmptyArray === false && isEmptyArray(this._definitions)) {
61
83
  throw new Error("Missing or invalid attribute 'definitions'");
62
84
  }
63
- // Fill options map
64
- this.definitionsMapByKey = {};
65
- this.definitions.forEach((o) => {
66
- this.definitionsMapByKey[o.key] = o;
67
- });
85
+ this.mobile = this.mobile ?? isMobile(window);
86
+ this._autocompleteConfig = {
87
+ suggestFn: (value, filter) => this.suggestDefinition(value, filter),
88
+ displayWith: (value) => {
89
+ // Value is an object (a Property)
90
+ if (value && typeof value === 'object') {
91
+ return value.value;
92
+ }
93
+ // Value is a key
94
+ const def = typeof value === 'string' && this._definitionsMapByKey[value];
95
+ if (!def)
96
+ return value;
97
+ return this.translate.instant(def.label);
98
+ },
99
+ attributes: ['value'],
100
+ columnNames: [this.translate.instant('SETTINGS.PROPERTY_KEY')],
101
+ splitSearchText: false,
102
+ showAllOnFocus: true,
103
+ selectInputContentOnFocus: true,
104
+ };
105
+ this.updateDefinitionsMaps();
68
106
  // Retrieve the form
69
107
  const form = (this.formArray && this.formArray.parent) || (this.formGroupDir && this.formGroupDir.form) || this.formBuilder.group({});
70
108
  this.setForm(form);
@@ -76,55 +114,82 @@ export class AppPropertiesForm extends AppForm {
76
114
  this.formArray = this.formBuilder.array([]);
77
115
  this.form.addControl(this.formArrayName, this.formArray);
78
116
  }
79
- this.helper = new FormArrayHelper(this.formArray, (value) => this.validator.getFormGroup(value), (v1, v2) => (!v1 && !v2) || v1.key === v2.key, (value) => isNil(value) || (isNil(value.key) && isNil(value.value)), this.options);
117
+ this._helper = new FormArrayHelper(this.formArray, (value) => this.validator.getFormGroup(value), (v1, v2) => (!v1 && !v2) || v1.key === v2.key, (value) => this.isEmptyProperty(value), this.options);
80
118
  super.ngOnInit();
81
119
  }
120
+ updateDefinitionsMaps() {
121
+ // Fill options map
122
+ this._definitionsMapByKey = {};
123
+ this._options = (this._definitions || []).map((o) => {
124
+ this._definitionsMapByKey[o.key] = o;
125
+ return { key: o.key, value: this.translate.instant(o.label) };
126
+ });
127
+ }
82
128
  getDefinitionAt(index) {
83
- let definition = this.definitionsByIndex[index];
129
+ let definition = this._definitionsByIndex[index];
84
130
  if (!definition) {
85
- definition = this.updateDefinitionAt(index);
86
- this.definitionsByIndex[index] = definition;
131
+ definition = this.updateDefinitionAt(index, { emitEvent: false });
87
132
  }
88
133
  return definition;
89
134
  }
90
- updateDefinitionAt(index) {
91
- const key = this.formArray.at(index).controls.key.value;
92
- const definition = (key && this.definitionsMapByKey[key]) || null;
93
- this.definitionsByIndex[index] = definition; // update map by index
94
- this.markForCheck();
135
+ updateDefinitionAt(index, opts) {
136
+ let value = this.formArray.at(index).controls.key.value;
137
+ const key = value?.key || value;
138
+ const definition = (key && this._definitionsMapByKey[key]) || null;
139
+ this._definitionsByIndex[index] = definition; // update map by index
140
+ if (opts?.emitEvent !== false) {
141
+ this.markForCheck();
142
+ }
95
143
  return definition;
96
144
  }
97
145
  removeAt(index) {
98
- this.helper.removeAt(index);
99
- this.definitionsByIndex = {}; // clear map by index
146
+ this._helper.removeAt(index);
147
+ this._definitionsByIndex = {}; // clear map by index
100
148
  this.markForCheck();
101
149
  }
102
150
  isUnknownField(fieldForm) {
103
151
  const keyControl = fieldForm.get('key');
104
152
  const key = keyControl && keyControl.value;
105
- return key && isNil(this.definitionsMapByKey[key]);
153
+ return key && isNil(this._definitionsMapByKey[key]);
106
154
  }
107
155
  setValue(data) {
108
156
  if (!data)
109
157
  return; // Skip
110
158
  // Transform properties map into array
111
159
  const values = EntityUtils.getMapAsArray(data);
112
- this.helper.resize(values.length);
113
- this.helper.formArray.patchValue(values, { emitEvent: false });
160
+ this._helper.resize(values.length);
161
+ this._helper.formArray.patchValue(values, { emitEvent: false });
114
162
  this.markAsPristine();
115
163
  this.markAsLoaded();
116
164
  }
117
165
  /* -- protected methods -- */
166
+ async suggestDefinition(value, filter) {
167
+ value = value ?? '*';
168
+ // Get as key
169
+ if (typeof value === 'string') {
170
+ const obj = (this._options || []).find((o) => o.key === value);
171
+ if (obj)
172
+ return { data: [obj] };
173
+ }
174
+ // Get as object
175
+ if (typeof value === 'object') {
176
+ return { data: value };
177
+ }
178
+ return suggestFromArray(this._options, value, { searchAttribute: 'value', ...filter });
179
+ }
118
180
  markForCheck() {
119
181
  this.cd.markForCheck();
120
182
  }
121
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AppPropertiesForm, deps: [{ token: i0.Injector }, { token: i1.UntypedFormBuilder }, { token: i2.DateAdapter }, { token: i3.LocalSettingsService }, { token: i0.ChangeDetectorRef }, { token: i4.PropertyValidator }, { token: i1.FormGroupDirective, optional: true }], target: i0.ɵɵFactoryTarget.Component });
122
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: AppPropertiesForm, selector: "app-properties-form", inputs: { formArrayName: "formArrayName", formArray: "formArray", options: "options", definitions: "definitions", chipColor: "chipColor" }, providers: [{ provide: PropertyValidator, useClass: PropertyValidator }], usesInheritance: true, ngImport: i0, template: "<!-- Properties -->\n<form [formGroup]=\"form\" class=\"form-container\">\n <ion-grid *ngIf=\"!loading; else propertiesSkeleton\" formArrayName=\"properties\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button\n color=\"light\"\n *ngIf=\"formArray?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP' | translate\"\n (click)=\"helper.add()\"\n >\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <ng-container *ngFor=\"let fieldForm of fieldForms; let i = index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n <!-- property key -->\n <ion-col size=\"6\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"auto\" *ngIf=\"fieldForm | formGetControl: 'key' as control\">\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select\n [formControl]=\"control\"\n (selectionChange)=\"updateDefinitionAt(i)\"\n [tabindex]=\"20 + i * 2\"\n required\n >\n <!-- When option's key not a well known option, add it as first select option -->\n <mat-option *ngIf=\"isUnknownField(fieldForm)\" [value]=\"control.value\">\n {{ control.value }}\n </mat-option>\n\n <mat-option *ngFor=\"let item of definitions\" [value]=\"item.key\">{{ item.label | translate }}</mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"control.hasError('required') && !helper.isLast(i)\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field\n *ngIf=\"getDefinitionAt(i); let definition; else: unknownValue\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [chipColor]=\"chipColor\"\n [required]=\"true\"\n [tabindex]=\"20 + i * 2 + 1\"\n ></app-form-field>\n <ng-template #unknownValue>\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PROPERTY_VALUE' | translate }}</mat-label>\n <input\n type=\"text\"\n matInput\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [required]=\"true\"\n [tabindex]=\"20 + i * 2 + 1\"\n />\n </mat-form-field>\n </ng-template>\n </ion-col>\n\n <ion-col size=\"auto\" class=\"ion-no-padding\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removeAt(i)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <button\n [hidden]=\"!helper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"helper.add()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n</form>\n\n<ng-template #propertiesSkeleton>\n <ion-grid class=\"ion-no-padding\">\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n </ion-grid>\n</ng-template>\n\n<ng-template #propertyRowSkeleton>\n <ion-row>\n <!-- property key -->\n <ion-col>\n <mat-form-field>\n <input matInput hidden />\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n <ion-icon name=\"arrow-dropdown\" matSuffix></ion-icon>\n </mat-form-field>\n </ion-col>\n <!-- value -->\n <ion-col>\n <mat-form-field>\n <input matInput hidden />\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n </mat-form-field>\n </ion-col>\n <!-- buttons -->\n <ion-col size=\"2\">\n <button type=\"button\" mat-icon-button color=\"light\" [disabled]=\"true\">\n <mat-icon>close</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i6.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i6.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i6.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i6.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i6.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i6.IonRow, selector: "ion-row" }, { kind: "component", type: i6.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "directive", type: i7.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i9.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: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i13.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "appearance", "tabindex", "autofocus", "clearable", "chipColor", "class", "debug"], outputs: ["keyup.enter"] }, { kind: "pipe", type: i7.TranslatePipe, name: "translate" }, { kind: "pipe", type: i14.FormGetControlPipe, name: "formGetControl" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
183
+ isEmptyProperty(obj) {
184
+ return isNil(obj?.key) || isNil(obj.value);
185
+ }
186
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AppPropertiesForm, deps: [{ token: i0.Injector }, { token: i1.UntypedFormBuilder }, { token: i2.DateAdapter }, { token: i0.ChangeDetectorRef }, { token: i3.PropertyValidator }, { token: i1.FormGroupDirective, optional: true }], target: i0.ɵɵFactoryTarget.Component });
187
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.8", type: AppPropertiesForm, selector: "app-properties-form", inputs: { formArrayName: "formArrayName", formArray: "formArray", options: "options", chipColor: "chipColor", mobile: ["mobile", "mobile", booleanAttribute], appearance: "appearance", subscriptSizing: "subscriptSizing", showHintKey: ["showHintKey", "showHintKey", booleanAttribute], showHintKeyPrefix: "showHintKeyPrefix", showMoreButton: ["showMoreButton", "showMoreButton", booleanAttribute], showMoreButtonTitle: "showMoreButtonTitle", showAddButton: ["showAddButton", "showAddButton", booleanAttribute], definitions: "definitions" }, providers: [{ provide: PropertyValidator, useClass: PropertyValidator }], usesInheritance: true, ngImport: i0, template: "<!-- Properties -->\n<form [formGroup]=\"form\" class=\"form-container\">\n @if (loadingSubject | async) {\n <ion-list [inset]=\"mobile\">\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n </ion-list>\n } @else {\n <ion-list formArrayName=\"properties\" [inset]=\"mobile\">\n <!-- Show more options -->\n @if ((definitions | isNotEmptyArray) && formArray?.length === 0) {\n <ion-item lines=\"none\">\n <ion-button color=\"light\" [title]=\"showMoreButtonTitle | translate\" (click)=\"_helper.add()\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-item>\n }\n\n @for (fieldForm of fieldForms; track i; let i = $index) {\n <ion-item lines=\"none\" [class.outline]=\"appearance === 'outline'\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row [formGroupName]=\"i\" class=\"ion-no-padding\">\n <!-- property key -->\n @if (fieldForm | formGetControl: 'key'; as control) {\n <ion-col\n size=\"12\"\n size-sm=\"6\"\n [title]=\"(_definitionsMapByKey | mapGet: control?.value | propertyGet: 'label' | translate) || ''\"\n class=\"ion-no-padding\"\n >\n <mat-autocomplete-field\n floatLabel=\"auto\"\n [formControl]=\"control\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n (selectionChange)=\"updateDefinitionAt(i)\"\n [tabindex]=\"tabindex + i * 2\"\n [config]=\"_autocompleteConfig\"\n [placeholder]=\"'SETTINGS.PROPERTY_KEY' | translate\"\n [required]=\"true\"\n ></mat-autocomplete-field>\n <!--<mat-form-field floatLabel=\"auto\" [appearance]=\"appearance\" [subscriptSizing]=\"'dynamic'\">\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select\n [formControl]=\"control\"\n (selectionChange)=\"updateDefinitionAt(i)\"\n [tabindex]=\"tabindex + i * 2\"\n required\n >\n &lt;!&ndash; When option's key not a well known option, add it as first select option &ndash;&gt;\n @if (isUnknownField(fieldForm)) {\n <mat-option [value]=\"control.value\">\n {{ control.value }}\n </mat-option>\n }\n\n <mat-option *ngFor=\"let item of definitions\" [value]=\"item.key\">\n {{ item.label | translate }}\n </mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"control.hasError('required') && !_helper.isLast(i)\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n\n &lt;!&ndash; &ndash;&gt;\n @if (showHintKey) {\n <mat-hint>{{ showHintKeyPrefix || '' }}{{ control?.value || '' }}</mat-hint>\n }\n </mat-form-field>-->\n </ion-col>\n }\n\n <!-- property value -->\n <ion-col size=\"\" size-sm=\"\" class=\"ion-no-padding ion-padding-start-xs\">\n @let definition = getDefinitionAt(i);\n @if (definition) {\n <app-form-field\n [floatLabel]=\"mobile ? 'auto' : 'never'\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n [definition]=\"definition\"\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [chipColor]=\"chipColor\"\n [required]=\"true\"\n [tabindex]=\"tabindex + i * 2 + 1\"\n ></app-form-field>\n } @else {\n <!-- unknown definition -->\n <mat-form-field [appearance]=\"appearance\" [subscriptSizing]=\"subscriptSizing\">\n @if (mobile) {\n <mat-label>{{ 'SETTINGS.PROPERTY_VALUE' | translate }}</mat-label>\n }\n <input\n type=\"text\"\n matInput\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [placeholder]=\"mobile ? '' : ('SETTINGS.PROPERTY_VALUE' | translate)\"\n [required]=\"true\"\n [tabindex]=\"20 + i * 2 + 1\"\n />\n </mat-form-field>\n }\n </ion-col>\n\n <ion-col size=\"auto\" class=\"ion-no-padding\">\n @if (_helper.isLast(i)) {\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled || (fieldForm.value | asBoolean: isEmptyProperty)\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"_helper.add()\"\n [tabindex]=\"20 + i * 2 + 2\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removeAt(i)\"\n [tabindex]=\"-1\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n }\n </ion-list>\n }\n</form>\n\n<ng-template #propertyRowSkeleton>\n <ion-item lines=\"none\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <!-- property key -->\n <ion-col size=\"6\" class=\"ion-no-padding\">\n <mat-form-field [subscriptSizing]=\"subscriptSizing\" >\n <input matInput hidden disabled />\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n <ion-icon name=\"arrow-dropdown\" matSuffix></ion-icon>\n </mat-form-field>\n </ion-col>\n <!-- value -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [subscriptSizing]=\"subscriptSizing\" >\n <input matInput hidden disabled/>\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n </mat-form-field>\n </ion-col>\n <!-- buttons -->\n <ion-col size=\"auto\">\n <button type=\"button\" mat-icon-button color=\"light\" disabled>\n <mat-icon>close</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n</ng-template>\n", styles: [":host ion-item ion-row ion-col{--ion-padding-start: 0;min-width:48px}:host ion-item.outline{overflow:visible}:host ion-item.outline ion-grid,:host ion-item.outline ion-row,:host ion-item.outline ion-col{overflow:visible}\n"], dependencies: [{ kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i5.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i5.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i5.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i5.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i5.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i5.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i5.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i5.IonRow, selector: "ion-row" }, { kind: "component", type: i5.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i8.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: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i11.MatAutocompleteField, selector: "mat-autocomplete-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "appearance", "subscriptSizing", "placeholder", "suggestFn", "required", "mobile", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "multiple", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "debug", "showSearchBar", "stickySearchBar", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "splitSearchText", "selectInputContentOnFocus", "class", "filter", "readonly", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter", "selectionChange"] }, { kind: "component", type: i12.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "appearance", "subscriptSizing", "tabindex", "autofocus", "clearable", "chipColor", "class", "debug"], outputs: ["keyup.enter"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "pipe", type: i13.PropertyGetPipe, name: "propertyGet" }, { kind: "pipe", type: i14.NotEmptyArrayPipe, name: "isNotEmptyArray" }, { kind: "pipe", type: i15.MapGetPipe, name: "mapGet" }, { kind: "pipe", type: i16.FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: i17.AsBooleanPipe, name: "asBoolean" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
123
188
  }
124
189
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AppPropertiesForm, decorators: [{
125
190
  type: Component,
126
- args: [{ selector: 'app-properties-form', changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: PropertyValidator, useClass: PropertyValidator }], template: "<!-- Properties -->\n<form [formGroup]=\"form\" class=\"form-container\">\n <ion-grid *ngIf=\"!loading; else propertiesSkeleton\" formArrayName=\"properties\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button\n color=\"light\"\n *ngIf=\"formArray?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP' | translate\"\n (click)=\"helper.add()\"\n >\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <ng-container *ngFor=\"let fieldForm of fieldForms; let i = index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n <!-- property key -->\n <ion-col size=\"6\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"auto\" *ngIf=\"fieldForm | formGetControl: 'key' as control\">\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select\n [formControl]=\"control\"\n (selectionChange)=\"updateDefinitionAt(i)\"\n [tabindex]=\"20 + i * 2\"\n required\n >\n <!-- When option's key not a well known option, add it as first select option -->\n <mat-option *ngIf=\"isUnknownField(fieldForm)\" [value]=\"control.value\">\n {{ control.value }}\n </mat-option>\n\n <mat-option *ngFor=\"let item of definitions\" [value]=\"item.key\">{{ item.label | translate }}</mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"control.hasError('required') && !helper.isLast(i)\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field\n *ngIf=\"getDefinitionAt(i); let definition; else: unknownValue\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [chipColor]=\"chipColor\"\n [required]=\"true\"\n [tabindex]=\"20 + i * 2 + 1\"\n ></app-form-field>\n <ng-template #unknownValue>\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PROPERTY_VALUE' | translate }}</mat-label>\n <input\n type=\"text\"\n matInput\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [required]=\"true\"\n [tabindex]=\"20 + i * 2 + 1\"\n />\n </mat-form-field>\n </ng-template>\n </ion-col>\n\n <ion-col size=\"auto\" class=\"ion-no-padding\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removeAt(i)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <button\n [hidden]=\"!helper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"helper.add()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n</form>\n\n<ng-template #propertiesSkeleton>\n <ion-grid class=\"ion-no-padding\">\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n </ion-grid>\n</ng-template>\n\n<ng-template #propertyRowSkeleton>\n <ion-row>\n <!-- property key -->\n <ion-col>\n <mat-form-field>\n <input matInput hidden />\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n <ion-icon name=\"arrow-dropdown\" matSuffix></ion-icon>\n </mat-form-field>\n </ion-col>\n <!-- value -->\n <ion-col>\n <mat-form-field>\n <input matInput hidden />\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n </mat-form-field>\n </ion-col>\n <!-- buttons -->\n <ion-col size=\"2\">\n <button type=\"button\" mat-icon-button color=\"light\" [disabled]=\"true\">\n <mat-icon>close</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n</ng-template>\n" }]
127
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.UntypedFormBuilder }, { type: i2.DateAdapter }, { type: i3.LocalSettingsService }, { type: i0.ChangeDetectorRef }, { type: i4.PropertyValidator }, { type: i1.FormGroupDirective, decorators: [{
191
+ args: [{ selector: 'app-properties-form', providers: [{ provide: PropertyValidator, useClass: PropertyValidator }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Properties -->\n<form [formGroup]=\"form\" class=\"form-container\">\n @if (loadingSubject | async) {\n <ion-list [inset]=\"mobile\">\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"propertyRowSkeleton\"></ng-container>\n </ion-list>\n } @else {\n <ion-list formArrayName=\"properties\" [inset]=\"mobile\">\n <!-- Show more options -->\n @if ((definitions | isNotEmptyArray) && formArray?.length === 0) {\n <ion-item lines=\"none\">\n <ion-button color=\"light\" [title]=\"showMoreButtonTitle | translate\" (click)=\"_helper.add()\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-item>\n }\n\n @for (fieldForm of fieldForms; track i; let i = $index) {\n <ion-item lines=\"none\" [class.outline]=\"appearance === 'outline'\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row [formGroupName]=\"i\" class=\"ion-no-padding\">\n <!-- property key -->\n @if (fieldForm | formGetControl: 'key'; as control) {\n <ion-col\n size=\"12\"\n size-sm=\"6\"\n [title]=\"(_definitionsMapByKey | mapGet: control?.value | propertyGet: 'label' | translate) || ''\"\n class=\"ion-no-padding\"\n >\n <mat-autocomplete-field\n floatLabel=\"auto\"\n [formControl]=\"control\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n (selectionChange)=\"updateDefinitionAt(i)\"\n [tabindex]=\"tabindex + i * 2\"\n [config]=\"_autocompleteConfig\"\n [placeholder]=\"'SETTINGS.PROPERTY_KEY' | translate\"\n [required]=\"true\"\n ></mat-autocomplete-field>\n <!--<mat-form-field floatLabel=\"auto\" [appearance]=\"appearance\" [subscriptSizing]=\"'dynamic'\">\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select\n [formControl]=\"control\"\n (selectionChange)=\"updateDefinitionAt(i)\"\n [tabindex]=\"tabindex + i * 2\"\n required\n >\n &lt;!&ndash; When option's key not a well known option, add it as first select option &ndash;&gt;\n @if (isUnknownField(fieldForm)) {\n <mat-option [value]=\"control.value\">\n {{ control.value }}\n </mat-option>\n }\n\n <mat-option *ngFor=\"let item of definitions\" [value]=\"item.key\">\n {{ item.label | translate }}\n </mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"control.hasError('required') && !_helper.isLast(i)\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n\n &lt;!&ndash; &ndash;&gt;\n @if (showHintKey) {\n <mat-hint>{{ showHintKeyPrefix || '' }}{{ control?.value || '' }}</mat-hint>\n }\n </mat-form-field>-->\n </ion-col>\n }\n\n <!-- property value -->\n <ion-col size=\"\" size-sm=\"\" class=\"ion-no-padding ion-padding-start-xs\">\n @let definition = getDefinitionAt(i);\n @if (definition) {\n <app-form-field\n [floatLabel]=\"mobile ? 'auto' : 'never'\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n [definition]=\"definition\"\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [chipColor]=\"chipColor\"\n [required]=\"true\"\n [tabindex]=\"tabindex + i * 2 + 1\"\n ></app-form-field>\n } @else {\n <!-- unknown definition -->\n <mat-form-field [appearance]=\"appearance\" [subscriptSizing]=\"subscriptSizing\">\n @if (mobile) {\n <mat-label>{{ 'SETTINGS.PROPERTY_VALUE' | translate }}</mat-label>\n }\n <input\n type=\"text\"\n matInput\n [formControl]=\"fieldForm | formGetControl: 'value'\"\n [placeholder]=\"mobile ? '' : ('SETTINGS.PROPERTY_VALUE' | translate)\"\n [required]=\"true\"\n [tabindex]=\"20 + i * 2 + 1\"\n />\n </mat-form-field>\n }\n </ion-col>\n\n <ion-col size=\"auto\" class=\"ion-no-padding\">\n @if (_helper.isLast(i)) {\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled || (fieldForm.value | asBoolean: isEmptyProperty)\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"_helper.add()\"\n [tabindex]=\"20 + i * 2 + 2\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"disabled\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removeAt(i)\"\n [tabindex]=\"-1\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n }\n </ion-list>\n }\n</form>\n\n<ng-template #propertyRowSkeleton>\n <ion-item lines=\"none\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <!-- property key -->\n <ion-col size=\"6\" class=\"ion-no-padding\">\n <mat-form-field [subscriptSizing]=\"subscriptSizing\" >\n <input matInput hidden disabled />\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n <ion-icon name=\"arrow-dropdown\" matSuffix></ion-icon>\n </mat-form-field>\n </ion-col>\n <!-- value -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [subscriptSizing]=\"subscriptSizing\" >\n <input matInput hidden disabled/>\n <ion-skeleton-text animated style=\"width: 60%\"></ion-skeleton-text>\n </mat-form-field>\n </ion-col>\n <!-- buttons -->\n <ion-col size=\"auto\">\n <button type=\"button\" mat-icon-button color=\"light\" disabled>\n <mat-icon>close</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n</ng-template>\n", styles: [":host ion-item ion-row ion-col{--ion-padding-start: 0;min-width:48px}:host ion-item.outline{overflow:visible}:host ion-item.outline ion-grid,:host ion-item.outline ion-row,:host ion-item.outline ion-col{overflow:visible}\n"] }]
192
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.UntypedFormBuilder }, { type: i2.DateAdapter }, { type: i0.ChangeDetectorRef }, { type: i3.PropertyValidator }, { type: i1.FormGroupDirective, decorators: [{
128
193
  type: Optional
129
194
  }] }], propDecorators: { formArrayName: [{
130
195
  type: Input
@@ -132,9 +197,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
132
197
  type: Input
133
198
  }], options: [{
134
199
  type: Input
135
- }], definitions: [{
136
- type: Input
137
200
  }], chipColor: [{
138
201
  type: Input
202
+ }], mobile: [{
203
+ type: Input,
204
+ args: [{ transform: booleanAttribute }]
205
+ }], appearance: [{
206
+ type: Input
207
+ }], subscriptSizing: [{
208
+ type: Input
209
+ }], showHintKey: [{
210
+ type: Input,
211
+ args: [{ transform: booleanAttribute }]
212
+ }], showHintKeyPrefix: [{
213
+ type: Input
214
+ }], showMoreButton: [{
215
+ type: Input,
216
+ args: [{ transform: booleanAttribute }]
217
+ }], showMoreButtonTitle: [{
218
+ type: Input
219
+ }], showAddButton: [{
220
+ type: Input,
221
+ args: [{ transform: booleanAttribute }]
222
+ }], definitions: [{
223
+ type: Input
139
224
  }] } });
140
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5mb3JtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vcHJvcGVydGllcy9wcm9wZXJ0aWVzLmZvcm0udHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvZm9ybS9wcm9wZXJ0aWVzL3Byb3BlcnRpZXMuZm9ybS5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBcUIsU0FBUyxFQUFZLEtBQUssRUFBVSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFekgsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRWhFLE9BQU8sRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFJaEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsZUFBZSxFQUEwQixNQUFNLHFCQUFxQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7O0FBUTlFLE1BQU0sT0FBTyxpQkFBZ0MsU0FBUSxPQUFZO0lBNkJuRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ1U7SUFqQ3RCLG1CQUFtQixHQUEyQixFQUFFLENBQUM7SUFDakQsa0JBQWtCLEdBQTZDLEVBQUUsQ0FBQztJQUNsRSxNQUFNLENBQTRCO0lBRXpCLGFBQWEsQ0FBUztJQUN0QixTQUFTLENBQW1CO0lBQzVCLE9BQU8sQ0FBeUI7SUFDaEMsV0FBVyxDQUF3QjtJQUNuQyxTQUFTLEdBQW9DLFFBQVEsQ0FBQztJQUUvRCxJQUFJLEtBQUssQ0FBQyxJQUFTO1FBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksS0FBSztRQUNQLE9BQU8sSUFBSSxDQUFDLFNB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QTs7MkZEakhhLGlCQUFpQjtrQkFON0IsU0FBUzsrQkFDRSxxQkFBcUIsbUJBRWQsdUJBQXVCLENBQUMsTUFBTSxhQUNwQyxDQUFDLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxDQUFDOzswQkFvQ3JFLFFBQVE7eUNBN0JGLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEluamVjdG9yLCBJbnB1dCwgT25Jbml0LCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwRGlyZWN0aXZlLCBVbnR5cGVkRm9ybUFycmF5LCBVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBFbnRpdHlVdGlscyB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL21vZGVsL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQgeyBGb3JtRmllbGREZWZpbml0aW9uLCBGb3JtRmllbGREZWZpbml0aW9uTWFwIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL2Zvcm0vZmllbGQubW9kZWwnO1xuaW1wb3J0IHsgaXNFbXB0eUFycmF5LCBpc05pbCB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHsgRGF0ZUFkYXB0ZXIsIFRoZW1lUGFsZXR0ZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xuaW1wb3J0IHsgTW9tZW50IH0gZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IExvY2FsU2V0dGluZ3NTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbG9jYWwtc2V0dGluZ3Muc2VydmljZSc7XG5pbXBvcnQgeyBBcHBGb3JtIH0gZnJvbSAnLi4vZm9ybS5jbGFzcyc7XG5pbXBvcnQgeyBQcm9wZXJ0eSB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBQcm9wZXJ0eVZhbGlkYXRvciB9IGZyb20gJy4vcHJvcGVydHkudmFsaWRhdG9yJztcbmltcG9ydCB7IFByZWRlZmluZWRDb2xvcnMgfSBmcm9tICdAaW9uaWMvY29yZSc7XG5pbXBvcnQgeyBGb3JtQXJyYXlIZWxwZXIsIEZvcm1BcnJheUhlbHBlck9wdGlvbnMgfSBmcm9tICcuLi9hcnJheS9mb3JtLWFycmF5JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXByb3BlcnRpZXMtZm9ybScsXG4gIHRlbXBsYXRlVXJsOiAncHJvcGVydGllcy5mb3JtLmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBQcm9wZXJ0eVZhbGlkYXRvciwgdXNlQ2xhc3M6IFByb3BlcnR5VmFsaWRhdG9yIH1dLFxufSlcbmV4cG9ydCBjbGFzcyBBcHBQcm9wZXJ0aWVzRm9ybTxUID0gUHJvcGVydHk+IGV4dGVuZHMgQXBwRm9ybTxUW10+IGltcGxlbWVudHMgT25Jbml0IHtcbiAgZGVmaW5pdGlvbnNNYXBCeUtleTogRm9ybUZpZWxkRGVmaW5pdGlvbk1hcCA9IHt9O1xuICBkZWZpbml0aW9uc0J5SW5kZXg6IHsgW2luZGV4OiBudW1iZXJdOiBGb3JtRmllbGREZWZpbml0aW9uIH0gPSB7fTtcbiAgaGVscGVyOiBGb3JtQXJyYXlIZWxwZXI8UHJvcGVydHk+O1xuXG4gIEBJbnB1dCgpIGZvcm1BcnJheU5hbWU6IHN0cmluZztcbiAgQElucHV0KCkgZm9ybUFycmF5OiBVbnR5cGVkRm9ybUFycmF5O1xuICBASW5wdXQoKSBvcHRpb25zOiBGb3JtQXJyYXlIZWxwZXJPcHRpb25zO1xuICBASW5wdXQoKSBkZWZpbml0aW9uczogRm9ybUZpZWxkRGVmaW5pdGlvbltdO1xuICBASW5wdXQoKSBjaGlwQ29sb3I6IFRoZW1lUGFsZXR0ZSB8IFByZWRlZmluZWRDb2xvcnMgPSAnYWNjZW50JztcblxuICBzZXQgdmFsdWUoZGF0YTogVFtdKSB7XG4gICAgdGhpcy5zZXRWYWx1ZShkYXRhKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBUW10ge1xuICAgIHJldHVybiB0aGlzLmZvcm1BcnJheS52YWx1ZSBhcyBUW107XG4gIH1cblxuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybUFycmF5Py5sZW5ndGggfHwgMDtcbiAgfVxuXG4gIGdldCBmaWVsZEZvcm1zKCk6IFVudHlwZWRGb3JtR3JvdXBbXSB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybUFycmF5LmNvbnRyb2xzIGFzIFVudHlwZWRGb3JtR3JvdXBbXTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcm90ZWN0ZWQgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICBwcm90ZWN0ZWQgZGF0ZUFkYXB0ZXI6IERhdGVBZGFwdGVyPE1vbWVudD4sXG4gICAgcHJvdGVjdGVkIHNldHRpbmdzOiBMb2NhbFNldHRpbmdzU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByb3RlY3RlZCB2YWxpZGF0b3I6IFByb3BlcnR5VmFsaWRhdG9yLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZm9ybUdyb3VwRGlyOiBGb3JtR3JvdXBEaXJlY3RpdmVcbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IsIG51bGwpO1xuXG4gICAgLy90aGlzLmRlYnVnID0gIWVudmlyb25tZW50LnByb2R1Y3Rpb247XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAoaXNFbXB0eUFycmF5KHRoaXMuZGVmaW5pdGlvbnMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIG9yIGludmFsaWQgYXR0cmlidXRlICdkZWZpbml0aW9ucydcIik7XG4gICAgfVxuXG4gICAgLy8gRmlsbCBvcHRpb25zIG1hcFxuICAgIHRoaXMuZGVmaW5pdGlvbnNNYXBCeUtleSA9IHt9O1xuICAgIHRoaXMuZGVmaW5pdGlvbnMuZm9yRWFjaCgobykgPT4ge1xuICAgICAgdGhpcy5kZWZpbml0aW9uc01hcEJ5S2V5W28ua2V5XSA9IG87XG4gICAgfSk7XG5cbiAgICAvLyBSZXRyaWV2ZSB0aGUgZm9ybVxuICAgIGNvbnN0IGZvcm0gPVxuICAgICAgKHRoaXMuZm9ybUFycmF5ICYmICh0aGlzLmZvcm1BcnJheS5wYXJlbnQgYXMgVW50eXBlZEZvcm1Hcm91cCkpIHx8ICh0aGlzLmZvcm1Hcm91cERpciAmJiB0aGlzLmZvcm1Hcm91cERpci5mb3JtKSB8fCB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHt9KTtcbiAgICB0aGlzLnNldEZvcm0oZm9ybSk7XG5cbiAgICB0aGlzLmZvcm1BcnJheSA9IHRoaXMuZm9ybUFycmF5IHx8ICh0aGlzLmZvcm1BcnJheU5hbWUgJiYgKGZvcm0uZ2V0KHRoaXMuZm9ybUFycmF5TmFtZSkgYXMgVW50eXBlZEZvcm1BcnJheSkpO1xuICAgIHRoaXMuZm9ybUFycmF5TmFtZSA9XG4gICAgICB0aGlzLmZvcm1BcnJheU5hbWUgfHwgKHRoaXMuZm9ybUFycmF5ICYmIE9iamVjdC5rZXlzKGZvcm0uY29udHJvbHMpLmZpbmQoKGtleSkgPT4gZm9ybS5nZXQoa2V5KSA9PT0gdGhpcy5mb3JtQXJyYXkpKSB8fCAncHJvcGVydGllcyc7XG4gICAgaWYgKCF0aGlzLmZvcm1BcnJheSkge1xuICAgICAgY29uc29sZS53YXJuKGBNaXNzaW5nIGFycmF5IGNvbnRyb2wgJyR7dGhpcy5mb3JtQXJyYXlOYW1lfScuIFdpbGwgY3JlYXRlIGl0IWApO1xuICAgICAgdGhpcy5mb3JtQXJyYXkgPSB0aGlzLmZvcm1CdWlsZGVyLmFycmF5KFtdKTtcbiAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKHRoaXMuZm9ybUFycmF5TmFtZSwgdGhpcy5mb3JtQXJyYXkpO1xuICAgIH1cblxuICAgIHRoaXMuaGVscGVyID0gbmV3IEZvcm1BcnJheUhlbHBlcjxQcm9wZXJ0eT4oXG4gICAgICB0aGlzLmZvcm1BcnJheSxcbiAgICAgICh2YWx1ZSkgPT4gdGhpcy52YWxpZGF0b3IuZ2V0Rm9ybUdyb3VwKHZhbHVlKSxcbiAgICAgICh2MSwgdjIpID0+ICghdjEgJiYgIXYyKSB8fCB2MS5rZXkgPT09IHYyLmtleSxcbiAgICAgICh2YWx1ZSkgPT4gaXNOaWwodmFsdWUpIHx8IChpc05pbCh2YWx1ZS5rZXkpICYmIGlzTmlsKHZhbHVlLnZhbHVlKSksXG4gICAgICB0aGlzLm9wdGlvbnNcbiAgICApO1xuXG4gICAgc3VwZXIubmdPbkluaXQoKTtcbiAgfVxuXG4gIGdldERlZmluaXRpb25BdChpbmRleDogbnVtYmVyKTogRm9ybUZpZWxkRGVmaW5pdGlvbiB7XG4gICAgbGV0IGRlZmluaXRpb24gPSB0aGlzLmRlZmluaXRpb25zQnlJbmRleFtpbmRleF07XG4gICAgaWYgKCFkZWZpbml0aW9uKSB7XG4gICAgICBkZWZpbml0aW9uID0gdGhpcy51cGRhdGVEZWZpbml0aW9uQXQoaW5kZXgpO1xuICAgICAgdGhpcy5kZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdID0gZGVmaW5pdGlvbjtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmluaXRpb247XG4gIH1cblxuICB1cGRhdGVEZWZpbml0aW9uQXQoaW5kZXg6IG51bWJlcik6IEZvcm1GaWVsZERlZmluaXRpb24ge1xuICAgIGNvbnN0IGtleSA9ICh0aGlzLmZvcm1BcnJheS5hdChpbmRleCkgYXMgVW50eXBlZEZvcm1Hcm91cCkuY29udHJvbHMua2V5LnZhbHVlO1xuICAgIGNvbnN0IGRlZmluaXRpb24gPSAoa2V5ICYmIHRoaXMuZGVmaW5pdGlvbnNNYXBCeUtleVtrZXldKSB8fCBudWxsO1xuICAgIHRoaXMuZGVmaW5pdGlvbnNCeUluZGV4W2luZGV4XSA9IGRlZmluaXRpb247IC8vIHVwZGF0ZSBtYXAgYnkgaW5kZXhcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgcmVtb3ZlQXQoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuaGVscGVyLnJlbW92ZUF0KGluZGV4KTtcbiAgICB0aGlzLmRlZmluaXRpb25zQnlJbmRleCA9IHt9OyAvLyBjbGVhciBtYXAgYnkgaW5kZXhcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgaXNVbmtub3duRmllbGQoZmllbGRGb3JtOiBVbnR5cGVkRm9ybUdyb3VwKSB7XG4gICAgY29uc3Qga2V5Q29udHJvbCA9IGZpZWxkRm9ybS5nZXQoJ2tleScpO1xuICAgIGNvbnN0IGtleSA9IGtleUNvbnRyb2wgJiYga2V5Q29udHJvbC52YWx1ZTtcbiAgICByZXR1cm4ga2V5ICYmIGlzTmlsKHRoaXMuZGVmaW5pdGlvbnNNYXBCeUtleVtrZXldKTtcbiAgfVxuXG4gIHNldFZhbHVlKGRhdGE6IFRbXSB8IGFueSkge1xuICAgIGlmICghZGF0YSkgcmV0dXJuOyAvLyBTa2lwXG5cbiAgICAvLyBUcmFuc2Zvcm0gcHJvcGVydGllcyBtYXAgaW50byBhcnJheVxuICAgIGNvbnN0IHZhbHVlcyA9IEVudGl0eVV0aWxzLmdldE1hcEFzQXJyYXk8VD4oZGF0YSk7XG4gICAgdGhpcy5oZWxwZXIucmVzaXplKHZhbHVlcy5sZW5ndGgpO1xuICAgIHRoaXMuaGVscGVyLmZvcm1BcnJheS5wYXRjaFZhbHVlKHZhbHVlcywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuICAgIHRoaXMubWFya0FzTG9hZGVkKCk7XG4gIH1cblxuICAvKiAtLSBwcm90ZWN0ZWQgbWV0aG9kcyAtLSAqL1xuXG4gIHByb3RlY3RlZCBtYXJrRm9yQ2hlY2soKSB7XG4gICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgfVxufVxuIiwiPCEtLSBQcm9wZXJ0aWVzIC0tPlxuPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgY2xhc3M9XCJmb3JtLWNvbnRhaW5lclwiPlxuICA8aW9uLWdyaWQgKm5nSWY9XCIhbG9hZGluZzsgZWxzZSBwcm9wZXJ0aWVzU2tlbGV0b25cIiBmb3JtQXJyYXlOYW1lPVwicHJvcGVydGllc1wiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICA8aW9uLXJvdyBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi1uby1wYWRkaW5nIGlvbi1hbGlnbi1zZWxmLWVuZFwiIHNpemU9XCIxMlwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2xiYXItc3BhY2VyXCI+PC9zcGFuPlxuXG4gICAgICAgIDwhLS0gU2hvdyBtb3JlIG9wdGlvbnMgLS0+XG4gICAgICAgIDxpb24tYnV0dG9uXG4gICAgICAgICAgY29sb3I9XCJsaWdodFwiXG4gICAgICAgICAgKm5nSWY9XCJmb3JtQXJyYXk/Lmxlbmd0aCA9PT0gMFwiXG4gICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fU0hPV19NT1JFX0hFTFAnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAoY2xpY2spPVwiaGVscGVyLmFkZCgpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxpb24tbGFiZWwgdHJhbnNsYXRlPkNPTU1PTi5CVE5fU0hPV19NT1JFPC9pb24tbGFiZWw+XG4gICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJlbmRcIj5hcnJvd19kcm9wX2Rvd248L21hdC1pY29uPlxuICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICA8L2lvbi1jb2w+XG4gICAgPC9pb24tcm93PlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGRGb3JtIG9mIGZpZWxkRm9ybXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgIDxpb24tcm93IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBbZm9ybUdyb3VwTmFtZV09XCJpXCI+XG4gICAgICAgIDwhLS0gcHJvcGVydHkga2V5IC0tPlxuICAgICAgICA8aW9uLWNvbCBzaXplPVwiNlwiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgZmxvYXRMYWJlbD1cImF1dG9cIiAqbmdJZj1cImZpZWxkRm9ybSB8IGZvcm1HZXRDb250cm9sOiAna2V5JyBhcyBjb250cm9sXCI+XG4gICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdTRVRUSU5HUy5QUk9QRVJUWV9LRVknIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiY29udHJvbFwiXG4gICAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwidXBkYXRlRGVmaW5pdGlvbkF0KGkpXCJcbiAgICAgICAgICAgICAgW3RhYmluZGV4XT1cIjIwICsgaSAqIDJcIlxuICAgICAgICAgICAgICByZXF1aXJlZFxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8IS0tIFdoZW4gb3B0aW9uJ3Mga2V5IG5vdCBhIHdlbGwga25vd24gb3B0aW9uLCBhZGQgaXQgYXMgZmlyc3Qgc2VsZWN0IG9wdGlvbiAtLT5cbiAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nSWY9XCJpc1Vua25vd25GaWVsZChmaWVsZEZvcm0pXCIgW3ZhbHVlXT1cImNvbnRyb2wudmFsdWVcIj5cbiAgICAgICAgICAgICAgICB7eyBjb250cm9sLnZhbHVlIH19XG4gICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cblxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBkZWZpbml0aW9uc1wiIFt2YWx1ZV09XCJpdGVtLmtleVwiPnt7IGl0ZW0ubGFiZWwgfCB0cmFuc2xhdGUgfX08L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJjb250cm9sLmhhc0Vycm9yKCdyZXF1aXJlZCcpICYmICFoZWxwZXIuaXNMYXN0KGkpXCIgdHJhbnNsYXRlPlxuICAgICAgICAgICAgICBFUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgIDwhLS0gcHJvcGVydHkgdmFsdWUgLS0+XG4gICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBwYWRkaW5nLWxlZnQ+XG4gICAgICAgICAgPGFwcC1mb3JtLWZpZWxkXG4gICAgICAgICAgICAqbmdJZj1cImdldERlZmluaXRpb25BdChpKTsgbGV0IGRlZmluaXRpb247IGVsc2U6IHVua25vd25WYWx1ZVwiXG4gICAgICAgICAgICBmbG9hdExhYmVsPVwibmV2ZXJcIlxuICAgICAgICAgICAgW2RlZmluaXRpb25dPVwiZGVmaW5pdGlvblwiXG4gICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZmllbGRGb3JtIHwgZm9ybUdldENvbnRyb2w6ICd2YWx1ZSdcIlxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidTRVRUSU5HUy5QUk9QRVJUWV9WQUxVRScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgW2NoaXBDb2xvcl09XCJjaGlwQ29sb3JcIlxuICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxuICAgICAgICAgICAgW3RhYmluZGV4XT1cIjIwICsgaSAqIDIgKyAxXCJcbiAgICAgICAgICA+PC9hcHAtZm9ybS1maWVsZD5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI3Vua25vd25WYWx1ZT5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyAnU0VUVElOR1MuUFJPUEVSVFlfVkFMVUUnIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmaWVsZEZvcm0gfCBmb3JtR2V0Q29udHJvbDogJ3ZhbHVlJ1wiXG4gICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCIyMCArIGkgKiAyICsgMVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICA8aW9uLWNvbCBzaXplPVwiYXV0b1wiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgY29sb3I9XCJsaWdodFwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgICAgW3RpdGxlXT1cIidDT01NT04uQlROX0RFTEVURScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUF0KGkpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIFtoaWRkZW5dPVwiIWhlbHBlci5pc0xhc3QoaSlcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgIGNvbG9yPVwibGlnaHRcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgIFt0aXRsZV09XCInU0VUVElOR1MuQlROX0FERF9QUk9QRVJUWScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImhlbHBlci5hZGQoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvaW9uLWNvbD5cbiAgICAgIDwvaW9uLXJvdz5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9pb24tZ3JpZD5cbjwvZm9ybT5cblxuPG5nLXRlbXBsYXRlICNwcm9wZXJ0aWVzU2tlbGV0b24+XG4gIDxpb24tZ3JpZCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInByb3BlcnR5Um93U2tlbGV0b25cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicHJvcGVydHlSb3dTa2VsZXRvblwiPjwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJwcm9wZXJ0eVJvd1NrZWxldG9uXCI+PC9uZy1jb250YWluZXI+XG4gIDwvaW9uLWdyaWQ+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3Byb3BlcnR5Um93U2tlbGV0b24+XG4gIDxpb24tcm93PlxuICAgIDwhLS0gcHJvcGVydHkga2V5IC0tPlxuICAgIDxpb24tY29sPlxuICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8aW5wdXQgbWF0SW5wdXQgaGlkZGVuIC8+XG4gICAgICAgIDxpb24tc2tlbGV0b24tdGV4dCBhbmltYXRlZCBzdHlsZT1cIndpZHRoOiA2MCVcIj48L2lvbi1za2VsZXRvbi10ZXh0PlxuICAgICAgICA8aW9uLWljb24gbmFtZT1cImFycm93LWRyb3Bkb3duXCIgbWF0U3VmZml4PjwvaW9uLWljb24+XG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgIDwvaW9uLWNvbD5cbiAgICA8IS0tIHZhbHVlIC0tPlxuICAgIDxpb24tY29sPlxuICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8aW5wdXQgbWF0SW5wdXQgaGlkZGVuIC8+XG4gICAgICAgIDxpb24tc2tlbGV0b24tdGV4dCBhbmltYXRlZCBzdHlsZT1cIndpZHRoOiA2MCVcIj48L2lvbi1za2VsZXRvbi10ZXh0PlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICA8L2lvbi1jb2w+XG4gICAgPCEtLSBidXR0b25zIC0tPlxuICAgIDxpb24tY29sIHNpemU9XCIyXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gY29sb3I9XCJsaWdodFwiIFtkaXNhYmxlZF09XCJ0cnVlXCI+XG4gICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2lvbi1jb2w+XG4gIDwvaW9uLXJvdz5cbjwvbmctdGVtcGxhdGU+XG4iXX0=
225
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5mb3JtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vcHJvcGVydGllcy9wcm9wZXJ0aWVzLmZvcm0udHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvZm9ybS9wcm9wZXJ0aWVzL3Byb3BlcnRpZXMuZm9ybS5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSx1QkFBdUIsRUFBcUIsU0FBUyxFQUFZLEtBQUssRUFBVSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0ksT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRWhFLE9BQU8sRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHaEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsZUFBZSxFQUEwQixNQUFNLHFCQUFxQixDQUFDO0FBQzlFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUdyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVU1RCxNQUFNLE9BQU8saUJBQWdDLFNBQVEsT0FBWTtJQWlEbkQ7SUFDQTtJQUNBO0lBQ0E7SUFDVTtJQXBEWixZQUFZLENBQXdCO0lBQ3BDLFFBQVEsQ0FBYTtJQUNyQixvQkFBb0IsR0FBMkIsRUFBRSxDQUFDO0lBQ2xELG1CQUFtQixHQUE2QyxFQUFFLENBQUM7SUFDbkUsT0FBTyxDQUE0QjtJQUVuQyxtQkFBbUIsQ0FBNkI7SUFFakQsYUFBYSxDQUFTO0lBQ3RCLFNBQVMsQ0FBbUI7SUFDNUIsT0FBTyxDQUF5QjtJQUNoQyxTQUFT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QUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQUM3QixtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBQ2tDLGFBQWE7c0JBQXBELEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBRXpCLFdBQVc7c0JBQXZCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBib29sZWFuQXR0cmlidXRlLCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgSW5qZWN0b3IsIElucHV0LCBPbkluaXQsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXBEaXJlY3RpdmUsIFVudHlwZWRGb3JtQXJyYXksIFVudHlwZWRGb3JtQnVpbGRlciwgVW50eXBlZEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEVudGl0eVV0aWxzIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbW9kZWwvZW50aXR5Lm1vZGVsJztcbmltcG9ydCB7IEZvcm1GaWVsZERlZmluaXRpb24sIEZvcm1GaWVsZERlZmluaXRpb25NYXAgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZm9ybS9maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBpc0VtcHR5QXJyYXksIGlzTmlsIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBEYXRlQWRhcHRlciwgVGhlbWVQYWxldHRlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgeyBNb21lbnQgfSBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgQXBwRm9ybSB9IGZyb20gJy4uL2Zvcm0uY2xhc3MnO1xuaW1wb3J0IHsgUHJvcGVydHkgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgUHJvcGVydHlWYWxpZGF0b3IgfSBmcm9tICcuL3Byb3BlcnR5LnZhbGlkYXRvcic7XG5pbXBvcnQgeyBQcmVkZWZpbmVkQ29sb3JzIH0gZnJvbSAnQGlvbmljL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUFycmF5SGVscGVyLCBGb3JtQXJyYXlIZWxwZXJPcHRpb25zIH0gZnJvbSAnLi4vYXJyYXkvZm9ybS1hcnJheSc7XG5pbXBvcnQgeyBpc01vYmlsZSB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9wbGF0Zm9ybXMnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkQXBwZWFyYW5jZSwgU3Vic2NyaXB0U2l6aW5nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRBdXRvY29tcGxldGVGaWVsZENvbmZpZyB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9tYXRlcmlhbC9hdXRvY29tcGxldGUvbWF0ZXJpYWwuYXV0b2NvbXBsZXRlLmNvbmZpZyc7XG5pbXBvcnQgeyBzdWdnZXN0RnJvbUFycmF5IH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL3NlcnZpY2VzJztcbmltcG9ydCB7IExvYWRSZXN1bHQgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvc2VydmljZXMvZW50aXR5LXNlcnZpY2UuY2xhc3MnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcHJvcGVydGllcy1mb3JtJyxcbiAgdGVtcGxhdGVVcmw6ICdwcm9wZXJ0aWVzLmZvcm0uaHRtbCcsXG4gIHN0eWxlVXJsczogWydwcm9wZXJ0aWVzLmZvcm0uc2NzcyddLFxuICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IFByb3BlcnR5VmFsaWRhdG9yLCB1c2VDbGFzczogUHJvcGVydHlWYWxpZGF0b3IgfV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBBcHBQcm9wZXJ0aWVzRm9ybTxUID0gUHJvcGVydHk+IGV4dGVuZHMgQXBwRm9ybTxUW10+IGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJvdGVjdGVkIF9kZWZpbml0aW9uczogRm9ybUZpZWxkRGVmaW5pdGlvbltdO1xuICBwcm90ZWN0ZWQgX29wdGlvbnM6IFByb3BlcnR5W107XG4gIHByb3RlY3RlZCBfZGVmaW5pdGlvbnNNYXBCeUtleTogRm9ybUZpZWxkRGVmaW5pdGlvbk1hcCA9IHt9O1xuICBwcm90ZWN0ZWQgX2RlZmluaXRpb25zQnlJbmRleDogeyBbaW5kZXg6IG51bWJlcl06IEZvcm1GaWVsZERlZmluaXRpb24gfSA9IHt9O1xuICBwcm90ZWN0ZWQgX2hlbHBlcjogRm9ybUFycmF5SGVscGVyPFByb3BlcnR5PjtcblxuICBwcm90ZWN0ZWQgX2F1dG9jb21wbGV0ZUNvbmZpZzogTWF0QXV0b2NvbXBsZXRlRmllbGRDb25maWc7XG5cbiAgQElucHV0KCkgZm9ybUFycmF5TmFtZTogc3RyaW5nO1xuICBASW5wdXQoKSBmb3JtQXJyYXk6IFVudHlwZWRGb3JtQXJyYXk7XG4gIEBJbnB1dCgpIG9wdGlvbnM6IEZvcm1BcnJheUhlbHBlck9wdGlvbnM7XG4gIEBJbnB1dCgpIGNoaXBDb2xvcjogVGhlbWVQYWxldHRlIHwgUHJlZGVmaW5lZENvbG9ycyA9ICdhY2NlbnQnO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgbW9iaWxlOiBib29sZWFuO1xuICBASW5wdXQoKSBhcHBlYXJhbmNlOiBNYXRGb3JtRmllbGRBcHBlYXJhbmNlO1xuICBASW5wdXQoKSBzdWJzY3JpcHRTaXppbmc6IFN1YnNjcmlwdFNpemluZztcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIHNob3dIaW50S2V5ID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNob3dIaW50S2V5UHJlZml4ID0gJyc7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBzaG93TW9yZUJ1dHRvbiA9IHRydWU7XG4gIEBJbnB1dCgpIHNob3dNb3JlQnV0dG9uVGl0bGUgPSAnU0VUVElOR1MuQlROX1NIT1dfTU9SRV9IRUxQJztcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIHNob3dBZGRCdXR0b24gPSB0cnVlO1xuXG4gIEBJbnB1dCgpIHNldCBkZWZpbml0aW9ucyh2YWx1ZTogRm9ybUZpZWxkRGVmaW5pdGlvbltdKSB7XG4gICAgdGhpcy5fZGVmaW5pdGlvbnMgPSB2YWx1ZTtcbiAgICBpZiAodGhpcy5sb2FkZWQpIHRoaXMudXBkYXRlRGVmaW5pdGlvbnNNYXBzKCk7XG4gIH1cblxuICBnZXQgZGVmaW5pdGlvbnMoKTogRm9ybUZpZWxkRGVmaW5pdGlvbltdIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmaW5pdGlvbnM7XG4gIH1cblxuICBzZXQgdmFsdWUoZGF0YTogVFtdKSB7XG4gICAgdGhpcy5zZXRWYWx1ZShkYXRhKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBUW10ge1xuICAgIHJldHVybiB0aGlzLmZvcm1BcnJheS52YWx1ZSBhcyBUW107XG4gIH1cblxuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybUFycmF5Py5sZW5ndGggfHwgMDtcbiAgfVxuXG4gIGdldCBmaWVsZEZvcm1zKCk6IFVudHlwZWRGb3JtR3JvdXBbXSB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybUFycmF5LmNvbnRyb2xzIGFzIFVudHlwZWRGb3JtR3JvdXBbXTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcm90ZWN0ZWQgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICBwcm90ZWN0ZWQgZGF0ZUFkYXB0ZXI6IERhdGVBZGFwdGVyPE1vbWVudD4sXG4gICAgcHJvdGVjdGVkIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcm90ZWN0ZWQgdmFsaWRhdG9yOiBQcm9wZXJ0eVZhbGlkYXRvcixcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGZvcm1Hcm91cERpcjogRm9ybUdyb3VwRGlyZWN0aXZlXG4gICkge1xuICAgIHN1cGVyKGluamVjdG9yLCBudWxsKTtcblxuICAgIHRoaXMudGFiaW5kZXggPSAyMDsgLy8gRm9yIGNvbXBhdGliaWxpdHkgLSBUT0RPIHJlbW92ZSBsYXRlclxuICAgIC8vdGhpcy5kZWJ1ZyA9ICFlbnZpcm9ubWVudC5wcm9kdWN0aW9uO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucz8uYWxsb3dFbXB0eUFycmF5ID09PSBmYWxzZSAmJiBpc0VtcHR5QXJyYXkodGhpcy5fZGVmaW5pdGlvbnMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIG9yIGludmFsaWQgYXR0cmlidXRlICdkZWZpbml0aW9ucydcIik7XG4gICAgfVxuXG4gICAgdGhpcy5tb2JpbGUgPSB0aGlzLm1vYmlsZSA/PyBpc01vYmlsZSh3aW5kb3cpO1xuICAgIHRoaXMuX2F1dG9jb21wbGV0ZUNvbmZpZyA9IHtcbiAgICAgIHN1Z2dlc3RGbjogKHZhbHVlLCBmaWx0ZXIpID0+IHRoaXMuc3VnZ2VzdERlZmluaXRpb24odmFsdWUsIGZpbHRlciksXG4gICAgICBkaXNwbGF5V2l0aDogKHZhbHVlOiBhbnkpID0+IHtcbiAgICAgICAgLy8gVmFsdWUgaXMgYW4gb2JqZWN0IChhIFByb3BlcnR5KVxuICAgICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJldHVybiAodmFsdWUgYXMgUHJvcGVydHkpLnZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVmFsdWUgaXMgYSBrZXlcbiAgICAgICAgY29uc3QgZGVmID0gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB0aGlzLl9kZWZpbml0aW9uc01hcEJ5S2V5W3ZhbHVlXTtcbiAgICAgICAgaWYgKCFkZWYpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlLmluc3RhbnQoZGVmLmxhYmVsKTtcbiAgICAgIH0sXG4gICAgICBhdHRyaWJ1dGVzOiBbJ3ZhbHVlJ10sXG4gICAgICBjb2x1bW5OYW1lczogW3RoaXMudHJhbnNsYXRlLmluc3RhbnQoJ1NFVFRJTkdTLlBST1BFUlRZX0tFWScpXSxcbiAgICAgIHNwbGl0U2VhcmNoVGV4dDogZmFsc2UsXG4gICAgICBzaG93QWxsT25Gb2N1czogdHJ1ZSxcbiAgICAgIHNlbGVjdElucHV0Q29udGVudE9uRm9jdXM6IHRydWUsXG4gICAgfTtcblxuICAgIHRoaXMudXBkYXRlRGVmaW5pdGlvbnNNYXBzKCk7XG5cbiAgICAvLyBSZXRyaWV2ZSB0aGUgZm9ybVxuICAgIGNvbnN0IGZvcm0gPVxuICAgICAgKHRoaXMuZm9ybUFycmF5ICYmICh0aGlzLmZvcm1BcnJheS5wYXJlbnQgYXMgVW50eXBlZEZvcm1Hcm91cCkpIHx8ICh0aGlzLmZvcm1Hcm91cERpciAmJiB0aGlzLmZvcm1Hcm91cERpci5mb3JtKSB8fCB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHt9KTtcbiAgICB0aGlzLnNldEZvcm0oZm9ybSk7XG5cbiAgICB0aGlzLmZvcm1BcnJheSA9IHRoaXMuZm9ybUFycmF5IHx8ICh0aGlzLmZvcm1BcnJheU5hbWUgJiYgKGZvcm0uZ2V0KHRoaXMuZm9ybUFycmF5TmFtZSkgYXMgVW50eXBlZEZvcm1BcnJheSkpO1xuICAgIHRoaXMuZm9ybUFycmF5TmFtZSA9XG4gICAgICB0aGlzLmZvcm1BcnJheU5hbWUgfHwgKHRoaXMuZm9ybUFycmF5ICYmIE9iamVjdC5rZXlzKGZvcm0uY29udHJvbHMpLmZpbmQoKGtleSkgPT4gZm9ybS5nZXQoa2V5KSA9PT0gdGhpcy5mb3JtQXJyYXkpKSB8fCAncHJvcGVydGllcyc7XG4gICAgaWYgKCF0aGlzLmZvcm1BcnJheSkge1xuICAgICAgY29uc29sZS53YXJuKGBNaXNzaW5nIGFycmF5IGNvbnRyb2wgJyR7dGhpcy5mb3JtQXJyYXlOYW1lfScuIFdpbGwgY3JlYXRlIGl0IWApO1xuICAgICAgdGhpcy5mb3JtQXJyYXkgPSB0aGlzLmZvcm1CdWlsZGVyLmFycmF5KFtdKTtcbiAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKHRoaXMuZm9ybUFycmF5TmFtZSwgdGhpcy5mb3JtQXJyYXkpO1xuICAgIH1cblxuICAgIHRoaXMuX2hlbHBlciA9IG5ldyBGb3JtQXJyYXlIZWxwZXI8UHJvcGVydHk+KFxuICAgICAgdGhpcy5mb3JtQXJyYXksXG4gICAgICAodmFsdWUpID0+IHRoaXMudmFsaWRhdG9yLmdldEZvcm1Hcm91cCh2YWx1ZSksXG4gICAgICAodjEsIHYyKSA9PiAoIXYxICYmICF2MikgfHwgdjEua2V5ID09PSB2Mi5rZXksXG4gICAgICAodmFsdWUpID0+IHRoaXMuaXNFbXB0eVByb3BlcnR5KHZhbHVlKSxcbiAgICAgIHRoaXMub3B0aW9uc1xuICAgICk7XG5cbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZURlZmluaXRpb25zTWFwcygpIHtcbiAgICAvLyBGaWxsIG9wdGlvbnMgbWFwXG4gICAgdGhpcy5fZGVmaW5pdGlvbnNNYXBCeUtleSA9IHt9O1xuICAgIHRoaXMuX29wdGlvbnMgPSAodGhpcy5fZGVmaW5pdGlvbnMgfHwgW10pLm1hcCgobykgPT4ge1xuICAgICAgdGhpcy5fZGVmaW5pdGlvbnNNYXBCeUtleVtvLmtleV0gPSBvO1xuICAgICAgcmV0dXJuIHsga2V5OiBvLmtleSwgdmFsdWU6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoby5sYWJlbCkgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldERlZmluaXRpb25BdChpbmRleDogbnVtYmVyKTogRm9ybUZpZWxkRGVmaW5pdGlvbiB7XG4gICAgbGV0IGRlZmluaXRpb24gPSB0aGlzLl9kZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdO1xuICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgZGVmaW5pdGlvbiA9IHRoaXMudXBkYXRlRGVmaW5pdGlvbkF0KGluZGV4LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfVxuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgdXBkYXRlRGVmaW5pdGlvbkF0KGluZGV4OiBudW1iZXIsIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSk6IEZvcm1GaWVsZERlZmluaXRpb24ge1xuICAgIGxldCB2YWx1ZSA9ICh0aGlzLmZvcm1BcnJheS5hdChpbmRleCkgYXMgVW50eXBlZEZvcm1Hcm91cCkuY29udHJvbHMua2V5LnZhbHVlO1xuICAgIGNvbnN0IGtleSA9IHZhbHVlPy5rZXkgfHwgdmFsdWU7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IChrZXkgJiYgdGhpcy5fZGVmaW5pdGlvbnNNYXBCeUtleVtrZXldKSB8fCBudWxsO1xuICAgIHRoaXMuX2RlZmluaXRpb25zQnlJbmRleFtpbmRleF0gPSBkZWZpbml0aW9uOyAvLyB1cGRhdGUgbWFwIGJ5IGluZGV4XG4gICAgaWYgKG9wdHM/LmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgcmVtb3ZlQXQoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuX2hlbHBlci5yZW1vdmVBdChpbmRleCk7XG4gICAgdGhpcy5fZGVmaW5pdGlvbnNCeUluZGV4ID0ge307IC8vIGNsZWFyIG1hcCBieSBpbmRleFxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBpc1Vua25vd25GaWVsZChmaWVsZEZvcm06IFVudHlwZWRGb3JtR3JvdXApIHtcbiAgICBjb25zdCBrZXlDb250cm9sID0gZmllbGRGb3JtLmdldCgna2V5Jyk7XG4gICAgY29uc3Qga2V5ID0ga2V5Q29udHJvbCAmJiBrZXlDb250cm9sLnZhbHVlO1xuICAgIHJldHVybiBrZXkgJiYgaXNOaWwodGhpcy5fZGVmaW5pdGlvbnNNYXBCeUtleVtrZXldKTtcbiAgfVxuXG4gIHNldFZhbHVlKGRhdGE6IFRbXSB8IGFueSkge1xuICAgIGlmICghZGF0YSkgcmV0dXJuOyAvLyBTa2lwXG5cbiAgICAvLyBUcmFuc2Zvcm0gcHJvcGVydGllcyBtYXAgaW50byBhcnJheVxuICAgIGNvbnN0IHZhbHVlcyA9IEVudGl0eVV0aWxzLmdldE1hcEFzQXJyYXk8VD4oZGF0YSk7XG4gICAgdGhpcy5faGVscGVyLnJlc2l6ZSh2YWx1ZXMubGVuZ3RoKTtcbiAgICB0aGlzLl9oZWxwZXIuZm9ybUFycmF5LnBhdGNoVmFsdWUodmFsdWVzLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG5cbiAgICB0aGlzLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgdGhpcy5tYXJrQXNMb2FkZWQoKTtcbiAgfVxuXG4gIC8qIC0tIHByb3RlY3RlZCBtZXRob2RzIC0tICovXG5cbiAgcHJvdGVjdGVkIGFzeW5jIHN1Z2dlc3REZWZpbml0aW9uKHZhbHVlOiBhbnksIGZpbHRlcj86IGFueSk6IFByb21pc2U8TG9hZFJlc3VsdDxQcm9wZXJ0eT4+IHtcbiAgICB2YWx1ZSA9IHZhbHVlID8/ICcqJztcblxuICAgIC8vIEdldCBhcyBrZXlcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3Qgb2JqID0gKHRoaXMuX29wdGlvbnMgfHwgW10pLmZpbmQoKG8pID0+IG8ua2V5ID09PSB2YWx1ZSk7XG4gICAgICBpZiAob2JqKSByZXR1cm4geyBkYXRhOiBbb2JqXSB9IGFzIExvYWRSZXN1bHQ8UHJvcGVydHk+O1xuICAgIH1cbiAgICAvLyBHZXQgYXMgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiB7IGRhdGE6IHZhbHVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1Z2dlc3RGcm9tQXJyYXkodGhpcy5fb3B0aW9ucywgdmFsdWUsIHsgc2VhcmNoQXR0cmlidXRlOiAndmFsdWUnLCAuLi5maWx0ZXIgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNFbXB0eVByb3BlcnR5KG9iajogUHJvcGVydHkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNOaWwob2JqPy5rZXkpIHx8IGlzTmlsKG9iai52YWx1ZSk7XG4gIH1cbn1cbiIsIjwhLS0gUHJvcGVydGllcyAtLT5cbjxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIGNsYXNzPVwiZm9ybS1jb250YWluZXJcIj5cbiAgQGlmIChsb2FkaW5nU3ViamVjdCB8IGFzeW5jKSB7XG4gICAgPGlvbi1saXN0IFtpbnNldF09XCJtb2JpbGVcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJwcm9wZXJ0eVJvd1NrZWxldG9uXCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicHJvcGVydHlSb3dTa2VsZXRvblwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInByb3BlcnR5Um93U2tlbGV0b25cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2lvbi1saXN0PlxuICB9IEBlbHNlIHtcbiAgICA8aW9uLWxpc3QgZm9ybUFycmF5TmFtZT1cInByb3BlcnRpZXNcIiBbaW5zZXRdPVwibW9iaWxlXCI+XG4gICAgICA8IS0tIFNob3cgbW9yZSBvcHRpb25zIC0tPlxuICAgICAgQGlmICgoZGVmaW5pdGlvbnMgfCBpc05vdEVtcHR5QXJyYXkpICYmIGZvcm1BcnJheT8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIDxpb24taXRlbSBsaW5lcz1cIm5vbmVcIj5cbiAgICAgICAgICA8aW9uLWJ1dHRvbiBjb2xvcj1cImxpZ2h0XCIgW3RpdGxlXT1cInNob3dNb3JlQnV0dG9uVGl0bGUgfCB0cmFuc2xhdGVcIiAoY2xpY2spPVwiX2hlbHBlci5hZGQoKVwiPlxuICAgICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9TSE9XX01PUkU8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzbG90PVwiZW5kXCI+YXJyb3dfZHJvcF9kb3duPC9tYXQtaWNvbj5cbiAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICB9XG5cbiAgICAgIEBmb3IgKGZpZWxkRm9ybSBvZiBmaWVsZEZvcm1zOyB0cmFjayBpOyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCIgW2NsYXNzLm91dGxpbmVdPVwiYXBwZWFyYW5jZSA9PT0gJ291dGxpbmUnXCI+XG4gICAgICAgICAgPGlvbi1ncmlkIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgIDxpb24tcm93IFtmb3JtR3JvdXBOYW1lXT1cImlcIiBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgIDwhLS0gcHJvcGVydHkga2V5IC0tPlxuICAgICAgICAgICAgICBAaWYgKGZpZWxkRm9ybSB8IGZvcm1HZXRDb250cm9sOiAna2V5JzsgYXMgY29udHJvbCkge1xuICAgICAgICAgICAgICAgIDxpb24tY29sXG4gICAgICAgICAgICAgICAgICBzaXplPVwiMTJcIlxuICAgICAgICAgICAgICAgICAgc2l6ZS1zbT1cIjZcIlxuICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIihfZGVmaW5pdGlvbnNNYXBCeUtleSB8IG1hcEdldDogY29udHJvbD8udmFsdWUgfCBwcm9wZXJ0eUdldDogJ2xhYmVsJyB8IHRyYW5zbGF0ZSkgfHwgJydcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPG1hdC1hdXRvY29tcGxldGUtZmllbGRcbiAgICAgICAgICAgICAgICAgICAgZmxvYXRMYWJlbD1cImF1dG9cIlxuICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIlxuICAgICAgICAgICAgICAgICAgICBbc3Vic2NyaXB0U2l6aW5nXT1cIidkeW5hbWljJ1wiXG4gICAgICAgICAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwidXBkYXRlRGVmaW5pdGlvbkF0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4ICsgaSAqIDJcIlxuICAgICAgICAgICAgICAgICAgICBbY29uZmlnXT1cIl9hdXRvY29tcGxldGVDb25maWdcIlxuICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1NFVFRJTkdTLlBST1BFUlRZX0tFWScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICA+PC9tYXQtYXV0b2NvbXBsZXRlLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPCEtLTxtYXQtZm9ybS1maWVsZCBmbG9hdExhYmVsPVwiYXV0b1wiIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIiBbc3Vic2NyaXB0U2l6aW5nXT1cIidkeW5hbWljJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdTRVRUSU5HUy5QUk9QRVJUWV9LRVknIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwidXBkYXRlRGVmaW5pdGlvbkF0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbdGFiaW5kZXhdPVwidGFiaW5kZXggKyBpICogMlwiXG4gICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWRcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICZsdDshJm5kYXNoOyBXaGVuIG9wdGlvbidzIGtleSBub3QgYSB3ZWxsIGtub3duIG9wdGlvbiwgYWRkIGl0IGFzIGZpcnN0IHNlbGVjdCBvcHRpb24gJm5kYXNoOyZndDtcbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKGlzVW5rbm93bkZpZWxkKGZpZWxkRm9ybSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJjb250cm9sLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbnRyb2wudmFsdWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBkZWZpbml0aW9uc1wiIFt2YWx1ZV09XCJpdGVtLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgaXRlbS5sYWJlbCB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJjb250cm9sLmhhc0Vycm9yKCdyZXF1aXJlZCcpICYmICFfaGVscGVyLmlzTGFzdChpKVwiIHRyYW5zbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICBFUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cblxuICAgICAgICAgICAgICAgICAgICAmbHQ7ISZuZGFzaDsgJm5kYXNoOyZndDtcbiAgICAgICAgICAgICAgICAgICAgQGlmIChzaG93SGludEtleSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludD57eyBzaG93SGludEtleVByZWZpeCB8fCAnJyB9fXt7IGNvbnRyb2w/LnZhbHVlIHx8ICcnIH19PC9tYXQtaGludD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD4tLT5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICA8IS0tIHByb3BlcnR5IHZhbHVlIC0tPlxuICAgICAgICAgICAgICA8aW9uLWNvbCBzaXplPVwiXCIgc2l6ZS1zbT1cIlwiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmcgaW9uLXBhZGRpbmctc3RhcnQteHNcIj5cbiAgICAgICAgICAgICAgICBAbGV0IGRlZmluaXRpb24gPSBnZXREZWZpbml0aW9uQXQoaSk7XG4gICAgICAgICAgICAgICAgQGlmIChkZWZpbml0aW9uKSB7XG4gICAgICAgICAgICAgICAgICA8YXBwLWZvcm0tZmllbGRcbiAgICAgICAgICAgICAgICAgICAgW2Zsb2F0TGFiZWxdPVwibW9iaWxlID8gJ2F1dG8nIDogJ25ldmVyJ1wiXG4gICAgICAgICAgICAgICAgICAgIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIlxuICAgICAgICAgICAgICAgICAgICBbc3Vic2NyaXB0U2l6aW5nXT1cInN1YnNjcmlwdFNpemluZ1wiXG4gICAgICAgICAgICAgICAgICAgIFtkZWZpbml0aW9uXT1cImRlZmluaXRpb25cIlxuICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZmllbGRGb3JtIHwgZm9ybUdldENvbnRyb2w6ICd2YWx1ZSdcIlxuICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1NFVFRJTkdTLlBST1BFUlRZX1ZBTFVFJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtjaGlwQ29sb3JdPVwiY2hpcENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICBbdGFiaW5kZXhdPVwidGFiaW5kZXggKyBpICogMiArIDFcIlxuICAgICAgICAgICAgICAgICAgPjwvYXBwLWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICA8IS0tIHVua25vd24gZGVmaW5pdGlvbiAtLT5cbiAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCIgW3N1YnNjcmlwdFNpemluZ109XCJzdWJzY3JpcHRTaXppbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChtb2JpbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdTRVRUSU5HUy5QUk9QRVJUWV9WQUxVRScgfCB0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZmllbGRGb3JtIHwgZm9ybUdldENvbnRyb2w6ICd2YWx1ZSdcIlxuICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJtb2JpbGUgPyAnJyA6ICgnU0VUVElOR1MuUFJPUEVSVFlfVkFMVUUnIHwgdHJhbnNsYXRlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCIyMCArIGkgKiAyICsgMVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgICAgICAgIDxpb24tY29sIHNpemU9XCJhdXRvXCIgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICAgICAgICAgIEBpZiAoX2hlbHBlci5pc0xhc3QoaSkpIHtcbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBjb2xvcj1cImxpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkIHx8IChmaWVsZEZvcm0udmFsdWUgfCBhc0Jvb2xlYW46IGlzRW1wdHlQcm9wZXJ0eSlcIlxuICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ1NFVFRJTkdTLkJUTl9BRERfUFJPUEVSVFknIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIl9oZWxwZXIuYWRkKClcIlxuICAgICAgICAgICAgICAgICAgICBbdGFiaW5kZXhdPVwiMjAgKyBpICogMiArIDJcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgY29sb3I9XCJsaWdodFwiXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidDT01NT04uQlROX0RFTEVURScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUF0KGkpXCJcbiAgICAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCItMVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgIDwvaW9uLWdyaWQ+XG4gICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICB9XG4gICAgPC9pb24tbGlzdD5cbiAgfVxuPC9mb3JtPlxuXG48bmctdGVtcGxhdGUgI3Byb3BlcnR5Um93U2tlbGV0b24+XG4gIDxpb24taXRlbSBsaW5lcz1cIm5vbmVcIj5cbiAgICA8aW9uLWdyaWQgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICA8IS0tIHByb3BlcnR5IGtleSAtLT5cbiAgICAgICAgPGlvbi1jb2wgc2l6ZT1cIjZcIiBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtzdWJzY3JpcHRTaXppbmddPVwic3Vic2NyaXB0U2l6aW5nXCIgPlxuICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiBkaXNhYmxlZCAvPlxuICAgICAgICAgICAgPGlvbi1za2VsZXRvbi10ZXh0IGFuaW1hdGVkIHN0eWxlPVwid2lkdGg6IDYwJVwiPjwvaW9uLXNrZWxldG9uLXRleHQ+XG4gICAgICAgICAgICA8aW9uLWljb24gbmFtZT1cImFycm93LWRyb3Bkb3duXCIgbWF0U3VmZml4PjwvaW9uLWljb24+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPC9pb24tY29sPlxuICAgICAgICA8IS0tIHZhbHVlIC0tPlxuICAgICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtzdWJzY3JpcHRTaXppbmddPVwic3Vic2NyaXB0U2l6aW5nXCIgPlxuICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiBkaXNhYmxlZC8+XG4gICAgICAgICAgICA8aW9uLXNrZWxldG9uLXRleHQgYW5pbWF0ZWQgc3R5bGU9XCJ3aWR0aDogNjAlXCI+PC9pb24tc2tlbGV0b24tdGV4dD5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgIDwhLS0gYnV0dG9ucyAtLT5cbiAgICAgICAgPGlvbi1jb2wgc2l6ZT1cImF1dG9cIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gY29sb3I9XCJsaWdodFwiIGRpc2FibGVkPlxuICAgICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9pb24tY29sPlxuICAgICAgPC9pb24tcm93PlxuICAgIDwvaW9uLWdyaWQ+XG4gIDwvaW9uLWl0ZW0+XG48L25nLXRlbXBsYXRlPlxuIl19
@@ -1,6 +1,7 @@
1
- import { Directive } from '@angular/core';
1
+ import { Injectable } from '@angular/core';
2
2
  import { Validators } from '@angular/forms';
3
3
  import { AppValidatorService } from '../../services/validator/base.validator.class';
4
+ import { isNil } from '../../../shared/functions';
4
5
  import * as i0 from "@angular/core";
5
6
  import * as i1 from "@angular/forms";
6
7
  export class PropertyValidator extends AppValidatorService {
@@ -9,16 +10,29 @@ export class PropertyValidator extends AppValidatorService {
9
10
  super(formBuilder, null);
10
11
  this.formBuilder = formBuilder;
11
12
  }
12
- getFormGroupConfig(data) {
13
+ getFormGroup(data, opts) {
14
+ return this.formBuilder.group(this.getFormGroupConfig(data, opts));
15
+ }
16
+ getFormGroupConfig(data, opts) {
13
17
  return {
14
18
  key: [(data && data.key) || null, Validators.compose([Validators.required, Validators.max(50)])],
15
- value: [(data && data.value) || null, Validators.required],
19
+ value: [
20
+ (data && data.value) || null,
21
+ opts?.valueMaxLength > 0 ? Validators.compose([Validators.required, Validators.max(opts.valueMaxLength)]) : Validators.required,
22
+ ],
16
23
  };
17
24
  }
18
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PropertyValidator, deps: [{ token: i1.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Directive });
19
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.8", type: PropertyValidator, usesInheritance: true, ngImport: i0 });
25
+ equals(v1, v2) {
26
+ return (!v1 && !v2) || v1.key === v2.key;
27
+ }
28
+ isEmpty(obj) {
29
+ return isNil(obj?.key) || isNil(obj.value);
30
+ }
31
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PropertyValidator, deps: [{ token: i1.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Injectable });
32
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PropertyValidator, providedIn: 'root' });
20
33
  }
21
34
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PropertyValidator, decorators: [{
22
- type: Directive
35
+ type: Injectable,
36
+ args: [{ providedIn: 'root' }]
23
37
  }], ctorParameters: () => [{ type: i1.UntypedFormBuilder }] });
24
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHkudmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vcHJvcGVydGllcy9wcm9wZXJ0eS52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxQyxPQUFPLEVBQXNCLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWhFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDOzs7QUFHcEYsTUFBTSxPQUFPLGlCQUFrQixTQUFRLG1CQUE2QjtJQUM1QztJQUF0QixZQUFzQixXQUErQjtRQUNuRCxLQUFLLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBREwsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO0lBRXJELENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxJQUFlO1FBQ2hDLE9BQU87WUFDTCxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hHLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztTQUMzRCxDQUFDO0lBQ0osQ0FBQzt1R0FWVSxpQkFBaUI7MkZBQWpCLGlCQUFpQjs7MkZBQWpCLGlCQUFpQjtrQkFEN0IsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVW50eXBlZEZvcm1CdWlsZGVyLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUHJvcGVydHkgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQXBwVmFsaWRhdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3ZhbGlkYXRvci9iYXNlLnZhbGlkYXRvci5jbGFzcyc7XG5cbkBEaXJlY3RpdmUoKVxuZXhwb3J0IGNsYXNzIFByb3BlcnR5VmFsaWRhdG9yIGV4dGVuZHMgQXBwVmFsaWRhdG9yU2VydmljZTxQcm9wZXJ0eT4ge1xuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcikge1xuICAgIHN1cGVyKGZvcm1CdWlsZGVyLCBudWxsKTtcbiAgfVxuXG4gIGdldEZvcm1Hcm91cENvbmZpZyhkYXRhPzogUHJvcGVydHkpOiB7IFtwOiBzdHJpbmddOiBhbnkgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogWyhkYXRhICYmIGRhdGEua2V5KSB8fCBudWxsLCBWYWxpZGF0b3JzLmNvbXBvc2UoW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWF4KDUwKV0pXSxcbiAgICAgIHZhbHVlOiBbKGRhdGEgJiYgZGF0YS52YWx1ZSkgfHwgbnVsbCwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgfTtcbiAgfVxufVxuIl19
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHkudmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vcHJvcGVydGllcy9wcm9wZXJ0eS52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQXdDLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWxGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBT2xELE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxtQkFBNkI7SUFDNUM7SUFBdEIsWUFBc0IsV0FBK0I7UUFDbkQsS0FBSyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQURMLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtJQUVyRCxDQUFDO0lBRUQsWUFBWSxDQUFDLElBQWUsRUFBRSxJQUErQjtRQUMzRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBZSxFQUFFLElBQStCO1FBQ2pFLE9BQU87WUFDTCxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hHLEtBQUssRUFBRTtnQkFDTCxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSTtnQkFDNUIsSUFBSSxFQUFFLGNBQWMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVE7YUFDaEk7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sQ0FBQyxFQUFZLEVBQUUsRUFBWTtRQUMvQixPQUFPLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUM7SUFDM0MsQ0FBQztJQUVELE9BQU8sQ0FBQyxHQUFhO1FBQ25CLE9BQU8sS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdDLENBQUM7dUdBekJVLGlCQUFpQjsyR0FBakIsaUJBQWlCLGNBREosTUFBTTs7MkZBQ25CLGlCQUFpQjtrQkFEN0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBQcm9wZXJ0eSB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBBcHBWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdmFsaWRhdG9yL2Jhc2UudmFsaWRhdG9yLmNsYXNzJztcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvcGVydHlWYWxpZGF0b3JPcHRpb25zIHtcbiAgdmFsdWVNYXhMZW5ndGg/OiBudW1iZXI7XG59XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgUHJvcGVydHlWYWxpZGF0b3IgZXh0ZW5kcyBBcHBWYWxpZGF0b3JTZXJ2aWNlPFByb3BlcnR5PiB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyKSB7XG4gICAgc3VwZXIoZm9ybUJ1aWxkZXIsIG51bGwpO1xuICB9XG5cbiAgZ2V0Rm9ybUdyb3VwKGRhdGE/OiBQcm9wZXJ0eSwgb3B0cz86IFByb3BlcnR5VmFsaWRhdG9yT3B0aW9ucyk6IFVudHlwZWRGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHRoaXMuZ2V0Rm9ybUdyb3VwQ29uZmlnKGRhdGEsIG9wdHMpKTtcbiAgfVxuXG4gIGdldEZvcm1Hcm91cENvbmZpZyhkYXRhPzogUHJvcGVydHksIG9wdHM/OiBQcm9wZXJ0eVZhbGlkYXRvck9wdGlvbnMpOiB7IFtwOiBzdHJpbmddOiBhbnkgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogWyhkYXRhICYmIGRhdGEua2V5KSB8fCBudWxsLCBWYWxpZGF0b3JzLmNvbXBvc2UoW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWF4KDUwKV0pXSxcbiAgICAgIHZhbHVlOiBbXG4gICAgICAgIChkYXRhICYmIGRhdGEudmFsdWUpIHx8IG51bGwsXG4gICAgICAgIG9wdHM/LnZhbHVlTWF4TGVuZ3RoID4gMCA/IFZhbGlkYXRvcnMuY29tcG9zZShbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5tYXgob3B0cy52YWx1ZU1heExlbmd0aCldKSA6IFZhbGlkYXRvcnMucmVxdWlyZWQsXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBlcXVhbHModjE6IFByb3BlcnR5LCB2MjogUHJvcGVydHkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKCF2MSAmJiAhdjIpIHx8IHYxLmtleSA9PT0gdjIua2V5O1xuICB9XG5cbiAgaXNFbXB0eShvYmo6IFByb3BlcnR5KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTmlsKG9iaj8ua2V5KSB8fCBpc05pbChvYmoudmFsdWUpO1xuICB9XG59XG4iXX0=