@projectcor/maia-components 2.51.1 → 2.52.1-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/lib/App.js +44 -19
  2. package/lib/components/atoms/ActionableButton.spec.js +111 -0
  3. package/lib/components/atoms/AgentActivityIndicator/AgentActivityIndicator.spec.js +52 -0
  4. package/lib/components/atoms/AgentActivityIndicator/AgentActivityIndicator.utils.spec.js +11 -0
  5. package/lib/components/atoms/ApprovalBox/ApprovalBox.helpers.spec.js +63 -0
  6. package/lib/components/atoms/ApprovalBox/ApprovalBox.spec.js +183 -0
  7. package/lib/components/atoms/AttachmentCard/AttachmentCard.spec.js +123 -0
  8. package/lib/components/atoms/AttachmentCard/AttachmentCardAudio.helpers.js +3 -1
  9. package/lib/components/atoms/AttachmentCard/AttachmentCardAudio.helpers.spec.js +139 -0
  10. package/lib/components/atoms/AttachmentCard/AttachmentCardAudio.spec.js +385 -0
  11. package/lib/components/atoms/AttachmentCard/AttachmentCardImage.js +3 -1
  12. package/lib/components/atoms/AttachmentCard/AttachmentCardImage.spec.js +78 -0
  13. package/lib/components/atoms/AttachmentPreviewModal/AttachmentPreviewModal.helpers.spec.js +94 -0
  14. package/lib/components/atoms/AttachmentPreviewModal/AttachmentPreviewModal.js +24 -14
  15. package/lib/components/atoms/AttachmentPreviewModal/AttachmentPreviewModal.spec.js +396 -0
  16. package/lib/components/atoms/AttachmentPreviewModal/ExcelPreview.js +28 -10
  17. package/lib/components/atoms/AttachmentPreviewModal/ExcelPreview.spec.js +80 -0
  18. package/lib/components/atoms/AttachmentPreviewModal/PptPreview.helpers.spec.js +526 -0
  19. package/lib/components/atoms/AttachmentPreviewModal/PptPreview.js +19 -15
  20. package/lib/components/atoms/AttachmentPreviewModal/PptPreview.spec.js +169 -0
  21. package/lib/components/atoms/AttachmentPreviewModal/WordPreview.helpers.spec.js +11 -0
  22. package/lib/components/atoms/AttachmentPreviewModal/WordPreview.js +8 -4
  23. package/lib/components/atoms/AttachmentPreviewModal/WordPreview.spec.js +77 -0
  24. package/lib/components/atoms/Backdrop/Backdrop.spec.js +28 -0
  25. package/lib/components/atoms/CardMenu/CardMenu.spec.js +56 -0
  26. package/lib/components/atoms/ChatClientSelector/ChatClientSelector.spec.js +67 -0
  27. package/lib/components/atoms/Checkbox/Checkbox.spec.js +27 -0
  28. package/lib/components/atoms/Chip/Chip.spec.js +82 -0
  29. package/lib/components/atoms/ChipLlm/ChipLlm.spec.js +26 -0
  30. package/lib/components/atoms/ClientSelector/ClientSelector.helpers.spec.js +45 -0
  31. package/lib/components/atoms/ClientSelector/ClientSelector.js +15 -13
  32. package/lib/components/atoms/ClientSelector/ClientSelector.spec.js +133 -0
  33. package/lib/components/atoms/ContextCompactedNotice/ContextCompactedNotice.spec.js +107 -0
  34. package/lib/components/atoms/ContextMentionChip/ContextMentionChip.spec.js +29 -0
  35. package/lib/components/atoms/ContextMentionChip/MentionOverflowLabel.spec.js +46 -0
  36. package/lib/components/atoms/ContextMentionChip/buildChipElement.helpers.spec.js +109 -0
  37. package/lib/components/atoms/ContextMentionChip/buildChipElement.spec.js +81 -0
  38. package/lib/components/atoms/ContextMentionEditor/ContextMentionEditor.helpers.spec.js +92 -0
  39. package/lib/components/atoms/ContextMentionEditor/ContextMentionEditor.spec.js +319 -0
  40. package/lib/components/atoms/ContextMentionItem/ContextMentionItem.spec.js +107 -0
  41. package/lib/components/atoms/ContextMentionPopover/ContextMentionPopover.spec.js +136 -0
  42. package/lib/components/atoms/CopyToClipboard.spec.js +74 -0
  43. package/lib/components/atoms/EditableLabel/EditableLabel.spec.js +76 -0
  44. package/lib/components/atoms/EntitySelector/EntitySelector.spec.js +86 -0
  45. package/lib/components/atoms/Expand/Expand.spec.js +57 -0
  46. package/lib/components/atoms/Fade/Fade.js +10 -6
  47. package/lib/components/atoms/Fade/Fade.spec.js +66 -0
  48. package/lib/components/atoms/FeedbackButton/FeedbackButton.spec.js +75 -0
  49. package/lib/components/atoms/FrequentlyAskedQuestions/FrequentlyAskedQuestions.spec.js +104 -0
  50. package/lib/components/atoms/FrequentlyUsedActions/FrequentlyUsedActions.js +3 -1
  51. package/lib/components/atoms/FrequentlyUsedActions/FrequentlyUsedActions.spec.js +91 -0
  52. package/lib/components/atoms/FrequentlyUsedActions/FrequentlyUsedActions.styles.js +19 -7
  53. package/lib/components/atoms/HelpButton.spec.js +87 -0
  54. package/lib/components/atoms/ImagePreview/ImagePreview.spec.js +96 -0
  55. package/lib/components/atoms/ListMenuOption/ListMenuOption.spec.js +54 -0
  56. package/lib/components/atoms/LoadingFaqs/LoadingFaqs.spec.js +21 -0
  57. package/lib/components/atoms/LoadingSearchClients/LoadingSearchClients.spec.js +20 -0
  58. package/lib/components/atoms/LoadingSearchProjects/LoadingSearchProjects.spec.js +26 -0
  59. package/lib/components/atoms/LoadingText/LoadingText.spec.js +25 -0
  60. package/lib/components/atoms/MAIAButton/MAIAButton.spec.js +42 -0
  61. package/lib/components/atoms/MAIAError/MAIAError.spec.js +27 -0
  62. package/lib/components/atoms/MAIAInput/MAIAInput.attachments.helpers.js +3 -2
  63. package/lib/components/atoms/MAIAInput/MAIAInput.attachments.helpers.spec.js +113 -0
  64. package/lib/components/atoms/MAIAInput/MAIAInput.helpers.js +3 -2
  65. package/lib/components/atoms/MAIAInput/MAIAInput.helpers.spec.js +381 -0
  66. package/lib/components/atoms/MAIAInput/MAIAInput.js +123 -99
  67. package/lib/components/atoms/MAIAInput/MAIAInput.spec.js +719 -0
  68. package/lib/components/atoms/MAIAInput/MAIAInputEditor.helpers.spec.js +92 -0
  69. package/lib/components/atoms/MAIAInput/MAIAInputEditor.spec.js +193 -0
  70. package/lib/components/atoms/MAIAInput/maiaInputLayout.spec.js +32 -0
  71. package/lib/components/atoms/MaiaStreamdown/MaiaStreamdown.spec.js +64 -0
  72. package/lib/components/atoms/MaiaWrapper/MaiaWrapper.spec.js +43 -0
  73. package/lib/components/atoms/MaiaWrapper/MaiaWrapperBase.js +9 -4
  74. package/lib/components/atoms/MaiaWrapper/MaiaWrapperBase.spec.js +114 -0
  75. package/lib/components/atoms/MaiaWrapper/ModernMaiaWrapper.spec.js +51 -0
  76. package/lib/components/atoms/ModalClientAccess/ModalClientAccess.spec.js +48 -0
  77. package/lib/components/atoms/ModalProject/ModalProject.spec.js +66 -0
  78. package/lib/components/atoms/NextPageLoader.spec.js +37 -0
  79. package/lib/components/atoms/OnboardingModalButton/OnboardingModal.spec.js +20 -0
  80. package/lib/components/atoms/OnboardingModalButton/OnboardingModalButton.helpers.spec.js +35 -0
  81. package/lib/components/atoms/OnboardingModalButton/OnboardingModalButton.spec.js +47 -0
  82. package/lib/components/atoms/OptionAccessibility/OptionAccessibility.js +4 -5
  83. package/lib/components/atoms/OptionAccessibility/OptionAccessibility.spec.js +146 -0
  84. package/lib/components/atoms/PrimaryButton.spec.js +42 -0
  85. package/lib/components/atoms/ProjectSelector/ProjectSelector.spec.js +69 -0
  86. package/lib/components/atoms/ReasoningBlock/ReasoningBlock.js +7 -2
  87. package/lib/components/atoms/ReasoningBlock/ReasoningBlock.spec.js +69 -0
  88. package/lib/components/atoms/ReasoningBlock/ReasoningBlock.styles.js +41 -24
  89. package/lib/components/atoms/ReasoningBlock/ReasoningSteps.js +25 -10
  90. package/lib/components/atoms/ReasoningBlock/ReasoningSteps.spec.js +59 -0
  91. package/lib/components/atoms/ReasoningBlock/ReasoningTimeline.js +78 -43
  92. package/lib/components/atoms/ReasoningBlock/ReasoningTimeline.spec.js +170 -0
  93. package/lib/components/atoms/ReasoningBlock/groupParallelSteps.js +9 -11
  94. package/lib/components/atoms/ReasoningBlock/groupParallelSteps.spec.js +199 -0
  95. package/lib/components/atoms/ReasoningBlock/reasoningLeading.spec.js +70 -0
  96. package/lib/components/atoms/ReasoningBlock/reasoningLiveNarration.js +37 -15
  97. package/lib/components/atoms/ReasoningBlock/reasoningLiveNarration.spec.js +120 -0
  98. package/lib/components/atoms/ReasoningBlock/reasoningMotion.js +8 -0
  99. package/lib/components/atoms/ReasoningBlock/reasoningTimeline.helpers.spec.js +31 -0
  100. package/lib/components/atoms/ReasoningBlock/useCollapsibleHeight.js +52 -0
  101. package/lib/components/atoms/ReasoningBlock/useCollapsibleHeight.spec.js +90 -0
  102. package/lib/components/atoms/ReasoningBlock/useReasoningMarkerHandoff.js +29 -0
  103. package/lib/components/atoms/ReasoningBlock/useReasoningMarkerHandoff.spec.js +38 -0
  104. package/lib/components/atoms/SessionGeneratingDot/SessionGeneratingDot.spec.js +16 -0
  105. package/lib/components/atoms/SkillsDropdown/SkillsDropdown.spec.js +107 -0
  106. package/lib/components/atoms/SlashCommandChip/SlashCommandChip.spec.js +24 -0
  107. package/lib/components/atoms/SlashCommandDropdown/SlashCommandDropdown.helpers.spec.js +71 -0
  108. package/lib/components/atoms/SlashCommandDropdown/SlashCommandDropdown.spec.js +120 -0
  109. package/lib/components/atoms/Switch/Switch.spec.js +41 -0
  110. package/lib/components/atoms/TextArea/CustomTextArea.spec.js +52 -0
  111. package/lib/components/atoms/TextArea/TextArea.helpers.spec.js +25 -0
  112. package/lib/components/atoms/TextArea/TextArea.spec.js +126 -0
  113. package/lib/components/atoms/ThirdButton.spec.js +29 -0
  114. package/lib/components/atoms/VideoModal/VideoModal.spec.js +68 -0
  115. package/lib/components/atoms/WithAppCfg.spec.js +82 -0
  116. package/lib/components/index.js +2 -1
  117. package/lib/components/molecules/AbmSection/AbmAccessibilitySection/AbmAccessibilitySection.helpers.spec.js +53 -0
  118. package/lib/components/molecules/AbmSection/AbmAccessibilitySection/AbmAccessibilitySection.js +3 -2
  119. package/lib/components/molecules/AbmSection/AbmAccessibilitySection/AbmAccessibilitySection.spec.js +780 -0
  120. package/lib/components/molecules/AbmSection/AbmGeneralSection.helpers.spec.js +107 -0
  121. package/lib/components/molecules/AbmSection/AbmGeneralSection.spec.js +256 -0
  122. package/lib/components/molecules/AbmSection/AbmKnowledgeSection.helpers.js +6 -4
  123. package/lib/components/molecules/AbmSection/AbmKnowledgeSection.helpers.spec.js +175 -0
  124. package/lib/components/molecules/AbmSection/AbmKnowledgeSection.js +25 -16
  125. package/lib/components/molecules/AbmSection/AbmKnowledgeSection.spec.js +318 -0
  126. package/lib/components/molecules/AbmSection/AbmLoaderFiles.helpers.spec.js +50 -0
  127. package/lib/components/molecules/AbmSection/AbmLoaderFiles.spec.js +94 -0
  128. package/lib/components/molecules/AgentInputBlock/AgentInputBlockMessage.js +83 -0
  129. package/lib/components/molecules/AgentInputBlock/AgentInputBlockMessage.styles.js +30 -0
  130. package/lib/components/molecules/AgentInputBlock/index.js +5 -0
  131. package/lib/components/molecules/AgentInputBlock/resolveAgentInputBlock.js +52 -0
  132. package/lib/components/molecules/AgentInputBlock/resolveAgentInputBlock.spec.js +76 -0
  133. package/lib/components/molecules/AgentInputBlock/resolveLegacyContextSession.js +20 -0
  134. package/lib/components/molecules/AgentInputBlock/resolveLegacyContextSession.spec.js +34 -0
  135. package/lib/components/molecules/AgentInputBlock/useAgentChangeModelAction.js +36 -0
  136. package/lib/components/molecules/ChatAIClientSelector/ChatAIClientSelector.spec.js +66 -0
  137. package/lib/components/molecules/ChatAIContent/ChatAIContent.js +7 -3
  138. package/lib/components/molecules/ChatAIContent/ChatAIContent.spec.js +145 -0
  139. package/lib/components/molecules/ChatAIHistory/ChatAIHistory.spec.js +204 -0
  140. package/lib/components/molecules/ChatAIHome/ChatAIHome.helpers.spec.js +622 -0
  141. package/lib/components/molecules/ChatAIHome/ChatAIHome.js +93 -72
  142. package/lib/components/molecules/ChatAIHome/ChatAIHome.spec.js +264 -0
  143. package/lib/components/molecules/ChatAIHome/ChatAIHomeMaiaker.spec.js +86 -0
  144. package/lib/components/molecules/ChatAIHome/styles.js +85 -78
  145. package/lib/components/molecules/ChatAIMessages/ChatAICreateAgentActions.spec.js +104 -0
  146. package/lib/components/molecules/ChatAIMessages/ChatAIMessages.helpers.js +95 -3
  147. package/lib/components/molecules/ChatAIMessages/ChatAIMessages.helpers.spec.js +967 -0
  148. package/lib/components/molecules/ChatAIMessages/ChatAIMessages.js +136 -53
  149. package/lib/components/molecules/ChatAIMessages/ChatAIMessages.spec.js +646 -0
  150. package/lib/components/molecules/ChatAIMessages/ChatAISuggestions.spec.js +46 -0
  151. package/lib/components/molecules/ChatAIMessages/newStyles.js +32 -35
  152. package/lib/components/molecules/ChatAIModal/ChatAIModal.helpers.js +8 -1
  153. package/lib/components/molecules/ChatAIModal/ChatAIModal.helpers.spec.js +1395 -0
  154. package/lib/components/molecules/ChatAIModal/ChatAIModal.js +23 -8
  155. package/lib/components/molecules/ChatAIModal/ChatAIModal.spec.js +1434 -0
  156. package/lib/components/molecules/ChatAIModal/ChatAIModal.styles.js +3 -3
  157. package/lib/components/molecules/ChatAIModal/components/ChatAiAgentOptions/ChatAiAgentOptions.helpers.spec.js +33 -0
  158. package/lib/components/molecules/ChatAIModal/components/ChatAiAgentOptions/ChatAiAgentOptions.spec.js +116 -0
  159. package/lib/components/molecules/ChatAIModal/components/ChatAiModalFooter/ChatAiModalFooter.js +15 -153
  160. package/lib/components/molecules/ChatAIModal/components/ChatAiModalFooter/ChatAiModalFooter.spec.js +134 -0
  161. package/lib/components/molecules/ChatAIModal/components/ChatAiModalFooter/ChatAiModalFooter.styles.js +2 -26
  162. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.helpers.spec.js +142 -0
  163. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.js +63 -367
  164. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.spec.js +241 -0
  165. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.utils.js +69 -0
  166. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.utils.spec.js +144 -0
  167. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeaderAgentDropdown.js +95 -0
  168. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeaderAgentSelector.js +174 -0
  169. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeaderLayoutMenu.js +99 -0
  170. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeaderLayoutMenu.spec.js +65 -0
  171. package/lib/components/molecules/ChatAIModal/components/MaiaMinimizedPill/MaiaMinimizedPill.spec.js +37 -0
  172. package/lib/components/molecules/ChatAIModal/constants.spec.js +16 -0
  173. package/lib/components/molecules/ChatAIModal/floatingPanelMotion/FloatingPanelMotion.spec.js +22 -0
  174. package/lib/components/molecules/ChatAIModal/floatingPanelMotion/useFloatingPanelDragTilt.spec.js +67 -0
  175. package/lib/components/molecules/ChatAIModal/layout.spec.js +72 -0
  176. package/lib/components/molecules/ChatAIMultipleChoice/ChatAIMultipleChoice.js +108 -0
  177. package/lib/components/molecules/ChatAIMultipleChoice/ChatAIMultipleChoice.spec.js +102 -0
  178. package/lib/components/molecules/ChatAIMultipleChoice/ChatAIMultipleChoice.styles.js +77 -0
  179. package/lib/components/molecules/ChatAIMultipleChoice/ChatAIMultipleChoiceAnswer.js +62 -0
  180. package/lib/components/molecules/ChatAIMultipleChoice/ChatAIMultipleChoiceAnswer.spec.js +49 -0
  181. package/lib/components/molecules/ChatAIMultipleChoice/ChatAIMultipleChoiceAnswer.styles.js +26 -0
  182. package/lib/components/molecules/ChatAIMultipleChoice/index.js +3 -0
  183. package/lib/components/molecules/ChatAIMyAgents/ChatAIMyAgents.helpers.spec.js +93 -0
  184. package/lib/components/molecules/ChatAIMyAgents/ChatAIMyAgents.spec.js +297 -0
  185. package/lib/components/molecules/ChatAIMySkills/ChatAIMySkills.helpers.spec.js +62 -0
  186. package/lib/components/molecules/ChatAIMySkills/ChatAIMySkills.spec.js +221 -0
  187. package/lib/components/molecules/ChatAIProjectSelector/ChatAIProjectSelector.spec.js +66 -0
  188. package/lib/components/molecules/ChatFooter/ChatFooter.js +91 -5
  189. package/lib/components/molecules/ChatFooter/ChatFooter.spec.js +548 -0
  190. package/lib/components/molecules/ChatFooter/ChatFooterCorAccess.spec.js +10 -0
  191. package/lib/components/molecules/ChatFooter/ChatFooterFaqs.helpers.spec.js +104 -0
  192. package/lib/components/molecules/ChatFooter/ChatFooterFaqs.js +5 -2
  193. package/lib/components/molecules/ChatFooter/ChatFooterFaqs.spec.js +139 -0
  194. package/lib/components/molecules/ContextMentionInput/ContextMentionInput.spec.js +84 -0
  195. package/lib/components/molecules/MessageFeedback/MessageFeedback.spec.js +116 -0
  196. package/lib/components/molecules/ProjectSummaryChat/ProjectSummaryChat.spec.js +126 -0
  197. package/lib/components/molecules/ProjectSummaryConfig/ProjectSummaryConfig.spec.js +115 -0
  198. package/lib/components/molecules/ProjectSummaryContent/ProjectSummaryContent.spec.js +79 -0
  199. package/lib/components/molecules/ProjectSummaryModal/ProjectSummaryModal.spec.js +37 -0
  200. package/lib/components/molecules/Sidebar/Sidebar.helpers.spec.js +119 -0
  201. package/lib/components/molecules/Sidebar/Sidebar.js +41 -23
  202. package/lib/components/molecules/Sidebar/Sidebar.spec.js +526 -0
  203. package/lib/components/organisms/AbmAgentModal/AbmAgentModal.helpers.spec.js +1067 -0
  204. package/lib/components/organisms/AbmAgentModal/AbmAgentModal.js +2 -2
  205. package/lib/components/organisms/AbmAgentModal/AbmAgentModal.spec.js +1236 -0
  206. package/lib/components/organisms/AbmSkillGenerateModal/AbmSkillGenerateModal.spec.js +112 -0
  207. package/lib/components/organisms/AbmSkillModal/AbmSkillModal.helpers.spec.js +77 -0
  208. package/lib/components/organisms/AbmSkillModal/AbmSkillModal.spec.js +503 -0
  209. package/lib/components/organisms/ChatAI/ChatAI.spec.js +217 -0
  210. package/lib/components/organisms/ChatAIPage/ChatAIPage.js +525 -0
  211. package/lib/components/organisms/ChatAIPage/ChatAIPage.spec.js +246 -0
  212. package/lib/components/organisms/ChatAIPage/ChatAIPage.styles.js +16 -0
  213. package/lib/components/organisms/ChatAIPage/ChatAIPageHeader.js +253 -0
  214. package/lib/components/organisms/ChatAIPage/ChatAIPageHeader.spec.js +291 -0
  215. package/lib/components/organisms/ChatAIPage/ChatAIPageHeader.styles.js +13 -0
  216. package/lib/components/organisms/ChatAIPage/ChatAIPageHome.js +284 -0
  217. package/lib/components/organisms/ChatAIPage/ChatAIPageHome.spec.js +343 -0
  218. package/lib/components/organisms/ChatAIPage/ChatAIPageHome.styles.js +197 -0
  219. package/lib/components/organisms/ChatAIPage/ChatAIPageHomeActionCardSlot.js +94 -0
  220. package/lib/components/organisms/ChatAIPage/ChatAIPageHomeActionCardSlot.spec.js +69 -0
  221. package/lib/components/organisms/ChatAIPage/ChatAIPageHomeActionCards.skeleton.js +38 -0
  222. package/lib/components/organisms/ChatAIPage/getDaypart.js +9 -0
  223. package/lib/components/organisms/ChatAIPage/getDaypart.spec.js +19 -0
  224. package/lib/components/organisms/ChatAIPage/index.js +3 -0
  225. package/lib/components/organisms/ClientAIButton/ClientAIButton.spec.js +53 -0
  226. package/lib/components/organisms/DeleteAgentModal/DeleteAgentModal.spec.js +59 -0
  227. package/lib/components/organisms/DeleteQuestionModal/DeleteQuestionModal.spec.js +79 -0
  228. package/lib/components/organisms/EditQuestionModal/EditQuestionModal.spec.js +86 -0
  229. package/lib/components/organisms/ModalFileExceeds/ModalFileExceeds.spec.js +49 -0
  230. package/lib/components/organisms/ProjectAIButton/ProjectAIButton.spec.js +67 -0
  231. package/lib/components/organisms/ProjectSummary/ProjectSummary.js +11 -7
  232. package/lib/components/organisms/ProjectSummary/ProjectSummary.spec.js +117 -0
  233. package/lib/components/organisms/SnackBar/Snackbar.spec.js +66 -0
  234. package/lib/components/organisms/SourcesInformation/SourceItem.spec.js +19 -0
  235. package/lib/components/organisms/SourcesInformation/SourcesInformationModal.js +4 -1
  236. package/lib/components/organisms/SourcesInformation/SourcesInformationModal.spec.js +52 -0
  237. package/lib/constants/formatExtensions.spec.js +15 -0
  238. package/lib/constants/maiaExternalConnectorsAccess.spec.js +29 -0
  239. package/lib/constants/maiaFeatureAccess.spec.js +30 -0
  240. package/lib/constants/maiaHourAgentAccess.spec.js +30 -0
  241. package/lib/constants/maiaTaskPanelAccess.spec.js +41 -0
  242. package/lib/constants/permissions/clientRoleAccess.spec.js +65 -0
  243. package/lib/constants/permissions/index.js +2 -2
  244. package/lib/constants/permissions/utils.js +4 -1
  245. package/lib/constants/permissions/utils.spec.js +128 -0
  246. package/lib/constants/plannerSyncEvents.spec.js +31 -0
  247. package/lib/constants/taskUrls.spec.js +9 -0
  248. package/lib/dev/DevMaiaPage.js +30 -0
  249. package/lib/dev/DevReasoningTimeline.js +68 -37
  250. package/lib/dev/Providers.js +5 -3
  251. package/lib/hooks/frequentlyUsedActionsCache.js +17 -0
  252. package/lib/hooks/frequentlyUsedActionsCache.spec.js +25 -0
  253. package/lib/hooks/useAccessClient/useAccessClient.spec.js +149 -0
  254. package/lib/hooks/useAgentModel/useAgentModel.spec.js +83 -0
  255. package/lib/hooks/useAgentModel/useCreateAgent.helpers.spec.js +268 -0
  256. package/lib/hooks/useAgentModel/useCreateAgent.spec.js +314 -0
  257. package/lib/hooks/useAgentModel/useDeleteAgent.spec.js +183 -0
  258. package/lib/hooks/useAgentModel/useUpdateAgent.js +7 -6
  259. package/lib/hooks/useAgentModel/useUpdateAgent.spec.js +374 -0
  260. package/lib/hooks/useAgentSuggestions.spec.js +89 -0
  261. package/lib/hooks/useCaretPosition.spec.js +58 -0
  262. package/lib/hooks/useChatManager/useChatManager.helpers.js +8 -5
  263. package/lib/hooks/useChatManager/useChatManager.helpers.spec.js +2027 -0
  264. package/lib/hooks/useChatManager/useChatManager.js +53 -35
  265. package/lib/hooks/useChatManager/useChatManager.spec.js +2467 -0
  266. package/lib/hooks/useChatMessages/useChatMessages.helpers.spec.js +491 -0
  267. package/lib/hooks/useChatMessages/useChatMessages.spec.js +729 -0
  268. package/lib/hooks/useChats/useChats.spec.js +208 -0
  269. package/lib/hooks/useClientSearch.helpers.spec.js +52 -0
  270. package/lib/hooks/useClientSearch.spec.js +86 -0
  271. package/lib/hooks/useContextMentions.helpers.spec.js +267 -0
  272. package/lib/hooks/useContextMentions.spec.js +338 -0
  273. package/lib/hooks/useContextPinPopover.helpers.spec.js +183 -0
  274. package/lib/hooks/useContextPinPopover.spec.js +159 -0
  275. package/lib/hooks/useContinueLegacyContextInNewChat/index.js +2 -0
  276. package/lib/hooks/useContinueLegacyContextInNewChat/useContinueLegacyContextInNewChat.js +93 -0
  277. package/lib/hooks/useContinueLegacyContextInNewChat/useContinueLegacyContextInNewChat.spec.js +257 -0
  278. package/lib/hooks/useDebounce.spec.js +42 -0
  279. package/lib/hooks/useEntitySearch.helpers.spec.js +723 -0
  280. package/lib/hooks/useEntitySearch.js +3 -1
  281. package/lib/hooks/useEntitySearch.spec.js +718 -0
  282. package/lib/hooks/useEvent.js +3 -1
  283. package/lib/hooks/useEvent.spec.js +45 -0
  284. package/lib/hooks/useFrequentlyAskedQuestions.spec.js +222 -0
  285. package/lib/hooks/useFrequentlyUsedActions.js +61 -22
  286. package/lib/hooks/useFrequentlyUsedActions.spec.js +293 -0
  287. package/lib/hooks/useIsMaiaPageRoute.spec.js +26 -0
  288. package/lib/hooks/useKnowledge/deleteKnowledge.spec.js +122 -0
  289. package/lib/hooks/useKnowledge/downloadKnowledge.js +4 -4
  290. package/lib/hooks/useKnowledge/downloadKnowledge.spec.js +148 -0
  291. package/lib/hooks/useKnowledge/saveKnowledge.spec.js +104 -0
  292. package/lib/hooks/useKnowledge/useKnowledgeOperations.js +16 -15
  293. package/lib/hooks/useKnowledge/useKnowledgeOperations.spec.js +178 -0
  294. package/lib/hooks/useLatestRef.js +15 -0
  295. package/lib/hooks/useLatestRef.spec.js +50 -0
  296. package/lib/hooks/useMaiaChatSessionMeta/index.js +2 -0
  297. package/lib/hooks/useMaiaChatSessionMeta/useMaiaChatSessionMeta.js +24 -0
  298. package/lib/hooks/useMentionAllowedTypes.spec.js +89 -0
  299. package/lib/hooks/useMentionPopover.helpers.spec.js +100 -0
  300. package/lib/hooks/useMentionPopover.spec.js +392 -0
  301. package/lib/hooks/useMinimizedPillBottomOffset.helpers.spec.js +176 -0
  302. package/lib/hooks/useMinimizedPillBottomOffset.spec.js +89 -0
  303. package/lib/hooks/useMinimizedPillNoveltyDot/useMinimizedPillNoveltyDot.spec.js +67 -0
  304. package/lib/hooks/useModal/useModal.spec.js +73 -0
  305. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.helpers.js +4 -2
  306. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.helpers.spec.js +138 -0
  307. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.interface.js +1 -1
  308. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.js +3 -3
  309. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.spec.js +485 -0
  310. package/lib/hooks/useProjectSearch.helpers.spec.js +89 -0
  311. package/lib/hooks/useProjectSearch.spec.js +91 -0
  312. package/lib/hooks/useProjectSummary.spec.js +193 -0
  313. package/lib/hooks/useProjectSummaryConfig.helpers.spec.js +151 -0
  314. package/lib/hooks/useProjectSummaryConfig.js +10 -5
  315. package/lib/hooks/useProjectSummaryConfig.spec.js +133 -0
  316. package/lib/hooks/useReasoningTrace/reasoningStore.spec.js +112 -0
  317. package/lib/hooks/useRecentClientsSearch.helpers.spec.js +33 -0
  318. package/lib/hooks/useRecentClientsSearch.spec.js +85 -0
  319. package/lib/hooks/useRecentContexts.spec.js +139 -0
  320. package/lib/hooks/useResize.spec.js +37 -0
  321. package/lib/hooks/useSkillsCatalog.spec.js +88 -0
  322. package/lib/hooks/useSlashCommands.spec.js +139 -0
  323. package/lib/hooks/useSmoothStreamText/useSmoothStreamText.spec.js +101 -0
  324. package/lib/hooks/useSnackBarManager/useSnackBarManager.spec.js +33 -0
  325. package/lib/hooks/useStreamResponse.spec.js +199 -0
  326. package/lib/hooks/useT.spec.js +20 -0
  327. package/lib/hooks/useToggle.spec.js +33 -0
  328. package/lib/hooks/useToggleFavorite/useToggleFavorite.spec.js +171 -0
  329. package/lib/index.js +5 -2
  330. package/lib/lang/br/index.js +32 -1
  331. package/lib/lang/en/index.js +32 -1
  332. package/lib/lang/es/index.js +32 -1
  333. package/lib/lang/fr/index.js +32 -1
  334. package/lib/services/appcues.spec.js +37 -0
  335. package/lib/services/maia/Access/updateAccess.spec.js +137 -0
  336. package/lib/services/maia/Actions/getFrequentlyUsedActions.js +1 -1
  337. package/lib/services/maia/Actions/getFrequentlyUsedActions.spec.js +121 -0
  338. package/lib/services/maia/Actions/getSlashCommands.spec.js +91 -0
  339. package/lib/services/maia/Agents/connectors.js +3 -1
  340. package/lib/services/maia/Agents/connectors.spec.js +496 -0
  341. package/lib/services/maia/Agents/createAgent.spec.js +55 -0
  342. package/lib/services/maia/Agents/deleteAgent.spec.js +57 -0
  343. package/lib/services/maia/Agents/fetchAgentDetail.spec.js +108 -0
  344. package/lib/services/maia/Agents/getAgentById.spec.js +190 -0
  345. package/lib/services/maia/Agents/getAgentModels.spec.js +190 -0
  346. package/lib/services/maia/Agents/getAgentSuggestions.spec.js +89 -0
  347. package/lib/services/maia/Agents/getAgents.helpers.spec.js +325 -0
  348. package/lib/services/maia/Agents/getAgents.spec.js +1135 -0
  349. package/lib/services/maia/Agents/setAgentToolGroups.spec.js +45 -0
  350. package/lib/services/maia/Agents/toggleFavorite.spec.js +59 -0
  351. package/lib/services/maia/Agents/updateAgent.spec.js +48 -0
  352. package/lib/services/maia/Chats/deleteChat.spec.js +31 -0
  353. package/lib/services/maia/Chats/getChatMessages.spec.js +150 -0
  354. package/lib/services/maia/Chats/getChatsByUserId.spec.js +181 -0
  355. package/lib/services/maia/Chats/markSessionAsRead.spec.js +30 -0
  356. package/lib/services/maia/Chats/patchChat.spec.js +41 -0
  357. package/lib/services/maia/Chats/wasHelpfulChat.spec.js +28 -0
  358. package/lib/services/maia/Faqs/getFrequentlyAskedQuestions.spec.js +58 -0
  359. package/lib/services/maia/Knowledge/delete.spec.js +45 -0
  360. package/lib/services/maia/Knowledge/download.spec.js +78 -0
  361. package/lib/services/maia/Knowledge/save.spec.js +58 -0
  362. package/lib/services/maia/Orchestrator/orchestrator.helpers.js +11 -6
  363. package/lib/services/maia/Orchestrator/orchestrator.helpers.spec.js +261 -0
  364. package/lib/services/maia/Orchestrator/orchestrator.js +5 -4
  365. package/lib/services/maia/Orchestrator/orchestrator.spec.js +181 -0
  366. package/lib/services/maia/RecentClients/getRecentClients.spec.js +52 -0
  367. package/lib/services/maia/RecentContexts/getRecentContexts.spec.js +103 -0
  368. package/lib/services/maia/RecentProjects/getRecentProjects.spec.js +82 -0
  369. package/lib/services/maia/RecentTasks/getRecentTasks.spec.js +63 -0
  370. package/lib/services/maia/RecentUsers/getRecentUsers.spec.js +82 -0
  371. package/lib/services/maia/Skills/createSkill.spec.js +68 -0
  372. package/lib/services/maia/Skills/deleteSkill.spec.js +42 -0
  373. package/lib/services/maia/Skills/generateSkill.spec.js +48 -0
  374. package/lib/services/maia/Skills/getSkills.spec.js +152 -0
  375. package/lib/services/maia/Skills/updateSkill.spec.js +62 -0
  376. package/lib/services/maia/client.spec.js +56 -0
  377. package/lib/services/utils/fetchCOR.spec.js +211 -0
  378. package/lib/services/utils/getCookie.spec.js +20 -0
  379. package/lib/services/utils/mapChatMessages.helpers.js +6 -3
  380. package/lib/services/utils/mapChatMessages.helpers.spec.js +336 -0
  381. package/lib/services/utils/mapChatMessages.multipleChoice.spec.js +87 -0
  382. package/lib/services/utils/mapChatMessages.spec.js +254 -0
  383. package/lib/store/chatsSidebarOptimistic.spec.js +145 -0
  384. package/lib/store/maiaLastChatPersistence.spec.js +22 -0
  385. package/lib/store/maiaPanelSessionPersistence.spec.js +62 -0
  386. package/lib/store/sessions/sessionNotificationSound.spec.js +145 -0
  387. package/lib/store/sessions/sessionNotifications.helpers.spec.js +63 -0
  388. package/lib/store/sessions/sessionNotifications.spec.js +106 -0
  389. package/lib/store/sessions/sessionStreamManager.helpers.js +7 -1
  390. package/lib/store/sessions/sessionStreamManager.helpers.spec.js +177 -0
  391. package/lib/store/sessions/sessionStreamManager.js +51 -55
  392. package/lib/store/sessions/sessionStreamManager.spec.js +939 -0
  393. package/lib/store/sessions/sessions.types.js +1 -1
  394. package/lib/store/sessions/sessions.types.spec.js +16 -0
  395. package/lib/store/sessions/useSessionsStore.spec.js +135 -0
  396. package/lib/store/useChatsStore.js +4 -3
  397. package/lib/store/useChatsStore.spec.js +690 -0
  398. package/lib/store/useFaqsStore.spec.js +57 -0
  399. package/lib/store/useMultipleChoiceStore.js +47 -0
  400. package/lib/store/useMultipleChoiceStore.spec.js +44 -0
  401. package/lib/styles/cascade.js +29 -3
  402. package/lib/styles/transitions.js +3 -1
  403. package/lib/types/Chat.js +3 -1
  404. package/lib/types/global.d.js +1 -1
  405. package/lib/utils/actionCategoryMap.spec.js +18 -0
  406. package/lib/utils/agentDisplayName.spec.js +48 -0
  407. package/lib/utils/autoApproveStorage.spec.js +25 -0
  408. package/lib/utils/chatInputFiles.spec.js +39 -0
  409. package/lib/utils/contextMentionIcons.spec.js +41 -0
  410. package/lib/utils/contextMentionLabel.spec.js +13 -0
  411. package/lib/utils/contextMentionTriggers.spec.js +44 -0
  412. package/lib/utils/contextMentionTypeLabel.spec.js +14 -0
  413. package/lib/utils/corConnectorMentionTypes.spec.js +23 -0
  414. package/lib/utils/entityLinkRender.spec.js +72 -0
  415. package/lib/utils/fileDownloadHelper.spec.js +67 -0
  416. package/lib/utils/formatQuickActionMessage.spec.js +27 -0
  417. package/lib/utils/formatUnreadCount.spec.js +12 -0
  418. package/lib/utils/getUnitFileSize.spec.js +18 -0
  419. package/lib/utils/hitlAnalytics.spec.js +136 -0
  420. package/lib/utils/hoursPlannerQuickActionType.js +116 -1
  421. package/lib/utils/hoursPlannerQuickActionType.spec.js +124 -0
  422. package/lib/utils/imagePreprocessor.helpers.spec.js +28 -0
  423. package/lib/utils/imagePreprocessor.js +14 -3
  424. package/lib/utils/imagePreprocessor.spec.js +112 -0
  425. package/lib/utils/maiaPageRoute.spec.js +23 -0
  426. package/lib/utils/mapBackendLang.spec.js +19 -0
  427. package/lib/utils/navigateContextEntity.js +2 -2
  428. package/lib/utils/navigateContextEntity.spec.js +50 -0
  429. package/lib/utils/normalizeAgentConnectors.spec.js +98 -0
  430. package/lib/utils/openTaskInCorPanel.js +2 -2
  431. package/lib/utils/openTaskInCorPanel.spec.js +43 -0
  432. package/lib/utils/orchestratorSubagents.spec.js +32 -0
  433. package/lib/utils/reasoningMappers.spec.js +103 -0
  434. package/lib/utils/recentContextsHomeLimit.spec.js +32 -0
  435. package/lib/utils/renderContextMentions.helpers.spec.js +87 -0
  436. package/lib/utils/renderContextMentions.spec.js +268 -0
  437. package/lib/utils/retryCompletion.spec.js +181 -0
  438. package/lib/utils/skillContentSize.spec.js +13 -0
  439. package/lib/utils/slashCommandMarker.spec.js +43 -0
  440. package/lib/utils/sortManagerHoursHomeFuas.spec.js +51 -0
  441. package/lib/utils/sseStreamContent.spec.js +31 -0
  442. package/lib/utils/streamActivityMessages.helpers.js +5 -4
  443. package/lib/utils/streamActivityMessages.helpers.spec.js +84 -0
  444. package/lib/utils/streamActivityMessages.js +32 -20
  445. package/lib/utils/streamActivityMessages.spec.js +336 -0
  446. package/lib/utils/validateTrimmedFields.spec.js +26 -0
  447. package/package.json +1 -1
  448. package/README.md +0 -2
@@ -0,0 +1,2467 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
6
+ import { act, renderHook } from '@testing-library/react';
7
+ import { GlobalContextTestProvider, testAgent } from '../../test/global-context';
8
+ import { useSessionsStore } from '../../store/sessions/useSessionsStore';
9
+ import { sessionStreamManager } from '../../store/sessions/sessionStreamManager';
10
+ import { ChatHistoryRole } from '../../types/Chat';
11
+ import { Feedback } from '../../components/molecules/MessageFeedback/MessageFeedback';
12
+ import maia from '../../services/maia';
13
+ import { activeView } from '../../store/sessions/activeView';
14
+ import { useOrchestratorStream } from '../useOrchestratorStream';
15
+ import { getChatsStoreState } from '../../store/useChatsStore';
16
+ import { notifySessionFinishedInBackground } from '../../store/sessions/sessionNotifications';
17
+ import { fetchAgentDetail } from '../../services/maia/Agents/fetchAgentDetail';
18
+ import { MAIA_HOURS_CHARGED_EVENT } from '../../constants/plannerSyncEvents';
19
+ import { streamingPlaceholderMessageId } from '../../utils/streamActivityMessages';
20
+ import { useMultipleChoiceStore } from '../../store/useMultipleChoiceStore';
21
+ import { useChatManager } from './useChatManager';
22
+ import { jsx as _jsx } from "react/jsx-runtime";
23
+ var fetchAgentDetailMock = fetchAgentDetail;
24
+ var mockUseOrchestratorStream = useOrchestratorStream;
25
+ var streamCallbacks = {};
26
+ var startContinueStreamMock = jest.fn().mockResolvedValue({
27
+ started: true
28
+ });
29
+ var askMaiaMock = jest.fn().mockResolvedValue({
30
+ started: true
31
+ });
32
+ var retryCompletionMock = jest.fn().mockResolvedValue({
33
+ started: true
34
+ });
35
+ var stopStreamingMock = jest.fn();
36
+ var replaceMessagesMock = jest.fn();
37
+ var addMessageMock = jest.fn();
38
+ var eventMock = jest.fn();
39
+ var chatMessagesState = {
40
+ loadingMessages: false,
41
+ messages: [],
42
+ isLoadingMoreMessages: false,
43
+ loadMessages: jest.fn(),
44
+ addMessage: addMessageMock,
45
+ removeMessage: jest.fn(),
46
+ replaceMessages: replaceMessagesMock,
47
+ handleScroll: jest.fn()
48
+ };
49
+ jest.mock('../useChatMessages', function () {
50
+ return {
51
+ useChatMessages: function useChatMessages() {
52
+ return chatMessagesState;
53
+ }
54
+ };
55
+ });
56
+ jest.mock('../useOrchestratorStream', function () {
57
+ return {
58
+ useOrchestratorStream: jest.fn()
59
+ };
60
+ });
61
+ jest.mock('../useProjects', function () {
62
+ return {
63
+ useProjects: function useProjects() {
64
+ return {
65
+ fetchProjects: jest.fn().mockResolvedValue([])
66
+ };
67
+ }
68
+ };
69
+ });
70
+ jest.mock('../useTabTaskDefault', function () {
71
+ return {
72
+ useTabTaskDefault: function useTabTaskDefault() {
73
+ return {
74
+ getTabTaskDefault: jest.fn().mockResolvedValue('detail')
75
+ };
76
+ }
77
+ };
78
+ });
79
+ jest.mock('../useEvent', function () {
80
+ return {
81
+ EVENTS: {
82
+ pmAiTypedText: 'PM_AI_TYPED_TEXT'
83
+ },
84
+ useEvent: function useEvent() {
85
+ return eventMock;
86
+ }
87
+ };
88
+ });
89
+ jest.mock('../../context/cor-user', function () {
90
+ return {
91
+ useUser: function useUser() {
92
+ return {
93
+ id: 7,
94
+ firstName: 'Ana',
95
+ lastName: 'García',
96
+ picture: 'pic.png',
97
+ lang: 'es',
98
+ company_id: 10
99
+ };
100
+ }
101
+ };
102
+ });
103
+ jest.mock('../../store/useChatsStore', function () {
104
+ var state = {
105
+ setActiveChatId: jest.fn(),
106
+ markChatAsRead: jest.fn(),
107
+ markChatAsUnread: jest.fn(),
108
+ isChatViewVisible: true,
109
+ chats: [],
110
+ prependChat: jest.fn()
111
+ };
112
+ var useChatsStore = function useChatsStore(selector) {
113
+ return selector(state);
114
+ };
115
+ Object.assign(useChatsStore, {
116
+ getState: function getState() {
117
+ return state;
118
+ }
119
+ });
120
+ return {
121
+ useChatsStore: useChatsStore,
122
+ getChatsStoreState: function getChatsStoreState() {
123
+ return state;
124
+ }
125
+ };
126
+ });
127
+ jest.mock('../../services/maia', function () {
128
+ return {
129
+ __esModule: true,
130
+ "default": {
131
+ Chats: {
132
+ wasHelpfulChat: jest.fn()
133
+ }
134
+ }
135
+ };
136
+ });
137
+ jest.mock('../../services/maia/Agents/fetchAgentDetail', function () {
138
+ return {
139
+ fetchAgentDetail: jest.fn()
140
+ };
141
+ });
142
+ jest.mock('../../store/sessions/sessionNotifications', function () {
143
+ return {
144
+ notifySessionFinishedInBackground: jest.fn(),
145
+ ensureSessionNotificationsInitialized: jest.fn()
146
+ };
147
+ });
148
+ jest.mock('../../store/sessions/sessionStreamManager', function () {
149
+ return {
150
+ sessionStreamManager: {
151
+ isActive: jest.fn(function () {
152
+ return false;
153
+ }),
154
+ getActiveCount: jest.fn(function () {
155
+ return 0;
156
+ }),
157
+ startStream: jest.fn(),
158
+ startContinueStream: function startContinueStream() {
159
+ return startContinueStreamMock.apply(void 0, arguments);
160
+ },
161
+ stopStream: jest.fn()
162
+ },
163
+ MAX_CONCURRENT_STREAMS: 3
164
+ };
165
+ });
166
+ var wrapper = function wrapper(_ref) {
167
+ var children = _ref.children;
168
+ return /*#__PURE__*/_jsx(GlobalContextTestProvider, {
169
+ value: {
170
+ agent: testAgent
171
+ },
172
+ children: children
173
+ });
174
+ };
175
+ describe('useChatManager', function () {
176
+ beforeEach(function () {
177
+ jest.clearAllMocks();
178
+ streamCallbacks = {};
179
+ mockUseOrchestratorStream.mockImplementation(function (options) {
180
+ streamCallbacks = {
181
+ onError: options.onError,
182
+ onStreamUpdate: options.onStreamUpdate,
183
+ onStop: options.onStop,
184
+ onApprovalRequired: options.onApprovalRequired,
185
+ onFinishStream: options.onFinishStream
186
+ };
187
+ return {
188
+ askMaia: askMaiaMock,
189
+ retryCompletion: retryCompletionMock,
190
+ isLoading: false,
191
+ isWriting: false,
192
+ loadingMessage: '',
193
+ streamActivity: null,
194
+ updateStreamActivity: jest.fn(),
195
+ stopStreaming: stopStreamingMock
196
+ };
197
+ });
198
+ chatMessagesState.loadingMessages = false;
199
+ chatMessagesState.messages = [];
200
+ useSessionsStore.setState({
201
+ meta: {},
202
+ messages: {},
203
+ viewCache: {}
204
+ });
205
+ activeView.set(null);
206
+ sessionStreamManager.isActive.mockReturnValue(false);
207
+ sessionStreamManager.getActiveCount.mockReturnValue(0);
208
+ startContinueStreamMock.mockResolvedValue({
209
+ started: true
210
+ });
211
+ askMaiaMock.mockResolvedValue({
212
+ started: true
213
+ });
214
+ retryCompletionMock.mockResolvedValue({
215
+ started: true
216
+ });
217
+ });
218
+ it('starts with empty messages and send enabled', function () {
219
+ var _renderHook = renderHook(function () {
220
+ return useChatManager({
221
+ chatId: 'session-1',
222
+ agents: [testAgent]
223
+ });
224
+ }, {
225
+ wrapper: wrapper
226
+ }),
227
+ result = _renderHook.result;
228
+ expect(result.current.messages).toEqual([]);
229
+ expect(result.current.isDisabled).toBe(false);
230
+ });
231
+ it('sendMessage delegates to askMaia with the current session', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
232
+ var _renderHook2, result;
233
+ return _regeneratorRuntime.wrap(function (_context2) {
234
+ while (1) switch (_context2.prev = _context2.next) {
235
+ case 0:
236
+ _renderHook2 = renderHook(function () {
237
+ return useChatManager({
238
+ chatId: 'session-1',
239
+ agents: [testAgent]
240
+ });
241
+ }, {
242
+ wrapper: wrapper
243
+ }), result = _renderHook2.result;
244
+ _context2.next = 1;
245
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
246
+ return _regeneratorRuntime.wrap(function (_context) {
247
+ while (1) switch (_context.prev = _context.next) {
248
+ case 0:
249
+ _context.next = 1;
250
+ return result.current.sendMessage('Hola MAIA');
251
+ case 1:
252
+ case "end":
253
+ return _context.stop();
254
+ }
255
+ }, _callee);
256
+ })));
257
+ case 1:
258
+ expect(askMaiaMock).toHaveBeenCalledWith(expect.objectContaining({
259
+ message: 'Hola MAIA',
260
+ chatId: 'session-1',
261
+ agentId: testAgent.id,
262
+ agentName: testAgent.name
263
+ }));
264
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
265
+ message: 'Hola MAIA',
266
+ role: 'user'
267
+ }));
268
+ case 2:
269
+ case "end":
270
+ return _context2.stop();
271
+ }
272
+ }, _callee2);
273
+ })));
274
+ it('marks the message that answers a multiple-choice card and consumes the answer', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
275
+ var _renderHook3, result;
276
+ return _regeneratorRuntime.wrap(function (_context4) {
277
+ while (1) switch (_context4.prev = _context4.next) {
278
+ case 0:
279
+ useMultipleChoiceStore.setState({
280
+ pending: {
281
+ messageId: 'a1',
282
+ question: null,
283
+ options: []
284
+ },
285
+ answer: null,
286
+ dismissedMessageIds: {}
287
+ });
288
+ useMultipleChoiceStore.getState().answerPending({
289
+ key: 'B'
290
+ });
291
+ _renderHook3 = renderHook(function () {
292
+ return useChatManager({
293
+ chatId: 'session-1',
294
+ agents: [testAgent]
295
+ });
296
+ }, {
297
+ wrapper: wrapper
298
+ }), result = _renderHook3.result;
299
+ _context4.next = 1;
300
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
301
+ return _regeneratorRuntime.wrap(function (_context3) {
302
+ while (1) switch (_context3.prev = _context3.next) {
303
+ case 0:
304
+ _context3.next = 1;
305
+ return result.current.sendMessage('Proyecto Beta');
306
+ case 1:
307
+ case "end":
308
+ return _context3.stop();
309
+ }
310
+ }, _callee3);
311
+ })));
312
+ case 1:
313
+ expect(askMaiaMock).toHaveBeenLastCalledWith(expect.objectContaining({
314
+ multipleChoiceAnswer: {
315
+ key: 'B'
316
+ }
317
+ }));
318
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
319
+ message: 'Proyecto Beta',
320
+ multipleChoiceAnswer: {
321
+ key: 'B'
322
+ }
323
+ }));
324
+ expect(useMultipleChoiceStore.getState().answer).toBeNull();
325
+ case 2:
326
+ case "end":
327
+ return _context4.stop();
328
+ }
329
+ }, _callee4);
330
+ })));
331
+ it('does not send when the concurrent stream limit is reached', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
332
+ var dispatchSpy, _renderHook4, result;
333
+ return _regeneratorRuntime.wrap(function (_context6) {
334
+ while (1) switch (_context6.prev = _context6.next) {
335
+ case 0:
336
+ ;
337
+ sessionStreamManager.getActiveCount.mockReturnValue(3);
338
+ dispatchSpy = jest.spyOn(document, 'dispatchEvent');
339
+ _renderHook4 = renderHook(function () {
340
+ return useChatManager({
341
+ chatId: 'session-1',
342
+ agents: [testAgent]
343
+ });
344
+ }, {
345
+ wrapper: wrapper
346
+ }), result = _renderHook4.result;
347
+ _context6.next = 1;
348
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
349
+ return _regeneratorRuntime.wrap(function (_context5) {
350
+ while (1) switch (_context5.prev = _context5.next) {
351
+ case 0:
352
+ _context5.next = 1;
353
+ return result.current.sendMessage('Hola');
354
+ case 1:
355
+ case "end":
356
+ return _context5.stop();
357
+ }
358
+ }, _callee5);
359
+ })));
360
+ case 1:
361
+ expect(askMaiaMock).not.toHaveBeenCalled();
362
+ expect(dispatchSpy).toHaveBeenCalledWith(expect.objectContaining({
363
+ type: 'snackbar-event'
364
+ }));
365
+ dispatchSpy.mockRestore();
366
+ case 2:
367
+ case "end":
368
+ return _context6.stop();
369
+ }
370
+ }, _callee6);
371
+ })));
372
+ it('stopGeneration stops the active stream', function () {
373
+ var _renderHook5 = renderHook(function () {
374
+ return useChatManager({
375
+ chatId: 'session-1',
376
+ agents: [testAgent]
377
+ });
378
+ }, {
379
+ wrapper: wrapper
380
+ }),
381
+ result = _renderHook5.result;
382
+ act(function () {
383
+ result.current.stopGeneration();
384
+ });
385
+ expect(stopStreamingMock).toHaveBeenCalled();
386
+ });
387
+ it('resetChat clears the active chat id in the store hook path', function () {
388
+ var _renderHook6 = renderHook(function () {
389
+ return useChatManager({
390
+ chatId: 'session-1',
391
+ agents: [testAgent]
392
+ });
393
+ }, {
394
+ wrapper: wrapper
395
+ }),
396
+ result = _renderHook6.result;
397
+ act(function () {
398
+ result.current.resetChat();
399
+ });
400
+ expect(result.current.currentChatId).not.toBe('session-1');
401
+ });
402
+ it('does not send while messages are loading', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
403
+ var _renderHook7, result;
404
+ return _regeneratorRuntime.wrap(function (_context8) {
405
+ while (1) switch (_context8.prev = _context8.next) {
406
+ case 0:
407
+ chatMessagesState.loadingMessages = true;
408
+ _renderHook7 = renderHook(function () {
409
+ return useChatManager({
410
+ chatId: 'session-1',
411
+ agents: [testAgent]
412
+ });
413
+ }, {
414
+ wrapper: wrapper
415
+ }), result = _renderHook7.result;
416
+ expect(result.current.isDisabled).toBe(true);
417
+ _context8.next = 1;
418
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
419
+ return _regeneratorRuntime.wrap(function (_context7) {
420
+ while (1) switch (_context7.prev = _context7.next) {
421
+ case 0:
422
+ _context7.next = 1;
423
+ return result.current.sendMessage('Hola');
424
+ case 1:
425
+ case "end":
426
+ return _context7.stop();
427
+ }
428
+ }, _callee7);
429
+ })));
430
+ case 1:
431
+ expect(askMaiaMock).not.toHaveBeenCalled();
432
+ case 2:
433
+ case "end":
434
+ return _context8.stop();
435
+ }
436
+ }, _callee8);
437
+ })));
438
+ it('includes context mentions when they are sent via options', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee0() {
439
+ var _renderHook8, result;
440
+ return _regeneratorRuntime.wrap(function (_context0) {
441
+ while (1) switch (_context0.prev = _context0.next) {
442
+ case 0:
443
+ _renderHook8 = renderHook(function () {
444
+ return useChatManager({
445
+ chatId: 'session-1',
446
+ agents: [testAgent]
447
+ });
448
+ }, {
449
+ wrapper: wrapper
450
+ }), result = _renderHook8.result;
451
+ _context0.next = 1;
452
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
453
+ return _regeneratorRuntime.wrap(function (_context9) {
454
+ while (1) switch (_context9.prev = _context9.next) {
455
+ case 0:
456
+ _context9.next = 1;
457
+ return result.current.sendMessage('Hola', {
458
+ mentions: [{
459
+ id: 'u1',
460
+ type: 'user',
461
+ label: 'Ana'
462
+ }]
463
+ });
464
+ case 1:
465
+ case "end":
466
+ return _context9.stop();
467
+ }
468
+ }, _callee9);
469
+ })));
470
+ case 1:
471
+ expect(askMaiaMock).toHaveBeenCalledWith(expect.objectContaining({
472
+ contextMessage: expect.objectContaining({
473
+ user: expect.arrayContaining([expect.objectContaining({
474
+ id: 'u1',
475
+ name: 'Ana'
476
+ })])
477
+ })
478
+ }));
479
+ expect(eventMock).toHaveBeenCalledWith('PM_AI_TYPED_TEXT');
480
+ case 2:
481
+ case "end":
482
+ return _context0.stop();
483
+ }
484
+ }, _callee0);
485
+ })));
486
+ it('retries a cancelled assistant turn through askMaia', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
487
+ var _renderHook9, result;
488
+ return _regeneratorRuntime.wrap(function (_context10) {
489
+ while (1) switch (_context10.prev = _context10.next) {
490
+ case 0:
491
+ chatMessagesState.messages = [{
492
+ id: 'question-1',
493
+ message: 'Hola',
494
+ role: ChatHistoryRole.USER,
495
+ user: {
496
+ id: '7',
497
+ name: 'Ana'
498
+ },
499
+ date: new Date()
500
+ }, {
501
+ id: 'answer-stream-1-cancelled',
502
+ message: 'Respuesta parcial',
503
+ role: ChatHistoryRole.ASSISTANT,
504
+ user: {
505
+ id: 'assistant',
506
+ name: 'Assistant'
507
+ },
508
+ date: new Date(),
509
+ isFrontendCancelled: true
510
+ }];
511
+ _renderHook9 = renderHook(function () {
512
+ return useChatManager({
513
+ chatId: 'session-1',
514
+ agents: [testAgent]
515
+ });
516
+ }, {
517
+ wrapper: wrapper
518
+ }), result = _renderHook9.result;
519
+ _context10.next = 1;
520
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee1() {
521
+ return _regeneratorRuntime.wrap(function (_context1) {
522
+ while (1) switch (_context1.prev = _context1.next) {
523
+ case 0:
524
+ _context1.next = 1;
525
+ return result.current.retryMessage(chatMessagesState.messages[1]);
526
+ case 1:
527
+ case "end":
528
+ return _context1.stop();
529
+ }
530
+ }, _callee1);
531
+ })));
532
+ case 1:
533
+ expect(askMaiaMock).toHaveBeenCalledWith(expect.objectContaining({
534
+ message: 'Hola',
535
+ chatId: 'session-1'
536
+ }));
537
+ expect(replaceMessagesMock).toHaveBeenCalled();
538
+ case 2:
539
+ case "end":
540
+ return _context10.stop();
541
+ }
542
+ }, _callee10);
543
+ })));
544
+ it('re-asks with the new project when a pending question exists', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
545
+ var setProject, project, _renderHook0, result;
546
+ return _regeneratorRuntime.wrap(function (_context12) {
547
+ while (1) switch (_context12.prev = _context12.next) {
548
+ case 0:
549
+ setProject = jest.fn();
550
+ project = {
551
+ id: 10,
552
+ name: 'Proyecto A'
553
+ };
554
+ _renderHook0 = renderHook(function () {
555
+ return useChatManager({
556
+ chatId: 'session-1',
557
+ agents: [testAgent]
558
+ });
559
+ }, {
560
+ wrapper: function wrapper(_ref13) {
561
+ var children = _ref13.children;
562
+ return /*#__PURE__*/_jsx(GlobalContextTestProvider, {
563
+ value: {
564
+ agent: testAgent,
565
+ project: project,
566
+ setProject: setProject
567
+ },
568
+ children: children
569
+ });
570
+ }
571
+ }), result = _renderHook0.result;
572
+ _context12.next = 1;
573
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
574
+ return _regeneratorRuntime.wrap(function (_context11) {
575
+ while (1) switch (_context11.prev = _context11.next) {
576
+ case 0:
577
+ _context11.next = 1;
578
+ return result.current.sendMessage('¿Cuántas horas van?');
579
+ case 1:
580
+ case "end":
581
+ return _context11.stop();
582
+ }
583
+ }, _callee11);
584
+ })));
585
+ case 1:
586
+ askMaiaMock.mockClear();
587
+ act(function () {
588
+ result.current.changeProject({
589
+ id: 99,
590
+ name: 'Proyecto X',
591
+ feeId: 5,
592
+ clientId: 7
593
+ });
594
+ });
595
+ expect(setProject).toHaveBeenCalledWith(expect.objectContaining({
596
+ id: 99
597
+ }));
598
+ expect(askMaiaMock).toHaveBeenCalledWith(expect.objectContaining({
599
+ message: '¿Cuántas horas van?',
600
+ projectId: 99,
601
+ feeId: 5,
602
+ clientId: 7
603
+ }));
604
+ case 2:
605
+ case "end":
606
+ return _context12.stop();
607
+ }
608
+ }, _callee12);
609
+ })));
610
+ it('does not change project when there is no pending user question', function () {
611
+ var _renderHook1 = renderHook(function () {
612
+ return useChatManager({
613
+ chatId: 'session-1',
614
+ agents: [testAgent]
615
+ });
616
+ }, {
617
+ wrapper: wrapper
618
+ }),
619
+ result = _renderHook1.result;
620
+ act(function () {
621
+ result.current.changeProject({
622
+ id: 99,
623
+ name: 'Proyecto X'
624
+ });
625
+ });
626
+ expect(askMaiaMock).not.toHaveBeenCalled();
627
+ });
628
+ it('starts a continue stream when rejecting a HITL action', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee14() {
629
+ var _renderHook10, result;
630
+ return _regeneratorRuntime.wrap(function (_context14) {
631
+ while (1) switch (_context14.prev = _context14.next) {
632
+ case 0:
633
+ activeView.set('session-1');
634
+ chatMessagesState.messages = [{
635
+ id: 'msg-approval',
636
+ message: 'Approve task edit?',
637
+ role: ChatHistoryRole.ASSISTANT,
638
+ user: {
639
+ id: 'assistant',
640
+ name: 'MAIA'
641
+ },
642
+ date: new Date(),
643
+ approval: {
644
+ session_id: 'session-1',
645
+ pending_actions: [{
646
+ thread_id: 'thread-a',
647
+ tool_name: 'edit_task',
648
+ tool_args: {
649
+ task_id: 42
650
+ }
651
+ }]
652
+ }
653
+ }];
654
+ _renderHook10 = renderHook(function () {
655
+ return useChatManager({
656
+ chatId: 'session-1',
657
+ agents: [testAgent]
658
+ });
659
+ }, {
660
+ wrapper: wrapper
661
+ }), result = _renderHook10.result;
662
+ _context14.next = 1;
663
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
664
+ return _regeneratorRuntime.wrap(function (_context13) {
665
+ while (1) switch (_context13.prev = _context13.next) {
666
+ case 0:
667
+ _context13.next = 1;
668
+ return result.current.handleApprovalDecision(['thread-a'], 'reject');
669
+ case 1:
670
+ case "end":
671
+ return _context13.stop();
672
+ }
673
+ }, _callee13);
674
+ })));
675
+ case 1:
676
+ expect(startContinueStreamMock).toHaveBeenCalledWith(expect.objectContaining({
677
+ continueRequest: expect.objectContaining({
678
+ decision: 'reject'
679
+ })
680
+ }));
681
+ case 2:
682
+ case "end":
683
+ return _context14.stop();
684
+ }
685
+ }, _callee14);
686
+ })));
687
+ it('starts a continue stream when approving a HITL action', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee16() {
688
+ var _renderHook11, result;
689
+ return _regeneratorRuntime.wrap(function (_context16) {
690
+ while (1) switch (_context16.prev = _context16.next) {
691
+ case 0:
692
+ activeView.set('session-1');
693
+ chatMessagesState.messages = [{
694
+ id: 'msg-approval',
695
+ message: 'Approve task edit?',
696
+ role: ChatHistoryRole.ASSISTANT,
697
+ user: {
698
+ id: 'assistant',
699
+ name: 'MAIA'
700
+ },
701
+ date: new Date(),
702
+ approval: {
703
+ session_id: 'session-1',
704
+ pending_actions: [{
705
+ thread_id: 'thread-a',
706
+ tool_name: 'edit_task',
707
+ tool_args: {
708
+ task_id: 42
709
+ }
710
+ }]
711
+ }
712
+ }];
713
+ _renderHook11 = renderHook(function () {
714
+ return useChatManager({
715
+ chatId: 'session-1',
716
+ agents: [testAgent]
717
+ });
718
+ }, {
719
+ wrapper: wrapper
720
+ }), result = _renderHook11.result;
721
+ _context16.next = 1;
722
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee15() {
723
+ return _regeneratorRuntime.wrap(function (_context15) {
724
+ while (1) switch (_context15.prev = _context15.next) {
725
+ case 0:
726
+ _context15.next = 1;
727
+ return result.current.handleApprovalDecision(['thread-a'], 'approve');
728
+ case 1:
729
+ case "end":
730
+ return _context15.stop();
731
+ }
732
+ }, _callee15);
733
+ })));
734
+ case 1:
735
+ expect(startContinueStreamMock).toHaveBeenCalledWith(expect.objectContaining({
736
+ sessionId: 'session-1',
737
+ continueRequest: expect.objectContaining({
738
+ threadIds: ['thread-a'],
739
+ decision: 'approve'
740
+ })
741
+ }));
742
+ case 2:
743
+ case "end":
744
+ return _context16.stop();
745
+ }
746
+ }, _callee16);
747
+ })));
748
+ it('submits feedback through the maia chats service', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee18() {
749
+ var _renderHook12, result;
750
+ return _regeneratorRuntime.wrap(function (_context18) {
751
+ while (1) switch (_context18.prev = _context18.next) {
752
+ case 0:
753
+ chatMessagesState.messages = [{
754
+ id: 'answer-1',
755
+ message: 'Respuesta',
756
+ role: ChatHistoryRole.ASSISTANT,
757
+ user: {
758
+ id: 'assistant',
759
+ name: 'Assistant'
760
+ },
761
+ date: new Date()
762
+ }];
763
+ jest.mocked(maia.Chats.wasHelpfulChat).mockResolvedValue(true);
764
+ _renderHook12 = renderHook(function () {
765
+ return useChatManager({
766
+ chatId: 'session-1',
767
+ agents: [testAgent]
768
+ });
769
+ }, {
770
+ wrapper: wrapper
771
+ }), result = _renderHook12.result;
772
+ _context18.next = 1;
773
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee17() {
774
+ return _regeneratorRuntime.wrap(function (_context17) {
775
+ while (1) switch (_context17.prev = _context17.next) {
776
+ case 0:
777
+ _context17.next = 1;
778
+ return result.current.handleFeedback(Feedback.THUMBS_UP, 'answer-1');
779
+ case 1:
780
+ case "end":
781
+ return _context17.stop();
782
+ }
783
+ }, _callee17);
784
+ })));
785
+ case 1:
786
+ expect(maia.Chats.wasHelpfulChat).toHaveBeenCalledWith('answer-1', true);
787
+ case 2:
788
+ case "end":
789
+ return _context18.stop();
790
+ }
791
+ }, _callee18);
792
+ })));
793
+ it('ignores feedback updates when the API rejects the vote', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee20() {
794
+ var _renderHook13, result;
795
+ return _regeneratorRuntime.wrap(function (_context20) {
796
+ while (1) switch (_context20.prev = _context20.next) {
797
+ case 0:
798
+ chatMessagesState.messages = [{
799
+ id: 'answer-1',
800
+ message: 'Respuesta',
801
+ role: ChatHistoryRole.ASSISTANT,
802
+ user: {
803
+ id: 'assistant',
804
+ name: 'Assistant'
805
+ },
806
+ date: new Date()
807
+ }];
808
+ jest.mocked(maia.Chats.wasHelpfulChat).mockResolvedValue(false);
809
+ _renderHook13 = renderHook(function () {
810
+ return useChatManager({
811
+ chatId: 'session-1',
812
+ agents: [testAgent]
813
+ });
814
+ }, {
815
+ wrapper: wrapper
816
+ }), result = _renderHook13.result;
817
+ _context20.next = 1;
818
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee19() {
819
+ return _regeneratorRuntime.wrap(function (_context19) {
820
+ while (1) switch (_context19.prev = _context19.next) {
821
+ case 0:
822
+ _context19.next = 1;
823
+ return result.current.handleFeedback(Feedback.THUMBS_DOWN, 'answer-1');
824
+ case 1:
825
+ case "end":
826
+ return _context19.stop();
827
+ }
828
+ }, _callee19);
829
+ })));
830
+ case 1:
831
+ expect(chatMessagesState.messages[0]).not.toHaveProperty('wasHelpful');
832
+ case 2:
833
+ case "end":
834
+ return _context20.stop();
835
+ }
836
+ }, _callee20);
837
+ })));
838
+ it('does not start approval streams without thread ids', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee22() {
839
+ var consoleSpy, _renderHook14, result;
840
+ return _regeneratorRuntime.wrap(function (_context22) {
841
+ while (1) switch (_context22.prev = _context22.next) {
842
+ case 0:
843
+ consoleSpy = jest.spyOn(console, 'error').mockImplementation(function () {
844
+ return undefined;
845
+ });
846
+ _renderHook14 = renderHook(function () {
847
+ return useChatManager({
848
+ chatId: 'session-1',
849
+ agents: [testAgent]
850
+ });
851
+ }, {
852
+ wrapper: wrapper
853
+ }), result = _renderHook14.result;
854
+ _context22.next = 1;
855
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee21() {
856
+ return _regeneratorRuntime.wrap(function (_context21) {
857
+ while (1) switch (_context21.prev = _context21.next) {
858
+ case 0:
859
+ _context21.next = 1;
860
+ return result.current.handleApprovalDecision([], 'approve');
861
+ case 1:
862
+ case "end":
863
+ return _context21.stop();
864
+ }
865
+ }, _callee21);
866
+ })));
867
+ case 1:
868
+ expect(startContinueStreamMock).not.toHaveBeenCalled();
869
+ expect(consoleSpy).toHaveBeenCalled();
870
+ consoleSpy.mockRestore();
871
+ case 2:
872
+ case "end":
873
+ return _context22.stop();
874
+ }
875
+ }, _callee22);
876
+ })));
877
+ it('sendMessage accepts a bare attachments array', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee24() {
878
+ var attachment, _renderHook15, result;
879
+ return _regeneratorRuntime.wrap(function (_context24) {
880
+ while (1) switch (_context24.prev = _context24.next) {
881
+ case 0:
882
+ attachment = {
883
+ id: 'a1',
884
+ name: 'doc.pdf',
885
+ type: 'pdf',
886
+ size: 1,
887
+ file: new File([], 'doc.pdf')
888
+ };
889
+ _renderHook15 = renderHook(function () {
890
+ return useChatManager({
891
+ chatId: 'session-1',
892
+ agents: [testAgent]
893
+ });
894
+ }, {
895
+ wrapper: wrapper
896
+ }), result = _renderHook15.result;
897
+ _context24.next = 1;
898
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee23() {
899
+ return _regeneratorRuntime.wrap(function (_context23) {
900
+ while (1) switch (_context23.prev = _context23.next) {
901
+ case 0:
902
+ _context23.next = 1;
903
+ return result.current.sendMessage('Con adjunto', [attachment]);
904
+ case 1:
905
+ case "end":
906
+ return _context23.stop();
907
+ }
908
+ }, _callee23);
909
+ })));
910
+ case 1:
911
+ expect(askMaiaMock).toHaveBeenCalledWith(expect.objectContaining({
912
+ message: 'Con adjunto',
913
+ attachments: [attachment]
914
+ }));
915
+ case 2:
916
+ case "end":
917
+ return _context24.stop();
918
+ }
919
+ }, _callee24);
920
+ })));
921
+ it('loads messages when initializeChat runs with an existing chat id', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee26() {
922
+ var _renderHook16, result;
923
+ return _regeneratorRuntime.wrap(function (_context26) {
924
+ while (1) switch (_context26.prev = _context26.next) {
925
+ case 0:
926
+ chatMessagesState.loadMessages.mockResolvedValue(undefined);
927
+ _renderHook16 = renderHook(function () {
928
+ return useChatManager({
929
+ chatId: 'session-1',
930
+ agents: [testAgent]
931
+ });
932
+ }, {
933
+ wrapper: wrapper
934
+ }), result = _renderHook16.result;
935
+ _context26.next = 1;
936
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee25() {
937
+ return _regeneratorRuntime.wrap(function (_context25) {
938
+ while (1) switch (_context25.prev = _context25.next) {
939
+ case 0:
940
+ _context25.next = 1;
941
+ return result.current.initializeChat();
942
+ case 1:
943
+ case "end":
944
+ return _context25.stop();
945
+ }
946
+ }, _callee25);
947
+ })));
948
+ case 1:
949
+ expect(chatMessagesState.loadMessages).toHaveBeenCalled();
950
+ case 2:
951
+ case "end":
952
+ return _context26.stop();
953
+ }
954
+ }, _callee26);
955
+ })));
956
+ it('auto-sends the initial FAQ when initializeChat receives faqId only', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee28() {
957
+ var _renderHook17, result;
958
+ return _regeneratorRuntime.wrap(function (_context28) {
959
+ while (1) switch (_context28.prev = _context28.next) {
960
+ case 0:
961
+ _renderHook17 = renderHook(function () {
962
+ return useChatManager({
963
+ userInitialMessage: {
964
+ message: '',
965
+ attachments: [],
966
+ faqId: 'faq-rentabilidad'
967
+ },
968
+ agents: [testAgent]
969
+ });
970
+ }, {
971
+ wrapper: wrapper
972
+ }), result = _renderHook17.result;
973
+ _context28.next = 1;
974
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee27() {
975
+ return _regeneratorRuntime.wrap(function (_context27) {
976
+ while (1) switch (_context27.prev = _context27.next) {
977
+ case 0:
978
+ _context27.next = 1;
979
+ return result.current.initializeChat();
980
+ case 1:
981
+ case "end":
982
+ return _context27.stop();
983
+ }
984
+ }, _callee27);
985
+ })));
986
+ case 1:
987
+ expect(askMaiaMock).toHaveBeenCalledWith(expect.objectContaining({
988
+ faqId: 'faq-rentabilidad'
989
+ }));
990
+ case 2:
991
+ case "end":
992
+ return _context28.stop();
993
+ }
994
+ }, _callee28);
995
+ })));
996
+ it('skips initializeChat auto-send when the initial payload is empty', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee30() {
997
+ var _renderHook18, result;
998
+ return _regeneratorRuntime.wrap(function (_context30) {
999
+ while (1) switch (_context30.prev = _context30.next) {
1000
+ case 0:
1001
+ _renderHook18 = renderHook(function () {
1002
+ return useChatManager({
1003
+ userInitialMessage: {
1004
+ message: ' ',
1005
+ attachments: []
1006
+ },
1007
+ agents: [testAgent]
1008
+ });
1009
+ }, {
1010
+ wrapper: wrapper
1011
+ }), result = _renderHook18.result;
1012
+ _context30.next = 1;
1013
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee29() {
1014
+ return _regeneratorRuntime.wrap(function (_context29) {
1015
+ while (1) switch (_context29.prev = _context29.next) {
1016
+ case 0:
1017
+ _context29.next = 1;
1018
+ return result.current.initializeChat();
1019
+ case 1:
1020
+ case "end":
1021
+ return _context29.stop();
1022
+ }
1023
+ }, _callee29);
1024
+ })));
1025
+ case 1:
1026
+ expect(askMaiaMock).not.toHaveBeenCalled();
1027
+ expect(chatMessagesState.loadMessages).not.toHaveBeenCalled();
1028
+ case 2:
1029
+ case "end":
1030
+ return _context30.stop();
1031
+ }
1032
+ }, _callee30);
1033
+ })));
1034
+ it('does not retry when the concurrent stream limit is reached', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee32() {
1035
+ var dispatchSpy, _renderHook19, result;
1036
+ return _regeneratorRuntime.wrap(function (_context32) {
1037
+ while (1) switch (_context32.prev = _context32.next) {
1038
+ case 0:
1039
+ ;
1040
+ sessionStreamManager.getActiveCount.mockReturnValue(3);
1041
+ dispatchSpy = jest.spyOn(document, 'dispatchEvent');
1042
+ chatMessagesState.messages = [{
1043
+ id: 'question-1',
1044
+ message: 'Hola',
1045
+ role: ChatHistoryRole.USER,
1046
+ user: {
1047
+ id: '7',
1048
+ name: 'Ana'
1049
+ },
1050
+ date: new Date()
1051
+ }, {
1052
+ id: 'answer-stream-1-cancelled',
1053
+ message: 'Respuesta parcial',
1054
+ role: ChatHistoryRole.ASSISTANT,
1055
+ user: {
1056
+ id: 'assistant',
1057
+ name: 'Assistant'
1058
+ },
1059
+ date: new Date(),
1060
+ isFrontendCancelled: true
1061
+ }];
1062
+ _renderHook19 = renderHook(function () {
1063
+ return useChatManager({
1064
+ chatId: 'session-1',
1065
+ agents: [testAgent]
1066
+ });
1067
+ }, {
1068
+ wrapper: wrapper
1069
+ }), result = _renderHook19.result;
1070
+ _context32.next = 1;
1071
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee31() {
1072
+ return _regeneratorRuntime.wrap(function (_context31) {
1073
+ while (1) switch (_context31.prev = _context31.next) {
1074
+ case 0:
1075
+ _context31.next = 1;
1076
+ return result.current.retryMessage(chatMessagesState.messages[1]);
1077
+ case 1:
1078
+ case "end":
1079
+ return _context31.stop();
1080
+ }
1081
+ }, _callee31);
1082
+ })));
1083
+ case 1:
1084
+ expect(askMaiaMock).not.toHaveBeenCalled();
1085
+ expect(dispatchSpy).toHaveBeenCalledWith(expect.objectContaining({
1086
+ type: 'snackbar-event'
1087
+ }));
1088
+ dispatchSpy.mockRestore();
1089
+ case 2:
1090
+ case "end":
1091
+ return _context32.stop();
1092
+ }
1093
+ }, _callee32);
1094
+ })));
1095
+ it('does not start approval streams when the session is already streaming', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee34() {
1096
+ var _renderHook20, result;
1097
+ return _regeneratorRuntime.wrap(function (_context34) {
1098
+ while (1) switch (_context34.prev = _context34.next) {
1099
+ case 0:
1100
+ activeView.set('session-1');
1101
+ sessionStreamManager.isActive.mockReturnValue(true);
1102
+ chatMessagesState.messages = [{
1103
+ id: 'msg-approval',
1104
+ message: 'Approve?',
1105
+ role: ChatHistoryRole.ASSISTANT,
1106
+ user: {
1107
+ id: 'assistant',
1108
+ name: 'MAIA'
1109
+ },
1110
+ date: new Date(),
1111
+ approval: {
1112
+ session_id: 'session-1',
1113
+ pending_actions: [{
1114
+ thread_id: 'thread-a',
1115
+ tool_name: 'edit_task',
1116
+ tool_args: {}
1117
+ }]
1118
+ }
1119
+ }];
1120
+ _renderHook20 = renderHook(function () {
1121
+ return useChatManager({
1122
+ chatId: 'session-1',
1123
+ agents: [testAgent]
1124
+ });
1125
+ }, {
1126
+ wrapper: wrapper
1127
+ }), result = _renderHook20.result;
1128
+ _context34.next = 1;
1129
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee33() {
1130
+ return _regeneratorRuntime.wrap(function (_context33) {
1131
+ while (1) switch (_context33.prev = _context33.next) {
1132
+ case 0:
1133
+ _context33.next = 1;
1134
+ return result.current.handleApprovalDecision(['thread-a'], 'approve');
1135
+ case 1:
1136
+ case "end":
1137
+ return _context33.stop();
1138
+ }
1139
+ }, _callee33);
1140
+ })));
1141
+ case 1:
1142
+ expect(startContinueStreamMock).not.toHaveBeenCalled();
1143
+ case 2:
1144
+ case "end":
1145
+ return _context34.stop();
1146
+ }
1147
+ }, _callee34);
1148
+ })));
1149
+ it('starts a continue stream with edit decision when actions were edited', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee36() {
1150
+ var editedActions, _renderHook21, result;
1151
+ return _regeneratorRuntime.wrap(function (_context36) {
1152
+ while (1) switch (_context36.prev = _context36.next) {
1153
+ case 0:
1154
+ activeView.set('session-1');
1155
+ chatMessagesState.messages = [{
1156
+ id: 'msg-approval',
1157
+ message: 'Approve task edit?',
1158
+ role: ChatHistoryRole.ASSISTANT,
1159
+ user: {
1160
+ id: 'assistant',
1161
+ name: 'MAIA'
1162
+ },
1163
+ date: new Date(),
1164
+ approval: {
1165
+ session_id: 'session-1',
1166
+ pending_actions: [{
1167
+ thread_id: 'thread-a',
1168
+ tool_name: 'edit_task',
1169
+ tool_args: {
1170
+ task_id: 42
1171
+ }
1172
+ }]
1173
+ }
1174
+ }];
1175
+ editedActions = [{
1176
+ tool_name: 'edit_task',
1177
+ args: {
1178
+ task_id: 99
1179
+ }
1180
+ }];
1181
+ _renderHook21 = renderHook(function () {
1182
+ return useChatManager({
1183
+ chatId: 'session-1',
1184
+ agents: [testAgent]
1185
+ });
1186
+ }, {
1187
+ wrapper: wrapper
1188
+ }), result = _renderHook21.result;
1189
+ _context36.next = 1;
1190
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee35() {
1191
+ return _regeneratorRuntime.wrap(function (_context35) {
1192
+ while (1) switch (_context35.prev = _context35.next) {
1193
+ case 0:
1194
+ _context35.next = 1;
1195
+ return result.current.handleApprovalDecision(['thread-a'], 'reject', editedActions);
1196
+ case 1:
1197
+ case "end":
1198
+ return _context35.stop();
1199
+ }
1200
+ }, _callee35);
1201
+ })));
1202
+ case 1:
1203
+ expect(startContinueStreamMock).toHaveBeenCalledWith(expect.objectContaining({
1204
+ continueRequest: expect.objectContaining({
1205
+ decision: 'edit',
1206
+ editedActions: editedActions
1207
+ })
1208
+ }));
1209
+ case 2:
1210
+ case "end":
1211
+ return _context36.stop();
1212
+ }
1213
+ }, _callee36);
1214
+ })));
1215
+ it('commits access denied stream errors without retry suggestions', function () {
1216
+ renderHook(function () {
1217
+ return useChatManager({
1218
+ chatId: 'session-1',
1219
+ agents: [testAgent]
1220
+ });
1221
+ }, {
1222
+ wrapper: wrapper
1223
+ });
1224
+ act(function () {
1225
+ var _streamCallbacks$onEr, _streamCallbacks;
1226
+ (_streamCallbacks$onEr = (_streamCallbacks = streamCallbacks).onError) === null || _streamCallbacks$onEr === void 0 || _streamCallbacks$onEr.call(_streamCallbacks, {
1227
+ sessionId: 'session-1',
1228
+ messageId: 'msg-err',
1229
+ placeholderId: 'answer-msg-err-streaming'
1230
+ }, "Access denied: You don't have permission to access this agent");
1231
+ });
1232
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
1233
+ isError: true,
1234
+ message: 'chat.errorAccessDenied'
1235
+ }));
1236
+ expect(addMessageMock).not.toHaveBeenCalledWith(expect.objectContaining({
1237
+ suggestions: ['chat.retry']
1238
+ }));
1239
+ });
1240
+ it('maps prompt-too-long stream errors without retry suggestions', function () {
1241
+ activeView.set('session-1');
1242
+ renderHook(function () {
1243
+ return useChatManager({
1244
+ chatId: 'session-1',
1245
+ agents: [testAgent]
1246
+ });
1247
+ }, {
1248
+ wrapper: wrapper
1249
+ });
1250
+ act(function () {
1251
+ var _streamCallbacks$onEr2, _streamCallbacks2;
1252
+ (_streamCallbacks$onEr2 = (_streamCallbacks2 = streamCallbacks).onError) === null || _streamCallbacks$onEr2 === void 0 || _streamCallbacks$onEr2.call(_streamCallbacks2, {
1253
+ sessionId: 'session-1',
1254
+ messageId: 'msg-long',
1255
+ placeholderId: 'answer-msg-long-streaming'
1256
+ }, 'invalid_request_error', 'prompt is too long: 12000 tokens');
1257
+ });
1258
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
1259
+ isError: true,
1260
+ message: 'chat.errorPromptTooLong'
1261
+ }));
1262
+ expect(addMessageMock).not.toHaveBeenCalledWith(expect.objectContaining({
1263
+ suggestions: ['chat.retry']
1264
+ }));
1265
+ });
1266
+ it('marks background sessions unread when a stream errors off-screen', function () {
1267
+ activeView.set('session-visible');
1268
+ renderHook(function () {
1269
+ return useChatManager({
1270
+ chatId: 'session-visible',
1271
+ agents: [testAgent]
1272
+ });
1273
+ }, {
1274
+ wrapper: wrapper
1275
+ });
1276
+ act(function () {
1277
+ var _streamCallbacks$onEr3, _streamCallbacks3;
1278
+ (_streamCallbacks$onEr3 = (_streamCallbacks3 = streamCallbacks).onError) === null || _streamCallbacks$onEr3 === void 0 || _streamCallbacks$onEr3.call(_streamCallbacks3, {
1279
+ sessionId: 'session-bg',
1280
+ messageId: 'bg-err',
1281
+ placeholderId: 'answer-bg-err-streaming'
1282
+ }, 'server_error');
1283
+ });
1284
+ expect(getChatsStoreState().markChatAsUnread).toHaveBeenCalledWith('session-bg');
1285
+ expect(notifySessionFinishedInBackground).toHaveBeenCalledWith('session-bg', 'error');
1286
+ });
1287
+ it('adds retry suggestions for generic stream errors on the active session', function () {
1288
+ renderHook(function () {
1289
+ return useChatManager({
1290
+ chatId: 'session-1',
1291
+ agents: [testAgent]
1292
+ });
1293
+ }, {
1294
+ wrapper: wrapper
1295
+ });
1296
+ act(function () {
1297
+ var _streamCallbacks$onEr4, _streamCallbacks4;
1298
+ (_streamCallbacks$onEr4 = (_streamCallbacks4 = streamCallbacks).onError) === null || _streamCallbacks$onEr4 === void 0 || _streamCallbacks$onEr4.call(_streamCallbacks4, {
1299
+ sessionId: 'session-1',
1300
+ messageId: 'msg-500',
1301
+ placeholderId: 'answer-msg-500-streaming'
1302
+ }, 'server_error');
1303
+ });
1304
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
1305
+ isError: true,
1306
+ suggestions: ['chat.retry']
1307
+ }));
1308
+ });
1309
+ it('creates the streaming placeholder on the first stream update', function () {
1310
+ activeView.set('session-1');
1311
+ renderHook(function () {
1312
+ return useChatManager({
1313
+ chatId: 'session-1',
1314
+ agents: [testAgent]
1315
+ });
1316
+ }, {
1317
+ wrapper: wrapper
1318
+ });
1319
+ var ctx = {
1320
+ sessionId: 'session-1',
1321
+ messageId: 'live-1',
1322
+ placeholderId: 'answer-live-1-streaming'
1323
+ };
1324
+ act(function () {
1325
+ var _streamCallbacks$onSt, _streamCallbacks5;
1326
+ (_streamCallbacks$onSt = (_streamCallbacks5 = streamCallbacks).onStreamUpdate) === null || _streamCallbacks$onSt === void 0 || _streamCallbacks$onSt.call(_streamCallbacks5, ctx, 'Generando');
1327
+ });
1328
+ expect(useSessionsStore.getState().getMessages('session-1')).toEqual(expect.arrayContaining([expect.objectContaining({
1329
+ id: 'answer-live-1-streaming',
1330
+ message: ''
1331
+ })]));
1332
+ });
1333
+ it('marks background sessions unread when a stream finishes off-screen', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee38() {
1334
+ return _regeneratorRuntime.wrap(function (_context38) {
1335
+ while (1) switch (_context38.prev = _context38.next) {
1336
+ case 0:
1337
+ renderHook(function () {
1338
+ return useChatManager({
1339
+ chatId: 'session-1',
1340
+ agents: [testAgent]
1341
+ });
1342
+ }, {
1343
+ wrapper: wrapper
1344
+ });
1345
+ activeView.set('session-visible');
1346
+ _context38.next = 1;
1347
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee37() {
1348
+ var _streamCallbacks$onFi, _streamCallbacks6;
1349
+ return _regeneratorRuntime.wrap(function (_context37) {
1350
+ while (1) switch (_context37.prev = _context37.next) {
1351
+ case 0:
1352
+ _context37.next = 1;
1353
+ return (_streamCallbacks$onFi = (_streamCallbacks6 = streamCallbacks).onFinishStream) === null || _streamCallbacks$onFi === void 0 ? void 0 : _streamCallbacks$onFi.call(_streamCallbacks6, {
1354
+ sessionId: 'session-1',
1355
+ messageId: 'bg-1',
1356
+ placeholderId: 'answer-bg-1-streaming'
1357
+ }, 'Respuesta en background', [], 'memory-bg-1', null, null, null);
1358
+ case 1:
1359
+ case "end":
1360
+ return _context37.stop();
1361
+ }
1362
+ }, _callee37);
1363
+ })));
1364
+ case 1:
1365
+ expect(getChatsStoreState().markChatAsUnread).toHaveBeenCalledWith('session-1');
1366
+ expect(notifySessionFinishedInBackground).toHaveBeenCalledWith('session-1', 'complete');
1367
+ expect(addMessageMock).not.toHaveBeenCalled();
1368
+ case 2:
1369
+ case "end":
1370
+ return _context38.stop();
1371
+ }
1372
+ }, _callee38);
1373
+ })));
1374
+ it('commits prompt-too-long stream errors without retry suggestions', function () {
1375
+ renderHook(function () {
1376
+ return useChatManager({
1377
+ chatId: 'session-1',
1378
+ agents: [testAgent]
1379
+ });
1380
+ }, {
1381
+ wrapper: wrapper
1382
+ });
1383
+ act(function () {
1384
+ var _streamCallbacks$onEr5, _streamCallbacks7;
1385
+ (_streamCallbacks$onEr5 = (_streamCallbacks7 = streamCallbacks).onError) === null || _streamCallbacks$onEr5 === void 0 || _streamCallbacks$onEr5.call(_streamCallbacks7, {
1386
+ sessionId: 'session-1',
1387
+ messageId: 'msg-long',
1388
+ placeholderId: 'answer-msg-long-streaming'
1389
+ }, 'invalid_request_error', 'prompt is too long: 12000 tokens');
1390
+ });
1391
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
1392
+ isError: true,
1393
+ message: expect.stringContaining('chat.errorPromptTooLong')
1394
+ }));
1395
+ expect(addMessageMock).not.toHaveBeenCalledWith(expect.objectContaining({
1396
+ suggestions: ['chat.retry']
1397
+ }));
1398
+ });
1399
+ it('marks background sessions unread when a stream errors off-screen', function () {
1400
+ renderHook(function () {
1401
+ return useChatManager({
1402
+ chatId: 'session-1',
1403
+ agents: [testAgent]
1404
+ });
1405
+ }, {
1406
+ wrapper: wrapper
1407
+ });
1408
+ activeView.set('other-session');
1409
+ act(function () {
1410
+ var _streamCallbacks$onEr6, _streamCallbacks8;
1411
+ (_streamCallbacks$onEr6 = (_streamCallbacks8 = streamCallbacks).onError) === null || _streamCallbacks$onEr6 === void 0 || _streamCallbacks$onEr6.call(_streamCallbacks8, {
1412
+ sessionId: 'session-1',
1413
+ messageId: 'bg-err',
1414
+ placeholderId: 'answer-bg-err-streaming'
1415
+ }, 'server_error');
1416
+ });
1417
+ expect(getChatsStoreState().markChatAsUnread).toHaveBeenCalledWith('session-1');
1418
+ expect(notifySessionFinishedInBackground).toHaveBeenCalledWith('session-1', 'error');
1419
+ });
1420
+ it('syncs task creation with the project dashboard when approval completes on the active session', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee40() {
1421
+ var addExistingTaskToDashboard, originalPathname, taskUrl;
1422
+ return _regeneratorRuntime.wrap(function (_context40) {
1423
+ while (1) switch (_context40.prev = _context40.next) {
1424
+ case 0:
1425
+ addExistingTaskToDashboard = jest.fn();
1426
+ window.newProjectDashboard = {
1427
+ addExistingTaskToDashboard: addExistingTaskToDashboard
1428
+ };
1429
+ originalPathname = window.location.pathname;
1430
+ Object.defineProperty(window, 'location', {
1431
+ configurable: true,
1432
+ value: _objectSpread(_objectSpread({}, window.location), {}, {
1433
+ pathname: '/projects/42/tasks'
1434
+ })
1435
+ });
1436
+ activeView.set('session-1');
1437
+ chatMessagesState.messages = [{
1438
+ id: 'user-1',
1439
+ message: 'Crea la tarea',
1440
+ role: ChatHistoryRole.USER,
1441
+ user: {
1442
+ id: '7',
1443
+ name: 'Ana'
1444
+ },
1445
+ date: new Date(),
1446
+ projectId: 42
1447
+ }, {
1448
+ id: 'approval-msg',
1449
+ message: '¿Confirmás?',
1450
+ role: ChatHistoryRole.ASSISTANT,
1451
+ user: {
1452
+ id: 'assistant',
1453
+ name: 'MAIA'
1454
+ },
1455
+ date: new Date(),
1456
+ approvalStatus: 'approved',
1457
+ approval: {
1458
+ session_id: 'session-1',
1459
+ pending_actions: [{
1460
+ thread_id: 't1',
1461
+ tool_name: 'create_task',
1462
+ tool_args: {
1463
+ task_id: 55
1464
+ }
1465
+ }]
1466
+ }
1467
+ }];
1468
+ renderHook(function () {
1469
+ return useChatManager({
1470
+ chatId: 'session-1',
1471
+ agents: [testAgent]
1472
+ });
1473
+ }, {
1474
+ wrapper: function wrapper(_ref42) {
1475
+ var children = _ref42.children;
1476
+ return /*#__PURE__*/_jsx(GlobalContextTestProvider, {
1477
+ value: {
1478
+ agent: testAgent,
1479
+ project: {
1480
+ id: 42,
1481
+ name: 'Alpha'
1482
+ }
1483
+ },
1484
+ children: children
1485
+ });
1486
+ }
1487
+ });
1488
+ taskUrl = 'https://app.cor.com/tasks/55/detail';
1489
+ _context40.next = 1;
1490
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee39() {
1491
+ var _streamCallbacks$onFi2, _streamCallbacks9;
1492
+ return _regeneratorRuntime.wrap(function (_context39) {
1493
+ while (1) switch (_context39.prev = _context39.next) {
1494
+ case 0:
1495
+ _context39.next = 1;
1496
+ return (_streamCallbacks$onFi2 = (_streamCallbacks9 = streamCallbacks).onFinishStream) === null || _streamCallbacks$onFi2 === void 0 ? void 0 : _streamCallbacks$onFi2.call(_streamCallbacks9, {
1497
+ sessionId: 'session-1',
1498
+ messageId: 'live-1',
1499
+ placeholderId: streamingPlaceholderMessageId('live-1')
1500
+ }, taskUrl, [], 'memory-task-1', null, ['Seguir'], null);
1501
+ case 1:
1502
+ case "end":
1503
+ return _context39.stop();
1504
+ }
1505
+ }, _callee39);
1506
+ })));
1507
+ case 1:
1508
+ expect(addExistingTaskToDashboard).toHaveBeenCalledWith([55]);
1509
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
1510
+ id: 'answer-memory-task-1',
1511
+ suggestions: ['Seguir']
1512
+ }));
1513
+ Object.defineProperty(window, 'location', {
1514
+ configurable: true,
1515
+ value: _objectSpread(_objectSpread({}, window.location), {}, {
1516
+ pathname: originalPathname
1517
+ })
1518
+ });
1519
+ delete window.newProjectDashboard;
1520
+ case 2:
1521
+ case "end":
1522
+ return _context40.stop();
1523
+ }
1524
+ }, _callee40);
1525
+ })));
1526
+ it('dispatches planner sync when hours charge approval completes', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee42() {
1527
+ var onHoursCharged, event;
1528
+ return _regeneratorRuntime.wrap(function (_context42) {
1529
+ while (1) switch (_context42.prev = _context42.next) {
1530
+ case 0:
1531
+ onHoursCharged = jest.fn();
1532
+ window.addEventListener(MAIA_HOURS_CHARGED_EVENT, onHoursCharged);
1533
+ activeView.set('session-1');
1534
+ chatMessagesState.messages = [{
1535
+ id: 'approval-hours',
1536
+ message: '¿Cargo horas?',
1537
+ role: ChatHistoryRole.ASSISTANT,
1538
+ user: {
1539
+ id: 'assistant',
1540
+ name: 'MAIA'
1541
+ },
1542
+ date: new Date(),
1543
+ approvalStatus: 'approved',
1544
+ approval: {
1545
+ session_id: 'session-1',
1546
+ pending_actions: [{
1547
+ thread_id: 'h1',
1548
+ tool_name: 'create_hours',
1549
+ tool_args: {}
1550
+ }]
1551
+ }
1552
+ }];
1553
+ renderHook(function () {
1554
+ return useChatManager({
1555
+ chatId: 'session-1',
1556
+ agents: [testAgent]
1557
+ });
1558
+ }, {
1559
+ wrapper: wrapper
1560
+ });
1561
+ _context42.next = 1;
1562
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee41() {
1563
+ var _streamCallbacks$onFi3, _streamCallbacks0;
1564
+ return _regeneratorRuntime.wrap(function (_context41) {
1565
+ while (1) switch (_context41.prev = _context41.next) {
1566
+ case 0:
1567
+ _context41.next = 1;
1568
+ return (_streamCallbacks$onFi3 = (_streamCallbacks0 = streamCallbacks).onFinishStream) === null || _streamCallbacks$onFi3 === void 0 ? void 0 : _streamCallbacks$onFi3.call(_streamCallbacks0, {
1569
+ sessionId: 'session-1',
1570
+ messageId: 'hours-1',
1571
+ placeholderId: streamingPlaceholderMessageId('hours-1')
1572
+ }, 'Horas cargadas', [], 'memory-hours-1');
1573
+ case 1:
1574
+ case "end":
1575
+ return _context41.stop();
1576
+ }
1577
+ }, _callee41);
1578
+ })));
1579
+ case 1:
1580
+ expect(onHoursCharged).toHaveBeenCalled();
1581
+ event = onHoursCharged.mock.calls[0][0];
1582
+ expect(event.detail.tools).toEqual(['create_hours']);
1583
+ window.removeEventListener(MAIA_HOURS_CHARGED_EVENT, onHoursCharged);
1584
+ case 2:
1585
+ case "end":
1586
+ return _context42.stop();
1587
+ }
1588
+ }, _callee42);
1589
+ })));
1590
+ it('fetches and merges a newly created agent after stream finish', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee44() {
1591
+ var onMergeAgent;
1592
+ return _regeneratorRuntime.wrap(function (_context44) {
1593
+ while (1) switch (_context44.prev = _context44.next) {
1594
+ case 0:
1595
+ window.MAIA_CHAT_AI_FEATURE_ACCESS_MULTI_AGENTS = true;
1596
+ fetchAgentDetailMock.mockResolvedValue({
1597
+ id: 'agent-new',
1598
+ name: 'Nuevo'
1599
+ });
1600
+ onMergeAgent = jest.fn();
1601
+ document.addEventListener('maia-merge-created-agent-into-list', onMergeAgent);
1602
+ activeView.set('session-1');
1603
+ chatMessagesState.messages = [{
1604
+ id: 'approval-agent',
1605
+ message: '¿Creo el agente?',
1606
+ role: ChatHistoryRole.ASSISTANT,
1607
+ user: {
1608
+ id: 'assistant',
1609
+ name: 'MAIA'
1610
+ },
1611
+ date: new Date(),
1612
+ approvalStatus: 'approved',
1613
+ approval: {
1614
+ session_id: 'session-1',
1615
+ pending_actions: [{
1616
+ thread_id: 'a1',
1617
+ tool_name: 'create_agent',
1618
+ tool_args: {}
1619
+ }]
1620
+ }
1621
+ }];
1622
+ renderHook(function () {
1623
+ return useChatManager({
1624
+ chatId: 'session-1',
1625
+ agents: [testAgent]
1626
+ });
1627
+ }, {
1628
+ wrapper: wrapper
1629
+ });
1630
+ _context44.next = 1;
1631
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee43() {
1632
+ var _streamCallbacks$onFi4, _streamCallbacks1;
1633
+ return _regeneratorRuntime.wrap(function (_context43) {
1634
+ while (1) switch (_context43.prev = _context43.next) {
1635
+ case 0:
1636
+ _context43.next = 1;
1637
+ return (_streamCallbacks$onFi4 = (_streamCallbacks1 = streamCallbacks).onFinishStream) === null || _streamCallbacks$onFi4 === void 0 ? void 0 : _streamCallbacks$onFi4.call(_streamCallbacks1, {
1638
+ sessionId: 'session-1',
1639
+ messageId: 'agent-live',
1640
+ placeholderId: streamingPlaceholderMessageId('agent-live')
1641
+ }, 'Agente creado', [], 'memory-agent-1', null, null, 'agent-new');
1642
+ case 1:
1643
+ _context43.next = 2;
1644
+ return Promise.resolve();
1645
+ case 2:
1646
+ case "end":
1647
+ return _context43.stop();
1648
+ }
1649
+ }, _callee43);
1650
+ })));
1651
+ case 1:
1652
+ expect(fetchAgentDetailMock).toHaveBeenCalledWith('agent-new');
1653
+ expect(onMergeAgent).toHaveBeenCalled();
1654
+ document.removeEventListener('maia-merge-created-agent-into-list', onMergeAgent);
1655
+ window.MAIA_CHAT_AI_FEATURE_ACCESS_MULTI_AGENTS = false;
1656
+ case 2:
1657
+ case "end":
1658
+ return _context44.stop();
1659
+ }
1660
+ }, _callee44);
1661
+ })));
1662
+ it('refetches the open task panel after an approved task edit', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee46() {
1663
+ var refetchTask;
1664
+ return _regeneratorRuntime.wrap(function (_context46) {
1665
+ while (1) switch (_context46.prev = _context46.next) {
1666
+ case 0:
1667
+ refetchTask = jest.fn();
1668
+ window.taskPanel = {
1669
+ taskId: 88,
1670
+ refetchTask: refetchTask
1671
+ };
1672
+ activeView.set('session-1');
1673
+ chatMessagesState.messages = [{
1674
+ id: 'approval-edit',
1675
+ message: '¿Edito?',
1676
+ role: ChatHistoryRole.ASSISTANT,
1677
+ user: {
1678
+ id: 'assistant',
1679
+ name: 'MAIA'
1680
+ },
1681
+ date: new Date(),
1682
+ approvalStatus: 'approved',
1683
+ approval: {
1684
+ session_id: 'session-1',
1685
+ pending_actions: [{
1686
+ thread_id: 'e1',
1687
+ tool_name: 'edit_task',
1688
+ tool_args: {
1689
+ task_id: 88
1690
+ }
1691
+ }]
1692
+ }
1693
+ }];
1694
+ renderHook(function () {
1695
+ return useChatManager({
1696
+ chatId: 'session-1',
1697
+ agents: [testAgent]
1698
+ });
1699
+ }, {
1700
+ wrapper: wrapper
1701
+ });
1702
+ _context46.next = 1;
1703
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee45() {
1704
+ var _streamCallbacks$onFi5, _streamCallbacks10;
1705
+ return _regeneratorRuntime.wrap(function (_context45) {
1706
+ while (1) switch (_context45.prev = _context45.next) {
1707
+ case 0:
1708
+ _context45.next = 1;
1709
+ return (_streamCallbacks$onFi5 = (_streamCallbacks10 = streamCallbacks).onFinishStream) === null || _streamCallbacks$onFi5 === void 0 ? void 0 : _streamCallbacks$onFi5.call(_streamCallbacks10, {
1710
+ sessionId: 'session-1',
1711
+ messageId: 'edit-live',
1712
+ placeholderId: streamingPlaceholderMessageId('edit-live')
1713
+ }, 'Tarea actualizada', [], 'memory-edit-1');
1714
+ case 1:
1715
+ case "end":
1716
+ return _context45.stop();
1717
+ }
1718
+ }, _callee45);
1719
+ })));
1720
+ case 1:
1721
+ expect(refetchTask).toHaveBeenCalled();
1722
+ delete window.taskPanel;
1723
+ case 2:
1724
+ case "end":
1725
+ return _context46.stop();
1726
+ }
1727
+ }, _callee46);
1728
+ })));
1729
+ it('reloads messages when the active session ends with a stale streaming placeholder', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee48() {
1730
+ return _regeneratorRuntime.wrap(function (_context48) {
1731
+ while (1) switch (_context48.prev = _context48.next) {
1732
+ case 0:
1733
+ useSessionsStore.setState({
1734
+ meta: {
1735
+ 'session-1': {
1736
+ status: 'complete',
1737
+ finishedAt: '2024-06-01T00:00:00.000Z'
1738
+ }
1739
+ },
1740
+ messages: {
1741
+ 'session-1': [{
1742
+ id: streamingPlaceholderMessageId('stale'),
1743
+ message: '',
1744
+ role: ChatHistoryRole.ASSISTANT,
1745
+ user: {
1746
+ id: 'assistant',
1747
+ name: 'MAIA'
1748
+ },
1749
+ date: new Date()
1750
+ }]
1751
+ }
1752
+ });
1753
+ renderHook(function () {
1754
+ return useChatManager({
1755
+ chatId: 'session-1',
1756
+ agents: [testAgent]
1757
+ });
1758
+ }, {
1759
+ wrapper: wrapper
1760
+ });
1761
+ _context48.next = 1;
1762
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee47() {
1763
+ return _regeneratorRuntime.wrap(function (_context47) {
1764
+ while (1) switch (_context47.prev = _context47.next) {
1765
+ case 0:
1766
+ _context47.next = 1;
1767
+ return Promise.resolve();
1768
+ case 1:
1769
+ case "end":
1770
+ return _context47.stop();
1771
+ }
1772
+ }, _callee47);
1773
+ })));
1774
+ case 1:
1775
+ expect(chatMessagesState.loadMessages).toHaveBeenCalledWith({
1776
+ force: true
1777
+ });
1778
+ case 2:
1779
+ case "end":
1780
+ return _context48.stop();
1781
+ }
1782
+ }, _callee48);
1783
+ })));
1784
+ it('rotates to a fresh session id when initial chat id clears', function () {
1785
+ var _renderHook22 = renderHook(function (_ref52) {
1786
+ var chatId = _ref52.chatId;
1787
+ return useChatManager({
1788
+ chatId: chatId,
1789
+ agents: [testAgent]
1790
+ });
1791
+ }, {
1792
+ wrapper: wrapper,
1793
+ initialProps: {
1794
+ chatId: 'previous-session'
1795
+ }
1796
+ }),
1797
+ rerender = _renderHook22.rerender;
1798
+ rerender({
1799
+ chatId: null
1800
+ });
1801
+ expect(getChatsStoreState().setActiveChatId).toHaveBeenCalledWith(null);
1802
+ });
1803
+ it('restores the message list when a retry stream fails on the active session', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee50() {
1804
+ var dispatchSpy, _renderHook23, result;
1805
+ return _regeneratorRuntime.wrap(function (_context50) {
1806
+ while (1) switch (_context50.prev = _context50.next) {
1807
+ case 0:
1808
+ chatMessagesState.messages = [{
1809
+ id: 'question-1',
1810
+ message: 'Hola',
1811
+ role: ChatHistoryRole.USER,
1812
+ user: {
1813
+ id: '7',
1814
+ name: 'Ana'
1815
+ },
1816
+ date: new Date()
1817
+ }, {
1818
+ id: 'answer-stream-1-cancelled',
1819
+ message: 'Respuesta parcial',
1820
+ role: ChatHistoryRole.ASSISTANT,
1821
+ user: {
1822
+ id: 'assistant',
1823
+ name: 'Assistant'
1824
+ },
1825
+ date: new Date(),
1826
+ isFrontendCancelled: true
1827
+ }];
1828
+ dispatchSpy = jest.spyOn(document, 'dispatchEvent');
1829
+ activeView.set('session-1');
1830
+ _renderHook23 = renderHook(function () {
1831
+ return useChatManager({
1832
+ chatId: 'session-1',
1833
+ agents: [testAgent]
1834
+ });
1835
+ }, {
1836
+ wrapper: wrapper
1837
+ }), result = _renderHook23.result;
1838
+ _context50.next = 1;
1839
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee49() {
1840
+ return _regeneratorRuntime.wrap(function (_context49) {
1841
+ while (1) switch (_context49.prev = _context49.next) {
1842
+ case 0:
1843
+ _context49.next = 1;
1844
+ return result.current.retryMessage(chatMessagesState.messages[1]);
1845
+ case 1:
1846
+ case "end":
1847
+ return _context49.stop();
1848
+ }
1849
+ }, _callee49);
1850
+ })));
1851
+ case 1:
1852
+ replaceMessagesMock.mockClear();
1853
+ act(function () {
1854
+ var _streamCallbacks$onEr7, _streamCallbacks11;
1855
+ (_streamCallbacks$onEr7 = (_streamCallbacks11 = streamCallbacks).onError) === null || _streamCallbacks$onEr7 === void 0 || _streamCallbacks$onEr7.call(_streamCallbacks11, {
1856
+ sessionId: 'session-1',
1857
+ messageId: 'retry-1',
1858
+ placeholderId: 'answer-retry-1-streaming'
1859
+ }, 'server_error');
1860
+ });
1861
+ expect(replaceMessagesMock).toHaveBeenCalledWith(chatMessagesState.messages);
1862
+ expect(dispatchSpy).toHaveBeenCalledWith(expect.objectContaining({
1863
+ type: 'snackbar-event',
1864
+ detail: expect.objectContaining({
1865
+ severity: 'error'
1866
+ })
1867
+ }));
1868
+ dispatchSpy.mockRestore();
1869
+ case 2:
1870
+ case "end":
1871
+ return _context50.stop();
1872
+ }
1873
+ }, _callee50);
1874
+ })));
1875
+ it('commits assistant attachments when an active stream finishes', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee52() {
1876
+ var attachment;
1877
+ return _regeneratorRuntime.wrap(function (_context52) {
1878
+ while (1) switch (_context52.prev = _context52.next) {
1879
+ case 0:
1880
+ activeView.set('session-1');
1881
+ useSessionsStore.setState({
1882
+ messages: {
1883
+ 'session-1': [{
1884
+ id: streamingPlaceholderMessageId('live-attach'),
1885
+ message: '',
1886
+ role: ChatHistoryRole.ASSISTANT,
1887
+ user: {
1888
+ id: 'assistant',
1889
+ name: 'MAIA'
1890
+ },
1891
+ date: new Date()
1892
+ }]
1893
+ }
1894
+ });
1895
+ renderHook(function () {
1896
+ return useChatManager({
1897
+ chatId: 'session-1',
1898
+ agents: [testAgent]
1899
+ });
1900
+ }, {
1901
+ wrapper: wrapper
1902
+ });
1903
+ attachment = {
1904
+ id: 'att-1',
1905
+ name: 'brief.pdf',
1906
+ type: 'pdf',
1907
+ size: 10,
1908
+ file: new File([], 'brief.pdf')
1909
+ };
1910
+ _context52.next = 1;
1911
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee51() {
1912
+ var _streamCallbacks$onFi6, _streamCallbacks12;
1913
+ return _regeneratorRuntime.wrap(function (_context51) {
1914
+ while (1) switch (_context51.prev = _context51.next) {
1915
+ case 0:
1916
+ _context51.next = 1;
1917
+ return (_streamCallbacks$onFi6 = (_streamCallbacks12 = streamCallbacks).onFinishStream) === null || _streamCallbacks$onFi6 === void 0 ? void 0 : _streamCallbacks$onFi6.call(_streamCallbacks12, {
1918
+ sessionId: 'session-1',
1919
+ messageId: 'live-attach',
1920
+ placeholderId: streamingPlaceholderMessageId('live-attach')
1921
+ }, 'Respuesta con adjunto', [], 'memory-attach-1', [attachment], null, null);
1922
+ case 1:
1923
+ case "end":
1924
+ return _context51.stop();
1925
+ }
1926
+ }, _callee51);
1927
+ })));
1928
+ case 1:
1929
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
1930
+ id: 'answer-memory-attach-1',
1931
+ attachments: expect.arrayContaining([expect.objectContaining({
1932
+ id: 'att-1',
1933
+ name: 'brief.pdf'
1934
+ })])
1935
+ }));
1936
+ case 2:
1937
+ case "end":
1938
+ return _context52.stop();
1939
+ }
1940
+ }, _callee52);
1941
+ })));
1942
+ it('syncs task deletion on the project dashboard after approval', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee54() {
1943
+ var deleteExistingTaskFromDashboard, originalPathname;
1944
+ return _regeneratorRuntime.wrap(function (_context54) {
1945
+ while (1) switch (_context54.prev = _context54.next) {
1946
+ case 0:
1947
+ deleteExistingTaskFromDashboard = jest.fn();
1948
+ window.newProjectDashboard = {
1949
+ deleteExistingTaskFromDashboard: deleteExistingTaskFromDashboard
1950
+ };
1951
+ originalPathname = window.location.pathname;
1952
+ Object.defineProperty(window, 'location', {
1953
+ configurable: true,
1954
+ value: _objectSpread(_objectSpread({}, window.location), {}, {
1955
+ pathname: '/projects/42/tasks'
1956
+ })
1957
+ });
1958
+ activeView.set('session-1');
1959
+ chatMessagesState.messages = [{
1960
+ id: 'approval-delete',
1961
+ message: '¿Elimino la tarea?',
1962
+ role: ChatHistoryRole.ASSISTANT,
1963
+ user: {
1964
+ id: 'assistant',
1965
+ name: 'MAIA'
1966
+ },
1967
+ date: new Date(),
1968
+ approvalStatus: 'approved',
1969
+ approval: {
1970
+ session_id: 'session-1',
1971
+ pending_actions: [{
1972
+ thread_id: 'd1',
1973
+ tool_name: 'delete_task',
1974
+ tool_args: {
1975
+ task_id: 77
1976
+ }
1977
+ }]
1978
+ }
1979
+ }];
1980
+ renderHook(function () {
1981
+ return useChatManager({
1982
+ chatId: 'session-1',
1983
+ agents: [testAgent]
1984
+ });
1985
+ }, {
1986
+ wrapper: function wrapper(_ref58) {
1987
+ var children = _ref58.children;
1988
+ return /*#__PURE__*/_jsx(GlobalContextTestProvider, {
1989
+ value: {
1990
+ agent: testAgent,
1991
+ project: {
1992
+ id: 42,
1993
+ name: 'Alpha'
1994
+ }
1995
+ },
1996
+ children: children
1997
+ });
1998
+ }
1999
+ });
2000
+ _context54.next = 1;
2001
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee53() {
2002
+ var _streamCallbacks$onFi7, _streamCallbacks13;
2003
+ return _regeneratorRuntime.wrap(function (_context53) {
2004
+ while (1) switch (_context53.prev = _context53.next) {
2005
+ case 0:
2006
+ _context53.next = 1;
2007
+ return (_streamCallbacks$onFi7 = (_streamCallbacks13 = streamCallbacks).onFinishStream) === null || _streamCallbacks$onFi7 === void 0 ? void 0 : _streamCallbacks$onFi7.call(_streamCallbacks13, {
2008
+ sessionId: 'session-1',
2009
+ messageId: 'delete-live',
2010
+ placeholderId: streamingPlaceholderMessageId('delete-live')
2011
+ }, 'Tarea eliminada', [], 'memory-delete-1');
2012
+ case 1:
2013
+ case "end":
2014
+ return _context53.stop();
2015
+ }
2016
+ }, _callee53);
2017
+ })));
2018
+ case 1:
2019
+ expect(deleteExistingTaskFromDashboard).toHaveBeenCalledWith([77]);
2020
+ Object.defineProperty(window, 'location', {
2021
+ configurable: true,
2022
+ value: _objectSpread(_objectSpread({}, window.location), {}, {
2023
+ pathname: originalPathname
2024
+ })
2025
+ });
2026
+ delete window.newProjectDashboard;
2027
+ case 2:
2028
+ case "end":
2029
+ return _context54.stop();
2030
+ }
2031
+ }, _callee54);
2032
+ })));
2033
+ it('commits a pending approval message on the active session', function () {
2034
+ activeView.set('session-1');
2035
+ renderHook(function () {
2036
+ return useChatManager({
2037
+ chatId: 'session-1',
2038
+ agents: [testAgent]
2039
+ });
2040
+ }, {
2041
+ wrapper: wrapper
2042
+ });
2043
+ act(function () {
2044
+ var _streamCallbacks$onAp, _streamCallbacks14;
2045
+ (_streamCallbacks$onAp = (_streamCallbacks14 = streamCallbacks).onApprovalRequired) === null || _streamCallbacks$onAp === void 0 || _streamCallbacks$onAp.call(_streamCallbacks14, {
2046
+ sessionId: 'session-1',
2047
+ messageId: 'live-hitl',
2048
+ placeholderId: streamingPlaceholderMessageId('live-hitl')
2049
+ }, {
2050
+ type: 'approval_required',
2051
+ session_id: 'session-1',
2052
+ original_thread_id: 'orig-1',
2053
+ pending_actions: [{
2054
+ thread_id: 't1',
2055
+ tool_name: 'edit_task',
2056
+ tool_args: {
2057
+ task_id: 1
2058
+ },
2059
+ tool_call_id: 'c1'
2060
+ }],
2061
+ total_actions: 1,
2062
+ metadata: {}
2063
+ }, '¿Confirmás la edición?');
2064
+ });
2065
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
2066
+ approvalStatus: 'pending',
2067
+ message: '¿Confirmás la edición?'
2068
+ }));
2069
+ });
2070
+ it('does not paint approval UI when the stream was auto-approved', function () {
2071
+ activeView.set('session-1');
2072
+ renderHook(function () {
2073
+ return useChatManager({
2074
+ chatId: 'session-1',
2075
+ agents: [testAgent]
2076
+ });
2077
+ }, {
2078
+ wrapper: wrapper
2079
+ });
2080
+ act(function () {
2081
+ var _streamCallbacks$onAp2, _streamCallbacks15;
2082
+ (_streamCallbacks$onAp2 = (_streamCallbacks15 = streamCallbacks).onApprovalRequired) === null || _streamCallbacks$onAp2 === void 0 || _streamCallbacks$onAp2.call(_streamCallbacks15, {
2083
+ sessionId: 'session-1',
2084
+ messageId: 'auto-hitl',
2085
+ placeholderId: streamingPlaceholderMessageId('auto-hitl')
2086
+ }, {
2087
+ type: 'approval_required',
2088
+ session_id: 'session-1',
2089
+ original_thread_id: 'orig-auto',
2090
+ pending_actions: [{
2091
+ thread_id: 't-auto',
2092
+ tool_name: 'create_task',
2093
+ tool_args: {},
2094
+ tool_call_id: 'c-auto'
2095
+ }],
2096
+ total_actions: 1,
2097
+ metadata: {},
2098
+ auto_approved: true
2099
+ }, 'Creando tarea');
2100
+ });
2101
+ expect(addMessageMock).not.toHaveBeenCalled();
2102
+ });
2103
+ it('marks background sessions unread when approval is required off-screen', function () {
2104
+ activeView.set('session-visible');
2105
+ renderHook(function () {
2106
+ return useChatManager({
2107
+ chatId: 'session-visible',
2108
+ agents: [testAgent]
2109
+ });
2110
+ }, {
2111
+ wrapper: wrapper
2112
+ });
2113
+ act(function () {
2114
+ var _streamCallbacks$onAp3, _streamCallbacks16;
2115
+ (_streamCallbacks$onAp3 = (_streamCallbacks16 = streamCallbacks).onApprovalRequired) === null || _streamCallbacks$onAp3 === void 0 || _streamCallbacks$onAp3.call(_streamCallbacks16, {
2116
+ sessionId: 'session-bg',
2117
+ messageId: 'bg-hitl',
2118
+ placeholderId: streamingPlaceholderMessageId('bg-hitl')
2119
+ }, {
2120
+ type: 'approval_required',
2121
+ session_id: 'session-bg',
2122
+ original_thread_id: 'orig-bg',
2123
+ pending_actions: [{
2124
+ thread_id: 't-bg',
2125
+ tool_name: 'edit_task',
2126
+ tool_args: {},
2127
+ tool_call_id: 'c-bg'
2128
+ }],
2129
+ total_actions: 1,
2130
+ metadata: {}
2131
+ }, 'Aprobación pendiente');
2132
+ });
2133
+ expect(getChatsStoreState().markChatAsUnread).toHaveBeenCalledWith('session-bg');
2134
+ expect(notifySessionFinishedInBackground).toHaveBeenCalledWith('session-bg', 'approval_required');
2135
+ expect(addMessageMock).not.toHaveBeenCalled();
2136
+ });
2137
+ it('clears pinned context when switching to another existing chat', function () {
2138
+ var setProject = jest.fn();
2139
+ var setClient = jest.fn();
2140
+ var setChipsProject = jest.fn();
2141
+ var setTask = jest.fn();
2142
+ var contextWrapper = function contextWrapper(_ref60) {
2143
+ var children = _ref60.children;
2144
+ return /*#__PURE__*/_jsx(GlobalContextTestProvider, {
2145
+ value: {
2146
+ agent: testAgent,
2147
+ setProject: setProject,
2148
+ setClient: setClient,
2149
+ setChipsProject: setChipsProject,
2150
+ setTask: setTask
2151
+ },
2152
+ children: children
2153
+ });
2154
+ };
2155
+ var _renderHook24 = renderHook(function (_ref61) {
2156
+ var chatId = _ref61.chatId;
2157
+ return useChatManager({
2158
+ chatId: chatId,
2159
+ agents: [testAgent]
2160
+ });
2161
+ }, {
2162
+ wrapper: contextWrapper,
2163
+ initialProps: {
2164
+ chatId: 'session-a'
2165
+ }
2166
+ }),
2167
+ rerender = _renderHook24.rerender;
2168
+ sessionStreamManager.isActive.mockReturnValue(true);
2169
+ rerender({
2170
+ chatId: 'session-b'
2171
+ });
2172
+ expect(setProject).toHaveBeenCalledWith(null);
2173
+ expect(setClient).toHaveBeenCalledWith(null);
2174
+ expect(setChipsProject).toHaveBeenCalledWith(null);
2175
+ expect(setTask).toHaveBeenCalledWith(null);
2176
+ });
2177
+ it('commits partial assistant text when the stream stops mid-response', function () {
2178
+ activeView.set('session-1');
2179
+ renderHook(function () {
2180
+ return useChatManager({
2181
+ chatId: 'session-1',
2182
+ agents: [testAgent]
2183
+ });
2184
+ }, {
2185
+ wrapper: wrapper
2186
+ });
2187
+ var ctx = {
2188
+ sessionId: 'session-1',
2189
+ messageId: 'live-stop-1',
2190
+ placeholderId: streamingPlaceholderMessageId('live-stop-1')
2191
+ };
2192
+ act(function () {
2193
+ var _streamCallbacks$onSt2, _streamCallbacks17;
2194
+ (_streamCallbacks$onSt2 = (_streamCallbacks17 = streamCallbacks).onStreamUpdate) === null || _streamCallbacks$onSt2 === void 0 || _streamCallbacks$onSt2.call(_streamCallbacks17, ctx, 'Parcial');
2195
+ });
2196
+ act(function () {
2197
+ var _streamCallbacks$onSt3, _streamCallbacks18;
2198
+ (_streamCallbacks$onSt3 = (_streamCallbacks18 = streamCallbacks).onStop) === null || _streamCallbacks$onSt3 === void 0 || _streamCallbacks$onSt3.call(_streamCallbacks18, 'Parcial');
2199
+ });
2200
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
2201
+ message: 'Parcial',
2202
+ role: ChatHistoryRole.ASSISTANT
2203
+ }));
2204
+ expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
2205
+ role: ChatHistoryRole.ASSISTANT,
2206
+ message: expect.stringMatching(/cancel/i)
2207
+ }));
2208
+ });
2209
+ it('replays via orchestrator when retryCompletion reports turn_not_found', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee56() {
2210
+ var _renderHook25, result;
2211
+ return _regeneratorRuntime.wrap(function (_context56) {
2212
+ while (1) switch (_context56.prev = _context56.next) {
2213
+ case 0:
2214
+ chatMessagesState.messages = [{
2215
+ id: 'question-retry',
2216
+ message: '¿Status?',
2217
+ role: ChatHistoryRole.USER,
2218
+ user: {
2219
+ id: '7',
2220
+ name: 'Ana'
2221
+ },
2222
+ date: new Date()
2223
+ }, {
2224
+ id: 'answer-turn-abc',
2225
+ message: 'Error',
2226
+ role: ChatHistoryRole.ASSISTANT,
2227
+ user: {
2228
+ id: 'assistant',
2229
+ name: 'MAIA'
2230
+ },
2231
+ date: new Date(),
2232
+ isError: true,
2233
+ memorySessionId: 'turn-abc'
2234
+ }];
2235
+ retryCompletionMock.mockResolvedValue({
2236
+ started: false,
2237
+ reason: 'turn_not_found'
2238
+ });
2239
+ _renderHook25 = renderHook(function () {
2240
+ return useChatManager({
2241
+ chatId: 'session-1',
2242
+ agents: [testAgent]
2243
+ });
2244
+ }, {
2245
+ wrapper: wrapper
2246
+ }), result = _renderHook25.result;
2247
+ _context56.next = 1;
2248
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee55() {
2249
+ return _regeneratorRuntime.wrap(function (_context55) {
2250
+ while (1) switch (_context55.prev = _context55.next) {
2251
+ case 0:
2252
+ _context55.next = 1;
2253
+ return result.current.retryMessage(chatMessagesState.messages[1]);
2254
+ case 1:
2255
+ case "end":
2256
+ return _context55.stop();
2257
+ }
2258
+ }, _callee55);
2259
+ })));
2260
+ case 1:
2261
+ expect(retryCompletionMock).toHaveBeenCalled();
2262
+ expect(askMaiaMock).toHaveBeenCalledWith(expect.objectContaining({
2263
+ message: '¿Status?'
2264
+ }));
2265
+ case 2:
2266
+ case "end":
2267
+ return _context56.stop();
2268
+ }
2269
+ }, _callee56);
2270
+ })));
2271
+ it('shows a snackbar when retryCompletion hits the concurrent stream limit', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee58() {
2272
+ var dispatchSpy, _renderHook26, result;
2273
+ return _regeneratorRuntime.wrap(function (_context58) {
2274
+ while (1) switch (_context58.prev = _context58.next) {
2275
+ case 0:
2276
+ chatMessagesState.messages = [{
2277
+ id: 'question-limit',
2278
+ message: 'Retry me',
2279
+ role: ChatHistoryRole.USER,
2280
+ user: {
2281
+ id: '7',
2282
+ name: 'Ana'
2283
+ },
2284
+ date: new Date()
2285
+ }, {
2286
+ id: 'answer-turn-limit',
2287
+ message: 'Error',
2288
+ role: ChatHistoryRole.ASSISTANT,
2289
+ user: {
2290
+ id: 'assistant',
2291
+ name: 'MAIA'
2292
+ },
2293
+ date: new Date(),
2294
+ isError: true,
2295
+ memorySessionId: 'turn-limit'
2296
+ }];
2297
+ retryCompletionMock.mockResolvedValue({
2298
+ started: false,
2299
+ reason: 'limit'
2300
+ });
2301
+ dispatchSpy = jest.spyOn(document, 'dispatchEvent');
2302
+ _renderHook26 = renderHook(function () {
2303
+ return useChatManager({
2304
+ chatId: 'session-1',
2305
+ agents: [testAgent]
2306
+ });
2307
+ }, {
2308
+ wrapper: wrapper
2309
+ }), result = _renderHook26.result;
2310
+ _context58.next = 1;
2311
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee57() {
2312
+ return _regeneratorRuntime.wrap(function (_context57) {
2313
+ while (1) switch (_context57.prev = _context57.next) {
2314
+ case 0:
2315
+ _context57.next = 1;
2316
+ return result.current.retryMessage(chatMessagesState.messages[1]);
2317
+ case 1:
2318
+ case "end":
2319
+ return _context57.stop();
2320
+ }
2321
+ }, _callee57);
2322
+ })));
2323
+ case 1:
2324
+ expect(dispatchSpy).toHaveBeenCalledWith(expect.objectContaining({
2325
+ type: 'snackbar-event',
2326
+ detail: expect.objectContaining({
2327
+ message: expect.any(String)
2328
+ })
2329
+ }));
2330
+ dispatchSpy.mockRestore();
2331
+ case 2:
2332
+ case "end":
2333
+ return _context58.stop();
2334
+ }
2335
+ }, _callee58);
2336
+ })));
2337
+ it('shows a snackbar when replayViaOrchestrator hits the concurrent stream limit', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee60() {
2338
+ var dispatchSpy, _renderHook27, result;
2339
+ return _regeneratorRuntime.wrap(function (_context60) {
2340
+ while (1) switch (_context60.prev = _context60.next) {
2341
+ case 0:
2342
+ chatMessagesState.messages = [{
2343
+ id: 'question-replay-limit',
2344
+ message: 'Hola',
2345
+ role: ChatHistoryRole.USER,
2346
+ user: {
2347
+ id: '7',
2348
+ name: 'Ana'
2349
+ },
2350
+ date: new Date()
2351
+ }, {
2352
+ id: 'answer-turn-replay-limit',
2353
+ message: 'Error',
2354
+ role: ChatHistoryRole.ASSISTANT,
2355
+ user: {
2356
+ id: 'assistant',
2357
+ name: 'MAIA'
2358
+ },
2359
+ date: new Date(),
2360
+ isError: true,
2361
+ memorySessionId: 'turn-replay-limit'
2362
+ }];
2363
+ retryCompletionMock.mockResolvedValue({
2364
+ started: false,
2365
+ reason: 'turn_not_found'
2366
+ });
2367
+ askMaiaMock.mockResolvedValue({
2368
+ started: false,
2369
+ reason: 'limit'
2370
+ });
2371
+ dispatchSpy = jest.spyOn(document, 'dispatchEvent');
2372
+ _renderHook27 = renderHook(function () {
2373
+ return useChatManager({
2374
+ chatId: 'session-1',
2375
+ agents: [testAgent]
2376
+ });
2377
+ }, {
2378
+ wrapper: wrapper
2379
+ }), result = _renderHook27.result;
2380
+ _context60.next = 1;
2381
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee59() {
2382
+ return _regeneratorRuntime.wrap(function (_context59) {
2383
+ while (1) switch (_context59.prev = _context59.next) {
2384
+ case 0:
2385
+ _context59.next = 1;
2386
+ return result.current.retryMessage(chatMessagesState.messages[1]);
2387
+ case 1:
2388
+ case "end":
2389
+ return _context59.stop();
2390
+ }
2391
+ }, _callee59);
2392
+ })));
2393
+ case 1:
2394
+ expect(dispatchSpy).toHaveBeenCalledWith(expect.objectContaining({
2395
+ type: 'snackbar-event'
2396
+ }));
2397
+ dispatchSpy.mockRestore();
2398
+ case 2:
2399
+ case "end":
2400
+ return _context60.stop();
2401
+ }
2402
+ }, _callee60);
2403
+ })));
2404
+ it('shows a snackbar when approval continue stream fails to start due to limit', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee62() {
2405
+ var dispatchSpy, _renderHook28, result;
2406
+ return _regeneratorRuntime.wrap(function (_context62) {
2407
+ while (1) switch (_context62.prev = _context62.next) {
2408
+ case 0:
2409
+ activeView.set('session-1');
2410
+ startContinueStreamMock.mockResolvedValue({
2411
+ started: false,
2412
+ reason: 'limit'
2413
+ });
2414
+ dispatchSpy = jest.spyOn(document, 'dispatchEvent');
2415
+ chatMessagesState.messages = [{
2416
+ id: 'msg-approval-limit',
2417
+ message: 'Approve?',
2418
+ role: ChatHistoryRole.ASSISTANT,
2419
+ user: {
2420
+ id: 'assistant',
2421
+ name: 'MAIA'
2422
+ },
2423
+ date: new Date(),
2424
+ approval: {
2425
+ session_id: 'session-1',
2426
+ pending_actions: [{
2427
+ thread_id: 'thread-limit',
2428
+ tool_name: 'edit_task',
2429
+ tool_args: {}
2430
+ }]
2431
+ }
2432
+ }];
2433
+ _renderHook28 = renderHook(function () {
2434
+ return useChatManager({
2435
+ chatId: 'session-1',
2436
+ agents: [testAgent]
2437
+ });
2438
+ }, {
2439
+ wrapper: wrapper
2440
+ }), result = _renderHook28.result;
2441
+ _context62.next = 1;
2442
+ return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee61() {
2443
+ return _regeneratorRuntime.wrap(function (_context61) {
2444
+ while (1) switch (_context61.prev = _context61.next) {
2445
+ case 0:
2446
+ _context61.next = 1;
2447
+ return result.current.handleApprovalDecision(['thread-limit'], 'approve');
2448
+ case 1:
2449
+ case "end":
2450
+ return _context61.stop();
2451
+ }
2452
+ }, _callee61);
2453
+ })));
2454
+ case 1:
2455
+ expect(startContinueStreamMock).toHaveBeenCalled();
2456
+ expect(dispatchSpy).toHaveBeenCalledWith(expect.objectContaining({
2457
+ type: 'snackbar-event'
2458
+ }));
2459
+ dispatchSpy.mockRestore();
2460
+ case 2:
2461
+ case "end":
2462
+ return _context62.stop();
2463
+ }
2464
+ }, _callee62);
2465
+ })));
2466
+ });
2467
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhY3QiLCJyZW5kZXJIb29rIiwiR2xvYmFsQ29udGV4dFRlc3RQcm92aWRlciIsInRlc3RBZ2VudCIsInVzZVNlc3Npb25zU3RvcmUiLCJzZXNzaW9uU3RyZWFtTWFuYWdlciIsIkNoYXRIaXN0b3J5Um9sZSIsIkZlZWRiYWNrIiwibWFpYSIsImFjdGl2ZVZpZXciLCJ1c2VPcmNoZXN0cmF0b3JTdHJlYW0iLCJnZXRDaGF0c1N0b3JlU3RhdGUiLCJub3RpZnlTZXNzaW9uRmluaXNoZWRJbkJhY2tncm91bmQiLCJmZXRjaEFnZW50RGV0YWlsIiwiTUFJQV9IT1VSU19DSEFSR0VEX0VWRU5UIiwic3RyZWFtaW5nUGxhY2Vob2xkZXJNZXNzYWdlSWQiLCJ1c2VNdWx0aXBsZUNob2ljZVN0b3JlIiwidXNlQ2hhdE1hbmFnZXIiLCJqc3giLCJfanN4IiwiZmV0Y2hBZ2VudERldGFpbE1vY2siLCJtb2NrVXNlT3JjaGVzdHJhdG9yU3RyZWFtIiwic3RyZWFtQ2FsbGJhY2tzIiwic3RhcnRDb250aW51ZVN0cmVhbU1vY2siLCJqZXN0IiwiZm4iLCJtb2NrUmVzb2x2ZWRWYWx1ZSIsInN0YXJ0ZWQiLCJhc2tNYWlhTW9jayIsInJldHJ5Q29tcGxldGlvbk1vY2siLCJzdG9wU3RyZWFtaW5nTW9jayIsInJlcGxhY2VNZXNzYWdlc01vY2siLCJhZGRNZXNzYWdlTW9jayIsImV2ZW50TW9jayIsImNoYXRNZXNzYWdlc1N0YXRlIiwibG9hZGluZ01lc3NhZ2VzIiwibWVzc2FnZXMiLCJpc0xvYWRpbmdNb3JlTWVzc2FnZXMiLCJsb2FkTWVzc2FnZXMiLCJhZGRNZXNzYWdlIiwicmVtb3ZlTWVzc2FnZSIsInJlcGxhY2VNZXNzYWdlcyIsImhhbmRsZVNjcm9sbCIsIm1vY2siLCJ1c2VDaGF0TWVzc2FnZXMiLCJ1c2VQcm9qZWN0cyIsImZldGNoUHJvamVjdHMiLCJ1c2VUYWJUYXNrRGVmYXVsdCIsImdldFRhYlRhc2tEZWZhdWx0IiwiRVZFTlRTIiwicG1BaVR5cGVkVGV4dCIsInVzZUV2ZW50IiwidXNlVXNlciIsImlkIiwiZmlyc3ROYW1lIiwibGFzdE5hbWUiLCJwaWN0dXJlIiwibGFuZyIsImNvbXBhbnlfaWQiLCJzdGF0ZSIsInNldEFjdGl2ZUNoYXRJZCIsIm1hcmtDaGF0QXNSZWFkIiwibWFya0NoYXRBc1VucmVhZCIsImlzQ2hhdFZpZXdWaXNpYmxlIiwiY2hhdHMiLCJwcmVwZW5kQ2hhdCIsInVzZUNoYXRzU3RvcmUiLCJzZWxlY3RvciIsIk9iamVjdCIsImFzc2lnbiIsImdldFN0YXRlIiwiX19lc01vZHVsZSIsIkNoYXRzIiwid2FzSGVscGZ1bENoYXQiLCJlbnN1cmVTZXNzaW9uTm90aWZpY2F0aW9uc0luaXRpYWxpemVkIiwiaXNBY3RpdmUiLCJnZXRBY3RpdmVDb3VudCIsInN0YXJ0U3RyZWFtIiwic3RhcnRDb250aW51ZVN0cmVhbSIsImFwcGx5IiwiYXJndW1lbnRzIiwic3RvcFN0cmVhbSIsIk1BWF9DT05DVVJSRU5UX1NUUkVBTVMiLCJ3cmFwcGVyIiwiX3JlZiIsImNoaWxkcmVuIiwidmFsdWUiLCJhZ2VudCIsImRlc2NyaWJlIiwiYmVmb3JlRWFjaCIsImNsZWFyQWxsTW9ja3MiLCJtb2NrSW1wbGVtZW50YXRpb24iLCJvcHRpb25zIiwib25FcnJvciIsIm9uU3RyZWFtVXBkYXRlIiwib25TdG9wIiwib25BcHByb3ZhbFJlcXVpcmVkIiwib25GaW5pc2hTdHJlYW0iLCJhc2tNYWlhIiwicmV0cnlDb21wbGV0aW9uIiwiaXNMb2FkaW5nIiwiaXNXcml0aW5nIiwibG9hZGluZ01lc3NhZ2UiLCJzdHJlYW1BY3Rpdml0eSIsInVwZGF0ZVN0cmVhbUFjdGl2aXR5Iiwic3RvcFN0cmVhbWluZyIsInNldFN0YXRlIiwibWV0YSIsInZpZXdDYWNoZSIsInNldCIsIm1vY2tSZXR1cm5WYWx1ZSIsIml0IiwiX3JlbmRlckhvb2siLCJjaGF0SWQiLCJhZ2VudHMiLCJyZXN1bHQiLCJleHBlY3QiLCJjdXJyZW50IiwidG9FcXVhbCIsImlzRGlzYWJsZWQiLCJ0b0JlIiwiX2FzeW5jVG9HZW5lcmF0b3IiLCJfcmVnZW5lcmF0b3JSdW50aW1lIiwibWFyayIsIl9jYWxsZWUyIiwiX3JlbmRlckhvb2syIiwid3JhcCIsIl9jb250ZXh0MiIsInByZXYiLCJuZXh0IiwiX2NhbGxlZSIsIl9jb250ZXh0Iiwic2VuZE1lc3NhZ2UiLCJzdG9wIiwidG9IYXZlQmVlbkNhbGxlZFdpdGgiLCJvYmplY3RDb250YWluaW5nIiwibWVzc2FnZSIsImFnZW50SWQiLCJhZ2VudE5hbWUiLCJuYW1lIiwicm9sZSIsIl9jYWxsZWU0IiwiX3JlbmRlckhvb2szIiwiX2NvbnRleHQ0IiwicGVuZGluZyIsIm1lc3NhZ2VJZCIsInF1ZXN0aW9uIiwiYW5zd2VyIiwiZGlzbWlzc2VkTWVzc2FnZUlkcyIsImFuc3dlclBlbmRpbmciLCJrZXkiLCJfY2FsbGVlMyIsIl9jb250ZXh0MyIsInRvSGF2ZUJlZW5MYXN0Q2FsbGVkV2l0aCIsIm11bHRpcGxlQ2hvaWNlQW5zd2VyIiwidG9CZU51bGwiLCJfY2FsbGVlNiIsImRpc3BhdGNoU3B5IiwiX3JlbmRlckhvb2s0IiwiX2NvbnRleHQ2Iiwic3B5T24iLCJkb2N1bWVudCIsIl9jYWxsZWU1IiwiX2NvbnRleHQ1Iiwibm90IiwidG9IYXZlQmVlbkNhbGxlZCIsInR5cGUiLCJtb2NrUmVzdG9yZSIsIl9yZW5kZXJIb29rNSIsInN0b3BHZW5lcmF0aW9uIiwiX3JlbmRlckhvb2s2IiwicmVzZXRDaGF0IiwiY3VycmVudENoYXRJZCIsIl9jYWxsZWU4IiwiX3JlbmRlckhvb2s3IiwiX2NvbnRleHQ4IiwiX2NhbGxlZTciLCJfY29udGV4dDciLCJfY2FsbGVlMCIsIl9yZW5kZXJIb29rOCIsIl9jb250ZXh0MCIsIl9jYWxsZWU5IiwiX2NvbnRleHQ5IiwibWVudGlvbnMiLCJsYWJlbCIsImNvbnRleHRNZXNzYWdlIiwidXNlciIsImFycmF5Q29udGFpbmluZyIsIl9jYWxsZWUxMCIsIl9yZW5kZXJIb29rOSIsIl9jb250ZXh0MTAiLCJVU0VSIiwiZGF0ZSIsIkRhdGUiLCJBU1NJU1RBTlQiLCJpc0Zyb250ZW5kQ2FuY2VsbGVkIiwiX2NhbGxlZTEiLCJfY29udGV4dDEiLCJyZXRyeU1lc3NhZ2UiLCJfY2FsbGVlMTIiLCJzZXRQcm9qZWN0IiwicHJvamVjdCIsIl9yZW5kZXJIb29rMCIsIl9jb250ZXh0MTIiLCJfcmVmMTMiLCJfY2FsbGVlMTEiLCJfY29udGV4dDExIiwibW9ja0NsZWFyIiwiY2hhbmdlUHJvamVjdCIsImZlZUlkIiwiY2xpZW50SWQiLCJwcm9qZWN0SWQiLCJfcmVuZGVySG9vazEiLCJfY2FsbGVlMTQiLCJfcmVuZGVySG9vazEwIiwiX2NvbnRleHQxNCIsImFwcHJvdmFsIiwic2Vzc2lvbl9pZCIsInBlbmRpbmdfYWN0aW9ucyIsInRocmVhZF9pZCIsInRvb2xfbmFtZSIsInRvb2xfYXJncyIsInRhc2tfaWQiLCJfY2FsbGVlMTMiLCJfY29udGV4dDEzIiwiaGFuZGxlQXBwcm92YWxEZWNpc2lvbiIsImNvbnRpbnVlUmVxdWVzdCIsImRlY2lzaW9uIiwiX2NhbGxlZTE2IiwiX3JlbmRlckhvb2sxMSIsIl9jb250ZXh0MTYiLCJfY2FsbGVlMTUiLCJfY29udGV4dDE1Iiwic2Vzc2lvbklkIiwidGhyZWFkSWRzIiwiX2NhbGxlZTE4IiwiX3JlbmRlckhvb2sxMiIsIl9jb250ZXh0MTgiLCJtb2NrZWQiLCJfY2FsbGVlMTciLCJfY29udGV4dDE3IiwiaGFuZGxlRmVlZGJhY2siLCJUSFVNQlNfVVAiLCJfY2FsbGVlMjAiLCJfcmVuZGVySG9vazEzIiwiX2NvbnRleHQyMCIsIl9jYWxsZWUxOSIsIl9jb250ZXh0MTkiLCJUSFVNQlNfRE9XTiIsInRvSGF2ZVByb3BlcnR5IiwiX2NhbGxlZTIyIiwiY29uc29sZVNweSIsIl9yZW5kZXJIb29rMTQiLCJfY29udGV4dDIyIiwiY29uc29sZSIsInVuZGVmaW5lZCIsIl9jYWxsZWUyMSIsIl9jb250ZXh0MjEiLCJfY2FsbGVlMjQiLCJhdHRhY2htZW50IiwiX3JlbmRlckhvb2sxNSIsIl9jb250ZXh0MjQiLCJzaXplIiwiZmlsZSIsIkZpbGUiLCJfY2FsbGVlMjMiLCJfY29udGV4dDIzIiwiYXR0YWNobWVudHMiLCJfY2FsbGVlMjYiLCJfcmVuZGVySG9vazE2IiwiX2NvbnRleHQyNiIsIl9jYWxsZWUyNSIsIl9jb250ZXh0MjUiLCJpbml0aWFsaXplQ2hhdCIsIl9jYWxsZWUyOCIsIl9yZW5kZXJIb29rMTciLCJfY29udGV4dDI4IiwidXNlckluaXRpYWxNZXNzYWdlIiwiZmFxSWQiLCJfY2FsbGVlMjciLCJfY29udGV4dDI3IiwiX2NhbGxlZTMwIiwiX3JlbmRlckhvb2sxOCIsIl9jb250ZXh0MzAiLCJfY2FsbGVlMjkiLCJfY29udGV4dDI5IiwiX2NhbGxlZTMyIiwiX3JlbmRlckhvb2sxOSIsIl9jb250ZXh0MzIiLCJfY2FsbGVlMzEiLCJfY29udGV4dDMxIiwiX2NhbGxlZTM0IiwiX3JlbmRlckhvb2syMCIsIl9jb250ZXh0MzQiLCJfY2FsbGVlMzMiLCJfY29udGV4dDMzIiwiX2NhbGxlZTM2IiwiZWRpdGVkQWN0aW9ucyIsIl9yZW5kZXJIb29rMjEiLCJfY29udGV4dDM2IiwiYXJncyIsIl9jYWxsZWUzNSIsIl9jb250ZXh0MzUiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRXIiLCJfc3RyZWFtQ2FsbGJhY2tzIiwiY2FsbCIsInBsYWNlaG9sZGVySWQiLCJpc0Vycm9yIiwic3VnZ2VzdGlvbnMiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRXIyIiwiX3N0cmVhbUNhbGxiYWNrczIiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRXIzIiwiX3N0cmVhbUNhbGxiYWNrczMiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRXI0IiwiX3N0cmVhbUNhbGxiYWNrczQiLCJjdHgiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uU3QiLCJfc3RyZWFtQ2FsbGJhY2tzNSIsImdldE1lc3NhZ2VzIiwiX2NhbGxlZTM4IiwiX2NvbnRleHQzOCIsIl9jYWxsZWUzNyIsIl9zdHJlYW1DYWxsYmFja3Mkb25GaSIsIl9zdHJlYW1DYWxsYmFja3M2IiwiX2NvbnRleHQzNyIsIl9zdHJlYW1DYWxsYmFja3Mkb25FcjUiLCJfc3RyZWFtQ2FsbGJhY2tzNyIsInN0cmluZ0NvbnRhaW5pbmciLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRXI2IiwiX3N0cmVhbUNhbGxiYWNrczgiLCJfY2FsbGVlNDAiLCJhZGRFeGlzdGluZ1Rhc2tUb0Rhc2hib2FyZCIsIm9yaWdpbmFsUGF0aG5hbWUiLCJ0YXNrVXJsIiwiX2NvbnRleHQ0MCIsIndpbmRvdyIsIm5ld1Byb2plY3REYXNoYm9hcmQiLCJsb2NhdGlvbiIsInBhdGhuYW1lIiwiZGVmaW5lUHJvcGVydHkiLCJjb25maWd1cmFibGUiLCJfb2JqZWN0U3ByZWFkIiwiYXBwcm92YWxTdGF0dXMiLCJfcmVmNDIiLCJfY2FsbGVlMzkiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRmkyIiwiX3N0cmVhbUNhbGxiYWNrczkiLCJfY29udGV4dDM5IiwiX2NhbGxlZTQyIiwib25Ib3Vyc0NoYXJnZWQiLCJldmVudCIsIl9jb250ZXh0NDIiLCJhZGRFdmVudExpc3RlbmVyIiwiX2NhbGxlZTQxIiwiX3N0cmVhbUNhbGxiYWNrcyRvbkZpMyIsIl9zdHJlYW1DYWxsYmFja3MwIiwiX2NvbnRleHQ0MSIsImNhbGxzIiwiZGV0YWlsIiwidG9vbHMiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiX2NhbGxlZTQ0Iiwib25NZXJnZUFnZW50IiwiX2NvbnRleHQ0NCIsIk1BSUFfQ0hBVF9BSV9GRUFUVVJFX0FDQ0VTU19NVUxUSV9BR0VOVFMiLCJfY2FsbGVlNDMiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRmk0IiwiX3N0cmVhbUNhbGxiYWNrczEiLCJfY29udGV4dDQzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJfY2FsbGVlNDYiLCJyZWZldGNoVGFzayIsIl9jb250ZXh0NDYiLCJ0YXNrUGFuZWwiLCJ0YXNrSWQiLCJfY2FsbGVlNDUiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRmk1IiwiX3N0cmVhbUNhbGxiYWNrczEwIiwiX2NvbnRleHQ0NSIsIl9jYWxsZWU0OCIsIl9jb250ZXh0NDgiLCJzdGF0dXMiLCJmaW5pc2hlZEF0IiwiX2NhbGxlZTQ3IiwiX2NvbnRleHQ0NyIsImZvcmNlIiwiX3JlbmRlckhvb2syMiIsIl9yZWY1MiIsImluaXRpYWxQcm9wcyIsInJlcmVuZGVyIiwiX2NhbGxlZTUwIiwiX3JlbmRlckhvb2syMyIsIl9jb250ZXh0NTAiLCJfY2FsbGVlNDkiLCJfY29udGV4dDQ5IiwiX3N0cmVhbUNhbGxiYWNrcyRvbkVyNyIsIl9zdHJlYW1DYWxsYmFja3MxMSIsInNldmVyaXR5IiwiX2NhbGxlZTUyIiwiX2NvbnRleHQ1MiIsIl9jYWxsZWU1MSIsIl9zdHJlYW1DYWxsYmFja3Mkb25GaTYiLCJfc3RyZWFtQ2FsbGJhY2tzMTIiLCJfY29udGV4dDUxIiwiX2NhbGxlZTU0IiwiZGVsZXRlRXhpc3RpbmdUYXNrRnJvbURhc2hib2FyZCIsIl9jb250ZXh0NTQiLCJfcmVmNTgiLCJfY2FsbGVlNTMiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uRmk3IiwiX3N0cmVhbUNhbGxiYWNrczEzIiwiX2NvbnRleHQ1MyIsIl9zdHJlYW1DYWxsYmFja3Mkb25BcCIsIl9zdHJlYW1DYWxsYmFja3MxNCIsIm9yaWdpbmFsX3RocmVhZF9pZCIsInRvb2xfY2FsbF9pZCIsInRvdGFsX2FjdGlvbnMiLCJtZXRhZGF0YSIsIl9zdHJlYW1DYWxsYmFja3Mkb25BcDIiLCJfc3RyZWFtQ2FsbGJhY2tzMTUiLCJhdXRvX2FwcHJvdmVkIiwiX3N0cmVhbUNhbGxiYWNrcyRvbkFwMyIsIl9zdHJlYW1DYWxsYmFja3MxNiIsInNldENsaWVudCIsInNldENoaXBzUHJvamVjdCIsInNldFRhc2siLCJjb250ZXh0V3JhcHBlciIsIl9yZWY2MCIsIl9yZW5kZXJIb29rMjQiLCJfcmVmNjEiLCJfc3RyZWFtQ2FsbGJhY2tzJG9uU3QyIiwiX3N0cmVhbUNhbGxiYWNrczE3IiwiX3N0cmVhbUNhbGxiYWNrcyRvblN0MyIsIl9zdHJlYW1DYWxsYmFja3MxOCIsInN0cmluZ01hdGNoaW5nIiwiX2NhbGxlZTU2IiwiX3JlbmRlckhvb2syNSIsIl9jb250ZXh0NTYiLCJtZW1vcnlTZXNzaW9uSWQiLCJyZWFzb24iLCJfY2FsbGVlNTUiLCJfY29udGV4dDU1IiwiX2NhbGxlZTU4IiwiX3JlbmRlckhvb2syNiIsIl9jb250ZXh0NTgiLCJfY2FsbGVlNTciLCJfY29udGV4dDU3IiwiYW55IiwiU3RyaW5nIiwiX2NhbGxlZTYwIiwiX3JlbmRlckhvb2syNyIsIl9jb250ZXh0NjAiLCJfY2FsbGVlNTkiLCJfY29udGV4dDU5IiwiX2NhbGxlZTYyIiwiX3JlbmRlckhvb2syOCIsIl9jb250ZXh0NjIiLCJfY2FsbGVlNjEiLCJfY29udGV4dDYxIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hvb2tzL3VzZUNoYXRNYW5hZ2VyL3VzZUNoYXRNYW5hZ2VyLnNwZWMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlYWN0Tm9kZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgYWN0LCByZW5kZXJIb29rIH0gZnJvbSAnQHRlc3RpbmctbGlicmFyeS9yZWFjdCdcbmltcG9ydCB7IEdsb2JhbENvbnRleHRUZXN0UHJvdmlkZXIsIHRlc3RBZ2VudCB9IGZyb20gJy4uLy4uL3Rlc3QvZ2xvYmFsLWNvbnRleHQnXG5pbXBvcnQgeyB1c2VTZXNzaW9uc1N0b3JlIH0gZnJvbSAnLi4vLi4vc3RvcmUvc2Vzc2lvbnMvdXNlU2Vzc2lvbnNTdG9yZSdcbmltcG9ydCB7IHNlc3Npb25TdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vc3RvcmUvc2Vzc2lvbnMvc2Vzc2lvblN0cmVhbU1hbmFnZXInXG5pbXBvcnQgeyBBcHByb3ZhbFJlcXVlc3QsIENoYXRIaXN0b3J5Um9sZSwgQ2hhdE1lc3NhZ2UgfSBmcm9tICcuLi8uLi90eXBlcy9DaGF0J1xuaW1wb3J0IHsgRmVlZGJhY2sgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL21vbGVjdWxlcy9NZXNzYWdlRmVlZGJhY2svTWVzc2FnZUZlZWRiYWNrJ1xuaW1wb3J0IG1haWEgZnJvbSAnLi4vLi4vc2VydmljZXMvbWFpYSdcbmltcG9ydCB7IGFjdGl2ZVZpZXcgfSBmcm9tICcuLi8uLi9zdG9yZS9zZXNzaW9ucy9hY3RpdmVWaWV3J1xuaW1wb3J0IHsgdXNlT3JjaGVzdHJhdG9yU3RyZWFtIH0gZnJvbSAnLi4vdXNlT3JjaGVzdHJhdG9yU3RyZWFtJ1xuaW1wb3J0IHR5cGUgeyBTdHJlYW1Db250ZXh0IH0gZnJvbSAnLi4vdXNlT3JjaGVzdHJhdG9yU3RyZWFtL3VzZU9yY2hlc3RyYXRvclN0cmVhbS5pbnRlcmZhY2UnXG5pbXBvcnQgeyBnZXRDaGF0c1N0b3JlU3RhdGUgfSBmcm9tICcuLi8uLi9zdG9yZS91c2VDaGF0c1N0b3JlJ1xuaW1wb3J0IHsgbm90aWZ5U2Vzc2lvbkZpbmlzaGVkSW5CYWNrZ3JvdW5kIH0gZnJvbSAnLi4vLi4vc3RvcmUvc2Vzc2lvbnMvc2Vzc2lvbk5vdGlmaWNhdGlvbnMnXG5pbXBvcnQgeyBmZXRjaEFnZW50RGV0YWlsIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbWFpYS9BZ2VudHMvZmV0Y2hBZ2VudERldGFpbCdcbmltcG9ydCB7IE1BSUFfSE9VUlNfQ0hBUkdFRF9FVkVOVCB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9wbGFubmVyU3luY0V2ZW50cydcbmltcG9ydCB7IHN0cmVhbWluZ1BsYWNlaG9sZGVyTWVzc2FnZUlkIH0gZnJvbSAnLi4vLi4vdXRpbHMvc3RyZWFtQWN0aXZpdHlNZXNzYWdlcydcbmltcG9ydCB7IHVzZU11bHRpcGxlQ2hvaWNlU3RvcmUgfSBmcm9tICcuLi8uLi9zdG9yZS91c2VNdWx0aXBsZUNob2ljZVN0b3JlJ1xuaW1wb3J0IHsgdXNlQ2hhdE1hbmFnZXIgfSBmcm9tICcuL3VzZUNoYXRNYW5hZ2VyJ1xuXG5jb25zdCBmZXRjaEFnZW50RGV0YWlsTW9jayA9IGZldGNoQWdlbnREZXRhaWwgYXMgamVzdC5Nb2NrZWRGdW5jdGlvbjx0eXBlb2YgZmV0Y2hBZ2VudERldGFpbD5cblxuY29uc3QgbW9ja1VzZU9yY2hlc3RyYXRvclN0cmVhbSA9IHVzZU9yY2hlc3RyYXRvclN0cmVhbSBhcyBqZXN0Lk1vY2tlZEZ1bmN0aW9uPHR5cGVvZiB1c2VPcmNoZXN0cmF0b3JTdHJlYW0+XG5cbnR5cGUgQ2FwdHVyZWRTdHJlYW1DYWxsYmFja3MgPSB7XG4gIG9uRXJyb3I/OiAoY3R4OiBTdHJlYW1Db250ZXh0LCBlcnJvck1lc3NhZ2U/OiBzdHJpbmcsIGVycm9yUmF3TWVzc2FnZT86IHN0cmluZykgPT4gdm9pZFxuICBvblN0cmVhbVVwZGF0ZT86IChjdHg6IFN0cmVhbUNvbnRleHQsIGNvbnRlbnQ6IHN0cmluZykgPT4gdm9pZFxuICBvblN0b3A/OiAocGFydGlhbFRleHQ6IHN0cmluZykgPT4gdm9pZFxuICBvbkFwcHJvdmFsUmVxdWlyZWQ/OiAoY3R4OiBTdHJlYW1Db250ZXh0LCBhcHByb3ZhbDogQXBwcm92YWxSZXF1ZXN0LCBjb250ZW50OiBzdHJpbmcpID0+IHZvaWRcbiAgb25GaW5pc2hTdHJlYW0/OiAoXG4gICAgY3R4OiBTdHJlYW1Db250ZXh0LFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICBzb3VyY2VzOiB1bmtub3duLFxuICAgIG1lbW9yeVNlc3Npb25JZDogc3RyaW5nLFxuICAgIGF0dGFjaG1lbnRzPzogdW5rbm93bltdIHwgbnVsbCxcbiAgICBzdWdnZXN0aW9ucz86IHN0cmluZ1tdIHwgbnVsbCxcbiAgICBhZ2VudElkPzogc3RyaW5nIHwgbnVsbFxuICApID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+XG59XG5cbmxldCBzdHJlYW1DYWxsYmFja3M6IENhcHR1cmVkU3RyZWFtQ2FsbGJhY2tzID0ge31cblxuY29uc3Qgc3RhcnRDb250aW51ZVN0cmVhbU1vY2sgPSBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoeyBzdGFydGVkOiB0cnVlIH0pXG5cbmNvbnN0IGFza01haWFNb2NrID0gamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKHsgc3RhcnRlZDogdHJ1ZSB9KVxuY29uc3QgcmV0cnlDb21wbGV0aW9uTW9jayA9IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7IHN0YXJ0ZWQ6IHRydWUgfSlcbmNvbnN0IHN0b3BTdHJlYW1pbmdNb2NrID0gamVzdC5mbigpXG5jb25zdCByZXBsYWNlTWVzc2FnZXNNb2NrID0gamVzdC5mbigpXG5jb25zdCBhZGRNZXNzYWdlTW9jayA9IGplc3QuZm4oKVxuY29uc3QgZXZlbnRNb2NrID0gamVzdC5mbigpXG5cbmNvbnN0IGNoYXRNZXNzYWdlc1N0YXRlID0ge1xuICBsb2FkaW5nTWVzc2FnZXM6IGZhbHNlLFxuICBtZXNzYWdlczogW10gYXMgQ2hhdE1lc3NhZ2VbXSxcbiAgaXNMb2FkaW5nTW9yZU1lc3NhZ2VzOiBmYWxzZSxcbiAgbG9hZE1lc3NhZ2VzOiBqZXN0LmZuKCksXG4gIGFkZE1lc3NhZ2U6IGFkZE1lc3NhZ2VNb2NrLFxuICByZW1vdmVNZXNzYWdlOiBqZXN0LmZuKCksXG4gIHJlcGxhY2VNZXNzYWdlczogcmVwbGFjZU1lc3NhZ2VzTW9jayxcbiAgaGFuZGxlU2Nyb2xsOiBqZXN0LmZuKCksXG59XG5cbmplc3QubW9jaygnLi4vdXNlQ2hhdE1lc3NhZ2VzJywgKCkgPT4gKHtcbiAgdXNlQ2hhdE1lc3NhZ2VzOiAoKSA9PiBjaGF0TWVzc2FnZXNTdGF0ZSxcbn0pKVxuXG5qZXN0Lm1vY2soJy4uL3VzZU9yY2hlc3RyYXRvclN0cmVhbScsICgpID0+ICh7XG4gIHVzZU9yY2hlc3RyYXRvclN0cmVhbTogamVzdC5mbigpLFxufSkpXG5cbmplc3QubW9jaygnLi4vdXNlUHJvamVjdHMnLCAoKSA9PiAoe1xuICB1c2VQcm9qZWN0czogKCkgPT4gKHtcbiAgICBmZXRjaFByb2plY3RzOiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoW10pLFxuICB9KSxcbn0pKVxuXG5qZXN0Lm1vY2soJy4uL3VzZVRhYlRhc2tEZWZhdWx0JywgKCkgPT4gKHtcbiAgdXNlVGFiVGFza0RlZmF1bHQ6ICgpID0+ICh7XG4gICAgZ2V0VGFiVGFza0RlZmF1bHQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSgnZGV0YWlsJyksXG4gIH0pLFxufSkpXG5cbmplc3QubW9jaygnLi4vdXNlRXZlbnQnLCAoKSA9PiAoe1xuICBFVkVOVFM6IHsgcG1BaVR5cGVkVGV4dDogJ1BNX0FJX1RZUEVEX1RFWFQnIH0sXG4gIHVzZUV2ZW50OiAoKSA9PiBldmVudE1vY2ssXG59KSlcblxuamVzdC5tb2NrKCcuLi8uLi9jb250ZXh0L2Nvci11c2VyJywgKCkgPT4gKHtcbiAgdXNlVXNlcjogKCkgPT4gKHtcbiAgICBpZDogNyxcbiAgICBmaXJzdE5hbWU6ICdBbmEnLFxuICAgIGxhc3ROYW1lOiAnR2FyY8OtYScsXG4gICAgcGljdHVyZTogJ3BpYy5wbmcnLFxuICAgIGxhbmc6ICdlcycsXG4gICAgY29tcGFueV9pZDogMTAsXG4gIH0pLFxufSkpXG5cbmplc3QubW9jaygnLi4vLi4vc3RvcmUvdXNlQ2hhdHNTdG9yZScsICgpID0+IHtcbiAgY29uc3Qgc3RhdGUgPSB7XG4gICAgc2V0QWN0aXZlQ2hhdElkOiBqZXN0LmZuKCksXG4gICAgbWFya0NoYXRBc1JlYWQ6IGplc3QuZm4oKSxcbiAgICBtYXJrQ2hhdEFzVW5yZWFkOiBqZXN0LmZuKCksXG4gICAgaXNDaGF0Vmlld1Zpc2libGU6IHRydWUsXG4gICAgY2hhdHM6IFtdIGFzIEFycmF5PHsgc2Vzc2lvbkV4dGVybmFsSWQ6IHN0cmluZyB9PixcbiAgICBwcmVwZW5kQ2hhdDogamVzdC5mbigpLFxuICB9XG4gIGNvbnN0IHVzZUNoYXRzU3RvcmUgPSAoc2VsZWN0b3I6ICh2YWx1ZTogdHlwZW9mIHN0YXRlKSA9PiB1bmtub3duKSA9PiBzZWxlY3RvcihzdGF0ZSlcbiAgT2JqZWN0LmFzc2lnbih1c2VDaGF0c1N0b3JlLCB7IGdldFN0YXRlOiAoKSA9PiBzdGF0ZSB9KVxuXG4gIHJldHVybiB7XG4gICAgdXNlQ2hhdHNTdG9yZSxcbiAgICBnZXRDaGF0c1N0b3JlU3RhdGU6ICgpID0+IHN0YXRlLFxuICB9XG59KVxuXG5qZXN0Lm1vY2soJy4uLy4uL3NlcnZpY2VzL21haWEnLCAoKSA9PiAoe1xuICBfX2VzTW9kdWxlOiB0cnVlLFxuICBkZWZhdWx0OiB7XG4gICAgQ2hhdHM6IHtcbiAgICAgIHdhc0hlbHBmdWxDaGF0OiBqZXN0LmZuKCksXG4gICAgfSxcbiAgfSxcbn0pKVxuXG5qZXN0Lm1vY2soJy4uLy4uL3NlcnZpY2VzL21haWEvQWdlbnRzL2ZldGNoQWdlbnREZXRhaWwnLCAoKSA9PiAoe1xuICBmZXRjaEFnZW50RGV0YWlsOiBqZXN0LmZuKCksXG59KSlcblxuamVzdC5tb2NrKCcuLi8uLi9zdG9yZS9zZXNzaW9ucy9zZXNzaW9uTm90aWZpY2F0aW9ucycsICgpID0+ICh7XG4gIG5vdGlmeVNlc3Npb25GaW5pc2hlZEluQmFja2dyb3VuZDogamVzdC5mbigpLFxuICBlbnN1cmVTZXNzaW9uTm90aWZpY2F0aW9uc0luaXRpYWxpemVkOiBqZXN0LmZuKCksXG59KSlcblxuamVzdC5tb2NrKCcuLi8uLi9zdG9yZS9zZXNzaW9ucy9zZXNzaW9uU3RyZWFtTWFuYWdlcicsICgpID0+ICh7XG4gIHNlc3Npb25TdHJlYW1NYW5hZ2VyOiB7XG4gICAgaXNBY3RpdmU6IGplc3QuZm4oKCkgPT4gZmFsc2UpLFxuICAgIGdldEFjdGl2ZUNvdW50OiBqZXN0LmZuKCgpID0+IDApLFxuICAgIHN0YXJ0U3RyZWFtOiBqZXN0LmZuKCksXG4gICAgc3RhcnRDb250aW51ZVN0cmVhbTogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gc3RhcnRDb250aW51ZVN0cmVhbU1vY2soLi4uYXJncyksXG4gICAgc3RvcFN0cmVhbTogamVzdC5mbigpLFxuICB9LFxuICBNQVhfQ09OQ1VSUkVOVF9TVFJFQU1TOiAzLFxufSkpXG5cbmNvbnN0IHdyYXBwZXIgPSAoeyBjaGlsZHJlbiB9OiB7IGNoaWxkcmVuOiBSZWFjdE5vZGUgfSkgPT4gKFxuICA8R2xvYmFsQ29udGV4dFRlc3RQcm92aWRlciB2YWx1ZT17eyBhZ2VudDogdGVzdEFnZW50IH19PntjaGlsZHJlbn08L0dsb2JhbENvbnRleHRUZXN0UHJvdmlkZXI+XG4pXG5cbmRlc2NyaWJlKCd1c2VDaGF0TWFuYWdlcicsICgpID0+IHtcbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgamVzdC5jbGVhckFsbE1vY2tzKClcbiAgICBzdHJlYW1DYWxsYmFja3MgPSB7fVxuICAgIG1vY2tVc2VPcmNoZXN0cmF0b3JTdHJlYW0ubW9ja0ltcGxlbWVudGF0aW9uKG9wdGlvbnMgPT4ge1xuICAgICAgc3RyZWFtQ2FsbGJhY2tzID0ge1xuICAgICAgICBvbkVycm9yOiBvcHRpb25zLm9uRXJyb3IsXG4gICAgICAgIG9uU3RyZWFtVXBkYXRlOiBvcHRpb25zLm9uU3RyZWFtVXBkYXRlLFxuICAgICAgICBvblN0b3A6IG9wdGlvbnMub25TdG9wLFxuICAgICAgICBvbkFwcHJvdmFsUmVxdWlyZWQ6IG9wdGlvbnMub25BcHByb3ZhbFJlcXVpcmVkLFxuICAgICAgICBvbkZpbmlzaFN0cmVhbTogb3B0aW9ucy5vbkZpbmlzaFN0cmVhbSxcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFza01haWE6IGFza01haWFNb2NrLFxuICAgICAgICByZXRyeUNvbXBsZXRpb246IHJldHJ5Q29tcGxldGlvbk1vY2ssXG4gICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgIGlzV3JpdGluZzogZmFsc2UsXG4gICAgICAgIGxvYWRpbmdNZXNzYWdlOiAnJyxcbiAgICAgICAgc3RyZWFtQWN0aXZpdHk6IG51bGwsXG4gICAgICAgIHVwZGF0ZVN0cmVhbUFjdGl2aXR5OiBqZXN0LmZuKCksXG4gICAgICAgIHN0b3BTdHJlYW1pbmc6IHN0b3BTdHJlYW1pbmdNb2NrLFxuICAgICAgfVxuICAgIH0pXG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubG9hZGluZ01lc3NhZ2VzID0gZmFsc2VcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlcyA9IFtdXG4gICAgdXNlU2Vzc2lvbnNTdG9yZS5zZXRTdGF0ZSh7IG1ldGE6IHt9LCBtZXNzYWdlczoge30sIHZpZXdDYWNoZToge30gfSlcbiAgICBhY3RpdmVWaWV3LnNldChudWxsKVxuICAgIDsoc2Vzc2lvblN0cmVhbU1hbmFnZXIuaXNBY3RpdmUgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoZmFsc2UpXG4gICAgOyhzZXNzaW9uU3RyZWFtTWFuYWdlci5nZXRBY3RpdmVDb3VudCBhcyBqZXN0Lk1vY2spLm1vY2tSZXR1cm5WYWx1ZSgwKVxuICAgIHN0YXJ0Q29udGludWVTdHJlYW1Nb2NrLm1vY2tSZXNvbHZlZFZhbHVlKHsgc3RhcnRlZDogdHJ1ZSB9KVxuICAgIGFza01haWFNb2NrLm1vY2tSZXNvbHZlZFZhbHVlKHsgc3RhcnRlZDogdHJ1ZSB9KVxuICAgIHJldHJ5Q29tcGxldGlvbk1vY2subW9ja1Jlc29sdmVkVmFsdWUoeyBzdGFydGVkOiB0cnVlIH0pXG4gIH0pXG5cbiAgaXQoJ3N0YXJ0cyB3aXRoIGVtcHR5IG1lc3NhZ2VzIGFuZCBzZW5kIGVuYWJsZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgZXhwZWN0KHJlc3VsdC5jdXJyZW50Lm1lc3NhZ2VzKS50b0VxdWFsKFtdKVxuICAgIGV4cGVjdChyZXN1bHQuY3VycmVudC5pc0Rpc2FibGVkKS50b0JlKGZhbHNlKVxuICB9KVxuXG4gIGl0KCdzZW5kTWVzc2FnZSBkZWxlZ2F0ZXMgdG8gYXNrTWFpYSB3aXRoIHRoZSBjdXJyZW50IHNlc3Npb24nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHJlc3VsdC5jdXJyZW50LnNlbmRNZXNzYWdlKCdIb2xhIE1BSUEnKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYXNrTWFpYU1vY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICBtZXNzYWdlOiAnSG9sYSBNQUlBJyxcbiAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgYWdlbnRJZDogdGVzdEFnZW50LmlkLFxuICAgICAgICBhZ2VudE5hbWU6IHRlc3RBZ2VudC5uYW1lLFxuICAgICAgfSlcbiAgICApXG4gICAgZXhwZWN0KGFkZE1lc3NhZ2VNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgbWVzc2FnZTogJ0hvbGEgTUFJQScsXG4gICAgICAgIHJvbGU6ICd1c2VyJyxcbiAgICAgIH0pXG4gICAgKVxuICB9KVxuXG4gIGl0KCdtYXJrcyB0aGUgbWVzc2FnZSB0aGF0IGFuc3dlcnMgYSBtdWx0aXBsZS1jaG9pY2UgY2FyZCBhbmQgY29uc3VtZXMgdGhlIGFuc3dlcicsIGFzeW5jICgpID0+IHtcbiAgICB1c2VNdWx0aXBsZUNob2ljZVN0b3JlLnNldFN0YXRlKHtcbiAgICAgIHBlbmRpbmc6IHsgbWVzc2FnZUlkOiAnYTEnLCBxdWVzdGlvbjogbnVsbCwgb3B0aW9uczogW10gfSxcbiAgICAgIGFuc3dlcjogbnVsbCxcbiAgICAgIGRpc21pc3NlZE1lc3NhZ2VJZHM6IHt9LFxuICAgIH0pXG4gICAgdXNlTXVsdGlwbGVDaG9pY2VTdG9yZS5nZXRTdGF0ZSgpLmFuc3dlclBlbmRpbmcoeyBrZXk6ICdCJyB9KVxuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKCgpID0+IHVzZUNoYXRNYW5hZ2VyKHsgY2hhdElkOiAnc2Vzc2lvbi0xJywgYWdlbnRzOiBbdGVzdEFnZW50XSB9KSwgeyB3cmFwcGVyIH0pXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuc2VuZE1lc3NhZ2UoJ1Byb3llY3RvIEJldGEnKVxuICAgIH0pXG4gICAgZXhwZWN0KGFza01haWFNb2NrKS50b0hhdmVCZWVuTGFzdENhbGxlZFdpdGgoZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoeyBtdWx0aXBsZUNob2ljZUFuc3dlcjogeyBrZXk6ICdCJyB9IH0pKVxuICAgIGV4cGVjdChhZGRNZXNzYWdlTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IG1lc3NhZ2U6ICdQcm95ZWN0byBCZXRhJywgbXVsdGlwbGVDaG9pY2VBbnN3ZXI6IHsga2V5OiAnQicgfSB9KVxuICAgIClcblxuICAgIGV4cGVjdCh1c2VNdWx0aXBsZUNob2ljZVN0b3JlLmdldFN0YXRlKCkuYW5zd2VyKS50b0JlTnVsbCgpXG4gIH0pXG5cbiAgaXQoJ2RvZXMgbm90IHNlbmQgd2hlbiB0aGUgY29uY3VycmVudCBzdHJlYW0gbGltaXQgaXMgcmVhY2hlZCcsIGFzeW5jICgpID0+IHtcbiAgICA7KHNlc3Npb25TdHJlYW1NYW5hZ2VyLmdldEFjdGl2ZUNvdW50IGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKDMpXG4gICAgY29uc3QgZGlzcGF0Y2hTcHkgPSBqZXN0LnNweU9uKGRvY3VtZW50LCAnZGlzcGF0Y2hFdmVudCcpXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuc2VuZE1lc3NhZ2UoJ0hvbGEnKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYXNrTWFpYU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgICBleHBlY3QoZGlzcGF0Y2hTcHkpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICB0eXBlOiAnc25hY2tiYXItZXZlbnQnLFxuICAgICAgfSlcbiAgICApXG5cbiAgICBkaXNwYXRjaFNweS5tb2NrUmVzdG9yZSgpXG4gIH0pXG5cbiAgaXQoJ3N0b3BHZW5lcmF0aW9uIHN0b3BzIHRoZSBhY3RpdmUgc3RyZWFtJywgKCkgPT4ge1xuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGFjdCgoKSA9PiB7XG4gICAgICByZXN1bHQuY3VycmVudC5zdG9wR2VuZXJhdGlvbigpXG4gICAgfSlcblxuICAgIGV4cGVjdChzdG9wU3RyZWFtaW5nTW9jaykudG9IYXZlQmVlbkNhbGxlZCgpXG4gIH0pXG5cbiAgaXQoJ3Jlc2V0Q2hhdCBjbGVhcnMgdGhlIGFjdGl2ZSBjaGF0IGlkIGluIHRoZSBzdG9yZSBob29rIHBhdGgnLCAoKSA9PiB7XG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHJlc3VsdC5jdXJyZW50LnJlc2V0Q2hhdCgpXG4gICAgfSlcblxuICAgIGV4cGVjdChyZXN1bHQuY3VycmVudC5jdXJyZW50Q2hhdElkKS5ub3QudG9CZSgnc2Vzc2lvbi0xJylcbiAgfSlcblxuICBpdCgnZG9lcyBub3Qgc2VuZCB3aGlsZSBtZXNzYWdlcyBhcmUgbG9hZGluZycsIGFzeW5jICgpID0+IHtcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5sb2FkaW5nTWVzc2FnZXMgPSB0cnVlXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBleHBlY3QocmVzdWx0LmN1cnJlbnQuaXNEaXNhYmxlZCkudG9CZSh0cnVlKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHJlc3VsdC5jdXJyZW50LnNlbmRNZXNzYWdlKCdIb2xhJylcbiAgICB9KVxuXG4gICAgZXhwZWN0KGFza01haWFNb2NrKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpXG4gIH0pXG5cbiAgaXQoJ2luY2x1ZGVzIGNvbnRleHQgbWVudGlvbnMgd2hlbiB0aGV5IGFyZSBzZW50IHZpYSBvcHRpb25zJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCByZXN1bHQuY3VycmVudC5zZW5kTWVzc2FnZSgnSG9sYScsIHtcbiAgICAgICAgbWVudGlvbnM6IFt7IGlkOiAndTEnLCB0eXBlOiAndXNlcicsIGxhYmVsOiAnQW5hJyB9XSxcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIGV4cGVjdChhc2tNYWlhTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIGNvbnRleHRNZXNzYWdlOiBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgICAgdXNlcjogZXhwZWN0LmFycmF5Q29udGFpbmluZyhbZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoeyBpZDogJ3UxJywgbmFtZTogJ0FuYScgfSldKSxcbiAgICAgICAgfSksXG4gICAgICB9KVxuICAgIClcbiAgICBleHBlY3QoZXZlbnRNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnUE1fQUlfVFlQRURfVEVYVCcpXG4gIH0pXG5cbiAgaXQoJ3JldHJpZXMgYSBjYW5jZWxsZWQgYXNzaXN0YW50IHR1cm4gdGhyb3VnaCBhc2tNYWlhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzID0gW1xuICAgICAge1xuICAgICAgICBpZDogJ3F1ZXN0aW9uLTEnLFxuICAgICAgICBtZXNzYWdlOiAnSG9sYScsXG4gICAgICAgIHJvbGU6IENoYXRIaXN0b3J5Um9sZS5VU0VSLFxuICAgICAgICB1c2VyOiB7IGlkOiAnNycsIG5hbWU6ICdBbmEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBpZDogJ2Fuc3dlci1zdHJlYW0tMS1jYW5jZWxsZWQnLFxuICAgICAgICBtZXNzYWdlOiAnUmVzcHVlc3RhIHBhcmNpYWwnLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ0Fzc2lzdGFudCcgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgaXNGcm9udGVuZENhbmNlbGxlZDogdHJ1ZSxcbiAgICAgIH0sXG4gICAgXVxuXG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHJlc3VsdC5jdXJyZW50LnJldHJ5TWVzc2FnZShjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlc1sxXSlcbiAgICB9KVxuXG4gICAgZXhwZWN0KGFza01haWFNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgbWVzc2FnZTogJ0hvbGEnLFxuICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgfSlcbiAgICApXG4gICAgZXhwZWN0KHJlcGxhY2VNZXNzYWdlc01vY2spLnRvSGF2ZUJlZW5DYWxsZWQoKVxuICB9KVxuXG4gIGl0KCdyZS1hc2tzIHdpdGggdGhlIG5ldyBwcm9qZWN0IHdoZW4gYSBwZW5kaW5nIHF1ZXN0aW9uIGV4aXN0cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBzZXRQcm9qZWN0ID0gamVzdC5mbigpXG4gICAgY29uc3QgcHJvamVjdCA9IHsgaWQ6IDEwLCBuYW1lOiAnUHJveWVjdG8gQScgfSBhcyBuZXZlclxuXG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHtcbiAgICAgICAgd3JhcHBlcjogKHsgY2hpbGRyZW4gfTogeyBjaGlsZHJlbjogUmVhY3ROb2RlIH0pID0+IChcbiAgICAgICAgICA8R2xvYmFsQ29udGV4dFRlc3RQcm92aWRlciB2YWx1ZT17eyBhZ2VudDogdGVzdEFnZW50LCBwcm9qZWN0LCBzZXRQcm9qZWN0IH19PlxuICAgICAgICAgICAge2NoaWxkcmVufVxuICAgICAgICAgIDwvR2xvYmFsQ29udGV4dFRlc3RQcm92aWRlcj5cbiAgICAgICAgKSxcbiAgICAgIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuc2VuZE1lc3NhZ2UoJ8K/Q3XDoW50YXMgaG9yYXMgdmFuPycpXG4gICAgfSlcblxuICAgIGFza01haWFNb2NrLm1vY2tDbGVhcigpXG5cbiAgICBhY3QoKCkgPT4ge1xuICAgICAgcmVzdWx0LmN1cnJlbnQuY2hhbmdlUHJvamVjdCh7IGlkOiA5OSwgbmFtZTogJ1Byb3llY3RvIFgnLCBmZWVJZDogNSwgY2xpZW50SWQ6IDcgfSBhcyBuZXZlcilcbiAgICB9KVxuXG4gICAgZXhwZWN0KHNldFByb2plY3QpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgaWQ6IDk5IH0pKVxuICAgIGV4cGVjdChhc2tNYWlhTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIG1lc3NhZ2U6ICfCv0N1w6FudGFzIGhvcmFzIHZhbj8nLFxuICAgICAgICBwcm9qZWN0SWQ6IDk5LFxuICAgICAgICBmZWVJZDogNSxcbiAgICAgICAgY2xpZW50SWQ6IDcsXG4gICAgICB9KVxuICAgIClcbiAgfSlcblxuICBpdCgnZG9lcyBub3QgY2hhbmdlIHByb2plY3Qgd2hlbiB0aGVyZSBpcyBubyBwZW5kaW5nIHVzZXIgcXVlc3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHJlc3VsdC5jdXJyZW50LmNoYW5nZVByb2plY3QoeyBpZDogOTksIG5hbWU6ICdQcm95ZWN0byBYJyB9IGFzIG5ldmVyKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYXNrTWFpYU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgfSlcblxuICBpdCgnc3RhcnRzIGEgY29udGludWUgc3RyZWFtIHdoZW4gcmVqZWN0aW5nIGEgSElUTCBhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgYWN0aXZlVmlldy5zZXQoJ3Nlc3Npb24tMScpXG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnbXNnLWFwcHJvdmFsJyxcbiAgICAgICAgbWVzc2FnZTogJ0FwcHJvdmUgdGFzayBlZGl0PycsXG4gICAgICAgIHJvbGU6IENoYXRIaXN0b3J5Um9sZS5BU1NJU1RBTlQsXG4gICAgICAgIHVzZXI6IHsgaWQ6ICdhc3Npc3RhbnQnLCBuYW1lOiAnTUFJQScgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgYXBwcm92YWw6IHtcbiAgICAgICAgICBzZXNzaW9uX2lkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBwZW5kaW5nX2FjdGlvbnM6IFt7IHRocmVhZF9pZDogJ3RocmVhZC1hJywgdG9vbF9uYW1lOiAnZWRpdF90YXNrJywgdG9vbF9hcmdzOiB7IHRhc2tfaWQ6IDQyIH0gfV0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF1cblxuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCByZXN1bHQuY3VycmVudC5oYW5kbGVBcHByb3ZhbERlY2lzaW9uKFsndGhyZWFkLWEnXSwgJ3JlamVjdCcpXG4gICAgfSlcblxuICAgIGV4cGVjdChzdGFydENvbnRpbnVlU3RyZWFtTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIGNvbnRpbnVlUmVxdWVzdDogZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICAgIGRlY2lzaW9uOiAncmVqZWN0JyxcbiAgICAgICAgfSksXG4gICAgICB9KVxuICAgIClcbiAgfSlcblxuICBpdCgnc3RhcnRzIGEgY29udGludWUgc3RyZWFtIHdoZW4gYXBwcm92aW5nIGEgSElUTCBhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgYWN0aXZlVmlldy5zZXQoJ3Nlc3Npb24tMScpXG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnbXNnLWFwcHJvdmFsJyxcbiAgICAgICAgbWVzc2FnZTogJ0FwcHJvdmUgdGFzayBlZGl0PycsXG4gICAgICAgIHJvbGU6IENoYXRIaXN0b3J5Um9sZS5BU1NJU1RBTlQsXG4gICAgICAgIHVzZXI6IHsgaWQ6ICdhc3Npc3RhbnQnLCBuYW1lOiAnTUFJQScgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgYXBwcm92YWw6IHtcbiAgICAgICAgICBzZXNzaW9uX2lkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBwZW5kaW5nX2FjdGlvbnM6IFt7IHRocmVhZF9pZDogJ3RocmVhZC1hJywgdG9vbF9uYW1lOiAnZWRpdF90YXNrJywgdG9vbF9hcmdzOiB7IHRhc2tfaWQ6IDQyIH0gfV0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF1cblxuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCByZXN1bHQuY3VycmVudC5oYW5kbGVBcHByb3ZhbERlY2lzaW9uKFsndGhyZWFkLWEnXSwgJ2FwcHJvdmUnKVxuICAgIH0pXG5cbiAgICBleHBlY3Qoc3RhcnRDb250aW51ZVN0cmVhbU1vY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICBjb250aW51ZVJlcXVlc3Q6IGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgICB0aHJlYWRJZHM6IFsndGhyZWFkLWEnXSxcbiAgICAgICAgICBkZWNpc2lvbjogJ2FwcHJvdmUnLFxuICAgICAgICB9KSxcbiAgICAgIH0pXG4gICAgKVxuICB9KVxuXG4gIGl0KCdzdWJtaXRzIGZlZWRiYWNrIHRocm91Z2ggdGhlIG1haWEgY2hhdHMgc2VydmljZScsIGFzeW5jICgpID0+IHtcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdhbnN3ZXItMScsXG4gICAgICAgIG1lc3NhZ2U6ICdSZXNwdWVzdGEnLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ0Fzc2lzdGFudCcgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgIH0sXG4gICAgXVxuXG4gICAgamVzdC5tb2NrZWQobWFpYS5DaGF0cy53YXNIZWxwZnVsQ2hhdCkubW9ja1Jlc29sdmVkVmFsdWUodHJ1ZSlcblxuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCByZXN1bHQuY3VycmVudC5oYW5kbGVGZWVkYmFjayhGZWVkYmFjay5USFVNQlNfVVAsICdhbnN3ZXItMScpXG4gICAgfSlcblxuICAgIGV4cGVjdChtYWlhLkNoYXRzLndhc0hlbHBmdWxDaGF0KS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnYW5zd2VyLTEnLCB0cnVlKVxuICB9KVxuXG4gIGl0KCdpZ25vcmVzIGZlZWRiYWNrIHVwZGF0ZXMgd2hlbiB0aGUgQVBJIHJlamVjdHMgdGhlIHZvdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnYW5zd2VyLTEnLFxuICAgICAgICBtZXNzYWdlOiAnUmVzcHVlc3RhJyxcbiAgICAgICAgcm9sZTogQ2hhdEhpc3RvcnlSb2xlLkFTU0lTVEFOVCxcbiAgICAgICAgdXNlcjogeyBpZDogJ2Fzc2lzdGFudCcsIG5hbWU6ICdBc3Npc3RhbnQnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICB9LFxuICAgIF1cblxuICAgIGplc3QubW9ja2VkKG1haWEuQ2hhdHMud2FzSGVscGZ1bENoYXQpLm1vY2tSZXNvbHZlZFZhbHVlKGZhbHNlKVxuXG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHJlc3VsdC5jdXJyZW50LmhhbmRsZUZlZWRiYWNrKEZlZWRiYWNrLlRIVU1CU19ET1dOLCAnYW5zd2VyLTEnKVxuICAgIH0pXG5cbiAgICBleHBlY3QoY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXNbMF0pLm5vdC50b0hhdmVQcm9wZXJ0eSgnd2FzSGVscGZ1bCcpXG4gIH0pXG5cbiAgaXQoJ2RvZXMgbm90IHN0YXJ0IGFwcHJvdmFsIHN0cmVhbXMgd2l0aG91dCB0aHJlYWQgaWRzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGNvbnNvbGVTcHkgPSBqZXN0LnNweU9uKGNvbnNvbGUsICdlcnJvcicpLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiB1bmRlZmluZWQpXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuaGFuZGxlQXBwcm92YWxEZWNpc2lvbihbXSwgJ2FwcHJvdmUnKVxuICAgIH0pXG5cbiAgICBleHBlY3Qoc3RhcnRDb250aW51ZVN0cmVhbU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgICBleHBlY3QoY29uc29sZVNweSkudG9IYXZlQmVlbkNhbGxlZCgpXG5cbiAgICBjb25zb2xlU3B5Lm1vY2tSZXN0b3JlKClcbiAgfSlcblxuICBpdCgnc2VuZE1lc3NhZ2UgYWNjZXB0cyBhIGJhcmUgYXR0YWNobWVudHMgYXJyYXknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYXR0YWNobWVudCA9IHsgaWQ6ICdhMScsIG5hbWU6ICdkb2MucGRmJywgdHlwZTogJ3BkZicsIHNpemU6IDEsIGZpbGU6IG5ldyBGaWxlKFtdLCAnZG9jLnBkZicpIH1cblxuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCByZXN1bHQuY3VycmVudC5zZW5kTWVzc2FnZSgnQ29uIGFkanVudG8nLCBbYXR0YWNobWVudF0pXG4gICAgfSlcblxuICAgIGV4cGVjdChhc2tNYWlhTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIG1lc3NhZ2U6ICdDb24gYWRqdW50bycsXG4gICAgICAgIGF0dGFjaG1lbnRzOiBbYXR0YWNobWVudF0sXG4gICAgICB9KVxuICAgIClcbiAgfSlcblxuICBpdCgnbG9hZHMgbWVzc2FnZXMgd2hlbiBpbml0aWFsaXplQ2hhdCBydW5zIHdpdGggYW4gZXhpc3RpbmcgY2hhdCBpZCcsIGFzeW5jICgpID0+IHtcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5sb2FkTWVzc2FnZXMubW9ja1Jlc29sdmVkVmFsdWUodW5kZWZpbmVkKVxuXG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHJlc3VsdC5jdXJyZW50LmluaXRpYWxpemVDaGF0KClcbiAgICB9KVxuXG4gICAgZXhwZWN0KGNoYXRNZXNzYWdlc1N0YXRlLmxvYWRNZXNzYWdlcykudG9IYXZlQmVlbkNhbGxlZCgpXG4gIH0pXG5cbiAgaXQoJ2F1dG8tc2VuZHMgdGhlIGluaXRpYWwgRkFRIHdoZW4gaW5pdGlhbGl6ZUNoYXQgcmVjZWl2ZXMgZmFxSWQgb25seScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICB1c2VySW5pdGlhbE1lc3NhZ2U6IHsgbWVzc2FnZTogJycsIGF0dGFjaG1lbnRzOiBbXSwgZmFxSWQ6ICdmYXEtcmVudGFiaWxpZGFkJyB9LFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuaW5pdGlhbGl6ZUNoYXQoKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYXNrTWFpYU1vY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgZmFxSWQ6ICdmYXEtcmVudGFiaWxpZGFkJyB9KSlcbiAgfSlcblxuICBpdCgnc2tpcHMgaW5pdGlhbGl6ZUNoYXQgYXV0by1zZW5kIHdoZW4gdGhlIGluaXRpYWwgcGF5bG9hZCBpcyBlbXB0eScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICB1c2VySW5pdGlhbE1lc3NhZ2U6IHsgbWVzc2FnZTogJyAgICcsIGF0dGFjaG1lbnRzOiBbXSB9LFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuaW5pdGlhbGl6ZUNoYXQoKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYXNrTWFpYU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgICBleHBlY3QoY2hhdE1lc3NhZ2VzU3RhdGUubG9hZE1lc3NhZ2VzKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpXG4gIH0pXG5cbiAgaXQoJ2RvZXMgbm90IHJldHJ5IHdoZW4gdGhlIGNvbmN1cnJlbnQgc3RyZWFtIGxpbWl0IGlzIHJlYWNoZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgOyhzZXNzaW9uU3RyZWFtTWFuYWdlci5nZXRBY3RpdmVDb3VudCBhcyBqZXN0Lk1vY2spLm1vY2tSZXR1cm5WYWx1ZSgzKVxuICAgIGNvbnN0IGRpc3BhdGNoU3B5ID0gamVzdC5zcHlPbihkb2N1bWVudCwgJ2Rpc3BhdGNoRXZlbnQnKVxuXG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAncXVlc3Rpb24tMScsXG4gICAgICAgIG1lc3NhZ2U6ICdIb2xhJyxcbiAgICAgICAgcm9sZTogQ2hhdEhpc3RvcnlSb2xlLlVTRVIsXG4gICAgICAgIHVzZXI6IHsgaWQ6ICc3JywgbmFtZTogJ0FuYScgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnYW5zd2VyLXN0cmVhbS0xLWNhbmNlbGxlZCcsXG4gICAgICAgIG1lc3NhZ2U6ICdSZXNwdWVzdGEgcGFyY2lhbCcsXG4gICAgICAgIHJvbGU6IENoYXRIaXN0b3J5Um9sZS5BU1NJU1RBTlQsXG4gICAgICAgIHVzZXI6IHsgaWQ6ICdhc3Npc3RhbnQnLCBuYW1lOiAnQXNzaXN0YW50JyB9LFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgICBpc0Zyb250ZW5kQ2FuY2VsbGVkOiB0cnVlLFxuICAgICAgfSxcbiAgICBdXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQucmV0cnlNZXNzYWdlKGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzWzFdKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYXNrTWFpYU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgICBleHBlY3QoZGlzcGF0Y2hTcHkpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICB0eXBlOiAnc25hY2tiYXItZXZlbnQnLFxuICAgICAgfSlcbiAgICApXG5cbiAgICBkaXNwYXRjaFNweS5tb2NrUmVzdG9yZSgpXG4gIH0pXG5cbiAgaXQoJ2RvZXMgbm90IHN0YXJ0IGFwcHJvdmFsIHN0cmVhbXMgd2hlbiB0aGUgc2Vzc2lvbiBpcyBhbHJlYWR5IHN0cmVhbWluZycsIGFzeW5jICgpID0+IHtcbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcbiAgICA7KHNlc3Npb25TdHJlYW1NYW5hZ2VyLmlzQWN0aXZlIGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKHRydWUpXG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnbXNnLWFwcHJvdmFsJyxcbiAgICAgICAgbWVzc2FnZTogJ0FwcHJvdmU/JyxcbiAgICAgICAgcm9sZTogQ2hhdEhpc3RvcnlSb2xlLkFTU0lTVEFOVCxcbiAgICAgICAgdXNlcjogeyBpZDogJ2Fzc2lzdGFudCcsIG5hbWU6ICdNQUlBJyB9LFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgICBhcHByb3ZhbDoge1xuICAgICAgICAgIHNlc3Npb25faWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIHBlbmRpbmdfYWN0aW9uczogW3sgdGhyZWFkX2lkOiAndGhyZWFkLWEnLCB0b29sX25hbWU6ICdlZGl0X3Rhc2snLCB0b29sX2FyZ3M6IHt9IH1dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuaGFuZGxlQXBwcm92YWxEZWNpc2lvbihbJ3RocmVhZC1hJ10sICdhcHByb3ZlJylcbiAgICB9KVxuXG4gICAgZXhwZWN0KHN0YXJ0Q29udGludWVTdHJlYW1Nb2NrKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpXG4gIH0pXG5cbiAgaXQoJ3N0YXJ0cyBhIGNvbnRpbnVlIHN0cmVhbSB3aXRoIGVkaXQgZGVjaXNpb24gd2hlbiBhY3Rpb25zIHdlcmUgZWRpdGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGFjdGl2ZVZpZXcuc2V0KCdzZXNzaW9uLTEnKVxuICAgIGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzID0gW1xuICAgICAge1xuICAgICAgICBpZDogJ21zZy1hcHByb3ZhbCcsXG4gICAgICAgIG1lc3NhZ2U6ICdBcHByb3ZlIHRhc2sgZWRpdD8nLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGFwcHJvdmFsOiB7XG4gICAgICAgICAgc2Vzc2lvbl9pZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgcGVuZGluZ19hY3Rpb25zOiBbeyB0aHJlYWRfaWQ6ICd0aHJlYWQtYScsIHRvb2xfbmFtZTogJ2VkaXRfdGFzaycsIHRvb2xfYXJnczogeyB0YXNrX2lkOiA0MiB9IH1dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdXG5cbiAgICBjb25zdCBlZGl0ZWRBY3Rpb25zID0gW3sgdG9vbF9uYW1lOiAnZWRpdF90YXNrJywgYXJnczogeyB0YXNrX2lkOiA5OSB9IH1dXG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHJlc3VsdC5jdXJyZW50LmhhbmRsZUFwcHJvdmFsRGVjaXNpb24oWyd0aHJlYWQtYSddLCAncmVqZWN0JywgZWRpdGVkQWN0aW9ucylcbiAgICB9KVxuXG4gICAgZXhwZWN0KHN0YXJ0Q29udGludWVTdHJlYW1Nb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgY29udGludWVSZXF1ZXN0OiBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgICAgZGVjaXNpb246ICdlZGl0JyxcbiAgICAgICAgICBlZGl0ZWRBY3Rpb25zLFxuICAgICAgICB9KSxcbiAgICAgIH0pXG4gICAgKVxuICB9KVxuXG4gIGl0KCdjb21taXRzIGFjY2VzcyBkZW5pZWQgc3RyZWFtIGVycm9ycyB3aXRob3V0IHJldHJ5IHN1Z2dlc3Rpb25zJywgKCkgPT4ge1xuICAgIHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHN0cmVhbUNhbGxiYWNrcy5vbkVycm9yPy4oXG4gICAgICAgIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG1lc3NhZ2VJZDogJ21zZy1lcnInLFxuICAgICAgICAgIHBsYWNlaG9sZGVySWQ6ICdhbnN3ZXItbXNnLWVyci1zdHJlYW1pbmcnLFxuICAgICAgICB9LFxuICAgICAgICBcIkFjY2VzcyBkZW5pZWQ6IFlvdSBkb24ndCBoYXZlIHBlcm1pc3Npb24gdG8gYWNjZXNzIHRoaXMgYWdlbnRcIlxuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYWRkTWVzc2FnZU1vY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICBpc0Vycm9yOiB0cnVlLFxuICAgICAgICBtZXNzYWdlOiAnY2hhdC5lcnJvckFjY2Vzc0RlbmllZCcsXG4gICAgICB9KVxuICAgIClcbiAgICBleHBlY3QoYWRkTWVzc2FnZU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgc3VnZ2VzdGlvbnM6IFsnY2hhdC5yZXRyeSddLFxuICAgICAgfSlcbiAgICApXG4gIH0pXG5cbiAgaXQoJ21hcHMgcHJvbXB0LXRvby1sb25nIHN0cmVhbSBlcnJvcnMgd2l0aG91dCByZXRyeSBzdWdnZXN0aW9ucycsICgpID0+IHtcbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcblxuICAgIHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHN0cmVhbUNhbGxiYWNrcy5vbkVycm9yPy4oXG4gICAgICAgIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG1lc3NhZ2VJZDogJ21zZy1sb25nJyxcbiAgICAgICAgICBwbGFjZWhvbGRlcklkOiAnYW5zd2VyLW1zZy1sb25nLXN0cmVhbWluZycsXG4gICAgICAgIH0sXG4gICAgICAgICdpbnZhbGlkX3JlcXVlc3RfZXJyb3InLFxuICAgICAgICAncHJvbXB0IGlzIHRvbyBsb25nOiAxMjAwMCB0b2tlbnMnXG4gICAgICApXG4gICAgfSlcblxuICAgIGV4cGVjdChhZGRNZXNzYWdlTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIGlzRXJyb3I6IHRydWUsXG4gICAgICAgIG1lc3NhZ2U6ICdjaGF0LmVycm9yUHJvbXB0VG9vTG9uZycsXG4gICAgICB9KVxuICAgIClcbiAgICBleHBlY3QoYWRkTWVzc2FnZU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgc3VnZ2VzdGlvbnM6IFsnY2hhdC5yZXRyeSddLFxuICAgICAgfSlcbiAgICApXG4gIH0pXG5cbiAgaXQoJ21hcmtzIGJhY2tncm91bmQgc2Vzc2lvbnMgdW5yZWFkIHdoZW4gYSBzdHJlYW0gZXJyb3JzIG9mZi1zY3JlZW4nLCAoKSA9PiB7XG4gICAgYWN0aXZlVmlldy5zZXQoJ3Nlc3Npb24tdmlzaWJsZScpXG5cbiAgICByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tdmlzaWJsZScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGFjdCgoKSA9PiB7XG4gICAgICBzdHJlYW1DYWxsYmFja3Mub25FcnJvcj8uKFxuICAgICAgICB7XG4gICAgICAgICAgc2Vzc2lvbklkOiAnc2Vzc2lvbi1iZycsXG4gICAgICAgICAgbWVzc2FnZUlkOiAnYmctZXJyJyxcbiAgICAgICAgICBwbGFjZWhvbGRlcklkOiAnYW5zd2VyLWJnLWVyci1zdHJlYW1pbmcnLFxuICAgICAgICB9LFxuICAgICAgICAnc2VydmVyX2Vycm9yJ1xuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QoZ2V0Q2hhdHNTdG9yZVN0YXRlKCkubWFya0NoYXRBc1VucmVhZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ3Nlc3Npb24tYmcnKVxuICAgIGV4cGVjdChub3RpZnlTZXNzaW9uRmluaXNoZWRJbkJhY2tncm91bmQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdzZXNzaW9uLWJnJywgJ2Vycm9yJylcbiAgfSlcblxuICBpdCgnYWRkcyByZXRyeSBzdWdnZXN0aW9ucyBmb3IgZ2VuZXJpYyBzdHJlYW0gZXJyb3JzIG9uIHRoZSBhY3RpdmUgc2Vzc2lvbicsICgpID0+IHtcbiAgICByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGFjdCgoKSA9PiB7XG4gICAgICBzdHJlYW1DYWxsYmFja3Mub25FcnJvcj8uKFxuICAgICAgICB7XG4gICAgICAgICAgc2Vzc2lvbklkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBtZXNzYWdlSWQ6ICdtc2ctNTAwJyxcbiAgICAgICAgICBwbGFjZWhvbGRlcklkOiAnYW5zd2VyLW1zZy01MDAtc3RyZWFtaW5nJyxcbiAgICAgICAgfSxcbiAgICAgICAgJ3NlcnZlcl9lcnJvcidcbiAgICAgIClcbiAgICB9KVxuXG4gICAgZXhwZWN0KGFkZE1lc3NhZ2VNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgaXNFcnJvcjogdHJ1ZSxcbiAgICAgICAgc3VnZ2VzdGlvbnM6IFsnY2hhdC5yZXRyeSddLFxuICAgICAgfSlcbiAgICApXG4gIH0pXG5cbiAgaXQoJ2NyZWF0ZXMgdGhlIHN0cmVhbWluZyBwbGFjZWhvbGRlciBvbiB0aGUgZmlyc3Qgc3RyZWFtIHVwZGF0ZScsICgpID0+IHtcbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcbiAgICByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGNvbnN0IGN0eDogU3RyZWFtQ29udGV4dCA9IHtcbiAgICAgIHNlc3Npb25JZDogJ3Nlc3Npb24tMScsXG4gICAgICBtZXNzYWdlSWQ6ICdsaXZlLTEnLFxuICAgICAgcGxhY2Vob2xkZXJJZDogJ2Fuc3dlci1saXZlLTEtc3RyZWFtaW5nJyxcbiAgICB9XG5cbiAgICBhY3QoKCkgPT4ge1xuICAgICAgc3RyZWFtQ2FsbGJhY2tzLm9uU3RyZWFtVXBkYXRlPy4oY3R4LCAnR2VuZXJhbmRvJylcbiAgICB9KVxuXG4gICAgZXhwZWN0KHVzZVNlc3Npb25zU3RvcmUuZ2V0U3RhdGUoKS5nZXRNZXNzYWdlcygnc2Vzc2lvbi0xJykpLnRvRXF1YWwoXG4gICAgICBleHBlY3QuYXJyYXlDb250YWluaW5nKFtleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IGlkOiAnYW5zd2VyLWxpdmUtMS1zdHJlYW1pbmcnLCBtZXNzYWdlOiAnJyB9KV0pXG4gICAgKVxuICB9KVxuXG4gIGl0KCdtYXJrcyBiYWNrZ3JvdW5kIHNlc3Npb25zIHVucmVhZCB3aGVuIGEgc3RyZWFtIGZpbmlzaGVzIG9mZi1zY3JlZW4nLCBhc3luYyAoKSA9PiB7XG4gICAgcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi12aXNpYmxlJylcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzdHJlYW1DYWxsYmFja3Mub25GaW5pc2hTdHJlYW0/LihcbiAgICAgICAge1xuICAgICAgICAgIHNlc3Npb25JZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgbWVzc2FnZUlkOiAnYmctMScsXG4gICAgICAgICAgcGxhY2Vob2xkZXJJZDogJ2Fuc3dlci1iZy0xLXN0cmVhbWluZycsXG4gICAgICAgIH0sXG4gICAgICAgICdSZXNwdWVzdGEgZW4gYmFja2dyb3VuZCcsXG4gICAgICAgIFtdLFxuICAgICAgICAnbWVtb3J5LWJnLTEnLFxuICAgICAgICBudWxsLFxuICAgICAgICBudWxsLFxuICAgICAgICBudWxsXG4gICAgICApXG4gICAgfSlcblxuICAgIGV4cGVjdChnZXRDaGF0c1N0b3JlU3RhdGUoKS5tYXJrQ2hhdEFzVW5yZWFkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnc2Vzc2lvbi0xJylcbiAgICBleHBlY3Qobm90aWZ5U2Vzc2lvbkZpbmlzaGVkSW5CYWNrZ3JvdW5kKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnc2Vzc2lvbi0xJywgJ2NvbXBsZXRlJylcbiAgICBleHBlY3QoYWRkTWVzc2FnZU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgfSlcblxuICBpdCgnY29tbWl0cyBwcm9tcHQtdG9vLWxvbmcgc3RyZWFtIGVycm9ycyB3aXRob3V0IHJldHJ5IHN1Z2dlc3Rpb25zJywgKCkgPT4ge1xuICAgIHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHN0cmVhbUNhbGxiYWNrcy5vbkVycm9yPy4oXG4gICAgICAgIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG1lc3NhZ2VJZDogJ21zZy1sb25nJyxcbiAgICAgICAgICBwbGFjZWhvbGRlcklkOiAnYW5zd2VyLW1zZy1sb25nLXN0cmVhbWluZycsXG4gICAgICAgIH0sXG4gICAgICAgICdpbnZhbGlkX3JlcXVlc3RfZXJyb3InLFxuICAgICAgICAncHJvbXB0IGlzIHRvbyBsb25nOiAxMjAwMCB0b2tlbnMnXG4gICAgICApXG4gICAgfSlcblxuICAgIGV4cGVjdChhZGRNZXNzYWdlTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIGlzRXJyb3I6IHRydWUsXG4gICAgICAgIG1lc3NhZ2U6IGV4cGVjdC5zdHJpbmdDb250YWluaW5nKCdjaGF0LmVycm9yUHJvbXB0VG9vTG9uZycpLFxuICAgICAgfSlcbiAgICApXG4gICAgZXhwZWN0KGFkZE1lc3NhZ2VNb2NrKS5ub3QudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIHN1Z2dlc3Rpb25zOiBbJ2NoYXQucmV0cnknXSxcbiAgICAgIH0pXG4gICAgKVxuICB9KVxuXG4gIGl0KCdtYXJrcyBiYWNrZ3JvdW5kIHNlc3Npb25zIHVucmVhZCB3aGVuIGEgc3RyZWFtIGVycm9ycyBvZmYtc2NyZWVuJywgKCkgPT4ge1xuICAgIHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYWN0aXZlVmlldy5zZXQoJ290aGVyLXNlc3Npb24nKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHN0cmVhbUNhbGxiYWNrcy5vbkVycm9yPy4oXG4gICAgICAgIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG1lc3NhZ2VJZDogJ2JnLWVycicsXG4gICAgICAgICAgcGxhY2Vob2xkZXJJZDogJ2Fuc3dlci1iZy1lcnItc3RyZWFtaW5nJyxcbiAgICAgICAgfSxcbiAgICAgICAgJ3NlcnZlcl9lcnJvcidcbiAgICAgIClcbiAgICB9KVxuXG4gICAgZXhwZWN0KGdldENoYXRzU3RvcmVTdGF0ZSgpLm1hcmtDaGF0QXNVbnJlYWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdzZXNzaW9uLTEnKVxuICAgIGV4cGVjdChub3RpZnlTZXNzaW9uRmluaXNoZWRJbkJhY2tncm91bmQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdzZXNzaW9uLTEnLCAnZXJyb3InKVxuICB9KVxuXG4gIGl0KCdzeW5jcyB0YXNrIGNyZWF0aW9uIHdpdGggdGhlIHByb2plY3QgZGFzaGJvYXJkIHdoZW4gYXBwcm92YWwgY29tcGxldGVzIG9uIHRoZSBhY3RpdmUgc2Vzc2lvbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhZGRFeGlzdGluZ1Rhc2tUb0Rhc2hib2FyZCA9IGplc3QuZm4oKVxuICAgIHdpbmRvdy5uZXdQcm9qZWN0RGFzaGJvYXJkID0geyBhZGRFeGlzdGluZ1Rhc2tUb0Rhc2hib2FyZCB9XG4gICAgY29uc3Qgb3JpZ2luYWxQYXRobmFtZSA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdsb2NhdGlvbicsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHZhbHVlOiB7IC4uLndpbmRvdy5sb2NhdGlvbiwgcGF0aG5hbWU6ICcvcHJvamVjdHMvNDIvdGFza3MnIH0sXG4gICAgfSlcblxuICAgIGFjdGl2ZVZpZXcuc2V0KCdzZXNzaW9uLTEnKVxuICAgIGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzID0gW1xuICAgICAge1xuICAgICAgICBpZDogJ3VzZXItMScsXG4gICAgICAgIG1lc3NhZ2U6ICdDcmVhIGxhIHRhcmVhJyxcbiAgICAgICAgcm9sZTogQ2hhdEhpc3RvcnlSb2xlLlVTRVIsXG4gICAgICAgIHVzZXI6IHsgaWQ6ICc3JywgbmFtZTogJ0FuYScgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgcHJvamVjdElkOiA0MixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnYXBwcm92YWwtbXNnJyxcbiAgICAgICAgbWVzc2FnZTogJ8K/Q29uZmlybcOhcz8nLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGFwcHJvdmFsU3RhdHVzOiAnYXBwcm92ZWQnLFxuICAgICAgICBhcHByb3ZhbDoge1xuICAgICAgICAgIHNlc3Npb25faWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIHBlbmRpbmdfYWN0aW9uczogW3sgdGhyZWFkX2lkOiAndDEnLCB0b29sX25hbWU6ICdjcmVhdGVfdGFzaycsIHRvb2xfYXJnczogeyB0YXNrX2lkOiA1NSB9IH1dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdXG5cbiAgICByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7XG4gICAgICAgIHdyYXBwZXI6ICh7IGNoaWxkcmVuIH0pID0+IChcbiAgICAgICAgICA8R2xvYmFsQ29udGV4dFRlc3RQcm92aWRlciB2YWx1ZT17eyBhZ2VudDogdGVzdEFnZW50LCBwcm9qZWN0OiB7IGlkOiA0MiwgbmFtZTogJ0FscGhhJyB9IGFzIG5ldmVyIH19PlxuICAgICAgICAgICAge2NoaWxkcmVufVxuICAgICAgICAgIDwvR2xvYmFsQ29udGV4dFRlc3RQcm92aWRlcj5cbiAgICAgICAgKSxcbiAgICAgIH1cbiAgICApXG5cbiAgICBjb25zdCB0YXNrVXJsID0gJ2h0dHBzOi8vYXBwLmNvci5jb20vdGFza3MvNTUvZGV0YWlsJ1xuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHN0cmVhbUNhbGxiYWNrcy5vbkZpbmlzaFN0cmVhbT8uKFxuICAgICAgICB7XG4gICAgICAgICAgc2Vzc2lvbklkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBtZXNzYWdlSWQ6ICdsaXZlLTEnLFxuICAgICAgICAgIHBsYWNlaG9sZGVySWQ6IHN0cmVhbWluZ1BsYWNlaG9sZGVyTWVzc2FnZUlkKCdsaXZlLTEnKSxcbiAgICAgICAgfSxcbiAgICAgICAgdGFza1VybCxcbiAgICAgICAgW10sXG4gICAgICAgICdtZW1vcnktdGFzay0xJyxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgWydTZWd1aXInXSxcbiAgICAgICAgbnVsbFxuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYWRkRXhpc3RpbmdUYXNrVG9EYXNoYm9hcmQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFs1NV0pXG4gICAgZXhwZWN0KGFkZE1lc3NhZ2VNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgaWQ6ICdhbnN3ZXItbWVtb3J5LXRhc2stMScsXG4gICAgICAgIHN1Z2dlc3Rpb25zOiBbJ1NlZ3VpciddLFxuICAgICAgfSlcbiAgICApXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCAnbG9jYXRpb24nLCB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB2YWx1ZTogeyAuLi53aW5kb3cubG9jYXRpb24sIHBhdGhuYW1lOiBvcmlnaW5hbFBhdGhuYW1lIH0sXG4gICAgfSlcbiAgICBkZWxldGUgd2luZG93Lm5ld1Byb2plY3REYXNoYm9hcmRcbiAgfSlcblxuICBpdCgnZGlzcGF0Y2hlcyBwbGFubmVyIHN5bmMgd2hlbiBob3VycyBjaGFyZ2UgYXBwcm92YWwgY29tcGxldGVzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG9uSG91cnNDaGFyZ2VkID0gamVzdC5mbigpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoTUFJQV9IT1VSU19DSEFSR0VEX0VWRU5ULCBvbkhvdXJzQ2hhcmdlZClcbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdhcHByb3ZhbC1ob3VycycsXG4gICAgICAgIG1lc3NhZ2U6ICfCv0NhcmdvIGhvcmFzPycsXG4gICAgICAgIHJvbGU6IENoYXRIaXN0b3J5Um9sZS5BU1NJU1RBTlQsXG4gICAgICAgIHVzZXI6IHsgaWQ6ICdhc3Npc3RhbnQnLCBuYW1lOiAnTUFJQScgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgYXBwcm92YWxTdGF0dXM6ICdhcHByb3ZlZCcsXG4gICAgICAgIGFwcHJvdmFsOiB7XG4gICAgICAgICAgc2Vzc2lvbl9pZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgcGVuZGluZ19hY3Rpb25zOiBbeyB0aHJlYWRfaWQ6ICdoMScsIHRvb2xfbmFtZTogJ2NyZWF0ZV9ob3VycycsIHRvb2xfYXJnczoge30gfV0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF1cblxuICAgIHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHN0cmVhbUNhbGxiYWNrcy5vbkZpbmlzaFN0cmVhbT8uKFxuICAgICAgICB7XG4gICAgICAgICAgc2Vzc2lvbklkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBtZXNzYWdlSWQ6ICdob3Vycy0xJyxcbiAgICAgICAgICBwbGFjZWhvbGRlcklkOiBzdHJlYW1pbmdQbGFjZWhvbGRlck1lc3NhZ2VJZCgnaG91cnMtMScpLFxuICAgICAgICB9LFxuICAgICAgICAnSG9yYXMgY2FyZ2FkYXMnLFxuICAgICAgICBbXSxcbiAgICAgICAgJ21lbW9yeS1ob3Vycy0xJ1xuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3Qob25Ib3Vyc0NoYXJnZWQpLnRvSGF2ZUJlZW5DYWxsZWQoKVxuICAgIGNvbnN0IGV2ZW50ID0gb25Ib3Vyc0NoYXJnZWQubW9jay5jYWxsc1swXVswXSBhcyBDdXN0b21FdmVudFxuICAgIGV4cGVjdChldmVudC5kZXRhaWwudG9vbHMpLnRvRXF1YWwoWydjcmVhdGVfaG91cnMnXSlcblxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKE1BSUFfSE9VUlNfQ0hBUkdFRF9FVkVOVCwgb25Ib3Vyc0NoYXJnZWQpXG4gIH0pXG5cbiAgaXQoJ2ZldGNoZXMgYW5kIG1lcmdlcyBhIG5ld2x5IGNyZWF0ZWQgYWdlbnQgYWZ0ZXIgc3RyZWFtIGZpbmlzaCcsIGFzeW5jICgpID0+IHtcbiAgICB3aW5kb3cuTUFJQV9DSEFUX0FJX0ZFQVRVUkVfQUNDRVNTX01VTFRJX0FHRU5UUyA9IHRydWVcbiAgICBmZXRjaEFnZW50RGV0YWlsTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZSh7IGlkOiAnYWdlbnQtbmV3JywgbmFtZTogJ051ZXZvJyB9IGFzIG5ldmVyKVxuICAgIGNvbnN0IG9uTWVyZ2VBZ2VudCA9IGplc3QuZm4oKVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21haWEtbWVyZ2UtY3JlYXRlZC1hZ2VudC1pbnRvLWxpc3QnLCBvbk1lcmdlQWdlbnQpXG4gICAgYWN0aXZlVmlldy5zZXQoJ3Nlc3Npb24tMScpXG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnYXBwcm92YWwtYWdlbnQnLFxuICAgICAgICBtZXNzYWdlOiAnwr9DcmVvIGVsIGFnZW50ZT8nLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGFwcHJvdmFsU3RhdHVzOiAnYXBwcm92ZWQnLFxuICAgICAgICBhcHByb3ZhbDoge1xuICAgICAgICAgIHNlc3Npb25faWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIHBlbmRpbmdfYWN0aW9uczogW3sgdGhyZWFkX2lkOiAnYTEnLCB0b29sX25hbWU6ICdjcmVhdGVfYWdlbnQnLCB0b29sX2FyZ3M6IHt9IH1dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdXG5cbiAgICByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzdHJlYW1DYWxsYmFja3Mub25GaW5pc2hTdHJlYW0/LihcbiAgICAgICAge1xuICAgICAgICAgIHNlc3Npb25JZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgbWVzc2FnZUlkOiAnYWdlbnQtbGl2ZScsXG4gICAgICAgICAgcGxhY2Vob2xkZXJJZDogc3RyZWFtaW5nUGxhY2Vob2xkZXJNZXNzYWdlSWQoJ2FnZW50LWxpdmUnKSxcbiAgICAgICAgfSxcbiAgICAgICAgJ0FnZW50ZSBjcmVhZG8nLFxuICAgICAgICBbXSxcbiAgICAgICAgJ21lbW9yeS1hZ2VudC0xJyxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgJ2FnZW50LW5ldydcbiAgICAgIClcbiAgICAgIGF3YWl0IFByb21pc2UucmVzb2x2ZSgpXG4gICAgfSlcblxuICAgIGV4cGVjdChmZXRjaEFnZW50RGV0YWlsTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ2FnZW50LW5ldycpXG4gICAgZXhwZWN0KG9uTWVyZ2VBZ2VudCkudG9IYXZlQmVlbkNhbGxlZCgpXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWFpYS1tZXJnZS1jcmVhdGVkLWFnZW50LWludG8tbGlzdCcsIG9uTWVyZ2VBZ2VudClcbiAgICB3aW5kb3cuTUFJQV9DSEFUX0FJX0ZFQVRVUkVfQUNDRVNTX01VTFRJX0FHRU5UUyA9IGZhbHNlXG4gIH0pXG5cbiAgaXQoJ3JlZmV0Y2hlcyB0aGUgb3BlbiB0YXNrIHBhbmVsIGFmdGVyIGFuIGFwcHJvdmVkIHRhc2sgZWRpdCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZWZldGNoVGFzayA9IGplc3QuZm4oKVxuICAgIHdpbmRvdy50YXNrUGFuZWwgPSB7IHRhc2tJZDogODgsIHJlZmV0Y2hUYXNrIH1cbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdhcHByb3ZhbC1lZGl0JyxcbiAgICAgICAgbWVzc2FnZTogJ8K/RWRpdG8/JyxcbiAgICAgICAgcm9sZTogQ2hhdEhpc3RvcnlSb2xlLkFTU0lTVEFOVCxcbiAgICAgICAgdXNlcjogeyBpZDogJ2Fzc2lzdGFudCcsIG5hbWU6ICdNQUlBJyB9LFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgICBhcHByb3ZhbFN0YXR1czogJ2FwcHJvdmVkJyxcbiAgICAgICAgYXBwcm92YWw6IHtcbiAgICAgICAgICBzZXNzaW9uX2lkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBwZW5kaW5nX2FjdGlvbnM6IFt7IHRocmVhZF9pZDogJ2UxJywgdG9vbF9uYW1lOiAnZWRpdF90YXNrJywgdG9vbF9hcmdzOiB7IHRhc2tfaWQ6IDg4IH0gfV0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF1cblxuICAgIHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHN0cmVhbUNhbGxiYWNrcy5vbkZpbmlzaFN0cmVhbT8uKFxuICAgICAgICB7XG4gICAgICAgICAgc2Vzc2lvbklkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBtZXNzYWdlSWQ6ICdlZGl0LWxpdmUnLFxuICAgICAgICAgIHBsYWNlaG9sZGVySWQ6IHN0cmVhbWluZ1BsYWNlaG9sZGVyTWVzc2FnZUlkKCdlZGl0LWxpdmUnKSxcbiAgICAgICAgfSxcbiAgICAgICAgJ1RhcmVhIGFjdHVhbGl6YWRhJyxcbiAgICAgICAgW10sXG4gICAgICAgICdtZW1vcnktZWRpdC0xJ1xuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QocmVmZXRjaFRhc2spLnRvSGF2ZUJlZW5DYWxsZWQoKVxuICAgIGRlbGV0ZSB3aW5kb3cudGFza1BhbmVsXG4gIH0pXG5cbiAgaXQoJ3JlbG9hZHMgbWVzc2FnZXMgd2hlbiB0aGUgYWN0aXZlIHNlc3Npb24gZW5kcyB3aXRoIGEgc3RhbGUgc3RyZWFtaW5nIHBsYWNlaG9sZGVyJywgYXN5bmMgKCkgPT4ge1xuICAgIHVzZVNlc3Npb25zU3RvcmUuc2V0U3RhdGUoe1xuICAgICAgbWV0YTogeyAnc2Vzc2lvbi0xJzogeyBzdGF0dXM6ICdjb21wbGV0ZScsIGZpbmlzaGVkQXQ6ICcyMDI0LTA2LTAxVDAwOjAwOjAwLjAwMFonIH0gfSxcbiAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICdzZXNzaW9uLTEnOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6IHN0cmVhbWluZ1BsYWNlaG9sZGVyTWVzc2FnZUlkKCdzdGFsZScpLFxuICAgICAgICAgICAgbWVzc2FnZTogJycsXG4gICAgICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICAgICAgdXNlcjogeyBpZDogJ2Fzc2lzdGFudCcsIG5hbWU6ICdNQUlBJyB9LFxuICAgICAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKClcbiAgICB9KVxuXG4gICAgZXhwZWN0KGNoYXRNZXNzYWdlc1N0YXRlLmxvYWRNZXNzYWdlcykudG9IYXZlQmVlbkNhbGxlZFdpdGgoeyBmb3JjZTogdHJ1ZSB9KVxuICB9KVxuXG4gIGl0KCdyb3RhdGVzIHRvIGEgZnJlc2ggc2Vzc2lvbiBpZCB3aGVuIGluaXRpYWwgY2hhdCBpZCBjbGVhcnMnLCAoKSA9PiB7XG4gICAgY29uc3QgeyByZXJlbmRlciB9ID0gcmVuZGVySG9vayhcbiAgICAgICh7IGNoYXRJZCB9OiB7IGNoYXRJZDogc3RyaW5nIHwgbnVsbCB9KSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAge1xuICAgICAgICB3cmFwcGVyLFxuICAgICAgICBpbml0aWFsUHJvcHM6IHsgY2hhdElkOiAncHJldmlvdXMtc2Vzc2lvbicgYXMgc3RyaW5nIHwgbnVsbCB9LFxuICAgICAgfVxuICAgIClcblxuICAgIHJlcmVuZGVyKHsgY2hhdElkOiBudWxsIH0pXG5cbiAgICBleHBlY3QoZ2V0Q2hhdHNTdG9yZVN0YXRlKCkuc2V0QWN0aXZlQ2hhdElkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChudWxsKVxuICB9KVxuXG4gIGl0KCdyZXN0b3JlcyB0aGUgbWVzc2FnZSBsaXN0IHdoZW4gYSByZXRyeSBzdHJlYW0gZmFpbHMgb24gdGhlIGFjdGl2ZSBzZXNzaW9uJywgYXN5bmMgKCkgPT4ge1xuICAgIGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzID0gW1xuICAgICAge1xuICAgICAgICBpZDogJ3F1ZXN0aW9uLTEnLFxuICAgICAgICBtZXNzYWdlOiAnSG9sYScsXG4gICAgICAgIHJvbGU6IENoYXRIaXN0b3J5Um9sZS5VU0VSLFxuICAgICAgICB1c2VyOiB7IGlkOiAnNycsIG5hbWU6ICdBbmEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBpZDogJ2Fuc3dlci1zdHJlYW0tMS1jYW5jZWxsZWQnLFxuICAgICAgICBtZXNzYWdlOiAnUmVzcHVlc3RhIHBhcmNpYWwnLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ0Fzc2lzdGFudCcgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgaXNGcm9udGVuZENhbmNlbGxlZDogdHJ1ZSxcbiAgICAgIH0sXG4gICAgXVxuICAgIGNvbnN0IGRpc3BhdGNoU3B5ID0gamVzdC5zcHlPbihkb2N1bWVudCwgJ2Rpc3BhdGNoRXZlbnQnKVxuICAgIGFjdGl2ZVZpZXcuc2V0KCdzZXNzaW9uLTEnKVxuXG4gICAgY29uc3QgeyByZXN1bHQgfSA9IHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYXdhaXQgYWN0KGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHJlc3VsdC5jdXJyZW50LnJldHJ5TWVzc2FnZShjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlc1sxXSlcbiAgICB9KVxuXG4gICAgcmVwbGFjZU1lc3NhZ2VzTW9jay5tb2NrQ2xlYXIoKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHN0cmVhbUNhbGxiYWNrcy5vbkVycm9yPy4oXG4gICAgICAgIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG1lc3NhZ2VJZDogJ3JldHJ5LTEnLFxuICAgICAgICAgIHBsYWNlaG9sZGVySWQ6ICdhbnN3ZXItcmV0cnktMS1zdHJlYW1pbmcnLFxuICAgICAgICB9LFxuICAgICAgICAnc2VydmVyX2Vycm9yJ1xuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QocmVwbGFjZU1lc3NhZ2VzTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMpXG4gICAgZXhwZWN0KGRpc3BhdGNoU3B5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgdHlwZTogJ3NuYWNrYmFyLWV2ZW50JyxcbiAgICAgICAgZGV0YWlsOiBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHNldmVyaXR5OiAnZXJyb3InIH0pLFxuICAgICAgfSlcbiAgICApXG5cbiAgICBkaXNwYXRjaFNweS5tb2NrUmVzdG9yZSgpXG4gIH0pXG5cbiAgaXQoJ2NvbW1pdHMgYXNzaXN0YW50IGF0dGFjaG1lbnRzIHdoZW4gYW4gYWN0aXZlIHN0cmVhbSBmaW5pc2hlcycsIGFzeW5jICgpID0+IHtcbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcbiAgICB1c2VTZXNzaW9uc1N0b3JlLnNldFN0YXRlKHtcbiAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICdzZXNzaW9uLTEnOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6IHN0cmVhbWluZ1BsYWNlaG9sZGVyTWVzc2FnZUlkKCdsaXZlLWF0dGFjaCcpLFxuICAgICAgICAgICAgbWVzc2FnZTogJycsXG4gICAgICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICAgICAgdXNlcjogeyBpZDogJ2Fzc2lzdGFudCcsIG5hbWU6ICdNQUlBJyB9LFxuICAgICAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBjb25zdCBhdHRhY2htZW50ID0ge1xuICAgICAgaWQ6ICdhdHQtMScsXG4gICAgICBuYW1lOiAnYnJpZWYucGRmJyxcbiAgICAgIHR5cGU6ICdwZGYnLFxuICAgICAgc2l6ZTogMTAsXG4gICAgICBmaWxlOiBuZXcgRmlsZShbXSwgJ2JyaWVmLnBkZicpLFxuICAgIH1cblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzdHJlYW1DYWxsYmFja3Mub25GaW5pc2hTdHJlYW0/LihcbiAgICAgICAge1xuICAgICAgICAgIHNlc3Npb25JZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgbWVzc2FnZUlkOiAnbGl2ZS1hdHRhY2gnLFxuICAgICAgICAgIHBsYWNlaG9sZGVySWQ6IHN0cmVhbWluZ1BsYWNlaG9sZGVyTWVzc2FnZUlkKCdsaXZlLWF0dGFjaCcpLFxuICAgICAgICB9LFxuICAgICAgICAnUmVzcHVlc3RhIGNvbiBhZGp1bnRvJyxcbiAgICAgICAgW10sXG4gICAgICAgICdtZW1vcnktYXR0YWNoLTEnLFxuICAgICAgICBbYXR0YWNobWVudF0sXG4gICAgICAgIG51bGwsXG4gICAgICAgIG51bGxcbiAgICAgIClcbiAgICB9KVxuXG4gICAgZXhwZWN0KGFkZE1lc3NhZ2VNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgaWQ6ICdhbnN3ZXItbWVtb3J5LWF0dGFjaC0xJyxcbiAgICAgICAgYXR0YWNobWVudHM6IGV4cGVjdC5hcnJheUNvbnRhaW5pbmcoW2V4cGVjdC5vYmplY3RDb250YWluaW5nKHsgaWQ6ICdhdHQtMScsIG5hbWU6ICdicmllZi5wZGYnIH0pXSksXG4gICAgICB9KVxuICAgIClcbiAgfSlcblxuICBpdCgnc3luY3MgdGFzayBkZWxldGlvbiBvbiB0aGUgcHJvamVjdCBkYXNoYm9hcmQgYWZ0ZXIgYXBwcm92YWwnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZGVsZXRlRXhpc3RpbmdUYXNrRnJvbURhc2hib2FyZCA9IGplc3QuZm4oKVxuICAgIHdpbmRvdy5uZXdQcm9qZWN0RGFzaGJvYXJkID0geyBkZWxldGVFeGlzdGluZ1Rhc2tGcm9tRGFzaGJvYXJkIH1cbiAgICBjb25zdCBvcmlnaW5hbFBhdGhuYW1lID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdywgJ2xvY2F0aW9uJywge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IHsgLi4ud2luZG93LmxvY2F0aW9uLCBwYXRobmFtZTogJy9wcm9qZWN0cy80Mi90YXNrcycgfSxcbiAgICB9KVxuXG4gICAgYWN0aXZlVmlldy5zZXQoJ3Nlc3Npb24tMScpXG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnYXBwcm92YWwtZGVsZXRlJyxcbiAgICAgICAgbWVzc2FnZTogJ8K/RWxpbWlubyBsYSB0YXJlYT8nLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGFwcHJvdmFsU3RhdHVzOiAnYXBwcm92ZWQnLFxuICAgICAgICBhcHByb3ZhbDoge1xuICAgICAgICAgIHNlc3Npb25faWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIHBlbmRpbmdfYWN0aW9uczogW3sgdGhyZWFkX2lkOiAnZDEnLCB0b29sX25hbWU6ICdkZWxldGVfdGFzaycsIHRvb2xfYXJnczogeyB0YXNrX2lkOiA3NyB9IH1dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdXG5cbiAgICByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7XG4gICAgICAgIHdyYXBwZXI6ICh7IGNoaWxkcmVuIH0pID0+IChcbiAgICAgICAgICA8R2xvYmFsQ29udGV4dFRlc3RQcm92aWRlciB2YWx1ZT17eyBhZ2VudDogdGVzdEFnZW50LCBwcm9qZWN0OiB7IGlkOiA0MiwgbmFtZTogJ0FscGhhJyB9IGFzIG5ldmVyIH19PlxuICAgICAgICAgICAge2NoaWxkcmVufVxuICAgICAgICAgIDwvR2xvYmFsQ29udGV4dFRlc3RQcm92aWRlcj5cbiAgICAgICAgKSxcbiAgICAgIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgc3RyZWFtQ2FsbGJhY2tzLm9uRmluaXNoU3RyZWFtPy4oXG4gICAgICAgIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG1lc3NhZ2VJZDogJ2RlbGV0ZS1saXZlJyxcbiAgICAgICAgICBwbGFjZWhvbGRlcklkOiBzdHJlYW1pbmdQbGFjZWhvbGRlck1lc3NhZ2VJZCgnZGVsZXRlLWxpdmUnKSxcbiAgICAgICAgfSxcbiAgICAgICAgJ1RhcmVhIGVsaW1pbmFkYScsXG4gICAgICAgIFtdLFxuICAgICAgICAnbWVtb3J5LWRlbGV0ZS0xJ1xuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QoZGVsZXRlRXhpc3RpbmdUYXNrRnJvbURhc2hib2FyZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoWzc3XSlcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdsb2NhdGlvbicsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHZhbHVlOiB7IC4uLndpbmRvdy5sb2NhdGlvbiwgcGF0aG5hbWU6IG9yaWdpbmFsUGF0aG5hbWUgfSxcbiAgICB9KVxuICAgIGRlbGV0ZSB3aW5kb3cubmV3UHJvamVjdERhc2hib2FyZFxuICB9KVxuXG4gIGl0KCdjb21taXRzIGEgcGVuZGluZyBhcHByb3ZhbCBtZXNzYWdlIG9uIHRoZSBhY3RpdmUgc2Vzc2lvbicsICgpID0+IHtcbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcblxuICAgIHJlbmRlckhvb2soXG4gICAgICAoKSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBhZ2VudHM6IFt0ZXN0QWdlbnRdLFxuICAgICAgICB9KSxcbiAgICAgIHsgd3JhcHBlciB9XG4gICAgKVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHN0cmVhbUNhbGxiYWNrcy5vbkFwcHJvdmFsUmVxdWlyZWQ/LihcbiAgICAgICAge1xuICAgICAgICAgIHNlc3Npb25JZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgbWVzc2FnZUlkOiAnbGl2ZS1oaXRsJyxcbiAgICAgICAgICBwbGFjZWhvbGRlcklkOiBzdHJlYW1pbmdQbGFjZWhvbGRlck1lc3NhZ2VJZCgnbGl2ZS1oaXRsJyksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYXBwcm92YWxfcmVxdWlyZWQnLFxuICAgICAgICAgIHNlc3Npb25faWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG9yaWdpbmFsX3RocmVhZF9pZDogJ29yaWctMScsXG4gICAgICAgICAgcGVuZGluZ19hY3Rpb25zOiBbeyB0aHJlYWRfaWQ6ICd0MScsIHRvb2xfbmFtZTogJ2VkaXRfdGFzaycsIHRvb2xfYXJnczogeyB0YXNrX2lkOiAxIH0sIHRvb2xfY2FsbF9pZDogJ2MxJyB9XSxcbiAgICAgICAgICB0b3RhbF9hY3Rpb25zOiAxLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgJ8K/Q29uZmlybcOhcyBsYSBlZGljacOzbj8nXG4gICAgICApXG4gICAgfSlcblxuICAgIGV4cGVjdChhZGRNZXNzYWdlTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIGFwcHJvdmFsU3RhdHVzOiAncGVuZGluZycsXG4gICAgICAgIG1lc3NhZ2U6ICfCv0NvbmZpcm3DoXMgbGEgZWRpY2nDs24/JyxcbiAgICAgIH0pXG4gICAgKVxuICB9KVxuXG4gIGl0KCdkb2VzIG5vdCBwYWludCBhcHByb3ZhbCBVSSB3aGVuIHRoZSBzdHJlYW0gd2FzIGF1dG8tYXBwcm92ZWQnLCAoKSA9PiB7XG4gICAgYWN0aXZlVmlldy5zZXQoJ3Nlc3Npb24tMScpXG5cbiAgICByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGFjdCgoKSA9PiB7XG4gICAgICBzdHJlYW1DYWxsYmFja3Mub25BcHByb3ZhbFJlcXVpcmVkPy4oXG4gICAgICAgIHtcbiAgICAgICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIG1lc3NhZ2VJZDogJ2F1dG8taGl0bCcsXG4gICAgICAgICAgcGxhY2Vob2xkZXJJZDogc3RyZWFtaW5nUGxhY2Vob2xkZXJNZXNzYWdlSWQoJ2F1dG8taGl0bCcpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ2FwcHJvdmFsX3JlcXVpcmVkJyxcbiAgICAgICAgICBzZXNzaW9uX2lkOiAnc2Vzc2lvbi0xJyxcbiAgICAgICAgICBvcmlnaW5hbF90aHJlYWRfaWQ6ICdvcmlnLWF1dG8nLFxuICAgICAgICAgIHBlbmRpbmdfYWN0aW9uczogW3sgdGhyZWFkX2lkOiAndC1hdXRvJywgdG9vbF9uYW1lOiAnY3JlYXRlX3Rhc2snLCB0b29sX2FyZ3M6IHt9LCB0b29sX2NhbGxfaWQ6ICdjLWF1dG8nIH1dLFxuICAgICAgICAgIHRvdGFsX2FjdGlvbnM6IDEsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICAgIGF1dG9fYXBwcm92ZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgICdDcmVhbmRvIHRhcmVhJ1xuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QoYWRkTWVzc2FnZU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgfSlcblxuICBpdCgnbWFya3MgYmFja2dyb3VuZCBzZXNzaW9ucyB1bnJlYWQgd2hlbiBhcHByb3ZhbCBpcyByZXF1aXJlZCBvZmYtc2NyZWVuJywgKCkgPT4ge1xuICAgIGFjdGl2ZVZpZXcuc2V0KCdzZXNzaW9uLXZpc2libGUnKVxuXG4gICAgcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLXZpc2libGUnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhY3QoKCkgPT4ge1xuICAgICAgc3RyZWFtQ2FsbGJhY2tzLm9uQXBwcm92YWxSZXF1aXJlZD8uKFxuICAgICAgICB7XG4gICAgICAgICAgc2Vzc2lvbklkOiAnc2Vzc2lvbi1iZycsXG4gICAgICAgICAgbWVzc2FnZUlkOiAnYmctaGl0bCcsXG4gICAgICAgICAgcGxhY2Vob2xkZXJJZDogc3RyZWFtaW5nUGxhY2Vob2xkZXJNZXNzYWdlSWQoJ2JnLWhpdGwnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdhcHByb3ZhbF9yZXF1aXJlZCcsXG4gICAgICAgICAgc2Vzc2lvbl9pZDogJ3Nlc3Npb24tYmcnLFxuICAgICAgICAgIG9yaWdpbmFsX3RocmVhZF9pZDogJ29yaWctYmcnLFxuICAgICAgICAgIHBlbmRpbmdfYWN0aW9uczogW3sgdGhyZWFkX2lkOiAndC1iZycsIHRvb2xfbmFtZTogJ2VkaXRfdGFzaycsIHRvb2xfYXJnczoge30sIHRvb2xfY2FsbF9pZDogJ2MtYmcnIH1dLFxuICAgICAgICAgIHRvdGFsX2FjdGlvbnM6IDEsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICAnQXByb2JhY2nDs24gcGVuZGllbnRlJ1xuICAgICAgKVxuICAgIH0pXG5cbiAgICBleHBlY3QoZ2V0Q2hhdHNTdG9yZVN0YXRlKCkubWFya0NoYXRBc1VucmVhZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ3Nlc3Npb24tYmcnKVxuICAgIGV4cGVjdChub3RpZnlTZXNzaW9uRmluaXNoZWRJbkJhY2tncm91bmQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdzZXNzaW9uLWJnJywgJ2FwcHJvdmFsX3JlcXVpcmVkJylcbiAgICBleHBlY3QoYWRkTWVzc2FnZU1vY2spLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgfSlcblxuICBpdCgnY2xlYXJzIHBpbm5lZCBjb250ZXh0IHdoZW4gc3dpdGNoaW5nIHRvIGFub3RoZXIgZXhpc3RpbmcgY2hhdCcsICgpID0+IHtcbiAgICBjb25zdCBzZXRQcm9qZWN0ID0gamVzdC5mbigpXG4gICAgY29uc3Qgc2V0Q2xpZW50ID0gamVzdC5mbigpXG4gICAgY29uc3Qgc2V0Q2hpcHNQcm9qZWN0ID0gamVzdC5mbigpXG4gICAgY29uc3Qgc2V0VGFzayA9IGplc3QuZm4oKVxuXG4gICAgY29uc3QgY29udGV4dFdyYXBwZXIgPSAoeyBjaGlsZHJlbiB9OiB7IGNoaWxkcmVuOiBSZWFjdE5vZGUgfSkgPT4gKFxuICAgICAgPEdsb2JhbENvbnRleHRUZXN0UHJvdmlkZXJcbiAgICAgICAgdmFsdWU9e3tcbiAgICAgICAgICBhZ2VudDogdGVzdEFnZW50LFxuICAgICAgICAgIHNldFByb2plY3QsXG4gICAgICAgICAgc2V0Q2xpZW50LFxuICAgICAgICAgIHNldENoaXBzUHJvamVjdCxcbiAgICAgICAgICBzZXRUYXNrLFxuICAgICAgICB9fVxuICAgICAgPlxuICAgICAgICB7Y2hpbGRyZW59XG4gICAgICA8L0dsb2JhbENvbnRleHRUZXN0UHJvdmlkZXI+XG4gICAgKVxuXG4gICAgY29uc3QgeyByZXJlbmRlciB9ID0gcmVuZGVySG9vayhcbiAgICAgICh7IGNoYXRJZCB9OiB7IGNoYXRJZDogc3RyaW5nIHwgbnVsbCB9KSA9PlxuICAgICAgICB1c2VDaGF0TWFuYWdlcih7XG4gICAgICAgICAgY2hhdElkLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAge1xuICAgICAgICB3cmFwcGVyOiBjb250ZXh0V3JhcHBlcixcbiAgICAgICAgaW5pdGlhbFByb3BzOiB7IGNoYXRJZDogJ3Nlc3Npb24tYScgYXMgc3RyaW5nIHwgbnVsbCB9LFxuICAgICAgfVxuICAgIClcblxuICAgIDsoc2Vzc2lvblN0cmVhbU1hbmFnZXIuaXNBY3RpdmUgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUodHJ1ZSlcbiAgICByZXJlbmRlcih7IGNoYXRJZDogJ3Nlc3Npb24tYicgfSlcblxuICAgIGV4cGVjdChzZXRQcm9qZWN0KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChudWxsKVxuICAgIGV4cGVjdChzZXRDbGllbnQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKG51bGwpXG4gICAgZXhwZWN0KHNldENoaXBzUHJvamVjdCkudG9IYXZlQmVlbkNhbGxlZFdpdGgobnVsbClcbiAgICBleHBlY3Qoc2V0VGFzaykudG9IYXZlQmVlbkNhbGxlZFdpdGgobnVsbClcbiAgfSlcblxuICBpdCgnY29tbWl0cyBwYXJ0aWFsIGFzc2lzdGFudCB0ZXh0IHdoZW4gdGhlIHN0cmVhbSBzdG9wcyBtaWQtcmVzcG9uc2UnLCAoKSA9PiB7XG4gICAgYWN0aXZlVmlldy5zZXQoJ3Nlc3Npb24tMScpXG4gICAgcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBjb25zdCBjdHg6IFN0cmVhbUNvbnRleHQgPSB7XG4gICAgICBzZXNzaW9uSWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgbWVzc2FnZUlkOiAnbGl2ZS1zdG9wLTEnLFxuICAgICAgcGxhY2Vob2xkZXJJZDogc3RyZWFtaW5nUGxhY2Vob2xkZXJNZXNzYWdlSWQoJ2xpdmUtc3RvcC0xJyksXG4gICAgfVxuXG4gICAgYWN0KCgpID0+IHtcbiAgICAgIHN0cmVhbUNhbGxiYWNrcy5vblN0cmVhbVVwZGF0ZT8uKGN0eCwgJ1BhcmNpYWwnKVxuICAgIH0pXG5cbiAgICBhY3QoKCkgPT4ge1xuICAgICAgc3RyZWFtQ2FsbGJhY2tzLm9uU3RvcD8uKCdQYXJjaWFsJylcbiAgICB9KVxuXG4gICAgZXhwZWN0KGFkZE1lc3NhZ2VNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgbWVzc2FnZTogJ1BhcmNpYWwnLCByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5UIH0pXG4gICAgKVxuICAgIGV4cGVjdChhZGRNZXNzYWdlTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHJvbGU6IENoYXRIaXN0b3J5Um9sZS5BU1NJU1RBTlQsIG1lc3NhZ2U6IGV4cGVjdC5zdHJpbmdNYXRjaGluZygvY2FuY2VsL2kpIH0pXG4gICAgKVxuICB9KVxuXG4gIGl0KCdyZXBsYXlzIHZpYSBvcmNoZXN0cmF0b3Igd2hlbiByZXRyeUNvbXBsZXRpb24gcmVwb3J0cyB0dXJuX25vdF9mb3VuZCcsIGFzeW5jICgpID0+IHtcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdxdWVzdGlvbi1yZXRyeScsXG4gICAgICAgIG1lc3NhZ2U6ICfCv1N0YXR1cz8nLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuVVNFUixcbiAgICAgICAgdXNlcjogeyBpZDogJzcnLCBuYW1lOiAnQW5hJyB9LFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdhbnN3ZXItdHVybi1hYmMnLFxuICAgICAgICBtZXNzYWdlOiAnRXJyb3InLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGlzRXJyb3I6IHRydWUsXG4gICAgICAgIG1lbW9yeVNlc3Npb25JZDogJ3R1cm4tYWJjJyxcbiAgICAgIH0sXG4gICAgXVxuICAgIHJldHJ5Q29tcGxldGlvbk1vY2subW9ja1Jlc29sdmVkVmFsdWUoeyBzdGFydGVkOiBmYWxzZSwgcmVhc29uOiAndHVybl9ub3RfZm91bmQnIH0pXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQucmV0cnlNZXNzYWdlKGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzWzFdKVxuICAgIH0pXG5cbiAgICBleHBlY3QocmV0cnlDb21wbGV0aW9uTW9jaykudG9IYXZlQmVlbkNhbGxlZCgpXG4gICAgZXhwZWN0KGFza01haWFNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IG1lc3NhZ2U6ICfCv1N0YXR1cz8nIH0pKVxuICB9KVxuXG4gIGl0KCdzaG93cyBhIHNuYWNrYmFyIHdoZW4gcmV0cnlDb21wbGV0aW9uIGhpdHMgdGhlIGNvbmN1cnJlbnQgc3RyZWFtIGxpbWl0JywgYXN5bmMgKCkgPT4ge1xuICAgIGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzID0gW1xuICAgICAge1xuICAgICAgICBpZDogJ3F1ZXN0aW9uLWxpbWl0JyxcbiAgICAgICAgbWVzc2FnZTogJ1JldHJ5IG1lJyxcbiAgICAgICAgcm9sZTogQ2hhdEhpc3RvcnlSb2xlLlVTRVIsXG4gICAgICAgIHVzZXI6IHsgaWQ6ICc3JywgbmFtZTogJ0FuYScgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnYW5zd2VyLXR1cm4tbGltaXQnLFxuICAgICAgICBtZXNzYWdlOiAnRXJyb3InLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGlzRXJyb3I6IHRydWUsXG4gICAgICAgIG1lbW9yeVNlc3Npb25JZDogJ3R1cm4tbGltaXQnLFxuICAgICAgfSxcbiAgICBdXG4gICAgcmV0cnlDb21wbGV0aW9uTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZSh7IHN0YXJ0ZWQ6IGZhbHNlLCByZWFzb246ICdsaW1pdCcgfSlcbiAgICBjb25zdCBkaXNwYXRjaFNweSA9IGplc3Quc3B5T24oZG9jdW1lbnQsICdkaXNwYXRjaEV2ZW50JylcblxuICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZW5kZXJIb29rKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXNlQ2hhdE1hbmFnZXIoe1xuICAgICAgICAgIGNoYXRJZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgYWdlbnRzOiBbdGVzdEFnZW50XSxcbiAgICAgICAgfSksXG4gICAgICB7IHdyYXBwZXIgfVxuICAgIClcblxuICAgIGF3YWl0IGFjdChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCByZXN1bHQuY3VycmVudC5yZXRyeU1lc3NhZ2UoY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXNbMV0pXG4gICAgfSlcblxuICAgIGV4cGVjdChkaXNwYXRjaFNweSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIHR5cGU6ICdzbmFja2Jhci1ldmVudCcsXG4gICAgICAgIGRldGFpbDogZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoeyBtZXNzYWdlOiBleHBlY3QuYW55KFN0cmluZykgfSksXG4gICAgICB9KVxuICAgIClcbiAgICBkaXNwYXRjaFNweS5tb2NrUmVzdG9yZSgpXG4gIH0pXG5cbiAgaXQoJ3Nob3dzIGEgc25hY2tiYXIgd2hlbiByZXBsYXlWaWFPcmNoZXN0cmF0b3IgaGl0cyB0aGUgY29uY3VycmVudCBzdHJlYW0gbGltaXQnLCBhc3luYyAoKSA9PiB7XG4gICAgY2hhdE1lc3NhZ2VzU3RhdGUubWVzc2FnZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiAncXVlc3Rpb24tcmVwbGF5LWxpbWl0JyxcbiAgICAgICAgbWVzc2FnZTogJ0hvbGEnLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuVVNFUixcbiAgICAgICAgdXNlcjogeyBpZDogJzcnLCBuYW1lOiAnQW5hJyB9LFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdhbnN3ZXItdHVybi1yZXBsYXktbGltaXQnLFxuICAgICAgICBtZXNzYWdlOiAnRXJyb3InLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGlzRXJyb3I6IHRydWUsXG4gICAgICAgIG1lbW9yeVNlc3Npb25JZDogJ3R1cm4tcmVwbGF5LWxpbWl0JyxcbiAgICAgIH0sXG4gICAgXVxuICAgIHJldHJ5Q29tcGxldGlvbk1vY2subW9ja1Jlc29sdmVkVmFsdWUoeyBzdGFydGVkOiBmYWxzZSwgcmVhc29uOiAndHVybl9ub3RfZm91bmQnIH0pXG4gICAgYXNrTWFpYU1vY2subW9ja1Jlc29sdmVkVmFsdWUoeyBzdGFydGVkOiBmYWxzZSwgcmVhc29uOiAnbGltaXQnIH0pXG4gICAgY29uc3QgZGlzcGF0Y2hTcHkgPSBqZXN0LnNweU9uKGRvY3VtZW50LCAnZGlzcGF0Y2hFdmVudCcpXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQucmV0cnlNZXNzYWdlKGNoYXRNZXNzYWdlc1N0YXRlLm1lc3NhZ2VzWzFdKVxuICAgIH0pXG5cbiAgICBleHBlY3QoZGlzcGF0Y2hTcHkpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICB0eXBlOiAnc25hY2tiYXItZXZlbnQnLFxuICAgICAgfSlcbiAgICApXG4gICAgZGlzcGF0Y2hTcHkubW9ja1Jlc3RvcmUoKVxuICB9KVxuXG4gIGl0KCdzaG93cyBhIHNuYWNrYmFyIHdoZW4gYXBwcm92YWwgY29udGludWUgc3RyZWFtIGZhaWxzIHRvIHN0YXJ0IGR1ZSB0byBsaW1pdCcsIGFzeW5jICgpID0+IHtcbiAgICBhY3RpdmVWaWV3LnNldCgnc2Vzc2lvbi0xJylcbiAgICBzdGFydENvbnRpbnVlU3RyZWFtTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZSh7IHN0YXJ0ZWQ6IGZhbHNlLCByZWFzb246ICdsaW1pdCcgfSlcbiAgICBjb25zdCBkaXNwYXRjaFNweSA9IGplc3Quc3B5T24oZG9jdW1lbnQsICdkaXNwYXRjaEV2ZW50JylcbiAgICBjaGF0TWVzc2FnZXNTdGF0ZS5tZXNzYWdlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdtc2ctYXBwcm92YWwtbGltaXQnLFxuICAgICAgICBtZXNzYWdlOiAnQXBwcm92ZT8nLFxuICAgICAgICByb2xlOiBDaGF0SGlzdG9yeVJvbGUuQVNTSVNUQU5ULFxuICAgICAgICB1c2VyOiB7IGlkOiAnYXNzaXN0YW50JywgbmFtZTogJ01BSUEnIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGFwcHJvdmFsOiB7XG4gICAgICAgICAgc2Vzc2lvbl9pZDogJ3Nlc3Npb24tMScsXG4gICAgICAgICAgcGVuZGluZ19hY3Rpb25zOiBbeyB0aHJlYWRfaWQ6ICd0aHJlYWQtbGltaXQnLCB0b29sX25hbWU6ICdlZGl0X3Rhc2snLCB0b29sX2FyZ3M6IHt9IH1dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdXG5cbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVuZGVySG9vayhcbiAgICAgICgpID0+XG4gICAgICAgIHVzZUNoYXRNYW5hZ2VyKHtcbiAgICAgICAgICBjaGF0SWQ6ICdzZXNzaW9uLTEnLFxuICAgICAgICAgIGFnZW50czogW3Rlc3RBZ2VudF0sXG4gICAgICAgIH0pLFxuICAgICAgeyB3cmFwcGVyIH1cbiAgICApXG5cbiAgICBhd2FpdCBhY3QoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgcmVzdWx0LmN1cnJlbnQuaGFuZGxlQXBwcm92YWxEZWNpc2lvbihbJ3RocmVhZC1saW1pdCddLCAnYXBwcm92ZScpXG4gICAgfSlcblxuICAgIGV4cGVjdChzdGFydENvbnRpbnVlU3RyZWFtTW9jaykudG9IYXZlQmVlbkNhbGxlZCgpXG4gICAgZXhwZWN0KGRpc3BhdGNoU3B5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgdHlwZTogJ3NuYWNrYmFyLWV2ZW50JyxcbiAgICAgIH0pXG4gICAgKVxuICAgIGRpc3BhdGNoU3B5Lm1vY2tSZXN0b3JlKClcbiAgfSlcbn0pXG4iXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0EsU0FBU0EsR0FBRyxFQUFFQyxVQUFVLFFBQVEsd0JBQXdCO0FBQ3hELFNBQVNDLHlCQUF5QixFQUFFQyxTQUFTLFFBQVEsMkJBQTJCO0FBQ2hGLFNBQVNDLGdCQUFnQixRQUFRLHVDQUF1QztBQUN4RSxTQUFTQyxvQkFBb0IsUUFBUSwyQ0FBMkM7QUFDaEYsU0FBMEJDLGVBQWUsUUFBcUIsa0JBQWtCO0FBQ2hGLFNBQVNDLFFBQVEsUUFBUSw0REFBNEQ7QUFDckYsT0FBT0MsSUFBSSxNQUFNLHFCQUFxQjtBQUN0QyxTQUFTQyxVQUFVLFFBQVEsaUNBQWlDO0FBQzVELFNBQVNDLHFCQUFxQixRQUFRLDBCQUEwQjtBQUVoRSxTQUFTQyxrQkFBa0IsUUFBUSwyQkFBMkI7QUFDOUQsU0FBU0MsaUNBQWlDLFFBQVEsMkNBQTJDO0FBQzdGLFNBQVNDLGdCQUFnQixRQUFRLDZDQUE2QztBQUM5RSxTQUFTQyx3QkFBd0IsUUFBUSxtQ0FBbUM7QUFDNUUsU0FBU0MsNkJBQTZCLFFBQVEsb0NBQW9DO0FBQ2xGLFNBQVNDLHNCQUFzQixRQUFRLG9DQUFvQztBQUMzRSxTQUFTQyxjQUFjLFFBQVEsa0JBQWtCO0FBQUEsU0FBQUMsR0FBQSxJQUFBQyxJQUFBO0FBRWpELElBQU1DLG9CQUFvQixHQUFHUCxnQkFBZ0U7QUFFN0YsSUFBTVEseUJBQXlCLEdBQUdYLHFCQUEwRTtBQWtCNUcsSUFBSVksZUFBd0MsR0FBRyxDQUFDLENBQUM7QUFFakQsSUFBTUMsdUJBQXVCLEdBQUdDLElBQUksQ0FBQ0MsRUFBRSxDQUFDLENBQUMsQ0FBQ0MsaUJBQWlCLENBQUM7RUFBRUMsT0FBTyxFQUFFO0FBQUssQ0FBQyxDQUFDO0FBRTlFLElBQU1DLFdBQVcsR0FBR0osSUFBSSxDQUFDQyxFQUFFLENBQUMsQ0FBQyxDQUFD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