@sapui5/sap.fe.core 1.124.2 → 1.126.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/package.json +1 -1
  2. package/src/sap/fe/core/.library +5 -1
  3. package/src/sap/fe/core/ActionRuntime.js +2 -2
  4. package/src/sap/fe/core/ActionRuntime.ts +4 -4
  5. package/src/sap/fe/core/AppComponent.js +2 -2
  6. package/src/sap/fe/core/AppComponent.ts +1 -1
  7. package/src/sap/fe/core/AppStateHandler.js +2 -2
  8. package/src/sap/fe/core/AppStateHandler.ts +1 -1
  9. package/src/sap/fe/core/BaseController.js +2 -2
  10. package/src/sap/fe/core/BaseController.ts +1 -1
  11. package/src/sap/fe/core/CommonUtils.js +3 -3
  12. package/src/sap/fe/core/CommonUtils.ts +12 -15
  13. package/src/sap/fe/core/ExtensionAPI.js +2 -2
  14. package/src/sap/fe/core/ExtensionAPI.ts +4 -3
  15. package/src/sap/fe/core/PageController.js +2 -2
  16. package/src/sap/fe/core/PageController.ts +1 -1
  17. package/src/sap/fe/core/ResourceModel.js +2 -2
  18. package/src/sap/fe/core/ResourceModel.ts +1 -1
  19. package/src/sap/fe/core/ReuseComponent.js +172 -0
  20. package/src/sap/fe/core/ReuseComponent.ts +165 -0
  21. package/src/sap/fe/core/TemplateComponent.js +2 -2
  22. package/src/sap/fe/core/TemplateComponent.ts +5 -1
  23. package/src/sap/fe/core/TemplateModel.js +2 -2
  24. package/src/sap/fe/core/TemplateModel.ts +1 -1
  25. package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.js +92 -6
  26. package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.ts +90 -10
  27. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.js +1 -1
  28. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.ts +1 -1
  29. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.js +30 -3
  30. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.ts +28 -4
  31. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.js +10 -16
  32. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.ts +19 -16
  33. package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.js +3 -3
  34. package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.ts +5 -5
  35. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.js +2 -2
  36. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.ts +1 -1
  37. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.js +17 -5
  38. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.ts +14 -6
  39. package/src/sap/fe/core/controllerextensions/ContextSharing.js +2 -2
  40. package/src/sap/fe/core/controllerextensions/ContextSharing.ts +1 -1
  41. package/src/sap/fe/core/controllerextensions/EditFlow.js +57 -43
  42. package/src/sap/fe/core/controllerextensions/EditFlow.ts +61 -46
  43. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +2 -2
  44. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +1 -1
  45. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +8 -11
  46. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +8 -16
  47. package/src/sap/fe/core/controllerextensions/InternalRouting.js +10 -7
  48. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +5 -5
  49. package/src/sap/fe/core/controllerextensions/KPIManagement.js +22 -18
  50. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +28 -23
  51. package/src/sap/fe/core/controllerextensions/MessageHandler.js +4 -4
  52. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +4 -1
  53. package/src/sap/fe/core/controllerextensions/PageReady.js +21 -15
  54. package/src/sap/fe/core/controllerextensions/PageReady.ts +29 -20
  55. package/src/sap/fe/core/controllerextensions/Paginator.js +2 -2
  56. package/src/sap/fe/core/controllerextensions/Paginator.ts +1 -1
  57. package/src/sap/fe/core/controllerextensions/Placeholder.js +12 -6
  58. package/src/sap/fe/core/controllerextensions/Placeholder.ts +15 -1
  59. package/src/sap/fe/core/controllerextensions/Recommendations.js +26 -8
  60. package/src/sap/fe/core/controllerextensions/Recommendations.ts +29 -3
  61. package/src/sap/fe/core/controllerextensions/Routing.js +5 -7
  62. package/src/sap/fe/core/controllerextensions/Routing.ts +4 -4
  63. package/src/sap/fe/core/controllerextensions/Share.js +4 -4
  64. package/src/sap/fe/core/controllerextensions/Share.ts +10 -6
  65. package/src/sap/fe/core/controllerextensions/SideEffects.js +20 -5
  66. package/src/sap/fe/core/controllerextensions/SideEffects.ts +22 -2
  67. package/src/sap/fe/core/controllerextensions/Telemetry.js +2 -2
  68. package/src/sap/fe/core/controllerextensions/Telemetry.ts +1 -1
  69. package/src/sap/fe/core/controllerextensions/ViewState.js +79 -81
  70. package/src/sap/fe/core/controllerextensions/ViewState.ts +117 -105
  71. package/src/sap/fe/core/controllerextensions/cards/CollaborationManager.js +3 -3
  72. package/src/sap/fe/core/controllerextensions/cards/CollaborationManager.ts +1 -1
  73. package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.js +2 -2
  74. package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.ts +2 -2
  75. package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.js +17 -8
  76. package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.tsx +8 -2
  77. package/src/sap/fe/core/controllerextensions/editFlow/NotApplicableContextDialog.js +1 -1
  78. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +10 -9
  79. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +15 -10
  80. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.js +2 -2
  81. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.ts +1 -1
  82. package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.js +130 -158
  83. package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.ts +240 -275
  84. package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +2 -2
  85. package/src/sap/fe/core/controllerextensions/editFlow/sticky.ts +1 -1
  86. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +46 -28
  87. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +60 -32
  88. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +2 -2
  89. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +1 -1
  90. package/src/sap/fe/core/controllerextensions/viewState/IViewStateContributor.js +2 -2
  91. package/src/sap/fe/core/controllerextensions/viewState/IViewStateContributor.ts +27 -3
  92. package/src/sap/fe/core/controls/CommandExecution.js +2 -2
  93. package/src/sap/fe/core/controls/CommandExecution.ts +2 -2
  94. package/src/sap/fe/core/controls/ComponentLoader.js +3 -3
  95. package/src/sap/fe/core/controls/ComponentLoader.ts +2 -2
  96. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.js +3 -3
  97. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.tsx +2 -2
  98. package/src/sap/fe/core/controls/EventDelegateHook.js +2 -2
  99. package/src/sap/fe/core/controls/EventDelegateHook.ts +2 -2
  100. package/src/sap/fe/core/controls/FormElementWrapper.js +51 -6
  101. package/src/sap/fe/core/controls/FormElementWrapper.ts +43 -2
  102. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.js +3 -3
  103. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.tsx +3 -3
  104. package/src/sap/fe/core/converters/ConverterContext.js +4 -2
  105. package/src/sap/fe/core/converters/ConverterContext.ts +5 -2
  106. package/src/sap/fe/core/converters/ManifestSettings.js +8 -2
  107. package/src/sap/fe/core/converters/ManifestSettings.ts +25 -3
  108. package/src/sap/fe/core/converters/ManifestWrapper.js +12 -3
  109. package/src/sap/fe/core/converters/ManifestWrapper.ts +11 -1
  110. package/src/sap/fe/core/converters/MetaModelConverter.js +7 -6
  111. package/src/sap/fe/core/converters/MetaModelConverter.ts +6 -2
  112. package/src/sap/fe/core/converters/annotations/DataField.js +56 -16
  113. package/src/sap/fe/core/converters/annotations/DataField.ts +74 -25
  114. package/src/sap/fe/core/converters/common/AnnotationConverter.js +19 -18
  115. package/src/sap/fe/core/converters/controls/Common/Action.js +5 -5
  116. package/src/sap/fe/core/converters/controls/Common/Action.ts +14 -14
  117. package/src/sap/fe/core/converters/controls/Common/Chart.js +40 -7
  118. package/src/sap/fe/core/converters/controls/Common/Chart.ts +56 -20
  119. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +8 -11
  120. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +23 -27
  121. package/src/sap/fe/core/converters/controls/Common/Form.js +10 -3
  122. package/src/sap/fe/core/converters/controls/Common/Form.ts +13 -4
  123. package/src/sap/fe/core/converters/controls/Common/KPI.js +3 -2
  124. package/src/sap/fe/core/converters/controls/Common/KPI.ts +6 -2
  125. package/src/sap/fe/core/converters/controls/Common/Table.js +137 -48
  126. package/src/sap/fe/core/converters/controls/Common/Table.ts +174 -52
  127. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +73 -21
  128. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +91 -20
  129. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +4 -4
  130. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +2 -2
  131. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +2 -2
  132. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +2 -2
  133. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +3 -3
  134. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +1 -1
  135. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +17 -16
  136. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +18 -17
  137. package/src/sap/fe/core/converters/helpers/InsightsHelpers.js +2 -2
  138. package/src/sap/fe/core/converters/helpers/InsightsHelpers.ts +1 -1
  139. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +9 -9
  140. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +12 -12
  141. package/src/sap/fe/core/converters/templates/ListReportConverter.js +13 -7
  142. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +12 -5
  143. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +9 -73
  144. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +4 -74
  145. package/src/sap/fe/core/designtime/AppComponent.designtime.js +5 -10
  146. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +3 -12
  147. package/src/sap/fe/core/formatters/CriticalityFormatter.js +4 -7
  148. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +3 -3
  149. package/src/sap/fe/core/formatters/FiscalFormat.js +5 -3
  150. package/src/sap/fe/core/formatters/FiscalFormat.ts +4 -2
  151. package/src/sap/fe/core/formatters/StandardFormatter.js +2 -2
  152. package/src/sap/fe/core/formatters/StandardFormatter.ts +3 -3
  153. package/src/sap/fe/core/fpm/Component.js +3 -3
  154. package/src/sap/fe/core/fpm/Component.ts +3 -3
  155. package/src/sap/fe/core/fpm/manifest.json +1 -1
  156. package/src/sap/fe/core/helpers/AdaptiveCardExpressionCompiler.js +2 -2
  157. package/src/sap/fe/core/helpers/AdaptiveCardExpressionCompiler.ts +1 -1
  158. package/src/sap/fe/core/helpers/BindingHelper.js +2 -2
  159. package/src/sap/fe/core/helpers/BindingHelper.ts +2 -2
  160. package/src/sap/fe/core/helpers/BindingToolkitEvaluator.js +2 -2
  161. package/src/sap/fe/core/helpers/BindingToolkitEvaluator.ts +2 -2
  162. package/src/sap/fe/core/helpers/DeleteHelper.js +7 -4
  163. package/src/sap/fe/core/helpers/DeleteHelper.ts +9 -3
  164. package/src/sap/fe/core/helpers/MetaModelFunction.js +5 -5
  165. package/src/sap/fe/core/helpers/MetaModelFunction.ts +2 -2
  166. package/src/sap/fe/core/helpers/MetaPath.js +9 -3
  167. package/src/sap/fe/core/helpers/MetaPath.ts +8 -2
  168. package/src/sap/fe/core/helpers/ModelHelper.js +149 -3
  169. package/src/sap/fe/core/helpers/ModelHelper.ts +202 -6
  170. package/src/sap/fe/core/helpers/StandardRecommendationHelper.js +3 -3
  171. package/src/sap/fe/core/helpers/StandardRecommendationHelper.ts +2 -2
  172. package/src/sap/fe/core/helpers/TitleHelper.js +4 -4
  173. package/src/sap/fe/core/helpers/TitleHelper.ts +4 -4
  174. package/src/sap/fe/core/library.js +4 -4
  175. package/src/sap/fe/core/library.ts +2 -1
  176. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +11 -3
  177. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +10 -2
  178. package/src/sap/fe/core/messagebundle.properties +8 -57
  179. package/src/sap/fe/core/messagebundle_ar.properties +2 -0
  180. package/src/sap/fe/core/messagebundle_bg.properties +2 -0
  181. package/src/sap/fe/core/messagebundle_ca.properties +2 -0
  182. package/src/sap/fe/core/messagebundle_cnr.properties +2 -0
  183. package/src/sap/fe/core/messagebundle_cs.properties +2 -0
  184. package/src/sap/fe/core/messagebundle_cy.properties +4 -2
  185. package/src/sap/fe/core/messagebundle_da.properties +2 -0
  186. package/src/sap/fe/core/messagebundle_de.properties +2 -0
  187. package/src/sap/fe/core/messagebundle_el.properties +2 -0
  188. package/src/sap/fe/core/messagebundle_en.properties +6 -57
  189. package/src/sap/fe/core/messagebundle_en_GB.properties +2 -0
  190. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +3 -36
  191. package/src/sap/fe/core/messagebundle_es.properties +2 -0
  192. package/src/sap/fe/core/messagebundle_es_MX.properties +2 -0
  193. package/src/sap/fe/core/messagebundle_et.properties +2 -0
  194. package/src/sap/fe/core/messagebundle_fi.properties +2 -0
  195. package/src/sap/fe/core/messagebundle_fr.properties +2 -0
  196. package/src/sap/fe/core/messagebundle_fr_CA.properties +3 -1
  197. package/src/sap/fe/core/messagebundle_hi.properties +2 -0
  198. package/src/sap/fe/core/messagebundle_hr.properties +2 -0
  199. package/src/sap/fe/core/messagebundle_hu.properties +3 -1
  200. package/src/sap/fe/core/messagebundle_id.properties +2 -0
  201. package/src/sap/fe/core/messagebundle_it.properties +2 -0
  202. package/src/sap/fe/core/messagebundle_iw.properties +3 -1
  203. package/src/sap/fe/core/messagebundle_ja.properties +2 -0
  204. package/src/sap/fe/core/messagebundle_kk.properties +2 -0
  205. package/src/sap/fe/core/messagebundle_ko.properties +2 -0
  206. package/src/sap/fe/core/messagebundle_lt.properties +2 -0
  207. package/src/sap/fe/core/messagebundle_lv.properties +2 -0
  208. package/src/sap/fe/core/messagebundle_mk.properties +2 -0
  209. package/src/sap/fe/core/messagebundle_ms.properties +2 -0
  210. package/src/sap/fe/core/messagebundle_nl.properties +2 -0
  211. package/src/sap/fe/core/messagebundle_no.properties +2 -0
  212. package/src/sap/fe/core/messagebundle_pl.properties +2 -0
  213. package/src/sap/fe/core/messagebundle_pt.properties +2 -0
  214. package/src/sap/fe/core/messagebundle_pt_PT.properties +2 -0
  215. package/src/sap/fe/core/messagebundle_ro.properties +2 -0
  216. package/src/sap/fe/core/messagebundle_ru.properties +2 -0
  217. package/src/sap/fe/core/messagebundle_sh.properties +64 -62
  218. package/src/sap/fe/core/messagebundle_sk.properties +2 -0
  219. package/src/sap/fe/core/messagebundle_sl.properties +2 -0
  220. package/src/sap/fe/core/messagebundle_sr.properties +2 -0
  221. package/src/sap/fe/core/messagebundle_sv.properties +2 -0
  222. package/src/sap/fe/core/messagebundle_th.properties +2 -0
  223. package/src/sap/fe/core/messagebundle_tr.properties +2 -0
  224. package/src/sap/fe/core/messagebundle_uk.properties +3 -1
  225. package/src/sap/fe/core/messagebundle_vi.properties +2 -0
  226. package/src/sap/fe/core/messagebundle_zh_CN.properties +2 -0
  227. package/src/sap/fe/core/messagebundle_zh_TW.properties +2 -0
  228. package/src/sap/fe/core/operationsHelper.js +3 -3
  229. package/src/sap/fe/core/operationsHelper.ts +2 -2
  230. package/src/sap/fe/core/rootView/Fcl.controller.js +3 -3
  231. package/src/sap/fe/core/rootView/Fcl.controller.ts +2 -2
  232. package/src/sap/fe/core/rootView/NavContainer.controller.js +2 -2
  233. package/src/sap/fe/core/rootView/NavContainer.controller.ts +1 -1
  234. package/src/sap/fe/core/rootView/RootViewBaseController.js +114 -92
  235. package/src/sap/fe/core/rootView/RootViewBaseController.ts +120 -106
  236. package/src/sap/fe/core/services/CollaborativeToolsServiceFactory.js +2 -2
  237. package/src/sap/fe/core/services/CollaborativeToolsServiceFactory.ts +1 -1
  238. package/src/sap/fe/core/services/NavigationServiceFactory.js +6 -4
  239. package/src/sap/fe/core/services/NavigationServiceFactory.ts +4 -3
  240. package/src/sap/fe/core/services/RoutingServiceFactory.js +2 -2
  241. package/src/sap/fe/core/services/RoutingServiceFactory.ts +1 -1
  242. package/src/sap/fe/core/services/ShellServicesFactory.js +1 -1
  243. package/src/sap/fe/core/services/ShellServicesFactory.ts +12 -2
  244. package/src/sap/fe/core/services/TelemetryServiceFactory.js +8 -2
  245. package/src/sap/fe/core/services/TelemetryServiceFactory.ts +7 -1
  246. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +16 -9
  247. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +22 -11
  248. package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.js +2 -2
  249. package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.ts +1 -1
  250. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +2 -2
  251. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +1 -1
  252. package/src/sap/fe/core/templating/ActionHelper.js +2 -2
  253. package/src/sap/fe/core/templating/ActionHelper.ts +2 -2
  254. package/src/sap/fe/core/templating/CommonFormatters.js +2 -2
  255. package/src/sap/fe/core/templating/CommonFormatters.ts +3 -3
  256. package/src/sap/fe/core/templating/CriticalityFormatters.js +2 -2
  257. package/src/sap/fe/core/templating/CriticalityFormatters.ts +2 -2
  258. package/src/sap/fe/core/templating/DataFieldFormatters.js +4 -4
  259. package/src/sap/fe/core/templating/DataFieldFormatters.ts +2 -2
  260. package/src/sap/fe/core/templating/DataModelPathHelper.js +2 -2
  261. package/src/sap/fe/core/templating/DataModelPathHelper.ts +2 -2
  262. package/src/sap/fe/core/templating/EntityTypeHelper.js +2 -2
  263. package/src/sap/fe/core/templating/EntityTypeHelper.ts +2 -2
  264. package/src/sap/fe/core/templating/FieldControlHelper.js +2 -2
  265. package/src/sap/fe/core/templating/FieldControlHelper.ts +2 -2
  266. package/src/sap/fe/core/templating/SemanticObjectHelper.js +2 -2
  267. package/src/sap/fe/core/templating/SemanticObjectHelper.ts +2 -2
  268. package/src/sap/fe/core/templating/UIFormatters.js +7 -7
  269. package/src/sap/fe/core/templating/UIFormatters.ts +6 -6
  270. package/src/sap/fe/core/type/DateTimeWithTimezone.js +2 -2
  271. package/src/sap/fe/core/type/DateTimeWithTimezone.ts +1 -1
  272. package/src/sap/fe/core/type/Email.js +2 -2
  273. package/src/sap/fe/core/type/Email.ts +1 -1
  274. package/src/sap/fe/core/type/FiscalDate.js +2 -2
  275. package/src/sap/fe/core/type/FiscalDate.ts +1 -1
  276. package/src/sap/fe/core/type/InputMask.js +124 -0
  277. package/src/sap/fe/core/type/InputMask.ts +131 -0
  278. package/ui5.yaml +19 -0
  279. package/src/sap/fe/core/controllerextensions/editFlow/operations/_internal.js +0 -81
  280. package/src/sap/fe/core/controllerextensions/editFlow/operations/_internal.ts +0 -117
  281. package/src/sap/fe/core/helpers/AnnotationEnum.js +0 -33
  282. package/src/sap/fe/core/helpers/AnnotationEnum.ts +0 -21
  283. package/src/sap/fe/core/helpers/BindingToolkit.js +0 -1813
  284. package/src/sap/fe/core/helpers/BindingToolkit.ts +0 -2450
  285. package/src/sap/fe/core/helpers/ClassSupport.js +0 -584
  286. package/src/sap/fe/core/helpers/ClassSupport.ts +0 -697
  287. package/src/sap/fe/core/jsx-runtime/Fragment.js +0 -14
  288. package/src/sap/fe/core/jsx-runtime/Fragment.ts +0 -3
  289. package/src/sap/fe/core/jsx-runtime/ViewLoader.js +0 -93
  290. package/src/sap/fe/core/jsx-runtime/ViewLoader.tsx +0 -86
  291. package/src/sap/fe/core/jsx-runtime/jsx-control.js +0 -177
  292. package/src/sap/fe/core/jsx-runtime/jsx-control.ts +0 -197
  293. package/src/sap/fe/core/jsx-runtime/jsx-xml.js +0 -237
  294. package/src/sap/fe/core/jsx-runtime/jsx-xml.ts +0 -246
  295. package/src/sap/fe/core/jsx-runtime/jsx.js +0 -47
  296. package/src/sap/fe/core/jsx-runtime/jsx.ts +0 -71
  297. package/src/sap/fe/core/jsx-runtime/jsxs.js +0 -10
  298. package/src/sap/fe/core/jsx-runtime/jsxs.ts +0 -3
  299. package/src/sap/fe/core/jsx-runtime/useMDXComponents.js +0 -172
  300. package/src/sap/fe/core/jsx-runtime/useMDXComponents.tsx +0 -194
@@ -1,1813 +0,0 @@
1
- /*!
2
- * SAP UI development toolkit for HTML5 (SAPUI5)
3
- * (c) Copyright 2009-2024 SAP SE. All rights reserved
4
- */
5
- sap.ui.define(["sap/fe/core/helpers/TypeGuards", "./AnnotationEnum"], function (TypeGuards, AnnotationEnum) {
6
- "use strict";
7
-
8
- var _exports = {};
9
- var resolveEnumValue = AnnotationEnum.resolveEnumValue;
10
- var isProperty = TypeGuards.isProperty;
11
- const EDM_TYPE_MAPPING = {
12
- "Edm.Boolean": {
13
- type: "sap.ui.model.odata.type.Boolean"
14
- },
15
- "Edm.Byte": {
16
- type: "sap.ui.model.odata.type.Byte"
17
- },
18
- "Edm.Date": {
19
- type: "sap.ui.model.odata.type.Date"
20
- },
21
- "Edm.DateTimeOffset": {
22
- constraints: {
23
- $Precision: "precision",
24
- $V4: "V4"
25
- },
26
- type: "sap.ui.model.odata.type.DateTimeOffset"
27
- },
28
- "Edm.Decimal": {
29
- constraints: {
30
- "@Org.OData.Validation.V1.Minimum/$Decimal": "minimum",
31
- "@Org.OData.Validation.V1.Minimum@Org.OData.Validation.V1.Exclusive": "minimumExclusive",
32
- "@Org.OData.Validation.V1.Maximum/$Decimal": "maximum",
33
- "@Org.OData.Validation.V1.Maximum@Org.OData.Validation.V1.Exclusive": "maximumExclusive",
34
- $Precision: "precision",
35
- $Scale: "scale"
36
- },
37
- type: "sap.ui.model.odata.type.Decimal"
38
- },
39
- "Edm.Double": {
40
- type: "sap.ui.model.odata.type.Double"
41
- },
42
- "Edm.Guid": {
43
- type: "sap.ui.model.odata.type.Guid"
44
- },
45
- "Edm.Int16": {
46
- type: "sap.ui.model.odata.type.Int16"
47
- },
48
- "Edm.Int32": {
49
- type: "sap.ui.model.odata.type.Int32"
50
- },
51
- "Edm.Int64": {
52
- type: "sap.ui.model.odata.type.Int64"
53
- },
54
- "Edm.SByte": {
55
- type: "sap.ui.model.odata.type.SByte"
56
- },
57
- "Edm.Single": {
58
- type: "sap.ui.model.odata.type.Single"
59
- },
60
- "Edm.Stream": {
61
- type: "sap.ui.model.odata.type.Stream"
62
- },
63
- "Edm.Binary": {
64
- type: "sap.ui.model.odata.type.Stream"
65
- },
66
- "Edm.String": {
67
- constraints: {
68
- "@com.sap.vocabularies.Common.v1.IsDigitSequence": "isDigitSequence",
69
- $MaxLength: "maxLength",
70
- $Nullable: "nullable"
71
- },
72
- type: "sap.ui.model.odata.type.String"
73
- },
74
- "Edm.TimeOfDay": {
75
- constraints: {
76
- $Precision: "precision"
77
- },
78
- type: "sap.ui.model.odata.type.TimeOfDay"
79
- }
80
- };
81
-
82
- /**
83
- * An expression that evaluates to type T, or a constant value of type T
84
- */
85
- _exports.EDM_TYPE_MAPPING = EDM_TYPE_MAPPING;
86
- const unresolvableExpression = {
87
- _type: "Unresolvable"
88
- };
89
- _exports.unresolvableExpression = unresolvableExpression;
90
- function escapeXmlAttribute(inputString) {
91
- return inputString.replace(/'/g, "\\'");
92
- }
93
- _exports.escapeXmlAttribute = escapeXmlAttribute;
94
- function hasUnresolvableExpression() {
95
- for (var _len = arguments.length, expressions = new Array(_len), _key = 0; _key < _len; _key++) {
96
- expressions[_key] = arguments[_key];
97
- }
98
- return expressions.find(expr => expr._type === "Unresolvable") !== undefined;
99
- }
100
- /**
101
- * Check two expressions for (deep) equality.
102
- *
103
- * @param a
104
- * @param b
105
- * @returns `true` if the two expressions are equal
106
- */
107
- _exports.hasUnresolvableExpression = hasUnresolvableExpression;
108
- function _checkExpressionsAreEqual(a, b) {
109
- if (a._type !== b._type) {
110
- return false;
111
- }
112
- switch (a._type) {
113
- case "Unresolvable":
114
- return false;
115
- // Unresolvable is never equal to anything even itself
116
- case "Constant":
117
- case "EmbeddedBinding":
118
- case "EmbeddedExpressionBinding":
119
- return a.value === b.value;
120
- case "Not":
121
- return _checkExpressionsAreEqual(a.operand, b.operand);
122
- case "Truthy":
123
- return _checkExpressionsAreEqual(a.operand, b.operand);
124
- case "Set":
125
- return a.operator === b.operator && a.operands.length === b.operands.length && a.operands.every(expression => b.operands.some(otherExpression => _checkExpressionsAreEqual(expression, otherExpression)));
126
- case "IfElse":
127
- return _checkExpressionsAreEqual(a.condition, b.condition) && _checkExpressionsAreEqual(a.onTrue, b.onTrue) && _checkExpressionsAreEqual(a.onFalse, b.onFalse);
128
- case "Comparison":
129
- return a.operator === b.operator && _checkExpressionsAreEqual(a.operand1, b.operand1) && _checkExpressionsAreEqual(a.operand2, b.operand2);
130
- case "Concat":
131
- const aExpressions = a.expressions;
132
- const bExpressions = b.expressions;
133
- if (aExpressions.length !== bExpressions.length) {
134
- return false;
135
- }
136
- return aExpressions.every((expression, index) => {
137
- return _checkExpressionsAreEqual(expression, bExpressions[index]);
138
- });
139
- case "Length":
140
- return _checkExpressionsAreEqual(a.pathInModel, b.pathInModel);
141
- case "PathInModel":
142
- return a.modelName === b.modelName && a.path === b.path && a.targetEntitySet === b.targetEntitySet;
143
- case "Formatter":
144
- return a.fn === b.fn && a.parameters.length === b.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(b.parameters[index], value));
145
- case "ComplexType":
146
- return a.type === b.type && a.bindingParameters.length === b.bindingParameters.length && a.bindingParameters.every((value, index) => _checkExpressionsAreEqual(b.bindingParameters[index], value));
147
- case "Function":
148
- const otherFunction = b;
149
- if (a.obj === undefined || otherFunction.obj === undefined) {
150
- return a.obj === otherFunction;
151
- }
152
- return a.fn === otherFunction.fn && _checkExpressionsAreEqual(a.obj, otherFunction.obj) && a.parameters.length === otherFunction.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(otherFunction.parameters[index], value));
153
- case "Ref":
154
- return a.ref === b.ref;
155
- }
156
- return false;
157
- }
158
-
159
- /**
160
- * Converts a nested SetExpression by inlining operands of type SetExpression with the same operator.
161
- *
162
- * @param expression The expression to flatten
163
- * @returns A new SetExpression with the same operator
164
- */
165
- _exports._checkExpressionsAreEqual = _checkExpressionsAreEqual;
166
- function flattenSetExpression(expression) {
167
- return expression.operands.reduce((result, operand) => {
168
- const candidatesForFlattening = operand._type === "Set" && operand.operator === expression.operator ? operand.operands : [operand];
169
- candidatesForFlattening.forEach(candidate => {
170
- if (result.operands.every(e => !_checkExpressionsAreEqual(e, candidate))) {
171
- result.operands.push(candidate);
172
- }
173
- });
174
- return result;
175
- }, {
176
- _type: "Set",
177
- operator: expression.operator,
178
- operands: []
179
- });
180
- }
181
-
182
- /**
183
- * Detects whether an array of boolean expressions contains an expression and its negation.
184
- *
185
- * @param expressions Array of expressions
186
- * @returns `true` if the set of expressions contains an expression and its negation
187
- */
188
- function hasOppositeExpressions(expressions) {
189
- const negatedExpressions = expressions.map(not);
190
- return expressions.some((expression, index) => {
191
- for (let i = index + 1; i < negatedExpressions.length; i++) {
192
- if (_checkExpressionsAreEqual(expression, negatedExpressions[i])) {
193
- return true;
194
- }
195
- }
196
- return false;
197
- });
198
- }
199
-
200
- /**
201
- * Logical `and` expression.
202
- *
203
- * The expression is simplified to false if this can be decided statically (that is, if one operand is a constant
204
- * false or if the expression contains an operand and its negation).
205
- *
206
- * @param operands Expressions to connect by `and`
207
- * @returns Expression evaluating to boolean
208
- */
209
- function and() {
210
- for (var _len2 = arguments.length, operands = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
211
- operands[_key2] = arguments[_key2];
212
- }
213
- const expressions = flattenSetExpression({
214
- _type: "Set",
215
- operator: "&&",
216
- operands: operands.map(wrapPrimitive)
217
- }).operands;
218
- if (hasUnresolvableExpression(...expressions)) {
219
- return unresolvableExpression;
220
- }
221
- let isStaticFalse = false;
222
- const nonTrivialExpression = expressions.filter(expression => {
223
- if (isFalse(expression)) {
224
- isStaticFalse = true;
225
- }
226
- return !isConstant(expression);
227
- });
228
- if (isStaticFalse) {
229
- return constant(false);
230
- } else if (nonTrivialExpression.length === 0) {
231
- // Resolve the constant then
232
- const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
233
- return constant(isValid);
234
- } else if (nonTrivialExpression.length === 1) {
235
- return nonTrivialExpression[0];
236
- } else if (hasOppositeExpressions(nonTrivialExpression)) {
237
- return constant(false);
238
- } else {
239
- return {
240
- _type: "Set",
241
- operator: "&&",
242
- operands: nonTrivialExpression
243
- };
244
- }
245
- }
246
-
247
- /**
248
- * Logical `or` expression.
249
- *
250
- * The expression is simplified to true if this can be decided statically (that is, if one operand is a constant
251
- * true or if the expression contains an operand and its negation).
252
- *
253
- * @param operands Expressions to connect by `or`
254
- * @returns Expression evaluating to boolean
255
- */
256
- _exports.and = and;
257
- function or() {
258
- for (var _len3 = arguments.length, operands = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
259
- operands[_key3] = arguments[_key3];
260
- }
261
- const expressions = flattenSetExpression({
262
- _type: "Set",
263
- operator: "||",
264
- operands: operands.map(wrapPrimitive)
265
- }).operands;
266
- if (hasUnresolvableExpression(...expressions)) {
267
- return unresolvableExpression;
268
- }
269
- let isStaticTrue = false;
270
- const nonTrivialExpression = expressions.filter(expression => {
271
- if (isTrue(expression)) {
272
- isStaticTrue = true;
273
- }
274
- return !isConstant(expression) || expression.value;
275
- });
276
- if (isStaticTrue) {
277
- return constant(true);
278
- } else if (nonTrivialExpression.length === 0) {
279
- // Resolve the constant then
280
- const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
281
- return constant(isValid);
282
- } else if (nonTrivialExpression.length === 1) {
283
- return nonTrivialExpression[0];
284
- } else if (hasOppositeExpressions(nonTrivialExpression)) {
285
- return constant(true);
286
- } else {
287
- return {
288
- _type: "Set",
289
- operator: "||",
290
- operands: nonTrivialExpression
291
- };
292
- }
293
- }
294
-
295
- /**
296
- * Logical `not` operator.
297
- *
298
- * @param operand The expression to reverse
299
- * @returns The resulting expression that evaluates to boolean
300
- */
301
- _exports.or = or;
302
- function not(operand) {
303
- operand = wrapPrimitive(operand);
304
- if (hasUnresolvableExpression(operand)) {
305
- return unresolvableExpression;
306
- } else if (isConstant(operand)) {
307
- return constant(!operand.value);
308
- } else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "||" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
309
- return and(...operand.operands.map(expression => not(expression)));
310
- } else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "&&" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
311
- return or(...operand.operands.map(expression => not(expression)));
312
- } else if (isComparison(operand)) {
313
- // Create the reverse comparison
314
- switch (operand.operator) {
315
- case "!==":
316
- return {
317
- ...operand,
318
- operator: "==="
319
- };
320
- case "<":
321
- return {
322
- ...operand,
323
- operator: ">="
324
- };
325
- case "<=":
326
- return {
327
- ...operand,
328
- operator: ">"
329
- };
330
- case "===":
331
- return {
332
- ...operand,
333
- operator: "!=="
334
- };
335
- case ">":
336
- return {
337
- ...operand,
338
- operator: "<="
339
- };
340
- case ">=":
341
- return {
342
- ...operand,
343
- operator: "<"
344
- };
345
- }
346
- } else if (operand._type === "Not") {
347
- return operand.operand;
348
- }
349
- return {
350
- _type: "Not",
351
- operand: operand
352
- };
353
- }
354
-
355
- /**
356
- * Evaluates whether a binding expression is equal to true with a loose equality.
357
- *
358
- * @param operand The expression to check
359
- * @returns The resulting expression that evaluates to boolean
360
- */
361
- _exports.not = not;
362
- function isTruthy(operand) {
363
- if (isConstant(operand)) {
364
- return constant(!!operand.value);
365
- } else {
366
- return {
367
- _type: "Truthy",
368
- operand: operand
369
- };
370
- }
371
- }
372
-
373
- /**
374
- * Creates a binding expression that will be evaluated by the corresponding model.
375
- *
376
- * @param path
377
- * @param modelName
378
- * @param visitedNavigationPaths
379
- * @param pathVisitor
380
- * @returns An expression representating that path in the model
381
- * @deprecated use pathInModel instead
382
- */
383
- _exports.isTruthy = isTruthy;
384
- function bindingExpression(path, modelName) {
385
- let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
386
- let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
387
- return pathInModel(path, modelName, visitedNavigationPaths, pathVisitor);
388
- }
389
-
390
- /**
391
- * Creates a binding expression that will be evaluated by the corresponding model.
392
- *
393
- * @template TargetType
394
- * @param path The path on the model
395
- * @param [modelName] The name of the model
396
- * @param [visitedNavigationPaths] The paths from the root entitySet
397
- * @param [pathVisitor] A function to modify the resulting path
398
- * @returns An expression representating that path in the model
399
- */
400
- _exports.bindingExpression = bindingExpression;
401
- function pathInModel(path, modelName) {
402
- let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
403
- let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
404
- if (path === undefined) {
405
- return unresolvableExpression;
406
- }
407
- let targetPath;
408
- if (pathVisitor) {
409
- targetPath = pathVisitor(path);
410
- if (targetPath === undefined) {
411
- return unresolvableExpression;
412
- }
413
- } else {
414
- const localPath = visitedNavigationPaths.concat();
415
- localPath.push(path);
416
- targetPath = localPath.join("/");
417
- }
418
- return {
419
- _type: "PathInModel",
420
- modelName: modelName,
421
- path: targetPath
422
- };
423
- }
424
- _exports.pathInModel = pathInModel;
425
- /**
426
- * Creates a constant expression based on a primitive value.
427
- *
428
- * @template T
429
- * @param value The constant to wrap in an expression
430
- * @returns The constant expression
431
- */
432
- function constant(value) {
433
- let constantValue;
434
- if (typeof value === "object" && value !== null && value !== undefined) {
435
- if (Array.isArray(value)) {
436
- constantValue = value.map(wrapPrimitive);
437
- } else if (isPrimitiveObject(value)) {
438
- constantValue = value.valueOf();
439
- } else {
440
- constantValue = Object.entries(value).reduce((plainExpression, _ref) => {
441
- let [key, val] = _ref;
442
- const wrappedValue = wrapPrimitive(val);
443
- if (wrappedValue._type !== "Constant" || wrappedValue.value !== undefined) {
444
- plainExpression[key] = wrappedValue;
445
- }
446
- return plainExpression;
447
- }, {});
448
- }
449
- } else {
450
- constantValue = value;
451
- }
452
- return {
453
- _type: "Constant",
454
- value: constantValue
455
- };
456
- }
457
- _exports.constant = constant;
458
- function resolveBindingString(value, targetType) {
459
- if (value !== undefined && typeof value === "string" && value.startsWith("{")) {
460
- const pathInModelRegex = /^{(.*)>(.+)}$/; // Matches model paths like "model>path" or ">path" (default model)
461
- const pathInModelRegexMatch = pathInModelRegex.exec(value);
462
- if (value.startsWith("{=")) {
463
- // Expression binding, we can just remove the outer binding things
464
- return {
465
- _type: "EmbeddedExpressionBinding",
466
- value: value
467
- };
468
- } else if (pathInModelRegexMatch) {
469
- return pathInModel(pathInModelRegexMatch[2] || "", pathInModelRegexMatch[1] || undefined);
470
- } else {
471
- return {
472
- _type: "EmbeddedBinding",
473
- value: value
474
- };
475
- }
476
- } else if (targetType === "boolean" && typeof value === "string" && (value === "true" || value === "false")) {
477
- return constant(value === "true");
478
- } else if (targetType === "number" && typeof value === "string" && (!isNaN(Number(value)) || value === "NaN")) {
479
- return constant(Number(value));
480
- } else {
481
- return constant(value);
482
- }
483
- }
484
-
485
- /**
486
- * A named reference.
487
- *
488
- * @see fn
489
- * @param reference Reference
490
- * @returns The object reference binding part
491
- */
492
- _exports.resolveBindingString = resolveBindingString;
493
- function ref(reference) {
494
- return {
495
- _type: "Ref",
496
- ref: reference
497
- };
498
- }
499
-
500
- /**
501
- * Wrap a primitive into a constant expression if it is not already an expression.
502
- *
503
- * @template T
504
- * @param something The object to wrap in a Constant expression
505
- * @returns Either the original object or the wrapped one depending on the case
506
- */
507
- _exports.ref = ref;
508
- function wrapPrimitive(something) {
509
- if (isBindingToolkitExpression(something)) {
510
- return something;
511
- }
512
- return constant(something);
513
- }
514
-
515
- /**
516
- * Checks if the expression or value provided is a binding tooling expression or not.
517
- *
518
- * Every object having a property named `_type` of some value is considered an expression, even if there is actually
519
- * no such expression type supported.
520
- *
521
- * @param expression
522
- * @returns `true` if the expression is a binding toolkit expression
523
- */
524
- _exports.wrapPrimitive = wrapPrimitive;
525
- function isBindingToolkitExpression(expression) {
526
- return (expression === null || expression === void 0 ? void 0 : expression._type) !== undefined;
527
- }
528
-
529
- /**
530
- * Checks if the expression or value provided is constant or not.
531
- *
532
- * @template T The target type
533
- * @param maybeConstant The expression or primitive value that is to be checked
534
- * @returns `true` if it is constant
535
- */
536
- _exports.isBindingToolkitExpression = isBindingToolkitExpression;
537
- function isConstant(maybeConstant) {
538
- return typeof maybeConstant !== "object" || maybeConstant._type === "Constant";
539
- }
540
- _exports.isConstant = isConstant;
541
- function isTrue(expression) {
542
- return isConstant(expression) && expression.value === true;
543
- }
544
- function isFalse(expression) {
545
- return isConstant(expression) && expression.value === false;
546
- }
547
-
548
- /**
549
- * Checks if the expression or value provided is a path in model expression or not.
550
- *
551
- * @template T The target type
552
- * @param maybeBinding The expression or primitive value that is to be checked
553
- * @returns `true` if it is a path in model expression
554
- */
555
- function isPathInModelExpression(maybeBinding) {
556
- return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "PathInModel";
557
- }
558
-
559
- /**
560
- * Checks if the expression or value provided is a complex type expression.
561
- *
562
- * @template T The target type
563
- * @param maybeBinding The expression or primitive value that is to be checked
564
- * @returns `true` if it is a path in model expression
565
- */
566
- _exports.isPathInModelExpression = isPathInModelExpression;
567
- function isComplexTypeExpression(maybeBinding) {
568
- return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "ComplexType";
569
- }
570
-
571
- /**
572
- * Checks if the expression or value provided is a concat expression or not.
573
- *
574
- * @param expression
575
- * @returns `true` if the expression is a ConcatExpression
576
- */
577
- _exports.isComplexTypeExpression = isComplexTypeExpression;
578
- function isConcatExpression(expression) {
579
- return (expression === null || expression === void 0 ? void 0 : expression._type) === "Concat";
580
- }
581
-
582
- /**
583
- * Checks if the expression or value provided is a IfElse expression or not.
584
- *
585
- * @param expression
586
- * @returns `true` if the expression is a IfElseExpression
587
- */
588
- function isIfElseExpression(expression) {
589
- return (expression === null || expression === void 0 ? void 0 : expression._type) === "IfElse";
590
- }
591
-
592
- /**
593
- * Checks if the expression provided is a comparison or not.
594
- *
595
- * @template T The target type
596
- * @param expression The expression
597
- * @returns `true` if the expression is a ComparisonExpression
598
- */
599
- function isComparison(expression) {
600
- return expression._type === "Comparison";
601
- }
602
-
603
- /**
604
- * Checks whether the input parameter is a constant expression of type undefined.
605
- *
606
- * @param expression The input expression or object in general
607
- * @returns `true` if the input is constant which has undefined for value
608
- */
609
- function isUndefinedExpression(expression) {
610
- const expressionAsExpression = expression;
611
- return (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression._type) === "Constant" && (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression.value) === undefined;
612
- }
613
- _exports.isUndefinedExpression = isUndefinedExpression;
614
- function isPrimitiveObject(objectType) {
615
- switch (objectType.constructor.name) {
616
- case "String":
617
- case "Number":
618
- case "Boolean":
619
- return true;
620
- default:
621
- return false;
622
- }
623
- }
624
- /**
625
- * Check if the passed annotation annotationValue is a ComplexAnnotationExpression.
626
- *
627
- * @template T The target type
628
- * @param annotationValue The annotation annotationValue to evaluate
629
- * @returns `true` if the object is a {ComplexAnnotationExpression}
630
- */
631
- function isComplexAnnotationExpression(annotationValue) {
632
- return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue);
633
- }
634
-
635
- /**
636
- * Generate the corresponding annotationValue for a given annotation annotationValue.
637
- *
638
- * @template T The target type
639
- * @param annotationValue The source annotation annotationValue
640
- * @param visitedNavigationPaths The path from the root entity set
641
- * @param defaultValue Default value if the annotationValue is undefined
642
- * @param pathVisitor A function to modify the resulting path
643
- * @returns The annotationValue equivalent to that annotation annotationValue
644
- */
645
- function getExpressionFromAnnotation(annotationValue) {
646
- var _annotationValue;
647
- let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
648
- let defaultValue = arguments.length > 2 ? arguments[2] : undefined;
649
- let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
650
- if (annotationValue === undefined) {
651
- return wrapPrimitive(defaultValue);
652
- }
653
- annotationValue = (_annotationValue = annotationValue) === null || _annotationValue === void 0 ? void 0 : _annotationValue.valueOf();
654
- if (!isComplexAnnotationExpression(annotationValue)) {
655
- return constant(annotationValue);
656
- }
657
- switch (annotationValue.type) {
658
- case "Path":
659
- return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
660
- case "If":
661
- return annotationIfExpression(annotationValue.If, visitedNavigationPaths, pathVisitor);
662
- case "Not":
663
- return not(parseAnnotationCondition(annotationValue.Not, visitedNavigationPaths, pathVisitor));
664
- case "Eq":
665
- return equal(parseAnnotationCondition(annotationValue.Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Eq[1], visitedNavigationPaths, pathVisitor));
666
- case "Ne":
667
- return notEqual(parseAnnotationCondition(annotationValue.Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ne[1], visitedNavigationPaths, pathVisitor));
668
- case "Gt":
669
- return greaterThan(parseAnnotationCondition(annotationValue.Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Gt[1], visitedNavigationPaths, pathVisitor));
670
- case "Ge":
671
- return greaterOrEqual(parseAnnotationCondition(annotationValue.Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ge[1], visitedNavigationPaths, pathVisitor));
672
- case "Lt":
673
- return lessThan(parseAnnotationCondition(annotationValue.Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Lt[1], visitedNavigationPaths, pathVisitor));
674
- case "Le":
675
- return lessOrEqual(parseAnnotationCondition(annotationValue.Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Le[1], visitedNavigationPaths, pathVisitor));
676
- case "Or":
677
- return or(...annotationValue.Or.map(function (orCondition) {
678
- return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
679
- }));
680
- case "And":
681
- return and(...annotationValue.And.map(function (andCondition) {
682
- return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
683
- }));
684
- case "Apply":
685
- return annotationApplyExpression(annotationValue, visitedNavigationPaths, pathVisitor);
686
- }
687
- return unresolvableExpression;
688
- }
689
-
690
- /**
691
- * Parse the annotation condition into an expression.
692
- *
693
- * @template T The target type
694
- * @param annotationValue The condition or value from the annotation
695
- * @param visitedNavigationPaths The path from the root entity set
696
- * @param pathVisitor A function to modify the resulting path
697
- * @returns An equivalent expression
698
- */
699
- _exports.getExpressionFromAnnotation = getExpressionFromAnnotation;
700
- function parseAnnotationCondition(annotationValue) {
701
- let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
702
- let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
703
- if (annotationValue === null || typeof annotationValue !== "object") {
704
- return constant(annotationValue);
705
- } else if (annotationValue.hasOwnProperty("$Or")) {
706
- return or(...annotationValue.$Or.map(function (orCondition) {
707
- return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
708
- }));
709
- } else if (annotationValue.hasOwnProperty("$And")) {
710
- return and(...annotationValue.$And.map(function (andCondition) {
711
- return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
712
- }));
713
- } else if (annotationValue.hasOwnProperty("$Not")) {
714
- return not(parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor));
715
- } else if (annotationValue.hasOwnProperty("$Eq")) {
716
- return equal(parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor));
717
- } else if (annotationValue.hasOwnProperty("$Ne")) {
718
- return notEqual(parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor));
719
- } else if (annotationValue.hasOwnProperty("$Gt")) {
720
- return greaterThan(parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor));
721
- } else if (annotationValue.hasOwnProperty("$Ge")) {
722
- return greaterOrEqual(parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor));
723
- } else if (annotationValue.hasOwnProperty("$Lt")) {
724
- return lessThan(parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor));
725
- } else if (annotationValue.hasOwnProperty("$Le")) {
726
- return lessOrEqual(parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor));
727
- } else if (annotationValue.hasOwnProperty("$Path")) {
728
- return pathInModel(annotationValue.$Path, undefined, visitedNavigationPaths, pathVisitor);
729
- } else if (annotationValue.hasOwnProperty("$Apply")) {
730
- return getExpressionFromAnnotation({
731
- type: "Apply",
732
- Function: annotationValue.$Function,
733
- Apply: annotationValue.$Apply
734
- }, visitedNavigationPaths, undefined, pathVisitor);
735
- } else if (annotationValue.hasOwnProperty("$If")) {
736
- return getExpressionFromAnnotation({
737
- type: "If",
738
- If: annotationValue.$If
739
- }, visitedNavigationPaths, undefined, pathVisitor);
740
- } else if (annotationValue.hasOwnProperty("$EnumMember")) {
741
- return constant(resolveEnumValue(annotationValue.$EnumMember));
742
- }
743
- return constant(false);
744
- }
745
-
746
- /**
747
- * Process the {IfAnnotationExpressionValue} into an expression.
748
- *
749
- * @template T The target type
750
- * @param annotationValue An If expression returning the type T
751
- * @param visitedNavigationPaths The path from the root entity set
752
- * @param pathVisitor A function to modify the resulting path
753
- * @returns The equivalent ifElse expression
754
- */
755
- function annotationIfExpression(annotationValue) {
756
- let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
757
- let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
758
- return ifElse(parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[1], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[2], visitedNavigationPaths, pathVisitor));
759
- }
760
- // This type is not recursively transformed from the metamodel content, as such we have some ugly things there
761
- _exports.annotationIfExpression = annotationIfExpression;
762
- function convertSubApplyParameters(applyParam) {
763
- let applyParamConverted = applyParam;
764
- if (applyParam.hasOwnProperty("$Path")) {
765
- applyParamConverted = {
766
- type: "Path",
767
- path: applyParam.$Path
768
- };
769
- } else if (applyParam.hasOwnProperty("$If")) {
770
- applyParamConverted = {
771
- type: "If",
772
- If: applyParam.$If
773
- };
774
- } else if (applyParam.hasOwnProperty("$Apply")) {
775
- applyParamConverted = {
776
- type: "Apply",
777
- Function: applyParam.$Function,
778
- Apply: applyParam.$Apply
779
- };
780
- }
781
- return applyParamConverted;
782
- }
783
- function annotationApplyExpression(applyExpression) {
784
- let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
785
- let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
786
- switch (applyExpression.Function) {
787
- case "odata.concat":
788
- return concat(...applyExpression.Apply.map(applyParam => {
789
- return getExpressionFromAnnotation(convertSubApplyParameters(applyParam), visitedNavigationPaths, undefined, pathVisitor);
790
- }));
791
- case "odata.uriEncode":
792
- const parameter = getExpressionFromAnnotation(convertSubApplyParameters(applyExpression.Apply[0]), visitedNavigationPaths, undefined, pathVisitor);
793
- // The second parameter for uriEncode is always a string since the target evaluation is against a formatValue call in ODataUtils which expect the target type as second parameter
794
- return fn("odata.uriEncode", [parameter, "Edm.String"], undefined, true);
795
- case "odata.fillUriTemplate":
796
- const template = applyExpression.Apply[0];
797
- const templateParams = applyExpression.Apply.slice(1);
798
- const targetObject = {};
799
- templateParams.forEach(applyParam => {
800
- targetObject[applyParam.$Name] = getExpressionFromAnnotation(convertSubApplyParameters(applyParam.$LabeledElement), visitedNavigationPaths, undefined, pathVisitor);
801
- });
802
- return fn("odata.fillUriTemplate", [template, targetObject], undefined, true);
803
- }
804
- return unresolvableExpression;
805
- }
806
-
807
- /**
808
- * Generic helper for the comparison operations (equal, notEqual, ...).
809
- *
810
- * @template T The target type
811
- * @param operator The operator to apply
812
- * @param leftOperand The operand on the left side of the operator
813
- * @param rightOperand The operand on the right side of the operator
814
- * @returns An expression representing the comparison
815
- */
816
- _exports.annotationApplyExpression = annotationApplyExpression;
817
- function comparison(operator, leftOperand, rightOperand) {
818
- const leftExpression = wrapPrimitive(leftOperand);
819
- const rightExpression = wrapPrimitive(rightOperand);
820
- if (hasUnresolvableExpression(leftExpression, rightExpression)) {
821
- return unresolvableExpression;
822
- }
823
- if (isConstant(leftExpression) && isConstant(rightExpression)) {
824
- switch (operator) {
825
- case "!==":
826
- return constant(leftExpression.value !== rightExpression.value);
827
- case "===":
828
- return constant(leftExpression.value === rightExpression.value);
829
- case "<":
830
- if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
831
- return constant(false);
832
- }
833
- return constant(leftExpression.value < rightExpression.value);
834
- case "<=":
835
- if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
836
- return constant(false);
837
- }
838
- return constant(leftExpression.value <= rightExpression.value);
839
- case ">":
840
- if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
841
- return constant(false);
842
- }
843
- return constant(leftExpression.value > rightExpression.value);
844
- case ">=":
845
- if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
846
- return constant(false);
847
- }
848
- return constant(leftExpression.value >= rightExpression.value);
849
- }
850
- } else {
851
- return {
852
- _type: "Comparison",
853
- operator: operator,
854
- operand1: leftExpression,
855
- operand2: rightExpression
856
- };
857
- }
858
- }
859
-
860
- /**
861
- * Generic helper for the length of an expression.
862
- *
863
- * @param expression The input expression pointing to an array
864
- * @param checkUndefined Is the array potentially undefined
865
- * @returns An expression representing the length
866
- */
867
- function length(expression) {
868
- let checkUndefined = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
869
- if (expression._type === "Unresolvable") {
870
- return expression;
871
- }
872
- if (!checkUndefined) {
873
- return {
874
- _type: "Length",
875
- pathInModel: expression
876
- };
877
- }
878
- return ifElse(equal(expression, undefined), -1, length(expression));
879
- }
880
-
881
- /**
882
- * Comparison: "equal" (===).
883
- *
884
- * @template T The target type
885
- * @param leftOperand The operand on the left side
886
- * @param rightOperand The operand on the right side of the comparison
887
- * @returns An expression representing the comparison
888
- */
889
- _exports.length = length;
890
- function equal(leftOperand, rightOperand) {
891
- const leftExpression = wrapPrimitive(leftOperand);
892
- const rightExpression = wrapPrimitive(rightOperand);
893
- if (hasUnresolvableExpression(leftExpression, rightExpression)) {
894
- return unresolvableExpression;
895
- }
896
- if (_checkExpressionsAreEqual(leftExpression, rightExpression)) {
897
- return constant(true);
898
- }
899
- function reduce(left, right) {
900
- if (left._type === "Comparison" && isTrue(right)) {
901
- // compare(a, b) === true ~~> compare(a, b)
902
- return left;
903
- } else if (left._type === "Comparison" && isFalse(right)) {
904
- // compare(a, b) === false ~~> !compare(a, b)
905
- return not(left);
906
- } else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onTrue, right)) {
907
- // (if (x) { a } else { b }) === a ~~> x || (b === a)
908
- return or(left.condition, equal(left.onFalse, right));
909
- } else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onFalse, right)) {
910
- // (if (x) { a } else { b }) === b ~~> !x || (a === b)
911
- return or(not(left.condition), equal(left.onTrue, right));
912
- } else if (left._type === "IfElse" && isConstant(left.onTrue) && isConstant(left.onFalse) && isConstant(right) && !_checkExpressionsAreEqual(left.onTrue, right) && !_checkExpressionsAreEqual(left.onFalse, right)) {
913
- return constant(false);
914
- }
915
- return undefined;
916
- }
917
-
918
- // exploit symmetry: a === b <~> b === a
919
- const reduced = reduce(leftExpression, rightExpression) ?? reduce(rightExpression, leftExpression);
920
- return reduced ?? comparison("===", leftExpression, rightExpression);
921
- }
922
-
923
- /**
924
- * Comparison: "not equal" (!==).
925
- *
926
- * @template T The target type
927
- * @param leftOperand The operand on the left side
928
- * @param rightOperand The operand on the right side of the comparison
929
- * @returns An expression representing the comparison
930
- */
931
- _exports.equal = equal;
932
- function notEqual(leftOperand, rightOperand) {
933
- return not(equal(leftOperand, rightOperand));
934
- }
935
-
936
- /**
937
- * Comparison: "greater or equal" (>=).
938
- *
939
- * @template T The target type
940
- * @param leftOperand The operand on the left side
941
- * @param rightOperand The operand on the right side of the comparison
942
- * @returns An expression representing the comparison
943
- */
944
- _exports.notEqual = notEqual;
945
- function greaterOrEqual(leftOperand, rightOperand) {
946
- return comparison(">=", leftOperand, rightOperand);
947
- }
948
-
949
- /**
950
- * Comparison: "greater than" (>).
951
- *
952
- * @template T The target type
953
- * @param leftOperand The operand on the left side
954
- * @param rightOperand The operand on the right side of the comparison
955
- * @returns An expression representing the comparison
956
- */
957
- _exports.greaterOrEqual = greaterOrEqual;
958
- function greaterThan(leftOperand, rightOperand) {
959
- return comparison(">", leftOperand, rightOperand);
960
- }
961
-
962
- /**
963
- * Comparison: "less or equal" (<=).
964
- *
965
- * @template T The target type
966
- * @param leftOperand The operand on the left side
967
- * @param rightOperand The operand on the right side of the comparison
968
- * @returns An expression representing the comparison
969
- */
970
- _exports.greaterThan = greaterThan;
971
- function lessOrEqual(leftOperand, rightOperand) {
972
- return comparison("<=", leftOperand, rightOperand);
973
- }
974
-
975
- /**
976
- * Comparison: "less than" (<).
977
- *
978
- * @template T The target type
979
- * @param leftOperand The operand on the left side
980
- * @param rightOperand The operand on the right side of the comparison
981
- * @returns An expression representing the comparison
982
- */
983
- _exports.lessOrEqual = lessOrEqual;
984
- function lessThan(leftOperand, rightOperand) {
985
- return comparison("<", leftOperand, rightOperand);
986
- }
987
-
988
- /**
989
- * If-then-else expression.
990
- *
991
- * Evaluates to onTrue if the condition evaluates to true, else evaluates to onFalse.
992
- *
993
- * @template T The target type
994
- * @param condition The condition to evaluate
995
- * @param onTrue Expression result if the condition evaluates to true
996
- * @param onFalse Expression result if the condition evaluates to false
997
- * @returns The expression that represents this conditional check
998
- */
999
- _exports.lessThan = lessThan;
1000
- function ifElse(condition, onTrue, onFalse) {
1001
- let conditionExpression = wrapPrimitive(condition);
1002
- let onTrueExpression = wrapPrimitive(onTrue);
1003
- let onFalseExpression = wrapPrimitive(onFalse);
1004
-
1005
- // swap branches if the condition is a negation
1006
- if (conditionExpression._type === "Not") {
1007
- // ifElse(not(X), a, b) --> ifElse(X, b, a)
1008
- [onTrueExpression, onFalseExpression] = [onFalseExpression, onTrueExpression];
1009
- conditionExpression = not(conditionExpression);
1010
- }
1011
-
1012
- // inline nested if-else expressions: onTrue branch
1013
- // ifElse(X, ifElse(X, a, b), c) ==> ifElse(X, a, c)
1014
- if (onTrueExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onTrueExpression.condition)) {
1015
- onTrueExpression = onTrueExpression.onTrue;
1016
- }
1017
-
1018
- // inline nested if-else expressions: onFalse branch
1019
- // ifElse(X, a, ifElse(X, b, c)) ==> ifElse(X, a, c)
1020
- if (onFalseExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onFalseExpression.condition)) {
1021
- onFalseExpression = onFalseExpression.onFalse;
1022
- }
1023
-
1024
- // (if true then a else b) ~~> a
1025
- // (if false then a else b) ~~> b
1026
- if (isConstant(conditionExpression)) {
1027
- return conditionExpression.value ? onTrueExpression : onFalseExpression;
1028
- }
1029
-
1030
- // if (isConstantBoolean(onTrueExpression) || isConstantBoolean(onFalseExpression)) {
1031
- // return or(and(condition, onTrueExpression as Expression<boolean>), and(not(condition), onFalseExpression as Expression<boolean>)) as Expression<T>
1032
- // }
1033
-
1034
- // (if X then a else a) ~~> a
1035
- if (_checkExpressionsAreEqual(onTrueExpression, onFalseExpression)) {
1036
- return onTrueExpression;
1037
- }
1038
-
1039
- // if X then a else false ~~> X && a
1040
- if (isFalse(onFalseExpression)) {
1041
- return and(conditionExpression, onTrueExpression);
1042
- }
1043
-
1044
- // if X then a else true ~~> !X || a
1045
- if (isTrue(onFalseExpression)) {
1046
- return or(not(conditionExpression), onTrueExpression);
1047
- }
1048
-
1049
- // if X then false else a ~~> !X && a
1050
- if (isFalse(onTrueExpression)) {
1051
- return and(not(conditionExpression), onFalseExpression);
1052
- }
1053
-
1054
- // if X then true else a ~~> X || a
1055
- if (isTrue(onTrueExpression)) {
1056
- return or(conditionExpression, onFalseExpression);
1057
- }
1058
- if (hasUnresolvableExpression(conditionExpression, onTrueExpression, onFalseExpression)) {
1059
- return unresolvableExpression;
1060
- }
1061
- if (isComplexTypeExpression(condition) || isComplexTypeExpression(onTrue) || isComplexTypeExpression(onFalse)) {
1062
- let pathIdx = 0;
1063
- const myIfElseExpression = formatResult([condition, onTrue, onFalse], "sap.fe.core.formatters.StandardFormatter#ifElse");
1064
- const allParts = [];
1065
- transformRecursively(myIfElseExpression, "PathInModel", constantPath => {
1066
- allParts.push(constantPath);
1067
- return pathInModel(`$${pathIdx++}`, "$");
1068
- }, true);
1069
- allParts.unshift(constant(JSON.stringify(myIfElseExpression)));
1070
- return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
1071
- }
1072
- return {
1073
- _type: "IfElse",
1074
- condition: conditionExpression,
1075
- onTrue: onTrueExpression,
1076
- onFalse: onFalseExpression
1077
- };
1078
- }
1079
-
1080
- /**
1081
- * Checks whether the current expression has a reference to the default model (undefined).
1082
- *
1083
- * @param expression The expression to evaluate
1084
- * @returns `true` if there is a reference to the default context
1085
- */
1086
- _exports.ifElse = ifElse;
1087
- function hasReferenceToDefaultContext(expression) {
1088
- switch (expression._type) {
1089
- case "Constant":
1090
- case "Formatter":
1091
- case "ComplexType":
1092
- return false;
1093
- case "Set":
1094
- return expression.operands.some(hasReferenceToDefaultContext);
1095
- case "PathInModel":
1096
- return expression.modelName === undefined;
1097
- case "Comparison":
1098
- return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
1099
- case "IfElse":
1100
- return hasReferenceToDefaultContext(expression.condition) || hasReferenceToDefaultContext(expression.onTrue) || hasReferenceToDefaultContext(expression.onFalse);
1101
- case "Not":
1102
- case "Truthy":
1103
- return hasReferenceToDefaultContext(expression.operand);
1104
- default:
1105
- return false;
1106
- }
1107
- }
1108
-
1109
- // This is one case where any does make sense...
1110
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1111
-
1112
- /**
1113
- * Calls a formatter function to process the parameters.
1114
- * If requireContext is set to true and no context is passed a default context will be added automatically.
1115
- *
1116
- * @template T
1117
- * @template U
1118
- * @param parameters The list of parameter that should match the type and number of the formatter function
1119
- * @param formatterFunction The function to call
1120
- * @param [contextEntityType] If no parameter refers to the context then we use this information to add a reference to the keys from the entity type.
1121
- * @param [ignoreComplexType] Whether to ignore the transgformation to the StandardFormatter or not
1122
- * @returns The corresponding expression
1123
- */
1124
- function formatResult(parameters, formatterFunction, contextEntityType) {
1125
- let ignoreComplexType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1126
- const parameterExpressions = parameters.map(wrapPrimitive);
1127
- if (hasUnresolvableExpression(...parameterExpressions)) {
1128
- return unresolvableExpression;
1129
- }
1130
- if (contextEntityType) {
1131
- // Otherwise, if the context is required and no context is provided make sure to add the default binding
1132
- if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1133
- contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
1134
- }
1135
- }
1136
- let functionName = "";
1137
- if (typeof formatterFunction === "string") {
1138
- functionName = formatterFunction;
1139
- } else {
1140
- functionName = formatterFunction.__functionName;
1141
- }
1142
- // FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
1143
- const [formatterClass, formatterName] = functionName.split("#");
1144
-
1145
- // In some case we also cannot call directly a function because of too complex input, in that case we need to convert to a simpler function call
1146
- if (!ignoreComplexType && (parameterExpressions.some(isComplexTypeExpression) || parameterExpressions.some(isConcatExpression) || parameterExpressions.some(isIfElseExpression))) {
1147
- let pathIdx = 0;
1148
- const myFormatExpression = formatResult(parameterExpressions, functionName, undefined, true);
1149
- const allParts = [];
1150
- transformRecursively(myFormatExpression, "PathInModel", constantPath => {
1151
- allParts.push(constantPath);
1152
- return pathInModel(`$${pathIdx++}`, "$");
1153
- }, true);
1154
- allParts.unshift(constant(JSON.stringify(myFormatExpression)));
1155
- return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
1156
- } else if (!!formatterName && formatterName.length > 0) {
1157
- parameterExpressions.unshift(constant(formatterName));
1158
- }
1159
- return {
1160
- _type: "Formatter",
1161
- fn: formatterClass,
1162
- parameters: parameterExpressions
1163
- };
1164
- }
1165
- _exports.formatResult = formatResult;
1166
- function setUpConstraints(targetMapping, property) {
1167
- var _targetMapping$constr, _targetMapping$constr2, _targetMapping$constr3, _targetMapping$constr4, _property$annotations, _property$annotations2, _targetMapping$constr5, _property$annotations5, _property$annotations6, _property$annotations9, _property$annotations10, _targetMapping$constr6, _targetMapping$constr7;
1168
- const constraints = {};
1169
- if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr = targetMapping.constraints) !== null && _targetMapping$constr !== void 0 && _targetMapping$constr.$Scale && property.scale !== undefined) {
1170
- constraints.scale = property.scale;
1171
- }
1172
- if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr2 = targetMapping.constraints) !== null && _targetMapping$constr2 !== void 0 && _targetMapping$constr2.$Precision && property.precision !== undefined) {
1173
- constraints.precision = property.precision;
1174
- }
1175
- if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr3 = targetMapping.constraints) !== null && _targetMapping$constr3 !== void 0 && _targetMapping$constr3.$MaxLength && property.maxLength !== undefined) {
1176
- constraints.maxLength = property.maxLength;
1177
- }
1178
- if (property.nullable === false) {
1179
- constraints.nullable = false;
1180
- }
1181
- if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr4 = targetMapping.constraints) !== null && _targetMapping$constr4 !== void 0 && _targetMapping$constr4["@Org.OData.Validation.V1.Minimum/$Decimal"] && !isNaN((_property$annotations = property.annotations) === null || _property$annotations === void 0 ? void 0 : (_property$annotations2 = _property$annotations.Validation) === null || _property$annotations2 === void 0 ? void 0 : _property$annotations2.Minimum)) {
1182
- var _property$annotations3, _property$annotations4;
1183
- constraints.minimum = `${(_property$annotations3 = property.annotations) === null || _property$annotations3 === void 0 ? void 0 : (_property$annotations4 = _property$annotations3.Validation) === null || _property$annotations4 === void 0 ? void 0 : _property$annotations4.Minimum}`;
1184
- }
1185
- if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr5 = targetMapping.constraints) !== null && _targetMapping$constr5 !== void 0 && _targetMapping$constr5["@Org.OData.Validation.V1.Maximum/$Decimal"] && !isNaN((_property$annotations5 = property.annotations) === null || _property$annotations5 === void 0 ? void 0 : (_property$annotations6 = _property$annotations5.Validation) === null || _property$annotations6 === void 0 ? void 0 : _property$annotations6.Maximum)) {
1186
- var _property$annotations7, _property$annotations8;
1187
- constraints.maximum = `${(_property$annotations7 = property.annotations) === null || _property$annotations7 === void 0 ? void 0 : (_property$annotations8 = _property$annotations7.Validation) === null || _property$annotations8 === void 0 ? void 0 : _property$annotations8.Maximum}`;
1188
- }
1189
- if ((_property$annotations9 = property.annotations) !== null && _property$annotations9 !== void 0 && (_property$annotations10 = _property$annotations9.Common) !== null && _property$annotations10 !== void 0 && _property$annotations10.IsDigitSequence && targetMapping.type === "sap.ui.model.odata.type.String" && targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr6 = targetMapping.constraints) !== null && _targetMapping$constr6 !== void 0 && _targetMapping$constr6["@com.sap.vocabularies.Common.v1.IsDigitSequence"]) {
1190
- constraints.isDigitSequence = true;
1191
- }
1192
- if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr7 = targetMapping.constraints) !== null && _targetMapping$constr7 !== void 0 && _targetMapping$constr7.$V4) {
1193
- constraints.V4 = true;
1194
- }
1195
- return constraints;
1196
- }
1197
-
1198
- /**
1199
- * Generates the binding expression for the property, and sets up the formatOptions and constraints.
1200
- *
1201
- * @param property The Property for which we are setting up the binding
1202
- * @param propertyBindingExpression The BindingExpression of the property above. Serves as the basis to which information can be added
1203
- * @param ignoreConstraints Ignore constraints of the property
1204
- * @returns The binding expression for the property with formatOptions and constraints
1205
- */
1206
- _exports.setUpConstraints = setUpConstraints;
1207
- function formatWithTypeInformation(property, propertyBindingExpression) {
1208
- var _outExpression$type, _outExpression$constr3, _outExpression$constr4;
1209
- let ignoreConstraints = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1210
- const outExpression = propertyBindingExpression;
1211
- if (property._type !== "Property" && property._type !== "ActionParameter") {
1212
- return outExpression;
1213
- }
1214
- const targetMapping = EDM_TYPE_MAPPING[property.type];
1215
- if (!targetMapping) {
1216
- return outExpression;
1217
- }
1218
- if (!outExpression.formatOptions) {
1219
- outExpression.formatOptions = {};
1220
- }
1221
- outExpression.constraints = {};
1222
- outExpression.type = targetMapping.type;
1223
- if (!ignoreConstraints) {
1224
- outExpression.constraints = setUpConstraints(targetMapping, property);
1225
- }
1226
- if ((outExpression === null || outExpression === void 0 ? void 0 : (_outExpression$type = outExpression.type) === null || _outExpression$type === void 0 ? void 0 : _outExpression$type.indexOf("sap.ui.model.odata.type.Int")) === 0 && (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) !== "sap.ui.model.odata.type.Int64" || (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) === "sap.ui.model.odata.type.Double") {
1227
- outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
1228
- parseAsString: false
1229
- });
1230
- }
1231
- if (outExpression.type === "sap.ui.model.odata.type.String" && isProperty(property)) {
1232
- var _outExpression$constr, _outExpression$constr2;
1233
- if (!((_outExpression$constr = outExpression.constraints) !== null && _outExpression$constr !== void 0 && _outExpression$constr.isDigitSequence) || ((_outExpression$constr2 = outExpression.constraints) === null || _outExpression$constr2 === void 0 ? void 0 : _outExpression$constr2.nullable) === false) {
1234
- outExpression.formatOptions.parseKeepsEmptyString = true;
1235
- }
1236
- const fiscalType = getFiscalType(property);
1237
- if (fiscalType) {
1238
- outExpression.formatOptions.fiscalType = fiscalType;
1239
- outExpression.type = "sap.fe.core.type.FiscalDate";
1240
- }
1241
- }
1242
- const typesSupportingParseEmptyValueToZero = ["sap.ui.model.odata.type.Int16", "sap.ui.model.odata.type.Int32", "sap.ui.model.odata.type.Int64", "sap.ui.model.odata.type.Single", "sap.ui.model.odata.type.Double", "sap.ui.model.odata.type.Decimal", "sap.ui.model.odata.type.Byte", "sap.ui.model.odata.type.SByte"];
1243
- if (((_outExpression$constr3 = outExpression.constraints) === null || _outExpression$constr3 === void 0 ? void 0 : _outExpression$constr3.nullable) === false && outExpression.type && typesSupportingParseEmptyValueToZero.includes(outExpression.type)) {
1244
- outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
1245
- parseEmptyValueToZero: true
1246
- });
1247
- }
1248
- if (((_outExpression$constr4 = outExpression.constraints) === null || _outExpression$constr4 === void 0 ? void 0 : _outExpression$constr4.nullable) !== false && (outExpression.type === "sap.ui.model.odata.type.Int64" || outExpression.type === "sap.ui.model.odata.type.Decimal")) {
1249
- outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
1250
- emptyString: ""
1251
- });
1252
- }
1253
- return outExpression;
1254
- }
1255
- _exports.formatWithTypeInformation = formatWithTypeInformation;
1256
- const getFiscalType = function (property) {
1257
- var _property$annotations11, _property$annotations12, _property$annotations13, _property$annotations14, _property$annotations15, _property$annotations16, _property$annotations17, _property$annotations18, _property$annotations19, _property$annotations20, _property$annotations21, _property$annotations22, _property$annotations23, _property$annotations24, _property$annotations25, _property$annotations26;
1258
- if ((_property$annotations11 = property.annotations) !== null && _property$annotations11 !== void 0 && (_property$annotations12 = _property$annotations11.Common) !== null && _property$annotations12 !== void 0 && _property$annotations12.IsFiscalYear) {
1259
- return "com.sap.vocabularies.Common.v1.IsFiscalYear";
1260
- }
1261
- if ((_property$annotations13 = property.annotations) !== null && _property$annotations13 !== void 0 && (_property$annotations14 = _property$annotations13.Common) !== null && _property$annotations14 !== void 0 && _property$annotations14.IsFiscalPeriod) {
1262
- return "com.sap.vocabularies.Common.v1.IsFiscalPeriod";
1263
- }
1264
- if ((_property$annotations15 = property.annotations) !== null && _property$annotations15 !== void 0 && (_property$annotations16 = _property$annotations15.Common) !== null && _property$annotations16 !== void 0 && _property$annotations16.IsFiscalYearPeriod) {
1265
- return "com.sap.vocabularies.Common.v1.IsFiscalYearPeriod";
1266
- }
1267
- if ((_property$annotations17 = property.annotations) !== null && _property$annotations17 !== void 0 && (_property$annotations18 = _property$annotations17.Common) !== null && _property$annotations18 !== void 0 && _property$annotations18.IsFiscalQuarter) {
1268
- return "com.sap.vocabularies.Common.v1.IsFiscalQuarter";
1269
- }
1270
- if ((_property$annotations19 = property.annotations) !== null && _property$annotations19 !== void 0 && (_property$annotations20 = _property$annotations19.Common) !== null && _property$annotations20 !== void 0 && _property$annotations20.IsFiscalYearQuarter) {
1271
- return "com.sap.vocabularies.Common.v1.IsFiscalYearQuarter";
1272
- }
1273
- if ((_property$annotations21 = property.annotations) !== null && _property$annotations21 !== void 0 && (_property$annotations22 = _property$annotations21.Common) !== null && _property$annotations22 !== void 0 && _property$annotations22.IsFiscalWeek) {
1274
- return "com.sap.vocabularies.Common.v1.IsFiscalWeek";
1275
- }
1276
- if ((_property$annotations23 = property.annotations) !== null && _property$annotations23 !== void 0 && (_property$annotations24 = _property$annotations23.Common) !== null && _property$annotations24 !== void 0 && _property$annotations24.IsFiscalYearWeek) {
1277
- return "com.sap.vocabularies.Common.v1.IsFiscalYearWeek";
1278
- }
1279
- if ((_property$annotations25 = property.annotations) !== null && _property$annotations25 !== void 0 && (_property$annotations26 = _property$annotations25.Common) !== null && _property$annotations26 !== void 0 && _property$annotations26.IsDayOfFiscalYear) {
1280
- return "com.sap.vocabularies.Common.v1.IsDayOfFiscalYear";
1281
- }
1282
- };
1283
-
1284
- /**
1285
- * Calls a complex type to process the parameters.
1286
- * If requireContext is set to true and no context is passed, a default context will be added automatically.
1287
- *
1288
- * @template T
1289
- * @template U
1290
- * @param parameters The list of parameters that should match the type for the complex type=
1291
- * @param type The complex type to use
1292
- * @param [contextEntityType] The context entity type to consider
1293
- * @param oFormatOptions
1294
- * @returns The corresponding expression
1295
- */
1296
- _exports.getFiscalType = getFiscalType;
1297
- function addTypeInformation(parameters, type, contextEntityType, oFormatOptions) {
1298
- const parameterExpressions = parameters.map(wrapPrimitive);
1299
- if (hasUnresolvableExpression(...parameterExpressions)) {
1300
- return unresolvableExpression;
1301
- }
1302
- // If there is only one parameter and it is a constant and we don't expect the context then return the constant
1303
- if (parameterExpressions.length === 1 && isConstant(parameterExpressions[0]) && !contextEntityType) {
1304
- return parameterExpressions[0];
1305
- } else if (contextEntityType) {
1306
- // Otherwise, if the context is required and no context is provided make sure to add the default binding
1307
- if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1308
- contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
1309
- }
1310
- }
1311
- oFormatOptions = _getComplexTypeFormatOptionsFromFirstParam(parameters[0], oFormatOptions);
1312
- if (type === "sap.ui.model.odata.type.Unit") {
1313
- const uomPath = pathInModel("/##@@requestUnitsOfMeasure");
1314
- uomPath.targetType = "any";
1315
- uomPath.mode = "OneTime";
1316
- parameterExpressions.push(uomPath);
1317
- } else if (type === "sap.ui.model.odata.type.Currency") {
1318
- const currencyPath = pathInModel("/##@@requestCurrencyCodes");
1319
- currencyPath.targetType = "any";
1320
- currencyPath.mode = "OneTime";
1321
- parameterExpressions.push(currencyPath);
1322
- }
1323
- return {
1324
- _type: "ComplexType",
1325
- type: type,
1326
- formatOptions: oFormatOptions || {},
1327
- parameters: {},
1328
- bindingParameters: parameterExpressions
1329
- };
1330
- }
1331
- _exports.addTypeInformation = addTypeInformation;
1332
- /**
1333
- * Process the formatOptions for a complexType based on the first parameter.
1334
- *
1335
- * @param param The first parameter of the complex type
1336
- * @param formatOptions Initial formatOptions
1337
- * @returns The modified formatOptions
1338
- */
1339
- function _getComplexTypeFormatOptionsFromFirstParam(param, formatOptions) {
1340
- var _param$type;
1341
- // if showMeasure is set to false we want to not parse as string to see the 0
1342
- // we do that also for all bindings because otherwise the mdc Field isn't editable
1343
- if (!(formatOptions && formatOptions.showNumber === false) && ((param === null || param === void 0 ? void 0 : (_param$type = param.type) === null || _param$type === void 0 ? void 0 : _param$type.indexOf("sap.ui.model.odata.type.Int")) === 0 || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Double")) {
1344
- if ((param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Int64" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal") {
1345
- var _formatOptions;
1346
- //sap.ui.model.odata.type.Int64 do not support parseAsString false
1347
- formatOptions = ((_formatOptions = formatOptions) === null || _formatOptions === void 0 ? void 0 : _formatOptions.showMeasure) === false ? {
1348
- showMeasure: false
1349
- } : {};
1350
- } else {
1351
- var _formatOptions2;
1352
- formatOptions = ((_formatOptions2 = formatOptions) === null || _formatOptions2 === void 0 ? void 0 : _formatOptions2.showMeasure) === false ? {
1353
- parseAsString: false,
1354
- showMeasure: false
1355
- } : {
1356
- parseAsString: false
1357
- };
1358
- }
1359
- formatOptions.emptyString = null;
1360
- }
1361
- return formatOptions;
1362
- }
1363
- /**
1364
- * Function call, optionally with arguments.
1365
- *
1366
- * @param func Function name or reference to function
1367
- * @param parameters Arguments
1368
- * @param on Object to call the function on
1369
- * @param isFormattingFn
1370
- * @returns Expression representing the function call (not the result of the function call!)
1371
- */
1372
- function fn(func, parameters, on) {
1373
- let isFormattingFn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1374
- const functionName = typeof func === "string" ? func : func.__functionName;
1375
- return {
1376
- _type: "Function",
1377
- obj: on !== undefined ? wrapPrimitive(on) : undefined,
1378
- fn: functionName,
1379
- isFormattingFn: isFormattingFn,
1380
- parameters: parameters.map(wrapPrimitive)
1381
- };
1382
- }
1383
-
1384
- /**
1385
- * Shortcut function to determine if a binding value is null, undefined or empty.
1386
- *
1387
- * @param expression
1388
- * @returns A Boolean expression evaluating the fact that the current element is empty
1389
- */
1390
- _exports.fn = fn;
1391
- function isEmpty(expression) {
1392
- const aBindings = [];
1393
- transformRecursively(expression, "PathInModel", expr => {
1394
- aBindings.push(or(equal(expr, ""), equal(expr, undefined), equal(expr, null)));
1395
- return expr;
1396
- });
1397
- return and(...aBindings);
1398
- }
1399
- _exports.isEmpty = isEmpty;
1400
- function concat() {
1401
- for (var _len4 = arguments.length, inExpressions = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
1402
- inExpressions[_key4] = arguments[_key4];
1403
- }
1404
- const expressions = inExpressions.map(wrapPrimitive);
1405
- if (hasUnresolvableExpression(...expressions)) {
1406
- return unresolvableExpression;
1407
- }
1408
- if (expressions.every(isConstant)) {
1409
- return constant(expressions.reduce((concatenated, value) => {
1410
- if (value.value !== undefined && value.value !== null) {
1411
- return concatenated + value.value.toString();
1412
- }
1413
- return concatenated;
1414
- }, ""));
1415
- } else if (expressions.some(isComplexTypeExpression)) {
1416
- let pathIdx = 0;
1417
- const myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat", undefined, true);
1418
- const allParts = [];
1419
- transformRecursively(myConcatExpression, "PathInModel", constantPath => {
1420
- allParts.push(constantPath);
1421
- return pathInModel(`$${pathIdx++}`, "$");
1422
- });
1423
- allParts.unshift(constant(JSON.stringify(myConcatExpression)));
1424
- return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
1425
- }
1426
- return {
1427
- _type: "Concat",
1428
- expressions: expressions
1429
- };
1430
- }
1431
- _exports.concat = concat;
1432
- function transformRecursively(inExpression, expressionType, transformFunction) {
1433
- let includeAllExpression = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1434
- let expression = inExpression;
1435
- switch (expression._type) {
1436
- case "Function":
1437
- case "Formatter":
1438
- expression.parameters = expression.parameters.map(parameter => transformRecursively(parameter, expressionType, transformFunction, includeAllExpression));
1439
- break;
1440
- case "Concat":
1441
- expression.expressions = expression.expressions.map(subExpression => transformRecursively(subExpression, expressionType, transformFunction, includeAllExpression));
1442
- expression = concat(...expression.expressions);
1443
- break;
1444
- case "ComplexType":
1445
- expression.bindingParameters = expression.bindingParameters.map(bindingParameter => transformRecursively(bindingParameter, expressionType, transformFunction, includeAllExpression));
1446
- break;
1447
- case "IfElse":
1448
- const onTrue = transformRecursively(expression.onTrue, expressionType, transformFunction, includeAllExpression);
1449
- const onFalse = transformRecursively(expression.onFalse, expressionType, transformFunction, includeAllExpression);
1450
- let condition = expression.condition;
1451
- if (includeAllExpression) {
1452
- condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
1453
- }
1454
- expression = ifElse(condition, onTrue, onFalse);
1455
- break;
1456
- case "Not":
1457
- if (includeAllExpression) {
1458
- const operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
1459
- expression = not(operand);
1460
- }
1461
- break;
1462
- case "Truthy":
1463
- break;
1464
- case "Set":
1465
- if (includeAllExpression) {
1466
- const operands = expression.operands.map(operand => transformRecursively(operand, expressionType, transformFunction, includeAllExpression));
1467
- expression = expression.operator === "||" ? or(...operands) : and(...operands);
1468
- }
1469
- break;
1470
- case "Comparison":
1471
- if (includeAllExpression) {
1472
- const operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
1473
- const operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
1474
- expression = comparison(expression.operator, operand1, operand2);
1475
- }
1476
- break;
1477
- case "Constant":
1478
- const constantValue = expression.value;
1479
- if (typeof constantValue === "object" && constantValue) {
1480
- Object.keys(constantValue).forEach(key => {
1481
- constantValue[key] = transformRecursively(constantValue[key], expressionType, transformFunction, includeAllExpression);
1482
- });
1483
- }
1484
- break;
1485
- case "Ref":
1486
- case "Length":
1487
- case "PathInModel":
1488
- case "EmbeddedBinding":
1489
- case "EmbeddedExpressionBinding":
1490
- case "Unresolvable":
1491
- // Do nothing
1492
- break;
1493
- }
1494
- if (expressionType === expression._type) {
1495
- expression = transformFunction(inExpression);
1496
- }
1497
- return expression;
1498
- }
1499
- _exports.transformRecursively = transformRecursively;
1500
- const needParenthesis = function (expr) {
1501
- return !isConstant(expr) && !isPathInModelExpression(expr) && isBindingToolkitExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
1502
- };
1503
-
1504
- /**
1505
- * Compiles a constant object to a string.
1506
- *
1507
- * @param expr
1508
- * @param isNullable
1509
- * @returns The compiled string
1510
- */
1511
- function compileConstantObject(expr) {
1512
- let isNullable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1513
- if (isNullable && Object.keys(expr.value).length === 0) {
1514
- return "";
1515
- }
1516
- const objects = expr.value;
1517
- const properties = [];
1518
- Object.keys(objects).forEach(key => {
1519
- const value = objects[key];
1520
- const childResult = compileExpression(value, true, false, isNullable);
1521
- if (childResult && childResult.length > 0) {
1522
- properties.push(`${key}: ${childResult}`);
1523
- }
1524
- });
1525
- return `{${properties.join(", ")}}`;
1526
- }
1527
-
1528
- /**
1529
- * Compiles a Constant Binding Expression.
1530
- *
1531
- * @param expr
1532
- * @param embeddedInBinding
1533
- * @param isNullable
1534
- * @param doNotStringify
1535
- * @returns The compiled string
1536
- */
1537
-
1538
- function compileConstant(expr, embeddedInBinding) {
1539
- let isNullable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1540
- let doNotStringify = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1541
- if (expr.value === null) {
1542
- return doNotStringify ? null : "null";
1543
- }
1544
- if (expr.value === undefined) {
1545
- return doNotStringify ? undefined : "undefined";
1546
- }
1547
- if (typeof expr.value === "object") {
1548
- if (Array.isArray(expr.value)) {
1549
- const entries = expr.value.map(expression => compileExpression(expression, true));
1550
- return `[${entries.join(", ")}]`;
1551
- } else {
1552
- return compileConstantObject(expr, isNullable);
1553
- }
1554
- }
1555
- if (embeddedInBinding) {
1556
- switch (typeof expr.value) {
1557
- case "number":
1558
- case "bigint":
1559
- case "boolean":
1560
- return expr.value.toString();
1561
- case "string":
1562
- return `'${escapeXmlAttribute(expr.value.toString())}'`;
1563
- default:
1564
- return "";
1565
- }
1566
- } else {
1567
- return doNotStringify ? expr.value : expr.value.toString();
1568
- }
1569
- }
1570
-
1571
- /**
1572
- * Generates the binding string for a Binding expression.
1573
- *
1574
- * @param expressionForBinding The expression to compile
1575
- * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1576
- * @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
1577
- * @returns The corresponding expression binding
1578
- */
1579
- _exports.compileConstant = compileConstant;
1580
- function compilePathInModelExpression(expressionForBinding, embeddedInBinding, embeddedSeparator) {
1581
- if (expressionForBinding.type || expressionForBinding.parameters || expressionForBinding.targetType || expressionForBinding.formatOptions || expressionForBinding.constraints) {
1582
- // This is now a complex binding definition, let's prepare for it
1583
- const complexBindingDefinition = {
1584
- path: compilePathInModel(expressionForBinding),
1585
- type: expressionForBinding.type,
1586
- targetType: expressionForBinding.targetType,
1587
- parameters: expressionForBinding.parameters,
1588
- formatOptions: expressionForBinding.formatOptions,
1589
- constraints: expressionForBinding.constraints
1590
- };
1591
- const outBinding = compileExpression(complexBindingDefinition, false, false, true);
1592
- if (embeddedInBinding) {
1593
- return `${embeddedSeparator}${outBinding}`;
1594
- }
1595
- return outBinding;
1596
- } else if (embeddedInBinding) {
1597
- return `${embeddedSeparator}{${compilePathInModel(expressionForBinding)}}`;
1598
- } else {
1599
- return `{${compilePathInModel(expressionForBinding)}}`;
1600
- }
1601
- }
1602
- function compileComplexTypeExpression(expression) {
1603
- if (expression.bindingParameters.length === 1) {
1604
- return `{${compilePathParameter(expression.bindingParameters[0], true)}, type: '${expression.type}'}`;
1605
- }
1606
- let outputEnd = `], type: '${expression.type}'`;
1607
- if (hasElements(expression.formatOptions)) {
1608
- outputEnd += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1609
- }
1610
- if (hasElements(expression.parameters)) {
1611
- outputEnd += `, parameters: ${compileExpression(expression.parameters)}`;
1612
- }
1613
- outputEnd += "}";
1614
- return `{mode:'TwoWay', parts:[${expression.bindingParameters.map(param => compilePathParameter(param)).join(",")}${outputEnd}`;
1615
- }
1616
-
1617
- /**
1618
- * Wrap the compiled binding string as required depending on its context.
1619
- *
1620
- * @param expression The compiled expression
1621
- * @param embeddedInBinding True if the compiled expression is to be embedded in a binding
1622
- * @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
1623
- * @returns Finalized compiled expression
1624
- */
1625
- function wrapBindingExpression(expression, embeddedInBinding) {
1626
- let parenthesisRequired = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1627
- if (embeddedInBinding) {
1628
- if (parenthesisRequired) {
1629
- return `(${expression})`;
1630
- } else {
1631
- return expression;
1632
- }
1633
- } else {
1634
- return `{= ${expression}}`;
1635
- }
1636
- }
1637
-
1638
- /**
1639
- * Compile an expression into an expression binding.
1640
- *
1641
- * @template T The target type
1642
- * @param expression The expression to compile
1643
- * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1644
- * @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
1645
- * @param isNullable Whether binding expression can resolve to empty string or not
1646
- * @returns The corresponding expression binding
1647
- */
1648
- _exports.wrapBindingExpression = wrapBindingExpression;
1649
- function compileExpression(expression) {
1650
- let embeddedInBinding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1651
- let keepTargetType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1652
- let isNullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1653
- const expr = wrapPrimitive(expression);
1654
- const embeddedSeparator = keepTargetType ? "$" : "%";
1655
- switch (expr._type) {
1656
- case "Unresolvable":
1657
- return undefined;
1658
- case "Constant":
1659
- return compileConstant(expr, embeddedInBinding, isNullable);
1660
- case "Ref":
1661
- return expr.ref || "null";
1662
- case "Function":
1663
- let hasEmbeddedFunctionCallOrBinding = false;
1664
- if (expr.isFormattingFn) {
1665
- transformRecursively(expr, "Function", subFn => {
1666
- if (subFn !== expr && subFn.obj === undefined) {
1667
- hasEmbeddedFunctionCallOrBinding = true;
1668
- }
1669
- return subFn;
1670
- }, true);
1671
- transformRecursively(expr, "Constant", subFn => {
1672
- if (subFn !== expr && typeof subFn.value === "object") {
1673
- transformRecursively(subFn, "PathInModel", subSubFn => {
1674
- hasEmbeddedFunctionCallOrBinding = true;
1675
- return subSubFn;
1676
- });
1677
- }
1678
- return subFn;
1679
- }, true);
1680
- }
1681
- const argumentString = `${expr.parameters.map(arg => compileExpression(arg, true)).join(", ")}`;
1682
- let fnCall = expr.obj === undefined ? `${expr.fn}(${argumentString})` : `${compileExpression(expr.obj, true)}.${expr.fn}(${argumentString})`;
1683
- if (!embeddedInBinding && hasEmbeddedFunctionCallOrBinding) {
1684
- fnCall = `{= ${fnCall}}`;
1685
- }
1686
- return fnCall;
1687
- case "EmbeddedExpressionBinding":
1688
- return embeddedInBinding ? `(${expr.value.substring(2, expr.value.length - 1)})` : `${expr.value}`;
1689
- case "EmbeddedBinding":
1690
- return embeddedInBinding ? `${embeddedSeparator}${expr.value}` : `${expr.value}`;
1691
- case "PathInModel":
1692
- return compilePathInModelExpression(expr, embeddedInBinding, embeddedSeparator);
1693
- case "Comparison":
1694
- const comparisonExpression = compileComparisonExpression(expr);
1695
- return wrapBindingExpression(comparisonExpression, embeddedInBinding);
1696
- case "IfElse":
1697
- const ifElseExpression = `${compileExpression(expr.condition, true)} ? ${compileExpression(expr.onTrue, true, keepTargetType)} : ${compileExpression(expr.onFalse, true, keepTargetType)}`;
1698
- return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
1699
- case "Set":
1700
- const setExpression = expr.operands.map(operand => compileExpression(operand, true)).join(` ${expr.operator} `);
1701
- return wrapBindingExpression(setExpression, embeddedInBinding, true);
1702
- case "Concat":
1703
- const concatExpression = expr.expressions.map(nestedExpression => compileExpression(nestedExpression, true, true)).join(" + ");
1704
- return wrapBindingExpression(concatExpression, embeddedInBinding);
1705
- case "Length":
1706
- const lengthExpression = `${compileExpression(expr.pathInModel, true)}.length`;
1707
- return wrapBindingExpression(lengthExpression, embeddedInBinding);
1708
- case "Not":
1709
- const notExpression = `!${compileExpression(expr.operand, true)}`;
1710
- return wrapBindingExpression(notExpression, embeddedInBinding);
1711
- case "Truthy":
1712
- const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
1713
- return wrapBindingExpression(truthyExpression, embeddedInBinding);
1714
- case "Formatter":
1715
- const formatterExpression = compileFormatterExpression(expr);
1716
- return embeddedInBinding ? `$${formatterExpression}` : formatterExpression;
1717
- case "ComplexType":
1718
- const complexTypeExpression = compileComplexTypeExpression(expr);
1719
- return embeddedInBinding ? `$${complexTypeExpression}` : complexTypeExpression;
1720
- default:
1721
- return "";
1722
- }
1723
- }
1724
-
1725
- /**
1726
- * Compile a comparison expression.
1727
- *
1728
- * @param expression The comparison expression.
1729
- * @returns The compiled expression. Needs wrapping before it can be used as an expression binding.
1730
- */
1731
- _exports.compileExpression = compileExpression;
1732
- function compileComparisonExpression(expression) {
1733
- function compileOperand(operand) {
1734
- const compiledOperand = compileExpression(operand, true) ?? "undefined";
1735
- return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
1736
- }
1737
- return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
1738
- }
1739
-
1740
- /**
1741
- * Compile a formatter expression.
1742
- *
1743
- * @param expression The formatter expression.
1744
- * @returns The compiled expression.
1745
- */
1746
- function compileFormatterExpression(expression) {
1747
- if (expression.parameters.length === 1) {
1748
- return `{${compilePathParameter(expression.parameters[0], true)}, formatter: '${expression.fn}'}`;
1749
- } else {
1750
- const parts = expression.parameters.map(param => {
1751
- if (param._type === "ComplexType") {
1752
- return compileComplexTypeExpression(param);
1753
- } else {
1754
- return compilePathParameter(param);
1755
- }
1756
- });
1757
- return `{parts: [${parts.join(", ")}], formatter: '${expression.fn}'}`;
1758
- }
1759
- }
1760
-
1761
- /**
1762
- * Compile the path parameter of a formatter call.
1763
- *
1764
- * @param expression The binding part to evaluate
1765
- * @param singlePath Whether there is one or multiple path to consider
1766
- * @returns The string snippet to include in the overall binding definition
1767
- */
1768
- function compilePathParameter(expression) {
1769
- let singlePath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1770
- let outValue = "";
1771
- if (expression._type === "Constant") {
1772
- if (expression.value === undefined) {
1773
- // Special case otherwise the JSTokenizer complains about incorrect content
1774
- outValue = `value: 'undefined'`;
1775
- } else {
1776
- outValue = `value: ${compileConstant(expression, true)}`;
1777
- }
1778
- } else if (expression._type === "PathInModel") {
1779
- outValue = `path: '${compilePathInModel(expression)}'`;
1780
- outValue += expression.type ? `, type: '${expression.type}'` : `, targetType: 'any'`;
1781
- if (expression.mode) {
1782
- outValue += `, mode: '${compileExpression(expression.mode)}'`;
1783
- }
1784
- if (hasElements(expression.constraints)) {
1785
- outValue += `, constraints: ${compileExpression(expression.constraints)}`;
1786
- }
1787
- if (hasElements(expression.formatOptions)) {
1788
- outValue += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1789
- }
1790
- if (hasElements(expression.parameters)) {
1791
- outValue += `, parameters: ${compileExpression(expression.parameters)}`;
1792
- }
1793
- } else {
1794
- return "";
1795
- }
1796
- return singlePath ? outValue : `{${outValue}}`;
1797
- }
1798
- function hasElements(obj) {
1799
- return !!obj && Object.keys(obj).length > 0;
1800
- }
1801
-
1802
- /**
1803
- * Compile a binding expression path.
1804
- *
1805
- * @param expression The expression to compile.
1806
- * @returns The compiled path.
1807
- */
1808
- function compilePathInModel(expression) {
1809
- return `${expression.modelName ? expression.modelName + ">" : ""}${expression.path}`;
1810
- }
1811
- return _exports;
1812
- }, false);
1813
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFRE1fVFlQRV9NQVBQSU5HIiwidHlwZSIsImNvbnN0cmFpbnRzIiwiJFByZWNpc2lvbiIsIiRWNCIsIiRTY2FsZSIsIiRNYXhMZW5ndGgiLCIkTnVsbGFibGUiLCJ1bnJlc29sdmFibGVFeHByZXNzaW9uIiwiX3R5cGUiLCJlc2NhcGVYbWxBdHRyaWJ1dGUiLCJpbnB1dFN0cmluZyIsInJlcGxhY2UiLCJoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uIiwiZXhwcmVzc2lvbnMiLCJmaW5kIiwiZXhwciIsInVuZGVmaW5lZCIsIl9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwiLCJhIiwiYiIsInZhbHVlIiwib3BlcmFuZCIsIm9wZXJhdG9yIiwib3BlcmFuZHMiLCJsZW5ndGgiLCJldmVyeSIsImV4cHJlc3Npb24iLCJzb21lIiwib3RoZXJFeHByZXNzaW9uIiwiY29uZGl0aW9uIiwib25UcnVlIiwib25GYWxzZSIsIm9wZXJhbmQxIiwib3BlcmFuZDIiLCJhRXhwcmVzc2lvbnMiLCJiRXhwcmVzc2lvbnMiLCJpbmRleCIsInBhdGhJbk1vZGVsIiwibW9kZWxOYW1lIiwicGF0aCIsInRhcmdldEVudGl0eVNldCIsImZuIiwicGFyYW1ldGVycyIsImJpbmRpbmdQYXJhbWV0ZXJzIiwib3RoZXJGdW5jdGlvbiIsIm9iaiIsInJlZiIsImZsYXR0ZW5TZXRFeHByZXNzaW9uIiwicmVkdWNlIiwicmVzdWx0IiwiY2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmciLCJmb3JFYWNoIiwiY2FuZGlkYXRlIiwiZSIsInB1c2giLCJoYXNPcHBvc2l0ZUV4cHJlc3Npb25zIiwibmVnYXRlZEV4cHJlc3Npb25zIiwibWFwIiwibm90IiwiaSIsImFuZCIsIndyYXBQcmltaXRpdmUiLCJpc1N0YXRpY0ZhbHNlIiwibm9uVHJpdmlhbEV4cHJlc3Npb24iLCJmaWx0ZXIiLCJpc0ZhbHNlIiwiaXNDb25zdGFudCIsImNvbnN0YW50IiwiaXNWYWxpZCIsImlzVHJ1ZSIsIm9yIiwiaXNTdGF0aWNUcnVlIiwiaXNDb21wYXJpc29uIiwiaXNUcnV0aHkiLCJiaW5kaW5nRXhwcmVzc2lvbiIsInZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMiLCJwYXRoVmlzaXRvciIsInRhcmdldFBhdGgiLCJsb2NhbFBhdGgiLCJjb25jYXQiLCJqb2luIiwiY29uc3RhbnRWYWx1ZSIsIkFycmF5IiwiaXNBcnJheSIsImlzUHJpbWl0aXZlT2JqZWN0IiwidmFsdWVPZiIsIk9iamVjdCIsImVudHJpZXMiLCJwbGFpbkV4cHJlc3Npb24iLCJrZXkiLCJ2YWwiLCJ3cmFwcGVkVmFsdWUiLCJyZXNvbHZlQmluZGluZ1N0cmluZyIsInRhcmdldFR5cGUiLCJzdGFydHNXaXRoIiwicGF0aEluTW9kZWxSZWdleCIsInBhdGhJbk1vZGVsUmVnZXhNYXRjaCIsImV4ZWMiLCJpc05hTiIsIk51bWJlciIsInJlZmVyZW5jZSIsInNvbWV0aGluZyIsImlzQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIiwibWF5YmVDb25zdGFudCIsImlzUGF0aEluTW9kZWxFeHByZXNzaW9uIiwibWF5YmVCaW5kaW5nIiwiaXNDb21wbGV4VHlwZUV4cHJlc3Npb24iLCJpc0NvbmNhdEV4cHJlc3Npb24iLCJpc0lmRWxzZUV4cHJlc3Npb24iLCJpc1VuZGVmaW5lZEV4cHJlc3Npb24iLCJleHByZXNzaW9uQXNFeHByZXNzaW9uIiwib2JqZWN0VHlwZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsImlzQ29tcGxleEFubm90YXRpb25FeHByZXNzaW9uIiwiYW5ub3RhdGlvblZhbHVlIiwiZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uIiwiZGVmYXVsdFZhbHVlIiwiYW5ub3RhdGlvbklmRXhwcmVzc2lvbiIsIklmIiwicGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uIiwiTm90IiwiZXF1YWwiLCJFcSIsIm5vdEVxdWFsIiwiTmUiLCJncmVhdGVyVGhhbiIsIkd0IiwiZ3JlYXRlck9yRXF1YWwiLCJHZSIsImxlc3NUaGFuIiwiTHQiLCJsZXNzT3JFcXVhbCIsIkxlIiwiT3IiLCJvckNvbmRpdGlvbiIsIkFuZCIsImFuZENvbmRpdGlvbiIsImFubm90YXRpb25BcHBseUV4cHJlc3Npb24iLCJoYXNPd25Qcm9wZXJ0eSIsIiRPciIsIiRBbmQiLCIkTm90IiwiJEVxIiwiJE5lIiwiJEd0IiwiJEdlIiwiJEx0IiwiJExlIiwiJFBhdGgiLCJGdW5jdGlvbiIsIiRGdW5jdGlvbiIsIkFwcGx5IiwiJEFwcGx5IiwiJElmIiwicmVzb2x2ZUVudW1WYWx1ZSIsIiRFbnVtTWVtYmVyIiwiaWZFbHNlIiwiY29udmVydFN1YkFwcGx5UGFyYW1ldGVycyIsImFwcGx5UGFyYW0iLCJhcHBseVBhcmFtQ29udmVydGVkIiwiYXBwbHlFeHByZXNzaW9uIiwicGFyYW1ldGVyIiwidGVtcGxhdGUiLCJ0ZW1wbGF0ZVBhcmFtcyIsInNsaWNlIiwidGFyZ2V0T2JqZWN0IiwiJE5hbWUiLCIkTGFiZWxlZEVsZW1lbnQiLCJjb21wYXJpc29uIiwibGVmdE9wZXJhbmQiLCJyaWdodE9wZXJhbmQiLCJsZWZ0RXhwcmVzc2lvbiIsInJpZ2h0RXhwcmVzc2lvbiIsImNoZWNrVW5kZWZpbmVkIiwibGVmdCIsInJpZ2h0IiwicmVkdWNlZCIsImNvbmRpdGlvbkV4cHJlc3Npb24iLCJvblRydWVFeHByZXNzaW9uIiwib25GYWxzZUV4cHJlc3Npb24iLCJwYXRoSWR4IiwibXlJZkVsc2VFeHByZXNzaW9uIiwiZm9ybWF0UmVzdWx0IiwiYWxsUGFydHMiLCJ0cmFuc2Zvcm1SZWN1cnNpdmVseSIsImNvbnN0YW50UGF0aCIsInVuc2hpZnQiLCJKU09OIiwic3RyaW5naWZ5IiwiaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCIsImZvcm1hdHRlckZ1bmN0aW9uIiwiY29udGV4dEVudGl0eVR5cGUiLCJpZ25vcmVDb21wbGV4VHlwZSIsInBhcmFtZXRlckV4cHJlc3Npb25zIiwia2V5cyIsImZ1bmN0aW9uTmFtZSIsIl9fZnVuY3Rpb25OYW1lIiwiZm9ybWF0dGVyQ2xhc3MiLCJmb3JtYXR0ZXJOYW1lIiwic3BsaXQiLCJteUZvcm1hdEV4cHJlc3Npb24iLCJzZXRVcENvbnN0cmFpbnRzIiwidGFyZ2V0TWFwcGluZyIsInByb3BlcnR5Iiwic2NhbGUiLCJwcmVjaXNpb24iLCJtYXhMZW5ndGgiLCJudWxsYWJsZSIsImFubm90YXRpb25zIiwiVmFsaWRhdGlvbiIsIk1pbmltdW0iLCJtaW5pbXVtIiwiTWF4aW11bSIsIm1heGltdW0iLCJDb21tb24iLCJJc0RpZ2l0U2VxdWVuY2UiLCJpc0RpZ2l0U2VxdWVuY2UiLCJWNCIsImZvcm1hdFdpdGhUeXBlSW5mb3JtYXRpb24iLCJwcm9wZXJ0eUJpbmRpbmdFeHByZXNzaW9uIiwiaWdub3JlQ29uc3RyYWludHMiLCJvdXRFeHByZXNzaW9uIiwiZm9ybWF0T3B0aW9ucyIsImluZGV4T2YiLCJhc3NpZ24iLCJwYXJzZUFzU3RyaW5nIiwiaXNQcm9wZXJ0eSIsInBhcnNlS2VlcHNFbXB0eVN0cmluZyIsImZpc2NhbFR5cGUiLCJnZXRGaXNjYWxUeXBlIiwidHlwZXNTdXBwb3J0aW5nUGFyc2VFbXB0eVZhbHVlVG9aZXJvIiwiaW5jbHVkZXMiLCJwYXJzZUVtcHR5VmFsdWVUb1plcm8iLCJlbXB0eVN0cmluZyIsIklzRmlzY2FsWWVhciIsIklzRmlzY2FsUGVyaW9kIiwiSXNGaXNjYWxZZWFyUGVyaW9kIiwiSXNGaXNjYWxRdWFydGVyIiwiSXNGaXNjYWxZZWFyUXVhcnRlciIsIklzRmlzY2FsV2VlayIsIklzRmlzY2FsWWVhcldlZWsiLCJJc0RheU9mRmlzY2FsWWVhciIsImFkZFR5cGVJbmZvcm1hdGlvbiIsIm9Gb3JtYXRPcHRpb25zIiwiX2dldENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc0Zyb21GaXJzdFBhcmFtIiwidW9tUGF0aCIsIm1vZGUiLCJjdXJyZW5jeVBhdGgiLCJwYXJhbSIsInNob3dOdW1iZXIiLCJzaG93TWVhc3VyZSIsImZ1bmMiLCJvbiIsImlzRm9ybWF0dGluZ0ZuIiwiaXNFbXB0eSIsImFCaW5kaW5ncyIsImluRXhwcmVzc2lvbnMiLCJjb25jYXRlbmF0ZWQiLCJ0b1N0cmluZyIsIm15Q29uY2F0RXhwcmVzc2lvbiIsImluRXhwcmVzc2lvbiIsImV4cHJlc3Npb25UeXBlIiwidHJhbnNmb3JtRnVuY3Rpb24iLCJpbmNsdWRlQWxsRXhwcmVzc2lvbiIsInN1YkV4cHJlc3Npb24iLCJiaW5kaW5nUGFyYW1ldGVyIiwibmVlZFBhcmVudGhlc2lzIiwiY29tcGlsZUNvbnN0YW50T2JqZWN0IiwiaXNOdWxsYWJsZSIsIm9iamVjdHMiLCJwcm9wZXJ0aWVzIiwiY2hpbGRSZXN1bHQiLCJjb21waWxlRXhwcmVzc2lvbiIsImNvbXBpbGVDb25zdGFudCIsImVtYmVkZGVkSW5CaW5kaW5nIiwiZG9Ob3RTdHJpbmdpZnkiLCJjb21waWxlUGF0aEluTW9kZWxFeHByZXNzaW9uIiwiZXhwcmVzc2lvbkZvckJpbmRpbmciLCJlbWJlZGRlZFNlcGFyYXRvciIsImNvbXBsZXhCaW5kaW5nRGVmaW5pdGlvbiIsImNvbXBpbGVQYXRoSW5Nb2RlbCIsIm91dEJpbmRpbmciLCJjb21waWxlQ29tcGxleFR5cGVFeHByZXNzaW9uIiwiY29tcGlsZVBhdGhQYXJhbWV0ZXIiLCJvdXRwdXRFbmQiLCJoYXNFbGVtZW50cyIsIndyYXBCaW5kaW5nRXhwcmVzc2lvbiIsInBhcmVudGhlc2lzUmVxdWlyZWQiLCJrZWVwVGFyZ2V0VHlwZSIsImhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nIiwic3ViRm4iLCJzdWJTdWJGbiIsImFyZ3VtZW50U3RyaW5nIiwiYXJnIiwiZm5DYWxsIiwic3Vic3RyaW5nIiwiY29tcGFyaXNvbkV4cHJlc3Npb24iLCJjb21waWxlQ29tcGFyaXNvbkV4cHJlc3Npb24iLCJpZkVsc2VFeHByZXNzaW9uIiwic2V0RXhwcmVzc2lvbiIsImNvbmNhdEV4cHJlc3Npb24iLCJuZXN0ZWRFeHByZXNzaW9uIiwibGVuZ3RoRXhwcmVzc2lvbiIsIm5vdEV4cHJlc3Npb24iLCJ0cnV0aHlFeHByZXNzaW9uIiwiZm9ybWF0dGVyRXhwcmVzc2lvbiIsImNvbXBpbGVGb3JtYXR0ZXJFeHByZXNzaW9uIiwiY29tcGxleFR5cGVFeHByZXNzaW9uIiwiY29tcGlsZU9wZXJhbmQiLCJjb21waWxlZE9wZXJhbmQiLCJwYXJ0cyIsInNpbmdsZVBhdGgiLCJvdXRWYWx1ZSJdLCJzb3VyY2VSb290IjoiLiIsInNvdXJjZXMiOlsiQmluZGluZ1Rvb2xraXQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUge1xuXHRBY3Rpb25QYXJhbWV0ZXIsXG5cdEFuZEFubm90YXRpb25FeHByZXNzaW9uLFxuXHRBbmRDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEJvb2xlYW4sXG5cdENvbmRpdGlvbmFsQ2hlY2tPclZhbHVlLFxuXHRFbnRpdHlTZXQsXG5cdEVudGl0eVR5cGUsXG5cdEVxQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRHZUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRHZUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0R3RBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0R3RDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdElmQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdElmQW5ub3RhdGlvbkV4cHJlc3Npb25WYWx1ZSxcblx0TGVBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0TGVDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEx0QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEx0Q29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHROZUFubm90YXRpb25FeHByZXNzaW9uLFxuXHROZUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0Tm90QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdE5vdENvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0T3JBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0T3JDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0UGF0aENvbmRpdGlvbkV4cHJlc3Npb24sXG5cdFByb3BlcnR5LFxuXHRQcm9wZXJ0eUFubm90YXRpb25WYWx1ZVxufSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXNcIjtcbmltcG9ydCB7IENvbW1vbkFubm90YXRpb25UZXJtcyB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy92b2NhYnVsYXJpZXMvQ29tbW9uXCI7XG5pbXBvcnQgeyBpc1Byb3BlcnR5IH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvVHlwZUd1YXJkc1wiO1xuaW1wb3J0IHsgcmVzb2x2ZUVudW1WYWx1ZSB9IGZyb20gXCIuL0Fubm90YXRpb25FbnVtXCI7XG5cbmV4cG9ydCB0eXBlIFByaW1pdGl2ZVR5cGUgPSBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQgfCBib29sZWFuIHwgb2JqZWN0IHwgbnVsbCB8IHVuZGVmaW5lZDtcbnR5cGUgRGVmaW5lZFByaW1pdGl2ZVR5cGUgPSBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQgfCBib29sZWFuIHwgb2JqZWN0O1xudHlwZSBQcmltaXRpdmVUeXBlQ2FzdDxQPiA9IFAgZXh0ZW5kcyBTdHJpbmcgPyBzdHJpbmcgOiBQIGV4dGVuZHMgQm9vbGVhbiA/IGJvb2xlYW4gOiBQIGV4dGVuZHMgTnVtYmVyID8gbnVtYmVyIDogUDtcbnR5cGUgQmFzZUV4cHJlc3Npb248X1Q+ID0ge1xuXHRfdHlwZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgRm9ybWF0T3B0aW9ucyA9IFBhcnRpYWw8e1xuXHRjdXN0b21Vbml0czogUmVjb3JkPHN0cmluZywgb2JqZWN0Pjtcblx0Y3VzdG9tQ3VycmVuY2llczogUmVjb3JkPHN0cmluZywgb2JqZWN0Pjtcblx0ZGVjaW1hbHM6IG51bWJlcjtcblx0ZW1wdHlTdHJpbmc6IG51bGwgfCBudW1iZXIgfCBzdHJpbmc7XG5cdGZpc2NhbFR5cGU6IHN0cmluZztcblx0Z3JvdXBpbmdFbmFibGVkOiBib29sZWFuO1xuXHRtYXhGcmFjdGlvbkRpZ2l0czogbnVtYmVyO1xuXHRtYXhJbnRlZ2VyRGlnaXRzOiBudW1iZXI7XG5cdG1pbkZyYWN0aW9uRGlnaXRzOiBudW1iZXI7XG5cdG1pbkludGVnZXJEaWdpdHM6IG51bWJlcjtcblx0cGFyc2VBc1N0cmluZzogYm9vbGVhbjtcblx0cGFyc2VLZWVwc0VtcHR5U3RyaW5nOiBib29sZWFuO1xuXHRwYXR0ZXJuOiBzdHJpbmc7XG5cdHByZWNpc2lvbjogbnVtYmVyO1xuXHRwcmVzZXJ2ZURlY2ltYWxzOiBib29sZWFuO1xuXHRzaG9ydERlY2ltYWxzOiBudW1iZXI7XG5cdHNob3J0UmVmTnVtYmVyOiBudW1iZXI7XG5cdHNob3dNZWFzdXJlOiBib29sZWFuO1xuXHRzaG93TnVtYmVyOiBib29sZWFuO1xuXHRzaG93U2NhbGU6IGJvb2xlYW47XG5cdHN0eWxlOiBzdHJpbmc7XG59PjtcblxuZXhwb3J0IHR5cGUgQ29uc3RhbnRFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkNvbnN0YW50XCI7XG5cdHZhbHVlOiBUO1xufTtcblxudHlwZSBTZXRPcGVyYXRvciA9IFwiJiZcIiB8IFwifHxcIjtcbmV4cG9ydCB0eXBlIFNldEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiU2V0XCI7XG5cdG9wZXJhdG9yOiBTZXRPcGVyYXRvcjtcblx0b3BlcmFuZHM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdO1xufTtcblxuZXhwb3J0IHR5cGUgTm90RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJOb3RcIjtcblx0b3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+O1xufTtcblxuZXhwb3J0IHR5cGUgVHJ1dGh5RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJUcnV0aHlcIjtcblx0b3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz47XG59O1xuXG5leHBvcnQgdHlwZSBSZWZlcmVuY2VFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248b2JqZWN0PiAmIHtcblx0X3R5cGU6IFwiUmVmXCI7XG5cdHJlZjogc3RyaW5nIHwgbnVsbDtcbn07XG5cbmV4cG9ydCB0eXBlIEZvcm1hdHRlckV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRm9ybWF0dGVyXCI7XG5cdGZuOiBzdHJpbmc7XG5cdHBhcmFtZXRlcnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPltdO1xufTtcblxudHlwZSBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiQ29tcGxleFR5cGVcIjtcblx0dHlwZTogc3RyaW5nO1xuXHRmb3JtYXRPcHRpb25zOiBGb3JtYXRPcHRpb25zO1xuXHRwYXJhbWV0ZXJzOiBvYmplY3Q7XG5cdGJpbmRpbmdQYXJhbWV0ZXJzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEZ1bmN0aW9uRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJGdW5jdGlvblwiO1xuXHRvYmo/OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248b2JqZWN0Pjtcblx0Zm46IHN0cmluZztcblx0aXNGb3JtYXR0aW5nRm46IGJvb2xlYW47XG5cdHBhcmFtZXRlcnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPltdO1xufTtcblxuZXhwb3J0IHR5cGUgQ29uY2F0RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPHN0cmluZz4gJiB7XG5cdF90eXBlOiBcIkNvbmNhdFwiO1xuXHRleHByZXNzaW9uczogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIExlbmd0aEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJMZW5ndGhcIjtcblx0cGF0aEluTW9kZWw6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPjtcbn07XG5cbnR5cGUgVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJVbnJlc29sdmFibGVcIjtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYgUGF0aEluTW9kZWxFeHByZXNzaW9uXG4gKi9cbmV4cG9ydCB0eXBlIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJQYXRoSW5Nb2RlbFwiO1xuXHRtb2RlbE5hbWU/OiBzdHJpbmc7XG5cdHBhdGg6IHN0cmluZztcblx0dGFyZ2V0RW50aXR5U2V0PzogRW50aXR5U2V0O1xuXHR0eXBlPzogc3RyaW5nO1xuXHRjb25zdHJhaW50cz86IEJpbmRpbmdDb25zdHJhaW50cztcblx0cGFyYW1ldGVycz86IG9iamVjdDtcblx0dGFyZ2V0VHlwZT86IHN0cmluZztcblx0bW9kZT86IHN0cmluZztcblx0Zm9ybWF0T3B0aW9ucz86IEZvcm1hdE9wdGlvbnM7XG59O1xuXG5leHBvcnQgdHlwZSBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkVtYmVkZGVkQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgQ29tcGFyaXNvbk9wZXJhdG9yID0gXCI9PT1cIiB8IFwiIT09XCIgfCBcIj49XCIgfCBcIj5cIiB8IFwiPD1cIiB8IFwiPFwiO1xuZXhwb3J0IHR5cGUgQ29tcGFyaXNvbkV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiQ29tcGFyaXNvblwiO1xuXHRvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yO1xuXHRvcGVyYW5kMTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+O1xuXHRvcGVyYW5kMjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+O1xufTtcblxuZXhwb3J0IHR5cGUgSWZFbHNlRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJJZkVsc2VcIjtcblx0Y29uZGl0aW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj47XG5cdG9uVHJ1ZTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRvbkZhbHNlOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG59O1xuXG4vKipcbiAqIEFuIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gdHlwZSBULlxuICpcbiAqIEB0eXBlZGVmIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvblxuICovXG5leHBvcnQgdHlwZSBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4gPVxuXHR8IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uXG5cdHwgQ29uc3RhbnRFeHByZXNzaW9uPFQ+XG5cdHwgU2V0RXhwcmVzc2lvblxuXHR8IE5vdEV4cHJlc3Npb25cblx0fCBUcnV0aHlFeHByZXNzaW9uXG5cdHwgQ29uY2F0RXhwcmVzc2lvblxuXHR8IExlbmd0aEV4cHJlc3Npb25cblx0fCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD5cblx0fCBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+XG5cdHwgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD5cblx0fCBDb21wYXJpc29uRXhwcmVzc2lvblxuXHR8IElmRWxzZUV4cHJlc3Npb248VD5cblx0fCBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+XG5cdHwgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+XG5cdHwgUmVmZXJlbmNlRXhwcmVzc2lvblxuXHR8IEZ1bmN0aW9uRXhwcmVzc2lvbjxUPjtcblxudHlwZSBUeXBlTWFwcGluZ0RlZmluaXRpb24gPSB7XG5cdHR5cGU6IHN0cmluZztcblx0Y29uc3RyYWludHM/OiB7XG5cdFx0JFByZWNpc2lvbj86IHN0cmluZztcblx0XHQkVjQ/OiBzdHJpbmc7XG5cdFx0JFNjYWxlPzogc3RyaW5nO1xuXHRcdCRNYXhMZW5ndGg/OiBzdHJpbmc7XG5cdFx0JE51bGxhYmxlPzogc3RyaW5nO1xuXHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1pbmltdW0vJERlY2ltYWxcIj86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiPzogc3RyaW5nO1xuXHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1heGltdW0vJERlY2ltYWxcIj86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiPzogc3RyaW5nO1xuXHRcdFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5Jc0RpZ2l0U2VxdWVuY2VcIj86IHN0cmluZztcblx0fTtcbn07XG5leHBvcnQgY29uc3QgRURNX1RZUEVfTUFQUElORzogUmVjb3JkPHN0cmluZywgVHlwZU1hcHBpbmdEZWZpbml0aW9uPiA9IHtcblx0XCJFZG0uQm9vbGVhblwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuQm9vbGVhblwiIH0sXG5cdFwiRWRtLkJ5dGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkJ5dGVcIiB9LFxuXHRcIkVkbS5EYXRlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EYXRlXCIgfSxcblx0XCJFZG0uRGF0ZVRpbWVPZmZzZXRcIjoge1xuXHRcdGNvbnN0cmFpbnRzOiB7XG5cdFx0XHQkUHJlY2lzaW9uOiBcInByZWNpc2lvblwiLFxuXHRcdFx0JFY0OiBcIlY0XCJcblx0XHR9LFxuXHRcdHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRGF0ZVRpbWVPZmZzZXRcIlxuXHR9LFxuXHRcIkVkbS5EZWNpbWFsXCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWluaW11bS8kRGVjaW1hbFwiOiBcIm1pbmltdW1cIixcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1pbmltdW1AT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuRXhjbHVzaXZlXCI6IFwibWluaW11bUV4Y2x1c2l2ZVwiLFxuXHRcdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWF4aW11bS8kRGVjaW1hbFwiOiBcIm1heGltdW1cIixcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1heGltdW1AT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuRXhjbHVzaXZlXCI6IFwibWF4aW11bUV4Y2x1c2l2ZVwiLFxuXHRcdFx0JFByZWNpc2lvbjogXCJwcmVjaXNpb25cIixcblx0XHRcdCRTY2FsZTogXCJzY2FsZVwiXG5cdFx0fSxcblx0XHR0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIlxuXHR9LFxuXHRcIkVkbS5Eb3VibGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRvdWJsZVwiIH0sXG5cdFwiRWRtLkd1aWRcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkd1aWRcIiB9LFxuXHRcIkVkbS5JbnQxNlwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MTZcIiB9LFxuXHRcIkVkbS5JbnQzMlwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MzJcIiB9LFxuXHRcIkVkbS5JbnQ2NFwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50NjRcIiB9LFxuXHRcIkVkbS5TQnl0ZVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU0J5dGVcIiB9LFxuXHRcIkVkbS5TaW5nbGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlNpbmdsZVwiIH0sXG5cdFwiRWRtLlN0cmVhbVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU3RyZWFtXCIgfSxcblx0XCJFZG0uQmluYXJ5XCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TdHJlYW1cIiB9LFxuXHRcIkVkbS5TdHJpbmdcIjoge1xuXHRcdGNvbnN0cmFpbnRzOiB7XG5cdFx0XHRcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuSXNEaWdpdFNlcXVlbmNlXCI6IFwiaXNEaWdpdFNlcXVlbmNlXCIsXG5cdFx0XHQkTWF4TGVuZ3RoOiBcIm1heExlbmd0aFwiLFxuXHRcdFx0JE51bGxhYmxlOiBcIm51bGxhYmxlXCJcblx0XHR9LFxuXHRcdHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU3RyaW5nXCJcblx0fSxcblx0XCJFZG0uVGltZU9mRGF5XCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0JFByZWNpc2lvbjogXCJwcmVjaXNpb25cIlxuXHRcdH0sXG5cdFx0dHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5UaW1lT2ZEYXlcIlxuXHR9XG59O1xuXG4vKipcbiAqIEFuIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gdHlwZSBULCBvciBhIGNvbnN0YW50IHZhbHVlIG9mIHR5cGUgVFxuICovXG5leHBvcnQgdHlwZSBFeHByZXNzaW9uT3JQcmltaXRpdmU8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+ID0gQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHwgVDtcblxuZXhwb3J0IGNvbnN0IHVucmVzb2x2YWJsZUV4cHJlc3Npb246IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uID0ge1xuXHRfdHlwZTogXCJVbnJlc29sdmFibGVcIlxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZVhtbEF0dHJpYnV0ZShpbnB1dFN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcblx0cmV0dXJuIGlucHV0U3RyaW5nLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPltdKTogYm9vbGVhbiB7XG5cdHJldHVybiBleHByZXNzaW9ucy5maW5kKChleHByKSA9PiBleHByLl90eXBlID09PSBcIlVucmVzb2x2YWJsZVwiKSAhPT0gdW5kZWZpbmVkO1xufVxuLyoqXG4gKiBDaGVjayB0d28gZXhwcmVzc2lvbnMgZm9yIChkZWVwKSBlcXVhbGl0eS5cbiAqXG4gKiBAcGFyYW0gYVxuICogQHBhcmFtIGJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgdHdvIGV4cHJlc3Npb25zIGFyZSBlcXVhbFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbDxUPihhOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sIGI6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPik6IGJvb2xlYW4ge1xuXHRpZiAoYS5fdHlwZSAhPT0gYi5fdHlwZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHN3aXRjaCAoYS5fdHlwZSkge1xuXHRcdGNhc2UgXCJVbnJlc29sdmFibGVcIjpcblx0XHRcdHJldHVybiBmYWxzZTsgLy8gVW5yZXNvbHZhYmxlIGlzIG5ldmVyIGVxdWFsIHRvIGFueXRoaW5nIGV2ZW4gaXRzZWxmXG5cdFx0Y2FzZSBcIkNvbnN0YW50XCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkQmluZGluZ1wiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCI6XG5cdFx0XHRyZXR1cm4gYS52YWx1ZSA9PT0gKGIgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+KS52YWx1ZTtcblxuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZCwgKGIgYXMgTm90RXhwcmVzc2lvbikub3BlcmFuZCk7XG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0cmV0dXJuIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vcGVyYW5kLCAoYiBhcyBUcnV0aHlFeHByZXNzaW9uKS5vcGVyYW5kKTtcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLm9wZXJhdG9yID09PSAoYiBhcyBTZXRFeHByZXNzaW9uKS5vcGVyYXRvciAmJlxuXHRcdFx0XHRhLm9wZXJhbmRzLmxlbmd0aCA9PT0gKGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmFuZHMubGVuZ3RoICYmXG5cdFx0XHRcdGEub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+XG5cdFx0XHRcdFx0KGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmFuZHMuc29tZSgob3RoZXJFeHByZXNzaW9uKSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGV4cHJlc3Npb24sIG90aGVyRXhwcmVzc2lvbikpXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEuY29uZGl0aW9uLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5jb25kaXRpb24pICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vblRydWUsIChiIGFzIElmRWxzZUV4cHJlc3Npb248VD4pLm9uVHJ1ZSkgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9uRmFsc2UsIChiIGFzIElmRWxzZUV4cHJlc3Npb248VD4pLm9uRmFsc2UpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEub3BlcmF0b3IgPT09IChiIGFzIENvbXBhcmlzb25FeHByZXNzaW9uKS5vcGVyYXRvciAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZDEsIChiIGFzIENvbXBhcmlzb25FeHByZXNzaW9uKS5vcGVyYW5kMSkgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQyLCAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmFuZDIpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIkNvbmNhdFwiOlxuXHRcdFx0Y29uc3QgYUV4cHJlc3Npb25zID0gYS5leHByZXNzaW9ucztcblx0XHRcdGNvbnN0IGJFeHByZXNzaW9ucyA9IChiIGFzIENvbmNhdEV4cHJlc3Npb24pLmV4cHJlc3Npb25zO1xuXHRcdFx0aWYgKGFFeHByZXNzaW9ucy5sZW5ndGggIT09IGJFeHByZXNzaW9ucy5sZW5ndGgpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGFFeHByZXNzaW9ucy5ldmVyeSgoZXhwcmVzc2lvbiwgaW5kZXgpID0+IHtcblx0XHRcdFx0cmV0dXJuIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoZXhwcmVzc2lvbiwgYkV4cHJlc3Npb25zW2luZGV4XSk7XG5cdFx0XHR9KTtcblxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEucGF0aEluTW9kZWwsIChiIGFzIExlbmd0aEV4cHJlc3Npb24pLnBhdGhJbk1vZGVsKTtcblxuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5tb2RlbE5hbWUgPT09IChiIGFzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPikubW9kZWxOYW1lICYmXG5cdFx0XHRcdGEucGF0aCA9PT0gKGIgYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+KS5wYXRoICYmXG5cdFx0XHRcdGEudGFyZ2V0RW50aXR5U2V0ID09PSAoYiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pLnRhcmdldEVudGl0eVNldFxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEuZm4gPT09IChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLmZuICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5sZW5ndGggPT09IChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLnBhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLnBhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSkpXG5cdFx0XHQpO1xuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS50eXBlID09PSAoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLnR5cGUgJiZcblx0XHRcdFx0YS5iaW5kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IChiIGFzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPikuYmluZGluZ1BhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEuYmluZGluZ1BhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT5cblx0XHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKChiIGFzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPikuYmluZGluZ1BhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSlcblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiRnVuY3Rpb25cIjpcblx0XHRcdGNvbnN0IG90aGVyRnVuY3Rpb24gPSBiIGFzIEZ1bmN0aW9uRXhwcmVzc2lvbjxUPjtcblx0XHRcdGlmIChhLm9iaiA9PT0gdW5kZWZpbmVkIHx8IG90aGVyRnVuY3Rpb24ub2JqID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmV0dXJuIGEub2JqID09PSBvdGhlckZ1bmN0aW9uO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLmZuID09PSBvdGhlckZ1bmN0aW9uLmZuICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vYmosIG90aGVyRnVuY3Rpb24ub2JqKSAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMubGVuZ3RoID09PSBvdGhlckZ1bmN0aW9uLnBhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKG90aGVyRnVuY3Rpb24ucGFyYW1ldGVyc1tpbmRleF0sIHZhbHVlKSlcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiUmVmXCI6XG5cdFx0XHRyZXR1cm4gYS5yZWYgPT09IChiIGFzIFJlZmVyZW5jZUV4cHJlc3Npb24pLnJlZjtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBuZXN0ZWQgU2V0RXhwcmVzc2lvbiBieSBpbmxpbmluZyBvcGVyYW5kcyBvZiB0eXBlIFNldEV4cHJlc3Npb24gd2l0aCB0aGUgc2FtZSBvcGVyYXRvci5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvbiB0byBmbGF0dGVuXG4gKiBAcmV0dXJucyBBIG5ldyBTZXRFeHByZXNzaW9uIHdpdGggdGhlIHNhbWUgb3BlcmF0b3JcbiAqL1xuZnVuY3Rpb24gZmxhdHRlblNldEV4cHJlc3Npb24oZXhwcmVzc2lvbjogU2V0RXhwcmVzc2lvbik6IFNldEV4cHJlc3Npb24ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbi5vcGVyYW5kcy5yZWR1Y2UoXG5cdFx0KHJlc3VsdDogU2V0RXhwcmVzc2lvbiwgb3BlcmFuZCkgPT4ge1xuXHRcdFx0Y29uc3QgY2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmcgPVxuXHRcdFx0XHRvcGVyYW5kLl90eXBlID09PSBcIlNldFwiICYmIG9wZXJhbmQub3BlcmF0b3IgPT09IGV4cHJlc3Npb24ub3BlcmF0b3IgPyBvcGVyYW5kLm9wZXJhbmRzIDogW29wZXJhbmRdO1xuXHRcdFx0Y2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmcuZm9yRWFjaCgoY2FuZGlkYXRlKSA9PiB7XG5cdFx0XHRcdGlmIChyZXN1bHQub3BlcmFuZHMuZXZlcnkoKGUpID0+ICFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGUsIGNhbmRpZGF0ZSkpKSB7XG5cdFx0XHRcdFx0cmVzdWx0Lm9wZXJhbmRzLnB1c2goY2FuZGlkYXRlKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sXG5cdFx0eyBfdHlwZTogXCJTZXRcIiwgb3BlcmF0b3I6IGV4cHJlc3Npb24ub3BlcmF0b3IsIG9wZXJhbmRzOiBbXSB9XG5cdCk7XG59XG5cbi8qKlxuICogRGV0ZWN0cyB3aGV0aGVyIGFuIGFycmF5IG9mIGJvb2xlYW4gZXhwcmVzc2lvbnMgY29udGFpbnMgYW4gZXhwcmVzc2lvbiBhbmQgaXRzIG5lZ2F0aW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9ucyBBcnJheSBvZiBleHByZXNzaW9uc1xuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBzZXQgb2YgZXhwcmVzc2lvbnMgY29udGFpbnMgYW4gZXhwcmVzc2lvbiBhbmQgaXRzIG5lZ2F0aW9uXG4gKi9cbmZ1bmN0aW9uIGhhc09wcG9zaXRlRXhwcmVzc2lvbnMoZXhwcmVzc2lvbnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdKTogYm9vbGVhbiB7XG5cdGNvbnN0IG5lZ2F0ZWRFeHByZXNzaW9ucyA9IGV4cHJlc3Npb25zLm1hcChub3QpO1xuXHRyZXR1cm4gZXhwcmVzc2lvbnMuc29tZSgoZXhwcmVzc2lvbiwgaW5kZXgpID0+IHtcblx0XHRmb3IgKGxldCBpID0gaW5kZXggKyAxOyBpIDwgbmVnYXRlZEV4cHJlc3Npb25zLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChleHByZXNzaW9uLCBuZWdhdGVkRXhwcmVzc2lvbnNbaV0pKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0pO1xufVxuXG4vKipcbiAqIExvZ2ljYWwgYGFuZGAgZXhwcmVzc2lvbi5cbiAqXG4gKiBUaGUgZXhwcmVzc2lvbiBpcyBzaW1wbGlmaWVkIHRvIGZhbHNlIGlmIHRoaXMgY2FuIGJlIGRlY2lkZWQgc3RhdGljYWxseSAodGhhdCBpcywgaWYgb25lIG9wZXJhbmQgaXMgYSBjb25zdGFudFxuICogZmFsc2Ugb3IgaWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYW4gb3BlcmFuZCBhbmQgaXRzIG5lZ2F0aW9uKS5cbiAqXG4gKiBAcGFyYW0gb3BlcmFuZHMgRXhwcmVzc2lvbnMgdG8gY29ubmVjdCBieSBgYW5kYFxuICogQHJldHVybnMgRXhwcmVzc2lvbiBldmFsdWF0aW5nIHRvIGJvb2xlYW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuZCguLi5vcGVyYW5kczogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+W10pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBleHByZXNzaW9ucyA9IGZsYXR0ZW5TZXRFeHByZXNzaW9uKHtcblx0XHRfdHlwZTogXCJTZXRcIixcblx0XHRvcGVyYXRvcjogXCImJlwiLFxuXHRcdG9wZXJhbmRzOiBvcGVyYW5kcy5tYXAod3JhcFByaW1pdGl2ZSlcblx0fSkub3BlcmFuZHM7XG5cblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnMpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IGlzU3RhdGljRmFsc2UgPSBmYWxzZTtcblx0Y29uc3Qgbm9uVHJpdmlhbEV4cHJlc3Npb24gPSBleHByZXNzaW9ucy5maWx0ZXIoKGV4cHJlc3Npb24pID0+IHtcblx0XHRpZiAoaXNGYWxzZShleHByZXNzaW9uKSkge1xuXHRcdFx0aXNTdGF0aWNGYWxzZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAhaXNDb25zdGFudChleHByZXNzaW9uKTtcblx0fSk7XG5cdGlmIChpc1N0YXRpY0ZhbHNlKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDApIHtcblx0XHQvLyBSZXNvbHZlIHRoZSBjb25zdGFudCB0aGVuXG5cdFx0Y29uc3QgaXNWYWxpZCA9IGV4cHJlc3Npb25zLnJlZHVjZSgocmVzdWx0LCBleHByZXNzaW9uKSA9PiByZXN1bHQgJiYgaXNUcnVlKGV4cHJlc3Npb24pLCB0cnVlKTtcblx0XHRyZXR1cm4gY29uc3RhbnQoaXNWYWxpZCk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIG5vblRyaXZpYWxFeHByZXNzaW9uWzBdO1xuXHR9IGVsc2UgaWYgKGhhc09wcG9zaXRlRXhwcmVzc2lvbnMobm9uVHJpdmlhbEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0XHRvcGVyYXRvcjogXCImJlwiLFxuXHRcdFx0b3BlcmFuZHM6IG5vblRyaXZpYWxFeHByZXNzaW9uXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIExvZ2ljYWwgYG9yYCBleHByZXNzaW9uLlxuICpcbiAqIFRoZSBleHByZXNzaW9uIGlzIHNpbXBsaWZpZWQgdG8gdHJ1ZSBpZiB0aGlzIGNhbiBiZSBkZWNpZGVkIHN0YXRpY2FsbHkgKHRoYXQgaXMsIGlmIG9uZSBvcGVyYW5kIGlzIGEgY29uc3RhbnRcbiAqIHRydWUgb3IgaWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYW4gb3BlcmFuZCBhbmQgaXRzIG5lZ2F0aW9uKS5cbiAqXG4gKiBAcGFyYW0gb3BlcmFuZHMgRXhwcmVzc2lvbnMgdG8gY29ubmVjdCBieSBgb3JgXG4gKiBAcmV0dXJucyBFeHByZXNzaW9uIGV2YWx1YXRpbmcgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gb3IoLi4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgZXhwcmVzc2lvbnMgPSBmbGF0dGVuU2V0RXhwcmVzc2lvbih7XG5cdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0b3BlcmF0b3I6IFwifHxcIixcblx0XHRvcGVyYW5kczogb3BlcmFuZHMubWFwKHdyYXBQcmltaXRpdmUpXG5cdH0pLm9wZXJhbmRzO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5leHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRsZXQgaXNTdGF0aWNUcnVlID0gZmFsc2U7XG5cdGNvbnN0IG5vblRyaXZpYWxFeHByZXNzaW9uID0gZXhwcmVzc2lvbnMuZmlsdGVyKChleHByZXNzaW9uKSA9PiB7XG5cdFx0aWYgKGlzVHJ1ZShleHByZXNzaW9uKSkge1xuXHRcdFx0aXNTdGF0aWNUcnVlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuICFpc0NvbnN0YW50KGV4cHJlc3Npb24pIHx8IGV4cHJlc3Npb24udmFsdWU7XG5cdH0pO1xuXHRpZiAoaXNTdGF0aWNUcnVlKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHRydWUpO1xuXHR9IGVsc2UgaWYgKG5vblRyaXZpYWxFeHByZXNzaW9uLmxlbmd0aCA9PT0gMCkge1xuXHRcdC8vIFJlc29sdmUgdGhlIGNvbnN0YW50IHRoZW5cblx0XHRjb25zdCBpc1ZhbGlkID0gZXhwcmVzc2lvbnMucmVkdWNlKChyZXN1bHQsIGV4cHJlc3Npb24pID0+IHJlc3VsdCAmJiBpc1RydWUoZXhwcmVzc2lvbiksIHRydWUpO1xuXHRcdHJldHVybiBjb25zdGFudChpc1ZhbGlkKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4gbm9uVHJpdmlhbEV4cHJlc3Npb25bMF07XG5cdH0gZWxzZSBpZiAoaGFzT3Bwb3NpdGVFeHByZXNzaW9ucyhub25Ucml2aWFsRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdFx0b3BlcmF0b3I6IFwifHxcIixcblx0XHRcdG9wZXJhbmRzOiBub25Ucml2aWFsRXhwcmVzc2lvblxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBub3RgIG9wZXJhdG9yLlxuICpcbiAqIEBwYXJhbSBvcGVyYW5kIFRoZSBleHByZXNzaW9uIHRvIHJldmVyc2VcbiAqIEByZXR1cm5zIFRoZSByZXN1bHRpbmcgZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3Qob3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+KTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0b3BlcmFuZCA9IHdyYXBQcmltaXRpdmUob3BlcmFuZCk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKG9wZXJhbmQpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH0gZWxzZSBpZiAoaXNDb25zdGFudChvcGVyYW5kKSkge1xuXHRcdHJldHVybiBjb25zdGFudCghb3BlcmFuZC52YWx1ZSk7XG5cdH0gZWxzZSBpZiAoXG5cdFx0dHlwZW9mIG9wZXJhbmQgPT09IFwib2JqZWN0XCIgJiZcblx0XHRvcGVyYW5kLl90eXBlID09PSBcIlNldFwiICYmXG5cdFx0b3BlcmFuZC5vcGVyYXRvciA9PT0gXCJ8fFwiICYmXG5cdFx0b3BlcmFuZC5vcGVyYW5kcy5ldmVyeSgoZXhwcmVzc2lvbikgPT4gaXNDb25zdGFudChleHByZXNzaW9uKSB8fCBpc0NvbXBhcmlzb24oZXhwcmVzc2lvbikpXG5cdCkge1xuXHRcdHJldHVybiBhbmQoLi4ub3BlcmFuZC5vcGVyYW5kcy5tYXAoKGV4cHJlc3Npb24pID0+IG5vdChleHByZXNzaW9uKSkpO1xuXHR9IGVsc2UgaWYgKFxuXHRcdHR5cGVvZiBvcGVyYW5kID09PSBcIm9iamVjdFwiICYmXG5cdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmF0b3IgPT09IFwiJiZcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+IGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgaXNDb21wYXJpc29uKGV4cHJlc3Npb24pKVxuXHQpIHtcblx0XHRyZXR1cm4gb3IoLi4ub3BlcmFuZC5vcGVyYW5kcy5tYXAoKGV4cHJlc3Npb24pID0+IG5vdChleHByZXNzaW9uKSkpO1xuXHR9IGVsc2UgaWYgKGlzQ29tcGFyaXNvbihvcGVyYW5kKSkge1xuXHRcdC8vIENyZWF0ZSB0aGUgcmV2ZXJzZSBjb21wYXJpc29uXG5cdFx0c3dpdGNoIChvcGVyYW5kLm9wZXJhdG9yKSB7XG5cdFx0XHRjYXNlIFwiIT09XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIj09PVwiIH07XG5cdFx0XHRjYXNlIFwiPFwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI+PVwiIH07XG5cdFx0XHRjYXNlIFwiPD1cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPlwiIH07XG5cdFx0XHRjYXNlIFwiPT09XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIiE9PVwiIH07XG5cdFx0XHRjYXNlIFwiPlwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI8PVwiIH07XG5cdFx0XHRjYXNlIFwiPj1cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPFwiIH07XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG9wZXJhbmQuX3R5cGUgPT09IFwiTm90XCIpIHtcblx0XHRyZXR1cm4gb3BlcmFuZC5vcGVyYW5kO1xuXHR9XG5cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJOb3RcIixcblx0XHRvcGVyYW5kOiBvcGVyYW5kXG5cdH07XG59XG5cbi8qKlxuICogRXZhbHVhdGVzIHdoZXRoZXIgYSBiaW5kaW5nIGV4cHJlc3Npb24gaXMgZXF1YWwgdG8gdHJ1ZSB3aXRoIGEgbG9vc2UgZXF1YWxpdHkuXG4gKlxuICogQHBhcmFtIG9wZXJhbmQgVGhlIGV4cHJlc3Npb24gdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRoZSByZXN1bHRpbmcgZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1RydXRoeShvcGVyYW5kOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGlmIChpc0NvbnN0YW50KG9wZXJhbmQpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KCEhb3BlcmFuZC52YWx1ZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlRydXRoeVwiLFxuXHRcdFx0b3BlcmFuZDogb3BlcmFuZFxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYmluZGluZyBleHByZXNzaW9uIHRoYXQgd2lsbCBiZSBldmFsdWF0ZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgbW9kZWwuXG4gKlxuICogQHBhcmFtIHBhdGhcbiAqIEBwYXJhbSBtb2RlbE5hbWVcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzXG4gKiBAcGFyYW0gcGF0aFZpc2l0b3JcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50YXRpbmcgdGhhdCBwYXRoIGluIHRoZSBtb2RlbFxuICogQGRlcHJlY2F0ZWQgdXNlIHBhdGhJbk1vZGVsIGluc3RlYWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbmRpbmdFeHByZXNzaW9uPFRhcmdldFR5cGUgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0cGF0aDogc3RyaW5nLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUYXJnZXRUeXBlPiB8IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uIHtcblx0cmV0dXJuIHBhdGhJbk1vZGVsKHBhdGgsIG1vZGVsTmFtZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBiaW5kaW5nIGV4cHJlc3Npb24gdGhhdCB3aWxsIGJlIGV2YWx1YXRlZCBieSB0aGUgY29ycmVzcG9uZGluZyBtb2RlbC5cbiAqXG4gKiBAdGVtcGxhdGUgVGFyZ2V0VHlwZVxuICogQHBhcmFtIHBhdGggVGhlIHBhdGggb24gdGhlIG1vZGVsXG4gKiBAcGFyYW0gW21vZGVsTmFtZV0gVGhlIG5hbWUgb2YgdGhlIG1vZGVsXG4gKiBAcGFyYW0gW3Zpc2l0ZWROYXZpZ2F0aW9uUGF0aHNdIFRoZSBwYXRocyBmcm9tIHRoZSByb290IGVudGl0eVNldFxuICogQHBhcmFtIFtwYXRoVmlzaXRvcl0gQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGF0aW5nIHRoYXQgcGF0aCBpbiB0aGUgbW9kZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGhJbk1vZGVsKFxuXHRwYXRoOiB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbjtcbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbDxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzPzogc3RyaW5nW10sXG5cdHBhdGhWaXNpdG9yPzogdW5kZWZpbmVkXG4pOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiB8IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUYXJnZXRUeXBlPjtcbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbDxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZCxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiB8IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUYXJnZXRUeXBlPiB7XG5cdGlmIChwYXRoID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRsZXQgdGFyZ2V0UGF0aDtcblx0aWYgKHBhdGhWaXNpdG9yKSB7XG5cdFx0dGFyZ2V0UGF0aCA9IHBhdGhWaXNpdG9yKHBhdGgpO1xuXHRcdGlmICh0YXJnZXRQYXRoID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRjb25zdCBsb2NhbFBhdGggPSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLmNvbmNhdCgpO1xuXHRcdGxvY2FsUGF0aC5wdXNoKHBhdGgpO1xuXHRcdHRhcmdldFBhdGggPSBsb2NhbFBhdGguam9pbihcIi9cIik7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJQYXRoSW5Nb2RlbFwiLFxuXHRcdG1vZGVsTmFtZTogbW9kZWxOYW1lLFxuXHRcdHBhdGg6IHRhcmdldFBhdGhcblx0fTtcbn1cblxudHlwZSBQbGFpbkV4cHJlc3Npb25PYmplY3QgPSB7IFtpbmRleDogc3RyaW5nXTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+IH07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbnN0YW50IGV4cHJlc3Npb24gYmFzZWQgb24gYSBwcmltaXRpdmUgdmFsdWUuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgY29uc3RhbnQgdG8gd3JhcCBpbiBhbiBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBUaGUgY29uc3RhbnQgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gY29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KHZhbHVlOiBUKTogQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHtcblx0bGV0IGNvbnN0YW50VmFsdWU6IFQ7XG5cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG5cdFx0XHRjb25zdGFudFZhbHVlID0gdmFsdWUubWFwKHdyYXBQcmltaXRpdmUpIGFzIFQ7XG5cdFx0fSBlbHNlIGlmIChpc1ByaW1pdGl2ZU9iamVjdCh2YWx1ZSkpIHtcblx0XHRcdGNvbnN0YW50VmFsdWUgPSB2YWx1ZS52YWx1ZU9mKCkgYXMgVDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3RhbnRWYWx1ZSA9IE9iamVjdC5lbnRyaWVzKHZhbHVlKS5yZWR1Y2UoKHBsYWluRXhwcmVzc2lvbiwgW2tleSwgdmFsXSkgPT4ge1xuXHRcdFx0XHRjb25zdCB3cmFwcGVkVmFsdWUgPSB3cmFwUHJpbWl0aXZlKHZhbCk7XG5cdFx0XHRcdGlmICh3cmFwcGVkVmFsdWUuX3R5cGUgIT09IFwiQ29uc3RhbnRcIiB8fCB3cmFwcGVkVmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdHBsYWluRXhwcmVzc2lvbltrZXldID0gd3JhcHBlZFZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBwbGFpbkV4cHJlc3Npb247XG5cdFx0XHR9LCB7fSBhcyBQbGFpbkV4cHJlc3Npb25PYmplY3QpIGFzIFQ7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGNvbnN0YW50VmFsdWUgPSB2YWx1ZTtcblx0fVxuXG5cdHJldHVybiB7IF90eXBlOiBcIkNvbnN0YW50XCIsIHZhbHVlOiBjb25zdGFudFZhbHVlIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQmluZGluZ1N0cmluZzxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHZhbHVlOiBzdHJpbmcgfCBib29sZWFuIHwgbnVtYmVyLFxuXHR0YXJnZXRUeXBlPzogc3RyaW5nXG4pOiBDb25zdGFudEV4cHJlc3Npb248VD4gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4gfCBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+IHwgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD4ge1xuXHRpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWUuc3RhcnRzV2l0aChcIntcIikpIHtcblx0XHRjb25zdCBwYXRoSW5Nb2RlbFJlZ2V4ID0gL157KC4qKT4oLispfSQvOyAvLyBNYXRjaGVzIG1vZGVsIHBhdGhzIGxpa2UgXCJtb2RlbD5wYXRoXCIgb3IgXCI+cGF0aFwiIChkZWZhdWx0IG1vZGVsKVxuXHRcdGNvbnN0IHBhdGhJbk1vZGVsUmVnZXhNYXRjaCA9IHBhdGhJbk1vZGVsUmVnZXguZXhlYyh2YWx1ZSk7XG5cblx0XHRpZiAodmFsdWUuc3RhcnRzV2l0aChcIns9XCIpKSB7XG5cdFx0XHQvLyBFeHByZXNzaW9uIGJpbmRpbmcsIHdlIGNhbiBqdXN0IHJlbW92ZSB0aGUgb3V0ZXIgYmluZGluZyB0aGluZ3Ncblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdF90eXBlOiBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIixcblx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHR9O1xuXHRcdH0gZWxzZSBpZiAocGF0aEluTW9kZWxSZWdleE1hdGNoKSB7XG5cdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwocGF0aEluTW9kZWxSZWdleE1hdGNoWzJdIHx8IFwiXCIsIHBhdGhJbk1vZGVsUmVnZXhNYXRjaFsxXSB8fCB1bmRlZmluZWQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRfdHlwZTogXCJFbWJlZGRlZEJpbmRpbmdcIixcblx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIGlmICh0YXJnZXRUeXBlID09PSBcImJvb2xlYW5cIiAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgKHZhbHVlID09PSBcInRydWVcIiB8fCB2YWx1ZSA9PT0gXCJmYWxzZVwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudCh2YWx1ZSA9PT0gXCJ0cnVlXCIpIGFzIENvbnN0YW50RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmICh0YXJnZXRUeXBlID09PSBcIm51bWJlclwiICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAoIWlzTmFOKE51bWJlcih2YWx1ZSkpIHx8IHZhbHVlID09PSBcIk5hTlwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudChOdW1iZXIodmFsdWUpKSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHZhbHVlKSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH1cbn1cblxuLyoqXG4gKiBBIG5hbWVkIHJlZmVyZW5jZS5cbiAqXG4gKiBAc2VlIGZuXG4gKiBAcGFyYW0gcmVmZXJlbmNlIFJlZmVyZW5jZVxuICogQHJldHVybnMgVGhlIG9iamVjdCByZWZlcmVuY2UgYmluZGluZyBwYXJ0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWYocmVmZXJlbmNlOiBzdHJpbmcgfCBudWxsKTogUmVmZXJlbmNlRXhwcmVzc2lvbiB7XG5cdHJldHVybiB7IF90eXBlOiBcIlJlZlwiLCByZWY6IHJlZmVyZW5jZSB9O1xufVxuXG4vKipcbiAqIFdyYXAgYSBwcmltaXRpdmUgaW50byBhIGNvbnN0YW50IGV4cHJlc3Npb24gaWYgaXQgaXMgbm90IGFscmVhZHkgYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHNvbWV0aGluZyBUaGUgb2JqZWN0IHRvIHdyYXAgaW4gYSBDb25zdGFudCBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBFaXRoZXIgdGhlIG9yaWdpbmFsIG9iamVjdCBvciB0aGUgd3JhcHBlZCBvbmUgZGVwZW5kaW5nIG9uIHRoZSBjYXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwUHJpbWl0aXZlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihzb21ldGhpbmc6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGlmIChpc0JpbmRpbmdUb29sa2l0RXhwcmVzc2lvbihzb21ldGhpbmcpKSB7XG5cdFx0cmV0dXJuIHNvbWV0aGluZyBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblxuXHRyZXR1cm4gY29uc3RhbnQoc29tZXRoaW5nKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBiaW5kaW5nIHRvb2xpbmcgZXhwcmVzc2lvbiBvciBub3QuXG4gKlxuICogRXZlcnkgb2JqZWN0IGhhdmluZyBhIHByb3BlcnR5IG5hbWVkIGBfdHlwZWAgb2Ygc29tZSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFuIGV4cHJlc3Npb24sIGV2ZW4gaWYgdGhlcmUgaXMgYWN0dWFsbHlcbiAqIG5vIHN1Y2ggZXhwcmVzc2lvbiB0eXBlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgYmluZGluZyB0b29sa2l0IGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uKFxuXHRleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4gfCB1bmtub3duXG4pOiBleHByZXNzaW9uIGlzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPiB7XG5cdHJldHVybiAoZXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4pPy5fdHlwZSAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBjb25zdGFudCBvciBub3QuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIG1heWJlQ29uc3RhbnQgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGNvbnN0YW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbnN0YW50PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihtYXliZUNvbnN0YW50OiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBtYXliZUNvbnN0YW50IGlzIENvbnN0YW50RXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiB0eXBlb2YgbWF5YmVDb25zdGFudCAhPT0gXCJvYmplY3RcIiB8fCAobWF5YmVDb25zdGFudCBhcyBCYXNlRXhwcmVzc2lvbjxUPikuX3R5cGUgPT09IFwiQ29uc3RhbnRcIjtcbn1cblxuZnVuY3Rpb24gaXNUcnVlKGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gaXNDb25zdGFudChleHByZXNzaW9uKSAmJiBleHByZXNzaW9uLnZhbHVlID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc0ZhbHNlKGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gaXNDb25zdGFudChleHByZXNzaW9uKSAmJiBleHByZXNzaW9uLnZhbHVlID09PSBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBwYXRoIGluIG1vZGVsIGV4cHJlc3Npb24gb3Igbm90LlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtICBtYXliZUJpbmRpbmcgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGEgcGF0aCBpbiBtb2RlbCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1BhdGhJbk1vZGVsRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdG1heWJlQmluZGluZzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBtYXliZUJpbmRpbmcgaXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIChtYXliZUJpbmRpbmcgYXMgQmFzZUV4cHJlc3Npb248VD4pPy5fdHlwZSA9PT0gXCJQYXRoSW5Nb2RlbFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIGNvbXBsZXggdHlwZSBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtICBtYXliZUJpbmRpbmcgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGEgcGF0aCBpbiBtb2RlbCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdG1heWJlQmluZGluZzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBtYXliZUJpbmRpbmcgaXMgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIChtYXliZUJpbmRpbmcgYXMgQmFzZUV4cHJlc3Npb248VD4pPy5fdHlwZSA9PT0gXCJDb21wbGV4VHlwZVwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIGNvbmNhdCBleHByZXNzaW9uIG9yIG5vdC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgQ29uY2F0RXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0NvbmNhdEV4cHJlc3Npb24oZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTogZXhwcmVzc2lvbiBpcyBDb25jYXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIEJhc2VFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KT8uX3R5cGUgPT09IFwiQ29uY2F0XCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGEgSWZFbHNlIGV4cHJlc3Npb24gb3Igbm90LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBJZkVsc2VFeHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIGlzSWZFbHNlRXhwcmVzc2lvbihleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pOiBleHByZXNzaW9uIGlzIENvbmNhdEV4cHJlc3Npb24ge1xuXHRyZXR1cm4gKGV4cHJlc3Npb24gYXMgQmFzZUV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pPy5fdHlwZSA9PT0gXCJJZkVsc2VcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gcHJvdmlkZWQgaXMgYSBjb21wYXJpc29uIG9yIG5vdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBDb21wYXJpc29uRXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0NvbXBhcmlzb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPik6IGV4cHJlc3Npb24gaXMgQ29tcGFyaXNvbkV4cHJlc3Npb24ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJDb21wYXJpc29uXCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGlucHV0IHBhcmFtZXRlciBpcyBhIGNvbnN0YW50IGV4cHJlc3Npb24gb2YgdHlwZSB1bmRlZmluZWQuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGlucHV0IGV4cHJlc3Npb24gb3Igb2JqZWN0IGluIGdlbmVyYWxcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgaW5wdXQgaXMgY29uc3RhbnQgd2hpY2ggaGFzIHVuZGVmaW5lZCBmb3IgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVW5kZWZpbmVkRXhwcmVzc2lvbihleHByZXNzaW9uOiB1bmtub3duKTogZXhwcmVzc2lvbiBpcyBDb25zdGFudEV4cHJlc3Npb248dW5kZWZpbmVkPiB7XG5cdGNvbnN0IGV4cHJlc3Npb25Bc0V4cHJlc3Npb24gPSBleHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPjtcblx0cmV0dXJuIGV4cHJlc3Npb25Bc0V4cHJlc3Npb24/Ll90eXBlID09PSBcIkNvbnN0YW50XCIgJiYgZXhwcmVzc2lvbkFzRXhwcmVzc2lvbj8udmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxudHlwZSBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248UD4gPVxuXHR8IFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBJZkFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgT3JBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEFuZEFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTmVBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEVxQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBOb3RBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEd0QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBHZUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTGVBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEx0QW5ub3RhdGlvbkV4cHJlc3Npb248UD47XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlT2JqZWN0KG9iamVjdFR5cGU6IG9iamVjdCk6IGJvb2xlYW4ge1xuXHRzd2l0Y2ggKG9iamVjdFR5cGUuY29uc3RydWN0b3IubmFtZSkge1xuXHRcdGNhc2UgXCJTdHJpbmdcIjpcblx0XHRjYXNlIFwiTnVtYmVyXCI6XG5cdFx0Y2FzZSBcIkJvb2xlYW5cIjpcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHBhc3NlZCBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZSBpcyBhIENvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgYW5ub3RhdGlvblZhbHVlIFRoZSBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZSB0byBldmFsdWF0ZVxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3QgaXMgYSB7Q29tcGxleEFubm90YXRpb25FeHByZXNzaW9ufVxuICovXG5mdW5jdGlvbiBpc0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPihhbm5vdGF0aW9uVmFsdWU6IFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPFQ+KTogYW5ub3RhdGlvblZhbHVlIGlzIENvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiB0eXBlb2YgYW5ub3RhdGlvblZhbHVlID09PSBcIm9iamVjdFwiICYmICFpc1ByaW1pdGl2ZU9iamVjdChhbm5vdGF0aW9uVmFsdWUgYXMgb2JqZWN0KTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBhbm5vdGF0aW9uVmFsdWUgZm9yIGEgZ2l2ZW4gYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gYW5ub3RhdGlvblZhbHVlIFRoZSBzb3VyY2UgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWVcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIGRlZmF1bHRWYWx1ZSBEZWZhdWx0IHZhbHVlIGlmIHRoZSBhbm5vdGF0aW9uVmFsdWUgaXMgdW5kZWZpbmVkXG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBUaGUgYW5ub3RhdGlvblZhbHVlIGVxdWl2YWxlbnQgdG8gdGhhdCBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0YW5ub3RhdGlvblZhbHVlOiBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPiB8IHVuZGVmaW5lZCxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0ZGVmYXVsdFZhbHVlPzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+IHtcblx0aWYgKGFubm90YXRpb25WYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIHdyYXBQcmltaXRpdmUoZGVmYXVsdFZhbHVlIGFzIFByaW1pdGl2ZVR5cGVDYXN0PFQ+KTtcblx0fVxuXHRhbm5vdGF0aW9uVmFsdWUgPSBhbm5vdGF0aW9uVmFsdWU/LnZhbHVlT2YoKSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPjtcblx0aWYgKCFpc0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbihhbm5vdGF0aW9uVmFsdWUpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGFubm90YXRpb25WYWx1ZSk7XG5cdH1cblxuXHRzd2l0Y2ggKGFubm90YXRpb25WYWx1ZS50eXBlKSB7XG5cdFx0Y2FzZSBcIlBhdGhcIjpcblx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChhbm5vdGF0aW9uVmFsdWUucGF0aCwgdW5kZWZpbmVkLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0Y2FzZSBcIklmXCI6XG5cdFx0XHRyZXR1cm4gYW5ub3RhdGlvbklmRXhwcmVzc2lvbihhbm5vdGF0aW9uVmFsdWUuSWYsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248XG5cdFx0XHRcdFByaW1pdGl2ZVR5cGVDYXN0PFQ+XG5cdFx0XHQ+O1xuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRcdHJldHVybiBub3QocGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5Ob3QsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFxuXHRcdFx0XHRQcmltaXRpdmVUeXBlQ2FzdDxUPlxuXHRcdFx0Pjtcblx0XHRjYXNlIFwiRXFcIjpcblx0XHRcdHJldHVybiBlcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5FcVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkVxWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTmVcIjpcblx0XHRcdHJldHVybiBub3RFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5OZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLk5lWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiR3RcIjpcblx0XHRcdHJldHVybiBncmVhdGVyVGhhbihcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkd0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiR2VcIjpcblx0XHRcdHJldHVybiBncmVhdGVyT3JFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkdlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTHRcIjpcblx0XHRcdHJldHVybiBsZXNzVGhhbihcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkx0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTGVcIjpcblx0XHRcdHJldHVybiBsZXNzT3JFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkxlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiT3JcIjpcblx0XHRcdHJldHVybiBvcihcblx0XHRcdFx0Li4uYW5ub3RhdGlvblZhbHVlLk9yLm1hcChmdW5jdGlvbiAob3JDb25kaXRpb24pIHtcblx0XHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uPGJvb2xlYW4+KG9yQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHRcdH0pXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkFuZFwiOlxuXHRcdFx0cmV0dXJuIGFuZChcblx0XHRcdFx0Li4uYW5ub3RhdGlvblZhbHVlLkFuZC5tYXAoZnVuY3Rpb24gKGFuZENvbmRpdGlvbikge1xuXHRcdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb248Ym9vbGVhbj4oYW5kQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHRcdH0pXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkFwcGx5XCI6XG5cdFx0XHRyZXR1cm4gYW5ub3RhdGlvbkFwcGx5RXhwcmVzc2lvbihcblx0XHRcdFx0YW5ub3RhdGlvblZhbHVlIGFzIEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPixcblx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0cGF0aFZpc2l0b3Jcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0fVxuXHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcbn1cblxuLyoqXG4gKiBQYXJzZSB0aGUgYW5ub3RhdGlvbiBjb25kaXRpb24gaW50byBhbiBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGFubm90YXRpb25WYWx1ZSBUaGUgY29uZGl0aW9uIG9yIHZhbHVlIGZyb20gdGhlIGFubm90YXRpb25cbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgQW4gZXF1aXZhbGVudCBleHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogQ29uZGl0aW9uYWxDaGVja09yVmFsdWUsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGlmIChhbm5vdGF0aW9uVmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIGFubm90YXRpb25WYWx1ZSAhPT0gXCJvYmplY3RcIikge1xuXHRcdHJldHVybiBjb25zdGFudChhbm5vdGF0aW9uVmFsdWUgYXMgVCk7XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJE9yXCIpKSB7XG5cdFx0cmV0dXJuIG9yKFxuXHRcdFx0Li4uKChhbm5vdGF0aW9uVmFsdWUgYXMgT3JDb25kaXRpb25hbEV4cHJlc3Npb24pLiRPci5tYXAoZnVuY3Rpb24gKG9yQ29uZGl0aW9uKSB7XG5cdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb24ob3JDb25kaXRpb24sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0XHRcdH0pIGFzIHVua25vd24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+W10pXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEFuZFwiKSkge1xuXHRcdHJldHVybiBhbmQoXG5cdFx0XHQuLi4oKGFubm90YXRpb25WYWx1ZSBhcyBBbmRDb25kaXRpb25hbEV4cHJlc3Npb24pLiRBbmQubWFwKGZ1bmN0aW9uIChhbmRDb25kaXRpb24pIHtcblx0XHRcdFx0cmV0dXJuIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbmRDb25kaXRpb24sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0XHRcdH0pIGFzIHVua25vd24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+W10pXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJE5vdFwiKSkge1xuXHRcdHJldHVybiBub3QoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOb3RDb25kaXRpb25hbEV4cHJlc3Npb24pLiROb3QsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRFcVwiKSkge1xuXHRcdHJldHVybiBlcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kRXFbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kRXFbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiROZVwiKSkge1xuXHRcdHJldHVybiBub3RFcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIE5lQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTmVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIE5lQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTmVbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRHdFwiKSkge1xuXHRcdHJldHVybiBncmVhdGVyVGhhbihcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEd0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR3RbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEd0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR3RbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRHZVwiKSkge1xuXHRcdHJldHVybiBncmVhdGVyT3JFcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEdlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR2VbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEdlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR2VbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRMdFwiKSkge1xuXHRcdHJldHVybiBsZXNzVGhhbihcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEx0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTHRbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEx0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTHRbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRMZVwiKSkge1xuXHRcdHJldHVybiBsZXNzT3JFcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIExlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTGVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIExlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTGVbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRQYXRoXCIpKSB7XG5cdFx0cmV0dXJuIHBhdGhJbk1vZGVsKChhbm5vdGF0aW9uVmFsdWUgYXMgUGF0aENvbmRpdGlvbkV4cHJlc3Npb248VD4pLiRQYXRoLCB1bmRlZmluZWQsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkQXBwbHlcIikpIHtcblx0XHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiBcIkFwcGx5XCIsXG5cdFx0XHRcdEZ1bmN0aW9uOiAoYW5ub3RhdGlvblZhbHVlIGFzIHsgJEZ1bmN0aW9uPzogc3RyaW5nIH0pLiRGdW5jdGlvbixcblx0XHRcdFx0QXBwbHk6IChhbm5vdGF0aW9uVmFsdWUgYXMgeyAkQXBwbHk/OiB1bmtub3duIH0pLiRBcHBseVxuXHRcdFx0fSBhcyBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPFQ+LFxuXHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJElmXCIpKSB7XG5cdFx0cmV0dXJuIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogXCJJZlwiLFxuXHRcdFx0XHRJZjogKGFubm90YXRpb25WYWx1ZSBhcyB7ICRJZj86IHVua25vd24gfSkuJElmXG5cdFx0XHR9IGFzIElmQW5ub3RhdGlvbkV4cHJlc3Npb248VD4sXG5cdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0cGF0aFZpc2l0b3Jcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkRW51bU1lbWJlclwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudChyZXNvbHZlRW51bVZhbHVlKChhbm5vdGF0aW9uVmFsdWUgYXMgeyAkRW51bU1lbWJlcj86IHN0cmluZyB9KS4kRW51bU1lbWJlcikgYXMgVCk7XG5cdH1cblx0cmV0dXJuIGNvbnN0YW50KGZhbHNlIGFzIFQpO1xufVxuXG4vKipcbiAqIFByb2Nlc3MgdGhlIHtJZkFubm90YXRpb25FeHByZXNzaW9uVmFsdWV9IGludG8gYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBhbm5vdGF0aW9uVmFsdWUgQW4gSWYgZXhwcmVzc2lvbiByZXR1cm5pbmcgdGhlIHR5cGUgVFxuICogQHBhcmFtIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMgVGhlIHBhdGggZnJvbSB0aGUgcm9vdCBlbnRpdHkgc2V0XG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBUaGUgZXF1aXZhbGVudCBpZkVsc2UgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbklmRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogSWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlPFQ+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gaWZFbHNlKFxuXHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlWzFdIGFzIENvbmRpdGlvbmFsQ2hlY2tPclZhbHVlLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZVsyXSBhcyBDb25kaXRpb25hbENoZWNrT3JWYWx1ZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdCk7XG59XG4vLyBUaGlzIHR5cGUgaXMgbm90IHJlY3Vyc2l2ZWx5IHRyYW5zZm9ybWVkIGZyb20gdGhlIG1ldGFtb2RlbCBjb250ZW50LCBhcyBzdWNoIHdlIGhhdmUgc29tZSB1Z2x5IHRoaW5ncyB0aGVyZVxudHlwZSBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5mdW5jdGlvbiBjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKGFwcGx5UGFyYW06IFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWwpOiBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsIHtcblx0bGV0IGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSBhcHBseVBhcmFtO1xuXHRpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRQYXRoXCIpKSB7XG5cdFx0YXBwbHlQYXJhbUNvbnZlcnRlZCA9IHtcblx0XHRcdHR5cGU6IFwiUGF0aFwiLFxuXHRcdFx0cGF0aDogYXBwbHlQYXJhbS4kUGF0aFxuXHRcdH0gYXMgUGF0aEFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz47XG5cdH0gZWxzZSBpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRJZlwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIklmXCIsXG5cdFx0XHRJZjogYXBwbHlQYXJhbS4kSWZcblx0XHR9IGFzIElmQW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPjtcblx0fSBlbHNlIGlmIChhcHBseVBhcmFtLmhhc093blByb3BlcnR5KFwiJEFwcGx5XCIpKSB7XG5cdFx0YXBwbHlQYXJhbUNvbnZlcnRlZCA9IHtcblx0XHRcdHR5cGU6IFwiQXBwbHlcIixcblx0XHRcdEZ1bmN0aW9uOiBhcHBseVBhcmFtLiRGdW5jdGlvbixcblx0XHRcdEFwcGx5OiBhcHBseVBhcmFtLiRBcHBseVxuXHRcdH0gYXMgQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+O1xuXHR9XG5cdHJldHVybiBhcHBseVBhcmFtQ29udmVydGVkO1xufVxuXG50eXBlIE9EYXRhRnVuY3Rpb24gPSBcIm9kYXRhLmNvbmNhdFwiIHwgXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIiB8IFwib2RhdGEudXJpRW5jb2RlXCI7XG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbkFwcGx5RXhwcmVzc2lvbihcblx0YXBwbHlFeHByZXNzaW9uOiBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz4sXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+IHtcblx0c3dpdGNoIChhcHBseUV4cHJlc3Npb24uRnVuY3Rpb24gYXMgT0RhdGFGdW5jdGlvbikge1xuXHRcdGNhc2UgXCJvZGF0YS5jb25jYXRcIjpcblx0XHRcdHJldHVybiBjb25jYXQoXG5cdFx0XHRcdC4uLmFwcGx5RXhwcmVzc2lvbi5BcHBseS5tYXAoKGFwcGx5UGFyYW0pID0+IHtcblx0XHRcdFx0XHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0XHRcdFx0Y29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhhcHBseVBhcmFtKSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxzdHJpbmc+LFxuXHRcdFx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdFx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0Y2FzZSBcIm9kYXRhLnVyaUVuY29kZVwiOlxuXHRcdFx0Y29uc3QgcGFyYW1ldGVyID0gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0XHRjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKFxuXHRcdFx0XHRcdGFwcGx5RXhwcmVzc2lvbi5BcHBseVswXSBhcyB1bmtub3duIGFzIFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWxcblx0XHRcdFx0KSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxzdHJpbmc+LFxuXHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0XHQpO1xuXHRcdFx0Ly8gVGhlIHNlY29uZCBwYXJhbWV0ZXIgZm9yIHVyaUVuY29kZSBpcyBhbHdheXMgYSBzdHJpbmcgc2luY2UgdGhlIHRhcmdldCBldmFsdWF0aW9uIGlzIGFnYWluc3QgYSBmb3JtYXRWYWx1ZSBjYWxsIGluIE9EYXRhVXRpbHMgd2hpY2ggZXhwZWN0IHRoZSB0YXJnZXQgdHlwZSBhcyBzZWNvbmQgcGFyYW1ldGVyXG5cdFx0XHRyZXR1cm4gZm4oXCJvZGF0YS51cmlFbmNvZGVcIiwgW3BhcmFtZXRlciwgXCJFZG0uU3RyaW5nXCJdLCB1bmRlZmluZWQsIHRydWUpO1xuXHRcdGNhc2UgXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIjpcblx0XHRcdGNvbnN0IHRlbXBsYXRlID0gYXBwbHlFeHByZXNzaW9uLkFwcGx5WzBdO1xuXHRcdFx0Y29uc3QgdGVtcGxhdGVQYXJhbXMgPSBhcHBseUV4cHJlc3Npb24uQXBwbHkuc2xpY2UoMSkgYXMgdW5rbm93biBhcyBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsW107XG5cdFx0XHRjb25zdCB0YXJnZXRPYmplY3Q6IFJlY29yZDxzdHJpbmcsIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPj4gPSB7fTtcblx0XHRcdHRlbXBsYXRlUGFyYW1zLmZvckVhY2goKGFwcGx5UGFyYW0pID0+IHtcblx0XHRcdFx0dGFyZ2V0T2JqZWN0W2FwcGx5UGFyYW0uJE5hbWUgYXMgc3RyaW5nXSA9IGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdFx0XHRjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKFxuXHRcdFx0XHRcdFx0YXBwbHlQYXJhbS4kTGFiZWxlZEVsZW1lbnQgYXMgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbFxuXHRcdFx0XHRcdCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8c3RyaW5nPixcblx0XHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0XHQpO1xuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gZm4oXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIiwgW3RlbXBsYXRlLCB0YXJnZXRPYmplY3RdLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xufVxuXG4vKipcbiAqIEdlbmVyaWMgaGVscGVyIGZvciB0aGUgY29tcGFyaXNvbiBvcGVyYXRpb25zIChlcXVhbCwgbm90RXF1YWwsIC4uLikuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gb3BlcmF0b3IgVGhlIG9wZXJhdG9yIHRvIGFwcGx5XG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZSBvZiB0aGUgb3BlcmF0b3JcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIG9wZXJhdG9yXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5mdW5jdGlvbiBjb21wYXJpc29uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0b3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcixcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGxlZnRFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShsZWZ0T3BlcmFuZCk7XG5cdGNvbnN0IHJpZ2h0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUocmlnaHRPcGVyYW5kKTtcblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24obGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoaXNDb25zdGFudChsZWZ0RXhwcmVzc2lvbikgJiYgaXNDb25zdGFudChyaWdodEV4cHJlc3Npb24pKSB7XG5cdFx0c3dpdGNoIChvcGVyYXRvcikge1xuXHRcdFx0Y2FzZSBcIiE9PVwiOlxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgIT09IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPT09XCI6XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHRcdGNhc2UgXCI8XCI6XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA8IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPD1cIjpcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlIDw9IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPlwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPiByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj49XCI6XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA+PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiQ29tcGFyaXNvblwiLFxuXHRcdFx0b3BlcmF0b3I6IG9wZXJhdG9yLFxuXHRcdFx0b3BlcmFuZDE6IGxlZnRFeHByZXNzaW9uLFxuXHRcdFx0b3BlcmFuZDI6IHJpZ2h0RXhwcmVzc2lvblxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBHZW5lcmljIGhlbHBlciBmb3IgdGhlIGxlbmd0aCBvZiBhbiBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBpbnB1dCBleHByZXNzaW9uIHBvaW50aW5nIHRvIGFuIGFycmF5XG4gKiBAcGFyYW0gY2hlY2tVbmRlZmluZWQgSXMgdGhlIGFycmF5IHBvdGVudGlhbGx5IHVuZGVmaW5lZFxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGxlbmd0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gbGVuZ3RoKFxuXHRleHByZXNzaW9uOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj4gfCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbixcblx0Y2hlY2tVbmRlZmluZWQgPSBmYWxzZVxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPG51bWJlcj4ge1xuXHRpZiAoZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJVbnJlc29sdmFibGVcIikge1xuXHRcdHJldHVybiBleHByZXNzaW9uO1xuXHR9XG5cdGlmICghY2hlY2tVbmRlZmluZWQpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiTGVuZ3RoXCIsXG5cdFx0XHRwYXRoSW5Nb2RlbDogZXhwcmVzc2lvblxuXHRcdH07XG5cdH1cblx0cmV0dXJuIGlmRWxzZShlcXVhbChleHByZXNzaW9uLCB1bmRlZmluZWQpLCAtMSwgbGVuZ3RoKGV4cHJlc3Npb24pKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImVxdWFsXCIgKD09PSkuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVxdWFsPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGxlZnRFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShsZWZ0T3BlcmFuZCk7XG5cdGNvbnN0IHJpZ2h0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUocmlnaHRPcGVyYW5kKTtcblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24obGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25zdGFudCh0cnVlKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHJlZHVjZShsZWZ0OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sIHJpZ2h0OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4gfCB1bmRlZmluZWQge1xuXHRcdGlmIChsZWZ0Ll90eXBlID09PSBcIkNvbXBhcmlzb25cIiAmJiBpc1RydWUocmlnaHQpKSB7XG5cdFx0XHQvLyBjb21wYXJlKGEsIGIpID09PSB0cnVlIH5+PiBjb21wYXJlKGEsIGIpXG5cdFx0XHRyZXR1cm4gbGVmdDtcblx0XHR9IGVsc2UgaWYgKGxlZnQuX3R5cGUgPT09IFwiQ29tcGFyaXNvblwiICYmIGlzRmFsc2UocmlnaHQpKSB7XG5cdFx0XHQvLyBjb21wYXJlKGEsIGIpID09PSBmYWxzZSB+fj4gIWNvbXBhcmUoYSwgYilcblx0XHRcdHJldHVybiBub3QobGVmdCk7XG5cdFx0fSBlbHNlIGlmIChsZWZ0Ll90eXBlID09PSBcIklmRWxzZVwiICYmIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdC5vblRydWUsIHJpZ2h0KSkge1xuXHRcdFx0Ly8gKGlmICh4KSB7IGEgfSBlbHNlIHsgYiB9KSA9PT0gYSB+fj4geCB8fCAoYiA9PT0gYSlcblx0XHRcdHJldHVybiBvcihsZWZ0LmNvbmRpdGlvbiwgZXF1YWwobGVmdC5vbkZhbHNlLCByaWdodCkpO1xuXHRcdH0gZWxzZSBpZiAobGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpKSB7XG5cdFx0XHQvLyAoaWYgKHgpIHsgYSB9IGVsc2UgeyBiIH0pID09PSBiIH5+PiAheCB8fCAoYSA9PT0gYilcblx0XHRcdHJldHVybiBvcihub3QobGVmdC5jb25kaXRpb24pLCBlcXVhbChsZWZ0Lm9uVHJ1ZSwgcmlnaHQpKTtcblx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0bGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJlxuXHRcdFx0aXNDb25zdGFudChsZWZ0Lm9uVHJ1ZSkgJiZcblx0XHRcdGlzQ29uc3RhbnQobGVmdC5vbkZhbHNlKSAmJlxuXHRcdFx0aXNDb25zdGFudChyaWdodCkgJiZcblx0XHRcdCFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25UcnVlLCByaWdodCkgJiZcblx0XHRcdCFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpXG5cdFx0KSB7XG5cdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdH1cblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cblx0Ly8gZXhwbG9pdCBzeW1tZXRyeTogYSA9PT0gYiA8fj4gYiA9PT0gYVxuXHRjb25zdCByZWR1Y2VkID0gcmVkdWNlKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pID8/IHJlZHVjZShyaWdodEV4cHJlc3Npb24sIGxlZnRFeHByZXNzaW9uKTtcblx0cmV0dXJuIHJlZHVjZWQgPz8gY29tcGFyaXNvbihcIj09PVwiLCBsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcIm5vdCBlcXVhbFwiICghPT0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3RFcXVhbDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gbm90KGVxdWFsKGxlZnRPcGVyYW5kLCByaWdodE9wZXJhbmQpKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImdyZWF0ZXIgb3IgZXF1YWxcIiAoPj0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncmVhdGVyT3JFcXVhbDxUIGV4dGVuZHMgRGVmaW5lZFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIGNvbXBhcmlzb24oXCI+PVwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImdyZWF0ZXIgdGhhblwiICg+KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JlYXRlclRoYW48VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPlwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImxlc3Mgb3IgZXF1YWxcIiAoPD0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsZXNzT3JFcXVhbDxUIGV4dGVuZHMgRGVmaW5lZFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIGNvbXBhcmlzb24oXCI8PVwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImxlc3MgdGhhblwiICg8KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gbGVzc1RoYW48VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPFwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBJZi10aGVuLWVsc2UgZXhwcmVzc2lvbi5cbiAqXG4gKiBFdmFsdWF0ZXMgdG8gb25UcnVlIGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIHRydWUsIGVsc2UgZXZhbHVhdGVzIHRvIG9uRmFsc2UuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gY29uZGl0aW9uIFRoZSBjb25kaXRpb24gdG8gZXZhbHVhdGVcbiAqIEBwYXJhbSBvblRydWUgRXhwcmVzc2lvbiByZXN1bHQgaWYgdGhlIGNvbmRpdGlvbiBldmFsdWF0ZXMgdG8gdHJ1ZVxuICogQHBhcmFtIG9uRmFsc2UgRXhwcmVzc2lvbiByZXN1bHQgaWYgdGhlIGNvbmRpdGlvbiBldmFsdWF0ZXMgdG8gZmFsc2VcbiAqIEByZXR1cm5zIFRoZSBleHByZXNzaW9uIHRoYXQgcmVwcmVzZW50cyB0aGlzIGNvbmRpdGlvbmFsIGNoZWNrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpZkVsc2U8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRjb25kaXRpb246IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPixcblx0b25UcnVlOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdG9uRmFsc2U6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0bGV0IGNvbmRpdGlvbkV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKGNvbmRpdGlvbik7XG5cdGxldCBvblRydWVFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShvblRydWUpO1xuXHRsZXQgb25GYWxzZUV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKG9uRmFsc2UpO1xuXG5cdC8vIHN3YXAgYnJhbmNoZXMgaWYgdGhlIGNvbmRpdGlvbiBpcyBhIG5lZ2F0aW9uXG5cdGlmIChjb25kaXRpb25FeHByZXNzaW9uLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0Ly8gaWZFbHNlKG5vdChYKSwgYSwgYikgLS0+IGlmRWxzZShYLCBiLCBhKVxuXHRcdFtvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbl0gPSBbb25GYWxzZUV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb25dO1xuXHRcdGNvbmRpdGlvbkV4cHJlc3Npb24gPSBub3QoY29uZGl0aW9uRXhwcmVzc2lvbik7XG5cdH1cblxuXHQvLyBpbmxpbmUgbmVzdGVkIGlmLWVsc2UgZXhwcmVzc2lvbnM6IG9uVHJ1ZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGlmRWxzZShYLCBhLCBiKSwgYykgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25UcnVlRXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24uY29uZGl0aW9uKSkge1xuXHRcdG9uVHJ1ZUV4cHJlc3Npb24gPSBvblRydWVFeHByZXNzaW9uLm9uVHJ1ZTtcblx0fVxuXG5cdC8vIGlubGluZSBuZXN0ZWQgaWYtZWxzZSBleHByZXNzaW9uczogb25GYWxzZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGEsIGlmRWxzZShYLCBiLCBjKSkgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25GYWxzZUV4cHJlc3Npb24uX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChjb25kaXRpb25FeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbi5jb25kaXRpb24pKSB7XG5cdFx0b25GYWxzZUV4cHJlc3Npb24gPSBvbkZhbHNlRXhwcmVzc2lvbi5vbkZhbHNlO1xuXHR9XG5cblx0Ly8gKGlmIHRydWUgdGhlbiBhIGVsc2UgYikgIH5+PiBhXG5cdC8vIChpZiBmYWxzZSB0aGVuIGEgZWxzZSBiKSB+fj4gYlxuXHRpZiAoaXNDb25zdGFudChjb25kaXRpb25FeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25kaXRpb25FeHByZXNzaW9uLnZhbHVlID8gb25UcnVlRXhwcmVzc2lvbiA6IG9uRmFsc2VFeHByZXNzaW9uO1xuXHR9XG5cblx0Ly8gaWYgKGlzQ29uc3RhbnRCb29sZWFuKG9uVHJ1ZUV4cHJlc3Npb24pIHx8IGlzQ29uc3RhbnRCb29sZWFuKG9uRmFsc2VFeHByZXNzaW9uKSkge1xuXHQvLyBcdHJldHVybiBvcihhbmQoY29uZGl0aW9uLCBvblRydWVFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pLCBhbmQobm90KGNvbmRpdGlvbiksIG9uRmFsc2VFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pKSBhcyBFeHByZXNzaW9uPFQ+XG5cdC8vIH1cblxuXHQvLyAoaWYgWCB0aGVuIGEgZWxzZSBhKSB+fj4gYVxuXHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb25UcnVlRXhwcmVzc2lvbjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBhIGVsc2UgZmFsc2Ugfn4+IFggJiYgYVxuXHRpZiAoaXNGYWxzZShvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gYW5kKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gYSBlbHNlIHRydWUgfn4+ICFYIHx8IGFcblx0aWYgKGlzVHJ1ZShvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb3Iobm90KGNvbmRpdGlvbkV4cHJlc3Npb24pLCBvblRydWVFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0Ly8gaWYgWCB0aGVuIGZhbHNlIGVsc2UgYSB+fj4gIVggJiYgYVxuXHRpZiAoaXNGYWxzZShvblRydWVFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBhbmQobm90KGNvbmRpdGlvbkV4cHJlc3Npb24pLCBvbkZhbHNlRXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4pIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiB0cnVlIGVsc2UgYSB+fj4gWCB8fCBhXG5cdGlmIChpc1RydWUob25UcnVlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb3IoY29uZGl0aW9uRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oY29uZGl0aW9uRXhwcmVzc2lvbiwgb25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKGNvbmRpdGlvbikgfHwgaXNDb21wbGV4VHlwZUV4cHJlc3Npb24ob25UcnVlKSB8fCBpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbihvbkZhbHNlKSkge1xuXHRcdGxldCBwYXRoSWR4ID0gMDtcblx0XHRjb25zdCBteUlmRWxzZUV4cHJlc3Npb24gPSBmb3JtYXRSZXN1bHQoW2NvbmRpdGlvbiwgb25UcnVlLCBvbkZhbHNlXSwgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2lmRWxzZVwiKTtcblx0XHRjb25zdCBhbGxQYXJ0cyA9IFtdO1xuXHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0bXlJZkVsc2VFeHByZXNzaW9uLFxuXHRcdFx0XCJQYXRoSW5Nb2RlbFwiLFxuXHRcdFx0KGNvbnN0YW50UGF0aDogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+KSA9PiB7XG5cdFx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKGAkJHtwYXRoSWR4Kyt9YCwgXCIkXCIpO1xuXHRcdFx0fSxcblx0XHRcdHRydWVcblx0XHQpO1xuXHRcdGFsbFBhcnRzLnVuc2hpZnQoY29uc3RhbnQoSlNPTi5zdHJpbmdpZnkobXlJZkVsc2VFeHByZXNzaW9uKSkpO1xuXHRcdHJldHVybiBmb3JtYXRSZXN1bHQoYWxsUGFydHMsIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNldmFsdWF0ZUNvbXBsZXhFeHByZXNzaW9uXCIsIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJJZkVsc2VcIixcblx0XHRjb25kaXRpb246IGNvbmRpdGlvbkV4cHJlc3Npb24sXG5cdFx0b25UcnVlOiBvblRydWVFeHByZXNzaW9uLFxuXHRcdG9uRmFsc2U6IG9uRmFsc2VFeHByZXNzaW9uXG5cdH07XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGN1cnJlbnQgZXhwcmVzc2lvbiBoYXMgYSByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgbW9kZWwgKHVuZGVmaW5lZCkuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gZXZhbHVhdGVcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGVyZSBpcyBhIHJlZmVyZW5jZSB0byB0aGUgZGVmYXVsdCBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+KTogYm9vbGVhbiB7XG5cdHN3aXRjaCAoZXhwcmVzc2lvbi5fdHlwZSkge1xuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRyZXR1cm4gZXhwcmVzc2lvbi5vcGVyYW5kcy5zb21lKGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQpO1xuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdFx0cmV0dXJuIGV4cHJlc3Npb24ubW9kZWxOYW1lID09PSB1bmRlZmluZWQ7XG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdHJldHVybiBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub3BlcmFuZDEpIHx8IGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vcGVyYW5kMik7XG5cdFx0Y2FzZSBcIklmRWxzZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0aGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLmNvbmRpdGlvbikgfHxcblx0XHRcdFx0aGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9uVHJ1ZSkgfHxcblx0XHRcdFx0aGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9uRmFsc2UpXG5cdFx0XHQpO1xuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRjYXNlIFwiVHJ1dGh5XCI6XG5cdFx0XHRyZXR1cm4gaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9wZXJhbmQpO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxuLy8gVGhpcyBpcyBvbmUgY2FzZSB3aGVyZSBhbnkgZG9lcyBtYWtlIHNlbnNlLi4uXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuZXhwb3J0IHR5cGUgRm48VD4gPSAoKC4uLnBhcmFtczogYW55KSA9PiBUIHwgUHJvbWlzZTxUPikgJiB7XG5cdF9fZnVuY3Rpb25OYW1lOiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIFdyYXBwZWRUdXBsZVxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4vLyBAdHMtaWdub3JlXG50eXBlIFdyYXBwZWRUdXBsZTxUPiA9IHsgW0sgaW4ga2V5b2YgVF06IFdyYXBwZWRUdXBsZTxUW0tdPiB8IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUW0tdPiB8IHVuZGVmaW5lZCB9O1xuXG4vLyBTbywgdGhpcyB3b3JrcyBidXQgSSBjYW5ub3QgZ2V0IGl0IHRvIGNvbXBpbGUgOkQsIGJ1dCBpdCBzdGlsbCBkb2VzIHdoYXQgaXMgZXhwZWN0ZWQuLi5cblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHJlZmVyZW5jZSBvciBhIGZ1bmN0aW9uIG5hbWUuXG4gKi9cbnR5cGUgRnVuY3Rpb25Pck5hbWU8VD4gPSBGbjxUPiB8IHN0cmluZztcblxuLyoqXG4gKiBGdW5jdGlvbiBwYXJhbWV0ZXJzLCBlaXRoZXIgZGVyaXZlZCBmcm9tIHRoZSBmdW5jdGlvbiBvciBhbiB1bnR5cGVkIGFycmF5LlxuICovXG50eXBlIEZ1bmN0aW9uUGFyYW1ldGVyczxULCBGIGV4dGVuZHMgRnVuY3Rpb25Pck5hbWU8VD4+ID0gRiBleHRlbmRzIEZuPFQ+ID8gUGFyYW1ldGVyczxGPiA6IHVua25vd25bXTtcblxuLyoqXG4gKiBDYWxscyBhIGZvcm1hdHRlciBmdW5jdGlvbiB0byBwcm9jZXNzIHRoZSBwYXJhbWV0ZXJzLlxuICogSWYgcmVxdWlyZUNvbnRleHQgaXMgc2V0IHRvIHRydWUgYW5kIG5vIGNvbnRleHQgaXMgcGFzc2VkIGEgZGVmYXVsdCBjb250ZXh0IHdpbGwgYmUgYWRkZWQgYXV0b21hdGljYWxseS5cbiAqXG4gKiBAdGVtcGxhdGUgVFxuICogQHRlbXBsYXRlIFVcbiAqIEBwYXJhbSBwYXJhbWV0ZXJzIFRoZSBsaXN0IG9mIHBhcmFtZXRlciB0aGF0IHNob3VsZCBtYXRjaCB0aGUgdHlwZSBhbmQgbnVtYmVyIG9mIHRoZSBmb3JtYXR0ZXIgZnVuY3Rpb25cbiAqIEBwYXJhbSBmb3JtYXR0ZXJGdW5jdGlvbiBUaGUgZnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIFtjb250ZXh0RW50aXR5VHlwZV0gSWYgbm8gcGFyYW1ldGVyIHJlZmVycyB0byB0aGUgY29udGV4dCB0aGVuIHdlIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGFkZCBhIHJlZmVyZW5jZSB0byB0aGUga2V5cyBmcm9tIHRoZSBlbnRpdHkgdHlwZS5cbiAqIEBwYXJhbSBbaWdub3JlQ29tcGxleFR5cGVdIFdoZXRoZXIgdG8gaWdub3JlIHRoZSB0cmFuc2dmb3JtYXRpb24gdG8gdGhlIFN0YW5kYXJkRm9ybWF0dGVyIG9yIG5vdFxuICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0UmVzdWx0PFQsIFUgZXh0ZW5kcyBGbjxUPj4oXG5cdHBhcmFtZXRlcnM6IFdyYXBwZWRUdXBsZTxQYXJhbWV0ZXJzPFU+Pixcblx0Zm9ybWF0dGVyRnVuY3Rpb246IFUgfCBzdHJpbmcsXG5cdGNvbnRleHRFbnRpdHlUeXBlPzogRW50aXR5VHlwZSxcblx0aWdub3JlQ29tcGxleFR5cGUgPSBmYWxzZVxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgcGFyYW1ldGVyRXhwcmVzc2lvbnMgPSAocGFyYW1ldGVycyBhcyBFeHByZXNzaW9uT3JQcmltaXRpdmU8UHJpbWl0aXZlVHlwZT5bXSkubWFwKHdyYXBQcmltaXRpdmUpO1xuXG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLnBhcmFtZXRlckV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGlmIChjb250ZXh0RW50aXR5VHlwZSkge1xuXHRcdC8vIE90aGVyd2lzZSwgaWYgdGhlIGNvbnRleHQgaXMgcmVxdWlyZWQgYW5kIG5vIGNvbnRleHQgaXMgcHJvdmlkZWQgbWFrZSBzdXJlIHRvIGFkZCB0aGUgZGVmYXVsdCBiaW5kaW5nXG5cdFx0aWYgKCFwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQpKSB7XG5cdFx0XHRjb250ZXh0RW50aXR5VHlwZS5rZXlzLmZvckVhY2goKGtleSkgPT4gcGFyYW1ldGVyRXhwcmVzc2lvbnMucHVzaChwYXRoSW5Nb2RlbChrZXkubmFtZSwgXCJcIikpKTtcblx0XHR9XG5cdH1cblx0bGV0IGZ1bmN0aW9uTmFtZSA9IFwiXCI7XG5cdGlmICh0eXBlb2YgZm9ybWF0dGVyRnVuY3Rpb24gPT09IFwic3RyaW5nXCIpIHtcblx0XHRmdW5jdGlvbk5hbWUgPSBmb3JtYXR0ZXJGdW5jdGlvbjtcblx0fSBlbHNlIHtcblx0XHRmdW5jdGlvbk5hbWUgPSBmb3JtYXR0ZXJGdW5jdGlvbi5fX2Z1bmN0aW9uTmFtZTtcblx0fVxuXHQvLyBGb3JtYXR0ZXJOYW1lIGNhbiBiZSBvZiBmb3JtYXQgc2FwLmZlLmNvcmUueHh4I21ldGhvZE5hbWUgdG8gaGF2ZSBtdWx0aXBsZSBmb3JtYXR0ZXIgaW4gb25lIGNsYXNzXG5cdGNvbnN0IFtmb3JtYXR0ZXJDbGFzcywgZm9ybWF0dGVyTmFtZV0gPSBmdW5jdGlvbk5hbWUuc3BsaXQoXCIjXCIpO1xuXG5cdC8vIEluIHNvbWUgY2FzZSB3ZSBhbHNvIGNhbm5vdCBjYWxsIGRpcmVjdGx5IGEgZnVuY3Rpb24gYmVjYXVzZSBvZiB0b28gY29tcGxleCBpbnB1dCwgaW4gdGhhdCBjYXNlIHdlIG5lZWQgdG8gY29udmVydCB0byBhIHNpbXBsZXIgZnVuY3Rpb24gY2FsbFxuXHRpZiAoXG5cdFx0IWlnbm9yZUNvbXBsZXhUeXBlICYmXG5cdFx0KHBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaXNDb21wbGV4VHlwZUV4cHJlc3Npb24pIHx8XG5cdFx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGlzQ29uY2F0RXhwcmVzc2lvbikgfHxcblx0XHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaXNJZkVsc2VFeHByZXNzaW9uKSlcblx0KSB7XG5cdFx0bGV0IHBhdGhJZHggPSAwO1xuXHRcdGNvbnN0IG15Rm9ybWF0RXhwcmVzc2lvbiA9IGZvcm1hdFJlc3VsdChwYXJhbWV0ZXJFeHByZXNzaW9ucywgZnVuY3Rpb25OYW1lLCB1bmRlZmluZWQsIHRydWUpO1xuXHRcdGNvbnN0IGFsbFBhcnRzID0gW107XG5cdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRteUZvcm1hdEV4cHJlc3Npb24sXG5cdFx0XHRcIlBhdGhJbk1vZGVsXCIsXG5cdFx0XHQoY29uc3RhbnRQYXRoOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj4pID0+IHtcblx0XHRcdFx0YWxsUGFydHMucHVzaChjb25zdGFudFBhdGgpO1xuXHRcdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwoYCQke3BhdGhJZHgrK31gLCBcIiRcIik7XG5cdFx0XHR9LFxuXHRcdFx0dHJ1ZVxuXHRcdCk7XG5cdFx0YWxsUGFydHMudW5zaGlmdChjb25zdGFudChKU09OLnN0cmluZ2lmeShteUZvcm1hdEV4cHJlc3Npb24pKSk7XG5cdFx0cmV0dXJuIGZvcm1hdFJlc3VsdChhbGxQYXJ0cywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2V2YWx1YXRlQ29tcGxleEV4cHJlc3Npb25cIiwgdW5kZWZpbmVkLCB0cnVlKTtcblx0fSBlbHNlIGlmICghIWZvcm1hdHRlck5hbWUgJiYgZm9ybWF0dGVyTmFtZS5sZW5ndGggPiAwKSB7XG5cdFx0cGFyYW1ldGVyRXhwcmVzc2lvbnMudW5zaGlmdChjb25zdGFudChmb3JtYXR0ZXJOYW1lKSk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkZvcm1hdHRlclwiLFxuXHRcdGZuOiBmb3JtYXR0ZXJDbGFzcyxcblx0XHRwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJFeHByZXNzaW9uc1xuXHR9O1xufVxuXG50eXBlIEJpbmRpbmdDb25zdHJhaW50cyA9IHtcblx0c2NhbGU/OiBudW1iZXI7XG5cdHByZWNpc2lvbj86IG51bWJlcjtcblx0bWF4TGVuZ3RoPzogbnVtYmVyO1xuXHRudWxsYWJsZT86IGJvb2xlYW47XG5cdG1pbmltdW0/OiBzdHJpbmc7XG5cdG1heGltdW0/OiBzdHJpbmc7XG5cdGlzRGlnaXRTZXF1ZW5jZT86IGJvb2xlYW47XG5cdFY0PzogYm9vbGVhbjtcbn07XG5leHBvcnQgZnVuY3Rpb24gc2V0VXBDb25zdHJhaW50cyh0YXJnZXRNYXBwaW5nOiBUeXBlTWFwcGluZ0RlZmluaXRpb24sIHByb3BlcnR5OiBQcm9wZXJ0eSB8IEFjdGlvblBhcmFtZXRlcik6IEJpbmRpbmdDb25zdHJhaW50cyB7XG5cdGNvbnN0IGNvbnN0cmFpbnRzOiBCaW5kaW5nQ29uc3RyYWludHMgPSB7fTtcblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy4kU2NhbGUgJiYgcHJvcGVydHkuc2NhbGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdGNvbnN0cmFpbnRzLnNjYWxlID0gcHJvcGVydHkuc2NhbGU7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy4kUHJlY2lzaW9uICYmIHByb3BlcnR5LnByZWNpc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0Y29uc3RyYWludHMucHJlY2lzaW9uID0gcHJvcGVydHkucHJlY2lzaW9uO1xuXHR9XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJE1heExlbmd0aCAmJiBwcm9wZXJ0eS5tYXhMZW5ndGggIT09IHVuZGVmaW5lZCkge1xuXHRcdGNvbnN0cmFpbnRzLm1heExlbmd0aCA9IHByb3BlcnR5Lm1heExlbmd0aDtcblx0fVxuXHRpZiAocHJvcGVydHkubnVsbGFibGUgPT09IGZhbHNlKSB7XG5cdFx0Y29uc3RyYWludHMubnVsbGFibGUgPSBmYWxzZTtcblx0fVxuXHRpZiAodGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LltcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtLyREZWNpbWFsXCJdICYmICFpc05hTihwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uVmFsaWRhdGlvbj8uTWluaW11bSkpIHtcblx0XHRjb25zdHJhaW50cy5taW5pbXVtID0gYCR7cHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1pbmltdW19YDtcblx0fVxuXHRpZiAodGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LltcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtLyREZWNpbWFsXCJdICYmICFpc05hTihwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uVmFsaWRhdGlvbj8uTWF4aW11bSkpIHtcblx0XHRjb25zdHJhaW50cy5tYXhpbXVtID0gYCR7cHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1heGltdW19YDtcblx0fVxuXHRpZiAoXG5cdFx0cHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNEaWdpdFNlcXVlbmNlICYmXG5cdFx0dGFyZ2V0TWFwcGluZy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmluZ1wiICYmXG5cdFx0dGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LltcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuSXNEaWdpdFNlcXVlbmNlXCJdXG5cdCkge1xuXHRcdGNvbnN0cmFpbnRzLmlzRGlnaXRTZXF1ZW5jZSA9IHRydWU7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy4kVjQpIHtcblx0XHRjb25zdHJhaW50cy5WNCA9IHRydWU7XG5cdH1cblx0cmV0dXJuIGNvbnN0cmFpbnRzO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgYmluZGluZyBleHByZXNzaW9uIGZvciB0aGUgcHJvcGVydHksIGFuZCBzZXRzIHVwIHRoZSBmb3JtYXRPcHRpb25zIGFuZCBjb25zdHJhaW50cy5cbiAqXG4gKiBAcGFyYW0gcHJvcGVydHkgVGhlIFByb3BlcnR5IGZvciB3aGljaCB3ZSBhcmUgc2V0dGluZyB1cCB0aGUgYmluZGluZ1xuICogQHBhcmFtIHByb3BlcnR5QmluZGluZ0V4cHJlc3Npb24gVGhlIEJpbmRpbmdFeHByZXNzaW9uIG9mIHRoZSBwcm9wZXJ0eSBhYm92ZS4gU2VydmVzIGFzIHRoZSBiYXNpcyB0byB3aGljaCBpbmZvcm1hdGlvbiBjYW4gYmUgYWRkZWRcbiAqIEBwYXJhbSBpZ25vcmVDb25zdHJhaW50cyBJZ25vcmUgY29uc3RyYWludHMgb2YgdGhlIHByb3BlcnR5XG4gKiBAcmV0dXJucyBUaGUgYmluZGluZyBleHByZXNzaW9uIGZvciB0aGUgcHJvcGVydHkgd2l0aCBmb3JtYXRPcHRpb25zIGFuZCBjb25zdHJhaW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0V2l0aFR5cGVJbmZvcm1hdGlvbjxUPihcblx0cHJvcGVydHk6IFByb3BlcnR5IHwgQWN0aW9uUGFyYW1ldGVyLFxuXHRwcm9wZXJ0eUJpbmRpbmdFeHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPixcblx0aWdub3JlQ29uc3RyYWludHMgPSBmYWxzZVxuKTogUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3Qgb3V0RXhwcmVzc2lvbjogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+ID0gcHJvcGVydHlCaW5kaW5nRXhwcmVzc2lvbiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj47XG5cdGlmIChwcm9wZXJ0eS5fdHlwZSAhPT0gXCJQcm9wZXJ0eVwiICYmIHByb3BlcnR5Ll90eXBlICE9PSBcIkFjdGlvblBhcmFtZXRlclwiKSB7XG5cdFx0cmV0dXJuIG91dEV4cHJlc3Npb247XG5cdH1cblx0Y29uc3QgdGFyZ2V0TWFwcGluZyA9IEVETV9UWVBFX01BUFBJTkdbcHJvcGVydHkudHlwZV07XG5cdGlmICghdGFyZ2V0TWFwcGluZykge1xuXHRcdHJldHVybiBvdXRFeHByZXNzaW9uO1xuXHR9XG5cdGlmICghb3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0ge307XG5cdH1cblx0b3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cyA9IHt9O1xuXG5cdG91dEV4cHJlc3Npb24udHlwZSA9IHRhcmdldE1hcHBpbmcudHlwZTtcblx0aWYgKCFpZ25vcmVDb25zdHJhaW50cykge1xuXHRcdG91dEV4cHJlc3Npb24uY29uc3RyYWludHMgPSBzZXRVcENvbnN0cmFpbnRzKHRhcmdldE1hcHBpbmcsIHByb3BlcnR5KTtcblx0fVxuXG5cdGlmIChcblx0XHQob3V0RXhwcmVzc2lvbj8udHlwZT8uaW5kZXhPZihcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludFwiKSA9PT0gMCAmJiBvdXRFeHByZXNzaW9uPy50eXBlICE9PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIpIHx8XG5cdFx0b3V0RXhwcmVzc2lvbj8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Eb3VibGVcIlxuXHQpIHtcblx0XHRvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucywge1xuXHRcdFx0cGFyc2VBc1N0cmluZzogZmFsc2Vcblx0XHR9KTtcblx0fVxuXHRpZiAob3V0RXhwcmVzc2lvbi50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmluZ1wiICYmIGlzUHJvcGVydHkocHJvcGVydHkpKSB7XG5cdFx0aWYgKCFvdXRFeHByZXNzaW9uLmNvbnN0cmFpbnRzPy5pc0RpZ2l0U2VxdWVuY2UgfHwgb3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8ubnVsbGFibGUgPT09IGZhbHNlKSB7XG5cdFx0XHRvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMucGFyc2VLZWVwc0VtcHR5U3RyaW5nID0gdHJ1ZTtcblx0XHR9XG5cdFx0Y29uc3QgZmlzY2FsVHlwZSA9IGdldEZpc2NhbFR5cGUocHJvcGVydHkpO1xuXHRcdGlmIChmaXNjYWxUeXBlKSB7XG5cdFx0XHRvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMuZmlzY2FsVHlwZSA9IGZpc2NhbFR5cGU7XG5cdFx0XHRvdXRFeHByZXNzaW9uLnR5cGUgPSBcInNhcC5mZS5jb3JlLnR5cGUuRmlzY2FsRGF0ZVwiO1xuXHRcdH1cblx0fVxuXHRjb25zdCB0eXBlc1N1cHBvcnRpbmdQYXJzZUVtcHR5VmFsdWVUb1plcm8gPSBbXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQxNlwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MzJcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIsXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TaW5nbGVcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRvdWJsZVwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRGVjaW1hbFwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuQnl0ZVwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU0J5dGVcIlxuXHRdO1xuXHRpZiAoXG5cdFx0b3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8ubnVsbGFibGUgPT09IGZhbHNlICYmXG5cdFx0b3V0RXhwcmVzc2lvbi50eXBlICYmXG5cdFx0dHlwZXNTdXBwb3J0aW5nUGFyc2VFbXB0eVZhbHVlVG9aZXJvLmluY2x1ZGVzKG91dEV4cHJlc3Npb24udHlwZSlcblx0KSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMsIHtcblx0XHRcdHBhcnNlRW1wdHlWYWx1ZVRvWmVybzogdHJ1ZVxuXHRcdH0pO1xuXHR9XG5cdGlmIChcblx0XHRvdXRFeHByZXNzaW9uLmNvbnN0cmFpbnRzPy5udWxsYWJsZSAhPT0gZmFsc2UgJiZcblx0XHQob3V0RXhwcmVzc2lvbi50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIgfHwgb3V0RXhwcmVzc2lvbi50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIilcblx0KSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMsIHtcblx0XHRcdGVtcHR5U3RyaW5nOiBcIlwiXG5cdFx0fSk7XG5cdH1cblxuXHRyZXR1cm4gb3V0RXhwcmVzc2lvbjtcbn1cblxuZXhwb3J0IGNvbnN0IGdldEZpc2NhbFR5cGUgPSBmdW5jdGlvbiAocHJvcGVydHk6IFByb3BlcnR5KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhcikge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxZZWFyO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFBlcmlvZCkge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxQZXJpb2Q7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhclBlcmlvZCkge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxZZWFyUGVyaW9kO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFF1YXJ0ZXIpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsUXVhcnRlcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxZZWFyUXVhcnRlcikge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxZZWFyUXVhcnRlcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxXZWVrKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFdlZWs7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhcldlZWspIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhcldlZWs7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRGF5T2ZGaXNjYWxZZWFyKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0RheU9mRmlzY2FsWWVhcjtcblx0fVxufTtcblxuLyoqXG4gKiBDYWxscyBhIGNvbXBsZXggdHlwZSB0byBwcm9jZXNzIHRoZSBwYXJhbWV0ZXJzLlxuICogSWYgcmVxdWlyZUNvbnRleHQgaXMgc2V0IHRvIHRydWUgYW5kIG5vIGNvbnRleHQgaXMgcGFzc2VkLCBhIGRlZmF1bHQgY29udGV4dCB3aWxsIGJlIGFkZGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0ZW1wbGF0ZSBVXG4gKiBAcGFyYW0gcGFyYW1ldGVycyBUaGUgbGlzdCBvZiBwYXJhbWV0ZXJzIHRoYXQgc2hvdWxkIG1hdGNoIHRoZSB0eXBlIGZvciB0aGUgY29tcGxleCB0eXBlPVxuICogQHBhcmFtIHR5cGUgVGhlIGNvbXBsZXggdHlwZSB0byB1c2VcbiAqIEBwYXJhbSBbY29udGV4dEVudGl0eVR5cGVdIFRoZSBjb250ZXh0IGVudGl0eSB0eXBlIHRvIGNvbnNpZGVyXG4gKiBAcGFyYW0gb0Zvcm1hdE9wdGlvbnNcbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFR5cGVJbmZvcm1hdGlvbjxULCBVIGV4dGVuZHMgRm48VD4+KFxuXHRwYXJhbWV0ZXJzOiBXcmFwcGVkVHVwbGU8UGFyYW1ldGVyczxVPj4sXG5cdHR5cGU6IHN0cmluZyxcblx0Y29udGV4dEVudGl0eVR5cGU/OiBFbnRpdHlUeXBlLFxuXHRvRm9ybWF0T3B0aW9ucz86IENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc1xuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4gfCBDb25zdGFudEV4cHJlc3Npb248VD4ge1xuXHRjb25zdCBwYXJhbWV0ZXJFeHByZXNzaW9ucyA9IChwYXJhbWV0ZXJzIGFzIEV4cHJlc3Npb25PclByaW1pdGl2ZTxQcmltaXRpdmVUeXBlPltdKS5tYXAod3JhcFByaW1pdGl2ZSk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLnBhcmFtZXRlckV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdC8vIElmIHRoZXJlIGlzIG9ubHkgb25lIHBhcmFtZXRlciBhbmQgaXQgaXMgYSBjb25zdGFudCBhbmQgd2UgZG9uJ3QgZXhwZWN0IHRoZSBjb250ZXh0IHRoZW4gcmV0dXJuIHRoZSBjb25zdGFudFxuXHRpZiAocGFyYW1ldGVyRXhwcmVzc2lvbnMubGVuZ3RoID09PSAxICYmIGlzQ29uc3RhbnQocGFyYW1ldGVyRXhwcmVzc2lvbnNbMF0pICYmICFjb250ZXh0RW50aXR5VHlwZSkge1xuXHRcdHJldHVybiBwYXJhbWV0ZXJFeHByZXNzaW9uc1swXSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHQvLyBPdGhlcndpc2UsIGlmIHRoZSBjb250ZXh0IGlzIHJlcXVpcmVkIGFuZCBubyBjb250ZXh0IGlzIHByb3ZpZGVkIG1ha2Ugc3VyZSB0byBhZGQgdGhlIGRlZmF1bHQgYmluZGluZ1xuXHRcdGlmICghcGFyYW1ldGVyRXhwcmVzc2lvbnMuc29tZShoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KSkge1xuXHRcdFx0Y29udGV4dEVudGl0eVR5cGUua2V5cy5mb3JFYWNoKChrZXkpID0+IHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2gocGF0aEluTW9kZWwoa2V5Lm5hbWUsIFwiXCIpKSk7XG5cdFx0fVxuXHR9XG5cdG9Gb3JtYXRPcHRpb25zID0gX2dldENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc0Zyb21GaXJzdFBhcmFtKHBhcmFtZXRlcnNbMF0sIG9Gb3JtYXRPcHRpb25zKTtcblxuXHRpZiAodHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Vbml0XCIpIHtcblx0XHRjb25zdCB1b21QYXRoID0gcGF0aEluTW9kZWwoXCIvIyNAQHJlcXVlc3RVbml0c09mTWVhc3VyZVwiKTtcblx0XHR1b21QYXRoLnRhcmdldFR5cGUgPSBcImFueVwiO1xuXHRcdHVvbVBhdGgubW9kZSA9IFwiT25lVGltZVwiO1xuXHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2godW9tUGF0aCk7XG5cdH0gZWxzZSBpZiAodHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5DdXJyZW5jeVwiKSB7XG5cdFx0Y29uc3QgY3VycmVuY3lQYXRoID0gcGF0aEluTW9kZWwoXCIvIyNAQHJlcXVlc3RDdXJyZW5jeUNvZGVzXCIpO1xuXHRcdGN1cnJlbmN5UGF0aC50YXJnZXRUeXBlID0gXCJhbnlcIjtcblx0XHRjdXJyZW5jeVBhdGgubW9kZSA9IFwiT25lVGltZVwiO1xuXHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2goY3VycmVuY3lQYXRoKTtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiQ29tcGxleFR5cGVcIixcblx0XHR0eXBlOiB0eXBlLFxuXHRcdGZvcm1hdE9wdGlvbnM6IG9Gb3JtYXRPcHRpb25zIHx8IHt9LFxuXHRcdHBhcmFtZXRlcnM6IHt9LFxuXHRcdGJpbmRpbmdQYXJhbWV0ZXJzOiBwYXJhbWV0ZXJFeHByZXNzaW9uc1xuXHR9O1xufVxuXG50eXBlIENvbXBsZXhUeXBlRm9ybWF0T3B0aW9ucyA9IHtcblx0c2hvd051bWJlcj86IGJvb2xlYW47XG5cdHNob3dNZWFzdXJlPzogYm9vbGVhbjtcblx0cGFyc2VBc1N0cmluZz86IGJvb2xlYW47XG5cdHBhcnNlS2VlcHNFbXB0eVN0cmluZz86IGJvb2xlYW47XG5cdGVtcHR5U3RyaW5nPzogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbDtcblx0c2hvd1RpbWU/OiBib29sZWFuO1xuXHRzaG93RGF0ZT86IGJvb2xlYW47XG5cdHNob3dUaW1lem9uZT86IGJvb2xlYW47XG59O1xuXG4vKipcbiAqIFByb2Nlc3MgdGhlIGZvcm1hdE9wdGlvbnMgZm9yIGEgY29tcGxleFR5cGUgYmFzZWQgb24gdGhlIGZpcnN0IHBhcmFtZXRlci5cbiAqXG4gKiBAcGFyYW0gcGFyYW0gVGhlIGZpcnN0IHBhcmFtZXRlciBvZiB0aGUgY29tcGxleCB0eXBlXG4gKiBAcGFyYW0gZm9ybWF0T3B0aW9ucyBJbml0aWFsIGZvcm1hdE9wdGlvbnNcbiAqIEByZXR1cm5zIFRoZSBtb2RpZmllZCBmb3JtYXRPcHRpb25zXG4gKi9cbmZ1bmN0aW9uIF9nZXRDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNGcm9tRmlyc3RQYXJhbTxULCBVIGV4dGVuZHMgRm48VD4+KFxuXHRwYXJhbTogUGFyYW1ldGVyczxVPixcblx0Zm9ybWF0T3B0aW9uczogdW5kZWZpbmVkIHwgQ29tcGxleFR5cGVGb3JtYXRPcHRpb25zXG4pOiBDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnMgfCB1bmRlZmluZWQge1xuXHQvLyBpZiBzaG93TWVhc3VyZSBpcyBzZXQgdG8gZmFsc2Ugd2Ugd2FudCB0byBub3QgcGFyc2UgYXMgc3RyaW5nIHRvIHNlZSB0aGUgMFxuXHQvLyB3ZSBkbyB0aGF0IGFsc28gZm9yIGFsbCBiaW5kaW5ncyBiZWNhdXNlIG90aGVyd2lzZSB0aGUgbWRjIEZpZWxkIGlzbid0IGVkaXRhYmxlXG5cdGlmIChcblx0XHQhKGZvcm1hdE9wdGlvbnMgJiYgZm9ybWF0T3B0aW9ucy5zaG93TnVtYmVyID09PSBmYWxzZSkgJiZcblx0XHQocGFyYW0/LnR5cGU/LmluZGV4T2YoXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnRcIikgPT09IDAgfHxcblx0XHRcdHBhcmFtPy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIiB8fFxuXHRcdFx0cGFyYW0/LnR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRG91YmxlXCIpXG5cdCkge1xuXHRcdGlmIChwYXJhbT8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiIHx8IHBhcmFtPy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIikge1xuXHRcdFx0Ly9zYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NCBkbyBub3Qgc3VwcG9ydCBwYXJzZUFzU3RyaW5nIGZhbHNlXG5cdFx0XHRmb3JtYXRPcHRpb25zID0gZm9ybWF0T3B0aW9ucz8uc2hvd01lYXN1cmUgPT09IGZhbHNlID8geyBzaG93TWVhc3VyZTogZmFsc2UgfSA6IHt9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3JtYXRPcHRpb25zID0gZm9ybWF0T3B0aW9ucz8uc2hvd01lYXN1cmUgPT09IGZhbHNlID8geyBwYXJzZUFzU3RyaW5nOiBmYWxzZSwgc2hvd01lYXN1cmU6IGZhbHNlIH0gOiB7IHBhcnNlQXNTdHJpbmc6IGZhbHNlIH07XG5cdFx0fVxuXHRcdGZvcm1hdE9wdGlvbnMuZW1wdHlTdHJpbmcgPSBudWxsO1xuXHR9XG5cdHJldHVybiBmb3JtYXRPcHRpb25zO1xufVxuLyoqXG4gKiBGdW5jdGlvbiBjYWxsLCBvcHRpb25hbGx5IHdpdGggYXJndW1lbnRzLlxuICpcbiAqIEBwYXJhbSBmdW5jIEZ1bmN0aW9uIG5hbWUgb3IgcmVmZXJlbmNlIHRvIGZ1bmN0aW9uXG4gKiBAcGFyYW0gcGFyYW1ldGVycyBBcmd1bWVudHNcbiAqIEBwYXJhbSBvbiBPYmplY3QgdG8gY2FsbCB0aGUgZnVuY3Rpb24gb25cbiAqIEBwYXJhbSBpc0Zvcm1hdHRpbmdGblxuICogQHJldHVybnMgRXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGZ1bmN0aW9uIGNhbGwgKG5vdCB0aGUgcmVzdWx0IG9mIHRoZSBmdW5jdGlvbiBjYWxsISlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZuPFQsIFUgZXh0ZW5kcyBGdW5jdGlvbk9yTmFtZTxUPj4oXG5cdGZ1bmM6IFUsXG5cdHBhcmFtZXRlcnM6IFdyYXBwZWRUdXBsZTxGdW5jdGlvblBhcmFtZXRlcnM8VCwgVT4+LFxuXHRvbj86IEV4cHJlc3Npb25PclByaW1pdGl2ZTxvYmplY3Q+LFxuXHRpc0Zvcm1hdHRpbmdGbiA9IGZhbHNlXG4pOiBGdW5jdGlvbkV4cHJlc3Npb248VD4ge1xuXHRjb25zdCBmdW5jdGlvbk5hbWUgPSB0eXBlb2YgZnVuYyA9PT0gXCJzdHJpbmdcIiA/IGZ1bmMgOiBmdW5jLl9fZnVuY3Rpb25OYW1lO1xuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkZ1bmN0aW9uXCIsXG5cdFx0b2JqOiBvbiAhPT0gdW5kZWZpbmVkID8gd3JhcFByaW1pdGl2ZShvbikgOiB1bmRlZmluZWQsXG5cdFx0Zm46IGZ1bmN0aW9uTmFtZSxcblx0XHRpc0Zvcm1hdHRpbmdGbjogaXNGb3JtYXR0aW5nRm4sXG5cdFx0cGFyYW1ldGVyczogKHBhcmFtZXRlcnMgYXMgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFByaW1pdGl2ZVR5cGU+W10pLm1hcCh3cmFwUHJpbWl0aXZlKVxuXHR9O1xufVxuXG4vKipcbiAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBhIGJpbmRpbmcgdmFsdWUgaXMgbnVsbCwgdW5kZWZpbmVkIG9yIGVtcHR5LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBBIEJvb2xlYW4gZXhwcmVzc2lvbiBldmFsdWF0aW5nIHRoZSBmYWN0IHRoYXQgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBlbXB0eVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGFCaW5kaW5nczogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+W10gPSBbXTtcblx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoZXhwcmVzc2lvbiwgXCJQYXRoSW5Nb2RlbFwiLCAoZXhwcikgPT4ge1xuXHRcdGFCaW5kaW5ncy5wdXNoKG9yKGVxdWFsKGV4cHIsIFwiXCIpLCBlcXVhbChleHByLCB1bmRlZmluZWQpLCBlcXVhbChleHByLCBudWxsKSkpO1xuXHRcdHJldHVybiBleHByO1xuXHR9KTtcblx0cmV0dXJuIGFuZCguLi5hQmluZGluZ3MpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29uY2F0KC4uLmluRXhwcmVzc2lvbnM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxzdHJpbmc+W10pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPiB7XG5cdGNvbnN0IGV4cHJlc3Npb25zID0gaW5FeHByZXNzaW9ucy5tYXAod3JhcFByaW1pdGl2ZSk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGlmIChleHByZXNzaW9ucy5ldmVyeShpc0NvbnN0YW50KSkge1xuXHRcdHJldHVybiBjb25zdGFudChcblx0XHRcdGV4cHJlc3Npb25zLnJlZHVjZSgoY29uY2F0ZW5hdGVkOiBzdHJpbmcsIHZhbHVlKSA9PiB7XG5cdFx0XHRcdGlmICh2YWx1ZS52YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnZhbHVlICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbmNhdGVuYXRlZCArIHZhbHVlLnZhbHVlLnRvU3RyaW5nKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbmNhdGVuYXRlZDtcblx0XHRcdH0sIFwiXCIpXG5cdFx0KTtcblx0fSBlbHNlIGlmIChleHByZXNzaW9ucy5zb21lKGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKSkge1xuXHRcdGxldCBwYXRoSWR4ID0gMDtcblx0XHRjb25zdCBteUNvbmNhdEV4cHJlc3Npb24gPSBmb3JtYXRSZXN1bHQoZXhwcmVzc2lvbnMsIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNjb25jYXRcIiwgdW5kZWZpbmVkLCB0cnVlKTtcblx0XHRjb25zdCBhbGxQYXJ0cyA9IFtdO1xuXHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KG15Q29uY2F0RXhwcmVzc2lvbiwgXCJQYXRoSW5Nb2RlbFwiLCAoY29uc3RhbnRQYXRoOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj4pID0+IHtcblx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChgJCR7cGF0aElkeCsrfWAsIFwiJFwiKTtcblx0XHR9KTtcblx0XHRhbGxQYXJ0cy51bnNoaWZ0KGNvbnN0YW50KEpTT04uc3RyaW5naWZ5KG15Q29uY2F0RXhwcmVzc2lvbikpKTtcblx0XHRyZXR1cm4gZm9ybWF0UmVzdWx0KGFsbFBhcnRzLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjZXZhbHVhdGVDb21wbGV4RXhwcmVzc2lvblwiLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiQ29uY2F0XCIsXG5cdFx0ZXhwcmVzc2lvbnM6IGV4cHJlc3Npb25zXG5cdH07XG59XG5cbnR5cGUgRXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248VCBleHRlbmRzIEV4cHJlc3Npb25UeXBlLCBWPiA9IFQgZXh0ZW5kcyBcIkNvbnN0YW50XCJcblx0PyBDb25zdGFudEV4cHJlc3Npb248Vj5cblx0OiBUIGV4dGVuZHMgXCJQYXRoSW5Nb2RlbFwiXG5cdD8gUGF0aEluTW9kZWxFeHByZXNzaW9uPFY+XG5cdDogVCBleHRlbmRzIFwiRnVuY3Rpb25cIlxuXHQ/IEZ1bmN0aW9uRXhwcmVzc2lvbjxWPlxuXHQ6IFQgZXh0ZW5kcyBcIlVucmVzb2x2YWJsZVwiXG5cdD8gVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb25cblx0OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Vj47XG5cbmV4cG9ydCB0eXBlIFRyYW5zZm9ybUZ1bmN0aW9uPFQsIFY+ID0gKGV4cHJlc3Npb25QYXJ0OiBUKSA9PiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Vj47XG5leHBvcnQgdHlwZSBFeHByZXNzaW9uVHlwZSA9IFBpY2s8QmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+LCBcIl90eXBlXCI+W1wiX3R5cGVcIl07XG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtUmVjdXJzaXZlbHk8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGUgfCB1bmtub3duLCBFVCBleHRlbmRzIEV4cHJlc3Npb25UeXBlPihcblx0aW5FeHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdGV4cHJlc3Npb25UeXBlOiBFVCxcblx0dHJhbnNmb3JtRnVuY3Rpb246IFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBUPiwgVD4sXG5cdGluY2x1ZGVBbGxFeHByZXNzaW9uID0gZmFsc2Vcbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4gPSBpbkV4cHJlc3Npb247XG5cdHN3aXRjaCAoZXhwcmVzc2lvbi5fdHlwZSkge1xuXHRcdGNhc2UgXCJGdW5jdGlvblwiOlxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRcdGV4cHJlc3Npb24ucGFyYW1ldGVycyA9IGV4cHJlc3Npb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT5cblx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkocGFyYW1ldGVyIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiwgZXhwcmVzc2lvblR5cGUsIHRyYW5zZm9ybUZ1bmN0aW9uLCBpbmNsdWRlQWxsRXhwcmVzc2lvbilcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29uY2F0XCI6XG5cdFx0XHRleHByZXNzaW9uLmV4cHJlc3Npb25zID0gZXhwcmVzc2lvbi5leHByZXNzaW9ucy5tYXAoKHN1YkV4cHJlc3Npb24pID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdHN1YkV4cHJlc3Npb24sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgc3RyaW5nPiwgc3RyaW5nPixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdFx0ZXhwcmVzc2lvbiA9IGNvbmNhdCguLi5leHByZXNzaW9uLmV4cHJlc3Npb25zKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdGV4cHJlc3Npb24uYmluZGluZ1BhcmFtZXRlcnMgPSBleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzLm1hcCgoYmluZGluZ1BhcmFtZXRlcikgPT5cblx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0YmluZGluZ1BhcmFtZXRlciBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJJZkVsc2VcIjpcblx0XHRcdGNvbnN0IG9uVHJ1ZSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRleHByZXNzaW9uLm9uVHJ1ZSxcblx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIHVua25vd24+LCB1bmtub3duPixcblx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdCk7XG5cdFx0XHRjb25zdCBvbkZhbHNlID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdGV4cHJlc3Npb24ub25GYWxzZSxcblx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIHVua25vd24+LCB1bmtub3duPixcblx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdCk7XG5cdFx0XHRsZXQgY29uZGl0aW9uID0gZXhwcmVzc2lvbi5jb25kaXRpb247XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uZGl0aW9uID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5jb25kaXRpb24sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgYm9vbGVhbj4sIGJvb2xlYW4+LFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRleHByZXNzaW9uID0gaWZFbHNlKGNvbmRpdGlvbiwgb25UcnVlLCBvbkZhbHNlKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZCA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24ub3BlcmFuZCxcblx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBib29sZWFuPiwgYm9vbGVhbj4sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KTtcblx0XHRcdFx0ZXhwcmVzc2lvbiA9IG5vdChvcGVyYW5kKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiVHJ1dGh5XCI6XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZHMgPSBleHByZXNzaW9uLm9wZXJhbmRzLm1hcCgob3BlcmFuZCkgPT5cblx0XHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRcdG9wZXJhbmQsXG5cdFx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIGJvb2xlYW4+LCBib29sZWFuPixcblx0XHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRleHByZXNzaW9uID1cblx0XHRcdFx0XHRleHByZXNzaW9uLm9wZXJhdG9yID09PSBcInx8XCJcblx0XHRcdFx0XHRcdD8gKG9yKC4uLm9wZXJhbmRzKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pXG5cdFx0XHRcdFx0XHQ6IChhbmQoLi4ub3BlcmFuZHMpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPik7XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29tcGFyaXNvblwiOlxuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmQxID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5vcGVyYW5kMSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KTtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZDIgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRleHByZXNzaW9uLm9wZXJhbmQyIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPixcblx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpO1xuXHRcdFx0XHRleHByZXNzaW9uID0gY29tcGFyaXNvbihleHByZXNzaW9uLm9wZXJhdG9yLCBvcGVyYW5kMSwgb3BlcmFuZDIpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdFx0Y29uc3QgY29uc3RhbnRWYWx1ZTogUmVjb3JkPHN0cmluZywgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+PiA9IGV4cHJlc3Npb24udmFsdWUgYXMgUmVjb3JkPFxuXHRcdFx0XHRzdHJpbmcsXG5cdFx0XHRcdEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPlxuXHRcdFx0Pjtcblx0XHRcdGlmICh0eXBlb2YgY29uc3RhbnRWYWx1ZSA9PT0gXCJvYmplY3RcIiAmJiBjb25zdGFudFZhbHVlKSB7XG5cdFx0XHRcdE9iamVjdC5rZXlzKGNvbnN0YW50VmFsdWUpLmZvckVhY2goKGtleSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0YW50VmFsdWVba2V5XSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdFx0Y29uc3RhbnRWYWx1ZVtrZXldLFxuXHRcdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCB1bmtub3duPiwgdW5rbm93bj4sXG5cdFx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRjYXNlIFwiRW1iZWRkZWRCaW5kaW5nXCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIjpcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHQvLyBEbyBub3RoaW5nXG5cdFx0XHRicmVhaztcblx0fVxuXHRpZiAoZXhwcmVzc2lvblR5cGUgPT09IGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRleHByZXNzaW9uID0gdHJhbnNmb3JtRnVuY3Rpb24oaW5FeHByZXNzaW9uIGFzIEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBUPik7XG5cdH1cblx0cmV0dXJuIGV4cHJlc3Npb247XG59XG5cbmV4cG9ydCB0eXBlIENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uID0gc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG5jb25zdCBuZWVkUGFyZW50aGVzaXMgPSBmdW5jdGlvbiA8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHI6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gKFxuXHRcdCFpc0NvbnN0YW50KGV4cHIpICYmXG5cdFx0IWlzUGF0aEluTW9kZWxFeHByZXNzaW9uKGV4cHIpICYmXG5cdFx0aXNCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24oZXhwcikgJiZcblx0XHRleHByLl90eXBlICE9PSBcIklmRWxzZVwiICYmXG5cdFx0ZXhwci5fdHlwZSAhPT0gXCJGdW5jdGlvblwiXG5cdCk7XG59O1xuXG4vKipcbiAqIENvbXBpbGVzIGEgY29uc3RhbnQgb2JqZWN0IHRvIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBleHByXG4gKiBAcGFyYW0gaXNOdWxsYWJsZVxuICogQHJldHVybnMgVGhlIGNvbXBpbGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiBjb21waWxlQ29uc3RhbnRPYmplY3QoZXhwcjogQ29uc3RhbnRFeHByZXNzaW9uPG9iamVjdD4sIGlzTnVsbGFibGUgPSBmYWxzZSk6IHN0cmluZyB7XG5cdGlmIChpc051bGxhYmxlICYmIE9iamVjdC5rZXlzKGV4cHIudmFsdWUpLmxlbmd0aCA9PT0gMCkge1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cdGNvbnN0IG9iamVjdHMgPSBleHByLnZhbHVlIGFzIFBsYWluRXhwcmVzc2lvbk9iamVjdDtcblx0Y29uc3QgcHJvcGVydGllczogc3RyaW5nW10gPSBbXTtcblx0T2JqZWN0LmtleXMob2JqZWN0cykuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdFx0Y29uc3QgdmFsdWUgPSBvYmplY3RzW2tleV07XG5cdFx0Y29uc3QgY2hpbGRSZXN1bHQgPSBjb21waWxlRXhwcmVzc2lvbih2YWx1ZSwgdHJ1ZSwgZmFsc2UsIGlzTnVsbGFibGUpO1xuXHRcdGlmIChjaGlsZFJlc3VsdCAmJiBjaGlsZFJlc3VsdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRwcm9wZXJ0aWVzLnB1c2goYCR7a2V5fTogJHtjaGlsZFJlc3VsdH1gKTtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4gYHske3Byb3BlcnRpZXMuam9pbihcIiwgXCIpfX1gO1xufVxuXG4vKipcbiAqIENvbXBpbGVzIGEgQ29uc3RhbnQgQmluZGluZyBFeHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmdcbiAqIEBwYXJhbSBpc051bGxhYmxlXG4gKiBAcGFyYW0gZG9Ob3RTdHJpbmdpZnlcbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVDb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGV4cHI6IENvbnN0YW50RXhwcmVzc2lvbjxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdGlzTnVsbGFibGU/OiBib29sZWFuLFxuXHRkb05vdFN0cmluZ2lmeT86IGZhbHNlXG4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjtcbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlQ29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByOiBDb25zdGFudEV4cHJlc3Npb248VD4sXG5cdGVtYmVkZGVkSW5CaW5kaW5nOiBib29sZWFuLFxuXHRpc051bGxhYmxlPzogYm9vbGVhbixcblx0ZG9Ob3RTdHJpbmdpZnk/OiB0cnVlXG4pOiBQcmltaXRpdmVUeXBlO1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVDb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGV4cHI6IENvbnN0YW50RXhwcmVzc2lvbjxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdGlzTnVsbGFibGUgPSBmYWxzZSxcblx0ZG9Ob3RTdHJpbmdpZnkgPSBmYWxzZVxuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24gfCBQcmltaXRpdmVUeXBlIHtcblx0aWYgKGV4cHIudmFsdWUgPT09IG51bGwpIHtcblx0XHRyZXR1cm4gZG9Ob3RTdHJpbmdpZnkgPyBudWxsIDogXCJudWxsXCI7XG5cdH1cblx0aWYgKGV4cHIudmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBkb05vdFN0cmluZ2lmeSA/IHVuZGVmaW5lZCA6IFwidW5kZWZpbmVkXCI7XG5cdH1cblx0aWYgKHR5cGVvZiBleHByLnZhbHVlID09PSBcIm9iamVjdFwiKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkoZXhwci52YWx1ZSkpIHtcblx0XHRcdGNvbnN0IGVudHJpZXMgPSBleHByLnZhbHVlLm1hcCgoZXhwcmVzc2lvbikgPT4gY29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdHJ1ZSkpO1xuXHRcdFx0cmV0dXJuIGBbJHtlbnRyaWVzLmpvaW4oXCIsIFwiKX1dYDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGNvbXBpbGVDb25zdGFudE9iamVjdChleHByIGFzIENvbnN0YW50RXhwcmVzc2lvbjxvYmplY3Q+LCBpc051bGxhYmxlKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoZW1iZWRkZWRJbkJpbmRpbmcpIHtcblx0XHRzd2l0Y2ggKHR5cGVvZiBleHByLnZhbHVlKSB7XG5cdFx0XHRjYXNlIFwibnVtYmVyXCI6XG5cdFx0XHRjYXNlIFwiYmlnaW50XCI6XG5cdFx0XHRjYXNlIFwiYm9vbGVhblwiOlxuXHRcdFx0XHRyZXR1cm4gZXhwci52YWx1ZS50b1N0cmluZygpO1xuXHRcdFx0Y2FzZSBcInN0cmluZ1wiOlxuXHRcdFx0XHRyZXR1cm4gYCcke2VzY2FwZVhtbEF0dHJpYnV0ZShleHByLnZhbHVlLnRvU3RyaW5nKCkpfSdgO1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0cmV0dXJuIFwiXCI7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBkb05vdFN0cmluZ2lmeSA/IGV4cHIudmFsdWUgOiBleHByLnZhbHVlLnRvU3RyaW5nKCk7XG5cdH1cbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGJpbmRpbmcgc3RyaW5nIGZvciBhIEJpbmRpbmcgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbkZvckJpbmRpbmcgVGhlIGV4cHJlc3Npb24gdG8gY29tcGlsZVxuICogQHBhcmFtIGVtYmVkZGVkSW5CaW5kaW5nIFdoZXRoZXIgdGhlIGV4cHJlc3Npb24gdG8gY29tcGlsZSBpcyBlbWJlZGRlZCBpbnRvIGFub3RoZXIgZXhwcmVzc2lvblxuICogQHBhcmFtIGVtYmVkZGVkU2VwYXJhdG9yIFRoZSBiaW5kaW5nIHZhbHVlIGV2YWx1YXRvciAoJCBvciAlIGRlcGVuZGluZyBvbiB3aGV0aGVyIHdlIHdhbnQgdG8gZm9yY2UgdGhlIHR5cGUgb3Igbm90KVxuICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgZXhwcmVzc2lvbiBiaW5kaW5nXG4gKi9cbmZ1bmN0aW9uIGNvbXBpbGVQYXRoSW5Nb2RlbEV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByZXNzaW9uRm9yQmluZGluZzogUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+LFxuXHRlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbixcblx0ZW1iZWRkZWRTZXBhcmF0b3I6IHN0cmluZ1xuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24ge1xuXHRpZiAoXG5cdFx0ZXhwcmVzc2lvbkZvckJpbmRpbmcudHlwZSB8fFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLnBhcmFtZXRlcnMgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy50YXJnZXRUeXBlIHx8XG5cdFx0ZXhwcmVzc2lvbkZvckJpbmRpbmcuZm9ybWF0T3B0aW9ucyB8fFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLmNvbnN0cmFpbnRzXG5cdCkge1xuXHRcdC8vIFRoaXMgaXMgbm93IGEgY29tcGxleCBiaW5kaW5nIGRlZmluaXRpb24sIGxldCdzIHByZXBhcmUgZm9yIGl0XG5cdFx0Y29uc3QgY29tcGxleEJpbmRpbmdEZWZpbml0aW9uID0ge1xuXHRcdFx0cGF0aDogY29tcGlsZVBhdGhJbk1vZGVsKGV4cHJlc3Npb25Gb3JCaW5kaW5nKSxcblx0XHRcdHR5cGU6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLnR5cGUsXG5cdFx0XHR0YXJnZXRUeXBlOiBleHByZXNzaW9uRm9yQmluZGluZy50YXJnZXRUeXBlLFxuXHRcdFx0cGFyYW1ldGVyczogZXhwcmVzc2lvbkZvckJpbmRpbmcucGFyYW1ldGVycyxcblx0XHRcdGZvcm1hdE9wdGlvbnM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLmZvcm1hdE9wdGlvbnMsXG5cdFx0XHRjb25zdHJhaW50czogZXhwcmVzc2lvbkZvckJpbmRpbmcuY29uc3RyYWludHNcblx0XHR9O1xuXHRcdGNvbnN0IG91dEJpbmRpbmcgPSBjb21waWxlRXhwcmVzc2lvbihjb21wbGV4QmluZGluZ0RlZmluaXRpb24sIGZhbHNlLCBmYWxzZSwgdHJ1ZSk7XG5cdFx0aWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0XHRyZXR1cm4gYCR7ZW1iZWRkZWRTZXBhcmF0b3J9JHtvdXRCaW5kaW5nfWA7XG5cdFx0fVxuXHRcdHJldHVybiBvdXRCaW5kaW5nO1xuXHR9IGVsc2UgaWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0cmV0dXJuIGAke2VtYmVkZGVkU2VwYXJhdG9yfXske2NvbXBpbGVQYXRoSW5Nb2RlbChleHByZXNzaW9uRm9yQmluZGluZyl9fWA7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGB7JHtjb21waWxlUGF0aEluTW9kZWwoZXhwcmVzc2lvbkZvckJpbmRpbmcpfX1gO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPik6IHN0cmluZyB7XG5cdGlmIChleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBgeyR7Y29tcGlsZVBhdGhQYXJhbWV0ZXIoZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVyc1swXSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4sIHRydWUpfSwgdHlwZTogJyR7XG5cdFx0XHRleHByZXNzaW9uLnR5cGVcblx0XHR9J31gO1xuXHR9XG5cblx0bGV0IG91dHB1dEVuZCA9IGBdLCB0eXBlOiAnJHtleHByZXNzaW9uLnR5cGV9J2A7XG5cdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLmZvcm1hdE9wdGlvbnMpKSB7XG5cdFx0b3V0cHV0RW5kICs9IGAsIGZvcm1hdE9wdGlvbnM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKX1gO1xuXHR9XG5cdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLnBhcmFtZXRlcnMpKSB7XG5cdFx0b3V0cHV0RW5kICs9IGAsIHBhcmFtZXRlcnM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKX1gO1xuXHR9XG5cdG91dHB1dEVuZCArPSBcIn1cIjtcblxuXHRyZXR1cm4gYHttb2RlOidUd29XYXknLCBwYXJ0czpbJHtleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzXG5cdFx0Lm1hcCgocGFyYW0pID0+IGNvbXBpbGVQYXRoUGFyYW1ldGVyKHBhcmFtIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPikpXG5cdFx0LmpvaW4oXCIsXCIpfSR7b3V0cHV0RW5kfWA7XG59XG5cbi8qKlxuICogV3JhcCB0aGUgY29tcGlsZWQgYmluZGluZyBzdHJpbmcgYXMgcmVxdWlyZWQgZGVwZW5kaW5nIG9uIGl0cyBjb250ZXh0LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBjb21waWxlZCBleHByZXNzaW9uXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmcgVHJ1ZSBpZiB0aGUgY29tcGlsZWQgZXhwcmVzc2lvbiBpcyB0byBiZSBlbWJlZGRlZCBpbiBhIGJpbmRpbmdcbiAqIEBwYXJhbSBwYXJlbnRoZXNpc1JlcXVpcmVkIFRydWUgaWYgdGhlIGVtYmVkZGVkIGJpbmRpbmcgbmVlZHMgdG8gYmUgd3JhcHBlZCBpbiBwYXJldGhlc2lzIHNvIHRoYXQgaXQgaXMgZXZhbHVhdGVkIGFzIG9uZVxuICogQHJldHVybnMgRmluYWxpemVkIGNvbXBpbGVkIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihcblx0ZXhwcmVzc2lvbjogc3RyaW5nLFxuXHRlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbixcblx0cGFyZW50aGVzaXNSZXF1aXJlZCA9IGZhbHNlXG4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiB7XG5cdGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdGlmIChwYXJlbnRoZXNpc1JlcXVpcmVkKSB7XG5cdFx0XHRyZXR1cm4gYCgke2V4cHJlc3Npb259KWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBleHByZXNzaW9uO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gYHs9ICR7ZXhwcmVzc2lvbn19YDtcblx0fVxufVxuXG4vKipcbiAqIENvbXBpbGUgYW4gZXhwcmVzc2lvbiBpbnRvIGFuIGV4cHJlc3Npb24gYmluZGluZy5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGVcbiAqIEBwYXJhbSBlbWJlZGRlZEluQmluZGluZyBXaGV0aGVyIHRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUgaXMgZW1iZWRkZWQgaW50byBhbm90aGVyIGV4cHJlc3Npb25cbiAqIEBwYXJhbSBrZWVwVGFyZ2V0VHlwZSBLZWVwIHRoZSB0YXJnZXQgdHlwZSBvZiB0aGUgZW1iZWRkZWQgYmluZGluZ3MgaW5zdGVhZCBvZiBjYXN0aW5nIHRoZW0gdG8gYW55XG4gKiBAcGFyYW0gaXNOdWxsYWJsZSBXaGV0aGVyIGJpbmRpbmcgZXhwcmVzc2lvbiBjYW4gcmVzb2x2ZSB0byBlbXB0eSBzdHJpbmcgb3Igbm90XG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uIGJpbmRpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0ZXhwcmVzc2lvbjogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRlbWJlZGRlZEluQmluZGluZyA9IGZhbHNlLFxuXHRrZWVwVGFyZ2V0VHlwZSA9IGZhbHNlLFxuXHRpc051bGxhYmxlID0gZmFsc2Vcbik6IENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIHtcblx0Y29uc3QgZXhwciA9IHdyYXBQcmltaXRpdmUoZXhwcmVzc2lvbik7XG5cdGNvbnN0IGVtYmVkZGVkU2VwYXJhdG9yID0ga2VlcFRhcmdldFR5cGUgPyBcIiRcIiA6IFwiJVwiO1xuXG5cdHN3aXRjaCAoZXhwci5fdHlwZSkge1xuXHRcdGNhc2UgXCJVbnJlc29sdmFibGVcIjpcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cblx0XHRjYXNlIFwiQ29uc3RhbnRcIjpcblx0XHRcdHJldHVybiBjb21waWxlQ29uc3RhbnQoZXhwciwgZW1iZWRkZWRJbkJpbmRpbmcsIGlzTnVsbGFibGUpO1xuXG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdFx0cmV0dXJuIGV4cHIucmVmIHx8IFwibnVsbFwiO1xuXG5cdFx0Y2FzZSBcIkZ1bmN0aW9uXCI6XG5cdFx0XHRsZXQgaGFzRW1iZWRkZWRGdW5jdGlvbkNhbGxPckJpbmRpbmcgPSBmYWxzZTtcblx0XHRcdGlmIChleHByLmlzRm9ybWF0dGluZ0ZuKSB7XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHIsXG5cdFx0XHRcdFx0XCJGdW5jdGlvblwiLFxuXHRcdFx0XHRcdChzdWJGbikgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKHN1YkZuICE9PSBleHByICYmIHN1YkZuLm9iaiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRcdGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHJldHVybiBzdWJGbjtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdHRydWVcblx0XHRcdFx0KTtcblx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcixcblx0XHRcdFx0XHRcIkNvbnN0YW50XCIsXG5cdFx0XHRcdFx0KHN1YkZuOiBDb25zdGFudEV4cHJlc3Npb248VD4pID0+IHtcblx0XHRcdFx0XHRcdGlmICgoc3ViRm4gYXMgdW5rbm93bikgIT09IGV4cHIgJiYgdHlwZW9mIHN1YkZuLnZhbHVlID09PSBcIm9iamVjdFwiKSB7XG5cdFx0XHRcdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KHN1YkZuLCBcIlBhdGhJbk1vZGVsXCIsIChzdWJTdWJGbikgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gc3ViU3ViRm47XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gc3ViRm47XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBhcmd1bWVudFN0cmluZyA9IGAke2V4cHIucGFyYW1ldGVycy5tYXAoKGFyZykgPT4gY29tcGlsZUV4cHJlc3Npb24oYXJnLCB0cnVlKSkuam9pbihcIiwgXCIpfWA7XG5cdFx0XHRsZXQgZm5DYWxsID1cblx0XHRcdFx0ZXhwci5vYmogPT09IHVuZGVmaW5lZFxuXHRcdFx0XHRcdD8gYCR7ZXhwci5mbn0oJHthcmd1bWVudFN0cmluZ30pYFxuXHRcdFx0XHRcdDogYCR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5vYmosIHRydWUpfS4ke2V4cHIuZm59KCR7YXJndW1lbnRTdHJpbmd9KWA7XG5cdFx0XHRpZiAoIWVtYmVkZGVkSW5CaW5kaW5nICYmIGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nKSB7XG5cdFx0XHRcdGZuQ2FsbCA9IGB7PSAke2ZuQ2FsbH19YDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmbkNhbGw7XG5cblx0XHRjYXNlIFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiOlxuXHRcdFx0cmV0dXJuIGVtYmVkZGVkSW5CaW5kaW5nID8gYCgke2V4cHIudmFsdWUuc3Vic3RyaW5nKDIsIGV4cHIudmFsdWUubGVuZ3RoIC0gMSl9KWAgOiBgJHtleHByLnZhbHVlfWA7XG5cblx0XHRjYXNlIFwiRW1iZWRkZWRCaW5kaW5nXCI6XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgJHtlbWJlZGRlZFNlcGFyYXRvcn0ke2V4cHIudmFsdWV9YCA6IGAke2V4cHIudmFsdWV9YDtcblxuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdFx0cmV0dXJuIGNvbXBpbGVQYXRoSW5Nb2RlbEV4cHJlc3Npb24oZXhwciwgZW1iZWRkZWRJbkJpbmRpbmcsIGVtYmVkZGVkU2VwYXJhdG9yKTtcblxuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRjb25zdCBjb21wYXJpc29uRXhwcmVzc2lvbiA9IGNvbXBpbGVDb21wYXJpc29uRXhwcmVzc2lvbihleHByKTtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oY29tcGFyaXNvbkV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nKTtcblxuXHRcdGNhc2UgXCJJZkVsc2VcIjpcblx0XHRcdGNvbnN0IGlmRWxzZUV4cHJlc3Npb24gPSBgJHtjb21waWxlRXhwcmVzc2lvbihleHByLmNvbmRpdGlvbiwgdHJ1ZSl9ID8gJHtjb21waWxlRXhwcmVzc2lvbihcblx0XHRcdFx0ZXhwci5vblRydWUsXG5cdFx0XHRcdHRydWUsXG5cdFx0XHRcdGtlZXBUYXJnZXRUeXBlXG5cdFx0XHQpfSA6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5vbkZhbHNlLCB0cnVlLCBrZWVwVGFyZ2V0VHlwZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oaWZFbHNlRXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcsIHRydWUpO1xuXG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0Y29uc3Qgc2V0RXhwcmVzc2lvbiA9IGV4cHIub3BlcmFuZHMubWFwKChvcGVyYW5kKSA9PiBjb21waWxlRXhwcmVzc2lvbihvcGVyYW5kLCB0cnVlKSkuam9pbihgICR7ZXhwci5vcGVyYXRvcn0gYCk7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKHNldEV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nLCB0cnVlKTtcblxuXHRcdGNhc2UgXCJDb25jYXRcIjpcblx0XHRcdGNvbnN0IGNvbmNhdEV4cHJlc3Npb24gPSBleHByLmV4cHJlc3Npb25zXG5cdFx0XHRcdC5tYXAoKG5lc3RlZEV4cHJlc3Npb24pID0+IGNvbXBpbGVFeHByZXNzaW9uKG5lc3RlZEV4cHJlc3Npb24sIHRydWUsIHRydWUpKVxuXHRcdFx0XHQuam9pbihcIiArIFwiKTtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oY29uY2F0RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIkxlbmd0aFwiOlxuXHRcdFx0Y29uc3QgbGVuZ3RoRXhwcmVzc2lvbiA9IGAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIucGF0aEluTW9kZWwsIHRydWUpfS5sZW5ndGhgO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihsZW5ndGhFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRjb25zdCBub3RFeHByZXNzaW9uID0gYCEke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub3BlcmFuZCwgdHJ1ZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24obm90RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0Y29uc3QgdHJ1dGh5RXhwcmVzc2lvbiA9IGAhISR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5vcGVyYW5kLCB0cnVlKX1gO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbih0cnV0aHlFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRjb25zdCBmb3JtYXR0ZXJFeHByZXNzaW9uID0gY29tcGlsZUZvcm1hdHRlckV4cHJlc3Npb24oZXhwcik7XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgJCR7Zm9ybWF0dGVyRXhwcmVzc2lvbn1gIDogZm9ybWF0dGVyRXhwcmVzc2lvbjtcblxuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0Y29uc3QgY29tcGxleFR5cGVFeHByZXNzaW9uID0gY29tcGlsZUNvbXBsZXhUeXBlRXhwcmVzc2lvbihleHByKTtcblx0XHRcdHJldHVybiBlbWJlZGRlZEluQmluZGluZyA/IGAkJHtjb21wbGV4VHlwZUV4cHJlc3Npb259YCA6IGNvbXBsZXhUeXBlRXhwcmVzc2lvbjtcblxuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gXCJcIjtcblx0fVxufVxuXG4vKipcbiAqIENvbXBpbGUgYSBjb21wYXJpc29uIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGNvbXBhcmlzb24gZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBleHByZXNzaW9uLiBOZWVkcyB3cmFwcGluZyBiZWZvcmUgaXQgY2FuIGJlIHVzZWQgYXMgYW4gZXhwcmVzc2lvbiBiaW5kaW5nLlxuICovXG5mdW5jdGlvbiBjb21waWxlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbjogQ29tcGFyaXNvbkV4cHJlc3Npb24pOiBzdHJpbmcge1xuXHRmdW5jdGlvbiBjb21waWxlT3BlcmFuZChvcGVyYW5kOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiB7XG5cdFx0Y29uc3QgY29tcGlsZWRPcGVyYW5kID0gY29tcGlsZUV4cHJlc3Npb24ob3BlcmFuZCwgdHJ1ZSkgPz8gXCJ1bmRlZmluZWRcIjtcblx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGNvbXBpbGVkT3BlcmFuZCwgdHJ1ZSwgbmVlZFBhcmVudGhlc2lzKG9wZXJhbmQpKTtcblx0fVxuXG5cdHJldHVybiBgJHtjb21waWxlT3BlcmFuZChleHByZXNzaW9uLm9wZXJhbmQxKX0gJHtleHByZXNzaW9uLm9wZXJhdG9yfSAke2NvbXBpbGVPcGVyYW5kKGV4cHJlc3Npb24ub3BlcmFuZDIpfWA7XG59XG5cbi8qKlxuICogQ29tcGlsZSBhIGZvcm1hdHRlciBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBmb3JtYXR0ZXIgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBleHByZXNzaW9uLlxuICovXG5mdW5jdGlvbiBjb21waWxlRm9ybWF0dGVyRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oZXhwcmVzc2lvbjogRm9ybWF0dGVyRXhwcmVzc2lvbjxUPik6IHN0cmluZyB7XG5cdGlmIChleHByZXNzaW9uLnBhcmFtZXRlcnMubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIGB7JHtjb21waWxlUGF0aFBhcmFtZXRlcihleHByZXNzaW9uLnBhcmFtZXRlcnNbMF0gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+LCB0cnVlKX0sIGZvcm1hdHRlcjogJyR7XG5cdFx0XHRleHByZXNzaW9uLmZuXG5cdFx0fSd9YDtcblx0fSBlbHNlIHtcblx0XHRjb25zdCBwYXJ0cyA9IGV4cHJlc3Npb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG5cdFx0XHRpZiAocGFyYW0uX3R5cGUgPT09IFwiQ29tcGxleFR5cGVcIikge1xuXHRcdFx0XHRyZXR1cm4gY29tcGlsZUNvbXBsZXhUeXBlRXhwcmVzc2lvbihwYXJhbSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gY29tcGlsZVBhdGhQYXJhbWV0ZXIocGFyYW0gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gYHtwYXJ0czogWyR7cGFydHMuam9pbihcIiwgXCIpfV0sIGZvcm1hdHRlcjogJyR7ZXhwcmVzc2lvbi5mbn0nfWA7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIHRoZSBwYXRoIHBhcmFtZXRlciBvZiBhIGZvcm1hdHRlciBjYWxsLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBiaW5kaW5nIHBhcnQgdG8gZXZhbHVhdGVcbiAqIEBwYXJhbSBzaW5nbGVQYXRoIFdoZXRoZXIgdGhlcmUgaXMgb25lIG9yIG11bHRpcGxlIHBhdGggdG8gY29uc2lkZXJcbiAqIEByZXR1cm5zIFRoZSBzdHJpbmcgc25pcHBldCB0byBpbmNsdWRlIGluIHRoZSBvdmVyYWxsIGJpbmRpbmcgZGVmaW5pdGlvblxuICovXG5mdW5jdGlvbiBjb21waWxlUGF0aFBhcmFtZXRlcihleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4sIHNpbmdsZVBhdGggPSBmYWxzZSk6IHN0cmluZyB7XG5cdGxldCBvdXRWYWx1ZSA9IFwiXCI7XG5cdGlmIChleHByZXNzaW9uLl90eXBlID09PSBcIkNvbnN0YW50XCIpIHtcblx0XHRpZiAoZXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHQvLyBTcGVjaWFsIGNhc2Ugb3RoZXJ3aXNlIHRoZSBKU1Rva2VuaXplciBjb21wbGFpbnMgYWJvdXQgaW5jb3JyZWN0IGNvbnRlbnRcblx0XHRcdG91dFZhbHVlID0gYHZhbHVlOiAndW5kZWZpbmVkJ2A7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG91dFZhbHVlID0gYHZhbHVlOiAke2NvbXBpbGVDb25zdGFudChleHByZXNzaW9uLCB0cnVlKX1gO1xuXHRcdH1cblx0fSBlbHNlIGlmIChleHByZXNzaW9uLl90eXBlID09PSBcIlBhdGhJbk1vZGVsXCIpIHtcblx0XHRvdXRWYWx1ZSA9IGBwYXRoOiAnJHtjb21waWxlUGF0aEluTW9kZWwoZXhwcmVzc2lvbil9J2A7XG5cblx0XHRvdXRWYWx1ZSArPSBleHByZXNzaW9uLnR5cGUgPyBgLCB0eXBlOiAnJHtleHByZXNzaW9uLnR5cGV9J2AgOiBgLCB0YXJnZXRUeXBlOiAnYW55J2A7XG5cdFx0aWYgKGV4cHJlc3Npb24ubW9kZSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgbW9kZTogJyR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5tb2RlKX0nYDtcblx0XHR9XG5cdFx0aWYgKGhhc0VsZW1lbnRzKGV4cHJlc3Npb24uY29uc3RyYWludHMpKSB7XG5cdFx0XHRvdXRWYWx1ZSArPSBgLCBjb25zdHJhaW50czogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLmNvbnN0cmFpbnRzKX1gO1xuXHRcdH1cblx0XHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgZm9ybWF0T3B0aW9uczogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLmZvcm1hdE9wdGlvbnMpfWA7XG5cdFx0fVxuXHRcdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLnBhcmFtZXRlcnMpKSB7XG5cdFx0XHRvdXRWYWx1ZSArPSBgLCBwYXJhbWV0ZXJzOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ucGFyYW1ldGVycyl9YDtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblx0cmV0dXJuIHNpbmdsZVBhdGggPyBvdXRWYWx1ZSA6IGB7JHtvdXRWYWx1ZX19YDtcbn1cblxuZnVuY3Rpb24gaGFzRWxlbWVudHMob2JqOiBvYmplY3QgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcblx0cmV0dXJuICEhb2JqICYmIE9iamVjdC5rZXlzKG9iaikubGVuZ3RoID4gMDtcbn1cblxuLyoqXG4gKiBDb21waWxlIGEgYmluZGluZyBleHByZXNzaW9uIHBhdGguXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gY29tcGlsZS5cbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBwYXRoLlxuICovXG5mdW5jdGlvbiBjb21waWxlUGF0aEluTW9kZWw8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPik6IHN0cmluZyB7XG5cdHJldHVybiBgJHtleHByZXNzaW9uLm1vZGVsTmFtZSA/IGV4cHJlc3Npb24ubW9kZWxOYW1lICsgXCI+XCIgOiBcIlwifSR7ZXhwcmVzc2lvbi5wYXRofWA7XG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUFBO0FBQUE7Ozs7Ozs7RUFpTk8sTUFBTUEs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