keevo-components 1.5.140 → 1.5.142

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 (164) hide show
  1. package/README.md +24 -24
  2. package/esm2020/keevo-components.mjs +4 -4
  3. package/esm2020/lib/api/base-components/base-component-button.mjs +36 -36
  4. package/esm2020/lib/api/base-components/base-component-chart.mjs +92 -92
  5. package/esm2020/lib/api/base-components/base-component-crud-form.mjs +278 -278
  6. package/esm2020/lib/api/base-components/base-component-crud-list.mjs +67 -67
  7. package/esm2020/lib/api/base-components/base-component-crud.mjs +65 -65
  8. package/esm2020/lib/api/base-components/base-component-dropdown.mjs +161 -161
  9. package/esm2020/lib/api/base-components/base-component-input.mjs +93 -93
  10. package/esm2020/lib/api/base-components/base-component-multi-select.mjs +128 -128
  11. package/esm2020/lib/api/base-components/base-component.mjs +49 -49
  12. package/esm2020/lib/api/components/chart/chart.config.mjs +2 -2
  13. package/esm2020/lib/api/components/chart/chart.model.mjs +2 -2
  14. package/esm2020/lib/api/components/chart/orchart.config.mjs +2 -2
  15. package/esm2020/lib/api/components/chart/orchart.item.mjs +2 -2
  16. package/esm2020/lib/api/components/dropdown/filtro.combo.mjs +2 -2
  17. package/esm2020/lib/api/components/error/error.component.mjs +26 -26
  18. package/esm2020/lib/api/components/error/kverror.module.mjs +35 -35
  19. package/esm2020/lib/api/components/table/action-item.mjs +2 -2
  20. package/esm2020/lib/api/components/table/kv-menuitem.mjs +3 -3
  21. package/esm2020/lib/api/components/table/table.config.column.mjs +2 -2
  22. package/esm2020/lib/api/components/table/table.config.mjs +2 -2
  23. package/esm2020/lib/api/components/table/table.paginate.mjs +9 -9
  24. package/esm2020/lib/api/helpers/component-providers.mjs +16 -16
  25. package/esm2020/lib/api/helpers/translate-primeng.mjs +23 -23
  26. package/esm2020/lib/api/models/menu/master.model.mjs +2 -2
  27. package/esm2020/lib/api/models/menu/menu.model.mjs +2 -2
  28. package/esm2020/lib/api/models/menu/menucompleto.model.mjs +2 -2
  29. package/esm2020/lib/api/models/menu/sistemamenu.model.mjs +2 -2
  30. package/esm2020/lib/api/modules/primeng.module.mjs +247 -247
  31. package/esm2020/lib/api/services/base.api.service.mjs +74 -0
  32. package/esm2020/lib/api/services/component.service.mjs +27 -27
  33. package/esm2020/lib/api/services/form.service.mjs +102 -102
  34. package/esm2020/lib/api/services/imagens.service.mjs +22 -22
  35. package/esm2020/lib/api/services/notification.service.mjs +67 -67
  36. package/esm2020/lib/api/services/object.service.mjs +26 -26
  37. package/esm2020/lib/buttons/button-personalize/button-personalize.component.mjs +17 -17
  38. package/esm2020/lib/buttons/button-popup/button-popup.component.mjs +30 -0
  39. package/esm2020/lib/buttons/button-secondary/button-secondary.component.mjs +17 -17
  40. package/esm2020/lib/buttons/button-success/button-success.component.mjs +17 -17
  41. package/esm2020/lib/buttons/kvbutton.module.mjs +39 -34
  42. package/esm2020/lib/chart/chart.component.mjs +145 -145
  43. package/esm2020/lib/chart/kvchart.module.mjs +32 -32
  44. package/esm2020/lib/directives/template.directive.mjs +24 -24
  45. package/esm2020/lib/inputs/check/check.component.mjs +26 -26
  46. package/esm2020/lib/inputs/dropdown/dropdown.component.mjs +36 -36
  47. package/esm2020/lib/inputs/input-calendar/input-calendar.component.mjs +88 -88
  48. package/esm2020/lib/inputs/input-mask/input-mask.component.mjs +22 -22
  49. package/esm2020/lib/inputs/input-number/input-number.component.mjs +56 -56
  50. package/esm2020/lib/inputs/input-password/input-password.component.mjs +32 -32
  51. package/esm2020/lib/inputs/input-text/input-text.component.mjs +20 -20
  52. package/esm2020/lib/inputs/input-text-checkbox/input-text-checkbox.component.mjs +37 -37
  53. package/esm2020/lib/inputs/input-textarea/input-textarea.component.mjs +42 -42
  54. package/esm2020/lib/inputs/input-time/input-time.component.mjs +23 -23
  55. package/esm2020/lib/inputs/kvinputs.module.mjs +99 -99
  56. package/esm2020/lib/inputs/multi-select/multi-select.component.mjs +37 -37
  57. package/esm2020/lib/inputs/radio-group/radio-group.component.mjs +49 -49
  58. package/esm2020/lib/inputs/switch/switch.component.mjs +32 -32
  59. package/esm2020/lib/keevo-components.module.mjs +91 -91
  60. package/esm2020/lib/login/kvlogin.module.mjs +47 -47
  61. package/esm2020/lib/login/login.component.mjs +38 -38
  62. package/esm2020/lib/menu/kvmenu.module.mjs +43 -43
  63. package/esm2020/lib/menu/menu.component.mjs +212 -212
  64. package/esm2020/lib/orgchart/orgchart.component.mjs +100 -100
  65. package/esm2020/lib/orgchart/orgchart.module.mjs +24 -24
  66. package/esm2020/lib/picklist/kvpicklist.module.mjs +32 -32
  67. package/esm2020/lib/picklist/picklist.component.mjs +48 -48
  68. package/esm2020/lib/pipes/codigofile.pipe.mjs +19 -19
  69. package/esm2020/lib/pipes/cpfcnpj.pipe.mjs +25 -25
  70. package/esm2020/lib/pipes/pipes.module.mjs +34 -34
  71. package/esm2020/lib/pipes/telefone.pipe.mjs +45 -45
  72. package/esm2020/lib/table/kvtable.module.mjs +32 -32
  73. package/esm2020/lib/table/table.component.mjs +476 -476
  74. package/esm2020/lib/tree-table/kv-treetable.component.mjs +290 -290
  75. package/esm2020/lib/tree-table/kv-treetable.module.mjs +32 -32
  76. package/esm2020/lib/tree-view/kvtree-view.module.mjs +28 -28
  77. package/esm2020/lib/tree-view/tree-view.component.mjs +29 -29
  78. package/esm2020/lib/workspace/kvworkspace.module.mjs +47 -47
  79. package/esm2020/lib/workspace/workspace.component.mjs +77 -77
  80. package/esm2020/public-api.mjs +124 -70
  81. package/fesm2015/keevo-components.mjs +3838 -3737
  82. package/fesm2015/keevo-components.mjs.map +1 -1
  83. package/fesm2020/keevo-components.mjs +3829 -3728
  84. package/fesm2020/keevo-components.mjs.map +1 -1
  85. package/index.d.ts +5 -5
  86. package/lib/api/base-components/base-component-button.d.ts +14 -14
  87. package/lib/api/base-components/base-component-chart.d.ts +40 -40
  88. package/lib/api/base-components/base-component-crud-form.d.ts +134 -134
  89. package/lib/api/base-components/base-component-crud-list.d.ts +63 -63
  90. package/lib/api/base-components/base-component-crud.d.ts +36 -36
  91. package/lib/api/base-components/base-component-dropdown.d.ts +42 -42
  92. package/lib/api/base-components/base-component-input.d.ts +31 -31
  93. package/lib/api/base-components/base-component-multi-select.d.ts +35 -35
  94. package/lib/api/base-components/base-component.d.ts +21 -21
  95. package/lib/api/components/chart/chart.config.d.ts +11 -11
  96. package/lib/api/components/chart/chart.model.d.ts +9 -9
  97. package/lib/api/components/chart/orchart.config.d.ts +35 -35
  98. package/lib/api/components/chart/orchart.item.d.ts +26 -26
  99. package/lib/api/components/dropdown/filtro.combo.d.ts +4 -4
  100. package/lib/api/components/error/error.component.d.ts +12 -12
  101. package/lib/api/components/error/kverror.module.d.ts +10 -10
  102. package/lib/api/components/table/action-item.d.ts +5 -5
  103. package/lib/api/components/table/kv-menuitem.d.ts +9 -9
  104. package/lib/api/components/table/table.config.column.d.ts +21 -21
  105. package/lib/api/components/table/table.config.d.ts +17 -17
  106. package/lib/api/components/table/table.paginate.d.ts +6 -6
  107. package/lib/api/helpers/component-providers.d.ts +2 -2
  108. package/lib/api/helpers/translate-primeng.d.ts +4 -4
  109. package/lib/api/models/menu/master.model.d.ts +6 -6
  110. package/lib/api/models/menu/menu.model.d.ts +10 -10
  111. package/lib/api/models/menu/menucompleto.model.d.ts +6 -6
  112. package/lib/api/models/menu/sistemamenu.model.d.ts +8 -8
  113. package/lib/api/modules/primeng.module.d.ts +60 -60
  114. package/lib/api/services/base.api.service.d.ts +25 -0
  115. package/lib/api/services/component.service.d.ts +11 -11
  116. package/lib/api/services/form.service.d.ts +27 -27
  117. package/lib/api/services/imagens.service.d.ts +8 -8
  118. package/lib/api/services/notification.service.d.ts +25 -25
  119. package/lib/api/services/object.service.d.ts +8 -8
  120. package/lib/buttons/button-personalize/button-personalize.component.d.ts +7 -7
  121. package/lib/buttons/button-popup/button-popup.component.d.ts +13 -0
  122. package/lib/buttons/button-secondary/button-secondary.component.d.ts +7 -7
  123. package/lib/buttons/button-success/button-success.component.d.ts +7 -7
  124. package/lib/buttons/kvbutton.module.d.ts +11 -10
  125. package/lib/chart/chart.component.d.ts +56 -56
  126. package/lib/chart/kvchart.module.d.ts +10 -10
  127. package/lib/directives/template.directive.d.ts +11 -11
  128. package/lib/inputs/check/check.component.d.ts +11 -11
  129. package/lib/inputs/dropdown/dropdown.component.d.ts +14 -14
  130. package/lib/inputs/input-calendar/input-calendar.component.d.ts +27 -27
  131. package/lib/inputs/input-mask/input-mask.component.d.ts +10 -10
  132. package/lib/inputs/input-number/input-number.component.d.ts +18 -18
  133. package/lib/inputs/input-password/input-password.component.d.ts +13 -13
  134. package/lib/inputs/input-text/input-text.component.d.ts +9 -9
  135. package/lib/inputs/input-text-checkbox/input-text-checkbox.component.d.ts +15 -15
  136. package/lib/inputs/input-textarea/input-textarea.component.d.ts +16 -16
  137. package/lib/inputs/input-time/input-time.component.d.ts +10 -10
  138. package/lib/inputs/kvinputs.module.d.ts +23 -23
  139. package/lib/inputs/multi-select/multi-select.component.d.ts +12 -12
  140. package/lib/inputs/radio-group/radio-group.component.d.ts +17 -17
  141. package/lib/inputs/switch/switch.component.d.ts +13 -13
  142. package/lib/keevo-components.module.d.ts +17 -17
  143. package/lib/login/kvlogin.module.d.ts +13 -13
  144. package/lib/login/login.component.d.ts +17 -17
  145. package/lib/menu/kvmenu.module.d.ts +12 -12
  146. package/lib/menu/menu.component.d.ts +67 -67
  147. package/lib/orgchart/orgchart.component.d.ts +27 -27
  148. package/lib/orgchart/orgchart.module.d.ts +9 -9
  149. package/lib/picklist/kvpicklist.module.d.ts +10 -10
  150. package/lib/picklist/picklist.component.d.ts +20 -20
  151. package/lib/pipes/codigofile.pipe.d.ts +7 -7
  152. package/lib/pipes/cpfcnpj.pipe.d.ts +7 -7
  153. package/lib/pipes/pipes.module.d.ts +10 -10
  154. package/lib/pipes/telefone.pipe.d.ts +7 -7
  155. package/lib/table/kvtable.module.d.ts +10 -10
  156. package/lib/table/table.component.d.ts +103 -103
  157. package/lib/tree-table/kv-treetable.component.d.ts +69 -69
  158. package/lib/tree-table/kv-treetable.module.d.ts +11 -11
  159. package/lib/tree-view/kvtree-view.module.d.ts +9 -9
  160. package/lib/tree-view/tree-view.component.d.ts +14 -14
  161. package/lib/workspace/kvworkspace.module.d.ts +13 -13
  162. package/lib/workspace/workspace.component.d.ts +28 -28
  163. package/package.json +1 -1
  164. package/public-api.d.ts +120 -66
@@ -1,278 +1,278 @@
1
- import { Component } from "@angular/core";
2
- import { FormGroup } from "@angular/forms";
3
- import { combineLatest, filter, finalize } from "rxjs";
4
- import { BaseComponentCrud } from "./base-component-crud";
5
- import { FormService } from "../services/form.service";
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "primeng/dynamicdialog";
8
- import * as i2 from "../services/notification.service";
9
- import * as i3 from "@angular/router";
10
- export class BaseComponentCrudForm extends BaseComponentCrud {
11
- constructor(dialogService, notificationService, activatedRoute, dynamicDialogRef, dynamicDialogConfig, router) {
12
- super(dialogService, notificationService);
13
- this.activatedRoute = activatedRoute;
14
- this.dynamicDialogRef = dynamicDialogRef;
15
- this.dynamicDialogConfig = dynamicDialogConfig;
16
- this.router = router;
17
- this.isAccordionExpanded = false;
18
- this.isNewRegistry = false;
19
- this.isSaveLoading = false;
20
- this.isView = false;
21
- this.formGroup = new FormGroup({});
22
- this.actions = [];
23
- this.popup = false;
24
- this.registry = null;
25
- this.onSetFormValues = false;
26
- }
27
- /**
28
- * Método disparado para tratamento das notificações do backend
29
- * @param err - Notificação
30
- */
31
- backendError(err) {
32
- if (err) {
33
- if (err.status == 404) {
34
- this.notificationService.toastError(err.error.item2[0].message);
35
- return;
36
- }
37
- else if (err.status == 400) {
38
- // Erros de validação de domínio do backend
39
- if (Array.isArray(err.error)) {
40
- if (err.error?.length) {
41
- if (err.error.length == 1 && err.error[0].key == '') {
42
- this.notificationService.toastError(err.error[0].message);
43
- return;
44
- }
45
- this.invalidForm(err.error);
46
- return;
47
- }
48
- }
49
- else if (err.error?.title) {
50
- // Erro de json no backend
51
- this.notificationService.toastError(err.error.title);
52
- return;
53
- }
54
- }
55
- else if (err.status == 415) {
56
- if (err.error?.title) {
57
- // Erro de json no backend
58
- this.notificationService.toastError(err.error.title);
59
- return;
60
- }
61
- }
62
- // Qualquer outro tipo de erro que tenha mensagem
63
- if (err.message) {
64
- this.notificationService.toastError(err.message);
65
- }
66
- }
67
- }
68
- /**
69
- * Método disparado ao clicar no botão de cancelamento
70
- */
71
- cancel() {
72
- this.notificationService.question({
73
- type: 'question',
74
- message: 'Deseja cancelar a operação?',
75
- accept: () => {
76
- this.navigateList();
77
- },
78
- });
79
- }
80
- /**
81
- * Verifica se houveram alterações nos componentes do formControl
82
- * @param controls - Nomes do controles no formGroup
83
- * @returns Observable
84
- */
85
- detectFormControlChanges(controls) {
86
- const controlList = [];
87
- controls.forEach(controlName => controlList.push(this.formGroup.controls[controlName].valueChanges));
88
- return combineLatest(controlList).pipe(filter(() => !this.onSetFormValues));
89
- }
90
- /**
91
- * Método responsável por desabilitar um componente
92
- * @param controlName - Nome do controle no formGroup
93
- */
94
- disableComponent(controlName) {
95
- FormService.disableControl(this.formGroup, controlName);
96
- }
97
- /**
98
- * Método responsável por limpar e desabilitar um componente
99
- * @param controlName - Nome do controle no formGroup
100
- * @param value - Valor default
101
- */
102
- disableAndClearComponent(controlName, value) {
103
- FormService.disableAndClearControl(this.formGroup, controlName, value);
104
- }
105
- /**
106
- * Método responsável por habilitar um componente
107
- * @param controlName - Nome do controle no formGroup
108
- */
109
- enableComponent(controName) {
110
- FormService.enableControl(this.formGroup, controName);
111
- }
112
- /**
113
- * Método que retorna o valor de um componente
114
- * @param controlName - Nome do controle no formGroup
115
- * @returns - Valor
116
- */
117
- getFormValue(controlName) {
118
- return FormService.getFormValue(this.formGroup, controlName);
119
- }
120
- /**
121
- * Verifica se o componente possui erro
122
- * @param controlName - Nome do controle no formGroup
123
- */
124
- hasControlError(controlName, errorCode) {
125
- return FormService.hasControlError(this.formGroup, controlName, errorCode);
126
- }
127
- /**
128
- * Seta inconsistências para o fomulário
129
- * @param notification - Lista de notificações
130
- */
131
- invalidForm(notification) {
132
- FormService.invalidForm(this.formGroup, notification);
133
- }
134
- /**
135
- * Método responsável pelo carregamento da tela
136
- * @param obs - Observable responsável pelo salvamento dos dados
137
- */
138
- loadData(obs, propertyDescripton) {
139
- obs
140
- //.pipe(loading())
141
- .subscribe((data) => {
142
- this.isNewRegistry = false;
143
- this.registry = data;
144
- this.setFormValues(this.registry);
145
- this.loadGrids();
146
- //this.dadosTela.tituloForm = this.tituloForm<T>(false, propertyDescripton);
147
- //this.setTitlePopup();
148
- });
149
- }
150
- loadGrids() { }
151
- /**
152
- * Método disparado para retornar a lista
153
- */
154
- navigateList(id = null) {
155
- if (this.popup) {
156
- this.dynamicDialogRef.close(id);
157
- }
158
- else if (this.dadosTela?.rotaListar) {
159
- this.router.navigate([this.dadosTela.rotaListar]);
160
- }
161
- }
162
- ngOnDestroy() {
163
- if (this.dynamicDialogRef) {
164
- this.dynamicDialogRef.close();
165
- }
166
- }
167
- ngOnInit() {
168
- this.configureForm();
169
- this.popup = this.dynamicDialogConfig?.data?.popup || false;
170
- this.activatedRoute.params.subscribe((params) => {
171
- if (params['id']) {
172
- this.loadForm(params['id']);
173
- }
174
- else if (this.dynamicDialogConfig?.data?.id) {
175
- this.loadForm(this.dynamicDialogConfig.data.id);
176
- }
177
- else {
178
- this.isNewRegistry = true;
179
- //this.dadosTela.tituloForm = this.tituloForm(true, '');
180
- //this.setTitlePopup();
181
- this.loadGrids();
182
- }
183
- });
184
- }
185
- /**
186
- * Método disparado para salvar dados
187
- * @param obs - Observable responsável pelo salvamento dos dados
188
- */
189
- saveData(obs) {
190
- obs
191
- .pipe((src) => {
192
- this.isSaveLoading = true;
193
- return src.pipe(finalize(() => {
194
- this.isSaveLoading = false;
195
- }));
196
- })
197
- .subscribe({
198
- next: (res) => {
199
- this.notificationService.toastSuccess(res.item2[0].message);
200
- this.navigateList(res.item1);
201
- },
202
- error: (e) => {
203
- this.backendError(e);
204
- },
205
- });
206
- }
207
- /**
208
- * Método se atualiza o valor de um componente do formGroup
209
- * @param controName - Nome do controle
210
- * @param value - Valor para atualização
211
- */
212
- setControlValue(controName, value) {
213
- FormService.setControlValue(this.formGroup, controName, value);
214
- }
215
- /**
216
- * Atualiza valores dos componentes do formGroup
217
- * @param values - Valores para atualização
218
- */
219
- setFormValues(values) {
220
- this.onSetFormValues = true;
221
- this.formGroup.patchValue(values, { emitEvent: false });
222
- this.onSetFormValues = false;
223
- }
224
- /**
225
- * Atualiza o validador de um componente do formGroup
226
- * @param controName - Nome do controle
227
- * @param validators - Regra de validação
228
- */
229
- setValidators(controName, validators) {
230
- FormService.setValidators(this.formGroup, controName, validators);
231
- }
232
- // private setTitlePopup() {
233
- // if (this.popup) {
234
- // if (this.dynamicDialogConfig)
235
- // this.dynamicDialogConfig.header = this.dadosTela.tituloForm;
236
- // }
237
- // }
238
- // protected tituloForm<T>(isNew: boolean, propertyDescripton: string): string {
239
- // if (isNew) {
240
- // return `${this.dadosTela.masculino ? 'Novo' : 'Nova'} ${this.dadosTela.nomeCadastro}`;
241
- // }
242
- // else if (this.isView) {
243
- // return `Visualização ${this.dadosTela.masculino ? 'do' : 'da'} ${this.dadosTela.nomeCadastro}: ${ObjectService.getProperty<T>(this.registry, propertyDescripton)}`;
244
- // } else {
245
- // return `Edição ${this.dadosTela.masculino ? 'do' : 'da'} ${this.dadosTela.nomeCadastro}: ${ObjectService.getProperty<T>(this.registry, propertyDescripton)}`;
246
- // }
247
- // }
248
- /**
249
- * Dispara os métodos de validações do formulário
250
- * @returns - True/False
251
- */
252
- validateForm() {
253
- let valid = false;
254
- if (this.formGroup && this.formGroup.valid) {
255
- valid = true;
256
- }
257
- else {
258
- this.isAccordionExpanded = true;
259
- this.invalidForm();
260
- if (this.dadosTela?.mensagemValidacao) {
261
- this.notificationService.dialog({
262
- type: 'alert',
263
- message: 'Verifique os campos obrigatórios.',
264
- });
265
- }
266
- }
267
- return valid;
268
- }
269
- }
270
- BaseComponentCrudForm.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: BaseComponentCrudForm, deps: [{ token: i1.DialogService }, { token: i2.NotificationService }, { token: i3.ActivatedRoute }, { token: i1.DynamicDialogRef }, { token: i1.DynamicDialogConfig }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
271
- BaseComponentCrudForm.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.8", type: BaseComponentCrudForm, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: BaseComponentCrudForm, decorators: [{
273
- type: Component,
274
- args: [{
275
- template: ''
276
- }]
277
- }], ctorParameters: function () { return [{ type: i1.DialogService }, { type: i2.NotificationService }, { type: i3.ActivatedRoute }, { type: i1.DynamicDialogRef }, { type: i1.DynamicDialogConfig }, { type: i3.Router }]; } });
278
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1jb21wb25lbnQtY3J1ZC1mb3JtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva2Vldm8tY29tcG9uZW50cy9zcmMvbGliL2FwaS9iYXNlLWNvbXBvbmVudHMvYmFzZS1jb21wb25lbnQtY3J1ZC1mb3JtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBRTdELE9BQU8sRUFBRSxTQUFTLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RCxPQUFPLEVBQWMsYUFBYSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHbkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7OztBQWN2RCxNQUFNLE9BQWdCLHFCQUFzQixTQUFRLGlCQUFpQjtJQWdCbkUsWUFDRSxhQUE0QixFQUM1QixtQkFBd0MsRUFDOUIsY0FBOEIsRUFDOUIsZ0JBQWtDLEVBQ2xDLG1CQUF3QyxFQUN4QyxNQUFjO1FBQ3hCLEtBQUssQ0FFRCxhQUFhLEVBQ2IsbUJBQW1CLENBQ3BCLENBQUM7UUFSTSxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFwQmhCLHdCQUFtQixHQUFHLEtBQUssQ0FBQztRQUM1QixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUN0QixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUN0QixXQUFNLEdBQUcsS0FBSyxDQUFDO1FBRWYsY0FBUyxHQUFjLElBQUksU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3pDLFlBQU8sR0FBaUIsRUFBRSxDQUFDO1FB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aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gXCJAYW5ndWxhci9yb3V0ZXJcIjtcclxuaW1wb3J0IHsgQ29tcG9uZW50LCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IERpYWxvZ1NlcnZpY2UsIER5bmFtaWNEaWFsb2dDb25maWcsIER5bmFtaWNEaWFsb2dSZWYgfSBmcm9tIFwicHJpbWVuZy9keW5hbWljZGlhbG9nXCI7XHJcbmltcG9ydCB7IEZvcm1Hcm91cCwgVmFsaWRhdG9yRm4gfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgY29tYmluZUxhdGVzdCwgZmlsdGVyLCBmaW5hbGl6ZSB9IGZyb20gXCJyeGpzXCI7XHJcblxyXG5pbXBvcnQgeyBBY3Rpb25JdGVtIH0gZnJvbSBcIi4uL2NvbXBvbmVudHMvdGFibGUvYWN0aW9uLWl0ZW1cIjtcclxuaW1wb3J0IHsgQmFzZUNvbXBvbmVudENydWQgfSBmcm9tIFwiLi9iYXNlLWNvbXBvbmVudC1jcnVkXCI7XHJcbmltcG9ydCB7IEZvcm1TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL2Zvcm0uc2VydmljZVwiO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL25vdGlmaWNhdGlvbi5zZXJ2aWNlXCI7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIERhZG9zVGVsYSB7XHJcbiAgbm9tZUNhZGFzdHJvOiBzdHJpbmc7XHJcbiAgdGl0dWxvRm9ybTogc3RyaW5nO1xyXG4gIHJvdGFMaXN0YXI6IHN0cmluZztcclxuICBtYXNjdWxpbm86IGJvb2xlYW47XHJcbiAgbWVuc2FnZW1WYWxpZGFjYW86IGJvb2xlYW5cclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgdGVtcGxhdGU6ICcnXHJcbn0pXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlQ29tcG9uZW50Q3J1ZEZvcm0gZXh0ZW5kcyBCYXNlQ29tcG9uZW50Q3J1ZCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgcHJvdGVjdGVkIGlzQWNjb3JkaW9uRXhwYW5kZWQgPSBmYWxzZTtcclxuICBwcm90ZWN0ZWQgaXNOZXdSZWdpc3RyeSA9IGZhbHNlO1xyXG4gIHByb3RlY3RlZCBpc1NhdmVMb2FkaW5nID0gZmFsc2U7XHJcbiAgcHJvdGVjdGVkIGlzVmlldyA9IGZhbHNlO1xyXG5cclxuICBwcm90ZWN0ZWQgZm9ybUdyb3VwOiBGb3JtR3JvdXAgPSBuZXcgRm9ybUdyb3VwKHt9KTtcclxuICBwcm90ZWN0ZWQgYWN0aW9uczogQWN0aW9uSXRlbVtdID0gW107XHJcblxyXG4gIHByb3RlY3RlZCBkYWRvc1RlbGE6IERhZG9zVGVsYSB8IHVuZGVmaW5lZDtcclxuICBwcm90ZWN0ZWQgcG9wdXA6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcm90ZWN0ZWQgcmVnaXN0cnk6IGFueSA9IG51bGw7XHJcblxyXG4gIHByaXZhdGUgb25TZXRGb3JtVmFsdWVzOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSxcclxuICAgIG5vdGlmaWNhdGlvblNlcnZpY2U6IE5vdGlmaWNhdGlvblNlcnZpY2UsXHJcbiAgICBwcm90ZWN0ZWQgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLFxyXG4gICAgcHJvdGVjdGVkIGR5bmFtaWNEaWFsb2dSZWY6IER5bmFtaWNEaWFsb2dSZWYsXHJcbiAgICBwcm90ZWN0ZWQgZHluYW1pY0RpYWxvZ0NvbmZpZzogRHluYW1pY0RpYWxvZ0NvbmZpZyxcclxuICAgIHByb3RlY3RlZCByb3V0ZXI6IFJvdXRlcikge1xyXG4gICAgc3VwZXJcclxuICAgICAgKFxyXG4gICAgICAgIGRpYWxvZ1NlcnZpY2UsXHJcbiAgICAgICAgbm90aWZpY2F0aW9uU2VydmljZVxyXG4gICAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTcOpdG9kbyBkaXNwYXJhZG8gcGFyYSBjb25maWd1cmHDp8OjbyBkbyBmb3JtXHJcbiAgICovXHJcbiAgYWJzdHJhY3QgY29uZmlndXJlRm9ybSgpOiB2b2lkO1xyXG5cclxuICAvKipcclxuICAgKiBNw6l0b2RvIGRpc3BhcmFkbyBwYXJhIG8gY2FycmVnYW1lbnRvIGRvIGZvcm1cclxuICAgKiBAcGFyYW0gaWRcclxuICAgKi9cclxuICBhYnN0cmFjdCBsb2FkRm9ybShpZDogYW55KTogdm9pZDtcclxuXHJcbiAgLyoqXHJcbiAgICogTcOpdG9kbyBkaXNwYXJhZG8gcGFyYSBzYWx2YW1lbnRvIGRvcyBkYWRvc1xyXG4gICAqL1xyXG4gIGFic3RyYWN0IHNhdmUoKTogdm9pZDtcclxuXHJcbiAgLyoqXHJcbiAgICogTcOpdG9kbyBkaXNwYXJhZG8gcGFyYSB0cmF0YW1lbnRvIGRhcyBub3RpZmljYcOnw7VlcyBkbyBiYWNrZW5kXHJcbiAgICogQHBhcmFtIGVyciAtIE5vdGlmaWNhw6fDo29cclxuICAgKi9cclxuICBwcm90ZWN0ZWQgYmFja2VuZEVycm9yKGVycjogYW55KTogdm9pZCB7XHJcbiAgICBpZiAoZXJyKSB7XHJcbiAgICAgIGlmIChlcnIuc3RhdHVzID09IDQwNCkge1xyXG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS50b2FzdEVycm9yKGVyci5lcnJvci5pdGVtMlswXS5tZXNzYWdlKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoZXJyLnN0YXR1cyA9PSA0MDApIHtcclxuICAgICAgICAvLyBFcnJvcyBkZSB2YWxpZGHDp8OjbyBkZSBkb23DrW5pbyBkbyBiYWNrZW5kXHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXJyLmVycm9yKSkge1xyXG4gICAgICAgICAgaWYgKGVyci5lcnJvcj8ubGVuZ3RoKSB7XHJcblxyXG4gICAgICAgICAgICBpZiAoZXJyLmVycm9yLmxlbmd0aCA9PSAxICYmIGVyci5lcnJvclswXS5rZXkgPT0gJycpIHtcclxuICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UudG9hc3RFcnJvcihlcnIuZXJyb3JbMF0ubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmludmFsaWRGb3JtKGVyci5lcnJvcik7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoZXJyLmVycm9yPy50aXRsZSkge1xyXG4gICAgICAgICAgLy8gRXJybyBkZSBqc29uIG5vIGJhY2tlbmRcclxuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS50b2FzdEVycm9yKGVyci5lcnJvci50aXRsZSk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGVyci5zdGF0dXMgPT0gNDE1KSB7XHJcbiAgICAgICAgaWYgKGVyci5lcnJvcj8udGl0bGUpIHtcclxuICAgICAgICAgIC8vIEVycm8gZGUganNvbiBubyBiYWNrZW5kXHJcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UudG9hc3RFcnJvcihlcnIuZXJyb3IudGl0bGUpO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gUXVhbHF1ZXIgb3V0cm8gdGlwbyBkZSBlcnJvIHF1ZSB0ZW5oYSBtZW5zYWdlbVxyXG4gICAgICBpZiAoZXJyLm1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UudG9hc3RFcnJvcihlcnIubWVzc2FnZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE3DqXRvZG8gZGlzcGFyYWRvIGFvIGNsaWNhciBubyBib3TDo28gZGUgY2FuY2VsYW1lbnRvXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIGNhbmNlbCgpIHtcclxuICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5xdWVzdGlvbih7XHJcbiAgICAgIHR5cGU6ICdxdWVzdGlvbicsXHJcbiAgICAgIG1lc3NhZ2U6ICdEZXNlamEgY2FuY2VsYXIgYSBvcGVyYcOnw6NvPycsXHJcbiAgICAgIGFjY2VwdDogKCkgPT4ge1xyXG4gICAgICAgIHRoaXMubmF2aWdhdGVMaXN0KCk7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFZlcmlmaWNhIHNlIGhvdXZlcmFtIGFsdGVyYcOnw7VlcyBub3MgY29tcG9uZW50ZXMgZG8gZm9ybUNvbnRyb2xcclxuICAgKiBAcGFyYW0gY29udHJvbHMgLSBOb21lcyBkbyBjb250cm9sZXMgbm8gZm9ybUdyb3VwXHJcbiAgICogQHJldHVybnMgT2JzZXJ2YWJsZVxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBkZXRlY3RGb3JtQ29udHJvbENoYW5nZXMoY29udHJvbHM6IEFycmF5PHN0cmluZz4pOiBPYnNlcnZhYmxlPGFueT4ge1xyXG4gICAgY29uc3QgY29udHJvbExpc3Q6IE9ic2VydmFibGU8YW55PltdID0gW107XHJcbiAgICBjb250cm9scy5mb3JFYWNoKGNvbnRyb2xOYW1lID0+IGNvbnRyb2xMaXN0LnB1c2godGhpcy5mb3JtR3JvdXAuY29udHJvbHNbY29udHJvbE5hbWVdLnZhbHVlQ2hhbmdlcykpO1xyXG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoY29udHJvbExpc3QpLnBpcGUoZmlsdGVyKCgpID0+ICF0aGlzLm9uU2V0Rm9ybVZhbHVlcykpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTcOpdG9kbyByZXNwb25zw6F2ZWwgcG9yIGRlc2FiaWxpdGFyIHVtIGNvbXBvbmVudGVcclxuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgLSBOb21lIGRvIGNvbnRyb2xlIG5vIGZvcm1Hcm91cFxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBkaXNhYmxlQ29tcG9uZW50KGNvbnRyb2xOYW1lOiBzdHJpbmcpIHtcclxuICAgIEZvcm1TZXJ2aWNlLmRpc2FibGVDb250cm9sKHRoaXMuZm9ybUdyb3VwLCBjb250cm9sTmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNw6l0b2RvIHJlc3BvbnPDoXZlbCBwb3IgbGltcGFyIGUgZGVzYWJpbGl0YXIgdW0gY29tcG9uZW50ZVxyXG4gICAqIEBwYXJhbSBjb250cm9sTmFtZSAtIE5vbWUgZG8gY29udHJvbGUgbm8gZm9ybUdyb3VwXHJcbiAgICogQHBhcmFtIHZhbHVlIC0gVmFsb3IgZGVmYXVsdFxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBkaXNhYmxlQW5kQ2xlYXJDb21wb25lbnQoY29udHJvbE5hbWU6IHN0cmluZywgdmFsdWU/OiBhbnkpIHtcclxuICAgIEZvcm1TZXJ2aWNlLmRpc2FibGVBbmRDbGVhckNvbnRyb2wodGhpcy5mb3JtR3JvdXAsIGNvbnRyb2xOYW1lLCB2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNw6l0b2RvIHJlc3BvbnPDoXZlbCBwb3IgaGFiaWxpdGFyIHVtIGNvbXBvbmVudGVcclxuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgLSBOb21lIGRvIGNvbnRyb2xlIG5vIGZvcm1Hcm91cFxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBlbmFibGVDb21wb25lbnQoY29udHJvTmFtZTogc3RyaW5nKSB7XHJcbiAgICBGb3JtU2VydmljZS5lbmFibGVDb250cm9sKHRoaXMuZm9ybUdyb3VwLCBjb250cm9OYW1lKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE3DqXRvZG8gcXVlIHJldG9ybmEgbyB2YWxvciBkZSB1bSBjb21wb25lbnRlXHJcbiAgICogQHBhcmFtIGNvbnRyb2xOYW1lIC0gTm9tZSBkbyBjb250cm9sZSBubyBmb3JtR3JvdXBcclxuICAgKiBAcmV0dXJucyAtIFZhbG9yXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIGdldEZvcm1WYWx1ZTxUPihjb250cm9sTmFtZTogc3RyaW5nKTogVCB7XHJcbiAgICByZXR1cm4gRm9ybVNlcnZpY2UuZ2V0Rm9ybVZhbHVlPFQ+KHRoaXMuZm9ybUdyb3VwLCBjb250cm9sTmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBWZXJpZmljYSBzZSBvIGNvbXBvbmVudGUgcG9zc3VpIGVycm9cclxuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgLSBOb21lIGRvIGNvbnRyb2xlIG5vIGZvcm1Hcm91cFxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBoYXNDb250cm9sRXJyb3IoY29udHJvbE5hbWU6IHN0cmluZywgZXJyb3JDb2RlPzogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gRm9ybVNlcnZpY2UuaGFzQ29udHJvbEVycm9yKHRoaXMuZm9ybUdyb3VwLCBjb250cm9sTmFtZSwgZXJyb3JDb2RlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldGEgaW5jb25zaXN0w6puY2lhcyBwYXJhIG8gZm9tdWzDoXJpb1xyXG4gICAqIEBwYXJhbSBub3RpZmljYXRpb24gLSBMaXN0YSBkZSBub3RpZmljYcOnw7Vlc1xyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBpbnZhbGlkRm9ybShub3RpZmljYXRpb24/OiBhbnkpIHtcclxuICAgIEZvcm1TZXJ2aWNlLmludmFsaWRGb3JtKHRoaXMuZm9ybUdyb3VwLCBub3RpZmljYXRpb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTcOpdG9kbyByZXNwb25zw6F2ZWwgcGVsbyBjYXJyZWdhbWVudG8gZGEgdGVsYVxyXG4gICAqIEBwYXJhbSBvYnMgLSBPYnNlcnZhYmxlIHJlc3BvbnPDoXZlbCBwZWxvIHNhbHZhbWVudG8gZG9zIGRhZG9zXHJcbiAgICovXHJcbiAgcHVibGljIGxvYWREYXRhPFQ+KG9iczogT2JzZXJ2YWJsZTxhbnk+LCBwcm9wZXJ0eURlc2NyaXB0b246IHN0cmluZykge1xyXG4gICAgb2JzXHJcbiAgICAgIC8vLnBpcGUobG9hZGluZygpKVxyXG4gICAgICAuc3Vic2NyaWJlKChkYXRhOiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLmlzTmV3UmVnaXN0cnkgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnJlZ2lzdHJ5ID0gZGF0YSBhcyBUO1xyXG4gICAgICAgIHRoaXMuc2V0Rm9ybVZhbHVlcyh0aGlzLnJlZ2lzdHJ5KTtcclxuICAgICAgICB0aGlzLmxvYWRHcmlkcygpO1xyXG4gICAgICAgIC8vdGhpcy5kYWRvc1RlbGEudGl0dWxvRm9ybSA9IHRoaXMudGl0dWxvRm9ybTxUPihmYWxzZSwgcHJvcGVydHlEZXNjcmlwdG9uKTtcclxuICAgICAgICAvL3RoaXMuc2V0VGl0bGVQb3B1cCgpO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBsb2FkR3JpZHMoKSB7IH1cclxuXHJcbiAgLyoqXHJcbiAgICogTcOpdG9kbyBkaXNwYXJhZG8gcGFyYSByZXRvcm5hciBhIGxpc3RhXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIG5hdmlnYXRlTGlzdChpZDogYW55ID0gbnVsbCkge1xyXG4gICAgaWYgKHRoaXMucG9wdXApIHtcclxuICAgICAgdGhpcy5keW5hbWljRGlhbG9nUmVmLmNsb3NlKGlkKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHRoaXMuZGFkb3NUZWxhPy5yb3RhTGlzdGFyKSB7XHJcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFt0aGlzLmRhZG9zVGVsYS5yb3RhTGlzdGFyXSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy5keW5hbWljRGlhbG9nUmVmKSB7XHJcbiAgICAgIHRoaXMuZHluYW1pY0RpYWxvZ1JlZi5jbG9zZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5jb25maWd1cmVGb3JtKCk7XHJcblxyXG4gICAgdGhpcy5wb3B1cCA9IHRoaXMuZHluYW1pY0RpYWxvZ0NvbmZpZz8uZGF0YT8ucG9wdXAgfHwgZmFsc2U7XHJcblxyXG4gICAgdGhpcy5hY3RpdmF0ZWRSb3V0ZS5wYXJhbXMuc3Vic2NyaWJlKChwYXJhbXM6IGFueSkgPT4ge1xyXG4gICAgICBpZiAocGFyYW1zWydpZCddKSB7XHJcbiAgICAgICAgdGhpcy5sb2FkRm9ybShwYXJhbXNbJ2lkJ10pO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKHRoaXMuZHluYW1pY0RpYWxvZ0NvbmZpZz8uZGF0YT8uaWQpIHtcclxuICAgICAgICB0aGlzLmxvYWRGb3JtKHRoaXMuZHluYW1pY0RpYWxvZ0NvbmZpZy5kYXRhLmlkKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLmlzTmV3UmVnaXN0cnkgPSB0cnVlO1xyXG4gICAgICAgIC8vdGhpcy5kYWRvc1RlbGEudGl0dWxvRm9ybSA9IHRoaXMudGl0dWxvRm9ybSh0cnVlLCAnJyk7XHJcbiAgICAgICAgLy90aGlzLnNldFRpdGxlUG9wdXAoKTtcclxuICAgICAgICB0aGlzLmxvYWRHcmlkcygpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE3DqXRvZG8gZGlzcGFyYWRvIHBhcmEgc2FsdmFyIGRhZG9zXHJcbiAgICogQHBhcmFtIG9icyAtIE9ic2VydmFibGUgcmVzcG9uc8OhdmVsIHBlbG8gc2FsdmFtZW50byBkb3MgZGFkb3NcclxuICAgKi9cclxuICBwcm90ZWN0ZWQgc2F2ZURhdGEob2JzOiBPYnNlcnZhYmxlPGFueT4pIHtcclxuICAgIG9ic1xyXG4gICAgICAucGlwZSgoc3JjOiBPYnNlcnZhYmxlPGFueT4pID0+IHtcclxuICAgICAgICB0aGlzLmlzU2F2ZUxvYWRpbmcgPSB0cnVlO1xyXG4gICAgICAgIHJldHVybiBzcmMucGlwZShmaW5hbGl6ZSgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmlzU2F2ZUxvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICB9KSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5zdWJzY3JpYmUoe1xyXG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLnRvYXN0U3VjY2VzcyhyZXMuaXRlbTJbMF0ubWVzc2FnZSk7XHJcbiAgICAgICAgICB0aGlzLm5hdmlnYXRlTGlzdChyZXMuaXRlbTEpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZXJyb3I6IChlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmJhY2tlbmRFcnJvcihlKTtcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE3DqXRvZG8gc2UgYXR1YWxpemEgbyB2YWxvciBkZSB1bSBjb21wb25lbnRlIGRvIGZvcm1Hcm91cFxyXG4gICAqIEBwYXJhbSBjb250cm9OYW1lIC0gTm9tZSBkbyBjb250cm9sZVxyXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFZhbG9yIHBhcmEgYXR1YWxpemHDp8Ojb1xyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBzZXRDb250cm9sVmFsdWUoY29udHJvTmFtZTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XHJcbiAgICBGb3JtU2VydmljZS5zZXRDb250cm9sVmFsdWUodGhpcy5mb3JtR3JvdXAsIGNvbnRyb05hbWUsIHZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEF0dWFsaXphIHZhbG9yZXMgZG9zIGNvbXBvbmVudGVzIGRvIGZvcm1Hcm91cFxyXG4gICAqIEBwYXJhbSB2YWx1ZXMgLSBWYWxvcmVzIHBhcmEgYXR1YWxpemHDp8Ojb1xyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBzZXRGb3JtVmFsdWVzKHZhbHVlczogYW55KSB7XHJcbiAgICB0aGlzLm9uU2V0Rm9ybVZhbHVlcyA9IHRydWU7XHJcbiAgICB0aGlzLmZvcm1Hcm91cC5wYXRjaFZhbHVlKHZhbHVlcywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgdGhpcy5vblNldEZvcm1WYWx1ZXMgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEF0dWFsaXphIG8gdmFsaWRhZG9yIGRlIHVtIGNvbXBvbmVudGUgZG8gZm9ybUdyb3VwXHJcbiAgICogQHBhcmFtIGNvbnRyb05hbWUgLSBOb21lIGRvIGNvbnRyb2xlXHJcbiAgICogQHBhcmFtIHZhbGlkYXRvcnMgLSBSZWdyYSBkZSB2YWxpZGHDp8Ojb1xyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBzZXRWYWxpZGF0b3JzKGNvbnRyb05hbWU6IHN0cmluZywgdmFsaWRhdG9yczogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdIHwgbnVsbCkge1xyXG4gICAgRm9ybVNlcnZpY2Uuc2V0VmFsaWRhdG9ycyh0aGlzLmZvcm1Hcm91cCwgY29udHJvTmFtZSwgdmFsaWRhdG9ycyk7XHJcbiAgfVxyXG5cclxuICAvLyBwcml2YXRlIHNldFRpdGxlUG9wdXAoKSB7XHJcbiAgLy8gICBpZiAodGhpcy5wb3B1cCkge1xyXG4gIC8vICAgICBpZiAodGhpcy5keW5hbWljRGlhbG9nQ29uZmlnKVxyXG4gIC8vICAgICAgIHRoaXMuZHluYW1pY0RpYWxvZ0NvbmZpZy5oZWFkZXIgPSB0aGlzLmRhZG9zVGVsYS50aXR1bG9Gb3JtO1xyXG4gIC8vICAgfVxyXG4gIC8vIH1cclxuXHJcbiAgLy8gcHJvdGVjdGVkIHRpdHVsb0Zvcm08VD4oaXNOZXc6IGJvb2xlYW4sIHByb3BlcnR5RGVzY3JpcHRvbjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAvLyAgIGlmIChpc05ldykge1xyXG4gIC8vICAgICByZXR1cm4gYCR7dGhpcy5kYWRvc1RlbGEubWFzY3VsaW5vID8gJ05vdm8nIDogJ05vdmEnfSAke3RoaXMuZGFkb3NUZWxhLm5vbWVDYWRhc3Ryb31gO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgZWxzZSBpZiAodGhpcy5pc1ZpZXcpIHtcclxuICAvLyAgICAgcmV0dXJuIGBWaXN1YWxpemHDp8OjbyAke3RoaXMuZGFkb3NUZWxhLm1hc2N1bGlubyA/ICdkbycgOiAnZGEnfSAke3RoaXMuZGFkb3NUZWxhLm5vbWVDYWRhc3Ryb306ICR7T2JqZWN0U2VydmljZS5nZXRQcm9wZXJ0eTxUPih0aGlzLnJlZ2lzdHJ5LCBwcm9wZXJ0eURlc2NyaXB0b24pfWA7XHJcbiAgLy8gICB9IGVsc2Uge1xyXG4gIC8vICAgICByZXR1cm4gYEVkacOnw6NvICR7dGhpcy5kYWRvc1RlbGEubWFzY3VsaW5vID8gJ2RvJyA6ICdkYSd9ICR7dGhpcy5kYWRvc1RlbGEubm9tZUNhZGFzdHJvfTogJHtPYmplY3RTZXJ2aWNlLmdldFByb3BlcnR5PFQ+KHRoaXMucmVnaXN0cnksIHByb3BlcnR5RGVzY3JpcHRvbil9YDtcclxuICAvLyAgIH1cclxuICAvLyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc3BhcmEgb3MgbcOpdG9kb3MgZGUgdmFsaWRhw6fDtWVzIGRvIGZvcm11bMOhcmlvXHJcbiAgICogQHJldHVybnMgLSBUcnVlL0ZhbHNlXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIHZhbGlkYXRlRm9ybSgpOiBib29sZWFuIHtcclxuICAgIGxldCB2YWxpZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIGlmICh0aGlzLmZvcm1Hcm91cCAmJiB0aGlzLmZvcm1Hcm91cC52YWxpZCkge1xyXG4gICAgICB2YWxpZCA9IHRydWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmlzQWNjb3JkaW9uRXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgICB0aGlzLmludmFsaWRGb3JtKCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5kYWRvc1RlbGE/Lm1lbnNhZ2VtVmFsaWRhY2FvKSB7XHJcbiAgICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLmRpYWxvZyh7XHJcbiAgICAgICAgICB0eXBlOiAnYWxlcnQnLFxyXG4gICAgICAgICAgbWVzc2FnZTogJ1ZlcmlmaXF1ZSBvcyBjYW1wb3Mgb2JyaWdhdMOzcmlvcy4nLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbGlkO1xyXG4gIH1cclxufVxyXG4iXX0=
1
+ import { Component } from "@angular/core";
2
+ import { FormGroup } from "@angular/forms";
3
+ import { combineLatest, filter, finalize } from "rxjs";
4
+ import { BaseComponentCrud } from "./base-component-crud";
5
+ import { FormService } from "../services/form.service";
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "primeng/dynamicdialog";
8
+ import * as i2 from "../services/notification.service";
9
+ import * as i3 from "@angular/router";
10
+ export class BaseComponentCrudForm extends BaseComponentCrud {
11
+ constructor(dialogService, notificationService, activatedRoute, dynamicDialogRef, dynamicDialogConfig, router) {
12
+ super(dialogService, notificationService);
13
+ this.activatedRoute = activatedRoute;
14
+ this.dynamicDialogRef = dynamicDialogRef;
15
+ this.dynamicDialogConfig = dynamicDialogConfig;
16
+ this.router = router;
17
+ this.isAccordionExpanded = false;
18
+ this.isNewRegistry = false;
19
+ this.isSaveLoading = false;
20
+ this.isView = false;
21
+ this.formGroup = new FormGroup({});
22
+ this.actions = [];
23
+ this.popup = false;
24
+ this.registry = null;
25
+ this.onSetFormValues = false;
26
+ }
27
+ /**
28
+ * Método disparado para tratamento das notificações do backend
29
+ * @param err - Notificação
30
+ */
31
+ backendError(err) {
32
+ if (err) {
33
+ if (err.status == 404) {
34
+ this.notificationService.toastError(err.error.item2[0].message);
35
+ return;
36
+ }
37
+ else if (err.status == 400) {
38
+ // Erros de validação de domínio do backend
39
+ if (Array.isArray(err.error)) {
40
+ if (err.error?.length) {
41
+ if (err.error.length == 1 && err.error[0].key == '') {
42
+ this.notificationService.toastError(err.error[0].message);
43
+ return;
44
+ }
45
+ this.invalidForm(err.error);
46
+ return;
47
+ }
48
+ }
49
+ else if (err.error?.title) {
50
+ // Erro de json no backend
51
+ this.notificationService.toastError(err.error.title);
52
+ return;
53
+ }
54
+ }
55
+ else if (err.status == 415) {
56
+ if (err.error?.title) {
57
+ // Erro de json no backend
58
+ this.notificationService.toastError(err.error.title);
59
+ return;
60
+ }
61
+ }
62
+ // Qualquer outro tipo de erro que tenha mensagem
63
+ if (err.message) {
64
+ this.notificationService.toastError(err.message);
65
+ }
66
+ }
67
+ }
68
+ /**
69
+ * Método disparado ao clicar no botão de cancelamento
70
+ */
71
+ cancel() {
72
+ this.notificationService.question({
73
+ type: 'question',
74
+ message: 'Deseja cancelar a operação?',
75
+ accept: () => {
76
+ this.navigateList();
77
+ },
78
+ });
79
+ }
80
+ /**
81
+ * Verifica se houveram alterações nos componentes do formControl
82
+ * @param controls - Nomes do controles no formGroup
83
+ * @returns Observable
84
+ */
85
+ detectFormControlChanges(controls) {
86
+ const controlList = [];
87
+ controls.forEach(controlName => controlList.push(this.formGroup.controls[controlName].valueChanges));
88
+ return combineLatest(controlList).pipe(filter(() => !this.onSetFormValues));
89
+ }
90
+ /**
91
+ * Método responsável por desabilitar um componente
92
+ * @param controlName - Nome do controle no formGroup
93
+ */
94
+ disableComponent(controlName) {
95
+ FormService.disableControl(this.formGroup, controlName);
96
+ }
97
+ /**
98
+ * Método responsável por limpar e desabilitar um componente
99
+ * @param controlName - Nome do controle no formGroup
100
+ * @param value - Valor default
101
+ */
102
+ disableAndClearComponent(controlName, value) {
103
+ FormService.disableAndClearControl(this.formGroup, controlName, value);
104
+ }
105
+ /**
106
+ * Método responsável por habilitar um componente
107
+ * @param controlName - Nome do controle no formGroup
108
+ */
109
+ enableComponent(controName) {
110
+ FormService.enableControl(this.formGroup, controName);
111
+ }
112
+ /**
113
+ * Método que retorna o valor de um componente
114
+ * @param controlName - Nome do controle no formGroup
115
+ * @returns - Valor
116
+ */
117
+ getFormValue(controlName) {
118
+ return FormService.getFormValue(this.formGroup, controlName);
119
+ }
120
+ /**
121
+ * Verifica se o componente possui erro
122
+ * @param controlName - Nome do controle no formGroup
123
+ */
124
+ hasControlError(controlName, errorCode) {
125
+ return FormService.hasControlError(this.formGroup, controlName, errorCode);
126
+ }
127
+ /**
128
+ * Seta inconsistências para o fomulário
129
+ * @param notification - Lista de notificações
130
+ */
131
+ invalidForm(notification) {
132
+ FormService.invalidForm(this.formGroup, notification);
133
+ }
134
+ /**
135
+ * Método responsável pelo carregamento da tela
136
+ * @param obs - Observable responsável pelo salvamento dos dados
137
+ */
138
+ loadData(obs, propertyDescripton) {
139
+ obs
140
+ //.pipe(loading())
141
+ .subscribe((data) => {
142
+ this.isNewRegistry = false;
143
+ this.registry = data;
144
+ this.setFormValues(this.registry);
145
+ this.loadGrids();
146
+ //this.dadosTela.tituloForm = this.tituloForm<T>(false, propertyDescripton);
147
+ //this.setTitlePopup();
148
+ });
149
+ }
150
+ loadGrids() { }
151
+ /**
152
+ * Método disparado para retornar a lista
153
+ */
154
+ navigateList(id = null) {
155
+ if (this.popup) {
156
+ this.dynamicDialogRef.close(id);
157
+ }
158
+ else if (this.dadosTela?.rotaListar) {
159
+ this.router.navigate([this.dadosTela.rotaListar]);
160
+ }
161
+ }
162
+ ngOnDestroy() {
163
+ if (this.dynamicDialogRef) {
164
+ this.dynamicDialogRef.close();
165
+ }
166
+ }
167
+ ngOnInit() {
168
+ this.configureForm();
169
+ this.popup = this.dynamicDialogConfig?.data?.popup || false;
170
+ this.activatedRoute.params.subscribe((params) => {
171
+ if (params['id']) {
172
+ this.loadForm(params['id']);
173
+ }
174
+ else if (this.dynamicDialogConfig?.data?.id) {
175
+ this.loadForm(this.dynamicDialogConfig.data.id);
176
+ }
177
+ else {
178
+ this.isNewRegistry = true;
179
+ //this.dadosTela.tituloForm = this.tituloForm(true, '');
180
+ //this.setTitlePopup();
181
+ this.loadGrids();
182
+ }
183
+ });
184
+ }
185
+ /**
186
+ * Método disparado para salvar dados
187
+ * @param obs - Observable responsável pelo salvamento dos dados
188
+ */
189
+ saveData(obs) {
190
+ obs
191
+ .pipe((src) => {
192
+ this.isSaveLoading = true;
193
+ return src.pipe(finalize(() => {
194
+ this.isSaveLoading = false;
195
+ }));
196
+ })
197
+ .subscribe({
198
+ next: (res) => {
199
+ this.notificationService.toastSuccess(res.item2[0].message);
200
+ this.navigateList(res.item1);
201
+ },
202
+ error: (e) => {
203
+ this.backendError(e);
204
+ },
205
+ });
206
+ }
207
+ /**
208
+ * Método se atualiza o valor de um componente do formGroup
209
+ * @param controName - Nome do controle
210
+ * @param value - Valor para atualização
211
+ */
212
+ setControlValue(controName, value) {
213
+ FormService.setControlValue(this.formGroup, controName, value);
214
+ }
215
+ /**
216
+ * Atualiza valores dos componentes do formGroup
217
+ * @param values - Valores para atualização
218
+ */
219
+ setFormValues(values) {
220
+ this.onSetFormValues = true;
221
+ this.formGroup.patchValue(values, { emitEvent: false });
222
+ this.onSetFormValues = false;
223
+ }
224
+ /**
225
+ * Atualiza o validador de um componente do formGroup
226
+ * @param controName - Nome do controle
227
+ * @param validators - Regra de validação
228
+ */
229
+ setValidators(controName, validators) {
230
+ FormService.setValidators(this.formGroup, controName, validators);
231
+ }
232
+ // private setTitlePopup() {
233
+ // if (this.popup) {
234
+ // if (this.dynamicDialogConfig)
235
+ // this.dynamicDialogConfig.header = this.dadosTela.tituloForm;
236
+ // }
237
+ // }
238
+ // protected tituloForm<T>(isNew: boolean, propertyDescripton: string): string {
239
+ // if (isNew) {
240
+ // return `${this.dadosTela.masculino ? 'Novo' : 'Nova'} ${this.dadosTela.nomeCadastro}`;
241
+ // }
242
+ // else if (this.isView) {
243
+ // return `Visualização ${this.dadosTela.masculino ? 'do' : 'da'} ${this.dadosTela.nomeCadastro}: ${ObjectService.getProperty<T>(this.registry, propertyDescripton)}`;
244
+ // } else {
245
+ // return `Edição ${this.dadosTela.masculino ? 'do' : 'da'} ${this.dadosTela.nomeCadastro}: ${ObjectService.getProperty<T>(this.registry, propertyDescripton)}`;
246
+ // }
247
+ // }
248
+ /**
249
+ * Dispara os métodos de validações do formulário
250
+ * @returns - True/False
251
+ */
252
+ validateForm() {
253
+ let valid = false;
254
+ if (this.formGroup && this.formGroup.valid) {
255
+ valid = true;
256
+ }
257
+ else {
258
+ this.isAccordionExpanded = true;
259
+ this.invalidForm();
260
+ if (this.dadosTela?.mensagemValidacao) {
261
+ this.notificationService.dialog({
262
+ type: 'alert',
263
+ message: 'Verifique os campos obrigatórios.',
264
+ });
265
+ }
266
+ }
267
+ return valid;
268
+ }
269
+ }
270
+ BaseComponentCrudForm.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: BaseComponentCrudForm, deps: [{ token: i1.DialogService }, { token: i2.NotificationService }, { token: i3.ActivatedRoute }, { token: i1.DynamicDialogRef }, { token: i1.DynamicDialogConfig }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
271
+ BaseComponentCrudForm.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.8", type: BaseComponentCrudForm, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: BaseComponentCrudForm, decorators: [{
273
+ type: Component,
274
+ args: [{
275
+ template: ''
276
+ }]
277
+ }], ctorParameters: function () { return [{ type: i1.DialogService }, { type: i2.NotificationService }, { type: i3.ActivatedRoute }, { type: i1.DynamicDialogRef }, { type: i1.DynamicDialogConfig }, { type: i3.Router }]; } });
278
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1jb21wb25lbnQtY3J1ZC1mb3JtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva2Vldm8tY29tcG9uZW50cy9zcmMvbGliL2FwaS9iYXNlLWNvbXBvbmVudHMvYmFzZS1jb21wb25lbnQtY3J1ZC1mb3JtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBRTdELE9BQU8sRUFBRSxTQUFTLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RCxPQUFPLEVBQWMsYUFBYSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHbkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7OztBQWN2RCxNQUFNLE9BQWdCLHFCQUFzQixTQUFRLGlCQUFpQjtJQWdCbkUsWUFDRSxhQUE0QixFQUM1QixtQkFBd0MsRUFDOUIsY0FBOEIsRUFDOUIsZ0JBQWtDLEVBQ2xDLG1CQUF3QyxFQUN4QyxNQUFjO1FBQ3hCLEtBQUssQ0FFRCxhQUFhLEVBQ2IsbUJBQW1CLENBQ3BCLENBQUM7UUFSTSxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFwQmhCLHdCQUFtQixHQUFHLEtBQUssQ0FBQztRQUM1QixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUN0QixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUN0QixXQUFNLEdBQUcsS0FBSyxDQUFDO1FBRWYsY0FBUyxHQUFjLElBQUksU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3pDLFlBQU8sR0FBaUIsRUFBRSxDQUFDO1FB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aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gXCJAYW5ndWxhci9yb3V0ZXJcIjtcbmltcG9ydCB7IENvbXBvbmVudCwgT25EZXN0cm95LCBPbkluaXQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgRGlhbG9nU2VydmljZSwgRHluYW1pY0RpYWxvZ0NvbmZpZywgRHluYW1pY0RpYWxvZ1JlZiB9IGZyb20gXCJwcmltZW5nL2R5bmFtaWNkaWFsb2dcIjtcbmltcG9ydCB7IEZvcm1Hcm91cCwgVmFsaWRhdG9yRm4gfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIGNvbWJpbmVMYXRlc3QsIGZpbHRlciwgZmluYWxpemUgfSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQgeyBBY3Rpb25JdGVtIH0gZnJvbSBcIi4uL2NvbXBvbmVudHMvdGFibGUvYWN0aW9uLWl0ZW1cIjtcbmltcG9ydCB7IEJhc2VDb21wb25lbnRDcnVkIH0gZnJvbSBcIi4vYmFzZS1jb21wb25lbnQtY3J1ZFwiO1xuaW1wb3J0IHsgRm9ybVNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZXMvZm9ybS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL25vdGlmaWNhdGlvbi5zZXJ2aWNlXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGFkb3NUZWxhIHtcbiAgbm9tZUNhZGFzdHJvOiBzdHJpbmc7XG4gIHRpdHVsb0Zvcm06IHN0cmluZztcbiAgcm90YUxpc3Rhcjogc3RyaW5nO1xuICBtYXNjdWxpbm86IGJvb2xlYW47XG4gIG1lbnNhZ2VtVmFsaWRhY2FvOiBib29sZWFuXG59XG5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZTogJydcbn0pXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUNvbXBvbmVudENydWRGb3JtIGV4dGVuZHMgQmFzZUNvbXBvbmVudENydWQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgcHJvdGVjdGVkIGlzQWNjb3JkaW9uRXhwYW5kZWQgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGlzTmV3UmVnaXN0cnkgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGlzU2F2ZUxvYWRpbmcgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGlzVmlldyA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBmb3JtR3JvdXA6IEZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICBwcm90ZWN0ZWQgYWN0aW9uczogQWN0aW9uSXRlbVtdID0gW107XG5cbiAgcHJvdGVjdGVkIGRhZG9zVGVsYTogRGFkb3NUZWxhIHwgdW5kZWZpbmVkO1xuICBwcm90ZWN0ZWQgcG9wdXA6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHJlZ2lzdHJ5OiBhbnkgPSBudWxsO1xuXG4gIHByaXZhdGUgb25TZXRGb3JtVmFsdWVzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSxcbiAgICBub3RpZmljYXRpb25TZXJ2aWNlOiBOb3RpZmljYXRpb25TZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJvdGVjdGVkIGR5bmFtaWNEaWFsb2dSZWY6IER5bmFtaWNEaWFsb2dSZWYsXG4gICAgcHJvdGVjdGVkIGR5bmFtaWNEaWFsb2dDb25maWc6IER5bmFtaWNEaWFsb2dDb25maWcsXG4gICAgcHJvdGVjdGVkIHJvdXRlcjogUm91dGVyKSB7XG4gICAgc3VwZXJcbiAgICAgIChcbiAgICAgICAgZGlhbG9nU2VydmljZSxcbiAgICAgICAgbm90aWZpY2F0aW9uU2VydmljZVxuICAgICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNw6l0b2RvIGRpc3BhcmFkbyBwYXJhIGNvbmZpZ3VyYcOnw6NvIGRvIGZvcm1cbiAgICovXG4gIGFic3RyYWN0IGNvbmZpZ3VyZUZvcm0oKTogdm9pZDtcblxuICAvKipcbiAgICogTcOpdG9kbyBkaXNwYXJhZG8gcGFyYSBvIGNhcnJlZ2FtZW50byBkbyBmb3JtXG4gICAqIEBwYXJhbSBpZFxuICAgKi9cbiAgYWJzdHJhY3QgbG9hZEZvcm0oaWQ6IGFueSk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIE3DqXRvZG8gZGlzcGFyYWRvIHBhcmEgc2FsdmFtZW50byBkb3MgZGFkb3NcbiAgICovXG4gIGFic3RyYWN0IHNhdmUoKTogdm9pZDtcblxuICAvKipcbiAgICogTcOpdG9kbyBkaXNwYXJhZG8gcGFyYSB0cmF0YW1lbnRvIGRhcyBub3RpZmljYcOnw7VlcyBkbyBiYWNrZW5kXG4gICAqIEBwYXJhbSBlcnIgLSBOb3RpZmljYcOnw6NvXG4gICAqL1xuICBwcm90ZWN0ZWQgYmFja2VuZEVycm9yKGVycjogYW55KTogdm9pZCB7XG4gICAgaWYgKGVycikge1xuICAgICAgaWYgKGVyci5zdGF0dXMgPT0gNDA0KSB7XG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS50b2FzdEVycm9yKGVyci5lcnJvci5pdGVtMlswXS5tZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoZXJyLnN0YXR1cyA9PSA0MDApIHtcbiAgICAgICAgLy8gRXJyb3MgZGUgdmFsaWRhw6fDo28gZGUgZG9tw61uaW8gZG8gYmFja2VuZFxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShlcnIuZXJyb3IpKSB7XG4gICAgICAgICAgaWYgKGVyci5lcnJvcj8ubGVuZ3RoKSB7XG5cbiAgICAgICAgICAgIGlmIChlcnIuZXJyb3IubGVuZ3RoID09IDEgJiYgZXJyLmVycm9yWzBdLmtleSA9PSAnJykge1xuICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UudG9hc3RFcnJvcihlcnIuZXJyb3JbMF0ubWVzc2FnZSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5pbnZhbGlkRm9ybShlcnIuZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChlcnIuZXJyb3I/LnRpdGxlKSB7XG4gICAgICAgICAgLy8gRXJybyBkZSBqc29uIG5vIGJhY2tlbmRcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UudG9hc3RFcnJvcihlcnIuZXJyb3IudGl0bGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSBpZiAoZXJyLnN0YXR1cyA9PSA0MTUpIHtcbiAgICAgICAgaWYgKGVyci5lcnJvcj8udGl0bGUpIHtcbiAgICAgICAgICAvLyBFcnJvIGRlIGpzb24gbm8gYmFja2VuZFxuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS50b2FzdEVycm9yKGVyci5lcnJvci50aXRsZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFF1YWxxdWVyIG91dHJvIHRpcG8gZGUgZXJybyBxdWUgdGVuaGEgbWVuc2FnZW1cbiAgICAgIGlmIChlcnIubWVzc2FnZSkge1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UudG9hc3RFcnJvcihlcnIubWVzc2FnZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE3DqXRvZG8gZGlzcGFyYWRvIGFvIGNsaWNhciBubyBib3TDo28gZGUgY2FuY2VsYW1lbnRvXG4gICAqL1xuICBwcm90ZWN0ZWQgY2FuY2VsKCkge1xuICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5xdWVzdGlvbih7XG4gICAgICB0eXBlOiAncXVlc3Rpb24nLFxuICAgICAgbWVzc2FnZTogJ0Rlc2VqYSBjYW5jZWxhciBhIG9wZXJhw6fDo28/JyxcbiAgICAgIGFjY2VwdDogKCkgPT4ge1xuICAgICAgICB0aGlzLm5hdmlnYXRlTGlzdCgpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmljYSBzZSBob3V2ZXJhbSBhbHRlcmHDp8O1ZXMgbm9zIGNvbXBvbmVudGVzIGRvIGZvcm1Db250cm9sXG4gICAqIEBwYXJhbSBjb250cm9scyAtIE5vbWVzIGRvIGNvbnRyb2xlcyBubyBmb3JtR3JvdXBcbiAgICogQHJldHVybnMgT2JzZXJ2YWJsZVxuICAgKi9cbiAgcHJvdGVjdGVkIGRldGVjdEZvcm1Db250cm9sQ2hhbmdlcyhjb250cm9sczogQXJyYXk8c3RyaW5nPik6IE9ic2VydmFibGU8YW55PiB7XG4gICAgY29uc3QgY29udHJvbExpc3Q6IE9ic2VydmFibGU8YW55PltdID0gW107XG4gICAgY29udHJvbHMuZm9yRWFjaChjb250cm9sTmFtZSA9PiBjb250cm9sTGlzdC5wdXNoKHRoaXMuZm9ybUdyb3VwLmNvbnRyb2xzW2NvbnRyb2xOYW1lXS52YWx1ZUNoYW5nZXMpKTtcbiAgICByZXR1cm4gY29tYmluZUxhdGVzdChjb250cm9sTGlzdCkucGlwZShmaWx0ZXIoKCkgPT4gIXRoaXMub25TZXRGb3JtVmFsdWVzKSk7XG4gIH1cblxuICAvKipcbiAgICogTcOpdG9kbyByZXNwb25zw6F2ZWwgcG9yIGRlc2FiaWxpdGFyIHVtIGNvbXBvbmVudGVcbiAgICogQHBhcmFtIGNvbnRyb2xOYW1lIC0gTm9tZSBkbyBjb250cm9sZSBubyBmb3JtR3JvdXBcbiAgICovXG4gIHByb3RlY3RlZCBkaXNhYmxlQ29tcG9uZW50KGNvbnRyb2xOYW1lOiBzdHJpbmcpIHtcbiAgICBGb3JtU2VydmljZS5kaXNhYmxlQ29udHJvbCh0aGlzLmZvcm1Hcm91cCwgY29udHJvbE5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIE3DqXRvZG8gcmVzcG9uc8OhdmVsIHBvciBsaW1wYXIgZSBkZXNhYmlsaXRhciB1bSBjb21wb25lbnRlXG4gICAqIEBwYXJhbSBjb250cm9sTmFtZSAtIE5vbWUgZG8gY29udHJvbGUgbm8gZm9ybUdyb3VwXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFZhbG9yIGRlZmF1bHRcbiAgICovXG4gIHByb3RlY3RlZCBkaXNhYmxlQW5kQ2xlYXJDb21wb25lbnQoY29udHJvbE5hbWU6IHN0cmluZywgdmFsdWU/OiBhbnkpIHtcbiAgICBGb3JtU2VydmljZS5kaXNhYmxlQW5kQ2xlYXJDb250cm9sKHRoaXMuZm9ybUdyb3VwLCBjb250cm9sTmFtZSwgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIE3DqXRvZG8gcmVzcG9uc8OhdmVsIHBvciBoYWJpbGl0YXIgdW0gY29tcG9uZW50ZVxuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgLSBOb21lIGRvIGNvbnRyb2xlIG5vIGZvcm1Hcm91cFxuICAgKi9cbiAgcHJvdGVjdGVkIGVuYWJsZUNvbXBvbmVudChjb250cm9OYW1lOiBzdHJpbmcpIHtcbiAgICBGb3JtU2VydmljZS5lbmFibGVDb250cm9sKHRoaXMuZm9ybUdyb3VwLCBjb250cm9OYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNw6l0b2RvIHF1ZSByZXRvcm5hIG8gdmFsb3IgZGUgdW0gY29tcG9uZW50ZVxuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgLSBOb21lIGRvIGNvbnRyb2xlIG5vIGZvcm1Hcm91cFxuICAgKiBAcmV0dXJucyAtIFZhbG9yXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Rm9ybVZhbHVlPFQ+KGNvbnRyb2xOYW1lOiBzdHJpbmcpOiBUIHtcbiAgICByZXR1cm4gRm9ybVNlcnZpY2UuZ2V0Rm9ybVZhbHVlPFQ+KHRoaXMuZm9ybUdyb3VwLCBjb250cm9sTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZpY2Egc2UgbyBjb21wb25lbnRlIHBvc3N1aSBlcnJvXG4gICAqIEBwYXJhbSBjb250cm9sTmFtZSAtIE5vbWUgZG8gY29udHJvbGUgbm8gZm9ybUdyb3VwXG4gICAqL1xuICBwcm90ZWN0ZWQgaGFzQ29udHJvbEVycm9yKGNvbnRyb2xOYW1lOiBzdHJpbmcsIGVycm9yQ29kZT86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBGb3JtU2VydmljZS5oYXNDb250cm9sRXJyb3IodGhpcy5mb3JtR3JvdXAsIGNvbnRyb2xOYW1lLCBlcnJvckNvZGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldGEgaW5jb25zaXN0w6puY2lhcyBwYXJhIG8gZm9tdWzDoXJpb1xuICAgKiBAcGFyYW0gbm90aWZpY2F0aW9uIC0gTGlzdGEgZGUgbm90aWZpY2HDp8O1ZXNcbiAgICovXG4gIHByb3RlY3RlZCBpbnZhbGlkRm9ybShub3RpZmljYXRpb24/OiBhbnkpIHtcbiAgICBGb3JtU2VydmljZS5pbnZhbGlkRm9ybSh0aGlzLmZvcm1Hcm91cCwgbm90aWZpY2F0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNw6l0b2RvIHJlc3BvbnPDoXZlbCBwZWxvIGNhcnJlZ2FtZW50byBkYSB0ZWxhXG4gICAqIEBwYXJhbSBvYnMgLSBPYnNlcnZhYmxlIHJlc3BvbnPDoXZlbCBwZWxvIHNhbHZhbWVudG8gZG9zIGRhZG9zXG4gICAqL1xuICBwdWJsaWMgbG9hZERhdGE8VD4ob2JzOiBPYnNlcnZhYmxlPGFueT4sIHByb3BlcnR5RGVzY3JpcHRvbjogc3RyaW5nKSB7XG4gICAgb2JzXG4gICAgICAvLy5waXBlKGxvYWRpbmcoKSlcbiAgICAgIC5zdWJzY3JpYmUoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmlzTmV3UmVnaXN0cnkgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZWdpc3RyeSA9IGRhdGEgYXMgVDtcbiAgICAgICAgdGhpcy5zZXRGb3JtVmFsdWVzKHRoaXMucmVnaXN0cnkpO1xuICAgICAgICB0aGlzLmxvYWRHcmlkcygpO1xuICAgICAgICAvL3RoaXMuZGFkb3NUZWxhLnRpdHVsb0Zvcm0gPSB0aGlzLnRpdHVsb0Zvcm08VD4oZmFsc2UsIHByb3BlcnR5RGVzY3JpcHRvbik7XG4gICAgICAgIC8vdGhpcy5zZXRUaXRsZVBvcHVwKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkR3JpZHMoKSB7IH1cblxuICAvKipcbiAgICogTcOpdG9kbyBkaXNwYXJhZG8gcGFyYSByZXRvcm5hciBhIGxpc3RhXG4gICAqL1xuICBwcm90ZWN0ZWQgbmF2aWdhdGVMaXN0KGlkOiBhbnkgPSBudWxsKSB7XG4gICAgaWYgKHRoaXMucG9wdXApIHtcbiAgICAgIHRoaXMuZHluYW1pY0RpYWxvZ1JlZi5jbG9zZShpZCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuZGFkb3NUZWxhPy5yb3RhTGlzdGFyKSB7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbdGhpcy5kYWRvc1RlbGEucm90YUxpc3Rhcl0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5keW5hbWljRGlhbG9nUmVmKSB7XG4gICAgICB0aGlzLmR5bmFtaWNEaWFsb2dSZWYuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5jb25maWd1cmVGb3JtKCk7XG5cbiAgICB0aGlzLnBvcHVwID0gdGhpcy5keW5hbWljRGlhbG9nQ29uZmlnPy5kYXRhPy5wb3B1cCB8fCBmYWxzZTtcblxuICAgIHRoaXMuYWN0aXZhdGVkUm91dGUucGFyYW1zLnN1YnNjcmliZSgocGFyYW1zOiBhbnkpID0+IHtcbiAgICAgIGlmIChwYXJhbXNbJ2lkJ10pIHtcbiAgICAgICAgdGhpcy5sb2FkRm9ybShwYXJhbXNbJ2lkJ10pO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAodGhpcy5keW5hbWljRGlhbG9nQ29uZmlnPy5kYXRhPy5pZCkge1xuICAgICAgICB0aGlzLmxvYWRGb3JtKHRoaXMuZHluYW1pY0RpYWxvZ0NvbmZpZy5kYXRhLmlkKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLmlzTmV3UmVnaXN0cnkgPSB0cnVlO1xuICAgICAgICAvL3RoaXMuZGFkb3NUZWxhLnRpdHVsb0Zvcm0gPSB0aGlzLnRpdHVsb0Zvcm0odHJ1ZSwgJycpO1xuICAgICAgICAvL3RoaXMuc2V0VGl0bGVQb3B1cCgpO1xuICAgICAgICB0aGlzLmxvYWRHcmlkcygpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE3DqXRvZG8gZGlzcGFyYWRvIHBhcmEgc2FsdmFyIGRhZG9zXG4gICAqIEBwYXJhbSBvYnMgLSBPYnNlcnZhYmxlIHJlc3BvbnPDoXZlbCBwZWxvIHNhbHZhbWVudG8gZG9zIGRhZG9zXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURhdGEob2JzOiBPYnNlcnZhYmxlPGFueT4pIHtcbiAgICBvYnNcbiAgICAgIC5waXBlKChzcmM6IE9ic2VydmFibGU8YW55PikgPT4ge1xuICAgICAgICB0aGlzLmlzU2F2ZUxvYWRpbmcgPSB0cnVlO1xuICAgICAgICByZXR1cm4gc3JjLnBpcGUoZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuaXNTYXZlTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB9KSk7XG4gICAgICB9KVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS50b2FzdFN1Y2Nlc3MocmVzLml0ZW0yWzBdLm1lc3NhZ2UpO1xuICAgICAgICAgIHRoaXMubmF2aWdhdGVMaXN0KHJlcy5pdGVtMSk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZSkgPT4ge1xuICAgICAgICAgIHRoaXMuYmFja2VuZEVycm9yKGUpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTcOpdG9kbyBzZSBhdHVhbGl6YSBvIHZhbG9yIGRlIHVtIGNvbXBvbmVudGUgZG8gZm9ybUdyb3VwXG4gICAqIEBwYXJhbSBjb250cm9OYW1lIC0gTm9tZSBkbyBjb250cm9sZVxuICAgKiBAcGFyYW0gdmFsdWUgLSBWYWxvciBwYXJhIGF0dWFsaXphw6fDo29cbiAgICovXG4gIHByb3RlY3RlZCBzZXRDb250cm9sVmFsdWUoY29udHJvTmFtZTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgRm9ybVNlcnZpY2Uuc2V0Q29udHJvbFZhbHVlKHRoaXMuZm9ybUdyb3VwLCBjb250cm9OYW1lLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQXR1YWxpemEgdmFsb3JlcyBkb3MgY29tcG9uZW50ZXMgZG8gZm9ybUdyb3VwXG4gICAqIEBwYXJhbSB2YWx1ZXMgLSBWYWxvcmVzIHBhcmEgYXR1YWxpemHDp8Ojb1xuICAgKi9cbiAgcHJvdGVjdGVkIHNldEZvcm1WYWx1ZXModmFsdWVzOiBhbnkpIHtcbiAgICB0aGlzLm9uU2V0Rm9ybVZhbHVlcyA9IHRydWU7XG4gICAgdGhpcy5mb3JtR3JvdXAucGF0Y2hWYWx1ZSh2YWx1ZXMsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB0aGlzLm9uU2V0Rm9ybVZhbHVlcyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dWFsaXphIG8gdmFsaWRhZG9yIGRlIHVtIGNvbXBvbmVudGUgZG8gZm9ybUdyb3VwXG4gICAqIEBwYXJhbSBjb250cm9OYW1lIC0gTm9tZSBkbyBjb250cm9sZVxuICAgKiBAcGFyYW0gdmFsaWRhdG9ycyAtIFJlZ3JhIGRlIHZhbGlkYcOnw6NvXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0VmFsaWRhdG9ycyhjb250cm9OYW1lOiBzdHJpbmcsIHZhbGlkYXRvcnM6IFZhbGlkYXRvckZuIHwgVmFsaWRhdG9yRm5bXSB8IG51bGwpIHtcbiAgICBGb3JtU2VydmljZS5zZXRWYWxpZGF0b3JzKHRoaXMuZm9ybUdyb3VwLCBjb250cm9OYW1lLCB2YWxpZGF0b3JzKTtcbiAgfVxuXG4gIC8vIHByaXZhdGUgc2V0VGl0bGVQb3B1cCgpIHtcbiAgLy8gICBpZiAodGhpcy5wb3B1cCkge1xuICAvLyAgICAgaWYgKHRoaXMuZHluYW1pY0RpYWxvZ0NvbmZpZylcbiAgLy8gICAgICAgdGhpcy5keW5hbWljRGlhbG9nQ29uZmlnLmhlYWRlciA9IHRoaXMuZGFkb3NUZWxhLnRpdHVsb0Zvcm07XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgLy8gcHJvdGVjdGVkIHRpdHVsb0Zvcm08VD4oaXNOZXc6IGJvb2xlYW4sIHByb3BlcnR5RGVzY3JpcHRvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gICBpZiAoaXNOZXcpIHtcbiAgLy8gICAgIHJldHVybiBgJHt0aGlzLmRhZG9zVGVsYS5tYXNjdWxpbm8gPyAnTm92bycgOiAnTm92YSd9ICR7dGhpcy5kYWRvc1RlbGEubm9tZUNhZGFzdHJvfWA7XG4gIC8vICAgfVxuICAvLyAgIGVsc2UgaWYgKHRoaXMuaXNWaWV3KSB7XG4gIC8vICAgICByZXR1cm4gYFZpc3VhbGl6YcOnw6NvICR7dGhpcy5kYWRvc1RlbGEubWFzY3VsaW5vID8gJ2RvJyA6ICdkYSd9ICR7dGhpcy5kYWRvc1RlbGEubm9tZUNhZGFzdHJvfTogJHtPYmplY3RTZXJ2aWNlLmdldFByb3BlcnR5PFQ+KHRoaXMucmVnaXN0cnksIHByb3BlcnR5RGVzY3JpcHRvbil9YDtcbiAgLy8gICB9IGVsc2Uge1xuICAvLyAgICAgcmV0dXJuIGBFZGnDp8OjbyAke3RoaXMuZGFkb3NUZWxhLm1hc2N1bGlubyA/ICdkbycgOiAnZGEnfSAke3RoaXMuZGFkb3NUZWxhLm5vbWVDYWRhc3Ryb306ICR7T2JqZWN0U2VydmljZS5nZXRQcm9wZXJ0eTxUPih0aGlzLnJlZ2lzdHJ5LCBwcm9wZXJ0eURlc2NyaXB0b24pfWA7XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgLyoqXG4gICAqIERpc3BhcmEgb3MgbcOpdG9kb3MgZGUgdmFsaWRhw6fDtWVzIGRvIGZvcm11bMOhcmlvXG4gICAqIEByZXR1cm5zIC0gVHJ1ZS9GYWxzZVxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlRm9ybSgpOiBib29sZWFuIHtcbiAgICBsZXQgdmFsaWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLmZvcm1Hcm91cCAmJiB0aGlzLmZvcm1Hcm91cC52YWxpZCkge1xuICAgICAgdmFsaWQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzQWNjb3JkaW9uRXhwYW5kZWQgPSB0cnVlO1xuICAgICAgdGhpcy5pbnZhbGlkRm9ybSgpO1xuXG4gICAgICBpZiAodGhpcy5kYWRvc1RlbGE/Lm1lbnNhZ2VtVmFsaWRhY2FvKSB7XG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5kaWFsb2coe1xuICAgICAgICAgIHR5cGU6ICdhbGVydCcsXG4gICAgICAgICAgbWVzc2FnZTogJ1ZlcmlmaXF1ZSBvcyBjYW1wb3Mgb2JyaWdhdMOzcmlvcy4nLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWQ7XG4gIH1cbn1cbiJdfQ==