@sapui5/sap.fe.core 1.99.0 → 1.101.1

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 (289) hide show
  1. package/package.json +6 -4
  2. package/src/sap/fe/core/.library +2 -3
  3. package/src/sap/fe/core/AnnotationHelper.js +43 -92
  4. package/src/sap/fe/core/AnnotationHelper.ts +43 -107
  5. package/src/sap/fe/core/AppComponent.js +381 -399
  6. package/src/sap/fe/core/AppComponent.ts +397 -0
  7. package/src/sap/fe/core/AppStateHandler.js +131 -162
  8. package/src/sap/fe/core/AppStateHandler.ts +2 -2
  9. package/src/sap/fe/core/BaseController.js +82 -58
  10. package/src/sap/fe/core/BaseController.ts +67 -0
  11. package/src/sap/fe/core/CommonUtils.js +179 -31
  12. package/src/sap/fe/core/CommonUtils.ts +295 -125
  13. package/src/sap/fe/core/ExtensionAPI.js +279 -274
  14. package/src/sap/fe/core/ExtensionAPI.ts +242 -0
  15. package/src/sap/fe/core/PageController.js +158 -29
  16. package/src/sap/fe/core/PageController.ts +65 -37
  17. package/src/sap/fe/core/RouterProxy.js +700 -750
  18. package/src/sap/fe/core/RouterProxy.ts +47 -31
  19. package/src/sap/fe/core/Synchronization.js +21 -31
  20. package/src/sap/fe/core/TemplateComponent.js +193 -118
  21. package/src/sap/fe/core/TemplateComponent.ts +104 -109
  22. package/src/sap/fe/core/TemplateModel.js +24 -44
  23. package/src/sap/fe/core/TemplateModel.ts +3 -3
  24. package/src/sap/fe/core/TransactionHelper.js +1368 -1369
  25. package/src/sap/fe/core/TransactionHelper.ts +201 -171
  26. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +406 -0
  27. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +362 -0
  28. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +146 -0
  29. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +129 -0
  30. package/src/sap/fe/core/actions/collaboration/Manage.js +264 -0
  31. package/src/sap/fe/core/actions/collaboration/Manage.ts +246 -0
  32. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +100 -0
  33. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  34. package/src/sap/fe/core/actions/draft.js +324 -220
  35. package/src/sap/fe/core/actions/draft.ts +209 -133
  36. package/src/sap/fe/core/actions/messageHandling.js +79 -48
  37. package/src/sap/fe/core/actions/messageHandling.ts +113 -83
  38. package/src/sap/fe/core/actions/operations.js +37 -18
  39. package/src/sap/fe/core/actions/operations.ts +51 -20
  40. package/src/sap/fe/core/actions/sticky.js +17 -4
  41. package/src/sap/fe/core/actions/sticky.ts +21 -4
  42. package/src/sap/fe/core/buildingBlocks/AttributeModel.js +60 -0
  43. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
  44. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
  45. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
  46. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +707 -0
  47. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +628 -0
  48. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
  49. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
  50. package/src/sap/fe/core/controllerextensions/EditFlow.js +1854 -1669
  51. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1792 -0
  52. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +79 -54
  53. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +60 -0
  54. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +716 -779
  55. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +785 -0
  56. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +796 -816
  57. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +810 -0
  58. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1056 -1005
  59. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +1001 -0
  60. package/src/sap/fe/core/controllerextensions/KPIManagement.js +498 -532
  61. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +13 -12
  62. package/src/sap/fe/core/controllerextensions/MassEdit.js +141 -169
  63. package/src/sap/fe/core/controllerextensions/MassEdit.ts +155 -0
  64. package/src/sap/fe/core/controllerextensions/MessageHandler.js +221 -244
  65. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +215 -0
  66. package/src/sap/fe/core/controllerextensions/PageReady.js +312 -345
  67. package/src/sap/fe/core/controllerextensions/PageReady.ts +57 -53
  68. package/src/sap/fe/core/controllerextensions/Paginator.js +188 -175
  69. package/src/sap/fe/core/controllerextensions/Paginator.ts +169 -0
  70. package/src/sap/fe/core/controllerextensions/Placeholder.js +157 -149
  71. package/src/sap/fe/core/controllerextensions/Placeholder.ts +149 -0
  72. package/src/sap/fe/core/controllerextensions/Routing.js +144 -125
  73. package/src/sap/fe/core/controllerextensions/Routing.ts +131 -0
  74. package/src/sap/fe/core/controllerextensions/RoutingListener.js +7 -6
  75. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  76. package/src/sap/fe/core/controllerextensions/Share.js +230 -268
  77. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  78. package/src/sap/fe/core/controllerextensions/SideEffects.js +603 -644
  79. package/src/sap/fe/core/controllerextensions/SideEffects.ts +68 -68
  80. package/src/sap/fe/core/controllerextensions/ViewState.js +774 -806
  81. package/src/sap/fe/core/controllerextensions/ViewState.ts +796 -0
  82. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
  83. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  84. package/src/sap/fe/core/controls/Any.js +28 -0
  85. package/src/sap/fe/core/controls/Any.ts +30 -0
  86. package/src/sap/fe/core/controls/CommandExecution.js +92 -68
  87. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  88. package/src/sap/fe/core/controls/ConditionalWrapper.js +165 -79
  89. package/src/sap/fe/core/controls/ConditionalWrapper.ts +74 -0
  90. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +366 -0
  91. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +278 -0
  92. package/src/sap/fe/core/controls/CustomQuickViewPage.js +167 -125
  93. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +116 -0
  94. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +44 -5
  95. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +163 -122
  96. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +155 -0
  97. package/src/sap/fe/core/controls/FieldWrapper.js +212 -141
  98. package/src/sap/fe/core/controls/FieldWrapper.ts +104 -0
  99. package/src/sap/fe/core/controls/FileWrapper.js +313 -0
  100. package/src/sap/fe/core/controls/FileWrapper.ts +169 -0
  101. package/src/sap/fe/core/controls/FilterBar.js +197 -159
  102. package/src/sap/fe/core/controls/FilterBar.ts +148 -0
  103. package/src/sap/fe/core/controls/FormElementWrapper.js +100 -39
  104. package/src/sap/fe/core/controls/FormElementWrapper.ts +37 -0
  105. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +37 -42
  106. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  107. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +147 -115
  108. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +102 -0
  109. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +300 -265
  110. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +252 -0
  111. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +185 -140
  112. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  113. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +335 -322
  114. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  115. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +37 -42
  116. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +75 -74
  117. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +71 -0
  118. package/src/sap/fe/core/converters/ConverterContext.js +348 -379
  119. package/src/sap/fe/core/converters/ConverterContext.ts +19 -16
  120. package/src/sap/fe/core/converters/ManifestSettings.js +13 -1
  121. package/src/sap/fe/core/converters/ManifestSettings.ts +17 -2
  122. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -378
  123. package/src/sap/fe/core/converters/ManifestWrapper.ts +10 -0
  124. package/src/sap/fe/core/converters/MetaModelConverter.js +6 -4
  125. package/src/sap/fe/core/converters/MetaModelConverter.ts +5 -2
  126. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  127. package/src/sap/fe/core/converters/TemplateConverter.ts +2 -1
  128. package/src/sap/fe/core/converters/annotations/DataField.js +26 -13
  129. package/src/sap/fe/core/converters/annotations/DataField.ts +40 -17
  130. package/src/sap/fe/core/converters/controls/Common/Action.js +10 -10
  131. package/src/sap/fe/core/converters/controls/Common/Action.ts +20 -19
  132. package/src/sap/fe/core/converters/controls/Common/Chart.js +8 -8
  133. package/src/sap/fe/core/converters/controls/Common/Chart.ts +12 -11
  134. package/src/sap/fe/core/converters/controls/Common/Form.js +6 -6
  135. package/src/sap/fe/core/converters/controls/Common/Form.ts +7 -3
  136. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  137. package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -2
  138. package/src/sap/fe/core/converters/controls/Common/Table.js +326 -86
  139. package/src/sap/fe/core/converters/controls/Common/Table.ts +384 -167
  140. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +120 -55
  141. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +158 -98
  142. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +206 -223
  143. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +263 -287
  144. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
  145. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
  146. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +5 -2
  147. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +4 -1
  148. package/src/sap/fe/core/converters/helpers/Aggregation.js +115 -133
  149. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  150. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  151. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  152. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  153. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  154. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  155. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
  156. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
  157. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +51 -27
  158. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +69 -43
  159. package/src/sap/fe/core/converters/templates/ListReportConverter.js +42 -25
  160. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +91 -65
  161. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +11 -9
  162. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +8 -8
  163. package/src/sap/fe/core/designtime/AppComponent.designtime.js +92 -98
  164. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  165. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  166. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  167. package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
  168. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -2
  169. package/src/sap/fe/core/formatters/TableFormatter.js +53 -2
  170. package/src/sap/fe/core/formatters/TableFormatter.ts +51 -0
  171. package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
  172. package/src/sap/fe/core/formatters/ValueFormatter.ts +4 -7
  173. package/src/sap/fe/core/fpm/Component.js +80 -55
  174. package/src/sap/fe/core/fpm/Component.ts +43 -0
  175. package/src/sap/fe/core/helpers/AppStartupHelper.js +323 -309
  176. package/src/sap/fe/core/helpers/AppStartupHelper.ts +363 -337
  177. package/src/sap/fe/core/helpers/BindingExpression.js +7 -7
  178. package/src/sap/fe/core/helpers/BindingExpression.ts +7 -7
  179. package/src/sap/fe/core/helpers/ClassSupport.js +307 -166
  180. package/src/sap/fe/core/helpers/ClassSupport.ts +348 -155
  181. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +5 -4
  182. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -5
  183. package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
  184. package/src/sap/fe/core/helpers/FPMHelper.ts +1 -1
  185. package/src/sap/fe/core/helpers/MassEditHelper.js +735 -684
  186. package/src/sap/fe/core/helpers/MassEditHelper.ts +803 -0
  187. package/src/sap/fe/core/helpers/ModelHelper.js +53 -1
  188. package/src/sap/fe/core/helpers/ModelHelper.ts +46 -0
  189. package/src/sap/fe/core/helpers/PasteHelper.js +4 -4
  190. package/src/sap/fe/core/helpers/PasteHelper.ts +4 -3
  191. package/src/sap/fe/core/helpers/SemanticDateOperators.js +7 -3
  192. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +7 -1
  193. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
  194. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +1 -1
  195. package/src/sap/fe/core/helpers/StableIdHelper.js +1 -7
  196. package/src/sap/fe/core/helpers/StableIdHelper.ts +0 -4
  197. package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
  198. package/src/sap/fe/core/jsx-runtime/jsx.ts +22 -8
  199. package/src/sap/fe/core/library.js +425 -451
  200. package/src/sap/fe/core/library.support.js +22 -33
  201. package/src/sap/fe/core/library.support.ts +23 -0
  202. package/src/sap/fe/core/library.ts +420 -0
  203. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
  204. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +4 -4
  205. package/src/sap/fe/core/messagebundle.properties +45 -13
  206. package/src/sap/fe/core/messagebundle_ar.properties +29 -7
  207. package/src/sap/fe/core/messagebundle_bg.properties +29 -7
  208. package/src/sap/fe/core/messagebundle_ca.properties +29 -7
  209. package/src/sap/fe/core/messagebundle_cs.properties +29 -7
  210. package/src/sap/fe/core/messagebundle_cy.properties +29 -7
  211. package/src/sap/fe/core/messagebundle_da.properties +29 -7
  212. package/src/sap/fe/core/messagebundle_de.properties +29 -7
  213. package/src/sap/fe/core/messagebundle_el.properties +29 -7
  214. package/src/sap/fe/core/messagebundle_en.properties +29 -7
  215. package/src/sap/fe/core/messagebundle_en_GB.properties +29 -7
  216. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +29 -7
  217. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +29 -7
  218. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +29 -7
  219. package/src/sap/fe/core/messagebundle_es.properties +29 -7
  220. package/src/sap/fe/core/messagebundle_es_MX.properties +29 -7
  221. package/src/sap/fe/core/messagebundle_et.properties +29 -7
  222. package/src/sap/fe/core/messagebundle_fi.properties +30 -8
  223. package/src/sap/fe/core/messagebundle_fr.properties +31 -9
  224. package/src/sap/fe/core/messagebundle_fr_CA.properties +31 -9
  225. package/src/sap/fe/core/messagebundle_hi.properties +29 -7
  226. package/src/sap/fe/core/messagebundle_hr.properties +29 -7
  227. package/src/sap/fe/core/messagebundle_hu.properties +29 -7
  228. package/src/sap/fe/core/messagebundle_id.properties +29 -7
  229. package/src/sap/fe/core/messagebundle_it.properties +29 -7
  230. package/src/sap/fe/core/messagebundle_iw.properties +29 -7
  231. package/src/sap/fe/core/messagebundle_ja.properties +28 -6
  232. package/src/sap/fe/core/messagebundle_kk.properties +29 -7
  233. package/src/sap/fe/core/messagebundle_ko.properties +29 -7
  234. package/src/sap/fe/core/messagebundle_lt.properties +29 -7
  235. package/src/sap/fe/core/messagebundle_lv.properties +30 -8
  236. package/src/sap/fe/core/messagebundle_ms.properties +29 -7
  237. package/src/sap/fe/core/messagebundle_nl.properties +29 -7
  238. package/src/sap/fe/core/messagebundle_no.properties +29 -7
  239. package/src/sap/fe/core/messagebundle_pl.properties +29 -7
  240. package/src/sap/fe/core/messagebundle_pt.properties +30 -8
  241. package/src/sap/fe/core/messagebundle_pt_PT.properties +29 -7
  242. package/src/sap/fe/core/messagebundle_ro.properties +29 -7
  243. package/src/sap/fe/core/messagebundle_ru.properties +29 -7
  244. package/src/sap/fe/core/messagebundle_sh.properties +29 -7
  245. package/src/sap/fe/core/messagebundle_sk.properties +29 -7
  246. package/src/sap/fe/core/messagebundle_sl.properties +29 -7
  247. package/src/sap/fe/core/messagebundle_sv.properties +30 -8
  248. package/src/sap/fe/core/messagebundle_th.properties +28 -6
  249. package/src/sap/fe/core/messagebundle_tr.properties +32 -10
  250. package/src/sap/fe/core/messagebundle_uk.properties +29 -7
  251. package/src/sap/fe/core/messagebundle_vi.properties +29 -7
  252. package/src/sap/fe/core/messagebundle_zh_CN.properties +29 -7
  253. package/src/sap/fe/core/messagebundle_zh_TW.properties +29 -7
  254. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +47 -73
  255. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +1 -1
  256. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +158 -196
  257. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +5 -6
  258. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +70 -96
  259. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +7 -6
  260. package/src/sap/fe/core/services/NavigationServiceFactory.js +287 -342
  261. package/src/sap/fe/core/services/NavigationServiceFactory.ts +11 -14
  262. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +70 -105
  263. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +6 -3
  264. package/src/sap/fe/core/services/RoutingServiceFactory.js +796 -820
  265. package/src/sap/fe/core/services/RoutingServiceFactory.ts +62 -53
  266. package/src/sap/fe/core/services/ShellServicesFactory.js +694 -741
  267. package/src/sap/fe/core/services/ShellServicesFactory.ts +33 -33
  268. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +570 -595
  269. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +23 -4
  270. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +357 -389
  271. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +25 -29
  272. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +43 -5
  273. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +7 -4
  274. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  275. package/src/sap/fe/core/support/CommonHelper.ts +1 -4
  276. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  277. package/src/sap/fe/core/templating/DataModelPathHelper.js +91 -90
  278. package/src/sap/fe/core/templating/DataModelPathHelper.ts +126 -123
  279. package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
  280. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +26 -5
  281. package/src/sap/fe/core/templating/FilterHelper.js +25 -32
  282. package/src/sap/fe/core/templating/FilterHelper.ts +36 -35
  283. package/src/sap/fe/core/templating/PropertyHelper.js +16 -2
  284. package/src/sap/fe/core/templating/PropertyHelper.ts +31 -24
  285. package/src/sap/fe/core/templating/UIFormatters.js +150 -44
  286. package/src/sap/fe/core/templating/UIFormatters.ts +165 -67
  287. package/src/sap/fe/core/type/Email.js +26 -8
  288. package/src/sap/fe/core/type/Email.ts +8 -7
  289. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -75
@@ -5,355 +5,369 @@
5
5
  sap.ui.define(["sap/ui/model/Filter", "sap/ui/model/FilterOperator", "./ModelHelper"], function (Filter, FilterOperator, ModelHelper) {
6
6
  "use strict";
7
7
 
8
- /**
9
- * Retrieves a set of key values from startup parameters.
10
- *
11
- * @param aKeyNames The array of key names
12
- * @param oStartupParameters The startup parameters
13
- * @returns An array of pairs {name, value} if all key values could be found in the startup parameters, undefined otherwise
14
- */
15
- function _getKeysFromStartupParams(aKeyNames, oStartupParameters) {
16
- var bAllFound = true;
17
- var aKeys = aKeyNames.map(function (name) {
18
- if (oStartupParameters[name] && oStartupParameters[name].length === 1) {
19
- return {
20
- name: name,
21
- value: oStartupParameters[name][0]
22
- };
23
- } else {
24
- // A unique key value couldn't be found in the startup parameters
25
- bAllFound = false;
26
- return {
27
- name: name,
28
- value: ""
29
- };
30
- }
31
- });
32
- return bAllFound ? aKeys : undefined;
33
- }
34
- /**
35
- * Creates a filter from a list of key values.
36
- *
37
- * @param aKeys Array of semantic keys or technical keys (with values)
38
- * @param bDraftMode True if the entity supports draft mode
39
- * @param oMetaModel The metamodel
40
- * @returns The filter
41
- */
42
-
43
-
44
- function _createFilterFromKeys(aKeys, bDraftMode, oMetaModel) {
45
- var bFilterCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
46
- var bFilterOnActiveEntity = false;
47
- var aFilters = aKeys.map(function (key) {
48
- if (key.name === "IsActiveEntity") {
49
- bFilterOnActiveEntity = true;
50
- }
51
-
52
- return new Filter({
53
- path: key.name,
54
- operator: FilterOperator.EQ,
55
- value1: key.value,
56
- caseSensitive: bFilterCaseSensitive
8
+ var AppStartupHelper = {
9
+ /**
10
+ * Retrieves a set of key values from startup parameters.
11
+ *
12
+ * @param aKeyNames The array of key names
13
+ * @param oStartupParameters The startup parameters
14
+ * @returns {any[]} An array of pairs {name, value} if all key values could be found in the startup parameters, undefined otherwise
15
+ */
16
+ _getKeysFromStartupParams: function (aKeyNames, oStartupParameters) {
17
+ var bAllFound = true;
18
+ var aKeys = aKeyNames.map(function (name) {
19
+ if (oStartupParameters[name] && oStartupParameters[name].length === 1) {
20
+ return {
21
+ name: name,
22
+ value: oStartupParameters[name][0]
23
+ };
24
+ } else {
25
+ // A unique key value couldn't be found in the startup parameters
26
+ bAllFound = false;
27
+ return {
28
+ name: name,
29
+ value: ""
30
+ };
31
+ }
57
32
  });
58
- });
33
+ return bAllFound ? aKeys : undefined;
34
+ },
35
+
36
+ /**
37
+ * Creates a filter from a list of key values.
38
+ *
39
+ * @param aKeys Array of semantic keys or technical keys (with values)
40
+ * @param bDraftMode True if the entity supports draft mode
41
+ * @param oMetaModel The metamodel
42
+ * @returns The filter
43
+ */
44
+ _createFilterFromKeys: function (aKeys, bDraftMode, oMetaModel) {
45
+ var bFilterCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
46
+ var bFilterOnActiveEntity = false;
47
+ var aFilters = aKeys.map(function (key) {
48
+ if (key.name === "IsActiveEntity") {
49
+ bFilterOnActiveEntity = true;
50
+ }
59
51
 
60
- if (bDraftMode && !bFilterOnActiveEntity) {
61
- var oDraftFilter = new Filter({
62
- filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
63
- and: false
52
+ return new Filter({
53
+ path: key.name,
54
+ operator: FilterOperator.EQ,
55
+ value1: key.value,
56
+ caseSensitive: bFilterCaseSensitive
57
+ });
64
58
  });
65
- aFilters.push(oDraftFilter);
66
- }
67
59
 
68
- return new Filter(aFilters, true);
69
- }
70
- /**
71
- * Loads all contexts for a list of page infos.
72
- *
73
- * @param aStartupPages The list of page infos
74
- * @param oModel The model used to load the contexts
75
- * @returns A Promise for all contexts
76
- */
60
+ if (bDraftMode && !bFilterOnActiveEntity) {
61
+ var oDraftFilter = new Filter({
62
+ filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
63
+ and: false
64
+ });
65
+ aFilters.push(oDraftFilter);
66
+ }
67
+
68
+ return new Filter(aFilters, true);
69
+ },
77
70
 
71
+ /**
72
+ * Loads all contexts for a list of page infos.
73
+ *
74
+ * @param aStartupPages The list of page infos
75
+ * @param oModel The model used to load the contexts
76
+ * @returns A Promise for all contexts
77
+ */
78
+ _requestObjectsFromParameters: function (aStartupPages, oModel) {
79
+ var _this = this;
78
80
 
79
- function _requestObjectsFromParameters(aStartupPages, oModel) {
80
- // Load the respective objects for all object pages found in aExternallyNavigablePages
81
- var aContextPromises = aStartupPages.map(function (pageInfo) {
82
- var aKeys = pageInfo.semanticKeys || pageInfo.technicalKeys || [];
81
+ // Load the respective objects for all object pages found in aExternallyNavigablePages
82
+ var aContextPromises = aStartupPages.map(function (pageInfo) {
83
+ var aKeys = pageInfo.semanticKeys || pageInfo.technicalKeys || [];
83
84
 
84
- var oFilter = _createFilterFromKeys(aKeys, pageInfo.draftMode, oModel.getMetaModel()); // only request a minimum of fields to boost backend performance since this is only used to check if an object exists
85
+ var oFilter = _this._createFilterFromKeys(aKeys, pageInfo.draftMode, oModel.getMetaModel()); // only request a minimum of fields to boost backend performance since this is only used to check if an object exists
85
86
 
86
87
 
87
- var oListBind = oModel.bindList(pageInfo.contextPath, undefined, undefined, oFilter, {
88
- "$select": aKeys.map(function (key) {
89
- return key.name;
90
- }).join(",")
88
+ var oListBind = oModel.bindList(pageInfo.contextPath, undefined, undefined, oFilter, {
89
+ "$select": aKeys.map(function (key) {
90
+ return key.name;
91
+ }).join(",")
92
+ });
93
+ return oListBind.requestContexts(0, 2);
91
94
  });
92
- return oListBind.requestContexts(0, 2);
93
- });
94
- return Promise.all(aContextPromises);
95
- }
96
- /**
97
- * Returns the list of all pages that allow deeplink and that can be reached using the startup parameters.
98
- *
99
- * @param oManifestRouting The routing information from the app manifest
100
- * @param oStartupParameters The startup parameters
101
- * @param oMetaModel The metamodel
102
- * @returns
103
- */
104
-
105
-
106
- function _getReachablePages(oManifestRouting, oStartupParameters, oMetaModel) {
107
- var aRoutes = oManifestRouting.routes;
108
- var mPagesByLevel = {};
109
- aRoutes.forEach(function (oRoute) {
95
+ return Promise.all(aContextPromises);
96
+ },
97
+
98
+ /**
99
+ * Creates a PageInfo from a route if ti's reachable from the startup parameters.
100
+ *
101
+ * @param oRoute The route
102
+ * @param oManifestRouting The app manifest routing section
103
+ * @param oStartupParameters The startup parameters
104
+ * @param oMetaModel The app metamodel
105
+ * @returns {any} A page info if the page is reachable, undefined otherwise
106
+ */
107
+ _getReachablePageInfoFromRoute: function (oRoute, oManifestRouting, oStartupParameters, oMetaModel) {
108
+ var _oTarget$options, _oTarget$options$sett;
109
+
110
+ // Remove trailing ':?query:' and '/'
110
111
  var sPattern = oRoute.pattern.replace(":?query:", "");
112
+ sPattern = sPattern.replace(/\/$/, "");
111
113
 
112
- if (sPattern.endsWith("/")) {
113
- sPattern = sPattern.substr(0, sPattern.length - 1);
114
+ if (!sPattern) {
115
+ return undefined; // Ignore level-0 routes (ListReport)
114
116
  }
115
117
 
116
- if (sPattern) {
117
- var _oTarget$options, _oTarget$options$sett;
118
+ sPattern = sPattern.replace(/\(\{[^\}]*\}\)/g, "(#)"); // Replace keys with #
119
+ // Get the rightmost target for this route
118
120
 
119
- // Ignore level-0 routes (ListReport)
120
- sPattern = sPattern.replace(/\(\{[^\}]*\}\)/g, "(#)"); // Replace keys with #
121
- // Get the rightmost target for this route
121
+ var sTargetName = Array.isArray(oRoute.target) ? oRoute.target[oRoute.target.length - 1] : oRoute.target;
122
+ var oTarget = oManifestRouting.targets[sTargetName];
123
+ var aPatternSegments = sPattern.split("/");
124
+ var pageLevel = aPatternSegments.length - 1;
122
125
 
123
- var sTargetName = Array.isArray(oRoute.target) ? oRoute.target[oRoute.target.length - 1] : oRoute.target;
124
- var oTarget = oManifestRouting.targets[sTargetName];
125
- var aPatternSegments = sPattern.split("/");
126
- var pageLevel = aPatternSegments.length - 1; // The first level of object page allows deep linking by default.
126
+ if (pageLevel !== 0 && (oTarget === null || oTarget === void 0 ? void 0 : (_oTarget$options = oTarget.options) === null || _oTarget$options === void 0 ? void 0 : (_oTarget$options$sett = _oTarget$options.settings) === null || _oTarget$options$sett === void 0 ? void 0 : _oTarget$options$sett.allowDeepLinking) !== true) {
127
+ // The first level of object page allows deep linking by default.
127
128
  // Otherwise, the target must allow deep linking explicitely in the manifest
128
-
129
- if (pageLevel === 0 || oTarget !== null && oTarget !== void 0 && (_oTarget$options = oTarget.options) !== null && _oTarget$options !== void 0 && (_oTarget$options$sett = _oTarget$options.settings) !== null && _oTarget$options$sett !== void 0 && _oTarget$options$sett.allowDeepLinking) {
130
- var sContextPath = oTarget.options.settings.contextPath || oTarget.options.settings.entitySet && "/" + oTarget.options.settings.entitySet;
131
- var oEntityType = sContextPath && oMetaModel.getObject("/$EntityContainer" + sContextPath + "/");
132
-
133
- if (oEntityType) {
134
- // Get the semantic key values for the entity
135
- var aSemanticKeyNames = oMetaModel.getObject("/$EntityContainer" + sContextPath + "/@com.sap.vocabularies.Common.v1.SemanticKey");
136
- var aSemantickKeys = aSemanticKeyNames ? _getKeysFromStartupParams(aSemanticKeyNames.map(function (semKey) {
137
- return semKey.$PropertyPath;
138
- }), oStartupParameters) : undefined; // Get the technical keys only if we couldn't find the semantic key values, and on first level OP
139
-
140
- var aTechnicalKeys = !aSemantickKeys && pageLevel === 0 ? _getKeysFromStartupParams(oEntityType["$Key"], oStartupParameters) : undefined;
141
-
142
- if (aSemantickKeys || aTechnicalKeys) {
143
- // The startup parameters contain values for all semantic keys (or technical keys) --> we can store the page info in the corresponding level
144
- var draftMode = oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot") || oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode") ? true : false;
145
-
146
- if (!mPagesByLevel[pageLevel]) {
147
- mPagesByLevel[pageLevel] = [];
148
- }
149
-
150
- mPagesByLevel[pageLevel].push({
151
- pattern: sPattern,
152
- contextPath: sContextPath,
153
- draftMode: draftMode,
154
- technicalKeys: aTechnicalKeys,
155
- semanticKeys: aSemantickKeys,
156
- target: sTargetName
157
- });
158
- }
159
- }
160
- }
129
+ return undefined;
161
130
  }
162
- }); // A page is reachable only if all its parents are also reachable
163
- // So if we couldn't find any pages for a given level, all pages with a higher level won't be reachable anyway
164
131
 
165
- var aReachablePages = [];
166
- var level = 0;
132
+ var sContextPath = oTarget.options.settings.contextPath || oTarget.options.settings.entitySet && "/" + oTarget.options.settings.entitySet;
133
+ var oEntityType = sContextPath && oMetaModel.getObject("/$EntityContainer" + sContextPath + "/");
167
134
 
168
- while (mPagesByLevel[level]) {
169
- aReachablePages.push(mPagesByLevel[level]);
170
- level++;
171
- }
135
+ if (!oEntityType) {
136
+ return undefined;
137
+ } // Get the semantic key values for the entity
172
138
 
173
- return aReachablePages;
174
- }
175
- /**
176
- * Get the list of startup pages.
177
- *
178
- * @param oManifestRouting The routing information from the app manifest
179
- * @param oStartupParameters The startup parameters
180
- * @param oMetaModel The metamodel
181
- * @returns An array of startup page infos
182
- */
183
-
184
-
185
- function _getStartupPagesFromStartupParams(oManifestRouting, oStartupParameters, oMetaModel) {
186
- // Find all pages that can be reached with the startup parameters
187
- var aReachablePages = _getReachablePages(oManifestRouting, oStartupParameters, oMetaModel);
188
-
189
- if (aReachablePages.length === 0) {
190
- return [];
191
- } // Find the longest sequence of pages that can be reached (recursively)
192
-
193
-
194
- var result = [];
195
- var current = [];
196
-
197
- function findRecursive(level) {
198
- var aCurrentLevelPages = aReachablePages[level];
199
- var lastPage = current.length ? current[current.length - 1] : undefined;
200
-
201
- if (aCurrentLevelPages) {
202
- aCurrentLevelPages.forEach(function (nextPage) {
203
- if (!lastPage || nextPage.pattern.indexOf(lastPage.pattern) === 0) {
204
- // We only consider pages that can be reached from the page at the previous level,
205
- // --> their pattern must be the pattern of the previous page with another segment appended
206
- current.push(nextPage);
207
- findRecursive(level + 1);
208
- current.pop();
209
- }
210
- });
211
- }
212
139
 
213
- if (current.length > result.length) {
214
- result = current.slice(); // We have found a sequence longer than our previous best --> store it as the new longest
215
- }
216
- }
140
+ var aSemanticKeyNames = oMetaModel.getObject("/$EntityContainer" + sContextPath + "/@com.sap.vocabularies.Common.v1.SemanticKey");
141
+ var aSemantickKeys = aSemanticKeyNames ? this._getKeysFromStartupParams(aSemanticKeyNames.map(function (semKey) {
142
+ return semKey.$PropertyPath;
143
+ }), oStartupParameters) : undefined; // Get the technical keys only if we couldn't find the semantic key values, and on first level OP
217
144
 
218
- findRecursive(0);
219
- return result;
220
- }
221
- /**
222
- * Creates the startup object from the list of pages and contexts.
223
- *
224
- * @param aStartupPages The pages
225
- * @param aContexts The contexts
226
- * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
227
- */
145
+ var aTechnicalKeys = !aSemantickKeys && pageLevel === 0 ? this._getKeysFromStartupParams(oEntityType["$Key"], oStartupParameters) : undefined;
228
146
 
147
+ if (aSemantickKeys === undefined && aTechnicalKeys === undefined) {
148
+ // We couldn't find the semantic/technical keys in the startup parameters
149
+ return undefined;
150
+ } // The startup parameters contain values for all semantic keys (or technical keys) --> we can store the page info in the corresponding level
229
151
 
230
- function _getDeepLinkObject(aStartupPages, aContexts) {
231
- if (aContexts.length === 1) {
232
- return {
233
- context: aContexts[0]
234
- };
235
- } else if (aContexts.length > 1) {
236
- // Navigation to a deeper level --> use the pattern of the deepest object page
237
- // and replace the parameters by the ID from the contexts
238
- var hash = aStartupPages[aStartupPages.length - 1].pattern;
239
- aContexts.forEach(function (oContext) {
240
- hash = hash.replace("(#)", "(" + oContext.getPath().split("(")[1]);
241
- });
152
+
153
+ var draftMode = oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot") || oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode") ? true : false;
242
154
  return {
243
- hash: hash
155
+ pattern: sPattern,
156
+ contextPath: sContextPath,
157
+ draftMode: draftMode,
158
+ technicalKeys: aTechnicalKeys,
159
+ semanticKeys: aSemantickKeys,
160
+ target: sTargetName,
161
+ pageLevel: pageLevel
244
162
  };
245
- } else {
246
- return {};
247
- }
248
- }
249
- /**
250
- * Calculates startup parameters for a deeplink case, from startup parameters and routing infoirmation.
251
- *
252
- * @param oManifestRouting The routing information from the app manifest
253
- * @param oStartupParameters The startup parameters
254
- * @param oModel The OData model
255
- * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
256
- */
257
-
258
-
259
- function getDeepLinkStartupHash(oManifestRouting, oStartupParameters, oModel) {
260
- var aStartupPages;
261
- return oModel.getMetaModel().requestObject("/$EntityContainer/").then(function () {
262
- // Check if semantic keys are present in url parameters for every object page at each level
263
- aStartupPages = _getStartupPagesFromStartupParams(oManifestRouting, oStartupParameters, oModel.getMetaModel());
264
- return _requestObjectsFromParameters(aStartupPages, oModel);
265
- }).then(function (aValues) {
266
- if (aValues.length) {
267
- // Make sure we only get 1 context per promise, and flatten the array
268
- var aContexts = [];
269
- aValues.forEach(function (aFoundContexts) {
270
- if (aFoundContexts.length === 1) {
271
- aContexts.push(aFoundContexts[0]);
163
+ },
164
+
165
+ /**
166
+ * Returns the list of all pages that allow deeplink and that can be reached using the startup parameters.
167
+ *
168
+ * @param oManifestRouting The routing information from the app manifest
169
+ * @param oStartupParameters The startup parameters
170
+ * @param oMetaModel The metamodel
171
+ * @returns {any} The reachable pages
172
+ */
173
+ _getReachablePages: function (oManifestRouting, oStartupParameters, oMetaModel) {
174
+ var _this2 = this;
175
+
176
+ var aRoutes = oManifestRouting.routes;
177
+ var mPagesByLevel = {};
178
+ aRoutes.forEach(function (oRoute) {
179
+ var oPageInfo = _this2._getReachablePageInfoFromRoute(oRoute, oManifestRouting, oStartupParameters, oMetaModel);
180
+
181
+ if (oPageInfo) {
182
+ if (!mPagesByLevel[oPageInfo.pageLevel]) {
183
+ mPagesByLevel[oPageInfo.pageLevel] = [];
272
184
  }
185
+
186
+ mPagesByLevel[oPageInfo.pageLevel].push(oPageInfo);
187
+ }
188
+ }); // A page is reachable only if all its parents are also reachable
189
+ // So if we couldn't find any pages for a given level, all pages with a higher level won't be reachable anyway
190
+
191
+ var aReachablePages = [];
192
+ var level = 0;
193
+
194
+ while (mPagesByLevel[level]) {
195
+ aReachablePages.push(mPagesByLevel[level]);
196
+ level++;
197
+ }
198
+
199
+ return aReachablePages;
200
+ },
201
+
202
+ /**
203
+ * Get the list of startup pages.
204
+ *
205
+ * @param oManifestRouting The routing information from the app manifest
206
+ * @param oStartupParameters The startup parameters
207
+ * @param oMetaModel The metamodel
208
+ * @returns {any} An array of startup page infos
209
+ */
210
+ _getStartupPagesFromStartupParams: function (oManifestRouting, oStartupParameters, oMetaModel) {
211
+ // Find all pages that can be reached with the startup parameters
212
+ var aReachablePages = this._getReachablePages(oManifestRouting, oStartupParameters, oMetaModel);
213
+
214
+ if (aReachablePages.length === 0) {
215
+ return [];
216
+ } // Find the longest sequence of pages that can be reached (recursively)
217
+
218
+
219
+ var result = [];
220
+ var current = [];
221
+
222
+ function findRecursive(level) {
223
+ var aCurrentLevelPages = aReachablePages[level];
224
+ var lastPage = current.length ? current[current.length - 1] : undefined;
225
+
226
+ if (aCurrentLevelPages) {
227
+ aCurrentLevelPages.forEach(function (nextPage) {
228
+ if (!lastPage || nextPage.pattern.indexOf(lastPage.pattern) === 0) {
229
+ // We only consider pages that can be reached from the page at the previous level,
230
+ // --> their pattern must be the pattern of the previous page with another segment appended
231
+ current.push(nextPage);
232
+ findRecursive(level + 1);
233
+ current.pop();
234
+ }
235
+ });
236
+ }
237
+
238
+ if (current.length > result.length) {
239
+ result = current.slice(); // We have found a sequence longer than our previous best --> store it as the new longest
240
+ }
241
+ }
242
+
243
+ findRecursive(0);
244
+ return result;
245
+ },
246
+
247
+ /**
248
+ * Creates the startup object from the list of pages and contexts.
249
+ *
250
+ * @param aStartupPages The pages
251
+ * @param aContexts The contexts
252
+ * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
253
+ */
254
+ _getDeepLinkObject: function (aStartupPages, aContexts) {
255
+ if (aContexts.length === 1) {
256
+ return {
257
+ context: aContexts[0]
258
+ };
259
+ } else if (aContexts.length > 1) {
260
+ // Navigation to a deeper level --> use the pattern of the deepest object page
261
+ // and replace the parameters by the ID from the contexts
262
+ var hash = aStartupPages[aStartupPages.length - 1].pattern;
263
+ aContexts.forEach(function (oContext) {
264
+ hash = hash.replace("(#)", "(" + oContext.getPath().split("(")[1]);
273
265
  });
274
- return aContexts.length === aValues.length ? _getDeepLinkObject(aStartupPages, aContexts) : {};
266
+ return {
267
+ hash: hash
268
+ };
275
269
  } else {
276
270
  return {};
277
271
  }
278
- });
279
- }
280
- /**
281
- * Calculates the new hash based on the startup parameters.
282
- *
283
- * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
284
- * @param sContextPath The context path for the startup of the app (generally the path to the main entity set)
285
- * @param oRouter The router instance
286
- * @param oMetaModel The meta model
287
- * @returns A promise containing the hash to navigate to, or an empty string if there's no need to navigate
288
- */
289
-
290
-
291
- function getCreateStartupHash(oStartupParameters, sContextPath, oRouter, oMetaModel) {
292
- return oMetaModel.requestObject(sContextPath + "@").then(function (oEntitySetAnnotations) {
293
- var sMetaPath = "";
294
- var bCreatable = true;
295
-
296
- if (oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"] && oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"]["NewAction"]) {
297
- sMetaPath = sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction@Org.OData.Core.V1.OperationAvailable";
298
- } else if (oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"] && oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"]["NewAction"]) {
299
- sMetaPath = sContextPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction@Org.OData.Core.V1.OperationAvailable";
300
- }
272
+ },
273
+
274
+ /**
275
+ * Calculates startup parameters for a deeplink case, from startup parameters and routing infoirmation.
276
+ *
277
+ * @param oManifestRouting The routing information from the app manifest
278
+ * @param oStartupParameters The startup parameters
279
+ * @param oModel The OData model
280
+ * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
281
+ */
282
+ getDeepLinkStartupHash: function (oManifestRouting, oStartupParameters, oModel) {
283
+ var _this3 = this;
284
+
285
+ var aStartupPages;
286
+ return oModel.getMetaModel().requestObject("/$EntityContainer/").then(function () {
287
+ // Check if semantic keys are present in url parameters for every object page at each level
288
+ aStartupPages = _this3._getStartupPagesFromStartupParams(oManifestRouting, oStartupParameters, oModel.getMetaModel());
289
+ return _this3._requestObjectsFromParameters(aStartupPages, oModel);
290
+ }).then(function (aValues) {
291
+ if (aValues.length) {
292
+ // Make sure we only get 1 context per promise, and flatten the array
293
+ var aContexts = [];
294
+ aValues.forEach(function (aFoundContexts) {
295
+ if (aFoundContexts.length === 1) {
296
+ aContexts.push(aFoundContexts[0]);
297
+ }
298
+ });
299
+ return aContexts.length === aValues.length ? _this3._getDeepLinkObject(aStartupPages, aContexts) : {};
300
+ } else {
301
+ return {};
302
+ }
303
+ });
304
+ },
305
+
306
+ /**
307
+ * Calculates the new hash based on the startup parameters.
308
+ *
309
+ * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
310
+ * @param sContextPath The context path for the startup of the app (generally the path to the main entity set)
311
+ * @param oRouter The router instance
312
+ * @param oMetaModel The meta model
313
+ * @returns A promise containing the hash to navigate to, or an empty string if there's no need to navigate
314
+ */
315
+ getCreateStartupHash: function (oStartupParameters, sContextPath, oRouter, oMetaModel) {
316
+ var _this4 = this;
317
+
318
+ return oMetaModel.requestObject(sContextPath + "@").then(function (oEntitySetAnnotations) {
319
+ var sMetaPath = "";
320
+ var bCreatable = true;
321
+
322
+ if (oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"] && oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"]["NewAction"]) {
323
+ sMetaPath = sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction@Org.OData.Core.V1.OperationAvailable";
324
+ } else if (oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"] && oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"]["NewAction"]) {
325
+ sMetaPath = sContextPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction@Org.OData.Core.V1.OperationAvailable";
326
+ }
301
327
 
302
- if (sMetaPath) {
303
- var bNewActionOperationAvailable = oMetaModel.getObject(sMetaPath);
328
+ if (sMetaPath) {
329
+ var bNewActionOperationAvailable = oMetaModel.getObject(sMetaPath);
304
330
 
305
- if (bNewActionOperationAvailable === false) {
306
- bCreatable = false;
307
- }
308
- } else {
309
- var oInsertRestrictions = oEntitySetAnnotations["@Org.OData.Capabilities.V1.InsertRestrictions"];
331
+ if (bNewActionOperationAvailable === false) {
332
+ bCreatable = false;
333
+ }
334
+ } else {
335
+ var oInsertRestrictions = oEntitySetAnnotations["@Org.OData.Capabilities.V1.InsertRestrictions"];
310
336
 
311
- if (oInsertRestrictions && oInsertRestrictions.Insertable === false) {
312
- bCreatable = false;
337
+ if (oInsertRestrictions && oInsertRestrictions.Insertable === false) {
338
+ bCreatable = false;
339
+ }
313
340
  }
314
- }
315
341
 
316
- if (bCreatable) {
317
- return getDefaultCreateHash(oStartupParameters, sContextPath, oRouter);
342
+ if (bCreatable) {
343
+ return _this4.getDefaultCreateHash(oStartupParameters, sContextPath, oRouter);
344
+ } else {
345
+ return "";
346
+ }
347
+ });
348
+ },
349
+
350
+ /**
351
+ * Calculates the hash to create a new object.
352
+ *
353
+ * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
354
+ * @param sContextPath The context path of the entity set to be used for the creation
355
+ * @param oRouter The router instance
356
+ * @returns The hash
357
+ */
358
+ getDefaultCreateHash: function (oStartupParameters, sContextPath, oRouter) {
359
+ var sDefaultCreateHash = oStartupParameters && oStartupParameters.preferredMode ? oStartupParameters.preferredMode[0] : "create";
360
+ var sHash = "";
361
+ sDefaultCreateHash = sDefaultCreateHash.indexOf(":") !== -1 && sDefaultCreateHash.length > sDefaultCreateHash.indexOf(":") + 1 ? sDefaultCreateHash.substr(0, sDefaultCreateHash.indexOf(":")) : "create";
362
+ sHash = sContextPath.substring(1) + "(...)?i-action=" + sDefaultCreateHash;
363
+
364
+ if (oRouter.getRouteInfoByHash(sHash)) {
365
+ return sHash;
318
366
  } else {
319
- return "";
367
+ throw new Error("No route match for creating a new " + sContextPath.substring(1));
320
368
  }
321
- });
322
- }
323
- /**
324
- * Calculates the hash to create a new object.
325
- *
326
- * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
327
- * @param sContextPath The context path of the entity set to be used for the creation
328
- * @param oRouter The router instance
329
- * @returns The hash
330
- */
331
-
332
-
333
- function getDefaultCreateHash(oStartupParameters, sContextPath, oRouter) {
334
- var sDefaultCreateHash = oStartupParameters && oStartupParameters.preferredMode ? oStartupParameters.preferredMode[0] : "create";
335
- var sHash = "";
336
- sDefaultCreateHash = sDefaultCreateHash.indexOf(":") !== -1 && sDefaultCreateHash.length > sDefaultCreateHash.indexOf(":") + 1 ? sDefaultCreateHash.substr(0, sDefaultCreateHash.indexOf(":")) : "create";
337
- sHash = sContextPath.substring(1) + "(...)?i-action=" + sDefaultCreateHash;
338
-
339
- if (oRouter.getRouteInfoByHash(sHash)) {
340
- return sHash;
341
- } else {
342
- throw new Error("No route match for creating a new " + sContextPath.substring(1));
343
369
  }
344
- }
345
-
346
- var AppStartupHelper = {
347
- _getKeysFromStartupParams: _getKeysFromStartupParams,
348
- _createFilterFromKeys: _createFilterFromKeys,
349
- _requestObjectsFromParameters: _requestObjectsFromParameters,
350
- _getReachablePages: _getReachablePages,
351
- _getStartupPagesFromStartupParams: _getStartupPagesFromStartupParams,
352
- _getDeepLinkObject: _getDeepLinkObject,
353
- getDeepLinkStartupHash: getDeepLinkStartupHash,
354
- getCreateStartupHash: getCreateStartupHash,
355
- getDefaultCreateHash: getDefaultCreateHash
356
370
  };
357
371
  return AppStartupHelper;
358
372
  }, false);
359
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkFwcFN0YXJ0dXBIZWxwZXIudHMiXSwibmFtZXMiOlsiX2dldEtleXNGcm9tU3RhcnR1cFBhcmFtcyIsImFLZXlOYW1lcyIsIm9TdGFydHVwUGFyYW1ldGVycyIsImJBbGxGb3VuZCIsImFLZXlzIiwibWFwIiwibmFtZSIsImxlbmd0aCIsInZhbHVlIiwidW5kZWZpbmVkIiwiX2NyZWF0ZUZpbHRlckZyb21LZXlzIiwiYkRyYWZ0TW9kZSIsIm9NZXRhTW9kZWwiLCJiRmlsdGVyQ2FzZVNlbnNpdGl2ZSIsIk1vZGVsSGVscGVyIiwiaXNGaWx0ZXJpbmdDYXNlU2Vuc2l0aXZlIiwiYkZpbHRlck9uQWN0aXZlRW50aXR5IiwiYUZpbHRlcnMiLCJrZXkiLCJGaWx0ZXIiLCJwYXRoIiwib3BlcmF0b3IiLCJGaWx0ZXJPcGVyYXRvciIsIkVRIiwidmFsdWUxIiwiY2FzZVNlbnNpdGl2ZSIsIm9EcmFmdEZpbHRlciIsImZpbHRlcnMiLCJhbmQiLCJwdXNoIiwiX3JlcXVlc3RPYmplY3RzRnJvbVBhcmFtZXRlcnMiLCJhU3RhcnR1cFBhZ2VzIiwib01vZGVsIiwiYUNvbnRleHRQcm9taXNlcyIsInBhZ2VJbmZvIiwic2VtYW50aWNLZXlzIiwidGVjaG5pY2FsS2V5cyIsIm9GaWx0ZXIiLCJkcmFmdE1vZGUiLCJnZXRNZXRhTW9kZWwiLCJvTGlzdEJpbmQiLCJiaW5kTGlzdCIsImNvbnRleHRQYXRoIiwiam9pbiIsInJlcXVlc3RDb250ZXh0cyIsIlByb21pc2UiLCJhbGwiLCJfZ2V0UmVhY2hhYmxlUGFnZXMiLCJvTWFuaWZlc3RSb3V0aW5nIiwiYVJvdXRlcyIsInJvdXRlcyIsIm1QYWdlc0J5TGV2ZWwiLCJmb3JFYWNoIiwib1JvdXRlIiwic1BhdHRlcm4iLCJwYXR0ZXJuIiwicmVwbGFjZSIsImVuZHNXaXRoIiwic3Vic3RyIiwic1RhcmdldE5hbWUiLCJBcnJheSIsImlzQXJyYXkiLCJ0YXJnZXQiLCJvVGFyZ2V0IiwidGFyZ2V0cyIsImFQYXR0ZXJuU2VnbWVudHMiLCJzcGxpdCIsInBhZ2VMZXZlbCIsIm9wdGlvbnMiLCJzZXR0aW5ncyIsImFsbG93RGVlcExpbmtpbmciLCJzQ29udGV4dFBhdGgiLCJlbnRpdHlTZXQiLCJvRW50aXR5VHlwZSIsImdldE9iamVjdCIsImFTZW1hbnRpY0tleU5hbWVzIiwiYVNlbWFudGlja0tleXMiLCJzZW1LZXkiLCIkUHJvcGVydHlQYXRoIiwiYVRlY2huaWNhbEtleXMiLCJhUmVhY2hhYmxlUGFnZXMiLCJsZXZlbCIsIl9nZXRTdGFydHVwUGFnZXNGcm9tU3RhcnR1cFBhcmFtcyIsInJlc3VsdCIsImN1cnJlbnQiLCJmaW5kUmVjdXJzaXZlIiwiYUN1cnJlbnRMZXZlbFBhZ2VzIiwibGFzdFBhZ2UiLCJuZXh0UGFnZSIsImluZGV4T2YiLCJwb3AiLCJzbGljZSIsIl9nZXREZWVwTGlua09iamVjdCIsImFDb250ZXh0cyIsImNvbnRleHQiLCJoYXNoIiwib0NvbnRleHQiLCJnZXRQYXRoIiwiZ2V0RGVlcExpbmtTdGFydHVwSGFzaCIsInJlcXVlc3RPYmplY3QiLCJ0aGVuIiwiYVZhbHVlcyIsImFGb3VuZENvbnRleHRzIiwiZ2V0Q3JlYXRlU3RhcnR1cEhhc2giLCJvUm91dGVyIiwib0VudGl0eVNldEFubm90YXRpb25zIiwic01ldGFQYXRoIiwiYkNyZWF0YWJsZSIsImJOZXdBY3Rpb25PcGVyYXRpb25BdmFpbGFibGUiLCJvSW5zZXJ0UmVzdHJpY3Rpb25zIiwiSW5zZXJ0YWJsZSIsImdldERlZmF1bHRDcmVhdGVIYXNoIiwic0RlZmF1bHRDcmVhdGVIYXNoIiwicHJlZmVycmVkTW9kZSIsInNIYXNoIiwic3Vic3RyaW5nIiwiZ2V0Um91dGVJbmZvQnlIYXNoIiwiRXJyb3IiLCJBcHBTdGFydHVwSGVscGVyIl0sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBOzs7O0FBb0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBU0EseUJBQVQsQ0FBbUNDLFNBQW5DLEVBQXdEQyxrQkFBeEQsRUFBMEc7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a0IsRUFBbEJBLGtCQUp3QjtBQUt4Qm1DLElBQUFBLGlDQUFpQyxFQUFqQ0EsaUNBTHdCO0FBTXhCVSxJQUFBQSxrQkFBa0IsRUFBbEJBLGtCQU53QjtBQU94Qk0sSUFBQUEsc0JBQXNCLEVBQXRCQSxzQkFQd0I7QUFReEJLLElBQUFBLG9CQUFvQixFQUFwQkEsb0JBUndCO0FBU3hCUSxJQUFBQSxvQkFBb0IsRUFBcEJBO0FBVHdCLEdBQXpCO1NBWWVPLGdCIiwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgT0RhdGFNZXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1ldGFNb2RlbFwiO1xuaW1wb3J0IE9EYXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1vZGVsXCI7XG5pbXBvcnQgQ29udGV4dCBmcm9tIFwic2FwL3VpL21vZGVsL29kYXRhL3Y0L0NvbnRleHRcIjtcbmltcG9ydCBGaWx0ZXIgZnJvbSBcInNhcC91aS9tb2RlbC9GaWx0ZXJcIjtcbmltcG9ydCBGaWx0ZXJPcGVyYXRvciBmcm9tIFwic2FwL3VpL21vZGVsL0ZpbHRlck9wZXJhdG9yXCI7XG5pbXBvcnQgUm91dGVyIGZyb20gXCJzYXAvdWkvY29yZS9yb3V0aW5nL1JvdXRlclwiO1xuaW1wb3J0IE1vZGVsSGVscGVyIGZyb20gXCIuL01vZGVsSGVscGVyXCI7XG5cbnR5cGUgVmFsdWVkS2V5ID0ge1xuXHRuYW1lOiBzdHJpbmc7XG5cdHZhbHVlOiBzdHJpbmc7XG59O1xuXG50eXBlIFBhZ2VJbmZvID0ge1xuXHRwYXR0ZXJuOiBzdHJpbmc7XG5cdGNvbnRleHRQYXRoOiBzdHJpbmc7XG5cdGRyYWZ0TW9kZTogQm9vbGVhbjtcblx0dGVjaG5pY2FsS2V5czogVmFsdWVkS2V5W10gfCB1bmRlZmluZWQ7XG5cdHNlbWFudGljS2V5czogVmFsdWVkS2V5W10gfCB1bmRlZmluZWQ7XG5cdHRhcmdldDogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBzZXQgb2Yga2V5IHZhbHVlcyBmcm9tIHN0YXJ0dXAgcGFyYW1ldGVycy5cbiAqXG4gKiBAcGFyYW0gYUtleU5hbWVzIFRoZSBhcnJheSBvZiBrZXkgbmFtZXNcbiAqIEBwYXJhbSBvU3RhcnR1cFBhcmFtZXRlcnMgVGhlIHN0YXJ0dXAgcGFyYW1ldGVyc1xuICogQHJldHVybnMgQW4gYXJyYXkgb2YgcGFpcnMge25hbWUsIHZhbHVlfSBpZiBhbGwga2V5IHZhbHVlcyBjb3VsZCBiZSBmb3VuZCBpbiB0aGUgc3RhcnR1cCBwYXJhbWV0ZXJzLCB1bmRlZmluZWQgb3RoZXJ3aXNlXG4gKi9cbmZ1bmN0aW9uIF9nZXRLZXlzRnJvbVN0YXJ0dXBQYXJhbXMoYUtleU5hbWVzOiBzdHJpbmdbXSwgb1N0YXJ0dXBQYXJhbWV0ZXJzOiBhbnkpOiBWYWx1ZWRLZXlbXSB8IHVuZGVmaW5lZCB7XG5cdGxldCBiQWxsRm91bmQgPSB0cnVlO1xuXHRjb25zdCBhS2V5cyA9IGFLZXlOYW1lcy5tYXAobmFtZSA9PiB7XG5cdFx0aWYgKG9TdGFydHVwUGFyYW1ldGVyc1tuYW1lXSAmJiBvU3RhcnR1cFBhcmFtZXRlcnNbbmFtZV0ubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRyZXR1cm4geyBuYW1lLCB2YWx1ZTogb1N0YXJ0dXBQYXJhbWV0ZXJzW25hbWVdWzBdIGFzIHN0cmluZyB9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBBIHVuaXF1ZSBrZXkgdmFsdWUgY291bGRuJ3QgYmUgZm91bmQgaW4gdGhlIHN0YXJ0dXAgcGFyYW1ldGVyc1xuXHRcdFx0YkFsbEZvdW5kID0gZmFsc2U7XG5cdFx0XHRyZXR1cm4geyBuYW1lLCB2YWx1ZTogXCJcIiB9O1xuXHRcdH1cblx0fSk7XG5cblx0cmV0dXJuIGJBbGxGb3VuZCA/IGFLZXlzIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBmaWx0ZXIgZnJvbSBhIGxpc3Qgb2Yga2V5IHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0gYUtleXMgQXJyYXkgb2Ygc2VtYW50aWMga2V5cyBvciB0ZWNobmljYWwga2V5cyAod2l0aCB2YWx1ZXMpXG4gKiBAcGFyYW0gYkRyYWZ0TW9kZSBUcnVlIGlmIHRoZSBlbnRpdHkgc3VwcG9ydHMgZHJhZnQgbW9kZVxuICogQHBhcmFtIG9NZXRhTW9kZWwgVGhlIG1ldGFtb2RlbFxuICogQHJldHVybnMgVGhlIGZpbHRlclxuICovXG5mdW5jdGlvbiBfY3JlYXRlRmlsdGVyRnJvbUtleXMoYUtleXM6IFZhbHVlZEtleVtdLCBiRHJhZnRNb2RlOiBCb29sZWFuLCBvTWV0YU1vZGVsOiBPRGF0YU1ldGFNb2RlbCk6IEZpbHRlciB7XG5cdGNvbnN0IGJGaWx0ZXJDYXNlU2Vuc2l0aXZlID0gTW9kZWxIZWxwZXIuaXNGaWx0ZXJpbmdDYXNlU2Vuc2l0aXZlKG9NZXRhTW9kZWwpO1xuXG5cdGxldCBiRmlsdGVyT25BY3RpdmVFbnRpdHkgPSBmYWxzZTtcblx0Y29uc3QgYUZpbHRlcnMgPSBhS2V5cy5tYXAoa2V5ID0+IHtcblx0XHRpZiAoa2V5Lm5hbWUgPT09IFwiSXNBY3RpdmVFbnRpdHlcIikge1xuXHRcdFx0YkZpbHRlck9uQWN0aXZlRW50aXR5ID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIG5ldyBGaWx0ZXIoe1xuXHRcdFx0cGF0aDoga2V5Lm5hbWUsXG5cdFx0XHRvcGVyYXRvcjogRmlsdGVyT3BlcmF0b3IuRVEsXG5cdFx0XHR2YWx1ZTE6IGtleS52YWx1ZSxcblx0XHRcdGNhc2VTZW5zaXRpdmU6IGJGaWx0ZXJDYXNlU2Vuc2l0aXZlXG5cdFx0fSk7XG5cdH0pO1xuXHRpZiAoYkRyYWZ0TW9kZSAmJiAhYkZpbHRlck9uQWN0aXZlRW50aXR5KSB7XG5cdFx0Y29uc3Qgb0RyYWZ0RmlsdGVyID0gbmV3IEZpbHRlcih7XG5cdFx0XHRmaWx0ZXJzOiBbbmV3IEZpbHRlcihcIklzQWN0aXZlRW50aXR5XCIsIFwiRVFcIiwgZmFsc2UpLCBuZXcgRmlsdGVyKFwiU2libGluZ0VudGl0eS9Jc0FjdGl2ZUVudGl0eVwiLCBcIkVRXCIsIG51bGwpXSxcblx0XHRcdGFuZDogZmFsc2Vcblx0XHR9KTtcblx0XHRhRmlsdGVycy5wdXNoKG9EcmFmdEZpbHRlcik7XG5cdH1cblxuXHRyZXR1cm4gbmV3IEZpbHRlcihhRmlsdGVycywgdHJ1ZSk7XG59XG5cbi8qKlxuICogTG9hZHMgYWxsIGNvbnRleHRzIGZvciBhIGxpc3Qgb2YgcGFnZSBpbmZvcy5cbiAqXG4gKiBAcGFyYW0gYVN0YXJ0dXBQYWdlcyBUaGUgbGlzdCBvZiBwYWdlIGluZm9zXG4gKiBAcGFyYW0gb01vZGVsIFRoZSBtb2RlbCB1c2VkIHRvIGxvYWQgdGhlIGNvbnRleHRzXG4gKiBAcmV0dXJucyBBIFByb21pc2UgZm9yIGFsbCBjb250ZXh0c1xuICovXG5mdW5jdGlvbiBfcmVxdWVzdE9iamVjdHNGcm9tUGFyYW1ldGVycyhhU3RhcnR1cFBhZ2VzOiBQYWdlSW5mb1tdLCBvTW9kZWw6IE9EYXRhTW9kZWwpOiBQcm9taXNlPENvbnRleHRbXVtdPiB7XG5cdC8vIExvYWQgdGhlIHJlc3BlY3RpdmUgb2JqZWN0cyBmb3IgYWxsIG9iamVjdCBwYWdlcyBmb3VuZCBpbiBhRXh0ZXJuYWxseU5hdmlnYWJsZVBhZ2VzXG5cdGNvbnN0IGFDb250ZXh0UHJvbWlzZXMgPSBhU3RhcnR1cFBhZ2VzLm1hcChwYWdlSW5mbyA9PiB7XG5cdFx0Y29uc3QgYUtleXMgPSBwYWdlSW5mby5zZW1hbnRpY0tleXMgfHwgcGFnZUluZm8udGVjaG5pY2FsS2V5cyB8fCBbXTtcblx0XHRjb25zdCBvRmlsdGVyID0gX2NyZWF0ZUZpbHRlckZyb21LZXlzKGFLZXlzLCBwYWdlSW5mby5kcmFmdE1vZGUsIG9Nb2RlbC5nZXRNZXRhTW9kZWwoKSk7XG5cblx0XHQvLyBvbmx5IHJlcXVlc3QgYSBtaW5pbXVtIG9mIGZpZWxkcyB0byBib29zdCBiYWNrZW5kIHBlcmZvcm1hbmNlIHNpbmNlIHRoaXMgaXMgb25seSB1c2VkIHRvIGNoZWNrIGlmIGFuIG9iamVjdCBleGlzdHNcblx0XHRjb25zdCBvTGlzdEJpbmQgPSBvTW9kZWwuYmluZExpc3QocGFnZUluZm8uY29udGV4dFBhdGgsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBvRmlsdGVyLCB7XG5cdFx0XHRcIiRzZWxlY3RcIjogYUtleXNcblx0XHRcdFx0Lm1hcChrZXkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiBrZXkubmFtZTtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmpvaW4oXCIsXCIpXG5cdFx0fSBhcyBhbnkpO1xuXHRcdHJldHVybiBvTGlzdEJpbmQucmVxdWVzdENvbnRleHRzKDAsIDIpO1xuXHR9KTtcblxuXHRyZXR1cm4gUHJvbWlzZS5hbGwoYUNvbnRleHRQcm9taXNlcyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbGlzdCBvZiBhbGwgcGFnZXMgdGhhdCBhbGxvdyBkZWVwbGluayBhbmQgdGhhdCBjYW4gYmUgcmVhY2hlZCB1c2luZyB0aGUgc3RhcnR1cCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSBvTWFuaWZlc3RSb3V0aW5nIFRoZSByb3V0aW5nIGluZm9ybWF0aW9uIGZyb20gdGhlIGFwcCBtYW5pZmVzdFxuICogQHBhcmFtIG9TdGFydHVwUGFyYW1ldGVycyBUaGUgc3RhcnR1cCBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0gb01ldGFNb2RlbCBUaGUgbWV0YW1vZGVsXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBfZ2V0UmVhY2hhYmxlUGFnZXMob01hbmlmZXN0Um91dGluZzogYW55LCBvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSwgb01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWwpOiBQYWdlSW5mb1tdW10ge1xuXHRjb25zdCBhUm91dGVzOiBhbnlbXSA9IG9NYW5pZmVzdFJvdXRpbmcucm91dGVzO1xuXHRjb25zdCBtUGFnZXNCeUxldmVsOiBSZWNvcmQ8bnVtYmVyLCBQYWdlSW5mb1tdPiA9IHt9O1xuXG5cdGFSb3V0ZXMuZm9yRWFjaChvUm91dGUgPT4ge1xuXHRcdGxldCBzUGF0dGVybjogc3RyaW5nID0gb1JvdXRlLnBhdHRlcm4ucmVwbGFjZShcIjo/cXVlcnk6XCIsIFwiXCIpO1xuXHRcdGlmIChzUGF0dGVybi5lbmRzV2l0aChcIi9cIikpIHtcblx0XHRcdHNQYXR0ZXJuID0gc1BhdHRlcm4uc3Vic3RyKDAsIHNQYXR0ZXJuLmxlbmd0aCAtIDEpO1xuXHRcdH1cblxuXHRcdGlmIChzUGF0dGVybikge1xuXHRcdFx0Ly8gSWdub3JlIGxldmVsLTAgcm91dGVzIChMaXN0UmVwb3J0KVxuXHRcdFx0c1BhdHRlcm4gPSBzUGF0dGVybi5yZXBsYWNlKC9cXChcXHtbXlxcfV0qXFx9XFwpL2csIFwiKCMpXCIpOyAvLyBSZXBsYWNlIGtleXMgd2l0aCAjXG5cblx0XHRcdC8vIEdldCB0aGUgcmlnaHRtb3N0IHRhcmdldCBmb3IgdGhpcyByb3V0ZVxuXHRcdFx0Y29uc3Qgc1RhcmdldE5hbWU6IHN0cmluZyA9IEFycmF5LmlzQXJyYXkob1JvdXRlLnRhcmdldCkgPyBvUm91dGUudGFyZ2V0W29Sb3V0ZS50YXJnZXQubGVuZ3RoIC0gMV0gOiBvUm91dGUudGFyZ2V0O1xuXHRcdFx0Y29uc3Qgb1RhcmdldCA9IG9NYW5pZmVzdFJvdXRpbmcudGFyZ2V0c1tzVGFyZ2V0TmFtZV07XG5cblx0XHRcdGNvbnN0IGFQYXR0ZXJuU2VnbWVudHMgPSBzUGF0dGVybi5zcGxpdChcIi9cIik7XG5cdFx0XHRjb25zdCBwYWdlTGV2ZWwgPSBhUGF0dGVyblNlZ21lbnRzLmxlbmd0aCAtIDE7XG5cblx0XHRcdC8vIFRoZSBmaXJzdCBsZXZlbCBvZiBvYmplY3QgcGFnZSBhbGxvd3MgZGVlcCBsaW5raW5nIGJ5IGRlZmF1bHQuXG5cdFx0XHQvLyBPdGhlcndpc2UsIHRoZSB0YXJnZXQgbXVzdCBhbGxvdyBkZWVwIGxpbmtpbmcgZXhwbGljaXRlbHkgaW4gdGhlIG1hbmlmZXN0XG5cdFx0XHRpZiAocGFnZUxldmVsID09PSAwIHx8IG9UYXJnZXQ/Lm9wdGlvbnM/LnNldHRpbmdzPy5hbGxvd0RlZXBMaW5raW5nKSB7XG5cdFx0XHRcdGNvbnN0IHNDb250ZXh0UGF0aDogc3RyaW5nID1cblx0XHRcdFx0XHRvVGFyZ2V0Lm9wdGlvbnMuc2V0dGluZ3MuY29udGV4dFBhdGggfHxcblx0XHRcdFx0XHQob1RhcmdldC5vcHRpb25zLnNldHRpbmdzLmVudGl0eVNldCAmJiBcIi9cIiArIG9UYXJnZXQub3B0aW9ucy5zZXR0aW5ncy5lbnRpdHlTZXQpO1xuXHRcdFx0XHRjb25zdCBvRW50aXR5VHlwZSA9IHNDb250ZXh0UGF0aCAmJiBvTWV0YU1vZGVsLmdldE9iamVjdChcIi8kRW50aXR5Q29udGFpbmVyXCIgKyBzQ29udGV4dFBhdGggKyBcIi9cIik7XG5cblx0XHRcdFx0aWYgKG9FbnRpdHlUeXBlKSB7XG5cdFx0XHRcdFx0Ly8gR2V0IHRoZSBzZW1hbnRpYyBrZXkgdmFsdWVzIGZvciB0aGUgZW50aXR5XG5cdFx0XHRcdFx0Y29uc3QgYVNlbWFudGljS2V5TmFtZXM6IGFueSA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KFxuXHRcdFx0XHRcdFx0XCIvJEVudGl0eUNvbnRhaW5lclwiICsgc0NvbnRleHRQYXRoICsgXCIvQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5TZW1hbnRpY0tleVwiXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRjb25zdCBhU2VtYW50aWNrS2V5cyA9IGFTZW1hbnRpY0tleU5hbWVzXG5cdFx0XHRcdFx0XHQ/IF9nZXRLZXlzRnJvbVN0YXJ0dXBQYXJhbXMoXG5cdFx0XHRcdFx0XHRcdFx0YVNlbWFudGljS2V5TmFtZXMubWFwKChzZW1LZXk6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHNlbUtleS4kUHJvcGVydHlQYXRoIGFzIHN0cmluZztcblx0XHRcdFx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRcdFx0XHRvU3RhcnR1cFBhcmFtZXRlcnNcblx0XHRcdFx0XHRcdCAgKVxuXHRcdFx0XHRcdFx0OiB1bmRlZmluZWQ7XG5cblx0XHRcdFx0XHQvLyBHZXQgdGhlIHRlY2huaWNhbCBrZXlzIG9ubHkgaWYgd2UgY291bGRuJ3QgZmluZCB0aGUgc2VtYW50aWMga2V5IHZhbHVlcywgYW5kIG9uIGZpcnN0IGxldmVsIE9QXG5cdFx0XHRcdFx0Y29uc3QgYVRlY2huaWNhbEtleXMgPVxuXHRcdFx0XHRcdFx0IWFTZW1hbnRpY2tLZXlzICYmIHBhZ2VMZXZlbCA9PT0gMCA/IF9nZXRLZXlzRnJvbVN0YXJ0dXBQYXJhbXMob0VudGl0eVR5cGVbXCIkS2V5XCJdLCBvU3RhcnR1cFBhcmFtZXRlcnMpIDogdW5kZWZpbmVkO1xuXG5cdFx0XHRcdFx0aWYgKGFTZW1hbnRpY2tLZXlzIHx8IGFUZWNobmljYWxLZXlzKSB7XG5cdFx0XHRcdFx0XHQvLyBUaGUgc3RhcnR1cCBwYXJhbWV0ZXJzIGNvbnRhaW4gdmFsdWVzIGZvciBhbGwgc2VtYW50aWMga2V5cyAob3IgdGVjaG5pY2FsIGtleXMpIC0tPiB3ZSBjYW4gc3RvcmUgdGhlIHBhZ2UgaW5mbyBpbiB0aGUgY29ycmVzcG9uZGluZyBsZXZlbFxuXHRcdFx0XHRcdFx0Y29uc3QgZHJhZnRNb2RlID1cblx0XHRcdFx0XHRcdFx0b01ldGFNb2RlbC5nZXRPYmplY3QoXCIvJEVudGl0eUNvbnRhaW5lclwiICsgc0NvbnRleHRQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRyYWZ0Um9vdFwiKSB8fFxuXHRcdFx0XHRcdFx0XHRvTWV0YU1vZGVsLmdldE9iamVjdChcIi8kRW50aXR5Q29udGFpbmVyXCIgKyBzQ29udGV4dFBhdGggKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRHJhZnROb2RlXCIpXG5cdFx0XHRcdFx0XHRcdFx0PyB0cnVlXG5cdFx0XHRcdFx0XHRcdFx0OiBmYWxzZTtcblxuXHRcdFx0XHRcdFx0aWYgKCFtUGFnZXNCeUxldmVsW3BhZ2VMZXZlbF0pIHtcblx0XHRcdFx0XHRcdFx0bVBhZ2VzQnlMZXZlbFtwYWdlTGV2ZWxdID0gW107XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRtUGFnZXNCeUxldmVsW3BhZ2VMZXZlbF0ucHVzaCh7XG5cdFx0XHRcdFx0XHRcdHBhdHRlcm46IHNQYXR0ZXJuLFxuXHRcdFx0XHRcdFx0XHRjb250ZXh0UGF0aDogc0NvbnRleHRQYXRoLFxuXHRcdFx0XHRcdFx0XHRkcmFmdE1vZGUsXG5cdFx0XHRcdFx0XHRcdHRlY2huaWNhbEtleXM6IGFUZWNobmljYWxLZXlzLFxuXHRcdFx0XHRcdFx0XHRzZW1hbnRpY0tleXM6IGFTZW1hbnRpY2tLZXlzLFxuXHRcdFx0XHRcdFx0XHR0YXJnZXQ6IHNUYXJnZXROYW1lXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0pO1xuXG5cdC8vIEEgcGFnZSBpcyByZWFjaGFibGUgb25seSBpZiBhbGwgaXRzIHBhcmVudHMgYXJlIGFsc28gcmVhY2hhYmxlXG5cdC8vIFNvIGlmIHdlIGNvdWxkbid0IGZpbmQgYW55IHBhZ2VzIGZvciBhIGdpdmVuIGxldmVsLCBhbGwgcGFnZXMgd2l0aCBhIGhpZ2hlciBsZXZlbCB3b24ndCBiZSByZWFjaGFibGUgYW55d2F5XG5cdGNvbnN0IGFSZWFjaGFibGVQYWdlczogUGFnZUluZm9bXVtdID0gW107XG5cdGxldCBsZXZlbCA9IDA7XG5cdHdoaWxlIChtUGFnZXNCeUxldmVsW2xldmVsXSkge1xuXHRcdGFSZWFjaGFibGVQYWdlcy5wdXNoKG1QYWdlc0J5TGV2ZWxbbGV2ZWxdKTtcblx0XHRsZXZlbCsrO1xuXHR9XG5cblx0cmV0dXJuIGFSZWFjaGFibGVQYWdlcztcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGxpc3Qgb2Ygc3RhcnR1cCBwYWdlcy5cbiAqXG4gKiBAcGFyYW0gb01hbmlmZXN0Um91dGluZyBUaGUgcm91dGluZyBpbmZvcm1hdGlvbiBmcm9tIHRoZSBhcHAgbWFuaWZlc3RcbiAqIEBwYXJhbSBvU3RhcnR1cFBhcmFtZXRlcnMgVGhlIHN0YXJ0dXAgcGFyYW1ldGVyc1xuICogQHBhcmFtIG9NZXRhTW9kZWwgVGhlIG1ldGFtb2RlbFxuICogQHJldHVybnMgQW4gYXJyYXkgb2Ygc3RhcnR1cCBwYWdlIGluZm9zXG4gKi9cbmZ1bmN0aW9uIF9nZXRTdGFydHVwUGFnZXNGcm9tU3RhcnR1cFBhcmFtcyhvTWFuaWZlc3RSb3V0aW5nOiBhbnksIG9TdGFydHVwUGFyYW1ldGVyczogYW55LCBvTWV0YU1vZGVsOiBPRGF0YU1ldGFNb2RlbCk6IFBhZ2VJbmZvW10ge1xuXHQvLyBGaW5kIGFsbCBwYWdlcyB0aGF0IGNhbiBiZSByZWFjaGVkIHdpdGggdGhlIHN0YXJ0dXAgcGFyYW1ldGVyc1xuXHRjb25zdCBhUmVhY2hhYmxlUGFnZXMgPSBfZ2V0UmVhY2hhYmxlUGFnZXMob01hbmlmZXN0Um91dGluZywgb1N0YXJ0dXBQYXJhbWV0ZXJzLCBvTWV0YU1vZGVsKTtcblxuXHRpZiAoYVJlYWNoYWJsZVBhZ2VzLmxlbmd0aCA9PT0gMCkge1xuXHRcdHJldHVybiBbXTtcblx0fVxuXG5cdC8vIEZpbmQgdGhlIGxvbmdlc3Qgc2VxdWVuY2Ugb2YgcGFnZXMgdGhhdCBjYW4gYmUgcmVhY2hlZCAocmVjdXJzaXZlbHkpXG5cdGxldCByZXN1bHQ6IFBhZ2VJbmZvW10gPSBbXTtcblx0Y29uc3QgY3VycmVudDogUGFnZUluZm9bXSA9IFtdO1xuXG5cdGZ1bmN0aW9uIGZpbmRSZWN1cnNpdmUobGV2ZWw6IG51bWJlcikge1xuXHRcdGNvbnN0IGFDdXJyZW50TGV2ZWxQYWdlcyA9IGFSZWFjaGFibGVQYWdlc1tsZXZlbF07XG5cdFx0Y29uc3QgbGFzdFBhZ2UgPSBjdXJyZW50Lmxlbmd0aCA/IGN1cnJlbnRbY3VycmVudC5sZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcblxuXHRcdGlmIChhQ3VycmVudExldmVsUGFnZXMpIHtcblx0XHRcdGFDdXJyZW50TGV2ZWxQYWdlcy5mb3JFYWNoKGZ1bmN0aW9uKG5leHRQYWdlKSB7XG5cdFx0XHRcdGlmICghbGFzdFBhZ2UgfHwgbmV4dFBhZ2UucGF0dGVybi5pbmRleE9mKGxhc3RQYWdlLnBhdHRlcm4pID09PSAwKSB7XG5cdFx0XHRcdFx0Ly8gV2Ugb25seSBjb25zaWRlciBwYWdlcyB0aGF0IGNhbiBiZSByZWFjaGVkIGZyb20gdGhlIHBhZ2UgYXQgdGhlIHByZXZpb3VzIGxldmVsLFxuXHRcdFx0XHRcdC8vIC0tPiB0aGVpciBwYXR0ZXJuIG11c3QgYmUgdGhlIHBhdHRlcm4gb2YgdGhlIHByZXZpb3VzIHBhZ2Ugd2l0aCBhbm90aGVyIHNlZ21lbnQgYXBwZW5kZWRcblx0XHRcdFx0XHRjdXJyZW50LnB1c2gobmV4dFBhZ2UpO1xuXHRcdFx0XHRcdGZpbmRSZWN1cnNpdmUobGV2ZWwgKyAxKTtcblx0XHRcdFx0XHRjdXJyZW50LnBvcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0aWYgKGN1cnJlbnQubGVuZ3RoID4gcmVzdWx0Lmxlbmd0aCkge1xuXHRcdFx0cmVzdWx0ID0gY3VycmVudC5zbGljZSgpOyAvLyBXZSBoYXZlIGZvdW5kIGEgc2VxdWVuY2UgbG9uZ2VyIHRoYW4gb3VyIHByZXZpb3VzIGJlc3QgLS0+IHN0b3JlIGl0IGFzIHRoZSBuZXcgbG9uZ2VzdFxuXHRcdH1cblx0fVxuXG5cdGZpbmRSZWN1cnNpdmUoMCk7XG5cblx0cmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBzdGFydHVwIG9iamVjdCBmcm9tIHRoZSBsaXN0IG9mIHBhZ2VzIGFuZCBjb250ZXh0cy5cbiAqXG4gKiBAcGFyYW0gYVN0YXJ0dXBQYWdlcyBUaGUgcGFnZXNcbiAqIEBwYXJhbSBhQ29udGV4dHMgVGhlIGNvbnRleHRzXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyBlaXRoZXIgYSBoYXNoIG9yIGEgY29udGV4dCB0byBuYXZpZ2F0ZSB0bywgb3IgYW4gZW1wdHkgb2JqZWN0IGlmIG5vIGRlZXAgbGluayB3YXMgZm91bmRcbiAqL1xuZnVuY3Rpb24gX2dldERlZXBMaW5rT2JqZWN0KGFTdGFydHVwUGFnZXM6IFBhZ2VJbmZvW10sIGFDb250ZXh0czogQ29udGV4dFtdKTogeyBoYXNoPzogc3RyaW5nOyBjb250ZXh0PzogQ29udGV4dCB9IHtcblx0aWYgKGFDb250ZXh0cy5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4geyBjb250ZXh0OiBhQ29udGV4dHNbMF0gfTtcblx0fSBlbHNlIGlmIChhQ29udGV4dHMubGVuZ3RoID4gMSkge1xuXHRcdC8vIE5hdmlnYXRpb24gdG8gYSBkZWVwZXIgbGV2ZWwgLS0+IHVzZSB0aGUgcGF0dGVybiBvZiB0aGUgZGVlcGVzdCBvYmplY3QgcGFnZVxuXHRcdC8vIGFuZCByZXBsYWNlIHRoZSBwYXJhbWV0ZXJzIGJ5IHRoZSBJRCBmcm9tIHRoZSBjb250ZXh0c1xuXHRcdGxldCBoYXNoID0gYVN0YXJ0dXBQYWdlc1thU3RhcnR1cFBhZ2VzLmxlbmd0aCAtIDFdLnBhdHRlcm47XG5cdFx0YUNvbnRleHRzLmZvckVhY2goZnVuY3Rpb24ob0NvbnRleHQpIHtcblx0XHRcdGhhc2ggPSBoYXNoLnJlcGxhY2UoXCIoIylcIiwgXCIoXCIgKyBvQ29udGV4dC5nZXRQYXRoKCkuc3BsaXQoXCIoXCIpWzFdKTtcblx0XHR9KTtcblxuXHRcdHJldHVybiB7IGhhc2ggfTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge307XG5cdH1cbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHN0YXJ0dXAgcGFyYW1ldGVycyBmb3IgYSBkZWVwbGluayBjYXNlLCBmcm9tIHN0YXJ0dXAgcGFyYW1ldGVycyBhbmQgcm91dGluZyBpbmZvaXJtYXRpb24uXG4gKlxuICogQHBhcmFtIG9NYW5pZmVzdFJvdXRpbmcgVGhlIHJvdXRpbmcgaW5mb3JtYXRpb24gZnJvbSB0aGUgYXBwIG1hbmlmZXN0XG4gKiBAcGFyYW0gb1N0YXJ0dXBQYXJhbWV0ZXJzIFRoZSBzdGFydHVwIHBhcmFtZXRlcnNcbiAqIEBwYXJhbSBvTW9kZWwgVGhlIE9EYXRhIG1vZGVsXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyBlaXRoZXIgYSBoYXNoIG9yIGEgY29udGV4dCB0byBuYXZpZ2F0ZSB0bywgb3IgYW4gZW1wdHkgb2JqZWN0IGlmIG5vIGRlZXAgbGluayB3YXMgZm91bmRcbiAqL1xuZnVuY3Rpb24gZ2V0RGVlcExpbmtTdGFydHVwSGFzaChcblx0b01hbmlmZXN0Um91dGluZzogYW55LFxuXHRvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSxcblx0b01vZGVsOiBPRGF0YU1vZGVsXG4pOiBQcm9taXNlPHsgaGFzaD86IHN0cmluZzsgY29udGV4dD86IENvbnRleHQgfT4ge1xuXHRsZXQgYVN0YXJ0dXBQYWdlczogUGFnZUluZm9bXTtcblxuXHRyZXR1cm4gb01vZGVsXG5cdFx0LmdldE1ldGFNb2RlbCgpXG5cdFx0LnJlcXVlc3RPYmplY3QoXCIvJEVudGl0eUNvbnRhaW5lci9cIilcblx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHQvLyBDaGVjayBpZiBzZW1hbnRpYyBrZXlzIGFyZSBwcmVzZW50IGluIHVybCBwYXJhbWV0ZXJzIGZvciBldmVyeSBvYmplY3QgcGFnZSBhdCBlYWNoIGxldmVsXG5cdFx0XHRhU3RhcnR1cFBhZ2VzID0gX2dldFN0YXJ0dXBQYWdlc0Zyb21TdGFydHVwUGFyYW1zKG9NYW5pZmVzdFJvdXRpbmcsIG9TdGFydHVwUGFyYW1ldGVycywgb01vZGVsLmdldE1ldGFNb2RlbCgpKTtcblxuXHRcdFx0cmV0dXJuIF9yZXF1ZXN0T2JqZWN0c0Zyb21QYXJhbWV0ZXJzKGFTdGFydHVwUGFnZXMsIG9Nb2RlbCk7XG5cdFx0fSlcblx0XHQudGhlbigoYVZhbHVlczogQ29udGV4dFtdW10pID0+IHtcblx0XHRcdGlmIChhVmFsdWVzLmxlbmd0aCkge1xuXHRcdFx0XHQvLyBNYWtlIHN1cmUgd2Ugb25seSBnZXQgMSBjb250ZXh0IHBlciBwcm9taXNlLCBhbmQgZmxhdHRlbiB0aGUgYXJyYXlcblx0XHRcdFx0Y29uc3QgYUNvbnRleHRzOiBDb250ZXh0W10gPSBbXTtcblx0XHRcdFx0YVZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uKGFGb3VuZENvbnRleHRzKSB7XG5cdFx0XHRcdFx0aWYgKGFGb3VuZENvbnRleHRzLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRcdFx0YUNvbnRleHRzLnB1c2goYUZvdW5kQ29udGV4dHNbMF0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0cmV0dXJuIGFDb250ZXh0cy5sZW5ndGggPT09IGFWYWx1ZXMubGVuZ3RoID8gX2dldERlZXBMaW5rT2JqZWN0KGFTdGFydHVwUGFnZXMsIGFDb250ZXh0cykgOiB7fTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiB7fTtcblx0XHRcdH1cblx0XHR9KTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBuZXcgaGFzaCBiYXNlZCBvbiB0aGUgc3RhcnR1cCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSBvU3RhcnR1cFBhcmFtZXRlcnMgVGhlIHN0YXJ0dXAgcGFyYW1ldGVyIHZhbHVlcyAobWFwIHBhcmFtZXRlciBuYW1lIC0+IGFycmF5IG9mIHZhbHVlcylcbiAqIEBwYXJhbSBzQ29udGV4dFBhdGggVGhlIGNvbnRleHQgcGF0aCBmb3IgdGhlIHN0YXJ0dXAgb2YgdGhlIGFwcCAoZ2VuZXJhbGx5IHRoZSBwYXRoIHRvIHRoZSBtYWluIGVudGl0eSBzZXQpXG4gKiBAcGFyYW0gb1JvdXRlciBUaGUgcm91dGVyIGluc3RhbmNlXG4gKiBAcGFyYW0gb01ldGFNb2RlbCBUaGUgbWV0YSBtb2RlbFxuICogQHJldHVybnMgQSBwcm9taXNlIGNvbnRhaW5pbmcgdGhlIGhhc2ggdG8gbmF2aWdhdGUgdG8sIG9yIGFuIGVtcHR5IHN0cmluZyBpZiB0aGVyZSdzIG5vIG5lZWQgdG8gbmF2aWdhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0Q3JlYXRlU3RhcnR1cEhhc2gob1N0YXJ0dXBQYXJhbWV0ZXJzOiBhbnksIHNDb250ZXh0UGF0aDogc3RyaW5nLCBvUm91dGVyOiBSb3V0ZXIsIG9NZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsKTogUHJvbWlzZTxTdHJpbmc+IHtcblx0cmV0dXJuIG9NZXRhTW9kZWwucmVxdWVzdE9iamVjdChzQ29udGV4dFBhdGggKyBcIkBcIikudGhlbihmdW5jdGlvbihvRW50aXR5U2V0QW5ub3RhdGlvbnM6IGFueSkge1xuXHRcdGxldCBzTWV0YVBhdGggPSBcIlwiO1xuXHRcdGxldCBiQ3JlYXRhYmxlID0gdHJ1ZTtcblxuXHRcdGlmIChcblx0XHRcdG9FbnRpdHlTZXRBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRHJhZnRSb290XCJdICYmXG5cdFx0XHRvRW50aXR5U2V0QW5ub3RhdGlvbnNbXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRyYWZ0Um9vdFwiXVtcIk5ld0FjdGlvblwiXVxuXHRcdCkge1xuXHRcdFx0c01ldGFQYXRoID0gc0NvbnRleHRQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRyYWZ0Um9vdC9OZXdBY3Rpb25AT3JnLk9EYXRhLkNvcmUuVjEuT3BlcmF0aW9uQXZhaWxhYmxlXCI7XG5cdFx0fSBlbHNlIGlmIChcblx0XHRcdG9FbnRpdHlTZXRBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5TZXNzaW9uLnYxLlN0aWNreVNlc3Npb25TdXBwb3J0ZWRcIl0gJiZcblx0XHRcdG9FbnRpdHlTZXRBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5TZXNzaW9uLnYxLlN0aWNreVNlc3Npb25TdXBwb3J0ZWRcIl1bXCJOZXdBY3Rpb25cIl1cblx0XHQpIHtcblx0XHRcdHNNZXRhUGF0aCA9XG5cdFx0XHRcdHNDb250ZXh0UGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlNlc3Npb24udjEuU3RpY2t5U2Vzc2lvblN1cHBvcnRlZC9OZXdBY3Rpb25AT3JnLk9EYXRhLkNvcmUuVjEuT3BlcmF0aW9uQXZhaWxhYmxlXCI7XG5cdFx0fVxuXG5cdFx0aWYgKHNNZXRhUGF0aCkge1xuXHRcdFx0Y29uc3QgYk5ld0FjdGlvbk9wZXJhdGlvbkF2YWlsYWJsZSA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCk7XG5cdFx0XHRpZiAoYk5ld0FjdGlvbk9wZXJhdGlvbkF2YWlsYWJsZSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0YkNyZWF0YWJsZSA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBvSW5zZXJ0UmVzdHJpY3Rpb25zID0gb0VudGl0eVNldEFubm90YXRpb25zW1wiQE9yZy5PRGF0YS5DYXBhYmlsaXRpZXMuVjEuSW5zZXJ0UmVzdHJpY3Rpb25zXCJdO1xuXHRcdFx0aWYgKG9JbnNlcnRSZXN0cmljdGlvbnMgJiYgb0luc2VydFJlc3RyaWN0aW9ucy5JbnNlcnRhYmxlID09PSBmYWxzZSkge1xuXHRcdFx0XHRiQ3JlYXRhYmxlID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChiQ3JlYXRhYmxlKSB7XG5cdFx0XHRyZXR1cm4gZ2V0RGVmYXVsdENyZWF0ZUhhc2gob1N0YXJ0dXBQYXJhbWV0ZXJzLCBzQ29udGV4dFBhdGgsIG9Sb3V0ZXIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gXCJcIjtcblx0XHR9XG5cdH0pO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGhhc2ggdG8gY3JlYXRlIGEgbmV3IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0gb1N0YXJ0dXBQYXJhbWV0ZXJzIFRoZSBzdGFydHVwIHBhcmFtZXRlciB2YWx1ZXMgKG1hcCBwYXJhbWV0ZXIgbmFtZSAtPiBhcnJheSBvZiB2YWx1ZXMpXG4gKiBAcGFyYW0gc0NvbnRleHRQYXRoIFRoZSBjb250ZXh0IHBhdGggb2YgdGhlIGVudGl0eSBzZXQgdG8gYmUgdXNlZCBmb3IgdGhlIGNyZWF0aW9uXG4gKiBAcGFyYW0gb1JvdXRlciBUaGUgcm91dGVyIGluc3RhbmNlXG4gKiBAcmV0dXJucyBUaGUgaGFzaFxuICovXG5mdW5jdGlvbiBnZXREZWZhdWx0Q3JlYXRlSGFzaChvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSwgc0NvbnRleHRQYXRoOiBzdHJpbmcsIG9Sb3V0ZXI6IFJvdXRlcik6IHN0cmluZyB7XG5cdGxldCBzRGVmYXVsdENyZWF0ZUhhc2ggPVxuXHRcdG9TdGFydHVwUGFyYW1ldGVycyAmJiBvU3RhcnR1cFBhcmFtZXRlcnMucHJlZmVycmVkTW9kZSA/IChvU3RhcnR1cFBhcmFtZXRlcnMucHJlZmVycmVkTW9kZVswXSBhcyBzdHJpbmcpIDogXCJjcmVhdGVcIjtcblx0bGV0IHNIYXNoID0gXCJcIjtcblxuXHRzRGVmYXVsdENyZWF0ZUhhc2ggPVxuXHRcdHNEZWZhdWx0Q3JlYXRlSGFzaC5pbmRleE9mKFwiOlwiKSAhPT0gLTEgJiYgc0RlZmF1bHRDcmVhdGVIYXNoLmxlbmd0aCA+IHNEZWZhdWx0Q3JlYXRlSGFzaC5pbmRleE9mKFwiOlwiKSArIDFcblx0XHRcdD8gc0RlZmF1bHRDcmVhdGVIYXNoLnN1YnN0cigwLCBzRGVmYXVsdENyZWF0ZUhhc2guaW5kZXhPZihcIjpcIikpXG5cdFx0XHQ6IFwiY3JlYXRlXCI7XG5cdHNIYXNoID0gc0NvbnRleHRQYXRoLnN1YnN0cmluZygxKSArIFwiKC4uLik/aS1hY3Rpb249XCIgKyBzRGVmYXVsdENyZWF0ZUhhc2g7XG5cdGlmIChvUm91dGVyLmdldFJvdXRlSW5mb0J5SGFzaChzSGFzaCkpIHtcblx0XHRyZXR1cm4gc0hhc2g7XG5cdH0gZWxzZSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiTm8gcm91dGUgbWF0Y2ggZm9yIGNyZWF0aW5nIGEgbmV3IFwiICsgc0NvbnRleHRQYXRoLnN1YnN0cmluZygxKSk7XG5cdH1cbn1cblxuY29uc3QgQXBwU3RhcnR1cEhlbHBlciA9IHtcblx0X2dldEtleXNGcm9tU3RhcnR1cFBhcmFtcyxcblx0X2NyZWF0ZUZpbHRlckZyb21LZXlzLFxuXHRfcmVxdWVzdE9iamVjdHNGcm9tUGFyYW1ldGVycyxcblx0X2dldFJlYWNoYWJsZVBhZ2VzLFxuXHRfZ2V0U3RhcnR1cFBhZ2VzRnJvbVN0YXJ0dXBQYXJhbXMsXG5cdF9nZXREZWVwTGlua09iamVjdCxcblx0Z2V0RGVlcExpbmtTdGFydHVwSGFzaCxcblx0Z2V0Q3JlYXRlU3RhcnR1cEhhc2gsXG5cdGdldERlZmF1bHRDcmVhdGVIYXNoXG59O1xuXG5leHBvcnQgZGVmYXVsdCBBcHBTdGFydHVwSGVscGVyO1xuIl19
373
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkFwcFN0YXJ0dXBIZWxwZXIudHMiXSwibmFtZXMiOlsiQXBwU3RhcnR1cEhlbHBlciIsIl9nZXRLZXlzRnJvbVN0YXJ0dXBQYXJhbXMiLCJhS2V5TmFtZXMiLCJvU3RhcnR1cFBhcmFtZXRlcnMiLCJiQWxsRm91bmQiLCJhS2V5cyIsIm1hcCIsIm5hbWUiLCJsZW5ndGgiLCJ2YWx1ZSIsInVuZGVmaW5lZCIsIl9jcmVhdGVGaWx0ZXJGcm9tS2V5cyIsImJEcmFmdE1vZGUiLCJvTWV0YU1vZGVsIiwiYkZpbHRlckNhc2VTZW5zaXRpdmUiLCJNb2RlbEhlbHBlciIsImlzRmlsdGVyaW5nQ2FzZVNlbnNpdGl2ZSIsImJGaWx0ZXJPbkFjdGl2ZUVudGl0eSIsImFGaWx0ZXJzIiwia2V5IiwiRmlsdGVyIiwicGF0aCIsIm9wZXJhdG9yIiwiRmlsdGVyT3BlcmF0b3IiLCJFUSIsInZhbHVlMSIsImNhc2VTZW5zaXRpdmUiLCJvRHJhZnRGaWx0ZXIiLCJmaWx0ZXJzIiwiYW5kIiwicHVzaCIsIl9yZXF1ZXN0T2JqZWN0c0Zyb21QYXJhbWV0ZXJzIiwiYVN0YXJ0dXBQYWdlcyIsIm9Nb2RlbCIsImFDb250ZXh0UHJvbWlzZXMiLCJwYWdlSW5mbyIsInNlbWFudGljS2V5cyIsInRlY2huaWNhbEtleXMiLCJvRmlsdGVyIiwiZHJhZnRNb2RlIiwiZ2V0TWV0YU1vZGVsIiwib0xpc3RCaW5kIiwiYmluZExpc3QiLCJjb250ZXh0UGF0aCIsImpvaW4iLCJyZXF1ZXN0Q29udGV4dHMiLCJQcm9taXNlIiwiYWxsIiwiX2dldFJlYWNoYWJsZVBhZ2VJbmZvRnJvbVJvdXRlIiwib1JvdXRlIiwib01hbmlmZXN0Um91dGluZyIsInNQYXR0ZXJuIiwicGF0dGVybiIsInJlcGxhY2UiLCJzVGFyZ2V0TmFtZSIsIkFycmF5IiwiaXNBcnJheSIsInRhcmdldCIsIm9UYXJnZXQiLCJ0YXJnZXRzIiwiYVBhdHRlcm5TZWdtZW50cyIsInNwbGl0IiwicGFnZUxldmVsIiwib3B0aW9ucyIsInNldHRpbmdzIiwiYWxsb3dEZWVwTGlua2luZyIsInNDb250ZXh0UGF0aCIsImVudGl0eVNldCIsIm9FbnRpdHlUeXBlIiwiZ2V0T2JqZWN0IiwiYVNlbWFudGljS2V5TmFtZXMiLCJhU2VtYW50aWNrS2V5cyIsInNlbUtleSIsIiRQcm9wZXJ0eVBhdGgiLCJhVGVjaG5pY2FsS2V5cyIsIl9nZXRSZWFjaGFibGVQYWdlcyIsImFSb3V0ZXMiLCJyb3V0ZXMiLCJtUGFnZXNCeUxldmVsIiwiZm9yRWFjaCIsIm9QYWdlSW5mbyIsImFSZWFjaGFibGVQYWdlcyIsImxldmVsIiwiX2dldFN0YXJ0dXBQYWdlc0Zyb21TdGFydHVwUGFyYW1zIiwicmVzdWx0IiwiY3VycmVudCIsImZpbmRSZWN1cnNpdmUiLCJhQ3VycmVudExldmVsUGFnZXMiLCJsYXN0UGFnZSIsIm5leHRQYWdlIiwiaW5kZXhPZiIsInBvcCIsInNsaWNlIiwiX2dldERlZXBMaW5rT2JqZWN0IiwiYUNvbnRleHRzIiwiY29udGV4dCIsImhhc2giLCJvQ29udGV4dCIsImdldFBhdGgiLCJnZXREZWVwTGlua1N0YXJ0dXBIYXNoIiwicmVxdWVzdE9iamVjdCIsInRoZW4iLCJhVmFsdWVzIiwiYUZvdW5kQ29udGV4dHMiLCJnZXRDcmVhdGVTdGFydHVwSGFzaCIsIm9Sb3V0ZXIiLCJvRW50aXR5U2V0QW5ub3RhdGlvbnMiLCJzTWV0YVBhdGgiLCJiQ3JlYXRhYmxlIiwiYk5ld0FjdGlvbk9wZXJhdGlvbkF2YWlsYWJsZSIsIm9JbnNlcnRSZXN0cmljdGlvbnMiLCJJbnNlcnRhYmxlIiwiZ2V0RGVmYXVsdENyZWF0ZUhhc2giLCJzRGVmYXVsdENyZWF0ZUhhc2giLCJwcmVmZXJyZWRNb2RlIiwic0hhc2giLCJzdWJzdHIiLCJzdWJzdHJpbmciLCJnZXRSb3V0ZUluZm9CeUhhc2giLCJFcnJvciJdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTs7OztBQXFCQSxNQUFNQSxnQkFBZ0IsR0FBRztBQUN4QjtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FB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QUFLLEdBQUcsRUFBWjtBQUVBRixNQUFBQSxrQkFBa0IsR0FDakJBLGtCQUFrQixDQUFDdkIsT0FBbkIsQ0FBMkIsR0FBM0IsTUFBb0MsQ0FBQyxDQUFyQyxJQUEwQ3VCLGtCQUFrQixDQUFDekcsTUFBbkIsR0FBNEJ5RyxrQkFBa0IsQ0FBQ3ZCLE9BQW5CLENBQTJCLEdBQTNCLElBQWtDLENBQXhHLEdBQ0d1QixrQkFBa0IsQ0FBQ0csTUFBbkIsQ0FBMEIsQ0FBMUIsRUFBNkJILGtCQUFrQixDQUFDdkIsT0FBbkIsQ0FBMkIsR0FBM0IsQ0FBN0IsQ0FESCxHQUVHLFFBSEo7QUFJQXlCLE1BQUFBLEtBQUssR0FBR2pELFlBQVksQ0FBQ21ELFNBQWIsQ0FBdUIsQ0FBdkIsSUFBNEIsaUJBQTVCLEdBQWdESixrQkFBeEQ7O0FBQ0EsVUFBSVIsT0FBTyxDQUFDYSxrQkFBUixDQUEyQkgsS0FBM0IsQ0FBSixFQUF1QztBQUN0QyxlQUFPQSxLQUFQO0FBQ0EsT0FGRCxNQUVPO0FBQ04sY0FBTSxJQUFJSSxLQUFKLENBQVUsdUNBQXVDckQsWUFBWSxDQUFDbUQsU0FBYixDQUF1QixDQUF2QixDQUFqRCxDQUFOO0FBQ0E7QUFDRDtBQXRZdUIsR0FBekI7U0F5WWVySCxnQiIsInNvdXJjZVJvb3QiOiIuIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE9EYXRhTWV0YU1vZGVsIGZyb20gXCJzYXAvdWkvbW9kZWwvb2RhdGEvdjQvT0RhdGFNZXRhTW9kZWxcIjtcbmltcG9ydCBPRGF0YU1vZGVsIGZyb20gXCJzYXAvdWkvbW9kZWwvb2RhdGEvdjQvT0RhdGFNb2RlbFwiO1xuaW1wb3J0IENvbnRleHQgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9Db250ZXh0XCI7XG5pbXBvcnQgRmlsdGVyIGZyb20gXCJzYXAvdWkvbW9kZWwvRmlsdGVyXCI7XG5pbXBvcnQgRmlsdGVyT3BlcmF0b3IgZnJvbSBcInNhcC91aS9tb2RlbC9GaWx0ZXJPcGVyYXRvclwiO1xuaW1wb3J0IFJvdXRlciBmcm9tIFwic2FwL3VpL2NvcmUvcm91dGluZy9Sb3V0ZXJcIjtcbmltcG9ydCBNb2RlbEhlbHBlciBmcm9tIFwiLi9Nb2RlbEhlbHBlclwiO1xuXG50eXBlIFZhbHVlZEtleSA9IHtcblx0bmFtZTogc3RyaW5nO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxudHlwZSBQYWdlSW5mbyA9IHtcblx0cGF0dGVybjogc3RyaW5nO1xuXHRjb250ZXh0UGF0aDogc3RyaW5nO1xuXHRkcmFmdE1vZGU6IEJvb2xlYW47XG5cdHRlY2huaWNhbEtleXM6IFZhbHVlZEtleVtdIHwgdW5kZWZpbmVkO1xuXHRzZW1hbnRpY0tleXM6IFZhbHVlZEtleVtdIHwgdW5kZWZpbmVkO1xuXHR0YXJnZXQ6IHN0cmluZztcblx0cGFnZUxldmVsOiBudW1iZXI7XG59O1xuXG5jb25zdCBBcHBTdGFydHVwSGVscGVyID0ge1xuXHQvKipcblx0ICogUmV0cmlldmVzIGEgc2V0IG9mIGtleSB2YWx1ZXMgZnJvbSBzdGFydHVwIHBhcmFtZXRlcnMuXG5cdCAqXG5cdCAqIEBwYXJhbSBhS2V5TmFtZXMgVGhlIGFycmF5IG9mIGtleSBuYW1lc1xuXHQgKiBAcGFyYW0gb1N0YXJ0dXBQYXJhbWV0ZXJzIFRoZSBzdGFydHVwIHBhcmFtZXRlcnNcblx0ICogQHJldHVybnMge2FueVtdfSBBbiBhcnJheSBvZiBwYWlycyB7bmFtZSwgdmFsdWV9IGlmIGFsbCBrZXkgdmFsdWVzIGNvdWxkIGJlIGZvdW5kIGluIHRoZSBzdGFydHVwIHBhcmFtZXRlcnMsIHVuZGVmaW5lZCBvdGhlcndpc2Vcblx0ICovXG5cdF9nZXRLZXlzRnJvbVN0YXJ0dXBQYXJhbXM6IGZ1bmN0aW9uKGFLZXlOYW1lczogc3RyaW5nW10sIG9TdGFydHVwUGFyYW1ldGVyczogYW55KTogVmFsdWVkS2V5W10gfCB1bmRlZmluZWQge1xuXHRcdGxldCBiQWxsRm91bmQgPSB0cnVlO1xuXHRcdGNvbnN0IGFLZXlzID0gYUtleU5hbWVzLm1hcChuYW1lID0+IHtcblx0XHRcdGlmIChvU3RhcnR1cFBhcmFtZXRlcnNbbmFtZV0gJiYgb1N0YXJ0dXBQYXJhbWV0ZXJzW25hbWVdLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRyZXR1cm4geyBuYW1lLCB2YWx1ZTogb1N0YXJ0dXBQYXJhbWV0ZXJzW25hbWVdWzBdIGFzIHN0cmluZyB9O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gQSB1bmlxdWUga2V5IHZhbHVlIGNvdWxkbid0IGJlIGZvdW5kIGluIHRoZSBzdGFydHVwIHBhcmFtZXRlcnNcblx0XHRcdFx0YkFsbEZvdW5kID0gZmFsc2U7XG5cdFx0XHRcdHJldHVybiB7IG5hbWUsIHZhbHVlOiBcIlwiIH07XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gYkFsbEZvdW5kID8gYUtleXMgOiB1bmRlZmluZWQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBmaWx0ZXIgZnJvbSBhIGxpc3Qgb2Yga2V5IHZhbHVlcy5cblx0ICpcblx0ICogQHBhcmFtIGFLZXlzIEFycmF5IG9mIHNlbWFudGljIGtleXMgb3IgdGVjaG5pY2FsIGtleXMgKHdpdGggdmFsdWVzKVxuXHQgKiBAcGFyYW0gYkRyYWZ0TW9kZSBUcnVlIGlmIHRoZSBlbnRpdHkgc3VwcG9ydHMgZHJhZnQgbW9kZVxuXHQgKiBAcGFyYW0gb01ldGFNb2RlbCBUaGUgbWV0YW1vZGVsXG5cdCAqIEByZXR1cm5zIFRoZSBmaWx0ZXJcblx0ICovXG5cdF9jcmVhdGVGaWx0ZXJGcm9tS2V5czogZnVuY3Rpb24oYUtleXM6IFZhbHVlZEtleVtdLCBiRHJhZnRNb2RlOiBCb29sZWFuLCBvTWV0YU1vZGVsOiBPRGF0YU1ldGFNb2RlbCk6IEZpbHRlciB7XG5cdFx0Y29uc3QgYkZpbHRlckNhc2VTZW5zaXRpdmUgPSBNb2RlbEhlbHBlci5pc0ZpbHRlcmluZ0Nhc2VTZW5zaXRpdmUob01ldGFNb2RlbCk7XG5cblx0XHRsZXQgYkZpbHRlck9uQWN0aXZlRW50aXR5ID0gZmFsc2U7XG5cdFx0Y29uc3QgYUZpbHRlcnMgPSBhS2V5cy5tYXAoa2V5ID0+IHtcblx0XHRcdGlmIChrZXkubmFtZSA9PT0gXCJJc0FjdGl2ZUVudGl0eVwiKSB7XG5cdFx0XHRcdGJGaWx0ZXJPbkFjdGl2ZUVudGl0eSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbmV3IEZpbHRlcih7XG5cdFx0XHRcdHBhdGg6IGtleS5uYW1lLFxuXHRcdFx0XHRvcGVyYXRvcjogRmlsdGVyT3BlcmF0b3IuRVEsXG5cdFx0XHRcdHZhbHVlMToga2V5LnZhbHVlLFxuXHRcdFx0XHRjYXNlU2Vuc2l0aXZlOiBiRmlsdGVyQ2FzZVNlbnNpdGl2ZVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0aWYgKGJEcmFmdE1vZGUgJiYgIWJGaWx0ZXJPbkFjdGl2ZUVudGl0eSkge1xuXHRcdFx0Y29uc3Qgb0RyYWZ0RmlsdGVyID0gbmV3IEZpbHRlcih7XG5cdFx0XHRcdGZpbHRlcnM6IFtuZXcgRmlsdGVyKFwiSXNBY3RpdmVFbnRpdHlcIiwgXCJFUVwiLCBmYWxzZSksIG5ldyBGaWx0ZXIoXCJTaWJsaW5nRW50aXR5L0lzQWN0aXZlRW50aXR5XCIsIFwiRVFcIiwgbnVsbCldLFxuXHRcdFx0XHRhbmQ6IGZhbHNlXG5cdFx0XHR9KTtcblx0XHRcdGFGaWx0ZXJzLnB1c2gob0RyYWZ0RmlsdGVyKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbmV3IEZpbHRlcihhRmlsdGVycywgdHJ1ZSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIExvYWRzIGFsbCBjb250ZXh0cyBmb3IgYSBsaXN0IG9mIHBhZ2UgaW5mb3MuXG5cdCAqXG5cdCAqIEBwYXJhbSBhU3RhcnR1cFBhZ2VzIFRoZSBsaXN0IG9mIHBhZ2UgaW5mb3Ncblx0ICogQHBhcmFtIG9Nb2RlbCBUaGUgbW9kZWwgdXNlZCB0byBsb2FkIHRoZSBjb250ZXh0c1xuXHQgKiBAcmV0dXJucyBBIFByb21pc2UgZm9yIGFsbCBjb250ZXh0c1xuXHQgKi9cblx0X3JlcXVlc3RPYmplY3RzRnJvbVBhcmFtZXRlcnM6IGZ1bmN0aW9uKGFTdGFydHVwUGFnZXM6IFBhZ2VJbmZvW10sIG9Nb2RlbDogT0RhdGFNb2RlbCk6IFByb21pc2U8Q29udGV4dFtdW10+IHtcblx0XHQvLyBMb2FkIHRoZSByZXNwZWN0aXZlIG9iamVjdHMgZm9yIGFsbCBvYmplY3QgcGFnZXMgZm91bmQgaW4gYUV4dGVybmFsbHlOYXZpZ2FibGVQYWdlc1xuXHRcdGNvbnN0IGFDb250ZXh0UHJvbWlzZXMgPSBhU3RhcnR1cFBhZ2VzLm1hcChwYWdlSW5mbyA9PiB7XG5cdFx0XHRjb25zdCBhS2V5cyA9IHBhZ2VJbmZvLnNlbWFudGljS2V5cyB8fCBwYWdlSW5mby50ZWNobmljYWxLZXlzIHx8IFtdO1xuXHRcdFx0Y29uc3Qgb0ZpbHRlciA9IHRoaXMuX2NyZWF0ZUZpbHRlckZyb21LZXlzKGFLZXlzLCBwYWdlSW5mby5kcmFmdE1vZGUsIG9Nb2RlbC5nZXRNZXRhTW9kZWwoKSk7XG5cblx0XHRcdC8vIG9ubHkgcmVxdWVzdCBhIG1pbmltdW0gb2YgZmllbGRzIHRvIGJvb3N0IGJhY2tlbmQgcGVyZm9ybWFuY2Ugc2luY2UgdGhpcyBpcyBvbmx5IHVzZWQgdG8gY2hlY2sgaWYgYW4gb2JqZWN0IGV4aXN0c1xuXHRcdFx0Y29uc3Qgb0xpc3RCaW5kID0gb01vZGVsLmJpbmRMaXN0KHBhZ2VJbmZvLmNvbnRleHRQYXRoLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgb0ZpbHRlciwge1xuXHRcdFx0XHRcIiRzZWxlY3RcIjogYUtleXNcblx0XHRcdFx0XHQubWFwKGtleSA9PiB7XG5cdFx0XHRcdFx0XHRyZXR1cm4ga2V5Lm5hbWU7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuam9pbihcIixcIilcblx0XHRcdH0gYXMgYW55KTtcblx0XHRcdHJldHVybiBvTGlzdEJpbmQucmVxdWVzdENvbnRleHRzKDAsIDIpO1xuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIFByb21pc2UuYWxsKGFDb250ZXh0UHJvbWlzZXMpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgUGFnZUluZm8gZnJvbSBhIHJvdXRlIGlmIHRpJ3MgcmVhY2hhYmxlIGZyb20gdGhlIHN0YXJ0dXAgcGFyYW1ldGVycy5cblx0ICpcblx0ICogQHBhcmFtIG9Sb3V0ZSBUaGUgcm91dGVcblx0ICogQHBhcmFtIG9NYW5pZmVzdFJvdXRpbmcgVGhlIGFwcCBtYW5pZmVzdCByb3V0aW5nIHNlY3Rpb25cblx0ICogQHBhcmFtIG9TdGFydHVwUGFyYW1ldGVycyBUaGUgc3RhcnR1cCBwYXJhbWV0ZXJzXG5cdCAqIEBwYXJhbSBvTWV0YU1vZGVsIFRoZSBhcHAgbWV0YW1vZGVsXG5cdCAqIEByZXR1cm5zIHthbnl9IEEgcGFnZSBpbmZvIGlmIHRoZSBwYWdlIGlzIHJlYWNoYWJsZSwgdW5kZWZpbmVkIG90aGVyd2lzZVxuXHQgKi9cblx0X2dldFJlYWNoYWJsZVBhZ2VJbmZvRnJvbVJvdXRlOiBmdW5jdGlvbihcblx0XHRvUm91dGU6IGFueSxcblx0XHRvTWFuaWZlc3RSb3V0aW5nOiBhbnksXG5cdFx0b1N0YXJ0dXBQYXJhbWV0ZXJzOiBhbnksXG5cdFx0b01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWxcblx0KTogUGFnZUluZm8gfCB1bmRlZmluZWQge1xuXHRcdC8vIFJlbW92ZSB0cmFpbGluZyAnOj9xdWVyeTonIGFuZCAnLydcblx0XHRsZXQgc1BhdHRlcm46IHN0cmluZyA9IG9Sb3V0ZS5wYXR0ZXJuLnJlcGxhY2UoXCI6P3F1ZXJ5OlwiLCBcIlwiKTtcblx0XHRzUGF0dGVybiA9IHNQYXR0ZXJuLnJlcGxhY2UoL1xcLyQvLCBcIlwiKTtcblxuXHRcdGlmICghc1BhdHRlcm4pIHtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7IC8vIElnbm9yZSBsZXZlbC0wIHJvdXRlcyAoTGlzdFJlcG9ydClcblx0XHR9XG5cblx0XHRzUGF0dGVybiA9IHNQYXR0ZXJuLnJlcGxhY2UoL1xcKFxce1teXFx9XSpcXH1cXCkvZywgXCIoIylcIik7IC8vIFJlcGxhY2Uga2V5cyB3aXRoICNcblxuXHRcdC8vIEdldCB0aGUgcmlnaHRtb3N0IHRhcmdldCBmb3IgdGhpcyByb3V0ZVxuXHRcdGNvbnN0IHNUYXJnZXROYW1lOiBzdHJpbmcgPSBBcnJheS5pc0FycmF5KG9Sb3V0ZS50YXJnZXQpID8gb1JvdXRlLnRhcmdldFtvUm91dGUudGFyZ2V0Lmxlbmd0aCAtIDFdIDogb1JvdXRlLnRhcmdldDtcblx0XHRjb25zdCBvVGFyZ2V0ID0gb01hbmlmZXN0Um91dGluZy50YXJnZXRzW3NUYXJnZXROYW1lXTtcblxuXHRcdGNvbnN0IGFQYXR0ZXJuU2VnbWVudHMgPSBzUGF0dGVybi5zcGxpdChcIi9cIik7XG5cdFx0Y29uc3QgcGFnZUxldmVsID0gYVBhdHRlcm5TZWdtZW50cy5sZW5ndGggLSAxO1xuXG5cdFx0aWYgKHBhZ2VMZXZlbCAhPT0gMCAmJiBvVGFyZ2V0Py5vcHRpb25zPy5zZXR0aW5ncz8uYWxsb3dEZWVwTGlua2luZyAhPT0gdHJ1ZSkge1xuXHRcdFx0Ly8gVGhlIGZpcnN0IGxldmVsIG9mIG9iamVjdCBwYWdlIGFsbG93cyBkZWVwIGxpbmtpbmcgYnkgZGVmYXVsdC5cblx0XHRcdC8vIE90aGVyd2lzZSwgdGhlIHRhcmdldCBtdXN0IGFsbG93IGRlZXAgbGlua2luZyBleHBsaWNpdGVseSBpbiB0aGUgbWFuaWZlc3Rcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Y29uc3Qgc0NvbnRleHRQYXRoOiBzdHJpbmcgPVxuXHRcdFx0b1RhcmdldC5vcHRpb25zLnNldHRpbmdzLmNvbnRleHRQYXRoIHx8IChvVGFyZ2V0Lm9wdGlvbnMuc2V0dGluZ3MuZW50aXR5U2V0ICYmIFwiL1wiICsgb1RhcmdldC5vcHRpb25zLnNldHRpbmdzLmVudGl0eVNldCk7XG5cdFx0Y29uc3Qgb0VudGl0eVR5cGUgPSBzQ29udGV4dFBhdGggJiYgb01ldGFNb2RlbC5nZXRPYmplY3QoXCIvJEVudGl0eUNvbnRhaW5lclwiICsgc0NvbnRleHRQYXRoICsgXCIvXCIpO1xuXG5cdFx0aWYgKCFvRW50aXR5VHlwZSkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBHZXQgdGhlIHNlbWFudGljIGtleSB2YWx1ZXMgZm9yIHRoZSBlbnRpdHlcblx0XHRjb25zdCBhU2VtYW50aWNLZXlOYW1lczogYW55ID0gb01ldGFNb2RlbC5nZXRPYmplY3QoXG5cdFx0XHRcIi8kRW50aXR5Q29udGFpbmVyXCIgKyBzQ29udGV4dFBhdGggKyBcIi9AY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlNlbWFudGljS2V5XCJcblx0XHQpO1xuXG5cdFx0Y29uc3QgYVNlbWFudGlja0tleXMgPSBhU2VtYW50aWNLZXlOYW1lc1xuXHRcdFx0PyB0aGlzLl9nZXRLZXlzRnJvbVN0YXJ0dXBQYXJhbXMoXG5cdFx0XHRcdFx0YVNlbWFudGljS2V5TmFtZXMubWFwKChzZW1LZXk6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHNlbUtleS4kUHJvcGVydHlQYXRoIGFzIHN0cmluZztcblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRvU3RhcnR1cFBhcmFtZXRlcnNcblx0XHRcdCAgKVxuXHRcdFx0OiB1bmRlZmluZWQ7XG5cblx0XHQvLyBHZXQgdGhlIHRlY2huaWNhbCBrZXlzIG9ubHkgaWYgd2UgY291bGRuJ3QgZmluZCB0aGUgc2VtYW50aWMga2V5IHZhbHVlcywgYW5kIG9uIGZpcnN0IGxldmVsIE9QXG5cdFx0Y29uc3QgYVRlY2huaWNhbEtleXMgPVxuXHRcdFx0IWFTZW1hbnRpY2tLZXlzICYmIHBhZ2VMZXZlbCA9PT0gMCA/IHRoaXMuX2dldEtleXNGcm9tU3RhcnR1cFBhcmFtcyhvRW50aXR5VHlwZVtcIiRLZXlcIl0sIG9TdGFydHVwUGFyYW1ldGVycykgOiB1bmRlZmluZWQ7XG5cblx0XHRpZiAoYVNlbWFudGlja0tleXMgPT09IHVuZGVmaW5lZCAmJiBhVGVjaG5pY2FsS2V5cyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHQvLyBXZSBjb3VsZG4ndCBmaW5kIHRoZSBzZW1hbnRpYy90ZWNobmljYWwga2V5cyBpbiB0aGUgc3RhcnR1cCBwYXJhbWV0ZXJzXG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIFRoZSBzdGFydHVwIHBhcmFtZXRlcnMgY29udGFpbiB2YWx1ZXMgZm9yIGFsbCBzZW1hbnRpYyBrZXlzIChvciB0ZWNobmljYWwga2V5cykgLS0+IHdlIGNhbiBzdG9yZSB0aGUgcGFnZSBpbmZvIGluIHRoZSBjb3JyZXNwb25kaW5nIGxldmVsXG5cdFx0Y29uc3QgZHJhZnRNb2RlID1cblx0XHRcdG9NZXRhTW9kZWwuZ2V0T2JqZWN0KFwiLyRFbnRpdHlDb250YWluZXJcIiArIHNDb250ZXh0UGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdFJvb3RcIikgfHxcblx0XHRcdG9NZXRhTW9kZWwuZ2V0T2JqZWN0KFwiLyRFbnRpdHlDb250YWluZXJcIiArIHNDb250ZXh0UGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdE5vZGVcIilcblx0XHRcdFx0PyB0cnVlXG5cdFx0XHRcdDogZmFsc2U7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0cGF0dGVybjogc1BhdHRlcm4sXG5cdFx0XHRjb250ZXh0UGF0aDogc0NvbnRleHRQYXRoLFxuXHRcdFx0ZHJhZnRNb2RlLFxuXHRcdFx0dGVjaG5pY2FsS2V5czogYVRlY2huaWNhbEtleXMsXG5cdFx0XHRzZW1hbnRpY0tleXM6IGFTZW1hbnRpY2tLZXlzLFxuXHRcdFx0dGFyZ2V0OiBzVGFyZ2V0TmFtZSxcblx0XHRcdHBhZ2VMZXZlbFxuXHRcdH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGxpc3Qgb2YgYWxsIHBhZ2VzIHRoYXQgYWxsb3cgZGVlcGxpbmsgYW5kIHRoYXQgY2FuIGJlIHJlYWNoZWQgdXNpbmcgdGhlIHN0YXJ0dXAgcGFyYW1ldGVycy5cblx0ICpcblx0ICogQHBhcmFtIG9NYW5pZmVzdFJvdXRpbmcgVGhlIHJvdXRpbmcgaW5mb3JtYXRpb24gZnJvbSB0aGUgYXBwIG1hbmlmZXN0XG5cdCAqIEBwYXJhbSBvU3RhcnR1cFBhcmFtZXRlcnMgVGhlIHN0YXJ0dXAgcGFyYW1ldGVyc1xuXHQgKiBAcGFyYW0gb01ldGFNb2RlbCBUaGUgbWV0YW1vZGVsXG5cdCAqIEByZXR1cm5zIHthbnl9IFRoZSByZWFjaGFibGUgcGFnZXNcblx0ICovXG5cdF9nZXRSZWFjaGFibGVQYWdlczogZnVuY3Rpb24ob01hbmlmZXN0Um91dGluZzogYW55LCBvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSwgb01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWwpOiBQYWdlSW5mb1tdW10ge1xuXHRcdGNvbnN0IGFSb3V0ZXM6IGFueVtdID0gb01hbmlmZXN0Um91dGluZy5yb3V0ZXM7XG5cdFx0Y29uc3QgbVBhZ2VzQnlMZXZlbDogUmVjb3JkPG51bWJlciwgUGFnZUluZm9bXT4gPSB7fTtcblxuXHRcdGFSb3V0ZXMuZm9yRWFjaChvUm91dGUgPT4ge1xuXHRcdFx0Y29uc3Qgb1BhZ2VJbmZvID0gdGhpcy5fZ2V0UmVhY2hhYmxlUGFnZUluZm9Gcm9tUm91dGUob1JvdXRlLCBvTWFuaWZlc3RSb3V0aW5nLCBvU3RhcnR1cFBhcmFtZXRlcnMsIG9NZXRhTW9kZWwpO1xuXG5cdFx0XHRpZiAob1BhZ2VJbmZvKSB7XG5cdFx0XHRcdGlmICghbVBhZ2VzQnlMZXZlbFtvUGFnZUluZm8ucGFnZUxldmVsXSkge1xuXHRcdFx0XHRcdG1QYWdlc0J5TGV2ZWxbb1BhZ2VJbmZvLnBhZ2VMZXZlbF0gPSBbXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRtUGFnZXNCeUxldmVsW29QYWdlSW5mby5wYWdlTGV2ZWxdLnB1c2gob1BhZ2VJbmZvKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIEEgcGFnZSBpcyByZWFjaGFibGUgb25seSBpZiBhbGwgaXRzIHBhcmVudHMgYXJlIGFsc28gcmVhY2hhYmxlXG5cdFx0Ly8gU28gaWYgd2UgY291bGRuJ3QgZmluZCBhbnkgcGFnZXMgZm9yIGEgZ2l2ZW4gbGV2ZWwsIGFsbCBwYWdlcyB3aXRoIGEgaGlnaGVyIGxldmVsIHdvbid0IGJlIHJlYWNoYWJsZSBhbnl3YXlcblx0XHRjb25zdCBhUmVhY2hhYmxlUGFnZXM6IFBhZ2VJbmZvW11bXSA9IFtdO1xuXHRcdGxldCBsZXZlbCA9IDA7XG5cdFx0d2hpbGUgKG1QYWdlc0J5TGV2ZWxbbGV2ZWxdKSB7XG5cdFx0XHRhUmVhY2hhYmxlUGFnZXMucHVzaChtUGFnZXNCeUxldmVsW2xldmVsXSk7XG5cdFx0XHRsZXZlbCsrO1xuXHRcdH1cblxuXHRcdHJldHVybiBhUmVhY2hhYmxlUGFnZXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgbGlzdCBvZiBzdGFydHVwIHBhZ2VzLlxuXHQgKlxuXHQgKiBAcGFyYW0gb01hbmlmZXN0Um91dGluZyBUaGUgcm91dGluZyBpbmZvcm1hdGlvbiBmcm9tIHRoZSBhcHAgbWFuaWZlc3Rcblx0ICogQHBhcmFtIG9TdGFydHVwUGFyYW1ldGVycyBUaGUgc3RhcnR1cCBwYXJhbWV0ZXJzXG5cdCAqIEBwYXJhbSBvTWV0YU1vZGVsIFRoZSBtZXRhbW9kZWxcblx0ICogQHJldHVybnMge2FueX0gQW4gYXJyYXkgb2Ygc3RhcnR1cCBwYWdlIGluZm9zXG5cdCAqL1xuXHRfZ2V0U3RhcnR1cFBhZ2VzRnJvbVN0YXJ0dXBQYXJhbXM6IGZ1bmN0aW9uKG9NYW5pZmVzdFJvdXRpbmc6IGFueSwgb1N0YXJ0dXBQYXJhbWV0ZXJzOiBhbnksIG9NZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsKTogUGFnZUluZm9bXSB7XG5cdFx0Ly8gRmluZCBhbGwgcGFnZXMgdGhhdCBjYW4gYmUgcmVhY2hlZCB3aXRoIHRoZSBzdGFydHVwIHBhcmFtZXRlcnNcblx0XHRjb25zdCBhUmVhY2hhYmxlUGFnZXMgPSB0aGlzLl9nZXRSZWFjaGFibGVQYWdlcyhvTWFuaWZlc3RSb3V0aW5nLCBvU3RhcnR1cFBhcmFtZXRlcnMsIG9NZXRhTW9kZWwpO1xuXG5cdFx0aWYgKGFSZWFjaGFibGVQYWdlcy5sZW5ndGggPT09IDApIHtcblx0XHRcdHJldHVybiBbXTtcblx0XHR9XG5cblx0XHQvLyBGaW5kIHRoZSBsb25nZXN0IHNlcXVlbmNlIG9mIHBhZ2VzIHRoYXQgY2FuIGJlIHJlYWNoZWQgKHJlY3Vyc2l2ZWx5KVxuXHRcdGxldCByZXN1bHQ6IFBhZ2VJbmZvW10gPSBbXTtcblx0XHRjb25zdCBjdXJyZW50OiBQYWdlSW5mb1tdID0gW107XG5cblx0XHRmdW5jdGlvbiBmaW5kUmVjdXJzaXZlKGxldmVsOiBudW1iZXIpIHtcblx0XHRcdGNvbnN0IGFDdXJyZW50TGV2ZWxQYWdlcyA9IGFSZWFjaGFibGVQYWdlc1tsZXZlbF07XG5cdFx0XHRjb25zdCBsYXN0UGFnZSA9IGN1cnJlbnQubGVuZ3RoID8gY3VycmVudFtjdXJyZW50Lmxlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG5cdFx0XHRpZiAoYUN1cnJlbnRMZXZlbFBhZ2VzKSB7XG5cdFx0XHRcdGFDdXJyZW50TGV2ZWxQYWdlcy5mb3JFYWNoKGZ1bmN0aW9uKG5leHRQYWdlKSB7XG5cdFx0XHRcdFx0aWYgKCFsYXN0UGFnZSB8fCBuZXh0UGFnZS5wYXR0ZXJuLmluZGV4T2YobGFzdFBhZ2UucGF0dGVybikgPT09IDApIHtcblx0XHRcdFx0XHRcdC8vIFdlIG9ubHkgY29uc2lkZXIgcGFnZXMgdGhhdCBjYW4gYmUgcmVhY2hlZCBmcm9tIHRoZSBwYWdlIGF0IHRoZSBwcmV2aW91cyBsZXZlbCxcblx0XHRcdFx0XHRcdC8vIC0tPiB0aGVpciBwYXR0ZXJuIG11c3QgYmUgdGhlIHBhdHRlcm4gb2YgdGhlIHByZXZpb3VzIHBhZ2Ugd2l0aCBhbm90aGVyIHNlZ21lbnQgYXBwZW5kZWRcblx0XHRcdFx0XHRcdGN1cnJlbnQucHVzaChuZXh0UGFnZSk7XG5cdFx0XHRcdFx0XHRmaW5kUmVjdXJzaXZlKGxldmVsICsgMSk7XG5cdFx0XHRcdFx0XHRjdXJyZW50LnBvcCgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoY3VycmVudC5sZW5ndGggPiByZXN1bHQubGVuZ3RoKSB7XG5cdFx0XHRcdHJlc3VsdCA9IGN1cnJlbnQuc2xpY2UoKTsgLy8gV2UgaGF2ZSBmb3VuZCBhIHNlcXVlbmNlIGxvbmdlciB0aGFuIG91ciBwcmV2aW91cyBiZXN0IC0tPiBzdG9yZSBpdCBhcyB0aGUgbmV3IGxvbmdlc3Rcblx0XHRcdH1cblx0XHR9XG5cblx0XHRmaW5kUmVjdXJzaXZlKDApO1xuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSxcblxuXHQvKipcblx0ICogQ3JlYXRlcyB0aGUgc3RhcnR1cCBvYmplY3QgZnJvbSB0aGUgbGlzdCBvZiBwYWdlcyBhbmQgY29udGV4dHMuXG5cdCAqXG5cdCAqIEBwYXJhbSBhU3RhcnR1cFBhZ2VzIFRoZSBwYWdlc1xuXHQgKiBAcGFyYW0gYUNvbnRleHRzIFRoZSBjb250ZXh0c1xuXHQgKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyBlaXRoZXIgYSBoYXNoIG9yIGEgY29udGV4dCB0byBuYXZpZ2F0ZSB0bywgb3IgYW4gZW1wdHkgb2JqZWN0IGlmIG5vIGRlZXAgbGluayB3YXMgZm91bmRcblx0ICovXG5cdF9nZXREZWVwTGlua09iamVjdDogZnVuY3Rpb24oYVN0YXJ0dXBQYWdlczogUGFnZUluZm9bXSwgYUNvbnRleHRzOiBDb250ZXh0W10pOiB7IGhhc2g/OiBzdHJpbmc7IGNvbnRleHQ/OiBDb250ZXh0IH0ge1xuXHRcdGlmIChhQ29udGV4dHMubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRyZXR1cm4geyBjb250ZXh0OiBhQ29udGV4dHNbMF0gfTtcblx0XHR9IGVsc2UgaWYgKGFDb250ZXh0cy5sZW5ndGggPiAxKSB7XG5cdFx0XHQvLyBOYXZpZ2F0aW9uIHRvIGEgZGVlcGVyIGxldmVsIC0tPiB1c2UgdGhlIHBhdHRlcm4gb2YgdGhlIGRlZXBlc3Qgb2JqZWN0IHBhZ2Vcblx0XHRcdC8vIGFuZCByZXBsYWNlIHRoZSBwYXJhbWV0ZXJzIGJ5IHRoZSBJRCBmcm9tIHRoZSBjb250ZXh0c1xuXHRcdFx0bGV0IGhhc2ggPSBhU3RhcnR1cFBhZ2VzW2FTdGFydHVwUGFnZXMubGVuZ3RoIC0gMV0ucGF0dGVybjtcblx0XHRcdGFDb250ZXh0cy5mb3JFYWNoKGZ1bmN0aW9uKG9Db250ZXh0KSB7XG5cdFx0XHRcdGhhc2ggPSBoYXNoLnJlcGxhY2UoXCIoIylcIiwgXCIoXCIgKyBvQ29udGV4dC5nZXRQYXRoKCkuc3BsaXQoXCIoXCIpWzFdKTtcblx0XHRcdH0pO1xuXG5cdFx0XHRyZXR1cm4geyBoYXNoIH07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiB7fTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIENhbGN1bGF0ZXMgc3RhcnR1cCBwYXJhbWV0ZXJzIGZvciBhIGRlZXBsaW5rIGNhc2UsIGZyb20gc3RhcnR1cCBwYXJhbWV0ZXJzIGFuZCByb3V0aW5nIGluZm9pcm1hdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIG9NYW5pZmVzdFJvdXRpbmcgVGhlIHJvdXRpbmcgaW5mb3JtYXRpb24gZnJvbSB0aGUgYXBwIG1hbmlmZXN0XG5cdCAqIEBwYXJhbSBvU3RhcnR1cFBhcmFtZXRlcnMgVGhlIHN0YXJ0dXAgcGFyYW1ldGVyc1xuXHQgKiBAcGFyYW0gb01vZGVsIFRoZSBPRGF0YSBtb2RlbFxuXHQgKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyBlaXRoZXIgYSBoYXNoIG9yIGEgY29udGV4dCB0byBuYXZpZ2F0ZSB0bywgb3IgYW4gZW1wdHkgb2JqZWN0IGlmIG5vIGRlZXAgbGluayB3YXMgZm91bmRcblx0ICovXG5cdGdldERlZXBMaW5rU3RhcnR1cEhhc2g6IGZ1bmN0aW9uKFxuXHRcdG9NYW5pZmVzdFJvdXRpbmc6IGFueSxcblx0XHRvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSxcblx0XHRvTW9kZWw6IE9EYXRhTW9kZWxcblx0KTogUHJvbWlzZTx7IGhhc2g/OiBzdHJpbmc7IGNvbnRleHQ/OiBDb250ZXh0IH0+IHtcblx0XHRsZXQgYVN0YXJ0dXBQYWdlczogUGFnZUluZm9bXTtcblxuXHRcdHJldHVybiBvTW9kZWxcblx0XHRcdC5nZXRNZXRhTW9kZWwoKVxuXHRcdFx0LnJlcXVlc3RPYmplY3QoXCIvJEVudGl0eUNvbnRhaW5lci9cIilcblx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgc2VtYW50aWMga2V5cyBhcmUgcHJlc2VudCBpbiB1cmwgcGFyYW1ldGVycyBmb3IgZXZlcnkgb2JqZWN0IHBhZ2UgYXQgZWFjaCBsZXZlbFxuXHRcdFx0XHRhU3RhcnR1cFBhZ2VzID0gdGhpcy5fZ2V0U3RhcnR1cFBhZ2VzRnJvbVN0YXJ0dXBQYXJhbXMob01hbmlmZXN0Um91dGluZywgb1N0YXJ0dXBQYXJhbWV0ZXJzLCBvTW9kZWwuZ2V0TWV0YU1vZGVsKCkpO1xuXG5cdFx0XHRcdHJldHVybiB0aGlzLl9yZXF1ZXN0T2JqZWN0c0Zyb21QYXJhbWV0ZXJzKGFTdGFydHVwUGFnZXMsIG9Nb2RlbCk7XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4oKGFWYWx1ZXM6IENvbnRleHRbXVtdKSA9PiB7XG5cdFx0XHRcdGlmIChhVmFsdWVzLmxlbmd0aCkge1xuXHRcdFx0XHRcdC8vIE1ha2Ugc3VyZSB3ZSBvbmx5IGdldCAxIGNvbnRleHQgcGVyIHByb21pc2UsIGFuZCBmbGF0dGVuIHRoZSBhcnJheVxuXHRcdFx0XHRcdGNvbnN0IGFDb250ZXh0czogQ29udGV4dFtdID0gW107XG5cdFx0XHRcdFx0YVZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uKGFGb3VuZENvbnRleHRzKSB7XG5cdFx0XHRcdFx0XHRpZiAoYUZvdW5kQ29udGV4dHMubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRcdFx0XHRcdGFDb250ZXh0cy5wdXNoKGFGb3VuZENvbnRleHRzWzBdKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdHJldHVybiBhQ29udGV4dHMubGVuZ3RoID09PSBhVmFsdWVzLmxlbmd0aCA/IHRoaXMuX2dldERlZXBMaW5rT2JqZWN0KGFTdGFydHVwUGFnZXMsIGFDb250ZXh0cykgOiB7fTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4ge307XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDYWxjdWxhdGVzIHRoZSBuZXcgaGFzaCBiYXNlZCBvbiB0aGUgc3RhcnR1cCBwYXJhbWV0ZXJzLlxuXHQgKlxuXHQgKiBAcGFyYW0gb1N0YXJ0dXBQYXJhbWV0ZXJzIFRoZSBzdGFydHVwIHBhcmFtZXRlciB2YWx1ZXMgKG1hcCBwYXJhbWV0ZXIgbmFtZSAtPiBhcnJheSBvZiB2YWx1ZXMpXG5cdCAqIEBwYXJhbSBzQ29udGV4dFBhdGggVGhlIGNvbnRleHQgcGF0aCBmb3IgdGhlIHN0YXJ0dXAgb2YgdGhlIGFwcCAoZ2VuZXJhbGx5IHRoZSBwYXRoIHRvIHRoZSBtYWluIGVudGl0eSBzZXQpXG5cdCAqIEBwYXJhbSBvUm91dGVyIFRoZSByb3V0ZXIgaW5zdGFuY2Vcblx0ICogQHBhcmFtIG9NZXRhTW9kZWwgVGhlIG1ldGEgbW9kZWxcblx0ICogQHJldHVybnMgQSBwcm9taXNlIGNvbnRhaW5pbmcgdGhlIGhhc2ggdG8gbmF2aWdhdGUgdG8sIG9yIGFuIGVtcHR5IHN0cmluZyBpZiB0aGVyZSdzIG5vIG5lZWQgdG8gbmF2aWdhdGVcblx0ICovXG5cdGdldENyZWF0ZVN0YXJ0dXBIYXNoOiBmdW5jdGlvbihcblx0XHRvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSxcblx0XHRzQ29udGV4dFBhdGg6IHN0cmluZyxcblx0XHRvUm91dGVyOiBSb3V0ZXIsXG5cdFx0b01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWxcblx0KTogUHJvbWlzZTxTdHJpbmc+IHtcblx0XHRyZXR1cm4gb01ldGFNb2RlbC5yZXF1ZXN0T2JqZWN0KHNDb250ZXh0UGF0aCArIFwiQFwiKS50aGVuKChvRW50aXR5U2V0QW5ub3RhdGlvbnM6IGFueSkgPT4ge1xuXHRcdFx0bGV0IHNNZXRhUGF0aCA9IFwiXCI7XG5cdFx0XHRsZXQgYkNyZWF0YWJsZSA9IHRydWU7XG5cblx0XHRcdGlmIChcblx0XHRcdFx0b0VudGl0eVNldEFubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdFJvb3RcIl0gJiZcblx0XHRcdFx0b0VudGl0eVNldEFubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdFJvb3RcIl1bXCJOZXdBY3Rpb25cIl1cblx0XHRcdCkge1xuXHRcdFx0XHRzTWV0YVBhdGggPSBzQ29udGV4dFBhdGggKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRHJhZnRSb290L05ld0FjdGlvbkBPcmcuT0RhdGEuQ29yZS5WMS5PcGVyYXRpb25BdmFpbGFibGVcIjtcblx0XHRcdH0gZWxzZSBpZiAoXG5cdFx0XHRcdG9FbnRpdHlTZXRBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5TZXNzaW9uLnYxLlN0aWNreVNlc3Npb25TdXBwb3J0ZWRcIl0gJiZcblx0XHRcdFx0b0VudGl0eVNldEFubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlNlc3Npb24udjEuU3RpY2t5U2Vzc2lvblN1cHBvcnRlZFwiXVtcIk5ld0FjdGlvblwiXVxuXHRcdFx0KSB7XG5cdFx0XHRcdHNNZXRhUGF0aCA9XG5cdFx0XHRcdFx0c0NvbnRleHRQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuU2Vzc2lvbi52MS5TdGlja3lTZXNzaW9uU3VwcG9ydGVkL05ld0FjdGlvbkBPcmcuT0RhdGEuQ29yZS5WMS5PcGVyYXRpb25BdmFpbGFibGVcIjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHNNZXRhUGF0aCkge1xuXHRcdFx0XHRjb25zdCBiTmV3QWN0aW9uT3BlcmF0aW9uQXZhaWxhYmxlID0gb01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoKTtcblx0XHRcdFx0aWYgKGJOZXdBY3Rpb25PcGVyYXRpb25BdmFpbGFibGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0YkNyZWF0YWJsZSA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCBvSW5zZXJ0UmVzdHJpY3Rpb25zID0gb0VudGl0eVNldEFubm90YXRpb25zW1wiQE9yZy5PRGF0YS5DYXBhYmlsaXRpZXMuVjEuSW5zZXJ0UmVzdHJpY3Rpb25zXCJdO1xuXHRcdFx0XHRpZiAob0luc2VydFJlc3RyaWN0aW9ucyAmJiBvSW5zZXJ0UmVzdHJpY3Rpb25zLkluc2VydGFibGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0YkNyZWF0YWJsZSA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoYkNyZWF0YWJsZSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5nZXREZWZhdWx0Q3JlYXRlSGFzaChvU3RhcnR1cFBhcmFtZXRlcnMsIHNDb250ZXh0UGF0aCwgb1JvdXRlcik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gXCJcIjtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogQ2FsY3VsYXRlcyB0aGUgaGFzaCB0byBjcmVhdGUgYSBuZXcgb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0gb1N0YXJ0dXBQYXJhbWV0ZXJzIFRoZSBzdGFydHVwIHBhcmFtZXRlciB2YWx1ZXMgKG1hcCBwYXJhbWV0ZXIgbmFtZSAtPiBhcnJheSBvZiB2YWx1ZXMpXG5cdCAqIEBwYXJhbSBzQ29udGV4dFBhdGggVGhlIGNvbnRleHQgcGF0aCBvZiB0aGUgZW50aXR5IHNldCB0byBiZSB1c2VkIGZvciB0aGUgY3JlYXRpb25cblx0ICogQHBhcmFtIG9Sb3V0ZXIgVGhlIHJvdXRlciBpbnN0YW5jZVxuXHQgKiBAcmV0dXJucyBUaGUgaGFzaFxuXHQgKi9cblx0Z2V0RGVmYXVsdENyZWF0ZUhhc2g6IGZ1bmN0aW9uKG9TdGFydHVwUGFyYW1ldGVyczogYW55LCBzQ29udGV4dFBhdGg6IHN0cmluZywgb1JvdXRlcjogUm91dGVyKTogc3RyaW5nIHtcblx0XHRsZXQgc0RlZmF1bHRDcmVhdGVIYXNoID1cblx0XHRcdG9TdGFydHVwUGFyYW1ldGVycyAmJiBvU3RhcnR1cFBhcmFtZXRlcnMucHJlZmVycmVkTW9kZSA/IChvU3RhcnR1cFBhcmFtZXRlcnMucHJlZmVycmVkTW9kZVswXSBhcyBzdHJpbmcpIDogXCJjcmVhdGVcIjtcblx0XHRsZXQgc0hhc2ggPSBcIlwiO1xuXG5cdFx0c0RlZmF1bHRDcmVhdGVIYXNoID1cblx0XHRcdHNEZWZhdWx0Q3JlYXRlSGFzaC5pbmRleE9mKFwiOlwiKSAhPT0gLTEgJiYgc0RlZmF1bHRDcmVhdGVIYXNoLmxlbmd0aCA+IHNEZWZhdWx0Q3JlYXRlSGFzaC5pbmRleE9mKFwiOlwiKSArIDFcblx0XHRcdFx0PyBzRGVmYXVsdENyZWF0ZUhhc2guc3Vic3RyKDAsIHNEZWZhdWx0Q3JlYXRlSGFzaC5pbmRleE9mKFwiOlwiKSlcblx0XHRcdFx0OiBcImNyZWF0ZVwiO1xuXHRcdHNIYXNoID0gc0NvbnRleHRQYXRoLnN1YnN0cmluZygxKSArIFwiKC4uLik/aS1hY3Rpb249XCIgKyBzRGVmYXVsdENyZWF0ZUhhc2g7XG5cdFx0aWYgKG9Sb3V0ZXIuZ2V0Um91dGVJbmZvQnlIYXNoKHNIYXNoKSkge1xuXHRcdFx0cmV0dXJuIHNIYXNoO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJObyByb3V0ZSBtYXRjaCBmb3IgY3JlYXRpbmcgYSBuZXcgXCIgKyBzQ29udGV4dFBhdGguc3Vic3RyaW5nKDEpKTtcblx0XHR9XG5cdH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFwcFN0YXJ0dXBIZWxwZXI7XG4iXX0=