@gnggln/ng-ui-system 1.0.0-alpha.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 (141) hide show
  1. package/esm2022/gnggln-ng-ui-system.mjs +5 -0
  2. package/esm2022/lib/components/accordion/accordion.component.mjs +353 -0
  3. package/esm2022/lib/components/accordion/accordion.types.mjs +6 -0
  4. package/esm2022/lib/components/accordion/index.mjs +2 -0
  5. package/esm2022/lib/components/base-layout/base-layout.component.mjs +218 -0
  6. package/esm2022/lib/components/base-layout/base-layout.types.mjs +6 -0
  7. package/esm2022/lib/components/base-layout/index.mjs +14 -0
  8. package/esm2022/lib/components/button/button-area.component.mjs +196 -0
  9. package/esm2022/lib/components/button/button.component.mjs +164 -0
  10. package/esm2022/lib/components/button/button.types.mjs +6 -0
  11. package/esm2022/lib/components/button/index.mjs +16 -0
  12. package/esm2022/lib/components/crud-table/crud-table.component.mjs +789 -0
  13. package/esm2022/lib/components/crud-table/crud-table.types.mjs +6 -0
  14. package/esm2022/lib/components/crud-table/index.mjs +16 -0
  15. package/esm2022/lib/components/form-builder/adapters/it-date-adapter.mjs +82 -0
  16. package/esm2022/lib/components/form-builder/directives/currency-input.directive.mjs +184 -0
  17. package/esm2022/lib/components/form-builder/form-builder.component.mjs +824 -0
  18. package/esm2022/lib/components/form-builder/form-wizard.component.mjs +510 -0
  19. package/esm2022/lib/components/form-builder/index.mjs +19 -0
  20. package/esm2022/lib/components/form-builder/services/form-condition.service.mjs +132 -0
  21. package/esm2022/lib/components/form-builder/services/form-validation.service.mjs +381 -0
  22. package/esm2022/lib/components/form-builder/services/location.service.mjs +140 -0
  23. package/esm2022/lib/components/form-builder/services/wizard-sync.service.mjs +84 -0
  24. package/esm2022/lib/components/form-builder/sub-components/error-summary/form-error-summary.component.mjs +161 -0
  25. package/esm2022/lib/components/form-builder/sub-components/file-input/file-input.component.mjs +310 -0
  26. package/esm2022/lib/components/form-builder/sub-components/specifica-territoriale/specifica-territoriale.component.mjs +648 -0
  27. package/esm2022/lib/components/form-builder/sub-components/table-territoriale/table-territoriale.component.mjs +432 -0
  28. package/esm2022/lib/components/form-builder/types/condition.types.mjs +6 -0
  29. package/esm2022/lib/components/form-builder/types/field.types.mjs +6 -0
  30. package/esm2022/lib/components/form-builder/types/index.mjs +2 -0
  31. package/esm2022/lib/components/form-builder/types/schema.types.mjs +6 -0
  32. package/esm2022/lib/components/form-builder/types/territoriale.types.mjs +6 -0
  33. package/esm2022/lib/components/form-builder/types/validation.types.mjs +6 -0
  34. package/esm2022/lib/components/form-builder-editor/form-builder-editor.component.mjs +730 -0
  35. package/esm2022/lib/components/form-builder-editor/form-builder-editor.service.mjs +56 -0
  36. package/esm2022/lib/components/form-builder-editor/index.mjs +21 -0
  37. package/esm2022/lib/components/form-builder-editor/services/editor-persistence.service.mjs +190 -0
  38. package/esm2022/lib/components/form-builder-editor/services/editor-state.service.mjs +324 -0
  39. package/esm2022/lib/components/form-builder-editor/services/field-factory.service.mjs +188 -0
  40. package/esm2022/lib/components/form-builder-editor/sub-components/condition-editor/condition-editor.component.mjs +667 -0
  41. package/esm2022/lib/components/form-builder-editor/sub-components/editor-toolbar/editor-toolbar.component.mjs +317 -0
  42. package/esm2022/lib/components/form-builder-editor/sub-components/field-config-panel/field-config-panel.component.mjs +611 -0
  43. package/esm2022/lib/components/form-builder-editor/sub-components/field-palette/field-palette.component.mjs +267 -0
  44. package/esm2022/lib/components/form-builder-editor/sub-components/form-values-panel/form-values-panel.component.mjs +276 -0
  45. package/esm2022/lib/components/form-builder-editor/sub-components/options-editor/options-editor.component.mjs +323 -0
  46. package/esm2022/lib/components/form-builder-editor/sub-components/preview-container/preview-container.component.mjs +238 -0
  47. package/esm2022/lib/components/form-builder-editor/sub-components/section-editor/section-editor.component.mjs +472 -0
  48. package/esm2022/lib/components/form-builder-editor/sub-components/validation-editor/validation-editor.component.mjs +473 -0
  49. package/esm2022/lib/components/form-builder-editor/types/editor.types.mjs +6 -0
  50. package/esm2022/lib/components/layout-builder/index.mjs +18 -0
  51. package/esm2022/lib/components/layout-builder/layout-builder.component.mjs +1730 -0
  52. package/esm2022/lib/components/layout-builder/layout-builder.types.mjs +9 -0
  53. package/esm2022/lib/components/layout-builder/layout.service.mjs +239 -0
  54. package/esm2022/lib/components/modal/confirm-dialog.component.mjs +151 -0
  55. package/esm2022/lib/components/modal/index.mjs +4 -0
  56. package/esm2022/lib/components/modal/modal.component.mjs +139 -0
  57. package/esm2022/lib/components/modal/modal.service.mjs +194 -0
  58. package/esm2022/lib/components/modal/modal.types.mjs +6 -0
  59. package/esm2022/lib/components/page-header/breadcrumb.service.mjs +242 -0
  60. package/esm2022/lib/components/page-header/index.mjs +20 -0
  61. package/esm2022/lib/components/page-header/page-header.component.mjs +243 -0
  62. package/esm2022/lib/components/page-header/page-header.types.mjs +21 -0
  63. package/esm2022/lib/components/table/index.mjs +2 -0
  64. package/esm2022/lib/components/table/paginated-table.component.mjs +407 -0
  65. package/esm2022/lib/components/table/table.types.mjs +6 -0
  66. package/esm2022/lib/core/types/index.mjs +6 -0
  67. package/esm2022/lib/core/utils/index.mjs +53 -0
  68. package/esm2022/lib/sources/location-data.opt.json +8942 -0
  69. package/esm2022/lib/sources/nazioni.opt.json +215 -0
  70. package/esm2022/public-api.mjs +34 -0
  71. package/fesm2022/gnggln-ng-ui-system.mjs +55752 -0
  72. package/fesm2022/gnggln-ng-ui-system.mjs.map +1 -0
  73. package/index.d.ts +5 -0
  74. package/lib/components/accordion/accordion.component.d.ts +118 -0
  75. package/lib/components/accordion/accordion.types.d.ts +62 -0
  76. package/lib/components/accordion/index.d.ts +2 -0
  77. package/lib/components/base-layout/base-layout.component.d.ts +83 -0
  78. package/lib/components/base-layout/base-layout.types.d.ts +26 -0
  79. package/lib/components/base-layout/index.d.ts +13 -0
  80. package/lib/components/button/button-area.component.d.ts +88 -0
  81. package/lib/components/button/button.component.d.ts +55 -0
  82. package/lib/components/button/button.types.d.ts +70 -0
  83. package/lib/components/button/index.d.ts +15 -0
  84. package/lib/components/crud-table/crud-table.component.d.ts +143 -0
  85. package/lib/components/crud-table/crud-table.types.d.ts +207 -0
  86. package/lib/components/crud-table/index.d.ts +15 -0
  87. package/lib/components/form-builder/adapters/it-date-adapter.d.ts +32 -0
  88. package/lib/components/form-builder/directives/currency-input.directive.d.ts +48 -0
  89. package/lib/components/form-builder/form-builder.component.d.ts +183 -0
  90. package/lib/components/form-builder/form-wizard.component.d.ts +87 -0
  91. package/lib/components/form-builder/index.d.ts +13 -0
  92. package/lib/components/form-builder/services/form-condition.service.d.ts +46 -0
  93. package/lib/components/form-builder/services/form-validation.service.d.ts +63 -0
  94. package/lib/components/form-builder/services/location.service.d.ts +83 -0
  95. package/lib/components/form-builder/services/wizard-sync.service.d.ts +63 -0
  96. package/lib/components/form-builder/sub-components/error-summary/form-error-summary.component.d.ts +28 -0
  97. package/lib/components/form-builder/sub-components/file-input/file-input.component.d.ts +41 -0
  98. package/lib/components/form-builder/sub-components/specifica-territoriale/specifica-territoriale.component.d.ts +145 -0
  99. package/lib/components/form-builder/sub-components/table-territoriale/table-territoriale.component.d.ts +108 -0
  100. package/lib/components/form-builder/types/condition.types.d.ts +51 -0
  101. package/lib/components/form-builder/types/field.types.d.ts +288 -0
  102. package/lib/components/form-builder/types/index.d.ts +5 -0
  103. package/lib/components/form-builder/types/schema.types.d.ts +227 -0
  104. package/lib/components/form-builder/types/territoriale.types.d.ts +170 -0
  105. package/lib/components/form-builder/types/validation.types.d.ts +174 -0
  106. package/lib/components/form-builder-editor/form-builder-editor.component.d.ts +117 -0
  107. package/lib/components/form-builder-editor/form-builder-editor.service.d.ts +38 -0
  108. package/lib/components/form-builder-editor/index.d.ts +15 -0
  109. package/lib/components/form-builder-editor/services/editor-persistence.service.d.ts +42 -0
  110. package/lib/components/form-builder-editor/services/editor-state.service.d.ts +66 -0
  111. package/lib/components/form-builder-editor/services/field-factory.service.d.ts +28 -0
  112. package/lib/components/form-builder-editor/sub-components/condition-editor/condition-editor.component.d.ts +139 -0
  113. package/lib/components/form-builder-editor/sub-components/editor-toolbar/editor-toolbar.component.d.ts +43 -0
  114. package/lib/components/form-builder-editor/sub-components/field-config-panel/field-config-panel.component.d.ts +83 -0
  115. package/lib/components/form-builder-editor/sub-components/field-palette/field-palette.component.d.ts +40 -0
  116. package/lib/components/form-builder-editor/sub-components/form-values-panel/form-values-panel.component.d.ts +51 -0
  117. package/lib/components/form-builder-editor/sub-components/options-editor/options-editor.component.d.ts +63 -0
  118. package/lib/components/form-builder-editor/sub-components/preview-container/preview-container.component.d.ts +68 -0
  119. package/lib/components/form-builder-editor/sub-components/section-editor/section-editor.component.d.ts +82 -0
  120. package/lib/components/form-builder-editor/sub-components/validation-editor/validation-editor.component.d.ts +112 -0
  121. package/lib/components/form-builder-editor/types/editor.types.d.ts +124 -0
  122. package/lib/components/layout-builder/index.d.ts +16 -0
  123. package/lib/components/layout-builder/layout-builder.component.d.ts +85 -0
  124. package/lib/components/layout-builder/layout-builder.types.d.ts +436 -0
  125. package/lib/components/layout-builder/layout.service.d.ts +100 -0
  126. package/lib/components/modal/confirm-dialog.component.d.ts +46 -0
  127. package/lib/components/modal/index.d.ts +4 -0
  128. package/lib/components/modal/modal.component.d.ts +44 -0
  129. package/lib/components/modal/modal.service.d.ts +93 -0
  130. package/lib/components/modal/modal.types.d.ts +110 -0
  131. package/lib/components/page-header/breadcrumb.service.d.ts +96 -0
  132. package/lib/components/page-header/index.d.ts +16 -0
  133. package/lib/components/page-header/page-header.component.d.ts +59 -0
  134. package/lib/components/page-header/page-header.types.d.ts +96 -0
  135. package/lib/components/table/index.d.ts +2 -0
  136. package/lib/components/table/paginated-table.component.d.ts +85 -0
  137. package/lib/components/table/table.types.d.ts +81 -0
  138. package/lib/core/types/index.d.ts +57 -0
  139. package/lib/core/utils/index.d.ts +29 -0
  140. package/package.json +44 -0
  141. package/public-api.d.ts +22 -0
@@ -0,0 +1,648 @@
1
+ import { Component, Input, forwardRef, ViewEncapsulation, } from '@angular/core';
2
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS, Validators, NgControl, ReactiveFormsModule, } from '@angular/forms';
3
+ import { Subject, combineLatest, takeUntil, distinctUntilChanged, startWith, map } from 'rxjs';
4
+ import { MatFormFieldModule } from '@angular/material/form-field';
5
+ import { MatSelectModule } from '@angular/material/select';
6
+ import { MatInputModule } from '@angular/material/input';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/forms";
9
+ import * as i2 from "../../services/location.service";
10
+ import * as i3 from "@angular/material/form-field";
11
+ import * as i4 from "@angular/material/select";
12
+ import * as i5 from "@angular/material/core";
13
+ import * as i6 from "@angular/material/input";
14
+ /**
15
+ * Componente standalone per la selezione di dati geografici italiani o esteri.
16
+ *
17
+ * Supporta due modalita:
18
+ * - **Italia**: selezione a cascata nazione -> provincia -> comune -> CAP
19
+ * - **Estero**: selezione nazione + campo testo libero per il comune
20
+ *
21
+ * Campi opzionali configurabili: indirizzo, mail, PEC, telefono.
22
+ *
23
+ * Implementa `ControlValueAccessor` e `Validator` per l'integrazione
24
+ * diretta con Angular Reactive Forms.
25
+ *
26
+ * Utilizza dati da JSON statici tramite `UiLocationService`
27
+ * (nessuna dipendenza al backend).
28
+ *
29
+ * @selector ui-specifica-territoriale
30
+ *
31
+ * @example
32
+ * ```html
33
+ * <ui-specifica-territoriale
34
+ * [formControl]="myControl"
35
+ * [config]="{ italyByDefault: true, cap: { show: true } }"
36
+ * />
37
+ * ```
38
+ */
39
+ export class UiSpecificaTerritorialeComponent {
40
+ constructor(fb, injector, cdr, locationService) {
41
+ this.fb = fb;
42
+ this.injector = injector;
43
+ this.cdr = cdr;
44
+ this.locationService = locationService;
45
+ /** Configurazione del componente. */
46
+ this.config = {};
47
+ /** Stato disabilitato globale. */
48
+ this.disabled = false;
49
+ // ─── Pattern di validazione ──────────────────────────────────────
50
+ this.EMAIL_PATTERN = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
51
+ this.PEC_PATTERN = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
52
+ this.PHONE_PATTERN = /^[+]?[0-9\s\-()]{6,16}$/;
53
+ this.isItalian = false;
54
+ this.isForeign = false;
55
+ /** Elenco nazioni disponibili. */
56
+ this.nazioni = [];
57
+ /** Elenco province disponibili. */
58
+ this.province = [];
59
+ /** Comuni filtrati per la provincia selezionata. */
60
+ this.filteredComuni = [];
61
+ /** CAP filtrati per il comune selezionato. */
62
+ this.filteredCaps = [];
63
+ /** Promise di inizializzazione (utile per test e table-territoriale). */
64
+ this.initializationPromise = null;
65
+ this.destroy$ = new Subject();
66
+ this.onChange = (_value) => { };
67
+ this.onTouched = () => { };
68
+ this.onValidatorChange = () => { };
69
+ this.subscriptionsInitialized = false;
70
+ this.pendingWriteValue = null;
71
+ this.isInitializing = false;
72
+ this.tipologicheLoaded = false;
73
+ this.initializeForm();
74
+ }
75
+ ngOnInit() {
76
+ this.setupNgControl();
77
+ this.initializationPromise = this.initializeComponent();
78
+ }
79
+ ngOnDestroy() {
80
+ this.destroy$.next();
81
+ this.destroy$.complete();
82
+ }
83
+ // ─── ControlValueAccessor ───────────────────────────────────────
84
+ writeValue(value) {
85
+ if (!this.tipologicheLoaded) {
86
+ this.pendingWriteValue = value;
87
+ return;
88
+ }
89
+ this.processWriteValue(value);
90
+ }
91
+ registerOnChange(fn) {
92
+ this.onChange = (value) => {
93
+ if (!this.isInitializing)
94
+ fn(value);
95
+ };
96
+ }
97
+ registerOnTouched(fn) {
98
+ this.onTouched = fn;
99
+ }
100
+ registerOnValidatorChange(fn) {
101
+ this.onValidatorChange = fn;
102
+ }
103
+ setDisabledState(isDisabled) {
104
+ this.disabled = isDisabled;
105
+ if (isDisabled) {
106
+ this.form.disable();
107
+ }
108
+ else {
109
+ this.form.enable();
110
+ this.applyFieldsDisabledState();
111
+ }
112
+ }
113
+ // ─── Validator ──────────────────────────────────────────────────
114
+ validate(_control) {
115
+ if (!this.form)
116
+ return null;
117
+ const errors = {};
118
+ const isNazioneRequired = this.config.nazione?.required !== false;
119
+ const isProvinciaRequired = this.config.provincia?.required !== false;
120
+ const isComuneRequired = this.config.comune?.required !== false;
121
+ const isComuneEsteroRequired = this.config.comuneEstero?.required !== false;
122
+ // Validazione nazione
123
+ if (isNazioneRequired && !this.form.get('nazioneId')?.value) {
124
+ errors['nazioneRequired'] = 'Seleziona una nazione';
125
+ }
126
+ // Validazioni Italia
127
+ if (this.isItalian) {
128
+ if (isProvinciaRequired && !this.form.get('provinciaId')?.value) {
129
+ errors['provinciaRequired'] = 'Seleziona una provincia';
130
+ }
131
+ if (isComuneRequired && !this.form.get('comuneId')?.value) {
132
+ errors['comuneRequired'] = 'Seleziona un comune';
133
+ }
134
+ if (this.config.cap?.required && this.showCAP && !this.form.get('cap')?.value) {
135
+ errors['capRequired'] = 'Inserisci il CAP';
136
+ }
137
+ if (this.config.indirizzo?.required && this.showIndirizzo) {
138
+ const v = this.form.get('indirizzo')?.value;
139
+ if (!v || v.trim() === '')
140
+ errors['indirizzoRequired'] = "Inserisci l'indirizzo";
141
+ }
142
+ this.validateContactFields(errors);
143
+ }
144
+ // Validazioni estero
145
+ if (this.isForeign) {
146
+ const comuneEstero = this.form.get('comuneEstero')?.value;
147
+ if (isComuneEsteroRequired && (!comuneEstero || comuneEstero.trim() === '')) {
148
+ errors['comuneEsteroRequired'] = 'Inserisci il comune estero';
149
+ }
150
+ }
151
+ return Object.keys(errors).length > 0 ? errors : null;
152
+ }
153
+ // ─── API pubblica ───────────────────────────────────────────────
154
+ /** Marca tutti i controlli interni come touched. */
155
+ markAsTouched() {
156
+ Object.values(this.form.controls).forEach((c) => c.markAsTouched());
157
+ this.cdr.detectChanges();
158
+ }
159
+ /** Verifica se mostrare gli errori per un campo interno. */
160
+ shouldShowFieldErrors(fieldKey) {
161
+ const control = this.form.get(fieldKey);
162
+ return !!(control?.invalid && (control.touched || control.dirty));
163
+ }
164
+ /** Errori di un campo interno come array di messaggi. */
165
+ getFieldErrors(fieldKey) {
166
+ const control = this.form.get(fieldKey);
167
+ if (!control?.errors)
168
+ return [];
169
+ const messages = [];
170
+ const errs = control.errors;
171
+ if (errs['required'])
172
+ messages.push('Campo obbligatorio');
173
+ if (errs['pattern'])
174
+ messages.push('Formato non valido');
175
+ if (errs['email'])
176
+ messages.push('Email non valida');
177
+ return messages;
178
+ }
179
+ /** Handler blur per propagare il touched. */
180
+ onBlur() {
181
+ this.onTouched();
182
+ }
183
+ /** Resetta lo stato del componente. */
184
+ resetComponentState() {
185
+ this.isItalian = false;
186
+ this.isForeign = false;
187
+ this.filteredComuni = [];
188
+ this.filteredCaps = [];
189
+ this.form.get('comuneId')?.disable({ emitEvent: false });
190
+ this.form.get('cap')?.disable({ emitEvent: false });
191
+ this.updateValidators();
192
+ }
193
+ // ─── Getter calcolati ───────────────────────────────────────────
194
+ /** Labels personalizzabili con valori di default. */
195
+ get labels() {
196
+ return {
197
+ nazione: this.config.labels?.nazione || 'Nazione',
198
+ provincia: this.config.labels?.provincia || 'Provincia',
199
+ comune: this.config.labels?.comune || 'Comune',
200
+ cap: this.config.labels?.cap || 'CAP',
201
+ indirizzo: this.config.labels?.indirizzo || 'Indirizzo',
202
+ comuneEstero: this.config.labels?.comuneEstero || 'Comune Estero',
203
+ mail: this.config.labels?.mail || 'Email',
204
+ pec: this.config.labels?.pec || 'PEC',
205
+ telefono: this.config.labels?.telefono || 'Telefono',
206
+ };
207
+ }
208
+ get hasValidationErrors() {
209
+ const externalInvalid = !!(this.ngControl?.control?.invalid &&
210
+ (this.ngControl.control.touched || this.ngControl.control.dirty));
211
+ if (externalInvalid)
212
+ return true;
213
+ const isInteracted = this.form?.touched || this.form?.dirty || this.ngControl?.control?.touched || this.ngControl?.control?.dirty;
214
+ if (isInteracted) {
215
+ return !!this.validate(null);
216
+ }
217
+ return false;
218
+ }
219
+ get validationErrors() {
220
+ // Errori esterni dal FormBuilder
221
+ if (this.ngControl?.control?.errors) {
222
+ const errors = [];
223
+ if (this.ngControl.control.errors['required']) {
224
+ errors.push('Inizia selezionando la nazione');
225
+ }
226
+ if (errors.length > 0)
227
+ return errors;
228
+ }
229
+ // Errori interni
230
+ const internalErrors = this.validate(null);
231
+ if (!internalErrors)
232
+ return [];
233
+ return Object.values(internalErrors);
234
+ }
235
+ get showCAP() {
236
+ return this.config.cap?.show !== false;
237
+ }
238
+ get showIndirizzo() {
239
+ return this.config.indirizzo?.show !== false;
240
+ }
241
+ get showMail() {
242
+ return this.config.mail?.show === true;
243
+ }
244
+ get showPEC() {
245
+ return this.config.pec?.show === true;
246
+ }
247
+ get showTelefono() {
248
+ return this.config.telefono?.show === true;
249
+ }
250
+ get capColumns() {
251
+ return this.config.cap?.columns || 6;
252
+ }
253
+ get indirizzoColumns() {
254
+ return this.config.indirizzo?.columns || 12;
255
+ }
256
+ get mailColumns() {
257
+ return this.config.mail?.columns || 6;
258
+ }
259
+ get pecColumns() {
260
+ return this.config.pec?.columns || 6;
261
+ }
262
+ get telefonoColumns() {
263
+ return this.config.telefono?.columns || 6;
264
+ }
265
+ get isItalyByDefault() {
266
+ return this.config.italyByDefault === true;
267
+ }
268
+ get isCapDisabled() {
269
+ const comuneId = this.form.get('comuneId')?.value;
270
+ return !comuneId || this.filteredCaps.length === 0 || this.filteredCaps.length === 1;
271
+ }
272
+ get isNazioneDisabled() {
273
+ return this.disabled || this.config.italyByDefault === true;
274
+ }
275
+ get isRequired() {
276
+ if (this.config.nazione?.required !== false)
277
+ return true;
278
+ if (!this.ngControl?.control)
279
+ return false;
280
+ const validator = this.ngControl.control.validator;
281
+ if (validator) {
282
+ const errors = validator({});
283
+ return !!errors?.['required'];
284
+ }
285
+ return false;
286
+ }
287
+ // ─── Inizializzazione ──────────────────────────────────────────
288
+ async initializeComponent() {
289
+ try {
290
+ await this.loadLocationData();
291
+ this.tipologicheLoaded = true;
292
+ if (this.pendingWriteValue !== null) {
293
+ this.processWriteValue(this.pendingWriteValue);
294
+ this.pendingWriteValue = null;
295
+ }
296
+ else {
297
+ this.applyInitialConfiguration();
298
+ }
299
+ if (!this.subscriptionsInitialized) {
300
+ this.setupFormSubscriptions();
301
+ this.subscriptionsInitialized = true;
302
+ }
303
+ }
304
+ catch (error) {
305
+ console.error('[UiSpecificaTerritoriale] Errore inizializzazione:', error);
306
+ this.tipologicheLoaded = false;
307
+ }
308
+ }
309
+ initializeForm() {
310
+ this.form = this.fb.group({
311
+ nazioneId: [null, Validators.required],
312
+ provinciaId: [null],
313
+ comuneId: [{ value: null, disabled: true }],
314
+ cap: [{ value: null, disabled: true }],
315
+ comuneEstero: [null],
316
+ indirizzo: [null],
317
+ mail: [null],
318
+ pec: [null],
319
+ telefono: [null],
320
+ });
321
+ }
322
+ setupNgControl() {
323
+ const ngControl = this.injector.get(NgControl, null, { self: true, optional: true });
324
+ if (ngControl) {
325
+ this.ngControl = ngControl;
326
+ this.ngControl.valueAccessor = this;
327
+ }
328
+ }
329
+ async loadLocationData() {
330
+ const [nazioniResult, provinceResult] = await Promise.all([
331
+ this.locationService.getNazioni(),
332
+ this.locationService.getProvince(),
333
+ ]);
334
+ this.nazioni = nazioniResult.data;
335
+ this.province = provinceResult.content;
336
+ }
337
+ // ─── Gestione writeValue ────────────────────────────────────────
338
+ processWriteValue(value) {
339
+ this.isInitializing = true;
340
+ if (value) {
341
+ const processedValue = this.handleItalyByDefaultValue(value);
342
+ this.form.patchValue(processedValue, { emitEvent: false });
343
+ this.updateComponentState(processedValue).then(() => {
344
+ this.applyInitialConfiguration();
345
+ this.isInitializing = false;
346
+ this.form.patchValue(processedValue, { emitEvent: true });
347
+ this.handleTerritorialChanges(processedValue.nazioneId || '', processedValue.provinciaId || '', processedValue.comuneId || '');
348
+ this.updateValidators();
349
+ Object.values(this.form.controls).forEach((ctrl) => ctrl.updateValueAndValidity({ emitEvent: false }));
350
+ this.form.updateValueAndValidity();
351
+ });
352
+ }
353
+ else {
354
+ this.form.reset(undefined, { emitEvent: false });
355
+ this.resetComponentState();
356
+ this.applyInitialConfiguration();
357
+ this.isInitializing = false;
358
+ }
359
+ }
360
+ handleItalyByDefaultValue(value) {
361
+ if (!this.config.italyByDefault)
362
+ return value;
363
+ if (value.nazioneId && value.nazioneId !== 'ITA') {
364
+ return { ...value, nazioneId: 'ITA', comuneEstero: undefined };
365
+ }
366
+ return value;
367
+ }
368
+ // ─── Subscriptions ──────────────────────────────────────────────
369
+ setupFormSubscriptions() {
370
+ // Subscription per i cambiamenti territoriali (nazione/provincia/comune)
371
+ combineLatest([
372
+ this.form
373
+ .get('nazioneId')
374
+ .valueChanges.pipe(startWith(this.form.get('nazioneId').value), distinctUntilChanged()),
375
+ this.form
376
+ .get('provinciaId')
377
+ .valueChanges.pipe(startWith(this.form.get('provinciaId').value), distinctUntilChanged()),
378
+ this.form.get('comuneId').valueChanges.pipe(startWith(this.form.get('comuneId').value), distinctUntilChanged()),
379
+ ])
380
+ .pipe(takeUntil(this.destroy$), map(([nazioneId, provinciaId, comuneId]) => ({ nazioneId, provinciaId, comuneId })))
381
+ .subscribe(({ nazioneId, provinciaId, comuneId }) => {
382
+ if (!this.isInitializing && this.tipologicheLoaded) {
383
+ this.handleTerritorialChanges(nazioneId, provinciaId, comuneId);
384
+ }
385
+ });
386
+ // Subscription per tutti i cambiamenti del form
387
+ this.form.valueChanges
388
+ .pipe(takeUntil(this.destroy$), distinctUntilChanged((prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)))
389
+ .subscribe((formValue) => {
390
+ if (!this.isInitializing && this.tipologicheLoaded) {
391
+ this.onChange(formValue);
392
+ this.notifyValidationChange();
393
+ }
394
+ });
395
+ this.cdr.detectChanges();
396
+ }
397
+ // ─── Logica territoriale ────────────────────────────────────────
398
+ async handleTerritorialChanges(nazioneId, provinciaId, comuneId) {
399
+ this.updateNationalityState(nazioneId);
400
+ await this.updateTerritorialData(provinciaId, comuneId);
401
+ this.updateValidators();
402
+ }
403
+ updateNationalityState(nazioneId) {
404
+ const nazione = this.nazioni.find((n) => n.codStatoPk === nazioneId);
405
+ this.isItalian = nazione?.codStatoPk === 'ITA';
406
+ this.isForeign = !!(nazione && nazione.codStatoPk !== 'ITA');
407
+ }
408
+ async updateTerritorialData(provinciaId, comuneId) {
409
+ if (this.isItalian && provinciaId) {
410
+ await this.updateFilteredComuni(provinciaId);
411
+ }
412
+ else {
413
+ this.filteredComuni = [];
414
+ }
415
+ if (this.isItalian && comuneId) {
416
+ await this.updateFilteredCaps(comuneId);
417
+ }
418
+ else {
419
+ this.filteredCaps = [];
420
+ }
421
+ this.applyFieldsDisabledState();
422
+ }
423
+ async updateFilteredComuni(provinciaId) {
424
+ if (!provinciaId) {
425
+ this.filteredComuni = [];
426
+ return;
427
+ }
428
+ try {
429
+ this.filteredComuni = await this.locationService.getComuniByProvincia(provinciaId);
430
+ const currentComuneId = this.form.get('comuneId')?.value;
431
+ if (currentComuneId && !this.filteredComuni.find((c) => c.codiceComunePk === currentComuneId)) {
432
+ this.form.patchValue({ comuneId: null }, { emitEvent: false });
433
+ }
434
+ }
435
+ catch {
436
+ this.filteredComuni = [];
437
+ }
438
+ }
439
+ async updateFilteredCaps(comuneId) {
440
+ if (!comuneId) {
441
+ this.filteredCaps = [];
442
+ this.form.patchValue({ cap: null }, { emitEvent: true });
443
+ return;
444
+ }
445
+ const caps = await this.locationService.getCapList(comuneId);
446
+ this.filteredCaps = caps.map((capCode) => ({ id: capCode, codice: capCode, comuneId }));
447
+ const currentCap = this.form.get('cap')?.value;
448
+ if (this.filteredCaps.length === 1) {
449
+ this.form.patchValue({ cap: this.filteredCaps[0].id }, { emitEvent: true });
450
+ }
451
+ else if (this.filteredCaps.length > 1) {
452
+ if (!currentCap || !this.filteredCaps.some((c) => c.id === currentCap)) {
453
+ this.form.patchValue({ cap: null }, { emitEvent: true });
454
+ }
455
+ }
456
+ else {
457
+ this.form.patchValue({ cap: null }, { emitEvent: true });
458
+ }
459
+ }
460
+ async updateComponentState(value) {
461
+ this.updateNationalityState(value.nazioneId || '');
462
+ await this.updateFilteredComuni(value.provinciaId || '');
463
+ await this.updateFilteredCaps(value.comuneId || '');
464
+ this.applyFieldsDisabledState();
465
+ this.updateValidators();
466
+ }
467
+ // ─── Stato campi ───────────────────────────────────────────────
468
+ applyFieldsDisabledState() {
469
+ if (this.disabled) {
470
+ this.form.disable({ emitEvent: false });
471
+ return;
472
+ }
473
+ const comuneControl = this.form.get('comuneId');
474
+ const capControl = this.form.get('cap');
475
+ const nazioneControl = this.form.get('nazioneId');
476
+ // Comune abilitato solo se Italia + provincia selezionata
477
+ if (this.isItalian && this.form.get('provinciaId')?.value) {
478
+ comuneControl?.enable({ emitEvent: false });
479
+ }
480
+ else {
481
+ comuneControl?.disable({ emitEvent: false });
482
+ }
483
+ // CAP segue logica specifica
484
+ if (this.isCapDisabled) {
485
+ capControl?.disable({ emitEvent: false });
486
+ }
487
+ else {
488
+ capControl?.enable({ emitEvent: false });
489
+ }
490
+ // Nazione disabilitata se italyByDefault
491
+ if (this.isItalyByDefault) {
492
+ nazioneControl?.disable({ emitEvent: false });
493
+ }
494
+ else {
495
+ nazioneControl?.enable({ emitEvent: false });
496
+ }
497
+ }
498
+ // ─── Validazione dinamica ──────────────────────────────────────
499
+ updateValidators() {
500
+ const controls = {
501
+ nazione: this.form.get('nazioneId'),
502
+ provincia: this.form.get('provinciaId'),
503
+ comune: this.form.get('comuneId'),
504
+ comuneEstero: this.form.get('comuneEstero'),
505
+ cap: this.form.get('cap'),
506
+ indirizzo: this.form.get('indirizzo'),
507
+ mail: this.form.get('mail'),
508
+ pec: this.form.get('pec'),
509
+ telefono: this.form.get('telefono'),
510
+ };
511
+ // Pulisci tutti i validatori
512
+ Object.values(controls).forEach((c) => c?.clearValidators());
513
+ // Nazione
514
+ if (this.config.nazione?.required !== false) {
515
+ controls['nazione']?.setValidators(Validators.required);
516
+ }
517
+ if (this.isItalian) {
518
+ if (this.config.provincia?.required !== false) {
519
+ controls['provincia']?.setValidators(Validators.required);
520
+ }
521
+ if (this.config.comune?.required !== false) {
522
+ controls['comune']?.setValidators(Validators.required);
523
+ }
524
+ if (this.config.cap?.required && this.showCAP) {
525
+ controls['cap']?.setValidators(Validators.required);
526
+ }
527
+ if (this.config.indirizzo?.required && this.showIndirizzo) {
528
+ controls['indirizzo']?.setValidators(Validators.required);
529
+ }
530
+ this.applyContactValidators(controls);
531
+ }
532
+ else if (this.isForeign) {
533
+ if (this.config.comuneEstero?.required !== false) {
534
+ controls['comuneEstero']?.setValidators(Validators.required);
535
+ }
536
+ }
537
+ // Aggiorna senza emettere eventi
538
+ Object.values(controls).forEach((c) => c?.updateValueAndValidity({ emitEvent: false }));
539
+ this.notifyValidationChange();
540
+ }
541
+ applyContactValidators(controls) {
542
+ if (this.config.mail?.required && this.showMail) {
543
+ controls['mail']?.setValidators([Validators.required, Validators.pattern(this.EMAIL_PATTERN)]);
544
+ }
545
+ else if (this.showMail) {
546
+ controls['mail']?.setValidators([Validators.pattern(this.EMAIL_PATTERN)]);
547
+ }
548
+ if (this.config.pec?.required && this.showPEC) {
549
+ controls['pec']?.setValidators([Validators.required, Validators.pattern(this.PEC_PATTERN)]);
550
+ }
551
+ else if (this.showPEC) {
552
+ controls['pec']?.setValidators([Validators.pattern(this.PEC_PATTERN)]);
553
+ }
554
+ if (this.config.telefono?.required && this.showTelefono) {
555
+ controls['telefono']?.setValidators([Validators.required, Validators.pattern(this.PHONE_PATTERN)]);
556
+ }
557
+ else if (this.showTelefono) {
558
+ controls['telefono']?.setValidators([Validators.pattern(this.PHONE_PATTERN)]);
559
+ }
560
+ }
561
+ validateContactFields(errors) {
562
+ if (this.config.mail?.required && this.showMail) {
563
+ const v = this.form.get('mail')?.value;
564
+ if (!v || v.trim() === '') {
565
+ errors['mailRequired'] = "Inserisci l'email";
566
+ }
567
+ else if (!this.EMAIL_PATTERN.test(v)) {
568
+ errors['mailInvalid'] = "Inserisci un'email valida";
569
+ }
570
+ }
571
+ if (this.config.pec?.required && this.showPEC) {
572
+ const v = this.form.get('pec')?.value;
573
+ if (!v || v.trim() === '') {
574
+ errors['pecRequired'] = 'Inserisci la PEC';
575
+ }
576
+ else if (!this.PEC_PATTERN.test(v)) {
577
+ errors['pecInvalid'] = 'Inserisci una PEC valida';
578
+ }
579
+ }
580
+ if (this.config.telefono?.required && this.showTelefono) {
581
+ const v = this.form.get('telefono')?.value;
582
+ if (!v || v.trim() === '') {
583
+ errors['telefonoRequired'] = 'Inserisci il telefono';
584
+ }
585
+ else if (!this.PHONE_PATTERN.test(v)) {
586
+ errors['telefonoInvalid'] = 'Inserisci un numero di telefono valido';
587
+ }
588
+ }
589
+ }
590
+ // ─── Configurazione iniziale ───────────────────────────────────
591
+ applyInitialConfiguration() {
592
+ const nazioneControl = this.form.get('nazioneId');
593
+ const currentNazioneId = nazioneControl?.value;
594
+ if (this.config.italyByDefault) {
595
+ const italia = this.nazioni.find((n) => n.codStatoPk === 'ITA');
596
+ if (italia && (!currentNazioneId || currentNazioneId !== 'ITA')) {
597
+ this.form.patchValue({ nazioneId: italia.codStatoPk }, { emitEvent: false });
598
+ }
599
+ this.updateNationalityState('ITA');
600
+ nazioneControl?.disable({ emitEvent: false });
601
+ }
602
+ else {
603
+ if (currentNazioneId)
604
+ this.updateNationalityState(currentNazioneId);
605
+ if (!this.disabled)
606
+ nazioneControl?.enable({ emitEvent: false });
607
+ }
608
+ this.updateValidators();
609
+ }
610
+ notifyValidationChange() {
611
+ if (this.onValidatorChange) {
612
+ setTimeout(() => this.onValidatorChange(), 0);
613
+ }
614
+ }
615
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UiSpecificaTerritorialeComponent, deps: [{ token: i1.FormBuilder }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }, { token: i2.UiLocationService }], target: i0.ɵɵFactoryTarget.Component }); }
616
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: UiSpecificaTerritorialeComponent, isStandalone: true, selector: "ui-specifica-territoriale", inputs: { config: "config", disabled: "disabled" }, providers: [
617
+ {
618
+ provide: NG_VALUE_ACCESSOR,
619
+ useExisting: forwardRef(() => UiSpecificaTerritorialeComponent),
620
+ multi: true,
621
+ },
622
+ {
623
+ provide: NG_VALIDATORS,
624
+ useExisting: forwardRef(() => UiSpecificaTerritorialeComponent),
625
+ multi: true,
626
+ },
627
+ ], ngImport: i0, template: "<!--\r\n Componente per la selezione di dati geografici (Italia/Estero).\r\n Utilizza il flow control moderno di Angular (@if, @for).\r\n-->\r\n<div\r\n class=\"ui-location\"\r\n [formGroup]=\"form\"\r\n [class.ui-location--foreign]=\"isForeign\"\r\n [class.ui-location--italian]=\"isItalian\"\r\n>\r\n <!-- ==================== NAZIONE ==================== -->\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field\r\n appearance=\"outline\"\r\n class=\"ui-location__full-width\"\r\n [class.ui-location__italy-default]=\"config.italyByDefault\"\r\n >\r\n <mat-label>{{ labels.nazione }}</mat-label>\r\n <mat-select\r\n formControlName=\"nazioneId\"\r\n [disabled]=\"disabled || isNazioneDisabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona nazione\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona nazione</mat-option>\r\n @for (nazione of nazioni; track nazione.codStatoPk) {\r\n <mat-option [value]=\"nazione.codStatoPk\">\r\n {{ nazione.descrizione }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('nazioneId')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('nazioneId'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- ==================== CAMPI ITALIA ==================== -->\r\n @if (isItalian) {\r\n <div class=\"ui-location__provincia-comune\">\r\n <!-- Provincia -->\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.provincia }}</mat-label>\r\n <mat-select\r\n formControlName=\"provinciaId\"\r\n [disabled]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona provincia\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona provincia</mat-option>\r\n @for (prov of province; track prov.codiceProvinciaPk) {\r\n <mat-option [value]=\"prov.codiceProvinciaPk\">\r\n {{ prov.nomeProvincia }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('provinciaId')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('provinciaId'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- Comune -->\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.comune }}</mat-label>\r\n <mat-select\r\n formControlName=\"comuneId\"\r\n [disabled]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona comune\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona comune</mat-option>\r\n @for (comune of filteredComuni; track comune.codiceComunePk) {\r\n <mat-option [value]=\"comune.codiceComunePk\">\r\n {{ comune.nomeComune }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('comuneId')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('comuneId'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n\r\n <!-- ==================== GRIGLIA CAMPI DINAMICI ==================== -->\r\n <div class=\"ui-location__dynamic-grid\">\r\n <!-- CAP -->\r\n @if (showCAP && isItalian) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + capColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.cap }}</mat-label>\r\n <mat-select\r\n formControlName=\"cap\"\r\n [disabled]=\"disabled || isCapDisabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona CAP\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona CAP</mat-option>\r\n @for (cap of filteredCaps; track cap.id) {\r\n <mat-option [value]=\"cap.id\">{{ cap.codice }}</mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('cap')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('cap'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- Indirizzo -->\r\n @if (showIndirizzo) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + indirizzoColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.indirizzo }}</mat-label>\r\n <input\r\n matInput\r\n formControlName=\"indirizzo\"\r\n placeholder=\"Via, numero civico\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('indirizzo')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('indirizzo'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- Mail -->\r\n @if (showMail) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + mailColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.mail }}</mat-label>\r\n <input\r\n matInput\r\n type=\"email\"\r\n formControlName=\"mail\"\r\n placeholder=\"esempio@email.com\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('mail')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('mail'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- PEC -->\r\n @if (showPEC) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + pecColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.pec }}</mat-label>\r\n <input\r\n matInput\r\n type=\"email\"\r\n formControlName=\"pec\"\r\n placeholder=\"esempio@pec.it\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('pec')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('pec'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- Telefono -->\r\n @if (showTelefono) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + telefonoColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.telefono }}</mat-label>\r\n <input\r\n matInput\r\n type=\"tel\"\r\n formControlName=\"telefono\"\r\n placeholder=\"+39 123 456 7890\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('telefono')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('telefono'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ==================== CAMPO ESTERO ==================== -->\r\n @if (isForeign) {\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.comuneEstero }}</mat-label>\r\n <input\r\n matInput\r\n formControlName=\"comuneEstero\"\r\n placeholder=\"Inserisci citta/comune\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('comuneEstero')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('comuneEstero'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".ui-location{display:flex;flex-direction:column;gap:var(--ui-spacing-1, .25rem);width:100%}.ui-location__field-row{display:flex;width:100%}.ui-location__full-width{width:100%}.ui-location__italy-default .mat-mdc-select-disabled,.ui-location__italy-default .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--ui-color-text, rgba(0, 0, 0, .87))!important}.ui-location__provincia-comune{display:grid;grid-template-columns:1fr 1fr;gap:var(--ui-spacing-5, 1.25rem)}.ui-location__dynamic-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--ui-spacing-4, 1rem);width:100%;margin-top:var(--ui-spacing-2, .5rem)}.ui-location__grid-cell mat-form-field{width:100%}.ui-location mat-form-field.mat-form-field-disabled{opacity:.6}.ui-location--foreign{display:grid!important;grid-template-columns:1fr 1fr;gap:var(--ui-spacing-5, 1.25rem)}@media (max-width: 768px){.ui-location{gap:var(--ui-spacing-3, .75rem)}.ui-location__field-row{flex-direction:column}.ui-location__provincia-comune,.ui-location__dynamic-grid{grid-template-columns:1fr;gap:var(--ui-spacing-3, .75rem)}.ui-location__dynamic-grid .ui-location__grid-cell{grid-column:span 1!important}.ui-location--foreign{grid-template-columns:1fr}}@media (min-width: 769px) and (max-width: 1024px){.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 1\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 2\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 3\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 4\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 5\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 6\"]{grid-column:span 6}.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 7\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 8\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 9\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 10\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 11\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 12\"]{grid-column:span 12}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { 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: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.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"] }], encapsulation: i0.ViewEncapsulation.None }); }
628
+ }
629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UiSpecificaTerritorialeComponent, decorators: [{
630
+ type: Component,
631
+ args: [{ selector: 'ui-specifica-territoriale', standalone: true, imports: [ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatInputModule], providers: [
632
+ {
633
+ provide: NG_VALUE_ACCESSOR,
634
+ useExisting: forwardRef(() => UiSpecificaTerritorialeComponent),
635
+ multi: true,
636
+ },
637
+ {
638
+ provide: NG_VALIDATORS,
639
+ useExisting: forwardRef(() => UiSpecificaTerritorialeComponent),
640
+ multi: true,
641
+ },
642
+ ], encapsulation: ViewEncapsulation.None, template: "<!--\r\n Componente per la selezione di dati geografici (Italia/Estero).\r\n Utilizza il flow control moderno di Angular (@if, @for).\r\n-->\r\n<div\r\n class=\"ui-location\"\r\n [formGroup]=\"form\"\r\n [class.ui-location--foreign]=\"isForeign\"\r\n [class.ui-location--italian]=\"isItalian\"\r\n>\r\n <!-- ==================== NAZIONE ==================== -->\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field\r\n appearance=\"outline\"\r\n class=\"ui-location__full-width\"\r\n [class.ui-location__italy-default]=\"config.italyByDefault\"\r\n >\r\n <mat-label>{{ labels.nazione }}</mat-label>\r\n <mat-select\r\n formControlName=\"nazioneId\"\r\n [disabled]=\"disabled || isNazioneDisabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona nazione\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona nazione</mat-option>\r\n @for (nazione of nazioni; track nazione.codStatoPk) {\r\n <mat-option [value]=\"nazione.codStatoPk\">\r\n {{ nazione.descrizione }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('nazioneId')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('nazioneId'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- ==================== CAMPI ITALIA ==================== -->\r\n @if (isItalian) {\r\n <div class=\"ui-location__provincia-comune\">\r\n <!-- Provincia -->\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.provincia }}</mat-label>\r\n <mat-select\r\n formControlName=\"provinciaId\"\r\n [disabled]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona provincia\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona provincia</mat-option>\r\n @for (prov of province; track prov.codiceProvinciaPk) {\r\n <mat-option [value]=\"prov.codiceProvinciaPk\">\r\n {{ prov.nomeProvincia }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('provinciaId')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('provinciaId'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- Comune -->\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.comune }}</mat-label>\r\n <mat-select\r\n formControlName=\"comuneId\"\r\n [disabled]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona comune\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona comune</mat-option>\r\n @for (comune of filteredComuni; track comune.codiceComunePk) {\r\n <mat-option [value]=\"comune.codiceComunePk\">\r\n {{ comune.nomeComune }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('comuneId')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('comuneId'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n\r\n <!-- ==================== GRIGLIA CAMPI DINAMICI ==================== -->\r\n <div class=\"ui-location__dynamic-grid\">\r\n <!-- CAP -->\r\n @if (showCAP && isItalian) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + capColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.cap }}</mat-label>\r\n <mat-select\r\n formControlName=\"cap\"\r\n [disabled]=\"disabled || isCapDisabled\"\r\n (blur)=\"onBlur()\"\r\n aria-label=\"Seleziona CAP\"\r\n >\r\n <mat-option [value]=\"null\">Seleziona CAP</mat-option>\r\n @for (cap of filteredCaps; track cap.id) {\r\n <mat-option [value]=\"cap.id\">{{ cap.codice }}</mat-option>\r\n }\r\n </mat-select>\r\n @if (shouldShowFieldErrors('cap')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('cap'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- Indirizzo -->\r\n @if (showIndirizzo) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + indirizzoColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.indirizzo }}</mat-label>\r\n <input\r\n matInput\r\n formControlName=\"indirizzo\"\r\n placeholder=\"Via, numero civico\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('indirizzo')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('indirizzo'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- Mail -->\r\n @if (showMail) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + mailColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.mail }}</mat-label>\r\n <input\r\n matInput\r\n type=\"email\"\r\n formControlName=\"mail\"\r\n placeholder=\"esempio@email.com\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('mail')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('mail'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- PEC -->\r\n @if (showPEC) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + pecColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.pec }}</mat-label>\r\n <input\r\n matInput\r\n type=\"email\"\r\n formControlName=\"pec\"\r\n placeholder=\"esempio@pec.it\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('pec')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('pec'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n\r\n <!-- Telefono -->\r\n @if (showTelefono) {\r\n <div class=\"ui-location__grid-cell\" [style.grid-column]=\"'span ' + telefonoColumns\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.telefono }}</mat-label>\r\n <input\r\n matInput\r\n type=\"tel\"\r\n formControlName=\"telefono\"\r\n placeholder=\"+39 123 456 7890\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('telefono')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('telefono'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ==================== CAMPO ESTERO ==================== -->\r\n @if (isForeign) {\r\n <div class=\"ui-location__field-row\">\r\n <mat-form-field appearance=\"outline\" class=\"ui-location__full-width\">\r\n <mat-label>{{ labels.comuneEstero }}</mat-label>\r\n <input\r\n matInput\r\n formControlName=\"comuneEstero\"\r\n placeholder=\"Inserisci citta/comune\"\r\n [readonly]=\"disabled\"\r\n (blur)=\"onBlur()\"\r\n />\r\n @if (shouldShowFieldErrors('comuneEstero')) {\r\n <mat-error>\r\n @for (error of getFieldErrors('comuneEstero'); track $index) {\r\n <div>{{ error }}</div>\r\n }\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".ui-location{display:flex;flex-direction:column;gap:var(--ui-spacing-1, .25rem);width:100%}.ui-location__field-row{display:flex;width:100%}.ui-location__full-width{width:100%}.ui-location__italy-default .mat-mdc-select-disabled,.ui-location__italy-default .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--ui-color-text, rgba(0, 0, 0, .87))!important}.ui-location__provincia-comune{display:grid;grid-template-columns:1fr 1fr;gap:var(--ui-spacing-5, 1.25rem)}.ui-location__dynamic-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--ui-spacing-4, 1rem);width:100%;margin-top:var(--ui-spacing-2, .5rem)}.ui-location__grid-cell mat-form-field{width:100%}.ui-location mat-form-field.mat-form-field-disabled{opacity:.6}.ui-location--foreign{display:grid!important;grid-template-columns:1fr 1fr;gap:var(--ui-spacing-5, 1.25rem)}@media (max-width: 768px){.ui-location{gap:var(--ui-spacing-3, .75rem)}.ui-location__field-row{flex-direction:column}.ui-location__provincia-comune,.ui-location__dynamic-grid{grid-template-columns:1fr;gap:var(--ui-spacing-3, .75rem)}.ui-location__dynamic-grid .ui-location__grid-cell{grid-column:span 1!important}.ui-location--foreign{grid-template-columns:1fr}}@media (min-width: 769px) and (max-width: 1024px){.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 1\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 2\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 3\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 4\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 5\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 6\"]{grid-column:span 6}.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 7\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 8\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 9\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 10\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 11\"],.ui-location__dynamic-grid .ui-location__grid-cell[style*=\"span 12\"]{grid-column:span 12}}\n"] }]
643
+ }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }, { type: i2.UiLocationService }], propDecorators: { config: [{
644
+ type: Input
645
+ }], disabled: [{
646
+ type: Input
647
+ }] } });
648
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlY2lmaWNhLXRlcnJpdG9yaWFsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9uZy11aS1zeXN0ZW0vc3JjL2xpYi9jb21wb25lbnRzL2Zvcm0tYnVpbGRlci9zdWItY29tcG9uZW50cy9zcGVjaWZpY2EtdGVycml0b3JpYWxlL3NwZWNpZmljYS10ZXJyaXRvcmlhbGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbmctdWktc3lzdGVtL3NyYy9saWIvY29tcG9uZW50cy9mb3JtLWJ1aWxkZXIvc3ViLWNvbXBvbmVudHMvc3BlY2lmaWNhLXRlcnJpdG9yaWFsZS9zcGVjaWZpY2EtdGVycml0b3JpYWxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLFVBQVUsRUFLVixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUlMLGlCQUFpQixFQUNqQixhQUFhLEVBSWIsVUFBVSxFQUVWLFNBQVMsRUFDVCxtQkFBbUIsR0FDcEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsb0JBQW9CLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7Ozs7OztBQWdCekQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRztBQXFCSCxNQUFNLE9BQU8sZ0NBQWdDO0lBdUMzQyxZQUNtQixFQUFlLEVBQ2YsUUFBa0Is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c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBJbnB1dCxcclxuICBmb3J3YXJkUmVmLFxyXG4gIE9uSW5pdCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgSW5qZWN0b3IsXHJcbiAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQ29udHJvbFZhbHVlQWNjZXNzb3IsXHJcbiAgRm9ybUJ1aWxkZXIsXHJcbiAgRm9ybUdyb3VwLFxyXG4gIE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gIE5HX1ZBTElEQVRPUlMsXHJcbiAgRm9ybUNvbnRyb2wsXHJcbiAgQWJzdHJhY3RDb250cm9sLFxyXG4gIFZhbGlkYXRpb25FcnJvcnMsXHJcbiAgVmFsaWRhdG9ycyxcclxuICBWYWxpZGF0b3IsXHJcbiAgTmdDb250cm9sLFxyXG4gIFJlYWN0aXZlRm9ybXNNb2R1bGUsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCB0YWtlVW50aWwsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBzdGFydFdpdGgsIG1hcCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcclxuaW1wb3J0IHsgTWF0U2VsZWN0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcclxuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XHJcbmltcG9ydCB7IFVpTG9jYXRpb25TZXJ2aWNlLCBVaU5hemlvbmUsIFVpUHJvdmluY2lhLCBVaUNvbXVuZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2xvY2F0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBVaUxvY2F0aW9uQ29uZmlnLCBVaUxvY2F0aW9uVmFsdWUgfSBmcm9tICcuLi8uLi90eXBlcy90ZXJyaXRvcmlhbGUudHlwZXMnO1xyXG5cclxuLyoqXHJcbiAqIEludGVyZmFjY2lhIGludGVybmEgcGVyIGkgQ0FQIG5lbCBjb21wb25lbnRlLlxyXG4gKi9cclxuaW50ZXJmYWNlIFVpQ2FwT3B0aW9uIHtcclxuICAvKiogSUQgZGVsIENBUC4gKi9cclxuICBpZDogc3RyaW5nO1xyXG4gIC8qKiBDb2RpY2UgQ0FQIHZpc3VhbGl6emF0by4gKi9cclxuICBjb2RpY2U6IHN0cmluZztcclxuICAvKiogSUQgZGVsIGNvbXVuZSBhc3NvY2lhdG8uICovXHJcbiAgY29tdW5lSWQ6IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbXBvbmVudGUgc3RhbmRhbG9uZSBwZXIgbGEgc2VsZXppb25lIGRpIGRhdGkgZ2VvZ3JhZmljaSBpdGFsaWFuaSBvIGVzdGVyaS5cclxuICpcclxuICogU3VwcG9ydGEgZHVlIG1vZGFsaXRhOlxyXG4gKiAtICoqSXRhbGlhKio6IHNlbGV6aW9uZSBhIGNhc2NhdGEgbmF6aW9uZSAtPiBwcm92aW5jaWEgLT4gY29tdW5lIC0+IENBUFxyXG4gKiAtICoqRXN0ZXJvKio6IHNlbGV6aW9uZSBuYXppb25lICsgY2FtcG8gdGVzdG8gbGliZXJvIHBlciBpbCBjb211bmVcclxuICpcclxuICogQ2FtcGkgb3B6aW9uYWxpIGNvbmZpZ3VyYWJpbGk6IGluZGlyaXp6bywgbWFpbCwgUEVDLCB0ZWxlZm9uby5cclxuICpcclxuICogSW1wbGVtZW50YSBgQ29udHJvbFZhbHVlQWNjZXNzb3JgIGUgYFZhbGlkYXRvcmAgcGVyIGwnaW50ZWdyYXppb25lXHJcbiAqIGRpcmV0dGEgY29uIEFuZ3VsYXIgUmVhY3RpdmUgRm9ybXMuXHJcbiAqXHJcbiAqIFV0aWxpenphIGRhdGkgZGEgSlNPTiBzdGF0aWNpIHRyYW1pdGUgYFVpTG9jYXRpb25TZXJ2aWNlYFxyXG4gKiAobmVzc3VuYSBkaXBlbmRlbnphIGFsIGJhY2tlbmQpLlxyXG4gKlxyXG4gKiBAc2VsZWN0b3IgdWktc3BlY2lmaWNhLXRlcnJpdG9yaWFsZVxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGBodG1sXHJcbiAqIDx1aS1zcGVjaWZpY2EtdGVycml0b3JpYWxlXHJcbiAqICAgW2Zvcm1Db250cm9sXT1cIm15Q29udHJvbFwiXHJcbiAqICAgW2NvbmZpZ109XCJ7IGl0YWx5QnlEZWZhdWx0OiB0cnVlLCBjYXA6IHsgc2hvdzogdHJ1ZSB9IH1cIlxyXG4gKiAvPlxyXG4gKiBgYGBcclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAndWktc3BlY2lmaWNhLXRlcnJpdG9yaWFsZScsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbUmVhY3RpdmVGb3Jtc01vZHVsZSwgTWF0Rm9ybUZpZWxkTW9kdWxlLCBNYXRTZWxlY3RNb2R1bGUsIE1hdElucHV0TW9kdWxlXSxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFVpU3BlY2lmaWNhVGVycml0b3JpYWxlQ29tcG9uZW50KSxcclxuICAgICAgbXVsdGk6IHRydWUsXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBwcm92aWRlOiBOR19WQUxJREFUT1JTLFxyXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBVaVNwZWNpZmljYVRlcnJpdG9yaWFsZUNvbXBvbmVudCksXHJcbiAgICAgIG11bHRpOiB0cnVlLFxyXG4gICAgfSxcclxuICBdLFxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3NwZWNpZmljYS10ZXJyaXRvcmlhbGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9zcGVjaWZpY2EtdGVycml0b3JpYWxlLmNvbXBvbmVudC5zY3NzJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFVpU3BlY2lmaWNhVGVycml0b3JpYWxlQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIFZhbGlkYXRvciwgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIC8qKiBDb25maWd1cmF6aW9uZSBkZWwgY29tcG9uZW50ZS4gKi9cclxuICBASW5wdXQoKSBjb25maWc6IFVpTG9jYXRpb25Db25maWcgPSB7fTtcclxuXHJcbiAgLyoqIFN0YXRvIGRpc2FiaWxpdGF0byBnbG9iYWxlLiAqL1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBQYXR0ZXJuIGRpIHZhbGlkYXppb25lIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4gIHByaXZhdGUgcmVhZG9ubHkgRU1BSUxfUEFUVEVSTiA9IC9eW2EtekEtWjAtOS5fJSstXStAW2EtekEtWjAtOS4tXStcXC5bYS16QS1aXXsyLH0kLztcclxuICBwcml2YXRlIHJlYWRvbmx5IFBFQ19QQVRURVJOID0gL15bYS16QS1aMC05Ll8lKy1dK0BbYS16QS1aMC05Li1dK1xcLlthLXpBLVpdezIsfSQvO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgUEhPTkVfUEFUVEVSTiA9IC9eWytdP1swLTlcXHNcXC0oKV17NiwxNn0kLztcclxuXHJcbiAgLy8g4pSA4pSA4pSAIFN0YXRvIGludGVybm8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbiAgZm9ybSE6IEZvcm1Hcm91cDtcclxuICBpc0l0YWxpYW4gPSBmYWxzZTtcclxuICBpc0ZvcmVpZ24gPSBmYWxzZTtcclxuICBuZ0NvbnRyb2whOiBOZ0NvbnRyb2w7XHJcblxyXG4gIC8qKiBFbGVuY28gbmF6aW9uaSBkaXNwb25pYmlsaS4gKi9cclxuICBuYXppb25pOiBVaU5hemlvbmVbXSA9IFtdO1xyXG4gIC8qKiBFbGVuY28gcHJvdmluY2UgZGlzcG9uaWJpbGkuICovXHJcbiAgcHJvdmluY2U6IFVpUHJvdmluY2lhW10gPSBbXTtcclxuICAvKiogQ29tdW5pIGZpbHRyYXRpIHBlciBsYSBwcm92aW5jaWEgc2VsZXppb25hdGEuICovXHJcbiAgZmlsdGVyZWRDb211bmk6IFVpQ29tdW5lW10gPSBbXTtcclxuICAvKiogQ0FQIGZpbHRyYXRpIHBlciBpbCBjb211bmUgc2VsZXppb25hdG8uICovXHJcbiAgZmlsdGVyZWRDYXBzOiBVaUNhcE9wdGlvbltdID0gW107XHJcblxyXG4gIC8qKiBQcm9taXNlIGRpIGluaXppYWxpenphemlvbmUgKHV0aWxlIHBlciB0ZXN0IGUgdGFibGUtdGVycml0b3JpYWxlKS4gKi9cclxuICBpbml0aWFsaXphdGlvblByb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcbiAgcHJpdmF0ZSBvbkNoYW5nZSA9IChfdmFsdWU6IFVpTG9jYXRpb25WYWx1ZSkgPT4ge307XHJcbiAgcHJpdmF0ZSBvblRvdWNoZWQgPSAoKSA9PiB7fTtcclxuICBwcml2YXRlIG9uVmFsaWRhdG9yQ2hhbmdlID0gKCkgPT4ge307XHJcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zSW5pdGlhbGl6ZWQgPSBmYWxzZTtcclxuICBwcml2YXRlIHBlbmRpbmdXcml0ZVZhbHVlOiBVaUxvY2F0aW9uVmFsdWUgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIGlzSW5pdGlhbGl6aW5nID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSB0aXBvbG9naWNoZUxvYWRlZCA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZmI6IEZvcm1CdWlsZGVyLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBpbmplY3RvcjogSW5qZWN0b3IsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvY2F0aW9uU2VydmljZTogVWlMb2NhdGlvblNlcnZpY2UsXHJcbiAgKSB7XHJcbiAgICB0aGlzLmluaXRpYWxpemVGb3JtKCk7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuc2V0dXBOZ0NvbnRyb2woKTtcclxuICAgIHRoaXMuaW5pdGlhbGl6YXRpb25Qcm9taXNlID0gdGhpcy5pbml0aWFsaXplQ29tcG9uZW50KCk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xyXG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIENvbnRyb2xWYWx1ZUFjY2Vzc29yIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICB3cml0ZVZhbHVlKHZhbHVlOiBVaUxvY2F0aW9uVmFsdWUgfCBudWxsKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMudGlwb2xvZ2ljaGVMb2FkZWQpIHtcclxuICAgICAgdGhpcy5wZW5kaW5nV3JpdGVWYWx1ZSA9IHZhbHVlO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLnByb2Nlc3NXcml0ZVZhbHVlKHZhbHVlKTtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogVWlMb2NhdGlvblZhbHVlKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICB0aGlzLm9uQ2hhbmdlID0gKHZhbHVlKSA9PiB7XHJcbiAgICAgIGlmICghdGhpcy5pc0luaXRpYWxpemluZykgZm4odmFsdWUpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPblZhbGlkYXRvckNoYW5nZShmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgdGhpcy5vblZhbGlkYXRvckNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcclxuICAgIGlmIChpc0Rpc2FibGVkKSB7XHJcbiAgICAgIHRoaXMuZm9ybS5kaXNhYmxlKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZvcm0uZW5hYmxlKCk7XHJcbiAgICAgIHRoaXMuYXBwbHlGaWVsZHNEaXNhYmxlZFN0YXRlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgVmFsaWRhdG9yIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICB2YWxpZGF0ZShfY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xyXG4gICAgaWYgKCF0aGlzLmZvcm0pIHJldHVybiBudWxsO1xyXG5cclxuICAgIGNvbnN0IGVycm9yczogVmFsaWRhdGlvbkVycm9ycyA9IHt9O1xyXG4gICAgY29uc3QgaXNOYXppb25lUmVxdWlyZWQgPSB0aGlzLmNvbmZpZy5uYXppb25lPy5yZXF1aXJlZCAhPT0gZmFsc2U7XHJcbiAgICBjb25zdCBpc1Byb3ZpbmNpYVJlcXVpcmVkID0gdGhpcy5jb25maWcucHJvdmluY2lhPy5yZXF1aXJlZCAhPT0gZmFsc2U7XHJcbiAgICBjb25zdCBpc0NvbXVuZVJlcXVpcmVkID0gdGhpcy5jb25maWcuY29tdW5lPy5yZXF1aXJlZCAhPT0gZmFsc2U7XHJcbiAgICBjb25zdCBpc0NvbXVuZUVzdGVyb1JlcXVpcmVkID0gdGhpcy5jb25maWcuY29tdW5lRXN0ZXJvPy5yZXF1aXJlZCAhPT0gZmFsc2U7XHJcblxyXG4gICAgLy8gVmFsaWRhemlvbmUgbmF6aW9uZVxyXG4gICAgaWYgKGlzTmF6aW9uZVJlcXVpcmVkICYmICF0aGlzLmZvcm0uZ2V0KCduYXppb25lSWQnKT8udmFsdWUpIHtcclxuICAgICAgZXJyb3JzWyduYXppb25lUmVxdWlyZWQnXSA9ICdTZWxlemlvbmEgdW5hIG5hemlvbmUnO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFZhbGlkYXppb25pIEl0YWxpYVxyXG4gICAgaWYgKHRoaXMuaXNJdGFsaWFuKSB7XHJcbiAgICAgIGlmIChpc1Byb3ZpbmNpYVJlcXVpcmVkICYmICF0aGlzLmZvcm0uZ2V0KCdwcm92aW5jaWFJZCcpPy52YWx1ZSkge1xyXG4gICAgICAgIGVycm9yc1sncHJvdmluY2lhUmVxdWlyZWQnXSA9ICdTZWxlemlvbmEgdW5hIHByb3ZpbmNpYSc7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGlzQ29tdW5lUmVxdWlyZWQgJiYgIXRoaXMuZm9ybS5nZXQoJ2NvbXVuZUlkJyk/LnZhbHVlKSB7XHJcbiAgICAgICAgZXJyb3JzWydjb211bmVSZXF1aXJlZCddID0gJ1NlbGV6aW9uYSB1biBjb211bmUnO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5jYXA/LnJlcXVpcmVkICYmIHRoaXMuc2hvd0NBUCAmJiAhdGhpcy5mb3JtLmdldCgnY2FwJyk/LnZhbHVlKSB7XHJcbiAgICAgICAgZXJyb3JzWydjYXBSZXF1aXJlZCddID0gJ0luc2VyaXNjaSBpbCBDQVAnO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5pbmRpcml6em8/LnJlcXVpcmVkICYmIHRoaXMuc2hvd0luZGlyaXp6bykge1xyXG4gICAgICAgIGNvbnN0IHYgPSB0aGlzLmZvcm0uZ2V0KCdpbmRpcml6em8nKT8udmFsdWU7XHJcbiAgICAgICAgaWYgKCF2IHx8IHYudHJpbSgpID09PSAnJykgZXJyb3JzWydpbmRpcml6em9SZXF1aXJlZCddID0gXCJJbnNlcmlzY2kgbCdpbmRpcml6em9cIjtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnZhbGlkYXRlQ29udGFjdEZpZWxkcyhlcnJvcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFZhbGlkYXppb25pIGVzdGVyb1xyXG4gICAgaWYgKHRoaXMuaXNGb3JlaWduKSB7XHJcbiAgICAgIGNvbnN0IGNvbXVuZUVzdGVybyA9IHRoaXMuZm9ybS5nZXQoJ2NvbXVuZUVzdGVybycpPy52YWx1ZTtcclxuICAgICAgaWYgKGlzQ29tdW5lRXN0ZXJvUmVxdWlyZWQgJiYgKCFjb211bmVFc3Rlcm8gfHwgY29tdW5lRXN0ZXJvLnRyaW0oKSA9PT0gJycpKSB7XHJcbiAgICAgICAgZXJyb3JzWydjb211bmVFc3Rlcm9SZXF1aXJlZCddID0gJ0luc2VyaXNjaSBpbCBjb211bmUgZXN0ZXJvJztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBPYmplY3Qua2V5cyhlcnJvcnMpLmxlbmd0aCA+IDAgPyBlcnJvcnMgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIEFQSSBwdWJibGljYSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgLyoqIE1hcmNhIHR1dHRpIGkgY29udHJvbGxpIGludGVybmkgY29tZSB0b3VjaGVkLiAqL1xyXG4gIG1hcmtBc1RvdWNoZWQoKTogdm9pZCB7XHJcbiAgICBPYmplY3QudmFsdWVzKHRoaXMuZm9ybS5jb250cm9scykuZm9yRWFjaCgoYykgPT4gYy5tYXJrQXNUb3VjaGVkKCkpO1xyXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH1cclxuXHJcbiAgLyoqIFZlcmlmaWNhIHNlIG1vc3RyYXJlIGdsaSBlcnJvcmkgcGVyIHVuIGNhbXBvIGludGVybm8uICovXHJcbiAgc2hvdWxkU2hvd0ZpZWxkRXJyb3JzKGZpZWxkS2V5OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KGZpZWxkS2V5KTtcclxuICAgIHJldHVybiAhIShjb250cm9sPy5pbnZhbGlkICYmIChjb250cm9sLnRvdWNoZWQgfHwgY29udHJvbC5kaXJ0eSkpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEVycm9yaSBkaSB1biBjYW1wbyBpbnRlcm5vIGNvbWUgYXJyYXkgZGkgbWVzc2FnZ2kuICovXHJcbiAgZ2V0RmllbGRFcnJvcnMoZmllbGRLZXk6IHN0cmluZyk6IHN0cmluZ1tdIHtcclxuICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KGZpZWxkS2V5KTtcclxuICAgIGlmICghY29udHJvbD8uZXJyb3JzKSByZXR1cm4gW107XHJcbiAgICBjb25zdCBtZXNzYWdlczogc3RyaW5nW10gPSBbXTtcclxuICAgIGNvbnN0IGVycnMgPSBjb250cm9sLmVycm9ycztcclxuICAgIGlmIChlcnJzWydyZXF1aXJlZCddKSBtZXNzYWdlcy5wdXNoKCdDYW1wbyBvYmJsaWdhdG9yaW8nKTtcclxuICAgIGlmIChlcnJzWydwYXR0ZXJuJ10pIG1lc3NhZ2VzLnB1c2goJ0Zvcm1hdG8gbm9uIHZhbGlkbycpO1xyXG4gICAgaWYgKGVycnNbJ2VtYWlsJ10pIG1lc3NhZ2VzLnB1c2goJ0VtYWlsIG5vbiB2YWxpZGEnKTtcclxuICAgIHJldHVybiBtZXNzYWdlcztcclxuICB9XHJcblxyXG4gIC8qKiBIYW5kbGVyIGJsdXIgcGVyIHByb3BhZ2FyZSBpbCB0b3VjaGVkLiAqL1xyXG4gIG9uQmx1cigpOiB2b2lkIHtcclxuICAgIHRoaXMub25Ub3VjaGVkKCk7XHJcbiAgfVxyXG5cclxuICAvKiogUmVzZXR0YSBsbyBzdGF0byBkZWwgY29tcG9uZW50ZS4gKi9cclxuICByZXNldENvbXBvbmVudFN0YXRlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5pc0l0YWxpYW4gPSBmYWxzZTtcclxuICAgIHRoaXMuaXNGb3JlaWduID0gZmFsc2U7XHJcbiAgICB0aGlzLmZpbHRlcmVkQ29tdW5pID0gW107XHJcbiAgICB0aGlzLmZpbHRlcmVkQ2FwcyA9IFtdO1xyXG4gICAgdGhpcy5mb3JtLmdldCgnY29tdW5lSWQnKT8uZGlzYWJsZSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB0aGlzLmZvcm0uZ2V0KCdjYXAnKT8uZGlzYWJsZSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB0aGlzLnVwZGF0ZVZhbGlkYXRvcnMoKTtcclxuICB9XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBHZXR0ZXIgY2FsY29sYXRpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICAvKiogTGFiZWxzIHBlcnNvbmFsaXp6YWJpbGkgY29uIHZhbG9yaSBkaSBkZWZhdWx0LiAqL1xyXG4gIGdldCBsYWJlbHMoKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBuYXppb25lOiB0aGlzLmNvbmZpZy5sYWJlbHM/Lm5hemlvbmUgfHwgJ05hemlvbmUnLFxyXG4gICAgICBwcm92aW5jaWE6IHRoaXMuY29uZmlnLmxhYmVscz8ucHJvdmluY2lhIHx8ICdQcm92aW5jaWEnLFxyXG4gICAgICBjb211bmU6IHRoaXMuY29uZmlnLmxhYmVscz8uY29tdW5lIHx8ICdDb211bmUnLFxyXG4gICAgICBjYXA6IHRoaXMuY29uZmlnLmxhYmVscz8uY2FwIHx8ICdDQVAnLFxyXG4gICAgICBpbmRpcml6em86IHRoaXMuY29uZmlnLmxhYmVscz8uaW5kaXJpenpvIHx8ICdJbmRpcml6em8nLFxyXG4gICAgICBjb211bmVFc3Rlcm86IHRoaXMuY29uZmlnLmxhYmVscz8uY29tdW5lRXN0ZXJvIHx8ICdDb211bmUgRXN0ZXJvJyxcclxuICAgICAgbWFpbDogdGhpcy5jb25maWcubGFiZWxzPy5tYWlsIHx8ICdFbWFpbCcsXHJcbiAgICAgIHBlYzogdGhpcy5jb25maWcubGFiZWxzPy5wZWMgfHwgJ1BFQycsXHJcbiAgICAgIHRlbGVmb25vOiB0aGlzLmNvbmZpZy5sYWJlbHM/LnRlbGVmb25vIHx8ICdUZWxlZm9ubycsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgZ2V0IGhhc1ZhbGlkYXRpb25FcnJvcnMoKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBleHRlcm5hbEludmFsaWQgPSAhIShcclxuICAgICAgdGhpcy5uZ0NvbnRyb2w/LmNvbnRyb2w/LmludmFsaWQgJiZcclxuICAgICAgKHRoaXMubmdDb250cm9sLmNvbnRyb2wudG91Y2hlZCB8fCB0aGlzLm5nQ29udHJvbC5jb250cm9sLmRpcnR5KVxyXG4gICAgKTtcclxuICAgIGlmIChleHRlcm5hbEludmFsaWQpIHJldHVybiB0cnVlO1xyXG5cclxuICAgIGNvbnN0IGlzSW50ZXJhY3RlZCA9XHJcbiAgICAgIHRoaXMuZm9ybT8udG91Y2hlZCB8fCB0aGlzLmZvcm0/LmRpcnR5IHx8IHRoaXMubmdDb250cm9sPy5jb250cm9sPy50b3VjaGVkIHx8IHRoaXMubmdDb250cm9sPy5jb250cm9sPy5kaXJ0eTtcclxuICAgIGlmIChpc0ludGVyYWN0ZWQpIHtcclxuICAgICAgcmV0dXJuICEhdGhpcy52YWxpZGF0ZShudWxsIGFzIGFueSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBnZXQgdmFsaWRhdGlvbkVycm9ycygpOiBzdHJpbmdbXSB7XHJcbiAgICAvLyBFcnJvcmkgZXN0ZXJuaSBkYWwgRm9ybUJ1aWxkZXJcclxuICAgIGlmICh0aGlzLm5nQ29udHJvbD8uY29udHJvbD8uZXJyb3JzKSB7XHJcbiAgICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcclxuICAgICAgaWYgKHRoaXMubmdDb250cm9sLmNvbnRyb2wuZXJyb3JzWydyZXF1aXJlZCddKSB7XHJcbiAgICAgICAgZXJyb3JzLnB1c2goJ0luaXppYSBzZWxlemlvbmFuZG8gbGEgbmF6aW9uZScpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMCkgcmV0dXJuIGVycm9ycztcclxuICAgIH1cclxuXHJcbiAgICAvLyBFcnJvcmkgaW50ZXJuaVxyXG4gICAgY29uc3QgaW50ZXJuYWxFcnJvcnMgPSB0aGlzLnZhbGlkYXRlKG51bGwgYXMgYW55KTtcclxuICAgIGlmICghaW50ZXJuYWxFcnJvcnMpIHJldHVybiBbXTtcclxuICAgIHJldHVybiBPYmplY3QudmFsdWVzKGludGVybmFsRXJyb3JzKSBhcyBzdHJpbmdbXTtcclxuICB9XHJcblxyXG4gIGdldCBzaG93Q0FQKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmNhcD8uc2hvdyAhPT0gZmFsc2U7XHJcbiAgfVxyXG4gIGdldCBzaG93SW5kaXJpenpvKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmluZGlyaXp6bz8uc2hvdyAhPT0gZmFsc2U7XHJcbiAgfVxyXG4gIGdldCBzaG93TWFpbCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5tYWlsPy5zaG93ID09PSB0cnVlO1xyXG4gIH1cclxuICBnZXQgc2hvd1BFQygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5wZWM/LnNob3cgPT09IHRydWU7XHJcbiAgfVxyXG4gIGdldCBzaG93VGVsZWZvbm8oKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcudGVsZWZvbm8/LnNob3cgPT09IHRydWU7XHJcbiAgfVxyXG5cclxuICBnZXQgY2FwQ29sdW1ucygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmNhcD8uY29sdW1ucyB8fCA2O1xyXG4gIH1cclxuICBnZXQgaW5kaXJpenpvQ29sdW1ucygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmluZGlyaXp6bz8uY29sdW1ucyB8fCAxMjtcclxuICB9XHJcbiAgZ2V0IG1haWxDb2x1bW5zKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcubWFpbD8uY29sdW1ucyB8fCA2O1xyXG4gIH1cclxuICBnZXQgcGVjQ29sdW1ucygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnBlYz8uY29sdW1ucyB8fCA2O1xyXG4gIH1cclxuICBnZXQgdGVsZWZvbm9Db2x1bW5zKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcudGVsZWZvbm8/LmNvbHVtbnMgfHwgNjtcclxuICB9XHJcblxyXG4gIGdldCBpc0l0YWx5QnlEZWZhdWx0KCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLml0YWx5QnlEZWZhdWx0ID09PSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGlzQ2FwRGlzYWJsZWQoKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBjb211bmVJZCA9IHRoaXMuZm9ybS5nZXQoJ2NvbXVuZUlkJyk/LnZhbHVlO1xyXG4gICAgcmV0dXJuICFjb211bmVJZCB8fCB0aGlzLmZpbHRlcmVkQ2Fwcy5sZW5ndGggPT09IDAgfHwgdGhpcy5maWx0ZXJlZENhcHMubGVuZ3RoID09PSAxO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGlzTmF6aW9uZURpc2FibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5jb25maWcuaXRhbHlCeURlZmF1bHQgPT09IHRydWU7XHJcbiAgfVxyXG5cclxuICBnZXQgaXNSZXF1aXJlZCgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLmNvbmZpZy5uYXppb25lPy5yZXF1aXJlZCAhPT0gZmFsc2UpIHJldHVybiB0cnVlO1xyXG4gICAgaWYgKCF0aGlzLm5nQ29udHJvbD8uY29udHJvbCkgcmV0dXJuIGZhbHNlO1xyXG4gICAgY29uc3QgdmFsaWRhdG9yID0gdGhpcy5uZ0NvbnRyb2wuY29udHJvbC52YWxpZGF0b3I7XHJcbiAgICBpZiAodmFsaWRhdG9yKSB7XHJcbiAgICAgIGNvbnN0IGVycm9ycyA9IHZhbGlkYXRvcih7fSBhcyBBYnN0cmFjdENvbnRyb2wpO1xyXG4gICAgICByZXR1cm4gISFlcnJvcnM/LlsncmVxdWlyZWQnXTtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBJbml6aWFsaXp6YXppb25lIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICBwcml2YXRlIGFzeW5jIGluaXRpYWxpemVDb21wb25lbnQoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICB0cnkge1xyXG4gICAgICBhd2FpdCB0aGlzLmxvYWRMb2NhdGlvbkRhdGEoKTtcclxuICAgICAgdGhpcy50aXBvbG9naWNoZUxvYWRlZCA9IHRydWU7XHJcblxyXG4gICAgICBpZiAodGhpcy5wZW5kaW5nV3JpdGVWYWx1ZSAhPT0gbnVsbCkge1xyXG4gICAgICAgIHRoaXMucHJvY2Vzc1dyaXRlVmFsdWUodGhpcy5wZW5kaW5nV3JpdGVWYWx1ZSk7XHJcbiAgICAgICAgdGhpcy5wZW5kaW5nV3JpdGVWYWx1ZSA9IG51bGw7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5hcHBseUluaXRpYWxDb25maWd1cmF0aW9uKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghdGhpcy5zdWJzY3JpcHRpb25zSW5pdGlhbGl6ZWQpIHtcclxuICAgICAgICB0aGlzLnNldHVwRm9ybVN1YnNjcmlwdGlvbnMoKTtcclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnNJbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tVaVNwZWNpZmljYVRlcnJpdG9yaWFsZV0gRXJyb3JlIGluaXppYWxpenphemlvbmU6JywgZXJyb3IpO1xyXG4gICAgICB0aGlzLnRpcG9sb2dpY2hlTG9hZGVkID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXRpYWxpemVGb3JtKCk6IHZvaWQge1xyXG4gICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7XHJcbiAgICAgIG5hemlvbmVJZDogW251bGwsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxyXG4gICAgICBwcm92aW5jaWFJZDogW251bGxdLFxyXG4gICAgICBjb211bmVJZDogW3sgdmFsdWU6IG51bGwsIGRpc2FibGVkOiB0cnVlIH1dLFxyXG4gICAgICBjYXA6IFt7IHZhbHVlOiBudWxsLCBkaXNhYmxlZDogdHJ1ZSB9XSxcclxuICAgICAgY29tdW5lRXN0ZXJvOiBbbnVsbF0sXHJcbiAgICAgIGluZGlyaXp6bzogW251bGxdLFxyXG4gICAgICBtYWlsOiBbbnVsbF0sXHJcbiAgICAgIHBlYzogW251bGxdLFxyXG4gICAgICB0ZWxlZm9ubzogW251bGxdLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNldHVwTmdDb250cm9sKCk6IHZvaWQge1xyXG4gICAgY29uc3QgbmdDb250cm9sID0gdGhpcy5pbmplY3Rvci5nZXQoTmdDb250cm9sLCBudWxsLCB7IHNlbGY6IHRydWUsIG9wdGlvbmFsOiB0cnVlIH0pO1xyXG4gICAgaWYgKG5nQ29udHJvbCkge1xyXG4gICAgICB0aGlzLm5nQ29udHJvbCA9IG5nQ29udHJvbDtcclxuICAgICAgdGhpcy5uZ0NvbnRyb2wudmFsdWVBY2Nlc3NvciA9IHRoaXM7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGxvYWRMb2NhdGlvbkRhdGEoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBbbmF6aW9uaVJlc3VsdCwgcHJvdmluY2VSZXN1bHRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xyXG4gICAgICB0aGlzLmxvY2F0aW9uU2VydmljZS5nZXROYXppb25pKCksXHJcbiAgICAgIHRoaXMubG9jYXRpb25TZXJ2aWNlLmdldFByb3ZpbmNlKCksXHJcbiAgICBdKTtcclxuICAgIHRoaXMubmF6aW9uaSA9IG5hemlvbmlSZXN1bHQuZGF0YTtcclxuICAgIHRoaXMucHJvdmluY2UgPSBwcm92aW5jZVJlc3VsdC5jb250ZW50O1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIEdlc3Rpb25lIHdyaXRlVmFsdWUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG4gIHByaXZhdGUgcHJvY2Vzc1dyaXRlVmFsdWUodmFsdWU6IFVpTG9jYXRpb25WYWx1ZSB8IG51bGwpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNJbml0aWFsaXppbmcgPSB0cnVlO1xyXG5cclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICBjb25zdCBwcm9jZXNzZWRWYWx1ZSA9IHRoaXMuaGFuZGxlSXRhbHlCeURlZmF1bHRWYWx1ZSh2YWx1ZSk7XHJcbiAgICAgIHRoaXMuZm9ybS5wYXRjaFZhbHVlKHByb2Nlc3NlZFZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcblxyXG4gICAgICB0aGlzLnVwZGF0ZUNvbXBvbmVudFN0YXRlKHByb2Nlc3NlZFZhbHVlKS50aGVuKCgpID0+IHtcclxuICAgICAgICB0aGlzLmFwcGx5SW5pdGlhbENvbmZpZ3VyYXRpb24oKTtcclxuICAgICAgICB0aGlzLmlzSW5pdGlhbGl6aW5nID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUocHJvY2Vzc2VkVmFsdWUsIHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xyXG4gICAgICAgIHRoaXMuaGFuZGxlVGVycml0b3JpYWxDaGFuZ2VzKFxyXG4gICAgICAgICAgcHJvY2Vzc2VkVmFsdWUubmF6aW9uZUlkIHx8ICcnLFxyXG4gICAgICAgICAgcHJvY2Vzc2VkVmFsdWUucHJvdmluY2lhSWQgfHwgJycsXHJcbiAgICAgICAgICBwcm9jZXNzZWRWYWx1ZS5jb211bmVJZCB8fCAnJyxcclxuICAgICAgICApO1xyXG4gICAgICAgIHRoaXMudXBkYXRlVmFsaWRhdG9ycygpO1xyXG4gICAgICAgIE9iamVjdC52YWx1ZXModGhpcy5mb3JtLmNvbnRyb2xzKS5mb3JFYWNoKChjdHJsKSA9PiBjdHJsLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pKTtcclxuICAgICAgICB0aGlzLmZvcm0udXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZm9ybS5yZXNldCh1bmRlZmluZWQsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuICAgICAgdGhpcy5yZXNldENvbXBvbmVudFN0YXRlKCk7XHJcbiAgICAgIHRoaXMuYXBwbHlJbml0aWFsQ29uZmlndXJhdGlvbigpO1xyXG4gICAgICB0aGlzLmlzSW5pdGlhbGl6aW5nID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhbmRsZUl0YWx5QnlEZWZhdWx0VmFsdWUodmFsdWU6IFVpTG9jYXRpb25WYWx1ZSk6IFVpTG9jYXRpb25WYWx1ZSB7XHJcbiAgICBpZiAoIXRoaXMuY29uZmlnLml0YWx5QnlEZWZhdWx0KSByZXR1cm4gdmFsdWU7XHJcbiAgICBpZiAodmFsdWUubmF6aW9uZUlkICYmIHZhbHVlLm5hemlvbmVJZCAhPT0gJ0lUQScpIHtcclxuICAgICAgcmV0dXJuIHsgLi4udmFsdWUsIG5hemlvbmVJZDogJ0lUQScsIGNvbXVuZUVzdGVybzogdW5kZWZpbmVkIH07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgU3Vic2NyaXB0aW9ucyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgcHJpdmF0ZSBzZXR1cEZvcm1TdWJzY3JpcHRpb25zKCk6IHZvaWQge1xyXG4gICAgLy8gU3Vic2NyaXB0aW9uIHBlciBpIGNhbWJpYW1lbnRpIHRlcnJpdG9yaWFsaSAobmF6aW9uZS9wcm92aW5jaWEvY29tdW5lKVxyXG4gICAgY29tYmluZUxhdGVzdChbXHJcbiAgICAgIHRoaXMuZm9ybVxyXG4gICAgICAgIC5nZXQoJ25hemlvbmVJZCcpIVxyXG4gICAgICAgIC52YWx1ZUNoYW5nZXMucGlwZShzdGFydFdpdGgodGhpcy5mb3JtLmdldCgnbmF6aW9uZUlkJykhLnZhbHVlKSwgZGlzdGluY3RVbnRpbENoYW5nZWQoKSksXHJcbiAgICAgIHRoaXMuZm9ybVxyXG4gICAgICAgIC5nZXQoJ3Byb3ZpbmNpYUlkJykhXHJcbiAgICAgICAgLnZhbHVlQ2hhbmdlcy5waXBlKHN0YXJ0V2l0aCh0aGlzLmZvcm0uZ2V0KCdwcm92aW5jaWFJZCcpIS52YWx1ZSksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpLFxyXG4gICAgICB0aGlzLmZvcm0uZ2V0KCdjb211bmVJZCcpIS52YWx1ZUNoYW5nZXMucGlwZShzdGFydFdpdGgodGhpcy5mb3JtLmdldCgnY29tdW5lSWQnKSEudmFsdWUpLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKSxcclxuICAgIF0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSxcclxuICAgICAgICBtYXAoKFtuYXppb25lSWQsIHByb3ZpbmNpYUlkLCBjb211bmVJZF0pID0+ICh7IG5hemlvbmVJZCwgcHJvdmluY2lhSWQsIGNvbXVuZUlkIH0pKSxcclxuICAgICAgKVxyXG4gICAgICAuc3Vic2NyaWJlKCh7IG5hemlvbmVJZCwgcHJvdmluY2lhSWQsIGNvbXVuZUlkIH0pID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNJbml0aWFsaXppbmcgJiYgdGhpcy50aXBvbG9naWNoZUxvYWRlZCkge1xyXG4gICAgICAgICAgdGhpcy5oYW5kbGVUZXJyaXRvcmlhbENoYW5nZXMobmF6aW9uZUlkLCBwcm92aW5jaWFJZCwgY29tdW5lSWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgLy8gU3Vic2NyaXB0aW9uIHBlciB0dXR0aSBpIGNhbWJpYW1lbnRpIGRlbCBmb3JtXHJcbiAgICB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSxcclxuICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgocHJldiwgY3VycikgPT4gSlNPTi5zdHJpbmdpZnkocHJldikgPT09IEpTT04uc3RyaW5naWZ5KGN1cnIpKSxcclxuICAgICAgKVxyXG4gICAgICAuc3Vic2NyaWJlKChmb3JtVmFsdWUpID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNJbml0aWFsaXppbmcgJiYgdGhpcy50aXBvbG9naWNoZUxvYWRlZCkge1xyXG4gICAgICAgICAgdGhpcy5vbkNoYW5nZShmb3JtVmFsdWUpO1xyXG4gICAgICAgICAgdGhpcy5ub3RpZnlWYWxpZGF0aW9uQ2hhbmdlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgTG9naWNhIHRlcnJpdG9yaWFsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVUZXJyaXRvcmlhbENoYW5nZXMobmF6aW9uZUlkOiBzdHJpbmcsIHByb3ZpbmNpYUlkOiBzdHJpbmcsIGNvbXVuZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMudXBkYXRlTmF0aW9uYWxpdHlTdGF0ZShuYXppb25lSWQpO1xyXG4gICAgYXdhaXQgdGhpcy51cGRhdGVUZXJyaXRvcmlhbERhdGEocHJvdmluY2lhSWQsIGNvbXVuZUlkKTtcclxuICAgIHRoaXMudXBkYXRlVmFsaWRhdG9ycygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVOYXRpb25hbGl0eVN0YXRlKG5hemlvbmVJZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBuYXppb25lID0gdGhpcy5uYXppb25pLmZpbmQoKG4pID0+IG4uY29kU3RhdG9QayA9PT0gbmF6aW9uZUlkKTtcclxuICAgIHRoaXMuaXNJdGFsaWFuID0gbmF6aW9uZT8uY29kU3RhdG9QayA9PT0gJ0lUQSc7XHJcbiAgICB0aGlzLmlzRm9yZWlnbiA9ICEhKG5hemlvbmUgJiYgbmF6aW9uZS5jb2RTdGF0b1BrICE9PSAnSVRBJyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZVRlcnJpdG9yaWFsRGF0YShwcm92aW5jaWFJZDogc3RyaW5nLCBjb211bmVJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5pc0l0YWxpYW4gJiYgcHJvdmluY2lhSWQpIHtcclxuICAgICAgYXdhaXQgdGhpcy51cGRhdGVGaWx0ZXJlZENvbXVuaShwcm92aW5jaWFJZCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZpbHRlcmVkQ29tdW5pID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaXNJdGFsaWFuICYmIGNvbXVuZUlkKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlRmlsdGVyZWRDYXBzKGNvbXVuZUlkKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZmlsdGVyZWRDYXBzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5hcHBseUZpZWxkc0Rpc2FibGVkU3RhdGUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlRmlsdGVyZWRDb211bmkocHJvdmluY2lhSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKCFwcm92aW5jaWFJZCkge1xyXG4gICAgICB0aGlzLmZpbHRlcmVkQ29tdW5pID0gW107XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRyeSB7XHJcbiAgICAgIHRoaXMuZmlsdGVyZWRDb211bmkgPSBhd2FpdCB0aGlzLmxvY2F0aW9uU2VydmljZS5nZXRDb211bmlCeVByb3ZpbmNpYShwcm92aW5jaWFJZCk7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRDb211bmVJZCA9IHRoaXMuZm9ybS5nZXQoJ2NvbXVuZUlkJyk/LnZhbHVlO1xyXG4gICAgICBpZiAoY3VycmVudENvbXVuZUlkICYmICF0aGlzLmZpbHRlcmVkQ29tdW5pLmZpbmQoKGMpID0+IGMuY29kaWNlQ29tdW5lUGsgPT09IGN1cnJlbnRDb211bmVJZCkpIHtcclxuICAgICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh7IGNvbXVuZUlkOiBudWxsIH0sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCB7XHJcbiAgICAgIHRoaXMuZmlsdGVyZWRDb211bmkgPSBbXTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlRmlsdGVyZWRDYXBzKGNvbXVuZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICghY29tdW5lSWQpIHtcclxuICAgICAgdGhpcy5maWx0ZXJlZENhcHMgPSBbXTtcclxuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBjYXA6IG51bGwgfSwgeyBlbWl0RXZlbnQ6IHRydWUgfSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjYXBzID0gYXdhaXQgdGhpcy5sb2NhdGlvblNlcnZpY2UuZ2V0Q2FwTGlzdChjb211bmVJZCk7XHJcbiAgICB0aGlzLmZpbHRlcmVkQ2FwcyA9IGNhcHMubWFwKChjYXBDb2RlKSA9PiAoeyBpZDogY2FwQ29kZSwgY29kaWNlOiBjYXBDb2RlLCBjb211bmVJZCB9KSk7XHJcblxyXG4gICAgY29uc3QgY3VycmVudENhcCA9IHRoaXMuZm9ybS5nZXQoJ2NhcCcpPy52YWx1ZTtcclxuICAgIGlmICh0aGlzLmZpbHRlcmVkQ2Fwcy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBjYXA6IHRoaXMuZmlsdGVyZWRDYXBzWzBdLmlkIH0sIHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLmZpbHRlcmVkQ2Fwcy5sZW5ndGggPiAxKSB7XHJcbiAgICAgIGlmICghY3VycmVudENhcCB8fCAhdGhpcy5maWx0ZXJlZENhcHMuc29tZSgoYykgPT4gYy5pZCA9PT0gY3VycmVudENhcCkpIHtcclxuICAgICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh7IGNhcDogbnVsbCB9LCB7IGVtaXRFdmVudDogdHJ1ZSB9KTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBjYXA6IG51bGwgfSwgeyBlbWl0RXZlbnQ6IHRydWUgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUNvbXBvbmVudFN0YXRlKHZhbHVlOiBVaUxvY2F0aW9uVmFsdWUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMudXBkYXRlTmF0aW9uYWxpdHlTdGF0ZSh2YWx1ZS5uYXppb25lSWQgfHwgJycpO1xyXG4gICAgYXdhaXQgdGhpcy51cGRhdGVGaWx0ZXJlZENvbXVuaSh2YWx1ZS5wcm92aW5jaWFJZCB8fCAnJyk7XHJcbiAgICBhd2FpdCB0aGlzLnVwZGF0ZUZpbHRlcmVkQ2Fwcyh2YWx1ZS5jb211bmVJZCB8fCAnJyk7XHJcbiAgICB0aGlzLmFwcGx5RmllbGRzRGlzYWJsZWRTdGF0ZSgpO1xyXG4gICAgdGhpcy51cGRhdGVWYWxpZGF0b3JzKCk7XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgU3RhdG8gY2FtcGkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG4gIHByaXZhdGUgYXBwbHlGaWVsZHNEaXNhYmxlZFN0YXRlKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgdGhpcy5mb3JtLmRpc2FibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY29tdW5lQ29udHJvbCA9IHRoaXMuZm9ybS5nZXQoJ2NvbXVuZUlkJyk7XHJcbiAgICBjb25zdCBjYXBDb250cm9sID0gdGhpcy5mb3JtLmdldCgnY2FwJyk7XHJcbiAgICBjb25zdCBuYXppb25lQ29udHJvbCA9IHRoaXMuZm9ybS5nZXQoJ25hemlvbmVJZCcpO1xyXG5cclxuICAgIC8vIENvbXVuZSBhYmlsaXRhdG8gc29sbyBzZSBJdGFsaWEgKyBwcm92aW5jaWEgc2VsZXppb25hdGFcclxuICAgIGlmICh0aGlzLmlzSXRhbGlhbiAmJiB0aGlzLmZvcm0uZ2V0KCdwcm92aW5jaWFJZCcpPy52YWx1ZSkge1xyXG4gICAgICBjb211bmVDb250cm9sPy5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29tdW5lQ29udHJvbD8uZGlzYWJsZSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ0FQIHNlZ3VlIGxvZ2ljYSBzcGVjaWZpY2FcclxuICAgIGlmICh0aGlzLmlzQ2FwRGlzYWJsZWQpIHtcclxuICAgICAgY2FwQ29udHJvbD8uZGlzYWJsZSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjYXBDb250cm9sPy5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIE5hemlvbmUgZGlzYWJpbGl0YXRhIHNlIGl0YWx5QnlEZWZhdWx0XHJcbiAgICBpZiAodGhpcy5pc0l0YWx5QnlEZWZhdWx0KSB7XHJcbiAgICAgIG5hemlvbmVDb250cm9sPy5kaXNhYmxlKHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG5hemlvbmVDb250cm9sPy5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIFZhbGlkYXppb25lIGRpbmFtaWNhIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICBwcml2YXRlIHVwZGF0ZVZhbGlkYXRvcnMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBjb250cm9sczogUmVjb3JkPHN0cmluZywgQWJzdHJhY3RDb250cm9sIHwgbnVsbD4gPSB7XHJcbiAgICAgIG5hemlvbmU6IHRoaXMuZm9ybS5nZXQoJ25hemlvbmVJZCcpLFxyXG4gICAgICBwcm92aW5jaWE6IHRoaXMuZm9ybS5nZXQoJ3Byb3ZpbmNpYUlkJyksXHJcbiAgICAgIGNvbXVuZTogdGhpcy5mb3JtLmdldCgnY29tdW5lSWQnKSxcclxuICAgICAgY29tdW5lRXN0ZXJvOiB0aGlzLmZvcm0uZ2V0KCdjb211bmVFc3Rlcm8nKSxcclxuICAgICAgY2FwOiB0aGlzLmZvcm0uZ2V0KCdjYXAnKSxcclxuICAgICAgaW5kaXJpenpvOiB0aGlzLmZvcm0uZ2V0KCdpbmRpcml6em8nKSxcclxuICAgICAgbWFpbDogdGhpcy5mb3JtLmdldCgnbWFpbCcpLFxyXG4gICAgICBwZWM6IHRoaXMuZm9ybS5nZXQoJ3BlYycpLFxyXG4gICAgICB0ZWxlZm9ubzogdGhpcy5mb3JtLmdldCgndGVsZWZvbm8nKSxcclxuICAgIH07XHJcblxyXG4gICAgLy8gUHVsaXNjaSB0dXR0aSBpIHZhbGlkYXRvcmlcclxuICAgIE9iamVjdC52YWx1ZXMoY29udHJvbHMpLmZvckVhY2goKGMpID0+IGM/LmNsZWFyVmFsaWRhdG9ycygpKTtcclxuXHJcbiAgICAvLyBOYXppb25lXHJcbiAgICBpZiAodGhpcy5jb25maWcubmF6aW9uZT8ucmVxdWlyZWQgIT09IGZhbHNlKSB7XHJcbiAgICAgIGNvbnRyb2xzWyduYXppb25lJ10/LnNldFZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaXNJdGFsaWFuKSB7XHJcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5wcm92aW5jaWE/LnJlcXVpcmVkICE9PSBmYWxzZSkge1xyXG4gICAgICAgIGNvbnRyb2xzWydwcm92aW5jaWEnXT8uc2V0VmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy5jb25maWcuY29tdW5lPy5yZXF1aXJlZCAhPT0gZmFsc2UpIHtcclxuICAgICAgICBjb250cm9sc1snY29tdW5lJ10/LnNldFZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuY29uZmlnLmNhcD8ucmVxdWlyZWQgJiYgdGhpcy5zaG93Q0FQKSB7XHJcbiAgICAgICAgY29udHJvbHNbJ2NhcCddPy5zZXRWYWxpZGF0b3JzKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5pbmRpcml6em8/LnJlcXVpcmVkICYmIHRoaXMuc2hvd0luZGlyaXp6bykge1xyXG4gICAgICAgIGNvbnRyb2xzWydpbmRpcml6em8nXT8uc2V0VmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmFwcGx5Q29udGFjdFZhbGlkYXRvcnMoY29udHJvbHMpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLmlzRm9yZWlnbikge1xyXG4gICAgICBpZiAodGhpcy5jb25maWcuY29tdW5lRXN0ZXJvPy5yZXF1aXJlZCAhPT0gZmFsc2UpIHtcclxuICAgICAgICBjb250cm9sc1snY29tdW5lRXN0ZXJvJ10/LnNldFZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBBZ2dpb3JuYSBzZW56YSBlbWV0dGVyZSBldmVudGlcclxuICAgIE9iamVjdC52YWx1ZXMoY29udHJvbHMpLmZvckVhY2goKGMpID0+IGM/LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pKTtcclxuICAgIHRoaXMubm90aWZ5VmFsaWRhdGlvbkNoYW5nZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhcHBseUNvbnRhY3RWYWxpZGF0b3JzKGNvbnRyb2xzOiBSZWNvcmQ8c3RyaW5nLCBBYnN0cmFjdENvbnRyb2wgfCBudWxsPik6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY29uZmlnLm1haWw/LnJlcXVpcmVkICYmIHRoaXMuc2hvd01haWwpIHtcclxuICAgICAgY29udHJvbHNbJ21haWwnXT8uc2V0VmFsaWRhdG9ycyhbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5wYXR0ZXJuKHRoaXMuRU1BSUxfUEFUVEVSTildKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5zaG93TWFpbCkge1xyXG4gICAgICBjb250cm9sc1snbWFpbCddPy5zZXRWYWxpZGF0b3JzKFtWYWxpZGF0b3JzLnBhdHRlcm4odGhpcy5FTUFJTF9QQVRURVJOKV0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmNvbmZpZy5wZWM/LnJlcXVpcmVkICYmIHRoaXMuc2hvd1BFQykge1xyXG4gICAgICBjb250cm9sc1sncGVjJ10/LnNldFZhbGlkYXRvcnMoW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMucGF0dGVybih0aGlzLlBFQ19QQVRURVJOKV0pO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLnNob3dQRUMpIHtcclxuICAgICAgY29udHJvbHNbJ3BlYyddPy5zZXRWYWxpZGF0b3JzKFtWYWxpZGF0b3JzLnBhdHRlcm4odGhpcy5QRUNfUEFUVEVSTildKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5jb25maWcudGVsZWZvbm8/LnJlcXVpcmVkICYmIHRoaXMuc2hvd1RlbGVmb25vKSB7XHJcbiAgICAgIGNvbnRyb2xzWyd0ZWxlZm9ubyddPy5zZXRWYWxpZGF0b3JzKFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLnBhdHRlcm4odGhpcy5QSE9ORV9QQVRURVJOKV0pO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLnNob3dUZWxlZm9ubykge1xyXG4gICAgICBjb250cm9sc1sndGVsZWZvbm8nXT8uc2V0VmFsaWRhdG9ycyhbVmFsaWRhdG9ycy5wYXR0ZXJuKHRoaXMuUEhPTkVfUEFUVEVSTildKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdmFsaWRhdGVDb250YWN0RmllbGRzKGVycm9yczogVmFsaWRhdGlvbkVycm9ycyk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY29uZmlnLm1haWw/LnJlcXVpcmVkICYmIHRoaXMuc2hvd01haWwpIHtcclxuICAgICAgY29uc3QgdiA9IHRoaXMuZm9ybS5nZXQoJ21haWwnKT8udmFsdWU7XHJcbiAgICAgIGlmICghdiB8fCB2LnRyaW0oKSA9PT0gJycpIHtcclxuICAgICAgICBlcnJvcnNbJ21haWxSZXF1aXJlZCddID0gXCJJbnNlcmlzY2kgbCdlbWFpbFwiO1xyXG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLkVNQUlMX1BBVFRFUk4udGVzdCh2KSkge1xyXG4gICAgICAgIGVycm9yc1snbWFpbEludmFsaWQnXSA9IFwiSW5zZXJpc2NpIHVuJ2VtYWlsIHZhbGlkYVwiO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5jb25maWcucGVjPy5yZXF1aXJlZCAmJiB0aGlzLnNob3dQRUMpIHtcclxuICAgICAgY29uc3QgdiA9IHRoaXMuZm9ybS5nZXQoJ3BlYycpPy52YWx1ZTtcclxuICAgICAgaWYgKCF2IHx8IHYudHJpbSgpID09PSAnJykge1xyXG4gICAgICAgIGVycm9yc1sncGVjUmVxdWlyZWQnXSA9ICdJbnNlcmlzY2kgbGEgUEVDJztcclxuICAgICAgfSBlbHNlIGlmICghdGhpcy5QRUNfUEFUVEVSTi50ZXN0KHYpKSB7XHJcbiAgICAgICAgZXJyb3JzWydwZWNJbnZhbGlkJ10gPSAnSW5zZXJpc2NpIHVuYSBQRUMgdmFsaWRhJztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuY29uZmlnLnRlbGVmb25vPy5yZXF1aXJlZCAmJiB0aGlzLnNob3dUZWxlZm9ubykge1xyXG4gICAgICBjb25zdCB2ID0gdGhpcy5mb3JtLmdldCgndGVsZWZvbm8nKT8udmFsdWU7XHJcbiAgICAgIGlmICghdiB8fCB2LnRyaW0oKSA9PT0gJycpIHtcclxuICAgICAgICBlcnJvcnNbJ3RlbGVmb25vUmVxdWlyZWQnXSA9ICdJbnNlcmlzY2kgaWwgdGVsZWZvbm8nO1xyXG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLlBIT05FX1BBVFRFUk4udGVzdCh2KSkge1xyXG4gICAgICAgIGVycm9yc1sndGVsZWZvbm9JbnZhbGlkJ10gPSAnSW5zZXJpc2NpIHVuIG51bWVybyBkaSB0ZWxlZm9ubyB2YWxpZG8nO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgQ29uZmlndXJhemlvbmUgaW5pemlhbGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG4gIHByaXZhdGUgYXBwbHlJbml0aWFsQ29uZmlndXJhdGlvbigpOiB2b2lkIHtcclxuICAgIGNvbnN0IG5hemlvbmVDb250cm9sID0gdGhpcy5mb3JtLmdldCgnbmF6aW9uZUlkJyk7XHJcbiAgICBjb25zdCBjdXJyZW50TmF6aW9uZUlkID0gbmF6aW9uZUNvbnRyb2w/LnZhbHVlO1xyXG5cclxuICAgIGlmICh0aGlzLmNvbmZpZy5pdGFseUJ5RGVmYXVsdCkge1xyXG4gICAgICBjb25zdCBpdGFsaWEgPSB0aGlzLm5hemlvbmkuZmluZCgobikgPT4gbi5jb2RTdGF0b1BrID09PSAnSVRBJyk7XHJcbiAgICAgIGlmIChpdGFsaWEgJiYgKCFjdXJyZW50TmF6aW9uZUlkIHx8IGN1cnJlbnROYXppb25lSWQgIT09ICdJVEEnKSkge1xyXG4gICAgICAgIHRoaXMuZm9ybS5wYXRjaFZhbHVlKHsgbmF6aW9uZUlkOiBpdGFsaWEuY29kU3RhdG9QayB9LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy51cGRhdGVOYXRpb25hbGl0eVN0YXRlKCdJVEEnKTtcclxuICAgICAgbmF6aW9uZUNvbnRyb2w/LmRpc2FibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKGN1cnJlbnROYXppb25lSWQpIHRoaXMudXBkYXRlTmF0aW9uYWxpdHlTdGF0ZShjdXJyZW50TmF6aW9uZUlkKTtcclxuICAgICAgaWYgKCF0aGlzLmRpc2FibGVkKSBuYXppb25lQ29udHJvbD8uZW5hYmxlKHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnVwZGF0ZVZhbGlkYXRvcnMoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbm90aWZ5VmFsaWRhdGlvbkNoYW5nZSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLm9uVmFsaWRhdG9yQ2hhbmdlKSB7XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5vblZhbGlkYXRvckNoYW5nZSgpLCAwKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPCEtLVxyXG4gIENvbXBvbmVudGUgcGVyIGxhIHNlbGV6aW9uZSBkaSBkYXRpIGdlb2dyYWZpY2kgKEl0YWxpYS9Fc3Rlcm8pLlxyXG4gIFV0aWxpenphIGlsIGZsb3cgY29udHJvbCBtb2Rlcm5vIGRpIEFuZ3VsYXIgKEBpZiwgQGZvcikuXHJcbi0tPlxyXG48ZGl2XHJcbiAgY2xhc3M9XCJ1aS1sb2NhdGlvblwiXHJcbiAgW2Zvcm1Hcm91cF09XCJmb3JtXCJcclxuICBbY2xhc3MudWktbG9jYXRpb24tLWZvcmVpZ25dPVwiaXNGb3JlaWduXCJcclxuICBbY2xhc3MudWktbG9jYXRpb24tLWl0YWxpYW5dPVwiaXNJdGFsaWFuXCJcclxuPlxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT09PT0gTkFaSU9ORSA9PT09PT09PT09PT09PT09PT09PSAtLT5cclxuICA8ZGl2IGNsYXNzPVwidWktbG9jYXRpb25fX2ZpZWxkLXJvd1wiPlxyXG4gICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZnVsbC13aWR0aFwiXHJcbiAgICAgIFtjbGFzcy51aS1sb2NhdGlvbl9faXRhbHktZGVmYXVsdF09XCJjb25maWcuaXRhbHlCeURlZmF1bHRcIlxyXG4gICAgPlxyXG4gICAgICA8bWF0LWxhYmVsPnt7IGxhYmVscy5uYXppb25lIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgIDxtYXQtc2VsZWN0XHJcbiAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibmF6aW9uZUlkXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWQgfHwgaXNOYXppb25lRGlzYWJsZWRcIlxyXG4gICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcclxuICAgICAgICBhcmlhLWxhYmVsPVwiU2VsZXppb25hIG5hemlvbmVcIlxyXG4gICAgICA+XHJcbiAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm51bGxcIj5TZWxlemlvbmEgbmF6aW9uZTwvbWF0LW9wdGlvbj5cclxuICAgICAgICBAZm9yIChuYXppb25lIG9mIG5hemlvbmk7IHRyYWNrIG5hemlvbmUuY29kU3RhdG9Qaykge1xyXG4gICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm5hemlvbmUuY29kU3RhdG9Qa1wiPlxyXG4gICAgICAgICAgICB7eyBuYXppb25lLmRlc2NyaXppb25lIH19XHJcbiAgICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgfVxyXG4gICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIEBpZiAoc2hvdWxkU2hvd0ZpZWxkRXJyb3JzKCduYXppb25lSWQnKSkge1xyXG4gICAgICAgIDxtYXQtZXJyb3I+XHJcbiAgICAgICAgICBAZm9yIChlcnJvciBvZiBnZXRGaWVsZEVycm9ycygnbmF6aW9uZUlkJyk7IHRyYWNrICRpbmRleCkge1xyXG4gICAgICAgICAgICA8ZGl2Pnt7IGVycm9yIH19PC9kaXY+XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgPC9tYXQtZXJyb3I+XHJcbiAgICAgIH1cclxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT09PT0gQ0FNUEkgSVRBTElBID09PT09PT09PT09PT09PT09PT09IC0tPlxyXG4gIEBpZiAoaXNJdGFsaWFuKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwidWktbG9jYXRpb25fX3Byb3ZpbmNpYS1jb211bmVcIj5cclxuICAgICAgPCEtLSBQcm92aW5jaWEgLS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZmllbGQtcm93XCI+XHJcbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZnVsbC13aWR0aFwiPlxyXG4gICAgICAgICAgPG1hdC1sYWJlbD57eyBsYWJlbHMucHJvdmluY2lhIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICA8bWF0LXNlbGVjdFxyXG4gICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJwcm92aW5jaWFJZFwiXHJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXHJcbiAgICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcclxuICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlNlbGV6aW9uYSBwcm92aW5jaWFcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwibnVsbFwiPlNlbGV6aW9uYSBwcm92aW5jaWE8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgIEBmb3IgKHByb3Ygb2YgcHJvdmluY2U7IHRyYWNrIHByb3YuY29kaWNlUHJvdmluY2lhUGspIHtcclxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwicHJvdi5jb2RpY2VQcm92aW5jaWFQa1wiPlxyXG4gICAgICAgICAgICAgICAge3sgcHJvdi5ub21lUHJvdmluY2lhIH19XHJcbiAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgICAgICBAaWYgKHNob3VsZFNob3dGaWVsZEVycm9ycygncHJvdmluY2lhSWQnKSkge1xyXG4gICAgICAgICAgICA8bWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgIEBmb3IgKGVycm9yIG9mIGdldEZpZWxkRXJyb3JzKCdwcm92aW5jaWFJZCcpOyB0cmFjayAkaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIDxkaXY+e3sgZXJyb3IgfX08L2Rpdj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgPCEtLSBDb211bmUgLS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZmllbGQtcm93XCI+XHJcbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZnVsbC13aWR0aFwiPlxyXG4gICAgICAgICAgPG1hdC1sYWJlbD57eyBsYWJlbHMuY29tdW5lIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICA8bWF0LXNlbGVjdFxyXG4gICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJjb211bmVJZFwiXHJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXHJcbiAgICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcclxuICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlNlbGV6aW9uYSBjb211bmVcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwibnVsbFwiPlNlbGV6aW9uYSBjb211bmU8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgIEBmb3IgKGNvbXVuZSBvZiBmaWx0ZXJlZENvbXVuaTsgdHJhY2sgY29tdW5lLmNvZGljZUNvbXVuZVBrKSB7XHJcbiAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cImNvbXVuZS5jb2RpY2VDb211bmVQa1wiPlxyXG4gICAgICAgICAgICAgICAge3sgY29tdW5lLm5vbWVDb211bmUgfX1cclxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICAgIEBpZiAoc2hvdWxkU2hvd0ZpZWxkRXJyb3JzKCdjb211bmVJZCcpKSB7XHJcbiAgICAgICAgICAgIDxtYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgQGZvciAoZXJyb3Igb2YgZ2V0RmllbGRFcnJvcnMoJ2NvbXVuZUlkJyk7IHRyYWNrICRpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgPGRpdj57eyBlcnJvciB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tID09PT09PT09PT09PT09PT09PT09IEdSSUdMSUEgQ0FNUEkgRElOQU1JQ0kgPT09PT09PT09PT09PT09PT09PT0gLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwidWktbG9jYXRpb25fX2R5bmFtaWMtZ3JpZFwiPlxyXG4gICAgICA8IS0tIENBUCAtLT5cclxuICAgICAgQGlmIChzaG93Q0FQICYmIGlzSXRhbGlhbikge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZ3JpZC1jZWxsXCIgW3N0eWxlLmdyaWQtY29sdW1uXT1cIidzcGFuICcgKyBjYXBDb2x1bW5zXCI+XHJcbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInVpLWxvY2F0aW9uX19mdWxsLXdpZHRoXCI+XHJcbiAgICAgICAgICAgIDxtYXQtbGFiZWw+e3sgbGFiZWxzLmNhcCB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICA8bWF0LXNlbGVjdFxyXG4gICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImNhcFwiXHJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkIHx8IGlzQ2FwRGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcclxuICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiU2VsZXppb25hIENBUFwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwibnVsbFwiPlNlbGV6aW9uYSBDQVA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgICAgQGZvciAoY2FwIG9mIGZpbHRlcmVkQ2FwczsgdHJhY2sgY2FwLmlkKSB7XHJcbiAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiY2FwLmlkXCI+e3sgY2FwLmNvZGljZSB9fTwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICAgICAgQGlmIChzaG91bGRTaG93RmllbGRFcnJvcnMoJ2NhcCcpKSB7XHJcbiAgICAgICAgICAgICAgPG1hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgIEBmb3IgKGVycm9yIG9mIGdldEZpZWxkRXJyb3JzKCdjYXAnKTsgdHJhY2sgJGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgIDxkaXY+e3sgZXJyb3IgfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgfVxyXG5cclxuICAgICAgPCEtLSBJbmRpcml6em8gLS0+XHJcbiAgICAgIEBpZiAoc2hvd0luZGlyaXp6bykge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZ3JpZC1jZWxsXCIgW3N0eWxlLmdyaWQtY29sdW1uXT1cIidzcGFuICcgKyBpbmRpcml6em9Db2x1bW5zXCI+XHJcbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInVpLWxvY2F0aW9uX19mdWxsLXdpZHRoXCI+XHJcbiAgICAgICAgICAgIDxtYXQtbGFiZWw+e3sgbGFiZWxzLmluZGlyaXp6byB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImluZGlyaXp6b1wiXHJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJWaWEsIG51bWVybyBjaXZpY29cIlxyXG4gICAgICAgICAgICAgIFtyZWFkb25seV09XCJkaXNhYmxlZFwiXHJcbiAgICAgICAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxyXG4gICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICBAaWYgKHNob3VsZFNob3dGaWVsZEVycm9ycygnaW5kaXJpenpvJykpIHtcclxuICAgICAgICAgICAgICA8bWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgQGZvciAoZXJyb3Igb2YgZ2V0RmllbGRFcnJvcnMoJ2luZGlyaXp6bycpOyB0cmFjayAkaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgPGRpdj57eyBlcnJvciB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcblxyXG4gICAgICA8IS0tIE1haWwgLS0+XHJcbiAgICAgIEBpZiAoc2hvd01haWwpIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwidWktbG9jYXRpb25fX2dyaWQtY2VsbFwiIFtzdHlsZS5ncmlkLWNvbHVtbl09XCInc3BhbiAnICsgbWFpbENvbHVtbnNcIj5cclxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIGNsYXNzPVwidWktbG9jYXRpb25fX2Z1bGwtd2lkdGhcIj5cclxuICAgICAgICAgICAgPG1hdC1sYWJlbD57eyBsYWJlbHMubWFpbCB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgIHR5cGU9XCJlbWFpbFwiXHJcbiAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibWFpbFwiXHJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlc2VtcGlvQGVtYWlsLmNvbVwiXHJcbiAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cImRpc2FibGVkXCJcclxuICAgICAgICAgICAgICAoYmx1cik9XCJvbkJsdXIoKVwiXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIEBpZiAoc2hvdWxkU2hvd0ZpZWxkRXJyb3JzKCdtYWlsJykpIHtcclxuICAgICAgICAgICAgICA8bWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgQGZvciAoZXJyb3Igb2YgZ2V0RmllbGRFcnJvcnMoJ21haWwnKTsgdHJhY2sgJGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgIDxkaXY+e3sgZXJyb3IgfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgfVxyXG5cclxuICAgICAgPCEtLSBQRUMgLS0+XHJcbiAgICAgIEBpZiAoc2hvd1BFQykge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ1aS1sb2NhdGlvbl9fZ3JpZC1jZWxsXCIgW3N0eWxlLmdyaWQtY29sdW1uXT1cIidzcGFuICcgKyBwZWNDb2x1bW5zXCI+XHJcbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInVpLWxvY2F0aW9uX19mdWxsLXdpZHRoXCI+XHJcbiAgICAgICAgICAgIDxtYXQtbGFiZWw+e3sgbGFiZWxzLnBlYyB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgIHR5cGU9XCJlbWFpbFwiXHJcbiAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwicGVjXCJcclxuICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImVzZW1waW9AcGVjLml0XCJcclxuICAgICAgICAgICAgICBbcmVhZG9ubHldPVwiZGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcclxuICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgQGlmIChzaG91bGRTaG93RmllbGRFcnJvcnMoJ3BlYycpKSB7XHJcbiAgICAgICAgICAgICAgPG1hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgIEBmb3IgKGVycm9yIG9mIGdldEZpZWxkRXJyb3JzKCdwZWMnKTsgdHJhY2sgJGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgIDxkaXY+e3sgZXJyb3IgfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgfVxyXG5cclxuICAgICAgPCEtLSBUZWxlZm9ubyAtLT5cclxuICAgICAgQGlmIChzaG93VGVsZWZvbm8pIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwidWktbG9jYXRpb25fX2dyaWQtY2VsbFwiIFtzdHlsZS5ncmlkLWNvbHVtbl09XCInc3BhbiAnICsgdGVsZWZvbm9Db2x1bW5zXCI+XHJcbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInVpLWxvY2F0aW9uX19mdWxsLXdpZHRoXCI+XHJcbiAgICAgICAgICAgIDxtYXQtbGFiZWw+e3sgbGFiZWxzLnRlbGVmb25vIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgdHlwZT1cInRlbFwiXHJcbiAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwidGVsZWZvbm9cIlxyXG4gICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiKzM5IDEyMyA0NTYgNzg5MFwiXHJcbiAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cImRpc2FibGVkXCJcclxuICAgICAgICAgICAgICAoYmx1cik9XCJvbkJsdXIoKVwiXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIEBpZiAoc2hvdWxkU2hvd0ZpZWxkRXJyb3JzKCd0ZWxlZm9ubycpKSB7XHJcbiAgICAgICAgICAgICAgPG1hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgIEBmb3IgKGVycm9yIG9mIGdldEZpZWxkRXJyb3JzKCd0ZWxlZm9ubycpOyB0cmFjayAkaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgPGRpdj57eyBlcnJvciB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICB9XHJcblxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT09PT0gQ0FNUE8gRVNURVJPID09PT09PT09PT09PT09PT09PT09IC0tPlxyXG4gIEBpZiAoaXNGb3JlaWduKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwidWktbG9jYXRpb25fX2ZpZWxkLXJvd1wiPlxyXG4gICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInVpLWxvY2F0aW9uX19mdWxsLXdpZHRoXCI+XHJcbiAgICAgICAgPG1hdC1sYWJlbD57eyBsYWJlbHMuY29tdW5lRXN0ZXJvIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiY29tdW5lRXN0ZXJvXCJcclxuICAgICAgICAgIHBsYWNlaG9sZGVyPVwiSW5zZXJpc2NpIGNpdHRhL2NvbXVuZVwiXHJcbiAgICAgICAgICBbcmVhZG9ubHldPVwiZGlzYWJsZWRcIlxyXG4gICAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxyXG4gICAgICAgIC8+XHJcbiAgICAgICAgQGlmIChzaG91bGRTaG93RmllbGRFcnJvcnMoJ2NvbXVuZUVzdGVybycpKSB7XHJcbiAgICAgICAgICA8bWF0LWVycm9yPlxyXG4gICAgICAgICAgICBAZm9yIChlcnJvciBvZiBnZXRGaWVsZEVycm9ycygnY29tdW5lRXN0ZXJvJyk7IHRyYWNrICRpbmRleCkge1xyXG4gICAgICAgICAgICAgIDxkaXY+e3sgZXJyb3IgfX08L2Rpdj5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgPC9tYXQtZXJyb3I+XHJcbiAgICAgICAgfVxyXG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgPC9kaXY+XHJcbiAgfVxyXG48L2Rpdj5cclxuIl19