@sapui5/sap.fe.core 1.100.0 → 1.102.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 (295) hide show
  1. package/package.json +4 -4
  2. package/src/sap/fe/core/.library +2 -3
  3. package/src/sap/fe/core/AppComponent.js +23 -30
  4. package/src/sap/fe/core/AppComponent.ts +35 -40
  5. package/src/sap/fe/core/AppStateHandler.js +8 -8
  6. package/src/sap/fe/core/AppStateHandler.ts +11 -11
  7. package/src/sap/fe/core/BaseController.js +9 -9
  8. package/src/sap/fe/core/BaseController.ts +3 -4
  9. package/src/sap/fe/core/CommonUtils.js +122 -101
  10. package/src/sap/fe/core/CommonUtils.ts +239 -193
  11. package/src/sap/fe/core/ExtensionAPI.js +12 -13
  12. package/src/sap/fe/core/ExtensionAPI.ts +21 -31
  13. package/src/sap/fe/core/PageController.js +19 -13
  14. package/src/sap/fe/core/PageController.ts +40 -34
  15. package/src/sap/fe/core/TemplateComponent.js +198 -123
  16. package/src/sap/fe/core/TemplateComponent.ts +109 -121
  17. package/src/sap/fe/core/TemplateModel.js +7 -9
  18. package/src/sap/fe/core/TemplateModel.ts +3 -3
  19. package/src/sap/fe/core/buildingBlocks/AttributeModel.js +60 -0
  20. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
  21. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
  22. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
  23. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +935 -0
  24. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +837 -0
  25. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
  26. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
  27. package/src/sap/fe/core/{BusyLocker.js → controllerextensions/BusyLocker.js} +1 -1
  28. package/src/sap/fe/core/{BusyLocker.ts → controllerextensions/BusyLocker.ts} +7 -7
  29. package/src/sap/fe/core/controllerextensions/EditFlow.js +660 -288
  30. package/src/sap/fe/core/controllerextensions/EditFlow.ts +513 -331
  31. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +11 -11
  32. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +6 -7
  33. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +43 -25
  34. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +132 -103
  35. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +16 -16
  36. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +64 -55
  37. package/src/sap/fe/core/controllerextensions/InternalRouting.js +166 -99
  38. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +187 -149
  39. package/src/sap/fe/core/controllerextensions/KPIManagement.js +14 -14
  40. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +12 -11
  41. package/src/sap/fe/core/controllerextensions/MassEdit.js +13 -12
  42. package/src/sap/fe/core/controllerextensions/MassEdit.ts +22 -22
  43. package/src/sap/fe/core/controllerextensions/MessageHandler.js +14 -26
  44. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +20 -30
  45. package/src/sap/fe/core/controllerextensions/PageReady.js +25 -23
  46. package/src/sap/fe/core/controllerextensions/PageReady.ts +49 -47
  47. package/src/sap/fe/core/controllerextensions/Paginator.js +24 -15
  48. package/src/sap/fe/core/controllerextensions/Paginator.ts +35 -20
  49. package/src/sap/fe/core/controllerextensions/Placeholder.js +10 -10
  50. package/src/sap/fe/core/controllerextensions/Placeholder.ts +12 -14
  51. package/src/sap/fe/core/controllerextensions/Routing.js +11 -11
  52. package/src/sap/fe/core/controllerextensions/Routing.ts +12 -13
  53. package/src/sap/fe/core/controllerextensions/Share.js +34 -16
  54. package/src/sap/fe/core/controllerextensions/Share.ts +50 -32
  55. package/src/sap/fe/core/controllerextensions/SideEffects.js +15 -15
  56. package/src/sap/fe/core/controllerextensions/SideEffects.ts +64 -65
  57. package/src/sap/fe/core/controllerextensions/ViewState.js +27 -31
  58. package/src/sap/fe/core/controllerextensions/ViewState.ts +103 -102
  59. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +105 -0
  60. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +98 -0
  61. package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.js +360 -0
  62. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/ActivitySync.ts +90 -132
  63. package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.js +146 -0
  64. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/CollaborationCommon.ts +18 -8
  65. package/src/sap/fe/core/controllerextensions/collaboration/Manage.js +264 -0
  66. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/Manage.ts +35 -33
  67. package/src/sap/fe/core/controllerextensions/collaboration/ManageDialog.fragment.xml +100 -0
  68. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/UserDetails.fragment.xml +5 -7
  69. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +1584 -0
  70. package/src/sap/fe/core/{TransactionHelper.ts → controllerextensions/editFlow/TransactionHelper.ts} +190 -159
  71. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +780 -0
  72. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/draft.ts +329 -76
  73. package/src/sap/fe/core/controllerextensions/editFlow/operations.js +1149 -0
  74. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/operations.ts +169 -97
  75. package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +190 -0
  76. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/sticky.ts +76 -12
  77. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +592 -0
  78. package/src/sap/fe/core/{actions → controllerextensions/messageHandler}/messageHandling.ts +83 -60
  79. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +940 -0
  80. package/src/sap/fe/core/{RouterProxy.ts → controllerextensions/routing/RouterProxy.ts} +52 -36
  81. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +21 -18
  82. package/src/sap/fe/core/controls/Any.js +28 -0
  83. package/src/sap/fe/core/controls/Any.ts +30 -0
  84. package/src/sap/fe/core/controls/CommandExecution.js +50 -16
  85. package/src/sap/fe/core/controls/CommandExecution.ts +31 -22
  86. package/src/sap/fe/core/controls/ConditionalWrapper.js +136 -65
  87. package/src/sap/fe/core/controls/ConditionalWrapper.ts +49 -58
  88. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +371 -0
  89. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +282 -0
  90. package/src/sap/fe/core/controls/CustomQuickViewPage.js +74 -36
  91. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +23 -32
  92. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +52 -5
  93. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +127 -67
  94. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +127 -67
  95. package/src/sap/fe/core/controls/FieldWrapper.js +171 -87
  96. package/src/sap/fe/core/controls/FieldWrapper.ts +69 -80
  97. package/src/sap/fe/core/controls/FileWrapper.js +360 -0
  98. package/src/sap/fe/core/controls/FileWrapper.ts +202 -0
  99. package/src/sap/fe/core/controls/FilterBar.js +154 -119
  100. package/src/sap/fe/core/controls/FilterBar.ts +128 -123
  101. package/src/sap/fe/core/controls/FormElementWrapper.js +102 -37
  102. package/src/sap/fe/core/controls/FormElementWrapper.ts +43 -35
  103. package/src/sap/fe/core/controls/MassEditSelect.js +33 -0
  104. package/src/sap/fe/core/controls/MassEditSelect.ts +45 -0
  105. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +111 -89
  106. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +86 -82
  107. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +242 -193
  108. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +211 -204
  109. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +152 -116
  110. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +105 -105
  111. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +2 -2
  112. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +23 -28
  113. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +41 -81
  114. package/src/sap/fe/core/controls/massEdit/MassEditField.fragment.xml +107 -0
  115. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +550 -35
  116. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +604 -35
  117. package/src/sap/fe/core/converters/ManifestSettings.js +3 -1
  118. package/src/sap/fe/core/converters/ManifestSettings.ts +9 -2
  119. package/src/sap/fe/core/converters/MetaModelConverter.js +11 -40
  120. package/src/sap/fe/core/converters/MetaModelConverter.ts +56 -84
  121. package/src/sap/fe/core/converters/annotations/DataField.js +20 -5
  122. package/src/sap/fe/core/converters/annotations/DataField.ts +27 -6
  123. package/src/sap/fe/core/converters/controls/Common/Action.js +14 -21
  124. package/src/sap/fe/core/converters/controls/Common/Action.ts +23 -28
  125. package/src/sap/fe/core/converters/controls/Common/Chart.js +17 -10
  126. package/src/sap/fe/core/converters/controls/Common/Chart.ts +20 -14
  127. package/src/sap/fe/core/converters/controls/Common/Form.js +16 -18
  128. package/src/sap/fe/core/converters/controls/Common/Form.ts +20 -20
  129. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  130. package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -3
  131. package/src/sap/fe/core/converters/controls/Common/Table.js +389 -173
  132. package/src/sap/fe/core/converters/controls/Common/Table.ts +440 -244
  133. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +26 -16
  134. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +27 -19
  135. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +78 -47
  136. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +146 -107
  137. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
  138. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
  139. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +30 -25
  140. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +39 -34
  141. package/src/sap/fe/core/converters/helpers/Aggregation.js +10 -2
  142. package/src/sap/fe/core/converters/helpers/Aggregation.ts +18 -13
  143. package/src/sap/fe/core/converters/helpers/BindingHelper.js +3 -2
  144. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +6 -5
  145. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
  146. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
  147. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +27 -24
  148. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +49 -40
  149. package/src/sap/fe/core/converters/templates/ListReportConverter.js +33 -22
  150. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +77 -62
  151. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +28 -28
  152. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +38 -45
  153. package/src/sap/fe/core/designtime/AppComponent.designtime.js +3 -3
  154. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +8 -6
  155. package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
  156. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -2
  157. package/src/sap/fe/core/formatters/TableFormatter.js +74 -13
  158. package/src/sap/fe/core/formatters/TableFormatter.ts +71 -16
  159. package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
  160. package/src/sap/fe/core/formatters/ValueFormatter.ts +4 -7
  161. package/src/sap/fe/core/fpm/Component.js +46 -17
  162. package/src/sap/fe/core/fpm/Component.ts +11 -16
  163. package/src/sap/fe/core/helpers/AppStartupHelper.js +4 -4
  164. package/src/sap/fe/core/helpers/AppStartupHelper.ts +3 -3
  165. package/src/sap/fe/core/helpers/BindingExpression.js +10 -7
  166. package/src/sap/fe/core/helpers/BindingExpression.ts +37 -35
  167. package/src/sap/fe/core/helpers/ClassSupport.js +273 -256
  168. package/src/sap/fe/core/helpers/ClassSupport.ts +315 -237
  169. package/src/sap/fe/core/helpers/FPMHelper.js +3 -2
  170. package/src/sap/fe/core/helpers/FPMHelper.ts +9 -8
  171. package/src/sap/fe/core/helpers/MassEditHelper.js +522 -147
  172. package/src/sap/fe/core/helpers/MassEditHelper.ts +563 -236
  173. package/src/sap/fe/core/helpers/ModelHelper.js +29 -1
  174. package/src/sap/fe/core/helpers/ModelHelper.ts +39 -26
  175. package/src/sap/fe/core/helpers/PasteHelper.js +4 -4
  176. package/src/sap/fe/core/helpers/PasteHelper.ts +4 -3
  177. package/src/sap/fe/core/helpers/SemanticDateOperators.js +3 -3
  178. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +3 -1
  179. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
  180. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +1 -1
  181. package/src/sap/fe/core/helpers/StableIdHelper.js +5 -7
  182. package/src/sap/fe/core/helpers/StableIdHelper.ts +8 -8
  183. package/src/sap/fe/core/{Synchronization.js → helpers/Synchronization.js} +1 -1
  184. package/src/sap/fe/core/{Synchronization.ts → helpers/Synchronization.ts} +1 -1
  185. package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
  186. package/src/sap/fe/core/jsx-runtime/jsx.ts +22 -8
  187. package/src/sap/fe/core/library.js +13 -5
  188. package/src/sap/fe/core/library.ts +26 -17
  189. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +1 -1
  190. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +0 -3
  191. package/src/sap/fe/core/messagebundle.properties +135 -180
  192. package/src/sap/fe/core/messagebundle_ar.properties +31 -64
  193. package/src/sap/fe/core/messagebundle_bg.properties +31 -64
  194. package/src/sap/fe/core/messagebundle_ca.properties +31 -64
  195. package/src/sap/fe/core/messagebundle_cs.properties +31 -64
  196. package/src/sap/fe/core/messagebundle_cy.properties +32 -65
  197. package/src/sap/fe/core/messagebundle_da.properties +31 -64
  198. package/src/sap/fe/core/messagebundle_de.properties +29 -62
  199. package/src/sap/fe/core/messagebundle_el.properties +32 -65
  200. package/src/sap/fe/core/messagebundle_en.properties +32 -65
  201. package/src/sap/fe/core/messagebundle_en_GB.properties +29 -62
  202. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +41 -74
  203. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +32 -65
  204. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +20 -6
  205. package/src/sap/fe/core/messagebundle_es.properties +31 -64
  206. package/src/sap/fe/core/messagebundle_es_MX.properties +31 -64
  207. package/src/sap/fe/core/messagebundle_et.properties +31 -64
  208. package/src/sap/fe/core/messagebundle_fi.properties +29 -62
  209. package/src/sap/fe/core/messagebundle_fr.properties +36 -69
  210. package/src/sap/fe/core/messagebundle_fr_CA.properties +33 -66
  211. package/src/sap/fe/core/messagebundle_hi.properties +29 -62
  212. package/src/sap/fe/core/messagebundle_hr.properties +32 -65
  213. package/src/sap/fe/core/messagebundle_hu.properties +30 -63
  214. package/src/sap/fe/core/messagebundle_id.properties +32 -65
  215. package/src/sap/fe/core/messagebundle_it.properties +31 -64
  216. package/src/sap/fe/core/messagebundle_iw.properties +31 -64
  217. package/src/sap/fe/core/messagebundle_ja.properties +29 -62
  218. package/src/sap/fe/core/messagebundle_kk.properties +31 -64
  219. package/src/sap/fe/core/messagebundle_ko.properties +31 -64
  220. package/src/sap/fe/core/messagebundle_lt.properties +31 -64
  221. package/src/sap/fe/core/messagebundle_lv.properties +32 -65
  222. package/src/sap/fe/core/messagebundle_ms.properties +31 -64
  223. package/src/sap/fe/core/messagebundle_nl.properties +31 -64
  224. package/src/sap/fe/core/messagebundle_no.properties +31 -64
  225. package/src/sap/fe/core/messagebundle_pl.properties +34 -67
  226. package/src/sap/fe/core/messagebundle_pt.properties +32 -65
  227. package/src/sap/fe/core/messagebundle_pt_PT.properties +31 -64
  228. package/src/sap/fe/core/messagebundle_ro.properties +33 -66
  229. package/src/sap/fe/core/messagebundle_ru.properties +33 -66
  230. package/src/sap/fe/core/messagebundle_sh.properties +31 -64
  231. package/src/sap/fe/core/messagebundle_sk.properties +31 -64
  232. package/src/sap/fe/core/messagebundle_sl.properties +29 -62
  233. package/src/sap/fe/core/messagebundle_sv.properties +30 -63
  234. package/src/sap/fe/core/messagebundle_th.properties +31 -64
  235. package/src/sap/fe/core/messagebundle_tr.properties +31 -64
  236. package/src/sap/fe/core/messagebundle_uk.properties +32 -65
  237. package/src/sap/fe/core/messagebundle_vi.properties +31 -64
  238. package/src/sap/fe/core/messagebundle_zh_CN.properties +32 -65
  239. package/src/sap/fe/core/messagebundle_zh_TW.properties +34 -67
  240. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +4 -4
  241. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +1 -1
  242. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +5 -5
  243. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +1 -2
  244. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +11 -8
  245. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +15 -13
  246. package/src/sap/fe/core/services/NavigationServiceFactory.js +5 -5
  247. package/src/sap/fe/core/services/NavigationServiceFactory.ts +9 -5
  248. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +4 -4
  249. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +1 -1
  250. package/src/sap/fe/core/services/RoutingServiceFactory.js +105 -66
  251. package/src/sap/fe/core/services/RoutingServiceFactory.ts +59 -49
  252. package/src/sap/fe/core/services/ShellServicesFactory.js +104 -29
  253. package/src/sap/fe/core/services/ShellServicesFactory.ts +64 -30
  254. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +4 -4
  255. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +1 -1
  256. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +11 -10
  257. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +38 -51
  258. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +43 -5
  259. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +6 -3
  260. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  261. package/src/sap/fe/core/support/CommonHelper.ts +0 -3
  262. package/src/sap/fe/core/templating/DataModelPathHelper.js +2 -9
  263. package/src/sap/fe/core/templating/DataModelPathHelper.ts +32 -38
  264. package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
  265. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +27 -6
  266. package/src/sap/fe/core/templating/EntitySetHelper.js +1 -9
  267. package/src/sap/fe/core/templating/EntitySetHelper.ts +11 -13
  268. package/src/sap/fe/core/templating/FilterHelper.js +4 -4
  269. package/src/sap/fe/core/templating/FilterHelper.ts +6 -5
  270. package/src/sap/fe/core/templating/PropertyHelper.js +70 -33
  271. package/src/sap/fe/core/templating/PropertyHelper.ts +49 -27
  272. package/src/sap/fe/core/templating/UIFormatters.js +133 -22
  273. package/src/sap/fe/core/templating/UIFormatters.ts +144 -50
  274. package/src/sap/fe/core/type/DateTimeWithTimezone.js +47 -0
  275. package/src/sap/fe/core/type/DateTimeWithTimezone.ts +23 -0
  276. package/src/sap/fe/core/type/Email.js +26 -8
  277. package/src/sap/fe/core/type/Email.ts +8 -7
  278. package/src/sap/fe/core/AnnotationHelper.js +0 -312
  279. package/src/sap/fe/core/AnnotationHelper.ts +0 -315
  280. package/src/sap/fe/core/RouterProxy.js +0 -926
  281. package/src/sap/fe/core/TransactionHelper.js +0 -1562
  282. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +0 -392
  283. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +0 -136
  284. package/src/sap/fe/core/actions/collaboration/Manage.js +0 -262
  285. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +0 -103
  286. package/src/sap/fe/core/actions/draft.js +0 -523
  287. package/src/sap/fe/core/actions/messageHandling.js +0 -567
  288. package/src/sap/fe/core/actions/nonDraft.js +0 -20
  289. package/src/sap/fe/core/actions/nonDraft.ts +0 -12
  290. package/src/sap/fe/core/actions/operations.js +0 -1096
  291. package/src/sap/fe/core/actions/sticky.js +0 -130
  292. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -78
  293. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +0 -65
  294. package/src/sap/fe/core/formatters/CriticalityFormatter.js +0 -77
  295. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +0 -58
@@ -1,926 +0,0 @@
1
- /*!
2
- * SAP UI development toolkit for HTML5 (SAPUI5)
3
- * (c) Copyright 2009-2021 SAP SE. All rights reserved
4
- */
5
- sap.ui.define(["sap/base/Log", "sap/ui/base/Object", "sap/fe/core/Synchronization", "sap/ui/thirdparty/URI", "sap/fe/core/helpers/ClassSupport"], function (Log, BaseObject, Synchronization, URI, ClassSupport) {
6
- "use strict";
7
-
8
- var _dec, _class;
9
-
10
- var UI5Class = ClassSupport.UI5Class;
11
-
12
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
13
-
14
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
15
-
16
- var enumState = {
17
- EQUAL: 0,
18
- COMPATIBLE: 1,
19
- ANCESTOR: 2,
20
- DIFFERENT: 3
21
- };
22
- var enumURLParams = {
23
- LAYOUTPARAM: "layout",
24
- IAPPSTATEPARAM: "sap-iapp-state"
25
- };
26
- /**
27
- * Creates a HashGuard object.
28
- *
29
- * @param {string} sGuardHash The hash used for the guard
30
- * @returns {object} The created hash guard
31
- */
32
-
33
- function createGuardFromHash(sGuardHash) {
34
- return {
35
- _guardHash: sGuardHash.replace(/\?[^\?]*$/, ""),
36
- // Remove query part
37
- check: function (sHash) {
38
- return sHash.indexOf(this._guardHash) === 0;
39
- }
40
- };
41
- }
42
- /**
43
- * Returns the iAppState part from a hash (or null if not found).
44
- *
45
- * @param {string} sHash The hash
46
- * @returns {string} The iAppState part of the hash
47
- */
48
-
49
-
50
- function findAppStateInHash(sHash) {
51
- var aAppState = sHash.match(new RegExp("\\?.*" + enumURLParams.IAPPSTATEPARAM + "=([^&]*)"));
52
- return aAppState && aAppState.length > 1 ? aAppState[1] : null;
53
- }
54
- /**
55
- * Returns a hash without its iAppState part.
56
- *
57
- * @param {string} sHash The hash
58
- * @returns {string} The hash without the iAppState
59
- */
60
-
61
-
62
- function removeAppStateInHash(sHash) {
63
- return sHash.replace(new RegExp("[&?]*" + enumURLParams.IAPPSTATEPARAM + "=[^&]*"), "");
64
- }
65
- /**
66
- * Adds an iAppState inside a hash (or replaces an existing one).
67
- *
68
- * @param {*} sHash The hash
69
- * @param {*} sAppStateKey The iAppState to add
70
- * @returns {string} The hash with the app state
71
- */
72
-
73
-
74
- function setAppStateInHash(sHash, sAppStateKey) {
75
- var sNewHash;
76
-
77
- if (sHash.indexOf(enumURLParams.IAPPSTATEPARAM) >= 0) {
78
- // If there's already an iAppState parameter in the hash, replace it
79
- sNewHash = sHash.replace(new RegExp(enumURLParams.IAPPSTATEPARAM + "=[^&]*"), enumURLParams.IAPPSTATEPARAM + "=" + sAppStateKey);
80
- } else {
81
- // Add the iAppState parameter in the hash
82
- if (sHash.indexOf("?") < 0) {
83
- sNewHash = sHash + "?";
84
- } else {
85
- sNewHash = sHash + "&";
86
- }
87
-
88
- sNewHash += enumURLParams.IAPPSTATEPARAM + "=" + sAppStateKey;
89
- }
90
-
91
- return sNewHash;
92
- }
93
-
94
- var RouterProxy = (_dec = UI5Class("sap.fe.core.RouterProxy"), _dec(_class = /*#__PURE__*/function (_BaseObject) {
95
- _inherits(RouterProxy, _BaseObject);
96
-
97
- function RouterProxy() {
98
- var _this;
99
-
100
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
101
- args[_key] = arguments[_key];
102
- }
103
-
104
- _this = _BaseObject.call.apply(_BaseObject, [this].concat(args)) || this;
105
- _this.bIsRebuildHistoryRunning = false;
106
- _this.bIsComputingTitleHierachy = false;
107
- _this.bIsGuardCrossAllowed = false;
108
- _this.sIAppStateKey = null;
109
- _this._bActivateRouteMatchSynchro = false;
110
- _this._bApplyRestore = false;
111
- _this._bDelayedRebuild = false;
112
- return _this;
113
- }
114
-
115
- var _proto = RouterProxy.prototype;
116
-
117
- _proto.init = function init(oAppComponent, isfclEnabled) {
118
- var _this2 = this;
119
-
120
- // Save the name of the app (including startup parameters) for rebuilding full hashes later
121
- oAppComponent.getService("shellServices").then(function () {
122
- _this2._oShellServices = oAppComponent.getShellServices();
123
-
124
- _this2.initRaw(oAppComponent.getRouter()); // We want to wait until the initial routeMatched is done before doing any navigation
125
-
126
-
127
- _this2.waitForRouteMatchBeforeNavigation(); // Set feLevel=0 for the first Application page in the history
128
-
129
-
130
- history.replaceState(Object.assign({
131
- feLevel: 0
132
- }, history.state), "", window.location);
133
- _this2.fclEnabled = isfclEnabled;
134
- _this2._fnBlockingNavFilter = _this2._blockingNavigationFilter.bind(_this2);
135
-
136
- _this2._oShellServices.registerNavigationFilter(_this2._fnBlockingNavFilter);
137
- }).catch(function (oError) {
138
- Log.error("Cannot retrieve the shell services", oError);
139
- });
140
- this._fnHashGuard = this.hashGuard.bind(this);
141
- window.addEventListener("popstate", this._fnHashGuard);
142
- this._bDisableOnHashChange = false;
143
- this._bIgnoreRestore = false;
144
- this._bCleanedRestore = false;
145
- this._bForceFocus = true; // Trigger the focus mechanism for the first view displayed by the app
146
- };
147
-
148
- _proto.destroy = function destroy() {
149
- if (this._oShellServices) {
150
- this._oShellServices.unregisterNavigationFilter(this._fnBlockingNavFilter);
151
- }
152
-
153
- window.removeEventListener("popstate", this._fnHashGuard);
154
- }
155
- /**
156
- * Raw initialization (for unit tests).
157
- *
158
- * @param {sap.ui.core.routing.Router} oRouter The router used by this proxy
159
- */
160
- ;
161
-
162
- _proto.initRaw = function initRaw(oRouter) {
163
- this._oRouter = oRouter;
164
- this._oManagedHistory = [];
165
- this._oNavigationGuard = null;
166
- var sCurrentAppHash = this.getHash();
167
-
168
- this._oManagedHistory.push(this._extractStateFromHash(sCurrentAppHash)); // Set the iAppState if the initial hash contains one
169
-
170
-
171
- this.sIAppStateKey = findAppStateInHash(sCurrentAppHash);
172
- };
173
-
174
- _proto.getHash = function getHash() {
175
- return this._oRouter.getHashChanger().getHash();
176
- };
177
-
178
- _proto.isFocusForced = function isFocusForced() {
179
- return this._bForceFocus;
180
- };
181
-
182
- _proto.setFocusForced = function setFocusForced(bForced) {
183
- this._bForceFocus = bForced;
184
- }
185
- /**
186
- * Resets the internal variable sIAppStateKey.
187
- *
188
- * @function
189
- * @name sap.fe.core.RouterProxy#removeIAppStateKey
190
- *
191
- * @ui5-restricted
192
- */
193
- ;
194
-
195
- _proto.removeIAppStateKey = function removeIAppStateKey() {
196
- this.sIAppStateKey = null;
197
- }
198
- /**
199
- * Navigates to a specific hash.
200
- *
201
- * @function
202
- * @name sap.fe.core.RouterProxy#navToHash
203
- * @memberof sap.fe.core.RouterProxy
204
- * @static
205
- * @param {string} sHash Hash to be navigated to
206
- * @param {boolean} bPreserveHistory If set to true, non-ancestor entries in history will be retained
207
- * @param {boolean} bDisablePreservationCache If set to true, cache preservation mechanism is disabled for the current navigation
208
- * @param {boolean} bForceFocus If set to true, the logic to set the focus once the navigation is finalized will be triggered (onPageReady)
209
- * @param {boolean} bPreserveShellBackNavigationHandler If not set to false, the back navigation is set to undefined
210
- * @returns {Promise} Promise (resolved when the navigation is finalized) that returns 'true' if a navigation took place, 'false' if the navigation didn't happen
211
- * @ui5-restricted
212
- */
213
- ;
214
-
215
- _proto.navToHash = function navToHash(sHash, bPreserveHistory, bDisablePreservationCache, bForceFocus, bPreserveShellBackNavigationHandler) {
216
- var _this3 = this;
217
-
218
- if (bPreserveShellBackNavigationHandler !== false) {
219
- this._oShellServices.setBackNavigation();
220
- }
221
-
222
- if (this._oRouteMatchSynchronization) {
223
- return this._oRouteMatchSynchronization.waitFor().then(function () {
224
- _this3._oRouteMatchSynchronization = undefined;
225
- return _this3._internalNavToHash(sHash, bPreserveHistory, bDisablePreservationCache, bForceFocus);
226
- });
227
- } else {
228
- if (this._bActivateRouteMatchSynchro) {
229
- this.waitForRouteMatchBeforeNavigation();
230
- }
231
-
232
- return this._internalNavToHash(sHash, bPreserveHistory, bDisablePreservationCache, bForceFocus);
233
- }
234
- };
235
-
236
- _proto._internalNavToHash = function _internalNavToHash(sHash, bPreserveHistory, bDisablePreservationCache, bForceFocus) {
237
- // Add the app state in the hash if needed
238
- if (this.fclEnabled && this.sIAppStateKey && !findAppStateInHash(sHash)) {
239
- sHash = setAppStateInHash(sHash, this.sIAppStateKey);
240
- }
241
-
242
- if (!this.checkHashWithGuard(sHash)) {
243
- if (!this.oResourceBundle) {
244
- this.oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
245
- } // We have to use a confirm here for UI consistency reasons, as with some scenarios
246
- // in the EditFlow we rely on a UI5 mechanism that displays a confirm dialog.
247
- // eslint-disable-next-line no-alert
248
-
249
-
250
- if (!confirm(this.oResourceBundle.getText("C_ROUTER_PROXY_SAPFE_EXIT_NOTSAVED_MESSAGE"))) {
251
- // The user clicked on Cancel --> cancel navigation
252
- return Promise.resolve(false);
253
- }
254
-
255
- this.bIsGuardCrossAllowed = true;
256
- } // In case the navigation will cause a new view to be displayed, we force the focus
257
- // I.e. if the keys for the hash we're navigating to is a superset of the current hash keys.
258
-
259
-
260
- var oNewState = this._extractStateFromHash(sHash);
261
-
262
- if (!this._bForceFocus) {
263
- // If the focus was already forced, keep it
264
- var aCurrentHashKeys = this._extractKeysFromHash(this.getHash());
265
-
266
- this._bForceFocus = bForceFocus || aCurrentHashKeys.length < oNewState.keys.length && aCurrentHashKeys.every(function (key, index) {
267
- return key === oNewState.keys[index];
268
- });
269
- }
270
-
271
- var oHistoryAction = this._pushNewState(oNewState, false, bPreserveHistory, bDisablePreservationCache);
272
-
273
- return this._rebuildBrowserHistory(oHistoryAction, false);
274
- }
275
- /**
276
- * Clears browser history if entries have been added without using the RouterProxy.
277
- * Updates the internal history accordingly.
278
- *
279
- * @returns {Promise} Promise that is resolved once the history is rebuilt
280
- */
281
- ;
282
-
283
- _proto.restoreHistory = function restoreHistory() {
284
- if (this._bApplyRestore) {
285
- this._bApplyRestore = false;
286
- var sTargetHash = this.getHash();
287
- sTargetHash = sTargetHash.replace(/(\?|&)restoreHistory=true/, "");
288
-
289
- var oNewState = this._extractStateFromHash(sTargetHash);
290
-
291
- var oHistoryAction = this._pushNewState(oNewState, true, false, true);
292
-
293
- return this._rebuildBrowserHistory(oHistoryAction, true);
294
- } else {
295
- return Promise.resolve();
296
- }
297
- }
298
- /**
299
- * Navigates back in the history.
300
- *
301
- * @returns {Promise} Promise that is resolved when the navigation is finalized
302
- */
303
- ;
304
-
305
- _proto.navBack = function navBack() {
306
- var sCurrentHash = this.getHash();
307
- var sPreviousHash; // Look for the current hash in the managed history
308
-
309
- for (var i = this._oManagedHistory.length - 1; i > 0; i--) {
310
- if (this._oManagedHistory[i].hash === sCurrentHash) {
311
- sPreviousHash = this._oManagedHistory[i - 1].hash;
312
- break;
313
- }
314
- }
315
-
316
- if (sPreviousHash) {
317
- return this.navToHash(sPreviousHash);
318
- } else {
319
- // We couldn't find a previous hash in history
320
- // This can happen when navigating from a transient hash in a create app, and
321
- // in that case history.back would go back to the FLP
322
- window.history.back();
323
- return Promise.resolve();
324
- }
325
- }
326
- /**
327
- * Navigates to a route with parameters.
328
- * @param {string} sRouteName The route name to be navigated to
329
- * @param {object} oParameters Parameters for the navigation
330
- * @returns {Promise} Promise that is resolved when the navigation is finalized
331
- * @ui5-restricted
332
- */
333
- ;
334
-
335
- _proto.navTo = function navTo(sRouteName, oParameters) {
336
- var sHash = this._oRouter.getURL(sRouteName, oParameters);
337
-
338
- return this.navToHash(sHash, false, oParameters.noPreservationCache, false, !oParameters.bIsStickyMode);
339
- }
340
- /**
341
- * Exits the current app by navigating back
342
- * to the previous app (if any) or the FLP.
343
- *
344
- * @returns {Promise} Promise that is resolved when we exit the app
345
- */
346
- ;
347
-
348
- _proto.exitFromApp = function exitFromApp() {
349
- return this._oShellServices.backToPreviousApp();
350
- }
351
- /**
352
- * Checks whether a given hash can have an impact on the current state
353
- * i.e. if the hash is equal, compatible or an ancestor of the current state.
354
- *
355
- * @param {*} sHash `true` if there is an impact
356
- * @returns {boolean} If there is an impact
357
- */
358
- ;
359
-
360
- _proto.isCurrentStateImpactedBy = function isCurrentStateImpactedBy(sHash) {
361
- if (sHash[0] === "/") {
362
- sHash = sHash.substring(1);
363
- }
364
-
365
- var oLocalGuard = createGuardFromHash(sHash);
366
- return oLocalGuard.check(this.getHash());
367
- }
368
- /**
369
- * Checks if a navigation is currently being processed.
370
- *
371
- * @returns {boolean} `false` if a navigation has been triggered in the RouterProxy and is not yet finalized
372
- */
373
- ;
374
-
375
- _proto.isNavigationFinalized = function isNavigationFinalized() {
376
- return !this.bIsRebuildHistoryRunning && !this._bDelayedRebuild;
377
- }
378
- /**
379
- * Sets the last state as a guard.
380
- * Each future navigation will be checked against this guard, and a confirmation dialog will
381
- * be displayed before the navigation crosses the guard (i.e. goes to an ancestor of the guard).
382
- */
383
- ;
384
-
385
- _proto.setNavigationGuard = function setNavigationGuard() {
386
- this._oNavigationGuard = createGuardFromHash(this.getHash());
387
- this.bIsGuardCrossAllowed = false;
388
- }
389
- /**
390
- * Disables the navigation guard.
391
- */
392
- ;
393
-
394
- _proto.discardNavigationGuard = function discardNavigationGuard() {
395
- this._oNavigationGuard = null;
396
- }
397
- /**
398
- * Checks for the availability of the navigation guard.
399
- *
400
- * @returns {boolean} `true` if navigating guard is available
401
- */
402
- ;
403
-
404
- _proto.hasNavigationGuard = function hasNavigationGuard() {
405
- return this._oNavigationGuard !== null;
406
- }
407
- /**
408
- * Tests a hash against the navigation guard.
409
- *
410
- * @param {string} sHash The hash to be tested
411
- * @returns {boolean} `true` if navigating to the hash doesn't cross the guard
412
- */
413
- ;
414
-
415
- _proto.checkHashWithGuard = function checkHashWithGuard(sHash) {
416
- return this._oNavigationGuard === null || this._oNavigationGuard.check(sHash);
417
- }
418
- /**
419
- * Checks if the user allowed the navigation guard to be crossed.
420
- *
421
- * @returns {boolean} `true` if crossing the guard has been allowed by the user
422
- */
423
- ;
424
-
425
- _proto.isGuardCrossAllowedByUser = function isGuardCrossAllowedByUser() {
426
- return this.bIsGuardCrossAllowed;
427
- }
428
- /**
429
- * Activates the synchronization for routeMatchedEvent.
430
- * The next NavToHash call will create a Synchronization object that will be resolved
431
- * by the corresponding onRouteMatched event, preventing another NavToHash to happen in parallel.
432
- */
433
- ;
434
-
435
- _proto.activateRouteMatchSynchronization = function activateRouteMatchSynchronization() {
436
- this._bActivateRouteMatchSynchro = true;
437
- }
438
- /**
439
- * Resolve the routeMatch synchronization object, unlocking potential pending NavToHash calls.
440
- */
441
- ;
442
-
443
- _proto.resolveRouteMatch = function resolveRouteMatch() {
444
- if (this._oRouteMatchSynchronization) {
445
- this._oRouteMatchSynchronization.resolve();
446
- }
447
- }
448
- /**
449
- * Makes sure no navigation can happen before a routeMatch happened.
450
- */
451
- ;
452
-
453
- _proto.waitForRouteMatchBeforeNavigation = function waitForRouteMatchBeforeNavigation() {
454
- this._oRouteMatchSynchronization = new Synchronization();
455
- this._bActivateRouteMatchSynchro = false;
456
- };
457
-
458
- _proto._extractKeysFromHash = function _extractKeysFromHash(sHash) {
459
- if (sHash === undefined) {
460
- sHash = "";
461
- }
462
-
463
- var sHashNoParams = sHash.split("?")[0]; // remove params
464
-
465
- var aTokens = sHashNoParams.split("/");
466
- var aKeys = [];
467
- aTokens.forEach(function (sToken) {
468
- var regexKey = /[^\(\)]+\([^\(\)]+\)/; // abc(def)
469
-
470
- if (regexKey.test(sToken)) {
471
- aKeys.push(sToken.split("(")[0]);
472
- }
473
- });
474
- return aKeys;
475
- }
476
- /**
477
- * Builds a state from a hash.
478
- *
479
- * @param {string} sHash The hash to be used as entry
480
- * @returns {object} The state
481
- *
482
- * @ui5-restricted
483
- */
484
- ;
485
-
486
- _proto._extractStateFromHash = function _extractStateFromHash(sHash) {
487
- if (sHash === undefined) {
488
- sHash = "";
489
- }
490
-
491
- var oState = {
492
- keys: this._extractKeysFromHash(sHash)
493
- }; // Retrieve layout (if any)
494
-
495
- var aLayout = sHash.match(new RegExp("\\?.*" + enumURLParams.LAYOUTPARAM + "=([^&]*)"));
496
- oState.sLayout = aLayout && aLayout.length > 1 ? aLayout[1] : null;
497
-
498
- if (oState.sLayout === "MidColumnFullScreen") {
499
- oState.screenMode = 1;
500
- } else if (oState.sLayout === "EndColumnFullScreen") {
501
- oState.screenMode = 2;
502
- } else {
503
- oState.screenMode = 0;
504
- }
505
-
506
- oState.hash = sHash;
507
- return oState;
508
- }
509
- /**
510
- * Adds a new state into the internal history structure.
511
- * Makes sure this new state is added after an ancestor.
512
- * Also sets the iAppState key in the whole history.
513
- *
514
- * @memberof sap.fe.core.RouterProxy
515
- * @param {object} oNewState The new state to be added
516
- * @param {boolean} bRebuildOnly `true` if we're rebuilding the history after a shell menu navigation
517
- * @param {boolean} bPreserveHistory If set to true, non-ancestor entries in history will be retained
518
- * @param {boolean} bDisableHistoryPreservation Disable the mechanism to retained marked entries in cache
519
- * @returns {object} The new state
520
- * @ui5-restricted
521
- * @final
522
- */
523
- ;
524
-
525
- _proto._pushNewState = function _pushNewState(oNewState, bRebuildOnly, bPreserveHistory, bDisableHistoryPreservation) {
526
- var _this4 = this;
527
-
528
- var sCurrentHash = this.getHash();
529
- var lastIndex = this._oManagedHistory.length - 1;
530
- var iPopCount = bRebuildOnly ? 1 : 0; // 1. Do some cleanup in the managed history : in case the user has navigated back in the browser history, we need to remove
531
- // the states ahead in history and make sure the top state corresponds to the current page
532
- // We don't do that when restoring the history, as the current state has been added on top of the browser history
533
- // and is not reflected in the managed history
534
-
535
- if (!bRebuildOnly) {
536
- while (lastIndex >= 0 && this._oManagedHistory[lastIndex].hash !== sCurrentHash) {
537
- this._oManagedHistory.pop();
538
-
539
- lastIndex--;
540
- }
541
-
542
- if (this._oManagedHistory.length === 0) {
543
- // We couldn't find the current location in the history. This can happen if a browser reload
544
- // happened, causing a reinitialization of the managed history.
545
- // In that case, we use the current location as the new starting point in the managed history
546
- this._oManagedHistory.push(this._extractStateFromHash(sCurrentHash));
547
-
548
- history.replaceState(Object.assign({
549
- feLevel: 0
550
- }, history.state), "");
551
- }
552
- } // 2. Mark the top state as preserved if required
553
-
554
-
555
- if (bPreserveHistory && !bDisableHistoryPreservation) {
556
- this._oManagedHistory[this._oManagedHistory.length - 1].preserved = true;
557
- } // 3. Then pop all states until we find an ancestor of the new state, or we find a state that need to be preserved
558
-
559
-
560
- var oLastRemovedItem;
561
-
562
- while (this._oManagedHistory.length > 0) {
563
- var oTopState = this._oManagedHistory[this._oManagedHistory.length - 1];
564
-
565
- if ((bDisableHistoryPreservation || !oTopState.preserved) && this._compareCacheStates(oTopState, oNewState) !== enumState.ANCESTOR) {
566
- // The top state is not an ancestor of oNewState and is not preserved --> we can pop it
567
- oLastRemovedItem = this._oManagedHistory.pop();
568
- iPopCount++;
569
- } else if (oTopState.preserved && removeAppStateInHash(oTopState.hash) === removeAppStateInHash(oNewState.hash)) {
570
- // We try to add a state that is already in cache (due to preserved flag) but with a different iapp-state
571
- // --> we should delete the previous entry (it will be later replaced by the new one) and stop popping
572
- oLastRemovedItem = this._oManagedHistory.pop();
573
- iPopCount++;
574
- oNewState.preserved = true;
575
- break;
576
- } else {
577
- break; // Ancestor or preserved state found --> we stop popping out states
578
- }
579
- } // 4. iAppState management
580
-
581
-
582
- this.sIAppStateKey = findAppStateInHash(oNewState.hash);
583
-
584
- if (this.fclEnabled && this.sIAppStateKey) {
585
- // In case of FCL, the new app state needs to be applied to the whole history
586
- this._oManagedHistory.forEach(function (oManagedState) {
587
- oManagedState.hash = setAppStateInHash(oManagedState.hash, _this4.sIAppStateKey);
588
- });
589
- } else if (!this.fclEnabled && oLastRemovedItem) {
590
- var sPreviousIAppStateKey = findAppStateInHash(oLastRemovedItem.hash);
591
-
592
- var oComparisonStateResult = this._compareCacheStates(oLastRemovedItem, oNewState); // if current state doesn't contain a i-appstate and this state should replace a state containing a iAppState
593
- // then the previous iAppState is preserved
594
-
595
-
596
- if (!this.sIAppStateKey && sPreviousIAppStateKey && (oComparisonStateResult === enumState.EQUAL || oComparisonStateResult === enumState.COMPATIBLE)) {
597
- oNewState.hash = setAppStateInHash(oNewState.hash, sPreviousIAppStateKey);
598
- }
599
- } // 5. Now we can push the state at the top of the internal history
600
-
601
-
602
- var bHasSameHash = oLastRemovedItem && oNewState.hash === oLastRemovedItem.hash;
603
-
604
- if (this._oManagedHistory.length === 0 || this._oManagedHistory[this._oManagedHistory.length - 1].hash !== oNewState.hash) {
605
- this._oManagedHistory.push(oNewState);
606
- } // 6. Determine which actions to do on the history
607
-
608
-
609
- if (iPopCount === 0) {
610
- // No state was popped --> append
611
- return {
612
- type: "append"
613
- };
614
- } else if (iPopCount === 1) {
615
- // Only 1 state was popped --> replace current hash unless hash is the same (then nothing to do)
616
- return bHasSameHash ? {
617
- type: "none"
618
- } : {
619
- type: "replace"
620
- };
621
- } else {
622
- // More than 1 state was popped --> go bakc in history and replace hash if necessary
623
- return bHasSameHash ? {
624
- type: "back",
625
- steps: iPopCount - 1
626
- } : {
627
- type: "back-replace",
628
- steps: iPopCount - 1
629
- };
630
- }
631
- };
632
-
633
- _proto._blockingNavigationFilter = function _blockingNavigationFilter() {
634
- return this._bDisableOnHashChange ? "Custom" : "Continue";
635
- }
636
- /**
637
- * Disable the routing by calling the router stop method.
638
- *
639
- * @function
640
- * @memberof sap.fe.core.RouterProxy
641
- *
642
- * @ui5-restricted
643
- * @final
644
- */
645
- ;
646
-
647
- _proto._disableEventOnHashChange = function _disableEventOnHashChange() {
648
- this._bDisableOnHashChange = true;
649
-
650
- this._oRouter.stop();
651
- }
652
- /**
653
- * Enable the routing by calling the router initialize method.
654
- *
655
- * @function
656
- * @name sap.fe.core.RouterProxy#_enableEventOnHashChange
657
- * @memberof sap.fe.core.RouterProxy
658
- * @param {boolean} [bIgnoreCurrentHash] Ignore the last hash event triggered before the router has initialized
659
- *
660
- * @ui5-restricted
661
- * @final
662
- */
663
- ;
664
-
665
- _proto._enableEventOnHashChange = function _enableEventOnHashChange(bIgnoreCurrentHash) {
666
- this._bDisableOnHashChange = false;
667
-
668
- this._oRouter.initialize(bIgnoreCurrentHash);
669
- }
670
- /**
671
- * Synchronizes the browser history with the internal history of the routerProxy, and triggers a navigation if needed.
672
- *
673
- * @memberof sap.fe.core.RouterProxy
674
- * @param {object} oHistoryAction Specifies the navigation action to be performed
675
- * @param {boolean} bRebuildOnly `true` if internal history is currently being rebuilt
676
- * @returns {Promise} Promise (resolved when the navigation is finalized) that returns 'true' if a navigation took place, 'false' if the navigation didn't happen
677
- * @ui5-restricted
678
- * @final
679
- */
680
- ;
681
-
682
- _proto._rebuildBrowserHistory = function _rebuildBrowserHistory(oHistoryAction, bRebuildOnly) {
683
- var _this5 = this;
684
-
685
- // eslint-disable-next-line @typescript-eslint/no-this-alias
686
- var that = this;
687
- return new Promise(function (resolve) {
688
- _this5.bIsRebuildHistoryRunning = true;
689
- var oTargetState = _this5._oManagedHistory[_this5._oManagedHistory.length - 1],
690
- newLevel = _this5._oManagedHistory.length - 1;
691
-
692
- function replaceAsync() {
693
- if (!bRebuildOnly) {
694
- that._enableEventOnHashChange(true);
695
- }
696
-
697
- that._oRouter.getHashChanger().replaceHash(oTargetState.hash);
698
-
699
- history.replaceState(Object.assign({
700
- feLevel: newLevel
701
- }, history.state), "");
702
-
703
- if (bRebuildOnly) {
704
- setTimeout(function () {
705
- // Timeout to let 'hashchange' event be processed before by the HashChanger, so that
706
- // onRouteMatched notification isn't raised
707
- that._enableEventOnHashChange(true);
708
- }, 0);
709
- }
710
-
711
- that.bIsRebuildHistoryRunning = false;
712
- resolve(true); // a navigation occurred
713
- } // Async callbacks when navigating back, in order to let all notifications and events get processed
714
-
715
-
716
- function backReplaceAsync() {
717
- window.removeEventListener("popstate", backReplaceAsync);
718
- setTimeout(function () {
719
- // Timeout to let 'hashchange' event be processed before by the HashChanger
720
- replaceAsync();
721
- }, 0);
722
- }
723
-
724
- function backAsync() {
725
- window.removeEventListener("popstate", backAsync);
726
- that.bIsRebuildHistoryRunning = false;
727
- resolve(true); // a navigation occurred
728
- }
729
-
730
- that._bIgnoreRestore = true;
731
-
732
- switch (oHistoryAction.type) {
733
- case "replace":
734
- that._oRouter.getHashChanger().replaceHash(oTargetState.hash);
735
-
736
- history.replaceState(Object.assign({
737
- feLevel: newLevel
738
- }, history.state), "");
739
- that.bIsRebuildHistoryRunning = false;
740
- resolve(true); // a navigation occurred
741
-
742
- break;
743
-
744
- case "append":
745
- that._oRouter.getHashChanger().setHash(oTargetState.hash);
746
-
747
- history.replaceState(Object.assign({
748
- feLevel: newLevel
749
- }, history.state), "");
750
- that.bIsRebuildHistoryRunning = false;
751
- resolve(true); // a navigation occurred
752
-
753
- break;
754
-
755
- case "back":
756
- window.addEventListener("popstate", backAsync);
757
- history.go(-oHistoryAction.steps);
758
- break;
759
-
760
- case "back-replace":
761
- _this5._disableEventOnHashChange();
762
-
763
- window.addEventListener("popstate", backReplaceAsync);
764
- history.go(-oHistoryAction.steps);
765
- break;
766
-
767
- default:
768
- // No navigation
769
- _this5.bIsRebuildHistoryRunning = false;
770
- resolve(false);
771
- // no navigation --> resolve to false
772
- }
773
- });
774
- };
775
-
776
- _proto.getLastHistoryEntry = function getLastHistoryEntry() {
777
- return this._oManagedHistory[this._oManagedHistory.length - 1];
778
- };
779
-
780
- _proto.hashGuard = function hashGuard() {
781
- var _this6 = this;
782
-
783
- if (this._bCleanedRestore) {
784
- this._bCleanedRestore = false;
785
- return;
786
- }
787
-
788
- var sHash = window.location.hash;
789
-
790
- if (sHash.indexOf("restoreHistory=true") !== -1) {
791
- this._bApplyRestore = true;
792
- } else if (!this.bIsRebuildHistoryRunning) {
793
- var aHashSplit = sHash.split("&/");
794
- var sAppHash = aHashSplit[1] ? aHashSplit[1] : "";
795
-
796
- if (this.checkHashWithGuard(sAppHash)) {
797
- this._bDelayedRebuild = true;
798
-
799
- var oNewState = this._extractStateFromHash(sAppHash);
800
-
801
- this._pushNewState(oNewState, false, false, true);
802
-
803
- setTimeout(function () {
804
- _this6._bDelayedRebuild = false;
805
- }, 0);
806
- }
807
- }
808
- }
809
- /**
810
- * Compares 2 states.
811
- *
812
- * @param {object} oState1
813
- * @param {object} oState2
814
- * @returns {number} The result of the comparison:
815
- * - enumState.EQUAL if oState1 and oState2 are equal
816
- * - enumState.COMPATIBLE if oState1 and oState2 are compatible
817
- * - enumState.ANCESTOR if oState1 is an ancestor of oState2
818
- * - enumState.DIFFERENT if the 2 states are different
819
- */
820
- ;
821
-
822
- _proto._compareCacheStates = function _compareCacheStates(oState1, oState2) {
823
- // First compare object keys
824
- if (oState1.keys.length > oState2.keys.length) {
825
- return enumState.DIFFERENT;
826
- }
827
-
828
- var equal = true;
829
- var index;
830
-
831
- for (index = 0; equal && index < oState1.keys.length; index++) {
832
- if (oState1.keys[index] !== oState2.keys[index]) {
833
- equal = false;
834
- }
835
- }
836
-
837
- if (!equal) {
838
- // Some objects keys are different
839
- return enumState.DIFFERENT;
840
- } // All keys from oState1 are in oState2 --> check if ancestor
841
-
842
-
843
- if (oState1.keys.length < oState2.keys.length || oState1.screenMode < oState2.screenMode) {
844
- return enumState.ANCESTOR;
845
- }
846
-
847
- if (oState1.screenMode > oState2.screenMode) {
848
- return enumState.DIFFERENT; // Not sure this case can happen...
849
- } // At this stage, the 2 states have the same object keys (in the same order) and same screenmode
850
- // They can be either compatible or equal
851
-
852
-
853
- return oState1.sLayout === oState2.sLayout ? enumState.EQUAL : enumState.COMPATIBLE;
854
- }
855
- /**
856
- * Checks if back exits the present guard set.
857
- *
858
- * @param {string} sPresentHash The current hash. Only used for unit tests.
859
- * @returns {boolean} `true` if back exits there is a guard exit on back
860
- */
861
- ;
862
-
863
- _proto.checkIfBackIsOutOfGuard = function checkIfBackIsOutOfGuard(sPresentHash) {
864
- var sPrevHash;
865
- var sCurrentHash;
866
-
867
- if (sPresentHash === undefined) {
868
- // We use window.location.hash instead of HashChanger.getInstance().getHash() because the latter
869
- // replaces characters in the URL (e.g. %24 replaced by $) and it causes issues when comparing
870
- // with the URLs in the managed history
871
- var oSplitHash = this._oShellServices.splitHash(window.location.hash);
872
-
873
- if (oSplitHash && oSplitHash.appSpecificRoute) {
874
- sCurrentHash = oSplitHash.appSpecificRoute;
875
-
876
- if (sCurrentHash.indexOf("&/") === 0) {
877
- sCurrentHash = sCurrentHash.substring(2);
878
- }
879
- } else {
880
- sCurrentHash = window.location.hash.substring(1); // To remove the '#'
881
-
882
- if (sCurrentHash[0] === "/") {
883
- sCurrentHash = sCurrentHash.substring(1);
884
- }
885
- }
886
- } else {
887
- sCurrentHash = sPresentHash;
888
- }
889
-
890
- sPresentHash = URI.decode(sCurrentHash);
891
-
892
- if (this._oNavigationGuard) {
893
- for (var i = this._oManagedHistory.length - 1; i > 0; i--) {
894
- if (this._oManagedHistory[i].hash === sPresentHash) {
895
- sPrevHash = this._oManagedHistory[i - 1].hash;
896
- break;
897
- }
898
- }
899
-
900
- return !sPrevHash || !this.checkHashWithGuard(sPrevHash);
901
- }
902
-
903
- return false;
904
- }
905
- /**
906
- * Checks if the last 2 entries in the history share the same context.
907
- *
908
- * @returns {boolean} `true` if they share the same context.
909
- */
910
- ;
911
-
912
- _proto.checkIfBackHasSameContext = function checkIfBackHasSameContext() {
913
- if (this._oManagedHistory.length < 2) {
914
- return false;
915
- }
916
-
917
- var oCurrentState = this._oManagedHistory[this._oManagedHistory.length - 1];
918
- var oPreviousState = this._oManagedHistory[this._oManagedHistory.length - 2];
919
- return oCurrentState.hash.split("?")[0] === oPreviousState.hash.split("?")[0];
920
- };
921
-
922
- return RouterProxy;
923
- }(BaseObject)) || _class);
924
- return RouterProxy;
925
- }, false);
926
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlJvdXRlclByb3h5LnRzIl0sIm5hbWVzIjpbImVudW1TdGF0ZSIsIkVRVUFMIiwiQ09NUEFUSUJMRSIsIkFOQ0VTVE9SIiwiRElGRkVSRU5UIiwiZW51bVVSTFBhcmFtcyIsIkxBWU9VVFBBUkFNIiwiSUFQUFNUQVRFUEFSQU0iLCJjcmVhdGVHdWFyZEZyb21IYXNoIiwic0d1YXJkSGFzaCIsIl9ndWFyZEhhc2giLCJyZXBsYWNlIiwiY2hlY2siLCJzSGFzaCIsImluZGV4T2YiLCJmaW5kQXBwU3RhdGVJbkhhc2giLCJhQXBwU3RhdGUiLCJtYXRjaCIsIlJlZ0V4cCIsImxlbmd0aCIsInJlbW92ZUFwcFN0YXRlSW5IYXNoIiwic2V0QXBwU3RhdGVJbkhhc2giLCJzQXBwU3RhdGVLZXkiLCJzTmV3SGFzaCIsIlJvdXRlclByb3h5IiwiVUk1Q2xhc3MiLCJiSXNSZWJ1aWxkSGlzdG9yeVJ1bm5pbmciLCJiSXNDb21wdXRpbmdUaXRsZUhpZXJhY2h5IiwiYklzR3VhcmRDcm9zc0FsbG93ZWQiLCJzSUFwcFN0YXRlS2V5IiwiX2JBY3RpdmF0ZVJvdXRlTWF0Y2hTeW5jaHJvIiwiX2JBcHBseVJlc3RvcmUiLCJfYkRlbGF5ZWRSZWJ1aWxkIiwiaW5pdCIsIm9BcHBDb21wb25lbnQiLCJpc2ZjbEVuYWJsZWQiLCJnZXRTZXJ2aWNlIiwidGhlbiIsIl9vU2hlbGxTZXJ2aWNlcyIsImdldFNoZWxsU2VydmljZXMiLCJpbml0UmF3IiwiZ2V0Um91dGVyIiwid2FpdEZvclJvdXRlTWF0Y2hCZWZvcmVOYXZpZ2F0aW9uIiwiaGlzdG9yeSIsInJlcGxhY2VTdGF0ZSIsIk9iamVjdCIsImFzc2lnbiIsImZlTGV2ZWwiLCJzdGF0ZSIsIndpbmRvdyIsImxvY2F0aW9uIiwiZmNsRW5hYmxlZCIsIl9mbkJsb2NraW5nTmF2RmlsdGVyIiwiX2Jsb2NraW5nTmF2aWdhdGlvbkZpbHRlciIsImJpbmQiLCJyZWdpc3Rlck5hdmlnYXRpb25GaWx0ZXIiLCJjYXRjaCIsIm9FcnJvciIsIkxvZyIsImVycm9yIiwiX2ZuSGFzaEd1YXJkIiwiaGFzaEd1YXJkIiwiYWRkRXZlbnRMaXN0ZW5lciIsIl9iRGlzYWJsZU9uSGFzaENoYW5nZSIsIl9iSWdub3JlUmVzdG9yZSIsIl9iQ2xlYW5lZFJlc3RvcmUiLCJfYkZvcmNlRm9jdXMiLCJkZXN0cm95IiwidW5yZWdpc3Rlck5hdmlnYXRpb25GaWx0ZXIiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwib1JvdXRlciIsIl9vUm91dGVyIiwiX29NYW5hZ2VkSGlzdG9yeSIsIl9vTmF2aWdhdGlvbkd1YXJkIiwic0N1cnJlbnRBcHBIYXNoIiwiZ2V0SGFzaCIsInB1c2giLCJfZXh0cmFjdFN0YXRlRnJvbUhhc2giLCJnZXRIYXNoQ2hhbmdlciIsImlzRm9jdXNGb3JjZWQiLCJzZXRGb2N1c0ZvcmNlZCIsImJGb3JjZWQiLCJyZW1vdmVJQXBwU3RhdGVLZXkiLCJuYXZUb0hhc2giLCJiUHJlc2VydmVIaXN0b3J5IiwiYkRpc2FibGVQcmVzZXJ2YXRpb25DYWNoZSIsImJGb3JjZUZvY3VzIiwiYlByZXNlcnZlU2hlbGxCYWNrTmF2aWdhdGlvbkhhbmRsZXIiLCJzZXRCYWNrTmF2aWdhdGlvbiIsIl9vUm91dGVNYXRjaFN5bmNocm9uaXphdGlvbiIsIndhaXRGb3IiLCJ1bmRlZmluZWQiLCJfaW50ZXJuYWxOYXZUb0hhc2giLCJjaGVja0hhc2hXaXRoR3VhcmQiLCJvUmVzb3VyY2VCdW5kbGUiLCJzYXAiLCJ1aSIsImdldENvcmUiLCJnZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUiLCJjb25maXJtIiwiZ2V0VGV4dCIsIlByb21pc2UiLCJyZXNvbHZlIiwib05ld1N0YXRlIiwiYUN1cnJlbnRIYXNoS2V5cyIsIl9leHRyYWN0S2V5c0Zyb21IYXNoIiwia2V5cyIsImV2ZXJ5Iiwia2V5IiwiaW5kZXgiLCJvSGlzdG9yeUFjdGlvbiIsIl9wdXNoTmV3U3RhdGUiLCJfcmVidWlsZEJyb3dzZXJIaXN0b3J5IiwicmVzdG9yZUhpc3RvcnkiLCJzVGFyZ2V0SGFzaCIsIm5hdkJhY2siLCJzQ3VycmVudEhhc2giLCJzUHJldmlvdXNIYXNoIiwiaSIsImhhc2giLCJiYWNrIiwibmF2VG8iLCJzUm91dGVOYW1lIiwib1BhcmFtZXRlcnMiLCJnZXRVUkwiLCJub1ByZXNlcnZhdGlvbkNhY2hlIiwiYklzU3RpY2t5TW9kZSIsImV4aXRGcm9tQXBwIiwiYmFja1RvUHJldmlvdXNBcHAiLCJpc0N1cnJlbnRTdGF0ZUltcGFjdGVkQnkiLCJzdWJzdHJpbmciLCJvTG9jYWxHdWFyZCIsImlzTmF2aWdhdGlvbkZpbmFsaXplZCIsInNldE5hdmlnYXRpb25HdWFyZCIsImRpc2NhcmROYXZpZ2F0aW9uR3VhcmQiLCJoYXNOYXZpZ2F0aW9uR3VhcmQiLCJpc0d1YXJkQ3Jvc3NBbGxvd2VkQnlVc2VyIiwiYWN0aXZhdGVSb3V0ZU1hdGNoU3luY2hyb25pemF0aW9uIiwicmVzb2x2ZVJvdXRlTWF0Y2giLCJTeW5jaHJvbml6YXRpb24iLCJzSGFzaE5vUGFyYW1zIiwic3BsaXQiLCJhVG9rZW5zIiwiYUtleXMiLCJmb3JFYWNoIiwic1Rva2VuIiwicmVnZXhLZXkiLCJ0ZXN0Iiwib1N0YXRlIiwiYUxheW91dCIsInNMYXlvdXQiLCJzY3JlZW5Nb2RlIiwiYlJlYnVpbGRPbmx5IiwiYkRpc2FibGVIaXN0b3J5UHJlc2VydmF0aW9uIiwibGFzdEluZGV4IiwiaVBvcENvdW50IiwicG9wIiwicHJlc2VydmVkIiwib0xhc3RSZW1vdmVkSXRlbSIsIm9Ub3BTdGF0ZSIsIl9jb21wYXJlQ2FjaGVTdGF0ZXMiLCJvTWFuYWdlZFN0YXRlIiwic1ByZXZpb3VzSUFwcFN0YXRlS2V5Iiwib0NvbXBhcmlzb25TdGF0ZVJlc3VsdCIsImJIYXNTYW1lSGFzaCIsInR5cGUiLCJzdGVwcyIsIl9kaXNhYmxlRXZlbnRPbkhhc2hDaGFuZ2UiLCJzdG9wIiwiX2VuYWJsZUV2ZW50T25IYXNoQ2hhbmdlIiwiYklnbm9yZUN1cnJlbnRIYXNoIiwiaW5pdGlhbGl6ZSIsInRoYXQiLCJvVGFyZ2V0U3RhdGUiLCJuZXdMZXZlbCIsInJlcGxhY2VBc3luYyIsInJlcGxhY2VIYXNoIiwic2V0VGltZW91dCIsImJhY2tSZXBsYWNlQXN5bmMiLCJiYWNrQXN5bmMiLCJzZXRIYXNoIiwiZ28iLCJnZXRMYXN0SGlzdG9yeUVudHJ5IiwiYUhhc2hTcGxpdCIsInNBcHBIYXNoIiwib1N0YXRlMSIsIm9TdGF0ZTIiLCJlcXVhbCIsImNoZWNrSWZCYWNrSXNPdXRPZkd1YXJkIiwic1ByZXNlbnRIYXNoIiwic1ByZXZIYXNoIiwib1NwbGl0SGFzaCIsInNwbGl0SGFzaCIsImFwcFNwZWNpZmljUm91dGUiLCJVUkkiLCJkZWNvZGUiLCJjaGVja0lmQmFja0hhc1NhbWVDb250ZXh0Iiwib0N1cnJlbnRTdGF0ZSIsIm9QcmV2aW91c1N0YXRlIiwiQmFzZU9iamVjdCJdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FBT0EsTUFBTUEsU0FBUyxHQUFHO0FBQ2pCQyxJQUFBQSxLQUFLLEVBQUUsQ0FEVTtBQUVqQkMsSUFBQUEsVUFBVSxFQUFFLENBRks7QUFHakJDLElBQUFBLFFBQVEsRUFBRSxDQUhPO0FBSWpCQyxJQUFBQSxTQUFTLEVBQUU7QUFKTSxHQUFsQjtBQU1BLE1BQU1DLGFBQWEsR0FBRztBQUNyQkMsSUFBQUEsV0FBVyxFQUFFLFFBRFE7QUFFckJDLElBQUFBLGNBQWMsRUFBRTtBQUZLLEdBQXRCO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUNBLFdBQVNDLG1CQUFULENBQTZCQyxVQUE3QixFQUFpRDtBQUNoRCxXQUFPO0FBQ05DLE1BQUFBLFVBQVUsRUFBRUQsVUFBVSxDQUFDRSxPQUFYLENBQW1CLFdBQW5CLEVBQWdDLEVBQWhDLENBRE47QUFDMkM7QUFDakRDLE1BQUFBLEtBQUssRUFBRSxVQUFTQyxLQUFULEVBQXFCO0FBQzNCLGVBQU9BLEtBQUssQ0FBQ0MsT0FBTixDQUFjLEtBQUtKLFVBQW5CLE1BQW1DLENBQTFDO0FBQ0E7QUFKSyxLQUFQO0FBTUE7QUFDRDtBQUNBO0FBQ0E7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TCxDQUFzQnJELE1BQXRCLEdBQStCLENBQXJELENBQXZCO0FBRUEsYUFBT2tMLGFBQWEsQ0FBQzlFLElBQWQsQ0FBbUJzQixLQUFuQixDQUF5QixHQUF6QixFQUE4QixDQUE5QixNQUFxQ3lELGNBQWMsQ0FBQy9FLElBQWYsQ0FBb0JzQixLQUFwQixDQUEwQixHQUExQixFQUErQixDQUEvQixDQUE1QztBQUNBLEs7OztJQXB2QndCMEQsVTtTQXV2QlgvSyxXIiwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTG9nIGZyb20gXCJzYXAvYmFzZS9Mb2dcIjtcbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gXCJzYXAvdWkvYmFzZS9PYmplY3RcIjtcbmltcG9ydCBTeW5jaHJvbml6YXRpb24gZnJvbSBcInNhcC9mZS9jb3JlL1N5bmNocm9uaXphdGlvblwiO1xuaW1wb3J0IFVSSSBmcm9tIFwic2FwL3VpL3RoaXJkcGFydHkvVVJJXCI7XG5pbXBvcnQgeyBJU2hlbGxTZXJ2aWNlcyB9IGZyb20gXCJzYXAvZmUvY29yZS9zZXJ2aWNlcy9TaGVsbFNlcnZpY2VzRmFjdG9yeVwiO1xuaW1wb3J0IFJvdXRlciBmcm9tIFwic2FwL3VpL2NvcmUvcm91dGluZy9Sb3V0ZXJcIjtcbmltcG9ydCB7IFVJNUNsYXNzIH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvQ2xhc3NTdXBwb3J0XCI7XG5pbXBvcnQgUmVzb3VyY2VCdW5kbGUgZnJvbSBcInNhcC9iYXNlL2kxOG4vUmVzb3VyY2VCdW5kbGVcIjtcblxuY29uc3QgZW51bVN0YXRlID0ge1xuXHRFUVVBTDogMCxcblx0Q09NUEFUSUJMRTogMSxcblx0QU5DRVNUT1I6IDIsXG5cdERJRkZFUkVOVDogM1xufTtcbmNvbnN0IGVudW1VUkxQYXJhbXMgPSB7XG5cdExBWU9VVFBBUkFNOiBcImxheW91dFwiLFxuXHRJQVBQU1RBVEVQQVJBTTogXCJzYXAtaWFwcC1zdGF0ZVwiXG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBIYXNoR3VhcmQgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzR3VhcmRIYXNoIFRoZSBoYXNoIHVzZWQgZm9yIHRoZSBndWFyZFxuICogQHJldHVybnMge29iamVjdH0gVGhlIGNyZWF0ZWQgaGFzaCBndWFyZFxuICovXG5mdW5jdGlvbiBjcmVhdGVHdWFyZEZyb21IYXNoKHNHdWFyZEhhc2g6IHN0cmluZykge1xuXHRyZXR1cm4ge1xuXHRcdF9ndWFyZEhhc2g6IHNHdWFyZEhhc2gucmVwbGFjZSgvXFw/W15cXD9dKiQvLCBcIlwiKSwgLy8gUmVtb3ZlIHF1ZXJ5IHBhcnRcblx0XHRjaGVjazogZnVuY3Rpb24oc0hhc2g6IGFueSkge1xuXHRcdFx0cmV0dXJuIHNIYXNoLmluZGV4T2YodGhpcy5fZ3VhcmRIYXNoKSA9PT0gMDtcblx0XHR9XG5cdH07XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGlBcHBTdGF0ZSBwYXJ0IGZyb20gYSBoYXNoIChvciBudWxsIGlmIG5vdCBmb3VuZCkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNIYXNoIFRoZSBoYXNoXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgaUFwcFN0YXRlIHBhcnQgb2YgdGhlIGhhc2hcbiAqL1xuZnVuY3Rpb24gZmluZEFwcFN0YXRlSW5IYXNoKHNIYXNoOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcblx0Y29uc3QgYUFwcFN0YXRlID0gc0hhc2gubWF0Y2gobmV3IFJlZ0V4cChcIlxcXFw/LipcIiArIGVudW1VUkxQYXJhbXMuSUFQUFNUQVRFUEFSQU0gKyBcIj0oW14mXSopXCIpKTtcblx0cmV0dXJuIGFBcHBTdGF0ZSAmJiBhQXBwU3RhdGUubGVuZ3RoID4gMSA/IGFBcHBTdGF0ZVsxXSA6IG51bGw7XG59XG4vKipcbiAqIFJldHVybnMgYSBoYXNoIHdpdGhvdXQgaXRzIGlBcHBTdGF0ZSBwYXJ0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzSGFzaCBUaGUgaGFzaFxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGhhc2ggd2l0aG91dCB0aGUgaUFwcFN0YXRlXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUFwcFN0YXRlSW5IYXNoKHNIYXNoOiBzdHJpbmcpIHtcblx0cmV0dXJuIHNIYXNoLnJlcGxhY2UobmV3IFJlZ0V4cChcIlsmP10qXCIgKyBlbnVtVVJMUGFyYW1zLklBUFBTVEFURVBBUkFNICsgXCI9W14mXSpcIiksIFwiXCIpO1xufVxuLyoqXG4gKiBBZGRzIGFuIGlBcHBTdGF0ZSBpbnNpZGUgYSBoYXNoIChvciByZXBsYWNlcyBhbiBleGlzdGluZyBvbmUpLlxuICpcbiAqIEBwYXJhbSB7Kn0gc0hhc2ggVGhlIGhhc2hcbiAqIEBwYXJhbSB7Kn0gc0FwcFN0YXRlS2V5IFRoZSBpQXBwU3RhdGUgdG8gYWRkXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgaGFzaCB3aXRoIHRoZSBhcHAgc3RhdGVcbiAqL1xuZnVuY3Rpb24gc2V0QXBwU3RhdGVJbkhhc2goc0hhc2g6IGFueSwgc0FwcFN0YXRlS2V5OiBhbnkpIHtcblx0bGV0IHNOZXdIYXNoO1xuXG5cdGlmIChzSGFzaC5pbmRleE9mKGVudW1VUkxQYXJhbXMuSUFQUFNUQVRFUEFSQU0pID49IDApIHtcblx0XHQvLyBJZiB0aGVyZSdzIGFscmVhZHkgYW4gaUFwcFN0YXRlIHBhcmFtZXRlciBpbiB0aGUgaGFzaCwgcmVwbGFjZSBpdFxuXHRcdHNOZXdIYXNoID0gc0hhc2gucmVwbGFjZShuZXcgUmVnRXhwKGVudW1VUkxQYXJhbXMuSUFQUFNUQVRFUEFSQU0gKyBcIj1bXiZdKlwiKSwgZW51bVVSTFBhcmFtcy5JQVBQU1RBVEVQQVJBTSArIFwiPVwiICsgc0FwcFN0YXRlS2V5KTtcblx0fSBlbHNlIHtcblx0XHQvLyBBZGQgdGhlIGlBcHBTdGF0ZSBwYXJhbWV0ZXIgaW4gdGhlIGhhc2hcblx0XHRpZiAoc0hhc2guaW5kZXhPZihcIj9cIikgPCAwKSB7XG5cdFx0XHRzTmV3SGFzaCA9IHNIYXNoICsgXCI/XCI7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNOZXdIYXNoID0gc0hhc2ggKyBcIiZcIjtcblx0XHR9XG5cdFx0c05ld0hhc2ggKz0gZW51bVVSTFBhcmFtcy5JQVBQU1RBVEVQQVJBTSArIFwiPVwiICsgc0FwcFN0YXRlS2V5O1xuXHR9XG5cblx0cmV0dXJuIHNOZXdIYXNoO1xufVxuXG5AVUk1Q2xhc3MoXCJzYXAuZmUuY29yZS5Sb3V0ZXJQcm94eVwiKVxuY2xhc3MgUm91dGVyUHJveHkgZXh0ZW5kcyBCYXNlT2JqZWN0IHtcblx0YklzUmVidWlsZEhpc3RvcnlSdW5uaW5nID0gZmFsc2U7XG5cdGJJc0NvbXB1dGluZ1RpdGxlSGllcmFjaHkgPSBmYWxzZTtcblx0YklzR3VhcmRDcm9zc0FsbG93ZWQgPSBmYWxzZTtcblx0c0lBcHBTdGF0ZUtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cdF9vU2hlbGxTZXJ2aWNlcyE6IElTaGVsbFNlcnZpY2VzO1xuXHRmY2xFbmFibGVkITogYm9vbGVhbjtcblx0X2ZuQmxvY2tpbmdOYXZGaWx0ZXIhOiBGdW5jdGlvbjtcblx0X2ZuSGFzaEd1YXJkITogRnVuY3Rpb247XG5cdF9iRGlzYWJsZU9uSGFzaENoYW5nZSE6IGJvb2xlYW47XG5cdF9iSWdub3JlUmVzdG9yZSE6IGJvb2xlYW47XG5cdF9iQ2xlYW5lZFJlc3RvcmUhOiBib29sZWFuO1xuXHRfYkZvcmNlRm9jdXMhOiBib29sZWFuO1xuXHRfb1JvdXRlciE6IFJvdXRlcjtcblx0X29NYW5hZ2VkSGlzdG9yeSE6IGFueVtdO1xuXHRfb05hdmlnYXRpb25HdWFyZDogYW55O1xuXHRvUmVzb3VyY2VCdW5kbGU/OiBSZXNvdXJjZUJ1bmRsZTtcblx0X29Sb3V0ZU1hdGNoU3luY2hyb25pemF0aW9uPzogU3luY2hyb25pemF0aW9uO1xuXHRfYkFjdGl2YXRlUm91dGVNYXRjaFN5bmNocm86IGJvb2xlYW4gPSBmYWxzZTtcblx0X2JBcHBseVJlc3RvcmU6IGJvb2xlYW4gPSBmYWxzZTtcblx0X2JEZWxheWVkUmVidWlsZDogYm9vbGVhbiA9IGZhbHNlO1xuXG5cdGluaXQob0FwcENvbXBvbmVudDogYW55LCBpc2ZjbEVuYWJsZWQ6IGJvb2xlYW4pIHtcblx0XHQvLyBTYXZlIHRoZSBuYW1lIG9mIHRoZSBhcHAgKGluY2x1ZGluZyBzdGFydHVwIHBhcmFtZXRlcnMpIGZvciByZWJ1aWxkaW5nIGZ1bGwgaGFzaGVzIGxhdGVyXG5cdFx0b0FwcENvbXBvbmVudFxuXHRcdFx0LmdldFNlcnZpY2UoXCJzaGVsbFNlcnZpY2VzXCIpXG5cdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdHRoaXMuX29TaGVsbFNlcnZpY2VzID0gb0FwcENvbXBvbmVudC5nZXRTaGVsbFNlcnZpY2VzKCk7XG5cblx0XHRcdFx0dGhpcy5pbml0UmF3KG9BcHBDb21wb25lbnQuZ2V0Um91dGVyKCkpO1xuXHRcdFx0XHQvLyBXZSB3YW50IHRvIHdhaXQgdW50aWwgdGhlIGluaXRpYWwgcm91dGVNYXRjaGVkIGlzIGRvbmUgYmVmb3JlIGRvaW5nIGFueSBuYXZpZ2F0aW9uXG5cdFx0XHRcdHRoaXMud2FpdEZvclJvdXRlTWF0Y2hCZWZvcmVOYXZpZ2F0aW9uKCk7XG5cblx0XHRcdFx0Ly8gU2V0IGZlTGV2ZWw9MCBmb3IgdGhlIGZpcnN0IEFwcGxpY2F0aW9uIHBhZ2UgaW4gdGhlIGhpc3Rvcnlcblx0XHRcdFx0aGlzdG9yeS5yZXBsYWNlU3RhdGUoXG5cdFx0XHRcdFx0T2JqZWN0LmFzc2lnbihcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0ZmVMZXZlbDogMFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdGhpc3Rvcnkuc3RhdGVcblx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdFwiXCIsXG5cdFx0XHRcdFx0d2luZG93LmxvY2F0aW9uIGFzIGFueVxuXHRcdFx0XHQpO1xuXHRcdFx0XHR0aGlzLmZjbEVuYWJsZWQgPSBpc2ZjbEVuYWJsZWQ7XG5cblx0XHRcdFx0dGhpcy5fZm5CbG9ja2luZ05hdkZpbHRlciA9IHRoaXMuX2Jsb2NraW5nTmF2aWdhdGlvbkZpbHRlci5iaW5kKHRoaXMpO1xuXHRcdFx0XHR0aGlzLl9vU2hlbGxTZXJ2aWNlcy5yZWdpc3Rlck5hdmlnYXRpb25GaWx0ZXIodGhpcy5fZm5CbG9ja2luZ05hdkZpbHRlcik7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdExvZy5lcnJvcihcIkNhbm5vdCByZXRyaWV2ZSB0aGUgc2hlbGwgc2VydmljZXNcIiwgb0Vycm9yKTtcblx0XHRcdH0pO1xuXHRcdHRoaXMuX2ZuSGFzaEd1YXJkID0gdGhpcy5oYXNoR3VhcmQuYmluZCh0aGlzKTtcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBvcHN0YXRlXCIsIHRoaXMuX2ZuSGFzaEd1YXJkIGFzIGFueSk7XG5cdFx0dGhpcy5fYkRpc2FibGVPbkhhc2hDaGFuZ2UgPSBmYWxzZTtcblx0XHR0aGlzLl9iSWdub3JlUmVzdG9yZSA9IGZhbHNlO1xuXHRcdHRoaXMuX2JDbGVhbmVkUmVzdG9yZSA9IGZhbHNlO1xuXHRcdHRoaXMuX2JGb3JjZUZvY3VzID0gdHJ1ZTsgLy8gVHJpZ2dlciB0aGUgZm9jdXMgbWVjaGFuaXNtIGZvciB0aGUgZmlyc3QgdmlldyBkaXNwbGF5ZWQgYnkgdGhlIGFwcFxuXHR9XG5cblx0ZGVzdHJveSgpIHtcblx0XHRpZiAodGhpcy5fb1NoZWxsU2VydmljZXMpIHtcblx0XHRcdHRoaXMuX29TaGVsbFNlcnZpY2VzLnVucmVnaXN0ZXJOYXZpZ2F0aW9uRmlsdGVyKHRoaXMuX2ZuQmxvY2tpbmdOYXZGaWx0ZXIpO1xuXHRcdH1cblx0XHR3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBvcHN0YXRlXCIsIHRoaXMuX2ZuSGFzaEd1YXJkIGFzIGFueSk7XG5cdH1cblxuXHQvKipcblx0ICogUmF3IGluaXRpYWxpemF0aW9uIChmb3IgdW5pdCB0ZXN0cykuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c2FwLnVpLmNvcmUucm91dGluZy5Sb3V0ZXJ9IG9Sb3V0ZXIgVGhlIHJvdXRlciB1c2VkIGJ5IHRoaXMgcHJveHlcblx0ICovXG5cdGluaXRSYXcob1JvdXRlcjogUm91dGVyKSB7XG5cdFx0dGhpcy5fb1JvdXRlciA9IG9Sb3V0ZXI7XG5cdFx0dGhpcy5fb01hbmFnZWRIaXN0b3J5ID0gW107XG5cdFx0dGhpcy5fb05hdmlnYXRpb25HdWFyZCA9IG51bGw7XG5cblx0XHRjb25zdCBzQ3VycmVudEFwcEhhc2ggPSB0aGlzLmdldEhhc2goKTtcblx0XHR0aGlzLl9vTWFuYWdlZEhpc3RvcnkucHVzaCh0aGlzLl9leHRyYWN0U3RhdGVGcm9tSGFzaChzQ3VycmVudEFwcEhhc2gpKTtcblxuXHRcdC8vIFNldCB0aGUgaUFwcFN0YXRlIGlmIHRoZSBpbml0aWFsIGhhc2ggY29udGFpbnMgb25lXG5cdFx0dGhpcy5zSUFwcFN0YXRlS2V5ID0gZmluZEFwcFN0YXRlSW5IYXNoKHNDdXJyZW50QXBwSGFzaCk7XG5cdH1cblxuXHRnZXRIYXNoKCkge1xuXHRcdHJldHVybiB0aGlzLl9vUm91dGVyLmdldEhhc2hDaGFuZ2VyKCkuZ2V0SGFzaCgpO1xuXHR9XG5cblx0aXNGb2N1c0ZvcmNlZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5fYkZvcmNlRm9jdXM7XG5cdH1cblxuXHRzZXRGb2N1c0ZvcmNlZChiRm9yY2VkOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fYkZvcmNlRm9jdXMgPSBiRm9yY2VkO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlc2V0cyB0aGUgaW50ZXJuYWwgdmFyaWFibGUgc0lBcHBTdGF0ZUtleS5cblx0ICpcblx0ICogQGZ1bmN0aW9uXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlJvdXRlclByb3h5I3JlbW92ZUlBcHBTdGF0ZUtleVxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cdHJlbW92ZUlBcHBTdGF0ZUtleSgpIHtcblx0XHR0aGlzLnNJQXBwU3RhdGVLZXkgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIE5hdmlnYXRlcyB0byBhIHNwZWNpZmljIGhhc2guXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAbmFtZSBzYXAuZmUuY29yZS5Sb3V0ZXJQcm94eSNuYXZUb0hhc2hcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlJvdXRlclByb3h5XG5cdCAqIEBzdGF0aWNcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNIYXNoIEhhc2ggdG8gYmUgbmF2aWdhdGVkIHRvXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gYlByZXNlcnZlSGlzdG9yeSBJZiBzZXQgdG8gdHJ1ZSwgbm9uLWFuY2VzdG9yIGVudHJpZXMgaW4gaGlzdG9yeSB3aWxsIGJlIHJldGFpbmVkXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gYkRpc2FibGVQcmVzZXJ2YXRpb25DYWNoZSBJZiBzZXQgdG8gdHJ1ZSwgY2FjaGUgcHJlc2VydmF0aW9uIG1lY2hhbmlzbSBpcyBkaXNhYmxlZCBmb3IgdGhlIGN1cnJlbnQgbmF2aWdhdGlvblxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGJGb3JjZUZvY3VzIElmIHNldCB0byB0cnVlLCB0aGUgbG9naWMgdG8gc2V0IHRoZSBmb2N1cyBvbmNlIHRoZSBuYXZpZ2F0aW9uIGlzIGZpbmFsaXplZCB3aWxsIGJlIHRyaWdnZXJlZCAob25QYWdlUmVhZHkpXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gYlByZXNlcnZlU2hlbGxCYWNrTmF2aWdhdGlvbkhhbmRsZXIgSWYgbm90IHNldCB0byBmYWxzZSwgdGhlIGJhY2sgbmF2aWdhdGlvbiBpcyBzZXQgdG8gdW5kZWZpbmVkXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIChyZXNvbHZlZCB3aGVuIHRoZSBuYXZpZ2F0aW9uIGlzIGZpbmFsaXplZCkgdGhhdCByZXR1cm5zICd0cnVlJyBpZiBhIG5hdmlnYXRpb24gdG9vayBwbGFjZSwgJ2ZhbHNlJyBpZiB0aGUgbmF2aWdhdGlvbiBkaWRuJ3QgaGFwcGVuXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0bmF2VG9IYXNoKFxuXHRcdHNIYXNoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdFx0YlByZXNlcnZlSGlzdG9yeT86IGJvb2xlYW4sXG5cdFx0YkRpc2FibGVQcmVzZXJ2YXRpb25DYWNoZT86IGJvb2xlYW4sXG5cdFx0YkZvcmNlRm9jdXM/OiBib29sZWFuLFxuXHRcdGJQcmVzZXJ2ZVNoZWxsQmFja05hdmlnYXRpb25IYW5kbGVyPzogYm9vbGVhblxuXHQpIHtcblx0XHRpZiAoYlByZXNlcnZlU2hlbGxCYWNrTmF2aWdhdGlvbkhhbmRsZXIgIT09IGZhbHNlKSB7XG5cdFx0XHR0aGlzLl9vU2hlbGxTZXJ2aWNlcy5zZXRCYWNrTmF2aWdhdGlvbigpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5fb1JvdXRlTWF0Y2hTeW5jaHJvbml6YXRpb24pIHtcblx0XHRcdHJldHVybiB0aGlzLl9vUm91dGVNYXRjaFN5bmNocm9uaXphdGlvbi53YWl0Rm9yKCkudGhlbigoKSA9PiB7XG5cdFx0XHRcdHRoaXMuX29Sb3V0ZU1hdGNoU3luY2hyb25pemF0aW9uID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5faW50ZXJuYWxOYXZUb0hhc2goc0hhc2gsIGJQcmVzZXJ2ZUhpc3RvcnksIGJEaXNhYmxlUHJlc2VydmF0aW9uQ2FjaGUsIGJGb3JjZUZvY3VzKTtcblx0XHRcdH0pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodGhpcy5fYkFjdGl2YXRlUm91dGVNYXRjaFN5bmNocm8pIHtcblx0XHRcdFx0dGhpcy53YWl0Rm9yUm91dGVNYXRjaEJlZm9yZU5hdmlnYXRpb24oKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzLl9pbnRlcm5hbE5hdlRvSGFzaChzSGFzaCwgYlByZXNlcnZlSGlzdG9yeSwgYkRpc2FibGVQcmVzZXJ2YXRpb25DYWNoZSwgYkZvcmNlRm9jdXMpO1xuXHRcdH1cblx0fVxuXG5cdF9pbnRlcm5hbE5hdlRvSGFzaChzSGFzaDogYW55LCBiUHJlc2VydmVIaXN0b3J5OiBhbnksIGJEaXNhYmxlUHJlc2VydmF0aW9uQ2FjaGU6IGFueSwgYkZvcmNlRm9jdXM/OiBib29sZWFuKSB7XG5cdFx0Ly8gQWRkIHRoZSBhcHAgc3RhdGUgaW4gdGhlIGhhc2ggaWYgbmVlZGVkXG5cdFx0aWYgKHRoaXMuZmNsRW5hYmxlZCAmJiB0aGlzLnNJQXBwU3RhdGVLZXkgJiYgIWZpbmRBcHBTdGF0ZUluSGFzaChzSGFzaCkpIHtcblx0XHRcdHNIYXNoID0gc2V0QXBwU3RhdGVJbkhhc2goc0hhc2gsIHRoaXMuc0lBcHBTdGF0ZUtleSk7XG5cdFx0fVxuXG5cdFx0aWYgKCF0aGlzLmNoZWNrSGFzaFdpdGhHdWFyZChzSGFzaCkpIHtcblx0XHRcdGlmICghdGhpcy5vUmVzb3VyY2VCdW5kbGUpIHtcblx0XHRcdFx0dGhpcy5vUmVzb3VyY2VCdW5kbGUgPSBzYXAudWkuZ2V0Q29yZSgpLmdldExpYnJhcnlSZXNvdXJjZUJ1bmRsZShcInNhcC5mZS5jb3JlXCIpIGFzIFJlc291cmNlQnVuZGxlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXZSBoYXZlIHRvIHVzZSBhIGNvbmZpcm0gaGVyZSBmb3IgVUkgY29uc2lzdGVuY3kgcmVhc29ucywgYXMgd2l0aCBzb21lIHNjZW5hcmlvc1xuXHRcdFx0Ly8gaW4gdGhlIEVkaXRGbG93IHdlIHJlbHkgb24gYSBVSTUgbWVjaGFuaXNtIHRoYXQgZGlzcGxheXMgYSBjb25maXJtIGRpYWxvZy5cblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hbGVydFxuXHRcdFx0aWYgKCFjb25maXJtKHRoaXMub1Jlc291cmNlQnVuZGxlLmdldFRleHQoXCJDX1JPVVRFUl9QUk9YWV9TQVBGRV9FWElUX05PVFNBVkVEX01FU1NBR0VcIikpKSB7XG5cdFx0XHRcdC8vIFRoZSB1c2VyIGNsaWNrZWQgb24gQ2FuY2VsIC0tPiBjYW5jZWwgbmF2aWdhdGlvblxuXHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuYklzR3VhcmRDcm9zc0FsbG93ZWQgPSB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIEluIGNhc2UgdGhlIG5hdmlnYXRpb24gd2lsbCBjYXVzZSBhIG5ldyB2aWV3IHRvIGJlIGRpc3BsYXllZCwgd2UgZm9yY2UgdGhlIGZvY3VzXG5cdFx0Ly8gSS5lLiBpZiB0aGUga2V5cyBmb3IgdGhlIGhhc2ggd2UncmUgbmF2aWdhdGluZyB0byBpcyBhIHN1cGVyc2V0IG9mIHRoZSBjdXJyZW50IGhhc2gga2V5cy5cblx0XHRjb25zdCBvTmV3U3RhdGUgPSB0aGlzLl9leHRyYWN0U3RhdGVGcm9tSGFzaChzSGFzaCk7XG5cdFx0aWYgKCF0aGlzLl9iRm9yY2VGb2N1cykge1xuXHRcdFx0Ly8gSWYgdGhlIGZvY3VzIHdhcyBhbHJlYWR5IGZvcmNlZCwga2VlcCBpdFxuXHRcdFx0Y29uc3QgYUN1cnJlbnRIYXNoS2V5cyA9IHRoaXMuX2V4dHJhY3RLZXlzRnJvbUhhc2godGhpcy5nZXRIYXNoKCkpO1xuXHRcdFx0dGhpcy5fYkZvcmNlRm9jdXMgPVxuXHRcdFx0XHRiRm9yY2VGb2N1cyB8fFxuXHRcdFx0XHQoYUN1cnJlbnRIYXNoS2V5cy5sZW5ndGggPCBvTmV3U3RhdGUua2V5cy5sZW5ndGggJiZcblx0XHRcdFx0XHRhQ3VycmVudEhhc2hLZXlzLmV2ZXJ5KGZ1bmN0aW9uKGtleTogYW55LCBpbmRleDogYW55KSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4ga2V5ID09PSBvTmV3U3RhdGUua2V5c1tpbmRleF07XG5cdFx0XHRcdFx0fSkpO1xuXHRcdH1cblxuXHRcdGNvbnN0IG9IaXN0b3J5QWN0aW9uID0gdGhpcy5fcHVzaE5ld1N0YXRlKG9OZXdTdGF0ZSwgZmFsc2UsIGJQcmVzZXJ2ZUhpc3RvcnksIGJEaXNhYmxlUHJlc2VydmF0aW9uQ2FjaGUpO1xuXG5cdFx0cmV0dXJuIHRoaXMuX3JlYnVpbGRCcm93c2VySGlzdG9yeShvSGlzdG9yeUFjdGlvbiwgZmFsc2UpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFycyBicm93c2VyIGhpc3RvcnkgaWYgZW50cmllcyBoYXZlIGJlZW4gYWRkZWQgd2l0aG91dCB1c2luZyB0aGUgUm91dGVyUHJveHkuXG5cdCAqIFVwZGF0ZXMgdGhlIGludGVybmFsIGhpc3RvcnkgYWNjb3JkaW5nbHkuXG5cdCAqXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRoYXQgaXMgcmVzb2x2ZWQgb25jZSB0aGUgaGlzdG9yeSBpcyByZWJ1aWx0XG5cdCAqL1xuXHRyZXN0b3JlSGlzdG9yeSgpIHtcblx0XHRpZiAodGhpcy5fYkFwcGx5UmVzdG9yZSkge1xuXHRcdFx0dGhpcy5fYkFwcGx5UmVzdG9yZSA9IGZhbHNlO1xuXHRcdFx0bGV0IHNUYXJnZXRIYXNoID0gdGhpcy5nZXRIYXNoKCk7XG5cdFx0XHRzVGFyZ2V0SGFzaCA9IHNUYXJnZXRIYXNoLnJlcGxhY2UoLyhcXD98JilyZXN0b3JlSGlzdG9yeT10cnVlLywgXCJcIik7XG5cdFx0XHRjb25zdCBvTmV3U3RhdGUgPSB0aGlzLl9leHRyYWN0U3RhdGVGcm9tSGFzaChzVGFyZ2V0SGFzaCk7XG5cblx0XHRcdGNvbnN0IG9IaXN0b3J5QWN0aW9uID0gdGhpcy5fcHVzaE5ld1N0YXRlKG9OZXdTdGF0ZSwgdHJ1ZSwgZmFsc2UsIHRydWUpO1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5fcmVidWlsZEJyb3dzZXJIaXN0b3J5KG9IaXN0b3J5QWN0aW9uLCB0cnVlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBOYXZpZ2F0ZXMgYmFjayBpbiB0aGUgaGlzdG9yeS5cblx0ICpcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdGhhdCBpcyByZXNvbHZlZCB3aGVuIHRoZSBuYXZpZ2F0aW9uIGlzIGZpbmFsaXplZFxuXHQgKi9cblx0bmF2QmFjaygpIHtcblx0XHRjb25zdCBzQ3VycmVudEhhc2ggPSB0aGlzLmdldEhhc2goKTtcblx0XHRsZXQgc1ByZXZpb3VzSGFzaDtcblxuXHRcdC8vIExvb2sgZm9yIHRoZSBjdXJyZW50IGhhc2ggaW4gdGhlIG1hbmFnZWQgaGlzdG9yeVxuXHRcdGZvciAobGV0IGkgPSB0aGlzLl9vTWFuYWdlZEhpc3RvcnkubGVuZ3RoIC0gMTsgaSA+IDA7IGktLSkge1xuXHRcdFx0aWYgKHRoaXMuX29NYW5hZ2VkSGlzdG9yeVtpXS5oYXNoID09PSBzQ3VycmVudEhhc2gpIHtcblx0XHRcdFx0c1ByZXZpb3VzSGFzaCA9IHRoaXMuX29NYW5hZ2VkSGlzdG9yeVtpIC0gMV0uaGFzaDtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHNQcmV2aW91c0hhc2gpIHtcblx0XHRcdHJldHVybiB0aGlzLm5hdlRvSGFzaChzUHJldmlvdXNIYXNoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gV2UgY291bGRuJ3QgZmluZCBhIHByZXZpb3VzIGhhc2ggaW4gaGlzdG9yeVxuXHRcdFx0Ly8gVGhpcyBjYW4gaGFwcGVuIHdoZW4gbmF2aWdhdGluZyBmcm9tIGEgdHJhbnNpZW50IGhhc2ggaW4gYSBjcmVhdGUgYXBwLCBhbmRcblx0XHRcdC8vIGluIHRoYXQgY2FzZSBoaXN0b3J5LmJhY2sgd291bGQgZ28gYmFjayB0byB0aGUgRkxQXG5cdFx0XHR3aW5kb3cuaGlzdG9yeS5iYWNrKCk7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE5hdmlnYXRlcyB0byBhIHJvdXRlIHdpdGggcGFyYW1ldGVycy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHNSb3V0ZU5hbWUgVGhlIHJvdXRlIG5hbWUgdG8gYmUgbmF2aWdhdGVkIHRvXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvUGFyYW1ldGVycyBQYXJhbWV0ZXJzIGZvciB0aGUgbmF2aWdhdGlvblxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdoZW4gdGhlIG5hdmlnYXRpb24gaXMgZmluYWxpemVkXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0bmF2VG8oc1JvdXRlTmFtZTogc3RyaW5nLCBvUGFyYW1ldGVyczogYW55KSB7XG5cdFx0Y29uc3Qgc0hhc2ggPSB0aGlzLl9vUm91dGVyLmdldFVSTChzUm91dGVOYW1lLCBvUGFyYW1ldGVycyk7XG5cdFx0cmV0dXJuIHRoaXMubmF2VG9IYXNoKHNIYXNoLCBmYWxzZSwgb1BhcmFtZXRlcnMubm9QcmVzZXJ2YXRpb25DYWNoZSwgZmFsc2UsICFvUGFyYW1ldGVycy5iSXNTdGlja3lNb2RlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeGl0cyB0aGUgY3VycmVudCBhcHAgYnkgbmF2aWdhdGluZyBiYWNrXG5cdCAqIHRvIHRoZSBwcmV2aW91cyBhcHAgKGlmIGFueSkgb3IgdGhlIEZMUC5cblx0ICpcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdGhhdCBpcyByZXNvbHZlZCB3aGVuIHdlIGV4aXQgdGhlIGFwcFxuXHQgKi9cblx0ZXhpdEZyb21BcHAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX29TaGVsbFNlcnZpY2VzLmJhY2tUb1ByZXZpb3VzQXBwKCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIHdoZXRoZXIgYSBnaXZlbiBoYXNoIGNhbiBoYXZlIGFuIGltcGFjdCBvbiB0aGUgY3VycmVudCBzdGF0ZVxuXHQgKiBpLmUuIGlmIHRoZSBoYXNoIGlzIGVxdWFsLCBjb21wYXRpYmxlIG9yIGFuIGFuY2VzdG9yIG9mIHRoZSBjdXJyZW50IHN0YXRlLlxuXHQgKlxuXHQgKiBAcGFyYW0geyp9IHNIYXNoIGB0cnVlYCBpZiB0aGVyZSBpcyBhbiBpbXBhY3Rcblx0ICogQHJldHVybnMge2Jvb2xlYW59IElmIHRoZXJlIGlzIGFuIGltcGFjdFxuXHQgKi9cblx0aXNDdXJyZW50U3RhdGVJbXBhY3RlZEJ5KHNIYXNoOiBhbnkpIHtcblx0XHRpZiAoc0hhc2hbMF0gPT09IFwiL1wiKSB7XG5cdFx0XHRzSGFzaCA9IHNIYXNoLnN1YnN0cmluZygxKTtcblx0XHR9XG5cdFx0Y29uc3Qgb0xvY2FsR3VhcmQgPSBjcmVhdGVHdWFyZEZyb21IYXNoKHNIYXNoKTtcblx0XHRyZXR1cm4gb0xvY2FsR3VhcmQuY2hlY2sodGhpcy5nZXRIYXNoKCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBhIG5hdmlnYXRpb24gaXMgY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZC5cblx0ICpcblx0ICogQHJldHVybnMge2Jvb2xlYW59IGBmYWxzZWAgaWYgYSBuYXZpZ2F0aW9uIGhhcyBiZWVuIHRyaWdnZXJlZCBpbiB0aGUgUm91dGVyUHJveHkgYW5kIGlzIG5vdCB5ZXQgZmluYWxpemVkXG5cdCAqL1xuXHRpc05hdmlnYXRpb25GaW5hbGl6ZWQoKSB7XG5cdFx0cmV0dXJuICF0aGlzLmJJc1JlYnVpbGRIaXN0b3J5UnVubmluZyAmJiAhdGhpcy5fYkRlbGF5ZWRSZWJ1aWxkO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGxhc3Qgc3RhdGUgYXMgYSBndWFyZC5cblx0ICogRWFjaCBmdXR1cmUgbmF2aWdhdGlvbiB3aWxsIGJlIGNoZWNrZWQgYWdhaW5zdCB0aGlzIGd1YXJkLCBhbmQgYSBjb25maXJtYXRpb24gZGlhbG9nIHdpbGxcblx0ICogYmUgZGlzcGxheWVkIGJlZm9yZSB0aGUgbmF2aWdhdGlvbiBjcm9zc2VzIHRoZSBndWFyZCAoaS5lLiBnb2VzIHRvIGFuIGFuY2VzdG9yIG9mIHRoZSBndWFyZCkuXG5cdCAqL1xuXHRzZXROYXZpZ2F0aW9uR3VhcmQoKSB7XG5cdFx0dGhpcy5fb05hdmlnYXRpb25HdWFyZCA9IGNyZWF0ZUd1YXJkRnJvbUhhc2godGhpcy5nZXRIYXNoKCkpO1xuXHRcdHRoaXMuYklzR3VhcmRDcm9zc0FsbG93ZWQgPSBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNhYmxlcyB0aGUgbmF2aWdhdGlvbiBndWFyZC5cblx0ICovXG5cdGRpc2NhcmROYXZpZ2F0aW9uR3VhcmQoKSB7XG5cdFx0dGhpcy5fb05hdmlnYXRpb25HdWFyZCA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGZvciB0aGUgYXZhaWxhYmlsaXR5IG9mIHRoZSBuYXZpZ2F0aW9uIGd1YXJkLlxuXHQgKlxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIG5hdmlnYXRpbmcgZ3VhcmQgaXMgYXZhaWxhYmxlXG5cdCAqL1xuXHRoYXNOYXZpZ2F0aW9uR3VhcmQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX29OYXZpZ2F0aW9uR3VhcmQgIT09IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogVGVzdHMgYSBoYXNoIGFnYWluc3QgdGhlIG5hdmlnYXRpb24gZ3VhcmQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzSGFzaCBUaGUgaGFzaCB0byBiZSB0ZXN0ZWRcblx0ICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBuYXZpZ2F0aW5nIHRvIHRoZSBoYXNoIGRvZXNuJ3QgY3Jvc3MgdGhlIGd1YXJkXG5cdCAqL1xuXHRjaGVja0hhc2hXaXRoR3VhcmQoc0hhc2g6IHN0cmluZykge1xuXHRcdHJldHVybiB0aGlzLl9vTmF2aWdhdGlvbkd1YXJkID09PSBudWxsIHx8IHRoaXMuX29OYXZpZ2F0aW9uR3VhcmQuY2hlY2soc0hhc2gpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgdXNlciBhbGxvd2VkIHRoZSBuYXZpZ2F0aW9uIGd1YXJkIHRvIGJlIGNyb3NzZWQuXG5cdCAqXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgY3Jvc3NpbmcgdGhlIGd1YXJkIGhhcyBiZWVuIGFsbG93ZWQgYnkgdGhlIHVzZXJcblx0ICovXG5cdGlzR3VhcmRDcm9zc0FsbG93ZWRCeVVzZXIoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYklzR3VhcmRDcm9zc0FsbG93ZWQ7XG5cdH1cblxuXHQvKipcblx0ICogQWN0aXZhdGVzIHRoZSBzeW5jaHJvbml6YXRpb24gZm9yIHJvdXRlTWF0Y2hlZEV2ZW50LlxuXHQgKiBUaGUgbmV4dCBOYXZUb0hhc2ggY2FsbCB3aWxsIGNyZWF0ZSBhIFN5bmNocm9uaXphdGlvbiBvYmplY3QgdGhhdCB3aWxsIGJlIHJlc29sdmVkXG5cdCAqIGJ5IHRoZSBjb3JyZXNwb25kaW5nIG9uUm91dGVNYXRjaGVkIGV2ZW50LCBwcmV2ZW50aW5nIGFub3RoZXIgTmF2VG9IYXNoIHRvIGhhcHBlbiBpbiBwYXJhbGxlbC5cblx0ICovXG5cdGFjdGl2YXRlUm91dGVNYXRjaFN5bmNocm9uaXphdGlvbigpIHtcblx0XHR0aGlzLl9iQWN0aXZhdGVSb3V0ZU1hdGNoU3luY2hybyA9IHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogUmVzb2x2ZSB0aGUgcm91dGVNYXRjaCBzeW5jaHJvbml6YXRpb24gb2JqZWN0LCB1bmxvY2tpbmcgcG90ZW50aWFsIHBlbmRpbmcgTmF2VG9IYXNoIGNhbGxzLlxuXHQgKi9cblx0cmVzb2x2ZVJvdXRlTWF0Y2goKSB7XG5cdFx0aWYgKHRoaXMuX29Sb3V0ZU1hdGNoU3luY2hyb25pemF0aW9uKSB7XG5cdFx0XHR0aGlzLl9vUm91dGVNYXRjaFN5bmNocm9uaXphdGlvbi5yZXNvbHZlKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1ha2VzIHN1cmUgbm8gbmF2aWdhdGlvbiBjYW4gaGFwcGVuIGJlZm9yZSBhIHJvdXRlTWF0Y2ggaGFwcGVuZWQuXG5cdCAqL1xuXHR3YWl0Rm9yUm91dGVNYXRjaEJlZm9yZU5hdmlnYXRpb24oKSB7XG5cdFx0dGhpcy5fb1JvdXRlTWF0Y2hTeW5jaHJvbml6YXRpb24gPSBuZXcgU3luY2hyb25pemF0aW9uKCk7XG5cdFx0dGhpcy5fYkFjdGl2YXRlUm91dGVNYXRjaFN5bmNocm8gPSBmYWxzZTtcblx0fVxuXG5cdF9leHRyYWN0S2V5c0Zyb21IYXNoKHNIYXNoOiBhbnkpIHtcblx0XHRpZiAoc0hhc2ggPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0c0hhc2ggPSBcIlwiO1xuXHRcdH1cblx0XHRjb25zdCBzSGFzaE5vUGFyYW1zID0gc0hhc2guc3BsaXQoXCI/XCIpWzBdOyAvLyByZW1vdmUgcGFyYW1zXG5cdFx0Y29uc3QgYVRva2VucyA9IHNIYXNoTm9QYXJhbXMuc3BsaXQoXCIvXCIpO1xuXHRcdGNvbnN0IGFLZXlzOiBhbnlbXSA9IFtdO1xuXG5cdFx0YVRva2Vucy5mb3JFYWNoKGZ1bmN0aW9uKHNUb2tlbjogYW55KSB7XG5cdFx0XHRjb25zdCByZWdleEtleSA9IC9bXlxcKFxcKV0rXFwoW15cXChcXCldK1xcKS87IC8vIGFiYyhkZWYpXG5cdFx0XHRpZiAocmVnZXhLZXkudGVzdChzVG9rZW4pKSB7XG5cdFx0XHRcdGFLZXlzLnB1c2goc1Rva2VuLnNwbGl0KFwiKFwiKVswXSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gYUtleXM7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGEgc3RhdGUgZnJvbSBhIGhhc2guXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzSGFzaCBUaGUgaGFzaCB0byBiZSB1c2VkIGFzIGVudHJ5XG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IFRoZSBzdGF0ZVxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cdF9leHRyYWN0U3RhdGVGcm9tSGFzaChzSGFzaDogc3RyaW5nKSB7XG5cdFx0aWYgKHNIYXNoID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHNIYXNoID0gXCJcIjtcblx0XHR9XG5cblx0XHRjb25zdCBvU3RhdGU6IGFueSA9IHtcblx0XHRcdGtleXM6IHRoaXMuX2V4dHJhY3RLZXlzRnJvbUhhc2goc0hhc2gpXG5cdFx0fTtcblxuXHRcdC8vIFJldHJpZXZlIGxheW91dCAoaWYgYW55KVxuXHRcdGNvbnN0IGFMYXlvdXQgPSBzSGFzaC5tYXRjaChuZXcgUmVnRXhwKFwiXFxcXD8uKlwiICsgZW51bVVSTFBhcmFtcy5MQVlPVVRQQVJBTSArIFwiPShbXiZdKilcIikpO1xuXHRcdG9TdGF0ZS5zTGF5b3V0ID0gYUxheW91dCAmJiBhTGF5b3V0Lmxlbmd0aCA+IDEgPyBhTGF5b3V0WzFdIDogbnVsbDtcblx0XHRpZiAob1N0YXRlLnNMYXlvdXQgPT09IFwiTWlkQ29sdW1uRnVsbFNjcmVlblwiKSB7XG5cdFx0XHRvU3RhdGUuc2NyZWVuTW9kZSA9IDE7XG5cdFx0fSBlbHNlIGlmIChvU3RhdGUuc0xheW91dCA9PT0gXCJFbmRDb2x1bW5GdWxsU2NyZWVuXCIpIHtcblx0XHRcdG9TdGF0ZS5zY3JlZW5Nb2RlID0gMjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b1N0YXRlLnNjcmVlbk1vZGUgPSAwO1xuXHRcdH1cblxuXHRcdG9TdGF0ZS5oYXNoID0gc0hhc2g7XG5cdFx0cmV0dXJuIG9TdGF0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbmV3IHN0YXRlIGludG8gdGhlIGludGVybmFsIGhpc3Rvcnkgc3RydWN0dXJlLlxuXHQgKiBNYWtlcyBzdXJlIHRoaXMgbmV3IHN0YXRlIGlzIGFkZGVkIGFmdGVyIGFuIGFuY2VzdG9yLlxuXHQgKiBBbHNvIHNldHMgdGhlIGlBcHBTdGF0ZSBrZXkgaW4gdGhlIHdob2xlIGhpc3RvcnkuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5Sb3V0ZXJQcm94eVxuXHQgKiBAcGFyYW0ge29iamVjdH0gb05ld1N0YXRlIFRoZSBuZXcgc3RhdGUgdG8gYmUgYWRkZWRcblx0ICogQHBhcmFtIHtib29sZWFufSBiUmVidWlsZE9ubHkgYHRydWVgIGlmIHdlJ3JlIHJlYnVpbGRpbmcgdGhlIGhpc3RvcnkgYWZ0ZXIgYSBzaGVsbCBtZW51IG5hdmlnYXRpb25cblx0ICogQHBhcmFtIHtib29sZWFufSBiUHJlc2VydmVIaXN0b3J5IElmIHNldCB0byB0cnVlLCBub24tYW5jZXN0b3IgZW50cmllcyBpbiBoaXN0b3J5IHdpbGwgYmUgcmV0YWluZWRcblx0ICogQHBhcmFtIHtib29sZWFufSBiRGlzYWJsZUhpc3RvcnlQcmVzZXJ2YXRpb24gRGlzYWJsZSB0aGUgbWVjaGFuaXNtIHRvIHJldGFpbmVkIG1hcmtlZCBlbnRyaWVzIGluIGNhY2hlXG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IFRoZSBuZXcgc3RhdGVcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0X3B1c2hOZXdTdGF0ZShvTmV3U3RhdGU6IGFueSwgYlJlYnVpbGRPbmx5OiBib29sZWFuLCBiUHJlc2VydmVIaXN0b3J5OiBib29sZWFuLCBiRGlzYWJsZUhpc3RvcnlQcmVzZXJ2YXRpb246IGJvb2xlYW4pIHtcblx0XHRjb25zdCBzQ3VycmVudEhhc2ggPSB0aGlzLmdldEhhc2goKTtcblx0XHRsZXQgbGFzdEluZGV4ID0gdGhpcy5fb01hbmFnZWRIaXN0b3J5Lmxlbmd0aCAtIDE7XG5cdFx0bGV0IGlQb3BDb3VudCA9IGJSZWJ1aWxkT25seSA/IDEgOiAwO1xuXG5cdFx0Ly8gMS4gRG8gc29tZSBjbGVhbnVwIGluIHRoZSBtYW5hZ2VkIGhpc3RvcnkgOiBpbiBjYXNlIHRoZSB1c2VyIGhhcyBuYXZpZ2F0ZWQgYmFjayBpbiB0aGUgYnJvd3NlciBoaXN0b3J5LCB3ZSBuZWVkIHRvIHJlbW92ZVxuXHRcdC8vIHRoZSBzdGF0ZXMgYWhlYWQgaW4gaGlzdG9yeSBhbmQgbWFrZSBzdXJlIHRoZSB0b3Agc3RhdGUgY29ycmVzcG9uZHMgdG8gdGhlIGN1cnJlbnQgcGFnZVxuXHRcdC8vIFdlIGRvbid0IGRvIHRoYXQgd2hlbiByZXN0b3JpbmcgdGhlIGhpc3RvcnksIGFzIHRoZSBjdXJyZW50IHN0YXRlIGhhcyBiZWVuIGFkZGVkIG9uIHRvcCBvZiB0aGUgYnJvd3NlciBoaXN0b3J5XG5cdFx0Ly8gYW5kIGlzIG5vdCByZWZsZWN0ZWQgaW4gdGhlIG1hbmFnZWQgaGlzdG9yeVxuXHRcdGlmICghYlJlYnVpbGRPbmx5KSB7XG5cdFx0XHR3aGlsZSAobGFzdEluZGV4ID49IDAgJiYgdGhpcy5fb01hbmFnZWRIaXN0b3J5W2xhc3RJbmRleF0uaGFzaCAhPT0gc0N1cnJlbnRIYXNoKSB7XG5cdFx0XHRcdHRoaXMuX29NYW5hZ2VkSGlzdG9yeS5wb3AoKTtcblx0XHRcdFx0bGFzdEluZGV4LS07XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vTWFuYWdlZEhpc3RvcnkubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRcdC8vIFdlIGNvdWxkbid0IGZpbmQgdGhlIGN1cnJlbnQgbG9jYXRpb24gaW4gdGhlIGhpc3RvcnkuIFRoaXMgY2FuIGhhcHBlbiBpZiBhIGJyb3dzZXIgcmVsb2FkXG5cdFx0XHRcdC8vIGhhcHBlbmVkLCBjYXVzaW5nIGEgcmVpbml0aWFsaXphdGlvbiBvZiB0aGUgbWFuYWdlZCBoaXN0b3J5LlxuXHRcdFx0XHQvLyBJbiB0aGF0IGNhc2UsIHdlIHVzZSB0aGUgY3VycmVudCBsb2NhdGlvbiBhcyB0aGUgbmV3IHN0YXJ0aW5nIHBvaW50IGluIHRoZSBtYW5hZ2VkIGhpc3Rvcnlcblx0XHRcdFx0dGhpcy5fb01hbmFnZWRIaXN0b3J5LnB1c2godGhpcy5fZXh0cmFjdFN0YXRlRnJvbUhhc2goc0N1cnJlbnRIYXNoKSk7XG5cdFx0XHRcdGhpc3RvcnkucmVwbGFjZVN0YXRlKE9iamVjdC5hc3NpZ24oeyBmZUxldmVsOiAwIH0sIGhpc3Rvcnkuc3RhdGUpLCBcIlwiKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyAyLiBNYXJrIHRoZSB0b3Agc3RhdGUgYXMgcHJlc2VydmVkIGlmIHJlcXVpcmVkXG5cdFx0aWYgKGJQcmVzZXJ2ZUhpc3RvcnkgJiYgIWJEaXNhYmxlSGlzdG9yeVByZXNlcnZhdGlvbikge1xuXHRcdFx0dGhpcy5fb01hbmFnZWRIaXN0b3J5W3RoaXMuX29NYW5hZ2VkSGlzdG9yeS5sZW5ndGggLSAxXS5wcmVzZXJ2ZWQgPSB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIDMuIFRoZW4gcG9wIGFsbCBzdGF0ZXMgdW50aWwgd2UgZmluZCBhbiBhbmNlc3RvciBvZiB0aGUgbmV3IHN0YXRlLCBvciB3ZSBmaW5kIGEgc3RhdGUgdGhhdCBuZWVkIHRvIGJlIHByZXNlcnZlZFxuXHRcdGxldCBvTGFzdFJlbW92ZWRJdGVtO1xuXHRcdHdoaWxlICh0aGlzLl9vTWFuYWdlZEhpc3RvcnkubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uc3Qgb1RvcFN0YXRlID0gdGhpcy5fb01hbmFnZWRIaXN0b3J5W3RoaXMuX29NYW5hZ2VkSGlzdG9yeS5sZW5ndGggLSAxXTtcblx0XHRcdGlmIChcblx0XHRcdFx0KGJEaXNhYmxlSGlzdG9yeVByZXNlcnZhdGlvbiB8fCAhb1RvcFN0YXRlLnByZXNlcnZlZCkgJiZcblx0XHRcdFx0dGhpcy5fY29tcGFyZUNhY2hlU3RhdGVzKG9Ub3BTdGF0ZSwgb05ld1N0YXRlKSAhPT0gZW51bVN0YXRlLkFOQ0VTVE9SXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gVGhlIHRvcCBzdGF0ZSBpcyBub3QgYW4gYW5jZXN0b3Igb2Ygb05ld1N0YXRlIGFuZCBpcyBub3QgcHJlc2VydmVkIC0tPiB3ZSBjYW4gcG9wIGl0XG5cdFx0XHRcdG9MYXN0UmVtb3ZlZEl0ZW0gPSB0aGlzLl9vTWFuYWdlZEhpc3RvcnkucG9wKCk7XG5cdFx0XHRcdGlQb3BDb3VudCsrO1xuXHRcdFx0fSBlbHNlIGlmIChvVG9wU3RhdGUucHJlc2VydmVkICYmIHJlbW92ZUFwcFN0YXRlSW5IYXNoKG9Ub3BTdGF0ZS5oYXNoKSA9PT0gcmVtb3ZlQXBwU3RhdGVJbkhhc2gob05ld1N0YXRlLmhhc2gpKSB7XG5cdFx0XHRcdC8vIFdlIHRyeSB0byBhZGQgYSBzdGF0ZSB0aGF0IGlzIGFscmVhZHkgaW4gY2FjaGUgKGR1ZSB0byBwcmVzZXJ2ZWQgZmxhZykgYnV0IHdpdGggYSBkaWZmZXJlbnQgaWFwcC1zdGF0ZVxuXHRcdFx0XHQvLyAtLT4gd2Ugc2hvdWxkIGRlbGV0ZSB0aGUgcHJldmlvdXMgZW50cnkgKGl0IHdpbGwgYmUgbGF0ZXIgcmVwbGFjZWQgYnkgdGhlIG5ldyBvbmUpIGFuZCBzdG9wIHBvcHBpbmdcblx0XHRcdFx0b0xhc3RSZW1vdmVkSXRlbSA9IHRoaXMuX29NYW5hZ2VkSGlzdG9yeS5wb3AoKTtcblx0XHRcdFx0aVBvcENvdW50Kys7XG5cdFx0XHRcdG9OZXdTdGF0ZS5wcmVzZXJ2ZWQgPSB0cnVlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJyZWFrOyAvLyBBbmNlc3RvciBvciBwcmVzZXJ2ZWQgc3RhdGUgZm91bmQgLS0+IHdlIHN0b3AgcG9wcGluZyBvdXQgc3RhdGVzXG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gNC4gaUFwcFN0YXRlIG1hbmFnZW1lbnRcblx0XHR0aGlzLnNJQXBwU3RhdGVLZXkgPSBmaW5kQXBwU3RhdGVJbkhhc2gob05ld1N0YXRlLmhhc2gpO1xuXHRcdGlmICh0aGlzLmZjbEVuYWJsZWQgJiYgdGhpcy5zSUFwcFN0YXRlS2V5KSB7XG5cdFx0XHQvLyBJbiBjYXNlIG9mIEZDTCwgdGhlIG5ldyBhcHAgc3RhdGUgbmVlZHMgdG8gYmUgYXBwbGllZCB0byB0aGUgd2hvbGUgaGlzdG9yeVxuXHRcdFx0dGhpcy5fb01hbmFnZWRIaXN0b3J5LmZvckVhY2goKG9NYW5hZ2VkU3RhdGU6IGFueSkgPT4ge1xuXHRcdFx0XHRvTWFuYWdlZFN0YXRlLmhhc2ggPSBzZXRBcHBTdGF0ZUluSGFzaChvTWFuYWdlZFN0YXRlLmhhc2gsIHRoaXMuc0lBcHBTdGF0ZUtleSk7XG5cdFx0XHR9KTtcblx0XHR9IGVsc2UgaWYgKCF0aGlzLmZjbEVuYWJsZWQgJiYgb0xhc3RSZW1vdmVkSXRlbSkge1xuXHRcdFx0Y29uc3Qgc1ByZXZpb3VzSUFwcFN0YXRlS2V5ID0gZmluZEFwcFN0YXRlSW5IYXNoKG9MYXN0UmVtb3ZlZEl0ZW0uaGFzaCk7XG5cdFx0XHRjb25zdCBvQ29tcGFyaXNvblN0YXRlUmVzdWx0ID0gdGhpcy5fY29tcGFyZUNhY2hlU3RhdGVzKG9MYXN0UmVtb3ZlZEl0ZW0sIG9OZXdTdGF0ZSk7XG5cdFx0XHQvLyBpZiBjdXJyZW50IHN0YXRlIGRvZXNuJ3QgY29udGFpbiBhIGktYXBwc3RhdGUgYW5kIHRoaXMgc3RhdGUgc2hvdWxkIHJlcGxhY2UgYSBzdGF0ZSBjb250YWluaW5nIGEgaUFwcFN0YXRlXG5cdFx0XHQvLyB0aGVuIHRoZSBwcmV2aW91cyBpQXBwU3RhdGUgaXMgcHJlc2VydmVkXG5cdFx0XHRpZiAoXG5cdFx0XHRcdCF0aGlzLnNJQXBwU3RhdGVLZXkgJiZcblx0XHRcdFx0c1ByZXZpb3VzSUFwcFN0YXRlS2V5ICYmXG5cdFx0XHRcdChvQ29tcGFyaXNvblN0YXRlUmVzdWx0ID09PSBlbnVtU3RhdGUuRVFVQUwgfHwgb0NvbXBhcmlzb25TdGF0ZVJlc3VsdCA9PT0gZW51bVN0YXRlLkNPTVBBVElCTEUpXG5cdFx0XHQpIHtcblx0XHRcdFx0b05ld1N0YXRlLmhhc2ggPSBzZXRBcHBTdGF0ZUluSGFzaChvTmV3U3RhdGUuaGFzaCwgc1ByZXZpb3VzSUFwcFN0YXRlS2V5KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyA1LiBOb3cgd2UgY2FuIHB1c2ggdGhlIHN0YXRlIGF0IHRoZSB0b3Agb2YgdGhlIGludGVybmFsIGhpc3Rvcnlcblx0XHRjb25zdCBiSGFzU2FtZUhhc2ggPSBvTGFzdFJlbW92ZWRJdGVtICYmIG9OZXdTdGF0ZS5oYXNoID09PSBvTGFzdFJlbW92ZWRJdGVtLmhhc2g7XG5cdFx0aWYgKHRoaXMuX29NYW5hZ2VkSGlzdG9yeS5sZW5ndGggPT09IDAgfHwgdGhpcy5fb01hbmFnZWRIaXN0b3J5W3RoaXMuX29NYW5hZ2VkSGlzdG9yeS5sZW5ndGggLSAxXS5oYXNoICE9PSBvTmV3U3RhdGUuaGFzaCkge1xuXHRcdFx0dGhpcy5fb01hbmFnZWRIaXN0b3J5LnB1c2gob05ld1N0YXRlKTtcblx0XHR9XG5cblx0XHQvLyA2LiBEZXRlcm1pbmUgd2hpY2ggYWN0aW9ucyB0byBkbyBvbiB0aGUgaGlzdG9yeVxuXHRcdGlmIChpUG9wQ291bnQgPT09IDApIHtcblx0XHRcdC8vIE5vIHN0YXRlIHdhcyBwb3BwZWQgLS0+IGFwcGVuZFxuXHRcdFx0cmV0dXJuIHsgdHlwZTogXCJhcHBlbmRcIiB9O1xuXHRcdH0gZWxzZSBpZiAoaVBvcENvdW50ID09PSAxKSB7XG5cdFx0XHQvLyBPbmx5IDEgc3RhdGUgd2FzIHBvcHBlZCAtLT4gcmVwbGFjZSBjdXJyZW50IGhhc2ggdW5sZXNzIGhhc2ggaXMgdGhlIHNhbWUgKHRoZW4gbm90aGluZyB0byBkbylcblx0XHRcdHJldHVybiBiSGFzU2FtZUhhc2ggPyB7IHR5cGU6IFwibm9uZVwiIH0gOiB7IHR5cGU6IFwicmVwbGFjZVwiIH07XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE1vcmUgdGhhbiAxIHN0YXRlIHdhcyBwb3BwZWQgLS0+IGdvIGJha2MgaW4gaGlzdG9yeSBhbmQgcmVwbGFjZSBoYXNoIGlmIG5lY2Vzc2FyeVxuXHRcdFx0cmV0dXJuIGJIYXNTYW1lSGFzaCA/IHsgdHlwZTogXCJiYWNrXCIsIHN0ZXBzOiBpUG9wQ291bnQgLSAxIH0gOiB7IHR5cGU6IFwiYmFjay1yZXBsYWNlXCIsIHN0ZXBzOiBpUG9wQ291bnQgLSAxIH07XG5cdFx0fVxuXHR9XG5cblx0X2Jsb2NraW5nTmF2aWdhdGlvbkZpbHRlcigpIHtcblx0XHRyZXR1cm4gdGhpcy5fYkRpc2FibGVPbkhhc2hDaGFuZ2UgPyBcIkN1c3RvbVwiIDogXCJDb250aW51ZVwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc2FibGUgdGhlIHJvdXRpbmcgYnkgY2FsbGluZyB0aGUgcm91dGVyIHN0b3AgbWV0aG9kLlxuXHQgKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlJvdXRlclByb3h5XG5cdCAqXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKiBAZmluYWxcblx0ICovXG5cdF9kaXNhYmxlRXZlbnRPbkhhc2hDaGFuZ2UoKSB7XG5cdFx0dGhpcy5fYkRpc2FibGVPbkhhc2hDaGFuZ2UgPSB0cnVlO1xuXHRcdHRoaXMuX29Sb3V0ZXIuc3RvcCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEVuYWJsZSB0aGUgcm91dGluZyBieSBjYWxsaW5nIHRoZSByb3V0ZXIgaW5pdGlhbGl6ZSBtZXRob2QuXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAbmFtZSBzYXAuZmUuY29yZS5Sb3V0ZXJQcm94eSNfZW5hYmxlRXZlbnRPbkhhc2hDaGFuZ2Vcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlJvdXRlclByb3h5XG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JJZ25vcmVDdXJyZW50SGFzaF0gSWdub3JlIHRoZSBsYXN0IGhhc2ggZXZlbnQgdHJpZ2dlcmVkIGJlZm9yZSB0aGUgcm91dGVyIGhhcyBpbml0aWFsaXplZFxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqL1xuXHRfZW5hYmxlRXZlbnRPbkhhc2hDaGFuZ2UoYklnbm9yZUN1cnJlbnRIYXNoOiBib29sZWFuIHwgdW5kZWZpbmVkKSB7XG5cdFx0dGhpcy5fYkRpc2FibGVPbkhhc2hDaGFuZ2UgPSBmYWxzZTtcblx0XHR0aGlzLl9vUm91dGVyLmluaXRpYWxpemUoYklnbm9yZUN1cnJlbnRIYXNoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTeW5jaHJvbml6ZXMgdGhlIGJyb3dzZXIgaGlzdG9yeSB3aXRoIHRoZSBpbnRlcm5hbCBoaXN0b3J5IG9mIHRoZSByb3V0ZXJQcm94eSwgYW5kIHRyaWdnZXJzIGEgbmF2aWdhdGlvbiBpZiBuZWVkZWQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5Sb3V0ZXJQcm94eVxuXHQgKiBAcGFyYW0ge29iamVjdH0gb0hpc3RvcnlBY3Rpb24gU3BlY2lmaWVzIHRoZSBuYXZpZ2F0aW9uIGFjdGlvbiB0byBiZSBwZXJmb3JtZWRcblx0ICogQHBhcmFtIHtib29sZWFufSBiUmVidWlsZE9ubHkgYHRydWVgIGlmIGludGVybmFsIGhpc3RvcnkgaXMgY3VycmVudGx5IGJlaW5nIHJlYnVpbHRcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgKHJlc29sdmVkIHdoZW4gdGhlIG5hdmlnYXRpb24gaXMgZmluYWxpemVkKSB0aGF0IHJldHVybnMgJ3RydWUnIGlmIGEgbmF2aWdhdGlvbiB0b29rIHBsYWNlLCAnZmFsc2UnIGlmIHRoZSBuYXZpZ2F0aW9uIGRpZG4ndCBoYXBwZW5cblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0X3JlYnVpbGRCcm93c2VySGlzdG9yeShvSGlzdG9yeUFjdGlvbjogYW55LCBiUmVidWlsZE9ubHk6IGJvb2xlYW4pIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcztcblx0XHRyZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG5cdFx0XHR0aGlzLmJJc1JlYnVpbGRIaXN0b3J5UnVubmluZyA9IHRydWU7XG5cdFx0XHRjb25zdCBvVGFyZ2V0U3RhdGUgPSB0aGlzLl9vTWFuYWdlZEhpc3RvcnlbdGhpcy5fb01hbmFnZWRIaXN0b3J5Lmxlbmd0aCAtIDFdLFxuXHRcdFx0XHRuZXdMZXZlbCA9IHRoaXMuX29NYW5hZ2VkSGlzdG9yeS5sZW5ndGggLSAxO1xuXG5cdFx0XHRmdW5jdGlvbiByZXBsYWNlQXN5bmMoKSB7XG5cdFx0XHRcdGlmICghYlJlYnVpbGRPbmx5KSB7XG5cdFx0XHRcdFx0dGhhdC5fZW5hYmxlRXZlbnRPbkhhc2hDaGFuZ2UodHJ1ZSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQodGhhdC5fb1JvdXRlci5nZXRIYXNoQ2hhbmdlcigpLnJlcGxhY2VIYXNoIGFzIGFueSkob1RhcmdldFN0YXRlLmhhc2gpO1xuXHRcdFx0XHRoaXN0b3J5LnJlcGxhY2VTdGF0ZShPYmplY3QuYXNzaWduKHsgZmVMZXZlbDogbmV3TGV2ZWwgfSwgaGlzdG9yeS5zdGF0ZSksIFwiXCIpO1xuXG5cdFx0XHRcdGlmIChiUmVidWlsZE9ubHkpIHtcblx0XHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0Ly8gVGltZW91dCB0byBsZXQgJ2hhc2hjaGFuZ2UnIGV2ZW50IGJlIHByb2Nlc3NlZCBiZWZvcmUgYnkgdGhlIEhhc2hDaGFuZ2VyLCBzbyB0aGF0XG5cdFx0XHRcdFx0XHQvLyBvblJvdXRlTWF0Y2hlZCBub3RpZmljYXRpb24gaXNuJ3QgcmFpc2VkXG5cdFx0XHRcdFx0XHR0aGF0Ll9lbmFibGVFdmVudE9uSGFzaENoYW5nZSh0cnVlKTtcblx0XHRcdFx0XHR9LCAwKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoYXQuYklzUmVidWlsZEhpc3RvcnlSdW5uaW5nID0gZmFsc2U7XG5cdFx0XHRcdHJlc29sdmUodHJ1ZSk7IC8vIGEgbmF2aWdhdGlvbiBvY2N1cnJlZFxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBc3luYyBjYWxsYmFja3Mgd2hlbiBuYXZpZ2F0aW5nIGJhY2ssIGluIG9yZGVyIHRvIGxldCBhbGwgbm90aWZpY2F0aW9ucyBhbmQgZXZlbnRzIGdldCBwcm9jZXNzZWRcblx0XHRcdGZ1bmN0aW9uIGJhY2tSZXBsYWNlQXN5bmMoKSB7XG5cdFx0XHRcdHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9wc3RhdGVcIiwgYmFja1JlcGxhY2VBc3luYyk7XG5cdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0Ly8gVGltZW91dCB0byBsZXQgJ2hhc2hjaGFuZ2UnIGV2ZW50IGJlIHByb2Nlc3NlZCBiZWZvcmUgYnkgdGhlIEhhc2hDaGFuZ2VyXG5cdFx0XHRcdFx0cmVwbGFjZUFzeW5jKCk7XG5cdFx0XHRcdH0sIDApO1xuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBiYWNrQXN5bmMoKSB7XG5cdFx0XHRcdHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9wc3RhdGVcIiwgYmFja0FzeW5jKTtcblx0XHRcdFx0dGhhdC5iSXNSZWJ1aWxkSGlzdG9yeVJ1bm5pbmcgPSBmYWxzZTtcblx0XHRcdFx0cmVzb2x2ZSh0cnVlKTsgLy8gYSBuYXZpZ2F0aW9uIG9jY3VycmVkXG5cdFx0XHR9XG5cblx0XHRcdHRoYXQuX2JJZ25vcmVSZXN0b3JlID0gdHJ1ZTtcblxuXHRcdFx0c3dpdGNoIChvSGlzdG9yeUFjdGlvbi50eXBlKSB7XG5cdFx0XHRcdGNhc2UgXCJyZXBsYWNlXCI6XG5cdFx0XHRcdFx0KHRoYXQuX29Sb3V0ZXIuZ2V0SGFzaENoYW5nZXIoKS5yZXBsYWNlSGFzaCBhcyBhbnkpKG9UYXJnZXRTdGF0ZS5oYXNoKTtcblx0XHRcdFx0XHRoaXN0b3J5LnJlcGxhY2VTdGF0ZShPYmplY3QuYXNzaWduKHsgZmVMZXZlbDogbmV3TGV2ZWwgfSwgaGlzdG9yeS5zdGF0ZSksIFwiXCIpO1xuXHRcdFx0XHRcdHRoYXQuYklzUmVidWlsZEhpc3RvcnlSdW5uaW5nID0gZmFsc2U7XG5cdFx0XHRcdFx0cmVzb2x2ZSh0cnVlKTsgLy8gYSBuYXZpZ2F0aW9uIG9jY3VycmVkXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBcImFwcGVuZFwiOlxuXHRcdFx0XHRcdHRoYXQuX29Sb3V0ZXIuZ2V0SGFzaENoYW5nZXIoKS5zZXRIYXNoKG9UYXJnZXRTdGF0ZS5oYXNoKTtcblx0XHRcdFx0XHRoaXN0b3J5LnJlcGxhY2VTdGF0ZShPYmplY3QuYXNzaWduKHsgZmVMZXZlbDogbmV3TGV2ZWwgfSwgaGlzdG9yeS5zdGF0ZSksIFwiXCIpO1xuXHRcdFx0XHRcdHRoYXQuYklzUmVidWlsZEhpc3RvcnlSdW5uaW5nID0gZmFsc2U7XG5cdFx0XHRcdFx0cmVzb2x2ZSh0cnVlKTsgLy8gYSBuYXZpZ2F0aW9uIG9jY3VycmVkXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBcImJhY2tcIjpcblx0XHRcdFx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBvcHN0YXRlXCIsIGJhY2tBc3luYyk7XG5cdFx0XHRcdFx0aGlzdG9yeS5nbygtb0hpc3RvcnlBY3Rpb24uc3RlcHMpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgXCJiYWNrLXJlcGxhY2VcIjpcblx0XHRcdFx0XHR0aGlzLl9kaXNhYmxlRXZlbnRPbkhhc2hDaGFuZ2UoKTtcblx0XHRcdFx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBvcHN0YXRlXCIsIGJhY2tSZXBsYWNlQXN5bmMpO1xuXHRcdFx0XHRcdGhpc3RvcnkuZ28oLW9IaXN0b3J5QWN0aW9uLnN0ZXBzKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdC8vIE5vIG5hdmlnYXRpb25cblx0XHRcdFx0XHR0aGlzLmJJc1JlYnVpbGRIaXN0b3J5UnVubmluZyA9IGZhbHNlO1xuXHRcdFx0XHRcdHJlc29sdmUoZmFsc2UpOyAvLyBubyBuYXZpZ2F0aW9uIC0tPiByZXNvbHZlIHRvIGZhbHNlXG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRnZXRMYXN0SGlzdG9yeUVudHJ5KCkge1xuXHRcdHJldHVybiB0aGlzLl9vTWFuYWdlZEhpc3RvcnlbdGhpcy5fb01hbmFnZWRIaXN0b3J5Lmxlbmd0aCAtIDFdO1xuXHR9XG5cblx0aGFzaEd1YXJkKCkge1xuXHRcdGlmICh0aGlzLl9iQ2xlYW5lZFJlc3RvcmUpIHtcblx0XHRcdHRoaXMuX2JDbGVhbmVkUmVzdG9yZSA9IGZhbHNlO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRjb25zdCBzSGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdGlmIChzSGFzaC5pbmRleE9mKFwicmVzdG9yZUhpc3Rvcnk9dHJ1ZVwiKSAhPT0gLTEpIHtcblx0XHRcdHRoaXMuX2JBcHBseVJlc3RvcmUgPSB0cnVlO1xuXHRcdH0gZWxzZSBpZiAoIXRoaXMuYklzUmVidWlsZEhpc3RvcnlSdW5uaW5nKSB7XG5cdFx0XHRjb25zdCBhSGFzaFNwbGl0ID0gc0hhc2guc3BsaXQoXCImL1wiKTtcblx0XHRcdGNvbnN0IHNBcHBIYXNoID0gYUhhc2hTcGxpdFsxXSA/IGFIYXNoU3BsaXRbMV0gOiBcIlwiO1xuXHRcdFx0aWYgKHRoaXMuY2hlY2tIYXNoV2l0aEd1YXJkKHNBcHBIYXNoKSkge1xuXHRcdFx0XHR0aGlzLl9iRGVsYXllZFJlYnVpbGQgPSB0cnVlO1xuXHRcdFx0XHRjb25zdCBvTmV3U3RhdGUgPSB0aGlzLl9leHRyYWN0U3RhdGVGcm9tSGFzaChzQXBwSGFzaCk7XG5cdFx0XHRcdHRoaXMuX3B1c2hOZXdTdGF0ZShvTmV3U3RhdGUsIGZhbHNlLCBmYWxzZSwgdHJ1ZSk7XG5cblx0XHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5fYkRlbGF5ZWRSZWJ1aWxkID0gZmFsc2U7XG5cdFx0XHRcdH0sIDApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDb21wYXJlcyAyIHN0YXRlcy5cblx0ICpcblx0ICogQHBhcmFtIHtvYmplY3R9IG9TdGF0ZTFcblx0ICogQHBhcmFtIHtvYmplY3R9IG9TdGF0ZTJcblx0ICogQHJldHVybnMge251bWJlcn0gVGhlIHJlc3VsdCBvZiB0aGUgY29tcGFyaXNvbjpcblx0ICogICAgICAgIC0gZW51bVN0YXRlLkVRVUFMIGlmIG9TdGF0ZTEgYW5kIG9TdGF0ZTIgYXJlIGVxdWFsXG5cdCAqICAgICAgICAtIGVudW1TdGF0ZS5DT01QQVRJQkxFIGlmIG9TdGF0ZTEgYW5kIG9TdGF0ZTIgYXJlIGNvbXBhdGlibGVcblx0ICogICAgICAgIC0gZW51bVN0YXRlLkFOQ0VTVE9SIGlmIG9TdGF0ZTEgaXMgYW4gYW5jZXN0b3Igb2Ygb1N0YXRlMlxuXHQgKiAgICAgICAgLSBlbnVtU3RhdGUuRElGRkVSRU5UIGlmIHRoZSAyIHN0YXRlcyBhcmUgZGlmZmVyZW50XG5cdCAqL1xuXG5cdF9jb21wYXJlQ2FjaGVTdGF0ZXMob1N0YXRlMTogYW55LCBvU3RhdGUyOiBhbnkpIHtcblx0XHQvLyBGaXJzdCBjb21wYXJlIG9iamVjdCBrZXlzXG5cdFx0aWYgKG9TdGF0ZTEua2V5cy5sZW5ndGggPiBvU3RhdGUyLmtleXMubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZW51bVN0YXRlLkRJRkZFUkVOVDtcblx0XHR9XG5cdFx0bGV0IGVxdWFsID0gdHJ1ZTtcblx0XHRsZXQgaW5kZXg7XG5cdFx0Zm9yIChpbmRleCA9IDA7IGVxdWFsICYmIGluZGV4IDwgb1N0YXRlMS5rZXlzLmxlbmd0aDsgaW5kZXgrKykge1xuXHRcdFx0aWYgKG9TdGF0ZTEua2V5c1tpbmRleF0gIT09IG9TdGF0ZTIua2V5c1tpbmRleF0pIHtcblx0XHRcdFx0ZXF1YWwgPSBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKCFlcXVhbCkge1xuXHRcdFx0Ly8gU29tZSBvYmplY3RzIGtleXMgYXJlIGRpZmZlcmVudFxuXHRcdFx0cmV0dXJuIGVudW1TdGF0ZS5ESUZGRVJFTlQ7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsIGtleXMgZnJvbSBvU3RhdGUxIGFyZSBpbiBvU3RhdGUyIC0tPiBjaGVjayBpZiBhbmNlc3RvclxuXHRcdGlmIChvU3RhdGUxLmtleXMubGVuZ3RoIDwgb1N0YXRlMi5rZXlzLmxlbmd0aCB8fCBvU3RhdGUxLnNjcmVlbk1vZGUgPCBvU3RhdGUyLnNjcmVlbk1vZGUpIHtcblx0XHRcdHJldHVybiBlbnVtU3RhdGUuQU5DRVNUT1I7XG5cdFx0fVxuXHRcdGlmIChvU3RhdGUxLnNjcmVlbk1vZGUgPiBvU3RhdGUyLnNjcmVlbk1vZGUpIHtcblx0XHRcdHJldHVybiBlbnVtU3RhdGUuRElGRkVSRU5UOyAvLyBOb3Qgc3VyZSB0aGlzIGNhc2UgY2FuIGhhcHBlbi4uLlxuXHRcdH1cblxuXHRcdC8vIEF0IHRoaXMgc3RhZ2UsIHRoZSAyIHN0YXRlcyBoYXZlIHRoZSBzYW1lIG9iamVjdCBrZXlzIChpbiB0aGUgc2FtZSBvcmRlcikgYW5kIHNhbWUgc2NyZWVubW9kZVxuXHRcdC8vIFRoZXkgY2FuIGJlIGVpdGhlciBjb21wYXRpYmxlIG9yIGVxdWFsXG5cdFx0cmV0dXJuIG9TdGF0ZTEuc0xheW91dCA9PT0gb1N0YXRlMi5zTGF5b3V0ID8gZW51bVN0YXRlLkVRVUFMIDogZW51bVN0YXRlLkNPTVBBVElCTEU7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGJhY2sgZXhpdHMgdGhlIHByZXNlbnQgZ3VhcmQgc2V0LlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc1ByZXNlbnRIYXNoIFRoZSBjdXJyZW50IGhhc2guIE9ubHkgdXNlZCBmb3IgdW5pdCB0ZXN0cy5cblx0ICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBiYWNrIGV4aXRzIHRoZXJlIGlzIGEgZ3VhcmQgZXhpdCBvbiBiYWNrXG5cdCAqL1xuXHRjaGVja0lmQmFja0lzT3V0T2ZHdWFyZChzUHJlc2VudEhhc2g/OiBzdHJpbmcpIHtcblx0XHRsZXQgc1ByZXZIYXNoO1xuXHRcdGxldCBzQ3VycmVudEhhc2g6IHN0cmluZztcblx0XHRpZiAoc1ByZXNlbnRIYXNoID09PSB1bmRlZmluZWQpIHtcblx0XHRcdC8vIFdlIHVzZSB3aW5kb3cubG9jYXRpb24uaGFzaCBpbnN0ZWFkIG9mIEhhc2hDaGFuZ2VyLmdldEluc3RhbmNlKCkuZ2V0SGFzaCgpIGJlY2F1c2UgdGhlIGxhdHRlclxuXHRcdFx0Ly8gcmVwbGFjZXMgY2hhcmFjdGVycyBpbiB0aGUgVVJMIChlLmcuICUyNCByZXBsYWNlZCBieSAkKSBhbmQgaXQgY2F1c2VzIGlzc3VlcyB3aGVuIGNvbXBhcmluZ1xuXHRcdFx0Ly8gd2l0aCB0aGUgVVJMcyBpbiB0aGUgbWFuYWdlZCBoaXN0b3J5XG5cdFx0XHRjb25zdCBvU3BsaXRIYXNoID0gdGhpcy5fb1NoZWxsU2VydmljZXMuc3BsaXRIYXNoKHdpbmRvdy5sb2NhdGlvbi5oYXNoKSBhcyBhbnk7XG5cdFx0XHRpZiAob1NwbGl0SGFzaCAmJiBvU3BsaXRIYXNoLmFwcFNwZWNpZmljUm91dGUpIHtcblx0XHRcdFx0c0N1cnJlbnRIYXNoID0gb1NwbGl0SGFzaC5hcHBTcGVjaWZpY1JvdXRlO1xuXHRcdFx0XHRpZiAoc0N1cnJlbnRIYXNoLmluZGV4T2YoXCImL1wiKSA9PT0gMCkge1xuXHRcdFx0XHRcdHNDdXJyZW50SGFzaCA9IHNDdXJyZW50SGFzaC5zdWJzdHJpbmcoMik7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNDdXJyZW50SGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoLnN1YnN0cmluZygxKTsgLy8gVG8gcmVtb3ZlIHRoZSAnIydcblx0XHRcdFx0aWYgKHNDdXJyZW50SGFzaFswXSA9PT0gXCIvXCIpIHtcblx0XHRcdFx0XHRzQ3VycmVudEhhc2ggPSBzQ3VycmVudEhhc2guc3Vic3RyaW5nKDEpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNDdXJyZW50SGFzaCA9IHNQcmVzZW50SGFzaDtcblx0XHR9XG5cdFx0c1ByZXNlbnRIYXNoID0gVVJJLmRlY29kZShzQ3VycmVudEhhc2gpO1xuXHRcdGlmICh0aGlzLl9vTmF2aWdhdGlvbkd1YXJkKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gdGhpcy5fb01hbmFnZWRIaXN0b3J5Lmxlbmd0aCAtIDE7IGkgPiAwOyBpLS0pIHtcblx0XHRcdFx0aWYgKHRoaXMuX29NYW5hZ2VkSGlzdG9yeVtpXS5oYXNoID09PSBzUHJlc2VudEhhc2gpIHtcblx0XHRcdFx0XHRzUHJldkhhc2ggPSB0aGlzLl9vTWFuYWdlZEhpc3RvcnlbaSAtIDFdLmhhc2g7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuICFzUHJldkhhc2ggfHwgIXRoaXMuY2hlY2tIYXNoV2l0aEd1YXJkKHNQcmV2SGFzaCk7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGxhc3QgMiBlbnRyaWVzIGluIHRoZSBoaXN0b3J5IHNoYXJlIHRoZSBzYW1lIGNvbnRleHQuXG5cdCAqXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhleSBzaGFyZSB0aGUgc2FtZSBjb250ZXh0LlxuXHQgKi9cblx0Y2hlY2tJZkJhY2tIYXNTYW1lQ29udGV4dCgpIHtcblx0XHRpZiAodGhpcy5fb01hbmFnZWRIaXN0b3J5Lmxlbmd0aCA8IDIpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRjb25zdCBvQ3VycmVudFN0YXRlID0gdGhpcy5fb01hbmFnZWRIaXN0b3J5W3RoaXMuX29NYW5hZ2VkSGlzdG9yeS5sZW5ndGggLSAxXTtcblx0XHRjb25zdCBvUHJldmlvdXNTdGF0ZSA9IHRoaXMuX29NYW5hZ2VkSGlzdG9yeVt0aGlzLl9vTWFuYWdlZEhpc3RvcnkubGVuZ3RoIC0gMl07XG5cblx0XHRyZXR1cm4gb0N1cnJlbnRTdGF0ZS5oYXNoLnNwbGl0KFwiP1wiKVswXSA9PT0gb1ByZXZpb3VzU3RhdGUuaGFzaC5zcGxpdChcIj9cIilbMF07XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUm91dGVyUHJveHk7XG4iXX0=