ngx-dynamic-entity 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +129 -139
  2. package/esm2022/lib/field-types/array-field.component.mjs +112 -104
  3. package/esm2022/lib/field-types/boolean-field.component.mjs +62 -61
  4. package/esm2022/lib/field-types/checkbox-field.component.mjs +48 -47
  5. package/esm2022/lib/field-types/currency-field.component.mjs +54 -53
  6. package/esm2022/lib/field-types/date-field.component.mjs +46 -45
  7. package/esm2022/lib/field-types/dropdown-field.component.mjs +89 -87
  8. package/esm2022/lib/field-types/email-field.component.mjs +64 -63
  9. package/esm2022/lib/field-types/entity-ref-field.component.mjs +85 -71
  10. package/esm2022/lib/field-types/field-component.contract.mjs +2 -0
  11. package/esm2022/lib/field-types/file-field.component.mjs +88 -87
  12. package/esm2022/lib/field-types/group-field.component.mjs +50 -50
  13. package/esm2022/lib/field-types/image-field.component.mjs +92 -91
  14. package/esm2022/lib/field-types/month-year-field.component.mjs +80 -79
  15. package/esm2022/lib/field-types/multi-select-field.component.mjs +66 -65
  16. package/esm2022/lib/field-types/number-field.component.mjs +71 -75
  17. package/esm2022/lib/field-types/password-field.component.mjs +68 -67
  18. package/esm2022/lib/field-types/radio-field.component.mjs +66 -65
  19. package/esm2022/lib/field-types/text-field.component.mjs +81 -74
  20. package/esm2022/lib/field-types/textarea-field.component.mjs +48 -47
  21. package/esm2022/lib/form/dynamic-field/dynamic-field.component.mjs +53 -6
  22. package/esm2022/lib/form/dynamic-form.component.mjs +309 -20
  23. package/esm2022/lib/form/dynamic-record-form.component.mjs +36 -11
  24. package/esm2022/lib/providers/provide-field-types.mjs +1 -1
  25. package/esm2022/lib/providers/provide-ngx-dynamic-entity.mjs +8 -2
  26. package/esm2022/lib/services/cascade-data.service.mjs +2 -2
  27. package/esm2022/lib/services/entity-ref-cache.mjs +1 -1
  28. package/esm2022/lib/services/entity-ref-registry.service.mjs +2 -2
  29. package/esm2022/lib/services/entity-ref-selection.service.mjs +1 -1
  30. package/esm2022/lib/services/entity-reference.service.mjs +1 -1
  31. package/esm2022/lib/services/field-registry.service.mjs +1 -1
  32. package/esm2022/lib/services/file-upload.service.mjs +1 -1
  33. package/esm2022/lib/services/lookup-registry.service.mjs +2 -2
  34. package/esm2022/lib/services/rbac.service.mjs +1 -1
  35. package/esm2022/lib/services/validation-messages.service.mjs +56 -0
  36. package/esm2022/lib/services/validator-registry.service.mjs +35 -2
  37. package/esm2022/lib/tokens/injection-tokens.mjs +35 -6
  38. package/esm2022/public-api.mjs +23 -2
  39. package/fesm2022/ngx-dynamic-entity.mjs +1754 -1236
  40. package/fesm2022/ngx-dynamic-entity.mjs.map +1 -1
  41. package/lib/field-types/array-field.component.d.ts +7 -1
  42. package/lib/field-types/dropdown-field.component.d.ts +2 -1
  43. package/lib/field-types/entity-ref-field.component.d.ts +12 -2
  44. package/lib/field-types/field-component.contract.d.ts +49 -0
  45. package/lib/field-types/group-field.component.d.ts +1 -1
  46. package/lib/field-types/multi-select-field.component.d.ts +1 -1
  47. package/lib/field-types/number-field.component.d.ts +1 -0
  48. package/lib/field-types/radio-field.component.d.ts +1 -1
  49. package/lib/field-types/text-field.component.d.ts +10 -2
  50. package/lib/form/dynamic-field/dynamic-field.component.d.ts +39 -4
  51. package/lib/form/dynamic-form.component.d.ts +155 -8
  52. package/lib/form/dynamic-record-form.component.d.ts +13 -2
  53. package/lib/providers/provide-ngx-dynamic-entity.d.ts +25 -3
  54. package/lib/services/cascade-data.service.d.ts +1 -1
  55. package/lib/services/entity-ref-registry.service.d.ts +1 -1
  56. package/lib/services/lookup-registry.service.d.ts +1 -1
  57. package/lib/services/validation-messages.service.d.ts +43 -0
  58. package/lib/services/validator-registry.service.d.ts +13 -1
  59. package/lib/tokens/injection-tokens.d.ts +42 -7
  60. package/package.json +17 -18
  61. package/public-api.d.ts +12 -0
  62. package/styles.css +579 -0
@@ -1,4 +1,4 @@
1
- import { Component, DestroyRef, Input, inject, signal } from '@angular/core';
1
+ import { Component, DestroyRef, Input, inject, signal, ChangeDetectionStrategy } from '@angular/core';
2
2
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
3
  import { ReactiveFormsModule } from '@angular/forms';
4
4
  import { resolveLabel } from '@dynamic-entity/core';
@@ -41,6 +41,9 @@ export class EntityRefFieldComponent {
41
41
  return;
42
42
  void this.reload();
43
43
  this.watchParent();
44
+ this.control?.valueChanges
45
+ .pipe(takeUntilDestroyed(this.destroyRef))
46
+ .subscribe(value => this.publishSelection(String(value ?? '')));
44
47
  }
45
48
  /** Reload options against the parent's current value. */
46
49
  async reload() {
@@ -58,8 +61,20 @@ export class EntityRefFieldComponent {
58
61
  this.loading.set(false);
59
62
  }
60
63
  }
61
- onSelectionChange() {
62
- const selected = this.options().find(o => String(o.value) === String(this.control.value));
64
+ /**
65
+ * Publish the selected option so autoPatch can copy from its record.
66
+ *
67
+ * Driven from `valueChanges` rather than the select's `change` event: that event is the
68
+ * same one the `formControl` directive listens to, so reading the control inside a
69
+ * template `(change)` handler can see the previous value. `valueChanges` fires after the
70
+ * model has updated — including Playwright `selectOption`, which updates the control
71
+ * through the value accessor.
72
+ */
73
+ onSelectionChange(value) {
74
+ this.publishSelection(value ?? String(this.control?.value ?? ''));
75
+ }
76
+ publishSelection(current) {
77
+ const selected = this.options().find(o => String(o.value) === current);
63
78
  this.selectionBus.emit(this.field.id, selected ?? null);
64
79
  }
65
80
  getLabel(value) {
@@ -91,80 +106,79 @@ export class EntityRefFieldComponent {
91
106
  });
92
107
  }
93
108
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EntityRefFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
94
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EntityRefFieldComponent, isStandalone: true, selector: "ngx-entity-ref-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
95
- <div class="ngx-field ngx-field--entity-ref"
96
- [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
97
- <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
98
- @if (masked) {
99
- <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
100
- } @else if (readonly) {
101
- <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ getLabel(control.value) }}</span>
102
- } @else {
103
- @if (loading()) {
104
- <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-loading'" role="status">Loading…</span>
105
- } @else {
106
- <select
107
- class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
108
- [id]="'field-' + field.id"
109
- [formControl]="$any(control)"
110
- [attr.disabled]="field.disabled ? true : null"
111
- (change)="onSelectionChange()"
112
- >
113
- <option value="">{{ placeholder || 'Select...' }}</option>
114
- @for (option of options(); track option.value) {
115
- <option [value]="option.value">{{ option.label }}</option>
116
- }
117
- </select>
118
- @if (awaitingParent()) {
119
- <span class="ngx-field__hint" [attr.data-testid]="'field-' + field.id + '-hint'">Select {{ parentFieldId }} first.</span>
120
- }
121
- }
122
- @if (control.invalid && control.touched) {
123
- <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
124
- }
125
- }
126
- </div>
127
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
109
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EntityRefFieldComponent, isStandalone: true, selector: "ngx-entity-ref-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
110
+ <div class="ngx-field ngx-field--entity-ref"
111
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
112
+ <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
113
+ @if (masked) {
114
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
115
+ } @else if (readonly) {
116
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ getLabel(control.value) }}</span>
117
+ } @else {
118
+ @if (loading()) {
119
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-loading'" role="status">Loading…</span>
120
+ } @else {
121
+ <select
122
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
123
+ [id]="'field-' + field.id"
124
+ [formControl]="$any(control)"
125
+ [attr.disabled]="field.disabled ? true : null"
126
+ >
127
+ <option value="">{{ placeholder || 'Select...' }}</option>
128
+ @for (option of options(); track option.value) {
129
+ <option [value]="option.value">{{ option.label }}</option>
130
+ }
131
+ </select>
132
+ @if (awaitingParent()) {
133
+ <span class="ngx-field__hint" [attr.data-testid]="'field-' + field.id + '-hint'">Select {{ parentFieldId }} first.</span>
134
+ }
135
+ }
136
+ @if (control.invalid && control.touched) {
137
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
138
+ }
139
+ }
140
+ </div>
141
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
128
142
  }
129
143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EntityRefFieldComponent, decorators: [{
130
144
  type: Component,
131
145
  args: [{
146
+ changeDetection: ChangeDetectionStrategy.OnPush,
132
147
  selector: 'ngx-entity-ref-field',
133
148
  standalone: true,
134
149
  imports: [ReactiveFormsModule],
135
- template: `
136
- <div class="ngx-field ngx-field--entity-ref"
137
- [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
138
- <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
139
- @if (masked) {
140
- <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
141
- } @else if (readonly) {
142
- <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ getLabel(control.value) }}</span>
143
- } @else {
144
- @if (loading()) {
145
- <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-loading'" role="status">Loading…</span>
146
- } @else {
147
- <select
148
- class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
149
- [id]="'field-' + field.id"
150
- [formControl]="$any(control)"
151
- [attr.disabled]="field.disabled ? true : null"
152
- (change)="onSelectionChange()"
153
- >
154
- <option value="">{{ placeholder || 'Select...' }}</option>
155
- @for (option of options(); track option.value) {
156
- <option [value]="option.value">{{ option.label }}</option>
157
- }
158
- </select>
159
- @if (awaitingParent()) {
160
- <span class="ngx-field__hint" [attr.data-testid]="'field-' + field.id + '-hint'">Select {{ parentFieldId }} first.</span>
161
- }
162
- }
163
- @if (control.invalid && control.touched) {
164
- <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
165
- }
166
- }
167
- </div>
150
+ template: `
151
+ <div class="ngx-field ngx-field--entity-ref"
152
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
153
+ <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
154
+ @if (masked) {
155
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
156
+ } @else if (readonly) {
157
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ getLabel(control.value) }}</span>
158
+ } @else {
159
+ @if (loading()) {
160
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-loading'" role="status">Loading…</span>
161
+ } @else {
162
+ <select
163
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
164
+ [id]="'field-' + field.id"
165
+ [formControl]="$any(control)"
166
+ [attr.disabled]="field.disabled ? true : null"
167
+ >
168
+ <option value="">{{ placeholder || 'Select...' }}</option>
169
+ @for (option of options(); track option.value) {
170
+ <option [value]="option.value">{{ option.label }}</option>
171
+ }
172
+ </select>
173
+ @if (awaitingParent()) {
174
+ <span class="ngx-field__hint" [attr.data-testid]="'field-' + field.id + '-hint'">Select {{ parentFieldId }} first.</span>
175
+ }
176
+ }
177
+ @if (control.invalid && control.touched) {
178
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
179
+ }
180
+ }
181
+ </div>
168
182
  `,
169
183
  }]
170
184
  }], propDecorators: { field: [{
@@ -178,4 +192,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
178
192
  }], masked: [{
179
193
  type: Input
180
194
  }] } });
181
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXJlZi1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL2VudGl0eS1yZWYtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBbUIsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMENBQTBDLENBQUM7OztBQUVyRjs7Ozs7OztHQU9HO0FBd0NILE1BQU0sT0FBTyx1QkFBdUI7SUFDekIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQW1CO0lBQzFCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixNQUFNLEdBQVksS0FBSyxDQUFDO0lBRWhCLE9BQU8sR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNyQyxZQUFZLEdBQUcsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDakQsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUV4QyxPQUFPLEdBQUcsTUFBTSxDQUFvQixFQUFFLENBQUMsQ0FBQztJQUN4QyxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLHFFQUFxRTtJQUM1RCxjQUFjLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRXhDLElBQUksS0FBSztRQUNQLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ2IsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRCxJQUFJLGFBQWE7UUFDZixPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLFdBQVcsQ0FBQztJQUNsRCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPO1FBQ3hCLEtBQUssSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQseURBQXlEO0lBQ3pELEtBQUssQ0FBQyxNQUFNO1FBQ1YsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUNyQixDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLFdBQVcsS0FBSyxJQUFJLElBQUksV0FBVyxLQUFLLFNBQVMsSUFBSSxXQUFXLEtBQUssRUFBRSxDQUFDLENBQ2xHLENBQUM7UUFFRixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDckIsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FDZCxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUMxRSxDQUFDO1FBQ0osQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUM7SUFFRCxpQkFBaUI7UUFDZixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzFGLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLFFBQVEsSUFBSSxJQUFJLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQVU7UUFDakIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDM0UsT0FBTyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFTyxXQUFXO1FBQ2pCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDcEMsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUNoQyxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUM7SUFDcEQsQ0FBQztJQUVELCtFQUErRTtJQUN2RSxXQUFXO1FBQ2pCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDcEMsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBQ3RCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFFM0IsYUFBYSxDQUFDLFlBQVk7YUFDdkIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUN6QyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDOUMsQ0FBQztZQUNELEtBQUssSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQzt3R0F4RlUsdUJBQXVCOzRGQUF2Qix1QkFBdUIsOExBbkN4Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUNULDJEQWxDUyxtQkFBbUI7OzRGQW9DbEIsdUJBQXVCO2tCQXZDbkMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsc0JBQXNCO29CQUNoQyxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsbUJBQW1CLENBQUM7b0JBQzlCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUNUO2lCQUNGOzhCQUVVLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRGVzdHJveVJlZiwgSW5wdXQsIE9uSW5pdCwgaW5qZWN0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xyXG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB0eXBlIHsgTmVzdGVkRmllbGRDb25maWcsIFJlZmVyZW5jZU9wdGlvbiB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcclxuaW1wb3J0IHsgcmVzb2x2ZUxhYmVsIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xyXG5pbXBvcnQgeyBDYXNjYWRlRGF0YVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9jYXNjYWRlLWRhdGEuc2VydmljZSc7XHJcbmltcG9ydCB7IEVudGl0eVJlZlNlbGVjdGlvblNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9lbnRpdHktcmVmLXNlbGVjdGlvbi5zZXJ2aWNlJztcclxuXHJcbi8qKlxyXG4gKiBFbnRpdHlSZWZGaWVsZENvbXBvbmVudCDigJQgYSBzZWxlY3QgcG9wdWxhdGVkIGZyb20gYSBjb25zdW1lci1yZWdpc3RlcmVkIGxvYWRlci5cclxuICpcclxuICogQ2FzY2FkZXM6IHdoZW4gYGVudGl0eVJlZmVyZW5jZS5wYXJlbnRGaWVsZGAgaXMgc2V0LCB0aGUgY29tcG9uZW50IHdhdGNoZXMgdGhhdCBzaWJsaW5nXHJcbiAqIGNvbnRyb2wgKHZpYSBgY29udHJvbC5wYXJlbnRgKSBhbmQgcmVsb2FkcyBpdHMgb3duIG9wdGlvbnMgb24gZXZlcnkgcGFyZW50IGNoYW5nZSxcclxuICogY2xlYXJpbmcgYSBub3ctaW52YWxpZCBzZWxlY3Rpb24uIEl0IHB1Ymxpc2hlcyB0aGUgcGlja2VkIHJlY29yZCBvblxyXG4gKiBgRW50aXR5UmVmU2VsZWN0aW9uU2VydmljZWAgc28gdGhlIG93bmluZyBmb3JtIGNhbiBydW4gYGF1dG9QYXRjaGAuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25neC1lbnRpdHktcmVmLWZpZWxkJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPGRpdiBjbGFzcz1cIm5neC1maWVsZCBuZ3gtZmllbGQtLWVudGl0eS1yZWZcIlxyXG4gICAgICBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkXCIgW2F0dHIuZGF0YS1maWVsZC10eXBlXT1cImZpZWxkLnR5cGVcIiBbY2xhc3Mubmd4LWZpZWxkLS1yZWFkb25seV09XCJyZWFkb25seVwiIFtjbGFzcy5uZ3gtZmllbGQtLW1hc2tlZF09XCJtYXNrZWRcIj5cclxuICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZpZWxkX19sYWJlbFwiIFthdHRyLmZvcl09XCInZmllbGQtJyArIGZpZWxkLmlkXCI+e3sgbGFiZWwgfX08L2xhYmVsPlxyXG4gICAgICBAaWYgKG1hc2tlZCkge1xyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZSBuZ3gtZmllbGRfX3ZhbHVlLS1tYXNrZWRcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1tYXNrZWQnXCI+WFhYWFhYWFhYPC9zcGFuPlxyXG4gICAgICB9IEBlbHNlIGlmIChyZWFkb25seSkge1xyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZVwiIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWQgKyAnLXZhbHVlJ1wiPnt7IGdldExhYmVsKGNvbnRyb2wudmFsdWUpIH19PC9zcGFuPlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgICBAaWYgKGxvYWRpbmcoKSkge1xyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctbG9hZGluZydcIiByb2xlPVwic3RhdHVzXCI+TG9hZGluZ+KApjwvc3Bhbj5cclxuICAgICAgICB9IEBlbHNlIHtcclxuICAgICAgICAgIDxzZWxlY3RcclxuICAgICAgICAgICAgY2xhc3M9XCJuZ3gtZmllbGRfX2lucHV0XCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctaW5wdXQnXCJcclxuICAgICAgICAgICAgW2lkXT1cIidmaWVsZC0nICsgZmllbGQuaWRcIlxyXG4gICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiJGFueShjb250cm9sKVwiXHJcbiAgICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cImZpZWxkLmRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxyXG4gICAgICAgICAgICAoY2hhbmdlKT1cIm9uU2VsZWN0aW9uQ2hhbmdlKClcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+e3sgcGxhY2Vob2xkZXIgfHwgJ1NlbGVjdC4uLicgfX08L29wdGlvbj5cclxuICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIG9wdGlvbnMoKTsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgQGlmIChhd2FpdGluZ1BhcmVudCgpKSB7XHJcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX19oaW50XCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctaGludCdcIj5TZWxlY3Qge3sgcGFyZW50RmllbGRJZCB9fSBmaXJzdC48L3NwYW4+XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIEBpZiAoY29udHJvbC5pbnZhbGlkICYmIGNvbnRyb2wudG91Y2hlZCkge1xyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctZXJyb3InXCI+VGhpcyBmaWVsZCBoYXMgYW4gZXJyb3I8L3NwYW4+XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICBgLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRW50aXR5UmVmRmllbGRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIEBJbnB1dCgpIGZpZWxkITogTmVzdGVkRmllbGRDb25maWc7XHJcbiAgQElucHV0KCkgY29udHJvbCE6IEFic3RyYWN0Q29udHJvbDtcclxuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcclxuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIG1hc2tlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IGNhc2NhZGUgPSBpbmplY3QoQ2FzY2FkZURhdGFTZXJ2aWNlKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IHNlbGVjdGlvbkJ1cyA9IGluamVjdChFbnRpdHlSZWZTZWxlY3Rpb25TZXJ2aWNlKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XHJcblxyXG4gIHJlYWRvbmx5IG9wdGlvbnMgPSBzaWduYWw8UmVmZXJlbmNlT3B0aW9uW10+KFtdKTtcclxuICByZWFkb25seSBsb2FkaW5nID0gc2lnbmFsKGZhbHNlKTtcclxuICAvKiogVHJ1ZSB3aGVuIHRoaXMgZmllbGQgY2FzY2FkZXMgYnV0IGl0cyBwYXJlbnQgaGFzIG5vIHZhbHVlIHlldC4gKi9cclxuICByZWFkb25seSBhd2FpdGluZ1BhcmVudCA9IHNpZ25hbChmYWxzZSk7XHJcblxyXG4gIGdldCBsYWJlbCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHJlc29sdmVMYWJlbCh0aGlzLmZpZWxkPy5sYWJlbCwgdGhpcy5sYW5ndWFnZSk7XHJcbiAgfVxyXG5cclxuICBnZXQgcGxhY2Vob2xkZXIoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiByZXNvbHZlTGFiZWwodGhpcy5maWVsZD8ucGxhY2Vob2xkZXIsIHRoaXMubGFuZ3VhZ2UpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHBhcmVudEZpZWxkSWQoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcclxuICAgIHJldHVybiB0aGlzLmZpZWxkPy5lbnRpdHlSZWZlcmVuY2U/LnBhcmVudEZpZWxkO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5tYXNrZWQpIHJldHVybjtcclxuICAgIHZvaWQgdGhpcy5yZWxvYWQoKTtcclxuICAgIHRoaXMud2F0Y2hQYXJlbnQoKTtcclxuICB9XHJcblxyXG4gIC8qKiBSZWxvYWQgb3B0aW9ucyBhZ2FpbnN0IHRoZSBwYXJlbnQncyBjdXJyZW50IHZhbHVlLiAqL1xyXG4gIGFzeW5jIHJlbG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IHBhcmVudFZhbHVlID0gdGhpcy5wYXJlbnRWYWx1ZSgpO1xyXG4gICAgdGhpcy5hd2FpdGluZ1BhcmVudC5zZXQoXHJcbiAgICAgICEhdGhpcy5wYXJlbnRGaWVsZElkICYmIChwYXJlbnRWYWx1ZSA9PT0gbnVsbCB8fCBwYXJlbnRWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHBhcmVudFZhbHVlID09PSAnJyksXHJcbiAgICApO1xyXG5cclxuICAgIGlmICghdGhpcy5jYXNjYWRlLmNhbkxvYWQodGhpcy5maWVsZCkpIHtcclxuICAgICAgdGhpcy5vcHRpb25zLnNldChbXSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy5vcHRpb25zLnNldChcclxuICAgICAgICBhd2FpdCB0aGlzLmNhc2NhZGUubG9hZCh0aGlzLmZpZWxkLCB7IHBhcmVudFZhbHVlLCBsYW5nOiB0aGlzLmxhbmd1YWdlIH0pLFxyXG4gICAgICApO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvblNlbGVjdGlvbkNoYW5nZSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5vcHRpb25zKCkuZmluZChvID0+IFN0cmluZyhvLnZhbHVlKSA9PT0gU3RyaW5nKHRoaXMuY29udHJvbC52YWx1ZSkpO1xyXG4gICAgdGhpcy5zZWxlY3Rpb25CdXMuZW1pdCh0aGlzLmZpZWxkLmlkLCBzZWxlY3RlZCA/PyBudWxsKTtcclxuICB9XHJcblxyXG4gIGdldExhYmVsKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgY29uc3Qgb3B0aW9uID0gdGhpcy5vcHRpb25zKCkuZmluZChvID0+IFN0cmluZyhvLnZhbHVlKSA9PT0gU3RyaW5nKHZhbHVlKSk7XHJcbiAgICByZXR1cm4gb3B0aW9uPy5sYWJlbCA/PyAodmFsdWUgPz8gJ+KAlCcpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwYXJlbnRWYWx1ZSgpOiB1bmtub3duIHtcclxuICAgIGNvbnN0IHBhcmVudElkID0gdGhpcy5wYXJlbnRGaWVsZElkO1xyXG4gICAgaWYgKCFwYXJlbnRJZCkgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIHJldHVybiB0aGlzLmNvbnRyb2w/LnBhcmVudD8uZ2V0KHBhcmVudElkKT8udmFsdWU7XHJcbiAgfVxyXG5cclxuICAvKiogUmVsb2FkIChhbmQgZHJvcCBhIHN0YWxlIHNlbGVjdGlvbikgd2hlbmV2ZXIgdGhlIHBhcmVudCBjb250cm9sIGNoYW5nZXMuICovXHJcbiAgcHJpdmF0ZSB3YXRjaFBhcmVudCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHBhcmVudElkID0gdGhpcy5wYXJlbnRGaWVsZElkO1xyXG4gICAgaWYgKCFwYXJlbnRJZCkgcmV0dXJuO1xyXG4gICAgY29uc3QgcGFyZW50Q29udHJvbCA9IHRoaXMuY29udHJvbD8ucGFyZW50Py5nZXQocGFyZW50SWQpO1xyXG4gICAgaWYgKCFwYXJlbnRDb250cm9sKSByZXR1cm47XHJcblxyXG4gICAgcGFyZW50Q29udHJvbC52YWx1ZUNoYW5nZXNcclxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLmNvbnRyb2wudmFsdWUpIHtcclxuICAgICAgICAgIHRoaXMuY29udHJvbC5zZXRWYWx1ZSgnJywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3Rpb25CdXMuZW1pdCh0aGlzLmZpZWxkLmlkLCBudWxsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdm9pZCB0aGlzLnJlbG9hZCgpO1xyXG4gICAgICB9KTtcclxuICB9XHJcbn1cclxuIl19
195
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXJlZi1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL2VudGl0eS1yZWYtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBbUIsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMENBQTBDLENBQUM7OztBQUVyRjs7Ozs7OztHQU9HO0FBd0NILE1BQU0sT0FBTyx1QkFBdUI7SUFDekIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQW1CO0lBQzFCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixNQUFNLEdBQVksS0FBSyxDQUFDO0lBRWhCLE9BQU8sR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNyQyxZQUFZLEdBQUcsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDakQsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUV4QyxPQUFPLEdBQUcsTUFBTSxDQUFvQixFQUFFLENBQUMsQ0FBQztJQUN4QyxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLHFFQUFxRTtJQUM1RCxjQUFjLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFD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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdDVCwyREFqQ1MsbUJBQW1COzs0RkFtQ2xCLHVCQUF1QjtrQkF2Q25DLFNBQVM7bUJBQUM7b0JBQ1QsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLFFBQVEsRUFBRSxzQkFBc0I7b0JBQ2hDLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztvQkFDOUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdDVDtpQkFDRjs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIERlc3Ryb3lSZWYsIElucHV0LCBPbkluaXQsIGluamVjdCwgc2lnbmFsLCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBOZXN0ZWRGaWVsZENvbmZpZywgUmVmZXJlbmNlT3B0aW9uIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xuaW1wb3J0IHsgcmVzb2x2ZUxhYmVsIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xuaW1wb3J0IHsgQ2FzY2FkZURhdGFTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvY2FzY2FkZS1kYXRhLnNlcnZpY2UnO1xuaW1wb3J0IHsgRW50aXR5UmVmU2VsZWN0aW9uU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2VudGl0eS1yZWYtc2VsZWN0aW9uLnNlcnZpY2UnO1xuXG4vKipcbiAqIEVudGl0eVJlZkZpZWxkQ29tcG9uZW50IOKAlCBhIHNlbGVjdCBwb3B1bGF0ZWQgZnJvbSBhIGNvbnN1bWVyLXJlZ2lzdGVyZWQgbG9hZGVyLlxuICpcbiAqIENhc2NhZGVzOiB3aGVuIGBlbnRpdHlSZWZlcmVuY2UucGFyZW50RmllbGRgIGlzIHNldCwgdGhlIGNvbXBvbmVudCB3YXRjaGVzIHRoYXQgc2libGluZ1xuICogY29udHJvbCAodmlhIGBjb250cm9sLnBhcmVudGApIGFuZCByZWxvYWRzIGl0cyBvd24gb3B0aW9ucyBvbiBldmVyeSBwYXJlbnQgY2hhbmdlLFxuICogY2xlYXJpbmcgYSBub3ctaW52YWxpZCBzZWxlY3Rpb24uIEl0IHB1Ymxpc2hlcyB0aGUgcGlja2VkIHJlY29yZCBvblxuICogYEVudGl0eVJlZlNlbGVjdGlvblNlcnZpY2VgIHNvIHRoZSBvd25pbmcgZm9ybSBjYW4gcnVuIGBhdXRvUGF0Y2hgLlxuICovXG5AQ29tcG9uZW50KHtcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHNlbGVjdG9yOiAnbmd4LWVudGl0eS1yZWYtZmllbGQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbUmVhY3RpdmVGb3Jtc01vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cIm5neC1maWVsZCBuZ3gtZmllbGQtLWVudGl0eS1yZWZcIlxuICAgICAgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZFwiIFthdHRyLmRhdGEtZmllbGQtdHlwZV09XCJmaWVsZC50eXBlXCIgW2NsYXNzLm5neC1maWVsZC0tcmVhZG9ubHldPVwicmVhZG9ubHlcIiBbY2xhc3Mubmd4LWZpZWxkLS1tYXNrZWRdPVwibWFza2VkXCI+XG4gICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCIgW2F0dHIuZm9yXT1cIidmaWVsZC0nICsgZmllbGQuaWRcIj57eyBsYWJlbCB9fTwvbGFiZWw+XG4gICAgICBAaWYgKG1hc2tlZCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWUgbmd4LWZpZWxkX192YWx1ZS0tbWFza2VkXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctbWFza2VkJ1wiPlhYWFhYWFhYWDwvc3Bhbj5cbiAgICAgIH0gQGVsc2UgaWYgKHJlYWRvbmx5KSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZVwiIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWQgKyAnLXZhbHVlJ1wiPnt7IGdldExhYmVsKGNvbnRyb2wudmFsdWUpIH19PC9zcGFuPlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIEBpZiAobG9hZGluZygpKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctbG9hZGluZydcIiByb2xlPVwic3RhdHVzXCI+TG9hZGluZ+KApjwvc3Bhbj5cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgY2xhc3M9XCJuZ3gtZmllbGRfX2lucHV0XCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctaW5wdXQnXCJcbiAgICAgICAgICAgIFtpZF09XCInZmllbGQtJyArIGZpZWxkLmlkXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCIkYW55KGNvbnRyb2wpXCJcbiAgICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cImZpZWxkLmRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj57eyBwbGFjZWhvbGRlciB8fCAnU2VsZWN0Li4uJyB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIG9wdGlvbnMoKTsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIEBpZiAoYXdhaXRpbmdQYXJlbnQoKSkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2hpbnRcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1oaW50J1wiPlNlbGVjdCB7eyBwYXJlbnRGaWVsZElkIH19IGZpcnN0Ljwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChjb250cm9sLmludmFsaWQgJiYgY29udHJvbC50b3VjaGVkKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctZXJyb3InXCI+VGhpcyBmaWVsZCBoYXMgYW4gZXJyb3I8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgRW50aXR5UmVmRmllbGRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBmaWVsZCE6IE5lc3RlZEZpZWxkQ29uZmlnO1xuICBASW5wdXQoKSBjb250cm9sITogQWJzdHJhY3RDb250cm9sO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWFza2VkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjYXNjYWRlID0gaW5qZWN0KENhc2NhZGVEYXRhU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2VsZWN0aW9uQnVzID0gaW5qZWN0KEVudGl0eVJlZlNlbGVjdGlvblNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgcmVhZG9ubHkgb3B0aW9ucyA9IHNpZ25hbDxSZWZlcmVuY2VPcHRpb25bXT4oW10pO1xuICByZWFkb25seSBsb2FkaW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgLyoqIFRydWUgd2hlbiB0aGlzIGZpZWxkIGNhc2NhZGVzIGJ1dCBpdHMgcGFyZW50IGhhcyBubyB2YWx1ZSB5ZXQuICovXG4gIHJlYWRvbmx5IGF3YWl0aW5nUGFyZW50ID0gc2lnbmFsKGZhbHNlKTtcblxuICBnZXQgbGFiZWwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVzb2x2ZUxhYmVsKHRoaXMuZmllbGQ/LmxhYmVsLCB0aGlzLmxhbmd1YWdlKTtcbiAgfVxuXG4gIGdldCBwbGFjZWhvbGRlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNvbHZlTGFiZWwodGhpcy5maWVsZD8ucGxhY2Vob2xkZXIsIHRoaXMubGFuZ3VhZ2UpO1xuICB9XG5cbiAgZ2V0IHBhcmVudEZpZWxkSWQoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5maWVsZD8uZW50aXR5UmVmZXJlbmNlPy5wYXJlbnRGaWVsZDtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1hc2tlZCkgcmV0dXJuO1xuICAgIHZvaWQgdGhpcy5yZWxvYWQoKTtcbiAgICB0aGlzLndhdGNoUGFyZW50KCk7XG4gICAgdGhpcy5jb250cm9sPy52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSh2YWx1ZSA9PiB0aGlzLnB1Ymxpc2hTZWxlY3Rpb24oU3RyaW5nKHZhbHVlID8/ICcnKSkpO1xuICB9XG5cbiAgLyoqIFJlbG9hZCBvcHRpb25zIGFnYWluc3QgdGhlIHBhcmVudCdzIGN1cnJlbnQgdmFsdWUuICovXG4gIGFzeW5jIHJlbG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwYXJlbnRWYWx1ZSA9IHRoaXMucGFyZW50VmFsdWUoKTtcbiAgICB0aGlzLmF3YWl0aW5nUGFyZW50LnNldChcbiAgICAgICEhdGhpcy5wYXJlbnRGaWVsZElkICYmIChwYXJlbnRWYWx1ZSA9PT0gbnVsbCB8fCBwYXJlbnRWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHBhcmVudFZhbHVlID09PSAnJyksXG4gICAgKTtcblxuICAgIGlmICghdGhpcy5jYXNjYWRlLmNhbkxvYWQodGhpcy5maWVsZCkpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5zZXQoW10pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMub3B0aW9ucy5zZXQoXG4gICAgICAgIGF3YWl0IHRoaXMuY2FzY2FkZS5sb2FkKHRoaXMuZmllbGQsIHsgcGFyZW50VmFsdWUsIGxhbmc6IHRoaXMubGFuZ3VhZ2UgfSksXG4gICAgICApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVibGlzaCB0aGUgc2VsZWN0ZWQgb3B0aW9uIHNvIGF1dG9QYXRjaCBjYW4gY29weSBmcm9tIGl0cyByZWNvcmQuXG4gICAqXG4gICAqIERyaXZlbiBmcm9tIGB2YWx1ZUNoYW5nZXNgIHJhdGhlciB0aGFuIHRoZSBzZWxlY3QncyBgY2hhbmdlYCBldmVudDogdGhhdCBldmVudCBpcyB0aGVcbiAgICogc2FtZSBvbmUgdGhlIGBmb3JtQ29udHJvbGAgZGlyZWN0aXZlIGxpc3RlbnMgdG8sIHNvIHJlYWRpbmcgdGhlIGNvbnRyb2wgaW5zaWRlIGFcbiAgICogdGVtcGxhdGUgYChjaGFuZ2UpYCBoYW5kbGVyIGNhbiBzZWUgdGhlIHByZXZpb3VzIHZhbHVlLiBgdmFsdWVDaGFuZ2VzYCBmaXJlcyBhZnRlciB0aGVcbiAgICogbW9kZWwgaGFzIHVwZGF0ZWQg4oCUIGluY2x1ZGluZyBQbGF5d3JpZ2h0IGBzZWxlY3RPcHRpb25gLCB3aGljaCB1cGRhdGVzIHRoZSBjb250cm9sXG4gICAqIHRocm91Z2ggdGhlIHZhbHVlIGFjY2Vzc29yLlxuICAgKi9cbiAgb25TZWxlY3Rpb25DaGFuZ2UodmFsdWU/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnB1Ymxpc2hTZWxlY3Rpb24odmFsdWUgPz8gU3RyaW5nKHRoaXMuY29udHJvbD8udmFsdWUgPz8gJycpKTtcbiAgfVxuXG4gIHByaXZhdGUgcHVibGlzaFNlbGVjdGlvbihjdXJyZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMub3B0aW9ucygpLmZpbmQobyA9PiBTdHJpbmcoby52YWx1ZSkgPT09IGN1cnJlbnQpO1xuICAgIHRoaXMuc2VsZWN0aW9uQnVzLmVtaXQodGhpcy5maWVsZC5pZCwgc2VsZWN0ZWQgPz8gbnVsbCk7XG4gIH1cblxuICBnZXRMYWJlbCh2YWx1ZTogYW55KTogc3RyaW5nIHtcbiAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnMoKS5maW5kKG8gPT4gU3RyaW5nKG8udmFsdWUpID09PSBTdHJpbmcodmFsdWUpKTtcbiAgICByZXR1cm4gb3B0aW9uPy5sYWJlbCA/PyAodmFsdWUgPz8gJ+KAlCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJlbnRWYWx1ZSgpOiB1bmtub3duIHtcbiAgICBjb25zdCBwYXJlbnRJZCA9IHRoaXMucGFyZW50RmllbGRJZDtcbiAgICBpZiAoIXBhcmVudElkKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiB0aGlzLmNvbnRyb2w/LnBhcmVudD8uZ2V0KHBhcmVudElkKT8udmFsdWU7XG4gIH1cblxuICAvKiogUmVsb2FkIChhbmQgZHJvcCBhIHN0YWxlIHNlbGVjdGlvbikgd2hlbmV2ZXIgdGhlIHBhcmVudCBjb250cm9sIGNoYW5nZXMuICovXG4gIHByaXZhdGUgd2F0Y2hQYXJlbnQoKTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50SWQgPSB0aGlzLnBhcmVudEZpZWxkSWQ7XG4gICAgaWYgKCFwYXJlbnRJZCkgcmV0dXJuO1xuICAgIGNvbnN0IHBhcmVudENvbnRyb2wgPSB0aGlzLmNvbnRyb2w/LnBhcmVudD8uZ2V0KHBhcmVudElkKTtcbiAgICBpZiAoIXBhcmVudENvbnRyb2wpIHJldHVybjtcblxuICAgIHBhcmVudENvbnRyb2wudmFsdWVDaGFuZ2VzXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5jb250cm9sLnZhbHVlKSB7XG4gICAgICAgICAgdGhpcy5jb250cm9sLnNldFZhbHVlKCcnLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgdGhpcy5zZWxlY3Rpb25CdXMuZW1pdCh0aGlzLmZpZWxkLmlkLCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgICB2b2lkIHRoaXMucmVsb2FkKCk7XG4gICAgICB9KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGQtY29tcG9uZW50LmNvbnRyYWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9maWVsZC10eXBlcy9maWVsZC1jb21wb25lbnQuY29udHJhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBOZXN0ZWRGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcblxuLyoqXG4gKiBXaGF0IGEgZmllbGQgY29tcG9uZW50IG11c3QgYWNjZXB0IHRvIGJlIHJlZ2lzdGVyZWQgd2l0aCBgcHJvdmlkZUZpZWxkVHlwZXNgLlxuICpcbiAqIFRoZSByZW5kZXJlciBpbnN0YW50aWF0ZXMgYSBmaWVsZCBjb21wb25lbnQgZHluYW1pY2FsbHkgYW5kIGFzc2lnbnMgZXhhY3RseSB0aGVzZSBmaXZlXG4gKiBpbnB1dHMg4oCUIG5vIG1vcmUsIG5vIGxlc3Mg4oCUIHNvIGFueSBjb21wb25lbnQgc2F0aXNmeWluZyB0aGlzIGludGVyZmFjZSBjYW4gc3RhbmQgaW4gZm9yIGFcbiAqIGJ1aWx0LWluIHR5cGUgb3IgYWRkIGEgbmV3IG9uZS5cbiAqXG4gKiBJbXBsZW1lbnQgaXQgZXhwbGljaXRseSBhbmQgVHlwZVNjcmlwdCB3aWxsIHRlbGwgeW91IHdoZW4geW91IGhhdmUgbWlzc2VkIG9uZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdhcHAtc2lnbmF0dXJlLWZpZWxkJyxcbiAqICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAqICAgdGVtcGxhdGU6IGA8Y2FudmFzIFthdHRyLmFyaWEtbGFiZWxdPVwiZmllbGQuaWRcIj48L2NhbnZhcz5gLFxuICogfSlcbiAqIGV4cG9ydCBjbGFzcyBTaWduYXR1cmVGaWVsZENvbXBvbmVudCBpbXBsZW1lbnRzIER5bmFtaWNGaWVsZENvbXBvbmVudENvbnRyYWN0IHtcbiAqICAgQElucHV0KCkgZmllbGQhOiBOZXN0ZWRGaWVsZENvbmZpZztcbiAqICAgQElucHV0KCkgY29udHJvbCE6IEFic3RyYWN0Q29udHJvbDtcbiAqICAgQElucHV0KCkgbGFuZ3VhZ2UgPSAnZW4nO1xuICogICBASW5wdXQoKSByZWFkb25seSA9IGZhbHNlO1xuICogICBASW5wdXQoKSBtYXNrZWQgPSBmYWxzZTtcbiAqIH1cbiAqXG4gKiBwcm92aWRlRmllbGRUeXBlcyh7IHNpZ25hdHVyZTogU2lnbmF0dXJlRmllbGRDb21wb25lbnQgfSk7XG4gKiBgYGBcbiAqXG4gKiBUd28gaW1wbGVtZW50YXRpb24gbm90ZXMgdGhhdCBhcmUgZWFzeSB0byBnZXQgd3Jvbmc6XG4gKlxuICogLSBEZWNsYXJlIHRoZSBpbnB1dHMgd2l0aCBkZWZpbml0ZSBhc3NpZ25tZW50IChgZmllbGQhOiDigKZgKSBvciBhbiBpbml0aWFsaXNlci4gVGhlXG4gKiAgIHJlbmRlcmVyIHNldHMgdGhlbSB0aHJvdWdoIGBDb21wb25lbnRSZWYuc2V0SW5wdXQoKWAgYWZ0ZXIgY29uc3RydWN0aW9uLCBzbyB0aGV5IGFyZVxuICogICBnZW51aW5lbHkgdW5kZWZpbmVkIHVudGlsIHRoZSBmaXJzdCBhc3NpZ25tZW50LlxuICogLSBgbWFza2VkYCBtZWFucyB0aGUgdmFsdWUgbXVzdCBub3QgYmUgZGlzcGxheWVkLiBSZW5kZXIgYSBwbGFjZWhvbGRlciByYXRoZXIgdGhhbiB0aGVcbiAqICAgY29udHJvbCdzIHZhbHVlLiBUaGlzIGlzIHByZXNlbnRhdGlvbmFsOiB0aGUgcmVhbCB2YWx1ZSBzdGF5cyBpbiB0aGUgY29udHJvbCBhbmQgaXNcbiAqICAgaW5jbHVkZWQgaW4gdGhlIHN1Ym1pdHRlZCByZWNvcmQsIHNvIGl0IGlzIG5vdCBhbiBhY2Nlc3MtY29udHJvbCBib3VuZGFyeS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljRmllbGRDb21wb25lbnRDb250cmFjdCB7XG4gIC8qKiBUaGUgZmllbGQncyBzY2hlbWEgZW50cnk6IGlkLCB0eXBlLCBsYWJlbCwgdmFsaWRhdG9ycywgb3B0aW9ucywgYW5kIHNvIG9uLiAqL1xuICBmaWVsZDogTmVzdGVkRmllbGRDb25maWc7XG5cbiAgLyoqIFRoZSByZWFjdGl2ZSBjb250cm9sIGJhY2tpbmcgdGhpcyBmaWVsZC4gQSBgRm9ybUdyb3VwYCBmb3IgYGdyb3VwYCwgYEZvcm1BcnJheWAgZm9yIGBhcnJheWAuICovXG4gIGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbDtcblxuICAvKiogQWN0aXZlIGxhbmd1YWdlLCBmb3IgcmVzb2x2aW5nIGBMb2NhbGl6ZWRUZXh0YCBsYWJlbHMsIHBsYWNlaG9sZGVycyBhbmQgb3B0aW9ucy4gKi9cbiAgbGFuZ3VhZ2U6IHN0cmluZztcblxuICAvKiogUmVuZGVyIHRoZSB2YWx1ZSBhcyB0ZXh0IHJhdGhlciB0aGFuIGFuIGVkaXRhYmxlIGNvbnRyb2wuICovXG4gIHJlYWRvbmx5OiBib29sZWFuO1xuXG4gIC8qKiBIaWRlIHRoZSB2YWx1ZSBmcm9tIGRpc3BsYXkuIFNlZSB0aGUgbm90ZSBhYm92ZSDigJQgcHJlc2VudGF0aW9uYWwgb25seS4gKi9cbiAgbWFza2VkOiBib29sZWFuO1xufVxuIl19
@@ -1,4 +1,4 @@
1
- import { Component, inject, Input, signal } from '@angular/core';
1
+ import { Component, inject, Input, signal, ChangeDetectionStrategy } from '@angular/core';
2
2
  import { fileRefName, resolveLabel } from '@dynamic-entity/core';
3
3
  import { FileUploadService } from '../services/file-upload.service';
4
4
  import * as i0 from "@angular/core";
@@ -48,98 +48,99 @@ export class FileFieldComponent {
48
48
  this.control.markAsTouched();
49
49
  }
50
50
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
51
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: FileFieldComponent, isStandalone: true, selector: "ngx-file-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
52
- <div class="ngx-field ngx-field--file"
53
- [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
54
- <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
55
- @if (masked) {
56
- <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
57
- } @else if (readonly) {
58
- @if (fileUrl()) {
59
- <a class="ngx-field__file-link" [href]="fileUrl()!" target="_blank" rel="noopener">
60
- 📎 {{ fileName() || 'Download file' }}
61
- </a>
62
- } @else {
63
- <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">—</span>
64
- }
65
- } @else {
66
- <div class="ngx-field__file-wrap">
67
- @if (fileName()) {
68
- <div class="ngx-field__file-selected">
69
- <span class="ngx-field__file-name">📎 {{ fileName() }}</span>
70
- <button type="button" class="ngx-field__remove-btn" (click)="remove()" aria-label="Remove file">✕</button>
71
- </div>
72
- }
73
- <label class="ngx-field__upload-btn" [class.ngx-field__upload-btn--loading]="uploading()">
74
- @if (uploading()) {
75
- <span>Uploading…</span>
76
- } @else {
77
- <span>{{ fileName() ? 'Replace file' : 'Choose file' }}</span>
78
- <input
79
- type="file"
80
- class="ngx-field__file-input"
81
- [id]="'field-' + field.id"
82
- [disabled]="field.disabled || uploading()"
83
- (change)="onFileSelect($any($event.target).files[0])"
84
- />
85
- }
86
- </label>
87
- </div>
88
- @if (uploadError()) {
89
- <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">{{ uploadError() }}</span>
90
- }
91
- }
92
- </div>
93
- `, isInline: true });
51
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: FileFieldComponent, isStandalone: true, selector: "ngx-file-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
52
+ <div class="ngx-field ngx-field--file"
53
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
54
+ <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
55
+ @if (masked) {
56
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
57
+ } @else if (readonly) {
58
+ @if (fileUrl()) {
59
+ <a class="ngx-field__file-link" [href]="fileUrl()!" target="_blank" rel="noopener">
60
+ 📎 {{ fileName() || 'Download file' }}
61
+ </a>
62
+ } @else {
63
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">—</span>
64
+ }
65
+ } @else {
66
+ <div class="ngx-field__file-wrap">
67
+ @if (fileName()) {
68
+ <div class="ngx-field__file-selected">
69
+ <span class="ngx-field__file-name">📎 {{ fileName() }}</span>
70
+ <button type="button" class="ngx-field__remove-btn" (click)="remove()" aria-label="Remove file">✕</button>
71
+ </div>
72
+ }
73
+ <label class="ngx-field__upload-btn" [class.ngx-field__upload-btn--loading]="uploading()">
74
+ @if (uploading()) {
75
+ <span>Uploading…</span>
76
+ } @else {
77
+ <span>{{ fileName() ? 'Replace file' : 'Choose file' }}</span>
78
+ <input
79
+ type="file"
80
+ class="ngx-field__file-input"
81
+ [id]="'field-' + field.id"
82
+ [disabled]="field.disabled || uploading()"
83
+ (change)="onFileSelect($any($event.target).files[0])"
84
+ />
85
+ }
86
+ </label>
87
+ </div>
88
+ @if (uploadError()) {
89
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">{{ uploadError() }}</span>
90
+ }
91
+ }
92
+ </div>
93
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
94
94
  }
95
95
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileFieldComponent, decorators: [{
96
96
  type: Component,
97
97
  args: [{
98
+ changeDetection: ChangeDetectionStrategy.OnPush,
98
99
  selector: 'ngx-file-field',
99
100
  standalone: true,
100
101
  imports: [],
101
- template: `
102
- <div class="ngx-field ngx-field--file"
103
- [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
104
- <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
105
- @if (masked) {
106
- <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
107
- } @else if (readonly) {
108
- @if (fileUrl()) {
109
- <a class="ngx-field__file-link" [href]="fileUrl()!" target="_blank" rel="noopener">
110
- 📎 {{ fileName() || 'Download file' }}
111
- </a>
112
- } @else {
113
- <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">—</span>
114
- }
115
- } @else {
116
- <div class="ngx-field__file-wrap">
117
- @if (fileName()) {
118
- <div class="ngx-field__file-selected">
119
- <span class="ngx-field__file-name">📎 {{ fileName() }}</span>
120
- <button type="button" class="ngx-field__remove-btn" (click)="remove()" aria-label="Remove file">✕</button>
121
- </div>
122
- }
123
- <label class="ngx-field__upload-btn" [class.ngx-field__upload-btn--loading]="uploading()">
124
- @if (uploading()) {
125
- <span>Uploading…</span>
126
- } @else {
127
- <span>{{ fileName() ? 'Replace file' : 'Choose file' }}</span>
128
- <input
129
- type="file"
130
- class="ngx-field__file-input"
131
- [id]="'field-' + field.id"
132
- [disabled]="field.disabled || uploading()"
133
- (change)="onFileSelect($any($event.target).files[0])"
134
- />
135
- }
136
- </label>
137
- </div>
138
- @if (uploadError()) {
139
- <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">{{ uploadError() }}</span>
140
- }
141
- }
142
- </div>
102
+ template: `
103
+ <div class="ngx-field ngx-field--file"
104
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
105
+ <label class="ngx-field__label" [attr.for]="'field-' + field.id">{{ label }}</label>
106
+ @if (masked) {
107
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
108
+ } @else if (readonly) {
109
+ @if (fileUrl()) {
110
+ <a class="ngx-field__file-link" [href]="fileUrl()!" target="_blank" rel="noopener">
111
+ 📎 {{ fileName() || 'Download file' }}
112
+ </a>
113
+ } @else {
114
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">—</span>
115
+ }
116
+ } @else {
117
+ <div class="ngx-field__file-wrap">
118
+ @if (fileName()) {
119
+ <div class="ngx-field__file-selected">
120
+ <span class="ngx-field__file-name">📎 {{ fileName() }}</span>
121
+ <button type="button" class="ngx-field__remove-btn" (click)="remove()" aria-label="Remove file">✕</button>
122
+ </div>
123
+ }
124
+ <label class="ngx-field__upload-btn" [class.ngx-field__upload-btn--loading]="uploading()">
125
+ @if (uploading()) {
126
+ <span>Uploading…</span>
127
+ } @else {
128
+ <span>{{ fileName() ? 'Replace file' : 'Choose file' }}</span>
129
+ <input
130
+ type="file"
131
+ class="ngx-field__file-input"
132
+ [id]="'field-' + field.id"
133
+ [disabled]="field.disabled || uploading()"
134
+ (change)="onFileSelect($any($event.target).files[0])"
135
+ />
136
+ }
137
+ </label>
138
+ </div>
139
+ @if (uploadError()) {
140
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">{{ uploadError() }}</span>
141
+ }
142
+ }
143
+ </div>
143
144
  `,
144
145
  }]
145
146
  }], propDecorators: { field: [{
@@ -153,4 +154,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
153
154
  }], masked: [{
154
155
  type: Input
155
156
  }] } });
156
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL2ZpbGUtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7QUFFcEU7OztHQUdHO0FBaURILE1BQU0sT0FBTyxrQkFBa0I7SUFDcEIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQW1CO0lBQzFCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixNQUFNLEdBQVksS0FBSyxDQUFDO0lBRWhCLE9BQU8sR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUU1QyxTQUFTLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLFdBQVcsR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO0lBRW5ELElBQUksS0FBSztRQUNQLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsSUFBWSxLQUFLO1FBQ2YsT0FBUSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQXdCLElBQUksSUFBSSxDQUFDO0lBQ3pELENBQUM7SUFFRCxPQUFPO1FBQ0wsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxJQUFJLENBQUM7SUFDakMsQ0FBQztJQUVELFFBQVE7UUFDTixPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDO0lBQ3pDLENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUFDLElBQXNCO1FBQ3ZDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMvQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUMzRCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQy9CLENBQUM7d0dBN0NVLGtCQUFrQjs0RkFBbEIsa0JBQWtCLHdMQTVDbkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBDVDs7NEZBRVUsa0JBQWtCO2tCQWhEOUIsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsZ0JBQWdCO29CQUMxQixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQ1Q7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBpbmplY3QsIElucHV0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgdHlwZSB7IEZpbGVSZWYsIE5lc3RlZEZpZWxkQ29uZmlnIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xyXG5pbXBvcnQgeyBmaWxlUmVmTmFtZSwgcmVzb2x2ZUxhYmVsIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xyXG5pbXBvcnQgeyBGaWxlVXBsb2FkU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2ZpbGUtdXBsb2FkLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIEZpbGUgZmllbGQ6IGZpbGUgaW5wdXQgd2l0aCBmaWxlbmFtZSBkaXNwbGF5IGFuZCBkb3dubG9hZCBsaW5rLlxyXG4gKiBTaGFyZXMgdGhlIGBGaWxlUmVmYCAvIGBVUExPQURfSEFORExFUmAgY29udHJhY3Qgd2l0aCBpbWFnZS1maWVsZCB2aWEgRmlsZVVwbG9hZFNlcnZpY2UuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25neC1maWxlLWZpZWxkJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtdLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8ZGl2IGNsYXNzPVwibmd4LWZpZWxkIG5neC1maWVsZC0tZmlsZVwiXHJcbiAgICAgIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWRcIiBbYXR0ci5kYXRhLWZpZWxkLXR5cGVdPVwiZmllbGQudHlwZVwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxyXG4gICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCIgW2F0dHIuZm9yXT1cIidmaWVsZC0nICsgZmllbGQuaWRcIj57eyBsYWJlbCB9fTwvbGFiZWw+XHJcbiAgICAgIEBpZiAobWFza2VkKSB7XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlIG5neC1maWVsZF9fdmFsdWUtLW1hc2tlZFwiIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWQgKyAnLW1hc2tlZCdcIj5YWFhYWFhYWFg8L3NwYW4+XHJcbiAgICAgIH0gQGVsc2UgaWYgKHJlYWRvbmx5KSB7XHJcbiAgICAgICAgQGlmIChmaWxlVXJsKCkpIHtcclxuICAgICAgICAgIDxhIGNsYXNzPVwibmd4LWZpZWxkX19maWxlLWxpbmtcIiBbaHJlZl09XCJmaWxlVXJsKCkhXCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXJcIj5cclxuICAgICAgICAgICAg8J+TjiB7eyBmaWxlTmFtZSgpIHx8ICdEb3dubG9hZCBmaWxlJyB9fVxyXG4gICAgICAgICAgPC9hPlxyXG4gICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctdmFsdWUnXCI+4oCUPC9zcGFuPlxyXG4gICAgICAgIH1cclxuICAgICAgfSBAZWxzZSB7XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cIm5neC1maWVsZF9fZmlsZS13cmFwXCI+XHJcbiAgICAgICAgICBAaWYgKGZpbGVOYW1lKCkpIHtcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5neC1maWVsZF9fZmlsZS1zZWxlY3RlZFwiPlxyXG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX19maWxlLW5hbWVcIj7wn5OOIHt7IGZpbGVOYW1lKCkgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJuZ3gtZmllbGRfX3JlbW92ZS1idG5cIiAoY2xpY2spPVwicmVtb3ZlKClcIiBhcmlhLWxhYmVsPVwiUmVtb3ZlIGZpbGVcIj7inJU8L2J1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX3VwbG9hZC1idG5cIiBbY2xhc3Mubmd4LWZpZWxkX191cGxvYWQtYnRuLS1sb2FkaW5nXT1cInVwbG9hZGluZygpXCI+XHJcbiAgICAgICAgICAgIEBpZiAodXBsb2FkaW5nKCkpIHtcclxuICAgICAgICAgICAgICA8c3Bhbj5VcGxvYWRpbmfigKY8L3NwYW4+XHJcbiAgICAgICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgICAgIDxzcGFuPnt7IGZpbGVOYW1lKCkgPyAnUmVwbGFjZSBmaWxlJyA6ICdDaG9vc2UgZmlsZScgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICB0eXBlPVwiZmlsZVwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9fZmlsZS1pbnB1dFwiXHJcbiAgICAgICAgICAgICAgICBbaWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZFwiXHJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZmllbGQuZGlzYWJsZWQgfHwgdXBsb2FkaW5nKClcIlxyXG4gICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkZpbGVTZWxlY3QoJGFueSgkZXZlbnQudGFyZ2V0KS5maWxlc1swXSlcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgQGlmICh1cGxvYWRFcnJvcigpKSB7XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fZXJyb3JcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1lcnJvcidcIj57eyB1cGxvYWRFcnJvcigpIH19PC9zcGFuPlxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgPC9kaXY+XHJcbiAgYCxcclxufSlcclxuZXhwb3J0IGNsYXNzIEZpbGVGaWVsZENvbXBvbmVudCB7XHJcbiAgQElucHV0KCkgZmllbGQhOiBOZXN0ZWRGaWVsZENvbmZpZztcclxuICBASW5wdXQoKSBjb250cm9sITogQWJzdHJhY3RDb250cm9sO1xyXG4gIEBJbnB1dCgpIGxhbmd1YWdlOiBzdHJpbmcgPSAnZW4nO1xyXG4gIEBJbnB1dCgpIHJlYWRvbmx5OiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgbWFza2VkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBsb2FkcyA9IGluamVjdChGaWxlVXBsb2FkU2VydmljZSk7XHJcblxyXG4gIHJlYWRvbmx5IHVwbG9hZGluZyA9IHNpZ25hbChmYWxzZSk7XHJcbiAgcmVhZG9ubHkgdXBsb2FkRXJyb3IgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XHJcblxyXG4gIGdldCBsYWJlbCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHJlc29sdmVMYWJlbCh0aGlzLmZpZWxkPy5sYWJlbCwgdGhpcy5sYW5ndWFnZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldCB2YWx1ZSgpOiBGaWxlUmVmIHwgbnVsbCB7XHJcbiAgICByZXR1cm4gKHRoaXMuY29udHJvbD8udmFsdWUgYXMgRmlsZVJlZiB8IG51bGwpID8/IG51bGw7XHJcbiAgfVxyXG5cclxuICBmaWxlVXJsKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgcmV0dXJuIHRoaXMudmFsdWU/LnVybCA/PyBudWxsO1xyXG4gIH1cclxuXHJcbiAgZmlsZU5hbWUoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICByZXR1cm4gZmlsZVJlZk5hbWUodGhpcy52YWx1ZSkgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGFzeW5jIG9uRmlsZVNlbGVjdChmaWxlOiBGaWxlIHwgdW5kZWZpbmVkKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIWZpbGUpIHJldHVybjtcclxuICAgIHRoaXMudXBsb2FkRXJyb3Iuc2V0KG51bGwpO1xyXG4gICAgdGhpcy51cGxvYWRpbmcuc2V0KHRydWUpO1xyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy5jb250cm9sLnNldFZhbHVlKGF3YWl0IHRoaXMudXBsb2Fkcy50b0ZpbGVSZWYoZmlsZSkpO1xyXG4gICAgICB0aGlzLmNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xyXG4gICAgfSBjYXRjaCB7XHJcbiAgICAgIHRoaXMudXBsb2FkRXJyb3Iuc2V0KCdVcGxvYWQgZmFpbGVkLiBQbGVhc2UgdHJ5IGFnYWluLicpO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgdGhpcy51cGxvYWRpbmcuc2V0KGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJlbW92ZSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY29udHJvbC5zZXRWYWx1ZShudWxsKTtcclxuICAgIHRoaXMuY29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
157
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL2ZpbGUtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHMUYsT0FBTyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7QUFFcEU7OztHQUdHO0FBa0RILE1BQU0sT0FBTyxrQkFBa0I7SUFDcEIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQW1CO0lBQzFCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixNQUFNLEdBQVksS0FBSyxDQUFDO0lBRWhCLE9BQU8sR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUU1QyxTQUFTLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLFdBQVcsR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO0lBRW5ELElBQUksS0FBSztRQUNQLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsSUFBWSxLQUFLO1FBQ2YsT0FBUSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQXdCLElBQUksSUFBSSxDQUFDO0lBQ3pELENBQUM7SUFFRCxPQUFPO1FBQ0wsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxJQUFJLENBQUM7SUFDakMsQ0FBQztJQUVELFFBQVE7UUFDTixPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDO0lBQ3pDLENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUFDLElBQXNCO1FBQ3ZDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMvQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUMzRCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQy9CLENBQUM7d0dBN0NVLGtCQUFrQjs0RkFBbEIsa0JBQWtCLHdMQTVDbkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBDVDs7NEZBRVUsa0JBQWtCO2tCQWpEOUIsU0FBUzttQkFBQztvQkFDVCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsUUFBUSxFQUFFLGdCQUFnQjtvQkFDMUIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRSxFQUFFO29CQUNYLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMENUO2lCQUNGOzhCQUVVLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5qZWN0LCBJbnB1dCwgc2lnbmFsLCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBGaWxlUmVmLCBOZXN0ZWRGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcbmltcG9ydCB7IGZpbGVSZWZOYW1lLCByZXNvbHZlTGFiZWwgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XG5pbXBvcnQgeyBGaWxlVXBsb2FkU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2ZpbGUtdXBsb2FkLnNlcnZpY2UnO1xuXG4vKipcbiAqIEZpbGUgZmllbGQ6IGZpbGUgaW5wdXQgd2l0aCBmaWxlbmFtZSBkaXNwbGF5IGFuZCBkb3dubG9hZCBsaW5rLlxuICogU2hhcmVzIHRoZSBgRmlsZVJlZmAgLyBgVVBMT0FEX0hBTkRMRVJgIGNvbnRyYWN0IHdpdGggaW1hZ2UtZmllbGQgdmlhIEZpbGVVcGxvYWRTZXJ2aWNlLlxuICovXG5AQ29tcG9uZW50KHtcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHNlbGVjdG9yOiAnbmd4LWZpbGUtZmllbGQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwibmd4LWZpZWxkIG5neC1maWVsZC0tZmlsZVwiXG4gICAgICBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkXCIgW2F0dHIuZGF0YS1maWVsZC10eXBlXT1cImZpZWxkLnR5cGVcIiBbY2xhc3Mubmd4LWZpZWxkLS1yZWFkb25seV09XCJyZWFkb25seVwiIFtjbGFzcy5uZ3gtZmllbGQtLW1hc2tlZF09XCJtYXNrZWRcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cIm5neC1maWVsZF9fbGFiZWxcIiBbYXR0ci5mb3JdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZFwiPnt7IGxhYmVsIH19PC9sYWJlbD5cbiAgICAgIEBpZiAobWFza2VkKSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZSBuZ3gtZmllbGRfX3ZhbHVlLS1tYXNrZWRcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1tYXNrZWQnXCI+WFhYWFhYWFhYPC9zcGFuPlxuICAgICAgfSBAZWxzZSBpZiAocmVhZG9ubHkpIHtcbiAgICAgICAgQGlmIChmaWxlVXJsKCkpIHtcbiAgICAgICAgICA8YSBjbGFzcz1cIm5neC1maWVsZF9fZmlsZS1saW5rXCIgW2hyZWZdPVwiZmlsZVVybCgpIVwiIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyXCI+XG4gICAgICAgICAgICDwn5OOIHt7IGZpbGVOYW1lKCkgfHwgJ0Rvd25sb2FkIGZpbGUnIH19XG4gICAgICAgICAgPC9hPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWVcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy12YWx1ZSdcIj7igJQ8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8ZGl2IGNsYXNzPVwibmd4LWZpZWxkX19maWxlLXdyYXBcIj5cbiAgICAgICAgICBAaWYgKGZpbGVOYW1lKCkpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJuZ3gtZmllbGRfX2ZpbGUtc2VsZWN0ZWRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2ZpbGUtbmFtZVwiPvCfk44ge3sgZmlsZU5hbWUoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJuZ3gtZmllbGRfX3JlbW92ZS1idG5cIiAoY2xpY2spPVwicmVtb3ZlKClcIiBhcmlhLWxhYmVsPVwiUmVtb3ZlIGZpbGVcIj7inJU8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX3VwbG9hZC1idG5cIiBbY2xhc3Mubmd4LWZpZWxkX191cGxvYWQtYnRuLS1sb2FkaW5nXT1cInVwbG9hZGluZygpXCI+XG4gICAgICAgICAgICBAaWYgKHVwbG9hZGluZygpKSB7XG4gICAgICAgICAgICAgIDxzcGFuPlVwbG9hZGluZ+KApjwvc3Bhbj5cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICA8c3Bhbj57eyBmaWxlTmFtZSgpID8gJ1JlcGxhY2UgZmlsZScgOiAnQ2hvb3NlIGZpbGUnIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICB0eXBlPVwiZmlsZVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJuZ3gtZmllbGRfX2ZpbGUtaW5wdXRcIlxuICAgICAgICAgICAgICAgIFtpZF09XCInZmllbGQtJyArIGZpZWxkLmlkXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZmllbGQuZGlzYWJsZWQgfHwgdXBsb2FkaW5nKClcIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25GaWxlU2VsZWN0KCRhbnkoJGV2ZW50LnRhcmdldCkuZmlsZXNbMF0pXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgQGlmICh1cGxvYWRFcnJvcigpKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctZXJyb3InXCI+e3sgdXBsb2FkRXJyb3IoKSB9fTwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBGaWxlRmllbGRDb21wb25lbnQge1xuICBASW5wdXQoKSBmaWVsZCE6IE5lc3RlZEZpZWxkQ29uZmlnO1xuICBASW5wdXQoKSBjb250cm9sITogQWJzdHJhY3RDb250cm9sO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWFza2VkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB1cGxvYWRzID0gaW5qZWN0KEZpbGVVcGxvYWRTZXJ2aWNlKTtcblxuICByZWFkb25seSB1cGxvYWRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSB1cGxvYWRFcnJvciA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICBnZXQgbGFiZWwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVzb2x2ZUxhYmVsKHRoaXMuZmllbGQ/LmxhYmVsLCB0aGlzLmxhbmd1YWdlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHZhbHVlKCk6IEZpbGVSZWYgfCBudWxsIHtcbiAgICByZXR1cm4gKHRoaXMuY29udHJvbD8udmFsdWUgYXMgRmlsZVJlZiB8IG51bGwpID8/IG51bGw7XG4gIH1cblxuICBmaWxlVXJsKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnZhbHVlPy51cmwgPz8gbnVsbDtcbiAgfVxuXG4gIGZpbGVOYW1lKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiBmaWxlUmVmTmFtZSh0aGlzLnZhbHVlKSB8fCBudWxsO1xuICB9XG5cbiAgYXN5bmMgb25GaWxlU2VsZWN0KGZpbGU6IEZpbGUgfCB1bmRlZmluZWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWZpbGUpIHJldHVybjtcbiAgICB0aGlzLnVwbG9hZEVycm9yLnNldChudWxsKTtcbiAgICB0aGlzLnVwbG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY29udHJvbC5zZXRWYWx1ZShhd2FpdCB0aGlzLnVwbG9hZHMudG9GaWxlUmVmKGZpbGUpKTtcbiAgICAgIHRoaXMuY29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0aGlzLnVwbG9hZEVycm9yLnNldCgnVXBsb2FkIGZhaWxlZC4gUGxlYXNlIHRyeSBhZ2Fpbi4nKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy51cGxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICByZW1vdmUoKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9sLnNldFZhbHVlKG51bGwpO1xuICAgIHRoaXMuY29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gIH1cbn1cbiJdfQ==