@eqproject/eqp-dynamic-module 0.0.1

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 (125) hide show
  1. package/README.md +24 -0
  2. package/bundles/eqproject-eqp-dynamic-module.umd.js +3117 -0
  3. package/bundles/eqproject-eqp-dynamic-module.umd.js.map +1 -0
  4. package/bundles/eqproject-eqp-dynamic-module.umd.min.js +17 -0
  5. package/bundles/eqproject-eqp-dynamic-module.umd.min.js.map +1 -0
  6. package/eqproject-eqp-dynamic-module.d.ts +5 -0
  7. package/eqproject-eqp-dynamic-module.metadata.json +1 -0
  8. package/esm2015/eqproject-eqp-dynamic-module.js +6 -0
  9. package/esm2015/lib/components/exported/eqp-dynamic-module/eqp-dynamic-module.component.js +65 -0
  10. package/esm2015/lib/components/exported/eqp-dynamic-module-configurator/eqp-dynamic-module-configurator.component.js +534 -0
  11. package/esm2015/lib/components/private/add-form-field/add-form-field.component.js +486 -0
  12. package/esm2015/lib/components/private/dynamic-module-field/dynamic-module-field.component.js +127 -0
  13. package/esm2015/lib/components/private/field-templates/attachment-field-template/attachment-field-template.component.js +181 -0
  14. package/esm2015/lib/components/private/field-templates/boolean-field-template/boolean-field-template.component.js +56 -0
  15. package/esm2015/lib/components/private/field-templates/date-field-template/date-field-template.component.js +71 -0
  16. package/esm2015/lib/components/private/field-templates/image-field-template/image-field-template.component.js +54 -0
  17. package/esm2015/lib/components/private/field-templates/list-value-field-template/list-value-field-template.component.js +118 -0
  18. package/esm2015/lib/components/private/field-templates/numeric-field-template/numeric-field-template.component.js +63 -0
  19. package/esm2015/lib/components/private/field-templates/text-field-template/text-field-template.component.js +51 -0
  20. package/esm2015/lib/components/private/field-templates/textarea-field-template/textarea-field-template.component.js +51 -0
  21. package/esm2015/lib/components/private/form-records/add-form-record/add-form-record.component.js +126 -0
  22. package/esm2015/lib/components/private/form-records/list-form-record/list-form-record.component.js +210 -0
  23. package/esm2015/lib/eqp-dynamic-module.module.js +67 -0
  24. package/esm2015/lib/interfaces/iBaseFieldComponent.interface.js +1 -0
  25. package/esm2015/lib/interfaces/iRootObject.interface.js +1 -0
  26. package/esm2015/lib/models/baseField.model.js +36 -0
  27. package/esm2015/lib/models/baseObj.model.js +9 -0
  28. package/esm2015/lib/models/context.model.js +8 -0
  29. package/esm2015/lib/models/entity.model.js +7 -0
  30. package/esm2015/lib/models/fields/attachmentField.model.js +22 -0
  31. package/esm2015/lib/models/fields/booleanField.model.js +12 -0
  32. package/esm2015/lib/models/fields/dateField.model.js +11 -0
  33. package/esm2015/lib/models/fields/imageField.model.js +4 -0
  34. package/esm2015/lib/models/fields/listValueField.model.js +12 -0
  35. package/esm2015/lib/models/fields/lookupField.model.js +5 -0
  36. package/esm2015/lib/models/fields/numericField.model.js +5 -0
  37. package/esm2015/lib/models/fields/testareaField.model.js +4 -0
  38. package/esm2015/lib/models/fields/textField.model.js +5 -0
  39. package/esm2015/lib/models/form.model.js +24 -0
  40. package/esm2015/lib/models/record.model.js +3 -0
  41. package/esm2015/lib/modules/material.module.js +108 -0
  42. package/esm2015/lib/services/custom-form-validators.service.js +19 -0
  43. package/esm2015/lib/services/eqp-dynamic-module-dialog.service.js +104 -0
  44. package/esm2015/lib/services/utilityHelper.services.js +220 -0
  45. package/esm2015/public-api.js +37 -0
  46. package/esm5/eqproject-eqp-dynamic-module.js +6 -0
  47. package/esm5/lib/components/exported/eqp-dynamic-module/eqp-dynamic-module.component.js +66 -0
  48. package/esm5/lib/components/exported/eqp-dynamic-module-configurator/eqp-dynamic-module-configurator.component.js +546 -0
  49. package/esm5/lib/components/private/add-form-field/add-form-field.component.js +497 -0
  50. package/esm5/lib/components/private/dynamic-module-field/dynamic-module-field.component.js +128 -0
  51. package/esm5/lib/components/private/field-templates/attachment-field-template/attachment-field-template.component.js +184 -0
  52. package/esm5/lib/components/private/field-templates/boolean-field-template/boolean-field-template.component.js +57 -0
  53. package/esm5/lib/components/private/field-templates/date-field-template/date-field-template.component.js +72 -0
  54. package/esm5/lib/components/private/field-templates/image-field-template/image-field-template.component.js +55 -0
  55. package/esm5/lib/components/private/field-templates/list-value-field-template/list-value-field-template.component.js +121 -0
  56. package/esm5/lib/components/private/field-templates/numeric-field-template/numeric-field-template.component.js +64 -0
  57. package/esm5/lib/components/private/field-templates/text-field-template/text-field-template.component.js +52 -0
  58. package/esm5/lib/components/private/field-templates/textarea-field-template/textarea-field-template.component.js +52 -0
  59. package/esm5/lib/components/private/form-records/add-form-record/add-form-record.component.js +129 -0
  60. package/esm5/lib/components/private/form-records/list-form-record/list-form-record.component.js +216 -0
  61. package/esm5/lib/eqp-dynamic-module.module.js +70 -0
  62. package/esm5/lib/interfaces/iBaseFieldComponent.interface.js +1 -0
  63. package/esm5/lib/interfaces/iRootObject.interface.js +1 -0
  64. package/esm5/lib/models/baseField.model.js +43 -0
  65. package/esm5/lib/models/baseObj.model.js +13 -0
  66. package/esm5/lib/models/context.model.js +14 -0
  67. package/esm5/lib/models/entity.model.js +14 -0
  68. package/esm5/lib/models/fields/attachmentField.model.js +29 -0
  69. package/esm5/lib/models/fields/booleanField.model.js +19 -0
  70. package/esm5/lib/models/fields/dateField.model.js +18 -0
  71. package/esm5/lib/models/fields/imageField.model.js +11 -0
  72. package/esm5/lib/models/fields/listValueField.model.js +19 -0
  73. package/esm5/lib/models/fields/lookupField.model.js +12 -0
  74. package/esm5/lib/models/fields/numericField.model.js +12 -0
  75. package/esm5/lib/models/fields/testareaField.model.js +11 -0
  76. package/esm5/lib/models/fields/textField.model.js +12 -0
  77. package/esm5/lib/models/form.model.js +39 -0
  78. package/esm5/lib/models/record.model.js +7 -0
  79. package/esm5/lib/modules/material.module.js +111 -0
  80. package/esm5/lib/services/custom-form-validators.service.js +23 -0
  81. package/esm5/lib/services/eqp-dynamic-module-dialog.service.js +113 -0
  82. package/esm5/lib/services/utilityHelper.services.js +225 -0
  83. package/esm5/public-api.js +37 -0
  84. package/fesm2015/eqproject-eqp-dynamic-module.js +2757 -0
  85. package/fesm2015/eqproject-eqp-dynamic-module.js.map +1 -0
  86. package/fesm5/eqproject-eqp-dynamic-module.js +2902 -0
  87. package/fesm5/eqproject-eqp-dynamic-module.js.map +1 -0
  88. package/lib/components/exported/eqp-dynamic-module/eqp-dynamic-module.component.d.ts +21 -0
  89. package/lib/components/exported/eqp-dynamic-module-configurator/eqp-dynamic-module-configurator.component.d.ts +186 -0
  90. package/lib/components/private/add-form-field/add-form-field.component.d.ts +160 -0
  91. package/lib/components/private/dynamic-module-field/dynamic-module-field.component.d.ts +55 -0
  92. package/lib/components/private/field-templates/attachment-field-template/attachment-field-template.component.d.ts +84 -0
  93. package/lib/components/private/field-templates/boolean-field-template/boolean-field-template.component.d.ts +21 -0
  94. package/lib/components/private/field-templates/date-field-template/date-field-template.component.d.ts +27 -0
  95. package/lib/components/private/field-templates/image-field-template/image-field-template.component.d.ts +16 -0
  96. package/lib/components/private/field-templates/list-value-field-template/list-value-field-template.component.d.ts +59 -0
  97. package/lib/components/private/field-templates/numeric-field-template/numeric-field-template.component.d.ts +26 -0
  98. package/lib/components/private/field-templates/text-field-template/text-field-template.component.d.ts +20 -0
  99. package/lib/components/private/field-templates/textarea-field-template/textarea-field-template.component.d.ts +20 -0
  100. package/lib/components/private/form-records/add-form-record/add-form-record.component.d.ts +50 -0
  101. package/lib/components/private/form-records/list-form-record/list-form-record.component.d.ts +59 -0
  102. package/lib/eqp-dynamic-module.module.d.ts +2 -0
  103. package/lib/interfaces/iBaseFieldComponent.interface.d.ts +8 -0
  104. package/lib/interfaces/iRootObject.interface.d.ts +10 -0
  105. package/lib/models/baseField.model.d.ts +56 -0
  106. package/lib/models/baseObj.model.d.ts +9 -0
  107. package/lib/models/context.model.d.ts +9 -0
  108. package/lib/models/entity.model.d.ts +10 -0
  109. package/lib/models/fields/attachmentField.model.d.ts +17 -0
  110. package/lib/models/fields/booleanField.model.d.ts +11 -0
  111. package/lib/models/fields/dateField.model.d.ts +12 -0
  112. package/lib/models/fields/imageField.model.d.ts +10 -0
  113. package/lib/models/fields/listValueField.model.d.ts +21 -0
  114. package/lib/models/fields/lookupField.model.d.ts +10 -0
  115. package/lib/models/fields/numericField.model.d.ts +9 -0
  116. package/lib/models/fields/testareaField.model.d.ts +7 -0
  117. package/lib/models/fields/textField.model.d.ts +7 -0
  118. package/lib/models/form.model.d.ts +45 -0
  119. package/lib/models/record.model.d.ts +5 -0
  120. package/lib/modules/material.module.d.ts +2 -0
  121. package/lib/services/custom-form-validators.service.d.ts +5 -0
  122. package/lib/services/eqp-dynamic-module-dialog.service.d.ts +28 -0
  123. package/lib/services/utilityHelper.services.d.ts +48 -0
  124. package/package.json +39 -0
  125. package/public-api.d.ts +35 -0
@@ -0,0 +1,546 @@
1
+ import { __decorate } from "tslib";
2
+ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
3
+ import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
4
+ import { MatDialog, MatDialogRef } from '@angular/material/dialog';
5
+ import { CellAlignmentEnum, TypeColumn } from '@eqproject/eqp-table';
6
+ import { BaseField, FieldTypeEnum } from '../../../models/baseField.model';
7
+ import { Context } from '../../../models/context.model';
8
+ import { ActionOnRecord, Form, FormScalarTypeEnum, FormTypeEnum } from '../../../models/form.model';
9
+ import { ArrayValidators } from '../../../services/custom-form-validators.service';
10
+ import { EqpDynamicModuleDialogService } from '../../../services/eqp-dynamic-module-dialog.service';
11
+ import { UtilityHelperService } from '../../../services/utilityHelper.services';
12
+ var EqpDynamicModuleConfiguratorComponent = /** @class */ (function () {
13
+ function EqpDynamicModuleConfiguratorComponent(formBuilder, dialog) {
14
+ this.formBuilder = formBuilder;
15
+ this.dialog = dialog;
16
+ this.context = new Context();
17
+ this.form = new Form();
18
+ this.innerFormManagment = false;
19
+ this.formCompleted = false;
20
+ //#region Enumeratori usati nell'html
21
+ this.FormTypeEnum = FormTypeEnum;
22
+ this.FormScalarTypeEnum = FormScalarTypeEnum;
23
+ //#endregion
24
+ this.saveFormEvent = new EventEmitter();
25
+ }
26
+ EqpDynamicModuleConfiguratorComponent.prototype.ngOnInit = function () {
27
+ if (this.context) {
28
+ UtilityHelperService.SetContext(this.context);
29
+ }
30
+ this.configureColumns();
31
+ this.createFormForm();
32
+ };
33
+ /**
34
+ * Metodo invocato al cambio del tipo di visualizzazione della form.
35
+ * Se l'utente sceglie una visualizzazione raggruppata il metodo aggiunge al FormGroup un nuovo
36
+ * controllo per l'array dei nomi delle sezioni da creare.
37
+ */
38
+ EqpDynamicModuleConfiguratorComponent.prototype.onChangeFormScalarType = function () {
39
+ if (this.form.FormScalarType != FormScalarTypeEnum.Semplice) {
40
+ if (!this.formFormGroup.contains("FormFieldsGroups")) {
41
+ this.formFormGroup.removeControl("FormFieldsGroups");
42
+ this.formFormGroup.addControl("FormFieldsGroups", new FormControl(this.form.FormFieldsGroups, [Validators.required, ArrayValidators.minLenght(1)]));
43
+ }
44
+ }
45
+ else {
46
+ this.form.FormFieldsGroups = null;
47
+ if (this.formFormGroup.contains("FormFieldsGroups"))
48
+ this.formFormGroup.removeControl("FormFieldsGroups");
49
+ }
50
+ this.formFormGroup.updateValueAndValidity();
51
+ this.configureColumns();
52
+ };
53
+ /**
54
+ * Evento invocato al keyup nell'input per inserire i nomi delle sezioni per la visualizzazione
55
+ * raggruppata della form. Quanto l'utente preme il tasto invio viene aggiunto il nuovo nome alle
56
+ * sezioni dispobili se non ne esiste una con lo stesso nome.
57
+ * @param event Evento che rappresenta il keyup sulla tastiera.
58
+ */
59
+ EqpDynamicModuleConfiguratorComponent.prototype.onFormFieldGroupNameKeyUp = function (event) {
60
+ var _this = this;
61
+ if (event.code === 'Enter' || event.code === 'NumpadEnter') {
62
+ if (!this.form.FormFieldsGroups) {
63
+ this.form.FormFieldsGroups = new Array();
64
+ }
65
+ if (!this.form.FormFieldsGroups.find(function (n) { return n.Name == _this.formFieldGroupName; })) {
66
+ this.form.FormFieldsGroups.push({ Name: this.formFieldGroupName });
67
+ }
68
+ // Imposto il nuovo valore del FormControl per aggiornare lo stato della form.
69
+ this.formFormGroup.controls["FormFieldsGroups"].setValue(this.form.FormFieldsGroups);
70
+ this.formFieldGroupName = null;
71
+ this.setFormFieldGroupOrdinalPosition();
72
+ }
73
+ };
74
+ /**
75
+ * Metodo per rimuovere la sezione selezionata da quelle disponibili per la form.
76
+ * @param groupName Nome della sezione da eliminare.
77
+ */
78
+ EqpDynamicModuleConfiguratorComponent.prototype.onDeleteFormFieldGroupName = function (groupName) {
79
+ this.form.FormFieldsGroups.splice(this.form.FormFieldsGroups.findIndex(function (g) { return g.Name === groupName; }), 1);
80
+ // Imposto il nuovo valore del FormControl per aggiornare lo stato della form.
81
+ this.formFormGroup.controls["FormFieldsGroups"].setValue(this.form.FormFieldsGroups);
82
+ // Se esistono Field legati alla sezione che si vuole eliminare allora rompo il legame.
83
+ if (this.form.Fields.find(function (f) { return f.FieldGroup == groupName; })) {
84
+ this.form.Fields.filter(function (f) { return f.FieldGroup == groupName; }).forEach(function (f) { return f.FieldGroup = null; });
85
+ }
86
+ this.setFormFieldGroupOrdinalPosition();
87
+ };
88
+ /**
89
+ * Metodo chiamato quando si vuole aggiungere un nuovo campo o si vuole modificare uno esistente.
90
+ * Memorizza l'eventuale Field scelto one crea uno nuovo prima di aprire il dialog per modificarlo/aggiungerlo.
91
+ * @param field Oggetto BaseField da modificare. Se null ne viene creata una nuova istanza per l'aggiunta.
92
+ */
93
+ EqpDynamicModuleConfiguratorComponent.prototype.openFieldDialog = function (field) {
94
+ if (field === void 0) { field = null; }
95
+ if (field) {
96
+ this.indexSelectedField = this.form.Fields.indexOf(field);
97
+ this.selectedField = JSON.parse(JSON.stringify(field));
98
+ }
99
+ else {
100
+ this.selectedField = new BaseField();
101
+ this.indexSelectedField = null;
102
+ }
103
+ this.dialogFieldRef = this.dialog.open(this.dialogField, {
104
+ disableClose: true,
105
+ hasBackdrop: true,
106
+ width: '75%'
107
+ });
108
+ };
109
+ /**
110
+ * Metodo che salva il campo appena creato o modificato.
111
+ * Prima del salvataggio controlla se esiste un altro campo con la stessa label, in questo
112
+ * case genere un errore (i campi devono avere nomi, e quindi label, univoche - i nomi vengono
113
+ * ricavati unendo le parole che formano la label tramite "_").
114
+ * @param field Campo da salvare
115
+ */
116
+ EqpDynamicModuleConfiguratorComponent.prototype.onSaveField = function (field) {
117
+ var _this = this;
118
+ if (field) {
119
+ if (this.form.Fields
120
+ && this.form.Fields.find(function (f, i) { return f.Label === field.Label
121
+ && (_this.indexSelectedField == null ? true : _this.indexSelectedField !== i); })) {
122
+ EqpDynamicModuleDialogService.Warning('Impossibile inserire due campi con la stessa label.');
123
+ throw new Error('Impossibile inserire due campi con la stessa label.');
124
+ }
125
+ if (this.indexSelectedField != null && this.indexSelectedField >= 0) {
126
+ this.form.Fields[this.indexSelectedField] = field;
127
+ }
128
+ else {
129
+ if (!this.form.Fields) {
130
+ this.form.Fields = new Array();
131
+ }
132
+ this.form.Fields.push(field);
133
+ }
134
+ }
135
+ this.closeFieldDialog();
136
+ this.setFieldOrdinalPosition();
137
+ this.reloadFieldsTable();
138
+ };
139
+ /**
140
+ * Metodo che controlla se lo step per l'aggiunta dei campi nella form è concluso.
141
+ * @returns Se TRUE lo step viene considerato completato ed è possbile passare al successivo.
142
+ */
143
+ EqpDynamicModuleConfiguratorComponent.prototype.isFieldStepCompleted = function () {
144
+ if (!this.form.Fields) {
145
+ return false;
146
+ }
147
+ if (this.form.FormScalarType != FormScalarTypeEnum.Semplice && this.form.Fields.find(function (f) { return !f.FieldGroup; })) {
148
+ return false;
149
+ }
150
+ return this.form.Fields.length > 0;
151
+ };
152
+ /**
153
+ * Metodo per aprire il dialog di creazione/modifica delle form di dettaglio.
154
+ * Se il parametro passato è null sono in aggiunta altrimenti sono in modifica.
155
+ * @param innenrForm Form di dettaglio da modificare (se null allora vado in add).
156
+ */
157
+ EqpDynamicModuleConfiguratorComponent.prototype.openInnerFormDialog = function (innenrForm) {
158
+ if (innenrForm === void 0) { innenrForm = null; }
159
+ if (innenrForm) {
160
+ this.indexSelectedInnerForm = this.form.InnerForms.indexOf(innenrForm);
161
+ this.selectedInnerForm = JSON.parse(JSON.stringify(innenrForm));
162
+ this.selectedInnerForm.OldName = innenrForm.Name;
163
+ this.indexSelectedField = this.form.Fields.findIndex(function (f) { return f.Label === innenrForm.Name; });
164
+ }
165
+ else {
166
+ this.selectedInnerForm = new Form();
167
+ this.indexSelectedInnerForm = null;
168
+ this.indexSelectedField = null;
169
+ }
170
+ this.dialogInnerFormRef = this.dialog.open(this.dialogInnerForm, {
171
+ disableClose: true,
172
+ hasBackdrop: true,
173
+ width: '85%'
174
+ });
175
+ };
176
+ /**
177
+ * Metodo scatenato al salvataggio di una form di dettaglio.
178
+ * @param event Form creata/modificata dall'utente. Se è null allora l'utente ha abbandonato la configurazione.
179
+ */
180
+ EqpDynamicModuleConfiguratorComponent.prototype.onSaveOrExitInnerForm = function (event) {
181
+ var _this = this;
182
+ if (event != null) {
183
+ if (this.form.Name === event.Name ||
184
+ (this.form.InnerForms
185
+ && this.form.InnerForms.find(function (a, i) { return a.Name === event.Name
186
+ && (_this.indexSelectedInnerForm == null ? true : _this.indexSelectedInnerForm !== i); })) ||
187
+ (this.form.Fields
188
+ && this.indexSelectedInnerForm == null
189
+ && this.form.Fields.find(function (f, i) { return f.Label === event.Name
190
+ && (_this.indexSelectedField == null ? true : _this.indexSelectedField !== i); }))) {
191
+ EqpDynamicModuleDialogService.Warning('Impossibile inserire due form di dettaglio con lo stesso nome.');
192
+ throw new Error('Impossibile inserire due form di dettaglio con lo stesso nome.');
193
+ }
194
+ var innerFormField = new BaseField();
195
+ innerFormField.Name = event.Name.split(" ").join("_");
196
+ innerFormField.Label = event.Name;
197
+ innerFormField.FieldType = FieldTypeEnum['Form di dettaglio'];
198
+ innerFormField.FieldGroup = this.indexSelectedField != null ? this.form.Fields[this.indexSelectedField].FieldGroup : null;
199
+ if (this.indexSelectedInnerForm != null && this.indexSelectedInnerForm >= 0) {
200
+ this.form.InnerForms[this.indexSelectedInnerForm] = event;
201
+ this.form.Fields[this.indexSelectedField] = innerFormField;
202
+ }
203
+ else {
204
+ if (!this.form.InnerForms) {
205
+ this.form.InnerForms = new Array();
206
+ }
207
+ this.form.InnerForms.push(event);
208
+ this.form.Fields.push(innerFormField);
209
+ }
210
+ this.reloadFieldsTable();
211
+ }
212
+ this.dialogInnerFormRef.close();
213
+ };
214
+ /**
215
+ * Metodo per aprire il dialog di creazione/modifica delle action.
216
+ * Se il parametro passato è null sono in aggiunta altrimenti sono in modifica.
217
+ * @param action ActionOnRecord da modificare (se null allora vado in add).
218
+ */
219
+ EqpDynamicModuleConfiguratorComponent.prototype.openActionOnRecordDialog = function (action) {
220
+ if (action === void 0) { action = null; }
221
+ if (action) {
222
+ this.indexSelectedAction = this.form.ActionsOnRecord.indexOf(action);
223
+ this.selectedAction = JSON.parse(JSON.stringify(action));
224
+ }
225
+ else {
226
+ this.selectedAction = new ActionOnRecord();
227
+ this.indexSelectedAction = null;
228
+ }
229
+ this.createActionOnRecordForm();
230
+ this.dialogActionOnRecordRef = this.dialog.open(this.dialogActionOnRecord, {
231
+ disableClose: true,
232
+ hasBackdrop: true,
233
+ width: '75%'
234
+ });
235
+ };
236
+ /**
237
+ * Metodo per impostare i valori da suggerire nell'autocomplete del campo Formula.
238
+ * Viene scatenato al focus (in questo caso viene passato il parametro a null per differenziarlo
239
+ * dall'evento di click sulla tastiera) e al keyup sull'input (il parametro è diverso da null).
240
+ * @param keyboardEvent Evento scatenato al keyup sulla tastiera. Se null allora il metodo è stato invocato dal focus sull'input.
241
+ * @summary Aggiorna l'elenco dei suggerimenti per l'autocomplete se l'utente esegue il focus sull'input
242
+ * oppure al keyup sulla tastiera di un tasto diverso dalle frecce.
243
+ */
244
+ EqpDynamicModuleConfiguratorComponent.prototype.setActionAutocompleteOptions = function (keyboardEvent) {
245
+ // Creo l'array per l'autocomplete solo se sto facendo il focus sull'input o se sto premendo un tasto
246
+ // sulla tastiera diverso dalle frecce (in quest'ultimo caso, se non viene eseguito il filtro sull'evento,
247
+ // non si può selezionare un suggerimento dell'autocomplete perchè al click verrebbe ricaricato l'array e
248
+ // si prederebbe la selezione appena fatta).
249
+ if (!keyboardEvent || !keyboardEvent.code.includes("Arrow")) {
250
+ this.actionAutocompleteOptions = UtilityHelperService.GetAutocompleteOptions(this.form.Fields, this.selectedAction.Action);
251
+ }
252
+ };
253
+ /**
254
+ * Metodo per salvare l'azione creata/modificate.
255
+ */
256
+ EqpDynamicModuleConfiguratorComponent.prototype.saveActionOnRecord = function () {
257
+ var _this = this;
258
+ if (this.form.ActionsOnRecord
259
+ && this.form.ActionsOnRecord.find(function (a, i) { return a.Name === _this.selectedAction.Name
260
+ && (_this.indexSelectedAction == null ? true : _this.indexSelectedAction !== i); })) {
261
+ EqpDynamicModuleDialogService.Warning('Impossibile inserire due action con lo stesso nome.');
262
+ throw new Error('Impossibile inserire due action con lo stesso nome.');
263
+ }
264
+ if (this.indexSelectedAction != null && this.indexSelectedAction >= 0) {
265
+ this.form.ActionsOnRecord[this.indexSelectedAction] = this.selectedAction;
266
+ }
267
+ else {
268
+ if (!this.form.ActionsOnRecord) {
269
+ this.form.ActionsOnRecord = new Array();
270
+ }
271
+ this.form.ActionsOnRecord.push(this.selectedAction);
272
+ }
273
+ this.closeDialogActionOnRecord();
274
+ this.setActionOrdinalPosition();
275
+ this.reloadActionsOnRecordTable();
276
+ };
277
+ /**
278
+ * Metodo per chiudere il dialog di gestione delle action.
279
+ */
280
+ EqpDynamicModuleConfiguratorComponent.prototype.closeDialogActionOnRecord = function () {
281
+ this.dialogActionOnRecordRef.close();
282
+ };
283
+ /**
284
+ * Metodo per segnare come conclusa la creazione della form e per crearne una copia
285
+ * da visalizzare come anteprima.
286
+ * @param completed Se TRUE segna la form come conclusa e ne crea una copia da visualizzare
287
+ */
288
+ EqpDynamicModuleConfiguratorComponent.prototype.setFormStatus = function (completed) {
289
+ if (completed) {
290
+ this.formCompleted = true;
291
+ this.previewForm = JSON.parse(JSON.stringify(this.form));
292
+ // Per visualizzare correttamente l'oanteprima della form appena creata
293
+ // bisogna valorizzare la proprietà Name dei campi della form e delle InnerForms.
294
+ this.previewForm.Fields.forEach(function (field) { field.Name = field.Label.split(' ').join('_'); });
295
+ if (this.previewForm.InnerForms && this.previewForm.InnerForms.length > 0) {
296
+ this.previewForm.InnerForms.forEach(function (form) {
297
+ form.Fields.forEach(function (field) { field.Name = field.Label.split(' ').join('_'); });
298
+ });
299
+ }
300
+ }
301
+ else {
302
+ this.formCompleted = false;
303
+ this.previewForm = null;
304
+ }
305
+ };
306
+ /**
307
+ * Metodo che scatena l'evento di output per salvare la form creata alla fine del wizard
308
+ */
309
+ EqpDynamicModuleConfiguratorComponent.prototype.saveForm = function () {
310
+ this.saveFormEvent.emit(this.form);
311
+ };
312
+ /**
313
+ * Configura le colonne per le tabelle necessarie alla creazione della form:
314
+ * - per la visualizzazione dei campi inseriti
315
+ * - per le form di dettaglio create
316
+ * - per le azioni configurate sui record della form
317
+ */
318
+ EqpDynamicModuleConfiguratorComponent.prototype.configureColumns = function () {
319
+ var _this = this;
320
+ this.fieldsColumns = [
321
+ {
322
+ key: 'action', display: '', type: TypeColumn.MenuAction, buttonMenuIcon: 'more_vert', styles: { flex: '0 0 6%' },
323
+ actions: [
324
+ { name: 'Modifica', icon: 'edit', fn: function (element, index, col) { return _this.editField(element); } },
325
+ { name: 'Elimina', icon: 'delete', fn: function (element, index, col) { return _this.deleteElement(element, "Fields"); } },
326
+ {
327
+ name: 'Sposta su', icon: 'arrow_upward',
328
+ fn: function (element, index, col) { return _this.moveElement(element, true, "Fields"); },
329
+ disabled: function (element) { return _this.form.Fields.indexOf(element) === 0; }
330
+ },
331
+ {
332
+ name: 'Sposta giù', icon: 'arrow_downward',
333
+ fn: function (element, index, col) { return _this.moveElement(element, false, "Fields"); },
334
+ disabled: function (element) { return _this.form.Fields.indexOf(element) >= (_this.form.Fields.length - 1); }
335
+ },
336
+ ]
337
+ },
338
+ { key: 'FieldType', display: 'Tipologia', type: TypeColumn.Enum, enumModel: FieldTypeEnum },
339
+ { key: 'Label', display: 'Label' },
340
+ { key: 'Description', display: 'Descrizione' },
341
+ {
342
+ key: 'Required', display: 'Obbligatorio',
343
+ value: function (element) { return !!element.Required; },
344
+ type: TypeColumn.Boolean,
345
+ booleanValues: {
346
+ true: '<i class="fa fa-check success-color"></i>',
347
+ false: '<i class="fa fa-close error-color"></i>'
348
+ },
349
+ styles: { flex: '0 0 7%', cellAlignment: CellAlignmentEnum.CENTER }
350
+ },
351
+ ];
352
+ if (this.form.FormScalarType && this.form.FormScalarType != FormScalarTypeEnum.Semplice) {
353
+ this.fieldsColumns.splice(this.fieldsColumns.findIndex(function (c) { return c.key == 'Description'; }), 0, { key: 'FieldGroup', display: 'Sezione', type: TypeColumn.ExternalTemplate, externalTemplate: this.fieldSectionColumnTemplate });
354
+ }
355
+ this.actionsOnRecordColumns = [
356
+ {
357
+ key: 'action', display: '', type: TypeColumn.MenuAction, buttonMenuIcon: 'more_vert', styles: { flex: '0 0 6%' },
358
+ actions: [
359
+ { name: 'Modifica', icon: 'edit', fn: function (element, index, col) { return _this.openActionOnRecordDialog(element); } },
360
+ { name: 'Elimina', icon: 'delete', fn: function (element, index, col) { return _this.deleteElement(element, "ActionsOnRecord"); } },
361
+ {
362
+ name: 'Sposta su', icon: 'arrow_upward',
363
+ fn: function (element, index, col) { return _this.moveElement(element, true, "ActionsOnRecord"); },
364
+ disabled: function (element) { return _this.form.ActionsOnRecord.indexOf(element) === 0; }
365
+ },
366
+ {
367
+ name: 'Sposta giù', icon: 'arrow_downward',
368
+ fn: function (element, index, col) { return _this.moveElement(element, false, "ActionsOnRecord"); },
369
+ disabled: function (element) { return _this.form.ActionsOnRecord.indexOf(element) >= (_this.form.ActionsOnRecord.length - 1); }
370
+ },
371
+ ]
372
+ },
373
+ { key: 'Icon', display: 'Icona', styles: { flex: ' 0 0 15%' } },
374
+ { key: 'Name', display: 'Nome', styles: { flex: ' 0 0 20%' } },
375
+ { key: 'Action', display: 'Azione' },
376
+ ];
377
+ };
378
+ /**
379
+ * Crea il FormGroup per l'oggetto Form
380
+ */
381
+ EqpDynamicModuleConfiguratorComponent.prototype.createFormForm = function () {
382
+ this.formFormGroup = this.formBuilder.group({
383
+ Name: [this.form.Name, Validators.required],
384
+ FormScalarType: [this.form.FormScalarType, Validators.required],
385
+ });
386
+ this.onChangeFormScalarType();
387
+ };
388
+ /**
389
+ * Crea il FormGroup epr l'aggiunta o la modifica di una action sui record della Form.
390
+ */
391
+ EqpDynamicModuleConfiguratorComponent.prototype.createActionOnRecordForm = function () {
392
+ this.actionOnRecordFormGroup = this.formBuilder.group({
393
+ Name: [this.selectedAction.Name, Validators.required],
394
+ Icon: [this.selectedAction.Icon, Validators.required],
395
+ Action: [this.selectedAction.Action, Validators.required],
396
+ });
397
+ };
398
+ /**
399
+ * Chiude il dialog per aggiungere/modificare un Field senza salvare
400
+ */
401
+ EqpDynamicModuleConfiguratorComponent.prototype.closeFieldDialog = function () {
402
+ this.dialogFieldRef.close();
403
+ };
404
+ /**
405
+ * Metodo per gestire l'apertura del dialog per la modifica di un Field.
406
+ * Se il field è di tipo "Form di dettaglio" apre il dialog per la modifica di una
407
+ * InnerForm altrimenti apre quello per la modifica di un Field.
408
+ * @param field Campo da modificare
409
+ */
410
+ EqpDynamicModuleConfiguratorComponent.prototype.editField = function (field) {
411
+ if (field.FieldType != FieldTypeEnum['Form di dettaglio']) {
412
+ this.openFieldDialog(field);
413
+ }
414
+ else {
415
+ this.openInnerFormDialog(this.form.InnerForms.find(function (f) { return f.Name == field.Label; }));
416
+ }
417
+ };
418
+ /**
419
+ * Metodo per rimuovere un Field all'interno di una Form.
420
+ * Richiede conferma all'utente prima di rimuoverlo.
421
+ * @param field BaseField da rimuovere
422
+ */
423
+ EqpDynamicModuleConfiguratorComponent.prototype.deleteElement = function (element, propertyName) {
424
+ var _this = this;
425
+ EqpDynamicModuleDialogService.Confirm('Eliminare l\'elemento selezionato?', function () {
426
+ _this.form[propertyName].splice(_this.form[propertyName].indexOf(element), 1);
427
+ if (propertyName === "Fields") {
428
+ _this.setFieldOrdinalPosition();
429
+ _this.reloadFieldsTable();
430
+ }
431
+ else if (propertyName === "ActionsOnRecord") {
432
+ _this.setActionOrdinalPosition();
433
+ _this.reloadActionsOnRecordTable();
434
+ }
435
+ }, false, 'Richiesta conferma');
436
+ };
437
+ /**
438
+ * Metodo per spostare un campo all'interno della form.
439
+ * @param field Oggetto di tipo BaseField da spostare.
440
+ * @param moveUp Se TRUE allora sposta verso l'alto il campo (abbassa l'indice) altrimenti il contrario.
441
+ */
442
+ EqpDynamicModuleConfiguratorComponent.prototype.moveElement = function (element, moveUp, propertyName) {
443
+ var startingIndex = this.form[propertyName].indexOf(element);
444
+ var endingIndex = startingIndex + (moveUp ? -1 : 1);
445
+ this.form[propertyName].splice(startingIndex, 1);
446
+ this.form[propertyName].splice(endingIndex, 0, element);
447
+ if (propertyName === "Fields") {
448
+ this.setFieldOrdinalPosition();
449
+ this.reloadFieldsTable();
450
+ }
451
+ else if (propertyName === "ActionsOnRecord") {
452
+ this.setActionOrdinalPosition();
453
+ this.reloadActionsOnRecordTable();
454
+ }
455
+ };
456
+ /**
457
+ * Imposta l'ordinamento delle sezioni che compongono la form.
458
+ */
459
+ EqpDynamicModuleConfiguratorComponent.prototype.setFormFieldGroupOrdinalPosition = function () {
460
+ this.form.FormFieldsGroups.forEach(function (g, i) { return g.OrdinalPosition = i; });
461
+ };
462
+ /**
463
+ * Imposta l'ordinamento dei campi all'interno della form in base all'ordine che l'utente
464
+ * ha definito nella tabella in cui sono mostrati
465
+ */
466
+ EqpDynamicModuleConfiguratorComponent.prototype.setFieldOrdinalPosition = function () {
467
+ var _this = this;
468
+ if (this.form.Fields) {
469
+ this.form.Fields.forEach(function (field) {
470
+ field.OrdinalPosition = _this.form.Fields.indexOf(field);
471
+ });
472
+ }
473
+ };
474
+ /**
475
+ * Metodo per ricaricare i dati della tabella dei campi aggiunti in una form
476
+ */
477
+ EqpDynamicModuleConfiguratorComponent.prototype.reloadFieldsTable = function () {
478
+ if (this.fieldsTable) {
479
+ this.fieldsTable.reloadDatatable();
480
+ }
481
+ };
482
+ /**
483
+ * Imposta l'ordinamento dei campi all'interno della form in base all'ordine che l'utente
484
+ * ha definito nella tabella in cui sono mostrati
485
+ */
486
+ EqpDynamicModuleConfiguratorComponent.prototype.setActionOrdinalPosition = function () {
487
+ var _this = this;
488
+ if (this.form.ActionsOnRecord) {
489
+ this.form.ActionsOnRecord.forEach(function (action) {
490
+ action.OrdinalPosition = _this.form.ActionsOnRecord.indexOf(action);
491
+ });
492
+ }
493
+ };
494
+ /**
495
+ * Metodo per ricaricare i dati della tabella delle azioni aggiuntive sui record della Form.
496
+ */
497
+ EqpDynamicModuleConfiguratorComponent.prototype.reloadActionsOnRecordTable = function () {
498
+ if (this.actionsOnRecordTable) {
499
+ this.actionsOnRecordTable.reloadDatatable();
500
+ }
501
+ };
502
+ EqpDynamicModuleConfiguratorComponent.ctorParameters = function () { return [
503
+ { type: FormBuilder },
504
+ { type: MatDialog }
505
+ ]; };
506
+ __decorate([
507
+ Input()
508
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "context", void 0);
509
+ __decorate([
510
+ Input()
511
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "form", void 0);
512
+ __decorate([
513
+ Input()
514
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "innerFormManagment", void 0);
515
+ __decorate([
516
+ ViewChild('fieldsTable', { static: false })
517
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "fieldsTable", void 0);
518
+ __decorate([
519
+ ViewChild('dialogField', { static: true })
520
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "dialogField", void 0);
521
+ __decorate([
522
+ ViewChild('fieldSectionColumnTemplate', { static: true })
523
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "fieldSectionColumnTemplate", void 0);
524
+ __decorate([
525
+ ViewChild('dialogInnerForm', { static: true })
526
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "dialogInnerForm", void 0);
527
+ __decorate([
528
+ ViewChild('actionsOnRecordTable', { static: false })
529
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "actionsOnRecordTable", void 0);
530
+ __decorate([
531
+ ViewChild('dialogActionOnRecord', { static: true })
532
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "dialogActionOnRecord", void 0);
533
+ __decorate([
534
+ Output()
535
+ ], EqpDynamicModuleConfiguratorComponent.prototype, "saveFormEvent", void 0);
536
+ EqpDynamicModuleConfiguratorComponent = __decorate([
537
+ Component({
538
+ selector: 'eqp-dynamic-module-configurator',
539
+ template: "<mat-horizontal-stepper linear #stepper>\r\n <!-- DATI GENERALI DELLA FORM -->\r\n <mat-step [stepControl]=\"formFormGroup\">\r\n <form [formGroup]=\"formFormGroup\" (keydown.enter)=\"false\">\r\n <ng-template matStepLabel>\r\n <div class=\"stepper-header-overlay\" (click)=\"setFormStatus(false)\"></div>\r\n Dati generali della form\r\n </ng-template>\r\n\r\n <div class=\"row\">\r\n <div class=\"col-md-4\">\r\n <mat-form-field>\r\n <mat-label>Nome</mat-label>\r\n <input matInput formControlName=\"Name\" [(ngModel)]=\"form.Name\" required>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <eqp-select [enumData]=\"FormScalarTypeEnum\" [(ngModelInput)]=\"form.FormScalarType\"\r\n [isRequired]=\"true\" [showCancelButton]=\"false\" placeholder=\"Tipo di visualizzazione\"\r\n [formGroupInput]=\"formFormGroup\" [formControlNameInput]=\"'FormScalarType'\"\r\n (ngModelInputChange)=\"onChangeFormScalarType()\">\r\n </eqp-select>\r\n </div>\r\n </div>\r\n <div class=\"row\" *ngIf=\"form.FormScalarType && form.FormScalarType != FormScalarTypeEnum.Semplice\">\r\n <div class=\"col-md-4 d-flex align-items-center\">\r\n <mat-form-field>\r\n <mat-label> Nome sezione (invio per confermare) </mat-label>\r\n <input matInput [(ngModel)]=\"formFieldGroupName\" [ngModelOptions]=\"{standalone: true}\"\r\n (keyup)=\"onFormFieldGroupNameKeyUp($event)\">\r\n </mat-form-field>\r\n </div>\r\n <div class=\"col-md-4 d-flex align-items-center\">\r\n <span class=\"mr-3\">Sezioni inserite:</span>\r\n <ul class=\"section-list\">\r\n <li *ngFor=\"let groupName of form.FormFieldsGroups, let i=index\">\r\n <mat-icon class=\"mr-1\" (click)=\"onDeleteFormFieldGroupName(groupName.Name)\">close\r\n </mat-icon>\r\n <span> {{i+1}}) {{groupName.Name}}</span>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mt-2 d-flex justify-content-end\">\r\n <button mat-raised-button color=\"primary\" matStepperNext\r\n [disabled]=\"formFormGroup.invalid\">Successivo</button>\r\n </div>\r\n </form>\r\n </mat-step>\r\n\r\n <!-- AGGIUNTA DEI CAMPI DELLA FORM -->\r\n <mat-step [completed]=\"isFieldStepCompleted()\">\r\n <ng-template matStepLabel>\r\n <div class=\"stepper-header-overlay\" (click)=\"setFormStatus(false)\"></div>\r\n Campi da inserire\r\n </ng-template>\r\n\r\n <div class=\"row justify-content-end\">\r\n <button class=\"btn btn-primary\" mat-raised-button color=\"primary\" type=\"button\" (click)=\"openFieldDialog()\">\r\n <mat-icon>add</mat-icon>\r\n <span style=\"margin-left: 10px;\">Aggiungi campo</span>\r\n </button>\r\n\r\n <button class=\"btn btn-primary ml-2\" mat-raised-button color=\"primary\" type=\"button\"\r\n (click)=\"openInnerFormDialog()\" *ngIf=\"!innerFormManagment\">\r\n <mat-icon>add</mat-icon>\r\n <span style=\"margin-left: 10px;\">Aggiungi form di dettaglio</span>\r\n </button>\r\n </div>\r\n\r\n <eqp-table #fieldsTable [createMatCard]=\"false\" [columns]=\"fieldsColumns\" [data]=\"form.Fields\"\r\n [emptyTableMessage]=\"'Nessun campo inserito'\" [searchText]=\"'Cerca'\">\r\n </eqp-table>\r\n\r\n <div class=\"mt-2 d-flex justify-content-end\">\r\n <button class=\"mr-2\" mat-raised-button matStepperPrevious>Precedente</button>\r\n <button mat-raised-button color=\"primary\" matStepperNext [disabled]=\"!isFieldStepCompleted()\"\r\n (click)=\"setFormStatus(false)\">Successivo</button>\r\n </div>\r\n </mat-step>\r\n\r\n <!-- AGGIUNTA DELLE OPERAZIONI SUI RECORD -->\r\n <mat-step>\r\n <ng-template matStepLabel>\r\n <div class=\"stepper-header-overlay\" (click)=\"setFormStatus(false)\"></div>\r\n Azioni aggiuntive sui record\r\n </ng-template>\r\n\r\n <div class=\"row justify-content-end\">\r\n <button class=\"btn btn-primary\" mat-raised-button color=\"primary\" type=\"button\"\r\n (click)=\"openActionOnRecordDialog()\">\r\n <mat-icon>add</mat-icon>\r\n <span style=\"margin-left: 10px;\">Aggiungi azione</span>\r\n </button>\r\n </div>\r\n <eqp-table #actionsOnRecordTable [createMatCard]=\"false\" [columns]=\"actionsOnRecordColumns\"\r\n [data]=\"form.ActionsOnRecord\" [emptyTableMessage]=\"'Nessuna action inserita'\" [searchText]=\"'Cerca'\">\r\n </eqp-table>\r\n\r\n <div class=\"mt-2 d-flex justify-content-end\">\r\n <button class=\"mr-2\" mat-raised-button matStepperPrevious>Precedente</button>\r\n <button mat-raised-button color=\"primary\" matStepperNext (click)=\"setFormStatus(true)\">\r\n Successivo\r\n </button>\r\n </div>\r\n </mat-step>\r\n\r\n <!-- VISUALIZZAZIONE FORM CREATA -->\r\n <mat-step>\r\n <ng-template matStepLabel>\r\n <div class=\"stepper-header-overlay\"\r\n (click)=\"setFormStatus(formFormGroup.valid && form.Fields && form.Fields.length > 0)\"></div>\r\n Riepilogo\r\n </ng-template>\r\n\r\n <eqp-dynamic-module [form]=\"previewForm\" *ngIf=\"previewForm && formCompleted\" [showButtons]=\"false\"\r\n [viewMode]=\"FormTypeEnum.SCALAR\"></eqp-dynamic-module>\r\n\r\n <div class=\"mt-2 d-flex justify-content-end\">\r\n <button class=\"mr-2\" mat-raised-button matStepperPrevious (click)=\"setFormStatus(false)\">Precedente</button>\r\n <button mat-raised-button color=\"primary\" (click)=\"saveForm()\">Salva form</button>\r\n </div>\r\n </mat-step>\r\n</mat-horizontal-stepper>\r\n\r\n<div class=\"row\" *ngIf=\"innerFormManagment\">\r\n <div class=\"col-md-12 text-right\">\r\n <button mat-raised-button (click)=\"saveFormEvent.emit(null)\">Esci</button>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG AGGIUNTA/MODIFICA CAMPO -->\r\n<ng-template #dialogField>\r\n <eqp-dynamic-module-add-form-field [field]=\"selectedField\" [indexField]=\"indexSelectedField\"\r\n (saveFieldEvent)=\"onSaveField($event)\" [availableFields]=\"form.Fields\"\r\n [formFieldsGroups]=\"form.FormScalarType != FormScalarTypeEnum.Semplice ? form.FormFieldsGroups : null\">\r\n </eqp-dynamic-module-add-form-field>\r\n</ng-template>\r\n\r\n<!-- TEMPLATE PER VISUALIZZARE LA COLONNA DELLA SEZIONE NELLA TABELLA DEI FIELDS -->\r\n<ng-template #fieldSectionColumnTemplate let-row=\"row\">\r\n <eqp-select [arrayData]=\"form.FormFieldsGroups\" [(ngModelInput)]=\"row.FieldGroup\" [arrayKeyProperty]=\"'Name'\"\r\n [arrayValueProperty]=\"'Name'\" placeholder=\"Sezione\" [isRequired]=\"true\" [includeFullObject]=\"false\">\r\n </eqp-select>\r\n</ng-template>\r\n\r\n<!-- DIALOG PER AGGIUNGERE/MODIFICARE UNA ACTION SUI RECORD DELLA FORM -->\r\n<ng-template #dialogActionOnRecord>\r\n <div class=\"container-fluid\" style=\"max-height: 70vh !important; overflow-x: hidden; overflow-y: auto;\">\r\n <form [formGroup]=\"actionOnRecordFormGroup\">\r\n <div class=\"row\">\r\n <div class=\"header-title-standard\">{{indexSelectedAction != null && indexSelectedAction >= 0 ?\r\n \"Modifica\"\r\n : \"Aggiungi\"}} azione sul record</div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-4 mt-2\">\r\n <mat-form-field>\r\n <mat-label> Nome </mat-label>\r\n <input formControlName=\"Name\" required matInput [(ngModel)]=\"selectedAction.Name\">\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"col-sm-12 col-md-4 mt-2\">\r\n <mat-form-field>\r\n <mat-label> Icona </mat-label>\r\n <input formControlName=\"Icon\" required matInput [(ngModel)]=\"selectedAction.Icon\">\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-12 mt-2\">\r\n <mat-form-field>\r\n <textarea matInput [placeholder]=\"'Azione (Javascript)'\" [rows]=\"3\" formControlName=\"Action\"\r\n required [(ngModel)]=\"selectedAction.Action\" [matAutocomplete]=\"actionAutocomplete\"\r\n (keyup)=\"setActionAutocompleteOptions($event)\"\r\n (focus)=\"setActionAutocompleteOptions(null)\"></textarea>\r\n <mat-autocomplete #actionAutocomplete=\"matAutocomplete\">\r\n <mat-option *ngFor=\"let option of actionAutocompleteOptions\" [value]=\"option.value\">\r\n {{option.label}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"row mt-2 mb-1\">\r\n <div class=\"col-sm-12 text-right\">\r\n <button class=\"mr-2\" mat-raised-button color=\"primary\" (click)=\"saveActionOnRecord()\"\r\n [disabled]=\"actionOnRecordFormGroup.invalid\" type=\"button\">\r\n Salva\r\n </button>\r\n <button class=\"btn mat-raised-button\" (click)=\"closeDialogActionOnRecord()\" type=\"button\">\r\n Esci\r\n </button>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dialogInnerForm>\r\n <eqp-dynamic-module-configurator [form]=\"selectedInnerForm\" [innerFormManagment]=\"true\"\r\n (saveFormEvent)=\"onSaveOrExitInnerForm($event)\"></eqp-dynamic-module-configurator>\r\n</ng-template>",
540
+ styles: ["::ng-deep mat-form-field{width:100%}.stepper-header-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.section-list{list-style:none;padding:0}.section-list mat-icon{vertical-align:middle;font-size:15px;height:15px;width:15px;color:var(--danger);margin-right:10px;cursor:pointer}.danger-color{color:var(--danger)}"]
541
+ })
542
+ ], EqpDynamicModuleConfiguratorComponent);
543
+ return EqpDynamicModuleConfiguratorComponent;
544
+ }());
545
+ export { EqpDynamicModuleConfiguratorComponent };
546
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXFwLWR5bmFtaWMtbW9kdWxlLWNvbmZpZ3VyYXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AZXFwcm9qZWN0L2VxcC1keW5hbWljLW1vZHVsZS8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL2V4cG9ydGVkL2VxcC1keW5hbWljLW1vZHVsZS1jb25maWd1cmF0b3IvZXFwLWR5bmFtaWMtbW9kdWxlLWNvbmZpZ3VyYXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQWUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNqRixPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxpQkFBaUIsRUFBbUMsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEcsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQWtCLGtCQUFrQixFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BILE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUNuRixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUNwRyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQU9oRjtJQWdERSwrQ0FDVSxXQUF3QixFQUN4QixNQUFpQjtRQURqQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixXQUFNLEdB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RUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7OEVBQStCO0lBQ2Y7UUFBMUQsU0FBUyxDQUFDLDRCQUE0QixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDOzZGQUE4QztJQU94RDtRQUEvQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7a0ZBQW1DO0lBSzVCO1FBQXJELFNBQVMsQ0FBQyxzQkFBc0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQzt1RkFBeUM7SUFJekM7UUFBcEQsU0FBUyxDQUFDLHNCQUFzQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDO3VGQUF3QztJQUlsRjtRQUFULE1BQU0sRUFBRTtnRkFBOEQ7SUE5QzVELHFDQUFxQztRQUxqRCxTQUFTLENBQUM7WUFDVCxRQUFRLEVBQUUsaUNBQWlDO1lBQzNDLGtuVkFBK0Q7O1NBRWhFLENBQUM7T0FDVyxxQ0FBcUMsQ0FrakJqRDtJQUFELDRDQUFDO0NBQUEsQUFsakJELElBa2pCQztTQWxqQlkscUNBQXFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgTWF0RGlhbG9nLCBNYXREaWFsb2dSZWYgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xyXG5pbXBvcnQgeyBDZWxsQWxpZ25tZW50RW51bSwgQ29uZmlnQ29sdW1uLCBFcXBUYWJsZUNvbXBvbmVudCwgVHlwZUNvbHVtbiB9IGZyb20gJ0BlcXByb2plY3QvZXFwLXRhYmxlJztcclxuaW1wb3J0IHsgQmFzZUZpZWxkLCBGaWVsZFR5cGVFbnVtIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2Jhc2VGaWVsZC5tb2RlbCc7XHJcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvY29udGV4dC5tb2RlbCc7XHJcbmltcG9ydCB7IEFjdGlvbk9uUmVjb3JkLCBGb3JtLCBGb3JtRmllbGRHcm91cCwgRm9ybVNjYWxhclR5cGVFbnVtLCBGb3JtVHlwZUVudW0gfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvZm9ybS5tb2RlbCc7XHJcbmltcG9ydCB7IEFycmF5VmFsaWRhdG9ycyB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2N1c3RvbS1mb3JtLXZhbGlkYXRvcnMuc2VydmljZSc7XHJcbmltcG9ydCB7IEVxcER5bmFtaWNNb2R1bGVEaWFsb2dTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZXFwLWR5bmFtaWMtbW9kdWxlLWRpYWxvZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXRpbGl0eUhlbHBlclNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy91dGlsaXR5SGVscGVyLnNlcnZpY2VzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZXFwLWR5bmFtaWMtbW9kdWxlLWNvbmZpZ3VyYXRvcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2VxcC1keW5hbWljLW1vZHVsZS1jb25maWd1cmF0b3IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2VxcC1keW5hbWljLW1vZHVsZS1jb25maWd1cmF0b3IuY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRXFwRHluYW1pY01vZHVsZUNvbmZpZ3VyYXRvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBJbnB1dCgpIGNvbnRleHQ6IENvbnRleHQgPSBuZXcgQ29udGV4dCgpO1xyXG4gIEBJbnB1dCgpIGZvcm06IEZvcm0gPSBuZXcgRm9ybSgpO1xyXG4gIEBJbnB1dCgpIGlubmVyRm9ybU1hbmFnbWVudDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBmb3JtRm9ybUdyb3VwOiBGb3JtR3JvdXA7XHJcbiAgZm9ybUNvbXBsZXRlZCA9IGZhbHNlO1xyXG4gIHByZXZpZXdGb3JtOiBGb3JtO1xyXG4gIGZvcm1GaWVsZEdyb3VwTmFtZTogc3RyaW5nO1xyXG5cclxuICBhY3Rpb25BdXRvY29tcGxldGVPcHRpb25zOiBBcnJheTx7IGxhYmVsOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfT47XHJcblxyXG4gIC8vI3JlZ2lvbiBFbnVtZXJhdG9yaSB1c2F0aSBuZWxsJ2h0bWxcclxuICBGb3JtVHlwZUVudW0gPSBGb3JtVHlwZUVudW07XHJcbiAgRm9ybVNjYWxhclR5cGVFbnVtID0gRm9ybVNjYWxhclR5cGVFbnVtO1xyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICAvLyNyZWdpb24gUHJvcHJpZXTDoCBwZXIgY3JlYXppb25lL21vZGlmaWNhIGNhbXBvXHJcbiAgZmllbGRzQ29sdW1uczogQXJyYXk8Q29uZmlnQ29sdW1uPjtcclxuICBAVmlld0NoaWxkKCdmaWVsZHNUYWJsZScsIHsgc3RhdGljOiBmYWxzZSB9KSBmaWVsZHNUYWJsZTogRXFwVGFibGVDb21wb25lbnQ7XHJcbiAgc2VsZWN0ZWRGaWVsZDogQmFzZUZpZWxkIHwgYW55O1xyXG4gIGluZGV4U2VsZWN0ZWRGaWVsZDogbnVtYmVyO1xyXG4gIGFjdGlvbk9uUmVjb3JkRm9ybUdyb3VwOiBGb3JtR3JvdXA7XHJcbiAgZGlhbG9nRmllbGRSZWY6IE1hdERpYWxvZ1JlZjxUZW1wbGF0ZVJlZjxhbnk+PjtcclxuICBAVmlld0NoaWxkKCdkaWFsb2dGaWVsZCcsIHsgc3RhdGljOiB0cnVlIH0pIGRpYWxvZ0ZpZWxkOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBWaWV3Q2hpbGQoJ2ZpZWxkU2VjdGlvbkNvbHVtblRlbXBsYXRlJywgeyBzdGF0aWM6IHRydWUgfSkgZmllbGRTZWN0aW9uQ29sdW1uVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8vI3JlZ2lvbiBQcm9wcmlldMOgIHBlciBjcmVhcmUvbW9kaWZpY2FyZSB1bmEgRm9ybSBkaSBkZXR0YWdsaW9cclxuICBzZWxlY3RlZElubmVyRm9ybTogRm9ybTtcclxuICBpbmRleFNlbGVjdGVkSW5uZXJGb3JtOiBudW1iZXI7XHJcbiAgZGlhbG9nSW5uZXJGb3JtUmVmOiBNYXREaWFsb2dSZWY8VGVtcGxhdGVSZWY8YW55Pj47XHJcbiAgQFZpZXdDaGlsZCgnZGlhbG9nSW5uZXJGb3JtJywgeyBzdGF0aWM6IHRydWUgfSkgZGlhbG9nSW5uZXJGb3JtOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICAvLyNyZWdpb24gUHJvcHJpZXTDoCBwZXIgY3JlYXJlL21vZGlmaWNhcmUgdW5hIGFjdGlvbiBzdWkgcmVjb3JkIGRpIHVuYSBGb3JtXHJcbiAgYWN0aW9uc09uUmVjb3JkQ29sdW1uczogQXJyYXk8Q29uZmlnQ29sdW1uPjtcclxuICBAVmlld0NoaWxkKCdhY3Rpb25zT25SZWNvcmRUYWJsZScsIHsgc3RhdGljOiBmYWxzZSB9KSBhY3Rpb25zT25SZWNvcmRUYWJsZTogRXFwVGFibGVDb21wb25lbnQ7XHJcbiAgc2VsZWN0ZWRBY3Rpb246IEFjdGlvbk9uUmVjb3JkO1xyXG4gIGluZGV4U2VsZWN0ZWRBY3Rpb246IG51bWJlcjtcclxuICBkaWFsb2dBY3Rpb25PblJlY29yZFJlZjogTWF0RGlhbG9nUmVmPFRlbXBsYXRlUmVmPGFueT4+O1xyXG4gIEBWaWV3Q2hpbGQoJ2RpYWxvZ0FjdGlvbk9uUmVjb3JkJywgeyBzdGF0aWM6IHRydWUgfSkgZGlhbG9nQWN0aW9uT25SZWNvcmQ6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG5cclxuICBAT3V0cHV0KCkgc2F2ZUZvcm1FdmVudDogRXZlbnRFbWl0dGVyPEZvcm0+ID0gbmV3IEV2ZW50RW1pdHRlcjxGb3JtPigpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxyXG4gICAgcHJpdmF0ZSBkaWFsb2c6IE1hdERpYWxvZ1xyXG4gICkgeyB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY29udGV4dCkge1xyXG4gICAgICBVdGlsaXR5SGVscGVyU2VydmljZS5TZXRDb250ZXh0KHRoaXMuY29udGV4dCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmNvbmZpZ3VyZUNvbHVtbnMoKTtcclxuICAgIHRoaXMuY3JlYXRlRm9ybUZvcm0oKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBpbnZvY2F0byBhbCBjYW1iaW8gZGVsIHRpcG8gZGkgdmlzdWFsaXp6YXppb25lIGRlbGxhIGZvcm0uXHJcbiAgICogU2UgbCd1dGVudGUgc2NlZ2xpZSB1bmEgdmlzdWFsaXp6YXppb25lIHJhZ2dydXBwYXRhIGlsIG1ldG9kbyBhZ2dpdW5nZSBhbCBGb3JtR3JvdXAgdW4gbnVvdm9cclxuICAgKiBjb250cm9sbG8gcGVyIGwnYXJyYXkgZGVpIG5vbWkgZGVsbGUgc2V6aW9uaSBkYSBjcmVhcmUuXHJcbiAgICovXHJcbiAgb25DaGFuZ2VGb3JtU2NhbGFyVHlwZSgpIHtcclxuICAgIGlmICh0aGlzLmZvcm0uRm9ybVNjYWxhclR5cGUgIT0gRm9ybVNjYWxhclR5cGVFbnVtLlNlbXBsaWNlKSB7XHJcbiAgICAgIGlmICghdGhpcy5mb3JtRm9ybUdyb3VwLmNvbnRhaW5zKFwiRm9ybUZpZWxkc0dyb3Vwc1wiKSkge1xyXG4gICAgICAgIHRoaXMuZm9ybUZvcm1Hcm91cC5yZW1vdmVDb250cm9sKFwiRm9ybUZpZWxkc0dyb3Vwc1wiKTtcclxuICAgICAgICB0aGlzLmZvcm1Gb3JtR3JvdXAuYWRkQ29udHJvbChcIkZvcm1GaWVsZHNHcm91cHNcIiwgbmV3IEZvcm1Db250cm9sKHRoaXMuZm9ybS5Gb3JtRmllbGRzR3JvdXBzLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgQXJyYXlWYWxpZGF0b3JzLm1pbkxlbmdodCgxKV0pKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5mb3JtLkZvcm1GaWVsZHNHcm91cHMgPSBudWxsO1xyXG4gICAgICBpZiAodGhpcy5mb3JtRm9ybUdyb3VwLmNvbnRhaW5zKFwiRm9ybUZpZWxkc0dyb3Vwc1wiKSlcclxuICAgICAgICB0aGlzLmZvcm1Gb3JtR3JvdXAucmVtb3ZlQ29udHJvbChcIkZvcm1GaWVsZHNHcm91cHNcIik7XHJcbiAgICB9XHJcbiAgICB0aGlzLmZvcm1Gb3JtR3JvdXAudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgdGhpcy5jb25maWd1cmVDb2x1bW5zKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFdmVudG8gaW52b2NhdG8gYWwga2V5dXAgbmVsbCdpbnB1dCBwZXIgaW5zZXJpcmUgaSBub21pIGRlbGxlIHNlemlvbmkgcGVyIGxhIHZpc3VhbGl6emF6aW9uZSBcclxuICAgKiByYWdncnVwcGF0YSBkZWxsYSBmb3JtLiBRdWFudG8gbCd1dGVudGUgcHJlbWUgaWwgdGFzdG8gaW52aW8gdmllbmUgYWdnaXVudG8gaWwgbnVvdm8gbm9tZSBhbGxlXHJcbiAgICogc2V6aW9uaSBkaXNwb2JpbGkgc2Ugbm9uIG5lIGVzaXN0ZSB1bmEgY29uIGxvIHN0ZXNzbyBub21lLlxyXG4gICAqIEBwYXJhbSBldmVudCBFdmVudG8gY2hlIHJhcHByZXNlbnRhIGlsIGtleXVwIHN1bGxhIHRhc3RpZXJhLlxyXG4gICAqL1xyXG4gIG9uRm9ybUZpZWxkR3JvdXBOYW1lS2V5VXAoZXZlbnQpIHtcclxuICAgIGlmIChldmVudC5jb2RlID09PSAnRW50ZXInIHx8IGV2ZW50LmNvZGUgPT09ICdOdW1wYWRFbnRlcicpIHtcclxuICAgICAgaWYgKCF0aGlzLmZvcm0uRm9ybUZpZWxkc0dyb3Vwcykge1xyXG4gICAgICAgIHRoaXMuZm9ybS5Gb3JtRmllbGRzR3JvdXBzID0gbmV3IEFycmF5PEZvcm1GaWVsZEdyb3VwPigpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICghdGhpcy5mb3JtLkZvcm1GaWVsZHNHcm91cHMuZmluZChuID0+IG4uTmFtZSA9PSB0aGlzLmZvcm1GaWVsZEdyb3VwTmFtZSkpIHtcclxuICAgICAgICB0aGlzLmZvcm0uRm9ybUZpZWxkc0dyb3Vwcy5wdXNoKHsgTmFtZTogdGhpcy5mb3JtRmllbGRHcm91cE5hbWUgfSk7XHJcbiAgICAgIH1cclxuICAgICAgLy8gSW1wb3N0byBpbCBudW92byB2YWxvcmUgZGVsIEZvcm1Db250cm9sIHBlciBhZ2dpb3JuYXJlIGxvIHN0YXRvIGRlbGxhIGZvcm0uXHJcbiAgICAgIHRoaXMuZm9ybUZvcm1Hcm91cC5jb250cm9sc1tcIkZvcm1GaWVsZHNHcm91cHNcIl0uc2V0VmFsdWUodGhpcy5mb3JtLkZvcm1GaWVsZHNHcm91cHMpO1xyXG4gICAgICB0aGlzLmZvcm1GaWVsZEdyb3VwTmFtZSA9IG51bGw7XHJcbiAgICAgIHRoaXMuc2V0Rm9ybUZpZWxkR3JvdXBPcmRpbmFsUG9zaXRpb24oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBwZXIgcmltdW92ZXJlIGxhIHNlemlvbmUgc2VsZXppb25hdGEgZGEgcXVlbGxlIGRpc3BvbmliaWxpIHBlciBsYSBmb3JtLlxyXG4gICAqIEBwYXJhbSBncm91cE5hbWUgTm9tZSBkZWxsYSBzZXppb25lIGRhIGVsaW1pbmFyZS5cclxuICAgKi9cclxuICBvbkRlbGV0ZUZvcm1GaWVsZEdyb3VwTmFtZShncm91cE5hbWU6IHN0cmluZykge1xyXG4gICAgdGhpcy5mb3JtLkZvcm1GaWVsZHNHcm91cHMuc3BsaWNlKHRoaXMuZm9ybS5Gb3JtRmllbGRzR3JvdXBzLmZpbmRJbmRleChnID0+IGcuTmFtZSA9PT0gZ3JvdXBOYW1lKSwgMSk7XHJcbiAgICAvLyBJbXBvc3RvIGlsIG51b3ZvIHZhbG9yZSBkZWwgRm9ybUNvbnRyb2wgcGVyIGFnZ2lvcm5hcmUgbG8gc3RhdG8gZGVsbGEgZm9ybS5cclxuICAgIHRoaXMuZm9ybUZvcm1Hcm91cC5jb250cm9sc1tcIkZvcm1GaWVsZHNHcm91cHNcIl0uc2V0VmFsdWUodGhpcy5mb3JtLkZvcm1GaWVsZHNHcm91cHMpO1xyXG4gICAgLy8gU2UgZXNpc3Rvbm8gRmllbGQgbGVnYXRpIGFsbGEgc2V6aW9uZSBjaGUgc2kgdnVvbGUgZWxpbWluYXJlIGFsbG9yYSByb21wbyBpbCBsZWdhbWUuXHJcbiAgICBpZiAodGhpcy5mb3JtLkZpZWxkcy5maW5kKGYgPT4gZi5GaWVsZEdyb3VwID09IGdyb3VwTmFtZSkpIHtcclxuICAgICAgdGhpcy5mb3JtLkZpZWxkcy5maWx0ZXIoZiA9PiBmLkZpZWxkR3JvdXAgPT0gZ3JvdXBOYW1lKS5mb3JFYWNoKGYgPT4gZi5GaWVsZEdyb3VwID0gbnVsbCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnNldEZvcm1GaWVsZEdyb3VwT3JkaW5hbFBvc2l0aW9uKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gY2hpYW1hdG8gcXVhbmRvIHNpIHZ1b2xlIGFnZ2l1bmdlcmUgdW4gbnVvdm8gY2FtcG8gbyBzaSB2dW9sZSBtb2RpZmljYXJlIHVubyBlc2lzdGVudGUuXHJcbiAgICogTWVtb3JpenphIGwnZXZlbnR1YWxlIEZpZWxkIHNjZWx0byBvbmUgY3JlYSB1bm8gbnVvdm8gcHJpbWEgZGkgYXByaXJlIGlsIGRpYWxvZyBwZXIgbW9kaWZpY2FybG8vYWdnaXVuZ2VybG8uXHJcbiAgICogQHBhcmFtIGZpZWxkIE9nZ2V0dG8gQmFzZUZpZWxkIGRhIG1vZGlmaWNhcmUuIFNlIG51bGwgbmUgdmllbmUgY3JlYXRhIHVuYSBudW92YSBpc3RhbnphIHBlciBsJ2FnZ2l1bnRhLlxyXG4gICAqL1xyXG4gIG9wZW5GaWVsZERpYWxvZyhmaWVsZDogQmFzZUZpZWxkID0gbnVsbCkge1xyXG4gICAgaWYgKGZpZWxkKSB7XHJcbiAgICAgIHRoaXMuaW5kZXhTZWxlY3RlZEZpZWxkID0gdGhpcy5mb3JtLkZpZWxkcy5pbmRleE9mKGZpZWxkKTtcclxuICAgICAgdGhpcy5zZWxlY3RlZEZpZWxkID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShmaWVsZCkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZEZpZWxkID0gbmV3IEJhc2VGaWVsZCgpO1xyXG4gICAgICB0aGlzLmluZGV4U2VsZWN0ZWRGaWVsZCA9IG51bGw7XHJcbiAgICB9XHJcbiAgICB0aGlzLmRpYWxvZ0ZpZWxkUmVmID0gdGhpcy5kaWFsb2cub3Blbih0aGlzLmRpYWxvZ0ZpZWxkLCB7XHJcbiAgICAgIGRpc2FibGVDbG9zZTogdHJ1ZSxcclxuICAgICAgaGFzQmFja2Ryb3A6IHRydWUsXHJcbiAgICAgIHdpZHRoOiAnNzUlJ1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gY2hlIHNhbHZhIGlsIGNhbXBvIGFwcGVuYSBjcmVhdG8gbyBtb2RpZmljYXRvLlxyXG4gICAqIFByaW1hIGRlbCBzYWx2YXRhZ2dpbyBjb250cm9sbGEgc2UgZXNpc3RlIHVuIGFsdHJvIGNhbXBvIGNvbiBsYSBzdGVzc2EgbGFiZWwsIGluIHF1ZXN0b1xyXG4gICAqIGNhc2UgZ2VuZXJlIHVuIGVycm9yZSAoaSBjYW1waSBkZXZvbm8gYXZlcmUgbm9taSwgZSBxdWluZGkgbGFiZWwsIHVuaXZvY2hlIC0gaSBub21pIHZlbmdvbm9cclxuICAgKiByaWNhdmF0aSB1bmVuZG8gbGUgcGFyb2xlIGNoZSBmb3JtYW5vIGxhIGxhYmVsIHRyYW1pdGUgXCJfXCIpLlxyXG4gICAqIEBwYXJhbSBmaWVsZCBDYW1wbyBkYSBzYWx2YXJlXHJcbiAgICovXHJcbiAgb25TYXZlRmllbGQoZmllbGQ6IEJhc2VGaWVsZCkge1xyXG4gICAgaWYgKGZpZWxkKSB7XHJcbiAgICAgIGlmIChcclxuICAgICAgICB0aGlzLmZvcm0uRmllbGRzXHJcbiAgICAgICAgJiYgdGhpcy5mb3JtLkZpZWxkcy5maW5kKFxyXG4gICAgICAgICAgKGYsIGkpID0+IGYuTGFiZWwgPT09IGZpZWxkLkxhYmVsXHJcbiAgICAgICAgICAgICYmICh0aGlzLmluZGV4U2VsZWN0ZWRGaWVsZCA9PSBudWxsID8gdHJ1ZSA6IHRoaXMuaW5kZXhTZWxlY3RlZEZpZWxkICE9PSBpKVxyXG4gICAgICAgIClcclxuICAgICAgKSB7XHJcbiAgICAgICAgRXFwRHluYW1pY01vZHVsZURpYWxvZ1NlcnZpY2UuV2FybmluZygnSW1wb3NzaWJpbGUgaW5zZXJpcmUgZHVlIGNhbXBpIGNvbiBsYSBzdGVzc2EgbGFiZWwuJyk7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbXBvc3NpYmlsZSBpbnNlcmlyZSBkdWUgY2FtcGkgY29uIGxhIHN0ZXNzYSBsYWJlbC4nKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHRoaXMuaW5kZXhTZWxlY3RlZEZpZWxkICE9IG51bGwgJiYgdGhpcy5pbmRleFNlbGVjdGVkRmllbGQgPj0gMCkge1xyXG4gICAgICAgIHRoaXMuZm9ybS5GaWVsZHNbdGhpcy5pbmRleFNlbGVjdGVkRmllbGRdID0gZmllbGQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmZvcm0uRmllbGRzKSB7XHJcbiAgICAgICAgICB0aGlzLmZvcm0uRmllbGRzID0gbmV3IEFycmF5PEJhc2VGaWVsZD4oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5mb3JtLkZpZWxkcy5wdXNoKGZpZWxkKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5jbG9zZUZpZWxkRGlhbG9nKCk7XHJcbiAgICB0aGlzLnNldEZpZWxkT3JkaW5hbFBvc2l0aW9uKCk7XHJcbiAgICB0aGlzLnJlbG9hZEZpZWxkc1RhYmxlKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gY2hlIGNvbnRyb2xsYSBzZSBsbyBzdGVwIHBlciBsJ2FnZ2l1bnRhIGRlaSBjYW1waSBuZWxsYSBmb3JtIMOoIGNvbmNsdXNvLlxyXG4gICAqIEByZXR1cm5zIFNlIFRSVUUgbG8gc3RlcCB2aWVuZSBjb25zaWRlcmF0byBjb21wbGV0YXRvIGVkIMOoIHBvc3NiaWxlIHBhc3NhcmUgYWwgc3VjY2Vzc2l2by5cclxuICAgKi9cclxuICBpc0ZpZWxkU3RlcENvbXBsZXRlZCgpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5mb3JtLkZpZWxkcykge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5mb3JtLkZvcm1TY2FsYXJUeXBlICE9IEZvcm1TY2FsYXJUeXBlRW51bS5TZW1wbGljZSAmJiB0aGlzLmZvcm0uRmllbGRzLmZpbmQoZiA9PiAhZi5GaWVsZEdyb3VwKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtLkZpZWxkcy5sZW5ndGggPiAwO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIHBlciBhcHJpcmUgaWwgZGlhbG9nIGRpIGNyZWF6aW9uZS9tb2RpZmljYSBkZWxsZSBmb3JtIGRpIGRldHRhZ2xpby5cclxuICAgKiBTZSBpbCBwYXJhbWV0cm8gcGFzc2F0byDDqCBudWxsIHNvbm8gaW4gYWdnaXVudGEgYWx0cmltZW50aSBzb25vIGluIG1vZGlmaWNhLlxyXG4gICAqIEBwYXJhbSBpbm5lbnJGb3JtIEZvcm0gZGkgZGV0dGFnbGlvIGRhIG1vZGlmaWNhcmUgKHNlIG51bGwgYWxsb3JhIHZhZG8gaW4gYWRkKS5cclxuICAgKi9cclxuICBvcGVuSW5uZXJGb3JtRGlhbG9nKGlubmVuckZvcm06IEZvcm0gPSBudWxsKSB7XHJcbiAgICBpZiAoaW5uZW5yRm9ybSkge1xyXG4gICAgICB0aGlzLmluZGV4U2VsZWN0ZWRJbm5lckZvcm0gPSB0aGlzLmZvcm0uSW5uZXJGb3Jtcy5pbmRleE9mKGlubmVuckZvcm0pO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSW5uZXJGb3JtID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbm5lbnJGb3JtKSk7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRJbm5lckZvcm0uT2xkTmFtZSA9IGlubmVuckZvcm0uTmFtZTtcclxuICAgICAgdGhpcy5pbmRleFNlbGVjdGVkRmllbGQgPSB0aGlzLmZvcm0uRmllbGRzLmZpbmRJbmRleChmID0+IGYuTGFiZWwgPT09IGlubmVuckZvcm0uTmFtZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSW5uZXJGb3JtID0gbmV3IEZvcm0oKTtcclxuICAgICAgdGhpcy5pbmRleFNlbGVjdGVkSW5uZXJGb3JtID0gbnVsbDtcclxuICAgICAgdGhpcy5pbmRleFNlbGVjdGVkRmllbGQgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgdGhpcy5kaWFsb2dJbm5lckZvcm1SZWYgPSB0aGlzLmRpYWxvZy5vcGVuKHRoaXMuZGlhbG9nSW5uZXJGb3JtLCB7XHJcbiAgICAgIGRpc2FibGVDbG9zZTogdHJ1ZSxcclxuICAgICAgaGFzQmFja2Ryb3A6IHRydWUsXHJcbiAgICAgIHdpZHRoOiAnODUlJ1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gc2NhdGVuYXRvIGFsIHNhbHZhdGFnZ2lvIGRpIHVuYSBmb3JtIGRpIGRldHRhZ2xpby4gXHJcbiAgICogQHBhcmFtIGV2ZW50IEZvcm0gY3JlYXRhL21vZGlmaWNhdGEgZGFsbCd1dGVudGUuIFNlIMOoIG51bGwgYWxsb3JhIGwndXRlbnRlIGhhIGFiYmFuZG9uYXRvIGxhIGNvbmZpZ3VyYXppb25lLlxyXG4gICAqL1xyXG4gIG9uU2F2ZU9yRXhpdElubmVyRm9ybShldmVudDogRm9ybSkge1xyXG4gICAgaWYgKGV2ZW50ICE9IG51bGwpIHtcclxuICAgICAgaWYgKHRoaXMuZm9ybS5OYW1lID09PSBldmVudC5OYW1lIHx8XHJcbiAgICAgICAgKFxyXG4gICAgICAgICAgdGhpcy5mb3JtLklubmVyRm9ybXNcclxuICAgICAgICAgICYmIHRoaXMuZm9ybS5Jbm5lckZvcm1zLmZpbmQoXHJcbiAgICAgICAgICAgIChhLCBpKSA9PiBhLk5hbWUgPT09IGV2ZW50Lk5hbWVcclxuICAgICAgICAgICAgICAmJiAodGhpcy5pbmRleFNlbGVjdGVkSW5uZXJGb3JtID09IG51bGwgPyB0cnVlIDogdGhpcy5pbmRleFNlbGVjdGVkSW5uZXJGb3JtICE9PSBpKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICkgfHxcclxuICAgICAgICAoXHJcbiAgICAgICAgICB0aGlzLmZvcm0uRmllbGRzXHJcbiAgICAgICAgICAmJiB0aGlzLmluZGV4U2VsZWN0ZWRJbm5lckZvcm0gPT0gbnVsbFxyXG4gICAgICAgICAgJiYgdGhpcy5mb3JtLkZpZWxkcy5maW5kKFxyXG4gICAgICAgICAgICAoZiwgaSkgPT4gZi5MYWJlbCA9PT0gZXZlbnQuTmFtZVxyXG4gICAgICAgICAgICAgICYmICh0aGlzLmluZGV4U2VsZWN0ZWRGaWVsZCA9PSBudWxsID8gdHJ1ZSA6IHRoaXMuaW5kZXhTZWxlY3RlZEZpZWxkICE9PSBpKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgIClcclxuICAgICAgKSB7XHJcbiAgICAgICAgRXFwRHluYW1pY01vZHVsZURpYWxvZ1NlcnZpY2UuV2FybmluZygnSW1wb3NzaWJpbGUgaW5zZXJpcmUgZHVlIGZvcm0gZGkgZGV0dGFnbGlvIGNvbiBsbyBzdGVzc28gbm9tZS4nKTtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltcG9zc2liaWxlIGluc2VyaXJlIGR1ZSBmb3JtIGRpIGRldHRhZ2xpbyBjb24gbG8gc3Rlc3NvIG5vbWUuJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGxldCBpbm5lckZvcm1GaWVsZDogQmFzZUZpZWxkID0gbmV3IEJhc2VGaWVsZCgpO1xyXG4gICAgICBpbm5lckZvcm1GaWVsZC5OYW1lID0gZXZlbnQuTmFtZS5zcGxpdChcIiBcIikuam9pbihcIl9cIik7XHJcbiAgICAgIGlubmVyRm9ybUZpZWxkLkxhYmVsID0gZXZlbnQuTmFtZTtcclxuICAgICAgaW5uZXJGb3JtRmllbGQuRmllbGRUeXBlID0gRmllbGRUeXBlRW51bVsnRm9ybSBkaSBkZXR0YWdsaW8nXTtcclxuICAgICAgaW5uZXJGb3JtRmllbGQuRmllbGRHcm91cCA9IHRoaXMuaW5kZXhTZWxlY3RlZEZpZWxkICE9IG51bGwgPyB0aGlzLmZvcm0uRmllbGRzW3RoaXMuaW5kZXhTZWxlY3RlZEZpZWxkXS5GaWVsZEdyb3VwIDogbnVsbDtcclxuXHJcbiAgICAgIGlmICh0aGlzLmluZGV4U2VsZWN0ZWRJbm5lckZvcm0gIT0gbnVsbCAmJiB0aGlzLmluZGV4U2VsZWN0ZWRJbm5lckZvcm0gPj0gMCkge1xyXG4gICAgICAgIHRoaXMuZm9ybS5Jbm5lckZvcm1zW3RoaXMuaW5kZXhTZWxlY3RlZElubmVyRm9ybV0gPSBldmVudDtcclxuICAgICAgICB0aGlzLmZvcm0uRmllbGRzW3RoaXMuaW5kZXhTZWxlY3RlZEZpZWxkXSA9IGlubmVyRm9ybUZpZWxkO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICghdGhpcy5mb3JtLklubmVyRm9ybXMpIHtcclxuICAgICAgICAgIHRoaXMuZm9ybS5Jbm5lckZvcm1zID0gbmV3IEFycmF5PEZvcm0+KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZm9ybS5Jbm5lckZvcm1zLnB1c2goZXZlbnQpO1xyXG4gICAgICAgIHRoaXMuZm9ybS5GaWVsZHMucHVzaChpbm5lckZvcm1GaWVsZCk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5yZWxvYWRGaWVsZHNUYWJsZSgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5kaWFsb2dJbm5lckZvcm1SZWYuY2xvc2UoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBwZXIgYXByaXJlIGlsIGRpYWxvZyBkaSBjcmVhemlvbmUvbW9kaWZpY2EgZGVsbGUgYWN0aW9uLlxyXG4gICAqIFNlIGlsIHBhcmFtZXRybyBwYXNzYXRvIMOoIG51bGwgc29ubyBpbiBhZ2dpdW50YSBhbHRyaW1lbnRpIHNvbm8gaW4gbW9kaWZpY2EuXHJcbiAgICogQHBhcmFtIGFjdGlvbiBBY3Rpb25PblJlY29yZCBkYSBtb2RpZmljYXJlIChzZSBudWxsIGFsbG9yYSB2YWRvIGluIGFkZCkuXHJcbiAgICovXHJcbiAgb3BlbkFjdGlvbk9uUmVjb3JkRGlhbG9nKGFjdGlvbjogQWN0aW9uT25SZWNvcmQgPSBudWxsKSB7XHJcbiAgICBpZiAoYWN0aW9uKSB7XHJcbiAgICAgIHRoaXMuaW5kZXhTZWxlY3RlZEFjdGlvbiA9IHRoaXMuZm9ybS5BY3Rpb25zT25SZWNvcmQuaW5kZXhPZihhY3Rpb24pO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkQWN0aW9uID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShhY3Rpb24pKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRBY3Rpb24gPSBuZXcgQWN0aW9uT25SZWNvcmQoKTtcclxuICAgICAgdGhpcy5pbmRleFNlbGVjdGVkQWN0aW9uID0gbnVsbDtcclxuICAgIH1cclxuICAgIHRoaXMuY3JlYXRlQWN0aW9uT25SZWNvcmRGb3JtKCk7XHJcbiAgICB0aGlzLmRpYWxvZ0FjdGlvbk9uUmVjb3JkUmVmID0gdGhpcy5kaWFsb2cub3Blbih0aGlzLmRpYWxvZ0FjdGlvbk9uUmVjb3JkLCB7XHJcbiAgICAgIGRpc2FibGVDbG9zZTogdHJ1ZSxcclxuICAgICAgaGFzQmFja2Ryb3A6IHRydWUsXHJcbiAgICAgIHdpZHRoOiAnNzUlJ1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gcGVyIGltcG9zdGFyZSBpIHZhbG9yaSBkYSBzdWdnZXJpcmUgbmVsbCdhdXRvY29tcGxldGUgZGVsIGNhbXBvIEZvcm11bGEuXHJcbiAgICogVmllbmUgc2NhdGVuYXRvIGFsIGZvY3VzIChpbiBxdWVzdG8gY2FzbyB2aWVuZSBwYXNzYXRvIGlsIHBhcmFtZXRybyBhIG51bGwgcGVyIGRpZmZlcmVuemlhcmxvXHJcbiAgICogZGFsbCdldmVudG8gZGkgY2xpY2sgc3VsbGEgdGFzdGllcmEpIGUgYWwga2V5dXAgc3VsbCdpbnB1dCAoaWwgcGFyYW1ldHJvIMOoIGRpdmVyc28gZGEgbnVsbCkuXHJcbiAgICogQHBhcmFtIGtleWJvYXJkRXZlbnQgRXZlbnRvIHNjYXRlbmF0byBhbCBrZXl1cCBzdWxsYSB0YXN0aWVyYS4gU2UgbnVsbCBhbGxvcmEgaWwgbWV0b2RvIMOoIHN0YXRvIGludm9jYXRvIGRhbCBmb2N1cyBzdWxsJ2lucHV0LlxyXG4gICAqIEBzdW1tYXJ5IEFnZ2lvcm5hIGwnZWxlbmNvIGRlaSBzdWdnZXJpbWVudGkgcGVyIGwnYXV0b2NvbXBsZXRlIHNlIGwndXRlbnRlIGVzZWd1ZSBpbCBmb2N1cyBzdWxsJ2lucHV0XHJcbiAgICogb3BwdXJlIGFsIGtleXVwIHN1bGxhIHRhc3RpZXJhIGRpIHVuIHRhc3RvIGRpdmVyc28gZGFsbGUgZnJlY2NlLlxyXG4gICAqL1xyXG4gIHNldEFjdGlvbkF1dG9jb21wbGV0ZU9wdGlvbnMoa2V5Ym9hcmRFdmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgLy8gQ3JlbyBsJ2FycmF5IHBlciBsJ2F1dG9jb21wbGV0ZSBzb2xvIHNlIHN0byBmYWNlbmRvIGlsIGZvY3VzIHN1bGwnaW5wdXQgbyBzZSBzdG8gcHJlbWVuZG8gdW4gdGFzdG9cclxuICAgIC8vIHN1bGxhIHRhc3RpZXJhIGRpdmVyc28gZGFsbGUgZnJlY2NlIChpbiBxdWVzdCd1bHRpbW8gY2Fzbywgc2Ugbm9uIHZpZW5lIGVzZWd1aXRvIGlsIGZpbHRybyBzdWxsJ2V2ZW50byxcclxuICAgIC8vIG5vbiBzaSBwdcOyIHNlbGV6aW9uYXJlIHVuIHN1Z2dlcmltZW50byBkZWxsJ2F1dG9jb21wbGV0ZSBwZXJjaMOoIGFsIGNsaWNrIHZlcnJlYmJlIHJpY2FyaWNhdG8gbCdhcnJheSBlXHJcbiAgICAvLyBzaSBwcmVkZXJlYmJlIGxhIHNlbGV6aW9uZSBhcHBlbmEgZmF0dGEpLlxyXG4gICAgaWYgKCFrZXlib2FyZEV2ZW50IHx8ICFrZXlib2FyZEV2ZW50LmNvZGUuaW5jbHVkZXMoXCJBcnJvd1wiKSkge1xyXG4gICAgICB0aGlzLmFjdGlvbkF1dG9jb21wbGV0ZU9wdGlvbnMgPSBVdGlsaXR5SGVscGVyU2VydmljZS5HZXRBdXRvY29tcGxldGVPcHRpb25zKHRoaXMuZm9ybS5GaWVsZHMsIHRoaXMuc2VsZWN0ZWRBY3Rpb24uQWN0aW9uKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBwZXIgc2FsdmFyZSBsJ2F6aW9uZSBjcmVhdGEvbW9kaWZpY2F0ZS5cclxuICAgKi9cclxuICBzYXZlQWN0aW9uT25SZWNvcmQoKSB7XHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMuZm9ybS5BY3Rpb25zT25SZWNvcmRcclxuICAgICAgJiYgdGhpcy5mb3JtLkFjdGlvbnNPblJlY29yZC5maW5kKFxyXG4gICAgICAgIChhLCBpKSA9PiBhLk5hbWUgPT09IHRoaXMuc2VsZWN0ZWRBY3Rpb24uTmFtZVxyXG4gICAgICAgICAgJiYgKHRoaXMuaW5kZXhTZWxlY3RlZEFjdGlvbiA9PSBudWxsID8gdHJ1ZSA6IHRoaXMuaW5kZXhTZWxlY3RlZEFjdGlvbiAhPT0gaSlcclxuICAgICAgKVxyXG4gICAgKSB7XHJcbiAgICAgIEVxcER5bmFtaWNNb2R1bGVEaWFsb2dTZXJ2aWNlLldhcm5pbmcoJ0ltcG9zc2liaWxlIGluc2VyaXJlIGR1ZSBhY3Rpb24gY29uIGxvIHN0ZXNzbyBub21lLicpO1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltcG9zc2liaWxlIGluc2VyaXJlIGR1ZSBhY3Rpb24gY29uIGxvIHN0ZXNzbyBub21lLicpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmluZGV4U2VsZWN0ZWRBY3Rpb24gIT0gbnVsbCAmJiB0aGlzLmluZGV4U2VsZWN0ZWRBY3Rpb24gPj0gMCkge1xyXG4gICAgICB0aGlzLmZvcm0uQWN0aW9uc09uUmVjb3JkW3RoaXMuaW5kZXhTZWxlY3RlZEFjdGlvbl0gPSB0aGlzLnNlbGVjdGVkQWN0aW9uO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKCF0aGlzLmZvcm0uQWN0aW9uc09uUmVjb3JkKSB7XHJcbiAgICAgICAgdGhpcy5mb3JtLkFjdGlvbnNPblJlY29yZCA9IG5ldyBBcnJheTxBY3Rpb25PblJlY29yZD4oKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmZvcm0uQWN0aW9uc09uUmVjb3JkLnB1c2godGhpcy5zZWxlY3RlZEFjdGlvbik7XHJcbiAgICB9XHJcbiAgICB0aGlzLmNsb3NlRGlhbG9nQWN0aW9uT25SZWNvcmQoKTtcclxuICAgIHRoaXMuc2V0QWN0aW9uT3JkaW5hbFBvc2l0aW9uKCk7XHJcbiAgICB0aGlzLnJlbG9hZEFjdGlvbnNPblJlY29yZFRhYmxlKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gcGVyIGNoaXVkZXJlIGlsIGRpYWxvZyBkaSBnZXN0aW9uZSBkZWxsZSBhY3Rpb24uXHJcbiAgICovXHJcbiAgY2xvc2VEaWFsb2dBY3Rpb25PblJlY29yZCgpIHtcclxuICAgIHRoaXMuZGlhbG9nQWN0aW9uT25SZWNvcmRSZWYuY2xvc2UoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBwZXIgc2VnbmFyZSBjb21lIGNvbmNsdXNhIGxhIGNyZWF6aW9uZSBkZWxsYSBmb3JtIGUgcGVyIGNyZWFybmUgdW5hIGNvcGlhXHJcbiAgICogZGEgdmlzYWxpenphcmUgY29tZSBhbnRlcHJpbWEuXHJcbiAgICogQHBhcmFtIGNvbXBsZXRlZCBTZSBUUlVFIHNlZ25hIGxhIGZvcm0gY29tZSBjb25jbHVzYSBlIG5lIGNyZWEgdW5hIGNvcGlhIGRhIHZpc3VhbGl6emFyZVxyXG4gICAqL1xyXG4gIHNldEZvcm1TdGF0dXMoY29tcGxldGVkOiBib29sZWFuKSB7XHJcbiAgICBpZiAoY29tcGxldGVkKSB7XHJcbiAgICAgIHRoaXMuZm9ybUNvbXBsZXRlZCA9IHRydWU7XHJcbiAgICAgIHRoaXMucHJldmlld0Zvcm0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuZm9ybSkpO1xyXG5cclxuICAgICAgLy8gUGVyIHZpc3VhbGl6emFyZSBjb3JyZXR0YW1lbnRlIGwnb2FudGVwcmltYSBkZWxsYSBmb3JtIGFwcGVuYSBjcmVhdGFcclxuICAgICAgLy8gYmlzb2duYSB2YWxvcml6emFyZSBsYSBwcm9wcmlldMOgIE5hbWUgZGVpIGNhbXBpIGRlbGxhIGZvcm0gZSBkZWxsZSBJbm5lckZvcm1zLlxyXG4gICAgICB0aGlzLnByZXZpZXdGb3JtLkZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHsgZmllbGQuTmFtZSA9IGZpZWxkLkxhYmVsLnNwbGl0KCcgJykuam9pbignXycpOyB9KTtcclxuICAgICAgaWYgKHRoaXMucHJldmlld0Zvcm0uSW5uZXJGb3JtcyAmJiB0aGlzLnByZXZpZXdGb3JtLklubmVyRm9ybXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHRoaXMucHJldmlld0Zvcm0uSW5uZXJGb3Jtcy5mb3JFYWNoKGZvcm0gPT4ge1xyXG4gICAgICAgICAgZm9ybS5GaWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7IGZpZWxkLk5hbWUgPSBmaWVsZC5MYWJlbC5zcGxpdCgnICcpLmpvaW4oJ18nKTsgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZm9ybUNvbXBsZXRlZCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnByZXZpZXdGb3JtID0gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBjaGUgc2NhdGVuYSBsJ2V2ZW50byBkaSBvdXRwdXQgcGVyIHNhbHZhcmUgbGEgZm9ybSBjcmVhdGEgYWxsYSBmaW5lIGRlbCB3aXphcmRcclxuICAgKi9cclxuICBzYXZlRm9ybSgpIHtcclxuICAgIHRoaXMuc2F2ZUZvcm1FdmVudC5lbWl0KHRoaXMuZm9ybSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb25maWd1cmEgbGUgY29sb25uZSBwZXIgbGUgdGFiZWxsZSBuZWNlc3NhcmllIGFsbGEgY3JlYXppb25lIGRlbGxhIGZvcm06XHJcbiAgICogIC0gcGVyIGxhIHZpc3VhbGl6emF6aW9uZSBkZWkgY2FtcGkgaW5zZXJpdGlcclxuICAgKiAgLSBwZXIgbGUgZm9ybSBkaSBkZXR0YWdsaW8gY3JlYXRlXHJcbiAgICogIC0gcGVyIGxlIGF6aW9uaSBjb25maWd1cmF0ZSBzdWkgcmVjb3JkIGRlbGxhIGZvcm1cclxuICAgKi9cclxuICBwcml2YXRlIGNvbmZpZ3VyZUNvbHVtbnMoKSB7XHJcbiAgICB0aGlzLmZpZWxkc0NvbHVtbnMgPSBbXHJcbiAgICAgIHtcclxuICAgICAgICBrZXk6ICdhY3Rpb24nLCBkaXNwbGF5OiAnJywgdHlwZTogVHlwZUNvbHVtbi5NZW51QWN0aW9uLCBidXR0b25NZW51SWNvbjogJ21vcmVfdmVydCcsIHN0eWxlczogeyBmbGV4OiAnMCAwIDYlJyB9LFxyXG4gICAgICAgIGFjdGlvbnM6IFtcclxuICAgICAgICAgIHsgbmFtZTogJ01vZGlmaWNhJywgaWNvbjogJ2VkaXQnLCBmbjogKGVsZW1lbnQsIGluZGV4LCBjb2wpID0+IHRoaXMuZWRpdEZpZWxkKGVsZW1lbnQpIH0sXHJcbiAgICAgICAgICB7IG5hbWU6ICdFbGltaW5hJywgaWNvbjogJ2RlbGV0ZScsIGZuOiAoZWxlbWVudCwgaW5kZXgsIGNvbCkgPT4gdGhpcy5kZWxldGVFbGVtZW50KGVsZW1lbnQsIFwiRmllbGRzXCIpIH0sXHJcbiAgICAgICAgICB7XHJcbiAgICAgICAgICAgIG5hbWU6ICdTcG9zdGEgc3UnLCBpY29uOiAnYXJyb3dfdXB3YXJkJyxcclxuICAgICAgICAgICAgZm46IChlbGVtZW50LCBpbmRleCwgY29sKSA9PiB0aGlzLm1vdmVFbGVtZW50KGVsZW1lbnQsIHRydWUsIFwiRmllbGRzXCIpLFxyXG4gICAgICAgICAgICBkaXNhYmxlZDogKGVsZW1lbnQpID0+IHRoaXMuZm9ybS5GaWVsZHMuaW5kZXhPZihlbGVtZW50KSA9PT0gMFxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgbmFtZTogJ1Nwb3N0YSBnacO5JywgaWNvbjogJ2Fycm93X2Rvd253YXJkJyxcclxuICAgICAgICAgICAgZm46IChlbGVtZW50LCBpbmRleCwgY29sKSA9PiB0aGlzLm1vdmVFbGVtZW50KGVsZW1lbnQsIGZhbHNlLCBcIkZpZWxkc1wiKSxcclxuICAgICAgICAgICAgZGlzYWJsZWQ6IChlbGVtZW50KSA9PiB0aGlzLmZvcm0uRmllbGRzLmluZGV4T2YoZWxlbWVudCkgPj0gKHRoaXMuZm9ybS5GaWVsZHMubGVuZ3RoIC0gMSlcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgXVxyXG4gICAgICB9LFxyXG4gICAgICB7IGtleTogJ0ZpZWxkVHlwZScsIGRpc3BsYXk6ICdUaXBvbG9naWEnLCB0eXBlOiBUeXBlQ29sdW1uLkVudW0sIGVudW1Nb2RlbDogRmllbGRUeXBlRW51bSB9LFxyXG4gICAgICB7IGtleTogJ0xhYmVsJywgZGlzcGxheTogJ0xhYmVsJyB9LFxyXG4gICAgICB7IGtleTogJ0Rlc2NyaXB0aW9uJywgZGlzcGxheTogJ0Rlc2NyaXppb25lJyB9LFxyXG4gICAgICB7XHJcbiAgICAgICAga2V5OiAnUmVxdWlyZWQnLCBkaXNwbGF5OiAnT2JibGlnYXRvcmlvJyxcclxuICAgICAgICB2YWx1ZTogKGVsZW1lbnQpID0+ICEhZWxlbWVudC5SZXF1aXJlZCxcclxuICAgICAgICB0eXBlOiBUeXBlQ29sdW1uLkJvb2xlYW4sXHJcbiAgICAgICAgYm9vbGVhblZhbHVlczoge1xyXG4gICAgICAgICAgdHJ1ZTogJzxpIGNsYXNzPVwiZmEgZmEtY2hlY2sgc3VjY2Vzcy1jb2xvclwiPjwvaT4nLFxyXG4gICAgICAgICAgZmFsc2U6ICc8aSBjbGFzcz1cImZhIGZhLWNsb3NlIGVycm9yLWNvbG9yXCI+PC9pPidcclxuICAgICAgICB9LFxyXG4gICAgICAgIHN0eWxlczogeyBmbGV4OiAnMCAwIDclJywgY2VsbEFsaWdubWVudDogQ2VsbEFsaWdubWVudEVudW0uQ0VOVEVSIH1cclxuICAgICAgfSxcclxuICAgIF07XHJcblxyXG4gICAgaWYgKHRoaXMuZm9ybS5Gb3JtU2NhbGFyVHlwZSAmJiB0aGlzLmZvcm0uRm9ybVNjYWxhclR5cGUgIT0gRm9ybVNjYWxhclR5cGVFbnVtLlNlbXBsaWNlKSB7XHJcbiAgICAgIHRoaXMuZmllbGRzQ29sdW1ucy5zcGxpY2UoXHJcbiAgICAgICAgdGhpcy5maWVsZHNDb2x1bW5zLmZpbmRJbmRleChjID0+IGMua2V5ID09ICdEZXNjcmlwdGlvbicpLCAwLFxyXG4gICAgICAgIHsga2V5OiAnRmllbGRHcm91cCcsIGRpc3BsYXk6ICdTZXppb25lJywgdHlwZTogVHlwZUNvbHVtbi5FeHRlcm5hbFRlbXBsYXRlLCBleHRlcm5hbFRlbXBsYXRlOiB0aGlzLmZpZWxkU2VjdGlvbkNvbHVtblRlbXBsYXRlIH1cclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFjdGlvbnNPblJlY29yZENvbHVtbnMgPSBbXHJcbiAgICAgIHtcclxuICAgICAgICBrZXk6ICdhY3Rpb24nLCBkaXNwbGF5OiAnJywgdHlwZTogVHlwZUNvbHVtbi5NZW51QWN0aW9uLCBidXR0b25NZW51SWNvbjogJ21vcmVfdmVydCcsIHN0eWxlczogeyBmbGV4OiAnMCAwIDYlJyB9LFxyXG4gICAgICAgIGFjdGlvbnM6IFtcclxuICAgICAgICAgIHsgbmFtZTogJ01vZGlmaWNhJywgaWNvbjogJ2VkaXQnLCBmbjogKGVsZW1lbnQsIGluZGV4LCBjb2wpID0+IHRoaXMub3BlbkFjdGlvbk9uUmVjb3JkRGlhbG9nKGVsZW1lbnQpIH0sXHJcbiAgICAgICAgICB7IG5hbWU6ICdFbGltaW5hJywgaWNvbjogJ2RlbGV0ZScsIGZuOiAoZWxlbWVudCwgaW5kZXgsIGNvbCkgPT4gdGhpcy5kZWxldGVFbGVtZW50KGVsZW1lbnQsIFwiQWN0aW9uc09uUmVjb3JkXCIpIH0sXHJcbiAgICAgICAgICB7XHJcbiAgICAgICAgICAgIG5hbWU6ICdTcG9zdGEgc3UnLCBpY29uOiAnYXJyb3dfdXB3YXJkJyxcclxuICAgICAgICAgICAgZm46IChlbGVtZW50LCBpbmRleCwgY29sKSA9PiB0aGlzLm1vdmVFbGVtZW50KGVsZW1lbnQsIHRydWUsIFwiQWN0aW9uc09uUmVjb3JkXCIpLFxyXG4gICAgICAgICAgICBkaXNhYmxlZDogKGVsZW1lbnQpID0+IHRoaXMuZm9ybS5BY3Rpb25zT25SZWNvcmQuaW5kZXhPZihlbGVtZW50KSA9PT0gMFxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgbmFtZTogJ1Nwb3N0YSBnacO5JywgaWNvbjogJ2Fycm93X2Rvd253YXJkJyxcclxuICAgICAgICAgICAgZm46IChlbGVtZW50LCBpbmRleCwgY29sKSA9PiB0aGlzLm1vdmVFbGVtZW50KGVsZW1lbnQsIGZhbHNlLCBcIkFjdGlvbnNPblJlY29yZFwiKSxcclxuICAgICAgICAgICAgZGlzYWJsZWQ6IChlbGVtZW50KSA9PiB0aGlzLmZvcm0uQWN0aW9uc09uUmVjb3JkLmluZGV4T2YoZWxlbWVudCkgPj0gKHRoaXMuZm9ybS5BY3Rpb25zT25SZWNvcmQubGVuZ3RoIC0gMSlcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgXVxyXG4gICAgICB9LFxyXG4gICAgICB7IGtleTogJ0ljb24nLCBkaXNwbGF5OiAnSWNvbmEnLCBzdHlsZXM6IHsgZmxleDogJyAwIDAgMTUlJyB9IH0sXHJcbiAgICAgIHsga2V5OiAnTmFtZScsIGRpc3BsYXk6ICdOb21lJywgc3R5bGVzOiB7IGZsZXg6ICcgMCAwIDIwJScgfSB9LFxyXG4gICAgICB7IGtleTogJ0FjdGlvbicsIGRpc3BsYXk6ICdBemlvbmUnIH0sXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYSBpbCBGb3JtR3JvdXAgcGVyIGwnb2dnZXR0byBGb3JtXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjcmVhdGVGb3JtRm9ybSgpIHtcclxuICAgIHRoaXMuZm9ybUZvcm1Hcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xyXG4gICAgICBOYW1lOiBbdGhpcy5mb3JtLk5hbWUsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxyXG4gICAgICBGb3JtU2NhbGFyVHlwZTogW3RoaXMuZm9ybS5Gb3JtU2NhbGFyVHlwZSwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXHJcbiAgICB9KTtcclxuICAgIHRoaXMub25DaGFuZ2VGb3JtU2NhbGFyVHlwZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYSBpbCBGb3JtR3JvdXAgZXByIGwnYWdnaXVudGEgbyBsYSBtb2RpZmljYSBkaSB1bmEgYWN0aW9uIHN1aSByZWNvcmQgZGVsbGEgRm9ybS5cclxuICAgKi9cclxuICBwcml2YXRlIGNyZWF0ZUFjdGlvbk9uUmVjb3JkRm9ybSgpIHtcclxuICAgIHRoaXMuYWN0aW9uT25SZWNvcmRGb3JtR3JvdXAgPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcclxuICAgICAgTmFtZTogW3RoaXMuc2VsZWN0ZWRBY3Rpb24uTmFtZSwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXHJcbiAgICAgIEljb246IFt0aGlzLnNlbGVjdGVkQWN0aW9uLkljb24sIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxyXG4gICAgICBBY3Rpb246IFt0aGlzLnNlbGVjdGVkQWN0aW9uLkFjdGlvbiwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoaXVkZSBpbCBkaWFsb2cgcGVyIGFnZ2l1bmdlcmUvbW9kaWZpY2FyZSB1biBGaWVsZCBzZW56YSBzYWx2YXJlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjbG9zZUZpZWxkRGlhbG9nKCkge1xyXG4gICAgdGhpcy5kaWFsb2dGaWVsZFJlZi5jbG9zZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIHBlciBnZXN0aXJlIGwnYXBlcnR1cmEgZGVsIGRpYWxvZyBwZXIgbGEgbW9kaWZpY2EgZGkgdW4gRmllbGQuXHJcbiAgICogU2UgaWwgZmllbGQgw6ggZGkgdGlwbyBcIkZvcm0gZGkgZGV0dGFnbGlvXCIgYXByZSBpbCBkaWFsb2cgcGVyIGxhIG1vZGlmaWNhIGRpIHVuYSBcclxuICAgKiBJbm5lckZvcm0gYWx0cmltZW50aSBhcHJlIHF1ZWxsbyBwZXIgbGEgbW9kaWZpY2EgZGkgdW4gRmllbGQuXHJcbiAgICogQHBhcmFtIGZpZWxkIENhbXBvIGRhIG1vZGlmaWNhcmVcclxuICAgKi9cclxuICBwcml2YXRlIGVkaXRGaWVsZChmaWVsZDogQmFzZUZpZWxkKSB7XHJcbiAgICBpZiAoZmllbGQuRmllbGRUeXBlICE9IEZpZWxkVHlwZUVudW1bJ0Zvcm0gZGkgZGV0dGFnbGlvJ10pIHtcclxuICAgICAgdGhpcy5vcGVuRmllbGREaWFsb2coZmllbGQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5vcGVuSW5uZXJGb3JtRGlhbG9nKHRoaXMuZm9ybS5Jbm5lckZvcm1zLmZpbmQoZiA9PiBmLk5hbWUgPT0gZmllbGQuTGFiZWwpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBwZXIgcmltdW92ZXJlIHVuIEZpZWxkIGFsbCdpbnRlcm5vIGRpIHVuYSBGb3JtLlxyXG4gICAqIFJpY2hpZWRlIGNvbmZlcm1hIGFsbCd1dGVudGUgcHJpbWEgZGkgcmltdW92ZXJsby5cclxuICAgKiBAcGFyYW0gZmllbGQgQmFzZUZpZWxkIGRhIHJpbXVvdmVyZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZGVsZXRlRWxlbWVudChlbGVtZW50OiBCYXNlRmllbGQgfCBBY3Rpb25PblJlY29yZCB8IEZvcm0sIHByb3BlcnR5TmFtZTogc3RyaW5nKSB7XHJcbiAgICBFcXBEeW5hbWljTW9kdWxlRGlhbG9nU2VydmljZS5Db25maXJtKCdFbGltaW5hcmUgbFxcJ2VsZW1lbnRvIHNlbGV6aW9uYXRvPycsICgpID0+IHtcclxuICAgICAgdGhpcy5mb3JtW3Byb3BlcnR5TmFtZV0uc3BsaWNlKHRoaXMuZm9ybVtwcm9wZXJ0eU5hbWVdLmluZGV4T2YoZWxlbWVudCksIDEpO1xyXG4gICAgICBpZiAocHJvcGVydHlOYW1lID09PSBcIkZpZWxkc1wiKSB7XHJcbiAgICAgICAgdGhpcy5zZXRGaWVsZE9yZGluYWxQb3NpdGlvbigpO1xyXG4gICAgICAgIHRoaXMucmVsb2FkRmllbGRzVGFibGUoKTtcclxuICAgICAgfSBlbHNlIGlmIChwcm9wZXJ0eU5hbWUgPT09IFwiQWN0aW9uc09uUmVjb3JkXCIpIHtcclxuICAgICAgICB0aGlzLnNldEFjdGlvbk9yZGluYWxQb3NpdGlvbigpO1xyXG4gICAgICAgIHRoaXMucmVsb2FkQWN0aW9uc09uUmVjb3JkVGFibGUoKTtcclxuICAgICAgfVxyXG4gICAgfSwgZmFsc2UsICdSaWNoaWVzdGEgY29uZmVybWEnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBwZXIgc3Bvc3RhcmUgdW4gY2FtcG8gYWxsJ2ludGVybm8gZGVsbGEgZm9ybS5cclxuICAgKiBAcGFyYW0gZmllbGQgT2dnZXR0byBkaSB0aXBvIEJhc2VGaWVsZCBkYSBzcG9zdGFyZS5cclxuICAgKiBAcGFyYW0gbW92ZVVwIFNlIFRSVUUgYWxsb3JhIHNwb3N0YSB2ZXJzbyBsJ2FsdG8gaWwgY2FtcG8gKGFiYmFzc2EgbCdpbmRpY2UpIGFsdHJpbWVudGkgaWwgY29udHJhcmlvLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgbW92ZUVsZW1lbnQoZWxlbWVudDogQmFzZUZpZWxkIHwgQWN0aW9uT25SZWNvcmQsIG1vdmVVcDogYm9vbGVhbiwgcHJvcGVydHlOYW1lOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IHN0YXJ0aW5nSW5kZXggPSB0aGlzLmZvcm1bcHJvcGVydHlOYW1lXS5pbmRleE9mKGVsZW1lbnQpO1xyXG4gICAgY29uc3QgZW5kaW5nSW5kZXggPSBzdGFydGluZ0luZGV4ICsgKG1vdmVVcCA/IC0xIDogMSk7XHJcblxyXG4gICAgdGhpcy5mb3JtW3Byb3BlcnR5TmFtZV0uc3BsaWNlKHN0YXJ0aW5nSW5kZXgsIDEpO1xyXG4gICAgdGhpcy5mb3JtW3Byb3BlcnR5TmFtZV0uc3BsaWNlKGVuZGluZ0luZGV4LCAwLCBlbGVtZW50KTtcclxuXHJcbiAgICBpZiAocHJvcGVydHlOYW1lID09PSBcIkZpZWxkc1wiKSB7XHJcbiAgICAgIHRoaXMuc2V0RmllbGRPcmRpbmFsUG9zaXRpb24oKTtcclxuICAgICAgdGhpcy5yZWxvYWRGaWVsZHNUYWJsZSgpO1xyXG4gICAgfSBlbHNlIGlmIChwcm9wZXJ0eU5hbWUgPT09IFwiQWN0aW9uc09uUmVjb3JkXCIpIHtcclxuICAgICAgdGhpcy5zZXRBY3Rpb25PcmRpbmFsUG9zaXRpb24oKTtcclxuICAgICAgdGhpcy5yZWxvYWRBY3Rpb25zT25SZWNvcmRUYWJsZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW1wb3N0YSBsJ29yZGluYW1lbnRvIGRlbGxlIHNlemlvbmkgY2hlIGNvbXBvbmdvbm8gbGEgZm9ybS5cclxuICAgKi9cclxuICBwcml2YXRlIHNldEZvcm1GaWVsZEdyb3VwT3JkaW5hbFBvc2l0aW9uKCkge1xyXG4gICAgdGhpcy5mb3JtLkZvcm1GaWVsZHNHcm91cHMuZm9yRWFjaCgoZywgaSkgPT4gZy5PcmRpbmFsUG9zaXRpb24gPSBpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEltcG9zdGEgbCdvcmRpbmFtZW50byBkZWkgY2FtcGkgYWxsJ2ludGVybm8gZGVsbGEgZm9ybSBpbiBiYXNlIGFsbCdvcmRpbmUgY2hlIGwndXRlbnRlXHJcbiAgICogaGEgZGVmaW5pdG8gbmVsbGEgdGFiZWxsYSBpbiBjdWkgc29ubyBtb3N0cmF0aVxyXG4gICAqL1xyXG4gIHByaXZhdGUgc2V0RmllbGRPcmRpbmFsUG9zaXRpb24oKSB7XHJcbiAgICBpZiAodGhpcy5mb3JtLkZpZWxkcykge1xyXG4gICAgICB0aGlzLmZvcm0uRmllbGRzLmZvckVhY2goZmllbGQgPT4ge1xyXG4gICAgICAgIGZpZWxkLk9yZGluYWxQb3NpdGlvbiA9IHRoaXMuZm9ybS5GaWVsZHMuaW5kZXhPZihmaWVsZCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIHBlciByaWNhcmljYXJlIGkgZGF0aSBkZWxsYSB0YWJlbGxhIGRlaSBjYW1waSBhZ2dpdW50aSBpbiB1bmEgZm9ybVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVsb2FkRmllbGRzVGFibGUoKSB7XHJcbiAgICBpZiAodGhpcy5maWVsZHNUYWJsZSkge1xyXG4gICAgICB0aGlzLmZpZWxkc1RhYmxlLnJlbG9hZERhdGF0YWJsZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW1wb3N0YSBsJ29yZGluYW1lbnRvIGRlaSBjYW1waSBhbGwnaW50ZXJubyBkZWxsYSBmb3JtIGluIGJhc2UgYWxsJ29yZGluZSBjaGUgbCd1dGVudGVcclxuICAgKiBoYSBkZWZpbml0byBuZWxsYSB0YWJlbGxhIGluIGN1aSBzb25vIG1vc3RyYXRpXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXRBY3Rpb25PcmRpbmFsUG9zaXRpb24oKSB7XHJcbiAgICBpZiAodGhpcy5mb3JtLkFjdGlvbnNPblJlY29yZCkge1xyXG4gICAgICB0aGlzLmZvcm0uQWN0aW9uc09uUmVjb3JkLmZvckVhY2goYWN0aW9uID0+IHtcclxuICAgICAgICBhY3Rpb24uT3JkaW5hbFBvc2l0aW9uID0gdGhpcy5mb3JtLkFjdGlvbnNPblJlY29yZC5pbmRleE9mKGFjdGlvbik7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIHBlciByaWNhcmljYXJlIGkgZGF0aSBkZWxsYSB0YWJlbGxhIGRlbGxlIGF6aW9uaSBhZ2dpdW50aXZlIHN1aSByZWNvcmQgZGVsbGEgRm9ybS5cclxuICAgKi9cclxuICBwcml2YXRlIHJlbG9hZEFjdGlvbnNPblJlY29yZFRhYmxlKCkge1xyXG4gICAgaWYgKHRoaXMuYWN0aW9uc09uUmVjb3JkVGFibGUpIHtcclxuICAgICAgdGhpcy5hY3Rpb25zT25SZWNvcmRUYWJsZS5yZWxvYWREYXRhdGFibGUoKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19