@messaia/cdk 18.2.3 → 19.0.0-rc01

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 (659) hide show
  1. package/fesm2022/messaia-cdk.mjs +1147 -932
  2. package/fesm2022/messaia-cdk.mjs.map +1 -1
  3. package/lib/base/components/base.component.d.ts +1 -1
  4. package/lib/base/components/generic-embedded-list.component.d.ts +1 -1
  5. package/lib/base/components/generic-form-base.component.d.ts +1 -1
  6. package/lib/base/components/generic-form.component.d.ts +1 -1
  7. package/lib/base/components/generic-list.component.d.ts +7 -3
  8. package/lib/base/components/generic-reactive-form.component.d.ts +1 -1
  9. package/lib/base/helpers/auth-helper.d.ts +1 -1
  10. package/lib/chips/components/chips.component.d.ts +5 -16
  11. package/lib/common/functions/utils.d.ts +1 -1
  12. package/lib/common/helpers/app-storage.d.ts +1 -1
  13. package/lib/common/styles/_layout.scss +1 -1
  14. package/lib/common/styles/_variables.scss +4 -25
  15. package/lib/common/styles/colors/_colors-dark.scss +2 -0
  16. package/lib/common/styles/colors/_colors.scss +4 -4
  17. package/lib/common/styles/core/_button.scss +7 -21
  18. package/lib/common/styles/core/_card.scss +13 -97
  19. package/lib/common/styles/core/_core.scss +8 -21
  20. package/lib/common/styles/core/_sidenav.scss +9 -7
  21. package/lib/common/styles/core/_structure.scss +4 -11
  22. package/lib/common/styles/font/_font.scss +5 -13
  23. package/lib/common/styles/m2/_common-theme.scss +10 -10
  24. package/lib/common/styles/m3/_common-theme.scss +27 -10
  25. package/lib/common/styles/platform.scss +10 -8
  26. package/lib/common/styles/utilities/_general.scss +55 -51
  27. package/lib/common/styles/utilities/_pull.scss +23 -30
  28. package/lib/common/styles/utilities/_push.scss +23 -30
  29. package/lib/common/styles/utilities/_size.scss +3 -3
  30. package/lib/common/styles/utilities/_utilities.scss +14 -14
  31. package/lib/common/theming/_m2-all-theme.scss +4 -11
  32. package/lib/common/theming/_m3-all-theme.scss +18 -0
  33. package/lib/form-validators/directives/base-directive.d.ts +1 -1
  34. package/lib/form-validators/directives/template-validations/base-validator.directive.d.ts +1 -1
  35. package/lib/form-validators/directives/template-validations/control-expression-process.d.ts +1 -1
  36. package/lib/form-validators/services/rx-form-array.d.ts +2 -2
  37. package/lib/form-validators/util/reset-form.d.ts +3 -3
  38. package/lib/forms/directives/mat-form-field-editor.directive.d.ts +31 -28
  39. package/lib/forms/helpers/abstract-mat-form-field.d.ts +147 -91
  40. package/lib/forms/helpers/abstract-select-form-field.component.d.ts +144 -67
  41. package/lib/forms/helpers/value-accessor-base.d.ts +1 -1
  42. package/lib/layout/_m2-layout-theme.scss +14 -50
  43. package/lib/layout/layout-toggle.class.d.ts +1 -1
  44. package/lib/list/components/list.component.d.ts +3 -15
  45. package/lib/select/components/select.component.d.ts +3 -16
  46. package/lib/table/components/filter-select/filter-select.component.d.ts +2 -3
  47. package/package.json +3 -5
  48. package/esm2022/lib/base/base.module.mjs +0 -114
  49. package/esm2022/lib/base/components/base.component.mjs +0 -904
  50. package/esm2022/lib/base/components/dynamic-table-config-dialog/dynamic-table-config-dialog.comnponent.mjs +0 -123
  51. package/esm2022/lib/base/components/generic-embedded-list.component.mjs +0 -197
  52. package/esm2022/lib/base/components/generic-form-base.component.mjs +0 -891
  53. package/esm2022/lib/base/components/generic-form.component.mjs +0 -44
  54. package/esm2022/lib/base/components/generic-list.component.mjs +0 -966
  55. package/esm2022/lib/base/components/generic-reactive-form.component.mjs +0 -101
  56. package/esm2022/lib/base/components/task-dialog/task-dialog.component.mjs +0 -147
  57. package/esm2022/lib/base/constants/common.mjs +0 -92
  58. package/esm2022/lib/base/constants/global-roles.mjs +0 -9
  59. package/esm2022/lib/base/enums/message-type.mjs +0 -7
  60. package/esm2022/lib/base/helpers/auth-helper.mjs +0 -53
  61. package/esm2022/lib/base/interceptors/base.interceptor.mjs +0 -168
  62. package/esm2022/lib/base/interceptors/caching-interceptor.mjs +0 -67
  63. package/esm2022/lib/base/interceptors/loading.interceptor.mjs +0 -64
  64. package/esm2022/lib/base/interfaces/ibase-component.mjs +0 -2
  65. package/esm2022/lib/base/interfaces/igeneric-form-base.mjs +0 -2
  66. package/esm2022/lib/base/interfaces/igeneric-list-component.mjs +0 -2
  67. package/esm2022/lib/base/interfaces/igeneric-reactive-form-base.mjs +0 -2
  68. package/esm2022/lib/base/models/auth-user.mjs +0 -18
  69. package/esm2022/lib/base/models/task-dialog-data.mjs +0 -85
  70. package/esm2022/lib/base/public_api.mjs +0 -2
  71. package/esm2022/lib/base/services/file.service.mjs +0 -18
  72. package/esm2022/lib/base/services/loading-screen.service.mjs +0 -45
  73. package/esm2022/lib/base/services/print.service.mjs +0 -41
  74. package/esm2022/lib/chips/chips.module.mjs +0 -77
  75. package/esm2022/lib/chips/components/chips.component.mjs +0 -702
  76. package/esm2022/lib/chips/directives/autocomplete-option.directive.mjs +0 -18
  77. package/esm2022/lib/chips/directives/chip.directive.mjs +0 -18
  78. package/esm2022/lib/chips/public_api.mjs +0 -3
  79. package/esm2022/lib/common/animations/collapse/collapse.animation.mjs +0 -33
  80. package/esm2022/lib/common/animations/common/interfaces.mjs +0 -2
  81. package/esm2022/lib/common/behaviors/constructor.mjs +0 -2
  82. package/esm2022/lib/common/behaviors/control-value-accesor.mixin.mjs +0 -41
  83. package/esm2022/lib/common/behaviors/disabled.mixin.mjs +0 -24
  84. package/esm2022/lib/common/common.module.mjs +0 -176
  85. package/esm2022/lib/common/constants/constants.mjs +0 -3
  86. package/esm2022/lib/common/directives/autofocus.directive.mjs +0 -62
  87. package/esm2022/lib/common/directives/delayed-hover.directive.mjs +0 -133
  88. package/esm2022/lib/common/directives/disable-control.directive.mjs +0 -35
  89. package/esm2022/lib/common/enums/app-event-type.mjs +0 -6
  90. package/esm2022/lib/common/enums/filter-glue.mjs +0 -16
  91. package/esm2022/lib/common/enums/filter-operator.mjs +0 -15
  92. package/esm2022/lib/common/enums/salutation.mjs +0 -7
  93. package/esm2022/lib/common/functions/decorators.mjs +0 -22
  94. package/esm2022/lib/common/functions/functions.mjs +0 -22
  95. package/esm2022/lib/common/functions/utils.mjs +0 -271
  96. package/esm2022/lib/common/helpers/app-storage.mjs +0 -77
  97. package/esm2022/lib/common/helpers/delegate.mjs +0 -2
  98. package/esm2022/lib/common/helpers/dynamic-builder.mjs +0 -52
  99. package/esm2022/lib/common/helpers/dynamic-component-compiler.mjs +0 -11
  100. package/esm2022/lib/common/models/action-item.mjs +0 -77
  101. package/esm2022/lib/common/models/app-event.mjs +0 -21
  102. package/esm2022/lib/common/models/app-setting.mjs +0 -92
  103. package/esm2022/lib/common/models/audit-entity.mjs +0 -53
  104. package/esm2022/lib/common/models/audit-user.mjs +0 -24
  105. package/esm2022/lib/common/models/base-entity.mjs +0 -40
  106. package/esm2022/lib/common/models/common-error.mjs +0 -29
  107. package/esm2022/lib/common/models/common-handler-context.mjs +0 -45
  108. package/esm2022/lib/common/models/displayname-number-projection.mjs +0 -56
  109. package/esm2022/lib/common/models/displayname-projection.mjs +0 -38
  110. package/esm2022/lib/common/models/entity.mjs +0 -2
  111. package/esm2022/lib/common/models/enum-item.mjs +0 -2
  112. package/esm2022/lib/common/models/enum-metadata.mjs +0 -44
  113. package/esm2022/lib/common/models/filter-field.mjs +0 -2
  114. package/esm2022/lib/common/models/filter.mjs +0 -2
  115. package/esm2022/lib/common/models/icommon-handler-context.mjs +0 -2
  116. package/esm2022/lib/common/models/icon.mjs +0 -42
  117. package/esm2022/lib/common/models/key-value.mjs +0 -11
  118. package/esm2022/lib/common/models/modifiable-entity.mjs +0 -22
  119. package/esm2022/lib/common/models/name-number-projection.mjs +0 -35
  120. package/esm2022/lib/common/models/name-projection.mjs +0 -25
  121. package/esm2022/lib/common/models/permission.mjs +0 -29
  122. package/esm2022/lib/common/models/save-action.mjs +0 -7
  123. package/esm2022/lib/common/models/suffix-button.mjs +0 -15
  124. package/esm2022/lib/common/models/title-projection.mjs +0 -25
  125. package/esm2022/lib/common/pipes/bind.mjs +0 -31
  126. package/esm2022/lib/common/pipes/data-source.pipe.mjs +0 -15
  127. package/esm2022/lib/common/pipes/enum.pipe.mjs +0 -41
  128. package/esm2022/lib/common/pipes/file-size.pipe.mjs +0 -35
  129. package/esm2022/lib/common/pipes/filter.pipe.mjs +0 -54
  130. package/esm2022/lib/common/pipes/first-letter.mjs +0 -24
  131. package/esm2022/lib/common/pipes/form-array.pipe.mjs +0 -14
  132. package/esm2022/lib/common/pipes/form-control.pipe.mjs +0 -14
  133. package/esm2022/lib/common/pipes/form-group.pipe.mjs +0 -14
  134. package/esm2022/lib/common/pipes/func.pipe.mjs +0 -14
  135. package/esm2022/lib/common/pipes/join.pipe.mjs +0 -26
  136. package/esm2022/lib/common/pipes/keys.mjs +0 -18
  137. package/esm2022/lib/common/pipes/map.pipe.mjs +0 -48
  138. package/esm2022/lib/common/pipes/month-name.pipe.mjs +0 -25
  139. package/esm2022/lib/common/pipes/nested-property.mjs +0 -29
  140. package/esm2022/lib/common/pipes/only-number.mjs +0 -58
  141. package/esm2022/lib/common/pipes/order.pipe.mjs +0 -269
  142. package/esm2022/lib/common/pipes/placeholder.pipe.mjs +0 -26
  143. package/esm2022/lib/common/pipes/property-join.pipe.mjs +0 -27
  144. package/esm2022/lib/common/pipes/safe-html.pipe.mjs +0 -32
  145. package/esm2022/lib/common/pipes/split.pipe.mjs +0 -25
  146. package/esm2022/lib/common/pipes/time.pipe.mjs +0 -21
  147. package/esm2022/lib/common/pipes/titlecase.pipe.mjs +0 -14
  148. package/esm2022/lib/common/pipes/truncate.pipe.mjs +0 -15
  149. package/esm2022/lib/common/pipes/values.mjs +0 -14
  150. package/esm2022/lib/common/public_api.mjs +0 -41
  151. package/esm2022/lib/common/services/base.service.mjs +0 -19
  152. package/esm2022/lib/common/services/context-helper.mjs +0 -17
  153. package/esm2022/lib/common/services/enum.service.mjs +0 -81
  154. package/esm2022/lib/common/services/event-queue.service.mjs +0 -31
  155. package/esm2022/lib/common/services/service-locator.mjs +0 -25
  156. package/esm2022/lib/common/templates/templates.mjs +0 -87
  157. package/esm2022/lib/dialogs/alert-dialog/alert-dialog.component.mjs +0 -46
  158. package/esm2022/lib/dialogs/confirm-dialog/confirm-dialog.component.mjs +0 -60
  159. package/esm2022/lib/dialogs/dialog.component.mjs +0 -59
  160. package/esm2022/lib/dialogs/dialogs.module.mjs +0 -72
  161. package/esm2022/lib/dialogs/prompt-dialog/prompt-dialog.component.mjs +0 -44
  162. package/esm2022/lib/dialogs/public_api.mjs +0 -2
  163. package/esm2022/lib/dialogs/services/dialog.service.mjs +0 -154
  164. package/esm2022/lib/file/file-input.component.mjs +0 -334
  165. package/esm2022/lib/file/file.module.mjs +0 -37
  166. package/esm2022/lib/file/public_api.mjs +0 -2
  167. package/esm2022/lib/form-validators/abstract/typed-form.mjs +0 -13
  168. package/esm2022/lib/form-validators/algorithm/luhn-algorithm.mjs +0 -33
  169. package/esm2022/lib/form-validators/const/app-validators.const.mjs +0 -68
  170. package/esm2022/lib/form-validators/const/app.const.mjs +0 -65
  171. package/esm2022/lib/form-validators/const/config-names.const.mjs +0 -33
  172. package/esm2022/lib/form-validators/const/config-required-fields.const.mjs +0 -35
  173. package/esm2022/lib/form-validators/const/decorators.const.mjs +0 -23
  174. package/esm2022/lib/form-validators/const/events.const.mjs +0 -53
  175. package/esm2022/lib/form-validators/const/html-elements.const.mjs +0 -25
  176. package/esm2022/lib/form-validators/const/iban-country-wise-regex.const.mjs +0 -80
  177. package/esm2022/lib/form-validators/const/index.mjs +0 -6
  178. package/esm2022/lib/form-validators/const/operators.const.mjs +0 -7
  179. package/esm2022/lib/form-validators/const/validation-alphabet-locale.const.mjs +0 -9
  180. package/esm2022/lib/form-validators/const/validator.const.mjs +0 -29
  181. package/esm2022/lib/form-validators/core/annotation-types.mjs +0 -75
  182. package/esm2022/lib/form-validators/core/default-container.mjs +0 -500
  183. package/esm2022/lib/form-validators/decorators/allOf.decorator.mjs +0 -10
  184. package/esm2022/lib/form-validators/decorators/alpha.decorator.mjs +0 -10
  185. package/esm2022/lib/form-validators/decorators/alphaNumeric.decorator.mjs +0 -10
  186. package/esm2022/lib/form-validators/decorators/and.decorator.mjs +0 -6
  187. package/esm2022/lib/form-validators/decorators/ascii.decorator.mjs +0 -6
  188. package/esm2022/lib/form-validators/decorators/async.decorator.mjs +0 -6
  189. package/esm2022/lib/form-validators/decorators/base-decorator.function.mjs +0 -7
  190. package/esm2022/lib/form-validators/decorators/choice.decorator.mjs +0 -10
  191. package/esm2022/lib/form-validators/decorators/compare.decorator.mjs +0 -6
  192. package/esm2022/lib/form-validators/decorators/compose.decorator.mjs +0 -6
  193. package/esm2022/lib/form-validators/decorators/contains.decorator.mjs +0 -10
  194. package/esm2022/lib/form-validators/decorators/credit-card.decorator.mjs +0 -10
  195. package/esm2022/lib/form-validators/decorators/cusip.decorator.mjs +0 -6
  196. package/esm2022/lib/form-validators/decorators/custom.decorator.mjs +0 -10
  197. package/esm2022/lib/form-validators/decorators/dataUri.decorator.mjs +0 -6
  198. package/esm2022/lib/form-validators/decorators/date.decorator.mjs +0 -10
  199. package/esm2022/lib/form-validators/decorators/different.decorator.mjs +0 -6
  200. package/esm2022/lib/form-validators/decorators/digit.decorator.mjs +0 -6
  201. package/esm2022/lib/form-validators/decorators/email.decorator.mjs +0 -6
  202. package/esm2022/lib/form-validators/decorators/endsWith.decorator.mjs +0 -10
  203. package/esm2022/lib/form-validators/decorators/even.decorator.mjs +0 -6
  204. package/esm2022/lib/form-validators/decorators/extension.decorator.mjs +0 -10
  205. package/esm2022/lib/form-validators/decorators/factor.decorator.mjs +0 -10
  206. package/esm2022/lib/form-validators/decorators/file.decorator.mjs +0 -10
  207. package/esm2022/lib/form-validators/decorators/fileSize.decorator.mjs +0 -10
  208. package/esm2022/lib/form-validators/decorators/greater-than-equal-to.decorator.mjs +0 -10
  209. package/esm2022/lib/form-validators/decorators/greater-than.decorator.mjs +0 -10
  210. package/esm2022/lib/form-validators/decorators/grid.decorator.mjs +0 -6
  211. package/esm2022/lib/form-validators/decorators/hexColor.decorator.mjs +0 -6
  212. package/esm2022/lib/form-validators/decorators/image.decorator.mjs +0 -10
  213. package/esm2022/lib/form-validators/decorators/index.mjs +0 -93
  214. package/esm2022/lib/form-validators/decorators/json.decorator.mjs +0 -6
  215. package/esm2022/lib/form-validators/decorators/latLong.decorator.mjs +0 -6
  216. package/esm2022/lib/form-validators/decorators/latitude.decorator.mjs +0 -6
  217. package/esm2022/lib/form-validators/decorators/leapYear.decorator.mjs +0 -6
  218. package/esm2022/lib/form-validators/decorators/less-than-equal-to.decorator.mjs +0 -10
  219. package/esm2022/lib/form-validators/decorators/less-than.decorator.mjs +0 -10
  220. package/esm2022/lib/form-validators/decorators/longitude.decorator.mjs +0 -6
  221. package/esm2022/lib/form-validators/decorators/lowercase.decorator.mjs +0 -6
  222. package/esm2022/lib/form-validators/decorators/mac.decorator.mjs +0 -6
  223. package/esm2022/lib/form-validators/decorators/mask.decorator.mjs +0 -6
  224. package/esm2022/lib/form-validators/decorators/maxDate.decorator.mjs +0 -10
  225. package/esm2022/lib/form-validators/decorators/maxLength.decorator.mjs +0 -10
  226. package/esm2022/lib/form-validators/decorators/maxNumber.decorator.mjs +0 -10
  227. package/esm2022/lib/form-validators/decorators/maxTime.decorator.mjs +0 -10
  228. package/esm2022/lib/form-validators/decorators/minDate.decorator.mjs +0 -10
  229. package/esm2022/lib/form-validators/decorators/minLength.decorator.mjs +0 -10
  230. package/esm2022/lib/form-validators/decorators/minNumber.decorator.mjs +0 -10
  231. package/esm2022/lib/form-validators/decorators/minTime.decorator.mjs +0 -10
  232. package/esm2022/lib/form-validators/decorators/model.decorator.mjs +0 -7
  233. package/esm2022/lib/form-validators/decorators/non-validation-decorators/disable.decorator.mjs +0 -8
  234. package/esm2022/lib/form-validators/decorators/non-validation-decorators/elementClass.decorator.mjs +0 -8
  235. package/esm2022/lib/form-validators/decorators/non-validation-decorators/error.decorator.mjs +0 -8
  236. package/esm2022/lib/form-validators/decorators/non-validation-decorators/update-on.decorator.mjs +0 -6
  237. package/esm2022/lib/form-validators/decorators/noneOf.decorator.mjs +0 -10
  238. package/esm2022/lib/form-validators/decorators/not.decorator.mjs +0 -6
  239. package/esm2022/lib/form-validators/decorators/notEmpty.decorator.mjs +0 -6
  240. package/esm2022/lib/form-validators/decorators/numeric.decorator.mjs +0 -10
  241. package/esm2022/lib/form-validators/decorators/odd.decorator.mjs +0 -6
  242. package/esm2022/lib/form-validators/decorators/oneOf.decorator.mjs +0 -10
  243. package/esm2022/lib/form-validators/decorators/or.decorator.mjs +0 -6
  244. package/esm2022/lib/form-validators/decorators/password.decorator.mjs +0 -10
  245. package/esm2022/lib/form-validators/decorators/pattern.decorator.mjs +0 -10
  246. package/esm2022/lib/form-validators/decorators/port.decorator.mjs +0 -6
  247. package/esm2022/lib/form-validators/decorators/primeNumber.decorator.mjs +0 -6
  248. package/esm2022/lib/form-validators/decorators/prop-array.decorator.mjs +0 -18
  249. package/esm2022/lib/form-validators/decorators/prop-object.decorator.mjs +0 -8
  250. package/esm2022/lib/form-validators/decorators/prop.decorator.mjs +0 -18
  251. package/esm2022/lib/form-validators/decorators/range.decorator.mjs +0 -10
  252. package/esm2022/lib/form-validators/decorators/required.decorator.mjs +0 -6
  253. package/esm2022/lib/form-validators/decorators/requiredTrue.decorator.mjs +0 -6
  254. package/esm2022/lib/form-validators/decorators/rule.decorator.mjs +0 -6
  255. package/esm2022/lib/form-validators/decorators/sanitize/blacklist.decorator.mjs +0 -8
  256. package/esm2022/lib/form-validators/decorators/sanitize/escape.decorator.mjs +0 -8
  257. package/esm2022/lib/form-validators/decorators/sanitize/ltrim.decorator.mjs +0 -8
  258. package/esm2022/lib/form-validators/decorators/sanitize/prefix.decorator.mjs +0 -8
  259. package/esm2022/lib/form-validators/decorators/sanitize/rtrim.decorator.mjs +0 -8
  260. package/esm2022/lib/form-validators/decorators/sanitize/sanitize.decorator.mjs +0 -8
  261. package/esm2022/lib/form-validators/decorators/sanitize/stripLow.decorator.mjs +0 -8
  262. package/esm2022/lib/form-validators/decorators/sanitize/suffix.decorator.mjs +0 -8
  263. package/esm2022/lib/form-validators/decorators/sanitize/toBoolean.decorator.mjs +0 -8
  264. package/esm2022/lib/form-validators/decorators/sanitize/toDate.decorator.mjs +0 -8
  265. package/esm2022/lib/form-validators/decorators/sanitize/toDouble.decorator.mjs +0 -8
  266. package/esm2022/lib/form-validators/decorators/sanitize/toFloat.decorator.mjs +0 -8
  267. package/esm2022/lib/form-validators/decorators/sanitize/toInt.decorator.mjs +0 -8
  268. package/esm2022/lib/form-validators/decorators/sanitize/toString.decorator.mjs +0 -8
  269. package/esm2022/lib/form-validators/decorators/sanitize/trim.decorator.mjs +0 -8
  270. package/esm2022/lib/form-validators/decorators/sanitize/whitelist.decorator.mjs +0 -8
  271. package/esm2022/lib/form-validators/decorators/startsWith.decorator.mjs +0 -10
  272. package/esm2022/lib/form-validators/decorators/time.decorator.mjs +0 -10
  273. package/esm2022/lib/form-validators/decorators/unique.decorator.mjs +0 -6
  274. package/esm2022/lib/form-validators/decorators/uppercase.decorator.mjs +0 -6
  275. package/esm2022/lib/form-validators/decorators/url.decorator.mjs +0 -10
  276. package/esm2022/lib/form-validators/directives/base-directive.mjs +0 -75
  277. package/esm2022/lib/form-validators/directives/control-host.directive.mjs +0 -55
  278. package/esm2022/lib/form-validators/directives/html-control-template.directive.mjs +0 -36
  279. package/esm2022/lib/form-validators/directives/rx-form.directive.mjs +0 -234
  280. package/esm2022/lib/form-validators/directives/template-validations/async-validation.directive.mjs +0 -40
  281. package/esm2022/lib/form-validators/directives/template-validations/base-validator.directive.mjs +0 -76
  282. package/esm2022/lib/form-validators/directives/template-validations/control-expression-process.mjs +0 -60
  283. package/esm2022/lib/form-validators/directives/template-validations/file-control.directive.mjs +0 -122
  284. package/esm2022/lib/form-validators/directives/template-validations/image-file-control.directive.mjs +0 -74
  285. package/esm2022/lib/form-validators/directives/template-validations/rxformcontrol.directive.mjs +0 -394
  286. package/esm2022/lib/form-validators/domain/disable-provider.mjs +0 -198
  287. package/esm2022/lib/form-validators/domain/element-processor/decimal.provider.mjs +0 -134
  288. package/esm2022/lib/form-validators/domain/element-processor/mask.provider.mjs +0 -453
  289. package/esm2022/lib/form-validators/domain/form-data.mjs +0 -93
  290. package/esm2022/lib/form-validators/enums/error-message-binding-strategy.mjs +0 -11
  291. package/esm2022/lib/form-validators/enums/index.mjs +0 -5
  292. package/esm2022/lib/form-validators/enums/ip-version.mjs +0 -7
  293. package/esm2022/lib/form-validators/enums/numeric-value-type.mjs +0 -7
  294. package/esm2022/lib/form-validators/enums/reset-type.mjs +0 -10
  295. package/esm2022/lib/form-validators/enums/url-validation-type.mjs +0 -7
  296. package/esm2022/lib/form-validators/models/config/alpha-config.mjs +0 -2
  297. package/esm2022/lib/form-validators/models/config/array-config.mjs +0 -2
  298. package/esm2022/lib/form-validators/models/config/base-config-fn.mjs +0 -2
  299. package/esm2022/lib/form-validators/models/config/base-config.mjs +0 -2
  300. package/esm2022/lib/form-validators/models/config/base-date-config.mjs +0 -2
  301. package/esm2022/lib/form-validators/models/config/choice-config.mjs +0 -2
  302. package/esm2022/lib/form-validators/models/config/compare-config.mjs +0 -2
  303. package/esm2022/lib/form-validators/models/config/component-config.mjs +0 -2
  304. package/esm2022/lib/form-validators/models/config/compose-config.mjs +0 -2
  305. package/esm2022/lib/form-validators/models/config/contains-config.mjs +0 -2
  306. package/esm2022/lib/form-validators/models/config/credit-card-config.mjs +0 -2
  307. package/esm2022/lib/form-validators/models/config/custom-config.mjs +0 -2
  308. package/esm2022/lib/form-validators/models/config/date-config.mjs +0 -2
  309. package/esm2022/lib/form-validators/models/config/default-config.mjs +0 -2
  310. package/esm2022/lib/form-validators/models/config/digit-config.mjs +0 -2
  311. package/esm2022/lib/form-validators/models/config/disable-config.mjs +0 -2
  312. package/esm2022/lib/form-validators/models/config/element-class-config.mjs +0 -2
  313. package/esm2022/lib/form-validators/models/config/email-config.mjs +0 -2
  314. package/esm2022/lib/form-validators/models/config/error-config.mjs +0 -2
  315. package/esm2022/lib/form-validators/models/config/extension-config.mjs +0 -2
  316. package/esm2022/lib/form-validators/models/config/factor-config.mjs +0 -2
  317. package/esm2022/lib/form-validators/models/config/field-config.mjs +0 -2
  318. package/esm2022/lib/form-validators/models/config/file-config.mjs +0 -2
  319. package/esm2022/lib/form-validators/models/config/hex-color-config.mjs +0 -2
  320. package/esm2022/lib/form-validators/models/config/iban-config.mjs +0 -2
  321. package/esm2022/lib/form-validators/models/config/image-config.mjs +0 -2
  322. package/esm2022/lib/form-validators/models/config/index.mjs +0 -35
  323. package/esm2022/lib/form-validators/models/config/ip-config.mjs +0 -2
  324. package/esm2022/lib/form-validators/models/config/logical-operator-config.mjs +0 -2
  325. package/esm2022/lib/form-validators/models/config/mask-config.mjs +0 -2
  326. package/esm2022/lib/form-validators/models/config/max-date-config.mjs +0 -2
  327. package/esm2022/lib/form-validators/models/config/message-config.mjs +0 -2
  328. package/esm2022/lib/form-validators/models/config/min-date-config.mjs +0 -2
  329. package/esm2022/lib/form-validators/models/config/model-config.mjs +0 -2
  330. package/esm2022/lib/form-validators/models/config/number-config.mjs +0 -2
  331. package/esm2022/lib/form-validators/models/config/numeric-config.mjs +0 -2
  332. package/esm2022/lib/form-validators/models/config/password-config.mjs +0 -2
  333. package/esm2022/lib/form-validators/models/config/pattern-config.mjs +0 -2
  334. package/esm2022/lib/form-validators/models/config/prop-config.mjs +0 -2
  335. package/esm2022/lib/form-validators/models/config/props-config.mjs +0 -2
  336. package/esm2022/lib/form-validators/models/config/range-config.mjs +0 -2
  337. package/esm2022/lib/form-validators/models/config/relational-operator-config.mjs +0 -2
  338. package/esm2022/lib/form-validators/models/config/required-config.mjs +0 -2
  339. package/esm2022/lib/form-validators/models/config/rule-config.mjs +0 -2
  340. package/esm2022/lib/form-validators/models/config/sanitize-config.mjs +0 -2
  341. package/esm2022/lib/form-validators/models/config/size-config.mjs +0 -2
  342. package/esm2022/lib/form-validators/models/config/string-comparison-config.mjs +0 -2
  343. package/esm2022/lib/form-validators/models/config/string-value-config.mjs +0 -2
  344. package/esm2022/lib/form-validators/models/config/time-config.mjs +0 -2
  345. package/esm2022/lib/form-validators/models/config/todate-config.mjs +0 -2
  346. package/esm2022/lib/form-validators/models/config/unique-config.mjs +0 -2
  347. package/esm2022/lib/form-validators/models/config/update-on-config.mjs +0 -2
  348. package/esm2022/lib/form-validators/models/config/url-config.mjs +0 -2
  349. package/esm2022/lib/form-validators/models/control-info.mjs +0 -2
  350. package/esm2022/lib/form-validators/models/data-sanitizer.mjs +0 -2
  351. package/esm2022/lib/form-validators/models/decorator-configuration.mjs +0 -2
  352. package/esm2022/lib/form-validators/models/form-builder-configuration.mjs +0 -58
  353. package/esm2022/lib/form-validators/models/index.mjs +0 -3
  354. package/esm2022/lib/form-validators/models/instance-container.mjs +0 -2
  355. package/esm2022/lib/form-validators/models/interface/array-prop-instance-config.interface.mjs +0 -2
  356. package/esm2022/lib/form-validators/models/interface/auto-instance-config.interface.mjs +0 -2
  357. package/esm2022/lib/form-validators/models/interface/form-data-config.mjs +0 -2
  358. package/esm2022/lib/form-validators/models/interface/i-abstract-control.mjs +0 -30
  359. package/esm2022/lib/form-validators/models/interface/i-form-group.mjs +0 -2
  360. package/esm2022/lib/form-validators/models/interface/instance-argument.interface.mjs +0 -2
  361. package/esm2022/lib/form-validators/models/interface/object-prop-instance-config.interface.mjs +0 -2
  362. package/esm2022/lib/form-validators/models/interface/options.mjs +0 -2
  363. package/esm2022/lib/form-validators/models/password-validation.model.mjs +0 -2
  364. package/esm2022/lib/form-validators/models/prop-validation-config.mjs +0 -2
  365. package/esm2022/lib/form-validators/models/property-info.mjs +0 -2
  366. package/esm2022/lib/form-validators/public_api.mjs +0 -26
  367. package/esm2022/lib/form-validators/reactive-form-validators/allOf.validator.mjs +0 -33
  368. package/esm2022/lib/form-validators/reactive-form-validators/alpha.validator.mjs +0 -15
  369. package/esm2022/lib/form-validators/reactive-form-validators/alphaNumeric.validator.mjs +0 -15
  370. package/esm2022/lib/form-validators/reactive-form-validators/and.validator.mjs +0 -38
  371. package/esm2022/lib/form-validators/reactive-form-validators/ascii.validator.mjs +0 -15
  372. package/esm2022/lib/form-validators/reactive-form-validators/async/base.async.validator.mjs +0 -45
  373. package/esm2022/lib/form-validators/reactive-form-validators/choice.validator.mjs +0 -31
  374. package/esm2022/lib/form-validators/reactive-form-validators/compare.validator.mjs +0 -32
  375. package/esm2022/lib/form-validators/reactive-form-validators/compose.validator.mjs +0 -34
  376. package/esm2022/lib/form-validators/reactive-form-validators/conditional-change.validator.mjs +0 -63
  377. package/esm2022/lib/form-validators/reactive-form-validators/contains.validator.mjs +0 -22
  378. package/esm2022/lib/form-validators/reactive-form-validators/credit-card.validator.mjs +0 -48
  379. package/esm2022/lib/form-validators/reactive-form-validators/cusip.validator.mjs +0 -38
  380. package/esm2022/lib/form-validators/reactive-form-validators/custom.validator.mjs +0 -25
  381. package/esm2022/lib/form-validators/reactive-form-validators/dataUri.validator.mjs +0 -9
  382. package/esm2022/lib/form-validators/reactive-form-validators/date.validator.mjs +0 -8
  383. package/esm2022/lib/form-validators/reactive-form-validators/different.validator.mjs +0 -19
  384. package/esm2022/lib/form-validators/reactive-form-validators/digit.validator.mjs +0 -9
  385. package/esm2022/lib/form-validators/reactive-form-validators/email.validator.mjs +0 -9
  386. package/esm2022/lib/form-validators/reactive-form-validators/endsWith.validator.mjs +0 -23
  387. package/esm2022/lib/form-validators/reactive-form-validators/even.validator.mjs +0 -15
  388. package/esm2022/lib/form-validators/reactive-form-validators/extension.validator.mjs +0 -40
  389. package/esm2022/lib/form-validators/reactive-form-validators/factor.validator.mjs +0 -37
  390. package/esm2022/lib/form-validators/reactive-form-validators/file.validator.mjs +0 -26
  391. package/esm2022/lib/form-validators/reactive-form-validators/fileSize.validator.mjs +0 -34
  392. package/esm2022/lib/form-validators/reactive-form-validators/greater-than-equal-to.validator.mjs +0 -8
  393. package/esm2022/lib/form-validators/reactive-form-validators/greater-than.validator.mjs +0 -8
  394. package/esm2022/lib/form-validators/reactive-form-validators/grid.validator.mjs +0 -31
  395. package/esm2022/lib/form-validators/reactive-form-validators/hexcolor.validator.mjs +0 -9
  396. package/esm2022/lib/form-validators/reactive-form-validators/iban.validator.mjs +0 -28
  397. package/esm2022/lib/form-validators/reactive-form-validators/image.validator.mjs +0 -52
  398. package/esm2022/lib/form-validators/reactive-form-validators/index.mjs +0 -66
  399. package/esm2022/lib/form-validators/reactive-form-validators/ip.validator.mjs +0 -28
  400. package/esm2022/lib/form-validators/reactive-form-validators/json.validator.mjs +0 -26
  401. package/esm2022/lib/form-validators/reactive-form-validators/latLong.validator.mjs +0 -18
  402. package/esm2022/lib/form-validators/reactive-form-validators/latitude.validator.mjs +0 -9
  403. package/esm2022/lib/form-validators/reactive-form-validators/leapYear.validator.mjs +0 -16
  404. package/esm2022/lib/form-validators/reactive-form-validators/less-than-equal-to.validator.mjs +0 -8
  405. package/esm2022/lib/form-validators/reactive-form-validators/less-than.validator.mjs +0 -8
  406. package/esm2022/lib/form-validators/reactive-form-validators/longitude.validator.mjs +0 -9
  407. package/esm2022/lib/form-validators/reactive-form-validators/lowercase.validator.mjs +0 -15
  408. package/esm2022/lib/form-validators/reactive-form-validators/mac.validator.mjs +0 -9
  409. package/esm2022/lib/form-validators/reactive-form-validators/mask.validator.mjs +0 -14
  410. package/esm2022/lib/form-validators/reactive-form-validators/maxDate.validator.mjs +0 -8
  411. package/esm2022/lib/form-validators/reactive-form-validators/maxLength.validator.mjs +0 -17
  412. package/esm2022/lib/form-validators/reactive-form-validators/maxNumber.validator.mjs +0 -17
  413. package/esm2022/lib/form-validators/reactive-form-validators/maxTime.validator.mjs +0 -8
  414. package/esm2022/lib/form-validators/reactive-form-validators/minDate.validator.mjs +0 -8
  415. package/esm2022/lib/form-validators/reactive-form-validators/minLength.validator.mjs +0 -16
  416. package/esm2022/lib/form-validators/reactive-form-validators/minNumber.validator.mjs +0 -16
  417. package/esm2022/lib/form-validators/reactive-form-validators/minTime.validator.mjs +0 -8
  418. package/esm2022/lib/form-validators/reactive-form-validators/noneOf.validator.mjs +0 -24
  419. package/esm2022/lib/form-validators/reactive-form-validators/not.validator.mjs +0 -25
  420. package/esm2022/lib/form-validators/reactive-form-validators/notEmpty.validator.mjs +0 -17
  421. package/esm2022/lib/form-validators/reactive-form-validators/numeric.validator.mjs +0 -22
  422. package/esm2022/lib/form-validators/reactive-form-validators/odd.validator.mjs +0 -17
  423. package/esm2022/lib/form-validators/reactive-form-validators/oneOf.validator.mjs +0 -26
  424. package/esm2022/lib/form-validators/reactive-form-validators/or.validator.mjs +0 -25
  425. package/esm2022/lib/form-validators/reactive-form-validators/password.validator.mjs +0 -35
  426. package/esm2022/lib/form-validators/reactive-form-validators/pattern.validator.mjs +0 -19
  427. package/esm2022/lib/form-validators/reactive-form-validators/port.validator.mjs +0 -19
  428. package/esm2022/lib/form-validators/reactive-form-validators/primeNumber.validator.mjs +0 -27
  429. package/esm2022/lib/form-validators/reactive-form-validators/range.validator.mjs +0 -17
  430. package/esm2022/lib/form-validators/reactive-form-validators/required.validator.mjs +0 -17
  431. package/esm2022/lib/form-validators/reactive-form-validators/requiredTrue.validator.mjs +0 -16
  432. package/esm2022/lib/form-validators/reactive-form-validators/rule.validator.mjs +0 -22
  433. package/esm2022/lib/form-validators/reactive-form-validators/startsWith.validator.mjs +0 -25
  434. package/esm2022/lib/form-validators/reactive-form-validators/time.validator.mjs +0 -19
  435. package/esm2022/lib/form-validators/reactive-form-validators/unique.validator.mjs +0 -77
  436. package/esm2022/lib/form-validators/reactive-form-validators/uppercase.validator.mjs +0 -16
  437. package/esm2022/lib/form-validators/reactive-form-validators/url.validator.mjs +0 -28
  438. package/esm2022/lib/form-validators/services/base-form-builder.mjs +0 -220
  439. package/esm2022/lib/form-validators/services/entity.service.mjs +0 -76
  440. package/esm2022/lib/form-validators/services/form-control.mjs +0 -370
  441. package/esm2022/lib/form-validators/services/form-group.mjs +0 -2
  442. package/esm2022/lib/form-validators/services/reactive-form.module.mjs +0 -52
  443. package/esm2022/lib/form-validators/services/rx-form-array.mjs +0 -114
  444. package/esm2022/lib/form-validators/services/rx-form-builder.mjs +0 -1035
  445. package/esm2022/lib/form-validators/services/rx-form-group.mjs +0 -451
  446. package/esm2022/lib/form-validators/services/typed-form-builder.mjs +0 -25
  447. package/esm2022/lib/form-validators/util/alphabet-regex.locale.mjs +0 -29
  448. package/esm2022/lib/form-validators/util/app-util.mjs +0 -161
  449. package/esm2022/lib/form-validators/util/check-length.mjs +0 -11
  450. package/esm2022/lib/form-validators/util/config-provider.mjs +0 -37
  451. package/esm2022/lib/form-validators/util/date-checker.function.mjs +0 -52
  452. package/esm2022/lib/form-validators/util/date-provider.mjs +0 -108
  453. package/esm2022/lib/form-validators/util/form-const.mjs +0 -3
  454. package/esm2022/lib/form-validators/util/form-provider.mjs +0 -87
  455. package/esm2022/lib/form-validators/util/index.mjs +0 -7
  456. package/esm2022/lib/form-validators/util/instance-provider.function.mjs +0 -63
  457. package/esm2022/lib/form-validators/util/ip-checker.mjs +0 -19
  458. package/esm2022/lib/form-validators/util/linq.mjs +0 -157
  459. package/esm2022/lib/form-validators/util/object-maker.mjs +0 -68
  460. package/esm2022/lib/form-validators/util/reactive-form-config.mjs +0 -25
  461. package/esm2022/lib/form-validators/util/regex-rules.mjs +0 -37
  462. package/esm2022/lib/form-validators/util/regex-validator.mjs +0 -74
  463. package/esm2022/lib/form-validators/util/relational-checker.function.mjs +0 -92
  464. package/esm2022/lib/form-validators/util/reset-form.mjs +0 -57
  465. package/esm2022/lib/form-validators/util/sanitizers.mjs +0 -140
  466. package/esm2022/lib/form-validators/util/time-checker.function.mjs +0 -50
  467. package/esm2022/lib/form-validators/util/type.mjs +0 -2
  468. package/esm2022/lib/form-validators/util/validator-value-checker.mjs +0 -21
  469. package/esm2022/lib/form-validators/validators-extension/allOf-validator.extension.mjs +0 -11
  470. package/esm2022/lib/form-validators/validators-extension/alpha-validator.extension.mjs +0 -11
  471. package/esm2022/lib/form-validators/validators-extension/alphaNumeric-validator.extension.mjs +0 -11
  472. package/esm2022/lib/form-validators/validators-extension/and-validator.extension.mjs +0 -7
  473. package/esm2022/lib/form-validators/validators-extension/ascii-validator.extension.mjs +0 -7
  474. package/esm2022/lib/form-validators/validators-extension/base-validator.function.mjs +0 -34
  475. package/esm2022/lib/form-validators/validators-extension/choice-validator.extension.mjs +0 -11
  476. package/esm2022/lib/form-validators/validators-extension/compare-validator.extension.mjs +0 -7
  477. package/esm2022/lib/form-validators/validators-extension/compose-validator.extension.mjs +0 -7
  478. package/esm2022/lib/form-validators/validators-extension/contains-validator.extension.mjs +0 -11
  479. package/esm2022/lib/form-validators/validators-extension/credit-card-validator.extension.mjs +0 -11
  480. package/esm2022/lib/form-validators/validators-extension/cusip-validator.extension.mjs +0 -7
  481. package/esm2022/lib/form-validators/validators-extension/custom-validator.extension.mjs +0 -11
  482. package/esm2022/lib/form-validators/validators-extension/dataUri-validator.extension.mjs +0 -7
  483. package/esm2022/lib/form-validators/validators-extension/date-validator.extension.mjs +0 -11
  484. package/esm2022/lib/form-validators/validators-extension/different-validator.extension.mjs +0 -7
  485. package/esm2022/lib/form-validators/validators-extension/digit-validator.extension.mjs +0 -7
  486. package/esm2022/lib/form-validators/validators-extension/email-validator.extension.mjs +0 -7
  487. package/esm2022/lib/form-validators/validators-extension/endsWith-validator.extension.mjs +0 -11
  488. package/esm2022/lib/form-validators/validators-extension/even-validator.extension.mjs +0 -7
  489. package/esm2022/lib/form-validators/validators-extension/extension-validator.extension.mjs +0 -10
  490. package/esm2022/lib/form-validators/validators-extension/factor-validator.extension.mjs +0 -11
  491. package/esm2022/lib/form-validators/validators-extension/file-validator.extension.mjs +0 -10
  492. package/esm2022/lib/form-validators/validators-extension/fileSize-validator.extension.mjs +0 -10
  493. package/esm2022/lib/form-validators/validators-extension/greater-than-equal-to-validator.extension.mjs +0 -11
  494. package/esm2022/lib/form-validators/validators-extension/greater-than-validator.extension.mjs +0 -11
  495. package/esm2022/lib/form-validators/validators-extension/grid-validator.extension.mjs +0 -7
  496. package/esm2022/lib/form-validators/validators-extension/hexcolor-validator.extension.mjs +0 -7
  497. package/esm2022/lib/form-validators/validators-extension/iban-validator.extension.mjs +0 -11
  498. package/esm2022/lib/form-validators/validators-extension/image-validator.extension.mjs +0 -10
  499. package/esm2022/lib/form-validators/validators-extension/index.mjs +0 -68
  500. package/esm2022/lib/form-validators/validators-extension/ip-validator.extension.mjs +0 -11
  501. package/esm2022/lib/form-validators/validators-extension/json-validator.extension.mjs +0 -7
  502. package/esm2022/lib/form-validators/validators-extension/latLong-validator.extension.mjs +0 -7
  503. package/esm2022/lib/form-validators/validators-extension/latitude-validator.extension.mjs +0 -7
  504. package/esm2022/lib/form-validators/validators-extension/leapYear-validator.extension.mjs +0 -7
  505. package/esm2022/lib/form-validators/validators-extension/less-than-equal-to-validator.extension.mjs +0 -11
  506. package/esm2022/lib/form-validators/validators-extension/less-than-validator.extension.mjs +0 -11
  507. package/esm2022/lib/form-validators/validators-extension/longitude-validator.extension.mjs +0 -7
  508. package/esm2022/lib/form-validators/validators-extension/lowercase-validator.extension.mjs +0 -7
  509. package/esm2022/lib/form-validators/validators-extension/mac-validator.extension.mjs +0 -7
  510. package/esm2022/lib/form-validators/validators-extension/mask-validator.extension.mjs +0 -7
  511. package/esm2022/lib/form-validators/validators-extension/maxDate-validator.extension.mjs +0 -11
  512. package/esm2022/lib/form-validators/validators-extension/maxLength-validator.extension.mjs +0 -11
  513. package/esm2022/lib/form-validators/validators-extension/maxNumber-validator.extension.mjs +0 -11
  514. package/esm2022/lib/form-validators/validators-extension/maxTime-validator.extension.mjs +0 -11
  515. package/esm2022/lib/form-validators/validators-extension/minDate-validator.extension.mjs +0 -11
  516. package/esm2022/lib/form-validators/validators-extension/minLength-validator.extension.mjs +0 -11
  517. package/esm2022/lib/form-validators/validators-extension/minNumber-validator.extension.mjs +0 -11
  518. package/esm2022/lib/form-validators/validators-extension/minTime-validator.extension.mjs +0 -11
  519. package/esm2022/lib/form-validators/validators-extension/noneOf-validator.extension.mjs +0 -11
  520. package/esm2022/lib/form-validators/validators-extension/not-validator.extension.mjs +0 -7
  521. package/esm2022/lib/form-validators/validators-extension/notEmpty-validator.extension.mjs +0 -7
  522. package/esm2022/lib/form-validators/validators-extension/numeric-validator.extension.mjs +0 -11
  523. package/esm2022/lib/form-validators/validators-extension/odd-validator.extension.mjs +0 -7
  524. package/esm2022/lib/form-validators/validators-extension/oneOf-validator.extension.mjs +0 -11
  525. package/esm2022/lib/form-validators/validators-extension/or-validator.extension.mjs +0 -7
  526. package/esm2022/lib/form-validators/validators-extension/password-validator.extension.mjs +0 -11
  527. package/esm2022/lib/form-validators/validators-extension/pattern-validator.extension.mjs +0 -11
  528. package/esm2022/lib/form-validators/validators-extension/port-validator.extension.mjs +0 -7
  529. package/esm2022/lib/form-validators/validators-extension/primeNumber-validator.extension.mjs +0 -7
  530. package/esm2022/lib/form-validators/validators-extension/range-validator.extension.mjs +0 -11
  531. package/esm2022/lib/form-validators/validators-extension/required-validator.extension.mjs +0 -7
  532. package/esm2022/lib/form-validators/validators-extension/requiredTrue-validator.extension.mjs +0 -7
  533. package/esm2022/lib/form-validators/validators-extension/rxweb-validators.mjs +0 -108
  534. package/esm2022/lib/form-validators/validators-extension/startsWith-validator.extension.mjs +0 -11
  535. package/esm2022/lib/form-validators/validators-extension/time-validator.extension.mjs +0 -11
  536. package/esm2022/lib/form-validators/validators-extension/unique-validator.extension.mjs +0 -7
  537. package/esm2022/lib/form-validators/validators-extension/uppercase-validator.extension.mjs +0 -7
  538. package/esm2022/lib/form-validators/validators-extension/url-validator.extension.mjs +0 -11
  539. package/esm2022/lib/form-validators/validators-function/alpha-validation.function.mjs +0 -71
  540. package/esm2022/lib/form-validators/validators-function/regex-validation.function.mjs +0 -33
  541. package/esm2022/lib/forms/components/datepicker/datepicker-header.component.mjs +0 -84
  542. package/esm2022/lib/forms/components/generic-form/generic-form.component.mjs +0 -602
  543. package/esm2022/lib/forms/constants/constants.mjs +0 -4
  544. package/esm2022/lib/forms/directives/mat-form-field-editor.directive.mjs +0 -197
  545. package/esm2022/lib/forms/directives/mat-form-field-readonly.directive.mjs +0 -34
  546. package/esm2022/lib/forms/directives/parse-decimal-directive.mjs +0 -87
  547. package/esm2022/lib/forms/directives/vd-generic-form-custom-field.directive.mjs +0 -35
  548. package/esm2022/lib/forms/enums/form-field-type.mjs +0 -23
  549. package/esm2022/lib/forms/forms.module.mjs +0 -168
  550. package/esm2022/lib/forms/functions/decorators.mjs +0 -136
  551. package/esm2022/lib/forms/functions/functions.mjs +0 -72
  552. package/esm2022/lib/forms/helpers/abstract-mat-form-field.mjs +0 -308
  553. package/esm2022/lib/forms/helpers/abstract-select-form-field.component.mjs +0 -492
  554. package/esm2022/lib/forms/helpers/value-accessor-base.mjs +0 -146
  555. package/esm2022/lib/forms/models/form-definition.mjs +0 -63
  556. package/esm2022/lib/forms/models/form-field-definition.mjs +0 -468
  557. package/esm2022/lib/forms/models/form-field-group-definition.mjs +0 -55
  558. package/esm2022/lib/forms/pipes/field-func.pipe.mjs +0 -23
  559. package/esm2022/lib/forms/pipes/group-filter.pipe.mjs +0 -34
  560. package/esm2022/lib/forms/public_api.mjs +0 -5
  561. package/esm2022/lib/forms/validators/empty-string-reset.directive.mjs +0 -25
  562. package/esm2022/lib/forms/validators/equal-validator.directive.mjs +0 -69
  563. package/esm2022/lib/forms/validators/native-element-injector.directive.mjs +0 -41
  564. package/esm2022/lib/forms/validators/unique-validator-directive.mjs +0 -88
  565. package/esm2022/lib/http/http.module.mjs +0 -15
  566. package/esm2022/lib/http/models/response.mjs +0 -24
  567. package/esm2022/lib/http/public_api.mjs +0 -2
  568. package/esm2022/lib/http/services/generic.service.mjs +0 -331
  569. package/esm2022/lib/layout/dynamic-menu/dynamic-menu.component.mjs +0 -103
  570. package/esm2022/lib/layout/layout-card-over/layout-card-over.component.mjs +0 -49
  571. package/esm2022/lib/layout/layout-compact/layout-compact.component.mjs +0 -193
  572. package/esm2022/lib/layout/layout-footer/layout-footer.component.mjs +0 -37
  573. package/esm2022/lib/layout/layout-manage-list/layout-manage-list.component.mjs +0 -150
  574. package/esm2022/lib/layout/layout-manage-list/layout-manage-list.directives.mjs +0 -108
  575. package/esm2022/lib/layout/layout-nav/layout-nav.component.mjs +0 -146
  576. package/esm2022/lib/layout/layout-nav-list/layout-nav-list.component.mjs +0 -141
  577. package/esm2022/lib/layout/layout-nav-list/layout-nav-list.directives.mjs +0 -105
  578. package/esm2022/lib/layout/layout-toggle.class.mjs +0 -89
  579. package/esm2022/lib/layout/layout.component.mjs +0 -230
  580. package/esm2022/lib/layout/layout.directives.mjs +0 -81
  581. package/esm2022/lib/layout/layout.module.mjs +0 -144
  582. package/esm2022/lib/layout/list-toolbar/list-toolbar.component.mjs +0 -47
  583. package/esm2022/lib/layout/navigation-drawer/navigation-drawer.component.mjs +0 -275
  584. package/esm2022/lib/layout/public_api.mjs +0 -2
  585. package/esm2022/lib/list/components/list.component.mjs +0 -78
  586. package/esm2022/lib/list/directives/vd-list-option.directive.mjs +0 -23
  587. package/esm2022/lib/list/list.module.mjs +0 -36
  588. package/esm2022/lib/list/public_api.mjs +0 -3
  589. package/esm2022/lib/media/directives/media-toggle.directive.mjs +0 -154
  590. package/esm2022/lib/media/media.module.mjs +0 -35
  591. package/esm2022/lib/media/public_api.mjs +0 -2
  592. package/esm2022/lib/media/services/media.service.mjs +0 -110
  593. package/esm2022/lib/menu/components/menu.component.mjs +0 -95
  594. package/esm2022/lib/menu/enums/menu-scope.mjs +0 -6
  595. package/esm2022/lib/menu/menu.module.mjs +0 -64
  596. package/esm2022/lib/menu/models/menu-client.mjs +0 -39
  597. package/esm2022/lib/menu/models/menu-department.mjs +0 -39
  598. package/esm2022/lib/menu/models/menu-item-client.mjs +0 -39
  599. package/esm2022/lib/menu/models/menu-item-department.mjs +0 -39
  600. package/esm2022/lib/menu/models/menu-item.mjs +0 -351
  601. package/esm2022/lib/menu/models/menu-settings.mjs +0 -13
  602. package/esm2022/lib/menu/models/menu.mjs +0 -224
  603. package/esm2022/lib/menu/public_api.mjs +0 -3
  604. package/esm2022/lib/menu/resolvers/menu-form-includes.resolve.mjs +0 -50
  605. package/esm2022/lib/menu/resolvers/menu-item-form-includes.resolve.mjs +0 -50
  606. package/esm2022/lib/menu/resolvers/menu-list-projection.resolve.mjs +0 -51
  607. package/esm2022/lib/menu/resolvers/menu-settings.resolve.mjs +0 -24
  608. package/esm2022/lib/menu/services/menu-items.service.mjs +0 -19
  609. package/esm2022/lib/menu/services/menu.resolve.mjs +0 -68
  610. package/esm2022/lib/menu/services/menu.service.mjs +0 -19
  611. package/esm2022/lib/search/public_api.mjs +0 -2
  612. package/esm2022/lib/search/search.module.mjs +0 -33
  613. package/esm2022/lib/select/components/select.component.mjs +0 -215
  614. package/esm2022/lib/select/directives/vd-select-option.directive.mjs +0 -23
  615. package/esm2022/lib/select/directives/vd-select-trigger.directive.mjs +0 -23
  616. package/esm2022/lib/select/public_api.mjs +0 -4
  617. package/esm2022/lib/select/select.module.mjs +0 -48
  618. package/esm2022/lib/table/components/dynamic-table/dynamic-table.component.mjs +0 -810
  619. package/esm2022/lib/table/components/filter-clear/filter-clear.component.mjs +0 -36
  620. package/esm2022/lib/table/components/filter-date/filter-date.component.mjs +0 -146
  621. package/esm2022/lib/table/components/filter-input/filter-input.component.mjs +0 -198
  622. package/esm2022/lib/table/components/filter-select/filter-select.component.mjs +0 -375
  623. package/esm2022/lib/table/constants/constants.mjs +0 -3
  624. package/esm2022/lib/table/directives/data-source-filter.directive.mjs +0 -49
  625. package/esm2022/lib/table/directives/vd-table-field.directive.mjs +0 -35
  626. package/esm2022/lib/table/enums/grid.mjs +0 -12
  627. package/esm2022/lib/table/enums/table-column-type.mjs +0 -17
  628. package/esm2022/lib/table/functions/decorators.mjs +0 -163
  629. package/esm2022/lib/table/functions/functions.mjs +0 -28
  630. package/esm2022/lib/table/models/facet-value.mjs +0 -47
  631. package/esm2022/lib/table/models/facet.mjs +0 -48
  632. package/esm2022/lib/table/models/pagination.mjs +0 -27
  633. package/esm2022/lib/table/models/table-column-config.mjs +0 -128
  634. package/esm2022/lib/table/models/table-column.mjs +0 -270
  635. package/esm2022/lib/table/models/table-config.mjs +0 -41
  636. package/esm2022/lib/table/models/table-definition.mjs +0 -110
  637. package/esm2022/lib/table/models/table-query-config.mjs +0 -26
  638. package/esm2022/lib/table/paginator-intl.mjs +0 -41
  639. package/esm2022/lib/table/public_api.mjs +0 -2
  640. package/esm2022/lib/table/table.data-source.mjs +0 -326
  641. package/esm2022/lib/table/table.module.mjs +0 -165
  642. package/esm2022/lib/table/table.static-data-source.mjs +0 -198
  643. package/esm2022/messaia-cdk.mjs +0 -5
  644. package/esm2022/public_api.mjs +0 -19
  645. package/lib/common/styles/_elevation.scss +0 -147
  646. package/lib/common/styles/_rtl.scss +0 -28
  647. package/lib/common/styles/_styles.scss +0 -12
  648. package/lib/common/styles/_theme-functions.scss +0 -4
  649. package/lib/common/styles/_typography.scss +0 -76
  650. package/lib/common/styles/core/_content.scss +0 -42
  651. package/lib/common/styles/core/_divider.scss +0 -14
  652. package/lib/common/styles/core/_icons.scss +0 -27
  653. package/lib/common/styles/core/_list.scss +0 -8
  654. package/lib/common/styles/core/_toolbar.scss +0 -31
  655. package/lib/common/styles/core/_whiteframe.scss +0 -111
  656. package/lib/common/styles/m2/_theme-functions.scss +0 -21
  657. package/lib/common/styles/m3/_theme-functions.scss +0 -21
  658. package/lib/common/theming/_all-theme.scss +0 -27
  659. package/lib/common/typography/_all-typography.scss +0 -33
@@ -1,602 +0,0 @@
1
- import { COMMA, ENTER } from '@angular/cdk/keycodes';
2
- import { CdkPortal } from '@angular/cdk/portal';
3
- import { Component, ContentChild, ContentChildren, Directive, Input, QueryList, SimpleChange, TemplateRef, Type, ViewContainerRef } from '@angular/core';
4
- import { FormGroup, Validators } from '@angular/forms';
5
- import { VdGenericFormCustomFieldDirective } from '../../directives/vd-generic-form-custom-field.directive';
6
- import { FormFieldType } from '../../enums/form-field-type';
7
- import { getFormDefinition } from '../../functions/functions';
8
- import { FormDefinition } from '../../models/form-definition';
9
- import { DatePickerHeaderComponent } from '../datepicker/datepicker-header.component';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/common";
12
- import * as i2 from "../../../common/directives/disable-control.directive";
13
- import * as i3 from "../../../common/pipes/only-number";
14
- import * as i4 from "../../../common/directives/autofocus.directive";
15
- import * as i5 from "../../../select/components/select.component";
16
- import * as i6 from "../../../select/directives/vd-select-option.directive";
17
- import * as i7 from "../../../select/directives/vd-select-trigger.directive";
18
- import * as i8 from "../../../chips/components/chips.component";
19
- import * as i9 from "../../../chips/directives/autocomplete-option.directive";
20
- import * as i10 from "../../../chips/directives/chip.directive";
21
- import * as i11 from "../../../file/file-input.component";
22
- import * as i12 from "../../../list/components/list.component";
23
- import * as i13 from "../../../list/directives/vd-list-option.directive";
24
- import * as i14 from "@angular/forms";
25
- import * as i15 from "@angular/material/form-field";
26
- import * as i16 from "@angular/material/select";
27
- import * as i17 from "@angular/material/core";
28
- import * as i18 from "@angular/material/icon";
29
- import * as i19 from "@angular/material/input";
30
- import * as i20 from "@angular/material/button";
31
- import * as i21 from "@angular/material/datepicker";
32
- import * as i22 from "@angular/material/checkbox";
33
- import * as i23 from "@angular/material/autocomplete";
34
- import * as i24 from "@angular/material/chips";
35
- import * as i25 from "ngx-colors";
36
- import * as i26 from "../../validators/empty-string-reset.directive";
37
- import * as i27 from "../../directives/mat-form-field-readonly.directive";
38
- import * as i28 from "../../validators/native-element-injector.directive";
39
- import * as i29 from "../../directives/parse-decimal-directive";
40
- import * as i30 from "../../../common/pipes/func.pipe";
41
- /**
42
- * @class VdEditorDirective
43
- * @description The `VdEditorDirective` is a custom directive that attaches a `CdkPortal`
44
- * to a template with the `vd-editor` selector. It allows content to be dynamically rendered
45
- * inside the component, using a template reference.
46
- */
47
- export class VdEditorDirective extends CdkPortal {
48
- /**
49
- * @constructor
50
- * @param {TemplateRef<any>} templateRef - The reference to the template to be rendered.
51
- * @param {ViewContainerRef} viewContainerRef - The container where the template will be inserted.
52
- */
53
- constructor(templateRef, viewContainerRef) {
54
- super(templateRef, viewContainerRef);
55
- }
56
- /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdEditorDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
57
- /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.7", type: VdEditorDirective, selector: "[vd-editor]ng-template", usesInheritance: true, ngImport: i0 });
58
- }
59
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdEditorDirective, decorators: [{
60
- type: Directive,
61
- args: [{ selector: '[vd-editor]ng-template' }]
62
- }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }] });
63
- /**
64
- * @class VdCodeDirective
65
- * @description The `VdCodeDirective` is a custom directive that attaches a `CdkPortal`
66
- * to a template with the `vd-code` selector. It is used to dynamically render code blocks
67
- * inside the component, using a template reference.
68
- */
69
- export class VdCodeDirective extends CdkPortal {
70
- /**
71
- * @constructor
72
- * @param {TemplateRef<any>} templateRef - The reference to the template to be rendered.
73
- * @param {ViewContainerRef} viewContainerRef - The container where the template will be inserted.
74
- */
75
- constructor(templateRef, viewContainerRef) {
76
- super(templateRef, viewContainerRef);
77
- }
78
- /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdCodeDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
79
- /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.7", type: VdCodeDirective, selector: "[vd-code]ng-template", usesInheritance: true, ngImport: i0 });
80
- }
81
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdCodeDirective, decorators: [{
82
- type: Directive,
83
- args: [{ selector: '[vd-code]ng-template' }]
84
- }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }] });
85
- /**
86
- * @class VdFileDirective
87
- * @description The `VdFileDirective` is a custom directive that attaches a `CdkPortal`
88
- * to a template with the `vd-file` selector. It enables the dynamic rendering of file-related
89
- * content inside the component, using a template reference.
90
- */
91
- export class VdFileDirective extends CdkPortal {
92
- /**
93
- * @constructor
94
- * @param {TemplateRef<any>} templateRef - The reference to the template to be rendered.
95
- * @param {ViewContainerRef} viewContainerRef - The container where the template will be inserted.
96
- */
97
- constructor(templateRef, viewContainerRef) {
98
- super(templateRef, viewContainerRef);
99
- }
100
- /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdFileDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
101
- /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.7", type: VdFileDirective, selector: "[vd-file]ng-template", usesInheritance: true, ngImport: i0 });
102
- }
103
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdFileDirective, decorators: [{
104
- type: Directive,
105
- args: [{ selector: '[vd-file]ng-template' }]
106
- }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }] });
107
- /**
108
- * @class VdCustomDirective
109
- * @description The `VdCustomDirective` is a custom directive that attaches a `CdkPortal`
110
- * to a template with the `vd-custom` selector. It allows custom content to be dynamically
111
- * rendered inside the component, using a template reference.
112
- */
113
- export class VdCustomDirective extends CdkPortal {
114
- /**
115
- * @constructor
116
- * @param {TemplateRef<any>} templateRef - The reference to the template to be rendered.
117
- * @param {ViewContainerRef} viewContainerRef - The container where the template will be inserted.
118
- */
119
- constructor(templateRef, viewContainerRef) {
120
- super(templateRef, viewContainerRef);
121
- }
122
- /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdCustomDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
123
- /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.7", type: VdCustomDirective, selector: "[vd-custom]ng-template", usesInheritance: true, ngImport: i0 });
124
- }
125
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdCustomDirective, decorators: [{
126
- type: Directive,
127
- args: [{ selector: '[vd-custom]ng-template' }]
128
- }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }] });
129
- export class VdGenericFormComponent {
130
- /**
131
- * @property Form group associated with the form.
132
- * @description The `formGroup` is an instance of `FormGroup` that holds the controls and validation rules
133
- * for the form.
134
- * @type {FormGroup}
135
- */
136
- formGroup;
137
- /**
138
- * @property Raw value of the form.
139
- * @description This getter returns the raw values of all controls in the form as an object,
140
- * which does not include any validation or status information.
141
- * @type {any}
142
- */
143
- get formValue() { return this.formGroup?.getRawValue(); }
144
- /**
145
- * @property Specifies the class type for the form.
146
- * @description The `classType` is a generic type used to define the form's structure and behavior.
147
- * @type {Type<any>}
148
- */
149
- classType;
150
- /**
151
- * @property The definition of the form structure.
152
- * @description The `formDefinition` holds the structure and metadata of the form
153
- * to dynamically generate form fields and validation rules.
154
- * @type {FormDefinition}
155
- */
156
- formDefinition;
157
- /**
158
- * @property Array of form field groups.
159
- * @description The `fieldGroups` define groups of fields used in the form, enabling organization and structure
160
- * of the form sections.
161
- * @type {FormFieldGroupDefinition[]}
162
- */
163
- fieldGroups;
164
- /**
165
- * @property Name of the form group.
166
- * @description The `groupName` is a string used to identify and target a specific group of form fields
167
- * within the form.
168
- * @type {string}
169
- */
170
- groupName;
171
- /**
172
- * @property List of field sets.
173
- * @description The `fieldSets` array is used to filter and group form fields based on specific sets,
174
- * allowing dynamic field rendering.
175
- * @type {string[]}
176
- */
177
- fieldSets;
178
- /**
179
- * @property Context for the form.
180
- * @description The `context` represents the current context or environment in which the form is being used,
181
- * providing necessary information for field rendering and validation.
182
- * @type {any}
183
- */
184
- context;
185
- /**
186
- * @property Flag indicating if debugging is enabled.
187
- * @description The `debugValue` flag is used to enable or disable debugging features like logging
188
- * or additional UI components to facilitate troubleshooting.
189
- * @type {boolean}
190
- */
191
- debugValue = false;
192
- /**
193
- * @property Flag indicating if the form is read-only.
194
- * @description The `readonly` flag determines whether the form fields can be edited or not.
195
- * If set to `true`, the form fields are disabled for editing.
196
- * @type {boolean}
197
- */
198
- readonly;
199
- /**
200
- * @property Key codes used for separating input values.
201
- * @description The `separatorKeysCodes` is an array of key codes (e.g., for comma or enter) used for
202
- * separating values in input fields like tags or chips.
203
- * @type {number[]}
204
- */
205
- separatorKeysCodes = [ENTER, COMMA];
206
- /**
207
- * @property Array of field rows.
208
- * @description The `fieldRows` represent the layout and organization of form fields grouped in rows.
209
- * Each row contains an array of `FormFieldDefinition` objects.
210
- * @type {FormFieldDefinition[][]}
211
- */
212
- fieldRows;
213
- /**
214
- * @property Array of form fields.
215
- * @description The `fields` array holds the list of form fields to be rendered, each defined by a `FormFieldDefinition`.
216
- * @type {FormFieldDefinition[]}
217
- */
218
- fields;
219
- /**
220
- * @property The `FormFieldType` enumeration.
221
- * @description The `FormFieldType` is an enum used to classify different types of form fields, such as
222
- * text, checkbox, file, etc.
223
- * @type {typeof FormFieldType}
224
- */
225
- FormFieldType = FormFieldType;
226
- /**
227
- * @property Editor template content.
228
- * @description The `editorTemplate` holds the content for the editor section, which can be customized
229
- * using a `VdEditorDirective`.
230
- * @type {VdEditorDirective}
231
- */
232
- editorTemplate;
233
- /**
234
- * @property Code template content.
235
- * @description The `codeTemplate` holds the content for the code section, which can be customized
236
- * using a `VdCodeDirective`.
237
- * @type {VdCodeDirective}
238
- */
239
- codeTemplate;
240
- /**
241
- * @property File template content.
242
- * @description The `fileTemplate` holds the content for the file upload section, which can be customized
243
- * using a `VdFileDirective`.
244
- * @type {VdFileDirective}
245
- */
246
- fileTemplate;
247
- /**
248
- * @property Custom template content.
249
- * @description The `customTemplate` holds the content for custom form sections, which can be customized
250
- * using a `VdCustomDirective`.
251
- * @type {VdCustomDirective}
252
- */
253
- customTemplate;
254
- /**
255
- * @property Date picker header component.
256
- * @description The `datePickerHeaderComponent` represents the component used for displaying a custom
257
- * header in the date picker.
258
- * @type {DatePickerHeaderComponent}
259
- */
260
- datePickerHeaderComponent = DatePickerHeaderComponent;
261
- /**
262
- * @property Template reference for custom fields at the bottom.
263
- * @description The `bottom` template reference is used to display custom fields at the bottom of the form
264
- * if needed.
265
- * @type {TemplateRef<any>}
266
- */
267
- bottom;
268
- /**
269
- * @property Template reference for custom fields.
270
- * @description The `customFields` template reference is used to render custom fields in the form as defined
271
- * by the user.
272
- * @type {TemplateRef<any>}
273
- */
274
- customFields;
275
- /**
276
- * @property Template references for custom fields.
277
- * @description The `customFieldsTemplates` holds a collection of `VdGenericFormCustomFieldDirective` templates
278
- * used for rendering custom fields in the form.
279
- * @type {QueryList<VdGenericFormCustomFieldDirective>}
280
- */
281
- customFieldsTemplates;
282
- /**
283
- * @property Filtered options for autocomplete fields.
284
- * @description The `autocompleteFilteredOptions` holds the options for autocomplete fields after they have
285
- * been filtered based on the user input.
286
- * @type {any}
287
- */
288
- autocompleteFilteredOptions = {};
289
- /**
290
- * A callback method that is invoked immediately after the
291
- * default change detector has checked the directive's
292
- * data-bound properties for the first time,
293
- * and before any of the view or content children have been checked.
294
- * It is invoked only once when the directive is instantiated.
295
- */
296
- ngOnInit() {
297
- /* Build the form fields if a class type is defined */
298
- if (this.classType /*&& !this.fieldGroups*/) {
299
- this.buildFields();
300
- }
301
- /* Retrieve the field rows matching the specified group name, excluding hidden groups */
302
- let fieldRows = this.fieldGroups?.filter(x => x.name?.trim() == this.groupName?.trim() &&
303
- !x.hidden)[0]?.groups;
304
- /* Clone the field rows to avoid modifying the original data */
305
- if (fieldRows) {
306
- this.fieldRows = fieldRows.map(a => [...a.map(y => ({ ...y }))]);
307
- }
308
- /* Filter the fields to retain only those belonging to the specified field sets */
309
- if (this.fieldSets && this.fieldRows) {
310
- this.fieldRows = this.fieldRows
311
- .map(x => x.filter(y => y.fieldSets?.some(z => this.fieldSets?.some(a => a?.trim()?.toLowerCase() == z?.trim()?.toLowerCase()))))
312
- .filter(x => x.length); // Remove empty rows
313
- }
314
- /* Flatten the field rows to extract all fields and clone them */
315
- let fields = this.fieldRows?.reduce((a, b) => a.concat(b), []);
316
- if (fields) {
317
- this.fields = fields.map(a => ({ ...a }));
318
- }
319
- /* Subscribe to value change events for fields with custom 'change' handlers */
320
- fields
321
- ?.filter(y => y.type != FormFieldType.File && y.change)
322
- ?.forEach(x => {
323
- this.formGroup
324
- ?.get(x.name ?? '')
325
- ?.valueChanges?.subscribe(y => x.change?.(y, this.formGroup?.value, this.formGroup, this.context));
326
- });
327
- /**
328
- * Updates the dynamic properties (type, label, options, etc.) of a field.
329
- * @param orgField - The original field definition.
330
- * @param x - The current field instance being updated.
331
- */
332
- let updateFormField = (orgField, x) => {
333
- /* Retrieve and render the field type */
334
- x.type = typeof orgField?.type === 'function'
335
- ? orgField.type(this.formValue, this.formGroup, this.context)
336
- : x.type;
337
- /* Retrieve and render the field label */
338
- x.label = typeof orgField?.label === 'function'
339
- ? orgField.label(this.formValue, this.formGroup, this.context)
340
- : x.label;
341
- /* Retrieve and render the field options */
342
- x.options = typeof orgField?.options === 'function'
343
- ? orgField.options(this.formValue, this.formGroup, this.context)
344
- : x.options;
345
- /* Get the form control associated with the field */
346
- let formControl = this.formGroup?.get(x.name ?? '');
347
- /* Check if the field is required and update validators accordingly */
348
- let required = typeof x.required === 'function' ? x.required(this.formValue, this.formGroup, this.context) : x.required;
349
- if (formControl && required !== undefined) {
350
- if (required === true) {
351
- formControl.addValidators(Validators.required);
352
- }
353
- else {
354
- formControl.removeValidators(Validators.required);
355
- }
356
- }
357
- };
358
- /* Update dynamic properties for each field and subscribe to form value changes */
359
- fields?.forEach(x => {
360
- const orgField = this.fields?.find(y => y.name == x.name);
361
- if (orgField) {
362
- updateFormField(orgField, x);
363
- this.formGroup?.valueChanges?.subscribe(() => updateFormField(orgField, x));
364
- }
365
- });
366
- }
367
- /**
368
- * Handles the autocomplete event by filtering options based on user input.
369
- * @param field - The field definition for which autocomplete is handled.
370
- * @param event - The input event containing the current value.
371
- */
372
- filterAutocomplete(field, event) {
373
- if (field.name) {
374
- this.autocompleteFilteredOptions[field.name] = field.options
375
- ?.filter(option => option.name.toLowerCase().includes(event.value?.toString()?.toLowerCase()));
376
- }
377
- }
378
- /**
379
- * Adds a chip when an autocomplete value is selected.
380
- * @param field - The form field definition where the chip is added.
381
- * @param event - The event containing the selected autocomplete option.
382
- * @param chipInputEvent - The input event associated with the chip input.
383
- */
384
- autocompleteValueSelected(field, event, chipInputEvent) {
385
- /* Add the selected value as a chip */
386
- this._addChip(field, event.option.viewValue);
387
- /* Clear the input value */
388
- chipInputEvent.value = '';
389
- }
390
- /**
391
- * Adds a chip from the chip input event.
392
- * @param field - The form field definition where the chip is added.
393
- * @param event - The event containing the chip input value.
394
- */
395
- addChip(field, event) {
396
- /* Add the value from the chip input */
397
- this._addChip(field, event.value);
398
- /* Clear the chip input field */
399
- event.chipInput.clear();
400
- }
401
- /**
402
- * Handles pasting multiple chips into the chip input field.
403
- * @param field - The form field definition where chips are added.
404
- * @param event - The clipboard event containing the pasted data.
405
- */
406
- onPasteChips(field, event) {
407
- /* Extract text from the clipboard data */
408
- const clipboardData = event.clipboardData;
409
- const pastedText = clipboardData?.getData('text') || '';
410
- /* Split the pasted text by commas, semicolons, or newlines, then trim and filter out empty items */
411
- const items = pastedText
412
- .split(/[,\n;]/) /* Split by commas, semicolons, or newlines */
413
- .map(item => item.trim()) /* Trim leading and trailing spaces */
414
- .filter(item => item); /* Remove empty items */
415
- /* Add each valid item as a chip */
416
- items?.forEach(x => this._addChip(field, x.trim()));
417
- /* Prevent the default paste action */
418
- event.preventDefault();
419
- }
420
- /**
421
- * Removes a chip from the chip list.
422
- * @param field - The form field definition where the chip is removed.
423
- * @param chip - The chip value to remove.
424
- */
425
- removeChip(field, chip) {
426
- /* Get the form control associated with the field name */
427
- let control = this.formGroup?.controls[field.name ?? ''];
428
- /* Find the index of the chip to remove */
429
- const index = control?.value.indexOf(chip);
430
- if (control && index >= 0) {
431
- /* Remove the chip from the control's value array */
432
- control.value.splice(index, 1);
433
- /* Update the form control state and validity */
434
- control.updateValueAndValidity();
435
- this.formGroup?.markAsDirty();
436
- this.formGroup?.updateValueAndValidity();
437
- }
438
- }
439
- /**
440
- * Adds a chip to the form control based on its value.
441
- * @param field - The form field definition where the chip is added.
442
- * @param value - The value of the chip to add.
443
- */
444
- _addChip(field, value) {
445
- /* Get the form control associated with the field name */
446
- let control = this.formGroup?.controls[field.name ?? ''];
447
- /* Trim the input value */
448
- value = (value || '').trim();
449
- if (control && value) {
450
- /* Add the value to the control based on its input type */
451
- switch (field.inputType) {
452
- case 'number':
453
- /* Parse and add a number if valid */
454
- let number = parseInt(value);
455
- if (!isNaN(number)) {
456
- control.value.push(number);
457
- }
458
- break;
459
- case 'float':
460
- /* Parse and add a float if valid */
461
- let float = parseFloat(value);
462
- if (!isNaN(float)) {
463
- control.value.push(float);
464
- }
465
- break;
466
- default:
467
- /* Add the value as a string */
468
- control.value.push(value);
469
- break;
470
- }
471
- /* Update the form control state and validity */
472
- control.updateValueAndValidity();
473
- this.formGroup?.markAsDirty();
474
- this.formGroup?.updateValueAndValidity();
475
- }
476
- }
477
- /**
478
- * Handles the event when a date picker is opened.
479
- * @param datePicker - The date picker instance that is opened.
480
- * @param field - The form field definition associated with the date picker.
481
- */
482
- handleDatePickerOpened(datePicker, field) {
483
- if (field?.datePickerOpened) {
484
- /* Invoke the custom callback for when the date picker is opened */
485
- field.datePickerOpened(datePicker, this.formGroup?.value, this.formGroup, this.context);
486
- }
487
- }
488
- /**
489
- * Handles date filter event asynchronously for the date picker.
490
- * @param datePicker - The date picker instance to apply the filter to.
491
- * @param field - The form field definition containing the async filter logic.
492
- * @param date - The current date value to be validated.
493
- */
494
- handleDatePickerFilterAsync(datePicker, field, date) {
495
- if (field?.dateFilterAsync) {
496
- /* Disable all dates by setting the date filter to always return false. */
497
- datePicker.datepickerInput.dateFilter = (d) => false;
498
- /* Trigger Angular's change detection to update the date filter in the view. */
499
- datePicker.ngOnChanges({ 'dateFilter': new SimpleChange("", "", false) });
500
- /* Call the asynchronous date filter function to validate the provided date. */
501
- field.dateFilterAsync(date, this.formGroup?.value, this.formGroup, this.context).subscribe(x => {
502
- /* Update the date filter based on the asynchronous validation result. */
503
- datePicker.datepickerInput.dateFilter = (d) => d && x(d);
504
- /* Trigger Angular's change detection again to reflect the new date filter. */
505
- datePicker.ngOnChanges({ 'dateFilter': new SimpleChange("", "", false) });
506
- });
507
- }
508
- }
509
- /**
510
- * Handles calendar filter event asynchronously for the calendar component.
511
- * @param calendar - The calendar instance to apply the filter to.
512
- * @param field - The form field definition containing the async filter logic.
513
- * @param date - The current date value to be validated.
514
- */
515
- handleCalendarFilterAsync(calendar, field, date) {
516
- if (field?.dateFilterAsync) {
517
- /* Disable all dates by setting the date filter to always return false. */
518
- calendar.dateFilter = (d) => false;
519
- /* Trigger Angular's change detection to update the date filter in the view. */
520
- calendar.ngOnChanges({ 'dateFilter': new SimpleChange("", "", false) });
521
- /* Call the asynchronous date filter function to validate the provided date. */
522
- var subscription = field.dateFilterAsync(date, this.formGroup?.value, this.formGroup, this.context).subscribe(x => {
523
- /* Update the date filter based on the asynchronous validation result. */
524
- calendar.dateFilter = (d) => d && x(d);
525
- /* Trigger Angular's change detection again to reflect the new date filter. */
526
- calendar.ngOnChanges({ 'dateFilter': new SimpleChange("", "", false) });
527
- /* Unsubscribe from the observable to prevent memory leaks. */
528
- subscription.unsubscribe();
529
- });
530
- }
531
- }
532
- /**
533
- * Builds the form fields for the component.
534
- */
535
- buildFields() {
536
- /* Ensure the class type is defined, as it is required to generate the form definition. */
537
- if (!this.classType) {
538
- throw new Error('Invalid classType. Please ensure classType is defined, not null, and is a constructor function.');
539
- }
540
- /* Generate the form definition using the class type's metadata. */
541
- this.formDefinition = getFormDefinition(new this.classType());
542
- /* Create form field groups, excluding any hidden fields. */
543
- this.fieldGroups = this.formDefinition?.fieldGroups?.filter(x => !x.hidden)?.map(a => { return { ...a }; });
544
- }
545
- /**
546
- * Logs a message to the console.
547
- * @param message - The primary message to log.
548
- * @param optionalParams - Additional parameters to include in the log.
549
- */
550
- log(message, ...optionalParams) {
551
- /* Log the provided message and optional parameters to the console. */
552
- console.log(message, optionalParams);
553
- }
554
- /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdGenericFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
555
- /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: VdGenericFormComponent, selector: "vd-generic-form", inputs: { formGroup: "formGroup", classType: "classType", formDefinition: "formDefinition", fieldGroups: "fieldGroups", groupName: "groupName", fieldSets: "fieldSets", context: "context", debugValue: "debugValue", readonly: "readonly", separatorKeysCodes: "separatorKeysCodes" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: VdEditorDirective, descendants: true }, { propertyName: "codeTemplate", first: true, predicate: VdCodeDirective, descendants: true }, { propertyName: "fileTemplate", first: true, predicate: VdFileDirective, descendants: true }, { propertyName: "customTemplate", first: true, predicate: VdCustomDirective, descendants: true }, { propertyName: "bottom", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "customFields", first: true, predicate: ["customFields"], descendants: true }, { propertyName: "customFieldsTemplates", predicate: VdGenericFormCustomFieldDirective }], ngImport: i0, template: "<div *ngIf=\"formGroup && fieldRows\" [formGroup]=\"formGroup\">\r\n <!-- #region Fields -->\r\n <ng-container *ngFor=\"let fields of fieldRows; let i = index\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <ng-container *ngFor=\"let field of fields\" [ngSwitch]=\"field.type\">\r\n <ng-container *ngIf=\"!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))\">\r\n <ng-container *ngIf=\"field.wrapped\">\r\n <!-- #region Text input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Text\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput\r\n [type]=\"field.inputType ?? 'text'\"\r\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\r\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\r\n [min]=\"field.min\" [max]=\"field.max\"\r\n [formControlName]=\"field.name!\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\r\n [autoFocus]=\"((field.focus | func:formValue:formGroup:context)??false)\"\r\n [selectText]=\"((field.selectText | func:formValue:formGroup:context)??false)\"\r\n [onlyNumber]=\"(field.numbersOnly??false)\"\r\n parseDecimal\r\n [parseDecimalEnabled]=\"(field.parseDecimal??false)\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\"\r\n mat-icon-button\r\n *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\"\r\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Textarea -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.TextArea\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <textarea matInput\r\n [formControlName]=\"field.name!\"\r\n rows=\"field.rows||2\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n </textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\"\r\n mat-icon-button\r\n *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\"\r\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Enum -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Enum\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\"\r\n [enum]=\"field.enumType\"\r\n [enumMetadata]=\"field.enumMetadata\"\r\n [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\"\r\n [optionValueProperty]=\"field.optionValueProperty\"\r\n [optionTextProperty]=\"field.optionTextProperty\"\r\n [defaultOption]=\"field.defaultOption??true\"\r\n [multiple]=\"field.multiple\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [triggerCssClass]=\"field.triggerCssClass\"\r\n [triggerMode]=\"field.triggerMode\"\r\n layout=\"row\"\r\n flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\" *ngIf=\"field.optionIcon && !field.optionTemplate\">\r\n <div layout=\"row\" layout-align=\"start center\">\r\n <ng-template #optionIconTemplate\r\n [ngTemplateOutlet]=\"optionIconTemplate\"\r\n let-optionIcon=\"optionIcon\"\r\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\r\n <mat-icon *ngIf=\"optionIcon.svgIcon\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\r\n <mat-icon *ngIf=\"optionIcon.matIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\r\n </ng-template>\r\n <span>{{text}}</span>\r\n </div>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\"\r\n mat-icon-button\r\n *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\"\r\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdSelect -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdSelect\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\"\r\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\r\n [params]=\"field.params??{} | func:formValue:formGroup:context\"\r\n [projection]=\"field.projection\" [mapper]=\"field.mapper\"\r\n [compareWith]=\"field.compareWith\"\r\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\r\n [optionValueProperty]=\"field.optionValueProperty\"\r\n [optionTextProperty]=\"field.optionTextProperty\"\r\n [defaultOption]=\"field.defaultOption??true\"\r\n [matIconKey]=\"field.optionMatIconProperty\"\r\n [svgIconKey]=\"field.optionSvgIconProperty\"\r\n [fontSet]=\"field.optionIconFontSet\"\r\n [multiple]=\"field.multiple\"\r\n [selectFirst]=\"field.selectFirst\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [triggerCssClass]=\"field.triggerCssClass\"\r\n [triggerMode]=\"field.triggerMode\"\r\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\r\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\r\n layout=\"row\"\r\n flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerMapper && field.multiple && field.triggerMode == 'chip'\">\r\n <mat-chip-set>\r\n <mat-chip *ngFor=\"let item of trigger\" [color]=\"field.chipColor\" [color]=\"field.chipColor\" highlighted selected>\r\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\r\n </mat-chip>\r\n </mat-chip-set>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\" *ngIf=\"field.optionIcon && !field.optionTemplate\">\r\n <div layout=\"row\" layout-align=\"start center\">\r\n <ng-template #optionIconTemplate\r\n [ngTemplateOutlet]=\"optionIconTemplate\"\r\n let-optionIcon=\"optionIcon\"\r\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\r\n <mat-icon *ngIf=\"optionIcon.svgIcon\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\r\n <mat-icon *ngIf=\"optionIcon.matIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\r\n </ng-template>\r\n <span>{{text}}</span>\r\n </div>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdList -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdList\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-list [formControlName]=\"field.name!\"\r\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\r\n [params]=\"field.params ??{} | func:formValue:formGroup:context\"\r\n [projection]=\"field.projection\"\r\n [mapper]=\"field.mapper\"\r\n [compareWith]=\"field.compareWith\"\r\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\r\n [optionValueProperty]=\"field.optionValueProperty\"\r\n [optionTextProperty]=\"field.optionTextProperty\"\r\n [multiple]=\"field.multiple\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\r\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\r\n [style.max-width]=\"field.maxWidth\"\r\n [style.max-height]=\"field.maxHeight\"\r\n flex>\r\n <ng-template vd-list-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-list>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Chips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Chips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-chip-row *ngFor=\"let chip of $any(formGroup.controls[field.name!])?.value\"\r\n (removed)=\"removeChip(field, chip)\"\r\n [color]=\"field.chipColor\"\r\n selectable=\"true\"\r\n highlighted\r\n selected>\r\n <span>{{chip}}</span>\r\n <button matChipRemove>\r\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"$any(field.label)\"\r\n #chipInput\r\n [matChipInputFor]=\"chipList\"\r\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\r\n [matAutocomplete]=\"chipAutocomplete\"\r\n (input)=\"filterAutocomplete(field, chipInput)\"\r\n (matChipInputTokenEnd)=\"addChip(field, $event)\"\r\n (paste)=\"onPasteChips(field, $event)\"\r\n autocomplete=\"off\">\r\n </mat-chip-grid>\r\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdChips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdChips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-chips #vdChip\r\n [formControlName]=\"field.name!\"\r\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\r\n [params]=\"field.params || {} | func:formValue:formGroup:context\"\r\n [searchField]=\"field.searchField\"\r\n [searchFields]=\"field.searchFields\"\r\n [filters]=\"field.filters\"\r\n [selectFirst]=\"field.selectFirst\"\r\n [classType]=\"field.classType\"\r\n [projection]=\"field.projection\"\r\n [key]=\"field.optionValueProperty\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [removable]=\"!field.clear\"\r\n [context]=\"context\"\r\n [suffixButtons]=\"field.suffixButtons\"\r\n [autocompleteCssClass]=\"field.autocompleteCssClass\"\r\n (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\r\n (selected)=\"!field.itemChange ? $event.callback(true) : $event.callback(field.itemChange($event.value, formValue, formGroup, context) !== false)\"\r\n (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\"\r\n [customValue]=\"field.customValue\"\r\n layout=\"row\"\r\n flex>\r\n <ng-template vd-chip let-chip=\"chip\" *ngIf=\"field.chipTemplate\">\r\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n <ng-template vd-autocomplete-option let-option=\"option\" *ngIf=\"field.autocompleteTemplate\">\r\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n </vd-chips>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-hint *ngIf=\"vdChip.emptyResult\" class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Select -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Select\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-select [formControlName]=\"field.name!\"\r\n [multiple]=\"field.multiple\"\r\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n flex>\r\n <mat-option *ngFor=\"let option of $any(field.options)\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Autocomplete -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Autocomplete\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input type=\"text\"\r\n matInput\r\n [formControlName]=\"field.name!\"\r\n [min]=\"field.min\"\r\n [max]=\"field.max\"\r\n [matAutocomplete]=\"auto\"\r\n (input)=\"filterAutocomplete(field, autocompleteInput)\"\r\n autocomplete=\"off\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\r\n #autocompleteInput>\r\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Date -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Date\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput\r\n [formControlName]=\"field.name!\"\r\n [min]=\"field.min\" [max]=\"field.max\"\r\n autocomplete=\"off\"\r\n [matDatepicker]=\"datePicker\"\r\n [matDatepickerFilter]=\"field.dateFilter\"\r\n [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Calendar -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Calendar\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\r\n <mat-calendar #calendar\r\n [selected]=\"formGroup.get(field.name!)?.value\"\r\n (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\"\r\n (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\"\r\n [headerComponent]=\"datePickerHeaderComponent\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\r\n style=\"width: 100%;\"></mat-calendar>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Color input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Color\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType ?? 'text'\"\r\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\r\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\r\n [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\r\n [onlyNumber]=\"(field.numbersOnly??false)\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n </ng-container>\r\n\r\n <!-- #region Checkbox -->\r\n <div *ngSwitchCase=\"FormFieldType.Checkbox\" [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name!\"\r\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n {{field.label}}\r\n </mat-checkbox>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Editor -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Editor\">\r\n <ng-template *ngIf=\"editorTemplate?.templateRef!\" [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Code -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Code\">\r\n <ng-template *ngIf=\"codeTemplate?.templateRef!\" [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region File -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.File\">\r\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <div vd-file-input\r\n [formControlName]=\"field.name!\"\r\n (select)=\"field.change && field.change(field, $event, formGroup, context)\"\r\n [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n flex>\r\n </div>\r\n </mat-form-field>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Custom -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Custom\">\r\n <ng-template *ngIf=\"customTemplate?.templateRef!\" [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == fields[0]?.row && customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </div>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngIf=\"customFields\" [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == ((fields[0]?.row??0)+1) && !customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Form bottom -->\r\n <ng-container *ngIf=\"bottom\" [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Template for suffix buttons -->\r\n <ng-template #suffixButtons let-field>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </ng-template>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formValue | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mdc-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "directive", type: i3.OnlyNumberDirective, selector: "[onlyNumber]", inputs: ["onlyNumber"] }, { kind: "directive", type: i4.AutofocusDirective, selector: "[autoFocus]", inputs: ["focusDelay", "selectText", "autoFocus"] }, { kind: "component", type: i5.VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass", "triggerMode"] }, { kind: "directive", type: i6.VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: i7.VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "component", type: i8.VdChipsComponent, selector: "vd-chips", inputs: ["classType", "chips", "endpoint", "params", "projection", "paginated", "customValue", "context", "key", "searchField", "searchFields", "filters", "removable", "selectFirst", "debounce", "autocompleteCssClass", "suffixButtons"], outputs: ["initSelect", "selected", "cleared", "launch", "chipFocus"] }, { kind: "directive", type: i9.VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "directive", type: i10.VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "component", type: i11.VdFileInputComponent, selector: "[vd-file-input]", inputs: ["accept", "placeholder", "required", "multiple", "disabled", "errorState"], outputs: ["select", "clear"] }, { kind: "component", type: i12.VdListComponent, selector: "vd-list" }, { kind: "directive", type: i13.VdListOptionDirective, selector: "[vd-list-option]ng-template" }, { kind: "directive", type: i14.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i14.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i14.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i14.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i14.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i14.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i14.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i15.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i15.MatLabel, selector: "mat-label" }, { kind: "directive", type: i15.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i15.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i15.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i16.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i17.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i18.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i19.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i20.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i21.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "component", type: i21.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i21.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i21.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i22.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i23.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i23.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i24.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i24.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i24.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i24.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i24.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i24.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: i25.NgxColorsComponent, selector: "ngx-colors" }, { kind: "directive", type: i25.NgxColorsTriggerDirective, selector: "[ngx-colors-trigger]", inputs: ["colorsAnimation", "palette", "format", "formats", "position", "hideTextInput", "hideColorPicker", "attachTo", "overlayClassName", "colorPickerControls", "acceptLabel", "cancelLabel"], outputs: ["change", "input", "slider", "close", "open"] }, { kind: "directive", type: i26.EmptyStringResetDirective, selector: "[ngModel],[formControlName],[formControl]" }, { kind: "directive", type: i27.MatFormFieldReadonlyDirective, selector: "mat-form-field" }, { kind: "directive", type: i28.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i29.ParseDecimalDirective, selector: "[parseDecimal]", inputs: ["parseDecimalEnabled"] }, { kind: "pipe", type: i1.JsonPipe, name: "json" }, { kind: "pipe", type: i30.FuncPipe, name: "func" }] });
556
- }
557
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: VdGenericFormComponent, decorators: [{
558
- type: Component,
559
- args: [{ selector: 'vd-generic-form', template: "<div *ngIf=\"formGroup && fieldRows\" [formGroup]=\"formGroup\">\r\n <!-- #region Fields -->\r\n <ng-container *ngFor=\"let fields of fieldRows; let i = index\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <ng-container *ngFor=\"let field of fields\" [ngSwitch]=\"field.type\">\r\n <ng-container *ngIf=\"!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))\">\r\n <ng-container *ngIf=\"field.wrapped\">\r\n <!-- #region Text input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Text\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput\r\n [type]=\"field.inputType ?? 'text'\"\r\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\r\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\r\n [min]=\"field.min\" [max]=\"field.max\"\r\n [formControlName]=\"field.name!\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\r\n [autoFocus]=\"((field.focus | func:formValue:formGroup:context)??false)\"\r\n [selectText]=\"((field.selectText | func:formValue:formGroup:context)??false)\"\r\n [onlyNumber]=\"(field.numbersOnly??false)\"\r\n parseDecimal\r\n [parseDecimalEnabled]=\"(field.parseDecimal??false)\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\"\r\n mat-icon-button\r\n *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\"\r\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Textarea -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.TextArea\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <textarea matInput\r\n [formControlName]=\"field.name!\"\r\n rows=\"field.rows||2\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n </textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\"\r\n mat-icon-button\r\n *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\"\r\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Enum -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Enum\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\"\r\n [enum]=\"field.enumType\"\r\n [enumMetadata]=\"field.enumMetadata\"\r\n [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\"\r\n [optionValueProperty]=\"field.optionValueProperty\"\r\n [optionTextProperty]=\"field.optionTextProperty\"\r\n [defaultOption]=\"field.defaultOption??true\"\r\n [multiple]=\"field.multiple\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [triggerCssClass]=\"field.triggerCssClass\"\r\n [triggerMode]=\"field.triggerMode\"\r\n layout=\"row\"\r\n flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\" *ngIf=\"field.optionIcon && !field.optionTemplate\">\r\n <div layout=\"row\" layout-align=\"start center\">\r\n <ng-template #optionIconTemplate\r\n [ngTemplateOutlet]=\"optionIconTemplate\"\r\n let-optionIcon=\"optionIcon\"\r\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\r\n <mat-icon *ngIf=\"optionIcon.svgIcon\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\r\n <mat-icon *ngIf=\"optionIcon.matIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\r\n </ng-template>\r\n <span>{{text}}</span>\r\n </div>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\"\r\n mat-icon-button\r\n *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\"\r\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdSelect -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdSelect\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\"\r\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\r\n [params]=\"field.params??{} | func:formValue:formGroup:context\"\r\n [projection]=\"field.projection\" [mapper]=\"field.mapper\"\r\n [compareWith]=\"field.compareWith\"\r\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\r\n [optionValueProperty]=\"field.optionValueProperty\"\r\n [optionTextProperty]=\"field.optionTextProperty\"\r\n [defaultOption]=\"field.defaultOption??true\"\r\n [matIconKey]=\"field.optionMatIconProperty\"\r\n [svgIconKey]=\"field.optionSvgIconProperty\"\r\n [fontSet]=\"field.optionIconFontSet\"\r\n [multiple]=\"field.multiple\"\r\n [selectFirst]=\"field.selectFirst\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [triggerCssClass]=\"field.triggerCssClass\"\r\n [triggerMode]=\"field.triggerMode\"\r\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\r\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\r\n layout=\"row\"\r\n flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerMapper && field.multiple && field.triggerMode == 'chip'\">\r\n <mat-chip-set>\r\n <mat-chip *ngFor=\"let item of trigger\" [color]=\"field.chipColor\" [color]=\"field.chipColor\" highlighted selected>\r\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\r\n </mat-chip>\r\n </mat-chip-set>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\" *ngIf=\"field.optionIcon && !field.optionTemplate\">\r\n <div layout=\"row\" layout-align=\"start center\">\r\n <ng-template #optionIconTemplate\r\n [ngTemplateOutlet]=\"optionIconTemplate\"\r\n let-optionIcon=\"optionIcon\"\r\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\r\n <mat-icon *ngIf=\"optionIcon.svgIcon\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\r\n <mat-icon *ngIf=\"optionIcon.matIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\r\n </ng-template>\r\n <span>{{text}}</span>\r\n </div>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdList -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdList\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-list [formControlName]=\"field.name!\"\r\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\r\n [params]=\"field.params ??{} | func:formValue:formGroup:context\"\r\n [projection]=\"field.projection\"\r\n [mapper]=\"field.mapper\"\r\n [compareWith]=\"field.compareWith\"\r\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\r\n [optionValueProperty]=\"field.optionValueProperty\"\r\n [optionTextProperty]=\"field.optionTextProperty\"\r\n [multiple]=\"field.multiple\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\r\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\r\n [style.max-width]=\"field.maxWidth\"\r\n [style.max-height]=\"field.maxHeight\"\r\n flex>\r\n <ng-template vd-list-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-list>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Chips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Chips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-chip-row *ngFor=\"let chip of $any(formGroup.controls[field.name!])?.value\"\r\n (removed)=\"removeChip(field, chip)\"\r\n [color]=\"field.chipColor\"\r\n selectable=\"true\"\r\n highlighted\r\n selected>\r\n <span>{{chip}}</span>\r\n <button matChipRemove>\r\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"$any(field.label)\"\r\n #chipInput\r\n [matChipInputFor]=\"chipList\"\r\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\r\n [matAutocomplete]=\"chipAutocomplete\"\r\n (input)=\"filterAutocomplete(field, chipInput)\"\r\n (matChipInputTokenEnd)=\"addChip(field, $event)\"\r\n (paste)=\"onPasteChips(field, $event)\"\r\n autocomplete=\"off\">\r\n </mat-chip-grid>\r\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdChips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdChips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-chips #vdChip\r\n [formControlName]=\"field.name!\"\r\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\r\n [params]=\"field.params || {} | func:formValue:formGroup:context\"\r\n [searchField]=\"field.searchField\"\r\n [searchFields]=\"field.searchFields\"\r\n [filters]=\"field.filters\"\r\n [selectFirst]=\"field.selectFirst\"\r\n [classType]=\"field.classType\"\r\n [projection]=\"field.projection\"\r\n [key]=\"field.optionValueProperty\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [removable]=\"!field.clear\"\r\n [context]=\"context\"\r\n [suffixButtons]=\"field.suffixButtons\"\r\n [autocompleteCssClass]=\"field.autocompleteCssClass\"\r\n (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\r\n (selected)=\"!field.itemChange ? $event.callback(true) : $event.callback(field.itemChange($event.value, formValue, formGroup, context) !== false)\"\r\n (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\"\r\n [customValue]=\"field.customValue\"\r\n layout=\"row\"\r\n flex>\r\n <ng-template vd-chip let-chip=\"chip\" *ngIf=\"field.chipTemplate\">\r\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n <ng-template vd-autocomplete-option let-option=\"option\" *ngIf=\"field.autocompleteTemplate\">\r\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n </vd-chips>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-hint *ngIf=\"vdChip.emptyResult\" class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Select -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Select\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-select [formControlName]=\"field.name!\"\r\n [multiple]=\"field.multiple\"\r\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n flex>\r\n <mat-option *ngFor=\"let option of $any(field.options)\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Autocomplete -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Autocomplete\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input type=\"text\"\r\n matInput\r\n [formControlName]=\"field.name!\"\r\n [min]=\"field.min\"\r\n [max]=\"field.max\"\r\n [matAutocomplete]=\"auto\"\r\n (input)=\"filterAutocomplete(field, autocompleteInput)\"\r\n autocomplete=\"off\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\r\n #autocompleteInput>\r\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Date -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Date\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput\r\n [formControlName]=\"field.name!\"\r\n [min]=\"field.min\" [max]=\"field.max\"\r\n autocomplete=\"off\"\r\n [matDatepicker]=\"datePicker\"\r\n [matDatepickerFilter]=\"field.dateFilter\"\r\n [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Calendar -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Calendar\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\r\n <mat-calendar #calendar\r\n [selected]=\"formGroup.get(field.name!)?.value\"\r\n (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\"\r\n (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\"\r\n [headerComponent]=\"datePickerHeaderComponent\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\r\n style=\"width: 100%;\"></mat-calendar>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Color input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Color\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType ?? 'text'\"\r\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\r\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\r\n [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\"\r\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\r\n [onlyNumber]=\"(field.numbersOnly??false)\"\r\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\r\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n </ng-container>\r\n\r\n <!-- #region Checkbox -->\r\n <div *ngSwitchCase=\"FormFieldType.Checkbox\" [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name!\"\r\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n {{field.label}}\r\n </mat-checkbox>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Editor -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Editor\">\r\n <ng-template *ngIf=\"editorTemplate?.templateRef!\" [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Code -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Code\">\r\n <ng-template *ngIf=\"codeTemplate?.templateRef!\" [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region File -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.File\">\r\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <div vd-file-input\r\n [formControlName]=\"field.name!\"\r\n (select)=\"field.change && field.change(field, $event, formGroup, context)\"\r\n [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\r\n flex>\r\n </div>\r\n </mat-form-field>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Custom -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Custom\">\r\n <ng-template *ngIf=\"customTemplate?.templateRef!\" [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == fields[0]?.row && customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </div>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngIf=\"customFields\" [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == ((fields[0]?.row??0)+1) && !customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Form bottom -->\r\n <ng-container *ngIf=\"bottom\" [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Template for suffix buttons -->\r\n <ng-template #suffixButtons let-field>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </ng-template>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formValue | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mdc-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}\n"] }]
560
- }], propDecorators: { formGroup: [{
561
- type: Input
562
- }], classType: [{
563
- type: Input
564
- }], formDefinition: [{
565
- type: Input
566
- }], fieldGroups: [{
567
- type: Input
568
- }], groupName: [{
569
- type: Input
570
- }], fieldSets: [{
571
- type: Input
572
- }], context: [{
573
- type: Input
574
- }], debugValue: [{
575
- type: Input
576
- }], readonly: [{
577
- type: Input
578
- }], separatorKeysCodes: [{
579
- type: Input
580
- }], editorTemplate: [{
581
- type: ContentChild,
582
- args: [VdEditorDirective]
583
- }], codeTemplate: [{
584
- type: ContentChild,
585
- args: [VdCodeDirective]
586
- }], fileTemplate: [{
587
- type: ContentChild,
588
- args: [VdFileDirective]
589
- }], customTemplate: [{
590
- type: ContentChild,
591
- args: [VdCustomDirective]
592
- }], bottom: [{
593
- type: ContentChild,
594
- args: ['bottom']
595
- }], customFields: [{
596
- type: ContentChild,
597
- args: ['customFields']
598
- }], customFieldsTemplates: [{
599
- type: ContentChildren,
600
- args: [VdGenericFormCustomFieldDirective]
601
- }] } });
602
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nkay9zcmMvbGliL2Zvcm1zL2NvbXBvbmVudHMvZ2VuZXJpYy1mb3JtL2dlbmVyaWMtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZGsvc3JjL2xpYi9mb3Jtcy9jb21wb25lbnRzL2dlbmVyaWMtZm9ybS9nZW5lcmljLWZvcm0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsU0FBUyxFQUFFLFlBQVksRUFBaUIsV0FBVyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoTCxPQUFPLEVBQWUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSXBFLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQzVHLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFHOUQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMkNBQTJDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRXRGOzs7OztHQUtHO0FBRUgsTUFBTSxPQUFPLGlCQUFrQixTQUFRLFNBQVM7SUFDNUM7Ozs7T0FJRztJQUNI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N0Msc0VBQXNFO1FBQ3RFLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7MEhBbGdCUSxzQkFBc0I7OEdBQXRCLHNCQUFzQiwyWEErSGpCLGlCQUFpQiwrRUFTakIsZUFBZSwrRUFTZixlQUFlLGlGQVNmLGlCQUFpQiw2UEFtQ2QsaUNBQWlDLDZCQ3pSdEQsb21zQ0F3Y007OzJGRDVXTyxzQkFBc0I7a0JBTGxDLFNBQVM7K0JBQ0ksaUJBQWlCOzhCQVlwQixTQUFTO3NCQURmLEtBQUs7Z0JBaUJDLFNBQVM7c0JBRGYsS0FBSztnQkFVQyxjQUFjO3NCQURwQixLQUFLO2dCQVVDLFdBQVc7c0JBRGpCLEtBQUs7Z0JBVUMsU0FBUztzQkFEZixLQUFLO2dCQVVDLFNBQVM7c0JBRGYsS0FBSztnQkFVQyxPQUFPO3NCQURiLEtBQUs7Z0JBVUMsVUFBVTtzQkFEaEIsS0FBSztnQkFVQyxRQUFRO3NCQURkLEtBQUs7Z0JBVUMsa0JBQWtCO3NCQUR4QixLQUFLO2dCQWlDQyxjQUFjO3NCQURwQixZQUFZO3VCQUFDLGlCQUFpQjtnQkFVeEIsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxlQUFlO2dCQVV0QixZQUFZO3NCQURsQixZQUFZO3VCQUFDLGVBQWU7Z0JBVXRCLGNBQWM7c0JBRHBCLFlBQVk7dUJBQUMsaUJBQWlCO2dCQWtCeEIsTUFBTTtzQkFEWixZQUFZO3VCQUFDLFFBQVE7Z0JBVWYsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxjQUFjO2dCQVVyQixxQkFBcUI7c0JBRDNCLGVBQWU7dUJBQUMsaUNBQWlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ09NTUEsIEVOVEVSIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcclxuaW1wb3J0IHsgQ2RrUG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XHJcbmltcG9ydCB7IENvbXBvbmVudCwgQ29udGVudENoaWxkLCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgSW5wdXQsIE9uSW5pdCwgUXVlcnlMaXN0LCBTaW1wbGVDaGFuZ2UsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBUeXBlLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE1hdEF1dG9jb21wbGV0ZVNlbGVjdGVkRXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9hdXRvY29tcGxldGUnO1xyXG5pbXBvcnQgeyBNYXRDaGlwSW5wdXRFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NoaXBzJztcclxuaW1wb3J0IHsgTWF0Q2FsZW5kYXIsIE1hdERhdGVwaWNrZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcclxuaW1wb3J0IHsgVmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy92ZC1nZW5lcmljLWZvcm0tY3VzdG9tLWZpZWxkLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEZvcm1GaWVsZFR5cGUgfSBmcm9tICcuLi8uLi9lbnVtcy9mb3JtLWZpZWxkLXR5cGUnO1xyXG5pbXBvcnQgeyBnZXRGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBGb3JtRmllbGREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Zvcm0tZmllbGQtZGVmaW5pdGlvbic7XHJcbmltcG9ydCB7IEZvcm1GaWVsZEdyb3VwRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWZpZWxkLWdyb3VwLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBEYXRlUGlja2VySGVhZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vZGF0ZXBpY2tlci9kYXRlcGlja2VyLWhlYWRlci5jb21wb25lbnQnO1xyXG5cclxuLyoqXHJcbiAqIEBjbGFzcyBWZEVkaXRvckRpcmVjdGl2ZVxyXG4gKiBAZGVzY3JpcHRpb24gVGhlIGBWZEVkaXRvckRpcmVjdGl2ZWAgaXMgYSBjdXN0b20gZGlyZWN0aXZlIHRoYXQgYXR0YWNoZXMgYSBgQ2RrUG9ydGFsYCBcclxuICogdG8gYSB0ZW1wbGF0ZSB3aXRoIHRoZSBgdmQtZWRpdG9yYCBzZWxlY3Rvci4gSXQgYWxsb3dzIGNvbnRlbnQgdG8gYmUgZHluYW1pY2FsbHkgcmVuZGVyZWQgXHJcbiAqIGluc2lkZSB0aGUgY29tcG9uZW50LCB1c2luZyBhIHRlbXBsYXRlIHJlZmVyZW5jZS5cclxuICovXHJcbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1t2ZC1lZGl0b3JdbmctdGVtcGxhdGUnIH0pXHJcbmV4cG9ydCBjbGFzcyBWZEVkaXRvckRpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICAvKipcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtUZW1wbGF0ZVJlZjxhbnk+fSB0ZW1wbGF0ZVJlZiAtIFRoZSByZWZlcmVuY2UgdG8gdGhlIHRlbXBsYXRlIHRvIGJlIHJlbmRlcmVkLlxyXG4gICAgICogQHBhcmFtIHtWaWV3Q29udGFpbmVyUmVmfSB2aWV3Q29udGFpbmVyUmVmIC0gVGhlIGNvbnRhaW5lciB3aGVyZSB0aGUgdGVtcGxhdGUgd2lsbCBiZSBpbnNlcnRlZC5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAY2xhc3MgVmRDb2RlRGlyZWN0aXZlXHJcbiAqIEBkZXNjcmlwdGlvbiBUaGUgYFZkQ29kZURpcmVjdGl2ZWAgaXMgYSBjdXN0b20gZGlyZWN0aXZlIHRoYXQgYXR0YWNoZXMgYSBgQ2RrUG9ydGFsYCBcclxuICogdG8gYSB0ZW1wbGF0ZSB3aXRoIHRoZSBgdmQtY29kZWAgc2VsZWN0b3IuIEl0IGlzIHVzZWQgdG8gZHluYW1pY2FsbHkgcmVuZGVyIGNvZGUgYmxvY2tzIFxyXG4gKiBpbnNpZGUgdGhlIGNvbXBvbmVudCwgdXNpbmcgYSB0ZW1wbGF0ZSByZWZlcmVuY2UuXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtY29kZV1uZy10ZW1wbGF0ZScgfSlcclxuZXhwb3J0IGNsYXNzIFZkQ29kZURpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICAvKipcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtUZW1wbGF0ZVJlZjxhbnk+fSB0ZW1wbGF0ZVJlZiAtIFRoZSByZWZlcmVuY2UgdG8gdGhlIHRlbXBsYXRlIHRvIGJlIHJlbmRlcmVkLlxyXG4gICAgICogQHBhcmFtIHtWaWV3Q29udGFpbmVyUmVmfSB2aWV3Q29udGFpbmVyUmVmIC0gVGhlIGNvbnRhaW5lciB3aGVyZSB0aGUgdGVtcGxhdGUgd2lsbCBiZSBpbnNlcnRlZC5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAY2xhc3MgVmRGaWxlRGlyZWN0aXZlXHJcbiAqIEBkZXNjcmlwdGlvbiBUaGUgYFZkRmlsZURpcmVjdGl2ZWAgaXMgYSBjdXN0b20gZGlyZWN0aXZlIHRoYXQgYXR0YWNoZXMgYSBgQ2RrUG9ydGFsYCBcclxuICogdG8gYSB0ZW1wbGF0ZSB3aXRoIHRoZSBgdmQtZmlsZWAgc2VsZWN0b3IuIEl0IGVuYWJsZXMgdGhlIGR5bmFtaWMgcmVuZGVyaW5nIG9mIGZpbGUtcmVsYXRlZCBcclxuICogY29udGVudCBpbnNpZGUgdGhlIGNvbXBvbmVudCwgdXNpbmcgYSB0ZW1wbGF0ZSByZWZlcmVuY2UuXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtZmlsZV1uZy10ZW1wbGF0ZScgfSlcclxuZXhwb3J0IGNsYXNzIFZkRmlsZURpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICAvKipcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtUZW1wbGF0ZVJlZjxhbnk+fSB0ZW1wbGF0ZVJlZiAtIFRoZSByZWZlcmVuY2UgdG8gdGhlIHRlbXBsYXRlIHRvIGJlIHJlbmRlcmVkLlxyXG4gICAgICogQHBhcmFtIHtWaWV3Q29udGFpbmVyUmVmfSB2aWV3Q29udGFpbmVyUmVmIC0gVGhlIGNvbnRhaW5lciB3aGVyZSB0aGUgdGVtcGxhdGUgd2lsbCBiZSBpbnNlcnRlZC5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAY2xhc3MgVmRDdXN0b21EaXJlY3RpdmVcclxuICogQGRlc2NyaXB0aW9uIFRoZSBgVmRDdXN0b21EaXJlY3RpdmVgIGlzIGEgY3VzdG9tIGRpcmVjdGl2ZSB0aGF0IGF0dGFjaGVzIGEgYENka1BvcnRhbGAgXHJcbiAqIHRvIGEgdGVtcGxhdGUgd2l0aCB0aGUgYHZkLWN1c3RvbWAgc2VsZWN0b3IuIEl0IGFsbG93cyBjdXN0b20gY29udGVudCB0byBiZSBkeW5hbWljYWxseSBcclxuICogcmVuZGVyZWQgaW5zaWRlIHRoZSBjb21wb25lbnQsIHVzaW5nIGEgdGVtcGxhdGUgcmVmZXJlbmNlLlxyXG4gKi9cclxuQERpcmVjdGl2ZSh7IHNlbGVjdG9yOiAnW3ZkLWN1c3RvbV1uZy10ZW1wbGF0ZScgfSlcclxuZXhwb3J0IGNsYXNzIFZkQ3VzdG9tRGlyZWN0aXZlIGV4dGVuZHMgQ2RrUG9ydGFsIHtcclxuICAgIC8qKlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge1RlbXBsYXRlUmVmPGFueT59IHRlbXBsYXRlUmVmIC0gVGhlIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgdG8gYmUgcmVuZGVyZWQuXHJcbiAgICAgKiBAcGFyYW0ge1ZpZXdDb250YWluZXJSZWZ9IHZpZXdDb250YWluZXJSZWYgLSBUaGUgY29udGFpbmVyIHdoZXJlIHRoZSB0ZW1wbGF0ZSB3aWxsIGJlIGluc2VydGVkLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcih0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Piwgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZikge1xyXG4gICAgICAgIHN1cGVyKHRlbXBsYXRlUmVmLCB2aWV3Q29udGFpbmVyUmVmKTtcclxuICAgIH1cclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3ZkLWdlbmVyaWMtZm9ybScsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZ2VuZXJpYy1mb3JtLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2dlbmVyaWMtZm9ybS5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBWZEdlbmVyaWNGb3JtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IEZvcm0gZ3JvdXAgYXNzb2NpYXRlZCB3aXRoIHRoZSBmb3JtLlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgZm9ybUdyb3VwYCBpcyBhbiBpbnN0YW5jZSBvZiBgRm9ybUdyb3VwYCB0aGF0IGhvbGRzIHRoZSBjb250cm9scyBhbmQgdmFsaWRhdGlvbiBydWxlcyBcclxuICAgICAqIGZvciB0aGUgZm9ybS5cclxuICAgICAqIEB0eXBlIHtGb3JtR3JvdXB9XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZm9ybUdyb3VwPzogRm9ybUdyb3VwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IFJhdyB2YWx1ZSBvZiB0aGUgZm9ybS5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGlzIGdldHRlciByZXR1cm5zIHRoZSByYXcgdmFsdWVzIG9mIGFsbCBjb250cm9scyBpbiB0aGUgZm9ybSBhcyBhbiBvYmplY3QsIFxyXG4gICAgICogd2hpY2ggZG9lcyBub3QgaW5jbHVkZSBhbnkgdmFsaWRhdGlvbiBvciBzdGF0dXMgaW5mb3JtYXRpb24uXHJcbiAgICAgKiBAdHlwZSB7YW55fVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGZvcm1WYWx1ZSgpOiBhbnkgeyByZXR1cm4gdGhpcy5mb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwcm9wZXJ0eSBTcGVjaWZpZXMgdGhlIGNsYXNzIHR5cGUgZm9yIHRoZSBmb3JtLlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgY2xhc3NUeXBlYCBpcyBhIGdlbmVyaWMgdHlwZSB1c2VkIHRvIGRlZmluZSB0aGUgZm9ybSdzIHN0cnVjdHVyZSBhbmQgYmVoYXZpb3IuXHJcbiAgICAgKiBAdHlwZSB7VHlwZTxhbnk+fVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGNsYXNzVHlwZT86IFR5cGU8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwcm9wZXJ0eSBUaGUgZGVmaW5pdGlvbiBvZiB0aGUgZm9ybSBzdHJ1Y3R1cmUuXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGBmb3JtRGVmaW5pdGlvbmAgaG9sZHMgdGhlIHN0cnVjdHVyZSBhbmQgbWV0YWRhdGEgb2YgdGhlIGZvcm0gXHJcbiAgICAgKiB0byBkeW5hbWljYWxseSBnZW5lcmF0ZSBmb3JtIGZpZWxkcyBhbmQgdmFsaWRhdGlvbiBydWxlcy5cclxuICAgICAqIEB0eXBlIHtGb3JtRGVmaW5pdGlvbn1cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmb3JtRGVmaW5pdGlvbj86IEZvcm1EZWZpbml0aW9uO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IEFycmF5IG9mIGZvcm0gZmllbGQgZ3JvdXBzLlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgZmllbGRHcm91cHNgIGRlZmluZSBncm91cHMgb2YgZmllbGRzIHVzZWQgaW4gdGhlIGZvcm0sIGVuYWJsaW5nIG9yZ2FuaXphdGlvbiBhbmQgc3RydWN0dXJlIFxyXG4gICAgICogb2YgdGhlIGZvcm0gc2VjdGlvbnMuXHJcbiAgICAgKiBAdHlwZSB7Rm9ybUZpZWxkR3JvdXBEZWZpbml0aW9uW119XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZmllbGRHcm91cHM/OiBGb3JtRmllbGRHcm91cERlZmluaXRpb25bXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwcm9wZXJ0eSBOYW1lIG9mIHRoZSBmb3JtIGdyb3VwLlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgZ3JvdXBOYW1lYCBpcyBhIHN0cmluZyB1c2VkIHRvIGlkZW50aWZ5IGFuZCB0YXJnZXQgYSBzcGVjaWZpYyBncm91cCBvZiBmb3JtIGZpZWxkcyBcclxuICAgICAqIHdpdGhpbiB0aGUgZm9ybS5cclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZ3JvdXBOYW1lPzogc3RyaW5nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IExpc3Qgb2YgZmllbGQgc2V0cy5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgYGZpZWxkU2V0c2AgYXJyYXkgaXMgdXNlZCB0byBmaWx0ZXIgYW5kIGdyb3VwIGZvcm0gZmllbGRzIGJhc2VkIG9uIHNwZWNpZmljIHNldHMsXHJcbiAgICAgKiBhbGxvd2luZyBkeW5hbWljIGZpZWxkIHJlbmRlcmluZy5cclxuICAgICAqIEB0eXBlIHtzdHJpbmdbXX1cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmaWVsZFNldHM/OiBzdHJpbmdbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwcm9wZXJ0eSBDb250ZXh0IGZvciB0aGUgZm9ybS5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgYGNvbnRleHRgIHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgY29udGV4dCBvciBlbnZpcm9ubWVudCBpbiB3aGljaCB0aGUgZm9ybSBpcyBiZWluZyB1c2VkLFxyXG4gICAgICogcHJvdmlkaW5nIG5lY2Vzc2FyeSBpbmZvcm1hdGlvbiBmb3IgZmllbGQgcmVuZGVyaW5nIGFuZCB2YWxpZGF0aW9uLlxyXG4gICAgICogQHR5cGUge2FueX1cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjb250ZXh0OiBhbnk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcHJvcGVydHkgRmxhZyBpbmRpY2F0aW5nIGlmIGRlYnVnZ2luZyBpcyBlbmFibGVkLlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgZGVidWdWYWx1ZWAgZmxhZyBpcyB1c2VkIHRvIGVuYWJsZSBvciBkaXNhYmxlIGRlYnVnZ2luZyBmZWF0dXJlcyBsaWtlIGxvZ2dpbmcgXHJcbiAgICAgKiBvciBhZGRpdGlvbmFsIFVJIGNvbXBvbmVudHMgdG8gZmFjaWxpdGF0ZSB0cm91Ymxlc2hvb3RpbmcuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBkZWJ1Z1ZhbHVlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcHJvcGVydHkgRmxhZyBpbmRpY2F0aW5nIGlmIHRoZSBmb3JtIGlzIHJlYWQtb25seS5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgYHJlYWRvbmx5YCBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGUgZm9ybSBmaWVsZHMgY2FuIGJlIGVkaXRlZCBvciBub3QuIFxyXG4gICAgICogSWYgc2V0IHRvIGB0cnVlYCwgdGhlIGZvcm0gZmllbGRzIGFyZSBkaXNhYmxlZCBmb3IgZWRpdGluZy5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIHJlYWRvbmx5PzogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwcm9wZXJ0eSBLZXkgY29kZXMgdXNlZCBmb3Igc2VwYXJhdGluZyBpbnB1dCB2YWx1ZXMuXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGBzZXBhcmF0b3JLZXlzQ29kZXNgIGlzIGFuIGFycmF5IG9mIGtleSBjb2RlcyAoZS5nLiwgZm9yIGNvbW1hIG9yIGVudGVyKSB1c2VkIGZvciBcclxuICAgICAqIHNlcGFyYXRpbmcgdmFsdWVzIGluIGlucHV0IGZpZWxkcyBsaWtlIHRhZ3Mgb3IgY2hpcHMuXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyW119XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2VwYXJhdG9yS2V5c0NvZGVzOiBudW1iZXJbXSA9IFtFTlRFUiwgQ09NTUFdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IEFycmF5IG9mIGZpZWxkIHJvd3MuXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGBmaWVsZFJvd3NgIHJlcHJlc2VudCB0aGUgbGF5b3V0IGFuZCBvcmdhbml6YXRpb24gb2YgZm9ybSBmaWVsZHMgZ3JvdXBlZCBpbiByb3dzLlxyXG4gICAgICogRWFjaCByb3cgY29udGFpbnMgYW4gYXJyYXkgb2YgYEZvcm1GaWVsZERlZmluaXRpb25gIG9iamVjdHMuXHJcbiAgICAgKiBAdHlwZSB7Rm9ybUZpZWxkRGVmaW5pdGlvbltdW119XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmaWVsZFJvd3M/OiBGb3JtRmllbGREZWZpbml0aW9uW11bXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwcm9wZXJ0eSBBcnJheSBvZiBmb3JtIGZpZWxkcy5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgYGZpZWxkc2AgYXJyYXkgaG9sZHMgdGhlIGxpc3Qgb2YgZm9ybSBmaWVsZHMgdG8gYmUgcmVuZGVyZWQsIGVhY2ggZGVmaW5lZCBieSBhIGBGb3JtRmllbGREZWZpbml0aW9uYC5cclxuICAgICAqIEB0eXBlIHtGb3JtRmllbGREZWZpbml0aW9uW119XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmaWVsZHM/OiBGb3JtRmllbGREZWZpbml0aW9uW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcHJvcGVydHkgVGhlIGBGb3JtRmllbGRUeXBlYCBlbnVtZXJhdGlvbi5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgYEZvcm1GaWVsZFR5cGVgIGlzIGFuIGVudW0gdXNlZCB0byBjbGFzc2lmeSBkaWZmZXJlbnQgdHlwZXMgb2YgZm9ybSBmaWVsZHMsIHN1Y2ggYXMgXHJcbiAgICAgKiB0ZXh0LCBjaGVja2JveCwgZmlsZSwgZXRjLlxyXG4gICAgICogQHR5cGUge3R5cGVvZiBGb3JtRmllbGRUeXBlfVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgRm9ybUZpZWxkVHlwZTogdHlwZW9mIEZvcm1GaWVsZFR5cGUgPSBGb3JtRmllbGRUeXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IEVkaXRvciB0ZW1wbGF0ZSBjb250ZW50LlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgZWRpdG9yVGVtcGxhdGVgIGhvbGRzIHRoZSBjb250ZW50IGZvciB0aGUgZWRpdG9yIHNlY3Rpb24sIHdoaWNoIGNhbiBiZSBjdXN0b21pemVkIFxyXG4gICAgICogdXNpbmcgYSBgVmRFZGl0b3JEaXJlY3RpdmVgLlxyXG4gICAgICogQHR5cGUge1ZkRWRpdG9yRGlyZWN0aXZlfVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKFZkRWRpdG9yRGlyZWN0aXZlKVxyXG4gICAgcHVibGljIGVkaXRvclRlbXBsYXRlPzogVmRFZGl0b3JEaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcHJvcGVydHkgQ29kZSB0ZW1wbGF0ZSBjb250ZW50LlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgY29kZVRlbXBsYXRlYCBob2xkcyB0aGUgY29udGVudCBmb3IgdGhlIGNvZGUgc2VjdGlvbiwgd2hpY2ggY2FuIGJlIGN1c3RvbWl6ZWQgXHJcbiAgICAgKiB1c2luZyBhIGBWZENvZGVEaXJlY3RpdmVgLlxyXG4gICAgICogQHR5cGUge1ZkQ29kZURpcmVjdGl2ZX1cclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZENvZGVEaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgY29kZVRlbXBsYXRlPzogVmRDb2RlRGlyZWN0aXZlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IEZpbGUgdGVtcGxhdGUgY29udGVudC5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgYGZpbGVUZW1wbGF0ZWAgaG9sZHMgdGhlIGNvbnRlbnQgZm9yIHRoZSBmaWxlIHVwbG9hZCBzZWN0aW9uLCB3aGljaCBjYW4gYmUgY3VzdG9taXplZCBcclxuICAgICAqIHVzaW5nIGEgYFZkRmlsZURpcmVjdGl2ZWAuXHJcbiAgICAgKiBAdHlwZSB7VmRGaWxlRGlyZWN0aXZlfVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKFZkRmlsZURpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBmaWxlVGVtcGxhdGU/OiBWZEZpbGVEaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcHJvcGVydHkgQ3VzdG9tIHRlbXBsYXRlIGNvbnRlbnQuXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGBjdXN0b21UZW1wbGF0ZWAgaG9sZHMgdGhlIGNvbnRlbnQgZm9yIGN1c3RvbSBmb3JtIHNlY3Rpb25zLCB3aGljaCBjYW4gYmUgY3VzdG9taXplZCBcclxuICAgICAqIHVzaW5nIGEgYFZkQ3VzdG9tRGlyZWN0aXZlYC5cclxuICAgICAqIEB0eXBlIHtWZEN1c3RvbURpcmVjdGl2ZX1cclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZEN1c3RvbURpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBjdXN0b21UZW1wbGF0ZT86IFZkQ3VzdG9tRGlyZWN0aXZlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IERhdGUgcGlja2VyIGhlYWRlciBjb21wb25lbnQuXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGBkYXRlUGlja2VySGVhZGVyQ29tcG9uZW50YCByZXByZXNlbnRzIHRoZSBjb21wb25lbnQgdXNlZCBmb3IgZGlzcGxheWluZyBhIGN1c3RvbSBcclxuICAgICAqIGhlYWRlciBpbiB0aGUgZGF0ZSBwaWNrZXIuXHJcbiAgICAgKiBAdHlwZSB7RGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudH1cclxuICAgICAqL1xyXG4gICAgcHVibGljIGRhdGVQaWNrZXJIZWFkZXJDb21wb25lbnQgPSBEYXRlUGlja2VySGVhZGVyQ29tcG9uZW50O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IFRlbXBsYXRlIHJlZmVyZW5jZSBmb3IgY3VzdG9tIGZpZWxkcyBhdCB0aGUgYm90dG9tLlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgYm90dG9tYCB0ZW1wbGF0ZSByZWZlcmVuY2UgaXMgdXNlZCB0byBkaXNwbGF5IGN1c3RvbSBmaWVsZHMgYXQgdGhlIGJvdHRvbSBvZiB0aGUgZm9ybSBcclxuICAgICAqIGlmIG5lZWRlZC5cclxuICAgICAqIEB0eXBlIHtUZW1wbGF0ZVJlZjxhbnk+fVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKCdib3R0b20nKVxyXG4gICAgcHVibGljIGJvdHRvbT86IFRlbXBsYXRlUmVmPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcHJvcGVydHkgVGVtcGxhdGUgcmVmZXJlbmNlIGZvciBjdXN0b20gZmllbGRzLlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgY3VzdG9tRmllbGRzYCB0ZW1wbGF0ZSByZWZlcmVuY2UgaXMgdXNlZCB0byByZW5kZXIgY3VzdG9tIGZpZWxkcyBpbiB0aGUgZm9ybSBhcyBkZWZpbmVkIFxyXG4gICAgICogYnkgdGhlIHVzZXIuXHJcbiAgICAgKiBAdHlwZSB7VGVtcGxhdGVSZWY8YW55Pn1cclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZCgnY3VzdG9tRmllbGRzJylcclxuICAgIHB1YmxpYyBjdXN0b21GaWVsZHM/OiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHByb3BlcnR5IFRlbXBsYXRlIHJlZmVyZW5jZXMgZm9yIGN1c3RvbSBmaWVsZHMuXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGBjdXN0b21GaWVsZHNUZW1wbGF0ZXNgIGhvbGRzIGEgY29sbGVjdGlvbiBvZiBgVmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlYCB0ZW1wbGF0ZXMgXHJcbiAgICAgKiB1c2VkIGZvciByZW5kZXJpbmcgY3VzdG9tIGZpZWxkcyBpbiB0aGUgZm9ybS5cclxuICAgICAqIEB0eXBlIHtRdWVyeUxpc3Q8VmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlPn1cclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihWZEdlbmVyaWNGb3JtQ3VzdG9tRmllbGREaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgY3VzdG9tRmllbGRzVGVtcGxhdGVzPzogUXVlcnlMaXN0PFZkR2VuZXJpY0Zvcm1DdXN0b21GaWVsZERpcmVjdGl2ZT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcHJvcGVydHkgRmlsdGVyZWQgb3B0aW9ucyBmb3IgYXV0b2NvbXBsZXRlIGZpZWxkcy5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgYGF1dG9jb21wbGV0ZUZpbHRlcmVkT3B0aW9uc2AgaG9sZHMgdGhlIG9wdGlvbnMgZm9yIGF1dG9jb21wbGV0ZSBmaWVsZHMgYWZ0ZXIgdGhleSBoYXZlIFxyXG4gICAgICogYmVlbiBmaWx0ZXJlZCBiYXNlZCBvbiB0aGUgdXNlciBpbnB1dC5cclxuICAgICAqIEB0eXBlIHthbnl9XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdXRvY29tcGxldGVGaWx0ZXJlZE9wdGlvbnM6IGFueSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWxsYmFjayBtZXRob2QgdGhhdCBpcyBpbnZva2VkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZVxyXG4gICAgICogZGVmYXVsdCBjaGFuZ2UgZGV0ZWN0b3IgaGFzIGNoZWNrZWQgdGhlIGRpcmVjdGl2ZSdzXHJcbiAgICAgKiBkYXRhLWJvdW5kIHByb3BlcnRpZXMgZm9yIHRoZSBmaXJzdCB0aW1lLFxyXG4gICAgICogYW5kIGJlZm9yZSBhbnkgb2YgdGhlIHZpZXcgb3IgY29udGVudCBjaGlsZHJlbiBoYXZlIGJlZW4gY2hlY2tlZC5cclxuICAgICAqIEl0IGlzIGludm9rZWQgb25seSBvbmNlIHdoZW4gdGhlIGRpcmVjdGl2ZSBpcyBpbnN0YW50aWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgICAgICAvKiBCdWlsZCB0aGUgZm9ybSBmaWVsZHMgaWYgYSBjbGFzcyB0eXBlIGlzIGRlZmluZWQgKi9cclxuICAgICAgICBpZiAodGhpcy5jbGFzc1R5cGUgLyomJiAhdGhpcy5maWVsZEdyb3VwcyovKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYnVpbGRGaWVsZHMoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIFJldHJpZXZlIHRoZSBmaWVsZCByb3dzIG1hdGNoaW5nIHRoZSBzcGVjaWZpZWQgZ3JvdXAgbmFtZSwgZXhjbHVkaW5nIGhpZGRlbiBncm91cHMgKi9cclxuICAgICAgICBsZXQgZmllbGRSb3dzID0gdGhpcy5maWVsZEdyb3Vwcz8uZmlsdGVyKHggPT5cclxuICAgICAgICAgICAgeC5uYW1lPy50cmltKCkgPT0gdGhpcy5ncm91cE5hbWU/LnRyaW0oKSAmJlxyXG4gICAgICAgICAgICAheC5oaWRkZW5cclxuICAgICAgICApWzBdPy5ncm91cHM7XHJcblxyXG4gICAgICAgIC8qIENsb25lIHRoZSBmaWVsZCByb3dzIHRvIGF2b2lkIG1vZGlmeWluZyB0aGUgb3JpZ2luYWwgZGF0YSAqL1xyXG4gICAgICAgIGlmIChmaWVsZFJvd3MpIHtcclxuICAgICAgICAgICAgdGhpcy5maWVsZFJvd3MgPSBmaWVsZFJvd3MubWFwKGEgPT4gWy4uLmEubWFwKHkgPT4gKHsgLi4ueSB9KSldKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIEZpbHRlciB0aGUgZmllbGRzIHRvIHJldGFpbiBvbmx5IHRob3NlIGJlbG9uZ2luZyB0byB0aGUgc3BlY2lmaWVkIGZpZWxkIHNldHMgKi9cclxuICAgICAgICBpZiAodGhpcy5maWVsZFNldHMgJiYgdGhpcy5maWVsZFJvd3MpIHtcclxuICAgICAgICAgICAgdGhpcy5maWVsZFJvd3MgPSB0aGlzLmZpZWxkUm93c1xyXG4gICAgICAgICAgICAgICAgLm1hcCh4ID0+XHJcbiAgICAgICAgICAgICAgICAgICAgeC5maWx0ZXIoeSA9PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5LmZpZWxkU2V0cz8uc29tZSh6ID0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpZWxkU2V0cz8uc29tZShhID0+IGE/LnRyaW0oKT8udG9Mb3dlckNhc2UoKSA9PSB6Py50cmltKCk/LnRvTG93ZXJDYXNlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICAuZmlsdGVyKHggPT4geC5sZW5ndGgpOyAvLyBSZW1vdmUgZW1wdHkgcm93c1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogRmxhdHRlbiB0aGUgZmllbGQgcm93cyB0byBleHRyYWN0IGFsbCBmaWVsZHMgYW5kIGNsb25lIHRoZW0gKi9cclxuICAgICAgICBsZXQgZmllbGRzID0gdGhpcy5maWVsZFJvd3M/LnJlZHVjZSgoYSwgYikgPT4gYS5jb25jYXQoYiksIFtdKTtcclxuICAgICAgICBpZiAoZmllbGRzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmllbGRzID0gZmllbGRzLm1hcChhID0+ICh7IC4uLmEgfSkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogU3Vic2NyaWJlIHRvIHZhbHVlIGNoYW5nZSBldmVudHMgZm9yIGZpZWxkcyB3aXRoIGN1c3RvbSAnY2hhbmdlJyBoYW5kbGVycyAqL1xyXG4gICAgICAgIGZpZWxkc1xyXG4gICAgICAgICAgICA/LmZpbHRlcih5ID0+IHkudHlwZSAhPSBGb3JtRmllbGRUeXBlLkZpbGUgJiYgeS5jaGFuZ2UpXHJcbiAgICAgICAgICAgID8uZm9yRWFjaCh4ID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwXHJcbiAgICAgICAgICAgICAgICAgICAgPy5nZXQoeC5uYW1lID8/ICcnKVxyXG4gICAgICAgICAgICAgICAgICAgID8udmFsdWVDaGFuZ2VzPy5zdWJzY3JpYmUoeSA9PiB4LmNoYW5nZT8uKHksIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVXBkYXRlcyB0aGUgZHluYW1pYyBwcm9wZXJ0aWVzICh0eXBlLCBsYWJlbCwgb3B0aW9ucywgZXRjLikgb2YgYSBmaWVsZC5cclxuICAgICAgICAgKiBAcGFyYW0gb3JnRmllbGQgLSBUaGUgb3JpZ2luYWwgZmllbGQgZGVmaW5pdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0geCAtIFRoZSBjdXJyZW50IGZpZWxkIGluc3RhbmNlIGJlaW5nIHVwZGF0ZWQuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbGV0IHVwZGF0ZUZvcm1GaWVsZCA9IChvcmdGaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgeDogRm9ybUZpZWxkRGVmaW5pdGlvbikgPT4ge1xyXG4gICAgICAgICAgICAvKiBSZXRyaWV2ZSBhbmQgcmVuZGVyIHRoZSBmaWVsZCB0eXBlICovXHJcbiAgICAgICAgICAgIHgudHlwZSA9IHR5cGVvZiBvcmdGaWVsZD8udHlwZSA9PT0gJ2Z1bmN0aW9uJ1xyXG4gICAgICAgICAgICAgICAgPyBvcmdGaWVsZC50eXBlKHRoaXMuZm9ybVZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KVxyXG4gICAgICAgICAgICAgICAgOiB4LnR5cGU7XHJcblxyXG4gICAgICAgICAgICAvKiBSZXRyaWV2ZSBhbmQgcmVuZGVyIHRoZSBmaWVsZCBsYWJlbCAqL1xyXG4gICAgICAgICAgICB4LmxhYmVsID0gdHlwZW9mIG9yZ0ZpZWxkPy5sYWJlbCA9PT0gJ2Z1bmN0aW9uJ1xyXG4gICAgICAgICAgICAgICAgPyBvcmdGaWVsZC5sYWJlbCh0aGlzLmZvcm1WYWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dClcclxuICAgICAgICAgICAgICAgIDogeC5sYWJlbDtcclxuXHJcbiAgICAgICAgICAgIC8qIFJldHJpZXZlIGFuZCByZW5kZXIgdGhlIGZpZWxkIG9wdGlvbnMgKi9cclxuICAgICAgICAgICAgeC5vcHRpb25zID0gdHlwZW9mIG9yZ0ZpZWxkPy5vcHRpb25zID09PSAnZnVuY3Rpb24nXHJcbiAgICAgICAgICAgICAgICA/IG9yZ0ZpZWxkLm9wdGlvbnModGhpcy5mb3JtVmFsdWUsIHRoaXMuZm9ybUdyb3VwLCB0aGlzLmNvbnRleHQpXHJcbiAgICAgICAgICAgICAgICA6IHgub3B0aW9ucztcclxuXHJcbiAgICAgICAgICAgIC8qIEdldCB0aGUgZm9ybSBjb250cm9sIGFzc29jaWF0ZWQgd2l0aCB0aGUgZmllbGQgKi9cclxuICAgICAgICAgICAgbGV0IGZvcm1Db250cm9sOiBGb3JtQ29udHJvbDxhbnk+ID0gPEZvcm1Db250cm9sPGFueT4+dGhpcy5mb3JtR3JvdXA/LmdldCh4Lm5hbWUgPz8gJycpO1xyXG5cclxuICAgICAgICAgICAgLyogQ2hlY2sgaWYgdGhlIGZpZWxkIGlzIHJlcXVpcmVkIGFuZCB1cGRhdGUgdmFsaWRhdG9ycyBhY2NvcmRpbmdseSAqL1xyXG4gICAgICAgICAgICBsZXQgcmVxdWlyZWQgPSB0eXBlb2YgeC5yZXF1aXJlZCA9PT0gJ2Z1bmN0aW9uJyA/IHgucmVxdWlyZWQodGhpcy5mb3JtVmFsdWUsIHRoaXMuZm9ybUdyb3VwLCB0aGlzLmNvbnRleHQpIDogeC5yZXF1aXJlZDtcclxuICAgICAgICAgICAgaWYgKGZvcm1Db250cm9sICYmIHJlcXVpcmVkICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlZCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sLmFkZFZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sLnJlbW92ZVZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKiBVcGRhdGUgZHluYW1pYyBwcm9wZXJ0aWVzIGZvciBlYWNoIGZpZWxkIGFuZCBzdWJzY3JpYmUgdG8gZm9ybSB2YWx1ZSBjaGFuZ2VzICovXHJcbiAgICAgICAgZmllbGRzPy5mb3JFYWNoKHggPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBvcmdGaWVsZCA9IHRoaXMuZmllbGRzPy5maW5kKHkgPT4geS5uYW1lID09IHgubmFtZSk7XHJcbiAgICAgICAgICAgIGlmIChvcmdGaWVsZCkge1xyXG4gICAgICAgICAgICAgICAgdXBkYXRlRm9ybUZpZWxkKG9yZ0ZpZWxkLCB4KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy52YWx1ZUNoYW5nZXM/LnN1YnNjcmliZSgoKSA9PiB1cGRhdGVGb3JtRmllbGQob3JnRmllbGQsIHgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyB0aGUgYXV0b2NvbXBsZXRlIGV2ZW50IGJ5IGZpbHRlcmluZyBvcHRpb25zIGJhc2VkIG9uIHVzZXIgaW5wdXQuXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgLSBUaGUgZmllbGQgZGVmaW5pdGlvbiBmb3Igd2hpY2ggYXV0b2NvbXBsZXRlIGlzIGhhbmRsZWQuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgaW5wdXQgZXZlbnQgY29udGFpbmluZyB0aGUgY3VycmVudCB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGZpbHRlckF1dG9jb21wbGV0ZShmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIGlmIChmaWVsZC5uYW1lKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWVdID0gKDx7IGlkOiBhbnk7IG5hbWU6IHN0cmluZyB9W10+ZmllbGQub3B0aW9ucylcclxuICAgICAgICAgICAgICAgID8uZmlsdGVyKG9wdGlvbiA9PiBvcHRpb24ubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGV2ZW50LnZhbHVlPy50b1N0cmluZygpPy50b0xvd2VyQ2FzZSgpKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIGNoaXAgd2hlbiBhbiBhdXRvY29tcGxldGUgdmFsdWUgaXMgc2VsZWN0ZWQuXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgLSBUaGUgZm9ybSBmaWVsZCBkZWZpbml0aW9uIHdoZXJlIHRoZSBjaGlwIGlzIGFkZGVkLlxyXG4gICAgICogQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IGNvbnRhaW5pbmcgdGhlIHNlbGVjdGVkIGF1dG9jb21wbGV0ZSBvcHRpb24uXHJcbiAgICAgKiBAcGFyYW0gY2hpcElucHV0RXZlbnQgLSBUaGUgaW5wdXQgZXZlbnQgYXNzb2NpYXRlZCB3aXRoIHRoZSBjaGlwIGlucHV0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXV0b2NvbXBsZXRlVmFsdWVTZWxlY3RlZChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgZXZlbnQ6IE1hdEF1dG9jb21wbGV0ZVNlbGVjdGVkRXZlbnQsIGNoaXBJbnB1dEV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgICAgICAvKiBBZGQgdGhlIHNlbGVjdGVkIHZhbHVlIGFzIGEgY2hpcCAqL1xyXG4gICAgICAgIHRoaXMuX2FkZENoaXAoZmllbGQsIGV2ZW50Lm9wdGlvbi52aWV3VmFsdWUpO1xyXG5cclxuICAgICAgICAvKiBDbGVhciB0aGUgaW5wdXQgdmFsdWUgKi9cclxuICAgICAgICBjaGlwSW5wdXRFdmVudC52YWx1ZSA9ICcnO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIGNoaXAgZnJvbSB0aGUgY2hpcCBpbnB1dCBldmVudC5cclxuICAgICAqIEBwYXJhbSBmaWVsZCAtIFRoZSBmb3JtIGZpZWxkIGRlZmluaXRpb24gd2hlcmUgdGhlIGNoaXAgaXMgYWRkZWQuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgY29udGFpbmluZyB0aGUgY2hpcCBpbnB1dCB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFkZENoaXAoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGV2ZW50OiBNYXRDaGlwSW5wdXRFdmVudCk6IHZvaWQge1xyXG4gICAgICAgIC8qIEFkZCB0aGUgdmFsdWUgZnJvbSB0aGUgY2hpcCBpbnB1dCAqL1xyXG4gICAgICAgIHRoaXMuX2FkZENoaXAoZmllbGQsIGV2ZW50LnZhbHVlKTtcclxuXHJcbiAgICAgICAgLyogQ2xlYXIgdGhlIGNoaXAgaW5wdXQgZmllbGQgKi9cclxuICAgICAgICBldmVudC5jaGlwSW5wdXQhLmNsZWFyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIHBhc3RpbmcgbXVsdGlwbGUgY2hpcHMgaW50byB0aGUgY2hpcCBpbnB1dCBmaWVsZC5cclxuICAgICAqIEBwYXJhbSBmaWVsZCAtIFRoZSBmb3JtIGZpZWxkIGRlZmluaXRpb24gd2hlcmUgY2hpcHMgYXJlIGFkZGVkLlxyXG4gICAgICogQHBhcmFtIGV2ZW50IC0gVGhlIGNsaXBib2FyZCBldmVudCBjb250YWluaW5nIHRoZSBwYXN0ZWQgZGF0YS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uUGFzdGVDaGlwcyhmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XHJcbiAgICAgICAgLyogRXh0cmFjdCB0ZXh0IGZyb20gdGhlIGNsaXBib2FyZCBkYXRhICovXHJcbiAgICAgICAgY29uc3QgY2xpcGJvYXJkRGF0YSA9IGV2ZW50LmNsaXBib2FyZERhdGE7XHJcbiAgICAgICAgY29uc3QgcGFzdGVkVGV4dCA9IGNsaXBib2FyZERhdGE/LmdldERhdGEoJ3RleHQnKSB8fCAnJztcclxuXHJcbiAgICAgICAgLyogU3BsaXQgdGhlIHBhc3RlZCB0ZXh0IGJ5IGNvbW1hcywgc2VtaWNvbG9ucywgb3IgbmV3bGluZXMsIHRoZW4gdHJpbSBhbmQgZmlsdGVyIG91dCBlbXB0eSBpdGVtcyAqL1xyXG4gICAgICAgIGNvbnN0IGl0ZW1zID0gcGFzdGVkVGV4dFxyXG4gICAgICAgICAgICAuc3BsaXQoL1ssXFxuO10vKSAgICAgICAgICAgIC8qIFNwbGl0IGJ5IGNvbW1hcywgc2VtaWNvbG9ucywgb3IgbmV3bGluZXMgKi9cclxuICAgICAgICAgICAgLm1hcChpdGVtID0+IGl0ZW0udHJpbSgpKSAgIC8qIFRyaW0gbGVhZGluZyBhbmQgdHJhaWxpbmcgc3BhY2VzICovXHJcbiAgICAgICAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtKTsgICAgICAvKiBSZW1vdmUgZW1wdHkgaXRlbXMgKi9cclxuXHJcbiAgICAgICAgLyogQWRkIGVhY2ggdmFsaWQgaXRlbSBhcyBhIGNoaXAgKi9cclxuICAgICAgICBpdGVtcz8uZm9yRWFjaCh4ID0+IHRoaXMuX2FkZENoaXAoZmllbGQsIHgudHJpbSgpKSk7XHJcblxyXG4gICAgICAgIC8qIFByZXZlbnQgdGhlIGRlZmF1bHQgcGFzdGUgYWN0aW9uICovXHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYSBjaGlwIGZyb20gdGhlIGNoaXAgbGlzdC5cclxuICAgICAqIEBwYXJhbSBmaWVsZCAtIFRoZSBmb3JtIGZpZWxkIGRlZmluaXRpb24gd2hlcmUgdGhlIGNoaXAgaXMgcmVtb3ZlZC5cclxuICAgICAqIEBwYXJhbSBjaGlwIC0gVGhlIGNoaXAgdmFsdWUgdG8gcmVtb3ZlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVtb3ZlQ2hpcChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgY2hpcDogYW55KTogdm9pZCB7XHJcbiAgICAgICAgLyogR2V0IHRoZSBmb3JtIGNvbnRyb2wgYXNzb2NpYXRlZCB3aXRoIHRoZSBmaWVsZCBuYW1lICovXHJcbiAgICAgICAgbGV0IGNvbnRyb2wgPSB0aGlzLmZvcm1Hcm91cD8uY29udHJvbHNbZmllbGQubmFtZSA/PyAnJ107XHJcblxyXG4gICAgICAgIC8qIEZpbmQgdGhlIGluZGV4IG9mIHRoZSBjaGlwIHRvIHJlbW92ZSAqL1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gY29udHJvbD8udmFsdWUuaW5kZXhPZihjaGlwKTtcclxuICAgICAgICBpZiAoY29udHJvbCAmJiBpbmRleCA+PSAwKSB7XHJcbiAgICAgICAgICAgIC8qIFJlbW92ZSB0aGUgY2hpcCBmcm9tIHRoZSBjb250cm9sJ3MgdmFsdWUgYXJyYXkgKi9cclxuICAgICAgICAgICAgY29udHJvbC52YWx1ZS5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cclxuICAgICAgICAgICAgLyogVXBkYXRlIHRoZSBmb3JtIGNvbnRyb2wgc3RhdGUgYW5kIHZhbGlkaXR5ICovXHJcbiAgICAgICAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cD8ubWFya0FzRGlydHkoKTtcclxuICAgICAgICAgICAgdGhpcy5mb3JtR3JvdXA/LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGEgY2hpcCB0byB0aGUgZm9ybSBjb250cm9sIGJhc2VkIG9uIGl0cyB2YWx1ZS5cclxuICAgICAqIEBwYXJhbSBmaWVsZCAtIFRoZSBmb3JtIGZpZWxkIGRlZmluaXRpb24gd2hlcmUgdGhlIGNoaXAgaXMgYWRkZWQuXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgb2YgdGhlIGNoaXAgdG8gYWRkLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9hZGRDaGlwKGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCB2YWx1ZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgLyogR2V0IHRoZSBmb3JtIGNvbnRyb2wgYXNzb2NpYXRlZCB3aXRoIHRoZSBmaWVsZCBuYW1lICovXHJcbiAgICAgICAgbGV0IGNvbnRyb2wgPSB0aGlzLmZvcm1Hcm91cD8uY29udHJvbHNbZmllbGQubmFtZSA/PyAnJ107XHJcblxyXG4gICAgICAgIC8qIFRyaW0gdGhlIGlucHV0IHZhbHVlICovXHJcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfHwgJycpLnRyaW0oKTtcclxuXHJcbiAgICAgICAgaWYgKGNvbnRyb2wgJiYgdmFsdWUpIHtcclxuICAgICAgICAgICAgLyogQWRkIHRoZSB2YWx1ZSB0byB0aGUgY29udHJvbCBiYXNlZCBvbiBpdHMgaW5wdXQgdHlwZSAqL1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGZpZWxkLmlucHV0VHlwZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnbnVtYmVyJzpcclxuICAgICAgICAgICAgICAgICAgICAvKiBQYXJzZSBhbmQgYWRkIGEgbnVtYmVyIGlmIHZhbGlkICovXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IG51bWJlciA9IHBhcnNlSW50KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzTmFOKG51bWJlcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC52YWx1ZS5wdXNoKG51bWJlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Zsb2F0JzpcclxuICAgICAgICAgICAgICAgICAgICAvKiBQYXJzZSBhbmQgYWRkIGEgZmxvYXQgaWYgdmFsaWQgKi9cclxuICAgICAgICAgICAgICAgICAgICBsZXQgZmxvYXQgPSBwYXJzZUZsb2F0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzTmFOKGZsb2F0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2goZmxvYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIC8qIEFkZCB0aGUgdmFsdWUgYXMgYSBzdHJpbmcgKi9cclxuICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2godmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiBVcGRhdGUgdGhlIGZvcm0gY29udHJvbCBzdGF0ZSBhbmQgdmFsaWRpdHkgKi9cclxuICAgICAgICAgICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cD8udXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhhbmRsZXMgdGhlIGV2ZW50IHdoZW4gYSBkYXRlIHBpY2tlciBpcyBvcGVuZWQuXHJcbiAgICAgKiBAcGFyYW0gZGF0ZVBpY2tlciAtIFRoZSBkYXRlIHBpY2tlciBpbnN0YW5jZSB0aGF0IGlzIG9wZW5lZC5cclxuICAgICAqIEBwYXJhbSBmaWVsZCAtIFRoZSBmb3JtIGZpZWxkIGRlZmluaXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBkYXRlIHBpY2tlci5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGhhbmRsZURhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlcjogTWF0RGF0ZXBpY2tlcjxhbnk+LCBmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbik6IHZvaWQge1xyXG4gICAgICAgIGlmIChmaWVsZD8uZGF0ZVBpY2tlck9wZW5lZCkge1xyXG4gICAgICAgICAgICAvKiBJbnZva2UgdGhlIGN1c3RvbSBjYWxsYmFjayBmb3Igd2hlbiB0aGUgZGF0ZSBwaWNrZXIgaXMgb3BlbmVkICovXHJcbiAgICAgICAgICAgIGZpZWxkLmRhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGRhdGUgZmlsdGVyIGV2ZW50IGFzeW5jaHJvbm91c2x5IGZvciB0aGUgZGF0ZSBwaWNrZXIuXHJcbiAgICAgKiBAcGFyYW0gZGF0ZVBpY2tlciAtIFRoZSBkYXRlIHBpY2tlciBpbnN0YW5jZSB0byBhcHBseSB0aGUgZmlsdGVyIHRvLlxyXG4gICAgICogQHBhcmFtIGZpZWxkIC0gVGhlIGZvcm0gZmllbGQgZGVmaW5pdGlvbiBjb250YWluaW5nIHRoZSBhc3luYyBmaWx0ZXIgbG9naWMuXHJcbiAgICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBjdXJyZW50IGRhdGUgdmFsdWUgdG8gYmUgdmFsaWRhdGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlRGF0ZVBpY2tlckZpbHRlckFzeW5jKGRhdGVQaWNrZXI6IE1hdERhdGVwaWNrZXI8YW55PiwgZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGRhdGU6IERhdGUgfCBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZmllbGQ/LmRhdGVGaWx0ZXJBc3luYykge1xyXG4gICAgICAgICAgICAvKiBEaXNhYmxlIGFsbCBkYXRlcyBieSBzZXR0aW5nIHRoZSBkYXRlIGZpbHRlciB0byBhbHdheXMgcmV0dXJuIGZhbHNlLiAqL1xyXG4gICAgICAgICAgICBkYXRlUGlja2VyLmRhdGVwaWNrZXJJbnB1dC5kYXRlRmlsdGVyID0gKGQ6IERhdGUpID0+IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgLyogVHJpZ2dlciBBbmd1bGFyJ3MgY2hhbmdlIGRldGVjdGlvbiB0byB1cGRhdGUgdGhlIGRhdGUgZmlsdGVyIGluIHRoZSB2aWV3LiAqL1xyXG4gICAgICAgICAgICBkYXRlUGlja2VyLm5nT25DaGFuZ2VzKDxTaW1wbGVDaGFuZ2VzPnsgJ2RhdGVGaWx0ZXInOiBuZXcgU2ltcGxlQ2hhbmdlKFwiXCIsIFwiXCIsIGZhbHNlKSB9KTtcclxuXHJcbiAgICAgICAgICAgIC8qIENhbGwgdGhlIGFzeW5jaHJvbm91cyBkYXRlIGZpbHRlciBmdW5jdGlvbiB0byB2YWxpZGF0ZSB0aGUgcHJvdmlkZWQgZGF0ZS4gKi9cclxuICAgICAgICAgICAgZmllbGQuZGF0ZUZpbHRlckFzeW5jKGRhdGUsIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkuc3Vic2NyaWJlKHggPT4ge1xyXG4gICAgICAgICAgICAgICAgLyogVXBkYXRlIHRoZSBkYXRlIGZpbHRlciBiYXNlZCBvbiB0aGUgYXN5bmNocm9ub3VzIHZhbGlkYXRpb24gcmVzdWx0LiAqL1xyXG4gICAgICAgICAgICAgICAgZGF0ZVBpY2tlci5kYXRlcGlja2VySW5wdXQuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBkICYmIHgoZCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLyogVHJpZ2dlciBBbmd1bGFyJ3MgY2hhbmdlIGRldGVjdGlvbiBhZ2FpbiB0byByZWZsZWN0IHRoZSBuZXcgZGF0ZSBmaWx0ZXIuICovXHJcbiAgICAgICAgICAgICAgICBkYXRlUGlja2VyLm5nT25DaGFuZ2VzKDxTaW1wbGVDaGFuZ2VzPnsgJ2RhdGVGaWx0ZXInOiBuZXcgU2ltcGxlQ2hhbmdlKFwiXCIsIFwiXCIsIGZhbHNlKSB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyBjYWxlbmRhciBmaWx0ZXIgZXZlbnQgYXN5bmNocm9ub3VzbHkgZm9yIHRoZSBjYWxlbmRhciBjb21wb25lbnQuXHJcbiAgICAgKiBAcGFyYW0gY2FsZW5kYXIgLSBUaGUgY2FsZW5kYXIgaW5zdGFuY2UgdG8gYXBwbHkgdGhlIGZpbHRlciB0by5cclxuICAgICAqIEBwYXJhbSBmaWVsZCAtIFRoZSBmb3JtIGZpZWxkIGRlZmluaXRpb24gY29udGFpbmluZyB0aGUgYXN5bmMgZmlsdGVyIGxvZ2ljLlxyXG4gICAgICogQHBhcmFtIGRhdGUgLSBUaGUgY3VycmVudCBkYXRlIHZhbHVlIHRvIGJlIHZhbGlkYXRlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGhhbmRsZUNhbGVuZGFyRmlsdGVyQXN5bmMoY2FsZW5kYXI6IE1hdENhbGVuZGFyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBkYXRlOiBEYXRlIHwgYW55KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlRmlsdGVyQXN5bmMpIHtcclxuICAgICAgICAgICAgLyogRGlzYWJsZSBhbGwgZGF0ZXMgYnkgc2V0dGluZyB0aGUgZGF0ZSBmaWx0ZXIgdG8gYWx3YXlzIHJldHVybiBmYWxzZS4gKi9cclxuICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIC8qIFRyaWdnZXIgQW5ndWxhcidzIGNoYW5nZSBkZXRlY3Rpb24gdG8gdXBkYXRlIHRoZSBkYXRlIGZpbHRlciBpbiB0aGUgdmlldy4gKi9cclxuICAgICAgICAgICAgY2FsZW5kYXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogQ2FsbCB0aGUgYXN5bmNocm9ub3VzIGRhdGUgZmlsdGVyIGZ1bmN0aW9uIHRvIHZhbGlkYXRlIHRoZSBwcm92aWRlZCBkYXRlLiAqL1xyXG4gICAgICAgICAgICB2YXIgc3Vic2NyaXB0aW9uID0gZmllbGQuZGF0ZUZpbHRlckFzeW5jKGRhdGUsIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkuc3Vic2NyaWJlKHggPT4ge1xyXG4gICAgICAgICAgICAgICAgLyogVXBkYXRlIHRoZSBkYXRlIGZpbHRlciBiYXNlZCBvbiB0aGUgYXN5bmNocm9ub3VzIHZhbGlkYXRpb24gcmVzdWx0LiAqL1xyXG4gICAgICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBkICYmIHgoZCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLyogVHJpZ2dlciBBbmd1bGFyJ3MgY2hhbmdlIGRldGVjdGlvbiBhZ2FpbiB0byByZWZsZWN0IHRoZSBuZXcgZGF0ZSBmaWx0ZXIuICovXHJcbiAgICAgICAgICAgICAgICBjYWxlbmRhci5uZ09uQ2hhbmdlcyg8U2ltcGxlQ2hhbmdlcz57ICdkYXRlRmlsdGVyJzogbmV3IFNpbXBsZUNoYW5nZShcIlwiLCBcIlwiLCBmYWxzZSkgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLyogVW5zdWJzY3JpYmUgZnJvbSB0aGUgb2JzZXJ2YWJsZSB0byBwcmV2ZW50IG1lbW9yeSBsZWFrcy4gKi9cclxuICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCdWlsZHMgdGhlIGZvcm0gZmllbGRzIGZvciB0aGUgY29tcG9uZW50LlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYnVpbGRGaWVsZHMoKTogdm9pZCB7XHJcbiAgICAgICAgLyogRW5zdXJlIHRoZSBjbGFzcyB0eXBlIGlzIGRlZmluZWQsIGFzIGl0IGlzIHJlcXVpcmVkIHRvIGdlbmVyYXRlIHRoZSBmb3JtIGRlZmluaXRpb24uICovXHJcbiAgICAgICAgaWYgKCF0aGlzLmNsYXNzVHlwZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2xhc3NUeXBlLiBQbGVhc2UgZW5zdXJlIGNsYXNzVHlwZSBpcyBkZWZpbmVkLCBub3QgbnVsbCwgYW5kIGlzIGEgY29uc3RydWN0b3IgZnVuY3Rpb24uJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBHZW5lcmF0ZSB0aGUgZm9ybSBkZWZpbml0aW9uIHVzaW5nIHRoZSBjbGFzcyB0eXBlJ3MgbWV0YWRhdGEuICovXHJcbiAgICAgICAgdGhpcy5mb3JtRGVmaW5pdGlvbiA9IGdldEZvcm1EZWZpbml0aW9uKG5ldyB0aGlzLmNsYXNzVHlwZSgpKTtcclxuXHJcbiAgICAgICAgLyogQ3JlYXRlIGZvcm0gZmllbGQgZ3JvdXBzLCBleGNsdWRpbmcgYW55IGhpZGRlbiBmaWVsZHMuICovXHJcbiAgICAgICAgdGhpcy5maWVsZEdyb3VwcyA9IHRoaXMuZm9ybURlZmluaXRpb24/LmZpZWxkR3JvdXBzPy5maWx0ZXIoeCA9PiAheC5oaWRkZW4pPy5tYXAoYSA9PiB7IHJldHVybiB7IC4uLmEgfSB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvZ3MgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlLlxyXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgcHJpbWFyeSBtZXNzYWdlIHRvIGxvZy5cclxuICAgICAqIEBwYXJhbSBvcHRpb25hbFBhcmFtcyAtIEFkZGl0aW9uYWwgcGFyYW1ldGVycyB0byBpbmNsdWRlIGluIHRoZSBsb2cuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2cobWVzc2FnZTogYW55LCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pOiB2b2lkIHtcclxuICAgICAgICAvKiBMb2cgdGhlIHByb3ZpZGVkIG1lc3NhZ2UgYW5kIG9wdGlvbmFsIHBhcmFtZXRlcnMgdG8gdGhlIGNvbnNvbGUuICovXHJcbiAgICAgICAgY29uc29sZS5sb2cobWVzc2FnZSwgb3B0aW9uYWxQYXJhbXMpO1xyXG4gICAgfVxyXG59IiwiPGRpdiAqbmdJZj1cImZvcm1Hcm91cCAmJiBmaWVsZFJvd3NcIiBbZm9ybUdyb3VwXT1cImZvcm1Hcm91cFwiPlxyXG4gICAgPCEtLSAjcmVnaW9uIEZpZWxkcyAtLT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkcyBvZiBmaWVsZFJvd3M7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICA8ZGl2IGxheW91dC1ndC1zbT1cInJvd1wiIGxheW91dD1cImNvbHVtblwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmaWVsZHNcIiBbbmdTd2l0Y2hdPVwiZmllbGQudHlwZVwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmaWVsZC5oaWRkZW4gJiYgIShmaWVsZC5oaWRlICYmIGZpZWxkLmhpZGUoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWVsZC53cmFwcGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZXh0IGlucHV0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVGV4dFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZmllbGQuaW5wdXRUeXBlID8/ICd0ZXh0J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbmxlbmd0aF09XCJmaWVsZC5taW5MZW5ndGggfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21heGxlbmd0aF09XCJmaWVsZC5tYXhMZW5ndGggfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGF0dGVybl09XCIoKGZpZWxkLnBhdHRlcm4gIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHQpPz8nJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdXRvRm9jdXNdPVwiKChmaWVsZC5mb2N1cyAgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dCk/P2ZhbHNlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlbGVjdFRleHRdPVwiKChmaWVsZC5zZWxlY3RUZXh0ICB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0KT8/ZmFsc2UpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb25seU51bWJlcl09XCIoZmllbGQubnVtYmVyc09ubHk/P2ZhbHNlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VEZWNpbWFsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhcnNlRGVjaW1hbEVuYWJsZWRdPVwiKGZpZWxkLnBhcnNlRGVjaW1hbD8/ZmFsc2UpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bik9XCJmaWVsZC5rZXlkb3duICYmIGZpZWxkLmtleWRvd24oJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KCRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSkpWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZXh0YXJlYSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlRleHRBcmVhXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGV4dGFyZWEgbWF0SW5wdXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3dzPVwiZmllbGQucm93c3x8MlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bik9XCJmaWVsZC5rZXlkb3duICYmIGZpZWxkLmtleWRvd24oJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGV4dGFyZWE+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic3VmZml4QnV0dG9uLmV2ZW50ICYmIHN1ZmZpeEJ1dHRvbi5ldmVudChmb3JtVmFsdWUsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBmb250U2V0PVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gRW51bSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkVudW1cIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx2ZC1zZWxlY3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlbnVtXT1cImZpZWxkLmVudW1UeXBlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2VudW1NZXRhZGF0YV09XCJmaWVsZC5lbnVtTWV0YWRhdGFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW51bUZpbHRlcl09XCJmaWVsZC5lbnVtRmlsdGVyIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uVmFsdWVQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25WYWx1ZVByb3BlcnR5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvblRleHRQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25UZXh0UHJvcGVydHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGVmYXVsdE9wdGlvbl09XCJmaWVsZC5kZWZhdWx0T3B0aW9uPz90cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RyaWdnZXJDc3NDbGFzc109XCJmaWVsZC50cmlnZ2VyQ3NzQ2xhc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHJpZ2dlck1vZGVdPVwiZmllbGQudHJpZ2dlck1vZGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXQ9XCJyb3dcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3QtdHJpZ2dlciBsZXQtdHJpZ2dlcj1cInRyaWdnZXJcIiAqbmdJZj1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZSh0cmlnZ2VyLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LW9wdGlvbiBsZXQtb3B0aW9uPVwib3B0aW9uXCIgKm5nSWY9XCJmaWVsZC5vcHRpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbb3V0ZXJIVE1MXT1cImZpZWxkLm9wdGlvblRlbXBsYXRlKG9wdGlvbiwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiIGxldC10ZXh0PVwidGV4dFwiICpuZ0lmPVwiZmllbGQub3B0aW9uSWNvbiAmJiAhZmllbGQub3B0aW9uVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBsYXlvdXQ9XCJyb3dcIiBsYXlvdXQtYWxpZ249XCJzdGFydCBjZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjb3B0aW9uSWNvblRlbXBsYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwib3B0aW9uSWNvblRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtb3B0aW9uSWNvbj1cIm9wdGlvbkljb25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IG9wdGlvbkljb246IGZpZWxkLm9wdGlvbkljb24ob3B0aW9uLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIm9wdGlvbkljb24uc3ZnSWNvblwiIFtzdmdJY29uXT1cIm9wdGlvbkljb24uc3ZnSWNvblwiIFtmb250U2V0XT1cIm9wdGlvbkljb24uZm9udFNldCB8fCAnbWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZCdcIiBbbmdTdHlsZV09XCJ7IGNvbG9yOiBvcHRpb25JY29uLmljb25Db2xvcj8/JycgfVwiPjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwib3B0aW9uSWNvbi5tYXRJY29uXCIgW2ZvbnRTZXRdPVwib3B0aW9uSWNvbi5mb250U2V0IHx8ICdtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkJ1wiIFtuZ1N0eWxlXT1cInsgY29sb3I6IG9wdGlvbkljb24uaWNvbkNvbG9yPz8nJyB9XCI+e3tvcHRpb25JY29uLm1hdEljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3t0ZXh0fX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3ZkLXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZFNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlZkU2VsZWN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW5kcG9pbnRdPVwiZmllbGQuZW5kcG9pbnQ/PycnIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGFyYW1zXT1cImZpZWxkLnBhcmFtcz8/e30gfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIiBbbWFwcGVyXT1cImZpZWxkLm1hcHBlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYXJlV2l0aF09XCJmaWVsZC5jb21wYXJlV2l0aFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsb2FkRGF0YV09XCJmaWVsZC5mZXRjaENvbmRpdGlvbiB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvblZhbHVlUHJvcGVydHldPVwiZmllbGQub3B0aW9uVmFsdWVQcm9wZXJ0eVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25UZXh0UHJvcGVydHldPVwiZmllbGQub3B0aW9uVGV4dFByb3BlcnR5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RlZmF1bHRPcHRpb25dPVwiZmllbGQuZGVmYXVsdE9wdGlvbj8/dHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRJY29uS2V5XT1cImZpZWxkLm9wdGlvbk1hdEljb25Qcm9wZXJ0eVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdmdJY29uS2V5XT1cImZpZWxkLm9wdGlvblN2Z0ljb25Qcm9wZXJ0eVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb250U2V0XT1cImZpZWxkLm9wdGlvbkljb25Gb250U2V0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlbGVjdEZpcnN0XT1cImZpZWxkLnNlbGVjdEZpcnN0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RyaWdnZXJDc3NDbGFzc109XCJmaWVsZC50cmlnZ2VyQ3NzQ2xhc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHJpZ2dlck1vZGVdPVwiZmllbGQudHJpZ2dlck1vZGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaXRlbVNlbGVjdGVkKT1cImZpZWxkLml0ZW1TZWxlY3QgJiYgZmllbGQuaXRlbVNlbGVjdCgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaXRlbUNoYW5nZSk9XCJmaWVsZC5pdGVtQ2hhbmdlICYmIGZpZWxkLml0ZW1DaGFuZ2UoJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF5b3V0PVwicm93XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LXRyaWdnZXIgbGV0LXRyaWdnZXI9XCJ0cmlnZ2VyXCIgKm5nSWY9XCJmaWVsZC50cmlnZ2VyVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySFRNTF09XCJmaWVsZC50cmlnZ2VyVGVtcGxhdGUodHJpZ2dlciwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC10cmlnZ2VyIGxldC10cmlnZ2VyPVwidHJpZ2dlclwiICpuZ0lmPVwiZmllbGQudHJpZ2dlck1hcHBlciAmJiBmaWVsZC5tdWx0aXBsZSAmJiBmaWVsZC50cmlnZ2VyTW9kZSA9PSAnY2hpcCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGlwLXNldD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hpcCAqbmdGb3I9XCJsZXQgaXRlbSBvZiB0cmlnZ2VyXCIgW2NvbG9yXT1cImZpZWxkLmNoaXBDb2xvclwiIFtjb2xvcl09XCJmaWVsZC5jaGlwQ29sb3JcIiBoaWdobGlnaHRlZCBzZWxlY3RlZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJNYXBwZXIoaXRlbSwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hpcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hpcC1zZXQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LW9wdGlvbiBsZXQtb3B0aW9uPVwib3B0aW9uXCIgKm5nSWY9XCJmaWVsZC5vcHRpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbb3V0ZXJIVE1MXT1cImZpZWxkLm9wdGlvblRlbXBsYXRlKG9wdGlvbiwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiIGxldC10ZXh0PVwidGV4dFwiICpuZ0lmPVwiZmllbGQub3B0aW9uSWNvbiAmJiAhZmllbGQub3B0aW9uVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBsYXlvdXQ9XCJyb3dcIiBsYXlvdXQtYWxpZ249XCJzdGFydCBjZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjb3B0aW9uSWNvblRlbXBsYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwib3B0aW9uSWNvblRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtb3B0aW9uSWNvbj1cIm9wdGlvbkljb25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IG9wdGlvbkljb246IGZpZWxkLm9wdGlvbkljb24ob3B0aW9uLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIm9wdGlvbkljb24uc3ZnSWNvblwiIFtzdmdJY29uXT1cIm9wdGlvbkljb24uc3ZnSWNvblwiIFtmb250U2V0XT1cIm9wdGlvbkljb24uZm9udFNldCB8fCAnbWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZCdcIiBbbmdTdHlsZV09XCJ7IGNvbG9yOiBvcHRpb25JY29uLmljb25Db2xvcj8/JycgfVwiPjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwib3B0aW9uSWNvbi5tYXRJY29uXCIgW2ZvbnRTZXRdPVwib3B0aW9uSWNvbi5mb250U2V0IHx8ICdtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkJ1wiIFtuZ1N0eWxlXT1cInsgY29sb3I6IG9wdGlvbkljb24uaWNvbkNvbG9yPz8nJyB9XCI+e3tvcHRpb25JY29uLm1hdEljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3t0ZXh0fX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3ZkLXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZExpc3QgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5WZExpc3RcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBmbG9hdExhYmVsPVwiYWx3YXlzXCIgY2xhc3M9XCJmb3JtLWZpZWxkLXR5cGUtbGlzdFwiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHZkLWxpc3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW5kcG9pbnRdPVwiZmllbGQuZW5kcG9pbnQ/PycnIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgPz97fSB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hcHBlcl09XCJmaWVsZC5tYXBwZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbXBhcmVXaXRoXT1cImZpZWxkLmNvbXBhcmVXaXRoXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsb2FkRGF0YV09XCJmaWVsZC5mZXRjaENvbmRpdGlvbiB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25WYWx1ZVByb3BlcnR5XT1cImZpZWxkLm9wdGlvblZhbHVlUHJvcGVydHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvblRleHRQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25UZXh0UHJvcGVydHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaXRlbVNlbGVjdGVkKT1cImZpZWxkLml0ZW1TZWxlY3QgJiYgZmllbGQuaXRlbVNlbGVjdCgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGl0ZW1DaGFuZ2UpPVwiZmllbGQuaXRlbUNoYW5nZSAmJiBmaWVsZC5pdGVtQ2hhbmdlKCRldmVudCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpO1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoXT1cImZpZWxkLm1heFdpZHRoXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtaGVpZ2h0XT1cImZpZWxkLm1heEhlaWdodFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1saXN0LW9wdGlvbiBsZXQtb3B0aW9uPVwib3B0aW9uXCIgKm5nSWY9XCJmaWVsZC5vcHRpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbb3V0ZXJIVE1MXT1cImZpZWxkLm9wdGlvblRlbXBsYXRlKG9wdGlvbiwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3ZkLWxpc3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENoaXBzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2hpcHNcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hpcC1ncmlkICNjaGlwTGlzdCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW2Rpc2FibGVDb250cm9sXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGlwLXJvdyAqbmdGb3I9XCJsZXQgY2hpcCBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pPy52YWx1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlZCk9XCJyZW1vdmVDaGlwKGZpZWxkLCBjaGlwKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY29sb3JdPVwiZmllbGQuY2hpcENvbG9yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGFibGU9XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hsaWdodGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3tjaGlwfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0Q2hpcFJlbW92ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBmb250U2V0PVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPmNhbmNlbDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoaXAtcm93PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBbcGxhY2Vob2xkZXJdPVwiJGFueShmaWVsZC5sYWJlbClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjY2hpcElucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRDaGlwSW5wdXRGb3JdPVwiY2hpcExpc3RcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0Q2hpcElucHV0U2VwYXJhdG9yS2V5Q29kZXNdPVwic2VwYXJhdG9yS2V5c0NvZGVzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdEF1dG9jb21wbGV0ZV09XCJjaGlwQXV0b2NvbXBsZXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cImZpbHRlckF1dG9jb21wbGV0ZShmaWVsZCwgY2hpcElucHV0KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRDaGlwSW5wdXRUb2tlbkVuZCk9XCJhZGRDaGlwKGZpZWxkLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBhc3RlKT1cIm9uUGFzdGVDaGlwcyhmaWVsZCwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hpcC1ncmlkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1hdXRvY29tcGxldGUgYXV0b0FjdGl2ZUZpcnN0T3B0aW9uICNjaGlwQXV0b2NvbXBsZXRlPVwibWF0QXV0b2NvbXBsZXRlXCIgW2NsYXNzXT1cImZpZWxkLmF1dG9jb21wbGV0ZUNzc0NsYXNzXCIgKG9wdGlvblNlbGVjdGVkKT1cImF1dG9jb21wbGV0ZVZhbHVlU2VsZWN0ZWQoZmllbGQsICRldmVudCwgY2hpcElucHV0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWUhXVwiIFt2YWx1ZV09XCJvcHRpb24uaWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tvcHRpb24ubmFtZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtYXV0b2NvbXBsZXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFZkQ2hpcHMgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5WZENoaXBzXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtY2hpcHMgI3ZkQ2hpcFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlbmRwb2ludF09XCJmaWVsZC5lbmRwb2ludD8/JycgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgfHwge30gfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlYXJjaEZpZWxkXT1cImZpZWxkLnNlYXJjaEZpZWxkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VhcmNoRmllbGRzXT1cImZpZWxkLnNlYXJjaEZpZWxkc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZpbHRlcnNdPVwiZmllbGQuZmlsdGVyc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlbGVjdEZpcnN0XT1cImZpZWxkLnNlbGVjdEZpcnN0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NUeXBlXT1cImZpZWxkLmNsYXNzVHlwZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2plY3Rpb25dPVwiZmllbGQucHJvamVjdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2tleV09XCJmaWVsZC5vcHRpb25WYWx1ZVByb3BlcnR5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZW1vdmFibGVdPVwiIWZpZWxkLmNsZWFyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY29udGV4dF09XCJjb250ZXh0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3VmZml4QnV0dG9uc109XCJmaWVsZC5zdWZmaXhCdXR0b25zXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXV0b2NvbXBsZXRlQ3NzQ2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbml0U2VsZWN0KT1cImZpZWxkLml0ZW1TZWxlY3QgJiYgZmllbGQuaXRlbVNlbGVjdCgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZCk9XCIhZmllbGQuaXRlbUNoYW5nZSA/ICRldmVudC5jYWxsYmFjayh0cnVlKSA6ICRldmVudC5jYWxsYmFjayhmaWVsZC5pdGVtQ2hhbmdlKCRldmVudC52YWx1ZSwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpICE9PSBmYWxzZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGVhcmVkKT1cImZpZWxkLmNsZWFyICYmIGZpZWxkLmNsZWFyKGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjdXN0b21WYWx1ZV09XCJmaWVsZC5jdXN0b21WYWx1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF5b3V0PVwicm93XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1jaGlwIGxldC1jaGlwPVwiY2hpcFwiICpuZ0lmPVwiZmllbGQuY2hpcFRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW291dGVySFRNTF09XCJmaWVsZC5jaGlwVGVtcGxhdGUoY2hpcCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtYXV0b2NvbXBsZXRlLW9wdGlvbiBsZXQtb3B0aW9uPVwib3B0aW9uXCIgKm5nSWY9XCJmaWVsZC5hdXRvY29tcGxldGVUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtvdXRlckhUTUxdPVwiZmllbGQuYXV0b2NvbXBsZXRlVGVtcGxhdGUob3B0aW9uLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC92ZC1jaGlwcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJ2ZENoaXAuZW1wdHlSZXN1bHRcIiBjbGFzcz1cInRjLXJlZC00MDBcIiBpMThuPVwiQEBub1Jlc3VsdHNGb3VuZFwiPk5vIHJlc3VsdHMgd2VyZSBmb3VuZC48L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlNlbGVjdFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVDb250cm9sXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsZXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiAkYW55KGZpZWxkLm9wdGlvbnMpXCIgW3ZhbHVlXT1cIm9wdGlvbi5pZFwiPnt7b3B0aW9uLm5hbWV9fTwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBBdXRvY29tcGxldGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5BdXRvY29tcGxldGVcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluXT1cImZpZWxkLm1pblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21heF09XCJmaWVsZC5tYXhcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRBdXRvY29tcGxldGVdPVwiYXV0b1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cImZpbHRlckF1dG9jb21wbGV0ZShmaWVsZCwgYXV0b2NvbXBsZXRlSW5wdXQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleWRvd24pPVwiZmllbGQua2V5ZG93biAmJiBmaWVsZC5rZXlkb3duKCRldmVudCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjYXV0b2NvbXBsZXRlSW5wdXQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWF1dG9jb21wbGV0ZSBhdXRvQWN0aXZlRmlyc3RPcHRpb24gI2F1dG89XCJtYXRBdXRvY29tcGxldGVcIiBbY2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGF1dG9jb21wbGV0ZUZpbHRlcmVkT3B0aW9uc1tmaWVsZC5uYW1lIV1cIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9uLm5hbWV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBEYXRlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuRGF0ZVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0RGF0ZXBpY2tlcl09XCJkYXRlUGlja2VyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0RGF0ZXBpY2tlckZpbHRlcl09XCJmaWVsZC5kYXRlRmlsdGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgZmllbGQuZm9yY2VTZWxlY3QgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlkb3duKT1cImZpZWxkLmtleWRvd24gJiYgZmllbGQua2V5ZG93bigkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlcGlja2VyLXRvZ2dsZSBtYXRTdWZmaXggW2Zvcl09XCJkYXRlUGlja2VyXCI+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWRhdGVwaWNrZXIgI2RhdGVQaWNrZXIgW2Rpc2FibGVkXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCIgKG1vbnRoU2VsZWN0ZWQpPVwiaGFuZGxlRGF0ZVBpY2tlckZpbHRlckFzeW5jKGRhdGVQaWNrZXIsIGZpZWxkLCAkZXZlbnQgKVwiIChvcGVuZWQpPVwiaGFuZGxlRGF0ZVBpY2tlck9wZW5lZChkYXRlUGlja2VyLCBmaWVsZClcIiBbY2FsZW5kYXJIZWFkZXJDb21wb25lbnRdPVwiZGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudFwiPjwvbWF0LWRhdGVwaWNrZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENhbGVuZGFyIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2FsZW5kYXJcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBmbG9hdExhYmVsPVwiYWx3YXlzXCIgY2xhc3M9XCJmb3JtLWZpZWxkLXR5cGUtY2FsZW5kYXJcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpbnB1dD1cImhpZGRlblwiIGhpZGRlbiBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNhbGVuZGFyICNjYWxlbmRhclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VsZWN0ZWRdPVwiZm9ybUdyb3VwLmdldChmaWVsZC5uYW1lISk/LnZhbHVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGVkQ2hhbmdlKT1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSEpPy5zZXRWYWx1ZSgkZXZlbnQpO1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtb250aFNlbGVjdGVkKT1cImhhbmRsZUNhbGVuZGFyRmlsdGVyQXN5bmMoY2FsZW5kYXIsIGZpZWxkLCAkZXZlbnQgKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtoZWFkZXJDb21wb25lbnRdPVwiZGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlkb3duKT1cImZpZWxkLmtleWRvd24gJiYgZmllbGQua2V5ZG93bigkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7XCI+PC9tYXQtY2FsZW5kYXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCIgbGF5b3V0LW1hcmdpbj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDb2xvciBpbnB1dCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkNvbG9yXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgW3R5cGVdPVwiZmllbGQuaW5wdXRUeXBlID8/ICd0ZXh0J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbmxlbmd0aF09XCJmaWVsZC5taW5MZW5ndGggfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21heGxlbmd0aF09XCJmaWVsZC5tYXhMZW5ndGggfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiIG1hdElucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhdHRlcm5dPVwiKChmaWVsZC5wYXR0ZXJuICB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0KT8/JycpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb25seU51bWJlcl09XCIoZmllbGQubnVtYmVyc09ubHk/P2ZhbHNlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleWRvd24pPVwiZmllbGQua2V5ZG93biAmJiBmaWVsZC5rZXlkb3duKCRldmVudCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmd4LWNvbG9ycyBtYXRTdWZmaXggbmd4LWNvbG9ycy10cmlnZ2VyIFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbaGlkZVRleHRJbnB1dF09XCJ0cnVlXCIgKGNsb3NlKT1cInRoaXMuZm9ybUdyb3VwLmdldChmaWVsZC5uYW1lISk/LnNldFZhbHVlKCRldmVudClcIiBmb3JtYXQ9XCJoZXhcIiBjbGFzcz1cImNvbG9yLXBpY2tlclwiPjwvbmd4LWNvbG9ycz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KCRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSkpWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENoZWNrYm94IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2hlY2tib3hcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBjbGFzcz1cIm1hdC1jaGVja2JveC13cmFwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVDb250cm9sXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkLmxhYmVsfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIiBsYXlvdXQtbWFyZ2luPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBFZGl0b3IgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5FZGl0b3JcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiZWRpdG9yVGVtcGxhdGU/LnRlbXBsYXRlUmVmIVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImVkaXRvclRlbXBsYXRlPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBmaWVsZDogZmllbGQsIGZvcm1Hcm91cDogZm9ybUdyb3VwIH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENvZGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5Db2RlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImNvZGVUZW1wbGF0ZT8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29kZVRlbXBsYXRlPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBmaWVsZDogZmllbGQsIGZvcm1Hcm91cDogZm9ybUdyb3VwIH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIEZpbGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5GaWxlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgdmQtZmlsZS1pbnB1dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdCk9XCJmaWVsZC5jaGFuZ2UgJiYgZmllbGQuY2hhbmdlKGZpZWxkLCAkZXZlbnQsIGZvcm1Hcm91cCwgY29udGV4dClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYWNjZXB0XT1cImZpZWxkLmZpbGVFeHRlbnNpb25zXCIgW2Rpc2FibGVDb250cm9sXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIEN1c3RvbSAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkN1c3RvbVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJjdXN0b21UZW1wbGF0ZT8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tVGVtcGxhdGU/LnRlbXBsYXRlUmVmIVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGZpZWxkOiBmaWVsZCwgZm9ybUdyb3VwOiBmb3JtR3JvdXAgfVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFRlbXBsYXRlIGZvciBjdXN0b20gZmllbGRzIC0tPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjdXN0b21GaWVsZCBvZiBjdXN0b21GaWVsZHNUZW1wbGF0ZXNcIj5cclxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZiAmJiBjdXN0b21GaWVsZC5yb3cgPT0gZmllbGRzWzBdPy5yb3cgJiYgY3VzdG9tRmllbGQuaW5saW5lXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmIVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPCEtLSAjcmVnaW9uIFRlbXBsYXRlIGZvciBjdXN0b20gZmllbGRzIC0tPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjdXN0b21GaWVsZHNcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJjdXN0b21GaWVsZHNcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2Zvcm1Hcm91cDogZm9ybUdyb3VwLCByb3c6IGZpZWxkc1swXS5yb3d9XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY3VzdG9tRmllbGQgb2YgY3VzdG9tRmllbGRzVGVtcGxhdGVzXCI+XHJcbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZiAmJiBjdXN0b21GaWVsZC5yb3cgPT0gKChmaWVsZHNbMF0/LnJvdz8/MCkrMSkgJiYgIWN1c3RvbUZpZWxkLmlubGluZVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2Zvcm1Hcm91cDogZm9ybUdyb3VwfVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgPCEtLSAjcmVnaW9uIEZvcm0gYm90dG9tIC0tPlxyXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJvdHRvbVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImJvdHRvbVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXB9XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgPCEtLSAjcmVnaW9uIFRlbXBsYXRlIGZvciBzdWZmaXggYnV0dG9ucyAtLT5cclxuICAgIDxuZy10ZW1wbGF0ZSAjc3VmZml4QnV0dG9ucyBsZXQtZmllbGQ+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBmb250U2V0PVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICA8IS0tICNyZWdpb24gRGVidWcgdmFsdWUgLS0+XHJcbiAgICA8Y29kZSAqbmdJZj1cImRlYnVnVmFsdWVcIj5cclxuICAgICAgICA8cHJlPnt7Zm9ybVZhbHVlIHwganNvbn19PC9wcmU+XHJcbiAgICA8L2NvZGU+XHJcbiAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcbjwvZGl2PiJdfQ==