@sapui5/sap.fe.core 1.101.1 → 1.102.2

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