@muraai/mnl-form 0.0.1-alpha-db495b1 → 0.0.1-alpha-6116399

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 (61) hide show
  1. package/fesm2022/muraai-mnl-form.mjs +150 -143
  2. package/fesm2022/muraai-mnl-form.mjs.map +1 -1
  3. package/lib/types/upload-file.d.ts +1 -1
  4. package/lib/workflow-status/ workflow-status.module.d.ts +8 -8
  5. package/lib/workflow-status/workflow-status.component.d.ts +1 -1
  6. package/package.json +4 -5
  7. package/esm2022/lib/confirmation-dialog/confirmation-dialog.component.mjs +0 -34
  8. package/esm2022/lib/mnl-form/mnl-form-standalone.module.mjs +0 -155
  9. package/esm2022/lib/mnl-form/mnl-form.component.mjs +0 -199
  10. package/esm2022/lib/models/custom-form-field.model.mjs +0 -2
  11. package/esm2022/lib/models/workflow-status.model.mjs +0 -2
  12. package/esm2022/lib/services/graphql.service.mjs +0 -30
  13. package/esm2022/lib/services/scoring.service.mjs +0 -103
  14. package/esm2022/lib/types/action-button-renderer.component.mjs +0 -59
  15. package/esm2022/lib/types/autocomplete-type.component.mjs +0 -68
  16. package/esm2022/lib/types/button.type.mjs +0 -72
  17. package/esm2022/lib/types/comments.type.mjs +0 -102
  18. package/esm2022/lib/types/country-code-input.type.mjs +0 -181
  19. package/esm2022/lib/types/custom-date.type.mjs +0 -20
  20. package/esm2022/lib/types/custom-input.component.mjs +0 -62
  21. package/esm2022/lib/types/date-format.type.mjs +0 -196
  22. package/esm2022/lib/types/expansion-panel.types.mjs +0 -85
  23. package/esm2022/lib/types/formly-field-panel.type.mjs +0 -70
  24. package/esm2022/lib/types/grid-actionable.type.mjs +0 -197
  25. package/esm2022/lib/types/grid-formly-cell.component.mjs +0 -42
  26. package/esm2022/lib/types/grid.type.mjs +0 -125
  27. package/esm2022/lib/types/input.type.mjs +0 -43
  28. package/esm2022/lib/types/mu-helper-text.type.mjs +0 -331
  29. package/esm2022/lib/types/multi-select-autocomplete.mjs +0 -139
  30. package/esm2022/lib/types/multi-select-checkbox.component.mjs +0 -247
  31. package/esm2022/lib/types/radio.type.mjs +0 -71
  32. package/esm2022/lib/types/scrollable-tabs.types.mjs +0 -220
  33. package/esm2022/lib/types/select-api-auto-complete.component.mjs +0 -111
  34. package/esm2022/lib/types/select-autocomplete-redefined.component.mjs +0 -142
  35. package/esm2022/lib/types/select-autocomplete.type.mjs +0 -254
  36. package/esm2022/lib/types/stepper.type.mjs +0 -268
  37. package/esm2022/lib/types/table.types.mjs +0 -79
  38. package/esm2022/lib/types/tabs.types.mjs +0 -293
  39. package/esm2022/lib/types/tabular-form-dialog.component.mjs +0 -331
  40. package/esm2022/lib/types/tabular-form.type.mjs +0 -641
  41. package/esm2022/lib/types/upload-file.mjs +0 -524
  42. package/esm2022/lib/types/view-file-dialog.component.mjs +0 -90
  43. package/esm2022/lib/utils/formly.utils.mjs +0 -105
  44. package/esm2022/lib/validators/custom-email-validator.mjs +0 -18
  45. package/esm2022/lib/validators/ein-validators.mjs +0 -11
  46. package/esm2022/lib/validators/gst-validator.mjs +0 -11
  47. package/esm2022/lib/validators/normal-email-validator.mjs +0 -17
  48. package/esm2022/lib/validators/npi-validator.mjs +0 -11
  49. package/esm2022/lib/validators/pan-validator.mjs +0 -11
  50. package/esm2022/lib/validators/phone-number-validator.mjs +0 -22
  51. package/esm2022/lib/validators/select-validator.mjs +0 -7
  52. package/esm2022/lib/validators/tinSsn-validator.mjs +0 -12
  53. package/esm2022/lib/workflow-status/ workflow-status.module.mjs +0 -52
  54. package/esm2022/lib/workflow-status/workflow-status.component.mjs +0 -70
  55. package/esm2022/lib/wrappers/form-field-description-wrapper.component.mjs +0 -44
  56. package/esm2022/lib/wrappers/form-field-wrapper.component.mjs +0 -34
  57. package/esm2022/lib/wrappers/formly-wrapper-with-old-value.component.mjs +0 -140
  58. package/esm2022/lib/wrappers/prefix-suffix-wrapper.component.mjs +0 -95
  59. package/esm2022/lib/wrappers/prefix-sufix-extension.component.mjs +0 -9
  60. package/esm2022/muraai-mnl-form.mjs +0 -5
  61. package/esm2022/public-api.mjs +0 -12
@@ -1,331 +0,0 @@
1
- import { TextFieldModule } from '@angular/cdk/text-field';
2
- import { CommonModule } from '@angular/common';
3
- import { Component, ViewChild } from '@angular/core';
4
- import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
5
- import { MatNativeDateModule } from '@angular/material/core';
6
- import { MatDatepickerModule } from '@angular/material/datepicker';
7
- import { MatFormFieldModule } from '@angular/material/form-field';
8
- import { MatInputModule } from '@angular/material/input';
9
- import { MatSelectModule } from '@angular/material/select';
10
- import { MatSlideToggleModule } from '@angular/material/slide-toggle';
11
- import { FormlyModule, } from '@ngx-formly/core';
12
- import { FieldType } from '@ngx-formly/material';
13
- import * as i0 from "@angular/core";
14
- import * as i1 from "@angular/common";
15
- import * as i2 from "@angular/material/input";
16
- import * as i3 from "@angular/material/form-field";
17
- import * as i4 from "@angular/cdk/text-field";
18
- import * as i5 from "@ngx-formly/core";
19
- import * as i6 from "@angular/forms";
20
- import * as i7 from "@angular/material/slide-toggle";
21
- export class MnlFormHelperTextInputComponent extends FieldType {
22
- get helperLabel() {
23
- return this.to['helperProps']?.['helperLabel'] || 'Need help?';
24
- }
25
- get defaultHelperText() {
26
- return this.to['helperProps']?.['defaultHelperText'] || '';
27
- }
28
- // Get value from primary model (answers)
29
- get originalValue() {
30
- const fieldKey = this.field.key;
31
- return this.field.model?.[fieldKey];
32
- }
33
- // Get/Set value from secondary model (helper)
34
- get helperModel() {
35
- return (this.to['helperModel'] ||
36
- this.props['helperModel'] ||
37
- this.options?.formState?.['helperModel']);
38
- }
39
- get helperKey() {
40
- return this.to['helperKey'] || this.field.key;
41
- }
42
- get currentHelperValue() {
43
- if (this.helperModel && this.helperKey) {
44
- return this.helperModel[this.helperKey];
45
- }
46
- return '';
47
- }
48
- set currentHelperValue(value) {
49
- if (this.helperModel && this.helperKey) {
50
- this.helperModel[this.helperKey] = value;
51
- }
52
- }
53
- get readonly() {
54
- return this.to['readonly'] || this.props['readonly'] || false;
55
- }
56
- constructor(cdr) {
57
- super();
58
- this.cdr = cdr;
59
- this.checked = false;
60
- }
61
- ngOnInit() {
62
- // Initialize helper form control with value from helper model
63
- this.helperFormControl = new FormControl(this.currentHelperValue || '');
64
- // Subscribe to changes in helper form control and update helper model
65
- this.helperFormControl.valueChanges.subscribe((value) => {
66
- this.currentHelperValue = value;
67
- // Emit helper model change to parent component
68
- this.options?.formState?.['onHelperModelChange']?.(this.helperModel);
69
- });
70
- this.setupDefaultField();
71
- if (this.to['enableHelper']) {
72
- this.setCorrectValue();
73
- this.determineInitialState();
74
- }
75
- if (this.currentHelperValue && this.currentHelperValue.trim() !== '') {
76
- this.checked = true;
77
- }
78
- }
79
- ngAfterViewInit() {
80
- setTimeout(() => {
81
- this.cdr.detectChanges();
82
- this.autosize?.resizeToFitContent(true);
83
- });
84
- }
85
- resizeTextarea() {
86
- if (this.autosize) {
87
- this.cdr.detectChanges();
88
- setTimeout(() => this.autosize?.resizeToFitContent(true), 50);
89
- }
90
- }
91
- toggleSlide() {
92
- this.checked = !this.checked;
93
- if (this.checked) {
94
- // When toggle is opened, check if helper field is empty
95
- const currenthelper = this.helperFormControl.value;
96
- if (!currenthelper || currenthelper.trim() === '') {
97
- this.helperFormControl.setValue(this.defaultHelperText);
98
- }
99
- }
100
- else {
101
- this.helperFormControl.setValue('');
102
- }
103
- this.cdr.detectChanges();
104
- }
105
- setupDefaultField() {
106
- const fieldConfig = this.to['defaultFieldConfig'];
107
- if (fieldConfig) {
108
- // Get current value from model and sync with formControl
109
- const fieldKey = this.field.key;
110
- const modelValue = this.field.model?.[fieldKey];
111
- // Sync formControl value with model value if it exists
112
- if (modelValue !== undefined && modelValue !== null) {
113
- this.formControl.setValue(modelValue, { emitEvent: false });
114
- }
115
- // Create enhanced props with necessary fixes for production
116
- const enhancedProps = {
117
- ...fieldConfig.props,
118
- };
119
- // For select fields, add compareWith function to ensure proper value matching in production builds
120
- if (fieldConfig.type === 'select' && !enhancedProps['compareWith']) {
121
- enhancedProps['compareWith'] = (o1, o2) => o1 === o2;
122
- }
123
- this.defaultFieldConfig = {
124
- type: fieldConfig.type,
125
- key: this.field.key || fieldConfig.key || 'defaultKey',
126
- formControl: this.formControl,
127
- props: enhancedProps,
128
- wrappers: fieldConfig.wrappers || [],
129
- modelOptions: fieldConfig.modelOptions || this.field.modelOptions || {},
130
- validators: fieldConfig.validators || this.field.validators || {},
131
- asyncValidators: fieldConfig.asyncValidators || this.field.asyncValidators || {},
132
- hooks: fieldConfig.hooks || this.field.hooks || {},
133
- expressions: fieldConfig.expressions || this.field.expressions || {},
134
- hide: fieldConfig.hide !== undefined ? fieldConfig.hide : false,
135
- className: fieldConfig.className || this.field.className || '',
136
- fieldGroupClassName: fieldConfig.fieldGroupClassName ||
137
- this.field.fieldGroupClassName ||
138
- '',
139
- parent: this.field.parent,
140
- options: this.field.options,
141
- model: this.field.model,
142
- form: this.field.form,
143
- };
144
- }
145
- }
146
- determineInitialState() {
147
- // Auto-open helper based on scoring criteria
148
- switch (this.to['scoring']?.['criteria']) {
149
- case 'exactMatch':
150
- if (Array.isArray(this.to['scoring']?.['answer'])) {
151
- // Handle multiselect case where answer is also an array
152
- if (Array.isArray(this.originalValue)) {
153
- // Check if not empty AND all selected answers are in expected answers
154
- const isCorrect = this.originalValue.length > 0 &&
155
- this.originalValue.every(a => this.to['scoring']?.['answer'].includes(a));
156
- if (!isCorrect) {
157
- this.checked = true;
158
- }
159
- }
160
- else {
161
- // Single value case
162
- if (!this.to['scoring']?.['answer'].includes(this.originalValue)) {
163
- this.checked = true;
164
- }
165
- }
166
- }
167
- break;
168
- case 'range':
169
- const answer = this.originalValue;
170
- const num = typeof answer === 'number' ? answer : Number(answer);
171
- const correct = Number.isFinite(num) &&
172
- num >= this.to['scoring']?.['answer'].min &&
173
- num <= this.to['scoring']?.['answer'].max;
174
- if (!correct) {
175
- this.checked = true;
176
- }
177
- break;
178
- }
179
- }
180
- setCorrectValue() {
181
- const currentHelperValue = this.currentHelperValue;
182
- // If helper already has a value (user edited), don't override
183
- if (currentHelperValue && currentHelperValue.trim() !== '') {
184
- return;
185
- }
186
- switch (this.to['scoring']?.['criteria']) {
187
- case 'attempted':
188
- // For attempted, set defaultHelperText
189
- this.helperFormControl.setValue('');
190
- break;
191
- case 'exactMatch':
192
- if (Array.isArray(this.to['scoring']?.['answer'])) {
193
- // Handle multiselect case where answer is also an array
194
- if (Array.isArray(this.originalValue)) {
195
- // Check if not empty AND all selected answers are in expected answers
196
- const isCorrect = this.originalValue.length > 0 &&
197
- this.originalValue.every(a => this.to['scoring']?.['answer'].includes(a));
198
- if (isCorrect) {
199
- // Answer is correct - set empty value in helper
200
- this.helperFormControl.setValue('');
201
- }
202
- else {
203
- // Answer is incorrect - set defaultHelperText in helper
204
- this.helperFormControl.setValue(this.defaultHelperText);
205
- }
206
- }
207
- else {
208
- // Single value case
209
- if (this.to['scoring']?.['answer'].includes(this.originalValue)) {
210
- // Answer is correct - set empty value in helper
211
- this.helperFormControl.setValue('');
212
- }
213
- else {
214
- // Answer is incorrect - set defaultHelperText in helper
215
- this.helperFormControl.setValue(this.defaultHelperText);
216
- }
217
- }
218
- }
219
- break;
220
- case 'range':
221
- const answer = this.originalValue;
222
- const num = typeof answer === 'number' ? answer : Number(answer);
223
- const correct = Number.isFinite(num) &&
224
- num >= this.to['scoring']?.['answer'].min &&
225
- num <= this.to['scoring']?.['answer'].max;
226
- if (correct) {
227
- // Answer is correct - set empty value in helper
228
- this.helperFormControl.setValue('');
229
- }
230
- else {
231
- // Answer is incorrect - set defaultHelperText in helper
232
- this.helperFormControl.setValue(this.defaultHelperText);
233
- }
234
- break;
235
- default:
236
- break;
237
- }
238
- }
239
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MnlFormHelperTextInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
240
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MnlFormHelperTextInputComponent, isStandalone: true, selector: "mu-helper-text", viewQueries: [{ propertyName: "autosize", first: true, predicate: ["autosize"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
241
- <div class="helper-text-container">
242
- <!-- Helper Mode - Show toggle and conditional content -->
243
- <div *ngIf="to['enableHelper']">
244
- <mat-label>{{ to.label }}</mat-label>
245
- <div *ngIf="originalValue" class="flex-row">
246
- <span class="answer">{{ originalValue }}</span>
247
- <mat-slide-toggle
248
- [(ngModel)]="checked"
249
- (toggleChange)="toggleSlide()"
250
- [disabled]="field.form?.disabled"
251
- >{{ helperLabel }}</mat-slide-toggle
252
- >
253
- </div>
254
-
255
- <mat-form-field class="textarea" appearance="outline" *ngIf="checked">
256
- <textarea
257
- cdkTextareaAutosize
258
- #autosize="cdkTextareaAutosize"
259
- cdkAutosizeMinRows="2"
260
- rows="2"
261
- matInput
262
- [formControl]="helperFormControl"
263
- [readonly]="readonly || field.form?.disabled"
264
- [disabled]="field.form?.disabled"
265
- ></textarea>
266
- </mat-form-field>
267
- </div>
268
-
269
- <!-- Default Mode - Show field directly -->
270
- <div *ngIf="!to['enableHelper']">
271
- <formly-field *ngIf="defaultFieldConfig" [field]="defaultFieldConfig">
272
- </formly-field>
273
- </div>
274
- </div>
275
- `, isInline: true, styles: [".helper-text-container{display:flex;flex-direction:column}.answer{font-size:12px;width:85%;overflow-wrap:break-word;word-wrap:break-word}.textarea{margin:0!important;width:100%}.flex-row{display:flex;flex-direction:row;justify-content:space-between}.w-full{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.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: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i5.FormlyField, selector: "formly-field", inputs: ["field"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: TextFieldModule }] }); }
276
- }
277
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MnlFormHelperTextInputComponent, decorators: [{
278
- type: Component,
279
- args: [{ selector: 'mu-helper-text', standalone: true, imports: [
280
- CommonModule,
281
- MatInputModule,
282
- FormlyModule,
283
- ReactiveFormsModule,
284
- FormsModule,
285
- MatFormFieldModule,
286
- MatSlideToggleModule,
287
- MatSelectModule,
288
- MatDatepickerModule,
289
- MatNativeDateModule,
290
- TextFieldModule
291
- ], template: `
292
- <div class="helper-text-container">
293
- <!-- Helper Mode - Show toggle and conditional content -->
294
- <div *ngIf="to['enableHelper']">
295
- <mat-label>{{ to.label }}</mat-label>
296
- <div *ngIf="originalValue" class="flex-row">
297
- <span class="answer">{{ originalValue }}</span>
298
- <mat-slide-toggle
299
- [(ngModel)]="checked"
300
- (toggleChange)="toggleSlide()"
301
- [disabled]="field.form?.disabled"
302
- >{{ helperLabel }}</mat-slide-toggle
303
- >
304
- </div>
305
-
306
- <mat-form-field class="textarea" appearance="outline" *ngIf="checked">
307
- <textarea
308
- cdkTextareaAutosize
309
- #autosize="cdkTextareaAutosize"
310
- cdkAutosizeMinRows="2"
311
- rows="2"
312
- matInput
313
- [formControl]="helperFormControl"
314
- [readonly]="readonly || field.form?.disabled"
315
- [disabled]="field.form?.disabled"
316
- ></textarea>
317
- </mat-form-field>
318
- </div>
319
-
320
- <!-- Default Mode - Show field directly -->
321
- <div *ngIf="!to['enableHelper']">
322
- <formly-field *ngIf="defaultFieldConfig" [field]="defaultFieldConfig">
323
- </formly-field>
324
- </div>
325
- </div>
326
- `, styles: [".helper-text-container{display:flex;flex-direction:column}.answer{font-size:12px;width:85%;overflow-wrap:break-word;word-wrap:break-word}.textarea{margin:0!important;width:100%}.flex-row{display:flex;flex-direction:row;justify-content:space-between}.w-full{width:100%}\n"] }]
327
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { autosize: [{
328
- type: ViewChild,
329
- args: ['autosize']
330
- }] } });
331
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXUtaGVscGVyLXRleHQudHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZm9ybS9zcmMvbGliL3R5cGVzL211LWhlbHBlci10ZXh0LnR5cGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUF1QixlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFvQyxTQUFTLEVBQVUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9GLE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0UsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN0RSxPQUFPLEVBR0wsWUFBWSxHQUNiLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7Ozs7Ozs7QUErRWpELE1BQU0sT0FBTywrQkFDWCxTQUFRLFNBQTBCO0lBT2xDLElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLFlBQVksQ0FBQztJQUNqRSxDQUFDO0lBQ0QsSUFBSSxpQkFBaUI7UUFDbkIsT0FBTyxJQUFJLENBQUMs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Q0FBQyxDQUFDO2dCQUN0QyxDQUFDO3FCQUFNLENBQUM7b0JBQ04sd0RBQXdEO29CQUN4RCxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUMxRCxDQUFDO2dCQUNELE1BQU07WUFFUjtnQkFDRSxNQUFNO1FBQ1YsQ0FBQztJQUNILENBQUM7K0dBaFFVLCtCQUErQjttR0FBL0IsK0JBQStCLHVNQTdEaEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUNULHVWQS9DQyxZQUFZLGtJQUNaLGNBQWMscTFCQUNkLFlBQVksd0hBQ1osbUJBQW1CLHlrQkFDbkIsV0FBVyxzUEFDWCxrQkFBa0IsOEJBQ2xCLG9CQUFvQix5WEFDcEIsZUFBZSw4QkFDZixtQkFBbUIsOEJBQ25CLG1CQUFtQiw4QkFDbkIsZUFBZTs7NEZBK0ROLCtCQUErQjtrQkE3RTNDLFNBQVM7K0JBQ0UsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxZQUFZO3dCQUNaLG1CQUFtQjt3QkFDbkIsV0FBVzt3QkFDWCxrQkFBa0I7d0JBQ2xCLG9CQUFvQjt3QkFDcEIsZUFBZTt3QkFDZixtQkFBbUI7d0JBQ25CLG1CQUFtQjt3QkFDbkIsZUFBZTtxQkFDaEIsWUFDUzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQ1Q7c0ZBOEJzQixRQUFRO3NCQUE5QixTQUFTO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZGtUZXh0YXJlYUF1dG9zaXplLCBUZXh0RmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvdGV4dC1maWVsZCc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdE5hdGl2ZURhdGVNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcbmltcG9ydCB7IE1hdERhdGVwaWNrZXJNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBNYXRTZWxlY3RNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0U2xpZGVUb2dnbGVNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbGlkZS10b2dnbGUnO1xuaW1wb3J0IHtcbiAgRmllbGRUeXBlQ29uZmlnLFxuICBGb3JtbHlGaWVsZENvbmZpZyxcbiAgRm9ybWx5TW9kdWxlLFxufSBmcm9tICdAbmd4LWZvcm1seS9jb3JlJztcbmltcG9ydCB7IEZpZWxkVHlwZSB9IGZyb20gJ0BuZ3gtZm9ybWx5L21hdGVyaWFsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbXUtaGVscGVyLXRleHQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIE1hdElucHV0TW9kdWxlLFxuICAgIEZvcm1seU1vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIE1hdEZvcm1GaWVsZE1vZHVsZSxcbiAgICBNYXRTbGlkZVRvZ2dsZU1vZHVsZSxcbiAgICBNYXRTZWxlY3RNb2R1bGUsXG4gICAgTWF0RGF0ZXBpY2tlck1vZHVsZSxcbiAgICBNYXROYXRpdmVEYXRlTW9kdWxlLFxuICAgIFRleHRGaWVsZE1vZHVsZSBcbiAgXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwiaGVscGVyLXRleHQtY29udGFpbmVyXCI+XG4gICAgICA8IS0tIEhlbHBlciBNb2RlIC0gU2hvdyB0b2dnbGUgYW5kIGNvbmRpdGlvbmFsIGNvbnRlbnQgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwidG9bJ2VuYWJsZUhlbHBlciddXCI+XG4gICAgICAgIDxtYXQtbGFiZWw+e3sgdG8ubGFiZWwgfX08L21hdC1sYWJlbD5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm9yaWdpbmFsVmFsdWVcIiBjbGFzcz1cImZsZXgtcm93XCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJhbnN3ZXJcIj57eyBvcmlnaW5hbFZhbHVlIH19PC9zcGFuPlxuICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cImNoZWNrZWRcIlxuICAgICAgICAgICAgKHRvZ2dsZUNoYW5nZSk9XCJ0b2dnbGVTbGlkZSgpXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJmaWVsZC5mb3JtPy5kaXNhYmxlZFwiXG4gICAgICAgICAgICA+e3sgaGVscGVyTGFiZWwgfX08L21hdC1zbGlkZS10b2dnbGVcbiAgICAgICAgICA+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cInRleHRhcmVhXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiAqbmdJZj1cImNoZWNrZWRcIj5cbiAgICAgICAgICA8dGV4dGFyZWFcbiAgICAgICAgICAgIGNka1RleHRhcmVhQXV0b3NpemVcbiAgICAgICAgICAgICNhdXRvc2l6ZT1cImNka1RleHRhcmVhQXV0b3NpemVcIlxuICAgICAgICAgICAgY2RrQXV0b3NpemVNaW5Sb3dzPVwiMlwiXG4gICAgICAgICAgICByb3dzPVwiMlwiXG4gICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImhlbHBlckZvcm1Db250cm9sXCJcbiAgICAgICAgICAgIFtyZWFkb25seV09XCJyZWFkb25seSB8fCBmaWVsZC5mb3JtPy5kaXNhYmxlZFwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiZmllbGQuZm9ybT8uZGlzYWJsZWRcIlxuICAgICAgICAgID48L3RleHRhcmVhPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gRGVmYXVsdCBNb2RlIC0gU2hvdyBmaWVsZCBkaXJlY3RseSAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCIhdG9bJ2VuYWJsZUhlbHBlciddXCI+XG4gICAgICAgIDxmb3JtbHktZmllbGQgKm5nSWY9XCJkZWZhdWx0RmllbGRDb25maWdcIiBbZmllbGRdPVwiZGVmYXVsdEZpZWxkQ29uZmlnXCI+XG4gICAgICAgIDwvZm9ybWx5LWZpZWxkPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlczogYFxuICAgICAuaGVscGVyLXRleHQtY29udGFpbmVye1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgIH1cbiAgICAgLmFuc3dlcntcbiAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgIHdpZHRoOiA4NSU7XG4gICAgICBvdmVyZmxvdy13cmFwOiBicmVhay13b3JkO1xuICAgICAgd29yZC13cmFwOiBicmVhay13b3JkO1xuICAgICB9XG4gICAgICAudGV4dGFyZWF7XG4gICAgICBtYXJnaW46IDBweCAhaW1wb3J0YW50O1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgIH1cbiAgICAgLmZsZXgtcm93e1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgIH1cbiAgICAgLnctZnVsbHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICB9XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIE1ubEZvcm1IZWxwZXJUZXh0SW5wdXRDb21wb25lbnRcbiAgZXh0ZW5kcyBGaWVsZFR5cGU8RmllbGRUeXBlQ29uZmlnPlxuICBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdFxue1xuICBAVmlld0NoaWxkKCdhdXRvc2l6ZScpIGF1dG9zaXplPzogQ2RrVGV4dGFyZWFBdXRvc2l6ZTtcbiAgY2hlY2tlZCA9IGZhbHNlO1xuICBoZWxwZXJGb3JtQ29udHJvbCE6IEZvcm1Db250cm9sOyAvLyBTZXBhcmF0ZSBmb3JtIGNvbnRyb2wgZm9yIGhlbHBlciBtb2RlbFxuXG4gIGdldCBoZWxwZXJMYWJlbCgpIHtcbiAgICByZXR1cm4gdGhpcy50b1snaGVscGVyUHJvcHMnXT8uWydoZWxwZXJMYWJlbCddIHx8ICdOZWVkIGhlbHA/JztcbiAgfVxuICBnZXQgZGVmYXVsdEhlbHBlclRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9bJ2hlbHBlclByb3BzJ10/LlsnZGVmYXVsdEhlbHBlclRleHQnXSB8fCAnJztcbiAgfVxuXG4gIC8vIEdldCB2YWx1ZSBmcm9tIHByaW1hcnkgbW9kZWwgKGFuc3dlcnMpXG4gIGdldCBvcmlnaW5hbFZhbHVlKCkge1xuICAgIGNvbnN0IGZpZWxkS2V5ID0gdGhpcy5maWVsZC5rZXkgYXMgc3RyaW5nO1xuICAgIHJldHVybiB0aGlzLmZpZWxkLm1vZGVsPy5bZmllbGRLZXldO1xuICB9XG5cbiAgLy8gR2V0L1NldCB2YWx1ZSBmcm9tIHNlY29uZGFyeSBtb2RlbCAoaGVscGVyKVxuICBnZXQgaGVscGVyTW9kZWwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMudG9bJ2hlbHBlck1vZGVsJ10gfHxcbiAgICAgIHRoaXMucHJvcHNbJ2hlbHBlck1vZGVsJ10gfHxcbiAgICAgIHRoaXMub3B0aW9ucz8uZm9ybVN0YXRlPy5bJ2hlbHBlck1vZGVsJ11cbiAgICApO1xuICB9XG5cbiAgZ2V0IGhlbHBlcktleSgpIHtcbiAgICByZXR1cm4gdGhpcy50b1snaGVscGVyS2V5J10gfHwgdGhpcy5maWVsZC5rZXk7XG4gIH1cblxuICBnZXQgY3VycmVudEhlbHBlclZhbHVlKCkge1xuICAgIGlmICh0aGlzLmhlbHBlck1vZGVsICYmIHRoaXMuaGVscGVyS2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5oZWxwZXJNb2RlbFt0aGlzLmhlbHBlcktleSBhcyBzdHJpbmddO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBzZXQgY3VycmVudEhlbHBlclZhbHVlKHZhbHVlOiBhbnkpIHtcbiAgICBpZiAodGhpcy5oZWxwZXJNb2RlbCAmJiB0aGlzLmhlbHBlcktleSkge1xuICAgICAgdGhpcy5oZWxwZXJNb2RlbFt0aGlzLmhlbHBlcktleSBhcyBzdHJpbmddID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHJlYWRvbmx5KCkge1xuICAgIHJldHVybiB0aGlzLnRvWydyZWFkb25seSddIHx8IHRoaXMucHJvcHNbJ3JlYWRvbmx5J10gfHwgZmFsc2U7XG4gIH1cblxuICBkZWZhdWx0RmllbGRDb25maWc/OiBGb3JtbHlGaWVsZENvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgLy8gSW5pdGlhbGl6ZSBoZWxwZXIgZm9ybSBjb250cm9sIHdpdGggdmFsdWUgZnJvbSBoZWxwZXIgbW9kZWxcbiAgICB0aGlzLmhlbHBlckZvcm1Db250cm9sID0gbmV3IEZvcm1Db250cm9sKHRoaXMuY3VycmVudEhlbHBlclZhbHVlIHx8ICcnKTtcblxuICAgIC8vIFN1YnNjcmliZSB0byBjaGFuZ2VzIGluIGhlbHBlciBmb3JtIGNvbnRyb2wgYW5kIHVwZGF0ZSBoZWxwZXIgbW9kZWxcbiAgICB0aGlzLmhlbHBlckZvcm1Db250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICB0aGlzLmN1cnJlbnRIZWxwZXJWYWx1ZSA9IHZhbHVlO1xuICAgICAgLy8gRW1pdCBoZWxwZXIgbW9kZWwgY2hhbmdlIHRvIHBhcmVudCBjb21wb25lbnRcbiAgICAgIHRoaXMub3B0aW9ucz8uZm9ybVN0YXRlPy5bJ29uSGVscGVyTW9kZWxDaGFuZ2UnXT8uKHRoaXMuaGVscGVyTW9kZWwpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXR1cERlZmF1bHRGaWVsZCgpO1xuXG4gICAgaWYgKHRoaXMudG9bJ2VuYWJsZUhlbHBlciddKSB7XG4gICAgICB0aGlzLnNldENvcnJlY3RWYWx1ZSgpO1xuICAgICAgdGhpcy5kZXRlcm1pbmVJbml0aWFsU3RhdGUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY3VycmVudEhlbHBlclZhbHVlICYmIHRoaXMuY3VycmVudEhlbHBlclZhbHVlLnRyaW0oKSAhPT0gJycpIHtcbiAgICAgIHRoaXMuY2hlY2tlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgdGhpcy5hdXRvc2l6ZT8ucmVzaXplVG9GaXRDb250ZW50KHRydWUpO1xuICAgIH0pO1xuICB9XG5cblxuICBwdWJsaWMgcmVzaXplVGV4dGFyZWEoKSB7XG4gICAgaWYgKHRoaXMuYXV0b3NpemUpIHtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5hdXRvc2l6ZT8ucmVzaXplVG9GaXRDb250ZW50KHRydWUpLCA1MCk7XG4gICAgfVxuICB9XG5cbiAgdG9nZ2xlU2xpZGUoKSB7XG4gICAgdGhpcy5jaGVja2VkID0gIXRoaXMuY2hlY2tlZDtcbiAgICBpZiAodGhpcy5jaGVja2VkKSB7XG4gICAgICAvLyBXaGVuIHRvZ2dsZSBpcyBvcGVuZWQsIGNoZWNrIGlmIGhlbHBlciBmaWVsZCBpcyBlbXB0eVxuICAgICAgY29uc3QgY3VycmVudGhlbHBlciA9IHRoaXMuaGVscGVyRm9ybUNvbnRyb2wudmFsdWU7XG4gICAgICBpZiAoIWN1cnJlbnRoZWxwZXIgfHwgY3VycmVudGhlbHBlci50cmltKCkgPT09ICcnKSB7XG4gICAgICAgIHRoaXMuaGVscGVyRm9ybUNvbnRyb2wuc2V0VmFsdWUodGhpcy5kZWZhdWx0SGVscGVyVGV4dCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGVscGVyRm9ybUNvbnRyb2wuc2V0VmFsdWUoJycpO1xuICAgIH1cbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBzZXR1cERlZmF1bHRGaWVsZCgpIHtcbiAgICBjb25zdCBmaWVsZENvbmZpZyA9IHRoaXMudG9bJ2RlZmF1bHRGaWVsZENvbmZpZyddO1xuICAgIGlmIChmaWVsZENvbmZpZykge1xuICAgICAgLy8gR2V0IGN1cnJlbnQgdmFsdWUgZnJvbSBtb2RlbCBhbmQgc3luYyB3aXRoIGZvcm1Db250cm9sXG4gICAgICBjb25zdCBmaWVsZEtleSA9IHRoaXMuZmllbGQua2V5IGFzIHN0cmluZztcbiAgICAgIGNvbnN0IG1vZGVsVmFsdWUgPSB0aGlzLmZpZWxkLm1vZGVsPy5bZmllbGRLZXldO1xuICAgICAgXG4gICAgICAvLyBTeW5jIGZvcm1Db250cm9sIHZhbHVlIHdpdGggbW9kZWwgdmFsdWUgaWYgaXQgZXhpc3RzXG4gICAgICBpZiAobW9kZWxWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIG1vZGVsVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRWYWx1ZShtb2RlbFZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIENyZWF0ZSBlbmhhbmNlZCBwcm9wcyB3aXRoIG5lY2Vzc2FyeSBmaXhlcyBmb3IgcHJvZHVjdGlvblxuICAgICAgY29uc3QgZW5oYW5jZWRQcm9wcyA9IHtcbiAgICAgICAgLi4uZmllbGRDb25maWcucHJvcHMsXG4gICAgICB9O1xuICAgICAgXG4gICAgICAvLyBGb3Igc2VsZWN0IGZpZWxkcywgYWRkIGNvbXBhcmVXaXRoIGZ1bmN0aW9uIHRvIGVuc3VyZSBwcm9wZXIgdmFsdWUgbWF0Y2hpbmcgaW4gcHJvZHVjdGlvbiBidWlsZHNcbiAgICAgIGlmIChmaWVsZENvbmZpZy50eXBlID09PSAnc2VsZWN0JyAmJiAhZW5oYW5jZWRQcm9wc1snY29tcGFyZVdpdGgnXSkge1xuICAgICAgICBlbmhhbmNlZFByb3BzWydjb21wYXJlV2l0aCddID0gKG8xOiBhbnksIG8yOiBhbnkpID0+IG8xID09PSBvMjtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgdGhpcy5kZWZhdWx0RmllbGRDb25maWcgPSB7XG4gICAgICAgIHR5cGU6IGZpZWxkQ29uZmlnLnR5cGUsXG4gICAgICAgIGtleTogdGhpcy5maWVsZC5rZXkgfHwgZmllbGRDb25maWcua2V5IHx8ICdkZWZhdWx0S2V5JyxcbiAgICAgICAgZm9ybUNvbnRyb2w6IHRoaXMuZm9ybUNvbnRyb2wsXG4gICAgICAgIHByb3BzOiBlbmhhbmNlZFByb3BzLFxuICAgICAgICB3cmFwcGVyczogZmllbGRDb25maWcud3JhcHBlcnMgfHwgW10sXG4gICAgICAgIG1vZGVsT3B0aW9uczogZmllbGRDb25maWcubW9kZWxPcHRpb25zIHx8IHRoaXMuZmllbGQubW9kZWxPcHRpb25zIHx8IHt9LFxuICAgICAgICB2YWxpZGF0b3JzOiBmaWVsZENvbmZpZy52YWxpZGF0b3JzIHx8IHRoaXMuZmllbGQudmFsaWRhdG9ycyB8fCB7fSxcbiAgICAgICAgYXN5bmNWYWxpZGF0b3JzOlxuICAgICAgICAgIGZpZWxkQ29uZmlnLmFzeW5jVmFsaWRhdG9ycyB8fCB0aGlzLmZpZWxkLmFzeW5jVmFsaWRhdG9ycyB8fCB7fSxcbiAgICAgICAgaG9va3M6IGZpZWxkQ29uZmlnLmhvb2tzIHx8IHRoaXMuZmllbGQuaG9va3MgfHwge30sXG4gICAgICAgIGV4cHJlc3Npb25zOiBmaWVsZENvbmZpZy5leHByZXNzaW9ucyB8fCB0aGlzLmZpZWxkLmV4cHJlc3Npb25zIHx8IHt9LFxuICAgICAgICBoaWRlOiBmaWVsZENvbmZpZy5oaWRlICE9PSB1bmRlZmluZWQgPyBmaWVsZENvbmZpZy5oaWRlIDogZmFsc2UsXG4gICAgICAgIGNsYXNzTmFtZTogZmllbGRDb25maWcuY2xhc3NOYW1lIHx8IHRoaXMuZmllbGQuY2xhc3NOYW1lIHx8ICcnLFxuICAgICAgICBmaWVsZEdyb3VwQ2xhc3NOYW1lOlxuICAgICAgICAgIGZpZWxkQ29uZmlnLmZpZWxkR3JvdXBDbGFzc05hbWUgfHxcbiAgICAgICAgICB0aGlzLmZpZWxkLmZpZWxkR3JvdXBDbGFzc05hbWUgfHxcbiAgICAgICAgICAnJyxcbiAgICAgICAgcGFyZW50OiB0aGlzLmZpZWxkLnBhcmVudCxcbiAgICAgICAgb3B0aW9uczogdGhpcy5maWVsZC5vcHRpb25zLFxuICAgICAgICBtb2RlbDogdGhpcy5maWVsZC5tb2RlbCxcbiAgICAgICAgZm9ybTogdGhpcy5maWVsZC5mb3JtLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBkZXRlcm1pbmVJbml0aWFsU3RhdGUoKSB7XG4gICAgLy8gQXV0by1vcGVuIGhlbHBlciBiYXNlZCBvbiBzY29yaW5nIGNyaXRlcmlhXG4gICAgc3dpdGNoICh0aGlzLnRvWydzY29yaW5nJ10/LlsnY3JpdGVyaWEnXSkge1xuICAgICAgY2FzZSAnZXhhY3RNYXRjaCc6XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMudG9bJ3Njb3JpbmcnXT8uWydhbnN3ZXInXSkpIHtcbiAgICAgICAgICAvLyBIYW5kbGUgbXVsdGlzZWxlY3QgY2FzZSB3aGVyZSBhbnN3ZXIgaXMgYWxzbyBhbiBhcnJheVxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMub3JpZ2luYWxWYWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIG5vdCBlbXB0eSBBTkQgYWxsIHNlbGVjdGVkIGFuc3dlcnMgYXJlIGluIGV4cGVjdGVkIGFuc3dlcnNcbiAgICAgICAgICAgIGNvbnN0IGlzQ29ycmVjdCA9IHRoaXMub3JpZ2luYWxWYWx1ZS5sZW5ndGggPiAwICYmIFxuICAgICAgICAgICAgICB0aGlzLm9yaWdpbmFsVmFsdWUuZXZlcnkoYSA9PiB0aGlzLnRvWydzY29yaW5nJ10/LlsnYW5zd2VyJ10uaW5jbHVkZXMoYSkpO1xuICAgICAgICAgICAgaWYgKCFpc0NvcnJlY3QpIHtcbiAgICAgICAgICAgICAgdGhpcy5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2luZ2xlIHZhbHVlIGNhc2VcbiAgICAgICAgICAgIGlmICghdGhpcy50b1snc2NvcmluZyddPy5bJ2Fuc3dlciddLmluY2x1ZGVzKHRoaXMub3JpZ2luYWxWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgdGhpcy5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3JhbmdlJzpcbiAgICAgICAgY29uc3QgYW5zd2VyID0gdGhpcy5vcmlnaW5hbFZhbHVlO1xuICAgICAgICBjb25zdCBudW0gPSB0eXBlb2YgYW5zd2VyID09PSAnbnVtYmVyJyA/IGFuc3dlciA6IE51bWJlcihhbnN3ZXIpO1xuXG4gICAgICAgIGNvbnN0IGNvcnJlY3QgPVxuICAgICAgICAgIE51bWJlci5pc0Zpbml0ZShudW0pICYmXG4gICAgICAgICAgbnVtID49IHRoaXMudG9bJ3Njb3JpbmcnXT8uWydhbnN3ZXInXS5taW4gJiZcbiAgICAgICAgICBudW0gPD0gdGhpcy50b1snc2NvcmluZyddPy5bJ2Fuc3dlciddLm1heDtcblxuICAgICAgICBpZiAoIWNvcnJlY3QpIHtcbiAgICAgICAgICB0aGlzLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNldENvcnJlY3RWYWx1ZSgpIHtcbiAgICBjb25zdCBjdXJyZW50SGVscGVyVmFsdWUgPSB0aGlzLmN1cnJlbnRIZWxwZXJWYWx1ZTtcblxuICAgIC8vIElmIGhlbHBlciBhbHJlYWR5IGhhcyBhIHZhbHVlICh1c2VyIGVkaXRlZCksIGRvbid0IG92ZXJyaWRlXG4gICAgaWYgKGN1cnJlbnRIZWxwZXJWYWx1ZSAmJiBjdXJyZW50SGVscGVyVmFsdWUudHJpbSgpICE9PSAnJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy50b1snc2NvcmluZyddPy5bJ2NyaXRlcmlhJ10pIHtcbiAgICAgIGNhc2UgJ2F0dGVtcHRlZCc6XG4gICAgICAgIC8vIEZvciBhdHRlbXB0ZWQsIHNldCBkZWZhdWx0SGVscGVyVGV4dFxuICAgICAgICB0aGlzLmhlbHBlckZvcm1Db250cm9sLnNldFZhbHVlKCcnKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2V4YWN0TWF0Y2gnOlxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnRvWydzY29yaW5nJ10/LlsnYW5zd2VyJ10pKSB7XG4gICAgICAgICAgLy8gSGFuZGxlIG11bHRpc2VsZWN0IGNhc2Ugd2hlcmUgYW5zd2VyIGlzIGFsc28gYW4gYXJyYXlcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLm9yaWdpbmFsVmFsdWUpKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiBub3QgZW1wdHkgQU5EIGFsbCBzZWxlY3RlZCBhbnN3ZXJzIGFyZSBpbiBleHBlY3RlZCBhbnN3ZXJzXG4gICAgICAgICAgICBjb25zdCBpc0NvcnJlY3QgPSB0aGlzLm9yaWdpbmFsVmFsdWUubGVuZ3RoID4gMCAmJiBcbiAgICAgICAgICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlLmV2ZXJ5KGEgPT4gdGhpcy50b1snc2NvcmluZyddPy5bJ2Fuc3dlciddLmluY2x1ZGVzKGEpKTtcbiAgICAgICAgICAgIGlmIChpc0NvcnJlY3QpIHtcbiAgICAgICAgICAgICAgLy8gQW5zd2VyIGlzIGNvcnJlY3QgLSBzZXQgZW1wdHkgdmFsdWUgaW4gaGVscGVyXG4gICAgICAgICAgICAgIHRoaXMuaGVscGVyRm9ybUNvbnRyb2wuc2V0VmFsdWUoJycpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gQW5zd2VyIGlzIGluY29ycmVjdCAtIHNldCBkZWZhdWx0SGVscGVyVGV4dCBpbiBoZWxwZXJcbiAgICAgICAgICAgICAgdGhpcy5oZWxwZXJGb3JtQ29udHJvbC5zZXRWYWx1ZSh0aGlzLmRlZmF1bHRIZWxwZXJUZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2luZ2xlIHZhbHVlIGNhc2VcbiAgICAgICAgICAgIGlmICh0aGlzLnRvWydzY29yaW5nJ10/LlsnYW5zd2VyJ10uaW5jbHVkZXModGhpcy5vcmlnaW5hbFZhbHVlKSkge1xuICAgICAgICAgICAgICAvLyBBbnN3ZXIgaXMgY29ycmVjdCAtIHNldCBlbXB0eSB2YWx1ZSBpbiBoZWxwZXJcbiAgICAgICAgICAgICAgdGhpcy5oZWxwZXJGb3JtQ29udHJvbC5zZXRWYWx1ZSgnJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBBbnN3ZXIgaXMgaW5jb3JyZWN0IC0gc2V0IGRlZmF1bHRIZWxwZXJUZXh0IGluIGhlbHBlclxuICAgICAgICAgICAgICB0aGlzLmhlbHBlckZvcm1Db250cm9sLnNldFZhbHVlKHRoaXMuZGVmYXVsdEhlbHBlclRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAncmFuZ2UnOlxuICAgICAgICBjb25zdCBhbnN3ZXIgPSB0aGlzLm9yaWdpbmFsVmFsdWU7XG4gICAgICAgIGNvbnN0IG51bSA9IHR5cGVvZiBhbnN3ZXIgPT09ICdudW1iZXInID8gYW5zd2VyIDogTnVtYmVyKGFuc3dlcik7XG5cbiAgICAgICAgY29uc3QgY29ycmVjdCA9XG4gICAgICAgICAgTnVtYmVyLmlzRmluaXRlKG51bSkgJiZcbiAgICAgICAgICBudW0gPj0gdGhpcy50b1snc2NvcmluZyddPy5bJ2Fuc3dlciddLm1pbiAmJlxuICAgICAgICAgIG51bSA8PSB0aGlzLnRvWydzY29yaW5nJ10/LlsnYW5zd2VyJ10ubWF4O1xuXG4gICAgICAgIGlmIChjb3JyZWN0KSB7XG4gICAgICAgICAgLy8gQW5zd2VyIGlzIGNvcnJlY3QgLSBzZXQgZW1wdHkgdmFsdWUgaW4gaGVscGVyXG4gICAgICAgICAgdGhpcy5oZWxwZXJGb3JtQ29udHJvbC5zZXRWYWx1ZSgnJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gQW5zd2VyIGlzIGluY29ycmVjdCAtIHNldCBkZWZhdWx0SGVscGVyVGV4dCBpbiBoZWxwZXJcbiAgICAgICAgICB0aGlzLmhlbHBlckZvcm1Db250cm9sLnNldFZhbHVlKHRoaXMuZGVmYXVsdEhlbHBlclRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -1,139 +0,0 @@
1
- import { Component, computed, inject, model, signal } from "@angular/core";
2
- import { FieldType } from "@ngx-formly/material";
3
- import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms";
4
- import { MatFormFieldModule } from "@angular/material/form-field";
5
- import { MatInputModule } from "@angular/material/input";
6
- import { MatAutocompleteModule } from "@angular/material/autocomplete";
7
- import { AsyncPipe, CommonModule } from "@angular/common";
8
- import { FormlyModule } from "@ngx-formly/core";
9
- import { MatChipsModule } from "@angular/material/chips";
10
- import { LiveAnnouncer } from "@angular/cdk/a11y";
11
- import { MatIconModule } from "@angular/material/icon";
12
- import * as i0 from "@angular/core";
13
- import * as i1 from "@angular/forms";
14
- import * as i2 from "@angular/material/form-field";
15
- import * as i3 from "@angular/material/autocomplete";
16
- import * as i4 from "@angular/material/core";
17
- import * as i5 from "@ngx-formly/core";
18
- import * as i6 from "@angular/material/chips";
19
- import * as i7 from "@angular/material/icon";
20
- import * as i8 from "@angular/common";
21
- export class MultiSelectAutocompleteComponent extends FieldType {
22
- constructor() {
23
- super(...arguments);
24
- this.currentState = model("");
25
- this.chipsArr = signal([]);
26
- this.announcer = inject(LiveAnnouncer);
27
- this.itemControl = new FormControl();
28
- this.filteredStates = computed(() => {
29
- const currentState = this.currentState().toLowerCase();
30
- this.tempArr = this.props.options;
31
- this.tempArr = this.tempArr?.filter((state) => !this.formControl.value.includes(state));
32
- return currentState
33
- ? this.tempArr?.filter((state) => state.toLowerCase().includes(currentState))
34
- : this.tempArr?.slice();
35
- });
36
- }
37
- removeChip(i) {
38
- const value = this.formControl.value;
39
- this.formControl.setValue([
40
- ...value.slice(0, i),
41
- ...value.slice(i + 1, value.length)
42
- ]);
43
- this.formControl.markAsTouched();
44
- }
45
- selectedChip(event) {
46
- const data = [
47
- ...this.itemControl.value,
48
- event.option.viewValue,
49
- ];
50
- this.formControl.setValue([...new Set(data)]);
51
- this.itemControl.setValue("");
52
- this.currentState.set("");
53
- }
54
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectAutocompleteComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
55
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MultiSelectAutocompleteComponent, isStandalone: true, selector: "mu-formly-autocomplete-type", inputs: { currentState: { classPropertyName: "currentState", publicName: "currentState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentState: "currentStateChange" }, usesInheritance: true, ngImport: i0, template: `
56
- <mat-chip-grid
57
- #chipGrid
58
- [formControl]="itemControl"
59
- [formlyAttributes]="field"
60
- >
61
- @for (chip of formControl.value; track $index; let i= $index) {
62
- <mat-chip-row (removed)="removeChip(i)">
63
- {{ chip }}
64
- <button matChipRemove [attr.aria-label]="'remove ' + chip">
65
- <mat-icon>cancel</mat-icon>
66
- </button>
67
- </mat-chip-row>
68
- }
69
- </mat-chip-grid>
70
- <input
71
- [(ngModel)]="currentState"
72
- [matChipInputFor]="chipGrid"
73
- [matAutocomplete]="auto"
74
- />
75
- <mat-autocomplete
76
- #auto="matAutocomplete"
77
- (optionSelected)="selectedChip($event)"
78
- >
79
- @for (state of filteredStates(); track state) {
80
- <mat-option [value]="state">{{ state }}</mat-option>
81
- }
82
- </mat-autocomplete>
83
- <mat-error *ngIf="formControl.invalid && formControl.touched">
84
- {{ field.validation?.messages?.['required'] }}
85
- </mat-error>
86
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "directive", type: i5.ɵFormlyAttributes, selector: "[formlyAttributes]", inputs: ["formlyAttributes", "id"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i6.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i6.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i6.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
87
- }
88
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectAutocompleteComponent, decorators: [{
89
- type: Component,
90
- args: [{
91
- selector: "mu-formly-autocomplete-type",
92
- standalone: true,
93
- imports: [
94
- FormsModule,
95
- MatFormFieldModule,
96
- MatInputModule,
97
- MatAutocompleteModule,
98
- ReactiveFormsModule,
99
- AsyncPipe,
100
- FormlyModule,
101
- MatChipsModule,
102
- MatIconModule,
103
- CommonModule
104
- ],
105
- template: `
106
- <mat-chip-grid
107
- #chipGrid
108
- [formControl]="itemControl"
109
- [formlyAttributes]="field"
110
- >
111
- @for (chip of formControl.value; track $index; let i= $index) {
112
- <mat-chip-row (removed)="removeChip(i)">
113
- {{ chip }}
114
- <button matChipRemove [attr.aria-label]="'remove ' + chip">
115
- <mat-icon>cancel</mat-icon>
116
- </button>
117
- </mat-chip-row>
118
- }
119
- </mat-chip-grid>
120
- <input
121
- [(ngModel)]="currentState"
122
- [matChipInputFor]="chipGrid"
123
- [matAutocomplete]="auto"
124
- />
125
- <mat-autocomplete
126
- #auto="matAutocomplete"
127
- (optionSelected)="selectedChip($event)"
128
- >
129
- @for (state of filteredStates(); track state) {
130
- <mat-option [value]="state">{{ state }}</mat-option>
131
- }
132
- </mat-autocomplete>
133
- <mat-error *ngIf="formControl.invalid && formControl.touched">
134
- {{ field.validation?.messages?.['required'] }}
135
- </mat-error>
136
- `,
137
- }]
138
- }] });
139
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktc2VsZWN0LWF1dG9jb21wbGV0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZm9ybS9zcmMvbGliL3R5cGVzL211bHRpLXNlbGVjdC1hdXRvY29tcGxldGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkYsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxxQkFBcUIsRUFBZ0MsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNyRyxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7Ozs7OztBQWtEdkQsTUFBTSxPQUFPLGdDQUFpQyxTQUFRLFNBQTBCO0lBaERoRjs7UUFpRFcsaUJBQVksR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekIsYUFBUSxHQUFHLE1BQU0sQ0FBVyxFQUFFLENBQUMsQ0FBQztRQUNoQyxjQUFTLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTNDLGdCQUFXLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUV2QixtQkFBYyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDdEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3ZELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDbEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEtBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUM3RixPQUFPLFlBQVk7Z0JBQ2YsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FDcEMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FDM0M7Z0JBQ0QsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7S0FzQk47SUFuQkMsVUFBVSxDQUFDLENBQUs7UUFDZCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztRQUNyQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQztZQUN4QixHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNwQixHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDO1NBQ3BDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLENBQUE7SUFDbEMsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFtQztRQUM5QyxNQUFNLElBQUksR0FBSTtZQUNaLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLO1lBQ3pCLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUztTQUN2QixDQUFBO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM1QixDQUFDOytHQXBDVSxnQ0FBZ0M7bUdBQWhDLGdDQUFnQyx3VEFqQ2pDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0JULDJEQTFDQyxXQUFXLDhtQkFDWCxrQkFBa0IsMkhBQ2xCLGNBQWMsOEJBQ2QscUJBQXFCLHcxQkFDckIsbUJBQW1CLGlOQUVuQixZQUFZLHFKQUNaLGNBQWMsNHVCQUNkLGFBQWEsbUxBQ2IsWUFBWTs7NEZBbUNILGdDQUFnQztrQkFoRDVDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLDZCQUE2QjtvQkFDdkMsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRTt3QkFDUCxXQUFXO3dCQUNYLGtCQUFrQjt3QkFDbEIsY0FBYzt3QkFDZCxxQkFBcUI7d0JBQ3JCLG1CQUFtQjt3QkFDbkIsU0FBUzt3QkFDVCxZQUFZO3dCQUNaLGNBQWM7d0JBQ2QsYUFBYTt3QkFDYixZQUFZO3FCQUNiO29CQUNELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCVDtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgbW9kZWwsIE9uSW5pdCwgc2lnbmFsIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEZpZWxkVHlwZSB9IGZyb20gXCJAbmd4LWZvcm1seS9tYXRlcmlhbFwiO1xuaW1wb3J0IHsgRmllbGRUeXBlQ29uZmlnIH0gZnJvbSBcIkBuZ3gtZm9ybWx5L2NvcmVcIjtcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGRcIjtcbmltcG9ydCB7IE1hdElucHV0TW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2lucHV0XCI7XG5pbXBvcnQgeyBNYXRBdXRvY29tcGxldGVNb2R1bGUsIE1hdEF1dG9jb21wbGV0ZVNlbGVjdGVkRXZlbnQgfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvYXV0b2NvbXBsZXRlXCI7XG5pbXBvcnQgeyBBc3luY1BpcGUsIENvbW1vbk1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7IEZvcm1seU1vZHVsZSB9IGZyb20gXCJAbmd4LWZvcm1seS9jb3JlXCI7XG5pbXBvcnQgeyBNYXRDaGlwc01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9jaGlwc1wiO1xuaW1wb3J0IHsgTGl2ZUFubm91bmNlciB9IGZyb20gXCJAYW5ndWxhci9jZGsvYTExeVwiO1xuaW1wb3J0IHsgTWF0SWNvbk1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9pY29uXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJtdS1mb3JtbHktYXV0b2NvbXBsZXRlLXR5cGVcIixcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEZvcm1zTW9kdWxlLFxuICAgIE1hdEZvcm1GaWVsZE1vZHVsZSxcbiAgICBNYXRJbnB1dE1vZHVsZSxcbiAgICBNYXRBdXRvY29tcGxldGVNb2R1bGUsXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcbiAgICBBc3luY1BpcGUsXG4gICAgRm9ybWx5TW9kdWxlLFxuICAgIE1hdENoaXBzTW9kdWxlLFxuICAgIE1hdEljb25Nb2R1bGUsXG4gICAgQ29tbW9uTW9kdWxlXG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPG1hdC1jaGlwLWdyaWRcbiAgICAgICNjaGlwR3JpZFxuICAgICAgW2Zvcm1Db250cm9sXT1cIml0ZW1Db250cm9sXCJcbiAgICAgIFtmb3JtbHlBdHRyaWJ1dGVzXT1cImZpZWxkXCJcbiAgICA+XG4gICAgICBAZm9yIChjaGlwIG9mIGZvcm1Db250cm9sLnZhbHVlOyB0cmFjayAkaW5kZXg7IGxldCBpPSAkaW5kZXgpIHtcbiAgICAgIDxtYXQtY2hpcC1yb3cgKHJlbW92ZWQpPVwicmVtb3ZlQ2hpcChpKVwiPlxuICAgICAgICB7eyBjaGlwIH19XG4gICAgICAgIDxidXR0b24gbWF0Q2hpcFJlbW92ZSBbYXR0ci5hcmlhLWxhYmVsXT1cIidyZW1vdmUgJyArIGNoaXBcIj5cbiAgICAgICAgICA8bWF0LWljb24+Y2FuY2VsPC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L21hdC1jaGlwLXJvdz5cbiAgICAgIH1cbiAgICA8L21hdC1jaGlwLWdyaWQ+XG4gICAgPGlucHV0XG4gICAgICBbKG5nTW9kZWwpXT1cImN1cnJlbnRTdGF0ZVwiXG4gICAgICBbbWF0Q2hpcElucHV0Rm9yXT1cImNoaXBHcmlkXCJcbiAgICAgIFttYXRBdXRvY29tcGxldGVdPVwiYXV0b1wiXG4gICAgLz5cbiAgICA8bWF0LWF1dG9jb21wbGV0ZVxuICAgICAgI2F1dG89XCJtYXRBdXRvY29tcGxldGVcIlxuICAgICAgKG9wdGlvblNlbGVjdGVkKT1cInNlbGVjdGVkQ2hpcCgkZXZlbnQpXCJcbiAgICA+XG4gICAgICBAZm9yIChzdGF0ZSBvZiBmaWx0ZXJlZFN0YXRlcygpOyB0cmFjayBzdGF0ZSkge1xuICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cInN0YXRlXCI+e3sgc3RhdGUgfX08L21hdC1vcHRpb24+XG4gICAgICB9XG4gICAgPC9tYXQtYXV0b2NvbXBsZXRlPlxuICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtQ29udHJvbC5pbnZhbGlkICYmIGZvcm1Db250cm9sLnRvdWNoZWRcIj5cbiAgICAgICAge3sgZmllbGQudmFsaWRhdGlvbj8ubWVzc2FnZXM/LlsncmVxdWlyZWQnXSB9fVxuICAgIDwvbWF0LWVycm9yPlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBNdWx0aVNlbGVjdEF1dG9jb21wbGV0ZUNvbXBvbmVudCBleHRlbmRzIEZpZWxkVHlwZTxGaWVsZFR5cGVDb25maWc+IHtcbiAgcmVhZG9ubHkgY3VycmVudFN0YXRlID0gbW9kZWwoXCJcIik7XG4gIHJlYWRvbmx5IGNoaXBzQXJyID0gc2lnbmFsPHN0cmluZ1tdPihbXSk7XG4gIHJlYWRvbmx5IGFubm91bmNlciA9IGluamVjdChMaXZlQW5ub3VuY2VyKTtcbiAgdGVtcEFycjogYW55O1xuICBpdGVtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCgpO1xuXG4gIHJlYWRvbmx5IGZpbHRlcmVkU3RhdGVzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuY3VycmVudFN0YXRlKCkudG9Mb3dlckNhc2UoKTsgICAgXG4gICAgdGhpcy50ZW1wQXJyID0gdGhpcy5wcm9wcy5vcHRpb25zO1xuICAgIHRoaXMudGVtcEFyciA9IHRoaXMudGVtcEFycj8uZmlsdGVyKChzdGF0ZTogYW55KSA9PiAhdGhpcy5mb3JtQ29udHJvbC52YWx1ZS5pbmNsdWRlcyhzdGF0ZSkpO1xuICAgIHJldHVybiBjdXJyZW50U3RhdGVcbiAgICAgICAgPyB0aGlzLnRlbXBBcnI/LmZpbHRlcigoc3RhdGU6IGFueSkgPT5cbiAgICAgICAgICBzdGF0ZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGN1cnJlbnRTdGF0ZSlcbiAgICAgICAgKVxuICAgICAgICA6IHRoaXMudGVtcEFycj8uc2xpY2UoKTtcbiAgICB9KTtcblxuXG4gIHJlbW92ZUNoaXAoaTphbnkpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZm9ybUNvbnRyb2wudmFsdWU7ICAgIFxuICAgIHRoaXMuZm9ybUNvbnRyb2wuc2V0VmFsdWUoW1xuICAgICAgLi4udmFsdWUuc2xpY2UoMCwgaSksXG4gICAgICAuLi52YWx1ZS5zbGljZShpICsgMSwgdmFsdWUubGVuZ3RoKVxuICAgIF0pO1xuICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpICBcbiAgfVxuXG4gIHNlbGVjdGVkQ2hpcChldmVudDogTWF0QXV0b2NvbXBsZXRlU2VsZWN0ZWRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGRhdGEgPSAgW1xuICAgICAgLi4udGhpcy5pdGVtQ29udHJvbC52YWx1ZSxcbiAgICAgIGV2ZW50Lm9wdGlvbi52aWV3VmFsdWUsXG4gICAgXVxuICAgIHRoaXMuZm9ybUNvbnRyb2wuc2V0VmFsdWUoWy4uLm5ldyBTZXQoZGF0YSldKTtcbiAgICB0aGlzLml0ZW1Db250cm9sLnNldFZhbHVlKFwiXCIpO1xuICAgIHRoaXMuY3VycmVudFN0YXRlLnNldChcIlwiKTtcbiAgfVxuXG59XG4iXX0=