@messaia/cdk 18.2.3 → 19.0.0-rc02

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 (669) hide show
  1. package/fesm2022/messaia-cdk.mjs +1592 -1239
  2. package/fesm2022/messaia-cdk.mjs.map +1 -1
  3. package/lib/base/base.module.d.ts +14 -13
  4. package/lib/base/components/base.component.d.ts +1 -1
  5. package/lib/base/components/generic-embedded-list.component.d.ts +1 -1
  6. package/lib/base/components/generic-form-base.component.d.ts +3 -2
  7. package/lib/base/components/generic-form.component.d.ts +1 -1
  8. package/lib/base/components/generic-list.component.d.ts +23 -3
  9. package/lib/base/components/generic-reactive-form.component.d.ts +1 -1
  10. package/lib/base/constants/common.d.ts +2 -0
  11. package/lib/base/helpers/auth-helper.d.ts +1 -1
  12. package/lib/chips/components/chips.component.d.ts +5 -16
  13. package/lib/common/functions/utils.d.ts +1 -1
  14. package/lib/common/helpers/app-storage.d.ts +1 -1
  15. package/lib/common/styles/_layout.scss +1 -1
  16. package/lib/common/styles/_variables.scss +4 -25
  17. package/lib/common/styles/colors/_colors-dark.scss +2 -0
  18. package/lib/common/styles/colors/_colors.scss +34 -4
  19. package/lib/common/styles/core/_button.scss +7 -21
  20. package/lib/common/styles/core/_card.scss +19 -88
  21. package/lib/common/styles/core/_core.scss +10 -21
  22. package/lib/common/styles/core/_overrides.scss +45 -0
  23. package/lib/common/styles/core/_sidenav.scss +9 -7
  24. package/lib/common/styles/core/_structure.scss +4 -11
  25. package/lib/common/styles/font/_font.scss +5 -13
  26. package/lib/common/styles/m2/_common-theme.scss +10 -10
  27. package/lib/common/styles/m2/platform.scss +13 -0
  28. package/lib/common/styles/m3/_common-theme.scss +27 -10
  29. package/lib/common/styles/m3/platform.scss +13 -0
  30. package/lib/common/styles/utilities/_general.scss +522 -492
  31. package/lib/common/styles/utilities/_pull.scss +23 -30
  32. package/lib/common/styles/utilities/_push.scss +23 -30
  33. package/lib/common/styles/utilities/_size.scss +3 -3
  34. package/lib/common/styles/utilities/_utilities.scss +14 -14
  35. package/lib/common/theming/_m2-all-theme.scss +4 -11
  36. package/lib/form-validators/directives/base-directive.d.ts +1 -1
  37. package/lib/form-validators/directives/template-validations/base-validator.directive.d.ts +1 -1
  38. package/lib/form-validators/directives/template-validations/control-expression-process.d.ts +1 -1
  39. package/lib/form-validators/services/rx-form-array.d.ts +2 -2
  40. package/lib/form-validators/util/reset-form.d.ts +3 -3
  41. package/lib/forms/directives/mat-form-field-editor.directive.d.ts +31 -28
  42. package/lib/forms/forms.module.d.ts +4 -3
  43. package/lib/forms/helpers/abstract-mat-form-field.d.ts +147 -91
  44. package/lib/forms/helpers/abstract-select-form-field.component.d.ts +144 -67
  45. package/lib/forms/helpers/value-accessor-base.d.ts +1 -1
  46. package/lib/layout/_m2-layout-theme.scss +14 -50
  47. package/lib/layout/layout-nav/layout-nav.component.d.ts +7 -1
  48. package/lib/layout/layout-toggle.class.d.ts +1 -1
  49. package/lib/list/components/list.component.d.ts +3 -15
  50. package/lib/menu/components/menu.component.d.ts +16 -1
  51. package/lib/menu/menu.module.d.ts +3 -2
  52. package/lib/select/components/select.component.d.ts +3 -16
  53. package/lib/table/components/dynamic-table/dynamic-table.component.d.ts +5 -1
  54. package/lib/table/components/filter-select/filter-select.component.d.ts +2 -3
  55. package/lib/table/models/table-definition.d.ts +69 -20
  56. package/package.json +3 -5
  57. package/esm2022/lib/base/base.module.mjs +0 -114
  58. package/esm2022/lib/base/components/base.component.mjs +0 -904
  59. package/esm2022/lib/base/components/dynamic-table-config-dialog/dynamic-table-config-dialog.comnponent.mjs +0 -123
  60. package/esm2022/lib/base/components/generic-embedded-list.component.mjs +0 -197
  61. package/esm2022/lib/base/components/generic-form-base.component.mjs +0 -891
  62. package/esm2022/lib/base/components/generic-form.component.mjs +0 -44
  63. package/esm2022/lib/base/components/generic-list.component.mjs +0 -966
  64. package/esm2022/lib/base/components/generic-reactive-form.component.mjs +0 -101
  65. package/esm2022/lib/base/components/task-dialog/task-dialog.component.mjs +0 -147
  66. package/esm2022/lib/base/constants/common.mjs +0 -92
  67. package/esm2022/lib/base/constants/global-roles.mjs +0 -9
  68. package/esm2022/lib/base/enums/message-type.mjs +0 -7
  69. package/esm2022/lib/base/helpers/auth-helper.mjs +0 -53
  70. package/esm2022/lib/base/interceptors/base.interceptor.mjs +0 -168
  71. package/esm2022/lib/base/interceptors/caching-interceptor.mjs +0 -67
  72. package/esm2022/lib/base/interceptors/loading.interceptor.mjs +0 -64
  73. package/esm2022/lib/base/interfaces/ibase-component.mjs +0 -2
  74. package/esm2022/lib/base/interfaces/igeneric-form-base.mjs +0 -2
  75. package/esm2022/lib/base/interfaces/igeneric-list-component.mjs +0 -2
  76. package/esm2022/lib/base/interfaces/igeneric-reactive-form-base.mjs +0 -2
  77. package/esm2022/lib/base/models/auth-user.mjs +0 -18
  78. package/esm2022/lib/base/models/task-dialog-data.mjs +0 -85
  79. package/esm2022/lib/base/public_api.mjs +0 -2
  80. package/esm2022/lib/base/services/file.service.mjs +0 -18
  81. package/esm2022/lib/base/services/loading-screen.service.mjs +0 -45
  82. package/esm2022/lib/base/services/print.service.mjs +0 -41
  83. package/esm2022/lib/chips/chips.module.mjs +0 -77
  84. package/esm2022/lib/chips/components/chips.component.mjs +0 -702
  85. package/esm2022/lib/chips/directives/autocomplete-option.directive.mjs +0 -18
  86. package/esm2022/lib/chips/directives/chip.directive.mjs +0 -18
  87. package/esm2022/lib/chips/public_api.mjs +0 -3
  88. package/esm2022/lib/common/animations/collapse/collapse.animation.mjs +0 -33
  89. package/esm2022/lib/common/animations/common/interfaces.mjs +0 -2
  90. package/esm2022/lib/common/behaviors/constructor.mjs +0 -2
  91. package/esm2022/lib/common/behaviors/control-value-accesor.mixin.mjs +0 -41
  92. package/esm2022/lib/common/behaviors/disabled.mixin.mjs +0 -24
  93. package/esm2022/lib/common/common.module.mjs +0 -176
  94. package/esm2022/lib/common/constants/constants.mjs +0 -3
  95. package/esm2022/lib/common/directives/autofocus.directive.mjs +0 -62
  96. package/esm2022/lib/common/directives/delayed-hover.directive.mjs +0 -133
  97. package/esm2022/lib/common/directives/disable-control.directive.mjs +0 -35
  98. package/esm2022/lib/common/enums/app-event-type.mjs +0 -6
  99. package/esm2022/lib/common/enums/filter-glue.mjs +0 -16
  100. package/esm2022/lib/common/enums/filter-operator.mjs +0 -15
  101. package/esm2022/lib/common/enums/salutation.mjs +0 -7
  102. package/esm2022/lib/common/functions/decorators.mjs +0 -22
  103. package/esm2022/lib/common/functions/functions.mjs +0 -22
  104. package/esm2022/lib/common/functions/utils.mjs +0 -271
  105. package/esm2022/lib/common/helpers/app-storage.mjs +0 -77
  106. package/esm2022/lib/common/helpers/delegate.mjs +0 -2
  107. package/esm2022/lib/common/helpers/dynamic-builder.mjs +0 -52
  108. package/esm2022/lib/common/helpers/dynamic-component-compiler.mjs +0 -11
  109. package/esm2022/lib/common/models/action-item.mjs +0 -77
  110. package/esm2022/lib/common/models/app-event.mjs +0 -21
  111. package/esm2022/lib/common/models/app-setting.mjs +0 -92
  112. package/esm2022/lib/common/models/audit-entity.mjs +0 -53
  113. package/esm2022/lib/common/models/audit-user.mjs +0 -24
  114. package/esm2022/lib/common/models/base-entity.mjs +0 -40
  115. package/esm2022/lib/common/models/common-error.mjs +0 -29
  116. package/esm2022/lib/common/models/common-handler-context.mjs +0 -45
  117. package/esm2022/lib/common/models/displayname-number-projection.mjs +0 -56
  118. package/esm2022/lib/common/models/displayname-projection.mjs +0 -38
  119. package/esm2022/lib/common/models/entity.mjs +0 -2
  120. package/esm2022/lib/common/models/enum-item.mjs +0 -2
  121. package/esm2022/lib/common/models/enum-metadata.mjs +0 -44
  122. package/esm2022/lib/common/models/filter-field.mjs +0 -2
  123. package/esm2022/lib/common/models/filter.mjs +0 -2
  124. package/esm2022/lib/common/models/icommon-handler-context.mjs +0 -2
  125. package/esm2022/lib/common/models/icon.mjs +0 -42
  126. package/esm2022/lib/common/models/key-value.mjs +0 -11
  127. package/esm2022/lib/common/models/modifiable-entity.mjs +0 -22
  128. package/esm2022/lib/common/models/name-number-projection.mjs +0 -35
  129. package/esm2022/lib/common/models/name-projection.mjs +0 -25
  130. package/esm2022/lib/common/models/permission.mjs +0 -29
  131. package/esm2022/lib/common/models/save-action.mjs +0 -7
  132. package/esm2022/lib/common/models/suffix-button.mjs +0 -15
  133. package/esm2022/lib/common/models/title-projection.mjs +0 -25
  134. package/esm2022/lib/common/pipes/bind.mjs +0 -31
  135. package/esm2022/lib/common/pipes/data-source.pipe.mjs +0 -15
  136. package/esm2022/lib/common/pipes/enum.pipe.mjs +0 -41
  137. package/esm2022/lib/common/pipes/file-size.pipe.mjs +0 -35
  138. package/esm2022/lib/common/pipes/filter.pipe.mjs +0 -54
  139. package/esm2022/lib/common/pipes/first-letter.mjs +0 -24
  140. package/esm2022/lib/common/pipes/form-array.pipe.mjs +0 -14
  141. package/esm2022/lib/common/pipes/form-control.pipe.mjs +0 -14
  142. package/esm2022/lib/common/pipes/form-group.pipe.mjs +0 -14
  143. package/esm2022/lib/common/pipes/func.pipe.mjs +0 -14
  144. package/esm2022/lib/common/pipes/join.pipe.mjs +0 -26
  145. package/esm2022/lib/common/pipes/keys.mjs +0 -18
  146. package/esm2022/lib/common/pipes/map.pipe.mjs +0 -48
  147. package/esm2022/lib/common/pipes/month-name.pipe.mjs +0 -25
  148. package/esm2022/lib/common/pipes/nested-property.mjs +0 -29
  149. package/esm2022/lib/common/pipes/only-number.mjs +0 -58
  150. package/esm2022/lib/common/pipes/order.pipe.mjs +0 -269
  151. package/esm2022/lib/common/pipes/placeholder.pipe.mjs +0 -26
  152. package/esm2022/lib/common/pipes/property-join.pipe.mjs +0 -27
  153. package/esm2022/lib/common/pipes/safe-html.pipe.mjs +0 -32
  154. package/esm2022/lib/common/pipes/split.pipe.mjs +0 -25
  155. package/esm2022/lib/common/pipes/time.pipe.mjs +0 -21
  156. package/esm2022/lib/common/pipes/titlecase.pipe.mjs +0 -14
  157. package/esm2022/lib/common/pipes/truncate.pipe.mjs +0 -15
  158. package/esm2022/lib/common/pipes/values.mjs +0 -14
  159. package/esm2022/lib/common/public_api.mjs +0 -41
  160. package/esm2022/lib/common/services/base.service.mjs +0 -19
  161. package/esm2022/lib/common/services/context-helper.mjs +0 -17
  162. package/esm2022/lib/common/services/enum.service.mjs +0 -81
  163. package/esm2022/lib/common/services/event-queue.service.mjs +0 -31
  164. package/esm2022/lib/common/services/service-locator.mjs +0 -25
  165. package/esm2022/lib/common/templates/templates.mjs +0 -87
  166. package/esm2022/lib/dialogs/alert-dialog/alert-dialog.component.mjs +0 -46
  167. package/esm2022/lib/dialogs/confirm-dialog/confirm-dialog.component.mjs +0 -60
  168. package/esm2022/lib/dialogs/dialog.component.mjs +0 -59
  169. package/esm2022/lib/dialogs/dialogs.module.mjs +0 -72
  170. package/esm2022/lib/dialogs/prompt-dialog/prompt-dialog.component.mjs +0 -44
  171. package/esm2022/lib/dialogs/public_api.mjs +0 -2
  172. package/esm2022/lib/dialogs/services/dialog.service.mjs +0 -154
  173. package/esm2022/lib/file/file-input.component.mjs +0 -334
  174. package/esm2022/lib/file/file.module.mjs +0 -37
  175. package/esm2022/lib/file/public_api.mjs +0 -2
  176. package/esm2022/lib/form-validators/abstract/typed-form.mjs +0 -13
  177. package/esm2022/lib/form-validators/algorithm/luhn-algorithm.mjs +0 -33
  178. package/esm2022/lib/form-validators/const/app-validators.const.mjs +0 -68
  179. package/esm2022/lib/form-validators/const/app.const.mjs +0 -65
  180. package/esm2022/lib/form-validators/const/config-names.const.mjs +0 -33
  181. package/esm2022/lib/form-validators/const/config-required-fields.const.mjs +0 -35
  182. package/esm2022/lib/form-validators/const/decorators.const.mjs +0 -23
  183. package/esm2022/lib/form-validators/const/events.const.mjs +0 -53
  184. package/esm2022/lib/form-validators/const/html-elements.const.mjs +0 -25
  185. package/esm2022/lib/form-validators/const/iban-country-wise-regex.const.mjs +0 -80
  186. package/esm2022/lib/form-validators/const/index.mjs +0 -6
  187. package/esm2022/lib/form-validators/const/operators.const.mjs +0 -7
  188. package/esm2022/lib/form-validators/const/validation-alphabet-locale.const.mjs +0 -9
  189. package/esm2022/lib/form-validators/const/validator.const.mjs +0 -29
  190. package/esm2022/lib/form-validators/core/annotation-types.mjs +0 -75
  191. package/esm2022/lib/form-validators/core/default-container.mjs +0 -500
  192. package/esm2022/lib/form-validators/decorators/allOf.decorator.mjs +0 -10
  193. package/esm2022/lib/form-validators/decorators/alpha.decorator.mjs +0 -10
  194. package/esm2022/lib/form-validators/decorators/alphaNumeric.decorator.mjs +0 -10
  195. package/esm2022/lib/form-validators/decorators/and.decorator.mjs +0 -6
  196. package/esm2022/lib/form-validators/decorators/ascii.decorator.mjs +0 -6
  197. package/esm2022/lib/form-validators/decorators/async.decorator.mjs +0 -6
  198. package/esm2022/lib/form-validators/decorators/base-decorator.function.mjs +0 -7
  199. package/esm2022/lib/form-validators/decorators/choice.decorator.mjs +0 -10
  200. package/esm2022/lib/form-validators/decorators/compare.decorator.mjs +0 -6
  201. package/esm2022/lib/form-validators/decorators/compose.decorator.mjs +0 -6
  202. package/esm2022/lib/form-validators/decorators/contains.decorator.mjs +0 -10
  203. package/esm2022/lib/form-validators/decorators/credit-card.decorator.mjs +0 -10
  204. package/esm2022/lib/form-validators/decorators/cusip.decorator.mjs +0 -6
  205. package/esm2022/lib/form-validators/decorators/custom.decorator.mjs +0 -10
  206. package/esm2022/lib/form-validators/decorators/dataUri.decorator.mjs +0 -6
  207. package/esm2022/lib/form-validators/decorators/date.decorator.mjs +0 -10
  208. package/esm2022/lib/form-validators/decorators/different.decorator.mjs +0 -6
  209. package/esm2022/lib/form-validators/decorators/digit.decorator.mjs +0 -6
  210. package/esm2022/lib/form-validators/decorators/email.decorator.mjs +0 -6
  211. package/esm2022/lib/form-validators/decorators/endsWith.decorator.mjs +0 -10
  212. package/esm2022/lib/form-validators/decorators/even.decorator.mjs +0 -6
  213. package/esm2022/lib/form-validators/decorators/extension.decorator.mjs +0 -10
  214. package/esm2022/lib/form-validators/decorators/factor.decorator.mjs +0 -10
  215. package/esm2022/lib/form-validators/decorators/file.decorator.mjs +0 -10
  216. package/esm2022/lib/form-validators/decorators/fileSize.decorator.mjs +0 -10
  217. package/esm2022/lib/form-validators/decorators/greater-than-equal-to.decorator.mjs +0 -10
  218. package/esm2022/lib/form-validators/decorators/greater-than.decorator.mjs +0 -10
  219. package/esm2022/lib/form-validators/decorators/grid.decorator.mjs +0 -6
  220. package/esm2022/lib/form-validators/decorators/hexColor.decorator.mjs +0 -6
  221. package/esm2022/lib/form-validators/decorators/image.decorator.mjs +0 -10
  222. package/esm2022/lib/form-validators/decorators/index.mjs +0 -93
  223. package/esm2022/lib/form-validators/decorators/json.decorator.mjs +0 -6
  224. package/esm2022/lib/form-validators/decorators/latLong.decorator.mjs +0 -6
  225. package/esm2022/lib/form-validators/decorators/latitude.decorator.mjs +0 -6
  226. package/esm2022/lib/form-validators/decorators/leapYear.decorator.mjs +0 -6
  227. package/esm2022/lib/form-validators/decorators/less-than-equal-to.decorator.mjs +0 -10
  228. package/esm2022/lib/form-validators/decorators/less-than.decorator.mjs +0 -10
  229. package/esm2022/lib/form-validators/decorators/longitude.decorator.mjs +0 -6
  230. package/esm2022/lib/form-validators/decorators/lowercase.decorator.mjs +0 -6
  231. package/esm2022/lib/form-validators/decorators/mac.decorator.mjs +0 -6
  232. package/esm2022/lib/form-validators/decorators/mask.decorator.mjs +0 -6
  233. package/esm2022/lib/form-validators/decorators/maxDate.decorator.mjs +0 -10
  234. package/esm2022/lib/form-validators/decorators/maxLength.decorator.mjs +0 -10
  235. package/esm2022/lib/form-validators/decorators/maxNumber.decorator.mjs +0 -10
  236. package/esm2022/lib/form-validators/decorators/maxTime.decorator.mjs +0 -10
  237. package/esm2022/lib/form-validators/decorators/minDate.decorator.mjs +0 -10
  238. package/esm2022/lib/form-validators/decorators/minLength.decorator.mjs +0 -10
  239. package/esm2022/lib/form-validators/decorators/minNumber.decorator.mjs +0 -10
  240. package/esm2022/lib/form-validators/decorators/minTime.decorator.mjs +0 -10
  241. package/esm2022/lib/form-validators/decorators/model.decorator.mjs +0 -7
  242. package/esm2022/lib/form-validators/decorators/non-validation-decorators/disable.decorator.mjs +0 -8
  243. package/esm2022/lib/form-validators/decorators/non-validation-decorators/elementClass.decorator.mjs +0 -8
  244. package/esm2022/lib/form-validators/decorators/non-validation-decorators/error.decorator.mjs +0 -8
  245. package/esm2022/lib/form-validators/decorators/non-validation-decorators/update-on.decorator.mjs +0 -6
  246. package/esm2022/lib/form-validators/decorators/noneOf.decorator.mjs +0 -10
  247. package/esm2022/lib/form-validators/decorators/not.decorator.mjs +0 -6
  248. package/esm2022/lib/form-validators/decorators/notEmpty.decorator.mjs +0 -6
  249. package/esm2022/lib/form-validators/decorators/numeric.decorator.mjs +0 -10
  250. package/esm2022/lib/form-validators/decorators/odd.decorator.mjs +0 -6
  251. package/esm2022/lib/form-validators/decorators/oneOf.decorator.mjs +0 -10
  252. package/esm2022/lib/form-validators/decorators/or.decorator.mjs +0 -6
  253. package/esm2022/lib/form-validators/decorators/password.decorator.mjs +0 -10
  254. package/esm2022/lib/form-validators/decorators/pattern.decorator.mjs +0 -10
  255. package/esm2022/lib/form-validators/decorators/port.decorator.mjs +0 -6
  256. package/esm2022/lib/form-validators/decorators/primeNumber.decorator.mjs +0 -6
  257. package/esm2022/lib/form-validators/decorators/prop-array.decorator.mjs +0 -18
  258. package/esm2022/lib/form-validators/decorators/prop-object.decorator.mjs +0 -8
  259. package/esm2022/lib/form-validators/decorators/prop.decorator.mjs +0 -18
  260. package/esm2022/lib/form-validators/decorators/range.decorator.mjs +0 -10
  261. package/esm2022/lib/form-validators/decorators/required.decorator.mjs +0 -6
  262. package/esm2022/lib/form-validators/decorators/requiredTrue.decorator.mjs +0 -6
  263. package/esm2022/lib/form-validators/decorators/rule.decorator.mjs +0 -6
  264. package/esm2022/lib/form-validators/decorators/sanitize/blacklist.decorator.mjs +0 -8
  265. package/esm2022/lib/form-validators/decorators/sanitize/escape.decorator.mjs +0 -8
  266. package/esm2022/lib/form-validators/decorators/sanitize/ltrim.decorator.mjs +0 -8
  267. package/esm2022/lib/form-validators/decorators/sanitize/prefix.decorator.mjs +0 -8
  268. package/esm2022/lib/form-validators/decorators/sanitize/rtrim.decorator.mjs +0 -8
  269. package/esm2022/lib/form-validators/decorators/sanitize/sanitize.decorator.mjs +0 -8
  270. package/esm2022/lib/form-validators/decorators/sanitize/stripLow.decorator.mjs +0 -8
  271. package/esm2022/lib/form-validators/decorators/sanitize/suffix.decorator.mjs +0 -8
  272. package/esm2022/lib/form-validators/decorators/sanitize/toBoolean.decorator.mjs +0 -8
  273. package/esm2022/lib/form-validators/decorators/sanitize/toDate.decorator.mjs +0 -8
  274. package/esm2022/lib/form-validators/decorators/sanitize/toDouble.decorator.mjs +0 -8
  275. package/esm2022/lib/form-validators/decorators/sanitize/toFloat.decorator.mjs +0 -8
  276. package/esm2022/lib/form-validators/decorators/sanitize/toInt.decorator.mjs +0 -8
  277. package/esm2022/lib/form-validators/decorators/sanitize/toString.decorator.mjs +0 -8
  278. package/esm2022/lib/form-validators/decorators/sanitize/trim.decorator.mjs +0 -8
  279. package/esm2022/lib/form-validators/decorators/sanitize/whitelist.decorator.mjs +0 -8
  280. package/esm2022/lib/form-validators/decorators/startsWith.decorator.mjs +0 -10
  281. package/esm2022/lib/form-validators/decorators/time.decorator.mjs +0 -10
  282. package/esm2022/lib/form-validators/decorators/unique.decorator.mjs +0 -6
  283. package/esm2022/lib/form-validators/decorators/uppercase.decorator.mjs +0 -6
  284. package/esm2022/lib/form-validators/decorators/url.decorator.mjs +0 -10
  285. package/esm2022/lib/form-validators/directives/base-directive.mjs +0 -75
  286. package/esm2022/lib/form-validators/directives/control-host.directive.mjs +0 -55
  287. package/esm2022/lib/form-validators/directives/html-control-template.directive.mjs +0 -36
  288. package/esm2022/lib/form-validators/directives/rx-form.directive.mjs +0 -234
  289. package/esm2022/lib/form-validators/directives/template-validations/async-validation.directive.mjs +0 -40
  290. package/esm2022/lib/form-validators/directives/template-validations/base-validator.directive.mjs +0 -76
  291. package/esm2022/lib/form-validators/directives/template-validations/control-expression-process.mjs +0 -60
  292. package/esm2022/lib/form-validators/directives/template-validations/file-control.directive.mjs +0 -122
  293. package/esm2022/lib/form-validators/directives/template-validations/image-file-control.directive.mjs +0 -74
  294. package/esm2022/lib/form-validators/directives/template-validations/rxformcontrol.directive.mjs +0 -394
  295. package/esm2022/lib/form-validators/domain/disable-provider.mjs +0 -198
  296. package/esm2022/lib/form-validators/domain/element-processor/decimal.provider.mjs +0 -134
  297. package/esm2022/lib/form-validators/domain/element-processor/mask.provider.mjs +0 -453
  298. package/esm2022/lib/form-validators/domain/form-data.mjs +0 -93
  299. package/esm2022/lib/form-validators/enums/error-message-binding-strategy.mjs +0 -11
  300. package/esm2022/lib/form-validators/enums/index.mjs +0 -5
  301. package/esm2022/lib/form-validators/enums/ip-version.mjs +0 -7
  302. package/esm2022/lib/form-validators/enums/numeric-value-type.mjs +0 -7
  303. package/esm2022/lib/form-validators/enums/reset-type.mjs +0 -10
  304. package/esm2022/lib/form-validators/enums/url-validation-type.mjs +0 -7
  305. package/esm2022/lib/form-validators/models/config/alpha-config.mjs +0 -2
  306. package/esm2022/lib/form-validators/models/config/array-config.mjs +0 -2
  307. package/esm2022/lib/form-validators/models/config/base-config-fn.mjs +0 -2
  308. package/esm2022/lib/form-validators/models/config/base-config.mjs +0 -2
  309. package/esm2022/lib/form-validators/models/config/base-date-config.mjs +0 -2
  310. package/esm2022/lib/form-validators/models/config/choice-config.mjs +0 -2
  311. package/esm2022/lib/form-validators/models/config/compare-config.mjs +0 -2
  312. package/esm2022/lib/form-validators/models/config/component-config.mjs +0 -2
  313. package/esm2022/lib/form-validators/models/config/compose-config.mjs +0 -2
  314. package/esm2022/lib/form-validators/models/config/contains-config.mjs +0 -2
  315. package/esm2022/lib/form-validators/models/config/credit-card-config.mjs +0 -2
  316. package/esm2022/lib/form-validators/models/config/custom-config.mjs +0 -2
  317. package/esm2022/lib/form-validators/models/config/date-config.mjs +0 -2
  318. package/esm2022/lib/form-validators/models/config/default-config.mjs +0 -2
  319. package/esm2022/lib/form-validators/models/config/digit-config.mjs +0 -2
  320. package/esm2022/lib/form-validators/models/config/disable-config.mjs +0 -2
  321. package/esm2022/lib/form-validators/models/config/element-class-config.mjs +0 -2
  322. package/esm2022/lib/form-validators/models/config/email-config.mjs +0 -2
  323. package/esm2022/lib/form-validators/models/config/error-config.mjs +0 -2
  324. package/esm2022/lib/form-validators/models/config/extension-config.mjs +0 -2
  325. package/esm2022/lib/form-validators/models/config/factor-config.mjs +0 -2
  326. package/esm2022/lib/form-validators/models/config/field-config.mjs +0 -2
  327. package/esm2022/lib/form-validators/models/config/file-config.mjs +0 -2
  328. package/esm2022/lib/form-validators/models/config/hex-color-config.mjs +0 -2
  329. package/esm2022/lib/form-validators/models/config/iban-config.mjs +0 -2
  330. package/esm2022/lib/form-validators/models/config/image-config.mjs +0 -2
  331. package/esm2022/lib/form-validators/models/config/index.mjs +0 -35
  332. package/esm2022/lib/form-validators/models/config/ip-config.mjs +0 -2
  333. package/esm2022/lib/form-validators/models/config/logical-operator-config.mjs +0 -2
  334. package/esm2022/lib/form-validators/models/config/mask-config.mjs +0 -2
  335. package/esm2022/lib/form-validators/models/config/max-date-config.mjs +0 -2
  336. package/esm2022/lib/form-validators/models/config/message-config.mjs +0 -2
  337. package/esm2022/lib/form-validators/models/config/min-date-config.mjs +0 -2
  338. package/esm2022/lib/form-validators/models/config/model-config.mjs +0 -2
  339. package/esm2022/lib/form-validators/models/config/number-config.mjs +0 -2
  340. package/esm2022/lib/form-validators/models/config/numeric-config.mjs +0 -2
  341. package/esm2022/lib/form-validators/models/config/password-config.mjs +0 -2
  342. package/esm2022/lib/form-validators/models/config/pattern-config.mjs +0 -2
  343. package/esm2022/lib/form-validators/models/config/prop-config.mjs +0 -2
  344. package/esm2022/lib/form-validators/models/config/props-config.mjs +0 -2
  345. package/esm2022/lib/form-validators/models/config/range-config.mjs +0 -2
  346. package/esm2022/lib/form-validators/models/config/relational-operator-config.mjs +0 -2
  347. package/esm2022/lib/form-validators/models/config/required-config.mjs +0 -2
  348. package/esm2022/lib/form-validators/models/config/rule-config.mjs +0 -2
  349. package/esm2022/lib/form-validators/models/config/sanitize-config.mjs +0 -2
  350. package/esm2022/lib/form-validators/models/config/size-config.mjs +0 -2
  351. package/esm2022/lib/form-validators/models/config/string-comparison-config.mjs +0 -2
  352. package/esm2022/lib/form-validators/models/config/string-value-config.mjs +0 -2
  353. package/esm2022/lib/form-validators/models/config/time-config.mjs +0 -2
  354. package/esm2022/lib/form-validators/models/config/todate-config.mjs +0 -2
  355. package/esm2022/lib/form-validators/models/config/unique-config.mjs +0 -2
  356. package/esm2022/lib/form-validators/models/config/update-on-config.mjs +0 -2
  357. package/esm2022/lib/form-validators/models/config/url-config.mjs +0 -2
  358. package/esm2022/lib/form-validators/models/control-info.mjs +0 -2
  359. package/esm2022/lib/form-validators/models/data-sanitizer.mjs +0 -2
  360. package/esm2022/lib/form-validators/models/decorator-configuration.mjs +0 -2
  361. package/esm2022/lib/form-validators/models/form-builder-configuration.mjs +0 -58
  362. package/esm2022/lib/form-validators/models/index.mjs +0 -3
  363. package/esm2022/lib/form-validators/models/instance-container.mjs +0 -2
  364. package/esm2022/lib/form-validators/models/interface/array-prop-instance-config.interface.mjs +0 -2
  365. package/esm2022/lib/form-validators/models/interface/auto-instance-config.interface.mjs +0 -2
  366. package/esm2022/lib/form-validators/models/interface/form-data-config.mjs +0 -2
  367. package/esm2022/lib/form-validators/models/interface/i-abstract-control.mjs +0 -30
  368. package/esm2022/lib/form-validators/models/interface/i-form-group.mjs +0 -2
  369. package/esm2022/lib/form-validators/models/interface/instance-argument.interface.mjs +0 -2
  370. package/esm2022/lib/form-validators/models/interface/object-prop-instance-config.interface.mjs +0 -2
  371. package/esm2022/lib/form-validators/models/interface/options.mjs +0 -2
  372. package/esm2022/lib/form-validators/models/password-validation.model.mjs +0 -2
  373. package/esm2022/lib/form-validators/models/prop-validation-config.mjs +0 -2
  374. package/esm2022/lib/form-validators/models/property-info.mjs +0 -2
  375. package/esm2022/lib/form-validators/public_api.mjs +0 -26
  376. package/esm2022/lib/form-validators/reactive-form-validators/allOf.validator.mjs +0 -33
  377. package/esm2022/lib/form-validators/reactive-form-validators/alpha.validator.mjs +0 -15
  378. package/esm2022/lib/form-validators/reactive-form-validators/alphaNumeric.validator.mjs +0 -15
  379. package/esm2022/lib/form-validators/reactive-form-validators/and.validator.mjs +0 -38
  380. package/esm2022/lib/form-validators/reactive-form-validators/ascii.validator.mjs +0 -15
  381. package/esm2022/lib/form-validators/reactive-form-validators/async/base.async.validator.mjs +0 -45
  382. package/esm2022/lib/form-validators/reactive-form-validators/choice.validator.mjs +0 -31
  383. package/esm2022/lib/form-validators/reactive-form-validators/compare.validator.mjs +0 -32
  384. package/esm2022/lib/form-validators/reactive-form-validators/compose.validator.mjs +0 -34
  385. package/esm2022/lib/form-validators/reactive-form-validators/conditional-change.validator.mjs +0 -63
  386. package/esm2022/lib/form-validators/reactive-form-validators/contains.validator.mjs +0 -22
  387. package/esm2022/lib/form-validators/reactive-form-validators/credit-card.validator.mjs +0 -48
  388. package/esm2022/lib/form-validators/reactive-form-validators/cusip.validator.mjs +0 -38
  389. package/esm2022/lib/form-validators/reactive-form-validators/custom.validator.mjs +0 -25
  390. package/esm2022/lib/form-validators/reactive-form-validators/dataUri.validator.mjs +0 -9
  391. package/esm2022/lib/form-validators/reactive-form-validators/date.validator.mjs +0 -8
  392. package/esm2022/lib/form-validators/reactive-form-validators/different.validator.mjs +0 -19
  393. package/esm2022/lib/form-validators/reactive-form-validators/digit.validator.mjs +0 -9
  394. package/esm2022/lib/form-validators/reactive-form-validators/email.validator.mjs +0 -9
  395. package/esm2022/lib/form-validators/reactive-form-validators/endsWith.validator.mjs +0 -23
  396. package/esm2022/lib/form-validators/reactive-form-validators/even.validator.mjs +0 -15
  397. package/esm2022/lib/form-validators/reactive-form-validators/extension.validator.mjs +0 -40
  398. package/esm2022/lib/form-validators/reactive-form-validators/factor.validator.mjs +0 -37
  399. package/esm2022/lib/form-validators/reactive-form-validators/file.validator.mjs +0 -26
  400. package/esm2022/lib/form-validators/reactive-form-validators/fileSize.validator.mjs +0 -34
  401. package/esm2022/lib/form-validators/reactive-form-validators/greater-than-equal-to.validator.mjs +0 -8
  402. package/esm2022/lib/form-validators/reactive-form-validators/greater-than.validator.mjs +0 -8
  403. package/esm2022/lib/form-validators/reactive-form-validators/grid.validator.mjs +0 -31
  404. package/esm2022/lib/form-validators/reactive-form-validators/hexcolor.validator.mjs +0 -9
  405. package/esm2022/lib/form-validators/reactive-form-validators/iban.validator.mjs +0 -28
  406. package/esm2022/lib/form-validators/reactive-form-validators/image.validator.mjs +0 -52
  407. package/esm2022/lib/form-validators/reactive-form-validators/index.mjs +0 -66
  408. package/esm2022/lib/form-validators/reactive-form-validators/ip.validator.mjs +0 -28
  409. package/esm2022/lib/form-validators/reactive-form-validators/json.validator.mjs +0 -26
  410. package/esm2022/lib/form-validators/reactive-form-validators/latLong.validator.mjs +0 -18
  411. package/esm2022/lib/form-validators/reactive-form-validators/latitude.validator.mjs +0 -9
  412. package/esm2022/lib/form-validators/reactive-form-validators/leapYear.validator.mjs +0 -16
  413. package/esm2022/lib/form-validators/reactive-form-validators/less-than-equal-to.validator.mjs +0 -8
  414. package/esm2022/lib/form-validators/reactive-form-validators/less-than.validator.mjs +0 -8
  415. package/esm2022/lib/form-validators/reactive-form-validators/longitude.validator.mjs +0 -9
  416. package/esm2022/lib/form-validators/reactive-form-validators/lowercase.validator.mjs +0 -15
  417. package/esm2022/lib/form-validators/reactive-form-validators/mac.validator.mjs +0 -9
  418. package/esm2022/lib/form-validators/reactive-form-validators/mask.validator.mjs +0 -14
  419. package/esm2022/lib/form-validators/reactive-form-validators/maxDate.validator.mjs +0 -8
  420. package/esm2022/lib/form-validators/reactive-form-validators/maxLength.validator.mjs +0 -17
  421. package/esm2022/lib/form-validators/reactive-form-validators/maxNumber.validator.mjs +0 -17
  422. package/esm2022/lib/form-validators/reactive-form-validators/maxTime.validator.mjs +0 -8
  423. package/esm2022/lib/form-validators/reactive-form-validators/minDate.validator.mjs +0 -8
  424. package/esm2022/lib/form-validators/reactive-form-validators/minLength.validator.mjs +0 -16
  425. package/esm2022/lib/form-validators/reactive-form-validators/minNumber.validator.mjs +0 -16
  426. package/esm2022/lib/form-validators/reactive-form-validators/minTime.validator.mjs +0 -8
  427. package/esm2022/lib/form-validators/reactive-form-validators/noneOf.validator.mjs +0 -24
  428. package/esm2022/lib/form-validators/reactive-form-validators/not.validator.mjs +0 -25
  429. package/esm2022/lib/form-validators/reactive-form-validators/notEmpty.validator.mjs +0 -17
  430. package/esm2022/lib/form-validators/reactive-form-validators/numeric.validator.mjs +0 -22
  431. package/esm2022/lib/form-validators/reactive-form-validators/odd.validator.mjs +0 -17
  432. package/esm2022/lib/form-validators/reactive-form-validators/oneOf.validator.mjs +0 -26
  433. package/esm2022/lib/form-validators/reactive-form-validators/or.validator.mjs +0 -25
  434. package/esm2022/lib/form-validators/reactive-form-validators/password.validator.mjs +0 -35
  435. package/esm2022/lib/form-validators/reactive-form-validators/pattern.validator.mjs +0 -19
  436. package/esm2022/lib/form-validators/reactive-form-validators/port.validator.mjs +0 -19
  437. package/esm2022/lib/form-validators/reactive-form-validators/primeNumber.validator.mjs +0 -27
  438. package/esm2022/lib/form-validators/reactive-form-validators/range.validator.mjs +0 -17
  439. package/esm2022/lib/form-validators/reactive-form-validators/required.validator.mjs +0 -17
  440. package/esm2022/lib/form-validators/reactive-form-validators/requiredTrue.validator.mjs +0 -16
  441. package/esm2022/lib/form-validators/reactive-form-validators/rule.validator.mjs +0 -22
  442. package/esm2022/lib/form-validators/reactive-form-validators/startsWith.validator.mjs +0 -25
  443. package/esm2022/lib/form-validators/reactive-form-validators/time.validator.mjs +0 -19
  444. package/esm2022/lib/form-validators/reactive-form-validators/unique.validator.mjs +0 -77
  445. package/esm2022/lib/form-validators/reactive-form-validators/uppercase.validator.mjs +0 -16
  446. package/esm2022/lib/form-validators/reactive-form-validators/url.validator.mjs +0 -28
  447. package/esm2022/lib/form-validators/services/base-form-builder.mjs +0 -220
  448. package/esm2022/lib/form-validators/services/entity.service.mjs +0 -76
  449. package/esm2022/lib/form-validators/services/form-control.mjs +0 -370
  450. package/esm2022/lib/form-validators/services/form-group.mjs +0 -2
  451. package/esm2022/lib/form-validators/services/reactive-form.module.mjs +0 -52
  452. package/esm2022/lib/form-validators/services/rx-form-array.mjs +0 -114
  453. package/esm2022/lib/form-validators/services/rx-form-builder.mjs +0 -1035
  454. package/esm2022/lib/form-validators/services/rx-form-group.mjs +0 -451
  455. package/esm2022/lib/form-validators/services/typed-form-builder.mjs +0 -25
  456. package/esm2022/lib/form-validators/util/alphabet-regex.locale.mjs +0 -29
  457. package/esm2022/lib/form-validators/util/app-util.mjs +0 -161
  458. package/esm2022/lib/form-validators/util/check-length.mjs +0 -11
  459. package/esm2022/lib/form-validators/util/config-provider.mjs +0 -37
  460. package/esm2022/lib/form-validators/util/date-checker.function.mjs +0 -52
  461. package/esm2022/lib/form-validators/util/date-provider.mjs +0 -108
  462. package/esm2022/lib/form-validators/util/form-const.mjs +0 -3
  463. package/esm2022/lib/form-validators/util/form-provider.mjs +0 -87
  464. package/esm2022/lib/form-validators/util/index.mjs +0 -7
  465. package/esm2022/lib/form-validators/util/instance-provider.function.mjs +0 -63
  466. package/esm2022/lib/form-validators/util/ip-checker.mjs +0 -19
  467. package/esm2022/lib/form-validators/util/linq.mjs +0 -157
  468. package/esm2022/lib/form-validators/util/object-maker.mjs +0 -68
  469. package/esm2022/lib/form-validators/util/reactive-form-config.mjs +0 -25
  470. package/esm2022/lib/form-validators/util/regex-rules.mjs +0 -37
  471. package/esm2022/lib/form-validators/util/regex-validator.mjs +0 -74
  472. package/esm2022/lib/form-validators/util/relational-checker.function.mjs +0 -92
  473. package/esm2022/lib/form-validators/util/reset-form.mjs +0 -57
  474. package/esm2022/lib/form-validators/util/sanitizers.mjs +0 -140
  475. package/esm2022/lib/form-validators/util/time-checker.function.mjs +0 -50
  476. package/esm2022/lib/form-validators/util/type.mjs +0 -2
  477. package/esm2022/lib/form-validators/util/validator-value-checker.mjs +0 -21
  478. package/esm2022/lib/form-validators/validators-extension/allOf-validator.extension.mjs +0 -11
  479. package/esm2022/lib/form-validators/validators-extension/alpha-validator.extension.mjs +0 -11
  480. package/esm2022/lib/form-validators/validators-extension/alphaNumeric-validator.extension.mjs +0 -11
  481. package/esm2022/lib/form-validators/validators-extension/and-validator.extension.mjs +0 -7
  482. package/esm2022/lib/form-validators/validators-extension/ascii-validator.extension.mjs +0 -7
  483. package/esm2022/lib/form-validators/validators-extension/base-validator.function.mjs +0 -34
  484. package/esm2022/lib/form-validators/validators-extension/choice-validator.extension.mjs +0 -11
  485. package/esm2022/lib/form-validators/validators-extension/compare-validator.extension.mjs +0 -7
  486. package/esm2022/lib/form-validators/validators-extension/compose-validator.extension.mjs +0 -7
  487. package/esm2022/lib/form-validators/validators-extension/contains-validator.extension.mjs +0 -11
  488. package/esm2022/lib/form-validators/validators-extension/credit-card-validator.extension.mjs +0 -11
  489. package/esm2022/lib/form-validators/validators-extension/cusip-validator.extension.mjs +0 -7
  490. package/esm2022/lib/form-validators/validators-extension/custom-validator.extension.mjs +0 -11
  491. package/esm2022/lib/form-validators/validators-extension/dataUri-validator.extension.mjs +0 -7
  492. package/esm2022/lib/form-validators/validators-extension/date-validator.extension.mjs +0 -11
  493. package/esm2022/lib/form-validators/validators-extension/different-validator.extension.mjs +0 -7
  494. package/esm2022/lib/form-validators/validators-extension/digit-validator.extension.mjs +0 -7
  495. package/esm2022/lib/form-validators/validators-extension/email-validator.extension.mjs +0 -7
  496. package/esm2022/lib/form-validators/validators-extension/endsWith-validator.extension.mjs +0 -11
  497. package/esm2022/lib/form-validators/validators-extension/even-validator.extension.mjs +0 -7
  498. package/esm2022/lib/form-validators/validators-extension/extension-validator.extension.mjs +0 -10
  499. package/esm2022/lib/form-validators/validators-extension/factor-validator.extension.mjs +0 -11
  500. package/esm2022/lib/form-validators/validators-extension/file-validator.extension.mjs +0 -10
  501. package/esm2022/lib/form-validators/validators-extension/fileSize-validator.extension.mjs +0 -10
  502. package/esm2022/lib/form-validators/validators-extension/greater-than-equal-to-validator.extension.mjs +0 -11
  503. package/esm2022/lib/form-validators/validators-extension/greater-than-validator.extension.mjs +0 -11
  504. package/esm2022/lib/form-validators/validators-extension/grid-validator.extension.mjs +0 -7
  505. package/esm2022/lib/form-validators/validators-extension/hexcolor-validator.extension.mjs +0 -7
  506. package/esm2022/lib/form-validators/validators-extension/iban-validator.extension.mjs +0 -11
  507. package/esm2022/lib/form-validators/validators-extension/image-validator.extension.mjs +0 -10
  508. package/esm2022/lib/form-validators/validators-extension/index.mjs +0 -68
  509. package/esm2022/lib/form-validators/validators-extension/ip-validator.extension.mjs +0 -11
  510. package/esm2022/lib/form-validators/validators-extension/json-validator.extension.mjs +0 -7
  511. package/esm2022/lib/form-validators/validators-extension/latLong-validator.extension.mjs +0 -7
  512. package/esm2022/lib/form-validators/validators-extension/latitude-validator.extension.mjs +0 -7
  513. package/esm2022/lib/form-validators/validators-extension/leapYear-validator.extension.mjs +0 -7
  514. package/esm2022/lib/form-validators/validators-extension/less-than-equal-to-validator.extension.mjs +0 -11
  515. package/esm2022/lib/form-validators/validators-extension/less-than-validator.extension.mjs +0 -11
  516. package/esm2022/lib/form-validators/validators-extension/longitude-validator.extension.mjs +0 -7
  517. package/esm2022/lib/form-validators/validators-extension/lowercase-validator.extension.mjs +0 -7
  518. package/esm2022/lib/form-validators/validators-extension/mac-validator.extension.mjs +0 -7
  519. package/esm2022/lib/form-validators/validators-extension/mask-validator.extension.mjs +0 -7
  520. package/esm2022/lib/form-validators/validators-extension/maxDate-validator.extension.mjs +0 -11
  521. package/esm2022/lib/form-validators/validators-extension/maxLength-validator.extension.mjs +0 -11
  522. package/esm2022/lib/form-validators/validators-extension/maxNumber-validator.extension.mjs +0 -11
  523. package/esm2022/lib/form-validators/validators-extension/maxTime-validator.extension.mjs +0 -11
  524. package/esm2022/lib/form-validators/validators-extension/minDate-validator.extension.mjs +0 -11
  525. package/esm2022/lib/form-validators/validators-extension/minLength-validator.extension.mjs +0 -11
  526. package/esm2022/lib/form-validators/validators-extension/minNumber-validator.extension.mjs +0 -11
  527. package/esm2022/lib/form-validators/validators-extension/minTime-validator.extension.mjs +0 -11
  528. package/esm2022/lib/form-validators/validators-extension/noneOf-validator.extension.mjs +0 -11
  529. package/esm2022/lib/form-validators/validators-extension/not-validator.extension.mjs +0 -7
  530. package/esm2022/lib/form-validators/validators-extension/notEmpty-validator.extension.mjs +0 -7
  531. package/esm2022/lib/form-validators/validators-extension/numeric-validator.extension.mjs +0 -11
  532. package/esm2022/lib/form-validators/validators-extension/odd-validator.extension.mjs +0 -7
  533. package/esm2022/lib/form-validators/validators-extension/oneOf-validator.extension.mjs +0 -11
  534. package/esm2022/lib/form-validators/validators-extension/or-validator.extension.mjs +0 -7
  535. package/esm2022/lib/form-validators/validators-extension/password-validator.extension.mjs +0 -11
  536. package/esm2022/lib/form-validators/validators-extension/pattern-validator.extension.mjs +0 -11
  537. package/esm2022/lib/form-validators/validators-extension/port-validator.extension.mjs +0 -7
  538. package/esm2022/lib/form-validators/validators-extension/primeNumber-validator.extension.mjs +0 -7
  539. package/esm2022/lib/form-validators/validators-extension/range-validator.extension.mjs +0 -11
  540. package/esm2022/lib/form-validators/validators-extension/required-validator.extension.mjs +0 -7
  541. package/esm2022/lib/form-validators/validators-extension/requiredTrue-validator.extension.mjs +0 -7
  542. package/esm2022/lib/form-validators/validators-extension/rxweb-validators.mjs +0 -108
  543. package/esm2022/lib/form-validators/validators-extension/startsWith-validator.extension.mjs +0 -11
  544. package/esm2022/lib/form-validators/validators-extension/time-validator.extension.mjs +0 -11
  545. package/esm2022/lib/form-validators/validators-extension/unique-validator.extension.mjs +0 -7
  546. package/esm2022/lib/form-validators/validators-extension/uppercase-validator.extension.mjs +0 -7
  547. package/esm2022/lib/form-validators/validators-extension/url-validator.extension.mjs +0 -11
  548. package/esm2022/lib/form-validators/validators-function/alpha-validation.function.mjs +0 -71
  549. package/esm2022/lib/form-validators/validators-function/regex-validation.function.mjs +0 -33
  550. package/esm2022/lib/forms/components/datepicker/datepicker-header.component.mjs +0 -84
  551. package/esm2022/lib/forms/components/generic-form/generic-form.component.mjs +0 -602
  552. package/esm2022/lib/forms/constants/constants.mjs +0 -4
  553. package/esm2022/lib/forms/directives/mat-form-field-editor.directive.mjs +0 -197
  554. package/esm2022/lib/forms/directives/mat-form-field-readonly.directive.mjs +0 -34
  555. package/esm2022/lib/forms/directives/parse-decimal-directive.mjs +0 -87
  556. package/esm2022/lib/forms/directives/vd-generic-form-custom-field.directive.mjs +0 -35
  557. package/esm2022/lib/forms/enums/form-field-type.mjs +0 -23
  558. package/esm2022/lib/forms/forms.module.mjs +0 -168
  559. package/esm2022/lib/forms/functions/decorators.mjs +0 -136
  560. package/esm2022/lib/forms/functions/functions.mjs +0 -72
  561. package/esm2022/lib/forms/helpers/abstract-mat-form-field.mjs +0 -308
  562. package/esm2022/lib/forms/helpers/abstract-select-form-field.component.mjs +0 -492
  563. package/esm2022/lib/forms/helpers/value-accessor-base.mjs +0 -146
  564. package/esm2022/lib/forms/models/form-definition.mjs +0 -63
  565. package/esm2022/lib/forms/models/form-field-definition.mjs +0 -468
  566. package/esm2022/lib/forms/models/form-field-group-definition.mjs +0 -55
  567. package/esm2022/lib/forms/pipes/field-func.pipe.mjs +0 -23
  568. package/esm2022/lib/forms/pipes/group-filter.pipe.mjs +0 -34
  569. package/esm2022/lib/forms/public_api.mjs +0 -5
  570. package/esm2022/lib/forms/validators/empty-string-reset.directive.mjs +0 -25
  571. package/esm2022/lib/forms/validators/equal-validator.directive.mjs +0 -69
  572. package/esm2022/lib/forms/validators/native-element-injector.directive.mjs +0 -41
  573. package/esm2022/lib/forms/validators/unique-validator-directive.mjs +0 -88
  574. package/esm2022/lib/http/http.module.mjs +0 -15
  575. package/esm2022/lib/http/models/response.mjs +0 -24
  576. package/esm2022/lib/http/public_api.mjs +0 -2
  577. package/esm2022/lib/http/services/generic.service.mjs +0 -331
  578. package/esm2022/lib/layout/dynamic-menu/dynamic-menu.component.mjs +0 -103
  579. package/esm2022/lib/layout/layout-card-over/layout-card-over.component.mjs +0 -49
  580. package/esm2022/lib/layout/layout-compact/layout-compact.component.mjs +0 -193
  581. package/esm2022/lib/layout/layout-footer/layout-footer.component.mjs +0 -37
  582. package/esm2022/lib/layout/layout-manage-list/layout-manage-list.component.mjs +0 -150
  583. package/esm2022/lib/layout/layout-manage-list/layout-manage-list.directives.mjs +0 -108
  584. package/esm2022/lib/layout/layout-nav/layout-nav.component.mjs +0 -146
  585. package/esm2022/lib/layout/layout-nav-list/layout-nav-list.component.mjs +0 -141
  586. package/esm2022/lib/layout/layout-nav-list/layout-nav-list.directives.mjs +0 -105
  587. package/esm2022/lib/layout/layout-toggle.class.mjs +0 -89
  588. package/esm2022/lib/layout/layout.component.mjs +0 -230
  589. package/esm2022/lib/layout/layout.directives.mjs +0 -81
  590. package/esm2022/lib/layout/layout.module.mjs +0 -144
  591. package/esm2022/lib/layout/list-toolbar/list-toolbar.component.mjs +0 -47
  592. package/esm2022/lib/layout/navigation-drawer/navigation-drawer.component.mjs +0 -275
  593. package/esm2022/lib/layout/public_api.mjs +0 -2
  594. package/esm2022/lib/list/components/list.component.mjs +0 -78
  595. package/esm2022/lib/list/directives/vd-list-option.directive.mjs +0 -23
  596. package/esm2022/lib/list/list.module.mjs +0 -36
  597. package/esm2022/lib/list/public_api.mjs +0 -3
  598. package/esm2022/lib/media/directives/media-toggle.directive.mjs +0 -154
  599. package/esm2022/lib/media/media.module.mjs +0 -35
  600. package/esm2022/lib/media/public_api.mjs +0 -2
  601. package/esm2022/lib/media/services/media.service.mjs +0 -110
  602. package/esm2022/lib/menu/components/menu.component.mjs +0 -95
  603. package/esm2022/lib/menu/enums/menu-scope.mjs +0 -6
  604. package/esm2022/lib/menu/menu.module.mjs +0 -64
  605. package/esm2022/lib/menu/models/menu-client.mjs +0 -39
  606. package/esm2022/lib/menu/models/menu-department.mjs +0 -39
  607. package/esm2022/lib/menu/models/menu-item-client.mjs +0 -39
  608. package/esm2022/lib/menu/models/menu-item-department.mjs +0 -39
  609. package/esm2022/lib/menu/models/menu-item.mjs +0 -351
  610. package/esm2022/lib/menu/models/menu-settings.mjs +0 -13
  611. package/esm2022/lib/menu/models/menu.mjs +0 -224
  612. package/esm2022/lib/menu/public_api.mjs +0 -3
  613. package/esm2022/lib/menu/resolvers/menu-form-includes.resolve.mjs +0 -50
  614. package/esm2022/lib/menu/resolvers/menu-item-form-includes.resolve.mjs +0 -50
  615. package/esm2022/lib/menu/resolvers/menu-list-projection.resolve.mjs +0 -51
  616. package/esm2022/lib/menu/resolvers/menu-settings.resolve.mjs +0 -24
  617. package/esm2022/lib/menu/services/menu-items.service.mjs +0 -19
  618. package/esm2022/lib/menu/services/menu.resolve.mjs +0 -68
  619. package/esm2022/lib/menu/services/menu.service.mjs +0 -19
  620. package/esm2022/lib/search/public_api.mjs +0 -2
  621. package/esm2022/lib/search/search.module.mjs +0 -33
  622. package/esm2022/lib/select/components/select.component.mjs +0 -215
  623. package/esm2022/lib/select/directives/vd-select-option.directive.mjs +0 -23
  624. package/esm2022/lib/select/directives/vd-select-trigger.directive.mjs +0 -23
  625. package/esm2022/lib/select/public_api.mjs +0 -4
  626. package/esm2022/lib/select/select.module.mjs +0 -48
  627. package/esm2022/lib/table/components/dynamic-table/dynamic-table.component.mjs +0 -810
  628. package/esm2022/lib/table/components/filter-clear/filter-clear.component.mjs +0 -36
  629. package/esm2022/lib/table/components/filter-date/filter-date.component.mjs +0 -146
  630. package/esm2022/lib/table/components/filter-input/filter-input.component.mjs +0 -198
  631. package/esm2022/lib/table/components/filter-select/filter-select.component.mjs +0 -375
  632. package/esm2022/lib/table/constants/constants.mjs +0 -3
  633. package/esm2022/lib/table/directives/data-source-filter.directive.mjs +0 -49
  634. package/esm2022/lib/table/directives/vd-table-field.directive.mjs +0 -35
  635. package/esm2022/lib/table/enums/grid.mjs +0 -12
  636. package/esm2022/lib/table/enums/table-column-type.mjs +0 -17
  637. package/esm2022/lib/table/functions/decorators.mjs +0 -163
  638. package/esm2022/lib/table/functions/functions.mjs +0 -28
  639. package/esm2022/lib/table/models/facet-value.mjs +0 -47
  640. package/esm2022/lib/table/models/facet.mjs +0 -48
  641. package/esm2022/lib/table/models/pagination.mjs +0 -27
  642. package/esm2022/lib/table/models/table-column-config.mjs +0 -128
  643. package/esm2022/lib/table/models/table-column.mjs +0 -270
  644. package/esm2022/lib/table/models/table-config.mjs +0 -41
  645. package/esm2022/lib/table/models/table-definition.mjs +0 -110
  646. package/esm2022/lib/table/models/table-query-config.mjs +0 -26
  647. package/esm2022/lib/table/paginator-intl.mjs +0 -41
  648. package/esm2022/lib/table/public_api.mjs +0 -2
  649. package/esm2022/lib/table/table.data-source.mjs +0 -326
  650. package/esm2022/lib/table/table.module.mjs +0 -165
  651. package/esm2022/lib/table/table.static-data-source.mjs +0 -198
  652. package/esm2022/messaia-cdk.mjs +0 -5
  653. package/esm2022/public_api.mjs +0 -19
  654. package/lib/common/styles/_elevation.scss +0 -147
  655. package/lib/common/styles/_rtl.scss +0 -28
  656. package/lib/common/styles/_styles.scss +0 -12
  657. package/lib/common/styles/_theme-functions.scss +0 -4
  658. package/lib/common/styles/_typography.scss +0 -76
  659. package/lib/common/styles/core/_content.scss +0 -42
  660. package/lib/common/styles/core/_divider.scss +0 -14
  661. package/lib/common/styles/core/_icons.scss +0 -27
  662. package/lib/common/styles/core/_list.scss +0 -8
  663. package/lib/common/styles/core/_toolbar.scss +0 -31
  664. package/lib/common/styles/core/_whiteframe.scss +0 -111
  665. package/lib/common/styles/m2/_theme-functions.scss +0 -21
  666. package/lib/common/styles/m3/_theme-functions.scss +0 -21
  667. package/lib/common/styles/platform.scss +0 -11
  668. package/lib/common/theming/_all-theme.scss +0 -27
  669. package/lib/common/typography/_all-typography.scss +0 -33
@@ -1,1035 +0,0 @@
1
- import { Injectable } from "@angular/core";
2
- import { FormArray, FormBuilder, FormControl, FormGroup } from "@angular/forms";
3
- import { Utils } from "../../common/functions/utils";
4
- import { ARRAY_PROPERTY, BOOLEAN, FUNCTION_STRING, MODEL, NUMBER, OBJECT_PROPERTY, OBJECT_STRING, PROPERTY, RX_WEB_VALIDATOR, STRING } from "../const";
5
- import { APP_VALIDATORS } from '../const/app-validators.const';
6
- import { AnnotationTypes } from "../core/annotation-types";
7
- import { defaultContainer } from '../core/default-container';
8
- import { FormBuilderConfiguration } from "../models";
9
- import { andValidator } from '../reactive-form-validators/and.validator';
10
- import { conditionalChangeValidator } from "../reactive-form-validators/conditional-change.validator";
11
- import { notValidator } from '../reactive-form-validators/not.validator';
12
- import { orValidator } from '../reactive-form-validators/or.validator';
13
- import { Linq } from '../util/linq';
14
- import { ReactiveFormConfig } from '../util/reactive-form-config';
15
- import { RegexValidator } from "../util/regex-validator";
16
- import { BaseFormBuilder } from './base-form-builder';
17
- import { RxFormControl } from './form-control';
18
- import { RxFormArray } from './rx-form-array';
19
- import { RxFormGroup } from './rx-form-group';
20
- import * as i0 from "@angular/core";
21
- const LOGICAL_VALIDATORS = { and: andValidator, or: orValidator, not: notValidator };
22
- const ASYNC = "async";
23
- const ENTITY_OBJECT = "entityObject";
24
- export class RxFormBuilder extends BaseFormBuilder {
25
- /**
26
- * Private field: Array to store conditional object properties
27
- */
28
- conditionalObjectProps = [];
29
- /**
30
- * Private field: Object to store conditional validation instances
31
- */
32
- conditionalValidationInstance = {};
33
- /**
34
- * Private field: Array to store builder configuration conditional object properties
35
- */
36
- builderConfigurationConditionalObjectProps = [];
37
- /**
38
- * Private field: Object to store form group properties other validators
39
- */
40
- formGroupPropOtherValidator = {};
41
- /**
42
- * Private field: Object to store current form group properties other validators
43
- */
44
- currentFormGroupPropOtherValidator = {};
45
- /**
46
- * Private field: Flag to indicate if the form is nested
47
- */
48
- isNested = false;
49
- /**
50
- * Private field: Flag to indicate if the form group is called
51
- */
52
- isGroupCalled = false;
53
- /**
54
- * Private field: Flag to indicate if the form is nested binding
55
- */
56
- isNestedBinding = false;
57
- /**
58
- * Private method: Gets the instance container based on the instance function and entity object.
59
- *
60
- * @param instanceFunc The function to provide an instance from.
61
- * @param entityObject The entity object to use.
62
- * @returns The provided instance container.
63
- */
64
- getInstanceContainer(instanceFunc, entityObject) {
65
- return this.instaceProvider(instanceFunc, entityObject);
66
- }
67
- /**
68
- * Private method: Extracts expressions from the form builder configuration for dynamic validation.
69
- *
70
- * @param formBuilderConfiguration The configuration for the form builder.
71
- * @returns An object containing extracted expressions or null.
72
- */
73
- extractExpressions(formBuilderConfiguration) {
74
- /*
75
- * Extracts expressions from the form builder configuration for dynamic validation.
76
- * If dynamic validation is configured in the formBuilderConfiguration, iterate through each property and decorator.
77
- */
78
- if (formBuilderConfiguration && formBuilderConfiguration.dynamicValidation) {
79
- for (var property in formBuilderConfiguration.dynamicValidation) {
80
- for (var decorator in formBuilderConfiguration.dynamicValidation[property]) {
81
- /* Checks if a conditional expression exists for the current decorator */
82
- if (formBuilderConfiguration.dynamicValidation[property][decorator].conditionalExpression) {
83
- /* Extract columns from the conditional expression */
84
- let columns = Linq.expressionColumns(formBuilderConfiguration.dynamicValidation[property][decorator].conditionalExpression);
85
- /* Add change validation based on the extracted column */
86
- defaultContainer.addChangeValidation(this.conditionalValidationInstance, property, columns);
87
- }
88
- }
89
- }
90
- }
91
- return null;
92
- }
93
- /**
94
- * Adds async validation to the property based on provided validators and configuration.
95
- *
96
- * @param property The property information.
97
- * @param propertyValidators The array of decorator configurations for the property.
98
- * @param propValidationConfig The configuration for property validation.
99
- * @returns An array of async validators.
100
- */
101
- addAsyncValidation(property, propertyValidators, propValidationConfig) {
102
- /* Collects async validators from property validators and validation configuration */
103
- let asyncValidators = [];
104
- if (propertyValidators) {
105
- /* Iterate through property validators */
106
- for (let propertyValidator of propertyValidators) {
107
- /* Check if the validator is async */
108
- if (propertyValidator.isAsync) {
109
- /* Push each async validator into the asyncValidators array */
110
- propertyValidator.config.forEach((t) => { asyncValidators.push(t); });
111
- }
112
- }
113
- }
114
- if (propValidationConfig && propValidationConfig[ASYNC]) {
115
- /* Add async validators from propValidationConfig */
116
- propValidationConfig[ASYNC].forEach((t) => { asyncValidators.push(t); });
117
- }
118
- return asyncValidators;
119
- }
120
- /**
121
- * Adds form control validators based on property validators and validation configuration.
122
- *
123
- * @param property The property information.
124
- * @param propertyValidators The array of decorator configurations for the property.
125
- * @param propValidationConfig The configuration for property validation.
126
- * @param instance The instance container.
127
- * @param entity The entity object.
128
- * @returns An array of form control validators.
129
- */
130
- addFormControl(property, propertyValidators, propValidationConfig, instance, entity) {
131
- let validators = [];
132
- let columns = [];
133
- /* Check if conditional validation props are defined either in instance or conditionalValidationInstance */
134
- if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name]) || (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name])) {
135
- /* Collects conditional validation properties from instance and conditionalValidationInstance and adds conditional change validator */
136
- let props = [];
137
- /* Check if conditionalValidationProps are defined in instance for the property */
138
- if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name])) {
139
- instance.conditionalValidationProps[property.name].forEach(t => props.push(t));
140
- }
141
- /* Check if conditionalValidationProps are defined in conditionalValidationInstance for the property */
142
- if (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name]) {
143
- this.conditionalValidationInstance.conditionalValidationProps[property.name].forEach((t) => props.push(t));
144
- }
145
- /* Add conditional change validator */
146
- validators.push(conditionalChangeValidator(props));
147
- }
148
- /* Check if conditionalObjectProps or builderConfigurationConditionalObjectProps are defined */
149
- if (this.conditionalObjectProps.length > 0 || this.builderConfigurationConditionalObjectProps.length > 0) {
150
- let propConditions = [];
151
- /* Check if conditionalObjectProps is defined */
152
- if (this.conditionalObjectProps) {
153
- /* Filter conditionalObjectProps for properties matching the current property name */
154
- propConditions = this.conditionalObjectProps.filter(t => t.propName == property.name);
155
- }
156
- /* Check if builderConfigurationConditionalObjectProps is defined */
157
- if (this.builderConfigurationConditionalObjectProps) {
158
- /* Filter builderConfigurationConditionalObjectProps for properties matching the current property name */
159
- this.builderConfigurationConditionalObjectProps.filter(t => t.propName == property.name).forEach(t => propConditions.push(t));
160
- }
161
- propConditions.forEach(t => {
162
- /* Add reference property name to columns array */
163
- if (t.referencePropName && columns.indexOf(t.referencePropName) == -1) {
164
- columns.push(t.referencePropName);
165
- }
166
- });
167
- /* Add conditional change validator */
168
- if (columns.length > 0) {
169
- validators.push(conditionalChangeValidator(columns));
170
- }
171
- }
172
- /* Iterate through property validators */
173
- for (let propertyValidator of propertyValidators) {
174
- if (!propertyValidator.isAsync) {
175
- switch (propertyValidator.annotationType) {
176
- /* Add rule validator */
177
- case AnnotationTypes.rule:
178
- validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config, entity));
179
- break;
180
- /* Add logical validator */
181
- case AnnotationTypes.and:
182
- case AnnotationTypes.or:
183
- case AnnotationTypes.not:
184
- validators.push(LOGICAL_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
185
- break;
186
- /* Add custom validator */
187
- default:
188
- validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
189
- break;
190
- }
191
- }
192
- }
193
- /* Additional validation from propValidationConfig */
194
- if (propValidationConfig) {
195
- this.additionalValidation(validators, propValidationConfig);
196
- }
197
- /* Additional validation from currentFormGroupPropOtherValidator */
198
- if (this.currentFormGroupPropOtherValidator[property.name]) {
199
- this.currentFormGroupPropOtherValidator[property.name].forEach((t) => { validators.push(t); });
200
- }
201
- return validators;
202
- }
203
- /**
204
- * Adds additional validation to the validations array based on propValidationConfig.
205
- *
206
- * @param validations An array of existing validations.
207
- * @param propValidationConfig The configuration for property validation.
208
- */
209
- additionalValidation(validations, propValidationConfig) {
210
- for (var col in AnnotationTypes) {
211
- /* Check if the validation configuration for the current annotation type exists and it's not a custom validator */
212
- if (propValidationConfig[AnnotationTypes[col]] && col != "custom") {
213
- /* Add validator from APP_VALIDATORS */
214
- validations.push(APP_VALIDATORS[AnnotationTypes[col]](propValidationConfig[AnnotationTypes[col]]));
215
- }
216
- /* Check if the current annotation type is custom and the custom validator exists in the validation configuration */
217
- else if (col == AnnotationTypes.custom && propValidationConfig[AnnotationTypes[col]]) {
218
- /* Add custom validator */
219
- validations.push(propValidationConfig[col]);
220
- }
221
- }
222
- }
223
- /**
224
- * Retrieves the entity type based on the provided object and property information.
225
- *
226
- * @param object The object for which the entity type is retrieved.
227
- * @param formBuilderConfiguration The configuration for the form builder.
228
- * @param propertyName The name of the property.
229
- * @param isSameObjectConstructor Indicates if the entity type is the same as the object's constructor.
230
- * @returns The entity type.
231
- */
232
- getEntity(object, formBuilderConfiguration, propertyName, isSameObjectConstructor = false) {
233
- /* Check if the entity type is defined in the form builder configuration */
234
- if (formBuilderConfiguration && formBuilderConfiguration.genericEntities && formBuilderConfiguration.genericEntities[propertyName]) {
235
- /* Return the entity type from formBuilderConfiguration if available */
236
- return formBuilderConfiguration.genericEntities[propertyName];
237
- }
238
- /* Return the object's constructor if isSameObjectConstructor is true */
239
- return isSameObjectConstructor ? object.constructor : undefined;
240
- }
241
- /**
242
- * Retrieves the constructor of the object property instance based on the provided object and property information.
243
- *
244
- * @param object The object containing the property.
245
- * @param propertyInfo Information about the property.
246
- * @param formBuilderConfiguration The configuration for the form builder.
247
- * @returns The constructor of the object property instance.
248
- */
249
- getObjectPropertyInstance(object, propertyInfo, formBuilderConfiguration) {
250
- /* Check if the property type is OBJECT_PROPERTY and the property exists in the object */
251
- if (propertyInfo.propertyType == OBJECT_PROPERTY && object[propertyInfo.name]) {
252
- /* Return the constructor of the object property if it exists */
253
- return object[propertyInfo.name].constructor;
254
- }
255
- /* Check if the property type is ARRAY_PROPERTY and the property exists and contains items in the object */
256
- else if (propertyInfo.propertyType == ARRAY_PROPERTY && object[propertyInfo.name] && object[propertyInfo.name].length > 0) {
257
- /* Return the constructor of the first item in the array property if it exists */
258
- return object[propertyInfo.name][0].constructor;
259
- }
260
- /* Return the entity type based on the object and property information */
261
- return this.getEntity(object, formBuilderConfiguration, propertyInfo.name);
262
- }
263
- /**
264
- * Checks for additional validation configurations for object properties in the instance container.
265
- *
266
- * @param instanceContainer The container for the instance.
267
- * @param object The object to check for additional validation configurations.
268
- * @param formBuilderConfiguration The configuration for the form builder.
269
- */
270
- checkObjectPropAdditionalValidation(instanceContainer, object, formBuilderConfiguration) {
271
- /* Filter properties of type OBJECT_PROPERTY or ARRAY_PROPERTY */
272
- var props = instanceContainer.properties?.filter(t => t.propertyType == OBJECT_PROPERTY || t.propertyType == ARRAY_PROPERTY);
273
- /* Iterate through the filtered properties */
274
- props?.forEach(t => {
275
- let entity = t.entity;
276
- /* If entity type is not defined in the property, retrieve it from the object */
277
- if (!t.entity)
278
- entity = this.getObjectPropertyInstance(object, t, formBuilderConfiguration);
279
- if (entity) {
280
- let instance = this.getInstanceContainer(entity, null);
281
- /* Check if instance exists and has conditional validation properties */
282
- if (instance && instance.conditionalValidationProps) {
283
- for (var key in instance.conditionalValidationProps) {
284
- var prop = instanceContainer.properties?.filter(t => t.name == key)[0];
285
- if (prop) {
286
- /* Initialize conditional validation properties in instance container if not already initialized */
287
- if (!instanceContainer.conditionalValidationProps)
288
- instanceContainer.conditionalValidationProps = {};
289
- if (!instanceContainer.conditionalValidationProps[key])
290
- instanceContainer.conditionalValidationProps[key] = [];
291
- /* Add conditional validation properties */
292
- instance.conditionalValidationProps[key].forEach(x => {
293
- if (t.propertyType != ARRAY_PROPERTY) {
294
- instanceContainer.conditionalValidationProps[key].push([t.name, x].join('.'));
295
- }
296
- else {
297
- instanceContainer.conditionalValidationProps[key].push([t.name, x].join('[]'));
298
- }
299
- });
300
- }
301
- }
302
- }
303
- }
304
- });
305
- }
306
- /**
307
- * Constructs an object containing model, entityObject, and formBuilderConfiguration based on the provided parameters.
308
- *
309
- * @param model The model to be used for object construction.
310
- * @param entityObject The entity object to be used.
311
- * @param formBuilderConfiguration The configuration for the form builder.
312
- * @returns An object containing model, entityObject, and formBuilderConfiguration.
313
- */
314
- getObject(model, entityObject, formBuilderConfiguration) {
315
- /* Initializes an empty object to store the JSON representation */
316
- let json = {};
317
- /* Checks if the model is a function */
318
- if (typeof model == FUNCTION_STRING) {
319
- json.model = model;
320
- }
321
- /* Checks if the model is a function and entityObject is an instance of FormBuilderConfiguration */
322
- if (typeof model == FUNCTION_STRING && (entityObject instanceof FormBuilderConfiguration)) {
323
- /* Creates the entity object using createClassObject method */
324
- json.entityObject = this.createClassObject(json.model, entityObject);
325
- }
326
- /* Checks if entityObject exists and is not an instance of FormBuilderConfiguration */
327
- if (entityObject && !(entityObject instanceof FormBuilderConfiguration)) {
328
- json.entityObject = entityObject;
329
- }
330
- /* Checks if entityObject is an instance of FormBuilderConfiguration and formBuilderConfiguration is not provided */
331
- if (entityObject instanceof FormBuilderConfiguration && !formBuilderConfiguration) {
332
- json.formBuilderConfiguration = entityObject;
333
- }
334
- /* Checks if entityObject is not an instance of FormBuilderConfiguration and formBuilderConfiguration is provided */
335
- else if (!(entityObject instanceof FormBuilderConfiguration) && formBuilderConfiguration) {
336
- /* Sets the formBuilderConfiguration in the JSON */
337
- json.formBuilderConfiguration = formBuilderConfiguration;
338
- /* Creates the entity object using createClassObject method */
339
- json.entityObject = this.createClassObject(json.model, json.formBuilderConfiguration, json.entityObject);
340
- }
341
- /* If entityObject does not exist */
342
- if (!entityObject) {
343
- /* Checks if the model is an object */
344
- if (typeof model == OBJECT_STRING) {
345
- /* Stores the constructor of the model */
346
- json.model = model.constructor;
347
- }
348
- /* Creates the entity object using createClassObject method */
349
- json.entityObject = this.createClassObject(json.model, json.formBuilderConfiguration, model);
350
- }
351
- /* If entityObject exists and is an instance of FormBuilderConfiguration and model is an object */
352
- else if (model && (entityObject instanceof FormBuilderConfiguration) && (typeof model == OBJECT_STRING)) {
353
- /* Stores the constructor of the model */
354
- json[MODEL] = model.constructor;
355
- /* Creates the entity object using createClassObject method */
356
- json[ENTITY_OBJECT] = this.createClassObject(json.model, json.formBuilderConfiguration, model);
357
- }
358
- /* Returns the constructed JSON object */
359
- return json;
360
- }
361
- /**
362
- * Creates a form control with the specified value and validators.
363
- *
364
- * @param value The value for the form control.
365
- * @param validators An array of synchronous validators.
366
- * @param asyncValidators An array of asynchronous validators.
367
- * @returns An instance of IAbstractControl.
368
- */
369
- control(value, validators, asyncValidators) {
370
- return new RxFormControl(value, { validators: validators, asyncValidators: asyncValidators }, {}, {}, '', []);
371
- }
372
- /**
373
- * Creates a form array with the specified values and validator configuration.
374
- *
375
- * @param values An array of objects to initialize the form array.
376
- * @param validatorConfig The configuration for validators.
377
- * @returns An instance of FormArray.
378
- */
379
- array(values, validatorConfig) {
380
- /* Creates a FormGroup instance with a single control named "temp" and assigns it to formArray */
381
- let formArray = this.group({ temp: values }, validatorConfig).get("temp");
382
- /* Instantiates a new instance of the FormBuilder */
383
- var formBuilder = new FormBuilder();
384
- /* Creates a FormArray instance using the controls of the FormGroup */
385
- return formBuilder.array(formArray.controls);
386
- }
387
- /**
388
- * Creates a form group with the specified group object and validator configuration.
389
- *
390
- * @param groupObject An object representing the group.
391
- * @param validatorConfig The configuration for validators.
392
- * @returns An instance of FormGroup.
393
- */
394
- group(groupObject, validatorConfig) {
395
- /* Create a new instance of the model */
396
- let modelInstance = super.createInstance();
397
- /* Initialize an empty object for the entity */
398
- let entityObject = {};
399
- /* Initialize an empty object for formGroupPropOtherValidator */
400
- this.formGroupPropOtherValidator = {};
401
- /* Set currentFormGroupPropOtherValidator to formGroupPropOtherValidator */
402
- this.currentFormGroupPropOtherValidator = this.formGroupPropOtherValidator;
403
- /* Create the validator form group */
404
- this.createValidatorFormGroup(groupObject, entityObject, modelInstance, validatorConfig);
405
- /* Set currentFormGroupPropOtherValidator back to formGroupPropOtherValidator */
406
- this.currentFormGroupPropOtherValidator = this.formGroupPropOtherValidator;
407
- /* Flag that a group is being called */
408
- this.isGroupCalled = true;
409
- /* Create the form group */
410
- let formGroup = this.formGroup(modelInstance.constructor, entityObject, validatorConfig);
411
- /* Reset isGroupCalled flag */
412
- this.isGroupCalled = false;
413
- /* Reset formGroupPropOtherValidator */
414
- this.formGroupPropOtherValidator = {};
415
- /* Reset currentFormGroupPropOtherValidator */
416
- this.currentFormGroupPropOtherValidator = this.formGroupPropOtherValidator;
417
- /* Reset formGroupPropOtherValidator */
418
- this.formGroupPropOtherValidator = {};
419
- /* Return the created form group */
420
- return formGroup;
421
- }
422
- /**
423
- * Apply all property validators specified in the validator configuration to a given property.
424
- *
425
- * @param propName The name of the property to which validators are applied.
426
- * @param validatorConfig The configuration for property validation.
427
- * @param modelInstance The instance of the model.
428
- */
429
- applyAllPropValidator(propName, validatorConfig, modelInstance) {
430
- /* Check if the validator configuration and applyAllProps array exist */
431
- if (validatorConfig && validatorConfig.applyAllProps) {
432
- /* Check if the excludeProps array exists and if the propName is not in the excludeProps array */
433
- if (!(validatorConfig.excludeProps && validatorConfig.excludeProps.length > 0 && validatorConfig.excludeProps.indexOf(propName) == -1)) {
434
- /* Iterate through each item in the applyAllProps array */
435
- validatorConfig.applyAllProps.forEach((t) => {
436
- /* Check if the validator function is an RxWeb validator */
437
- if (t.name == RX_WEB_VALIDATOR) {
438
- /* Apply RxWeb validator to the propName with the modelInstance */
439
- t(propName, modelInstance);
440
- }
441
- else {
442
- /* Check if the currentFormGroupPropOtherValidator has an entry for the propName */
443
- if (!this.currentFormGroupPropOtherValidator[propName]) {
444
- /* If not, create an empty array for the propName */
445
- this.currentFormGroupPropOtherValidator[propName] = [];
446
- }
447
- /* Push the custom validator to the currentFormGroupPropOtherValidator array */
448
- this.currentFormGroupPropOtherValidator[propName].push(t);
449
- }
450
- });
451
- }
452
- }
453
- }
454
- /**
455
- * Checks if dynamic validation should be applied to a property.
456
- *
457
- * @param propName The name of the property to check.
458
- * @param validatorConfig The configuration for property validation.
459
- * @returns A boolean indicating whether dynamic validation should be applied to the property.
460
- */
461
- dynamicValidationPropCheck(propName, validatorConfig) {
462
- return (validatorConfig == undefined) ? true : (!validatorConfig.dynamicValidationConfigurationPropertyName) ? true : validatorConfig.dynamicValidationConfigurationPropertyName == propName ? false : true;
463
- }
464
- /**
465
- * Checks if the given value is not an object.
466
- *
467
- * @param value The value to check.
468
- * @returns A boolean indicating whether the value is not an object.
469
- */
470
- isNotObject(value) {
471
- return value instanceof Date || value === null || typeof value != OBJECT_STRING;
472
- }
473
- /**
474
- * Creates a validator form group based on the groupObject and applies validation rules.
475
- *
476
- * @param groupObject The object containing the properties to create the form group.
477
- * @param entityObject The entity object to store the form group.
478
- * @param modelInstance The model instance used for initialization.
479
- * @param validatorConfig The configuration for property validation.
480
- */
481
- createValidatorFormGroup(groupObject, entityObject, modelInstance, validatorConfig) {
482
- /* Iterates over each property in the groupObject to create form controls and apply validators. */
483
- for (var propName in groupObject) {
484
- var prop = groupObject[propName];
485
- /* Check if the property is an array and needs validation */
486
- if (prop instanceof Array && prop.length > 0 && this.isNotObject(prop[0])) {
487
- let propValidators = (prop.length > 1 && prop[1] instanceof Array) ? prop[1] : (prop.length == 2) ? [prop[1]] : [];
488
- let propertyAdded = false;
489
- /* Iterate over each validator for the current property */
490
- for (var i = 0; i < propValidators.length; i++) {
491
- if (propValidators[i].name == RX_WEB_VALIDATOR) {
492
- propValidators[i](propName, modelInstance);
493
- propertyAdded = true;
494
- }
495
- else {
496
- /* Add other validators to the currentFormGroupPropOtherValidator */
497
- if (!this.currentFormGroupPropOtherValidator[propName]) {
498
- this.currentFormGroupPropOtherValidator[propName] = [];
499
- }
500
- this.currentFormGroupPropOtherValidator[propName].push(propValidators[i]);
501
- }
502
- }
503
- /* If no property validator added, initialize the property object */
504
- if (!propertyAdded) {
505
- defaultContainer.initPropertyObject(propName, PROPERTY, undefined, typeof modelInstance == OBJECT_STRING ? modelInstance : { constructor: modelInstance });
506
- }
507
- /* Apply all property validators */
508
- this.applyAllPropValidator(propName, validatorConfig, modelInstance);
509
- }
510
- else if (prop === null || prop === undefined || typeof prop == STRING || typeof prop == NUMBER || typeof prop == BOOLEAN || prop instanceof Date) {
511
- /* Initialize the property object if it's a simple type */
512
- defaultContainer.initPropertyObject(propName, PROPERTY, undefined, typeof modelInstance == OBJECT_STRING ? modelInstance : { constructor: modelInstance });
513
- /* Apply all property validators */
514
- this.applyAllPropValidator(propName, validatorConfig, modelInstance);
515
- }
516
- else if (prop instanceof Array) {
517
- if (prop instanceof FormArray) {
518
- /* If the property is a FormArray, assign it directly */
519
- entityObject[propName] = prop;
520
- }
521
- else {
522
- /* If it's an array of objects, create form controls recursively */
523
- let propModelInstance = super.createInstance();
524
- if (typeof modelInstance == "function") {
525
- modelInstance.constructor = modelInstance;
526
- }
527
- /* Initialize the property as an array */
528
- defaultContainer.initPropertyObject(propName, ARRAY_PROPERTY, propModelInstance.constructor, modelInstance);
529
- /* Initialize an empty array for the property */
530
- entityObject[propName] = [];
531
- /* Iterate through each element of the array */
532
- for (let row of prop) {
533
- /* Create a new object for each element */
534
- let jObject = {};
535
- /* Push the new object into the array */
536
- entityObject[propName].push(jObject);
537
- /* Recursively create validator form groups for each object */
538
- this.createValidatorFormGroup(row, jObject, propModelInstance.constructor, validatorConfig);
539
- }
540
- }
541
- }
542
- else if (typeof prop == OBJECT_STRING && !(prop instanceof FormControl || prop instanceof RxFormControl)) {
543
- /* Determine the formGroup based on the type of 'prop' */
544
- let formGroup = (prop instanceof FormArray) ? prop.controls[0] : prop;
545
- /* If 'prop' is a FormGroup or RxFormGroup and does not have a model, create a form group */
546
- if (!formGroup.model && (prop instanceof FormGroup || prop instanceof RxFormGroup)) {
547
- formGroup = this.group(formGroup.controls);
548
- }
549
- /* If 'prop' is a FormGroup or RxFormGroup, initialize the property as an object */
550
- if (prop instanceof FormGroup || prop instanceof RxFormGroup) {
551
- entityObject[propName] = prop;
552
- defaultContainer.initPropertyObject(propName, OBJECT_PROPERTY, formGroup.model, modelInstance);
553
- }
554
- /* If 'prop' is a FormArray, initialize the property as an array */
555
- else if (prop instanceof FormArray) {
556
- entityObject[propName] = prop;
557
- defaultContainer.initPropertyObject(propName, ARRAY_PROPERTY, formGroup.model, modelInstance);
558
- }
559
- /* If 'prop' is neither a FormGroup/RxFormGroup nor a FormArray */
560
- else {
561
- /* Check if dynamic validation is required for the property */
562
- if (this.dynamicValidationPropCheck(propName, validatorConfig)) {
563
- /* Initialize property for dynamic validation */
564
- this.formGroupPropOtherValidator[propName] = {};
565
- /* Set the currentFormGroupPropOtherValidator to the current property */
566
- this.currentFormGroupPropOtherValidator = this.formGroupPropOtherValidator[propName];
567
- /* Create a new instance for the property model */
568
- let propModelInstance = super.createInstance();
569
- /* Initialize the property object */
570
- entityObject[propName] = {};
571
- entityObject[propName].constructor = propModelInstance.constructor;
572
- defaultContainer.initPropertyObject(propName, OBJECT_PROPERTY, entityObject[propName].constructor, modelInstance.constructor == Function ? { constructor: modelInstance } : modelInstance);
573
- /* Get the validation configuration for the property */
574
- let objectValidationConfig = this.getValidatorConfig(validatorConfig, groupObject, propName + ".");
575
- /* Recursively create the validator form group for the property */
576
- this.createValidatorFormGroup(groupObject[propName], entityObject[propName], entityObject[propName].constructor, objectValidationConfig);
577
- }
578
- else {
579
- /* Initialize property without dynamic validation */
580
- entityObject[propName] = groupObject[propName];
581
- }
582
- }
583
- }
584
- /* Assign property value if it's of simple type */
585
- if (typeof prop == STRING || typeof prop == NUMBER || typeof prop == BOOLEAN || prop instanceof Date) {
586
- entityObject[propName] = prop;
587
- }
588
- /* Assign property value if it's an array or object */
589
- else if ((prop && prop.length > 0 && this.isNotObject(prop[0]) && !(prop instanceof FormControl || prop instanceof RxFormControl) && !(prop instanceof FormArray))) {
590
- entityObject[propName] = prop[0];
591
- }
592
- /* Assign property value if it's a FormArray */
593
- else if (prop instanceof FormArray) {
594
- entityObject[propName] = prop;
595
- }
596
- /* Assign property value if it's a FormControl */
597
- else if (prop instanceof FormControl || prop instanceof RxFormControl) {
598
- entityObject[propName] = prop;
599
- defaultContainer.initPropertyObject(propName, PROPERTY, undefined, modelInstance.constructor ? modelInstance : { constructor: modelInstance });
600
- }
601
- }
602
- }
603
- /**
604
- * Retrieves the validator configuration for a given entity object and root property name.
605
- *
606
- * @param validatorConfig The validator configuration to process.
607
- * @param entityObject The entity object for which the validator configuration is applied.
608
- * @param rootPropertyName The root property name to consider.
609
- * @param arrayPropertyName Optional. The array property name to consider.
610
- * @returns An object containing the processed validator configuration.
611
- */
612
- getValidatorConfig(validatorConfig, entityObject, rootPropertyName, arrayPropertyName) {
613
- let excludeProps = [];
614
- let includeProps = [];
615
- let ignoreUndefinedProps = [];
616
- /* Check if the validatorConfig exists */
617
- if (!validatorConfig)
618
- return {};
619
- /* Retrieve validation properties and abstract control options */
620
- const validationProps = this.getObjectForProperty(validatorConfig.dynamicValidation, rootPropertyName, arrayPropertyName);
621
- const abstractControlOptions = this.getObjectForProperty(validatorConfig.abstractControlOptions, rootPropertyName, arrayPropertyName);
622
- /* Populate excludeProps, includeProps, and ignoreUndefinedProps arrays */
623
- if (validatorConfig.excludeProps) {
624
- excludeProps = this.getProps(validatorConfig.excludeProps, rootPropertyName);
625
- }
626
- if (validatorConfig.includeProps) {
627
- includeProps = this.getProps(validatorConfig.includeProps, rootPropertyName);
628
- }
629
- if (validatorConfig.ignoreUndefinedProps) {
630
- ignoreUndefinedProps = this.getProps(validatorConfig.ignoreUndefinedProps, rootPropertyName, true);
631
- }
632
- /* Append global abstract control options if not found */
633
- if (!Object.keys(abstractControlOptions).length && rootPropertyName.endsWith('.') && validatorConfig.abstractControlOptions && validatorConfig.abstractControlOptions[rootPropertyName.substring(0, rootPropertyName.length - 1)]) {
634
- abstractControlOptions['global'] = validatorConfig.abstractControlOptions[rootPropertyName.substring(0, rootPropertyName.length - 1)];
635
- }
636
- /* Retrieve dynamic validation configuration */
637
- const dynamicValidation = (validatorConfig.dynamicValidationConfigurationPropertyName && entityObject[validatorConfig.dynamicValidationConfigurationPropertyName]) ? entityObject[validatorConfig.dynamicValidationConfigurationPropertyName] : validationProps;
638
- /* Return processed validator configuration */
639
- return {
640
- ignoreUndefinedProps: ignoreUndefinedProps,
641
- includeProps: includeProps,
642
- dynamicValidation: dynamicValidation,
643
- excludeProps: excludeProps,
644
- abstractControlOptions: abstractControlOptions
645
- };
646
- }
647
- /**
648
- * Retrieves the object properties matching the specified root property name and array property name (if provided).
649
- *
650
- * @param rootObject The root object to search for properties.
651
- * @param rootPropertyName The root property name to match against.
652
- * @param arrayPropertyName Optional. The array property name to match against.
653
- * @returns An object containing the properties matching the root property name and array property name (if provided).
654
- */
655
- getObjectForProperty(rootObject, rootPropertyName, arrayPropertyName) {
656
- const result = {};
657
- /* Iterate through the properties of the root object */
658
- for (let propName in rootObject) {
659
- /* Skip properties that do not match the rootPropertyName or arrayPropertyName */
660
- if (!propName.startsWith(rootPropertyName) && (!arrayPropertyName || !propName.startsWith(arrayPropertyName))) {
661
- continue;
662
- }
663
- /* Extract the split property name */
664
- let splitProp = propName.split(".", 2)[1];
665
- /* If splitProp is undefined, continue to the next property */
666
- if (!splitProp) {
667
- continue;
668
- }
669
- /* Add the property to the result object */
670
- result[splitProp] = rootObject[propName];
671
- }
672
- return result;
673
- }
674
- /**
675
- * Retrieves the properties matching the specified root property name from the given array of properties.
676
- *
677
- * @param properties The array of properties to search.
678
- * @param rootPropertyName The root property name to match against.
679
- * @param isIgnoreProp Optional. Indicates whether to include the root property itself as a property.
680
- * @returns An array containing the properties matching the root property name.
681
- */
682
- getProps(properties, rootPropertyName, isIgnoreProp = false) {
683
- let props = [];
684
- /* Iterate through the properties */
685
- for (let prop of properties) {
686
- /* Check if the property contains the rootPropertyName */
687
- if (prop.indexOf(rootPropertyName) != -1) {
688
- let splitProps = prop.split(".");
689
- /* If the property has two parts, add the second part to the props array */
690
- if (splitProps.length == 2) {
691
- props.push(splitProps[1]);
692
- }
693
- /* If the property has more than two parts, join the parts after the first one and add to the props array */
694
- else if (splitProps.length > 2) {
695
- splitProps.splice(0, 1);
696
- props.push(splitProps.join("."));
697
- }
698
- }
699
- }
700
- /* If isIgnoreProp is true and the root property itself is present in the properties array, add ':self:' to the props array */
701
- if (isIgnoreProp && properties.filter(x => x == rootPropertyName.replace('.', '')).length == 1) {
702
- props.push(':self:');
703
- }
704
- return props;
705
- }
706
- /**
707
- * Creates a form group based on the provided model, entity object, and form builder configuration.
708
- *
709
- * @param model The model or type definition to create the form group from.
710
- * @param entityObject Optional. The entity object for which the form group is created.
711
- * @param formBuilderConfiguration Optional. The form builder configuration to customize the form group creation.
712
- * @returns An instance of RxFormGroup, FormGroup, or AppFormGroup<T>.
713
- */
714
- formGroup(model, entityObject, formBuilderConfiguration) {
715
- /* Retrieves necessary data from the provided model, entity object, and form builder configuration to create a form group */
716
- let json = this.getObject(model, entityObject, formBuilderConfiguration);
717
- model = json.model;
718
- entityObject = json.entityObject;
719
- /*
720
- * If the entity object's constructor differs from the model's constructor and formGroup is not previously called,
721
- * update the entity object to match the model.
722
- */
723
- if (entityObject.constructor != model && !this.isGroupCalled) {
724
- entityObject = json.entityObject = this.updateObject(model, json.entityObject, formBuilderConfiguration);
725
- }
726
- formBuilderConfiguration = json.formBuilderConfiguration;
727
- /* Extract expressions from the form builder configuration if provided. */
728
- if (formBuilderConfiguration) {
729
- this.extractExpressions(formBuilderConfiguration);
730
- }
731
- /* Get the container for instances based on the model and entity object. */
732
- let instanceContainer = this.getInstanceContainer(model, entityObject);
733
- /* Check and apply additional validation for object properties. */
734
- this.checkObjectPropAdditionalValidation(instanceContainer, entityObject, formBuilderConfiguration);
735
- /* Initialize variables for form group creation. */
736
- let formGroupObject = {};
737
- let extendedProperties = {};
738
- var additionalValidations = {};
739
- /* Iterate through properties defined in the instance container. */
740
- instanceContainer.properties?.forEach(property => {
741
- let isIncludeProp = true;
742
- /* Check if the property should be included based on form builder configuration. */
743
- if (formBuilderConfiguration) {
744
- /* Check if the property should be excluded based on form builder configuration. */
745
- if (formBuilderConfiguration.excludeProps && formBuilderConfiguration.excludeProps.length > 0) {
746
- isIncludeProp = formBuilderConfiguration.excludeProps.indexOf(property.name) == -1;
747
- }
748
- /* Check if dynamic validation is provided in the form builder configuration. */
749
- if (formBuilderConfiguration.dynamicValidation) {
750
- additionalValidations = formBuilderConfiguration.dynamicValidation;
751
- }
752
- /* Check if the property should be included based on form builder configuration. */
753
- if (formBuilderConfiguration.includeProps && formBuilderConfiguration.includeProps.length > 0) {
754
- isIncludeProp = formBuilderConfiguration.includeProps.indexOf(property.name) != -1;
755
- }
756
- /* Check if undefined properties should be ignored based on form builder configuration. */
757
- if (formBuilderConfiguration.ignoreUndefinedProps && formBuilderConfiguration.ignoreUndefinedProps.length > 0) {
758
- isIncludeProp = !(property.propertyType == PROPERTY &&
759
- !RegexValidator.isNotBlank(json.entityObject[property.name]) &&
760
- (formBuilderConfiguration.ignoreUndefinedProps.indexOf(property.name) !== -1 ||
761
- formBuilderConfiguration.ignoreUndefinedProps.indexOf(":self:") !== -1));
762
- }
763
- }
764
- if (property.ignore) {
765
- isIncludeProp = !property.ignore.call(json.entityObject, json.entityObject);
766
- }
767
- /* If the property should be included, create form controls, form groups, or form arrays based on its type. */
768
- if (isIncludeProp) {
769
- switch (property.propertyType) {
770
- case PROPERTY:
771
- /* If the property is not already a form control, create one with appropriate validators and options */
772
- if (!(entityObject[property.name] instanceof FormControl || entityObject[property.name] instanceof RxFormControl)) {
773
- /* Extract property validators based on annotations. */
774
- let propertyValidators = instanceContainer.propertyAnnotations.filter(t => t.propertyName == property.name && t.isValidator);
775
- /* Extract updateOn configuration based on annotations. */
776
- let updateOn = instanceContainer.propertyAnnotations.filter(t => t.propertyName == property.name && !t.isValidator && t.annotationType === "updateOn")[0];
777
- /* Retrieve the value from entityObject based on valuePath or property name, or use the custom value function if provided */
778
- let value = property.value
779
- ? property.value(entityObject)
780
- : (property.valuePath
781
- ? Utils.getPropertyValue(entityObject, property.valuePath)
782
- : entityObject[property.name]);
783
- /* Sanitize the property value. */
784
- let sanitizeValue = super.sanitizeValue(instanceContainer, property.name, super.getDefaultValue(property, value, formBuilderConfiguration), json.entityObject, Object.assign({}, json.entityObject));
785
- /* If the property value is undefined and there is a sanitized value, assign it. */
786
- if (entityObject[property.name] === undefined && sanitizeValue) {
787
- entityObject[property.name] = sanitizeValue;
788
- }
789
- /* Add form control validators. */
790
- let validators = this.addFormControl(property, propertyValidators, additionalValidations[property.name], instanceContainer, entityObject);
791
- /* Define abstract control options including validators and async validators. */
792
- let abstractControlOptions = { validators: validators, asyncValidators: this.addAsyncValidation(property, propertyValidators, additionalValidations[property.name]) };
793
- /* Retrieve additional abstract control options based on property name. */
794
- abstractControlOptions = this.getAbstractControlOptions(property.name, formBuilderConfiguration, abstractControlOptions);
795
- /* Assign updateOn configuration if available. */
796
- if (updateOn && !abstractControlOptions.updateOn) {
797
- abstractControlOptions.updateOn = updateOn.config.runOn;
798
- }
799
- /* Create a new form control instance. */
800
- formGroupObject[property.name] = new RxFormControl(sanitizeValue, abstractControlOptions, json.entityObject, Object.assign({}, json.entityObject), property.name, instanceContainer.sanitizers[property.name]);
801
- this.isNested = false;
802
- }
803
- else {
804
- /* If the property is already a form control, use its default value. */
805
- formGroupObject[property.name] = super.getDefaultValue(property, entityObject[property.name], formBuilderConfiguration);
806
- }
807
- /* Mark the property as extended */
808
- extendedProperties[property.name] = true;
809
- break;
810
- case OBJECT_PROPERTY:
811
- let objectValue = entityObject[property.name];
812
- /* If the property is an object and not a form group, recursively create a form group for it */
813
- if (objectValue && objectValue instanceof Object && !(objectValue instanceof FormGroup || objectValue instanceof RxFormGroup)) {
814
- /* Set flags to indicate nested binding. */
815
- this.isNestedBinding = this.isNested = true;
816
- /* Filter conditional object properties based on the current property name. */
817
- if (instanceContainer && instanceContainer.conditionalObjectProps) {
818
- this.conditionalObjectProps = instanceContainer.conditionalObjectProps.filter((t) => t.objectPropName == property.name);
819
- }
820
- /* Filter conditional object properties for builder configuration based on the current property name. */
821
- if (this.conditionalValidationInstance && this.conditionalValidationInstance.conditionalObjectProps) {
822
- this.builderConfigurationConditionalObjectProps = this.conditionalValidationInstance.conditionalObjectProps.filter((t) => t.objectPropName == property.name);
823
- }
824
- /* Set the current form group other validator if available. */
825
- if (this.formGroupPropOtherValidator[property.name]) {
826
- this.currentFormGroupPropOtherValidator = this.formGroupPropOtherValidator[property.name];
827
- }
828
- /* Obtain validation configuration for the nested object. */
829
- let objectValidationConfig = this.getValidatorConfig(formBuilderConfiguration, objectValue, `${property.name}.`);
830
- /* Obtain the entity to use for the nested object. */
831
- let entity = property.entityProvider ? property.entityProvider.call(entityObject) : undefined;
832
- /* Create a form group for the nested object. */
833
- formGroupObject[property.name] = this.formGroup(entity || property.entity || this.getEntity(objectValue, formBuilderConfiguration, property.name, true), objectValue, objectValidationConfig);
834
- /* Reset flags to indicate the end of nested binding. */
835
- this.conditionalObjectProps = [];
836
- this.builderConfigurationConditionalObjectProps = [];
837
- this.isNestedBinding = this.isNested = false;
838
- }
839
- /* If the property is already a form group, use it as is */
840
- else if (objectValue instanceof FormGroup || objectValue instanceof RxFormGroup) {
841
- formGroupObject[property.name] = objectValue;
842
- }
843
- break;
844
- case ARRAY_PROPERTY:
845
- let arrayObjectValue = entityObject[property.name];
846
- /* If the property is an array and not a form array, recursively create a form array for it */
847
- if (arrayObjectValue && arrayObjectValue instanceof Array && !(arrayObjectValue instanceof FormArray)) {
848
- /* Set flags to indicate nested binding. */
849
- this.isNestedBinding = this.isNested = true;
850
- /* Initialize an array to hold form groups for each sub-object in the array. */
851
- var formArrayGroup = [];
852
- let index = 0;
853
- let entity = property.entityProvider ? property.entityProvider.call(entityObject) : undefined;
854
- let objectValidationConfig = null;
855
- /* Iterate over each sub-object in the array. */
856
- for (let subObject of arrayObjectValue) {
857
- /* Filter conditional object properties based on the current property name and array index. */
858
- if (instanceContainer && instanceContainer.conditionalObjectProps) {
859
- this.conditionalObjectProps = instanceContainer.conditionalObjectProps.filter((t) => t.objectPropName == property.name && t.arrayIndex == index);
860
- }
861
- if (this.conditionalValidationInstance && this.conditionalValidationInstance.conditionalObjectProps) {
862
- this.builderConfigurationConditionalObjectProps = this.conditionalValidationInstance.conditionalObjectProps.filter((t) => t.objectPropName == property.name && t.arrayIndex == index);
863
- }
864
- /* Set the current form group other validator if available. */
865
- if (this.formGroupPropOtherValidator[property.name]) {
866
- this.currentFormGroupPropOtherValidator = this.formGroupPropOtherValidator[property.name];
867
- }
868
- /* Obtain validation configuration for the sub-object. */
869
- objectValidationConfig = this.getValidatorConfig(formBuilderConfiguration, subObject, `${property.name}.`, `${property.name}[${index}].`);
870
- /* Create a form group for the sub-object and add it to the formArrayGroup array. */
871
- formArrayGroup.push(this.formGroup(entity || property.entity || this.getEntity(subObject, formBuilderConfiguration, property.name, true), subObject, objectValidationConfig));
872
- /* Increment the index. */
873
- index++;
874
- /* Reset conditional object properties and builder configuration conditional object properties. */
875
- this.conditionalObjectProps = [];
876
- this.builderConfigurationConditionalObjectProps = [];
877
- }
878
- /* Obtain abstract control options for the property. */
879
- let abstractControlOptions = this.getAbstractControlOptions(property.name, formBuilderConfiguration, {});
880
- /* Create a new RxFormArray using the arrayObjectValue and the formArrayGroup, along with the abstract control options. */
881
- formGroupObject[property.name] = new RxFormArray(arrayObjectValue, formArrayGroup, abstractControlOptions, null, property.arrayConfig);
882
- /* If autoInstancePush is enabled, override the push and splice methods of the arrayObjectValue to manage form groups dynamically. */
883
- if (ReactiveFormConfig.autoInstancePush) {
884
- arrayObjectValue.push = (instance) => {
885
- let formGroup = this.formGroup(instance.constructor, instance, objectValidationConfig);
886
- formGroupObject[property.name].push(formGroup, { isAddedInstance: true });
887
- return 0;
888
- };
889
- arrayObjectValue.splice = (start, deleteCount) => {
890
- let end = (start + deleteCount) - 1;
891
- for (var i = start; i <= end; i++) {
892
- formGroupObject[property.name].removeAt(i, { isRemovedInstance: true });
893
- }
894
- return [];
895
- };
896
- }
897
- /* Reset flags to indicate the end of nested binding. */
898
- this.isNestedBinding = this.isNested = false;
899
- }
900
- /* If the property is already a form array, use it as is */
901
- else if (arrayObjectValue instanceof FormArray) {
902
- formGroupObject[property.name] = arrayObjectValue;
903
- }
904
- /* If the property configuration specifies creating a blank form array, create one */
905
- else if (property.arrayConfig && property.arrayConfig.createBlank) {
906
- formGroupObject[property.name] = new RxFormArray([], [], null, null, property.arrayConfig);
907
- }
908
- break;
909
- }
910
- }
911
- });
912
- /* If no nested form groups or arrays are created, reset conditional validation instance and related properties. */
913
- if (!this.isNested) {
914
- this.conditionalValidationInstance = {};
915
- this.builderConfigurationConditionalObjectProps = [];
916
- }
917
- /* Set abstract control options for the form group based on form builder configuration. */
918
- let abstractControlOptions = {
919
- validators: [],
920
- asyncValidators: [],
921
- updateOn: formBuilderConfiguration && formBuilderConfiguration.abstractControlOptions && formBuilderConfiguration.abstractControlOptions['global']
922
- ? formBuilderConfiguration.abstractControlOptions['global']
923
- : undefined
924
- };
925
- /* Obtain abstract control options for the global property. */
926
- abstractControlOptions = this.getAbstractControlOptions("global", formBuilderConfiguration, abstractControlOptions);
927
- /* Create a new RxFormGroup using the model, entity object, formGroupObject, and abstract control options. */
928
- var formGroup = new RxFormGroup(json.model, json.entityObject, formGroupObject, abstractControlOptions);
929
- /* If experimental mode is enabled, assign the form group to the entity object and override properties if needed. */
930
- if (defaultContainer.isExperimental) {
931
- json.entityObject["formGroup"] = formGroup;
932
- this.overrideProperties(formGroup, json.entityObject, extendedProperties);
933
- }
934
- /* If not in nested binding mode and formGroup is not previously called, refresh disable status of the form group. */
935
- if (!this.isNestedBinding && !this.isGroupCalled) {
936
- formGroup.refreshDisable();
937
- }
938
- return formGroup;
939
- }
940
- /**
941
- * Overrides properties in the form group based on the provided entity object and properties.
942
- * @param formGroup The RxFormGroup instance to override properties.
943
- * @param entityObject The entity object containing the properties to override.
944
- * @param properties An object containing the properties to override as keys.
945
- */
946
- overrideProperties(formGroup, entityObject, properties) {
947
- Object.keys(properties).forEach(t => this.overrideProp(entityObject, t, formGroup));
948
- }
949
- /**
950
- * Retrieves the abstract control options for a given control name.
951
- *
952
- * @param name The name of the control.
953
- * @param formBuilderConfiguration The FormBuilderConfiguration containing the abstract control options.
954
- * @param abstractControlOptions The existing AbstractControlOptions.
955
- * @returns The updated AbstractControlOptions based on the provided configuration.
956
- */
957
- getAbstractControlOptions(name, formBuilderConfiguration, abstractControlOptions) {
958
- /* Update updateOn option if defined in formBuilderConfiguration */
959
- if (formBuilderConfiguration && formBuilderConfiguration.abstractControlOptions && formBuilderConfiguration.abstractControlOptions[name]) {
960
- abstractControlOptions.updateOn = formBuilderConfiguration.abstractControlOptions[name];
961
- }
962
- /* Check if controlOptions are defined in formBuilderConfiguration */
963
- const controlOptions = formBuilderConfiguration ? formBuilderConfiguration.baseAbstractControlOptions : null;
964
- if (controlOptions && controlOptions[name]) {
965
- /* Update updateOn option from controlOptions if defined */
966
- if (controlOptions[name].updateOn) {
967
- abstractControlOptions.updateOn = controlOptions[name].updateOn;
968
- }
969
- /* Add validators from controlOptions if defined */
970
- if (controlOptions[name].validators) {
971
- if (Array.isArray(controlOptions[name].validators)) {
972
- controlOptions[name].validators
973
- .forEach(validator => abstractControlOptions.validators.push(validator));
974
- }
975
- else {
976
- abstractControlOptions.validators
977
- .push(controlOptions[name].validators);
978
- }
979
- }
980
- /* Add async validators from controlOptions if defined */
981
- if (controlOptions[name].asyncValidators) {
982
- if (Array.isArray(controlOptions[name].asyncValidators)) {
983
- controlOptions[name].asyncValidators
984
- .forEach(validator => abstractControlOptions.asyncValidators.push(validator));
985
- }
986
- else {
987
- abstractControlOptions.asyncValidators
988
- .push(controlOptions[name].validators);
989
- }
990
- }
991
- }
992
- return abstractControlOptions;
993
- }
994
- /**
995
- * Overrides a property on the entity object with custom getters and setters.
996
- *
997
- * @param entityObject The entity object whose property needs to be overridden.
998
- * @param propName The name of the property to be overridden.
999
- * @param formGroup The RxFormGroup associated with the entity object.
1000
- */
1001
- overrideProp(entityObject, propName, formGroup) {
1002
- /* Get the property descriptor and current value */
1003
- let descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(entityObject), propName);
1004
- let value = entityObject[propName];
1005
- let oldValue = null;
1006
- /* Define the property with custom getters and setters */
1007
- Object.defineProperty(entityObject, propName, {
1008
- /* Custom getter */
1009
- get: () => { return descriptor ? descriptor.get.call(entityObject) : value; },
1010
- /* Custom setter */
1011
- set: (v) => {
1012
- value = v;
1013
- /* Check if value has changed */
1014
- if (oldValue != v) {
1015
- /* Call the original setter if defined */
1016
- if (descriptor) {
1017
- descriptor.set.call(entityObject, v);
1018
- }
1019
- /* Update the corresponding control in the form group */
1020
- if (!formGroup.changing && formGroup.controls[propName]) {
1021
- formGroup.controls[propName].setValue(v);
1022
- }
1023
- }
1024
- /* Update the old value */
1025
- oldValue = v;
1026
- }
1027
- });
1028
- }
1029
- /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: RxFormBuilder, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1030
- /** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: RxFormBuilder });
1031
- }
1032
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: RxFormBuilder, decorators: [{
1033
- type: Injectable
1034
- }] });
1035
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicngtZm9ybS1idWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2RrL3NyYy9saWIvZm9ybS12YWxpZGF0b3JzL3NlcnZpY2VzL3J4LWZvcm0tYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBNEMsU0FBUyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFlLE1BQU0sZ0JBQWdCLENBQUM7QUFFdkksT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN2SixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQU9yRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDekUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFDdEcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUV2RSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFD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QUMsRUFBRSxDQUFDO29CQUNoQix5Q0FBeUM7b0JBQ3pDLElBQUksVUFBVSxFQUFFLENBQUM7d0JBQ2IsVUFBVSxDQUFDLEdBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUMxQyxDQUFDO29CQUNELHdEQUF3RDtvQkFDeEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO3dCQUN0RCxTQUFTLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDN0MsQ0FBQztnQkFDTCxDQUFDO2dCQUNELDBCQUEwQjtnQkFDMUIsUUFBUSxHQUFHLENBQUMsQ0FBQztZQUNqQixDQUFDO1NBQ0osQ0FBQyxDQUFDO0lBQ1AsQ0FBQzswSEEzcENRLGFBQWE7OEhBQWIsYUFBYTs7MkZBQWIsYUFBYTtrQkFEekIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2xPcHRpb25zLCBBc3luY1ZhbGlkYXRvckZuLCBGb3JtQXJyYXksIEZvcm1CdWlsZGVyLCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBWYWxpZGF0b3JGbiB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xyXG5cclxuaW1wb3J0IHsgVXRpbHMgfSBmcm9tIFwiLi4vLi4vY29tbW9uL2Z1bmN0aW9ucy91dGlsc1wiO1xyXG5pbXBvcnQgeyBBUlJBWV9QUk9QRVJUWSwgQk9PTEVBTiwgRlVOQ1RJT05fU1RSSU5HLCBNT0RFTCwgTlVNQkVSLCBPQkpFQ1RfUFJPUEVSVFksIE9CSkVDVF9TVFJJTkcsIFBST1BFUlRZLCBSWF9XRUJfVkFMSURBVE9SLCBTVFJJTkcgfSBmcm9tIFwiLi4vY29uc3RcIjtcclxuaW1wb3J0IHsgQVBQX1ZBTElEQVRPUlMgfSBmcm9tICcuLi9jb25zdC9hcHAtdmFsaWRhdG9ycy5jb25zdCc7XHJcbmltcG9ydCB7IEFubm90YXRpb25UeXBlcyB9IGZyb20gXCIuLi9jb3JlL2Fubm90YXRpb24tdHlwZXNcIjtcclxuaW1wb3J0IHsgZGVmYXVsdENvbnRhaW5lciB9IGZyb20gJy4uL2NvcmUvZGVmYXVsdC1jb250YWluZXInO1xyXG5pbXBvcnQgeyBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gfSBmcm9tIFwiLi4vbW9kZWxzXCI7XHJcbmltcG9ydCB7IERlY29yYXRvckNvbmZpZ3VyYXRpb24gfSBmcm9tIFwiLi4vbW9kZWxzL2RlY29yYXRvci1jb25maWd1cmF0aW9uXCI7XHJcbmltcG9ydCB7IEluc3RhbmNlQ29udGFpbmVyIH0gZnJvbSBcIi4uL21vZGVscy9pbnN0YW5jZS1jb250YWluZXJcIjtcclxuaW1wb3J0IHsgSUFic3RyYWN0Q29udHJvbCB9IGZyb20gXCIuLi9tb2RlbHMvaW50ZXJmYWNlL2ktYWJzdHJhY3QtY29udHJvbFwiO1xyXG5pbXBvcnQgeyBBcHBGb3JtR3JvdXAgfSBmcm9tICcuLi9tb2RlbHMvaW50ZXJmYWNlL2ktZm9ybS1ncm91cCc7XHJcbmltcG9ydCB7IFByb3BWYWxpZGF0aW9uQ29uZmlnIH0gZnJvbSBcIi4uL21vZGVscy9wcm9wLXZhbGlkYXRpb24tY29uZmlnXCI7XHJcbmltcG9ydCB7IFByb3BlcnR5SW5mbyB9IGZyb20gXCIuLi9tb2RlbHMvcHJvcGVydHktaW5mb1wiO1xyXG5pbXBvcnQgeyBhbmRWYWxpZGF0b3IgfSBmcm9tICcuLi9yZWFjdGl2ZS1mb3JtLXZhbGlkYXRvcnMvYW5kLnZhbGlkYXRvcic7XHJcbmltcG9ydCB7IGNvbmRpdGlvbmFsQ2hhbmdlVmFsaWRhdG9yIH0gZnJvbSBcIi4uL3JlYWN0aXZlLWZvcm0tdmFsaWRhdG9ycy9jb25kaXRpb25hbC1jaGFuZ2UudmFsaWRhdG9yXCI7XHJcbmltcG9ydCB7IG5vdFZhbGlkYXRvciB9IGZyb20gJy4uL3JlYWN0aXZlLWZvcm0tdmFsaWRhdG9ycy9ub3QudmFsaWRhdG9yJztcclxuaW1wb3J0IHsgb3JWYWxpZGF0b3IgfSBmcm9tICcuLi9yZWFjdGl2ZS1mb3JtLXZhbGlkYXRvcnMvb3IudmFsaWRhdG9yJztcclxuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCIuLi91dGlsXCI7XHJcbmltcG9ydCB7IExpbnEgfSBmcm9tICcuLi91dGlsL2xpbnEnO1xyXG5pbXBvcnQgeyBSZWFjdGl2ZUZvcm1Db25maWcgfSBmcm9tICcuLi91dGlsL3JlYWN0aXZlLWZvcm0tY29uZmlnJztcclxuaW1wb3J0IHsgUmVnZXhWYWxpZGF0b3IgfSBmcm9tIFwiLi4vdXRpbC9yZWdleC12YWxpZGF0b3JcIjtcclxuaW1wb3J0IHsgQmFzZUZvcm1CdWlsZGVyIH0gZnJvbSAnLi9iYXNlLWZvcm0tYnVpbGRlcic7XHJcbmltcG9ydCB7IFJ4Rm9ybUNvbnRyb2wgfSBmcm9tICcuL2Zvcm0tY29udHJvbCc7XHJcbmltcG9ydCB7IFJ4Rm9ybUFycmF5IH0gZnJvbSAnLi9yeC1mb3JtLWFycmF5JztcclxuaW1wb3J0IHsgUnhGb3JtR3JvdXAgfSBmcm9tICcuL3J4LWZvcm0tZ3JvdXAnO1xyXG5cclxuY29uc3QgTE9HSUNBTF9WQUxJREFUT1JTOiB7IFtrZXk6IHN0cmluZ106IEZ1bmN0aW9uIH0gPSB7IGFuZDogYW5kVmFsaWRhdG9yLCBvcjogb3JWYWxpZGF0b3IsIG5vdDogbm90VmFsaWRhdG9yIH1cclxuY29uc3QgQVNZTkM6IHN0cmluZyA9IFwiYXN5bmNcIlxyXG5jb25zdCBFTlRJVFlfT0JKRUNUOiBzdHJpbmcgPSBcImVudGl0eU9iamVjdFwiO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgUnhGb3JtQnVpbGRlciBleHRlbmRzIEJhc2VGb3JtQnVpbGRlciB7XHJcbiAgICAvKipcclxuICAgICAqIFByaXZhdGUgZmllbGQ6IEFycmF5IHRvIHN0b3JlIGNvbmRpdGlvbmFsIG9iamVjdCBwcm9wZXJ0aWVzXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgY29uZGl0aW9uYWxPYmplY3RQcm9wczogYW55W10gPSBbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByaXZhdGUgZmllbGQ6IE9iamVjdCB0byBzdG9yZSBjb25kaXRpb25hbCB2YWxpZGF0aW9uIGluc3RhbmNlc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlOiBhbnkgPSB7fTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByaXZhdGUgZmllbGQ6IEFycmF5IHRvIHN0b3JlIGJ1aWxkZXIgY29uZmlndXJhdGlvbiBjb25kaXRpb25hbCBvYmplY3QgcHJvcGVydGllc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wczogYW55W10gPSBbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByaXZhdGUgZmllbGQ6IE9iamVjdCB0byBzdG9yZSBmb3JtIGdyb3VwIHByb3BlcnRpZXMgb3RoZXIgdmFsaWRhdG9yc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvcjogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJpdmF0ZSBmaWVsZDogT2JqZWN0IHRvIHN0b3JlIGN1cnJlbnQgZm9ybSBncm91cCBwcm9wZXJ0aWVzIG90aGVyIHZhbGlkYXRvcnNcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBjdXJyZW50Rm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcml2YXRlIGZpZWxkOiBGbGFnIHRvIGluZGljYXRlIGlmIHRoZSBmb3JtIGlzIG5lc3RlZFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzTmVzdGVkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcml2YXRlIGZpZWxkOiBGbGFnIHRvIGluZGljYXRlIGlmIHRoZSBmb3JtIGdyb3VwIGlzIGNhbGxlZFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzR3JvdXBDYWxsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByaXZhdGUgZmllbGQ6IEZsYWcgdG8gaW5kaWNhdGUgaWYgdGhlIGZvcm0gaXMgbmVzdGVkIGJpbmRpbmdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpc05lc3RlZEJpbmRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByaXZhdGUgbWV0aG9kOiBHZXRzIHRoZSBpbnN0YW5jZSBjb250YWluZXIgYmFzZWQgb24gdGhlIGluc3RhbmNlIGZ1bmN0aW9uIGFuZCBlbnRpdHkgb2JqZWN0LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gaW5zdGFuY2VGdW5jIFRoZSBmdW5jdGlvbiB0byBwcm92aWRlIGFuIGluc3RhbmNlIGZyb20uXHJcbiAgICAgKiBAcGFyYW0gZW50aXR5T2JqZWN0IFRoZSBlbnRpdHkgb2JqZWN0IHRvIHVzZS5cclxuICAgICAqIEByZXR1cm5zIFRoZSBwcm92aWRlZCBpbnN0YW5jZSBjb250YWluZXIuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0SW5zdGFuY2VDb250YWluZXIoaW5zdGFuY2VGdW5jOiBhbnksIGVudGl0eU9iamVjdDogYW55KTogSW5zdGFuY2VDb250YWluZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmluc3RhY2VQcm92aWRlcihpbnN0YW5jZUZ1bmMsIGVudGl0eU9iamVjdCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcml2YXRlIG1ldGhvZDogRXh0cmFjdHMgZXhwcmVzc2lvbnMgZnJvbSB0aGUgZm9ybSBidWlsZGVyIGNvbmZpZ3VyYXRpb24gZm9yIGR5bmFtaWMgdmFsaWRhdGlvbi5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIGZvcm0gYnVpbGRlci5cclxuICAgICAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIGV4dHJhY3RlZCBleHByZXNzaW9ucyBvciBudWxsLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV4dHJhY3RFeHByZXNzaW9ucyhmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb246IEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbik6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSB8IG51bGwge1xyXG4gICAgICAgIC8qIFxyXG4gICAgICAgICAqIEV4dHJhY3RzIGV4cHJlc3Npb25zIGZyb20gdGhlIGZvcm0gYnVpbGRlciBjb25maWd1cmF0aW9uIGZvciBkeW5hbWljIHZhbGlkYXRpb24uXHJcbiAgICAgICAgICogSWYgZHluYW1pYyB2YWxpZGF0aW9uIGlzIGNvbmZpZ3VyZWQgaW4gdGhlIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiwgaXRlcmF0ZSB0aHJvdWdoIGVhY2ggcHJvcGVydHkgYW5kIGRlY29yYXRvci5cclxuICAgICAgICAgKi9cclxuICAgICAgICBpZiAoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uICYmIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5keW5hbWljVmFsaWRhdGlvbikge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uZHluYW1pY1ZhbGlkYXRpb24pIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGRlY29yYXRvciBpbiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uZHluYW1pY1ZhbGlkYXRpb25bcHJvcGVydHldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLyogQ2hlY2tzIGlmIGEgY29uZGl0aW9uYWwgZXhwcmVzc2lvbiBleGlzdHMgZm9yIHRoZSBjdXJyZW50IGRlY29yYXRvciAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmR5bmFtaWNWYWxpZGF0aW9uIGFzIGFueSlbcHJvcGVydHldW2RlY29yYXRvcl0uY29uZGl0aW9uYWxFeHByZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEV4dHJhY3QgY29sdW1ucyBmcm9tIHRoZSBjb25kaXRpb25hbCBleHByZXNzaW9uICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb2x1bW5zID0gTGlucS5leHByZXNzaW9uQ29sdW1ucygoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmR5bmFtaWNWYWxpZGF0aW9uIGFzIGFueSlbcHJvcGVydHldW2RlY29yYXRvcl0uY29uZGl0aW9uYWxFeHByZXNzaW9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEFkZCBjaGFuZ2UgdmFsaWRhdGlvbiBiYXNlZCBvbiB0aGUgZXh0cmFjdGVkIGNvbHVtbiAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Q29udGFpbmVyLmFkZENoYW5nZVZhbGlkYXRpb24odGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZSwgcHJvcGVydHksIGNvbHVtbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFxyXG4gICAgICogQWRkcyBhc3luYyB2YWxpZGF0aW9uIHRvIHRoZSBwcm9wZXJ0eSBiYXNlZCBvbiBwcm92aWRlZCB2YWxpZGF0b3JzIGFuZCBjb25maWd1cmF0aW9uLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gcHJvcGVydHkgVGhlIHByb3BlcnR5IGluZm9ybWF0aW9uLlxyXG4gICAgICogQHBhcmFtIHByb3BlcnR5VmFsaWRhdG9ycyBUaGUgYXJyYXkgb2YgZGVjb3JhdG9yIGNvbmZpZ3VyYXRpb25zIGZvciB0aGUgcHJvcGVydHkuXHJcbiAgICAgKiBAcGFyYW0gcHJvcFZhbGlkYXRpb25Db25maWcgVGhlIGNvbmZpZ3VyYXRpb24gZm9yIHByb3BlcnR5IHZhbGlkYXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBhc3luYyB2YWxpZGF0b3JzLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFkZEFzeW5jVmFsaWRhdGlvbihwcm9wZXJ0eTogUHJvcGVydHlJbmZvLCBwcm9wZXJ0eVZhbGlkYXRvcnM6IERlY29yYXRvckNvbmZpZ3VyYXRpb25bXSwgcHJvcFZhbGlkYXRpb25Db25maWc6IFByb3BWYWxpZGF0aW9uQ29uZmlnKSB7XHJcbiAgICAgICAgLyogQ29sbGVjdHMgYXN5bmMgdmFsaWRhdG9ycyBmcm9tIHByb3BlcnR5IHZhbGlkYXRvcnMgYW5kIHZhbGlkYXRpb24gY29uZmlndXJhdGlvbiAqL1xyXG4gICAgICAgIGxldCBhc3luY1ZhbGlkYXRvcnM6IGFueVtdID0gW107XHJcbiAgICAgICAgaWYgKHByb3BlcnR5VmFsaWRhdG9ycykge1xyXG4gICAgICAgICAgICAvKiBJdGVyYXRlIHRocm91Z2ggcHJvcGVydHkgdmFsaWRhdG9ycyAqL1xyXG4gICAgICAgICAgICBmb3IgKGxldCBwcm9wZXJ0eVZhbGlkYXRvciBvZiBwcm9wZXJ0eVZhbGlkYXRvcnMpIHtcclxuICAgICAgICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSB2YWxpZGF0b3IgaXMgYXN5bmMgKi9cclxuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0eVZhbGlkYXRvci5pc0FzeW5jKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLyogUHVzaCBlYWNoIGFzeW5jIHZhbGlkYXRvciBpbnRvIHRoZSBhc3luY1ZhbGlkYXRvcnMgYXJyYXkgKi9cclxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eVZhbGlkYXRvci5jb25maWcuZm9yRWFjaCgodDogYW55KSA9PiB7IGFzeW5jVmFsaWRhdG9ycy5wdXNoKHQpIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcFZhbGlkYXRpb25Db25maWcgJiYgKHByb3BWYWxpZGF0aW9uQ29uZmlnIGFzIGFueSlbQVNZTkNdKSB7XHJcbiAgICAgICAgICAgIC8qIEFkZCBhc3luYyB2YWxpZGF0b3JzIGZyb20gcHJvcFZhbGlkYXRpb25Db25maWcgKi9cclxuICAgICAgICAgICAgKHByb3BWYWxpZGF0aW9uQ29uZmlnIGFzIGFueSlbQVNZTkNdLmZvckVhY2goKHQ6IGFueSkgPT4geyBhc3luY1ZhbGlkYXRvcnMucHVzaCh0KSB9KVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFzeW5jVmFsaWRhdG9ycztcclxuICAgIH1cclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBBZGRzIGZvcm0gY29udHJvbCB2YWxpZGF0b3JzIGJhc2VkIG9uIHByb3BlcnR5IHZhbGlkYXRvcnMgYW5kIHZhbGlkYXRpb24gY29uZmlndXJhdGlvbi5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHByb3BlcnR5IFRoZSBwcm9wZXJ0eSBpbmZvcm1hdGlvbi5cclxuICAgICAqIEBwYXJhbSBwcm9wZXJ0eVZhbGlkYXRvcnMgVGhlIGFycmF5IG9mIGRlY29yYXRvciBjb25maWd1cmF0aW9ucyBmb3IgdGhlIHByb3BlcnR5LlxyXG4gICAgICogQHBhcmFtIHByb3BWYWxpZGF0aW9uQ29uZmlnIFRoZSBjb25maWd1cmF0aW9uIGZvciBwcm9wZXJ0eSB2YWxpZGF0aW9uLlxyXG4gICAgICogQHBhcmFtIGluc3RhbmNlIFRoZSBpbnN0YW5jZSBjb250YWluZXIuXHJcbiAgICAgKiBAcGFyYW0gZW50aXR5IFRoZSBlbnRpdHkgb2JqZWN0LlxyXG4gICAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgZm9ybSBjb250cm9sIHZhbGlkYXRvcnMuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYWRkRm9ybUNvbnRyb2wocHJvcGVydHk6IFByb3BlcnR5SW5mbywgcHJvcGVydHlWYWxpZGF0b3JzOiBEZWNvcmF0b3JDb25maWd1cmF0aW9uW10sIHByb3BWYWxpZGF0aW9uQ29uZmlnOiBQcm9wVmFsaWRhdGlvbkNvbmZpZywgaW5zdGFuY2U6IEluc3RhbmNlQ29udGFpbmVyLCBlbnRpdHk6IGFueSkge1xyXG4gICAgICAgIGxldCB2YWxpZGF0b3JzID0gW107XHJcbiAgICAgICAgbGV0IGNvbHVtbnM6IGFueVtdID0gW107XHJcbiAgICAgICAgLyogQ2hlY2sgaWYgY29uZGl0aW9uYWwgdmFsaWRhdGlvbiBwcm9wcyBhcmUgZGVmaW5lZCBlaXRoZXIgaW4gaW5zdGFuY2Ugb3IgY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UgKi9cclxuICAgICAgICBpZiAoKGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzICYmIGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW3Byb3BlcnR5Lm5hbWVdKSB8fCAodGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcyAmJiB0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW3Byb3BlcnR5Lm5hbWVdKSkge1xyXG4gICAgICAgICAgICAvKiBDb2xsZWN0cyBjb25kaXRpb25hbCB2YWxpZGF0aW9uIHByb3BlcnRpZXMgZnJvbSBpbnN0YW5jZSBhbmQgY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UgYW5kIGFkZHMgY29uZGl0aW9uYWwgY2hhbmdlIHZhbGlkYXRvciAqL1xyXG4gICAgICAgICAgICBsZXQgcHJvcHM6IGFueVtdID0gW107XHJcblxyXG4gICAgICAgICAgICAvKiBDaGVjayBpZiBjb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcyBhcmUgZGVmaW5lZCBpbiBpbnN0YW5jZSBmb3IgdGhlIHByb3BlcnR5ICovXHJcbiAgICAgICAgICAgIGlmICgoaW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHMgJiYgaW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHNbcHJvcGVydHkubmFtZV0pKSB7XHJcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1twcm9wZXJ0eS5uYW1lXS5mb3JFYWNoKHQgPT4gcHJvcHMucHVzaCh0KSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qIENoZWNrIGlmIGNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzIGFyZSBkZWZpbmVkIGluIGNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlIGZvciB0aGUgcHJvcGVydHkgKi9cclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHMgJiYgdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1twcm9wZXJ0eS5uYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1twcm9wZXJ0eS5uYW1lXS5mb3JFYWNoKCh0OiBhbnkpID0+IHByb3BzLnB1c2godCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBBZGQgY29uZGl0aW9uYWwgY2hhbmdlIHZhbGlkYXRvciAqL1xyXG4gICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goY29uZGl0aW9uYWxDaGFuZ2VWYWxpZGF0b3IocHJvcHMpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIENoZWNrIGlmIGNvbmRpdGlvbmFsT2JqZWN0UHJvcHMgb3IgYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzIGFyZSBkZWZpbmVkICovXHJcbiAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxPYmplY3RQcm9wcy5sZW5ndGggPiAwIHx8IHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgbGV0IHByb3BDb25kaXRpb25zID0gW107XHJcblxyXG4gICAgICAgICAgICAvKiBDaGVjayBpZiBjb25kaXRpb25hbE9iamVjdFByb3BzIGlzIGRlZmluZWQgKi9cclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxPYmplY3RQcm9wcykge1xyXG4gICAgICAgICAgICAgICAgLyogRmlsdGVyIGNvbmRpdGlvbmFsT2JqZWN0UHJvcHMgZm9yIHByb3BlcnRpZXMgbWF0Y2hpbmcgdGhlIGN1cnJlbnQgcHJvcGVydHkgbmFtZSAqL1xyXG4gICAgICAgICAgICAgICAgcHJvcENvbmRpdGlvbnMgPSB0aGlzLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMuZmlsdGVyKHQgPT4gdC5wcm9wTmFtZSA9PSBwcm9wZXJ0eS5uYW1lKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyogQ2hlY2sgaWYgYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzIGlzIGRlZmluZWQgKi9cclxuICAgICAgICAgICAgaWYgKHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAvKiBGaWx0ZXIgYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzIGZvciBwcm9wZXJ0aWVzIG1hdGNoaW5nIHRoZSBjdXJyZW50IHByb3BlcnR5IG5hbWUgKi9cclxuICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzLmZpbHRlcih0ID0+IHQucHJvcE5hbWUgPT0gcHJvcGVydHkubmFtZSkuZm9yRWFjaCh0ID0+IHByb3BDb25kaXRpb25zLnB1c2godCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBwcm9wQ29uZGl0aW9ucy5mb3JFYWNoKHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgLyogQWRkIHJlZmVyZW5jZSBwcm9wZXJ0eSBuYW1lIHRvIGNvbHVtbnMgYXJyYXkgKi9cclxuICAgICAgICAgICAgICAgIGlmICh0LnJlZmVyZW5jZVByb3BOYW1lICYmIGNvbHVtbnMuaW5kZXhPZih0LnJlZmVyZW5jZVByb3BOYW1lKSA9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbnMucHVzaCh0LnJlZmVyZW5jZVByb3BOYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAvKiBBZGQgY29uZGl0aW9uYWwgY2hhbmdlIHZhbGlkYXRvciAqL1xyXG4gICAgICAgICAgICBpZiAoY29sdW1ucy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goY29uZGl0aW9uYWxDaGFuZ2VWYWxpZGF0b3IoY29sdW1ucykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBJdGVyYXRlIHRocm91Z2ggcHJvcGVydHkgdmFsaWRhdG9ycyAqL1xyXG4gICAgICAgIGZvciAobGV0IHByb3BlcnR5VmFsaWRhdG9yIG9mIHByb3BlcnR5VmFsaWRhdG9ycykge1xyXG4gICAgICAgICAgICBpZiAoIXByb3BlcnR5VmFsaWRhdG9yLmlzQXN5bmMpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAocHJvcGVydHlWYWxpZGF0b3IuYW5ub3RhdGlvblR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvKiBBZGQgcnVsZSB2YWxpZGF0b3IgKi9cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIEFubm90YXRpb25UeXBlcy5ydWxlOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goQVBQX1ZBTElEQVRPUlNbcHJvcGVydHlWYWxpZGF0b3IuYW5ub3RhdGlvblR5cGVdKHByb3BlcnR5VmFsaWRhdG9yLmNvbmZpZywgZW50aXR5KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvKiBBZGQgbG9naWNhbCB2YWxpZGF0b3IgKi9cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIEFubm90YXRpb25UeXBlcy5hbmQ6XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uVHlwZXMub3I6XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uVHlwZXMubm90OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goTE9HSUNBTF9WQUxJREFUT1JTW3Byb3BlcnR5VmFsaWRhdG9yLmFubm90YXRpb25UeXBlXShwcm9wZXJ0eVZhbGlkYXRvci5jb25maWcpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8qIEFkZCBjdXN0b20gdmFsaWRhdG9yICovXHJcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdG9ycy5wdXNoKEFQUF9WQUxJREFUT1JTW3Byb3BlcnR5VmFsaWRhdG9yLmFubm90YXRpb25UeXBlXShwcm9wZXJ0eVZhbGlkYXRvci5jb25maWcpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIEFkZGl0aW9uYWwgdmFsaWRhdGlvbiBmcm9tIHByb3BWYWxpZGF0aW9uQ29uZmlnICovXHJcbiAgICAgICAgaWYgKHByb3BWYWxpZGF0aW9uQ29uZmlnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYWRkaXRpb25hbFZhbGlkYXRpb24odmFsaWRhdG9ycywgcHJvcFZhbGlkYXRpb25Db25maWcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogQWRkaXRpb25hbCB2YWxpZGF0aW9uIGZyb20gY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciAqL1xyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRGb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3JbcHJvcGVydHkubmFtZV0pIHtcclxuICAgICAgICAgICAgdGhpcy5jdXJyZW50Rm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yW3Byb3BlcnR5Lm5hbWVdLmZvckVhY2goKHQ6IGFueSkgPT4geyB2YWxpZGF0b3JzLnB1c2godCk7IH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRvcnM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFxyXG4gICAgICogQWRkcyBhZGRpdGlvbmFsIHZhbGlkYXRpb24gdG8gdGhlIHZhbGlkYXRpb25zIGFycmF5IGJhc2VkIG9uIHByb3BWYWxpZGF0aW9uQ29uZmlnLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gdmFsaWRhdGlvbnMgQW4gYXJyYXkgb2YgZXhpc3RpbmcgdmFsaWRhdGlvbnMuXHJcbiAgICAgKiBAcGFyYW0gcHJvcFZhbGlkYXRpb25Db25maWcgVGhlIGNvbmZpZ3VyYXRpb24gZm9yIHByb3BlcnR5IHZhbGlkYXRpb24uXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYWRkaXRpb25hbFZhbGlkYXRpb24odmFsaWRhdGlvbnM6IGFueVtdLCBwcm9wVmFsaWRhdGlvbkNvbmZpZzogUHJvcFZhbGlkYXRpb25Db25maWcgfCBhbnkpIHtcclxuICAgICAgICBmb3IgKHZhciBjb2wgaW4gQW5ub3RhdGlvblR5cGVzKSB7XHJcbiAgICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSB2YWxpZGF0aW9uIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBjdXJyZW50IGFubm90YXRpb24gdHlwZSBleGlzdHMgYW5kIGl0J3Mgbm90IGEgY3VzdG9tIHZhbGlkYXRvciAqL1xyXG4gICAgICAgICAgICBpZiAocHJvcFZhbGlkYXRpb25Db25maWdbQW5ub3RhdGlvblR5cGVzW2NvbF1dICYmIGNvbCAhPSBcImN1c3RvbVwiKSB7XHJcbiAgICAgICAgICAgICAgICAvKiBBZGQgdmFsaWRhdG9yIGZyb20gQVBQX1ZBTElEQVRPUlMgKi9cclxuICAgICAgICAgICAgICAgIHZhbGlkYXRpb25zLnB1c2goQVBQX1ZBTElEQVRPUlNbQW5ub3RhdGlvblR5cGVzW2NvbF1dKHByb3BWYWxpZGF0aW9uQ29uZmlnW0Fubm90YXRpb25UeXBlc1tjb2xdXSkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBDaGVjayBpZiB0aGUgY3VycmVudCBhbm5vdGF0aW9uIHR5cGUgaXMgY3VzdG9tIGFuZCB0aGUgY3VzdG9tIHZhbGlkYXRvciBleGlzdHMgaW4gdGhlIHZhbGlkYXRpb24gY29uZmlndXJhdGlvbiAqL1xyXG4gICAgICAgICAgICBlbHNlIGlmIChjb2wgPT0gQW5ub3RhdGlvblR5cGVzLmN1c3RvbSAmJiBwcm9wVmFsaWRhdGlvbkNvbmZpZ1tBbm5vdGF0aW9uVHlwZXNbY29sXV0pIHtcclxuICAgICAgICAgICAgICAgIC8qIEFkZCBjdXN0b20gdmFsaWRhdG9yICovXHJcbiAgICAgICAgICAgICAgICB2YWxpZGF0aW9ucy5wdXNoKHByb3BWYWxpZGF0aW9uQ29uZmlnW2NvbF0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0cmlldmVzIHRoZSBlbnRpdHkgdHlwZSBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgb2JqZWN0IGFuZCBwcm9wZXJ0eSBpbmZvcm1hdGlvbi5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIG9iamVjdCBUaGUgb2JqZWN0IGZvciB3aGljaCB0aGUgZW50aXR5IHR5cGUgaXMgcmV0cmlldmVkLlxyXG4gICAgICogQHBhcmFtIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIGZvcm0gYnVpbGRlci5cclxuICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LlxyXG4gICAgICogQHBhcmFtIGlzU2FtZU9iamVjdENvbnN0cnVjdG9yIEluZGljYXRlcyBpZiB0aGUgZW50aXR5IHR5cGUgaXMgdGhlIHNhbWUgYXMgdGhlIG9iamVjdCdzIGNvbnN0cnVjdG9yLlxyXG4gICAgICogQHJldHVybnMgVGhlIGVudGl0eSB0eXBlLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldEVudGl0eTxUPihvYmplY3Q6IFQsIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbjogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLCBwcm9wZXJ0eU5hbWU6IHN0cmluZywgaXNTYW1lT2JqZWN0Q29uc3RydWN0b3I6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgICAgIC8qIENoZWNrIGlmIHRoZSBlbnRpdHkgdHlwZSBpcyBkZWZpbmVkIGluIHRoZSBmb3JtIGJ1aWxkZXIgY29uZmlndXJhdGlvbiAqL1xyXG4gICAgICAgIGlmIChmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gJiYgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmdlbmVyaWNFbnRpdGllcyAmJiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uZ2VuZXJpY0VudGl0aWVzW3Byb3BlcnR5TmFtZV0pIHtcclxuICAgICAgICAgICAgLyogUmV0dXJuIHRoZSBlbnRpdHkgdHlwZSBmcm9tIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiBpZiBhdmFpbGFibGUgKi9cclxuICAgICAgICAgICAgcmV0dXJuIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5nZW5lcmljRW50aXRpZXNbcHJvcGVydHlOYW1lXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIFJldHVybiB0aGUgb2JqZWN0J3MgY29uc3RydWN0b3IgaWYgaXNTYW1lT2JqZWN0Q29uc3RydWN0b3IgaXMgdHJ1ZSAqL1xyXG4gICAgICAgIHJldHVybiBpc1NhbWVPYmplY3RDb25zdHJ1Y3RvciA/IG9iamVjdCEuY29uc3RydWN0b3IgOiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBvYmplY3QgcHJvcGVydHkgaW5zdGFuY2UgYmFzZWQgb24gdGhlIHByb3ZpZGVkIG9iamVjdCBhbmQgcHJvcGVydHkgaW5mb3JtYXRpb24uXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSBvYmplY3QgVGhlIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0eS5cclxuICAgICAqIEBwYXJhbSBwcm9wZXJ0eUluZm8gSW5mb3JtYXRpb24gYWJvdXQgdGhlIHByb3BlcnR5LlxyXG4gICAgICogQHBhcmFtIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIGZvcm0gYnVpbGRlci5cclxuICAgICAqIEByZXR1cm5zIFRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgb2JqZWN0IHByb3BlcnR5IGluc3RhbmNlLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldE9iamVjdFByb3BlcnR5SW5zdGFuY2Uob2JqZWN0OiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBwcm9wZXJ0eUluZm86IFByb3BlcnR5SW5mbywgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uOiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pIHtcclxuICAgICAgICAvKiBDaGVjayBpZiB0aGUgcHJvcGVydHkgdHlwZSBpcyBPQkpFQ1RfUFJPUEVSVFkgYW5kIHRoZSBwcm9wZXJ0eSBleGlzdHMgaW4gdGhlIG9iamVjdCAqL1xyXG4gICAgICAgIGlmIChwcm9wZXJ0eUluZm8ucHJvcGVydHlUeXBlID09IE9CSkVDVF9QUk9QRVJUWSAmJiBvYmplY3RbcHJvcGVydHlJbmZvLm5hbWVdKSB7XHJcbiAgICAgICAgICAgIC8qIFJldHVybiB0aGUgY29uc3RydWN0b3Igb2YgdGhlIG9iamVjdCBwcm9wZXJ0eSBpZiBpdCBleGlzdHMgKi9cclxuICAgICAgICAgICAgcmV0dXJuIG9iamVjdFtwcm9wZXJ0eUluZm8ubmFtZV0uY29uc3RydWN0b3I7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBDaGVjayBpZiB0aGUgcHJvcGVydHkgdHlwZSBpcyBBUlJBWV9QUk9QRVJUWSBhbmQgdGhlIHByb3BlcnR5IGV4aXN0cyBhbmQgY29udGFpbnMgaXRlbXMgaW4gdGhlIG9iamVjdCAqL1xyXG4gICAgICAgIGVsc2UgaWYgKHByb3BlcnR5SW5mby5wcm9wZXJ0eVR5cGUgPT0gQVJSQVlfUFJPUEVSVFkgJiYgb2JqZWN0W3Byb3BlcnR5SW5mby5uYW1lXSAmJiBvYmplY3RbcHJvcGVydHlJbmZvLm5hbWVdLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgLyogUmV0dXJuIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgYXJyYXkgcHJvcGVydHkgaWYgaXQgZXhpc3RzICovXHJcbiAgICAgICAgICAgIHJldHVybiBvYmplY3RbcHJvcGVydHlJbmZvLm5hbWVdWzBdLmNvbnN0cnVjdG9yO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogUmV0dXJuIHRoZSBlbnRpdHkgdHlwZSBiYXNlZCBvbiB0aGUgb2JqZWN0IGFuZCBwcm9wZXJ0eSBpbmZvcm1hdGlvbiAqL1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldEVudGl0eShvYmplY3QsIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiwgcHJvcGVydHlJbmZvLm5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGZvciBhZGRpdGlvbmFsIHZhbGlkYXRpb24gY29uZmlndXJhdGlvbnMgZm9yIG9iamVjdCBwcm9wZXJ0aWVzIGluIHRoZSBpbnN0YW5jZSBjb250YWluZXIuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSBpbnN0YW5jZUNvbnRhaW5lciBUaGUgY29udGFpbmVyIGZvciB0aGUgaW5zdGFuY2UuXHJcbiAgICAgKiBAcGFyYW0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2hlY2sgZm9yIGFkZGl0aW9uYWwgdmFsaWRhdGlvbiBjb25maWd1cmF0aW9ucy5cclxuICAgICAqIEBwYXJhbSBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gVGhlIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBmb3JtIGJ1aWxkZXIuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgY2hlY2tPYmplY3RQcm9wQWRkaXRpb25hbFZhbGlkYXRpb248VD4oaW5zdGFuY2VDb250YWluZXI6IEluc3RhbmNlQ29udGFpbmVyLCBvYmplY3Q6IFQsIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbjogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSB7XHJcbiAgICAgICAgLyogRmlsdGVyIHByb3BlcnRpZXMgb2YgdHlwZSBPQkpFQ1RfUFJPUEVSVFkgb3IgQVJSQVlfUFJPUEVSVFkgKi9cclxuICAgICAgICB2YXIgcHJvcHMgPSBpbnN0YW5jZUNvbnRhaW5lci5wcm9wZXJ0aWVzPy5maWx0ZXIodCA9PiB0LnByb3BlcnR5VHlwZSA9PSBPQkpFQ1RfUFJPUEVSVFkgfHwgdC5wcm9wZXJ0eVR5cGUgPT0gQVJSQVlfUFJPUEVSVFkpO1xyXG5cclxuICAgICAgICAvKiBJdGVyYXRlIHRocm91Z2ggdGhlIGZpbHRlcmVkIHByb3BlcnRpZXMgKi9cclxuICAgICAgICBwcm9wcz8uZm9yRWFjaCh0ID0+IHtcclxuICAgICAgICAgICAgbGV0IGVudGl0eSA9IHQuZW50aXR5O1xyXG5cclxuICAgICAgICAgICAgLyogSWYgZW50aXR5IHR5cGUgaXMgbm90IGRlZmluZWQgaW4gdGhlIHByb3BlcnR5LCByZXRyaWV2ZSBpdCBmcm9tIHRoZSBvYmplY3QgKi9cclxuICAgICAgICAgICAgaWYgKCF0LmVudGl0eSlcclxuICAgICAgICAgICAgICAgIGVudGl0eSA9IHRoaXMuZ2V0T2JqZWN0UHJvcGVydHlJbnN0YW5jZShvYmplY3QhLCB0LCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pO1xyXG5cclxuICAgICAgICAgICAgaWYgKGVudGl0eSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IGluc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZUNvbnRhaW5lcihlbnRpdHksIG51bGwpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8qIENoZWNrIGlmIGluc3RhbmNlIGV4aXN0cyBhbmQgaGFzIGNvbmRpdGlvbmFsIHZhbGlkYXRpb24gcHJvcGVydGllcyAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlICYmIGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcm9wID0gaW5zdGFuY2VDb250YWluZXIucHJvcGVydGllcz8uZmlsdGVyKHQgPT4gdC5uYW1lID09IGtleSlbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvcCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSW5pdGlhbGl6ZSBjb25kaXRpb25hbCB2YWxpZGF0aW9uIHByb3BlcnRpZXMgaW4gaW5zdGFuY2UgY29udGFpbmVyIGlmIG5vdCBhbHJlYWR5IGluaXRpYWxpemVkICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1trZXldKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW2tleV0gPSBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBBZGQgY29uZGl0aW9uYWwgdmFsaWRhdGlvbiBwcm9wZXJ0aWVzICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1trZXldLmZvckVhY2goeCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQucHJvcGVydHlUeXBlICE9IEFSUkFZX1BST1BFUlRZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcyBhcyBhbnkpW2tleV0ucHVzaChbdC5uYW1lLCB4XS5qb2luKCcuJykpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcyBhcyBhbnkpW2tleV0ucHVzaChbdC5uYW1lLCB4XS5qb2luKCdbXScpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhbiBvYmplY3QgY29udGFpbmluZyBtb2RlbCwgZW50aXR5T2JqZWN0LCBhbmQgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBwYXJhbWV0ZXJzLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gbW9kZWwgVGhlIG1vZGVsIHRvIGJlIHVzZWQgZm9yIG9iamVjdCBjb25zdHJ1Y3Rpb24uXHJcbiAgICAgKiBAcGFyYW0gZW50aXR5T2JqZWN0IFRoZSBlbnRpdHkgb2JqZWN0IHRvIGJlIHVzZWQuXHJcbiAgICAgKiBAcGFyYW0gZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uIFRoZSBjb25maWd1cmF0aW9uIGZvciB0aGUgZm9ybSBidWlsZGVyLlxyXG4gICAgICogQHJldHVybnMgQW4gb2JqZWN0IGNvbnRhaW5pbmcgbW9kZWwsIGVudGl0eU9iamVjdCwgYW5kIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRPYmplY3QobW9kZWw6IGFueSB8IHsgW2tleTogc3RyaW5nXTogYW55IH0sIGVudGl0eU9iamVjdD86IHsgW2tleTogc3RyaW5nXTogYW55IH0gfCBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24sIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbj86IEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbik6IHsgW2tleTogc3RyaW5nXTogYW55IH0ge1xyXG4gICAgICAgIC8qIEluaXRpYWxpemVzIGFuIGVtcHR5IG9iamVjdCB0byBzdG9yZSB0aGUgSlNPTiByZXByZXNlbnRhdGlvbiAqL1xyXG4gICAgICAgIGxldCBqc29uOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XHJcblxyXG4gICAgICAgIC8qIENoZWNrcyBpZiB0aGUgbW9kZWwgaXMgYSBmdW5jdGlvbiAqL1xyXG4gICAgICAgIGlmICh0eXBlb2YgbW9kZWwgPT0gRlVOQ1RJT05fU1RSSU5HKSB7XHJcbiAgICAgICAgICAgIGpzb24ubW9kZWwgPSBtb2RlbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIENoZWNrcyBpZiB0aGUgbW9kZWwgaXMgYSBmdW5jdGlvbiBhbmQgZW50aXR5T2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mIEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiAqL1xyXG4gICAgICAgIGlmICh0eXBlb2YgbW9kZWwgPT0gRlVOQ1RJT05fU1RSSU5HICYmIChlbnRpdHlPYmplY3QgaW5zdGFuY2VvZiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pKSB7XHJcbiAgICAgICAgICAgIC8qIENyZWF0ZXMgdGhlIGVudGl0eSBvYmplY3QgdXNpbmcgY3JlYXRlQ2xhc3NPYmplY3QgbWV0aG9kICovXHJcbiAgICAgICAgICAgIGpzb24uZW50aXR5T2JqZWN0ID0gdGhpcy5jcmVhdGVDbGFzc09iamVjdChqc29uLm1vZGVsLCBlbnRpdHlPYmplY3QpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogQ2hlY2tzIGlmIGVudGl0eU9iamVjdCBleGlzdHMgYW5kIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gKi9cclxuICAgICAgICBpZiAoZW50aXR5T2JqZWN0ICYmICEoZW50aXR5T2JqZWN0IGluc3RhbmNlb2YgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSkge1xyXG4gICAgICAgICAgICBqc29uLmVudGl0eU9iamVjdCA9IGVudGl0eU9iamVjdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIENoZWNrcyBpZiBlbnRpdHlPYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uIGFuZCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gaXMgbm90IHByb3ZpZGVkICovXHJcbiAgICAgICAgaWYgKGVudGl0eU9iamVjdCBpbnN0YW5jZW9mIEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiAmJiAhZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgIGpzb24uZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uID0gZW50aXR5T2JqZWN0O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvKiBDaGVja3MgaWYgZW50aXR5T2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gYW5kIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiBpcyBwcm92aWRlZCAqL1xyXG4gICAgICAgIGVsc2UgaWYgKCEoZW50aXR5T2JqZWN0IGluc3RhbmNlb2YgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSAmJiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pIHtcclxuICAgICAgICAgICAgLyogU2V0cyB0aGUgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uIGluIHRoZSBKU09OICovXHJcbiAgICAgICAgICAgIGpzb24uZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uID0gZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uO1xyXG4gICAgICAgICAgICAvKiBDcmVhdGVzIHRoZSBlbnRpdHkgb2JqZWN0IHVzaW5nIGNyZWF0ZUNsYXNzT2JqZWN0IG1ldGhvZCAqL1xyXG4gICAgICAgICAgICBqc29uLmVudGl0eU9iamVjdCA9IHRoaXMuY3JlYXRlQ2xhc3NPYmplY3QoanNvbi5tb2RlbCwganNvbi5mb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24sIGpzb24uZW50aXR5T2JqZWN0KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIElmIGVudGl0eU9iamVjdCBkb2VzIG5vdCBleGlzdCAqL1xyXG4gICAgICAgIGlmICghZW50aXR5T2JqZWN0KSB7XHJcbiAgICAgICAgICAgIC8qIENoZWNrcyBpZiB0aGUgbW9kZWwgaXMgYW4gb2JqZWN0ICovXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbW9kZWwgPT0gT0JKRUNUX1NUUklORykge1xyXG4gICAgICAgICAgICAgICAgLyogU3RvcmVzIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgbW9kZWwgKi9cclxuICAgICAgICAgICAgICAgIGpzb24ubW9kZWwgPSBtb2RlbC5jb25zdHJ1Y3RvcjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyogQ3JlYXRlcyB0aGUgZW50aXR5IG9iamVjdCB1c2luZyBjcmVhdGVDbGFzc09iamVjdCBtZXRob2QgKi9cclxuICAgICAgICAgICAganNvbi5lbnRpdHlPYmplY3QgPSB0aGlzLmNyZWF0ZUNsYXNzT2JqZWN0KGpzb24ubW9kZWwsIGpzb24uZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLCBtb2RlbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8qIElmIGVudGl0eU9iamVjdCBleGlzdHMgYW5kIGlzIGFuIGluc3RhbmNlIG9mIEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiBhbmQgbW9kZWwgaXMgYW4gb2JqZWN0ICovXHJcbiAgICAgICAgZWxzZSBpZiAobW9kZWwgJiYgKGVudGl0eU9iamVjdCBpbnN0YW5jZW9mIEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbikgJiYgKHR5cGVvZiBtb2RlbCA9PSBPQkpFQ1RfU1RSSU5HKSkge1xyXG4gICAgICAgICAgICAvKiBTdG9yZXMgdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBtb2RlbCAqL1xyXG4gICAgICAgICAgICBqc29uW01PREVMXSA9IG1vZGVsLmNvbnN0cnVjdG9yO1xyXG4gICAgICAgICAgICAvKiBDcmVhdGVzIHRoZSBlbnRpdHkgb2JqZWN0IHVzaW5nIGNyZWF0ZUNsYXNzT2JqZWN0IG1ldGhvZCAqL1xyXG4gICAgICAgICAgICBqc29uW0VOVElUWV9PQkpFQ1RdID0gdGhpcy5jcmVhdGVDbGFzc09iamVjdChqc29uLm1vZGVsLCBqc29uLmZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiwgbW9kZWwpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogUmV0dXJucyB0aGUgY29uc3RydWN0ZWQgSlNPTiBvYmplY3QgKi9cclxuICAgICAgICByZXR1cm4ganNvbjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBmb3JtIGNvbnRyb2wgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlIGFuZCB2YWxpZGF0b3JzLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIGZvciB0aGUgZm9ybSBjb250cm9sLlxyXG4gICAgICogQHBhcmFtIHZhbGlkYXRvcnMgQW4gYXJyYXkgb2Ygc3luY2hyb25vdXMgdmFsaWRhdG9ycy5cclxuICAgICAqIEBwYXJhbSBhc3luY1ZhbGlkYXRvcnMgQW4gYXJyYXkgb2YgYXN5bmNocm9ub3VzIHZhbGlkYXRvcnMuXHJcbiAgICAgKiBAcmV0dXJucyBBbiBpbnN0YW5jZSBvZiBJQWJzdHJhY3RDb250cm9sLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29udHJvbCh2YWx1ZT86IGFueSwgdmFsaWRhdG9ycz86IFZhbGlkYXRvckZuW10sIGFzeW5jVmFsaWRhdG9ycz86IEFzeW5jVmFsaWRhdG9yRm5bXSk6IElBYnN0cmFjdENvbnRyb2wge1xyXG4gICAgICAgIHJldHVybiBuZXcgUnhGb3JtQ29udHJvbCh2YWx1ZSwgeyB2YWxpZGF0b3JzOiB2YWxpZGF0b3JzLCBhc3luY1ZhbGlkYXRvcnM6IGFzeW5jVmFsaWRhdG9ycyB9LCB7fSwge30sICcnLCBbXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgZm9ybSBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWVzIGFuZCB2YWxpZGF0b3IgY29uZmlndXJhdGlvbi5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHZhbHVlcyBBbiBhcnJheSBvZiBvYmplY3RzIHRvIGluaXRpYWxpemUgdGhlIGZvcm0gYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0gdmFsaWRhdG9yQ29uZmlnIFRoZSBjb25maWd1cmF0aW9uIGZvciB2YWxpZGF0b3JzLlxyXG4gICAgICogQHJldHVybnMgQW4gaW5zdGFuY2Ugb2YgRm9ybUFycmF5LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXJyYXkodmFsdWVzOiBbeyBba2V5OiBzdHJpbmddOiBhbnkgfV0sIHZhbGlkYXRvckNvbmZpZz86IEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbikge1xyXG4gICAgICAgIC8qIENyZWF0ZXMgYSBGb3JtR3JvdXAgaW5zdGFuY2Ugd2l0aCBhIHNpbmdsZSBjb250cm9sIG5hbWVkIFwidGVtcFwiIGFuZCBhc3NpZ25zIGl0IHRvIGZvcm1BcnJheSAqL1xyXG4gICAgICAgIGxldCBmb3JtQXJyYXkgPSB0aGlzLmdyb3VwKHsgdGVtcDogdmFsdWVzIH0sIHZhbGlkYXRvckNvbmZpZykuZ2V0KFwidGVtcFwiKSBhcyBGb3JtQXJyYXk7XHJcblxyXG4gICAgICAgIC8qIEluc3RhbnRpYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRm9ybUJ1aWxkZXIgKi9cclxuICAgICAgICB2YXIgZm9ybUJ1aWxkZXIgPSBuZXcgRm9ybUJ1aWxkZXIoKTtcclxuXHJcbiAgICAgICAgLyogQ3JlYXRlcyBhIEZvcm1BcnJheSBpbnN0YW5jZSB1c2luZyB0aGUgY29udHJvbHMgb2YgdGhlIEZvcm1Hcm91cCAqL1xyXG4gICAgICAgIHJldHVybiBmb3JtQnVpbGRlci5hcnJheShmb3JtQXJyYXkuY29udHJvbHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGZvcm0gZ3JvdXAgd2l0aCB0aGUgc3BlY2lmaWVkIGdyb3VwIG9iamVjdCBhbmQgdmFsaWRhdG9yIGNvbmZpZ3VyYXRpb24uXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSBncm91cE9iamVjdCBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBncm91cC5cclxuICAgICAqIEBwYXJhbSB2YWxpZGF0b3JDb25maWcgVGhlIGNvbmZpZ3VyYXRpb24gZm9yIHZhbGlkYXRvcnMuXHJcbiAgICAgKiBAcmV0dXJucyBBbiBpbnN0YW5jZSBvZiBGb3JtR3JvdXAuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBncm91cChncm91cE9iamVjdDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSwgdmFsaWRhdG9yQ29uZmlnPzogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKTogRm9ybUdyb3VwIHtcclxuICAgICAgICAvKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIG1vZGVsICovXHJcbiAgICAgICAgbGV0IG1vZGVsSW5zdGFuY2UgPSBzdXBlci5jcmVhdGVJbnN0YW5jZSgpO1xyXG5cclxuICAgICAgICAvKiBJbml0aWFsaXplIGFuIGVtcHR5IG9iamVjdCBmb3IgdGhlIGVudGl0eSAqL1xyXG4gICAgICAgIGxldCBlbnRpdHlPYmplY3QgPSB7fTtcclxuXHJcbiAgICAgICAgLyogSW5pdGlhbGl6ZSBhbiBlbXB0eSBvYmplY3QgZm9yIGZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciAqL1xyXG4gICAgICAgIHRoaXMuZm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yID0ge307XHJcblxyXG4gICAgICAgIC8qIFNldCBjdXJyZW50Rm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yIHRvIGZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciAqL1xyXG4gICAgICAgIHRoaXMuY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciA9IHRoaXMuZm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yO1xyXG5cclxuICAgICAgICAvKiBDcmVhdGUgdGhlIHZhbGlkYXRvciBmb3JtIGdyb3VwICovXHJcbiAgICAgICAgdGhpcy5jcmVhdGVWYWxpZGF0b3JGb3JtR3JvdXAoZ3JvdXBPYmplY3QsIGVudGl0eU9iamVjdCwgbW9kZWxJbnN0YW5jZSwgdmFsaWRhdG9yQ29uZmlnISk7XHJcblxyXG4gICAgICAgIC8qIFNldCBjdXJyZW50Rm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yIGJhY2sgdG8gZm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yICovXHJcbiAgICAgICAgdGhpcy5jdXJyZW50Rm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yID0gdGhpcy5mb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3I7XHJcblxyXG4gICAgICAgIC8qIEZsYWcgdGhhdCBhIGdyb3VwIGlzIGJlaW5nIGNhbGxlZCAqL1xyXG4gICAgICAgIHRoaXMuaXNHcm91cENhbGxlZCA9IHRydWU7XHJcblxyXG4gICAgICAgIC8qIENyZWF0ZSB0aGUgZm9ybSBncm91cCAqL1xyXG4gICAgICAgIGxldCBmb3JtR3JvdXAgPSB0aGlzLmZvcm1Hcm91cChtb2RlbEluc3RhbmNlLmNvbnN0cnVjdG9yLCBlbnRpdHlPYmplY3QsIHZhbGlkYXRvckNvbmZpZyk7XHJcblxyXG4gICAgICAgIC8qIFJlc2V0IGlzR3JvdXBDYWxsZWQgZmxhZyAqL1xyXG4gICAgICAgIHRoaXMuaXNHcm91cENhbGxlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAvKiBSZXNldCBmb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3IgKi9cclxuICAgICAgICB0aGlzLmZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciA9IHt9O1xyXG5cclxuICAgICAgICAvKiBSZXNldCBjdXJyZW50Rm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yICovXHJcbiAgICAgICAgdGhpcy5jdXJyZW50Rm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yID0gdGhpcy5mb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3I7XHJcblxyXG4gICAgICAgIC8qIFJlc2V0IGZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciAqL1xyXG4gICAgICAgIHRoaXMuZm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yID0ge307XHJcblxyXG4gICAgICAgIC8qIFJldHVybiB0aGUgY3JlYXRlZCBmb3JtIGdyb3VwICovXHJcbiAgICAgICAgcmV0dXJuIGZvcm1Hcm91cDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGx5IGFsbCBwcm9wZXJ0eSB2YWxpZGF0b3JzIHNwZWNpZmllZCBpbiB0aGUgdmFsaWRhdG9yIGNvbmZpZ3VyYXRpb24gdG8gYSBnaXZlbiBwcm9wZXJ0eS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHByb3BOYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byB3aGljaCB2YWxpZGF0b3JzIGFyZSBhcHBsaWVkLlxyXG4gICAgICogQHBhcmFtIHZhbGlkYXRvckNvbmZpZyBUaGUgY29uZmlndXJhdGlvbiBmb3IgcHJvcGVydHkgdmFsaWRhdGlvbi5cclxuICAgICAqIEBwYXJhbSBtb2RlbEluc3RhbmNlIFRoZSBpbnN0YW5jZSBvZiB0aGUgbW9kZWwuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYXBwbHlBbGxQcm9wVmFsaWRhdG9yKHByb3BOYW1lOiBzdHJpbmcsIHZhbGlkYXRvckNvbmZpZzogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLCBtb2RlbEluc3RhbmNlOiBhbnkpIHtcclxuICAgICAgICAvKiBDaGVjayBpZiB0aGUgdmFsaWRhdG9yIGNvbmZpZ3VyYXRpb24gYW5kIGFwcGx5QWxsUHJvcHMgYXJyYXkgZXhpc3QgKi9cclxuICAgICAgICBpZiAodmFsaWRhdG9yQ29uZmlnICYmIHZhbGlkYXRvckNvbmZpZy5hcHBseUFsbFByb3BzKSB7XHJcbiAgICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSBleGNsdWRlUHJvcHMgYXJyYXkgZXhpc3RzIGFuZCBpZiB0aGUgcHJvcE5hbWUgaXMgbm90IGluIHRoZSBleGNsdWRlUHJvcHMgYXJyYXkgKi9cclxuICAgICAgICAgICAgaWYgKCEodmFsaWRhdG9yQ29uZmlnLmV4Y2x1ZGVQcm9wcyAmJiB2YWxpZGF0b3JDb25maWcuZXhjbHVkZVByb3BzLmxlbmd0aCA+IDAgJiYgdmFsaWRhdG9yQ29uZmlnLmV4Y2x1ZGVQcm9wcy5pbmRleE9mKHByb3BOYW1lKSA9PSAtMSkpIHtcclxuICAgICAgICAgICAgICAgIC8qIEl0ZXJhdGUgdGhyb3VnaCBlYWNoIGl0ZW0gaW4gdGhlIGFwcGx5QWxsUHJvcHMgYXJyYXkgKi9cclxuICAgICAgICAgICAgICAgIHZhbGlkYXRvckNvbmZpZy5hcHBseUFsbFByb3BzLmZvckVhY2goKHQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSB2YWxpZGF0b3IgZnVuY3Rpb24gaXMgYW4gUnhXZWIgdmFsaWRhdG9yICovXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQubmFtZSA9PSBSWF9XRUJfVkFMSURBVE9SKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEFwcGx5IFJ4V2ViIHZhbGlkYXRvciB0byB0aGUgcHJvcE5hbWUgd2l0aCB0aGUgbW9kZWxJbnN0YW5jZSAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0KHByb3BOYW1lLCBtb2RlbEluc3RhbmNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBDaGVjayBpZiB0aGUgY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciBoYXMgYW4gZW50cnkgZm9yIHRoZSBwcm9wTmFtZSAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvcltwcm9wTmFtZV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIElmIG5vdCwgY3JlYXRlIGFuIGVtcHR5IGFycmF5IGZvciB0aGUgcHJvcE5hbWUgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvcltwcm9wTmFtZV0gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogUHVzaCB0aGUgY3VzdG9tIHZhbGlkYXRvciB0byB0aGUgY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciBhcnJheSAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRGb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3JbcHJvcE5hbWVdLnB1c2godCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgICogQ2hlY2tzIGlmIGR5bmFtaWMgdmFsaWRhdGlvbiBzaG91bGQgYmUgYXBwbGllZCB0byBhIHByb3BlcnR5LlxyXG4gICAgICAqIFxyXG4gICAgICAqIEBwYXJhbSBwcm9wTmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gY2hlY2suXHJcbiAgICAgICogQHBhcmFtIHZhbGlkYXRvckNvbmZpZyBUaGUgY29uZmlndXJhdGlvbiBmb3IgcHJvcGVydHkgdmFsaWRhdGlvbi5cclxuICAgICAgKiBAcmV0dXJucyBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGR5bmFtaWMgdmFsaWRhdGlvbiBzaG91bGQgYmUgYXBwbGllZCB0byB0aGUgcHJvcGVydHkuXHJcbiAgICAgICovXHJcbiAgICBwcml2YXRlIGR5bmFtaWNWYWxpZGF0aW9uUHJvcENoZWNrKHByb3BOYW1lOiBzdHJpbmcsIHZhbGlkYXRvckNvbmZpZzogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSB7XHJcbiAgICAgICAgcmV0dXJuICh2YWxpZGF0b3JDb25maWcgPT0gdW5kZWZpbmVkKSA/IHRydWUgOiAoIXZhbGlkYXRvckNvbmZpZy5keW5hbWljVmFsaWRhdGlvbkNvbmZpZ3VyYXRpb25Qcm9wZXJ0eU5hbWUpID8gdHJ1ZSA6IHZhbGlkYXRvckNvbmZpZy5keW5hbWljVmFsaWRhdGlvbkNvbmZpZ3VyYXRpb25Qcm9wZXJ0eU5hbWUgPT0gcHJvcE5hbWUgPyBmYWxzZSA6IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIG5vdCBhbiBvYmplY3QuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXHJcbiAgICAgKiBAcmV0dXJucyBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB2YWx1ZSBpcyBub3QgYW4gb2JqZWN0LlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzTm90T2JqZWN0KHZhbHVlOiBhbnkpIHtcclxuICAgICAgICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBEYXRlIHx8IHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSAhPSBPQkpFQ1RfU1RSSU5HO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIHZhbGlkYXRvciBmb3JtIGdyb3VwIGJhc2VkIG9uIHRoZSBncm91cE9iamVjdCBhbmQgYXBwbGllcyB2YWxpZGF0aW9uIHJ1bGVzLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gZ3JvdXBPYmplY3QgVGhlIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIHRvIGNyZWF0ZSB0aGUgZm9ybSBncm91cC5cclxuICAgICAqIEBwYXJhbSBlbnRpdHlPYmplY3QgVGhlIGVudGl0eSBvYmplY3QgdG8gc3RvcmUgdGhlIGZvcm0gZ3JvdXAuXHJcbiAgICAgKiBAcGFyYW0gbW9kZWxJbnN0YW5jZSBUaGUgbW9kZWwgaW5zdGFuY2UgdXNlZCBmb3IgaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgKiBAcGFyYW0gdmFsaWRhdG9yQ29uZmlnIFRoZSBjb25maWd1cmF0aW9uIGZvciBwcm9wZXJ0eSB2YWxpZGF0aW9uLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNyZWF0ZVZhbGlkYXRvckZvcm1Hcm91cChncm91cE9iamVjdDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSwgZW50aXR5T2JqZWN0OiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBtb2RlbEluc3RhbmNlOiBhbnksIHZhbGlkYXRvckNvbmZpZzogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSB7XHJcbiAgICAgICAgLyogSXRlcmF0ZXMgb3ZlciBlYWNoIHByb3BlcnR5IGluIHRoZSBncm91cE9iamVjdCB0byBjcmVhdGUgZm9ybSBjb250cm9scyBhbmQgYXBwbHkgdmFsaWRhdG9ycy4gKi9cclxuICAgICAgICBmb3IgKHZhciBwcm9wTmFtZSBpbiBncm91cE9iamVjdCkge1xyXG4gICAgICAgICAgICB2YXIgcHJvcCA9IGdyb3VwT2JqZWN0W3Byb3BOYW1lXTtcclxuXHJcbiAgICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSBwcm9wZXJ0eSBpcyBhbiBhcnJheSBhbmQgbmVlZHMgdmFsaWRhdGlvbiAqL1xyXG4gICAgICAgICAgICBpZiAocHJvcCBpbnN0YW5jZW9mIEFycmF5ICYmIHByb3AubGVuZ3RoID4gMCAmJiB0aGlzLmlzTm90T2JqZWN0KHByb3BbMF0pKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcHJvcFZhbGlkYXRvcnMgPSAocHJvcC5sZW5ndGggPiAxICYmIHByb3BbMV0gaW5zdGFuY2VvZiBBcnJheSkgPyBwcm9wWzFdIDogKHByb3AubGVuZ3RoID09IDIpID8gW3Byb3BbMV1dIDogW107XHJcbiAgICAgICAgICAgICAgICBsZXQgcHJvcGVydHlBZGRlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIC8qIEl0ZXJhdGUgb3ZlciBlYWNoIHZhbGlkYXRvciBmb3IgdGhlIGN1cnJlbnQgcHJvcGVydHkgKi9cclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcFZhbGlkYXRvcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcFZhbGlkYXRvcnNbaV0ubmFtZSA9PSBSWF9XRUJfVkFMSURBVE9SKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3BWYWxpZGF0b3JzW2ldKHByb3BOYW1lLCBtb2RlbEluc3RhbmNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlBZGRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogQWRkIG90aGVyIHZhbGlkYXRvcnMgdG8gdGhlIGN1cnJlbnRGb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3IgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnRGb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3JbcHJvcE5hbWVdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRGb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3JbcHJvcE5hbWVdID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvcltwcm9wTmFtZV0ucHVzaChwcm9wVmFsaWRhdG9yc1tpXSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyogSWYgbm8gcHJvcGVydHkgdmFsaWRhdG9yIGFkZGVkLCBpbml0aWFsaXplIHRoZSBwcm9wZXJ0eSBvYmplY3QgKi9cclxuICAgICAgICAgICAgICAgIGlmICghcHJvcGVydHlBZGRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRDb250YWluZXIuaW5pdFByb3BlcnR5T2JqZWN0KHByb3BOYW1lLCBQUk9QRVJUWSwgdW5kZWZpbmVkLCB0eXBlb2YgbW9kZWxJbnN0YW5jZSA9PSBPQkpFQ1RfU1RSSU5HID8gbW9kZWxJbnN0YW5jZSA6IHsgY29uc3RydWN0b3I6IG1vZGVsSW5zdGFuY2UgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyogQXBwbHkgYWxsIHByb3BlcnR5IHZhbGlkYXRvcnMgKi9cclxuICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlBbGxQcm9wVmFsaWRhdG9yKHByb3BOYW1lLCB2YWxpZGF0b3JDb25maWcsIG1vZGVsSW5zdGFuY2UpXHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvcCA9PT0gbnVsbCB8fCBwcm9wID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHByb3AgPT0gU1RSSU5HIHx8IHR5cGVvZiBwcm9wID09IE5VTUJFUiB8fCB0eXBlb2YgcHJvcCA9PSBCT09MRUFOIHx8IHByb3AgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIHRoZSBwcm9wZXJ0eSBvYmplY3QgaWYgaXQncyBhIHNpbXBsZSB0eXBlICovXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0Q29udGFpbmVyLmluaXRQcm9wZXJ0eU9iamVjdChwcm9wTmFtZSwgUFJPUEVSVFksIHVuZGVmaW5lZCwgdHlwZW9mIG1vZGVsSW5zdGFuY2UgPT0gT0JKRUNUX1NUUklORyA/IG1vZGVsSW5zdGFuY2UgOiB7IGNvbnN0cnVjdG9yOiBtb2RlbEluc3RhbmNlIH0pO1xyXG4gICAgICAgICAgICAgICAgLyogQXBwbHkgYWxsIHByb3BlcnR5IHZhbGlkYXRvcnMgKi9cclxuICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlBbGxQcm9wVmFsaWRhdG9yKHByb3BOYW1lLCB2YWxpZGF0b3JDb25maWcsIG1vZGVsSW5zdGFuY2UpXHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvcCBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbnN0YW5jZW9mIEZvcm1BcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8qIElmIHRoZSBwcm9wZXJ0eSBpcyBhIEZvcm1BcnJheSwgYXNzaWduIGl0IGRpcmVjdGx5ICovXHJcbiAgICAgICAgICAgICAgICAgICAgZW50aXR5T2JqZWN0W3Byb3BOYW1lXSA9IHByb3A7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8qIElmIGl0J3MgYW4gYXJyYXkgb2Ygb2JqZWN0cywgY3JlYXRlIGZvcm0gY29udHJvbHMgcmVjdXJzaXZlbHkgKi9cclxuICAgICAgICAgICAgICAgICAgICBsZXQgcHJvcE1vZGVsSW5zdGFuY2UgPSBzdXBlci5jcmVhdGVJbnN0YW5jZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbW9kZWxJbnN0YW5jZSA9PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxJbnN0YW5jZS5jb25zdHJ1Y3RvciA9IG1vZGVsSW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIHRoZSBwcm9wZXJ0eSBhcyBhbiBhcnJheSAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRDb250YWluZXIuaW5pdFByb3BlcnR5T2JqZWN0KHByb3BOYW1lLCBBUlJBWV9QUk9QRVJUWSwgcHJvcE1vZGVsSW5zdGFuY2UuY29uc3RydWN0b3IsIG1vZGVsSW5zdGFuY2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIGFuIGVtcHR5IGFycmF5IGZvciB0aGUgcHJvcGVydHkgKi9cclxuICAgICAgICAgICAgICAgICAgICBlbnRpdHlPYmplY3RbcHJvcE5hbWVdID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8qIEl0ZXJhdGUgdGhyb3VnaCBlYWNoIGVsZW1lbnQgb2YgdGhlIGFycmF5ICovXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgcm93IG9mIHByb3ApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogQ3JlYXRlIGEgbmV3IG9iamVjdCBmb3IgZWFjaCBlbGVtZW50ICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBqT2JqZWN0ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFB1c2ggdGhlIG5ldyBvYmplY3QgaW50byB0aGUgYXJyYXkgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5T2JqZWN0W3Byb3BOYW1lXS5wdXNoKGpPYmplY3QpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFJlY3Vyc2l2ZWx5IGNyZWF0ZSB2YWxpZGF0b3IgZm9ybSBncm91cHMgZm9yIGVhY2ggb2JqZWN0ICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlVmFsaWRhdG9yRm9ybUdyb3VwKHJvdywgak9iamVjdCwgcHJvcE1vZGVsSW5zdGFuY2UuY29uc3RydWN0b3IsIHZhbGlkYXRvckNvbmZpZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9wID09IE9CSkVDVF9TVFJJTkcgJiYgIShwcm9wIGluc3RhbmNlb2YgRm9ybUNvbnRyb2wgfHwgcHJvcCBpbnN0YW5jZW9mIFJ4Rm9ybUNvbnRyb2wpKSB7XHJcbiAgICAgICAgICAgICAgICAvKiBEZXRlcm1pbmUgdGhlIGZvcm1Hcm91cCBiYXNlZCBvbiB0aGUgdHlwZSBvZiAncHJvcCcgKi9cclxuICAgICAgICAgICAgICAgIGxldCBmb3JtR3JvdXA6IGFueSA9IChwcm9wIGluc3RhbmNlb2YgRm9ybUFycmF5KSA/IHByb3AuY29udHJvbHNbMF0gOiBwcm9wO1xyXG5cclxuICAgICAgICAgICAgICAgIC8qIElmICdwcm9wJyBpcyBhIEZvcm1Hcm91cCBvciBSeEZvcm1Hcm91cCBhbmQgZG9lcyBub3QgaGF2ZSBhIG1vZGVsLCBjcmVhdGUgYSBmb3JtIGdyb3VwICovXHJcbiAgICAgICAgICAgICAgICBpZiAoIWZvcm1Hcm91cC5tb2RlbCAmJiAocHJvcCBpbnN0YW5jZW9mIEZvcm1Hcm91cCB8fCBwcm9wIGluc3RhbmNlb2YgUnhGb3JtR3JvdXApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybUdyb3VwID0gdGhpcy5ncm91cChmb3JtR3JvdXAuY29udHJvbHMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qIElmICdwcm9wJyBpcyBhIEZvcm1Hcm91cCBvciBSeEZvcm1Hcm91cCwgaW5pdGlhbGl6ZSB0aGUgcHJvcGVydHkgYXMgYW4gb2JqZWN0ICovXHJcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbnN0YW5jZW9mIEZvcm1Hcm91cCB8fCBwcm9wIGluc3RhbmNlb2YgUnhGb3JtR3JvdXApIHtcclxuICAgICAgICAgICAgICAgICAgICBlbnRpdHlPYmplY3RbcHJvcE5hbWVdID0gcHJvcDtcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Q29udGFpbmVyLmluaXRQcm9wZXJ0eU9iamVjdChwcm9wTmFtZSwgT0JKRUNUX1BST1BFUlRZLCBmb3JtR3JvdXAubW9kZWwsIG1vZGVsSW5zdGFuY2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLyogSWYgJ3Byb3AnIGlzIGEgRm9ybUFycmF5LCBpbml0aWFsaXplIHRoZSBwcm9wZXJ0eSBhcyBhbiBhcnJheSAqL1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAocHJvcCBpbnN0YW5jZW9mIEZvcm1BcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVudGl0eU9iamVjdFtwcm9wTmFtZV0gPSBwcm9wO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRDb250YWluZXIuaW5pdFByb3BlcnR5T2JqZWN0KHByb3BOYW1lLCBBUlJBWV9QUk9QRVJUWSwgZm9ybUdyb3VwLm1vZGVsLCBtb2RlbEluc3RhbmNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8qIElmICdwcm9wJyBpcyBuZWl0aGVyIGEgRm9ybUdyb3VwL1J4Rm9ybUdyb3VwIG5vciBhIEZvcm1BcnJheSAqL1xyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLyogQ2hlY2sgaWYgZHluYW1pYyB2YWxpZGF0aW9uIGlzIHJlcXVpcmVkIGZvciB0aGUgcHJvcGVydHkgKi9cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5keW5hbWljVmFsaWRhdGlvblByb3BDaGVjayhwcm9wTmFtZSwgdmFsaWRhdG9yQ29uZmlnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIHByb3BlcnR5IGZvciBkeW5hbWljIHZhbGlkYXRpb24gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3JbcHJvcE5hbWVdID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNldCB0aGUgY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciB0byB0aGUgY3VycmVudCBwcm9wZXJ0eSAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRGb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3IgPSB0aGlzLmZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvcltwcm9wTmFtZV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2UgZm9yIHRoZSBwcm9wZXJ0eSBtb2RlbCAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcHJvcE1vZGVsSW5zdGFuY2UgPSBzdXBlci5jcmVhdGVJbnN0YW5jZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogSW5pdGlhbGl6ZSB0aGUgcHJvcGVydHkgb2JqZWN0ICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eU9iamVjdFtwcm9wTmFtZV0gPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5T2JqZWN0W3Byb3BOYW1lXS5jb25zdHJ1Y3RvciA9IHByb3BNb2RlbEluc3RhbmNlLmNvbnN0cnVjdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Q29udGFpbmVyLmluaXRQcm9wZXJ0eU9iamVjdChwcm9wTmFtZSwgT0JKRUNUX1BST1BFUlRZLCBlbnRpdHlPYmplY3RbcHJvcE5hbWVdLmNvbnN0cnVjdG9yLCBtb2RlbEluc3RhbmNlLmNvbnN0cnVjdG9yID09IEZ1bmN0aW9uID8geyBjb25zdHJ1Y3RvcjogbW9kZWxJbnN0YW5jZSB9IDogbW9kZWxJbnN0YW5jZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBHZXQgdGhlIHZhbGlkYXRpb24gY29uZmlndXJhdGlvbiBmb3IgdGhlIHByb3BlcnR5ICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBvYmplY3RWYWxpZGF0aW9uQ29uZmlnID0gdGhpcy5nZXRWYWxpZGF0b3JDb25maWcodmFsaWRhdG9yQ29uZmlnLCBncm91cE9iamVjdCwgcHJvcE5hbWUgKyBcIi5cIik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBSZWN1cnNpdmVseSBjcmVhdGUgdGhlIHZhbGlkYXRvciBmb3JtIGdyb3VwIGZvciB0aGUgcHJvcGVydHkgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVWYWxpZGF0b3JGb3JtR3JvdXAoZ3JvdXBPYmplY3RbcHJvcE5hbWVdLCBlbnRpdHlPYmplY3RbcHJvcE5hbWVdLCBlbnRpdHlPYmplY3RbcHJvcE5hbWVdLmNvbnN0cnVjdG9yLCBvYmplY3RWYWxpZGF0aW9uQ29uZmlnKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIHByb3BlcnR5IHdpdGhvdXQgZHluYW1pYyB2YWxpZGF0aW9uICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eU9iamVjdFtwcm9wTmFtZV0gPSBncm91cE9iamVjdFtwcm9wTmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBBc3NpZ24gcHJvcGVydHkgdmFsdWUgaWYgaXQncyBvZiBzaW1wbGUgdHlwZSAqL1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHByb3AgPT0gU1RSSU5HIHx8IHR5cGVvZiBwcm9wID09IE5VTUJFUiB8fCB0eXBlb2YgcHJvcCA9PSBCT09MRUFOIHx8IHByb3AgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgICAgICAgICAgICBlbnRpdHlPYmplY3RbcHJvcE5hbWVdID0gcHJvcFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBBc3NpZ24gcHJvcGVydHkgdmFsdWUgaWYgaXQncyBhbiBhcnJheSBvciBvYmplY3QgKi9cclxuICAgICAgICAgICAgZWxzZSBpZiAoKHByb3AgJiYgcHJvcC5sZW5ndGggPiAwICYmIHRoaXMuaXNOb3RPYmplY3QocHJvcFswXSkgJiYgIShwcm9wIGluc3RhbmNlb2YgRm9ybUNvbnRyb2wgfHwgcHJvcCBpbnN0YW5jZW9mIFJ4Rm9ybUNvbnRyb2wpICYmICEocHJvcCBpbnN0YW5jZW9mIEZvcm1BcnJheSkpKSB7XHJcbiAgICAgICAgICAgICAgICBlbnRpdHlPYmplY3RbcHJvcE5hbWVdID0gcHJvcFswXVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBBc3NpZ24gcHJvcGVydHkgdmFsdWUgaWYgaXQncyBhIEZvcm1BcnJheSAqL1xyXG4gICAgICAgICAgICBlbHNlIGlmIChwcm9wIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XHJcbiAgICAgICAgICAgICAgICBlbnRpdHlPYmplY3RbcHJvcE5hbWVdID0gcHJvcFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBBc3NpZ24gcHJvcGVydHkgdmFsdWUgaWYgaXQncyBhIEZvcm1Db250cm9sICovXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHByb3AgaW5zdGFuY2VvZiBGb3JtQ29udHJvbCB8fCBwcm9wIGluc3RhbmNlb2YgUnhGb3JtQ29udHJvbCkge1xyXG4gICAgICAgICAgICAgICAgZW50aXR5T2JqZWN0W3Byb3BOYW1lXSA9IHByb3BcclxuICAgICAgICAgICAgICAgIGRlZmF1bHRDb250YWluZXIuaW5pdFByb3BlcnR5T2JqZWN0KHByb3BOYW1lLCBQUk9QRVJUWSwgdW5kZWZpbmVkLCBtb2RlbEluc3RhbmNlLmNvbnN0cnVjdG9yID8gbW9kZWxJbnN0YW5jZSA6IHsgY29uc3RydWN0b3I6IG1vZGVsSW5zdGFuY2UgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIHZhbGlkYXRvciBjb25maWd1cmF0aW9uIGZvciBhIGdpdmVuIGVudGl0eSBvYmplY3QgYW5kIHJvb3QgcHJvcGVydHkgbmFtZS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHZhbGlkYXRvckNvbmZpZyBUaGUgdmFsaWRhdG9yIGNvbmZpZ3VyYXRpb24gdG8gcHJvY2Vzcy5cclxuICAgICAqIEBwYXJhbSBlbnRpdHlPYmplY3QgVGhlIGVudGl0eSBvYmplY3QgZm9yIHdoaWNoIHRoZSB2YWxpZGF0b3IgY29uZmlndXJhdGlvbiBpcyBhcHBsaWVkLlxyXG4gICAgICogQHBhcmFtIHJvb3RQcm9wZXJ0eU5hbWUgVGhlIHJvb3QgcHJvcGVydHkgbmFtZSB0byBjb25zaWRlci5cclxuICAgICAqIEBwYXJhbSBhcnJheVByb3BlcnR5TmFtZSBPcHRpb25hbC4gVGhlIGFycmF5IHByb3BlcnR5IG5hbWUgdG8gY29uc2lkZXIuXHJcbiAgICAgKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvY2Vzc2VkIHZhbGlkYXRvciBjb25maWd1cmF0aW9uLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldFZhbGlkYXRvckNvbmZpZyh2YWxpZGF0b3JDb25maWc6IEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiwgZW50aXR5T2JqZWN0OiBhbnksIHJvb3RQcm9wZXJ0eU5hbWU6IHN0cmluZywgYXJyYXlQcm9wZXJ0eU5hbWU/OiBzdHJpbmcpOiBhbnkge1xyXG4gICAgICAgIGxldCBleGNsdWRlUHJvcHM6IGFueVtdID0gW107XHJcbiAgICAgICAgbGV0IGluY2x1ZGVQcm9wczogYW55W10gPSBbXTtcclxuICAgICAgICBsZXQgaWdub3JlVW5kZWZpbmVkUHJvcHM6IGFueVtdID0gW107XHJcblxyXG4gICAgICAgIC8qIENoZWNrIGlmIHRoZSB2YWxpZGF0b3JDb25maWcgZXhpc3RzICovXHJcbiAgICAgICAgaWYgKCF2YWxpZGF0b3JDb25maWcpIHJldHVybiB7fTtcclxuXHJcbiAgICAgICAgLyogUmV0cmlldmUgdmFsaWRhdGlvbiBwcm9wZXJ0aWVzIGFuZCBhYnN0cmFjdCBjb250cm9sIG9wdGlvbnMgKi9cclxuICAgICAgICBjb25zdCB2YWxpZGF0aW9uUHJvcHMgPSB0aGlzLmdldE9iamVjdEZvclByb3BlcnR5KHZhbGlkYXRvckNvbmZpZy5keW5hbWljVmFsaWRhdGlvbiEsIHJvb3RQcm9wZXJ0eU5hbWUsIGFycmF5UHJvcGVydHlOYW1lKTtcclxuICAgICAgICBjb25zdCBhYnN0cmFjdENvbnRyb2xPcHRpb25zID0gdGhpcy5nZXRPYmplY3RGb3JQcm9wZXJ0eSh2YWxpZGF0b3JDb25maWcuYWJzdHJhY3RDb250cm9sT3B0aW9ucyEsIHJvb3RQcm9wZXJ0eU5hbWUsIGFycmF5UHJvcGVydHlOYW1lKTtcclxuXHJcbiAgICAgICAgLyogUG9wdWxhdGUgZXhjbHVkZVByb3BzLCBpbmNsdWRlUHJvcHMsIGFuZCBpZ25vcmVVbmRlZmluZWRQcm9wcyBhcnJheXMgKi9cclxuICAgICAgICBpZiAodmFsaWRhdG9yQ29uZmlnLmV4Y2x1ZGVQcm9wcykge1xyXG4gICAgICAgICAgICBleGNsdWRlUHJvcHMgPSB0aGlzLmdldFByb3BzKHZhbGlkYXRvckNvbmZpZy5leGNsdWRlUHJvcHMsIHJvb3RQcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHZhbGlkYXRvckNvbmZpZy5pbmNsdWRlUHJvcHMpIHtcclxuICAgICAgICAgICAgaW5jbHVkZVByb3BzID0gdGhpcy5nZXRQcm9wcyh2YWxpZGF0b3JDb25maWcuaW5jbHVkZVByb3BzLCByb290UHJvcGVydHlOYW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh2YWxpZGF0b3JDb25maWcuaWdub3JlVW5kZWZpbmVkUHJvcHMpIHtcclxuICAgICAgICAgICAgaWdub3JlVW5kZWZpbmVkUHJvcHMgPSB0aGlzLmdldFByb3BzKHZhbGlkYXRvckNvbmZpZy5pZ25vcmVVbmRlZmluZWRQcm9wcywgcm9vdFByb3BlcnR5TmFtZSwgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBBcHBlbmQgZ2xvYmFsIGFic3RyYWN0IGNvbnRyb2wgb3B0aW9ucyBpZiBub3QgZm91bmQgKi9cclxuICAgICAgICBpZiAoIU9iamVjdC5rZXlzKGFic3RyYWN0Q29udHJvbE9wdGlvbnMpLmxlbmd0aCAmJiByb290UHJvcGVydHlOYW1lLmVuZHNXaXRoKCcuJykgJiYgdmFsaWRhdG9yQ29uZmlnLmFic3RyYWN0Q29udHJvbE9wdGlvbnMgJiYgdmFsaWRhdG9yQ29uZmlnLmFic3RyYWN0Q29udHJvbE9wdGlvbnNbcm9vdFByb3BlcnR5TmFtZS5zdWJzdHJpbmcoMCwgcm9vdFByb3BlcnR5TmFtZS5sZW5ndGggLSAxKV0pIHtcclxuICAgICAgICAgICAgYWJzdHJhY3RDb250cm9sT3B0aW9uc1snZ2xvYmFsJ10gPSB2YWxpZGF0b3JDb25maWcuYWJzdHJhY3RDb250cm9sT3B0aW9uc1tyb290UHJvcGVydHlOYW1lLnN1YnN0cmluZygwLCByb290UHJvcGVydHlOYW1lLmxlbmd0aCAtIDEpXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIFJldHJpZXZlIGR5bmFtaWMgdmFsaWRhdGlvbiBjb25maWd1cmF0aW9uICovXHJcbiAgICAgICAgY29uc3QgZHluYW1pY1ZhbGlkYXRpb24gPSAodmFsaWRhdG9yQ29uZmlnLmR5bmFtaWNWYWxpZGF0aW9uQ29uZmlndXJhdGlvblByb3BlcnR5TmFtZSAmJiBlbnRpdHlPYmplY3RbdmFsaWRhdG9yQ29uZmlnLmR5bmFtaWNWYWxpZGF0aW9uQ29uZmlndXJhdGlvblByb3BlcnR5TmFtZV0pID8gZW50aXR5T2JqZWN0W3ZhbGlkYXRvckNvbmZpZy5keW5hbWljVmFsaWRhdGlvbkNvbmZpZ3VyYXRpb25Qcm9wZXJ0eU5hbWVdIDogdmFsaWRhdGlvblByb3BzO1xyXG5cclxuICAgICAgICAvKiBSZXR1cm4gcHJvY2Vzc2VkIHZhbGlkYXRvciBjb25maWd1cmF0aW9uICovXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgaWdub3JlVW5kZWZpbmVkUHJvcHM6IGlnbm9yZVVuZGVmaW5lZFByb3BzLFxyXG4gICAgICAgICAgICBpbmNsdWRlUHJvcHM6IGluY2x1ZGVQcm9wcyxcclxuICAgICAgICAgICAgZHluYW1pY1ZhbGlkYXRpb246IGR5bmFtaWNWYWxpZGF0aW9uLFxyXG4gICAgICAgICAgICBleGNsdWRlUHJvcHM6IGV4Y2x1ZGVQcm9wcyxcclxuICAgICAgICAgICAgYWJzdHJhY3RDb250cm9sT3B0aW9uczogYWJzdHJhY3RDb250cm9sT3B0aW9uc1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHJpZXZlcyB0aGUgb2JqZWN0IHByb3BlcnRpZXMgbWF0Y2hpbmcgdGhlIHNwZWNpZmllZCByb290IHByb3BlcnR5IG5hbWUgYW5kIGFycmF5IHByb3BlcnR5IG5hbWUgKGlmIHByb3ZpZGVkKS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHJvb3RPYmplY3QgVGhlIHJvb3Qgb2JqZWN0IHRvIHNlYXJjaCBmb3IgcHJvcGVydGllcy5cclxuICAgICAqIEBwYXJhbSByb290UHJvcGVydHlOYW1lIFRoZSByb290IHByb3BlcnR5IG5hbWUgdG8gbWF0Y2ggYWdhaW5zdC5cclxuICAgICAqIEBwYXJhbSBhcnJheVByb3BlcnR5TmFtZSBPcHRpb25hbC4gVGhlIGFycmF5IHByb3BlcnR5IG5hbWUgdG8gbWF0Y2ggYWdhaW5zdC5cclxuICAgICAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIG1hdGNoaW5nIHRoZSByb290IHByb3BlcnR5IG5hbWUgYW5kIGFycmF5IHByb3BlcnR5IG5hbWUgKGlmIHByb3ZpZGVkKS5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRPYmplY3RGb3JQcm9wZXJ0eTxUPihyb290T2JqZWN0OiB7IFtrZXk6IHN0cmluZ106IFQgfSwgcm9vdFByb3BlcnR5TmFtZTogc3RyaW5nLCBhcnJheVByb3BlcnR5TmFtZT86IHN0cmluZyk6IHsgW2tleTogc3RyaW5nXTogVCB9IHtcclxuICAgICAgICBjb25zdCByZXN1bHQ6IHsgW2tleTogc3RyaW5nXTogVCB9ID0ge307XHJcblxyXG4gICAgICAgIC8qIEl0ZXJhdGUgdGhyb3VnaCB0aGUgcHJvcGVydGllcyBvZiB0aGUgcm9vdCBvYmplY3QgKi9cclxuICAgICAgICBmb3IgKGxldCBwcm9wTmFtZSBpbiByb290T2JqZWN0KSB7XHJcbiAgICAgICAgICAgIC8qIFNraXAgcHJvcGVydGllcyB0aGF0IGRvIG5vdCBtYXRjaCB0aGUgcm9vdFByb3BlcnR5TmFtZSBvciBhcnJheVByb3BlcnR5TmFtZSAqL1xyXG4gICAgICAgICAgICBpZiAoIXByb3BOYW1lLnN0YXJ0c1dpdGgocm9vdFByb3BlcnR5TmFtZSkgJiYgKCFhcnJheVByb3BlcnR5TmFtZSB8fCAhcHJvcE5hbWUuc3RhcnRzV2l0aChhcnJheVByb3BlcnR5TmFtZSkpKSB7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyogRXh0cmFjdCB0aGUgc3BsaXQgcHJvcGVydHkgbmFtZSAqL1xyXG4gICAgICAgICAgICBsZXQgc3BsaXRQcm9wID0gcHJvcE5hbWUuc3BsaXQoXCIuXCIsIDIpWzFdO1xyXG5cclxuICAgICAgICAgICAgLyogSWYgc3BsaXRQcm9wIGlzIHVuZGVmaW5lZCwgY29udGludWUgdG8gdGhlIG5leHQgcHJvcGVydHkgKi9cclxuICAgICAgICAgICAgaWYgKCFzcGxpdFByb3ApIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBBZGQgdGhlIHByb3BlcnR5IHRvIHRoZSByZXN1bHQgb2JqZWN0ICovXHJcbiAgICAgICAgICAgIHJlc3VsdFtzcGxpdFByb3BdID0gcm9vdE9iamVjdFtwcm9wTmFtZV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHJpZXZlcyB0aGUgcHJvcGVydGllcyBtYXRjaGluZyB0aGUgc3BlY2lmaWVkIHJvb3QgcHJvcGVydHkgbmFtZSBmcm9tIHRoZSBnaXZlbiBhcnJheSBvZiBwcm9wZXJ0aWVzLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gcHJvcGVydGllcyBUaGUgYXJyYXkgb2YgcHJvcGVydGllcyB0byBzZWFyY2guXHJcbiAgICAgKiBAcGFyYW0gcm9vdFByb3BlcnR5TmFtZSBUaGUgcm9vdCBwcm9wZXJ0eSBuYW1lIHRvIG1hdGNoIGFnYWluc3QuXHJcbiAgICAgKiBAcGFyYW0gaXNJZ25vcmVQcm9wIE9wdGlvbmFsLiBJbmRpY2F0ZXMgd2hldGhlciB0byBpbmNsdWRlIHRoZSByb290IHByb3BlcnR5IGl0c2VsZiBhcyBhIHByb3BlcnR5LlxyXG4gICAgICogQHJldHVybnMgQW4gYXJyYXkgY29udGFpbmluZyB0aGUgcHJvcGVydGllcyBtYXRjaGluZyB0aGUgcm9vdCBwcm9wZXJ0eSBuYW1lLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldFByb3BzKHByb3BlcnRpZXM6IHN0cmluZ1tdLCByb290UHJvcGVydHlOYW1lOiBzdHJpbmcsIGlzSWdub3JlUHJvcDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICAgICAgbGV0IHByb3BzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgICAgICAvKiBJdGVyYXRlIHRocm91Z2ggdGhlIHByb3BlcnRpZXMgKi9cclxuICAgICAgICBmb3IgKGxldCBwcm9wIG9mIHByb3BlcnRpZXMpIHtcclxuICAgICAgICAgICAgLyogQ2hlY2sgaWYgdGhlIHByb3BlcnR5IGNvbnRhaW5zIHRoZSByb290UHJvcGVydHlOYW1lICovXHJcbiAgICAgICAgICAgIGlmIChwcm9wLmluZGV4T2Yocm9vdFByb3BlcnR5TmFtZSkgIT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGxldCBzcGxpdFByb3BzID0gcHJvcC5zcGxpdChcIi5cIik7XHJcblxyXG4gICAgICAgICAgICAgICAgLyogSWYgdGhlIHByb3BlcnR5IGhhcyB0d28gcGFydHMsIGFkZCB0aGUgc2Vjb25kIHBhcnQgdG8gdGhlIHByb3BzIGFycmF5ICovXHJcbiAgICAgICAgICAgICAgICBpZiAoc3BsaXRQcm9wcy5sZW5ndGggPT0gMikge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb3BzLnB1c2goc3BsaXRQcm9wc1sxXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyogSWYgdGhlIHByb3BlcnR5IGhhcyBtb3JlIHRoYW4gdHdvIHBhcnRzLCBqb2luIHRoZSBwYXJ0cyBhZnRlciB0aGUgZmlyc3Qgb25lIGFuZCBhZGQgdG8gdGhlIHByb3BzIGFycmF5ICovXHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChzcGxpdFByb3BzLmxlbmd0aCA+IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICBzcGxpdFByb3BzLnNwbGljZSgwLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9wcy5wdXNoKHNwbGl0UHJvcHMuam9pbihcIi5cIikpXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIElmIGlzSWdub3JlUHJvcCBpcyB0cnVlIGFuZCB0aGUgcm9vdCBwcm9wZXJ0eSBpdHNlbGYgaXMgcHJlc2VudCBpbiB0aGUgcHJvcGVydGllcyBhcnJheSwgYWRkICc6c2VsZjonIHRvIHRoZSBwcm9wcyBhcnJheSAqL1xyXG4gICAgICAgIGlmIChpc0lnbm9yZVByb3AgJiYgcHJvcGVydGllcy5maWx0ZXIoeCA9PiB4ID09IHJvb3RQcm9wZXJ0eU5hbWUucmVwbGFjZSgnLicsICcnKSkubGVuZ3RoID09IDEpIHtcclxuICAgICAgICAgICAgcHJvcHMucHVzaCgnOnNlbGY6Jyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcHJvcHM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgZm9ybSBncm91cCBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgbW9kZWwsIGVudGl0eSBvYmplY3QsIGFuZCBmb3JtIGJ1aWxkZXIgY29uZmlndXJhdGlvbi5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIG1vZGVsIFRoZSBtb2RlbCBvciB0eXBlIGRlZmluaXRpb24gdG8gY3JlYXRlIHRoZSBmb3JtIGdyb3VwIGZyb20uXHJcbiAgICAgKiBAcGFyYW0gZW50aXR5T2JqZWN0IE9wdGlvbmFsLiBUaGUgZW50aXR5IG9iamVjdCBmb3Igd2hpY2ggdGhlIGZvcm0gZ3JvdXAgaXMgY3JlYXRlZC5cclxuICAgICAqIEBwYXJhbSBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gT3B0aW9uYWwuIFRoZSBmb3JtIGJ1aWxkZXIgY29uZmlndXJhdGlvbiB0byBjdXN0b21pemUgdGhlIGZvcm0gZ3JvdXAgY3JlYXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyBBbiBpbnN0YW5jZSBvZiBSeEZvcm1Hcm91cCwgRm9ybUdyb3VwLCBvciBBcHBGb3JtR3JvdXA8VD4uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmb3JtR3JvdXA8VD4obW9kZWw6IFR5cGU8VD4gfCB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBlbnRpdHlPYmplY3Q/OiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHwgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24/OiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pOiBSeEZvcm1Hcm91cCB8IEZvcm1Hcm91cCB8IEFwcEZvcm1Hcm91cDxUPiB7XHJcbiAgICAgICAgLyogUmV0cmlldmVzIG5lY2Vzc2FyeSBkYXRhIGZyb20gdGhlIHByb3ZpZGVkIG1vZGVsLCBlbnRpdHkgb2JqZWN0LCBhbmQgZm9ybSBidWlsZGVyIGNvbmZpZ3VyYXRpb24gdG8gY3JlYXRlIGEgZm9ybSBncm91cCAqL1xyXG4gICAgICAgIGxldCBqc29uID0gdGhpcy5nZXRPYmplY3QobW9kZWwsIGVudGl0eU9iamVjdCwgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKTtcclxuICAgICAgICBtb2RlbCA9IGpzb24ubW9kZWw7XHJcbiAgICAgICAgZW50aXR5T2JqZWN0ID0ganNvbi5lbnRpdHlPYmplY3Q7XHJcblxyXG4gICAgICAgIC8qIFxyXG4gICAgICAgICAqIElmIHRoZSBlbnRpdHkgb2JqZWN0J3MgY29uc3RydWN0b3IgZGlmZmVycyBmcm9tIHRoZSBtb2RlbCdzIGNvbnN0cnVjdG9yIGFuZCBmb3JtR3JvdXAgaXMgbm90IHByZXZpb3VzbHkgY2FsbGVkLFxyXG4gICAgICAgICAqIHVwZGF0ZSB0aGUgZW50aXR5IG9iamVjdCB0byBtYXRjaCB0aGUgbW9kZWwuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaWYgKGVudGl0eU9iamVjdCEuY29uc3RydWN0b3IgIT0gbW9kZWwgJiYgIXRoaXMuaXNHcm91cENhbGxlZCkge1xyXG4gICAgICAgICAgICBlbnRpdHlPYmplY3QgPSBqc29uLmVudGl0eU9iamVjdCA9IHRoaXMudXBkYXRlT2JqZWN0KG1vZGVsLCBqc29uLmVudGl0eU9iamVjdCwgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uISk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gPSBqc29uLmZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbjtcclxuXHJcbiAgICAgICAgLyogRXh0cmFjdCBleHByZXNzaW9ucyBmcm9tIHRoZSBmb3JtIGJ1aWxkZXIgY29uZmlndXJhdGlvbiBpZiBwcm92aWRlZC4gKi9cclxuICAgICAgICBpZiAoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXh0cmFjdEV4cHJlc3Npb25zKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBHZXQgdGhlIGNvbnRhaW5lciBmb3IgaW5zdGFuY2VzIGJhc2VkIG9uIHRoZSBtb2RlbCBhbmQgZW50aXR5IG9iamVjdC4gKi9cclxuICAgICAgICBsZXQgaW5zdGFuY2VDb250YWluZXI6IEluc3RhbmNlQ29udGFpbmVyID0gdGhpcy5nZXRJbnN0YW5jZUNvbnRhaW5lcihtb2RlbCwgZW50aXR5T2JqZWN0KTtcclxuXHJcbiAgICAgICAgLyogQ2hlY2sgYW5kIGFwcGx5IGFkZGl0aW9uYWwgdmFsaWRhdGlvbiBmb3Igb2JqZWN0IHByb3BlcnRpZXMuICovXHJcbiAgICAgICAgdGhpcy5jaGVja09iamVjdFByb3BBZGRpdGlvbmFsVmFsaWRhdGlvbihpbnN0YW5jZUNvbnRhaW5lciwgZW50aXR5T2JqZWN0LCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24hKTtcclxuXHJcbiAgICAgICAgLyogSW5pdGlhbGl6ZSB2YXJpYWJsZXMgZm9yIGZvcm0gZ3JvdXAgY3JlYXRpb24uICovXHJcbiAgICAgICAgbGV0IGZvcm1Hcm91cE9iamVjdCA9IHt9O1xyXG4gICAgICAgIGxldCBleHRlbmRlZFByb3BlcnRpZXMgPSB7fTtcclxuICAgICAgICB2YXIgYWRkaXRpb25hbFZhbGlkYXRpb25zOiB7IFtrZXk6IHN0cmluZ106IFByb3BWYWxpZGF0aW9uQ29uZmlnIH0gPSB7fTtcclxuXHJcbiAgICAgICAgLyogSXRlcmF0ZSB0aHJvdWdoIHByb3BlcnRpZXMgZGVmaW5lZCBpbiB0aGUgaW5zdGFuY2UgY29udGFpbmVyLiAqL1xyXG4gICAgICAgIGluc3RhbmNlQ29udGFpbmVyLnByb3BlcnRpZXM/LmZvckVhY2gocHJvcGVydHkgPT4ge1xyXG4gICAgICAgICAgICBsZXQgaXNJbmNsdWRlUHJvcCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAvKiBDaGVjayBpZiB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIGluY2x1ZGVkIGJhc2VkIG9uIGZvcm0gYnVpbGRlciBjb25maWd1cmF0aW9uLiAqL1xyXG4gICAgICAgICAgICBpZiAoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAvKiBDaGVjayBpZiB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIGV4Y2x1ZGVkIGJhc2VkIG9uIGZvcm0gYnVpbGRlciBjb25maWd1cmF0aW9uLiAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5leGNsdWRlUHJvcHMgJiYgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmV4Y2x1ZGVQcm9wcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNJbmNsdWRlUHJvcCA9IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5leGNsdWRlUHJvcHMuaW5kZXhPZihwcm9wZXJ0eS5uYW1lKSA9PSAtMTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKiBDaGVjayBpZiBkeW5hbWljIHZhbGlkYXRpb24gaXMgcHJvdmlkZWQgaW4gdGhlIGZvcm0gYnVpbGRlciBjb25maWd1cmF0aW9uLiAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5keW5hbWljVmFsaWRhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxWYWxpZGF0aW9ucyA9IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5keW5hbWljVmFsaWRhdGlvbjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKiBDaGVjayBpZiB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIGluY2x1ZGVkIGJhc2VkIG9uIGZvcm0gYnVpbGRlciBjb25maWd1cmF0aW9uLiAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5pbmNsdWRlUHJvcHMgJiYgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmluY2x1ZGVQcm9wcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNJbmNsdWRlUHJvcCA9IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5pbmNsdWRlUHJvcHMuaW5kZXhPZihwcm9wZXJ0eS5uYW1lKSAhPSAtMTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKiBDaGVjayBpZiB1bmRlZmluZWQgcHJvcGVydGllcyBzaG91bGQgYmUgaWdub3JlZCBiYXNlZCBvbiBmb3JtIGJ1aWxkZXIgY29uZmlndXJhdGlvbi4gKi9cclxuICAgICAgICAgICAgICAgIGlmIChmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uaWdub3JlVW5kZWZpbmVkUHJvcHMgJiYgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmlnbm9yZVVuZGVmaW5lZFByb3BzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpc0luY2x1ZGVQcm9wID0gIShcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHkucHJvcGVydHlUeXBlID09IFBST1BFUlRZICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICFSZWdleFZhbGlkYXRvci5pc05vdEJsYW5rKGpzb24uZW50aXR5T2JqZWN0W3Byb3BlcnR5Lm5hbWVdKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uaWdub3JlVW5kZWZpbmVkUHJvcHMuaW5kZXhPZihwcm9wZXJ0eS5uYW1lKSAhPT0gLTEgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5pZ25vcmVVbmRlZmluZWRQcm9wcy5pbmRleE9mKFwiOnNlbGY6XCIpICE9PSAtMVxyXG4gICAgICAgICAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHByb3BlcnR5Lmlnbm9yZSkge1xyXG4gICAgICAgICAgICAgICAgaXNJbmNsdWRlUHJvcCA9ICFwcm9wZXJ0eS5pZ25vcmUuY2FsbChqc29uLmVudGl0eU9iamVjdCwganNvbi5lbnRpdHlPYmplY3QpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBJZiB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIGluY2x1ZGVkLCBjcmVhdGUgZm9ybSBjb250cm9scywgZm9ybSBncm91cHMsIG9yIGZvcm0gYXJyYXlzIGJhc2VkIG9uIGl0cyB0eXBlLiAqL1xyXG4gICAgICAgICAgICBpZiAoaXNJbmNsdWRlUHJvcCkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChwcm9wZXJ0eS5wcm9wZXJ0eVR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFBST1BFUlRZOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBJZiB0aGUgcHJvcGVydHkgaXMgbm90IGFscmVhZHkgYSBmb3JtIGNvbnRyb2wsIGNyZWF0ZSBvbmUgd2l0aCBhcHByb3ByaWF0ZSB2YWxpZGF0b3JzIGFuZCBvcHRpb25zICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKChlbnRpdHlPYmplY3QgYXMgYW55KVtwcm9wZXJ0eS5uYW1lXSBpbnN0YW5jZW9mIEZvcm1Db250cm9sIHx8IChlbnRpdHlPYmplY3QgYXMgYW55KVtwcm9wZXJ0eS5uYW1lXSBpbnN0YW5jZW9mIFJ4Rm9ybUNvbnRyb2wpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBFeHRyYWN0IHByb3BlcnR5IHZhbGlkYXRvcnMgYmFzZWQgb24gYW5ub3RhdGlvbnMuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcHJvcGVydHlWYWxpZGF0b3JzID0gaW5zdGFuY2VDb250YWluZXIucHJvcGVydHlBbm5vdGF0aW9ucy5maWx0ZXIodCA9PiB0LnByb3BlcnR5TmFtZSA9PSBwcm9wZXJ0eS5uYW1lICYmIHQuaXNWYWxpZGF0b3IpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEV4dHJhY3QgdXBkYXRlT24gY29uZmlndXJhdGlvbiBiYXNlZCBvbiBhbm5vdGF0aW9ucy4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB1cGRhdGVPbiA9IGluc3RhbmNlQ29udGFpbmVyLnByb3BlcnR5QW5ub3RhdGlvbnMuZmlsdGVyKHQgPT4gdC5wcm9wZXJ0eU5hbWUgPT0gcHJvcGVydHkubmFtZSAmJiAhdC5pc1ZhbGlkYXRvciAmJiB0LmFubm90YXRpb25UeXBlID09PSBcInVwZGF0ZU9uXCIpWzBdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFJldHJpZXZlIHRoZSB2YWx1ZSBmcm9tIGVudGl0eU9iamVjdCBiYXNlZCBvbiB2YWx1ZVBhdGggb3IgcHJvcGVydHkgbmFtZSwgb3IgdXNlIHRoZSBjdXN0b20gdmFsdWUgZnVuY3Rpb24gaWYgcHJvdmlkZWQgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHByb3BlcnR5LnZhbHVlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBwcm9wZXJ0eS52YWx1ZShlbnRpdHlPYmplY3QpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAocHJvcGVydHkudmFsdWVQYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gVXRpbHMuZ2V0UHJvcGVydHlWYWx1ZShlbnRpdHlPYmplY3QsIHByb3BlcnR5LnZhbHVlUGF0aClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoZW50aXR5T2JqZWN0IGFzIGFueSlbcHJvcGVydHkubmFtZV0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNhbml0aXplIHRoZSBwcm9wZXJ0eSB2YWx1ZS4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzYW5pdGl6ZVZhbHVlID0gc3VwZXIuc2FuaXRpemVWYWx1ZShpbnN0YW5jZUNvbnRhaW5lciwgcHJvcGVydHkubmFtZSwgc3VwZXIuZ2V0RGVmYXVsdFZhbHVlKHByb3BlcnR5LCB2YWx1ZSwgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uISksIGpzb24uZW50aXR5T2JqZWN0LCBPYmplY3QuYXNzaWduKHt9LCBqc29uLmVudGl0eU9iamVjdCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIElmIHRoZSBwcm9wZXJ0eSB2YWx1ZSBpcyB1bmRlZmluZWQgYW5kIHRoZXJlIGlzIGEgc2FuaXRpemVkIHZhbHVlLCBhc3NpZ24gaXQuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGVudGl0eU9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdID09PSB1bmRlZmluZWQgJiYgc2FuaXRpemVWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlbnRpdHlPYmplY3QgYXMgYW55KVtwcm9wZXJ0eS5uYW1lXSA9IHNhbml0aXplVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQWRkIGZvcm0gY29udHJvbCB2YWxpZGF0b3JzLiAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHZhbGlkYXRvcnMgPSB0aGlzLmFkZEZvcm1Db250cm9sKHByb3BlcnR5LCBwcm9wZXJ0eVZhbGlkYXRvcnMsIGFkZGl0aW9uYWxWYWxpZGF0aW9uc1twcm9wZXJ0eS5uYW1lXSwgaW5zdGFuY2VDb250YWluZXIsIGVudGl0eU9iamVjdCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRGVmaW5lIGFic3RyYWN0IGNvbnRyb2wgb3B0aW9ucyBpbmNsdWRpbmcgdmFsaWRhdG9ycyBhbmQgYXN5bmMgdmFsaWRhdG9ycy4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhYnN0cmFjdENvbnRyb2xPcHRpb25zOiBBYnN0cmFjdENvbnRyb2xPcHRpb25zID0geyB2YWxpZGF0b3JzOiB2YWxpZGF0b3JzLCBhc3luY1ZhbGlkYXRvcnM6IHRoaXMuYWRkQXN5bmNWYWxpZGF0aW9uKHByb3BlcnR5LCBwcm9wZXJ0eVZhbGlkYXRvcnMsIGFkZGl0aW9uYWxWYWxpZGF0aW9uc1twcm9wZXJ0eS5uYW1lXSkgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBSZXRyaWV2ZSBhZGRpdGlvbmFsIGFic3RyYWN0IGNvbnRyb2wgb3B0aW9ucyBiYXNlZCBvbiBwcm9wZXJ0eSBuYW1lLiAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJzdHJhY3RDb250cm9sT3B0aW9ucyA9IHRoaXMuZ2V0QWJzdHJhY3RDb250cm9sT3B0aW9ucyhwcm9wZXJ0eS5uYW1lLCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24hLCBhYnN0cmFjdENvbnRyb2xPcHRpb25zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBBc3NpZ24gdXBkYXRlT24gY29uZmlndXJhdGlvbiBpZiBhdmFpbGFibGUuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXBkYXRlT24gJiYgIWFic3RyYWN0Q29udHJvbE9wdGlvbnMudXBkYXRlT24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYnN0cmFjdENvbnRyb2xPcHRpb25zLnVwZGF0ZU9uID0gdXBkYXRlT24uY29uZmlnLnJ1bk9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIENyZWF0ZSBhIG5ldyBmb3JtIGNvbnRyb2wgaW5zdGFuY2UuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9ybUdyb3VwT2JqZWN0IGFzIGFueSlbcHJvcGVydHkubmFtZV0gPSBuZXcgUnhGb3JtQ29udHJvbChzYW5pdGl6ZVZhbHVlLCBhYnN0cmFjdENvbnRyb2xPcHRpb25zLCBqc29uLmVudGl0eU9iamVjdCwgT2JqZWN0LmFzc2lnbih7fSwganNvbi5lbnRpdHlPYmplY3QpLCBwcm9wZXJ0eS5uYW1lLCBpbnN0YW5jZUNvbnRhaW5lci5zYW5pdGl6ZXJzIVtwcm9wZXJ0eS5uYW1lXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhlIHByb3BlcnR5IGlzIGFscmVhZHkgYSBmb3JtIGNvbnRyb2wsIHVzZSBpdHMgZGVmYXVsdCB2YWx1ZS4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb3JtR3JvdXBPYmplY3QgYXMgYW55KVtwcm9wZXJ0eS5uYW1lXSA9IHN1cGVyLmdldERlZmF1bHRWYWx1ZShwcm9wZXJ0eSwgKGVudGl0eU9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdLCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24hKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogTWFyayB0aGUgcHJvcGVydHkgYXMgZXh0ZW5kZWQgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgKGV4dGVuZGVkUHJvcGVydGllcyBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIE9CSkVDVF9QUk9QRVJUWTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG9iamVjdFZhbHVlID0gKGVudGl0eU9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhlIHByb3BlcnR5IGlzIGFuIG9iamVjdCBhbmQgbm90IGEgZm9ybSBncm91cCwgcmVjdXJzaXZlbHkgY3JlYXRlIGEgZm9ybSBncm91cCBmb3IgaXQgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9iamVjdFZhbHVlICYmIG9iamVjdFZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmICEob2JqZWN0VmFsdWUgaW5zdGFuY2VvZiBGb3JtR3JvdXAgfHwgb2JqZWN0VmFsdWUgaW5zdGFuY2VvZiBSeEZvcm1Hcm91cCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNldCBmbGFncyB0byBpbmRpY2F0ZSBuZXN0ZWQgYmluZGluZy4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNOZXN0ZWRCaW5kaW5nID0gdGhpcy5pc05lc3RlZCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRmlsdGVyIGNvbmRpdGlvbmFsIG9iamVjdCBwcm9wZXJ0aWVzIGJhc2VkIG9uIHRoZSBjdXJyZW50IHByb3BlcnR5IG5hbWUuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VDb250YWluZXIgJiYgaW5zdGFuY2VDb250YWluZXIuY29uZGl0aW9uYWxPYmplY3RQcm9wcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uYWxPYmplY3RQcm9wcyA9IGluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMuZmlsdGVyKCh0OiBhbnkpID0+IHQub2JqZWN0UHJvcE5hbWUgPT0gcHJvcGVydHkubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRmlsdGVyIGNvbmRpdGlvbmFsIG9iamVjdCBwcm9wZXJ0aWVzIGZvciBidWlsZGVyIGNvbmZpZ3VyYXRpb24gYmFzZWQgb24gdGhlIGN1cnJlbnQgcHJvcGVydHkgbmFtZS4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlICYmIHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UuY29uZGl0aW9uYWxPYmplY3RQcm9wcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzID0gdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbE9iamVjdFByb3BzLmZpbHRlcigodDogYW55KSA9PiB0Lm9iamVjdFByb3BOYW1lID09IHByb3BlcnR5Lm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNldCB0aGUgY3VycmVudCBmb3JtIGdyb3VwIG90aGVyIHZhbGlkYXRvciBpZiBhdmFpbGFibGUuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3JbcHJvcGVydHkubmFtZV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRGb3JtR3JvdXBQcm9wT3RoZXJWYWxpZGF0b3IgPSB0aGlzLmZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvcltwcm9wZXJ0eS5uYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBPYnRhaW4gdmFsaWRhdGlvbiBjb25maWd1cmF0aW9uIGZvciB0aGUgbmVzdGVkIG9iamVjdC4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBvYmplY3RWYWxpZGF0aW9uQ29uZmlnID0gdGhpcy5nZXRWYWxpZGF0b3JDb25maWcoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uISwgb2JqZWN0VmFsdWUsIGAke3Byb3BlcnR5Lm5hbWV9LmApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE9idGFpbiB0aGUgZW50aXR5IHRvIHVzZSBmb3IgdGhlIG5lc3RlZCBvYmplY3QuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZW50aXR5ID0gcHJvcGVydHkuZW50aXR5UHJvdmlkZXIgPyBwcm9wZXJ0eS5lbnRpdHlQcm92aWRlci5jYWxsKGVudGl0eU9iamVjdCkgOiB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQ3JlYXRlIGEgZm9ybSBncm91cCBmb3IgdGhlIG5lc3RlZCBvYmplY3QuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9ybUdyb3VwT2JqZWN0IGFzIGFueSlbcHJvcGVydHkubmFtZV0gPSB0aGlzLmZvcm1Hcm91cChlbnRpdHkgfHwgcHJvcGVydHkuZW50aXR5IHx8IHRoaXMuZ2V0RW50aXR5KG9iamVjdFZhbHVlLCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24hLCBwcm9wZXJ0eS5uYW1lLCB0cnVlKSwgb2JqZWN0VmFsdWUsIG9iamVjdFZhbGlkYXRpb25Db25maWcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFJlc2V0IGZsYWdzIHRvIGluZGljYXRlIHRoZSBlbmQgb2YgbmVzdGVkIGJpbmRpbmcuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTmVzdGVkQmluZGluZyA9IHRoaXMuaXNOZXN0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhlIHByb3BlcnR5IGlzIGFscmVhZHkgYSBmb3JtIGdyb3VwLCB1c2UgaXQgYXMgaXMgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAob2JqZWN0VmFsdWUgaW5zdGFuY2VvZiBGb3JtR3JvdXAgfHwgb2JqZWN0VmFsdWUgaW5zdGFuY2VvZiBSeEZvcm1Hcm91cCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvcm1Hcm91cE9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdID0gb2JqZWN0VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQVJSQVlfUFJPUEVSVFk6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhcnJheU9iamVjdFZhbHVlID0gKGVudGl0eU9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhlIHByb3BlcnR5IGlzIGFuIGFycmF5IGFuZCBub3QgYSBmb3JtIGFycmF5LCByZWN1cnNpdmVseSBjcmVhdGUgYSBmb3JtIGFycmF5IGZvciBpdCAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyYXlPYmplY3RWYWx1ZSAmJiBhcnJheU9iamVjdFZhbHVlIGluc3RhbmNlb2YgQXJyYXkgJiYgIShhcnJheU9iamVjdFZhbHVlIGluc3RhbmNlb2YgRm9ybUFycmF5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogU2V0IGZsYWdzIHRvIGluZGljYXRlIG5lc3RlZCBiaW5kaW5nLiAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc05lc3RlZEJpbmRpbmcgPSB0aGlzLmlzTmVzdGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIGFuIGFycmF5IHRvIGhvbGQgZm9ybSBncm91cHMgZm9yIGVhY2ggc3ViLW9iamVjdCBpbiB0aGUgYXJyYXkuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZm9ybUFycmF5R3JvdXAgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbmRleCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZW50aXR5ID0gcHJvcGVydHkuZW50aXR5UHJvdmlkZXIgPyBwcm9wZXJ0eS5lbnRpdHlQcm92aWRlci5jYWxsKGVudGl0eU9iamVjdCkgOiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgb2JqZWN0VmFsaWRhdGlvbkNvbmZpZyA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSXRlcmF0ZSBvdmVyIGVhY2ggc3ViLW9iamVjdCBpbiB0aGUgYXJyYXkuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBzdWJPYmplY3Qgb2YgYXJyYXlPYmplY3RWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEZpbHRlciBjb25kaXRpb25hbCBvYmplY3QgcHJvcGVydGllcyBiYXNlZCBvbiB0aGUgY3VycmVudCBwcm9wZXJ0eSBuYW1lIGFuZCBhcnJheSBpbmRleC4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VDb250YWluZXIgJiYgaW5zdGFuY2VDb250YWluZXIuY29uZGl0aW9uYWxPYmplY3RQcm9wcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMgPSBpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbE9iamVjdFByb3BzLmZpbHRlcigodDogYW55KSA9PiB0Lm9iamVjdFByb3BOYW1lID09IHByb3BlcnR5Lm5hbWUgJiYgdC5hcnJheUluZGV4ID09IGluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UgJiYgdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbE9iamVjdFByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzID0gdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbE9iamVjdFByb3BzLmZpbHRlcigodDogYW55KSA9PiB0Lm9iamVjdFByb3BOYW1lID09IHByb3BlcnR5Lm5hbWUgJiYgdC5hcnJheUluZGV4ID09IGluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNldCB0aGUgY3VycmVudCBmb3JtIGdyb3VwIG90aGVyIHZhbGlkYXRvciBpZiBhdmFpbGFibGUuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yW3Byb3BlcnR5Lm5hbWVdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEZvcm1Hcm91cFByb3BPdGhlclZhbGlkYXRvciA9IHRoaXMuZm9ybUdyb3VwUHJvcE90aGVyVmFsaWRhdG9yW3Byb3BlcnR5Lm5hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogT2J0YWluIHZhbGlkYXRpb24gY29uZmlndXJhdGlvbiBmb3IgdGhlIHN1Yi1vYmplY3QuICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0VmFsaWRhdGlvbkNvbmZpZyA9IHRoaXMuZ2V0VmFsaWRhdG9yQ29uZmlnKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiEsIHN1Yk9iamVjdCwgYCR7cHJvcGVydHkubmFtZX0uYCwgYCR7cHJvcGVydHkubmFtZX1bJHtpbmRleH1dLmApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBDcmVhdGUgYSBmb3JtIGdyb3VwIGZvciB0aGUgc3ViLW9iamVjdCBhbmQgYWRkIGl0IHRvIHRoZSBmb3JtQXJyYXlHcm91cCBhcnJheS4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQXJyYXlHcm91cC5wdXNoKHRoaXMuZm9ybUdyb3VwKGVudGl0eSB8fCBwcm9wZXJ0eS5lbnRpdHkgfHwgdGhpcy5nZXRFbnRpdHkoc3ViT2JqZWN0LCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24hLCBwcm9wZXJ0eS5uYW1lLCB0cnVlKSwgc3ViT2JqZWN0LCBvYmplY3RWYWxpZGF0aW9uQ29uZmlnKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEluY3JlbWVudCB0aGUgaW5kZXguICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgrKztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogUmVzZXQgY29uZGl0aW9uYWwgb2JqZWN0IHByb3BlcnRpZXMgYW5kIGJ1aWxkZXIgY29uZmlndXJhdGlvbiBjb25kaXRpb25hbCBvYmplY3QgcHJvcGVydGllcy4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE9idGFpbiBhYnN0cmFjdCBjb250cm9sIG9wdGlvbnMgZm9yIHRoZSBwcm9wZXJ0eS4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhYnN0cmFjdENvbnRyb2xPcHRpb25zID0gdGhpcy5nZXRBYnN0cmFjdENvbnRyb2xPcHRpb25zKHByb3BlcnR5Lm5hbWUsIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiEsIHt9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBDcmVhdGUgYSBuZXcgUnhGb3JtQXJyYXkgdXNpbmcgdGhlIGFycmF5T2JqZWN0VmFsdWUgYW5kIHRoZSBmb3JtQXJyYXlHcm91cCwgYWxvbmcgd2l0aCB0aGUgYWJzdHJhY3QgY29udHJvbCBvcHRpb25zLiAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvcm1Hcm91cE9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdID0gbmV3IFJ4Rm9ybUFycmF5KGFycmF5T2JqZWN0VmFsdWUsIGZvcm1BcnJheUdyb3VwLCBhYnN0cmFjdENvbnRyb2xPcHRpb25zLCBudWxsLCBwcm9wZXJ0eS5hcnJheUNvbmZpZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgYXV0b0luc3RhbmNlUHVzaCBpcyBlbmFibGVkLCBvdmVycmlkZSB0aGUgcHVzaCBhbmQgc3BsaWNlIG1ldGhvZHMgb2YgdGhlIGFycmF5T2JqZWN0VmFsdWUgdG8gbWFuYWdlIGZvcm0gZ3JvdXBzIGR5bmFtaWNhbGx5LiAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFJlYWN0aXZlRm9ybUNvbmZpZy5hdXRvSW5zdGFuY2VQdXNoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlPYmplY3RWYWx1ZS5wdXNoID0gKGluc3RhbmNlOiBhbnlbXSk6IG51bWJlciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmb3JtR3JvdXAgPSB0aGlzLmZvcm1Hcm91cChpbnN0YW5jZS5jb25zdHJ1Y3RvciwgaW5zdGFuY2UsIG9iamVjdFZhbGlkYXRpb25Db25maWchKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvcm1Hcm91cE9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdLnB1c2goZm9ybUdyb3VwLCB7IGlzQWRkZWRJbnN0YW5jZTogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlPYmplY3RWYWx1ZS5zcGxpY2UgPSAoc3RhcnQsIGRlbGV0ZUNvdW50KTogYW55W10gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZW5kID0gKHN0YXJ0ICsgZGVsZXRlQ291bnQhKSAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8PSBlbmQ7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvcm1Hcm91cE9iamVjdCBhcyBhbnkpW3Byb3BlcnR5Lm5hbWVdLnJlbW92ZUF0KGksIHsgaXNSZW1vdmVkSW5zdGFuY2U6IHRydWUgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogUmVzZXQgZmxhZ3MgdG8gaW5kaWNhdGUgdGhlIGVuZCBvZiBuZXN0ZWQgYmluZGluZy4gKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNOZXN0ZWRCaW5kaW5nID0gdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBJZiB0aGUgcHJvcGVydHkgaXMgYWxyZWFkeSBhIGZvcm0gYXJyYXksIHVzZSBpdCBhcyBpcyAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhcnJheU9iamVjdFZhbHVlIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9ybUdyb3VwT2JqZWN0IGFzIGFueSlbcHJvcGVydHkubmFtZV0gPSBhcnJheU9iamVjdFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBJZiB0aGUgcHJvcGVydHkgY29uZmlndXJhdGlvbiBzcGVjaWZpZXMgY3JlYXRpbmcgYSBibGFuayBmb3JtIGFycmF5LCBjcmVhdGUgb25lICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHByb3BlcnR5LmFycmF5Q29uZmlnICYmIHByb3BlcnR5LmFycmF5Q29uZmlnLmNyZWF0ZUJsYW5rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9ybUdyb3VwT2JqZWN0IGFzIGFueSlbcHJvcGVydHkubmFtZV0gPSBuZXcgUnhGb3JtQXJyYXkoW10sIFtdLCBudWxsLCBudWxsLCBwcm9wZXJ0eS5hcnJheUNvbmZpZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8qIElmIG5vIG5lc3RlZCBmb3JtIGdyb3VwcyBvciBhcnJheXMgYXJlIGNyZWF0ZWQsIHJlc2V0IGNvbmRpdGlvbmFsIHZhbGlkYXRpb24gaW5zdGFuY2UgYW5kIHJlbGF0ZWQgcHJvcGVydGllcy4gKi9cclxuICAgICAgICBpZiAoIXRoaXMuaXNOZXN0ZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZSA9IHt9O1xyXG4gICAgICAgICAgICB0aGlzLmJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wcyA9IFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogU2V0IGFic3RyYWN0IGNvbnRyb2wgb3B0aW9ucyBmb3IgdGhlIGZvcm0gZ3JvdXAgYmFzZWQgb24gZm9ybSBidWlsZGVyIGNvbmZpZ3VyYXRpb24uICovXHJcbiAgICAgICAgbGV0IGFic3RyYWN0Q29udHJvbE9wdGlvbnM6IEFic3RyYWN0Q29udHJvbE9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRvcnM6IFtdLFxyXG4gICAgICAgICAgICBhc3luY1ZhbGlkYXRvcnM6IFtdLFxyXG4gICAgICAgICAgICB1cGRhdGVPbjogZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uICYmIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5hYnN0cmFjdENvbnRyb2xPcHRpb25zICYmIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5hYnN0cmFjdENvbnRyb2xPcHRpb25zWydnbG9iYWwnXVxyXG4gICAgICAgICAgICAgICAgPyBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uYWJzdHJhY3RDb250cm9sT3B0aW9uc1snZ2xvYmFsJ11cclxuICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyogT2J0YWluIGFic3RyYWN0IGNvbnRyb2wgb3B0aW9ucyBmb3IgdGhlIGdsb2JhbCBwcm9wZXJ0eS4gKi9cclxuICAgICAgICBhYnN0cmFjdENvbnRyb2xPcHRpb25zID0gdGhpcy5nZXRBYnN0cmFjdENvbnRyb2xPcHRpb25zKFwiZ2xvYmFsXCIsIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiEsIGFic3RyYWN0Q29udHJvbE9wdGlvbnMpO1xyXG5cclxuICAgICAgICAvKiBDcmVhdGUgYSBuZXcgUnhGb3JtR3JvdXAgdXNpbmcgdGhlIG1vZGVsLCBlbnRpdHkgb2JqZWN0LCBmb3JtR3JvdXBPYmplY3QsIGFuZCBhYnN0cmFjdCBjb250cm9sIG9wdGlvbnMuICovXHJcbiAgICAgICAgdmFyIGZvcm1Hcm91cDogUnhGb3JtR3JvdXAgPSBuZXcgUnhGb3JtR3JvdXAoanNvbi5tb2RlbCwganNvbi5lbnRpdHlPYmplY3QsIGZvcm1Hcm91cE9iamVjdCwgYWJzdHJhY3RDb250cm9sT3B0aW9ucyk7XHJcblxyXG4gICAgICAgIC8qIElmIGV4cGVyaW1lbnRhbCBtb2RlIGlzIGVuYWJsZWQsIGFzc2lnbiB0aGUgZm9ybSBncm91cCB0byB0aGUgZW50aXR5IG9iamVjdCBhbmQgb3ZlcnJpZGUgcHJvcGVydGllcyBpZiBuZWVkZWQuICovXHJcbiAgICAgICAgaWYgKGRlZmF1bHRDb250YWluZXIuaXNFeHBlcmltZW50YWwpIHtcclxuICAgICAgICAgICAganNvbi5lbnRpdHlPYmplY3RbXCJmb3JtR3JvdXBcIl0gPSBmb3JtR3JvdXA7XHJcbiAgICAgICAgICAgIHRoaXMub3ZlcnJpZGVQcm9wZXJ0aWVzKGZvcm1Hcm91cCwganNvbi5lbnRpdHlPYmplY3QsIGV4dGVuZGVkUHJvcGVydGllcyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBJZiBub3QgaW4gbmVzdGVkIGJpbmRpbmcgbW9kZSBhbmQgZm9ybUdyb3VwIGlzIG5vdCBwcmV2aW91c2x5IGNhbGxlZCwgcmVmcmVzaCBkaXNhYmxlIHN0YXR1cyBvZiB0aGUgZm9ybSBncm91cC4gKi9cclxuICAgICAgICBpZiAoIXRoaXMuaXNOZXN0ZWRCaW5kaW5nICYmICF0aGlzLmlzR3JvdXBDYWxsZWQpIHtcclxuICAgICAgICAgICAgZm9ybUdyb3VwLnJlZnJlc2hEaXNhYmxlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZm9ybUdyb3VwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3ZlcnJpZGVzIHByb3BlcnRpZXMgaW4gdGhlIGZvcm0gZ3JvdXAgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGVudGl0eSBvYmplY3QgYW5kIHByb3BlcnRpZXMuXHJcbiAgICAgKiBAcGFyYW0gZm9ybUdyb3VwIFRoZSBSeEZvcm1Hcm91cCBpbnN0YW5jZSB0byBvdmVycmlkZSBwcm9wZXJ0aWVzLlxyXG4gICAgICogQHBhcmFtIGVudGl0eU9iamVjdCBUaGUgZW50aXR5IG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIHRvIG92ZXJyaWRlLlxyXG4gICAgICogQHBhcmFtIHByb3BlcnRpZXMgQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgdG8gb3ZlcnJpZGUgYXMga2V5cy5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBvdmVycmlkZVByb3BlcnRpZXMoZm9ybUdyb3VwOiBSeEZvcm1Hcm91cCwgZW50aXR5T2JqZWN0OiBhbnksIHByb3BlcnRpZXM6IHsgW2tleTogc3RyaW5nXTogYm9vbGVhbiB9KSB7XHJcbiAgICAgICAgT2JqZWN0LmtleXMocHJvcGVydGllcykuZm9yRWFjaCh0ID0+IHRoaXMub3ZlcnJpZGVQcm9wKGVudGl0eU9iamVjdCwgdCwgZm9ybUdyb3VwKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGFic3RyYWN0IGNvbnRyb2wgb3B0aW9ucyBmb3IgYSBnaXZlbiBjb250cm9sIG5hbWUuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBjb250cm9sLlxyXG4gICAgICogQHBhcmFtIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiBUaGUgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uIGNvbnRhaW5pbmcgdGhlIGFic3RyYWN0IGNvbnRyb2wgb3B0aW9ucy5cclxuICAgICAqIEBwYXJhbSBhYnN0cmFjdENvbnRyb2xPcHRpb25zIFRoZSBleGlzdGluZyBBYnN0cmFjdENvbnRyb2xPcHRpb25zLlxyXG4gICAgICogQHJldHVybnMgVGhlIHVwZGF0ZWQgQWJzdHJhY3RDb250cm9sT3B0aW9ucyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgY29uZmlndXJhdGlvbi5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRBYnN0cmFjdENvbnRyb2xPcHRpb25zKG5hbWU6IHN0cmluZywgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uOiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24sIGFic3RyYWN0Q29udHJvbE9wdGlvbnM6IEFic3RyYWN0Q29udHJvbE9wdGlvbnMpIHtcclxuICAgICAgICAvKiBVcGRhdGUgdXBkYXRlT24gb3B0aW9uIGlmIGRlZmluZWQgaW4gZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uICovXHJcbiAgICAgICAgaWYgKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiAmJiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uYWJzdHJhY3RDb250cm9sT3B0aW9ucyAmJiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uYWJzdHJhY3RDb250cm9sT3B0aW9uc1tuYW1lXSkge1xyXG4gICAgICAgICAgICBhYnN0cmFjdENvbnRyb2xPcHRpb25zLnVwZGF0ZU9uID0gZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmFic3RyYWN0Q29udHJvbE9wdGlvbnNbbmFtZV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBDaGVjayBpZiBjb250cm9sT3B0aW9ucyBhcmUgZGVmaW5lZCBpbiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gKi9cclxuICAgICAgICBjb25zdCBjb250cm9sT3B0aW9ucyA9IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiA/IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5iYXNlQWJzdHJhY3RDb250cm9sT3B0aW9ucyA6IG51bGw7XHJcbiAgICAgICAgaWYgKGNvbnRyb2xPcHRpb25zICYmIGNvbnRyb2xPcHRpb25zW25hbWVdKSB7XHJcbiAgICAgICAgICAgIC8qIFVwZGF0ZSB1cGRhdGVPbiBvcHRpb24gZnJvbSBjb250cm9sT3B0aW9ucyBpZiBkZWZpbmVkICovXHJcbiAgICAgICAgICAgIGlmIChjb250cm9sT3B0aW9uc1tuYW1lXS51cGRhdGVPbikge1xyXG4gICAgICAgICAgICAgICAgYWJzdHJhY3RDb250cm9sT3B0aW9ucy51cGRhdGVPbiA9IGNvbnRyb2xPcHRpb25zW25hbWVdLnVwZGF0ZU9uO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBBZGQgdmFsaWRhdG9ycyBmcm9tIGNvbnRyb2xPcHRpb25zIGlmIGRlZmluZWQgKi9cclxuICAgICAgICAgICAgaWYgKGNvbnRyb2xPcHRpb25zW25hbWVdLnZhbGlkYXRvcnMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNvbnRyb2xPcHRpb25zW25hbWVdLnZhbGlkYXRvcnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgKDxWYWxpZGF0b3JGbltdPmNvbnRyb2xPcHRpb25zW25hbWVdLnZhbGlkYXRvcnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JFYWNoKHZhbGlkYXRvciA9PiAoPFZhbGlkYXRvckZuW10+YWJzdHJhY3RDb250cm9sT3B0aW9ucy52YWxpZGF0b3JzKS5wdXNoKHZhbGlkYXRvcikpXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICg8VmFsaWRhdG9yRm5bXT5hYnN0cmFjdENvbnRyb2xPcHRpb25zLnZhbGlkYXRvcnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5wdXNoKDxWYWxpZGF0b3JGbj5jb250cm9sT3B0aW9uc1tuYW1lXS52YWxpZGF0b3JzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyogQWRkIGFzeW5jIHZhbGlkYXRvcnMgZnJvbSBjb250cm9sT3B0aW9ucyBpZiBkZWZpbmVkICovXHJcbiAgICAgICAgICAgIGlmIChjb250cm9sT3B0aW9uc1tuYW1lXS5hc3luY1ZhbGlkYXRvcnMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNvbnRyb2xPcHRpb25zW25hbWVdLmFzeW5jVmFsaWRhdG9ycykpIHtcclxuICAgICAgICAgICAgICAgICAgICAoPFZhbGlkYXRvckZuW10+Y29udHJvbE9wdGlvbnNbbmFtZV0uYXN5bmNWYWxpZGF0b3JzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuZm9yRWFjaCh2YWxpZGF0b3IgPT4gKDxWYWxpZGF0b3JGbltdPmFic3RyYWN0Q29udHJvbE9wdGlvbnMuYXN5bmNWYWxpZGF0b3JzKS5wdXNoKHZhbGlkYXRvcikpXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICg8VmFsaWRhdG9yRm5bXT5hYnN0cmFjdENvbnRyb2xPcHRpb25zLmFzeW5jVmFsaWRhdG9ycylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnB1c2goPFZhbGlkYXRvckZuPmNvbnRyb2xPcHRpb25zW25hbWVdLnZhbGlkYXRvcnMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYWJzdHJhY3RDb250cm9sT3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE92ZXJyaWRlcyBhIHByb3BlcnR5IG9uIHRoZSBlbnRpdHkgb2JqZWN0IHdpdGggY3VzdG9tIGdldHRlcnMgYW5kIHNldHRlcnMuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSBlbnRpdHlPYmplY3QgVGhlIGVudGl0eSBvYmplY3Qgd2hvc2UgcHJvcGVydHkgbmVlZHMgdG8gYmUgb3ZlcnJpZGRlbi5cclxuICAgICAqIEBwYXJhbSBwcm9wTmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gYmUgb3ZlcnJpZGRlbi5cclxuICAgICAqIEBwYXJhbSBmb3JtR3JvdXAgVGhlIFJ4Rm9ybUdyb3VwIGFzc29jaWF0ZWQgd2l0aCB0aGUgZW50aXR5IG9iamVjdC5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBvdmVycmlkZVByb3AoZW50aXR5T2JqZWN0OiBhbnksIHByb3BOYW1lOiBzdHJpbmcsIGZvcm1Hcm91cDogUnhGb3JtR3JvdXApIHtcclxuICAgICAgICAvKiBHZXQgdGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgYW5kIGN1cnJlbnQgdmFsdWUgKi9cclxuICAgICAgICBsZXQgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoT2JqZWN0LmdldFByb3RvdHlwZU9mKGVudGl0eU9iamVjdCksIHByb3BOYW1lKTtcclxuICAgICAgICBsZXQgdmFsdWUgPSBlbnRpdHlPYmplY3RbcHJvcE5hbWVdO1xyXG4gICAgICAgIGxldCBvbGRWYWx1ZTogYW55ID0gbnVsbDtcclxuXHJcbiAgICAgICAgLyogRGVmaW5lIHRoZSBwcm9wZXJ0eSB3aXRoIGN1c3RvbSBnZXR0ZXJzIGFuZCBzZXR0ZXJzICovXHJcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudGl0eU9iamVjdCwgcHJvcE5hbWUsIHtcclxuICAgICAgICAgICAgLyogQ3VzdG9tIGdldHRlciAqL1xyXG4gICAgICAgICAgICBnZXQ6ICgpID0+IHsgcmV0dXJuIGRlc2NyaXB0b3IgPyBkZXNjcmlwdG9yLmdldCEuY2FsbChlbnRpdHlPYmplY3QpIDogdmFsdWUgfSxcclxuICAgICAgICAgICAgLyogQ3VzdG9tIHNldHRlciAqL1xyXG4gICAgICAgICAgICBzZXQ6ICh2KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHY7XHJcbiAgICAgICAgICAgICAgICAvKiBDaGVjayBpZiB2YWx1ZSBoYXMgY2hhbmdlZCAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKG9sZFZhbHVlICE9IHYpIHtcclxuICAgICAgICAgICAgICAgICAgICAvKiBDYWxsIHRoZSBvcmlnaW5hbCBzZXR0ZXIgaWYgZGVmaW5lZCAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3Iuc2V0IS5jYWxsKGVudGl0eU9iamVjdCwgdik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8qIFVwZGF0ZSB0aGUgY29ycmVzcG9uZGluZyBjb250cm9sIGluIHRoZSBmb3JtIGdyb3VwICovXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmb3JtR3JvdXAuY2hhbmdpbmcgJiYgZm9ybUdyb3VwLmNvbnRyb2xzW3Byb3BOYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtR3JvdXAuY29udHJvbHNbcHJvcE5hbWVdLnNldFZhbHVlKHYpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8qIFVwZGF0ZSB0aGUgb2xkIHZhbHVlICovXHJcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHY7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG4iXX0=