@magic-xpa/engine 4.1100.0-dev4110.23 → 4.1100.0-dev4110.236

Sign up to get free protection for your applications and to get access to all the features.
Files changed (516) hide show
  1. package/{esm2020 → esm2022}/index.mjs +188 -188
  2. package/{esm2020 → esm2022}/magic-xpa-engine.mjs +1 -1
  3. package/esm2022/src/AccessHelper.mjs +15 -0
  4. package/esm2022/src/ClientManager.mjs +416 -0
  5. package/esm2022/src/CommandsProcessorBase.mjs +56 -0
  6. package/esm2022/src/CommandsProcessorManager.mjs +26 -0
  7. package/esm2022/src/CommandsTable.mjs +162 -0
  8. package/esm2022/src/ConstInterface.mjs +517 -0
  9. package/{esm2020 → esm2022}/src/CurrentClientVersion.mjs +2 -2
  10. package/esm2022/src/FlowMonitorInterface.mjs +16 -0
  11. package/esm2022/src/GUIManager.mjs +62 -0
  12. package/esm2022/src/GlobalCommandsManager.mjs +34 -0
  13. package/esm2022/src/GuiEventsProcessor.mjs +156 -0
  14. package/{esm2020 → esm2022}/src/ICommandsTable.mjs +1 -1
  15. package/esm2022/src/ServerConfig.mjs +122 -0
  16. package/{esm2020 → esm2022}/src/bridge/IGuiEvent.mjs +19 -19
  17. package/esm2022/src/bridge/MagicBridge.mjs +41 -0
  18. package/esm2022/src/commands/ClientOriginatedCommandTaskTag.mjs +12 -0
  19. package/{esm2020 → esm2022}/src/commands/ClientToServer/AddUserLocateDataViewCommand.mjs +8 -8
  20. package/{esm2020 → esm2022}/src/commands/ClientToServer/AddUserRangeDataviewCommand.mjs +9 -9
  21. package/{esm2020 → esm2022}/src/commands/ClientToServer/AddUserSortDataViewCommand.mjs +9 -9
  22. package/{esm2020 → esm2022}/src/commands/ClientToServer/BrowserEscEventCommand.mjs +23 -23
  23. package/{esm2020 → esm2022}/src/commands/ClientToServer/ClientOriginatedCommand.mjs +14 -14
  24. package/esm2022/src/commands/ClientToServer/ClientOriginatedCommandSerializer.mjs +60 -0
  25. package/{esm2020 → esm2022}/src/commands/ClientToServer/ColumnSortEventCommand.mjs +26 -26
  26. package/esm2022/src/commands/ClientToServer/CommandFactory.mjs +260 -0
  27. package/esm2022/src/commands/ClientToServer/CommandSerializationHelper.mjs +67 -0
  28. package/{esm2020 → esm2022}/src/commands/ClientToServer/ComputeEventCommand.mjs +23 -23
  29. package/{esm2020 → esm2022}/src/commands/ClientToServer/ContextTerminationEventCommand.mjs +20 -20
  30. package/{esm2020 → esm2022}/src/commands/ClientToServer/ContextTimeoutResetCommand.mjs +19 -19
  31. package/{esm2020 → esm2022}/src/commands/ClientToServer/ControlItemsRefreshCommand.mjs +8 -8
  32. package/esm2022/src/commands/ClientToServer/DataViewOutputCommand.mjs +13 -0
  33. package/{esm2020 → esm2022}/src/commands/ClientToServer/DataviewCommand.mjs +44 -44
  34. package/esm2022/src/commands/ClientToServer/EvaluateCommand.mjs +37 -0
  35. package/esm2022/src/commands/ClientToServer/EventCommand.mjs +40 -0
  36. package/esm2022/src/commands/ClientToServer/ExecOperCommand.mjs +67 -0
  37. package/esm2022/src/commands/ClientToServer/FetchDataControlValuesEventCommand.mjs +22 -0
  38. package/{esm2020 → esm2022}/src/commands/ClientToServer/GlobalParamsQueryCommand.mjs +10 -10
  39. package/{esm2020 → esm2022}/src/commands/ClientToServer/ICommandTaskTag.mjs +1 -1
  40. package/{esm2020 → esm2022}/src/commands/ClientToServer/IndexChangeEventCommand.mjs +21 -21
  41. package/esm2022/src/commands/ClientToServer/IniputForceWriteCommand.mjs +23 -0
  42. package/{esm2020 → esm2022}/src/commands/ClientToServer/NonReversibleExitEventCommand.mjs +23 -23
  43. package/{esm2020 → esm2022}/src/commands/ClientToServer/QueryCommand.mjs +20 -20
  44. package/esm2022/src/commands/ClientToServer/RecomputeCommand.mjs +27 -0
  45. package/esm2022/src/commands/ClientToServer/RefreshEventCommand.mjs +27 -0
  46. package/esm2022/src/commands/ClientToServer/RefreshScreenEventCommand.mjs +24 -0
  47. package/esm2022/src/commands/ClientToServer/RollbackEventCommand.mjs +40 -0
  48. package/{esm2020 → esm2022}/src/commands/ClientToServer/SelectProgramCommand.mjs +14 -14
  49. package/{esm2020 → esm2022}/src/commands/ClientToServer/SetTransactionStateDataviewCommand.mjs +9 -9
  50. package/{esm2020 → esm2022}/src/commands/ClientToServer/SubformOpenEventCommand.mjs +21 -21
  51. package/esm2022/src/commands/ClientToServer/SubformRefreshEventCommand.mjs +24 -0
  52. package/esm2022/src/commands/ClientToServer/TransactionCommand.mjs +30 -0
  53. package/{esm2020 → esm2022}/src/commands/ClientToServer/UnloadCommand.mjs +14 -14
  54. package/esm2022/src/commands/ClientToServer/WriteMessageToServerLogCommand.mjs +18 -0
  55. package/esm2022/src/commands/DataViewCommandBase.mjs +8 -0
  56. package/{esm2020 → esm2022}/src/commands/IClientCommand.mjs +1 -1
  57. package/esm2022/src/commands/IClientTargetedCommand.mjs +13 -0
  58. package/{esm2020 → esm2022}/src/commands/IClientToServerCommandInfo.mjs +1 -1
  59. package/esm2022/src/commands/ServerToClient/AbortCommand.mjs +65 -0
  60. package/{esm2020 → esm2022}/src/commands/ServerToClient/AddLocateCommand.mjs +21 -21
  61. package/esm2022/src/commands/ServerToClient/AddRangeCommand.mjs +62 -0
  62. package/esm2022/src/commands/ServerToClient/AddSortCommand.mjs +33 -0
  63. package/esm2022/src/commands/ServerToClient/ClientRefreshCommand.mjs +25 -0
  64. package/esm2022/src/commands/ServerToClient/ClientTargetedCommandBase.mjs +24 -0
  65. package/esm2022/src/commands/ServerToClient/EnhancedVerifyCommand.mjs +45 -0
  66. package/esm2022/src/commands/ServerToClient/OpenURLCommand.mjs +221 -0
  67. package/{esm2020 → esm2022}/src/commands/ServerToClient/ResetLocateCommand.mjs +14 -14
  68. package/{esm2020 → esm2022}/src/commands/ServerToClient/ResetRangeCommand.mjs +14 -14
  69. package/{esm2020 → esm2022}/src/commands/ServerToClient/ResetSortCommand.mjs +14 -14
  70. package/esm2022/src/commands/ServerToClient/ResultCommand.mjs +37 -0
  71. package/esm2022/src/commands/ServerToClient/VerifyCommand.mjs +83 -0
  72. package/esm2022/src/commands/ServerToClient/XMLBasedCommandBuilder.mjs +132 -0
  73. package/{esm2020 → esm2022}/src/communications/IConnectionStateManager.mjs +1 -1
  74. package/esm2022/src/communications/InteractiveCommunicationsFailureHandler.mjs +15 -0
  75. package/{esm2020 → esm2022}/src/data/DataSourceIdKey.mjs +2 -2
  76. package/esm2022/src/data/DataView.mjs +1613 -0
  77. package/{esm2020 → esm2022}/src/data/DataViewBase.mjs +3 -3
  78. package/esm2022/src/data/DataviewManager.mjs +28 -0
  79. package/esm2022/src/data/DataviewManagerBase.mjs +15 -0
  80. package/esm2022/src/data/DvCache.mjs +67 -0
  81. package/esm2022/src/data/Field.mjs +646 -0
  82. package/esm2022/src/data/FieldBase.mjs +15 -0
  83. package/esm2022/src/data/FieldsTable.mjs +103 -0
  84. package/{esm2020 → esm2022}/src/data/IRecordsTable.mjs +1 -1
  85. package/esm2022/src/data/Key.mjs +88 -0
  86. package/esm2022/src/data/Record.mjs +866 -0
  87. package/{esm2020 → esm2022}/src/data/RecordOutOfDataViewException.mjs +15 -15
  88. package/esm2022/src/data/RecordsTable.mjs +267 -0
  89. package/esm2022/src/data/TaskTransactionManager.mjs +103 -0
  90. package/esm2022/src/data/XMLBasedDcValuesBuilder.mjs +74 -0
  91. package/{esm2020 → esm2022}/src/enums.mjs +23 -23
  92. package/esm2022/src/env/EnvVariablesTable.mjs +340 -0
  93. package/esm2022/src/env/Environment.mjs +487 -0
  94. package/{esm2020 → esm2022}/src/env/ILanguageData.mjs +1 -1
  95. package/esm2022/src/env/LanguageData.mjs +227 -0
  96. package/esm2022/src/env/MirrorString.mjs +65 -0
  97. package/esm2022/src/event/ActionManager.mjs +91 -0
  98. package/esm2022/src/event/Event.mjs +1333 -0
  99. package/esm2022/src/event/EventHandler.mjs +766 -0
  100. package/esm2022/src/event/EventHandlerPosition.mjs +204 -0
  101. package/esm2022/src/event/EventsManager.mjs +2988 -0
  102. package/{esm2020 → esm2022}/src/event/IEventsManager.mjs +6 -6
  103. package/esm2022/src/event/RunTimeEvent.mjs +399 -0
  104. package/{esm2020 → esm2022}/src/event/RunTimeEventBase.mjs +3 -3
  105. package/esm2022/src/event/UserEventsTable.mjs +47 -0
  106. package/esm2022/src/exp/ExpTable.mjs +57 -0
  107. package/esm2022/src/exp/Expression.mjs +200 -0
  108. package/esm2022/src/exp/ExpressionDict.mjs +727 -0
  109. package/esm2022/src/exp/ExpressionEvaluator.mjs +4206 -0
  110. package/esm2022/src/exp/ExpressionLocalJpn.mjs +314 -0
  111. package/esm2022/src/exp/GlobalParamsTable.mjs +85 -0
  112. package/esm2022/src/exp/YesNoExp.mjs +36 -0
  113. package/esm2022/src/gui/CreatedFormVector.mjs +23 -0
  114. package/esm2022/src/gui/FormsTable.mjs +66 -0
  115. package/esm2022/src/gui/MgControl.mjs +363 -0
  116. package/esm2022/src/gui/MgForm.mjs +1224 -0
  117. package/esm2022/src/http/HttpManager.mjs +97 -0
  118. package/esm2022/src/http/client/HttpClientAsync.mjs +68 -0
  119. package/esm2022/src/http/client/HttpClientBase.mjs +132 -0
  120. package/esm2022/src/http/client/HttpClientEvents.mjs +39 -0
  121. package/esm2022/src/http/client/HttpClientSync.mjs +42 -0
  122. package/esm2022/src/http/client/HttpUtility.mjs +84 -0
  123. package/{esm2020 → esm2022}/src/http/client/ICommunicationsFailureHandler.mjs +1 -1
  124. package/esm2022/src/remote/AddUserLocateRemoteDataViewCommand.mjs +18 -0
  125. package/esm2022/src/remote/AddUserRangeRemoteDataViewCommand.mjs +18 -0
  126. package/esm2022/src/remote/AddUserSortRemoteDataViewCommand.mjs +18 -0
  127. package/esm2022/src/remote/RemoteCommandsProcessor.mjs +880 -0
  128. package/esm2022/src/remote/RemoteControlItemsRefreshCommand.mjs +25 -0
  129. package/esm2022/src/remote/RemoteDataViewCommandBase.mjs +24 -0
  130. package/esm2022/src/remote/RemoteDataViewCommandFactory.mjs +61 -0
  131. package/{esm2020 → esm2022}/src/remote/RemoteDataViewCommandUpdateNonModifiable.mjs +15 -15
  132. package/{esm2020 → esm2022}/src/remote/RemoteDataviewManager.mjs +17 -17
  133. package/{esm2020 → esm2022}/src/remote/RemoteInitDataViewCommand.mjs +10 -10
  134. package/esm2022/src/remote/ResetUserLocateRemoteDataviewCommand.mjs +17 -0
  135. package/{esm2020 → esm2022}/src/remote/ResetUserRangeRemoteDataviewCommand.mjs +12 -12
  136. package/esm2022/src/remote/ResetUserSortRemoteDataviewCommand.mjs +16 -0
  137. package/esm2022/src/remote/ServerError.mjs +40 -0
  138. package/esm2022/src/remote/SetTransactionStateRemoteDataViewCommand.mjs +20 -0
  139. package/esm2022/src/rt/Argument.mjs +265 -0
  140. package/esm2022/src/rt/ArgumentsList.mjs +103 -0
  141. package/esm2022/src/rt/Boundary.mjs +152 -0
  142. package/esm2022/src/rt/CompMainPrgTable.mjs +63 -0
  143. package/{esm2020 → esm2022}/src/rt/DataviewHeaderBase.mjs +98 -96
  144. package/{esm2020 → esm2022}/src/rt/DataviewHeaderFactory.mjs +6 -6
  145. package/esm2022/src/rt/DataviewHeaders.mjs +53 -0
  146. package/esm2022/src/rt/DataviewHeadersSaxHandler.mjs +38 -0
  147. package/esm2022/src/rt/ExecutionStack.mjs +94 -0
  148. package/{esm2020 → esm2022}/src/rt/ExecutionStackEntry.mjs +17 -17
  149. package/esm2022/src/rt/HandlersTable.mjs +96 -0
  150. package/{esm2020 → esm2022}/src/rt/IDataSourceViewDefinition.mjs +1 -1
  151. package/{esm2020 → esm2022}/src/rt/IDataviewHeader.mjs +1 -1
  152. package/{esm2020 → esm2022}/src/rt/IResultValue.mjs +1 -1
  153. package/esm2022/src/rt/LastFocusedManager.mjs +65 -0
  154. package/esm2022/src/rt/Operation.mjs +735 -0
  155. package/esm2022/src/rt/OperationTable.mjs +67 -0
  156. package/esm2022/src/rt/Recompute.mjs +355 -0
  157. package/esm2022/src/rt/RecomputeTable.mjs +63 -0
  158. package/esm2022/src/rt/RemoteDataviewHeader.mjs +108 -0
  159. package/esm2022/src/rt/ResultValue.mjs +10 -0
  160. package/esm2022/src/rt/TableCache.mjs +177 -0
  161. package/esm2022/src/rt/TableCacheManager.mjs +67 -0
  162. package/esm2022/src/rt/Transaction.mjs +53 -0
  163. package/esm2022/src/security/UserDetails.mjs +71 -0
  164. package/{esm2020 → esm2022}/src/tasks/IMGDataCollection.mjs +1 -1
  165. package/esm2022/src/tasks/MGData.mjs +552 -0
  166. package/esm2022/src/tasks/MGDataCollection.mjs +252 -0
  167. package/esm2022/src/tasks/RCTimer.mjs +63 -0
  168. package/esm2022/src/tasks/RemoteTaskService.mjs +45 -0
  169. package/esm2022/src/tasks/Task.mjs +2499 -0
  170. package/esm2022/src/tasks/TaskBase.mjs +83 -0
  171. package/esm2022/src/tasks/TaskServiceBase.mjs +25 -0
  172. package/esm2022/src/tasks/TasksTable.mjs +80 -0
  173. package/esm2022/src/tasks/sort/Sort.mjs +5 -0
  174. package/esm2022/src/tasks/sort/SortCollection.mjs +67 -0
  175. package/esm2022/src/util/ConstUtils.mjs +14 -0
  176. package/esm2022/src/util/FlowMonitorQueue.mjs +451 -0
  177. package/esm2022/src/util/HeapSort.mjs +70 -0
  178. package/{esm2020 → esm2022}/src/util/IMirrorXML.mjs +1 -1
  179. package/{esm2020 → esm2022}/src/util/IServerConfig.mjs +1 -1
  180. package/{esm2020 → esm2022}/src/util/MgBlockingQueue.mjs +1 -1
  181. package/esm2022/src/util/MgPriorityBlockingQueue.mjs +74 -0
  182. package/esm2022/src/util/MgPriorityQueue.mjs +66 -0
  183. package/{esm2020 → esm2022}/src/util/ParamParseResult.mjs +7 -7
  184. package/esm2022/src/util/PrmMap.mjs +152 -0
  185. package/esm2022/src/util/ReturnResult.mjs +46 -0
  186. package/esm2022/src/util/ReturnResultBase.mjs +18 -0
  187. package/esm2022/src/util/Scrambler.mjs +89 -0
  188. package/esm2022/src/util/UniqueIDUtils.mjs +13 -0
  189. package/esm2022/src/util/cookie.service.mjs +92 -0
  190. package/{fesm2020 → fesm2022}/magic-xpa-engine.mjs +29797 -29693
  191. package/fesm2022/magic-xpa-engine.mjs.map +1 -0
  192. package/index.d.ts +187 -187
  193. package/package.json +8 -14
  194. package/src/AccessHelper.d.ts +20 -20
  195. package/src/ClientManager.d.ts +35 -32
  196. package/src/CommandsProcessorBase.d.ts +23 -23
  197. package/src/CommandsProcessorManager.d.ts +6 -6
  198. package/src/CommandsTable.d.ts +22 -22
  199. package/src/ConstInterface.d.ts +516 -515
  200. package/src/CurrentClientVersion.d.ts +1 -1
  201. package/src/FlowMonitorInterface.d.ts +15 -15
  202. package/src/GUIManager.d.ts +17 -17
  203. package/src/GlobalCommandsManager.d.ts +17 -17
  204. package/src/GuiEventsProcessor.d.ts +24 -24
  205. package/src/ICommandsTable.d.ts +9 -9
  206. package/src/ServerConfig.d.ts +35 -34
  207. package/src/bridge/IGuiEvent.d.ts +19 -19
  208. package/src/bridge/MagicBridge.d.ts +16 -16
  209. package/src/commands/ClientOriginatedCommandTaskTag.d.ts +8 -8
  210. package/src/commands/ClientToServer/AddUserLocateDataViewCommand.d.ts +4 -4
  211. package/src/commands/ClientToServer/AddUserRangeDataviewCommand.d.ts +6 -6
  212. package/src/commands/ClientToServer/AddUserSortDataViewCommand.d.ts +6 -6
  213. package/src/commands/ClientToServer/BrowserEscEventCommand.d.ts +8 -8
  214. package/src/commands/ClientToServer/ClientOriginatedCommand.d.ts +8 -8
  215. package/src/commands/ClientToServer/ClientOriginatedCommandSerializer.d.ts +6 -6
  216. package/src/commands/ClientToServer/ColumnSortEventCommand.d.ts +10 -10
  217. package/src/commands/ClientToServer/CommandFactory.d.ts +64 -64
  218. package/src/commands/ClientToServer/CommandSerializationHelper.d.ts +20 -20
  219. package/src/commands/ClientToServer/ComputeEventCommand.d.ts +8 -8
  220. package/src/commands/ClientToServer/ContextTerminationEventCommand.d.ts +7 -7
  221. package/src/commands/ClientToServer/ContextTimeoutResetCommand.d.ts +7 -7
  222. package/src/commands/ClientToServer/ControlItemsRefreshCommand.d.ts +6 -6
  223. package/src/commands/ClientToServer/DataViewOutputCommand.d.ts +9 -9
  224. package/src/commands/ClientToServer/DataviewCommand.d.ts +32 -32
  225. package/src/commands/ClientToServer/EvaluateCommand.d.ts +15 -15
  226. package/src/commands/ClientToServer/EventCommand.d.ts +15 -15
  227. package/src/commands/ClientToServer/ExecOperCommand.d.ts +23 -23
  228. package/src/commands/ClientToServer/FetchDataControlValuesEventCommand.d.ts +8 -8
  229. package/src/commands/ClientToServer/GlobalParamsQueryCommand.d.ts +5 -5
  230. package/src/commands/ClientToServer/ICommandTaskTag.d.ts +3 -3
  231. package/src/commands/ClientToServer/IndexChangeEventCommand.d.ts +8 -8
  232. package/src/commands/ClientToServer/IniputForceWriteCommand.d.ts +10 -10
  233. package/src/commands/ClientToServer/NonReversibleExitEventCommand.d.ts +8 -8
  234. package/src/commands/ClientToServer/QueryCommand.d.ts +8 -8
  235. package/src/commands/ClientToServer/RecomputeCommand.d.ts +11 -11
  236. package/src/commands/ClientToServer/RefreshEventCommand.d.ts +12 -12
  237. package/src/commands/ClientToServer/RefreshScreenEventCommand.d.ts +10 -10
  238. package/src/commands/ClientToServer/RollbackEventCommand.d.ts +14 -14
  239. package/src/commands/ClientToServer/SelectProgramCommand.d.ts +6 -6
  240. package/src/commands/ClientToServer/SetTransactionStateDataviewCommand.d.ts +5 -5
  241. package/src/commands/ClientToServer/SubformOpenEventCommand.d.ts +8 -8
  242. package/src/commands/ClientToServer/SubformRefreshEventCommand.d.ts +9 -9
  243. package/src/commands/ClientToServer/TransactionCommand.d.ts +12 -12
  244. package/src/commands/ClientToServer/UnloadCommand.d.ts +7 -7
  245. package/src/commands/ClientToServer/WriteMessageToServerLogCommand.d.ts +6 -6
  246. package/src/commands/DataViewCommandBase.d.ts +6 -6
  247. package/src/commands/IClientCommand.d.ts +2 -2
  248. package/src/commands/IClientTargetedCommand.d.ts +12 -12
  249. package/src/commands/IClientToServerCommandInfo.d.ts +3 -3
  250. package/src/commands/ServerToClient/AbortCommand.d.ts +11 -11
  251. package/src/commands/ServerToClient/AddLocateCommand.d.ts +6 -6
  252. package/src/commands/ServerToClient/AddRangeCommand.d.ts +10 -10
  253. package/src/commands/ServerToClient/AddSortCommand.d.ts +9 -9
  254. package/src/commands/ServerToClient/ClientRefreshCommand.d.ts +7 -7
  255. package/src/commands/ServerToClient/ClientTargetedCommandBase.d.ts +12 -12
  256. package/src/commands/ServerToClient/EnhancedVerifyCommand.d.ts +13 -13
  257. package/src/commands/ServerToClient/OpenURLCommand.d.ts +21 -21
  258. package/src/commands/ServerToClient/ResetLocateCommand.d.ts +6 -6
  259. package/src/commands/ServerToClient/ResetRangeCommand.d.ts +6 -6
  260. package/src/commands/ServerToClient/ResetSortCommand.d.ts +6 -6
  261. package/src/commands/ServerToClient/ResultCommand.d.ts +10 -10
  262. package/src/commands/ServerToClient/VerifyCommand.d.ts +17 -17
  263. package/src/commands/ServerToClient/XMLBasedCommandBuilder.d.ts +11 -11
  264. package/src/communications/IConnectionStateManager.d.ts +4 -4
  265. package/src/communications/InteractiveCommunicationsFailureHandler.d.ts +6 -6
  266. package/src/data/DataSourceIdKey.d.ts +2 -2
  267. package/src/data/DataView.d.ts +162 -162
  268. package/src/data/DataViewBase.d.ts +12 -12
  269. package/src/data/DataviewManager.d.ts +14 -14
  270. package/src/data/DataviewManagerBase.d.ts +11 -11
  271. package/src/data/DvCache.d.ts +15 -15
  272. package/src/data/Field.d.ts +103 -103
  273. package/src/data/FieldBase.d.ts +23 -23
  274. package/src/data/FieldsTable.d.ts +27 -27
  275. package/src/data/IRecordsTable.d.ts +7 -7
  276. package/src/data/Key.d.ts +15 -15
  277. package/src/data/Record.d.ts +156 -156
  278. package/src/data/RecordOutOfDataViewException.d.ts +10 -10
  279. package/src/data/RecordsTable.d.ts +38 -38
  280. package/src/data/TaskTransactionManager.d.ts +17 -17
  281. package/src/data/XMLBasedDcValuesBuilder.d.ts +11 -11
  282. package/src/enums.d.ts +21 -21
  283. package/src/env/EnvVariablesTable.d.ts +17 -17
  284. package/src/env/Environment.d.ts +118 -118
  285. package/src/env/ILanguageData.d.ts +3 -3
  286. package/src/env/LanguageData.d.ts +20 -20
  287. package/src/env/MirrorString.d.ts +15 -15
  288. package/src/event/ActionManager.d.ts +14 -14
  289. package/src/event/Event.d.ts +79 -79
  290. package/src/event/EventHandler.d.ts +66 -66
  291. package/src/event/EventHandlerPosition.d.ts +25 -25
  292. package/src/event/EventsManager.d.ts +205 -204
  293. package/src/event/IEventsManager.d.ts +77 -77
  294. package/src/event/RunTimeEvent.d.ts +126 -123
  295. package/src/event/RunTimeEventBase.d.ts +5 -5
  296. package/src/event/UserEventsTable.d.ts +11 -11
  297. package/src/exp/ExpTable.d.ts +11 -11
  298. package/src/exp/Expression.d.ts +37 -37
  299. package/src/exp/ExpressionDict.d.ts +12 -12
  300. package/src/exp/ExpressionEvaluator.d.ts +198 -198
  301. package/src/exp/ExpressionLocalJpn.d.ts +18 -18
  302. package/src/exp/GlobalParamsTable.d.ts +19 -19
  303. package/src/exp/YesNoExp.d.ts +9 -9
  304. package/src/gui/CreatedFormVector.d.ts +10 -10
  305. package/src/gui/FormsTable.d.ts +15 -15
  306. package/src/gui/MgControl.d.ts +60 -60
  307. package/src/gui/MgForm.d.ts +96 -93
  308. package/src/http/HttpManager.d.ts +25 -25
  309. package/src/http/client/HttpClientAsync.d.ts +16 -16
  310. package/src/http/client/HttpClientBase.d.ts +30 -30
  311. package/src/http/client/HttpClientEvents.d.ts +18 -18
  312. package/src/http/client/HttpClientSync.d.ts +17 -17
  313. package/src/http/client/HttpUtility.d.ts +10 -10
  314. package/src/http/client/ICommunicationsFailureHandler.d.ts +5 -5
  315. package/src/remote/AddUserLocateRemoteDataViewCommand.d.ts +8 -8
  316. package/src/remote/AddUserRangeRemoteDataViewCommand.d.ts +8 -8
  317. package/src/remote/AddUserSortRemoteDataViewCommand.d.ts +8 -8
  318. package/src/remote/RemoteCommandsProcessor.d.ts +51 -51
  319. package/src/remote/RemoteControlItemsRefreshCommand.d.ts +8 -8
  320. package/src/remote/RemoteDataViewCommandBase.d.ts +10 -10
  321. package/src/remote/RemoteDataViewCommandFactory.d.ts +6 -6
  322. package/src/remote/RemoteDataViewCommandUpdateNonModifiable.d.ts +8 -8
  323. package/src/remote/RemoteDataviewManager.d.ts +9 -9
  324. package/src/remote/RemoteInitDataViewCommand.d.ts +7 -7
  325. package/src/remote/ResetUserLocateRemoteDataviewCommand.d.ts +7 -7
  326. package/src/remote/ResetUserRangeRemoteDataviewCommand.d.ts +7 -7
  327. package/src/remote/ResetUserSortRemoteDataviewCommand.d.ts +7 -7
  328. package/src/remote/ServerError.d.ts +16 -16
  329. package/src/remote/SetTransactionStateRemoteDataViewCommand.d.ts +8 -8
  330. package/src/rt/Argument.d.ts +36 -36
  331. package/src/rt/ArgumentsList.d.ts +24 -24
  332. package/src/rt/Boundary.d.ts +27 -27
  333. package/src/rt/CompMainPrgTable.d.ts +10 -10
  334. package/src/rt/DataviewHeaderBase.d.ts +34 -34
  335. package/src/rt/DataviewHeaderFactory.d.ts +5 -5
  336. package/src/rt/DataviewHeaders.d.ts +12 -12
  337. package/src/rt/DataviewHeadersSaxHandler.d.ts +10 -10
  338. package/src/rt/ExecutionStack.d.ts +22 -22
  339. package/src/rt/ExecutionStackEntry.d.ts +7 -7
  340. package/src/rt/HandlersTable.d.ts +19 -19
  341. package/src/rt/IDataSourceViewDefinition.d.ts +6 -6
  342. package/src/rt/IDataviewHeader.d.ts +10 -10
  343. package/src/rt/IResultValue.d.ts +4 -4
  344. package/src/rt/LastFocusedManager.d.ts +23 -23
  345. package/src/rt/Operation.d.ts +97 -97
  346. package/src/rt/OperationTable.d.ts +15 -15
  347. package/src/rt/Recompute.d.ts +41 -41
  348. package/src/rt/RecomputeTable.d.ts +9 -9
  349. package/src/rt/RemoteDataviewHeader.d.ts +14 -14
  350. package/src/rt/ResultValue.d.ts +7 -7
  351. package/src/rt/TableCache.d.ts +29 -29
  352. package/src/rt/TableCacheManager.d.ts +10 -10
  353. package/src/rt/Transaction.d.ts +23 -23
  354. package/src/security/UserDetails.d.ts +16 -16
  355. package/src/tasks/IMGDataCollection.d.ts +26 -26
  356. package/src/tasks/MGData.d.ts +63 -63
  357. package/src/tasks/MGDataCollection.d.ts +42 -42
  358. package/src/tasks/RCTimer.d.ts +13 -13
  359. package/src/tasks/RemoteTaskService.d.ts +16 -16
  360. package/src/tasks/Task.d.ts +312 -312
  361. package/src/tasks/TaskBase.d.ts +123 -123
  362. package/src/tasks/TaskServiceBase.d.ts +16 -16
  363. package/src/tasks/TasksTable.d.ts +21 -21
  364. package/src/tasks/sort/Sort.d.ts +4 -4
  365. package/src/tasks/sort/SortCollection.d.ts +11 -11
  366. package/src/util/ConstUtils.d.ts +3 -3
  367. package/src/util/FlowMonitorQueue.d.ts +70 -70
  368. package/src/util/HeapSort.d.ts +6 -6
  369. package/src/util/IMirrorXML.d.ts +6 -6
  370. package/src/util/IServerConfig.d.ts +11 -11
  371. package/src/util/MgBlockingQueue.d.ts +5 -5
  372. package/src/util/MgPriorityBlockingQueue.d.ts +17 -17
  373. package/src/util/MgPriorityQueue.d.ts +13 -13
  374. package/src/util/ParamParseResult.d.ts +6 -6
  375. package/src/util/PrmMap.d.ts +28 -28
  376. package/src/util/ReturnResult.d.ts +18 -18
  377. package/src/util/ReturnResultBase.d.ts +11 -11
  378. package/src/util/Scrambler.d.ts +10 -10
  379. package/src/util/UniqueIDUtils.d.ts +4 -4
  380. package/src/util/cookie.service.d.ts +8 -8
  381. package/esm2020/src/AccessHelper.mjs +0 -9
  382. package/esm2020/src/ClientManager.mjs +0 -399
  383. package/esm2020/src/CommandsProcessorBase.mjs +0 -58
  384. package/esm2020/src/CommandsProcessorManager.mjs +0 -26
  385. package/esm2020/src/CommandsTable.mjs +0 -162
  386. package/esm2020/src/ConstInterface.mjs +0 -516
  387. package/esm2020/src/FlowMonitorInterface.mjs +0 -16
  388. package/esm2020/src/GUIManager.mjs +0 -62
  389. package/esm2020/src/GlobalCommandsManager.mjs +0 -34
  390. package/esm2020/src/GuiEventsProcessor.mjs +0 -154
  391. package/esm2020/src/ServerConfig.mjs +0 -117
  392. package/esm2020/src/bridge/MagicBridge.mjs +0 -41
  393. package/esm2020/src/commands/ClientOriginatedCommandTaskTag.mjs +0 -11
  394. package/esm2020/src/commands/ClientToServer/ClientOriginatedCommandSerializer.mjs +0 -60
  395. package/esm2020/src/commands/ClientToServer/CommandFactory.mjs +0 -260
  396. package/esm2020/src/commands/ClientToServer/CommandSerializationHelper.mjs +0 -69
  397. package/esm2020/src/commands/ClientToServer/DataViewOutputCommand.mjs +0 -13
  398. package/esm2020/src/commands/ClientToServer/EvaluateCommand.mjs +0 -36
  399. package/esm2020/src/commands/ClientToServer/EventCommand.mjs +0 -40
  400. package/esm2020/src/commands/ClientToServer/ExecOperCommand.mjs +0 -67
  401. package/esm2020/src/commands/ClientToServer/FetchDataControlValuesEventCommand.mjs +0 -22
  402. package/esm2020/src/commands/ClientToServer/IniputForceWriteCommand.mjs +0 -23
  403. package/esm2020/src/commands/ClientToServer/RecomputeCommand.mjs +0 -27
  404. package/esm2020/src/commands/ClientToServer/RefreshEventCommand.mjs +0 -27
  405. package/esm2020/src/commands/ClientToServer/RefreshScreenEventCommand.mjs +0 -24
  406. package/esm2020/src/commands/ClientToServer/RollbackEventCommand.mjs +0 -39
  407. package/esm2020/src/commands/ClientToServer/SubformRefreshEventCommand.mjs +0 -24
  408. package/esm2020/src/commands/ClientToServer/TransactionCommand.mjs +0 -28
  409. package/esm2020/src/commands/ClientToServer/WriteMessageToServerLogCommand.mjs +0 -18
  410. package/esm2020/src/commands/DataViewCommandBase.mjs +0 -10
  411. package/esm2020/src/commands/IClientTargetedCommand.mjs +0 -9
  412. package/esm2020/src/commands/ServerToClient/AbortCommand.mjs +0 -65
  413. package/esm2020/src/commands/ServerToClient/AddRangeCommand.mjs +0 -62
  414. package/esm2020/src/commands/ServerToClient/AddSortCommand.mjs +0 -33
  415. package/esm2020/src/commands/ServerToClient/ClientRefreshCommand.mjs +0 -25
  416. package/esm2020/src/commands/ServerToClient/ClientTargetedCommandBase.mjs +0 -27
  417. package/esm2020/src/commands/ServerToClient/EnhancedVerifyCommand.mjs +0 -45
  418. package/esm2020/src/commands/ServerToClient/OpenURLCommand.mjs +0 -221
  419. package/esm2020/src/commands/ServerToClient/ResultCommand.mjs +0 -37
  420. package/esm2020/src/commands/ServerToClient/VerifyCommand.mjs +0 -83
  421. package/esm2020/src/commands/ServerToClient/XMLBasedCommandBuilder.mjs +0 -132
  422. package/esm2020/src/communications/InteractiveCommunicationsFailureHandler.mjs +0 -17
  423. package/esm2020/src/data/DataView.mjs +0 -1610
  424. package/esm2020/src/data/DataviewManager.mjs +0 -28
  425. package/esm2020/src/data/DataviewManagerBase.mjs +0 -15
  426. package/esm2020/src/data/DvCache.mjs +0 -67
  427. package/esm2020/src/data/Field.mjs +0 -646
  428. package/esm2020/src/data/FieldBase.mjs +0 -18
  429. package/esm2020/src/data/FieldsTable.mjs +0 -103
  430. package/esm2020/src/data/Key.mjs +0 -88
  431. package/esm2020/src/data/Record.mjs +0 -846
  432. package/esm2020/src/data/RecordsTable.mjs +0 -267
  433. package/esm2020/src/data/TaskTransactionManager.mjs +0 -103
  434. package/esm2020/src/data/XMLBasedDcValuesBuilder.mjs +0 -74
  435. package/esm2020/src/env/EnvVariablesTable.mjs +0 -340
  436. package/esm2020/src/env/Environment.mjs +0 -489
  437. package/esm2020/src/env/LanguageData.mjs +0 -226
  438. package/esm2020/src/env/MirrorString.mjs +0 -65
  439. package/esm2020/src/event/ActionManager.mjs +0 -91
  440. package/esm2020/src/event/Event.mjs +0 -1333
  441. package/esm2020/src/event/EventHandler.mjs +0 -766
  442. package/esm2020/src/event/EventHandlerPosition.mjs +0 -204
  443. package/esm2020/src/event/EventsManager.mjs +0 -2975
  444. package/esm2020/src/event/RunTimeEvent.mjs +0 -392
  445. package/esm2020/src/event/UserEventsTable.mjs +0 -47
  446. package/esm2020/src/exp/ExpTable.mjs +0 -59
  447. package/esm2020/src/exp/Expression.mjs +0 -200
  448. package/esm2020/src/exp/ExpressionDict.mjs +0 -727
  449. package/esm2020/src/exp/ExpressionEvaluator.mjs +0 -4212
  450. package/esm2020/src/exp/ExpressionLocalJpn.mjs +0 -314
  451. package/esm2020/src/exp/GlobalParamsTable.mjs +0 -85
  452. package/esm2020/src/exp/YesNoExp.mjs +0 -36
  453. package/esm2020/src/gui/CreatedFormVector.mjs +0 -23
  454. package/esm2020/src/gui/FormsTable.mjs +0 -66
  455. package/esm2020/src/gui/MgControl.mjs +0 -353
  456. package/esm2020/src/gui/MgForm.mjs +0 -1181
  457. package/esm2020/src/http/HttpManager.mjs +0 -97
  458. package/esm2020/src/http/client/HttpClientAsync.mjs +0 -67
  459. package/esm2020/src/http/client/HttpClientBase.mjs +0 -132
  460. package/esm2020/src/http/client/HttpClientEvents.mjs +0 -39
  461. package/esm2020/src/http/client/HttpClientSync.mjs +0 -42
  462. package/esm2020/src/http/client/HttpUtility.mjs +0 -84
  463. package/esm2020/src/remote/AddUserLocateRemoteDataViewCommand.mjs +0 -18
  464. package/esm2020/src/remote/AddUserRangeRemoteDataViewCommand.mjs +0 -18
  465. package/esm2020/src/remote/AddUserSortRemoteDataViewCommand.mjs +0 -18
  466. package/esm2020/src/remote/RemoteCommandsProcessor.mjs +0 -880
  467. package/esm2020/src/remote/RemoteControlItemsRefreshCommand.mjs +0 -25
  468. package/esm2020/src/remote/RemoteDataViewCommandBase.mjs +0 -24
  469. package/esm2020/src/remote/RemoteDataViewCommandFactory.mjs +0 -61
  470. package/esm2020/src/remote/ResetUserLocateRemoteDataviewCommand.mjs +0 -17
  471. package/esm2020/src/remote/ResetUserSortRemoteDataviewCommand.mjs +0 -16
  472. package/esm2020/src/remote/ServerError.mjs +0 -40
  473. package/esm2020/src/remote/SetTransactionStateRemoteDataViewCommand.mjs +0 -20
  474. package/esm2020/src/rt/Argument.mjs +0 -265
  475. package/esm2020/src/rt/ArgumentsList.mjs +0 -103
  476. package/esm2020/src/rt/Boundary.mjs +0 -152
  477. package/esm2020/src/rt/CompMainPrgTable.mjs +0 -65
  478. package/esm2020/src/rt/DataviewHeaders.mjs +0 -53
  479. package/esm2020/src/rt/DataviewHeadersSaxHandler.mjs +0 -38
  480. package/esm2020/src/rt/ExecutionStack.mjs +0 -94
  481. package/esm2020/src/rt/HandlersTable.mjs +0 -96
  482. package/esm2020/src/rt/LastFocusedManager.mjs +0 -67
  483. package/esm2020/src/rt/Operation.mjs +0 -735
  484. package/esm2020/src/rt/OperationTable.mjs +0 -67
  485. package/esm2020/src/rt/Recompute.mjs +0 -355
  486. package/esm2020/src/rt/RecomputeTable.mjs +0 -63
  487. package/esm2020/src/rt/RemoteDataviewHeader.mjs +0 -108
  488. package/esm2020/src/rt/ResultValue.mjs +0 -12
  489. package/esm2020/src/rt/TableCache.mjs +0 -177
  490. package/esm2020/src/rt/TableCacheManager.mjs +0 -67
  491. package/esm2020/src/rt/Transaction.mjs +0 -53
  492. package/esm2020/src/security/UserDetails.mjs +0 -71
  493. package/esm2020/src/tasks/MGData.mjs +0 -552
  494. package/esm2020/src/tasks/MGDataCollection.mjs +0 -252
  495. package/esm2020/src/tasks/RCTimer.mjs +0 -63
  496. package/esm2020/src/tasks/RemoteTaskService.mjs +0 -45
  497. package/esm2020/src/tasks/Task.mjs +0 -2495
  498. package/esm2020/src/tasks/TaskBase.mjs +0 -87
  499. package/esm2020/src/tasks/TaskServiceBase.mjs +0 -25
  500. package/esm2020/src/tasks/TasksTable.mjs +0 -80
  501. package/esm2020/src/tasks/sort/Sort.mjs +0 -7
  502. package/esm2020/src/tasks/sort/SortCollection.mjs +0 -67
  503. package/esm2020/src/util/ConstUtils.mjs +0 -14
  504. package/esm2020/src/util/FlowMonitorQueue.mjs +0 -453
  505. package/esm2020/src/util/HeapSort.mjs +0 -70
  506. package/esm2020/src/util/MgPriorityBlockingQueue.mjs +0 -74
  507. package/esm2020/src/util/MgPriorityQueue.mjs +0 -66
  508. package/esm2020/src/util/PrmMap.mjs +0 -151
  509. package/esm2020/src/util/ReturnResult.mjs +0 -46
  510. package/esm2020/src/util/ReturnResultBase.mjs +0 -18
  511. package/esm2020/src/util/Scrambler.mjs +0 -89
  512. package/esm2020/src/util/UniqueIDUtils.mjs +0 -12
  513. package/esm2020/src/util/cookie.service.mjs +0 -92
  514. package/fesm2015/magic-xpa-engine.mjs +0 -30835
  515. package/fesm2015/magic-xpa-engine.mjs.map +0 -1
  516. package/fesm2020/magic-xpa-engine.mjs.map +0 -1
@@ -0,0 +1,880 @@
1
+ import { Base64, JSON_Utils, Logger, Logger_LogLevels, Misc, MsgInterface, OSEnvironment, RequestInfo, StrUtil, XMLConstants } from "@magic-xpa/utils";
2
+ import { Debug, Encoding, Exception, List, NString, RefParam, StringBuilder, isNullOrUndefined, isUndefined } from "@magic-xpa/mscorelib";
3
+ import { Commands, RuntimeContextBase, Styles, UsernamePasswordCredentials } from "@magic-xpa/gui";
4
+ import { ExecOperCommand } from '../commands/ClientToServer/ExecOperCommand';
5
+ import { CommandsProcessorBase, CommandsProcessorBase_SendingInstruction, CommandsProcessorBase_SessionStage } from "../CommandsProcessorBase";
6
+ import { HttpManager } from "../http/HttpManager";
7
+ import { ConstInterface } from "../ConstInterface";
8
+ import { Scrambler } from "../util/Scrambler";
9
+ import { ServerError } from "./ServerError";
10
+ import { FlowMonitorQueue } from "../util/FlowMonitorQueue";
11
+ import { OpeningTaskDetails } from "../tasks/TaskBase";
12
+ import { HttpUtility } from "../http/client/HttpUtility";
13
+ import { HttpClientEvents } from "../http/client/HttpClientEvents";
14
+ import { ServerConfig } from "../ServerConfig";
15
+ import { AccessHelper } from "../AccessHelper";
16
+ import { Environment, Event, EventCommand, EventsManager, GUIManager } from "../../";
17
+ import { MGDataCollection } from "../tasks/MGDataCollection";
18
+ import { timer } from "rxjs";
19
+ var RequestStatus;
20
+ (function (RequestStatus) {
21
+ RequestStatus[RequestStatus["Handled"] = 0] = "Handled";
22
+ RequestStatus[RequestStatus["Retry"] = 1] = "Retry";
23
+ RequestStatus[RequestStatus["Abort"] = 2] = "Abort";
24
+ })(RequestStatus || (RequestStatus = {}));
25
+ export class RemoteCommandsProcessor extends CommandsProcessorBase {
26
+ static RC_NO_CONTEXT_ID = '-1';
27
+ static _instance = null;
28
+ static IsSessionReInitializing = false;
29
+ static lastExceptionMessage = null;
30
+ static InitialUrl = null;
31
+ static WEB_COMMUNICATION_PROTOCOL_VERSION = "14002";
32
+ _lastRequestTime = 0;
33
+ ServerUrl = null;
34
+ static _shouldScrambleAndUnscrambleMessages = false;
35
+ SessionId;
36
+ DelayCommandExecution = false;
37
+ _requestInfo = new RequestInfo();
38
+ static GetInstance() {
39
+ if (RemoteCommandsProcessor._instance === null) {
40
+ RemoteCommandsProcessor._instance = new RemoteCommandsProcessor();
41
+ }
42
+ return RemoteCommandsProcessor._instance;
43
+ }
44
+ constructor() {
45
+ super();
46
+ this.ServerUrl = ServerConfig.Instance.getServerURL();
47
+ HttpManager.GetInstance();
48
+ this.RegisterDelegates();
49
+ }
50
+ CheckAndSetSessionCounter(newSessionCounter) {
51
+ if (newSessionCounter === ConstInterface.SESSION_COUNTER_CLOSE_CTX_INDICATION) {
52
+ Debug.Assert(this.GetSessionCounter() === ConstInterface.SESSION_COUNTER_CLOSE_CTX_INDICATION);
53
+ }
54
+ else {
55
+ Debug.Assert(newSessionCounter === this.GetSessionCounter() + 1);
56
+ this.SetSessionCounter(newSessionCounter);
57
+ Logger.Instance.WriteServerToLog(NString.Format("Session Counter --> {0}", this._sessionCounter));
58
+ }
59
+ }
60
+ ClearSessionCounter() {
61
+ this._sessionCounter = 0;
62
+ Logger.Instance.WriteServerToLog(NString.Format("Session Counter --> {0}", this._sessionCounter));
63
+ }
64
+ SetSessionCounter(newSessionCounter) {
65
+ this._sessionCounter = newSessionCounter;
66
+ }
67
+ get GetLastRequestTime() {
68
+ return this._lastRequestTime;
69
+ }
70
+ async ReStartSession() {
71
+ RemoteCommandsProcessor.IsSessionReInitializing = true;
72
+ await this.StoreSessionReInitializingDataOnLocalStorage();
73
+ let navigateRootRoute = false;
74
+ if (!RuntimeContextBase.Instance.RemovedContextFromServer)
75
+ navigateRootRoute = Environment.Instance.getSpecialRouteToRootProgOnContextRecreation() ? true : false;
76
+ Commands.addRefreshPage(navigateRootRoute, RemoteCommandsProcessor.InitialUrl);
77
+ throw new Exception('');
78
+ }
79
+ async StoreSessionReInitializingDataOnLocalStorage() {
80
+ let mainPrgViewStringForServer = await this.BuildXMLForMainProgramDataView();
81
+ let globalParamsString = AccessHelper.globalParams.mirrorAllToXML();
82
+ let changedEnvVarList = AccessHelper.envParamsTable.mirrorAllToXML();
83
+ let dataStorage = window.localStorage;
84
+ dataStorage.setItem(ConstInterface.IS_SESSION_REINITIALIZING, "true");
85
+ dataStorage.setItem(ConstInterface.MAIN_PROG_VIEW, mainPrgViewStringForServer.toString());
86
+ dataStorage.setItem(ConstInterface.GLOBAL_PARAM_LIST, globalParamsString);
87
+ dataStorage.setItem(ConstInterface.ENV_VAR_LIST, changedEnvVarList);
88
+ dataStorage.setItem(ConstInterface.LAST_EXCEPTION, RemoteCommandsProcessor.lastExceptionMessage);
89
+ if (RuntimeContextBase.Instance.RemovedContextFromServer)
90
+ dataStorage.setItem(ConstInterface.CTX_REMOVED_FROM_SRVR, "1");
91
+ EventsManager.Instance.storeLastSavedRouteEventOnLocalStorage();
92
+ }
93
+ RestoreSessionReInitializingDataFromLocalStorage(key) {
94
+ let dataStorage = window.localStorage;
95
+ let val = dataStorage.getItem(key);
96
+ return val;
97
+ }
98
+ async StartSession() {
99
+ let authenticationCancelled = false;
100
+ let handshakeResponse = null;
101
+ try {
102
+ let lastTypedUserId = null;
103
+ let handshakeInitialTokens = new StringBuilder();
104
+ handshakeInitialTokens.Append(ConstInterface.UTF8TRANS +
105
+ ConstInterface.REQ_APP_NAME + "=" +
106
+ HttpUtility.UrlEncode(ServerConfig.Instance.getAppName(), Encoding.UTF8));
107
+ handshakeInitialTokens.Append("&" + ConstInterface.REQ_ARGS + "=" + ConstInterface.REQ_ARG_ALPHA +
108
+ "<Richclient><Requires EncryptionKey=\"False\"/><RIAProtocolVersion=\"" + RemoteCommandsProcessor.WEB_COMMUNICATION_PROTOCOL_VERSION + "\"/></Richclient>");
109
+ Logger.Instance.WriteDevToLog(NString.Format("Handshake request #1 (not scrambled) : {0}", this.ServerUrl + ConstInterface.REQ_ARG_START +
110
+ ConstInterface.RC_INDICATION_INITIAL + handshakeInitialTokens));
111
+ let handshakeInitialUrl = this.ServerUrl + ConstInterface.REQ_ARG_START +
112
+ ConstInterface.RC_INDICATION_INITIAL +
113
+ ConstInterface.RC_TOKEN_DATA +
114
+ HttpUtility.UrlEncode(Scrambler.Scramble(handshakeInitialTokens.ToString()), Encoding.UTF8);
115
+ Logger.Instance.WriteServerMessagesToLog("");
116
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake request #1: {0}", handshakeInitialUrl));
117
+ let ctxGroup = ServerConfig.Instance.getCtxGroup();
118
+ while (!authenticationCancelled) {
119
+ let requestStatus = new RefParam(RequestStatus.Handled);
120
+ let responseStr = await this.DispatchRequest(handshakeInitialUrl, null, CommandsProcessorBase_SessionStage.HANDSHAKE, requestStatus);
121
+ if (NString.IsNullOrEmpty(responseStr)) {
122
+ throw new ServerError("Client failed to initialize a session." + OSEnvironment.EolSeq +
123
+ "Empty response was received from the web server." + OSEnvironment.EolSeq + OSEnvironment.EolSeq + this.ServerUrl);
124
+ }
125
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake response #1: {0}", responseStr));
126
+ Logger.Instance.WriteServerMessagesToLog("");
127
+ handshakeResponse = new HandshakeResponse(responseStr);
128
+ RuntimeContextBase.Instance.ContextID = handshakeResponse.ContextId;
129
+ this.SessionId = handshakeResponse.GetSessionId;
130
+ HttpManager.GetInstance().HttpCommunicationTimeoutMS = handshakeResponse.HttpTimeout * 1000;
131
+ if (NString.IsNullOrEmpty(ServerConfig.Instance.getCtxGroup())) {
132
+ ctxGroup = handshakeResponse.ContextId;
133
+ }
134
+ let credentials = null;
135
+ if (ServerConfig.Instance.getSkipAuthenticationDialog()) {
136
+ if (ServerConfig.Instance.getUsername() !== null) {
137
+ credentials = new UsernamePasswordCredentials(ServerConfig.Instance.getUsername(), ServerConfig.Instance.getPassword());
138
+ ServerConfig.Instance.setUsername("");
139
+ ServerConfig.Instance.setPassword("");
140
+ }
141
+ }
142
+ else if (handshakeResponse.InputPassword && handshakeResponse.SystemLogin !== HandshakeResponse.SYSTEM_LOGIN_AD) {
143
+ if (lastTypedUserId !== null) {
144
+ let title = AccessHelper.languageData.getConstMessage(MsgInterface.BRKTAB_STR_ERROR);
145
+ let error = AccessHelper.languageData.getConstMessage(MsgInterface.USRINP_STR_BADPASSW);
146
+ await GUIManager.Instance.MessageBox(title, error, Styles.MSGBOX_ICON_ERROR | Styles.MSGBOX_BUTTON_OK);
147
+ }
148
+ }
149
+ if (authenticationCancelled) {
150
+ this.SetSessionCounter(ConstInterface.SESSION_COUNTER_CLOSE_CTX_INDICATION);
151
+ }
152
+ let handshakeAuthUrl = this.PrepareAuthenticationUrl(handshakeResponse.ContextId, ctxGroup, this.GetSessionCounter());
153
+ try {
154
+ if (credentials !== null) {
155
+ let credentialsStr = credentials.Username + ":";
156
+ if (!NString.IsNullOrEmpty(credentials.Password)) {
157
+ credentialsStr = credentialsStr + credentials.Password + ":";
158
+ }
159
+ credentialsStr += handshakeResponse.ContextId;
160
+ credentialsStr = Scrambler.Scramble(credentialsStr);
161
+ credentialsStr = Base64.encode(credentialsStr, true, Encoding.UTF8);
162
+ handshakeAuthUrl += ("&USERNAME=" + HttpUtility.UrlEncode(credentialsStr, Encoding.UTF8));
163
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake request #2: {0}", handshakeAuthUrl));
164
+ let statusRequest = new RefParam(RequestStatus.Handled);
165
+ responseStr = await this.DispatchRequest(handshakeAuthUrl, null, CommandsProcessorBase_SessionStage.HANDSHAKE, statusRequest);
166
+ if (responseStr.indexOf(handshakeResponse.ContextId) === -1) {
167
+ throw new ServerError(AccessHelper.languageData.getConstMessage(MsgInterface.USRINP_STR_BADPASSW));
168
+ }
169
+ ServerConfig.Instance.setUsername(credentials.Username);
170
+ ServerConfig.Instance.setPassword(credentials.Password);
171
+ }
172
+ else {
173
+ let requestStatus = new RefParam(RequestStatus.Handled);
174
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake request #2: {0}", handshakeAuthUrl));
175
+ responseStr = await this.DispatchRequest(handshakeAuthUrl, null, CommandsProcessorBase_SessionStage.HANDSHAKE, requestStatus);
176
+ }
177
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake response #2: {0}", responseStr));
178
+ Logger.Instance.WriteServerMessagesToLog("");
179
+ break;
180
+ }
181
+ catch (ex) {
182
+ if (ex instanceof ServerError) {
183
+ let serverError = ex;
184
+ if (ServerConfig.Instance.getSkipAuthenticationDialog()) {
185
+ switch (serverError.GetCode()) {
186
+ case ServerError.ERR_ACCESS_DENIED:
187
+ case ServerError.ERR_AUTHENTICATION:
188
+ ServerConfig.Instance.setSkipAuthenticationDialog(false);
189
+ throw serverError;
190
+ }
191
+ }
192
+ if (!handshakeResponse.InputPassword)
193
+ throw serverError;
194
+ if (serverError.GetCode() !== ServerError.ERR_AUTHENTICATION &&
195
+ (!authenticationCancelled || serverError.GetCode() !== ServerError.INF_NO_RESULT)) {
196
+ throw serverError;
197
+ }
198
+ }
199
+ else
200
+ throw ex;
201
+ }
202
+ }
203
+ ServerConfig.Instance.setSkipAuthenticationDialog(true);
204
+ ServerConfig.Instance.setCtxGroup(ctxGroup);
205
+ RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages = handshakeResponse.ScrambleMessages;
206
+ if (Logger.Instance.LogLevel !== Logger_LogLevels.Basic) {
207
+ let maxInternalLogLevel = handshakeResponse.MaxInternalLogLevel;
208
+ if (maxInternalLogLevel !== null) {
209
+ let maxLogLevel = this.parseLogLevel(maxInternalLogLevel);
210
+ if (maxLogLevel < Logger.Instance.LogLevel) {
211
+ ServerConfig.Instance.setInternalLogLevel(maxInternalLogLevel);
212
+ Logger.Instance.WriteToLog(NString.Format("Internal log level was restricted to '{0}' by the Magic xpa server.", maxInternalLogLevel), false);
213
+ Logger.Instance.LogLevel = maxLogLevel;
214
+ }
215
+ }
216
+ }
217
+ if (!authenticationCancelled) {
218
+ await this.ExecuteInitialRequest();
219
+ }
220
+ }
221
+ catch (ex) {
222
+ if (ex instanceof ServerError)
223
+ throw ex;
224
+ if (isNullOrUndefined(ex.InnerException))
225
+ throw new ServerError(ex.message, new Exception(ex));
226
+ else
227
+ throw new ServerError(ex.message, ex.InnerException);
228
+ }
229
+ return !authenticationCancelled;
230
+ }
231
+ PrepareAuthenticationUrl(contextId, ctxGroup, sessionCount) {
232
+ let handshakeAuthUrl = this.ServerUrl + ConstInterface.REQ_ARG_START +
233
+ ConstInterface.RC_INDICATION + ConstInterface.UTF8TRANS +
234
+ ConstInterface.RC_TOKEN_CTX_ID + contextId;
235
+ if (!isNullOrUndefined(this.SessionId))
236
+ handshakeAuthUrl += (ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.RC_TOKEN_SESSION_ID + this.SessionId);
237
+ handshakeAuthUrl += (ConstInterface.REQ_ARG_SEPARATOR +
238
+ ConstInterface.RC_TOKEN_SESSION_COUNT + sessionCount +
239
+ ConstInterface.REQ_ARG_SEPARATOR +
240
+ ConstInterface.RC_TOKEN_CTX_GROUP + ctxGroup +
241
+ ConstInterface.REQ_ARG_SEPARATOR +
242
+ ConstInterface.RC_AUTHENTICATION_REQUEST);
243
+ return handshakeAuthUrl;
244
+ }
245
+ async ExecuteInitialRequest() {
246
+ await this.Execute_1(CommandsProcessorBase_SendingInstruction.TASKS_AND_COMMANDS, CommandsProcessorBase_SessionStage.INITIAL, null);
247
+ }
248
+ GetTaskTree(task) {
249
+ let taskTree = new List();
250
+ while (!isNullOrUndefined(task)) {
251
+ taskTree.push(task.getTaskInfo());
252
+ task = task.getParent();
253
+ }
254
+ return taskTree;
255
+ }
256
+ async UpdateRequestInfo() {
257
+ let currMGData = AccessHelper.mgDataTable.getCurrMGData();
258
+ let eventsManager = AccessHelper.eventsManager;
259
+ let operExecution = false;
260
+ let cmdsToServer = currMGData.CmdsToServer;
261
+ for (let i = 0; i < cmdsToServer.getSize(); i++) {
262
+ if (cmdsToServer.getCmd(i) instanceof ExecOperCommand) {
263
+ let operCmd = currMGData.CmdsToServer.getCmd(i);
264
+ this._requestInfo.serverCallAt = operCmd.getCommandInfo();
265
+ this._requestInfo.runtimeTaskTree = this.GetTaskTree(operCmd.getTask());
266
+ operExecution = true;
267
+ break;
268
+ }
269
+ }
270
+ this._requestInfo.extraInfo.contextID = RuntimeContextBase.Instance.ContextID;
271
+ this._requestInfo.extraInfo.sessionCounter = this.GetSessionCounter();
272
+ if (!operExecution) {
273
+ if (eventsManager.getLastRtEvent() != null && eventsManager.getLastRtEvent().InternalEvent != 0) {
274
+ let rtEvt = eventsManager.getLastRtEvent();
275
+ this._requestInfo.runtimeTaskTree = this.GetTaskTree(rtEvt.getTask());
276
+ let eventDescription = rtEvt.isNewInternalEvent()
277
+ ? NString.TrimEnd(rtEvt.getNewInternalEventDescription())
278
+ : Event.getInternalEvtDescription(rtEvt.InternalEvent);
279
+ let cmd = cmdsToServer.getCmd(cmdsToServer.getSize() - 1);
280
+ if (cmd) {
281
+ let commandInfo = NString.IsNullOrEmpty(cmd.getCommandInfo())
282
+ ? NString.Empty
283
+ : cmd.getCommandInfo();
284
+ if (cmd instanceof EventCommand && rtEvt.InternalEvent == cmd.MagicEvent)
285
+ eventDescription = NString.Empty;
286
+ this._requestInfo.serverCallAt = 'Event ' + commandInfo +
287
+ (!NString.IsNullOrEmpty(eventDescription)
288
+ ? NString.Format(' while executing [{0}]', eventDescription)
289
+ : NString.Empty);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ async BuildXMLForMainProgramDataView() {
295
+ let message = new StringBuilder();
296
+ let firstMgData = MGDataCollection.Instance.getMGData(0);
297
+ let mainPrg = firstMgData.getMainProg(0);
298
+ while (mainPrg != null) {
299
+ await mainPrg.buildXML(message);
300
+ mainPrg = firstMgData.getNextMainProg(mainPrg.getCtlIdx());
301
+ }
302
+ if (RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages) {
303
+ let scrambledChanges = Scrambler.Scramble(message.ToString());
304
+ message = new StringBuilder(scrambledChanges);
305
+ }
306
+ message.Insert(0, XMLConstants.MG_TAG_OPEN);
307
+ message.Append(XMLConstants.MG_TAG_XML_END_TAGGED);
308
+ return message.ToString();
309
+ }
310
+ async Execute_1(sendingInstruction, sessionStage, res) {
311
+ let reqBuf;
312
+ let isInitialCall = sessionStage === CommandsProcessorBase_SessionStage.INITIAL;
313
+ let globalParamsString = null;
314
+ let envVarsString = null;
315
+ if (this.DelayCommandExecution)
316
+ return;
317
+ if (Logger.Instance.LogLevel == Logger_LogLevels.RequestInfo && !isInitialCall)
318
+ await this.UpdateRequestInfo();
319
+ if (isInitialCall) {
320
+ let val = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.IS_SESSION_REINITIALIZING);
321
+ if (val === 'true') {
322
+ RemoteCommandsProcessor.IsSessionReInitializing = (val === "true") ? true : false;
323
+ RemoteCommandsProcessor.lastExceptionMessage = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.LAST_EXCEPTION);
324
+ let ctxRemoved = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.CTX_REMOVED_FROM_SRVR);
325
+ if (ctxRemoved !== '1') {
326
+ Logger.Instance.WriteErrorToLog(RemoteCommandsProcessor.lastExceptionMessage);
327
+ Logger.Instance.WriteToLog("Session is reinitializing...", true);
328
+ }
329
+ }
330
+ }
331
+ if (sendingInstruction === CommandsProcessorBase_SendingInstruction.NO_TASKS_OR_COMMANDS)
332
+ reqBuf = null;
333
+ else {
334
+ reqBuf = await this.PrepareRequest(sendingInstruction === CommandsProcessorBase_SendingInstruction.TASKS_AND_COMMANDS);
335
+ let changes = new StringBuilder();
336
+ let buffer = new StringBuilder();
337
+ if (!RemoteCommandsProcessor.IsSessionReInitializing)
338
+ buffer.Append(reqBuf);
339
+ if (RemoteCommandsProcessor.IsSessionReInitializing) {
340
+ globalParamsString = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.GLOBAL_PARAM_LIST);
341
+ envVarsString = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.ENV_VAR_LIST);
342
+ }
343
+ else {
344
+ globalParamsString = AccessHelper.globalParams.mirrorToXML();
345
+ envVarsString = AccessHelper.envParamsTable.mirrorToXML();
346
+ }
347
+ changes.Append(globalParamsString);
348
+ changes.Append(envVarsString);
349
+ if (changes.Length > 0) {
350
+ changes.Insert(0, "<" + ConstInterface.MG_TAG_ENV_CHANGES + ">");
351
+ changes.Append("</" + ConstInterface.MG_TAG_ENV_CHANGES + ">");
352
+ if (RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages) {
353
+ let scrambledChanges = Scrambler.Scramble(changes.ToString());
354
+ changes = new StringBuilder(scrambledChanges);
355
+ }
356
+ changes.Insert(0, XMLConstants.MG_TAG_OPEN);
357
+ changes.Append(XMLConstants.MG_TAG_XML_END_TAGGED);
358
+ buffer.Append(changes.ToString());
359
+ }
360
+ reqBuf = buffer.ToString();
361
+ }
362
+ let requestStatus = new RefParam(RequestStatus.Handled);
363
+ let respBuf = null;
364
+ if (RemoteCommandsProcessor.IsSessionReInitializing) {
365
+ reqBuf = reqBuf + this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.MAIN_PROG_VIEW);
366
+ }
367
+ if (RuntimeContextBase.Instance.RemovedContextFromServer)
368
+ requestStatus.value = RequestStatus.Retry;
369
+ else {
370
+ if (RuntimeContextBase.Instance.RemovingContextFromServer)
371
+ RuntimeContextBase.Instance.RemovedContextFromServer = true;
372
+ respBuf = await this.DispatchRequest(this.ServerUrl, reqBuf, sessionStage, requestStatus);
373
+ }
374
+ if (requestStatus.value == RequestStatus.Retry) {
375
+ await this.ReStartSession();
376
+ }
377
+ if (respBuf == null)
378
+ return;
379
+ if (isInitialCall) {
380
+ RemoteCommandsProcessor.InitialUrl = window.location.href;
381
+ if (RemoteCommandsProcessor.IsSessionReInitializing) {
382
+ let dataStorage = window.localStorage;
383
+ dataStorage.removeItem(ConstInterface.IS_SESSION_REINITIALIZING);
384
+ dataStorage.removeItem(ConstInterface.MAIN_PROG_VIEW);
385
+ dataStorage.removeItem(ConstInterface.GLOBAL_PARAM_LIST);
386
+ dataStorage.removeItem(ConstInterface.ENV_VAR_LIST);
387
+ dataStorage.removeItem(ConstInterface.LAST_EXCEPTION);
388
+ }
389
+ }
390
+ FlowMonitorQueue.Instance.enable(false);
391
+ await this.ProcessResponse(respBuf, AccessHelper.mgDataTable.currMgdID, null, res);
392
+ if (RemoteCommandsProcessor.IsSessionReInitializing) {
393
+ AccessHelper.globalParams.RestoreParams(globalParamsString);
394
+ AccessHelper.envParamsTable.RestoreParams(envVarsString);
395
+ let dataStorage = window.localStorage;
396
+ let ctxRemoved = dataStorage.getItem(ConstInterface.CTX_REMOVED_FROM_SRVR);
397
+ if (ctxRemoved === "1") {
398
+ EventsManager.Instance.restoreLastSavedRouteEventFromLocalStorage();
399
+ dataStorage.removeItem(ConstInterface.CTX_REMOVED_FROM_SRVR);
400
+ dataStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT);
401
+ dataStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT_SRC_TSK);
402
+ dataStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT_ARG_LIST);
403
+ }
404
+ RemoteCommandsProcessor.IsSessionReInitializing = false;
405
+ }
406
+ if (sendingInstruction === CommandsProcessorBase_SendingInstruction.TASKS_AND_COMMANDS) {
407
+ AccessHelper.mgDataTable.startTasksIteration();
408
+ let task;
409
+ while ((task = AccessHelper.mgDataTable.getNextTask()) !== null) {
410
+ let dataViewWasRetrieved = task.DataViewWasRetrieved;
411
+ if (dataViewWasRetrieved) {
412
+ await task.RefreshDisplay();
413
+ }
414
+ }
415
+ }
416
+ if (isInitialCall)
417
+ ServerConfig.Instance.setGlobalParams(null);
418
+ }
419
+ async DispatchRequest(url, reqBuf, sessionStage, requestStatus) {
420
+ let response = null;
421
+ let encodedBody = null;
422
+ requestStatus.value = RequestStatus.Handled;
423
+ if (url === null) {
424
+ Logger.Instance.WriteExceptionToLogWithMsg("in sendMsgToSrvr() unknown server");
425
+ return response;
426
+ }
427
+ if (sessionStage !== CommandsProcessorBase_SessionStage.HANDSHAKE) {
428
+ let urlSuffix = this.BuildUrlSuffix(reqBuf !== null, sessionStage === CommandsProcessorBase_SessionStage.INITIAL);
429
+ let reqBufEncoded = HttpUtility.UrlEncode(reqBuf, Encoding.UTF8);
430
+ encodedBody = urlSuffix + reqBufEncoded;
431
+ }
432
+ try {
433
+ if (Logger.Instance.ShouldLogExtendedServerRelatedMessages())
434
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("MESSAGE TO SERVER:\n URL: {0}\n BODY: {1}", url, encodedBody));
435
+ response = await this.ExecuteRequest(url, encodedBody);
436
+ if (!response.toUpperCase().startsWith("<HTML")) {
437
+ let startIdx = response.indexOf("<xml id=\"MGDATA\">");
438
+ if (startIdx > 0)
439
+ response = response.substr(startIdx);
440
+ }
441
+ Logger.Instance.WriteServerMessagesToLog("MESSAGE FROM SERVER: " + response);
442
+ if (sessionStage === CommandsProcessorBase_SessionStage.HANDSHAKE ||
443
+ (response.length > 0 &&
444
+ RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages && response !== "<xml id=\"MGDATA\">\n</xml>")) {
445
+ if (sessionStage === CommandsProcessorBase_SessionStage.HANDSHAKE) {
446
+ Debug.Assert(response.length > 0 && response[0] !== '<');
447
+ }
448
+ response = CommandsProcessorBase.UnScramble(response);
449
+ }
450
+ Logger.Instance.WriteDevToLog("MESSAGE FROM SERVER: (size = " + response.length + ")" + OSEnvironment.EolSeq + response);
451
+ this._lastRequestTime = Misc.getSystemMilliseconds();
452
+ }
453
+ catch (ex) {
454
+ if (ex instanceof ServerError) {
455
+ requestStatus.value = RequestStatus.Abort;
456
+ if (sessionStage == CommandsProcessorBase_SessionStage.NORMAL) {
457
+ if (ex.GetCode() == ServerError.ERR_CTX_NOT_FOUND || ex.GetCode() == ServerError.ERR_THREAD_ABORTED) {
458
+ if (RuntimeContextBase.Instance.RemovedContextFromServer) {
459
+ requestStatus.value = RequestStatus.Retry;
460
+ }
461
+ else {
462
+ switch (Environment.Instance.getWebClientReinitSession()) {
463
+ case 'Y':
464
+ requestStatus.value = RequestStatus.Retry;
465
+ break;
466
+ case 'A':
467
+ let retval = await GUIManager.Instance.MessageBox("Error", "Unknown error occurred at server-side." +
468
+ " Would you like to reinitialize the session?", Styles.MSGBOX_BUTTON_YES_NO);
469
+ requestStatus.value = (retval == Styles.MSGBOX_RESULT_YES) ? RequestStatus.Retry : RequestStatus.Abort;
470
+ break;
471
+ case 'N':
472
+ default:
473
+ requestStatus.value = RequestStatus.Abort;
474
+ break;
475
+ }
476
+ }
477
+ if (requestStatus.value == RequestStatus.Abort) {
478
+ Environment.Instance.setWebClientReinitSession('N');
479
+ throw ex;
480
+ }
481
+ else {
482
+ let errForConsole = StrUtil.getConsoleErorString(ex.GetMessage());
483
+ RemoteCommandsProcessor.lastExceptionMessage = "Exception Occured at server side : " + ex.GetCode().toString() + " : " + errForConsole;
484
+ console.log(RemoteCommandsProcessor.lastExceptionMessage);
485
+ }
486
+ return null;
487
+ }
488
+ }
489
+ }
490
+ this.clearLocalStorage();
491
+ throw ex;
492
+ }
493
+ return response;
494
+ }
495
+ clearLocalStorage() {
496
+ window.localStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT);
497
+ window.localStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT_SRC_TSK);
498
+ window.localStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT_ARG_LIST);
499
+ window.localStorage.removeItem(ConstInterface.IS_SESSION_REINITIALIZING);
500
+ window.localStorage.removeItem(ConstInterface.MAIN_PROG_VIEW);
501
+ window.localStorage.removeItem(ConstInterface.GLOBAL_PARAM_LIST);
502
+ window.localStorage.removeItem(ConstInterface.ENV_VAR_LIST);
503
+ window.localStorage.removeItem(ConstInterface.LAST_EXCEPTION);
504
+ window.localStorage.removeItem(ConstInterface.CTX_REMOVED_FROM_SRVR);
505
+ }
506
+ HandleErrorResponse(response) {
507
+ try {
508
+ Logger.Instance.WriteServerMessagesToLog("MESSAGE FROM SERVER: " + response);
509
+ response = CommandsProcessorBase.UnScramble(response);
510
+ Logger.Instance.WriteServerMessagesToLog("MESSAGE FROM SERVER: " + StrUtil.getConsoleErorString(response));
511
+ }
512
+ catch (ex) {
513
+ }
514
+ if (response.startsWith("<xmlerr")) {
515
+ let errorMessageXml = new ErrorMessageXml(response, this._lastRequestTime, AccessHelper.environment.getContextInactivityTimeout());
516
+ throw new ServerError(errorMessageXml.GetMessage(), errorMessageXml.GetCode());
517
+ }
518
+ else if (response.toUpperCase().startsWith("<HTML")) {
519
+ throw new ServerError(response);
520
+ }
521
+ }
522
+ async ExecuteRequest(url, encodedBody) {
523
+ return await this.GetContent(url, false, encodedBody);
524
+ }
525
+ async GetContent(requestedURL, useCache, requestContent) {
526
+ if (isUndefined(requestContent))
527
+ requestContent = null;
528
+ let responseStr;
529
+ try {
530
+ if (requestedURL.startsWith("/"))
531
+ requestedURL = ServerConfig.Instance.getProtocol() + "://" + ServerConfig.Instance.getServer() + requestedURL;
532
+ var spinnerTimer = timer(50, 50);
533
+ var spinnerTimerSubscription = spinnerTimer.subscribe(() => {
534
+ AccessHelper.eventsManager.CheckAndShowSpinner(true);
535
+ });
536
+ let isError = new RefParam(false);
537
+ responseStr = await HttpManager.GetInstance().GetContent(requestedURL, requestContent, useCache, isError);
538
+ spinnerTimerSubscription.unsubscribe();
539
+ spinnerTimerSubscription = null;
540
+ if (isError.value) {
541
+ this.HandleErrorResponse(responseStr);
542
+ }
543
+ }
544
+ catch (ex) {
545
+ if (!(ex instanceof ServerError) || Logger.Instance.LogLevel !== Logger_LogLevels.Basic) {
546
+ Logger.Instance.WriteExceptionToLog(ex, NString.Format("requested URL = \"{0}\"", requestedURL));
547
+ }
548
+ if (!(ex instanceof ServerError)) {
549
+ ex = new ServerError(ex.Message, ex.InnerException ? ex.InnerException : ex);
550
+ }
551
+ throw ex;
552
+ }
553
+ finally {
554
+ if (spinnerTimerSubscription != null)
555
+ spinnerTimerSubscription.unsubscribe();
556
+ }
557
+ return responseStr;
558
+ }
559
+ ClientActivated() {
560
+ }
561
+ BuildUrlSuffix(hasContent, isInitialCall) {
562
+ let prefix = ConstInterface.RC_INDICATION + ConstInterface.RC_TOKEN_CTX_ID + RuntimeContextBase.Instance.ContextID;
563
+ if (!isNullOrUndefined(this.SessionId))
564
+ prefix += (ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.RC_TOKEN_SESSION_ID + this.SessionId);
565
+ if (isInitialCall) {
566
+ if (RemoteCommandsProcessor.IsSessionReInitializing)
567
+ prefix += (ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.WEBCLIENT_REINITIALIZE_REQUEST);
568
+ let globalParams = ServerConfig.Instance.getGlobalParams();
569
+ if (globalParams !== null) {
570
+ globalParams = NString.Replace(globalParams, "+", "%2B");
571
+ prefix += ("&" + ConstInterface.MG_TAG_GLOBALPARAMS + "=" + globalParams);
572
+ }
573
+ }
574
+ if (hasContent) {
575
+ prefix += ("&" + ConstInterface.RC_TOKEN_SESSION_COUNT + this.GetSessionCounter() +
576
+ ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.RC_TOKEN_DATA);
577
+ }
578
+ return prefix;
579
+ }
580
+ async SendMonitorOnly() {
581
+ let flowMonitor = FlowMonitorQueue.Instance;
582
+ if (AccessHelper.mgDataTable == null || AccessHelper.mgDataTable.getMGData(0) == null || AccessHelper.mgDataTable.getMGData(0).IsAborting)
583
+ return;
584
+ if (!flowMonitor.isEmpty()) {
585
+ let buffer = this.BuildMonitorMessage();
586
+ let shouldAccumulateClientLog = false;
587
+ if (shouldAccumulateClientLog) {
588
+ }
589
+ else {
590
+ try {
591
+ let requestStatus = new RefParam(RequestStatus.Handled);
592
+ await this.DispatchRequest(this.ServerUrl, buffer.ToString(), CommandsProcessorBase_SessionStage.NORMAL, requestStatus);
593
+ }
594
+ catch (err) {
595
+ }
596
+ }
597
+ }
598
+ }
599
+ BuildMonitorMessage() {
600
+ let buffer = new StringBuilder(1000);
601
+ let flowMonitor = FlowMonitorQueue.Instance;
602
+ if (!RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages) {
603
+ buffer.Append(XMLConstants.MG_TAG_OPEN);
604
+ flowMonitor.buildXML(buffer);
605
+ }
606
+ else {
607
+ flowMonitor.buildXML(buffer);
608
+ let scrambledOut = Scrambler.Scramble(buffer.ToString());
609
+ buffer = new StringBuilder(1000);
610
+ buffer.Append(XMLConstants.MG_TAG_OPEN + scrambledOut);
611
+ }
612
+ buffer.Append("</" + XMLConstants.MG_TAG_XML + XMLConstants.TAG_CLOSE);
613
+ return buffer;
614
+ }
615
+ RegisterDelegates() {
616
+ HttpClientEvents.GetSessionCounter_Event = this.GetSessionCounter.bind(this);
617
+ HttpClientEvents.CheckAndSetSessionCounter_Event = this.CheckAndSetSessionCounter.bind(this);
618
+ HttpClientEvents.ComputeAndLogRequestInfo_Event = this.ComputeAndLogRequestInfo.bind(this);
619
+ AccessHelper.eventsManager.SpinnerStopped.subscribe(clientBusyTime => this.ClientActivated());
620
+ }
621
+ ComputeAndLogRequestInfo(contentLength, roundTrip, isLoggingResponse) {
622
+ if (!isNullOrUndefined(this._requestInfo.serverCallAt)) {
623
+ this._requestInfo.extraInfo.contentLength = contentLength;
624
+ this._requestInfo.extraInfo.timeStamp = new Date().toString();
625
+ let extraMessageStr = isLoggingResponse ? 'Response ⤵' : 'Request ⤵';
626
+ if (isLoggingResponse) {
627
+ this._requestInfo.roundtripTime = roundTrip;
628
+ }
629
+ Logger.Instance.WriteRequestInfoToLog(this._requestInfo, extraMessageStr);
630
+ if (isLoggingResponse)
631
+ this._requestInfo.clear();
632
+ }
633
+ }
634
+ static set ShouldScrambleAndUnscrambleMessages(value) {
635
+ RemoteCommandsProcessor._shouldScrambleAndUnscrambleMessages = value;
636
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("ShouldScrambleAndUnscrambleMessages.Set: {0}", this._shouldScrambleAndUnscrambleMessages));
637
+ }
638
+ static get ShouldScrambleAndUnscrambleMessages() {
639
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("ShouldScrambleAndUnscrambleMessages.Get: {0}", this._shouldScrambleAndUnscrambleMessages));
640
+ return RemoteCommandsProcessor._shouldScrambleAndUnscrambleMessages;
641
+ }
642
+ parseLogLevel(strLogLevel) {
643
+ let logLevel = Logger_LogLevels.None;
644
+ if (!NString.IsNullOrEmpty(strLogLevel)) {
645
+ if (strLogLevel.toUpperCase().startsWith("SERVER"))
646
+ logLevel = strLogLevel.endsWith("#") ? Logger_LogLevels.ServerMessages : Logger_LogLevels.Server;
647
+ else if (strLogLevel.toUpperCase().startsWith("S") || strLogLevel.toUpperCase().startsWith("Q"))
648
+ logLevel = Logger_LogLevels.Support;
649
+ else if (strLogLevel.toUpperCase().startsWith("G"))
650
+ logLevel = Logger_LogLevels.Gui;
651
+ else if (strLogLevel.toUpperCase().startsWith("D"))
652
+ logLevel = Logger_LogLevels.Development;
653
+ else if (strLogLevel.toUpperCase().startsWith("B"))
654
+ logLevel = Logger_LogLevels.Basic;
655
+ else if (strLogLevel.toUpperCase().startsWith("R"))
656
+ logLevel = Logger_LogLevels.RequestInfo;
657
+ }
658
+ return logLevel;
659
+ }
660
+ async PrepareRequest(serializeTasks) {
661
+ let xmlBuf = new StringBuilder();
662
+ xmlBuf.Append(XMLConstants.MG_TAG_OPEN);
663
+ if (AccessHelper.mgDataTable.getCurrMGData() !== null) {
664
+ let xmlUnscrambled = new StringBuilder();
665
+ await AccessHelper.mgDataTable.buildXML(xmlUnscrambled, serializeTasks);
666
+ if (RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages)
667
+ xmlBuf.Append(Scrambler.Scramble(xmlUnscrambled.ToString()));
668
+ else
669
+ xmlBuf.Append(xmlUnscrambled.ToString());
670
+ }
671
+ xmlBuf.Append("</" + XMLConstants.MG_TAG_XML + XMLConstants.TAG_CLOSE);
672
+ return xmlBuf.ToString();
673
+ }
674
+ async ProcessResponse(response, currMgdID, openingTaskDetails, res) {
675
+ Logger.Instance.WriteDevToLog("<-- ProcessResponse started -->");
676
+ if (openingTaskDetails === null)
677
+ openingTaskDetails = new OpeningTaskDetails();
678
+ let systemMilliseconds = Misc.getSystemMilliseconds();
679
+ if (response === null || response.trim().length === 0)
680
+ return;
681
+ AccessHelper.mgDataTable.currMgdID = currMgdID;
682
+ RuntimeContextBase.Instance.Parser.push();
683
+ RuntimeContextBase.Instance.Parser.setXMLdata(response);
684
+ RuntimeContextBase.Instance.Parser.setCurrIndex(0);
685
+ let currMGData = AccessHelper.mgDataTable.getCurrMGData();
686
+ await currMGData.fillData(openingTaskDetails, RuntimeContextBase.Instance.Parser);
687
+ RuntimeContextBase.Instance.Parser.setXMLdata(null);
688
+ RuntimeContextBase.Instance.Parser.pop();
689
+ Logger.Instance.WriteDevToLog("<-- ProcessResponse finished --> (" + (Misc.getSystemMilliseconds() - systemMilliseconds) + ")");
690
+ await currMGData.CmdsToClient.Execute(res);
691
+ await this.ProcessRecovery();
692
+ }
693
+ async ProcessRecovery() {
694
+ AccessHelper.eventsManager.pushNewExecStacks();
695
+ await AccessHelper.mgDataTable.processRecovery();
696
+ AccessHelper.eventsManager.popNewExecStacks();
697
+ }
698
+ }
699
+ class HandshakeResponse {
700
+ static SYSTEM_LOGIN_AD = 'D';
701
+ _scrambleMessages = true;
702
+ get ScrambleMessages() {
703
+ return this._scrambleMessages;
704
+ }
705
+ _contextId = null;
706
+ get ContextId() {
707
+ return this._contextId;
708
+ }
709
+ _privateSessionId = null;
710
+ get GetSessionId() {
711
+ return this._privateSessionId;
712
+ }
713
+ _inputPassword = false;
714
+ get InputPassword() {
715
+ return this._inputPassword;
716
+ }
717
+ _httpTimeout = 0;
718
+ get HttpTimeout() {
719
+ return this._httpTimeout;
720
+ }
721
+ _systemLogin = null;
722
+ get SystemLogin() {
723
+ return this._systemLogin;
724
+ }
725
+ _maxInternalLogLevel = null;
726
+ get MaxInternalLogLevel() {
727
+ return this._maxInternalLogLevel;
728
+ }
729
+ constructor(responseXML) {
730
+ try {
731
+ JSON_Utils.JSONFromXML(responseXML, this.FillFromJSON.bind(this));
732
+ }
733
+ catch (ex) {
734
+ Logger.Instance.WriteExceptionToLog(ex, responseXML);
735
+ }
736
+ }
737
+ FillFromJSON(error, result) {
738
+ if (error != null) {
739
+ throw error;
740
+ }
741
+ let response = result['Richclientresponse'];
742
+ for (let elementName in response) {
743
+ if (response.hasOwnProperty(elementName)) {
744
+ switch (elementName) {
745
+ case "ContextID":
746
+ this._contextId = response[elementName][0];
747
+ break;
748
+ case "SessionID":
749
+ this._privateSessionId = response[elementName][0];
750
+ break;
751
+ case "Environment":
752
+ let envAttributes = response["Environment"][0]['$'];
753
+ if (!isNullOrUndefined(envAttributes["ScrambleMessages"])) {
754
+ Debug.Assert(envAttributes["ScrambleMessages"] === "N");
755
+ this._scrambleMessages = false;
756
+ }
757
+ if (!isNullOrUndefined(envAttributes["MaxInternalLogLevel"]))
758
+ this._maxInternalLogLevel = envAttributes["MaxInternalLogLevel"];
759
+ if (!isNullOrUndefined(envAttributes["InputPassword"]) && envAttributes["InputPassword"].toLocaleLowerCase() === "y")
760
+ this._inputPassword = true;
761
+ if (!isNullOrUndefined(envAttributes["SystemLogin"]))
762
+ this._systemLogin = envAttributes["SystemLogin"];
763
+ if (!isNullOrUndefined(envAttributes[ConstInterface.MG_TAG_HTTP_COMMUNICATION_TIMEOUT]))
764
+ this._httpTimeout = +envAttributes[ConstInterface.MG_TAG_HTTP_COMMUNICATION_TIMEOUT];
765
+ if (!isNullOrUndefined(envAttributes["ForwardSlash"]))
766
+ AccessHelper.environment.ForwardSlashUsage = envAttributes["ForwardSlash"];
767
+ break;
768
+ }
769
+ }
770
+ }
771
+ }
772
+ }
773
+ class ErrorMessageXml {
774
+ _lastRequestTime = 0;
775
+ contextInactivityTimeout;
776
+ _errorMessage = null;
777
+ _errorCode = 0;
778
+ _middlewareAddress = null;
779
+ _parsingFailed = false;
780
+ constructor(xmlContent, lastRequestTime, contextInactivityTimeout) {
781
+ this._lastRequestTime = lastRequestTime;
782
+ this.contextInactivityTimeout = contextInactivityTimeout;
783
+ try {
784
+ JSON_Utils.JSONFromXML(xmlContent, this.FillFromJSON.bind(this));
785
+ }
786
+ catch (ex) {
787
+ Logger.Instance.WriteExceptionToLog(ex);
788
+ Misc.WriteStackTrace(ex);
789
+ this._parsingFailed = true;
790
+ }
791
+ }
792
+ FillFromJSON(error, result) {
793
+ if (error != null) {
794
+ throw error;
795
+ }
796
+ let xmlerr = result['xmlerr'];
797
+ for (let elementName in xmlerr) {
798
+ if (xmlerr.hasOwnProperty(elementName)) {
799
+ switch (elementName) {
800
+ case "errmsg":
801
+ this._errorMessage = xmlerr[elementName][0];
802
+ break;
803
+ case "errcode":
804
+ this._errorCode = +(xmlerr[elementName]);
805
+ break;
806
+ case "server":
807
+ this._middlewareAddress = xmlerr[elementName][0];
808
+ break;
809
+ case "appname":
810
+ case "prgname":
811
+ case "arguments":
812
+ case "username":
813
+ case "xmlerr":
814
+ break;
815
+ default:
816
+ Logger.Instance.WriteExceptionToLogWithMsg(NString.Format("Unknown element: '{0}'", elementName));
817
+ break;
818
+ }
819
+ }
820
+ }
821
+ }
822
+ GetCode() {
823
+ return this._errorCode;
824
+ }
825
+ GetMessage() {
826
+ let sb = new StringBuilder();
827
+ if (this._parsingFailed) {
828
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.RC_STR_F7_UNEXPECTED_ERR));
829
+ }
830
+ else {
831
+ switch (this._errorCode) {
832
+ case ServerError.ERR_CTX_NOT_FOUND:
833
+ if (this.InactivityTimeoutExpired())
834
+ sb.Append(NString.Format("{0} ({1} {2})", AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_SESSION_CLOSED_INACTIVITY), Math.floor(this.contextInactivityTimeout / 600), AccessHelper.languageData.getConstMessage(MsgInterface.STR_MINUTES)));
835
+ else
836
+ sb.Append(NString.Format("{0} ({1}).", AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_SESSION_CLOSED), this._errorCode));
837
+ break;
838
+ case ServerError.ERR_WEBCLIENT_PROGRAM_RELOADED:
839
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_WEBCLIENT_PROGRAM_RELOADED));
840
+ break;
841
+ case ServerError.ERR_EXECUTED_PROGRAM_CHANGED:
842
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_EXECUTED_PROGRAM_CHANGED));
843
+ break;
844
+ case ServerError.ERR_AUTHENTICATION:
845
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.USRINP_STR_BADPASSW));
846
+ break;
847
+ case ServerError.ERR_ACCESS_DENIED:
848
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_AUTHORIZATION_FAILURE));
849
+ break;
850
+ default:
851
+ sb.Append(this._errorMessage);
852
+ break;
853
+ }
854
+ sb.Append(OSEnvironment.EolSeq + OSEnvironment.EolSeq);
855
+ if (!ServerConfig.Instance.ShouldDisplayGenericError()) {
856
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.BROWSER_OPT_INFO_SERVER_STR) + ": ");
857
+ sb.Append(ServerConfig.Instance.getServer());
858
+ if (!NString.IsNullOrEmpty(this._middlewareAddress)) {
859
+ sb.Append(" --> ");
860
+ sb.Append(this._middlewareAddress);
861
+ }
862
+ sb.Append(OSEnvironment.EolSeq);
863
+ }
864
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.TASKRULE_STR_APPLICATION) + ": \"");
865
+ sb.Append(ServerConfig.Instance.getAppName());
866
+ sb.Append("\" (\"");
867
+ sb.Append("\")");
868
+ }
869
+ return sb.ToString();
870
+ }
871
+ InactivityTimeoutExpired() {
872
+ let expired = false;
873
+ if (this.contextInactivityTimeout > 0) {
874
+ let currTimeMilli = Misc.getSystemMilliseconds();
875
+ expired = ((currTimeMilli - this._lastRequestTime) > (this.contextInactivityTimeout * 100));
876
+ }
877
+ return expired;
878
+ }
879
+ }
880
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lbmdpbmUvc3JjL3JlbW90ZS9SZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsTUFBTSxFQUNOLFVBQVUsRUFDVixNQUFNLEVBQ04sZ0JBQWdCLEVBQ2hCLElBQUksRUFDSixZQUFZLEVBQ1osYUFBYSxFQUNiLFdBQVcsRUFDWCxPQUFPLEVBQ1AsWUFBWSxFQUNiLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUNMLEtBQUssRUFDTCxRQUFRLEVBQ1IsU0FBUyxFQUNULElBQUksRUFDSixPQUFPLEVBQ1AsUUFBUSxFQUNSLGFBQWEsRUFDYixpQkFBaUIsRUFDakIsV0FBVyxFQUNaLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUNMLFFBQVEsRUFDUixrQkFBa0IsRUFDbEIsTUFBTSxFQUNOLDJCQUEyQixFQUM1QixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUU3RSxPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLHdDQUF3QyxFQUN4QyxrQ0FBa0MsRUFDbkMsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTVDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBWSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pFLE9BQU8s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QUFJLGFBQWEsR0FBVyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUN6RCxPQUFPLEdBQUcsQ0FBQyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzlGLENBQUM7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEJhc2U2NCxcclxuICBKU09OX1V0aWxzLFxyXG4gIExvZ2dlcixcclxuICBMb2dnZXJfTG9nTGV2ZWxzLFxyXG4gIE1pc2MsXHJcbiAgTXNnSW50ZXJmYWNlLFxyXG4gIE9TRW52aXJvbm1lbnQsXHJcbiAgUmVxdWVzdEluZm8sXHJcbiAgU3RyVXRpbCxcclxuICBYTUxDb25zdGFudHNcclxufSBmcm9tIFwiQG1hZ2ljLXhwYS91dGlsc1wiO1xyXG5pbXBvcnQge1xyXG4gIERlYnVnLFxyXG4gIEVuY29kaW5nLFxyXG4gIEV4Y2VwdGlvbixcclxuICBMaXN0LFxyXG4gIE5TdHJpbmcsXHJcbiAgUmVmUGFyYW0sXHJcbiAgU3RyaW5nQnVpbGRlcixcclxuICBpc051bGxPclVuZGVmaW5lZCxcclxuICBpc1VuZGVmaW5lZFxyXG59IGZyb20gXCJAbWFnaWMteHBhL21zY29yZWxpYlwiO1xyXG5pbXBvcnQge1xyXG4gIENvbW1hbmRzLFxyXG4gIFJ1bnRpbWVDb250ZXh0QmFzZSxcclxuICBTdHlsZXMsXHJcbiAgVXNlcm5hbWVQYXNzd29yZENyZWRlbnRpYWxzXHJcbn0gZnJvbSBcIkBtYWdpYy14cGEvZ3VpXCI7XHJcbmltcG9ydCB7IEV4ZWNPcGVyQ29tbWFuZCB9IGZyb20gJy4uL2NvbW1hbmRzL0NsaWVudFRvU2VydmVyL0V4ZWNPcGVyQ29tbWFuZCc7XHJcbmltcG9ydCB7IFRhc2sgfSBmcm9tICcuLi90YXNrcy9UYXNrJztcclxuaW1wb3J0IHtcclxuICBDb21tYW5kc1Byb2Nlc3NvckJhc2UsXHJcbiAgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbixcclxuICBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlXHJcbn0gZnJvbSBcIi4uL0NvbW1hbmRzUHJvY2Vzc29yQmFzZVwiO1xyXG5pbXBvcnQgeyBIdHRwTWFuYWdlciB9IGZyb20gXCIuLi9odHRwL0h0dHBNYW5hZ2VyXCI7XHJcbmltcG9ydCB7IENvbnN0SW50ZXJmYWNlIH0gZnJvbSBcIi4uL0NvbnN0SW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IFNjcmFtYmxlciB9IGZyb20gXCIuLi91dGlsL1NjcmFtYmxlclwiO1xyXG5pbXBvcnQgeyBTZXJ2ZXJFcnJvciB9IGZyb20gXCIuL1NlcnZlckVycm9yXCI7XHJcbmltcG9ydCB7IElSZXN1bHRWYWx1ZSB9IGZyb20gXCIuLi9ydC9JUmVzdWx0VmFsdWVcIjtcclxuaW1wb3J0IHsgRmxvd01vbml0b3JRdWV1ZSB9IGZyb20gXCIuLi91dGlsL0Zsb3dNb25pdG9yUXVldWVcIjtcclxuaW1wb3J0IHsgT3BlbmluZ1Rhc2tEZXRhaWxzLCBUYXNrQmFzZSB9IGZyb20gXCIuLi90YXNrcy9UYXNrQmFzZVwiO1xyXG5pbXBvcnQgeyBIdHRwVXRpbGl0eSB9IGZyb20gXCIuLi9odHRwL2NsaWVudC9IdHRwVXRpbGl0eVwiO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50RXZlbnRzIH0gZnJvbSBcIi4uL2h0dHAvY2xpZW50L0h0dHBDbGllbnRFdmVudHNcIjtcclxuaW1wb3J0IHsgU2VydmVyQ29uZmlnIH0gZnJvbSBcIi4uL1NlcnZlckNvbmZpZ1wiO1xyXG5pbXBvcnQgeyBNR0RhdGEgfSBmcm9tIFwiLi4vdGFza3MvTUdEYXRhXCI7XHJcbmltcG9ydCB7IENvbW1hbmRzVGFibGUgfSBmcm9tIFwiLi4vQ29tbWFuZHNUYWJsZVwiO1xyXG5pbXBvcnQgeyBBY2Nlc3NIZWxwZXIgfSBmcm9tIFwiLi4vQWNjZXNzSGVscGVyXCI7XHJcbmltcG9ydCB7IEVudmlyb25tZW50LCBFdmVudCwgRXZlbnRDb21tYW5kLCBFdmVudHNNYW5hZ2VyLCBHVUlNYW5hZ2VyLCBJQ2xpZW50Q29tbWFuZCwgUnVuVGltZUV2ZW50IH0gZnJvbSBcIi4uLy4uL1wiO1xyXG5pbXBvcnQgeyBJQ2xpZW50VG9TZXJ2ZXJDb21tYW5kSW5mbyB9IGZyb20gXCIuLi9jb21tYW5kcy9JQ2xpZW50VG9TZXJ2ZXJDb21tYW5kSW5mb1wiO1xyXG5pbXBvcnQgeyBNR0RhdGFDb2xsZWN0aW9uIH0gZnJvbSBcIi4uL3Rhc2tzL01HRGF0YUNvbGxlY3Rpb25cIjtcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uLCB0aW1lciB9IGZyb20gXCJyeGpzXCI7XHJcblxyXG4vLy8gPHN1bW1hcnk+IFJlcHJlc2VudHMgdGhlIHN0YXR1cyBvZiBhIHJlcXVlc3QgPC9zdW1tYXJ5PlxyXG5lbnVtIFJlcXVlc3RTdGF0dXMge1xyXG4gIEhhbmRsZWQsIC8vdGhlIHJlcXVlc3Qgd2FzIHN1Y2Nlc3NmdWxseSBoYW5kbGVkLlxyXG4gIFJldHJ5LCAgIC8vdGhlIHJlcXVlc3Qgc2hvdWxkIGJlIHJlLXNlbnQuXHJcbiAgQWJvcnQgICAvL3RoZSByZXF1ZXN0IGNvdWxkIG5vdCBiZSBoYW5kbGVkIGFuZCBzaG91bGQgYmUgYWJvcnRlZC5cclxufVxyXG5cclxuLy8gQGR5bmFtaWNcclxuZXhwb3J0IGNsYXNzIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yIGV4dGVuZHMgQ29tbWFuZHNQcm9jZXNzb3JCYXNlIHtcclxuICBzdGF0aWMgcmVhZG9ubHkgUkNfTk9fQ09OVEVYVF9JRDogc3RyaW5nID0gJy0xJztcclxuICBwcml2YXRlIHN0YXRpYyBfaW5zdGFuY2U6IFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yID0gbnVsbDtcclxuICBwdWJsaWMgc3RhdGljIElzU2Vzc2lvblJlSW5pdGlhbGl6aW5nID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgbGFzdEV4Y2VwdGlvbk1lc3NhZ2UgPSBudWxsO1xyXG4gIHByaXZhdGUgc3RhdGljIEluaXRpYWxVcmw6IHN0cmluZyA9IG51bGw7XHJcblxyXG5cclxuICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbiAgLy8gKioqKioqKiogV2hlbiBjaGFuZ2luZyBXRUJfQ09NTVVOSUNBVElPTl9QUk9UT0NPTF9WRVJTSU9OLCBwbGVhc2UgY2hhbmdlIG9uIG1vYmlsZSBwbGF0Zm9ybXMgYXMgd2VsbDpcclxuICAvLyAqKioqKioqKiBXMTBNOiBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5jc1xyXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFdFQl9DT01NVU5JQ0FUSU9OX1BST1RPQ09MX1ZFUlNJT046IHN0cmluZyA9IFwiMTQwMDJcIjtcclxuICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gIC8vIFRPRE86IENoZWNrIGlmIHdlIG5lZWQgX2xvZ0FjY3VtdWxhdG9yLlxyXG4gIC8vIHByaXZhdGUgX2xvZ0FjY3VtdWxhdG9yOiBDbGllbnRMb2dBY2N1bXVsYXRvciA9IG51bGw7XHJcblxyXG4gIHByaXZhdGUgX2xhc3RSZXF1ZXN0VGltZTogbnVtYmVyID0gMDsgLy8gdGhlIHRpbWUgb2YgdGhlIGxhc3QgcmVxdWVzdCB0byB0aGUgc2VydmVyXHJcblxyXG4gIFNlcnZlclVybDogc3RyaW5nID0gbnVsbDtcclxuICBwcml2YXRlIHN0YXRpYyBfc2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXM6IGJvb2xlYW4gPSBmYWxzZTsgLy8gc3RhdGljIGJlY2F1c2UgaXQgaXMgaW5pdGlhbGl6ZWQgYmVmb3JlIHRoZSBleGVjdXRpb24gcHJvcHMgYXJlIGF2YWlsYWJsZVxyXG5cclxuICBwdWJsaWMgU2Vzc2lvbklkOiBzdHJpbmc7XHJcblxyXG4gIHB1YmxpYyBEZWxheUNvbW1hbmRFeGVjdXRpb246IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcml2YXRlIF9yZXF1ZXN0SW5mbyA9IG5ldyBSZXF1ZXN0SW5mbygpO1xyXG5cclxuICBzdGF0aWMgR2V0SW5zdGFuY2UoKTogUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3Ige1xyXG4gICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLl9pbnN0YW5jZSA9PT0gbnVsbCkge1xyXG4gICAgICBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5faW5zdGFuY2UgPSBuZXcgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IoKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuX2luc3RhbmNlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgICB0aGlzLlNlcnZlclVybCA9IFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRTZXJ2ZXJVUkwoKTtcclxuXHJcbiAgICBIdHRwTWFuYWdlci5HZXRJbnN0YW5jZSgpO1xyXG5cclxuICAgIHRoaXMuUmVnaXN0ZXJEZWxlZ2F0ZXMoKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5cclxuICAvLy8gQ2hlY2tzIHRoYXQgc2Vzc2lvbiBjb3VudGVyIGlzIGNvbnNlY3V0aXZlIGR1cmluZyB0aGUgc2Vzc2lvbiBhbmQgc2V0cyBuZXcgdmFsdWUuXHJcbiAgLy8vIFRoZSBvbmx5IGV4Y2VwdGlvbiBpcyBpbiBjYXNlIHRoZSBjbGllbnQgc2VudCB0byB0aGUgc2VydmVyIENvbnN0SW50ZXJmYWNlLlNFU1NJT05fQ09VTlRFUl9DTE9TRV9DVFhfSU5ESUNBVElPTixcclxuICAvLy8gICAgdGhlIHNlcnZlciBpcyBleHBlY3RlZCB0byByZXR1cm4gQ29uc3RJbnRlcmZhY2UuU0VTU0lPTl9DT1VOVEVSX0NMT1NFX0NUWF9JTkRJQ0FUSU9OIGluIHJlc3BvbnNlIChSZXF1ZXN0c1NlcnZlckJhc2U6OlByb2Nlc3NSZXF1ZXN0KSwgdG8gYWNrbm93bGVkZ2UgdGhlIHJlcXVlc3QgdG8gY2xvc2UgdGhlIGNvbnRleHQuXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJuZXdTZXNzaW9uQ291bnRlclwiPiEhLjwvcGFyYW0+XHJcbiAgQ2hlY2tBbmRTZXRTZXNzaW9uQ291bnRlcihuZXdTZXNzaW9uQ291bnRlcjogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAobmV3U2Vzc2lvbkNvdW50ZXIgPT09IENvbnN0SW50ZXJmYWNlLlNFU1NJT05fQ09VTlRFUl9DTE9TRV9DVFhfSU5ESUNBVElPTikge1xyXG4gICAgICBEZWJ1Zy5Bc3NlcnQodGhpcy5HZXRTZXNzaW9uQ291bnRlcigpID09PSBDb25zdEludGVyZmFjZS5TRVNTSU9OX0NPVU5URVJfQ0xPU0VfQ1RYX0lORElDQVRJT04pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgRGVidWcuQXNzZXJ0KG5ld1Nlc3Npb25Db3VudGVyID09PSB0aGlzLkdldFNlc3Npb25Db3VudGVyKCkgKyAxKTtcclxuICAgICAgdGhpcy5TZXRTZXNzaW9uQ291bnRlcihuZXdTZXNzaW9uQ291bnRlcik7XHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlclRvTG9nKE5TdHJpbmcuRm9ybWF0KFwiU2Vzc2lvbiBDb3VudGVyIC0tPiB7MH1cIiwgdGhpcy5fc2Vzc2lvbkNvdW50ZXIpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5cclxuICAvLy8gWmVybyBzZXNzaW9uIGNvdW50ZXIgd2hlbiByZWluaXRpYWxpemluZyBzZXJ2ZXIgY29tbXVuaWNhdGlvbiBkZXRhaWxzXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPlxyXG4gIENsZWFyU2Vzc2lvbkNvdW50ZXIoKTogdm9pZCB7XHJcbiAgICB0aGlzLl9zZXNzaW9uQ291bnRlciA9IDA7XHJcbiAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJUb0xvZyhOU3RyaW5nLkZvcm1hdChcIlNlc3Npb24gQ291bnRlciAtLT4gezB9XCIsIHRoaXMuX3Nlc3Npb25Db3VudGVyKSk7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJuZXdTZXNzaW9uQ291bnRlclwiPjwvcGFyYW0+XHJcbiAgcHJpdmF0ZSBTZXRTZXNzaW9uQ291bnRlcihuZXdTZXNzaW9uQ291bnRlcjogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLl9zZXNzaW9uQ291bnRlciA9IG5ld1Nlc3Npb25Db3VudGVyO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBHZXRMYXN0UmVxdWVzdFRpbWUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fbGFzdFJlcXVlc3RUaW1lO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBSZVN0YXJ0U2Vzc2lvblxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgYXN5bmMgUmVTdGFydFNlc3Npb24oKTogUHJvbWlzZTx2b2lkPiB7XHJcblxyXG4gICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSXNTZXNzaW9uUmVJbml0aWFsaXppbmcgPSB0cnVlO1xyXG5cclxuICAgIGF3YWl0IHRoaXMuU3RvcmVTZXNzaW9uUmVJbml0aWFsaXppbmdEYXRhT25Mb2NhbFN0b3JhZ2UoKTtcclxuICAgIGxldCBuYXZpZ2F0ZVJvb3RSb3V0ZSA9IGZhbHNlO1xyXG4gICAgaWYgKCFSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUmVtb3ZlZENvbnRleHRGcm9tU2VydmVyKVxyXG4gICAgICBuYXZpZ2F0ZVJvb3RSb3V0ZSA9IEVudmlyb25tZW50Lkluc3RhbmNlLmdldFNwZWNpYWxSb3V0ZVRvUm9vdFByb2dPbkNvbnRleHRSZWNyZWF0aW9uKCkgPyB0cnVlIDogZmFsc2U7XHJcbiAgICBDb21tYW5kcy5hZGRSZWZyZXNoUGFnZShuYXZpZ2F0ZVJvb3RSb3V0ZSwgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSW5pdGlhbFVybCk7XHJcbiAgICAvL3N0b3AgdGhlIGV4ZWN1dGlvbiBieSB0aHJvd2luZyBleGNlcHRpb24uXHJcbiAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCcnKTtcclxuXHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIFN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YU9uTG9jYWxTdG9yYWdlXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBhc3luYyBTdG9yZVNlc3Npb25SZUluaXRpYWxpemluZ0RhdGFPbkxvY2FsU3RvcmFnZSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHJcbiAgICBsZXQgbWFpblByZ1ZpZXdTdHJpbmdGb3JTZXJ2ZXIgPSBhd2FpdCB0aGlzLkJ1aWxkWE1MRm9yTWFpblByb2dyYW1EYXRhVmlldygpO1xyXG4gICAgbGV0IGdsb2JhbFBhcmFtc1N0cmluZyA9IEFjY2Vzc0hlbHBlci5nbG9iYWxQYXJhbXMubWlycm9yQWxsVG9YTUwoKTtcclxuICAgIGxldCBjaGFuZ2VkRW52VmFyTGlzdCA9IEFjY2Vzc0hlbHBlci5lbnZQYXJhbXNUYWJsZS5taXJyb3JBbGxUb1hNTCgpO1xyXG4gICAgLy8gc3RvcmUgbWFpblByZ1ZpZXdTdHJpbmdGb3JTZXJ2ZXIsIElzU2Vzc2lvblJlSW5pdGlhbGl6aW5nIGFuZCBnbG9iYWxQYXJhbXNTdHJpbmcgb24gbG9jYWxcclxuICAgIC8vIHN0b3JhZ2UgaW4gb3JkZXIgdG8gdXNlIGl0IGZvciBuZXh0IHNlc3Npb24uXHJcbiAgICBsZXQgZGF0YVN0b3JhZ2UgPSB3aW5kb3cubG9jYWxTdG9yYWdlO1xyXG4gICAgZGF0YVN0b3JhZ2Uuc2V0SXRlbShDb25zdEludGVyZmFjZS5JU19TRVNTSU9OX1JFSU5JVElBTElaSU5HLCBcInRydWVcIik7XHJcbiAgICBkYXRhU3RvcmFnZS5zZXRJdGVtKENvbnN0SW50ZXJmYWNlLk1BSU5fUFJPR19WSUVXLCBtYWluUHJnVmlld1N0cmluZ0ZvclNlcnZlci50b1N0cmluZygpKTtcclxuICAgIGRhdGFTdG9yYWdlLnNldEl0ZW0oQ29uc3RJbnRlcmZhY2UuR0xPQkFMX1BBUkFNX0xJU1QsIGdsb2JhbFBhcmFtc1N0cmluZyk7XHJcbiAgICBkYXRhU3RvcmFnZS5zZXRJdGVtKENvbnN0SW50ZXJmYWNlLkVOVl9WQVJfTElTVCwgY2hhbmdlZEVudlZhckxpc3QpO1xyXG4gICAgZGF0YVN0b3JhZ2Uuc2V0SXRlbShDb25zdEludGVyZmFjZS5MQVNUX0VYQ0VQVElPTiwgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IubGFzdEV4Y2VwdGlvbk1lc3NhZ2UpO1xyXG4gICAgaWYgKFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5SZW1vdmVkQ29udGV4dEZyb21TZXJ2ZXIpXHJcbiAgICAgIGRhdGFTdG9yYWdlLnNldEl0ZW0oQ29uc3RJbnRlcmZhY2UuQ1RYX1JFTU9WRURfRlJPTV9TUlZSLCBcIjFcIik7XHJcbiAgICBFdmVudHNNYW5hZ2VyLkluc3RhbmNlLnN0b3JlTGFzdFNhdmVkUm91dGVFdmVudE9uTG9jYWxTdG9yYWdlKCk7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIFJlc3RvcmVTZXNzaW9uUmVJbml0aWFsaXppbmdEYXRhRnJvbUxvY2FsU3RvcmFnZVxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgUmVzdG9yZVNlc3Npb25SZUluaXRpYWxpemluZ0RhdGFGcm9tTG9jYWxTdG9yYWdlKGtleTogc3RyaW5nKTogc3RyaW5nIHtcclxuXHJcbiAgICBsZXQgZGF0YVN0b3JhZ2UgPSB3aW5kb3cubG9jYWxTdG9yYWdlO1xyXG4gICAgbGV0IHZhbCA9IGRhdGFTdG9yYWdlLmdldEl0ZW0oa2V5KTtcclxuICAgIHJldHVybiB2YWw7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+UHJlcGFyZSBhbmQgZXhlY3V0ZSB0aGUgMXN0ICYgMm5kIGhhbmRzaGFrZSByZXF1ZXN0czpcclxuICAvLy8gMXN0IHJlcXVlc3Q6ICBVVEY4VFJBTlM9Li4mYXBwbmFtZT0uLiZwcmduYW1lPS4uJmFyZ3VtZW50cz0tQTxSaWNoY2xpZW50PjxSZXF1ZXN0aW5nVmVyc2lvbkRldGFpbHM9XCIuLlwiLz48L1JpY2hjbGllbnQ+XHJcbiAgLy8vICAgICByZXNwb25zZTogaW5zdHJ1Y3Rpb25zIHRvIHRoZSBjbGllbnQgLSB3aGV0aGVyIHRvIGRpc3BsYXkgYXV0aGVudGljYXRpb24gZGlhbG9nLCB0aGUgc2VydmVyJ3MgdmVyc2lvbiwgYW5kIG1vcmUgLi5cclxuICAvLy8gICAgICAgICAgICAgICBlLmcuIDxSaWNoY2xpZW50cmVzcG9uc2U+PENvbnRleHRJRD4xMjAzMDg3ODk3MjYzNzEyMDA8L0NvbnRleHRJRD48RW52aXJvbm1lbnQgSW5wdXRQYXNzd29yZD1cIk5cIiBTeXN0ZW1Mb2dpbj1cIk5cIiBTY3JhbWJsZU1lc3NhZ2VzPVwiTlwiIE1heEludGVybmFsTG9nTGV2ZWw9XCJTZXJ2ZXIjXCIgSHR0cFRpbWVvdXQ9XCIxMFwiIENsaWVudE5ldHdvcmtSZWNvdmVyeUludGVydmFsPVwiMFwiIEZvcndhcmRTbGFzaD1cIndlYlwiLz48L1JpY2hjbGllbnRyZXNwb25zZT5cclxuICAvLy8gMm5kIHJlcXVlc3Q6IGF1dGhlbnRpY2F0aW9uIChvcHRpb25hbCwgZGVwZW5kaW5nIG9uIHRoZSAxc3QgcmVxdWVzdCkuXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHJldHVybnM+dHJ1ZSBvbmx5IGlmIHRoZSBjbGllbnQgc2hvdWxkIGNvbnRpbnVlIHRvIHN0YXJ0IHRoZSBhY3R1YWwgcHJvZ3JhbSAoaS5lLiBhZnRlciBoYW5kc2hha2UpLjwvcmV0dXJucz5cclxuICBhc3luYyBTdGFydFNlc3Npb24oKTogUHJvbWlzZTxib29sZWFuPiB7XHJcbiAgICBsZXQgYXV0aGVudGljYXRpb25DYW5jZWxsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGxldCBoYW5kc2hha2VSZXNwb25zZTogSGFuZHNoYWtlUmVzcG9uc2UgPSBudWxsO1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBsYXN0VHlwZWRVc2VySWQ6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAgIC8vIDFzdCBoYW5kc2hha2UgcmVxdWVzdDogcHJlcGFyZSAxc3QgaGFuZHNoYWtlIHJlcXVlc3QgYW5kIHNjcmFtYmxlIGl0XHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgICAgbGV0IGhhbmRzaGFrZUluaXRpYWxUb2tlbnM6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpO1xyXG4gICAgICBoYW5kc2hha2VJbml0aWFsVG9rZW5zLkFwcGVuZChDb25zdEludGVyZmFjZS5VVEY4VFJBTlMgK1xyXG4gICAgICAgIENvbnN0SW50ZXJmYWNlLlJFUV9BUFBfTkFNRSArIFwiPVwiICtcclxuICAgICAgICBIdHRwVXRpbGl0eS5VcmxFbmNvZGUoU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldEFwcE5hbWUoKSwgRW5jb2RpbmcuVVRGOCkpO1xyXG5cclxuICAgICAgaGFuZHNoYWtlSW5pdGlhbFRva2Vucy5BcHBlbmQoXCImXCIgKyBDb25zdEludGVyZmFjZS5SRVFfQVJHUyArIFwiPVwiICsgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19BTFBIQSArXHJcbiAgICAgICAgXCI8UmljaGNsaWVudD48UmVxdWlyZXMgRW5jcnlwdGlvbktleT1cXFwiRmFsc2VcXFwiLz48UklBUHJvdG9jb2xWZXJzaW9uPVxcXCJcIiArIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLldFQl9DT01NVU5JQ0FUSU9OX1BST1RPQ09MX1ZFUlNJT04gKyBcIlxcXCIvPjwvUmljaGNsaWVudD5cIik7XHJcblxyXG4gICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVEZXZUb0xvZyhOU3RyaW5nLkZvcm1hdChcIkhhbmRzaGFrZSByZXF1ZXN0ICMxIChub3Qgc2NyYW1ibGVkKSA6IHswfVwiLFxyXG4gICAgICAgIHRoaXMuU2VydmVyVXJsICsgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TVEFSVCArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfSU5ESUNBVElPTl9JTklUSUFMICsgaGFuZHNoYWtlSW5pdGlhbFRva2VucykpO1xyXG5cclxuICAgICAgbGV0IGhhbmRzaGFrZUluaXRpYWxVcmw6IHN0cmluZyA9IHRoaXMuU2VydmVyVXJsICsgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TVEFSVCArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfSU5ESUNBVElPTl9JTklUSUFMICtcclxuICAgICAgICBDb25zdEludGVyZmFjZS5SQ19UT0tFTl9EQVRBICtcclxuICAgICAgICBIdHRwVXRpbGl0eS5VcmxFbmNvZGUoU2NyYW1ibGVyLlNjcmFtYmxlKGhhbmRzaGFrZUluaXRpYWxUb2tlbnMuVG9TdHJpbmcoKSksIEVuY29kaW5nLlVURjgpO1xyXG5cclxuICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhcIlwiKTtcclxuICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhOU3RyaW5nLkZvcm1hdChcIkhhbmRzaGFrZSByZXF1ZXN0ICMxOiB7MH1cIiwgaGFuZHNoYWtlSW5pdGlhbFVybCkpO1xyXG5cclxuICAgICAgLy8gSW5pdGlhbGl6ZSB0ZW1wIGN0eEdyb3VwIHdpdGggQ3R4R3JvdXAgZnJvbSBleGVjdXRpb24ucHJvcGVydGllc1xyXG4gICAgICBsZXQgY3R4R3JvdXA6IHN0cmluZyA9IFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRDdHhHcm91cCgpO1xyXG5cclxuICAgICAgd2hpbGUgKCFhdXRoZW50aWNhdGlvbkNhbmNlbGxlZCkge1xyXG4gICAgICAgIGxldCByZXF1ZXN0U3RhdHVzOiBSZWZQYXJhbTxSZXF1ZXN0U3RhdHVzPiA9IG5ldyBSZWZQYXJhbShSZXF1ZXN0U3RhdHVzLkhhbmRsZWQpO1xyXG4gICAgICAgIC8vIGV4ZWN1dGUgdGhlIDFzdCByZXF1ZXN0XHJcbiAgICAgICAgbGV0IHJlc3BvbnNlU3RyOiBzdHJpbmcgPSBhd2FpdCB0aGlzLkRpc3BhdGNoUmVxdWVzdChoYW5kc2hha2VJbml0aWFsVXJsLCBudWxsLCBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLkhBTkRTSEFLRSwgcmVxdWVzdFN0YXR1cyk7XHJcblxyXG4gICAgICAgIC8vIHByb2Nlc3MgdGhlIDFzdCByZXNwb25zZSAtIGNoZWNrIGlmIHRoZSByZXNwb25zZSBpcyBlcnJvciwgdW5zY3JhbWJsZSBhbmQgcGFyc2UgaXRcclxuICAgICAgICBpZiAoTlN0cmluZy5Jc051bGxPckVtcHR5KHJlc3BvbnNlU3RyKSkge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IFNlcnZlckVycm9yKFwiQ2xpZW50IGZhaWxlZCB0byBpbml0aWFsaXplIGEgc2Vzc2lvbi5cIiArIE9TRW52aXJvbm1lbnQuRW9sU2VxICtcclxuICAgICAgICAgICAgXCJFbXB0eSByZXNwb25zZSB3YXMgcmVjZWl2ZWQgZnJvbSB0aGUgd2ViIHNlcnZlci5cIiArIE9TRW52aXJvbm1lbnQuRW9sU2VxICsgT1NFbnZpcm9ubWVudC5Fb2xTZXEgKyB0aGlzLlNlcnZlclVybCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKE5TdHJpbmcuRm9ybWF0KFwiSGFuZHNoYWtlIHJlc3BvbnNlICMxOiB7MH1cIiwgcmVzcG9uc2VTdHIpKTtcclxuICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKFwiXCIpO1xyXG5cclxuICAgICAgICBoYW5kc2hha2VSZXNwb25zZSA9IG5ldyBIYW5kc2hha2VSZXNwb25zZShyZXNwb25zZVN0cik7XHJcblxyXG4gICAgICAgIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5Db250ZXh0SUQgPSBoYW5kc2hha2VSZXNwb25zZS5Db250ZXh0SWQ7XHJcblxyXG4gICAgICAgIC8vIHNhdmUgc2Vzc2lvbiBpZCBvbiBjbGllbnQgd2hpY2ggaXMgcmVjZWl2ZWQgaW4gMXN0IHJlc3BvbnNlLlxyXG4gICAgICAgIHRoaXMuU2Vzc2lvbklkID0gaGFuZHNoYWtlUmVzcG9uc2UuR2V0U2Vzc2lvbklkO1xyXG5cclxuICAgICAgICBIdHRwTWFuYWdlci5HZXRJbnN0YW5jZSgpLkh0dHBDb21tdW5pY2F0aW9uVGltZW91dE1TID0gaGFuZHNoYWtlUmVzcG9uc2UuSHR0cFRpbWVvdXQgKiAxMDAwO1xyXG5cclxuICAgICAgICAvLyBEdXJpbmcgYXV0aGVudGljYXRpb24sIGlmIGF1dGhlbnRpY2F0aW9uIGZhaWxlZCB0aGVuIHNlcnZlciB1bmxvYWRzIGN0eCBhbmQgY3JlYXRlcyBuZXcgY3R4IGZvciBuZXh0IGF1dGhlbnRpY2F0aW9uIHJlcXVlc3QuXHJcbiAgICAgICAgLy8gU28gZXZlcnkgdGltZSBhZnRlciBhdXRoZW50aWNhdGlvbiBmYWlscyB3ZSByZWNlaXZlIG5ldyBjdHhpZCBmb3IgbmV4dCBhdXRoZW50aWNhdGlvbiByZXF1ZXN0LlxyXG4gICAgICAgIC8vIEhlbmNlIHRha2UgY3R4Z3JvdXAgaW4gbG9jYWwgdmFyaWFibGUgYW5kIHVwZGF0ZSBDbGllbnRNYW5hZ2VyIG9ubHkgYWZ0ZXIgYXV0aGVudGljYXRpb24gaXMgZG9uZS5cclxuICAgICAgICBpZiAoTlN0cmluZy5Jc051bGxPckVtcHR5KFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRDdHhHcm91cCgpKSkge1xyXG4gICAgICAgICAgY3R4R3JvdXAgPSBoYW5kc2hha2VSZXNwb25zZS5Db250ZXh0SWQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICAgIC8vIDJuZCBoYW5kc2hha2UgcmVxdWVzdFxyXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAgICAgbGV0IGNyZWRlbnRpYWxzOiBVc2VybmFtZVBhc3N3b3JkQ3JlZGVudGlhbHMgPSBudWxsO1xyXG4gICAgICAgIGlmIChTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0U2tpcEF1dGhlbnRpY2F0aW9uRGlhbG9nKCkpIHtcclxuICAgICAgICAgIC8vIHNraXAgYXV0aGVudGljYXRpb24gKHRvIHRoZSBydW50aW1lLWVuZ2luZSkgZGlhbG9nXHJcbiAgICAgICAgICBpZiAoU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldFVzZXJuYW1lKCkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgLy8gdXNlciB0aGUgdXNlcklkICYgcGFzc3dvcmQgdGhhdCB3ZXJlIHBhc3NlZCwgYW5kIHJlc2V0IHRoZW0gKHRoZXknbGwgYmUgc2V0IGJlbG93LCBpZiBhdXRoZW50aWNhdGVkIGJ5IHRoZSBydW50aW1lLWVuZ2luZSlcclxuICAgICAgICAgICAgY3JlZGVudGlhbHMgPSBuZXcgVXNlcm5hbWVQYXNzd29yZENyZWRlbnRpYWxzKFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRVc2VybmFtZSgpLCBTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0UGFzc3dvcmQoKSk7XHJcbiAgICAgICAgICAgIFNlcnZlckNvbmZpZy5JbnN0YW5jZS5zZXRVc2VybmFtZShcIlwiKTtcclxuICAgICAgICAgICAgU2VydmVyQ29uZmlnLkluc3RhbmNlLnNldFBhc3N3b3JkKFwiXCIpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoaGFuZHNoYWtlUmVzcG9uc2UuSW5wdXRQYXNzd29yZCAmJiBoYW5kc2hha2VSZXNwb25zZS5TeXN0ZW1Mb2dpbiAhPT0gSGFuZHNoYWtlUmVzcG9uc2UuU1lTVEVNX0xPR0lOX0FEKSB7XHJcbiAgICAgICAgICAvLyBhdXRoZW50aWNhdGlvbiAodG8gdGhlIHJ1bnRpbWUtZW5naW5lKSBkaWFsb2dcclxuICAgICAgICAgIGlmIChsYXN0VHlwZWRVc2VySWQgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgbGV0IHRpdGxlOiBzdHJpbmcgPSBBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuQlJLVEFCX1NUUl9FUlJPUik7XHJcbiAgICAgICAgICAgIGxldCBlcnJvcjogc3RyaW5nID0gQWNjZXNzSGVscGVyLmxhbmd1YWdlRGF0YS5nZXRDb25zdE1lc3NhZ2UoTXNnSW50ZXJmYWNlLlVTUklOUF9TVFJfQkFEUEFTU1cpO1xyXG4gICAgICAgICAgICBhd2FpdCBHVUlNYW5hZ2VyLkluc3RhbmNlLk1lc3NhZ2VCb3godGl0bGUsIGVycm9yLCBTdHlsZXMuTVNHQk9YX0lDT05fRVJST1IgfCBTdHlsZXMuTVNHQk9YX0JVVFRPTl9PSyk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgLy8gVE9ETzogaW1wbGVtZW50IGF1dGhlbnRpY2F0aW9uIGRpYWxvZ1xyXG4gICAgICAgICAgLy8gbGV0IHVzZXJJZDogc3RyaW5nID0gbGFzdFR5cGVkVXNlcklkO1xyXG4gICAgICAgICAgLy9cclxuICAgICAgICAgIC8vIGlmIChkaWFsb2cgPT09IG51bGwpIHtcclxuICAgICAgICAgIC8vICAgZGlhbG9nID0gbmV3IEF1dGhlbnRpY2F0aW9uRGlhbG9nSGFuZGxlcih1c2VySWQsIEdldExvZ29uRGlhbG9nRXhlY1Byb3BzKCkpO1xyXG4gICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgLy8gZGlhbG9nLm9wZW5EaWFsb2coKTtcclxuXHJcbiAgICAgICAgICAvLyBjcmVkZW50aWFscyA9IGRpYWxvZy5nZXRDcmVkZW50aWFscygpO1xyXG4gICAgICAgICAgLy8gaWYgKGNyZWRlbnRpYWxzICE9PSBudWxsKVxyXG4gICAgICAgICAgLy8gICBsYXN0VHlwZWRVc2VySWQgPSBjcmVkZW50aWFscy5Vc2VybmFtZTtcclxuICAgICAgICAgIC8vIGVsc2VcclxuICAgICAgICAgIC8vICAgYXV0aGVudGljYXRpb25DYW5jZWxsZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ29uc3RJbnRlcmZhY2UuU0VTU0lPTl9DT1VOVEVSX0NMT1NFX0NUWF9JTkRJQ0FUSU9OIGluc3RydWN0cyB0aGUgc2VydmVyIHRvIGNsb3NlIHRoZSBjb250ZXh0LlxyXG4gICAgICAgIC8vIChub3RlOiB1bmxvYWRpbmcgYSBjb250ZXh0IHBvc3QgaGFuZHNoYWtlIHNob3VsZCBiZSBkb25lIHVzaW5nIENvbW1hbmQuY3JlYXRlVW5sb2FkQ29tbWFuZCkuXHJcbiAgICAgICAgaWYgKGF1dGhlbnRpY2F0aW9uQ2FuY2VsbGVkKSB7XHJcbiAgICAgICAgICB0aGlzLlNldFNlc3Npb25Db3VudGVyKENvbnN0SW50ZXJmYWNlLlNFU1NJT05fQ09VTlRFUl9DTE9TRV9DVFhfSU5ESUNBVElPTik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgaGFuZHNoYWtlQXV0aFVybDogc3RyaW5nID0gdGhpcy5QcmVwYXJlQXV0aGVudGljYXRpb25VcmwoaGFuZHNoYWtlUmVzcG9uc2UuQ29udGV4dElkLCBjdHhHcm91cCwgdGhpcy5HZXRTZXNzaW9uQ291bnRlcigpKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIGlmIChjcmVkZW50aWFscyAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBsZXQgY3JlZGVudGlhbHNTdHI6IHN0cmluZyA9IGNyZWRlbnRpYWxzLlVzZXJuYW1lICsgXCI6XCI7XHJcbiAgICAgICAgICAgIGlmICghTlN0cmluZy5Jc051bGxPckVtcHR5KGNyZWRlbnRpYWxzLlBhc3N3b3JkKSkge1xyXG4gICAgICAgICAgICAgIGNyZWRlbnRpYWxzU3RyID0gY3JlZGVudGlhbHNTdHIgKyBjcmVkZW50aWFscy5QYXNzd29yZCArIFwiOlwiO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzU3RyICs9IGhhbmRzaGFrZVJlc3BvbnNlLkNvbnRleHRJZDtcclxuICAgICAgICAgICAgY3JlZGVudGlhbHNTdHIgPSBTY3JhbWJsZXIuU2NyYW1ibGUoY3JlZGVudGlhbHNTdHIpO1xyXG4gICAgICAgICAgICBjcmVkZW50aWFsc1N0ciA9IEJhc2U2NC5lbmNvZGUoY3JlZGVudGlhbHNTdHIsIHRydWUsIEVuY29kaW5nLlVURjgpO1xyXG4gICAgICAgICAgICBoYW5kc2hha2VBdXRoVXJsICs9IChcIiZVU0VSTkFNRT1cIiArIEh0dHBVdGlsaXR5LlVybEVuY29kZShjcmVkZW50aWFsc1N0ciwgRW5jb2RpbmcuVVRGOCkpO1xyXG5cclxuICAgICAgICAgICAgLy8gc2VuZCAybmQgaGFuZHNoYWtlIHJlcXVlc3QgLSB3aXRoIGF1dGhlbnRpY2F0aW9uXHJcbiAgICAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJIYW5kc2hha2UgcmVxdWVzdCAjMjogezB9XCIsIGhhbmRzaGFrZUF1dGhVcmwpKTtcclxuICAgICAgICAgICAgbGV0IHN0YXR1c1JlcXVlc3Q6IFJlZlBhcmFtPFJlcXVlc3RTdGF0dXM+ID0gbmV3IFJlZlBhcmFtKFJlcXVlc3RTdGF0dXMuSGFuZGxlZCk7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlU3RyID0gYXdhaXQgdGhpcy5EaXNwYXRjaFJlcXVlc3QoaGFuZHNoYWtlQXV0aFVybCwgbnVsbCwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5IQU5EU0hBS0UsIHN0YXR1c1JlcXVlc3QpO1xyXG5cclxuICAgICAgICAgICAgLy8gdmVyaWZ5IHRoYXQgdGhlIHJlc3BvbnNlIHdhc24ndCByZXBsYXllZFxyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2VTdHIuaW5kZXhPZihoYW5kc2hha2VSZXNwb25zZS5Db250ZXh0SWQpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ2ZXJFcnJvcihBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuVVNSSU5QX1NUUl9CQURQQVNTVykpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0VXNlcm5hbWUoY3JlZGVudGlhbHMuVXNlcm5hbWUpO1xyXG4gICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0UGFzc3dvcmQoY3JlZGVudGlhbHMuUGFzc3dvcmQpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IHJlcXVlc3RTdGF0dXM6IFJlZlBhcmFtPFJlcXVlc3RTdGF0dXM+ID0gbmV3IFJlZlBhcmFtKFJlcXVlc3RTdGF0dXMuSGFuZGxlZCk7XHJcbiAgICAgICAgICAgIC8vIHNlbmQgMm5kIGhhbmRzaGFrZSByZXF1ZXN0IC0gd2l0aG91dCBhdXRoZW50aWNhdGlvblxyXG4gICAgICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKE5TdHJpbmcuRm9ybWF0KFwiSGFuZHNoYWtlIHJlcXVlc3QgIzI6IHswfVwiLCBoYW5kc2hha2VBdXRoVXJsKSk7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlU3RyID0gYXdhaXQgdGhpcy5EaXNwYXRjaFJlcXVlc3QoaGFuZHNoYWtlQXV0aFVybCwgbnVsbCwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5IQU5EU0hBS0UsIHJlcXVlc3RTdGF0dXMpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhOU3RyaW5nLkZvcm1hdChcIkhhbmRzaGFrZSByZXNwb25zZSAjMjogezB9XCIsIHJlc3BvbnNlU3RyKSk7XHJcbiAgICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKFwiXCIpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcclxuICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNlcnZlckVycm9yKSB7XHJcbiAgICAgICAgICAgIGxldCBzZXJ2ZXJFcnJvcjogU2VydmVyRXJyb3IgPSA8U2VydmVyRXJyb3I+ZXg7XHJcbiAgICAgICAgICAgIGlmIChTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0U2tpcEF1dGhlbnRpY2F0aW9uRGlhbG9nKCkpIHtcclxuICAgICAgICAgICAgICBzd2l0Y2ggKHNlcnZlckVycm9yLkdldENvZGUoKSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBTZXJ2ZXJFcnJvci5FUlJfQUNDRVNTX0RFTklFRDpcclxuICAgICAgICAgICAgICAgIC8vIEV4dGVybmFsIEF1dGhlbnRpY2F0b3IgYXV0aGVudGljYXRlZCB0aGUgdXNlciwgYWNjZXNzIHRvIHRoZSBhcHBsaWNhdGlvbiB3YXNuJ3QgYXV0aG9yaXplZC5cclxuICAgICAgICAgICAgICAgIGNhc2UgU2VydmVyRXJyb3IuRVJSX0FVVEhFTlRJQ0FUSU9OOlxyXG4gICAgICAgICAgICAgICAgICAvLyBFeHRlcm5hbCBBdXRoZW50aWNhdG9yIGF1dGhlbnRpY2F0ZWQgdGhlIHVzZXIgYnV0IGFwcGxpY2F0aW9uIGF1dGhlbnRpY2F0aW9uIGZhaWxlZFxyXG4gICAgICAgICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0U2tpcEF1dGhlbnRpY2F0aW9uRGlhbG9nKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgdGhyb3cgc2VydmVyRXJyb3I7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyB0aGUgc2Vzc2lvbiB3aWxsIG5ldmVyIHByb3ZpZGUgYSB3YXkgdG8gY2hhbmdlIHRoZSBjcmVkZW50aWFscywgdGhlcmVmb3JlIGFib3J0XHJcbiAgICAgICAgICAgIGlmICghaGFuZHNoYWtlUmVzcG9uc2UuSW5wdXRQYXNzd29yZClcclxuICAgICAgICAgICAgICB0aHJvdyBzZXJ2ZXJFcnJvcjtcclxuXHJcbiAgICAgICAgICAgIC8vIEVycm9yLklORl9OT19SRVNVTFQ6XHJcbiAgICAgICAgICAgIC8vICAgIGlmIGF1dGhlbnRpY2F0aW9uIGRpYWxvZyB3YXMgY2FuY2VsZWQsIHRoZSByZXF1ZXN0IHdhcyBzZW50IG9ubHkgdG8gY2xvc2UgdGhlIGNvbnRleHQsXHJcbiAgICAgICAgICAgIC8vICAgIGFuZCB0aGUgc2VydmVyIGlzbid0IGV4cGVjdGVkIHRvIHJldHVybiBhIHJlc3BvbnNlXHJcbiAgICAgICAgICAgIGlmIChzZXJ2ZXJFcnJvci5HZXRDb2RlKCkgIT09IFNlcnZlckVycm9yLkVSUl9BVVRIRU5USUNBVElPTiAmJlxyXG4gICAgICAgICAgICAgICghYXV0aGVudGljYXRpb25DYW5jZWxsZWQgfHwgc2VydmVyRXJyb3IuR2V0Q29kZSgpICE9PSBTZXJ2ZXJFcnJvci5JTkZfTk9fUkVTVUxUKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IHNlcnZlckVycm9yO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgdGhyb3cgZXg7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBzdG9yZSBhbiBpbmRpY2F0aW9uIHRvIHNraXAgZnV0dXJlIGF1dGhlbnRpY2F0aW9uIChzZXNzaW9uIHJlc3RhcnQsIHBhcmFsbGVsIHByb2dyYW0pXHJcbiAgICAgIFNlcnZlckNvbmZpZy5JbnN0YW5jZS5zZXRTa2lwQXV0aGVudGljYXRpb25EaWFsb2codHJ1ZSk7XHJcblxyXG4gICAgICAvLyBzYXZlIGNvbnRleHQgZ3JvdXBcclxuICAgICAgU2VydmVyQ29uZmlnLkluc3RhbmNlLnNldEN0eEdyb3VwKGN0eEdyb3VwKTtcclxuXHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICAvLyBzZXQgc2Vzc2lvbiBwcm9wZXJ0aWVzXHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5TaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcyA9IGhhbmRzaGFrZVJlc3BvbnNlLlNjcmFtYmxlTWVzc2FnZXM7XHJcbiAgICAgIGlmIChMb2dnZXIuSW5zdGFuY2UuTG9nTGV2ZWwgIT09IExvZ2dlcl9Mb2dMZXZlbHMuQmFzaWMpIHtcclxuICAgICAgICAvLyBtYXhpbWFsIHZhbHVlIG9mIHRoZSBJbnRlcm5hbExvZ0xldmVsIHRoYXQgY2FuIGJlIHNldCBieSB0aGUgY2xpZW50LlxyXG4gICAgICAgIC8vIGlmIHNldCwgaXQgY29udHJvbHMgdGhlIG1heGltYWwgdmFsdWU7IG90aGVyd2lzZSwgYW55IGxvZyBsZXZlbCBpcyBhbGxvd2VkLlxyXG4gICAgICAgIGxldCBtYXhJbnRlcm5hbExvZ0xldmVsOiBzdHJpbmcgPSBoYW5kc2hha2VSZXNwb25zZS5NYXhJbnRlcm5hbExvZ0xldmVsO1xyXG4gICAgICAgIGlmIChtYXhJbnRlcm5hbExvZ0xldmVsICE9PSBudWxsKSB7XHJcbiAgICAgICAgICBsZXQgbWF4TG9nTGV2ZWw6IExvZ2dlcl9Mb2dMZXZlbHMgPSB0aGlzLnBhcnNlTG9nTGV2ZWwobWF4SW50ZXJuYWxMb2dMZXZlbCk7XHJcbiAgICAgICAgICBpZiAobWF4TG9nTGV2ZWwgPCBMb2dnZXIuSW5zdGFuY2UuTG9nTGV2ZWwpIHtcclxuICAgICAgICAgICAgLy8gdGV4dHVhbCB2YWx1ZSAoYXMgbG9hZGVkIGZyb20gdGhlIGV4ZWN1dGlvbiBwcm9wZXJ0aWVzKVxyXG4gICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0SW50ZXJuYWxMb2dMZXZlbChtYXhJbnRlcm5hbExvZ0xldmVsKTtcclxuXHJcbiAgICAgICAgICAgIC8vIHNldCB0aGUgYWN0dWFsIGxvZyBsZXZlbCB0byB0aGUgbGV2ZWwgYWxsb3dlZCBieSB0aGUgc2VydmVyXHJcbiAgICAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVRvTG9nKE5TdHJpbmcuRm9ybWF0KFwiSW50ZXJuYWwgbG9nIGxldmVsIHdhcyByZXN0cmljdGVkIHRvICd7MH0nIGJ5IHRoZSBNYWdpYyB4cGEgc2VydmVyLlwiLCBtYXhJbnRlcm5hbExvZ0xldmVsKSwgZmFsc2UpO1xyXG4gICAgICAgICAgICBMb2dnZXIuSW5zdGFuY2UuTG9nTGV2ZWwgPSBtYXhMb2dMZXZlbDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgICAgLy8gM3JkIHJlcXVlc3Q6IEV4ZWN1dGVzIHRoZSBpbml0aWFsIHByb2dyYW0gaW4gdGhlIHNlcnZlci5cclxuICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICBpZiAoIWF1dGhlbnRpY2F0aW9uQ2FuY2VsbGVkKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5FeGVjdXRlSW5pdGlhbFJlcXVlc3QoKTtcclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXgpIHtcclxuICAgICAgaWYgKGV4IGluc3RhbmNlb2YgU2VydmVyRXJyb3IpXHJcbiAgICAgICAgdGhyb3cgZXg7XHJcblxyXG4gICAgICBpZiAoaXNOdWxsT3JVbmRlZmluZWQoZXguSW5uZXJFeGNlcHRpb24pKVxyXG4gICAgICAgIHRocm93ICBuZXcgU2VydmVyRXJyb3IoZXgubWVzc2FnZSwgbmV3IEV4Y2VwdGlvbihleCkpO1xyXG4gICAgICBlbHNlXHJcbiAgICAgICAgdGhyb3cgbmV3IFNlcnZlckVycm9yKGV4Lm1lc3NhZ2UsIGV4LklubmVyRXhjZXB0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gIWF1dGhlbnRpY2F0aW9uQ2FuY2VsbGVkO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBwcmVwYXJlcyBoYW5kc2hha2UgcmVxdWVzdCB1cmwgZm9yIGF1dGhlbnRpY2F0aW9uXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJjb250ZXh0SWRcIj48L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cImN0eEdyb3VwXCI+PC9wYXJhbT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJzZXNzaW9uQ291bnRcIj48L3BhcmFtPlxyXG4gIC8vLyA8cmV0dXJucz48L3JldHVybnM+XHJcbiAgcHJpdmF0ZSBQcmVwYXJlQXV0aGVudGljYXRpb25VcmwoY29udGV4dElkOiBzdHJpbmcsIGN0eEdyb3VwOiBzdHJpbmcsIHNlc3Npb25Db3VudDogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIGxldCBoYW5kc2hha2VBdXRoVXJsOiBzdHJpbmcgPSB0aGlzLlNlcnZlclVybCArIENvbnN0SW50ZXJmYWNlLlJFUV9BUkdfU1RBUlQgK1xyXG4gICAgICBDb25zdEludGVyZmFjZS5SQ19JTkRJQ0FUSU9OICsgQ29uc3RJbnRlcmZhY2UuVVRGOFRSQU5TICtcclxuICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfVE9LRU5fQ1RYX0lEICsgY29udGV4dElkO1xyXG5cclxuICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQodGhpcy5TZXNzaW9uSWQpKVxyXG4gICAgICBoYW5kc2hha2VBdXRoVXJsICs9IChDb25zdEludGVyZmFjZS5SRVFfQVJHX1NFUEFSQVRPUiArIENvbnN0SW50ZXJmYWNlLlJDX1RPS0VOX1NFU1NJT05fSUQgKyB0aGlzLlNlc3Npb25JZCk7XHJcblxyXG4gICAgaGFuZHNoYWtlQXV0aFVybCArPSAoQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgK1xyXG4gICAgICBDb25zdEludGVyZmFjZS5SQ19UT0tFTl9TRVNTSU9OX0NPVU5UICsgc2Vzc2lvbkNvdW50ICtcclxuICAgICAgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgK1xyXG4gICAgICBDb25zdEludGVyZmFjZS5SQ19UT0tFTl9DVFhfR1JPVVAgKyBjdHhHcm91cCArXHJcbiAgICAgIENvbnN0SW50ZXJmYWNlLlJFUV9BUkdfU0VQQVJBVE9SICtcclxuICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfQVVUSEVOVElDQVRJT05fUkVRVUVTVCk7XHJcblxyXG4gICAgcmV0dXJuIGhhbmRzaGFrZUF1dGhVcmw7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIEV4ZWN1dGVzIHRoZSBpbml0aWFsIHByb2dyYW0gaW4gdGhlIHNlcnZlcjpcclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIHByaXZhdGUgYXN5bmMgRXhlY3V0ZUluaXRpYWxSZXF1ZXN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgLy8gc2VuZCB0aGUgSU5JVElBTCByZXF1ZXN0IHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICBhd2FpdCB0aGlzLkV4ZWN1dGVfMShDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2VuZGluZ0luc3RydWN0aW9uLlRBU0tTX0FORF9DT01NQU5EUywgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5JTklUSUFMLCBudWxsKTtcclxuICB9XHJcblxyXG4gIC8vIHByaXZhdGUgc3RhdGljIEdldExvZ29uRGlhbG9nRXhlY1Byb3BzKCk6IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc+IHtcclxuICAvLyAgIGxldCBkaWN0aW9uYXJ5OiBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPiA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPigpO1xyXG4gIC8vICAgbGV0IHZhbHVlOiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uV2luZG93VGl0bGUoKTtcclxuICAvLyAgIGxldCBmbGFnOiBib29sZWFuID0gTlN0cmluZy5Jc051bGxPckVtcHR5KHZhbHVlKTtcclxuICAvLyAgIGlmIChmbGFnKSB7XHJcbiAgLy8gICAgIHZhbHVlID0gXCJMb2dvbiAtIFwiICsgQ2xpZW50TWFuYWdlci5JbnN0YW5jZS5nZXRBcHBOYW1lKCk7XHJcbiAgLy8gICB9XHJcbiAgLy8gICBkaWN0aW9uYXJ5LkFkZChcIkxvZ29uV2luZG93VGl0bGVcIiwgdmFsdWUpO1xyXG4gIC8vICAgbGV0IHRleHQ6IHN0cmluZyA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25Hcm91cFRpdGxlKCk7XHJcbiAgLy8gICBsZXQgZmxhZzI6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KHRleHQpO1xyXG4gIC8vICAgaWYgKGZsYWcyKSB7XHJcbiAgLy8gICAgIHRleHQgPSAoKHRleHQubGVuZ3RoID4gNjIpID8gTlN0cmluZy5TdWJzdHJpbmcodGV4dCwgMCwgNjIpIDogdGV4dCk7XHJcbiAgLy8gICB9XHJcbiAgLy8gICBlbHNlIHtcclxuICAvLyAgICAgdGV4dCA9IFwiTG9nb24gUGFyYW1ldGVyc1wiO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvbkdyb3VwVGl0bGVcIiwgdGV4dCk7XHJcbiAgLy8gICBsZXQgdGV4dDI6IHN0cmluZyA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25Nc2dDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzM6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KHRleHQyKTtcclxuICAvLyAgIGlmIChmbGFnMykge1xyXG4gIC8vICAgICB0ZXh0MiA9ICgodGV4dDIubGVuZ3RoID4gNTYpID8gTlN0cmluZy5TdWJzdHJpbmcodGV4dDIsIDAsIDU2KSA6IHRleHQyKTtcclxuICAvLyAgICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvbk1lc3NhZ2VDYXB0aW9uXCIsIHRleHQyKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCBsb2dvbldpbmRvd0ljb25VUkw6IFVyaSA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25XaW5kb3dJY29uVVJMKCk7XHJcbiAgLy8gICBsZXQgZmxhZzQ6IGJvb2xlYW4gPSBVcmkub3BfSW5lcXVhbGl0eShsb2dvbldpbmRvd0ljb25VUkwsIG51bGwpICYmICFOU3RyaW5nLklzTnVsbE9yRW1wdHkobG9nb25XaW5kb3dJY29uVVJMLlRvU3RyaW5nKCkpO1xyXG4gIC8vICAgaWYgKGZsYWc0KSB7XHJcbiAgLy8gICAgIGRpY3Rpb25hcnkuQWRkKFwiTG9nb25XaW5kb3dJY29uVVJMXCIsIGxvZ29uV2luZG93SWNvblVSTC5Ub1N0cmluZygpKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCBsb2dvbldpbmRvd0ltYWdlVVJMOiBVcmkgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uV2luZG93SW1hZ2VVUkwoKTtcclxuICAvLyAgIGxldCBmbGFnNTogYm9vbGVhbiA9IFVyaS5vcF9JbmVxdWFsaXR5KGxvZ29uV2luZG93SW1hZ2VVUkwsIG51bGwpICYmICFOU3RyaW5nLklzTnVsbE9yRW1wdHkobG9nb25XaW5kb3dJbWFnZVVSTC5Ub1N0cmluZygpKTtcclxuICAvLyAgIGlmIChmbGFnNSkge1xyXG4gIC8vICAgICBkaWN0aW9uYXJ5LkFkZChcIkxvZ29uSW1hZ2VVUkxcIiwgbG9nb25XaW5kb3dJbWFnZVVSTC5Ub1N0cmluZygpKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCB0ZXh0Mzogc3RyaW5nID0gQ2xpZW50TWFuYWdlci5JbnN0YW5jZS5nZXRMb2dvblVzZXJJZENhcHRpb24oKTtcclxuICAvLyAgIGxldCBmbGFnNjogYm9vbGVhbiA9ICFOU3RyaW5nLklzTnVsbE9yRW1wdHkodGV4dDMpO1xyXG4gIC8vICAgaWYgKGZsYWc2KSB7XHJcbiAgLy8gICAgIHRleHQzID0gKCh0ZXh0My5sZW5ndGggPiA5KSA/IE5TdHJpbmcuU3Vic3RyaW5nKHRleHQzLCAwLCA5KSA6IHRleHQzKTtcclxuICAvLyAgICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvblVzZXJJRENhcHRpb25cIiwgdGV4dDMpO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgbGV0IHRleHQ0OiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uUGFzc3dvcmRDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzc6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KHRleHQ0KTtcclxuICAvLyAgIGlmIChmbGFnNykge1xyXG4gIC8vICAgICB0ZXh0NCA9ICgodGV4dDQubGVuZ3RoID4gOSkgPyBOU3RyaW5nLlN1YnN0cmluZyh0ZXh0NCwgMCwgOSkgOiB0ZXh0NCk7XHJcbiAgLy8gICAgIGRpY3Rpb25hcnkuQWRkKFwiTG9nb25QYXNzd29yZENhcHRpb25cIiwgdGV4dDQpO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgbGV0IGxvZ29uT0tDYXB0aW9uOiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uT0tDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzg6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KGxvZ29uT0tDYXB0aW9uKTtcclxuICAvLyAgIGlmIChmbGFnOCkge1xyXG4gIC8vICAgICBkaWN0aW9uYXJ5LkFkZChcIkxvZ29uT0tDYXB0aW9uXCIsIGxvZ29uT0tDYXB0aW9uKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCBsb2dvbkNhbmNlbENhcHRpb246IHN0cmluZyA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25DYW5jZWxDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzk6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KGxvZ29uQ2FuY2VsQ2FwdGlvbik7XHJcbiAgLy8gICBpZiAoZmxhZzkpIHtcclxuICAvLyAgICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvbkNhbmNlbENhcHRpb25cIiwgbG9nb25DYW5jZWxDYXB0aW9uKTtcclxuICAvLyAgIH1cclxuICAvLyAgIHJldHVybiBkaWN0aW9uYXJ5O1xyXG4gIC8vIH1cclxuXHJcblxyXG4gIC8vLyA8c3VtbWFyeT5cclxuICAvLy8gUmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgcnVudGltZSB0YXNrIHRyZWUgc3RydWN0dXJlIGJ5IGdvaW5nIHVwIGZyb20gdGhlIGN1cnJlbnQgdGFza1xyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgcHJpdmF0ZSBHZXRUYXNrVHJlZSh0YXNrOiBUYXNrKTogTGlzdDxzdHJpbmc+IHtcclxuICAgIGxldCB0YXNrVHJlZTogTGlzdDxzdHJpbmc+ID0gbmV3IExpc3Q8c3RyaW5nPigpO1xyXG5cclxuICAgIHdoaWxlICghaXNOdWxsT3JVbmRlZmluZWQodGFzaykpIHtcclxuICAgICAgdGFza1RyZWUucHVzaCh0YXNrLmdldFRhc2tJbmZvKCkpO1xyXG4gICAgICB0YXNrID0gPFRhc2s+dGFzay5nZXRQYXJlbnQoKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGFza1RyZWU7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIFVwZGF0ZSB0aGUgcmVxdWVzdCBpbmZvIG9iamVjdCB1c2luZyBpbmZvcm1hdGlvbiBvYnRhaW5lZCBmcm9tIGN1cnJlbnQgb3BlcmF0aW9uIGJlaW5nIGV4ZWN1dGVkLlxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgcHJpdmF0ZSBhc3luYyBVcGRhdGVSZXF1ZXN0SW5mbygpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGxldCBjdXJyTUdEYXRhOiBNR0RhdGEgPSBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuZ2V0Q3Vyck1HRGF0YSgpO1xyXG4gICAgbGV0IGV2ZW50c01hbmFnZXI6IEV2ZW50c01hbmFnZXIgPSA8RXZlbnRzTWFuYWdlcj5BY2Nlc3NIZWxwZXIuZXZlbnRzTWFuYWdlcjtcclxuICAgIGxldCBvcGVyRXhlY3V0aW9uOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBsZXQgY21kc1RvU2VydmVyOiBDb21tYW5kc1RhYmxlID0gPENvbW1hbmRzVGFibGU+Y3Vyck1HRGF0YS5DbWRzVG9TZXJ2ZXI7XHJcblxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjbWRzVG9TZXJ2ZXIuZ2V0U2l6ZSgpOyBpKyspIHtcclxuICAgICAgLy8gV2hlbiB0aGUgcmVxdWVzdCBpcyBiZWluZyBzZW50IHRvIHNlcnZlciBkdWUgdG8gYW4gb3BlcmF0aW9uIGV4ZWN1dGlvbiwgZ2V0IHRoZSBpbmZvcm1hdGlvbiBvZiBjdXJyZW50IG9wZXJhdGlvbiBmcm9tIENtZHNUb1NlcnZlclxyXG4gICAgICBpZiAoY21kc1RvU2VydmVyLmdldENtZChpKSBpbnN0YW5jZW9mIEV4ZWNPcGVyQ29tbWFuZCkge1xyXG4gICAgICAgIGxldCBvcGVyQ21kOiBFeGVjT3BlckNvbW1hbmQgPSA8RXhlY09wZXJDb21tYW5kPig8Q29tbWFuZHNUYWJsZT5jdXJyTUdEYXRhLkNtZHNUb1NlcnZlcikuZ2V0Q21kKGkpO1xyXG5cclxuICAgICAgICB0aGlzLl9yZXF1ZXN0SW5mby5zZXJ2ZXJDYWxsQXQgPSBvcGVyQ21kLmdldENvbW1hbmRJbmZvKCk7XHJcblxyXG4gICAgICAgIHRoaXMuX3JlcXVlc3RJbmZvLnJ1bnRpbWVUYXNrVHJlZSA9IHRoaXMuR2V0VGFza1RyZWUob3BlckNtZC5nZXRUYXNrKCkpO1xyXG4gICAgICAgIG9wZXJFeGVjdXRpb24gPSB0cnVlO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fcmVxdWVzdEluZm8uZXh0cmFJbmZvLmNvbnRleHRJRCA9IFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5Db250ZXh0SUQ7XHJcbiAgICB0aGlzLl9yZXF1ZXN0SW5mby5leHRyYUluZm8uc2Vzc2lvbkNvdW50ZXIgPSB0aGlzLkdldFNlc3Npb25Db3VudGVyKCk7XHJcblxyXG4gICAgLy8gTG9nIGluZm9ybWF0aW9uIGFib3V0IG1hZ2ljIGludGVybmFsIGV2ZW50cyBjYXVzaW5nIHJlcXVlc3RzIHRvIHNlcnZlclxyXG4gICAgaWYgKCFvcGVyRXhlY3V0aW9uKSB7XHJcbiAgICAgIGlmIChldmVudHNNYW5hZ2VyLmdldExhc3RSdEV2ZW50KCkgIT0gbnVsbCAmJiBldmVudHNNYW5hZ2VyLmdldExhc3RSdEV2ZW50KCkuSW50ZXJuYWxFdmVudCAhPSAwKSB7XHJcbiAgICAgICAgbGV0IHJ0RXZ0OiBSdW5UaW1lRXZlbnQgPSBldmVudHNNYW5hZ2VyLmdldExhc3RSdEV2ZW50KCk7XHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdEluZm8ucnVudGltZVRhc2tUcmVlID0gdGhpcy5HZXRUYXNrVHJlZSg8VGFzaz5ydEV2dC5nZXRUYXNrKCkpO1xyXG5cclxuICAgICAgICAvLyByZXR1cm4gZGVzY3JpcHRpb24gYXMgcGVyIG5ldy9vbGQgaW50ZXJuYWwgZXZlbnQgZGVzY1xyXG4gICAgICAgIGxldCBldmVudERlc2NyaXB0aW9uOiBzdHJpbmcgPSBydEV2dC5pc05ld0ludGVybmFsRXZlbnQoKVxyXG4gICAgICAgICAgPyBOU3RyaW5nLlRyaW1FbmQocnRFdnQuZ2V0TmV3SW50ZXJuYWxFdmVudERlc2NyaXB0aW9uKCkpXHJcbiAgICAgICAgICA6IEV2ZW50LmdldEludGVybmFsRXZ0RGVzY3JpcHRpb24ocnRFdnQuSW50ZXJuYWxFdmVudCk7XHJcblxyXG5cclxuICAgICAgICAvLyBlLmcuIEV2ZW50IFs8TmV4dCBDaHVuaz5dIHdoaWxlIGV4ZWN1dGluZyBbPFZpZXcgUmVmcmVzaD5dXHJcbiAgICAgICAgbGV0IGNtZDogSUNsaWVudENvbW1hbmQgPSBjbWRzVG9TZXJ2ZXIuZ2V0Q21kKGNtZHNUb1NlcnZlci5nZXRTaXplKCkgLSAxKTtcclxuICAgICAgICBpZiAoY21kIGFzIElDbGllbnRUb1NlcnZlckNvbW1hbmRJbmZvKSB7XHJcbiAgICAgICAgICBsZXQgY29tbWFuZEluZm86IHN0cmluZyA9IE5TdHJpbmcuSXNOdWxsT3JFbXB0eSgoPElDbGllbnRUb1NlcnZlckNvbW1hbmRJbmZvPmNtZCkuZ2V0Q29tbWFuZEluZm8oKSlcclxuICAgICAgICAgICAgPyBOU3RyaW5nLkVtcHR5XHJcbiAgICAgICAgICAgIDogKDxJQ2xpZW50VG9TZXJ2ZXJDb21tYW5kSW5mbz5jbWQpLmdldENvbW1hbmRJbmZvKCk7XHJcblxyXG4gICAgICAgICAgLy8gSW4gY2FzZSB0aGUgcnVudGltZSBldmVudCBhbmQgRXZlbnQgY29tbWFuZCBhcmUgc2FtZSwgbm8gbmVlZCB0byBsb2cgdGhlIGV4dHJhIGluZm9ybWF0aW9uXHJcbiAgICAgICAgICBpZiAoY21kIGluc3RhbmNlb2YgRXZlbnRDb21tYW5kICYmIHJ0RXZ0LkludGVybmFsRXZlbnQgPT0gKDxFdmVudENvbW1hbmQ+Y21kKS5NYWdpY0V2ZW50KVxyXG4gICAgICAgICAgICBldmVudERlc2NyaXB0aW9uID0gTlN0cmluZy5FbXB0eTtcclxuXHJcbiAgICAgICAgICB0aGlzLl9yZXF1ZXN0SW5mby5zZXJ2ZXJDYWxsQXQgPSAnRXZlbnQgJyArIGNvbW1hbmRJbmZvICtcclxuICAgICAgICAgICAgKCFOU3RyaW5nLklzTnVsbE9yRW1wdHkoZXZlbnREZXNjcmlwdGlvbilcclxuICAgICAgICAgICAgICA/IE5TdHJpbmcuRm9ybWF0KCcgd2hpbGUgZXhlY3V0aW5nIFt7MH1dJywgZXZlbnREZXNjcmlwdGlvbilcclxuICAgICAgICAgICAgICA6IE5TdHJpbmcuRW1wdHkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBCdWlsZCB4bWwgZm9yIG1haW4gcHJvZyBkYXRhdmlldy4gcmVxdWlyZWQgZm9yIHJlLWluaXRpYWxpemluZyBzZXNzaW9uLlxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgcHJpdmF0ZSBhc3luYyBCdWlsZFhNTEZvck1haW5Qcm9ncmFtRGF0YVZpZXcoKTogUHJvbWlzZTxTdHJpbmc+IHtcclxuICAgIGxldCBtZXNzYWdlOiBTdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTtcclxuICAgIGxldCBmaXJzdE1nRGF0YTogTUdEYXRhID0gTUdEYXRhQ29sbGVjdGlvbi5JbnN0YW5jZS5nZXRNR0RhdGEoMCk7XHJcbiAgICBsZXQgbWFpblByZzogVGFzayA9IGZpcnN0TWdEYXRhLmdldE1haW5Qcm9nKDApO1xyXG5cclxuICAgIHdoaWxlIChtYWluUHJnICE9IG51bGwpIHtcclxuICAgICAgYXdhaXQgbWFpblByZy5idWlsZFhNTChtZXNzYWdlKTtcclxuICAgICAgbWFpblByZyA9IGZpcnN0TWdEYXRhLmdldE5leHRNYWluUHJvZyhtYWluUHJnLmdldEN0bElkeCgpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuU2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXMpIHtcclxuICAgICAgbGV0IHNjcmFtYmxlZENoYW5nZXM6IHN0cmluZyA9IFNjcmFtYmxlci5TY3JhbWJsZShtZXNzYWdlLlRvU3RyaW5nKCkpO1xyXG4gICAgICBtZXNzYWdlID0gbmV3IFN0cmluZ0J1aWxkZXIoc2NyYW1ibGVkQ2hhbmdlcyk7XHJcbiAgICB9XHJcblxyXG4gICAgbWVzc2FnZS5JbnNlcnQoMCwgWE1MQ29uc3RhbnRzLk1HX1RBR19PUEVOKTtcclxuICAgIG1lc3NhZ2UuQXBwZW5kKFhNTENvbnN0YW50cy5NR19UQUdfWE1MX0VORF9UQUdHRUQpO1xyXG5cclxuICAgIHJldHVybiBtZXNzYWdlLlRvU3RyaW5nKCk7XHJcbiAgfVxyXG5cclxuXHJcbiAgYXN5bmMgRXhlY3V0ZV8xKHNlbmRpbmdJbnN0cnVjdGlvbjogQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbiwgc2Vzc2lvblN0YWdlOiBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLCByZXM6IElSZXN1bHRWYWx1ZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgbGV0IHJlcUJ1Zjogc3RyaW5nO1xyXG4gICAgbGV0IGlzSW5pdGlhbENhbGw6IGJvb2xlYW4gPSBzZXNzaW9uU3RhZ2UgPT09IENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZXNzaW9uU3RhZ2UuSU5JVElBTDtcclxuICAgIGxldCBnbG9iYWxQYXJhbXNTdHJpbmc6IHN0cmluZyA9IG51bGw7XHJcbiAgICBsZXQgZW52VmFyc1N0cmluZzogc3RyaW5nID0gbnVsbDtcclxuXHJcbiAgICBpZiAodGhpcy5EZWxheUNvbW1hbmRFeGVjdXRpb24pXHJcbiAgICAgIHJldHVybjtcclxuXHJcbiAgICBpZiAoTG9nZ2VyLkluc3RhbmNlLkxvZ0xldmVsID09IExvZ2dlcl9Mb2dMZXZlbHMuUmVxdWVzdEluZm8gJiYgIWlzSW5pdGlhbENhbGwpXHJcbiAgICAgIGF3YWl0IHRoaXMuVXBkYXRlUmVxdWVzdEluZm8oKTtcclxuXHJcbiAgICBpZiAoaXNJbml0aWFsQ2FsbCkge1xyXG4gICAgICBsZXQgdmFsID0gdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuSVNfU0VTU0lPTl9SRUlOSVRJQUxJWklORyk7XHJcbiAgICAgIGlmICh2YWwgPT09ICd0cnVlJykge1xyXG4gICAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nID0gKHZhbCA9PT0gXCJ0cnVlXCIpID8gdHJ1ZSA6IGZhbHNlO1xyXG4gICAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLmxhc3RFeGNlcHRpb25NZXNzYWdlID0gdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuTEFTVF9FWENFUFRJT04pO1xyXG4gICAgICAgIGxldCBjdHhSZW1vdmVkID0gdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuQ1RYX1JFTU9WRURfRlJPTV9TUlZSKTtcclxuXHJcbiAgICAgICAgaWYgKGN0eFJlbW92ZWQgIT09ICcxJykge1xyXG4gICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRXJyb3JUb0xvZyhSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5sYXN0RXhjZXB0aW9uTWVzc2FnZSk7XHJcbiAgICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVUb0xvZyhcIlNlc3Npb24gaXMgcmVpbml0aWFsaXppbmcuLi5cIiwgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHNlbmRpbmdJbnN0cnVjdGlvbiA9PT0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbi5OT19UQVNLU19PUl9DT01NQU5EUylcclxuICAgICAgcmVxQnVmID0gbnVsbDtcclxuICAgIGVsc2Uge1xyXG4gICAgICByZXFCdWYgPSBhd2FpdCB0aGlzLlByZXBhcmVSZXF1ZXN0KHNlbmRpbmdJbnN0cnVjdGlvbiA9PT0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbi5UQVNLU19BTkRfQ09NTUFORFMpO1xyXG5cclxuICAgICAgbGV0IGNoYW5nZXM6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpO1xyXG4gICAgICBsZXQgYnVmZmVyOiBTdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTtcclxuICAgICAgaWYgKCFSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5Jc1Nlc3Npb25SZUluaXRpYWxpemluZylcclxuICAgICAgICBidWZmZXIuQXBwZW5kKHJlcUJ1Zik7XHJcblxyXG4gICAgICAvLyBzZW5kIGFjdGl2aXR5IG1vbml0b3IgbG9ncyB0byB0aGUgc2VydmVyXHJcbiAgICAgIC8vIGlmICh0aGlzLl9sb2dBY2N1bXVsYXRvciAhPT0gbnVsbCAmJiAhdGhpcy5fbG9nQWNjdW11bGF0b3IuRW1wdHkoKSlcclxuICAgICAgLy8gICBidWZmZXIuQXBwZW5kKHRoaXMuX2xvZ0FjY3VtdWxhdG9yLlJlYWQoKSk7XHJcblxyXG4gICAgICAvLyBzeW5jaHJvbml6ZSBjbGllbnQtc2lkZSBTZXRQYXJhbXMgYW5kIElOSVB1dCBkYXRhIHRvIHRoZSBzZXJ2ZXJcclxuICAgICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nKVxyXG4gICAgICB7XHJcbiAgICAgICAgZ2xvYmFsUGFyYW1zU3RyaW5nID0gdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuR0xPQkFMX1BBUkFNX0xJU1QpO1xyXG4gICAgICAgIGVudlZhcnNTdHJpbmcgPSB0aGlzLlJlc3RvcmVTZXNzaW9uUmVJbml0aWFsaXppbmdEYXRhRnJvbUxvY2FsU3RvcmFnZShDb25zdEludGVyZmFjZS5FTlZfVkFSX0xJU1QpO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2VcclxuICAgICAge1xyXG4gICAgICAgIGdsb2JhbFBhcmFtc1N0cmluZyA9IEFjY2Vzc0hlbHBlci5nbG9iYWxQYXJhbXMubWlycm9yVG9YTUwoKTtcclxuICAgICAgICBlbnZWYXJzU3RyaW5nID0gQWNjZXNzSGVscGVyLmVudlBhcmFtc1RhYmxlLm1pcnJvclRvWE1MKCk7XHJcbiAgICAgIH1cclxuICAgICAgY2hhbmdlcy5BcHBlbmQoZ2xvYmFsUGFyYW1zU3RyaW5nKTtcclxuICAgICAgY2hhbmdlcy5BcHBlbmQoZW52VmFyc1N0cmluZyk7XHJcblxyXG4gICAgICAvLyBJZiB0aGVyZSBpcyBzdHVmZiB0byBzeW5jaHJvbml6ZSwgd3JhcCBpdCwgc2NyYW1ibGUgaXQgYW5kIGFkZCB0aGUgTUdEQVRBIGZsYWdcclxuICAgICAgaWYgKGNoYW5nZXMuTGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNoYW5nZXMuSW5zZXJ0KDAsIFwiPFwiICsgQ29uc3RJbnRlcmZhY2UuTUdfVEFHX0VOVl9DSEFOR0VTICsgXCI+XCIpO1xyXG4gICAgICAgIGNoYW5nZXMuQXBwZW5kKFwiPC9cIiArIENvbnN0SW50ZXJmYWNlLk1HX1RBR19FTlZfQ0hBTkdFUyArIFwiPlwiKTtcclxuXHJcbiAgICAgICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLlNob3VsZFNjcmFtYmxlQW5kVW5zY3JhbWJsZU1lc3NhZ2VzKSB7XHJcbiAgICAgICAgICBsZXQgc2NyYW1ibGVkQ2hhbmdlczogc3RyaW5nID0gU2NyYW1ibGVyLlNjcmFtYmxlKGNoYW5nZXMuVG9TdHJpbmcoKSk7XHJcbiAgICAgICAgICBjaGFuZ2VzID0gbmV3IFN0cmluZ0J1aWxkZXIoc2NyYW1ibGVkQ2hhbmdlcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNoYW5nZXMuSW5zZXJ0KDAsIFhNTENvbnN0YW50cy5NR19UQUdfT1BFTik7XHJcbiAgICAgICAgY2hhbmdlcy5BcHBlbmQoWE1MQ29uc3RhbnRzLk1HX1RBR19YTUxfRU5EX1RBR0dFRCk7XHJcblxyXG4gICAgICAgIGJ1ZmZlci5BcHBlbmQoY2hhbmdlcy5Ub1N0cmluZygpKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmVxQnVmID0gYnVmZmVyLlRvU3RyaW5nKCk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHJlcXVlc3RTdGF0dXM6IFJlZlBhcmFtPFJlcXVlc3RTdGF0dXM+ID0gbmV3IFJlZlBhcmFtKFJlcXVlc3RTdGF0dXMuSGFuZGxlZCk7XHJcbiAgICBsZXQgcmVzcEJ1Zjogc3RyaW5nID0gbnVsbDtcclxuXHJcbiAgICBpZiAoUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSXNTZXNzaW9uUmVJbml0aWFsaXppbmcpIHtcclxuICAgICAgcmVxQnVmID0gcmVxQnVmICsgdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuTUFJTl9QUk9HX1ZJRVcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUmVtb3ZlZENvbnRleHRGcm9tU2VydmVyKVxyXG4gICAgICByZXF1ZXN0U3RhdHVzLnZhbHVlID0gUmVxdWVzdFN0YXR1cy5SZXRyeTsgLy90cnkgdG8gcmUtc3RhcnQgc2Vzc2lvbiBmaXJzdFxyXG4gICAgZWxzZSB7XHJcbiAgICAgIGlmIChSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUmVtb3ZpbmdDb250ZXh0RnJvbVNlcnZlcilcclxuICAgICAgICBSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUmVtb3ZlZENvbnRleHRGcm9tU2VydmVyID0gdHJ1ZTtcclxuXHJcbiAgICAgIHJlc3BCdWYgPSBhd2FpdCB0aGlzLkRpc3BhdGNoUmVxdWVzdCh0aGlzLlNlcnZlclVybCwgcmVxQnVmLCBzZXNzaW9uU3RhZ2UsIHJlcXVlc3RTdGF0dXMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChyZXF1ZXN0U3RhdHVzLnZhbHVlID09IFJlcXVlc3RTdGF0dXMuUmV0cnkpIHtcclxuICAgICAgYXdhaXQgdGhpcy5SZVN0YXJ0U2Vzc2lvbigpO1xyXG4gICAgfVxyXG4gICAgaWYgKHJlc3BCdWYgPT0gbnVsbClcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGlmIChpc0luaXRpYWxDYWxsKSB7XHJcbiAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLkluaXRpYWxVcmwgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nKSB7XHJcbiAgICAgICAgbGV0IGRhdGFTdG9yYWdlID0gd2luZG93LmxvY2FsU3RvcmFnZTtcclxuICAgICAgICBkYXRhU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLklTX1NFU1NJT05fUkVJTklUSUFMSVpJTkcpO1xyXG4gICAgICAgIGRhdGFTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuTUFJTl9QUk9HX1ZJRVcpO1xyXG4gICAgICAgIGRhdGFTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuR0xPQkFMX1BBUkFNX0xJU1QpO1xyXG4gICAgICAgIGRhdGFTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuRU5WX1ZBUl9MSVNUKTtcclxuICAgICAgICBkYXRhU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLkxBU1RfRVhDRVBUSU9OKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEZsb3dNb25pdG9yUXVldWUuSW5zdGFuY2UuZW5hYmxlKGZhbHNlKTtcclxuICAgIGF3YWl0IHRoaXMuUHJvY2Vzc1Jlc3BvbnNlKHJlc3BCdWYsIEFjY2Vzc0hlbHBlci5tZ0RhdGFUYWJsZS5jdXJyTWdkSUQsIG51bGwsIHJlcyk7XHJcblxyXG4gICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nKSB7XHJcbiAgICAgICAgQWNjZXNzSGVscGVyLmdsb2JhbFBhcmFtcy5SZXN0b3JlUGFyYW1zKGdsb2JhbFBhcmFtc1N0cmluZyk7XHJcbiAgICAgICAgQWNjZXNzSGVscGVyLmVudlBhcmFtc1RhYmxlLlJlc3RvcmVQYXJhbXMoZW52VmFyc1N0cmluZyk7XHJcblxyXG4gICAgICBsZXQgZGF0YVN0b3JhZ2UgPSB3aW5kb3cubG9jYWxTdG9yYWdlO1xyXG4gICAgICBsZXQgY3R4UmVtb3ZlZCA9IGRhdGFTdG9yYWdlLmdldEl0ZW0oQ29uc3RJbnRlcmZhY2UuQ1RYX1JFTU9WRURfRlJPTV9TUlZSKTtcclxuXHJcbiAgICAgIGlmIChjdHhSZW1vdmVkID09PSBcIjFcIikge1xyXG5cclxuICAgICAgICBFdmVudHNNYW5hZ2VyLkluc3RhbmNlLnJlc3RvcmVMYXN0U2F2ZWRSb3V0ZUV2ZW50RnJvbUxvY2FsU3RvcmFnZSgpO1xyXG5cclxuICAgICAgICBkYXRhU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLkNUWF9SRU1PVkVEX0ZST01fU1JWUik7XHJcbiAgICAgICAgZGF0YVN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5MQVNUX1JPVVRFX0VWRU5UKTtcclxuICAgICAgICBkYXRhU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLkxBU1RfUk9VVEVfRVZFTlRfU1JDX1RTSyk7XHJcbiAgICAgICAgZGF0YVN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5MQVNUX1JPVVRFX0VWRU5UX0FSR19MSVNUKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSXNTZXNzaW9uUmVJbml0aWFsaXppbmcgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vIGlmIChpc0luaXRpYWxDYWxsKSB7XHJcbiAgICAvLyAgIC8vIElmIGl0IHdhcyBpbml0aWFsIGNhbGwsIHdlIHdpbGwgc2VuZCBhbGwgcGVuZGluZyBsb2dzIChGYWlsZWQgZWFybGllciBleGVjdXRpb24gc2NlbmFyaW8pXHJcbiAgICAvLyAgIC8vIFRoZXkgd2lsbCBiZSBzZW50IGhlcmUsIGFmdGVyIGZpcnN0IHJlcXVlc3QgaXMgc2VydmVkLlxyXG4gICAgLy8gICBpZiAoQ2xpZW50TWFuYWdlci5JbnN0YW5jZS5nZXRMb2dDbGllbnRTZXF1ZW5jZUZvckFjdGl2aXR5TW9uaXRvcigpICYmIENsaWVudExvZ0FjY3VtdWxhdG9yLkV4aXN0aW5nTG9nc0ZvdW5kKCkpIHtcclxuICAgIC8vICAgICBsZXQgc3VjY2VzczogYm9vbGVhbiA9IHRoaXMuU2VuZFBlbmRpbmdMb2dzVG9TZXJ2ZXIoKTtcclxuICAgIC8vXHJcbiAgICAvLyAgICAgLy8gaWYgd2UgaGF2ZSBzdWNjZXNzZnVsbHkgc2VudCB0aGUgcGVuZGluZyBsb2dzIGRlbGV0ZSB0aGVtXHJcbiAgICAvLyAgICAgaWYgKHN1Y2Nlc3MpIHtcclxuICAgIC8vICAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLkRlbGV0ZVBlbmRpbmdMb2dzKCk7XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gICB9XHJcbiAgICAvLyB9XHJcbiAgICAvLyBlbHNlIGlmICh0aGlzLl9sb2dBY2N1bXVsYXRvciAhPT0gbnVsbCAmJiAhdGhpcy5fbG9nQWNjdW11bGF0b3IuRW1wdHkoKSkge1xyXG4gICAgLy8gICAvLyBBY2N1bXVsYXRlZCBsb2dzIHdlcmUgc2VudCwgc28gcmVzZXQgKGRlbGV0ZSkgdGhlbSBub3dcclxuICAgIC8vICAgdGhpcy5fbG9nQWNjdW11bGF0b3IuUmVzZXQoKTtcclxuICAgIC8vIH1cclxuXHJcbiAgICAvLyByZWZyZXNoIHRoZSBkaXNwbGF5c1xyXG4gICAgaWYgKHNlbmRpbmdJbnN0cnVjdGlvbiA9PT0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbi5UQVNLU19BTkRfQ09NTUFORFMpIHtcclxuICAgICAgQWNjZXNzSGVscGVyLm1nRGF0YVRhYmxlLnN0YXJ0VGFza3NJdGVyYXRpb24oKTtcclxuICAgICAgbGV0IHRhc2s6IFRhc2tCYXNlO1xyXG4gICAgICB3aGlsZSAoKHRhc2sgPSA8VGFza0Jhc2U+QWNjZXNzSGVscGVyLm1nRGF0YVRhYmxlLmdldE5leHRUYXNrKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgbGV0IGRhdGFWaWV3V2FzUmV0cmlldmVkOiBib29sZWFuID0gdGFzay5EYXRhVmlld1dhc1JldHJpZXZlZDtcclxuICAgICAgICBpZiAoZGF0YVZpZXdXYXNSZXRyaWV2ZWQpIHtcclxuICAgICAgICAgIGF3YWl0IHRhc2suUmVmcmVzaERpc3BsYXkoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoaXNJbml0aWFsQ2FsbClcclxuICAgICAgU2VydmVyQ29uZmlnLkluc3RhbmNlLnNldEdsb2JhbFBhcmFtcyhudWxsKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5zZW5kICdyZXFCdWYnIHRvICd1cmwnOyByZWNlaXZlIGEgcmVzcG9uc2UuXHJcbiAgLy8vIEZvciBOb3JtYWwvSW5pdGlhbENhbGwgcmVxdWVzdHMsIHRoZSB1cmwgcG9pbnRzIHRvIHRoZSB3ZWItcmVxdWVzdGVyLlxyXG4gIC8vLyBUaGUgb3RoZXIgcGFyYW1ldGVycyBhbmQgZGF0YSBnb2VzIGFzIHRoZSBlbmNvZGVkIGJvZHkuXHJcbiAgLy8vIFRoaXMgbWVhbnMgdGhhdCBpdCBpcyBhIFBPU1QgcmVxdWVzdC5cclxuICAvLy8gT24gdGhlIG90aGVyIGhhbmQsIEhhbmRTaGFrZSByZXF1ZXN0IGlzIGEgR0VUIHJlcXVlc3QgYW5kIHNvIHRoZSBwYXJhbWV0ZXJzIGFyZVxyXG4gIC8vLyBzZW50IGluIHRoZSBVUkwgaXRzZWxmLiBJbiB0aGlzIGNhc2UsIGVuY29kZWRCb2R5IGhhcyB0byBiZSBudWxsLlxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwidXJsXCI+VVJMIHRvIGJlIGFjY2Vzc2VkLjwvcGFyYW0+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwicmVxQnVmXCI+ZGF0YSB0byBiZSBzZW50IHRvIHRoZSB1cmw8L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInNlc3Npb25TdGFnZVwiPkhBTkRTSEFLRSAvIElOSVRJQUwgLyBOT1JNQUwuPC9wYXJhbT5cclxuICAvLy8gPHJldHVybnM+cmVzcG9uc2U8L3JldHVybnM+XHJcbiAgcHJpdmF0ZSBhc3luYyBEaXNwYXRjaFJlcXVlc3QodXJsOiBzdHJpbmcsIHJlcUJ1Zjogc3RyaW5nLCBzZXNzaW9uU3RhZ2U6IENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZXNzaW9uU3RhZ2UsIHJlcXVlc3RTdGF0dXM6IFJlZlBhcmFtPFJlcXVlc3RTdGF0dXM+KTogUHJvbWlzZTxzdHJpbmc+IHtcclxuICAgIGxldCByZXNwb25zZTogc3RyaW5nID0gbnVsbDtcclxuICAgIGxldCBlbmNvZGVkQm9keTogc3RyaW5nID0gbnVsbDtcclxuICAgIHJlcXVlc3RTdGF0dXMudmFsdWUgPSBSZXF1ZXN0U3RhdHVzLkhhbmRsZWQ7XHJcblxyXG4gICAgaWYgKHVybCA9PT0gbnVsbCkge1xyXG4gICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVFeGNlcHRpb25Ub0xvZ1dpdGhNc2coXCJpbiBzZW5kTXNnVG9TcnZyKCkgdW5rbm93biBzZXJ2ZXJcIik7XHJcbiAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoc2Vzc2lvblN0YWdlICE9PSBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLkhBTkRTSEFLRSkge1xyXG4gICAgICBsZXQgdXJsU3VmZml4OiBzdHJpbmcgPSB0aGlzLkJ1aWxkVXJsU3VmZml4KHJlcUJ1ZiAhPT0gbnVsbCwgc2Vzc2lvblN0YWdlID09PSBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLklOSVRJQUwpO1xyXG4gICAgICBsZXQgcmVxQnVmRW5jb2RlZDogc3RyaW5nID0gSHR0cFV0aWxpdHkuVXJsRW5jb2RlKHJlcUJ1ZiwgRW5jb2RpbmcuVVRGOCk7XHJcbiAgICAgIGVuY29kZWRCb2R5ID0gdXJsU3VmZml4ICsgcmVxQnVmRW5jb2RlZDtcclxuICAgIH1cclxuXHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgaWYgKExvZ2dlci5JbnN0YW5jZS5TaG91bGRMb2dFeHRlbmRlZFNlcnZlclJlbGF0ZWRNZXNzYWdlcygpKVxyXG4gICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJNRVNTQUdFIFRPIFNFUlZFUjpcXG4gVVJMOiB7MH1cXG4gQk9EWTogezF9XCIsIHVybCwgZW5jb2RlZEJvZHkpKTtcclxuXHJcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5FeGVjdXRlUmVxdWVzdCh1cmwsIGVuY29kZWRCb2R5KTtcclxuXHJcbiAgICAgIC8qIHJlbW92ZSB0aGUgdW53YW50ZWQgZGF0YSBiZWZvcmUgdGhlIE1HREFUQSB0YWcgKi9cclxuICAgICAgaWYgKCFyZXNwb25zZS50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoXCI8SFRNTFwiKSkge1xyXG4gICAgICAgIGxldCBzdGFydElkeDogbnVtYmVyID0gcmVzcG9uc2UuaW5kZXhPZihcIjx4bWwgaWQ9XFxcIk1HREFUQVxcXCI+XCIpO1xyXG4gICAgICAgIGlmIChzdGFydElkeCA+IDApXHJcbiAgICAgICAgICByZXNwb25zZSA9IHJlc3BvbnNlLnN1YnN0cihzdGFydElkeCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coXCJNRVNTQUdFIEZST00gU0VSVkVSOiBcIiArIHJlc3BvbnNlKTtcclxuXHJcbiAgICAgIC8vIGhhbmRzaGFrZSByZXF1ZXN0cyBhcmUgYWx3YXlzIHNjcmFtYmxlZCAodGhlIHNjcmFtYmxpbmcgY2FuIGJlIGRpc2FibGVkIHN0YXJ0aW5nIGZyb20gdGhlIDNyZCByZXF1ZXN0KS5cclxuICAgICAgaWYgKHNlc3Npb25TdGFnZSA9PT0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5IQU5EU0hBS0UgfHxcclxuICAgICAgICAocmVzcG9uc2UubGVuZ3RoID4gMCAmJlxyXG4gICAgICAgICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuU2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXMgJiYgcmVzcG9uc2UgIT09IFwiPHhtbCBpZD1cXFwiTUdEQVRBXFxcIj5cXG48L3htbD5cIikpIHtcclxuICAgICAgICBpZiAoc2Vzc2lvblN0YWdlID09PSBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLkhBTkRTSEFLRSkge1xyXG4gICAgICAgICAgLy8gaGFuZHNoYWtlIHJlcXVlc3RzIGFyZSBhbHdheXMgc2NyYW1ibGVkLlxyXG4gICAgICAgICAgRGVidWcuQXNzZXJ0KHJlc3BvbnNlLmxlbmd0aCA+IDAgJiYgcmVzcG9uc2VbMF0gIT09ICc8Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc3BvbnNlID0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlLlVuU2NyYW1ibGUocmVzcG9uc2UpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVEZXZUb0xvZyhcIk1FU1NBR0UgRlJPTSBTRVJWRVI6IChzaXplID0gXCIgKyByZXNwb25zZS5sZW5ndGggKyBcIilcIiArIE9TRW52aXJvbm1lbnQuRW9sU2VxICsgcmVzcG9uc2UpO1xyXG5cclxuICAgICAgdGhpcy5fbGFzdFJlcXVlc3RUaW1lID0gTWlzYy5nZXRTeXN0ZW1NaWxsaXNlY29uZHMoKTtcclxuICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNlcnZlckVycm9yKSB7XHJcbiAgICAgICAgcmVxdWVzdFN0YXR1cy52YWx1ZSA9IFJlcXVlc3RTdGF0dXMuQWJvcnQ7XHJcblxyXG5cclxuICAgICAgICBpZiAoc2Vzc2lvblN0YWdlID09IENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZXNzaW9uU3RhZ2UuTk9STUFMKSB7XHJcbiAgICAgICAgICAvLyBJZiBjb250ZXh0IGlzIG5vdCBmb3VuZCBhdCBzZXJ2ZXIgZHVlIHRvIGNyYXNoIG9yIHRocmVhZCBpcyBhYm9ydGVkIGR1ZSB0byBjcmFzaCxcclxuICAgICAgICAgIC8vIGNoZWNrIFdlYkNsaWVudFJlaW5pdFNlc3Npb24uIGJhc2VkIG9uIHRoZSBmbGFnLCByZS1pbml0aWFsaXppbmcgcmVxdWVzdCBzaG91bGQgYmUgc2VudCB0byBjcmVhdGVcclxuICAgICAgICAgIC8vIGEgbmV3IGNvbnRleHQgYW5kIGl0IHNob3VsZCBiZSBleGVjdXRlZCBpbiB0aGlzIG5ldyBjb250ZXh0LlxyXG4gICAgICAgICAgLy8gc28sIHNldCB0aGUgUmVxdWVzdFN0YXR1cyB0byBSZXRyeSBzbyB0aGF0IHRoZSBjbGllbnQgd2lsbCByZXNlbmQgcmVxdWVzdC5cclxuICAgICAgICAgIGlmIChleC5HZXRDb2RlKCkgPT0gU2VydmVyRXJyb3IuRVJSX0NUWF9OT1RfRk9VTkQgfHwgZXguR2V0Q29kZSgpID09IFNlcnZlckVycm9yLkVSUl9USFJFQURfQUJPUlRFRCkge1xyXG4gICAgICAgICAgICBpZiAoUnVudGltZUNvbnRleHRCYXNlLkluc3RhbmNlLlJlbW92ZWRDb250ZXh0RnJvbVNlcnZlcikge1xyXG4gICAgICAgICAgICAgIHJlcXVlc3RTdGF0dXMudmFsdWUgPSBSZXF1ZXN0U3RhdHVzLlJldHJ5O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHN3aXRjaCAoRW52aXJvbm1lbnQuSW5zdGFuY2UuZ2V0V2ViQ2xpZW50UmVpbml0U2Vzc2lvbigpKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdZJyA6XHJcbiAgICAgICAgICAgICAgICAgIHJlcXVlc3RTdGF0dXMudmFsdWUgPSBSZXF1ZXN0U3RhdHVzLlJldHJ5O1xyXG4gICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ0EnOlxyXG4gICAgICAgICAgICAgICAgICBsZXQgcmV0dmFsID0gYXdhaXQgR1VJTWFuYWdlci5JbnN0YW5jZS5NZXNzYWdlQm94KFwiRXJyb3JcIiwgXCJVbmtub3duIGVycm9yIG9jY3VycmVkIGF0IHNlcnZlci1zaWRlLlwiICtcclxuICAgICAgICAgICAgICAgICAgICBcIiBXb3VsZCB5b3UgbGlrZSB0byByZWluaXRpYWxpemUgdGhlIHNlc3Npb24/XCIsIFN0eWxlcy5NU0dCT1hfQlVUVE9OX1lFU19OTyk7XHJcbiAgICAgICAgICAgICAgICAgIHJlcXVlc3RTdGF0dXMudmFsdWUgPSAocmV0dmFsID09IFN0eWxlcy5NU0dCT1hfUkVTVUxUX1lFUykgPyBSZXF1ZXN0U3RhdHVzLlJldHJ5IDogUmVxdWVzdFN0YXR1cy5BYm9ydDtcclxuICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdOJzpcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgIHJlcXVlc3RTdGF0dXMudmFsdWUgPSBSZXF1ZXN0U3RhdHVzLkFib3J0O1xyXG4gICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RTdGF0dXMudmFsdWUgPT0gUmVxdWVzdFN0YXR1cy5BYm9ydCkge1xyXG4gICAgICAgICAgICAgIEVudmlyb25tZW50Lkluc3RhbmNlLnNldFdlYkNsaWVudFJlaW5pdFNlc3Npb24oJ04nKTtcclxuICAgICAgICAgICAgICB0aHJvdyAgZXg7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgbGV0IGVyckZvckNvbnNvbGUgPSBTdHJVdGlsLmdldENvbnNvbGVFcm9yU3RyaW5nKGV4LkdldE1lc3NhZ2UoKSk7XHJcbiAgICAgICAgICAgICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IubGFzdEV4Y2VwdGlvbk1lc3NhZ2UgPSBcIkV4Y2VwdGlvbiBPY2N1cmVkIGF0IHNlcnZlciBzaWRlIDogXCIgKyBleC5HZXRDb2RlKCkudG9TdHJpbmcoKSArIFwiIDogXCIgKyBlcnJGb3JDb25zb2xlO1xyXG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLmxhc3RFeGNlcHRpb25NZXNzYWdlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jbGVhckxvY2FsU3RvcmFnZSgpO1xyXG4gICAgICB0aHJvdyBleDtcclxuICAgIH1cclxuICAgIHJldHVybiByZXNwb25zZTtcclxuICB9XHJcblxyXG4gIC8vIDxzdW1tYXJ5PiBJZiBhbnkgaXRlbXMgYXJlIHN0b3JlZCBvbiBsb2NhbCBzdG9yYWdlIGNsZWFyIGl0IG5vdyBhcyBzZXNzaW9uIGNhbm5vdCBjb250aW51ZWQuXHJcbiAgLy8gQ2xlYXJpbmcgb25seSB0aGUgbG9jYWwgc3RvcmFnZSBpdGVtcyB3aGljaCBhcmUgc3RvcmVkIGJ5IG1hZ2ljIGxpYnJhcnkuXHJcbiAgY2xlYXJMb2NhbFN0b3JhZ2UoKXtcclxuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5MQVNUX1JPVVRFX0VWRU5UKTtcclxuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5MQVNUX1JPVVRFX0VWRU5UX1NSQ19UU0spO1xyXG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLkxBU1RfUk9VVEVfRVZFTlRfQVJHX0xJU1QpO1xyXG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLklTX1NFU1NJT05fUkVJTklUSUFMSVpJTkcpO1xyXG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLk1BSU5fUFJPR19WSUVXKTtcclxuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5HTE9CQUxfUEFSQU1fTElTVCk7XHJcbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuRU5WX1ZBUl9MSVNUKTtcclxuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5MQVNUX0VYQ0VQVElPTik7XHJcbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuQ1RYX1JFTU9WRURfRlJPTV9TUlZSKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT4gQ2hlY2tzIHRoZSByZXNwb25zZSBzdHJpbmcsIHRocm93cyBhbiBlcnJvciBpZiB0aGUgcmVzcG9uc2Ugc3RyaW5nIGNvbnRhaW5zXHJcbiAgLy8vIGFuIHhtbC9odG1sIGVycm9yPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInJlc3BvbnNlXCI+PC9wYXJhbT5cclxuICBwcml2YXRlIEhhbmRsZUVycm9yUmVzcG9uc2UocmVzcG9uc2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdHJ5IHtcclxuICAgICAgLy8gZXJyb3IgcmVzcG9uc2VzIGFyZSBhbHdheXMgc2NyYW1ibGVkIGJ5IHRoZSB3ZWIgc2VydmVyLlxyXG4gICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKFwiTUVTU0FHRSBGUk9NIFNFUlZFUjogXCIgKyByZXNwb25zZSk7XHJcbiAgICAgIHJlc3BvbnNlID0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlLlVuU2NyYW1ibGUocmVzcG9uc2UpO1xyXG4gICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKFwiTUVTU0FHRSBGUk9NIFNFUlZFUjogXCIgKyBTdHJVdGlsLmdldENvbnNvbGVFcm9yU3RyaW5nKHJlc3BvbnNlKSk7XHJcbiAgICB9IGNhdGNoIChleCkge1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChyZXNwb25zZS5zdGFydHNXaXRoKFwiPHhtbGVyclwiKSkge1xyXG4gICAgICBsZXQgZXJyb3JNZXNzYWdlWG1sOiBFcnJvck1lc3NhZ2VYbWwgPSBuZXcgRXJyb3JNZXNzYWdlWG1sKHJlc3BvbnNlLCB0aGlzLl9sYXN0UmVxdWVzdFRpbWUsIEFjY2Vzc0hlbHBlci5lbnZpcm9ubWVudC5nZXRDb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQoKSk7XHJcbiAgICAgIHRocm93IG5ldyBTZXJ2ZXJFcnJvcihlcnJvck1lc3NhZ2VYbWwuR2V0TWVzc2FnZSgpLCBlcnJvck1lc3NhZ2VYbWwuR2V0Q29kZSgpKTtcclxuICAgIH0gZWxzZSBpZiAocmVzcG9uc2UudG9VcHBlckNhc2UoKS5zdGFydHNXaXRoKFwiPEhUTUxcIikpIHtcclxuICAgICAgdGhyb3cgbmV3IFNlcnZlckVycm9yKHJlc3BvbnNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5zZW5kICdlbmNvZGVkQm9keScgdG8gJ3VybCcgYW5kIHJlY2VpdmUgYSByZXNwb25zZS5cclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInVybFwiPlVSTCB0byBiZSBhY2Nlc3NlZC48L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cImVuY29kZWRCb2R5XCI+SW4gY2FzZSBvZiBQT1NULCBjb250ZW50IHRvIGJlIHNlbnQgdG8gc2VydmVyLiBGb3Igb3RoZXIgbWV0aG9kcywgbnVsbC48L3BhcmFtPlxyXG4gIC8vLyA8cmV0dXJucz50aGUgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyPC9yZXR1cm5zPlxyXG4gIHByaXZhdGUgYXN5bmMgRXhlY3V0ZVJlcXVlc3QodXJsOiBzdHJpbmcsIGVuY29kZWRCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuR2V0Q29udGVudCh1cmwsIGZhbHNlLCBlbmNvZGVkQm9keSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBHZXRDb250ZW50KHJlcXVlc3RlZFVSTDogc3RyaW5nLCB1c2VDYWNoZTogYm9vbGVhbiwgcmVxdWVzdENvbnRlbnQ/OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgaWYgKGlzVW5kZWZpbmVkKHJlcXVlc3RDb250ZW50KSlcclxuICAgICAgcmVxdWVzdENvbnRlbnQgPSBudWxsO1xyXG5cclxuICAgIGxldCByZXNwb25zZVN0cjogc3RyaW5nO1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIGlmIHJlbGF0aXZlLCBwcmVmaXggd2l0aCB0aGUgJ3Byb3RvY29sOi8vc2VydmVyLycgZnJvbSB3aGljaCB0aGUgcmljaC1jbGllbnQgd2FzIGFjdGl2YXRlZFxyXG4gICAgICBpZiAocmVxdWVzdGVkVVJMLnN0YXJ0c1dpdGgoXCIvXCIpKVxyXG4gICAgICAgIHJlcXVlc3RlZFVSTCA9IFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRQcm90b2NvbCgpICsgXCI6Ly9cIiArIFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRTZXJ2ZXIoKSArIHJlcXVlc3RlZFVSTDtcclxuXHJcbiAgICAgIHZhciBzcGlubmVyVGltZXIgPSB0aW1lcig1MCwgNTApO1xyXG4gICAgICB2YXIgc3Bpbm5lclRpbWVyU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gPSBzcGlubmVyVGltZXIuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICBBY2Nlc3NIZWxwZXIuZXZlbnRzTWFuYWdlci5DaGVja0FuZFNob3dTcGlubmVyKHRydWUpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGxldCBpc0Vycm9yOiBSZWZQYXJhbTxib29sZWFuPiA9IG5ldyBSZWZQYXJhbShmYWxzZSk7XHJcblxyXG4gICAgICByZXNwb25zZVN0ciA9IGF3YWl0IEh0dHBNYW5hZ2VyLkdldEluc3RhbmNlKCkuR2V0Q29udGVudChyZXF1ZXN0ZWRVUkwsIHJlcXVlc3RDb250ZW50LCB1c2VDYWNoZSwgaXNFcnJvcik7XHJcblxyXG4gICAgICBzcGlubmVyVGltZXJTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgc3Bpbm5lclRpbWVyU3Vic2NyaXB0aW9uID0gbnVsbDtcclxuXHJcbiAgICAgIGlmIChpc0Vycm9yLnZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5IYW5kbGVFcnJvclJlc3BvbnNlKHJlc3BvbnNlU3RyKTtcclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXgpIHtcclxuICAgICAgLy8gZG9uJ3Qgd3JpdGUgc2VydmVyIGVycm9yIHRvIGxvZyB3aGVuIHRoZSBsb2cgbGV2ZWwgaXMgYmFzaWNcclxuICAgICAgaWYgKCEoZXggaW5zdGFuY2VvZiBTZXJ2ZXJFcnJvcikgfHwgTG9nZ2VyLkluc3RhbmNlLkxvZ0xldmVsICE9PSBMb2dnZXJfTG9nTGV2ZWxzLkJhc2ljKSB7XHJcbiAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRXhjZXB0aW9uVG9Mb2coZXgsIE5TdHJpbmcuRm9ybWF0KFwicmVxdWVzdGVkIFVSTCA9IFxcXCJ7MH1cXFwiXCIsIHJlcXVlc3RlZFVSTCkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyB0aGUgZXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gYW5kIHRoZSBjYWxsZXJzIHNob3VsZCBoYW5kbGUgaXQuXHJcbiAgICAgIGlmICghKGV4IGluc3RhbmNlb2YgU2VydmVyRXJyb3IpKSB7XHJcbiAgICAgICAgZXggPSBuZXcgU2VydmVyRXJyb3IoZXguTWVzc2FnZSwgZXguSW5uZXJFeGNlcHRpb24gPyBleC5Jbm5lckV4Y2VwdGlvbiA6IGV4KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhyb3cgZXg7XHJcbiAgICB9IGZpbmFsbHkge1xyXG4gICAgICBpZiAoc3Bpbm5lclRpbWVyU3Vic2NyaXB0aW9uICE9IG51bGwpXHJcbiAgICAgICAgc3Bpbm5lclRpbWVyU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3BvbnNlU3RyO1xyXG4gIH1cclxuXHJcblxyXG4gIENsaWVudEFjdGl2YXRlZCgpIHtcclxuXHJcbiAgICAvLyBsb2cgdGhlIHZhbHVlcyBhcyBjbGllbnQgaXMgYWN0aXZlIGFnYWluXHJcbiAgICAvLyBUT0RPIC0gZm9ybWF0dGluZ1xyXG4gICAgLy8gY29uc29sZS5sb2coJ0xvZ2dpbmcgU3VtbWFyeSAnICsgJ1xcbicgK1xyXG4gICAgLy8gICAnVG90YWwgbnVtYmVyIHJlcXVlc3RzIDogJyArIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLnJlcXVlc3ROdW1iZXIgKyAnXFxuJyArXHJcbiAgICAvLyAgICdUb3RhbCB0aW1lIG5lZWRlZCBmb3IgaHR0cCByZXF1ZXN0cyA6ICcgKyBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50b3RhbFRpbWVGb3JIVFRQUmVxdWVzdHMgKyAnIG1zICcgKyAnXFxuJyArXHJcbiAgICAvLyAgICdUb3RhbCB0aW1lIG5lZWRlZCBmb3IgY2xpZW50IHRvIGdldCBhY3RpdmUgOiAnICsgZXhlY3V0aW9uVGltZSArICcgbXMgJyArICdcXG4nXHJcbiAgICAvLyApO1xyXG4gICAgLy9cclxuICAgIC8vIC8vIFRPRE8gLSBtb3ZlIGl0IHRvIG1ldGhvZFxyXG4gICAgLy8gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IucmVxdWVzdE51bWJlciA9IDA7XHJcbiAgICAvLyBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50b3RhbFRpbWVGb3JIVFRQUmVxdWVzdHMgPSAwO1xyXG4gICAgLy8gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IudG90YWxSZXF1ZXN0RGF0YUxlbmd0aCA9IDA7XHJcbiAgICAvLyBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50b3RhbFJlc3BvbnNlRGF0YUxlbmd0aCA9IDA7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+IFdoZW4gTG9nQ2xpZW50U2VxdWVuY2VGb3JBY3Rpdml0eU1vbml0b3IgPSBZIHdlIHdpbGwgYmUga2VlcGluZyB0aGUgbG9ncyBpbiBmaWxlIGFuZCBzZW5kIHRoZSBmaWxlIHdpdGggbmV4dFxyXG4gIC8vLyBzZXJ2ZXIgYWNjZXNzLiBJZiBjbGllbnQgaXMgYWJub3JtYWxseSB0ZXJtaW5hdGVkIHRoZW4gdGhlcmUgY2FuIGJlIDEgb3IgbW9yZSBmaWxlcyBjb250YWluaW5nIGxvZ3Mgc2luY2VcclxuICAvLy8gbGFzdCBzZXJ2ZXIgYWNjZXNzLk5vdyB0aGVzZSBsb2dzIHdpbGwgYmUgc2VudCB0byBzZXJ2ZXIsIHdoZW4gbmV4dCB0aW1lIFJDIHByb2dyYW0gaXMgZXhlY3V0ZWQsLjwvc3VtbWFyeT5cclxuICAvLy8gPHJldHVybnM+IElmIHNlbmRpbmcgd2FzIHN1Y2Nlc3NmdWw8L3JldHVybnM+XHJcbiAgLy8gICBUT0RPOiBIYW5kbGUgcGVuZGluZyBsb2dzLlxyXG4gIC8vIHByaXZhdGUgU2VuZFBlbmRpbmdMb2dzVG9TZXJ2ZXIoKTogYm9vbGVhbiB7XHJcbiAgLy8gICBsZXQgc3VjY2VzczogYm9vbGVhbiA9IHRydWU7XHJcbiAgLy9cclxuICAvLyAgIFRoZSBwZW5kaW5nIGxvZ3MgY2Fubm90IGJlIHJlYWQgZnJvbSB0aGUgZmlsZSBzeXN0ZW0gc2luY2UgV2ViQ2xpZW50IGRvZXNuJ3QgaGF2ZSBhY2Nlc3MgdG8gdGhhdC5cclxuICAvLyAgIE1heWJlLCB0aGUgbG9ncyBzaG91bGQgYmUgd3JpdHRlbiBpbnRvIExvY2FsU3RvcmFnZSBhZCByZWFkIGZyb20gdGhlcmUuXHJcbiAgLy9cclxuICAvLyAgIGxldCBzdHJpbmdCdWlsZGVyOiBTdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoMTAwMCk7XHJcbiAgLy8gICBsZXQgZmxvd01vbml0b3I6IEZsb3dNb25pdG9yUXVldWUgPSBGbG93TW9uaXRvclF1ZXVlLkluc3RhbmNlO1xyXG4gIC8vXHJcbiAgLy8gICAvLyBHZXQgaXRlcmF0b3IgdG8gbmFtZXMgb2YgbG9nIGZpbGVzLlxyXG4gIC8vICAgbGV0IGVudW1lcmF0b3I6IElFbnVtZXJhdG9yPHN0cmluZz4gPSBDbGllbnRMb2dBY2N1bXVsYXRvci5FeGlzdGluZ0xvZ0l0ZXJhdG9yKCk7XHJcbiAgLy9cclxuICAvLyAgIC8vIHdoaWxlIHRoZXJlIGFyZSBtb3JlIGZpbGVzXHJcbiAgLy8gICB3aGlsZSAoZW51bWVyYXRvci5Nb3ZlTmV4dCgpKSB7XHJcbiAgLy8gICAgIC8vIFRha2UgbmV4dCBmaWxlIG5hbWVcclxuICAvLyAgICAgbGV0IGxvZ05hbWU6IHN0cmluZyA9IGVudW1lcmF0b3IuQ3VycmVudDtcclxuICAvLyAgICAgLy8gUHJlcGFyZSB0aGUgaGVhZGVyIGxpbmUgKENsaWVudCBsb2cgZmlsZSA6IDxDb250ZXh0IDogWFhYWFhYPikgYW5kIGFkZCBpdCB0b1xyXG4gIC8vICAgICAvLyBmbG93IG1vbml0b3IgYnVpbGQgbW9uaXRvciBtZXNzYWdlXHJcbiAgLy8gICAgIGxldCBoZWFkZXJMaW5lOiBzdHJpbmcgPSBDbGllbnRMb2dBY2N1bXVsYXRvci5CdWlsZExvZ0hlYWRlckxpbmUobG9nTmFtZSk7XHJcbiAgLy8gICAgIGZsb3dNb25pdG9yLmFkZEZsb3dWZXJpZnlJbmZvKGhlYWRlckxpbmUpO1xyXG4gIC8vICAgICBsZXQgbG9nQ3R4QnVmOiBTdHJpbmdCdWlsZGVyID0gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuQnVpbGRNb25pdG9yTWVzc2FnZSgpO1xyXG4gIC8vXHJcbiAgLy8gICAgIGxldCBmaWxlQ29udGVudHM6IHN0cmluZyA9IEhhbmRsZUZpbGVzLnJlYWRUb1N0cmluZyhsb2dOYW1lKTtcclxuICAvLyAgICAgbG9nQ3R4QnVmLkFwcGVuZChmaWxlQ29udGVudHMpO1xyXG4gIC8vICAgICBzdHJpbmdCdWlsZGVyLkFwcGVuZChsb2dDdHhCdWYuVG9TdHJpbmcoKSk7XHJcbiAgLy8gICB9XHJcbiAgLy9cclxuICAvLyAgIGxldCByZXNwQnVmOiBzdHJpbmcgPSBudWxsO1xyXG4gIC8vXHJcbiAgLy8gICB0cnkge1xyXG4gIC8vICAgICByZXNwQnVmID0gdGhpcy5EaXNwYXRjaFJlcXVlc3QodGhpcy5TZXJ2ZXJVcmwsIHN0cmluZ0J1aWxkZXIuVG9TdHJpbmcoKSwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5OT1JNQUwpO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgY2F0Y2ggKGV4KSB7XHJcbiAgLy8gICAgIC8vIGRvIG5vdGhpbmcuIGlmIHNlbmRpbmcgbG9nIGZhaWxzLCB0aGVyZSBpcyBubyBoYXJtLlxyXG4gIC8vICAgfVxyXG4gIC8vXHJcbiAgLy8gICBpZiAocmVzcEJ1ZiA9PT0gbnVsbCkge1xyXG4gIC8vICAgICBzdWNjZXNzID0gZmFsc2U7XHJcbiAgLy8gICB9XHJcbiAgLy9cclxuICAvLyAgIHJldHVybiBzdWNjZXNzO1xyXG4gIC8vIH1cclxuXHJcbiAgLy8gVE9ETzogSGFuZGxlIHBlbmRpbmcgbG9ncy5cclxuICAvLyBwcml2YXRlIHN0YXRpYyBEZWxldGVQZW5kaW5nTG9ncygpOiB2b2lkIHtcclxuICAvLyAgIGxldCBlbnVtZXJhdG9yOiBJRW51bWVyYXRvciA9IENsaWVudExvZ0FjY3VtdWxhdG9yLkV4aXN0aW5nTG9nSXRlcmF0b3IoKTtcclxuICAvLyAgIHdoaWxlIChlbnVtZXJhdG9yLk1vdmVOZXh0KCkpIHtcclxuICAvLyAgICAgbGV0IGZpbGVuYW1lOiBzdHJpbmcgPSA8c3RyaW5nPmVudW1lcmF0b3IuQ3VycmVudDtcclxuICAvLyAgICAgSGFuZGxlRmlsZXMuZGVsZXRlRmlsZShmaWxlbmFtZSk7XHJcbiAgLy8gICB9XHJcbiAgLy8gfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+IGdldCB0aGUgc3VmZml4IG9mIHRoZSBVUkwgdG8gYmUgc2VudCB0byB0aGUgc2VydmVyLiBUaGlzIGluY2x1ZGVzIHRoZSBDVFgsIFNFU1NJT04gYW5kIERBVEEgcGFyYW1ldGVycy48L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiaGFzQ29udGVudFwiPmlmIHRydWUsIHRoZSBIVFRQIERBVEEgcGFyYW1ldGVyIGNvbnRhaW5zIHNvbWV0aGluZy48L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cImlzSW5pdGlhbENhbGxcIj5pZiB0cnVlIHRoZW4gdGhlIGdlbmVyYXRlZCBzdWZmaXggaGFzIG5vIHNwZWNpZmljIGNvbnRleHQgZGF0YTwvcGFyYW0+XHJcbiAgLy8vIDxyZXR1cm5zPiB0aGUgVVJMIHN1ZmZpeCAoaS5lLiBcIkNUWD0uLi4mU0VTU0lPTj0uLi4mREFUQT1cIjwvcmV0dXJucz5cclxuICBwcml2YXRlIEJ1aWxkVXJsU3VmZml4KGhhc0NvbnRlbnQ6IGJvb2xlYW4sIGlzSW5pdGlhbENhbGw6IGJvb2xlYW4pOiBzdHJpbmcge1xyXG4gICAgbGV0IHByZWZpeDogc3RyaW5nID0gQ29uc3RJbnRlcmZhY2UuUkNfSU5ESUNBVElPTiArIENvbnN0SW50ZXJmYWNlLlJDX1RPS0VOX0NUWF9JRCArIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5Db250ZXh0SUQ7XHJcblxyXG4gICAgLy8gQXBwZW5kIHNlc3Npb24gaWQgaW4gdXJsIG9ubHkgd2hlbiBpdCBpcyBub3QgbnVsbCBvciBlbXB0eVxyXG4gICAgLy8gTk9URTogc2Vzc2lvbiBpZCB3aWxsIGJlIHNlbmQgYnkgc2VydmVyIG9ubHkgZm9yIEdTIGFzIG1pZGRsZXdhcmVcclxuICAgIC8vICAgICAgIGFuZCB3aGVuIHNlcGVjaWFsIGZsYWcgKFNwZWNpYWxSSUFHZW5lcmF0ZUFuZFZhbGlkYXRlU2Vzc2lvbklEKSBpcyBvblxyXG4gICAgLy8gICAgICAgc28gc2Vzc2lvbiBpZCB3aWxsIGJlIG51bGwgZm9yIGJyb2tlciBtaWRkbGV3YXJlIGFuZCB3aGVuIHNwZWNpYWwgZmxhZyBpcyBPRkYuXHJcbiAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKHRoaXMuU2Vzc2lvbklkKSlcclxuICAgICAgcHJlZml4ICs9IChDb25zdEludGVyZmFjZS5SRVFfQVJHX1NFUEFSQVRPUiArIENvbnN0SW50ZXJmYWNlLlJDX1RPS0VOX1NFU1NJT05fSUQgKyB0aGlzLlNlc3Npb25JZCk7XHJcblxyXG4gICAgaWYgKGlzSW5pdGlhbENhbGwpIHtcclxuICAgICAgLy8gVE9ETzogSG93IHRvIGdldCBlbnZpcm9ubWVudCB2YXJpYWJsZXM/XHJcbiAgICAgIC8vIGxldCBlbnZWYXJzOiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldEVudlZhcnMoKTtcclxuICAgICAgLy8gaWYgKCFOU3RyaW5nLklzTnVsbE9yRW1wdHkoZW52VmFycykpIHtcclxuICAgICAgLy8gICAvLyBlbnZpcm9ubWVudCB2YXJpYWJsZXM6IEVOVjEsRU5WMiwuLiAtLT4gJkVOVjE9dmFsMSZFTlYyPXZhbDIuLi5cclxuICAgICAgLy8gICBsZXQgZW52VmFyc1ZlYzogc3RyaW5nW10gPSBlbnZWYXJzLnNwbGl0KFwiLFwiKTtcclxuICAgICAgLy8gICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgZW52VmFyc1ZlYy5sZW5ndGg7IGkgPSBpICsgMSkge1xyXG4gICAgICAvLyAgICAgcHJlZml4ICs9IChcIiZcIiArIGVudlZhcnNWZWNbaV0gKyBcIj1cIiArIE9TRW52aXJvbm1lbnQuZ2V0KGVudlZhcnNWZWNbaV0pKTtcclxuICAgICAgLy8gICB9XHJcbiAgICAgIC8vIH1cclxuICAgICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nKVxyXG4gICAgICAgIHByZWZpeCArPSAoQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgKyBDb25zdEludGVyZmFjZS5XRUJDTElFTlRfUkVJTklUSUFMSVpFX1JFUVVFU1QpO1xyXG5cclxuICAgICAgbGV0IGdsb2JhbFBhcmFtczogc3RyaW5nID0gU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldEdsb2JhbFBhcmFtcygpO1xyXG4gICAgICBpZiAoZ2xvYmFsUGFyYW1zICE9PSBudWxsKSB7XHJcbiAgICAgICAgZ2xvYmFsUGFyYW1zID0gTlN0cmluZy5SZXBsYWNlKGdsb2JhbFBhcmFtcywgXCIrXCIsIFwiJTJCXCIpO1xyXG4gICAgICAgIHByZWZpeCArPSAoXCImXCIgKyBDb25zdEludGVyZmFjZS5NR19UQUdfR0xPQkFMUEFSQU1TICsgXCI9XCIgKyBnbG9iYWxQYXJhbXMpO1xyXG4gICAgICB9XHJcbiAgICB9IC8vIGlzSW5pdGlhbENhbGxcclxuXHJcbiAgICBpZiAoaGFzQ29udGVudCkge1xyXG4gICAgICBwcmVmaXggKz0gKFwiJlwiICsgQ29uc3RJbnRlcmZhY2UuUkNfVE9LRU5fU0VTU0lPTl9DT1VOVCArIHRoaXMuR2V0U2Vzc2lvbkNvdW50ZXIoKSArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgKyBDb25zdEludGVyZmFjZS5SQ19UT0tFTl9EQVRBKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcHJlZml4O1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PnNlbmQgTW9uaXRvciBtZXNzYWdpbmcgdG8gdGhlIHNlcnZlcjwvc3VtbWFyeT5cclxuICBwdWJsaWMgYXN5bmMgU2VuZE1vbml0b3JPbmx5KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgbGV0IGZsb3dNb25pdG9yOiBGbG93TW9uaXRvclF1ZXVlID0gRmxvd01vbml0b3JRdWV1ZS5JbnN0YW5jZTtcclxuXHJcbiAgICBpZiAoQWNjZXNzSGVscGVyLm1nRGF0YVRhYmxlID09IG51bGwgfHwgQWNjZXNzSGVscGVyLm1nRGF0YVRhYmxlLmdldE1HRGF0YSgwKSA9PSBudWxsIHx8IEFjY2Vzc0hlbHBlci5tZ0RhdGFUYWJsZS5nZXRNR0RhdGEoMCkuSXNBYm9ydGluZylcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGlmICghZmxvd01vbml0b3IuaXNFbXB0eSgpKSB7XHJcbiAgICAgIC8vIGJ1aWxkIG91dCBtZXNzYWdlXHJcbiAgICAgIGxldCBidWZmZXI6IFN0cmluZ0J1aWxkZXIgPSB0aGlzLkJ1aWxkTW9uaXRvck1lc3NhZ2UoKTtcclxuXHJcbiAgICAgIC8vIElmIGNsaWVudCBzZXF1ZW5jZSBpcyB0byBiZSBhY2N1bXVsYXRlZCB1bnRpbCBuZXh0IHNlcnZlciBhY2Nlc3MuXHJcbiAgICAgIGxldCBzaG91bGRBY2N1bXVsYXRlQ2xpZW50TG9nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAgIC8vIHNob3VsZEFjY3VtdWxhdGVDbGllbnRMb2cgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ0NsaWVudFNlcXVlbmNlRm9yQWN0aXZpdHlNb25pdG9yKCk7XHJcbiAgICAgIC8vIGlmIChzaG91bGRBY2N1bXVsYXRlQ2xpZW50TG9nKSB7XHJcbiAgICAgIC8vICAgaWYgKHRoaXMuX2xvZ0FjY3VtdWxhdG9yID09IG51bGwpXHJcbiAgICAgIC8vICAgICB0aGlzLl9sb2dBY2N1bXVsYXRvciA9IG5ldyBDbGllbnRMb2dBY2N1bXVsYXRvcihDbGllbnRNYW5hZ2VyUnVudGltZS5JbnN0YW5jZS5SdW50aW1lQ3R4LkNvbnRleHRJRCk7XHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICAgLy8gSWYgd2UncmUgdW5hYmxlIHRvIG9wZW4gdGhlIGZpbGUsIGRlYWN0aXZhdGUgbG9nZ2luZyBhY2N1bXVsYXRpb24sXHJcbiAgICAgIC8vICAgLy8gICAgYW5kIGxldCB0aGUgbWVzc2FnZSBiZSBzZW50IHRvIHRoZSBzZXJ2ZXIgYXMgZG9uZSB3aXRob3V0IGFjY3VtdWxhdGVkIGxvZ2dpbmdcclxuICAgICAgLy8gICBpZiAodGhpcy5fbG9nQWNjdW11bGF0b3IuSXNGYWlsZWQoKSlcclxuICAgICAgLy8gICAgIHNob3VsZEFjY3VtdWxhdGVDbGllbnRMb2cgPSBmYWxzZTtcclxuICAgICAgLy8gfVxyXG5cclxuICAgICAgaWYgKHNob3VsZEFjY3VtdWxhdGVDbGllbnRMb2cpIHtcclxuICAgICAgICAvLyBXcml0ZSBtZXNzYWdlIHRvIGZpbGUuXHJcbiAgICAgICAgLy8gdGhpcy5fbG9nQWNjdW11bGF0b3IuV3JpdGUoYnVmZmVyLlRvU3RyaW5nKCkpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBsZXQgcmVxdWVzdFN0YXR1czogUmVmUGFyYW08UmVxdWVzdFN0YXR1cz4gPSBuZXcgUmVmUGFyYW0oUmVxdWVzdFN0YXR1cy5IYW5kbGVkKTtcclxuICAgICAgICAgIGF3YWl0IHRoaXMuRGlzcGF0Y2hSZXF1ZXN0KHRoaXMuU2VydmVyVXJsLCBidWZmZXIuVG9TdHJpbmcoKSwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5OT1JNQUwsIHJlcXVlc3RTdGF0dXMpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgLy8gZG8gbm90aGluZy4gaWYgc2VuZGluZyBsb2cgZmFpbHMsIHRoZXJlIGlzIG5vIGhhcm0uXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+YnVpbGQgRmxvdyBNb25pdG9yIG1lc3NhZ2U8L3N1bW1hcnk+XHJcbiAgcHJpdmF0ZSBCdWlsZE1vbml0b3JNZXNzYWdlKCk6IFN0cmluZ0J1aWxkZXIge1xyXG4gICAgbGV0IGJ1ZmZlcjogU3RyaW5nQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKDEwMDApO1xyXG4gICAgbGV0IGZsb3dNb25pdG9yOiBGbG93TW9uaXRvclF1ZXVlID0gRmxvd01vbml0b3JRdWV1ZS5JbnN0YW5jZTtcclxuXHJcbiAgICBpZiAoIVJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLlNob3VsZFNjcmFtYmxlQW5kVW5zY3JhbWJsZU1lc3NhZ2VzKSB7XHJcbiAgICAgIGJ1ZmZlci5BcHBlbmQoWE1MQ29uc3RhbnRzLk1HX1RBR19PUEVOKTtcclxuICAgICAgZmxvd01vbml0b3IuYnVpbGRYTUwoYnVmZmVyKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGZsb3dNb25pdG9yLmJ1aWxkWE1MKGJ1ZmZlcik7XHJcbiAgICAgIGxldCBzY3JhbWJsZWRPdXQ6IHN0cmluZyA9IFNjcmFtYmxlci5TY3JhbWJsZShidWZmZXIuVG9TdHJpbmcoKSk7XHJcbiAgICAgIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKDEwMDApO1xyXG4gICAgICBidWZmZXIuQXBwZW5kKFhNTENvbnN0YW50cy5NR19UQUdfT1BFTiArIHNjcmFtYmxlZE91dCk7XHJcbiAgICB9XHJcbiAgICBidWZmZXIuQXBwZW5kKFwiPC9cIiArIFhNTENvbnN0YW50cy5NR19UQUdfWE1MICsgWE1MQ29uc3RhbnRzLlRBR19DTE9TRSk7XHJcblxyXG4gICAgcmV0dXJuIGJ1ZmZlcjtcclxuICB9XHJcblxyXG4gIFJlZ2lzdGVyRGVsZWdhdGVzKCk6IHZvaWQge1xyXG4gICAgSHR0cENsaWVudEV2ZW50cy5HZXRTZXNzaW9uQ291bnRlcl9FdmVudCA9IHRoaXMuR2V0U2Vzc2lvbkNvdW50ZXIuYmluZCh0aGlzKTtcclxuICAgIEh0dHBDbGllbnRFdmVudHMuQ2hlY2tBbmRTZXRTZXNzaW9uQ291bnRlcl9FdmVudCA9IHRoaXMuQ2hlY2tBbmRTZXRTZXNzaW9uQ291bnRlci5iaW5kKHRoaXMpO1xyXG4gICAgSHR0cENsaWVudEV2ZW50cy5Db21wdXRlQW5kTG9nUmVxdWVzdEluZm9fRXZlbnQgPSB0aGlzLkNvbXB1dGVBbmRMb2dSZXF1ZXN0SW5mby5iaW5kKHRoaXMpO1xyXG4gICAgQWNjZXNzSGVscGVyLmV2ZW50c01hbmFnZXIuU3Bpbm5lclN0b3BwZWQuc3Vic2NyaWJlKGNsaWVudEJ1c3lUaW1lID0+IHRoaXMuQ2xpZW50QWN0aXZhdGVkKCkpO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBMb2cgdGhlIGN1cnJlbnQgcmVxdWVzdCBpbmZvcm1hdGlvbiBpbiBjb25zb2xlXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBDb21wdXRlQW5kTG9nUmVxdWVzdEluZm8oY29udGVudExlbmd0aDogbnVtYmVyLCByb3VuZFRyaXA6IG51bWJlciwgaXNMb2dnaW5nUmVzcG9uc2U6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQodGhpcy5fcmVxdWVzdEluZm8uc2VydmVyQ2FsbEF0KSkge1xyXG5cclxuICAgICAgdGhpcy5fcmVxdWVzdEluZm8uZXh0cmFJbmZvLmNvbnRlbnRMZW5ndGggPSBjb250ZW50TGVuZ3RoO1xyXG4gICAgICB0aGlzLl9yZXF1ZXN0SW5mby5leHRyYUluZm8udGltZVN0YW1wID0gbmV3IERhdGUoKS50b1N0cmluZygpO1xyXG4gICAgICBsZXQgZXh0cmFNZXNzYWdlU3RyOiBzdHJpbmcgPSBpc0xvZ2dpbmdSZXNwb25zZSA/ICdSZXNwb25zZSDipLUnIDogJ1JlcXVlc3Qg4qS1JztcclxuXHJcbiAgICAgIGlmIChpc0xvZ2dpbmdSZXNwb25zZSkge1xyXG4gICAgICAgIHRoaXMuX3JlcXVlc3RJbmZvLnJvdW5kdHJpcFRpbWUgPSByb3VuZFRyaXA7XHJcbiAgICAgIH1cclxuXHJcblxyXG4gICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVSZXF1ZXN0SW5mb1RvTG9nKHRoaXMuX3JlcXVlc3RJbmZvLCBleHRyYU1lc3NhZ2VTdHIpO1xyXG5cclxuICAgICAgLy8gQ2xlYXIgdGhlIGNsaWVudCBzZXNzaW9uIGFmdGVyIGxvZ2dpbmcgdGhlIHJlc3BvbnNlXHJcbiAgICAgIGlmIChpc0xvZ2dpbmdSZXNwb25zZSlcclxuICAgICAgICB0aGlzLl9yZXF1ZXN0SW5mby5jbGVhcigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBXaGVuIHRydWUsIHJlcXVlc3RzIGFyZSBzY3JhbWJsZWQgYW5kIHJlc3BvbnNlcyBhcmUgdW5zY3JhbWJsZWQuXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBzdGF0aWMgc2V0IFNob3VsZFNjcmFtYmxlQW5kVW5zY3JhbWJsZU1lc3NhZ2VzKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5fc2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXMgPSB2YWx1ZTtcclxuICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJTaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcy5TZXQ6IHswfVwiLCB0aGlzLl9zaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcykpO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIGdldCBTaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcygpOiBib29sZWFuIHtcclxuICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJTaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcy5HZXQ6IHswfVwiLCB0aGlzLl9zaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcykpO1xyXG4gICAgcmV0dXJuIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLl9zaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcztcclxuICB9XHJcblxyXG5cclxuICAvLy8gPHN1bW1hcnk+cGFyc2UgdGhlIGxvZyBsZXZlbCBmcm9tIGEgc3RyaW5nIHZhbHVlPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInN0ckxvZ0xldmVsXCI+c3RyaW5nIHZhbHVlIG9mIHRoZSBsb2cgbGV2ZWw8L3BhcmFtPlxyXG4gIC8vLyA8cmV0dXJucz5sb2cgbGV2ZWw8L3JldHVybnM+XHJcbiAgcGFyc2VMb2dMZXZlbChzdHJMb2dMZXZlbDogc3RyaW5nKTogTG9nZ2VyX0xvZ0xldmVscyB7XHJcbiAgICBsZXQgbG9nTGV2ZWw6IExvZ2dlcl9Mb2dMZXZlbHMgPSBMb2dnZXJfTG9nTGV2ZWxzLk5vbmU7XHJcblxyXG4gICAgaWYgKCFOU3RyaW5nLklzTnVsbE9yRW1wdHkoc3RyTG9nTGV2ZWwpKSB7XHJcbiAgICAgIGlmIChzdHJMb2dMZXZlbC50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoXCJTRVJWRVJcIikpXHJcbiAgICAgICAgbG9nTGV2ZWwgPSBzdHJMb2dMZXZlbC5lbmRzV2l0aChcIiNcIikgPyBMb2dnZXJfTG9nTGV2ZWxzLlNlcnZlck1lc3NhZ2VzIDogTG9nZ2VyX0xvZ0xldmVscy5TZXJ2ZXI7IC8vIG9ubHkgcmVxdWVzdHMgdG8gdGhlIHNlcnZlclxyXG4gICAgICBlbHNlIGlmIChzdHJMb2dMZXZlbC50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoXCJTXCIpIHx8IHN0ckxvZ0xldmVsLnRvVXBwZXJDYXNlKCkuc3RhcnRzV2l0aChcIlFcIikpXHJcbiAgICAgICAgbG9nTGV2ZWwgPSBMb2dnZXJfTG9nTGV2ZWxzLlN1cHBvcnQ7XHJcbiAgICAgIGVsc2UgaWYgKHN0ckxvZ0xldmVsLnRvVXBwZXJDYXNlKCkuc3RhcnRzV2l0aChcIkdcIikpXHJcbiAgICAgICAgbG9nTGV2ZWwgPSBMb2dnZXJfTG9nTGV2ZWxzLkd1aTtcclxuICAgICAgZWxzZSBpZiAoc3RyTG9nTGV2ZWwudG9VcHBlckNhc2UoKS5zdGFydHNXaXRoKFwiRFwiKSlcclxuICAgICAgICBsb2dMZXZlbCA9IExvZ2dlcl9Mb2dMZXZlbHMuRGV2ZWxvcG1lbnQ7XHJcbiAgICAgIGVsc2UgaWYgKHN0ckxvZ0xldmVsLnRvVXBwZXJDYXNlKCkuc3RhcnRzV2l0aChcIkJcIikpXHJcbiAgICAgICAgbG9nTGV2ZWwgPSBMb2dnZXJfTG9nTGV2ZWxzLkJhc2ljO1xyXG4gICAgICBlbHNlIGlmIChzdHJMb2dMZXZlbC50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoXCJSXCIpKVxyXG4gICAgICAgIGxvZ0xldmVsID0gTG9nZ2VyX0xvZ0xldmVscy5SZXF1ZXN0SW5mbztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbG9nTGV2ZWw7XHJcbiAgfVxyXG5cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PiBidWlsZCB0aGUgWE1MIHN0cmluZyBvZiB0aGUgZGF0YSB0aGF0IHNob3VsZCBiZSBzZW50IHRvIHRoZSBzZXJ2ZXI8L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwic2VyaWFsaXplVGFza3NcIj5pZiB0cnVlLCB0YXNrcyBpbiB0aGUgY3VycmVudCBleGVjdXRpb24gd2lsbCBhbHNvIGJlIHNlcmlhbGl6ZWQuPC9wYXJhbT5cclxuICBhc3luYyBQcmVwYXJlUmVxdWVzdChzZXJpYWxpemVUYXNrczogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICBsZXQgeG1sQnVmOiBTdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTtcclxuICAgIHhtbEJ1Zi5BcHBlbmQoWE1MQ29uc3RhbnRzLk1HX1RBR19PUEVOKTtcclxuXHJcbiAgICAvLyB0aGUgY2xpZW50IG5vIGxvbmdlciBzZW5kcyAoYW5kIGVtcHRpZXMpIHRoZSBldmVudCBxdWV1ZSB0byB0aGUgc2VydmVyXHJcbiAgICAvLyBzaW5jZSB0aGUgc2VydmVyIGhhcyBub3RoaW5nIHVzZWZ1bCB0byBkbyB3aXRoIHRoZSBjbGllbnQgcGVuZGluZyBldmVudHNcclxuICAgIGlmIChBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuZ2V0Q3Vyck1HRGF0YSgpICE9PSBudWxsKSB7XHJcbiAgICAgIGxldCB4bWxVbnNjcmFtYmxlZDogU3RyaW5nQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7XHJcbiAgICAgIGF3YWl0IEFjY2Vzc0hlbHBlci5tZ0RhdGFUYWJsZS5idWlsZFhNTCh4bWxVbnNjcmFtYmxlZCwgc2VyaWFsaXplVGFza3MpO1xyXG5cclxuICAgICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLlNob3VsZFNjcmFtYmxlQW5kVW5zY3JhbWJsZU1lc3NhZ2VzKVxyXG4gICAgICAgIHhtbEJ1Zi5BcHBlbmQoU2NyYW1ibGVyLlNjcmFtYmxlKHhtbFVuc2NyYW1ibGVkLlRvU3RyaW5nKCkpKTtcclxuICAgICAgZWxzZVxyXG4gICAgICAgIHhtbEJ1Zi5BcHBlbmQoeG1sVW5zY3JhbWJsZWQuVG9TdHJpbmcoKSk7XHJcbiAgICB9XHJcbiAgICB4bWxCdWYuQXBwZW5kKFwiPC9cIiArIFhNTENvbnN0YW50cy5NR19UQUdfWE1MICsgWE1MQ29uc3RhbnRzLlRBR19DTE9TRSk7XHJcblxyXG4gICAgcmV0dXJuIHhtbEJ1Zi5Ub1N0cmluZygpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8vLyA8c3VtbWFyeT5wYXJzZSBhIHJlc3BvbnNlIChmcm9tIHRoZSBTZXJ2ZXIpIGFuZCBleGVjdXRlIGNvbW1hbmRzIGlmIHJldHVybmVkIHdpdGhpbiB0aGUgcmVzcG9uc2UuPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInJlc3BvbnNlXCI+KFhNTCBmb3JtYXR0ZWQpIHJlc3BvbnNlLjwvcGFyYW0+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiY3Vyck1nZElEXCI+bnVtYmVyIG9mIHdpbmRvdyBpbiBnbG9iYWwgYXJyYXk8L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cIm9wZW5pbmdUYXNrRGV0YWlsc1wiPmFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb2Ygb3BlbmluZyB0YXNrPC9wYXJhbT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJyZXNcIj5yZXN1bHQgdG8gYmUgcmVhZCBmcm9tIGNvbW1hbmQgcmV0dXJuZWQgd2l0aW4gdGhlIHJlc3BvbnNlLjwvcGFyYW0+XHJcbiAgYXN5bmMgUHJvY2Vzc1Jlc3BvbnNlKHJlc3BvbnNlOiBzdHJpbmcsIGN1cnJNZ2RJRDogbnVtYmVyLCBvcGVuaW5nVGFza0RldGFpbHM6IE9wZW5pbmdUYXNrRGV0YWlscywgcmVzOiBJUmVzdWx0VmFsdWUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZURldlRvTG9nKFwiPC0tIFByb2Nlc3NSZXNwb25zZSBzdGFydGVkIC0tPlwiKTtcclxuICAgIGlmIChvcGVuaW5nVGFza0RldGFpbHMgPT09IG51bGwpXHJcbiAgICAgIG9wZW5pbmdUYXNrRGV0YWlscyA9IG5ldyBPcGVuaW5nVGFza0RldGFpbHMoKTtcclxuXHJcbiAgICBsZXQgc3lzdGVtTWlsbGlzZWNvbmRzOiBudW1iZXIgPSBNaXNjLmdldFN5c3RlbU1pbGxpc2Vjb25kcygpO1xyXG4gICAgaWYgKHJlc3BvbnNlID09PSBudWxsIHx8IHJlc3BvbnNlLnRyaW0oKS5sZW5ndGggPT09IDApXHJcbiAgICAgIHJldHVybjtcclxuXHJcbiAgICBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuY3Vyck1nZElEID0gY3Vyck1nZElEO1xyXG5cclxuICAgIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5QYXJzZXIucHVzaCgpOyAvLyBhbGxvdyByZWN1cnNpdmUgcGFyc2luZ1xyXG4gICAgUnVudGltZUNvbnRleHRCYXNlLkluc3RhbmNlLlBhcnNlci5zZXRYTUxkYXRhKHJlc3BvbnNlKTtcclxuICAgIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5QYXJzZXIuc2V0Q3VyckluZGV4KDApO1xyXG5cclxuICAgIGxldCBjdXJyTUdEYXRhOiBNR0RhdGEgPSBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuZ2V0Q3Vyck1HRGF0YSgpO1xyXG4gICAgYXdhaXQgY3Vyck1HRGF0YS5maWxsRGF0YShvcGVuaW5nVGFza0RldGFpbHMsIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5QYXJzZXIpO1xyXG5cclxuICAgIC8vIGZyZWUgbWVtb3J5XHJcbiAgICBSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUGFyc2VyLnNldFhNTGRhdGEobnVsbCk7XHJcbiAgICBSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUGFyc2VyLnBvcCgpO1xyXG5cclxuICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZURldlRvTG9nKFwiPC0tIFByb2Nlc3NSZXNwb25zZSBmaW5pc2hlZCAtLT4gKFwiICsgKE1pc2MuZ2V0U3lzdGVtTWlsbGlzZWNvbmRzKCkgLSBzeXN0ZW1NaWxsaXNlY29uZHMpICsgXCIpXCIpO1xyXG4gICAgLy8gZXhlY3V0ZSB0aGUgY29tbWFuZHMgdGhhdCB3ZXJlIHJldHVybmVkIGluIHRoZSByZXNwb25zZVxyXG4gICAgYXdhaXQgKDxDb21tYW5kc1RhYmxlPmN1cnJNR0RhdGEuQ21kc1RvQ2xpZW50KS5FeGVjdXRlKHJlcyk7XHJcbiAgICBhd2FpdCB0aGlzLlByb2Nlc3NSZWNvdmVyeSgpO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBwcm9jZXNzUmVjb3ZlcnlcclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIGFzeW5jIFByb2Nlc3NSZWNvdmVyeSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHJcbiAgICAvLyBRQ1IgIzc3MTAxMiAtIHByb2Nlc3MgZGF0YSBlcnJvciByZWNvdmVyeSBvbmx5IGFmdGVyIHRoZSBwYXJzaW5nIHByb2Nlc3MgaXMgb3Zlci5cclxuICAgIEFjY2Vzc0hlbHBlci5ldmVudHNNYW5hZ2VyLnB1c2hOZXdFeGVjU3RhY2tzKCk7XHJcbiAgICBhd2FpdCBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUucHJvY2Vzc1JlY292ZXJ5KCk7XHJcbiAgICBBY2Nlc3NIZWxwZXIuZXZlbnRzTWFuYWdlci5wb3BOZXdFeGVjU3RhY2tzKCk7XHJcbiAgfVxyXG59XHJcblxyXG4vLy8gPHN1bW1hcnk+aGVscGVyIGNsYXNzOiBkZXRhaWxzIGZyb20gdGhlIHJ1bnRpbWUtZW5naW5lIC0gZW52aXJvbm1lbnQgdmFsdWVzLlxyXG4vLy8gSGFuZHNoYWtlIHJlc3BvbnNlOiA8UmljaGNsaWVudHJlc3BvbnNlPiA8Q29udGV4dElEPi4uLjwvQ29udGV4dElEPiA8RW52aXJvbm1lbnQgSW5wdXRQYXNzd29yZD1cIll8TlwiXHJcbi8vLyBTeXN0ZW1Mb2dpbj1cIkZ8TnxEfExcIiAvPiA8L1JpY2hjbGllbnRyZXNwb25zZT5cclxuLy8vIDwvc3VtbWFyeT5cclxuY2xhc3MgSGFuZHNoYWtlUmVzcG9uc2Uge1xyXG4gIHN0YXRpYyByZWFkb25seSBTWVNURU1fTE9HSU5fQUQ6IHN0cmluZyA9ICdEJztcclxuXHJcbiAgcHJpdmF0ZSBfc2NyYW1ibGVNZXNzYWdlczogYm9vbGVhbiA9IHRydWU7IC8vIHRydWUgaWYgbWVzc2FnZXMgc2hvdWxkIGJlIHNjcmFtYmxlZC91bnNjcmFtYmxlZCBieSB0aGUgY2xpZW50IGFuZCBzZXJ2ZXJcclxuICBnZXQgU2NyYW1ibGVNZXNzYWdlcygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9zY3JhbWJsZU1lc3NhZ2VzO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY29udGV4dElkOiBzdHJpbmcgPSBudWxsO1xyXG5cclxuICBnZXQgQ29udGV4dElkKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5fY29udGV4dElkO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfcHJpdmF0ZVNlc3Npb25JZDogc3RyaW5nID0gbnVsbDtcclxuXHJcbiAgZ2V0IEdldFNlc3Npb25JZCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuX3ByaXZhdGVTZXNzaW9uSWQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbnB1dFBhc3N3b3JkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGdldCBJbnB1dFBhc3N3b3JkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2lucHV0UGFzc3dvcmQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9odHRwVGltZW91dDogbnVtYmVyID0gMDtcclxuXHJcbiAgZ2V0IEh0dHBUaW1lb3V0KCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5faHR0cFRpbWVvdXQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zeXN0ZW1Mb2dpbjogc3RyaW5nID0gbnVsbDtcclxuXHJcbiAgZ2V0IFN5c3RlbUxvZ2luKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5fc3lzdGVtTG9naW47XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9tYXhJbnRlcm5hbExvZ0xldmVsOiBzdHJpbmcgPSBudWxsO1xyXG5cclxuICBnZXQgTWF4SW50ZXJuYWxMb2dMZXZlbCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuX21heEludGVybmFsTG9nTGV2ZWw7XHJcbiAgfVxyXG5cclxuICBjb25zdHJ1Y3RvcihyZXNwb25zZVhNTDogc3RyaW5nKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBKU09OX1V0aWxzLkpTT05Gcm9tWE1MKHJlc3BvbnNlWE1MLCB0aGlzLkZpbGxGcm9tSlNPTi5iaW5kKHRoaXMpKTtcclxuICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZUV4Y2VwdGlvblRvTG9nKGV4LCByZXNwb25zZVhNTCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIEZpbGxGcm9tSlNPTihlcnJvciwgcmVzdWx0KTogdm9pZCB7XHJcblxyXG4gICAgLy8gSWYgdGhlcmUgd2FzIGFuIGVycm9yIGluIHBhcnNpbmcgdGhlIFhNTCxcclxuICAgIGlmIChlcnJvciAhPSBudWxsKSB7XHJcbiAgICAgIHRocm93IGVycm9yO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCByZXNwb25zZSA9IHJlc3VsdFsnUmljaGNsaWVudHJlc3BvbnNlJ107XHJcblxyXG4gICAgZm9yIChsZXQgZWxlbWVudE5hbWUgaW4gcmVzcG9uc2UpIHtcclxuICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KGVsZW1lbnROYW1lKSkge1xyXG5cclxuICAgICAgICBzd2l0Y2ggKGVsZW1lbnROYW1lKSB7XHJcbiAgICAgICAgICBjYXNlIFwiQ29udGV4dElEXCI6XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRleHRJZCA9IHJlc3BvbnNlW2VsZW1lbnROYW1lXVswXTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiU2Vzc2lvbklEXCI6XHJcbiAgICAgICAgICAgIHRoaXMuX3ByaXZhdGVTZXNzaW9uSWQgPSByZXNwb25zZVtlbGVtZW50TmFtZV1bMF07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcIkVudmlyb25tZW50XCI6XHJcbiAgICAgICAgICAgIGxldCBlbnZBdHRyaWJ1dGVzID0gcmVzcG9uc2VbXCJFbnZpcm9ubWVudFwiXVswXVsnJCddO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZChlbnZBdHRyaWJ1dGVzW1wiU2NyYW1ibGVNZXNzYWdlc1wiXSkpIHtcclxuICAgICAgICAgICAgICBEZWJ1Zy5Bc3NlcnQoZW52QXR0cmlidXRlc1tcIlNjcmFtYmxlTWVzc2FnZXNcIl0gPT09IFwiTlwiKTtcclxuICAgICAgICAgICAgICB0aGlzLl9zY3JhbWJsZU1lc3NhZ2VzID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZChlbnZBdHRyaWJ1dGVzW1wiTWF4SW50ZXJuYWxMb2dMZXZlbFwiXSkpXHJcbiAgICAgICAgICAgICAgdGhpcy5fbWF4SW50ZXJuYWxMb2dMZXZlbCA9IGVudkF0dHJpYnV0ZXNbXCJNYXhJbnRlcm5hbExvZ0xldmVsXCJdO1xyXG4gICAgICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKGVudkF0dHJpYnV0ZXNbXCJJbnB1dFBhc3N3b3JkXCJdKSAmJiBlbnZBdHRyaWJ1dGVzW1wiSW5wdXRQYXNzd29yZFwiXS50b0xvY2FsZUxvd2VyQ2FzZSgpID09PSBcInlcIilcclxuICAgICAgICAgICAgICB0aGlzLl9pbnB1dFBhc3N3b3JkID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZChlbnZBdHRyaWJ1dGVzW1wiU3lzdGVtTG9naW5cIl0pKVxyXG4gICAgICAgICAgICAgIHRoaXMuX3N5c3RlbUxvZ2luID0gZW52QXR0cmlidXRlc1tcIlN5c3RlbUxvZ2luXCJdO1xyXG4gICAgICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKGVudkF0dHJpYnV0ZXNbQ29uc3RJbnRlcmZhY2UuTUdfVEFHX0hUVFBfQ09NTVVOSUNBVElPTl9USU1FT1VUXSkpXHJcbiAgICAgICAgICAgICAgdGhpcy5faHR0cFRpbWVvdXQgPSArZW52QXR0cmlidXRlc1tDb25zdEludGVyZmFjZS5NR19UQUdfSFRUUF9DT01NVU5JQ0FUSU9OX1RJTUVPVVRdO1xyXG4gICAgICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKGVudkF0dHJpYnV0ZXNbXCJGb3J3YXJkU2xhc2hcIl0pKVxyXG4gICAgICAgICAgICAgIEFjY2Vzc0hlbHBlci5lbnZpcm9ubWVudC5Gb3J3YXJkU2xhc2hVc2FnZSA9IGVudkF0dHJpYnV0ZXNbXCJGb3J3YXJkU2xhc2hcIl07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8vIDxzdW1tYXJ5PlRoaXMgY2xhc3MgaW1wbGVtZW50cyBNZ1NBWEhhbmRsZXJJbnRlcmZhY2UsIHdoaWNoIG1lYW5zIHRoYXQgaXQgZGVmaW5lcyBhbGwgdGhlIFwiY2FsbGJhY2tcIlxyXG4vLy8gbWV0aG9kcyB0aGF0IHRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRvIG5vdGlmeSB0aGUgYXBwbGljYXRpb24uIEluIHRoaXMgZXhhbXBsZSB3ZSBvdmVycmlkZSB0aGVcclxuLy8vIG1ldGhvZHMgdGhhdCB3ZSByZXF1aXJlLjwvc3VtbWFyeT5cclxuY2xhc3MgRXJyb3JNZXNzYWdlWG1sIHtcclxuICBwcml2YXRlIF9sYXN0UmVxdWVzdFRpbWU6IG51bWJlciA9IDA7XHJcbiAgY29udGV4dEluYWN0aXZpdHlUaW1lb3V0OiBudW1iZXI7XHJcblxyXG4gIHByaXZhdGUgX2Vycm9yTWVzc2FnZTogc3RyaW5nID0gbnVsbDtcclxuICBwcml2YXRlIF9lcnJvckNvZGU6IG51bWJlciA9IDA7XHJcbiAgcHJpdmF0ZSBfbWlkZGxld2FyZUFkZHJlc3M6IHN0cmluZyA9IG51bGw7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBfcGFyc2luZ0ZhaWxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3Rvcih4bWxDb250ZW50OiBzdHJpbmcsIGxhc3RSZXF1ZXN0VGltZTogbnVtYmVyLCBjb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQ6IG51bWJlcikge1xyXG4gICAgdGhpcy5fbGFzdFJlcXVlc3RUaW1lID0gbGFzdFJlcXVlc3RUaW1lO1xyXG4gICAgdGhpcy5jb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQgPSBjb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQ7XHJcbiAgICB0cnkge1xyXG4gICAgICBKU09OX1V0aWxzLkpTT05Gcm9tWE1MKHhtbENvbnRlbnQsIHRoaXMuRmlsbEZyb21KU09OLmJpbmQodGhpcykpO1xyXG4gICAgfSBjYXRjaCAoZXgpIHtcclxuICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRXhjZXB0aW9uVG9Mb2coZXgpO1xyXG4gICAgICBNaXNjLldyaXRlU3RhY2tUcmFjZShleCk7XHJcbiAgICAgIHRoaXMuX3BhcnNpbmdGYWlsZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBGaWxsRnJvbUpTT04oZXJyb3IsIHJlc3VsdCk6IHZvaWQge1xyXG5cclxuICAgIC8vIElmIHRoZXJlIHdhcyBhbiBlcnJvciBpbiBwYXJzaW5nIHRoZSBYTUwsXHJcbiAgICBpZiAoZXJyb3IgIT0gbnVsbCkge1xyXG4gICAgICB0aHJvdyBlcnJvcjtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgeG1sZXJyID0gcmVzdWx0Wyd4bWxlcnInXTtcclxuXHJcbiAgICBmb3IgKGxldCBlbGVtZW50TmFtZSBpbiB4bWxlcnIpIHtcclxuICAgICAgaWYgKHhtbGVyci5oYXNPd25Qcm9wZXJ0eShlbGVtZW50TmFtZSkpIHtcclxuICAgICAgICBzd2l0Y2ggKGVsZW1lbnROYW1lKSB7XHJcbiAgICAgICAgICBjYXNlIFwiZXJybXNnXCI6XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yTWVzc2FnZSA9IHhtbGVycltlbGVtZW50TmFtZV1bMF07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcImVycmNvZGVcIjpcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3JDb2RlID0gKyh4bWxlcnJbZWxlbWVudE5hbWVdKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwic2VydmVyXCI6XHJcbiAgICAgICAgICAgIHRoaXMuX21pZGRsZXdhcmVBZGRyZXNzID0geG1sZXJyW2VsZW1lbnROYW1lXVswXTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiYXBwbmFtZVwiOiAvLyBpZ25vcmVkIC0gdGhlIGNsaWVudCBsaXN0cyB0aGlzIHZhbHVlIGZyb20gdGhlIGV4ZWN1dGlvbiBwcm9wZXJ0aWVzXHJcbiAgICAgICAgICBjYXNlIFwicHJnbmFtZVwiOiAvLyBpZ25vcmVkIC0gdGhlIGNsaWVudCBsaXN0cyB0aGlzIHZhbHVlIGZyb20gdGhlIGV4ZWN1dGlvbiBwcm9wZXJ0aWVzXHJcbiAgICAgICAgICBjYXNlIFwiYXJndW1lbnRzXCI6IC8vIGlnbm9yZWRcclxuICAgICAgICAgIGNhc2UgXCJ1c2VybmFtZVwiOiAgLy8gaWdub3JlZFxyXG4gICAgICAgICAgY2FzZSBcInhtbGVyclwiOiAvLyBlbmQgb2YgdGhlIGVycm9yIG1lc3NhZ2VcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVFeGNlcHRpb25Ub0xvZ1dpdGhNc2coTlN0cmluZy5Gb3JtYXQoXCJVbmtub3duIGVsZW1lbnQ6ICd7MH0nXCIsIGVsZW1lbnROYW1lKSk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgR2V0Q29kZSgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2Vycm9yQ29kZTtcclxuICB9XHJcblxyXG4gIC8vIGJ1aWxkICYgcmV0dXJuIGEgZm9ybWF0dGVkIGVycm9yIG1lc3NhZ2VcclxuICBHZXRNZXNzYWdlKCk6IHN0cmluZyB7XHJcbiAgICBsZXQgc2I6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpO1xyXG5cclxuICAgIGlmICh0aGlzLl9wYXJzaW5nRmFpbGVkKSB7XHJcbiAgICAgIHNiLkFwcGVuZChBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuUkNfU1RSX0Y3X1VORVhQRUNURURfRVJSKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzd2l0Y2ggKHRoaXMuX2Vycm9yQ29kZSkge1xyXG4gICAgICAgIGNhc2UgU2VydmVyRXJyb3IuRVJSX0NUWF9OT1RfRk9VTkQ6XHJcbiAgICAgICAgICBpZiAodGhpcy5JbmFjdGl2aXR5VGltZW91dEV4cGlyZWQoKSlcclxuICAgICAgICAgICAgc2IuQXBwZW5kKE5TdHJpbmcuRm9ybWF0KFwiezB9ICh7MX0gezJ9KVwiLFxyXG4gICAgICAgICAgICAgIEFjY2Vzc0hlbHBlci5sYW5ndWFnZURhdGEuZ2V0Q29uc3RNZXNzYWdlKE1zZ0ludGVyZmFjZS5TVFJfRVJSX1NFU1NJT05fQ0xPU0VEX0lOQUNUSVZJVFkpLFxyXG4gICAgICAgICAgICAgIE1hdGguZmxvb3IodGhpcy5jb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQgLyA2MDApLCAvLyBjb252ZXJzaW9uIGZyb20gMS8xMCBvZiBzZWNvbmRzIHRvIG1pbnV0ZXNcclxuICAgICAgICAgICAgICBBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuU1RSX01JTlVURVMpKSk7XHJcbiAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHNiLkFwcGVuZChOU3RyaW5nLkZvcm1hdChcInswfSAoezF9KS5cIiwgQWNjZXNzSGVscGVyLmxhbmd1YWdlRGF0YS5nZXRDb25zdE1lc3NhZ2UoTXNnSW50ZXJmYWNlLlNUUl9FUlJfU0VTU0lPTl9DTE9TRUQpLCB0aGlzLl9lcnJvckNvZGUpKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFNlcnZlckVycm9yLkVSUl9XRUJDTElFTlRfUFJPR1JBTV9SRUxPQURFRDpcclxuICAgICAgICAgIHNiLkFwcGVuZChBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuU1RSX0VSUl9XRUJDTElFTlRfUFJPR1JBTV9SRUxPQURFRCkpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgU2VydmVyRXJyb3IuRVJSX0VYRUNVVEVEX1BST0dSQU1fQ0hBTkdFRDpcclxuICAgICAgICAgIHNiLkFwcGVuZChBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuU1RSX0VSUl9FWEVDVVRFRF9QUk9HUkFNX0NIQU5HRUQpKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFNlcnZlckVycm9yLkVSUl9BVVRIRU5USUNBVElPTjpcclxuICAgICAgICAgIHNiLkFwcGVuZChBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuVVNSSU5QX1NUUl9CQURQQVNTVykpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgU2VydmVyRXJyb3IuRVJSX0FDQ0VTU19ERU5JRUQ6XHJcbiAgICAgICAgICBzYi5BcHBlbmQoQWNjZXNzSGVscGVyLmxhbmd1YWdlRGF0YS5nZXRDb25zdE1lc3NhZ2UoTXNnSW50ZXJmYWNlLlNUUl9FUlJfQVVUSE9SSVpBVElPTl9GQUlMVVJFKSk7XHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgIHNiLkFwcGVuZCh0aGlzLl9lcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNiLkFwcGVuZChPU0Vudmlyb25tZW50LkVvbFNlcSArIE9TRW52aXJvbm1lbnQuRW9sU2VxKTtcclxuXHJcbiAgICAgIGlmICghU2VydmVyQ29uZmlnLkluc3RhbmNlLlNob3VsZERpc3BsYXlHZW5lcmljRXJyb3IoKSkge1xyXG4gICAgICAgIHNiLkFwcGVuZChBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuQlJPV1NFUl9PUFRfSU5GT19TRVJWRVJfU1RSKSArIFwiOiAgIFwiKTtcclxuICAgICAgICBzYi5BcHBlbmQoU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldFNlcnZlcigpKTtcclxuICAgICAgICBpZiAoIU5TdHJpbmcuSXNOdWxsT3JFbXB0eSh0aGlzLl9taWRkbGV3YXJlQWRkcmVzcykpIHtcclxuICAgICAgICAgIHNiLkFwcGVuZChcIiAtLT4gXCIpO1xyXG4gICAgICAgICAgc2IuQXBwZW5kKHRoaXMuX21pZGRsZXdhcmVBZGRyZXNzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc2IuQXBwZW5kKE9TRW52aXJvbm1lbnQuRW9sU2VxKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2IuQXBwZW5kKEFjY2Vzc0hlbHBlci5sYW5ndWFnZURhdGEuZ2V0Q29uc3RNZXNzYWdlKE1zZ0ludGVyZmFjZS5UQVNLUlVMRV9TVFJfQVBQTElDQVRJT04pICsgXCI6ICAgXFxcIlwiKTtcclxuICAgICAgc2IuQXBwZW5kKFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRBcHBOYW1lKCkpO1xyXG4gICAgICBzYi5BcHBlbmQoXCJcXFwiIChcXFwiXCIpO1xyXG4gICAgICBzYi5BcHBlbmQoXCJcXFwiKVwiKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc2IuVG9TdHJpbmcoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgSW5hY3Rpdml0eVRpbWVvdXRFeHBpcmVkKCk6IGJvb2xlYW4ge1xyXG4gICAgbGV0IGV4cGlyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGlmICh0aGlzLmNvbnRleHRJbmFjdGl2aXR5VGltZW91dCA+IDApIHtcclxuICAgICAgbGV0IGN1cnJUaW1lTWlsbGk6IG51bWJlciA9IE1pc2MuZ2V0U3lzdGVtTWlsbGlzZWNvbmRzKCk7XHJcbiAgICAgIGV4cGlyZWQgPSAoKGN1cnJUaW1lTWlsbGkgLSB0aGlzLl9sYXN0UmVxdWVzdFRpbWUpID4gKHRoaXMuY29udGV4dEluYWN0aXZpdHlUaW1lb3V0ICogMTAwKSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZXhwaXJlZDtcclxuICB9XHJcbn1cclxuXHJcbi8vIFRPRE86IEltcGxlbWVudCB0aGlzIGNsYXNzXHJcbi8vIGNsYXNzIENsaWVudExvZ0FjY3VtdWxhdG9yIHtcclxuLy9cclxuLy8gICBwcml2YXRlIHN0YXRpYyBDTElFTlRfTE9HX0hEUl9NU0c6IHN0cmluZyA9IFwiQ2xpZW50IGxvZyBmaWxlXCI7XHJcbi8vICAgcHJpdmF0ZSBzdGF0aWMgX2V4aXN0aW5nTG9nTmFtZXM6IExpc3Q8c3RyaW5nPiA9IG5ldyBMaXN0PHN0cmluZz4oKTtcclxuLy8gICBwcml2YXRlIF9jbGllbnRMb2dPczogU3RyZWFtV3JpdGVyID0gbnVsbDtcclxuLy8gICBwcml2YXRlIF9jb250ZXh0SWQ6IG51bWJlciA9IDA7XHJcbi8vICAgcHJpdmF0ZSBfZmFpbGVkOiBib29sZWFuID0gZmFsc2U7XHJcbi8vICAgcHJpdmF0ZSBfZmlsZU5hbWU6IHN0cmluZyA9IG51bGw7XHJcbi8vXHJcbi8vICAgY29uc3RydWN0b3IoY29udGV4dElEOiBudW1iZXIpIHtcclxuLy8gICAgIHRoaXMuX2NvbnRleHRJZCA9IGNvbnRleHRJRDtcclxuLy8gICAgIHRoaXMuX2ZpbGVOYW1lID0gdGhpcy5CdWlsZEZpbGVOYW1lKCk7XHJcbi8vICAgICB0aGlzLk9wZW5Gb3JXcml0ZSgpO1xyXG4vLyAgIH1cclxuLy9cclxuLy8gICBXcml0ZShidWZmZXI6IHN0cmluZyk6IHZvaWQge1xyXG4vLyAgICAgdHJ5IHtcclxuLy8gICAgICAgbGV0IGZsYWc6IGJvb2xlYW4gPSAhdGhpcy5fZmFpbGVkO1xyXG4vLyAgICAgICBpZiAoIWZsYWcpIHtcclxuLy8gICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oXCJDbGllbnRMb2dTZXF1ZW5jZSA6IExvZ2luZyBjbGllbnQgc2VxdWVuY2UgaXMgZGVhY3RpdmF0ZWRcIik7XHJcbi8vICAgICAgIH1cclxuLy8gICAgICAgbGV0IGZsYWcyOiBib29sZWFuID0gdGhpcy5PcGVuRm9yV3JpdGUoKTtcclxuLy8gICAgICAgaWYgKGZsYWcyKSB7XHJcbi8vICAgICAgICAgdGhpcy5fY2xpZW50TG9nT3MuV3JpdGUoYnVmZmVyKTtcclxuLy8gICAgICAgICB0aGlzLl9jbGllbnRMb2dPcy5DbG9zZSgpO1xyXG4vLyAgICAgICAgIHRoaXMuX2NsaWVudExvZ09zID0gbnVsbDtcclxuLy8gICAgICAgICB0aGlzLk9wZW5Gb3JXcml0ZSgpO1xyXG4vLyAgICAgICB9XHJcbi8vICAgICB9XHJcbi8vICAgICBjYXRjaCAoZXgpIHtcclxuLy8gICAgICAgaWYgKGV4IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHtcclxuLy8gICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVEZXZUb0xvZyhleC5NZXNzYWdlKTtcclxuLy8gICAgICAgICBNaXNjLldyaXRlU3RhY2tUcmFjZShleCwgTkNvbnNvbGUuRXJyb3IpO1xyXG4vLyAgICAgICB9XHJcbi8vICAgICAgIGVsc2VcclxuLy8gICAgICAgICB0aHJvdyBleDtcclxuLy8gICAgIH1cclxuLy8gICB9XHJcbi8vXHJcbi8vICAgUmVhZCgpOiBzdHJpbmcge1xyXG4vLyAgICAgbGV0IHJlc3VsdDogc3RyaW5nID0gbnVsbDtcclxuLy8gICAgIHRyeSB7XHJcbi8vICAgICAgIGxldCBmbGFnOiBib29sZWFuID0gIXRoaXMuX2ZhaWxlZDtcclxuLy8gICAgICAgaWYgKCFmbGFnKSB7XHJcbi8vICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKFwiQ2xpZW50TG9nU2VxdWVuY2UgOiBMb2dpbmcgY2xpZW50IHNlcXVlbmNlIGlzIGRlYWN0aXZhdGVkXCIpO1xyXG4vLyAgICAgICB9XHJcbi8vICAgICAgIHRoaXMuX2NsaWVudExvZ09zLkNsb3NlKCk7XHJcbi8vICAgICAgIHRoaXMuX2NsaWVudExvZ09zID0gbnVsbDtcclxuLy8gICAgICAgcmVzdWx0ID0gSGFuZGxlRmlsZXMucmVhZFRvU3RyaW5nKHRoaXMuX2ZpbGVOYW1lLCBFbmNvZGluZy5EZWZhdWx0KTtcclxuLy8gICAgICAgdGhpcy5PcGVuRm9yV3JpdGUoKTtcclxuLy8gICAgIH1cclxuLy8gICAgIGNhdGNoIChleCkge1xyXG4vLyAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikge1xyXG4vLyAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZURldlRvTG9nKGV4Lk1lc3NhZ2UpO1xyXG4vLyAgICAgICAgIE1pc2MuV3JpdGVTdGFja1RyYWNlKGV4LCBOQ29uc29sZS5FcnJvcik7XHJcbi8vICAgICAgIH1cclxuLy8gICAgICAgZWxzZVxyXG4vLyAgICAgICAgIHRocm93IGV4O1xyXG4vLyAgICAgfVxyXG4vLyAgICAgcmV0dXJuIHJlc3VsdDtcclxuLy8gICB9XHJcbi8vXHJcbi8vICAgUmVzZXQoKTogdm9pZCB7XHJcbi8vICAgICB0cnkge1xyXG4vLyAgICAgICBsZXQgZmxhZzogYm9vbGVhbiA9ICF0aGlzLl9mYWlsZWQ7XHJcbi8vICAgICAgIGlmICghZmxhZykge1xyXG4vLyAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihcIkNsaWVudExvZ1NlcXVlbmNlIDogTG9naW5nIGNsaWVudCBzZXF1ZW5jZSBpcyBkZWFjdGl2YXRlZFwiKTtcclxuLy8gICAgICAgfVxyXG4vLyAgICAgICB0aGlzLl9jbGllbnRMb2dPcy5DbG9zZSgpO1xyXG4vLyAgICAgICB0aGlzLl9jbGllbnRMb2dPcyA9IG51bGw7XHJcbi8vICAgICAgIEhhbmRsZUZpbGVzLmRlbGV0ZUZpbGUodGhpcy5fZmlsZU5hbWUpO1xyXG4vLyAgICAgfVxyXG4vLyAgICAgY2F0Y2ggKGV4KSB7XHJcbi8vICAgICAgIGlmIChleCBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7XHJcbi8vICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRXhjZXB0aW9uVG9Mb2coZXgpO1xyXG4vLyAgICAgICB9XHJcbi8vICAgICAgIGVsc2VcclxuLy8gICAgICAgICB0aHJvdyBleDtcclxuLy8gICAgIH1cclxuLy8gICB9XHJcbi8vXHJcbi8vICAgc3RhdGljIEV4aXN0aW5nTG9nc0ZvdW5kKCk6IGJvb2xlYW4ge1xyXG4vLyAgICAgbGV0IHJlc3VsdDogYm9vbGVhbiA9IGZhbHNlO1xyXG4vLyAgICAgQ2xpZW50TG9nQWNjdW11bGF0b3IuQnVpbGRleGlzdGluZ0xvZ0xpc3QoKTtcclxuLy8gICAgIGxldCBmbGFnOiBib29sZWFuID0gQ2xpZW50TG9nQWNjdW11bGF0b3IuX2V4aXN0aW5nTG9nTmFtZXMgIT09IG51bGwgJiYgQ2xpZW50TG9nQWNjdW11bGF0b3IuX2V4aXN0aW5nTG9nTmFtZXMuQ291bnQgPiAwO1xyXG4vLyAgICAgaWYgKGZsYWcpIHtcclxuLy8gICAgICAgcmVzdWx0ID0gdHJ1ZTtcclxuLy8gICAgIH1cclxuLy8gICAgIHJldHVybiByZXN1bHQ7XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIHN0YXRpYyBFeGlzdGluZ0xvZ0l0ZXJhdG9yKCk6IElFbnVtZXJhdG9yPHN0cmluZz4ge1xyXG4vLyAgICAgcmV0dXJuIENsaWVudExvZ0FjY3VtdWxhdG9yLl9leGlzdGluZ0xvZ05hbWVzLkdldEVudW1lcmF0b3IoKTtcclxuLy8gICB9XHJcbi8vXHJcbi8vICAgc3RhdGljIEJ1aWxkTG9nSGVhZGVyTGluZShsb2dOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4vLyAgICAgbGV0IHN0cmluZ0J1aWxkZXI6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcihcIkNsaWVudCBsb2cgZmlsZVwiKTtcclxuLy8gICAgIGxldCBzdHI6IHN0cmluZyA9IE5TdHJpbmcuU3Vic3RyaW5nKGxvZ05hbWUsIGxvZ05hbWUuTGFzdEluZGV4T2YoTk51bWJlci5Ub1N0cmluZyhQYXRoLkRpcmVjdG9yeVNlcGFyYXRvckNoYXIpICsgXCJDU1wiKSArIDMsIGxvZ05hbWUuTGFzdEluZGV4T2YoXCIubG9nXCIpIC0gKGxvZ05hbWUuTGFzdEluZGV4T2YoTk51bWJlci5Ub1N0cmluZyhQYXRoLkRpcmVjdG9yeVNlcGFyYXRvckNoYXIpICsgXCJDU1wiKSArIDMpKTtcclxuLy8gICAgIHN0cmluZ0J1aWxkZXIuQXBwZW5kKFwiIChDb250ZXh0IDogXCIpO1xyXG4vLyAgICAgc3RyaW5nQnVpbGRlci5BcHBlbmQoc3RyICsgXCIgKSBcIik7XHJcbi8vICAgICByZXR1cm4gc3RyaW5nQnVpbGRlci5Ub1N0cmluZygpO1xyXG4vLyAgIH1cclxuLy9cclxuLy8gICBFbXB0eSgpOiBib29sZWFuIHtcclxuLy8gICAgIHJldHVybiB0aGlzLl9mYWlsZWQgfHwgIUhhbmRsZUZpbGVzLmlzRXhpc3RzKHRoaXMuX2ZpbGVOYW1lKSB8fCBIYW5kbGVGaWxlcy5nZXRGaWxlU2l6ZSh0aGlzLl9maWxlTmFtZSkgPT09IDA7XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIElzRmFpbGVkKCk6IGJvb2xlYW4ge1xyXG4vLyAgICAgcmV0dXJuIHRoaXMuX2ZhaWxlZDtcclxuLy8gICB9XHJcbi8vXHJcbi8vICAgcHJpdmF0ZSBzdGF0aWMgQnVpbGRleGlzdGluZ0xvZ0xpc3QoKTogdm9pZCB7XHJcbi8vICAgICBsZXQgZmxhZzogYm9vbGVhbiA9IENsaWVudExvZ0FjY3VtdWxhdG9yLl9leGlzdGluZ0xvZ05hbWVzICE9PSBudWxsICYmIENsaWVudExvZ0FjY3VtdWxhdG9yLl9leGlzdGluZ0xvZ05hbWVzLkNvdW50ID09PSAwO1xyXG4vLyAgICAgaWYgKGZsYWcpIHtcclxuLy8gICAgICAgbGV0IHBhdGg6IHN0cmluZyA9IFwiXCI7XHJcbi8vICAgICAgIENsaWVudExvZ0FjY3VtdWxhdG9yLl9leGlzdGluZ0xvZ05hbWVzLkFkZFJhbmdlKE5BcnJheS5Ub0VudW1lcmFibGUoRGlyZWN0b3J5LkdldEZpbGVzKHBhdGgsIFwiQ1MqLkxPR1wiKSkpO1xyXG4vLyAgICAgfVxyXG4vLyAgIH1cclxuLy9cclxuLy8gICBwcml2YXRlIE9wZW5Gb3JXcml0ZSgpOiBib29sZWFuIHtcclxuLy8gICAgIGxldCBmbGFnOiBib29sZWFuID0gdGhpcy5fY2xpZW50TG9nT3MgPT09IG51bGw7XHJcbi8vICAgICBpZiAoZmxhZykge1xyXG4vLyAgICAgICB0cnkge1xyXG4vLyAgICAgICAgIHRoaXMuX2NsaWVudExvZ09zID0gbmV3IFN0cmVhbVdyaXRlcih0aGlzLl9maWxlTmFtZSwgdHJ1ZSwgRW5jb2RpbmcuRGVmYXVsdCk7XHJcbi8vICAgICAgICAgdGhpcy5fZmFpbGVkID0gZmFsc2U7XHJcbi8vICAgICAgIH1cclxuLy8gICAgICAgY2F0Y2ggKGV4KSB7XHJcbi8vICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHtcclxuLy8gICAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZURldlRvTG9nKFwiQ2xpZW50TG9nU2VxdWVuY2VzIDogXCIgKyBleC5NZXNzYWdlKTtcclxuLy8gICAgICAgICAgIHRoaXMuX2ZhaWxlZCA9IHRydWU7XHJcbi8vICAgICAgICAgICB0aGlzLl9jbGllbnRMb2dPcyA9IG51bGw7XHJcbi8vICAgICAgICAgICB0aGlzLl9jb250ZXh0SWQgPSAtMTtcclxuLy8gICAgICAgICAgIHRoaXMuX2ZpbGVOYW1lID0gbnVsbDtcclxuLy8gICAgICAgICB9XHJcbi8vICAgICAgICAgZWxzZVxyXG4vLyAgICAgICAgICAgdGhyb3cgZXg7XHJcbi8vICAgICAgIH1cclxuLy8gICAgIH1cclxuLy8gICAgIHJldHVybiAhdGhpcy5fZmFpbGVkO1xyXG4vLyAgIH1cclxuLy9cclxuLy8gICBwcml2YXRlIEJ1aWxkRmlsZU5hbWUoKTogc3RyaW5nIHtcclxuLy8gICAgIHJldHVybiBcIlwiO1xyXG4vLyAgIH1cclxuLy8gfVxyXG4iXX0=