@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,472 @@
1
+ /**
2
+ * @module ng-ui-system/form-builder-editor
3
+ * Componente editor di sezione per il form builder.
4
+ *
5
+ * Renderizza una singola sezione del form come card, con supporto
6
+ * per espansione/collasso, editing inline del titolo, drag & drop
7
+ * dei campi e azioni CRUD su sezione e campi.
8
+ */
9
+ import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core';
10
+ import { FormsModule } from '@angular/forms';
11
+ import { MatCardModule } from '@angular/material/card';
12
+ import { MatFormFieldModule } from '@angular/material/form-field';
13
+ import { MatInputModule } from '@angular/material/input';
14
+ import { DragDropModule } from '@angular/cdk/drag-drop';
15
+ import { LucideAngularModule } from 'lucide-angular';
16
+ import { UiButtonComponent } from '../../../button/index';
17
+ import * as i0 from "@angular/core";
18
+ import * as i1 from "@angular/forms";
19
+ import * as i2 from "@angular/material/card";
20
+ import * as i3 from "@angular/material/form-field";
21
+ import * as i4 from "@angular/material/input";
22
+ import * as i5 from "@angular/cdk/drag-drop";
23
+ import * as i6 from "lucide-angular";
24
+ /**
25
+ * Mappa tipo di campo -> nome icona Lucide.
26
+ * Usata per visualizzare l'icona corretta accanto a ciascun campo.
27
+ */
28
+ const FIELD_ICON_MAP = {
29
+ text: 'type',
30
+ email: 'mail',
31
+ password: 'lock', // NOSONAR - Icon name for password field type, not a credential
32
+ number: 'hash',
33
+ textarea: 'text',
34
+ select: 'chevron-down',
35
+ multiselect: 'list',
36
+ freemultiselect: 'list-plus',
37
+ radio: 'circle-dot',
38
+ checkbox: 'check-square',
39
+ switch: 'toggle-left',
40
+ date: 'calendar',
41
+ datetime: 'clock',
42
+ file: 'upload',
43
+ flag: 'flag',
44
+ custom: 'settings',
45
+ divider: 'minus',
46
+ location: 'map-pin',
47
+ 'location-table': 'map',
48
+ };
49
+ /**
50
+ * Editor visuale di una singola sezione del form.
51
+ *
52
+ * Supporta:
53
+ * - Header espandibile/collassabile con editing inline del titolo
54
+ * - Pulsanti azione: modifica titolo, duplica, elimina
55
+ * - Drop list CDK per ricevere campi dalla palette o da altre sezioni
56
+ * - Ogni campo mostra: handle di trascinamento, icona tipo, label, chiave, badge tipo, asterisco required
57
+ * - Azioni campo (al passaggio mouse): duplica, elimina
58
+ * - Stato vuoto quando non ci sono campi
59
+ */
60
+ export class UiSectionEditorComponent {
61
+ constructor() {
62
+ /** Indica se la sezione e attualmente selezionata. */
63
+ this.isSelected = false;
64
+ /** Chiave del campo attualmente selezionato (o null). */
65
+ this.selectedFieldKey = null;
66
+ /** Emette aggiornamenti parziali alla sezione. */
67
+ this.sectionUpdate = new EventEmitter();
68
+ /** Emette richiesta di eliminazione della sezione. */
69
+ this.sectionDelete = new EventEmitter();
70
+ /** Emette richiesta di duplicazione della sezione. */
71
+ this.sectionDuplicate = new EventEmitter();
72
+ /** Emette la chiave del campo selezionato. */
73
+ this.fieldSelect = new EventEmitter();
74
+ /** Emette la chiave del campo da duplicare. */
75
+ this.fieldDuplicate = new EventEmitter();
76
+ /** Emette la chiave del campo da eliminare. */
77
+ this.fieldDelete = new EventEmitter();
78
+ /** Emette l'evento di drop del CDK drag & drop. */
79
+ this.fieldDrop = new EventEmitter();
80
+ /** Stato di espansione della sezione. */
81
+ this.isExpanded = true;
82
+ /** Indica se il titolo e in fase di modifica inline. */
83
+ this.isEditingTitle = false;
84
+ /** Titolo temporaneo durante la modifica inline. */
85
+ this.tempTitle = '';
86
+ }
87
+ /**
88
+ * Alterna lo stato di espansione/collasso della sezione.
89
+ */
90
+ toggleExpand() {
91
+ this.isExpanded = !this.isExpanded;
92
+ }
93
+ /**
94
+ * Avvia la modifica inline del titolo della sezione.
95
+ * @param event - Evento del mouse per prevenire la propagazione.
96
+ */
97
+ startTitleEdit(event) {
98
+ event.stopPropagation();
99
+ this.tempTitle = this.section.title || '';
100
+ this.isEditingTitle = true;
101
+ }
102
+ /**
103
+ * Conferma la modifica del titolo ed emette l'aggiornamento.
104
+ */
105
+ confirmTitleEdit() {
106
+ if (this.isEditingTitle) {
107
+ this.isEditingTitle = false;
108
+ const trimmed = this.tempTitle.trim();
109
+ if (trimmed && trimmed !== this.section.title) {
110
+ this.sectionUpdate.emit({ title: trimmed });
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Annulla la modifica del titolo, ripristinando il valore originale.
116
+ */
117
+ cancelTitleEdit() {
118
+ this.isEditingTitle = false;
119
+ this.tempTitle = '';
120
+ }
121
+ /**
122
+ * Restituisce il nome dell'icona Lucide associata al tipo di campo.
123
+ * @param type - Tipo di campo del form.
124
+ * @returns Nome dell'icona Lucide.
125
+ */
126
+ getFieldIcon(type) {
127
+ return FIELD_ICON_MAP[type] || 'help-circle';
128
+ }
129
+ /**
130
+ * Gestisce l'evento di drop del CDK drag & drop e lo propaga al parent.
131
+ * @param event - Evento CdkDragDrop.
132
+ */
133
+ onFieldDrop(event) {
134
+ this.fieldDrop.emit(event);
135
+ }
136
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UiSectionEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
137
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: UiSectionEditorComponent, isStandalone: true, selector: "ui-section-editor", inputs: { section: "section", isSelected: "isSelected", selectedFieldKey: "selectedFieldKey" }, outputs: { sectionUpdate: "sectionUpdate", sectionDelete: "sectionDelete", sectionDuplicate: "sectionDuplicate", fieldSelect: "fieldSelect", fieldDuplicate: "fieldDuplicate", fieldDelete: "fieldDelete", fieldDrop: "fieldDrop" }, ngImport: i0, template: `
138
+ <!-- Card della sezione -->
139
+ <mat-card
140
+ class="section-card"
141
+ [class.section-card--selected]="isSelected"
142
+ >
143
+ <!-- Header della sezione -->
144
+ <div class="section-header" (click)="toggleExpand()">
145
+ <!-- Indicatore espansione -->
146
+ <ui-button
147
+ [icon]="isExpanded ? 'chevron-down' : 'chevron-right'"
148
+ variant="ghost"
149
+ size="sm"
150
+ [tooltip]="isExpanded ? 'Comprimi sezione' : 'Espandi sezione'"
151
+ ariaLabel="Espandi/Comprimi sezione"
152
+ />
153
+
154
+ <!-- Titolo della sezione (doppio click per modificare) -->
155
+ @if (isEditingTitle) {
156
+ <mat-form-field class="section-header__title-field" appearance="outline">
157
+ <input
158
+ matInput
159
+ [(ngModel)]="tempTitle"
160
+ (blur)="confirmTitleEdit()"
161
+ (keydown.enter)="confirmTitleEdit()"
162
+ (keydown.escape)="cancelTitleEdit()"
163
+ (click)="$event.stopPropagation()"
164
+ autofocus
165
+ />
166
+ </mat-form-field>
167
+ } @else {
168
+ <span
169
+ class="section-header__title"
170
+ (dblclick)="startTitleEdit($event)"
171
+ >
172
+ {{ section.title || 'Sezione senza titolo' }}
173
+ </span>
174
+ }
175
+
176
+ <!-- Badge conteggio campi -->
177
+ <span class="section-header__badge">
178
+ {{ section.fields.length }} {{ section.fields.length === 1 ? 'campo' : 'campi' }}
179
+ </span>
180
+
181
+ <!-- Azioni sezione -->
182
+ <div class="section-header__actions" (click)="$event.stopPropagation()">
183
+ <ui-button
184
+ icon="pencil"
185
+ variant="ghost"
186
+ size="sm"
187
+ ariaLabel="Modifica titolo"
188
+ tooltip="Modifica titolo"
189
+ (click)="startTitleEdit($event)"
190
+ />
191
+
192
+ <ui-button
193
+ icon="copy"
194
+ variant="ghost"
195
+ size="sm"
196
+ ariaLabel="Duplica sezione"
197
+ tooltip="Duplica sezione"
198
+ (click)="sectionDuplicate.emit()"
199
+ />
200
+
201
+ <ui-button
202
+ icon="trash-2"
203
+ variant="warn"
204
+ size="sm"
205
+ ariaLabel="Elimina sezione"
206
+ tooltip="Elimina sezione"
207
+ (click)="sectionDelete.emit()"
208
+ />
209
+ </div>
210
+ </div>
211
+
212
+ <!-- Corpo della sezione (espandibile) -->
213
+ @if (isExpanded) {
214
+ <div class="section-body">
215
+ <!-- Drop list CDK per i campi -->
216
+ <div
217
+ cdkDropList
218
+ [cdkDropListData]="section"
219
+ [id]="'section-' + section.id"
220
+ (cdkDropListDropped)="onFieldDrop($event)"
221
+ class="field-drop-list"
222
+ >
223
+ @for (field of section.fields; track field.key) {
224
+ <div
225
+ class="field-item"
226
+ cdkDrag
227
+ [cdkDragData]="field"
228
+ [class.field-item--selected]="field.key === selectedFieldKey"
229
+ (click)="fieldSelect.emit(field.key)"
230
+ >
231
+ <!-- Handle di trascinamento -->
232
+ <div class="field-item__handle" cdkDragHandle>
233
+ <lucide-icon name="grip-vertical" [size]="16" />
234
+ </div>
235
+
236
+ <!-- Icona tipo campo -->
237
+ <div class="field-item__icon">
238
+ <lucide-icon [name]="getFieldIcon(field.type)" [size]="16" />
239
+ </div>
240
+
241
+ <!-- Informazioni campo -->
242
+ <div class="field-item__info">
243
+ <span class="field-item__label">
244
+ {{ field.label || 'Senza etichetta' }}
245
+ @if (field.required) {
246
+ <span class="field-item__required">*</span>
247
+ }
248
+ </span>
249
+ <span class="field-item__key">{{ field.key }}</span>
250
+ </div>
251
+
252
+ <!-- Badge tipo campo -->
253
+ <span class="field-item__type-badge">{{ field.type }}</span>
254
+
255
+ <!-- Azioni campo (visibili al passaggio del mouse) -->
256
+ <div class="field-item__actions" (click)="$event.stopPropagation()">
257
+ <ui-button
258
+ icon="copy"
259
+ variant="ghost"
260
+ size="xs"
261
+ ariaLabel="Duplica campo"
262
+ tooltip="Duplica campo"
263
+ (click)="fieldDuplicate.emit(field.key)"
264
+ />
265
+
266
+ <ui-button
267
+ icon="trash-2"
268
+ variant="warn"
269
+ size="xs"
270
+ ariaLabel="Elimina campo"
271
+ tooltip="Elimina campo"
272
+ (click)="fieldDelete.emit(field.key)"
273
+ />
274
+ </div>
275
+ </div>
276
+ } @empty {
277
+ <!-- Stato vuoto -->
278
+ <div class="field-drop-list__empty">
279
+ <lucide-icon name="mouse-pointer-click" [size]="24" />
280
+ <span>Trascina qui i campi dalla palette</span>
281
+ </div>
282
+ }
283
+ </div>
284
+ </div>
285
+ }
286
+ </mat-card>
287
+ `, isInline: true, styles: [":host{display:block}.section-card{border:2px solid var(--ui-color-border);border-radius:var(--ui-radius-md);overflow:hidden;transition:border-color var(--ui-transition-fast),box-shadow var(--ui-transition-fast)}.section-card:hover{box-shadow:var(--ui-shadow-sm)}.section-card--selected{border-color:var(--ui-color-primary);box-shadow:var(--ui-shadow-md)}.section-header{display:flex;align-items:center;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-bg-subtle);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background var(--ui-transition-fast)}.section-header:hover{background:var(--ui-color-surface)}.section-header__title{flex:1;font-size:var(--ui-font-size-md);font-weight:600;color:var(--ui-color-text);cursor:pointer}.section-header__title-field{flex:1}.section-header__title-field ::ng-deep .mat-mdc-form-field-infix{padding-top:var(--ui-spacing-1)!important;padding-bottom:var(--ui-spacing-1)!important;min-height:unset}.section-header__badge{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted);background:var(--ui-color-surface);padding:var(--ui-spacing-1) var(--ui-spacing-2);border-radius:var(--ui-radius-sm);white-space:nowrap}.section-header__actions{display:flex;align-items:center;gap:var(--ui-spacing-1);opacity:0;transition:opacity var(--ui-transition-fast)}.section-header:hover .section-header__actions{opacity:1}.section-body{padding:var(--ui-spacing-3)}.field-drop-list{min-height:48px;border:2px dashed var(--ui-color-border);border-radius:var(--ui-radius-sm);transition:border-color var(--ui-transition-fast),background var(--ui-transition-fast)}.field-drop-list.cdk-drop-list-dragging{border-color:var(--ui-color-primary);background:var(--ui-color-primary-bg)}.field-drop-list__empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--ui-spacing-2);padding:var(--ui-spacing-6) var(--ui-spacing-4);color:var(--ui-color-text-muted);font-size:var(--ui-font-size-sm)}.field-item{display:flex;align-items:center;gap:var(--ui-spacing-2);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface);border-bottom:1px solid var(--ui-color-border);cursor:pointer;transition:background var(--ui-transition-fast)}.field-item:first-child{border-top-left-radius:var(--ui-radius-sm);border-top-right-radius:var(--ui-radius-sm)}.field-item:last-child{border-bottom:none;border-bottom-left-radius:var(--ui-radius-sm);border-bottom-right-radius:var(--ui-radius-sm)}.field-item:hover{background:var(--ui-color-bg-subtle)}.field-item--selected{background:var(--ui-color-primary-bg);border-left:3px solid var(--ui-color-primary)}.field-item__handle{display:flex;align-items:center;cursor:grab;color:var(--ui-color-text-muted);transition:color var(--ui-transition-fast)}.field-item__handle:active{cursor:grabbing}.field-item:hover .field-item__handle{color:var(--ui-color-text-secondary)}.field-item__icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--ui-radius-sm);background:var(--ui-color-bg-subtle);color:var(--ui-color-primary)}.field-item__info{flex:1;display:flex;flex-direction:column;min-width:0}.field-item__label{font-size:var(--ui-font-size-sm);font-weight:500;color:var(--ui-color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.field-item__required{color:var(--ui-color-warn);margin-left:var(--ui-spacing-1)}.field-item__key{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted);font-family:monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.field-item__type-badge{font-size:var(--ui-font-size-xs);color:var(--ui-color-primary);background:var(--ui-color-primary-bg);padding:2px var(--ui-spacing-2);border-radius:var(--ui-radius-sm);white-space:nowrap;font-weight:500}.field-item__actions{display:flex;align-items:center;gap:var(--ui-spacing-1);opacity:0;transition:opacity var(--ui-transition-fast)}.field-item:hover .field-item__actions{opacity:1}.cdk-drag-preview{box-sizing:border-box;border-radius:var(--ui-radius-sm);box-shadow:var(--ui-shadow-md);background:var(--ui-color-surface);padding:var(--ui-spacing-2) var(--ui-spacing-3);display:flex;align-items:center;gap:var(--ui-spacing-2)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i6.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["label", "tooltip", "variant", "size", "icon", "iconPosition", "loading", "disabled", "fullWidth", "type", "ariaLabel", "customClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
288
+ }
289
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UiSectionEditorComponent, decorators: [{
290
+ type: Component,
291
+ args: [{ selector: 'ui-section-editor', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
292
+ FormsModule,
293
+ MatCardModule,
294
+ MatFormFieldModule,
295
+ MatInputModule,
296
+ DragDropModule,
297
+ LucideAngularModule,
298
+ UiButtonComponent,
299
+ ], template: `
300
+ <!-- Card della sezione -->
301
+ <mat-card
302
+ class="section-card"
303
+ [class.section-card--selected]="isSelected"
304
+ >
305
+ <!-- Header della sezione -->
306
+ <div class="section-header" (click)="toggleExpand()">
307
+ <!-- Indicatore espansione -->
308
+ <ui-button
309
+ [icon]="isExpanded ? 'chevron-down' : 'chevron-right'"
310
+ variant="ghost"
311
+ size="sm"
312
+ [tooltip]="isExpanded ? 'Comprimi sezione' : 'Espandi sezione'"
313
+ ariaLabel="Espandi/Comprimi sezione"
314
+ />
315
+
316
+ <!-- Titolo della sezione (doppio click per modificare) -->
317
+ @if (isEditingTitle) {
318
+ <mat-form-field class="section-header__title-field" appearance="outline">
319
+ <input
320
+ matInput
321
+ [(ngModel)]="tempTitle"
322
+ (blur)="confirmTitleEdit()"
323
+ (keydown.enter)="confirmTitleEdit()"
324
+ (keydown.escape)="cancelTitleEdit()"
325
+ (click)="$event.stopPropagation()"
326
+ autofocus
327
+ />
328
+ </mat-form-field>
329
+ } @else {
330
+ <span
331
+ class="section-header__title"
332
+ (dblclick)="startTitleEdit($event)"
333
+ >
334
+ {{ section.title || 'Sezione senza titolo' }}
335
+ </span>
336
+ }
337
+
338
+ <!-- Badge conteggio campi -->
339
+ <span class="section-header__badge">
340
+ {{ section.fields.length }} {{ section.fields.length === 1 ? 'campo' : 'campi' }}
341
+ </span>
342
+
343
+ <!-- Azioni sezione -->
344
+ <div class="section-header__actions" (click)="$event.stopPropagation()">
345
+ <ui-button
346
+ icon="pencil"
347
+ variant="ghost"
348
+ size="sm"
349
+ ariaLabel="Modifica titolo"
350
+ tooltip="Modifica titolo"
351
+ (click)="startTitleEdit($event)"
352
+ />
353
+
354
+ <ui-button
355
+ icon="copy"
356
+ variant="ghost"
357
+ size="sm"
358
+ ariaLabel="Duplica sezione"
359
+ tooltip="Duplica sezione"
360
+ (click)="sectionDuplicate.emit()"
361
+ />
362
+
363
+ <ui-button
364
+ icon="trash-2"
365
+ variant="warn"
366
+ size="sm"
367
+ ariaLabel="Elimina sezione"
368
+ tooltip="Elimina sezione"
369
+ (click)="sectionDelete.emit()"
370
+ />
371
+ </div>
372
+ </div>
373
+
374
+ <!-- Corpo della sezione (espandibile) -->
375
+ @if (isExpanded) {
376
+ <div class="section-body">
377
+ <!-- Drop list CDK per i campi -->
378
+ <div
379
+ cdkDropList
380
+ [cdkDropListData]="section"
381
+ [id]="'section-' + section.id"
382
+ (cdkDropListDropped)="onFieldDrop($event)"
383
+ class="field-drop-list"
384
+ >
385
+ @for (field of section.fields; track field.key) {
386
+ <div
387
+ class="field-item"
388
+ cdkDrag
389
+ [cdkDragData]="field"
390
+ [class.field-item--selected]="field.key === selectedFieldKey"
391
+ (click)="fieldSelect.emit(field.key)"
392
+ >
393
+ <!-- Handle di trascinamento -->
394
+ <div class="field-item__handle" cdkDragHandle>
395
+ <lucide-icon name="grip-vertical" [size]="16" />
396
+ </div>
397
+
398
+ <!-- Icona tipo campo -->
399
+ <div class="field-item__icon">
400
+ <lucide-icon [name]="getFieldIcon(field.type)" [size]="16" />
401
+ </div>
402
+
403
+ <!-- Informazioni campo -->
404
+ <div class="field-item__info">
405
+ <span class="field-item__label">
406
+ {{ field.label || 'Senza etichetta' }}
407
+ @if (field.required) {
408
+ <span class="field-item__required">*</span>
409
+ }
410
+ </span>
411
+ <span class="field-item__key">{{ field.key }}</span>
412
+ </div>
413
+
414
+ <!-- Badge tipo campo -->
415
+ <span class="field-item__type-badge">{{ field.type }}</span>
416
+
417
+ <!-- Azioni campo (visibili al passaggio del mouse) -->
418
+ <div class="field-item__actions" (click)="$event.stopPropagation()">
419
+ <ui-button
420
+ icon="copy"
421
+ variant="ghost"
422
+ size="xs"
423
+ ariaLabel="Duplica campo"
424
+ tooltip="Duplica campo"
425
+ (click)="fieldDuplicate.emit(field.key)"
426
+ />
427
+
428
+ <ui-button
429
+ icon="trash-2"
430
+ variant="warn"
431
+ size="xs"
432
+ ariaLabel="Elimina campo"
433
+ tooltip="Elimina campo"
434
+ (click)="fieldDelete.emit(field.key)"
435
+ />
436
+ </div>
437
+ </div>
438
+ } @empty {
439
+ <!-- Stato vuoto -->
440
+ <div class="field-drop-list__empty">
441
+ <lucide-icon name="mouse-pointer-click" [size]="24" />
442
+ <span>Trascina qui i campi dalla palette</span>
443
+ </div>
444
+ }
445
+ </div>
446
+ </div>
447
+ }
448
+ </mat-card>
449
+ `, styles: [":host{display:block}.section-card{border:2px solid var(--ui-color-border);border-radius:var(--ui-radius-md);overflow:hidden;transition:border-color var(--ui-transition-fast),box-shadow var(--ui-transition-fast)}.section-card:hover{box-shadow:var(--ui-shadow-sm)}.section-card--selected{border-color:var(--ui-color-primary);box-shadow:var(--ui-shadow-md)}.section-header{display:flex;align-items:center;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-bg-subtle);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background var(--ui-transition-fast)}.section-header:hover{background:var(--ui-color-surface)}.section-header__title{flex:1;font-size:var(--ui-font-size-md);font-weight:600;color:var(--ui-color-text);cursor:pointer}.section-header__title-field{flex:1}.section-header__title-field ::ng-deep .mat-mdc-form-field-infix{padding-top:var(--ui-spacing-1)!important;padding-bottom:var(--ui-spacing-1)!important;min-height:unset}.section-header__badge{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted);background:var(--ui-color-surface);padding:var(--ui-spacing-1) var(--ui-spacing-2);border-radius:var(--ui-radius-sm);white-space:nowrap}.section-header__actions{display:flex;align-items:center;gap:var(--ui-spacing-1);opacity:0;transition:opacity var(--ui-transition-fast)}.section-header:hover .section-header__actions{opacity:1}.section-body{padding:var(--ui-spacing-3)}.field-drop-list{min-height:48px;border:2px dashed var(--ui-color-border);border-radius:var(--ui-radius-sm);transition:border-color var(--ui-transition-fast),background var(--ui-transition-fast)}.field-drop-list.cdk-drop-list-dragging{border-color:var(--ui-color-primary);background:var(--ui-color-primary-bg)}.field-drop-list__empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--ui-spacing-2);padding:var(--ui-spacing-6) var(--ui-spacing-4);color:var(--ui-color-text-muted);font-size:var(--ui-font-size-sm)}.field-item{display:flex;align-items:center;gap:var(--ui-spacing-2);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface);border-bottom:1px solid var(--ui-color-border);cursor:pointer;transition:background var(--ui-transition-fast)}.field-item:first-child{border-top-left-radius:var(--ui-radius-sm);border-top-right-radius:var(--ui-radius-sm)}.field-item:last-child{border-bottom:none;border-bottom-left-radius:var(--ui-radius-sm);border-bottom-right-radius:var(--ui-radius-sm)}.field-item:hover{background:var(--ui-color-bg-subtle)}.field-item--selected{background:var(--ui-color-primary-bg);border-left:3px solid var(--ui-color-primary)}.field-item__handle{display:flex;align-items:center;cursor:grab;color:var(--ui-color-text-muted);transition:color var(--ui-transition-fast)}.field-item__handle:active{cursor:grabbing}.field-item:hover .field-item__handle{color:var(--ui-color-text-secondary)}.field-item__icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--ui-radius-sm);background:var(--ui-color-bg-subtle);color:var(--ui-color-primary)}.field-item__info{flex:1;display:flex;flex-direction:column;min-width:0}.field-item__label{font-size:var(--ui-font-size-sm);font-weight:500;color:var(--ui-color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.field-item__required{color:var(--ui-color-warn);margin-left:var(--ui-spacing-1)}.field-item__key{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted);font-family:monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.field-item__type-badge{font-size:var(--ui-font-size-xs);color:var(--ui-color-primary);background:var(--ui-color-primary-bg);padding:2px var(--ui-spacing-2);border-radius:var(--ui-radius-sm);white-space:nowrap;font-weight:500}.field-item__actions{display:flex;align-items:center;gap:var(--ui-spacing-1);opacity:0;transition:opacity var(--ui-transition-fast)}.field-item:hover .field-item__actions{opacity:1}.cdk-drag-preview{box-sizing:border-box;border-radius:var(--ui-radius-sm);box-shadow:var(--ui-shadow-md);background:var(--ui-color-surface);padding:var(--ui-spacing-2) var(--ui-spacing-3);display:flex;align-items:center;gap:var(--ui-spacing-2)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
450
+ }], propDecorators: { section: [{
451
+ type: Input,
452
+ args: [{ required: true }]
453
+ }], isSelected: [{
454
+ type: Input
455
+ }], selectedFieldKey: [{
456
+ type: Input
457
+ }], sectionUpdate: [{
458
+ type: Output
459
+ }], sectionDelete: [{
460
+ type: Output
461
+ }], sectionDuplicate: [{
462
+ type: Output
463
+ }], fieldSelect: [{
464
+ type: Output
465
+ }], fieldDuplicate: [{
466
+ type: Output
467
+ }], fieldDelete: [{
468
+ type: Output
469
+ }], fieldDrop: [{
470
+ type: Output
471
+ }] } });
472
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdGlvbi1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbmctdWktc3lzdGVtL3NyYy9saWIvY29tcG9uZW50cy9mb3JtLWJ1aWxkZXItZWRpdG9yL3N1Yi1jb21wb25lbnRzL3NlY3Rpb24tZWRpdG9yL3NlY3Rpb24tZWRpdG9yLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztHQU9HO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSx1QkFBdUIsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQWUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7Ozs7Ozs7O0FBSTFEOzs7R0FHRztBQUNILE1BQU0sY0FBYyxHQUFnQztJQUNsRCxJQUFJLEVBQUUsTUFBTTtJQUNaLEtBQUssRUFBRSxNQUFNO0lBQ2IsUUFBUSxFQUFFLE1BQU0sRUFBRSxnRUFBZ0U7SUFDbEYsTUFBTSxFQUFFLE1BQU07SUFDZCxRQUFRLEVBQUUsTUFBTTtJQUNoQixNQUFNLEVBQUUsY0FBYztJQUN0QixXQUFXLEVBQUUsTUFBTTtJQUNuQixlQUFlLEVBQUUsV0FBVztJQUM1QixLQUFLLEVBQUUsWUFBWTtJQUNuQixRQUFRLEVBQUUsY0FBYztJQUN4QixNQUFNLEVBQUUsYUFBYTtJQUNyQixJQUFJLEVBQUUsVUFBVTtJQUNoQixRQUFRLEVBQUUsT0FBTztJQUNqQixJQUFJLEVBQUUsUUFBUTtJQUNkLElBQUksRUFBRSxNQUFNO0lBQ1osTUFBTSxFQUFFLFVBQVU7SUFDbEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsUUFBUSxFQUFFLFNBQVM7SUFDbkIsZ0JBQWdCLEVBQUUsS0FBSztDQUN4QixDQUFDO0FBRUY7Ozs7Ozs7Ozs7R0FVRztBQW1hSCxNQUFNLE9BQU8sd0JBQXdCO0lBbGFyQztRQXNhRSxzREFBc0Q7UUFDN0MsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUU1Qix5REFBeUQ7UUFDaEQscUJBQWdCLEdBQWtCLElBQUksQ0FBQztRQUVoRCxrREFBa0Q7UUFDeEMsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBMEIsQ0FBQztRQUVyRSxzREFBc0Q7UUFDNUMsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRW5ELHNEQUFzRDtRQUM1QyxxQkFBZ0IsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRXRELDhDQUE4QztRQUNwQyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFFbkQsK0NBQStDO1FBQ3JDLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUV0RCwrQ0FBK0M7UUFDckMsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRW5ELG1EQUFtRDtRQUN6QyxjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQW9CLENBQUM7UUFFM0QseUNBQXlDO1FBQ3pDLGVBQVUsR0FBRyxJQUFJLENBQUM7UUFFbEIsd0RBQXdEO1FBQ3hELG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBRXZCLG9EQUFvRDtRQUNwRCxjQUFTLEdBQUcsRUFBRSxDQUFDO0tBd0RoQjtJQXREQzs7T0FFRztJQUNILFlBQVk7UUFDVixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsY0FBYyxDQUFDLEtBQVk7UUFDekIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO0lBQzdCLENBQUM7SUFFRDs7T0FFRztJQUNILGdCQUFnQjtRQUNkLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1lBQzVCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDdEMsSUFBSSxPQUFPLElBQUksT0FBTyxLQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQzlDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsSUFBaUI7UUFDNUIsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksYUFBYSxDQUFDO0lBQy9DLENBQUM7SUFFRDs7O09BR0c7SUFDSCxXQUFXLENBQUMsS0FBdUI7UUFDakMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0IsQ0FBQzsrR0E3RlUsd0JBQXdCO21HQUF4Qix3QkFBd0Isa1pBclp6Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0pULDQwSUE5SkMsV0FBVyw4bUJBQ1gsYUFBYSw0SUFDYixrQkFBa0IseU9BQ2xCLGNBQWMsMFdBQ2QsY0FBYywybUNBQ2QsbUJBQW1CLGdQQUNuQixpQkFBaUI7OzRGQXVaUix3QkFBd0I7a0JBbGFwQyxTQUFTOytCQUNFLG1CQUFtQixjQUNqQixJQUFJLG1CQUNDLHVCQUF1QixDQUFDLE1BQU0sV0FDdEM7d0JBQ1AsV0FBVzt3QkFDWCxhQUFhO3dCQUNiLGtCQUFrQjt3QkFDbEIsY0FBYzt3QkFDZCxjQUFjO3dCQUNkLG1CQUFtQjt3QkFDbkIsaUJBQWlCO3FCQUNsQixZQUNTOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzSlQ7OEJBaVEwQixPQUFPO3NCQUFqQyxLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFHaEIsVUFBVTtzQkFBbEIsS0FBSztnQkFHRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBR0ksYUFBYTtzQkFBdEIsTUFBTTtnQkFHRyxhQUFhO3NCQUF0QixNQUFNO2dCQUdHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFHRyxXQUFXO3NCQUFwQixNQUFNO2dCQUdHLGNBQWM7c0JBQXZCLE1BQU07Z0JBR0csV0FBVztzQkFBcEIsTUFBTTtnQkFHRyxTQUFTO3NCQUFsQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEBtb2R1bGUgbmctdWktc3lzdGVtL2Zvcm0tYnVpbGRlci1lZGl0b3JcclxuICogQ29tcG9uZW50ZSBlZGl0b3IgZGkgc2V6aW9uZSBwZXIgaWwgZm9ybSBidWlsZGVyLlxyXG4gKlxyXG4gKiBSZW5kZXJpenphIHVuYSBzaW5nb2xhIHNlemlvbmUgZGVsIGZvcm0gY29tZSBjYXJkLCBjb24gc3VwcG9ydG9cclxuICogcGVyIGVzcGFuc2lvbmUvY29sbGFzc28sIGVkaXRpbmcgaW5saW5lIGRlbCB0aXRvbG8sIGRyYWcgJiBkcm9wXHJcbiAqIGRlaSBjYW1waSBlIGF6aW9uaSBDUlVEIHN1IHNlemlvbmUgZSBjYW1waS5cclxuICovXHJcblxyXG5pbXBvcnQgeyBDb21wb25lbnQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE1hdENhcmRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jYXJkJztcclxuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XHJcbmltcG9ydCB7IE1hdElucHV0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xyXG5pbXBvcnQgeyBDZGtEcmFnRHJvcCwgRHJhZ0Ryb3BNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcclxuaW1wb3J0IHsgTHVjaWRlQW5ndWxhck1vZHVsZSB9IGZyb20gJ2x1Y2lkZS1hbmd1bGFyJztcclxuXHJcbmltcG9ydCB7IFVpQnV0dG9uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vYnV0dG9uL2luZGV4JztcclxuaW1wb3J0IHsgVWlGb3JtU2VjdGlvbiB9IGZyb20gJy4uLy4uLy4uL2Zvcm0tYnVpbGRlci90eXBlcy9pbmRleCc7XHJcbmltcG9ydCB7IFVpRmllbGRUeXBlIH0gZnJvbSAnLi4vLi4vLi4vZm9ybS1idWlsZGVyL3R5cGVzL2luZGV4JztcclxuXHJcbi8qKlxyXG4gKiBNYXBwYSB0aXBvIGRpIGNhbXBvIC0+IG5vbWUgaWNvbmEgTHVjaWRlLlxyXG4gKiBVc2F0YSBwZXIgdmlzdWFsaXp6YXJlIGwnaWNvbmEgY29ycmV0dGEgYWNjYW50byBhIGNpYXNjdW4gY2FtcG8uXHJcbiAqL1xyXG5jb25zdCBGSUVMRF9JQ09OX01BUDogUmVjb3JkPFVpRmllbGRUeXBlLCBzdHJpbmc+ID0ge1xyXG4gIHRleHQ6ICd0eXBlJyxcclxuICBlbWFpbDogJ21haWwnLFxyXG4gIHBhc3N3b3JkOiAnbG9jaycsIC8vIE5PU09OQVIgLSBJY29uIG5hbWUgZm9yIHBhc3N3b3JkIGZpZWxkIHR5cGUsIG5vdCBhIGNyZWRlbnRpYWxcclxuICBudW1iZXI6ICdoYXNoJyxcclxuICB0ZXh0YXJlYTogJ3RleHQnLFxyXG4gIHNlbGVjdDogJ2NoZXZyb24tZG93bicsXHJcbiAgbXVsdGlzZWxlY3Q6ICdsaXN0JyxcclxuICBmcmVlbXVsdGlzZWxlY3Q6ICdsaXN0LXBsdXMnLFxyXG4gIHJhZGlvOiAnY2lyY2xlLWRvdCcsXHJcbiAgY2hlY2tib3g6ICdjaGVjay1zcXVhcmUnLFxyXG4gIHN3aXRjaDogJ3RvZ2dsZS1sZWZ0JyxcclxuICBkYXRlOiAnY2FsZW5kYXInLFxyXG4gIGRhdGV0aW1lOiAnY2xvY2snLFxyXG4gIGZpbGU6ICd1cGxvYWQnLFxyXG4gIGZsYWc6ICdmbGFnJyxcclxuICBjdXN0b206ICdzZXR0aW5ncycsXHJcbiAgZGl2aWRlcjogJ21pbnVzJyxcclxuICBsb2NhdGlvbjogJ21hcC1waW4nLFxyXG4gICdsb2NhdGlvbi10YWJsZSc6ICdtYXAnLFxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEVkaXRvciB2aXN1YWxlIGRpIHVuYSBzaW5nb2xhIHNlemlvbmUgZGVsIGZvcm0uXHJcbiAqXHJcbiAqIFN1cHBvcnRhOlxyXG4gKiAtIEhlYWRlciBlc3BhbmRpYmlsZS9jb2xsYXNzYWJpbGUgY29uIGVkaXRpbmcgaW5saW5lIGRlbCB0aXRvbG9cclxuICogLSBQdWxzYW50aSBhemlvbmU6IG1vZGlmaWNhIHRpdG9sbywgZHVwbGljYSwgZWxpbWluYVxyXG4gKiAtIERyb3AgbGlzdCBDREsgcGVyIHJpY2V2ZXJlIGNhbXBpIGRhbGxhIHBhbGV0dGUgbyBkYSBhbHRyZSBzZXppb25pXHJcbiAqIC0gT2duaSBjYW1wbyBtb3N0cmE6IGhhbmRsZSBkaSB0cmFzY2luYW1lbnRvLCBpY29uYSB0aXBvLCBsYWJlbCwgY2hpYXZlLCBiYWRnZSB0aXBvLCBhc3RlcmlzY28gcmVxdWlyZWRcclxuICogLSBBemlvbmkgY2FtcG8gKGFsIHBhc3NhZ2dpbyBtb3VzZSk6IGR1cGxpY2EsIGVsaW1pbmFcclxuICogLSBTdGF0byB2dW90byBxdWFuZG8gbm9uIGNpIHNvbm8gY2FtcGlcclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAndWktc2VjdGlvbi1lZGl0b3InLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgRm9ybXNNb2R1bGUsXHJcbiAgICBNYXRDYXJkTW9kdWxlLFxyXG4gICAgTWF0Rm9ybUZpZWxkTW9kdWxlLFxyXG4gICAgTWF0SW5wdXRNb2R1bGUsXHJcbiAgICBEcmFnRHJvcE1vZHVsZSxcclxuICAgIEx1Y2lkZUFuZ3VsYXJNb2R1bGUsXHJcbiAgICBVaUJ1dHRvbkNvbXBvbmVudCxcclxuICBdLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8IS0tIENhcmQgZGVsbGEgc2V6aW9uZSAtLT5cclxuICAgIDxtYXQtY2FyZFxyXG4gICAgICBjbGFzcz1cInNlY3Rpb24tY2FyZFwiXHJcbiAgICAgIFtjbGFzcy5zZWN0aW9uLWNhcmQtLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWRcIlxyXG4gICAgPlxyXG4gICAgICA8IS0tIEhlYWRlciBkZWxsYSBzZXppb25lIC0tPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1oZWFkZXJcIiAoY2xpY2spPVwidG9nZ2xlRXhwYW5kKClcIj5cclxuICAgICAgICA8IS0tIEluZGljYXRvcmUgZXNwYW5zaW9uZSAtLT5cclxuICAgICAgICA8dWktYnV0dG9uXHJcbiAgICAgICAgICBbaWNvbl09XCJpc0V4cGFuZGVkID8gJ2NoZXZyb24tZG93bicgOiAnY2hldnJvbi1yaWdodCdcIlxyXG4gICAgICAgICAgdmFyaWFudD1cImdob3N0XCJcclxuICAgICAgICAgIHNpemU9XCJzbVwiXHJcbiAgICAgICAgICBbdG9vbHRpcF09XCJpc0V4cGFuZGVkID8gJ0NvbXByaW1pIHNlemlvbmUnIDogJ0VzcGFuZGkgc2V6aW9uZSdcIlxyXG4gICAgICAgICAgYXJpYUxhYmVsPVwiRXNwYW5kaS9Db21wcmltaSBzZXppb25lXCJcclxuICAgICAgICAvPlxyXG5cclxuICAgICAgICA8IS0tIFRpdG9sbyBkZWxsYSBzZXppb25lIChkb3BwaW8gY2xpY2sgcGVyIG1vZGlmaWNhcmUpIC0tPlxyXG4gICAgICAgIEBpZiAoaXNFZGl0aW5nVGl0bGUpIHtcclxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cInNlY3Rpb24taGVhZGVyX190aXRsZS1maWVsZFwiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ0ZW1wVGl0bGVcIlxyXG4gICAgICAgICAgICAgIChibHVyKT1cImNvbmZpcm1UaXRsZUVkaXQoKVwiXHJcbiAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiY29uZmlybVRpdGxlRWRpdCgpXCJcclxuICAgICAgICAgICAgICAoa2V5ZG93bi5lc2NhcGUpPVwiY2FuY2VsVGl0bGVFZGl0KClcIlxyXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgICAgICAgIGF1dG9mb2N1c1xyXG4gICAgICAgICAgICAvPlxyXG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICB9IEBlbHNlIHtcclxuICAgICAgICAgIDxzcGFuXHJcbiAgICAgICAgICAgIGNsYXNzPVwic2VjdGlvbi1oZWFkZXJfX3RpdGxlXCJcclxuICAgICAgICAgICAgKGRibGNsaWNrKT1cInN0YXJ0VGl0bGVFZGl0KCRldmVudClcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICB7eyBzZWN0aW9uLnRpdGxlIHx8ICdTZXppb25lIHNlbnphIHRpdG9sbycgfX1cclxuICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIDwhLS0gQmFkZ2UgY29udGVnZ2lvIGNhbXBpIC0tPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2VjdGlvbi1oZWFkZXJfX2JhZGdlXCI+XHJcbiAgICAgICAgICB7eyBzZWN0aW9uLmZpZWxkcy5sZW5ndGggfX0ge3sgc2VjdGlvbi5maWVsZHMubGVuZ3RoID09PSAxID8gJ2NhbXBvJyA6ICdjYW1waScgfX1cclxuICAgICAgICA8L3NwYW4+XHJcblxyXG4gICAgICAgIDwhLS0gQXppb25pIHNlemlvbmUgLS0+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24taGVhZGVyX19hY3Rpb25zXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgPHVpLWJ1dHRvblxyXG4gICAgICAgICAgICBpY29uPVwicGVuY2lsXCJcclxuICAgICAgICAgICAgdmFyaWFudD1cImdob3N0XCJcclxuICAgICAgICAgICAgc2l6ZT1cInNtXCJcclxuICAgICAgICAgICAgYXJpYUxhYmVsPVwiTW9kaWZpY2EgdGl0b2xvXCJcclxuICAgICAgICAgICAgdG9vbHRpcD1cIk1vZGlmaWNhIHRpdG9sb1wiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJzdGFydFRpdGxlRWRpdCgkZXZlbnQpXCJcclxuICAgICAgICAgIC8+XHJcblxyXG4gICAgICAgICAgPHVpLWJ1dHRvblxyXG4gICAgICAgICAgICBpY29uPVwiY29weVwiXHJcbiAgICAgICAgICAgIHZhcmlhbnQ9XCJnaG9zdFwiXHJcbiAgICAgICAgICAgIHNpemU9XCJzbVwiXHJcbiAgICAgICAgICAgIGFyaWFMYWJlbD1cIkR1cGxpY2Egc2V6aW9uZVwiXHJcbiAgICAgICAgICAgIHRvb2x0aXA9XCJEdXBsaWNhIHNlemlvbmVcIlxyXG4gICAgICAgICAgICAoY2xpY2spPVwic2VjdGlvbkR1cGxpY2F0ZS5lbWl0KClcIlxyXG4gICAgICAgICAgLz5cclxuXHJcbiAgICAgICAgICA8dWktYnV0dG9uXHJcbiAgICAgICAgICAgIGljb249XCJ0cmFzaC0yXCJcclxuICAgICAgICAgICAgdmFyaWFudD1cIndhcm5cIlxyXG4gICAgICAgICAgICBzaXplPVwic21cIlxyXG4gICAgICAgICAgICBhcmlhTGFiZWw9XCJFbGltaW5hIHNlemlvbmVcIlxyXG4gICAgICAgICAgICB0b29sdGlwPVwiRWxpbWluYSBzZXppb25lXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cInNlY3Rpb25EZWxldGUuZW1pdCgpXCJcclxuICAgICAgICAgIC8+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgPCEtLSBDb3JwbyBkZWxsYSBzZXppb25lIChlc3BhbmRpYmlsZSkgLS0+XHJcbiAgICAgIEBpZiAoaXNFeHBhbmRlZCkge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLWJvZHlcIj5cclxuICAgICAgICAgIDwhLS0gRHJvcCBsaXN0IENESyBwZXIgaSBjYW1waSAtLT5cclxuICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgY2RrRHJvcExpc3RcclxuICAgICAgICAgICAgW2Nka0Ryb3BMaXN0RGF0YV09XCJzZWN0aW9uXCJcclxuICAgICAgICAgICAgW2lkXT1cIidzZWN0aW9uLScgKyBzZWN0aW9uLmlkXCJcclxuICAgICAgICAgICAgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJvbkZpZWxkRHJvcCgkZXZlbnQpXCJcclxuICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1kcm9wLWxpc3RcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICBAZm9yIChmaWVsZCBvZiBzZWN0aW9uLmZpZWxkczsgdHJhY2sgZmllbGQua2V5KSB7XHJcbiAgICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1pdGVtXCJcclxuICAgICAgICAgICAgICAgIGNka0RyYWdcclxuICAgICAgICAgICAgICAgIFtjZGtEcmFnRGF0YV09XCJmaWVsZFwiXHJcbiAgICAgICAgICAgICAgICBbY2xhc3MuZmllbGQtaXRlbS0tc2VsZWN0ZWRdPVwiZmllbGQua2V5ID09PSBzZWxlY3RlZEZpZWxkS2V5XCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJmaWVsZFNlbGVjdC5lbWl0KGZpZWxkLmtleSlcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDwhLS0gSGFuZGxlIGRpIHRyYXNjaW5hbWVudG8gLS0+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtaXRlbV9faGFuZGxlXCIgY2RrRHJhZ0hhbmRsZT5cclxuICAgICAgICAgICAgICAgICAgPGx1Y2lkZS1pY29uIG5hbWU9XCJncmlwLXZlcnRpY2FsXCIgW3NpemVdPVwiMTZcIiAvPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBJY29uYSB0aXBvIGNhbXBvIC0tPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWl0ZW1fX2ljb25cIj5cclxuICAgICAgICAgICAgICAgICAgPGx1Y2lkZS1pY29uIFtuYW1lXT1cImdldEZpZWxkSWNvbihmaWVsZC50eXBlKVwiIFtzaXplXT1cIjE2XCIgLz5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgIDwhLS0gSW5mb3JtYXppb25pIGNhbXBvIC0tPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWl0ZW1fX2luZm9cIj5cclxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWVsZC1pdGVtX19sYWJlbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7IGZpZWxkLmxhYmVsIHx8ICdTZW56YSBldGljaGV0dGEnIH19XHJcbiAgICAgICAgICAgICAgICAgICAgQGlmIChmaWVsZC5yZXF1aXJlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWVsZC1pdGVtX19yZXF1aXJlZFwiPio8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmllbGQtaXRlbV9fa2V5XCI+e3sgZmllbGQua2V5IH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBCYWRnZSB0aXBvIGNhbXBvIC0tPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWVsZC1pdGVtX190eXBlLWJhZGdlXCI+e3sgZmllbGQudHlwZSB9fTwvc3Bhbj5cclxuXHJcbiAgICAgICAgICAgICAgICA8IS0tIEF6aW9uaSBjYW1wbyAodmlzaWJpbGkgYWwgcGFzc2FnZ2lvIGRlbCBtb3VzZSkgLS0+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtaXRlbV9fYWN0aW9uc1wiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cclxuICAgICAgICAgICAgICAgICAgPHVpLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgIGljb249XCJjb3B5XCJcclxuICAgICAgICAgICAgICAgICAgICB2YXJpYW50PVwiZ2hvc3RcIlxyXG4gICAgICAgICAgICAgICAgICAgIHNpemU9XCJ4c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgYXJpYUxhYmVsPVwiRHVwbGljYSBjYW1wb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcD1cIkR1cGxpY2EgY2FtcG9cIlxyXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJmaWVsZER1cGxpY2F0ZS5lbWl0KGZpZWxkLmtleSlcIlxyXG4gICAgICAgICAgICAgICAgICAvPlxyXG5cclxuICAgICAgICAgICAgICAgICAgPHVpLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgIGljb249XCJ0cmFzaC0yXCJcclxuICAgICAgICAgICAgICAgICAgICB2YXJpYW50PVwid2FyblwiXHJcbiAgICAgICAgICAgICAgICAgICAgc2l6ZT1cInhzXCJcclxuICAgICAgICAgICAgICAgICAgICBhcmlhTGFiZWw9XCJFbGltaW5hIGNhbXBvXCJcclxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwPVwiRWxpbWluYSBjYW1wb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImZpZWxkRGVsZXRlLmVtaXQoZmllbGQua2V5KVwiXHJcbiAgICAgICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgfSBAZW1wdHkge1xyXG4gICAgICAgICAgICAgIDwhLS0gU3RhdG8gdnVvdG8gLS0+XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWRyb3AtbGlzdF9fZW1wdHlcIj5cclxuICAgICAgICAgICAgICAgIDxsdWNpZGUtaWNvbiBuYW1lPVwibW91c2UtcG9pbnRlci1jbGlja1wiIFtzaXplXT1cIjI0XCIgLz5cclxuICAgICAgICAgICAgICAgIDxzcGFuPlRyYXNjaW5hIHF1aSBpIGNhbXBpIGRhbGxhIHBhbGV0dGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcbiAgICA8L21hdC1jYXJkPlxyXG4gIGAsXHJcbiAgc3R5bGVzOiBbXHJcbiAgICBgXHJcbiAgICAvKiDilIDilIDilIAgQ2FyZCBzZXppb25lIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgCAqL1xyXG5cclxuICAgIDpob3N0IHtcclxuICAgICAgZGlzcGxheTogYmxvY2s7XHJcbiAgICB9XHJcblxyXG4gICAgLnNlY3Rpb24tY2FyZCB7XHJcbiAgICAgIGJvcmRlcjogMnB4IHNvbGlkIHZhcigtLXVpLWNvbG9yLWJvcmRlcik7XHJcbiAgICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXVpLXJhZGl1cy1tZCk7XHJcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XHJcbiAgICAgIHRyYW5zaXRpb246IGJvcmRlci1jb2xvciB2YXIoLS11aS10cmFuc2l0aW9uLWZhc3QpLFxyXG4gICAgICAgICAgICAgICAgICBib3gtc2hhZG93IHZhcigtLXVpLXRyYW5zaXRpb24tZmFzdCk7XHJcbiAgICB9XHJcblxyXG4gICAgLnNlY3Rpb24tY2FyZDpob3ZlciB7XHJcbiAgICAgIGJveC1zaGFkb3c6IHZhcigtLXVpLXNoYWRvdy1zbSk7XHJcbiAgICB9XHJcblxyXG4gICAgLnNlY3Rpb24tY2FyZC0tc2VsZWN0ZWQge1xyXG4gICAgICBib3JkZXItY29sb3I6IHZhcigtLXVpLWNvbG9yLXByaW1hcnkpO1xyXG4gICAgICBib3gtc2hhZG93OiB2YXIoLS11aS1zaGFkb3ctbWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIOKUgOKUgOKUgCBIZWFkZXIgc2V6aW9uZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgKi9cclxuXHJcbiAgICAuc2VjdGlvbi1oZWFkZXIge1xyXG4gICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xyXG4gICAgICBnYXA6IHZhcigtLXVpLXNwYWNpbmctMik7XHJcbiAgICAgIHBhZGRpbmc6IHZhcigtLXVpLXNwYWNpbmctMykgdmFyKC0tdWktc3BhY2luZy00KTtcclxuICAgICAgYmFja2dyb3VuZDogdmFyKC0tdWktY29sb3ItYmctc3VidGxlKTtcclxuICAgICAgY3Vyc29yOiBwb2ludGVyO1xyXG4gICAgICB1c2VyLXNlbGVjdDogbm9uZTtcclxuICAgICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCB2YXIoLS11aS10cmFuc2l0aW9uLWZhc3QpO1xyXG4gICAgfVxyXG5cclxuICAgIC5zZWN0aW9uLWhlYWRlcjpob3ZlciB7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXVpLWNvbG9yLXN1cmZhY2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC5zZWN0aW9uLWhlYWRlcl9fdGl0bGUge1xyXG4gICAgICBmbGV4OiAxO1xyXG4gICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS1tZCk7XHJcbiAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XHJcbiAgICAgIGNvbG9yOiB2YXIoLS11aS1jb2xvci10ZXh0KTtcclxuICAgICAgY3Vyc29yOiBwb2ludGVyO1xyXG4gICAgfVxyXG5cclxuICAgIC5zZWN0aW9uLWhlYWRlcl9fdGl0bGUtZmllbGQge1xyXG4gICAgICBmbGV4OiAxO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIFJpZHVjZSBpbCBwYWRkaW5nIGRlbCBmb3JtIGZpZWxkIGlubGluZSAqL1xyXG4gICAgLnNlY3Rpb24taGVhZGVyX190aXRsZS1maWVsZCA6Om5nLWRlZXAgLm1hdC1tZGMtZm9ybS1maWVsZC1pbmZpeCB7XHJcbiAgICAgIHBhZGRpbmctdG9wOiB2YXIoLS11aS1zcGFjaW5nLTEpICFpbXBvcnRhbnQ7XHJcbiAgICAgIHBhZGRpbmctYm90dG9tOiB2YXIoLS11aS1zcGFjaW5nLTEpICFpbXBvcnRhbnQ7XHJcbiAgICAgIG1pbi1oZWlnaHQ6IHVuc2V0O1xyXG4gICAgfVxyXG5cclxuICAgIC5zZWN0aW9uLWhlYWRlcl9fYmFkZ2Uge1xyXG4gICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS14cyk7XHJcbiAgICAgIGNvbG9yOiB2YXIoLS11aS1jb2xvci10ZXh0LW11dGVkKTtcclxuICAgICAgYmFja2dyb3VuZDogdmFyKC0tdWktY29sb3Itc3VyZmFjZSk7XHJcbiAgICAgIHBhZGRpbmc6IHZhcigtLXVpLXNwYWNpbmctMSkgdmFyKC0tdWktc3BhY2luZy0yKTtcclxuICAgICAgYm9yZGVyLXJhZGl1czogdmFyKC0tdWktcmFkaXVzLXNtKTtcclxuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcclxuICAgIH1cclxuXHJcbiAgICAuc2VjdGlvbi1oZWFkZXJfX2FjdGlvbnMge1xyXG4gICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xyXG4gICAgICBnYXA6IHZhcigtLXVpLXNwYWNpbmctMSk7XHJcbiAgICAgIG9wYWNpdHk6IDA7XHJcbiAgICAgIHRyYW5zaXRpb246IG9wYWNpdHkgdmFyKC0tdWktdHJhbnNpdGlvbi1mYXN0KTtcclxuICAgIH1cclxuXHJcbiAgICAuc2VjdGlvbi1oZWFkZXI6aG92ZXIgLnNlY3Rpb24taGVhZGVyX19hY3Rpb25zIHtcclxuICAgICAgb3BhY2l0eTogMTtcclxuICAgIH1cclxuXHJcbiAgICAvKiDilIDilIDilIAgQ29ycG8gc2V6aW9uZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgKi9cclxuXHJcbiAgICAuc2VjdGlvbi1ib2R5IHtcclxuICAgICAgcGFkZGluZzogdmFyKC0tdWktc3BhY2luZy0zKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiDilIDilIDilIAgRHJvcCBsaXN0IGNhbXBpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgCAqL1xyXG5cclxuICAgIC5maWVsZC1kcm9wLWxpc3Qge1xyXG4gICAgICBtaW4taGVpZ2h0OiA0OHB4O1xyXG4gICAgICBib3JkZXI6IDJweCBkYXNoZWQgdmFyKC0tdWktY29sb3ItYm9yZGVyKTtcclxuICAgICAgYm9yZGVyLXJhZGl1czogdmFyKC0tdWktcmFkaXVzLXNtKTtcclxuICAgICAgdHJhbnNpdGlvbjogYm9yZGVyLWNvbG9yIHZhcigtLXVpLXRyYW5zaXRpb24tZmFzdCksXHJcbiAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQgdmFyKC0tdWktdHJhbnNpdGlvbi1mYXN0KTtcclxuICAgIH1cclxuXHJcbiAgICAuZmllbGQtZHJvcC1saXN0LmNkay1kcm9wLWxpc3QtZHJhZ2dpbmcge1xyXG4gICAgICBib3JkZXItY29sb3I6IHZhcigtLXVpLWNvbG9yLXByaW1hcnkpO1xyXG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS11aS1jb2xvci1wcmltYXJ5LWJnKTtcclxuICAgIH1cclxuXHJcbiAgICAuZmllbGQtZHJvcC1saXN0X19lbXB0eSB7XHJcbiAgICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XHJcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xyXG4gICAgICBnYXA6IHZhcigtLXVpLXNwYWNpbmctMik7XHJcbiAgICAgIHBhZGRpbmc6IHZhcigtLXVpLXNwYWNpbmctNikgdmFyKC0tdWktc3BhY2luZy00KTtcclxuICAgICAgY29sb3I6IHZhcigtLXVpLWNvbG9yLXRleHQtbXV0ZWQpO1xyXG4gICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS1zbSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyog4pSA4pSA4pSAIEVsZW1lbnRvIGNhbXBvIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgCAqL1xyXG5cclxuICAgIC5maWVsZC1pdGVtIHtcclxuICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICAgICAgZ2FwOiB2YXIoLS11aS1zcGFjaW5nLTIpO1xyXG4gICAgICBwYWRkaW5nOiB2YXIoLS11aS1zcGFjaW5nLTIpIHZhcigtLXVpLXNwYWNpbmctMyk7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXVpLWNvbG9yLXN1cmZhY2UpO1xyXG4gICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tdWktY29sb3ItYm9yZGVyKTtcclxuICAgICAgY3Vyc29yOiBwb2ludGVyO1xyXG4gICAgICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIHZhcigtLXVpLXRyYW5zaXRpb24tZmFzdCk7XHJcbiAgICB9XHJcblxyXG4gICAgLmZpZWxkLWl0ZW06Zmlyc3QtY2hpbGQge1xyXG4gICAgICBib3JkZXItdG9wLWxlZnQtcmFkaXVzOiB2YXIoLS11aS1yYWRpdXMtc20pO1xyXG4gICAgICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogdmFyKC0tdWktcmFkaXVzLXNtKTtcclxuICAgIH1cclxuXHJcbiAgICAuZmllbGQtaXRlbTpsYXN0LWNoaWxkIHtcclxuICAgICAgYm9yZGVyLWJvdHRvbTogbm9uZTtcclxuICAgICAgYm9yZGVyLWJvdHRvbS1sZWZ0LXJhZGl1czogdmFyKC0tdWktcmFkaXVzLXNtKTtcclxuICAgICAgYm9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6IHZhcigtLXVpLXJhZGl1cy1zbSk7XHJcbiAgICB9XHJcblxyXG4gICAgLmZpZWxkLWl0ZW06aG92ZXIge1xyXG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS11aS1jb2xvci1iZy1zdWJ0bGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC5maWVsZC1pdGVtLS1zZWxlY3RlZCB7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXVpLWNvbG9yLXByaW1hcnktYmcpO1xyXG4gICAgICBib3JkZXItbGVmdDogM3B4IHNvbGlkIHZhcigtLXVpLWNvbG9yLXByaW1hcnkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIEhhbmRsZSBkaSB0cmFzY2luYW1lbnRvICovXHJcbiAgICAuZmllbGQtaXRlbV9faGFuZGxlIHtcclxuICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICAgICAgY3Vyc29yOiBncmFiO1xyXG4gICAgICBjb2xvcjogdmFyKC0tdWktY29sb3ItdGV4dC1tdXRlZCk7XHJcbiAgICAgIHRyYW5zaXRpb246IGNvbG9yIHZhcigtLXVpLXRyYW5zaXRpb24tZmFzdCk7XHJcbiAgICB9XHJcblxyXG4gICAgLmZpZWxkLWl0ZW1fX2hhbmRsZTphY3RpdmUge1xyXG4gICAgICBjdXJzb3I6IGdyYWJiaW5nO1xyXG4gICAgfVxyXG5cclxuICAgIC5maWVsZC1pdGVtOmhvdmVyIC5maWVsZC1pdGVtX19oYW5kbGUge1xyXG4gICAgICBjb2xvcjogdmFyKC0tdWktY29sb3ItdGV4dC1zZWNvbmRhcnkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIEljb25hIHRpcG8gY2FtcG8gKi9cclxuICAgIC5maWVsZC1pdGVtX19pY29uIHtcclxuICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XHJcbiAgICAgIHdpZHRoOiAyOHB4O1xyXG4gICAgICBoZWlnaHQ6IDI4cHg7XHJcbiAgICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXVpLXJhZGl1cy1zbSk7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXVpLWNvbG9yLWJnLXN1YnRsZSk7XHJcbiAgICAgIGNvbG9yOiB2YXIoLS11aS1jb2xvci1wcmltYXJ5KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBJbmZvcm1hemlvbmkgY2FtcG8gKi9cclxuICAgIC5maWVsZC1pdGVtX19pbmZvIHtcclxuICAgICAgZmxleDogMTtcclxuICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcclxuICAgICAgbWluLXdpZHRoOiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC5maWVsZC1pdGVtX19sYWJlbCB7XHJcbiAgICAgIGZvbnQtc2l6ZTogdmFyKC0tdWktZm9udC1zaXplLXNtKTtcclxuICAgICAgZm9udC13ZWlnaHQ6IDUwMDtcclxuICAgICAgY29sb3I6IHZhcigtLXVpLWNvbG9yLXRleHQpO1xyXG4gICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xyXG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xyXG4gICAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcclxuICAgIH1cclxuXHJcbiAgICAuZmllbGQtaXRlbV9fcmVxdWlyZWQge1xyXG4gICAgICBjb2xvcjogdmFyKC0tdWktY29sb3Itd2Fybik7XHJcbiAgICAgIG1hcmdpbi1sZWZ0OiB2YXIoLS11aS1zcGFjaW5nLTEpO1xyXG4gICAgfVxyXG5cclxuICAgIC5maWVsZC1pdGVtX19rZXkge1xyXG4gICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS14cyk7XHJcbiAgICAgIGNvbG9yOiB2YXIoLS11aS1jb2xvci10ZXh0LW11dGVkKTtcclxuICAgICAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcclxuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcclxuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcclxuICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyogQmFkZ2UgdGlwbyBjYW1wbyAqL1xyXG4gICAgLmZpZWxkLWl0ZW1fX3R5cGUtYmFkZ2Uge1xyXG4gICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS14cyk7XHJcbiAgICAgIGNvbG9yOiB2YXIoLS11aS1jb2xvci1wcmltYXJ5KTtcclxuICAgICAgYmFja2dyb3VuZDogdmFyKC0tdWktY29sb3ItcHJpbWFyeS1iZyk7XHJcbiAgICAgIHBhZGRpbmc6IDJweCB2YXIoLS11aS1zcGFjaW5nLTIpO1xyXG4gICAgICBib3JkZXItcmFkaXVzOiB2YXIoLS11aS1yYWRpdXMtc20pO1xyXG4gICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xyXG4gICAgICBmb250LXdlaWdodDogNTAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIEF6aW9uaSBjYW1wbyAqL1xyXG4gICAgLmZpZWxkLWl0ZW1fX2FjdGlvbnMge1xyXG4gICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xyXG4gICAgICBnYXA6IHZhcigtLXVpLXNwYWNpbmctMSk7XHJcbiAgICAgIG9wYWNpdHk6IDA7XHJcbiAgICAgIHRyYW5zaXRpb246IG9wYWNpdHkgdmFyKC0tdWktdHJhbnNpdGlvbi1mYXN0KTtcclxuICAgIH1cclxuXHJcbiAgICAuZmllbGQtaXRlbTpob3ZlciAuZmllbGQtaXRlbV9fYWN0aW9ucyB7XHJcbiAgICAgIG9wYWNpdHk6IDE7XHJcbiAgICB9XHJcblxyXG4gICAgLyog4pSA4pSA4pSAIENESyBEcmFnICYgRHJvcCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgKi9cclxuXHJcbiAgICAuY2RrLWRyYWctcHJldmlldyB7XHJcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XHJcbiAgICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXVpLXJhZGl1cy1zbSk7XHJcbiAgICAgIGJveC1zaGFkb3c6IHZhcigtLXVpLXNoYWRvdy1tZCk7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXVpLWNvbG9yLXN1cmZhY2UpO1xyXG4gICAgICBwYWRkaW5nOiB2YXIoLS11aS1zcGFjaW5nLTIpIHZhcigtLXVpLXNwYWNpbmctMyk7XHJcbiAgICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgICAgIGdhcDogdmFyKC0tdWktc3BhY2luZy0yKTtcclxuICAgIH1cclxuXHJcbiAgICAuY2RrLWRyYWctcGxhY2Vob2xkZXIge1xyXG4gICAgICBvcGFjaXR5OiAwLjM7XHJcbiAgICB9XHJcblxyXG4gICAgLmNkay1kcmFnLWFuaW1hdGluZyB7XHJcbiAgICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAyNTBtcyBjdWJpYy1iZXppZXIoMCwgMCwgMC4yLCAxKTtcclxuICAgIH1cclxuICBgLFxyXG4gIF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBVaVNlY3Rpb25FZGl0b3JDb21wb25lbnQge1xyXG4gIC8qKiBTZXppb25lIGRlbCBmb3JtIGRhIHJlbmRlcml6emFyZS4gKi9cclxuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBzZWN0aW9uITogVWlGb3JtU2VjdGlvbjtcclxuXHJcbiAgLyoqIEluZGljYSBzZSBsYSBzZXppb25lIGUgYXR0dWFsbWVudGUgc2VsZXppb25hdGEuICovXHJcbiAgQElucHV0KCkgaXNTZWxlY3RlZCA9IGZhbHNlO1xyXG5cclxuICAvKiogQ2hpYXZlIGRlbCBjYW1wbyBhdHR1YWxtZW50ZSBzZWxlemlvbmF0byAobyBudWxsKS4gKi9cclxuICBASW5wdXQoKSBzZWxlY3RlZEZpZWxkS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLyoqIEVtZXR0ZSBhZ2dpb3JuYW1lbnRpIHBhcnppYWxpIGFsbGEgc2V6aW9uZS4gKi9cclxuICBAT3V0cHV0KCkgc2VjdGlvblVwZGF0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8UGFydGlhbDxVaUZvcm1TZWN0aW9uPj4oKTtcclxuXHJcbiAgLyoqIEVtZXR0ZSByaWNoaWVzdGEgZGkgZWxpbWluYXppb25lIGRlbGxhIHNlemlvbmUuICovXHJcbiAgQE91dHB1dCgpIHNlY3Rpb25EZWxldGUgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8qKiBFbWV0dGUgcmljaGllc3RhIGRpIGR1cGxpY2F6aW9uZSBkZWxsYSBzZXppb25lLiAqL1xyXG4gIEBPdXRwdXQoKSBzZWN0aW9uRHVwbGljYXRlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAvKiogRW1ldHRlIGxhIGNoaWF2ZSBkZWwgY2FtcG8gc2VsZXppb25hdG8uICovXHJcbiAgQE91dHB1dCgpIGZpZWxkU2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcblxyXG4gIC8qKiBFbWV0dGUgbGEgY2hpYXZlIGRlbCBjYW1wbyBkYSBkdXBsaWNhcmUuICovXHJcbiAgQE91dHB1dCgpIGZpZWxkRHVwbGljYXRlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcblxyXG4gIC8qKiBFbWV0dGUgbGEgY2hpYXZlIGRlbCBjYW1wbyBkYSBlbGltaW5hcmUuICovXHJcbiAgQE91dHB1dCgpIGZpZWxkRGVsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcblxyXG4gIC8qKiBFbWV0dGUgbCdldmVudG8gZGkgZHJvcCBkZWwgQ0RLIGRyYWcgJiBkcm9wLiAqL1xyXG4gIEBPdXRwdXQoKSBmaWVsZERyb3AgPSBuZXcgRXZlbnRFbWl0dGVyPENka0RyYWdEcm9wPGFueT4+KCk7XHJcblxyXG4gIC8qKiBTdGF0byBkaSBlc3BhbnNpb25lIGRlbGxhIHNlemlvbmUuICovXHJcbiAgaXNFeHBhbmRlZCA9IHRydWU7XHJcblxyXG4gIC8qKiBJbmRpY2Egc2UgaWwgdGl0b2xvIGUgaW4gZmFzZSBkaSBtb2RpZmljYSBpbmxpbmUuICovXHJcbiAgaXNFZGl0aW5nVGl0bGUgPSBmYWxzZTtcclxuXHJcbiAgLyoqIFRpdG9sbyB0ZW1wb3JhbmVvIGR1cmFudGUgbGEgbW9kaWZpY2EgaW5saW5lLiAqL1xyXG4gIHRlbXBUaXRsZSA9ICcnO1xyXG5cclxuICAvKipcclxuICAgKiBBbHRlcm5hIGxvIHN0YXRvIGRpIGVzcGFuc2lvbmUvY29sbGFzc28gZGVsbGEgc2V6aW9uZS5cclxuICAgKi9cclxuICB0b2dnbGVFeHBhbmQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzRXhwYW5kZWQgPSAhdGhpcy5pc0V4cGFuZGVkO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQXZ2aWEgbGEgbW9kaWZpY2EgaW5saW5lIGRlbCB0aXRvbG8gZGVsbGEgc2V6aW9uZS5cclxuICAgKiBAcGFyYW0gZXZlbnQgLSBFdmVudG8gZGVsIG1vdXNlIHBlciBwcmV2ZW5pcmUgbGEgcHJvcGFnYXppb25lLlxyXG4gICAqL1xyXG4gIHN0YXJ0VGl0bGVFZGl0KGV2ZW50OiBFdmVudCk6IHZvaWQge1xyXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB0aGlzLnRlbXBUaXRsZSA9IHRoaXMuc2VjdGlvbi50aXRsZSB8fCAnJztcclxuICAgIHRoaXMuaXNFZGl0aW5nVGl0bGUgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29uZmVybWEgbGEgbW9kaWZpY2EgZGVsIHRpdG9sbyBlZCBlbWV0dGUgbCdhZ2dpb3JuYW1lbnRvLlxyXG4gICAqL1xyXG4gIGNvbmZpcm1UaXRsZUVkaXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5pc0VkaXRpbmdUaXRsZSkge1xyXG4gICAgICB0aGlzLmlzRWRpdGluZ1RpdGxlID0gZmFsc2U7XHJcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSB0aGlzLnRlbXBUaXRsZS50cmltKCk7XHJcbiAgICAgIGlmICh0cmltbWVkICYmIHRyaW1tZWQgIT09IHRoaXMuc2VjdGlvbi50aXRsZSkge1xyXG4gICAgICAgIHRoaXMuc2VjdGlvblVwZGF0ZS5lbWl0KHsgdGl0bGU6IHRyaW1tZWQgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFubnVsbGEgbGEgbW9kaWZpY2EgZGVsIHRpdG9sbywgcmlwcmlzdGluYW5kbyBpbCB2YWxvcmUgb3JpZ2luYWxlLlxyXG4gICAqL1xyXG4gIGNhbmNlbFRpdGxlRWRpdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNFZGl0aW5nVGl0bGUgPSBmYWxzZTtcclxuICAgIHRoaXMudGVtcFRpdGxlID0gJyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXN0aXR1aXNjZSBpbCBub21lIGRlbGwnaWNvbmEgTHVjaWRlIGFzc29jaWF0YSBhbCB0aXBvIGRpIGNhbXBvLlxyXG4gICAqIEBwYXJhbSB0eXBlIC0gVGlwbyBkaSBjYW1wbyBkZWwgZm9ybS5cclxuICAgKiBAcmV0dXJucyBOb21lIGRlbGwnaWNvbmEgTHVjaWRlLlxyXG4gICAqL1xyXG4gIGdldEZpZWxkSWNvbih0eXBlOiBVaUZpZWxkVHlwZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gRklFTERfSUNPTl9NQVBbdHlwZV0gfHwgJ2hlbHAtY2lyY2xlJztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdlc3Rpc2NlIGwnZXZlbnRvIGRpIGRyb3AgZGVsIENESyBkcmFnICYgZHJvcCBlIGxvIHByb3BhZ2EgYWwgcGFyZW50LlxyXG4gICAqIEBwYXJhbSBldmVudCAtIEV2ZW50byBDZGtEcmFnRHJvcC5cclxuICAgKi9cclxuICBvbkZpZWxkRHJvcChldmVudDogQ2RrRHJhZ0Ryb3A8YW55Pik6IHZvaWQge1xyXG4gICAgdGhpcy5maWVsZERyb3AuZW1pdChldmVudCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==