@sapui5/sap.fe.core 1.97.0 → 1.99.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 (249) hide show
  1. package/package.json +5 -4
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +377 -405
  4. package/src/sap/fe/core/AnnotationHelper.ts +385 -0
  5. package/src/sap/fe/core/AppComponent.js +6 -3
  6. package/src/sap/fe/core/AppStateHandler.js +229 -181
  7. package/src/sap/fe/core/AppStateHandler.ts +171 -0
  8. package/src/sap/fe/core/BaseController.js +3 -2
  9. package/src/sap/fe/core/BusyLocker.js +105 -121
  10. package/src/sap/fe/core/BusyLocker.ts +98 -0
  11. package/src/sap/fe/core/CommonUtils.js +2073 -2379
  12. package/src/sap/fe/core/CommonUtils.ts +2078 -0
  13. package/src/sap/fe/core/ExtensionAPI.js +16 -7
  14. package/src/sap/fe/core/PageController.js +84 -119
  15. package/src/sap/fe/core/PageController.ts +101 -0
  16. package/src/sap/fe/core/RouterProxy.js +986 -807
  17. package/src/sap/fe/core/RouterProxy.ts +838 -0
  18. package/src/sap/fe/core/Synchronization.js +51 -35
  19. package/src/sap/fe/core/Synchronization.ts +29 -0
  20. package/src/sap/fe/core/TemplateComponent.js +173 -155
  21. package/src/sap/fe/core/TemplateComponent.ts +166 -0
  22. package/src/sap/fe/core/TemplateModel.js +97 -54
  23. package/src/sap/fe/core/TemplateModel.ts +64 -0
  24. package/src/sap/fe/core/TransactionHelper.js +1576 -1579
  25. package/src/sap/fe/core/TransactionHelper.ts +1706 -0
  26. package/src/sap/fe/core/actions/draft.js +560 -581
  27. package/src/sap/fe/core/actions/draft.ts +594 -0
  28. package/src/sap/fe/core/actions/messageHandling.js +545 -511
  29. package/src/sap/fe/core/actions/messageHandling.ts +532 -0
  30. package/src/sap/fe/core/actions/nonDraft.js +17 -19
  31. package/src/sap/fe/core/actions/nonDraft.ts +12 -0
  32. package/src/sap/fe/core/actions/operations.js +1074 -1211
  33. package/src/sap/fe/core/actions/operations.ts +1162 -0
  34. package/src/sap/fe/core/actions/sticky.js +102 -105
  35. package/src/sap/fe/core/actions/sticky.ts +102 -0
  36. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +3 -2
  37. package/src/sap/fe/core/controllerextensions/EditFlow.js +229 -260
  38. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +3 -2
  39. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +288 -13
  40. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +27 -23
  41. package/src/sap/fe/core/controllerextensions/InternalRouting.js +82 -46
  42. package/src/sap/fe/core/controllerextensions/KPIManagement.js +113 -25
  43. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +135 -44
  44. package/src/sap/fe/core/controllerextensions/MassEdit.js +172 -0
  45. package/src/sap/fe/core/controllerextensions/MessageHandler.js +22 -9
  46. package/src/sap/fe/core/controllerextensions/PageReady.js +3 -3
  47. package/src/sap/fe/core/controllerextensions/PageReady.ts +12 -8
  48. package/src/sap/fe/core/controllerextensions/Paginator.js +37 -9
  49. package/src/sap/fe/core/controllerextensions/Placeholder.js +8 -4
  50. package/src/sap/fe/core/controllerextensions/Routing.js +25 -5
  51. package/src/sap/fe/core/controllerextensions/RoutingListener.js +3 -2
  52. package/src/sap/fe/core/controllerextensions/Share.js +22 -8
  53. package/src/sap/fe/core/controllerextensions/SideEffects.js +9 -9
  54. package/src/sap/fe/core/controllerextensions/SideEffects.ts +22 -21
  55. package/src/sap/fe/core/controllerextensions/ViewState.js +3 -2
  56. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -1
  57. package/src/sap/fe/core/controls/CommandExecution.js +3 -2
  58. package/src/sap/fe/core/controls/ConditionalWrapper.js +3 -2
  59. package/src/sap/fe/core/controls/CustomQuickViewPage.js +3 -2
  60. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +9 -5
  61. package/src/sap/fe/core/controls/FieldWrapper.js +18 -23
  62. package/src/sap/fe/core/controls/FilterBar.js +3 -2
  63. package/src/sap/fe/core/controls/FormElementWrapper.js +3 -7
  64. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +3 -2
  65. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +2 -1
  66. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +3 -2
  67. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +5 -4
  68. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +3 -2
  69. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +3 -2
  70. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +106 -0
  71. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +79 -0
  72. package/src/sap/fe/core/converters/ConverterContext.js +14 -2
  73. package/src/sap/fe/core/converters/ConverterContext.ts +14 -3
  74. package/src/sap/fe/core/converters/ManifestSettings.js +1 -1
  75. package/src/sap/fe/core/converters/ManifestSettings.ts +4 -0
  76. package/src/sap/fe/core/converters/ManifestWrapper.js +56 -32
  77. package/src/sap/fe/core/converters/ManifestWrapper.ts +24 -6
  78. package/src/sap/fe/core/converters/MetaModelConverter.js +67 -6
  79. package/src/sap/fe/core/converters/MetaModelConverter.ts +70 -14
  80. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  81. package/src/sap/fe/core/converters/TemplateConverter.ts +2 -2
  82. package/src/sap/fe/core/converters/annotations/DataField.js +3 -3
  83. package/src/sap/fe/core/converters/annotations/DataField.ts +1 -1
  84. package/src/sap/fe/core/converters/common/AnnotationConverter.js +33 -21
  85. package/src/sap/fe/core/converters/controls/Common/Action.js +11 -2
  86. package/src/sap/fe/core/converters/controls/Common/Action.ts +8 -2
  87. package/src/sap/fe/core/converters/controls/Common/Chart.js +5 -3
  88. package/src/sap/fe/core/converters/controls/Common/Chart.ts +11 -3
  89. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +3 -3
  90. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +2 -2
  91. package/src/sap/fe/core/converters/controls/Common/Form.js +20 -10
  92. package/src/sap/fe/core/converters/controls/Common/Form.ts +24 -4
  93. package/src/sap/fe/core/converters/controls/Common/KPI.js +69 -4
  94. package/src/sap/fe/core/converters/controls/Common/KPI.ts +72 -0
  95. package/src/sap/fe/core/converters/controls/Common/Table.js +390 -398
  96. package/src/sap/fe/core/converters/controls/Common/Table.ts +497 -484
  97. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +527 -0
  98. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +655 -0
  99. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +489 -37
  100. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +506 -58
  101. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +2 -2
  102. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +1 -1
  103. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +17 -9
  104. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +24 -9
  105. package/src/sap/fe/core/converters/helpers/Aggregation.js +18 -3
  106. package/src/sap/fe/core/converters/helpers/Aggregation.ts +28 -5
  107. package/src/sap/fe/core/converters/helpers/IssueManager.js +7 -1
  108. package/src/sap/fe/core/converters/helpers/IssueManager.ts +6 -0
  109. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +4 -4
  110. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +3 -3
  111. package/src/sap/fe/core/converters/templates/ListReportConverter.js +13 -6
  112. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +26 -15
  113. package/src/sap/fe/core/designtime/AppComponent.designtime.js +11 -2
  114. package/src/sap/fe/core/formatters/CriticalityFormatter.js +1 -1
  115. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +1 -1
  116. package/src/sap/fe/core/formatters/FPMFormatter.js +1 -1
  117. package/src/sap/fe/core/formatters/FPMFormatter.ts +4 -10
  118. package/src/sap/fe/core/formatters/KPIFormatter.js +1 -1
  119. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -1
  120. package/src/sap/fe/core/formatters/TableFormatter.js +39 -28
  121. package/src/sap/fe/core/formatters/TableFormatter.ts +43 -28
  122. package/src/sap/fe/core/formatters/ValueFormatter.js +30 -5
  123. package/src/sap/fe/core/formatters/ValueFormatter.ts +30 -7
  124. package/src/sap/fe/core/fpm/Component.js +3 -2
  125. package/src/sap/fe/core/helpers/AppStartupHelper.js +359 -0
  126. package/src/sap/fe/core/helpers/AppStartupHelper.ts +391 -0
  127. package/src/sap/fe/core/helpers/BindingExpression.js +484 -437
  128. package/src/sap/fe/core/helpers/BindingExpression.ts +480 -463
  129. package/src/sap/fe/core/helpers/ClassSupport.js +27 -15
  130. package/src/sap/fe/core/helpers/ClassSupport.ts +31 -20
  131. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +63 -59
  132. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +56 -0
  133. package/src/sap/fe/core/helpers/EditState.js +81 -84
  134. package/src/sap/fe/core/helpers/EditState.ts +81 -0
  135. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +62 -48
  136. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +49 -0
  137. package/src/sap/fe/core/helpers/FPMHelper.js +52 -56
  138. package/src/sap/fe/core/helpers/FPMHelper.ts +62 -0
  139. package/src/sap/fe/core/helpers/KeepAliveHelper.js +4 -5
  140. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +10 -10
  141. package/src/sap/fe/core/helpers/MassEditHelper.js +687 -0
  142. package/src/sap/fe/core/helpers/ModelHelper.js +229 -225
  143. package/src/sap/fe/core/helpers/ModelHelper.ts +227 -0
  144. package/src/sap/fe/core/helpers/PasteHelper.js +210 -132
  145. package/src/sap/fe/core/helpers/PasteHelper.ts +196 -0
  146. package/src/sap/fe/core/helpers/SemanticDateOperators.js +332 -313
  147. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +330 -0
  148. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +66 -67
  149. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +73 -0
  150. package/src/sap/fe/core/helpers/StableIdHelper.js +4 -7
  151. package/src/sap/fe/core/helpers/StableIdHelper.ts +2 -6
  152. package/src/sap/fe/core/jsx-runtime/jsx.js +1 -1
  153. package/src/sap/fe/core/jsx-runtime/jsx.ts +1 -1
  154. package/src/sap/fe/core/library.js +30 -3
  155. package/src/sap/fe/core/library.support.js +12 -5
  156. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +62 -0
  157. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +66 -0
  158. package/src/sap/fe/core/messagebundle.properties +61 -13
  159. package/src/sap/fe/core/messagebundle_ar.properties +33 -2
  160. package/src/sap/fe/core/messagebundle_bg.properties +33 -2
  161. package/src/sap/fe/core/messagebundle_ca.properties +33 -2
  162. package/src/sap/fe/core/messagebundle_cs.properties +34 -3
  163. package/src/sap/fe/core/messagebundle_cy.properties +33 -2
  164. package/src/sap/fe/core/messagebundle_da.properties +33 -2
  165. package/src/sap/fe/core/messagebundle_de.properties +33 -2
  166. package/src/sap/fe/core/messagebundle_el.properties +33 -2
  167. package/src/sap/fe/core/messagebundle_en.properties +32 -1
  168. package/src/sap/fe/core/messagebundle_en_GB.properties +32 -1
  169. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +36 -1
  170. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +33 -2
  171. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +33 -2
  172. package/src/sap/fe/core/messagebundle_es.properties +33 -2
  173. package/src/sap/fe/core/messagebundle_es_MX.properties +33 -2
  174. package/src/sap/fe/core/messagebundle_et.properties +33 -2
  175. package/src/sap/fe/core/messagebundle_fi.properties +34 -3
  176. package/src/sap/fe/core/messagebundle_fr.properties +38 -7
  177. package/src/sap/fe/core/messagebundle_fr_CA.properties +33 -2
  178. package/src/sap/fe/core/messagebundle_hi.properties +33 -2
  179. package/src/sap/fe/core/messagebundle_hr.properties +33 -2
  180. package/src/sap/fe/core/messagebundle_hu.properties +34 -3
  181. package/src/sap/fe/core/messagebundle_id.properties +36 -5
  182. package/src/sap/fe/core/messagebundle_it.properties +33 -2
  183. package/src/sap/fe/core/messagebundle_iw.properties +33 -2
  184. package/src/sap/fe/core/messagebundle_ja.properties +33 -2
  185. package/src/sap/fe/core/messagebundle_kk.properties +33 -2
  186. package/src/sap/fe/core/messagebundle_ko.properties +33 -2
  187. package/src/sap/fe/core/messagebundle_lt.properties +33 -2
  188. package/src/sap/fe/core/messagebundle_lv.properties +33 -2
  189. package/src/sap/fe/core/messagebundle_ms.properties +33 -2
  190. package/src/sap/fe/core/messagebundle_nl.properties +33 -2
  191. package/src/sap/fe/core/messagebundle_no.properties +33 -2
  192. package/src/sap/fe/core/messagebundle_pl.properties +33 -2
  193. package/src/sap/fe/core/messagebundle_pt.properties +34 -3
  194. package/src/sap/fe/core/messagebundle_pt_PT.properties +33 -2
  195. package/src/sap/fe/core/messagebundle_ro.properties +33 -2
  196. package/src/sap/fe/core/messagebundle_ru.properties +33 -2
  197. package/src/sap/fe/core/messagebundle_sh.properties +33 -2
  198. package/src/sap/fe/core/messagebundle_sk.properties +33 -2
  199. package/src/sap/fe/core/messagebundle_sl.properties +33 -2
  200. package/src/sap/fe/core/messagebundle_sv.properties +34 -3
  201. package/src/sap/fe/core/messagebundle_th.properties +33 -2
  202. package/src/sap/fe/core/messagebundle_tr.properties +33 -2
  203. package/src/sap/fe/core/messagebundle_uk.properties +33 -2
  204. package/src/sap/fe/core/messagebundle_vi.properties +33 -2
  205. package/src/sap/fe/core/messagebundle_zh_CN.properties +33 -2
  206. package/src/sap/fe/core/messagebundle_zh_TW.properties +33 -2
  207. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +2 -2
  208. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -1
  209. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +269 -202
  210. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +212 -0
  211. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +4 -3
  212. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +9 -5
  213. package/src/sap/fe/core/services/NavigationServiceFactory.js +406 -300
  214. package/src/sap/fe/core/services/NavigationServiceFactory.ts +316 -0
  215. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +149 -81
  216. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +80 -0
  217. package/src/sap/fe/core/services/RoutingServiceFactory.js +987 -1152
  218. package/src/sap/fe/core/services/RoutingServiceFactory.ts +898 -0
  219. package/src/sap/fe/core/services/ShellServicesFactory.js +31 -2
  220. package/src/sap/fe/core/services/ShellServicesFactory.ts +45 -11
  221. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +42 -85
  222. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +57 -100
  223. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +461 -478
  224. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +453 -0
  225. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +10 -8
  226. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +8 -0
  227. package/src/sap/fe/core/support/AnnotationIssue.support.js +15 -3
  228. package/src/sap/fe/core/support/AnnotationIssue.support.ts +16 -2
  229. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.js +2 -2
  230. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.ts +1 -1
  231. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +38 -0
  232. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.ts +18 -0
  233. package/src/sap/fe/core/templating/DataModelPathHelper.js +10 -48
  234. package/src/sap/fe/core/templating/DataModelPathHelper.ts +14 -46
  235. package/src/sap/fe/core/templating/DisplayModeFormatter.js +114 -0
  236. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +86 -0
  237. package/src/sap/fe/core/templating/FieldControlHelper.js +8 -8
  238. package/src/sap/fe/core/templating/FieldControlHelper.ts +25 -7
  239. package/src/sap/fe/core/templating/FilterHelper.js +139 -70
  240. package/src/sap/fe/core/templating/FilterHelper.ts +140 -70
  241. package/src/sap/fe/core/templating/PropertyHelper.js +2 -2
  242. package/src/sap/fe/core/templating/PropertyHelper.ts +1 -1
  243. package/src/sap/fe/core/templating/UIFormatters.js +45 -110
  244. package/src/sap/fe/core/templating/UIFormatters.ts +39 -75
  245. package/src/sap/fe/core/type/Email.js +1 -1
  246. package/src/sap/fe/core/type/Email.ts +4 -6
  247. package/ui5.yaml +0 -3
  248. package/src/sap/fe/core/controls/filterbar.d.js +0 -8
  249. package/src/sap/fe/core/controls/filterbar.d.ts +0 -0
@@ -1,2381 +1,2075 @@
1
1
  /*!
2
- * SAPUI5
3
- * (c) Copyright 2009-2021 SAP SE. All rights reserved.
2
+ * SAP UI development toolkit for HTML5 (SAPUI5)
3
+ * (c) Copyright 2009-2021 SAP SE. All rights reserved
4
4
  */
5
-
6
- sap.ui.define(
7
- [
8
- "sap/ui/core/mvc/View",
9
- "sap/ui/core/Component",
10
- "sap/m/MessageBox",
11
- "sap/base/Log",
12
- "sap/fe/navigation/SelectionVariant",
13
- "sap/ui/mdc/condition/FilterOperatorUtil",
14
- "sap/ui/mdc/odata/v4/TypeUtil",
15
- "sap/fe/core/helpers/StableIdHelper",
16
- "sap/fe/core/library",
17
- "sap/fe/core/helpers/ModelHelper",
18
- "sap/fe/core/helpers/SemanticDateOperators",
19
- "sap/fe/core/templating/FilterHelper",
20
- "sap/ui/mdc/condition/Condition",
21
- "sap/ui/mdc/enum/ConditionValidated",
22
- "sap/fe/core/converters/MetaModelConverter",
23
- "sap/fe/core/converters/ConverterContext",
24
- "sap/base/util/merge",
25
- "sap/fe/core/helpers/BindingExpression",
26
- "sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler",
27
- "sap/ui/core/XMLTemplateProcessor",
28
- "sap/ui/core/util/XMLPreprocessor",
29
- "sap/ui/core/Fragment"
30
- ],
31
- function(
32
- View,
33
- Component,
34
- MessageBox,
35
- Log,
36
- SelectionVariant,
37
- FilterOperatorUtil,
38
- TypeUtil,
39
- StableIdHelper,
40
- FELibrary,
41
- ModelHelper,
42
- SemanticDateOperators,
43
- FilterHelper,
44
- Condition,
45
- ConditionValidated,
46
- MetaModelConverter,
47
- ConverterContext,
48
- mergeObjects,
49
- BindingExpression,
50
- DataLossOrDraftDiscardHandler,
51
- XMLTemplateProcessor,
52
- XMLPreprocessor,
53
- Fragment
54
- ) {
55
- "use strict";
56
-
57
- var ProgrammingModel = FELibrary.ProgrammingModel;
58
-
59
- var aValidTypes = [
60
- "Edm.Boolean",
61
- "Edm.Byte",
62
- "Edm.Date",
63
- "Edm.DateTime",
64
- "Edm.DateTimeOffset",
65
- "Edm.Decimal",
66
- "Edm.Double",
67
- "Edm.Float",
68
- "Edm.Guid",
69
- "Edm.Int16",
70
- "Edm.Int32",
71
- "Edm.Int64",
72
- "Edm.SByte",
73
- "Edm.Single",
74
- "Edm.String",
75
- "Edm.Time",
76
- "Edm.TimeOfDay"
77
- ];
78
-
79
- /**
80
- * Method to split the search term on spaces and wrap each word in double quotes.
81
- *
82
- * @param {string} sSearchTerm The search term
83
- * @returns {string|undefined} The normalized search term, undefined if empty
84
- */
85
- function normalizeSearchTerm(sSearchTerm) {
86
- if (!sSearchTerm) {
87
- return undefined;
88
- }
89
-
90
- return sSearchTerm
91
- .replace(/"/g, " ")
92
- .split(/\s+/)
93
- .reduce(function(sNormalized, sCurrentWord) {
94
- if (sCurrentWord !== "") {
95
- sNormalized = (sNormalized ? sNormalized + " " : "") + '"' + sCurrentWord + '"';
96
- }
97
- return sNormalized;
98
- }, undefined);
99
- }
100
-
101
- /**
102
- * Returns the actual property type of a given data field or property.
103
- *
104
- * @param {sap.ui.model.Context} oNavigationContext The MetaModel context
105
- * @returns {string} The name of the actual data type
106
- */
107
- function getPropertyDataType(oNavigationContext) {
108
- var sDataType = oNavigationContext.getProperty("$Type");
109
- // if $kind exists, it's not a DataField and we have the final type already
110
- if (!oNavigationContext.getProperty("$kind")) {
111
- switch (sDataType) {
112
- case "com.sap.vocabularies.UI.v1.DataFieldForAction":
113
- case "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation":
114
- sDataType = undefined;
115
- break;
116
-
117
- case "com.sap.vocabularies.UI.v1.DataField":
118
- case "com.sap.vocabularies.UI.v1.DataFieldWithNavigationPath":
119
- case "com.sap.vocabularies.UI.v1.DataFieldWithUrl":
120
- sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
121
- break;
122
-
123
- case "com.sap.vocabularies.UI.v1.DataFieldForAnnotation":
124
- default:
125
- var sAnnotationPath = oNavigationContext.getProperty("Target/$AnnotationPath");
126
- if (sAnnotationPath) {
127
- if (sAnnotationPath.indexOf("com.sap.vocabularies.Communication.v1.Contact") > -1) {
128
- sDataType = oNavigationContext.getProperty("Target/$AnnotationPath/fn/$Path/$Type");
129
- } else if (sAnnotationPath.indexOf("com.sap.vocabularies.UI.v1.DataPoint") > -1) {
130
- sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
131
- } else {
132
- // e.g. FieldGroup or Chart
133
- sDataType = undefined;
134
- }
135
- } else {
136
- sDataType = undefined;
137
- }
138
- break;
139
- }
140
- }
141
-
142
- return sDataType;
143
- }
144
-
145
- function fnHasTransientContexts(oListBinding) {
146
- var bHasTransientContexts = false;
147
- if (oListBinding) {
148
- oListBinding.getCurrentContexts().forEach(function(oContext) {
149
- if (oContext && oContext.isTransient()) {
150
- bHasTransientContexts = true;
151
- }
152
- });
153
- }
154
- return bHasTransientContexts;
155
- }
156
-
157
- function getSearchRestrictions(sFullPath, oMetaModel) {
158
- var i = 0,
159
- aNavigationParts = sFullPath.split("/$NavigationPropertyBinding/");
160
- for (var sPath = aNavigationParts[0]; i < aNavigationParts.length - 1; i++) {
161
- var oNavigationRestrictions = getNavigationRestrictions(oMetaModel, sPath, aNavigationParts[i + 1]);
162
- if (oNavigationRestrictions && oNavigationRestrictions["SearchRestrictions"]) {
163
- return oNavigationRestrictions["SearchRestrictions"];
164
- }
165
- sPath = sPath + "/$NavigationPropertyBinding/" + aNavigationParts[i];
166
- }
167
- return oMetaModel.getObject(sFullPath + "@Org.OData.Capabilities.V1.SearchRestrictions");
168
- }
169
-
170
- function getNavigationRestrictions(oModel, sEntitySetPath, sNavigationPath) {
171
- var oNavigationRestrictions = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.NavigationRestrictions");
172
- var aRestrictedProperties = oNavigationRestrictions && oNavigationRestrictions.RestrictedProperties;
173
- return (
174
- aRestrictedProperties &&
175
- aRestrictedProperties.find(function(oRestrictedProperty) {
176
- return (
177
- oRestrictedProperty &&
178
- oRestrictedProperty.NavigationProperty &&
179
- oRestrictedProperty.NavigationProperty.$NavigationPropertyPath === sNavigationPath
180
- );
181
- })
182
- );
183
- }
184
-
185
- function _isInNonFilterableProperties(oModel, sEntitySetPath, sContextPath) {
186
- var bIsNotFilterable = false;
187
- var oAnnotation = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions");
188
- if (oAnnotation && oAnnotation.NonFilterableProperties) {
189
- bIsNotFilterable = oAnnotation.NonFilterableProperties.some(function(property) {
190
- return property.$NavigationPropertyPath === sContextPath || property.$PropertyPath === sContextPath;
191
- });
192
- }
193
- return bIsNotFilterable;
194
- }
195
-
196
- // TODO rework this!
197
- function _isContextPathFilterable(oModel, sEntitySetPath, sContexPath) {
198
- var sFullPath = sEntitySetPath + "/" + sContexPath,
199
- aESParts = sFullPath.split("/").splice(0, 2),
200
- aContext = sFullPath.split("/").splice(2),
201
- bIsNotFilterable = false,
202
- sContext = "";
203
-
204
- sEntitySetPath = aESParts.join("/");
205
-
206
- bIsNotFilterable = aContext.some(function(item, index, array) {
207
- if (sContext.length > 0) {
208
- sContext += "/" + item;
209
- } else {
210
- sContext = item;
211
- }
212
- if (index === array.length - 2) {
213
- // In case of "/Customer/Set/Property" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
214
- var oNavigationRestrictions = getNavigationRestrictions(oModel, sEntitySetPath, item);
215
- var oFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions.FilterRestrictions;
216
- var aNonFilterableProperties = oFilterRestrictions && oFilterRestrictions.NonFilterableProperties;
217
- var sTargetPropertyPath = array[array.length - 1];
218
- if (
219
- aNonFilterableProperties &&
220
- aNonFilterableProperties.find(function(oPropertyPath) {
221
- return oPropertyPath.$PropertyPath === sTargetPropertyPath;
222
- })
223
- ) {
224
- return true;
225
- }
226
- }
227
- if (index === array.length - 1) {
228
- //last path segment
229
- bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
230
- } else if (oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item)) {
231
- //check existing context path and initialize it
232
- bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
233
- sContext = "";
234
- //set the new EntitySet
235
- sEntitySetPath = "/" + oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item);
236
- }
237
- return bIsNotFilterable === true;
238
- });
239
- return bIsNotFilterable;
240
- }
241
-
242
- // TODO check used places and rework this
243
- /**
244
- * Checks if the property is filterable.
245
- *
246
- * @param {object} oModel MetaModel
247
- * @param {string} sEntitySetPath EntitySet Path
248
- * @param {string} sProperty Entityset's Property
249
- * @param {boolean} bSkipHiddenFilter If HiddenFilters annotation check needs to be skipped
250
- * @returns {boolean} `true`, if the property is filterable
251
- *
252
- */
253
- function isPropertyFilterable(oModel, sEntitySetPath, sProperty, bSkipHiddenFilter) {
254
- if (typeof sProperty !== "string") {
255
- throw new Error("sProperty parameter must be a string", sProperty);
256
- }
257
- var bIsFilterable;
258
-
259
- // Parameters should be rendered as filterfields
260
- if (oModel.getProperty(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
261
- return true;
262
- }
263
-
264
- var oNavigationContext = oModel.createBindingContext(sEntitySetPath + "/" + sProperty);
265
-
266
- if (oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.Hidden") === true) {
267
- return false;
268
- }
269
-
270
- if (!bSkipHiddenFilter && oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.HiddenFilter")) {
271
- return false;
272
- }
273
-
274
- if (sEntitySetPath.split("/").length === 2 && sProperty.indexOf("/") < 0) {
275
- // there is no navigation in entitySet path and property path
276
- bIsFilterable = !_isInNonFilterableProperties(oModel, sEntitySetPath, sProperty);
277
- } else {
278
- bIsFilterable = !_isContextPathFilterable(oModel, sEntitySetPath, sProperty);
279
- }
280
- // check if type can be used for filtering
281
- if (bIsFilterable && oNavigationContext) {
282
- var sPropertyDataType = getPropertyDataType(oNavigationContext);
283
- if (sPropertyDataType) {
284
- bIsFilterable = aValidTypes.indexOf(sPropertyDataType) !== -1;
285
- } else {
286
- bIsFilterable = false;
287
- }
288
- }
289
-
290
- return bIsFilterable;
291
- }
292
-
293
- function getShellServices(oControl) {
294
- return getAppComponent(oControl).getShellServices();
295
- }
296
-
297
- function _getSOIntents(oObjectPageLayout, oSemanticObject, oParam) {
298
- var oShellServiceHelper = CommonUtils.getShellServices(oObjectPageLayout);
299
- return oShellServiceHelper.getLinks({
300
- semanticObject: oSemanticObject,
301
- params: oParam
302
- });
303
- }
304
-
305
- // TO-DO add this as part of applySemanticObjectmappings logic in IntentBasednavigation controller extension
306
- function _createMappings(oMapping) {
307
- var aSOMappings = [];
308
- var aMappingKeys = Object.keys(oMapping);
309
- for (var i = 0; i < aMappingKeys.length; i++) {
310
- var oSemanticMapping = {
311
- "LocalProperty": {
312
- "$PropertyPath": aMappingKeys[i]
313
- },
314
- "SemanticObjectProperty": oMapping[aMappingKeys[i]]
315
- };
316
- aSOMappings.push(oSemanticMapping);
317
- }
318
-
319
- return aSOMappings;
320
- }
321
-
322
- function _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aItems) {
323
- for (var i = 0; i < aLinks.length; i++) {
324
- var oLink = aLinks[i];
325
- var sIntent = oLink.intent;
326
- var sAction = sIntent.split("-")[1].split("?")[0];
327
- if (aExcludedActions && aExcludedActions.indexOf(sAction) === -1) {
328
- aItems.push({
329
- text: oLink.text,
330
- targetSemObject: sIntent.split("#")[1].split("-")[0],
331
- targetAction: sAction.split("~")[0],
332
- targetParams: oTargetParams
333
- });
334
- }
335
- }
336
- }
337
-
338
- function _getRelatedIntents(oAdditionalSemanticObjects, oBindingContext, aManifestSOItems, aLinks) {
339
- if (aLinks && aLinks.length > 0) {
340
- var aExcludedActions = oAdditionalSemanticObjects.unavailableActions ? oAdditionalSemanticObjects.unavailableActions : [];
341
- var aSOMappings = oAdditionalSemanticObjects.mapping ? _createMappings(oAdditionalSemanticObjects.mapping) : [];
342
- var oTargetParams = { navigationContexts: oBindingContext, semanticObjectMapping: aSOMappings };
343
- _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aManifestSOItems);
344
- }
345
- }
346
-
347
- function updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath) {
348
- var oShellServiceHelper = getShellServices(oObjectPageLayout),
349
- oParam = {},
350
- sCurrentSemObj = "",
351
- sCurrentAction = "";
352
- var oSemanticObjectAnnotations;
353
- var aRelatedAppsMenuItems = [];
354
- var aExcludedActions = [];
355
-
356
- if (oEntry) {
357
- if (aSemKeys && aSemKeys.length > 0) {
358
- for (var j = 0; j < aSemKeys.length; j++) {
359
- var sSemKey = aSemKeys[j].$PropertyPath;
360
- if (!oParam[sSemKey]) {
361
- oParam[sSemKey] = { value: oEntry[sSemKey] };
362
- }
363
- }
364
- } else {
365
- // fallback to Technical Keys if no Semantic Key is present
366
- var aTechnicalKeys = oMetaModel.getObject(oMetaPath + "/$Type/$Key");
367
- for (var key in aTechnicalKeys) {
368
- var sObjKey = aTechnicalKeys[key];
369
- if (!oParam[sObjKey]) {
370
- oParam[sObjKey] = { value: oEntry[sObjKey] };
371
- }
372
- }
373
- }
374
- }
375
- // Logic to read additional SO from manifest and updated relatedapps model
376
-
377
- var oManifestData = getTargetView(oObjectPageLayout).getViewData();
378
- var aManifestSOItems = [];
379
- if (oManifestData.additionalSemanticObjects) {
380
- var aManifestSOKeys = Object.keys(oManifestData.additionalSemanticObjects);
381
- for (var key = 0; key < aManifestSOKeys.length; key++) {
382
- _getSOIntents(oObjectPageLayout, aManifestSOKeys[key], oParam)
383
- .then(
384
- _getRelatedIntents.bind(
385
- this,
386
- oManifestData.additionalSemanticObjects[aManifestSOKeys[key]],
387
- oBindingContext,
388
- aManifestSOItems
389
- )
390
- )
391
- .catch(function(oError) {
392
- Log.error("Error while retrieving SO Intents", oError);
393
- });
394
- }
395
- }
396
-
397
- function fnGetParseShellHashAndGetLinks() {
398
- var oParsedUrl = oShellServiceHelper.parseShellHash(document.location.hash);
399
- sCurrentSemObj = oParsedUrl.semanticObject; // Current Semantic Object
400
- sCurrentAction = oParsedUrl.action;
401
- return _getSOIntents(oObjectPageLayout, sCurrentSemObj, oParam);
402
- }
403
-
404
- fnGetParseShellHashAndGetLinks()
405
- .then(function(aLinks) {
406
- if (aLinks && aLinks.length > 0) {
407
- var oTargetParams = {};
408
- var aAnnotationsSOItems = [];
409
- var sEntitySetPath = oMetaPath + "@";
410
- var sEntityTypePath = oMetaPath + "/@";
411
- var oEntitySetAnnotations = oMetaModel.getObject(sEntitySetPath);
412
- oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntitySetAnnotations, sCurrentSemObj);
413
- if (!oSemanticObjectAnnotations.bHasEntitySetSO) {
414
- var oEntityTypeAnnotations = oMetaModel.getObject(sEntityTypePath);
415
- oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntityTypeAnnotations, sCurrentSemObj);
416
- }
417
- aExcludedActions = oSemanticObjectAnnotations.aUnavailableActions;
418
- //Skip same application from Related Apps
419
- aExcludedActions.push(sCurrentAction);
420
- oTargetParams.navigationContexts = oBindingContext;
421
- oTargetParams.semanticObjectMapping = oSemanticObjectAnnotations.aMappings;
422
- _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aAnnotationsSOItems);
423
- aRelatedAppsMenuItems = aAnnotationsSOItems.concat(aManifestSOItems);
424
- // If no app in list, related apps button will be hidden
425
- oObjectPageLayout
426
- .getBindingContext("internal")
427
- .setProperty("relatedApps/visibility", aRelatedAppsMenuItems.length > 0);
428
- oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/items", aRelatedAppsMenuItems);
429
- } else {
430
- oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/visibility", false);
431
- }
432
- })
433
- .catch(function(oError) {
434
- Log.error("Cannot read links", oError);
435
- });
436
- return aRelatedAppsMenuItems;
437
- }
438
-
439
- /**
440
- * @param {object} oEntityAnnotations Annotations at the EntitySet/EntityType level
441
- * @param sCurrentSemObj
442
- * @returns {object} Object containing one array of all semantic object mappings and another containing all SO unavailable actions
443
- */
444
- function _getSemanticObjectAnnotations(oEntityAnnotations, sCurrentSemObj) {
445
- var oSemanticObjectAnnotations = {
446
- bHasEntitySetSO: false,
447
- aUnavailableActions: [],
448
- aMappings: []
449
- };
450
- var sAnnotationMappingTerm, sAnnotationActionTerm;
451
- var sQualifier;
452
- for (var key in oEntityAnnotations) {
453
- if (key.indexOf("com.sap.vocabularies.Common.v1.SemanticObject") > -1 && oEntityAnnotations[key] === sCurrentSemObj) {
454
- oSemanticObjectAnnotations.bHasEntitySetSO = true;
455
- sAnnotationMappingTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectMapping";
456
- sAnnotationActionTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions";
457
-
458
- if (key.indexOf("#") > -1) {
459
- sQualifier = key.split("#")[1];
460
- sAnnotationMappingTerm = sAnnotationMappingTerm + "#" + sQualifier;
461
- sAnnotationActionTerm = sAnnotationActionTerm + "#" + sQualifier;
462
- }
463
-
464
- oSemanticObjectAnnotations.aMappings = oSemanticObjectAnnotations.aMappings.concat(
465
- oEntityAnnotations[sAnnotationMappingTerm]
466
- );
467
- oSemanticObjectAnnotations.aUnavailableActions = oSemanticObjectAnnotations.aUnavailableActions.concat(
468
- oEntityAnnotations[sAnnotationActionTerm]
469
- );
470
-
471
- break;
472
- }
473
- }
474
- return oSemanticObjectAnnotations;
475
- }
476
-
477
- function fnUpdateRelatedAppsDetails(oObjectPageLayout) {
478
- var oMetaModel = oObjectPageLayout.getModel().getMetaModel();
479
- var oBindingContext = oObjectPageLayout.getBindingContext();
480
- var oPath = oBindingContext && oBindingContext.getPath();
481
- var oMetaPath = oMetaModel.getMetaPath(oPath);
482
- // Semantic Key Vocabulary
483
- var sSemanticKeyVocabulary = oMetaPath + "/" + "@com.sap.vocabularies.Common.v1.SemanticKey";
484
- //Semantic Keys
485
- var aSemKeys = oMetaModel.getObject(sSemanticKeyVocabulary);
486
- // Unavailable Actions
487
- var oEntry = oBindingContext.getObject();
488
- if (!oEntry) {
489
- oBindingContext
490
- .requestObject()
491
- .then(function(oEntry) {
492
- return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
493
- })
494
- .catch(function(oError) {
495
- Log.error("Cannot update the related app details", oError);
496
- });
497
- } else {
498
- return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
499
- }
500
- }
501
-
502
- /**
503
- * Fire Press on a Button.
504
- * Test if oButton is an enabled and visible sap.m.Button before triggering a press event.
505
- *
506
- * @param {sap.m.Button | sap.m.OverflowToolbarButton} oButton A SAP UI5 Button
507
- */
508
- function fnFireButtonPress(oButton) {
509
- var aAuthorizedTypes = ["sap.m.Button", "sap.m.OverflowToolbarButton"];
510
- if (
511
- oButton &&
512
- aAuthorizedTypes.indexOf(oButton.getMetadata().getName()) !== -1 &&
513
- oButton.getVisible() &&
514
- oButton.getEnabled()
515
- ) {
516
- oButton.firePress();
517
- }
518
- }
519
-
520
- function fnResolveStringtoBoolean(sValue) {
521
- if (sValue === "true" || sValue === true) {
522
- return true;
523
- } else {
524
- return false;
525
- }
526
- }
527
-
528
- /**
529
- * Retrieves the main component associated with a given control / view.
530
- *
531
- * @param {sap.ui.base.ManagedObject} oControl A managed object
532
- * @returns {sap.fe.core.AppComponent} The SAP Fiori Element AppComponent
533
- */
534
- function getAppComponent(oControl) {
535
- if (oControl.isA("sap.fe.core.AppComponent")) {
536
- return oControl;
537
- }
538
- var oOwner = Component.getOwnerComponentFor(oControl);
539
- if (!oOwner) {
540
- return oControl;
541
- } else {
542
- return getAppComponent(oOwner);
543
- }
544
- }
545
-
546
- /**
547
- * Returns the containing view for the current control.
548
- * In case the provided control is a {@link sap.ui.core.ComponentContainer},
549
- * the root control of the contained component is used as a starting point,
550
- * which might be the returned view itself.
551
- *
552
- * @param {sap.ui.base.ManagedObject} oControl The control to get the view for
553
- * @returns {sap.ui.mvc.View} The view containing the given control
554
- */
555
- function getTargetView(oControl) {
556
- if (oControl && oControl.isA("sap.ui.core.ComponentContainer")) {
557
- oControl = oControl.getComponentInstance();
558
- oControl = oControl && oControl.getRootControl();
559
- }
560
- while (oControl && !(oControl instanceof View)) {
561
- oControl = oControl.getParent();
562
- }
563
- return oControl;
564
- }
565
-
566
- function fnProcessDataLossOrDraftDiscardConfirmation(
567
- fnProcessFunction,
568
- fnCancelFunction,
569
- oContext,
570
- oController,
571
- bSkipBindingToView
572
- ) {
573
- var oModel = oContext.getModel();
574
- var _bIsModified = false;
575
- var draftDataContext = oModel.bindContext(oContext.getPath() + "/DraftAdministrativeData").getBoundContext();
576
- if (
577
- oContext &&
578
- oContext.getObject() &&
579
- (!oContext.getObject().DraftAdministrativeData || oContext.getObject().IsActiveEntity === true)
580
- ) {
581
- fnProcessFunction();
582
- } else {
583
- draftDataContext
584
- .requestObject()
585
- .then(function(draftAdminData) {
586
- if (draftAdminData) {
587
- _bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
588
- if (_bIsModified) {
589
- DataLossOrDraftDiscardHandler.performAfterDiscardorKeepDraft(
590
- fnProcessFunction,
591
- fnCancelFunction,
592
- oController,
593
- bSkipBindingToView
594
- );
595
- } else {
596
- fnProcessFunction();
597
- }
598
- } else {
599
- fnProcessFunction();
600
- }
601
- })
602
- .catch(function(oError) {
603
- Log.error("Cannot retrieve draftDataContext information", oError);
604
- });
605
- }
606
- }
607
-
608
- /**
609
- * FE MessageBox to confirm in case data loss warning is to be given.
610
- *
611
- * @param {Function} fnProcess Task to be performed if user confirms.
612
- * @param {sap.ui.core.Control} oControl Control responsible for the the trigger of the dialog
613
- * @param {string} programmingModel Type of transaction model
614
- * @param oController
615
- * @returns {object} MessageBox if confirmation is required else the fnProcess function.
616
- */
617
- function fnProcessDataLossConfirmation(fnProcess, oControl, programmingModel, oController) {
618
- var bUIEditable = oControl.getModel("ui").getProperty("/isEditable"),
619
- oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.templates"),
620
- sWarningMsg = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_MSG"),
621
- sConfirmButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CONFIRM_BUTTON"),
622
- sCancelButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CANCEL_BUTTON");
623
-
624
- if (programmingModel === ProgrammingModel.Sticky && bUIEditable) {
625
- return MessageBox.warning(sWarningMsg, {
626
- actions: [sConfirmButtonTxt, sCancelButtonTxt],
627
- onClose: function(sAction) {
628
- if (sAction === sConfirmButtonTxt) {
629
- var oInternalModel = oControl && oControl.getModel("internal");
630
-
631
- Log.info("Navigation confirmed.");
632
- if (oInternalModel) {
633
- oInternalModel.setProperty("/sessionOn", false);
634
- } else {
635
- Log.warning("Local UIModel couldn't be found.");
636
- }
637
- fnProcess();
638
- } else {
639
- Log.info("Navigation rejected.");
640
- }
641
- }
642
- });
643
- }
644
- return fnProcess();
645
- }
646
-
647
- /**
648
- * Check if Path based FieldControl Evaluates to inapplicable.
649
- *
650
- * @param {string} sFieldControlPath Field control path
651
- * @param {object} oAttribute SemanticAttributes
652
- * @returns {boolean} `true` if inapplicable
653
- *
654
- */
655
- function isFieldControlPathInapplicable(sFieldControlPath, oAttribute) {
656
- var bInapplicable = false,
657
- aParts = sFieldControlPath.split("/");
658
- // sensitive data is removed only if the path has already been resolved.
659
- if (aParts.length > 1) {
660
- bInapplicable =
661
- oAttribute[aParts[0]] && oAttribute[aParts[0]].hasOwnProperty(aParts[1]) && oAttribute[aParts[0]][aParts[1]] === 0;
662
- } else {
663
- bInapplicable = oAttribute[sFieldControlPath] === 0;
664
- }
665
- return bInapplicable;
666
- }
667
-
668
- /**
669
- * Removes sensitive data from the semantic attribute with respect to entitySet.
670
- *
671
- * @param {Array} aAttributes Array of 'semantic Attributes' - context Data
672
- * @param {boolean} oMetaModel V4 MetaModel for anntations
673
- * @returns {Array} Array of semantic Attributes
674
- **/
675
-
676
- function removeSensitiveData(aAttributes, oMetaModel) {
677
- var aOutAttributes = [];
678
- for (var i = 0; i < aAttributes.length; i++) {
679
- var sEntitySet = aAttributes[i].entitySet,
680
- oAttribute = aAttributes[i].contextData,
681
- aProperties;
682
-
683
- delete oAttribute["@odata.context"];
684
- delete oAttribute["%40odata.context"];
685
- delete oAttribute["@odata.metadataEtag"];
686
- delete oAttribute["%40odata.metadataEtag"];
687
- delete oAttribute["SAP__Messages"];
688
- aProperties = Object.keys(oAttribute);
689
- for (var j = 0; j < aProperties.length; j++) {
690
- var sProp = aProperties[j],
691
- aPropertyAnnotations = oMetaModel.getObject("/" + sEntitySet + "/" + sProp + "@");
692
- if (aPropertyAnnotations) {
693
- if (
694
- aPropertyAnnotations["@com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive"] ||
695
- aPropertyAnnotations["@com.sap.vocabularies.UI.v1.ExcludeFromNavigationContext"] ||
696
- aPropertyAnnotations["@com.sap.vocabularies.Analytics.v1.Measure"]
697
- ) {
698
- delete oAttribute[sProp];
699
- } else if (aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"]) {
700
- var oFieldControl = aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"];
701
- if (oFieldControl["$EnumMember"] && oFieldControl["$EnumMember"].split("/")[1] === "Inapplicable") {
702
- delete oAttribute[sProp];
703
- } else if (
704
- oFieldControl["$Path"] &&
705
- CommonUtils.isFieldControlPathInapplicable(oFieldControl["$Path"], oAttribute)
706
- ) {
707
- delete oAttribute[sProp];
708
- }
709
- }
710
- }
711
- }
712
- aOutAttributes.push(oAttribute);
713
- }
714
-
715
- return aOutAttributes;
716
- }
717
-
718
- function _fnCheckIsMatch(oObject, oKeysToCheck) {
719
- for (var sKey in oKeysToCheck) {
720
- if (oKeysToCheck[sKey] !== oObject[sKey]) {
721
- return false;
722
- }
723
- }
724
- return true;
725
- }
726
-
727
- /**
728
- * Method to get metadata of entityset properties.
729
- *
730
- * @param {object} oMetaModel MetaModel for annotations
731
- * @param {string} sContextPath ContextPath for properities
732
- * @param {object} oFilter Filter for the properties
733
- * @returns {object} The entity type properties
734
- */
735
- function fnGetContextPathProperties(oMetaModel, sContextPath, oFilter) {
736
- var oEntityType = oMetaModel.getObject(sContextPath + "/") || {},
737
- oProperties = {};
738
-
739
- for (var sKey in oEntityType) {
740
- if (
741
- oEntityType.hasOwnProperty(sKey) &&
742
- !/^\$/i.test(sKey) &&
743
- oEntityType[sKey].$kind &&
744
- _fnCheckIsMatch(oEntityType[sKey], oFilter || { $kind: "Property" })
745
- ) {
746
- oProperties[sKey] = oEntityType[sKey];
747
- }
748
- }
749
- return oProperties;
750
- }
751
-
752
- /**
753
- * Method to get madatory filterfields.
754
- *
755
- * @param {object} oMetaModel MetaModel for annotations
756
- * @param {string} sContextPath ContextPath for properities
757
- * @returns {object[]} The mandatory filter fields
758
- */
759
- function fnGetMandatoryFilterFields(oMetaModel, sContextPath) {
760
- var aMandatoryFilterFields;
761
- if (oMetaModel && sContextPath) {
762
- aMandatoryFilterFields = oMetaModel.getObject(
763
- sContextPath + "@Org.OData.Capabilities.V1.FilterRestrictions/RequiredProperties"
764
- );
765
- }
766
- return aMandatoryFilterFields;
767
- }
768
-
769
- /**
770
- * Method to get madatory filterfields
771
- *
772
- * @param {object} oControl Control containing IBN Actions
773
- * @param {Array} aIBNActions array filled with IBN Actions
774
- * @returns {Array} array containing the IBN Actions
775
- *
776
- */
777
-
778
- function fnGetIBNActions(oControl, aIBNActions) {
779
- var aActions = oControl && oControl.getActions();
780
- if (aActions) {
781
- aActions.forEach(function(oAction) {
782
- if (oAction.isA("sap.ui.mdc.actiontoolbar.ActionToolbarAction")) {
783
- oAction = oAction.getAction();
784
- }
785
- if (oAction.data("IBNData")) {
786
- aIBNActions.push(oAction);
787
- }
788
- });
789
- }
790
- return aIBNActions;
791
- }
792
-
793
- /**
794
- * Method to update the IBN Buttons Visibility.
795
- *
796
- * @param {Array} aIBNActions Array containing all the IBN Actions with requires context false
797
- * @param {object} oView Instance of the view
798
- */
799
- function fnUpdateDataFieldForIBNButtonsVisibility(aIBNActions, oView) {
800
- var that = this;
801
- var oParams = {};
802
- var fnGetLinks = function(oData) {
803
- if (oData) {
804
- var aKeys = Object.keys(oData);
805
- aKeys.map(function(sKey) {
806
- if (sKey.indexOf("_") !== 0 && sKey.indexOf("odata.context") === -1) {
807
- oParams[sKey] = { value: oData[sKey] };
808
- }
809
- });
810
- }
811
- if (aIBNActions.length) {
812
- aIBNActions.forEach(function(oIBNAction) {
813
- var sSemanticObject = oIBNAction.data("IBNData").semanticObject;
814
- var sAction = oIBNAction.data("IBNData").action;
815
- that.getShellServices(oView)
816
- .getLinks({
817
- semanticObject: sSemanticObject,
818
- action: sAction,
819
- params: oParams
820
- })
821
- .then(function(aLink) {
822
- oIBNAction.setVisible(oIBNAction.getVisible() && aLink && aLink.length === 1);
823
- })
824
- .catch(function(oError) {
825
- Log.error("Cannot retrieve the links from the shell service", oError);
826
- });
827
- });
828
- }
829
- };
830
- if (oView && oView.getBindingContext()) {
831
- oView
832
- .getBindingContext()
833
- .requestObject()
834
- .then(function(oData) {
835
- return fnGetLinks(oData);
836
- })
837
- .catch(function(oError) {
838
- Log.error("Cannot retrieve the links from the shell service", oError);
839
- });
840
- } else {
841
- fnGetLinks();
842
- }
843
- }
844
-
845
- /**
846
- * Creates the updated key to check the i18n override and fallbacks to the old value if the new value is not available for the same key.
847
- *
848
- * @param {string} sFrameworkKey Current key.
849
- * @param {object} oResourceBundle Contains the local resource bundle
850
- * @param {object} [oParams] Parameter object for the resource value
851
- * @param {string} [sEntitySetName] EntitySet name of the control where the resource is being used
852
- * @returns {string} The translated text
853
- */
854
- function getTranslatedText(sFrameworkKey, oResourceBundle, oParams, sEntitySetName) {
855
- var sResourceKey = sFrameworkKey;
856
- if (oResourceBundle) {
857
- if (sEntitySetName) {
858
- // There are console errors logged when making calls to getText for keys that are not defined in the resource bundle
859
- // for instance keys which are supposed to be provided by the application, e.g, <key>|<entitySet> to override instance specific text
860
- // hence check if text exists (using "hasText") in the resource bundle before calling "getText"
861
-
862
- // "hasText" only checks for the key in the immediate resource bundle and not it's custom bundles
863
- // hence we need to do this recurrsively to check if the key exists in any of the bundles the forms the FE resource bundle
864
- var bResourceKeyExists = _checkIfResourceKeyExists(
865
- oResourceBundle.aCustomBundles,
866
- sFrameworkKey + "|" + sEntitySetName
867
- );
868
-
869
- // if resource key with entity set name for instance specific text overriding is provided by the application
870
- // then use the same key otherwise use the Framework key
871
- sResourceKey = bResourceKeyExists ? sFrameworkKey + "|" + sEntitySetName : sFrameworkKey;
872
- }
873
- return oResourceBundle.getText(sResourceKey, oParams);
874
- }
875
-
876
- // do not allow override so get text from the internal bundle directly
877
- oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
878
- return oResourceBundle.getText(sResourceKey, oParams);
879
- }
880
-
881
- function _checkIfResourceKeyExists(aCustomBundles, sKey) {
882
- if (aCustomBundles.length) {
883
- for (var i = aCustomBundles.length - 1; i >= 0; i--) {
884
- var sValue = aCustomBundles[i].hasText(sKey);
885
- // text found return true
886
- if (sValue) {
887
- return true;
888
- }
889
- _checkIfResourceKeyExists(aCustomBundles[i].aCustomBundles, sKey);
890
- }
891
- }
892
- return false;
893
- }
894
-
895
- /**
896
- * Returns the metamodel path correctly for bound actions if used with bReturnOnlyPath as true,
897
- * else returns an object which has 3 properties related to the action. They are the entity set name,
898
- * the $Path value of the OperationAvailable annotation and the binding parameter name. If
899
- * bCheckStaticValue is true, returns the static value of OperationAvailable annotation, if present.
900
- * e.g. for bound action someNameSpace.SomeBoundAction
901
- * of entity set SomeEntitySet, the string "/SomeEntitySet/someNameSpace.SomeBoundAction" is returned.
902
- *
903
- * @param {oAction} oAction Context object of the action
904
- * @param {boolean} bReturnOnlyPath If false, additional info is returned along with metamodel path to the bound action
905
- * @param {string} sActionName Name of the bound action of the form someNameSpace.SomeBoundAction
906
- * @param {boolean} bCheckStaticValue If true, the static value of OperationAvailable is returned, if present
907
- * @returns {string|object} String or object as specified by bReturnOnlyPath
908
- * @private
909
- * @ui5-restricted
910
- */
911
- function getActionPath(oAction, bReturnOnlyPath, sActionName, bCheckStaticValue) {
912
- sActionName = !sActionName ? oAction.getObject(oAction.getPath()) : sActionName;
913
- var sContextPath = oAction.getPath().split("/@")[0];
914
- var sEntityTypeName = oAction.getObject(sContextPath).$Type;
915
- var sEntityName = getEntitySetName(oAction.getModel(), sEntityTypeName);
916
- if (sEntityName) {
917
- sContextPath = "/" + sEntityName;
918
- }
919
- if (bCheckStaticValue) {
920
- return oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable");
921
- }
922
- if (bReturnOnlyPath) {
923
- return sContextPath + "/" + sActionName;
924
- } else {
925
- return {
926
- sContextPath: sContextPath,
927
- sProperty: oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable/$Path"),
928
- sBindingParameter: oAction.getObject(sContextPath + "/" + sActionName + "/@$ui5.overload/0/$Parameter/0/$Name")
929
- };
930
- }
931
- }
932
-
933
- function getEntitySetName(oMetaModel, sEntityType) {
934
- var oEntityContainer = oMetaModel.getObject("/");
935
- for (var key in oEntityContainer) {
936
- if (typeof oEntityContainer[key] === "object" && oEntityContainer[key].$Type === sEntityType) {
937
- return key;
938
- }
939
- }
940
- }
941
-
942
- function computeDisplayMode(oPropertyAnnotations, oCollectionAnnotations) {
943
- var oTextAnnotation = oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text"],
944
- oTextArrangementAnnotation =
945
- oTextAnnotation &&
946
- ((oPropertyAnnotations &&
947
- oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text@com.sap.vocabularies.UI.v1.TextArrangement"]) ||
948
- (oCollectionAnnotations && oCollectionAnnotations["@com.sap.vocabularies.UI.v1.TextArrangement"]));
949
-
950
- if (oTextArrangementAnnotation) {
951
- if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextOnly") {
952
- return "Description";
953
- } else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextLast") {
954
- return "ValueDescription";
955
- } else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextSeparate") {
956
- return "Value";
957
- }
958
- //Default should be TextFirst if there is a Text annotation and neither TextOnly nor TextLast are set
959
- return "DescriptionValue";
960
- }
961
- return oTextAnnotation ? "DescriptionValue" : "Value";
962
- }
963
-
964
- function _getEntityType(oContext) {
965
- var oMetaModel = oContext.getModel().getMetaModel();
966
- return oMetaModel.getObject(oMetaModel.getMetaPath(oContext.getPath()) + "/$Type");
967
- }
968
-
969
- function _requestObject(sAction, oSelectedContext, sProperty) {
970
- var oContext = oSelectedContext,
971
- nBracketIndex = sAction.indexOf("(");
972
-
973
- if (nBracketIndex > -1) {
974
- var sTargetType = sAction.slice(nBracketIndex + 1, -1),
975
- sCurrentType = _getEntityType(oContext);
976
-
977
- while (sCurrentType !== sTargetType) {
978
- // Find parent binding context and retrieve entity type
979
- oContext = oContext.getBinding().getContext();
980
- if (oContext) {
981
- sCurrentType = _getEntityType(oContext);
982
- } else {
983
- Log.warn("Cannot determine target type to request property value for bound action invocation");
984
- return Promise.resolve(undefined);
985
- }
986
- }
987
- }
988
-
989
- return oContext.requestObject(sProperty);
990
- }
991
-
992
- function _requestProperty(oSelectedContext, sAction, sProperty, sDynamicActionEnabledPath) {
993
- var oPromise =
994
- sProperty && sProperty.indexOf("/") === 0
995
- ? requestSingletonProperty(sProperty, oSelectedContext.getModel())
996
- : _requestObject(sAction, oSelectedContext, sProperty);
997
-
998
- return oPromise.then(function(vPropertyValue) {
999
- return Promise.resolve({
1000
- vPropertyValue: vPropertyValue,
1001
- oSelectedContext: oSelectedContext,
1002
- sAction: sAction,
1003
- sDynamicActionEnabledPath: sDynamicActionEnabledPath
1004
- });
1005
- });
1006
- }
1007
-
1008
- function _setContextsBasedOnOperationAvailable(oInternalModelContext, aRequestPromises) {
1009
- return Promise.all(aRequestPromises)
1010
- .then(function(aResults) {
1011
- if (aResults.length) {
1012
- var aApplicableContexts = [],
1013
- aNotApplicableContexts = [];
1014
- aResults.forEach(function(aResult) {
1015
- if (aResult) {
1016
- if (aResult.vPropertyValue) {
1017
- oInternalModelContext.getModel().setProperty(aResult.sDynamicActionEnabledPath, true);
1018
- aApplicableContexts.push(aResult.oSelectedContext);
1019
- } else {
1020
- aNotApplicableContexts.push(aResult.oSelectedContext);
1021
- }
1022
- }
1023
- });
1024
- _setDynamicActionContexts(oInternalModelContext, aResults[0].sAction, aApplicableContexts, aNotApplicableContexts);
1025
- }
1026
- })
1027
- .catch(function(oError) {
1028
- Log.trace("Cannot retrieve property value from path", oError);
1029
- });
1030
- }
1031
-
1032
- function _setDynamicActionContexts(oInternalModelContext, sAction, aApplicable, aNotApplicable) {
1033
- var sDynamicActionPathPrefix = oInternalModelContext.getPath() + "/dynamicActions/" + sAction,
1034
- oInternalModel = oInternalModelContext.getModel();
1035
- oInternalModel.setProperty(sDynamicActionPathPrefix + "/aApplicable", aApplicable);
1036
- oInternalModel.setProperty(sDynamicActionPathPrefix + "/aNotApplicable", aNotApplicable);
1037
- }
1038
-
1039
- /**
1040
- * Sets the 'enabled' property along with the applicable selected contexts of dynamic actions.
1041
- *
1042
- * @param oInternalModelContext The instance of the internal model context
1043
- * @param oActionOperationAvailableMap The collection of action names and properties configured as Core.OperationAvailable paths
1044
- * @param aSelectedContexts The array of selected contexts in the table
1045
- * @returns {Promise} A promise that sets the 'enabled' property for all dynamic actions
1046
- */
1047
- function setActionEnablement(oInternalModelContext, oActionOperationAvailableMap, aSelectedContexts) {
1048
- var aPromises = [];
1049
- for (var sAction in oActionOperationAvailableMap) {
1050
- // Reset all properties before computation
1051
- oInternalModelContext.setProperty("dynamicActions/" + sAction, {
1052
- bEnabled: false,
1053
- aApplicable: [],
1054
- aNotApplicable: []
1055
- });
1056
- // Note that non dynamic actions are not processed here. They are enabled because
1057
- // one or more are selected and the second part of the condition in the templating
1058
- // is then undefined and thus the button takes the default enabling, which is true!
1059
- var aApplicable = [],
1060
- aNotApplicable = [],
1061
- sProperty = oActionOperationAvailableMap[sAction],
1062
- sDynamicActionEnabledPath = oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled";
1063
-
1064
- if (typeof sProperty === "object" && sProperty !== null && sProperty !== undefined) {
1065
- for (var i = 0; i < aSelectedContexts.length; i++) {
1066
- var oSelectedContext = aSelectedContexts[i];
1067
- if (oSelectedContext) {
1068
- var oContextData = oSelectedContext.getObject();
1069
- var oTransformedBinding = BindingExpression.transformRecursively(
1070
- sProperty,
1071
- "Binding",
1072
- // eslint-disable-next-line no-loop-func
1073
- function(oBindingExpression) {
1074
- return BindingExpression.constant(oContextData[oBindingExpression.path]);
1075
- },
1076
- true
1077
- );
1078
- var sResult = BindingExpression.compileBinding(oTransformedBinding);
1079
- if (sResult === "true") {
1080
- oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
1081
- aApplicable.push(oSelectedContext);
1082
- } else {
1083
- aNotApplicable.push(oSelectedContext);
1084
- }
1085
- }
1086
- }
1087
- _setDynamicActionContexts(oInternalModelContext, sAction, aApplicable, aNotApplicable);
1088
- } else {
1089
- var aRequestPromises = [];
1090
- for (var i = 0; i < aSelectedContexts.length; i++) {
1091
- var oSelectedContext = aSelectedContexts[i];
1092
- if (oSelectedContext) {
1093
- var oContextData = oSelectedContext.getObject();
1094
- if (sProperty === null && !!oContextData["#" + sAction]) {
1095
- //look for action advertisement if present and its value is not null
1096
- oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
1097
- break;
1098
- } else {
1099
- // Collect promises to retrieve singleton or normal property value asynchronously
1100
- aRequestPromises.push(_requestProperty(oSelectedContext, sAction, sProperty, sDynamicActionEnabledPath));
1101
- }
1102
- }
1103
- }
1104
-
1105
- // When all property values have been retrieved, set
1106
- // The applicable and not-applicable selected contexts for each action and
1107
- // The enabled property of the dynamic action in internal model context.
1108
- aPromises.push(_setContextsBasedOnOperationAvailable(oInternalModelContext, aRequestPromises));
1109
- }
1110
- }
1111
- return Promise.all(aPromises);
1112
- }
1113
-
1114
- function _getDefaultOperators(oRealProperty) {
1115
- // mdc defines the full set of operations that are meaningful for each Edm Type
1116
- var oDataClass = TypeUtil.getDataTypeClassName(oRealProperty);
1117
- var oBaseType = TypeUtil.getBaseType(oDataClass);
1118
- return FilterOperatorUtil.getOperatorsForType(oBaseType);
1119
- }
1120
-
1121
- function _getRestrictions(aDefaultOps, aExpressionOps) {
1122
- // From the default set of Operators for the Base Type, select those that are defined in the Allowed Value.
1123
- // In case that no operators are found, return undefined so that the default set is used.
1124
- var aOperators = aDefaultOps.filter(function(sElement) {
1125
- return aExpressionOps.indexOf(sElement) > -1;
1126
- });
1127
- return aOperators.toString() || undefined;
1128
- }
1129
-
1130
- function getSpecificAllowedExpression(aExpressions) {
1131
- var aAllowedExpressionsPriority = CommonUtils.AllowedExpressionsPrio;
1132
-
1133
- aExpressions.sort(function(a, b) {
1134
- return aAllowedExpressionsPriority.indexOf(a) - aAllowedExpressionsPriority.indexOf(b);
1135
- });
1136
-
1137
- return aExpressions[0];
1138
- }
1139
-
1140
- function getOperatorsForProperty(sProperty, sEntitySetPath, oContext, sType, bUseSemanticDateRange, sSettings) {
1141
- var oFilterRestrictions = CommonUtils.getFilterRestrictionsByPath(sEntitySetPath, oContext);
1142
- var aEqualsOps = ["EQ"];
1143
- var aSingleRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
1144
- var aMultiRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NE", "NOTBT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
1145
- var aSearchExpressionOps = ["Contains", "NotContains", "StartsWith", "NotStartsWith", "EndsWith", "NotEndsWith"];
1146
- var aSemanticDateOpsExt = SemanticDateOperators.getSupportedOperations();
1147
- var bSemanticDateRange = bUseSemanticDateRange === "true" || bUseSemanticDateRange === true;
1148
- var aSemanticDateOps = [];
1149
- var oSettings = typeof sSettings === "string" ? JSON.parse(sSettings).customData : sSettings;
1150
-
1151
- if (oContext.getObject(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
1152
- return aEqualsOps.toString();
1153
- }
1154
-
1155
- if (oSettings && oSettings.operatorConfiguration && oSettings.operatorConfiguration.length > 0) {
1156
- aSemanticDateOps = SemanticDateOperators.getFilterOperations(oSettings.operatorConfiguration);
1157
- } else {
1158
- aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
1159
- }
1160
-
1161
- // Get the default Operators for this Property Type
1162
- var aDefaultOperators = _getDefaultOperators(sType);
1163
-
1164
- // Is there a Filter Restriction defined for this property?
1165
- if (
1166
- oFilterRestrictions &&
1167
- oFilterRestrictions.FilterAllowedExpressions &&
1168
- oFilterRestrictions.FilterAllowedExpressions[sProperty]
1169
- ) {
1170
- // Extending the default operators list with Semantic Date options DATERANGE, DATE, FROM and TO
1171
- if (bSemanticDateRange) {
1172
- aDefaultOperators = aSemanticDateOpsExt.concat(aDefaultOperators);
1173
- }
1174
-
1175
- var sAllowedExpression = CommonUtils.getSpecificAllowedExpression(oFilterRestrictions.FilterAllowedExpressions[sProperty]);
1176
- var sRestrictions;
1177
- // In case more than one Allowed Expressions has been defined for a property
1178
- // choose the most restrictive Allowed Expression
1179
-
1180
- // MultiValue has same Operator as SingleValue, but there can be more than one (maxConditions)
1181
- switch (sAllowedExpression) {
1182
- case "SingleValue":
1183
- sRestrictions = _getRestrictions(aDefaultOperators, aEqualsOps);
1184
- break;
1185
- case "MultiValue":
1186
- sRestrictions = _getRestrictions(aDefaultOperators, aEqualsOps);
1187
- break;
1188
- case "SingleRange":
1189
- var sOperators = _getRestrictions(
1190
- aDefaultOperators,
1191
- sType === "Edm.Date" && bSemanticDateRange ? aSemanticDateOps : aSingleRangeOps
1192
- );
1193
- sRestrictions = sOperators ? sOperators : "";
1194
- break;
1195
- case "MultiRange":
1196
- sRestrictions = _getRestrictions(aDefaultOperators, aMultiRangeOps);
1197
- break;
1198
- case "SearchExpression":
1199
- sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps);
1200
- break;
1201
- case "MultiRangeOrSearchExpression":
1202
- sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps.concat(aMultiRangeOps));
1203
- break;
1204
-
1205
- default:
1206
- break;
1207
- }
1208
- // In case AllowedExpressions is not recognised, undefined in return results in the default set of
1209
- // operators for the type.
1210
- return sRestrictions;
1211
- } else if (sType === "Edm.Date") {
1212
- // In case AllowedExpressions is not provided for type Edm.Date then all the default
1213
- // operators for the type should be returned excluding semantic operators from the list.
1214
- aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
1215
- var aOperators = aDefaultOperators.filter(function(sElement) {
1216
- return aSemanticDateOps.indexOf(sElement) < 0;
1217
- });
1218
- return aOperators.toString();
1219
- }
1220
- }
1221
-
1222
- function getParameterInfo(oMetaModel, sContextPath) {
1223
- var sParameterContextPath = sContextPath.substring(0, sContextPath.lastIndexOf("/"));
1224
- var bResultContext = oMetaModel.getObject(sParameterContextPath + "/@com.sap.vocabularies.Common.v1.ResultContext");
1225
- var oParameterInfo = {};
1226
- if (bResultContext && sParameterContextPath !== sContextPath) {
1227
- oParameterInfo.contextPath = sParameterContextPath;
1228
- oParameterInfo.parameterProperties = CommonUtils.getContextPathProperties(oMetaModel, sParameterContextPath);
1229
- }
1230
- return oParameterInfo;
1231
- }
1232
-
1233
- function addSelectOptionToConditions(oPropertyMetadata, aValidOperators, aCumulativeConditions, oSelectOption) {
1234
- var oCondition = FilterHelper.getConditions(oSelectOption, oPropertyMetadata);
1235
- if (oCondition) {
1236
- if (!aValidOperators || aValidOperators.indexOf(oCondition.operator) > -1) {
1237
- aCumulativeConditions.push(oCondition);
1238
- }
1239
- }
1240
- return aCumulativeConditions;
1241
- }
1242
-
1243
- function addSelectOptionsToConditions(
1244
- sContextPath,
1245
- oSelectionVariant,
1246
- sSelectOptionProp,
1247
- oConditions,
1248
- sConditionPath,
1249
- sConditionProp,
1250
- oValidProperties,
1251
- oMetaModel,
1252
- isParameter
1253
- ) {
1254
- var aConditions = [],
1255
- aSelectOptions,
1256
- aValidOperators;
1257
-
1258
- if (isParameter || CommonUtils.isPropertyFilterable(oMetaModel, sContextPath, sConditionProp, true)) {
1259
- aSelectOptions = oSelectionVariant.getSelectOption(sSelectOptionProp);
1260
- aValidOperators = isParameter ? ["EQ"] : CommonUtils.getOperatorsForProperty(sConditionProp, sContextPath, oMetaModel);
1261
- var oPropertyMetadata = oValidProperties[sConditionProp];
1262
- // Create conditions for all the selectOptions of the property
1263
- aConditions = isParameter
1264
- ? addSelectOptionToConditions(oPropertyMetadata, aValidOperators, aConditions, aSelectOptions[0])
1265
- : aSelectOptions.reduce(addSelectOptionToConditions.bind(null, oPropertyMetadata, aValidOperators), aConditions);
1266
- if (aConditions.length) {
1267
- if (sConditionPath) {
1268
- oConditions[sConditionPath + sConditionProp] = oConditions.hasOwnProperty(sConditionPath + sConditionProp)
1269
- ? oConditions[sConditionPath + sConditionProp].concat(aConditions)
1270
- : aConditions;
1271
- } else {
1272
- oConditions[sConditionProp] = oConditions.hasOwnProperty(sConditionProp)
1273
- ? oConditions[sConditionProp].concat(aConditions)
1274
- : aConditions;
1275
- }
1276
- }
1277
- }
1278
- }
1279
-
1280
- /**
1281
- * Method to convert selection variant to conditions.
1282
- * @param {object} oSelectionVariant SelectionVariant to be converted.
1283
- * @param {object} oConditions Conditions object to be extended.
1284
- * @param {object} oMetaModel Odata V4 metamodel.
1285
- * @param {string} sContextPath ContextPath for the SV properties.
1286
- * @returns {object}
1287
- */
1288
- function addSelectionVariantToConditions(oSelectionVariant, oConditions, oMetaModel, sContextPath) {
1289
- var aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames(),
1290
- oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sContextPath),
1291
- aMetadatProperties = Object.keys(oValidProperties),
1292
- oParameterInfo = CommonUtils.getParameterInfo(oMetaModel, sContextPath),
1293
- sParameterContextPath = oParameterInfo.contextPath,
1294
- oValidParameterProperties = oParameterInfo.parameterProperties,
1295
- bHasParameters =
1296
- !!oParameterInfo.contextPath && oValidParameterProperties && Object.keys(oValidParameterProperties).length > 0;
1297
-
1298
- if (bHasParameters) {
1299
- var aMetadataParameters = Object.keys(oValidParameterProperties);
1300
- aMetadataParameters.forEach(function(sMetadataParameter) {
1301
- var sSelectOptionName;
1302
- if (aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter)) {
1303
- sSelectOptionName = "$Parameter." + sMetadataParameter;
1304
- } else if (aSelectOptionsPropertyNames.includes(sMetadataParameter)) {
1305
- sSelectOptionName = sMetadataParameter;
1306
- } else if (
1307
- sMetadataParameter.startsWith("P_") &&
1308
- aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length))
1309
- ) {
1310
- sSelectOptionName = "$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length);
1311
- } else if (
1312
- sMetadataParameter.startsWith("P_") &&
1313
- aSelectOptionsPropertyNames.includes(sMetadataParameter.slice(2, sMetadataParameter.length))
1314
- ) {
1315
- sSelectOptionName = sMetadataParameter.slice(2, sMetadataParameter.length);
1316
- } else if (aSelectOptionsPropertyNames.includes("$Parameter.P_" + sMetadataParameter)) {
1317
- sSelectOptionName = "$Parameter.P_" + sMetadataParameter;
1318
- } else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataParameter)) {
1319
- sSelectOptionName = "P_" + sMetadataParameter;
1320
- }
1321
-
1322
- if (sSelectOptionName) {
1323
- addSelectOptionsToConditions(
1324
- sParameterContextPath,
1325
- oSelectionVariant,
1326
- sSelectOptionName,
1327
- oConditions,
1328
- undefined,
1329
- sMetadataParameter,
1330
- oValidParameterProperties,
1331
- oMetaModel,
1332
- true
1333
- );
1334
- }
1335
- });
1336
- }
1337
- aMetadatProperties.forEach(function(sMetadataProperty) {
1338
- var sSelectOptionName;
1339
- if (aSelectOptionsPropertyNames.includes(sMetadataProperty)) {
1340
- sSelectOptionName = sMetadataProperty;
1341
- } else if (
1342
- sMetadataProperty.startsWith("P_") &&
1343
- aSelectOptionsPropertyNames.includes(sMetadataProperty.slice(2, sMetadataProperty.length))
1344
- ) {
1345
- sSelectOptionName = sMetadataProperty.slice(2, sMetadataProperty.length);
1346
- } else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataProperty)) {
1347
- sSelectOptionName = "P_" + sMetadataProperty;
1348
- }
1349
- if (sSelectOptionName) {
1350
- addSelectOptionsToConditions(
1351
- sContextPath,
1352
- oSelectionVariant,
1353
- sSelectOptionName,
1354
- oConditions,
1355
- undefined,
1356
- sMetadataProperty,
1357
- oValidProperties,
1358
- oMetaModel,
1359
- false
1360
- );
1361
- }
1362
- });
1363
-
1364
- aSelectOptionsPropertyNames.forEach(function(sSelectOption) {
1365
- if (sSelectOption.indexOf(".") > 0 && !sSelectOption.includes("$Parameter")) {
1366
- var sFullContextPath = ("/" + sSelectOption.replaceAll(".", "/")).startsWith(sContextPath)
1367
- ? "/" + sSelectOption.replaceAll(".", "/")
1368
- : sContextPath + "/" + sSelectOption.replaceAll(".", "/"); // check if the full path, eg SalesOrderManage._Item.Material exists in the metamodel
1369
- if (oMetaModel.getObject(sFullContextPath.replace("P_", ""))) {
1370
- _createConditionsForNavProperties(
1371
- sFullContextPath,
1372
- sContextPath,
1373
- oSelectionVariant,
1374
- sSelectOption,
1375
- oMetaModel,
1376
- oConditions
1377
- );
1378
- }
1379
- }
1380
- });
1381
- return oConditions;
1382
- }
1383
-
1384
- function _createConditionsForNavProperties(
1385
- sFullContextPath,
1386
- sMainEntitySetPath,
1387
- oSelectionVariant,
1388
- sSelectOption,
1389
- oMetaModel,
1390
- oConditions
1391
- ) {
1392
- var aNavObjectNames = sSelectOption.split(".");
1393
- // Eg: "SalesOrderManage._Item._Material.Material" or "_Item.Material"
1394
- if (("/" + sSelectOption.replaceAll(".", "/")).startsWith(sMainEntitySetPath)) {
1395
- var sFullPath = ("/" + sSelectOption).replaceAll(".", "/"),
1396
- sNavPath = sFullPath.replace(sMainEntitySetPath + "/", "");
1397
- aNavObjectNames = sNavPath.split("/");
1398
- }
1399
- var sConditionPath = "";
1400
- var sPropertyName = aNavObjectNames[aNavObjectNames.length - 1]; // Material from SalesOrderManage._Item.Material
1401
- for (var i = 0; i < aNavObjectNames.length - 1; i++) {
1402
- if (oMetaModel.getObject(sMainEntitySetPath + "/" + aNavObjectNames[i].replace("P_", "")).$isCollection) {
1403
- sConditionPath = sConditionPath + aNavObjectNames[i] + "*/"; // _Item*/ in case of 1:n cardinality
1404
- } else {
1405
- sConditionPath = sConditionPath + aNavObjectNames[i] + "/"; // _Item/ in case of 1:1 cardinality
1406
- }
1407
- sMainEntitySetPath = sMainEntitySetPath + "/" + aNavObjectNames[i];
1408
- }
1409
- var sNavPropertyPath = sFullContextPath.slice(0, sFullContextPath.lastIndexOf("/")),
1410
- oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sNavPropertyPath),
1411
- aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames();
1412
- var sSelectOptionName = sPropertyName;
1413
- if (oValidProperties[sPropertyName]) {
1414
- sSelectOptionName = sPropertyName;
1415
- } else if (sPropertyName.startsWith("P_") && oValidProperties[sPropertyName.replace("P_", "")]) {
1416
- sSelectOptionName = sPropertyName.replace("P_", "");
1417
- } else if (oValidProperties["P_" + sPropertyName] && aSelectOptionsPropertyNames.includes("P_" + sPropertyName)) {
1418
- sSelectOptionName = "P_" + sPropertyName;
1419
- }
1420
- if (sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1421
- // if there is no SalesOrderManage._Item.Material yet in the oConditions
1422
- return;
1423
- } else if (!sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1424
- delete oConditions[sConditionPath + sSelectOptionName];
1425
- addSelectOptionsToConditions(
1426
- sNavPropertyPath,
1427
- oSelectionVariant,
1428
- sSelectOption,
1429
- oConditions,
1430
- sConditionPath,
1431
- sSelectOptionName,
1432
- oValidProperties,
1433
- oMetaModel,
1434
- false
1435
- );
1436
- } else {
1437
- addSelectOptionsToConditions(
1438
- sNavPropertyPath,
1439
- oSelectionVariant,
1440
- sSelectOption,
1441
- oConditions,
1442
- sConditionPath,
1443
- sSelectOptionName,
1444
- oValidProperties,
1445
- oMetaModel,
1446
- false
1447
- );
1448
- }
1449
- }
1450
-
1451
- /**
1452
- * Method to add condtions of page context to SelectionVariant.
1453
- * @param {object} oSelectionVariant Instance of {@link sap.fe.navigation.SelectionVariant} SelectionVariant to be used.
1454
- * @param {Array} mPageContext Conditons to be added to the SelectionVariant
1455
- * @param oView
1456
- * @returns {object} Instance of {@link sap.fe.navigation.SelectionVariant} SelectionVariant with the conditions.
1457
- * @private
1458
- * @ui5-restricted
1459
- * @example <code>
1460
- * </code>
1461
- */
1462
- function addPageContextToSelectionVariant(oSelectionVariant, mPageContext, oView) {
1463
- var oAppComponent = CommonUtils.getAppComponent(oView);
1464
- var oNavigationService = oAppComponent.getNavigationService();
1465
- return oNavigationService.mixAttributesAndSelectionVariant(mPageContext, oSelectionVariant.toJSONString());
1466
- }
1467
-
1468
- /**
1469
- * Method to add condtions to SelectionVariant.
1470
- * @param {object} oSelectionVariant Instance of {@link sap.fe.navigation.SelectionVariant} SelectionVariant to be used.
1471
- * @param {object} mFilters Conditons to be added to the SelectionVariant
1472
- * @param {object} oTargetInfo Object returned after selection variant from the table is prepared.
1473
- * @returns {object} Instance of {@link sap.fe.navigation.SelectionVariant} SelectionVariant with the conditions.
1474
- * @private
1475
- * @ui5-restricted
1476
- * @example <code>
1477
- * </code>
1478
- */
1479
- function addExternalStateFiltersToSelectionVariant(oSelectionVariant, mFilters, oTargetInfo) {
1480
- var sFilter,
1481
- sLow = "",
1482
- sHigh = null;
1483
- var fnGetSignAndOption = function(sOperator, sLowValue, sHighValue) {
1484
- var oSelectOptionState = {
1485
- option: "",
1486
- sign: "I",
1487
- low: sLowValue,
1488
- high: sHighValue
1489
- };
1490
- switch (sOperator) {
1491
- case "Contains":
1492
- oSelectOptionState.option = "CP";
1493
- break;
1494
- case "StartsWith":
1495
- oSelectOptionState.option = "CP";
1496
- oSelectOptionState.low += "*";
1497
- break;
1498
- case "EndsWith":
1499
- oSelectOptionState.option = "CP";
1500
- oSelectOptionState.low = "*" + oSelectOptionState.low;
1501
- break;
1502
- case "BT":
1503
- case "LE":
1504
- case "LT":
1505
- case "GT":
1506
- case "NE":
1507
- case "EQ":
1508
- oSelectOptionState.option = sOperator;
1509
- break;
1510
- case "EEQ":
1511
- oSelectOptionState.option = "EQ";
1512
- break;
1513
- case "Empty":
1514
- oSelectOptionState.option = "EQ";
1515
- oSelectOptionState.low = "";
1516
- break;
1517
- case "NotContains":
1518
- oSelectOptionState.option = "CP";
1519
- oSelectOptionState.sign = "E";
1520
- break;
1521
- case "NOTBT":
1522
- oSelectOptionState.option = "BT";
1523
- oSelectOptionState.sign = "E";
1524
- break;
1525
- case "NotStartsWith":
1526
- oSelectOptionState.option = "CP";
1527
- oSelectOptionState.low += "*";
1528
- oSelectOptionState.sign = "E";
1529
- break;
1530
- case "NotEndsWith":
1531
- oSelectOptionState.option = "CP";
1532
- oSelectOptionState.low = "*" + oSelectOptionState.low;
1533
- oSelectOptionState.sign = "E";
1534
- break;
1535
- case "NotEmpty":
1536
- oSelectOptionState.option = "NE";
1537
- oSelectOptionState.low = "";
1538
- break;
1539
- case "NOTLE":
1540
- oSelectOptionState.option = "LE";
1541
- oSelectOptionState.sign = "E";
1542
- break;
1543
- case "NOTGE":
1544
- oSelectOptionState.option = "GE";
1545
- oSelectOptionState.sign = "E";
1546
- break;
1547
- case "NOTLT":
1548
- oSelectOptionState.option = "LT";
1549
- oSelectOptionState.sign = "E";
1550
- break;
1551
- case "NOTGT":
1552
- oSelectOptionState.option = "GT";
1553
- oSelectOptionState.sign = "E";
1554
- break;
1555
- default:
1556
- Log.warning(sOperator + " is not supported. " + sFilter + " could not be added to the navigation context");
1557
- }
1558
- return oSelectOptionState;
1559
- };
1560
- var oFilterConditions = mFilters.filterConditions;
1561
- var oFiltersWithoutConflict = mFilters.filterConditionsWithoutConflict ? mFilters.filterConditionsWithoutConflict : {};
1562
- var oTablePropertiesWithoutConflict = oTargetInfo.propertiesWithoutConflict ? oTargetInfo.propertiesWithoutConflict : {};
1563
- var addFiltersToSelectionVariant = function(oSelectionVariant, sFilter, sPath) {
1564
- var aFilters = oFilterConditions[sFilter];
1565
- for (var item in aFilters) {
1566
- var oFilter = aFilters[item];
1567
- sLow = (oFilter.values[0] && oFilter.values[0].toString()) || "";
1568
- sHigh = (oFilter.values[1] && oFilter.values[1].toString()) || null;
1569
- var oSelectOptionValues = fnGetSignAndOption(oFilter.operator, sLow, sHigh);
1570
- if (oSelectOptionValues.option) {
1571
- oSelectionVariant.addSelectOption(
1572
- sPath ? sPath : sFilter,
1573
- oSelectOptionValues.sign,
1574
- oSelectOptionValues.option,
1575
- oSelectOptionValues.low,
1576
- oSelectOptionValues.high
1577
- );
1578
- }
1579
- }
1580
- };
1581
-
1582
- for (var sFilter in oFilterConditions) {
1583
- // only add the filter values if it is not already present in the SV already
1584
- if (!oSelectionVariant.getSelectOption(sFilter)) {
1585
- // TODO : custom filters should be ignored more generically
1586
- if (sFilter === "$editState") {
1587
- continue;
1588
- }
1589
- addFiltersToSelectionVariant(oSelectionVariant, sFilter);
1590
- } else {
1591
- if (oTablePropertiesWithoutConflict && sFilter in oTablePropertiesWithoutConflict) {
1592
- addFiltersToSelectionVariant(oSelectionVariant, sFilter, oTablePropertiesWithoutConflict[sFilter]);
1593
- }
1594
- // if property was without conflict in page context then add path from page context to SV
1595
- if (sFilter in oFiltersWithoutConflict) {
1596
- addFiltersToSelectionVariant(oSelectionVariant, sFilter, oFiltersWithoutConflict[sFilter]);
1597
- }
1598
- }
1599
- }
1600
- return oSelectionVariant;
1601
- }
1602
-
1603
- /**
1604
- * Returns true if Application is in sticky edit mode.
1605
- *
1606
- * @param {object} oControl
1607
- * @returns {boolean} If we are in sticky mode
1608
- */
1609
- function isStickyEditMode(oControl) {
1610
- var bIsStickyMode = ModelHelper.isStickySessionSupported(oControl.getModel().getMetaModel());
1611
- var bUIEditable = oControl.getModel("ui").getProperty("/isEditable");
1612
- return bIsStickyMode && bUIEditable;
1613
- }
1614
-
1615
- /**
1616
- * Method to add display currency to selection variant.
1617
- * @param {Array} aMandatoryFilterFields Mandatory filterfields of entitySet.
1618
- * @param {object} oSelectionVariant The selection variant
1619
- * @param {object} oSelectionVariantDefaults The defaulted selection variant
1620
- */
1621
- function addDefaultDisplayCurrency(aMandatoryFilterFields, oSelectionVariant, oSelectionVariantDefaults) {
1622
- if (oSelectionVariant && aMandatoryFilterFields && aMandatoryFilterFields.length) {
1623
- for (var i = 0; i < aMandatoryFilterFields.length; i++) {
1624
- var aSVOption = oSelectionVariant.getSelectOption("DisplayCurrency"),
1625
- aDefaultSVOption = oSelectionVariantDefaults && oSelectionVariantDefaults.getSelectOption("DisplayCurrency");
1626
- if (
1627
- aMandatoryFilterFields[i].$PropertyPath === "DisplayCurrency" &&
1628
- (!aSVOption || !aSVOption.length) &&
1629
- aDefaultSVOption &&
1630
- aDefaultSVOption.length
1631
- ) {
1632
- var displayCurrencySelectOption = aDefaultSVOption[0];
1633
- var sSign = displayCurrencySelectOption["Sign"];
1634
- var sOption = displayCurrencySelectOption["Option"];
1635
- var sLow = displayCurrencySelectOption["Low"];
1636
- var sHigh = displayCurrencySelectOption["High"];
1637
- oSelectionVariant.addSelectOption("DisplayCurrency", sSign, sOption, sLow, sHigh);
1638
- }
1639
- }
1640
- }
1641
- }
1642
-
1643
- /**
1644
- * Returns an array of visible, non-computed key and immutable properties.
1645
- *
1646
- * @param {object} oMetaModel
1647
- * @param sPath
1648
- * @returns {Array}
1649
- */
1650
- function getNonComputedVisibleFields(oMetaModel, sPath) {
1651
- var aTechnicalKeys = oMetaModel.getObject(sPath + "/").$Key;
1652
- var aNonComputedVisibleFields = [];
1653
- var oEntityType = oMetaModel.getObject(sPath + "/");
1654
- for (var item in oEntityType) {
1655
- if (oEntityType[item].$kind && oEntityType[item].$kind === "Property") {
1656
- var oAnnotations = oMetaModel.getObject(sPath + "/" + item + "@") || {},
1657
- bIsKey = aTechnicalKeys.indexOf(item) > -1,
1658
- bIsImmutable = bIsKey || oAnnotations["@Org.OData.Core.V1.Immutable"],
1659
- bIsNonComputed = !oAnnotations["@Org.OData.Core.V1.Computed"],
1660
- bIsVisible = !oAnnotations["@com.sap.vocabularies.UI.v1.Hidden"];
1661
- if (bIsImmutable && bIsNonComputed && bIsVisible) {
1662
- aNonComputedVisibleFields.push(item);
1663
- }
1664
- }
1665
- }
1666
- return aNonComputedVisibleFields;
1667
- }
1668
-
1669
- /**
1670
- * Defines the user default settings for the SAP Fiori Launchpad.
1671
- *
1672
- * @function
1673
- * @name sap.fe.core.CommonUtils.setUserDefaults
1674
- * @memberof sap.fe.core.CommonUtils
1675
- * @param {object} [oAppComponent] The AppComponent
1676
- * @param {Array} [aParameters] Parameters in the dialog
1677
- * @param {object} [oModel] Model for which the default value has to be set
1678
- * @param {boolean} [bIsAction] `true` if aParameters contains action parameters
1679
- * @param {boolean} [bIsCreate] `true` if preferredMode is 'create'
1680
- * @param {object} [oActionDefaultValues] Inbound Create Parameters from the Manifest
1681
- * @returns {Promise}
1682
- * @ui5-restricted
1683
- * @final
1684
- **/
1685
- function setUserDefaults(oAppComponent, aParameters, oModel, bIsAction, bIsCreate, oActionDefaultValues) {
1686
- return new Promise(function(resolve, reject) {
1687
- var oComponentData = oAppComponent.getComponentData(),
1688
- oStartupParameters = (oComponentData && oComponentData.startupParameters) || {},
1689
- oShellServices = oAppComponent.getShellServices();
1690
- if (!oShellServices.hasUShell()) {
1691
- aParameters.map(function(oParameter) {
1692
- var sPropertyName = bIsAction
1693
- ? "/" + oParameter.$Name
1694
- : oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
1695
- var sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
1696
- if (oActionDefaultValues && bIsCreate) {
1697
- if (oActionDefaultValues[sParameterName]) {
1698
- oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
1699
- }
1700
- } else if (oStartupParameters[sParameterName]) {
1701
- oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
1702
- }
1703
- });
1704
- return resolve(true);
1705
- }
1706
- return oShellServices.getStartupAppState(oAppComponent).then(function(oStartupAppState) {
1707
- var oData = oStartupAppState.getData() || {},
1708
- aExtendedParameters = (oData.selectionVariant && oData.selectionVariant.SelectOptions) || [];
1709
- aParameters.map(function(oParameter) {
1710
- var sPropertyName = bIsAction
1711
- ? "/" + oParameter.$Name
1712
- : oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
1713
- var sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
1714
- if (oActionDefaultValues && bIsCreate) {
1715
- if (oActionDefaultValues[sParameterName]) {
1716
- oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
1717
- }
1718
- } else if (oStartupParameters[sParameterName]) {
1719
- oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
1720
- } else if (aExtendedParameters.length > 0) {
1721
- for (var i in aExtendedParameters) {
1722
- var oExtendedParameter = aExtendedParameters[i];
1723
- if (oExtendedParameter.PropertyName === sParameterName) {
1724
- var oRange = oExtendedParameter.Ranges.length ? oExtendedParameter.Ranges[0] : undefined;
1725
- if (oRange && oRange.Sign === "I" && oRange.Option === "EQ") {
1726
- oModel.setProperty(sPropertyName, oRange.Low); // high is ignored when Option=EQ
1727
- }
1728
- }
1729
- }
1730
- }
1731
- });
1732
- return resolve(true);
1733
- });
1734
- });
1735
- }
1736
-
1737
- function getAdditionalParamsForCreate(oStartupParameters, oInboundParameters) {
1738
- var oInbounds = oInboundParameters,
1739
- aCreateParameters = oInbounds
1740
- ? Object.keys(oInbounds).filter(function(sParameter) {
1741
- return oInbounds[sParameter].useForCreate;
1742
- })
1743
- : [],
1744
- oRet;
1745
- for (var i = 0; i < aCreateParameters.length; i++) {
1746
- var sCreateParameter = aCreateParameters[i];
1747
- var aValues = oStartupParameters && oStartupParameters[sCreateParameter];
1748
- if (aValues && aValues.length === 1) {
1749
- oRet = oRet || Object.create(null);
1750
- oRet[sCreateParameter] = aValues[0];
1751
- }
1752
- }
1753
- return oRet;
1754
- }
1755
- /**
1756
- * Gets semantic object mappings defined in app descriptor outbounds.
1757
- *
1758
- * @function
1759
- * @name sap.fe.core.CommonUtils.getSemanticObjectMapping
1760
- * @memberof sap.fe.core.CommonUtils
1761
- * @param {object} [oOutbound] Outbound defined in app descriptor
1762
- * @returns {Array} A collection of semantic object mappings defined for one outbound
1763
- * @ui5-restricted
1764
- * @final
1765
- **/
1766
- function getSemanticObjectMapping(oOutbound) {
1767
- var aSemanticObjectMapping = [];
1768
- if (oOutbound.parameters) {
1769
- var aParameters = Object.keys(oOutbound.parameters) || [];
1770
- if (aParameters.length > 0) {
1771
- aParameters.forEach(function(sParam) {
1772
- var oMapping = oOutbound.parameters[sParam];
1773
- if (oMapping.value && oMapping.value.value && oMapping.value.format === "binding") {
1774
- // using the format of UI.Mapping
1775
- var oSemanticMapping = {
1776
- "LocalProperty": {
1777
- "$PropertyPath": oMapping.value.value
1778
- },
1779
- "SemanticObjectProperty": sParam
1780
- };
1781
-
1782
- if (aSemanticObjectMapping.length > 0) {
1783
- // To check if the semanticObject Mapping is done for the same local property more that once then first one will be considered
1784
- for (var i = 0; i < aSemanticObjectMapping.length; i++) {
1785
- if (
1786
- aSemanticObjectMapping[i]["LocalProperty"]["$PropertyPath"] !==
1787
- oSemanticMapping["LocalProperty"]["$PropertyPath"]
1788
- ) {
1789
- aSemanticObjectMapping.push(oSemanticMapping);
1790
- }
1791
- }
1792
- } else {
1793
- aSemanticObjectMapping.push(oSemanticMapping);
1794
- }
1795
- }
1796
- });
1797
- }
1798
- }
1799
- return aSemanticObjectMapping;
1800
- }
1801
-
1802
- /**
1803
- * Returns the datapoints/ microcharts for which target outbound is configured.
1804
- *
1805
- * @param {object} oViewData View data as given in app descriptor
1806
- * @param {object} oCrossNav The target outbound in cross navigation in manifest
1807
- * @returns {object} Datapoints/microcharts with outbound defined
1808
- */
1809
- function getHeaderFacetItemConfigForExternalNavigation(oViewData, oCrossNav) {
1810
- var aSemanticObjectMapping = [];
1811
- var oHeaderFacetItems = {};
1812
- var sId;
1813
- var oControlConfig = oViewData.controlConfiguration;
1814
- for (var config in oControlConfig) {
1815
- if (
1816
- config.indexOf("@com.sap.vocabularies.UI.v1.DataPoint") > -1 ||
1817
- config.indexOf("@com.sap.vocabularies.UI.v1.Chart") > -1
1818
- ) {
1819
- if (
1820
- oControlConfig[config].navigation &&
1821
- oControlConfig[config].navigation.targetOutbound &&
1822
- oControlConfig[config].navigation.targetOutbound.outbound
1823
- ) {
1824
- var sOutbound = oControlConfig[config].navigation.targetOutbound.outbound;
1825
- var oOutbound = oCrossNav[sOutbound];
1826
- if (oOutbound.semanticObject && oOutbound.action) {
1827
- if (config.indexOf("Chart") > -1) {
1828
- sId = StableIdHelper.generate(["fe", "MicroChartLink", config]);
1829
- } else {
1830
- sId = StableIdHelper.generate(["fe", "HeaderDPLink", config]);
1831
- }
1832
- var aSemanticObjectMapping = CommonUtils.getSemanticObjectMapping(oOutbound);
1833
- oHeaderFacetItems[sId] = {
1834
- semanticObject: oOutbound.semanticObject,
1835
- action: oOutbound.action,
1836
- semanticObjectMapping: aSemanticObjectMapping
1837
- };
1838
- } else {
1839
- Log.error("Cross navigation outbound is configured without semantic object and action for " + sOutbound);
1840
- }
1841
- }
1842
- }
1843
- }
1844
- return oHeaderFacetItems;
1845
- }
1846
-
1847
- /**
1848
- * Method to replace Local Properties with Semantic Object mappings.
1849
- *
1850
- * @param {object} oSelectionVariant SelectionVariant consisting of filterbar, Table and Page Context
1851
- * @param {object} vMappings String representation of semantic object mappings
1852
- * @returns {object} Modified SelectionVariant with LocalProperty replaced with SemanticObjectProperties.
1853
- */
1854
- function setSemanticObjectMappings(oSelectionVariant, vMappings) {
1855
- var oMappings = typeof vMappings === "string" ? JSON.parse(vMappings) : vMappings;
1856
- for (var i = 0; i < oMappings.length; i++) {
1857
- var sLocalProperty =
1858
- (oMappings[i]["LocalProperty"] && oMappings[i]["LocalProperty"]["$PropertyPath"]) ||
1859
- (oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"] &&
1860
- oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"]["$Path"]);
1861
- var sSemanticObjectProperty =
1862
- oMappings[i]["SemanticObjectProperty"] || oMappings[i]["@com.sap.vocabularies.Common.v1.SemanticObjectProperty"];
1863
- if (oSelectionVariant.getSelectOption(sLocalProperty)) {
1864
- var oSelectOption = oSelectionVariant.getSelectOption(sLocalProperty);
1865
-
1866
- //Create a new SelectOption with sSemanticObjectProperty as the property Name and remove the older one
1867
- oSelectionVariant.removeSelectOption(sLocalProperty);
1868
- oSelectionVariant.massAddSelectOption(sSemanticObjectProperty, oSelectOption);
1869
- }
1870
- }
1871
- return oSelectionVariant;
1872
- }
1873
-
1874
- /**
1875
- * Method to retrieve Semantic Object annotations from meta model.
1876
- * @param {oMetaModel} oMetaModel The Meta Model.
1877
- * @param {sPath} sPath Property path.
1878
- * @param oView
1879
- * @param oConverterContext
1880
- * @returns {object} - Promises resolving name of Semantic Objects.
1881
- */
1882
- function fnGetSemanticObjectsFromPath(oMetaModel, sPath, oView, oConverterContext) {
1883
- return new Promise(function(resolve) {
1884
- var sSemanticObject = oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.SemanticObject");
1885
- var aSemanticObjectUnavailableActions = oMetaModel.getObject(
1886
- sPath + "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions"
1887
- );
1888
- var aSemanticObjectForGetLinks, oSemanticObject;
1889
- aSemanticObjectForGetLinks = [{ semanticObject: sSemanticObject }];
1890
- oSemanticObject = {
1891
- semanticObject: sSemanticObject
1892
- };
1893
- resolve({
1894
- semanticObjectPath: sPath,
1895
- semanticObjectForGetLinks: aSemanticObjectForGetLinks,
1896
- semanticObject: oSemanticObject,
1897
- unavailableActions: aSemanticObjectUnavailableActions
1898
- });
1899
- }).catch(function(oError) {
1900
- Log.error("Error in fnGetSemanticObjectsFromPath", oError);
1901
- });
1902
- }
1903
-
1904
- function fnUpdateSemanticTargetsModel(aGetLinksPromises, aSemanticObjects, oInternalModelContext, sCurrentHash) {
1905
- return Promise.all(aGetLinksPromises)
1906
- .then(function(aValues) {
1907
- var aLinks,
1908
- _oLink,
1909
- _sLinkIntent,
1910
- aFinalLinks = [];
1911
- var oFinalSemanticObjects = {};
1912
- var bIntentHasActions = function(sIntent, aActions) {
1913
- for (var intent in aActions) {
1914
- if (intent === sIntent) {
1915
- return true;
1916
- } else {
1917
- return false;
1918
- }
1919
- }
1920
- };
1921
-
1922
- for (var k = 0; k < aValues.length; k++) {
1923
- aLinks = aValues[k];
1924
- if (aLinks && aLinks.length > 0 && aLinks[0] !== undefined) {
1925
- var oSemanticObject = {},
1926
- oTmp = {},
1927
- sAlternatePath;
1928
- for (var i = 0; i < aLinks.length; i++) {
1929
- aFinalLinks.push([]);
1930
- var hasTargetsNotFiltered = false;
1931
- var hasTargets = false;
1932
- for (var iLinkCount = 0; iLinkCount < aLinks[i][0].length; iLinkCount++) {
1933
- _oLink = aLinks[i][0][iLinkCount];
1934
- _sLinkIntent = _oLink && _oLink.intent.split("-")[1];
1935
- if (!(_oLink && _oLink.intent && _oLink.intent.indexOf(sCurrentHash) === 0)) {
1936
- hasTargetsNotFiltered = true;
1937
- if (!bIntentHasActions(_sLinkIntent, aSemanticObjects[k].unavailableActions)) {
1938
- aFinalLinks[i].push(_oLink);
1939
- hasTargets = true;
1940
- }
1941
- }
1942
- }
1943
- oTmp = {
1944
- semanticObject: aSemanticObjects[k].semanticObject,
1945
- path: aSemanticObjects[k].path,
1946
- HasTargets: hasTargets,
1947
- HasTargetsNotFiltered: hasTargetsNotFiltered
1948
- };
1949
- if (oSemanticObject[aSemanticObjects[k].semanticObject] === undefined) {
1950
- oSemanticObject[aSemanticObjects[k].semanticObject] = {};
1951
- }
1952
- sAlternatePath = aSemanticObjects[k].path.replace(/\//g, "_");
1953
- if (oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] === undefined) {
1954
- oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = {};
1955
- }
1956
- oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = Object.assign(
1957
- oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath],
1958
- oTmp
1959
- );
1960
- }
1961
- var sSemanticObjectName = Object.keys(oSemanticObject)[0];
1962
- if (Object.keys(oFinalSemanticObjects).includes(sSemanticObjectName)) {
1963
- oFinalSemanticObjects[sSemanticObjectName] = Object.assign(
1964
- oFinalSemanticObjects[sSemanticObjectName],
1965
- oSemanticObject[sSemanticObjectName]
1966
- );
1967
- } else {
1968
- oFinalSemanticObjects = Object.assign(oFinalSemanticObjects, oSemanticObject);
1969
- }
1970
- aFinalLinks = [];
1971
- }
1972
- }
1973
- if (Object.keys(oFinalSemanticObjects).length > 0) {
1974
- oInternalModelContext.setProperty(
1975
- "semanticsTargets",
1976
- mergeObjects(oFinalSemanticObjects, oInternalModelContext.getProperty("semanticsTargets"))
1977
- );
1978
- return oFinalSemanticObjects;
1979
- }
1980
- })
1981
- .catch(function(oError) {
1982
- Log.error("fnUpdateSemanticTargetsModel: Cannot read links", oError);
1983
- });
1984
- }
1985
-
1986
- function fnGetSemanticObjectPromise(oAppComponent, oView, oMetaModel, sPath) {
1987
- var oConverterContext;
1988
- var sEntitySetPath = ModelHelper.getEntitySetPath(sPath),
1989
- sTargetEntityPath = sEntitySetPath,
1990
- sTargetEntitySetName = sTargetEntityPath ? sTargetEntityPath.slice(1) : sTargetEntityPath;
1991
- var oDataModelPath = MetaModelConverter.getInvolvedDataModelObjects(
1992
- oMetaModel.createBindingContext("/" + sTargetEntitySetName)
1993
- );
1994
-
1995
- oConverterContext = ConverterContext.createConverterContextForMacro(
1996
- oDataModelPath.startingEntitySet.name,
1997
- oMetaModel,
1998
- oAppComponent && oAppComponent.getDiagnostics(),
1999
- mergeObjects,
2000
- oDataModelPath.contextLocation,
2001
- undefined
2002
- );
2003
- return CommonUtils.getSemanticObjectsFromPath(oMetaModel, sPath, oView, oConverterContext);
2004
- }
2005
-
2006
- /**
2007
- * Method to retrieve Semantic Object targets from page model and set the internal model.
2008
- *
2009
- * @param oController
2010
- * @param {string} sPageModel Name of the page model
2011
- * @returns {Promise} Once resolved, a promise is returned which is resolved without a result in case of success of setting internal Semantic Targets Model
2012
- */
2013
- function fnGetSemanticTargetsFromPageModel(oController, sPageModel) {
2014
- var _fnfindValues = function(obj, key) {
2015
- return _fnfindValuesHelper(obj, key, []);
2016
- };
2017
- var _fnfindValuesHelper = function(obj, key, list) {
2018
- if (!obj) {
2019
- return list;
2020
- }
2021
- if (obj instanceof Array) {
2022
- for (var i in obj) {
2023
- list = list.concat(_fnfindValuesHelper(obj[i], key, []));
2024
- }
2025
- return list;
2026
- }
2027
- if (obj[key]) {
2028
- list.push(obj[key]);
2029
- }
2030
-
2031
- if (typeof obj == "object" && obj !== null) {
2032
- var children = Object.keys(obj);
2033
- if (children.length > 0) {
2034
- for (i = 0; i < children.length; i++) {
2035
- list = list.concat(_fnfindValuesHelper(obj[children[i]], key, []));
2036
- }
2037
- }
2038
- }
2039
- return list;
2040
- };
2041
- var _fnDeleteDuplicateSemanticObjects = function(aSemanticObjectPath) {
2042
- return aSemanticObjectPath.filter(function(value, index) {
2043
- return aSemanticObjectPath.indexOf(value) === index;
2044
- });
2045
- };
2046
- var oView = oController.getView();
2047
- var oInternalModelContext = oView.getBindingContext("internal");
2048
-
2049
- if (oInternalModelContext) {
2050
- var aSemanticObjectsPromises = [];
2051
- var oComponent = oController.getOwnerComponent();
2052
- var oAppComponent = sap.ui.core.Component.getOwnerComponentFor(oComponent);
2053
- var oMetaModel = oAppComponent.getMetaModel();
2054
- var oPageModel = oComponent.getModel(sPageModel).getData();
2055
- if (JSON.stringify(oPageModel) === "{}") {
2056
- oPageModel = oComponent.getModel(sPageModel)._getObject("/", undefined);
2057
- }
2058
- var aSemanticObjectsFound = _fnfindValues(oPageModel, "semanticObjectPath");
2059
- aSemanticObjectsFound = _fnDeleteDuplicateSemanticObjects(aSemanticObjectsFound);
2060
- var oShellServiceHelper = CommonUtils.getShellServices(oAppComponent);
2061
- var sCurrentHash = oShellServiceHelper.hrefForExternal();
2062
- var aSemanticObjectsForGetLinks = [];
2063
- var aSemanticObjects = [];
2064
- var sPath;
2065
- var _oSemanticObject;
2066
-
2067
- if (sCurrentHash && sCurrentHash.indexOf("?") !== -1) {
2068
- // sCurrentHash can contain query string, cut it off!
2069
- sCurrentHash = sCurrentHash.split("?")[0];
2070
- }
2071
-
2072
- for (var i = 0; i < aSemanticObjectsFound.length; i++) {
2073
- sPath = aSemanticObjectsFound[i];
2074
- aSemanticObjectsPromises.push(CommonUtils.getSemanticObjectPromise(oAppComponent, oView, oMetaModel, sPath));
2075
- }
2076
-
2077
- if (aSemanticObjectsPromises.length === 0) {
2078
- return Promise.resolve();
2079
- } else {
2080
- Promise.all(aSemanticObjectsPromises)
2081
- .then(function(aValues) {
2082
- var aGetLinksPromises = [],
2083
- sSemObjExpression;
2084
- var aSemanticObjectsResolved = aValues.filter(function(element) {
2085
- if (
2086
- element.semanticObject !== undefined &&
2087
- element.semanticObject.semanticObject &&
2088
- typeof element.semanticObject.semanticObject === "object"
2089
- ) {
2090
- sSemObjExpression = BindingExpression.compileBinding(
2091
- BindingExpression.bindingExpression(element.semanticObject.semanticObject.$Path)
2092
- );
2093
- element.semanticObject.semanticObject = sSemObjExpression;
2094
- element.semanticObjectForGetLinks[0].semanticObject = sSemObjExpression;
2095
- return true;
2096
- } else if (element) {
2097
- return element.semanticObject !== undefined;
2098
- } else {
2099
- return false;
2100
- }
2101
- });
2102
- for (var j = 0; j < aSemanticObjectsResolved.length; j++) {
2103
- _oSemanticObject = aSemanticObjectsResolved[j];
2104
- if (
2105
- _oSemanticObject &&
2106
- _oSemanticObject.semanticObject &&
2107
- !(_oSemanticObject.semanticObject.semanticObject.indexOf("{") === 0)
2108
- ) {
2109
- aSemanticObjectsForGetLinks.push(_oSemanticObject.semanticObjectForGetLinks);
2110
- aSemanticObjects.push({
2111
- semanticObject: _oSemanticObject.semanticObject.semanticObject,
2112
- unavailableActions: _oSemanticObject.unavailableActions,
2113
- path: aSemanticObjectsResolved[j].semanticObjectPath
2114
- });
2115
- aGetLinksPromises.push(
2116
- oShellServiceHelper.getLinksWithCache([_oSemanticObject.semanticObjectForGetLinks])
2117
- );
2118
- }
2119
- }
2120
- return CommonUtils.updateSemanticTargets(
2121
- aGetLinksPromises,
2122
- aSemanticObjects,
2123
- oInternalModelContext,
2124
- sCurrentHash
2125
- );
2126
- })
2127
- .catch(function(oError) {
2128
- Log.error("fnGetSemanticTargetsFromTable: Cannot get Semantic Objects", oError);
2129
- });
2130
- }
2131
- } else {
2132
- return Promise.resolve();
2133
- }
2134
- }
2135
-
2136
- function getFilterRestrictions(oFilterRestrictionsAnnotation, sRestriction) {
2137
- var FilterRestrictions = CommonUtils.FilterRestrictions;
2138
- if (sRestriction === FilterRestrictions.REQUIRED_PROPERTIES || sRestriction === FilterRestrictions.NON_FILTERABLE_PROPERTIES) {
2139
- var aProps = [];
2140
- if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation[sRestriction]) {
2141
- aProps = oFilterRestrictionsAnnotation[sRestriction].map(function(oProperty) {
2142
- return oProperty.$PropertyPath;
2143
- });
2144
- }
2145
- return aProps;
2146
- } else if (sRestriction === FilterRestrictions.ALLOWED_EXPRESSIONS) {
2147
- var mAllowedExpressions = {};
2148
- if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation.FilterExpressionRestrictions) {
2149
- oFilterRestrictionsAnnotation.FilterExpressionRestrictions.forEach(function(oProperty) {
2150
- //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
2151
- if (mAllowedExpressions[oProperty.Property.$PropertyPath]) {
2152
- mAllowedExpressions[oProperty.Property.$PropertyPath].push(oProperty.AllowedExpressions);
2153
- } else {
2154
- mAllowedExpressions[oProperty.Property.$PropertyPath] = [oProperty.AllowedExpressions];
2155
- }
2156
- });
2157
- }
2158
- return mAllowedExpressions;
2159
- }
2160
- // Default return the FilterRestrictions Annotation
2161
- return oFilterRestrictionsAnnotation;
2162
- }
2163
-
2164
- function getFilterRestrictionsByPath(sEntitySetPath, oMetaModel) {
2165
- var oRet = {},
2166
- FilterRestrictions = CommonUtils.FilterRestrictions,
2167
- oFilterRestrictions = sEntitySetPath
2168
- ? oMetaModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions")
2169
- : {};
2170
- oRet[FilterRestrictions.REQUIRED_PROPERTIES] =
2171
- getFilterRestrictions(oFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || [];
2172
- oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES] =
2173
- getFilterRestrictions(oFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || [];
2174
- //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
2175
- oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] =
2176
- getFilterRestrictions(oFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {};
2177
-
2178
- var aPathParts = sEntitySetPath.split("/");
2179
-
2180
- if (aPathParts.length > 2) {
2181
- // In normal filterbar scenarios sEntitySetPath is of the format "/Customer".
2182
- // But, In case of sEntitySetPath of format "/Customer/Set" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
2183
- var sNavigationPath = aPathParts[aPathParts.length - 1];
2184
- aPathParts.splice(-1, 1); // removing NavigationProperty from the end.
2185
- var sParentEntitySetPath = aPathParts.join("/");
2186
- var oNavigationRestrictions = CommonUtils.getNavigationRestrictions(oMetaModel, sParentEntitySetPath, sNavigationPath);
2187
- var oNavigationFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions["FilterRestrictions"];
2188
- oRet[FilterRestrictions.REQUIRED_PROPERTIES].concat(
2189
- getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || []
2190
- );
2191
- oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES].concat(
2192
- getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || []
2193
- );
2194
- //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
2195
- oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] = mergeObjects(
2196
- {},
2197
- getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {},
2198
- oRet[FilterRestrictions.ALLOWED_EXPRESSIONS]
2199
- );
2200
- }
2201
-
2202
- return oRet;
2203
- }
2204
-
2205
- function templateControlFragment(sFragmentName, oPreprocessorSettings, oOptions, oModifier) {
2206
- oOptions = oOptions || {};
2207
- if (oModifier) {
2208
- return oModifier.templateControlFragment(sFragmentName, oPreprocessorSettings, oOptions.view).then(function(oFragment) {
2209
- // This is required as Flex returns an HTMLCollection as templating result in XML time.
2210
- return oModifier.targets === "xmlTree" && oFragment.length > 0 ? oFragment[0] : oFragment;
2211
- });
2212
- } else {
2213
- return loadMacroLibrary()
2214
- .then(function() {
2215
- return XMLPreprocessor.process(
2216
- XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
2217
- { name: sFragmentName },
2218
- oPreprocessorSettings
2219
- );
2220
- })
2221
- .then(function(oFragment) {
2222
- var oControl = oFragment.firstElementChild;
2223
- if (!!oOptions.isXML && oControl) {
2224
- return oControl;
2225
- }
2226
- return Fragment.load({
2227
- id: oOptions.id,
2228
- definition: oFragment,
2229
- controller: oOptions.controller
2230
- });
2231
- });
2232
- }
2233
- }
2234
-
2235
- /**
2236
- * Method which returns a promise that resolves to a singleton property value.
2237
- *
2238
- * @param {string} sPath Absolute path to the singleton property
2239
- * @param {object} oModel Instance of the OData V4 model
2240
- * @returns {Promise} A promise which resolves to the property value for a singleton, otherwise null.
2241
- */
2242
- function requestSingletonProperty(sPath, oModel) {
2243
- if (!sPath || !oModel) {
2244
- return Promise.resolve(null);
2245
- }
2246
-
2247
- var oMetaModel = oModel.getMetaModel();
2248
- // Find the underlying entity set from the property path and check whether it is a singleton.
2249
- var aParts = sPath.split("/").filter(Boolean),
2250
- sPropertyName = aParts.pop(),
2251
- sNavigationPath = aParts.join("/"),
2252
- oEntitySet = sNavigationPath && oMetaModel.getObject("/" + sNavigationPath);
2253
- if (oEntitySet && oEntitySet.$kind === "Singleton") {
2254
- var sSingletonName = aParts[aParts.length - 1],
2255
- oPropertyBinding = oModel.bindProperty("/" + sSingletonName + "/" + sPropertyName);
2256
- return oPropertyBinding.requestValue();
2257
- }
2258
-
2259
- return Promise.resolve(null);
2260
- }
2261
-
2262
- /**
2263
- * Add binding event listener.
2264
- *
2265
- * @param {object} oControl Control instance
2266
- * @param {object} sEventName Event name
2267
- * @param {object} fHandler Handler to be called
2268
- * @private
2269
- * @ui5-restricted
2270
- */
2271
- function addEventToBindingInfo(oControl, sEventName, fHandler) {
2272
- var oBindingInfo;
2273
- var setBindingInfo = function() {
2274
- if (oBindingInfo) {
2275
- if (!oBindingInfo.events) {
2276
- oBindingInfo.events = {};
2277
- }
2278
- if (!oBindingInfo.events[sEventName]) {
2279
- oBindingInfo.events[sEventName] = fHandler;
2280
- } else {
2281
- var fOriginalHandler = oBindingInfo.events[sEventName];
2282
- oBindingInfo.events[sEventName] = function() {
2283
- fHandler.apply(this, arguments);
2284
- fOriginalHandler.apply(this, arguments);
2285
- };
2286
- }
2287
- }
2288
- };
2289
- if (oControl.isA("sap.ui.mdc.ChartNew")) {
2290
- oControl
2291
- .innerChartBound()
2292
- .then(function() {
2293
- oBindingInfo = oControl
2294
- .getControlDelegate()
2295
- ._getChart(oControl)
2296
- .getBindingInfo("data");
2297
- setBindingInfo();
2298
- })
2299
- .catch(function(sError) {
2300
- Log.error(sError);
2301
- });
2302
- } else {
2303
- oBindingInfo = oControl.data("rowsBindingInfo");
2304
- setBindingInfo();
2305
- }
2306
- }
2307
-
2308
- function loadMacroLibrary() {
2309
- return new Promise(function(resolve, reject) {
2310
- sap.ui.require(["sap/fe/macros/macroLibrary"], function(/*macroLibrary*/) {
2311
- resolve();
2312
- });
2313
- });
2314
- }
2315
-
2316
- var CommonUtils = {
2317
- isPropertyFilterable: isPropertyFilterable,
2318
- isFieldControlPathInapplicable: isFieldControlPathInapplicable,
2319
- removeSensitiveData: removeSensitiveData,
2320
- fireButtonPress: fnFireButtonPress,
2321
- getTargetView: getTargetView,
2322
- hasTransientContext: fnHasTransientContexts,
2323
- updateRelatedAppsDetails: fnUpdateRelatedAppsDetails,
2324
- resolveStringtoBoolean: fnResolveStringtoBoolean,
2325
- getAppComponent: getAppComponent,
2326
- processDataLossConfirmation: fnProcessDataLossConfirmation,
2327
- getMandatoryFilterFields: fnGetMandatoryFilterFields,
2328
- getContextPathProperties: fnGetContextPathProperties,
2329
- getParameterInfo: getParameterInfo,
2330
- updateDataFieldForIBNButtonsVisibility: fnUpdateDataFieldForIBNButtonsVisibility,
2331
- getTranslatedText: getTranslatedText,
2332
- getEntitySetName: getEntitySetName,
2333
- getActionPath: getActionPath,
2334
- computeDisplayMode: computeDisplayMode,
2335
- setActionEnablement: setActionEnablement,
2336
- isStickyEditMode: isStickyEditMode,
2337
- getOperatorsForProperty: getOperatorsForProperty,
2338
- addSelectionVariantToConditions: addSelectionVariantToConditions,
2339
- addExternalStateFiltersToSelectionVariant: addExternalStateFiltersToSelectionVariant,
2340
- addPageContextToSelectionVariant: addPageContextToSelectionVariant,
2341
- addDefaultDisplayCurrency: addDefaultDisplayCurrency,
2342
- getNonComputedVisibleFields: getNonComputedVisibleFields,
2343
- setUserDefaults: setUserDefaults,
2344
- getShellServices: getShellServices,
2345
- getIBNActions: fnGetIBNActions,
2346
- getHeaderFacetItemConfigForExternalNavigation: getHeaderFacetItemConfigForExternalNavigation,
2347
- getSemanticObjectMapping: getSemanticObjectMapping,
2348
- setSemanticObjectMappings: setSemanticObjectMappings,
2349
- getSemanticObjectPromise: fnGetSemanticObjectPromise,
2350
- getSemanticTargetsFromPageModel: fnGetSemanticTargetsFromPageModel,
2351
- getSemanticObjectsFromPath: fnGetSemanticObjectsFromPath,
2352
- updateSemanticTargets: fnUpdateSemanticTargetsModel,
2353
- getPropertyDataType: getPropertyDataType,
2354
- getNavigationRestrictions: getNavigationRestrictions,
2355
- getSearchRestrictions: getSearchRestrictions,
2356
- getFilterRestrictionsByPath: getFilterRestrictionsByPath,
2357
- getSpecificAllowedExpression: getSpecificAllowedExpression,
2358
- getAdditionalParamsForCreate: getAdditionalParamsForCreate,
2359
- requestSingletonProperty: requestSingletonProperty,
2360
- templateControlFragment: templateControlFragment,
2361
- addEventToBindingInfo: addEventToBindingInfo,
2362
- FilterRestrictions: {
2363
- REQUIRED_PROPERTIES: "RequiredProperties",
2364
- NON_FILTERABLE_PROPERTIES: "NonFilterableProperties",
2365
- ALLOWED_EXPRESSIONS: "FilterAllowedExpressions"
2366
- },
2367
- AllowedExpressionsPrio: [
2368
- "SingleValue",
2369
- "MultiValue",
2370
- "SingleRange",
2371
- "MultiRange",
2372
- "SearchExpression",
2373
- "MultiRangeOrSearchExpression"
2374
- ],
2375
- fnProcessDataLossOrDraftDiscardConfirmation: fnProcessDataLossOrDraftDiscardConfirmation,
2376
- normalizeSearchTerm: normalizeSearchTerm
2377
- };
2378
-
2379
- return CommonUtils;
2380
- }
2381
- );
5
+ sap.ui.define(["sap/ui/core/mvc/View", "sap/ui/core/Component", "sap/m/MessageBox", "sap/base/Log", "sap/fe/core/library", "sap/fe/core/helpers/ModelHelper", "sap/fe/core/helpers/SemanticDateOperators", "sap/base/util/merge", "sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler", "sap/ui/core/XMLTemplateProcessor", "sap/ui/core/util/XMLPreprocessor", "sap/ui/core/Fragment", "sap/fe/core/helpers/BindingExpression", "./templating/FilterHelper", "sap/fe/core/helpers/StableIdHelper", "sap/ui/mdc/condition/FilterOperatorUtil", "sap/ui/mdc/odata/v4/TypeUtil", "sap/fe/core/converters/helpers/IssueManager"], function (View, Component, MessageBox, Log, library, ModelHelper, SemanticDateOperators, mergeObjects, DataLossOrDraftDiscardHandler, XMLTemplateProcessor, XMLPreprocessor, Fragment, BindingExpression, FilterHelper, StableIdHelper, FilterOperatorUtil, TypeUtil, IssueManager) {
6
+ "use strict";
7
+
8
+ var IssueCategoryType = IssueManager.IssueCategoryType;
9
+ var IssueSeverity = IssueManager.IssueSeverity;
10
+ var IssueCategory = IssueManager.IssueCategory;
11
+ var generate = StableIdHelper.generate;
12
+ var getConditions = FilterHelper.getConditions;
13
+ var transformRecursively = BindingExpression.transformRecursively;
14
+ var constant = BindingExpression.constant;
15
+ var compileBinding = BindingExpression.compileBinding;
16
+ var bindingExpression = BindingExpression.bindingExpression;
17
+
18
+ var ProgrammingModel = library.ProgrammingModel;
19
+ var aValidTypes = ["Edm.Boolean", "Edm.Byte", "Edm.Date", "Edm.DateTime", "Edm.DateTimeOffset", "Edm.Decimal", "Edm.Double", "Edm.Float", "Edm.Guid", "Edm.Int16", "Edm.Int32", "Edm.Int64", "Edm.SByte", "Edm.Single", "Edm.String", "Edm.Time", "Edm.TimeOfDay"];
20
+
21
+ function normalizeSearchTerm(sSearchTerm) {
22
+ if (!sSearchTerm) {
23
+ return undefined;
24
+ }
25
+
26
+ return sSearchTerm.replace(/"/g, " ").split(/\s+/).reduce(function (sNormalized, sCurrentWord) {
27
+ if (sCurrentWord !== "") {
28
+ sNormalized = (sNormalized ? sNormalized + " " : "") + '"' + sCurrentWord + '"';
29
+ }
30
+
31
+ return sNormalized;
32
+ }, undefined);
33
+ }
34
+
35
+ function getPropertyDataType(oNavigationContext) {
36
+ var sDataType = oNavigationContext.getProperty("$Type"); // if $kind exists, it's not a DataField and we have the final type already
37
+
38
+ if (!oNavigationContext.getProperty("$kind")) {
39
+ switch (sDataType) {
40
+ case "com.sap.vocabularies.UI.v1.DataFieldForAction":
41
+ case "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation":
42
+ sDataType = undefined;
43
+ break;
44
+
45
+ case "com.sap.vocabularies.UI.v1.DataField":
46
+ case "com.sap.vocabularies.UI.v1.DataFieldWithNavigationPath":
47
+ case "com.sap.vocabularies.UI.v1.DataFieldWithUrl":
48
+ sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
49
+ break;
50
+
51
+ case "com.sap.vocabularies.UI.v1.DataFieldForAnnotation":
52
+ default:
53
+ var sAnnotationPath = oNavigationContext.getProperty("Target/$AnnotationPath");
54
+
55
+ if (sAnnotationPath) {
56
+ if (sAnnotationPath.indexOf("com.sap.vocabularies.Communication.v1.Contact") > -1) {
57
+ sDataType = oNavigationContext.getProperty("Target/$AnnotationPath/fn/$Path/$Type");
58
+ } else if (sAnnotationPath.indexOf("com.sap.vocabularies.UI.v1.DataPoint") > -1) {
59
+ sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
60
+ } else {
61
+ // e.g. FieldGroup or Chart
62
+ sDataType = undefined;
63
+ }
64
+ } else {
65
+ sDataType = undefined;
66
+ }
67
+
68
+ break;
69
+ }
70
+ }
71
+
72
+ return sDataType;
73
+ }
74
+
75
+ function fnHasTransientContexts(oListBinding) {
76
+ var bHasTransientContexts = false;
77
+
78
+ if (oListBinding) {
79
+ oListBinding.getCurrentContexts().forEach(function (oContext) {
80
+ if (oContext && oContext.isTransient()) {
81
+ bHasTransientContexts = true;
82
+ }
83
+ });
84
+ }
85
+
86
+ return bHasTransientContexts;
87
+ }
88
+
89
+ function getSearchRestrictions(sFullPath, oMetaModel) {
90
+ var i = 0;
91
+ var aNavigationParts = sFullPath.split("/$NavigationPropertyBinding/");
92
+
93
+ for (var sPath = aNavigationParts[0]; i < aNavigationParts.length - 1; i++) {
94
+ var oNavigationRestrictions = getNavigationRestrictions(oMetaModel, sPath, aNavigationParts[i + 1]);
95
+
96
+ if (oNavigationRestrictions && oNavigationRestrictions["SearchRestrictions"]) {
97
+ return oNavigationRestrictions["SearchRestrictions"];
98
+ }
99
+
100
+ sPath = sPath + "/$NavigationPropertyBinding/" + aNavigationParts[i];
101
+ }
102
+
103
+ return oMetaModel.getObject(sFullPath + "@Org.OData.Capabilities.V1.SearchRestrictions");
104
+ }
105
+
106
+ function getNavigationRestrictions(oModel, sEntitySetPath, sNavigationPath) {
107
+ var oNavigationRestrictions = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.NavigationRestrictions");
108
+ var aRestrictedProperties = oNavigationRestrictions && oNavigationRestrictions.RestrictedProperties;
109
+ return aRestrictedProperties && aRestrictedProperties.find(function (oRestrictedProperty) {
110
+ return oRestrictedProperty && oRestrictedProperty.NavigationProperty && oRestrictedProperty.NavigationProperty.$NavigationPropertyPath === sNavigationPath;
111
+ });
112
+ }
113
+
114
+ function _isInNonFilterableProperties(oModel, sEntitySetPath, sContextPath) {
115
+ var bIsNotFilterable = false;
116
+ var oAnnotation = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions");
117
+
118
+ if (oAnnotation && oAnnotation.NonFilterableProperties) {
119
+ bIsNotFilterable = oAnnotation.NonFilterableProperties.some(function (property) {
120
+ return property.$NavigationPropertyPath === sContextPath || property.$PropertyPath === sContextPath;
121
+ });
122
+ }
123
+
124
+ return bIsNotFilterable;
125
+ } // TODO rework this!
126
+
127
+
128
+ function _isContextPathFilterable(oModel, sEntitySetPath, sContexPath) {
129
+ var sFullPath = sEntitySetPath + "/" + sContexPath,
130
+ aESParts = sFullPath.split("/").splice(0, 2),
131
+ aContext = sFullPath.split("/").splice(2);
132
+ var bIsNotFilterable = false,
133
+ sContext = "";
134
+ sEntitySetPath = aESParts.join("/");
135
+ bIsNotFilterable = aContext.some(function (item, index, array) {
136
+ if (sContext.length > 0) {
137
+ sContext += "/" + item;
138
+ } else {
139
+ sContext = item;
140
+ }
141
+
142
+ if (index === array.length - 2) {
143
+ // In case of "/Customer/Set/Property" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
144
+ var oNavigationRestrictions = getNavigationRestrictions(oModel, sEntitySetPath, item);
145
+ var oFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions.FilterRestrictions;
146
+ var aNonFilterableProperties = oFilterRestrictions && oFilterRestrictions.NonFilterableProperties;
147
+ var sTargetPropertyPath = array[array.length - 1];
148
+
149
+ if (aNonFilterableProperties && aNonFilterableProperties.find(function (oPropertyPath) {
150
+ return oPropertyPath.$PropertyPath === sTargetPropertyPath;
151
+ })) {
152
+ return true;
153
+ }
154
+ }
155
+
156
+ if (index === array.length - 1) {
157
+ //last path segment
158
+ bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
159
+ } else if (oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item)) {
160
+ //check existing context path and initialize it
161
+ bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
162
+ sContext = ""; //set the new EntitySet
163
+
164
+ sEntitySetPath = "/" + oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item);
165
+ }
166
+
167
+ return bIsNotFilterable === true;
168
+ });
169
+ return bIsNotFilterable;
170
+ } // TODO check used places and rework this
171
+
172
+
173
+ function isPropertyFilterable(oModel, sEntitySetPath, sProperty, bSkipHiddenFilter) {
174
+ if (typeof sProperty !== "string") {
175
+ throw new Error("sProperty parameter must be a string");
176
+ }
177
+
178
+ var bIsFilterable; // Parameters should be rendered as filterfields
179
+
180
+ if (oModel.getProperty(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
181
+ return true;
182
+ }
183
+
184
+ var oNavigationContext = oModel.createBindingContext(sEntitySetPath + "/" + sProperty);
185
+
186
+ if (oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.Hidden") === true) {
187
+ return false;
188
+ }
189
+
190
+ if (!bSkipHiddenFilter && oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.HiddenFilter")) {
191
+ return false;
192
+ }
193
+
194
+ if (sEntitySetPath.split("/").length === 2 && sProperty.indexOf("/") < 0) {
195
+ // there is no navigation in entitySet path and property path
196
+ bIsFilterable = !_isInNonFilterableProperties(oModel, sEntitySetPath, sProperty);
197
+ } else {
198
+ bIsFilterable = !_isContextPathFilterable(oModel, sEntitySetPath, sProperty);
199
+ } // check if type can be used for filtering
200
+
201
+
202
+ if (bIsFilterable && oNavigationContext) {
203
+ var sPropertyDataType = getPropertyDataType(oNavigationContext);
204
+
205
+ if (sPropertyDataType) {
206
+ bIsFilterable = aValidTypes.indexOf(sPropertyDataType) !== -1;
207
+ } else {
208
+ bIsFilterable = false;
209
+ }
210
+ }
211
+
212
+ return bIsFilterable;
213
+ }
214
+
215
+ function getShellServices(oControl) {
216
+ return getAppComponent(oControl).getShellServices();
217
+ }
218
+
219
+ function getHash() {
220
+ var sHash = window.location.hash;
221
+ return sHash.split("&")[0];
222
+ }
223
+
224
+ function _getSOIntents(oObjectPageLayout, oSemanticObject, oParam) {
225
+ var oShellServiceHelper = CommonUtils.getShellServices(oObjectPageLayout);
226
+ return oShellServiceHelper.getLinks({
227
+ semanticObject: oSemanticObject,
228
+ params: oParam
229
+ });
230
+ } // TO-DO add this as part of applySemanticObjectmappings logic in IntentBasednavigation controller extension
231
+
232
+
233
+ function _createMappings(oMapping) {
234
+ var aSOMappings = [];
235
+ var aMappingKeys = Object.keys(oMapping);
236
+ var oSemanticMapping;
237
+
238
+ for (var i = 0; i < aMappingKeys.length; i++) {
239
+ oSemanticMapping = {
240
+ "LocalProperty": {
241
+ "$PropertyPath": aMappingKeys[i]
242
+ },
243
+ "SemanticObjectProperty": oMapping[aMappingKeys[i]]
244
+ };
245
+ aSOMappings.push(oSemanticMapping);
246
+ }
247
+
248
+ return aSOMappings;
249
+ }
250
+ /**
251
+ * @param aLinks
252
+ * @param aExcludedActions
253
+ * @param oTargetParams
254
+ * @param aItems
255
+ */
256
+
257
+
258
+ function _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aItems) {
259
+ for (var i = 0; i < aLinks.length; i++) {
260
+ var oLink = aLinks[i];
261
+ var sIntent = oLink.intent;
262
+ var sAction = sIntent.split("-")[1].split("?")[0];
263
+
264
+ if (aExcludedActions && aExcludedActions.indexOf(sAction) === -1) {
265
+ aItems.push({
266
+ text: oLink.text,
267
+ targetSemObject: sIntent.split("#")[1].split("-")[0],
268
+ targetAction: sAction.split("~")[0],
269
+ targetParams: oTargetParams
270
+ });
271
+ }
272
+ }
273
+ }
274
+ /**
275
+ * @param oAdditionalSemanticObjects
276
+ * @param oBindingContext
277
+ * @param aManifestSOItems
278
+ * @param aLinks
279
+ */
280
+
281
+
282
+ function _getRelatedIntents(oAdditionalSemanticObjects, oBindingContext, aManifestSOItems, aLinks) {
283
+ if (aLinks && aLinks.length > 0) {
284
+ var aExcludedActions = oAdditionalSemanticObjects.unavailableActions ? oAdditionalSemanticObjects.unavailableActions : [];
285
+ var aSOMappings = oAdditionalSemanticObjects.mapping ? _createMappings(oAdditionalSemanticObjects.mapping) : [];
286
+ var oTargetParams = {
287
+ navigationContexts: oBindingContext,
288
+ semanticObjectMapping: aSOMappings
289
+ };
290
+
291
+ _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aManifestSOItems);
292
+ }
293
+ }
294
+
295
+ function updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath) {
296
+ var oShellServiceHelper = getShellServices(oObjectPageLayout);
297
+ var oParam = {};
298
+ var sCurrentSemObj = "",
299
+ sCurrentAction = "";
300
+ var oSemanticObjectAnnotations;
301
+ var aRelatedAppsMenuItems = [];
302
+ var aExcludedActions = [];
303
+
304
+ if (oEntry) {
305
+ if (aSemKeys && aSemKeys.length > 0) {
306
+ for (var j = 0; j < aSemKeys.length; j++) {
307
+ var sSemKey = aSemKeys[j].$PropertyPath;
308
+
309
+ if (!oParam[sSemKey]) {
310
+ oParam[sSemKey] = {
311
+ value: oEntry[sSemKey]
312
+ };
313
+ }
314
+ }
315
+ } else {
316
+ // fallback to Technical Keys if no Semantic Key is present
317
+ var aTechnicalKeys = oMetaModel.getObject(oMetaPath + "/$Type/$Key");
318
+
319
+ for (var key in aTechnicalKeys) {
320
+ var sObjKey = aTechnicalKeys[key];
321
+
322
+ if (!oParam[sObjKey]) {
323
+ oParam[sObjKey] = {
324
+ value: oEntry[sObjKey]
325
+ };
326
+ }
327
+ }
328
+ }
329
+ } // Logic to read additional SO from manifest and updated relatedapps model
330
+
331
+
332
+ var oManifestData = getTargetView(oObjectPageLayout).getViewData();
333
+ var aManifestSOItems = [];
334
+
335
+ if (oManifestData.additionalSemanticObjects) {
336
+ var aManifestSOKeys = Object.keys(oManifestData.additionalSemanticObjects);
337
+
338
+ for (var _key = 0; _key < aManifestSOKeys.length; _key++) {
339
+ _getSOIntents(oObjectPageLayout, aManifestSOKeys[_key], oParam).then(_getRelatedIntents.bind(this, oManifestData.additionalSemanticObjects[aManifestSOKeys[_key]], oBindingContext, aManifestSOItems)).catch(function (oError) {
340
+ Log.error("Error while retrieving SO Intents", oError);
341
+ });
342
+ }
343
+ }
344
+
345
+ function fnGetParseShellHashAndGetLinks() {
346
+ var oParsedUrl = oShellServiceHelper.parseShellHash(document.location.hash);
347
+ sCurrentSemObj = oParsedUrl.semanticObject; // Current Semantic Object
348
+
349
+ sCurrentAction = oParsedUrl.action;
350
+ return _getSOIntents(oObjectPageLayout, sCurrentSemObj, oParam);
351
+ }
352
+
353
+ fnGetParseShellHashAndGetLinks().then(function (aLinks) {
354
+ if (aLinks && aLinks.length > 0) {
355
+ var oTargetParams = {};
356
+ var aAnnotationsSOItems = [];
357
+ var sEntitySetPath = oMetaPath + "@";
358
+ var sEntityTypePath = oMetaPath + "/@";
359
+ var oEntitySetAnnotations = oMetaModel.getObject(sEntitySetPath);
360
+ oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntitySetAnnotations, sCurrentSemObj);
361
+
362
+ if (!oSemanticObjectAnnotations.bHasEntitySetSO) {
363
+ var oEntityTypeAnnotations = oMetaModel.getObject(sEntityTypePath);
364
+ oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntityTypeAnnotations, sCurrentSemObj);
365
+ }
366
+
367
+ aExcludedActions = oSemanticObjectAnnotations.aUnavailableActions; //Skip same application from Related Apps
368
+
369
+ aExcludedActions.push(sCurrentAction);
370
+ oTargetParams.navigationContexts = oBindingContext;
371
+ oTargetParams.semanticObjectMapping = oSemanticObjectAnnotations.aMappings;
372
+
373
+ _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aAnnotationsSOItems);
374
+
375
+ aRelatedAppsMenuItems = aAnnotationsSOItems.concat(aManifestSOItems); // If no app in list, related apps button will be hidden
376
+
377
+ oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/visibility", aRelatedAppsMenuItems.length > 0);
378
+ oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/items", aRelatedAppsMenuItems);
379
+ } else {
380
+ oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/visibility", false);
381
+ }
382
+ }).catch(function (oError) {
383
+ Log.error("Cannot read links", oError);
384
+ });
385
+ return aRelatedAppsMenuItems;
386
+ }
387
+
388
+ function _getSemanticObjectAnnotations(oEntityAnnotations, sCurrentSemObj) {
389
+ var oSemanticObjectAnnotations = {
390
+ bHasEntitySetSO: false,
391
+ aUnavailableActions: [],
392
+ aMappings: []
393
+ };
394
+ var sAnnotationMappingTerm, sAnnotationActionTerm;
395
+ var sQualifier;
396
+
397
+ for (var key in oEntityAnnotations) {
398
+ if (key.indexOf("com.sap.vocabularies.Common.v1.SemanticObject") > -1 && oEntityAnnotations[key] === sCurrentSemObj) {
399
+ oSemanticObjectAnnotations.bHasEntitySetSO = true;
400
+ sAnnotationMappingTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectMapping";
401
+ sAnnotationActionTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions";
402
+
403
+ if (key.indexOf("#") > -1) {
404
+ sQualifier = key.split("#")[1];
405
+ sAnnotationMappingTerm = sAnnotationMappingTerm + "#" + sQualifier;
406
+ sAnnotationActionTerm = sAnnotationActionTerm + "#" + sQualifier;
407
+ }
408
+
409
+ oSemanticObjectAnnotations.aMappings = oSemanticObjectAnnotations.aMappings.concat(oEntityAnnotations[sAnnotationMappingTerm]);
410
+ oSemanticObjectAnnotations.aUnavailableActions = oSemanticObjectAnnotations.aUnavailableActions.concat(oEntityAnnotations[sAnnotationActionTerm]);
411
+ break;
412
+ }
413
+ }
414
+
415
+ return oSemanticObjectAnnotations;
416
+ }
417
+
418
+ function fnUpdateRelatedAppsDetails(oObjectPageLayout) {
419
+ var oMetaModel = oObjectPageLayout.getModel().getMetaModel();
420
+ var oBindingContext = oObjectPageLayout.getBindingContext();
421
+ var oPath = oBindingContext && oBindingContext.getPath();
422
+ var oMetaPath = oMetaModel.getMetaPath(oPath); // Semantic Key Vocabulary
423
+
424
+ var sSemanticKeyVocabulary = oMetaPath + "/" + "@com.sap.vocabularies.Common.v1.SemanticKey"; //Semantic Keys
425
+
426
+ var aSemKeys = oMetaModel.getObject(sSemanticKeyVocabulary); // Unavailable Actions
427
+
428
+ var oEntry = oBindingContext.getObject();
429
+
430
+ if (!oEntry) {
431
+ oBindingContext.requestObject().then(function (oEntry) {
432
+ return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
433
+ }).catch(function (oError) {
434
+ Log.error("Cannot update the related app details", oError);
435
+ });
436
+ } else {
437
+ return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
438
+ }
439
+ }
440
+ /**
441
+ * @param oButton
442
+ */
443
+
444
+
445
+ function fnFireButtonPress(oButton) {
446
+ var aAuthorizedTypes = ["sap.m.Button", "sap.m.OverflowToolbarButton"];
447
+
448
+ if (oButton && aAuthorizedTypes.indexOf(oButton.getMetadata().getName()) !== -1 && oButton.getVisible() && oButton.getEnabled()) {
449
+ oButton.firePress();
450
+ }
451
+ }
452
+
453
+ function fnResolveStringtoBoolean(sValue) {
454
+ if (sValue === "true" || sValue === true) {
455
+ return true;
456
+ } else {
457
+ return false;
458
+ }
459
+ }
460
+
461
+ function getAppComponent(oControl) {
462
+ if (oControl.isA("sap.fe.core.AppComponent")) {
463
+ return oControl;
464
+ }
465
+
466
+ var oOwner = Component.getOwnerComponentFor(oControl);
467
+
468
+ if (!oOwner) {
469
+ return oControl;
470
+ } else {
471
+ return getAppComponent(oOwner);
472
+ }
473
+ }
474
+
475
+ function getTargetView(oControl) {
476
+ if (oControl && oControl.isA("sap.ui.core.ComponentContainer")) {
477
+ oControl = oControl.getComponentInstance();
478
+ oControl = oControl && oControl.getRootControl();
479
+ }
480
+
481
+ while (oControl && !(oControl instanceof View)) {
482
+ oControl = oControl.getParent();
483
+ }
484
+
485
+ return oControl;
486
+ }
487
+ /**
488
+ * @param fnProcessFunction
489
+ * @param fnCancelFunction
490
+ * @param oContext
491
+ * @param oController
492
+ * @param bSkipBindingToView
493
+ */
494
+
495
+
496
+ function fnProcessDataLossOrDraftDiscardConfirmation(fnProcessFunction, fnCancelFunction, oContext, oController, bSkipBindingToView) {
497
+ var oModel = oContext.getModel();
498
+ var _bIsModified = false;
499
+ var draftDataContext = oModel.bindContext(oContext.getPath() + "/DraftAdministrativeData").getBoundContext();
500
+
501
+ if (oContext && oContext.getObject() && (!oContext.getObject().DraftAdministrativeData || oContext.getObject().IsActiveEntity === true)) {
502
+ fnProcessFunction();
503
+ } else {
504
+ draftDataContext.requestObject().then(function (draftAdminData) {
505
+ if (draftAdminData) {
506
+ _bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
507
+
508
+ if (_bIsModified) {
509
+ DataLossOrDraftDiscardHandler.performAfterDiscardorKeepDraft(fnProcessFunction, fnCancelFunction, oController, bSkipBindingToView);
510
+ } else {
511
+ fnProcessFunction();
512
+ }
513
+ } else {
514
+ fnProcessFunction();
515
+ }
516
+ }).catch(function (oError) {
517
+ Log.error("Cannot retrieve draftDataContext information", oError);
518
+ });
519
+ }
520
+ }
521
+
522
+ function fnProcessDataLossConfirmation(fnProcess, oControl, programmingModel) {
523
+ var bUIEditable = oControl.getModel("ui").getProperty("/isEditable"),
524
+ oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.templates"),
525
+ sWarningMsg = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_MSG"),
526
+ sConfirmButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CONFIRM_BUTTON"),
527
+ sCancelButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CANCEL_BUTTON");
528
+
529
+ if (programmingModel === ProgrammingModel.Sticky && bUIEditable) {
530
+ return MessageBox.warning(sWarningMsg, {
531
+ actions: [sConfirmButtonTxt, sCancelButtonTxt],
532
+ onClose: function (sAction) {
533
+ if (sAction === sConfirmButtonTxt) {
534
+ var oInternalModel = oControl && oControl.getModel("internal");
535
+ Log.info("Navigation confirmed.");
536
+
537
+ if (oInternalModel) {
538
+ oInternalModel.setProperty("/sessionOn", false);
539
+ } else {
540
+ Log.warning("Local UIModel couldn't be found.");
541
+ }
542
+
543
+ fnProcess();
544
+ } else {
545
+ Log.info("Navigation rejected.");
546
+ }
547
+ }
548
+ });
549
+ }
550
+
551
+ return fnProcess();
552
+ }
553
+
554
+ function isFieldControlPathInapplicable(sFieldControlPath, oAttribute) {
555
+ var bInapplicable = false;
556
+ var aParts = sFieldControlPath.split("/"); // sensitive data is removed only if the path has already been resolved.
557
+
558
+ if (aParts.length > 1) {
559
+ bInapplicable = oAttribute[aParts[0]] && oAttribute[aParts[0]].hasOwnProperty(aParts[1]) && oAttribute[aParts[0]][aParts[1]] === 0;
560
+ } else {
561
+ bInapplicable = oAttribute[sFieldControlPath] === 0;
562
+ }
563
+
564
+ return bInapplicable;
565
+ }
566
+
567
+ function removeSensitiveData(aAttributes, oMetaModel) {
568
+ var aOutAttributes = [];
569
+
570
+ for (var i = 0; i < aAttributes.length; i++) {
571
+ var sEntitySet = aAttributes[i].entitySet,
572
+ oAttribute = aAttributes[i].contextData;
573
+ delete oAttribute["@odata.context"];
574
+ delete oAttribute["%40odata.context"];
575
+ delete oAttribute["@odata.metadataEtag"];
576
+ delete oAttribute["%40odata.metadataEtag"];
577
+ delete oAttribute["SAP__Messages"];
578
+ var aProperties = Object.keys(oAttribute);
579
+
580
+ for (var j = 0; j < aProperties.length; j++) {
581
+ var sProp = aProperties[j],
582
+ aPropertyAnnotations = oMetaModel.getObject("/" + sEntitySet + "/" + sProp + "@");
583
+
584
+ if (aPropertyAnnotations) {
585
+ if (aPropertyAnnotations["@com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive"] || aPropertyAnnotations["@com.sap.vocabularies.UI.v1.ExcludeFromNavigationContext"] || aPropertyAnnotations["@com.sap.vocabularies.Analytics.v1.Measure"]) {
586
+ delete oAttribute[sProp];
587
+ } else if (aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"]) {
588
+ var oFieldControl = aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"];
589
+
590
+ if (oFieldControl["$EnumMember"] && oFieldControl["$EnumMember"].split("/")[1] === "Inapplicable") {
591
+ delete oAttribute[sProp];
592
+ } else if (oFieldControl["$Path"] && CommonUtils.isFieldControlPathInapplicable(oFieldControl["$Path"], oAttribute)) {
593
+ delete oAttribute[sProp];
594
+ }
595
+ }
596
+ }
597
+ }
598
+
599
+ aOutAttributes.push(oAttribute);
600
+ }
601
+
602
+ return aOutAttributes;
603
+ }
604
+
605
+ function _fnCheckIsMatch(oObject, oKeysToCheck) {
606
+ for (var sKey in oKeysToCheck) {
607
+ if (oKeysToCheck[sKey] !== oObject[sKey]) {
608
+ return false;
609
+ }
610
+ }
611
+
612
+ return true;
613
+ }
614
+
615
+ function fnGetContextPathProperties(oMetaModel, sContextPath, oFilter) {
616
+ var oEntityType = oMetaModel.getObject(sContextPath + "/") || {},
617
+ oProperties = {};
618
+
619
+ for (var sKey in oEntityType) {
620
+ if (oEntityType.hasOwnProperty(sKey) && !/^\$/i.test(sKey) && oEntityType[sKey].$kind && _fnCheckIsMatch(oEntityType[sKey], oFilter || {
621
+ $kind: "Property"
622
+ })) {
623
+ oProperties[sKey] = oEntityType[sKey];
624
+ }
625
+ }
626
+
627
+ return oProperties;
628
+ }
629
+
630
+ function fnGetMandatoryFilterFields(oMetaModel, sContextPath) {
631
+ var aMandatoryFilterFields;
632
+
633
+ if (oMetaModel && sContextPath) {
634
+ aMandatoryFilterFields = oMetaModel.getObject(sContextPath + "@Org.OData.Capabilities.V1.FilterRestrictions/RequiredProperties");
635
+ }
636
+
637
+ return aMandatoryFilterFields;
638
+ }
639
+
640
+ function fnGetIBNActions(oControl, aIBNActions) {
641
+ var aActions = oControl && oControl.getActions();
642
+
643
+ if (aActions) {
644
+ aActions.forEach(function (oAction) {
645
+ if (oAction.isA("sap.ui.mdc.actiontoolbar.ActionToolbarAction")) {
646
+ oAction = oAction.getAction();
647
+ }
648
+
649
+ if (oAction.data("IBNData")) {
650
+ aIBNActions.push(oAction);
651
+ }
652
+ });
653
+ }
654
+
655
+ return aIBNActions;
656
+ }
657
+ /**
658
+ * @param aIBNActions
659
+ * @param oView
660
+ */
661
+
662
+
663
+ function fnUpdateDataFieldForIBNButtonsVisibility(aIBNActions, oView) {
664
+ var oParams = {};
665
+
666
+ var fnGetLinks = function (oData) {
667
+ if (oData) {
668
+ var aKeys = Object.keys(oData);
669
+ aKeys.forEach(function (sKey) {
670
+ if (sKey.indexOf("_") !== 0 && sKey.indexOf("odata.context") === -1) {
671
+ oParams[sKey] = {
672
+ value: oData[sKey]
673
+ };
674
+ }
675
+ });
676
+ }
677
+
678
+ if (aIBNActions.length) {
679
+ aIBNActions.forEach(function (oIBNAction) {
680
+ var sSemanticObject = oIBNAction.data("IBNData").semanticObject;
681
+ var sAction = oIBNAction.data("IBNData").action;
682
+ CommonUtils.getShellServices(oView).getLinks({
683
+ semanticObject: sSemanticObject,
684
+ action: sAction,
685
+ params: oParams
686
+ }).then(function (aLink) {
687
+ oIBNAction.setVisible(oIBNAction.getVisible() && aLink && aLink.length === 1);
688
+ }).catch(function (oError) {
689
+ Log.error("Cannot retrieve the links from the shell service", oError);
690
+ });
691
+ });
692
+ }
693
+ };
694
+
695
+ if (oView && oView.getBindingContext()) {
696
+ var _oView$getBindingCont;
697
+
698
+ (_oView$getBindingCont = oView.getBindingContext()) === null || _oView$getBindingCont === void 0 ? void 0 : _oView$getBindingCont.requestObject().then(function (oData) {
699
+ return fnGetLinks(oData);
700
+ }).catch(function (oError) {
701
+ Log.error("Cannot retrieve the links from the shell service", oError);
702
+ });
703
+ } else {
704
+ fnGetLinks();
705
+ }
706
+ }
707
+
708
+ function getTranslatedText(sFrameworkKey, oResourceBundle, oParams, sEntitySetName) {
709
+ var sResourceKey = sFrameworkKey;
710
+
711
+ if (oResourceBundle) {
712
+ if (sEntitySetName) {
713
+ // There are console errors logged when making calls to getText for keys that are not defined in the resource bundle
714
+ // for instance keys which are supposed to be provided by the application, e.g, <key>|<entitySet> to override instance specific text
715
+ // hence check if text exists (using "hasText") in the resource bundle before calling "getText"
716
+ // "hasText" only checks for the key in the immediate resource bundle and not it's custom bundles
717
+ // hence we need to do this recurrsively to check if the key exists in any of the bundles the forms the FE resource bundle
718
+ var bResourceKeyExists = _checkIfResourceKeyExists(oResourceBundle.aCustomBundles, sFrameworkKey + "|" + sEntitySetName); // if resource key with entity set name for instance specific text overriding is provided by the application
719
+ // then use the same key otherwise use the Framework key
720
+
721
+
722
+ sResourceKey = bResourceKeyExists ? sFrameworkKey + "|" + sEntitySetName : sFrameworkKey;
723
+ }
724
+
725
+ return oResourceBundle.getText(sResourceKey, oParams);
726
+ } // do not allow override so get text from the internal bundle directly
727
+
728
+
729
+ oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
730
+ return oResourceBundle.getText(sResourceKey, oParams);
731
+ }
732
+
733
+ function _checkIfResourceKeyExists(aCustomBundles, sKey) {
734
+ if (aCustomBundles.length) {
735
+ for (var i = aCustomBundles.length - 1; i >= 0; i--) {
736
+ var sValue = aCustomBundles[i].hasText(sKey); // text found return true
737
+
738
+ if (sValue) {
739
+ return true;
740
+ }
741
+
742
+ _checkIfResourceKeyExists(aCustomBundles[i].aCustomBundles, sKey);
743
+ }
744
+ }
745
+
746
+ return false;
747
+ }
748
+
749
+ function getActionPath(oAction, bReturnOnlyPath, sActionName, bCheckStaticValue) {
750
+ sActionName = !sActionName ? oAction.getObject(oAction.getPath()) : sActionName;
751
+ var sContextPath = oAction.getPath().split("/@")[0];
752
+ var sEntityTypeName = oAction.getObject(sContextPath).$Type;
753
+ var sEntityName = getEntitySetName(oAction.getModel(), sEntityTypeName);
754
+
755
+ if (sEntityName) {
756
+ sContextPath = "/" + sEntityName;
757
+ }
758
+
759
+ if (bCheckStaticValue) {
760
+ return oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable");
761
+ }
762
+
763
+ if (bReturnOnlyPath) {
764
+ return sContextPath + "/" + sActionName;
765
+ } else {
766
+ return {
767
+ sContextPath: sContextPath,
768
+ sProperty: oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable/$Path"),
769
+ sBindingParameter: oAction.getObject(sContextPath + "/" + sActionName + "/@$ui5.overload/0/$Parameter/0/$Name")
770
+ };
771
+ }
772
+ }
773
+
774
+ function getEntitySetName(oMetaModel, sEntityType) {
775
+ var oEntityContainer = oMetaModel.getObject("/");
776
+
777
+ for (var key in oEntityContainer) {
778
+ if (typeof oEntityContainer[key] === "object" && oEntityContainer[key].$Type === sEntityType) {
779
+ return key;
780
+ }
781
+ }
782
+ }
783
+
784
+ function computeDisplayMode(oPropertyAnnotations, oCollectionAnnotations) {
785
+ var oTextAnnotation = oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text"],
786
+ oTextArrangementAnnotation = oTextAnnotation && (oPropertyAnnotations && oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text@com.sap.vocabularies.UI.v1.TextArrangement"] || oCollectionAnnotations && oCollectionAnnotations["@com.sap.vocabularies.UI.v1.TextArrangement"]);
787
+
788
+ if (oTextArrangementAnnotation) {
789
+ if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextOnly") {
790
+ return "Description";
791
+ } else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextLast") {
792
+ return "ValueDescription";
793
+ } else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextSeparate") {
794
+ return "Value";
795
+ } //Default should be TextFirst if there is a Text annotation and neither TextOnly nor TextLast are set
796
+
797
+
798
+ return "DescriptionValue";
799
+ }
800
+
801
+ return oTextAnnotation ? "DescriptionValue" : "Value";
802
+ }
803
+
804
+ function _getEntityType(oContext) {
805
+ var oMetaModel = oContext.getModel().getMetaModel();
806
+ return oMetaModel.getObject(oMetaModel.getMetaPath(oContext.getPath()) + "/$Type");
807
+ }
808
+
809
+ function _requestObject(sAction, oSelectedContext, sProperty) {
810
+ var oContext = oSelectedContext;
811
+ var nBracketIndex = sAction.indexOf("(");
812
+
813
+ if (nBracketIndex > -1) {
814
+ var sTargetType = sAction.slice(nBracketIndex + 1, -1);
815
+
816
+ var sCurrentType = _getEntityType(oContext);
817
+
818
+ while (sCurrentType !== sTargetType) {
819
+ // Find parent binding context and retrieve entity type
820
+ oContext = oContext.getBinding().getContext();
821
+
822
+ if (oContext) {
823
+ sCurrentType = _getEntityType(oContext);
824
+ } else {
825
+ Log.warning("Cannot determine target type to request property value for bound action invocation");
826
+ return Promise.resolve(undefined);
827
+ }
828
+ }
829
+ }
830
+
831
+ return oContext.requestObject(sProperty);
832
+ }
833
+
834
+ function _requestProperty(oSelectedContext, sAction, sProperty, sDynamicActionEnabledPath) {
835
+ var oPromise = sProperty && sProperty.indexOf("/") === 0 ? requestSingletonProperty(sProperty, oSelectedContext.getModel()) : _requestObject(sAction, oSelectedContext, sProperty);
836
+ return oPromise.then(function (vPropertyValue) {
837
+ return Promise.resolve({
838
+ vPropertyValue: vPropertyValue,
839
+ oSelectedContext: oSelectedContext,
840
+ sAction: sAction,
841
+ sDynamicActionEnabledPath: sDynamicActionEnabledPath
842
+ });
843
+ });
844
+ }
845
+
846
+ function _setContextsBasedOnOperationAvailable(oInternalModelContext, aRequestPromises) {
847
+ return Promise.all(aRequestPromises).then(function (aResults) {
848
+ if (aResults.length) {
849
+ var aApplicableContexts = [],
850
+ aNotApplicableContexts = [];
851
+ aResults.forEach(function (aResult) {
852
+ if (aResult) {
853
+ if (aResult.vPropertyValue) {
854
+ oInternalModelContext.getModel().setProperty(aResult.sDynamicActionEnabledPath, true);
855
+ aApplicableContexts.push(aResult.oSelectedContext);
856
+ } else {
857
+ aNotApplicableContexts.push(aResult.oSelectedContext);
858
+ }
859
+ }
860
+ });
861
+
862
+ _setDynamicActionContexts(oInternalModelContext, aResults[0].sAction, aApplicableContexts, aNotApplicableContexts);
863
+ }
864
+ }).catch(function (oError) {
865
+ Log.trace("Cannot retrieve property value from path", oError);
866
+ });
867
+ }
868
+ /**
869
+ * @param oInternalModelContext
870
+ * @param sAction
871
+ * @param aApplicable
872
+ * @param aNotApplicable
873
+ */
874
+
875
+
876
+ function _setDynamicActionContexts(oInternalModelContext, sAction, aApplicable, aNotApplicable) {
877
+ var sDynamicActionPathPrefix = oInternalModelContext.getPath() + "/dynamicActions/" + sAction,
878
+ oInternalModel = oInternalModelContext.getModel();
879
+ oInternalModel.setProperty(sDynamicActionPathPrefix + "/aApplicable", aApplicable);
880
+ oInternalModel.setProperty(sDynamicActionPathPrefix + "/aNotApplicable", aNotApplicable);
881
+ }
882
+
883
+ function setActionEnablement(oInternalModelContext, oActionOperationAvailableMap, aSelectedContexts) {
884
+ var aPromises = [];
885
+
886
+ for (var sAction in oActionOperationAvailableMap) {
887
+ // Reset all properties before computation
888
+ oInternalModelContext.setProperty("dynamicActions/" + sAction, {
889
+ bEnabled: false,
890
+ aApplicable: [],
891
+ aNotApplicable: []
892
+ }); // Note that non dynamic actions are not processed here. They are enabled because
893
+ // one or more are selected and the second part of the condition in the templating
894
+ // is then undefined and thus the button takes the default enabling, which is true!
895
+
896
+ var aApplicable = [],
897
+ aNotApplicable = [],
898
+ sProperty = oActionOperationAvailableMap[sAction],
899
+ sDynamicActionEnabledPath = oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled";
900
+
901
+ if (typeof sProperty === "object" && sProperty !== null && sProperty !== undefined) {
902
+ for (var i = 0; i < aSelectedContexts.length; i++) {
903
+ var oSelectedContext = aSelectedContexts[i];
904
+
905
+ if (oSelectedContext) {
906
+ (function () {
907
+ var oContextData = oSelectedContext.getObject();
908
+ var oTransformedBinding = transformRecursively(sProperty, "Binding", // eslint-disable-next-line no-loop-func
909
+ function (oBindingExpression) {
910
+ return constant(oContextData[oBindingExpression.path]);
911
+ }, true);
912
+ var sResult = compileBinding(oTransformedBinding);
913
+
914
+ if (sResult === "true") {
915
+ oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
916
+ aApplicable.push(oSelectedContext);
917
+ } else {
918
+ aNotApplicable.push(oSelectedContext);
919
+ }
920
+ })();
921
+ }
922
+ }
923
+
924
+ _setDynamicActionContexts(oInternalModelContext, sAction, aApplicable, aNotApplicable);
925
+ } else {
926
+ var aRequestPromises = [];
927
+
928
+ for (var _i = 0; _i < aSelectedContexts.length; _i++) {
929
+ var _oSelectedContext = aSelectedContexts[_i];
930
+
931
+ if (_oSelectedContext) {
932
+ var oContextData = _oSelectedContext.getObject();
933
+
934
+ if (sProperty === null && !!oContextData["#" + sAction]) {
935
+ //look for action advertisement if present and its value is not null
936
+ oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
937
+ break;
938
+ } else {
939
+ // Collect promises to retrieve singleton or normal property value asynchronously
940
+ aRequestPromises.push(_requestProperty(_oSelectedContext, sAction, sProperty, sDynamicActionEnabledPath));
941
+ }
942
+ }
943
+ } // When all property values have been retrieved, set
944
+ // The applicable and not-applicable selected contexts for each action and
945
+ // The enabled property of the dynamic action in internal model context.
946
+
947
+
948
+ aPromises.push(_setContextsBasedOnOperationAvailable(oInternalModelContext, aRequestPromises));
949
+ }
950
+ }
951
+
952
+ return Promise.all(aPromises);
953
+ }
954
+
955
+ function _getDefaultOperators(oRealProperty) {
956
+ // mdc defines the full set of operations that are meaningful for each Edm Type
957
+ var oDataClass = TypeUtil.getDataTypeClassName(oRealProperty);
958
+ var oBaseType = TypeUtil.getBaseType(oDataClass);
959
+ return FilterOperatorUtil.getOperatorsForType(oBaseType);
960
+ }
961
+
962
+ function _getRestrictions(aDefaultOps, aExpressionOps) {
963
+ // From the default set of Operators for the Base Type, select those that are defined in the Allowed Value.
964
+ // In case that no operators are found, return undefined so that the default set is used.
965
+ var aOperators = aDefaultOps.filter(function (sElement) {
966
+ return aExpressionOps.indexOf(sElement) > -1;
967
+ });
968
+ return aOperators.toString() || undefined;
969
+ }
970
+
971
+ function getSpecificAllowedExpression(aExpressions) {
972
+ var aAllowedExpressionsPriority = CommonUtils.AllowedExpressionsPrio;
973
+ aExpressions.sort(function (a, b) {
974
+ return aAllowedExpressionsPriority.indexOf(a) - aAllowedExpressionsPriority.indexOf(b);
975
+ });
976
+ return aExpressions[0];
977
+ }
978
+
979
+ function getOperatorsForProperty(sProperty, sEntitySetPath, oContext, sType, bUseSemanticDateRange, sSettings) {
980
+ var oFilterRestrictions = CommonUtils.getFilterRestrictionsByPath(sEntitySetPath, oContext);
981
+ var aEqualsOps = ["EQ"];
982
+ var aSingleRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
983
+ var aSingleValueDateOps = ["TODAY", "TOMORROW", "YESTERDAY", "DATE"];
984
+ var aMultiRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NE", "NOTBT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
985
+ var aSearchExpressionOps = ["Contains", "NotContains", "StartsWith", "NotStartsWith", "EndsWith", "NotEndsWith"];
986
+ var aSemanticDateOpsExt = SemanticDateOperators.getSupportedOperations();
987
+ var bSemanticDateRange = bUseSemanticDateRange === "true" || bUseSemanticDateRange === true;
988
+ var aSemanticDateOps = [];
989
+ var oSettings = typeof sSettings === "string" ? JSON.parse(sSettings).customData : sSettings;
990
+
991
+ if (oContext.getObject(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
992
+ return aEqualsOps.toString();
993
+ }
994
+
995
+ if (oSettings && oSettings.operatorConfiguration && oSettings.operatorConfiguration.length > 0) {
996
+ aSemanticDateOps = SemanticDateOperators.getFilterOperations(oSettings.operatorConfiguration);
997
+ } else {
998
+ aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
999
+ } // Get the default Operators for this Property Type
1000
+
1001
+
1002
+ var aDefaultOperators = _getDefaultOperators(sType); // Is there a Filter Restriction defined for this property?
1003
+
1004
+
1005
+ if (oFilterRestrictions && oFilterRestrictions.FilterAllowedExpressions && oFilterRestrictions.FilterAllowedExpressions[sProperty]) {
1006
+ // Extending the default operators list with Semantic Date options DATERANGE, DATE, FROM and TO
1007
+ if (bSemanticDateRange) {
1008
+ aDefaultOperators = aSemanticDateOpsExt.concat(aDefaultOperators);
1009
+ }
1010
+
1011
+ var sAllowedExpression = CommonUtils.getSpecificAllowedExpression(oFilterRestrictions.FilterAllowedExpressions[sProperty]);
1012
+ var sRestrictions; // In case more than one Allowed Expressions has been defined for a property
1013
+ // choose the most restrictive Allowed Expression
1014
+ // MultiValue has same Operator as SingleValue, but there can be more than one (maxConditions)
1015
+
1016
+ switch (sAllowedExpression) {
1017
+ case "SingleValue":
1018
+ var aSingleValueOps = sType === "Edm.Date" && bSemanticDateRange ? aSingleValueDateOps : aEqualsOps;
1019
+ sRestrictions = _getRestrictions(aDefaultOperators, aSingleValueOps);
1020
+ break;
1021
+
1022
+ case "MultiValue":
1023
+ sRestrictions = _getRestrictions(aDefaultOperators, aEqualsOps);
1024
+ break;
1025
+
1026
+ case "SingleRange":
1027
+ var sOperators = _getRestrictions(aDefaultOperators, sType === "Edm.Date" && bSemanticDateRange ? aSemanticDateOps : aSingleRangeOps);
1028
+
1029
+ sRestrictions = sOperators ? sOperators : "";
1030
+ break;
1031
+
1032
+ case "MultiRange":
1033
+ sRestrictions = _getRestrictions(aDefaultOperators, aMultiRangeOps);
1034
+ break;
1035
+
1036
+ case "SearchExpression":
1037
+ sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps);
1038
+ break;
1039
+
1040
+ case "MultiRangeOrSearchExpression":
1041
+ sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps.concat(aMultiRangeOps));
1042
+ break;
1043
+
1044
+ default:
1045
+ break;
1046
+ } // In case AllowedExpressions is not recognised, undefined in return results in the default set of
1047
+ // operators for the type.
1048
+
1049
+
1050
+ return sRestrictions;
1051
+ } else if (sType === "Edm.Date") {
1052
+ // In case AllowedExpressions is not provided for type Edm.Date then all the default
1053
+ // operators for the type should be returned excluding semantic operators from the list.
1054
+ aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
1055
+ var aOperators = aDefaultOperators.filter(function (sElement) {
1056
+ return aSemanticDateOps.indexOf(sElement) < 0;
1057
+ });
1058
+ return aOperators.toString();
1059
+ }
1060
+ }
1061
+
1062
+ function getParameterInfo(oMetaModel, sContextPath) {
1063
+ var sParameterContextPath = sContextPath.substring(0, sContextPath.lastIndexOf("/"));
1064
+ var bResultContext = oMetaModel.getObject(sParameterContextPath + "/@com.sap.vocabularies.Common.v1.ResultContext");
1065
+ var oParameterInfo = {};
1066
+
1067
+ if (bResultContext && sParameterContextPath !== sContextPath) {
1068
+ oParameterInfo.contextPath = sParameterContextPath;
1069
+ oParameterInfo.parameterProperties = CommonUtils.getContextPathProperties(oMetaModel, sParameterContextPath);
1070
+ }
1071
+
1072
+ return oParameterInfo;
1073
+ }
1074
+
1075
+ function addSelectOptionToConditions(oPropertyMetadata, aValidOperators, aCumulativeConditions, oSelectOption) {
1076
+ var oCondition = getConditions(oSelectOption, oPropertyMetadata);
1077
+
1078
+ if (oCondition) {
1079
+ if (!aValidOperators || aValidOperators.indexOf(oCondition.operator) > -1) {
1080
+ aCumulativeConditions.push(oCondition);
1081
+ }
1082
+ }
1083
+
1084
+ return aCumulativeConditions;
1085
+ }
1086
+ /**
1087
+ * @param sContextPath
1088
+ * @param oSelectionVariant
1089
+ * @param sSelectOptionProp
1090
+ * @param oConditions
1091
+ * @param sConditionPath
1092
+ * @param sConditionProp
1093
+ * @param oValidProperties
1094
+ * @param oMetaModel
1095
+ * @param isParameter
1096
+ */
1097
+
1098
+
1099
+ function addSelectOptionsToConditions(sContextPath, oSelectionVariant, sSelectOptionProp, oConditions, sConditionPath, sConditionProp, oValidProperties, oMetaModel, isParameter) {
1100
+ var aConditions = [],
1101
+ aSelectOptions,
1102
+ aValidOperators;
1103
+
1104
+ if (isParameter || CommonUtils.isPropertyFilterable(oMetaModel, sContextPath, sConditionProp, true)) {
1105
+ aSelectOptions = oSelectionVariant.getSelectOption(sSelectOptionProp);
1106
+ aValidOperators = isParameter ? ["EQ"] : CommonUtils.getOperatorsForProperty(sConditionProp, sContextPath, oMetaModel);
1107
+ var oPropertyMetadata = oValidProperties[sConditionProp]; // Create conditions for all the selectOptions of the property
1108
+
1109
+ aConditions = isParameter ? addSelectOptionToConditions(oPropertyMetadata, aValidOperators, aConditions, aSelectOptions[0]) : aSelectOptions.reduce(addSelectOptionToConditions.bind(null, oPropertyMetadata, aValidOperators), aConditions);
1110
+
1111
+ if (aConditions.length) {
1112
+ if (sConditionPath) {
1113
+ oConditions[sConditionPath + sConditionProp] = oConditions.hasOwnProperty(sConditionPath + sConditionProp) ? oConditions[sConditionPath + sConditionProp].concat(aConditions) : aConditions;
1114
+ } else {
1115
+ oConditions[sConditionProp] = oConditions.hasOwnProperty(sConditionProp) ? oConditions[sConditionProp].concat(aConditions) : aConditions;
1116
+ }
1117
+ }
1118
+ }
1119
+ }
1120
+
1121
+ function addSelectionVariantToConditions(oSelectionVariant, oConditions, oMetaModel, sContextPath) {
1122
+ var aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames(),
1123
+ oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sContextPath),
1124
+ aMetadatProperties = Object.keys(oValidProperties),
1125
+ oParameterInfo = CommonUtils.getParameterInfo(oMetaModel, sContextPath),
1126
+ sParameterContextPath = oParameterInfo.contextPath,
1127
+ oValidParameterProperties = oParameterInfo.parameterProperties,
1128
+ bHasParameters = !!oParameterInfo.contextPath && oValidParameterProperties && Object.keys(oValidParameterProperties).length > 0;
1129
+
1130
+ if (bHasParameters) {
1131
+ var aMetadataParameters = Object.keys(oValidParameterProperties);
1132
+ aMetadataParameters.forEach(function (sMetadataParameter) {
1133
+ var sSelectOptionName;
1134
+
1135
+ if (aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter)) {
1136
+ sSelectOptionName = "$Parameter." + sMetadataParameter;
1137
+ } else if (aSelectOptionsPropertyNames.includes(sMetadataParameter)) {
1138
+ sSelectOptionName = sMetadataParameter;
1139
+ } else if (sMetadataParameter.startsWith("P_") && aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length))) {
1140
+ sSelectOptionName = "$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length);
1141
+ } else if (sMetadataParameter.startsWith("P_") && aSelectOptionsPropertyNames.includes(sMetadataParameter.slice(2, sMetadataParameter.length))) {
1142
+ sSelectOptionName = sMetadataParameter.slice(2, sMetadataParameter.length);
1143
+ } else if (aSelectOptionsPropertyNames.includes("$Parameter.P_" + sMetadataParameter)) {
1144
+ sSelectOptionName = "$Parameter.P_" + sMetadataParameter;
1145
+ } else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataParameter)) {
1146
+ sSelectOptionName = "P_" + sMetadataParameter;
1147
+ }
1148
+
1149
+ if (sSelectOptionName) {
1150
+ addSelectOptionsToConditions(sParameterContextPath, oSelectionVariant, sSelectOptionName, oConditions, undefined, sMetadataParameter, oValidParameterProperties, oMetaModel, true);
1151
+ }
1152
+ });
1153
+ }
1154
+
1155
+ aMetadatProperties.forEach(function (sMetadataProperty) {
1156
+ var sSelectOptionName;
1157
+
1158
+ if (aSelectOptionsPropertyNames.includes(sMetadataProperty)) {
1159
+ sSelectOptionName = sMetadataProperty;
1160
+ } else if (sMetadataProperty.startsWith("P_") && aSelectOptionsPropertyNames.includes(sMetadataProperty.slice(2, sMetadataProperty.length))) {
1161
+ sSelectOptionName = sMetadataProperty.slice(2, sMetadataProperty.length);
1162
+ } else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataProperty)) {
1163
+ sSelectOptionName = "P_" + sMetadataProperty;
1164
+ }
1165
+
1166
+ if (sSelectOptionName) {
1167
+ addSelectOptionsToConditions(sContextPath, oSelectionVariant, sSelectOptionName, oConditions, undefined, sMetadataProperty, oValidProperties, oMetaModel, false);
1168
+ }
1169
+ });
1170
+ aSelectOptionsPropertyNames.forEach(function (sSelectOption) {
1171
+ if (sSelectOption.indexOf(".") > 0 && !sSelectOption.includes("$Parameter")) {
1172
+ var sFullContextPath = ("/" + sSelectOption.replaceAll(".", "/")).startsWith(sContextPath) ? "/" + sSelectOption.replaceAll(".", "/") : sContextPath + "/" + sSelectOption.replaceAll(".", "/"); // check if the full path, eg SalesOrderManage._Item.Material exists in the metamodel
1173
+
1174
+ if (oMetaModel.getObject(sFullContextPath.replace("P_", ""))) {
1175
+ _createConditionsForNavProperties(sFullContextPath, sContextPath, oSelectionVariant, sSelectOption, oMetaModel, oConditions);
1176
+ }
1177
+ }
1178
+ });
1179
+ return oConditions;
1180
+ }
1181
+ /**
1182
+ * @param sFullContextPath
1183
+ * @param sMainEntitySetPath
1184
+ * @param oSelectionVariant
1185
+ * @param sSelectOption
1186
+ * @param oMetaModel
1187
+ * @param oConditions
1188
+ */
1189
+
1190
+
1191
+ function _createConditionsForNavProperties(sFullContextPath, sMainEntitySetPath, oSelectionVariant, sSelectOption, oMetaModel, oConditions) {
1192
+ var aNavObjectNames = sSelectOption.split("."); // Eg: "SalesOrderManage._Item._Material.Material" or "_Item.Material"
1193
+
1194
+ if (("/" + sSelectOption.replaceAll(".", "/")).startsWith(sMainEntitySetPath)) {
1195
+ var sFullPath = ("/" + sSelectOption).replaceAll(".", "/"),
1196
+ sNavPath = sFullPath.replace(sMainEntitySetPath + "/", "");
1197
+ aNavObjectNames = sNavPath.split("/");
1198
+ }
1199
+
1200
+ var sConditionPath = "";
1201
+ var sPropertyName = aNavObjectNames[aNavObjectNames.length - 1]; // Material from SalesOrderManage._Item.Material
1202
+
1203
+ for (var i = 0; i < aNavObjectNames.length - 1; i++) {
1204
+ if (oMetaModel.getObject(sMainEntitySetPath + "/" + aNavObjectNames[i].replace("P_", "")).$isCollection) {
1205
+ sConditionPath = sConditionPath + aNavObjectNames[i] + "*/"; // _Item*/ in case of 1:n cardinality
1206
+ } else {
1207
+ sConditionPath = sConditionPath + aNavObjectNames[i] + "/"; // _Item/ in case of 1:1 cardinality
1208
+ }
1209
+
1210
+ sMainEntitySetPath = sMainEntitySetPath + "/" + aNavObjectNames[i];
1211
+ }
1212
+
1213
+ var sNavPropertyPath = sFullContextPath.slice(0, sFullContextPath.lastIndexOf("/")),
1214
+ oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sNavPropertyPath),
1215
+ aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames();
1216
+ var sSelectOptionName = sPropertyName;
1217
+
1218
+ if (oValidProperties[sPropertyName]) {
1219
+ sSelectOptionName = sPropertyName;
1220
+ } else if (sPropertyName.startsWith("P_") && oValidProperties[sPropertyName.replace("P_", "")]) {
1221
+ sSelectOptionName = sPropertyName.replace("P_", "");
1222
+ } else if (oValidProperties["P_" + sPropertyName] && aSelectOptionsPropertyNames.includes("P_" + sPropertyName)) {
1223
+ sSelectOptionName = "P_" + sPropertyName;
1224
+ }
1225
+
1226
+ if (sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1227
+ // if there is no SalesOrderManage._Item.Material yet in the oConditions
1228
+ return;
1229
+ } else if (!sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1230
+ delete oConditions[sConditionPath + sSelectOptionName];
1231
+ addSelectOptionsToConditions(sNavPropertyPath, oSelectionVariant, sSelectOption, oConditions, sConditionPath, sSelectOptionName, oValidProperties, oMetaModel, false);
1232
+ } else {
1233
+ addSelectOptionsToConditions(sNavPropertyPath, oSelectionVariant, sSelectOption, oConditions, sConditionPath, sSelectOptionName, oValidProperties, oMetaModel, false);
1234
+ }
1235
+ }
1236
+
1237
+ function addPageContextToSelectionVariant(oSelectionVariant, mPageContext, oView) {
1238
+ var oAppComponent = CommonUtils.getAppComponent(oView);
1239
+ var oNavigationService = oAppComponent.getNavigationService();
1240
+ return oNavigationService.mixAttributesAndSelectionVariant(mPageContext, oSelectionVariant.toJSONString());
1241
+ }
1242
+
1243
+ function addExternalStateFiltersToSelectionVariant(oSelectionVariant, mFilters, oTargetInfo, oFilterInfo) {
1244
+ var sFilter,
1245
+ sLow = "",
1246
+ sHigh = null;
1247
+
1248
+ var fnGetSignAndOption = function (sOperator, sLowValue, sHighValue) {
1249
+ var oSelectOptionState = {
1250
+ option: "",
1251
+ sign: "I",
1252
+ low: sLowValue,
1253
+ high: sHighValue
1254
+ };
1255
+
1256
+ switch (sOperator) {
1257
+ case "Contains":
1258
+ oSelectOptionState.option = "CP";
1259
+ break;
1260
+
1261
+ case "StartsWith":
1262
+ oSelectOptionState.option = "CP";
1263
+ oSelectOptionState.low += "*";
1264
+ break;
1265
+
1266
+ case "EndsWith":
1267
+ oSelectOptionState.option = "CP";
1268
+ oSelectOptionState.low = "*" + oSelectOptionState.low;
1269
+ break;
1270
+
1271
+ case "BT":
1272
+ case "LE":
1273
+ case "LT":
1274
+ case "GT":
1275
+ case "NE":
1276
+ case "EQ":
1277
+ oSelectOptionState.option = sOperator;
1278
+ break;
1279
+
1280
+ case "TODAY":
1281
+ case "DATE":
1282
+ oSelectOptionState.option = "EQ";
1283
+ break;
1284
+
1285
+ case "EEQ":
1286
+ oSelectOptionState.option = "EQ";
1287
+ break;
1288
+
1289
+ case "Empty":
1290
+ oSelectOptionState.option = "EQ";
1291
+ oSelectOptionState.low = "";
1292
+ break;
1293
+
1294
+ case "NotContains":
1295
+ oSelectOptionState.option = "CP";
1296
+ oSelectOptionState.sign = "E";
1297
+ break;
1298
+
1299
+ case "NOTBT":
1300
+ oSelectOptionState.option = "BT";
1301
+ oSelectOptionState.sign = "E";
1302
+ break;
1303
+
1304
+ case "NotStartsWith":
1305
+ oSelectOptionState.option = "CP";
1306
+ oSelectOptionState.low += "*";
1307
+ oSelectOptionState.sign = "E";
1308
+ break;
1309
+
1310
+ case "NotEndsWith":
1311
+ oSelectOptionState.option = "CP";
1312
+ oSelectOptionState.low = "*" + oSelectOptionState.low;
1313
+ oSelectOptionState.sign = "E";
1314
+ break;
1315
+
1316
+ case "NotEmpty":
1317
+ oSelectOptionState.option = "NE";
1318
+ oSelectOptionState.low = "";
1319
+ break;
1320
+
1321
+ case "NOTLE":
1322
+ oSelectOptionState.option = "LE";
1323
+ oSelectOptionState.sign = "E";
1324
+ break;
1325
+
1326
+ case "NOTGE":
1327
+ oSelectOptionState.option = "GE";
1328
+ oSelectOptionState.sign = "E";
1329
+ break;
1330
+
1331
+ case "NOTLT":
1332
+ oSelectOptionState.option = "LT";
1333
+ oSelectOptionState.sign = "E";
1334
+ break;
1335
+
1336
+ case "NOTGT":
1337
+ oSelectOptionState.option = "GT";
1338
+ oSelectOptionState.sign = "E";
1339
+ break;
1340
+
1341
+ default:
1342
+ Log.warning(sOperator + " is not supported. " + sFilter + " could not be added to the navigation context");
1343
+ }
1344
+
1345
+ return oSelectOptionState;
1346
+ };
1347
+
1348
+ var oFilterConditions = mFilters.filterConditions;
1349
+ var oFiltersWithoutConflict = mFilters.filterConditionsWithoutConflict ? mFilters.filterConditionsWithoutConflict : {};
1350
+ var oTablePropertiesWithoutConflict = oTargetInfo.propertiesWithoutConflict ? oTargetInfo.propertiesWithoutConflict : {};
1351
+
1352
+ var addFiltersToSelectionVariant = function (oSelectionVariant, sFilterName, sPath) {
1353
+ var aFilters = oFilterConditions[sFilterName];
1354
+
1355
+ for (var item in aFilters) {
1356
+ var oFilter = aFilters[item];
1357
+ sLow = oFilter.values[0] && oFilter.values[0].toString() || "";
1358
+ sHigh = oFilter.values[1] && oFilter.values[1].toString() || null;
1359
+
1360
+ if (oFilter.operator === "TODAY" || oFilter.operator === "DATE") {
1361
+ var aFilter = oFilterInfo[0].aFilters.filter(function (oFilter) {
1362
+ return oFilter.sPath === sFilterName;
1363
+ });
1364
+ sLow = aFilter[0].oValue1 || "";
1365
+ sHigh = null;
1366
+ }
1367
+
1368
+ var oSelectOptionValues = fnGetSignAndOption(oFilter.operator, sLow, sHigh);
1369
+
1370
+ if (oSelectOptionValues.option) {
1371
+ oSelectionVariant.addSelectOption(sPath ? sPath : sFilterName, oSelectOptionValues.sign, oSelectOptionValues.option, oSelectOptionValues.low, oSelectOptionValues.high);
1372
+ }
1373
+ }
1374
+ };
1375
+
1376
+ for (sFilter in oFilterConditions) {
1377
+ // only add the filter values if it is not already present in the SV already
1378
+ if (!oSelectionVariant.getSelectOption(sFilter)) {
1379
+ // TODO : custom filters should be ignored more generically
1380
+ if (sFilter === "$editState") {
1381
+ continue;
1382
+ }
1383
+
1384
+ addFiltersToSelectionVariant(oSelectionVariant, sFilter);
1385
+ } else {
1386
+ if (oTablePropertiesWithoutConflict && sFilter in oTablePropertiesWithoutConflict) {
1387
+ addFiltersToSelectionVariant(oSelectionVariant, sFilter, oTablePropertiesWithoutConflict[sFilter]);
1388
+ } // if property was without conflict in page context then add path from page context to SV
1389
+
1390
+
1391
+ if (sFilter in oFiltersWithoutConflict) {
1392
+ addFiltersToSelectionVariant(oSelectionVariant, sFilter, oFiltersWithoutConflict[sFilter]);
1393
+ }
1394
+ }
1395
+ }
1396
+
1397
+ return oSelectionVariant;
1398
+ }
1399
+
1400
+ function isStickyEditMode(oControl) {
1401
+ var bIsStickyMode = ModelHelper.isStickySessionSupported(oControl.getModel().getMetaModel());
1402
+ var bUIEditable = oControl.getModel("ui").getProperty("/isEditable");
1403
+ return bIsStickyMode && bUIEditable;
1404
+ }
1405
+ /**
1406
+ * @param aMandatoryFilterFields
1407
+ * @param oSelectionVariant
1408
+ * @param oSelectionVariantDefaults
1409
+ */
1410
+
1411
+
1412
+ function addDefaultDisplayCurrency(aMandatoryFilterFields, oSelectionVariant, oSelectionVariantDefaults) {
1413
+ if (oSelectionVariant && aMandatoryFilterFields && aMandatoryFilterFields.length) {
1414
+ for (var i = 0; i < aMandatoryFilterFields.length; i++) {
1415
+ var aSVOption = oSelectionVariant.getSelectOption("DisplayCurrency"),
1416
+ aDefaultSVOption = oSelectionVariantDefaults && oSelectionVariantDefaults.getSelectOption("DisplayCurrency");
1417
+
1418
+ if (aMandatoryFilterFields[i].$PropertyPath === "DisplayCurrency" && (!aSVOption || !aSVOption.length) && aDefaultSVOption && aDefaultSVOption.length) {
1419
+ var displayCurrencySelectOption = aDefaultSVOption[0];
1420
+ var sSign = displayCurrencySelectOption["Sign"];
1421
+ var sOption = displayCurrencySelectOption["Option"];
1422
+ var sLow = displayCurrencySelectOption["Low"];
1423
+ var sHigh = displayCurrencySelectOption["High"];
1424
+ oSelectionVariant.addSelectOption("DisplayCurrency", sSign, sOption, sLow, sHigh);
1425
+ }
1426
+ }
1427
+ }
1428
+ }
1429
+
1430
+ function getNonComputedVisibleFields(oMetaModel, sPath, oView) {
1431
+ var aTechnicalKeys = oMetaModel.getObject(sPath + "/").$Key;
1432
+ var aNonComputedVisibleFields = [];
1433
+ var oEntityType = oMetaModel.getObject(sPath + "/");
1434
+
1435
+ for (var item in oEntityType) {
1436
+ if (oEntityType[item].$kind && oEntityType[item].$kind === "Property") {
1437
+ var oAnnotations = oMetaModel.getObject(sPath + "/" + item + "@") || {},
1438
+ bIsKey = aTechnicalKeys.indexOf(item) > -1,
1439
+ bIsImmutable = oAnnotations["@Org.OData.Core.V1.Immutable"],
1440
+ bIsNonComputed = !oAnnotations["@Org.OData.Core.V1.Computed"],
1441
+ bIsVisible = !oAnnotations["@com.sap.vocabularies.UI.v1.Hidden"],
1442
+ bIsComputedDefaultValue = oAnnotations["@Org.OData.Core.V1.ComputedDefaultValue"],
1443
+ bIsKeyComputedDefaultValueWithText = bIsKey && oEntityType[item].$Type === "Edm.Guid" ? bIsComputedDefaultValue && oAnnotations["@com.sap.vocabularies.Common.v1.Text"] : false;
1444
+
1445
+ if ((bIsImmutable || bIsKeyComputedDefaultValueWithText || bIsKey && oEntityType[item].$Type !== "Edm.Guid") && bIsNonComputed && bIsVisible) {
1446
+ aNonComputedVisibleFields.push(item);
1447
+ }
1448
+
1449
+ if (!bIsNonComputed && bIsComputedDefaultValue && oView) {
1450
+ var _IssueCategoryType$An;
1451
+
1452
+ var oDiagnostics = getAppComponent(oView).getDiagnostics();
1453
+ var sMessage = "Core.ComputedDefaultValue is ignored as Core.Computed is already set to true";
1454
+ oDiagnostics.addIssue(IssueCategory.Annotation, IssueSeverity.Medium, sMessage, IssueCategoryType, IssueCategoryType === null || IssueCategoryType === void 0 ? void 0 : (_IssueCategoryType$An = IssueCategoryType.Annotations) === null || _IssueCategoryType$An === void 0 ? void 0 : _IssueCategoryType$An.IgnoredAnnotation);
1455
+ }
1456
+ }
1457
+ }
1458
+
1459
+ return aNonComputedVisibleFields;
1460
+ }
1461
+
1462
+ function setUserDefaults(oAppComponent, aParameters, oModel, bIsAction, bIsCreate, oActionDefaultValues) {
1463
+ return new Promise(function (resolve) {
1464
+ var oComponentData = oAppComponent.getComponentData(),
1465
+ oStartupParameters = oComponentData && oComponentData.startupParameters || {},
1466
+ oShellServices = oAppComponent.getShellServices();
1467
+
1468
+ if (!oShellServices.hasUShell()) {
1469
+ aParameters.forEach(function (oParameter) {
1470
+ var sPropertyName = bIsAction ? "/" + oParameter.$Name : oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
1471
+ var sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
1472
+
1473
+ if (oActionDefaultValues && bIsCreate) {
1474
+ if (oActionDefaultValues[sParameterName]) {
1475
+ oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
1476
+ }
1477
+ } else if (oStartupParameters[sParameterName]) {
1478
+ oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
1479
+ }
1480
+ });
1481
+ return resolve(true);
1482
+ }
1483
+
1484
+ return oShellServices.getStartupAppState(oAppComponent).then(function (oStartupAppState) {
1485
+ var oData = oStartupAppState.getData() || {},
1486
+ aExtendedParameters = oData.selectionVariant && oData.selectionVariant.SelectOptions || [];
1487
+ aParameters.forEach(function (oParameter) {
1488
+ var sPropertyName = bIsAction ? "/" + oParameter.$Name : oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
1489
+ var sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
1490
+
1491
+ if (oActionDefaultValues && bIsCreate) {
1492
+ if (oActionDefaultValues[sParameterName]) {
1493
+ oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
1494
+ }
1495
+ } else if (oStartupParameters[sParameterName]) {
1496
+ oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
1497
+ } else if (aExtendedParameters.length > 0) {
1498
+ for (var i in aExtendedParameters) {
1499
+ var oExtendedParameter = aExtendedParameters[i];
1500
+
1501
+ if (oExtendedParameter.PropertyName === sParameterName) {
1502
+ var oRange = oExtendedParameter.Ranges.length ? oExtendedParameter.Ranges[0] : undefined;
1503
+
1504
+ if (oRange && oRange.Sign === "I" && oRange.Option === "EQ") {
1505
+ oModel.setProperty(sPropertyName, oRange.Low); // high is ignored when Option=EQ
1506
+ }
1507
+ }
1508
+ }
1509
+ }
1510
+ });
1511
+ return resolve(true);
1512
+ });
1513
+ });
1514
+ }
1515
+
1516
+ function getAdditionalParamsForCreate(oStartupParameters, oInboundParameters) {
1517
+ var oInbounds = oInboundParameters,
1518
+ aCreateParameters = oInbounds ? Object.keys(oInbounds).filter(function (sParameter) {
1519
+ return oInbounds[sParameter].useForCreate;
1520
+ }) : [];
1521
+ var oRet;
1522
+
1523
+ for (var i = 0; i < aCreateParameters.length; i++) {
1524
+ var sCreateParameter = aCreateParameters[i];
1525
+ var aValues = oStartupParameters && oStartupParameters[sCreateParameter];
1526
+
1527
+ if (aValues && aValues.length === 1) {
1528
+ oRet = oRet || Object.create(null);
1529
+ oRet[sCreateParameter] = aValues[0];
1530
+ }
1531
+ }
1532
+
1533
+ return oRet;
1534
+ }
1535
+
1536
+ function getSemanticObjectMapping(oOutbound) {
1537
+ var aSemanticObjectMapping = [];
1538
+
1539
+ if (oOutbound.parameters) {
1540
+ var aParameters = Object.keys(oOutbound.parameters) || [];
1541
+
1542
+ if (aParameters.length > 0) {
1543
+ aParameters.forEach(function (sParam) {
1544
+ var oMapping = oOutbound.parameters[sParam];
1545
+
1546
+ if (oMapping.value && oMapping.value.value && oMapping.value.format === "binding") {
1547
+ // using the format of UI.Mapping
1548
+ var oSemanticMapping = {
1549
+ "LocalProperty": {
1550
+ "$PropertyPath": oMapping.value.value
1551
+ },
1552
+ "SemanticObjectProperty": sParam
1553
+ };
1554
+
1555
+ if (aSemanticObjectMapping.length > 0) {
1556
+ // To check if the semanticObject Mapping is done for the same local property more that once then first one will be considered
1557
+ for (var i = 0; i < aSemanticObjectMapping.length; i++) {
1558
+ if (aSemanticObjectMapping[i]["LocalProperty"]["$PropertyPath"] !== oSemanticMapping["LocalProperty"]["$PropertyPath"]) {
1559
+ aSemanticObjectMapping.push(oSemanticMapping);
1560
+ }
1561
+ }
1562
+ } else {
1563
+ aSemanticObjectMapping.push(oSemanticMapping);
1564
+ }
1565
+ }
1566
+ });
1567
+ }
1568
+ }
1569
+
1570
+ return aSemanticObjectMapping;
1571
+ }
1572
+
1573
+ function getHeaderFacetItemConfigForExternalNavigation(oViewData, oCrossNav) {
1574
+ var oHeaderFacetItems = {};
1575
+ var sId;
1576
+ var oControlConfig = oViewData.controlConfiguration;
1577
+
1578
+ for (var config in oControlConfig) {
1579
+ if (config.indexOf("@com.sap.vocabularies.UI.v1.DataPoint") > -1 || config.indexOf("@com.sap.vocabularies.UI.v1.Chart") > -1) {
1580
+ if (oControlConfig[config].navigation && oControlConfig[config].navigation.targetOutbound && oControlConfig[config].navigation.targetOutbound.outbound) {
1581
+ var sOutbound = oControlConfig[config].navigation.targetOutbound.outbound;
1582
+ var oOutbound = oCrossNav[sOutbound];
1583
+
1584
+ if (oOutbound.semanticObject && oOutbound.action) {
1585
+ if (config.indexOf("Chart") > -1) {
1586
+ sId = generate(["fe", "MicroChartLink", config]);
1587
+ } else {
1588
+ sId = generate(["fe", "HeaderDPLink", config]);
1589
+ }
1590
+
1591
+ var aSemanticObjectMapping = CommonUtils.getSemanticObjectMapping(oOutbound);
1592
+ oHeaderFacetItems[sId] = {
1593
+ semanticObject: oOutbound.semanticObject,
1594
+ action: oOutbound.action,
1595
+ semanticObjectMapping: aSemanticObjectMapping
1596
+ };
1597
+ } else {
1598
+ Log.error("Cross navigation outbound is configured without semantic object and action for " + sOutbound);
1599
+ }
1600
+ }
1601
+ }
1602
+ }
1603
+
1604
+ return oHeaderFacetItems;
1605
+ }
1606
+
1607
+ function setSemanticObjectMappings(oSelectionVariant, vMappings) {
1608
+ var oMappings = typeof vMappings === "string" ? JSON.parse(vMappings) : vMappings;
1609
+
1610
+ for (var i = 0; i < oMappings.length; i++) {
1611
+ var sLocalProperty = oMappings[i]["LocalProperty"] && oMappings[i]["LocalProperty"]["$PropertyPath"] || oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"] && oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"]["$Path"];
1612
+ var sSemanticObjectProperty = oMappings[i]["SemanticObjectProperty"] || oMappings[i]["@com.sap.vocabularies.Common.v1.SemanticObjectProperty"];
1613
+
1614
+ if (oSelectionVariant.getSelectOption(sLocalProperty)) {
1615
+ var oSelectOption = oSelectionVariant.getSelectOption(sLocalProperty); //Create a new SelectOption with sSemanticObjectProperty as the property Name and remove the older one
1616
+
1617
+ oSelectionVariant.removeSelectOption(sLocalProperty);
1618
+ oSelectionVariant.massAddSelectOption(sSemanticObjectProperty, oSelectOption);
1619
+ }
1620
+ }
1621
+
1622
+ return oSelectionVariant;
1623
+ }
1624
+
1625
+ function fnGetSemanticObjectsFromPath(oMetaModel, sPath) {
1626
+ return new Promise(function (resolve) {
1627
+ var sSemanticObject = oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.SemanticObject");
1628
+ var aSemanticObjectUnavailableActions = oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions");
1629
+ var aSemanticObjectForGetLinks = [{
1630
+ semanticObject: sSemanticObject
1631
+ }];
1632
+ var oSemanticObject = {
1633
+ semanticObject: sSemanticObject
1634
+ };
1635
+ resolve({
1636
+ semanticObjectPath: sPath,
1637
+ semanticObjectForGetLinks: aSemanticObjectForGetLinks,
1638
+ semanticObject: oSemanticObject,
1639
+ unavailableActions: aSemanticObjectUnavailableActions
1640
+ });
1641
+ }).catch(function (oError) {
1642
+ Log.error("Error in fnGetSemanticObjectsFromPath", oError);
1643
+ });
1644
+ }
1645
+
1646
+ function fnUpdateSemanticTargetsModel(aGetLinksPromises, aSemanticObjects, oInternalModelContext, sCurrentHash) {
1647
+ return Promise.all(aGetLinksPromises).then(function (aValues) {
1648
+ var aLinks,
1649
+ _oLink,
1650
+ _sLinkIntentAction,
1651
+ aFinalLinks = [];
1652
+
1653
+ var oFinalSemanticObjects = {};
1654
+
1655
+ var bIntentHasActions = function (sIntent, aActions) {
1656
+ for (var intent in aActions) {
1657
+ if (intent === sIntent) {
1658
+ return true;
1659
+ } else {
1660
+ return false;
1661
+ }
1662
+ }
1663
+ };
1664
+
1665
+ for (var k = 0; k < aValues.length; k++) {
1666
+ aLinks = aValues[k];
1667
+
1668
+ if (aLinks && aLinks.length > 0 && aLinks[0] !== undefined) {
1669
+ var oSemanticObject = {};
1670
+ var oTmp = {};
1671
+ var sAlternatePath = void 0;
1672
+
1673
+ for (var i = 0; i < aLinks.length; i++) {
1674
+ aFinalLinks.push([]);
1675
+ var hasTargetsNotFiltered = false;
1676
+ var hasTargets = false;
1677
+
1678
+ for (var iLinkCount = 0; iLinkCount < aLinks[i][0].length; iLinkCount++) {
1679
+ _oLink = aLinks[i][0][iLinkCount];
1680
+ _sLinkIntentAction = _oLink && _oLink.intent.split("?")[0].split("-")[1];
1681
+
1682
+ if (!(_oLink && _oLink.intent && _oLink.intent.indexOf(sCurrentHash) === 0)) {
1683
+ hasTargetsNotFiltered = true;
1684
+
1685
+ if (!bIntentHasActions(_sLinkIntentAction, aSemanticObjects[k].unavailableActions)) {
1686
+ aFinalLinks[i].push(_oLink);
1687
+ hasTargets = true;
1688
+ }
1689
+ }
1690
+ }
1691
+
1692
+ oTmp = {
1693
+ semanticObject: aSemanticObjects[k].semanticObject,
1694
+ path: aSemanticObjects[k].path,
1695
+ HasTargets: hasTargets,
1696
+ HasTargetsNotFiltered: hasTargetsNotFiltered
1697
+ };
1698
+
1699
+ if (oSemanticObject[aSemanticObjects[k].semanticObject] === undefined) {
1700
+ oSemanticObject[aSemanticObjects[k].semanticObject] = {};
1701
+ }
1702
+
1703
+ sAlternatePath = aSemanticObjects[k].path.replace(/\//g, "_");
1704
+
1705
+ if (oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] === undefined) {
1706
+ oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = {};
1707
+ }
1708
+
1709
+ oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = Object.assign(oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath], oTmp);
1710
+ }
1711
+
1712
+ var sSemanticObjectName = Object.keys(oSemanticObject)[0];
1713
+
1714
+ if (Object.keys(oFinalSemanticObjects).includes(sSemanticObjectName)) {
1715
+ oFinalSemanticObjects[sSemanticObjectName] = Object.assign(oFinalSemanticObjects[sSemanticObjectName], oSemanticObject[sSemanticObjectName]);
1716
+ } else {
1717
+ oFinalSemanticObjects = Object.assign(oFinalSemanticObjects, oSemanticObject);
1718
+ }
1719
+
1720
+ aFinalLinks = [];
1721
+ }
1722
+ }
1723
+
1724
+ if (Object.keys(oFinalSemanticObjects).length > 0) {
1725
+ oInternalModelContext.setProperty("semanticsTargets", mergeObjects(oFinalSemanticObjects, oInternalModelContext.getProperty("semanticsTargets")));
1726
+ return oFinalSemanticObjects;
1727
+ }
1728
+ }).catch(function (oError) {
1729
+ Log.error("fnUpdateSemanticTargetsModel: Cannot read links", oError);
1730
+ });
1731
+ }
1732
+
1733
+ function fnGetSemanticObjectPromise(oAppComponent, oView, oMetaModel, sPath) {
1734
+ return CommonUtils.getSemanticObjectsFromPath(oMetaModel, sPath);
1735
+ }
1736
+
1737
+ function fnGetSemanticTargetsFromPageModel(oController, sPageModel) {
1738
+ var _fnfindValuesHelper = function (obj, key, list) {
1739
+ if (!obj) {
1740
+ return list;
1741
+ }
1742
+
1743
+ if (obj instanceof Array) {
1744
+ for (var i in obj) {
1745
+ list = list.concat(_fnfindValuesHelper(obj[i], key, []));
1746
+ }
1747
+
1748
+ return list;
1749
+ }
1750
+
1751
+ if (obj[key]) {
1752
+ list.push(obj[key]);
1753
+ }
1754
+
1755
+ if (typeof obj == "object" && obj !== null) {
1756
+ var children = Object.keys(obj);
1757
+
1758
+ if (children.length > 0) {
1759
+ for (var _i2 = 0; _i2 < children.length; _i2++) {
1760
+ list = list.concat(_fnfindValuesHelper(obj[children[_i2]], key, []));
1761
+ }
1762
+ }
1763
+ }
1764
+
1765
+ return list;
1766
+ };
1767
+
1768
+ var _fnfindValues = function (obj, key) {
1769
+ return _fnfindValuesHelper(obj, key, []);
1770
+ };
1771
+
1772
+ var _fnDeleteDuplicateSemanticObjects = function (aSemanticObjectPath) {
1773
+ return aSemanticObjectPath.filter(function (value, index) {
1774
+ return aSemanticObjectPath.indexOf(value) === index;
1775
+ });
1776
+ };
1777
+
1778
+ var oView = oController.getView();
1779
+ var oInternalModelContext = oView.getBindingContext("internal");
1780
+
1781
+ if (oInternalModelContext) {
1782
+ var aSemanticObjectsPromises = [];
1783
+ var oComponent = oController.getOwnerComponent();
1784
+ var oAppComponent = Component.getOwnerComponentFor(oComponent);
1785
+ var oMetaModel = oAppComponent.getMetaModel();
1786
+ var oPageModel = oComponent.getModel(sPageModel).getData();
1787
+
1788
+ if (JSON.stringify(oPageModel) === "{}") {
1789
+ oPageModel = oComponent.getModel(sPageModel)._getObject("/", undefined);
1790
+ }
1791
+
1792
+ var aSemanticObjectsFound = _fnfindValues(oPageModel, "semanticObjectPath");
1793
+
1794
+ aSemanticObjectsFound = _fnDeleteDuplicateSemanticObjects(aSemanticObjectsFound);
1795
+ var oShellServiceHelper = CommonUtils.getShellServices(oAppComponent);
1796
+ var sCurrentHash = CommonUtils.getHash();
1797
+ var aSemanticObjectsForGetLinks = [];
1798
+ var aSemanticObjects = [];
1799
+ var sPath;
1800
+
1801
+ var _oSemanticObject;
1802
+
1803
+ if (sCurrentHash && sCurrentHash.indexOf("?") !== -1) {
1804
+ // sCurrentHash can contain query string, cut it off!
1805
+ sCurrentHash = sCurrentHash.split("?")[0];
1806
+ }
1807
+
1808
+ for (var i = 0; i < aSemanticObjectsFound.length; i++) {
1809
+ sPath = aSemanticObjectsFound[i];
1810
+ aSemanticObjectsPromises.push(CommonUtils.getSemanticObjectPromise(oAppComponent, oView, oMetaModel, sPath));
1811
+ }
1812
+
1813
+ if (aSemanticObjectsPromises.length === 0) {
1814
+ return Promise.resolve();
1815
+ } else {
1816
+ Promise.all(aSemanticObjectsPromises).then(function (aValues) {
1817
+ var aGetLinksPromises = [];
1818
+ var sSemObjExpression;
1819
+ var aSemanticObjectsResolved = aValues.filter(function (element) {
1820
+ if (element.semanticObject !== undefined && element.semanticObject.semanticObject && typeof element.semanticObject.semanticObject === "object") {
1821
+ sSemObjExpression = compileBinding(bindingExpression(element.semanticObject.semanticObject.$Path));
1822
+ element.semanticObject.semanticObject = sSemObjExpression;
1823
+ element.semanticObjectForGetLinks[0].semanticObject = sSemObjExpression;
1824
+ return true;
1825
+ } else if (element) {
1826
+ return element.semanticObject !== undefined;
1827
+ } else {
1828
+ return false;
1829
+ }
1830
+ });
1831
+
1832
+ for (var j = 0; j < aSemanticObjectsResolved.length; j++) {
1833
+ _oSemanticObject = aSemanticObjectsResolved[j];
1834
+
1835
+ if (_oSemanticObject && _oSemanticObject.semanticObject && !(_oSemanticObject.semanticObject.semanticObject.indexOf("{") === 0)) {
1836
+ aSemanticObjectsForGetLinks.push(_oSemanticObject.semanticObjectForGetLinks);
1837
+ aSemanticObjects.push({
1838
+ semanticObject: _oSemanticObject.semanticObject.semanticObject,
1839
+ unavailableActions: _oSemanticObject.unavailableActions,
1840
+ path: aSemanticObjectsResolved[j].semanticObjectPath
1841
+ });
1842
+ aGetLinksPromises.push(oShellServiceHelper.getLinksWithCache([_oSemanticObject.semanticObjectForGetLinks]));
1843
+ }
1844
+ }
1845
+
1846
+ return CommonUtils.updateSemanticTargets(aGetLinksPromises, aSemanticObjects, oInternalModelContext, sCurrentHash);
1847
+ }).catch(function (oError) {
1848
+ Log.error("fnGetSemanticTargetsFromTable: Cannot get Semantic Objects", oError);
1849
+ });
1850
+ }
1851
+ } else {
1852
+ return Promise.resolve();
1853
+ }
1854
+ }
1855
+
1856
+ function getFilterRestrictions(oFilterRestrictionsAnnotation, sRestriction) {
1857
+ var FilterRestrictions = CommonUtils.FilterRestrictions;
1858
+
1859
+ if (sRestriction === FilterRestrictions.REQUIRED_PROPERTIES || sRestriction === FilterRestrictions.NON_FILTERABLE_PROPERTIES) {
1860
+ var aProps = [];
1861
+
1862
+ if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation[sRestriction]) {
1863
+ aProps = oFilterRestrictionsAnnotation[sRestriction].map(function (oProperty) {
1864
+ return oProperty.$PropertyPath;
1865
+ });
1866
+ }
1867
+
1868
+ return aProps;
1869
+ } else if (sRestriction === FilterRestrictions.ALLOWED_EXPRESSIONS) {
1870
+ var mAllowedExpressions = {};
1871
+
1872
+ if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation.FilterExpressionRestrictions) {
1873
+ oFilterRestrictionsAnnotation.FilterExpressionRestrictions.forEach(function (oProperty) {
1874
+ //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
1875
+ if (mAllowedExpressions[oProperty.Property.$PropertyPath]) {
1876
+ mAllowedExpressions[oProperty.Property.$PropertyPath].push(oProperty.AllowedExpressions);
1877
+ } else {
1878
+ mAllowedExpressions[oProperty.Property.$PropertyPath] = [oProperty.AllowedExpressions];
1879
+ }
1880
+ });
1881
+ }
1882
+
1883
+ return mAllowedExpressions;
1884
+ } // Default return the FilterRestrictions Annotation
1885
+
1886
+
1887
+ return oFilterRestrictionsAnnotation;
1888
+ }
1889
+
1890
+ function getFilterRestrictionsByPath(sEntitySetPath, oMetaModel) {
1891
+ var oRet = {},
1892
+ FilterRestrictions = CommonUtils.FilterRestrictions,
1893
+ oFilterRestrictions = sEntitySetPath ? oMetaModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions") : {};
1894
+ oRet[FilterRestrictions.REQUIRED_PROPERTIES] = getFilterRestrictions(oFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || [];
1895
+ oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES] = getFilterRestrictions(oFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || []; //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
1896
+
1897
+ oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] = getFilterRestrictions(oFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {};
1898
+ var aPathParts = sEntitySetPath.split("/");
1899
+
1900
+ if (aPathParts.length > 2) {
1901
+ // In normal filterbar scenarios sEntitySetPath is of the format "/Customer".
1902
+ // But, In case of sEntitySetPath of format "/Customer/Set" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
1903
+ var sNavigationPath = aPathParts[aPathParts.length - 1];
1904
+ aPathParts.splice(-1, 1); // removing NavigationProperty from the end.
1905
+
1906
+ var sParentEntitySetPath = aPathParts.join("/");
1907
+ var oNavigationRestrictions = CommonUtils.getNavigationRestrictions(oMetaModel, sParentEntitySetPath, sNavigationPath);
1908
+ var oNavigationFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions["FilterRestrictions"];
1909
+ oRet[FilterRestrictions.REQUIRED_PROPERTIES].concat(getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || []);
1910
+ oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES].concat(getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || []); //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
1911
+
1912
+ oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] = mergeObjects({}, getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {}, oRet[FilterRestrictions.ALLOWED_EXPRESSIONS]);
1913
+ }
1914
+
1915
+ return oRet;
1916
+ }
1917
+
1918
+ function templateControlFragment(sFragmentName, oPreprocessorSettings, oOptions, oModifier) {
1919
+ oOptions = oOptions || {};
1920
+
1921
+ if (oModifier) {
1922
+ return oModifier.templateControlFragment(sFragmentName, oPreprocessorSettings, oOptions.view).then(function (oFragment) {
1923
+ // This is required as Flex returns an HTMLCollection as templating result in XML time.
1924
+ return oModifier.targets === "xmlTree" && oFragment.length > 0 ? oFragment[0] : oFragment;
1925
+ });
1926
+ } else {
1927
+ return loadMacroLibrary().then(function () {
1928
+ return XMLPreprocessor.process(XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"), {
1929
+ name: sFragmentName
1930
+ }, oPreprocessorSettings);
1931
+ }).then(function (oFragment) {
1932
+ var oControl = oFragment.firstElementChild;
1933
+
1934
+ if (!!oOptions.isXML && oControl) {
1935
+ return oControl;
1936
+ }
1937
+
1938
+ return Fragment.load({
1939
+ id: oOptions.id,
1940
+ definition: oFragment,
1941
+ controller: oOptions.controller
1942
+ });
1943
+ });
1944
+ }
1945
+ }
1946
+
1947
+ function requestSingletonProperty(sPath, oModel) {
1948
+ if (!sPath || !oModel) {
1949
+ return Promise.resolve(null);
1950
+ }
1951
+
1952
+ var oMetaModel = oModel.getMetaModel(); // Find the underlying entity set from the property path and check whether it is a singleton.
1953
+
1954
+ var aParts = sPath.split("/").filter(Boolean),
1955
+ sPropertyName = aParts.pop(),
1956
+ sNavigationPath = aParts.join("/"),
1957
+ oEntitySet = sNavigationPath && oMetaModel.getObject("/" + sNavigationPath);
1958
+
1959
+ if (oEntitySet && oEntitySet.$kind === "Singleton") {
1960
+ var sSingletonName = aParts[aParts.length - 1],
1961
+ oPropertyBinding = oModel.bindProperty("/" + sSingletonName + "/" + sPropertyName);
1962
+ return oPropertyBinding.requestValue();
1963
+ }
1964
+
1965
+ return Promise.resolve(null);
1966
+ }
1967
+
1968
+ function addEventToBindingInfo(oControl, sEventName, fHandler) {
1969
+ var oBindingInfo;
1970
+
1971
+ var setBindingInfo = function () {
1972
+ if (oBindingInfo) {
1973
+ if (!oBindingInfo.events) {
1974
+ oBindingInfo.events = {};
1975
+ }
1976
+
1977
+ if (!oBindingInfo.events[sEventName]) {
1978
+ oBindingInfo.events[sEventName] = fHandler;
1979
+ } else {
1980
+ var fOriginalHandler = oBindingInfo.events[sEventName];
1981
+
1982
+ oBindingInfo.events[sEventName] = function () {
1983
+ for (var _len = arguments.length, args = new Array(_len), _key2 = 0; _key2 < _len; _key2++) {
1984
+ args[_key2] = arguments[_key2];
1985
+ }
1986
+
1987
+ fHandler.apply.apply(fHandler, [this].concat(args));
1988
+ fOriginalHandler.apply.apply(fOriginalHandler, [this].concat(args));
1989
+ };
1990
+ }
1991
+ }
1992
+ };
1993
+
1994
+ if (oControl.isA("sap.ui.mdc.Chart")) {
1995
+ oControl.innerChartBound().then(function () {
1996
+ oBindingInfo = oControl.getControlDelegate()._getChart(oControl).getBindingInfo("data");
1997
+ setBindingInfo();
1998
+ }).catch(function (sError) {
1999
+ Log.error(sError);
2000
+ });
2001
+ } else {
2002
+ oBindingInfo = oControl.data("rowsBindingInfo");
2003
+ setBindingInfo();
2004
+ }
2005
+ }
2006
+
2007
+ function loadMacroLibrary() {
2008
+ return new Promise(function (resolve) {
2009
+ sap.ui.require(["sap/fe/macros/macroLibrary"], function
2010
+ /*macroLibrary*/
2011
+ () {
2012
+ resolve();
2013
+ });
2014
+ });
2015
+ }
2016
+
2017
+ var CommonUtils = {
2018
+ isPropertyFilterable: isPropertyFilterable,
2019
+ isFieldControlPathInapplicable: isFieldControlPathInapplicable,
2020
+ removeSensitiveData: removeSensitiveData,
2021
+ fireButtonPress: fnFireButtonPress,
2022
+ getTargetView: getTargetView,
2023
+ hasTransientContext: fnHasTransientContexts,
2024
+ updateRelatedAppsDetails: fnUpdateRelatedAppsDetails,
2025
+ resolveStringtoBoolean: fnResolveStringtoBoolean,
2026
+ getAppComponent: getAppComponent,
2027
+ processDataLossConfirmation: fnProcessDataLossConfirmation,
2028
+ getMandatoryFilterFields: fnGetMandatoryFilterFields,
2029
+ getContextPathProperties: fnGetContextPathProperties,
2030
+ getParameterInfo: getParameterInfo,
2031
+ updateDataFieldForIBNButtonsVisibility: fnUpdateDataFieldForIBNButtonsVisibility,
2032
+ getTranslatedText: getTranslatedText,
2033
+ getEntitySetName: getEntitySetName,
2034
+ getActionPath: getActionPath,
2035
+ computeDisplayMode: computeDisplayMode,
2036
+ setActionEnablement: setActionEnablement,
2037
+ isStickyEditMode: isStickyEditMode,
2038
+ getOperatorsForProperty: getOperatorsForProperty,
2039
+ addSelectionVariantToConditions: addSelectionVariantToConditions,
2040
+ addExternalStateFiltersToSelectionVariant: addExternalStateFiltersToSelectionVariant,
2041
+ addPageContextToSelectionVariant: addPageContextToSelectionVariant,
2042
+ addDefaultDisplayCurrency: addDefaultDisplayCurrency,
2043
+ getNonComputedVisibleFields: getNonComputedVisibleFields,
2044
+ setUserDefaults: setUserDefaults,
2045
+ getShellServices: getShellServices,
2046
+ getHash: getHash,
2047
+ getIBNActions: fnGetIBNActions,
2048
+ getHeaderFacetItemConfigForExternalNavigation: getHeaderFacetItemConfigForExternalNavigation,
2049
+ getSemanticObjectMapping: getSemanticObjectMapping,
2050
+ setSemanticObjectMappings: setSemanticObjectMappings,
2051
+ getSemanticObjectPromise: fnGetSemanticObjectPromise,
2052
+ getSemanticTargetsFromPageModel: fnGetSemanticTargetsFromPageModel,
2053
+ getSemanticObjectsFromPath: fnGetSemanticObjectsFromPath,
2054
+ updateSemanticTargets: fnUpdateSemanticTargetsModel,
2055
+ getPropertyDataType: getPropertyDataType,
2056
+ getNavigationRestrictions: getNavigationRestrictions,
2057
+ getSearchRestrictions: getSearchRestrictions,
2058
+ getFilterRestrictionsByPath: getFilterRestrictionsByPath,
2059
+ getSpecificAllowedExpression: getSpecificAllowedExpression,
2060
+ getAdditionalParamsForCreate: getAdditionalParamsForCreate,
2061
+ requestSingletonProperty: requestSingletonProperty,
2062
+ templateControlFragment: templateControlFragment,
2063
+ addEventToBindingInfo: addEventToBindingInfo,
2064
+ FilterRestrictions: {
2065
+ REQUIRED_PROPERTIES: "RequiredProperties",
2066
+ NON_FILTERABLE_PROPERTIES: "NonFilterableProperties",
2067
+ ALLOWED_EXPRESSIONS: "FilterAllowedExpressions"
2068
+ },
2069
+ AllowedExpressionsPrio: ["SingleValue", "MultiValue", "SingleRange", "MultiRange", "SearchExpression", "MultiRangeOrSearchExpression"],
2070
+ fnProcessDataLossOrDraftDiscardConfirmation: fnProcessDataLossOrDraftDiscardConfirmation,
2071
+ normalizeSearchTerm: normalizeSearchTerm
2072
+ };
2073
+ return CommonUtils;
2074
+ }, false);
2075
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbW1vblV0aWxzLnRzIl0sIm5hbWVzIjpbIlByb2dyYW1taW5nTW9kZWwiLCJsaWJyYXJ5IiwiYVZhbGlkVHlwZXMiLCJub3JtYWxpemVTZWFyY2hUZXJtIiwic1NlYXJjaFRlcm0iLCJ1bmRlZmluZWQiLCJyZXBsYWNlIiwic3BsaXQiLCJyZWR1Y2UiLCJzTm9ybWFsaXplZCIsInNDdXJyZW50V29yZCIsImdldFByb3BlcnR5RGF0YVR5cGUiLCJvTmF2aWdhdGlvbkNvbnRleHQiLCJzRGF0YVR5cGUiLCJnZXRQcm9wZXJ0eSIsInNBbm5vdGF0aW9uUGF0aCIsImluZGV4T2YiLCJmbkhhc1RyYW5zaWVudENvbnRleHRzIiwib0xpc3RCaW5kaW5nIiwiYkhhc1RyYW5zaWVudENvbnRleHRzIiwiZ2V0Q3VycmVudENvbnRleHRzIiwiZm9yRWFjaCIsIm9Db250ZXh0IiwiaXNUcmFuc2llbnQiLCJnZXRTZWFyY2hSZXN0cmljdGlvbnMiLCJzRnVsbFBhdGgiLCJvTWV0YU1vZGVsIiwiaSIsImFOYXZpZ2F0aW9uUGFydHMiLCJzUGF0aCIsImxlbmd0aCIsIm9OYXZpZ2F0aW9uUmVzdHJpY3Rpb25zIiwiZ2V0TmF2aWdhdGlvblJlc3RyaWN0aW9ucyIsImdldE9iamVjdCIsIm9Nb2RlbCIsInNFbnRpdHlTZXRQYXRoIiwic05hdmlnYXRpb25QYXRoIiwiYVJlc3RyaWN0ZWRQcm9wZXJ0aWVzIiwiUmVzdHJpY3RlZFByb3BlcnRpZXMiLCJmaW5kIiwib1Jlc3RyaWN0ZWRQcm9wZXJ0eSIsIk5hdmlnYXRpb25Qcm9wZXJ0eSIsIiROYXZpZ2F0aW9uUHJvcGVydHlQYXRoIiwiX2lzSW5Ob25GaWx0ZXJhYmxlUHJvcGVydGllcyIsInNDb250ZXh0UGF0aCIsImJJc05vdEZpbHRlcmFibGUiLCJvQW5ub3RhdGlvbiIsIk5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzIiwic29tZSIsInByb3BlcnR5IiwiJFByb3BlcnR5UGF0aCIsIl9pc0NvbnRleHRQYXRoRmlsdGVyYWJsZSIsInNDb250ZXhQYXRoIiwiYUVTUGFydHMiLCJzcGxpY2UiLCJhQ29udGV4dCIsInNDb250ZXh0Iiwiam9pbiIsIml0ZW0iLCJpbmRleCIsImFycmF5Iiwib0ZpbHRlclJlc3RyaWN0aW9ucyIsIkZpbHRlclJlc3RyaWN0aW9ucyIsImFOb25GaWx0ZXJhYmxlUHJvcGVydGllcyIsInNUYXJnZXRQcm9wZXJ0eVBhdGgiLCJvUHJvcGVydHlQYXRoIiwiaXNQcm9wZXJ0eUZpbHRlcmFibGUiLCJzUHJvcGVydHkiLCJiU2tpcEhpZGRlbkZpbHRlciIsIkVycm9yIiwiYklzRmlsdGVyYWJsZSIsImNyZWF0ZUJpbmRpbmdDb250ZXh0Iiwic1Byb3BlcnR5RGF0YVR5cGUiLCJnZXRTaGVsbFNlcnZpY2VzIiwib0NvbnRyb2wiLCJnZXRBcHBDb21wb25lbnQiLCJnZXRIYXNoIiwic0hhc2giLCJ3aW5kb3ciLCJsb2NhdGlvbiIsImhhc2giLCJfZ2V0U09JbnRlbnRzIiwib09iamVjdFBhZ2VMYXlvdXQiLCJvU2VtYW50aWNPYmplY3QiLCJvUGFyYW0iLCJvU2hlbGxTZXJ2aWNlSGVscGVyIiwiQ29tbW9uVXRpbHMiLCJnZXRMaW5rcyIsInNlbWFudGljT2JqZWN0IiwicGFyYW1zIiwiX2NyZWF0ZU1hcHBpbmdzIiwib01hcHBpbmciLCJhU09NYXBwaW5ncyIsImFNYXBwaW5nS2V5cyIsIk9iamVjdCIsImtleXMiLCJvU2VtYW50aWNNYXBwaW5nIiwicHVzaCIsIl9nZXRSZWxhdGVkQXBwc01lbnVJdGVtcyIsImFMaW5rcyIsImFFeGNsdWRlZEFjdGlvbnMiLCJvVGFyZ2V0UGFyYW1zIiwiYUl0ZW1zIiwib0xpbmsiLCJzSW50ZW50IiwiaW50ZW50Iiwic0FjdGlvbiIsInRleHQiLCJ0YXJnZXRTZW1PYmplY3QiLCJ0YXJnZXRBY3Rpb24iLCJ0YXJnZXRQYXJhbXMiLCJfZ2V0UmVsYXRlZEludGVudHMiLCJvQWRkaXRpb25hbFNlbWFudGljT2JqZWN0cyIsIm9CaW5kaW5nQ29udGV4dCIsImFNYW5pZmVzdFNPSXRlbXMiLCJ1bmF2YWlsYWJsZUFjdGlvbnMiLCJtYXBwaW5nIiwibmF2aWdhdGlvbkNvbnRleHRzIiwic2VtYW50aWNPYmplY3RNYXBwaW5nIiwidXBkYXRlUmVsYXRlQXBwc01vZGVsIiwib0VudHJ5IiwiYVNlbUtleXMiLCJvTWV0YVBhdGgiLCJzQ3VycmVudFNlbU9iaiIsInNDdXJyZW50QWN0aW9uIiwib1NlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMiLCJhUmVsYXRlZEFwcHNNZW51SXRlbXMiLCJqIiwic1NlbUtleSIsInZhbHVlIiwiYVRlY2huaWNhbEtleXMiLCJrZXkiLCJzT2JqS2V5Iiwib01hbmlmZXN0RGF0YSIsImdldFRhcmdldFZpZXciLCJnZXRWaWV3RGF0YSIsImFkZGl0aW9uYWxTZW1hbnRpY09iamVjdHMiLCJhTWFuaWZlc3RTT0tleXMiLCJ0aGVuIiwiYmluZCIsImNhdGNoIiwib0Vycm9yIiwiTG9nIiwiZXJyb3IiLCJmbkdldFBhcnNlU2hlbGxIYXNoQW5kR2V0TGlua3MiLCJvUGFyc2VkVXJsIiwicGFyc2VTaGVsbEhhc2giLCJkb2N1bWVudCIsImFjdGlvbiIsImFBbm5vdGF0aW9uc1NPSXRlbXMiLCJzRW50aXR5VHlwZVBhdGgiLCJvRW50aXR5U2V0QW5ub3RhdGlvbnMiLCJfZ2V0U2VtYW50aWNPYmplY3RBbm5vdGF0aW9ucyIsImJIYXNFbnRpdHlTZXRTTyIsIm9FbnRpdHlUeXBlQW5ub3RhdGlvbnMiLCJhVW5hdmFpbGFibGVBY3Rpb25zIiwiYU1hcHBpbmdzIiwiY29uY2F0IiwiZ2V0QmluZGluZ0NvbnRleHQiLCJzZXRQcm9wZXJ0eSIsIm9FbnRpdHlBbm5vdGF0aW9ucyIsInNBbm5vdGF0aW9uTWFwcGluZ1Rlcm0iLCJzQW5ub3RhdGlvbkFjdGlvblRlcm0iLCJzUXVhbGlmaWVyIiwiZm5VcGRhdGVSZWxhdGVkQXBwc0RldGFpbHMiLCJnZXRNb2RlbCIsImdldE1ldGFNb2RlbCIsIm9QYXRoIiwiZ2V0UGF0aCIsImdldE1ldGFQYXRoIiwic1NlbWFudGljS2V5Vm9jYWJ1bGFyeSIsInJlcXVlc3RPYmplY3QiLCJmbkZpcmVCdXR0b25QcmVzcyIsIm9CdXR0b24iLCJhQXV0aG9yaXplZFR5cGVzIiwiZ2V0TWV0YWRhdGEiLCJnZXROYW1lIiwiZ2V0VmlzaWJsZSIsImdldEVuYWJsZWQiLCJmaXJlUHJlc3MiLCJmblJlc29sdmVTdHJpbmd0b0Jvb2xlYW4iLCJzVmFsdWUiLCJpc0EiLCJvT3duZXIiLCJDb21wb25lbnQiLCJnZXRPd25lckNvbXBvbmVudEZvciIsImdldENvbXBvbmVudEluc3RhbmNlIiwiZ2V0Um9vdENvbnRyb2wiLCJWaWV3IiwiZ2V0UGFyZW50IiwiZm5Qcm9jZXNzRGF0YUxvc3NPckRyYWZ0RGlzY2FyZENvbmZpcm1hdGlvbiIsImZuUHJvY2Vzc0Z1bmN0aW9uIiwiZm5DYW5jZWxGdW5jdGlvbiIsIm9Db250cm9sbGVyIiwiYlNraXBCaW5kaW5nVG9WaWV3IiwiX2JJc01vZGlmaWVkIiwiZHJhZnREYXRhQ29udGV4dCIsImJpbmRDb250ZXh0IiwiZ2V0Qm91bmRDb250ZXh0IiwiRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEiLCJJc0FjdGl2ZUVudGl0eSIsImRyYWZ0QWRtaW5EYXRhIiwiQ3JlYXRpb25EYXRlVGltZSIsIkxhc3RDaGFuZ2VEYXRlVGltZSIsIkRhdGFMb3NzT3JEcmFmdERpc2NhcmRIYW5kbGVyIiwicGVyZm9ybUFmdGVyRGlzY2FyZG9yS2VlcERyYWZ0IiwiZm5Qcm9jZXNzRGF0YUxvc3NDb25maXJtYXRpb24iLCJmblByb2Nlc3MiLCJwcm9ncmFtbWluZ01vZGVsIiwiYlVJRWRpdGFibGUiLCJvUmVzb3VyY2VCdW5kbGUiLCJzYXAiLCJ1aSIsImdldENvcmUiLCJnZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUiLCJzV2FybmluZ01zZyIsImdldFRleHQiLCJzQ29uZmlybUJ1dHRvblR4dCIsInNDYW5jZWxCdXR0b25UeHQiLCJTdGlja3kiLCJNZXNzYWdlQm94Iiwid2FybmluZyIsImFjdGlvbnMiLCJvbkNsb3NlIiwib0ludGVybmFsTW9kZWwiLCJpbmZvIiwiaXNGaWVsZENvbnRyb2xQYXRoSW5hcHBsaWNhYmxlIiwic0ZpZWxkQ29udHJvbFBhdGgiLCJvQXR0cmlidXRlIiwiYkluYXBwbGljYWJsZSIsImFQYXJ0cyIsImhhc093blByb3BlcnR5IiwicmVtb3ZlU2Vuc2l0aXZlRGF0YSIsImFBdHRyaWJ1dGVzIiwiYU91dEF0dHJpYnV0ZXMiLCJzRW50aXR5U2V0IiwiZW50aXR5U2V0IiwiY29udGV4dERhdGEiLCJhUHJvcGVydGllcyIsInNQcm9wIiwiYVByb3BlcnR5QW5ub3RhdGlvbnMiLCJvRmllbGRDb250cm9sIiwiX2ZuQ2hlY2tJc01hdGNoIiwib09iamVjdCIsIm9LZXlzVG9DaGVjayIsInNLZXkiLCJmbkdldENvbnRleHRQYXRoUHJvcGVydGllcyIsIm9GaWx0ZXIiLCJvRW50aXR5VHlwZSIsIm9Qcm9wZXJ0aWVzIiwidGVzdCIsIiRraW5kIiwiZm5HZXRNYW5kYXRvcnlGaWx0ZXJGaWVsZHMiLCJhTWFuZGF0b3J5RmlsdGVyRmllbGRzIiwiZm5HZXRJQk5BY3Rpb25zIiwiYUlCTkFjdGlvbnMiLCJhQWN0aW9ucyIsImdldEFjdGlvbnMiLCJvQWN0aW9uIiwiZ2V0QWN0aW9uIiwiZGF0YSIsImZuVXBkYXRlRGF0YUZpZWxkRm9ySUJOQnV0dG9uc1Zpc2liaWxpdHkiLCJvVmlldyIsIm9QYXJhbXMiLCJmbkdldExpbmtzIiwib0RhdGEiLCJhS2V5cyIsIm9JQk5BY3Rpb24iLCJzU2VtYW50aWNPYmplY3QiLCJhTGluayIsInNldFZpc2libGUiLCJnZXRUcmFuc2xhdGVkVGV4dCIsInNGcmFtZXdvcmtLZXkiLCJzRW50aXR5U2V0TmFtZSIsInNSZXNvdXJjZUtleSIsImJSZXNvdXJjZUtleUV4aXN0cyIsIl9jaGVja0lmUmVzb3VyY2VLZXlFeGlzdHMiLCJhQ3VzdG9tQnVuZGxlcyIsImhhc1RleHQiLCJnZXRBY3Rpb25QYXRoIiwiYlJldHVybk9ubHlQYXRoIiwic0FjdGlvbk5hbWUiLCJiQ2hlY2tTdGF0aWNWYWx1ZSIsInNFbnRpdHlUeXBlTmFtZSIsIiRUeXBlIiwic0VudGl0eU5hbWUiLCJnZXRFbnRpdHlTZXROYW1lIiwic0JpbmRpbmdQYXJhbWV0ZXIiLCJzRW50aXR5VHlwZSIsIm9FbnRpdHlDb250YWluZXIiLCJjb21wdXRlRGlzcGxheU1vZGUiLCJvUHJvcGVydHlBbm5vdGF0aW9ucyIsIm9Db2xsZWN0aW9uQW5ub3RhdGlvbnMiLCJvVGV4dEFubm90YXRpb24iLCJvVGV4dEFycmFuZ2VtZW50QW5ub3RhdGlvbiIsIiRFbnVtTWVtYmVyIiwiX2dldEVudGl0eVR5cGUiLCJfcmVxdWVzdE9iamVjdCIsIm9TZWxlY3RlZENvbnRleHQiLCJuQnJhY2tldEluZGV4Iiwic1RhcmdldFR5cGUiLCJzbGljZSIsInNDdXJyZW50VHlwZSIsImdldEJpbmRpbmciLCJnZXRDb250ZXh0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJfcmVxdWVzdFByb3BlcnR5Iiwic0R5bmFtaWNBY3Rpb25FbmFibGVkUGF0aCIsIm9Qcm9taXNlIiwicmVxdWVzdFNpbmdsZXRvblByb3BlcnR5IiwidlByb3BlcnR5VmFsdWUiLCJfc2V0Q29udGV4dHNCYXNlZE9uT3BlcmF0aW9uQXZhaWxhYmxlIiwib0ludGVybmFsTW9kZWxDb250ZXh0IiwiYVJlcXVlc3RQcm9taXNlcyIsImFsbCIsImFSZXN1bHRzIiwiYUFwcGxpY2FibGVDb250ZXh0cyIsImFOb3RBcHBsaWNhYmxlQ29udGV4dHMiLCJhUmVzdWx0IiwiX3NldER5bmFtaWNBY3Rpb25Db250ZXh0cyIsInRyYWNlIiwiYUFwcGxpY2FibGUiLCJhTm90QXBwbGljYWJsZSIsInNEeW5hbWljQWN0aW9uUGF0aFByZWZpeCIsInNldEFjdGlvbkVuYWJsZW1lbnQiLCJvQWN0aW9uT3BlcmF0aW9uQXZhaWxhYmxlTWFwIiwiYVNlbGVjdGVkQ29udGV4dHMiLCJhUHJvbWlzZXMiLCJiRW5hYmxlZCIsIm9Db250ZXh0RGF0YSIsIm9UcmFuc2Zvcm1lZEJpbmRpbmciLCJ0cmFuc2Zvcm1SZWN1cnNpdmVseSIsIm9CaW5kaW5nRXhwcmVzc2lvbiIsImNvbnN0YW50IiwicGF0aCIsInNSZXN1bHQiLCJjb21waWxlQmluZGluZyIsIl9nZXREZWZhdWx0T3BlcmF0b3JzIiwib1JlYWxQcm9wZXJ0eSIsIm9EYXRhQ2xhc3MiLCJUeXBlVXRpbCIsImdldERhdGFUeXBlQ2xhc3NOYW1lIiwib0Jhc2VUeXBlIiwiZ2V0QmFzZVR5cGUiLCJGaWx0ZXJPcGVyYXRvclV0aWwiLCJnZXRPcGVyYXRvcnNGb3JUeXBlIiwiX2dldFJlc3RyaWN0aW9ucyIsImFEZWZhdWx0T3BzIiwiYUV4cHJlc3Npb25PcHMiLCJhT3BlcmF0b3JzIiwiZmlsdGVyIiwic0VsZW1lbnQiLCJ0b1N0cmluZyIsImdldFNwZWNpZmljQWxsb3dlZEV4cHJlc3Npb24iLCJhRXhwcmVzc2lvbnMiLCJhQWxsb3dlZEV4cHJlc3Npb25zUHJpb3JpdHkiLCJBbGxvd2VkRXhwcmVzc2lvbnNQcmlvIiwic29ydCIsImEiLCJiIiwiZ2V0T3BlcmF0b3JzRm9yUHJvcGVydHkiLCJzVHlwZSIsImJVc2VTZW1hbnRpY0RhdGVSYW5nZSIsInNTZXR0aW5ncyIsImdldEZpbHRlclJlc3RyaWN0aW9uc0J5UGF0aCIsImFFcXVhbHNPcHMiLCJhU2luZ2xlUmFuZ2VPcHMiLCJhU2luZ2xlVmFsdWVEYXRlT3BzIiwiYU11bHRpUmFuZ2VPcHMiLCJhU2VhcmNoRXhwcmVzc2lvbk9wcyIsImFTZW1hbnRpY0RhdGVPcHNFeHQiLCJTZW1hbnRpY0RhdGVPcGVyYXRvcnMiLCJnZXRTdXBwb3J0ZWRPcGVyYXRpb25zIiwiYlNlbWFudGljRGF0ZVJhbmdlIiwiYVNlbWFudGljRGF0ZU9wcyIsIm9TZXR0aW5ncyIsIkpTT04iLCJwYXJzZSIsImN1c3RvbURhdGEiLCJvcGVyYXRvckNvbmZpZ3VyYXRpb24iLCJnZXRGaWx0ZXJPcGVyYXRpb25zIiwiZ2V0U2VtYW50aWNEYXRlT3BlcmF0aW9ucyIsImFEZWZhdWx0T3BlcmF0b3JzIiwiRmlsdGVyQWxsb3dlZEV4cHJlc3Npb25zIiwic0FsbG93ZWRFeHByZXNzaW9uIiwic1Jlc3RyaWN0aW9ucyIsImFTaW5nbGVWYWx1ZU9wcyIsInNPcGVyYXRvcnMiLCJnZXRQYXJhbWV0ZXJJbmZvIiwic1BhcmFtZXRlckNvbnRleHRQYXRoIiwic3Vic3RyaW5nIiwibGFzdEluZGV4T2YiLCJiUmVzdWx0Q29udGV4dCIsIm9QYXJhbWV0ZXJJbmZvIiwiY29udGV4dFBhdGgiLCJwYXJhbWV0ZXJQcm9wZXJ0aWVzIiwiZ2V0Q29udGV4dFBhdGhQcm9wZXJ0aWVzIiwiYWRkU2VsZWN0T3B0aW9uVG9Db25kaXRpb25zIiwib1Byb3BlcnR5TWV0YWRhdGEiLCJhVmFsaWRPcGVyYXRvcnMiLCJhQ3VtdWxhdGl2ZUNvbmRpdGlvbnMiLCJvU2VsZWN0T3B0aW9uIiwib0NvbmRpdGlvbiIsImdldENvbmRpdGlvbnMiLCJvcGVyYXRvciIsImFkZFNlbGVjdE9wdGlvbnNUb0NvbmRpdGlvbnMiLCJvU2VsZWN0aW9uVmFyaWFudCIsInNTZWxlY3RPcHRpb25Qcm9wIiwib0NvbmRpdGlvbnMiLCJzQ29uZGl0aW9uUGF0aCIsInNDb25kaXRpb25Qcm9wIiwib1ZhbGlkUHJvcGVydGllcyIsImlzUGFyYW1ldGVyIiwiYUNvbmRpdGlvbnMiLCJhU2VsZWN0T3B0aW9ucyIsImdldFNlbGVjdE9wdGlvbiIsImFkZFNlbGVjdGlvblZhcmlhbnRUb0NvbmRpdGlvbnMiLCJhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMiLCJnZXRTZWxlY3RPcHRpb25zUHJvcGVydHlOYW1lcyIsImFNZXRhZGF0UHJvcGVydGllcyIsIm9WYWxpZFBhcmFtZXRlclByb3BlcnRpZXMiLCJiSGFzUGFyYW1ldGVycyIsImFNZXRhZGF0YVBhcmFtZXRlcnMiLCJzTWV0YWRhdGFQYXJhbWV0ZXIiLCJzU2VsZWN0T3B0aW9uTmFtZSIsImluY2x1ZGVzIiwic3RhcnRzV2l0aCIsInNNZXRhZGF0YVByb3BlcnR5Iiwic1NlbGVjdE9wdGlvbiIsInNGdWxsQ29udGV4dFBhdGgiLCJyZXBsYWNlQWxsIiwiX2NyZWF0ZUNvbmRpdGlvbnNGb3JOYXZQcm9wZXJ0aWVzIiwic01haW5FbnRpdHlTZXRQYXRoIiwiYU5hdk9iamVjdE5hbWVzIiwic05hdlBhdGgiLCJzUHJvcGVydHlOYW1lIiwiJGlzQ29sbGVjdGlvbiIsInNOYXZQcm9wZXJ0eVBhdGgiLCJhZGRQYWdlQ29udGV4dFRvU2VsZWN0aW9uVmFyaWFudCIsIm1QYWdlQ29udGV4dCIsIm9BcHBDb21wb25lbnQiLCJvTmF2aWdhdGlvblNlcnZpY2UiLCJnZXROYXZpZ2F0aW9uU2VydmljZSIsIm1peEF0dHJpYnV0ZXNBbmRTZWxlY3Rpb25WYXJpYW50IiwidG9KU09OU3RyaW5nIiwiYWRkRXh0ZXJuYWxTdGF0ZUZpbHRlcnNUb1NlbGVjdGlvblZhcmlhbnQiLCJtRmlsdGVycyIsIm9UYXJnZXRJbmZvIiwib0ZpbHRlckluZm8iLCJzRmlsdGVyIiwic0xvdyIsInNIaWdoIiwiZm5HZXRTaWduQW5kT3B0aW9uIiwic09wZXJhdG9yIiwic0xvd1ZhbHVlIiwic0hpZ2hWYWx1ZSIsIm9TZWxlY3RPcHRpb25TdGF0ZSIsIm9wdGlvbiIsInNpZ24iLCJsb3ciLCJoaWdoIiwib0ZpbHRlckNvbmRpdGlvbnMiLCJmaWx0ZXJDb25kaXRpb25zIiwib0ZpbHRlcnNXaXRob3V0Q29uZmxpY3QiLCJmaWx0ZXJDb25kaXRpb25zV2l0aG91dENvbmZsaWN0Iiwib1RhYmxlUHJvcGVydGllc1dpdGhvdXRDb25mbGljdCIsInByb3BlcnRpZXNXaXRob3V0Q29uZmxpY3QiLCJhZGRGaWx0ZXJzVG9TZWxlY3Rpb25WYXJpYW50Iiwic0ZpbHRlck5hbWUiLCJhRmlsdGVycyIsInZhbHVlcyIsImFGaWx0ZXIiLCJvVmFsdWUxIiwib1NlbGVjdE9wdGlvblZhbHVlcyIsImFkZFNlbGVjdE9wdGlvbiIsImlzU3RpY2t5RWRpdE1vZGUiLCJiSXNTdGlja3lNb2RlIiwiTW9kZWxIZWxwZXIiLCJpc1N0aWNreVNlc3Npb25TdXBwb3J0ZWQiLCJhZGREZWZhdWx0RGlzcGxheUN1cnJlbmN5Iiwib1NlbGVjdGlvblZhcmlhbnREZWZhdWx0cyIsImFTVk9wdGlvbiIsImFEZWZhdWx0U1ZPcHRpb24iLCJkaXNwbGF5Q3VycmVuY3lTZWxlY3RPcHRpb24iLCJzU2lnbiIsInNPcHRpb24iLCJnZXROb25Db21wdXRlZFZpc2libGVGaWVsZHMiLCIkS2V5IiwiYU5vbkNvbXB1dGVkVmlzaWJsZUZpZWxkcyIsIm9Bbm5vdGF0aW9ucyIsImJJc0tleSIsImJJc0ltbXV0YWJsZSIsImJJc05vbkNvbXB1dGVkIiwiYklzVmlzaWJsZSIsImJJc0NvbXB1dGVkRGVmYXVsdFZhbHVlIiwiYklzS2V5Q29tcHV0ZWREZWZhdWx0VmFsdWVXaXRoVGV4dCIsIm9EaWFnbm9zdGljcyIsImdldERpYWdub3N0aWNzIiwic01lc3NhZ2UiLCJhZGRJc3N1ZSIsIklzc3VlQ2F0ZWdvcnkiLCJBbm5vdGF0aW9uIiwiSXNzdWVTZXZlcml0eSIsIk1lZGl1bSIsIklzc3VlQ2F0ZWdvcnlUeXBlIiwiQW5ub3RhdGlvbnMiLCJJZ25vcmVkQW5ub3RhdGlvbiIsInNldFVzZXJEZWZhdWx0cyIsImFQYXJhbWV0ZXJzIiwiYklzQWN0aW9uIiwiYklzQ3JlYXRlIiwib0FjdGlvbkRlZmF1bHRWYWx1ZXMiLCJvQ29tcG9uZW50RGF0YSIsImdldENvbXBvbmVudERhdGEiLCJvU3RhcnR1cFBhcmFtZXRlcnMiLCJzdGFydHVwUGFyYW1ldGVycyIsIm9TaGVsbFNlcnZpY2VzIiwiaGFzVVNoZWxsIiwib1BhcmFtZXRlciIsIiROYW1lIiwic1BhcmFtZXRlck5hbWUiLCJnZXRTdGFydHVwQXBwU3RhdGUiLCJvU3RhcnR1cEFwcFN0YXRlIiwiZ2V0RGF0YSIsImFFeHRlbmRlZFBhcmFtZXRlcnMiLCJzZWxlY3Rpb25WYXJpYW50IiwiU2VsZWN0T3B0aW9ucyIsIm9FeHRlbmRlZFBhcmFtZXRlciIsIlByb3BlcnR5TmFtZSIsIm9SYW5nZSIsIlJhbmdlcyIsIlNpZ24iLCJPcHRpb24iLCJMb3ciLCJnZXRBZGRpdGlvbmFsUGFyYW1zRm9yQ3JlYXRlIiwib0luYm91bmRQYXJhbWV0ZXJzIiwib0luYm91bmRzIiwiYUNyZWF0ZVBhcmFtZXRlcnMiLCJzUGFyYW1ldGVyIiwidXNlRm9yQ3JlYXRlIiwib1JldCIsInNDcmVhdGVQYXJhbWV0ZXIiLCJhVmFsdWVzIiwiY3JlYXRlIiwiZ2V0U2VtYW50aWNPYmplY3RNYXBwaW5nIiwib091dGJvdW5kIiwiYVNlbWFudGljT2JqZWN0TWFwcGluZyIsInBhcmFtZXRlcnMiLCJzUGFyYW0iLCJmb3JtYXQiLCJnZXRIZWFkZXJGYWNldEl0ZW1Db25maWdGb3JFeHRlcm5hbE5hdmlnYXRpb24iLCJvVmlld0RhdGEiLCJvQ3Jvc3NOYXYiLCJvSGVhZGVyRmFjZXRJdGVtcyIsInNJZCIsIm9Db250cm9sQ29uZmlnIiwiY29udHJvbENvbmZpZ3VyYXRpb24iLCJjb25maWciLCJuYXZpZ2F0aW9uIiwidGFyZ2V0T3V0Ym91bmQiLCJvdXRib3VuZCIsInNPdXRib3VuZCIsImdlbmVyYXRlIiwic2V0U2VtYW50aWNPYmplY3RNYXBwaW5ncyIsInZNYXBwaW5ncyIsIm9NYXBwaW5ncyIsInNMb2NhbFByb3BlcnR5Iiwic1NlbWFudGljT2JqZWN0UHJvcGVydHkiLCJyZW1vdmVTZWxlY3RPcHRpb24iLCJtYXNzQWRkU2VsZWN0T3B0aW9uIiwiZm5HZXRTZW1hbnRpY09iamVjdHNGcm9tUGF0aCIsImFTZW1hbnRpY09iamVjdFVuYXZhaWxhYmxlQWN0aW9ucyIsImFTZW1hbnRpY09iamVjdEZvckdldExpbmtzIiwic2VtYW50aWNPYmplY3RQYXRoIiwic2VtYW50aWNPYmplY3RGb3JHZXRMaW5rcyIsImZuVXBkYXRlU2VtYW50aWNUYXJnZXRzTW9kZWwiLCJhR2V0TGlua3NQcm9taXNlcyIsImFTZW1hbnRpY09iamVjdHMiLCJzQ3VycmVudEhhc2giLCJfb0xpbmsiLCJfc0xpbmtJbnRlbnRBY3Rpb24iLCJhRmluYWxMaW5rcyIsIm9GaW5hbFNlbWFudGljT2JqZWN0cyIsImJJbnRlbnRIYXNBY3Rpb25zIiwiayIsIm9UbXAiLCJzQWx0ZXJuYXRlUGF0aCIsImhhc1RhcmdldHNOb3RGaWx0ZXJlZCIsImhhc1RhcmdldHMiLCJpTGlua0NvdW50IiwiSGFzVGFyZ2V0cyIsIkhhc1RhcmdldHNOb3RGaWx0ZXJlZCIsImFzc2lnbiIsInNTZW1hbnRpY09iamVjdE5hbWUiLCJtZXJnZU9iamVjdHMiLCJmbkdldFNlbWFudGljT2JqZWN0UHJvbWlzZSIsImdldFNlbWFudGljT2JqZWN0c0Zyb21QYXRoIiwiZm5HZXRTZW1hbnRpY1RhcmdldHNGcm9tUGFnZU1vZGVsIiwic1BhZ2VNb2RlbCIsIl9mbmZpbmRWYWx1ZXNIZWxwZXIiLCJvYmoiLCJsaXN0IiwiQXJyYXkiLCJjaGlsZHJlbiIsIl9mbmZpbmRWYWx1ZXMiLCJfZm5EZWxldGVEdXBsaWNhdGVTZW1hbnRpY09iamVjdHMiLCJhU2VtYW50aWNPYmplY3RQYXRoIiwiZ2V0VmlldyIsImFTZW1hbnRpY09iamVjdHNQcm9taXNlcyIsIm9Db21wb25lbnQiLCJnZXRPd25lckNvbXBvbmVudCIsIm9QYWdlTW9kZWwiLCJzdHJpbmdpZnkiLCJfZ2V0T2JqZWN0IiwiYVNlbWFudGljT2JqZWN0c0ZvdW5kIiwiYVNlbWFudGljT2JqZWN0c0ZvckdldExpbmtzIiwiX29TZW1hbnRpY09iamVjdCIsImdldFNlbWFudGljT2JqZWN0UHJvbWlzZSIsInNTZW1PYmpFeHByZXNzaW9uIiwiYVNlbWFudGljT2JqZWN0c1Jlc29sdmVkIiwiZWxlbWVudCIsImJpbmRpbmdFeHByZXNzaW9uIiwiJFBhdGgiLCJnZXRMaW5rc1dpdGhDYWNoZSIsInVwZGF0ZVNlbWFudGljVGFyZ2V0cyIsImdldEZpbHRlclJlc3RyaWN0aW9ucyIsIm9GaWx0ZXJSZXN0cmljdGlvbnNBbm5vdGF0aW9uIiwic1Jlc3RyaWN0aW9uIiwiUkVRVUlSRURfUFJPUEVSVElFUyIsIk5PTl9GSUxURVJBQkxFX1BST1BFUlRJRVMiLCJhUHJvcHMiLCJtYXAiLCJvUHJvcGVydHkiLCJBTExPV0VEX0VYUFJFU1NJT05TIiwibUFsbG93ZWRFeHByZXNzaW9ucyIsIkZpbHRlckV4cHJlc3Npb25SZXN0cmljdGlvbnMiLCJQcm9wZXJ0eSIsIkFsbG93ZWRFeHByZXNzaW9ucyIsImFQYXRoUGFydHMiLCJzUGFyZW50RW50aXR5U2V0UGF0aCIsIm9OYXZpZ2F0aW9uRmlsdGVyUmVzdHJpY3Rpb25zIiwidGVtcGxhdGVDb250cm9sRnJhZ21lbnQiLCJzRnJhZ21lbnROYW1lIiwib1ByZXByb2Nlc3NvclNldHRpbmdzIiwib09wdGlvbnMiLCJvTW9kaWZpZXIiLCJ2aWV3Iiwib0ZyYWdtZW50IiwidGFyZ2V0cyIsImxvYWRNYWNyb0xpYnJhcnkiLCJYTUxQcmVwcm9jZXNzb3IiLCJwcm9jZXNzIiwiWE1MVGVtcGxhdGVQcm9jZXNzb3IiLCJsb2FkVGVtcGxhdGUiLCJuYW1lIiwiZmlyc3RFbGVtZW50Q2hpbGQiLCJpc1hNTCIsIkZyYWdtZW50IiwibG9hZCIsImlkIiwiZGVmaW5pdGlvbiIsImNvbnRyb2xsZXIiLCJCb29sZWFuIiwicG9wIiwib0VudGl0eVNldCIsInNTaW5nbGV0b25OYW1lIiwib1Byb3BlcnR5QmluZGluZyIsImJpbmRQcm9wZXJ0eSIsInJlcXVlc3RWYWx1ZSIsImFkZEV2ZW50VG9CaW5kaW5nSW5mbyIsInNFdmVudE5hbWUiLCJmSGFuZGxlciIsIm9CaW5kaW5nSW5mbyIsInNldEJpbmRpbmdJbmZvIiwiZXZlbnRzIiwiZk9yaWdpbmFsSGFuZGxlciIsImFyZ3MiLCJhcHBseSIsImlubmVyQ2hhcnRCb3VuZCIsImdldENvbnRyb2xEZWxlZ2F0ZSIsIl9nZXRDaGFydCIsImdldEJpbmRpbmdJbmZvIiwic0Vycm9yIiwicmVxdWlyZSIsImZpcmVCdXR0b25QcmVzcyIsImhhc1RyYW5zaWVudENvbnRleHQiLCJ1cGRhdGVSZWxhdGVkQXBwc0RldGFpbHMiLCJyZXNvbHZlU3RyaW5ndG9Cb29sZWFuIiwicHJvY2Vzc0RhdGFMb3NzQ29uZmlybWF0aW9uIiwiZ2V0TWFuZGF0b3J5RmlsdGVyRmllbGRzIiwidXBkYXRlRGF0YUZpZWxkRm9ySUJOQnV0dG9uc1Zpc2liaWxpdHkiLCJnZXRJQk5BY3Rpb25zIiwiZ2V0U2VtYW50aWNUYXJnZXRzRnJvbVBhZ2VNb2RlbCJdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUF1QkEsTUFBTUEsZ0JBQWdCLEdBQUdDLE9BQU8sQ0FBQ0QsZ0JBQWpDO0FBQ0EsTUFBTUUsV0FBVyxHQUFHLENBQ25CLGFBRG1CLEVBRW5CLFVBRm1CLEVBR25CLFVBSG1CLEVBSW5CLGNBSm1CLEVBS25CLG9CQUxtQixFQU1uQixhQU5tQixFQU9uQixZQVBtQixFQVFuQixXQVJtQixFQVNuQixVQVRtQixFQVVuQixXQVZtQixFQVduQixXQVhtQixFQVluQixXQVptQixFQWFuQixXQWJtQixFQWNuQixZQWRtQixFQWVuQixZQWZtQixFQWdCbkIsVUFoQm1CLEVBaUJuQixlQWpCbUIsQ0FBcEI7O0FBbUJBLFdBQVNDLG1CQUFULENBQTZCQyxXQUE3QixFQUFrRDtBQUNqRCxRQUFJLENBQUNBLFdBQUwsRUFBa0I7QUFDakIsYUFBT0MsU0FBUDtBQUNBOztBQUVELFdBQU9ELFdBQVcsQ0FDaEJFLE9BREssQ0FDRyxJQURILEVBQ1MsR0FEVCxFQUVMQyxLQUZLLENBRUMsS0FGRCxFQUdMQyxNQUhLLENBR0UsVUFBU0MsV0FBVCxFQUEwQ0MsWUFBMUMsRUFBZ0U7QUFDdkUsVUFBSUEsWUFBWSxLQUFLLEVBQXJCLEVBQXlCO0FBQ3hCRCxRQUFBQSxXQUFXLEdBQUcsQ0FBQ0EsV0FBVyxHQUFHQSxXQUFXLEdBQUcsR0FBakIsR0FBdUIsRUFBbkMsSUFBeUMsR0FBekMsR0FBK0NDLFlBQS9DLEdBQThELEdBQTVFO0FBQ0E7O0FBQ0QsYUFBT0QsV0FBUDtBQUNBLEtBUkssRUFRSEosU0FSRyxDQUFQO0FBU0E7O0FBRUQsV0FBU00sbUJBQVQsQ0FBNkJDLGtCQUE3QixFQUFzRDtBQUNyRCxRQUFJQyxTQUFTLEdBQUdELGtCQUFrQixDQUFDRSxXQUFuQixDQUErQixPQUEvQixDQUFoQixD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QThDbkI0QixJQUFBQSxxQkFBcUIsRUFBRUEscUJBOUNKO0FBK0NuQmhtQixJQUFBQSxrQkFBa0IsRUFBRTtBQUNuQnVqQixNQUFBQSxtQkFBbUIsRUFBRSxvQkFERjtBQUVuQkMsTUFBQUEseUJBQXlCLEVBQUUseUJBRlI7QUFHbkJJLE1BQUFBLG1CQUFtQixFQUFFO0FBSEYsS0EvQ0Q7QUFvRG5CclIsSUFBQUEsc0JBQXNCLEVBQUUsQ0FBQyxhQUFELEVBQWdCLFlBQWhCLEVBQThCLGFBQTlCLEVBQTZDLFlBQTdDLEVBQTJELGtCQUEzRCxFQUErRSw4QkFBL0UsQ0FwREw7QUFxRG5CdkssSUFBQUEsMkNBQTJDLEVBQUVBLDJDQXJEMUI7QUFzRG5CM0wsSUFBQUEsbUJBQW1CLEVBQUVBO0FBdERGLEdBQXBCO1NBeURlbUYsVyIsInNvdXJjZVJvb3QiOiIuIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZpZXcgZnJvbSBcInNhcC91aS9jb3JlL212Yy9WaWV3XCI7XG5pbXBvcnQgQ29tcG9uZW50IGZyb20gXCJzYXAvdWkvY29yZS9Db21wb25lbnRcIjtcbmltcG9ydCBNZXNzYWdlQm94IGZyb20gXCJzYXAvbS9NZXNzYWdlQm94XCI7XG5pbXBvcnQgTG9nIGZyb20gXCJzYXAvYmFzZS9Mb2dcIjtcbmltcG9ydCBsaWJyYXJ5IGZyb20gXCJzYXAvZmUvY29yZS9saWJyYXJ5XCI7XG5pbXBvcnQgTW9kZWxIZWxwZXIgZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvTW9kZWxIZWxwZXJcIjtcbmltcG9ydCBTZW1hbnRpY0RhdGVPcGVyYXRvcnMgZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvU2VtYW50aWNEYXRlT3BlcmF0b3JzXCI7XG5pbXBvcnQgbWVyZ2VPYmplY3RzIGZyb20gXCJzYXAvYmFzZS91dGlsL21lcmdlXCI7XG5pbXBvcnQgRGF0YUxvc3NPckRyYWZ0RGlzY2FyZEhhbmRsZXIgZnJvbSBcInNhcC9mZS9jb3JlL2NvbnRyb2xzL0RhdGFMb3NzT3JEcmFmdERpc2NhcmQvRGF0YUxvc3NPckRyYWZ0RGlzY2FyZEhhbmRsZXJcIjtcbmltcG9ydCBYTUxUZW1wbGF0ZVByb2Nlc3NvciBmcm9tIFwic2FwL3VpL2NvcmUvWE1MVGVtcGxhdGVQcm9jZXNzb3JcIjtcbmltcG9ydCBYTUxQcmVwcm9jZXNzb3IgZnJvbSBcInNhcC91aS9jb3JlL3V0aWwvWE1MUHJlcHJvY2Vzc29yXCI7XG5pbXBvcnQgRnJhZ21lbnQgZnJvbSBcInNhcC91aS9jb3JlL0ZyYWdtZW50XCI7XG5pbXBvcnQgT0RhdGFNZXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1ldGFNb2RlbFwiO1xuaW1wb3J0IFJlc291cmNlQnVuZGxlIGZyb20gXCJzYXAvYmFzZS9pMThuL1Jlc291cmNlQnVuZGxlXCI7XG5pbXBvcnQgeyBiaW5kaW5nRXhwcmVzc2lvbiwgY29tcGlsZUJpbmRpbmcsIGNvbnN0YW50LCB0cmFuc2Zvcm1SZWN1cnNpdmVseSB9IGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL0JpbmRpbmdFeHByZXNzaW9uXCI7XG5pbXBvcnQgeyBnZXRDb25kaXRpb25zIH0gZnJvbSBcIi4vdGVtcGxhdGluZy9GaWx0ZXJIZWxwZXJcIjtcbmltcG9ydCB7IEFwcENvbXBvbmVudCB9IGZyb20gXCJzYXAvZmUvY29yZVwiO1xuaW1wb3J0IEpTT05Nb2RlbCBmcm9tIFwic2FwL3VpL21vZGVsL2pzb24vSlNPTk1vZGVsXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZSB9IGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL1N0YWJsZUlkSGVscGVyXCI7XG5pbXBvcnQgT0RhdGFNb2RlbCBmcm9tIFwic2FwL3VpL21vZGVsL29kYXRhL3Y0L09EYXRhTW9kZWxcIjtcbmltcG9ydCBDb250cm9sIGZyb20gXCJzYXAvdWkvY29yZS9Db250cm9sXCI7XG5pbXBvcnQgRmlsdGVyT3BlcmF0b3JVdGlsIGZyb20gXCJzYXAvdWkvbWRjL2NvbmRpdGlvbi9GaWx0ZXJPcGVyYXRvclV0aWxcIjtcbmltcG9ydCBUeXBlVXRpbCBmcm9tIFwic2FwL3VpL21kYy9vZGF0YS92NC9UeXBlVXRpbFwiO1xuaW1wb3J0IHsgSXNzdWVDYXRlZ29yeSwgSXNzdWVTZXZlcml0eSwgSXNzdWVDYXRlZ29yeVR5cGUgfSBmcm9tIFwic2FwL2ZlL2NvcmUvY29udmVydGVycy9oZWxwZXJzL0lzc3VlTWFuYWdlclwiO1xuXG5jb25zdCBQcm9ncmFtbWluZ01vZGVsID0gbGlicmFyeS5Qcm9ncmFtbWluZ01vZGVsO1xuY29uc3QgYVZhbGlkVHlwZXMgPSBbXG5cdFwiRWRtLkJvb2xlYW5cIixcblx0XCJFZG0uQnl0ZVwiLFxuXHRcIkVkbS5EYXRlXCIsXG5cdFwiRWRtLkRhdGVUaW1lXCIsXG5cdFwiRWRtLkRhdGVUaW1lT2Zmc2V0XCIsXG5cdFwiRWRtLkRlY2ltYWxcIixcblx0XCJFZG0uRG91YmxlXCIsXG5cdFwiRWRtLkZsb2F0XCIsXG5cdFwiRWRtLkd1aWRcIixcblx0XCJFZG0uSW50MTZcIixcblx0XCJFZG0uSW50MzJcIixcblx0XCJFZG0uSW50NjRcIixcblx0XCJFZG0uU0J5dGVcIixcblx0XCJFZG0uU2luZ2xlXCIsXG5cdFwiRWRtLlN0cmluZ1wiLFxuXHRcIkVkbS5UaW1lXCIsXG5cdFwiRWRtLlRpbWVPZkRheVwiXG5dO1xuZnVuY3Rpb24gbm9ybWFsaXplU2VhcmNoVGVybShzU2VhcmNoVGVybTogc3RyaW5nKSB7XG5cdGlmICghc1NlYXJjaFRlcm0pIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cblx0cmV0dXJuIHNTZWFyY2hUZXJtXG5cdFx0LnJlcGxhY2UoL1wiL2csIFwiIFwiKVxuXHRcdC5zcGxpdCgvXFxzKy8pXG5cdFx0LnJlZHVjZShmdW5jdGlvbihzTm9ybWFsaXplZDogc3RyaW5nIHwgdW5kZWZpbmVkLCBzQ3VycmVudFdvcmQ6IHN0cmluZykge1xuXHRcdFx0aWYgKHNDdXJyZW50V29yZCAhPT0gXCJcIikge1xuXHRcdFx0XHRzTm9ybWFsaXplZCA9IChzTm9ybWFsaXplZCA/IHNOb3JtYWxpemVkICsgXCIgXCIgOiBcIlwiKSArICdcIicgKyBzQ3VycmVudFdvcmQgKyAnXCInO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHNOb3JtYWxpemVkO1xuXHRcdH0sIHVuZGVmaW5lZCk7XG59XG5cbmZ1bmN0aW9uIGdldFByb3BlcnR5RGF0YVR5cGUob05hdmlnYXRpb25Db250ZXh0OiBhbnkpIHtcblx0bGV0IHNEYXRhVHlwZSA9IG9OYXZpZ2F0aW9uQ29udGV4dC5nZXRQcm9wZXJ0eShcIiRUeXBlXCIpO1xuXHQvLyBpZiAka2luZCBleGlzdHMsIGl0J3Mgbm90IGEgRGF0YUZpZWxkIGFuZCB3ZSBoYXZlIHRoZSBmaW5hbCB0eXBlIGFscmVhZHlcblx0aWYgKCFvTmF2aWdhdGlvbkNvbnRleHQuZ2V0UHJvcGVydHkoXCIka2luZFwiKSkge1xuXHRcdHN3aXRjaCAoc0RhdGFUeXBlKSB7XG5cdFx0XHRjYXNlIFwiY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuRGF0YUZpZWxkRm9yQWN0aW9uXCI6XG5cdFx0XHRjYXNlIFwiY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuRGF0YUZpZWxkRm9ySW50ZW50QmFzZWROYXZpZ2F0aW9uXCI6XG5cdFx0XHRcdHNEYXRhVHlwZSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgXCJjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5EYXRhRmllbGRcIjpcblx0XHRcdGNhc2UgXCJjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5EYXRhRmllbGRXaXRoTmF2aWdhdGlvblBhdGhcIjpcblx0XHRcdGNhc2UgXCJjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5EYXRhRmllbGRXaXRoVXJsXCI6XG5cdFx0XHRcdHNEYXRhVHlwZSA9IG9OYXZpZ2F0aW9uQ29udGV4dC5nZXRQcm9wZXJ0eShcIlZhbHVlLyRQYXRoLyRUeXBlXCIpO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBcImNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkRhdGFGaWVsZEZvckFubm90YXRpb25cIjpcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdGNvbnN0IHNBbm5vdGF0aW9uUGF0aCA9IG9OYXZpZ2F0aW9uQ29udGV4dC5nZXRQcm9wZXJ0eShcIlRhcmdldC8kQW5ub3RhdGlvblBhdGhcIik7XG5cdFx0XHRcdGlmIChzQW5ub3RhdGlvblBhdGgpIHtcblx0XHRcdFx0XHRpZiAoc0Fubm90YXRpb25QYXRoLmluZGV4T2YoXCJjb20uc2FwLnZvY2FidWxhcmllcy5Db21tdW5pY2F0aW9uLnYxLkNvbnRhY3RcIikgPiAtMSkge1xuXHRcdFx0XHRcdFx0c0RhdGFUeXBlID0gb05hdmlnYXRpb25Db250ZXh0LmdldFByb3BlcnR5KFwiVGFyZ2V0LyRBbm5vdGF0aW9uUGF0aC9mbi8kUGF0aC8kVHlwZVwiKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKHNBbm5vdGF0aW9uUGF0aC5pbmRleE9mKFwiY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuRGF0YVBvaW50XCIpID4gLTEpIHtcblx0XHRcdFx0XHRcdHNEYXRhVHlwZSA9IG9OYXZpZ2F0aW9uQ29udGV4dC5nZXRQcm9wZXJ0eShcIlZhbHVlLyRQYXRoLyRUeXBlXCIpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQvLyBlLmcuIEZpZWxkR3JvdXAgb3IgQ2hhcnRcblx0XHRcdFx0XHRcdHNEYXRhVHlwZSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c0RhdGFUeXBlID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBzRGF0YVR5cGU7XG59XG5mdW5jdGlvbiBmbkhhc1RyYW5zaWVudENvbnRleHRzKG9MaXN0QmluZGluZzogYW55KSB7XG5cdGxldCBiSGFzVHJhbnNpZW50Q29udGV4dHMgPSBmYWxzZTtcblx0aWYgKG9MaXN0QmluZGluZykge1xuXHRcdG9MaXN0QmluZGluZy5nZXRDdXJyZW50Q29udGV4dHMoKS5mb3JFYWNoKGZ1bmN0aW9uKG9Db250ZXh0OiBhbnkpIHtcblx0XHRcdGlmIChvQ29udGV4dCAmJiBvQ29udGV4dC5pc1RyYW5zaWVudCgpKSB7XG5cdFx0XHRcdGJIYXNUcmFuc2llbnRDb250ZXh0cyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblx0cmV0dXJuIGJIYXNUcmFuc2llbnRDb250ZXh0cztcbn1cbmZ1bmN0aW9uIGdldFNlYXJjaFJlc3RyaWN0aW9ucyhzRnVsbFBhdGg6IGFueSwgb01ldGFNb2RlbDogYW55KSB7XG5cdGxldCBpID0gMDtcblx0Y29uc3QgYU5hdmlnYXRpb25QYXJ0cyA9IHNGdWxsUGF0aC5zcGxpdChcIi8kTmF2aWdhdGlvblByb3BlcnR5QmluZGluZy9cIik7XG5cdGZvciAobGV0IHNQYXRoID0gYU5hdmlnYXRpb25QYXJ0c1swXTsgaSA8IGFOYXZpZ2F0aW9uUGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG5cdFx0Y29uc3Qgb05hdmlnYXRpb25SZXN0cmljdGlvbnMgPSBnZXROYXZpZ2F0aW9uUmVzdHJpY3Rpb25zKG9NZXRhTW9kZWwsIHNQYXRoLCBhTmF2aWdhdGlvblBhcnRzW2kgKyAxXSk7XG5cdFx0aWYgKG9OYXZpZ2F0aW9uUmVzdHJpY3Rpb25zICYmIG9OYXZpZ2F0aW9uUmVzdHJpY3Rpb25zW1wiU2VhcmNoUmVzdHJpY3Rpb25zXCJdKSB7XG5cdFx0XHRyZXR1cm4gb05hdmlnYXRpb25SZXN0cmljdGlvbnNbXCJTZWFyY2hSZXN0cmljdGlvbnNcIl07XG5cdFx0fVxuXHRcdHNQYXRoID0gc1BhdGggKyBcIi8kTmF2aWdhdGlvblByb3BlcnR5QmluZGluZy9cIiArIGFOYXZpZ2F0aW9uUGFydHNbaV07XG5cdH1cblx0cmV0dXJuIG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNGdWxsUGF0aCArIFwiQE9yZy5PRGF0YS5DYXBhYmlsaXRpZXMuVjEuU2VhcmNoUmVzdHJpY3Rpb25zXCIpO1xufVxuZnVuY3Rpb24gZ2V0TmF2aWdhdGlvblJlc3RyaWN0aW9ucyhvTW9kZWw6IGFueSwgc0VudGl0eVNldFBhdGg6IGFueSwgc05hdmlnYXRpb25QYXRoOiBhbnkpIHtcblx0Y29uc3Qgb05hdmlnYXRpb25SZXN0cmljdGlvbnMgPSBvTW9kZWwuZ2V0T2JqZWN0KHNFbnRpdHlTZXRQYXRoICsgXCJAT3JnLk9EYXRhLkNhcGFiaWxpdGllcy5WMS5OYXZpZ2F0aW9uUmVzdHJpY3Rpb25zXCIpO1xuXHRjb25zdCBhUmVzdHJpY3RlZFByb3BlcnRpZXMgPSBvTmF2aWdhdGlvblJlc3RyaWN0aW9ucyAmJiBvTmF2aWdhdGlvblJlc3RyaWN0aW9ucy5SZXN0cmljdGVkUHJvcGVydGllcztcblx0cmV0dXJuIChcblx0XHRhUmVzdHJpY3RlZFByb3BlcnRpZXMgJiZcblx0XHRhUmVzdHJpY3RlZFByb3BlcnRpZXMuZmluZChmdW5jdGlvbihvUmVzdHJpY3RlZFByb3BlcnR5OiBhbnkpIHtcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdG9SZXN0cmljdGVkUHJvcGVydHkgJiZcblx0XHRcdFx0b1Jlc3RyaWN0ZWRQcm9wZXJ0eS5OYXZpZ2F0aW9uUHJvcGVydHkgJiZcblx0XHRcdFx0b1Jlc3RyaWN0ZWRQcm9wZXJ0eS5OYXZpZ2F0aW9uUHJvcGVydHkuJE5hdmlnYXRpb25Qcm9wZXJ0eVBhdGggPT09IHNOYXZpZ2F0aW9uUGF0aFxuXHRcdFx0KTtcblx0XHR9KVxuXHQpO1xufVxuZnVuY3Rpb24gX2lzSW5Ob25GaWx0ZXJhYmxlUHJvcGVydGllcyhvTW9kZWw6IGFueSwgc0VudGl0eVNldFBhdGg6IGFueSwgc0NvbnRleHRQYXRoOiBhbnkpIHtcblx0bGV0IGJJc05vdEZpbHRlcmFibGUgPSBmYWxzZTtcblx0Y29uc3Qgb0Fubm90YXRpb24gPSBvTW9kZWwuZ2V0T2JqZWN0KHNFbnRpdHlTZXRQYXRoICsgXCJAT3JnLk9EYXRhLkNhcGFiaWxpdGllcy5WMS5GaWx0ZXJSZXN0cmljdGlvbnNcIik7XG5cdGlmIChvQW5ub3RhdGlvbiAmJiBvQW5ub3RhdGlvbi5Ob25GaWx0ZXJhYmxlUHJvcGVydGllcykge1xuXHRcdGJJc05vdEZpbHRlcmFibGUgPSBvQW5ub3RhdGlvbi5Ob25GaWx0ZXJhYmxlUHJvcGVydGllcy5zb21lKGZ1bmN0aW9uKHByb3BlcnR5OiBhbnkpIHtcblx0XHRcdHJldHVybiBwcm9wZXJ0eS4kTmF2aWdhdGlvblByb3BlcnR5UGF0aCA9PT0gc0NvbnRleHRQYXRoIHx8IHByb3BlcnR5LiRQcm9wZXJ0eVBhdGggPT09IHNDb250ZXh0UGF0aDtcblx0XHR9KTtcblx0fVxuXHRyZXR1cm4gYklzTm90RmlsdGVyYWJsZTtcbn1cbi8vIFRPRE8gcmV3b3JrIHRoaXMhXG5mdW5jdGlvbiBfaXNDb250ZXh0UGF0aEZpbHRlcmFibGUob01vZGVsOiBhbnksIHNFbnRpdHlTZXRQYXRoOiBhbnksIHNDb250ZXhQYXRoOiBhbnkpIHtcblx0Y29uc3Qgc0Z1bGxQYXRoID0gc0VudGl0eVNldFBhdGggKyBcIi9cIiArIHNDb250ZXhQYXRoLFxuXHRcdGFFU1BhcnRzID0gc0Z1bGxQYXRoLnNwbGl0KFwiL1wiKS5zcGxpY2UoMCwgMiksXG5cdFx0YUNvbnRleHQgPSBzRnVsbFBhdGguc3BsaXQoXCIvXCIpLnNwbGljZSgyKTtcblx0bGV0IGJJc05vdEZpbHRlcmFibGUgPSBmYWxzZSxcblx0XHRzQ29udGV4dCA9IFwiXCI7XG5cblx0c0VudGl0eVNldFBhdGggPSBhRVNQYXJ0cy5qb2luKFwiL1wiKTtcblxuXHRiSXNOb3RGaWx0ZXJhYmxlID0gYUNvbnRleHQuc29tZShmdW5jdGlvbihpdGVtOiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIGFycmF5OiBzdHJpbmdbXSkge1xuXHRcdGlmIChzQ29udGV4dC5sZW5ndGggPiAwKSB7XG5cdFx0XHRzQ29udGV4dCArPSBcIi9cIiArIGl0ZW07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNDb250ZXh0ID0gaXRlbTtcblx0XHR9XG5cdFx0aWYgKGluZGV4ID09PSBhcnJheS5sZW5ndGggLSAyKSB7XG5cdFx0XHQvLyBJbiBjYXNlIG9mIFwiL0N1c3RvbWVyL1NldC9Qcm9wZXJ0eVwiIHRoaXMgaXMgdG8gY2hlY2sgbmF2aWdhdGlvbiByZXN0cmljdGlvbnMgb2YgXCJDdXN0b21lclwiIGZvciBub24tZmlsdGVyYWJsZSBwcm9wZXJ0aWVzIGluIFwiU2V0XCJcblx0XHRcdGNvbnN0IG9OYXZpZ2F0aW9uUmVzdHJpY3Rpb25zID0gZ2V0TmF2aWdhdGlvblJlc3RyaWN0aW9ucyhvTW9kZWwsIHNFbnRpdHlTZXRQYXRoLCBpdGVtKTtcblx0XHRcdGNvbnN0IG9GaWx0ZXJSZXN0cmljdGlvbnMgPSBvTmF2aWdhdGlvblJlc3RyaWN0aW9ucyAmJiBvTmF2aWdhdGlvblJlc3RyaWN0aW9ucy5GaWx0ZXJSZXN0cmljdGlvbnM7XG5cdFx0XHRjb25zdCBhTm9uRmlsdGVyYWJsZVByb3BlcnRpZXMgPSBvRmlsdGVyUmVzdHJpY3Rpb25zICYmIG9GaWx0ZXJSZXN0cmljdGlvbnMuTm9uRmlsdGVyYWJsZVByb3BlcnRpZXM7XG5cdFx0XHRjb25zdCBzVGFyZ2V0UHJvcGVydHlQYXRoID0gYXJyYXlbYXJyYXkubGVuZ3RoIC0gMV07XG5cdFx0XHRpZiAoXG5cdFx0XHRcdGFOb25GaWx0ZXJhYmxlUHJvcGVydGllcyAmJlxuXHRcdFx0XHRhTm9uRmlsdGVyYWJsZVByb3BlcnRpZXMuZmluZChmdW5jdGlvbihvUHJvcGVydHlQYXRoOiBhbnkpIHtcblx0XHRcdFx0XHRyZXR1cm4gb1Byb3BlcnR5UGF0aC4kUHJvcGVydHlQYXRoID09PSBzVGFyZ2V0UHJvcGVydHlQYXRoO1xuXHRcdFx0XHR9KVxuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoaW5kZXggPT09IGFycmF5Lmxlbmd0aCAtIDEpIHtcblx0XHRcdC8vbGFzdCBwYXRoIHNlZ21lbnRcblx0XHRcdGJJc05vdEZpbHRlcmFibGUgPSBfaXNJbk5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzKG9Nb2RlbCwgc0VudGl0eVNldFBhdGgsIHNDb250ZXh0KTtcblx0XHR9IGVsc2UgaWYgKG9Nb2RlbC5nZXRPYmplY3Qoc0VudGl0eVNldFBhdGggKyBcIi8kTmF2aWdhdGlvblByb3BlcnR5QmluZGluZy9cIiArIGl0ZW0pKSB7XG5cdFx0XHQvL2NoZWNrIGV4aXN0aW5nIGNvbnRleHQgcGF0aCBhbmQgaW5pdGlhbGl6ZSBpdFxuXHRcdFx0YklzTm90RmlsdGVyYWJsZSA9IF9pc0luTm9uRmlsdGVyYWJsZVByb3BlcnRpZXMob01vZGVsLCBzRW50aXR5U2V0UGF0aCwgc0NvbnRleHQpO1xuXHRcdFx0c0NvbnRleHQgPSBcIlwiO1xuXHRcdFx0Ly9zZXQgdGhlIG5ldyBFbnRpdHlTZXRcblx0XHRcdHNFbnRpdHlTZXRQYXRoID0gXCIvXCIgKyBvTW9kZWwuZ2V0T2JqZWN0KHNFbnRpdHlTZXRQYXRoICsgXCIvJE5hdmlnYXRpb25Qcm9wZXJ0eUJpbmRpbmcvXCIgKyBpdGVtKTtcblx0XHR9XG5cdFx0cmV0dXJuIGJJc05vdEZpbHRlcmFibGUgPT09IHRydWU7XG5cdH0pO1xuXHRyZXR1cm4gYklzTm90RmlsdGVyYWJsZTtcbn1cbi8vIFRPRE8gY2hlY2sgdXNlZCBwbGFjZXMgYW5kIHJld29yayB0aGlzXG5mdW5jdGlvbiBpc1Byb3BlcnR5RmlsdGVyYWJsZShvTW9kZWw6IE9EYXRhTWV0YU1vZGVsLCBzRW50aXR5U2V0UGF0aDogc3RyaW5nLCBzUHJvcGVydHk6IHN0cmluZywgYlNraXBIaWRkZW5GaWx0ZXI6IGJvb2xlYW4pIHtcblx0aWYgKHR5cGVvZiBzUHJvcGVydHkgIT09IFwic3RyaW5nXCIpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJzUHJvcGVydHkgcGFyYW1ldGVyIG11c3QgYmUgYSBzdHJpbmdcIik7XG5cdH1cblx0bGV0IGJJc0ZpbHRlcmFibGU7XG5cblx0Ly8gUGFyYW1ldGVycyBzaG91bGQgYmUgcmVuZGVyZWQgYXMgZmlsdGVyZmllbGRzXG5cdGlmIChvTW9kZWwuZ2V0UHJvcGVydHkoc0VudGl0eVNldFBhdGggKyBcIi9AY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlJlc3VsdENvbnRleHRcIikgPT09IHRydWUpIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdGNvbnN0IG9OYXZpZ2F0aW9uQ29udGV4dCA9IG9Nb2RlbC5jcmVhdGVCaW5kaW5nQ29udGV4dChzRW50aXR5U2V0UGF0aCArIFwiL1wiICsgc1Byb3BlcnR5KTtcblxuXHRpZiAob05hdmlnYXRpb25Db250ZXh0LmdldFByb3BlcnR5KFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkhpZGRlblwiKSA9PT0gdHJ1ZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGlmICghYlNraXBIaWRkZW5GaWx0ZXIgJiYgb05hdmlnYXRpb25Db250ZXh0LmdldFByb3BlcnR5KFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkhpZGRlbkZpbHRlclwiKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGlmIChzRW50aXR5U2V0UGF0aC5zcGxpdChcIi9cIikubGVuZ3RoID09PSAyICYmIHNQcm9wZXJ0eS5pbmRleE9mKFwiL1wiKSA8IDApIHtcblx0XHQvLyB0aGVyZSBpcyBubyBuYXZpZ2F0aW9uIGluIGVudGl0eVNldCBwYXRoIGFuZCBwcm9wZXJ0eSBwYXRoXG5cdFx0YklzRmlsdGVyYWJsZSA9ICFfaXNJbk5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzKG9Nb2RlbCwgc0VudGl0eVNldFBhdGgsIHNQcm9wZXJ0eSk7XG5cdH0gZWxzZSB7XG5cdFx0YklzRmlsdGVyYWJsZSA9ICFfaXNDb250ZXh0UGF0aEZpbHRlcmFibGUob01vZGVsLCBzRW50aXR5U2V0UGF0aCwgc1Byb3BlcnR5KTtcblx0fVxuXHQvLyBjaGVjayBpZiB0eXBlIGNhbiBiZSB1c2VkIGZvciBmaWx0ZXJpbmdcblx0aWYgKGJJc0ZpbHRlcmFibGUgJiYgb05hdmlnYXRpb25Db250ZXh0KSB7XG5cdFx0Y29uc3Qgc1Byb3BlcnR5RGF0YVR5cGUgPSBnZXRQcm9wZXJ0eURhdGFUeXBlKG9OYXZpZ2F0aW9uQ29udGV4dCk7XG5cdFx0aWYgKHNQcm9wZXJ0eURhdGFUeXBlKSB7XG5cdFx0XHRiSXNGaWx0ZXJhYmxlID0gYVZhbGlkVHlwZXMuaW5kZXhPZihzUHJvcGVydHlEYXRhVHlwZSkgIT09IC0xO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRiSXNGaWx0ZXJhYmxlID0gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGJJc0ZpbHRlcmFibGU7XG59XG5mdW5jdGlvbiBnZXRTaGVsbFNlcnZpY2VzKG9Db250cm9sOiBhbnkpIHtcblx0cmV0dXJuIGdldEFwcENvbXBvbmVudChvQ29udHJvbCkuZ2V0U2hlbGxTZXJ2aWNlcygpO1xufVxuZnVuY3Rpb24gZ2V0SGFzaCgpIHtcblx0Y29uc3Qgc0hhc2ggPSB3aW5kb3cubG9jYXRpb24uaGFzaDtcblx0cmV0dXJuIHNIYXNoLnNwbGl0KFwiJlwiKVswXTtcbn1cbmZ1bmN0aW9uIF9nZXRTT0ludGVudHMob09iamVjdFBhZ2VMYXlvdXQ6IGFueSwgb1NlbWFudGljT2JqZWN0OiBhbnksIG9QYXJhbTogYW55KSB7XG5cdGNvbnN0IG9TaGVsbFNlcnZpY2VIZWxwZXIgPSBDb21tb25VdGlscy5nZXRTaGVsbFNlcnZpY2VzKG9PYmplY3RQYWdlTGF5b3V0KTtcblx0cmV0dXJuIG9TaGVsbFNlcnZpY2VIZWxwZXIuZ2V0TGlua3Moe1xuXHRcdHNlbWFudGljT2JqZWN0OiBvU2VtYW50aWNPYmplY3QsXG5cdFx0cGFyYW1zOiBvUGFyYW1cblx0fSk7XG59XG4vLyBUTy1ETyBhZGQgdGhpcyBhcyBwYXJ0IG9mIGFwcGx5U2VtYW50aWNPYmplY3RtYXBwaW5ncyBsb2dpYyBpbiBJbnRlbnRCYXNlZG5hdmlnYXRpb24gY29udHJvbGxlciBleHRlbnNpb25cbmZ1bmN0aW9uIF9jcmVhdGVNYXBwaW5ncyhvTWFwcGluZzogYW55KSB7XG5cdGNvbnN0IGFTT01hcHBpbmdzID0gW107XG5cdGNvbnN0IGFNYXBwaW5nS2V5cyA9IE9iamVjdC5rZXlzKG9NYXBwaW5nKTtcblx0bGV0IG9TZW1hbnRpY01hcHBpbmc7XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgYU1hcHBpbmdLZXlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0b1NlbWFudGljTWFwcGluZyA9IHtcblx0XHRcdFwiTG9jYWxQcm9wZXJ0eVwiOiB7XG5cdFx0XHRcdFwiJFByb3BlcnR5UGF0aFwiOiBhTWFwcGluZ0tleXNbaV1cblx0XHRcdH0sXG5cdFx0XHRcIlNlbWFudGljT2JqZWN0UHJvcGVydHlcIjogb01hcHBpbmdbYU1hcHBpbmdLZXlzW2ldXVxuXHRcdH07XG5cdFx0YVNPTWFwcGluZ3MucHVzaChvU2VtYW50aWNNYXBwaW5nKTtcblx0fVxuXG5cdHJldHVybiBhU09NYXBwaW5ncztcbn1cbi8qKlxuICogQHBhcmFtIGFMaW5rc1xuICogQHBhcmFtIGFFeGNsdWRlZEFjdGlvbnNcbiAqIEBwYXJhbSBvVGFyZ2V0UGFyYW1zXG4gKiBAcGFyYW0gYUl0ZW1zXG4gKi9cbmZ1bmN0aW9uIF9nZXRSZWxhdGVkQXBwc01lbnVJdGVtcyhhTGlua3M6IGFueSwgYUV4Y2x1ZGVkQWN0aW9uczogYW55LCBvVGFyZ2V0UGFyYW1zOiBhbnksIGFJdGVtczogYW55KSB7XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgYUxpbmtzLmxlbmd0aDsgaSsrKSB7XG5cdFx0Y29uc3Qgb0xpbmsgPSBhTGlua3NbaV07XG5cdFx0Y29uc3Qgc0ludGVudCA9IG9MaW5rLmludGVudDtcblx0XHRjb25zdCBzQWN0aW9uID0gc0ludGVudC5zcGxpdChcIi1cIilbMV0uc3BsaXQoXCI/XCIpWzBdO1xuXHRcdGlmIChhRXhjbHVkZWRBY3Rpb25zICYmIGFFeGNsdWRlZEFjdGlvbnMuaW5kZXhPZihzQWN0aW9uKSA9PT0gLTEpIHtcblx0XHRcdGFJdGVtcy5wdXNoKHtcblx0XHRcdFx0dGV4dDogb0xpbmsudGV4dCxcblx0XHRcdFx0dGFyZ2V0U2VtT2JqZWN0OiBzSW50ZW50LnNwbGl0KFwiI1wiKVsxXS5zcGxpdChcIi1cIilbMF0sXG5cdFx0XHRcdHRhcmdldEFjdGlvbjogc0FjdGlvbi5zcGxpdChcIn5cIilbMF0sXG5cdFx0XHRcdHRhcmdldFBhcmFtczogb1RhcmdldFBhcmFtc1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59XG4vKipcbiAqIEBwYXJhbSBvQWRkaXRpb25hbFNlbWFudGljT2JqZWN0c1xuICogQHBhcmFtIG9CaW5kaW5nQ29udGV4dFxuICogQHBhcmFtIGFNYW5pZmVzdFNPSXRlbXNcbiAqIEBwYXJhbSBhTGlua3NcbiAqL1xuZnVuY3Rpb24gX2dldFJlbGF0ZWRJbnRlbnRzKG9BZGRpdGlvbmFsU2VtYW50aWNPYmplY3RzOiBhbnksIG9CaW5kaW5nQ29udGV4dDogYW55LCBhTWFuaWZlc3RTT0l0ZW1zOiBhbnksIGFMaW5rczogYW55KSB7XG5cdGlmIChhTGlua3MgJiYgYUxpbmtzLmxlbmd0aCA+IDApIHtcblx0XHRjb25zdCBhRXhjbHVkZWRBY3Rpb25zID0gb0FkZGl0aW9uYWxTZW1hbnRpY09iamVjdHMudW5hdmFpbGFibGVBY3Rpb25zID8gb0FkZGl0aW9uYWxTZW1hbnRpY09iamVjdHMudW5hdmFpbGFibGVBY3Rpb25zIDogW107XG5cdFx0Y29uc3QgYVNPTWFwcGluZ3MgPSBvQWRkaXRpb25hbFNlbWFudGljT2JqZWN0cy5tYXBwaW5nID8gX2NyZWF0ZU1hcHBpbmdzKG9BZGRpdGlvbmFsU2VtYW50aWNPYmplY3RzLm1hcHBpbmcpIDogW107XG5cdFx0Y29uc3Qgb1RhcmdldFBhcmFtcyA9IHsgbmF2aWdhdGlvbkNvbnRleHRzOiBvQmluZGluZ0NvbnRleHQsIHNlbWFudGljT2JqZWN0TWFwcGluZzogYVNPTWFwcGluZ3MgfTtcblx0XHRfZ2V0UmVsYXRlZEFwcHNNZW51SXRlbXMoYUxpbmtzLCBhRXhjbHVkZWRBY3Rpb25zLCBvVGFyZ2V0UGFyYW1zLCBhTWFuaWZlc3RTT0l0ZW1zKTtcblx0fVxufVxuZnVuY3Rpb24gdXBkYXRlUmVsYXRlQXBwc01vZGVsKFxuXHR0aGlzOiBhbnksXG5cdG9CaW5kaW5nQ29udGV4dDogYW55LFxuXHRvRW50cnk6IGFueSxcblx0b09iamVjdFBhZ2VMYXlvdXQ6IGFueSxcblx0YVNlbUtleXM6IGFueSxcblx0b01ldGFNb2RlbDogYW55LFxuXHRvTWV0YVBhdGg6IGFueVxuKSB7XG5cdGNvbnN0IG9TaGVsbFNlcnZpY2VIZWxwZXIgPSBnZXRTaGVsbFNlcnZpY2VzKG9PYmplY3RQYWdlTGF5b3V0KTtcblx0Y29uc3Qgb1BhcmFtOiBhbnkgPSB7fTtcblx0bGV0IHNDdXJyZW50U2VtT2JqID0gXCJcIixcblx0XHRzQ3VycmVudEFjdGlvbiA9IFwiXCI7XG5cdGxldCBvU2VtYW50aWNPYmplY3RBbm5vdGF0aW9ucztcblx0bGV0IGFSZWxhdGVkQXBwc01lbnVJdGVtczogYW55W10gPSBbXTtcblx0bGV0IGFFeGNsdWRlZEFjdGlvbnM6IGFueVtdID0gW107XG5cblx0aWYgKG9FbnRyeSkge1xuXHRcdGlmIChhU2VtS2V5cyAmJiBhU2VtS2V5cy5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IGFTZW1LZXlzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdGNvbnN0IHNTZW1LZXkgPSBhU2VtS2V5c1tqXS4kUHJvcGVydHlQYXRoO1xuXHRcdFx0XHRpZiAoIW9QYXJhbVtzU2VtS2V5XSkge1xuXHRcdFx0XHRcdG9QYXJhbVtzU2VtS2V5XSA9IHsgdmFsdWU6IG9FbnRyeVtzU2VtS2V5XSB9O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGZhbGxiYWNrIHRvIFRlY2huaWNhbCBLZXlzIGlmIG5vIFNlbWFudGljIEtleSBpcyBwcmVzZW50XG5cdFx0XHRjb25zdCBhVGVjaG5pY2FsS2V5cyA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KG9NZXRhUGF0aCArIFwiLyRUeXBlLyRLZXlcIik7XG5cdFx0XHRmb3IgKGNvbnN0IGtleSBpbiBhVGVjaG5pY2FsS2V5cykge1xuXHRcdFx0XHRjb25zdCBzT2JqS2V5ID0gYVRlY2huaWNhbEtleXNba2V5XTtcblx0XHRcdFx0aWYgKCFvUGFyYW1bc09iaktleV0pIHtcblx0XHRcdFx0XHRvUGFyYW1bc09iaktleV0gPSB7IHZhbHVlOiBvRW50cnlbc09iaktleV0gfTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHQvLyBMb2dpYyB0byByZWFkIGFkZGl0aW9uYWwgU08gZnJvbSBtYW5pZmVzdCBhbmQgdXBkYXRlZCByZWxhdGVkYXBwcyBtb2RlbFxuXG5cdGNvbnN0IG9NYW5pZmVzdERhdGEgPSBnZXRUYXJnZXRWaWV3KG9PYmplY3RQYWdlTGF5b3V0KS5nZXRWaWV3RGF0YSgpO1xuXHRjb25zdCBhTWFuaWZlc3RTT0l0ZW1zOiBhbnlbXSA9IFtdO1xuXHRpZiAob01hbmlmZXN0RGF0YS5hZGRpdGlvbmFsU2VtYW50aWNPYmplY3RzKSB7XG5cdFx0Y29uc3QgYU1hbmlmZXN0U09LZXlzID0gT2JqZWN0LmtleXMob01hbmlmZXN0RGF0YS5hZGRpdGlvbmFsU2VtYW50aWNPYmplY3RzKTtcblx0XHRmb3IgKGxldCBrZXkgPSAwOyBrZXkgPCBhTWFuaWZlc3RTT0tleXMubGVuZ3RoOyBrZXkrKykge1xuXHRcdFx0X2dldFNPSW50ZW50cyhvT2JqZWN0UGFnZUxheW91dCwgYU1hbmlmZXN0U09LZXlzW2tleV0sIG9QYXJhbSlcblx0XHRcdFx0LnRoZW4oXG5cdFx0XHRcdFx0X2dldFJlbGF0ZWRJbnRlbnRzLmJpbmQoXG5cdFx0XHRcdFx0XHR0aGlzIGFzIGFueSxcblx0XHRcdFx0XHRcdG9NYW5pZmVzdERhdGEuYWRkaXRpb25hbFNlbWFudGljT2JqZWN0c1thTWFuaWZlc3RTT0tleXNba2V5XV0sXG5cdFx0XHRcdFx0XHRvQmluZGluZ0NvbnRleHQsXG5cdFx0XHRcdFx0XHRhTWFuaWZlc3RTT0l0ZW1zXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHQpXG5cdFx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdExvZy5lcnJvcihcIkVycm9yIHdoaWxlIHJldHJpZXZpbmcgU08gSW50ZW50c1wiLCBvRXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHRmdW5jdGlvbiBmbkdldFBhcnNlU2hlbGxIYXNoQW5kR2V0TGlua3MoKSB7XG5cdFx0Y29uc3Qgb1BhcnNlZFVybCA9IG9TaGVsbFNlcnZpY2VIZWxwZXIucGFyc2VTaGVsbEhhc2goZG9jdW1lbnQubG9jYXRpb24uaGFzaCk7XG5cdFx0c0N1cnJlbnRTZW1PYmogPSBvUGFyc2VkVXJsLnNlbWFudGljT2JqZWN0OyAvLyBDdXJyZW50IFNlbWFudGljIE9iamVjdFxuXHRcdHNDdXJyZW50QWN0aW9uID0gb1BhcnNlZFVybC5hY3Rpb247XG5cdFx0cmV0dXJuIF9nZXRTT0ludGVudHMob09iamVjdFBhZ2VMYXlvdXQsIHNDdXJyZW50U2VtT2JqLCBvUGFyYW0pO1xuXHR9XG5cblx0Zm5HZXRQYXJzZVNoZWxsSGFzaEFuZEdldExpbmtzKClcblx0XHQudGhlbihmdW5jdGlvbihhTGlua3M6IGFueSkge1xuXHRcdFx0aWYgKGFMaW5rcyAmJiBhTGlua3MubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRjb25zdCBvVGFyZ2V0UGFyYW1zOiBhbnkgPSB7fTtcblx0XHRcdFx0Y29uc3QgYUFubm90YXRpb25zU09JdGVtczogYW55W10gPSBbXTtcblx0XHRcdFx0Y29uc3Qgc0VudGl0eVNldFBhdGggPSBvTWV0YVBhdGggKyBcIkBcIjtcblx0XHRcdFx0Y29uc3Qgc0VudGl0eVR5cGVQYXRoID0gb01ldGFQYXRoICsgXCIvQFwiO1xuXHRcdFx0XHRjb25zdCBvRW50aXR5U2V0QW5ub3RhdGlvbnMgPSBvTWV0YU1vZGVsLmdldE9iamVjdChzRW50aXR5U2V0UGF0aCk7XG5cdFx0XHRcdG9TZW1hbnRpY09iamVjdEFubm90YXRpb25zID0gX2dldFNlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMob0VudGl0eVNldEFubm90YXRpb25zLCBzQ3VycmVudFNlbU9iaik7XG5cdFx0XHRcdGlmICghb1NlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMuYkhhc0VudGl0eVNldFNPKSB7XG5cdFx0XHRcdFx0Y29uc3Qgb0VudGl0eVR5cGVBbm5vdGF0aW9ucyA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNFbnRpdHlUeXBlUGF0aCk7XG5cdFx0XHRcdFx0b1NlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMgPSBfZ2V0U2VtYW50aWNPYmplY3RBbm5vdGF0aW9ucyhvRW50aXR5VHlwZUFubm90YXRpb25zLCBzQ3VycmVudFNlbU9iaik7XG5cdFx0XHRcdH1cblx0XHRcdFx0YUV4Y2x1ZGVkQWN0aW9ucyA9IG9TZW1hbnRpY09iamVjdEFubm90YXRpb25zLmFVbmF2YWlsYWJsZUFjdGlvbnM7XG5cdFx0XHRcdC8vU2tpcCBzYW1lIGFwcGxpY2F0aW9uIGZyb20gUmVsYXRlZCBBcHBzXG5cdFx0XHRcdGFFeGNsdWRlZEFjdGlvbnMucHVzaChzQ3VycmVudEFjdGlvbik7XG5cdFx0XHRcdG9UYXJnZXRQYXJhbXMubmF2aWdhdGlvbkNvbnRleHRzID0gb0JpbmRpbmdDb250ZXh0O1xuXHRcdFx0XHRvVGFyZ2V0UGFyYW1zLnNlbWFudGljT2JqZWN0TWFwcGluZyA9IG9TZW1hbnRpY09iamVjdEFubm90YXRpb25zLmFNYXBwaW5ncztcblx0XHRcdFx0X2dldFJlbGF0ZWRBcHBzTWVudUl0ZW1zKGFMaW5rcywgYUV4Y2x1ZGVkQWN0aW9ucywgb1RhcmdldFBhcmFtcywgYUFubm90YXRpb25zU09JdGVtcyk7XG5cdFx0XHRcdGFSZWxhdGVkQXBwc01lbnVJdGVtcyA9IGFBbm5vdGF0aW9uc1NPSXRlbXMuY29uY2F0KGFNYW5pZmVzdFNPSXRlbXMpO1xuXHRcdFx0XHQvLyBJZiBubyBhcHAgaW4gbGlzdCwgcmVsYXRlZCBhcHBzIGJ1dHRvbiB3aWxsIGJlIGhpZGRlblxuXHRcdFx0XHRvT2JqZWN0UGFnZUxheW91dC5nZXRCaW5kaW5nQ29udGV4dChcImludGVybmFsXCIpLnNldFByb3BlcnR5KFwicmVsYXRlZEFwcHMvdmlzaWJpbGl0eVwiLCBhUmVsYXRlZEFwcHNNZW51SXRlbXMubGVuZ3RoID4gMCk7XG5cdFx0XHRcdG9PYmplY3RQYWdlTGF5b3V0LmdldEJpbmRpbmdDb250ZXh0KFwiaW50ZXJuYWxcIikuc2V0UHJvcGVydHkoXCJyZWxhdGVkQXBwcy9pdGVtc1wiLCBhUmVsYXRlZEFwcHNNZW51SXRlbXMpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b09iamVjdFBhZ2VMYXlvdXQuZ2V0QmluZGluZ0NvbnRleHQoXCJpbnRlcm5hbFwiKS5zZXRQcm9wZXJ0eShcInJlbGF0ZWRBcHBzL3Zpc2liaWxpdHlcIiwgZmFsc2UpO1xuXHRcdFx0fVxuXHRcdH0pXG5cdFx0LmNhdGNoKGZ1bmN0aW9uKG9FcnJvcjogYW55KSB7XG5cdFx0XHRMb2cuZXJyb3IoXCJDYW5ub3QgcmVhZCBsaW5rc1wiLCBvRXJyb3IpO1xuXHRcdH0pO1xuXHRyZXR1cm4gYVJlbGF0ZWRBcHBzTWVudUl0ZW1zO1xufVxuZnVuY3Rpb24gX2dldFNlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMob0VudGl0eUFubm90YXRpb25zOiBhbnksIHNDdXJyZW50U2VtT2JqOiBhbnkpIHtcblx0Y29uc3Qgb1NlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMgPSB7XG5cdFx0Ykhhc0VudGl0eVNldFNPOiBmYWxzZSxcblx0XHRhVW5hdmFpbGFibGVBY3Rpb25zOiBbXSxcblx0XHRhTWFwcGluZ3M6IFtdXG5cdH07XG5cdGxldCBzQW5ub3RhdGlvbk1hcHBpbmdUZXJtLCBzQW5ub3RhdGlvbkFjdGlvblRlcm07XG5cdGxldCBzUXVhbGlmaWVyO1xuXHRmb3IgKGNvbnN0IGtleSBpbiBvRW50aXR5QW5ub3RhdGlvbnMpIHtcblx0XHRpZiAoa2V5LmluZGV4T2YoXCJjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuU2VtYW50aWNPYmplY3RcIikgPiAtMSAmJiBvRW50aXR5QW5ub3RhdGlvbnNba2V5XSA9PT0gc0N1cnJlbnRTZW1PYmopIHtcblx0XHRcdG9TZW1hbnRpY09iamVjdEFubm90YXRpb25zLmJIYXNFbnRpdHlTZXRTTyA9IHRydWU7XG5cdFx0XHRzQW5ub3RhdGlvbk1hcHBpbmdUZXJtID0gXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlNlbWFudGljT2JqZWN0TWFwcGluZ1wiO1xuXHRcdFx0c0Fubm90YXRpb25BY3Rpb25UZXJtID0gXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlNlbWFudGljT2JqZWN0VW5hdmFpbGFibGVBY3Rpb25zXCI7XG5cblx0XHRcdGlmIChrZXkuaW5kZXhPZihcIiNcIikgPiAtMSkge1xuXHRcdFx0XHRzUXVhbGlmaWVyID0ga2V5LnNwbGl0KFwiI1wiKVsxXTtcblx0XHRcdFx0c0Fubm90YXRpb25NYXBwaW5nVGVybSA9IHNBbm5vdGF0aW9uTWFwcGluZ1Rlcm0gKyBcIiNcIiArIHNRdWFsaWZpZXI7XG5cdFx0XHRcdHNBbm5vdGF0aW9uQWN0aW9uVGVybSA9IHNBbm5vdGF0aW9uQWN0aW9uVGVybSArIFwiI1wiICsgc1F1YWxpZmllcjtcblx0XHRcdH1cblxuXHRcdFx0b1NlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMuYU1hcHBpbmdzID0gb1NlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMuYU1hcHBpbmdzLmNvbmNhdChvRW50aXR5QW5ub3RhdGlvbnNbc0Fubm90YXRpb25NYXBwaW5nVGVybV0pO1xuXHRcdFx0b1NlbWFudGljT2JqZWN0QW5ub3RhdGlvbnMuYVVuYXZhaWxhYmxlQWN0aW9ucyA9IG9TZW1hbnRpY09iamVjdEFubm90YXRpb25zLmFVbmF2YWlsYWJsZUFjdGlvbnMuY29uY2F0KFxuXHRcdFx0XHRvRW50aXR5QW5ub3RhdGlvbnNbc0Fubm90YXRpb25BY3Rpb25UZXJtXVxuXHRcdFx0KTtcblxuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBvU2VtYW50aWNPYmplY3RBbm5vdGF0aW9ucztcbn1cbmZ1bmN0aW9uIGZuVXBkYXRlUmVsYXRlZEFwcHNEZXRhaWxzKG9PYmplY3RQYWdlTGF5b3V0OiBhbnkpIHtcblx0Y29uc3Qgb01ldGFNb2RlbCA9IG9PYmplY3RQYWdlTGF5b3V0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCk7XG5cdGNvbnN0IG9CaW5kaW5nQ29udGV4dCA9IG9PYmplY3RQYWdlTGF5b3V0LmdldEJpbmRpbmdDb250ZXh0KCk7XG5cdGNvbnN0IG9QYXRoID0gb0JpbmRpbmdDb250ZXh0ICYmIG9CaW5kaW5nQ29udGV4dC5nZXRQYXRoKCk7XG5cdGNvbnN0IG9NZXRhUGF0aCA9IG9NZXRhTW9kZWwuZ2V0TWV0YVBhdGgob1BhdGgpO1xuXHQvLyBTZW1hbnRpYyBLZXkgVm9jYWJ1bGFyeVxuXHRjb25zdCBzU2VtYW50aWNLZXlWb2NhYnVsYXJ5ID0gb01ldGFQYXRoICsgXCIvXCIgKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuU2VtYW50aWNLZXlcIjtcblx0Ly9TZW1hbnRpYyBLZXlzXG5cdGNvbnN0IGFTZW1LZXlzID0gb01ldGFNb2RlbC5nZXRPYmplY3Qoc1NlbWFudGljS2V5Vm9jYWJ1bGFyeSk7XG5cdC8vIFVuYXZhaWxhYmxlIEFjdGlvbnNcblx0Y29uc3Qgb0VudHJ5ID0gb0JpbmRpbmdDb250ZXh0LmdldE9iamVjdCgpO1xuXHRpZiAoIW9FbnRyeSkge1xuXHRcdG9CaW5kaW5nQ29udGV4dFxuXHRcdFx0LnJlcXVlc3RPYmplY3QoKVxuXHRcdFx0LnRoZW4oZnVuY3Rpb24ob0VudHJ5OiBhbnkpIHtcblx0XHRcdFx0cmV0dXJuIHVwZGF0ZVJlbGF0ZUFwcHNNb2RlbChvQmluZGluZ0NvbnRleHQsIG9FbnRyeSwgb09iamVjdFBhZ2VMYXlvdXQsIGFTZW1LZXlzLCBvTWV0YU1vZGVsLCBvTWV0YVBhdGgpO1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRMb2cuZXJyb3IoXCJDYW5ub3QgdXBkYXRlIHRoZSByZWxhdGVkIGFwcCBkZXRhaWxzXCIsIG9FcnJvcik7XG5cdFx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gdXBkYXRlUmVsYXRlQXBwc01vZGVsKG9CaW5kaW5nQ29udGV4dCwgb0VudHJ5LCBvT2JqZWN0UGFnZUxheW91dCwgYVNlbUtleXMsIG9NZXRhTW9kZWwsIG9NZXRhUGF0aCk7XG5cdH1cbn1cbi8qKlxuICogQHBhcmFtIG9CdXR0b25cbiAqL1xuZnVuY3Rpb24gZm5GaXJlQnV0dG9uUHJlc3Mob0J1dHRvbjogYW55KSB7XG5cdGNvbnN0IGFBdXRob3JpemVkVHlwZXMgPSBbXCJzYXAubS5CdXR0b25cIiwgXCJzYXAubS5PdmVyZmxvd1Rvb2xiYXJCdXR0b25cIl07XG5cdGlmIChvQnV0dG9uICYmIGFBdXRob3JpemVkVHlwZXMuaW5kZXhPZihvQnV0dG9uLmdldE1ldGFkYXRhKCkuZ2V0TmFtZSgpKSAhPT0gLTEgJiYgb0J1dHRvbi5nZXRWaXNpYmxlKCkgJiYgb0J1dHRvbi5nZXRFbmFibGVkKCkpIHtcblx0XHRvQnV0dG9uLmZpcmVQcmVzcygpO1xuXHR9XG59XG5mdW5jdGlvbiBmblJlc29sdmVTdHJpbmd0b0Jvb2xlYW4oc1ZhbHVlOiBhbnkpIHtcblx0aWYgKHNWYWx1ZSA9PT0gXCJ0cnVlXCIgfHwgc1ZhbHVlID09PSB0cnVlKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG5mdW5jdGlvbiBnZXRBcHBDb21wb25lbnQob0NvbnRyb2w6IGFueSk6IEFwcENvbXBvbmVudCB7XG5cdGlmIChvQ29udHJvbC5pc0EoXCJzYXAuZmUuY29yZS5BcHBDb21wb25lbnRcIikpIHtcblx0XHRyZXR1cm4gb0NvbnRyb2w7XG5cdH1cblx0Y29uc3Qgb093bmVyID0gQ29tcG9uZW50LmdldE93bmVyQ29tcG9uZW50Rm9yKG9Db250cm9sKTtcblx0aWYgKCFvT3duZXIpIHtcblx0XHRyZXR1cm4gb0NvbnRyb2w7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGdldEFwcENvbXBvbmVudChvT3duZXIpO1xuXHR9XG59XG5mdW5jdGlvbiBnZXRUYXJnZXRWaWV3KG9Db250cm9sOiBhbnkpIHtcblx0aWYgKG9Db250cm9sICYmIG9Db250cm9sLmlzQShcInNhcC51aS5jb3JlLkNvbXBvbmVudENvbnRhaW5lclwiKSkge1xuXHRcdG9Db250cm9sID0gb0NvbnRyb2wuZ2V0Q29tcG9uZW50SW5zdGFuY2UoKTtcblx0XHRvQ29udHJvbCA9IG9Db250cm9sICYmIG9Db250cm9sLmdldFJvb3RDb250cm9sKCk7XG5cdH1cblx0d2hpbGUgKG9Db250cm9sICYmICEob0NvbnRyb2wgaW5zdGFuY2VvZiBWaWV3KSkge1xuXHRcdG9Db250cm9sID0gb0NvbnRyb2wuZ2V0UGFyZW50KCk7XG5cdH1cblx0cmV0dXJuIG9Db250cm9sO1xufVxuLyoqXG4gKiBAcGFyYW0gZm5Qcm9jZXNzRnVuY3Rpb25cbiAqIEBwYXJhbSBmbkNhbmNlbEZ1bmN0aW9uXG4gKiBAcGFyYW0gb0NvbnRleHRcbiAqIEBwYXJhbSBvQ29udHJvbGxlclxuICogQHBhcmFtIGJTa2lwQmluZGluZ1RvVmlld1xuICovXG5mdW5jdGlvbiBmblByb2Nlc3NEYXRhTG9zc09yRHJhZnREaXNjYXJkQ29uZmlybWF0aW9uKFxuXHRmblByb2Nlc3NGdW5jdGlvbjogYW55LFxuXHRmbkNhbmNlbEZ1bmN0aW9uOiBhbnksXG5cdG9Db250ZXh0OiBhbnksXG5cdG9Db250cm9sbGVyOiBhbnksXG5cdGJTa2lwQmluZGluZ1RvVmlldzogYW55XG4pIHtcblx0Y29uc3Qgb01vZGVsID0gb0NvbnRleHQuZ2V0TW9kZWwoKTtcblx0bGV0IF9iSXNNb2RpZmllZCA9IGZhbHNlO1xuXHRjb25zdCBkcmFmdERhdGFDb250ZXh0ID0gb01vZGVsLmJpbmRDb250ZXh0KG9Db250ZXh0LmdldFBhdGgoKSArIFwiL0RyYWZ0QWRtaW5pc3RyYXRpdmVEYXRhXCIpLmdldEJvdW5kQ29udGV4dCgpO1xuXHRpZiAoXG5cdFx0b0NvbnRleHQgJiZcblx0XHRvQ29udGV4dC5nZXRPYmplY3QoKSAmJlxuXHRcdCghb0NvbnRleHQuZ2V0T2JqZWN0KCkuRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEgfHwgb0NvbnRleHQuZ2V0T2JqZWN0KCkuSXNBY3RpdmVFbnRpdHkgPT09IHRydWUpXG5cdCkge1xuXHRcdGZuUHJvY2Vzc0Z1bmN0aW9uKCk7XG5cdH0gZWxzZSB7XG5cdFx0ZHJhZnREYXRhQ29udGV4dFxuXHRcdFx0LnJlcXVlc3RPYmplY3QoKVxuXHRcdFx0LnRoZW4oZnVuY3Rpb24oZHJhZnRBZG1pbkRhdGE6IGFueSkge1xuXHRcdFx0XHRpZiAoZHJhZnRBZG1pbkRhdGEpIHtcblx0XHRcdFx0XHRfYklzTW9kaWZpZWQgPSAhKGRyYWZ0QWRtaW5EYXRhLkNyZWF0aW9uRGF0ZVRpbWUgPT09IGRyYWZ0QWRtaW5EYXRhLkxhc3RDaGFuZ2VEYXRlVGltZSk7XG5cdFx0XHRcdFx0aWYgKF9iSXNNb2RpZmllZCkge1xuXHRcdFx0XHRcdFx0RGF0YUxvc3NPckRyYWZ0RGlzY2FyZEhhbmRsZXIucGVyZm9ybUFmdGVyRGlzY2FyZG9yS2VlcERyYWZ0KFxuXHRcdFx0XHRcdFx0XHRmblByb2Nlc3NGdW5jdGlvbixcblx0XHRcdFx0XHRcdFx0Zm5DYW5jZWxGdW5jdGlvbixcblx0XHRcdFx0XHRcdFx0b0NvbnRyb2xsZXIsXG5cdFx0XHRcdFx0XHRcdGJTa2lwQmluZGluZ1RvVmlld1xuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Zm5Qcm9jZXNzRnVuY3Rpb24oKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm5Qcm9jZXNzRnVuY3Rpb24oKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRMb2cuZXJyb3IoXCJDYW5ub3QgcmV0cmlldmUgZHJhZnREYXRhQ29udGV4dCBpbmZvcm1hdGlvblwiLCBvRXJyb3IpO1xuXHRcdFx0fSk7XG5cdH1cbn1cbmZ1bmN0aW9uIGZuUHJvY2Vzc0RhdGFMb3NzQ29uZmlybWF0aW9uKGZuUHJvY2VzczogRnVuY3Rpb24sIG9Db250cm9sOiBhbnksIHByb2dyYW1taW5nTW9kZWw6IHN0cmluZykge1xuXHRjb25zdCBiVUlFZGl0YWJsZSA9IG9Db250cm9sLmdldE1vZGVsKFwidWlcIikuZ2V0UHJvcGVydHkoXCIvaXNFZGl0YWJsZVwiKSxcblx0XHRvUmVzb3VyY2VCdW5kbGUgPSBzYXAudWkuZ2V0Q29yZSgpLmdldExpYnJhcnlSZXNvdXJjZUJ1bmRsZShcInNhcC5mZS50ZW1wbGF0ZXNcIikgYXMgUmVzb3VyY2VCdW5kbGUsXG5cdFx0c1dhcm5pbmdNc2cgPSBvUmVzb3VyY2VCdW5kbGUgJiYgb1Jlc291cmNlQnVuZGxlLmdldFRleHQoXCJUX0NPTU1PTl9VVElMU19OQVZJR0FUSU9OX0FXQVlfTVNHXCIpLFxuXHRcdHNDb25maXJtQnV0dG9uVHh0ID0gb1Jlc291cmNlQnVuZGxlICYmIG9SZXNvdXJjZUJ1bmRsZS5nZXRUZXh0KFwiVF9DT01NT05fVVRJTFNfTkFWSUdBVElPTl9BV0FZX0NPTkZJUk1fQlVUVE9OXCIpLFxuXHRcdHNDYW5jZWxCdXR0b25UeHQgPSBvUmVzb3VyY2VCdW5kbGUgJiYgb1Jlc291cmNlQnVuZGxlLmdldFRleHQoXCJUX0NPTU1PTl9VVElMU19OQVZJR0FUSU9OX0FXQVlfQ0FOQ0VMX0JVVFRPTlwiKTtcblxuXHRpZiAocHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3kgJiYgYlVJRWRpdGFibGUpIHtcblx0XHRyZXR1cm4gTWVzc2FnZUJveC53YXJuaW5nKHNXYXJuaW5nTXNnLCB7XG5cdFx0XHRhY3Rpb25zOiBbc0NvbmZpcm1CdXR0b25UeHQsIHNDYW5jZWxCdXR0b25UeHRdLFxuXHRcdFx0b25DbG9zZTogZnVuY3Rpb24oc0FjdGlvbjogYW55KSB7XG5cdFx0XHRcdGlmIChzQWN0aW9uID09PSBzQ29uZmlybUJ1dHRvblR4dCkge1xuXHRcdFx0XHRcdGNvbnN0IG9JbnRlcm5hbE1vZGVsID0gb0NvbnRyb2wgJiYgb0NvbnRyb2wuZ2V0TW9kZWwoXCJpbnRlcm5hbFwiKTtcblxuXHRcdFx0XHRcdExvZy5pbmZvKFwiTmF2aWdhdGlvbiBjb25maXJtZWQuXCIpO1xuXHRcdFx0XHRcdGlmIChvSW50ZXJuYWxNb2RlbCkge1xuXHRcdFx0XHRcdFx0b0ludGVybmFsTW9kZWwuc2V0UHJvcGVydHkoXCIvc2Vzc2lvbk9uXCIsIGZhbHNlKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0TG9nLndhcm5pbmcoXCJMb2NhbCBVSU1vZGVsIGNvdWxkbid0IGJlIGZvdW5kLlwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Zm5Qcm9jZXNzKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0TG9nLmluZm8oXCJOYXZpZ2F0aW9uIHJlamVjdGVkLlwiKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBmblByb2Nlc3MoKTtcbn1cbmZ1bmN0aW9uIGlzRmllbGRDb250cm9sUGF0aEluYXBwbGljYWJsZShzRmllbGRDb250cm9sUGF0aDogc3RyaW5nLCBvQXR0cmlidXRlOiBhbnkpIHtcblx0bGV0IGJJbmFwcGxpY2FibGUgPSBmYWxzZTtcblx0Y29uc3QgYVBhcnRzID0gc0ZpZWxkQ29udHJvbFBhdGguc3BsaXQoXCIvXCIpO1xuXHQvLyBzZW5zaXRpdmUgZGF0YSBpcyByZW1vdmVkIG9ubHkgaWYgdGhlIHBhdGggaGFzIGFscmVhZHkgYmVlbiByZXNvbHZlZC5cblx0aWYgKGFQYXJ0cy5sZW5ndGggPiAxKSB7XG5cdFx0YkluYXBwbGljYWJsZSA9IG9BdHRyaWJ1dGVbYVBhcnRzWzBdXSAmJiBvQXR0cmlidXRlW2FQYXJ0c1swXV0uaGFzT3duUHJvcGVydHkoYVBhcnRzWzFdKSAmJiBvQXR0cmlidXRlW2FQYXJ0c1swXV1bYVBhcnRzWzFdXSA9PT0gMDtcblx0fSBlbHNlIHtcblx0XHRiSW5hcHBsaWNhYmxlID0gb0F0dHJpYnV0ZVtzRmllbGRDb250cm9sUGF0aF0gPT09IDA7XG5cdH1cblx0cmV0dXJuIGJJbmFwcGxpY2FibGU7XG59XG5mdW5jdGlvbiByZW1vdmVTZW5zaXRpdmVEYXRhKGFBdHRyaWJ1dGVzOiBhbnlbXSwgb01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWwpIHtcblx0Y29uc3QgYU91dEF0dHJpYnV0ZXMgPSBbXTtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhQXR0cmlidXRlcy5sZW5ndGg7IGkrKykge1xuXHRcdGNvbnN0IHNFbnRpdHlTZXQgPSBhQXR0cmlidXRlc1tpXS5lbnRpdHlTZXQsXG5cdFx0XHRvQXR0cmlidXRlID0gYUF0dHJpYnV0ZXNbaV0uY29udGV4dERhdGE7XG5cblx0XHRkZWxldGUgb0F0dHJpYnV0ZVtcIkBvZGF0YS5jb250ZXh0XCJdO1xuXHRcdGRlbGV0ZSBvQXR0cmlidXRlW1wiJTQwb2RhdGEuY29udGV4dFwiXTtcblx0XHRkZWxldGUgb0F0dHJpYnV0ZVtcIkBvZGF0YS5tZXRhZGF0YUV0YWdcIl07XG5cdFx0ZGVsZXRlIG9BdHRyaWJ1dGVbXCIlNDBvZGF0YS5tZXRhZGF0YUV0YWdcIl07XG5cdFx0ZGVsZXRlIG9BdHRyaWJ1dGVbXCJTQVBfX01lc3NhZ2VzXCJdO1xuXHRcdGNvbnN0IGFQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMob0F0dHJpYnV0ZSk7XG5cdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBhUHJvcGVydGllcy5sZW5ndGg7IGorKykge1xuXHRcdFx0Y29uc3Qgc1Byb3AgPSBhUHJvcGVydGllc1tqXSxcblx0XHRcdFx0YVByb3BlcnR5QW5ub3RhdGlvbnMgPSBvTWV0YU1vZGVsLmdldE9iamVjdChcIi9cIiArIHNFbnRpdHlTZXQgKyBcIi9cIiArIHNQcm9wICsgXCJAXCIpO1xuXHRcdFx0aWYgKGFQcm9wZXJ0eUFubm90YXRpb25zKSB7XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRhUHJvcGVydHlBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5QZXJzb25hbERhdGEudjEuSXNQb3RlbnRpYWxseVNlbnNpdGl2ZVwiXSB8fFxuXHRcdFx0XHRcdGFQcm9wZXJ0eUFubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkV4Y2x1ZGVGcm9tTmF2aWdhdGlvbkNvbnRleHRcIl0gfHxcblx0XHRcdFx0XHRhUHJvcGVydHlBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5BbmFseXRpY3MudjEuTWVhc3VyZVwiXVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRkZWxldGUgb0F0dHJpYnV0ZVtzUHJvcF07XG5cdFx0XHRcdH0gZWxzZSBpZiAoYVByb3BlcnR5QW5ub3RhdGlvbnNbXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkZpZWxkQ29udHJvbFwiXSkge1xuXHRcdFx0XHRcdGNvbnN0IG9GaWVsZENvbnRyb2wgPSBhUHJvcGVydHlBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRmllbGRDb250cm9sXCJdO1xuXHRcdFx0XHRcdGlmIChvRmllbGRDb250cm9sW1wiJEVudW1NZW1iZXJcIl0gJiYgb0ZpZWxkQ29udHJvbFtcIiRFbnVtTWVtYmVyXCJdLnNwbGl0KFwiL1wiKVsxXSA9PT0gXCJJbmFwcGxpY2FibGVcIikge1xuXHRcdFx0XHRcdFx0ZGVsZXRlIG9BdHRyaWJ1dGVbc1Byb3BdO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAob0ZpZWxkQ29udHJvbFtcIiRQYXRoXCJdICYmIENvbW1vblV0aWxzLmlzRmllbGRDb250cm9sUGF0aEluYXBwbGljYWJsZShvRmllbGRDb250cm9sW1wiJFBhdGhcIl0sIG9BdHRyaWJ1dGUpKSB7XG5cdFx0XHRcdFx0XHRkZWxldGUgb0F0dHJpYnV0ZVtzUHJvcF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGFPdXRBdHRyaWJ1dGVzLnB1c2gob0F0dHJpYnV0ZSk7XG5cdH1cblxuXHRyZXR1cm4gYU91dEF0dHJpYnV0ZXM7XG59XG5mdW5jdGlvbiBfZm5DaGVja0lzTWF0Y2gob09iamVjdDogYW55LCBvS2V5c1RvQ2hlY2s6IGFueSkge1xuXHRmb3IgKGNvbnN0IHNLZXkgaW4gb0tleXNUb0NoZWNrKSB7XG5cdFx0aWYgKG9LZXlzVG9DaGVja1tzS2V5XSAhPT0gb09iamVjdFtzS2V5XSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGZuR2V0Q29udGV4dFBhdGhQcm9wZXJ0aWVzKG9NZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsLCBzQ29udGV4dFBhdGg6IHN0cmluZywgb0ZpbHRlcj86IG9iamVjdCkge1xuXHRjb25zdCBvRW50aXR5VHlwZSA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNDb250ZXh0UGF0aCArIFwiL1wiKSB8fCB7fSxcblx0XHRvUHJvcGVydGllczogYW55ID0ge307XG5cblx0Zm9yIChjb25zdCBzS2V5IGluIG9FbnRpdHlUeXBlKSB7XG5cdFx0aWYgKFxuXHRcdFx0b0VudGl0eVR5cGUuaGFzT3duUHJvcGVydHkoc0tleSkgJiZcblx0XHRcdCEvXlxcJC9pLnRlc3Qoc0tleSkgJiZcblx0XHRcdG9FbnRpdHlUeXBlW3NLZXldLiRraW5kICYmXG5cdFx0XHRfZm5DaGVja0lzTWF0Y2gob0VudGl0eVR5cGVbc0tleV0sIG9GaWx0ZXIgfHwgeyAka2luZDogXCJQcm9wZXJ0eVwiIH0pXG5cdFx0KSB7XG5cdFx0XHRvUHJvcGVydGllc1tzS2V5XSA9IG9FbnRpdHlUeXBlW3NLZXldO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gb1Byb3BlcnRpZXM7XG59XG5mdW5jdGlvbiBmbkdldE1hbmRhdG9yeUZpbHRlckZpZWxkcyhvTWV0YU1vZGVsOiBPRGF0YU1ldGFNb2RlbCwgc0NvbnRleHRQYXRoOiBzdHJpbmcpIHtcblx0bGV0IGFNYW5kYXRvcnlGaWx0ZXJGaWVsZHM7XG5cdGlmIChvTWV0YU1vZGVsICYmIHNDb250ZXh0UGF0aCkge1xuXHRcdGFNYW5kYXRvcnlGaWx0ZXJGaWVsZHMgPSBvTWV0YU1vZGVsLmdldE9iamVjdChzQ29udGV4dFBhdGggKyBcIkBPcmcuT0RhdGEuQ2FwYWJpbGl0aWVzLlYxLkZpbHRlclJlc3RyaWN0aW9ucy9SZXF1aXJlZFByb3BlcnRpZXNcIik7XG5cdH1cblx0cmV0dXJuIGFNYW5kYXRvcnlGaWx0ZXJGaWVsZHM7XG59XG5mdW5jdGlvbiBmbkdldElCTkFjdGlvbnMob0NvbnRyb2w6IGFueSwgYUlCTkFjdGlvbnM6IGFueVtdKSB7XG5cdGNvbnN0IGFBY3Rpb25zID0gb0NvbnRyb2wgJiYgb0NvbnRyb2wuZ2V0QWN0aW9ucygpO1xuXHRpZiAoYUFjdGlvbnMpIHtcblx0XHRhQWN0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKG9BY3Rpb246IGFueSkge1xuXHRcdFx0aWYgKG9BY3Rpb24uaXNBKFwic2FwLnVpLm1kYy5hY3Rpb250b29sYmFyLkFjdGlvblRvb2xiYXJBY3Rpb25cIikpIHtcblx0XHRcdFx0b0FjdGlvbiA9IG9BY3Rpb24uZ2V0QWN0aW9uKCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAob0FjdGlvbi5kYXRhKFwiSUJORGF0YVwiKSkge1xuXHRcdFx0XHRhSUJOQWN0aW9ucy5wdXNoKG9BY3Rpb24pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBhSUJOQWN0aW9ucztcbn1cbi8qKlxuICogQHBhcmFtIGFJQk5BY3Rpb25zXG4gKiBAcGFyYW0gb1ZpZXdcbiAqL1xuZnVuY3Rpb24gZm5VcGRhdGVEYXRhRmllbGRGb3JJQk5CdXR0b25zVmlzaWJpbGl0eShhSUJOQWN0aW9uczogYW55W10sIG9WaWV3OiBWaWV3KSB7XG5cdGNvbnN0IG9QYXJhbXM6IGFueSA9IHt9O1xuXHRjb25zdCBmbkdldExpbmtzID0gZnVuY3Rpb24ob0RhdGE/OiBhbnkpIHtcblx0XHRpZiAob0RhdGEpIHtcblx0XHRcdGNvbnN0IGFLZXlzID0gT2JqZWN0LmtleXMob0RhdGEpO1xuXHRcdFx0YUtleXMuZm9yRWFjaChmdW5jdGlvbihzS2V5OiBzdHJpbmcpIHtcblx0XHRcdFx0aWYgKHNLZXkuaW5kZXhPZihcIl9cIikgIT09IDAgJiYgc0tleS5pbmRleE9mKFwib2RhdGEuY29udGV4dFwiKSA9PT0gLTEpIHtcblx0XHRcdFx0XHRvUGFyYW1zW3NLZXldID0geyB2YWx1ZTogb0RhdGFbc0tleV0gfTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdGlmIChhSUJOQWN0aW9ucy5sZW5ndGgpIHtcblx0XHRcdGFJQk5BY3Rpb25zLmZvckVhY2goZnVuY3Rpb24ob0lCTkFjdGlvbjogYW55KSB7XG5cdFx0XHRcdGNvbnN0IHNTZW1hbnRpY09iamVjdCA9IG9JQk5BY3Rpb24uZGF0YShcIklCTkRhdGFcIikuc2VtYW50aWNPYmplY3Q7XG5cdFx0XHRcdGNvbnN0IHNBY3Rpb24gPSBvSUJOQWN0aW9uLmRhdGEoXCJJQk5EYXRhXCIpLmFjdGlvbjtcblx0XHRcdFx0Q29tbW9uVXRpbHMuZ2V0U2hlbGxTZXJ2aWNlcyhvVmlldylcblx0XHRcdFx0XHQuZ2V0TGlua3Moe1xuXHRcdFx0XHRcdFx0c2VtYW50aWNPYmplY3Q6IHNTZW1hbnRpY09iamVjdCxcblx0XHRcdFx0XHRcdGFjdGlvbjogc0FjdGlvbixcblx0XHRcdFx0XHRcdHBhcmFtczogb1BhcmFtc1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24oYUxpbms6IGFueSkge1xuXHRcdFx0XHRcdFx0b0lCTkFjdGlvbi5zZXRWaXNpYmxlKG9JQk5BY3Rpb24uZ2V0VmlzaWJsZSgpICYmIGFMaW5rICYmIGFMaW5rLmxlbmd0aCA9PT0gMSk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0XHRcdExvZy5lcnJvcihcIkNhbm5vdCByZXRyaWV2ZSB0aGUgbGlua3MgZnJvbSB0aGUgc2hlbGwgc2VydmljZVwiLCBvRXJyb3IpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9O1xuXHRpZiAob1ZpZXcgJiYgb1ZpZXcuZ2V0QmluZGluZ0NvbnRleHQoKSkge1xuXHRcdChvVmlldy5nZXRCaW5kaW5nQ29udGV4dCgpIGFzIGFueSlcblx0XHRcdD8ucmVxdWVzdE9iamVjdCgpXG5cdFx0XHQudGhlbihmdW5jdGlvbihvRGF0YTogYW55KSB7XG5cdFx0XHRcdHJldHVybiBmbkdldExpbmtzKG9EYXRhKTtcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0TG9nLmVycm9yKFwiQ2Fubm90IHJldHJpZXZlIHRoZSBsaW5rcyBmcm9tIHRoZSBzaGVsbCBzZXJ2aWNlXCIsIG9FcnJvcik7XG5cdFx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRmbkdldExpbmtzKCk7XG5cdH1cbn1cbmZ1bmN0aW9uIGdldFRyYW5zbGF0ZWRUZXh0KHNGcmFtZXdvcmtLZXk6IHN0cmluZywgb1Jlc291cmNlQnVuZGxlOiBSZXNvdXJjZUJ1bmRsZSwgb1BhcmFtcz86IGFueSwgc0VudGl0eVNldE5hbWU/OiBzdHJpbmcpIHtcblx0bGV0IHNSZXNvdXJjZUtleSA9IHNGcmFtZXdvcmtLZXk7XG5cdGlmIChvUmVzb3VyY2VCdW5kbGUpIHtcblx0XHRpZiAoc0VudGl0eVNldE5hbWUpIHtcblx0XHRcdC8vIFRoZXJlIGFyZSBjb25zb2xlIGVycm9ycyBsb2dnZWQgd2hlbiBtYWtpbmcgY2FsbHMgdG8gZ2V0VGV4dCBmb3Iga2V5cyB0aGF0IGFyZSBub3QgZGVmaW5lZCBpbiB0aGUgcmVzb3VyY2UgYnVuZGxlXG5cdFx0XHQvLyBmb3IgaW5zdGFuY2Uga2V5cyB3aGljaCBhcmUgc3VwcG9zZWQgdG8gYmUgcHJvdmlkZWQgYnkgdGhlIGFwcGxpY2F0aW9uLCBlLmcsIDxrZXk+fDxlbnRpdHlTZXQ+IHRvIG92ZXJyaWRlIGluc3RhbmNlIHNwZWNpZmljIHRleHRcblx0XHRcdC8vIGhlbmNlIGNoZWNrIGlmIHRleHQgZXhpc3RzICh1c2luZyBcImhhc1RleHRcIikgaW4gdGhlIHJlc291cmNlIGJ1bmRsZSBiZWZvcmUgY2FsbGluZyBcImdldFRleHRcIlxuXG5cdFx0XHQvLyBcImhhc1RleHRcIiBvbmx5IGNoZWNrcyBmb3IgdGhlIGtleSBpbiB0aGUgaW1tZWRpYXRlIHJlc291cmNlIGJ1bmRsZSBhbmQgbm90IGl0J3MgY3VzdG9tIGJ1bmRsZXNcblx0XHRcdC8vIGhlbmNlIHdlIG5lZWQgdG8gZG8gdGhpcyByZWN1cnJzaXZlbHkgdG8gY2hlY2sgaWYgdGhlIGtleSBleGlzdHMgaW4gYW55IG9mIHRoZSBidW5kbGVzIHRoZSBmb3JtcyB0aGUgRkUgcmVzb3VyY2UgYnVuZGxlXG5cdFx0XHRjb25zdCBiUmVzb3VyY2VLZXlFeGlzdHMgPSBfY2hlY2tJZlJlc291cmNlS2V5RXhpc3RzKFxuXHRcdFx0XHQob1Jlc291cmNlQnVuZGxlIGFzIGFueSkuYUN1c3RvbUJ1bmRsZXMsXG5cdFx0XHRcdHNGcmFtZXdvcmtLZXkgKyBcInxcIiArIHNFbnRpdHlTZXROYW1lXG5cdFx0XHQpO1xuXG5cdFx0XHQvLyBpZiByZXNvdXJjZSBrZXkgd2l0aCBlbnRpdHkgc2V0IG5hbWUgZm9yIGluc3RhbmNlIHNwZWNpZmljIHRleHQgb3ZlcnJpZGluZyBpcyBwcm92aWRlZCBieSB0aGUgYXBwbGljYXRpb25cblx0XHRcdC8vIHRoZW4gdXNlIHRoZSBzYW1lIGtleSBvdGhlcndpc2UgdXNlIHRoZSBGcmFtZXdvcmsga2V5XG5cdFx0XHRzUmVzb3VyY2VLZXkgPSBiUmVzb3VyY2VLZXlFeGlzdHMgPyBzRnJhbWV3b3JrS2V5ICsgXCJ8XCIgKyBzRW50aXR5U2V0TmFtZSA6IHNGcmFtZXdvcmtLZXk7XG5cdFx0fVxuXHRcdHJldHVybiBvUmVzb3VyY2VCdW5kbGUuZ2V0VGV4dChzUmVzb3VyY2VLZXksIG9QYXJhbXMpO1xuXHR9XG5cblx0Ly8gZG8gbm90IGFsbG93IG92ZXJyaWRlIHNvIGdldCB0ZXh0IGZyb20gdGhlIGludGVybmFsIGJ1bmRsZSBkaXJlY3RseVxuXHRvUmVzb3VyY2VCdW5kbGUgPSBzYXAudWkuZ2V0Q29yZSgpLmdldExpYnJhcnlSZXNvdXJjZUJ1bmRsZShcInNhcC5mZS5jb3JlXCIpIGFzIFJlc291cmNlQnVuZGxlO1xuXHRyZXR1cm4gb1Jlc291cmNlQnVuZGxlLmdldFRleHQoc1Jlc291cmNlS2V5LCBvUGFyYW1zKTtcbn1cbmZ1bmN0aW9uIF9jaGVja0lmUmVzb3VyY2VLZXlFeGlzdHMoYUN1c3RvbUJ1bmRsZXM6IGFueSwgc0tleTogYW55KSB7XG5cdGlmIChhQ3VzdG9tQnVuZGxlcy5sZW5ndGgpIHtcblx0XHRmb3IgKGxldCBpID0gYUN1c3RvbUJ1bmRsZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0XHRcdGNvbnN0IHNWYWx1ZSA9IGFDdXN0b21CdW5kbGVzW2ldLmhhc1RleHQoc0tleSk7XG5cdFx0XHQvLyB0ZXh0IGZvdW5kIHJldHVybiB0cnVlXG5cdFx0XHRpZiAoc1ZhbHVlKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0X2NoZWNrSWZSZXNvdXJjZUtleUV4aXN0cyhhQ3VzdG9tQnVuZGxlc1tpXS5hQ3VzdG9tQnVuZGxlcywgc0tleSk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGdldEFjdGlvblBhdGgob0FjdGlvbjogYW55LCBiUmV0dXJuT25seVBhdGg6IGJvb2xlYW4sIHNBY3Rpb25OYW1lPzogc3RyaW5nLCBiQ2hlY2tTdGF0aWNWYWx1ZT86IGJvb2xlYW4pIHtcblx0c0FjdGlvbk5hbWUgPSAhc0FjdGlvbk5hbWUgPyBvQWN0aW9uLmdldE9iamVjdChvQWN0aW9uLmdldFBhdGgoKSkgOiBzQWN0aW9uTmFtZTtcblx0bGV0IHNDb250ZXh0UGF0aCA9IG9BY3Rpb24uZ2V0UGF0aCgpLnNwbGl0KFwiL0BcIilbMF07XG5cdGNvbnN0IHNFbnRpdHlUeXBlTmFtZSA9IG9BY3Rpb24uZ2V0T2JqZWN0KHNDb250ZXh0UGF0aCkuJFR5cGU7XG5cdGNvbnN0IHNFbnRpdHlOYW1lID0gZ2V0RW50aXR5U2V0TmFtZShvQWN0aW9uLmdldE1vZGVsKCksIHNFbnRpdHlUeXBlTmFtZSk7XG5cdGlmIChzRW50aXR5TmFtZSkge1xuXHRcdHNDb250ZXh0UGF0aCA9IFwiL1wiICsgc0VudGl0eU5hbWU7XG5cdH1cblx0aWYgKGJDaGVja1N0YXRpY1ZhbHVlKSB7XG5cdFx0cmV0dXJuIG9BY3Rpb24uZ2V0T2JqZWN0KHNDb250ZXh0UGF0aCArIFwiL1wiICsgc0FjdGlvbk5hbWUgKyBcIkBPcmcuT0RhdGEuQ29yZS5WMS5PcGVyYXRpb25BdmFpbGFibGVcIik7XG5cdH1cblx0aWYgKGJSZXR1cm5Pbmx5UGF0aCkge1xuXHRcdHJldHVybiBzQ29udGV4dFBhdGggKyBcIi9cIiArIHNBY3Rpb25OYW1lO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiB7XG5cdFx0XHRzQ29udGV4dFBhdGg6IHNDb250ZXh0UGF0aCxcblx0XHRcdHNQcm9wZXJ0eTogb0FjdGlvbi5nZXRPYmplY3Qoc0NvbnRleHRQYXRoICsgXCIvXCIgKyBzQWN0aW9uTmFtZSArIFwiQE9yZy5PRGF0YS5Db3JlLlYxLk9wZXJhdGlvbkF2YWlsYWJsZS8kUGF0aFwiKSxcblx0XHRcdHNCaW5kaW5nUGFyYW1ldGVyOiBvQWN0aW9uLmdldE9iamVjdChzQ29udGV4dFBhdGggKyBcIi9cIiArIHNBY3Rpb25OYW1lICsgXCIvQCR1aTUub3ZlcmxvYWQvMC8kUGFyYW1ldGVyLzAvJE5hbWVcIilcblx0XHR9O1xuXHR9XG59XG5mdW5jdGlvbiBnZXRFbnRpdHlTZXROYW1lKG9NZXRhTW9kZWw6IGFueSwgc0VudGl0eVR5cGU6IGFueSkge1xuXHRjb25zdCBvRW50aXR5Q29udGFpbmVyID0gb01ldGFNb2RlbC5nZXRPYmplY3QoXCIvXCIpO1xuXHRmb3IgKGNvbnN0IGtleSBpbiBvRW50aXR5Q29udGFpbmVyKSB7XG5cdFx0aWYgKHR5cGVvZiBvRW50aXR5Q29udGFpbmVyW2tleV0gPT09IFwib2JqZWN0XCIgJiYgb0VudGl0eUNvbnRhaW5lcltrZXldLiRUeXBlID09PSBzRW50aXR5VHlwZSkge1xuXHRcdFx0cmV0dXJuIGtleTtcblx0XHR9XG5cdH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVEaXNwbGF5TW9kZShvUHJvcGVydHlBbm5vdGF0aW9uczogYW55LCBvQ29sbGVjdGlvbkFubm90YXRpb25zOiBhbnkpIHtcblx0Y29uc3Qgb1RleHRBbm5vdGF0aW9uID0gb1Byb3BlcnR5QW5ub3RhdGlvbnNbXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlRleHRcIl0sXG5cdFx0b1RleHRBcnJhbmdlbWVudEFubm90YXRpb24gPVxuXHRcdFx0b1RleHRBbm5vdGF0aW9uICYmXG5cdFx0XHQoKG9Qcm9wZXJ0eUFubm90YXRpb25zICYmXG5cdFx0XHRcdG9Qcm9wZXJ0eUFubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5UZXh0QGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLlRleHRBcnJhbmdlbWVudFwiXSkgfHxcblx0XHRcdFx0KG9Db2xsZWN0aW9uQW5ub3RhdGlvbnMgJiYgb0NvbGxlY3Rpb25Bbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5UZXh0QXJyYW5nZW1lbnRcIl0pKTtcblxuXHRpZiAob1RleHRBcnJhbmdlbWVudEFubm90YXRpb24pIHtcblx0XHRpZiAob1RleHRBcnJhbmdlbWVudEFubm90YXRpb24uJEVudW1NZW1iZXIgPT09IFwiY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuVGV4dEFycmFuZ2VtZW50VHlwZS9UZXh0T25seVwiKSB7XG5cdFx0XHRyZXR1cm4gXCJEZXNjcmlwdGlvblwiO1xuXHRcdH0gZWxzZSBpZiAob1RleHRBcnJhbmdlbWVudEFubm90YXRpb24uJEVudW1NZW1iZXIgPT09IFwiY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuVGV4dEFycmFuZ2VtZW50VHlwZS9UZXh0TGFzdFwiKSB7XG5cdFx0XHRyZXR1cm4gXCJWYWx1ZURlc2NyaXB0aW9uXCI7XG5cdFx0fSBlbHNlIGlmIChvVGV4dEFycmFuZ2VtZW50QW5ub3RhdGlvbi4kRW51bU1lbWJlciA9PT0gXCJjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5UZXh0QXJyYW5nZW1lbnRUeXBlL1RleHRTZXBhcmF0ZVwiKSB7XG5cdFx0XHRyZXR1cm4gXCJWYWx1ZVwiO1xuXHRcdH1cblx0XHQvL0RlZmF1bHQgc2hvdWxkIGJlIFRleHRGaXJzdCBpZiB0aGVyZSBpcyBhIFRleHQgYW5ub3RhdGlvbiBhbmQgbmVpdGhlciBUZXh0T25seSBub3IgVGV4dExhc3QgYXJlIHNldFxuXHRcdHJldHVybiBcIkRlc2NyaXB0aW9uVmFsdWVcIjtcblx0fVxuXHRyZXR1cm4gb1RleHRBbm5vdGF0aW9uID8gXCJEZXNjcmlwdGlvblZhbHVlXCIgOiBcIlZhbHVlXCI7XG59XG5mdW5jdGlvbiBfZ2V0RW50aXR5VHlwZShvQ29udGV4dDogYW55KSB7XG5cdGNvbnN0IG9NZXRhTW9kZWwgPSBvQ29udGV4dC5nZXRNb2RlbCgpLmdldE1ldGFNb2RlbCgpO1xuXHRyZXR1cm4gb01ldGFNb2RlbC5nZXRPYmplY3Qob01ldGFNb2RlbC5nZXRNZXRhUGF0aChvQ29udGV4dC5nZXRQYXRoKCkpICsgXCIvJFR5cGVcIik7XG59XG5mdW5jdGlvbiBfcmVxdWVzdE9iamVjdChzQWN0aW9uOiBhbnksIG9TZWxlY3RlZENvbnRleHQ6IGFueSwgc1Byb3BlcnR5OiBhbnkpIHtcblx0bGV0IG9Db250ZXh0ID0gb1NlbGVjdGVkQ29udGV4dDtcblx0Y29uc3QgbkJyYWNrZXRJbmRleCA9IHNBY3Rpb24uaW5kZXhPZihcIihcIik7XG5cblx0aWYgKG5CcmFja2V0SW5kZXggPiAtMSkge1xuXHRcdGNvbnN0IHNUYXJnZXRUeXBlID0gc0FjdGlvbi5zbGljZShuQnJhY2tldEluZGV4ICsgMSwgLTEpO1xuXHRcdGxldCBzQ3VycmVudFR5cGUgPSBfZ2V0RW50aXR5VHlwZShvQ29udGV4dCk7XG5cblx0XHR3aGlsZSAoc0N1cnJlbnRUeXBlICE9PSBzVGFyZ2V0VHlwZSkge1xuXHRcdFx0Ly8gRmluZCBwYXJlbnQgYmluZGluZyBjb250ZXh0IGFuZCByZXRyaWV2ZSBlbnRpdHkgdHlwZVxuXHRcdFx0b0NvbnRleHQgPSBvQ29udGV4dC5nZXRCaW5kaW5nKCkuZ2V0Q29udGV4dCgpO1xuXHRcdFx0aWYgKG9Db250ZXh0KSB7XG5cdFx0XHRcdHNDdXJyZW50VHlwZSA9IF9nZXRFbnRpdHlUeXBlKG9Db250ZXh0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdExvZy53YXJuaW5nKFwiQ2Fubm90IGRldGVybWluZSB0YXJnZXQgdHlwZSB0byByZXF1ZXN0IHByb3BlcnR5IHZhbHVlIGZvciBib3VuZCBhY3Rpb24gaW52b2NhdGlvblwiKTtcblx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSh1bmRlZmluZWQpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBvQ29udGV4dC5yZXF1ZXN0T2JqZWN0KHNQcm9wZXJ0eSk7XG59XG5mdW5jdGlvbiBfcmVxdWVzdFByb3BlcnR5KG9TZWxlY3RlZENvbnRleHQ6IGFueSwgc0FjdGlvbjogYW55LCBzUHJvcGVydHk6IGFueSwgc0R5bmFtaWNBY3Rpb25FbmFibGVkUGF0aDogYW55KSB7XG5cdGNvbnN0IG9Qcm9taXNlID1cblx0XHRzUHJvcGVydHkgJiYgc1Byb3BlcnR5LmluZGV4T2YoXCIvXCIpID09PSAwXG5cdFx0XHQ/IHJlcXVlc3RTaW5nbGV0b25Qcm9wZXJ0eShzUHJvcGVydHksIG9TZWxlY3RlZENvbnRleHQuZ2V0TW9kZWwoKSlcblx0XHRcdDogX3JlcXVlc3RPYmplY3Qoc0FjdGlvbiwgb1NlbGVjdGVkQ29udGV4dCwgc1Byb3BlcnR5KTtcblxuXHRyZXR1cm4gb1Byb21pc2UudGhlbihmdW5jdGlvbih2UHJvcGVydHlWYWx1ZTogYW55KSB7XG5cdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG5cdFx0XHR2UHJvcGVydHlWYWx1ZTogdlByb3BlcnR5VmFsdWUsXG5cdFx0XHRvU2VsZWN0ZWRDb250ZXh0OiBvU2VsZWN0ZWRDb250ZXh0LFxuXHRcdFx0c0FjdGlvbjogc0FjdGlvbixcblx0XHRcdHNEeW5hbWljQWN0aW9uRW5hYmxlZFBhdGg6IHNEeW5hbWljQWN0aW9uRW5hYmxlZFBhdGhcblx0XHR9KTtcblx0fSk7XG59XG5mdW5jdGlvbiBfc2V0Q29udGV4dHNCYXNlZE9uT3BlcmF0aW9uQXZhaWxhYmxlKG9JbnRlcm5hbE1vZGVsQ29udGV4dDogYW55LCBhUmVxdWVzdFByb21pc2VzOiBhbnkpIHtcblx0cmV0dXJuIFByb21pc2UuYWxsKGFSZXF1ZXN0UHJvbWlzZXMpXG5cdFx0LnRoZW4oZnVuY3Rpb24oYVJlc3VsdHM6IFthbnksIGFueSwgYW55LCBhbnksIGFueSwgYW55LCBhbnksIGFueSwgYW55LCBhbnldKSB7XG5cdFx0XHRpZiAoYVJlc3VsdHMubGVuZ3RoKSB7XG5cdFx0XHRcdGNvbnN0IGFBcHBsaWNhYmxlQ29udGV4dHM6IGFueVtdID0gW10sXG5cdFx0XHRcdFx0YU5vdEFwcGxpY2FibGVDb250ZXh0czogYW55W10gPSBbXTtcblx0XHRcdFx0YVJlc3VsdHMuZm9yRWFjaChmdW5jdGlvbihhUmVzdWx0OiBhbnkpIHtcblx0XHRcdFx0XHRpZiAoYVJlc3VsdCkge1xuXHRcdFx0XHRcdFx0aWYgKGFSZXN1bHQudlByb3BlcnR5VmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0b0ludGVybmFsTW9kZWxDb250ZXh0LmdldE1vZGVsKCkuc2V0UHJvcGVydHkoYVJlc3VsdC5zRHluYW1pY0FjdGlvbkVuYWJsZWRQYXRoLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0YUFwcGxpY2FibGVDb250ZXh0cy5wdXNoKGFSZXN1bHQub1NlbGVjdGVkQ29udGV4dCk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRhTm90QXBwbGljYWJsZUNvbnRleHRzLnB1c2goYVJlc3VsdC5vU2VsZWN0ZWRDb250ZXh0KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRfc2V0RHluYW1pY0FjdGlvbkNvbnRleHRzKG9JbnRlcm5hbE1vZGVsQ29udGV4dCwgYVJlc3VsdHNbMF0uc0FjdGlvbiwgYUFwcGxpY2FibGVDb250ZXh0cywgYU5vdEFwcGxpY2FibGVDb250ZXh0cyk7XG5cdFx0XHR9XG5cdFx0fSlcblx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdExvZy50cmFjZShcIkNhbm5vdCByZXRyaWV2ZSBwcm9wZXJ0eSB2YWx1ZSBmcm9tIHBhdGhcIiwgb0Vycm9yKTtcblx0XHR9KTtcbn1cbi8qKlxuICogQHBhcmFtIG9JbnRlcm5hbE1vZGVsQ29udGV4dFxuICogQHBhcmFtIHNBY3Rpb25cbiAqIEBwYXJhbSBhQXBwbGljYWJsZVxuICogQHBhcmFtIGFOb3RBcHBsaWNhYmxlXG4gKi9cbmZ1bmN0aW9uIF9zZXREeW5hbWljQWN0aW9uQ29udGV4dHMob0ludGVybmFsTW9kZWxDb250ZXh0OiBhbnksIHNBY3Rpb246IGFueSwgYUFwcGxpY2FibGU6IGFueSwgYU5vdEFwcGxpY2FibGU6IGFueSkge1xuXHRjb25zdCBzRHluYW1pY0FjdGlvblBhdGhQcmVmaXggPSBvSW50ZXJuYWxNb2RlbENvbnRleHQuZ2V0UGF0aCgpICsgXCIvZHluYW1pY0FjdGlvbnMvXCIgKyBzQWN0aW9uLFxuXHRcdG9JbnRlcm5hbE1vZGVsID0gb0ludGVybmFsTW9kZWxDb250ZXh0LmdldE1vZGVsKCk7XG5cdG9JbnRlcm5hbE1vZGVsLnNldFByb3BlcnR5KHNEeW5hbWljQWN0aW9uUGF0aFByZWZpeCArIFwiL2FBcHBsaWNhYmxlXCIsIGFBcHBsaWNhYmxlKTtcblx0b0ludGVybmFsTW9kZWwuc2V0UHJvcGVydHkoc0R5bmFtaWNBY3Rpb25QYXRoUHJlZml4ICsgXCIvYU5vdEFwcGxpY2FibGVcIiwgYU5vdEFwcGxpY2FibGUpO1xufVxuZnVuY3Rpb24gc2V0QWN0aW9uRW5hYmxlbWVudChvSW50ZXJuYWxNb2RlbENvbnRleHQ6IGFueSwgb0FjdGlvbk9wZXJhdGlvbkF2YWlsYWJsZU1hcDogYW55LCBhU2VsZWN0ZWRDb250ZXh0czogYW55KSB7XG5cdGNvbnN0IGFQcm9taXNlcyA9IFtdO1xuXHRmb3IgKGNvbnN0IHNBY3Rpb24gaW4gb0FjdGlvbk9wZXJhdGlvbkF2YWlsYWJsZU1hcCkge1xuXHRcdC8vIFJlc2V0IGFsbCBwcm9wZXJ0aWVzIGJlZm9yZSBjb21wdXRhdGlvblxuXHRcdG9JbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcImR5bmFtaWNBY3Rpb25zL1wiICsgc0FjdGlvbiwge1xuXHRcdFx0YkVuYWJsZWQ6IGZhbHNlLFxuXHRcdFx0YUFwcGxpY2FibGU6IFtdLFxuXHRcdFx0YU5vdEFwcGxpY2FibGU6IFtdXG5cdFx0fSk7XG5cdFx0Ly8gTm90ZSB0aGF0IG5vbiBkeW5hbWljIGFjdGlvbnMgYXJlIG5vdCBwcm9jZXNzZWQgaGVyZS4gVGhleSBhcmUgZW5hYmxlZCBiZWNhdXNlXG5cdFx0Ly8gb25lIG9yIG1vcmUgYXJlIHNlbGVjdGVkIGFuZCB0aGUgc2Vjb25kIHBhcnQgb2YgdGhlIGNvbmRpdGlvbiBpbiB0aGUgdGVtcGxhdGluZ1xuXHRcdC8vIGlzIHRoZW4gdW5kZWZpbmVkIGFuZCB0aHVzIHRoZSBidXR0b24gdGFrZXMgdGhlIGRlZmF1bHQgZW5hYmxpbmcsIHdoaWNoIGlzIHRydWUhXG5cdFx0Y29uc3QgYUFwcGxpY2FibGUgPSBbXSxcblx0XHRcdGFOb3RBcHBsaWNhYmxlID0gW10sXG5cdFx0XHRzUHJvcGVydHkgPSBvQWN0aW9uT3BlcmF0aW9uQXZhaWxhYmxlTWFwW3NBY3Rpb25dLFxuXHRcdFx0c0R5bmFtaWNBY3Rpb25FbmFibGVkUGF0aCA9IG9JbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRQYXRoKCkgKyBcIi9keW5hbWljQWN0aW9ucy9cIiArIHNBY3Rpb24gKyBcIi9iRW5hYmxlZFwiO1xuXG5cdFx0aWYgKHR5cGVvZiBzUHJvcGVydHkgPT09IFwib2JqZWN0XCIgJiYgc1Byb3BlcnR5ICE9PSBudWxsICYmIHNQcm9wZXJ0eSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFTZWxlY3RlZENvbnRleHRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGNvbnN0IG9TZWxlY3RlZENvbnRleHQgPSBhU2VsZWN0ZWRDb250ZXh0c1tpXTtcblx0XHRcdFx0aWYgKG9TZWxlY3RlZENvbnRleHQpIHtcblx0XHRcdFx0XHRjb25zdCBvQ29udGV4dERhdGEgPSBvU2VsZWN0ZWRDb250ZXh0LmdldE9iamVjdCgpO1xuXHRcdFx0XHRcdGNvbnN0IG9UcmFuc2Zvcm1lZEJpbmRpbmcgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRcdHNQcm9wZXJ0eSxcblx0XHRcdFx0XHRcdFwiQmluZGluZ1wiLFxuXHRcdFx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3AtZnVuY1xuXHRcdFx0XHRcdFx0ZnVuY3Rpb24ob0JpbmRpbmdFeHByZXNzaW9uOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KG9Db250ZXh0RGF0YVtvQmluZGluZ0V4cHJlc3Npb24ucGF0aF0pO1xuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdHRydWVcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdGNvbnN0IHNSZXN1bHQgPSBjb21waWxlQmluZGluZyhvVHJhbnNmb3JtZWRCaW5kaW5nKTtcblx0XHRcdFx0XHRpZiAoc1Jlc3VsdCA9PT0gXCJ0cnVlXCIpIHtcblx0XHRcdFx0XHRcdG9JbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRNb2RlbCgpLnNldFByb3BlcnR5KHNEeW5hbWljQWN0aW9uRW5hYmxlZFBhdGgsIHRydWUpO1xuXHRcdFx0XHRcdFx0YUFwcGxpY2FibGUucHVzaChvU2VsZWN0ZWRDb250ZXh0KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0YU5vdEFwcGxpY2FibGUucHVzaChvU2VsZWN0ZWRDb250ZXh0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdF9zZXREeW5hbWljQWN0aW9uQ29udGV4dHMob0ludGVybmFsTW9kZWxDb250ZXh0LCBzQWN0aW9uLCBhQXBwbGljYWJsZSwgYU5vdEFwcGxpY2FibGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBhUmVxdWVzdFByb21pc2VzID0gW107XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFTZWxlY3RlZENvbnRleHRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGNvbnN0IG9TZWxlY3RlZENvbnRleHQgPSBhU2VsZWN0ZWRDb250ZXh0c1tpXTtcblx0XHRcdFx0aWYgKG9TZWxlY3RlZENvbnRleHQpIHtcblx0XHRcdFx0XHRjb25zdCBvQ29udGV4dERhdGEgPSBvU2VsZWN0ZWRDb250ZXh0LmdldE9iamVjdCgpO1xuXHRcdFx0XHRcdGlmIChzUHJvcGVydHkgPT09IG51bGwgJiYgISFvQ29udGV4dERhdGFbXCIjXCIgKyBzQWN0aW9uXSkge1xuXHRcdFx0XHRcdFx0Ly9sb29rIGZvciBhY3Rpb24gYWR2ZXJ0aXNlbWVudCBpZiBwcmVzZW50IGFuZCBpdHMgdmFsdWUgaXMgbm90IG51bGxcblx0XHRcdFx0XHRcdG9JbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRNb2RlbCgpLnNldFByb3BlcnR5KHNEeW5hbWljQWN0aW9uRW5hYmxlZFBhdGgsIHRydWUpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIENvbGxlY3QgcHJvbWlzZXMgdG8gcmV0cmlldmUgc2luZ2xldG9uIG9yIG5vcm1hbCBwcm9wZXJ0eSB2YWx1ZSBhc3luY2hyb25vdXNseVxuXHRcdFx0XHRcdFx0YVJlcXVlc3RQcm9taXNlcy5wdXNoKF9yZXF1ZXN0UHJvcGVydHkob1NlbGVjdGVkQ29udGV4dCwgc0FjdGlvbiwgc1Byb3BlcnR5LCBzRHluYW1pY0FjdGlvbkVuYWJsZWRQYXRoKSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFdoZW4gYWxsIHByb3BlcnR5IHZhbHVlcyBoYXZlIGJlZW4gcmV0cmlldmVkLCBzZXRcblx0XHRcdC8vIFRoZSBhcHBsaWNhYmxlIGFuZCBub3QtYXBwbGljYWJsZSBzZWxlY3RlZCBjb250ZXh0cyBmb3IgZWFjaCBhY3Rpb24gYW5kXG5cdFx0XHQvLyBUaGUgZW5hYmxlZCBwcm9wZXJ0eSBvZiB0aGUgZHluYW1pYyBhY3Rpb24gaW4gaW50ZXJuYWwgbW9kZWwgY29udGV4dC5cblx0XHRcdGFQcm9taXNlcy5wdXNoKF9zZXRDb250ZXh0c0Jhc2VkT25PcGVyYXRpb25BdmFpbGFibGUob0ludGVybmFsTW9kZWxDb250ZXh0LCBhUmVxdWVzdFByb21pc2VzKSk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBQcm9taXNlLmFsbChhUHJvbWlzZXMpO1xufVxuZnVuY3Rpb24gX2dldERlZmF1bHRPcGVyYXRvcnMob1JlYWxQcm9wZXJ0eTogYW55KSB7XG5cdC8vIG1kYyBkZWZpbmVzIHRoZSBmdWxsIHNldCBvZiBvcGVyYXRpb25zIHRoYXQgYXJlIG1lYW5pbmdmdWwgZm9yIGVhY2ggRWRtIFR5cGVcblx0Y29uc3Qgb0RhdGFDbGFzcyA9IFR5cGVVdGlsLmdldERhdGFUeXBlQ2xhc3NOYW1lKG9SZWFsUHJvcGVydHkpO1xuXHRjb25zdCBvQmFzZVR5cGUgPSBUeXBlVXRpbC5nZXRCYXNlVHlwZShvRGF0YUNsYXNzKTtcblx0cmV0dXJuIEZpbHRlck9wZXJhdG9yVXRpbC5nZXRPcGVyYXRvcnNGb3JUeXBlKG9CYXNlVHlwZSk7XG59XG5mdW5jdGlvbiBfZ2V0UmVzdHJpY3Rpb25zKGFEZWZhdWx0T3BzOiBhbnksIGFFeHByZXNzaW9uT3BzOiBhbnkpIHtcblx0Ly8gRnJvbSB0aGUgZGVmYXVsdCBzZXQgb2YgT3BlcmF0b3JzIGZvciB0aGUgQmFzZSBUeXBlLCBzZWxlY3QgdGhvc2UgdGhhdCBhcmUgZGVmaW5lZCBpbiB0aGUgQWxsb3dlZCBWYWx1ZS5cblx0Ly8gSW4gY2FzZSB0aGF0IG5vIG9wZXJhdG9ycyBhcmUgZm91bmQsIHJldHVybiB1bmRlZmluZWQgc28gdGhhdCB0aGUgZGVmYXVsdCBzZXQgaXMgdXNlZC5cblx0Y29uc3QgYU9wZXJhdG9ycyA9IGFEZWZhdWx0T3BzLmZpbHRlcihmdW5jdGlvbihzRWxlbWVudDogYW55KSB7XG5cdFx0cmV0dXJuIGFFeHByZXNzaW9uT3BzLmluZGV4T2Yoc0VsZW1lbnQpID4gLTE7XG5cdH0pO1xuXHRyZXR1cm4gYU9wZXJhdG9ycy50b1N0cmluZygpIHx8IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGdldFNwZWNpZmljQWxsb3dlZEV4cHJlc3Npb24oYUV4cHJlc3Npb25zOiBhbnkpIHtcblx0Y29uc3QgYUFsbG93ZWRFeHByZXNzaW9uc1ByaW9yaXR5ID0gQ29tbW9uVXRpbHMuQWxsb3dlZEV4cHJlc3Npb25zUHJpbztcblxuXHRhRXhwcmVzc2lvbnMuc29ydChmdW5jdGlvbihhOiBhbnksIGI6IGFueSkge1xuXHRcdHJldHVybiBhQWxsb3dlZEV4cHJlc3Npb25zUHJpb3JpdHkuaW5kZXhPZihhKSAtIGFBbGxvd2VkRXhwcmVzc2lvbnNQcmlvcml0eS5pbmRleE9mKGIpO1xuXHR9KTtcblxuXHRyZXR1cm4gYUV4cHJlc3Npb25zWzBdO1xufVxuZnVuY3Rpb24gZ2V0T3BlcmF0b3JzRm9yUHJvcGVydHkoXG5cdHNQcm9wZXJ0eTogYW55LFxuXHRzRW50aXR5U2V0UGF0aDogYW55LFxuXHRvQ29udGV4dDogYW55LFxuXHRzVHlwZT86IGFueSxcblx0YlVzZVNlbWFudGljRGF0ZVJhbmdlPzogYW55LFxuXHRzU2V0dGluZ3M/OiBhbnlcbikge1xuXHRjb25zdCBvRmlsdGVyUmVzdHJpY3Rpb25zID0gQ29tbW9uVXRpbHMuZ2V0RmlsdGVyUmVzdHJpY3Rpb25zQnlQYXRoKHNFbnRpdHlTZXRQYXRoLCBvQ29udGV4dCk7XG5cdGNvbnN0IGFFcXVhbHNPcHMgPSBbXCJFUVwiXTtcblx0Y29uc3QgYVNpbmdsZVJhbmdlT3BzID0gW1wiRVFcIiwgXCJHRVwiLCBcIkxFXCIsIFwiTFRcIiwgXCJHVFwiLCBcIkJUXCIsIFwiTk9UTEVcIiwgXCJOT1RMVFwiLCBcIk5PVEdFXCIsIFwiTk9UR1RcIl07XG5cdGNvbnN0IGFTaW5nbGVWYWx1ZURhdGVPcHMgPSBbXCJUT0RBWVwiLCBcIlRPTU9SUk9XXCIsIFwiWUVTVEVSREFZXCIsIFwiREFURVwiXTtcblx0Y29uc3QgYU11bHRpUmFuZ2VPcHMgPSBbXCJFUVwiLCBcIkdFXCIsIFwiTEVcIiwgXCJMVFwiLCBcIkdUXCIsIFwiQlRcIiwgXCJORVwiLCBcIk5PVEJUXCIsIFwiTk9UTEVcIiwgXCJOT1RMVFwiLCBcIk5PVEdFXCIsIFwiTk9UR1RcIl07XG5cdGNvbnN0IGFTZWFyY2hFeHByZXNzaW9uT3BzID0gW1wiQ29udGFpbnNcIiwgXCJOb3RDb250YWluc1wiLCBcIlN0YXJ0c1dpdGhcIiwgXCJOb3RTdGFydHNXaXRoXCIsIFwiRW5kc1dpdGhcIiwgXCJOb3RFbmRzV2l0aFwiXTtcblx0Y29uc3QgYVNlbWFudGljRGF0ZU9wc0V4dCA9IFNlbWFudGljRGF0ZU9wZXJhdG9ycy5nZXRTdXBwb3J0ZWRPcGVyYXRpb25zKCk7XG5cdGNvbnN0IGJTZW1hbnRpY0RhdGVSYW5nZSA9IGJVc2VTZW1hbnRpY0RhdGVSYW5nZSA9PT0gXCJ0cnVlXCIgfHwgYlVzZVNlbWFudGljRGF0ZVJhbmdlID09PSB0cnVlO1xuXHRsZXQgYVNlbWFudGljRGF0ZU9wczogYW55W10gPSBbXTtcblx0Y29uc3Qgb1NldHRpbmdzID0gdHlwZW9mIHNTZXR0aW5ncyA9PT0gXCJzdHJpbmdcIiA/IEpTT04ucGFyc2Uoc1NldHRpbmdzKS5jdXN0b21EYXRhIDogc1NldHRpbmdzO1xuXG5cdGlmIChvQ29udGV4dC5nZXRPYmplY3Qoc0VudGl0eVNldFBhdGggKyBcIi9AY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlJlc3VsdENvbnRleHRcIikgPT09IHRydWUpIHtcblx0XHRyZXR1cm4gYUVxdWFsc09wcy50b1N0cmluZygpO1xuXHR9XG5cblx0aWYgKG9TZXR0aW5ncyAmJiBvU2V0dGluZ3Mub3BlcmF0b3JDb25maWd1cmF0aW9uICYmIG9TZXR0aW5ncy5vcGVyYXRvckNvbmZpZ3VyYXRpb24ubGVuZ3RoID4gMCkge1xuXHRcdGFTZW1hbnRpY0RhdGVPcHMgPSBTZW1hbnRpY0RhdGVPcGVyYXRvcnMuZ2V0RmlsdGVyT3BlcmF0aW9ucyhvU2V0dGluZ3Mub3BlcmF0b3JDb25maWd1cmF0aW9uKTtcblx0fSBlbHNlIHtcblx0XHRhU2VtYW50aWNEYXRlT3BzID0gU2VtYW50aWNEYXRlT3BlcmF0b3JzLmdldFNlbWFudGljRGF0ZU9wZXJhdGlvbnMoKTtcblx0fVxuXG5cdC8vIEdldCB0aGUgZGVmYXVsdCBPcGVyYXRvcnMgZm9yIHRoaXMgUHJvcGVydHkgVHlwZVxuXHRsZXQgYURlZmF1bHRPcGVyYXRvcnMgPSBfZ2V0RGVmYXVsdE9wZXJhdG9ycyhzVHlwZSk7XG5cblx0Ly8gSXMgdGhlcmUgYSBGaWx0ZXIgUmVzdHJpY3Rpb24gZGVmaW5lZCBmb3IgdGhpcyBwcm9wZXJ0eT9cblx0aWYgKG9GaWx0ZXJSZXN0cmljdGlvbnMgJiYgb0ZpbHRlclJlc3RyaWN0aW9ucy5GaWx0ZXJBbGxvd2VkRXhwcmVzc2lvbnMgJiYgb0ZpbHRlclJlc3RyaWN0aW9ucy5GaWx0ZXJBbGxvd2VkRXhwcmVzc2lvbnNbc1Byb3BlcnR5XSkge1xuXHRcdC8vIEV4dGVuZGluZyB0aGUgZGVmYXVsdCBvcGVyYXRvcnMgbGlzdCB3aXRoIFNlbWFudGljIERhdGUgb3B0aW9ucyBEQVRFUkFOR0UsIERBVEUsIEZST00gYW5kIFRPXG5cdFx0aWYgKGJTZW1hbnRpY0RhdGVSYW5nZSkge1xuXHRcdFx0YURlZmF1bHRPcGVyYXRvcnMgPSBhU2VtYW50aWNEYXRlT3BzRXh0LmNvbmNhdChhRGVmYXVsdE9wZXJhdG9ycyk7XG5cdFx0fVxuXG5cdFx0Y29uc3Qgc0FsbG93ZWRFeHByZXNzaW9uID0gQ29tbW9uVXRpbHMuZ2V0U3BlY2lmaWNBbGxvd2VkRXhwcmVzc2lvbihvRmlsdGVyUmVzdHJpY3Rpb25zLkZpbHRlckFsbG93ZWRFeHByZXNzaW9uc1tzUHJvcGVydHldKTtcblx0XHRsZXQgc1Jlc3RyaWN0aW9ucztcblx0XHQvLyBJbiBjYXNlIG1vcmUgdGhhbiBvbmUgQWxsb3dlZCBFeHByZXNzaW9ucyBoYXMgYmVlbiBkZWZpbmVkIGZvciBhIHByb3BlcnR5XG5cdFx0Ly8gY2hvb3NlIHRoZSBtb3N0IHJlc3RyaWN0aXZlIEFsbG93ZWQgRXhwcmVzc2lvblxuXG5cdFx0Ly8gTXVsdGlWYWx1ZSBoYXMgc2FtZSBPcGVyYXRvciBhcyBTaW5nbGVWYWx1ZSwgYnV0IHRoZXJlIGNhbiBiZSBtb3JlIHRoYW4gb25lIChtYXhDb25kaXRpb25zKVxuXHRcdHN3aXRjaCAoc0FsbG93ZWRFeHByZXNzaW9uKSB7XG5cdFx0XHRjYXNlIFwiU2luZ2xlVmFsdWVcIjpcblx0XHRcdFx0Y29uc3QgYVNpbmdsZVZhbHVlT3BzID0gc1R5cGUgPT09IFwiRWRtLkRhdGVcIiAmJiBiU2VtYW50aWNEYXRlUmFuZ2UgPyBhU2luZ2xlVmFsdWVEYXRlT3BzIDogYUVxdWFsc09wcztcblx0XHRcdFx0c1Jlc3RyaWN0aW9ucyA9IF9nZXRSZXN0cmljdGlvbnMoYURlZmF1bHRPcGVyYXRvcnMsIGFTaW5nbGVWYWx1ZU9wcyk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIk11bHRpVmFsdWVcIjpcblx0XHRcdFx0c1Jlc3RyaWN0aW9ucyA9IF9nZXRSZXN0cmljdGlvbnMoYURlZmF1bHRPcGVyYXRvcnMsIGFFcXVhbHNPcHMpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJTaW5nbGVSYW5nZVwiOlxuXHRcdFx0XHRjb25zdCBzT3BlcmF0b3JzID0gX2dldFJlc3RyaWN0aW9ucyhcblx0XHRcdFx0XHRhRGVmYXVsdE9wZXJhdG9ycyxcblx0XHRcdFx0XHRzVHlwZSA9PT0gXCJFZG0uRGF0ZVwiICYmIGJTZW1hbnRpY0RhdGVSYW5nZSA/IGFTZW1hbnRpY0RhdGVPcHMgOiBhU2luZ2xlUmFuZ2VPcHNcblx0XHRcdFx0KTtcblx0XHRcdFx0c1Jlc3RyaWN0aW9ucyA9IHNPcGVyYXRvcnMgPyBzT3BlcmF0b3JzIDogXCJcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTXVsdGlSYW5nZVwiOlxuXHRcdFx0XHRzUmVzdHJpY3Rpb25zID0gX2dldFJlc3RyaWN0aW9ucyhhRGVmYXVsdE9wZXJhdG9ycywgYU11bHRpUmFuZ2VPcHMpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJTZWFyY2hFeHByZXNzaW9uXCI6XG5cdFx0XHRcdHNSZXN0cmljdGlvbnMgPSBfZ2V0UmVzdHJpY3Rpb25zKGFEZWZhdWx0T3BlcmF0b3JzLCBhU2VhcmNoRXhwcmVzc2lvbk9wcyk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIk11bHRpUmFuZ2VPclNlYXJjaEV4cHJlc3Npb25cIjpcblx0XHRcdFx0c1Jlc3RyaWN0aW9ucyA9IF9nZXRSZXN0cmljdGlvbnMoYURlZmF1bHRPcGVyYXRvcnMsIGFTZWFyY2hFeHByZXNzaW9uT3BzLmNvbmNhdChhTXVsdGlSYW5nZU9wcykpO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdC8vIEluIGNhc2UgQWxsb3dlZEV4cHJlc3Npb25zIGlzIG5vdCByZWNvZ25pc2VkLCB1bmRlZmluZWQgaW4gcmV0dXJuIHJlc3VsdHMgaW4gdGhlIGRlZmF1bHQgc2V0IG9mXG5cdFx0Ly8gb3BlcmF0b3JzIGZvciB0aGUgdHlwZS5cblx0XHRyZXR1cm4gc1Jlc3RyaWN0aW9ucztcblx0fSBlbHNlIGlmIChzVHlwZSA9PT0gXCJFZG0uRGF0ZVwiKSB7XG5cdFx0Ly8gSW4gY2FzZSBBbGxvd2VkRXhwcmVzc2lvbnMgaXMgbm90IHByb3ZpZGVkIGZvciB0eXBlIEVkbS5EYXRlIHRoZW4gYWxsIHRoZSBkZWZhdWx0XG5cdFx0Ly8gb3BlcmF0b3JzIGZvciB0aGUgdHlwZSBzaG91bGQgYmUgcmV0dXJuZWQgZXhjbHVkaW5nIHNlbWFudGljIG9wZXJhdG9ycyBmcm9tIHRoZSBsaXN0LlxuXHRcdGFTZW1hbnRpY0RhdGVPcHMgPSBTZW1hbnRpY0RhdGVPcGVyYXRvcnMuZ2V0U2VtYW50aWNEYXRlT3BlcmF0aW9ucygpO1xuXHRcdGNvbnN0IGFPcGVyYXRvcnMgPSBhRGVmYXVsdE9wZXJhdG9ycy5maWx0ZXIoZnVuY3Rpb24oc0VsZW1lbnQ6IGFueSkge1xuXHRcdFx0cmV0dXJuIGFTZW1hbnRpY0RhdGVPcHMuaW5kZXhPZihzRWxlbWVudCkgPCAwO1xuXHRcdH0pO1xuXHRcdHJldHVybiBhT3BlcmF0b3JzLnRvU3RyaW5nKCk7XG5cdH1cbn1cbmZ1bmN0aW9uIGdldFBhcmFtZXRlckluZm8ob01ldGFNb2RlbDogYW55LCBzQ29udGV4dFBhdGg6IGFueSkge1xuXHRjb25zdCBzUGFyYW1ldGVyQ29udGV4dFBhdGggPSBzQ29udGV4dFBhdGguc3Vic3RyaW5nKDAsIHNDb250ZXh0UGF0aC5sYXN0SW5kZXhPZihcIi9cIikpO1xuXHRjb25zdCBiUmVzdWx0Q29udGV4dCA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNQYXJhbWV0ZXJDb250ZXh0UGF0aCArIFwiL0Bjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuUmVzdWx0Q29udGV4dFwiKTtcblx0Y29uc3Qgb1BhcmFtZXRlckluZm86IGFueSA9IHt9O1xuXHRpZiAoYlJlc3VsdENvbnRleHQgJiYgc1BhcmFtZXRlckNvbnRleHRQYXRoICE9PSBzQ29udGV4dFBhdGgpIHtcblx0XHRvUGFyYW1ldGVySW5mby5jb250ZXh0UGF0aCA9IHNQYXJhbWV0ZXJDb250ZXh0UGF0aDtcblx0XHRvUGFyYW1ldGVySW5mby5wYXJhbWV0ZXJQcm9wZXJ0aWVzID0gQ29tbW9uVXRpbHMuZ2V0Q29udGV4dFBhdGhQcm9wZXJ0aWVzKG9NZXRhTW9kZWwsIHNQYXJhbWV0ZXJDb250ZXh0UGF0aCk7XG5cdH1cblx0cmV0dXJuIG9QYXJhbWV0ZXJJbmZvO1xufVxuZnVuY3Rpb24gYWRkU2VsZWN0T3B0aW9uVG9Db25kaXRpb25zKG9Qcm9wZXJ0eU1ldGFkYXRhOiBhbnksIGFWYWxpZE9wZXJhdG9yczogYW55LCBhQ3VtdWxhdGl2ZUNvbmRpdGlvbnM6IGFueSwgb1NlbGVjdE9wdGlvbjogYW55KSB7XG5cdGNvbnN0IG9Db25kaXRpb24gPSBnZXRDb25kaXRpb25zKG9TZWxlY3RPcHRpb24sIG9Qcm9wZXJ0eU1ldGFkYXRhKTtcblx0aWYgKG9Db25kaXRpb24pIHtcblx0XHRpZiAoIWFWYWxpZE9wZXJhdG9ycyB8fCBhVmFsaWRPcGVyYXRvcnMuaW5kZXhPZihvQ29uZGl0aW9uLm9wZXJhdG9yKSA+IC0xKSB7XG5cdFx0XHRhQ3VtdWxhdGl2ZUNvbmRpdGlvbnMucHVzaChvQ29uZGl0aW9uKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGFDdW11bGF0aXZlQ29uZGl0aW9ucztcbn1cbi8qKlxuICogQHBhcmFtIHNDb250ZXh0UGF0aFxuICogQHBhcmFtIG9TZWxlY3Rpb25WYXJpYW50XG4gKiBAcGFyYW0gc1NlbGVjdE9wdGlvblByb3BcbiAqIEBwYXJhbSBvQ29uZGl0aW9uc1xuICogQHBhcmFtIHNDb25kaXRpb25QYXRoXG4gKiBAcGFyYW0gc0NvbmRpdGlvblByb3BcbiAqIEBwYXJhbSBvVmFsaWRQcm9wZXJ0aWVzXG4gKiBAcGFyYW0gb01ldGFNb2RlbFxuICogQHBhcmFtIGlzUGFyYW1ldGVyXG4gKi9cbmZ1bmN0aW9uIGFkZFNlbGVjdE9wdGlvbnNUb0NvbmRpdGlvbnMoXG5cdHNDb250ZXh0UGF0aDogYW55LFxuXHRvU2VsZWN0aW9uVmFyaWFudDogYW55LFxuXHRzU2VsZWN0T3B0aW9uUHJvcDogYW55LFxuXHRvQ29uZGl0aW9uczogYW55LFxuXHRzQ29uZGl0aW9uUGF0aDogYW55LFxuXHRzQ29uZGl0aW9uUHJvcDogYW55LFxuXHRvVmFsaWRQcm9wZXJ0aWVzOiBhbnksXG5cdG9NZXRhTW9kZWw6IGFueSxcblx0aXNQYXJhbWV0ZXI6IGFueVxuKSB7XG5cdGxldCBhQ29uZGl0aW9uczogYW55W10gPSBbXSxcblx0XHRhU2VsZWN0T3B0aW9ucyxcblx0XHRhVmFsaWRPcGVyYXRvcnM7XG5cblx0aWYgKGlzUGFyYW1ldGVyIHx8IENvbW1vblV0aWxzLmlzUHJvcGVydHlGaWx0ZXJhYmxlKG9NZXRhTW9kZWwsIHNDb250ZXh0UGF0aCwgc0NvbmRpdGlvblByb3AsIHRydWUpKSB7XG5cdFx0YVNlbGVjdE9wdGlvbnMgPSBvU2VsZWN0aW9uVmFyaWFudC5nZXRTZWxlY3RPcHRpb24oc1NlbGVjdE9wdGlvblByb3ApO1xuXHRcdGFWYWxpZE9wZXJhdG9ycyA9IGlzUGFyYW1ldGVyID8gW1wiRVFcIl0gOiBDb21tb25VdGlscy5nZXRPcGVyYXRvcnNGb3JQcm9wZXJ0eShzQ29uZGl0aW9uUHJvcCwgc0NvbnRleHRQYXRoLCBvTWV0YU1vZGVsKTtcblx0XHRjb25zdCBvUHJvcGVydHlNZXRhZGF0YSA9IG9WYWxpZFByb3BlcnRpZXNbc0NvbmRpdGlvblByb3BdO1xuXHRcdC8vIENyZWF0ZSBjb25kaXRpb25zIGZvciBhbGwgdGhlIHNlbGVjdE9wdGlvbnMgb2YgdGhlIHByb3BlcnR5XG5cdFx0YUNvbmRpdGlvbnMgPSBpc1BhcmFtZXRlclxuXHRcdFx0PyBhZGRTZWxlY3RPcHRpb25Ub0NvbmRpdGlvbnMob1Byb3BlcnR5TWV0YWRhdGEsIGFWYWxpZE9wZXJhdG9ycywgYUNvbmRpdGlvbnMsIGFTZWxlY3RPcHRpb25zWzBdKVxuXHRcdFx0OiBhU2VsZWN0T3B0aW9ucy5yZWR1Y2UoYWRkU2VsZWN0T3B0aW9uVG9Db25kaXRpb25zLmJpbmQobnVsbCwgb1Byb3BlcnR5TWV0YWRhdGEsIGFWYWxpZE9wZXJhdG9ycyksIGFDb25kaXRpb25zKTtcblx0XHRpZiAoYUNvbmRpdGlvbnMubGVuZ3RoKSB7XG5cdFx0XHRpZiAoc0NvbmRpdGlvblBhdGgpIHtcblx0XHRcdFx0b0NvbmRpdGlvbnNbc0NvbmRpdGlvblBhdGggKyBzQ29uZGl0aW9uUHJvcF0gPSBvQ29uZGl0aW9ucy5oYXNPd25Qcm9wZXJ0eShzQ29uZGl0aW9uUGF0aCArIHNDb25kaXRpb25Qcm9wKVxuXHRcdFx0XHRcdD8gb0NvbmRpdGlvbnNbc0NvbmRpdGlvblBhdGggKyBzQ29uZGl0aW9uUHJvcF0uY29uY2F0KGFDb25kaXRpb25zKVxuXHRcdFx0XHRcdDogYUNvbmRpdGlvbnM7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvQ29uZGl0aW9uc1tzQ29uZGl0aW9uUHJvcF0gPSBvQ29uZGl0aW9ucy5oYXNPd25Qcm9wZXJ0eShzQ29uZGl0aW9uUHJvcClcblx0XHRcdFx0XHQ/IG9Db25kaXRpb25zW3NDb25kaXRpb25Qcm9wXS5jb25jYXQoYUNvbmRpdGlvbnMpXG5cdFx0XHRcdFx0OiBhQ29uZGl0aW9ucztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gYWRkU2VsZWN0aW9uVmFyaWFudFRvQ29uZGl0aW9ucyhvU2VsZWN0aW9uVmFyaWFudDogYW55LCBvQ29uZGl0aW9uczogb2JqZWN0LCBvTWV0YU1vZGVsOiBPRGF0YU1ldGFNb2RlbCwgc0NvbnRleHRQYXRoOiBzdHJpbmcpIHtcblx0Y29uc3QgYVNlbGVjdE9wdGlvbnNQcm9wZXJ0eU5hbWVzID0gb1NlbGVjdGlvblZhcmlhbnQuZ2V0U2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMoKSxcblx0XHRvVmFsaWRQcm9wZXJ0aWVzID0gQ29tbW9uVXRpbHMuZ2V0Q29udGV4dFBhdGhQcm9wZXJ0aWVzKG9NZXRhTW9kZWwsIHNDb250ZXh0UGF0aCksXG5cdFx0YU1ldGFkYXRQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMob1ZhbGlkUHJvcGVydGllcyksXG5cdFx0b1BhcmFtZXRlckluZm8gPSBDb21tb25VdGlscy5nZXRQYXJhbWV0ZXJJbmZvKG9NZXRhTW9kZWwsIHNDb250ZXh0UGF0aCksXG5cdFx0c1BhcmFtZXRlckNvbnRleHRQYXRoID0gb1BhcmFtZXRlckluZm8uY29udGV4dFBhdGgsXG5cdFx0b1ZhbGlkUGFyYW1ldGVyUHJvcGVydGllcyA9IG9QYXJhbWV0ZXJJbmZvLnBhcmFtZXRlclByb3BlcnRpZXMsXG5cdFx0Ykhhc1BhcmFtZXRlcnMgPSAhIW9QYXJhbWV0ZXJJbmZvLmNvbnRleHRQYXRoICYmIG9WYWxpZFBhcmFtZXRlclByb3BlcnRpZXMgJiYgT2JqZWN0LmtleXMob1ZhbGlkUGFyYW1ldGVyUHJvcGVydGllcykubGVuZ3RoID4gMDtcblxuXHRpZiAoYkhhc1BhcmFtZXRlcnMpIHtcblx0XHRjb25zdCBhTWV0YWRhdGFQYXJhbWV0ZXJzID0gT2JqZWN0LmtleXMob1ZhbGlkUGFyYW1ldGVyUHJvcGVydGllcyk7XG5cdFx0YU1ldGFkYXRhUGFyYW1ldGVycy5mb3JFYWNoKGZ1bmN0aW9uKHNNZXRhZGF0YVBhcmFtZXRlcjogc3RyaW5nKSB7XG5cdFx0XHRsZXQgc1NlbGVjdE9wdGlvbk5hbWU7XG5cdFx0XHRpZiAoYVNlbGVjdE9wdGlvbnNQcm9wZXJ0eU5hbWVzLmluY2x1ZGVzKFwiJFBhcmFtZXRlci5cIiArIHNNZXRhZGF0YVBhcmFtZXRlcikpIHtcblx0XHRcdFx0c1NlbGVjdE9wdGlvbk5hbWUgPSBcIiRQYXJhbWV0ZXIuXCIgKyBzTWV0YWRhdGFQYXJhbWV0ZXI7XG5cdFx0XHR9IGVsc2UgaWYgKGFTZWxlY3RPcHRpb25zUHJvcGVydHlOYW1lcy5pbmNsdWRlcyhzTWV0YWRhdGFQYXJhbWV0ZXIpKSB7XG5cdFx0XHRcdHNTZWxlY3RPcHRpb25OYW1lID0gc01ldGFkYXRhUGFyYW1ldGVyO1xuXHRcdFx0fSBlbHNlIGlmIChcblx0XHRcdFx0c01ldGFkYXRhUGFyYW1ldGVyLnN0YXJ0c1dpdGgoXCJQX1wiKSAmJlxuXHRcdFx0XHRhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMuaW5jbHVkZXMoXCIkUGFyYW1ldGVyLlwiICsgc01ldGFkYXRhUGFyYW1ldGVyLnNsaWNlKDIsIHNNZXRhZGF0YVBhcmFtZXRlci5sZW5ndGgpKVxuXHRcdFx0KSB7XG5cdFx0XHRcdHNTZWxlY3RPcHRpb25OYW1lID0gXCIkUGFyYW1ldGVyLlwiICsgc01ldGFkYXRhUGFyYW1ldGVyLnNsaWNlKDIsIHNNZXRhZGF0YVBhcmFtZXRlci5sZW5ndGgpO1xuXHRcdFx0fSBlbHNlIGlmIChcblx0XHRcdFx0c01ldGFkYXRhUGFyYW1ldGVyLnN0YXJ0c1dpdGgoXCJQX1wiKSAmJlxuXHRcdFx0XHRhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMuaW5jbHVkZXMoc01ldGFkYXRhUGFyYW1ldGVyLnNsaWNlKDIsIHNNZXRhZGF0YVBhcmFtZXRlci5sZW5ndGgpKVxuXHRcdFx0KSB7XG5cdFx0XHRcdHNTZWxlY3RPcHRpb25OYW1lID0gc01ldGFkYXRhUGFyYW1ldGVyLnNsaWNlKDIsIHNNZXRhZGF0YVBhcmFtZXRlci5sZW5ndGgpO1xuXHRcdFx0fSBlbHNlIGlmIChhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMuaW5jbHVkZXMoXCIkUGFyYW1ldGVyLlBfXCIgKyBzTWV0YWRhdGFQYXJhbWV0ZXIpKSB7XG5cdFx0XHRcdHNTZWxlY3RPcHRpb25OYW1lID0gXCIkUGFyYW1ldGVyLlBfXCIgKyBzTWV0YWRhdGFQYXJhbWV0ZXI7XG5cdFx0XHR9IGVsc2UgaWYgKGFTZWxlY3RPcHRpb25zUHJvcGVydHlOYW1lcy5pbmNsdWRlcyhcIlBfXCIgKyBzTWV0YWRhdGFQYXJhbWV0ZXIpKSB7XG5cdFx0XHRcdHNTZWxlY3RPcHRpb25OYW1lID0gXCJQX1wiICsgc01ldGFkYXRhUGFyYW1ldGVyO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoc1NlbGVjdE9wdGlvbk5hbWUpIHtcblx0XHRcdFx0YWRkU2VsZWN0T3B0aW9uc1RvQ29uZGl0aW9ucyhcblx0XHRcdFx0XHRzUGFyYW1ldGVyQ29udGV4dFBhdGgsXG5cdFx0XHRcdFx0b1NlbGVjdGlvblZhcmlhbnQsXG5cdFx0XHRcdFx0c1NlbGVjdE9wdGlvbk5hbWUsXG5cdFx0XHRcdFx0b0NvbmRpdGlvbnMsXG5cdFx0XHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0XHRcdHNNZXRhZGF0YVBhcmFtZXRlcixcblx0XHRcdFx0XHRvVmFsaWRQYXJhbWV0ZXJQcm9wZXJ0aWVzLFxuXHRcdFx0XHRcdG9NZXRhTW9kZWwsXG5cdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdGFNZXRhZGF0UHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uKHNNZXRhZGF0YVByb3BlcnR5OiBzdHJpbmcpIHtcblx0XHRsZXQgc1NlbGVjdE9wdGlvbk5hbWU7XG5cdFx0aWYgKGFTZWxlY3RPcHRpb25zUHJvcGVydHlOYW1lcy5pbmNsdWRlcyhzTWV0YWRhdGFQcm9wZXJ0eSkpIHtcblx0XHRcdHNTZWxlY3RPcHRpb25OYW1lID0gc01ldGFkYXRhUHJvcGVydHk7XG5cdFx0fSBlbHNlIGlmIChcblx0XHRcdHNNZXRhZGF0YVByb3BlcnR5LnN0YXJ0c1dpdGgoXCJQX1wiKSAmJlxuXHRcdFx0YVNlbGVjdE9wdGlvbnNQcm9wZXJ0eU5hbWVzLmluY2x1ZGVzKHNNZXRhZGF0YVByb3BlcnR5LnNsaWNlKDIsIHNNZXRhZGF0YVByb3BlcnR5Lmxlbmd0aCkpXG5cdFx0KSB7XG5cdFx0XHRzU2VsZWN0T3B0aW9uTmFtZSA9IHNNZXRhZGF0YVByb3BlcnR5LnNsaWNlKDIsIHNNZXRhZGF0YVByb3BlcnR5Lmxlbmd0aCk7XG5cdFx0fSBlbHNlIGlmIChhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMuaW5jbHVkZXMoXCJQX1wiICsgc01ldGFkYXRhUHJvcGVydHkpKSB7XG5cdFx0XHRzU2VsZWN0T3B0aW9uTmFtZSA9IFwiUF9cIiArIHNNZXRhZGF0YVByb3BlcnR5O1xuXHRcdH1cblx0XHRpZiAoc1NlbGVjdE9wdGlvbk5hbWUpIHtcblx0XHRcdGFkZFNlbGVjdE9wdGlvbnNUb0NvbmRpdGlvbnMoXG5cdFx0XHRcdHNDb250ZXh0UGF0aCxcblx0XHRcdFx0b1NlbGVjdGlvblZhcmlhbnQsXG5cdFx0XHRcdHNTZWxlY3RPcHRpb25OYW1lLFxuXHRcdFx0XHRvQ29uZGl0aW9ucyxcblx0XHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0XHRzTWV0YWRhdGFQcm9wZXJ0eSxcblx0XHRcdFx0b1ZhbGlkUHJvcGVydGllcyxcblx0XHRcdFx0b01ldGFNb2RlbCxcblx0XHRcdFx0ZmFsc2Vcblx0XHRcdCk7XG5cdFx0fVxuXHR9KTtcblxuXHRhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMuZm9yRWFjaChmdW5jdGlvbihzU2VsZWN0T3B0aW9uOiBhbnkpIHtcblx0XHRpZiAoc1NlbGVjdE9wdGlvbi5pbmRleE9mKFwiLlwiKSA+IDAgJiYgIXNTZWxlY3RPcHRpb24uaW5jbHVkZXMoXCIkUGFyYW1ldGVyXCIpKSB7XG5cdFx0XHRjb25zdCBzRnVsbENvbnRleHRQYXRoID0gKFwiL1wiICsgc1NlbGVjdE9wdGlvbi5yZXBsYWNlQWxsKFwiLlwiLCBcIi9cIikpLnN0YXJ0c1dpdGgoc0NvbnRleHRQYXRoKVxuXHRcdFx0XHQ/IFwiL1wiICsgc1NlbGVjdE9wdGlvbi5yZXBsYWNlQWxsKFwiLlwiLCBcIi9cIilcblx0XHRcdFx0OiBzQ29udGV4dFBhdGggKyBcIi9cIiArIHNTZWxlY3RPcHRpb24ucmVwbGFjZUFsbChcIi5cIiwgXCIvXCIpOyAvLyBjaGVjayBpZiB0aGUgZnVsbCBwYXRoLCBlZyBTYWxlc09yZGVyTWFuYWdlLl9JdGVtLk1hdGVyaWFsIGV4aXN0cyBpbiB0aGUgbWV0YW1vZGVsXG5cdFx0XHRpZiAob01ldGFNb2RlbC5nZXRPYmplY3Qoc0Z1bGxDb250ZXh0UGF0aC5yZXBsYWNlKFwiUF9cIiwgXCJcIikpKSB7XG5cdFx0XHRcdF9jcmVhdGVDb25kaXRpb25zRm9yTmF2UHJvcGVydGllcyhcblx0XHRcdFx0XHRzRnVsbENvbnRleHRQYXRoLFxuXHRcdFx0XHRcdHNDb250ZXh0UGF0aCxcblx0XHRcdFx0XHRvU2VsZWN0aW9uVmFyaWFudCxcblx0XHRcdFx0XHRzU2VsZWN0T3B0aW9uLFxuXHRcdFx0XHRcdG9NZXRhTW9kZWwsXG5cdFx0XHRcdFx0b0NvbmRpdGlvbnNcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4gb0NvbmRpdGlvbnM7XG59XG4vKipcbiAqIEBwYXJhbSBzRnVsbENvbnRleHRQYXRoXG4gKiBAcGFyYW0gc01haW5FbnRpdHlTZXRQYXRoXG4gKiBAcGFyYW0gb1NlbGVjdGlvblZhcmlhbnRcbiAqIEBwYXJhbSBzU2VsZWN0T3B0aW9uXG4gKiBAcGFyYW0gb01ldGFNb2RlbFxuICogQHBhcmFtIG9Db25kaXRpb25zXG4gKi9cbmZ1bmN0aW9uIF9jcmVhdGVDb25kaXRpb25zRm9yTmF2UHJvcGVydGllcyhcblx0c0Z1bGxDb250ZXh0UGF0aDogYW55LFxuXHRzTWFpbkVudGl0eVNldFBhdGg6IGFueSxcblx0b1NlbGVjdGlvblZhcmlhbnQ6IGFueSxcblx0c1NlbGVjdE9wdGlvbjogYW55LFxuXHRvTWV0YU1vZGVsOiBhbnksXG5cdG9Db25kaXRpb25zOiBhbnlcbikge1xuXHRsZXQgYU5hdk9iamVjdE5hbWVzID0gc1NlbGVjdE9wdGlvbi5zcGxpdChcIi5cIik7XG5cdC8vIEVnOiBcIlNhbGVzT3JkZXJNYW5hZ2UuX0l0ZW0uX01hdGVyaWFsLk1hdGVyaWFsXCIgb3IgXCJfSXRlbS5NYXRlcmlhbFwiXG5cdGlmICgoXCIvXCIgKyBzU2VsZWN0T3B0aW9uLnJlcGxhY2VBbGwoXCIuXCIsIFwiL1wiKSkuc3RhcnRzV2l0aChzTWFpbkVudGl0eVNldFBhdGgpKSB7XG5cdFx0Y29uc3Qgc0Z1bGxQYXRoID0gKChcIi9cIiArIHNTZWxlY3RPcHRpb24pIGFzIGFueSkucmVwbGFjZUFsbChcIi5cIiwgXCIvXCIpLFxuXHRcdFx0c05hdlBhdGggPSBzRnVsbFBhdGgucmVwbGFjZShzTWFpbkVudGl0eVNldFBhdGggKyBcIi9cIiwgXCJcIik7XG5cdFx0YU5hdk9iamVjdE5hbWVzID0gc05hdlBhdGguc3BsaXQoXCIvXCIpO1xuXHR9XG5cdGxldCBzQ29uZGl0aW9uUGF0aCA9IFwiXCI7XG5cdGNvbnN0IHNQcm9wZXJ0eU5hbWUgPSBhTmF2T2JqZWN0TmFtZXNbYU5hdk9iamVjdE5hbWVzLmxlbmd0aCAtIDFdOyAvLyBNYXRlcmlhbCBmcm9tIFNhbGVzT3JkZXJNYW5hZ2UuX0l0ZW0uTWF0ZXJpYWxcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhTmF2T2JqZWN0TmFtZXMubGVuZ3RoIC0gMTsgaSsrKSB7XG5cdFx0aWYgKG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNYWluRW50aXR5U2V0UGF0aCArIFwiL1wiICsgYU5hdk9iamVjdE5hbWVzW2ldLnJlcGxhY2UoXCJQX1wiLCBcIlwiKSkuJGlzQ29sbGVjdGlvbikge1xuXHRcdFx0c0NvbmRpdGlvblBhdGggPSBzQ29uZGl0aW9uUGF0aCArIGFOYXZPYmplY3ROYW1lc1tpXSArIFwiKi9cIjsgLy8gX0l0ZW0qLyBpbiBjYXNlIG9mIDE6biBjYXJkaW5hbGl0eVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRzQ29uZGl0aW9uUGF0aCA9IHNDb25kaXRpb25QYXRoICsgYU5hdk9iamVjdE5hbWVzW2ldICsgXCIvXCI7IC8vIF9JdGVtLyBpbiBjYXNlIG9mIDE6MSBjYXJkaW5hbGl0eVxuXHRcdH1cblx0XHRzTWFpbkVudGl0eVNldFBhdGggPSBzTWFpbkVudGl0eVNldFBhdGggKyBcIi9cIiArIGFOYXZPYmplY3ROYW1lc1tpXTtcblx0fVxuXHRjb25zdCBzTmF2UHJvcGVydHlQYXRoID0gc0Z1bGxDb250ZXh0UGF0aC5zbGljZSgwLCBzRnVsbENvbnRleHRQYXRoLmxhc3RJbmRleE9mKFwiL1wiKSksXG5cdFx0b1ZhbGlkUHJvcGVydGllcyA9IENvbW1vblV0aWxzLmdldENvbnRleHRQYXRoUHJvcGVydGllcyhvTWV0YU1vZGVsLCBzTmF2UHJvcGVydHlQYXRoKSxcblx0XHRhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMgPSBvU2VsZWN0aW9uVmFyaWFudC5nZXRTZWxlY3RPcHRpb25zUHJvcGVydHlOYW1lcygpO1xuXHRsZXQgc1NlbGVjdE9wdGlvbk5hbWUgPSBzUHJvcGVydHlOYW1lO1xuXHRpZiAob1ZhbGlkUHJvcGVydGllc1tzUHJvcGVydHlOYW1lXSkge1xuXHRcdHNTZWxlY3RPcHRpb25OYW1lID0gc1Byb3BlcnR5TmFtZTtcblx0fSBlbHNlIGlmIChzUHJvcGVydHlOYW1lLnN0YXJ0c1dpdGgoXCJQX1wiKSAmJiBvVmFsaWRQcm9wZXJ0aWVzW3NQcm9wZXJ0eU5hbWUucmVwbGFjZShcIlBfXCIsIFwiXCIpXSkge1xuXHRcdHNTZWxlY3RPcHRpb25OYW1lID0gc1Byb3BlcnR5TmFtZS5yZXBsYWNlKFwiUF9cIiwgXCJcIik7XG5cdH0gZWxzZSBpZiAob1ZhbGlkUHJvcGVydGllc1tcIlBfXCIgKyBzUHJvcGVydHlOYW1lXSAmJiBhU2VsZWN0T3B0aW9uc1Byb3BlcnR5TmFtZXMuaW5jbHVkZXMoXCJQX1wiICsgc1Byb3BlcnR5TmFtZSkpIHtcblx0XHRzU2VsZWN0T3B0aW9uTmFtZSA9IFwiUF9cIiArIHNQcm9wZXJ0eU5hbWU7XG5cdH1cblx0aWYgKHNQcm9wZXJ0eU5hbWUuc3RhcnRzV2l0aChcIlBfXCIpICYmIG9Db25kaXRpb25zW3NDb25kaXRpb25QYXRoICsgc1NlbGVjdE9wdGlvbk5hbWVdKSB7XG5cdFx0Ly8gaWYgdGhlcmUgaXMgbm8gU2FsZXNPcmRlck1hbmFnZS5fSXRlbS5NYXRlcmlhbCB5ZXQgaW4gdGhlIG9Db25kaXRpb25zXG5cdFx0cmV0dXJuO1xuXHR9IGVsc2UgaWYgKCFzUHJvcGVydHlOYW1lLnN0YXJ0c1dpdGgoXCJQX1wiKSAmJiBvQ29uZGl0aW9uc1tzQ29uZGl0aW9uUGF0aCArIHNTZWxlY3RPcHRpb25OYW1lXSkge1xuXHRcdGRlbGV0ZSBvQ29uZGl0aW9uc1tzQ29uZGl0aW9uUGF0aCArIHNTZWxlY3RPcHRpb25OYW1lXTtcblx0XHRhZGRTZWxlY3RPcHRpb25zVG9Db25kaXRpb25zKFxuXHRcdFx0c05hdlByb3BlcnR5UGF0aCxcblx0XHRcdG9TZWxlY3Rpb25WYXJpYW50LFxuXHRcdFx0c1NlbGVjdE9wdGlvbixcblx0XHRcdG9Db25kaXRpb25zLFxuXHRcdFx0c0NvbmRpdGlvblBhdGgsXG5cdFx0XHRzU2VsZWN0T3B0aW9uTmFtZSxcblx0XHRcdG9WYWxpZFByb3BlcnRpZXMsXG5cdFx0XHRvTWV0YU1vZGVsLFxuXHRcdFx0ZmFsc2Vcblx0XHQpO1xuXHR9IGVsc2Uge1xuXHRcdGFkZFNlbGVjdE9wdGlvbnNUb0NvbmRpdGlvbnMoXG5cdFx0XHRzTmF2UHJvcGVydHlQYXRoLFxuXHRcdFx0b1NlbGVjdGlvblZhcmlhbnQsXG5cdFx0XHRzU2VsZWN0T3B0aW9uLFxuXHRcdFx0b0NvbmRpdGlvbnMsXG5cdFx0XHRzQ29uZGl0aW9uUGF0aCxcblx0XHRcdHNTZWxlY3RPcHRpb25OYW1lLFxuXHRcdFx0b1ZhbGlkUHJvcGVydGllcyxcblx0XHRcdG9NZXRhTW9kZWwsXG5cdFx0XHRmYWxzZVxuXHRcdCk7XG5cdH1cbn1cbmZ1bmN0aW9uIGFkZFBhZ2VDb250ZXh0VG9TZWxlY3Rpb25WYXJpYW50KG9TZWxlY3Rpb25WYXJpYW50OiBhbnksIG1QYWdlQ29udGV4dDogYW55W10sIG9WaWV3OiBhbnkpIHtcblx0Y29uc3Qgb0FwcENvbXBvbmVudCA9IENvbW1vblV0aWxzLmdldEFwcENvbXBvbmVudChvVmlldyk7XG5cdGNvbnN0IG9OYXZpZ2F0aW9uU2VydmljZSA9IG9BcHBDb21wb25lbnQuZ2V0TmF2aWdhdGlvblNlcnZpY2UoKTtcblx0cmV0dXJuIG9OYXZpZ2F0aW9uU2VydmljZS5taXhBdHRyaWJ1dGVzQW5kU2VsZWN0aW9uVmFyaWFudChtUGFnZUNvbnRleHQsIG9TZWxlY3Rpb25WYXJpYW50LnRvSlNPTlN0cmluZygpKTtcbn1cbmZ1bmN0aW9uIGFkZEV4dGVybmFsU3RhdGVGaWx0ZXJzVG9TZWxlY3Rpb25WYXJpYW50KG9TZWxlY3Rpb25WYXJpYW50OiBhbnksIG1GaWx0ZXJzOiBhbnksIG9UYXJnZXRJbmZvOiBhbnksIG9GaWx0ZXJJbmZvOiBhbnkpIHtcblx0bGV0IHNGaWx0ZXI6IGFueSxcblx0XHRzTG93ID0gXCJcIixcblx0XHRzSGlnaCA9IG51bGw7XG5cdGNvbnN0IGZuR2V0U2lnbkFuZE9wdGlvbiA9IGZ1bmN0aW9uKHNPcGVyYXRvcjogYW55LCBzTG93VmFsdWU6IGFueSwgc0hpZ2hWYWx1ZTogYW55KSB7XG5cdFx0Y29uc3Qgb1NlbGVjdE9wdGlvblN0YXRlID0ge1xuXHRcdFx0b3B0aW9uOiBcIlwiLFxuXHRcdFx0c2lnbjogXCJJXCIsXG5cdFx0XHRsb3c6IHNMb3dWYWx1ZSxcblx0XHRcdGhpZ2g6IHNIaWdoVmFsdWVcblx0XHR9O1xuXHRcdHN3aXRjaCAoc09wZXJhdG9yKSB7XG5cdFx0XHRjYXNlIFwiQ29udGFpbnNcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IFwiQ1BcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiU3RhcnRzV2l0aFwiOlxuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUub3B0aW9uID0gXCJDUFwiO1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUubG93ICs9IFwiKlwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJFbmRzV2l0aFwiOlxuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUub3B0aW9uID0gXCJDUFwiO1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUubG93ID0gXCIqXCIgKyBvU2VsZWN0T3B0aW9uU3RhdGUubG93O1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJCVFwiOlxuXHRcdFx0Y2FzZSBcIkxFXCI6XG5cdFx0XHRjYXNlIFwiTFRcIjpcblx0XHRcdGNhc2UgXCJHVFwiOlxuXHRcdFx0Y2FzZSBcIk5FXCI6XG5cdFx0XHRjYXNlIFwiRVFcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IHNPcGVyYXRvcjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiVE9EQVlcIjpcblx0XHRcdGNhc2UgXCJEQVRFXCI6XG5cdFx0XHRcdG9TZWxlY3RPcHRpb25TdGF0ZS5vcHRpb24gPSBcIkVRXCI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIkVFUVwiOlxuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUub3B0aW9uID0gXCJFUVwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJFbXB0eVwiOlxuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUub3B0aW9uID0gXCJFUVwiO1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUubG93ID0gXCJcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTm90Q29udGFpbnNcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IFwiQ1BcIjtcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLnNpZ24gPSBcIkVcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTk9UQlRcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IFwiQlRcIjtcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLnNpZ24gPSBcIkVcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTm90U3RhcnRzV2l0aFwiOlxuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUub3B0aW9uID0gXCJDUFwiO1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUubG93ICs9IFwiKlwiO1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUuc2lnbiA9IFwiRVwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJOb3RFbmRzV2l0aFwiOlxuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUub3B0aW9uID0gXCJDUFwiO1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUubG93ID0gXCIqXCIgKyBvU2VsZWN0T3B0aW9uU3RhdGUubG93O1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUuc2lnbiA9IFwiRVwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJOb3RFbXB0eVwiOlxuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUub3B0aW9uID0gXCJORVwiO1xuXHRcdFx0XHRvU2VsZWN0T3B0aW9uU3RhdGUubG93ID0gXCJcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTk9UTEVcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IFwiTEVcIjtcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLnNpZ24gPSBcIkVcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTk9UR0VcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IFwiR0VcIjtcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLnNpZ24gPSBcIkVcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTk9UTFRcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IFwiTFRcIjtcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLnNpZ24gPSBcIkVcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiTk9UR1RcIjpcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLm9wdGlvbiA9IFwiR1RcIjtcblx0XHRcdFx0b1NlbGVjdE9wdGlvblN0YXRlLnNpZ24gPSBcIkVcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRMb2cud2FybmluZyhzT3BlcmF0b3IgKyBcIiBpcyBub3Qgc3VwcG9ydGVkLiBcIiArIHNGaWx0ZXIgKyBcIiBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIG5hdmlnYXRpb24gY29udGV4dFwiKTtcblx0XHR9XG5cdFx0cmV0dXJuIG9TZWxlY3RPcHRpb25TdGF0ZTtcblx0fTtcblx0Y29uc3Qgb0ZpbHRlckNvbmRpdGlvbnMgPSBtRmlsdGVycy5maWx0ZXJDb25kaXRpb25zO1xuXHRjb25zdCBvRmlsdGVyc1dpdGhvdXRDb25mbGljdCA9IG1GaWx0ZXJzLmZpbHRlckNvbmRpdGlvbnNXaXRob3V0Q29uZmxpY3QgPyBtRmlsdGVycy5maWx0ZXJDb25kaXRpb25zV2l0aG91dENvbmZsaWN0IDoge307XG5cdGNvbnN0IG9UYWJsZVByb3BlcnRpZXNXaXRob3V0Q29uZmxpY3QgPSBvVGFyZ2V0SW5mby5wcm9wZXJ0aWVzV2l0aG91dENvbmZsaWN0ID8gb1RhcmdldEluZm8ucHJvcGVydGllc1dpdGhvdXRDb25mbGljdCA6IHt9O1xuXHRjb25zdCBhZGRGaWx0ZXJzVG9TZWxlY3Rpb25WYXJpYW50ID0gZnVuY3Rpb24ob1NlbGVjdGlvblZhcmlhbnQ6IGFueSwgc0ZpbHRlck5hbWU6IGFueSwgc1BhdGg/OiBhbnkpIHtcblx0XHRjb25zdCBhRmlsdGVycyA9IG9GaWx0ZXJDb25kaXRpb25zW3NGaWx0ZXJOYW1lXTtcblx0XHRmb3IgKGNvbnN0IGl0ZW0gaW4gYUZpbHRlcnMpIHtcblx0XHRcdGNvbnN0IG9GaWx0ZXIgPSBhRmlsdGVyc1tpdGVtXTtcblx0XHRcdHNMb3cgPSAob0ZpbHRlci52YWx1ZXNbMF0gJiYgb0ZpbHRlci52YWx1ZXNbMF0udG9TdHJpbmcoKSkgfHwgXCJcIjtcblx0XHRcdHNIaWdoID0gKG9GaWx0ZXIudmFsdWVzWzFdICYmIG9GaWx0ZXIudmFsdWVzWzFdLnRvU3RyaW5nKCkpIHx8IG51bGw7XG5cdFx0XHRpZiAob0ZpbHRlci5vcGVyYXRvciA9PT0gXCJUT0RBWVwiIHx8IG9GaWx0ZXIub3BlcmF0b3IgPT09IFwiREFURVwiKSB7XG5cdFx0XHRcdGNvbnN0IGFGaWx0ZXIgPSBvRmlsdGVySW5mb1swXS5hRmlsdGVycy5maWx0ZXIoZnVuY3Rpb24ob0ZpbHRlcjogYW55KSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9GaWx0ZXIuc1BhdGggPT09IHNGaWx0ZXJOYW1lO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0c0xvdyA9IGFGaWx0ZXJbMF0ub1ZhbHVlMSB8fCBcIlwiO1xuXHRcdFx0XHRzSGlnaCA9IG51bGw7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBvU2VsZWN0T3B0aW9uVmFsdWVzID0gZm5HZXRTaWduQW5kT3B0aW9uKG9GaWx0ZXIub3BlcmF0b3IsIHNMb3csIHNIaWdoKTtcblx0XHRcdGlmIChvU2VsZWN0T3B0aW9uVmFsdWVzLm9wdGlvbikge1xuXHRcdFx0XHRvU2VsZWN0aW9uVmFyaWFudC5hZGRTZWxlY3RPcHRpb24oXG5cdFx0XHRcdFx0c1BhdGggPyBzUGF0aCA6IHNGaWx0ZXJOYW1lLFxuXHRcdFx0XHRcdG9TZWxlY3RPcHRpb25WYWx1ZXMuc2lnbixcblx0XHRcdFx0XHRvU2VsZWN0T3B0aW9uVmFsdWVzLm9wdGlvbixcblx0XHRcdFx0XHRvU2VsZWN0T3B0aW9uVmFsdWVzLmxvdyxcblx0XHRcdFx0XHRvU2VsZWN0T3B0aW9uVmFsdWVzLmhpZ2hcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0Zm9yIChzRmlsdGVyIGluIG9GaWx0ZXJDb25kaXRpb25zKSB7XG5cdFx0Ly8gb25seSBhZGQgdGhlIGZpbHRlciB2YWx1ZXMgaWYgaXQgaXMgbm90IGFscmVhZHkgcHJlc2VudCBpbiB0aGUgU1YgYWxyZWFkeVxuXHRcdGlmICghb1NlbGVjdGlvblZhcmlhbnQuZ2V0U2VsZWN0T3B0aW9uKHNGaWx0ZXIpKSB7XG5cdFx0XHQvLyBUT0RPIDogY3VzdG9tIGZpbHRlcnMgc2hvdWxkIGJlIGlnbm9yZWQgbW9yZSBnZW5lcmljYWxseVxuXHRcdFx0aWYgKHNGaWx0ZXIgPT09IFwiJGVkaXRTdGF0ZVwiKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXHRcdFx0YWRkRmlsdGVyc1RvU2VsZWN0aW9uVmFyaWFudChvU2VsZWN0aW9uVmFyaWFudCwgc0ZpbHRlcik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmIChvVGFibGVQcm9wZXJ0aWVzV2l0aG91dENvbmZsaWN0ICYmIHNGaWx0ZXIgaW4gb1RhYmxlUHJvcGVydGllc1dpdGhvdXRDb25mbGljdCkge1xuXHRcdFx0XHRhZGRGaWx0ZXJzVG9TZWxlY3Rpb25WYXJpYW50KG9TZWxlY3Rpb25WYXJpYW50LCBzRmlsdGVyLCBvVGFibGVQcm9wZXJ0aWVzV2l0aG91dENvbmZsaWN0W3NGaWx0ZXJdKTtcblx0XHRcdH1cblx0XHRcdC8vIGlmIHByb3BlcnR5IHdhcyB3aXRob3V0IGNvbmZsaWN0IGluIHBhZ2UgY29udGV4dCB0aGVuIGFkZCBwYXRoIGZyb20gcGFnZSBjb250ZXh0IHRvIFNWXG5cdFx0XHRpZiAoc0ZpbHRlciBpbiBvRmlsdGVyc1dpdGhvdXRDb25mbGljdCkge1xuXHRcdFx0XHRhZGRGaWx0ZXJzVG9TZWxlY3Rpb25WYXJpYW50KG9TZWxlY3Rpb25WYXJpYW50LCBzRmlsdGVyLCBvRmlsdGVyc1dpdGhvdXRDb25mbGljdFtzRmlsdGVyXSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiBvU2VsZWN0aW9uVmFyaWFudDtcbn1cbmZ1bmN0aW9uIGlzU3RpY2t5RWRpdE1vZGUob0NvbnRyb2w6IENvbnRyb2wpIHtcblx0Y29uc3QgYklzU3RpY2t5TW9kZSA9IE1vZGVsSGVscGVyLmlzU3RpY2t5U2Vzc2lvblN1cHBvcnRlZCgob0NvbnRyb2wuZ2V0TW9kZWwoKSBhcyBPRGF0YU1vZGVsKS5nZXRNZXRhTW9kZWwoKSk7XG5cdGNvbnN0IGJVSUVkaXRhYmxlID0gb0NvbnRyb2wuZ2V0TW9kZWwoXCJ1aVwiKS5nZXRQcm9wZXJ0eShcIi9pc0VkaXRhYmxlXCIpO1xuXHRyZXR1cm4gYklzU3RpY2t5TW9kZSAmJiBiVUlFZGl0YWJsZTtcbn1cbi8qKlxuICogQHBhcmFtIGFNYW5kYXRvcnlGaWx0ZXJGaWVsZHNcbiAqIEBwYXJhbSBvU2VsZWN0aW9uVmFyaWFudFxuICogQHBhcmFtIG9TZWxlY3Rpb25WYXJpYW50RGVmYXVsdHNcbiAqL1xuZnVuY3Rpb24gYWRkRGVmYXVsdERpc3BsYXlDdXJyZW5jeShhTWFuZGF0b3J5RmlsdGVyRmllbGRzOiBhbnlbXSwgb1NlbGVjdGlvblZhcmlhbnQ6IGFueSwgb1NlbGVjdGlvblZhcmlhbnREZWZhdWx0czogYW55KSB7XG5cdGlmIChvU2VsZWN0aW9uVmFyaWFudCAmJiBhTWFuZGF0b3J5RmlsdGVyRmllbGRzICYmIGFNYW5kYXRvcnlGaWx0ZXJGaWVsZHMubGVuZ3RoKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhTWFuZGF0b3J5RmlsdGVyRmllbGRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCBhU1ZPcHRpb24gPSBvU2VsZWN0aW9uVmFyaWFudC5nZXRTZWxlY3RPcHRpb24oXCJEaXNwbGF5Q3VycmVuY3lcIiksXG5cdFx0XHRcdGFEZWZhdWx0U1ZPcHRpb24gPSBvU2VsZWN0aW9uVmFyaWFudERlZmF1bHRzICYmIG9TZWxlY3Rpb25WYXJpYW50RGVmYXVsdHMuZ2V0U2VsZWN0T3B0aW9uKFwiRGlzcGxheUN1cnJlbmN5XCIpO1xuXHRcdFx0aWYgKFxuXHRcdFx0XHRhTWFuZGF0b3J5RmlsdGVyRmllbGRzW2ldLiRQcm9wZXJ0eVBhdGggPT09IFwiRGlzcGxheUN1cnJlbmN5XCIgJiZcblx0XHRcdFx0KCFhU1ZPcHRpb24gfHwgIWFTVk9wdGlvbi5sZW5ndGgpICYmXG5cdFx0XHRcdGFEZWZhdWx0U1ZPcHRpb24gJiZcblx0XHRcdFx0YURlZmF1bHRTVk9wdGlvbi5sZW5ndGhcblx0XHRcdCkge1xuXHRcdFx0XHRjb25zdCBkaXNwbGF5Q3VycmVuY3lTZWxlY3RPcHRpb24gPSBhRGVmYXVsdFNWT3B0aW9uWzBdO1xuXHRcdFx0XHRjb25zdCBzU2lnbiA9IGRpc3BsYXlDdXJyZW5jeVNlbGVjdE9wdGlvbltcIlNpZ25cIl07XG5cdFx0XHRcdGNvbnN0IHNPcHRpb24gPSBkaXNwbGF5Q3VycmVuY3lTZWxlY3RPcHRpb25bXCJPcHRpb25cIl07XG5cdFx0XHRcdGNvbnN0IHNMb3cgPSBkaXNwbGF5Q3VycmVuY3lTZWxlY3RPcHRpb25bXCJMb3dcIl07XG5cdFx0XHRcdGNvbnN0IHNIaWdoID0gZGlzcGxheUN1cnJlbmN5U2VsZWN0T3B0aW9uW1wiSGlnaFwiXTtcblx0XHRcdFx0b1NlbGVjdGlvblZhcmlhbnQuYWRkU2VsZWN0T3B0aW9uKFwiRGlzcGxheUN1cnJlbmN5XCIsIHNTaWduLCBzT3B0aW9uLCBzTG93LCBzSGlnaCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59XG5mdW5jdGlvbiBnZXROb25Db21wdXRlZFZpc2libGVGaWVsZHMob01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWwsIHNQYXRoOiBhbnksIG9WaWV3OiBhbnkpIHtcblx0Y29uc3QgYVRlY2huaWNhbEtleXMgPSBvTWV0YU1vZGVsLmdldE9iamVjdChzUGF0aCArIFwiL1wiKS4kS2V5O1xuXHRjb25zdCBhTm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzID0gW107XG5cdGNvbnN0IG9FbnRpdHlUeXBlID0gb01ldGFNb2RlbC5nZXRPYmplY3Qoc1BhdGggKyBcIi9cIik7XG5cdGZvciAoY29uc3QgaXRlbSBpbiBvRW50aXR5VHlwZSkge1xuXHRcdGlmIChvRW50aXR5VHlwZVtpdGVtXS4ka2luZCAmJiBvRW50aXR5VHlwZVtpdGVtXS4ka2luZCA9PT0gXCJQcm9wZXJ0eVwiKSB7XG5cdFx0XHRjb25zdCBvQW5ub3RhdGlvbnMgPSBvTWV0YU1vZGVsLmdldE9iamVjdChzUGF0aCArIFwiL1wiICsgaXRlbSArIFwiQFwiKSB8fCB7fSxcblx0XHRcdFx0YklzS2V5ID0gYVRlY2huaWNhbEtleXMuaW5kZXhPZihpdGVtKSA+IC0xLFxuXHRcdFx0XHRiSXNJbW11dGFibGUgPSBvQW5ub3RhdGlvbnNbXCJAT3JnLk9EYXRhLkNvcmUuVjEuSW1tdXRhYmxlXCJdLFxuXHRcdFx0XHRiSXNOb25Db21wdXRlZCA9ICFvQW5ub3RhdGlvbnNbXCJAT3JnLk9EYXRhLkNvcmUuVjEuQ29tcHV0ZWRcIl0sXG5cdFx0XHRcdGJJc1Zpc2libGUgPSAhb0Fubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkhpZGRlblwiXSxcblx0XHRcdFx0YklzQ29tcHV0ZWREZWZhdWx0VmFsdWUgPSBvQW5ub3RhdGlvbnNbXCJAT3JnLk9EYXRhLkNvcmUuVjEuQ29tcHV0ZWREZWZhdWx0VmFsdWVcIl0sXG5cdFx0XHRcdGJJc0tleUNvbXB1dGVkRGVmYXVsdFZhbHVlV2l0aFRleHQgPVxuXHRcdFx0XHRcdGJJc0tleSAmJiBvRW50aXR5VHlwZVtpdGVtXS4kVHlwZSA9PT0gXCJFZG0uR3VpZFwiXG5cdFx0XHRcdFx0XHQ/IGJJc0NvbXB1dGVkRGVmYXVsdFZhbHVlICYmIG9Bbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuVGV4dFwiXVxuXHRcdFx0XHRcdFx0OiBmYWxzZTtcblx0XHRcdGlmIChcblx0XHRcdFx0KGJJc0ltbXV0YWJsZSB8fCBiSXNLZXlDb21wdXRlZERlZmF1bHRWYWx1ZVdpdGhUZXh0IHx8IChiSXNLZXkgJiYgb0VudGl0eVR5cGVbaXRlbV0uJFR5cGUgIT09IFwiRWRtLkd1aWRcIikpICYmXG5cdFx0XHRcdGJJc05vbkNvbXB1dGVkICYmXG5cdFx0XHRcdGJJc1Zpc2libGVcblx0XHRcdCkge1xuXHRcdFx0XHRhTm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzLnB1c2goaXRlbSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICghYklzTm9uQ29tcHV0ZWQgJiYgYklzQ29tcHV0ZWREZWZhdWx0VmFsdWUgJiYgb1ZpZXcpIHtcblx0XHRcdFx0Y29uc3Qgb0RpYWdub3N0aWNzID0gZ2V0QXBwQ29tcG9uZW50KG9WaWV3KS5nZXREaWFnbm9zdGljcygpO1xuXHRcdFx0XHRjb25zdCBzTWVzc2FnZSA9IFwiQ29yZS5Db21wdXRlZERlZmF1bHRWYWx1ZSBpcyBpZ25vcmVkIGFzIENvcmUuQ29tcHV0ZWQgaXMgYWxyZWFkeSBzZXQgdG8gdHJ1ZVwiO1xuXHRcdFx0XHRvRGlhZ25vc3RpY3MuYWRkSXNzdWUoXG5cdFx0XHRcdFx0SXNzdWVDYXRlZ29yeS5Bbm5vdGF0aW9uLFxuXHRcdFx0XHRcdElzc3VlU2V2ZXJpdHkuTWVkaXVtLFxuXHRcdFx0XHRcdHNNZXNzYWdlLFxuXHRcdFx0XHRcdElzc3VlQ2F0ZWdvcnlUeXBlLFxuXHRcdFx0XHRcdElzc3VlQ2F0ZWdvcnlUeXBlPy5Bbm5vdGF0aW9ucz8uSWdub3JlZEFubm90YXRpb25cblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIGFOb25Db21wdXRlZFZpc2libGVGaWVsZHM7XG59XG5mdW5jdGlvbiBzZXRVc2VyRGVmYXVsdHMoXG5cdG9BcHBDb21wb25lbnQ6IEFwcENvbXBvbmVudCxcblx0YVBhcmFtZXRlcnM6IGFueVtdLFxuXHRvTW9kZWw6IEpTT05Nb2RlbCxcblx0YklzQWN0aW9uOiBib29sZWFuLFxuXHRiSXNDcmVhdGU/OiBib29sZWFuLFxuXHRvQWN0aW9uRGVmYXVsdFZhbHVlcz86IGFueVxuKSB7XG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlOiAodmFsdWU6IGFueSkgPT4gdm9pZCkge1xuXHRcdGNvbnN0IG9Db21wb25lbnREYXRhID0gb0FwcENvbXBvbmVudC5nZXRDb21wb25lbnREYXRhKCksXG5cdFx0XHRvU3RhcnR1cFBhcmFtZXRlcnMgPSAob0NvbXBvbmVudERhdGEgJiYgb0NvbXBvbmVudERhdGEuc3RhcnR1cFBhcmFtZXRlcnMpIHx8IHt9LFxuXHRcdFx0b1NoZWxsU2VydmljZXMgPSBvQXBwQ29tcG9uZW50LmdldFNoZWxsU2VydmljZXMoKTtcblx0XHRpZiAoIW9TaGVsbFNlcnZpY2VzLmhhc1VTaGVsbCgpKSB7XG5cdFx0XHRhUGFyYW1ldGVycy5mb3JFYWNoKGZ1bmN0aW9uKG9QYXJhbWV0ZXI6IGFueSkge1xuXHRcdFx0XHRjb25zdCBzUHJvcGVydHlOYW1lID0gYklzQWN0aW9uXG5cdFx0XHRcdFx0PyBcIi9cIiArIG9QYXJhbWV0ZXIuJE5hbWVcblx0XHRcdFx0XHQ6IG9QYXJhbWV0ZXIuZ2V0UGF0aCgpLnNsaWNlKG9QYXJhbWV0ZXIuZ2V0UGF0aCgpLmxhc3RJbmRleE9mKFwiL1wiKSArIDEpO1xuXHRcdFx0XHRjb25zdCBzUGFyYW1ldGVyTmFtZSA9IGJJc0FjdGlvbiA/IHNQcm9wZXJ0eU5hbWUuc2xpY2UoMSkgOiBzUHJvcGVydHlOYW1lO1xuXHRcdFx0XHRpZiAob0FjdGlvbkRlZmF1bHRWYWx1ZXMgJiYgYklzQ3JlYXRlKSB7XG5cdFx0XHRcdFx0aWYgKG9BY3Rpb25EZWZhdWx0VmFsdWVzW3NQYXJhbWV0ZXJOYW1lXSkge1xuXHRcdFx0XHRcdFx0b01vZGVsLnNldFByb3BlcnR5KHNQcm9wZXJ0eU5hbWUsIG9BY3Rpb25EZWZhdWx0VmFsdWVzW3NQYXJhbWV0ZXJOYW1lXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2UgaWYgKG9TdGFydHVwUGFyYW1ldGVyc1tzUGFyYW1ldGVyTmFtZV0pIHtcblx0XHRcdFx0XHRvTW9kZWwuc2V0UHJvcGVydHkoc1Byb3BlcnR5TmFtZSwgb1N0YXJ0dXBQYXJhbWV0ZXJzW3NQYXJhbWV0ZXJOYW1lXVswXSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIHJlc29sdmUodHJ1ZSk7XG5cdFx0fVxuXHRcdHJldHVybiBvU2hlbGxTZXJ2aWNlcy5nZXRTdGFydHVwQXBwU3RhdGUob0FwcENvbXBvbmVudCkudGhlbihmdW5jdGlvbihvU3RhcnR1cEFwcFN0YXRlOiBhbnkpIHtcblx0XHRcdGNvbnN0IG9EYXRhID0gb1N0YXJ0dXBBcHBTdGF0ZS5nZXREYXRhKCkgfHwge30sXG5cdFx0XHRcdGFFeHRlbmRlZFBhcmFtZXRlcnMgPSAob0RhdGEuc2VsZWN0aW9uVmFyaWFudCAmJiBvRGF0YS5zZWxlY3Rpb25WYXJpYW50LlNlbGVjdE9wdGlvbnMpIHx8IFtdO1xuXHRcdFx0YVBhcmFtZXRlcnMuZm9yRWFjaChmdW5jdGlvbihvUGFyYW1ldGVyOiBhbnkpIHtcblx0XHRcdFx0Y29uc3Qgc1Byb3BlcnR5TmFtZSA9IGJJc0FjdGlvblxuXHRcdFx0XHRcdD8gXCIvXCIgKyBvUGFyYW1ldGVyLiROYW1lXG5cdFx0XHRcdFx0OiBvUGFyYW1ldGVyLmdldFBhdGgoKS5zbGljZShvUGFyYW1ldGVyLmdldFBhdGgoKS5sYXN0SW5kZXhPZihcIi9cIikgKyAxKTtcblx0XHRcdFx0Y29uc3Qgc1BhcmFtZXRlck5hbWUgPSBiSXNBY3Rpb24gPyBzUHJvcGVydHlOYW1lLnNsaWNlKDEpIDogc1Byb3BlcnR5TmFtZTtcblx0XHRcdFx0aWYgKG9BY3Rpb25EZWZhdWx0VmFsdWVzICYmIGJJc0NyZWF0ZSkge1xuXHRcdFx0XHRcdGlmIChvQWN0aW9uRGVmYXVsdFZhbHVlc1tzUGFyYW1ldGVyTmFtZV0pIHtcblx0XHRcdFx0XHRcdG9Nb2RlbC5zZXRQcm9wZXJ0eShzUHJvcGVydHlOYW1lLCBvQWN0aW9uRGVmYXVsdFZhbHVlc1tzUGFyYW1ldGVyTmFtZV0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmIChvU3RhcnR1cFBhcmFtZXRlcnNbc1BhcmFtZXRlck5hbWVdKSB7XG5cdFx0XHRcdFx0b01vZGVsLnNldFByb3BlcnR5KHNQcm9wZXJ0eU5hbWUsIG9TdGFydHVwUGFyYW1ldGVyc1tzUGFyYW1ldGVyTmFtZV1bMF0pO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGFFeHRlbmRlZFBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdGZvciAoY29uc3QgaSBpbiBhRXh0ZW5kZWRQYXJhbWV0ZXJzKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBvRXh0ZW5kZWRQYXJhbWV0ZXIgPSBhRXh0ZW5kZWRQYXJhbWV0ZXJzW2ldO1xuXHRcdFx0XHRcdFx0aWYgKG9FeHRlbmRlZFBhcmFtZXRlci5Qcm9wZXJ0eU5hbWUgPT09IHNQYXJhbWV0ZXJOYW1lKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IG9SYW5nZSA9IG9FeHRlbmRlZFBhcmFtZXRlci5SYW5nZXMubGVuZ3RoID8gb0V4dGVuZGVkUGFyYW1ldGVyLlJhbmdlc1swXSA6IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdFx0aWYgKG9SYW5nZSAmJiBvUmFuZ2UuU2lnbiA9PT0gXCJJXCIgJiYgb1JhbmdlLk9wdGlvbiA9PT0gXCJFUVwiKSB7XG5cdFx0XHRcdFx0XHRcdFx0b01vZGVsLnNldFByb3BlcnR5KHNQcm9wZXJ0eU5hbWUsIG9SYW5nZS5Mb3cpOyAvLyBoaWdoIGlzIGlnbm9yZWQgd2hlbiBPcHRpb249RVFcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gcmVzb2x2ZSh0cnVlKTtcblx0XHR9KTtcblx0fSk7XG59XG5mdW5jdGlvbiBnZXRBZGRpdGlvbmFsUGFyYW1zRm9yQ3JlYXRlKG9TdGFydHVwUGFyYW1ldGVyczogYW55LCBvSW5ib3VuZFBhcmFtZXRlcnM6IGFueSkge1xuXHRjb25zdCBvSW5ib3VuZHMgPSBvSW5ib3VuZFBhcmFtZXRlcnMsXG5cdFx0YUNyZWF0ZVBhcmFtZXRlcnMgPSBvSW5ib3VuZHNcblx0XHRcdD8gT2JqZWN0LmtleXMob0luYm91bmRzKS5maWx0ZXIoZnVuY3Rpb24oc1BhcmFtZXRlcjogc3RyaW5nKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9JbmJvdW5kc1tzUGFyYW1ldGVyXS51c2VGb3JDcmVhdGU7XG5cdFx0XHQgIH0pXG5cdFx0XHQ6IFtdO1xuXHRsZXQgb1JldDtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhQ3JlYXRlUGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuXHRcdGNvbnN0IHNDcmVhdGVQYXJhbWV0ZXIgPSBhQ3JlYXRlUGFyYW1ldGVyc1tpXTtcblx0XHRjb25zdCBhVmFsdWVzID0gb1N0YXJ0dXBQYXJhbWV0ZXJzICYmIG9TdGFydHVwUGFyYW1ldGVyc1tzQ3JlYXRlUGFyYW1ldGVyXTtcblx0XHRpZiAoYVZhbHVlcyAmJiBhVmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0b1JldCA9IG9SZXQgfHwgT2JqZWN0LmNyZWF0ZShudWxsKTtcblx0XHRcdG9SZXRbc0NyZWF0ZVBhcmFtZXRlcl0gPSBhVmFsdWVzWzBdO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gb1JldDtcbn1cbmZ1bmN0aW9uIGdldFNlbWFudGljT2JqZWN0TWFwcGluZyhvT3V0Ym91bmQ6IGFueSkge1xuXHRjb25zdCBhU2VtYW50aWNPYmplY3RNYXBwaW5nOiBhbnlbXSA9IFtdO1xuXHRpZiAob091dGJvdW5kLnBhcmFtZXRlcnMpIHtcblx0XHRjb25zdCBhUGFyYW1ldGVycyA9IE9iamVjdC5rZXlzKG9PdXRib3VuZC5wYXJhbWV0ZXJzKSB8fCBbXTtcblx0XHRpZiAoYVBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuXHRcdFx0YVBhcmFtZXRlcnMuZm9yRWFjaChmdW5jdGlvbihzUGFyYW06IHN0cmluZykge1xuXHRcdFx0XHRjb25zdCBvTWFwcGluZyA9IG9PdXRib3VuZC5wYXJhbWV0ZXJzW3NQYXJhbV07XG5cdFx0XHRcdGlmIChvTWFwcGluZy52YWx1ZSAmJiBvTWFwcGluZy52YWx1ZS52YWx1ZSAmJiBvTWFwcGluZy52YWx1ZS5mb3JtYXQgPT09IFwiYmluZGluZ1wiKSB7XG5cdFx0XHRcdFx0Ly8gdXNpbmcgdGhlIGZvcm1hdCBvZiBVSS5NYXBwaW5nXG5cdFx0XHRcdFx0Y29uc3Qgb1NlbWFudGljTWFwcGluZyA9IHtcblx0XHRcdFx0XHRcdFwiTG9jYWxQcm9wZXJ0eVwiOiB7XG5cdFx0XHRcdFx0XHRcdFwiJFByb3BlcnR5UGF0aFwiOiBvTWFwcGluZy52YWx1ZS52YWx1ZVxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFwiU2VtYW50aWNPYmplY3RQcm9wZXJ0eVwiOiBzUGFyYW1cblx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdFx0aWYgKGFTZW1hbnRpY09iamVjdE1hcHBpbmcubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdFx0Ly8gVG8gY2hlY2sgaWYgdGhlIHNlbWFudGljT2JqZWN0IE1hcHBpbmcgaXMgZG9uZSBmb3IgdGhlIHNhbWUgbG9jYWwgcHJvcGVydHkgbW9yZSB0aGF0IG9uY2UgdGhlbiBmaXJzdCBvbmUgd2lsbCBiZSBjb25zaWRlcmVkXG5cdFx0XHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFTZW1hbnRpY09iamVjdE1hcHBpbmcubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0XHRcdGFTZW1hbnRpY09iamVjdE1hcHBpbmdbaV1bXCJMb2NhbFByb3BlcnR5XCJdW1wiJFByb3BlcnR5UGF0aFwiXSAhPT1cblx0XHRcdFx0XHRcdFx0XHRvU2VtYW50aWNNYXBwaW5nW1wiTG9jYWxQcm9wZXJ0eVwiXVtcIiRQcm9wZXJ0eVBhdGhcIl1cblx0XHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdFx0YVNlbWFudGljT2JqZWN0TWFwcGluZy5wdXNoKG9TZW1hbnRpY01hcHBpbmcpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGFTZW1hbnRpY09iamVjdE1hcHBpbmcucHVzaChvU2VtYW50aWNNYXBwaW5nKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gYVNlbWFudGljT2JqZWN0TWFwcGluZztcbn1cbmZ1bmN0aW9uIGdldEhlYWRlckZhY2V0SXRlbUNvbmZpZ0ZvckV4dGVybmFsTmF2aWdhdGlvbihvVmlld0RhdGE6IGFueSwgb0Nyb3NzTmF2OiBhbnkpIHtcblx0Y29uc3Qgb0hlYWRlckZhY2V0SXRlbXM6IGFueSA9IHt9O1xuXHRsZXQgc0lkO1xuXHRjb25zdCBvQ29udHJvbENvbmZpZyA9IG9WaWV3RGF0YS5jb250cm9sQ29uZmlndXJhdGlvbjtcblx0Zm9yIChjb25zdCBjb25maWcgaW4gb0NvbnRyb2xDb25maWcpIHtcblx0XHRpZiAoY29uZmlnLmluZGV4T2YoXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuRGF0YVBvaW50XCIpID4gLTEgfHwgY29uZmlnLmluZGV4T2YoXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuQ2hhcnRcIikgPiAtMSkge1xuXHRcdFx0aWYgKFxuXHRcdFx0XHRvQ29udHJvbENvbmZpZ1tjb25maWddLm5hdmlnYXRpb24gJiZcblx0XHRcdFx0b0NvbnRyb2xDb25maWdbY29uZmlnXS5uYXZpZ2F0aW9uLnRhcmdldE91dGJvdW5kICYmXG5cdFx0XHRcdG9Db250cm9sQ29uZmlnW2NvbmZpZ10ubmF2aWdhdGlvbi50YXJnZXRPdXRib3VuZC5vdXRib3VuZFxuXHRcdFx0KSB7XG5cdFx0XHRcdGNvbnN0IHNPdXRib3VuZCA9IG9Db250cm9sQ29uZmlnW2NvbmZpZ10ubmF2aWdhdGlvbi50YXJnZXRPdXRib3VuZC5vdXRib3VuZDtcblx0XHRcdFx0Y29uc3Qgb091dGJvdW5kID0gb0Nyb3NzTmF2W3NPdXRib3VuZF07XG5cdFx0XHRcdGlmIChvT3V0Ym91bmQuc2VtYW50aWNPYmplY3QgJiYgb091dGJvdW5kLmFjdGlvbikge1xuXHRcdFx0XHRcdGlmIChjb25maWcuaW5kZXhPZihcIkNoYXJ0XCIpID4gLTEpIHtcblx0XHRcdFx0XHRcdHNJZCA9IGdlbmVyYXRlKFtcImZlXCIsIFwiTWljcm9DaGFydExpbmtcIiwgY29uZmlnXSk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHNJZCA9IGdlbmVyYXRlKFtcImZlXCIsIFwiSGVhZGVyRFBMaW5rXCIsIGNvbmZpZ10pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCBhU2VtYW50aWNPYmplY3RNYXBwaW5nID0gQ29tbW9uVXRpbHMuZ2V0U2VtYW50aWNPYmplY3RNYXBwaW5nKG9PdXRib3VuZCk7XG5cdFx0XHRcdFx0b0hlYWRlckZhY2V0SXRlbXNbc0lkXSA9IHtcblx0XHRcdFx0XHRcdHNlbWFudGljT2JqZWN0OiBvT3V0Ym91bmQuc2VtYW50aWNPYmplY3QsXG5cdFx0XHRcdFx0XHRhY3Rpb246IG9PdXRib3VuZC5hY3Rpb24sXG5cdFx0XHRcdFx0XHRzZW1hbnRpY09iamVjdE1hcHBpbmc6IGFTZW1hbnRpY09iamVjdE1hcHBpbmdcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdExvZy5lcnJvcihcIkNyb3NzIG5hdmlnYXRpb24gb3V0Ym91bmQgaXMgY29uZmlndXJlZCB3aXRob3V0IHNlbWFudGljIG9iamVjdCBhbmQgYWN0aW9uIGZvciBcIiArIHNPdXRib3VuZCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIG9IZWFkZXJGYWNldEl0ZW1zO1xufVxuZnVuY3Rpb24gc2V0U2VtYW50aWNPYmplY3RNYXBwaW5ncyhvU2VsZWN0aW9uVmFyaWFudDogYW55LCB2TWFwcGluZ3M6IG9iamVjdCkge1xuXHRjb25zdCBvTWFwcGluZ3MgPSB0eXBlb2Ygdk1hcHBpbmdzID09PSBcInN0cmluZ1wiID8gSlNPTi5wYXJzZSh2TWFwcGluZ3MpIDogdk1hcHBpbmdzO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IG9NYXBwaW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdGNvbnN0IHNMb2NhbFByb3BlcnR5ID1cblx0XHRcdChvTWFwcGluZ3NbaV1bXCJMb2NhbFByb3BlcnR5XCJdICYmIG9NYXBwaW5nc1tpXVtcIkxvY2FsUHJvcGVydHlcIl1bXCIkUHJvcGVydHlQYXRoXCJdKSB8fFxuXHRcdFx0KG9NYXBwaW5nc1tpXVtcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuTG9jYWxQcm9wZXJ0eVwiXSAmJlxuXHRcdFx0XHRvTWFwcGluZ3NbaV1bXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkxvY2FsUHJvcGVydHlcIl1bXCIkUGF0aFwiXSk7XG5cdFx0Y29uc3Qgc1NlbWFudGljT2JqZWN0UHJvcGVydHkgPVxuXHRcdFx0b01hcHBpbmdzW2ldW1wiU2VtYW50aWNPYmplY3RQcm9wZXJ0eVwiXSB8fCBvTWFwcGluZ3NbaV1bXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlNlbWFudGljT2JqZWN0UHJvcGVydHlcIl07XG5cdFx0aWYgKG9TZWxlY3Rpb25WYXJpYW50LmdldFNlbGVjdE9wdGlvbihzTG9jYWxQcm9wZXJ0eSkpIHtcblx0XHRcdGNvbnN0IG9TZWxlY3RPcHRpb24gPSBvU2VsZWN0aW9uVmFyaWFudC5nZXRTZWxlY3RPcHRpb24oc0xvY2FsUHJvcGVydHkpO1xuXG5cdFx0XHQvL0NyZWF0ZSBhIG5ldyBTZWxlY3RPcHRpb24gd2l0aCBzU2VtYW50aWNPYmplY3RQcm9wZXJ0eSBhcyB0aGUgcHJvcGVydHkgTmFtZSBhbmQgcmVtb3ZlIHRoZSBvbGRlciBvbmVcblx0XHRcdG9TZWxlY3Rpb25WYXJpYW50LnJlbW92ZVNlbGVjdE9wdGlvbihzTG9jYWxQcm9wZXJ0eSk7XG5cdFx0XHRvU2VsZWN0aW9uVmFyaWFudC5tYXNzQWRkU2VsZWN0T3B0aW9uKHNTZW1hbnRpY09iamVjdFByb3BlcnR5LCBvU2VsZWN0T3B0aW9uKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIG9TZWxlY3Rpb25WYXJpYW50O1xufVxuZnVuY3Rpb24gZm5HZXRTZW1hbnRpY09iamVjdHNGcm9tUGF0aChvTWV0YU1vZGVsOiBhbnksIHNQYXRoOiBhbnkpIHtcblx0cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmU6ICh2YWx1ZTogYW55KSA9PiB2b2lkKSB7XG5cdFx0Y29uc3Qgc1NlbWFudGljT2JqZWN0ID0gb01ldGFNb2RlbC5nZXRPYmplY3Qoc1BhdGggKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuU2VtYW50aWNPYmplY3RcIik7XG5cdFx0Y29uc3QgYVNlbWFudGljT2JqZWN0VW5hdmFpbGFibGVBY3Rpb25zID0gb01ldGFNb2RlbC5nZXRPYmplY3QoXG5cdFx0XHRzUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5TZW1hbnRpY09iamVjdFVuYXZhaWxhYmxlQWN0aW9uc1wiXG5cdFx0KTtcblx0XHRjb25zdCBhU2VtYW50aWNPYmplY3RGb3JHZXRMaW5rcyA9IFt7IHNlbWFudGljT2JqZWN0OiBzU2VtYW50aWNPYmplY3QgfV07XG5cdFx0Y29uc3Qgb1NlbWFudGljT2JqZWN0ID0ge1xuXHRcdFx0c2VtYW50aWNPYmplY3Q6IHNTZW1hbnRpY09iamVjdFxuXHRcdH07XG5cdFx0cmVzb2x2ZSh7XG5cdFx0XHRzZW1hbnRpY09iamVjdFBhdGg6IHNQYXRoLFxuXHRcdFx0c2VtYW50aWNPYmplY3RGb3JHZXRMaW5rczogYVNlbWFudGljT2JqZWN0Rm9yR2V0TGlua3MsXG5cdFx0XHRzZW1hbnRpY09iamVjdDogb1NlbWFudGljT2JqZWN0LFxuXHRcdFx0dW5hdmFpbGFibGVBY3Rpb25zOiBhU2VtYW50aWNPYmplY3RVbmF2YWlsYWJsZUFjdGlvbnNcblx0XHR9KTtcblx0fSkuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRMb2cuZXJyb3IoXCJFcnJvciBpbiBmbkdldFNlbWFudGljT2JqZWN0c0Zyb21QYXRoXCIsIG9FcnJvcik7XG5cdH0pO1xufVxuZnVuY3Rpb24gZm5VcGRhdGVTZW1hbnRpY1RhcmdldHNNb2RlbChhR2V0TGlua3NQcm9taXNlczogYW55LCBhU2VtYW50aWNPYmplY3RzOiBhbnksIG9JbnRlcm5hbE1vZGVsQ29udGV4dDogYW55LCBzQ3VycmVudEhhc2g6IGFueSkge1xuXHRyZXR1cm4gUHJvbWlzZS5hbGwoYUdldExpbmtzUHJvbWlzZXMpXG5cdFx0LnRoZW4oZnVuY3Rpb24oYVZhbHVlczogW2FueSwgYW55LCBhbnksIGFueSwgYW55LCBhbnksIGFueSwgYW55LCBhbnksIGFueV0pIHtcblx0XHRcdGxldCBhTGlua3MsXG5cdFx0XHRcdF9vTGluayxcblx0XHRcdFx0X3NMaW5rSW50ZW50QWN0aW9uLFxuXHRcdFx0XHRhRmluYWxMaW5rczogYW55W10gPSBbXTtcblx0XHRcdGxldCBvRmluYWxTZW1hbnRpY09iamVjdHM6IGFueSA9IHt9O1xuXHRcdFx0Y29uc3QgYkludGVudEhhc0FjdGlvbnMgPSBmdW5jdGlvbihzSW50ZW50OiBhbnksIGFBY3Rpb25zOiBhbnkpIHtcblx0XHRcdFx0Zm9yIChjb25zdCBpbnRlbnQgaW4gYUFjdGlvbnMpIHtcblx0XHRcdFx0XHRpZiAoaW50ZW50ID09PSBzSW50ZW50KSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdFx0Zm9yIChsZXQgayA9IDA7IGsgPCBhVmFsdWVzLmxlbmd0aDsgaysrKSB7XG5cdFx0XHRcdGFMaW5rcyA9IGFWYWx1ZXNba107XG5cdFx0XHRcdGlmIChhTGlua3MgJiYgYUxpbmtzLmxlbmd0aCA+IDAgJiYgYUxpbmtzWzBdICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRjb25zdCBvU2VtYW50aWNPYmplY3Q6IGFueSA9IHt9O1xuXHRcdFx0XHRcdGxldCBvVG1wID0ge307XG5cdFx0XHRcdFx0bGV0IHNBbHRlcm5hdGVQYXRoO1xuXHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYUxpbmtzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRhRmluYWxMaW5rcy5wdXNoKFtdKTtcblx0XHRcdFx0XHRcdGxldCBoYXNUYXJnZXRzTm90RmlsdGVyZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdGxldCBoYXNUYXJnZXRzID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRmb3IgKGxldCBpTGlua0NvdW50ID0gMDsgaUxpbmtDb3VudCA8IGFMaW5rc1tpXVswXS5sZW5ndGg7IGlMaW5rQ291bnQrKykge1xuXHRcdFx0XHRcdFx0XHRfb0xpbmsgPSBhTGlua3NbaV1bMF1baUxpbmtDb3VudF07XG5cdFx0XHRcdFx0XHRcdF9zTGlua0ludGVudEFjdGlvbiA9IF9vTGluayAmJiBfb0xpbmsuaW50ZW50LnNwbGl0KFwiP1wiKVswXS5zcGxpdChcIi1cIilbMV07XG5cblx0XHRcdFx0XHRcdFx0aWYgKCEoX29MaW5rICYmIF9vTGluay5pbnRlbnQgJiYgX29MaW5rLmludGVudC5pbmRleE9mKHNDdXJyZW50SGFzaCkgPT09IDApKSB7XG5cdFx0XHRcdFx0XHRcdFx0aGFzVGFyZ2V0c05vdEZpbHRlcmVkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIWJJbnRlbnRIYXNBY3Rpb25zKF9zTGlua0ludGVudEFjdGlvbiwgYVNlbWFudGljT2JqZWN0c1trXS51bmF2YWlsYWJsZUFjdGlvbnMpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRhRmluYWxMaW5rc1tpXS5wdXNoKF9vTGluayk7XG5cdFx0XHRcdFx0XHRcdFx0XHRoYXNUYXJnZXRzID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG9UbXAgPSB7XG5cdFx0XHRcdFx0XHRcdHNlbWFudGljT2JqZWN0OiBhU2VtYW50aWNPYmplY3RzW2tdLnNlbWFudGljT2JqZWN0LFxuXHRcdFx0XHRcdFx0XHRwYXRoOiBhU2VtYW50aWNPYmplY3RzW2tdLnBhdGgsXG5cdFx0XHRcdFx0XHRcdEhhc1RhcmdldHM6IGhhc1RhcmdldHMsXG5cdFx0XHRcdFx0XHRcdEhhc1RhcmdldHNOb3RGaWx0ZXJlZDogaGFzVGFyZ2V0c05vdEZpbHRlcmVkXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0aWYgKG9TZW1hbnRpY09iamVjdFthU2VtYW50aWNPYmplY3RzW2tdLnNlbWFudGljT2JqZWN0XSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRcdG9TZW1hbnRpY09iamVjdFthU2VtYW50aWNPYmplY3RzW2tdLnNlbWFudGljT2JqZWN0XSA9IHt9O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0c0FsdGVybmF0ZVBhdGggPSBhU2VtYW50aWNPYmplY3RzW2tdLnBhdGgucmVwbGFjZSgvXFwvL2csIFwiX1wiKTtcblx0XHRcdFx0XHRcdGlmIChvU2VtYW50aWNPYmplY3RbYVNlbWFudGljT2JqZWN0c1trXS5zZW1hbnRpY09iamVjdF1bc0FsdGVybmF0ZVBhdGhdID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRcdFx0b1NlbWFudGljT2JqZWN0W2FTZW1hbnRpY09iamVjdHNba10uc2VtYW50aWNPYmplY3RdW3NBbHRlcm5hdGVQYXRoXSA9IHt9O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0b1NlbWFudGljT2JqZWN0W2FTZW1hbnRpY09iamVjdHNba10uc2VtYW50aWNPYmplY3RdW3NBbHRlcm5hdGVQYXRoXSA9IE9iamVjdC5hc3NpZ24oXG5cdFx0XHRcdFx0XHRcdG9TZW1hbnRpY09iamVjdFthU2VtYW50aWNPYmplY3RzW2tdLnNlbWFudGljT2JqZWN0XVtzQWx0ZXJuYXRlUGF0aF0sXG5cdFx0XHRcdFx0XHRcdG9UbXBcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IHNTZW1hbnRpY09iamVjdE5hbWUgPSBPYmplY3Qua2V5cyhvU2VtYW50aWNPYmplY3QpWzBdO1xuXHRcdFx0XHRcdGlmIChPYmplY3Qua2V5cyhvRmluYWxTZW1hbnRpY09iamVjdHMpLmluY2x1ZGVzKHNTZW1hbnRpY09iamVjdE5hbWUpKSB7XG5cdFx0XHRcdFx0XHRvRmluYWxTZW1hbnRpY09iamVjdHNbc1NlbWFudGljT2JqZWN0TmFtZV0gPSBPYmplY3QuYXNzaWduKFxuXHRcdFx0XHRcdFx0XHRvRmluYWxTZW1hbnRpY09iamVjdHNbc1NlbWFudGljT2JqZWN0TmFtZV0sXG5cdFx0XHRcdFx0XHRcdG9TZW1hbnRpY09iamVjdFtzU2VtYW50aWNPYmplY3ROYW1lXVxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0b0ZpbmFsU2VtYW50aWNPYmplY3RzID0gT2JqZWN0LmFzc2lnbihvRmluYWxTZW1hbnRpY09iamVjdHMsIG9TZW1hbnRpY09iamVjdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGFGaW5hbExpbmtzID0gW107XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmIChPYmplY3Qua2V5cyhvRmluYWxTZW1hbnRpY09iamVjdHMpLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0b0ludGVybmFsTW9kZWxDb250ZXh0LnNldFByb3BlcnR5KFxuXHRcdFx0XHRcdFwic2VtYW50aWNzVGFyZ2V0c1wiLFxuXHRcdFx0XHRcdG1lcmdlT2JqZWN0cyhvRmluYWxTZW1hbnRpY09iamVjdHMsIG9JbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRQcm9wZXJ0eShcInNlbWFudGljc1RhcmdldHNcIikpXG5cdFx0XHRcdCk7XG5cdFx0XHRcdHJldHVybiBvRmluYWxTZW1hbnRpY09iamVjdHM7XG5cdFx0XHR9XG5cdFx0fSlcblx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdExvZy5lcnJvcihcImZuVXBkYXRlU2VtYW50aWNUYXJnZXRzTW9kZWw6IENhbm5vdCByZWFkIGxpbmtzXCIsIG9FcnJvcik7XG5cdFx0fSk7XG59XG5mdW5jdGlvbiBmbkdldFNlbWFudGljT2JqZWN0UHJvbWlzZShvQXBwQ29tcG9uZW50OiBhbnksIG9WaWV3OiBhbnksIG9NZXRhTW9kZWw6IGFueSwgc1BhdGg6IGFueSkge1xuXHRyZXR1cm4gQ29tbW9uVXRpbHMuZ2V0U2VtYW50aWNPYmplY3RzRnJvbVBhdGgob01ldGFNb2RlbCwgc1BhdGgpO1xufVxuZnVuY3Rpb24gZm5HZXRTZW1hbnRpY1RhcmdldHNGcm9tUGFnZU1vZGVsKG9Db250cm9sbGVyOiBhbnksIHNQYWdlTW9kZWw6IHN0cmluZykge1xuXHRjb25zdCBfZm5maW5kVmFsdWVzSGVscGVyID0gZnVuY3Rpb24ob2JqOiBhbnksIGtleTogYW55LCBsaXN0OiBhbnkpIHtcblx0XHRpZiAoIW9iaikge1xuXHRcdFx0cmV0dXJuIGxpc3Q7XG5cdFx0fVxuXHRcdGlmIChvYmogaW5zdGFuY2VvZiBBcnJheSkge1xuXHRcdFx0Zm9yIChjb25zdCBpIGluIG9iaikge1xuXHRcdFx0XHRsaXN0ID0gbGlzdC5jb25jYXQoX2ZuZmluZFZhbHVlc0hlbHBlcihvYmpbaV0sIGtleSwgW10pKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBsaXN0O1xuXHRcdH1cblx0XHRpZiAob2JqW2tleV0pIHtcblx0XHRcdGxpc3QucHVzaChvYmpba2V5XSk7XG5cdFx0fVxuXG5cdFx0aWYgKHR5cGVvZiBvYmogPT0gXCJvYmplY3RcIiAmJiBvYmogIT09IG51bGwpIHtcblx0XHRcdGNvbnN0IGNoaWxkcmVuID0gT2JqZWN0LmtleXMob2JqKTtcblx0XHRcdGlmIChjaGlsZHJlbi5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRsaXN0ID0gbGlzdC5jb25jYXQoX2ZuZmluZFZhbHVlc0hlbHBlcihvYmpbY2hpbGRyZW5baV1dLCBrZXksIFtdKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGxpc3Q7XG5cdH07XG5cdGNvbnN0IF9mbmZpbmRWYWx1ZXMgPSBmdW5jdGlvbihvYmo6IGFueSwga2V5OiBhbnkpIHtcblx0XHRyZXR1cm4gX2ZuZmluZFZhbHVlc0hlbHBlcihvYmosIGtleSwgW10pO1xuXHR9O1xuXHRjb25zdCBfZm5EZWxldGVEdXBsaWNhdGVTZW1hbnRpY09iamVjdHMgPSBmdW5jdGlvbihhU2VtYW50aWNPYmplY3RQYXRoOiBhbnkpIHtcblx0XHRyZXR1cm4gYVNlbWFudGljT2JqZWN0UGF0aC5maWx0ZXIoZnVuY3Rpb24odmFsdWU6IGFueSwgaW5kZXg6IGFueSkge1xuXHRcdFx0cmV0dXJuIGFTZW1hbnRpY09iamVjdFBhdGguaW5kZXhPZih2YWx1ZSkgPT09IGluZGV4O1xuXHRcdH0pO1xuXHR9O1xuXHRjb25zdCBvVmlldyA9IG9Db250cm9sbGVyLmdldFZpZXcoKTtcblx0Y29uc3Qgb0ludGVybmFsTW9kZWxDb250ZXh0ID0gb1ZpZXcuZ2V0QmluZGluZ0NvbnRleHQoXCJpbnRlcm5hbFwiKTtcblxuXHRpZiAob0ludGVybmFsTW9kZWxDb250ZXh0KSB7XG5cdFx0Y29uc3QgYVNlbWFudGljT2JqZWN0c1Byb21pc2VzID0gW107XG5cdFx0Y29uc3Qgb0NvbXBvbmVudCA9IG9Db250cm9sbGVyLmdldE93bmVyQ29tcG9uZW50KCk7XG5cdFx0Y29uc3Qgb0FwcENvbXBvbmVudCA9IENvbXBvbmVudC5nZXRPd25lckNvbXBvbmVudEZvcihvQ29tcG9uZW50KSBhcyBBcHBDb21wb25lbnQ7XG5cdFx0Y29uc3Qgb01ldGFNb2RlbCA9IG9BcHBDb21wb25lbnQuZ2V0TWV0YU1vZGVsKCk7XG5cdFx0bGV0IG9QYWdlTW9kZWwgPSBvQ29tcG9uZW50LmdldE1vZGVsKHNQYWdlTW9kZWwpLmdldERhdGEoKTtcblx0XHRpZiAoSlNPTi5zdHJpbmdpZnkob1BhZ2VNb2RlbCkgPT09IFwie31cIikge1xuXHRcdFx0b1BhZ2VNb2RlbCA9IG9Db21wb25lbnQuZ2V0TW9kZWwoc1BhZ2VNb2RlbCkuX2dldE9iamVjdChcIi9cIiwgdW5kZWZpbmVkKTtcblx0XHR9XG5cdFx0bGV0IGFTZW1hbnRpY09iamVjdHNGb3VuZCA9IF9mbmZpbmRWYWx1ZXMob1BhZ2VNb2RlbCwgXCJzZW1hbnRpY09iamVjdFBhdGhcIik7XG5cdFx0YVNlbWFudGljT2JqZWN0c0ZvdW5kID0gX2ZuRGVsZXRlRHVwbGljYXRlU2VtYW50aWNPYmplY3RzKGFTZW1hbnRpY09iamVjdHNGb3VuZCk7XG5cdFx0Y29uc3Qgb1NoZWxsU2VydmljZUhlbHBlciA9IENvbW1vblV0aWxzLmdldFNoZWxsU2VydmljZXMob0FwcENvbXBvbmVudCk7XG5cdFx0bGV0IHNDdXJyZW50SGFzaCA9IENvbW1vblV0aWxzLmdldEhhc2goKTtcblx0XHRjb25zdCBhU2VtYW50aWNPYmplY3RzRm9yR2V0TGlua3MgPSBbXTtcblx0XHRjb25zdCBhU2VtYW50aWNPYmplY3RzOiBhbnlbXSA9IFtdO1xuXHRcdGxldCBzUGF0aDtcblx0XHRsZXQgX29TZW1hbnRpY09iamVjdDtcblxuXHRcdGlmIChzQ3VycmVudEhhc2ggJiYgc0N1cnJlbnRIYXNoLmluZGV4T2YoXCI/XCIpICE9PSAtMSkge1xuXHRcdFx0Ly8gc0N1cnJlbnRIYXNoIGNhbiBjb250YWluIHF1ZXJ5IHN0cmluZywgY3V0IGl0IG9mZiFcblx0XHRcdHNDdXJyZW50SGFzaCA9IHNDdXJyZW50SGFzaC5zcGxpdChcIj9cIilbMF07XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhU2VtYW50aWNPYmplY3RzRm91bmQubGVuZ3RoOyBpKyspIHtcblx0XHRcdHNQYXRoID0gYVNlbWFudGljT2JqZWN0c0ZvdW5kW2ldO1xuXHRcdFx0YVNlbWFudGljT2JqZWN0c1Byb21pc2VzLnB1c2goQ29tbW9uVXRpbHMuZ2V0U2VtYW50aWNPYmplY3RQcm9taXNlKG9BcHBDb21wb25lbnQsIG9WaWV3LCBvTWV0YU1vZGVsLCBzUGF0aCkpO1xuXHRcdH1cblxuXHRcdGlmIChhU2VtYW50aWNPYmplY3RzUHJvbWlzZXMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFByb21pc2UuYWxsKGFTZW1hbnRpY09iamVjdHNQcm9taXNlcylcblx0XHRcdFx0LnRoZW4oZnVuY3Rpb24oYVZhbHVlczogYW55W10pIHtcblx0XHRcdFx0XHRjb25zdCBhR2V0TGlua3NQcm9taXNlcyA9IFtdO1xuXHRcdFx0XHRcdGxldCBzU2VtT2JqRXhwcmVzc2lvbjtcblx0XHRcdFx0XHRjb25zdCBhU2VtYW50aWNPYmplY3RzUmVzb2x2ZWQgPSBhVmFsdWVzLmZpbHRlcihmdW5jdGlvbihlbGVtZW50OiBhbnkpIHtcblx0XHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdFx0ZWxlbWVudC5zZW1hbnRpY09iamVjdCAhPT0gdW5kZWZpbmVkICYmXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQuc2VtYW50aWNPYmplY3Quc2VtYW50aWNPYmplY3QgJiZcblx0XHRcdFx0XHRcdFx0dHlwZW9mIGVsZW1lbnQuc2VtYW50aWNPYmplY3Quc2VtYW50aWNPYmplY3QgPT09IFwib2JqZWN0XCJcblx0XHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0XHRzU2VtT2JqRXhwcmVzc2lvbiA9IGNvbXBpbGVCaW5kaW5nKGJpbmRpbmdFeHByZXNzaW9uKGVsZW1lbnQuc2VtYW50aWNPYmplY3Quc2VtYW50aWNPYmplY3QuJFBhdGgpKTtcblx0XHRcdFx0XHRcdFx0ZWxlbWVudC5zZW1hbnRpY09iamVjdC5zZW1hbnRpY09iamVjdCA9IHNTZW1PYmpFeHByZXNzaW9uO1xuXHRcdFx0XHRcdFx0XHRlbGVtZW50LnNlbWFudGljT2JqZWN0Rm9yR2V0TGlua3NbMF0uc2VtYW50aWNPYmplY3QgPSBzU2VtT2JqRXhwcmVzc2lvbjtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKGVsZW1lbnQpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGVsZW1lbnQuc2VtYW50aWNPYmplY3QgIT09IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IGFTZW1hbnRpY09iamVjdHNSZXNvbHZlZC5sZW5ndGg7IGorKykge1xuXHRcdFx0XHRcdFx0X29TZW1hbnRpY09iamVjdCA9IGFTZW1hbnRpY09iamVjdHNSZXNvbHZlZFtqXTtcblx0XHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdFx0X29TZW1hbnRpY09iamVjdCAmJlxuXHRcdFx0XHRcdFx0XHRfb1NlbWFudGljT2JqZWN0LnNlbWFudGljT2JqZWN0ICYmXG5cdFx0XHRcdFx0XHRcdCEoX29TZW1hbnRpY09iamVjdC5zZW1hbnRpY09iamVjdC5zZW1hbnRpY09iamVjdC5pbmRleE9mKFwie1wiKSA9PT0gMClcblx0XHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0XHRhU2VtYW50aWNPYmplY3RzRm9yR2V0TGlua3MucHVzaChfb1NlbWFudGljT2JqZWN0LnNlbWFudGljT2JqZWN0Rm9yR2V0TGlua3MpO1xuXHRcdFx0XHRcdFx0XHRhU2VtYW50aWNPYmplY3RzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRcdHNlbWFudGljT2JqZWN0OiBfb1NlbWFudGljT2JqZWN0LnNlbWFudGljT2JqZWN0LnNlbWFudGljT2JqZWN0LFxuXHRcdFx0XHRcdFx0XHRcdHVuYXZhaWxhYmxlQWN0aW9uczogX29TZW1hbnRpY09iamVjdC51bmF2YWlsYWJsZUFjdGlvbnMsXG5cdFx0XHRcdFx0XHRcdFx0cGF0aDogYVNlbWFudGljT2JqZWN0c1Jlc29sdmVkW2pdLnNlbWFudGljT2JqZWN0UGF0aFxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0YUdldExpbmtzUHJvbWlzZXMucHVzaChvU2hlbGxTZXJ2aWNlSGVscGVyLmdldExpbmtzV2l0aENhY2hlKFtfb1NlbWFudGljT2JqZWN0LnNlbWFudGljT2JqZWN0Rm9yR2V0TGlua3NdKSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBDb21tb25VdGlscy51cGRhdGVTZW1hbnRpY1RhcmdldHMoYUdldExpbmtzUHJvbWlzZXMsIGFTZW1hbnRpY09iamVjdHMsIG9JbnRlcm5hbE1vZGVsQ29udGV4dCwgc0N1cnJlbnRIYXNoKTtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0TG9nLmVycm9yKFwiZm5HZXRTZW1hbnRpY1RhcmdldHNGcm9tVGFibGU6IENhbm5vdCBnZXQgU2VtYW50aWMgT2JqZWN0c1wiLCBvRXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG59XG5mdW5jdGlvbiBnZXRGaWx0ZXJSZXN0cmljdGlvbnMob0ZpbHRlclJlc3RyaWN0aW9uc0Fubm90YXRpb246IGFueSwgc1Jlc3RyaWN0aW9uOiBhbnkpIHtcblx0Y29uc3QgRmlsdGVyUmVzdHJpY3Rpb25zID0gQ29tbW9uVXRpbHMuRmlsdGVyUmVzdHJpY3Rpb25zO1xuXHRpZiAoc1Jlc3RyaWN0aW9uID09PSBGaWx0ZXJSZXN0cmljdGlvbnMuUkVRVUlSRURfUFJPUEVSVElFUyB8fCBzUmVzdHJpY3Rpb24gPT09IEZpbHRlclJlc3RyaWN0aW9ucy5OT05fRklMVEVSQUJMRV9QUk9QRVJUSUVTKSB7XG5cdFx0bGV0IGFQcm9wcyA9IFtdO1xuXHRcdGlmIChvRmlsdGVyUmVzdHJpY3Rpb25zQW5ub3RhdGlvbiAmJiBvRmlsdGVyUmVzdHJpY3Rpb25zQW5ub3RhdGlvbltzUmVzdHJpY3Rpb25dKSB7XG5cdFx0XHRhUHJvcHMgPSBvRmlsdGVyUmVzdHJpY3Rpb25zQW5ub3RhdGlvbltzUmVzdHJpY3Rpb25dLm1hcChmdW5jdGlvbihvUHJvcGVydHk6IGFueSkge1xuXHRcdFx0XHRyZXR1cm4gb1Byb3BlcnR5LiRQcm9wZXJ0eVBhdGg7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0cmV0dXJuIGFQcm9wcztcblx0fSBlbHNlIGlmIChzUmVzdHJpY3Rpb24gPT09IEZpbHRlclJlc3RyaWN0aW9ucy5BTExPV0VEX0VYUFJFU1NJT05TKSB7XG5cdFx0Y29uc3QgbUFsbG93ZWRFeHByZXNzaW9uczogYW55ID0ge307XG5cdFx0aWYgKG9GaWx0ZXJSZXN0cmljdGlvbnNBbm5vdGF0aW9uICYmIG9GaWx0ZXJSZXN0cmljdGlvbnNBbm5vdGF0aW9uLkZpbHRlckV4cHJlc3Npb25SZXN0cmljdGlvbnMpIHtcblx0XHRcdG9GaWx0ZXJSZXN0cmljdGlvbnNBbm5vdGF0aW9uLkZpbHRlckV4cHJlc3Npb25SZXN0cmljdGlvbnMuZm9yRWFjaChmdW5jdGlvbihvUHJvcGVydHk6IGFueSkge1xuXHRcdFx0XHQvL1NpbmdsZVZhbHVlIHwgTXVsdGlWYWx1ZSB8IFNpbmdsZVJhbmdlIHwgTXVsdGlSYW5nZSB8IFNlYXJjaEV4cHJlc3Npb24gfCBNdWx0aVJhbmdlT3JTZWFyY2hFeHByZXNzaW9uXG5cdFx0XHRcdGlmIChtQWxsb3dlZEV4cHJlc3Npb25zW29Qcm9wZXJ0eS5Qcm9wZXJ0eS4kUHJvcGVydHlQYXRoXSkge1xuXHRcdFx0XHRcdG1BbGxvd2VkRXhwcmVzc2lvbnNbb1Byb3BlcnR5LlByb3BlcnR5LiRQcm9wZXJ0eVBhdGhdLnB1c2gob1Byb3BlcnR5LkFsbG93ZWRFeHByZXNzaW9ucyk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bUFsbG93ZWRFeHByZXNzaW9uc1tvUHJvcGVydHkuUHJvcGVydHkuJFByb3BlcnR5UGF0aF0gPSBbb1Byb3BlcnR5LkFsbG93ZWRFeHByZXNzaW9uc107XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gbUFsbG93ZWRFeHByZXNzaW9ucztcblx0fVxuXHQvLyBEZWZhdWx0IHJldHVybiB0aGUgRmlsdGVyUmVzdHJpY3Rpb25zIEFubm90YXRpb25cblx0cmV0dXJuIG9GaWx0ZXJSZXN0cmljdGlvbnNBbm5vdGF0aW9uO1xufVxuZnVuY3Rpb24gZ2V0RmlsdGVyUmVzdHJpY3Rpb25zQnlQYXRoKHNFbnRpdHlTZXRQYXRoOiBhbnksIG9NZXRhTW9kZWw6IGFueSkge1xuXHRjb25zdCBvUmV0OiBhbnkgPSB7fSxcblx0XHRGaWx0ZXJSZXN0cmljdGlvbnMgPSBDb21tb25VdGlscy5GaWx0ZXJSZXN0cmljdGlvbnMsXG5cdFx0b0ZpbHRlclJlc3RyaWN0aW9ucyA9IHNFbnRpdHlTZXRQYXRoID8gb01ldGFNb2RlbC5nZXRPYmplY3Qoc0VudGl0eVNldFBhdGggKyBcIkBPcmcuT0RhdGEuQ2FwYWJpbGl0aWVzLlYxLkZpbHRlclJlc3RyaWN0aW9uc1wiKSA6IHt9O1xuXHRvUmV0W0ZpbHRlclJlc3RyaWN0aW9ucy5SRVFVSVJFRF9QUk9QRVJUSUVTXSA9IGdldEZpbHRlclJlc3RyaWN0aW9ucyhvRmlsdGVyUmVzdHJpY3Rpb25zLCBGaWx0ZXJSZXN0cmljdGlvbnMuUkVRVUlSRURfUFJPUEVSVElFUykgfHwgW107XG5cdG9SZXRbRmlsdGVyUmVzdHJpY3Rpb25zLk5PTl9GSUxURVJBQkxFX1BST1BFUlRJRVNdID1cblx0XHRnZXRGaWx0ZXJSZXN0cmljdGlvbnMob0ZpbHRlclJlc3RyaWN0aW9ucywgRmlsdGVyUmVzdHJpY3Rpb25zLk5PTl9GSUxURVJBQkxFX1BST1BFUlRJRVMpIHx8IFtdO1xuXHQvL1NpbmdsZVZhbHVlIHwgTXVsdGlWYWx1ZSB8IFNpbmdsZVJhbmdlIHwgTXVsdGlSYW5nZSB8IFNlYXJjaEV4cHJlc3Npb24gfCBNdWx0aVJhbmdlT3JTZWFyY2hFeHByZXNzaW9uXG5cdG9SZXRbRmlsdGVyUmVzdHJpY3Rpb25zLkFMTE9XRURfRVhQUkVTU0lPTlNdID0gZ2V0RmlsdGVyUmVzdHJpY3Rpb25zKG9GaWx0ZXJSZXN0cmljdGlvbnMsIEZpbHRlclJlc3RyaWN0aW9ucy5BTExPV0VEX0VYUFJFU1NJT05TKSB8fCB7fTtcblxuXHRjb25zdCBhUGF0aFBhcnRzID0gc0VudGl0eVNldFBhdGguc3BsaXQoXCIvXCIpO1xuXG5cdGlmIChhUGF0aFBhcnRzLmxlbmd0aCA+IDIpIHtcblx0XHQvLyBJbiBub3JtYWwgZmlsdGVyYmFyIHNjZW5hcmlvcyBzRW50aXR5U2V0UGF0aCBpcyBvZiB0aGUgZm9ybWF0IFwiL0N1c3RvbWVyXCIuXG5cdFx0Ly8gQnV0LCBJbiBjYXNlIG9mIHNFbnRpdHlTZXRQYXRoIG9mIGZvcm1hdCBcIi9DdXN0b21lci9TZXRcIiB0aGlzIGlzIHRvIGNoZWNrIG5hdmlnYXRpb24gcmVzdHJpY3Rpb25zIG9mIFwiQ3VzdG9tZXJcIiBmb3Igbm9uLWZpbHRlcmFibGUgcHJvcGVydGllcyBpbiBcIlNldFwiXG5cdFx0Y29uc3Qgc05hdmlnYXRpb25QYXRoID0gYVBhdGhQYXJ0c1thUGF0aFBhcnRzLmxlbmd0aCAtIDFdO1xuXHRcdGFQYXRoUGFydHMuc3BsaWNlKC0xLCAxKTsgLy8gcmVtb3ZpbmcgTmF2aWdhdGlvblByb3BlcnR5IGZyb20gdGhlIGVuZC5cblx0XHRjb25zdCBzUGFyZW50RW50aXR5U2V0UGF0aCA9IGFQYXRoUGFydHMuam9pbihcIi9cIik7XG5cdFx0Y29uc3Qgb05hdmlnYXRpb25SZXN0cmljdGlvbnMgPSBDb21tb25VdGlscy5nZXROYXZpZ2F0aW9uUmVzdHJpY3Rpb25zKG9NZXRhTW9kZWwsIHNQYXJlbnRFbnRpdHlTZXRQYXRoLCBzTmF2aWdhdGlvblBhdGgpO1xuXHRcdGNvbnN0IG9OYXZpZ2F0aW9uRmlsdGVyUmVzdHJpY3Rpb25zID0gb05hdmlnYXRpb25SZXN0cmljdGlvbnMgJiYgb05hdmlnYXRpb25SZXN0cmljdGlvbnNbXCJGaWx0ZXJSZXN0cmljdGlvbnNcIl07XG5cdFx0b1JldFtGaWx0ZXJSZXN0cmljdGlvbnMuUkVRVUlSRURfUFJPUEVSVElFU10uY29uY2F0KFxuXHRcdFx0Z2V0RmlsdGVyUmVzdHJpY3Rpb25zKG9OYXZpZ2F0aW9uRmlsdGVyUmVzdHJpY3Rpb25zLCBGaWx0ZXJSZXN0cmljdGlvbnMuUkVRVUlSRURfUFJPUEVSVElFUykgfHwgW11cblx0XHQpO1xuXHRcdG9SZXRbRmlsdGVyUmVzdHJpY3Rpb25zLk5PTl9GSUxURVJBQkxFX1BST1BFUlRJRVNdLmNvbmNhdChcblx0XHRcdGdldEZpbHRlclJlc3RyaWN0aW9ucyhvTmF2aWdhdGlvbkZpbHRlclJlc3RyaWN0aW9ucywgRmlsdGVyUmVzdHJpY3Rpb25zLk5PTl9GSUxURVJBQkxFX1BST1BFUlRJRVMpIHx8IFtdXG5cdFx0KTtcblx0XHQvL1NpbmdsZVZhbHVlIHwgTXVsdGlWYWx1ZSB8IFNpbmdsZVJhbmdlIHwgTXVsdGlSYW5nZSB8IFNlYXJjaEV4cHJlc3Npb24gfCBNdWx0aVJhbmdlT3JTZWFyY2hFeHByZXNzaW9uXG5cdFx0b1JldFtGaWx0ZXJSZXN0cmljdGlvbnMuQUxMT1dFRF9FWFBSRVNTSU9OU10gPSBtZXJnZU9iamVjdHMoXG5cdFx0XHR7fSxcblx0XHRcdGdldEZpbHRlclJlc3RyaWN0aW9ucyhvTmF2aWdhdGlvbkZpbHRlclJlc3RyaWN0aW9ucywgRmlsdGVyUmVzdHJpY3Rpb25zLkFMTE9XRURfRVhQUkVTU0lPTlMpIHx8IHt9LFxuXHRcdFx0b1JldFtGaWx0ZXJSZXN0cmljdGlvbnMuQUxMT1dFRF9FWFBSRVNTSU9OU11cblx0XHQpO1xuXHR9XG5cblx0cmV0dXJuIG9SZXQ7XG59XG5mdW5jdGlvbiB0ZW1wbGF0ZUNvbnRyb2xGcmFnbWVudChzRnJhZ21lbnROYW1lOiBhbnksIG9QcmVwcm9jZXNzb3JTZXR0aW5nczogYW55LCBvT3B0aW9uczogYW55LCBvTW9kaWZpZXI6IGFueSkge1xuXHRvT3B0aW9ucyA9IG9PcHRpb25zIHx8IHt9O1xuXHRpZiAob01vZGlmaWVyKSB7XG5cdFx0cmV0dXJuIG9Nb2RpZmllci50ZW1wbGF0ZUNvbnRyb2xGcmFnbWVudChzRnJhZ21lbnROYW1lLCBvUHJlcHJvY2Vzc29yU2V0dGluZ3MsIG9PcHRpb25zLnZpZXcpLnRoZW4oZnVuY3Rpb24ob0ZyYWdtZW50OiBhbnkpIHtcblx0XHRcdC8vIFRoaXMgaXMgcmVxdWlyZWQgYXMgRmxleCByZXR1cm5zIGFuIEhUTUxDb2xsZWN0aW9uIGFzIHRlbXBsYXRpbmcgcmVzdWx0IGluIFhNTCB0aW1lLlxuXHRcdFx0cmV0dXJuIG9Nb2RpZmllci50YXJnZXRzID09PSBcInhtbFRyZWVcIiAmJiBvRnJhZ21lbnQubGVuZ3RoID4gMCA/IG9GcmFnbWVudFswXSA6IG9GcmFnbWVudDtcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gbG9hZE1hY3JvTGlicmFyeSgpXG5cdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIFhNTFByZXByb2Nlc3Nvci5wcm9jZXNzKFxuXHRcdFx0XHRcdFhNTFRlbXBsYXRlUHJvY2Vzc29yLmxvYWRUZW1wbGF0ZShzRnJhZ21lbnROYW1lLCBcImZyYWdtZW50XCIpLFxuXHRcdFx0XHRcdHsgbmFtZTogc0ZyYWdtZW50TmFtZSB9LFxuXHRcdFx0XHRcdG9QcmVwcm9jZXNzb3JTZXR0aW5nc1xuXHRcdFx0XHQpO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuKGZ1bmN0aW9uKG9GcmFnbWVudDogYW55KSB7XG5cdFx0XHRcdGNvbnN0IG9Db250cm9sID0gb0ZyYWdtZW50LmZpcnN0RWxlbWVudENoaWxkO1xuXHRcdFx0XHRpZiAoISFvT3B0aW9ucy5pc1hNTCAmJiBvQ29udHJvbCkge1xuXHRcdFx0XHRcdHJldHVybiBvQ29udHJvbDtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gRnJhZ21lbnQubG9hZCh7XG5cdFx0XHRcdFx0aWQ6IG9PcHRpb25zLmlkLFxuXHRcdFx0XHRcdGRlZmluaXRpb246IG9GcmFnbWVudCxcblx0XHRcdFx0XHRjb250cm9sbGVyOiBvT3B0aW9ucy5jb250cm9sbGVyXG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdH1cbn1cbmZ1bmN0aW9uIHJlcXVlc3RTaW5nbGV0b25Qcm9wZXJ0eShzUGF0aDogc3RyaW5nLCBvTW9kZWw6IE9EYXRhTW9kZWwpIHtcblx0aWYgKCFzUGF0aCB8fCAhb01vZGVsKSB7XG5cdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcblx0fVxuXG5cdGNvbnN0IG9NZXRhTW9kZWwgPSBvTW9kZWwuZ2V0TWV0YU1vZGVsKCk7XG5cdC8vIEZpbmQgdGhlIHVuZGVybHlpbmcgZW50aXR5IHNldCBmcm9tIHRoZSBwcm9wZXJ0eSBwYXRoIGFuZCBjaGVjayB3aGV0aGVyIGl0IGlzIGEgc2luZ2xldG9uLlxuXHRjb25zdCBhUGFydHMgPSBzUGF0aC5zcGxpdChcIi9cIikuZmlsdGVyKEJvb2xlYW4pLFxuXHRcdHNQcm9wZXJ0eU5hbWUgPSBhUGFydHMucG9wKCksXG5cdFx0c05hdmlnYXRpb25QYXRoID0gYVBhcnRzLmpvaW4oXCIvXCIpLFxuXHRcdG9FbnRpdHlTZXQgPSBzTmF2aWdhdGlvblBhdGggJiYgb01ldGFNb2RlbC5nZXRPYmplY3QoXCIvXCIgKyBzTmF2aWdhdGlvblBhdGgpO1xuXHRpZiAob0VudGl0eVNldCAmJiBvRW50aXR5U2V0LiRraW5kID09PSBcIlNpbmdsZXRvblwiKSB7XG5cdFx0Y29uc3Qgc1NpbmdsZXRvbk5hbWUgPSBhUGFydHNbYVBhcnRzLmxlbmd0aCAtIDFdLFxuXHRcdFx0b1Byb3BlcnR5QmluZGluZyA9IG9Nb2RlbC5iaW5kUHJvcGVydHkoXCIvXCIgKyBzU2luZ2xldG9uTmFtZSArIFwiL1wiICsgc1Byb3BlcnR5TmFtZSk7XG5cdFx0cmV0dXJuIG9Qcm9wZXJ0eUJpbmRpbmcucmVxdWVzdFZhbHVlKCk7XG5cdH1cblxuXHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xufVxuZnVuY3Rpb24gYWRkRXZlbnRUb0JpbmRpbmdJbmZvKG9Db250cm9sOiBDb250cm9sLCBzRXZlbnROYW1lOiBzdHJpbmcsIGZIYW5kbGVyOiBGdW5jdGlvbikge1xuXHRsZXQgb0JpbmRpbmdJbmZvOiBhbnk7XG5cdGNvbnN0IHNldEJpbmRpbmdJbmZvID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKG9CaW5kaW5nSW5mbykge1xuXHRcdFx0aWYgKCFvQmluZGluZ0luZm8uZXZlbnRzKSB7XG5cdFx0XHRcdG9CaW5kaW5nSW5mby5ldmVudHMgPSB7fTtcblx0XHRcdH1cblx0XHRcdGlmICghb0JpbmRpbmdJbmZvLmV2ZW50c1tzRXZlbnROYW1lXSkge1xuXHRcdFx0XHRvQmluZGluZ0luZm8uZXZlbnRzW3NFdmVudE5hbWVdID0gZkhhbmRsZXI7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCBmT3JpZ2luYWxIYW5kbGVyID0gb0JpbmRpbmdJbmZvLmV2ZW50c1tzRXZlbnROYW1lXTtcblx0XHRcdFx0b0JpbmRpbmdJbmZvLmV2ZW50c1tzRXZlbnROYW1lXSA9IGZ1bmN0aW9uKC4uLmFyZ3M6IGFueVtdKSB7XG5cdFx0XHRcdFx0ZkhhbmRsZXIuYXBwbHkodGhpcywgLi4uYXJncyk7XG5cdFx0XHRcdFx0Zk9yaWdpbmFsSGFuZGxlci5hcHBseSh0aGlzLCAuLi5hcmdzKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGlmIChvQ29udHJvbC5pc0EoXCJzYXAudWkubWRjLkNoYXJ0XCIpKSB7XG5cdFx0KG9Db250cm9sIGFzIGFueSlcblx0XHRcdC5pbm5lckNoYXJ0Qm91bmQoKVxuXHRcdFx0LnRoZW4oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdG9CaW5kaW5nSW5mbyA9IChvQ29udHJvbCBhcyBhbnkpXG5cdFx0XHRcdFx0LmdldENvbnRyb2xEZWxlZ2F0ZSgpXG5cdFx0XHRcdFx0Ll9nZXRDaGFydChvQ29udHJvbClcblx0XHRcdFx0XHQuZ2V0QmluZGluZ0luZm8oXCJkYXRhXCIpO1xuXHRcdFx0XHRzZXRCaW5kaW5nSW5mbygpO1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChmdW5jdGlvbihzRXJyb3I6IGFueSkge1xuXHRcdFx0XHRMb2cuZXJyb3Ioc0Vycm9yKTtcblx0XHRcdH0pO1xuXHR9IGVsc2Uge1xuXHRcdG9CaW5kaW5nSW5mbyA9IG9Db250cm9sLmRhdGEoXCJyb3dzQmluZGluZ0luZm9cIik7XG5cdFx0c2V0QmluZGluZ0luZm8oKTtcblx0fVxufVxuZnVuY3Rpb24gbG9hZE1hY3JvTGlicmFyeSgpIHtcblx0cmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KGZ1bmN0aW9uKHJlc29sdmUpIHtcblx0XHRzYXAudWkucmVxdWlyZShbXCJzYXAvZmUvbWFjcm9zL21hY3JvTGlicmFyeVwiXSwgZnVuY3Rpb24oLyptYWNyb0xpYnJhcnkqLykge1xuXHRcdFx0cmVzb2x2ZSgpO1xuXHRcdH0pO1xuXHR9KTtcbn1cbmNvbnN0IENvbW1vblV0aWxzID0ge1xuXHRpc1Byb3BlcnR5RmlsdGVyYWJsZTogaXNQcm9wZXJ0eUZpbHRlcmFibGUsXG5cdGlzRmllbGRDb250cm9sUGF0aEluYXBwbGljYWJsZTogaXNGaWVsZENvbnRyb2xQYXRoSW5hcHBsaWNhYmxlLFxuXHRyZW1vdmVTZW5zaXRpdmVEYXRhOiByZW1vdmVTZW5zaXRpdmVEYXRhLFxuXHRmaXJlQnV0dG9uUHJlc3M6IGZuRmlyZUJ1dHRvblByZXNzLFxuXHRnZXRUYXJnZXRWaWV3OiBnZXRUYXJnZXRWaWV3LFxuXHRoYXNUcmFuc2llbnRDb250ZXh0OiBmbkhhc1RyYW5zaWVudENvbnRleHRzLFxuXHR1cGRhdGVSZWxhdGVkQXBwc0RldGFpbHM6IGZuVXBkYXRlUmVsYXRlZEFwcHNEZXRhaWxzLFxuXHRyZXNvbHZlU3RyaW5ndG9Cb29sZWFuOiBmblJlc29sdmVTdHJpbmd0b0Jvb2xlYW4sXG5cdGdldEFwcENvbXBvbmVudDogZ2V0QXBwQ29tcG9uZW50LFxuXHRwcm9jZXNzRGF0YUxvc3NDb25maXJtYXRpb246IGZuUHJvY2Vzc0RhdGFMb3NzQ29uZmlybWF0aW9uLFxuXHRnZXRNYW5kYXRvcnlGaWx0ZXJGaWVsZHM6IGZuR2V0TWFuZGF0b3J5RmlsdGVyRmllbGRzLFxuXHRnZXRDb250ZXh0UGF0aFByb3BlcnRpZXM6IGZuR2V0Q29udGV4dFBhdGhQcm9wZXJ0aWVzLFxuXHRnZXRQYXJhbWV0ZXJJbmZvOiBnZXRQYXJhbWV0ZXJJbmZvLFxuXHR1cGRhdGVEYXRhRmllbGRGb3JJQk5CdXR0b25zVmlzaWJpbGl0eTogZm5VcGRhdGVEYXRhRmllbGRGb3JJQk5CdXR0b25zVmlzaWJpbGl0eSxcblx0Z2V0VHJhbnNsYXRlZFRleHQ6IGdldFRyYW5zbGF0ZWRUZXh0LFxuXHRnZXRFbnRpdHlTZXROYW1lOiBnZXRFbnRpdHlTZXROYW1lLFxuXHRnZXRBY3Rpb25QYXRoOiBnZXRBY3Rpb25QYXRoLFxuXHRjb21wdXRlRGlzcGxheU1vZGU6IGNvbXB1dGVEaXNwbGF5TW9kZSxcblx0c2V0QWN0aW9uRW5hYmxlbWVudDogc2V0QWN0aW9uRW5hYmxlbWVudCxcblx0aXNTdGlja3lFZGl0TW9kZTogaXNTdGlja3lFZGl0TW9kZSxcblx0Z2V0T3BlcmF0b3JzRm9yUHJvcGVydHk6IGdldE9wZXJhdG9yc0ZvclByb3BlcnR5LFxuXHRhZGRTZWxlY3Rpb25WYXJpYW50VG9Db25kaXRpb25zOiBhZGRTZWxlY3Rpb25WYXJpYW50VG9Db25kaXRpb25zLFxuXHRhZGRFeHRlcm5hbFN0YXRlRmlsdGVyc1RvU2VsZWN0aW9uVmFyaWFudDogYWRkRXh0ZXJuYWxTdGF0ZUZpbHRlcnNUb1NlbGVjdGlvblZhcmlhbnQsXG5cdGFkZFBhZ2VDb250ZXh0VG9TZWxlY3Rpb25WYXJpYW50OiBhZGRQYWdlQ29udGV4dFRvU2VsZWN0aW9uVmFyaWFudCxcblx0YWRkRGVmYXVsdERpc3BsYXlDdXJyZW5jeTogYWRkRGVmYXVsdERpc3BsYXlDdXJyZW5jeSxcblx0Z2V0Tm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzOiBnZXROb25Db21wdXRlZFZpc2libGVGaWVsZHMsXG5cdHNldFVzZXJEZWZhdWx0czogc2V0VXNlckRlZmF1bHRzLFxuXHRnZXRTaGVsbFNlcnZpY2VzOiBnZXRTaGVsbFNlcnZpY2VzLFxuXHRnZXRIYXNoOiBnZXRIYXNoLFxuXHRnZXRJQk5BY3Rpb25zOiBmbkdldElCTkFjdGlvbnMsXG5cdGdldEhlYWRlckZhY2V0SXRlbUNvbmZpZ0ZvckV4dGVybmFsTmF2aWdhdGlvbjogZ2V0SGVhZGVyRmFjZXRJdGVtQ29uZmlnRm9yRXh0ZXJuYWxOYXZpZ2F0aW9uLFxuXHRnZXRTZW1hbnRpY09iamVjdE1hcHBpbmc6IGdldFNlbWFudGljT2JqZWN0TWFwcGluZyxcblx0c2V0U2VtYW50aWNPYmplY3RNYXBwaW5nczogc2V0U2VtYW50aWNPYmplY3RNYXBwaW5ncyxcblx0Z2V0U2VtYW50aWNPYmplY3RQcm9taXNlOiBmbkdldFNlbWFudGljT2JqZWN0UHJvbWlzZSxcblx0Z2V0U2VtYW50aWNUYXJnZXRzRnJvbVBhZ2VNb2RlbDogZm5HZXRTZW1hbnRpY1RhcmdldHNGcm9tUGFnZU1vZGVsLFxuXHRnZXRTZW1hbnRpY09iamVjdHNGcm9tUGF0aDogZm5HZXRTZW1hbnRpY09iamVjdHNGcm9tUGF0aCxcblx0dXBkYXRlU2VtYW50aWNUYXJnZXRzOiBmblVwZGF0ZVNlbWFudGljVGFyZ2V0c01vZGVsLFxuXHRnZXRQcm9wZXJ0eURhdGFUeXBlOiBnZXRQcm9wZXJ0eURhdGFUeXBlLFxuXHRnZXROYXZpZ2F0aW9uUmVzdHJpY3Rpb25zOiBnZXROYXZpZ2F0aW9uUmVzdHJpY3Rpb25zLFxuXHRnZXRTZWFyY2hSZXN0cmljdGlvbnM6IGdldFNlYXJjaFJlc3RyaWN0aW9ucyxcblx0Z2V0RmlsdGVyUmVzdHJpY3Rpb25zQnlQYXRoOiBnZXRGaWx0ZXJSZXN0cmljdGlvbnNCeVBhdGgsXG5cdGdldFNwZWNpZmljQWxsb3dlZEV4cHJlc3Npb246IGdldFNwZWNpZmljQWxsb3dlZEV4cHJlc3Npb24sXG5cdGdldEFkZGl0aW9uYWxQYXJhbXNGb3JDcmVhdGU6IGdldEFkZGl0aW9uYWxQYXJhbXNGb3JDcmVhdGUsXG5cdHJlcXVlc3RTaW5nbGV0b25Qcm9wZXJ0eTogcmVxdWVzdFNpbmdsZXRvblByb3BlcnR5LFxuXHR0ZW1wbGF0ZUNvbnRyb2xGcmFnbWVudDogdGVtcGxhdGVDb250cm9sRnJhZ21lbnQsXG5cdGFkZEV2ZW50VG9CaW5kaW5nSW5mbzogYWRkRXZlbnRUb0JpbmRpbmdJbmZvLFxuXHRGaWx0ZXJSZXN0cmljdGlvbnM6IHtcblx0XHRSRVFVSVJFRF9QUk9QRVJUSUVTOiBcIlJlcXVpcmVkUHJvcGVydGllc1wiLFxuXHRcdE5PTl9GSUxURVJBQkxFX1BST1BFUlRJRVM6IFwiTm9uRmlsdGVyYWJsZVByb3BlcnRpZXNcIixcblx0XHRBTExPV0VEX0VYUFJFU1NJT05TOiBcIkZpbHRlckFsbG93ZWRFeHByZXNzaW9uc1wiXG5cdH0sXG5cdEFsbG93ZWRFeHByZXNzaW9uc1ByaW86IFtcIlNpbmdsZVZhbHVlXCIsIFwiTXVsdGlWYWx1ZVwiLCBcIlNpbmdsZVJhbmdlXCIsIFwiTXVsdGlSYW5nZVwiLCBcIlNlYXJjaEV4cHJlc3Npb25cIiwgXCJNdWx0aVJhbmdlT3JTZWFyY2hFeHByZXNzaW9uXCJdLFxuXHRmblByb2Nlc3NEYXRhTG9zc09yRHJhZnREaXNjYXJkQ29uZmlybWF0aW9uOiBmblByb2Nlc3NEYXRhTG9zc09yRHJhZnREaXNjYXJkQ29uZmlybWF0aW9uLFxuXHRub3JtYWxpemVTZWFyY2hUZXJtOiBub3JtYWxpemVTZWFyY2hUZXJtXG59O1xuXG5leHBvcnQgZGVmYXVsdCBDb21tb25VdGlscztcbiJdfQ==