@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,1581 +1,1578 @@
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
- sap.ui.define(
6
- [
7
- "sap/ui/base/Object",
8
- "sap/fe/core/AnnotationHelper",
9
- "sap/fe/core/actions/draft",
10
- "sap/fe/core/actions/sticky",
11
- "sap/fe/core/actions/operations",
12
- "sap/ui/model/json/JSONModel",
13
- "sap/m/Popover",
14
- "sap/m/VBox",
15
- "sap/m/CheckBox",
16
- "sap/m/Text",
17
- "sap/m/Button",
18
- "sap/m/MessageToast",
19
- "sap/m/Dialog",
20
- "sap/ui/model/BindingMode",
21
- "sap/base/Log",
22
- "sap/ui/core/message/Message",
23
- "sap/fe/core/CommonUtils",
24
- "sap/fe/core/BusyLocker",
25
- "sap/ui/core/util/XMLPreprocessor",
26
- "sap/ui/core/XMLTemplateProcessor",
27
- "sap/ui/core/Fragment",
28
- "sap/m/MessageBox",
29
- "sap/fe/core/helpers/ModelHelper",
30
- "sap/fe/core/library",
31
- "sap/ui/core/ValueState",
32
- "sap/fe/core/actions/messageHandling"
33
- ],
34
- function(
35
- BaseObject,
36
- AnnotationHelper,
37
- draft,
38
- sticky,
39
- operations,
40
- JSONModel,
41
- Popover,
42
- VBox,
43
- CheckBox,
44
- Text,
45
- Button,
46
- MessageToast,
47
- Dialog,
48
- BindingMode,
49
- Log,
50
- Message,
51
- CommonUtils,
52
- BusyLocker,
53
- XMLPreprocessor,
54
- XMLTemplateProcessor,
55
- Fragment,
56
- MessageBox,
57
- ModelHelper,
58
- FELibrary,
59
- ValueState,
60
- messageHandling
61
- ) {
62
- "use strict";
63
- var CreationMode = FELibrary.CreationMode,
64
- ProgrammingModel = FELibrary.ProgrammingModel;
65
- /* Make sure that the mParameters is not the oEvent */
66
- function getParameters(mParameters) {
67
- if (mParameters && mParameters.getMetadata && mParameters.getMetadata().getName() === "sap.ui.base.Event") {
68
- mParameters = {};
69
- }
70
- return mParameters || {};
71
- }
72
- return BaseObject.extend("sap.fe.core.TransactionHelper", {
73
- constructor: function(oAppComponent, oLockObject) {
74
- this._oAppComponent = oAppComponent;
75
- this.oLockObject = oLockObject;
76
- },
77
- getProgrammingModel: function(oContext) {
78
- if (!this.sProgrammingModel && oContext) {
79
- if (ModelHelper.isDraftSupported(oContext.getModel().getMetaModel(), oContext.getPath())) {
80
- this.sProgrammingModel = ProgrammingModel.Draft;
81
- } else if (ModelHelper.isStickySessionSupported(oContext.getModel().getMetaModel())) {
82
- this.sProgrammingModel = ProgrammingModel.Sticky;
83
- } else {
84
- // as the transaction helper is a singleton we don't store the non draft as the user could
85
- // start with a non draft child page and navigates back to a draft enabled one
86
- return ProgrammingModel.NonDraft;
87
- }
88
- }
89
- return this.sProgrammingModel;
90
- },
91
- /**
92
- * Creates a new document.
93
- *
94
- * @memberof sap.fe.core.TransactionHelper
95
- * @static
96
- * @param {sap.ui.model.odata.v4.ODataListBinding} oMainListBinding OData v4 ListBinding object
97
- * @param {object} [mParameters] Optional, can contain the following attributes:
98
- * @param {boolean} [mParameters.refreshList] If the list shall be refreshed immediately after creating the instance
99
- * @param {map} [mParameters.data] A map of data that should be sent within the POST
100
- * @param {string} [mParameters.busyMode] Global (default), Local, None TODO: to be refactored
101
- * @param {map} [mParameters.keepTransientContextOnFailed] If set, the context stays in the list if the POST failed and POST will be repeated with the next change
102
- * @param oResourceBundle
103
- * @param messageHandler
104
- * @param bFromCopyPaste
105
- * @returns {Promise} Promise resolves with new binding context
106
- * @ui5-restricted
107
- * @final
108
- */
109
- createDocument: function(oMainListBinding, mParameters, oResourceBundle, messageHandler, bFromCopyPaste) {
110
- var oNewDocumentContext,
111
- that = this,
112
- bSkipRefresh,
113
- oModel = oMainListBinding.getModel(),
114
- oMetaModel = oModel.getMetaModel(),
115
- sMetaPath = oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()),
116
- sCreateHash = this._getAppComponent()
117
- .getRouterProxy()
118
- .getHash(),
119
- oComponentData = this._getAppComponent().getComponentData(),
120
- oStartupParameters = (oComponentData && oComponentData.startupParameters) || {},
121
- sNewAction = !oMainListBinding.isRelative()
122
- ? this._getNewAction(oStartupParameters, sCreateHash, oMetaModel, sMetaPath)
123
- : undefined,
124
- oCreationPromise,
125
- mBindingParameters = { "$$patchWithoutSideEffects": true },
126
- sMessagesPath = oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path"),
127
- sProgrammingModel,
128
- sBusyPath = "/busy",
129
- sFunctionName =
130
- oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") ||
131
- oMetaModel.getObject(
132
- ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) +
133
- "@com.sap.vocabularies.Common.v1.DefaultValuesFunction"
134
- );
135
-
136
- if (sMessagesPath) {
137
- mBindingParameters["$select"] = sMessagesPath;
138
- }
139
- mParameters = getParameters(mParameters);
140
- if (!oMainListBinding) {
141
- return Promise.reject("Binding required for new document creation");
142
- }
143
- sProgrammingModel = this.getProgrammingModel(oMainListBinding);
144
- if (sProgrammingModel !== ProgrammingModel.Draft && sProgrammingModel !== ProgrammingModel.Sticky) {
145
- return Promise.reject("Create document only allowed for draft or sticky session supported services");
146
- }
147
- if (mParameters.busyMode === "Local") {
148
- // in case of local busy mode we use the list binding name
149
- // there's no APY yet so we have to use the .sId TODO provide a public method?
150
- sBusyPath = "/busyLocal/" + oMainListBinding.sId;
151
- }
152
- BusyLocker.lock(this.oLockObject, sBusyPath);
153
- bSkipRefresh = !mParameters.refreshList;
154
- var oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
155
- if (sNewAction) {
156
- oCreationPromise = this.callAction(
157
- sNewAction,
158
- {
159
- contexts: oMainListBinding.getHeaderContext(),
160
- showActionParameterDialog: true,
161
- label: oResourceBundleCore.getText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE"),
162
- bindingParameters: mBindingParameters,
163
- parentControl: mParameters.parentControl,
164
- bIsCreateAction: true
165
- },
166
- null,
167
- messageHandler
168
- );
169
- } else {
170
- var bIsNewPageCreation =
171
- mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
172
- var aNonComputedVisibleKeyFields = bIsNewPageCreation
173
- ? CommonUtils.getNonComputedVisibleFields(oMetaModel, sMetaPath)
174
- : [];
175
- sFunctionName = bFromCopyPaste ? null : sFunctionName;
176
- oCreationPromise = operations
177
- .callFunctionImport(sFunctionName, oModel)
178
- .then(function(oContext) {
179
- if (oContext) {
180
- return oContext.getObject();
181
- } else {
182
- return undefined;
183
- }
184
- })
185
- .catch(function(oError) {
186
- Log.error("Error while calling function Import " + sFunctionName, oError);
187
- throw oError;
188
- })
189
- .then(function(oData) {
190
- mParameters.data = oData ? Object.assign({}, oData, mParameters.data) : mParameters.data;
191
- if (mParameters.data) {
192
- delete mParameters.data["@odata.context"];
193
- }
194
- if (aNonComputedVisibleKeyFields.length > 0) {
195
- var oTransientListBinding = oModel.bindList(
196
- oMainListBinding.getPath(),
197
- oMainListBinding.getContext(),
198
- [],
199
- [],
200
- {
201
- $$updateGroupId: "submitLater"
202
- }
203
- );
204
- oTransientListBinding.refreshInternal = function() {};
205
- oNewDocumentContext = oTransientListBinding.create(mParameters.data, bSkipRefresh);
206
- return that._launchDialogWithKeyFields(
207
- oMainListBinding,
208
- oTransientListBinding,
209
- oNewDocumentContext,
210
- aNonComputedVisibleKeyFields,
211
- oModel,
212
- mParameters,
213
- messageHandler
214
- );
215
- } else {
216
- oNewDocumentContext = oMainListBinding.create(mParameters.data, bSkipRefresh, mParameters.createAtEnd);
217
- return that.onAfterCreateCompletion(
218
- oMainListBinding,
219
- oNewDocumentContext,
220
- mParameters,
221
- oResourceBundleCore
222
- );
223
- }
224
- })
225
- .catch(function(oError) {
226
- Log.error("Error while creating the new document", oError);
227
- throw oError;
228
- });
229
- }
230
- return oCreationPromise
231
- .then(function(oResult) {
232
- if (!oMainListBinding.isRelative()) {
233
- // the create mode shall currently only be set on creating a root document
234
- that._bCreateMode = true;
235
- }
236
- oNewDocumentContext = oNewDocumentContext || (oResult && oResult.response);
237
- // TODO: where does this one coming from???
238
- if (oResult && oResult.bConsiderDocumentModified) {
239
- that.handleDocumentModifications();
240
- }
241
- return messageHandler.showMessageDialog().then(function() {
242
- return oNewDocumentContext;
243
- });
244
- })
245
- .catch(function(oError) {
246
- return messageHandler.showMessageDialog().then(function() {
247
- // for instance, on cancel of create dialog, the promise is rejected
248
- // a return here would restore the promise chain and result in errors while routing
249
- // solution - reject here as well
250
- if (oError && oError.bDeleteTransientContext && oNewDocumentContext.isTransient()) {
251
- // This is a workaround suggested by model as Context.delete results in an error
252
- // TODO: remove the $direct once model resolves this issue
253
- // this line shows the expected console error Uncaught (in promise) Error: Request canceled: POST Travel; group: submitLater
254
- oNewDocumentContext.delete("$direct");
255
- }
256
- return Promise.reject(oError);
257
- });
258
- })
259
- .finally(function() {
260
- BusyLocker.unlock(that.oLockObject, sBusyPath);
261
- });
262
- },
263
- /**
264
- * Find the active contexts of the documents, only for the draft roots.
265
- *
266
- * @memberof sap.fe.core.TransactionHelper
267
- * @static
268
- * @param {sap.ui.model.odata.v4.Context[]} aContexts Contexts Either one context or an array with contexts to be deleted
269
- * @param bFindActiveContexts
270
- * @returns {Array} Array of the active contexts
271
- */
272
- findActiveDraftRootContexts: function(aContexts, bFindActiveContexts) {
273
- if (!bFindActiveContexts) {
274
- return Promise.resolve();
275
- }
276
- var activeContexts = aContexts.reduce(function(aResult, oContext) {
277
- var oMetaModel = oContext.getModel().getMetaModel();
278
- var sMetaPath = oMetaModel.getMetaPath(oContext.getPath());
279
- if (oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot")) {
280
- var bIsActiveEntity = oContext.getObject().IsActiveEntity,
281
- bHasActiveEntity = oContext.getObject().HasActiveEntity,
282
- oActiveContext;
283
- if (!bIsActiveEntity && bHasActiveEntity) {
284
- oActiveContext = oContext
285
- .getModel()
286
- .bindContext(oContext.getPath() + "/SiblingEntity")
287
- .getBoundContext();
288
- aResult.push(oActiveContext);
289
- }
290
- }
291
- return aResult;
292
- }, []);
293
- return Promise.all(
294
- activeContexts.map(function(oContext) {
295
- return oContext.requestCanonicalPath().then(
296
- function() {
297
- return oContext;
298
- },
299
- function() {
300
- return;
301
- }
302
- );
303
- })
304
- );
305
- },
306
- afterDeleteProcess: function(mParameters, checkBox, aContexts, oResourceBundle) {
307
- var oInternalModelContext = mParameters.internalModelContext;
308
- if (oInternalModelContext && oInternalModelContext.getProperty("deleteEnabled") != undefined) {
309
- if (checkBox.isCheckBoxVisible === true && checkBox.isCheckBoxSelected === false) {
310
- //if unsaved objects are not deleted then we need to set the enabled to true and update the model data for next deletion
311
- oInternalModelContext.setProperty("deleteEnabled", true);
312
- var obj = Object.assign(oInternalModelContext.getObject(), {});
313
- obj.selectedContexts = obj.selectedContexts.filter(function(element) {
314
- return obj.deletableContexts.indexOf(element) === -1;
315
- });
316
- obj.deletableContexts = [];
317
- obj.selectedContexts = [];
318
- obj.numberOfSelectedContexts = obj.selectedContexts.length;
319
- oInternalModelContext.setProperty("", obj);
320
- } else {
321
- oInternalModelContext.setProperty("deleteEnabled", false);
322
- oInternalModelContext.setProperty("selectedContexts", []);
323
- oInternalModelContext.setProperty("numberOfSelectedContexts", 0);
324
- }
325
- }
326
- if (aContexts.length === 1) {
327
- MessageToast.show(
328
- CommonUtils.getTranslatedText(
329
- "C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_SINGULAR",
330
- oResourceBundle,
331
- null,
332
- mParameters.entitySetName
333
- )
334
- );
335
- } else {
336
- MessageToast.show(
337
- CommonUtils.getTranslatedText(
338
- "C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_PLURAL",
339
- oResourceBundle,
340
- null,
341
- mParameters.entitySetName
342
- )
343
- );
344
- }
345
- },
346
- /**
347
- * Delete one or multiple document(s).
348
- *
349
- * @memberof sap.fe.core.TransactionHelper
350
- * @static
351
- * @param {sap.ui.model.odata.v4.Context} vContexts Contexts Either one context or an array with contexts to be deleted
352
- * @param {object} mParameters Optional, can contain the following attributes:
353
- * @param {string} mParameters.title Title of the object to be deleted
354
- * @param {string} mParameters.description Description of the object to be deleted
355
- * @param {string} mParameters.numberOfSelectedContexts Number of objects selected
356
- * @param {boolean} mParameters.noDialog To disable the confirmation dialog
357
- * @param oResourceBundle
358
- * @param messageHandler
359
- * @returns {Promise}
360
- */
361
- deleteDocument: function(vContexts, mParameters, oResourceBundle, messageHandler) {
362
- var fnReject,
363
- fnResolve,
364
- aDeletableContexts = [],
365
- isCheckBoxVisible = false,
366
- isLockedTextVisible = false,
367
- cannotBeDeletedTextVisible = false,
368
- isCheckBoxSelected,
369
- bDialogConfirmed = false,
370
- that = this,
371
- oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core"),
372
- aParams,
373
- oDeleteMessage = {
374
- title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
375
- };
376
- BusyLocker.lock(this.oLockObject);
377
- if (!Array.isArray(vContexts)) {
378
- vContexts = [vContexts];
379
- }
380
- Promise.resolve(this.getProgrammingModel(vContexts[0]))
381
- .then(function(sProgrammingModel) {
382
- if (mParameters) {
383
- if (!mParameters.numberOfSelectedContexts) {
384
- if (sProgrammingModel === ProgrammingModel.Draft) {
385
- for (var i = 0; i < vContexts.length; i++) {
386
- var oContextData = vContexts[i].getObject();
387
- if (
388
- oContextData.IsActiveEntity === true &&
389
- oContextData.HasDraftEntity === true &&
390
- oContextData.DraftAdministrativeData &&
391
- oContextData.DraftAdministrativeData.InProcessByUser &&
392
- !oContextData.DraftAdministrativeData.DraftIsCreatedByMe
393
- ) {
394
- MessageBox.show(
395
- CommonUtils.getTranslatedText(
396
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_SINGLE_OBJECT_LOCKED",
397
- oResourceBundle
398
- ),
399
- {
400
- title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
401
- onClose: fnReject
402
- }
403
- );
404
- return;
405
- }
406
- }
407
- }
408
- mParameters = getParameters(mParameters);
409
- if (mParameters.title) {
410
- if (mParameters.description) {
411
- aParams = [mParameters.title, mParameters.description];
412
- oDeleteMessage.text = CommonUtils.getTranslatedText(
413
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO",
414
- oResourceBundle,
415
- aParams,
416
- mParameters.entitySetName
417
- );
418
- } else {
419
- oDeleteMessage.text = CommonUtils.getTranslatedText(
420
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
421
- oResourceBundle,
422
- null,
423
- mParameters.entitySetName
424
- );
425
- }
426
- } else {
427
- oDeleteMessage.text = CommonUtils.getTranslatedText(
428
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
429
- oResourceBundle
430
- );
431
- }
432
- aDeletableContexts = vContexts;
433
- } else {
434
- oDeleteMessage = {
435
- title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
436
- };
437
- if (
438
- mParameters.numberOfSelectedContexts === 1 &&
439
- mParameters.numberOfSelectedContexts === vContexts.length
440
- ) {
441
- aDeletableContexts = vContexts;
442
- oDeleteMessage.text = CommonUtils.getTranslatedText(
443
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
444
- oResourceBundle,
445
- null,
446
- mParameters.entitySetName
447
- );
448
- } else if (mParameters.numberOfSelectedContexts === 1 && mParameters.unSavedContexts.length === 1) {
449
- //only one unsaved object
450
- aDeletableContexts = mParameters.unSavedContexts;
451
- var draftAdminData = aDeletableContexts[0].getObject()["DraftAdministrativeData"];
452
- var sLastChangedByUser = "";
453
- if (draftAdminData) {
454
- sLastChangedByUser =
455
- draftAdminData["LastChangedByUserDescription"] || draftAdminData["LastChangedByUser"] || "";
456
- }
457
- aParams = [sLastChangedByUser];
458
- oDeleteMessage.text = CommonUtils.getTranslatedText(
459
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES",
460
- oResourceBundle,
461
- aParams
462
- );
463
- } else if (mParameters.numberOfSelectedContexts === mParameters.unSavedContexts.length) {
464
- //only multiple unsaved objects
465
- aDeletableContexts = mParameters.unSavedContexts;
466
- oDeleteMessage.text = CommonUtils.getTranslatedText(
467
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES_MULTIPLE_OBJECTS",
468
- oResourceBundle
469
- );
470
- } else if (
471
- mParameters.numberOfSelectedContexts ===
472
- vContexts.concat(mParameters.unSavedContexts.concat(mParameters.lockedContexts)).length
473
- ) {
474
- //only unsaved, locked ,deletable objects but not non-deletable objects
475
- aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
476
- oDeleteMessage.text =
477
- aDeletableContexts.length === 1
478
- ? CommonUtils.getTranslatedText(
479
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
480
- oResourceBundle,
481
- null,
482
- mParameters.entitySetName
483
- )
484
- : CommonUtils.getTranslatedText(
485
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL",
486
- oResourceBundle,
487
- null,
488
- mParameters.entitySetName
489
- );
490
- } else {
491
- //if non-deletable objects exists along with any of unsaved ,deletable objects
492
- aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
493
- cannotBeDeletedTextVisible = true;
494
- oDeleteMessage.text =
495
- aDeletableContexts.length === 1
496
- ? CommonUtils.getTranslatedText(
497
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR_NON_DELETABLE",
498
- oResourceBundle,
499
- null,
500
- mParameters.entitySetName
501
- )
502
- : CommonUtils.getTranslatedText(
503
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL_NON_DELETABLE",
504
- oResourceBundle,
505
- null,
506
- mParameters.entitySetName
507
- );
508
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
509
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_NON_DELETABLE",
510
- oResourceBundle,
511
- [
512
- mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length,
513
- mParameters.numberOfSelectedContexts
514
- ]
515
- );
516
- }
517
- if (mParameters.lockedContexts.length == 1) {
518
- //setting the locked text if locked objects exist
519
- isLockedTextVisible = true;
520
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
521
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED",
522
- oResourceBundle,
523
- [mParameters.numberOfSelectedContexts]
524
- );
525
- }
526
- if (mParameters.lockedContexts.length > 1) {
527
- //setting the locked text if locked objects exist
528
- isLockedTextVisible = true;
529
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
530
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED",
531
- oResourceBundle,
532
- [mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]
533
- );
534
- }
535
- if (
536
- mParameters.unSavedContexts.length > 0 &&
537
- mParameters.unSavedContexts.length !== mParameters.numberOfSelectedContexts
538
- ) {
539
- if (
540
- (cannotBeDeletedTextVisible || isLockedTextVisible) &&
541
- aDeletableContexts.length === mParameters.unSavedContexts.length
542
- ) {
543
- //if only unsaved and either or both of locked and non-deletable objects exist then we hide the check box
544
- isCheckBoxVisible = false;
545
- aDeletableContexts = mParameters.unSavedContexts;
546
- if (mParameters.unSavedContexts.length === 1) {
547
- oDeleteMessage.text = CommonUtils.getTranslatedText(
548
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_SINGULAR",
549
- oResourceBundle
550
- );
551
- } else {
552
- oDeleteMessage.text = CommonUtils.getTranslatedText(
553
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_PLURAL",
554
- oResourceBundle
555
- );
556
- }
557
- } else {
558
- if (mParameters.unSavedContexts.length === 1) {
559
- oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText(
560
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_SINGULAR",
561
- oResourceBundle
562
- );
563
- } else {
564
- oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText(
565
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_PLURAL",
566
- oResourceBundle
567
- );
568
- }
569
- isCheckBoxVisible = true;
570
- }
571
- }
572
- if (cannotBeDeletedTextVisible && isLockedTextVisible) {
573
- //if both locked and non-deletable objects exist along with deletable objects
574
- if (mParameters.unSavedContexts.length > 1) {
575
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
576
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED_AND_NON_DELETABLE",
577
- oResourceBundle,
578
- [
579
- mParameters.numberOfSelectedContexts -
580
- vContexts.concat(mParameters.unSavedContexts).length -
581
- mParameters.lockedContexts.length,
582
- mParameters.lockedContexts.length,
583
- mParameters.numberOfSelectedContexts
584
- ]
585
- );
586
- }
587
- if (mParameters.unSavedContexts.length == 1) {
588
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
589
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED_AND_NON_DELETABLE",
590
- oResourceBundle,
591
- [
592
- mParameters.numberOfSelectedContexts -
593
- vContexts.concat(mParameters.unSavedContexts).length -
594
- mParameters.lockedContexts.length,
595
- mParameters.numberOfSelectedContexts
596
- ]
597
- );
598
- }
599
- }
600
- }
601
- }
602
- var oNonDeletableMessageTextControl,
603
- oDeleteMessageTextControl,
604
- oContent = new VBox({
605
- items: [
606
- (oNonDeletableMessageTextControl = new Text({
607
- text: oDeleteMessage.nonDeletableText,
608
- visible: isLockedTextVisible || cannotBeDeletedTextVisible
609
- })),
610
- (oDeleteMessageTextControl = new Text({
611
- text: oDeleteMessage.text
612
- })),
613
- new CheckBox({
614
- text: oDeleteMessage.checkBoxText,
615
- selected: true,
616
- select: function(oEvent) {
617
- var selected = oEvent.getSource().getSelected();
618
- if (selected) {
619
- aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
620
- isCheckBoxSelected = true;
621
- } else {
622
- aDeletableContexts = vContexts;
623
- isCheckBoxSelected = false;
624
- }
625
- },
626
- visible: isCheckBoxVisible
627
- })
628
- ]
629
- });
630
- var sTitle = oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE");
631
- var fnConfirm = function() {
632
- bDialogConfirmed = true;
633
- BusyLocker.lock(that.oLockObject);
634
- var aContexts = aDeletableContexts;
635
- return that
636
- .findActiveDraftRootContexts(aContexts, mParameters.bFindActiveContexts)
637
- .then(function(activeContexts) {
638
- //make sure to fetch the active contexts before deleting the drafts
639
- return Promise.all(
640
- aContexts.map(function(oContext) {
641
- //delete the draft
642
- return draft.deleteDraft(oContext);
643
- })
644
- )
645
- .catch(function(oError) {
646
- return messageHandler.showMessages().then(function() {
647
- // re-throw error to enforce rejecting the general promise
648
- throw oError;
649
- });
650
- })
651
- .then(function() {
652
- var checkBox = {
653
- "isCheckBoxVisible": isCheckBoxVisible,
654
- "isCheckBoxSelected": isCheckBoxSelected
655
- };
656
- if (activeContexts && activeContexts.length) {
657
- return Promise.all(
658
- activeContexts.map(function(oContext) {
659
- return oContext.delete();
660
- })
661
- ).then(function() {
662
- that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
663
- return messageHandler.showMessageDialog().then(fnResolve);
664
- });
665
- } else {
666
- that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
667
- return messageHandler.showMessageDialog().then(fnResolve);
668
- }
669
- });
670
- })
671
- .catch(function() {
672
- fnReject();
673
- })
674
- .finally(function() {
675
- BusyLocker.unlock(that.oLockObject);
676
- });
677
- };
678
- var oDialog = new Dialog({
679
- title: sTitle,
680
- state: "Warning",
681
- content: [oContent],
682
- ariaLabelledBy: oNonDeletableMessageTextControl.getVisible()
683
- ? [oNonDeletableMessageTextControl, oDeleteMessageTextControl]
684
- : oDeleteMessageTextControl,
685
- beginButton: new Button({
686
- text: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
687
- type: "Emphasized",
688
- press: function() {
689
- oDialog.close();
690
- return fnConfirm();
691
- }
692
- }),
693
- endButton: new Button({
694
- text: CommonUtils.getTranslatedText("C_COMMON_OBJECT_PAGE_CANCEL", oResourceBundle),
695
- press: function() {
696
- oDialog.close();
697
- }
698
- }),
699
- afterClose: function() {
700
- oDialog.destroy();
701
- // if dialog is closed unconfirmed (e.g. via "Cancel" or Escape button), ensure to reject promise
702
- if (!bDialogConfirmed) {
703
- fnReject();
704
- }
705
- }
706
- });
707
- if (mParameters.noDialog) {
708
- return fnConfirm();
709
- } else {
710
- oDialog.addStyleClass("sapUiContentPadding");
711
- oDialog.open();
712
- }
713
- })
714
- .finally(function() {
715
- BusyLocker.unlock(that.oLockObject);
716
- })
717
- .catch(function() {
718
- Log.warning("Couldn't get Programming model");
719
- fnReject();
720
- });
721
- return new Promise(function(resolve, reject) {
722
- fnReject = reject;
723
- fnResolve = resolve;
724
- });
725
- },
726
- /**
727
- * Edits a document.
728
- *
729
- * @memberof sap.fe.core.TransactionHelper
730
- * @static
731
- * @param {sap.ui.model.odata.v4.Context} oContext Context of the active document
732
- * @param {boolean} bPrepareOnEdit Also call the 'prepare' action for draft-based documents
733
- * @param {object} oView Object of current view
734
- * @param messageHandler
735
- * @returns {Promise} Promise resolves with the new draft context in case of draft programming model
736
- * @ui5-restricted
737
- * @final
738
- */
739
- editDocument: function(oContext, bPrepareOnEdit, oView, messageHandler) {
740
- var that = this,
741
- sProgrammingModel = this.getProgrammingModel(oContext),
742
- oEditPromise;
743
- if (!oContext) {
744
- return Promise.reject(new Error("Binding context to active document is required"));
745
- }
746
- this._bIsModified = false;
747
- BusyLocker.lock(that.oLockObject);
748
- // before triggering the edit action we'll have to remove all bound transition messages
749
- messageHandler.removeTransitionMessages();
750
- if (sProgrammingModel === ProgrammingModel.Draft) {
751
- oEditPromise = draft.createDraftFromActiveDocument(oContext, this._getAppComponent(), {
752
- bPreserveChanges: true,
753
- bPrepareOnEdit: bPrepareOnEdit,
754
- oView: oView
755
- });
756
- } else if (sProgrammingModel === ProgrammingModel.Sticky) {
757
- oEditPromise = sticky.editDocumentInStickySession(oContext);
758
- } else {
759
- BusyLocker.unlock(that.oLockObject);
760
- return Promise.reject(new Error("Edit is only allowed for draft or sticky session supported services"));
761
- }
762
- return oEditPromise
763
- .then(function(oNewContext) {
764
- that._bCreateMode = false;
765
- return messageHandler.showMessageDialog().then(function() {
766
- return oNewContext;
767
- });
768
- })
769
- .catch(function(err) {
770
- return messageHandler.showMessages().then(function() {
771
- return Promise.reject(err);
772
- });
773
- })
774
- .finally(function() {
775
- BusyLocker.unlock(that.oLockObject);
776
- });
777
- },
778
- /**
779
- * Cancel 'edit' mode of a document.
780
- *
781
- * @memberof sap.fe.core.TransactionHelper
782
- * @static
783
- * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be canceled or deleted
784
- * @param {object} [mParameters] Optional, can contain the following attributes:
785
- * @param {sap.m.Button} mParameters.cancelButton Cancel Button of the discard popover (mandatory for now)
786
- * @param {boolean} mParameters.bSkipDiscardPopover Optional, supresses the discard popover incase of draft applications while navigating out of OP
787
- * @param oResourceBundle
788
- * @param messageHandler
789
- * @returns {Promise} Promise resolves with ???
790
- * @ui5-restricted
791
- * @final
792
- */
793
- cancelDocument: function(oContext, mParameters, oResourceBundle, messageHandler) {
794
- var that = this,
795
- sProgrammingModel;
796
- //context must always be passed - mandatory parameter
797
- if (!oContext) {
798
- return Promise.reject("No context exists. Pass a meaningful context");
799
- }
800
- BusyLocker.lock(that.oLockObject);
801
- mParameters = getParameters(mParameters);
802
- var oParamsContext = oContext,
803
- oCancelButton = mParameters.cancelButton,
804
- oModel = oParamsContext.getModel(),
805
- sCanonicalPath;
806
- return Promise.resolve(this.getProgrammingModel(oContext))
807
- .then(function(sPModel) {
808
- sProgrammingModel = sPModel;
809
- if (sPModel === ProgrammingModel.Draft) {
810
- var draftDataContext = oModel
811
- .bindContext(oParamsContext.getPath() + "/DraftAdministrativeData")
812
- .getBoundContext();
813
- if (!that._bIsModified) {
814
- return draftDataContext.requestObject().then(function(draftAdminData) {
815
- if (draftAdminData) {
816
- that._bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
817
- }
818
- });
819
- }
820
- }
821
- })
822
- .then(function() {
823
- if (!mParameters.bSkipDiscardPopover) {
824
- return that._showDiscardPopover(oCancelButton, that._bIsModified, oResourceBundle);
825
- } else {
826
- return Promise.resolve();
827
- }
828
- })
829
- .then(function() {
830
- // eslint-disable-next-line default-case
831
- switch (sProgrammingModel) {
832
- case ProgrammingModel.Draft:
833
- return oParamsContext.requestObject("HasActiveEntity").then(function(bHasActiveEntity) {
834
- var oDeletePromise;
835
- if (!bHasActiveEntity) {
836
- if (oParamsContext && oParamsContext.hasPendingChanges()) {
837
- oParamsContext.getBinding().resetChanges();
838
- }
839
- oDeletePromise = draft.deleteDraft(oParamsContext);
840
- return oDeletePromise;
841
- } else {
842
- var oActiveContext = oModel
843
- .bindContext(oParamsContext.getPath() + "/SiblingEntity")
844
- .getBoundContext();
845
- return oActiveContext
846
- .requestCanonicalPath()
847
- .then(
848
- function(sPath) {
849
- sCanonicalPath = sPath;
850
- if (oParamsContext && oParamsContext.hasPendingChanges()) {
851
- oParamsContext.getBinding().resetChanges();
852
- }
853
- oDeletePromise = draft.deleteDraft(oParamsContext);
854
- return oDeletePromise;
855
- },
856
- function() {
857
- draft.deleteDraft(oParamsContext);
858
- return;
859
- }
860
- )
861
- .then(function() {
862
- //oParamsContext.delete() in the previous promise doesnt return anything upon success.
863
- if (!sCanonicalPath) {
864
- return;
865
- }
866
- if (oActiveContext.getPath() !== sCanonicalPath) {
867
- // the active context is using the sibling entity - this path is not accessible anymore as we deleted the draft
868
- // document - therefore we need to create a new context with the canonical path
869
- oActiveContext = oModel.bindContext(sCanonicalPath).getBoundContext();
870
- }
871
- return oActiveContext;
872
- });
873
- }
874
- });
875
- case ProgrammingModel.Sticky:
876
- return sticky.discardDocument(oContext).then(function(oContext) {
877
- if (oContext) {
878
- if (oContext.hasPendingChanges()) {
879
- oContext.getBinding().resetChanges();
880
- }
881
- if (!that._bCreateMode) {
882
- oContext.refresh();
883
- return oContext;
884
- }
885
- }
886
- return false;
887
- });
888
- default:
889
- return Promise.reject("Cancel document only allowed for draft or sticky session supported services");
890
- }
891
- })
892
- .then(function(context) {
893
- that._bIsModified = false;
894
- // remove existing bound transition messages
895
- messageHandler.removeTransitionMessages();
896
- // show unbound messages
897
- return messageHandler.showMessages().then(function() {
898
- return context;
899
- });
900
- })
901
- .catch(function(err) {
902
- return messageHandler.showMessages().then(function() {
903
- return Promise.reject(err);
904
- });
905
- })
906
- .finally(function() {
907
- BusyLocker.unlock(that.oLockObject);
908
- });
909
- },
910
- /**
911
- * Saves the document.
912
- *
913
- * @memberof sap.fe.core.TransactionHelper
914
- * @static
915
- * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be saved
916
- * @param oResourceBundle
917
- * @param bExecuteSideEffectsOnError
918
- * @param aBindings
919
- * @param messageHandler
920
- * @returns {Promise} Promise resolves with ???
921
- * @ui5-restricted
922
- * @final
923
- */
924
- saveDocument: function(oContext, oResourceBundle, bExecuteSideEffectsOnError, aBindings, messageHandler) {
925
- var that = this,
926
- sProgrammingModel = this.getProgrammingModel(oContext),
927
- oSavePromise;
928
- if (!oContext) {
929
- return Promise.reject(new Error("Binding context to draft document is required"));
930
- }
931
- // in case of saving / activating the bound transition messages shall be removed before the PATCH/POST
932
- // is sent to the backend
933
- messageHandler.removeTransitionMessages();
934
- BusyLocker.lock(that.oLockObject);
935
- if (sProgrammingModel === ProgrammingModel.Draft) {
936
- oSavePromise = draft.activateDocument(oContext, this._getAppComponent());
937
- } else if (sProgrammingModel === ProgrammingModel.Sticky) {
938
- oSavePromise = sticky.activateDocument(oContext);
939
- } else {
940
- BusyLocker.unlock(that.oLockObject);
941
- return Promise.reject(new Error("Save is only allowed for draft or sticky session supported services"));
942
- }
943
- return oSavePromise
944
- .then(function(oActiveDocument) {
945
- var bNewObject =
946
- that.sProgrammingModel === ProgrammingModel.Sticky ? that._bCreateMode : !oContext.getObject().HasActiveEntity;
947
- MessageToast.show(
948
- bNewObject
949
- ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_CREATED", oResourceBundle)
950
- : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_SAVED", oResourceBundle)
951
- );
952
- that._bIsModified = false;
953
- return messageHandler.showMessageDialog().then(function() {
954
- return oActiveDocument;
955
- });
956
- })
957
- .catch(function(err) {
958
- if (aBindings && aBindings.length > 0) {
959
- /* The sideEffects are executed only for table items in transient state */
960
- aBindings.forEach(function(oListBinding) {
961
- if (!CommonUtils.hasTransientContext(oListBinding) && bExecuteSideEffectsOnError) {
962
- var oAppComponent = that._getAppComponent();
963
- oAppComponent
964
- .getSideEffectsService()
965
- .requestSideEffectsForNavigationProperty(oListBinding.getPath(), oContext);
966
- }
967
- });
968
- }
969
- return messageHandler.showMessages().then(function() {
970
- return Promise.reject(err);
971
- });
972
- })
973
- .finally(function() {
974
- BusyLocker.unlock(that.oLockObject);
975
- });
976
- },
977
- /**
978
- * Calls a bound/unbound action.
979
- *
980
- * @function
981
- * @static
982
- * @name sap.fe.core.TransactionHelper.callAction
983
- * @memberof sap.fe.core.TransactionHelper
984
- * @param {string} sActionName The name of the action to be called
985
- * @param {map} [mParameters] Contains the following attributes:
986
- * @param {sap.ui.model.odata.v4.Context} [mParameters.contexts] Mandatory for a bound action: Either one context or an array with contexts for which the action shall be called
987
- * @param {sap.ui.model.odata.v4.ODataModel} [mParameters.model] Mandatory for an unbound action: An instance of an OData v4 model
988
- * @param {string} [mParameters.invocationGrouping] Mode how actions are to be called: Changeset to put all action calls into one changeset, Isolated to put them into separate changesets (TODO: create enum)
989
- * @param {string} [mParameters.label] A human-readable label for the action
990
- * @param {boolean} [mParameters.bGetBoundContext] If specified, the action promise returns the bound context
991
- * @param {object} oView Contains the object of the current view
992
- * @param messageHandler
993
- * @returns {Promise} Promise resolves with an array of response objects (TODO: to be changed)
994
- * @ui5-restricted
995
- * @final
996
- **/
997
- callAction: function(sActionName, mParameters, oView, messageHandler) {
998
- mParameters = getParameters(mParameters);
999
- var that = this,
1000
- oContext,
1001
- oModel,
1002
- oPromise,
1003
- sName,
1004
- mBindingParameters = mParameters.bindingParameters;
1005
- if (!sActionName) {
1006
- return Promise.reject("Provide name of action to be executed");
1007
- }
1008
- // action imports are not directly obtained from the metaModel by it is present inside the entityContainer
1009
- // and the acions it refers to present outside the entitycontainer, hence to obtain kind of the action
1010
- // split() on its name was required
1011
- sName = sActionName.split("/")[1];
1012
- sActionName = sName || sActionName;
1013
- oContext = sName ? undefined : mParameters.contexts;
1014
- //checking whether the context is an array with more than 0 length or not an array(create action)
1015
- if (oContext && ((Array.isArray(oContext) && oContext.length) || !Array.isArray(oContext))) {
1016
- oContext = Array.isArray(oContext) ? oContext[0] : oContext;
1017
- oModel = oContext.getModel();
1018
- }
1019
- if (mParameters.model) {
1020
- oModel = mParameters.model;
1021
- }
1022
- if (!oModel) {
1023
- return Promise.reject("Pass a context for a bound action or pass the model for an unbound action");
1024
- }
1025
- // get the binding parameters $select and $expand for the side effect on this action
1026
- // also gather additional property paths to be requested such as text associations
1027
- var oAppComponent = that._getAppComponent();
1028
- var mSideEffectsParameters = oAppComponent.getSideEffectsService().getODataActionSideEffects(sActionName, oContext) || {};
1029
- if (oContext && oModel) {
1030
- oPromise = new Promise(function(resolve, reject) {
1031
- var oApplicableContextDialog;
1032
- var oController = {
1033
- onClose: function() {
1034
- // User cancels action
1035
- oApplicableContextDialog.close();
1036
- resolve();
1037
- },
1038
- onContinue: function() {
1039
- // Users continues the action with the bound contexts
1040
- oApplicableContextDialog.close();
1041
- resolve(mParameters.applicableContext);
1042
- }
1043
- };
1044
- var fnOpenAndFillDialog = function() {
1045
- var oDialogContent,
1046
- nNotApplicable = mParameters.notApplicableContext.length,
1047
- aNotApplicableItems = [];
1048
- for (var i = 0; i < mParameters.notApplicableContext.length; i++) {
1049
- oDialogContent = mParameters.notApplicableContext[i].getObject();
1050
- aNotApplicableItems.push(oDialogContent);
1051
- }
1052
- var oNotApplicableItemsModel = new JSONModel(aNotApplicableItems);
1053
- var oTotals = new JSONModel({ total: nNotApplicable, label: mParameters.label });
1054
- oApplicableContextDialog.setModel(oNotApplicableItemsModel, "notApplicable");
1055
- oApplicableContextDialog.setModel(oTotals, "totals");
1056
- oApplicableContextDialog.open();
1057
- };
1058
- if (mParameters.notApplicableContext && mParameters.notApplicableContext.length >= 1) {
1059
- // Show the contexts that are not applicable and will not therefore be processed
1060
- var sFragmentName = "sap.fe.core.controls.ActionPartial";
1061
- var oDialogFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
1062
- var oMetaModel = oModel.getMetaModel();
1063
- var sCanonicalPath = mParameters.contexts[0].getCanonicalPath();
1064
- var sEntitySet = sCanonicalPath.substr(0, sCanonicalPath.indexOf("(")) + "/";
1065
- var oDialogLabelModel = new JSONModel({
1066
- title: mParameters.label
1067
- });
1068
- Promise.resolve(
1069
- XMLPreprocessor.process(
1070
- oDialogFragment,
1071
- { name: sFragmentName },
1072
- {
1073
- bindingContexts: {
1074
- entityType: oMetaModel.createBindingContext(sEntitySet),
1075
- label: oDialogLabelModel.createBindingContext("/")
1076
- },
1077
- models: {
1078
- entityType: oMetaModel,
1079
- metaModel: oMetaModel,
1080
- label: oDialogLabelModel
1081
- }
1082
- }
1083
- )
1084
- )
1085
- .then(function(oFragment) {
1086
- return Fragment.load({ definition: oFragment, controller: oController });
1087
- })
1088
- .then(function(oPopover) {
1089
- oApplicableContextDialog = oPopover;
1090
- mParameters.parentControl.addDependent(oPopover);
1091
- fnOpenAndFillDialog();
1092
- })
1093
- .catch(reject);
1094
- } else {
1095
- resolve(mParameters.contexts);
1096
- }
1097
- }).then(function(contextToProcess) {
1098
- if (contextToProcess) {
1099
- return operations.callBoundAction(sActionName, contextToProcess, oModel, oAppComponent, {
1100
- invocationGrouping: mParameters.invocationGrouping,
1101
- label: mParameters.label,
1102
- showActionParameterDialog: true,
1103
- mBindingParameters: mBindingParameters,
1104
- entitySetName: mParameters.entitySetName,
1105
- additionalSideEffect: mSideEffectsParameters,
1106
- onSubmitted: function() {
1107
- messageHandler.removeTransitionMessages();
1108
- BusyLocker.lock(that.oLockObject);
1109
- },
1110
- onResponse: function() {
1111
- BusyLocker.unlock(that.oLockObject);
1112
- },
1113
- parentControl: mParameters.parentControl,
1114
- internalModelContext: mParameters.internalModelContext,
1115
- operationAvailableMap: mParameters.operationAvailableMap,
1116
- bIsCreateAction: mParameters.bIsCreateAction,
1117
- bGetBoundContext: mParameters.bGetBoundContext,
1118
- bObjectPage: mParameters.bObjectPage,
1119
- messageHandler: messageHandler,
1120
- defaultValuesExtensionFunction: mParameters.defaultValuesExtensionFunction
1121
- });
1122
- } else {
1123
- return null;
1124
- }
1125
- });
1126
- } else {
1127
- // TODO: confirm if action import needs side effects.
1128
- oPromise = operations.callActionImport(sActionName, oModel, oAppComponent, {
1129
- label: mParameters.label,
1130
- showActionParameterDialog: true,
1131
- bindingParameters: mBindingParameters,
1132
- entitySetName: mParameters.entitySetName,
1133
- onSubmitted: function() {
1134
- BusyLocker.lock(that.oLockObject);
1135
- },
1136
- onResponse: function() {
1137
- BusyLocker.unlock(that.oLockObject);
1138
- },
1139
- parentControl: mParameters.parentControl,
1140
- internalModelContext: mParameters.internalModelContext,
1141
- operationAvailableMap: mParameters.operationAvailableMap,
1142
- messageHandler: messageHandler,
1143
- bObjectPage: mParameters.bObjectPage
1144
- });
1145
- }
1146
- return oPromise
1147
- .then(function(oResult) {
1148
- // Succeeded
1149
- return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function() {
1150
- return oResult;
1151
- });
1152
- })
1153
- .catch(function(err) {
1154
- return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function() {
1155
- return Promise.reject(err);
1156
- });
1157
- });
1158
- },
1159
- /**
1160
- * Handles messages for action call.
1161
- *
1162
- * @function
1163
- * @name sap.fe.core.TransactionHelper#_handleActionResponse
1164
- * @memberof sap.fe.core.TransactionHelper
1165
- * @param messageHandler
1166
- * @param {object} mParameters Parameters to be considered for the action.
1167
- * @param {string} sActionName The name of the action to be called
1168
- * @returns {Promise} Promise after message dialog is opened if required.
1169
- * @ui5-restricted
1170
- * @final
1171
- */
1172
- _handleActionResponse: function(messageHandler, mParameters, sActionName) {
1173
- var aTransientMessages = messageHandling.getMessages(true, true);
1174
- if (aTransientMessages.length > 0 && mParameters && mParameters.internalModelContext) {
1175
- mParameters.internalModelContext.setProperty("sActionName", mParameters.label ? mParameters.label : sActionName);
1176
- }
1177
- return messageHandler.showMessages();
1178
- },
1179
- /**
1180
- * Handles validation errors for the 'discard' action.
1181
- *
1182
- * @function
1183
- * @name sap.fe.core.TransactionHelper#handleValidationError
1184
- * @memberof sap.fe.core.TransactionHelper
1185
- * @static
1186
- * @ui5-restricted
1187
- * @final
1188
- */
1189
- handleValidationError: function() {
1190
- var oMessageManager = sap.ui.getCore().getMessageManager(),
1191
- errorToRemove = oMessageManager
1192
- .getMessageModel()
1193
- .getData()
1194
- .filter(function(error) {
1195
- // only needs to handle validation messages, technical and persistent errors needs not to be checked here.
1196
- if (error.validation) {
1197
- return error;
1198
- }
1199
- });
1200
- oMessageManager.removeMessages(errorToRemove);
1201
- },
1202
- /**
1203
- * Shows a popover if it needs to be shown.
1204
- * TODO: Popover is shown if user has modified any data.
1205
- * TODO: Popover is shown if there's a difference from draft admin data.
1206
- * @static
1207
- * @name sap.fe.core.TransactionHelper._showDiscardPopover
1208
- * @memberof sap.fe.core.TransactionHelper
1209
- * @param {sap.ui.core.Control} oCancelButton The control which will open the popover
1210
- * @param bIsModified
1211
- * @param oResourceBundle
1212
- * @returns {Promise} Promise resolves if user confirms discard, rejects if otherwise, rejects if no control passed to open popover
1213
- * @ui5-restricted
1214
- * @final
1215
- */
1216
- _showDiscardPopover: function(oCancelButton, bIsModified, oResourceBundle) {
1217
- // TODO: Implement this popover as a fragment as in v2??
1218
- var that = this;
1219
- that._bContinueDiscard = false;
1220
- // to be implemented
1221
- return new Promise(function(resolve, reject) {
1222
- if (!oCancelButton) {
1223
- reject("Cancel button not found");
1224
- }
1225
- //Show popover only when data is changed.
1226
- if (bIsModified) {
1227
- var fnOnAfterDiscard = function() {
1228
- oCancelButton.setEnabled(true);
1229
- if (that._bContinueDiscard) {
1230
- resolve();
1231
- } else {
1232
- reject("Discard operation was rejected. Document has not been discarded");
1233
- }
1234
- that._oPopover.detachAfterClose(fnOnAfterDiscard);
1235
- };
1236
- if (!that._oPopover) {
1237
- var oText = new Text({
1238
- //This text is the same as LR v2.
1239
- //TODO: Display message provided by app developer???
1240
- text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_MESSAGE", oResourceBundle)
1241
- }),
1242
- oButton = new Button({
1243
- text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_BUTTON", oResourceBundle),
1244
- width: "100%",
1245
- press: function() {
1246
- that.handleValidationError();
1247
- that._bContinueDiscard = true;
1248
- that._oPopover.close();
1249
- },
1250
- ariaLabelledBy: oText
1251
- });
1252
- that._oPopover = new Popover({
1253
- showHeader: false,
1254
- placement: "Top",
1255
- content: [
1256
- new VBox({
1257
- items: [oText, oButton]
1258
- })
1259
- ],
1260
- beforeOpen: function() {
1261
- // make sure to NOT trigger multiple cancel flows
1262
- oCancelButton.setEnabled(false);
1263
- that._oPopover.setInitialFocus(oButton);
1264
- }
1265
- });
1266
- that._oPopover.addStyleClass("sapUiContentPadding");
1267
- }
1268
- that._oPopover.attachAfterClose(fnOnAfterDiscard);
1269
- that._oPopover.openBy(oCancelButton);
1270
- } else {
1271
- that.handleValidationError();
1272
- resolve();
1273
- }
1274
- });
1275
- },
1276
- /**
1277
- * Sets the document to modified state on patch event.
1278
- *
1279
- * @function
1280
- * @static
1281
- * @name sap.fe.core.TransactionHelper.handleDocumentModifications
1282
- * @memberof sap.fe.core.TransactionHelper
1283
- * @ui5-restricted
1284
- * @final
1285
- */
1286
- handleDocumentModifications: function() {
1287
- this._bIsModified = true;
1288
- },
1289
- /**
1290
- * Retrieves the owner component.
1291
- *
1292
- * @function
1293
- * @static
1294
- * @private
1295
- * @name sap.fe.core.TransactionHelper._getOwnerComponent
1296
- * @memberof sap.fe.core.TransactionHelper
1297
- * @returns {sap.fe.core.AppComponent} The app component
1298
- * @ui5-restricted
1299
- * @final
1300
- **/
1301
- _getAppComponent: function() {
1302
- return this._oAppComponent;
1303
- },
1304
- _launchDialogWithKeyFields: function(
1305
- oListBinding,
1306
- oTransientListBinding,
1307
- oTransientContext,
1308
- mFields,
1309
- oModel,
1310
- mParameters,
1311
- messageHandler
1312
- ) {
1313
- var that = this,
1314
- oDialog,
1315
- oParentControl = mParameters.parentControl,
1316
- bSuccess = false;
1317
- return new Promise(function(resolve, reject) {
1318
- var sFragmentName = "sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog";
1319
- var oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
1320
- oResourceBundle = oParentControl.getController().oResourceBundle,
1321
- oMetaModel = oModel.getMetaModel(),
1322
- aImmutableFields = [],
1323
- oAppComponent = that._getAppComponent(),
1324
- oEntitySetContext = oMetaModel.createBindingContext(oListBinding.getPath()),
1325
- sMetaPath = oMetaModel.getMetaPath(oListBinding.getPath());
1326
- for (var i in mFields) {
1327
- aImmutableFields.push(oMetaModel.createBindingContext(sMetaPath + "/" + mFields[i]));
1328
- }
1329
- var oImmutableCtx = new JSONModel(aImmutableFields);
1330
- oImmutableCtx = oImmutableCtx.createBindingContext("/");
1331
- return Promise.resolve(
1332
- XMLPreprocessor.process(
1333
- oFragment,
1334
- { name: sFragmentName },
1335
- {
1336
- bindingContexts: {
1337
- entitySet: oEntitySetContext,
1338
- fields: oImmutableCtx
1339
- },
1340
- models: {
1341
- entitySet: oEntitySetContext.getModel(),
1342
- fields: oImmutableCtx.getModel(),
1343
- metaModel: oMetaModel
1344
- }
1345
- }
1346
- )
1347
- ).then(function(oFragment) {
1348
- var aFormElements = [],
1349
- mFieldValueMap = {},
1350
- oCreateButton,
1351
- validateRequiredProperties = function() {
1352
- return Promise.all(
1353
- aFormElements
1354
- .map(function(oFormElement) {
1355
- return oFormElement.getFields()[0];
1356
- })
1357
- .filter(function(oField) {
1358
- return oField.getRequired();
1359
- })
1360
- .map(function(oField) {
1361
- var sFieldId = oField.getId();
1362
- if (sFieldId in mFieldValueMap) {
1363
- return Promise.resolve(mFieldValueMap[sFieldId])
1364
- .then(function(vValue) {
1365
- return vValue;
1366
- })
1367
- .catch(function() {
1368
- return undefined;
1369
- });
1370
- }
1371
- return oField.getValueState() === ValueState.Error ? undefined : oField.getValue();
1372
- })
1373
- )
1374
- .then(function(aResults) {
1375
- return aResults.every(function(vValue) {
1376
- return vValue !== undefined && vValue !== null && vValue !== "";
1377
- });
1378
- })
1379
- .catch(function() {
1380
- return false;
1381
- })
1382
- .then(function(bEnabled) {
1383
- oCreateButton.setEnabled(bEnabled);
1384
- });
1385
- },
1386
- oController = {
1387
- /*
1388
- fired on focus out from field or on selecting a value from the valuehelp.
1389
- the create button is enabled when a value is added.
1390
- liveChange is not fired when value is added from valuehelp.
1391
- value validation is not done for create button enablement.
1392
- */
1393
- handleChange: function(oEvent) {
1394
- messageHandler.removeTransitionMessages();
1395
- var oField = oEvent.getSource();
1396
- var sFieldId = oEvent.getParameter("id");
1397
- var oFieldPromise = oEvent.getParameter("promise");
1398
- if (oFieldPromise) {
1399
- mFieldValueMap[sFieldId] = oFieldPromise.then(function() {
1400
- return oField.getValue();
1401
- });
1402
- }
1403
- validateRequiredProperties();
1404
- },
1405
- /*
1406
- fired on key press. the create button is enabled when a value is added.
1407
- liveChange is not fired when value is added from valuehelp.
1408
- value validation is not done for create button enablement.
1409
- */
1410
- handleLiveChange: function(oEvent) {
1411
- var sFieldId = oEvent.getParameter("id");
1412
- var vValue = oEvent.getParameter("value");
1413
- mFieldValueMap[sFieldId] = vValue;
1414
- validateRequiredProperties();
1415
- }
1416
- };
1417
- return Fragment.load({
1418
- definition: oFragment,
1419
- controller: oController
1420
- }).then(function(oDialogContent) {
1421
- oDialog = new Dialog({
1422
- title: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE", oResourceBundle),
1423
- content: [oDialogContent],
1424
- beginButton: {
1425
- text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE_BUTTON", oResourceBundle),
1426
- type: "Emphasized",
1427
- press: function(oEvent) {
1428
- var oCreateButton = oEvent.getSource();
1429
- oCreateButton.setEnabled(false);
1430
- BusyLocker.lock(oDialog);
1431
- return Promise.all(
1432
- Object.keys(mFieldValueMap).map(function(sKey) {
1433
- return mFieldValueMap[sKey];
1434
- })
1435
- )
1436
- .then(function() {
1437
- var oPromise = that.onAfterCreateCompletion(
1438
- oTransientListBinding,
1439
- oTransientContext,
1440
- mParameters,
1441
- oResourceBundle
1442
- );
1443
- oModel.submitBatch("submitLater");
1444
- return oPromise;
1445
- })
1446
- .then(function(oResponse) {
1447
- oDialog.setBindingContext(null);
1448
- oDialog.close();
1449
- resolve(oResponse);
1450
- })
1451
- .finally(function() {
1452
- BusyLocker.unlock(oDialog);
1453
- oCreateButton.setEnabled(true);
1454
- return messageHandler.showMessages();
1455
- });
1456
- }
1457
- },
1458
- endButton: {
1459
- text: CommonUtils.getTranslatedText("C_COMMON_ACTION_PARAMETER_DIALOG_CANCEL", oResourceBundle),
1460
- press: function() {
1461
- oDialog.close();
1462
- }
1463
- },
1464
- afterClose: function() {
1465
- // show footer as per UX guidelines when dialog is not open
1466
- oDialog.getBindingContext("internal").setProperty("isCreateDialogOpen", false);
1467
- oDialog.destroy();
1468
- if (!bSuccess) {
1469
- reject({
1470
- bDeleteTransientContext: true
1471
- });
1472
- }
1473
- }
1474
- });
1475
- aFormElements = oDialogContent
1476
- .getAggregation("form")
1477
- .getAggregation("formContainers")[0]
1478
- .getAggregation("formElements");
1479
- if (oParentControl && oParentControl.addDependent) {
1480
- // if there is a parent control specified add the dialog as dependent
1481
- oParentControl.addDependent(oDialog);
1482
- }
1483
- oCreateButton = oDialog.getBeginButton();
1484
- oDialog.setBindingContext(oTransientContext);
1485
- return CommonUtils.setUserDefaults(
1486
- oAppComponent,
1487
- aImmutableFields,
1488
- oTransientContext,
1489
- undefined,
1490
- mParameters.createAction,
1491
- mParameters.data
1492
- )
1493
- .then(function() {
1494
- validateRequiredProperties();
1495
- // footer must not be visible when the dialog is open as per UX guidelines
1496
- oDialog.getBindingContext("internal").setProperty("isCreateDialogOpen", true);
1497
- oDialog.open();
1498
- })
1499
- .catch(function(oError) {
1500
- return messageHandler.showMessages().then(function() {
1501
- return Promise.reject(oError);
1502
- });
1503
- });
1504
- });
1505
- });
1506
- });
1507
- },
1508
- onAfterCreateCompletion: function(oListBinding, oNewDocumentContext, mParameters, oResourceBundle) {
1509
- var fnResolve,
1510
- fnReject,
1511
- oPromise = new Promise(function(resolve, reject) {
1512
- fnResolve = resolve;
1513
- fnReject = reject;
1514
- });
1515
- // Workaround suggested by OData model v4 colleagues
1516
- var fnCreateCompleted = function(oEvent) {
1517
- var oContext = oEvent.getParameter("context"),
1518
- bSuccess = oEvent.getParameter("success");
1519
- if (oContext === oNewDocumentContext) {
1520
- oListBinding.detachCreateCompleted(fnCreateCompleted, this);
1521
- if (!bSuccess) {
1522
- var oError = { bDeleteTransientContext: false };
1523
- if (!mParameters.keepTransientContextOnFailed) {
1524
- // the context is deleted
1525
- oError.bDeleteTransientContext = true;
1526
- // this is needed to avoid console errors TO be checked with model colleagues
1527
- oContext
1528
- .created()
1529
- .then(undefined, function() {
1530
- Log.trace("transient creation context deleted");
1531
- })
1532
- .catch(function(oError) {
1533
- Log.trace("transient creation context deletion error", oError);
1534
- });
1535
- // if current state is transient (...), browser will come back to previous state
1536
- oError.navigateBackFromTransientState = true;
1537
- }
1538
- fnReject(oError);
1539
- } else {
1540
- fnResolve();
1541
- }
1542
- }
1543
- };
1544
- oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1545
- return oPromise;
1546
- },
1547
- /**
1548
- * Retrieves the name of the NewAction to be executed.
1549
- *
1550
- * @function
1551
- * @static
1552
- * @private
1553
- * @name sap.fe.core.TransactionHelper._getNewAction
1554
- * @memberof sap.fe.core.TransactionHelper
1555
- * @param {object} oStartupParameters Startup parameters of the application
1556
- * @param {string} sCreateHash Hash to be checked for action type
1557
- * @param {object} oMetaModel The MetaModel used to check for NewAction parameter
1558
- * @param {string} sMetaPath The MetaPath
1559
- * @returns {string} The name of the action
1560
- * @ui5-restricted
1561
- * @final
1562
- **/
1563
- _getNewAction: function(oStartupParameters, sCreateHash, oMetaModel, sMetaPath) {
1564
- var sNewAction;
1565
-
1566
- if (oStartupParameters && oStartupParameters.preferredMode && sCreateHash.indexOf("i-action=createWith") > -1) {
1567
- var sPreferredMode = oStartupParameters.preferredMode[0];
1568
- sNewAction =
1569
- sPreferredMode.indexOf("createWith:") > -1 ? sPreferredMode.substr(sPreferredMode.lastIndexOf(":") + 1) : undefined;
1570
- } else {
1571
- sNewAction =
1572
- oMetaModel && oMetaModel.getObject !== undefined
1573
- ? oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction") ||
1574
- oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction")
1575
- : undefined;
1576
- }
1577
- return sNewAction;
1578
- }
1579
- });
1580
- }
1581
- );
5
+ sap.ui.define(["sap/fe/core/actions/draft", "sap/fe/core/actions/sticky", "sap/fe/core/actions/operations", "sap/ui/model/json/JSONModel", "sap/m/Popover", "sap/m/VBox", "sap/m/CheckBox", "sap/m/Text", "sap/m/Button", "sap/m/MessageToast", "sap/m/Dialog", "sap/base/Log", "sap/fe/core/CommonUtils", "sap/fe/core/BusyLocker", "sap/ui/core/util/XMLPreprocessor", "sap/ui/core/XMLTemplateProcessor", "sap/ui/core/Fragment", "sap/m/MessageBox", "sap/fe/core/helpers/ModelHelper", "sap/fe/core/library", "sap/ui/core/library", "sap/fe/core/actions/messageHandling", "sap/fe/core/helpers/FPMHelper"], function (draft, sticky, operations, JSONModel, Popover, VBox, CheckBox, Text, Button, MessageToast, Dialog, Log, CommonUtils, BusyLocker, XMLPreprocessor, XMLTemplateProcessor, Fragment, MessageBox, ModelHelper, FELibrary, coreLibrary, messageHandling, FPMHelper) {
6
+ "use strict";
7
+
8
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9
+
10
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
11
+
12
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
13
+
14
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
15
+
16
+ var CreationMode = FELibrary.CreationMode;
17
+ var ProgrammingModel = FELibrary.ProgrammingModel;
18
+ var ValueState = coreLibrary.ValueState;
19
+ /* Make sure that the mParameters is not the oEvent */
20
+
21
+ function getParameters(mParameters) {
22
+ if (mParameters && mParameters.getMetadata && mParameters.getMetadata().getName() === "sap.ui.base.Event") {
23
+ mParameters = {};
24
+ }
25
+
26
+ return mParameters || {};
27
+ }
28
+
29
+ var TransactionHelper = /*#__PURE__*/function () {
30
+ function TransactionHelper(oAppComponent, oLockObject) {
31
+ _classCallCheck(this, TransactionHelper);
32
+
33
+ _defineProperty(this, "_bIsModified", false);
34
+
35
+ _defineProperty(this, "_bCreateMode", false);
36
+
37
+ _defineProperty(this, "_bContinueDiscard", false);
38
+
39
+ this._oAppComponent = oAppComponent;
40
+ this.oLockObject = oLockObject;
41
+ }
42
+
43
+ _createClass(TransactionHelper, [{
44
+ key: "getProgrammingModel",
45
+ value: function getProgrammingModel(oContext) {
46
+ if (!this.sProgrammingModel && oContext) {
47
+ var sPath;
48
+
49
+ if (oContext.isA("sap.ui.model.odata.v4.Context")) {
50
+ sPath = oContext.getPath();
51
+ } else {
52
+ sPath = oContext.isRelative() ? oContext.getResolvedPath() : oContext.getPath();
53
+ }
54
+
55
+ if (ModelHelper.isDraftSupported(oContext.getModel().getMetaModel(), sPath)) {
56
+ this.sProgrammingModel = ProgrammingModel.Draft;
57
+ } else if (ModelHelper.isStickySessionSupported(oContext.getModel().getMetaModel())) {
58
+ this.sProgrammingModel = ProgrammingModel.Sticky;
59
+ } else {
60
+ // as the transaction helper is a singleton we don't store the non draft as the user could
61
+ // start with a non draft child page and navigates back to a draft enabled one
62
+ return ProgrammingModel.NonDraft;
63
+ }
64
+ }
65
+
66
+ return this.sProgrammingModel;
67
+ }
68
+ /**
69
+ * Validates a document.
70
+ *
71
+ * @memberof sap.fe.core.TransactionHelper
72
+ * @static
73
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be validated
74
+ * @param {object} [mParameters] Can contain the following attributes:
75
+ * * @param {object} [mParameters.data] A map of data that should be validated
76
+ * * @param {string} [mParameters.customValidationFunction] A string representing the path to the validation function
77
+ * @param {object} oView Contains the object of the current view
78
+ * @returns {Promise} Promise resolves with result of the custom validation function
79
+ * @ui5-restricted
80
+ * @final
81
+ */
82
+
83
+ }, {
84
+ key: "validateDocument",
85
+ value: function validateDocument(oContext, mParameters, oView) {
86
+ var sCustomValidationFunction = mParameters && mParameters.customValidationFunction;
87
+
88
+ if (sCustomValidationFunction) {
89
+ var sModule = sCustomValidationFunction.substring(0, sCustomValidationFunction.lastIndexOf(".") || -1).replace(/\./gi, "/"),
90
+ sFunctionName = sCustomValidationFunction.substring(sCustomValidationFunction.lastIndexOf(".") + 1, sCustomValidationFunction.length),
91
+ mData = mParameters.data;
92
+ delete mData["@$ui5.context.isTransient"];
93
+ return FPMHelper.validationWrapper(sModule, sFunctionName, mData, oView, oContext);
94
+ }
95
+
96
+ return Promise.resolve([]);
97
+ }
98
+ /**
99
+ * Creates a new document.
100
+ *
101
+ * @memberof sap.fe.core.TransactionHelper
102
+ * @static
103
+ * @param {sap.ui.model.odata.v4.ODataListBinding} oMainListBinding OData V4 ListBinding object
104
+ * @param {object} [mInParameters] Optional, can contain the following attributes:
105
+ * @param {map} [mInParameters.data] A map of data that should be sent within the POST
106
+ * @param {string} [mInParameters.busyMode] Global (default), Local, None TODO: to be refactored
107
+ * @param {map} [mInParameters.keepTransientContextOnFailed] If set, the context stays in the list if the POST failed and POST will be repeated with the next change
108
+ * @param oResourceBundle
109
+ * @param messageHandler
110
+ * @param bFromCopyPaste
111
+ * @param oView The current view
112
+ * @returns {Promise} Promise resolves with new binding context
113
+ * @ui5-restricted
114
+ * @final
115
+ */
116
+
117
+ }, {
118
+ key: "createDocument",
119
+ value: function createDocument(oMainListBinding, mInParameters, oResourceBundle, messageHandler, bFromCopyPaste, oView) {
120
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
121
+ var that = this,
122
+ oModel = oMainListBinding.getModel(),
123
+ oMetaModel = oModel.getMetaModel(),
124
+ sMetaPath = oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()),
125
+ sCreateHash = this._getAppComponent().getRouterProxy().getHash(),
126
+ oComponentData = this._getAppComponent().getComponentData(),
127
+ oStartupParameters = oComponentData && oComponentData.startupParameters || {},
128
+ sNewAction = !oMainListBinding.isRelative() ? this._getNewAction(oStartupParameters, sCreateHash, oMetaModel, sMetaPath) : undefined;
129
+
130
+ var oCreationPromise;
131
+ var mBindingParameters = {
132
+ "$$patchWithoutSideEffects": true
133
+ };
134
+ var sMessagesPath = oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
135
+ var sBusyPath = "/busy";
136
+ var sFunctionName = oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") || oMetaModel.getObject(ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction");
137
+ var bFunctionOnNavProp;
138
+ var oNewDocumentContext;
139
+
140
+ if (sFunctionName) {
141
+ if (oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") && ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) !== sMetaPath) {
142
+ bFunctionOnNavProp = true;
143
+ } else {
144
+ bFunctionOnNavProp = false;
145
+ }
146
+ }
147
+
148
+ if (sMessagesPath) {
149
+ mBindingParameters["$select"] = sMessagesPath;
150
+ }
151
+
152
+ var mParameters = getParameters(mInParameters);
153
+
154
+ if (!oMainListBinding) {
155
+ return Promise.reject("Binding required for new document creation");
156
+ }
157
+
158
+ var sProgrammingModel = this.getProgrammingModel(oMainListBinding);
159
+
160
+ if (sProgrammingModel !== ProgrammingModel.Draft && sProgrammingModel !== ProgrammingModel.Sticky) {
161
+ return Promise.reject("Create document only allowed for draft or sticky session supported services");
162
+ }
163
+
164
+ if (mParameters.busyMode === "Local") {
165
+ // in case of local busy mode we use the list binding name
166
+ // there's no APY yet so we have to use the .sId TODO provide a public method?
167
+ sBusyPath = "/busyLocal/" + oMainListBinding.sId;
168
+ }
169
+
170
+ mParameters.beforeCreateCallBack = bFromCopyPaste ? null : mParameters.beforeCreateCallBack;
171
+ BusyLocker.lock(this.oLockObject, sBusyPath);
172
+ var oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
173
+
174
+ if (sNewAction) {
175
+ oCreationPromise = this.callAction(sNewAction, {
176
+ contexts: oMainListBinding.getHeaderContext(),
177
+ showActionParameterDialog: true,
178
+ label: this._getSpecificCreateActionDialogLabel(oMetaModel, sMetaPath, sNewAction, oResourceBundleCore),
179
+ bindingParameters: mBindingParameters,
180
+ parentControl: mParameters.parentControl,
181
+ bIsCreateAction: true
182
+ }, null, messageHandler);
183
+ } else {
184
+ var bIsNewPageCreation = mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
185
+ var aNonComputedVisibleKeyFields = bIsNewPageCreation ? CommonUtils.getNonComputedVisibleFields(oMetaModel, sMetaPath, oView) : [];
186
+ sFunctionName = bFromCopyPaste ? null : sFunctionName;
187
+ var sFunctionPath, oFunctionContext;
188
+
189
+ if (sFunctionName) {
190
+ //bound to the source entity:
191
+ if (bFunctionOnNavProp) {
192
+ sFunctionPath = oMainListBinding.getContext() && oMetaModel.getMetaPath(oMainListBinding.getContext().getPath()) + "/" + sFunctionName;
193
+ oFunctionContext = oMainListBinding.getContext();
194
+ } else {
195
+ sFunctionPath = oMainListBinding.getHeaderContext() && oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()) + "/" + sFunctionName;
196
+ oFunctionContext = oMainListBinding.getHeaderContext();
197
+ }
198
+ }
199
+
200
+ var oFunction = sFunctionPath && oMetaModel.createBindingContext(sFunctionPath);
201
+
202
+ if (oFunction && oFunction.getObject() && oFunction.getObject()[0].$IsBound) {
203
+ oCreationPromise = operations.callBoundFunction(sFunctionName, oFunctionContext, oModel);
204
+ } else {
205
+ oCreationPromise = operations.callFunctionImport(sFunctionName, oModel);
206
+ }
207
+
208
+ oCreationPromise = oCreationPromise.then(function (oContext) {
209
+ if (oContext) {
210
+ return oContext.getObject();
211
+ } else {
212
+ return undefined;
213
+ }
214
+ }).catch(function (oError) {
215
+ Log.error("Error while executing the function " + sFunctionName, oError);
216
+ throw oError;
217
+ }).then(function (oData) {
218
+ mParameters.data = oData ? Object.assign({}, oData, mParameters.data) : mParameters.data;
219
+
220
+ if (mParameters.data) {
221
+ delete mParameters.data["@odata.context"];
222
+ }
223
+
224
+ if (aNonComputedVisibleKeyFields.length > 0) {
225
+ var oTransientListBinding = oModel.bindList(oMainListBinding.getPath(), oMainListBinding.getContext(), [], [], {
226
+ $$updateGroupId: "submitLater"
227
+ });
228
+
229
+ oTransientListBinding.refreshInternal = function () {
230
+ /* */
231
+ };
232
+
233
+ oNewDocumentContext = oTransientListBinding.create(mParameters.data, true);
234
+ return that._launchDialogWithKeyFields(oMainListBinding, oTransientListBinding, oNewDocumentContext, aNonComputedVisibleKeyFields, oModel, mParameters, messageHandler);
235
+ } else {
236
+ var onBeforeCreatePromise;
237
+
238
+ if (mParameters.beforeCreateCallBack) {
239
+ onBeforeCreatePromise = mParameters.beforeCreateCallBack({
240
+ contextPath: oMainListBinding && oMainListBinding.getPath()
241
+ });
242
+ } else {
243
+ onBeforeCreatePromise = Promise.resolve();
244
+ }
245
+
246
+ return onBeforeCreatePromise.then(function () {
247
+ oNewDocumentContext = oMainListBinding.create(mParameters.data, true, mParameters.createAtEnd);
248
+ return that.onAfterCreateCompletion(oMainListBinding, oNewDocumentContext, mParameters);
249
+ });
250
+ }
251
+ }).catch(function (oError) {
252
+ Log.error("Error while creating the new document", oError);
253
+ throw oError;
254
+ });
255
+ }
256
+
257
+ return oCreationPromise.then(function (oResult) {
258
+ if (!oMainListBinding.isRelative()) {
259
+ // the create mode shall currently only be set on creating a root document
260
+ that._bCreateMode = true;
261
+ }
262
+
263
+ oNewDocumentContext = oNewDocumentContext || oResult && oResult.response; // TODO: where does this one coming from???
264
+
265
+ if (oResult && oResult.bConsiderDocumentModified) {
266
+ that.handleDocumentModifications();
267
+ }
268
+
269
+ return messageHandler.showMessageDialog().then(function () {
270
+ return oNewDocumentContext;
271
+ });
272
+ }).catch(function (oError) {
273
+ return messageHandler.showMessageDialog().then(function () {
274
+ // for instance, on cancel of create dialog, the promise is rejected
275
+ // a return here would restore the promise chain and result in errors while routing
276
+ // solution - reject here as well
277
+ if (oError && oError.bDeleteTransientContext && oNewDocumentContext.isTransient()) {
278
+ // This is a workaround suggested by model as Context.delete results in an error
279
+ // TODO: remove the $direct once model resolves this issue
280
+ // this line shows the expected console error Uncaught (in promise) Error: Request canceled: POST Travel; group: submitLater
281
+ oNewDocumentContext.delete("$direct");
282
+ }
283
+
284
+ return Promise.reject(oError);
285
+ });
286
+ }).finally(function () {
287
+ BusyLocker.unlock(that.oLockObject, sBusyPath);
288
+ });
289
+ }
290
+ /**
291
+ * Find the active contexts of the documents, only for the draft roots.
292
+ *
293
+ * @memberof sap.fe.core.TransactionHelper
294
+ * @static
295
+ * @param {sap.ui.model.odata.v4.Context[]} aContexts Contexts Either one context or an array with contexts to be deleted
296
+ * @param bFindActiveContexts
297
+ * @returns {Array} Array of the active contexts
298
+ */
299
+
300
+ }, {
301
+ key: "findActiveDraftRootContexts",
302
+ value: function findActiveDraftRootContexts(aContexts, bFindActiveContexts) {
303
+ if (!bFindActiveContexts) {
304
+ return Promise.resolve();
305
+ }
306
+
307
+ var activeContexts = aContexts.reduce(function (aResult, oContext) {
308
+ var oMetaModel = oContext.getModel().getMetaModel();
309
+ var sMetaPath = oMetaModel.getMetaPath(oContext.getPath());
310
+
311
+ if (oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot")) {
312
+ var bIsActiveEntity = oContext.getObject().IsActiveEntity,
313
+ bHasActiveEntity = oContext.getObject().HasActiveEntity;
314
+
315
+ if (!bIsActiveEntity && bHasActiveEntity) {
316
+ var oActiveContext = oContext.getModel().bindContext(oContext.getPath() + "/SiblingEntity").getBoundContext();
317
+ aResult.push(oActiveContext);
318
+ }
319
+ }
320
+
321
+ return aResult;
322
+ }, []);
323
+ return Promise.all(activeContexts.map(function (oContext) {
324
+ return oContext.requestCanonicalPath().then(function () {
325
+ return oContext;
326
+ }, function () {
327
+ return;
328
+ });
329
+ }));
330
+ }
331
+ }, {
332
+ key: "afterDeleteProcess",
333
+ value: function afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle) {
334
+ var oInternalModelContext = mParameters.internalModelContext;
335
+
336
+ if (oInternalModelContext && oInternalModelContext.getProperty("deleteEnabled") != undefined) {
337
+ if (checkBox.isCheckBoxVisible === true && checkBox.isCheckBoxSelected === false) {
338
+ //if unsaved objects are not deleted then we need to set the enabled to true and update the model data for next deletion
339
+ oInternalModelContext.setProperty("deleteEnabled", true);
340
+ var obj = Object.assign(oInternalModelContext.getObject(), {});
341
+ obj.selectedContexts = obj.selectedContexts.filter(function (element) {
342
+ return obj.deletableContexts.indexOf(element) === -1;
343
+ });
344
+ obj.deletableContexts = [];
345
+ obj.selectedContexts = [];
346
+ obj.numberOfSelectedContexts = obj.selectedContexts.length;
347
+ oInternalModelContext.setProperty("", obj);
348
+ } else {
349
+ oInternalModelContext.setProperty("deleteEnabled", false);
350
+ oInternalModelContext.setProperty("selectedContexts", []);
351
+ oInternalModelContext.setProperty("numberOfSelectedContexts", 0);
352
+ }
353
+ }
354
+
355
+ if (aContexts.length === 1) {
356
+ MessageToast.show(CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_SINGULAR", oResourceBundle, null, mParameters.entitySetName));
357
+ } else {
358
+ MessageToast.show(CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_PLURAL", oResourceBundle, null, mParameters.entitySetName));
359
+ }
360
+ }
361
+ /**
362
+ * Delete one or multiple document(s).
363
+ *
364
+ * @memberof sap.fe.core.TransactionHelper
365
+ * @static
366
+ * @param {sap.ui.model.odata.v4.Context} vContexts Contexts Either one context or an array with contexts to be deleted
367
+ * @param {object} mParameters Optional, can contain the following attributes:
368
+ * @param {string} mParameters.title Title of the object to be deleted
369
+ * @param {string} mParameters.description Description of the object to be deleted
370
+ * @param {integer} mParameters.numberOfSelectedContexts Number of objects selected
371
+ * @param {boolean} mParameters.noDialog To disable the confirmation dialog
372
+ * @param oResourceBundle
373
+ * @param messageHandler
374
+ * @returns {Promise}
375
+ */
376
+
377
+ }, {
378
+ key: "deleteDocument",
379
+ value: function deleteDocument(vContexts, mParameters, oResourceBundle, messageHandler) {
380
+ var fnReject,
381
+ fnResolve,
382
+ aDeletableContexts = [],
383
+ isCheckBoxVisible = false,
384
+ isLockedTextVisible = false,
385
+ cannotBeDeletedTextVisible = false,
386
+ isCheckBoxSelected,
387
+ bDialogConfirmed = false; // eslint-disable-next-line @typescript-eslint/no-this-alias
388
+
389
+ var that = this,
390
+ oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
391
+ var aParams;
392
+ var oDeleteMessage = {
393
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
394
+ };
395
+ BusyLocker.lock(this.oLockObject);
396
+
397
+ if (!Array.isArray(vContexts)) {
398
+ vContexts = [vContexts];
399
+ }
400
+
401
+ Promise.resolve(this.getProgrammingModel(vContexts[0])).then(function (sProgrammingModel) {
402
+ if (mParameters) {
403
+ if (!mParameters.numberOfSelectedContexts) {
404
+ if (sProgrammingModel === ProgrammingModel.Draft) {
405
+ for (var i = 0; i < vContexts.length; i++) {
406
+ var oContextData = vContexts[i].getObject();
407
+
408
+ if (oContextData.IsActiveEntity === true && oContextData.HasDraftEntity === true && oContextData.DraftAdministrativeData && oContextData.DraftAdministrativeData.InProcessByUser && !oContextData.DraftAdministrativeData.DraftIsCreatedByMe) {
409
+ MessageBox.show(CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_SINGLE_OBJECT_LOCKED", oResourceBundle), {
410
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
411
+ onClose: fnReject
412
+ });
413
+ return;
414
+ }
415
+ }
416
+ }
417
+
418
+ mParameters = getParameters(mParameters);
419
+
420
+ if (mParameters.title) {
421
+ aParams = [mParameters.title, mParameters.description];
422
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO", oResourceBundle, aParams, mParameters.entitySetName);
423
+ } else {
424
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR", oResourceBundle);
425
+ }
426
+
427
+ aDeletableContexts = vContexts;
428
+ } else {
429
+ oDeleteMessage = {
430
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
431
+ };
432
+
433
+ if (mParameters.numberOfSelectedContexts === 1 && mParameters.numberOfSelectedContexts === vContexts.length) {
434
+ aDeletableContexts = vContexts;
435
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR", oResourceBundle, null, mParameters.entitySetName);
436
+ } else if (mParameters.numberOfSelectedContexts === 1 && mParameters.unSavedContexts.length === 1) {
437
+ //only one unsaved object
438
+ aDeletableContexts = mParameters.unSavedContexts;
439
+ var draftAdminData = aDeletableContexts[0].getObject()["DraftAdministrativeData"];
440
+ var sLastChangedByUser = "";
441
+
442
+ if (draftAdminData) {
443
+ sLastChangedByUser = draftAdminData["LastChangedByUserDescription"] || draftAdminData["LastChangedByUser"] || "";
444
+ }
445
+
446
+ aParams = [sLastChangedByUser];
447
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES", oResourceBundle, aParams);
448
+ } else if (mParameters.numberOfSelectedContexts === mParameters.unSavedContexts.length) {
449
+ //only multiple unsaved objects
450
+ aDeletableContexts = mParameters.unSavedContexts;
451
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES_MULTIPLE_OBJECTS", oResourceBundle);
452
+ } else if (mParameters.numberOfSelectedContexts === vContexts.concat(mParameters.unSavedContexts.concat(mParameters.lockedContexts)).length) {
453
+ //only unsaved, locked ,deletable objects but not non-deletable objects
454
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
455
+ oDeleteMessage.text = aDeletableContexts.length === 1 ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR", oResourceBundle, null, mParameters.entitySetName) : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL", oResourceBundle, null, mParameters.entitySetName);
456
+ } else {
457
+ //if non-deletable objects exists along with any of unsaved ,deletable objects
458
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
459
+ cannotBeDeletedTextVisible = true;
460
+ oDeleteMessage.text = aDeletableContexts.length === 1 ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR_NON_DELETABLE", oResourceBundle, null, mParameters.entitySetName) : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL_NON_DELETABLE", oResourceBundle, null, mParameters.entitySetName);
461
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_NON_DELETABLE", oResourceBundle, [mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length, mParameters.numberOfSelectedContexts]);
462
+ }
463
+
464
+ if (mParameters.lockedContexts.length == 1) {
465
+ //setting the locked text if locked objects exist
466
+ isLockedTextVisible = true;
467
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED", oResourceBundle, [mParameters.numberOfSelectedContexts]);
468
+ }
469
+
470
+ if (mParameters.lockedContexts.length > 1) {
471
+ //setting the locked text if locked objects exist
472
+ isLockedTextVisible = true;
473
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED", oResourceBundle, [mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]);
474
+ }
475
+
476
+ if (mParameters.unSavedContexts.length > 0 && mParameters.unSavedContexts.length !== mParameters.numberOfSelectedContexts) {
477
+ if ((cannotBeDeletedTextVisible || isLockedTextVisible) && aDeletableContexts.length === mParameters.unSavedContexts.length) {
478
+ //if only unsaved and either or both of locked and non-deletable objects exist then we hide the check box
479
+ isCheckBoxVisible = false;
480
+ aDeletableContexts = mParameters.unSavedContexts;
481
+
482
+ if (mParameters.unSavedContexts.length === 1) {
483
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_SINGULAR", oResourceBundle);
484
+ } else {
485
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_PLURAL", oResourceBundle);
486
+ }
487
+ } else {
488
+ if (mParameters.unSavedContexts.length === 1) {
489
+ oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_SINGULAR", oResourceBundle);
490
+ } else {
491
+ oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_PLURAL", oResourceBundle);
492
+ }
493
+
494
+ isCheckBoxVisible = true;
495
+ }
496
+ }
497
+
498
+ if (cannotBeDeletedTextVisible && isLockedTextVisible) {
499
+ //if both locked and non-deletable objects exist along with deletable objects
500
+ if (mParameters.unSavedContexts.length > 1) {
501
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED_AND_NON_DELETABLE", oResourceBundle, [mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length - mParameters.lockedContexts.length, mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]);
502
+ }
503
+
504
+ if (mParameters.unSavedContexts.length == 1) {
505
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED_AND_NON_DELETABLE", oResourceBundle, [mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length - mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]);
506
+ }
507
+ }
508
+ }
509
+ }
510
+
511
+ var oNonDeletableMessageTextControl, oDeleteMessageTextControl;
512
+ var oContent = new VBox({
513
+ items: [oNonDeletableMessageTextControl = new Text({
514
+ text: oDeleteMessage.nonDeletableText,
515
+ visible: isLockedTextVisible || cannotBeDeletedTextVisible
516
+ }), oDeleteMessageTextControl = new Text({
517
+ text: oDeleteMessage.text
518
+ }), new CheckBox({
519
+ text: oDeleteMessage.checkBoxText,
520
+ selected: true,
521
+ select: function (oEvent) {
522
+ var selected = oEvent.getSource().getSelected();
523
+
524
+ if (selected) {
525
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
526
+ isCheckBoxSelected = true;
527
+ } else {
528
+ aDeletableContexts = vContexts;
529
+ isCheckBoxSelected = false;
530
+ }
531
+ },
532
+ visible: isCheckBoxVisible
533
+ })]
534
+ });
535
+ var sTitle = oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE");
536
+
537
+ var fnConfirm = function () {
538
+ bDialogConfirmed = true;
539
+ BusyLocker.lock(that.oLockObject);
540
+ var aContexts = aDeletableContexts;
541
+ var onBeforeDeletePromise;
542
+
543
+ if (mParameters.beforeDeleteCallBack) {
544
+ onBeforeDeletePromise = mParameters.beforeDeleteCallBack({
545
+ contexts: aContexts
546
+ });
547
+ } else {
548
+ onBeforeDeletePromise = Promise.resolve();
549
+ }
550
+
551
+ return onBeforeDeletePromise.then(that.findActiveDraftRootContexts.bind(that, aContexts, mParameters.bFindActiveContexts)).then(function (activeContexts) {
552
+ //make sure to fetch the active contexts before deleting the drafts
553
+ return Promise.all(aContexts.map(function (oContext) {
554
+ //delete the draft
555
+ return draft.deleteDraft(oContext);
556
+ })).catch(function (oError) {
557
+ return messageHandler.showMessages().then(function () {
558
+ // re-throw error to enforce rejecting the general promise
559
+ throw oError;
560
+ });
561
+ }).then(function () {
562
+ var checkBox = {
563
+ "isCheckBoxVisible": isCheckBoxVisible,
564
+ "isCheckBoxSelected": isCheckBoxSelected
565
+ };
566
+
567
+ if (activeContexts && activeContexts.length) {
568
+ return Promise.all(activeContexts.map(function (oContext) {
569
+ return oContext.delete();
570
+ })).then(function () {
571
+ that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
572
+ return messageHandler.showMessageDialog().then(fnResolve);
573
+ });
574
+ } else {
575
+ that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
576
+ return messageHandler.showMessageDialog().then(fnResolve);
577
+ }
578
+ });
579
+ }).catch(function () {
580
+ fnReject();
581
+ }).finally(function () {
582
+ BusyLocker.unlock(that.oLockObject);
583
+ });
584
+ };
585
+
586
+ var oDialog = new Dialog({
587
+ title: sTitle,
588
+ state: "Warning",
589
+ content: [oContent],
590
+ ariaLabelledBy: oNonDeletableMessageTextControl.getVisible() ? [oNonDeletableMessageTextControl, oDeleteMessageTextControl] : oDeleteMessageTextControl,
591
+ beginButton: new Button({
592
+ text: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
593
+ type: "Emphasized",
594
+ press: function () {
595
+ oDialog.close();
596
+ return fnConfirm();
597
+ }
598
+ }),
599
+ endButton: new Button({
600
+ text: CommonUtils.getTranslatedText("C_COMMON_OBJECT_PAGE_CANCEL", oResourceBundle),
601
+ press: function () {
602
+ oDialog.close();
603
+ }
604
+ }),
605
+ afterClose: function () {
606
+ oDialog.destroy(); // if dialog is closed unconfirmed (e.g. via "Cancel" or Escape button), ensure to reject promise
607
+
608
+ if (!bDialogConfirmed) {
609
+ fnReject();
610
+ }
611
+ }
612
+ });
613
+
614
+ if (mParameters.noDialog) {
615
+ return fnConfirm();
616
+ } else {
617
+ oDialog.addStyleClass("sapUiContentPadding");
618
+ oDialog.open();
619
+ }
620
+ }).finally(function () {
621
+ BusyLocker.unlock(that.oLockObject);
622
+ }).catch(function () {
623
+ Log.warning("Couldn't get Programming model");
624
+ fnReject();
625
+ });
626
+ return new Promise(function (resolve, reject) {
627
+ fnReject = reject;
628
+ fnResolve = resolve;
629
+ });
630
+ }
631
+ /**
632
+ * Edits a document.
633
+ *
634
+ * @memberof sap.fe.core.TransactionHelper
635
+ * @static
636
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the active document
637
+ * @param {boolean} bPrepareOnEdit Also call the 'prepare' action for draft-based documents
638
+ * @param {object} oView Object of current view
639
+ * @param messageHandler
640
+ * @returns {Promise} Promise resolves with the new draft context in case of draft programming model
641
+ * @ui5-restricted
642
+ * @final
643
+ */
644
+
645
+ }, {
646
+ key: "editDocument",
647
+ value: function editDocument(oContext, bPrepareOnEdit, oView, messageHandler) {
648
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
649
+ var that = this;
650
+ var sProgrammingModel = this.getProgrammingModel(oContext);
651
+ var oEditPromise;
652
+
653
+ if (!oContext) {
654
+ return Promise.reject(new Error("Binding context to active document is required"));
655
+ }
656
+
657
+ this._bIsModified = false;
658
+ BusyLocker.lock(that.oLockObject); // before triggering the edit action we'll have to remove all bound transition messages
659
+
660
+ messageHandler.removeTransitionMessages();
661
+
662
+ if (sProgrammingModel === ProgrammingModel.Draft) {
663
+ oEditPromise = draft.createDraftFromActiveDocument(oContext, this._getAppComponent(), {
664
+ bPreserveChanges: true,
665
+ bPrepareOnEdit: bPrepareOnEdit,
666
+ oView: oView
667
+ });
668
+ } else if (sProgrammingModel === ProgrammingModel.Sticky) {
669
+ oEditPromise = sticky.editDocumentInStickySession(oContext);
670
+ } else {
671
+ BusyLocker.unlock(that.oLockObject);
672
+ return Promise.reject(new Error("Edit is only allowed for draft or sticky session supported services"));
673
+ }
674
+
675
+ return oEditPromise.then(function (oNewContext) {
676
+ that._bCreateMode = false;
677
+ return messageHandler.showMessageDialog().then(function () {
678
+ return oNewContext;
679
+ });
680
+ }).catch(function (err) {
681
+ return messageHandler.showMessages().then(function () {
682
+ return Promise.reject(err);
683
+ });
684
+ }).finally(function () {
685
+ BusyLocker.unlock(that.oLockObject);
686
+ });
687
+ }
688
+ /**
689
+ * Cancel 'edit' mode of a document.
690
+ *
691
+ * @memberof sap.fe.core.TransactionHelper
692
+ * @static
693
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be canceled or deleted
694
+ * @param {object} [mInParameters] Optional, can contain the following attributes:
695
+ * @param {sap.m.Button} mInParameters.cancelButton Cancel Button of the discard popover (mandatory for now)
696
+ * @param {boolean} mInParameters.skipDiscardPopover Optional, supresses the discard popover incase of draft applications while navigating out of OP
697
+ * @param oResourceBundle
698
+ * @param messageHandler
699
+ * @returns {Promise} Promise resolves with ???
700
+ * @ui5-restricted
701
+ * @final
702
+ */
703
+
704
+ }, {
705
+ key: "cancelDocument",
706
+ value: function cancelDocument(oContext, mInParameters, oResourceBundle, messageHandler) {
707
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
708
+ var that = this;
709
+ var sProgrammingModel; //context must always be passed - mandatory parameter
710
+
711
+ if (!oContext) {
712
+ return Promise.reject("No context exists. Pass a meaningful context");
713
+ }
714
+
715
+ BusyLocker.lock(that.oLockObject);
716
+ var mParameters = getParameters(mInParameters);
717
+ var oParamsContext = oContext,
718
+ oCancelButton = mParameters.cancelButton,
719
+ oModel = oParamsContext.getModel();
720
+ var onBeforeCancelPromise, sCanonicalPath;
721
+ return Promise.resolve(this.getProgrammingModel(oContext)).then(function (sPModel) {
722
+ sProgrammingModel = sPModel;
723
+
724
+ if (sPModel === ProgrammingModel.Draft) {
725
+ var draftDataContext = oModel.bindContext(oParamsContext.getPath() + "/DraftAdministrativeData").getBoundContext();
726
+
727
+ if (!that._bIsModified) {
728
+ return draftDataContext.requestObject().then(function (draftAdminData) {
729
+ if (draftAdminData) {
730
+ that._bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
731
+ }
732
+ });
733
+ }
734
+ }
735
+ }).then(function () {
736
+ if (!mParameters.skipDiscardPopover) {
737
+ return that._showDiscardPopover(oCancelButton, that._bIsModified, oResourceBundle);
738
+ } else {
739
+ return Promise.resolve();
740
+ }
741
+ }).then(function () {
742
+ if (mParameters.beforeCancelCallBack) {
743
+ onBeforeCancelPromise = mParameters.beforeCancelCallBack({
744
+ context: oContext
745
+ });
746
+ } else {
747
+ onBeforeCancelPromise = Promise.resolve();
748
+ }
749
+
750
+ return onBeforeCancelPromise;
751
+ }).then(function () {
752
+ // eslint-disable-next-line default-case
753
+ switch (sProgrammingModel) {
754
+ case ProgrammingModel.Draft:
755
+ return oParamsContext.requestObject("HasActiveEntity").then(function (bHasActiveEntity) {
756
+ var oDeletePromise;
757
+
758
+ if (!bHasActiveEntity) {
759
+ if (oParamsContext && oParamsContext.hasPendingChanges()) {
760
+ oParamsContext.getBinding().resetChanges();
761
+ }
762
+
763
+ oDeletePromise = draft.deleteDraft(oParamsContext);
764
+ return oDeletePromise;
765
+ } else {
766
+ var oActiveContext = oModel.bindContext(oParamsContext.getPath() + "/SiblingEntity").getBoundContext();
767
+ return oActiveContext.requestCanonicalPath().then(function (sPath) {
768
+ sCanonicalPath = sPath;
769
+
770
+ if (oParamsContext && oParamsContext.hasPendingChanges()) {
771
+ oParamsContext.getBinding().resetChanges();
772
+ }
773
+
774
+ oDeletePromise = draft.deleteDraft(oParamsContext);
775
+ return oDeletePromise;
776
+ }, function () {
777
+ draft.deleteDraft(oParamsContext);
778
+ return;
779
+ }).then(function () {
780
+ //oParamsContext.delete() in the previous promise doesnt return anything upon success.
781
+ if (!sCanonicalPath) {
782
+ return;
783
+ }
784
+
785
+ if (oActiveContext.getPath() !== sCanonicalPath) {
786
+ // the active context is using the sibling entity - this path is not accessible anymore as we deleted the draft
787
+ // document - therefore we need to create a new context with the canonical path
788
+ oActiveContext = oModel.bindContext(sCanonicalPath).getBoundContext();
789
+ }
790
+
791
+ return oActiveContext;
792
+ });
793
+ }
794
+ });
795
+
796
+ case ProgrammingModel.Sticky:
797
+ return sticky.discardDocument(oContext).then(function (oContext) {
798
+ if (oContext) {
799
+ if (oContext.hasPendingChanges()) {
800
+ oContext.getBinding().resetChanges();
801
+ }
802
+
803
+ if (!that._bCreateMode) {
804
+ oContext.refresh();
805
+ return oContext;
806
+ }
807
+ }
808
+
809
+ return false;
810
+ });
811
+
812
+ default:
813
+ return Promise.reject("Cancel document only allowed for draft or sticky session supported services");
814
+ }
815
+ }).then(function (context) {
816
+ that._bIsModified = false; // remove existing bound transition messages
817
+
818
+ messageHandler.removeTransitionMessages(); // show unbound messages
819
+
820
+ return messageHandler.showMessages().then(function () {
821
+ return context;
822
+ });
823
+ }).catch(function (err) {
824
+ return messageHandler.showMessages().then(function () {
825
+ return Promise.reject(err);
826
+ });
827
+ }).finally(function () {
828
+ BusyLocker.unlock(that.oLockObject);
829
+ });
830
+ }
831
+ /**
832
+ * Saves the document.
833
+ *
834
+ * @memberof sap.fe.core.TransactionHelper
835
+ * @static
836
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be saved
837
+ * @param oResourceBundle
838
+ * @param bExecuteSideEffectsOnError
839
+ * @param aBindings
840
+ * @param messageHandler
841
+ * @returns {Promise} Promise resolves with ???
842
+ * @ui5-restricted
843
+ * @final
844
+ */
845
+
846
+ }, {
847
+ key: "saveDocument",
848
+ value: function saveDocument(oContext, oResourceBundle, bExecuteSideEffectsOnError, aBindings, messageHandler) {
849
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
850
+ var that = this;
851
+ var sProgrammingModel = this.getProgrammingModel(oContext);
852
+ var oSavePromise;
853
+
854
+ if (!oContext) {
855
+ return Promise.reject(new Error("Binding context to draft document is required"));
856
+ } // in case of saving / activating the bound transition messages shall be removed before the PATCH/POST
857
+ // is sent to the backend
858
+
859
+
860
+ messageHandler.removeTransitionMessages();
861
+ BusyLocker.lock(that.oLockObject);
862
+
863
+ if (sProgrammingModel === ProgrammingModel.Draft) {
864
+ oSavePromise = draft.activateDocument(oContext, this._getAppComponent(), {});
865
+ } else if (sProgrammingModel === ProgrammingModel.Sticky) {
866
+ oSavePromise = sticky.activateDocument(oContext);
867
+ } else {
868
+ BusyLocker.unlock(that.oLockObject);
869
+ return Promise.reject(new Error("Save is only allowed for draft or sticky session supported services"));
870
+ }
871
+
872
+ return oSavePromise.then(function (oActiveDocument) {
873
+ var bNewObject = that.sProgrammingModel === ProgrammingModel.Sticky ? that._bCreateMode : !oContext.getObject().HasActiveEntity;
874
+ MessageToast.show(bNewObject ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_CREATED", oResourceBundle) : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_SAVED", oResourceBundle));
875
+ that._bIsModified = false;
876
+ return messageHandler.showMessageDialog().then(function () {
877
+ return oActiveDocument;
878
+ });
879
+ }).catch(function (err) {
880
+ if (aBindings && aBindings.length > 0) {
881
+ /* The sideEffects are executed only for table items in transient state */
882
+ aBindings.forEach(function (oListBinding) {
883
+ if (!CommonUtils.hasTransientContext(oListBinding) && bExecuteSideEffectsOnError) {
884
+ var oAppComponent = that._getAppComponent();
885
+
886
+ oAppComponent.getSideEffectsService().requestSideEffectsForNavigationProperty(oListBinding.getPath(), oContext);
887
+ }
888
+ });
889
+ }
890
+
891
+ return messageHandler.showMessages().then(function () {
892
+ return Promise.reject(err);
893
+ });
894
+ }).finally(function () {
895
+ BusyLocker.unlock(that.oLockObject);
896
+ });
897
+ }
898
+ /**
899
+ * Calls a bound or unbound action.
900
+ *
901
+ * @function
902
+ * @static
903
+ * @name sap.fe.core.TransactionHelper.callAction
904
+ * @memberof sap.fe.core.TransactionHelper
905
+ * @param {string} sActionName The name of the action to be called
906
+ * @param {map} [mParameters] Contains the following attributes:
907
+ * @param {sap.ui.model.odata.v4.Context} [mParameters.contexts] Mandatory for a bound action: Either one context or an array with contexts for which the action is to be called
908
+ * @param {sap.ui.model.odata.v4.ODataModel} [mParameters.model] Mandatory for an unbound action: An instance of an OData V4 model
909
+ * @param {string} [mParameters.invocationGrouping] Mode how actions are to be called: 'ChangeSet' to put all action calls into one changeset, 'Isolated' to put them into separate changesets
910
+ * @param {string} [mParameters.label] A human-readable label for the action
911
+ * @param {boolean} [mParameters.bGetBoundContext] If specified, the action promise returns the bound context
912
+ * @param {object} oView Contains the object of the current view
913
+ * @param messageHandler
914
+ * @returns {Promise} Promise resolves with an array of response objects (TODO: to be changed)
915
+ * @ui5-restricted
916
+ * @final
917
+ **/
918
+
919
+ }, {
920
+ key: "callAction",
921
+ value: function callAction(sActionName, mParameters, oView, messageHandler) {
922
+ mParameters = getParameters(mParameters); // eslint-disable-next-line @typescript-eslint/no-this-alias
923
+
924
+ var that = this;
925
+ var oContext, oModel, oPromise;
926
+ var mBindingParameters = mParameters.bindingParameters;
927
+
928
+ if (!sActionName) {
929
+ return Promise.reject("Provide name of action to be executed");
930
+ } // action imports are not directly obtained from the metaModel by it is present inside the entityContainer
931
+ // and the acions it refers to present outside the entitycontainer, hence to obtain kind of the action
932
+ // split() on its name was required
933
+
934
+
935
+ var sName = sActionName.split("/")[1];
936
+ sActionName = sName || sActionName;
937
+ oContext = sName ? undefined : mParameters.contexts; //checking whether the context is an array with more than 0 length or not an array(create action)
938
+
939
+ if (oContext && (Array.isArray(oContext) && oContext.length || !Array.isArray(oContext))) {
940
+ oContext = Array.isArray(oContext) ? oContext[0] : oContext;
941
+ oModel = oContext.getModel();
942
+ }
943
+
944
+ if (mParameters.model) {
945
+ oModel = mParameters.model;
946
+ }
947
+
948
+ if (!oModel) {
949
+ return Promise.reject("Pass a context for a bound action or pass the model for an unbound action");
950
+ } // get the binding parameters $select and $expand for the side effect on this action
951
+ // also gather additional property paths to be requested such as text associations
952
+
953
+
954
+ var oAppComponent = that._getAppComponent();
955
+
956
+ var mSideEffectsParameters = oAppComponent.getSideEffectsService().getODataActionSideEffects(sActionName, oContext) || {};
957
+
958
+ if (oContext && oModel) {
959
+ oPromise = new Promise(function (resolve, reject) {
960
+ var oApplicableContextDialog;
961
+ var oController = {
962
+ onClose: function () {
963
+ // User cancels action
964
+ oApplicableContextDialog.close();
965
+ resolve();
966
+ },
967
+ onContinue: function () {
968
+ // Users continues the action with the bound contexts
969
+ oApplicableContextDialog.close();
970
+ resolve(mParameters.applicableContext);
971
+ }
972
+ };
973
+
974
+ var fnOpenAndFillDialog = function () {
975
+ var oDialogContent;
976
+ var nNotApplicable = mParameters.notApplicableContext.length,
977
+ aNotApplicableItems = [];
978
+
979
+ for (var i = 0; i < mParameters.notApplicableContext.length; i++) {
980
+ oDialogContent = mParameters.notApplicableContext[i].getObject();
981
+ aNotApplicableItems.push(oDialogContent);
982
+ }
983
+
984
+ var oNotApplicableItemsModel = new JSONModel(aNotApplicableItems);
985
+ var oTotals = new JSONModel({
986
+ total: nNotApplicable,
987
+ label: mParameters.label
988
+ });
989
+ oApplicableContextDialog.setModel(oNotApplicableItemsModel, "notApplicable");
990
+ oApplicableContextDialog.setModel(oTotals, "totals");
991
+ oApplicableContextDialog.open();
992
+ };
993
+
994
+ if (mParameters.notApplicableContext && mParameters.notApplicableContext.length >= 1) {
995
+ // Show the contexts that are not applicable and will not therefore be processed
996
+ var sFragmentName = "sap.fe.core.controls.ActionPartial";
997
+ var oDialogFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
998
+ var oMetaModel = oModel.getMetaModel();
999
+ var sCanonicalPath = mParameters.contexts[0].getCanonicalPath();
1000
+ var sEntitySet = sCanonicalPath.substr(0, sCanonicalPath.indexOf("(")) + "/";
1001
+ var oDialogLabelModel = new JSONModel({
1002
+ title: mParameters.label
1003
+ });
1004
+ Promise.resolve(XMLPreprocessor.process(oDialogFragment, {
1005
+ name: sFragmentName
1006
+ }, {
1007
+ bindingContexts: {
1008
+ entityType: oMetaModel.createBindingContext(sEntitySet),
1009
+ label: oDialogLabelModel.createBindingContext("/")
1010
+ },
1011
+ models: {
1012
+ entityType: oMetaModel,
1013
+ metaModel: oMetaModel,
1014
+ label: oDialogLabelModel
1015
+ }
1016
+ })).then(function (oFragment) {
1017
+ return Fragment.load({
1018
+ definition: oFragment,
1019
+ controller: oController
1020
+ });
1021
+ }).then(function (oPopover) {
1022
+ oApplicableContextDialog = oPopover;
1023
+ mParameters.parentControl.addDependent(oPopover);
1024
+ fnOpenAndFillDialog();
1025
+ }).catch(reject);
1026
+ } else {
1027
+ resolve(mParameters.contexts);
1028
+ }
1029
+ }).then(function (contextToProcess) {
1030
+ if (contextToProcess) {
1031
+ return operations.callBoundAction(sActionName, contextToProcess, oModel, oAppComponent, {
1032
+ invocationGrouping: mParameters.invocationGrouping,
1033
+ label: mParameters.label,
1034
+ showActionParameterDialog: true,
1035
+ mBindingParameters: mBindingParameters,
1036
+ entitySetName: mParameters.entitySetName,
1037
+ additionalSideEffect: mSideEffectsParameters,
1038
+ onSubmitted: function () {
1039
+ messageHandler.removeTransitionMessages();
1040
+ BusyLocker.lock(that.oLockObject);
1041
+ },
1042
+ onResponse: function () {
1043
+ BusyLocker.unlock(that.oLockObject);
1044
+ },
1045
+ parentControl: mParameters.parentControl,
1046
+ internalModelContext: mParameters.internalModelContext,
1047
+ operationAvailableMap: mParameters.operationAvailableMap,
1048
+ bIsCreateAction: mParameters.bIsCreateAction,
1049
+ bGetBoundContext: mParameters.bGetBoundContext,
1050
+ bObjectPage: mParameters.bObjectPage,
1051
+ messageHandler: messageHandler,
1052
+ defaultValuesExtensionFunction: mParameters.defaultValuesExtensionFunction
1053
+ });
1054
+ } else {
1055
+ return null;
1056
+ }
1057
+ });
1058
+ } else {
1059
+ // TODO: confirm if action import needs side effects.
1060
+ oPromise = operations.callActionImport(sActionName, oModel, oAppComponent, {
1061
+ label: mParameters.label,
1062
+ showActionParameterDialog: true,
1063
+ bindingParameters: mBindingParameters,
1064
+ entitySetName: mParameters.entitySetName,
1065
+ onSubmitted: function () {
1066
+ BusyLocker.lock(that.oLockObject);
1067
+ },
1068
+ onResponse: function () {
1069
+ BusyLocker.unlock(that.oLockObject);
1070
+ },
1071
+ parentControl: mParameters.parentControl,
1072
+ internalModelContext: mParameters.internalModelContext,
1073
+ operationAvailableMap: mParameters.operationAvailableMap,
1074
+ messageHandler: messageHandler,
1075
+ bObjectPage: mParameters.bObjectPage
1076
+ });
1077
+ }
1078
+
1079
+ return oPromise.then(function (oResult) {
1080
+ // Succeeded
1081
+ return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function () {
1082
+ return oResult;
1083
+ });
1084
+ }).catch(function (err) {
1085
+ return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function () {
1086
+ return Promise.reject(err);
1087
+ });
1088
+ });
1089
+ }
1090
+ /**
1091
+ * Handles messages for action call.
1092
+ *
1093
+ * @function
1094
+ * @name sap.fe.core.TransactionHelper#_handleActionResponse
1095
+ * @memberof sap.fe.core.TransactionHelper
1096
+ * @param messageHandler
1097
+ * @param {object} mParameters Parameters to be considered for the action.
1098
+ * @param {string} sActionName The name of the action to be called
1099
+ * @returns {Promise} Promise after message dialog is opened if required.
1100
+ * @ui5-restricted
1101
+ * @final
1102
+ */
1103
+
1104
+ }, {
1105
+ key: "_handleActionResponse",
1106
+ value: function _handleActionResponse(messageHandler, mParameters, sActionName) {
1107
+ var aTransientMessages = messageHandling.getMessages(true, true);
1108
+
1109
+ if (aTransientMessages.length > 0 && mParameters && mParameters.internalModelContext) {
1110
+ mParameters.internalModelContext.setProperty("sActionName", mParameters.label ? mParameters.label : sActionName);
1111
+ }
1112
+
1113
+ return messageHandler.showMessages();
1114
+ }
1115
+ /**
1116
+ * Handles validation errors for the 'discard' action.
1117
+ *
1118
+ * @function
1119
+ * @name sap.fe.core.TransactionHelper#handleValidationError
1120
+ * @memberof sap.fe.core.TransactionHelper
1121
+ * @static
1122
+ * @ui5-restricted
1123
+ * @final
1124
+ */
1125
+
1126
+ }, {
1127
+ key: "handleValidationError",
1128
+ value: function handleValidationError() {
1129
+ var oMessageManager = sap.ui.getCore().getMessageManager(),
1130
+ errorToRemove = oMessageManager.getMessageModel().getData().filter(function (error) {
1131
+ // only needs to handle validation messages, technical and persistent errors needs not to be checked here.
1132
+ if (error.validation) {
1133
+ return error;
1134
+ }
1135
+ });
1136
+ oMessageManager.removeMessages(errorToRemove);
1137
+ }
1138
+ /**
1139
+ * Shows a popover if it needs to be shown.
1140
+ * TODO: Popover is shown if user has modified any data.
1141
+ * TODO: Popover is shown if there's a difference from draft admin data.
1142
+ * @static
1143
+ * @name sap.fe.core.TransactionHelper._showDiscardPopover
1144
+ * @memberof sap.fe.core.TransactionHelper
1145
+ * @param {sap.ui.core.Control} oCancelButton The control which will open the popover
1146
+ * @param bIsModified
1147
+ * @param oResourceBundle
1148
+ * @returns {Promise} Promise resolves if user confirms discard, rejects if otherwise, rejects if no control passed to open popover
1149
+ * @ui5-restricted
1150
+ * @final
1151
+ */
1152
+
1153
+ }, {
1154
+ key: "_showDiscardPopover",
1155
+ value: function _showDiscardPopover(oCancelButton, bIsModified, oResourceBundle) {
1156
+ // TODO: Implement this popover as a fragment as in v2??
1157
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1158
+ var that = this;
1159
+ that._bContinueDiscard = false; // to be implemented
1160
+
1161
+ return new Promise(function (resolve, reject) {
1162
+ if (!oCancelButton) {
1163
+ reject("Cancel button not found");
1164
+ } //Show popover only when data is changed.
1165
+
1166
+
1167
+ if (bIsModified) {
1168
+ var fnOnAfterDiscard = function () {
1169
+ oCancelButton.setEnabled(true);
1170
+
1171
+ if (that._bContinueDiscard) {
1172
+ resolve();
1173
+ } else {
1174
+ reject("Discard operation was rejected. Document has not been discarded");
1175
+ }
1176
+
1177
+ that._oPopover.detachAfterClose(fnOnAfterDiscard);
1178
+ };
1179
+
1180
+ if (!that._oPopover) {
1181
+ var oText = new Text({
1182
+ //This text is the same as LR v2.
1183
+ //TODO: Display message provided by app developer???
1184
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_MESSAGE", oResourceBundle)
1185
+ }),
1186
+ oButton = new Button({
1187
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_BUTTON", oResourceBundle),
1188
+ width: "100%",
1189
+ press: function () {
1190
+ that.handleValidationError();
1191
+ that._bContinueDiscard = true;
1192
+
1193
+ that._oPopover.close();
1194
+ },
1195
+ ariaLabelledBy: oText
1196
+ });
1197
+ that._oPopover = new Popover({
1198
+ showHeader: false,
1199
+ placement: "Top",
1200
+ content: [new VBox({
1201
+ items: [oText, oButton]
1202
+ })],
1203
+ beforeOpen: function () {
1204
+ // make sure to NOT trigger multiple cancel flows
1205
+ oCancelButton.setEnabled(false);
1206
+
1207
+ that._oPopover.setInitialFocus(oButton);
1208
+ }
1209
+ });
1210
+
1211
+ that._oPopover.addStyleClass("sapUiContentPadding");
1212
+ }
1213
+
1214
+ that._oPopover.attachAfterClose(fnOnAfterDiscard);
1215
+
1216
+ that._oPopover.openBy(oCancelButton, false);
1217
+ } else {
1218
+ that.handleValidationError();
1219
+ resolve();
1220
+ }
1221
+ });
1222
+ }
1223
+ /**
1224
+ * Sets the document to modified state on patch event.
1225
+ *
1226
+ * @function
1227
+ * @static
1228
+ * @name sap.fe.core.TransactionHelper.handleDocumentModifications
1229
+ * @memberof sap.fe.core.TransactionHelper
1230
+ * @ui5-restricted
1231
+ * @final
1232
+ */
1233
+
1234
+ }, {
1235
+ key: "handleDocumentModifications",
1236
+ value: function handleDocumentModifications() {
1237
+ this._bIsModified = true;
1238
+ }
1239
+ /**
1240
+ * Retrieves the owner component.
1241
+ *
1242
+ * @function
1243
+ * @static
1244
+ * @private
1245
+ * @name sap.fe.core.TransactionHelper._getOwnerComponent
1246
+ * @memberof sap.fe.core.TransactionHelper
1247
+ * @returns {sap.fe.core.AppComponent} The app component
1248
+ * @ui5-restricted
1249
+ * @final
1250
+ **/
1251
+
1252
+ }, {
1253
+ key: "_getAppComponent",
1254
+ value: function _getAppComponent() {
1255
+ return this._oAppComponent;
1256
+ }
1257
+ }, {
1258
+ key: "_launchDialogWithKeyFields",
1259
+ value: function _launchDialogWithKeyFields(oListBinding, oTransientListBinding, oTransientContext, mFields, oModel, mParameters, messageHandler) {
1260
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1261
+ var that = this;
1262
+ var oDialog;
1263
+ var oParentControl = mParameters.parentControl,
1264
+ bSuccess = false;
1265
+ return new Promise(function (resolve, reject) {
1266
+ var sFragmentName = "sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog";
1267
+
1268
+ var oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
1269
+ oResourceBundle = oParentControl.getController().oResourceBundle,
1270
+ oMetaModel = oModel.getMetaModel(),
1271
+ aImmutableFields = [],
1272
+ oAppComponent = that._getAppComponent(),
1273
+ sPath = oListBinding.isRelative() ? oListBinding.getResolvedPath() : oListBinding.getPath(),
1274
+ oEntitySetContext = oMetaModel.createBindingContext(sPath),
1275
+ sMetaPath = oMetaModel.getMetaPath(sPath);
1276
+
1277
+ for (var i in mFields) {
1278
+ aImmutableFields.push(oMetaModel.createBindingContext(sMetaPath + "/" + mFields[i]));
1279
+ }
1280
+
1281
+ var oImmutableCtxModel = new JSONModel(aImmutableFields);
1282
+ var oImmutableCtx = oImmutableCtxModel.createBindingContext("/");
1283
+ return Promise.resolve(XMLPreprocessor.process(oFragment, {
1284
+ name: sFragmentName
1285
+ }, {
1286
+ bindingContexts: {
1287
+ entitySet: oEntitySetContext,
1288
+ fields: oImmutableCtx
1289
+ },
1290
+ models: {
1291
+ entitySet: oEntitySetContext.getModel(),
1292
+ fields: oImmutableCtx.getModel(),
1293
+ metaModel: oMetaModel
1294
+ }
1295
+ })).then(function (oFragment) {
1296
+ var aFormElements = [];
1297
+ var mFieldValueMap = {};
1298
+ var oCreateButton;
1299
+
1300
+ var validateRequiredProperties = function () {
1301
+ return Promise.all(aFormElements.map(function (oFormElement) {
1302
+ return oFormElement.getFields()[0];
1303
+ }).filter(function (oField) {
1304
+ return oField.getRequired();
1305
+ }).map(function (oField) {
1306
+ var sFieldId = oField.getId();
1307
+
1308
+ if (sFieldId in mFieldValueMap) {
1309
+ return Promise.resolve(mFieldValueMap[sFieldId]).then(function (vValue) {
1310
+ return vValue;
1311
+ }).catch(function () {
1312
+ return undefined;
1313
+ });
1314
+ }
1315
+
1316
+ return oField.getValueState() === ValueState.Error ? undefined : oField.getValue();
1317
+ })).then(function (aResults) {
1318
+ return aResults.every(function (vValue) {
1319
+ return vValue !== undefined && vValue !== null && vValue !== "";
1320
+ });
1321
+ }).catch(function () {
1322
+ return false;
1323
+ }).then(function (bEnabled) {
1324
+ oCreateButton.setEnabled(bEnabled);
1325
+ });
1326
+ };
1327
+
1328
+ var oController = {
1329
+ /*
1330
+ fired on focus out from field or on selecting a value from the valuehelp.
1331
+ the create button is enabled when a value is added.
1332
+ liveChange is not fired when value is added from valuehelp.
1333
+ value validation is not done for create button enablement.
1334
+ */
1335
+ handleChange: function (oEvent) {
1336
+ messageHandler.removeTransitionMessages();
1337
+ var oField = oEvent.getSource();
1338
+ var sFieldId = oEvent.getParameter("id");
1339
+ var oFieldPromise = oEvent.getParameter("promise");
1340
+
1341
+ if (oFieldPromise) {
1342
+ mFieldValueMap[sFieldId] = oFieldPromise.then(function () {
1343
+ return oField.getValue();
1344
+ });
1345
+ }
1346
+
1347
+ validateRequiredProperties();
1348
+ },
1349
+
1350
+ /*
1351
+ fired on key press. the create button is enabled when a value is added.
1352
+ liveChange is not fired when value is added from valuehelp.
1353
+ value validation is not done for create button enablement.
1354
+ */
1355
+ handleLiveChange: function (oEvent) {
1356
+ var sFieldId = oEvent.getParameter("id");
1357
+ var vValue = oEvent.getParameter("value");
1358
+ mFieldValueMap[sFieldId] = vValue;
1359
+ validateRequiredProperties();
1360
+ }
1361
+ };
1362
+ return Fragment.load({
1363
+ definition: oFragment,
1364
+ controller: oController
1365
+ }).then(function (oDialogContent) {
1366
+ oDialog = new Dialog({
1367
+ title: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE", oResourceBundle),
1368
+ content: [oDialogContent],
1369
+ beginButton: {
1370
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE_BUTTON", oResourceBundle),
1371
+ type: "Emphasized",
1372
+ press: function (oEvent) {
1373
+ var oCreateButton = oEvent.getSource();
1374
+ oCreateButton.setEnabled(false);
1375
+ BusyLocker.lock(oDialog);
1376
+ return Promise.all(Object.keys(mFieldValueMap).map(function (sKey) {
1377
+ return mFieldValueMap[sKey].then(function (oValue) {
1378
+ var oDialogValue = {};
1379
+ oDialogValue[sKey] = oValue;
1380
+ return oDialogValue;
1381
+ });
1382
+ })).then(function (aValues) {
1383
+ var onBeforeCreatePromise;
1384
+
1385
+ if (mParameters.beforeCreateCallBack) {
1386
+ onBeforeCreatePromise = mParameters.beforeCreateCallBack({
1387
+ contextPath: oListBinding && oListBinding.getPath(),
1388
+ createParameters: aValues
1389
+ });
1390
+ } else {
1391
+ onBeforeCreatePromise = Promise.resolve();
1392
+ }
1393
+
1394
+ return onBeforeCreatePromise;
1395
+ }).then(function () {
1396
+ var oPromise = that.onAfterCreateCompletion(oTransientListBinding, oTransientContext, mParameters);
1397
+ oModel.submitBatch("submitLater");
1398
+ return oPromise;
1399
+ }).then(function (oResponse) {
1400
+ oDialog.setBindingContext(null);
1401
+ oDialog.close();
1402
+ resolve(oResponse);
1403
+ }).catch(function (oError) {
1404
+ reject(oError);
1405
+ }).finally(function () {
1406
+ BusyLocker.unlock(oDialog);
1407
+ oCreateButton.setEnabled(true);
1408
+ return messageHandler.showMessages();
1409
+ });
1410
+ }
1411
+ },
1412
+ endButton: {
1413
+ text: CommonUtils.getTranslatedText("C_COMMON_ACTION_PARAMETER_DIALOG_CANCEL", oResourceBundle),
1414
+ press: function () {
1415
+ oDialog.close();
1416
+ }
1417
+ },
1418
+ afterClose: function () {
1419
+ var _oDialog$getBindingCo;
1420
+
1421
+ // show footer as per UX guidelines when dialog is not open
1422
+ (_oDialog$getBindingCo = oDialog.getBindingContext("internal")) === null || _oDialog$getBindingCo === void 0 ? void 0 : _oDialog$getBindingCo.setProperty("isCreateDialogOpen", false);
1423
+ oDialog.destroy();
1424
+
1425
+ if (!bSuccess) {
1426
+ reject({
1427
+ bDeleteTransientContext: true
1428
+ });
1429
+ }
1430
+ }
1431
+ });
1432
+ aFormElements = oDialogContent.getAggregation("form").getAggregation("formContainers")[0].getAggregation("formElements");
1433
+
1434
+ if (oParentControl && oParentControl.addDependent) {
1435
+ // if there is a parent control specified add the dialog as dependent
1436
+ oParentControl.addDependent(oDialog);
1437
+ }
1438
+
1439
+ oCreateButton = oDialog.getBeginButton();
1440
+ oDialog.setBindingContext(oTransientContext);
1441
+ return CommonUtils.setUserDefaults(oAppComponent, aImmutableFields, oTransientContext, false, mParameters.createAction, mParameters.data).then(function () {
1442
+ validateRequiredProperties(); // footer must not be visible when the dialog is open as per UX guidelines
1443
+
1444
+ oDialog.getBindingContext("internal").setProperty("isCreateDialogOpen", true);
1445
+ oDialog.open();
1446
+ }).catch(function (oError) {
1447
+ return messageHandler.showMessages().then(function () {
1448
+ return Promise.reject(oError);
1449
+ });
1450
+ });
1451
+ });
1452
+ });
1453
+ });
1454
+ }
1455
+ }, {
1456
+ key: "onAfterCreateCompletion",
1457
+ value: function onAfterCreateCompletion(oListBinding, oNewDocumentContext, mParameters) {
1458
+ var fnResolve, fnReject;
1459
+ var oPromise = new Promise(function (resolve, reject) {
1460
+ fnResolve = resolve;
1461
+ fnReject = reject;
1462
+ }); // eslint-disable-next-line @typescript-eslint/no-this-alias
1463
+
1464
+ var that = this; // Workaround suggested by OData model v4 colleagues
1465
+
1466
+ var fnCreateCompleted = function (oEvent) {
1467
+ var oContext = oEvent.getParameter("context"),
1468
+ bSuccess = oEvent.getParameter("success");
1469
+
1470
+ if (oContext === oNewDocumentContext) {
1471
+ oListBinding.detachCreateCompleted(fnCreateCompleted, that);
1472
+
1473
+ if (!bSuccess) {
1474
+ var oError = {
1475
+ bDeleteTransientContext: false
1476
+ };
1477
+
1478
+ if (!mParameters.keepTransientContextOnFailed) {
1479
+ // the context is deleted
1480
+ oError.bDeleteTransientContext = true; // this is needed to avoid console errors TO be checked with model colleagues
1481
+
1482
+ oContext.created().then(undefined, function () {
1483
+ Log.trace("transient creation context deleted");
1484
+ }).catch(function (oError) {
1485
+ Log.trace("transient creation context deletion error", oError);
1486
+ }); // if current state is transient (...), browser will come back to previous state
1487
+
1488
+ oError.navigateBackFromTransientState = true;
1489
+ }
1490
+
1491
+ fnReject(oError);
1492
+ } else {
1493
+ fnResolve();
1494
+ }
1495
+ }
1496
+ };
1497
+
1498
+ oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1499
+ return oPromise;
1500
+ }
1501
+ /**
1502
+ * Retrieves the name of the NewAction to be executed.
1503
+ *
1504
+ * @function
1505
+ * @static
1506
+ * @private
1507
+ * @name sap.fe.core.TransactionHelper._getNewAction
1508
+ * @memberof sap.fe.core.TransactionHelper
1509
+ * @param {object} oStartupParameters Startup parameters of the application
1510
+ * @param {string} sCreateHash Hash to be checked for action type
1511
+ * @param {object} oMetaModel The MetaModel used to check for NewAction parameter
1512
+ * @param {string} sMetaPath The MetaPath
1513
+ * @returns {string} The name of the action
1514
+ * @ui5-restricted
1515
+ * @final
1516
+ **/
1517
+
1518
+ }, {
1519
+ key: "_getNewAction",
1520
+ value: function _getNewAction(oStartupParameters, sCreateHash, oMetaModel, sMetaPath) {
1521
+ var sNewAction;
1522
+
1523
+ if (oStartupParameters && oStartupParameters.preferredMode && sCreateHash.indexOf("i-action=createWith") > -1) {
1524
+ var sPreferredMode = oStartupParameters.preferredMode[0];
1525
+ sNewAction = sPreferredMode.indexOf("createWith:") > -1 ? sPreferredMode.substr(sPreferredMode.lastIndexOf(":") + 1) : undefined;
1526
+ } else {
1527
+ sNewAction = oMetaModel && oMetaModel.getObject !== undefined ? oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction") || oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction") : undefined;
1528
+ }
1529
+
1530
+ return sNewAction;
1531
+ }
1532
+ /**
1533
+ * Retrieves the label for the title of a specific create action dialog, e.g. Create Sales Order from Quotation.
1534
+ *
1535
+ * The following priority is applied:
1536
+ * 1. label of line-item annotation.
1537
+ * 2. label annotated in the action.
1538
+ * 3. "Create" as a constant from i18n.
1539
+ *
1540
+ * @function
1541
+ * @static
1542
+ * @private
1543
+ * @name sap.fe.core.TransactionHelper._getSpecificCreateActionDialogLabel
1544
+ * @memberof sap.fe.core.TransactionHelper
1545
+ * @param {object} oMetaModel The MetaModel used to check for the NewAction parameter
1546
+ * @param {string} sMetaPath The MetaPath
1547
+ * @param {string} sNewAction Contains the name of the action to be executed
1548
+ * @param {object} oResourceBundleCore ResourceBundle to access the default Create label
1549
+ * @returns {string} The label for the Create Action Dialog
1550
+ * @ui5-restricted
1551
+ * @final
1552
+ **/
1553
+
1554
+ }, {
1555
+ key: "_getSpecificCreateActionDialogLabel",
1556
+ value: function _getSpecificCreateActionDialogLabel(oMetaModel, sMetaPath, sNewAction, oResourceBundleCore) {
1557
+ var fnGetLabelFromLineItemAnnotation = function () {
1558
+ if (oMetaModel && oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")) {
1559
+ var iLineItemIndex = oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem").findIndex(function (oLineItem) {
1560
+ var aLineItemAction = oLineItem.Action ? oLineItem.Action.split("(") : undefined;
1561
+ return aLineItemAction ? aLineItemAction[0] === sNewAction : false;
1562
+ });
1563
+ return iLineItemIndex > -1 ? oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")[iLineItemIndex].Label : undefined;
1564
+ } else {
1565
+ return undefined;
1566
+ }
1567
+ };
1568
+
1569
+ return fnGetLabelFromLineItemAnnotation() || oMetaModel && oMetaModel.getObject(sMetaPath + "/" + sNewAction + "@com.sap.vocabularies.Common.v1.Label") || oResourceBundleCore && oResourceBundleCore.getText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE");
1570
+ }
1571
+ }]);
1572
+
1573
+ return TransactionHelper;
1574
+ }();
1575
+
1576
+ return TransactionHelper;
1577
+ }, false);
1578
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlRyYW5zYWN0aW9uSGVscGVyLnRzIl0sIm5hbWVzIjpbIkNyZWF0aW9uTW9kZSIsIkZFTGlicmFyeSIsIlByb2dyYW1taW5nTW9kZWwiLCJWYWx1ZVN0YXRlIiwiY29yZUxpYnJhcnkiLCJnZXRQYXJhbWV0ZXJzIiwibVBhcmFtZXRlcnMiLCJnZXRNZXRhZGF0YSIsImdldE5hbWUiLCJUcmFuc2FjdGlvbkhlbHBlciIsIm9BcHBDb21wb25lbnQiLCJvTG9ja09iamVjdCIsIl9vQXBwQ29tcG9uZW50Iiwib0NvbnRleHQiLCJzUHJvZ3JhbW1pbmdNb2RlbCIsInNQYXRoIiwiaXNBIiwiZ2V0UGF0aCIsImlzUmVsYXRpdmUiLCJnZXRSZXNvbHZlZFBhdGgiLCJNb2RlbEhlbHBlciIsImlzRHJhZnRTdXBwb3J0ZWQiLCJnZXRNb2RlbCIsImdldE1ldGFNb2RlbCIsIkRyYWZ0IiwiaXNTdGlja3lTZXNzaW9uU3VwcG9ydGVkIiwiU3RpY2t5IiwiTm9uRHJhZnQiLCJvVmlldyIsInNDdXN0b21WYWxpZGF0aW9uRnVuY3Rpb24iLCJjdXN0b21WYWxpZGF0aW9uRnVuY3Rpb24iLCJzTW9kdWxlIiwic3Vic3RyaW5nIiwibGFzdEluZGV4T2YiLCJyZXBsYWNlIiwic0Z1bmN0aW9uTmFtZSIsImxlbmd0aCIsIm1EYXRhIiwiZGF0YSIsIkZQTUhlbHBlciIsInZhbGlkYXRpb25XcmFwcGVyIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvTWFpbkxpc3RCaW5kaW5nIiwibUluUGFyYW1ldGVycyIsIm9SZXNvdXJjZUJ1bmRsZSIsIm1lc3NhZ2VIYW5kbGVyIiwiYkZyb21Db3B5UGFzdGUiLCJ0aGF0Iiwib01vZGVsIiwib01ldGFNb2RlbCIsInNNZXRhUGF0aCIsImdldE1ldGFQYXRoIiwiZ2V0SGVhZGVyQ29udGV4dCIsInNDcmVhdGVIYXNoIiwiX2dldEFwcENvbXBvbmVudCIsImdldFJvdXRlclByb3h5IiwiZ2V0SGFzaCIsIm9Db21wb25lbnREYXRhIiwiZ2V0Q29tcG9uZW50RGF0YSIsIm9TdGFydHVwUGFyYW1ldGVycyIsInN0YXJ0dXBQYXJhbWV0ZXJzIiwic05ld0FjdGlvbiIsIl9nZXROZXdBY3Rpb24iLCJ1bmRlZmluZWQiLCJvQ3JlYXRpb25Qcm9taXNlIiwibUJpbmRpbmdQYXJhbWV0ZXJzIiwic01lc3NhZ2VzUGF0aCIsImdldE9iamVjdCIsInNCdXN5UGF0aCIsImdldFRhcmdldEVudGl0eVNldCIsImdldENvbnRleHQiLCJiRnVuY3Rpb25Pbk5hdlByb3AiLCJvTmV3RG9jdW1lbnRDb250ZXh0IiwicmVqZWN0IiwiZ2V0UHJvZ3JhbW1pbmdNb2RlbCIsImJ1c3lNb2RlIiwic0lkIiwiYmVmb3JlQ3JlYXRlQ2FsbEJhY2siLCJCdXN5TG9ja2VyIiwibG9jayIsIm9SZXNvdXJjZUJ1bmRsZUNvcmUiLCJzYXAiLCJ1aSIsImdldENvcmUiLCJnZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUiLCJjYWxsQWN0aW9uIiwiY29udGV4dHMiLCJzaG93QWN0aW9uUGFyYW1ldGVyRGlhbG9nIiwibGFiZWwiLCJfZ2V0U3BlY2lmaWNDcmVhdGVBY3Rpb25EaWFsb2dMYWJlbCIsImJpbmRpbmdQYXJhbWV0ZXJzIiwicGFyZW50Q29udHJvbCIsImJJc0NyZWF0ZUFjdGlvbiIsImJJc05ld1BhZ2VDcmVhdGlvbiIsImNyZWF0aW9uTW9kZSIsIkNyZWF0aW9uUm93IiwiSW5saW5lIiwiYU5vbkNvbXB1dGVkVmlzaWJsZUtleUZpZWxkcyIsIkNvbW1vblV0aWxzIiwiZ2V0Tm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzIiwic0Z1bmN0aW9uUGF0aCIsIm9GdW5jdGlvbkNvbnRleHQiLCJvRnVuY3Rpb24iLCJjcmVhdGVCaW5kaW5nQ29udGV4dCIsIiRJc0JvdW5kIiwib3BlcmF0aW9ucyIsImNhbGxCb3VuZEZ1bmN0aW9uIiwiY2FsbEZ1bmN0aW9uSW1wb3J0IiwidGhlbiIsImNhdGNoIiwib0Vycm9yIiwiTG9nIiwiZXJyb3IiLCJvRGF0YSIsIk9iamVjdCIsImFzc2lnbiIsIm9UcmFuc2llbnRMaXN0QmluZGluZyIsImJpbmRMaXN0IiwiJCR1cGRhdGVHcm91cElkIiwicmVmcmVzaEludGVybmFsIiwiY3JlYXRlIiwiX2xhdW5jaERpYWxvZ1dpdGhLZXlGaWVsZHMiLCJvbkJlZm9yZUNyZWF0ZVByb21pc2UiLCJjb250ZXh0UGF0aCIsImNyZWF0ZUF0RW5kIiwib25BZnRlckNyZWF0ZUNvbXBsZXRpb24iLCJvUmVzdWx0IiwiX2JDcmVhdGVNb2RlIiwicmVzcG9uc2UiLCJiQ29uc2lkZXJEb2N1bWVudE1vZGlmaWVkIiwiaGFuZGxlRG9jdW1lbnRNb2RpZmljYXRpb25zIiwic2hvd01lc3NhZ2VEaWFsb2ciLCJiRGVsZXRlVHJhbnNpZW50Q29udGV4dCIsImlzVHJhbnNpZW50IiwiZGVsZXRlIiwiZmluYWxseSIsInVubG9jayIsImFDb250ZXh0cyIsImJGaW5kQWN0aXZlQ29udGV4dHMiLCJhY3RpdmVDb250ZXh0cyIsInJlZHVjZSIsImFSZXN1bHQiLCJiSXNBY3RpdmVFbnRpdHkiLCJJc0FjdGl2ZUVudGl0eSIsImJIYXNBY3RpdmVFbnRpdHkiLCJIYXNBY3RpdmVFbnRpdHkiLCJvQWN0aXZlQ29udGV4dCIsImJpbmRDb250ZXh0IiwiZ2V0Qm91bmRDb250ZXh0IiwicHVzaCIsImFsbCIsIm1hcCIsInJlcXVlc3RDYW5vbmljYWxQYXRoIiwiY2hlY2tCb3giLCJvSW50ZXJuYWxNb2RlbENvbnRleHQiLCJpbnRlcm5hbE1vZGVsQ29udGV4dCIsImdldFByb3BlcnR5IiwiaXNDaGVja0JveFZpc2libGUiLCJpc0NoZWNrQm94U2VsZWN0ZWQiLCJzZXRQcm9wZXJ0eSIsIm9iaiIsInNlbGVjdGVkQ29udGV4dHMiLCJmaWx0ZXIiLCJlbGVtZW50IiwiZGVsZXRhYmxlQ29udGV4dHMiLCJpbmRleE9mIiwibnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzIiwiTWVzc2FnZVRvYXN0Iiwic2hvdyIsImdldFRyYW5zbGF0ZWRUZXh0IiwiZW50aXR5U2V0TmFtZSIsInZDb250ZXh0cyIsImZuUmVqZWN0IiwiZm5SZXNvbHZlIiwiYURlbGV0YWJsZUNvbnRleHRzIiwiaXNMb2NrZWRUZXh0VmlzaWJsZSIsImNhbm5vdEJlRGVsZXRlZFRleHRWaXNpYmxlIiwiYkRpYWxvZ0NvbmZpcm1lZCIsImFQYXJhbXMiLCJvRGVsZXRlTWVzc2FnZSIsInRpdGxlIiwiZ2V0VGV4dCIsIkFycmF5IiwiaXNBcnJheSIsImkiLCJvQ29udGV4dERhdGEiLCJIYXNEcmFmdEVudGl0eSIsIkRyYWZ0QWRtaW5pc3RyYXRpdmVEYXRhIiwiSW5Qcm9jZXNzQnlVc2VyIiwiRHJhZnRJc0NyZWF0ZWRCeU1lIiwiTWVzc2FnZUJveCIsIm9uQ2xvc2UiLCJkZXNjcmlwdGlvbiIsInRleHQiLCJ1blNhdmVkQ29udGV4dHMiLCJkcmFmdEFkbWluRGF0YSIsInNMYXN0Q2hhbmdlZEJ5VXNlciIsImNvbmNhdCIsImxvY2tlZENvbnRleHRzIiwibm9uRGVsZXRhYmxlVGV4dCIsImNoZWNrQm94VGV4dCIsIm9Ob25EZWxldGFibGVNZXNzYWdlVGV4dENvbnRyb2wiLCJvRGVsZXRlTWVzc2FnZVRleHRDb250cm9sIiwib0NvbnRlbnQiLCJWQm94IiwiaXRlbXMiLCJUZXh0IiwidmlzaWJsZSIsIkNoZWNrQm94Iiwic2VsZWN0ZWQiLCJzZWxlY3QiLCJvRXZlbnQiLCJnZXRTb3VyY2UiLCJnZXRTZWxlY3RlZCIsInNUaXRsZSIsImZuQ29uZmlybSIsIm9uQmVmb3JlRGVsZXRlUHJvbWlzZSIsImJlZm9yZURlbGV0ZUNhbGxCYWNrIiwiZmluZEFjdGl2ZURyYWZ0Um9vdENvbnRleHRzIiwiYmluZCIsImRyYWZ0IiwiZGVsZXRlRHJhZnQiLCJzaG93TWVzc2FnZXMiLCJhZnRlckRlbGV0ZVByb2Nlc3MiLCJvRGlhbG9nIiwiRGlhbG9nIiwic3RhdGUiLCJjb250ZW50IiwiYXJpYUxhYmVsbGVkQnkiLCJnZXRWaXNpYmxlIiwiYmVnaW5CdXR0b24iLCJCdXR0b24iLCJ0eXBlIiwicHJlc3MiLCJjbG9zZSIsImVuZEJ1dHRvbiIsImFmdGVyQ2xvc2UiLCJkZXN0cm95Iiwibm9EaWFsb2ciLCJhZGRTdHlsZUNsYXNzIiwib3BlbiIsIndhcm5pbmciLCJiUHJlcGFyZU9uRWRpdCIsIm9FZGl0UHJvbWlzZSIsIkVycm9yIiwiX2JJc01vZGlmaWVkIiwicmVtb3ZlVHJhbnNpdGlvbk1lc3NhZ2VzIiwiY3JlYXRlRHJhZnRGcm9tQWN0aXZlRG9jdW1lbnQiLCJiUHJlc2VydmVDaGFuZ2VzIiwic3RpY2t5IiwiZWRpdERvY3VtZW50SW5TdGlja3lTZXNzaW9uIiwib05ld0NvbnRleHQiLCJlcnIiLCJvUGFyYW1zQ29udGV4dCIsIm9DYW5jZWxCdXR0b24iLCJjYW5jZWxCdXR0b24iLCJvbkJlZm9yZUNhbmNlbFByb21pc2UiLCJzQ2Fub25pY2FsUGF0aCIsInNQTW9kZWwiLCJkcmFmdERhdGFDb250ZXh0IiwicmVxdWVzdE9iamVjdCIsIkNyZWF0aW9uRGF0ZVRpbWUiLCJMYXN0Q2hhbmdlRGF0ZVRpbWUiLCJza2lwRGlzY2FyZFBvcG92ZXIiLCJfc2hvd0Rpc2NhcmRQb3BvdmVyIiwiYmVmb3JlQ2FuY2VsQ2FsbEJhY2siLCJjb250ZXh0Iiwib0RlbGV0ZVByb21pc2UiLCJoYXNQZW5kaW5nQ2hhbmdlcyIsImdldEJpbmRpbmciLCJyZXNldENoYW5nZXMiLCJkaXNjYXJkRG9jdW1lbnQiLCJyZWZyZXNoIiwiYkV4ZWN1dGVTaWRlRWZmZWN0c09uRXJyb3IiLCJhQmluZGluZ3MiLCJvU2F2ZVByb21pc2UiLCJhY3RpdmF0ZURvY3VtZW50Iiwib0FjdGl2ZURvY3VtZW50IiwiYk5ld09iamVjdCIsImZvckVhY2giLCJvTGlzdEJpbmRpbmciLCJoYXNUcmFuc2llbnRDb250ZXh0IiwiZ2V0U2lkZUVmZmVjdHNTZXJ2aWNlIiwicmVxdWVzdFNpZGVFZmZlY3RzRm9yTmF2aWdhdGlvblByb3BlcnR5Iiwic0FjdGlvbk5hbWUiLCJvUHJvbWlzZSIsInNOYW1lIiwic3BsaXQiLCJtb2RlbCIsIm1TaWRlRWZmZWN0c1BhcmFtZXRlcnMiLCJnZXRPRGF0YUFjdGlvblNpZGVFZmZlY3RzIiwib0FwcGxpY2FibGVDb250ZXh0RGlhbG9nIiwib0NvbnRyb2xsZXIiLCJvbkNvbnRpbnVlIiwiYXBwbGljYWJsZUNvbnRleHQiLCJmbk9wZW5BbmRGaWxsRGlhbG9nIiwib0RpYWxvZ0NvbnRlbnQiLCJuTm90QXBwbGljYWJsZSIsIm5vdEFwcGxpY2FibGVDb250ZXh0IiwiYU5vdEFwcGxpY2FibGVJdGVtcyIsIm9Ob3RBcHBsaWNhYmxlSXRlbXNNb2RlbCIsIkpTT05Nb2RlbCIsIm9Ub3RhbHMiLCJ0b3RhbCIsInNldE1vZGVsIiwic0ZyYWdtZW50TmFtZSIsIm9EaWFsb2dGcmFnbWVudCIsIlhNTFRlbXBsYXRlUHJvY2Vzc29yIiwibG9hZFRlbXBsYXRlIiwiZ2V0Q2Fub25pY2FsUGF0aCIsInNFbnRpdHlTZXQiLCJzdWJzdHIiLCJvRGlhbG9nTGFiZWxNb2RlbCIsIlhNTFByZXByb2Nlc3NvciIsInByb2Nlc3MiLCJuYW1lIiwiYmluZGluZ0NvbnRleHRzIiwiZW50aXR5VHlwZSIsIm1vZGVscyIsIm1ldGFNb2RlbCIsIm9GcmFnbWVudCIsIkZyYWdtZW50IiwibG9hZCIsImRlZmluaXRpb24iLCJjb250cm9sbGVyIiwib1BvcG92ZXIiLCJhZGREZXBlbmRlbnQiLCJjb250ZXh0VG9Qcm9jZXNzIiwiY2FsbEJvdW5kQWN0aW9uIiwiaW52b2NhdGlvbkdyb3VwaW5nIiwiYWRkaXRpb25hbFNpZGVFZmZlY3QiLCJvblN1Ym1pdHRlZCIsIm9uUmVzcG9uc2UiLCJvcGVyYXRpb25BdmFpbGFibGVNYXAiLCJiR2V0Qm91bmRDb250ZXh0IiwiYk9iamVjdFBhZ2UiLCJkZWZhdWx0VmFsdWVzRXh0ZW5zaW9uRnVuY3Rpb24iLCJjYWxsQWN0aW9uSW1wb3J0IiwiX2hhbmRsZUFjdGlvblJlc3BvbnNlIiwiYVRyYW5zaWVudE1lc3NhZ2VzIiwibWVzc2FnZUhhbmRsaW5nIiwiZ2V0TWVzc2FnZXMiLCJvTWVzc2FnZU1hbmFnZXIiLCJnZXRNZXNzYWdlTWFuYWdlciIsImVycm9yVG9SZW1vdmUiLCJnZXRNZXNzYWdlTW9kZWwiLCJnZXREYXRhIiwidmFsaWRhdGlvbiIsInJlbW92ZU1lc3NhZ2VzIiwiYklzTW9kaWZpZWQiLCJfYkNvbnRpbnVlRGlzY2FyZCIsImZuT25BZnRlckRpc2NhcmQiLCJzZXRFbmFibGVkIiwiX29Qb3BvdmVyIiwiZGV0YWNoQWZ0ZXJDbG9zZSIsIm9UZXh0Iiwib0J1dHRvbiIsIndpZHRoIiwiaGFuZGxlVmFsaWRhdGlvbkVycm9yIiwiUG9wb3ZlciIsInNob3dIZWFkZXIiLCJwbGFjZW1lbnQiLCJiZWZvcmVPcGVuIiwic2V0SW5pdGlhbEZvY3VzIiwiYXR0YWNoQWZ0ZXJDbG9zZSIsIm9wZW5CeSIsIm9UcmFuc2llbnRDb250ZXh0IiwibUZpZWxkcyIsIm9QYXJlbnRDb250cm9sIiwiYlN1Y2Nlc3MiLCJnZXRDb250cm9sbGVyIiwiYUltbXV0YWJsZUZpZWxkcyIsIm9FbnRpdHlTZXRDb250ZXh0Iiwib0ltbXV0YWJsZUN0eE1vZGVsIiwib0ltbXV0YWJsZUN0eCIsImVudGl0eVNldCIsImZpZWxkcyIsImFGb3JtRWxlbWVudHMiLCJtRmllbGRWYWx1ZU1hcCIsIm9DcmVhdGVCdXR0b24iLCJ2YWxpZGF0ZVJlcXVpcmVkUHJvcGVydGllcyIsIm9Gb3JtRWxlbWVudCIsImdldEZpZWxkcyIsIm9GaWVsZCIsImdldFJlcXVpcmVkIiwic0ZpZWxkSWQiLCJnZXRJZCIsInZWYWx1ZSIsImdldFZhbHVlU3RhdGUiLCJnZXRWYWx1ZSIsImFSZXN1bHRzIiwiZXZlcnkiLCJiRW5hYmxlZCIsImhhbmRsZUNoYW5nZSIsImdldFBhcmFtZXRlciIsIm9GaWVsZFByb21pc2UiLCJoYW5kbGVMaXZlQ2hhbmdlIiwia2V5cyIsInNLZXkiLCJvVmFsdWUiLCJvRGlhbG9nVmFsdWUiLCJhVmFsdWVzIiwiY3JlYXRlUGFyYW1ldGVycyIsInN1Ym1pdEJhdGNoIiwib1Jlc3BvbnNlIiwic2V0QmluZGluZ0NvbnRleHQiLCJnZXRCaW5kaW5nQ29udGV4dCIsImdldEFnZ3JlZ2F0aW9uIiwiZ2V0QmVnaW5CdXR0b24iLCJzZXRVc2VyRGVmYXVsdHMiLCJjcmVhdGVBY3Rpb24iLCJmbkNyZWF0ZUNvbXBsZXRlZCIsImRldGFjaENyZWF0ZUNvbXBsZXRlZCIsImtlZXBUcmFuc2llbnRDb250ZXh0T25GYWlsZWQiLCJjcmVhdGVkIiwidHJhY2UiLCJuYXZpZ2F0ZUJhY2tGcm9tVHJhbnNpZW50U3RhdGUiLCJhdHRhY2hDcmVhdGVDb21wbGV0ZWQiLCJwcmVmZXJyZWRNb2RlIiwic1ByZWZlcnJlZE1vZGUiLCJmbkdldExhYmVsRnJvbUxpbmVJdGVtQW5ub3RhdGlvbiIsImlMaW5lSXRlbUluZGV4IiwiZmluZEluZGV4Iiwib0xpbmVJdGVtIiwiYUxpbmVJdGVtQWN0aW9uIiwiQWN0aW9uIiwiTGFiZWwiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQTBCQSxNQUFNQSxZQUFZLEdBQUdDLFNBQVMsQ0FBQ0QsWUFBL0I7QUFDQSxNQUFNRSxnQkFBZ0IsR0FBR0QsU0FBUyxDQUFDQyxnQkFBbkM7QUFDQSxNQUFNQyxVQUFVLEdBQUdDLFdBQVcsQ0FBQ0QsVUFBL0I7QUFDQTs7QUFDQSxXQUFTRSxhQUFULENBQXVCQyxXQUF2QixFQUF5QztBQUN4QyxRQUFJQSxXQUFXLElBQUlBLFdBQVcsQ0FBQ0MsV0FBM0IsSUFBMENELFdBQVcsQ0FBQ0MsV0FBWixHQUEwQkMsT0FBMUIsT0FBd0MsbUJBQXRGLEVBQTJHO0FBQzFHRixNQUFBQSxXQUFXLEdBQUcsRUFBZDtBQUNBOztBQUNELFdBQU9BLFdBQVcsSUFBSSxFQUF0QjtBQUNBOztNQUVLRyxpQjtBQVFMLCtCQUFZQyxhQUFaLEVBQXlDQyxXQUF6QyxFQUEyRDtBQUFBOztBQUFBLDRDQUpuQyxLQUltQzs7QUFBQSw0Q0FIbkMsS0FHbUM7O0FBQUEsaURBRjlCLEtBRThCOztBQUMxRCxXQUFLQyxjQUFMLEdBQXNCRixhQUF0QjtBQUNBLFdBQUtDLFdBQUwsR0FBbUJBLFdBQW5CO0FBQ0E7Ozs7YUFDRCw2QkFBb0JF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LFNBZEQ7O0FBZ0JBLGVBQ0NxVyxnQ0FBZ0MsTUFDL0JuWCxVQUFVLElBQUlBLFVBQVUsQ0FBQ2tCLFNBQVgsQ0FBcUJqQixTQUFTLEdBQUcsR0FBWixHQUFrQlcsVUFBbEIsR0FBK0IsdUNBQXBELENBRGYsSUFFQ21CLG1CQUFtQixJQUFJQSxtQkFBbUIsQ0FBQ3FHLE9BQXBCLENBQTRCLDBDQUE1QixDQUh6QjtBQUtBOzs7Ozs7U0FHYTdLLGlCIiwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZHJhZnQgZnJvbSBcInNhcC9mZS9jb3JlL2FjdGlvbnMvZHJhZnRcIjtcbmltcG9ydCBzdGlja3kgZnJvbSBcInNhcC9mZS9jb3JlL2FjdGlvbnMvc3RpY2t5XCI7XG5pbXBvcnQgb3BlcmF0aW9ucyBmcm9tIFwic2FwL2ZlL2NvcmUvYWN0aW9ucy9vcGVyYXRpb25zXCI7XG5pbXBvcnQgSlNPTk1vZGVsIGZyb20gXCJzYXAvdWkvbW9kZWwvanNvbi9KU09OTW9kZWxcIjtcbmltcG9ydCBQb3BvdmVyIGZyb20gXCJzYXAvbS9Qb3BvdmVyXCI7XG5pbXBvcnQgVkJveCBmcm9tIFwic2FwL20vVkJveFwiO1xuaW1wb3J0IENoZWNrQm94IGZyb20gXCJzYXAvbS9DaGVja0JveFwiO1xuaW1wb3J0IFRleHQgZnJvbSBcInNhcC9tL1RleHRcIjtcbmltcG9ydCBCdXR0b24gZnJvbSBcInNhcC9tL0J1dHRvblwiO1xuaW1wb3J0IE1lc3NhZ2VUb2FzdCBmcm9tIFwic2FwL20vTWVzc2FnZVRvYXN0XCI7XG5pbXBvcnQgRGlhbG9nIGZyb20gXCJzYXAvbS9EaWFsb2dcIjtcbmltcG9ydCBMb2cgZnJvbSBcInNhcC9iYXNlL0xvZ1wiO1xuaW1wb3J0IENvbW1vblV0aWxzIGZyb20gXCJzYXAvZmUvY29yZS9Db21tb25VdGlsc1wiO1xuaW1wb3J0IEJ1c3lMb2NrZXIgZnJvbSBcInNhcC9mZS9jb3JlL0J1c3lMb2NrZXJcIjtcbmltcG9ydCBYTUxQcmVwcm9jZXNzb3IgZnJvbSBcInNhcC91aS9jb3JlL3V0aWwvWE1MUHJlcHJvY2Vzc29yXCI7XG5pbXBvcnQgWE1MVGVtcGxhdGVQcm9jZXNzb3IgZnJvbSBcInNhcC91aS9jb3JlL1hNTFRlbXBsYXRlUHJvY2Vzc29yXCI7XG5pbXBvcnQgRnJhZ21lbnQgZnJvbSBcInNhcC91aS9jb3JlL0ZyYWdtZW50XCI7XG5pbXBvcnQgTWVzc2FnZUJveCBmcm9tIFwic2FwL20vTWVzc2FnZUJveFwiO1xuaW1wb3J0IE1vZGVsSGVscGVyLCB7IEludGVybmFsTW9kZWxDb250ZXh0IH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvTW9kZWxIZWxwZXJcIjtcbmltcG9ydCBGRUxpYnJhcnksIHsgUHJvZ3JhbW1pbmdNb2RlbCBhcyBQcm9ncmFtbWluZ01vZGVsVHlwZSB9IGZyb20gXCJzYXAvZmUvY29yZS9saWJyYXJ5XCI7XG5pbXBvcnQgY29yZUxpYnJhcnkgZnJvbSBcInNhcC91aS9jb3JlL2xpYnJhcnlcIjtcbmltcG9ydCBtZXNzYWdlSGFuZGxpbmcgZnJvbSBcInNhcC9mZS9jb3JlL2FjdGlvbnMvbWVzc2FnZUhhbmRsaW5nXCI7XG5pbXBvcnQgeyBBcHBDb21wb25lbnQgfSBmcm9tIFwic2FwL2ZlL2NvcmVcIjtcbmltcG9ydCBSZXNvdXJjZUJ1bmRsZSBmcm9tIFwic2FwL2Jhc2UvaTE4bi9SZXNvdXJjZUJ1bmRsZVwiO1xuaW1wb3J0IE9EYXRhTWV0YU1vZGVsIGZyb20gXCJzYXAvdWkvbW9kZWwvb2RhdGEvdjQvT0RhdGFNZXRhTW9kZWxcIjtcbmltcG9ydCBWaWV3IGZyb20gXCJzYXAvdWkvY29yZS9tdmMvVmlld1wiO1xuaW1wb3J0IEZQTUhlbHBlciBmcm9tIFwic2FwL2ZlL2NvcmUvaGVscGVycy9GUE1IZWxwZXJcIjtcblxuY29uc3QgQ3JlYXRpb25Nb2RlID0gRkVMaWJyYXJ5LkNyZWF0aW9uTW9kZTtcbmNvbnN0IFByb2dyYW1taW5nTW9kZWwgPSBGRUxpYnJhcnkuUHJvZ3JhbW1pbmdNb2RlbDtcbmNvbnN0IFZhbHVlU3RhdGUgPSBjb3JlTGlicmFyeS5WYWx1ZVN0YXRlO1xuLyogTWFrZSBzdXJlIHRoYXQgdGhlIG1QYXJhbWV0ZXJzIGlzIG5vdCB0aGUgb0V2ZW50ICovXG5mdW5jdGlvbiBnZXRQYXJhbWV0ZXJzKG1QYXJhbWV0ZXJzOiBhbnkpIHtcblx0aWYgKG1QYXJhbWV0ZXJzICYmIG1QYXJhbWV0ZXJzLmdldE1ldGFkYXRhICYmIG1QYXJhbWV0ZXJzLmdldE1ldGFkYXRhKCkuZ2V0TmFtZSgpID09PSBcInNhcC51aS5iYXNlLkV2ZW50XCIpIHtcblx0XHRtUGFyYW1ldGVycyA9IHt9O1xuXHR9XG5cdHJldHVybiBtUGFyYW1ldGVycyB8fCB7fTtcbn1cblxuY2xhc3MgVHJhbnNhY3Rpb25IZWxwZXIge1xuXHRfb0FwcENvbXBvbmVudDogQXBwQ29tcG9uZW50O1xuXHRvTG9ja09iamVjdDogYW55O1xuXHRzUHJvZ3JhbW1pbmdNb2RlbD86IFByb2dyYW1taW5nTW9kZWxUeXBlO1xuXHRfYklzTW9kaWZpZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblx0X2JDcmVhdGVNb2RlOiBib29sZWFuID0gZmFsc2U7XG5cdF9iQ29udGludWVEaXNjYXJkOiBib29sZWFuID0gZmFsc2U7XG5cdF9vUG9wb3ZlciE6IFBvcG92ZXI7XG5cdGNvbnN0cnVjdG9yKG9BcHBDb21wb25lbnQ6IEFwcENvbXBvbmVudCwgb0xvY2tPYmplY3Q6IGFueSkge1xuXHRcdHRoaXMuX29BcHBDb21wb25lbnQgPSBvQXBwQ29tcG9uZW50O1xuXHRcdHRoaXMub0xvY2tPYmplY3QgPSBvTG9ja09iamVjdDtcblx0fVxuXHRnZXRQcm9ncmFtbWluZ01vZGVsKG9Db250ZXh0OiBhbnkpIHtcblx0XHRpZiAoIXRoaXMuc1Byb2dyYW1taW5nTW9kZWwgJiYgb0NvbnRleHQpIHtcblx0XHRcdGxldCBzUGF0aDtcblx0XHRcdGlmIChvQ29udGV4dC5pc0EoXCJzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dFwiKSkge1xuXHRcdFx0XHRzUGF0aCA9IG9Db250ZXh0LmdldFBhdGgoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNQYXRoID0gb0NvbnRleHQuaXNSZWxhdGl2ZSgpID8gb0NvbnRleHQuZ2V0UmVzb2x2ZWRQYXRoKCkgOiBvQ29udGV4dC5nZXRQYXRoKCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoTW9kZWxIZWxwZXIuaXNEcmFmdFN1cHBvcnRlZChvQ29udGV4dC5nZXRNb2RlbCgpLmdldE1ldGFNb2RlbCgpLCBzUGF0aCkpIHtcblx0XHRcdFx0dGhpcy5zUHJvZ3JhbW1pbmdNb2RlbCA9IFByb2dyYW1taW5nTW9kZWwuRHJhZnQ7XG5cdFx0XHR9IGVsc2UgaWYgKE1vZGVsSGVscGVyLmlzU3RpY2t5U2Vzc2lvblN1cHBvcnRlZChvQ29udGV4dC5nZXRNb2RlbCgpLmdldE1ldGFNb2RlbCgpKSkge1xuXHRcdFx0XHR0aGlzLnNQcm9ncmFtbWluZ01vZGVsID0gUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3k7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBhcyB0aGUgdHJhbnNhY3Rpb24gaGVscGVyIGlzIGEgc2luZ2xldG9uIHdlIGRvbid0IHN0b3JlIHRoZSBub24gZHJhZnQgYXMgdGhlIHVzZXIgY291bGRcblx0XHRcdFx0Ly8gc3RhcnQgd2l0aCBhIG5vbiBkcmFmdCBjaGlsZCBwYWdlIGFuZCBuYXZpZ2F0ZXMgYmFjayB0byBhIGRyYWZ0IGVuYWJsZWQgb25lXG5cdFx0XHRcdHJldHVybiBQcm9ncmFtbWluZ01vZGVsLk5vbkRyYWZ0O1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5zUHJvZ3JhbW1pbmdNb2RlbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBWYWxpZGF0ZXMgYSBkb2N1bWVudC5cblx0ICpcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBzdGF0aWNcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gb0NvbnRleHQgQ29udGV4dCBvZiB0aGUgZG9jdW1lbnQgdG8gYmUgdmFsaWRhdGVkXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbbVBhcmFtZXRlcnNdIENhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczpcblx0ICogKiBAcGFyYW0ge29iamVjdH0gW21QYXJhbWV0ZXJzLmRhdGFdIEEgbWFwIG9mIGRhdGEgdGhhdCBzaG91bGQgYmUgdmFsaWRhdGVkXG5cdCAqICogQHBhcmFtIHtzdHJpbmd9IFttUGFyYW1ldGVycy5jdXN0b21WYWxpZGF0aW9uRnVuY3Rpb25dIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcGF0aCB0byB0aGUgdmFsaWRhdGlvbiBmdW5jdGlvblxuXHQgKiBAcGFyYW0ge29iamVjdH0gb1ZpZXcgQ29udGFpbnMgdGhlIG9iamVjdCBvZiB0aGUgY3VycmVudCB2aWV3XG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIHdpdGggcmVzdWx0IG9mIHRoZSBjdXN0b20gdmFsaWRhdGlvbiBmdW5jdGlvblxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqL1xuXHR2YWxpZGF0ZURvY3VtZW50KG9Db250ZXh0OiBhbnksIG1QYXJhbWV0ZXJzOiBhbnksIG9WaWV3OiBWaWV3KTogUHJvbWlzZTxhbnk+IHtcblx0XHRjb25zdCBzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uID0gbVBhcmFtZXRlcnMgJiYgbVBhcmFtZXRlcnMuY3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uO1xuXHRcdGlmIChzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uKSB7XG5cdFx0XHRjb25zdCBzTW9kdWxlID0gc0N1c3RvbVZhbGlkYXRpb25GdW5jdGlvbi5zdWJzdHJpbmcoMCwgc0N1c3RvbVZhbGlkYXRpb25GdW5jdGlvbi5sYXN0SW5kZXhPZihcIi5cIikgfHwgLTEpLnJlcGxhY2UoL1xcLi9naSwgXCIvXCIpLFxuXHRcdFx0XHRzRnVuY3Rpb25OYW1lID0gc0N1c3RvbVZhbGlkYXRpb25GdW5jdGlvbi5zdWJzdHJpbmcoXG5cdFx0XHRcdFx0c0N1c3RvbVZhbGlkYXRpb25GdW5jdGlvbi5sYXN0SW5kZXhPZihcIi5cIikgKyAxLFxuXHRcdFx0XHRcdHNDdXN0b21WYWxpZGF0aW9uRnVuY3Rpb24ubGVuZ3RoXG5cdFx0XHRcdCksXG5cdFx0XHRcdG1EYXRhID0gbVBhcmFtZXRlcnMuZGF0YTtcblx0XHRcdGRlbGV0ZSBtRGF0YVtcIkAkdWk1LmNvbnRleHQuaXNUcmFuc2llbnRcIl07XG5cdFx0XHRyZXR1cm4gRlBNSGVscGVyLnZhbGlkYXRpb25XcmFwcGVyKHNNb2R1bGUsIHNGdW5jdGlvbk5hbWUsIG1EYXRhLCBvVmlldywgb0NvbnRleHQpO1xuXHRcdH1cblx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IGRvY3VtZW50LlxuXHQgKlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHN0YXRpY1xuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YUxpc3RCaW5kaW5nfSBvTWFpbkxpc3RCaW5kaW5nIE9EYXRhIFY0IExpc3RCaW5kaW5nIG9iamVjdFxuXHQgKiBAcGFyYW0ge29iamVjdH0gW21JblBhcmFtZXRlcnNdIE9wdGlvbmFsLCBjYW4gY29udGFpbiB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG5cdCAqIEBwYXJhbSB7bWFwfSBbbUluUGFyYW1ldGVycy5kYXRhXSBBIG1hcCBvZiBkYXRhIHRoYXQgc2hvdWxkIGJlIHNlbnQgd2l0aGluIHRoZSBQT1NUXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBbbUluUGFyYW1ldGVycy5idXN5TW9kZV0gR2xvYmFsIChkZWZhdWx0KSwgTG9jYWwsIE5vbmUgVE9ETzogdG8gYmUgcmVmYWN0b3JlZFxuXHQgKiBAcGFyYW0ge21hcH0gW21JblBhcmFtZXRlcnMua2VlcFRyYW5zaWVudENvbnRleHRPbkZhaWxlZF0gSWYgc2V0LCB0aGUgY29udGV4dCBzdGF5cyBpbiB0aGUgbGlzdCBpZiB0aGUgUE9TVCBmYWlsZWQgYW5kIFBPU1Qgd2lsbCBiZSByZXBlYXRlZCB3aXRoIHRoZSBuZXh0IGNoYW5nZVxuXHQgKiBAcGFyYW0gb1Jlc291cmNlQnVuZGxlXG5cdCAqIEBwYXJhbSBtZXNzYWdlSGFuZGxlclxuXHQgKiBAcGFyYW0gYkZyb21Db3B5UGFzdGVcblx0ICogQHBhcmFtIG9WaWV3IFRoZSBjdXJyZW50IHZpZXdcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgd2l0aCBuZXcgYmluZGluZyBjb250ZXh0XG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKiBAZmluYWxcblx0ICovXG5cdGNyZWF0ZURvY3VtZW50KFxuXHRcdG9NYWluTGlzdEJpbmRpbmc6IGFueSxcblx0XHRtSW5QYXJhbWV0ZXJzOiB7IGRhdGE/OiBhbnk7IGJ1c3lNb2RlPzogc3RyaW5nIHwgdW5kZWZpbmVkOyBrZWVwVHJhbnNpZW50Q29udGV4dE9uRmFpbGVkPzogYW55IH0gfCB1bmRlZmluZWQsXG5cdFx0b1Jlc291cmNlQnVuZGxlOiBhbnksXG5cdFx0bWVzc2FnZUhhbmRsZXI6IGFueSxcblx0XHRiRnJvbUNvcHlQYXN0ZTogYW55LFxuXHRcdG9WaWV3OiBhbnlcblx0KSB7XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG5cdFx0Y29uc3QgdGhhdCA9IHRoaXMsXG5cdFx0XHRvTW9kZWwgPSBvTWFpbkxpc3RCaW5kaW5nLmdldE1vZGVsKCksXG5cdFx0XHRvTWV0YU1vZGVsID0gb01vZGVsLmdldE1ldGFNb2RlbCgpLFxuXHRcdFx0c01ldGFQYXRoID0gb01ldGFNb2RlbC5nZXRNZXRhUGF0aChvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKS5nZXRQYXRoKCkpLFxuXHRcdFx0c0NyZWF0ZUhhc2ggPSB0aGlzLl9nZXRBcHBDb21wb25lbnQoKVxuXHRcdFx0XHQuZ2V0Um91dGVyUHJveHkoKVxuXHRcdFx0XHQuZ2V0SGFzaCgpLFxuXHRcdFx0b0NvbXBvbmVudERhdGEgPSB0aGlzLl9nZXRBcHBDb21wb25lbnQoKS5nZXRDb21wb25lbnREYXRhKCksXG5cdFx0XHRvU3RhcnR1cFBhcmFtZXRlcnMgPSAob0NvbXBvbmVudERhdGEgJiYgb0NvbXBvbmVudERhdGEuc3RhcnR1cFBhcmFtZXRlcnMpIHx8IHt9LFxuXHRcdFx0c05ld0FjdGlvbiA9ICFvTWFpbkxpc3RCaW5kaW5nLmlzUmVsYXRpdmUoKVxuXHRcdFx0XHQ/IHRoaXMuX2dldE5ld0FjdGlvbihvU3RhcnR1cFBhcmFtZXRlcnMsIHNDcmVhdGVIYXNoLCBvTWV0YU1vZGVsLCBzTWV0YVBhdGgpXG5cdFx0XHRcdDogdW5kZWZpbmVkO1xuXHRcdGxldCBvQ3JlYXRpb25Qcm9taXNlO1xuXHRcdGNvbnN0IG1CaW5kaW5nUGFyYW1ldGVyczogYW55ID0geyBcIiQkcGF0Y2hXaXRob3V0U2lkZUVmZmVjdHNcIjogdHJ1ZSB9O1xuXHRcdGNvbnN0IHNNZXNzYWdlc1BhdGggPSBvTWV0YU1vZGVsLmdldE9iamVjdChzTWV0YVBhdGggKyBcIi9AY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLk1lc3NhZ2VzLyRQYXRoXCIpO1xuXHRcdGxldCBzQnVzeVBhdGggPSBcIi9idXN5XCI7XG5cdFx0bGV0IHNGdW5jdGlvbk5hbWUgPVxuXHRcdFx0b01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRlZmF1bHRWYWx1ZXNGdW5jdGlvblwiKSB8fFxuXHRcdFx0b01ldGFNb2RlbC5nZXRPYmplY3QoXG5cdFx0XHRcdE1vZGVsSGVscGVyLmdldFRhcmdldEVudGl0eVNldChvTWV0YU1vZGVsLmdldENvbnRleHQoc01ldGFQYXRoKSkgKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRGVmYXVsdFZhbHVlc0Z1bmN0aW9uXCJcblx0XHRcdCk7XG5cdFx0bGV0IGJGdW5jdGlvbk9uTmF2UHJvcDtcblx0XHRsZXQgb05ld0RvY3VtZW50Q29udGV4dDogYW55O1xuXHRcdGlmIChzRnVuY3Rpb25OYW1lKSB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EZWZhdWx0VmFsdWVzRnVuY3Rpb25cIikgJiZcblx0XHRcdFx0TW9kZWxIZWxwZXIuZ2V0VGFyZ2V0RW50aXR5U2V0KG9NZXRhTW9kZWwuZ2V0Q29udGV4dChzTWV0YVBhdGgpKSAhPT0gc01ldGFQYXRoXG5cdFx0XHQpIHtcblx0XHRcdFx0YkZ1bmN0aW9uT25OYXZQcm9wID0gdHJ1ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJGdW5jdGlvbk9uTmF2UHJvcCA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoc01lc3NhZ2VzUGF0aCkge1xuXHRcdFx0bUJpbmRpbmdQYXJhbWV0ZXJzW1wiJHNlbGVjdFwiXSA9IHNNZXNzYWdlc1BhdGg7XG5cdFx0fVxuXHRcdGNvbnN0IG1QYXJhbWV0ZXJzID0gZ2V0UGFyYW1ldGVycyhtSW5QYXJhbWV0ZXJzKTtcblx0XHRpZiAoIW9NYWluTGlzdEJpbmRpbmcpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIkJpbmRpbmcgcmVxdWlyZWQgZm9yIG5ldyBkb2N1bWVudCBjcmVhdGlvblwiKTtcblx0XHR9XG5cdFx0Y29uc3Qgc1Byb2dyYW1taW5nTW9kZWwgPSB0aGlzLmdldFByb2dyYW1taW5nTW9kZWwob01haW5MaXN0QmluZGluZyk7XG5cdFx0aWYgKHNQcm9ncmFtbWluZ01vZGVsICE9PSBQcm9ncmFtbWluZ01vZGVsLkRyYWZ0ICYmIHNQcm9ncmFtbWluZ01vZGVsICE9PSBQcm9ncmFtbWluZ01vZGVsLlN0aWNreSkge1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KFwiQ3JlYXRlIGRvY3VtZW50IG9ubHkgYWxsb3dlZCBmb3IgZHJhZnQgb3Igc3RpY2t5IHNlc3Npb24gc3VwcG9ydGVkIHNlcnZpY2VzXCIpO1xuXHRcdH1cblx0XHRpZiAobVBhcmFtZXRlcnMuYnVzeU1vZGUgPT09IFwiTG9jYWxcIikge1xuXHRcdFx0Ly8gaW4gY2FzZSBvZiBsb2NhbCBidXN5IG1vZGUgd2UgdXNlIHRoZSBsaXN0IGJpbmRpbmcgbmFtZVxuXHRcdFx0Ly8gdGhlcmUncyBubyBBUFkgeWV0IHNvIHdlIGhhdmUgdG8gdXNlIHRoZSAuc0lkIFRPRE8gcHJvdmlkZSBhIHB1YmxpYyBtZXRob2Q/XG5cdFx0XHRzQnVzeVBhdGggPSBcIi9idXN5TG9jYWwvXCIgKyBvTWFpbkxpc3RCaW5kaW5nLnNJZDtcblx0XHR9XG5cdFx0bVBhcmFtZXRlcnMuYmVmb3JlQ3JlYXRlQ2FsbEJhY2sgPSBiRnJvbUNvcHlQYXN0ZSA/IG51bGwgOiBtUGFyYW1ldGVycy5iZWZvcmVDcmVhdGVDYWxsQmFjaztcblx0XHRCdXN5TG9ja2VyLmxvY2sodGhpcy5vTG9ja09iamVjdCwgc0J1c3lQYXRoKTtcblx0XHRjb25zdCBvUmVzb3VyY2VCdW5kbGVDb3JlID0gc2FwLnVpLmdldENvcmUoKS5nZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUoXCJzYXAuZmUuY29yZVwiKTtcblx0XHRpZiAoc05ld0FjdGlvbikge1xuXHRcdFx0b0NyZWF0aW9uUHJvbWlzZSA9IHRoaXMuY2FsbEFjdGlvbihcblx0XHRcdFx0c05ld0FjdGlvbixcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGNvbnRleHRzOiBvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKSxcblx0XHRcdFx0XHRzaG93QWN0aW9uUGFyYW1ldGVyRGlhbG9nOiB0cnVlLFxuXHRcdFx0XHRcdGxhYmVsOiB0aGlzLl9nZXRTcGVjaWZpY0NyZWF0ZUFjdGlvbkRpYWxvZ0xhYmVsKFxuXHRcdFx0XHRcdFx0b01ldGFNb2RlbCxcblx0XHRcdFx0XHRcdHNNZXRhUGF0aCxcblx0XHRcdFx0XHRcdHNOZXdBY3Rpb24sXG5cdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGVDb3JlIGFzIFJlc291cmNlQnVuZGxlXG5cdFx0XHRcdFx0KSxcblx0XHRcdFx0XHRiaW5kaW5nUGFyYW1ldGVyczogbUJpbmRpbmdQYXJhbWV0ZXJzLFxuXHRcdFx0XHRcdHBhcmVudENvbnRyb2w6IG1QYXJhbWV0ZXJzLnBhcmVudENvbnRyb2wsXG5cdFx0XHRcdFx0YklzQ3JlYXRlQWN0aW9uOiB0cnVlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdG51bGwsXG5cdFx0XHRcdG1lc3NhZ2VIYW5kbGVyXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBiSXNOZXdQYWdlQ3JlYXRpb24gPVxuXHRcdFx0XHRtUGFyYW1ldGVycy5jcmVhdGlvbk1vZGUgIT09IENyZWF0aW9uTW9kZS5DcmVhdGlvblJvdyAmJiBtUGFyYW1ldGVycy5jcmVhdGlvbk1vZGUgIT09IENyZWF0aW9uTW9kZS5JbmxpbmU7XG5cdFx0XHRjb25zdCBhTm9uQ29tcHV0ZWRWaXNpYmxlS2V5RmllbGRzID0gYklzTmV3UGFnZUNyZWF0aW9uXG5cdFx0XHRcdD8gQ29tbW9uVXRpbHMuZ2V0Tm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzKG9NZXRhTW9kZWwsIHNNZXRhUGF0aCwgb1ZpZXcpXG5cdFx0XHRcdDogW107XG5cdFx0XHRzRnVuY3Rpb25OYW1lID0gYkZyb21Db3B5UGFzdGUgPyBudWxsIDogc0Z1bmN0aW9uTmFtZTtcblx0XHRcdGxldCBzRnVuY3Rpb25QYXRoLCBvRnVuY3Rpb25Db250ZXh0O1xuXHRcdFx0aWYgKHNGdW5jdGlvbk5hbWUpIHtcblx0XHRcdFx0Ly9ib3VuZCB0byB0aGUgc291cmNlIGVudGl0eTpcblx0XHRcdFx0aWYgKGJGdW5jdGlvbk9uTmF2UHJvcCkge1xuXHRcdFx0XHRcdHNGdW5jdGlvblBhdGggPVxuXHRcdFx0XHRcdFx0b01haW5MaXN0QmluZGluZy5nZXRDb250ZXh0KCkgJiZcblx0XHRcdFx0XHRcdG9NZXRhTW9kZWwuZ2V0TWV0YVBhdGgob01haW5MaXN0QmluZGluZy5nZXRDb250ZXh0KCkuZ2V0UGF0aCgpKSArIFwiL1wiICsgc0Z1bmN0aW9uTmFtZTtcblx0XHRcdFx0XHRvRnVuY3Rpb25Db250ZXh0ID0gb01haW5MaXN0QmluZGluZy5nZXRDb250ZXh0KCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c0Z1bmN0aW9uUGF0aCA9XG5cdFx0XHRcdFx0XHRvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKSAmJlxuXHRcdFx0XHRcdFx0b01ldGFNb2RlbC5nZXRNZXRhUGF0aChvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKS5nZXRQYXRoKCkpICsgXCIvXCIgKyBzRnVuY3Rpb25OYW1lO1xuXHRcdFx0XHRcdG9GdW5jdGlvbkNvbnRleHQgPSBvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Y29uc3Qgb0Z1bmN0aW9uID0gc0Z1bmN0aW9uUGF0aCAmJiBvTWV0YU1vZGVsLmNyZWF0ZUJpbmRpbmdDb250ZXh0KHNGdW5jdGlvblBhdGgpO1xuXHRcdFx0aWYgKG9GdW5jdGlvbiAmJiBvRnVuY3Rpb24uZ2V0T2JqZWN0KCkgJiYgb0Z1bmN0aW9uLmdldE9iamVjdCgpWzBdLiRJc0JvdW5kKSB7XG5cdFx0XHRcdG9DcmVhdGlvblByb21pc2UgPSBvcGVyYXRpb25zLmNhbGxCb3VuZEZ1bmN0aW9uKHNGdW5jdGlvbk5hbWUsIG9GdW5jdGlvbkNvbnRleHQsIG9Nb2RlbCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvQ3JlYXRpb25Qcm9taXNlID0gb3BlcmF0aW9ucy5jYWxsRnVuY3Rpb25JbXBvcnQoc0Z1bmN0aW9uTmFtZSwgb01vZGVsKTtcblx0XHRcdH1cblxuXHRcdFx0b0NyZWF0aW9uUHJvbWlzZSA9IG9DcmVhdGlvblByb21pc2Vcblx0XHRcdFx0LnRoZW4oZnVuY3Rpb24ob0NvbnRleHQ6IGFueSkge1xuXHRcdFx0XHRcdGlmIChvQ29udGV4dCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIG9Db250ZXh0LmdldE9iamVjdCgpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0TG9nLmVycm9yKFwiRXJyb3Igd2hpbGUgZXhlY3V0aW5nIHRoZSBmdW5jdGlvbiBcIiArIHNGdW5jdGlvbk5hbWUsIG9FcnJvcik7XG5cdFx0XHRcdFx0dGhyb3cgb0Vycm9yO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQudGhlbihmdW5jdGlvbihvRGF0YTogYW55KSB7XG5cdFx0XHRcdFx0bVBhcmFtZXRlcnMuZGF0YSA9IG9EYXRhID8gT2JqZWN0LmFzc2lnbih7fSwgb0RhdGEsIG1QYXJhbWV0ZXJzLmRhdGEpIDogbVBhcmFtZXRlcnMuZGF0YTtcblx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMuZGF0YSkge1xuXHRcdFx0XHRcdFx0ZGVsZXRlIG1QYXJhbWV0ZXJzLmRhdGFbXCJAb2RhdGEuY29udGV4dFwiXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKGFOb25Db21wdXRlZFZpc2libGVLZXlGaWVsZHMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdFx0Y29uc3Qgb1RyYW5zaWVudExpc3RCaW5kaW5nID0gb01vZGVsLmJpbmRMaXN0KG9NYWluTGlzdEJpbmRpbmcuZ2V0UGF0aCgpLCBvTWFpbkxpc3RCaW5kaW5nLmdldENvbnRleHQoKSwgW10sIFtdLCB7XG5cdFx0XHRcdFx0XHRcdCQkdXBkYXRlR3JvdXBJZDogXCJzdWJtaXRMYXRlclwiXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdG9UcmFuc2llbnRMaXN0QmluZGluZy5yZWZyZXNoSW50ZXJuYWwgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0LyogKi9cblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRvTmV3RG9jdW1lbnRDb250ZXh0ID0gb1RyYW5zaWVudExpc3RCaW5kaW5nLmNyZWF0ZShtUGFyYW1ldGVycy5kYXRhLCB0cnVlKTtcblx0XHRcdFx0XHRcdHJldHVybiB0aGF0Ll9sYXVuY2hEaWFsb2dXaXRoS2V5RmllbGRzKFxuXHRcdFx0XHRcdFx0XHRvTWFpbkxpc3RCaW5kaW5nLFxuXHRcdFx0XHRcdFx0XHRvVHJhbnNpZW50TGlzdEJpbmRpbmcsXG5cdFx0XHRcdFx0XHRcdG9OZXdEb2N1bWVudENvbnRleHQsXG5cdFx0XHRcdFx0XHRcdGFOb25Db21wdXRlZFZpc2libGVLZXlGaWVsZHMsXG5cdFx0XHRcdFx0XHRcdG9Nb2RlbCxcblx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMsXG5cdFx0XHRcdFx0XHRcdG1lc3NhZ2VIYW5kbGVyXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRsZXQgb25CZWZvcmVDcmVhdGVQcm9taXNlO1xuXHRcdFx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLmJlZm9yZUNyZWF0ZUNhbGxCYWNrKSB7XG5cdFx0XHRcdFx0XHRcdG9uQmVmb3JlQ3JlYXRlUHJvbWlzZSA9IG1QYXJhbWV0ZXJzLmJlZm9yZUNyZWF0ZUNhbGxCYWNrKHtcblx0XHRcdFx0XHRcdFx0XHRjb250ZXh0UGF0aDogb01haW5MaXN0QmluZGluZyAmJiBvTWFpbkxpc3RCaW5kaW5nLmdldFBhdGgoKVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdG9uQmVmb3JlQ3JlYXRlUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0cmV0dXJuIG9uQmVmb3JlQ3JlYXRlUHJvbWlzZS50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRvTmV3RG9jdW1lbnRDb250ZXh0ID0gb01haW5MaXN0QmluZGluZy5jcmVhdGUobVBhcmFtZXRlcnMuZGF0YSwgdHJ1ZSwgbVBhcmFtZXRlcnMuY3JlYXRlQXRFbmQpO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdGhhdC5vbkFmdGVyQ3JlYXRlQ29tcGxldGlvbihvTWFpbkxpc3RCaW5kaW5nLCBvTmV3RG9jdW1lbnRDb250ZXh0LCBtUGFyYW1ldGVycyk7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdExvZy5lcnJvcihcIkVycm9yIHdoaWxlIGNyZWF0aW5nIHRoZSBuZXcgZG9jdW1lbnRcIiwgb0Vycm9yKTtcblx0XHRcdFx0XHR0aHJvdyBvRXJyb3I7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gb0NyZWF0aW9uUHJvbWlzZVxuXHRcdFx0LnRoZW4oZnVuY3Rpb24ob1Jlc3VsdDogYW55KSB7XG5cdFx0XHRcdGlmICghb01haW5MaXN0QmluZGluZy5pc1JlbGF0aXZlKCkpIHtcblx0XHRcdFx0XHQvLyB0aGUgY3JlYXRlIG1vZGUgc2hhbGwgY3VycmVudGx5IG9ubHkgYmUgc2V0IG9uIGNyZWF0aW5nIGEgcm9vdCBkb2N1bWVudFxuXHRcdFx0XHRcdHRoYXQuX2JDcmVhdGVNb2RlID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRvTmV3RG9jdW1lbnRDb250ZXh0ID0gb05ld0RvY3VtZW50Q29udGV4dCB8fCAob1Jlc3VsdCAmJiBvUmVzdWx0LnJlc3BvbnNlKTtcblx0XHRcdFx0Ly8gVE9ETzogd2hlcmUgZG9lcyB0aGlzIG9uZSBjb21pbmcgZnJvbT8/P1xuXHRcdFx0XHRpZiAob1Jlc3VsdCAmJiBvUmVzdWx0LmJDb25zaWRlckRvY3VtZW50TW9kaWZpZWQpIHtcblx0XHRcdFx0XHR0aGF0LmhhbmRsZURvY3VtZW50TW9kaWZpY2F0aW9ucygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZURpYWxvZygpLnRoZW4oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9OZXdEb2N1bWVudENvbnRleHQ7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VEaWFsb2coKS50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdC8vIGZvciBpbnN0YW5jZSwgb24gY2FuY2VsIG9mIGNyZWF0ZSBkaWFsb2csIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkXG5cdFx0XHRcdFx0Ly8gYSByZXR1cm4gaGVyZSB3b3VsZCByZXN0b3JlIHRoZSBwcm9taXNlIGNoYWluIGFuZCByZXN1bHQgaW4gZXJyb3JzIHdoaWxlIHJvdXRpbmdcblx0XHRcdFx0XHQvLyBzb2x1dGlvbiAtICByZWplY3QgaGVyZSBhcyB3ZWxsXG5cdFx0XHRcdFx0aWYgKG9FcnJvciAmJiBvRXJyb3IuYkRlbGV0ZVRyYW5zaWVudENvbnRleHQgJiYgb05ld0RvY3VtZW50Q29udGV4dC5pc1RyYW5zaWVudCgpKSB7XG5cdFx0XHRcdFx0XHQvLyBUaGlzIGlzIGEgd29ya2Fyb3VuZCBzdWdnZXN0ZWQgYnkgbW9kZWwgYXMgQ29udGV4dC5kZWxldGUgcmVzdWx0cyBpbiBhbiBlcnJvclxuXHRcdFx0XHRcdFx0Ly8gVE9ETzogcmVtb3ZlIHRoZSAkZGlyZWN0IG9uY2UgbW9kZWwgcmVzb2x2ZXMgdGhpcyBpc3N1ZVxuXHRcdFx0XHRcdFx0Ly8gdGhpcyBsaW5lIHNob3dzIHRoZSBleHBlY3RlZCBjb25zb2xlIGVycm9yIFVuY2F1Z2h0IChpbiBwcm9taXNlKSBFcnJvcjogUmVxdWVzdCBjYW5jZWxlZDogUE9TVCBUcmF2ZWw7IGdyb3VwOiBzdWJtaXRMYXRlclxuXHRcdFx0XHRcdFx0b05ld0RvY3VtZW50Q29udGV4dC5kZWxldGUoXCIkZGlyZWN0XCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3Qob0Vycm9yKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoYXQub0xvY2tPYmplY3QsIHNCdXN5UGF0aCk7XG5cdFx0XHR9KTtcblx0fVxuXHQvKipcblx0ICogRmluZCB0aGUgYWN0aXZlIGNvbnRleHRzIG9mIHRoZSBkb2N1bWVudHMsIG9ubHkgZm9yIHRoZSBkcmFmdCByb290cy5cblx0ICpcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBzdGF0aWNcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dFtdfSBhQ29udGV4dHMgQ29udGV4dHMgRWl0aGVyIG9uZSBjb250ZXh0IG9yIGFuIGFycmF5IHdpdGggY29udGV4dHMgdG8gYmUgZGVsZXRlZFxuXHQgKiBAcGFyYW0gYkZpbmRBY3RpdmVDb250ZXh0c1xuXHQgKiBAcmV0dXJucyB7QXJyYXl9IEFycmF5IG9mIHRoZSBhY3RpdmUgY29udGV4dHNcblx0ICovXG5cdGZpbmRBY3RpdmVEcmFmdFJvb3RDb250ZXh0cyhhQ29udGV4dHM6IGFueVtdLCBiRmluZEFjdGl2ZUNvbnRleHRzOiBhbnkpIHtcblx0XHRpZiAoIWJGaW5kQWN0aXZlQ29udGV4dHMpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblx0XHR9XG5cdFx0Y29uc3QgYWN0aXZlQ29udGV4dHMgPSBhQ29udGV4dHMucmVkdWNlKGZ1bmN0aW9uKGFSZXN1bHQ6IGFueSwgb0NvbnRleHQ6IGFueSkge1xuXHRcdFx0Y29uc3Qgb01ldGFNb2RlbCA9IG9Db250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCk7XG5cdFx0XHRjb25zdCBzTWV0YVBhdGggPSBvTWV0YU1vZGVsLmdldE1ldGFQYXRoKG9Db250ZXh0LmdldFBhdGgoKSk7XG5cdFx0XHRpZiAob01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRyYWZ0Um9vdFwiKSkge1xuXHRcdFx0XHRjb25zdCBiSXNBY3RpdmVFbnRpdHkgPSBvQ29udGV4dC5nZXRPYmplY3QoKS5Jc0FjdGl2ZUVudGl0eSxcblx0XHRcdFx0XHRiSGFzQWN0aXZlRW50aXR5ID0gb0NvbnRleHQuZ2V0T2JqZWN0KCkuSGFzQWN0aXZlRW50aXR5O1xuXHRcdFx0XHRpZiAoIWJJc0FjdGl2ZUVudGl0eSAmJiBiSGFzQWN0aXZlRW50aXR5KSB7XG5cdFx0XHRcdFx0Y29uc3Qgb0FjdGl2ZUNvbnRleHQgPSBvQ29udGV4dFxuXHRcdFx0XHRcdFx0LmdldE1vZGVsKClcblx0XHRcdFx0XHRcdC5iaW5kQ29udGV4dChvQ29udGV4dC5nZXRQYXRoKCkgKyBcIi9TaWJsaW5nRW50aXR5XCIpXG5cdFx0XHRcdFx0XHQuZ2V0Qm91bmRDb250ZXh0KCk7XG5cdFx0XHRcdFx0YVJlc3VsdC5wdXNoKG9BY3RpdmVDb250ZXh0KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGFSZXN1bHQ7XG5cdFx0fSwgW10pO1xuXHRcdHJldHVybiBQcm9taXNlLmFsbChcblx0XHRcdGFjdGl2ZUNvbnRleHRzLm1hcChmdW5jdGlvbihvQ29udGV4dDogYW55KSB7XG5cdFx0XHRcdHJldHVybiBvQ29udGV4dC5yZXF1ZXN0Q2Fub25pY2FsUGF0aCgpLnRoZW4oXG5cdFx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gb0NvbnRleHQ7XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdCk7XG5cdFx0XHR9KVxuXHRcdCk7XG5cdH1cblx0YWZ0ZXJEZWxldGVQcm9jZXNzKG1QYXJhbWV0ZXJzOiBhbnksIGNoZWNrQm94OiBhbnksIGFDb250ZXh0czogYW55LCBvUmVzb3VyY2VCdW5kbGU6IGFueSkge1xuXHRcdGNvbnN0IG9JbnRlcm5hbE1vZGVsQ29udGV4dCA9IG1QYXJhbWV0ZXJzLmludGVybmFsTW9kZWxDb250ZXh0O1xuXHRcdGlmIChvSW50ZXJuYWxNb2RlbENvbnRleHQgJiYgb0ludGVybmFsTW9kZWxDb250ZXh0LmdldFByb3BlcnR5KFwiZGVsZXRlRW5hYmxlZFwiKSAhPSB1bmRlZmluZWQpIHtcblx0XHRcdGlmIChjaGVja0JveC5pc0NoZWNrQm94VmlzaWJsZSA9PT0gdHJ1ZSAmJiBjaGVja0JveC5pc0NoZWNrQm94U2VsZWN0ZWQgPT09IGZhbHNlKSB7XG5cdFx0XHRcdC8vaWYgdW5zYXZlZCBvYmplY3RzIGFyZSBub3QgZGVsZXRlZCB0aGVuIHdlIG5lZWQgdG8gc2V0IHRoZSBlbmFibGVkIHRvIHRydWUgYW5kIHVwZGF0ZSB0aGUgbW9kZWwgZGF0YSBmb3IgbmV4dCBkZWxldGlvblxuXHRcdFx0XHRvSW50ZXJuYWxNb2RlbENvbnRleHQuc2V0UHJvcGVydHkoXCJkZWxldGVFbmFibGVkXCIsIHRydWUpO1xuXHRcdFx0XHRjb25zdCBvYmogPSBPYmplY3QuYXNzaWduKG9JbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRPYmplY3QoKSwge30pO1xuXHRcdFx0XHRvYmouc2VsZWN0ZWRDb250ZXh0cyA9IG9iai5zZWxlY3RlZENvbnRleHRzLmZpbHRlcihmdW5jdGlvbihlbGVtZW50OiBhbnkpIHtcblx0XHRcdFx0XHRyZXR1cm4gb2JqLmRlbGV0YWJsZUNvbnRleHRzLmluZGV4T2YoZWxlbWVudCkgPT09IC0xO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0b2JqLmRlbGV0YWJsZUNvbnRleHRzID0gW107XG5cdFx0XHRcdG9iai5zZWxlY3RlZENvbnRleHRzID0gW107XG5cdFx0XHRcdG9iai5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgPSBvYmouc2VsZWN0ZWRDb250ZXh0cy5sZW5ndGg7XG5cdFx0XHRcdG9JbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcIlwiLCBvYmopO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b0ludGVybmFsTW9kZWxDb250ZXh0LnNldFByb3BlcnR5KFwiZGVsZXRlRW5hYmxlZFwiLCBmYWxzZSk7XG5cdFx0XHRcdG9JbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcInNlbGVjdGVkQ29udGV4dHNcIiwgW10pO1xuXHRcdFx0XHRvSW50ZXJuYWxNb2RlbENvbnRleHQuc2V0UHJvcGVydHkoXCJudW1iZXJPZlNlbGVjdGVkQ29udGV4dHNcIiwgMCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChhQ29udGV4dHMubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRNZXNzYWdlVG9hc3Quc2hvdyhcblx0XHRcdFx0Q29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9ERUxFVEVfVE9BU1RfU0lOR1VMQVJcIixcblx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHRtUGFyYW1ldGVycy5lbnRpdHlTZXROYW1lXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdE1lc3NhZ2VUb2FzdC5zaG93KFxuXHRcdFx0XHRDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0RFTEVURV9UT0FTVF9QTFVSQUxcIixcblx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHRtUGFyYW1ldGVycy5lbnRpdHlTZXROYW1lXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cdC8qKlxuXHQgKiBEZWxldGUgb25lIG9yIG11bHRpcGxlIGRvY3VtZW50KHMpLlxuXHQgKlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHN0YXRpY1xuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0fSB2Q29udGV4dHMgQ29udGV4dHMgRWl0aGVyIG9uZSBjb250ZXh0IG9yIGFuIGFycmF5IHdpdGggY29udGV4dHMgdG8gYmUgZGVsZXRlZFxuXHQgKiBAcGFyYW0ge29iamVjdH0gbVBhcmFtZXRlcnMgT3B0aW9uYWwsIGNhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1QYXJhbWV0ZXJzLnRpdGxlIFRpdGxlIG9mIHRoZSBvYmplY3QgdG8gYmUgZGVsZXRlZFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbVBhcmFtZXRlcnMuZGVzY3JpcHRpb24gRGVzY3JpcHRpb24gb2YgdGhlIG9iamVjdCB0byBiZSBkZWxldGVkXG5cdCAqIEBwYXJhbSB7aW50ZWdlcn0gbVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzIE51bWJlciBvZiBvYmplY3RzIHNlbGVjdGVkXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gbVBhcmFtZXRlcnMubm9EaWFsb2cgVG8gZGlzYWJsZSB0aGUgY29uZmlybWF0aW9uIGRpYWxvZ1xuXHQgKiBAcGFyYW0gb1Jlc291cmNlQnVuZGxlXG5cdCAqIEBwYXJhbSBtZXNzYWdlSGFuZGxlclxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX1cblx0ICovXG5cdGRlbGV0ZURvY3VtZW50KHZDb250ZXh0czogYW55LCBtUGFyYW1ldGVyczogYW55LCBvUmVzb3VyY2VCdW5kbGU6IGFueSwgbWVzc2FnZUhhbmRsZXI6IGFueSkge1xuXHRcdGxldCBmblJlamVjdDogRnVuY3Rpb24sXG5cdFx0XHRmblJlc29sdmU6IEZ1bmN0aW9uLFxuXHRcdFx0YURlbGV0YWJsZUNvbnRleHRzOiBhbnlbXSA9IFtdLFxuXHRcdFx0aXNDaGVja0JveFZpc2libGUgPSBmYWxzZSxcblx0XHRcdGlzTG9ja2VkVGV4dFZpc2libGUgPSBmYWxzZSxcblx0XHRcdGNhbm5vdEJlRGVsZXRlZFRleHRWaXNpYmxlID0gZmFsc2UsXG5cdFx0XHRpc0NoZWNrQm94U2VsZWN0ZWQ6IGJvb2xlYW4sXG5cdFx0XHRiRGlhbG9nQ29uZmlybWVkID0gZmFsc2U7XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG5cdFx0Y29uc3QgdGhhdCA9IHRoaXMsXG5cdFx0XHRvUmVzb3VyY2VCdW5kbGVDb3JlID0gc2FwLnVpLmdldENvcmUoKS5nZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUoXCJzYXAuZmUuY29yZVwiKSBhcyBSZXNvdXJjZUJ1bmRsZTtcblx0XHRsZXQgYVBhcmFtcztcblx0XHRsZXQgb0RlbGV0ZU1lc3NhZ2U6IGFueSA9IHtcblx0XHRcdHRpdGxlOiBvUmVzb3VyY2VCdW5kbGVDb3JlLmdldFRleHQoXCJDX0NPTU1PTl9PQkpFQ1RfUEFHRV9ERUxFVEVcIilcblx0XHR9O1xuXHRcdEJ1c3lMb2NrZXIubG9jayh0aGlzLm9Mb2NrT2JqZWN0KTtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkodkNvbnRleHRzKSkge1xuXHRcdFx0dkNvbnRleHRzID0gW3ZDb250ZXh0c107XG5cdFx0fVxuXHRcdFByb21pc2UucmVzb2x2ZSh0aGlzLmdldFByb2dyYW1taW5nTW9kZWwodkNvbnRleHRzWzBdKSlcblx0XHRcdC50aGVuKGZ1bmN0aW9uKHNQcm9ncmFtbWluZ01vZGVsOiBhbnkpIHtcblx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzKSB7XG5cdFx0XHRcdFx0aWYgKCFtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMpIHtcblx0XHRcdFx0XHRcdGlmIChzUHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdCkge1xuXHRcdFx0XHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHZDb250ZXh0cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG9Db250ZXh0RGF0YSA9IHZDb250ZXh0c1tpXS5nZXRPYmplY3QoKTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0XHRcdFx0XHRvQ29udGV4dERhdGEuSXNBY3RpdmVFbnRpdHkgPT09IHRydWUgJiZcblx0XHRcdFx0XHRcdFx0XHRcdG9Db250ZXh0RGF0YS5IYXNEcmFmdEVudGl0eSA9PT0gdHJ1ZSAmJlxuXHRcdFx0XHRcdFx0XHRcdFx0b0NvbnRleHREYXRhLkRyYWZ0QWRtaW5pc3RyYXRpdmVEYXRhICYmXG5cdFx0XHRcdFx0XHRcdFx0XHRvQ29udGV4dERhdGEuRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEuSW5Qcm9jZXNzQnlVc2VyICYmXG5cdFx0XHRcdFx0XHRcdFx0XHQhb0NvbnRleHREYXRhLkRyYWZ0QWRtaW5pc3RyYXRpdmVEYXRhLkRyYWZ0SXNDcmVhdGVkQnlNZVxuXHRcdFx0XHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0TWVzc2FnZUJveC5zaG93KFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfU0lOR0xFX09CSkVDVF9MT0NLRURcIixcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGVcblx0XHRcdFx0XHRcdFx0XHRcdFx0KSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRpdGxlOiBvUmVzb3VyY2VCdW5kbGVDb3JlLmdldFRleHQoXCJDX0NPTU1PTl9PQkpFQ1RfUEFHRV9ERUxFVEVcIiksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b25DbG9zZTogZm5SZWplY3Rcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzID0gZ2V0UGFyYW1ldGVycyhtUGFyYW1ldGVycyk7XG5cdFx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMudGl0bGUpIHtcblx0XHRcdFx0XHRcdFx0YVBhcmFtcyA9IFttUGFyYW1ldGVycy50aXRsZSwgbVBhcmFtZXRlcnMuZGVzY3JpcHRpb25dO1xuXHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS50ZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX09CSkVDVElORk9cIixcblx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRcdFx0YVBhcmFtcyxcblx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5lbnRpdHlTZXROYW1lXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS50ZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX09CSkVDVFRJVExFX1NJTkdVTEFSXCIsXG5cdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMgPSB2Q29udGV4dHM7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlID0ge1xuXHRcdFx0XHRcdFx0XHR0aXRsZTogb1Jlc291cmNlQnVuZGxlQ29yZS5nZXRUZXh0KFwiQ19DT01NT05fT0JKRUNUX1BBR0VfREVMRVRFXCIpXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0cyA9PT0gMSAmJiBtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgPT09IHZDb250ZXh0cy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0YURlbGV0YWJsZUNvbnRleHRzID0gdkNvbnRleHRzO1xuXHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS50ZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX09CSkVDVFRJVExFX1NJTkdVTEFSXCIsXG5cdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmIChtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgPT09IDEgJiYgbVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRcdFx0XHQvL29ubHkgb25lIHVuc2F2ZWQgb2JqZWN0XG5cdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cyA9IG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cztcblx0XHRcdFx0XHRcdFx0Y29uc3QgZHJhZnRBZG1pbkRhdGEgPSBhRGVsZXRhYmxlQ29udGV4dHNbMF0uZ2V0T2JqZWN0KClbXCJEcmFmdEFkbWluaXN0cmF0aXZlRGF0YVwiXTtcblx0XHRcdFx0XHRcdFx0bGV0IHNMYXN0Q2hhbmdlZEJ5VXNlciA9IFwiXCI7XG5cdFx0XHRcdFx0XHRcdGlmIChkcmFmdEFkbWluRGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdHNMYXN0Q2hhbmdlZEJ5VXNlciA9XG5cdFx0XHRcdFx0XHRcdFx0XHRkcmFmdEFkbWluRGF0YVtcIkxhc3RDaGFuZ2VkQnlVc2VyRGVzY3JpcHRpb25cIl0gfHwgZHJhZnRBZG1pbkRhdGFbXCJMYXN0Q2hhbmdlZEJ5VXNlclwiXSB8fCBcIlwiO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGFQYXJhbXMgPSBbc0xhc3RDaGFuZ2VkQnlVc2VyXTtcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9VTlNBVkVEX0NIQU5HRVNcIixcblx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRcdFx0YVBhcmFtc1xuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmIChtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgPT09IG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0Ly9vbmx5IG11bHRpcGxlIHVuc2F2ZWQgb2JqZWN0c1xuXHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMgPSBtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHM7XG5cdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLnRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfVU5TQVZFRF9DSEFOR0VTX01VTFRJUExFX09CSkVDVFNcIixcblx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGVcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoXG5cdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0cyA9PT1cblx0XHRcdFx0XHRcdFx0dkNvbnRleHRzLmNvbmNhdChtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMuY29uY2F0KG1QYXJhbWV0ZXJzLmxvY2tlZENvbnRleHRzKSkubGVuZ3RoXG5cdFx0XHRcdFx0XHQpIHtcblx0XHRcdFx0XHRcdFx0Ly9vbmx5IHVuc2F2ZWQsIGxvY2tlZCAsZGVsZXRhYmxlIG9iamVjdHMgYnV0IG5vdCBub24tZGVsZXRhYmxlIG9iamVjdHNcblx0XHRcdFx0XHRcdFx0YURlbGV0YWJsZUNvbnRleHRzID0gdkNvbnRleHRzLmNvbmNhdChtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMpO1xuXHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS50ZXh0ID1cblx0XHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMubGVuZ3RoID09PSAxXG5cdFx0XHRcdFx0XHRcdFx0XHQ/IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RUSVRMRV9TSU5HVUxBUlwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmVudGl0eVNldE5hbWVcblx0XHRcdFx0XHRcdFx0XHRcdCAgKVxuXHRcdFx0XHRcdFx0XHRcdFx0OiBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUVElUTEVfUExVUkFMXCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZVxuXHRcdFx0XHRcdFx0XHRcdFx0ICApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly9pZiBub24tZGVsZXRhYmxlIG9iamVjdHMgZXhpc3RzIGFsb25nIHdpdGggYW55IG9mIHVuc2F2ZWQgLGRlbGV0YWJsZSBvYmplY3RzXG5cdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cyA9IHZDb250ZXh0cy5jb25jYXQobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzKTtcblx0XHRcdFx0XHRcdFx0Y2Fubm90QmVEZWxldGVkVGV4dFZpc2libGUgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS50ZXh0ID1cblx0XHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMubGVuZ3RoID09PSAxXG5cdFx0XHRcdFx0XHRcdFx0XHQ/IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RUSVRMRV9TSU5HVUxBUl9OT05fREVMRVRBQkxFXCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZVxuXHRcdFx0XHRcdFx0XHRcdFx0ICApXG5cdFx0XHRcdFx0XHRcdFx0XHQ6IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RUSVRMRV9QTFVSQUxfTk9OX0RFTEVUQUJMRVwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmVudGl0eVNldE5hbWVcblx0XHRcdFx0XHRcdFx0XHRcdCAgKTtcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2Uubm9uRGVsZXRhYmxlVGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RJTkZPX0FORF9GRVdfT0JKRUNUU19OT05fREVMRVRBQkxFXCIsXG5cdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdFtcblx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0cyAtIHZDb250ZXh0cy5jb25jYXQobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzKS5sZW5ndGgsXG5cdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHNcblx0XHRcdFx0XHRcdFx0XHRdXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMubG9ja2VkQ29udGV4dHMubGVuZ3RoID09IDEpIHtcblx0XHRcdFx0XHRcdFx0Ly9zZXR0aW5nIHRoZSBsb2NrZWQgdGV4dCBpZiBsb2NrZWQgb2JqZWN0cyBleGlzdFxuXHRcdFx0XHRcdFx0XHRpc0xvY2tlZFRleHRWaXNpYmxlID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2Uubm9uRGVsZXRhYmxlVGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RJTkZPX0FORF9PTkVfT0JKRUNUX0xPQ0tFRFwiLFxuXHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRbbVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzXVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLmxvY2tlZENvbnRleHRzLmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0XHRcdFx0Ly9zZXR0aW5nIHRoZSBsb2NrZWQgdGV4dCBpZiBsb2NrZWQgb2JqZWN0cyBleGlzdFxuXHRcdFx0XHRcdFx0XHRpc0xvY2tlZFRleHRWaXNpYmxlID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2Uubm9uRGVsZXRhYmxlVGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RJTkZPX0FORF9GRVdfT0JKRUNUU19MT0NLRURcIixcblx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRcdFx0W21QYXJhbWV0ZXJzLmxvY2tlZENvbnRleHRzLmxlbmd0aCwgbVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzXVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMubGVuZ3RoID4gMCAmJlxuXHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMubGVuZ3RoICE9PSBtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHNcblx0XHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0XHRcdFx0KGNhbm5vdEJlRGVsZXRlZFRleHRWaXNpYmxlIHx8IGlzTG9ja2VkVGV4dFZpc2libGUpICYmXG5cdFx0XHRcdFx0XHRcdFx0YURlbGV0YWJsZUNvbnRleHRzLmxlbmd0aCA9PT0gbVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmxlbmd0aFxuXHRcdFx0XHRcdFx0XHQpIHtcblx0XHRcdFx0XHRcdFx0XHQvL2lmIG9ubHkgdW5zYXZlZCBhbmQgZWl0aGVyIG9yIGJvdGggb2YgbG9ja2VkIGFuZCBub24tZGVsZXRhYmxlIG9iamVjdHMgZXhpc3QgdGhlbiB3ZSBoaWRlIHRoZSBjaGVjayBib3hcblx0XHRcdFx0XHRcdFx0XHRpc0NoZWNrQm94VmlzaWJsZSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cyA9IG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cztcblx0XHRcdFx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfVU5TQVZFRF9BTkRfRkVXX09CSkVDVFNfTE9DS0VEX1NJTkdVTEFSXCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZVxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfVU5TQVZFRF9BTkRfRkVXX09CSkVDVFNfTE9DS0VEX1BMVVJBTFwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGVcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS5jaGVja0JveFRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX09CSkVDVElORk9fQU5EX0ZFV19PQkpFQ1RTX1VOU0FWRURfU0lOR1VMQVJcIixcblx0XHRcdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlXG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS5jaGVja0JveFRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX09CSkVDVElORk9fQU5EX0ZFV19PQkpFQ1RTX1VOU0FWRURfUExVUkFMXCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZVxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0aXNDaGVja0JveFZpc2libGUgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAoY2Fubm90QmVEZWxldGVkVGV4dFZpc2libGUgJiYgaXNMb2NrZWRUZXh0VmlzaWJsZSkge1xuXHRcdFx0XHRcdFx0XHQvL2lmIGJvdGggbG9ja2VkIGFuZCBub24tZGVsZXRhYmxlIG9iamVjdHMgZXhpc3QgYWxvbmcgd2l0aCBkZWxldGFibGUgb2JqZWN0c1xuXHRcdFx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS5ub25EZWxldGFibGVUZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUSU5GT19BTkRfRkVXX09CSkVDVFNfTE9DS0VEX0FORF9OT05fREVMRVRBQkxFXCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRcdFx0XHRbXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0cyAtXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dkNvbnRleHRzLmNvbmNhdChtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMpLmxlbmd0aCAtXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMubG9ja2VkQ29udGV4dHMubGVuZ3RoLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5sb2NrZWRDb250ZXh0cy5sZW5ndGgsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0c1xuXHRcdFx0XHRcdFx0XHRcdFx0XVxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cy5sZW5ndGggPT0gMSkge1xuXHRcdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLm5vbkRlbGV0YWJsZVRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RJTkZPX0FORF9PTkVfT0JKRUNUX0xPQ0tFRF9BTkRfTk9OX0RFTEVUQUJMRVwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdFx0W1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgLVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHZDb250ZXh0cy5jb25jYXQobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzKS5sZW5ndGggLVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmxvY2tlZENvbnRleHRzLmxlbmd0aCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzXG5cdFx0XHRcdFx0XHRcdFx0XHRdXG5cdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRsZXQgb05vbkRlbGV0YWJsZU1lc3NhZ2VUZXh0Q29udHJvbCwgb0RlbGV0ZU1lc3NhZ2VUZXh0Q29udHJvbDtcblx0XHRcdFx0Y29uc3Qgb0NvbnRlbnQgPSBuZXcgVkJveCh7XG5cdFx0XHRcdFx0aXRlbXM6IFtcblx0XHRcdFx0XHRcdChvTm9uRGVsZXRhYmxlTWVzc2FnZVRleHRDb250cm9sID0gbmV3IFRleHQoe1xuXHRcdFx0XHRcdFx0XHR0ZXh0OiBvRGVsZXRlTWVzc2FnZS5ub25EZWxldGFibGVUZXh0LFxuXHRcdFx0XHRcdFx0XHR2aXNpYmxlOiBpc0xvY2tlZFRleHRWaXNpYmxlIHx8IGNhbm5vdEJlRGVsZXRlZFRleHRWaXNpYmxlXG5cdFx0XHRcdFx0XHR9KSksXG5cdFx0XHRcdFx0XHQob0RlbGV0ZU1lc3NhZ2VUZXh0Q29udHJvbCA9IG5ldyBUZXh0KHtcblx0XHRcdFx0XHRcdFx0dGV4dDogb0RlbGV0ZU1lc3NhZ2UudGV4dFxuXHRcdFx0XHRcdFx0fSkpLFxuXHRcdFx0XHRcdFx0bmV3IENoZWNrQm94KHtcblx0XHRcdFx0XHRcdFx0dGV4dDogb0RlbGV0ZU1lc3NhZ2UuY2hlY2tCb3hUZXh0LFxuXHRcdFx0XHRcdFx0XHRzZWxlY3RlZDogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0c2VsZWN0OiBmdW5jdGlvbihvRXZlbnQ6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHNlbGVjdGVkID0gb0V2ZW50LmdldFNvdXJjZSgpLmdldFNlbGVjdGVkKCk7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMgPSB2Q29udGV4dHMuY29uY2F0KG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRpc0NoZWNrQm94U2VsZWN0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMgPSB2Q29udGV4dHM7XG5cdFx0XHRcdFx0XHRcdFx0XHRpc0NoZWNrQm94U2VsZWN0ZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdHZpc2libGU6IGlzQ2hlY2tCb3hWaXNpYmxlXG5cdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdF1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdGNvbnN0IHNUaXRsZSA9IG9SZXNvdXJjZUJ1bmRsZUNvcmUuZ2V0VGV4dChcIkNfQ09NTU9OX09CSkVDVF9QQUdFX0RFTEVURVwiKTtcblx0XHRcdFx0Y29uc3QgZm5Db25maXJtID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0YkRpYWxvZ0NvbmZpcm1lZCA9IHRydWU7XG5cdFx0XHRcdFx0QnVzeUxvY2tlci5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0XHRcdGNvbnN0IGFDb250ZXh0cyA9IGFEZWxldGFibGVDb250ZXh0cztcblx0XHRcdFx0XHRsZXQgb25CZWZvcmVEZWxldGVQcm9taXNlO1xuXHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy5iZWZvcmVEZWxldGVDYWxsQmFjaykge1xuXHRcdFx0XHRcdFx0b25CZWZvcmVEZWxldGVQcm9taXNlID0gbVBhcmFtZXRlcnMuYmVmb3JlRGVsZXRlQ2FsbEJhY2soeyBjb250ZXh0czogYUNvbnRleHRzIH0pO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRvbkJlZm9yZURlbGV0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIG9uQmVmb3JlRGVsZXRlUHJvbWlzZVxuXHRcdFx0XHRcdFx0LnRoZW4odGhhdC5maW5kQWN0aXZlRHJhZnRSb290Q29udGV4dHMuYmluZCh0aGF0LCBhQ29udGV4dHMsIG1QYXJhbWV0ZXJzLmJGaW5kQWN0aXZlQ29udGV4dHMpKVxuXHRcdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24oYWN0aXZlQ29udGV4dHM6IGFueSkge1xuXHRcdFx0XHRcdFx0XHQvL21ha2Ugc3VyZSB0byBmZXRjaCB0aGUgYWN0aXZlIGNvbnRleHRzIGJlZm9yZSBkZWxldGluZyB0aGUgZHJhZnRzXG5cdFx0XHRcdFx0XHRcdHJldHVybiBQcm9taXNlLmFsbChcblx0XHRcdFx0XHRcdFx0XHRhQ29udGV4dHMubWFwKGZ1bmN0aW9uKG9Db250ZXh0OiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdC8vZGVsZXRlIHRoZSBkcmFmdFxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGRyYWZ0LmRlbGV0ZURyYWZ0KG9Db250ZXh0KTtcblx0XHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VzKCkudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gcmUtdGhyb3cgZXJyb3IgdG8gZW5mb3JjZSByZWplY3RpbmcgdGhlIGdlbmVyYWwgcHJvbWlzZVxuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aHJvdyBvRXJyb3I7XG5cdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29uc3QgY2hlY2tCb3ggPSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFwiaXNDaGVja0JveFZpc2libGVcIjogaXNDaGVja0JveFZpc2libGUsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFwiaXNDaGVja0JveFNlbGVjdGVkXCI6IGlzQ2hlY2tCb3hTZWxlY3RlZFxuXHRcdFx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdFx0XHRcdGlmIChhY3RpdmVDb250ZXh0cyAmJiBhY3RpdmVDb250ZXh0cy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIFByb21pc2UuYWxsKFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGFjdGl2ZUNvbnRleHRzLm1hcChmdW5jdGlvbihvQ29udGV4dDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0NvbnRleHQuZGVsZXRlKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHRcdFx0KS50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoYXQuYWZ0ZXJEZWxldGVQcm9jZXNzKG1QYXJhbWV0ZXJzLCBjaGVja0JveCwgYUNvbnRleHRzLCBvUmVzb3VyY2VCdW5kbGUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZURpYWxvZygpLnRoZW4oZm5SZXNvbHZlKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aGF0LmFmdGVyRGVsZXRlUHJvY2VzcyhtUGFyYW1ldGVycywgY2hlY2tCb3gsIGFDb250ZXh0cywgb1Jlc291cmNlQnVuZGxlKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VIYW5kbGVyLnNob3dNZXNzYWdlRGlhbG9nKCkudGhlbihmblJlc29sdmUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0Zm5SZWplY3QoKTtcblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHQuZmluYWxseShmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fTtcblx0XHRcdFx0Y29uc3Qgb0RpYWxvZyA9IG5ldyBEaWFsb2coe1xuXHRcdFx0XHRcdHRpdGxlOiBzVGl0bGUsXG5cdFx0XHRcdFx0c3RhdGU6IFwiV2FybmluZ1wiLFxuXHRcdFx0XHRcdGNvbnRlbnQ6IFtvQ29udGVudF0sXG5cdFx0XHRcdFx0YXJpYUxhYmVsbGVkQnk6IG9Ob25EZWxldGFibGVNZXNzYWdlVGV4dENvbnRyb2wuZ2V0VmlzaWJsZSgpXG5cdFx0XHRcdFx0XHQ/IFtvTm9uRGVsZXRhYmxlTWVzc2FnZVRleHRDb250cm9sLCBvRGVsZXRlTWVzc2FnZVRleHRDb250cm9sXVxuXHRcdFx0XHRcdFx0OiBvRGVsZXRlTWVzc2FnZVRleHRDb250cm9sLFxuXHRcdFx0XHRcdGJlZ2luQnV0dG9uOiBuZXcgQnV0dG9uKHtcblx0XHRcdFx0XHRcdHRleHQ6IG9SZXNvdXJjZUJ1bmRsZUNvcmUuZ2V0VGV4dChcIkNfQ09NTU9OX09CSkVDVF9QQUdFX0RFTEVURVwiKSxcblx0XHRcdFx0XHRcdHR5cGU6IFwiRW1waGFzaXplZFwiLFxuXHRcdFx0XHRcdFx0cHJlc3M6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRvRGlhbG9nLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBmbkNvbmZpcm0oKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRlbmRCdXR0b246IG5ldyBCdXR0b24oe1xuXHRcdFx0XHRcdFx0dGV4dDogQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXCJDX0NPTU1PTl9PQkpFQ1RfUEFHRV9DQU5DRUxcIiwgb1Jlc291cmNlQnVuZGxlKSxcblx0XHRcdFx0XHRcdHByZXNzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0b0RpYWxvZy5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdGFmdGVyQ2xvc2U6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0b0RpYWxvZy5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHQvLyBpZiBkaWFsb2cgaXMgY2xvc2VkIHVuY29uZmlybWVkIChlLmcuIHZpYSBcIkNhbmNlbFwiIG9yIEVzY2FwZSBidXR0b24pLCBlbnN1cmUgdG8gcmVqZWN0IHByb21pc2Vcblx0XHRcdFx0XHRcdGlmICghYkRpYWxvZ0NvbmZpcm1lZCkge1xuXHRcdFx0XHRcdFx0XHRmblJlamVjdCgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBhcyBhbnkpO1xuXHRcdFx0XHRpZiAobVBhcmFtZXRlcnMubm9EaWFsb2cpIHtcblx0XHRcdFx0XHRyZXR1cm4gZm5Db25maXJtKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0b0RpYWxvZy5hZGRTdHlsZUNsYXNzKFwic2FwVWlDb250ZW50UGFkZGluZ1wiKTtcblx0XHRcdFx0XHRvRGlhbG9nLm9wZW4oKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5maW5hbGx5KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdExvZy53YXJuaW5nKFwiQ291bGRuJ3QgZ2V0IFByb2dyYW1taW5nIG1vZGVsXCIpO1xuXHRcdFx0XHRmblJlamVjdCgpO1xuXHRcdFx0fSk7XG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmU6ICh2YWx1ZTogYW55KSA9PiB2b2lkLCByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWQpIHtcblx0XHRcdGZuUmVqZWN0ID0gcmVqZWN0O1xuXHRcdFx0Zm5SZXNvbHZlID0gcmVzb2x2ZTtcblx0XHR9KTtcblx0fVxuXHQvKipcblx0ICogRWRpdHMgYSBkb2N1bWVudC5cblx0ICpcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBzdGF0aWNcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gb0NvbnRleHQgQ29udGV4dCBvZiB0aGUgYWN0aXZlIGRvY3VtZW50XG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gYlByZXBhcmVPbkVkaXQgQWxzbyBjYWxsIHRoZSAncHJlcGFyZScgYWN0aW9uIGZvciBkcmFmdC1iYXNlZCBkb2N1bWVudHNcblx0ICogQHBhcmFtIHtvYmplY3R9IG9WaWV3IE9iamVjdCBvZiBjdXJyZW50IHZpZXdcblx0ICogQHBhcmFtIG1lc3NhZ2VIYW5kbGVyXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIHdpdGggdGhlIG5ldyBkcmFmdCBjb250ZXh0IGluIGNhc2Ugb2YgZHJhZnQgcHJvZ3JhbW1pbmcgbW9kZWxcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0ZWRpdERvY3VtZW50KG9Db250ZXh0OiBhbnksIGJQcmVwYXJlT25FZGl0OiBib29sZWFuLCBvVmlldzogb2JqZWN0LCBtZXNzYWdlSGFuZGxlcjogYW55KSB7XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG5cdFx0Y29uc3QgdGhhdCA9IHRoaXM7XG5cdFx0Y29uc3Qgc1Byb2dyYW1taW5nTW9kZWwgPSB0aGlzLmdldFByb2dyYW1taW5nTW9kZWwob0NvbnRleHQpO1xuXHRcdGxldCBvRWRpdFByb21pc2U7XG5cdFx0aWYgKCFvQ29udGV4dCkge1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkJpbmRpbmcgY29udGV4dCB0byBhY3RpdmUgZG9jdW1lbnQgaXMgcmVxdWlyZWRcIikpO1xuXHRcdH1cblx0XHR0aGlzLl9iSXNNb2RpZmllZCA9IGZhbHNlO1xuXHRcdEJ1c3lMb2NrZXIubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHQvLyBiZWZvcmUgdHJpZ2dlcmluZyB0aGUgZWRpdCBhY3Rpb24gd2UnbGwgaGF2ZSB0byByZW1vdmUgYWxsIGJvdW5kIHRyYW5zaXRpb24gbWVzc2FnZXNcblx0XHRtZXNzYWdlSGFuZGxlci5yZW1vdmVUcmFuc2l0aW9uTWVzc2FnZXMoKTtcblx0XHRpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuRHJhZnQpIHtcblx0XHRcdG9FZGl0UHJvbWlzZSA9IGRyYWZ0LmNyZWF0ZURyYWZ0RnJvbUFjdGl2ZURvY3VtZW50KG9Db250ZXh0LCB0aGlzLl9nZXRBcHBDb21wb25lbnQoKSwge1xuXHRcdFx0XHRiUHJlc2VydmVDaGFuZ2VzOiB0cnVlLFxuXHRcdFx0XHRiUHJlcGFyZU9uRWRpdDogYlByZXBhcmVPbkVkaXQsXG5cdFx0XHRcdG9WaWV3OiBvVmlld1xuXHRcdFx0fSBhcyBhbnkpO1xuXHRcdH0gZWxzZSBpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuU3RpY2t5KSB7XG5cdFx0XHRvRWRpdFByb21pc2UgPSBzdGlja3kuZWRpdERvY3VtZW50SW5TdGlja3lTZXNzaW9uKG9Db250ZXh0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRWRpdCBpcyBvbmx5IGFsbG93ZWQgZm9yIGRyYWZ0IG9yIHN0aWNreSBzZXNzaW9uIHN1cHBvcnRlZCBzZXJ2aWNlc1wiKSk7XG5cdFx0fVxuXHRcdHJldHVybiBvRWRpdFByb21pc2Vcblx0XHRcdC50aGVuKGZ1bmN0aW9uKG9OZXdDb250ZXh0OiBhbnkpIHtcblx0XHRcdFx0dGhhdC5fYkNyZWF0ZU1vZGUgPSBmYWxzZTtcblx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VIYW5kbGVyLnNob3dNZXNzYWdlRGlhbG9nKCkudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gb05ld0NvbnRleHQ7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChmdW5jdGlvbihlcnI6IGFueSkge1xuXHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VzKCkudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0fSk7XG5cdH1cblx0LyoqXG5cdCAqIENhbmNlbCAnZWRpdCcgbW9kZSBvZiBhIGRvY3VtZW50LlxuXHQgKlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHN0YXRpY1xuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0fSBvQ29udGV4dCBDb250ZXh0IG9mIHRoZSBkb2N1bWVudCB0byBiZSBjYW5jZWxlZCBvciBkZWxldGVkXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbbUluUGFyYW1ldGVyc10gT3B0aW9uYWwsIGNhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczpcblx0ICogQHBhcmFtIHtzYXAubS5CdXR0b259IG1JblBhcmFtZXRlcnMuY2FuY2VsQnV0dG9uIENhbmNlbCBCdXR0b24gb2YgdGhlIGRpc2NhcmQgcG9wb3ZlciAobWFuZGF0b3J5IGZvciBub3cpXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gbUluUGFyYW1ldGVycy5za2lwRGlzY2FyZFBvcG92ZXIgT3B0aW9uYWwsIHN1cHJlc3NlcyB0aGUgZGlzY2FyZCBwb3BvdmVyIGluY2FzZSBvZiBkcmFmdCBhcHBsaWNhdGlvbnMgd2hpbGUgbmF2aWdhdGluZyBvdXQgb2YgT1Bcblx0ICogQHBhcmFtIG9SZXNvdXJjZUJ1bmRsZVxuXHQgKiBAcGFyYW0gbWVzc2FnZUhhbmRsZXJcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgd2l0aCA/Pz9cblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0Y2FuY2VsRG9jdW1lbnQoXG5cdFx0b0NvbnRleHQ6IGFueSxcblx0XHRtSW5QYXJhbWV0ZXJzOiB7IGNhbmNlbEJ1dHRvbjogYW55OyBza2lwRGlzY2FyZFBvcG92ZXI6IGJvb2xlYW4gfSB8IHVuZGVmaW5lZCxcblx0XHRvUmVzb3VyY2VCdW5kbGU6IGFueSxcblx0XHRtZXNzYWdlSGFuZGxlcjogYW55XG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzO1xuXHRcdGxldCBzUHJvZ3JhbW1pbmdNb2RlbDogUHJvZ3JhbW1pbmdNb2RlbFR5cGU7XG5cdFx0Ly9jb250ZXh0IG11c3QgYWx3YXlzIGJlIHBhc3NlZCAtIG1hbmRhdG9yeSBwYXJhbWV0ZXJcblx0XHRpZiAoIW9Db250ZXh0KSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyBjb250ZXh0IGV4aXN0cy4gUGFzcyBhIG1lYW5pbmdmdWwgY29udGV4dFwiKTtcblx0XHR9XG5cdFx0QnVzeUxvY2tlci5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdGNvbnN0IG1QYXJhbWV0ZXJzID0gZ2V0UGFyYW1ldGVycyhtSW5QYXJhbWV0ZXJzKTtcblx0XHRjb25zdCBvUGFyYW1zQ29udGV4dCA9IG9Db250ZXh0LFxuXHRcdFx0b0NhbmNlbEJ1dHRvbiA9IG1QYXJhbWV0ZXJzLmNhbmNlbEJ1dHRvbixcblx0XHRcdG9Nb2RlbCA9IG9QYXJhbXNDb250ZXh0LmdldE1vZGVsKCk7XG5cdFx0bGV0IG9uQmVmb3JlQ2FuY2VsUHJvbWlzZSwgc0Nhbm9uaWNhbFBhdGg6IHN0cmluZztcblx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dCkpXG5cdFx0XHQudGhlbihmdW5jdGlvbihzUE1vZGVsOiBhbnkpIHtcblx0XHRcdFx0c1Byb2dyYW1taW5nTW9kZWwgPSBzUE1vZGVsO1xuXHRcdFx0XHRpZiAoc1BNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdCkge1xuXHRcdFx0XHRcdGNvbnN0IGRyYWZ0RGF0YUNvbnRleHQgPSBvTW9kZWwuYmluZENvbnRleHQob1BhcmFtc0NvbnRleHQuZ2V0UGF0aCgpICsgXCIvRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGFcIikuZ2V0Qm91bmRDb250ZXh0KCk7XG5cdFx0XHRcdFx0aWYgKCF0aGF0Ll9iSXNNb2RpZmllZCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGRyYWZ0RGF0YUNvbnRleHQucmVxdWVzdE9iamVjdCgpLnRoZW4oZnVuY3Rpb24oZHJhZnRBZG1pbkRhdGE6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRpZiAoZHJhZnRBZG1pbkRhdGEpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGF0Ll9iSXNNb2RpZmllZCA9ICEoZHJhZnRBZG1pbkRhdGEuQ3JlYXRpb25EYXRlVGltZSA9PT0gZHJhZnRBZG1pbkRhdGEuTGFzdENoYW5nZURhdGVUaW1lKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICghbVBhcmFtZXRlcnMuc2tpcERpc2NhcmRQb3BvdmVyKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoYXQuX3Nob3dEaXNjYXJkUG9wb3ZlcihvQ2FuY2VsQnV0dG9uLCB0aGF0Ll9iSXNNb2RpZmllZCwgb1Jlc291cmNlQnVuZGxlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLmJlZm9yZUNhbmNlbENhbGxCYWNrKSB7XG5cdFx0XHRcdFx0b25CZWZvcmVDYW5jZWxQcm9taXNlID0gbVBhcmFtZXRlcnMuYmVmb3JlQ2FuY2VsQ2FsbEJhY2soeyBjb250ZXh0OiBvQ29udGV4dCB9KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRvbkJlZm9yZUNhbmNlbFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb25CZWZvcmVDYW5jZWxQcm9taXNlO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVmYXVsdC1jYXNlXG5cdFx0XHRcdHN3aXRjaCAoc1Byb2dyYW1taW5nTW9kZWwpIHtcblx0XHRcdFx0XHRjYXNlIFByb2dyYW1taW5nTW9kZWwuRHJhZnQ6XG5cdFx0XHRcdFx0XHRyZXR1cm4gb1BhcmFtc0NvbnRleHQucmVxdWVzdE9iamVjdChcIkhhc0FjdGl2ZUVudGl0eVwiKS50aGVuKGZ1bmN0aW9uKGJIYXNBY3RpdmVFbnRpdHk6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRsZXQgb0RlbGV0ZVByb21pc2U7XG5cdFx0XHRcdFx0XHRcdGlmICghYkhhc0FjdGl2ZUVudGl0eSkge1xuXHRcdFx0XHRcdFx0XHRcdGlmIChvUGFyYW1zQ29udGV4dCAmJiBvUGFyYW1zQ29udGV4dC5oYXNQZW5kaW5nQ2hhbmdlcygpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvUGFyYW1zQ29udGV4dC5nZXRCaW5kaW5nKCkucmVzZXRDaGFuZ2VzKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdG9EZWxldGVQcm9taXNlID0gZHJhZnQuZGVsZXRlRHJhZnQob1BhcmFtc0NvbnRleHQpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBvRGVsZXRlUHJvbWlzZTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRsZXQgb0FjdGl2ZUNvbnRleHQgPSBvTW9kZWwuYmluZENvbnRleHQob1BhcmFtc0NvbnRleHQuZ2V0UGF0aCgpICsgXCIvU2libGluZ0VudGl0eVwiKS5nZXRCb3VuZENvbnRleHQoKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0FjdGl2ZUNvbnRleHRcblx0XHRcdFx0XHRcdFx0XHRcdC5yZXF1ZXN0Q2Fub25pY2FsUGF0aCgpXG5cdFx0XHRcdFx0XHRcdFx0XHQudGhlbihcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZnVuY3Rpb24oc1BhdGg6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHNDYW5vbmljYWxQYXRoID0gc1BhdGg7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKG9QYXJhbXNDb250ZXh0ICYmIG9QYXJhbXNDb250ZXh0Lmhhc1BlbmRpbmdDaGFuZ2VzKCkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9QYXJhbXNDb250ZXh0LmdldEJpbmRpbmcoKS5yZXNldENoYW5nZXMoKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b0RlbGV0ZVByb21pc2UgPSBkcmFmdC5kZWxldGVEcmFmdChvUGFyYW1zQ29udGV4dCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9EZWxldGVQcm9taXNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkcmFmdC5kZWxldGVEcmFmdChvUGFyYW1zQ29udGV4dCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9vUGFyYW1zQ29udGV4dC5kZWxldGUoKSBpbiB0aGUgcHJldmlvdXMgcHJvbWlzZSBkb2VzbnQgcmV0dXJuIGFueXRoaW5nIHVwb24gc3VjY2Vzcy5cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCFzQ2Fub25pY2FsUGF0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAob0FjdGl2ZUNvbnRleHQuZ2V0UGF0aCgpICE9PSBzQ2Fub25pY2FsUGF0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHRoZSBhY3RpdmUgY29udGV4dCBpcyB1c2luZyB0aGUgc2libGluZyBlbnRpdHkgLSB0aGlzIHBhdGggaXMgbm90IGFjY2Vzc2libGUgYW55bW9yZSBhcyB3ZSBkZWxldGVkIHRoZSBkcmFmdFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGRvY3VtZW50IC0gdGhlcmVmb3JlIHdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IGNvbnRleHQgd2l0aCB0aGUgY2Fub25pY2FsIHBhdGhcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvQWN0aXZlQ29udGV4dCA9IG9Nb2RlbC5iaW5kQ29udGV4dChzQ2Fub25pY2FsUGF0aCkuZ2V0Qm91bmRDb250ZXh0KCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9BY3RpdmVDb250ZXh0O1xuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGNhc2UgUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3k6XG5cdFx0XHRcdFx0XHRyZXR1cm4gc3RpY2t5LmRpc2NhcmREb2N1bWVudChvQ29udGV4dCkudGhlbihmdW5jdGlvbihvQ29udGV4dDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdGlmIChvQ29udGV4dCkge1xuXHRcdFx0XHRcdFx0XHRcdGlmIChvQ29udGV4dC5oYXNQZW5kaW5nQ2hhbmdlcygpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvQ29udGV4dC5nZXRCaW5kaW5nKCkucmVzZXRDaGFuZ2VzKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGlmICghdGhhdC5fYkNyZWF0ZU1vZGUpIHtcblx0XHRcdFx0XHRcdFx0XHRcdG9Db250ZXh0LnJlZnJlc2goKTtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBvQ29udGV4dDtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIkNhbmNlbCBkb2N1bWVudCBvbmx5IGFsbG93ZWQgZm9yIGRyYWZ0IG9yIHN0aWNreSBzZXNzaW9uIHN1cHBvcnRlZCBzZXJ2aWNlc1wiKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC50aGVuKGZ1bmN0aW9uKGNvbnRleHQ6IGFueSkge1xuXHRcdFx0XHR0aGF0Ll9iSXNNb2RpZmllZCA9IGZhbHNlO1xuXHRcdFx0XHQvLyByZW1vdmUgZXhpc3RpbmcgYm91bmQgdHJhbnNpdGlvbiBtZXNzYWdlc1xuXHRcdFx0XHRtZXNzYWdlSGFuZGxlci5yZW1vdmVUcmFuc2l0aW9uTWVzc2FnZXMoKTtcblx0XHRcdFx0Ly8gc2hvdyB1bmJvdW5kIG1lc3NhZ2VzXG5cdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZXMoKS50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiBjb250ZXh0O1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24oZXJyOiBhbnkpIHtcblx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VIYW5kbGVyLnNob3dNZXNzYWdlcygpLnRoZW4oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSlcblx0XHRcdC5maW5hbGx5KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRcdH0pO1xuXHR9XG5cdC8qKlxuXHQgKiBTYXZlcyB0aGUgZG9jdW1lbnQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlclxuXHQgKiBAc3RhdGljXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG9Db250ZXh0IENvbnRleHQgb2YgdGhlIGRvY3VtZW50IHRvIGJlIHNhdmVkXG5cdCAqIEBwYXJhbSBvUmVzb3VyY2VCdW5kbGVcblx0ICogQHBhcmFtIGJFeGVjdXRlU2lkZUVmZmVjdHNPbkVycm9yXG5cdCAqIEBwYXJhbSBhQmluZGluZ3Ncblx0ICogQHBhcmFtIG1lc3NhZ2VIYW5kbGVyXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIHdpdGggPz8/XG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKiBAZmluYWxcblx0ICovXG5cdHNhdmVEb2N1bWVudChvQ29udGV4dDogYW55LCBvUmVzb3VyY2VCdW5kbGU6IGFueSwgYkV4ZWN1dGVTaWRlRWZmZWN0c09uRXJyb3I6IGFueSwgYUJpbmRpbmdzOiBhbnksIG1lc3NhZ2VIYW5kbGVyOiBhbnkpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcztcblx0XHRjb25zdCBzUHJvZ3JhbW1pbmdNb2RlbCA9IHRoaXMuZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dCk7XG5cdFx0bGV0IG9TYXZlUHJvbWlzZTtcblx0XHRpZiAoIW9Db250ZXh0KSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQmluZGluZyBjb250ZXh0IHRvIGRyYWZ0IGRvY3VtZW50IGlzIHJlcXVpcmVkXCIpKTtcblx0XHR9XG5cdFx0Ly8gaW4gY2FzZSBvZiBzYXZpbmcgLyBhY3RpdmF0aW5nIHRoZSBib3VuZCB0cmFuc2l0aW9uIG1lc3NhZ2VzIHNoYWxsIGJlIHJlbW92ZWQgYmVmb3JlIHRoZSBQQVRDSC9QT1NUXG5cdFx0Ly8gaXMgc2VudCB0byB0aGUgYmFja2VuZFxuXHRcdG1lc3NhZ2VIYW5kbGVyLnJlbW92ZVRyYW5zaXRpb25NZXNzYWdlcygpO1xuXHRcdEJ1c3lMb2NrZXIubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuRHJhZnQpIHtcblx0XHRcdG9TYXZlUHJvbWlzZSA9IGRyYWZ0LmFjdGl2YXRlRG9jdW1lbnQob0NvbnRleHQsIHRoaXMuX2dldEFwcENvbXBvbmVudCgpLCB7fSk7XG5cdFx0fSBlbHNlIGlmIChzUHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3kpIHtcblx0XHRcdG9TYXZlUHJvbWlzZSA9IHN0aWNreS5hY3RpdmF0ZURvY3VtZW50KG9Db250ZXh0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiU2F2ZSBpcyBvbmx5IGFsbG93ZWQgZm9yIGRyYWZ0IG9yIHN0aWNreSBzZXNzaW9uIHN1cHBvcnRlZCBzZXJ2aWNlc1wiKSk7XG5cdFx0fVxuXHRcdHJldHVybiBvU2F2ZVByb21pc2Vcblx0XHRcdC50aGVuKGZ1bmN0aW9uKG9BY3RpdmVEb2N1bWVudDogYW55KSB7XG5cdFx0XHRcdGNvbnN0IGJOZXdPYmplY3QgPVxuXHRcdFx0XHRcdHRoYXQuc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuU3RpY2t5ID8gdGhhdC5fYkNyZWF0ZU1vZGUgOiAhb0NvbnRleHQuZ2V0T2JqZWN0KCkuSGFzQWN0aXZlRW50aXR5O1xuXHRcdFx0XHRNZXNzYWdlVG9hc3Quc2hvdyhcblx0XHRcdFx0XHRiTmV3T2JqZWN0XG5cdFx0XHRcdFx0XHQ/IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX0NSRUFURURcIiwgb1Jlc291cmNlQnVuZGxlKVxuXHRcdFx0XHRcdFx0OiBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9TQVZFRFwiLCBvUmVzb3VyY2VCdW5kbGUpXG5cdFx0XHRcdCk7XG5cdFx0XHRcdHRoYXQuX2JJc01vZGlmaWVkID0gZmFsc2U7XG5cdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZURpYWxvZygpLnRoZW4oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9BY3RpdmVEb2N1bWVudDtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uKGVycjogYW55KSB7XG5cdFx0XHRcdGlmIChhQmluZGluZ3MgJiYgYUJpbmRpbmdzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHQvKiBUaGUgc2lkZUVmZmVjdHMgYXJlIGV4ZWN1dGVkIG9ubHkgZm9yIHRhYmxlIGl0ZW1zIGluIHRyYW5zaWVudCBzdGF0ZSAqL1xuXHRcdFx0XHRcdGFCaW5kaW5ncy5mb3JFYWNoKGZ1bmN0aW9uKG9MaXN0QmluZGluZzogYW55KSB7XG5cdFx0XHRcdFx0XHRpZiAoIUNvbW1vblV0aWxzLmhhc1RyYW5zaWVudENvbnRleHQob0xpc3RCaW5kaW5nKSAmJiBiRXhlY3V0ZVNpZGVFZmZlY3RzT25FcnJvcikge1xuXHRcdFx0XHRcdFx0XHRjb25zdCBvQXBwQ29tcG9uZW50ID0gdGhhdC5fZ2V0QXBwQ29tcG9uZW50KCk7XG5cdFx0XHRcdFx0XHRcdG9BcHBDb21wb25lbnQuZ2V0U2lkZUVmZmVjdHNTZXJ2aWNlKCkucmVxdWVzdFNpZGVFZmZlY3RzRm9yTmF2aWdhdGlvblByb3BlcnR5KG9MaXN0QmluZGluZy5nZXRQYXRoKCksIG9Db250ZXh0KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VzKCkudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0fSk7XG5cdH1cblx0LyoqXG5cdCAqIENhbGxzIGEgYm91bmQgb3IgdW5ib3VuZCBhY3Rpb24uXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAc3RhdGljXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyLmNhbGxBY3Rpb25cblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzQWN0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiBAcGFyYW0ge21hcH0gW21QYXJhbWV0ZXJzXSBDb250YWlucyB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IFttUGFyYW1ldGVycy5jb250ZXh0c10gTWFuZGF0b3J5IGZvciBhIGJvdW5kIGFjdGlvbjogRWl0aGVyIG9uZSBjb250ZXh0IG9yIGFuIGFycmF5IHdpdGggY29udGV4dHMgZm9yIHdoaWNoIHRoZSBhY3Rpb24gaXMgdG8gYmUgY2FsbGVkXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTW9kZWx9IFttUGFyYW1ldGVycy5tb2RlbF0gTWFuZGF0b3J5IGZvciBhbiB1bmJvdW5kIGFjdGlvbjogQW4gaW5zdGFuY2Ugb2YgYW4gT0RhdGEgVjQgbW9kZWxcblx0ICogQHBhcmFtIHtzdHJpbmd9IFttUGFyYW1ldGVycy5pbnZvY2F0aW9uR3JvdXBpbmddIE1vZGUgaG93IGFjdGlvbnMgYXJlIHRvIGJlIGNhbGxlZDogJ0NoYW5nZVNldCcgdG8gcHV0IGFsbCBhY3Rpb24gY2FsbHMgaW50byBvbmUgY2hhbmdlc2V0LCAnSXNvbGF0ZWQnIHRvIHB1dCB0aGVtIGludG8gc2VwYXJhdGUgY2hhbmdlc2V0c1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gW21QYXJhbWV0ZXJzLmxhYmVsXSBBIGh1bWFuLXJlYWRhYmxlIGxhYmVsIGZvciB0aGUgYWN0aW9uXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW21QYXJhbWV0ZXJzLmJHZXRCb3VuZENvbnRleHRdIElmIHNwZWNpZmllZCwgdGhlIGFjdGlvbiBwcm9taXNlIHJldHVybnMgdGhlIGJvdW5kIGNvbnRleHRcblx0ICogQHBhcmFtIHtvYmplY3R9IG9WaWV3IENvbnRhaW5zIHRoZSBvYmplY3Qgb2YgdGhlIGN1cnJlbnQgdmlld1xuXHQgKiBAcGFyYW0gbWVzc2FnZUhhbmRsZXJcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgd2l0aCBhbiBhcnJheSBvZiByZXNwb25zZSBvYmplY3RzIChUT0RPOiB0byBiZSBjaGFuZ2VkKVxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqKi9cblx0Y2FsbEFjdGlvbihzQWN0aW9uTmFtZTogc3RyaW5nLCBtUGFyYW1ldGVyczogYW55LCBvVmlldzogVmlldyB8IG51bGwsIG1lc3NhZ2VIYW5kbGVyOiBhbnkpIHtcblx0XHRtUGFyYW1ldGVycyA9IGdldFBhcmFtZXRlcnMobVBhcmFtZXRlcnMpO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzO1xuXHRcdGxldCBvQ29udGV4dCwgb01vZGVsOiBhbnksIG9Qcm9taXNlO1xuXHRcdGNvbnN0IG1CaW5kaW5nUGFyYW1ldGVycyA9IG1QYXJhbWV0ZXJzLmJpbmRpbmdQYXJhbWV0ZXJzO1xuXHRcdGlmICghc0FjdGlvbk5hbWUpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIlByb3ZpZGUgbmFtZSBvZiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWRcIik7XG5cdFx0fVxuXHRcdC8vIGFjdGlvbiBpbXBvcnRzIGFyZSBub3QgZGlyZWN0bHkgb2J0YWluZWQgZnJvbSB0aGUgbWV0YU1vZGVsIGJ5IGl0IGlzIHByZXNlbnQgaW5zaWRlIHRoZSBlbnRpdHlDb250YWluZXJcblx0XHQvLyBhbmQgdGhlIGFjaW9ucyBpdCByZWZlcnMgdG8gcHJlc2VudCBvdXRzaWRlIHRoZSBlbnRpdHljb250YWluZXIsIGhlbmNlIHRvIG9idGFpbiBraW5kIG9mIHRoZSBhY3Rpb25cblx0XHQvLyBzcGxpdCgpIG9uIGl0cyBuYW1lIHdhcyByZXF1aXJlZFxuXHRcdGNvbnN0IHNOYW1lID0gc0FjdGlvbk5hbWUuc3BsaXQoXCIvXCIpWzFdO1xuXHRcdHNBY3Rpb25OYW1lID0gc05hbWUgfHwgc0FjdGlvbk5hbWU7XG5cdFx0b0NvbnRleHQgPSBzTmFtZSA/IHVuZGVmaW5lZCA6IG1QYXJhbWV0ZXJzLmNvbnRleHRzO1xuXHRcdC8vY2hlY2tpbmcgd2hldGhlciB0aGUgY29udGV4dCBpcyBhbiBhcnJheSB3aXRoIG1vcmUgdGhhbiAwIGxlbmd0aCBvciBub3QgYW4gYXJyYXkoY3JlYXRlIGFjdGlvbilcblx0XHRpZiAob0NvbnRleHQgJiYgKChBcnJheS5pc0FycmF5KG9Db250ZXh0KSAmJiBvQ29udGV4dC5sZW5ndGgpIHx8ICFBcnJheS5pc0FycmF5KG9Db250ZXh0KSkpIHtcblx0XHRcdG9Db250ZXh0ID0gQXJyYXkuaXNBcnJheShvQ29udGV4dCkgPyBvQ29udGV4dFswXSA6IG9Db250ZXh0O1xuXHRcdFx0b01vZGVsID0gb0NvbnRleHQuZ2V0TW9kZWwoKTtcblx0XHR9XG5cdFx0aWYgKG1QYXJhbWV0ZXJzLm1vZGVsKSB7XG5cdFx0XHRvTW9kZWwgPSBtUGFyYW1ldGVycy5tb2RlbDtcblx0XHR9XG5cdFx0aWYgKCFvTW9kZWwpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIlBhc3MgYSBjb250ZXh0IGZvciBhIGJvdW5kIGFjdGlvbiBvciBwYXNzIHRoZSBtb2RlbCBmb3IgYW4gdW5ib3VuZCBhY3Rpb25cIik7XG5cdFx0fVxuXHRcdC8vIGdldCB0aGUgYmluZGluZyBwYXJhbWV0ZXJzICRzZWxlY3QgYW5kICRleHBhbmQgZm9yIHRoZSBzaWRlIGVmZmVjdCBvbiB0aGlzIGFjdGlvblxuXHRcdC8vIGFsc28gZ2F0aGVyIGFkZGl0aW9uYWwgcHJvcGVydHkgcGF0aHMgdG8gYmUgcmVxdWVzdGVkIHN1Y2ggYXMgdGV4dCBhc3NvY2lhdGlvbnNcblx0XHRjb25zdCBvQXBwQ29tcG9uZW50ID0gdGhhdC5fZ2V0QXBwQ29tcG9uZW50KCk7XG5cdFx0Y29uc3QgbVNpZGVFZmZlY3RzUGFyYW1ldGVycyA9IG9BcHBDb21wb25lbnQuZ2V0U2lkZUVmZmVjdHNTZXJ2aWNlKCkuZ2V0T0RhdGFBY3Rpb25TaWRlRWZmZWN0cyhzQWN0aW9uTmFtZSwgb0NvbnRleHQpIHx8IHt9O1xuXHRcdGlmIChvQ29udGV4dCAmJiBvTW9kZWwpIHtcblx0XHRcdG9Qcm9taXNlID0gbmV3IFByb21pc2U8dm9pZD4oZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdFx0XHRcdGxldCBvQXBwbGljYWJsZUNvbnRleHREaWFsb2c6IERpYWxvZztcblx0XHRcdFx0Y29uc3Qgb0NvbnRyb2xsZXIgPSB7XG5cdFx0XHRcdFx0b25DbG9zZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHQvLyBVc2VyIGNhbmNlbHMgYWN0aW9uXG5cdFx0XHRcdFx0XHRvQXBwbGljYWJsZUNvbnRleHREaWFsb2cuY2xvc2UoKTtcblx0XHRcdFx0XHRcdHJlc29sdmUoKTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdG9uQ29udGludWU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0Ly8gVXNlcnMgY29udGludWVzIHRoZSBhY3Rpb24gd2l0aCB0aGUgYm91bmQgY29udGV4dHNcblx0XHRcdFx0XHRcdG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZy5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0cmVzb2x2ZShtUGFyYW1ldGVycy5hcHBsaWNhYmxlQ29udGV4dCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRjb25zdCBmbk9wZW5BbmRGaWxsRGlhbG9nID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0bGV0IG9EaWFsb2dDb250ZW50O1xuXHRcdFx0XHRcdGNvbnN0IG5Ob3RBcHBsaWNhYmxlID0gbVBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHQubGVuZ3RoLFxuXHRcdFx0XHRcdFx0YU5vdEFwcGxpY2FibGVJdGVtcyA9IFtdO1xuXHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbVBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHQubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdG9EaWFsb2dDb250ZW50ID0gbVBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHRbaV0uZ2V0T2JqZWN0KCk7XG5cdFx0XHRcdFx0XHRhTm90QXBwbGljYWJsZUl0ZW1zLnB1c2gob0RpYWxvZ0NvbnRlbnQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCBvTm90QXBwbGljYWJsZUl0ZW1zTW9kZWwgPSBuZXcgSlNPTk1vZGVsKGFOb3RBcHBsaWNhYmxlSXRlbXMpO1xuXHRcdFx0XHRcdGNvbnN0IG9Ub3RhbHMgPSBuZXcgSlNPTk1vZGVsKHsgdG90YWw6IG5Ob3RBcHBsaWNhYmxlLCBsYWJlbDogbVBhcmFtZXRlcnMubGFiZWwgfSk7XG5cdFx0XHRcdFx0b0FwcGxpY2FibGVDb250ZXh0RGlhbG9nLnNldE1vZGVsKG9Ob3RBcHBsaWNhYmxlSXRlbXNNb2RlbCwgXCJub3RBcHBsaWNhYmxlXCIpO1xuXHRcdFx0XHRcdG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZy5zZXRNb2RlbChvVG90YWxzLCBcInRvdGFsc1wiKTtcblx0XHRcdFx0XHRvQXBwbGljYWJsZUNvbnRleHREaWFsb2cub3BlbigpO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAobVBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHQgJiYgbVBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHQubGVuZ3RoID49IDEpIHtcblx0XHRcdFx0XHQvLyBTaG93IHRoZSBjb250ZXh0cyB0aGF0IGFyZSBub3QgYXBwbGljYWJsZSBhbmQgd2lsbCBub3QgdGhlcmVmb3JlIGJlIHByb2Nlc3NlZFxuXHRcdFx0XHRcdGNvbnN0IHNGcmFnbWVudE5hbWUgPSBcInNhcC5mZS5jb3JlLmNvbnRyb2xzLkFjdGlvblBhcnRpYWxcIjtcblx0XHRcdFx0XHRjb25zdCBvRGlhbG9nRnJhZ21lbnQgPSBYTUxUZW1wbGF0ZVByb2Nlc3Nvci5sb2FkVGVtcGxhdGUoc0ZyYWdtZW50TmFtZSwgXCJmcmFnbWVudFwiKTtcblx0XHRcdFx0XHRjb25zdCBvTWV0YU1vZGVsID0gb01vZGVsLmdldE1ldGFNb2RlbCgpO1xuXHRcdFx0XHRcdGNvbnN0IHNDYW5vbmljYWxQYXRoID0gbVBhcmFtZXRlcnMuY29udGV4dHNbMF0uZ2V0Q2Fub25pY2FsUGF0aCgpO1xuXHRcdFx0XHRcdGNvbnN0IHNFbnRpdHlTZXQgPSBzQ2Fub25pY2FsUGF0aC5zdWJzdHIoMCwgc0Nhbm9uaWNhbFBhdGguaW5kZXhPZihcIihcIikpICsgXCIvXCI7XG5cdFx0XHRcdFx0Y29uc3Qgb0RpYWxvZ0xhYmVsTW9kZWwgPSBuZXcgSlNPTk1vZGVsKHtcblx0XHRcdFx0XHRcdHRpdGxlOiBtUGFyYW1ldGVycy5sYWJlbFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFByb21pc2UucmVzb2x2ZShcblx0XHRcdFx0XHRcdFhNTFByZXByb2Nlc3Nvci5wcm9jZXNzKFxuXHRcdFx0XHRcdFx0XHRvRGlhbG9nRnJhZ21lbnQsXG5cdFx0XHRcdFx0XHRcdHsgbmFtZTogc0ZyYWdtZW50TmFtZSB9LFxuXHRcdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdFx0YmluZGluZ0NvbnRleHRzOiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRlbnRpdHlUeXBlOiBvTWV0YU1vZGVsLmNyZWF0ZUJpbmRpbmdDb250ZXh0KHNFbnRpdHlTZXQpLFxuXHRcdFx0XHRcdFx0XHRcdFx0bGFiZWw6IG9EaWFsb2dMYWJlbE1vZGVsLmNyZWF0ZUJpbmRpbmdDb250ZXh0KFwiL1wiKVxuXHRcdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdFx0bW9kZWxzOiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRlbnRpdHlUeXBlOiBvTWV0YU1vZGVsLFxuXHRcdFx0XHRcdFx0XHRcdFx0bWV0YU1vZGVsOiBvTWV0YU1vZGVsLFxuXHRcdFx0XHRcdFx0XHRcdFx0bGFiZWw6IG9EaWFsb2dMYWJlbE1vZGVsXG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24ob0ZyYWdtZW50OiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIEZyYWdtZW50LmxvYWQoeyBkZWZpbml0aW9uOiBvRnJhZ21lbnQsIGNvbnRyb2xsZXI6IG9Db250cm9sbGVyIH0pO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uKG9Qb3BvdmVyOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0b0FwcGxpY2FibGVDb250ZXh0RGlhbG9nID0gb1BvcG92ZXI7XG5cdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLnBhcmVudENvbnRyb2wuYWRkRGVwZW5kZW50KG9Qb3BvdmVyKTtcblx0XHRcdFx0XHRcdFx0Zm5PcGVuQW5kRmlsbERpYWxvZygpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaChyZWplY3QpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc29sdmUobVBhcmFtZXRlcnMuY29udGV4dHMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KS50aGVuKGZ1bmN0aW9uKGNvbnRleHRUb1Byb2Nlc3M6IGFueSkge1xuXHRcdFx0XHRpZiAoY29udGV4dFRvUHJvY2Vzcykge1xuXHRcdFx0XHRcdHJldHVybiBvcGVyYXRpb25zLmNhbGxCb3VuZEFjdGlvbihzQWN0aW9uTmFtZSwgY29udGV4dFRvUHJvY2Vzcywgb01vZGVsLCBvQXBwQ29tcG9uZW50LCB7XG5cdFx0XHRcdFx0XHRpbnZvY2F0aW9uR3JvdXBpbmc6IG1QYXJhbWV0ZXJzLmludm9jYXRpb25Hcm91cGluZyxcblx0XHRcdFx0XHRcdGxhYmVsOiBtUGFyYW1ldGVycy5sYWJlbCxcblx0XHRcdFx0XHRcdHNob3dBY3Rpb25QYXJhbWV0ZXJEaWFsb2c6IHRydWUsXG5cdFx0XHRcdFx0XHRtQmluZGluZ1BhcmFtZXRlcnM6IG1CaW5kaW5nUGFyYW1ldGVycyxcblx0XHRcdFx0XHRcdGVudGl0eVNldE5hbWU6IG1QYXJhbWV0ZXJzLmVudGl0eVNldE5hbWUsXG5cdFx0XHRcdFx0XHRhZGRpdGlvbmFsU2lkZUVmZmVjdDogbVNpZGVFZmZlY3RzUGFyYW1ldGVycyxcblx0XHRcdFx0XHRcdG9uU3VibWl0dGVkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0bWVzc2FnZUhhbmRsZXIucmVtb3ZlVHJhbnNpdGlvbk1lc3NhZ2VzKCk7XG5cdFx0XHRcdFx0XHRcdEJ1c3lMb2NrZXIubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRvblJlc3BvbnNlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0cGFyZW50Q29udHJvbDogbVBhcmFtZXRlcnMucGFyZW50Q29udHJvbCxcblx0XHRcdFx0XHRcdGludGVybmFsTW9kZWxDb250ZXh0OiBtUGFyYW1ldGVycy5pbnRlcm5hbE1vZGVsQ29udGV4dCxcblx0XHRcdFx0XHRcdG9wZXJhdGlvbkF2YWlsYWJsZU1hcDogbVBhcmFtZXRlcnMub3BlcmF0aW9uQXZhaWxhYmxlTWFwLFxuXHRcdFx0XHRcdFx0YklzQ3JlYXRlQWN0aW9uOiBtUGFyYW1ldGVycy5iSXNDcmVhdGVBY3Rpb24sXG5cdFx0XHRcdFx0XHRiR2V0Qm91bmRDb250ZXh0OiBtUGFyYW1ldGVycy5iR2V0Qm91bmRDb250ZXh0LFxuXHRcdFx0XHRcdFx0Yk9iamVjdFBhZ2U6IG1QYXJhbWV0ZXJzLmJPYmplY3RQYWdlLFxuXHRcdFx0XHRcdFx0bWVzc2FnZUhhbmRsZXI6IG1lc3NhZ2VIYW5kbGVyLFxuXHRcdFx0XHRcdFx0ZGVmYXVsdFZhbHVlc0V4dGVuc2lvbkZ1bmN0aW9uOiBtUGFyYW1ldGVycy5kZWZhdWx0VmFsdWVzRXh0ZW5zaW9uRnVuY3Rpb25cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIFRPRE86IGNvbmZpcm0gaWYgYWN0aW9uIGltcG9ydCBuZWVkcyBzaWRlIGVmZmVjdHMuXG5cdFx0XHRvUHJvbWlzZSA9IG9wZXJhdGlvbnMuY2FsbEFjdGlvbkltcG9ydChzQWN0aW9uTmFtZSwgb01vZGVsLCBvQXBwQ29tcG9uZW50LCB7XG5cdFx0XHRcdGxhYmVsOiBtUGFyYW1ldGVycy5sYWJlbCxcblx0XHRcdFx0c2hvd0FjdGlvblBhcmFtZXRlckRpYWxvZzogdHJ1ZSxcblx0XHRcdFx0YmluZGluZ1BhcmFtZXRlcnM6IG1CaW5kaW5nUGFyYW1ldGVycyxcblx0XHRcdFx0ZW50aXR5U2V0TmFtZTogbVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZSxcblx0XHRcdFx0b25TdWJtaXR0ZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdEJ1c3lMb2NrZXIubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRcdFx0fSxcblx0XHRcdFx0b25SZXNwb25zZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHBhcmVudENvbnRyb2w6IG1QYXJhbWV0ZXJzLnBhcmVudENvbnRyb2wsXG5cdFx0XHRcdGludGVybmFsTW9kZWxDb250ZXh0OiBtUGFyYW1ldGVycy5pbnRlcm5hbE1vZGVsQ29udGV4dCxcblx0XHRcdFx0b3BlcmF0aW9uQXZhaWxhYmxlTWFwOiBtUGFyYW1ldGVycy5vcGVyYXRpb25BdmFpbGFibGVNYXAsXG5cdFx0XHRcdG1lc3NhZ2VIYW5kbGVyOiBtZXNzYWdlSGFuZGxlcixcblx0XHRcdFx0Yk9iamVjdFBhZ2U6IG1QYXJhbWV0ZXJzLmJPYmplY3RQYWdlXG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0cmV0dXJuIG9Qcm9taXNlXG5cdFx0XHQudGhlbihmdW5jdGlvbihvUmVzdWx0OiBhbnkpIHtcblx0XHRcdFx0Ly8gU3VjY2VlZGVkXG5cdFx0XHRcdHJldHVybiB0aGF0Ll9oYW5kbGVBY3Rpb25SZXNwb25zZShtZXNzYWdlSGFuZGxlciwgbVBhcmFtZXRlcnMsIHNBY3Rpb25OYW1lKS50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiBvUmVzdWx0O1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24oZXJyOiBhbnkpIHtcblx0XHRcdFx0cmV0dXJuIHRoYXQuX2hhbmRsZUFjdGlvblJlc3BvbnNlKG1lc3NhZ2VIYW5kbGVyLCBtUGFyYW1ldGVycywgc0FjdGlvbk5hbWUpLnRoZW4oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdH1cblx0LyoqXG5cdCAqIEhhbmRsZXMgbWVzc2FnZXMgZm9yIGFjdGlvbiBjYWxsLlxuXHQgKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQG5hbWUgc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXIjX2hhbmRsZUFjdGlvblJlc3BvbnNlXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlclxuXHQgKiBAcGFyYW0gbWVzc2FnZUhhbmRsZXJcblx0ICogQHBhcmFtIHtvYmplY3R9IG1QYXJhbWV0ZXJzIFBhcmFtZXRlcnMgdG8gYmUgY29uc2lkZXJlZCBmb3IgdGhlIGFjdGlvbi5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHNBY3Rpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBhY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIGFmdGVyIG1lc3NhZ2UgZGlhbG9nIGlzIG9wZW5lZCBpZiByZXF1aXJlZC5cblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0X2hhbmRsZUFjdGlvblJlc3BvbnNlKG1lc3NhZ2VIYW5kbGVyOiBhbnksIG1QYXJhbWV0ZXJzOiBhbnksIHNBY3Rpb25OYW1lOiBzdHJpbmcpIHtcblx0XHRjb25zdCBhVHJhbnNpZW50TWVzc2FnZXMgPSBtZXNzYWdlSGFuZGxpbmcuZ2V0TWVzc2FnZXModHJ1ZSwgdHJ1ZSk7XG5cdFx0aWYgKGFUcmFuc2llbnRNZXNzYWdlcy5sZW5ndGggPiAwICYmIG1QYXJhbWV0ZXJzICYmIG1QYXJhbWV0ZXJzLmludGVybmFsTW9kZWxDb250ZXh0KSB7XG5cdFx0XHRtUGFyYW1ldGVycy5pbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcInNBY3Rpb25OYW1lXCIsIG1QYXJhbWV0ZXJzLmxhYmVsID8gbVBhcmFtZXRlcnMubGFiZWwgOiBzQWN0aW9uTmFtZSk7XG5cdFx0fVxuXHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZXMoKTtcblx0fVxuXHQvKipcblx0ICogSGFuZGxlcyB2YWxpZGF0aW9uIGVycm9ycyBmb3IgdGhlICdkaXNjYXJkJyBhY3Rpb24uXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAbmFtZSBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlciNoYW5kbGVWYWxpZGF0aW9uRXJyb3Jcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBzdGF0aWNcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0aGFuZGxlVmFsaWRhdGlvbkVycm9yKCkge1xuXHRcdGNvbnN0IG9NZXNzYWdlTWFuYWdlciA9IChzYXAudWkuZ2V0Q29yZSgpIGFzIGFueSkuZ2V0TWVzc2FnZU1hbmFnZXIoKSxcblx0XHRcdGVycm9yVG9SZW1vdmUgPSBvTWVzc2FnZU1hbmFnZXJcblx0XHRcdFx0LmdldE1lc3NhZ2VNb2RlbCgpXG5cdFx0XHRcdC5nZXREYXRhKClcblx0XHRcdFx0LmZpbHRlcihmdW5jdGlvbihlcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0Ly8gb25seSBuZWVkcyB0byBoYW5kbGUgdmFsaWRhdGlvbiBtZXNzYWdlcywgdGVjaG5pY2FsIGFuZCBwZXJzaXN0ZW50IGVycm9ycyBuZWVkcyBub3QgdG8gYmUgY2hlY2tlZCBoZXJlLlxuXHRcdFx0XHRcdGlmIChlcnJvci52YWxpZGF0aW9uKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZXJyb3I7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRvTWVzc2FnZU1hbmFnZXIucmVtb3ZlTWVzc2FnZXMoZXJyb3JUb1JlbW92ZSk7XG5cdH1cblx0LyoqXG5cdCAqIFNob3dzIGEgcG9wb3ZlciBpZiBpdCBuZWVkcyB0byBiZSBzaG93bi5cblx0ICogVE9ETzogUG9wb3ZlciBpcyBzaG93biBpZiB1c2VyIGhhcyBtb2RpZmllZCBhbnkgZGF0YS5cblx0ICogVE9ETzogUG9wb3ZlciBpcyBzaG93biBpZiB0aGVyZSdzIGEgZGlmZmVyZW5jZSBmcm9tIGRyYWZ0IGFkbWluIGRhdGEuXG5cdCAqIEBzdGF0aWNcblx0ICogQG5hbWUgc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXIuX3Nob3dEaXNjYXJkUG9wb3ZlclxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHBhcmFtIHtzYXAudWkuY29yZS5Db250cm9sfSBvQ2FuY2VsQnV0dG9uIFRoZSBjb250cm9sIHdoaWNoIHdpbGwgb3BlbiB0aGUgcG9wb3ZlclxuXHQgKiBAcGFyYW0gYklzTW9kaWZpZWRcblx0ICogQHBhcmFtIG9SZXNvdXJjZUJ1bmRsZVxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSByZXNvbHZlcyBpZiB1c2VyIGNvbmZpcm1zIGRpc2NhcmQsIHJlamVjdHMgaWYgb3RoZXJ3aXNlLCByZWplY3RzIGlmIG5vIGNvbnRyb2wgcGFzc2VkIHRvIG9wZW4gcG9wb3ZlclxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqL1xuXHRfc2hvd0Rpc2NhcmRQb3BvdmVyKG9DYW5jZWxCdXR0b246IGFueSwgYklzTW9kaWZpZWQ6IGFueSwgb1Jlc291cmNlQnVuZGxlOiBhbnkpIHtcblx0XHQvLyBUT0RPOiBJbXBsZW1lbnQgdGhpcyBwb3BvdmVyIGFzIGEgZnJhZ21lbnQgYXMgaW4gdjI/P1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzO1xuXHRcdHRoYXQuX2JDb250aW51ZURpc2NhcmQgPSBmYWxzZTtcblx0XHQvLyB0byBiZSBpbXBsZW1lbnRlZFxuXHRcdHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPihmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblx0XHRcdGlmICghb0NhbmNlbEJ1dHRvbikge1xuXHRcdFx0XHRyZWplY3QoXCJDYW5jZWwgYnV0dG9uIG5vdCBmb3VuZFwiKTtcblx0XHRcdH1cblx0XHRcdC8vU2hvdyBwb3BvdmVyIG9ubHkgd2hlbiBkYXRhIGlzIGNoYW5nZWQuXG5cdFx0XHRpZiAoYklzTW9kaWZpZWQpIHtcblx0XHRcdFx0Y29uc3QgZm5PbkFmdGVyRGlzY2FyZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdG9DYW5jZWxCdXR0b24uc2V0RW5hYmxlZCh0cnVlKTtcblx0XHRcdFx0XHRpZiAodGhhdC5fYkNvbnRpbnVlRGlzY2FyZCkge1xuXHRcdFx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZWplY3QoXCJEaXNjYXJkIG9wZXJhdGlvbiB3YXMgcmVqZWN0ZWQuIERvY3VtZW50IGhhcyBub3QgYmVlbiBkaXNjYXJkZWRcIik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoYXQuX29Qb3BvdmVyLmRldGFjaEFmdGVyQ2xvc2UoZm5PbkFmdGVyRGlzY2FyZCk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdGlmICghdGhhdC5fb1BvcG92ZXIpIHtcblx0XHRcdFx0XHRjb25zdCBvVGV4dCA9IG5ldyBUZXh0KHtcblx0XHRcdFx0XHRcdFx0Ly9UaGlzIHRleHQgaXMgdGhlIHNhbWUgYXMgTFIgdjIuXG5cdFx0XHRcdFx0XHRcdC8vVE9ETzogRGlzcGxheSBtZXNzYWdlIHByb3ZpZGVkIGJ5IGFwcCBkZXZlbG9wZXI/Pz9cblx0XHRcdFx0XHRcdFx0dGV4dDogQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9EUkFGVF9ESVNDQVJEX01FU1NBR0VcIiwgb1Jlc291cmNlQnVuZGxlKVxuXHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0XHRvQnV0dG9uID0gbmV3IEJ1dHRvbih7XG5cdFx0XHRcdFx0XHRcdHRleHQ6IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfRFJBRlRfRElTQ0FSRF9CVVRUT05cIiwgb1Jlc291cmNlQnVuZGxlKSxcblx0XHRcdFx0XHRcdFx0d2lkdGg6IFwiMTAwJVwiLFxuXHRcdFx0XHRcdFx0XHRwcmVzczogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhhdC5oYW5kbGVWYWxpZGF0aW9uRXJyb3IoKTtcblx0XHRcdFx0XHRcdFx0XHR0aGF0Ll9iQ29udGludWVEaXNjYXJkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHR0aGF0Ll9vUG9wb3Zlci5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRhcmlhTGFiZWxsZWRCeTogb1RleHRcblx0XHRcdFx0XHRcdH0gYXMgYW55KTtcblx0XHRcdFx0XHR0aGF0Ll9vUG9wb3ZlciA9IG5ldyBQb3BvdmVyKHtcblx0XHRcdFx0XHRcdHNob3dIZWFkZXI6IGZhbHNlLFxuXHRcdFx0XHRcdFx0cGxhY2VtZW50OiBcIlRvcFwiLFxuXHRcdFx0XHRcdFx0Y29udGVudDogW1xuXHRcdFx0XHRcdFx0XHRuZXcgVkJveCh7XG5cdFx0XHRcdFx0XHRcdFx0aXRlbXM6IFtvVGV4dCwgb0J1dHRvbl1cblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdF0sXG5cdFx0XHRcdFx0XHRiZWZvcmVPcGVuOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0Ly8gbWFrZSBzdXJlIHRvIE5PVCB0cmlnZ2VyIG11bHRpcGxlIGNhbmNlbCBmbG93c1xuXHRcdFx0XHRcdFx0XHRvQ2FuY2VsQnV0dG9uLnNldEVuYWJsZWQoZmFsc2UpO1xuXHRcdFx0XHRcdFx0XHR0aGF0Ll9vUG9wb3Zlci5zZXRJbml0aWFsRm9jdXMob0J1dHRvbik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0dGhhdC5fb1BvcG92ZXIuYWRkU3R5bGVDbGFzcyhcInNhcFVpQ29udGVudFBhZGRpbmdcIik7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhhdC5fb1BvcG92ZXIuYXR0YWNoQWZ0ZXJDbG9zZShmbk9uQWZ0ZXJEaXNjYXJkKTtcblx0XHRcdFx0dGhhdC5fb1BvcG92ZXIub3BlbkJ5KG9DYW5jZWxCdXR0b24sIGZhbHNlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoYXQuaGFuZGxlVmFsaWRhdGlvbkVycm9yKCk7XG5cdFx0XHRcdHJlc29sdmUoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXHQvKipcblx0ICogU2V0cyB0aGUgZG9jdW1lbnQgdG8gbW9kaWZpZWQgc3RhdGUgb24gcGF0Y2ggZXZlbnQuXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAc3RhdGljXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyLmhhbmRsZURvY3VtZW50TW9kaWZpY2F0aW9uc1xuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0aGFuZGxlRG9jdW1lbnRNb2RpZmljYXRpb25zKCkge1xuXHRcdHRoaXMuX2JJc01vZGlmaWVkID0gdHJ1ZTtcblx0fVxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSBvd25lciBjb21wb25lbnQuXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAc3RhdGljXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyLl9nZXRPd25lckNvbXBvbmVudFxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHJldHVybnMge3NhcC5mZS5jb3JlLkFwcENvbXBvbmVudH0gVGhlIGFwcCBjb21wb25lbnRcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKiovXG5cdF9nZXRBcHBDb21wb25lbnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX29BcHBDb21wb25lbnQ7XG5cdH1cblx0X2xhdW5jaERpYWxvZ1dpdGhLZXlGaWVsZHMoXG5cdFx0b0xpc3RCaW5kaW5nOiBhbnksXG5cdFx0b1RyYW5zaWVudExpc3RCaW5kaW5nOiBhbnksXG5cdFx0b1RyYW5zaWVudENvbnRleHQ6IGFueSxcblx0XHRtRmllbGRzOiBhbnksXG5cdFx0b01vZGVsOiBhbnksXG5cdFx0bVBhcmFtZXRlcnM6IGFueSxcblx0XHRtZXNzYWdlSGFuZGxlcjogYW55XG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzO1xuXHRcdGxldCBvRGlhbG9nOiBEaWFsb2c7XG5cdFx0Y29uc3Qgb1BhcmVudENvbnRyb2wgPSBtUGFyYW1ldGVycy5wYXJlbnRDb250cm9sLFxuXHRcdFx0YlN1Y2Nlc3MgPSBmYWxzZTtcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZTogKHZhbHVlOiBhbnkpID0+IHZvaWQsIHJlamVjdDogKHJlYXNvbj86IGFueSkgPT4gdm9pZCkge1xuXHRcdFx0Y29uc3Qgc0ZyYWdtZW50TmFtZSA9IFwic2FwL2ZlL2NvcmUvY29udHJvbHMvTm9uQ29tcHV0ZWRWaXNpYmxlS2V5RmllbGRzRGlhbG9nXCI7XG5cdFx0XHRjb25zdCBvRnJhZ21lbnQgPSBYTUxUZW1wbGF0ZVByb2Nlc3Nvci5sb2FkVGVtcGxhdGUoc0ZyYWdtZW50TmFtZSwgXCJmcmFnbWVudFwiKSxcblx0XHRcdFx0b1Jlc291cmNlQnVuZGxlID0gb1BhcmVudENvbnRyb2wuZ2V0Q29udHJvbGxlcigpLm9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0b01ldGFNb2RlbCA9IG9Nb2RlbC5nZXRNZXRhTW9kZWwoKSxcblx0XHRcdFx0YUltbXV0YWJsZUZpZWxkczogYW55W10gPSBbXSxcblx0XHRcdFx0b0FwcENvbXBvbmVudCA9IHRoYXQuX2dldEFwcENvbXBvbmVudCgpLFxuXHRcdFx0XHRzUGF0aCA9IG9MaXN0QmluZGluZy5pc1JlbGF0aXZlKCkgPyBvTGlzdEJpbmRpbmcuZ2V0UmVzb2x2ZWRQYXRoKCkgOiBvTGlzdEJpbmRpbmcuZ2V0UGF0aCgpLFxuXHRcdFx0XHRvRW50aXR5U2V0Q29udGV4dCA9IG9NZXRhTW9kZWwuY3JlYXRlQmluZGluZ0NvbnRleHQoc1BhdGgpLFxuXHRcdFx0XHRzTWV0YVBhdGggPSBvTWV0YU1vZGVsLmdldE1ldGFQYXRoKHNQYXRoKTtcblx0XHRcdGZvciAoY29uc3QgaSBpbiBtRmllbGRzKSB7XG5cdFx0XHRcdGFJbW11dGFibGVGaWVsZHMucHVzaChvTWV0YU1vZGVsLmNyZWF0ZUJpbmRpbmdDb250ZXh0KHNNZXRhUGF0aCArIFwiL1wiICsgbUZpZWxkc1tpXSkpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3Qgb0ltbXV0YWJsZUN0eE1vZGVsID0gbmV3IEpTT05Nb2RlbChhSW1tdXRhYmxlRmllbGRzKTtcblx0XHRcdGNvbnN0IG9JbW11dGFibGVDdHggPSBvSW1tdXRhYmxlQ3R4TW9kZWwuY3JlYXRlQmluZGluZ0NvbnRleHQoXCIvXCIpO1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZShcblx0XHRcdFx0WE1MUHJlcHJvY2Vzc29yLnByb2Nlc3MoXG5cdFx0XHRcdFx0b0ZyYWdtZW50LFxuXHRcdFx0XHRcdHsgbmFtZTogc0ZyYWdtZW50TmFtZSB9LFxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdGJpbmRpbmdDb250ZXh0czoge1xuXHRcdFx0XHRcdFx0XHRlbnRpdHlTZXQ6IG9FbnRpdHlTZXRDb250ZXh0LFxuXHRcdFx0XHRcdFx0XHRmaWVsZHM6IG9JbW11dGFibGVDdHhcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRtb2RlbHM6IHtcblx0XHRcdFx0XHRcdFx0ZW50aXR5U2V0OiBvRW50aXR5U2V0Q29udGV4dC5nZXRNb2RlbCgpLFxuXHRcdFx0XHRcdFx0XHRmaWVsZHM6IG9JbW11dGFibGVDdHguZ2V0TW9kZWwoKSxcblx0XHRcdFx0XHRcdFx0bWV0YU1vZGVsOiBvTWV0YU1vZGVsXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQpXG5cdFx0XHQpLnRoZW4oZnVuY3Rpb24ob0ZyYWdtZW50OiBhbnkpIHtcblx0XHRcdFx0bGV0IGFGb3JtRWxlbWVudHM6IGFueVtdID0gW107XG5cdFx0XHRcdGNvbnN0IG1GaWVsZFZhbHVlTWFwOiBhbnkgPSB7fTtcblx0XHRcdFx0bGV0IG9DcmVhdGVCdXR0b246IEJ1dHRvbjtcblx0XHRcdFx0Y29uc3QgdmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5hbGwoXG5cdFx0XHRcdFx0XHRhRm9ybUVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdC5tYXAoZnVuY3Rpb24ob0Zvcm1FbGVtZW50OiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0Zvcm1FbGVtZW50LmdldEZpZWxkcygpWzBdO1xuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHQuZmlsdGVyKGZ1bmN0aW9uKG9GaWVsZDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9GaWVsZC5nZXRSZXF1aXJlZCgpO1xuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHQubWFwKGZ1bmN0aW9uKG9GaWVsZDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgc0ZpZWxkSWQgPSBvRmllbGQuZ2V0SWQoKTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoc0ZpZWxkSWQgaW4gbUZpZWxkVmFsdWVNYXApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUobUZpZWxkVmFsdWVNYXBbc0ZpZWxkSWRdKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbih2VmFsdWU6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiB2VmFsdWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9GaWVsZC5nZXRWYWx1ZVN0YXRlKCkgPT09IFZhbHVlU3RhdGUuRXJyb3IgPyB1bmRlZmluZWQgOiBvRmllbGQuZ2V0VmFsdWUoKTtcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbihhUmVzdWx0czogYW55W10pIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGFSZXN1bHRzLmV2ZXJ5KGZ1bmN0aW9uKHZWYWx1ZTogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHZWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZWYWx1ZSAhPT0gbnVsbCAmJiB2VmFsdWUgIT09IFwiXCI7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uKGJFbmFibGVkOiBib29sZWFuKSB7XG5cdFx0XHRcdFx0XHRcdG9DcmVhdGVCdXR0b24uc2V0RW5hYmxlZChiRW5hYmxlZCk7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fTtcblx0XHRcdFx0Y29uc3Qgb0NvbnRyb2xsZXIgPSB7XG5cdFx0XHRcdFx0LypcbiAgICBcdFx0XHRcdFx0XHRcdFx0XHRmaXJlZCBvbiBmb2N1cyBvdXQgZnJvbSBmaWVsZCBvciBvbiBzZWxlY3RpbmcgYSB2YWx1ZSBmcm9tIHRoZSB2YWx1ZWhlbHAuXG4gICAgXHRcdFx0XHRcdFx0XHRcdFx0dGhlIGNyZWF0ZSBidXR0b24gaXMgZW5hYmxlZCB3aGVuIGEgdmFsdWUgaXMgYWRkZWQuXG4gICAgXHRcdFx0XHRcdFx0XHRcdFx0bGl2ZUNoYW5nZSBpcyBub3QgZmlyZWQgd2hlbiB2YWx1ZSBpcyBhZGRlZCBmcm9tIHZhbHVlaGVscC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0XHR2YWx1ZSB2YWxpZGF0aW9uIGlzIG5vdCBkb25lIGZvciBjcmVhdGUgYnV0dG9uIGVuYWJsZW1lbnQuXG4gICAgXHRcdFx0XHRcdFx0XHRcdCovXG5cdFx0XHRcdFx0aGFuZGxlQ2hhbmdlOiBmdW5jdGlvbihvRXZlbnQ6IGFueSkge1xuXHRcdFx0XHRcdFx0bWVzc2FnZUhhbmRsZXIucmVtb3ZlVHJhbnNpdGlvbk1lc3NhZ2VzKCk7XG5cdFx0XHRcdFx0XHRjb25zdCBvRmllbGQgPSBvRXZlbnQuZ2V0U291cmNlKCk7XG5cdFx0XHRcdFx0XHRjb25zdCBzRmllbGRJZCA9IG9FdmVudC5nZXRQYXJhbWV0ZXIoXCJpZFwiKTtcblx0XHRcdFx0XHRcdGNvbnN0IG9GaWVsZFByb21pc2UgPSBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwicHJvbWlzZVwiKTtcblx0XHRcdFx0XHRcdGlmIChvRmllbGRQcm9taXNlKSB7XG5cdFx0XHRcdFx0XHRcdG1GaWVsZFZhbHVlTWFwW3NGaWVsZElkXSA9IG9GaWVsZFByb21pc2UudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0ZpZWxkLmdldFZhbHVlKCk7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0dmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMoKTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdC8qXG4gICAgXHRcdFx0XHRcdFx0XHRcdFx0ZmlyZWQgb24ga2V5IHByZXNzLiB0aGUgY3JlYXRlIGJ1dHRvbiBpcyBlbmFibGVkIHdoZW4gYSB2YWx1ZSBpcyBhZGRlZC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0XHRsaXZlQ2hhbmdlIGlzIG5vdCBmaXJlZCB3aGVuIHZhbHVlIGlzIGFkZGVkIGZyb20gdmFsdWVoZWxwLlxuICAgIFx0XHRcdFx0XHRcdFx0XHRcdHZhbHVlIHZhbGlkYXRpb24gaXMgbm90IGRvbmUgZm9yIGNyZWF0ZSBidXR0b24gZW5hYmxlbWVudC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0Ki9cblx0XHRcdFx0XHRoYW5kbGVMaXZlQ2hhbmdlOiBmdW5jdGlvbihvRXZlbnQ6IGFueSkge1xuXHRcdFx0XHRcdFx0Y29uc3Qgc0ZpZWxkSWQgPSBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwiaWRcIik7XG5cdFx0XHRcdFx0XHRjb25zdCB2VmFsdWUgPSBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwidmFsdWVcIik7XG5cdFx0XHRcdFx0XHRtRmllbGRWYWx1ZU1hcFtzRmllbGRJZF0gPSB2VmFsdWU7XG5cdFx0XHRcdFx0XHR2YWxpZGF0ZVJlcXVpcmVkUHJvcGVydGllcygpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdFx0cmV0dXJuIEZyYWdtZW50LmxvYWQoe1xuXHRcdFx0XHRcdGRlZmluaXRpb246IG9GcmFnbWVudCxcblx0XHRcdFx0XHRjb250cm9sbGVyOiBvQ29udHJvbGxlclxuXHRcdFx0XHR9KS50aGVuKGZ1bmN0aW9uKG9EaWFsb2dDb250ZW50OiBhbnkpIHtcblx0XHRcdFx0XHRvRGlhbG9nID0gbmV3IERpYWxvZyh7XG5cdFx0XHRcdFx0XHR0aXRsZTogQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9TQVBGRV9BQ1RJT05fQ1JFQVRFXCIsIG9SZXNvdXJjZUJ1bmRsZSksXG5cdFx0XHRcdFx0XHRjb250ZW50OiBbb0RpYWxvZ0NvbnRlbnRdLFxuXHRcdFx0XHRcdFx0YmVnaW5CdXR0b246IHtcblx0XHRcdFx0XHRcdFx0dGV4dDogQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9TQVBGRV9BQ1RJT05fQ1JFQVRFX0JVVFRPTlwiLCBvUmVzb3VyY2VCdW5kbGUpLFxuXHRcdFx0XHRcdFx0XHR0eXBlOiBcIkVtcGhhc2l6ZWRcIixcblx0XHRcdFx0XHRcdFx0cHJlc3M6IGZ1bmN0aW9uKG9FdmVudDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb0NyZWF0ZUJ1dHRvbiA9IG9FdmVudC5nZXRTb3VyY2UoKTtcblx0XHRcdFx0XHRcdFx0XHRvQ3JlYXRlQnV0dG9uLnNldEVuYWJsZWQoZmFsc2UpO1xuXHRcdFx0XHRcdFx0XHRcdEJ1c3lMb2NrZXIubG9jayhvRGlhbG9nKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5hbGwoXG5cdFx0XHRcdFx0XHRcdFx0XHRPYmplY3Qua2V5cyhtRmllbGRWYWx1ZU1hcCkubWFwKGZ1bmN0aW9uKHNLZXk6IHN0cmluZykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbUZpZWxkVmFsdWVNYXBbc0tleV0udGhlbihmdW5jdGlvbihvVmFsdWU6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IG9EaWFsb2dWYWx1ZTogYW55ID0ge307XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b0RpYWxvZ1ZhbHVlW3NLZXldID0gb1ZhbHVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBvRGlhbG9nVmFsdWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbihhVmFsdWVzOiBhbnlbXSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRsZXQgb25CZWZvcmVDcmVhdGVQcm9taXNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMuYmVmb3JlQ3JlYXRlQ2FsbEJhY2spIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvbkJlZm9yZUNyZWF0ZVByb21pc2UgPSBtUGFyYW1ldGVycy5iZWZvcmVDcmVhdGVDYWxsQmFjayh7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjb250ZXh0UGF0aDogb0xpc3RCaW5kaW5nICYmIG9MaXN0QmluZGluZy5nZXRQYXRoKCksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjcmVhdGVQYXJhbWV0ZXJzOiBhVmFsdWVzXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b25CZWZvcmVDcmVhdGVQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9uQmVmb3JlQ3JlYXRlUHJvbWlzZTtcblx0XHRcdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb1Byb21pc2UgPSB0aGF0Lm9uQWZ0ZXJDcmVhdGVDb21wbGV0aW9uKFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9UcmFuc2llbnRMaXN0QmluZGluZyxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvVHJhbnNpZW50Q29udGV4dCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVyc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRvTW9kZWwuc3VibWl0QmF0Y2goXCJzdWJtaXRMYXRlclwiKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9Qcm9taXNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uKG9SZXNwb25zZTogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG9EaWFsb2cuc2V0QmluZGluZ0NvbnRleHQobnVsbCBhcyBhbnkpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRvRGlhbG9nLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUob1Jlc3BvbnNlKTtcblx0XHRcdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmVqZWN0KG9FcnJvcik7XG5cdFx0XHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKG9EaWFsb2cpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRvQ3JlYXRlQnV0dG9uLnNldEVuYWJsZWQodHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZXMoKTtcblx0XHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0ZW5kQnV0dG9uOiB7XG5cdFx0XHRcdFx0XHRcdHRleHQ6IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFwiQ19DT01NT05fQUNUSU9OX1BBUkFNRVRFUl9ESUFMT0dfQ0FOQ0VMXCIsIG9SZXNvdXJjZUJ1bmRsZSksXG5cdFx0XHRcdFx0XHRcdHByZXNzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRvRGlhbG9nLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRhZnRlckNsb3NlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0Ly8gc2hvdyBmb290ZXIgYXMgcGVyIFVYIGd1aWRlbGluZXMgd2hlbiBkaWFsb2cgaXMgbm90IG9wZW5cblx0XHRcdFx0XHRcdFx0KG9EaWFsb2cuZ2V0QmluZGluZ0NvbnRleHQoXCJpbnRlcm5hbFwiKSBhcyBJbnRlcm5hbE1vZGVsQ29udGV4dCk/LnNldFByb3BlcnR5KFwiaXNDcmVhdGVEaWFsb2dPcGVuXCIsIGZhbHNlKTtcblx0XHRcdFx0XHRcdFx0b0RpYWxvZy5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHRcdGlmICghYlN1Y2Nlc3MpIHtcblx0XHRcdFx0XHRcdFx0XHRyZWplY3Qoe1xuXHRcdFx0XHRcdFx0XHRcdFx0YkRlbGV0ZVRyYW5zaWVudENvbnRleHQ6IHRydWVcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gYXMgYW55KTtcblx0XHRcdFx0XHRhRm9ybUVsZW1lbnRzID0gb0RpYWxvZ0NvbnRlbnRcblx0XHRcdFx0XHRcdC5nZXRBZ2dyZWdhdGlvbihcImZvcm1cIilcblx0XHRcdFx0XHRcdC5nZXRBZ2dyZWdhdGlvbihcImZvcm1Db250YWluZXJzXCIpWzBdXG5cdFx0XHRcdFx0XHQuZ2V0QWdncmVnYXRpb24oXCJmb3JtRWxlbWVudHNcIik7XG5cdFx0XHRcdFx0aWYgKG9QYXJlbnRDb250cm9sICYmIG9QYXJlbnRDb250cm9sLmFkZERlcGVuZGVudCkge1xuXHRcdFx0XHRcdFx0Ly8gaWYgdGhlcmUgaXMgYSBwYXJlbnQgY29udHJvbCBzcGVjaWZpZWQgYWRkIHRoZSBkaWFsb2cgYXMgZGVwZW5kZW50XG5cdFx0XHRcdFx0XHRvUGFyZW50Q29udHJvbC5hZGREZXBlbmRlbnQob0RpYWxvZyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG9DcmVhdGVCdXR0b24gPSBvRGlhbG9nLmdldEJlZ2luQnV0dG9uKCk7XG5cdFx0XHRcdFx0b0RpYWxvZy5zZXRCaW5kaW5nQ29udGV4dChvVHJhbnNpZW50Q29udGV4dCk7XG5cdFx0XHRcdFx0cmV0dXJuIENvbW1vblV0aWxzLnNldFVzZXJEZWZhdWx0cyhcblx0XHRcdFx0XHRcdG9BcHBDb21wb25lbnQsXG5cdFx0XHRcdFx0XHRhSW1tdXRhYmxlRmllbGRzLFxuXHRcdFx0XHRcdFx0b1RyYW5zaWVudENvbnRleHQsXG5cdFx0XHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmNyZWF0ZUFjdGlvbixcblx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmRhdGFcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0dmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMoKTtcblx0XHRcdFx0XHRcdFx0Ly8gZm9vdGVyIG11c3Qgbm90IGJlIHZpc2libGUgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW4gYXMgcGVyIFVYIGd1aWRlbGluZXNcblx0XHRcdFx0XHRcdFx0KG9EaWFsb2cuZ2V0QmluZGluZ0NvbnRleHQoXCJpbnRlcm5hbFwiKSBhcyBJbnRlcm5hbE1vZGVsQ29udGV4dCkuc2V0UHJvcGVydHkoXCJpc0NyZWF0ZURpYWxvZ09wZW5cIiwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdG9EaWFsb2cub3BlbigpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VzKCkudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3Qob0Vycm9yKTtcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXHRvbkFmdGVyQ3JlYXRlQ29tcGxldGlvbihvTGlzdEJpbmRpbmc6IGFueSwgb05ld0RvY3VtZW50Q29udGV4dDogYW55LCBtUGFyYW1ldGVyczogYW55KSB7XG5cdFx0bGV0IGZuUmVzb2x2ZTogRnVuY3Rpb24sIGZuUmVqZWN0OiBGdW5jdGlvbjtcblx0XHRjb25zdCBvUHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdFx0Zm5SZXNvbHZlID0gcmVzb2x2ZTtcblx0XHRcdGZuUmVqZWN0ID0gcmVqZWN0O1xuXHRcdH0pO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzO1xuXHRcdC8vIFdvcmthcm91bmQgc3VnZ2VzdGVkIGJ5IE9EYXRhIG1vZGVsIHY0IGNvbGxlYWd1ZXNcblx0XHRjb25zdCBmbkNyZWF0ZUNvbXBsZXRlZCA9IGZ1bmN0aW9uKG9FdmVudDogYW55KSB7XG5cdFx0XHRjb25zdCBvQ29udGV4dCA9IG9FdmVudC5nZXRQYXJhbWV0ZXIoXCJjb250ZXh0XCIpLFxuXHRcdFx0XHRiU3VjY2VzcyA9IG9FdmVudC5nZXRQYXJhbWV0ZXIoXCJzdWNjZXNzXCIpO1xuXHRcdFx0aWYgKG9Db250ZXh0ID09PSBvTmV3RG9jdW1lbnRDb250ZXh0KSB7XG5cdFx0XHRcdG9MaXN0QmluZGluZy5kZXRhY2hDcmVhdGVDb21wbGV0ZWQoZm5DcmVhdGVDb21wbGV0ZWQsIHRoYXQpO1xuXHRcdFx0XHRpZiAoIWJTdWNjZXNzKSB7XG5cdFx0XHRcdFx0Y29uc3Qgb0Vycm9yOiBhbnkgPSB7IGJEZWxldGVUcmFuc2llbnRDb250ZXh0OiBmYWxzZSB9O1xuXHRcdFx0XHRcdGlmICghbVBhcmFtZXRlcnMua2VlcFRyYW5zaWVudENvbnRleHRPbkZhaWxlZCkge1xuXHRcdFx0XHRcdFx0Ly8gdGhlIGNvbnRleHQgaXMgZGVsZXRlZFxuXHRcdFx0XHRcdFx0b0Vycm9yLmJEZWxldGVUcmFuc2llbnRDb250ZXh0ID0gdHJ1ZTtcblx0XHRcdFx0XHRcdC8vIHRoaXMgaXMgbmVlZGVkIHRvIGF2b2lkIGNvbnNvbGUgZXJyb3JzIFRPIGJlIGNoZWNrZWQgd2l0aCBtb2RlbCBjb2xsZWFndWVzXG5cdFx0XHRcdFx0XHRvQ29udGV4dFxuXHRcdFx0XHRcdFx0XHQuY3JlYXRlZCgpXG5cdFx0XHRcdFx0XHRcdC50aGVuKHVuZGVmaW5lZCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0TG9nLnRyYWNlKFwidHJhbnNpZW50IGNyZWF0aW9uIGNvbnRleHQgZGVsZXRlZFwiKTtcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0TG9nLnRyYWNlKFwidHJhbnNpZW50IGNyZWF0aW9uIGNvbnRleHQgZGVsZXRpb24gZXJyb3JcIiwgb0Vycm9yKTtcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHQvLyBpZiBjdXJyZW50IHN0YXRlIGlzIHRyYW5zaWVudCAoLi4uKSwgYnJvd3NlciB3aWxsIGNvbWUgYmFjayB0byBwcmV2aW91cyBzdGF0ZVxuXHRcdFx0XHRcdFx0b0Vycm9yLm5hdmlnYXRlQmFja0Zyb21UcmFuc2llbnRTdGF0ZSA9IHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGZuUmVqZWN0KG9FcnJvcik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm5SZXNvbHZlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHRcdG9MaXN0QmluZGluZy5hdHRhY2hDcmVhdGVDb21wbGV0ZWQoZm5DcmVhdGVDb21wbGV0ZWQsIHRoaXMpO1xuXHRcdHJldHVybiBvUHJvbWlzZTtcblx0fVxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSBuYW1lIG9mIHRoZSBOZXdBY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAc3RhdGljXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyLl9nZXROZXdBY3Rpb25cblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvU3RhcnR1cFBhcmFtZXRlcnMgU3RhcnR1cCBwYXJhbWV0ZXJzIG9mIHRoZSBhcHBsaWNhdGlvblxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc0NyZWF0ZUhhc2ggSGFzaCB0byBiZSBjaGVja2VkIGZvciBhY3Rpb24gdHlwZVxuXHQgKiBAcGFyYW0ge29iamVjdH0gb01ldGFNb2RlbCBUaGUgTWV0YU1vZGVsIHVzZWQgdG8gY2hlY2sgZm9yIE5ld0FjdGlvbiBwYXJhbWV0ZXJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNNZXRhUGF0aCBUaGUgTWV0YVBhdGhcblx0ICogQHJldHVybnMge3N0cmluZ30gVGhlIG5hbWUgb2YgdGhlIGFjdGlvblxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqKi9cblx0X2dldE5ld0FjdGlvbihvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSwgc0NyZWF0ZUhhc2g6IHN0cmluZywgb01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWwsIHNNZXRhUGF0aDogc3RyaW5nKSB7XG5cdFx0bGV0IHNOZXdBY3Rpb247XG5cblx0XHRpZiAob1N0YXJ0dXBQYXJhbWV0ZXJzICYmIG9TdGFydHVwUGFyYW1ldGVycy5wcmVmZXJyZWRNb2RlICYmIHNDcmVhdGVIYXNoLmluZGV4T2YoXCJpLWFjdGlvbj1jcmVhdGVXaXRoXCIpID4gLTEpIHtcblx0XHRcdGNvbnN0IHNQcmVmZXJyZWRNb2RlID0gb1N0YXJ0dXBQYXJhbWV0ZXJzLnByZWZlcnJlZE1vZGVbMF07XG5cdFx0XHRzTmV3QWN0aW9uID1cblx0XHRcdFx0c1ByZWZlcnJlZE1vZGUuaW5kZXhPZihcImNyZWF0ZVdpdGg6XCIpID4gLTEgPyBzUHJlZmVycmVkTW9kZS5zdWJzdHIoc1ByZWZlcnJlZE1vZGUubGFzdEluZGV4T2YoXCI6XCIpICsgMSkgOiB1bmRlZmluZWQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNOZXdBY3Rpb24gPVxuXHRcdFx0XHRvTWV0YU1vZGVsICYmIG9NZXRhTW9kZWwuZ2V0T2JqZWN0ICE9PSB1bmRlZmluZWRcblx0XHRcdFx0XHQ/IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlNlc3Npb24udjEuU3RpY2t5U2Vzc2lvblN1cHBvcnRlZC9OZXdBY3Rpb25cIikgfHxcblx0XHRcdFx0XHQgIG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdFJvb3QvTmV3QWN0aW9uXCIpXG5cdFx0XHRcdFx0OiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdHJldHVybiBzTmV3QWN0aW9uO1xuXHR9XG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgdGhlIGxhYmVsIGZvciB0aGUgdGl0bGUgb2YgYSBzcGVjaWZpYyBjcmVhdGUgYWN0aW9uIGRpYWxvZywgZS5nLiBDcmVhdGUgU2FsZXMgT3JkZXIgZnJvbSBRdW90YXRpb24uXG5cdCAqXG5cdCAqIFRoZSBmb2xsb3dpbmcgcHJpb3JpdHkgaXMgYXBwbGllZDpcblx0ICogMS4gbGFiZWwgb2YgbGluZS1pdGVtIGFubm90YXRpb24uXG5cdCAqIDIuIGxhYmVsIGFubm90YXRlZCBpbiB0aGUgYWN0aW9uLlxuXHQgKiAzLiBcIkNyZWF0ZVwiIGFzIGEgY29uc3RhbnQgZnJvbSBpMThuLlxuXHQgKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQHN0YXRpY1xuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAbmFtZSBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlci5fZ2V0U3BlY2lmaWNDcmVhdGVBY3Rpb25EaWFsb2dMYWJlbFxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHBhcmFtIHtvYmplY3R9IG9NZXRhTW9kZWwgVGhlIE1ldGFNb2RlbCB1c2VkIHRvIGNoZWNrIGZvciB0aGUgTmV3QWN0aW9uIHBhcmFtZXRlclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc01ldGFQYXRoIFRoZSBNZXRhUGF0aFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc05ld0FjdGlvbiBDb250YWlucyB0aGUgbmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGV4ZWN1dGVkXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvUmVzb3VyY2VCdW5kbGVDb3JlIFJlc291cmNlQnVuZGxlIHRvIGFjY2VzcyB0aGUgZGVmYXVsdCBDcmVhdGUgbGFiZWxcblx0ICogQHJldHVybnMge3N0cmluZ30gVGhlIGxhYmVsIGZvciB0aGUgQ3JlYXRlIEFjdGlvbiBEaWFsb2dcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKiovXG5cdF9nZXRTcGVjaWZpY0NyZWF0ZUFjdGlvbkRpYWxvZ0xhYmVsKFxuXHRcdG9NZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsLFxuXHRcdHNNZXRhUGF0aDogc3RyaW5nLFxuXHRcdHNOZXdBY3Rpb246IHN0cmluZyxcblx0XHRvUmVzb3VyY2VCdW5kbGVDb3JlOiBSZXNvdXJjZUJ1bmRsZVxuXHQpIHtcblx0XHRjb25zdCBmbkdldExhYmVsRnJvbUxpbmVJdGVtQW5ub3RhdGlvbiA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKG9NZXRhTW9kZWwgJiYgb01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCIvQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkxpbmVJdGVtXCIpKSB7XG5cdFx0XHRcdGNvbnN0IGlMaW5lSXRlbUluZGV4ID0gb01ldGFNb2RlbFxuXHRcdFx0XHRcdC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCIvQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkxpbmVJdGVtXCIpXG5cdFx0XHRcdFx0LmZpbmRJbmRleChmdW5jdGlvbihvTGluZUl0ZW06IGFueSkge1xuXHRcdFx0XHRcdFx0Y29uc3QgYUxpbmVJdGVtQWN0aW9uID0gb0xpbmVJdGVtLkFjdGlvbiA/IG9MaW5lSXRlbS5BY3Rpb24uc3BsaXQoXCIoXCIpIDogdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGFMaW5lSXRlbUFjdGlvbiA/IGFMaW5lSXRlbUFjdGlvblswXSA9PT0gc05ld0FjdGlvbiA6IGZhbHNlO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm4gaUxpbmVJdGVtSW5kZXggPiAtMVxuXHRcdFx0XHRcdD8gb01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCIvQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlVJLnYxLkxpbmVJdGVtXCIpW2lMaW5lSXRlbUluZGV4XS5MYWJlbFxuXHRcdFx0XHRcdDogdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0cmV0dXJuIChcblx0XHRcdGZuR2V0TGFiZWxGcm9tTGluZUl0ZW1Bbm5vdGF0aW9uKCkgfHxcblx0XHRcdChvTWV0YU1vZGVsICYmIG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiL1wiICsgc05ld0FjdGlvbiArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5MYWJlbFwiKSkgfHxcblx0XHRcdChvUmVzb3VyY2VCdW5kbGVDb3JlICYmIG9SZXNvdXJjZUJ1bmRsZUNvcmUuZ2V0VGV4dChcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX1NBUEZFX0FDVElPTl9DUkVBVEVcIikpXG5cdFx0KTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBUcmFuc2FjdGlvbkhlbHBlcjtcbiJdfQ==