ngx-material-entity 18.2.5 → 20.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/fesm2022/ngx-material-entity.mjs +165 -155
  2. package/fesm2022/ngx-material-entity.mjs.map +1 -1
  3. package/index.d.ts +4501 -3
  4. package/package.json +10 -12
  5. package/classes/base.builder.d.ts +0 -37
  6. package/classes/entity.model.d.ts +0 -27
  7. package/components/confirm-dialog/confirm-dialog-data.builder.d.ts +0 -24
  8. package/components/confirm-dialog/confirm-dialog-data.d.ts +0 -48
  9. package/components/confirm-dialog/confirm-dialog.component.d.ts +0 -36
  10. package/components/create-page/create-data.route.d.ts +0 -16
  11. package/components/create-page/create-page.component.d.ts +0 -141
  12. package/components/create-page/page-create-data.builder.d.ts +0 -18
  13. package/components/custom-table/custom-table-configuration.model.d.ts +0 -65
  14. package/components/custom-table/custom-table.component.d.ts +0 -111
  15. package/components/edit-page/edit-data.route.d.ts +0 -16
  16. package/components/edit-page/edit-page.component.d.ts +0 -167
  17. package/components/edit-page/page-edit-data.builder.d.ts +0 -18
  18. package/components/form/form.component.d.ts +0 -64
  19. package/components/input/array/array-date-input/array-date-input.component.d.ts +0 -17
  20. package/components/input/array/array-date-range-input/array-date-range-input.component.d.ts +0 -25
  21. package/components/input/array/array-date-time-input/array-date-time-input.component.d.ts +0 -26
  22. package/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.d.ts +0 -30
  23. package/components/input/array/array-string-chips-input/array-string-chips-input.component.d.ts +0 -36
  24. package/components/input/array/array-table.class.d.ts +0 -56
  25. package/components/input/base-input.component.d.ts +0 -64
  26. package/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.d.ts +0 -10
  27. package/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.d.ts +0 -13
  28. package/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.d.ts +0 -10
  29. package/components/input/custom/custom.component.d.ts +0 -13
  30. package/components/input/date/date-input/date-input.component.d.ts +0 -11
  31. package/components/input/date/date-range-input/date-range-input.component.d.ts +0 -22
  32. package/components/input/date/date-time-input/date-time-input.component.d.ts +0 -32
  33. package/components/input/file/file-default-input/file-default-input.component.d.ts +0 -11
  34. package/components/input/file/file-image-input/file-image-input.component.d.ts +0 -28
  35. package/components/input/file/file-input/file-input.component.d.ts +0 -45
  36. package/components/input/input.component.d.ts +0 -590
  37. package/components/input/number/number-dropdown-input/number-dropdown-input.component.d.ts +0 -24
  38. package/components/input/number/number-input/number-input.component.d.ts +0 -9
  39. package/components/input/number/number-slider-input/number-slider-input.component.d.ts +0 -10
  40. package/components/input/relations/references-many-input/references-many-input.component.d.ts +0 -43
  41. package/components/input/string/string-autocomplete-input/string-autocomplete-input.component.d.ts +0 -19
  42. package/components/input/string/string-dropdown-input/string-dropdown-input.component.d.ts +0 -24
  43. package/components/input/string/string-input/string-input.component.d.ts +0 -9
  44. package/components/input/string/string-password-input/string-password-input.component.d.ts +0 -31
  45. package/components/input/string/string-textbox-input/string-textbox-input.component.d.ts +0 -9
  46. package/components/table/create-dialog/create-data.builder.d.ts +0 -25
  47. package/components/table/create-dialog/create-entity-data.builder.d.ts +0 -21
  48. package/components/table/create-dialog/create-entity-data.d.ts +0 -19
  49. package/components/table/create-dialog/create-entity-dialog.component.d.ts +0 -77
  50. package/components/table/default.actions.d.ts +0 -25
  51. package/components/table/display-column-value/base-display-column-value.component.d.ts +0 -15
  52. package/components/table/display-column-value/display-column-value.component.d.ts +0 -26
  53. package/components/table/edit-dialog/edit-data.builder.d.ts +0 -44
  54. package/components/table/edit-dialog/edit-entity-data.d.ts +0 -27
  55. package/components/table/edit-dialog/edit-entity-dialog.component.d.ts +0 -118
  56. package/components/table/edit-dialog/edit-entity.builder.d.ts +0 -23
  57. package/components/table/table-data.builder.d.ts +0 -102
  58. package/components/table/table-data.d.ts +0 -340
  59. package/components/table/table.component.d.ts +0 -119
  60. package/components/tooltip/tooltip.component.d.ts +0 -14
  61. package/decorators/array/array-decorator-internal.data.d.ts +0 -129
  62. package/decorators/array/array-decorator.data.d.ts +0 -252
  63. package/decorators/array/array.decorator.d.ts +0 -9
  64. package/decorators/base/base-property.decorator.d.ts +0 -9
  65. package/decorators/base/decorator-types.enum.d.ts +0 -48
  66. package/decorators/base/dropdown-value.interface.d.ts +0 -14
  67. package/decorators/base/property-decorator-internal.data.d.ts +0 -41
  68. package/decorators/base/property-decorator.data.d.ts +0 -88
  69. package/decorators/boolean/boolean-decorator-internal.data.d.ts +0 -26
  70. package/decorators/boolean/boolean-decorator.data.d.ts +0 -39
  71. package/decorators/boolean/boolean.decorator.d.ts +0 -7
  72. package/decorators/custom/custom-decorator-internal.data.d.ts +0 -17
  73. package/decorators/custom/custom-decorator.data.d.ts +0 -35
  74. package/decorators/custom/custom.decorator.d.ts +0 -9
  75. package/decorators/date/date-decorator-internal.data.d.ts +0 -45
  76. package/decorators/date/date-decorator.data.d.ts +0 -126
  77. package/decorators/date/date.decorator.d.ts +0 -7
  78. package/decorators/file/file-decorator-internal.data.d.ts +0 -93
  79. package/decorators/file/file-decorator.data.d.ts +0 -88
  80. package/decorators/file/file.decorator.d.ts +0 -8
  81. package/decorators/has-many/has-many-decorator-internal.data.d.ts +0 -16
  82. package/decorators/has-many/has-many-decorator.data.d.ts +0 -34
  83. package/decorators/has-many/has-many.decorator.d.ts +0 -8
  84. package/decorators/number/number-decorator-internal.data.d.ts +0 -38
  85. package/decorators/number/number-decorator.data.d.ts +0 -63
  86. package/decorators/number/number.decorator.d.ts +0 -7
  87. package/decorators/object/object-decorator-internal.data.d.ts +0 -23
  88. package/decorators/object/object-decorator.data.d.ts +0 -42
  89. package/decorators/object/object.decorator.d.ts +0 -8
  90. package/decorators/references-many/references-many-decorator-internal.data.d.ts +0 -30
  91. package/decorators/references-many/references-many-decorator.data.d.ts +0 -63
  92. package/decorators/references-many/references-many.decorator.d.ts +0 -8
  93. package/decorators/references-one/references-one-decorator-internal.data.d.ts +0 -16
  94. package/decorators/references-one/references-one-decorator.data.d.ts +0 -32
  95. package/decorators/references-one/references-one.decorator.d.ts +0 -8
  96. package/decorators/string/string-decorator-internal.data.d.ts +0 -56
  97. package/decorators/string/string-decorator.data.d.ts +0 -116
  98. package/decorators/string/string.decorator.d.ts +0 -7
  99. package/default-global-configuration-values.d.ts +0 -13
  100. package/directives/drag-drop.directive.d.ts +0 -29
  101. package/directives/dynamic-style-class.directive.d.ts +0 -24
  102. package/directives/included-in.directive.d.ts +0 -14
  103. package/directives/number.directive.d.ts +0 -16
  104. package/directives/password-match.directive.d.ts +0 -14
  105. package/directives/tooltip.directive.d.ts +0 -42
  106. package/encapsulation/js-2-xml.utilities.d.ts +0 -14
  107. package/encapsulation/jszip.utilities.d.ts +0 -12
  108. package/encapsulation/lodash.utilities.d.ts +0 -60
  109. package/encapsulation/reflect.utilities.d.ts +0 -59
  110. package/encapsulation/uuid.utilities.d.ts +0 -10
  111. package/esm2022/classes/base.builder.mjs +0 -47
  112. package/esm2022/classes/entity.model.mjs +0 -26
  113. package/esm2022/components/confirm-dialog/confirm-dialog-data.builder.mjs +0 -57
  114. package/esm2022/components/confirm-dialog/confirm-dialog-data.mjs +0 -2
  115. package/esm2022/components/confirm-dialog/confirm-dialog.component.mjs +0 -71
  116. package/esm2022/components/create-page/create-data.route.mjs +0 -12
  117. package/esm2022/components/create-page/create-page.component.mjs +0 -276
  118. package/esm2022/components/create-page/page-create-data.builder.mjs +0 -30
  119. package/esm2022/components/custom-table/custom-table-configuration.model.mjs +0 -37
  120. package/esm2022/components/custom-table/custom-table.component.mjs +0 -213
  121. package/esm2022/components/edit-page/edit-data.route.mjs +0 -12
  122. package/esm2022/components/edit-page/edit-page.component.mjs +0 -362
  123. package/esm2022/components/edit-page/page-edit-data.builder.mjs +0 -33
  124. package/esm2022/components/form/form.component.mjs +0 -106
  125. package/esm2022/components/input/array/array-date-input/array-date-input.component.mjs +0 -56
  126. package/esm2022/components/input/array/array-date-range-input/array-date-range-input.component.mjs +0 -82
  127. package/esm2022/components/input/array/array-date-time-input/array-date-time-input.component.mjs +0 -82
  128. package/esm2022/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +0 -81
  129. package/esm2022/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +0 -74
  130. package/esm2022/components/input/array/array-table.class.mjs +0 -107
  131. package/esm2022/components/input/base-input.component.mjs +0 -102
  132. package/esm2022/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +0 -29
  133. package/esm2022/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +0 -40
  134. package/esm2022/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +0 -29
  135. package/esm2022/components/input/custom/custom.component.mjs +0 -28
  136. package/esm2022/components/input/date/date-input/date-input.component.mjs +0 -28
  137. package/esm2022/components/input/date/date-range-input/date-range-input.component.mjs +0 -84
  138. package/esm2022/components/input/date/date-time-input/date-time-input.component.mjs +0 -90
  139. package/esm2022/components/input/file/file-default-input/file-default-input.component.mjs +0 -18
  140. package/esm2022/components/input/file/file-image-input/file-image-input.component.mjs +0 -104
  141. package/esm2022/components/input/file/file-input/file-input.component.mjs +0 -228
  142. package/esm2022/components/input/input.component.mjs +0 -1361
  143. package/esm2022/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +0 -65
  144. package/esm2022/components/input/number/number-input/number-input.component.mjs +0 -23
  145. package/esm2022/components/input/number/number-slider-input/number-slider-input.component.mjs +0 -27
  146. package/esm2022/components/input/relations/references-many-input/references-many-input.component.mjs +0 -145
  147. package/esm2022/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +0 -56
  148. package/esm2022/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +0 -65
  149. package/esm2022/components/input/string/string-input/string-input.component.mjs +0 -23
  150. package/esm2022/components/input/string/string-password-input/string-password-input.component.mjs +0 -107
  151. package/esm2022/components/input/string/string-textbox-input/string-textbox-input.component.mjs +0 -24
  152. package/esm2022/components/table/create-dialog/create-data.builder.mjs +0 -56
  153. package/esm2022/components/table/create-dialog/create-entity-data.builder.mjs +0 -32
  154. package/esm2022/components/table/create-dialog/create-entity-data.mjs +0 -2
  155. package/esm2022/components/table/create-dialog/create-entity-dialog.component.mjs +0 -180
  156. package/esm2022/components/table/default.actions.mjs +0 -83
  157. package/esm2022/components/table/display-column-value/base-display-column-value.component.mjs +0 -27
  158. package/esm2022/components/table/display-column-value/display-column-value.component.mjs +0 -41
  159. package/esm2022/components/table/edit-dialog/edit-data.builder.mjs +0 -136
  160. package/esm2022/components/table/edit-dialog/edit-entity-data.mjs +0 -2
  161. package/esm2022/components/table/edit-dialog/edit-entity-dialog.component.mjs +0 -295
  162. package/esm2022/components/table/edit-dialog/edit-entity.builder.mjs +0 -39
  163. package/esm2022/components/table/table-data.builder.mjs +0 -304
  164. package/esm2022/components/table/table-data.mjs +0 -2
  165. package/esm2022/components/table/table.component.mjs +0 -324
  166. package/esm2022/components/tooltip/tooltip.component.mjs +0 -26
  167. package/esm2022/decorators/array/array-decorator-internal.data.mjs +0 -310
  168. package/esm2022/decorators/array/array-decorator.data.mjs +0 -51
  169. package/esm2022/decorators/array/array.decorator.mjs +0 -37
  170. package/esm2022/decorators/base/base-property.decorator.mjs +0 -17
  171. package/esm2022/decorators/base/decorator-types.enum.mjs +0 -35
  172. package/esm2022/decorators/base/dropdown-value.interface.mjs +0 -2
  173. package/esm2022/decorators/base/property-decorator-internal.data.mjs +0 -101
  174. package/esm2022/decorators/base/property-decorator.data.mjs +0 -59
  175. package/esm2022/decorators/boolean/boolean-decorator-internal.data.mjs +0 -45
  176. package/esm2022/decorators/boolean/boolean-decorator.data.mjs +0 -11
  177. package/esm2022/decorators/boolean/boolean.decorator.mjs +0 -21
  178. package/esm2022/decorators/custom/custom-decorator-internal.data.mjs +0 -34
  179. package/esm2022/decorators/custom/custom-decorator.data.mjs +0 -2
  180. package/esm2022/decorators/custom/custom.decorator.mjs +0 -13
  181. package/esm2022/decorators/date/date-decorator-internal.data.mjs +0 -92
  182. package/esm2022/decorators/date/date-decorator.data.mjs +0 -11
  183. package/esm2022/decorators/date/date.decorator.mjs +0 -22
  184. package/esm2022/decorators/file/file-decorator-internal.data.mjs +0 -143
  185. package/esm2022/decorators/file/file-decorator.data.mjs +0 -59
  186. package/esm2022/decorators/file/file.decorator.mjs +0 -25
  187. package/esm2022/decorators/has-many/has-many-decorator-internal.data.mjs +0 -41
  188. package/esm2022/decorators/has-many/has-many-decorator.data.mjs +0 -2
  189. package/esm2022/decorators/has-many/has-many.decorator.mjs +0 -13
  190. package/esm2022/decorators/number/number-decorator-internal.data.mjs +0 -68
  191. package/esm2022/decorators/number/number-decorator.data.mjs +0 -11
  192. package/esm2022/decorators/number/number.decorator.mjs +0 -22
  193. package/esm2022/decorators/object/object-decorator-internal.data.mjs +0 -42
  194. package/esm2022/decorators/object/object-decorator.data.mjs +0 -22
  195. package/esm2022/decorators/object/object.decorator.mjs +0 -20
  196. package/esm2022/decorators/references-many/references-many-decorator-internal.data.mjs +0 -55
  197. package/esm2022/decorators/references-many/references-many-decorator.data.mjs +0 -2
  198. package/esm2022/decorators/references-many/references-many.decorator.mjs +0 -13
  199. package/esm2022/decorators/references-one/references-one-decorator-internal.data.mjs +0 -34
  200. package/esm2022/decorators/references-one/references-one-decorator.data.mjs +0 -2
  201. package/esm2022/decorators/references-one/references-one.decorator.mjs +0 -12
  202. package/esm2022/decorators/string/string-decorator-internal.data.mjs +0 -119
  203. package/esm2022/decorators/string/string-decorator.data.mjs +0 -11
  204. package/esm2022/decorators/string/string.decorator.mjs +0 -29
  205. package/esm2022/default-global-configuration-values.mjs +0 -91
  206. package/esm2022/directives/drag-drop.directive.mjs +0 -60
  207. package/esm2022/directives/dynamic-style-class.directive.mjs +0 -51
  208. package/esm2022/directives/included-in.directive.mjs +0 -33
  209. package/esm2022/directives/number.directive.mjs +0 -37
  210. package/esm2022/directives/password-match.directive.mjs +0 -30
  211. package/esm2022/directives/tooltip.directive.mjs +0 -142
  212. package/esm2022/encapsulation/js-2-xml.utilities.mjs +0 -17
  213. package/esm2022/encapsulation/jszip.utilities.mjs +0 -16
  214. package/esm2022/encapsulation/lodash.utilities.mjs +0 -80
  215. package/esm2022/encapsulation/reflect.utilities.mjs +0 -79
  216. package/esm2022/encapsulation/uuid.utilities.mjs +0 -14
  217. package/esm2022/functions/default-false.function.mjs +0 -9
  218. package/esm2022/functions/default-style-classes.function.mjs +0 -7
  219. package/esm2022/functions/default-true.function.mjs +0 -9
  220. package/esm2022/functions/dropdown-values-to-function.function.mjs +0 -15
  221. package/esm2022/functions/get-changes-tooltip-content.function.mjs +0 -23
  222. package/esm2022/functions/get-config-value.function.mjs +0 -14
  223. package/esm2022/functions/get-validation-error-message.function.mjs +0 -54
  224. package/esm2022/functions/get-validation-errors-tooltip-content.function.mjs +0 -23
  225. package/esm2022/functions/is-async-function.function.mjs +0 -9
  226. package/esm2022/functions/table-column-value-to-sort-value.function.mjs +0 -33
  227. package/esm2022/global-configuration-values.mjs +0 -27
  228. package/esm2022/mocks/placeholder-data.png.mjs +0 -3
  229. package/esm2022/ngx-material-entity.mjs +0 -5
  230. package/esm2022/public-api.mjs +0 -68
  231. package/esm2022/services/entity.service.mjs +0 -269
  232. package/esm2022/services/unsaved-changes.guard.mjs +0 -13
  233. package/esm2022/utilities/date.utilities.mjs +0 -138
  234. package/esm2022/utilities/entity.utilities.mjs +0 -611
  235. package/esm2022/utilities/file.utilities.mjs +0 -172
  236. package/esm2022/utilities/selection.utilities.mjs +0 -49
  237. package/esm2022/utilities/validation.utilities.mjs +0 -543
  238. package/functions/default-false.function.d.ts +0 -6
  239. package/functions/default-style-classes.function.d.ts +0 -6
  240. package/functions/default-true.function.d.ts +0 -6
  241. package/functions/dropdown-values-to-function.function.d.ts +0 -11
  242. package/functions/get-changes-tooltip-content.function.d.ts +0 -13
  243. package/functions/get-config-value.function.d.ts +0 -7
  244. package/functions/get-validation-error-message.function.d.ts +0 -5
  245. package/functions/get-validation-errors-tooltip-content.function.d.ts +0 -12
  246. package/functions/is-async-function.function.d.ts +0 -6
  247. package/functions/table-column-value-to-sort-value.function.d.ts +0 -9
  248. package/global-configuration-values.d.ts +0 -205
  249. package/mocks/placeholder-data.png.d.ts +0 -1
  250. package/public-api.d.ts +0 -60
  251. package/services/entity.service.d.ts +0 -146
  252. package/services/unsaved-changes.guard.d.ts +0 -23
  253. package/utilities/date.utilities.d.ts +0 -92
  254. package/utilities/entity.utilities.d.ts +0 -236
  255. package/utilities/file.utilities.d.ts +0 -67
  256. package/utilities/selection.utilities.d.ts +0 -28
  257. package/utilities/validation.utilities.d.ts +0 -58
@@ -1,1361 +0,0 @@
1
- import { SelectionModel } from '@angular/cdk/collections';
2
- import { CommonModule } from '@angular/common';
3
- import { HttpClient } from '@angular/common/http';
4
- import { Component, EnvironmentInjector, EventEmitter, Inject, Input, Output, TemplateRef, ViewChild, inject, runInInjectionContext } from '@angular/core';
5
- import { FormsModule } from '@angular/forms';
6
- import { MatBadgeModule } from '@angular/material/badge';
7
- import { MatButtonModule } from '@angular/material/button';
8
- import { MatCheckboxModule } from '@angular/material/checkbox';
9
- import { MatDialog, MatDialogModule } from '@angular/material/dialog';
10
- import { MatFormFieldModule } from '@angular/material/form-field';
11
- import { MatInputModule } from '@angular/material/input';
12
- import { MatMenuModule } from '@angular/material/menu';
13
- import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
14
- import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
15
- import { MatSelectModule } from '@angular/material/select';
16
- import { MatSort, MatSortModule } from '@angular/material/sort';
17
- import { MatTableDataSource, MatTableModule } from '@angular/material/table';
18
- import { MatTabsModule } from '@angular/material/tabs';
19
- import { Router } from '@angular/router';
20
- import { FaIconComponent } from '@fortawesome/angular-fontawesome';
21
- import { faSearch } from '@fortawesome/free-solid-svg-icons';
22
- import { firstValueFrom } from 'rxjs';
23
- import { ArrayDateInputComponent } from './array/array-date-input/array-date-input.component';
24
- import { ArrayDateRangeInputComponent } from './array/array-date-range-input/array-date-range-input.component';
25
- import { ArrayDateTimeInputComponent } from './array/array-date-time-input/array-date-time-input.component';
26
- import { ArrayStringAutocompleteChipsComponent } from './array/array-string-autocomplete-chips/array-string-autocomplete-chips.component';
27
- import { ArrayStringChipsInputComponent } from './array/array-string-chips-input/array-string-chips-input.component';
28
- import { BooleanCheckboxInputComponent } from './boolean/boolean-checkbox-input/boolean-checkbox-input.component';
29
- import { BooleanDropdownInputComponent } from './boolean/boolean-dropdown-input/boolean-dropdown-input.component';
30
- import { BooleanToggleInputComponent } from './boolean/boolean-toggle-input/boolean-toggle-input.component';
31
- import { CustomInputComponent } from './custom/custom.component';
32
- import { DateInputComponent } from './date/date-input/date-input.component';
33
- import { DateRangeInputComponent } from './date/date-range-input/date-range-input.component';
34
- import { DateTimeInputComponent } from './date/date-time-input/date-time-input.component';
35
- import { FileDefaultInputComponent } from './file/file-default-input/file-default-input.component';
36
- import { FileImageInputComponent } from './file/file-image-input/file-image-input.component';
37
- import { NumberDropdownInputComponent } from './number/number-dropdown-input/number-dropdown-input.component';
38
- import { NumberInputComponent } from './number/number-input/number-input.component';
39
- import { NumberSliderInputComponent } from './number/number-slider-input/number-slider-input.component';
40
- import { ReferencesManyInputComponent } from './relations/references-many-input/references-many-input.component';
41
- import { StringAutocompleteInputComponent } from './string/string-autocomplete-input/string-autocomplete-input.component';
42
- import { StringDropdownInputComponent } from './string/string-dropdown-input/string-dropdown-input.component';
43
- import { StringInputComponent } from './string/string-input/string-input.component';
44
- import { StringPasswordInputComponent } from './string/string-password-input/string-password-input.component';
45
- import { StringTextboxInputComponent } from './string/string-textbox-input/string-textbox-input.component';
46
- import { EntityArrayDecoratorConfigInternal } from '../../decorators/array/array-decorator-internal.data';
47
- import { DecoratorTypes } from '../../decorators/base/decorator-types.enum';
48
- import { HasManyDecoratorConfigInternal } from '../../decorators/has-many/has-many-decorator-internal.data';
49
- import { DynamicStyleClassDirective } from '../../directives/dynamic-style-class.directive';
50
- import { LodashUtilities } from '../../encapsulation/lodash.utilities';
51
- import { ReflectUtilities } from '../../encapsulation/reflect.utilities';
52
- import { UUIDUtilities } from '../../encapsulation/uuid.utilities';
53
- import { defaultFalse } from '../../functions/default-false.function';
54
- import { getChangesTooltipContent } from '../../functions/get-changes-tooltip-content.function';
55
- import { NGX_GET_VALIDATION_ERROR_MESSAGE } from '../../functions/get-validation-error-message.function';
56
- import { getValidationErrorsTooltipContent } from '../../functions/get-validation-errors-tooltip-content.function';
57
- import { tableColumnValueToSortValue } from '../../functions/table-column-value-to-sort-value.function';
58
- import { NGX_COMPLETE_GLOBAL_DEFAULT_VALUES } from '../../global-configuration-values';
59
- import { DateUtilities } from '../../utilities/date.utilities';
60
- import { EntityUtilities } from '../../utilities/entity.utilities';
61
- import { SelectionUtilities } from '../../utilities/selection.utilities';
62
- import { ValidationUtilities } from '../../utilities/validation.utilities';
63
- import { ConfirmDialogDataBuilder } from '../confirm-dialog/confirm-dialog-data.builder';
64
- import { NgxMatEntityConfirmDialogComponent } from '../confirm-dialog/confirm-dialog.component';
65
- import { InternalCustomTableConfiguration } from '../custom-table/custom-table-configuration.model';
66
- import { CreateDataBuilder } from '../table/create-dialog/create-data.builder';
67
- import { DisplayColumnValueComponent } from '../table/display-column-value/display-column-value.component';
68
- import { BaseTableActionInternal } from '../table/table-data.builder';
69
- import { TooltipComponent } from '../tooltip/tooltip.component';
70
- import * as i0 from "@angular/core";
71
- import * as i1 from "@angular/material/dialog";
72
- import * as i2 from "@angular/router";
73
- import * as i3 from "@angular/common/http";
74
- import * as i4 from "@angular/common";
75
- import * as i5 from "@angular/material/tabs";
76
- import * as i6 from "@angular/material/form-field";
77
- import * as i7 from "@angular/material/select";
78
- import * as i8 from "@angular/material/core";
79
- import * as i9 from "@angular/forms";
80
- import * as i10 from "@angular/material/badge";
81
- import * as i11 from "@angular/material/input";
82
- import * as i12 from "@angular/material/menu";
83
- import * as i13 from "@angular/material/paginator";
84
- import * as i14 from "@angular/material/progress-spinner";
85
- import * as i15 from "@angular/material/table";
86
- import * as i16 from "@angular/material/checkbox";
87
- import * as i17 from "@angular/material/button";
88
- import * as i18 from "@angular/material/sort";
89
- /**
90
- * The default input component. It gets the metadata of the property from the given @Input "entity" and @Input "propertyKey"
91
- * and displays the input field accordingly.
92
- *
93
- * You can also define a method that generates error-messages and if the input should be hidden when its metadata says
94
- * that it should be omitted for creating or updating.
95
- * The last part being mostly relevant if you want to use this component inside an ngFor.
96
- */
97
- export class NgxMatEntityInputComponent {
98
- dialog;
99
- injector;
100
- router;
101
- defaultGetValidationErrorMessage;
102
- globalConfig;
103
- http;
104
- // eslint-disable-next-line jsdoc/require-jsdoc
105
- faSearch = faSearch;
106
- /**
107
- * The entity on which the property exists. Used in conjunction with the "propertyKey"
108
- * to determine the property for which the input should be generated.
109
- */
110
- entity;
111
- /**
112
- * The name of the property to generate the input for. Used in conjunction with the "entity".
113
- */
114
- propertyKey;
115
- /**
116
- * (optional) A custom function to generate the error-message for invalid inputs.
117
- */
118
- getValidationErrorMessage;
119
- // eslint-disable-next-line jsdoc/require-jsdoc
120
- internalGetValidationErrorMessage;
121
- /**
122
- * Whether to hide a value if it is omitted for creation.
123
- * Is used internally for the object property.
124
- * @default false
125
- */
126
- hideOmitForCreate;
127
- /**
128
- * Whether to hide a value if it is omitted for editing.
129
- * Is used internally for the object property.
130
- * @default false
131
- */
132
- hideOmitForEdit;
133
- /**
134
- * Whether or not an empty value should be valid.
135
- * Is used internally for the object property.
136
- * @default undefined
137
- */
138
- validEmpty; // TODO
139
- /**
140
- * Whether or not the input should be readonly.
141
- * In that case it is disabled, but most of the default styling is overwritten.
142
- * @default false
143
- */
144
- isReadOnly;
145
- // eslint-disable-next-line jsdoc/require-jsdoc
146
- internalIsReadOnly;
147
- /**
148
- * Emits when the input value has been changed.
149
- */
150
- inputChangeEvent = new EventEmitter();
151
- /**
152
- * A setter for the has many and array sort.
153
- * Is needed because the sort is inside a switch case,
154
- * which means that at ngOnInit it can't be initialized.
155
- */
156
- set sort(sort) {
157
- if (this.hasManyTableContext != undefined) {
158
- this.hasManyTableContext.$implicit.dataSource.sort = this.hasManyTableContext.$implicit.dataSource.sort ?? sort;
159
- }
160
- if (this.entityArrayTableContext != undefined) {
161
- this.entityArrayTableContext.$implicit.dataSource.sort = this.entityArrayTableContext.$implicit.dataSource.sort ?? sort;
162
- }
163
- }
164
- /**
165
- * A setter for the has many and array paginator.
166
- * Is needed because the paginator is inside a switch case,
167
- * which means that at ngOnInit it can't be initialized.
168
- */
169
- set paginator(paginator) {
170
- if (this.hasManyTableContext != undefined) {
171
- this.hasManyTableContext.$implicit.dataSource.paginator = this.hasManyTableContext.$implicit.dataSource.paginator ?? paginator;
172
- }
173
- if (this.entityArrayTableContext != undefined) {
174
- // eslint-disable-next-line stylistic/max-len
175
- this.entityArrayTableContext.$implicit.dataSource.paginator = this.entityArrayTableContext.$implicit.dataSource.paginator ?? paginator;
176
- }
177
- }
178
- /**
179
- * The type of the decorator for this input.
180
- */
181
- type;
182
- /**
183
- * The property metadata received from the decorator.
184
- */
185
- metadata;
186
- /**
187
- * The metadata of an object property.
188
- */
189
- metadataDefaultObject;
190
- /**
191
- * The form context for an object property.
192
- */
193
- objectFormContext;
194
- /**
195
- * The metadata of an dropdown object property.
196
- */
197
- metadataDropdownObject;
198
- /**
199
- * All possible dropdown values for the object property.
200
- */
201
- objectDropdownValues = [];
202
- /**
203
- * A unique input name for the references one property.
204
- */
205
- objectDropdownName;
206
- /**
207
- * All currently shown dropdown values for the object property.
208
- */
209
- filteredObjectDropdownValues = [];
210
- // eslint-disable-next-line jsdoc/require-returns
211
- /**
212
- * The currently selected object as a drop down value.
213
- */
214
- get currentObjectDropdownValue() {
215
- const value = LodashUtilities.cloneDeep(this.objectDropdownValues ?? []);
216
- return value.find(v => LodashUtilities.isEqual(v.value, this.entity[this.propertyKey]));
217
- }
218
- // eslint-disable-next-line jsdoc/require-returns
219
- /**
220
- * Whether or not the current object dropdown value should be shown in the dropdown.
221
- */
222
- get shouldDisplayCurrentObjectDropdownValue() {
223
- return !!this.currentObjectDropdownValue
224
- && !this.filteredObjectDropdownValues.find(v => LodashUtilities.isEqual(v.value, this.currentObjectDropdownValue?.value));
225
- }
226
- /**
227
- * A compareWith method for the select.
228
- * Uses bind.
229
- */
230
- compareObjectsBound = this.compareObjects.bind(this);
231
- addArrayItemDialog;
232
- addArrayItemDialogRef;
233
- editArrayItemDialog;
234
- editArrayItemDialogRef;
235
- /**
236
- * The metadata of an entity array property.
237
- */
238
- metadataEntityArray;
239
- /**
240
- * The table context for the entity array input.
241
- */
242
- entityArrayTableContext;
243
- /**
244
- * The current array item to be added or updated.
245
- */
246
- arrayItem;
247
- /**
248
- * The array item before any changes have been made. Used to check if the form is dirty.
249
- */
250
- arrayItemPriorChanges;
251
- /**
252
- * The form context for adding an array item.
253
- */
254
- addArrayItemFormContext;
255
- // eslint-disable-next-line jsdoc/require-jsdoc
256
- addArrayItemFormContext2;
257
- /**
258
- * The form context for editing an array item.
259
- */
260
- editArrayItemFormContext;
261
- /**
262
- * Whether or not the array item is valid.
263
- */
264
- isArrayItemValid = false;
265
- /**
266
- * Whether or not the array item is dirty.
267
- */
268
- isArrayItemDirty = false;
269
- /**
270
- * The index of the array item that is being edited.
271
- */
272
- indexOfEditedArrayItem;
273
- /**
274
- * Config for the dialog that adds a new array item.
275
- */
276
- addArrayItemDialogData;
277
- /**
278
- * The tabs to display inside the edit array item dialog.
279
- */
280
- editArrayItemDialogData;
281
- /**
282
- * All validation errors for the array item.
283
- */
284
- arrayItemValidationErrors = [];
285
- /**
286
- * All the changes that have been done to the array item.
287
- */
288
- arrayItemChanges = [];
289
- /**
290
- * What to display inside the array item tooltip.
291
- */
292
- arrayItemTooltipContent = '';
293
- /**
294
- * Metadata of a has many property.
295
- */
296
- metadataHasMany;
297
- /**
298
- * The table context for the has many input.
299
- */
300
- hasManyTableContext;
301
- /**
302
- * The has many import action.
303
- */
304
- hasManyImportAction;
305
- hasManyEntityService;
306
- createHasManyDialog;
307
- createHasManyDialogRef;
308
- editHasManyDialog;
309
- editHasManyDialogRef;
310
- /**
311
- * A single has many entity.
312
- */
313
- hasManyEntity;
314
- /**
315
- * The single has many entity before any changes have been made. Is used to determine if the form is dirty.
316
- */
317
- hasManyEntityPriorChanges;
318
- /**
319
- * Whether or not the has many entity is valid.
320
- */
321
- isHasManyEntityValid = false;
322
- /**
323
- * All validation errors of the has many entity.
324
- */
325
- hasManyValidationErrors = [];
326
- /**
327
- * All the changes that have been done to the has many entity.
328
- */
329
- hasManyChanges = [];
330
- /**
331
- * What to display inside the has many tooltip.
332
- */
333
- hasManyTooltipContent = '';
334
- /**
335
- * Whether or not the has many entity is dirty.
336
- */
337
- isHasManyEntityDirty = false;
338
- /**
339
- * Whether or not the current user is allowed to create a has many entity.
340
- */
341
- hasManyAllowCreate;
342
- /**
343
- * The form context for creating an has many entity.
344
- */
345
- hasManyCreateFormContext;
346
- /**
347
- * The form context for editing an has many entity.
348
- */
349
- hasManyEditFormContext;
350
- hasManyCreateBaseUrl;
351
- /**
352
- * The metadata for a references one property.
353
- */
354
- metadataReferencesOne;
355
- /**
356
- * The values that can be possibly referenced.
357
- */
358
- referencesOneAllReferencedEntities;
359
- /**
360
- * The possible references one dropdown values.
361
- */
362
- referencesOneDropdownValues;
363
- /**
364
- * The filtered dropdown values that get displayed in the references one dropdown input.
365
- */
366
- filteredReferencesOneDropdownValues;
367
- /**
368
- * A unique input name for the references one property.
369
- */
370
- referencesOneName;
371
- /**
372
- * The form context for an references one property.
373
- */
374
- referencesOneFormContext;
375
- /**
376
- * The enum Values for all the different DecoratorTypes.
377
- */
378
- DecoratorTypes = DecoratorTypes;
379
- /**
380
- * Contains HelperMethods around handling Entities and their property-metadata.
381
- */
382
- EntityUtilities = EntityUtilities;
383
- /**
384
- * Contains Helper Functions for handling date properties.
385
- */
386
- DateUtilities = DateUtilities;
387
- /**
388
- * Provides functionality around material selections inside of tables.
389
- */
390
- SelectionUtilities = SelectionUtilities;
391
- // eslint-disable-next-line jsdoc/require-returns
392
- /**
393
- * Gets the currently selected dropdown value for references one.
394
- * Is needed so that the dropdown value will still be displayed,
395
- * even when the filter method removes the value from the selectable dropdown values.
396
- */
397
- get currentReferencesOneDropdownValue() {
398
- return LodashUtilities.cloneDeep(this.referencesOneDropdownValues ?? [])
399
- .find(v => v.value === this.entity[this.propertyKey]);
400
- }
401
- // eslint-disable-next-line jsdoc/require-returns
402
- /**
403
- * Whether or not the currently selected references one value should be shown,
404
- * although it would have been filtered out by the search.
405
- */
406
- get shouldDisplayCurrentReferencesOneDropdownValue() {
407
- return !!this.currentReferencesOneDropdownValue
408
- && !this.filteredReferencesOneDropdownValues.find(v => v.value === this.currentReferencesOneDropdownValue?.value);
409
- }
410
- constructor(dialog, injector, router, defaultGetValidationErrorMessage, globalConfig, http) {
411
- this.dialog = dialog;
412
- this.injector = injector;
413
- this.router = router;
414
- this.defaultGetValidationErrorMessage = defaultGetValidationErrorMessage;
415
- this.globalConfig = globalConfig;
416
- this.http = http;
417
- }
418
- /**
419
- * Checks if the input with the given key on the given property is readonly.
420
- * @param property - The property on which to check the input.
421
- * @param key - The key for the input to check.
422
- * @returns Whether or not the input is readonly.
423
- */
424
- isPropertyReadOnly(property, key) {
425
- return runInInjectionContext(this.injector, () => {
426
- if (this.internalIsReadOnly || this.metadataDefaultObject?.isReadOnly(property)) {
427
- return true;
428
- }
429
- const metadata = EntityUtilities.getPropertyMetadata(property, key);
430
- if (!metadata) {
431
- throw new Error(`No metadata was found for the key "${String(key)}"`);
432
- }
433
- return metadata.isReadOnly(property);
434
- });
435
- }
436
- /**
437
- * Gets the value to display in the column.
438
- * Runs in environment context to enable injection.
439
- * @param entity - The entity to get the value from.
440
- * @param displayColumn - The display column to get the value from.
441
- * @returns The value of the display column.
442
- */
443
- getDisplayColumnValue(entity, displayColumn) {
444
- return runInInjectionContext(this.injector, () => displayColumn.value(entity));
445
- }
446
- /**
447
- * Emits a cellClicked event when the clicked column is enabled and clicking is allowed by the configuration.
448
- * @param value - The value of the row that was clicked.
449
- * @param dCol - The display column of the row that was clicked.
450
- * @param context - The context of the table where the cell was clicked.
451
- */
452
- clickCell(value, dCol, context) {
453
- if (dCol.disableClick == true || !context.allowClick(value)) {
454
- return;
455
- }
456
- context.clickCell(value, dCol);
457
- }
458
- ngOnInit() {
459
- this.internalGetValidationErrorMessage = this.getValidationErrorMessage ?? this.defaultGetValidationErrorMessage;
460
- this.internalIsReadOnly = this.isReadOnly ?? false;
461
- const foundType = EntityUtilities.getPropertyType(this.entity, this.propertyKey);
462
- if (foundType == undefined) {
463
- throw new Error(`No type was found for the key "${String(this.propertyKey)}"`);
464
- }
465
- this.type = foundType;
466
- if (this.validEmpty === true) {
467
- const currentMetadata = ReflectUtilities.getMetadata('metadata', this.entity, this.propertyKey);
468
- ReflectUtilities.defineMetadata('metadata', { ...currentMetadata, required: defaultFalse }, this.entity, this.propertyKey);
469
- }
470
- const foundMetadata = EntityUtilities.getPropertyMetadata(this.entity, this.propertyKey, this.type);
471
- if (!foundMetadata) {
472
- throw new Error(`No metadata was found for the key "${String(this.propertyKey)}"`);
473
- }
474
- this.metadata = foundMetadata;
475
- switch (this.type) {
476
- case DecoratorTypes.OBJECT_DROPDOWN: {
477
- void this.initDropdownObjectInput();
478
- break;
479
- }
480
- case DecoratorTypes.OBJECT: {
481
- this.initObjectInput();
482
- break;
483
- }
484
- case DecoratorTypes.ARRAY: {
485
- this.initEntityArray();
486
- break;
487
- }
488
- case DecoratorTypes.HAS_MANY: {
489
- this.initHasMany();
490
- break;
491
- }
492
- case DecoratorTypes.REFERENCES_ONE: {
493
- void this.initReferencesOne();
494
- break;
495
- }
496
- default: {
497
- break;
498
- }
499
- }
500
- }
501
- async initReferencesOne() {
502
- this.metadataReferencesOne = this.metadata;
503
- this.referencesOneName = this.propertyKey.toString() + 'input' + UUIDUtilities.create();
504
- await runInInjectionContext(this.injector, async () => {
505
- this.referencesOneAllReferencedEntities = await this.metadataReferencesOne.getReferencedEntities();
506
- this.referencesOneDropdownValues = this.metadataReferencesOne.getDropdownValues(LodashUtilities.cloneDeep(this.referencesOneAllReferencedEntities));
507
- this.filteredReferencesOneDropdownValues = LodashUtilities.cloneDeep(this.referencesOneDropdownValues);
508
- this.setReferencesOneObject();
509
- });
510
- }
511
- /**
512
- * Filters the references one dropdown values.
513
- * @param searchInput - The search input to filter for.
514
- */
515
- filterReferencesOneValues(searchInput) {
516
- const filter = searchInput.toLowerCase();
517
- this.filteredReferencesOneDropdownValues = LodashUtilities.cloneDeep(this.referencesOneDropdownValues).filter(option => {
518
- return option.displayName.toLowerCase().includes(filter) || option.value.toLowerCase().includes(filter);
519
- });
520
- }
521
- initHasMany() {
522
- this.metadata = new HasManyDecoratorConfigInternal(this.metadata, this.globalConfig);
523
- ReflectUtilities.defineMetadata('metadata', this.metadata, this.entity, this.propertyKey);
524
- this.metadataHasMany = this.metadata;
525
- this.hasManyImportAction = new BaseTableActionInternal({
526
- ...this.metadataHasMany.tableData.baseData.importActionData,
527
- action: () => this.startImportJson()
528
- }, this.globalConfig);
529
- runInInjectionContext(this.injector, () => {
530
- this.hasManyAllowCreate = this.metadataHasMany.tableData.baseData.allowCreate();
531
- this.hasManyEntityService = inject(this.metadataHasMany.tableData.baseData.EntityServiceClass);
532
- this.hasManyCreateBaseUrl = this.metadataHasMany.createBaseUrl(this.entity, this.metadataHasMany);
533
- });
534
- const givenDisplayColumns = this.metadataHasMany.tableData.baseData.displayColumns.map((v) => v.displayName);
535
- if (givenDisplayColumns.find(s => s === 'select')) {
536
- throw new Error(`The name "select" for a display column is reserved.
537
- Please choose a different name.`);
538
- }
539
- this.hasManyTableContext = {
540
- $implicit: {
541
- ...new InternalCustomTableConfiguration(this.globalConfig, {
542
- displayColumns: this.metadataHasMany.tableData.baseData.displayColumns,
543
- withSelection: !this.internalIsReadOnly,
544
- // eslint-disable-next-line stylistic/max-len
545
- dynamicRowStyleClasses: this.metadataHasMany.tableData.baseData.dynamicRowStyleClasses,
546
- allowClick: ((entity) => {
547
- return this.metadataHasMany.tableData.baseData.allowRead(entity)
548
- || this.metadataHasMany.tableData.baseData.allowUpdate(entity);
549
- }),
550
- displayLoadingSpinner: this.metadataHasMany.tableData.baseData.displayLoadingSpinner,
551
- searchStringForRow: this.metadataHasMany.tableData.baseData.searchString
552
- }),
553
- displayedColumns: !this.metadataHasMany.tableData.baseData.tableActions.filter(tA => tA.type === 'multi-select').length
554
- ? givenDisplayColumns
555
- : ['select'].concat(givenDisplayColumns),
556
- dataSource: new MatTableDataSource(),
557
- isLoading: true,
558
- shouldShowMissingError: false,
559
- selection: new SelectionModel(true, []),
560
- clickCell: (entity, dCol) => this.editHasManyEntity(entity, dCol)
561
- }
562
- };
563
- this.hasManyTableContext.$implicit.dataSource.sortingDataAccessor = (entity, header) => {
564
- return runInInjectionContext(this.injector, () => {
565
- const displayColumn = this.metadataHasMany.tableData.baseData.displayColumns
566
- .find((dp) => dp.displayName === header);
567
- return tableColumnValueToSortValue(displayColumn.value(entity));
568
- });
569
- };
570
- this.hasManyTableContext.$implicit.dataSource.filterPredicate = (entity, filter) => {
571
- const searchStr = this.metadataHasMany.tableData.baseData.searchString(entity);
572
- const formattedSearchString = searchStr.toLowerCase();
573
- const formattedFilterString = filter.toLowerCase();
574
- return formattedSearchString.includes(formattedFilterString);
575
- };
576
- this.hasManyEntityService.entitiesSubject.subscribe((entities) => {
577
- this.hasManyTableContext.$implicit.dataSource.data = entities;
578
- this.hasManyTableContext.$implicit.selection.clear();
579
- });
580
- void runInInjectionContext(this.injector, async () => {
581
- const readBaseUrl = this.metadataHasMany.readBaseUrl(this.entity, this.metadataHasMany);
582
- await this.hasManyEntityService.read(readBaseUrl);
583
- this.hasManyTableContext.$implicit.isLoading = false;
584
- });
585
- }
586
- initEntityArray() {
587
- this.metadata = new EntityArrayDecoratorConfigInternal(this.metadata, this.globalConfig);
588
- this.metadataEntityArray = this.metadata;
589
- if (this.entity[this.propertyKey] == undefined) {
590
- this.entity[this.propertyKey] = [];
591
- ReflectUtilities.defineMetadata('metadata', this.metadata, this.entity, this.propertyKey);
592
- }
593
- if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
594
- this.metadataEntityArray.createDialogData = {
595
- title: 'Add'
596
- };
597
- }
598
- const givenDisplayColumns = this.metadataEntityArray.displayColumns.map((v) => v.displayName);
599
- if (givenDisplayColumns.find(s => s === 'select')) {
600
- throw new Error(`The name "select" for a display column is reserved.
601
- Please choose a different name.`);
602
- }
603
- this.entityArrayTableContext = {
604
- $implicit: {
605
- ...new InternalCustomTableConfiguration(this.globalConfig, {
606
- displayColumns: this.metadataEntityArray.displayColumns,
607
- withSelection: !this.internalIsReadOnly,
608
- dynamicRowStyleClasses: this.metadataEntityArray.dynamicRowStyleClasses,
609
- emptyErrorMessage: this.metadataEntityArray.missingErrorMessage
610
- }),
611
- displayedColumns: this.internalIsReadOnly ? givenDisplayColumns : ['select'].concat(givenDisplayColumns),
612
- dataSource: new MatTableDataSource(),
613
- isLoading: false,
614
- shouldShowMissingError: this.metadataEntityArray.required(this.entity),
615
- selection: new SelectionModel(true, []),
616
- // eslint-disable-next-line typescript/no-misused-promises
617
- clickCell: (entity, dCol) => this.editArrayItem(entity, dCol)
618
- }
619
- };
620
- this.entityArrayTableContext.$implicit.dataSource.data = this.entity[this.propertyKey];
621
- this.arrayItem = new this.metadataEntityArray.EntityClass();
622
- this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
623
- EntityUtilities.setDefaultValues(this.arrayItem);
624
- this.addArrayItemFormContext = {
625
- $implicit: {
626
- entity: this.arrayItem,
627
- tabs: EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true),
628
- inputChangeEvent: () => {
629
- void this.checkIsArrayItemValid();
630
- this.addArrayItemFormContext.$implicit.tabs = EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true);
631
- },
632
- hideOmitForCreate: true
633
- }
634
- };
635
- this.addArrayItemFormContext2 = LodashUtilities.cloneDeep(this.addArrayItemFormContext);
636
- this.addArrayItemDialogData = new CreateDataBuilder(this.globalConfig, this.metadataEntityArray.createDialogData)
637
- .withDefault('createButtonLabel', this.globalConfig.addLabel)
638
- .withDefault('title', this.globalConfig.addArrayItemTitle)
639
- .getResult();
640
- this.editArrayItemDialogData = this.metadataEntityArray.editDialogData;
641
- }
642
- async initDropdownObjectInput() {
643
- this.metadataDropdownObject = this.metadata;
644
- this.objectDropdownName = this.propertyKey.toString() + 'input' + UUIDUtilities.create();
645
- await runInInjectionContext(this.injector, async () => {
646
- this.objectDropdownValues = await this.metadataDropdownObject.dropdownValues(this.entity);
647
- this.filteredObjectDropdownValues = LodashUtilities.cloneDeep(this.objectDropdownValues);
648
- });
649
- }
650
- initObjectInput() {
651
- this.metadataDefaultObject = this.metadata;
652
- const objectProperty = this.entity[this.propertyKey];
653
- const objectPropertyTabs = EntityUtilities.getEntityTabs(objectProperty, this.injector, this.hideOmitForCreate, this.hideOmitForEdit, this.metadataDefaultObject.omit);
654
- this.objectFormContext = {
655
- $implicit: {
656
- entity: objectProperty,
657
- tabs: objectPropertyTabs,
658
- hideOmitForCreate: this.hideOmitForCreate,
659
- hideOmitForEdit: this.hideOmitForEdit,
660
- isReadOnly: (property, key) => this.isPropertyReadOnly(property, key),
661
- inputChangeEvent: () => this.emitChange(),
662
- validEmpty: () => !this.metadata.required(this.entity)
663
- }
664
- };
665
- }
666
- startImportJson() {
667
- const input = document.createElement('input');
668
- input.type = 'file';
669
- input.accept = 'application/json';
670
- input.onchange = async () => {
671
- if (input.files) {
672
- await this.importJson(input.files[0]);
673
- }
674
- };
675
- input.click();
676
- }
677
- async importJson(file) {
678
- // eslint-disable-next-line stylistic/max-len
679
- const dialogData = new ConfirmDialogDataBuilder(this.globalConfig, this.hasManyImportAction.confirmDialogData)
680
- .withDefault('text', this.metadataHasMany.tableData.baseData.importActionData.confirmDialogData?.text)
681
- .withDefault('title', this.hasManyImportAction.displayName)
682
- .getResult();
683
- const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
684
- data: dialogData,
685
- autoFocus: false,
686
- restoreFocus: false
687
- });
688
- const res = await firstValueFrom(dialogRef.afterClosed());
689
- if (res == true) {
690
- await this.hasManyEntityService.import(file);
691
- }
692
- }
693
- /**
694
- * Checks if two objects are equal. Is needed for the dropdown.
695
- * @param value1 - The first object to compare.
696
- * @param value2 - The second object to compare.
697
- * @returns Whether or not the objects are the same.
698
- */
699
- compareObjects(value1, value2) {
700
- const valueObject1 = new this.metadataDropdownObject.EntityClass(value1);
701
- const valueObject2 = new this.metadataDropdownObject.EntityClass(value2);
702
- return LodashUtilities.isEqual(valueObject1, valueObject2);
703
- }
704
- /**
705
- * Filters the dropdown values.
706
- * @param searchInput - The search input to filter for.
707
- */
708
- filterObjectDropdownValues(searchInput) {
709
- const filter = searchInput.toLowerCase();
710
- this.filteredObjectDropdownValues = LodashUtilities.cloneDeep(this.objectDropdownValues).filter(option => {
711
- return option.displayName.toLowerCase().includes(filter) || JSON.stringify(option.value).toLowerCase()
712
- .includes(filter);
713
- });
714
- }
715
- /**
716
- * Sets the references one object using the input id.
717
- */
718
- setReferencesOneObject() {
719
- const foundEntity = this.metadataReferencesOne.getEntityForId(this.entity[this.propertyKey], this.referencesOneAllReferencedEntities);
720
- const referencesOneObject = new this.metadataReferencesOne.EntityClass(foundEntity);
721
- const referencesOnePropertyTabs = EntityUtilities.getEntityTabs(referencesOneObject, this.injector, undefined, undefined, this.metadataReferencesOne.omit);
722
- if (this.metadataReferencesOne.dropdownOnly) {
723
- this.emitChange();
724
- return;
725
- }
726
- this.referencesOneFormContext = {
727
- $implicit: {
728
- entity: referencesOneObject,
729
- tabs: referencesOnePropertyTabs,
730
- hideOmitForCreate: this.hideOmitForCreate,
731
- hideOmitForEdit: this.hideOmitForEdit,
732
- isReadOnly: () => true,
733
- inputChangeEvent: () => this.emitChange(),
734
- validEmpty: () => !this.metadata.required(this.entity)
735
- }
736
- };
737
- this.emitChange();
738
- }
739
- /**
740
- * Edits an entity. This either calls the edit-Method provided by the user or uses a default edit-dialog.
741
- * @param entity - The entity that should be updated.
742
- * @param dCol - The display column that was clicked on.
743
- * @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
744
- */
745
- editHasManyEntity(entity, dCol) {
746
- if ((dCol.disableClick === true) || (!this.hasManyAllowUpdate(entity) && !this.hasManyAllowRead(entity))) {
747
- return;
748
- }
749
- if (!this.metadataHasMany.tableData.baseData.EntityClass) {
750
- throw new Error('No "EntityClass" specified for this table');
751
- }
752
- if (this.metadataHasMany.tableData.baseData.edit) {
753
- this.metadataHasMany.tableData.baseData.edit(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
754
- return;
755
- }
756
- if (this.metadataHasMany.tableData.baseData.defaultEdit == 'page') {
757
- this.editHasManyDefaultPage(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
758
- return;
759
- }
760
- void this.editHasManyDefaultDialog(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
761
- }
762
- /**
763
- * Whether updating the provided entity from the has many property is allowed.
764
- * @param entity - A single value of the has many property that the user wants to edit.
765
- * @returns True when the user can edit the provided entity and false otherwise.
766
- */
767
- hasManyAllowUpdate(entity) {
768
- return runInInjectionContext(this.injector, () => {
769
- return this.metadataHasMany.tableData.baseData.allowUpdate(entity);
770
- });
771
- }
772
- /**
773
- * Whether viewing the provided entity from the has many property is allowed.
774
- * @param entity - A single value of the has many property that the user wants to view.
775
- * @returns True when the user can view the provided entity and false otherwise.
776
- */
777
- hasManyAllowRead(entity) {
778
- return runInInjectionContext(this.injector, () => {
779
- return this.metadataHasMany.tableData.baseData.allowRead(entity);
780
- });
781
- }
782
- /**
783
- * Whether deleting the provided entity from the has many property is allowed.
784
- * @param entity - A single value of the has many property that the user wants to delete.
785
- * @returns True when the user can delete the provided entity and false otherwise.
786
- */
787
- hasManyAllowDelete(entity) {
788
- return runInInjectionContext(this.injector, () => {
789
- return this.metadataHasMany.tableData.baseData.allowDelete(entity);
790
- });
791
- }
792
- /**
793
- * Checks if an EditAction is disabled (e.g. Because the current entry doesn't fullfil the requirements).
794
- * @param action - The EditAction to check.
795
- * @returns Whether or not the Action can be used.
796
- */
797
- hasManyEditActionDisabled(action) {
798
- return runInInjectionContext(this.injector, () => {
799
- return !action.enabled(this.hasManyEntityPriorChanges);
800
- });
801
- }
802
- /**
803
- * Runs the edit action on the entity.
804
- * @param action - The action to run.
805
- */
806
- async hasManyRunEditAction(action) {
807
- const requireConfirmDialog = runInInjectionContext(this.injector, () => {
808
- return action.requireConfirmDialog(this.hasManyEntityPriorChanges);
809
- });
810
- if (!requireConfirmDialog) {
811
- await this.confirmHasManyRunEditAction(action);
812
- return;
813
- }
814
- const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
815
- data: action.confirmDialogData,
816
- autoFocus: false,
817
- restoreFocus: false
818
- });
819
- const res = await firstValueFrom(dialogRef.afterClosed());
820
- if (res == true) {
821
- await this.confirmHasManyRunEditAction(action);
822
- }
823
- }
824
- async confirmHasManyRunEditAction(action) {
825
- await runInInjectionContext(this.injector, async () => {
826
- await action.action(this.hasManyEntity, this.hasManyEntityPriorChanges);
827
- await this.checkHasManyEntity();
828
- });
829
- }
830
- editHasManyDefaultPage(entity) {
831
- void this.router.navigate(['', this.hasManyEntityService.editBaseRoute, entity[this.hasManyEntityService.idKey]]);
832
- }
833
- async editHasManyDefaultDialog(entity) {
834
- this.hasManyEntity = LodashUtilities.cloneDeep(entity);
835
- this.hasManyEntityPriorChanges = LodashUtilities.cloneDeep(this.hasManyEntity);
836
- this.hasManyEditFormContext = {
837
- $implicit: {
838
- entity: this.hasManyEntity,
839
- hideOmitForEdit: true,
840
- isReadOnly: (property, key) => this.isPropertyReadOnly(property, key),
841
- inputChangeEvent: () => {
842
- void this.checkHasManyEntity();
843
- this.hasManyEditFormContext.$implicit.tabs = EntityUtilities.getEntityTabs(this.hasManyEntity, this.injector, false, true);
844
- },
845
- tabs: EntityUtilities.getEntityTabs(this.hasManyEntity, this.injector, false, true)
846
- }
847
- };
848
- await this.checkHasManyEntity();
849
- this.editHasManyDialogRef = this.dialog.open(this.editHasManyDialog, {
850
- minWidth: '60%',
851
- autoFocus: false,
852
- restoreFocus: false
853
- });
854
- const res = await firstValueFrom(this.editHasManyDialogRef.afterClosed());
855
- if (res === 0) {
856
- const data = this.hasManyTableContext.$implicit.dataSource.data;
857
- // eslint-disable-next-line stylistic/max-len
858
- data[this.hasManyTableContext.$implicit.dataSource.data.findIndex((e) => e[this.hasManyEntityService.idKey] === entity[this.hasManyEntityService.idKey])] = entity;
859
- this.hasManyTableContext.$implicit.dataSource.data = data;
860
- this.hasManyTableContext.$implicit.selection.clear();
861
- }
862
- }
863
- /**
864
- * Tries to save the changes and close the dialog afterwards.
865
- * Also handles the confirmation if required.
866
- */
867
- async dialogEditHasMany() {
868
- if (this.internalIsReadOnly || !this.isHasManyEntityValid || !this.isHasManyEntityDirty) {
869
- return;
870
- }
871
- if (!this.metadataHasMany.tableData.editData.editRequiresConfirmDialog) {
872
- await this.dialogConfirmEditHasMany();
873
- return;
874
- }
875
- // eslint-disable-next-line stylistic/max-len
876
- const dialogData = new ConfirmDialogDataBuilder(this.globalConfig, this.metadataHasMany.tableData.editData.confirmEditDialogData)
877
- .withDefault('text', this.globalConfig.confirmSaveText)
878
- .withDefault('confirmButtonLabel', this.globalConfig.saveLabel)
879
- .withDefault('title', this.globalConfig.editLabel)
880
- .getResult();
881
- const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
882
- data: dialogData,
883
- autoFocus: false,
884
- restoreFocus: false
885
- });
886
- const res = await firstValueFrom(dialogRef.afterClosed());
887
- if (res == true) {
888
- await this.dialogConfirmEditHasMany();
889
- }
890
- }
891
- async dialogConfirmEditHasMany() {
892
- await this.hasManyEntityService.update(this.hasManyEntity, this.hasManyEntityPriorChanges);
893
- this.editHasManyDialogRef.close(1);
894
- this.emitChange();
895
- }
896
- /**
897
- * Tries to delete the entity and close the dialog afterwards.
898
- * Also handles the confirmation if required.
899
- */
900
- async deleteHasManyEntity() {
901
- if (!this.metadataHasMany.tableData.editData.deleteRequiresConfirmDialog) {
902
- await this.confirmDeleteHasManyEntity();
903
- return;
904
- }
905
- // eslint-disable-next-line stylistic/max-len
906
- const dialogData = new ConfirmDialogDataBuilder(this.globalConfig, this.metadataHasMany.tableData.editData.confirmDeleteDialogData)
907
- .withDefault('text', this.globalConfig.confirmDeleteText)
908
- .withDefault('type', 'delete')
909
- .withDefault('confirmButtonLabel', this.globalConfig.deleteLabel)
910
- .withDefault('title', this.globalConfig.deleteLabel)
911
- .getResult();
912
- const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
913
- data: dialogData,
914
- autoFocus: false,
915
- restoreFocus: false
916
- });
917
- const res = await firstValueFrom(dialogRef.afterClosed());
918
- if (res == true) {
919
- await this.confirmDeleteHasManyEntity();
920
- }
921
- }
922
- async confirmDeleteHasManyEntity() {
923
- await this.hasManyEntityService.delete(this.hasManyEntityPriorChanges);
924
- this.editHasManyDialogRef.close(2);
925
- this.emitChange();
926
- }
927
- /**
928
- * Cancels the editing of the has many entity and closes the dialog.
929
- */
930
- dialogCancelEditHasMany() {
931
- EntityUtilities.resetChangesOnEntity(this.hasManyEntity, this.hasManyEntityPriorChanges);
932
- this.editHasManyDialogRef.close(0);
933
- }
934
- /**
935
- * Creates a new Entity. This either calls the create-Method provided by the user or uses a default create-dialog.
936
- * @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
937
- */
938
- createHasManyEntity() {
939
- void runInInjectionContext(this.injector, async () => {
940
- if (this.metadataHasMany.tableData.baseData.allowCreate()) {
941
- if (!this.metadataHasMany.tableData.baseData.EntityClass) {
942
- throw new Error('No "EntityClass" specified for this table');
943
- }
944
- if (this.metadataHasMany.tableData.baseData.create) {
945
- this.metadataHasMany.tableData.baseData.create(new this.metadataHasMany.tableData.baseData.EntityClass());
946
- return;
947
- }
948
- const entity = new this.metadataHasMany.tableData.baseData.EntityClass();
949
- EntityUtilities.setDefaultValues(entity);
950
- if (this.metadataHasMany.tableData.baseData.defaultCreate == 'page') {
951
- this.createHasManyDefaultPage();
952
- return;
953
- }
954
- await this.createHasManyDefaultDialog(entity);
955
- }
956
- });
957
- }
958
- createHasManyDefaultPage() {
959
- void this.router.navigateByUrl(this.hasManyEntityService.createBaseRoute);
960
- }
961
- async createHasManyDefaultDialog(entity) {
962
- this.hasManyEntity = entity;
963
- this.hasManyCreateFormContext = {
964
- $implicit: {
965
- entity: this.hasManyEntity,
966
- hideOmitForCreate: true,
967
- inputChangeEvent: () => {
968
- void this.checkIsHasManyEntityValid('create');
969
- this.hasManyCreateFormContext.$implicit.tabs = EntityUtilities.getEntityTabs(this.hasManyEntity, this.injector, true);
970
- },
971
- tabs: EntityUtilities.getEntityTabs(this.hasManyEntity, this.injector, true)
972
- }
973
- };
974
- await this.checkIsHasManyEntityValid('create');
975
- this.createHasManyDialogRef = this.dialog.open(this.createHasManyDialog, {
976
- minWidth: '60%',
977
- autoFocus: false,
978
- restoreFocus: false
979
- });
980
- }
981
- /**
982
- * Creates the has many entity over the dialog.
983
- */
984
- async dialogCreateHasMany() {
985
- if (!this.isHasManyEntityValid) {
986
- return;
987
- }
988
- if (!this.metadataHasMany.tableData.createData.createRequiresConfirmDialog) {
989
- await this.dialogConfirmCreateHasMany();
990
- return;
991
- }
992
- // eslint-disable-next-line stylistic/max-len
993
- const dialogData = new ConfirmDialogDataBuilder(this.globalConfig, this.metadataHasMany.tableData.createData.confirmCreateDialogData)
994
- .withDefault('text', this.globalConfig.confirmCreateText)
995
- .withDefault('confirmButtonLabel', this.globalConfig.createLabel)
996
- .withDefault('title', this.globalConfig.createLabel)
997
- .getResult();
998
- const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
999
- data: dialogData,
1000
- autoFocus: false,
1001
- restoreFocus: false
1002
- });
1003
- const res = await firstValueFrom(dialogRef.afterClosed());
1004
- if (res == true) {
1005
- await this.dialogConfirmCreateHasMany();
1006
- }
1007
- }
1008
- async dialogConfirmCreateHasMany() {
1009
- await this.hasManyEntityService.create(this.hasManyEntity, this.hasManyCreateBaseUrl);
1010
- this.createHasManyDialogRef.close();
1011
- this.emitChange();
1012
- }
1013
- /**
1014
- * Cancels the creating of the has many entity and closes the dialog.
1015
- */
1016
- dialogCancelCreateHasMany() {
1017
- this.createHasManyDialogRef.close();
1018
- }
1019
- /**
1020
- * Runs the TableAction for all selected entries.
1021
- * Also handles confirmation with an additional dial#og if configured.
1022
- * @param action - The TableAction to run.
1023
- */
1024
- async runHasManyTableAction(action) {
1025
- const requireConfirmDialog = runInInjectionContext(this.injector, () => action.requireConfirmDialog(this.hasManyTableContext.$implicit.selection.selected));
1026
- if (!requireConfirmDialog) {
1027
- await this.confirmRunHasManyTableAction(action);
1028
- return;
1029
- }
1030
- const defaultText = action.type === 'multi-select'
1031
- ? this.globalConfig.confirmMultiSelectActionText(this.hasManyTableContext.$implicit.selection.selected)
1032
- : this.globalConfig.confirmBaseActionText;
1033
- const dialogData = new ConfirmDialogDataBuilder(this.globalConfig, action.confirmDialogData)
1034
- .withDefault('text', defaultText)
1035
- .withDefault('title', action.displayName)
1036
- .getResult();
1037
- const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1038
- data: dialogData,
1039
- autoFocus: false,
1040
- restoreFocus: false
1041
- });
1042
- const res = await firstValueFrom(dialogRef.afterClosed());
1043
- if (res == true) {
1044
- await this.confirmRunHasManyTableAction(action);
1045
- }
1046
- }
1047
- async confirmRunHasManyTableAction(action) {
1048
- await runInInjectionContext(this.injector, async () => {
1049
- await action.action(this.hasManyTableContext.$implicit.selection.selected);
1050
- this.emitChange();
1051
- });
1052
- }
1053
- /**
1054
- * Checks if an TableAction is disabled (e.g. Because no entries have been selected).
1055
- * @param action - The TableAction to check.
1056
- * @returns Whether or not the Action can be used.
1057
- */
1058
- hasManyTableActionDisabled(action) {
1059
- return runInInjectionContext(this.injector, () => {
1060
- return !action.enabled(this.hasManyTableContext.$implicit.selection.selected);
1061
- });
1062
- }
1063
- /**
1064
- * Applies the search input to filter the table entries.
1065
- * @param event - The keyup-event which contains the search-string of the user.
1066
- */
1067
- applyHasManyFilter(event) {
1068
- const filterValue = event.target.value;
1069
- this.hasManyTableContext.$implicit.dataSource.filter = filterValue.trim().toLowerCase();
1070
- }
1071
- /**
1072
- * Checks if the entity is valid for updating and if it is dirty.
1073
- */
1074
- async checkHasManyEntity() {
1075
- await this.checkIsHasManyEntityValid('update');
1076
- this.hasManyChanges = await EntityUtilities.getDifferencesBetweenEntities(this.hasManyEntity, this.hasManyEntityPriorChanges, this.http, this.injector);
1077
- if (!this.hasManyValidationErrors.length && this.hasManyChanges.length) {
1078
- this.hasManyTooltipContent = runInInjectionContext(this.injector, () => getChangesTooltipContent(this.hasManyChanges));
1079
- }
1080
- this.isHasManyEntityDirty = !!this.hasManyChanges.length;
1081
- }
1082
- /**
1083
- * Checks if the entity is valid.
1084
- * @param omit - Whether values omitted for create or update should be left out.
1085
- */
1086
- async checkIsHasManyEntityValid(omit) {
1087
- this.hasManyValidationErrors = await ValidationUtilities.getEntityValidationErrors(this.hasManyEntity, this.injector, omit);
1088
- if (this.hasManyValidationErrors.length) {
1089
- this.hasManyTooltipContent = runInInjectionContext(this.injector, () => getValidationErrorsTooltipContent(this.hasManyValidationErrors));
1090
- }
1091
- this.isHasManyEntityValid = this.hasManyValidationErrors.length === 0;
1092
- }
1093
- /**
1094
- * Checks whether the array item is valid and if the array item is dirty.
1095
- */
1096
- async checkArrayItem() {
1097
- await this.checkIsArrayItemValid();
1098
- await this.checkIsArrayItemDirty();
1099
- }
1100
- /**
1101
- * Checks if the array item is dirty.
1102
- */
1103
- async checkIsArrayItemDirty() {
1104
- this.arrayItemChanges = await EntityUtilities.getDifferencesBetweenEntities(this.arrayItem, this.arrayItemPriorChanges, this.http, this.injector);
1105
- if (!this.arrayItemValidationErrors.length && this.arrayItemChanges.length) {
1106
- this.arrayItemTooltipContent = runInInjectionContext(this.injector, () => getChangesTooltipContent(this.arrayItemChanges));
1107
- }
1108
- this.isArrayItemDirty = !!this.arrayItemChanges.length;
1109
- }
1110
- /**
1111
- * Checks if the arrayItem is valid.
1112
- */
1113
- async checkIsArrayItemValid() {
1114
- this.arrayItemValidationErrors = await ValidationUtilities.getEntityValidationErrors(this.arrayItem, this.injector, 'create');
1115
- if (this.arrayItemValidationErrors.length) {
1116
- this.arrayItemTooltipContent = runInInjectionContext(this.injector, () => getValidationErrorsTooltipContent(this.arrayItemValidationErrors));
1117
- }
1118
- this.isArrayItemValid = this.arrayItemValidationErrors.length === 0;
1119
- }
1120
- /**
1121
- * Emits that a the value has been changed.
1122
- */
1123
- emitChange() {
1124
- this.inputChangeEvent.emit();
1125
- }
1126
- /**
1127
- * Tries to add an item to the entity array.
1128
- * Does this either inline if the "createInline"-metadata is set to true
1129
- * or in a separate dialog if it is set to false.
1130
- */
1131
- async addEntity() {
1132
- await this.checkIsArrayItemValid();
1133
- if (!this.metadataEntityArray.createInline) {
1134
- this.arrayItem = new this.metadataEntityArray.EntityClass();
1135
- this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
1136
- EntityUtilities.setDefaultValues(this.arrayItem);
1137
- this.addArrayItemFormContext = {
1138
- $implicit: {
1139
- entity: this.arrayItem,
1140
- tabs: EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true),
1141
- inputChangeEvent: () => {
1142
- void this.checkIsArrayItemValid();
1143
- this.addArrayItemFormContext.$implicit.tabs = EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true);
1144
- },
1145
- hideOmitForCreate: true
1146
- }
1147
- };
1148
- this.addArrayItemFormContext2 = LodashUtilities.cloneDeep(this.addArrayItemFormContext);
1149
- this.addArrayItemDialogRef = this.dialog.open(this.addArrayItemDialog, {
1150
- minWidth: '60%',
1151
- autoFocus: false,
1152
- restoreFocus: false
1153
- });
1154
- return;
1155
- }
1156
- if (!this.metadataEntityArray.allowDuplicates) {
1157
- for (const v of this.entityArrayTableContext.$implicit.dataSource.data) {
1158
- if (await EntityUtilities.isEqual(this.arrayItem, v, this.metadata, this.metadataEntityArray.itemType, this.http)) {
1159
- this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1160
- data: this.metadataEntityArray.duplicatesErrorDialog,
1161
- autoFocus: false,
1162
- restoreFocus: false
1163
- });
1164
- return;
1165
- }
1166
- }
1167
- }
1168
- this.entity[this.propertyKey].push(LodashUtilities.cloneDeep(this.arrayItem));
1169
- this.entityArrayTableContext.$implicit.dataSource.data = this.entity[this.propertyKey];
1170
- this.addArrayItemFormContext = undefined;
1171
- this.arrayItem = new this.metadataEntityArray.EntityClass();
1172
- this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
1173
- EntityUtilities.setDefaultValues(this.arrayItem);
1174
- setTimeout(
1175
- // eslint-disable-next-line typescript/no-misused-promises
1176
- async () => {
1177
- this.addArrayItemFormContext = {
1178
- $implicit: {
1179
- entity: this.arrayItem,
1180
- tabs: EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true),
1181
- inputChangeEvent: () => {
1182
- void this.checkIsArrayItemValid();
1183
- // eslint-disable-next-line stylistic/max-len
1184
- this.addArrayItemFormContext.$implicit.tabs = EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true);
1185
- },
1186
- hideOmitForCreate: true
1187
- }
1188
- };
1189
- await this.checkIsArrayItemValid();
1190
- this.emitChange();
1191
- }, 1);
1192
- }
1193
- /**
1194
- * Adds the array item defined in the dialog.
1195
- */
1196
- async addArrayItem() {
1197
- if (!this.isArrayItemValid) {
1198
- return;
1199
- }
1200
- this.entity[this.propertyKey].push(LodashUtilities.cloneDeep(this.arrayItem));
1201
- this.entityArrayTableContext.$implicit.dataSource.data = this.entity[this.propertyKey];
1202
- await this.closeAddArrayItemDialog();
1203
- }
1204
- /**
1205
- * Cancels adding the array item defined in the dialog.
1206
- */
1207
- async closeAddArrayItemDialog() {
1208
- this.addArrayItemDialogRef.close();
1209
- EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
1210
- await this.checkIsArrayItemValid();
1211
- this.emitChange();
1212
- }
1213
- /**
1214
- * Edits an entity array item.
1215
- * @param entity - The entity that has been clicked.
1216
- * @param dCol - The display column that was clicked on.
1217
- */
1218
- async editArrayItem(entity, dCol) {
1219
- if (dCol.disableClick === true) {
1220
- return;
1221
- }
1222
- this.indexOfEditedArrayItem = this.entityArrayTableContext.$implicit.dataSource.data.indexOf(entity);
1223
- this.arrayItem = new this.metadataEntityArray.EntityClass(entity);
1224
- this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
1225
- this.editArrayItemFormContext = {
1226
- $implicit: {
1227
- entity: this.arrayItem,
1228
- tabs: EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true),
1229
- isReadOnly: (property, key) => this.isPropertyReadOnly(property, key),
1230
- inputChangeEvent: () => {
1231
- void this.checkArrayItem();
1232
- this.editArrayItemFormContext.$implicit.tabs = EntityUtilities.getEntityTabs(this.arrayItem, this.injector, true);
1233
- },
1234
- hideOmitForEdit: true
1235
- }
1236
- };
1237
- await this.checkArrayItem();
1238
- this.editArrayItemDialogRef = this.dialog.open(this.editArrayItemDialog, {
1239
- minWidth: '60%',
1240
- autoFocus: false,
1241
- restoreFocus: false
1242
- });
1243
- }
1244
- /**
1245
- * Saves changes on the array item in the dialog.
1246
- */
1247
- saveArrayItem() {
1248
- this.entity[this.propertyKey][this.indexOfEditedArrayItem] = LodashUtilities.cloneDeep(this.arrayItem);
1249
- this.entityArrayTableContext.$implicit.dataSource.data = this.entity[this.propertyKey];
1250
- void this.closeEditArrayItemDialog();
1251
- }
1252
- /**
1253
- * Closes the edit array item dialog and resets changes.
1254
- */
1255
- async closeEditArrayItemDialog() {
1256
- this.editArrayItemDialogRef.close();
1257
- this.arrayItem = new this.metadataEntityArray.EntityClass();
1258
- this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
1259
- await this.checkArrayItem();
1260
- this.emitChange();
1261
- }
1262
- /**
1263
- * Removes all selected entries from the entity array.
1264
- */
1265
- removeFromEntityArray() {
1266
- SelectionUtilities.remove(this.entityArrayTableContext.$implicit.selection, this.entity[this.propertyKey], this.entityArrayTableContext.$implicit.dataSource);
1267
- this.emitChange();
1268
- }
1269
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.7", ngImport: i0, type: NgxMatEntityInputComponent, deps: [{ token: i1.MatDialog }, { token: i0.EnvironmentInjector }, { token: i2.Router }, { token: NGX_GET_VALIDATION_ERROR_MESSAGE }, { token: NGX_COMPLETE_GLOBAL_DEFAULT_VALUES }, { token: i3.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
1270
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.7", type: NgxMatEntityInputComponent, isStandalone: true, selector: "ngx-mat-entity-input", inputs: { entity: "entity", propertyKey: "propertyKey", getValidationErrorMessage: "getValidationErrorMessage", hideOmitForCreate: "hideOmitForCreate", hideOmitForEdit: "hideOmitForEdit", validEmpty: "validEmpty", isReadOnly: "isReadOnly" }, outputs: { inputChangeEvent: "inputChangeEvent" }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "addArrayItemDialog", first: true, predicate: ["addArrayItemDialog"], descendants: true }, { propertyName: "editArrayItemDialog", first: true, predicate: ["editArrayItemDialog"], descendants: true }, { propertyName: "createHasManyDialog", first: true, predicate: ["createHasManyDialog"], descendants: true }, { propertyName: "editHasManyDialog", first: true, predicate: ["editHasManyDialog"], descendants: true }], ngImport: i0, template: "<!-- eslint-disable angular/no-call-expression -->\n@if(!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)) {\n @switch (type) {\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.STRING) {\n <string-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-input>\n }\n @case (DecoratorTypes.STRING_TEXTBOX) {\n <string-textbox-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-textbox-input>\n }\n @case (DecoratorTypes.STRING_AUTOCOMPLETE) {\n <string-autocomplete-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-autocomplete-input>\n }\n @case (DecoratorTypes.STRING_DROPDOWN) {\n <string-dropdown-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-dropdown-input>\n }\n @case (DecoratorTypes.STRING_PASSWORD) {\n <string-password-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-password-input>\n }\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.BOOLEAN_CHECKBOX) {\n <boolean-checkbox-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </boolean-checkbox-input>\n }\n @case (DecoratorTypes.BOOLEAN_TOGGLE) {\n <boolean-toggle-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </boolean-toggle-input>\n }\n @case (DecoratorTypes.BOOLEAN_DROPDOWN) {\n <boolean-dropdown-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </boolean-dropdown-input>\n }\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.NUMBER) {\n <number-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </number-input>\n }\n @case (DecoratorTypes.NUMBER_DROPDOWN) {\n <number-dropdown-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </number-dropdown-input>\n }\n @case (DecoratorTypes.NUMBER_SLIDER) {\n <number-slider-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </number-slider-input>\n }\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.ARRAY_DATE) {\n <array-date-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-date-input>\n }\n @case (DecoratorTypes.ARRAY_DATE_TIME) {\n <array-date-time-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-date-time-input>\n }\n @case (DecoratorTypes.ARRAY_DATE_RANGE) {\n <array-date-range-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-date-range-input>\n }\n @case (DecoratorTypes.ARRAY_STRING_CHIPS) {\n <array-string-chips-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-string-chips-input>\n }\n @case (DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS) {\n <array-string-autocomplete-chips\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-string-autocomplete-chips>\n }\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.DATE) {\n <date-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </date-input>\n }\n @case (DecoratorTypes.DATE_RANGE) {\n <date-range-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </date-range-input>\n }\n @case (DecoratorTypes.DATE_TIME) {\n <date-time-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </date-time-input>\n }\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.FILE_DEFAULT) {\n <file-default-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </file-default-input>\n }\n @case (DecoratorTypes.FILE_IMAGE) {\n <file-image-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </file-image-input>\n }\n <!-------------------------------------------->\n <!-------------- references many ------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.REFERENCES_MANY) {\n <references-many-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </references-many-input>\n }\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.CUSTOM) {\n <custom-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </custom-input>\n }\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.OBJECT) {\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <ng-container *ngTemplateOutlet=\"form; context: objectFormContext\"></ng-container>\n }\n <!-------------------------------------------->\n <!---------------Object Dropdown-------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.OBJECT_DROPDOWN) {\n <mat-form-field class=\"w-full\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select #model=\"ngModel\"\n [name]=\"objectDropdownName\"\n [required]=\"metadata.required(entity)\"\n [disabled]=\"internalIsReadOnly\"\n [compareWith]=\"compareObjectsBound\"\n [(ngModel)]=\"entity[propertyKey]\"\n (selectionChange)=\"emitChange()\"\n (opened)=\"selectSearchInput.focus()\"\n >\n <mat-form-field class=\"select-search-input\">\n <!-- eslint-disable-next-line angular/no-any -->\n <input #selectSearchInput matInput (keyup)=\"filterObjectDropdownValues($any($event.target).value)\">\n <fa-icon matSuffix [icon]=\"faSearch\"></fa-icon>\n </mat-form-field>\n @if (!metadata.required(entity)) {\n <mat-option>-</mat-option>\n }\n @if (shouldDisplayCurrentObjectDropdownValue) {\n <mat-option [value]=\"currentObjectDropdownValue?.value\">{{currentObjectDropdownValue?.displayName}}</mat-option>\n }\n @for (value of filteredObjectDropdownValues; track $index) {\n <mat-option [value]=\"value.value\">{{value.displayName}}</mat-option>\n }\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n }\n <!-------------------------------------------->\n <!-------------- references one -------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.REFERENCES_ONE) {\n <mat-form-field [class.w-full]=\"metadataReferencesOne.dropdownOnly\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select #inputModel=\"ngModel\"\n [name]=\"referencesOneName\"\n [disabled]=\"internalIsReadOnly\"\n [required]=\"metadata.required(entity)\"\n [(ngModel)]=\"entity[propertyKey]\"\n (selectionChange)=\"setReferencesOneObject()\"\n (opened)=\"selectSearchInput.focus()\"\n >\n <mat-form-field class=\"select-search-input\">\n <!-- eslint-disable-next-line angular/no-any -->\n <input #selectSearchInput matInput (keyup)=\"filterReferencesOneValues($any($event.target).value)\">\n <fa-icon matSuffix [icon]=\"faSearch\"></fa-icon>\n </mat-form-field>\n @if (!metadata.required(entity)) {\n <mat-option>-</mat-option>\n }\n @if (shouldDisplayCurrentReferencesOneDropdownValue) {\n <mat-option [value]=\"currentReferencesOneDropdownValue?.value\">{{currentReferencesOneDropdownValue?.displayName}}</mat-option>\n }\n @for (value of filteredReferencesOneDropdownValues; track $index) {\n <mat-option [value]=\"value.value\">{{value.displayName}}</mat-option>\n }\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(inputModel)}}</mat-error>\n </mat-form-field>\n <!-- iterates over the references one properties -->\n @if (referencesOneFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: referencesOneFormContext\"></ng-container>\n }\n }\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.ARRAY) {\n <div class=\"entityArray\">\n <div class=\"mat-elevation-z8 elevation-container\">\n <div class=\"array-headline\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n @if (metadataEntityArray.createInline && !internalIsReadOnly) {\n @if (addArrayItemFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: addArrayItemFormContext\"></ng-container>\n }\n @else if (addArrayItemFormContext2) {\n <ng-container *ngTemplateOutlet=\"form; context: addArrayItemFormContext2\"></ng-container>\n }\n }\n @if (!internalIsReadOnly && entityArrayTableContext) {\n <div class=\"buttons\">\n <button type=\"button\" mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button\n [disabled]=\"!entityArrayTableContext.$implicit.selection.selected.length\"\n (click)=\"removeFromEntityArray()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n }\n @if (entityArrayTableContext) {\n <ng-container *ngTemplateOutlet=\"table; context: entityArrayTableContext\"></ng-container>\n }\n </div>\n </div>\n }\n <!-------------------------------------------->\n <!------------------ has many ---------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.HAS_MANY) {\n <div class=\"hasMany\">\n <h2 class=\"title\">{{metadataHasMany.tableData.baseData.title}}</h2>\n <div class=\"grid grid-cols-12 gap-x-6\">\n <mat-form-field class=\"lg:col-span-8 md:col-span-6 col-span-12\">\n <mat-label>{{metadataHasMany.tableData.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyHasManyFilter($event)\">\n </mat-form-field>\n @if (metadataHasMany.tableData.baseData.tableActions.length) {\n <div\n [class.lg:col-span-2]=\"hasManyAllowCreate\"\n [class.lg:col-span-4]=\"!hasManyAllowCreate\"\n [class.md:col-span-3]=\"hasManyAllowCreate\"\n [class.md:col-span-6]=\"!hasManyAllowCreate\"\n [class.col-span-6]=\"hasManyAllowCreate\"\n [class.col-span-12]=\"!hasManyAllowCreate\"\n >\n <button type=\"button\" class=\"actions-button\" mat-raised-button [matMenuTriggerFor]=\"menu\">\n {{metadataHasMany.tableData.baseData.tableActionsLabel}}\n </button>\n </div>\n }\n <mat-menu #menu=\"matMenu\">\n @if (metadataHasMany.tableData.baseData.allowJsonImport) {\n <button type=\"button\" mat-menu-item [disabled]=\"hasManyTableActionDisabled(hasManyImportAction)\" (click)=\"runHasManyTableAction(hasManyImportAction)\">\n {{hasManyImportAction.displayName}}\n </button>\n }\n @for (action of metadataHasMany.tableData.baseData.tableActions; track $index) {\n <button type=\"button\" mat-menu-item [disabled]=\"hasManyTableActionDisabled(action)\" (click)=\"runHasManyTableAction(action)\">\n {{action.displayName}}\n </button>\n }\n </mat-menu>\n @if (hasManyAllowCreate) {\n <div\n [class.lg:col-span-2]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.lg:col-span-4]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.md:col-span-3]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.md:col-span-6]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-span-6]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-span-12]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n >\n <button type=\"button\" class=\"create-button\" mat-raised-button (click)=\"createHasManyEntity()\">\n {{metadataHasMany.tableData.baseData.createButtonLabel}}\n </button>\n </div>\n }\n </div>\n \n <div class=\"mat-elevation-z8 elevation-container\">\n @if (hasManyTableContext) {\n <ng-container *ngTemplateOutlet=\"table; context: hasManyTableContext\"></ng-container>\n }\n </div>\n </div>\n }\n \n @default {\n <div>ERROR: The type {{type}} is not known.</div>\n }\n }\n}\n\n\n<ng-template #table let-context>\n <mat-table matSort [dataSource]=\"context.dataSource\" [class.table-with-error-slot]=\"context.shouldShowMissingError\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [checked]=\"context.selection.hasValue() && SelectionUtilities.isAllSelected(context.selection, context.dataSource)\"\n [indeterminate]=\"context.selection.hasValue() && !SelectionUtilities.isAllSelected(context.selection, context.dataSource)\"\n (change)=\"$event ? SelectionUtilities.masterToggle(context.selection, context.dataSource) : null\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let value\" [dynamicStyleClasses]=\"context.dynamicRowStyleClasses\" [value]=\"value\">\n <mat-checkbox [checked]=\"context.selection.isSelected(value)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? context.selection.toggle(value) : null\">\n </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n @for (dCol of context.displayColumns; track $index) {\n <ng-container [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell *matCellDef=\"let value\" [class.enabled]=\"!dCol.disableClick && context.allowClick(value)\"\n [dynamicStyleClasses]=\"context.dynamicRowStyleClasses\" [value]=\"value\"\n (click)=\"clickCell(value, dCol, context)\"\n >\n @if (dCol.Component) {\n <display-column-value [entity]=\"value\" [ComponentClass]=\"dCol.Component\"></display-column-value>\n }\n @else {\n {{getDisplayColumnValue(value, dCol)}}\n }\n </mat-cell>\n </ng-container>\n }\n\n <mat-header-row *matHeaderRowDef=\"context.displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: context.displayedColumns\"></mat-row>\n </mat-table>\n\n @if (context.displayLoadingSpinner && context.isLoading) {\n <mat-spinner>\n </mat-spinner>\n }\n @else if (context.shouldShowMissingError && !context.dataSource.data.length) {\n <div class=\"table-error\">{{context.emptyErrorMessage}}</div>\n }\n\n <mat-paginator [length]=\"context.dataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"></mat-paginator>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!---------------------------Form-------------------------->\n<!--------------------------------------------------------->\n<ng-template #form let-context>\n <!-- eslint-disable angular/no-call-expression -->\n @if (context.tabs.length > 1) {\n <mat-tab-group preserveContent>\n @for (tab of context.tabs; track $index) {\n <mat-tab [label]=\"tab.tabName\">\n @for (row of tab.rows; track $index) {\n <div class=\"grid grid-cols-12 gap-x-6\">\n @for (key of row.keys; track key) {\n <ngx-mat-entity-input\n [entity]=\"context.entity\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [validEmpty]=\"context.validEmpty?.()\"\n [isReadOnly]=\"context.isReadOnly?.(context.entity, key)\"\n [class]=\"EntityUtilities.getWidthClasses(context.entity, key)\"\n [hideOmitForEdit]=\"context.hideOmitForEdit\"\n [hideOmitForCreate]=\"context.hideOmitForCreate\"\n (inputChangeEvent)=\"context.inputChangeEvent()\"\n >\n </ngx-mat-entity-input>\n }\n </div>\n }\n </mat-tab>\n }\n </mat-tab-group>\n }\n @else {\n @if (!context.tabs.length) {\n <span class=\"no-entity-tabs\">\n ERROR: No Inputs. Did you correctly assign all values in the model constructor?\n </span>\n }\n @else {\n @for (row of context.tabs[0].rows; track $index) {\n <div class=\"grid grid-cols-12 gap-x-6\">\n @for (key of row.keys; track key) {\n <ngx-mat-entity-input\n [entity]=\"context.entity\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [validEmpty]=\"context.validEmpty?.()\"\n [isReadOnly]=\"context.isReadOnly?.(context.entity, key)\"\n [class]=\"EntityUtilities.getWidthClasses(context.entity, key)\"\n [hideOmitForEdit]=\"context.hideOmitForEdit\"\n [hideOmitForCreate]=\"context.hideOmitForCreate\"\n (inputChangeEvent)=\"context.inputChangeEvent()\"\n >\n </ngx-mat-entity-input>\n }\n </div>\n }\n }\n }\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{addArrayItemDialogData.title}}</div>\n </div>\n\n <form (ngSubmit)=\"addArrayItem()\">\n <mat-dialog-content>\n @if (addArrayItemFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: addArrayItemFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [disabled]=\"!isArrayItemValid\"\n [matBadge]=\"arrayItemValidationErrors.length\"\n [matBadgeHidden]=\"!arrayItemValidationErrors.length\"\n >\n {{addArrayItemDialogData.createButtonLabel}}\n </button>\n @if (arrayItemValidationErrors.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"arrayItemTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"closeAddArrayItemDialog()\">\n {{addArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #editArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{editArrayItemDialogData.title(arrayItemPriorChanges)}}</div>\n </div>\n \n <form (ngSubmit)=\"saveArrayItem()\">\n <mat-dialog-content>\n @if (editArrayItemFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: editArrayItemFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [class.badge-changes]=\"!arrayItemValidationErrors.length\"\n [disabled]=\"internalIsReadOnly || !isArrayItemValid || !isArrayItemDirty\"\n [matBadge]=\"arrayItemValidationErrors.length > 0 ? arrayItemValidationErrors.length : arrayItemChanges.length\"\n [matBadgeHidden]=\"!arrayItemValidationErrors.length && !arrayItemChanges.length\"\n >\n {{editArrayItemDialogData.confirmButtonLabel}}\n </button>\n @if (arrayItemValidationErrors.length || arrayItemChanges.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"arrayItemTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"closeEditArrayItemDialog()\">\n {{editArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Create Has Many Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #createHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.createData.title}}</div>\n </div>\n \n <form (ngSubmit)=\"dialogCreateHasMany()\">\n <mat-dialog-content>\n @if (hasManyCreateFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: hasManyCreateFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [disabled]=\"!isHasManyEntityValid\"\n [matBadge]=\"hasManyValidationErrors.length\"\n [matBadgeHidden]=\"!hasManyValidationErrors.length\"\n >\n {{metadataHasMany.tableData.createData.createButtonLabel}}\n </button>\n @if (hasManyValidationErrors.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"hasManyTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"dialogCancelCreateHasMany()\">\n {{metadataHasMany.tableData.createData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n \n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Has Many Dialog----------------->\n<!--------------------------------------------------------->\n<ng-template #editHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.editData.title(hasManyEntityPriorChanges)}}</div>\n\n <div class=\"actions-container\">\n @if (metadataHasMany.tableData.editData.actions.length) {\n <button type=\"button\" mat-raised-button [matMenuTriggerFor]=\"menu\">\n {{metadataHasMany.tableData.editData.actionsLabel}}\n </button>\n }\n <mat-menu #menu=\"matMenu\">\n @for (action of metadataHasMany.tableData.editData.actions; track $index) {\n <button type=\"button\" mat-menu-item [disabled]=\"hasManyEditActionDisabled(action)\" (click)=\"hasManyRunEditAction(action)\">\n {{action.displayName}}\n </button>\n }\n </mat-menu>\n \n @if (hasManyAllowDelete(hasManyEntity)) {\n <button type=\"button\" mat-raised-button color=\"warn\" class=\"delete-button\" tabindex=\"-1\" (click)=\"deleteHasManyEntity()\">\n {{metadataHasMany.tableData.editData.deleteButtonLabel}}\n </button>\n }\n </div>\n </div>\n \n <form (ngSubmit)=\"dialogEditHasMany()\">\n <mat-dialog-content>\n @if (hasManyEditFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: hasManyEditFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [class.badge-changes]=\"!hasManyValidationErrors.length\"\n [disabled]=\"internalIsReadOnly || !isHasManyEntityValid || !isHasManyEntityDirty\"\n [matBadge]=\"hasManyValidationErrors.length > 0 ? hasManyValidationErrors.length : hasManyChanges.length\"\n [matBadgeHidden]=\"!hasManyValidationErrors.length && !hasManyChanges.length\"\n >\n {{metadataHasMany.tableData.editData.confirmButtonLabel}}\n </button>\n @if (hasManyValidationErrors.length || hasManyChanges.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"hasManyTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"dialogCancelEditHasMany()\">\n {{metadataHasMany.tableData.editData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>", styles: ["::ng-deep mat-tab-body{padding-top:10px;padding-left:12px;padding-right:12px}::ng-deep mat-tab-body .mat-mdc-tab-body-content{overflow:initial}::ng-deep .mat-mdc-tab-body-wrapper{margin-left:-12px;margin-right:-12px}::ng-deep .mat-mdc-form-field-has-icon-suffix .mat-mdc-text-field-wrapper{padding-right:16px}::ng-deep .select-search-input{width:100%;margin-top:-8px;margin-bottom:8px}::ng-deep .select-search-input .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mat-mdc-form-field.mat-form-field-disabled label{color:#0009}::ng-deep .mat-mdc-form-field.mat-form-field-disabled input,::ng-deep .mat-mdc-form-field.mat-form-field-disabled textarea,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-disabled,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-value{color:#000!important}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate):not([data-indeterminate=true])~.mdc-checkbox__background{border-color:#707070}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[disabled]:checked~.mdc-checkbox__background,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[disabled]:indeterminate~.mdc-checkbox__background,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[data-indeterminate=true][disabled]~.mdc-checkbox__background{background-color:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled button{opacity:.2}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--selected:disabled .mdc-switch__icons,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--unselected:disabled .mdc-switch__icons{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--selected:disabled .mdc-switch__handle:after,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--unselected:disabled .mdc-switch__handle:after{opacity:1;background:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--selected:disabled .mdc-switch__track,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--unselected:disabled .mdc-switch__track{opacity:.3}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled{opacity:1}::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled .mdc-slider__input{cursor:default}::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled mat-slider-visual-thumb .mat-mdc-slider,::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled mat-slider-visual-thumb .mdc-slider__thumb:hover,::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled mat-slider-visual-thumb .mdc-slider__thumb-knob{background-color:#000;border-color:#000}::ng-deep .mat-mdc-form-field .mat-mdc-slide-toggle{opacity:1}::ng-deep .badge-changes .mat-badge-content{background-color:orange;color:#fff}mat-spinner{margin:10px auto}.mdc-data-table__row:last-child .mdc-data-table__cell{border-bottom:1px solid rgba(0,0,0,.12)}mat-paginator{padding-top:10px;padding-bottom:10px}.dialog-button-with-info-icon{margin-top:10px;gap:12px;display:flex;align-items:center}.actions-container{display:flex;gap:10px}.w-full{width:100%}.table-with-error-slot{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:5px}.mat-column-select{flex:0 0 48px;padding-left:0;padding-right:0;justify-content:center}.enabled:hover{cursor:pointer}.table-error{display:flex;align-items:center;justify-content:center;margin-top:-6px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:fit-content;padding-left:4px;padding-right:4px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.entityArray .elevation-container{border-radius:5px;padding:15px 15px 0;margin-bottom:15px;margin-top:15px}.entityArray .array-headline{padding-bottom:10px}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px;flex-wrap:wrap;gap:10px;column-gap:24px}.entityArray .buttons button{flex:1}.hasMany button{width:100%;height:56px;line-height:24px;font-size:16px}.hasMany .title{text-align:center}.hasMany .elevation-container{margin-bottom:15px}\n", "::ng-deep .mdc-dialog .mdc-dialog__content{padding:6px 20px!important}mat-dialog-actions{justify-content:space-between;align-items:center;padding-left:20px;padding-right:20px}.mat-dialog-title{padding:12px 20px;display:flex;justify-content:space-between;align-items:center}.mat-dialog-title div{font-size:var(--mdc-dialog-subhead-size, 14px);font-weight:var(--mdc-dialog-subhead-weight, 500)}\n", ".grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.gap-x-6{column-gap:24px}.grid{display:grid}@media (min-width: 1024px){.lg\\:col-span-12{grid-column:span 12/span 12!important}.lg\\:col-span-11{grid-column:span 11/span 11!important}.lg\\:col-span-10{grid-column:span 10/span 10!important}.lg\\:col-span-9{grid-column:span 9/span 9!important}.lg\\:col-span-8{grid-column:span 8/span 8!important}.lg\\:col-span-7{grid-column:span 7/span 7!important}.lg\\:col-span-6{grid-column:span 6/span 6!important}.lg\\:col-span-5{grid-column:span 5/span 5!important}.lg\\:col-span-4{grid-column:span 4/span 4!important}.lg\\:col-span-3{grid-column:span 3/span 3!important}.lg\\:col-span-2{grid-column:span 2/span 2!important}.lg\\:col-span-1{grid-column:span 1/span 1!important}}@media (min-width: 768px) and (max-width: 1023px){.md\\:col-span-12{grid-column:span 12/span 12!important}.md\\:col-span-11{grid-column:span 11/span 11!important}.md\\:col-span-10{grid-column:span 10/span 10!important}.md\\:col-span-9{grid-column:span 9/span 9!important}.md\\:col-span-8{grid-column:span 8/span 8!important}.md\\:col-span-7{grid-column:span 7/span 7!important}.md\\:col-span-6{grid-column:span 6/span 6!important}.md\\:col-span-5{grid-column:span 5/span 5!important}.md\\:col-span-4{grid-column:span 4/span 4!important}.md\\:col-span-3{grid-column:span 3/span 3!important}.md\\:col-span-2{grid-column:span 2/span 2!important}.md\\:col-span-1{grid-column:span 1/span 1!important}}.col-span-12{grid-column:span 12/span 12}.col-span-11{grid-column:span 11/span 11}.col-span-10{grid-column:span 10/span 10}.col-span-9{grid-column:span 9/span 9}.col-span-8{grid-column:span 8/span 8}.col-span-7{grid-column:span 7/span 7}.col-span-6{grid-column:span 6/span 6}.col-span-5{grid-column:span 5/span 5}.col-span-4{grid-column:span 4/span 4}.col-span-3{grid-column:span 3/span 3}.col-span-2{grid-column:span 2/span 2}.col-span-1{grid-column:span 1/span 1}\n"], dependencies: [{ kind: "component", type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit", "validEmpty", "isReadOnly"], outputs: ["inputChangeEvent"] }, { kind: "component", type: DisplayColumnValueComponent, selector: "display-column-value", inputs: ["entity", "ComponentClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i5.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i5.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i7.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i9.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i9.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i10.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i12.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i12.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i12.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i13.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i14.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i15.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i15.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i15.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i15.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i15.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i15.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i15.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i15.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i15.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i15.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i16.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i17.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: TooltipComponent, selector: "ngx-mat-entity-tooltip", inputs: ["tooltipContent"] }, { kind: "component", type: StringInputComponent, selector: "string-input" }, { kind: "component", type: StringTextboxInputComponent, selector: "string-textbox-input" }, { kind: "component", type: StringAutocompleteInputComponent, selector: "string-autocomplete-input" }, { kind: "component", type: StringDropdownInputComponent, selector: "string-dropdown-input" }, { kind: "component", type: StringPasswordInputComponent, selector: "string-password-input" }, { kind: "component", type: BooleanCheckboxInputComponent, selector: "boolean-checkbox-input" }, { kind: "component", type: BooleanToggleInputComponent, selector: "boolean-toggle-input" }, { kind: "component", type: BooleanDropdownInputComponent, selector: "boolean-dropdown-input" }, { kind: "component", type: NumberInputComponent, selector: "number-input" }, { kind: "component", type: NumberDropdownInputComponent, selector: "number-dropdown-input" }, { kind: "component", type: NumberSliderInputComponent, selector: "number-slider-input" }, { kind: "component", type: ArrayDateInputComponent, selector: "array-date-input" }, { kind: "component", type: ArrayDateRangeInputComponent, selector: "array-date-range-input" }, { kind: "component", type: ArrayDateTimeInputComponent, selector: "array-date-time-input" }, { kind: "component", type: ArrayStringAutocompleteChipsComponent, selector: "array-string-autocomplete-chips" }, { kind: "component", type: ArrayStringChipsInputComponent, selector: "array-string-chips-input" }, { kind: "component", type: DateInputComponent, selector: "date-input" }, { kind: "component", type: DateRangeInputComponent, selector: "date-range-input" }, { kind: "component", type: DateTimeInputComponent, selector: "date-time-input" }, { kind: "component", type: FileDefaultInputComponent, selector: "file-default-input" }, { kind: "component", type: FileImageInputComponent, selector: "file-image-input" }, { kind: "component", type: ReferencesManyInputComponent, selector: "references-many-input" }, { kind: "component", type: CustomInputComponent, selector: "custom-input" }, { kind: "directive", type: DynamicStyleClassDirective, selector: "[dynamicStyleClasses]", inputs: ["dynamicStyleClasses", "value"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i18.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i18.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }] });
1271
- }
1272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.7", ngImport: i0, type: NgxMatEntityInputComponent, decorators: [{
1273
- type: Component,
1274
- args: [{ selector: 'ngx-mat-entity-input', standalone: true, imports: [
1275
- DisplayColumnValueComponent,
1276
- CommonModule,
1277
- MatTabsModule,
1278
- MatFormFieldModule,
1279
- MatSelectModule,
1280
- FormsModule,
1281
- MatDialogModule,
1282
- MatBadgeModule,
1283
- MatInputModule,
1284
- MatMenuModule,
1285
- MatPaginatorModule,
1286
- MatProgressSpinnerModule,
1287
- MatTableModule,
1288
- MatCheckboxModule,
1289
- MatButtonModule,
1290
- TooltipComponent,
1291
- StringInputComponent,
1292
- StringTextboxInputComponent,
1293
- StringAutocompleteInputComponent,
1294
- StringDropdownInputComponent,
1295
- StringPasswordInputComponent,
1296
- BooleanCheckboxInputComponent,
1297
- BooleanToggleInputComponent,
1298
- BooleanDropdownInputComponent,
1299
- NumberInputComponent,
1300
- NumberDropdownInputComponent,
1301
- NumberSliderInputComponent,
1302
- ArrayDateInputComponent,
1303
- ArrayDateRangeInputComponent,
1304
- ArrayDateTimeInputComponent,
1305
- ArrayStringAutocompleteChipsComponent,
1306
- ArrayStringChipsInputComponent,
1307
- DateInputComponent,
1308
- DateRangeInputComponent,
1309
- DateTimeInputComponent,
1310
- FileDefaultInputComponent,
1311
- FileImageInputComponent,
1312
- ReferencesManyInputComponent,
1313
- CustomInputComponent,
1314
- DynamicStyleClassDirective,
1315
- MatSortModule,
1316
- FaIconComponent
1317
- ], template: "<!-- eslint-disable angular/no-call-expression -->\n@if(!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)) {\n @switch (type) {\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.STRING) {\n <string-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-input>\n }\n @case (DecoratorTypes.STRING_TEXTBOX) {\n <string-textbox-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-textbox-input>\n }\n @case (DecoratorTypes.STRING_AUTOCOMPLETE) {\n <string-autocomplete-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-autocomplete-input>\n }\n @case (DecoratorTypes.STRING_DROPDOWN) {\n <string-dropdown-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-dropdown-input>\n }\n @case (DecoratorTypes.STRING_PASSWORD) {\n <string-password-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </string-password-input>\n }\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.BOOLEAN_CHECKBOX) {\n <boolean-checkbox-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </boolean-checkbox-input>\n }\n @case (DecoratorTypes.BOOLEAN_TOGGLE) {\n <boolean-toggle-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </boolean-toggle-input>\n }\n @case (DecoratorTypes.BOOLEAN_DROPDOWN) {\n <boolean-dropdown-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </boolean-dropdown-input>\n }\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.NUMBER) {\n <number-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </number-input>\n }\n @case (DecoratorTypes.NUMBER_DROPDOWN) {\n <number-dropdown-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </number-dropdown-input>\n }\n @case (DecoratorTypes.NUMBER_SLIDER) {\n <number-slider-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </number-slider-input>\n }\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.ARRAY_DATE) {\n <array-date-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-date-input>\n }\n @case (DecoratorTypes.ARRAY_DATE_TIME) {\n <array-date-time-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-date-time-input>\n }\n @case (DecoratorTypes.ARRAY_DATE_RANGE) {\n <array-date-range-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-date-range-input>\n }\n @case (DecoratorTypes.ARRAY_STRING_CHIPS) {\n <array-string-chips-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-string-chips-input>\n }\n @case (DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS) {\n <array-string-autocomplete-chips\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </array-string-autocomplete-chips>\n }\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.DATE) {\n <date-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </date-input>\n }\n @case (DecoratorTypes.DATE_RANGE) {\n <date-range-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </date-range-input>\n }\n @case (DecoratorTypes.DATE_TIME) {\n <date-time-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </date-time-input>\n }\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.FILE_DEFAULT) {\n <file-default-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </file-default-input>\n }\n @case (DecoratorTypes.FILE_IMAGE) {\n <file-image-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </file-image-input>\n }\n <!-------------------------------------------->\n <!-------------- references many ------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.REFERENCES_MANY) {\n <references-many-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </references-many-input>\n }\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.CUSTOM) {\n <custom-input\n [entity]=\"entity\"\n [key]=\"propertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </custom-input>\n }\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.OBJECT) {\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <ng-container *ngTemplateOutlet=\"form; context: objectFormContext\"></ng-container>\n }\n <!-------------------------------------------->\n <!---------------Object Dropdown-------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.OBJECT_DROPDOWN) {\n <mat-form-field class=\"w-full\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select #model=\"ngModel\"\n [name]=\"objectDropdownName\"\n [required]=\"metadata.required(entity)\"\n [disabled]=\"internalIsReadOnly\"\n [compareWith]=\"compareObjectsBound\"\n [(ngModel)]=\"entity[propertyKey]\"\n (selectionChange)=\"emitChange()\"\n (opened)=\"selectSearchInput.focus()\"\n >\n <mat-form-field class=\"select-search-input\">\n <!-- eslint-disable-next-line angular/no-any -->\n <input #selectSearchInput matInput (keyup)=\"filterObjectDropdownValues($any($event.target).value)\">\n <fa-icon matSuffix [icon]=\"faSearch\"></fa-icon>\n </mat-form-field>\n @if (!metadata.required(entity)) {\n <mat-option>-</mat-option>\n }\n @if (shouldDisplayCurrentObjectDropdownValue) {\n <mat-option [value]=\"currentObjectDropdownValue?.value\">{{currentObjectDropdownValue?.displayName}}</mat-option>\n }\n @for (value of filteredObjectDropdownValues; track $index) {\n <mat-option [value]=\"value.value\">{{value.displayName}}</mat-option>\n }\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n }\n <!-------------------------------------------->\n <!-------------- references one -------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.REFERENCES_ONE) {\n <mat-form-field [class.w-full]=\"metadataReferencesOne.dropdownOnly\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select #inputModel=\"ngModel\"\n [name]=\"referencesOneName\"\n [disabled]=\"internalIsReadOnly\"\n [required]=\"metadata.required(entity)\"\n [(ngModel)]=\"entity[propertyKey]\"\n (selectionChange)=\"setReferencesOneObject()\"\n (opened)=\"selectSearchInput.focus()\"\n >\n <mat-form-field class=\"select-search-input\">\n <!-- eslint-disable-next-line angular/no-any -->\n <input #selectSearchInput matInput (keyup)=\"filterReferencesOneValues($any($event.target).value)\">\n <fa-icon matSuffix [icon]=\"faSearch\"></fa-icon>\n </mat-form-field>\n @if (!metadata.required(entity)) {\n <mat-option>-</mat-option>\n }\n @if (shouldDisplayCurrentReferencesOneDropdownValue) {\n <mat-option [value]=\"currentReferencesOneDropdownValue?.value\">{{currentReferencesOneDropdownValue?.displayName}}</mat-option>\n }\n @for (value of filteredReferencesOneDropdownValues; track $index) {\n <mat-option [value]=\"value.value\">{{value.displayName}}</mat-option>\n }\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(inputModel)}}</mat-error>\n </mat-form-field>\n <!-- iterates over the references one properties -->\n @if (referencesOneFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: referencesOneFormContext\"></ng-container>\n }\n }\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.ARRAY) {\n <div class=\"entityArray\">\n <div class=\"mat-elevation-z8 elevation-container\">\n <div class=\"array-headline\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n @if (metadataEntityArray.createInline && !internalIsReadOnly) {\n @if (addArrayItemFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: addArrayItemFormContext\"></ng-container>\n }\n @else if (addArrayItemFormContext2) {\n <ng-container *ngTemplateOutlet=\"form; context: addArrayItemFormContext2\"></ng-container>\n }\n }\n @if (!internalIsReadOnly && entityArrayTableContext) {\n <div class=\"buttons\">\n <button type=\"button\" mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button\n [disabled]=\"!entityArrayTableContext.$implicit.selection.selected.length\"\n (click)=\"removeFromEntityArray()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n }\n @if (entityArrayTableContext) {\n <ng-container *ngTemplateOutlet=\"table; context: entityArrayTableContext\"></ng-container>\n }\n </div>\n </div>\n }\n <!-------------------------------------------->\n <!------------------ has many ---------------->\n <!-------------------------------------------->\n @case (DecoratorTypes.HAS_MANY) {\n <div class=\"hasMany\">\n <h2 class=\"title\">{{metadataHasMany.tableData.baseData.title}}</h2>\n <div class=\"grid grid-cols-12 gap-x-6\">\n <mat-form-field class=\"lg:col-span-8 md:col-span-6 col-span-12\">\n <mat-label>{{metadataHasMany.tableData.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyHasManyFilter($event)\">\n </mat-form-field>\n @if (metadataHasMany.tableData.baseData.tableActions.length) {\n <div\n [class.lg:col-span-2]=\"hasManyAllowCreate\"\n [class.lg:col-span-4]=\"!hasManyAllowCreate\"\n [class.md:col-span-3]=\"hasManyAllowCreate\"\n [class.md:col-span-6]=\"!hasManyAllowCreate\"\n [class.col-span-6]=\"hasManyAllowCreate\"\n [class.col-span-12]=\"!hasManyAllowCreate\"\n >\n <button type=\"button\" class=\"actions-button\" mat-raised-button [matMenuTriggerFor]=\"menu\">\n {{metadataHasMany.tableData.baseData.tableActionsLabel}}\n </button>\n </div>\n }\n <mat-menu #menu=\"matMenu\">\n @if (metadataHasMany.tableData.baseData.allowJsonImport) {\n <button type=\"button\" mat-menu-item [disabled]=\"hasManyTableActionDisabled(hasManyImportAction)\" (click)=\"runHasManyTableAction(hasManyImportAction)\">\n {{hasManyImportAction.displayName}}\n </button>\n }\n @for (action of metadataHasMany.tableData.baseData.tableActions; track $index) {\n <button type=\"button\" mat-menu-item [disabled]=\"hasManyTableActionDisabled(action)\" (click)=\"runHasManyTableAction(action)\">\n {{action.displayName}}\n </button>\n }\n </mat-menu>\n @if (hasManyAllowCreate) {\n <div\n [class.lg:col-span-2]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.lg:col-span-4]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.md:col-span-3]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.md:col-span-6]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-span-6]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-span-12]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n >\n <button type=\"button\" class=\"create-button\" mat-raised-button (click)=\"createHasManyEntity()\">\n {{metadataHasMany.tableData.baseData.createButtonLabel}}\n </button>\n </div>\n }\n </div>\n \n <div class=\"mat-elevation-z8 elevation-container\">\n @if (hasManyTableContext) {\n <ng-container *ngTemplateOutlet=\"table; context: hasManyTableContext\"></ng-container>\n }\n </div>\n </div>\n }\n \n @default {\n <div>ERROR: The type {{type}} is not known.</div>\n }\n }\n}\n\n\n<ng-template #table let-context>\n <mat-table matSort [dataSource]=\"context.dataSource\" [class.table-with-error-slot]=\"context.shouldShowMissingError\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [checked]=\"context.selection.hasValue() && SelectionUtilities.isAllSelected(context.selection, context.dataSource)\"\n [indeterminate]=\"context.selection.hasValue() && !SelectionUtilities.isAllSelected(context.selection, context.dataSource)\"\n (change)=\"$event ? SelectionUtilities.masterToggle(context.selection, context.dataSource) : null\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let value\" [dynamicStyleClasses]=\"context.dynamicRowStyleClasses\" [value]=\"value\">\n <mat-checkbox [checked]=\"context.selection.isSelected(value)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? context.selection.toggle(value) : null\">\n </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n @for (dCol of context.displayColumns; track $index) {\n <ng-container [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell *matCellDef=\"let value\" [class.enabled]=\"!dCol.disableClick && context.allowClick(value)\"\n [dynamicStyleClasses]=\"context.dynamicRowStyleClasses\" [value]=\"value\"\n (click)=\"clickCell(value, dCol, context)\"\n >\n @if (dCol.Component) {\n <display-column-value [entity]=\"value\" [ComponentClass]=\"dCol.Component\"></display-column-value>\n }\n @else {\n {{getDisplayColumnValue(value, dCol)}}\n }\n </mat-cell>\n </ng-container>\n }\n\n <mat-header-row *matHeaderRowDef=\"context.displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: context.displayedColumns\"></mat-row>\n </mat-table>\n\n @if (context.displayLoadingSpinner && context.isLoading) {\n <mat-spinner>\n </mat-spinner>\n }\n @else if (context.shouldShowMissingError && !context.dataSource.data.length) {\n <div class=\"table-error\">{{context.emptyErrorMessage}}</div>\n }\n\n <mat-paginator [length]=\"context.dataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"></mat-paginator>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!---------------------------Form-------------------------->\n<!--------------------------------------------------------->\n<ng-template #form let-context>\n <!-- eslint-disable angular/no-call-expression -->\n @if (context.tabs.length > 1) {\n <mat-tab-group preserveContent>\n @for (tab of context.tabs; track $index) {\n <mat-tab [label]=\"tab.tabName\">\n @for (row of tab.rows; track $index) {\n <div class=\"grid grid-cols-12 gap-x-6\">\n @for (key of row.keys; track key) {\n <ngx-mat-entity-input\n [entity]=\"context.entity\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [validEmpty]=\"context.validEmpty?.()\"\n [isReadOnly]=\"context.isReadOnly?.(context.entity, key)\"\n [class]=\"EntityUtilities.getWidthClasses(context.entity, key)\"\n [hideOmitForEdit]=\"context.hideOmitForEdit\"\n [hideOmitForCreate]=\"context.hideOmitForCreate\"\n (inputChangeEvent)=\"context.inputChangeEvent()\"\n >\n </ngx-mat-entity-input>\n }\n </div>\n }\n </mat-tab>\n }\n </mat-tab-group>\n }\n @else {\n @if (!context.tabs.length) {\n <span class=\"no-entity-tabs\">\n ERROR: No Inputs. Did you correctly assign all values in the model constructor?\n </span>\n }\n @else {\n @for (row of context.tabs[0].rows; track $index) {\n <div class=\"grid grid-cols-12 gap-x-6\">\n @for (key of row.keys; track key) {\n <ngx-mat-entity-input\n [entity]=\"context.entity\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [validEmpty]=\"context.validEmpty?.()\"\n [isReadOnly]=\"context.isReadOnly?.(context.entity, key)\"\n [class]=\"EntityUtilities.getWidthClasses(context.entity, key)\"\n [hideOmitForEdit]=\"context.hideOmitForEdit\"\n [hideOmitForCreate]=\"context.hideOmitForCreate\"\n (inputChangeEvent)=\"context.inputChangeEvent()\"\n >\n </ngx-mat-entity-input>\n }\n </div>\n }\n }\n }\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{addArrayItemDialogData.title}}</div>\n </div>\n\n <form (ngSubmit)=\"addArrayItem()\">\n <mat-dialog-content>\n @if (addArrayItemFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: addArrayItemFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [disabled]=\"!isArrayItemValid\"\n [matBadge]=\"arrayItemValidationErrors.length\"\n [matBadgeHidden]=\"!arrayItemValidationErrors.length\"\n >\n {{addArrayItemDialogData.createButtonLabel}}\n </button>\n @if (arrayItemValidationErrors.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"arrayItemTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"closeAddArrayItemDialog()\">\n {{addArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #editArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{editArrayItemDialogData.title(arrayItemPriorChanges)}}</div>\n </div>\n \n <form (ngSubmit)=\"saveArrayItem()\">\n <mat-dialog-content>\n @if (editArrayItemFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: editArrayItemFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [class.badge-changes]=\"!arrayItemValidationErrors.length\"\n [disabled]=\"internalIsReadOnly || !isArrayItemValid || !isArrayItemDirty\"\n [matBadge]=\"arrayItemValidationErrors.length > 0 ? arrayItemValidationErrors.length : arrayItemChanges.length\"\n [matBadgeHidden]=\"!arrayItemValidationErrors.length && !arrayItemChanges.length\"\n >\n {{editArrayItemDialogData.confirmButtonLabel}}\n </button>\n @if (arrayItemValidationErrors.length || arrayItemChanges.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"arrayItemTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"closeEditArrayItemDialog()\">\n {{editArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Create Has Many Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #createHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.createData.title}}</div>\n </div>\n \n <form (ngSubmit)=\"dialogCreateHasMany()\">\n <mat-dialog-content>\n @if (hasManyCreateFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: hasManyCreateFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [disabled]=\"!isHasManyEntityValid\"\n [matBadge]=\"hasManyValidationErrors.length\"\n [matBadgeHidden]=\"!hasManyValidationErrors.length\"\n >\n {{metadataHasMany.tableData.createData.createButtonLabel}}\n </button>\n @if (hasManyValidationErrors.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"hasManyTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"dialogCancelCreateHasMany()\">\n {{metadataHasMany.tableData.createData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n \n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Has Many Dialog----------------->\n<!--------------------------------------------------------->\n<ng-template #editHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.editData.title(hasManyEntityPriorChanges)}}</div>\n\n <div class=\"actions-container\">\n @if (metadataHasMany.tableData.editData.actions.length) {\n <button type=\"button\" mat-raised-button [matMenuTriggerFor]=\"menu\">\n {{metadataHasMany.tableData.editData.actionsLabel}}\n </button>\n }\n <mat-menu #menu=\"matMenu\">\n @for (action of metadataHasMany.tableData.editData.actions; track $index) {\n <button type=\"button\" mat-menu-item [disabled]=\"hasManyEditActionDisabled(action)\" (click)=\"hasManyRunEditAction(action)\">\n {{action.displayName}}\n </button>\n }\n </mat-menu>\n \n @if (hasManyAllowDelete(hasManyEntity)) {\n <button type=\"button\" mat-raised-button color=\"warn\" class=\"delete-button\" tabindex=\"-1\" (click)=\"deleteHasManyEntity()\">\n {{metadataHasMany.tableData.editData.deleteButtonLabel}}\n </button>\n }\n </div>\n </div>\n \n <form (ngSubmit)=\"dialogEditHasMany()\">\n <mat-dialog-content>\n @if (hasManyEditFormContext) {\n <ng-container *ngTemplateOutlet=\"form; context: hasManyEditFormContext\"></ng-container>\n }\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <div class=\"dialog-button-with-info-icon\">\n <button type=\"submit\" mat-raised-button matBadgeColor=\"warn\"\n [class.badge-changes]=\"!hasManyValidationErrors.length\"\n [disabled]=\"internalIsReadOnly || !isHasManyEntityValid || !isHasManyEntityDirty\"\n [matBadge]=\"hasManyValidationErrors.length > 0 ? hasManyValidationErrors.length : hasManyChanges.length\"\n [matBadgeHidden]=\"!hasManyValidationErrors.length && !hasManyChanges.length\"\n >\n {{metadataHasMany.tableData.editData.confirmButtonLabel}}\n </button>\n @if (hasManyValidationErrors.length || hasManyChanges.length) {\n <ngx-mat-entity-tooltip [tooltipContent]=\"hasManyTooltipContent\"></ngx-mat-entity-tooltip>\n }\n </div>\n <button type=\"button\" mat-raised-button class=\"cancel-button\" (click)=\"dialogCancelEditHasMany()\">\n {{metadataHasMany.tableData.editData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>", styles: ["::ng-deep mat-tab-body{padding-top:10px;padding-left:12px;padding-right:12px}::ng-deep mat-tab-body .mat-mdc-tab-body-content{overflow:initial}::ng-deep .mat-mdc-tab-body-wrapper{margin-left:-12px;margin-right:-12px}::ng-deep .mat-mdc-form-field-has-icon-suffix .mat-mdc-text-field-wrapper{padding-right:16px}::ng-deep .select-search-input{width:100%;margin-top:-8px;margin-bottom:8px}::ng-deep .select-search-input .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mat-mdc-form-field.mat-form-field-disabled label{color:#0009}::ng-deep .mat-mdc-form-field.mat-form-field-disabled input,::ng-deep .mat-mdc-form-field.mat-form-field-disabled textarea,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-disabled,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-value{color:#000!important}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate):not([data-indeterminate=true])~.mdc-checkbox__background{border-color:#707070}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[disabled]:checked~.mdc-checkbox__background,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[disabled]:indeterminate~.mdc-checkbox__background,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-checkbox .mdc-checkbox__native-control[data-indeterminate=true][disabled]~.mdc-checkbox__background{background-color:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled button{opacity:.2}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--selected:disabled .mdc-switch__icons,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--unselected:disabled .mdc-switch__icons{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--selected:disabled .mdc-switch__handle:after,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--unselected:disabled .mdc-switch__handle:after{opacity:1;background:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--selected:disabled .mdc-switch__track,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mdc-switch.mdc-switch--unselected:disabled .mdc-switch__track{opacity:.3}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled{opacity:1}::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled .mdc-slider__input{cursor:default}::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled mat-slider-visual-thumb .mat-mdc-slider,::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled mat-slider-visual-thumb .mdc-slider__thumb:hover,::ng-deep #slider.mat-mdc-slider.mdc-slider--disabled mat-slider-visual-thumb .mdc-slider__thumb-knob{background-color:#000;border-color:#000}::ng-deep .mat-mdc-form-field .mat-mdc-slide-toggle{opacity:1}::ng-deep .badge-changes .mat-badge-content{background-color:orange;color:#fff}mat-spinner{margin:10px auto}.mdc-data-table__row:last-child .mdc-data-table__cell{border-bottom:1px solid rgba(0,0,0,.12)}mat-paginator{padding-top:10px;padding-bottom:10px}.dialog-button-with-info-icon{margin-top:10px;gap:12px;display:flex;align-items:center}.actions-container{display:flex;gap:10px}.w-full{width:100%}.table-with-error-slot{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:5px}.mat-column-select{flex:0 0 48px;padding-left:0;padding-right:0;justify-content:center}.enabled:hover{cursor:pointer}.table-error{display:flex;align-items:center;justify-content:center;margin-top:-6px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:fit-content;padding-left:4px;padding-right:4px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.entityArray .elevation-container{border-radius:5px;padding:15px 15px 0;margin-bottom:15px;margin-top:15px}.entityArray .array-headline{padding-bottom:10px}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px;flex-wrap:wrap;gap:10px;column-gap:24px}.entityArray .buttons button{flex:1}.hasMany button{width:100%;height:56px;line-height:24px;font-size:16px}.hasMany .title{text-align:center}.hasMany .elevation-container{margin-bottom:15px}\n", "::ng-deep .mdc-dialog .mdc-dialog__content{padding:6px 20px!important}mat-dialog-actions{justify-content:space-between;align-items:center;padding-left:20px;padding-right:20px}.mat-dialog-title{padding:12px 20px;display:flex;justify-content:space-between;align-items:center}.mat-dialog-title div{font-size:var(--mdc-dialog-subhead-size, 14px);font-weight:var(--mdc-dialog-subhead-weight, 500)}\n", ".grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.gap-x-6{column-gap:24px}.grid{display:grid}@media (min-width: 1024px){.lg\\:col-span-12{grid-column:span 12/span 12!important}.lg\\:col-span-11{grid-column:span 11/span 11!important}.lg\\:col-span-10{grid-column:span 10/span 10!important}.lg\\:col-span-9{grid-column:span 9/span 9!important}.lg\\:col-span-8{grid-column:span 8/span 8!important}.lg\\:col-span-7{grid-column:span 7/span 7!important}.lg\\:col-span-6{grid-column:span 6/span 6!important}.lg\\:col-span-5{grid-column:span 5/span 5!important}.lg\\:col-span-4{grid-column:span 4/span 4!important}.lg\\:col-span-3{grid-column:span 3/span 3!important}.lg\\:col-span-2{grid-column:span 2/span 2!important}.lg\\:col-span-1{grid-column:span 1/span 1!important}}@media (min-width: 768px) and (max-width: 1023px){.md\\:col-span-12{grid-column:span 12/span 12!important}.md\\:col-span-11{grid-column:span 11/span 11!important}.md\\:col-span-10{grid-column:span 10/span 10!important}.md\\:col-span-9{grid-column:span 9/span 9!important}.md\\:col-span-8{grid-column:span 8/span 8!important}.md\\:col-span-7{grid-column:span 7/span 7!important}.md\\:col-span-6{grid-column:span 6/span 6!important}.md\\:col-span-5{grid-column:span 5/span 5!important}.md\\:col-span-4{grid-column:span 4/span 4!important}.md\\:col-span-3{grid-column:span 3/span 3!important}.md\\:col-span-2{grid-column:span 2/span 2!important}.md\\:col-span-1{grid-column:span 1/span 1!important}}.col-span-12{grid-column:span 12/span 12}.col-span-11{grid-column:span 11/span 11}.col-span-10{grid-column:span 10/span 10}.col-span-9{grid-column:span 9/span 9}.col-span-8{grid-column:span 8/span 8}.col-span-7{grid-column:span 7/span 7}.col-span-6{grid-column:span 6/span 6}.col-span-5{grid-column:span 5/span 5}.col-span-4{grid-column:span 4/span 4}.col-span-3{grid-column:span 3/span 3}.col-span-2{grid-column:span 2/span 2}.col-span-1{grid-column:span 1/span 1}\n"] }]
1318
- }], ctorParameters: () => [{ type: i1.MatDialog }, { type: i0.EnvironmentInjector }, { type: i2.Router }, { type: undefined, decorators: [{
1319
- type: Inject,
1320
- args: [NGX_GET_VALIDATION_ERROR_MESSAGE]
1321
- }] }, { type: undefined, decorators: [{
1322
- type: Inject,
1323
- args: [NGX_COMPLETE_GLOBAL_DEFAULT_VALUES]
1324
- }] }, { type: i3.HttpClient }], propDecorators: { entity: [{
1325
- type: Input,
1326
- args: [{ required: true }]
1327
- }], propertyKey: [{
1328
- type: Input,
1329
- args: [{ required: true }]
1330
- }], getValidationErrorMessage: [{
1331
- type: Input
1332
- }], hideOmitForCreate: [{
1333
- type: Input
1334
- }], hideOmitForEdit: [{
1335
- type: Input
1336
- }], validEmpty: [{
1337
- type: Input
1338
- }], isReadOnly: [{
1339
- type: Input
1340
- }], inputChangeEvent: [{
1341
- type: Output
1342
- }], sort: [{
1343
- type: ViewChild,
1344
- args: [MatSort]
1345
- }], paginator: [{
1346
- type: ViewChild,
1347
- args: [MatPaginator]
1348
- }], addArrayItemDialog: [{
1349
- type: ViewChild,
1350
- args: ['addArrayItemDialog']
1351
- }], editArrayItemDialog: [{
1352
- type: ViewChild,
1353
- args: ['editArrayItemDialog']
1354
- }], createHasManyDialog: [{
1355
- type: ViewChild,
1356
- args: ['createHasManyDialog']
1357
- }], editHasManyDialog: [{
1358
- type: ViewChild,
1359
- args: ['editHasManyDialog']
1360
- }] } });
1361
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW1hdGVyaWFsLWVudGl0eS9zcmMvY29tcG9uZW50cy9pbnB1dC9pbnB1dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbWF0ZXJpYWwtZW50aXR5L3NyYy9jb21wb25lbnRzL2lucHV0L2lucHV0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25LLE9BQU8sRUFBRSxXQUFXLEVBQVcsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFnQixNQUFNLDBCQUEwQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxF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QzVCLG9CQUFvQjt3QkFDcEIsMEJBQTBCO3dCQUMxQixhQUFhO3dCQUNiLGVBQWU7cUJBQ2xCOzswQkE0VkksTUFBTTsyQkFBQyxnQ0FBZ0M7OzBCQUV2QyxNQUFNOzJCQUFDLGtDQUFrQztrRUFsVjlDLE1BQU07c0JBREwsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBT3pCLFdBQVc7c0JBRFYsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBT3pCLHlCQUF5QjtzQkFEeEIsS0FBSztnQkFXTixpQkFBaUI7c0JBRGhCLEtBQUs7Z0JBU04sZUFBZTtzQkFEZCxLQUFLO2dCQVNOLFVBQVU7c0JBRFQsS0FBSztnQkFTTixVQUFVO3NCQURULEtBQUs7Z0JBU0csZ0JBQWdCO3NCQUR4QixNQUFNO2dCQVNLLElBQUk7c0JBRGYsU0FBUzt1QkFBQyxPQUFPO2dCQWdCTixTQUFTO3NCQURwQixTQUFTO3VCQUFDLFlBQVk7Z0JBb0VOLGtCQUFrQjtzQkFEbEMsU0FBUzt1QkFBQyxvQkFBb0I7Z0JBSWQsbUJBQW1CO3NCQURuQyxTQUFTO3VCQUFDLHFCQUFxQjtnQkE0RWYsbUJBQW1CO3NCQURuQyxTQUFTO3VCQUFDLHFCQUFxQjtnQkFJZixpQkFBaUI7c0JBRGpDLFNBQVM7dUJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2VsZWN0aW9uTW9kZWwgfSBmcm9tICdAYW5ndWxhci9jZGsvY29sbGVjdGlvbnMnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBDb21wb25lbnQsIEVudmlyb25tZW50SW5qZWN0b3IsIEV2ZW50RW1pdHRlciwgSW5qZWN0LCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQsIGluamVjdCwgcnVuSW5JbmplY3Rpb25Db250ZXh0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSwgTmdNb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdEJhZGdlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYmFkZ2UnO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdENoZWNrYm94TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY2hlY2tib3gnO1xuaW1wb3J0IHsgTWF0RGlhbG9nLCBNYXREaWFsb2dNb2R1bGUsIE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdElucHV0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgTWF0TWVudU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL21lbnUnO1xuaW1wb3J0IHsgTWF0UGFnaW5hdG9yLCBNYXRQYWdpbmF0b3JNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wYWdpbmF0b3InO1xuaW1wb3J0IHsgTWF0UHJvZ3Jlc3NTcGlubmVyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcHJvZ3Jlc3Mtc3Bpbm5lcic7XG5pbXBvcnQgeyBNYXRTZWxlY3RNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0U29ydCwgTWF0U29ydE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NvcnQnO1xuaW1wb3J0IHsgTWF0VGFibGVEYXRhU291cmNlLCBNYXRUYWJsZU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYmxlJztcbmltcG9ydCB7IE1hdFRhYnNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBGYUljb25Db21wb25lbnQsIEljb25EZWZpbml0aW9uIH0gZnJvbSAnQGZvcnRhd2Vzb21lL2FuZ3VsYXItZm9udGF3ZXNvbWUnO1xuaW1wb3J0IHsgZmFTZWFyY2ggfSBmcm9tICdAZm9ydGF3ZXNvbWUvZnJlZS1zb2xpZC1zdmctaWNvbnMnO1xuaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQXJyYXlEYXRlSW5wdXRDb21wb25lbnQgfSBmcm9tICcuL2FycmF5L2FycmF5LWRhdGUtaW5wdXQvYXJyYXktZGF0ZS1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgQXJyYXlEYXRlUmFuZ2VJbnB1dENvbXBvbmVudCB9IGZyb20gJy4vYXJyYXkvYXJyYXktZGF0ZS1yYW5nZS1pbnB1dC9hcnJheS1kYXRlLXJhbmdlLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBcnJheURhdGVUaW1lSW5wdXRDb21wb25lbnQgfSBmcm9tICcuL2FycmF5L2FycmF5LWRhdGUtdGltZS1pbnB1dC9hcnJheS1kYXRlLXRpbWUtaW5wdXQuY29tcG9uZW50JztcbmltcG9ydCB7IEFycmF5U3RyaW5nQXV0b2NvbXBsZXRlQ2hpcHNDb21wb25lbnQgfSBmcm9tICcuL2FycmF5L2FycmF5LXN0cmluZy1hdXRvY29tcGxldGUtY2hpcHMvYXJyYXktc3RyaW5nLWF1dG9jb21wbGV0ZS1jaGlwcy5jb21wb25lbnQnO1xuaW1wb3J0IHsgQXJyYXlTdHJpbmdDaGlwc0lucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9hcnJheS9hcnJheS1zdHJpbmctY2hpcHMtaW5wdXQvYXJyYXktc3RyaW5nLWNoaXBzLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCb29sZWFuQ2hlY2tib3hJbnB1dENvbXBvbmVudCB9IGZyb20gJy4vYm9vbGVhbi9ib29sZWFuLWNoZWNrYm94LWlucHV0L2Jvb2xlYW4tY2hlY2tib3gtaW5wdXQuY29tcG9uZW50JztcbmltcG9ydCB7IEJvb2xlYW5Ecm9wZG93bklucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9ib29sZWFuL2Jvb2xlYW4tZHJvcGRvd24taW5wdXQvYm9vbGVhbi1kcm9wZG93bi1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgQm9vbGVhblRvZ2dsZUlucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9ib29sZWFuL2Jvb2xlYW4tdG9nZ2xlLWlucHV0L2Jvb2xlYW4tdG9nZ2xlLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDdXN0b21JbnB1dENvbXBvbmVudCB9IGZyb20gJy4vY3VzdG9tL2N1c3RvbS5jb21wb25lbnQnO1xuaW1wb3J0IHsgRGF0ZUlucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9kYXRlL2RhdGUtaW5wdXQvZGF0ZS1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgRGF0ZVJhbmdlSW5wdXRDb21wb25lbnQgfSBmcm9tICcuL2RhdGUvZGF0ZS1yYW5nZS1pbnB1dC9kYXRlLXJhbmdlLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEYXRlVGltZUlucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9kYXRlL2RhdGUtdGltZS1pbnB1dC9kYXRlLXRpbWUtaW5wdXQuY29tcG9uZW50JztcbmltcG9ydCB7IEZpbGVEZWZhdWx0SW5wdXRDb21wb25lbnQgfSBmcm9tICcuL2ZpbGUvZmlsZS1kZWZhdWx0LWlucHV0L2ZpbGUtZGVmYXVsdC1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgRmlsZUltYWdlSW5wdXRDb21wb25lbnQgfSBmcm9tICcuL2ZpbGUvZmlsZS1pbWFnZS1pbnB1dC9maWxlLWltYWdlLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOdW1iZXJEcm9wZG93bklucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9udW1iZXIvbnVtYmVyLWRyb3Bkb3duLWlucHV0L251bWJlci1kcm9wZG93bi1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgTnVtYmVySW5wdXRDb21wb25lbnQgfSBmcm9tICcuL251bWJlci9udW1iZXItaW5wdXQvbnVtYmVyLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOdW1iZXJTbGlkZXJJbnB1dENvbXBvbmVudCB9IGZyb20gJy4vbnVtYmVyL251bWJlci1zbGlkZXItaW5wdXQvbnVtYmVyLXNsaWRlci1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVmZXJlbmNlc01hbnlJbnB1dENvbXBvbmVudCB9IGZyb20gJy4vcmVsYXRpb25zL3JlZmVyZW5jZXMtbWFueS1pbnB1dC9yZWZlcmVuY2VzLW1hbnktaW5wdXQuY29tcG9uZW50JztcbmltcG9ydCB7IFN0cmluZ0F1dG9jb21wbGV0ZUlucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9zdHJpbmcvc3RyaW5nLWF1dG9jb21wbGV0ZS1pbnB1dC9zdHJpbmctYXV0b2NvbXBsZXRlLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdHJpbmdEcm9wZG93bklucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9zdHJpbmcvc3RyaW5nLWRyb3Bkb3duLWlucHV0L3N0cmluZy1kcm9wZG93bi1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3RyaW5nSW5wdXRDb21wb25lbnQgfSBmcm9tICcuL3N0cmluZy9zdHJpbmctaW5wdXQvc3RyaW5nLWlucHV0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdHJpbmdQYXNzd29yZElucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9zdHJpbmcvc3RyaW5nLXBhc3N3b3JkLWlucHV0L3N0cmluZy1wYXNzd29yZC1pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3RyaW5nVGV4dGJveElucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9zdHJpbmcvc3RyaW5nLXRleHRib3gtaW5wdXQvc3RyaW5nLXRleHRib3gtaW5wdXQuY29tcG9uZW50JztcbmltcG9ydCB7IEJhc2VFbnRpdHlUeXBlIH0gZnJvbSAnLi4vLi4vY2xhc3Nlcy9lbnRpdHkubW9kZWwnO1xuaW1wb3J0IHsgRWRpdEFycmF5SXRlbURpYWxvZ0RhdGFJbnRlcm5hbCwgRW50aXR5QXJyYXlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCB9IGZyb20gJy4uLy4uL2RlY29yYXRvcnMvYXJyYXkvYXJyYXktZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgRGVjb3JhdG9yVHlwZXMgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL2Jhc2UvZGVjb3JhdG9yLXR5cGVzLmVudW0nO1xuaW1wb3J0IHsgRHJvcGRvd25WYWx1ZSB9IGZyb20gJy4uLy4uL2RlY29yYXRvcnMvYmFzZS9kcm9wZG93bi12YWx1ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCB9IGZyb20gJy4uLy4uL2RlY29yYXRvcnMvYmFzZS9wcm9wZXJ0eS1kZWNvcmF0b3ItaW50ZXJuYWwuZGF0YSc7XG5pbXBvcnQgeyBIYXNNYW55RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL2hhcy1tYW55L2hhcy1tYW55LWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IERlZmF1bHRPYmplY3REZWNvcmF0b3JDb25maWdJbnRlcm5hbCwgRHJvcGRvd25PYmplY3REZWNvcmF0b3JDb25maWdJbnRlcm5hbCB9IGZyb20gJy4uLy4uL2RlY29yYXRvcnMvb2JqZWN0L29iamVjdC1kZWNvcmF0b3ItaW50ZXJuYWwuZGF0YSc7XG5pbXBvcnQgeyBSZWZlcmVuY2VzT25lRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL3JlZmVyZW5jZXMtb25lL3JlZmVyZW5jZXMtb25lLWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IER5bmFtaWNTdHlsZUNsYXNzRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9keW5hbWljLXN0eWxlLWNsYXNzLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMb2Rhc2hVdGlsaXRpZXMgfSBmcm9tICcuLi8uLi9lbmNhcHN1bGF0aW9uL2xvZGFzaC51dGlsaXRpZXMnO1xuaW1wb3J0IHsgUmVmbGVjdFV0aWxpdGllcyB9IGZyb20gJy4uLy4uL2VuY2Fwc3VsYXRpb24vcmVmbGVjdC51dGlsaXRpZXMnO1xuaW1wb3J0IHsgVVVJRFV0aWxpdGllcyB9IGZyb20gJy4uLy4uL2VuY2Fwc3VsYXRpb24vdXVpZC51dGlsaXRpZXMnO1xuaW1wb3J0IHsgZGVmYXVsdEZhbHNlIH0gZnJvbSAnLi4vLi4vZnVuY3Rpb25zL2RlZmF1bHQtZmFsc2UuZnVuY3Rpb24nO1xuaW1wb3J0IHsgZ2V0Q2hhbmdlc1Rvb2x0aXBDb250ZW50IH0gZnJvbSAnLi4vLi4vZnVuY3Rpb25zL2dldC1jaGFuZ2VzLXRvb2x0aXAtY29udGVudC5mdW5jdGlvbic7XG5pbXBvcnQgeyBOR1hfR0VUX1ZBTElEQVRJT05fRVJST1JfTUVTU0FHRSB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9nZXQtdmFsaWRhdGlvbi1lcnJvci1tZXNzYWdlLmZ1bmN0aW9uJztcbmltcG9ydCB7IGdldFZhbGlkYXRpb25FcnJvcnNUb29sdGlwQ29udGVudCB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9nZXQtdmFsaWRhdGlvbi1lcnJvcnMtdG9vbHRpcC1jb250ZW50LmZ1bmN0aW9uJztcbmltcG9ydCB7IHRhYmxlQ29sdW1uVmFsdWVUb1NvcnRWYWx1ZSB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy90YWJsZS1jb2x1bW4tdmFsdWUtdG8tc29ydC12YWx1ZS5mdW5jdGlvbic7XG5pbXBvcnQgeyBOR1hfQ09NUExFVEVfR0xPQkFMX0RFRkFVTFRfVkFMVUVTLCBOZ3hHbG9iYWxEZWZhdWx0VmFsdWVzIH0gZnJvbSAnLi4vLi4vZ2xvYmFsLWNvbmZpZ3VyYXRpb24tdmFsdWVzJztcbmltcG9ydCB7IEVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9lbnRpdHkuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlVXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2RhdGUudXRpbGl0aWVzJztcbmltcG9ydCB7IERpZmZlcmVuY2UsIEVudGl0eVRhYiwgRW50aXR5VXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2VudGl0eS51dGlsaXRpZXMnO1xuaW1wb3J0IHsgU2VsZWN0aW9uVXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL3NlbGVjdGlvbi51dGlsaXRpZXMnO1xuaW1wb3J0IHsgVmFsaWRhdGlvbkVycm9yLCBWYWxpZGF0aW9uVXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL3ZhbGlkYXRpb24udXRpbGl0aWVzJztcbmltcG9ydCB7IENvbmZpcm1EaWFsb2dEYXRhQnVpbGRlciwgQ29uZmlybURpYWxvZ0RhdGFJbnRlcm5hbCB9IGZyb20gJy4uL2NvbmZpcm0tZGlhbG9nL2NvbmZpcm0tZGlhbG9nLWRhdGEuYnVpbGRlcic7XG5pbXBvcnQgeyBOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vY29uZmlybS1kaWFsb2cvY29uZmlybS1kaWFsb2cuY29tcG9uZW50JztcbmltcG9ydCB7IEludGVybmFsQ3VzdG9tVGFibGVDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vY3VzdG9tLXRhYmxlL2N1c3RvbS10YWJsZS1jb25maWd1cmF0aW9uLm1vZGVsJztcbmltcG9ydCB7IENyZWF0ZURhdGFCdWlsZGVyLCBDcmVhdGVEYXRhSW50ZXJuYWwgfSBmcm9tICcuLi90YWJsZS9jcmVhdGUtZGlhbG9nL2NyZWF0ZS1kYXRhLmJ1aWxkZXInO1xuaW1wb3J0IHsgRGlzcGxheUNvbHVtblZhbHVlQ29tcG9uZW50IH0gZnJvbSAnLi4vdGFibGUvZGlzcGxheS1jb2x1bW4tdmFsdWUvZGlzcGxheS1jb2x1bW4tdmFsdWUuY29tcG9uZW50JztcbmltcG9ydCB7IEVkaXRBY3Rpb25JbnRlcm5hbCB9IGZyb20gJy4uL3RhYmxlL2VkaXQtZGlhbG9nL2VkaXQtZGF0YS5idWlsZGVyJztcbmltcG9ydCB7IERpc3BsYXlDb2x1bW4sIER5bmFtaWNTdHlsZUNsYXNzZXMgfSBmcm9tICcuLi90YWJsZS90YWJsZS1kYXRhJztcbmltcG9ydCB7IEJhc2VUYWJsZUFjdGlvbkludGVybmFsLCBUYWJsZUFjdGlvbkludGVybmFsIH0gZnJvbSAnLi4vdGFibGUvdGFibGUtZGF0YS5idWlsZGVyJztcbmltcG9ydCB7IFRvb2x0aXBDb21wb25lbnQgfSBmcm9tICcuLi90b29sdGlwL3Rvb2x0aXAuY29tcG9uZW50JztcblxuLyoqXG4gKiBHZW5lcmljIHR5cGUgZm9yIGNvbnRleHRzIHRoYXQgY2FuIGZpbGwgYW4gaW5saW5lIHRlbXBsYXRlLlxuICovXG50eXBlIFRlbXBsYXRlQ29udGV4dDxUPiA9IHtcbiAgICAvKipcbiAgICAgKiBUaGUgYWN0dWFsIHZhbHVlLiBUaGUgJGltcGxpY2l0IGlzIG5lZWRlZCBzbyB0aGF0IHdlIGRvbid0IG5lZWQgdG8gc3BlY2lmeSBhIGtleSB3aGVuIHdyaXRpbmcgXCJsZXQtY29udGV4dFwiIGluIHRoZSBodG1sIHRlbXBsYXRlLlxuICAgICAqL1xuICAgICRpbXBsaWNpdDogVFxufTtcblxuLyoqXG4gKiBBIGZvcm0gY29udGV4dCB0aGF0IGlzIHVzZWQgdG8gZmlsbCBhbiBpbmxpbmUgdGVtcGxhdGUuXG4gKiBUaGlzIGlzIHVzZWQgdG8gZ28gYXJvdW5kIHRoZSBsaW1pdGF0aW9ucyBvZiBoYXZpbmcgZXZlcnl0aGluZyBpbiB0aGUgc2FtZSBmaWxlIGR1ZSB0byBjaXJjdWxhciBkZXBlbmRlbmNpZXMuXG4gKiBUaGUgZm9ybXMgYXJlIHVzZWQgZm9yIG9iamVjdCwgaGFzTWFueSwgcmVmZXJlbmNlc01hbnkgYW5kIHRoZSBkaWFsb2dzLlxuICovXG50eXBlIEZvcm1Db250ZXh0PEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4gPSB7XG4gICAgLyoqXG4gICAgICogVGhlIGVudGl0eSB0byBidWlsZCB0aGUgZm9ybSBmb3IuXG4gICAgICovXG4gICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgIC8qKlxuICAgICAqIFRoZSB0YWJzIHRvIGRpc3BsYXkuXG4gICAgICovXG4gICAgdGFiczogRW50aXR5VGFiPEVudGl0eVR5cGU+W10sXG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgZWRpdCB2YWx1ZXMgc2hvdWxkIGJlIG9taXR0ZWQuXG4gICAgICovXG4gICAgaGlkZU9taXRGb3JFZGl0PzogYm9vbGVhbixcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCBjcmVhdGUgdmFsdWVzIHNob3VsZCBiZSBvbWl0dGVkLlxuICAgICAqL1xuICAgIGhpZGVPbWl0Rm9yQ3JlYXRlPzogYm9vbGVhbixcbiAgICAvKipcbiAgICAgKiBXaGF0IGhhcHBlbnMgd2hlbiB0aGUgaW5wdXQgY2hhbmdlcy5cbiAgICAgKi9cbiAgICBpbnB1dENoYW5nZUV2ZW50OiAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgaW5wdXQgaXMgcmVhZG9ubHkuXG4gICAgICovXG4gICAgaXNSZWFkT25seT86IChwcm9wZXJ0eTogRW50aXR5VHlwZSwga2V5OiBrZXlvZiBFbnRpdHlUeXBlKSA9PiBib29sZWFuLFxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSBpbnB1dCBpcyB2YWxpZCBlbXB0eS5cbiAgICAgKi9cbiAgICB2YWxpZEVtcHR5PzogKCkgPT4gYm9vbGVhblxufTtcblxuLyoqXG4gKiBBIHRhYmxlIGNvbnRleHQgdGhhdCBpcyB1c2VkIHRvIGZpbGwgYW4gaW5saW5lIHRlbXBsYXRlLlxuICogVGhpcyBpcyB1c2VkIHRvIGdvIGFyb3VuZCB0aGUgbGltaXRhdGlvbnMgb2YgaGF2aW5nIGV2ZXJ5dGhpbmcgaW4gdGhlIHNhbWUgZmlsZSBkdWUgdG8gY2lyY3VsYXIgZGVwZW5kZW5jaWVzLlxuICogVGhlIHRhYmxlIGlzIHVzZWQgZm9yIGVudGl0eSBhcnJheSBhbmQgaGFzTWFueS5cbiAqL1xudHlwZSBUYWJsZUNvbnRleHQ8VD4gPSBJbnRlcm5hbEN1c3RvbVRhYmxlQ29uZmlndXJhdGlvbiAmIHtcbiAgICAvKipcbiAgICAgKiBUaGUgZGF0YSBzb3VyY2Ugb2YgdGhlIHRhYmxlLlxuICAgICAqL1xuICAgIGRhdGFTb3VyY2U6IE1hdFRhYmxlRGF0YVNvdXJjZTxUPixcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCBhIGVycm9yIG1lc3NhZ2Ugc2hvdWxkIGJlIHNob3duIHdoZW4gdGhlIHRhYmxlIGlzIGVtcHR5LlxuICAgICAqL1xuICAgIHNob3VsZFNob3dNaXNzaW5nRXJyb3I6IGJvb2xlYW4sXG4gICAgLyoqXG4gICAgICogVGhlIHNlbGVjdGlvbiBvZiB0aGUgdGFibGUuXG4gICAgICovXG4gICAgc2VsZWN0aW9uOiBTZWxlY3Rpb25Nb2RlbDxUPixcbiAgICAvKipcbiAgICAgKiBXaGF0IGhhcHBlbnMgd2hlbiBhIGNlbGwgaXMgY2xpY2tlZC5cbiAgICAgKi9cbiAgICBjbGlja0NlbGw6ICh2YWx1ZTogVCwgZGlzcGxheUNvbHVtbjogRGlzcGxheUNvbHVtbjxUPikgPT4gdm9pZCxcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgZGF0YSBmb3IgdGhlIHRhYmxlIGlzIGN1cnJlbnRseSBiZWluZyBsb2FkZWQuXG4gICAgICovXG4gICAgaXNMb2FkaW5nOiBib29sZWFuLFxuICAgIC8qKlxuICAgICAqIEFsbCBjb2x1bW5zIHRoYXQgc2hvdWxkIGJlIGRpc3BsYXllZC5cbiAgICAgKi9cbiAgICBkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXVxufTtcblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBpbnB1dCBjb21wb25lbnQuIEl0IGdldHMgdGhlIG1ldGFkYXRhIG9mIHRoZSBwcm9wZXJ0eSBmcm9tIHRoZSBnaXZlbiBASW5wdXQgXCJlbnRpdHlcIiBhbmQgQElucHV0IFwicHJvcGVydHlLZXlcIlxuICogYW5kIGRpc3BsYXlzIHRoZSBpbnB1dCBmaWVsZCBhY2NvcmRpbmdseS5cbiAqXG4gKiBZb3UgY2FuIGFsc28gZGVmaW5lIGEgbWV0aG9kIHRoYXQgZ2VuZXJhdGVzIGVycm9yLW1lc3NhZ2VzIGFuZCBpZiB0aGUgaW5wdXQgc2hvdWxkIGJlIGhpZGRlbiB3aGVuIGl0cyBtZXRhZGF0YSBzYXlzXG4gKiB0aGF0IGl0IHNob3VsZCBiZSBvbWl0dGVkIGZvciBjcmVhdGluZyBvciB1cGRhdGluZy5cbiAqIFRoZSBsYXN0IHBhcnQgYmVpbmcgbW9zdGx5IHJlbGV2YW50IGlmIHlvdSB3YW50IHRvIHVzZSB0aGlzIGNvbXBvbmVudCBpbnNpZGUgYW4gbmdGb3IuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmd4LW1hdC1lbnRpdHktaW5wdXQnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9pbnB1dC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vaW5wdXQuY29tcG9uZW50LnNjc3MnLCAnLi4vLi4vc2Nzcy9kaWFsb2ctc3R5bGVzLnNjc3MnLCAnLi4vLi4vc2Nzcy90YWlsd2luZC1jbGFzc2VzLnNjc3MnXSxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgRGlzcGxheUNvbHVtblZhbHVlQ29tcG9uZW50LFxuICAgICAgICBDb21tb25Nb2R1bGUsXG4gICAgICAgIE1hdFRhYnNNb2R1bGUsXG4gICAgICAgIE1hdEZvcm1GaWVsZE1vZHVsZSxcbiAgICAgICAgTWF0U2VsZWN0TW9kdWxlLFxuICAgICAgICBGb3Jtc01vZHVsZSxcbiAgICAgICAgTWF0RGlhbG9nTW9kdWxlLFxuICAgICAgICBNYXRCYWRnZU1vZHVsZSxcbiAgICAgICAgTWF0SW5wdXRNb2R1bGUsXG4gICAgICAgIE1hdE1lbnVNb2R1bGUsXG4gICAgICAgIE1hdFBhZ2luYXRvck1vZHVsZSxcbiAgICAgICAgTWF0UHJvZ3Jlc3NTcGlubmVyTW9kdWxlLFxuICAgICAgICBNYXRUYWJsZU1vZHVsZSxcbiAgICAgICAgTWF0Q2hlY2tib3hNb2R1bGUsXG4gICAgICAgIE1hdEJ1dHRvbk1vZHVsZSxcbiAgICAgICAgVG9vbHRpcENvbXBvbmVudCxcbiAgICAgICAgU3RyaW5nSW5wdXRDb21wb25lbnQsXG4gICAgICAgIFN0cmluZ1RleHRib3hJbnB1dENvbXBvbmVudCxcbiAgICAgICAgU3RyaW5nQXV0b2NvbXBsZXRlSW5wdXRDb21wb25lbnQsXG4gICAgICAgIFN0cmluZ0Ryb3Bkb3duSW5wdXRDb21wb25lbnQsXG4gICAgICAgIFN0cmluZ1Bhc3N3b3JkSW5wdXRDb21wb25lbnQsXG4gICAgICAgIEJvb2xlYW5DaGVja2JveElucHV0Q29tcG9uZW50LFxuICAgICAgICBCb29sZWFuVG9nZ2xlSW5wdXRDb21wb25lbnQsXG4gICAgICAgIEJvb2xlYW5Ecm9wZG93bklucHV0Q29tcG9uZW50LFxuICAgICAgICBOdW1iZXJJbnB1dENvbXBvbmVudCxcbiAgICAgICAgTnVtYmVyRHJvcGRvd25JbnB1dENvbXBvbmVudCxcbiAgICAgICAgTnVtYmVyU2xpZGVySW5wdXRDb21wb25lbnQsXG4gICAgICAgIEFycmF5RGF0ZUlucHV0Q29tcG9uZW50LFxuICAgICAgICBBcnJheURhdGVSYW5nZUlucHV0Q29tcG9uZW50LFxuICAgICAgICBBcnJheURhdGVUaW1lSW5wdXRDb21wb25lbnQsXG4gICAgICAgIEFycmF5U3RyaW5nQXV0b2NvbXBsZXRlQ2hpcHNDb21wb25lbnQsXG4gICAgICAgIEFycmF5U3RyaW5nQ2hpcHNJbnB1dENvbXBvbmVudCxcbiAgICAgICAgRGF0ZUlucHV0Q29tcG9uZW50LFxuICAgICAgICBEYXRlUmFuZ2VJbnB1dENvbXBvbmVudCxcbiAgICAgICAgRGF0ZVRpbWVJbnB1dENvbXBvbmVudCxcbiAgICAgICAgRmlsZURlZmF1bHRJbnB1dENvbXBvbmVudCxcbiAgICAgICAgRmlsZUltYWdlSW5wdXRDb21wb25lbnQsXG4gICAgICAgIFJlZmVyZW5jZXNNYW55SW5wdXRDb21wb25lbnQsXG4gICAgICAgIEN1c3RvbUlucHV0Q29tcG9uZW50LFxuICAgICAgICBEeW5hbWljU3R5bGVDbGFzc0RpcmVjdGl2ZSxcbiAgICAgICAgTWF0U29ydE1vZHVsZSxcbiAgICAgICAgRmFJY29uQ29tcG9uZW50XG4gICAgXVxufSlcbmV4cG9ydCBjbGFzcyBOZ3hNYXRFbnRpdHlJbnB1dENvbXBvbmVudDxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+IGltcGxlbWVudHMgT25Jbml0IHtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXG4gICAgZmFTZWFyY2g6IEljb25EZWZpbml0aW9uID0gZmFTZWFyY2g7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZW50aXR5IG9uIHdoaWNoIHRoZSBwcm9wZXJ0eSBleGlzdHMuIFVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgXCJwcm9wZXJ0eUtleVwiXG4gICAgICogdG8gZGV0ZXJtaW5lIHRoZSBwcm9wZXJ0eSBmb3Igd2hpY2ggdGhlIGlucHV0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG4gICAgICovXG4gICAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSlcbiAgICBlbnRpdHkhOiBFbnRpdHlUeXBlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGdlbmVyYXRlIHRoZSBpbnB1dCBmb3IuIFVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgXCJlbnRpdHlcIi5cbiAgICAgKi9cbiAgICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KVxuICAgIHByb3BlcnR5S2V5IToga2V5b2YgRW50aXR5VHlwZTtcblxuICAgIC8qKlxuICAgICAqIChvcHRpb25hbCkgQSBjdXN0b20gZnVuY3Rpb24gdG8gZ2VuZXJhdGUgdGhlIGVycm9yLW1lc3NhZ2UgZm9yIGludmFsaWQgaW5wdXRzLlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZT86IChtb2RlbDogTmdNb2RlbCkgPT4gc3RyaW5nO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXG4gICAgaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlITogKG1vZGVsOiBOZ01vZGVsKSA9PiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIGhpZGUgYSB2YWx1ZSBpZiBpdCBpcyBvbWl0dGVkIGZvciBjcmVhdGlvbi5cbiAgICAgKiBJcyB1c2VkIGludGVybmFsbHkgZm9yIHRoZSBvYmplY3QgcHJvcGVydHkuXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGhpZGVPbWl0Rm9yQ3JlYXRlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gaGlkZSBhIHZhbHVlIGlmIGl0IGlzIG9taXR0ZWQgZm9yIGVkaXRpbmcuXG4gICAgICogSXMgdXNlZCBpbnRlcm5hbGx5IGZvciB0aGUgb2JqZWN0IHByb3BlcnR5LlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBoaWRlT21pdEZvckVkaXQ/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgYW4gZW1wdHkgdmFsdWUgc2hvdWxkIGJlIHZhbGlkLlxuICAgICAqIElzIHVzZWQgaW50ZXJuYWxseSBmb3IgdGhlIG9iamVjdCBwcm9wZXJ0eS5cbiAgICAgKiBAZGVmYXVsdCB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHZhbGlkRW1wdHk/OiBib29sZWFuOyAvLyBUT0RPXG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgaW5wdXQgc2hvdWxkIGJlIHJlYWRvbmx5LlxuICAgICAqIEluIHRoYXQgY2FzZSBpdCBpcyBkaXNhYmxlZCwgYnV0IG1vc3Qgb2YgdGhlIGRlZmF1bHQgc3R5bGluZyBpcyBvdmVyd3JpdHRlbi5cbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgaXNSZWFkT25seT86IGJvb2xlYW47XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcbiAgICBpbnRlcm5hbElzUmVhZE9ubHkhOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgd2hlbiB0aGUgaW5wdXQgdmFsdWUgaGFzIGJlZW4gY2hhbmdlZC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICByZWFkb25seSBpbnB1dENoYW5nZUV2ZW50OiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICAvKipcbiAgICAgKiBBIHNldHRlciBmb3IgdGhlIGhhcyBtYW55IGFuZCBhcnJheSBzb3J0LlxuICAgICAqIElzIG5lZWRlZCBiZWNhdXNlIHRoZSBzb3J0IGlzIGluc2lkZSBhIHN3aXRjaCBjYXNlLFxuICAgICAqIHdoaWNoIG1lYW5zIHRoYXQgYXQgbmdPbkluaXQgaXQgY2FuJ3QgYmUgaW5pdGlhbGl6ZWQuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZChNYXRTb3J0KVxuICAgIHByaXZhdGUgc2V0IHNvcnQoc29ydDogTWF0U29ydCkge1xuICAgICAgICBpZiAodGhpcy5oYXNNYW55VGFibGVDb250ZXh0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLnNvcnQgPSB0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmRhdGFTb3VyY2Uuc29ydCA/PyBzb3J0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmVudGl0eUFycmF5VGFibGVDb250ZXh0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5lbnRpdHlBcnJheVRhYmxlQ29udGV4dC4kaW1wbGljaXQuZGF0YVNvdXJjZS5zb3J0ID0gdGhpcy5lbnRpdHlBcnJheVRhYmxlQ29udGV4dC4kaW1wbGljaXQuZGF0YVNvdXJjZS5zb3J0ID8/IHNvcnQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNldHRlciBmb3IgdGhlIGhhcyBtYW55IGFuZCBhcnJheSBwYWdpbmF0b3IuXG4gICAgICogSXMgbmVlZGVkIGJlY2F1c2UgdGhlIHBhZ2luYXRvciBpcyBpbnNpZGUgYSBzd2l0Y2ggY2FzZSxcbiAgICAgKiB3aGljaCBtZWFucyB0aGF0IGF0IG5nT25Jbml0IGl0IGNhbid0IGJlIGluaXRpYWxpemVkLlxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoTWF0UGFnaW5hdG9yKVxuICAgIHByaXZhdGUgc2V0IHBhZ2luYXRvcihwYWdpbmF0b3I6IE1hdFBhZ2luYXRvcikge1xuICAgICAgICBpZiAodGhpcy5oYXNNYW55VGFibGVDb250ZXh0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLnBhZ2luYXRvciA9IHRoaXMuaGFzTWFueVRhYmxlQ29udGV4dC4kaW1wbGljaXQuZGF0YVNvdXJjZS5wYWdpbmF0b3IgPz8gcGFnaW5hdG9yO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmVudGl0eUFycmF5VGFibGVDb250ZXh0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHN0eWxpc3RpYy9tYXgtbGVuXG4gICAgICAgICAgICB0aGlzLmVudGl0eUFycmF5VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLnBhZ2luYXRvciA9IHRoaXMuZW50aXR5QXJyYXlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmRhdGFTb3VyY2UucGFnaW5hdG9yID8/IHBhZ2luYXRvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBkZWNvcmF0b3IgZm9yIHRoaXMgaW5wdXQuXG4gICAgICovXG4gICAgdHlwZSE6IERlY29yYXRvclR5cGVzO1xuICAgIC8qKlxuICAgICAqIFRoZSBwcm9wZXJ0eSBtZXRhZGF0YSByZWNlaXZlZCBmcm9tIHRoZSBkZWNvcmF0b3IuXG4gICAgICovXG4gICAgbWV0YWRhdGEhOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsPHVua25vd24+O1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1ldGFkYXRhIG9mIGFuIG9iamVjdCBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBtZXRhZGF0YURlZmF1bHRPYmplY3QhOiBEZWZhdWx0T2JqZWN0RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgLyoqXG4gICAgICogVGhlIGZvcm0gY29udGV4dCBmb3IgYW4gb2JqZWN0IHByb3BlcnR5LlxuICAgICAqL1xuICAgIG9iamVjdEZvcm1Db250ZXh0ITogVGVtcGxhdGVDb250ZXh0PEZvcm1Db250ZXh0PEVudGl0eVR5cGU+PjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBtZXRhZGF0YSBvZiBhbiBkcm9wZG93biBvYmplY3QgcHJvcGVydHkuXG4gICAgICovXG4gICAgbWV0YWRhdGFEcm9wZG93bk9iamVjdCE6IERyb3Bkb3duT2JqZWN0RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgLyoqXG4gICAgICogQWxsIHBvc3NpYmxlIGRyb3Bkb3duIHZhbHVlcyBmb3IgdGhlIG9iamVjdCBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBwcml2YXRlIG9iamVjdERyb3Bkb3duVmFsdWVzOiBEcm9wZG93blZhbHVlPEVudGl0eVR5cGUgfCB1bmRlZmluZWQ+W10gPSBbXTtcbiAgICAvKipcbiAgICAgKiBBIHVuaXF1ZSBpbnB1dCBuYW1lIGZvciB0aGUgcmVmZXJlbmNlcyBvbmUgcHJvcGVydHkuXG4gICAgICovXG4gICAgb2JqZWN0RHJvcGRvd25OYW1lITogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEFsbCBjdXJyZW50bHkgc2hvd24gZHJvcGRvd24gdmFsdWVzIGZvciB0aGUgb2JqZWN0IHByb3BlcnR5LlxuICAgICAqL1xuICAgIGZpbHRlcmVkT2JqZWN0RHJvcGRvd25WYWx1ZXM6IERyb3Bkb3duVmFsdWU8RW50aXR5VHlwZSB8IHVuZGVmaW5lZD5bXSA9IFtdO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLXJldHVybnNcbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudGx5IHNlbGVjdGVkIG9iamVjdCBhcyBhIGRyb3AgZG93biB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgY3VycmVudE9iamVjdERyb3Bkb3duVmFsdWUoKTogRHJvcGRvd25WYWx1ZTxFbnRpdHlUeXBlIHwgdW5kZWZpbmVkPiB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IHZhbHVlOiBEcm9wZG93blZhbHVlPEVudGl0eVR5cGUgfCB1bmRlZmluZWQ+W10gPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMub2JqZWN0RHJvcGRvd25WYWx1ZXMgPz8gW10pO1xuICAgICAgICByZXR1cm4gdmFsdWUuZmluZCh2ID0+IExvZGFzaFV0aWxpdGllcy5pc0VxdWFsKHYudmFsdWUsIHRoaXMuZW50aXR5W3RoaXMucHJvcGVydHlLZXldKSk7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLXJldHVybnNcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgY3VycmVudCBvYmplY3QgZHJvcGRvd24gdmFsdWUgc2hvdWxkIGJlIHNob3duIGluIHRoZSBkcm9wZG93bi5cbiAgICAgKi9cbiAgICBnZXQgc2hvdWxkRGlzcGxheUN1cnJlbnRPYmplY3REcm9wZG93blZhbHVlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLmN1cnJlbnRPYmplY3REcm9wZG93blZhbHVlXG4gICAgICAgICAgICAmJiAhdGhpcy5maWx0ZXJlZE9iamVjdERyb3Bkb3duVmFsdWVzLmZpbmQodiA9PiBMb2Rhc2hVdGlsaXRpZXMuaXNFcXVhbCh2LnZhbHVlLCB0aGlzLmN1cnJlbnRPYmplY3REcm9wZG93blZhbHVlPy52YWx1ZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGNvbXBhcmVXaXRoIG1ldGhvZCBmb3IgdGhlIHNlbGVjdC5cbiAgICAgKiBVc2VzIGJpbmQuXG4gICAgICovXG4gICAgY29tcGFyZU9iamVjdHNCb3VuZDogKHZhbHVlMT86IEVudGl0eVR5cGUsIHZhbHVlMj86IEVudGl0eVR5cGUpID0+IGJvb2xlYW4gPSB0aGlzLmNvbXBhcmVPYmplY3RzLmJpbmQodGhpcyk7XG5cbiAgICBAVmlld0NoaWxkKCdhZGRBcnJheUl0ZW1EaWFsb2cnKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgYWRkQXJyYXlJdGVtRGlhbG9nITogVGVtcGxhdGVSZWY8dW5rbm93bj47XG4gICAgcHJpdmF0ZSBhZGRBcnJheUl0ZW1EaWFsb2dSZWYhOiBNYXREaWFsb2dSZWY8dW5rbm93bj47XG4gICAgQFZpZXdDaGlsZCgnZWRpdEFycmF5SXRlbURpYWxvZycpXG4gICAgcHJpdmF0ZSByZWFkb25seSBlZGl0QXJyYXlJdGVtRGlhbG9nITogVGVtcGxhdGVSZWY8dW5rbm93bj47XG4gICAgcHJpdmF0ZSBlZGl0QXJyYXlJdGVtRGlhbG9nUmVmITogTWF0RGlhbG9nUmVmPHVua25vd24+O1xuICAgIC8qKlxuICAgICAqIFRoZSBtZXRhZGF0YSBvZiBhbiBlbnRpdHkgYXJyYXkgcHJvcGVydHkuXG4gICAgICovXG4gICAgbWV0YWRhdGFFbnRpdHlBcnJheSE6IEVudGl0eUFycmF5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgLyoqXG4gICAgICogVGhlIHRhYmxlIGNvbnRleHQgZm9yIHRoZSBlbnRpdHkgYXJyYXkgaW5wdXQuXG4gICAgICovXG4gICAgZW50aXR5QXJyYXlUYWJsZUNvbnRleHQhOiBUZW1wbGF0ZUNvbnRleHQ8VGFibGVDb250ZXh0PEVudGl0eVR5cGU+PjtcbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCBhcnJheSBpdGVtIHRvIGJlIGFkZGVkIG9yIHVwZGF0ZWQuXG4gICAgICovXG4gICAgYXJyYXlJdGVtITogRW50aXR5VHlwZTtcbiAgICAvKipcbiAgICAgKiBUaGUgYXJyYXkgaXRlbSBiZWZvcmUgYW55IGNoYW5nZXMgaGF2ZSBiZWVuIG1hZGUuIFVzZWQgdG8gY2hlY2sgaWYgdGhlIGZvcm0gaXMgZGlydHkuXG4gICAgICovXG4gICAgYXJyYXlJdGVtUHJpb3JDaGFuZ2VzITogRW50aXR5VHlwZTtcbiAgICAvKipcbiAgICAgKiBUaGUgZm9ybSBjb250ZXh0IGZvciBhZGRpbmcgYW4gYXJyYXkgaXRlbS5cbiAgICAgKi9cbiAgICBhZGRBcnJheUl0ZW1Gb3JtQ29udGV4dCE6IFRlbXBsYXRlQ29udGV4dDxGb3JtQ29udGV4dDxFbnRpdHlUeXBlPj47XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcbiAgICBhZGRBcnJheUl0ZW1Gb3JtQ29udGV4dDIhOiBUZW1wbGF0ZUNvbnRleHQ8Rm9ybUNvbnRleHQ8RW50aXR5VHlwZT4+O1xuICAgIC8qKlxuICAgICAqIFRoZSBmb3JtIGNvbnRleHQgZm9yIGVkaXRpbmcgYW4gYXJyYXkgaXRlbS5cbiAgICAgKi9cbiAgICBlZGl0QXJyYXlJdGVtRm9ybUNvbnRleHQhOiBUZW1wbGF0ZUNvbnRleHQ8Rm9ybUNvbnRleHQ8RW50aXR5VHlwZT4+O1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSBhcnJheSBpdGVtIGlzIHZhbGlkLlxuICAgICAqL1xuICAgIGlzQXJyYXlJdGVtVmFsaWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgYXJyYXkgaXRlbSBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBpc0FycmF5SXRlbURpcnR5OiBib29sZWFuID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogVGhlIGluZGV4IG9mIHRoZSBhcnJheSBpdGVtIHRoYXQgaXMgYmVpbmcgZWRpdGVkLlxuICAgICAqL1xuICAgIHByaXZhdGUgaW5kZXhPZkVkaXRlZEFycmF5SXRlbSE6IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBDb25maWcgZm9yIHRoZSBkaWFsb2cgdGhhdCBhZGRzIGEgbmV3IGFycmF5IGl0ZW0uXG4gICAgICovXG4gICAgYWRkQXJyYXlJdGVtRGlhbG9nRGF0YSE6IENyZWF0ZURhdGFJbnRlcm5hbDtcbiAgICAvKipcbiAgICAgKiBUaGUgdGFicyB0byBkaXNwbGF5IGluc2lkZSB0aGUgZWRpdCBhcnJheSBpdGVtIGRpYWxvZy5cbiAgICAgKi9cbiAgICBlZGl0QXJyYXlJdGVtRGlhbG9nRGF0YSE6IEVkaXRBcnJheUl0ZW1EaWFsb2dEYXRhSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgLyoqXG4gICAgICogQWxsIHZhbGlkYXRpb24gZXJyb3JzIGZvciB0aGUgYXJyYXkgaXRlbS5cbiAgICAgKi9cbiAgICBhcnJheUl0ZW1WYWxpZGF0aW9uRXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JbXSA9IFtdO1xuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgY2hhbmdlcyB0aGF0IGhhdmUgYmVlbiBkb25lIHRvIHRoZSBhcnJheSBpdGVtLlxuICAgICAqL1xuICAgIGFycmF5SXRlbUNoYW5nZXM6IERpZmZlcmVuY2U8RW50aXR5VHlwZT5bXSA9IFtdO1xuICAgIC8qKlxuICAgICAqIFdoYXQgdG8gZGlzcGxheSBpbnNpZGUgdGhlIGFycmF5IGl0ZW0gdG9vbHRpcC5cbiAgICAgKi9cbiAgICBhcnJheUl0ZW1Ub29sdGlwQ29udGVudDogc3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBNZXRhZGF0YSBvZiBhIGhhcyBtYW55IHByb3BlcnR5LlxuICAgICAqL1xuICAgIG1ldGFkYXRhSGFzTWFueSE6IEhhc01hbnlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlLCBFbnRpdHlUeXBlPjtcbiAgICAvKipcbiAgICAgKiBUaGUgdGFibGUgY29udGV4dCBmb3IgdGhlIGhhcyBtYW55IGlucHV0LlxuICAgICAqL1xuICAgIGhhc01hbnlUYWJsZUNvbnRleHQhOiBUZW1wbGF0ZUNvbnRleHQ8VGFibGVDb250ZXh0PEVudGl0eVR5cGU+PjtcbiAgICAvKipcbiAgICAgKiBUaGUgaGFzIG1hbnkgaW1wb3J0IGFjdGlvbi5cbiAgICAgKi9cbiAgICBoYXNNYW55SW1wb3J0QWN0aW9uITogQmFzZVRhYmxlQWN0aW9uSW50ZXJuYWw7XG4gICAgcHJpdmF0ZSBoYXNNYW55RW50aXR5U2VydmljZSE6IEVudGl0eVNlcnZpY2U8RW50aXR5VHlwZT47XG4gICAgQFZpZXdDaGlsZCgnY3JlYXRlSGFzTWFueURpYWxvZycpXG4gICAgcHJpdmF0ZSByZWFkb25seSBjcmVhdGVIYXNNYW55RGlhbG9nITogVGVtcGxhdGVSZWY8dW5rbm93bj47XG4gICAgcHJpdmF0ZSBjcmVhdGVIYXNNYW55RGlhbG9nUmVmITogTWF0RGlhbG9nUmVmPHVua25vd24+O1xuICAgIEBWaWV3Q2hpbGQoJ2VkaXRIYXNNYW55RGlhbG9nJylcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVkaXRIYXNNYW55RGlhbG9nITogVGVtcGxhdGVSZWY8dW5rbm93bj47XG4gICAgcHJpdmF0ZSBlZGl0SGFzTWFueURpYWxvZ1JlZiE6IE1hdERpYWxvZ1JlZjx1bmtub3duPjtcbiAgICAvKipcbiAgICAgKiBBIHNpbmdsZSBoYXMgbWFueSBlbnRpdHkuXG4gICAgICovXG4gICAgaGFzTWFueUVudGl0eSE6IEVudGl0eVR5cGU7XG4gICAgLyoqXG4gICAgICogVGhlIHNpbmdsZSBoYXMgbWFueSBlbnRpdHkgYmVmb3JlIGFueSBjaGFuZ2VzIGhhdmUgYmVlbiBtYWRlLiBJcyB1c2VkIHRvIGRldGVybWluZSBpZiB0aGUgZm9ybSBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBoYXNNYW55RW50aXR5UHJpb3JDaGFuZ2VzITogRW50aXR5VHlwZTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgaGFzIG1hbnkgZW50aXR5IGlzIHZhbGlkLlxuICAgICAqL1xuICAgIGlzSGFzTWFueUVudGl0eVZhbGlkOiBib29sZWFuID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQWxsIHZhbGlkYXRpb24gZXJyb3JzIG9mIHRoZSBoYXMgbWFueSBlbnRpdHkuXG4gICAgICovXG4gICAgaGFzTWFueVZhbGlkYXRpb25FcnJvcnM6IFZhbGlkYXRpb25FcnJvcltdID0gW107XG4gICAgLyoqXG4gICAgICogQWxsIHRoZSBjaGFuZ2VzIHRoYXQgaGF2ZSBiZWVuIGRvbmUgdG8gdGhlIGhhcyBtYW55IGVudGl0eS5cbiAgICAgKi9cbiAgICBoYXNNYW55Q2hhbmdlczogRGlmZmVyZW5jZTxFbnRpdHlUeXBlPltdID0gW107XG4gICAgLyoqXG4gICAgICogV2hhdCB0byBkaXNwbGF5IGluc2lkZSB0aGUgaGFzIG1hbnkgdG9vbHRpcC5cbiAgICAgKi9cbiAgICBoYXNNYW55VG9vbHRpcENvbnRlbnQ6IHN0cmluZyA9ICcnO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSBoYXMgbWFueSBlbnRpdHkgaXMgZGlydHkuXG4gICAgICovXG4gICAgaXNIYXNNYW55RW50aXR5RGlydHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgY3VycmVudCB1c2VyIGlzIGFsbG93ZWQgdG8gY3JlYXRlIGEgaGFzIG1hbnkgZW50aXR5LlxuICAgICAqL1xuICAgIGhhc01hbnlBbGxvd0NyZWF0ZSE6IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogVGhlIGZvcm0gY29udGV4dCBmb3IgY3JlYXRpbmcgYW4gaGFzIG1hbnkgZW50aXR5LlxuICAgICAqL1xuICAgIGhhc01hbnlDcmVhdGVGb3JtQ29udGV4dCE6IFRlbXBsYXRlQ29udGV4dDxGb3JtQ29udGV4dDxFbnRpdHlUeXBlPj47XG4gICAgLyoqXG4gICAgICogVGhlIGZvcm0gY29udGV4dCBmb3IgZWRpdGluZyBhbiBoYXMgbWFueSBlbnRpdHkuXG4gICAgICovXG4gICAgaGFzTWFueUVkaXRGb3JtQ29udGV4dCE6IFRlbXBsYXRlQ29udGV4dDxGb3JtQ29udGV4dDxFbnRpdHlUeXBlPj47XG4gICAgcHJpdmF0ZSBoYXNNYW55Q3JlYXRlQmFzZVVybCE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBtZXRhZGF0YSBmb3IgYSByZWZlcmVuY2VzIG9uZSBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBtZXRhZGF0YVJlZmVyZW5jZXNPbmUhOiBSZWZlcmVuY2VzT25lRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgLyoqXG4gICAgICogVGhlIHZhbHVlcyB0aGF0IGNhbiBiZSBwb3NzaWJseSByZWZlcmVuY2VkLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVmZXJlbmNlc09uZUFsbFJlZmVyZW5jZWRFbnRpdGllcyE6IEVudGl0eVR5cGVbXTtcbiAgICAvKipcbiAgICAgKiBUaGUgcG9zc2libGUgcmVmZXJlbmNlcyBvbmUgZHJvcGRvd24gdmFsdWVzLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVmZXJlbmNlc09uZURyb3Bkb3duVmFsdWVzITogRHJvcGRvd25WYWx1ZTxzdHJpbmc+W107XG4gICAgLyoqXG4gICAgICogVGhlIGZpbHRlcmVkIGRyb3Bkb3duIHZhbHVlcyB0aGF0IGdldCBkaXNwbGF5ZWQgaW4gdGhlIHJlZmVyZW5jZXMgb25lIGRyb3Bkb3duIGlucHV0LlxuICAgICAqL1xuICAgIGZpbHRlcmVkUmVmZXJlbmNlc09uZURyb3Bkb3duVmFsdWVzITogRHJvcGRvd25WYWx1ZTxzdHJpbmc+W107XG4gICAgLyoqXG4gICAgICogQSB1bmlxdWUgaW5wdXQgbmFtZSBmb3IgdGhlIHJlZmVyZW5jZXMgb25lIHByb3BlcnR5LlxuICAgICAqL1xuICAgIHJlZmVyZW5jZXNPbmVOYW1lITogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFRoZSBmb3JtIGNvbnRleHQgZm9yIGFuIHJlZmVyZW5jZXMgb25lIHByb3BlcnR5LlxuICAgICAqL1xuICAgIHJlZmVyZW5jZXNPbmVGb3JtQ29udGV4dCE6IFRlbXBsYXRlQ29udGV4dDxGb3JtQ29udGV4dDxFbnRpdHlUeXBlPj47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZW51bSBWYWx1ZXMgZm9yIGFsbCB0aGUgZGlmZmVyZW50IERlY29yYXRvclR5cGVzLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IERlY29yYXRvclR5cGVzOiB0eXBlb2YgRGVjb3JhdG9yVHlwZXMgPSBEZWNvcmF0b3JUeXBlcztcbiAgICAvKipcbiAgICAgKiBDb250YWlucyBIZWxwZXJNZXRob2RzIGFyb3VuZCBoYW5kbGluZyBFbnRpdGllcyBhbmQgdGhlaXIgcHJvcGVydHktbWV0YWRhdGEuXG4gICAgICovXG4gICAgRW50aXR5VXRpbGl0aWVzOiB0eXBlb2YgRW50aXR5VXRpbGl0aWVzID0gRW50aXR5VXRpbGl0aWVzO1xuICAgIC8qKlxuICAgICAqIENvbnRhaW5zIEhlbHBlciBGdW5jdGlvbnMgZm9yIGhhbmRsaW5nIGRhdGUgcHJvcGVydGllcy5cbiAgICAgKi9cbiAgICBEYXRlVXRpbGl0aWVzOiB0eXBlb2YgRGF0ZVV0aWxpdGllcyA9IERhdGVVdGlsaXRpZXM7XG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBhcm91bmQgbWF0ZXJpYWwgc2VsZWN0aW9ucyBpbnNpZGUgb2YgdGFibGVzLlxuICAgICAqL1xuICAgIFNlbGVjdGlvblV0aWxpdGllczogdHlwZW9mIFNlbGVjdGlvblV0aWxpdGllcyA9IFNlbGVjdGlvblV0aWxpdGllcztcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLXJldHVybnNcbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZHJvcGRvd24gdmFsdWUgZm9yIHJlZmVyZW5jZXMgb25lLlxuICAgICAqIElzIG5lZWRlZCBzbyB0aGF0IHRoZSBkcm9wZG93biB2YWx1ZSB3aWxsIHN0aWxsIGJlIGRpc3BsYXllZCxcbiAgICAgKiBldmVuIHdoZW4gdGhlIGZpbHRlciBtZXRob2QgcmVtb3ZlcyB0aGUgdmFsdWUgZnJvbSB0aGUgc2VsZWN0YWJsZSBkcm9wZG93biB2YWx1ZXMuXG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnRSZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZSgpOiBEcm9wZG93blZhbHVlPHN0cmluZz4gfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLnJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlcyA/PyBbXSlcbiAgICAgICAgICAgIC5maW5kKHYgPT4gdi52YWx1ZSA9PT0gdGhpcy5lbnRpdHlbdGhpcy5wcm9wZXJ0eUtleV0pO1xuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLXJldHVybnNcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHJlZmVyZW5jZXMgb25lIHZhbHVlIHNob3VsZCBiZSBzaG93bixcbiAgICAgKiBhbHRob3VnaCBpdCB3b3VsZCBoYXZlIGJlZW4gZmlsdGVyZWQgb3V0IGJ5IHRoZSBzZWFyY2guXG4gICAgICovXG4gICAgZ2V0IHNob3VsZERpc3BsYXlDdXJyZW50UmVmZXJlbmNlc09uZURyb3Bkb3duVmFsdWUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuY3VycmVudFJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlXG4gICAgICAgICAgICAmJiAhdGhpcy5maWx0ZXJlZFJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlcy5maW5kKHYgPT4gdi52YWx1ZSA9PT0gdGhpcy5jdXJyZW50UmVmZXJlbmNlc09uZURyb3Bkb3duVmFsdWU/LnZhbHVlKTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBpbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3RvcixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgQEluamVjdChOR1hfR0VUX1ZBTElEQVRJT05fRVJST1JfTUVTU0FHRSlcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlZmF1bHRHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlOiAobW9kZWw6IE5nTW9kZWwpID0+IHN0cmluZyxcbiAgICAgICAgQEluamVjdChOR1hfQ09NUExFVEVfR0xPQkFMX0RFRkFVTFRfVkFMVUVTKVxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZ2xvYmFsQ29uZmlnOiBOZ3hHbG9iYWxEZWZhdWx0VmFsdWVzLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGh0dHA6IEh0dHBDbGllbnRcbiAgICApIHt9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGlucHV0IHdpdGggdGhlIGdpdmVuIGtleSBvbiB0aGUgZ2l2ZW4gcHJvcGVydHkgaXMgcmVhZG9ubHkuXG4gICAgICogQHBhcmFtIHByb3BlcnR5IC0gVGhlIHByb3BlcnR5IG9uIHdoaWNoIHRvIGNoZWNrIHRoZSBpbnB1dC5cbiAgICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSBmb3IgdGhlIGlucHV0IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IHRoZSBpbnB1dCBpcyByZWFkb25seS5cbiAgICAgKi9cbiAgICBpc1Byb3BlcnR5UmVhZE9ubHkocHJvcGVydHk6IEVudGl0eVR5cGUsIGtleToga2V5b2YgRW50aXR5VHlwZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcnVuSW5JbmplY3Rpb25Db250ZXh0KHRoaXMuaW5qZWN0b3IsICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmludGVybmFsSXNSZWFkT25seSB8fCB0aGlzLm1ldGFkYXRhRGVmYXVsdE9iamVjdD8uaXNSZWFkT25seShwcm9wZXJ0eSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsPHVua25vd24+IHwgdW5kZWZpbmVkID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEocHJvcGVydHksIGtleSk7XG4gICAgICAgICAgICBpZiAoIW1ldGFkYXRhKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBtZXRhZGF0YSB3YXMgZm91bmQgZm9yIHRoZSBrZXkgXCIke1N0cmluZyhrZXkpfVwiYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGEuaXNSZWFkT25seShwcm9wZXJ0eSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlIHRvIGRpc3BsYXkgaW4gdGhlIGNvbHVtbi5cbiAgICAgKiBSdW5zIGluIGVudmlyb25tZW50IGNvbnRleHQgdG8gZW5hYmxlIGluamVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0byBnZXQgdGhlIHZhbHVlIGZyb20uXG4gICAgICogQHBhcmFtIGRpc3BsYXlDb2x1bW4gLSBUaGUgZGlzcGxheSBjb2x1bW4gdG8gZ2V0IHRoZSB2YWx1ZSBmcm9tLlxuICAgICAqIEByZXR1cm5zIFRoZSB2YWx1ZSBvZiB0aGUgZGlzcGxheSBjb2x1bW4uXG4gICAgICovXG4gICAgZ2V0RGlzcGxheUNvbHVtblZhbHVlKGVudGl0eTogRW50aXR5VHlwZSwgZGlzcGxheUNvbHVtbjogRGlzcGxheUNvbHVtbjxFbnRpdHlUeXBlPik6IHVua25vd24ge1xuICAgICAgICByZXR1cm4gcnVuSW5JbmplY3Rpb25Db250ZXh0KHRoaXMuaW5qZWN0b3IsICgpID0+IGRpc3BsYXlDb2x1bW4udmFsdWUoZW50aXR5KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYSBjZWxsQ2xpY2tlZCBldmVudCB3aGVuIHRoZSBjbGlja2VkIGNvbHVtbiBpcyBlbmFibGVkIGFuZCBjbGlja2luZyBpcyBhbGxvd2VkIGJ5IHRoZSBjb25maWd1cmF0aW9uLlxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSBvZiB0aGUgcm93IHRoYXQgd2FzIGNsaWNrZWQuXG4gICAgICogQHBhcmFtIGRDb2wgLSBUaGUgZGlzcGxheSBjb2x1bW4gb2YgdGhlIHJvdyB0aGF0IHdhcyBjbGlja2VkLlxuICAgICAqIEBwYXJhbSBjb250ZXh0IC0gVGhlIGNvbnRleHQgb2YgdGhlIHRhYmxlIHdoZXJlIHRoZSBjZWxsIHdhcyBjbGlja2VkLlxuICAgICAqL1xuICAgIGNsaWNrQ2VsbDxUPih2YWx1ZTogVCwgZENvbDogRGlzcGxheUNvbHVtbjxUPiwgY29udGV4dDogVGFibGVDb250ZXh0PFQ+KTogdm9pZCB7XG4gICAgICAgIGlmIChkQ29sLmRpc2FibGVDbGljayA9PSB0cnVlIHx8ICFjb250ZXh0LmFsbG93Q2xpY2sodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dC5jbGlja0NlbGwodmFsdWUsIGRDb2wpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZSA9IHRoaXMuZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZSA/PyB0aGlzLmRlZmF1bHRHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlO1xuICAgICAgICB0aGlzLmludGVybmFsSXNSZWFkT25seSA9IHRoaXMuaXNSZWFkT25seSA/PyBmYWxzZTtcblxuICAgICAgICBjb25zdCBmb3VuZFR5cGU6IERlY29yYXRvclR5cGVzIHwgdW5kZWZpbmVkID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5VHlwZSh0aGlzLmVudGl0eSwgdGhpcy5wcm9wZXJ0eUtleSk7XG4gICAgICAgIGlmIChmb3VuZFR5cGUgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHR5cGUgd2FzIGZvdW5kIGZvciB0aGUga2V5IFwiJHtTdHJpbmcodGhpcy5wcm9wZXJ0eUtleSl9XCJgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnR5cGUgPSBmb3VuZFR5cGU7XG4gICAgICAgIGlmICh0aGlzLnZhbGlkRW1wdHkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRNZXRhZGF0YTogUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDx1bmtub3duPiA9IFJlZmxlY3RVdGlsaXRpZXMuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgICAgJ21ldGFkYXRhJyxcbiAgICAgICAgICAgICAgICB0aGlzLmVudGl0eSxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BlcnR5S2V5XG4gICAgICAgICAgICApIGFzIFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8dW5rbm93bj47XG4gICAgICAgICAgICBSZWZsZWN0VXRpbGl0aWVzLmRlZmluZU1ldGFkYXRhKCdtZXRhZGF0YScsIHsgLi4uY3VycmVudE1ldGFkYXRhLCByZXF1aXJlZDogZGVmYXVsdEZhbHNlIH0sIHRoaXMuZW50aXR5LCB0aGlzLnByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZvdW5kTWV0YWRhdGE6IFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8dW5rbm93bj4gfCB1bmRlZmluZWQgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShcbiAgICAgICAgICAgIHRoaXMuZW50aXR5LFxuICAgICAgICAgICAgdGhpcy5wcm9wZXJ0eUtleSxcbiAgICAgICAgICAgIHRoaXMudHlwZVxuICAgICAgICApO1xuICAgICAgICBpZiAoIWZvdW5kTWV0YWRhdGEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbWV0YWRhdGEgd2FzIGZvdW5kIGZvciB0aGUga2V5IFwiJHtTdHJpbmcodGhpcy5wcm9wZXJ0eUtleSl9XCJgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1ldGFkYXRhID0gZm91bmRNZXRhZGF0YTtcblxuICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5PQkpFQ1RfRFJPUERPV046IHtcbiAgICAgICAgICAgICAgICB2b2lkIHRoaXMuaW5pdERyb3Bkb3duT2JqZWN0SW5wdXQoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuT0JKRUNUOiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0T2JqZWN0SW5wdXQoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuQVJSQVk6IHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRFbnRpdHlBcnJheSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5IQVNfTUFOWToge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdEhhc01hbnkoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuUkVGRVJFTkNFU19PTkU6IHtcbiAgICAgICAgICAgICAgICB2b2lkIHRoaXMuaW5pdFJlZmVyZW5jZXNPbmUoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaW5pdFJlZmVyZW5jZXNPbmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMubWV0YWRhdGFSZWZlcmVuY2VzT25lID0gdGhpcy5tZXRhZGF0YSBhcyBSZWZlcmVuY2VzT25lRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgICAgIHRoaXMucmVmZXJlbmNlc09uZU5hbWUgPSB0aGlzLnByb3BlcnR5S2V5LnRvU3RyaW5nKCkgKyAnaW5wdXQnICsgVVVJRFV0aWxpdGllcy5jcmVhdGUoKTtcblxuICAgICAgICBhd2FpdCBydW5JbkluamVjdGlvbkNvbnRleHQoXG4gICAgICAgICAgICB0aGlzLmluamVjdG9yLFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlc09uZUFsbFJlZmVyZW5jZWRFbnRpdGllcyA9IGF3YWl0IHRoaXMubWV0YWRhdGFSZWZlcmVuY2VzT25lLmdldFJlZmVyZW5jZWRFbnRpdGllcygpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlc09uZURyb3Bkb3duVmFsdWVzID0gdGhpcy5tZXRhZGF0YVJlZmVyZW5jZXNPbmUuZ2V0RHJvcGRvd25WYWx1ZXMoXG4gICAgICAgICAgICAgICAgICAgIExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5yZWZlcmVuY2VzT25lQWxsUmVmZXJlbmNlZEVudGl0aWVzKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJlZFJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5yZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0UmVmZXJlbmNlc09uZU9iamVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbHRlcnMgdGhlIHJlZmVyZW5jZXMgb25lIGRyb3Bkb3duIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0gc2VhcmNoSW5wdXQgLSBUaGUgc2VhcmNoIGlucHV0IHRvIGZpbHRlciBmb3IuXG4gICAgICovXG4gICAgZmlsdGVyUmVmZXJlbmNlc09uZVZhbHVlcyhzZWFyY2hJbnB1dDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGZpbHRlcjogc3RyaW5nID0gc2VhcmNoSW5wdXQudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXJlZFJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5yZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZXMpLmZpbHRlcihvcHRpb24gPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbi5kaXNwbGF5TmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGZpbHRlcikgfHwgb3B0aW9uLnZhbHVlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZmlsdGVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0SGFzTWFueSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBIYXNNYW55RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwoXG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhIGFzIEhhc01hbnlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlLCBFbnRpdHlUeXBlPixcbiAgICAgICAgICAgIHRoaXMuZ2xvYmFsQ29uZmlnXG4gICAgICAgICk7XG4gICAgICAgIFJlZmxlY3RVdGlsaXRpZXMuZGVmaW5lTWV0YWRhdGEoJ21ldGFkYXRhJywgdGhpcy5tZXRhZGF0YSwgdGhpcy5lbnRpdHksIHRoaXMucHJvcGVydHlLZXkpO1xuICAgICAgICB0aGlzLm1ldGFkYXRhSGFzTWFueSA9IHRoaXMubWV0YWRhdGEgYXMgSGFzTWFueURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGUsIEVudGl0eVR5cGU+O1xuICAgICAgICB0aGlzLmhhc01hbnlJbXBvcnRBY3Rpb24gPSBuZXcgQmFzZVRhYmxlQWN0aW9uSW50ZXJuYWwoe1xuICAgICAgICAgICAgLi4udGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmltcG9ydEFjdGlvbkRhdGEsXG4gICAgICAgICAgICBhY3Rpb246ICgpID0+IHRoaXMuc3RhcnRJbXBvcnRKc29uKClcbiAgICAgICAgfSwgdGhpcy5nbG9iYWxDb25maWcpO1xuXG4gICAgICAgIHJ1bkluSW5qZWN0aW9uQ29udGV4dCh0aGlzLmluamVjdG9yLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlBbGxvd0NyZWF0ZSA9IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd0NyZWF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55RW50aXR5U2VydmljZSA9IGluamVjdDxFbnRpdHlTZXJ2aWNlPEVudGl0eVR5cGU+Pih0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuRW50aXR5U2VydmljZUNsYXNzKTtcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueUNyZWF0ZUJhc2VVcmwgPSB0aGlzLm1ldGFkYXRhSGFzTWFueS5jcmVhdGVCYXNlVXJsKHRoaXMuZW50aXR5LCB0aGlzLm1ldGFkYXRhSGFzTWFueSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGdpdmVuRGlzcGxheUNvbHVtbnM6IHN0cmluZ1tdID0gdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmRpc3BsYXlDb2x1bW5zLm1hcCgodikgPT4gdi5kaXNwbGF5TmFtZSk7XG4gICAgICAgIGlmIChnaXZlbkRpc3BsYXlDb2x1bW5zLmZpbmQocyA9PiBzID09PSAnc2VsZWN0JykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgVGhlIG5hbWUgXCJzZWxlY3RcIiBmb3IgYSBkaXNwbGF5IGNvbHVtbiBpcyByZXNlcnZlZC5cbiAgICAgICAgICAgICAgICBQbGVhc2UgY2hvb3NlIGEgZGlmZmVyZW50IG5hbWUuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQgPSB7XG4gICAgICAgICAgICAkaW1wbGljaXQ6IHtcbiAgICAgICAgICAgICAgICAuLi5uZXcgSW50ZXJuYWxDdXN0b21UYWJsZUNvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2xvYmFsQ29uZmlnLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5Q29sdW1uczogdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmRpc3BsYXlDb2x1bW5zIGFzIERpc3BsYXlDb2x1bW48dW5rbm93bj5bXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGhTZWxlY3Rpb246ICF0aGlzLmludGVybmFsSXNSZWFkT25seSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzdHlsaXN0aWMvbWF4LWxlblxuICAgICAgICAgICAgICAgICAgICAgICAgZHluYW1pY1Jvd1N0eWxlQ2xhc3NlczogdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmR5bmFtaWNSb3dTdHlsZUNsYXNzZXMgYXMgRHluYW1pY1N0eWxlQ2xhc3Nlczx1bmtub3duPixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93Q2xpY2s6ICgoZW50aXR5OiBFbnRpdHlUeXBlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd1JlYWQoZW50aXR5KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dVcGRhdGUoZW50aXR5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pIGFzICh2YWx1ZTogdW5rbm93bikgPT4gYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlMb2FkaW5nU3Bpbm5lcjogdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmRpc3BsYXlMb2FkaW5nU3Bpbm5lcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlYXJjaFN0cmluZ0ZvclJvdzogdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnNlYXJjaFN0cmluZyBhcyAodmFsdWU6IHVua25vd24pID0+IHN0cmluZ1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBkaXNwbGF5ZWRDb2x1bW5zOiAhdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5maWx0ZXIodEEgPT4gdEEudHlwZSA9PT0gJ211bHRpLXNlbGVjdCcpLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICA/IGdpdmVuRGlzcGxheUNvbHVtbnNcbiAgICAgICAgICAgICAgICAgICAgOiBbJ3NlbGVjdCddLmNvbmNhdChnaXZlbkRpc3BsYXlDb2x1bW5zKSxcbiAgICAgICAgICAgICAgICBkYXRhU291cmNlOiBuZXcgTWF0VGFibGVEYXRhU291cmNlKCksXG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNob3VsZFNob3dNaXNzaW5nRXJyb3I6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbjogbmV3IFNlbGVjdGlvbk1vZGVsPEVudGl0eVR5cGU+KHRydWUsIFtdKSxcbiAgICAgICAgICAgICAgICBjbGlja0NlbGw6IChlbnRpdHksIGRDb2wpID0+IHRoaXMuZWRpdEhhc01hbnlFbnRpdHkoZW50aXR5LCBkQ29sKVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuaGFzTWFueVRhYmxlQ29udGV4dC4kaW1wbGljaXQuZGF0YVNvdXJjZS5zb3J0aW5nRGF0YUFjY2Vzc29yID0gKGVudGl0eTogRW50aXR5VHlwZSwgaGVhZGVyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3BsYXlDb2x1bW46IERpc3BsYXlDb2x1bW48RW50aXR5VHlwZT4gPSB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZGlzcGxheUNvbHVtbnNcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoKGRwKSA9PiBkcC5kaXNwbGF5TmFtZSA9PT0gaGVhZGVyKSBhcyBEaXNwbGF5Q29sdW1uPEVudGl0eVR5cGU+O1xuICAgICAgICAgICAgICAgIHJldHVybiB0YWJsZUNvbHVtblZhbHVlVG9Tb3J0VmFsdWUoZGlzcGxheUNvbHVtbi52YWx1ZShlbnRpdHkpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmRhdGFTb3VyY2UuZmlsdGVyUHJlZGljYXRlID0gKGVudGl0eTogRW50aXR5VHlwZSwgZmlsdGVyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNlYXJjaFN0cjogc3RyaW5nID0gdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnNlYXJjaFN0cmluZyhlbnRpdHkpO1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkU2VhcmNoU3RyaW5nOiBzdHJpbmcgPSBzZWFyY2hTdHIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZEZpbHRlclN0cmluZzogc3RyaW5nID0gZmlsdGVyLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0dGVkU2VhcmNoU3RyaW5nLmluY2x1ZGVzKGZvcm1hdHRlZEZpbHRlclN0cmluZyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS5lbnRpdGllc1N1YmplY3Quc3Vic2NyaWJlKChlbnRpdGllcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLmRhdGEgPSBlbnRpdGllcztcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueVRhYmxlQ29udGV4dC4kaW1wbGljaXQuc2VsZWN0aW9uLmNsZWFyKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB2b2lkIHJ1bkluSW5qZWN0aW9uQ29udGV4dCh0aGlzLmluamVjdG9yLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZWFkQmFzZVVybDogc3RyaW5nID0gdGhpcy5tZXRhZGF0YUhhc01hbnkucmVhZEJhc2VVcmwodGhpcy5lbnRpdHksIHRoaXMubWV0YWRhdGFIYXNNYW55KTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UucmVhZChyZWFkQmFzZVVybCk7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRFbnRpdHlBcnJheSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBFbnRpdHlBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsKFxuICAgICAgICAgICAgdGhpcy5tZXRhZGF0YSBhcyBFbnRpdHlBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGU+LFxuICAgICAgICAgICAgdGhpcy5nbG9iYWxDb25maWdcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5ID0gdGhpcy5tZXRhZGF0YSBhcyBFbnRpdHlBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGU+O1xuICAgICAgICBpZiAodGhpcy5lbnRpdHlbdGhpcy5wcm9wZXJ0eUtleV0gPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAodGhpcy5lbnRpdHlbdGhpcy5wcm9wZXJ0eUtleV0gYXMgRW50aXR5VHlwZVtdKSA9IFtdO1xuICAgICAgICAgICAgUmVmbGVjdFV0aWxpdGllcy5kZWZpbmVNZXRhZGF0YSgnbWV0YWRhdGEnLCB0aGlzLm1ldGFkYXRhLCB0aGlzLmVudGl0eSwgdGhpcy5wcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlSW5saW5lICYmICF0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlRGlhbG9nRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmNyZWF0ZURpYWxvZ0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdBZGQnXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGdpdmVuRGlzcGxheUNvbHVtbnM6IHN0cmluZ1tdID0gdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmRpc3BsYXlDb2x1bW5zLm1hcCgodikgPT4gdi5kaXNwbGF5TmFtZSk7XG4gICAgICAgIGlmIChnaXZlbkRpc3BsYXlDb2x1bW5zLmZpbmQocyA9PiBzID09PSAnc2VsZWN0JykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgVGhlIG5hbWUgXCJzZWxlY3RcIiBmb3IgYSBkaXNwbGF5IGNvbHVtbiBpcyByZXNlcnZlZC5cbiAgICAgICAgICAgICAgICBQbGVhc2UgY2hvb3NlIGEgZGlmZmVyZW50IG5hbWUuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVudGl0eUFycmF5VGFibGVDb250ZXh0ID0ge1xuICAgICAgICAgICAgJGltcGxpY2l0OiB7XG4gICAgICAgICAgICAgICAgLi4ubmV3IEludGVybmFsQ3VzdG9tVGFibGVDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdsb2JhbENvbmZpZyxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheUNvbHVtbnM6IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5kaXNwbGF5Q29sdW1ucyBhcyBEaXNwbGF5Q29sdW1uPHVua25vd24+W10sXG4gICAgICAgICAgICAgICAgICAgICAgICB3aXRoU2VsZWN0aW9uOiAhdGhpcy5pbnRlcm5hbElzUmVhZE9ubHksXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljUm93U3R5bGVDbGFzc2VzOiB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuZHluYW1pY1Jvd1N0eWxlQ2xhc3NlcyBhcyBEeW5hbWljU3R5bGVDbGFzc2VzPHVua25vd24+LFxuICAgICAgICAgICAgICAgICAgICAgICAgZW1wdHlFcnJvck1lc3NhZ2U6IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5taXNzaW5nRXJyb3JNZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGRpc3BsYXllZENvbHVtbnM6IHRoaXMuaW50ZXJuYWxJc1JlYWRPbmx5ID8gZ2l2ZW5EaXNwbGF5Q29sdW1ucyA6IFsnc2VsZWN0J10uY29uY2F0KGdpdmVuRGlzcGxheUNvbHVtbnMpLFxuICAgICAgICAgICAgICAgIGRhdGFTb3VyY2U6IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UoKSxcbiAgICAgICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3VsZFNob3dNaXNzaW5nRXJyb3I6IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5yZXF1aXJlZCh0aGlzLmVudGl0eSksXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uOiBuZXcgU2VsZWN0aW9uTW9kZWw8RW50aXR5VHlwZT4odHJ1ZSwgW10pLFxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB0eXBlc2NyaXB0L25vLW1pc3VzZWQtcHJvbWlzZXNcbiAgICAgICAgICAgICAgICBjbGlja0NlbGw6IChlbnRpdHksIGRDb2wpID0+IHRoaXMuZWRpdEFycmF5SXRlbShlbnRpdHksIGRDb2wpXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW50aXR5QXJyYXlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmRhdGFTb3VyY2UuZGF0YSA9IHRoaXMuZW50aXR5W3RoaXMucHJvcGVydHlLZXldIGFzIEVudGl0eVR5cGVbXTtcblxuICAgICAgICB0aGlzLmFycmF5SXRlbSA9IG5ldyB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuRW50aXR5Q2xhc3MoKTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW1QcmlvckNoYW5nZXMgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMuYXJyYXlJdGVtKTtcbiAgICAgICAgRW50aXR5VXRpbGl0aWVzLnNldERlZmF1bHRWYWx1ZXModGhpcy5hcnJheUl0ZW0pO1xuXG4gICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQgPSB7XG4gICAgICAgICAgICAkaW1wbGljaXQ6IHtcbiAgICAgICAgICAgICAgICBlbnRpdHk6IHRoaXMuYXJyYXlJdGVtLFxuICAgICAgICAgICAgICAgIHRhYnM6IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCB0cnVlKSxcbiAgICAgICAgICAgICAgICBpbnB1dENoYW5nZUV2ZW50OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZvaWQgdGhpcy5jaGVja0lzQXJyYXlJdGVtVmFsaWQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1Gb3JtQ29udGV4dC4kaW1wbGljaXQudGFicyA9IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGhpZGVPbWl0Rm9yQ3JlYXRlOiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQyID0gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFkZEFycmF5SXRlbUZvcm1Db250ZXh0KTtcbiAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1EaWFsb2dEYXRhID0gbmV3IENyZWF0ZURhdGFCdWlsZGVyKHRoaXMuZ2xvYmFsQ29uZmlnLCB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlRGlhbG9nRGF0YSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgnY3JlYXRlQnV0dG9uTGFiZWwnLCB0aGlzLmdsb2JhbENvbmZpZy5hZGRMYWJlbClcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGl0bGUnLCB0aGlzLmdsb2JhbENvbmZpZy5hZGRBcnJheUl0ZW1UaXRsZSlcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcblxuICAgICAgICB0aGlzLmVkaXRBcnJheUl0ZW1EaWFsb2dEYXRhID0gdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmVkaXREaWFsb2dEYXRhO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaW5pdERyb3Bkb3duT2JqZWN0SW5wdXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMubWV0YWRhdGFEcm9wZG93bk9iamVjdCA9IHRoaXMubWV0YWRhdGEgYXMgRHJvcGRvd25PYmplY3REZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICAgICAgdGhpcy5vYmplY3REcm9wZG93bk5hbWUgPSB0aGlzLnByb3BlcnR5S2V5LnRvU3RyaW5nKCkgKyAnaW5wdXQnICsgVVVJRFV0aWxpdGllcy5jcmVhdGUoKTtcblxuICAgICAgICBhd2FpdCBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vYmplY3REcm9wZG93blZhbHVlcyA9IGF3YWl0IHRoaXMubWV0YWRhdGFEcm9wZG93bk9iamVjdC5kcm9wZG93blZhbHVlcyh0aGlzLmVudGl0eSk7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcmVkT2JqZWN0RHJvcGRvd25WYWx1ZXMgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMub2JqZWN0RHJvcGRvd25WYWx1ZXMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRPYmplY3RJbnB1dCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tZXRhZGF0YURlZmF1bHRPYmplY3QgPSB0aGlzLm1ldGFkYXRhIGFzIERlZmF1bHRPYmplY3REZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJvcGVydHk6IEVudGl0eVR5cGUgPSB0aGlzLmVudGl0eVt0aGlzLnByb3BlcnR5S2V5XSBhcyBFbnRpdHlUeXBlO1xuICAgICAgICBjb25zdCBvYmplY3RQcm9wZXJ0eVRhYnM6IEVudGl0eVRhYjxFbnRpdHlUeXBlPltdID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnMoXG4gICAgICAgICAgICBvYmplY3RQcm9wZXJ0eSxcbiAgICAgICAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICAgICAgICB0aGlzLmhpZGVPbWl0Rm9yQ3JlYXRlLFxuICAgICAgICAgICAgdGhpcy5oaWRlT21pdEZvckVkaXQsXG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhRGVmYXVsdE9iamVjdC5vbWl0XG4gICAgICAgICk7XG4gICAgICAgIHRoaXMub2JqZWN0Rm9ybUNvbnRleHQgPSB7XG4gICAgICAgICAgICAkaW1wbGljaXQ6IHtcbiAgICAgICAgICAgICAgICBlbnRpdHk6IG9iamVjdFByb3BlcnR5LFxuICAgICAgICAgICAgICAgIHRhYnM6IG9iamVjdFByb3BlcnR5VGFicyxcbiAgICAgICAgICAgICAgICBoaWRlT21pdEZvckNyZWF0ZTogdGhpcy5oaWRlT21pdEZvckNyZWF0ZSxcbiAgICAgICAgICAgICAgICBoaWRlT21pdEZvckVkaXQ6IHRoaXMuaGlkZU9taXRGb3JFZGl0LFxuICAgICAgICAgICAgICAgIGlzUmVhZE9ubHk6IChwcm9wZXJ0eSwga2V5KSA9PiB0aGlzLmlzUHJvcGVydHlSZWFkT25seShwcm9wZXJ0eSwga2V5KSxcbiAgICAgICAgICAgICAgICBpbnB1dENoYW5nZUV2ZW50OiAoKSA9PiB0aGlzLmVtaXRDaGFuZ2UoKSxcbiAgICAgICAgICAgICAgICB2YWxpZEVtcHR5OiAoKSA9PiAhdGhpcy5tZXRhZGF0YS5yZXF1aXJlZCh0aGlzLmVudGl0eSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXJ0SW1wb3J0SnNvbigpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICBpbnB1dC50eXBlID0gJ2ZpbGUnO1xuICAgICAgICBpbnB1dC5hY2NlcHQgPSAnYXBwbGljYXRpb24vanNvbic7XG4gICAgICAgIGlucHV0Lm9uY2hhbmdlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlucHV0LmZpbGVzKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5pbXBvcnRKc29uKGlucHV0LmZpbGVzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaW5wdXQuY2xpY2soKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGltcG9ydEpzb24oZmlsZTogRmlsZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc3R5bGlzdGljL21heC1sZW5cbiAgICAgICAgY29uc3QgZGlhbG9nRGF0YTogQ29uZmlybURpYWxvZ0RhdGFJbnRlcm5hbCA9IG5ldyBDb25maXJtRGlhbG9nRGF0YUJ1aWxkZXIodGhpcy5nbG9iYWxDb25maWcsIHRoaXMuaGFzTWFueUltcG9ydEFjdGlvbi5jb25maXJtRGlhbG9nRGF0YSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGV4dCcsIHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5pbXBvcnRBY3Rpb25EYXRhLmNvbmZpcm1EaWFsb2dEYXRhPy50ZXh0KVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsIHRoaXMuaGFzTWFueUltcG9ydEFjdGlvbi5kaXNwbGF5TmFtZSlcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVzOiBib29sZWFuIHwgdW5kZWZpbmVkID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkpO1xuICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuaW1wb3J0KGZpbGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHR3byBvYmplY3RzIGFyZSBlcXVhbC4gSXMgbmVlZGVkIGZvciB0aGUgZHJvcGRvd24uXG4gICAgICogQHBhcmFtIHZhbHVlMSAtIFRoZSBmaXJzdCBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0gdmFsdWUyIC0gVGhlIHNlY29uZCBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgb2JqZWN0cyBhcmUgdGhlIHNhbWUuXG4gICAgICovXG4gICAgcHJpdmF0ZSBjb21wYXJlT2JqZWN0cyh2YWx1ZTE/OiBFbnRpdHlUeXBlLCB2YWx1ZTI/OiBFbnRpdHlUeXBlKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHZhbHVlT2JqZWN0MTogRW50aXR5VHlwZSA9IG5ldyB0aGlzLm1ldGFkYXRhRHJvcGRvd25PYmplY3QuRW50aXR5Q2xhc3ModmFsdWUxKTtcbiAgICAgICAgY29uc3QgdmFsdWVPYmplY3QyOiBFbnRpdHlUeXBlID0gbmV3IHRoaXMubWV0YWRhdGFEcm9wZG93bk9iamVjdC5FbnRpdHlDbGFzcyh2YWx1ZTIpO1xuICAgICAgICByZXR1cm4gTG9kYXNoVXRpbGl0aWVzLmlzRXF1YWwodmFsdWVPYmplY3QxLCB2YWx1ZU9iamVjdDIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbHRlcnMgdGhlIGRyb3Bkb3duIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0gc2VhcmNoSW5wdXQgLSBUaGUgc2VhcmNoIGlucHV0IHRvIGZpbHRlciBmb3IuXG4gICAgICovXG4gICAgZmlsdGVyT2JqZWN0RHJvcGRvd25WYWx1ZXMoc2VhcmNoSW5wdXQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBmaWx0ZXI6IHN0cmluZyA9IHNlYXJjaElucHV0LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHRoaXMuZmlsdGVyZWRPYmplY3REcm9wZG93blZhbHVlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5vYmplY3REcm9wZG93blZhbHVlcykuZmlsdGVyKG9wdGlvbiA9PiB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9uLmRpc3BsYXlOYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZmlsdGVyKSB8fCBKU09OLnN0cmluZ2lmeShvcHRpb24udmFsdWUpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgICAuaW5jbHVkZXMoZmlsdGVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcmVmZXJlbmNlcyBvbmUgb2JqZWN0IHVzaW5nIHRoZSBpbnB1dCBpZC5cbiAgICAgKi9cbiAgICBzZXRSZWZlcmVuY2VzT25lT2JqZWN0KCk6IHZvaWQge1xuICAgICAgICBjb25zdCBmb3VuZEVudGl0eTogRW50aXR5VHlwZSB8IHVuZGVmaW5lZCA9IHRoaXMubWV0YWRhdGFSZWZlcmVuY2VzT25lLmdldEVudGl0eUZvcklkKFxuICAgICAgICAgICAgdGhpcy5lbnRpdHlbdGhpcy5wcm9wZXJ0eUtleV0gYXMgc3RyaW5nLFxuICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VzT25lQWxsUmVmZXJlbmNlZEVudGl0aWVzXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlZmVyZW5jZXNPbmVPYmplY3Q6IEVudGl0eVR5cGUgPSBuZXcgdGhpcy5tZXRhZGF0YVJlZmVyZW5jZXNPbmUuRW50aXR5Q2xhc3MoZm91bmRFbnRpdHkpO1xuICAgICAgICBjb25zdCByZWZlcmVuY2VzT25lUHJvcGVydHlUYWJzOiBFbnRpdHlUYWI8RW50aXR5VHlwZT5bXSA9IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKFxuICAgICAgICAgICAgcmVmZXJlbmNlc09uZU9iamVjdCxcbiAgICAgICAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhUmVmZXJlbmNlc09uZS5vbWl0XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFSZWZlcmVuY2VzT25lLmRyb3Bkb3duT25seSkge1xuICAgICAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlZmVyZW5jZXNPbmVGb3JtQ29udGV4dCA9IHtcbiAgICAgICAgICAgICRpbXBsaWNpdDoge1xuICAgICAgICAgICAgICAgIGVudGl0eTogcmVmZXJlbmNlc09uZU9iamVjdCxcbiAgICAgICAgICAgICAgICB0YWJzOiByZWZlcmVuY2VzT25lUHJvcGVydHlUYWJzLFxuICAgICAgICAgICAgICAgIGhpZGVPbWl0Rm9yQ3JlYXRlOiB0aGlzLmhpZGVPbWl0Rm9yQ3JlYXRlLFxuICAgICAgICAgICAgICAgIGhpZGVPbWl0Rm9yRWRpdDogdGhpcy5oaWRlT21pdEZvckVkaXQsXG4gICAgICAgICAgICAgICAgaXNSZWFkT25seTogKCkgPT4gdHJ1ZSxcbiAgICAgICAgICAgICAgICBpbnB1dENoYW5nZUV2ZW50OiAoKSA9PiB0aGlzLmVtaXRDaGFuZ2UoKSxcbiAgICAgICAgICAgICAgICB2YWxpZEVtcHR5OiAoKSA9PiAhdGhpcy5tZXRhZGF0YS5yZXF1aXJlZCh0aGlzLmVudGl0eSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRWRpdHMgYW4gZW50aXR5LiBUaGlzIGVpdGhlciBjYWxscyB0aGUgZWRpdC1NZXRob2QgcHJvdmlkZWQgYnkgdGhlIHVzZXIgb3IgdXNlcyBhIGRlZmF1bHQgZWRpdC1kaWFsb2cuXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgdGhhdCBzaG91bGQgYmUgdXBkYXRlZC5cbiAgICAgKiBAcGFyYW0gZENvbCAtIFRoZSBkaXNwbGF5IGNvbHVtbiB0aGF0IHdhcyBjbGlja2VkIG9uLlxuICAgICAqIEB0aHJvd3MgV2hlbiBubyBFbnRpdHlDbGFzcyB3YXMgcHJvdmlkZWQsIGFzIGEgbmV3IGNhbGwgaXMgbmVlZGVkIHRvIGluaXRpYWxpemUgbWV0YWRhdGEuXG4gICAgICovXG4gICAgZWRpdEhhc01hbnlFbnRpdHkoZW50aXR5OiBFbnRpdHlUeXBlLCBkQ29sOiBEaXNwbGF5Q29sdW1uPEVudGl0eVR5cGU+KTogdm9pZCB7XG4gICAgICAgIGlmICgoZENvbC5kaXNhYmxlQ2xpY2sgPT09IHRydWUpIHx8ICghdGhpcy5oYXNNYW55QWxsb3dVcGRhdGUoZW50aXR5KSAmJiAhdGhpcy5oYXNNYW55QWxsb3dSZWFkKGVudGl0eSkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuRW50aXR5Q2xhc3MpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gXCJFbnRpdHlDbGFzc1wiIHNwZWNpZmllZCBmb3IgdGhpcyB0YWJsZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZWRpdCkge1xuICAgICAgICAgICAgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmVkaXQobmV3IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcyhlbnRpdHkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmRlZmF1bHRFZGl0ID09ICdwYWdlJykge1xuICAgICAgICAgICAgdGhpcy5lZGl0SGFzTWFueURlZmF1bHRQYWdlKG5ldyB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuRW50aXR5Q2xhc3MoZW50aXR5KSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdm9pZCB0aGlzLmVkaXRIYXNNYW55RGVmYXVsdERpYWxvZyhuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKGVudGl0eSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdXBkYXRpbmcgdGhlIHByb3ZpZGVkIGVudGl0eSBmcm9tIHRoZSBoYXMgbWFueSBwcm9wZXJ0eSBpcyBhbGxvd2VkLlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBBIHNpbmdsZSB2YWx1ZSBvZiB0aGUgaGFzIG1hbnkgcHJvcGVydHkgdGhhdCB0aGUgdXNlciB3YW50cyB0byBlZGl0LlxuICAgICAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgdXNlciBjYW4gZWRpdCB0aGUgcHJvdmlkZWQgZW50aXR5IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaGFzTWFueUFsbG93VXBkYXRlKGVudGl0eTogRW50aXR5VHlwZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcnVuSW5JbmplY3Rpb25Db250ZXh0KHRoaXMuaW5qZWN0b3IsICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dVcGRhdGUoZW50aXR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB2aWV3aW5nIHRoZSBwcm92aWRlZCBlbnRpdHkgZnJvbSB0aGUgaGFzIG1hbnkgcHJvcGVydHkgaXMgYWxsb3dlZC5cbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gQSBzaW5nbGUgdmFsdWUgb2YgdGhlIGhhcyBtYW55IHByb3BlcnR5IHRoYXQgdGhlIHVzZXIgd2FudHMgdG8gdmlldy5cbiAgICAgKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHVzZXIgY2FuIHZpZXcgdGhlIHByb3ZpZGVkIGVudGl0eSBhbmQgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGhhc01hbnlBbGxvd1JlYWQoZW50aXR5OiBFbnRpdHlUeXBlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd1JlYWQoZW50aXR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBkZWxldGluZyB0aGUgcHJvdmlkZWQgZW50aXR5IGZyb20gdGhlIGhhcyBtYW55IHByb3BlcnR5IGlzIGFsbG93ZWQuXG4gICAgICogQHBhcmFtIGVudGl0eSAtIEEgc2luZ2xlIHZhbHVlIG9mIHRoZSBoYXMgbWFueSBwcm9wZXJ0eSB0aGF0IHRoZSB1c2VyIHdhbnRzIHRvIGRlbGV0ZS5cbiAgICAgKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHVzZXIgY2FuIGRlbGV0ZSB0aGUgcHJvdmlkZWQgZW50aXR5IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaGFzTWFueUFsbG93RGVsZXRlKGVudGl0eTogRW50aXR5VHlwZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcnVuSW5JbmplY3Rpb25Db250ZXh0KHRoaXMuaW5qZWN0b3IsICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dEZWxldGUoZW50aXR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGFuIEVkaXRBY3Rpb24gaXMgZGlzYWJsZWQgKGUuZy4gQmVjYXVzZSB0aGUgY3VycmVudCBlbnRyeSBkb2Vzbid0IGZ1bGxmaWwgdGhlIHJlcXVpcmVtZW50cykuXG4gICAgICogQHBhcmFtIGFjdGlvbiAtIFRoZSBFZGl0QWN0aW9uIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IHRoZSBBY3Rpb24gY2FuIGJlIHVzZWQuXG4gICAgICovXG4gICAgaGFzTWFueUVkaXRBY3Rpb25EaXNhYmxlZChhY3Rpb246IEVkaXRBY3Rpb25JbnRlcm5hbDxFbnRpdHlUeXBlPik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcnVuSW5JbmplY3Rpb25Db250ZXh0KHRoaXMuaW5qZWN0b3IsICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhYWN0aW9uLmVuYWJsZWQodGhpcy5oYXNNYW55RW50aXR5UHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyB0aGUgZWRpdCBhY3Rpb24gb24gdGhlIGVudGl0eS5cbiAgICAgKiBAcGFyYW0gYWN0aW9uIC0gVGhlIGFjdGlvbiB0byBydW4uXG4gICAgICovXG4gICAgYXN5bmMgaGFzTWFueVJ1bkVkaXRBY3Rpb24oYWN0aW9uOiBFZGl0QWN0aW9uSW50ZXJuYWw8RW50aXR5VHlwZT4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgcmVxdWlyZUNvbmZpcm1EaWFsb2c6IGJvb2xlYW4gPSBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbi5yZXF1aXJlQ29uZmlybURpYWxvZyh0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXJlcXVpcmVDb25maXJtRGlhbG9nKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbmZpcm1IYXNNYW55UnVuRWRpdEFjdGlvbihhY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIGJvb2xlYW4+ID0gdGhpcy5kaWFsb2cub3BlbihOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgICBkYXRhOiBhY3Rpb24uY29uZmlybURpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVzOiBib29sZWFuIHwgdW5kZWZpbmVkID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkpO1xuICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29uZmlybUhhc01hbnlSdW5FZGl0QWN0aW9uKGFjdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNvbmZpcm1IYXNNYW55UnVuRWRpdEFjdGlvbihhY3Rpb246IEVkaXRBY3Rpb25JbnRlcm5hbDxFbnRpdHlUeXBlPik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgYWN0aW9uLmFjdGlvbih0aGlzLmhhc01hbnlFbnRpdHksIHRoaXMuaGFzTWFueUVudGl0eVByaW9yQ2hhbmdlcyk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNoZWNrSGFzTWFueUVudGl0eSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGVkaXRIYXNNYW55RGVmYXVsdFBhZ2UoZW50aXR5OiBFbnRpdHlUeXBlKTogdm9pZCB7XG4gICAgICAgIHZvaWQgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycnLCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmVkaXRCYXNlUm91dGUsIGVudGl0eVt0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmlkS2V5XV0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZWRpdEhhc01hbnlEZWZhdWx0RGlhbG9nKGVudGl0eTogRW50aXR5VHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHkgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKGVudGl0eSk7XG4gICAgICAgIHRoaXMuaGFzTWFueUVudGl0eVByaW9yQ2hhbmdlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5oYXNNYW55RW50aXR5KTtcbiAgICAgICAgdGhpcy5oYXNNYW55RWRpdEZvcm1Db250ZXh0ID0ge1xuICAgICAgICAgICAgJGltcGxpY2l0OiB7XG4gICAgICAgICAgICAgICAgZW50aXR5OiB0aGlzLmhhc01hbnlFbnRpdHksXG4gICAgICAgICAgICAgICAgaGlkZU9taXRGb3JFZGl0OiB0cnVlLFxuICAgICAgICAgICAgICAgIGlzUmVhZE9ubHk6IChwcm9wZXJ0eSwga2V5KSA9PiB0aGlzLmlzUHJvcGVydHlSZWFkT25seShwcm9wZXJ0eSwga2V5KSxcbiAgICAgICAgICAgICAgICBpbnB1dENoYW5nZUV2ZW50OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZvaWQgdGhpcy5jaGVja0hhc01hbnlFbnRpdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNNYW55RWRpdEZvcm1Db250ZXh0LiRpbXBsaWNpdC50YWJzID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnMoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHksXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluamVjdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnVlXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0YWJzOiBFbnRpdHlVdGlsaXRpZXMuZ2V0RW50aXR5VGFicyh0aGlzLmhhc01hbnlFbnRpdHksIHRoaXMuaW5qZWN0b3IsIGZhbHNlLCB0cnVlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrSGFzTWFueUVudGl0eSgpO1xuICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuZWRpdEhhc01hbnlEaWFsb2csXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWluV2lkdGg6ICc2MCUnLFxuICAgICAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBjb25zdCByZXM6IG51bWJlciA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuZWRpdEhhc01hbnlEaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKSkgYXMgbnVtYmVyO1xuICAgICAgICBpZiAocmVzID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhOiBFbnRpdHlUeXBlW10gPSB0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmRhdGFTb3VyY2UuZGF0YTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzdHlsaXN0aWMvbWF4LWxlblxuICAgICAgICAgICAgZGF0YVt0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmRhdGFTb3VyY2UuZGF0YS5maW5kSW5kZXgoKGUpID0+IGVbdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS5pZEtleV0gPT09IGVudGl0eVt0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmlkS2V5XSldID0gZW50aXR5O1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLmRhdGEgPSBkYXRhO1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55VGFibGVDb250ZXh0LiRpbXBsaWNpdC5zZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWVzIHRvIHNhdmUgdGhlIGNoYW5nZXMgYW5kIGNsb3NlIHRoZSBkaWFsb2cgYWZ0ZXJ3YXJkcy5cbiAgICAgKiBBbHNvIGhhbmRsZXMgdGhlIGNvbmZpcm1hdGlvbiBpZiByZXF1aXJlZC5cbiAgICAgKi9cbiAgICBhc3luYyBkaWFsb2dFZGl0SGFzTWFueSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuaW50ZXJuYWxJc1JlYWRPbmx5IHx8ICF0aGlzLmlzSGFzTWFueUVudGl0eVZhbGlkIHx8ICF0aGlzLmlzSGFzTWFueUVudGl0eURpcnR5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuZWRpdFJlcXVpcmVzQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5kaWFsb2dDb25maXJtRWRpdEhhc01hbnkoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzdHlsaXN0aWMvbWF4LWxlblxuICAgICAgICBjb25zdCBkaWFsb2dEYXRhOiBDb25maXJtRGlhbG9nRGF0YUludGVybmFsID0gbmV3IENvbmZpcm1EaWFsb2dEYXRhQnVpbGRlcih0aGlzLmdsb2JhbENvbmZpZywgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmNvbmZpcm1FZGl0RGlhbG9nRGF0YSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGV4dCcsIHRoaXMuZ2xvYmFsQ29uZmlnLmNvbmZpcm1TYXZlVGV4dClcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgnY29uZmlybUJ1dHRvbkxhYmVsJywgdGhpcy5nbG9iYWxDb25maWcuc2F2ZUxhYmVsKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsIHRoaXMuZ2xvYmFsQ29uZmlnLmVkaXRMYWJlbClcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVzOiBib29sZWFuIHwgdW5kZWZpbmVkID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkpO1xuICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZGlhbG9nQ29uZmlybUVkaXRIYXNNYW55KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHJpdmF0ZSBhc3luYyBkaWFsb2dDb25maXJtRWRpdEhhc01hbnkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UudXBkYXRlKHRoaXMuaGFzTWFueUVudGl0eSwgdGhpcy5oYXNNYW55RW50aXR5UHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgdGhpcy5lZGl0SGFzTWFueURpYWxvZ1JlZi5jbG9zZSgxKTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJpZXMgdG8gZGVsZXRlIHRoZSBlbnRpdHkgYW5kIGNsb3NlIHRoZSBkaWFsb2cgYWZ0ZXJ3YXJkcy5cbiAgICAgKiBBbHNvIGhhbmRsZXMgdGhlIGNvbmZpcm1hdGlvbiBpZiByZXF1aXJlZC5cbiAgICAgKi9cbiAgICBhc3luYyBkZWxldGVIYXNNYW55RW50aXR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5lZGl0RGF0YS5kZWxldGVSZXF1aXJlc0NvbmZpcm1EaWFsb2cpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29uZmlybURlbGV0ZUhhc01hbnlFbnRpdHkoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzdHlsaXN0aWMvbWF4LWxlblxuICAgICAgICBjb25zdCBkaWFsb2dEYXRhOiBDb25maXJtRGlhbG9nRGF0YUludGVybmFsID0gbmV3IENvbmZpcm1EaWFsb2dEYXRhQnVpbGRlcih0aGlzLmdsb2JhbENvbmZpZywgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmNvbmZpcm1EZWxldGVEaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgdGhpcy5nbG9iYWxDb25maWcuY29uZmlybURlbGV0ZVRleHQpXG4gICAgICAgICAgICAud2l0aERlZmF1bHQoJ3R5cGUnLCAnZGVsZXRlJylcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgnY29uZmlybUJ1dHRvbkxhYmVsJywgdGhpcy5nbG9iYWxDb25maWcuZGVsZXRlTGFiZWwpXG4gICAgICAgICAgICAud2l0aERlZmF1bHQoJ3RpdGxlJywgdGhpcy5nbG9iYWxDb25maWcuZGVsZXRlTGFiZWwpXG4gICAgICAgICAgICAuZ2V0UmVzdWx0KCk7XG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIGJvb2xlYW4+ID0gdGhpcy5kaWFsb2cub3BlbihOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgICBkYXRhOiBkaWFsb2dEYXRhLFxuICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgIHJlc3RvcmVGb2N1czogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlczogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpKTtcbiAgICAgICAgaWYgKHJlcyA9PSB0cnVlKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbmZpcm1EZWxldGVIYXNNYW55RW50aXR5KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNvbmZpcm1EZWxldGVIYXNNYW55RW50aXR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmRlbGV0ZSh0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpO1xuICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGlhbG9nUmVmLmNsb3NlKDIpO1xuICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIHRoZSBlZGl0aW5nIG9mIHRoZSBoYXMgbWFueSBlbnRpdHkgYW5kIGNsb3NlcyB0aGUgZGlhbG9nLlxuICAgICAqL1xuICAgIGRpYWxvZ0NhbmNlbEVkaXRIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICBFbnRpdHlVdGlsaXRpZXMucmVzZXRDaGFuZ2VzT25FbnRpdHkodGhpcy5oYXNNYW55RW50aXR5LCB0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpO1xuICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGlhbG9nUmVmLmNsb3NlKDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgRW50aXR5LiBUaGlzIGVpdGhlciBjYWxscyB0aGUgY3JlYXRlLU1ldGhvZCBwcm92aWRlZCBieSB0aGUgdXNlciBvciB1c2VzIGEgZGVmYXVsdCBjcmVhdGUtZGlhbG9nLlxuICAgICAqIEB0aHJvd3MgV2hlbiBubyBFbnRpdHlDbGFzcyB3YXMgcHJvdmlkZWQsIGFzIGEgbmV3IGNhbGwgaXMgbmVlZGVkIHRvIGluaXRpYWxpemUgbWV0YWRhdGEuXG4gICAgICovXG4gICAgY3JlYXRlSGFzTWFueUVudGl0eSgpOiB2b2lkIHtcbiAgICAgICAgdm9pZCBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd0NyZWF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuRW50aXR5Q2xhc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBcIkVudGl0eUNsYXNzXCIgc3BlY2lmaWVkIGZvciB0aGlzIHRhYmxlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuY3JlYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5jcmVhdGUobmV3IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcygpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBlbnRpdHk6IEVudGl0eVR5cGUgPSBuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKCk7XG4gICAgICAgICAgICAgICAgRW50aXR5VXRpbGl0aWVzLnNldERlZmF1bHRWYWx1ZXMoZW50aXR5KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmRlZmF1bHRDcmVhdGUgPT0gJ3BhZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlSGFzTWFueURlZmF1bHRQYWdlKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jcmVhdGVIYXNNYW55RGVmYXVsdERpYWxvZyhlbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZUhhc01hbnlEZWZhdWx0UGFnZSgpOiB2b2lkIHtcbiAgICAgICAgdm9pZCB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuY3JlYXRlQmFzZVJvdXRlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNyZWF0ZUhhc01hbnlEZWZhdWx0RGlhbG9nKGVudGl0eTogRW50aXR5VHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHkgPSBlbnRpdHk7XG4gICAgICAgIHRoaXMuaGFzTWFueUNyZWF0ZUZvcm1Db250ZXh0ID0ge1xuICAgICAgICAgICAgJGltcGxpY2l0OiB7XG4gICAgICAgICAgICAgICAgZW50aXR5OiB0aGlzLmhhc01hbnlFbnRpdHksXG4gICAgICAgICAgICAgICAgaGlkZU9taXRGb3JDcmVhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgaW5wdXRDaGFuZ2VFdmVudDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB2b2lkIHRoaXMuY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZCgnY3JlYXRlJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGFzTWFueUNyZWF0ZUZvcm1Db250ZXh0LiRpbXBsaWNpdC50YWJzID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnModGhpcy5oYXNNYW55RW50aXR5LCB0aGlzLmluamVjdG9yLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRhYnM6IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuaGFzTWFueUVudGl0eSwgdGhpcy5pbmplY3RvciwgdHJ1ZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0lzSGFzTWFueUVudGl0eVZhbGlkKCdjcmVhdGUnKTtcbiAgICAgICAgdGhpcy5jcmVhdGVIYXNNYW55RGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlSGFzTWFueURpYWxvZyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogJzYwJScsXG4gICAgICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgaGFzIG1hbnkgZW50aXR5IG92ZXIgdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBhc3luYyBkaWFsb2dDcmVhdGVIYXNNYW55KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMuaXNIYXNNYW55RW50aXR5VmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEYXRhLmNyZWF0ZVJlcXVpcmVzQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5kaWFsb2dDb25maXJtQ3JlYXRlSGFzTWFueSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHN0eWxpc3RpYy9tYXgtbGVuXG4gICAgICAgIGNvbnN0IGRpYWxvZ0RhdGE6IENvbmZpcm1EaWFsb2dEYXRhSW50ZXJuYWwgPSBuZXcgQ29uZmlybURpYWxvZ0RhdGFCdWlsZGVyKHRoaXMuZ2xvYmFsQ29uZmlnLCB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuY3JlYXRlRGF0YS5jb25maXJtQ3JlYXRlRGlhbG9nRGF0YSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGV4dCcsIHRoaXMuZ2xvYmFsQ29uZmlnLmNvbmZpcm1DcmVhdGVUZXh0KVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCdjb25maXJtQnV0dG9uTGFiZWwnLCB0aGlzLmdsb2JhbENvbmZpZy5jcmVhdGVMYWJlbClcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGl0bGUnLCB0aGlzLmdsb2JhbENvbmZpZy5jcmVhdGVMYWJlbClcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVzOiBib29sZWFuIHwgdW5kZWZpbmVkID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkpO1xuICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZGlhbG9nQ29uZmlybUNyZWF0ZUhhc01hbnkoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwcml2YXRlIGFzeW5jIGRpYWxvZ0NvbmZpcm1DcmVhdGVIYXNNYW55KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmNyZWF0ZSh0aGlzLmhhc01hbnlFbnRpdHksIHRoaXMuaGFzTWFueUNyZWF0ZUJhc2VVcmwpO1xuICAgICAgICB0aGlzLmNyZWF0ZUhhc01hbnlEaWFsb2dSZWYuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FuY2VscyB0aGUgY3JlYXRpbmcgb2YgdGhlIGhhcyBtYW55IGVudGl0eSBhbmQgY2xvc2VzIHRoZSBkaWFsb2cuXG4gICAgICovXG4gICAgZGlhbG9nQ2FuY2VsQ3JlYXRlSGFzTWFueSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jcmVhdGVIYXNNYW55RGlhbG9nUmVmLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyB0aGUgVGFibGVBY3Rpb24gZm9yIGFsbCBzZWxlY3RlZCBlbnRyaWVzLlxuICAgICAqIEFsc28gaGFuZGxlcyBjb25maXJtYXRpb24gd2l0aCBhbiBhZGRpdGlvbmFsIGRpYWwjb2cgaWYgY29uZmlndXJlZC5cbiAgICAgKiBAcGFyYW0gYWN0aW9uIC0gVGhlIFRhYmxlQWN0aW9uIHRvIHJ1bi5cbiAgICAgKi9cbiAgICBhc3luYyBydW5IYXNNYW55VGFibGVBY3Rpb24oYWN0aW9uOiBUYWJsZUFjdGlvbkludGVybmFsPEVudGl0eVR5cGU+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHJlcXVpcmVDb25maXJtRGlhbG9nOiBib29sZWFuID0gcnVuSW5JbmplY3Rpb25Db250ZXh0KFxuICAgICAgICAgICAgdGhpcy5pbmplY3RvcixcbiAgICAgICAgICAgICgpID0+IGFjdGlvbi5yZXF1aXJlQ29uZmlybURpYWxvZyh0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LnNlbGVjdGlvbi5zZWxlY3RlZClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFyZXF1aXJlQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jb25maXJtUnVuSGFzTWFueVRhYmxlQWN0aW9uKGFjdGlvbik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZWZhdWx0VGV4dDogc3RyaW5nW10gPSBhY3Rpb24udHlwZSA9PT0gJ211bHRpLXNlbGVjdCdcbiAgICAgICAgICAgID8gdGhpcy5nbG9iYWxDb25maWcuY29uZmlybU11bHRpU2VsZWN0QWN0aW9uVGV4dCh0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LnNlbGVjdGlvbi5zZWxlY3RlZClcbiAgICAgICAgICAgIDogdGhpcy5nbG9iYWxDb25maWcuY29uZmlybUJhc2VBY3Rpb25UZXh0O1xuICAgICAgICBjb25zdCBkaWFsb2dEYXRhOiBDb25maXJtRGlhbG9nRGF0YUludGVybmFsID0gbmV3IENvbmZpcm1EaWFsb2dEYXRhQnVpbGRlcih0aGlzLmdsb2JhbENvbmZpZywgYWN0aW9uLmNvbmZpcm1EaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgZGVmYXVsdFRleHQpXG4gICAgICAgICAgICAud2l0aERlZmF1bHQoJ3RpdGxlJywgYWN0aW9uLmRpc3BsYXlOYW1lKVxuICAgICAgICAgICAgLmdldFJlc3VsdCgpO1xuICAgICAgICBjb25zdCBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCBib29sZWFuPiA9IHRoaXMuZGlhbG9nLm9wZW4oTmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICAgICAgZGF0YTogZGlhbG9nRGF0YSxcbiAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXM6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbShkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKSk7XG4gICAgICAgIGlmIChyZXMgPT0gdHJ1ZSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jb25maXJtUnVuSGFzTWFueVRhYmxlQWN0aW9uKGFjdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNvbmZpcm1SdW5IYXNNYW55VGFibGVBY3Rpb24oYWN0aW9uOiBUYWJsZUFjdGlvbkludGVybmFsPEVudGl0eVR5cGU+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHJ1bkluSW5qZWN0aW9uQ29udGV4dCh0aGlzLmluamVjdG9yLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBhY3Rpb24uYWN0aW9uKHRoaXMuaGFzTWFueVRhYmxlQ29udGV4dC4kaW1wbGljaXQuc2VsZWN0aW9uLnNlbGVjdGVkKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdENoYW5nZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYW4gVGFibGVBY3Rpb24gaXMgZGlzYWJsZWQgKGUuZy4gQmVjYXVzZSBubyBlbnRyaWVzIGhhdmUgYmVlbiBzZWxlY3RlZCkuXG4gICAgICogQHBhcmFtIGFjdGlvbiAtIFRoZSBUYWJsZUFjdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgQWN0aW9uIGNhbiBiZSB1c2VkLlxuICAgICAqL1xuICAgIGhhc01hbnlUYWJsZUFjdGlvbkRpc2FibGVkKGFjdGlvbjogVGFibGVBY3Rpb25JbnRlcm5hbDxFbnRpdHlUeXBlPik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcnVuSW5JbmplY3Rpb25Db250ZXh0KHRoaXMuaW5qZWN0b3IsICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhYWN0aW9uLmVuYWJsZWQodGhpcy5oYXNNYW55VGFibGVDb250ZXh0LiRpbXBsaWNpdC5zZWxlY3Rpb24uc2VsZWN0ZWQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIHRoZSBzZWFyY2ggaW5wdXQgdG8gZmlsdGVyIHRoZSB0YWJsZSBlbnRyaWVzLlxuICAgICAqIEBwYXJhbSBldmVudCAtIFRoZSBrZXl1cC1ldmVudCB3aGljaCBjb250YWlucyB0aGUgc2VhcmNoLXN0cmluZyBvZiB0aGUgdXNlci5cbiAgICAgKi9cbiAgICBhcHBseUhhc01hbnlGaWx0ZXIoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGZpbHRlclZhbHVlOiBzdHJpbmcgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlO1xuICAgICAgICB0aGlzLmhhc01hbnlUYWJsZUNvbnRleHQuJGltcGxpY2l0LmRhdGFTb3VyY2UuZmlsdGVyID0gZmlsdGVyVmFsdWUudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBlbnRpdHkgaXMgdmFsaWQgZm9yIHVwZGF0aW5nIGFuZCBpZiBpdCBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBhc3luYyBjaGVja0hhc01hbnlFbnRpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZCgndXBkYXRlJyk7XG4gICAgICAgIHRoaXMuaGFzTWFueUNoYW5nZXMgPSBhd2FpdCBFbnRpdHlVdGlsaXRpZXMuZ2V0RGlmZmVyZW5jZXNCZXR3ZWVuRW50aXRpZXMoXG4gICAgICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHksXG4gICAgICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMsXG4gICAgICAgICAgICB0aGlzLmh0dHAsXG4gICAgICAgICAgICB0aGlzLmluamVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGlmICghdGhpcy5oYXNNYW55VmFsaWRhdGlvbkVycm9ycy5sZW5ndGggJiYgdGhpcy5oYXNNYW55Q2hhbmdlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueVRvb2x0aXBDb250ZW50ID0gcnVuSW5JbmplY3Rpb25Db250ZXh0KFxuICAgICAgICAgICAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICAgICAgICAgICAgKCkgPT4gZ2V0Q2hhbmdlc1Rvb2x0aXBDb250ZW50KHRoaXMuaGFzTWFueUNoYW5nZXMpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXNIYXNNYW55RW50aXR5RGlydHkgPSAhIXRoaXMuaGFzTWFueUNoYW5nZXMubGVuZ3RoO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgZW50aXR5IGlzIHZhbGlkLlxuICAgICAqIEBwYXJhbSBvbWl0IC0gV2hldGhlciB2YWx1ZXMgb21pdHRlZCBmb3IgY3JlYXRlIG9yIHVwZGF0ZSBzaG91bGQgYmUgbGVmdCBvdXQuXG4gICAgICovXG4gICAgYXN5bmMgY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZChvbWl0OiAnY3JlYXRlJyB8ICd1cGRhdGUnKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuaGFzTWFueVZhbGlkYXRpb25FcnJvcnMgPSBhd2FpdCBWYWxpZGF0aW9uVXRpbGl0aWVzLmdldEVudGl0eVZhbGlkYXRpb25FcnJvcnModGhpcy5oYXNNYW55RW50aXR5LCB0aGlzLmluamVjdG9yLCBvbWl0KTtcbiAgICAgICAgaWYgKHRoaXMuaGFzTWFueVZhbGlkYXRpb25FcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlUb29sdGlwQ29udGVudCA9IHJ1bkluSW5qZWN0aW9uQ29udGV4dChcbiAgICAgICAgICAgICAgICB0aGlzLmluamVjdG9yLFxuICAgICAgICAgICAgICAgICgpID0+IGdldFZhbGlkYXRpb25FcnJvcnNUb29sdGlwQ29udGVudCh0aGlzLmhhc01hbnlWYWxpZGF0aW9uRXJyb3JzKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzSGFzTWFueUVudGl0eVZhbGlkID0gdGhpcy5oYXNNYW55VmFsaWRhdGlvbkVycm9ycy5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGFycmF5IGl0ZW0gaXMgdmFsaWQgYW5kIGlmIHRoZSBhcnJheSBpdGVtIGlzIGRpcnR5LlxuICAgICAqL1xuICAgIGFzeW5jIGNoZWNrQXJyYXlJdGVtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrSXNBcnJheUl0ZW1WYWxpZCgpO1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrSXNBcnJheUl0ZW1EaXJ0eSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgYXJyYXkgaXRlbSBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBhc3luYyBjaGVja0lzQXJyYXlJdGVtRGlydHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuYXJyYXlJdGVtQ2hhbmdlcyA9IGF3YWl0IEVudGl0eVV0aWxpdGllcy5nZXREaWZmZXJlbmNlc0JldHdlZW5FbnRpdGllcyhcbiAgICAgICAgICAgIHRoaXMuYXJyYXlJdGVtLFxuICAgICAgICAgICAgdGhpcy5hcnJheUl0ZW1QcmlvckNoYW5nZXMsXG4gICAgICAgICAgICB0aGlzLmh0dHAsXG4gICAgICAgICAgICB0aGlzLmluamVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGlmICghdGhpcy5hcnJheUl0ZW1WYWxpZGF0aW9uRXJyb3JzLmxlbmd0aCAmJiB0aGlzLmFycmF5SXRlbUNoYW5nZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmFycmF5SXRlbVRvb2x0aXBDb250ZW50ID0gcnVuSW5JbmplY3Rpb25Db250ZXh0KFxuICAgICAgICAgICAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICAgICAgICAgICAgKCkgPT4gZ2V0Q2hhbmdlc1Rvb2x0aXBDb250ZW50KHRoaXMuYXJyYXlJdGVtQ2hhbmdlcylcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pc0FycmF5SXRlbURpcnR5ID0gISF0aGlzLmFycmF5SXRlbUNoYW5nZXMubGVuZ3RoO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgYXJyYXlJdGVtIGlzIHZhbGlkLlxuICAgICAqL1xuICAgIGFzeW5jIGNoZWNrSXNBcnJheUl0ZW1WYWxpZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW1WYWxpZGF0aW9uRXJyb3JzID0gYXdhaXQgVmFsaWRhdGlvblV0aWxpdGllcy5nZXRFbnRpdHlWYWxpZGF0aW9uRXJyb3JzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCAnY3JlYXRlJyk7XG4gICAgICAgIGlmICh0aGlzLmFycmF5SXRlbVZhbGlkYXRpb25FcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmFycmF5SXRlbVRvb2x0aXBDb250ZW50ID0gcnVuSW5JbmplY3Rpb25Db250ZXh0KFxuICAgICAgICAgICAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICAgICAgICAgICAgKCkgPT4gZ2V0VmFsaWRhdGlvbkVycm9yc1Rvb2x0aXBDb250ZW50KHRoaXMuYXJyYXlJdGVtVmFsaWRhdGlvbkVycm9ycylcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pc0FycmF5SXRlbVZhbGlkID0gdGhpcy5hcnJheUl0ZW1WYWxpZGF0aW9uRXJyb3JzLmxlbmd0aCA9PT0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyB0aGF0IGEgdGhlIHZhbHVlIGhhcyBiZWVuIGNoYW5nZWQuXG4gICAgICovXG4gICAgZW1pdENoYW5nZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pbnB1dENoYW5nZUV2ZW50LmVtaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmllcyB0byBhZGQgYW4gaXRlbSB0byB0aGUgZW50aXR5IGFycmF5LlxuICAgICAqIERvZXMgdGhpcyBlaXRoZXIgaW5saW5lIGlmIHRoZSBcImNyZWF0ZUlubGluZVwiLW1ldGFkYXRhIGlzIHNldCB0byB0cnVlXG4gICAgICogb3IgaW4gYSBzZXBhcmF0ZSBkaWFsb2cgaWYgaXQgaXMgc2V0IHRvIGZhbHNlLlxuICAgICAqL1xuICAgIGFzeW5jIGFkZEVudGl0eSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0lzQXJyYXlJdGVtVmFsaWQoKTtcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlSW5saW5lKSB7XG4gICAgICAgICAgICB0aGlzLmFycmF5SXRlbSA9IG5ldyB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuRW50aXR5Q2xhc3MoKTtcbiAgICAgICAgICAgIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzID0gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSk7XG4gICAgICAgICAgICBFbnRpdHlVdGlsaXRpZXMuc2V0RGVmYXVsdFZhbHVlcyh0aGlzLmFycmF5SXRlbSk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQgPSB7XG4gICAgICAgICAgICAgICAgJGltcGxpY2l0OiB7XG4gICAgICAgICAgICAgICAgICAgIGVudGl0eTogdGhpcy5hcnJheUl0ZW0sXG4gICAgICAgICAgICAgICAgICAgIHRhYnM6IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCB0cnVlKSxcbiAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFuZ2VFdmVudDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCB0aGlzLmNoZWNrSXNBcnJheUl0ZW1WYWxpZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1Gb3JtQ29udGV4dC4kaW1wbGljaXQudGFicyA9IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaGlkZU9taXRGb3JDcmVhdGU6IHRydWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1Gb3JtQ29udGV4dDIgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMuYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1EaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKFxuICAgICAgICAgICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRGlhbG9nLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbWluV2lkdGg6ICc2MCUnLFxuICAgICAgICAgICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5hbGxvd0R1cGxpY2F0ZXMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLmVudGl0eUFycmF5VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLmRhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXdhaXQgRW50aXR5VXRpbGl0aWVzLmlzRXF1YWwodGhpcy5hcnJheUl0ZW0sIHYsIHRoaXMubWV0YWRhdGEsIHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5pdGVtVHlwZSwgdGhpcy5odHRwKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5kdXBsaWNhdGVzRXJyb3JEaWFsb2csXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgICh0aGlzLmVudGl0eVt0aGlzLnByb3BlcnR5S2V5XSBhcyBFbnRpdHlUeXBlW10pLnB1c2goTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSkpO1xuICAgICAgICB0aGlzLmVudGl0eUFycmF5VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLmRhdGEgPSAodGhpcy5lbnRpdHlbdGhpcy5wcm9wZXJ0eUtleV0gYXMgRW50aXR5VHlwZVtdKTtcblxuICAgICAgICB0aGlzLmFkZEFycmF5SXRlbUZvcm1Db250ZXh0ID0gdW5kZWZpbmVkIGFzIHVua25vd24gYXMgVGVtcGxhdGVDb250ZXh0PEZvcm1Db250ZXh0PEVudGl0eVR5cGU+PjtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW0gPSBuZXcgdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LkVudGl0eUNsYXNzKCk7XG4gICAgICAgIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzID0gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSk7XG4gICAgICAgIEVudGl0eVV0aWxpdGllcy5zZXREZWZhdWx0VmFsdWVzKHRoaXMuYXJyYXlJdGVtKTtcblxuICAgICAgICBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHR5cGVzY3JpcHQvbm8tbWlzdXNlZC1wcm9taXNlc1xuICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQgPSB7XG4gICAgICAgICAgICAgICAgICAgICRpbXBsaWNpdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5OiB0aGlzLmFycmF5SXRlbSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhYnM6IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCB0cnVlKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbmdlRXZlbnQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHRoaXMuY2hlY2tJc0FycmF5SXRlbVZhbGlkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHN0eWxpc3RpYy9tYXgtbGVuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1Gb3JtQ29udGV4dC4kaW1wbGljaXQudGFicyA9IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRlT21pdEZvckNyZWF0ZTogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY2hlY2tJc0FycmF5SXRlbVZhbGlkKCk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAxXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyB0aGUgYXJyYXkgaXRlbSBkZWZpbmVkIGluIHRoZSBkaWFsb2cuXG4gICAgICovXG4gICAgYXN5bmMgYWRkQXJyYXlJdGVtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMuaXNBcnJheUl0ZW1WYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgICh0aGlzLmVudGl0eVt0aGlzLnByb3BlcnR5S2V5XSBhcyBFbnRpdHlUeXBlW10pLnB1c2goTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSkpO1xuICAgICAgICB0aGlzLmVudGl0eUFycmF5VGFibGVDb250ZXh0LiRpbXBsaWNpdC5kYXRhU291cmNlLmRhdGEgPSAodGhpcy5lbnRpdHlbdGhpcy5wcm9wZXJ0eUtleV0gYXMgRW50aXR5VHlwZVtdKTtcblxuICAgICAgICBhd2FpdCB0aGlzLmNsb3NlQWRkQXJyYXlJdGVtRGlhbG9nKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FuY2VscyBhZGRpbmcgdGhlIGFycmF5IGl0ZW0gZGVmaW5lZCBpbiB0aGUgZGlhbG9nLlxuICAgICAqL1xuICAgIGFzeW5jIGNsb3NlQWRkQXJyYXlJdGVtRGlhbG9nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmFkZEFycmF5SXRlbURpYWxvZ1JlZi5jbG9zZSgpO1xuICAgICAgICBFbnRpdHlVdGlsaXRpZXMucmVzZXRDaGFuZ2VzT25FbnRpdHkodGhpcy5hcnJheUl0ZW0sIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0lzQXJyYXlJdGVtVmFsaWQoKTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRWRpdHMgYW4gZW50aXR5IGFycmF5IGl0ZW0uXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgdGhhdCBoYXMgYmVlbiBjbGlja2VkLlxuICAgICAqIEBwYXJhbSBkQ29sIC0gVGhlIGRpc3BsYXkgY29sdW1uIHRoYXQgd2FzIGNsaWNrZWQgb24uXG4gICAgICovXG4gICAgYXN5bmMgZWRpdEFycmF5SXRlbShlbnRpdHk6IEVudGl0eVR5cGUsIGRDb2w6IERpc3BsYXlDb2x1bW48RW50aXR5VHlwZT4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKGRDb2wuZGlzYWJsZUNsaWNrID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmRleE9mRWRpdGVkQXJyYXlJdGVtID0gdGhpcy5lbnRpdHlBcnJheVRhYmxlQ29udGV4dC4kaW1wbGljaXQuZGF0YVNvdXJjZS5kYXRhLmluZGV4T2YoZW50aXR5KTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW0gPSBuZXcgdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LkVudGl0eUNsYXNzKGVudGl0eSk7XG4gICAgICAgIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzID0gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSk7XG5cbiAgICAgICAgdGhpcy5lZGl0QXJyYXlJdGVtRm9ybUNvbnRleHQgPSB7XG4gICAgICAgICAgICAkaW1wbGljaXQ6IHtcbiAgICAgICAgICAgICAgICBlbnRpdHk6IHRoaXMuYXJyYXlJdGVtLFxuICAgICAgICAgICAgICAgIHRhYnM6IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuYXJyYXlJdGVtLCB0aGlzLmluamVjdG9yLCB0cnVlKSxcbiAgICAgICAgICAgICAgICBpc1JlYWRPbmx5OiAocHJvcGVydHksIGtleSkgPT4gdGhpcy5pc1Byb3BlcnR5UmVhZE9ubHkocHJvcGVydHksIGtleSksXG4gICAgICAgICAgICAgICAgaW5wdXRDaGFuZ2VFdmVudDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB2b2lkIHRoaXMuY2hlY2tBcnJheUl0ZW0oKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0QXJyYXlJdGVtRm9ybUNvbnRleHQuJGltcGxpY2l0LnRhYnMgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0RW50aXR5VGFicyh0aGlzLmFycmF5SXRlbSwgdGhpcy5pbmplY3RvciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBoaWRlT21pdEZvckVkaXQ6IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrQXJyYXlJdGVtKCk7XG5cbiAgICAgICAgdGhpcy5lZGl0QXJyYXlJdGVtRGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuZWRpdEFycmF5SXRlbURpYWxvZyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogJzYwJScsXG4gICAgICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2F2ZXMgY2hhbmdlcyBvbiB0aGUgYXJyYXkgaXRlbSBpbiB0aGUgZGlhbG9nLlxuICAgICAqL1xuICAgIHNhdmVBcnJheUl0ZW0oKTogdm9pZCB7XG4gICAgICAgICh0aGlzLmVudGl0eVt0aGlzLnByb3BlcnR5S2V5XSBhcyBFbnRpdHlUeXBlW10pW3RoaXMuaW5kZXhPZkVkaXRlZEFycmF5SXRlbV0gPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMuYXJyYXlJdGVtKTtcbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheVRhYmxlQ29udGV4dC4kaW1wbGljaXQuZGF0YVNvdXJjZS5kYXRhID0gKHRoaXMuZW50aXR5W3RoaXMucHJvcGVydHlLZXldIGFzIEVudGl0eVR5cGVbXSk7XG5cbiAgICAgICAgdm9pZCB0aGlzLmNsb3NlRWRpdEFycmF5SXRlbURpYWxvZygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgZWRpdCBhcnJheSBpdGVtIGRpYWxvZyBhbmQgcmVzZXRzIGNoYW5nZXMuXG4gICAgICovXG4gICAgYXN5bmMgY2xvc2VFZGl0QXJyYXlJdGVtRGlhbG9nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmVkaXRBcnJheUl0ZW1EaWFsb2dSZWYuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW0gPSBuZXcgdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LkVudGl0eUNsYXNzKCk7XG4gICAgICAgIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzID0gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSk7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tBcnJheUl0ZW0oKTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgc2VsZWN0ZWQgZW50cmllcyBmcm9tIHRoZSBlbnRpdHkgYXJyYXkuXG4gICAgICovXG4gICAgcmVtb3ZlRnJvbUVudGl0eUFycmF5KCk6IHZvaWQge1xuICAgICAgICBTZWxlY3Rpb25VdGlsaXRpZXMucmVtb3ZlKFxuICAgICAgICAgICAgdGhpcy5lbnRpdHlBcnJheVRhYmxlQ29udGV4dC4kaW1wbGljaXQuc2VsZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5lbnRpdHlbdGhpcy5wcm9wZXJ0eUtleV0gYXMgRW50aXR5VHlwZVtdLFxuICAgICAgICAgICAgdGhpcy5lbnRpdHlBcnJheVRhYmxlQ29udGV4dC4kaW1wbGljaXQuZGF0YVNvdXJjZVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICB9XG59IiwiPCEtLSBlc2xpbnQtZGlzYWJsZSBhbmd1bGFyL25vLWNhbGwtZXhwcmVzc2lvbiAtLT5cbkBpZighKGhpZGVPbWl0Rm9yQ3JlYXRlICYmIG1ldGFkYXRhLm9taXRGb3JDcmVhdGUpICYmICEoaGlkZU9taXRGb3JFZGl0ICYmIG1ldGFkYXRhLm9taXRGb3JVcGRhdGUpKSB7XG4gICAgQHN3aXRjaCAodHlwZSkge1xuICAgICAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgICAgICA8IS0tLS0tLS0tLS0tLS0tLS0tU3RyaW5ncy0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgICAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuU1RSSU5HKSB7XG4gICAgICAgICAgICA8c3RyaW5nLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9zdHJpbmctaW5wdXQ+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLlNUUklOR19URVhUQk9YKSB7XG4gICAgICAgICAgICA8c3RyaW5nLXRleHRib3gtaW5wdXRcbiAgICAgICAgICAgICAgICBbZW50aXR5XT1cImVudGl0eVwiXG4gICAgICAgICAgICAgICAgW2tleV09XCJwcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8L3N0cmluZy10ZXh0Ym94LWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5TVFJJTkdfQVVUT0NPTVBMRVRFKSB7XG4gICAgICAgICAgICA8c3RyaW5nLWF1dG9jb21wbGV0ZS1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvc3RyaW5nLWF1dG9jb21wbGV0ZS1pbnB1dD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuU1RSSU5HX0RST1BET1dOKSB7XG4gICAgICAgICAgICA8c3RyaW5nLWRyb3Bkb3duLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9zdHJpbmctZHJvcGRvd24taW5wdXQ+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLlNUUklOR19QQVNTV09SRCkge1xuICAgICAgICAgICAgPHN0cmluZy1wYXNzd29yZC1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvc3RyaW5nLXBhc3N3b3JkLWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS1Cb29sZWFucy0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5CT09MRUFOX0NIRUNLQk9YKSB7XG4gICAgICAgICAgICA8Ym9vbGVhbi1jaGVja2JveC1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvYm9vbGVhbi1jaGVja2JveC1pbnB1dD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuQk9PTEVBTl9UT0dHTEUpIHtcbiAgICAgICAgICAgIDxib29sZWFuLXRvZ2dsZS1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvYm9vbGVhbi10b2dnbGUtaW5wdXQ+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLkJPT0xFQU5fRFJPUERPV04pIHtcbiAgICAgICAgICAgIDxib29sZWFuLWRyb3Bkb3duLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9ib29sZWFuLWRyb3Bkb3duLWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tTnVtYmVycy0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5OVU1CRVIpIHtcbiAgICAgICAgICAgIDxudW1iZXItaW5wdXRcbiAgICAgICAgICAgICAgICBbZW50aXR5XT1cImVudGl0eVwiXG4gICAgICAgICAgICAgICAgW2tleV09XCJwcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8L251bWJlci1pbnB1dD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuTlVNQkVSX0RST1BET1dOKSB7XG4gICAgICAgICAgICA8bnVtYmVyLWRyb3Bkb3duLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9udW1iZXItZHJvcGRvd24taW5wdXQ+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLk5VTUJFUl9TTElERVIpIHtcbiAgICAgICAgICAgIDxudW1iZXItc2xpZGVyLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9udW1iZXItc2xpZGVyLWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLUFycmF5LS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5BUlJBWV9EQVRFKSB7XG4gICAgICAgICAgICA8YXJyYXktZGF0ZS1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvYXJyYXktZGF0ZS1pbnB1dD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuQVJSQVlfREFURV9USU1FKSB7XG4gICAgICAgICAgICA8YXJyYXktZGF0ZS10aW1lLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9hcnJheS1kYXRlLXRpbWUtaW5wdXQ+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLkFSUkFZX0RBVEVfUkFOR0UpIHtcbiAgICAgICAgICAgIDxhcnJheS1kYXRlLXJhbmdlLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9hcnJheS1kYXRlLXJhbmdlLWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5BUlJBWV9TVFJJTkdfQ0hJUFMpIHtcbiAgICAgICAgICAgIDxhcnJheS1zdHJpbmctY2hpcHMtaW5wdXRcbiAgICAgICAgICAgICAgICBbZW50aXR5XT1cImVudGl0eVwiXG4gICAgICAgICAgICAgICAgW2tleV09XCJwcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8L2FycmF5LXN0cmluZy1jaGlwcy1pbnB1dD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuQVJSQVlfU1RSSU5HX0FVVE9DT01QTEVURV9DSElQUykge1xuICAgICAgICAgICAgPGFycmF5LXN0cmluZy1hdXRvY29tcGxldGUtY2hpcHNcbiAgICAgICAgICAgICAgICBbZW50aXR5XT1cImVudGl0eVwiXG4gICAgICAgICAgICAgICAgW2tleV09XCJwcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8L2FycmF5LXN0cmluZy1hdXRvY29tcGxldGUtY2hpcHM+XG4gICAgICAgIH1cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tRGF0ZXMtLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLkRBVEUpIHtcbiAgICAgICAgICAgIDxkYXRlLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9kYXRlLWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5EQVRFX1JBTkdFKSB7XG4gICAgICAgICAgICA8ZGF0ZS1yYW5nZS1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvZGF0ZS1yYW5nZS1pbnB1dD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuREFURV9USU1FKSB7XG4gICAgICAgICAgICA8ZGF0ZS10aW1lLWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9kYXRlLXRpbWUtaW5wdXQ+XG4gICAgICAgIH1cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tRmlsZXMtLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLkZJTEVfREVGQVVMVCkge1xuICAgICAgICAgICAgPGZpbGUtZGVmYXVsdC1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvZmlsZS1kZWZhdWx0LWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5GSUxFX0lNQUdFKSB7XG4gICAgICAgICAgICA8ZmlsZS1pbWFnZS1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvZmlsZS1pbWFnZS1pbnB1dD5cbiAgICAgICAgfVxuICAgICAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgICAgICA8IS0tLS0tLS0tLS0tLS0tIHJlZmVyZW5jZXMgbWFueSAtLS0tLS0tLS0tLS0tPlxuICAgICAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgICAgICBAY2FzZSAoRGVjb3JhdG9yVHlwZXMuUkVGRVJFTkNFU19NQU5ZKSB7XG4gICAgICAgICAgICA8cmVmZXJlbmNlcy1tYW55LWlucHV0XG4gICAgICAgICAgICAgICAgW2VudGl0eV09XCJlbnRpdHlcIlxuICAgICAgICAgICAgICAgIFtrZXldPVwicHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9yZWZlcmVuY2VzLW1hbnktaW5wdXQ+XG4gICAgICAgIH1cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tQ3VzdG9tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLkNVU1RPTSkge1xuICAgICAgICAgICAgPGN1c3RvbS1pbnB1dFxuICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiZW50aXR5XCJcbiAgICAgICAgICAgICAgICBba2V5XT1cInByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvY3VzdG9tLWlucHV0PlxuICAgICAgICB9XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLU9iamVjdC0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgIEBjYXNlIChEZWNvcmF0b3JUeXBlcy5PQkpFQ1QpIHtcbiAgICAgICAgICAgIDxiPnt7bWV0YWRhdGFEZWZhdWx0T2JqZWN0LmRpc3BsYXlOYW1lfX08L2I+XG4gICAgICAgICAgICA8IS0tIGl0ZXJhdGVzIG92ZXIgdGhlIG9iamVjdCBwcm9wZXJ0aWVzIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvcm07IGNvbnRleHQ6IG9iamVjdEZvcm1Db250ZXh0XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIH1cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS1PYmplY3QgRHJvcGRvd24tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLk9CSkVDVF9EUk9QRE9XTikge1xuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwidy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e21ldGFkYXRhLmRpc3BsYXlOYW1lfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCAjbW9kZWw9XCJuZ01vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwib2JqZWN0RHJvcGRvd25OYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cIm1ldGFkYXRhLnJlcXVpcmVkKGVudGl0eSlcIlxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAgICAgW2NvbXBhcmVXaXRoXT1cImNvbXBhcmVPYmplY3RzQm91bmRcIlxuICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImVudGl0eVtwcm9wZXJ0eUtleV1cIlxuICAgICAgICAgICAgICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICAgICAgICAgIChvcGVuZWQpPVwic2VsZWN0U2VhcmNoSW5wdXQuZm9jdXMoKVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJzZWxlY3Qtc2VhcmNoLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBhbmd1bGFyL25vLWFueSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAjc2VsZWN0U2VhcmNoSW5wdXQgbWF0SW5wdXQgKGtleXVwKT1cImZpbHRlck9iamVjdERyb3Bkb3duVmFsdWVzKCRhbnkoJGV2ZW50LnRhcmdldCkudmFsdWUpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZmEtaWNvbiBtYXRTdWZmaXggW2ljb25dPVwiZmFTZWFyY2hcIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoIW1ldGFkYXRhLnJlcXVpcmVkKGVudGl0eSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uPi08L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChzaG91bGREaXNwbGF5Q3VycmVudE9iamVjdERyb3Bkb3duVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJjdXJyZW50T2JqZWN0RHJvcGRvd25WYWx1ZT8udmFsdWVcIj57e2N1cnJlbnRPYmplY3REcm9wZG93blZhbHVlPy5kaXNwbGF5TmFtZX19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKHZhbHVlIG9mIGZpbHRlcmVkT2JqZWN0RHJvcGRvd25WYWx1ZXM7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cInZhbHVlLnZhbHVlXCI+e3t2YWx1ZS5kaXNwbGF5TmFtZX19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3I+e3tpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2UobW9kZWwpfX08L21hdC1lcnJvcj5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIH1cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLSByZWZlcmVuY2VzIG9uZSAtLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLlJFRkVSRU5DRVNfT05FKSB7XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgW2NsYXNzLnctZnVsbF09XCJtZXRhZGF0YVJlZmVyZW5jZXNPbmUuZHJvcGRvd25Pbmx5XCI+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e21ldGFkYXRhLmRpc3BsYXlOYW1lfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCAjaW5wdXRNb2RlbD1cIm5nTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICBbbmFtZV09XCJyZWZlcmVuY2VzT25lTmFtZVwiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwibWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZW50aXR5W3Byb3BlcnR5S2V5XVwiXG4gICAgICAgICAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwic2V0UmVmZXJlbmNlc09uZU9iamVjdCgpXCJcbiAgICAgICAgICAgICAgICAgICAgKG9wZW5lZCk9XCJzZWxlY3RTZWFyY2hJbnB1dC5mb2N1cygpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cInNlbGVjdC1zZWFyY2gtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGFuZ3VsYXIvbm8tYW55IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0ICNzZWxlY3RTZWFyY2hJbnB1dCBtYXRJbnB1dCAoa2V5dXApPVwiZmlsdGVyUmVmZXJlbmNlc09uZVZhbHVlcygkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGZhLWljb24gbWF0U3VmZml4IFtpY29uXT1cImZhU2VhcmNoXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKCFtZXRhZGF0YS5yZXF1aXJlZChlbnRpdHkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbj4tPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoc2hvdWxkRGlzcGxheUN1cnJlbnRSZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cImN1cnJlbnRSZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZT8udmFsdWVcIj57e2N1cnJlbnRSZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZT8uZGlzcGxheU5hbWV9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAZm9yICh2YWx1ZSBvZiBmaWx0ZXJlZFJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlczsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwidmFsdWUudmFsdWVcIj57e3ZhbHVlLmRpc3BsYXlOYW1lfX08L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvcj57e2ludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZShpbnB1dE1vZGVsKX19PC9tYXQtZXJyb3I+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPCEtLSBpdGVyYXRlcyBvdmVyIHRoZSByZWZlcmVuY2VzIG9uZSBwcm9wZXJ0aWVzIC0tPlxuICAgICAgICAgICAgQGlmIChyZWZlcmVuY2VzT25lRm9ybUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9ybTsgY29udGV4dDogcmVmZXJlbmNlc09uZUZvcm1Db250ZXh0XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tQXJyYXktLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLkFSUkFZKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW50aXR5QXJyYXlcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF0LWVsZXZhdGlvbi16OCBlbGV2YXRpb24tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhcnJheS1oZWFkbGluZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGI+e3ttZXRhZGF0YUVudGl0eUFycmF5LmRpc3BsYXlOYW1lfX08L2I+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICBAaWYgKG1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlSW5saW5lICYmICFpbnRlcm5hbElzUmVhZE9ubHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9ybTsgY29udGV4dDogYWRkQXJyYXlJdGVtRm9ybUNvbnRleHRcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBlbHNlIGlmIChhZGRBcnJheUl0ZW1Gb3JtQ29udGV4dDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9ybTsgY29udGV4dDogYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQyXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmICghaW50ZXJuYWxJc1JlYWRPbmx5ICYmIGVudGl0eUFycmF5VGFibGVDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJtZXRhZGF0YUVudGl0eUFycmF5LmNyZWF0ZUlubGluZSAmJiAhaXNBcnJheUl0ZW1WYWxpZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRFbnRpdHkoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhRW50aXR5QXJyYXkuYWRkQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhZW50aXR5QXJyYXlUYWJsZUNvbnRleHQuJGltcGxpY2l0LnNlbGVjdGlvbi5zZWxlY3RlZC5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlRnJvbUVudGl0eUFycmF5KClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ttZXRhZGF0YUVudGl0eUFycmF5LnJlbW92ZUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoZW50aXR5QXJyYXlUYWJsZUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0YWJsZTsgY29udGV4dDogZW50aXR5QXJyYXlUYWJsZUNvbnRleHRcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0gaGFzIG1hbnkgLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgQGNhc2UgKERlY29yYXRvclR5cGVzLkhBU19NQU5ZKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGFzTWFueVwiPlxuICAgICAgICAgICAgICAgIDxoMiBjbGFzcz1cInRpdGxlXCI+e3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRpdGxlfX08L2gyPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkIGdyaWQtY29scy0xMiBnYXAteC02XCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImxnOmNvbC1zcGFuLTggbWQ6Y29sLXNwYW4tNiBjb2wtc3Bhbi0xMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuc2VhcmNoTGFiZWx9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IChrZXl1cCk9XCJhcHBseUhhc01hbnlGaWx0ZXIoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKG1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5sZzpjb2wtc3Bhbi0yXT1cImhhc01hbnlBbGxvd0NyZWF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmxnOmNvbC1zcGFuLTRdPVwiIWhhc01hbnlBbGxvd0NyZWF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLm1kOmNvbC1zcGFuLTNdPVwiaGFzTWFueUFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MubWQ6Y29sLXNwYW4tNl09XCIhaGFzTWFueUFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNwYW4tNl09XCJoYXNNYW55QWxsb3dDcmVhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtc3Bhbi0xMl09XCIhaGFzTWFueUFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImFjdGlvbnMtYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cIm1lbnVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9uc0xhYmVsfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtbWVudSAjbWVudT1cIm1hdE1lbnVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAobWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd0pzb25JbXBvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtbWVudS1pdGVtIFtkaXNhYmxlZF09XCJoYXNNYW55VGFibGVBY3Rpb25EaXNhYmxlZChoYXNNYW55SW1wb3J0QWN0aW9uKVwiIChjbGljayk9XCJydW5IYXNNYW55VGFibGVBY3Rpb24oaGFzTWFueUltcG9ydEFjdGlvbilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3toYXNNYW55SW1wb3J0QWN0aW9uLmRpc3BsYXlOYW1lfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9uczsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LW1lbnUtaXRlbSBbZGlzYWJsZWRdPVwiaGFzTWFueVRhYmxlQWN0aW9uRGlzYWJsZWQoYWN0aW9uKVwiIChjbGljayk9XCJydW5IYXNNYW55VGFibGVBY3Rpb24oYWN0aW9uKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2FjdGlvbi5kaXNwbGF5TmFtZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LW1lbnU+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoaGFzTWFueUFsbG93Q3JlYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmxnOmNvbC1zcGFuLTJdPVwibWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MubGc6Y29sLXNwYW4tNF09XCIhbWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MubWQ6Y29sLXNwYW4tM109XCJtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5tZDpjb2wtc3Bhbi02XT1cIiFtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtc3Bhbi02XT1cIm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1zcGFuLTEyXT1cIiFtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiY3JlYXRlLWJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIChjbGljayk9XCJjcmVhdGVIYXNNYW55RW50aXR5KClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmNyZWF0ZUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYXQtZWxldmF0aW9uLXo4IGVsZXZhdGlvbi1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChoYXNNYW55VGFibGVDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGFibGU7IGNvbnRleHQ6IGhhc01hbnlUYWJsZUNvbnRleHRcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIEBkZWZhdWx0IHtcbiAgICAgICAgICAgIDxkaXY+RVJST1I6IFRoZSB0eXBlIHt7dHlwZX19IGlzIG5vdCBrbm93bi48L2Rpdj5cbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG48bmctdGVtcGxhdGUgI3RhYmxlIGxldC1jb250ZXh0PlxuICAgIDxtYXQtdGFibGUgbWF0U29ydCBbZGF0YVNvdXJjZV09XCJjb250ZXh0LmRhdGFTb3VyY2VcIiBbY2xhc3MudGFibGUtd2l0aC1lcnJvci1zbG90XT1cImNvbnRleHQuc2hvdWxkU2hvd01pc3NpbmdFcnJvclwiPlxuICAgICAgICA8IS0tIHNlbGVjdCBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic2VsZWN0XCI+XG4gICAgICAgICAgICA8bWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlxuICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggW2NoZWNrZWRdPVwiY29udGV4dC5zZWxlY3Rpb24uaGFzVmFsdWUoKSAmJiBTZWxlY3Rpb25VdGlsaXRpZXMuaXNBbGxTZWxlY3RlZChjb250ZXh0LnNlbGVjdGlvbiwgY29udGV4dC5kYXRhU291cmNlKVwiXG4gICAgICAgICAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cImNvbnRleHQuc2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgIVNlbGVjdGlvblV0aWxpdGllcy5pc0FsbFNlbGVjdGVkKGNvbnRleHQuc2VsZWN0aW9uLCBjb250ZXh0LmRhdGFTb3VyY2UpXCJcbiAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCIkZXZlbnQgPyBTZWxlY3Rpb25VdGlsaXRpZXMubWFzdGVyVG9nZ2xlKGNvbnRleHQuc2VsZWN0aW9uLCBjb250ZXh0LmRhdGFTb3VyY2UpIDogbnVsbFwiPlxuICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgPC9tYXQtaGVhZGVyLWNlbGw+XG4gICAgICAgICAgICA8bWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgdmFsdWVcIiBbZHluYW1pY1N0eWxlQ2xhc3Nlc109XCJjb250ZXh0LmR5bmFtaWNSb3dTdHlsZUNsYXNzZXNcIiBbdmFsdWVdPVwidmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IFtjaGVja2VkXT1cImNvbnRleHQuc2VsZWN0aW9uLmlzU2VsZWN0ZWQodmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiJGV2ZW50ID8gY29udGV4dC5zZWxlY3Rpb24udG9nZ2xlKHZhbHVlKSA6IG51bGxcIj5cbiAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgIDwvbWF0LWNlbGw+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIEBmb3IgKGRDb2wgb2YgY29udGV4dC5kaXNwbGF5Q29sdW1uczsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFttYXRDb2x1bW5EZWZdPVwiZENvbC5kaXNwbGF5TmFtZVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlxuICAgICAgICAgICAgICAgICAgICB7e2RDb2wuZGlzcGxheU5hbWV9fVxuICAgICAgICAgICAgICAgIDwvbWF0LWhlYWRlci1jZWxsPlxuICAgICAgICAgICAgICAgIDxtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCB2YWx1ZVwiIFtjbGFzcy5lbmFibGVkXT1cIiFkQ29sLmRpc2FibGVDbGljayAmJiBjb250ZXh0LmFsbG93Q2xpY2sodmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgW2R5bmFtaWNTdHlsZUNsYXNzZXNdPVwiY29udGV4dC5keW5hbWljUm93U3R5bGVDbGFzc2VzXCIgW3ZhbHVlXT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsaWNrQ2VsbCh2YWx1ZSwgZENvbCwgY29udGV4dClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChkQ29sLkNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpc3BsYXktY29sdW1uLXZhbHVlIFtlbnRpdHldPVwidmFsdWVcIiBbQ29tcG9uZW50Q2xhc3NdPVwiZENvbC5Db21wb25lbnRcIj48L2Rpc3BsYXktY29sdW1uLXZhbHVlPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0RGlzcGxheUNvbHVtblZhbHVlKHZhbHVlLCBkQ29sKX19XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L21hdC1jZWxsPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIH1cblxuICAgICAgICA8bWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImNvbnRleHQuZGlzcGxheWVkQ29sdW1uc1wiPjwvbWF0LWhlYWRlci1yb3c+XG4gICAgICAgIDxtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBjb250ZXh0LmRpc3BsYXllZENvbHVtbnNcIj48L21hdC1yb3c+XG4gICAgPC9tYXQtdGFibGU+XG5cbiAgICBAaWYgKGNvbnRleHQuZGlzcGxheUxvYWRpbmdTcGlubmVyICYmIGNvbnRleHQuaXNMb2FkaW5nKSB7XG4gICAgICAgIDxtYXQtc3Bpbm5lcj5cbiAgICAgICAgPC9tYXQtc3Bpbm5lcj5cbiAgICB9XG4gICAgQGVsc2UgaWYgKGNvbnRleHQuc2hvdWxkU2hvd01pc3NpbmdFcnJvciAmJiAhY29udGV4dC5kYXRhU291cmNlLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1lcnJvclwiPnt7Y29udGV4dC5lbXB0eUVycm9yTWVzc2FnZX19PC9kaXY+XG4gICAgfVxuXG4gICAgPG1hdC1wYWdpbmF0b3IgW2xlbmd0aF09XCJjb250ZXh0LmRhdGFTb3VyY2UuZmlsdGVyZWREYXRhLmxlbmd0aFwiIFtwYWdlSW5kZXhdPVwiMFwiIFtwYWdlU2l6ZV09XCIxMFwiIFtwYWdlU2l6ZU9wdGlvbnNdPVwiWzUsIDEwLCAyNSwgNTBdXCI+PC9tYXQtcGFnaW5hdG9yPlxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLUZvcm0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuPG5nLXRlbXBsYXRlICNmb3JtIGxldC1jb250ZXh0PlxuICAgIDwhLS0gZXNsaW50LWRpc2FibGUgYW5ndWxhci9uby1jYWxsLWV4cHJlc3Npb24gLS0+XG4gICAgQGlmIChjb250ZXh0LnRhYnMubGVuZ3RoID4gMSkge1xuICAgICAgICA8bWF0LXRhYi1ncm91cCBwcmVzZXJ2ZUNvbnRlbnQ+XG4gICAgICAgICAgICBAZm9yICh0YWIgb2YgY29udGV4dC50YWJzOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgICA8bWF0LXRhYiBbbGFiZWxdPVwidGFiLnRhYk5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAocm93IG9mIHRhYi5yb3dzOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkIGdyaWQtY29scy0xMiBnYXAteC02XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoa2V5IG9mIHJvdy5rZXlzOyB0cmFjayBrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cImNvbnRleHQuZW50aXR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWxpZEVtcHR5XT1cImNvbnRleHQudmFsaWRFbXB0eT8uKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiY29udGV4dC5pc1JlYWRPbmx5Py4oY29udGV4dC5lbnRpdHksIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cIkVudGl0eVV0aWxpdGllcy5nZXRXaWR0aENsYXNzZXMoY29udGV4dC5lbnRpdHksIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yRWRpdF09XCJjb250ZXh0LmhpZGVPbWl0Rm9yRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwiY29udGV4dC5oaWRlT21pdEZvckNyZWF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjb250ZXh0LmlucHV0Q2hhbmdlRXZlbnQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgIH1cbiAgICBAZWxzZSB7XG4gICAgICAgIEBpZiAoIWNvbnRleHQudGFicy5sZW5ndGgpIHtcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm8tZW50aXR5LXRhYnNcIj5cbiAgICAgICAgICAgICAgICBFUlJPUjogTm8gSW5wdXRzLiBEaWQgeW91IGNvcnJlY3RseSBhc3NpZ24gYWxsIHZhbHVlcyBpbiB0aGUgbW9kZWwgY29uc3RydWN0b3I/XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgQGZvciAocm93IG9mIGNvbnRleHQudGFic1swXS5yb3dzOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZCBncmlkLWNvbHMtMTIgZ2FwLXgtNlwiPlxuICAgICAgICAgICAgICAgICAgICBAZm9yIChrZXkgb2Ygcm93LmtleXM7IHRyYWNrIGtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJjb250ZXh0LmVudGl0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsaWRFbXB0eV09XCJjb250ZXh0LnZhbGlkRW1wdHk/LigpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJjb250ZXh0LmlzUmVhZE9ubHk/Lihjb250ZXh0LmVudGl0eSwga2V5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cIkVudGl0eVV0aWxpdGllcy5nZXRXaWR0aENsYXNzZXMoY29udGV4dC5lbnRpdHksIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckVkaXRdPVwiY29udGV4dC5oaWRlT21pdEZvckVkaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJjb250ZXh0LmhpZGVPbWl0Rm9yQ3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjb250ZXh0LmlucHV0Q2hhbmdlRXZlbnQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG48L25nLXRlbXBsYXRlPlxuXG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS1BZGQgQXJyYXkgSXRlbSBEaWFsb2ctLS0tLS0tLS0tLS0tLS0tPlxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48bmctdGVtcGxhdGUgI2FkZEFycmF5SXRlbURpYWxvZz5cbiAgICA8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiPlxuICAgICAgICA8ZGl2Pnt7YWRkQXJyYXlJdGVtRGlhbG9nRGF0YS50aXRsZX19PC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8Zm9ybSAobmdTdWJtaXQpPVwiYWRkQXJyYXlJdGVtKClcIj5cbiAgICAgICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgICAgIEBpZiAoYWRkQXJyYXlJdGVtRm9ybUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9ybTsgY29udGV4dDogYWRkQXJyYXlJdGVtRm9ybUNvbnRleHRcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgXG4gICAgICAgIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWJ1dHRvbi13aXRoLWluZm8taWNvblwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIG1hdC1yYWlzZWQtYnV0dG9uIG1hdEJhZGdlQ29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFpc0FycmF5SXRlbVZhbGlkXCJcbiAgICAgICAgICAgICAgICAgICAgW21hdEJhZGdlXT1cImFycmF5SXRlbVZhbGlkYXRpb25FcnJvcnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgW21hdEJhZGdlSGlkZGVuXT1cIiFhcnJheUl0ZW1WYWxpZGF0aW9uRXJyb3JzLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7e2FkZEFycmF5SXRlbURpYWxvZ0RhdGEuY3JlYXRlQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIEBpZiAoYXJyYXlJdGVtVmFsaWRhdGlvbkVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LXRvb2x0aXAgW3Rvb2x0aXBDb250ZW50XT1cImFycmF5SXRlbVRvb2x0aXBDb250ZW50XCI+PC9uZ3gtbWF0LWVudGl0eS10b29sdGlwPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gY2xhc3M9XCJjYW5jZWwtYnV0dG9uXCIgKGNsaWNrKT1cImNsb3NlQWRkQXJyYXlJdGVtRGlhbG9nKClcIj5cbiAgICAgICAgICAgICAgICB7e2FkZEFycmF5SXRlbURpYWxvZ0RhdGEuY2FuY2VsQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgIDwvZm9ybT5cblxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tRWRpdCBBcnJheSBJdGVtIERpYWxvZy0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbjxuZy10ZW1wbGF0ZSAjZWRpdEFycmF5SXRlbURpYWxvZz5cbiAgICA8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiPlxuICAgICAgICA8ZGl2Pnt7ZWRpdEFycmF5SXRlbURpYWxvZ0RhdGEudGl0bGUoYXJyYXlJdGVtUHJpb3JDaGFuZ2VzKX19PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgXG4gICAgPGZvcm0gKG5nU3VibWl0KT1cInNhdmVBcnJheUl0ZW0oKVwiPlxuICAgICAgICA8bWF0LWRpYWxvZy1jb250ZW50PlxuICAgICAgICAgICAgQGlmIChlZGl0QXJyYXlJdGVtRm9ybUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9ybTsgY29udGV4dDogZWRpdEFycmF5SXRlbUZvcm1Db250ZXh0XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICB9XG4gICAgICAgIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuICAgICAgICBcbiAgICAgICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctYnV0dG9uLXdpdGgtaW5mby1pY29uXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgbWF0LXJhaXNlZC1idXR0b24gbWF0QmFkZ2VDb2xvcj1cIndhcm5cIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuYmFkZ2UtY2hhbmdlc109XCIhYXJyYXlJdGVtVmFsaWRhdGlvbkVycm9ycy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaW50ZXJuYWxJc1JlYWRPbmx5IHx8ICFpc0FycmF5SXRlbVZhbGlkIHx8ICFpc0FycmF5SXRlbURpcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgW21hdEJhZGdlXT1cImFycmF5SXRlbVZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCA/IGFycmF5SXRlbVZhbGlkYXRpb25FcnJvcnMubGVuZ3RoIDogYXJyYXlJdGVtQ2hhbmdlcy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICBbbWF0QmFkZ2VIaWRkZW5dPVwiIWFycmF5SXRlbVZhbGlkYXRpb25FcnJvcnMubGVuZ3RoICYmICFhcnJheUl0ZW1DaGFuZ2VzLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7e2VkaXRBcnJheUl0ZW1EaWFsb2dEYXRhLmNvbmZpcm1CdXR0b25MYWJlbH19XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgQGlmIChhcnJheUl0ZW1WYWxpZGF0aW9uRXJyb3JzLmxlbmd0aCB8fCBhcnJheUl0ZW1DaGFuZ2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktdG9vbHRpcCBbdG9vbHRpcENvbnRlbnRdPVwiYXJyYXlJdGVtVG9vbHRpcENvbnRlbnRcIj48L25neC1tYXQtZW50aXR5LXRvb2x0aXA+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtcmFpc2VkLWJ1dHRvbiBjbGFzcz1cImNhbmNlbC1idXR0b25cIiAoY2xpY2spPVwiY2xvc2VFZGl0QXJyYXlJdGVtRGlhbG9nKClcIj5cbiAgICAgICAgICAgICAgICB7e2VkaXRBcnJheUl0ZW1EaWFsb2dEYXRhLmNhbmNlbEJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L2Zvcm0+XG48L25nLXRlbXBsYXRlPlxuXG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS1DcmVhdGUgSGFzIE1hbnkgRGlhbG9nLS0tLS0tLS0tLS0tLS0tLT5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuPG5nLXRlbXBsYXRlICNjcmVhdGVIYXNNYW55RGlhbG9nPlxuICAgIDxkaXYgY2xhc3M9XCJtYXQtZGlhbG9nLXRpdGxlXCI+XG4gICAgICAgIDxkaXY+e3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmNyZWF0ZURhdGEudGl0bGV9fTwvZGl2PlxuICAgIDwvZGl2PlxuICAgIFxuICAgIDxmb3JtIChuZ1N1Ym1pdCk9XCJkaWFsb2dDcmVhdGVIYXNNYW55KClcIj5cbiAgICAgICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgICAgIEBpZiAoaGFzTWFueUNyZWF0ZUZvcm1Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvcm07IGNvbnRleHQ6IGhhc01hbnlDcmVhdGVGb3JtQ29udGV4dFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgfVxuICAgICAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgXG4gICAgICAgIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWJ1dHRvbi13aXRoLWluZm8taWNvblwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIG1hdC1yYWlzZWQtYnV0dG9uIG1hdEJhZGdlQ29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFpc0hhc01hbnlFbnRpdHlWYWxpZFwiXG4gICAgICAgICAgICAgICAgICAgIFttYXRCYWRnZV09XCJoYXNNYW55VmFsaWRhdGlvbkVycm9ycy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICBbbWF0QmFkZ2VIaWRkZW5dPVwiIWhhc01hbnlWYWxpZGF0aW9uRXJyb3JzLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuY3JlYXRlRGF0YS5jcmVhdGVCdXR0b25MYWJlbH19XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgQGlmIChoYXNNYW55VmFsaWRhdGlvbkVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LXRvb2x0aXAgW3Rvb2x0aXBDb250ZW50XT1cImhhc01hbnlUb29sdGlwQ29udGVudFwiPjwvbmd4LW1hdC1lbnRpdHktdG9vbHRpcD5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIGNsYXNzPVwiY2FuY2VsLWJ1dHRvblwiIChjbGljayk9XCJkaWFsb2dDYW5jZWxDcmVhdGVIYXNNYW55KClcIj5cbiAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuY3JlYXRlRGF0YS5jYW5jZWxCdXR0b25MYWJlbH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9mb3JtPlxuICAgIFxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tRWRpdCBIYXMgTWFueSBEaWFsb2ctLS0tLS0tLS0tLS0tLS0tLT5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuPG5nLXRlbXBsYXRlICNlZGl0SGFzTWFueURpYWxvZz5cbiAgICA8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiPlxuICAgICAgICA8ZGl2Pnt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5lZGl0RGF0YS50aXRsZShoYXNNYW55RW50aXR5UHJpb3JDaGFuZ2VzKX19PC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICBAaWYgKG1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuYWN0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtcmFpc2VkLWJ1dHRvbiBbbWF0TWVudVRyaWdnZXJGb3JdPVwibWVudVwiPlxuICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuYWN0aW9uc0xhYmVsfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDxtYXQtbWVudSAjbWVudT1cIm1hdE1lbnVcIj5cbiAgICAgICAgICAgICAgICBAZm9yIChhY3Rpb24gb2YgbWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5lZGl0RGF0YS5hY3Rpb25zOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LW1lbnUtaXRlbSBbZGlzYWJsZWRdPVwiaGFzTWFueUVkaXRBY3Rpb25EaXNhYmxlZChhY3Rpb24pXCIgKGNsaWNrKT1cImhhc01hbnlSdW5FZGl0QWN0aW9uKGFjdGlvbilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7YWN0aW9uLmRpc3BsYXlOYW1lfX1cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9tYXQtbWVudT5cbiAgICAgICAgXG4gICAgICAgICAgICBAaWYgKGhhc01hbnlBbGxvd0RlbGV0ZShoYXNNYW55RW50aXR5KSkge1xuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIGNvbG9yPVwid2FyblwiIGNsYXNzPVwiZGVsZXRlLWJ1dHRvblwiIHRhYmluZGV4PVwiLTFcIiAoY2xpY2spPVwiZGVsZXRlSGFzTWFueUVudGl0eSgpXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5lZGl0RGF0YS5kZWxldGVCdXR0b25MYWJlbH19XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIFxuICAgIDxmb3JtIChuZ1N1Ym1pdCk9XCJkaWFsb2dFZGl0SGFzTWFueSgpXCI+XG4gICAgICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgICAgICBAaWYgKGhhc01hbnlFZGl0Rm9ybUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9ybTsgY29udGV4dDogaGFzTWFueUVkaXRGb3JtQ29udGV4dFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgfVxuICAgICAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgXG4gICAgICAgIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWJ1dHRvbi13aXRoLWluZm8taWNvblwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIG1hdC1yYWlzZWQtYnV0dG9uIG1hdEJhZGdlQ29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmJhZGdlLWNoYW5nZXNdPVwiIWhhc01hbnlWYWxpZGF0aW9uRXJyb3JzLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpbnRlcm5hbElzUmVhZE9ubHkgfHwgIWlzSGFzTWFueUVudGl0eVZhbGlkIHx8ICFpc0hhc01hbnlFbnRpdHlEaXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgIFttYXRCYWRnZV09XCJoYXNNYW55VmFsaWRhdGlvbkVycm9ycy5sZW5ndGggPiAwID8gaGFzTWFueVZhbGlkYXRpb25FcnJvcnMubGVuZ3RoIDogaGFzTWFueUNoYW5nZXMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgW21hdEJhZGdlSGlkZGVuXT1cIiFoYXNNYW55VmFsaWRhdGlvbkVycm9ycy5sZW5ndGggJiYgIWhhc01hbnlDaGFuZ2VzLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuY29uZmlybUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICBAaWYgKGhhc01hbnlWYWxpZGF0aW9uRXJyb3JzLmxlbmd0aCB8fCBoYXNNYW55Q2hhbmdlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LXRvb2x0aXAgW3Rvb2x0aXBDb250ZW50XT1cImhhc01hbnlUb29sdGlwQ29udGVudFwiPjwvbmd4LW1hdC1lbnRpdHktdG9vbHRpcD5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIGNsYXNzPVwiY2FuY2VsLWJ1dHRvblwiIChjbGljayk9XCJkaWFsb2dDYW5jZWxFZGl0SGFzTWFueSgpXCI+XG4gICAgICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmNhbmNlbEJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L2Zvcm0+XG48L25nLXRlbXBsYXRlPiJdfQ==